Merge branch 'master' into careminster-presence-refactor

avinationmerge
Melanie 2010-03-06 12:37:24 +00:00
commit 8180c72cbc
34 changed files with 1259 additions and 428 deletions

View File

@ -85,6 +85,8 @@
</exec> </exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.data.mysql.tests)==0}" /> <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.data.mysql.tests)==0}" />
<delete dir="%temp%"/>
</target> </target>
<target name="test-cov" depends="build"> <target name="test-cov" depends="build">

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using OpenMetaverse;
using OpenSim.Framework;
namespace OpenSim.Data
{
// This MUST be a ref type!
public class GridUserData
{
public string UserID;
public Dictionary<string, string> Data;
}
/// <summary>
/// An interface for connecting to the user grid datastore
/// </summary>
public interface IGridUserData
{
GridUserData GetGridUserData(string userID);
bool StoreGridUserData(GridUserData data);
}
}

View File

@ -198,7 +198,6 @@ namespace OpenSim.Data.MySQL
{ {
using (MySqlCommand cmd = new MySqlCommand()) using (MySqlCommand cmd = new MySqlCommand())
{ {
string query = String.Format("select * from {0} where {1}", string query = String.Format("select * from {0} where {1}",
m_Realm, where); m_Realm, where);

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using System.Threading;
using log4net;
using OpenMetaverse;
using OpenSim.Framework;
using MySql.Data.MySqlClient;
namespace OpenSim.Data.MySQL
{
/// <summary>
/// A MySQL Interface for user grid data
/// </summary>
public class MySQLGridUserData : MySQLGenericTableHandler<GridUserData>, IGridUserData
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public MySQLGridUserData(string connectionString, string realm) : base(connectionString, realm, "UserGrid") {}
public GridUserData GetGridUserData(string userID)
{
GridUserData[] ret = Get("UserID", userID);
if (ret.Length == 0)
return null;
return ret[0];
}
public bool StoreGridUserData(GridUserData data)
{
return Store(data);
}
}
}

View File

@ -122,7 +122,7 @@ namespace OpenSim.Data.MySQL
cmd.CommandText = String.Format("select * from {0} where UserID=?UserID", m_Realm); cmd.CommandText = String.Format("select * from {0} where UserID=?UserID", m_Realm);
cmd.Parameters.AddWithValue("?UserID", userID); cmd.Parameters.AddWithValue("?UserID", userID);
;
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
@ -131,7 +131,6 @@ namespace OpenSim.Data.MySQL
using (IDataReader reader = cmd.ExecuteReader()) using (IDataReader reader = cmd.ExecuteReader())
{ {
List<UUID> deleteSessions = new List<UUID>(); List<UUID> deleteSessions = new List<UUID>();
int online = 0; int online = 0;
@ -143,6 +142,7 @@ namespace OpenSim.Data.MySQL
deleteSessions.Add(new UUID(reader["SessionID"].ToString())); deleteSessions.Add(new UUID(reader["SessionID"].ToString()));
} }
// Leave one session behind so that we can pick up details such as home location
if (online == 0 && deleteSessions.Count > 0) if (online == 0 && deleteSessions.Count > 0)
deleteSessions.RemoveAt(0); deleteSessions.RemoveAt(0);

View File

@ -28,6 +28,8 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using log4net;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Data; using OpenSim.Data;
@ -36,6 +38,8 @@ namespace OpenSim.Data.Null
{ {
public class NullPresenceData : IPresenceData public class NullPresenceData : IPresenceData
{ {
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static NullPresenceData Instance; private static NullPresenceData Instance;
Dictionary<UUID, PresenceData> m_presenceData = new Dictionary<UUID, PresenceData>(); Dictionary<UUID, PresenceData> m_presenceData = new Dictionary<UUID, PresenceData>();
@ -47,13 +51,6 @@ namespace OpenSim.Data.Null
Instance = this; Instance = this;
//Console.WriteLine("[XXX] NullRegionData constructor"); //Console.WriteLine("[XXX] NullRegionData constructor");
// Let's stick in a test presence
PresenceData p = new PresenceData();
p.SessionID = UUID.Zero;
p.UserID = UUID.Zero.ToString();
p.Data = new Dictionary<string, string>();
p.Data["Online"] = true.ToString();
m_presenceData.Add(UUID.Zero, p);
} }
} }
@ -62,6 +59,9 @@ namespace OpenSim.Data.Null
if (Instance != this) if (Instance != this)
return Instance.Store(data); return Instance.Store(data);
// m_log.DebugFormat("[NULL PRESENCE DATA]: Storing presence {0}", data.UserID);
// Console.WriteLine("HOME for " + data.UserID + " is " + (data.Data.ContainsKey("HomeRegionID") ? data.Data["HomeRegionID"] : "Not found"));
m_presenceData[data.SessionID] = data; m_presenceData[data.SessionID] = data;
return true; return true;
} }
@ -100,6 +100,7 @@ namespace OpenSim.Data.Null
{ {
if (Instance != this) if (Instance != this)
return Instance.ReportAgent(sessionID, regionID, position, lookAt); return Instance.ReportAgent(sessionID, regionID, position, lookAt);
if (m_presenceData.ContainsKey(sessionID)) if (m_presenceData.ContainsKey(sessionID))
{ {
m_presenceData[sessionID].RegionID = regionID; m_presenceData[sessionID].RegionID = regionID;
@ -121,6 +122,10 @@ namespace OpenSim.Data.Null
{ {
if (p.UserID == userID) if (p.UserID == userID)
{ {
// m_log.DebugFormat(
// "[NULL PRESENCE DATA]: Setting home location {0} {1} {2} for {3}",
// regionID, position, lookAt, p.UserID);
p.Data["HomeRegionID"] = regionID.ToString(); p.Data["HomeRegionID"] = regionID.ToString();
p.Data["HomePosition"] = position.ToString(); p.Data["HomePosition"] = position.ToString();
p.Data["HomeLookAt"] = lookAt.ToString(); p.Data["HomeLookAt"] = lookAt.ToString();
@ -136,12 +141,21 @@ namespace OpenSim.Data.Null
if (Instance != this) if (Instance != this)
return Instance.Get(field, data); return Instance.Get(field, data);
// m_log.DebugFormat(
// "[NULL PRESENCE DATA]: Getting presence data for field {0} with parameter {1}", field, data);
List<PresenceData> presences = new List<PresenceData>(); List<PresenceData> presences = new List<PresenceData>();
if (field == "UserID") if (field == "UserID")
{ {
foreach (PresenceData p in m_presenceData.Values) foreach (PresenceData p in m_presenceData.Values)
{
if (p.UserID == data) if (p.UserID == data)
{
presences.Add(p); presences.Add(p);
// Console.WriteLine("HOME for " + p.UserID + " is " + (p.Data.ContainsKey("HomeRegionID") ? p.Data["HomeRegionID"] : "Not found"));
}
}
return presences.ToArray(); return presences.ToArray();
} }
else if (field == "SessionID") else if (field == "SessionID")
@ -187,29 +201,39 @@ namespace OpenSim.Data.Null
return; return;
} }
// m_log.DebugFormat("[NULL PRESENCE DATA]: Prune called for {0}", userID);
List<UUID> deleteSessions = new List<UUID>(); List<UUID> deleteSessions = new List<UUID>();
int online = 0; int online = 0;
foreach (KeyValuePair<UUID, PresenceData> kvp in m_presenceData) foreach (KeyValuePair<UUID, PresenceData> kvp in m_presenceData)
{ {
// m_log.DebugFormat("Online: {0}", kvp.Value.Data["Online"]);
bool on = false; bool on = false;
if (bool.TryParse(kvp.Value.Data["Online"], out on) && on) if (bool.TryParse(kvp.Value.Data["Online"], out on) && on)
online++; online++;
else else
deleteSessions.Add(kvp.Key); deleteSessions.Add(kvp.Key);
} }
// m_log.DebugFormat("[NULL PRESENCE DATA]: online [{0}], deleteSession.Count [{1}]", online, deleteSessions.Count);
// Leave one session behind so that we can pick up details such as home location
if (online == 0 && deleteSessions.Count > 0) if (online == 0 && deleteSessions.Count > 0)
deleteSessions.RemoveAt(0); deleteSessions.RemoveAt(0);
foreach (UUID s in deleteSessions) foreach (UUID s in deleteSessions)
m_presenceData.Remove(s); m_presenceData.Remove(s);
} }
public bool Delete(string field, string data) public bool Delete(string field, string data)
{ {
// m_log.DebugFormat(
// "[NULL PRESENCE DATA]: Deleting presence data for field {0} with parameter {1}", field, data);
if (Instance != this) if (Instance != this)
return Delete(field, data); return Instance.Delete(field, data);
List<UUID> presences = new List<UUID>(); List<UUID> presences = new List<UUID>();
if (field == "UserID") if (field == "UserID")

View File

@ -1,10 +1,15 @@
using System; using System;
using System.Collections.Generic;
using System.Reflection;
using log4net;
using OpenMetaverse; using OpenMetaverse;
namespace OpenSim.Framework namespace OpenSim.Framework
{ {
public static class SLUtil public static class SLUtil
{ {
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
#region SL / file extension / content-type conversions #region SL / file extension / content-type conversions
public static string SLAssetTypeToContentType(int assetType) public static string SLAssetTypeToContentType(int assetType)
@ -181,5 +186,107 @@ namespace OpenSim.Framework
} }
#endregion SL / file extension / content-type conversions #endregion SL / file extension / content-type conversions
/// <summary>
/// Parse a notecard in Linden format to a string of ordinary text.
/// </summary>
/// <param name="rawInput"></param>
/// <returns></returns>
public static string ParseNotecardToString(string rawInput)
{
string[] output = ParseNotecardToList(rawInput).ToArray();
// foreach (string line in output)
// m_log.DebugFormat("[PARSE NOTECARD]: ParseNotecardToString got line {0}", line);
return string.Join("\n", output);
}
/// <summary>
/// Parse a notecard in Linden format to a list of ordinary lines.
/// </summary>
/// <param name="rawInput"></param>
/// <returns></returns>
public static List<string> ParseNotecardToList(string rawInput)
{
string[] input = rawInput.Replace("\r", "").Split('\n');
int idx = 0;
int level = 0;
List<string> output = new List<string>();
string[] words;
while (idx < input.Length)
{
if (input[idx] == "{")
{
level++;
idx++;
continue;
}
if (input[idx]== "}")
{
level--;
idx++;
continue;
}
switch (level)
{
case 0:
words = input[idx].Split(' '); // Linden text ver
// Notecards are created *really* empty. Treat that as "no text" (just like after saving an empty notecard)
if (words.Length < 3)
return output;
int version = int.Parse(words[3]);
if (version != 2)
return output;
break;
case 1:
words = input[idx].Split(' ');
if (words[0] == "LLEmbeddedItems")
break;
if (words[0] == "Text")
{
int len = int.Parse(words[2]);
idx++;
int count = -1;
while (count < len)
{
// int l = input[idx].Length;
string ln = input[idx];
int need = len-count-1;
if (ln.Length > need)
ln = ln.Substring(0, need);
// m_log.DebugFormat("[PARSE NOTECARD]: Adding line {0}", ln);
output.Add(ln);
count += ln.Length + 1;
idx++;
}
return output;
}
break;
case 2:
words = input[idx].Split(' '); // count
if (words[0] == "count")
{
int c = int.Parse(words[1]);
if (c > 0)
return output;
break;
}
break;
}
idx++;
}
return output;
}
} }
} }

View File

@ -42,6 +42,8 @@ namespace OpenSim
/// </summary> /// </summary>
public class ConfigurationLoader public class ConfigurationLoader
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary> /// <summary>
/// Various Config settings the region needs to start /// Various Config settings the region needs to start
/// Physics Engine, Mesh Engine, GridMode, PhysicsPrim allowed, Neighbor, /// Physics Engine, Mesh Engine, GridMode, PhysicsPrim allowed, Neighbor,
@ -60,17 +62,6 @@ namespace OpenSim
/// </summary> /// </summary>
protected NetworkServersInfo m_networkServersInfo; protected NetworkServersInfo m_networkServersInfo;
/// <summary>
/// Console logger
/// </summary>
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
public ConfigurationLoader()
{
}
/// <summary> /// <summary>
/// Loads the region configuration /// Loads the region configuration
/// </summary> /// </summary>
@ -164,12 +155,12 @@ namespace OpenSim
m_config.Source = new IniConfigSource(); m_config.Source = new IniConfigSource();
m_config.Source.Merge(DefaultConfig()); m_config.Source.Merge(DefaultConfig());
m_log.Info("[CONFIG] Reading configuration settings"); m_log.Info("[CONFIG]: Reading configuration settings");
if (sources.Count == 0) if (sources.Count == 0)
{ {
m_log.FatalFormat("[CONFIG] Could not load any configuration"); m_log.FatalFormat("[CONFIG]: Could not load any configuration");
m_log.FatalFormat("[CONFIG] Did you copy the OpenSim.ini.example file to OpenSim.ini?"); m_log.FatalFormat("[CONFIG]: Did you copy the OpenSim.ini.example file to OpenSim.ini?");
Environment.Exit(1); Environment.Exit(1);
} }
@ -182,13 +173,12 @@ namespace OpenSim
if (!iniFileExists) if (!iniFileExists)
{ {
m_log.FatalFormat("[CONFIG] Could not load any configuration"); m_log.FatalFormat("[CONFIG]: Could not load any configuration");
m_log.FatalFormat("[CONFIG] Configuration exists, but there was an error loading it!"); m_log.FatalFormat("[CONFIG]: Configuration exists, but there was an error loading it!");
Environment.Exit(1); Environment.Exit(1);
} }
// Make sure command line options take precedence // Make sure command line options take precedence
//
m_config.Source.Merge(argvSource); m_config.Source.Merge(argvSource);
ReadConfigSettings(); ReadConfigSettings();
@ -257,20 +247,17 @@ namespace OpenSim
if (!IsUri(iniPath)) if (!IsUri(iniPath))
{ {
m_log.InfoFormat("[CONFIG] Reading configuration file {0}", m_log.InfoFormat("[CONFIG]: Reading configuration file {0}", Path.GetFullPath(iniPath));
Path.GetFullPath(iniPath));
m_config.Source.Merge(new IniConfigSource(iniPath)); m_config.Source.Merge(new IniConfigSource(iniPath));
success = true; success = true;
} }
else else
{ {
m_log.InfoFormat("[CONFIG] {0} is a http:// URI, fetching ...", m_log.InfoFormat("[CONFIG]: {0} is a http:// URI, fetching ...", iniPath);
iniPath);
// The ini file path is a http URI // The ini file path is a http URI
// Try to read it // Try to read it
//
try try
{ {
XmlReader r = XmlReader.Create(iniPath); XmlReader r = XmlReader.Create(iniPath);
@ -281,7 +268,7 @@ namespace OpenSim
} }
catch (Exception e) catch (Exception e)
{ {
m_log.FatalFormat("[CONFIG] Exception reading config from URI {0}\n" + e.ToString(), iniPath); m_log.FatalFormat("[CONFIG]: Exception reading config from URI {0}\n" + e.ToString(), iniPath);
Environment.Exit(1); Environment.Exit(1);
} }
} }

View File

@ -144,6 +144,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>A reference to the LLUDPServer that is managing this client</summary> /// <summary>A reference to the LLUDPServer that is managing this client</summary>
private readonly LLUDPServer m_udpServer; private readonly LLUDPServer m_udpServer;
/// <summary>Caches packed throttle information</summary>
private byte[] m_packedThrottles;
private int m_defaultRTO = 3000; private int m_defaultRTO = 3000;
private int m_maxRTO = 60000; private int m_maxRTO = 60000;
@ -350,11 +353,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture]; bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture];
bucket.DripRate = texture; bucket.DripRate = texture;
bucket.MaxBurst = texture; bucket.MaxBurst = texture;
// Reset the packed throttles cached data
m_packedThrottles = null;
} }
public byte[] GetThrottlesPacked() public byte[] GetThrottlesPacked()
{ {
byte[] data = new byte[7 * 4]; byte[] data = m_packedThrottles;
if (data == null)
{
data = new byte[7 * 4];
int i = 0; int i = 0;
Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Resend].DripRate), 0, data, i, 4); i += 4; Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Resend].DripRate), 0, data, i, 4); i += 4;
@ -366,6 +376,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate), 0, data, i, 4); i += 4; Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate), 0, data, i, 4); i += 4;
Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate), 0, data, i, 4); i += 4; Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate), 0, data, i, 4); i += 4;
m_packedThrottles = data;
}
return data; return data;
} }

View File

@ -0,0 +1,257 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Collections.Generic;
using System.Reflection;
using log4net;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.CoreModules.Avatar.Attachments
{
public class AttachmentsModule : IAttachmentsModule, IRegionModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected Scene m_scene = null;
public void Initialise(Scene scene, IConfigSource source)
{
scene.RegisterModuleInterface<IAttachmentsModule>(this);
m_scene = scene;
}
public void PostInitialise()
{
}
public void Close()
{
}
public string Name
{
get { return "Attachments Module"; }
}
public bool IsSharedModule
{
get { return false; }
}
public bool AttachObject(
IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent)
{
SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
if (group != null)
{
if (m_scene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId))
{
// If the attachment point isn't the same as the one previously used
// set it's offset position = 0 so that it appears on the attachment point
// and not in a weird location somewhere unknown.
if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint())
{
attachPos = Vector3.Zero;
}
// AttachmentPt 0 means the client chose to 'wear' the attachment.
if (AttachmentPt == 0)
{
// Check object for stored attachment point
AttachmentPt = (uint)group.GetAttachmentPoint();
}
// if we still didn't find a suitable attachment point.......
if (AttachmentPt == 0)
{
// Stick it on left hand with Zero Offset from the attachment point.
AttachmentPt = (uint)AttachmentPoint.LeftHand;
attachPos = Vector3.Zero;
}
group.SetAttachmentPoint((byte)AttachmentPt);
group.AbsolutePosition = attachPos;
// Saves and gets itemID
UUID itemId;
if (group.GetFromItemID() == UUID.Zero)
{
m_scene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemId);
}
else
{
itemId = group.GetFromItemID();
}
SetAttachmentInventoryStatus(remoteClient, AttachmentPt, itemId, group);
group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent);
// In case it is later dropped again, don't let
// it get cleaned up
group.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
group.HasGroupChanged = false;
}
else
{
remoteClient.SendAgentAlertMessage(
"You don't have sufficient permissions to attach this object", false);
return false;
}
}
else
{
m_log.DebugFormat("[ATTACHMENTS MODULE]: AttachObject found no such scene object {0}", objectLocalID);
return false;
}
return true;
}
public UUID SetAttachmentInventoryStatus(
SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
{
m_log.DebugFormat(
"[ATTACHMENTS MODULEY]: Updating inventory of {0} to show attachment of {1} (item ID {2})",
remoteClient.Name, att.Name, itemID);
if (!att.IsDeleted)
AttachmentPt = att.RootPart.AttachmentPoint;
ScenePresence presence;
if (m_scene.TryGetAvatar(remoteClient.AgentId, out presence))
{
InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
item = m_scene.InventoryService.GetItem(item);
presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/);
}
return att.UUID;
}
/// <summary>
/// Update the user inventory to reflect an attachment
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="AttachmentPt"></param>
/// <param name="itemID"></param>
/// <param name="att"></param>
public void SetAttachmentInventoryStatus(
IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
{
// m_log.DebugFormat(
// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
// att.Name, remoteClient.Name, AttachmentPt, itemID);
if (UUID.Zero == itemID)
{
m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment. Error inventory item ID.");
return;
}
if (0 == AttachmentPt)
{
m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment. Error attachment point.");
return;
}
if (null == att.RootPart)
{
m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment for a prim without the rootpart!");
return;
}
ScenePresence presence;
if (m_scene.TryGetAvatar(remoteClient.AgentId, out presence))
{
// XXYY!!
InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
item = m_scene.InventoryService.GetItem(item);
presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /* att.UUID */);
if (m_scene.AvatarFactory != null)
m_scene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
}
}
public void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient)
{
ScenePresence presence;
if (m_scene.TryGetAvatar(remoteClient.AgentId, out presence))
{
presence.Appearance.DetachAttachment(itemID);
// Save avatar attachment information
if (m_scene.AvatarFactory != null)
{
m_log.Debug("[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + ", ItemID: " + itemID);
m_scene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
}
}
DetachSingleAttachmentToInv(itemID, remoteClient);
}
// What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards.
// To LocalId or UUID, *THAT* is the question. How now Brown UUID??
protected void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient)
{
if (itemID == UUID.Zero) // If this happened, someone made a mistake....
return;
// We can NOT use the dictionries here, as we are looking
// for an entity by the fromAssetID, which is NOT the prim UUID
List<EntityBase> detachEntities = m_scene.GetEntities();
SceneObjectGroup group;
foreach (EntityBase entity in detachEntities)
{
if (entity is SceneObjectGroup)
{
group = (SceneObjectGroup)entity;
if (group.GetFromItemID() == itemID)
{
m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero);
group.DetachToInventoryPrep();
m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString());
m_scene.UpdateKnownItem(remoteClient, group,group.GetFromItemID(), group.OwnerID);
m_scene.DeleteSceneObject(group, false);
return;
}
}
}
}
}
}

View File

@ -0,0 +1,139 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using log4net;
using Nini.Config;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
using OpenMetaverse;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser
{
public class LocalGridUserServicesConnector : ISharedRegionModule, IGridUserService
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IGridUserService m_service;
private bool m_Enabled = false;
public Type ReplaceableInterface
{
get { return null; }
}
public string Name
{
get { return "LocalGridUserServicesConnector"; }
}
public void Initialise(IConfigSource source)
{
IConfig moduleConfig = source.Configs["Modules"];
if (moduleConfig != null)
{
string name = moduleConfig.GetString("GridUserServices", "");
if (name == Name)
{
IConfig userConfig = source.Configs["GridUserService"];
if (userConfig == null)
{
m_log.Error("[LOCAL GRID USER SERVICE CONNECTOR]: GridUserService missing from ini files");
return;
}
string serviceDll = userConfig.GetString("LocalServiceModule", String.Empty);
if (serviceDll == String.Empty)
{
m_log.Error("[LOCAL GRID USER SERVICE CONNECTOR]: No LocalServiceModule named in section GridUserService");
return;
}
Object[] args = new Object[] { source };
m_service = ServerUtils.LoadPlugin<IGridUserService>(serviceDll, args);
if (m_service == null)
{
m_log.Error("[LOCAL GRID USER SERVICE CONNECTOR]: Can't load GridUser service");
return;
}
m_Enabled = true;
m_log.Info("[LOCAL GRID USER SERVICE CONNECTOR]: Local GridUser connector enabled");
}
}
}
public void PostInitialise()
{
if (!m_Enabled)
return;
}
public void Close()
{
if (!m_Enabled)
return;
}
public void AddRegion(Scene scene)
{
if (!m_Enabled)
return;
scene.RegisterModuleInterface<IGridUserService>(m_service);
}
public void RemoveRegion(Scene scene)
{
if (!m_Enabled)
return;
}
public void RegionLoaded(Scene scene)
{
if (!m_Enabled)
return;
}
public GridUserInfo GetGridUserInfo(string userID)
{
return m_service.GetGridUserInfo(userID);
}
public bool StoreGridUserInfo(GridUserInfo info)
{
return m_service.StoreGridUserInfo(info);
}
}
}

View File

@ -47,7 +47,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
private bool m_Enabled = false; private bool m_Enabled = false;
private PresenceDetector m_PresenceDetector; private PresenceDetector m_PresenceDetector;
private IPresenceService m_PresenceService;
/// <summary>
/// Underlying presence service. Do not use directly.
/// </summary>
public IPresenceService m_PresenceService;
public LocalPresenceServicesConnector() public LocalPresenceServicesConnector()
{ {

View File

@ -59,6 +59,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.Tests
config.Configs["PresenceService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); config.Configs["PresenceService"].Set("StorageProvider", "OpenSim.Data.Null.dll");
m_LocalConnector = new LocalPresenceServicesConnector(config); m_LocalConnector = new LocalPresenceServicesConnector(config);
// Let's stick in a test presence
m_LocalConnector.m_PresenceService.LoginAgent(UUID.Zero.ToString(), UUID.Zero, UUID.Zero);
} }
/// <summary> /// <summary>
@ -69,6 +72,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.Tests
{ {
SetUp(); SetUp();
// Let's stick in a test presence
/*
PresenceData p = new PresenceData();
p.SessionID = UUID.Zero;
p.UserID = UUID.Zero.ToString();
p.Data = new Dictionary<string, string>();
p.Data["Online"] = true.ToString();
m_presenceData.Add(UUID.Zero, p);
*/
string user1 = UUID.Zero.ToString(); string user1 = UUID.Zero.ToString();
UUID session1 = UUID.Zero; UUID session1 = UUID.Zero;

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.Framework.Interfaces
{
public interface IAttachmentsModule
{
/// <summary>
/// Attach an object to an avatar.
/// </summary>
/// <param name="controllingClient"></param>
/// <param name="localID"></param>
/// <param name="attachPoint"></param>
/// <param name="rot"></param>
/// <param name="pos"></param>
/// <param name="silent"></param>
/// <returns>true if the object was successfully attached, false otherwise</returns>
bool AttachObject(
IClientAPI controllingClient, uint localID, uint attachPoint, Quaternion rot, Vector3 pos, bool silent);
/// <summary>
/// Update the user inventory to the attachment of an item
/// </summary>
/// <param name="att"></param>
/// <param name="remoteClient"></param>
/// <param name="itemID"></param>
/// <param name="AttachmentPt"></param>
/// <returns></returns>
UUID SetAttachmentInventoryStatus(
SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt);
/// <summary>
/// Update the user inventory to show a detach.
/// </summary>
/// <param name="itemID">
/// A <see cref="UUID"/>
/// </param>
/// <param name="remoteClient">
/// A <see cref="IClientAPI"/>
/// </param>
void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient);
}
}

View File

@ -110,12 +110,12 @@ namespace OpenSim.Region.Framework.Scenes
public event OnSetRootAgentSceneDelegate OnSetRootAgentScene; public event OnSetRootAgentSceneDelegate OnSetRootAgentScene;
/// <summary> /// <summary>
/// Called when an object is touched/grabbed. /// Fired when an object is touched/grabbed.
/// </summary> /// </summary>
/// The originalID is the local ID of the part that was actually touched. The localID itself is always that of /// The originalID is the local ID of the part that was actually touched. The localID itself is always that of
/// the root part. /// the root part.
public delegate void ObjectGrabDelegate(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs);
public event ObjectGrabDelegate OnObjectGrab; public event ObjectGrabDelegate OnObjectGrab;
public delegate void ObjectGrabDelegate(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs);
public event ObjectGrabDelegate OnObjectGrabbing; public event ObjectGrabDelegate OnObjectGrabbing;
public event ObjectDeGrabDelegate OnObjectDeGrab; public event ObjectDeGrabDelegate OnObjectDeGrab;
@ -123,8 +123,11 @@ namespace OpenSim.Region.Framework.Scenes
public event OnPermissionErrorDelegate OnPermissionError; public event OnPermissionErrorDelegate OnPermissionError;
public delegate void NewRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource); /// <summary>
/// Fired when a new script is created.
/// </summary>
public event NewRezScript OnRezScript; public event NewRezScript OnRezScript;
public delegate void NewRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource);
public delegate void RemoveScript(uint localID, UUID itemID); public delegate void RemoveScript(uint localID, UUID itemID);
public event RemoveScript OnRemoveScript; public event RemoveScript OnRemoveScript;
@ -168,36 +171,33 @@ namespace OpenSim.Region.Framework.Scenes
public event ClientClosed OnClientClosed; public event ClientClosed OnClientClosed;
/// <summary>
/// This is fired when a scene object property that a script might be interested in (such as color, scale or
/// inventory) changes. Only enough information is sent for the LSL changed event
/// (see http://lslwiki.net/lslwiki/wakka.php?wakka=changed)
/// </summary>
public event ScriptChangedEvent OnScriptChangedEvent;
public delegate void ScriptChangedEvent(uint localID, uint change); public delegate void ScriptChangedEvent(uint localID, uint change);
public event ScriptChangedEvent OnScriptChangedEvent;
public delegate void ScriptControlEvent(uint localID, UUID item, UUID avatarID, uint held, uint changed); public delegate void ScriptControlEvent(uint localID, UUID item, UUID avatarID, uint held, uint changed);
public event ScriptControlEvent OnScriptControlEvent; public event ScriptControlEvent OnScriptControlEvent;
public delegate void ScriptAtTargetEvent(uint localID, uint handle, Vector3 targetpos, Vector3 atpos); public delegate void ScriptAtTargetEvent(uint localID, uint handle, Vector3 targetpos, Vector3 atpos);
public event ScriptAtTargetEvent OnScriptAtTargetEvent; public event ScriptAtTargetEvent OnScriptAtTargetEvent;
public delegate void ScriptNotAtTargetEvent(uint localID); public delegate void ScriptNotAtTargetEvent(uint localID);
public event ScriptNotAtTargetEvent OnScriptNotAtTargetEvent; public event ScriptNotAtTargetEvent OnScriptNotAtTargetEvent;
public delegate void ScriptAtRotTargetEvent(uint localID, uint handle, Quaternion targetrot, Quaternion atrot); public delegate void ScriptAtRotTargetEvent(uint localID, uint handle, Quaternion targetrot, Quaternion atrot);
public event ScriptAtRotTargetEvent OnScriptAtRotTargetEvent; public event ScriptAtRotTargetEvent OnScriptAtRotTargetEvent;
public delegate void ScriptNotAtRotTargetEvent(uint localID); public delegate void ScriptNotAtRotTargetEvent(uint localID);
public event ScriptNotAtRotTargetEvent OnScriptNotAtRotTargetEvent; public event ScriptNotAtRotTargetEvent OnScriptNotAtRotTargetEvent;
public delegate void ScriptColliding(uint localID, ColliderArgs colliders); public delegate void ScriptColliding(uint localID, ColliderArgs colliders);
public event ScriptColliding OnScriptColliderStart; public event ScriptColliding OnScriptColliderStart;
public event ScriptColliding OnScriptColliding; public event ScriptColliding OnScriptColliding;
public event ScriptColliding OnScriptCollidingEnd; public event ScriptColliding OnScriptCollidingEnd;
public event ScriptColliding OnScriptLandColliderStart; public event ScriptColliding OnScriptLandColliderStart;
public event ScriptColliding OnScriptLandColliding; public event ScriptColliding OnScriptLandColliding;
public event ScriptColliding OnScriptLandColliderEnd; public event ScriptColliding OnScriptLandColliderEnd;

View File

@ -1862,39 +1862,11 @@ namespace OpenSim.Region.Framework.Scenes
if (att == null) if (att == null)
{ {
DetachSingleAttachmentToInv(itemID, remoteClient); AttachmentsModule.ShowDetachInUserInventory(itemID, remoteClient);
return UUID.Zero; return UUID.Zero;
} }
return RezSingleAttachment(att, remoteClient, itemID, AttachmentPt); return AttachmentsModule.SetAttachmentInventoryStatus(att, remoteClient, itemID, AttachmentPt);
}
/// <summary>
/// Update the user inventory to reflect an attachment
/// </summary>
/// <param name="att"></param>
/// <param name="remoteClient"></param>
/// <param name="itemID"></param>
/// <param name="AttachmentPt"></param>
/// <returns></returns>
public UUID RezSingleAttachment(SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
{
m_log.DebugFormat(
"[USER INVENTORY]: Updating inventory of {0} to show attachment of {1} (item ID {2})",
remoteClient.Name, att.Name, itemID);
if (!att.IsDeleted)
AttachmentPt = att.RootPart.AttachmentPoint;
ScenePresence presence;
if (TryGetAvatar(remoteClient.AgentId, out presence))
{
InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
item = InventoryService.GetItem(item);
presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/);
}
return att.UUID;
} }
public void RezMultipleAttachments(IClientAPI remoteClient, RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header, public void RezMultipleAttachments(IClientAPI remoteClient, RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header,
@ -1906,65 +1878,6 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
/// <summary>
/// Attach an object.
/// </summary>
/// <param name="controllingClient"></param>
/// <param name="localID"></param>
/// <param name="attachPoint"></param>
/// <param name="rot"></param>
/// <param name="pos"></param>
/// <param name="silent"></param>
/// <returns>true if the object was successfully attached, false otherwise</returns>
public bool AttachObject(IClientAPI controllingClient, uint localID, uint attachPoint, Quaternion rot, Vector3 pos, bool silent)
{
return m_sceneGraph.AttachObject(controllingClient, localID, attachPoint, rot, pos, silent);
}
/// <summary>
/// This registers the item as attached in a user's inventory
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="AttachmentPt"></param>
/// <param name="itemID"></param>
/// <param name="att"></param>
public void AttachObject(IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
{
// m_log.DebugFormat(
// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
// att.Name, remoteClient.Name, AttachmentPt, itemID);
if (UUID.Zero == itemID)
{
m_log.Error("[SCENE INVENTORY]: Unable to save attachment. Error inventory item ID.");
return;
}
if (0 == AttachmentPt)
{
m_log.Error("[SCENE INVENTORY]: Unable to save attachment. Error attachment point.");
return;
}
if (null == att.RootPart)
{
m_log.Error("[SCENE INVENTORY]: Unable to save attachment for a prim without the rootpart!");
return;
}
ScenePresence presence;
if (TryGetAvatar(remoteClient.AgentId, out presence))
{
// XXYY!!
InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
item = InventoryService.GetItem(item);
presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /* att.UUID */);
if (m_AvatarFactory != null)
m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
}
}
public void DetachSingleAttachmentToGround(UUID itemID, IClientAPI remoteClient) public void DetachSingleAttachmentToGround(UUID itemID, IClientAPI remoteClient)
{ {
SceneObjectPart part = GetSceneObjectPart(itemID); SceneObjectPart part = GetSceneObjectPart(itemID);
@ -1995,24 +1908,6 @@ namespace OpenSim.Region.Framework.Scenes
SendAttachEvent(part.ParentGroup.LocalId, itemID, UUID.Zero); SendAttachEvent(part.ParentGroup.LocalId, itemID, UUID.Zero);
} }
public void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient)
{
ScenePresence presence;
if (TryGetAvatar(remoteClient.AgentId, out presence))
{
presence.Appearance.DetachAttachment(itemID);
// Save avatar attachment information
if (m_AvatarFactory != null)
{
m_log.Info("[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + ", ItemID: " + itemID);
m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
}
}
m_sceneGraph.DetachSingleAttachmentToInv(itemID, remoteClient);
}
public void GetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID) public void GetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID)
{ {
EventManager.TriggerGetScriptRunning(controllingClient, objectID, itemID); EventManager.TriggerGetScriptRunning(controllingClient, objectID, itemID);

View File

@ -307,6 +307,7 @@ namespace OpenSim.Region.Framework.Scenes
protected IXMLRPC m_xmlrpcModule; protected IXMLRPC m_xmlrpcModule;
protected IWorldComm m_worldCommModule; protected IWorldComm m_worldCommModule;
public IAttachmentsModule AttachmentsModule { get; set; }
protected IAvatarFactory m_AvatarFactory; protected IAvatarFactory m_AvatarFactory;
public IAvatarFactory AvatarFactory public IAvatarFactory AvatarFactory
{ {
@ -1145,12 +1146,9 @@ namespace OpenSim.Region.Framework.Scenes
} }
public int GetInaccurateNeighborCount() public int GetInaccurateNeighborCount()
{
lock (m_neighbours)
{ {
return m_neighbours.Count; return m_neighbours.Count;
} }
}
// This is the method that shuts down the scene. // This is the method that shuts down the scene.
public override void Close() public override void Close()
@ -1229,6 +1227,7 @@ namespace OpenSim.Region.Framework.Scenes
m_worldCommModule = RequestModuleInterface<IWorldComm>(); m_worldCommModule = RequestModuleInterface<IWorldComm>();
XferManager = RequestModuleInterface<IXfer>(); XferManager = RequestModuleInterface<IXfer>();
m_AvatarFactory = RequestModuleInterface<IAvatarFactory>(); m_AvatarFactory = RequestModuleInterface<IAvatarFactory>();
AttachmentsModule = RequestModuleInterface<IAttachmentsModule>();
m_serialiser = RequestModuleInterface<IRegionSerialiserModule>(); m_serialiser = RequestModuleInterface<IRegionSerialiserModule>();
m_dialogModule = RequestModuleInterface<IDialogModule>(); m_dialogModule = RequestModuleInterface<IDialogModule>();
m_capsModule = RequestModuleInterface<ICapabilitiesModule>(); m_capsModule = RequestModuleInterface<ICapabilitiesModule>();
@ -2433,8 +2432,10 @@ namespace OpenSim.Region.Framework.Scenes
m_log.DebugFormat( m_log.DebugFormat(
"[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition);
AttachObject( if (AttachmentsModule != null)
AttachmentsModule.AttachObject(
sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition, false); sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition, false);
RootPrim.RemFlag(PrimFlags.TemporaryOnRez); RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
grp.SendGroupFullUpdate(); grp.SendGroupFullUpdate();
} }
@ -2670,9 +2671,11 @@ namespace OpenSim.Region.Framework.Scenes
{ {
client.OnRezSingleAttachmentFromInv += RezSingleAttachment; client.OnRezSingleAttachmentFromInv += RezSingleAttachment;
client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachments; client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachments;
client.OnDetachAttachmentIntoInv += DetachSingleAttachmentToInv;
client.OnObjectAttach += m_sceneGraph.AttachObject; client.OnObjectAttach += m_sceneGraph.AttachObject;
client.OnObjectDetach += m_sceneGraph.DetachObject; client.OnObjectDetach += m_sceneGraph.DetachObject;
if (AttachmentsModule != null)
client.OnDetachAttachmentIntoInv += AttachmentsModule.ShowDetachInUserInventory;
} }
public virtual void SubscribeToClientTeleportEvents(IClientAPI client) public virtual void SubscribeToClientTeleportEvents(IClientAPI client)
@ -2720,7 +2723,6 @@ namespace OpenSim.Region.Framework.Scenes
protected virtual void UnsubscribeToClientEvents(IClientAPI client) protected virtual void UnsubscribeToClientEvents(IClientAPI client)
{ {
} }
/// <summary> /// <summary>
@ -2742,7 +2744,6 @@ namespace OpenSim.Region.Framework.Scenes
UnSubscribeToClientNetworkEvents(client); UnSubscribeToClientNetworkEvents(client);
// EventManager.TriggerOnNewClient(client); // EventManager.TriggerOnNewClient(client);
} }
@ -2823,11 +2824,13 @@ namespace OpenSim.Region.Framework.Scenes
public virtual void UnSubscribeToClientAttachmentEvents(IClientAPI client) public virtual void UnSubscribeToClientAttachmentEvents(IClientAPI client)
{ {
client.OnRezSingleAttachmentFromInv -= RezSingleAttachment;
client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachments; client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachments;
client.OnDetachAttachmentIntoInv -= DetachSingleAttachmentToInv; client.OnRezSingleAttachmentFromInv -= RezSingleAttachment;
client.OnObjectAttach -= m_sceneGraph.AttachObject; client.OnObjectAttach -= m_sceneGraph.AttachObject;
client.OnObjectDetach -= m_sceneGraph.DetachObject; client.OnObjectDetach -= m_sceneGraph.DetachObject;
if (AttachmentsModule != null)
client.OnDetachAttachmentIntoInv -= AttachmentsModule.ShowDetachInUserInventory;
} }
public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client) public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client)

View File

@ -476,7 +476,7 @@ namespace OpenSim.Region.Framework.Scenes
if (group != null) if (group != null)
{ {
//group.DetachToGround(); //group.DetachToGround();
m_parentScene.DetachSingleAttachmentToInv(group.GetFromItemID(), remoteClient); m_parentScene.AttachmentsModule.ShowDetachInUserInventory(group.GetFromItemID(), remoteClient);
} }
} }
@ -528,7 +528,7 @@ namespace OpenSim.Region.Framework.Scenes
return; return;
// Calls attach with a Zero position // Calls attach with a Zero position
if (AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false)) if (m_parentScene.AttachmentsModule.AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false))
{ {
m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
@ -571,8 +571,10 @@ namespace OpenSim.Region.Framework.Scenes
if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint())
tainted = true; tainted = true;
AttachObject(remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false); m_parentScene.AttachmentsModule.AttachObject(
remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false);
//objatt.ScheduleGroupForFullUpdate(); //objatt.ScheduleGroupForFullUpdate();
if (tainted) if (tainted)
objatt.HasGroupChanged = true; objatt.HasGroupChanged = true;
@ -596,131 +598,6 @@ namespace OpenSim.Region.Framework.Scenes
return null; return null;
} }
// What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards.
// To LocalId or UUID, *THAT* is the question. How now Brown UUID??
public void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient)
{
if (itemID == UUID.Zero) // If this happened, someone made a mistake....
return;
// We can NOT use the dictionries here, as we are looking
// for an entity by the fromAssetID, which is NOT the prim UUID
//
List<EntityBase> detachEntities = GetEntities();
SceneObjectGroup group;
foreach (EntityBase entity in detachEntities)
{
if (entity is SceneObjectGroup)
{
group = (SceneObjectGroup)entity;
if (group.GetFromItemID() == itemID)
{
m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero);
bool hasScripts = false;
foreach (SceneObjectPart part in group.Children.Values)
{
if (part.Inventory.ContainsScripts())
{
hasScripts = true;
break;
}
}
if (hasScripts) // Allow the object to execute the attach(NULL_KEY) event
System.Threading.Thread.Sleep(100);
group.DetachToInventoryPrep();
m_log.Debug("[DETACH]: Saving attachpoint: " +
((uint)group.GetAttachmentPoint()).ToString());
m_parentScene.UpdateKnownItem(remoteClient, group,
group.GetFromItemID(), group.OwnerID);
m_parentScene.DeleteSceneObject(group, false);
return;
}
}
}
}
/// <summary>
/// Attach a scene object to an avatar.
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="objectLocalID"></param>
/// <param name="AttachmentPt"></param>
/// <param name="rot"></param>
/// <param name="attachPos"></param>
/// <param name="silent"></param>
/// <returns>true if the attachment was successful, false otherwise</returns>
protected internal bool AttachObject(
IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent)
{
SceneObjectGroup group = GetGroupByPrim(objectLocalID);
if (group != null)
{
if (m_parentScene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId))
{
// If the attachment point isn't the same as the one previously used
// set it's offset position = 0 so that it appears on the attachment point
// and not in a weird location somewhere unknown.
if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint())
{
attachPos = Vector3.Zero;
}
// AttachmentPt 0 means the client chose to 'wear' the attachment.
if (AttachmentPt == 0)
{
// Check object for stored attachment point
AttachmentPt = (uint)group.GetAttachmentPoint();
}
// if we still didn't find a suitable attachment point.......
if (AttachmentPt == 0)
{
// Stick it on left hand with Zero Offset from the attachment point.
AttachmentPt = (uint)AttachmentPoint.LeftHand;
attachPos = Vector3.Zero;
}
group.SetAttachmentPoint((byte)AttachmentPt);
group.AbsolutePosition = attachPos;
// Saves and gets itemID
UUID itemId;
if (group.GetFromItemID() == UUID.Zero)
{
m_parentScene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemId);
}
else
{
itemId = group.GetFromItemID();
}
m_parentScene.AttachObject(remoteClient, AttachmentPt, itemId, group);
group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent);
// In case it is later dropped again, don't let
// it get cleaned up
//
group.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
group.HasGroupChanged = false;
}
else
{
remoteClient.SendAgentAlertMessage("You don't have sufficient permissions to attach this object", false);
return false;
}
}
else
{
m_log.DebugFormat("[SCENE GRAPH]: AttachObject found no such scene object {0}", objectLocalID);
return false;
}
return true;
}
protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance) protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance)
{ {
ScenePresence newAvatar = null; ScenePresence newAvatar = null;

View File

@ -4732,5 +4732,10 @@ namespace OpenSim.Region.Framework.Scenes
m_log.Error("[Physics] " + ex); m_log.Error("[Physics] " + ex);
} }
} }
public Color4 GetTextColor()
{
return new Color4((byte)Color.R, (byte)Color.G, (byte)Color.B, (byte)(0xFF - Color.A));
}
} }
} }

View File

@ -641,7 +641,6 @@ namespace OpenSim.Region.Framework.Scenes
m_items[item.ItemID] = item; m_items[item.ItemID] = item;
m_inventorySerial++; m_inventorySerial++;
m_part.TriggerScriptChangedEvent(Changed.INVENTORY); m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
HasInventoryChanged = true; HasInventoryChanged = true;
m_part.ParentGroup.HasGroupChanged = true; m_part.ParentGroup.HasGroupChanged = true;
m_items.LockItemsForWrite(false); m_items.LockItemsForWrite(false);

View File

@ -2872,6 +2872,9 @@ namespace OpenSim.Region.Framework.Scenes
if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance || if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance ||
Util.GetDistanceTo(CameraPosition, m_lastChildAgentUpdateCamPosition) >= Scene.ChildReprioritizationDistance) Util.GetDistanceTo(CameraPosition, m_lastChildAgentUpdateCamPosition) >= Scene.ChildReprioritizationDistance)
{ {
m_lastChildAgentUpdatePosition = AbsolutePosition;
m_lastChildAgentUpdateCamPosition = CameraPosition;
ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); ChildAgentDataUpdate cadu = new ChildAgentDataUpdate();
cadu.ActiveGroupID = UUID.Zero.Guid; cadu.ActiveGroupID = UUID.Zero.Guid;
cadu.AgentID = UUID.Guid; cadu.AgentID = UUID.Guid;
@ -2880,8 +2883,6 @@ namespace OpenSim.Region.Framework.Scenes
Vector3 tempCameraCenter = m_CameraCenter; Vector3 tempCameraCenter = m_CameraCenter;
cadu.cameraPosition = tempCameraCenter; cadu.cameraPosition = tempCameraCenter;
cadu.drawdistance = m_DrawDistance; cadu.drawdistance = m_DrawDistance;
if (m_scene.Permissions.IsGod(new UUID(cadu.AgentID)))
cadu.godlevel = m_godlevel;
cadu.GroupAccess = 0; cadu.GroupAccess = 0;
cadu.Position = AbsolutePosition; cadu.Position = AbsolutePosition;
cadu.regionHandle = m_rootRegionHandle; cadu.regionHandle = m_rootRegionHandle;
@ -2904,9 +2905,6 @@ namespace OpenSim.Region.Framework.Scenes
agentpos.CopyFrom(cadu); agentpos.CopyFrom(cadu);
m_scene.SendOutChildAgentUpdates(agentpos, this); m_scene.SendOutChildAgentUpdates(agentpos, this);
m_lastChildAgentUpdatePosition = AbsolutePosition;
m_lastChildAgentUpdateCamPosition = CameraPosition;
} }
} }

View File

@ -53,7 +53,6 @@ using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
using OpenSim.Region.ScriptEngine.Interfaces; using OpenSim.Region.ScriptEngine.Interfaces;
using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using OpenSim.Services.Interfaces;
using GridRegion = OpenSim.Services.Interfaces.GridRegion; using GridRegion = OpenSim.Services.Interfaces.GridRegion;
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
using PrimType = OpenSim.Region.Framework.Scenes.PrimType; using PrimType = OpenSim.Region.Framework.Scenes.PrimType;
@ -3066,9 +3065,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
ScenePresence presence = World.GetScenePresence(m_host.OwnerID); ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
m_ScriptEngine.World.AttachObject(presence.ControllingClient, IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
grp.LocalId, (uint)attachment, Quaternion.Identity, if (attachmentsModule != null)
Vector3.Zero, false); attachmentsModule.AttachObject(
presence.ControllingClient, grp.LocalId,
(uint)attachment, Quaternion.Identity, Vector3.Zero, false);
} }
} }
@ -3105,8 +3106,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
ScenePresence presence = World.GetScenePresence(m_host.OwnerID); ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
m_ScriptEngine.World.DetachSingleAttachmentToInv(itemID, IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
presence.ControllingClient); if (attachmentsModule != null)
attachmentsModule.ShowDetachInUserInventory(itemID, presence.ControllingClient);
} }
} }
@ -5598,6 +5600,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public void llSetTextureAnim(int mode, int face, int sizex, int sizey, double start, double length, double rate) public void llSetTextureAnim(int mode, int face, int sizex, int sizey, double start, double length, double rate)
{ {
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
SetTextureAnim(m_host, mode, face, sizex, sizey, start, length, rate);
}
public void llSetLinkTextureAnim(int linknumber, int mode, int face, int sizex, int sizey, double start, double length, double rate)
{
m_host.AddScriptLPS(1);
List<SceneObjectPart> parts = GetLinkParts(linknumber);
foreach (var part in parts)
{
SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
}
}
private void SetTextureAnim(SceneObjectPart part, int mode, int face, int sizex, int sizey, double start, double length, double rate)
{
Primitive.TextureAnimation pTexAnim = new Primitive.TextureAnimation(); Primitive.TextureAnimation pTexAnim = new Primitive.TextureAnimation();
pTexAnim.Flags = (Primitive.TextureAnimMode)mode; pTexAnim.Flags = (Primitive.TextureAnimMode)mode;
@ -5612,9 +5633,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
pTexAnim.SizeY = (uint)sizey; pTexAnim.SizeY = (uint)sizey;
pTexAnim.Start = (float)start; pTexAnim.Start = (float)start;
m_host.AddTextureAnimation(pTexAnim); part.AddTextureAnimation(pTexAnim);
m_host.SendFullUpdateToAllClients(); part.SendFullUpdateToAllClients();
m_host.ParentGroup.HasGroupChanged = true; part.ParentGroup.HasGroupChanged = true;
} }
public void llTriggerSoundLimited(string sound, double volume, LSL_Vector top_north_east, public void llTriggerSoundLimited(string sound, double volume, LSL_Vector top_north_east,
@ -6011,13 +6032,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return ps; return ps;
} }
public void llLinkParticleSystem(int linknumber, LSL_List rules)
{
m_host.AddScriptLPS(1);
List<SceneObjectPart> parts = GetLinkParts(linknumber);
foreach (var part in parts)
{
SetParticleSystem(part, rules);
}
}
public void llParticleSystem(LSL_List rules) public void llParticleSystem(LSL_List rules)
{ {
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
SetParticleSystem(m_host, rules);
}
private void SetParticleSystem(SceneObjectPart part, LSL_List rules) {
if (rules.Length == 0) if (rules.Length == 0)
{ {
m_host.RemoveParticleSystem(); part.RemoveParticleSystem();
m_host.ParentGroup.HasGroupChanged = true; part.ParentGroup.HasGroupChanged = true;
} }
else else
{ {
@ -6128,7 +6167,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
} }
else else
{ {
prules.Target = m_host.UUID; prules.Target = part.UUID;
} }
break; break;
@ -6154,10 +6193,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
} }
prules.CRC = 1; prules.CRC = 1;
m_host.AddNewParticleSystem(prules); part.AddNewParticleSystem(prules);
m_host.ParentGroup.HasGroupChanged = true; part.ParentGroup.HasGroupChanged = true;
} }
m_host.SendFullUpdateToAllClients(); part.SendFullUpdateToAllClients();
} }
public void llGroundRepel(double height, int water, double tau) public void llGroundRepel(double height, int water, double tau)
@ -6966,6 +7005,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
SetPrimParams(part, rules); SetPrimParams(part, rules);
} }
public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
{
llSetLinkPrimitiveParams(linknumber, rules);
}
protected void SetPrimParams(SceneObjectPart part, LSL_List rules) protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
{ {
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
@ -7324,6 +7368,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
face = rules.GetLSLIntegerItem(idx++); face = rules.GetLSLIntegerItem(idx++);
int style = rules.GetLSLIntegerItem(idx++); int style = rules.GetLSLIntegerItem(idx++);
SetTexGen(part, face, style); SetTexGen(part, face, style);
break;
case (int)ScriptBaseClass.PRIM_TEXT:
if (remain < 3)
return;
string primText = rules.GetLSLStringItem(idx++);
LSL_Vector primTextColor = rules.GetVector3Item(idx++);
LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++);
Vector3 av3 = new Vector3(Util.Clip((float)primTextColor.x, 0.0f, 1.0f),
Util.Clip((float)primTextColor.y, 0.0f, 1.0f),
Util.Clip((float)primTextColor.z, 0.0f, 1.0f));
part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f));
break; break;
} }
} }
@ -7568,6 +7624,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return GetLinkPrimitiveParams(m_host, rules); return GetLinkPrimitiveParams(m_host, rules);
} }
public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
{
m_host.AddScriptLPS(1);
List<SceneObjectPart> parts = GetLinkParts(linknumber);
LSL_List res = new LSL_List();
foreach (var part in parts)
{
LSL_List partRes = GetLinkPrimitiveParams(part, rules);
res += partRes;
}
return res;
}
public LSL_List GetLinkPrimitiveParams(SceneObjectPart part, LSL_List rules) public LSL_List GetLinkPrimitiveParams(SceneObjectPart part, LSL_List rules)
{ {
LSL_List res = new LSL_List(); LSL_List res = new LSL_List();
@ -7951,6 +8024,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
res.Add(new LSL_Float(primglow)); res.Add(new LSL_Float(primglow));
} }
break; break;
case (int)ScriptBaseClass.PRIM_TEXT:
Color4 textColor = part.GetTextColor();
res.Add(part.Text);
res.Add(new LSL_Vector(textColor.R,
textColor.G,
textColor.B));
res.Add(new LSL_Float(textColor.A));
break;
} }
} }
return res; return res;
@ -10050,90 +10131,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
Notecard nc = new Notecard(); Notecard nc = new Notecard();
nc.lastRef = DateTime.Now; nc.lastRef = DateTime.Now;
nc.text = ParseText(text.Replace("\r", "").Split('\n')); nc.text = SLUtil.ParseNotecardToList(text).ToArray();
m_Notecards[assetID] = nc; m_Notecards[assetID] = nc;
} }
} }
protected static string[] ParseText(string[] input)
{
int idx = 0;
int level = 0;
List<string> output = new List<string>();
string[] words;
while (idx < input.Length)
{
if (input[idx] == "{")
{
level++;
idx++;
continue;
}
if (input[idx]== "}")
{
level--;
idx++;
continue;
}
switch (level)
{
case 0:
words = input[idx].Split(' '); // Linden text ver
// Notecards are created *really* empty. Treat that as "no text" (just like after saving an empty notecard)
if (words.Length < 3)
return new String[0];
int version = int.Parse(words[3]);
if (version != 2)
return new String[0];
break;
case 1:
words = input[idx].Split(' ');
if (words[0] == "LLEmbeddedItems")
break;
if (words[0] == "Text")
{
int len = int.Parse(words[2]);
idx++;
int count = -1;
while (count < len)
{
// int l = input[idx].Length;
string ln = input[idx];
int need = len-count-1;
if (ln.Length > need)
ln = ln.Substring(0, need);
output.Add(ln);
count += ln.Length + 1;
idx++;
}
return output.ToArray();
}
break;
case 2:
words = input[idx].Split(' '); // count
if (words[0] == "count")
{
int c = int.Parse(words[1]);
if (c > 0)
return new String[0];
break;
}
break;
}
idx++;
}
return output.ToArray();
}
public static bool IsCached(UUID assetID) public static bool IsCached(UUID assetID)
{ {
lock (m_Notecards) lock (m_Notecards)

View File

@ -135,6 +135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
LSL_Key llGetLinkKey(int linknum); LSL_Key llGetLinkKey(int linknum);
LSL_String llGetLinkName(int linknum); LSL_String llGetLinkName(int linknum);
LSL_Integer llGetLinkNumber(); LSL_Integer llGetLinkNumber();
LSL_List llGetLinkPrimitiveParams(int linknum, LSL_List rules);
LSL_Integer llGetListEntryType(LSL_List src, int index); LSL_Integer llGetListEntryType(LSL_List src, int index);
LSL_Integer llGetListLength(LSL_List src); LSL_Integer llGetListLength(LSL_List src);
LSL_Vector llGetLocalPos(); LSL_Vector llGetLocalPos();
@ -206,6 +207,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
void llInstantMessage(string user, string message); void llInstantMessage(string user, string message);
LSL_String llIntegerToBase64(int number); LSL_String llIntegerToBase64(int number);
LSL_String llKey2Name(string id); LSL_String llKey2Name(string id);
void llLinkParticleSystem(int linknum, LSL_List rules);
LSL_String llList2CSV(LSL_List src); LSL_String llList2CSV(LSL_List src);
LSL_Float llList2Float(LSL_List src, int index); LSL_Float llList2Float(LSL_List src, int index);
LSL_Integer llList2Integer(LSL_List src, int index); LSL_Integer llList2Integer(LSL_List src, int index);
@ -322,6 +324,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
void llSetLinkColor(int linknumber, LSL_Vector color, int face); void llSetLinkColor(int linknumber, LSL_Vector color, int face);
void llSetLinkPrimitiveParams(int linknumber, LSL_List rules); void llSetLinkPrimitiveParams(int linknumber, LSL_List rules);
void llSetLinkTexture(int linknumber, string texture, int face); void llSetLinkTexture(int linknumber, string texture, int face);
void llSetLinkTextureAnim(int linknum, int mode, int face, int sizex, int sizey, double start, double length, double rate);
void llSetLocalRot(LSL_Rotation rot); void llSetLocalRot(LSL_Rotation rot);
void llSetObjectDesc(string desc); void llSetObjectDesc(string desc);
void llSetObjectName(string name); void llSetObjectName(string name);
@ -330,6 +333,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
void llSetPayPrice(int price, LSL_List quick_pay_buttons); void llSetPayPrice(int price, LSL_List quick_pay_buttons);
void llSetPos(LSL_Vector pos); void llSetPos(LSL_Vector pos);
void llSetPrimitiveParams(LSL_List rules); void llSetPrimitiveParams(LSL_List rules);
void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
void llSetPrimURL(string url); void llSetPrimURL(string url);
void llSetRemoteScriptAccessPin(int pin); void llSetRemoteScriptAccessPin(int pin);
void llSetRot(LSL_Rotation rot); void llSetRot(LSL_Rotation rot);

View File

@ -313,6 +313,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int PRIM_CAST_SHADOWS = 24; // Not implemented, here for completeness sake public const int PRIM_CAST_SHADOWS = 24; // Not implemented, here for completeness sake
public const int PRIM_POINT_LIGHT = 23; // Huh? public const int PRIM_POINT_LIGHT = 23; // Huh?
public const int PRIM_GLOW = 25; public const int PRIM_GLOW = 25;
public const int PRIM_TEXT = 26;
public const int PRIM_TEXGEN_DEFAULT = 0; public const int PRIM_TEXGEN_DEFAULT = 0;
public const int PRIM_TEXGEN_PLANAR = 1; public const int PRIM_TEXGEN_PLANAR = 1;

View File

@ -674,6 +674,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
return m_LSL_Functions.llGetPrimitiveParams(rules); return m_LSL_Functions.llGetPrimitiveParams(rules);
} }
public LSL_List llGetLinkPrimitiveParams(int linknum, LSL_List rules)
{
return m_LSL_Functions.llGetLinkPrimitiveParams(linknum, rules);
}
public LSL_Integer llGetRegionAgentCount() public LSL_Integer llGetRegionAgentCount()
{ {
return m_LSL_Functions.llGetRegionAgentCount(); return m_LSL_Functions.llGetRegionAgentCount();
@ -889,6 +894,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
return m_LSL_Functions.llKey2Name(id); return m_LSL_Functions.llKey2Name(id);
} }
public void llLinkParticleSystem(int linknum, LSL_List rules)
{
m_LSL_Functions.llLinkParticleSystem(linknum, rules);
}
public LSL_String llList2CSV(LSL_List src) public LSL_String llList2CSV(LSL_List src)
{ {
return m_LSL_Functions.llList2CSV(src); return m_LSL_Functions.llList2CSV(src);
@ -1468,6 +1478,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
m_LSL_Functions.llSetLinkTexture(linknumber, texture, face); m_LSL_Functions.llSetLinkTexture(linknumber, texture, face);
} }
public void llSetLinkTextureAnim(int linknum, int mode, int face, int sizex, int sizey, double start, double length, double rate)
{
m_LSL_Functions.llSetLinkTextureAnim(linknum, mode, face, sizex, sizey, start, length, rate);
}
public void llSetLocalRot(LSL_Rotation rot) public void llSetLocalRot(LSL_Rotation rot)
{ {
m_LSL_Functions.llSetLocalRot(rot); m_LSL_Functions.llSetLocalRot(rot);
@ -1508,6 +1523,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
m_LSL_Functions.llSetPrimitiveParams(rules); m_LSL_Functions.llSetPrimitiveParams(rules);
} }
public void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules)
{
m_LSL_Functions.llSetLinkPrimitiveParamsFast(linknum, rules);
}
public void llSetPrimURL(string url) public void llSetPrimURL(string url)
{ {
m_LSL_Functions.llSetPrimURL(url); m_LSL_Functions.llSetPrimURL(url);

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
namespace OpenSim.Services.Connectors
{
public class GridUserServiceConnector
{
public GridUserServiceConnector()
{
}
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using OpenMetaverse;
namespace OpenSim.Services.Interfaces
{
/// <summary>
/// Records user information specific to a grid but which is not part of a user's account.
/// </summary>
public class GridUserInfo
{
public string UserID;
public UUID HomeRegionID;
public Vector3 HomePosition;
public Vector3 HomeLookAt;
public GridUserInfo() {}
public GridUserInfo(Dictionary<string, object> kvp)
{
if (kvp.ContainsKey("UserID"))
UserID = kvp["UserID"].ToString();
if (kvp.ContainsKey("HomeRegionID"))
UUID.TryParse(kvp["HomeRegionID"].ToString(), out HomeRegionID);
if (kvp.ContainsKey("HomePosition"))
Vector3.TryParse(kvp["HomePosition"].ToString(), out HomePosition);
if (kvp.ContainsKey("HomeLookAt"))
Vector3.TryParse(kvp["HomeLookAt"].ToString(), out HomeLookAt);
}
public Dictionary<string, object> ToKeyValuePairs()
{
Dictionary<string, object> result = new Dictionary<string, object>();
result["UserID"] = UserID;
result["HomeRegionID"] = HomeRegionID.ToString();
result["HomePosition"] = HomePosition.ToString();
result["HomeLookAt"] = HomeLookAt.ToString();
return result;
}
}
public interface IGridUserService
{
GridUserInfo GetGridUserInfo(string userID);
bool StoreGridUserInfo(GridUserInfo info);
}
}

View File

@ -279,7 +279,31 @@ namespace OpenSim.Services.LLLoginService
GridRegion region = null; GridRegion region = null;
if (pinfo.HomeRegionID.Equals(UUID.Zero) || (region = m_GridService.GetRegionByUUID(account.ScopeID, pinfo.HomeRegionID)) == null) bool tryDefaults = false;
if (pinfo.HomeRegionID.Equals(UUID.Zero))
{
m_log.WarnFormat(
"[LLOGIN SERVICE]: User {0} {1} tried to login to a 'home' start location but they have none set",
account.FirstName, account.LastName);
tryDefaults = true;
}
else
{
region = m_GridService.GetRegionByUUID(account.ScopeID, pinfo.HomeRegionID);
if (null == region)
{
m_log.WarnFormat(
"[LLOGIN SERVICE]: User {0} {1} has a recorded home region of {2} but this cannot be found by the grid service",
account.FirstName, account.LastName, pinfo.HomeRegionID);
tryDefaults = true;
}
}
if (tryDefaults)
{ {
List<GridRegion> defaults = m_GridService.GetDefaultRegions(account.ScopeID); List<GridRegion> defaults = m_GridService.GetDefaultRegions(account.ScopeID);
if (defaults != null && defaults.Count > 0) if (defaults != null && defaults.Count > 0)
@ -288,7 +312,8 @@ namespace OpenSim.Services.LLLoginService
where = "safe"; where = "safe";
} }
else else
m_log.WarnFormat("[LLOGIN SERVICE]: User {0} {1} does not have a home set and this grid does not have default locations.", m_log.WarnFormat(
"[LLOGIN SERVICE]: User {0} {1} does not have a valid home and this grid does not have default locations.",
account.FirstName, account.LastName); account.FirstName, account.LastName);
} }
@ -318,8 +343,8 @@ namespace OpenSim.Services.LLLoginService
position = pinfo.Position; position = pinfo.Position;
lookAt = pinfo.LookAt; lookAt = pinfo.LookAt;
} }
return region;
return region;
} }
else else
{ {

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using Nini.Config;
using OpenSim.Data;
using OpenSim.Services.Interfaces;
using OpenSim.Framework.Console;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
using OpenMetaverse;
using log4net;
namespace OpenSim.Services.UserAccountService
{
public class GridUserService : GridUserServiceBase, IGridUserService
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public GridUserService(IConfigSource config) : base(config)
{
m_log.Debug("[USER GRID SERVICE]: Starting user grid service");
}
public GridUserInfo GetGridUserInfo(string userID)
{
GridUserData d = m_Database.GetGridUserData(userID);
GridUserInfo info = new GridUserInfo();
info.UserID = d.UserID;
info.HomeRegionID = new UUID(d.Data["HomeRegionID"]);
info.HomePosition = Vector3.Parse(d.Data["HomePosition"]);
info.HomeLookAt = Vector3.Parse(d.Data["HomeLookAt"]);
return info;
}
public bool StoreGridUserInfo(GridUserInfo info)
{
GridUserData d = new GridUserData();
d.Data["UserID"] = info.UserID;
d.Data["HomeRegionID"] = info.HomeRegionID.ToString();
d.Data["HomePosition"] = info.HomePosition.ToString();
d.Data["HomeLookAt"] = info.HomeLookAt.ToString();
return m_Database.StoreGridUserData(d);
}
}
}

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Reflection;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Data;
using OpenSim.Services.Interfaces;
using OpenSim.Services.Base;
namespace OpenSim.Services.UserAccountService
{
public class GridUserServiceBase : ServiceBase
{
protected IGridUserData m_Database = null;
public GridUserServiceBase(IConfigSource config) : base(config)
{
string dllName = String.Empty;
string connString = String.Empty;
string realm = "GridUser";
//
// Try reading the [DatabaseService] section, if it exists
//
IConfig dbConfig = config.Configs["DatabaseService"];
if (dbConfig != null)
{
if (dllName == String.Empty)
dllName = dbConfig.GetString("StorageProvider", String.Empty);
if (connString == String.Empty)
connString = dbConfig.GetString("ConnectionString", String.Empty);
}
//
// [GridUsetService] section overrides [DatabaseService], if it exists
//
IConfig presenceConfig = config.Configs["GridUserService"];
if (presenceConfig != null)
{
dllName = presenceConfig.GetString("StorageProvider", dllName);
connString = presenceConfig.GetString("ConnectionString", connString);
realm = presenceConfig.GetString("Realm", realm);
}
//
// We tried, but this doesn't exist. We can't proceed.
//
if (dllName.Equals(String.Empty))
throw new Exception("No StorageProvider configured");
m_Database = LoadPlugin<IGridUserData>(dllName, new Object[] { connString, realm });
if (m_Database == null)
throw new Exception("Could not find a storage interface in the given module " + dllName);
}
}
}

View File

@ -280,7 +280,7 @@ namespace OpenSim.Services.UserAccountService
if (null == account) if (null == account)
{ {
account = new UserAccount(UUID.Zero, firstName, lastName, email); account = new UserAccount(UUID.Zero, firstName, lastName, email);
if (account.ServiceURLs == null) if (account.ServiceURLs == null || (account.ServiceURLs != null && account.ServiceURLs.Count == 0))
{ {
account.ServiceURLs = new Dictionary<string, object>(); account.ServiceURLs = new Dictionary<string, object>();
account.ServiceURLs["HomeURI"] = string.Empty; account.ServiceURLs["HomeURI"] = string.Empty;

Binary file not shown.

BIN
bin/BclExtras35.dll Normal file

Binary file not shown.

View File

@ -158,7 +158,7 @@
<Reference name="System.Data"/> <Reference name="System.Data"/>
<Reference name="System.Drawing"/> <Reference name="System.Drawing"/>
<Reference name="System.Web"/> <Reference name="System.Web"/>
<Reference name="BclExtras.dll"/> <Reference name="BclExtras35.dll"/>
<Reference name="OpenMetaverseTypes.dll"/> <Reference name="OpenMetaverseTypes.dll"/>
<Reference name="OpenMetaverse.dll"/> <Reference name="OpenMetaverse.dll"/>
<Reference name="OpenMetaverse.StructuredData.dll"/> <Reference name="OpenMetaverse.StructuredData.dll"/>
@ -1635,7 +1635,7 @@
<Reference name="OpenSim.Region.ClientStack"/> <Reference name="OpenSim.Region.ClientStack"/>
<Reference name="OpenSim.Region.Physics.Manager"/> <Reference name="OpenSim.Region.Physics.Manager"/>
<Reference name="OpenSim.Services.Interfaces"/> <Reference name="OpenSim.Services.Interfaces"/>
<Reference name="BclExtras.dll"/> <Reference name="BclExtras35.dll"/>
<Reference name="XMLRPC.dll"/> <Reference name="XMLRPC.dll"/>
<Reference name="Nini.dll" /> <Reference name="Nini.dll" />
<Reference name="log4net.dll"/> <Reference name="log4net.dll"/>