diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index 2fe8b465d8..239b884363 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -117,6 +117,7 @@ what it is today.
* nornalbion
* Omar Vera Ustariz (IBM)
* openlifegrid.com
+* Oren Hurvitz (Kitely)
* otakup0pe
* ralphos
* RemedyTomm
diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
index ee3d7c58bc..86c0ac8f94 100644
--- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
+++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
@@ -812,6 +812,14 @@ namespace OpenSim.ApplicationPlugins.RemoteController
// ok, client wants us to use an explicit UUID
// regardless of what the avatar name provided
userID = new UUID((string) requestData["estate_owner_uuid"]);
+
+ // Check that the specified user exists
+ Scene currentOrFirst = m_application.SceneManager.CurrentOrFirstScene;
+ IUserAccountService accountService = currentOrFirst.UserAccountService;
+ UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID, userID);
+
+ if (user == null)
+ throw new Exception("Specified user was not found.");
}
else if (requestData.ContainsKey("estate_owner_first") & requestData.ContainsKey("estate_owner_last"))
{
@@ -823,6 +831,11 @@ namespace OpenSim.ApplicationPlugins.RemoteController
IUserAccountService accountService = currentOrFirst.UserAccountService;
UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID,
ownerFirst, ownerLast);
+
+ // Check that the specified user exists
+ if (user == null)
+ throw new Exception("Specified user was not found.");
+
userID = user.PrincipalID;
}
else
diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
index 105a1e028b..e1b4fe756b 100644
--- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
+++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
@@ -47,7 +47,6 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
namespace OpenSim.Capabilities.Handlers
{
-
public class GetTextureHandler : BaseStreamHandler
{
private static readonly ILog m_log =
@@ -67,7 +66,6 @@ namespace OpenSim.Capabilities.Handlers
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
-
// Try to parse the texture ID from the request URL
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
string textureStr = query.GetOne("texture_id");
@@ -85,6 +83,8 @@ namespace OpenSim.Capabilities.Handlers
UUID textureID;
if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID))
{
+// m_log.DebugFormat("[GETTEXTURE]: Received request for texture id {0}", textureID);
+
string[] formats;
if (format != null && format != string.Empty)
{
@@ -105,7 +105,6 @@ namespace OpenSim.Capabilities.Handlers
if (FetchTexture(httpRequest, httpResponse, textureID, f))
break;
}
-
}
else
{
diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs
index b9228d1480..3437250e5f 100644
--- a/OpenSim/Data/MySQL/MySQLSimulationData.cs
+++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs
@@ -1209,7 +1209,6 @@ namespace OpenSim.Data.MySQL
return prim;
}
-
///
/// Build a prim inventory item from the persisted data.
///
diff --git a/OpenSim/Data/Null/NullSimulationData.cs b/OpenSim/Data/Null/NullSimulationData.cs
index e8d733b582..c33a6f2c43 100644
--- a/OpenSim/Data/Null/NullSimulationData.cs
+++ b/OpenSim/Data/Null/NullSimulationData.cs
@@ -59,19 +59,23 @@ namespace OpenSim.Data.Null
public void StoreRegionSettings(RegionSettings rs)
{
}
+
public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
{
//This connector doesn't support the windlight module yet
//Return default LL windlight settings
return new RegionLightShareData();
}
+
public void RemoveRegionWindlightSettings(UUID regionID)
{
}
+
public void StoreRegionWindlightSettings(RegionLightShareData wl)
{
//This connector doesn't support the windlight module yet
}
+
public RegionSettings LoadRegionSettings(UUID regionUUID)
{
return null;
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs
index a68de574d6..21e2233ad2 100644
--- a/OpenSim/Framework/AvatarAppearance.cs
+++ b/OpenSim/Framework/AvatarAppearance.cs
@@ -405,31 +405,40 @@ namespace OpenSim.Framework
///
public List GetAttachments()
{
+
+
lock (m_attachments)
{
- List alist = new List();
+ List alist = new List();
foreach (KeyValuePair> kvp in m_attachments)
{
foreach (AvatarAttachment attach in kvp.Value)
alist.Add(new AvatarAttachment(attach));
}
-
- return alist;
- }
- }
+ return alist;
+ } }
internal void AppendAttachment(AvatarAttachment attach)
{
+// m_log.DebugFormat(
+// "[AVATAR APPEARNCE]: Appending itemID={0}, assetID={1} at {2}",
+// attach.ItemID, attach.AssetID, attach.AttachPoint);
+
lock (m_attachments)
{
if (!m_attachments.ContainsKey(attach.AttachPoint))
m_attachments[attach.AttachPoint] = new List();
+
m_attachments[attach.AttachPoint].Add(attach);
}
}
internal void ReplaceAttachment(AvatarAttachment attach)
{
+// m_log.DebugFormat(
+// "[AVATAR APPEARANCE]: Replacing itemID={0}, assetID={1} at {2}",
+// attach.ItemID, attach.AssetID, attach.AttachPoint);
+
lock (m_attachments)
{
m_attachments[attach.AttachPoint] = new List();
@@ -438,7 +447,7 @@ namespace OpenSim.Framework
}
///
- /// Add an attachment
+ /// Set an attachment
///
///
/// If the attachpoint has the
@@ -454,13 +463,13 @@ namespace OpenSim.Framework
///
public bool SetAttachment(int attachpoint, UUID item, UUID asset)
{
- if (attachpoint == 0)
- return false;
-
// m_log.DebugFormat(
// "[AVATAR APPEARANCE]: Setting attachment at {0} with item ID {1}, asset ID {2}",
// attachpoint, item, asset);
+ if (attachpoint == 0)
+ return false;
+
if (item == UUID.Zero)
{
lock (m_attachments)
@@ -470,12 +479,21 @@ namespace OpenSim.Framework
m_attachments.Remove(attachpoint);
return true;
}
- return false;
}
+
+ return false;
}
- // check if the item is already attached at this point
- if (GetAttachpoint(item) == (attachpoint & 0x7F))
+ // When a user logs in, the attachment item ids are pulled from persistence in the Avatars table. However,
+ // the asset ids are not saved. When the avatar enters a simulator the attachments are set again. If
+ // we simply perform an item check here then the asset ids (which are now present) are never set, and NPC attachments
+ // later fail unless the attachment is detached and reattached.
+ //
+ // Therefore, we will carry on with the set if the existing attachment has no asset id.
+ AvatarAttachment existingAttachment = GetAttachmentForItem(item);
+ if (existingAttachment != null
+ && existingAttachment.AssetID != UUID.Zero
+ && existingAttachment.AttachPoint == (attachpoint & 0x7F))
{
// m_log.DebugFormat("[AVATAR APPEARANCE] attempt to attach an already attached item {0}",item);
return false;
@@ -492,9 +510,30 @@ namespace OpenSim.Framework
{
ReplaceAttachment(new AvatarAttachment(attachpoint,item, asset));
}
+
return true;
}
+ ///
+ /// If the item is already attached, return it.
+ ///
+ ///
+ /// Returns null if this item is not attached.
+ public AvatarAttachment GetAttachmentForItem(UUID itemID)
+ {
+ lock (m_attachments)
+ {
+ foreach (KeyValuePair> kvp in m_attachments)
+ {
+ int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
+ if (index >= 0)
+ return kvp.Value[index];
+ }
+ }
+
+ return null;
+ }
+
public int GetAttachpoint(UUID itemID)
{
lock (m_attachments)
@@ -505,9 +544,8 @@ namespace OpenSim.Framework
if (index >= 0)
return kvp.Key;
}
-
- return 0;
}
+ return 0;
}
public bool DetachAttachment(UUID itemID)
@@ -521,23 +559,23 @@ namespace OpenSim.Framework
{
// Remove it from the list of attachments at that attach point
m_attachments[kvp.Key].RemoveAt(index);
-
+
// And remove the list if there are no more attachments here
if (m_attachments[kvp.Key].Count == 0)
m_attachments.Remove(kvp.Key);
+
return true;
}
}
}
+
return false;
}
public void ClearAttachments()
{
lock (m_attachments)
- {
m_attachments.Clear();
- }
}
#region Packing Functions
diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs
index 613db1c55a..5a4811e408 100644
--- a/OpenSim/Framework/ChildAgentDataUpdate.cs
+++ b/OpenSim/Framework/ChildAgentDataUpdate.cs
@@ -441,7 +441,6 @@ namespace OpenSim.Framework
args["controllers"] = controls;
}
-
if ((CallbackURI != null) && (!CallbackURI.Equals("")))
args["callback_uri"] = OSD.FromString(CallbackURI);
@@ -628,6 +627,7 @@ namespace OpenSim.Framework
// We know all of these must end up as attachments so we
// append rather than replace to ensure multiple attachments
// per point continues to work
+// m_log.DebugFormat("[CHILDAGENTDATAUPDATE]: Appending attachments for {0}", AgentID);
Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o));
}
}
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 2d58807b68..1cbb53f01b 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -1384,11 +1384,30 @@ namespace OpenSim.Framework
return (ipaddr1 != null) ? "http://" + ipaddr1.ToString() + ":" + port1 : uri;
}
+ ///
+ /// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 256 bytes if necessary.
+ ///
+ ///
+ /// If null or empty, then an bytes[0] is returned.
+ /// Using "\0" will return a conversion of the null character to a byte. This is not the same as bytes[0]
+ ///
+ ///
+ /// Arguments to substitute into the string via the {} mechanism.
+ ///
+ ///
public static byte[] StringToBytes256(string str, params object[] args)
{
return StringToBytes256(string.Format(str, args));
}
-
+
+ ///
+ /// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 256 bytes if necessary.
+ ///
+ ///
+ /// If null or empty, then an bytes[0] is returned.
+ /// Using "\0" will return a conversion of the null character to a byte. This is not the same as bytes[0]
+ ///
+ ///
public static byte[] StringToBytes256(string str)
{
if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; }
@@ -1407,11 +1426,30 @@ namespace OpenSim.Framework
return data;
}
+ ///
+ /// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 1024 bytes if necessary.
+ ///
+ ///
+ /// If null or empty, then an bytes[0] is returned.
+ /// Using "\0" will return a conversion of the null character to a byte. This is not the same as bytes[0]
+ ///
+ ///
+ /// Arguments to substitute into the string via the {} mechanism.
+ ///
+ ///
public static byte[] StringToBytes1024(string str, params object[] args)
{
return StringToBytes1024(string.Format(str, args));
}
-
+
+ ///
+ /// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 1024 bytes if necessary.
+ ///
+ ///
+ /// If null or empty, then an bytes[0] is returned.
+ /// Using "\0" will return a conversion of the null character to a byte. This is not the same as bytes[0]
+ ///
+ ///
public static byte[] StringToBytes1024(string str)
{
if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; }
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index fae8be759c..92ccb06925 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -269,13 +269,15 @@ namespace OpenSim
m_console.Commands.AddCommand("region", false, "save oar",
//"save oar [-v|--version=] [-p|--profile=] []",
- "save oar [-p|--profile=] [--noassets] []",
+ "save oar [-p|--profile=] [--noassets] [--perm=] []",
"Save a region's data to an OAR archive.",
// "-v|--version= generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
"-p|--profile= adds the url of the profile service to the saved user information." + Environment.NewLine
- + " The OAR path must be a filesystem path."
- + " If this is not given then the oar is saved to region.oar in the current directory." + Environment.NewLine
- + "--noassets stops assets being saved to the OAR.",
+ + "--noassets stops assets being saved to the OAR." + Environment.NewLine
+ + "--perm stops objects with insufficient permissions from being saved to the OAR." + Environment.NewLine
+ + " can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer" + Environment.NewLine
+ + "The OAR path must be a filesystem path."
+ + " If this is not given then the oar is saved to region.oar in the current directory.",
SaveOar);
m_console.Commands.AddCommand("region", false, "edit scale",
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index dbfd0f2290..dd0ea67731 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -489,6 +489,8 @@ namespace OpenSim
scene.StartTimer();
scene.StartTimerWatchdog();
+ scene.StartScripts();
+
return clientServer;
}
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 218b7b8096..2bf418d341 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -144,20 +144,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
public void SaveChangedAttachments(IScenePresence sp)
{
+// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name);
+
foreach (SceneObjectGroup grp in sp.GetAttachments())
{
- if (grp.HasGroupChanged) // Resizer scripts?
- {
+// if (grp.HasGroupChanged) // Resizer scripts?
+// {
grp.IsAttachment = false;
grp.AbsolutePosition = grp.RootPart.AttachedPos;
- UpdateKnownItem(sp.ControllingClient, grp, grp.GetFromItemID(), grp.OwnerID);
+ UpdateKnownItem(sp.ControllingClient, grp);
grp.IsAttachment = true;
- }
+// }
}
}
public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent)
{
+// m_log.DebugFormat(
+// "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}",
+// m_scene.RegionInfo.RegionName, sp.Name, silent);
+
foreach (SceneObjectGroup sop in sp.GetAttachments())
{
sop.Scene.DeleteSceneObject(sop, silent);
@@ -220,7 +226,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
// Save avatar attachment information
- m_log.Info(
+ m_log.Debug(
"[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
+ ", AttachmentPoint: " + AttachmentPt);
@@ -248,75 +254,83 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
private bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent)
{
-// m_log.DebugFormat(
-// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
-// group.Name, group.LocalId, sp.Name, AttachmentPt, silent);
-
- if (sp.GetAttachments(attachmentPt).Contains(group))
+ lock (sp.AttachmentsSyncLock)
{
-// m_log.WarnFormat(
-// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
-// group.Name, group.LocalId, sp.Name, AttachmentPt);
-
- return false;
- }
-
- Vector3 attachPos = group.AbsolutePosition;
-
- // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
- // be removed when that functionality is implemented in opensim
- attachmentPt &= 0x7f;
-
- // 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 != group.AttachmentPoint)
- {
- attachPos = Vector3.Zero;
- }
-
- // AttachmentPt 0 means the client chose to 'wear' the attachment.
- if (attachmentPt == 0)
- {
- // Check object for stored attachment point
- attachmentPt = group.AttachmentPoint;
- }
-
- // 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.AttachmentPoint = attachmentPt;
- group.AbsolutePosition = attachPos;
-
- // Remove any previous attachments
- UUID itemID = UUID.Zero;
-
- List attachments = sp.GetAttachments(attachmentPt);
-
- // At the moment we can only deal with a single attachment
- // We also don't want to do any of the inventory operations for an NPC.
- if (sp.PresenceType != PresenceType.Npc)
- {
- if (attachments.Count != 0)
- itemID = attachments[0].GetFromItemID();
+// m_log.DebugFormat(
+// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
+// group.Name, group.LocalId, sp.Name, attachmentPt, silent);
- if (itemID != UUID.Zero)
- DetachSingleAttachmentToInv(itemID, sp);
+ if (sp.GetAttachments(attachmentPt).Contains(group))
+ {
+ // m_log.WarnFormat(
+ // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
+ // group.Name, group.LocalId, sp.Name, AttachmentPt);
- itemID = group.GetFromItemID();
- if (itemID == UUID.Zero)
- itemID = AddSceneObjectAsAttachment(sp.ControllingClient, group).ID;
+ return false;
+ }
- ShowAttachInUserInventory(sp, attachmentPt, itemID, group);
+ Vector3 attachPos = group.AbsolutePosition;
+
+ // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
+ // be removed when that functionality is implemented in opensim
+ attachmentPt &= 0x7f;
+
+ // 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 != group.AttachmentPoint)
+ {
+ attachPos = Vector3.Zero;
+ }
+
+ // AttachmentPt 0 means the client chose to 'wear' the attachment.
+ if (attachmentPt == 0)
+ {
+ // Check object for stored attachment point
+ attachmentPt = group.AttachmentPoint;
+ }
+
+ // 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.AttachmentPoint = attachmentPt;
+ group.AbsolutePosition = attachPos;
+
+ // We also don't want to do any of the inventory operations for an NPC.
+ if (sp.PresenceType != PresenceType.Npc)
+ {
+ // Remove any previous attachments
+ List attachments = sp.GetAttachments(attachmentPt);
+
+ // At the moment we can only deal with a single attachment
+ if (attachments.Count != 0)
+ {
+ UUID oldAttachmentItemID = attachments[0].GetFromItemID();
+
+ if (oldAttachmentItemID != UUID.Zero)
+ DetachSingleAttachmentToInv(oldAttachmentItemID, sp);
+ else
+ m_log.WarnFormat(
+ "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!",
+ attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name);
+ }
+
+ // Add the new attachment to inventory if we don't already have it.
+ UUID newAttachmentItemID = group.GetFromItemID();
+ if (newAttachmentItemID == UUID.Zero)
+ newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp.ControllingClient, group).ID;
+
+ ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
+ }
+
+ AttachToAgent(sp, group, attachmentPt, attachPos, silent);
}
- AttachToAgent(sp, group, attachmentPt, attachPos, silent);
-
return true;
}
@@ -325,20 +339,28 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header,
RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects)
{
- foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in objects)
+ ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
+
+ if (sp == null)
{
- RezSingleAttachmentFromInventory(remoteClient, obj.ItemID, obj.AttachmentPt);
+ m_log.ErrorFormat(
+ "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezMultipleAttachmentsFromInventory()",
+ remoteClient.Name, remoteClient.AgentId);
+ return;
+ }
+
+ lock (sp.AttachmentsSyncLock)
+ {
+// m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name);
+
+ foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in objects)
+ {
+ RezSingleAttachmentFromInventory(sp, obj.ItemID, obj.AttachmentPt);
+ }
}
}
- public ISceneEntity RezSingleAttachmentFromInventory(
- IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
- {
- return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true);
- }
-
- public ISceneEntity RezSingleAttachmentFromInventory(
- IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus)
+ public ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
{
return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true, null);
}
@@ -347,21 +369,59 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc)
{
ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
- if (sp == null) { m_log.ErrorFormat( "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezSingleAttachmentFromInventory()", remoteClient.Name, remoteClient.AgentId); return null; }
+
+ if (sp == null)
+ {
+ m_log.ErrorFormat(
+ "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezSingleAttachmentFromInventory()",
+ remoteClient.Name, remoteClient.AgentId);
+ return null;
+ }
+
+ return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt);
+ }
+
+ public ISceneEntity RezSingleAttachmentFromInventory(ScenePresence sp, UUID itemID, uint AttachmentPt)
+ {
+// m_log.DebugFormat(
+// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}",
+// (AttachmentPoint)AttachmentPt, itemID, sp.Name);
+
// TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
// be removed when that functionality is implemented in opensim
AttachmentPt &= 0x7f;
- SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc);
-
- if (updateInventoryStatus)
+ // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such).
+ // This often happens during login - not sure the exact reason.
+ // For now, we will ignore the request. Unfortunately, this means that we need to dig through all the
+ // ScenePresence attachments. We can't use the data in AvatarAppearance because that's present at login
+ // before anything has actually been attached.
+ bool alreadyOn = false;
+ List existingAttachments = sp.GetAttachments();
+ foreach (SceneObjectGroup so in existingAttachments)
{
- if (att == null)
- DetachSingleAttachmentToInv(itemID, sp.ControllingClient);
- else
- ShowAttachInUserInventory(att, sp, itemID, AttachmentPt);
+ if (so.GetFromItemID() == itemID)
+ {
+ alreadyOn = true;
+ break;
+ }
}
+// if (sp.Appearance.GetAttachmentForItem(itemID) != null)
+ if (alreadyOn)
+ {
+// m_log.WarnFormat(
+// "[ATTACHMENTS MODULE]: Ignoring request by {0} to wear item {1} at {2} since it is already worn",
+// sp.Name, itemID, AttachmentPt);
+
+ return null;
+ }
+
+ SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, null);
+
+ if (att == null)
+ DetachSingleAttachmentToInv(itemID, sp.ControllingClient);
+
return att;
}
@@ -371,50 +431,67 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
IInventoryAccessModule invAccess = m_scene.RequestModuleInterface();
if (invAccess != null)
{
- SceneObjectGroup objatt;
-
- if (itemID != UUID.Zero)
- objatt = invAccess.RezObject(sp.ControllingClient,
- itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
- false, false, sp.UUID, true);
- else
- objatt = invAccess.RezObject(sp.ControllingClient,
- null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
- false, false, sp.UUID, true);
-
-// m_log.DebugFormat(
-// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
-// objatt.Name, remoteClient.Name, AttachmentPt);
-
- if (objatt != null)
+ lock (sp.AttachmentsSyncLock)
{
- // Loading the inventory from XML will have set this, but
- // there is no way the object could have changed yet,
- // since scripts aren't running yet. So, clear it here.
- objatt.HasGroupChanged = false;
- bool tainted = false;
- if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
- tainted = true;
-
- // This will throw if the attachment fails
- try
- {
- AttachObject(sp, objatt, attachmentPt, false);
- }
- catch (Exception e)
- {
- m_log.ErrorFormat(
- "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
- objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
-
- // Make sure the object doesn't stick around and bail
- sp.RemoveAttachment(objatt);
- m_scene.DeleteSceneObject(objatt, false);
- return null;
- }
+ SceneObjectGroup objatt;
+
+ if (itemID != UUID.Zero)
+ objatt = invAccess.RezObject(sp.ControllingClient,
+ itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
+ false, false, sp.UUID, true);
+ else
+ objatt = invAccess.RezObject(sp.ControllingClient,
+ null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
+ false, false, sp.UUID, true);
+
+ // m_log.DebugFormat(
+ // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
+ // objatt.Name, remoteClient.Name, AttachmentPt);
- if (tainted)
- objatt.HasGroupChanged = true;
+ if (objatt != null)
+ {
+ // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
+ objatt.HasGroupChanged = false;
+ bool tainted = false;
+ if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
+ tainted = true;
+
+ // This will throw if the attachment fails
+ try
+ {
+ AttachObject(sp, objatt, attachmentPt, false);
+ }
+ catch (Exception e)
+ {
+ m_log.ErrorFormat(
+ "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
+ objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
+
+ // Make sure the object doesn't stick around and bail
+ sp.RemoveAttachment(objatt);
+ m_scene.DeleteSceneObject(objatt, false);
+ return null;
+ }
+
+ if (tainted)
+ objatt.HasGroupChanged = true;
+
+ // Fire after attach, so we don't get messy perms dialogs
+ // 4 == AttachedRez
+ objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
+ objatt.ResumeScripts();
+
+ // Do this last so that event listeners have access to all the effects of the attachment
+ m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
+
+ return objatt;
+ }
+ else
+ {
+ m_log.WarnFormat(
+ "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
+ itemID, sp.Name, attachmentPt);
+ }
if (doc != null)
{
@@ -430,47 +507,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// Do this last so that event listeners have access to all the effects of the attachment
m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
}
- else
- {
- m_log.WarnFormat(
- "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
- itemID, sp.Name, attachmentPt);
- }
-
- return objatt;
}
return null;
}
-
- ///
- /// Update the user inventory to the attachment of an item
- ///
- ///
- ///
- ///
- ///
- ///
- private UUID ShowAttachInUserInventory(
- SceneObjectGroup att, IScenePresence sp, UUID itemID, uint attachmentPoint)
- {
-// m_log.DebugFormat(
-// "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} {2} (item ID {3}) at {4}",
-// sp.Name, att.Name, att.LocalId, itemID, AttachmentPt);
-
- if (!att.IsDeleted)
- attachmentPoint = att.AttachmentPoint;
-
- InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID);
- if (m_scene.InventoryService != null)
- item = m_scene.InventoryService.GetItem(item);
-
- bool changed = sp.Appearance.SetAttachment((int)attachmentPoint, itemID, item.AssetID);
- if (changed && m_scene.AvatarFactory != null)
- m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
-
- return att.UUID;
- }
///
/// Update the user inventory to reflect an attachment
@@ -483,8 +523,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
IScenePresence sp, 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);
+// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
+// att.Name, sp.Name, AttachmentPt, itemID);
if (UUID.Zero == itemID)
{
@@ -518,6 +558,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
public void DetachObject(uint objectLocalID, IClientAPI remoteClient)
{
+// m_log.DebugFormat(
+// "[ATTACHMENTS MODULE]: DetachObject() for object {0} on {1}", objectLocalID, remoteClient.Name);
+
SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
if (group != null)
{
@@ -530,14 +573,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
ScenePresence presence;
if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
{
- // Save avatar attachment information
- m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID);
+ lock (presence.AttachmentsSyncLock)
+ {
+ // Save avatar attachment information
+ m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID);
- bool changed = presence.Appearance.DetachAttachment(itemID);
- if (changed && m_scene.AvatarFactory != null)
- m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
-
- DetachSingleAttachmentToInv(itemID, presence);
+ bool changed = presence.Appearance.DetachAttachment(itemID);
+ if (changed && m_scene.AvatarFactory != null)
+ m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
+
+ DetachSingleAttachmentToInv(itemID, presence);
+ }
}
}
@@ -545,7 +591,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
{
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}",
-// remoteClient.Name, sceneObjectID);
+// remoteClient.Name, soLocalId);
SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId);
@@ -564,24 +610,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
ScenePresence presence;
if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
{
- if (!m_scene.Permissions.CanRezObject(
- so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition))
- return;
+ lock (presence.AttachmentsSyncLock)
+ {
+ if (!m_scene.Permissions.CanRezObject(
+ so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition))
+ return;
- bool changed = presence.Appearance.DetachAttachment(inventoryID);
- if (changed && m_scene.AvatarFactory != null)
- m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
+ bool changed = presence.Appearance.DetachAttachment(inventoryID);
+ if (changed && m_scene.AvatarFactory != null)
+ m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
- presence.RemoveAttachment(so);
- DetachSceneObjectToGround(so, presence);
+ presence.RemoveAttachment(so);
+ DetachSceneObjectToGround(so, presence);
- List uuids = new List();
- uuids.Add(inventoryID);
- m_scene.InventoryService.DeleteItems(remoteClient.AgentId, uuids);
- remoteClient.SendRemoveInventoryItem(inventoryID);
+ List uuids = new List();
+ uuids.Add(inventoryID);
+ m_scene.InventoryService.DeleteItems(remoteClient.AgentId, uuids);
+ remoteClient.SendRemoveInventoryItem(inventoryID);
+ }
+
+ m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero);
}
-
- m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero);
}
///
@@ -615,6 +664,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// To LocalId or UUID, *THAT* is the question. How now Brown UUID??
private void DetachSingleAttachmentToInv(UUID itemID, IScenePresence sp)
{
+// m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name);
+
if (itemID == UUID.Zero) // If this happened, someone made a mistake....
return;
@@ -623,40 +674,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
EntityBase[] detachEntities = m_scene.GetEntities();
SceneObjectGroup group;
- foreach (EntityBase entity in detachEntities)
+ lock (sp.AttachmentsSyncLock)
{
- if (entity is SceneObjectGroup)
+ foreach (EntityBase entity in detachEntities)
{
- group = (SceneObjectGroup)entity;
- if (group.GetFromItemID() == itemID)
+ if (entity is SceneObjectGroup)
{
- m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero);
+ group = (SceneObjectGroup)entity; if (group.GetFromItemID() == itemID) { m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero);
// CM / XMREngine!!!! Needed to conclude attach event
//SceneObjectSerializer.ToOriginalXmlFormat(group);
group.DetachToInventoryPrep();
m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString());
- // Prepare sog for storage
- group.AttachedAvatar = UUID.Zero;
+ // Prepare sog for storage
+ group.AttachedAvatar = UUID.Zero;
+ group.RootPart.SetParentLocalId(0);
+ group.IsAttachment = false;
+ group.AbsolutePosition = group.RootPart.AttachedPos;
- group.ForEachPart(
- delegate(SceneObjectPart part)
- {
- // If there are any scripts,
- // then always trigger a new object and state persistence in UpdateKnownItem()
- if (part.Inventory.ContainsScripts())
- group.HasGroupChanged = true;
- }
- );
+ UpdateKnownItem(sp.ControllingClient, group);
+ m_scene.DeleteSceneObject(group, false);
- group.RootPart.SetParentLocalId(0);
- group.IsAttachment = false;
- group.AbsolutePosition = group.RootPart.AttachedPos;
-
- UpdateKnownItem(sp.ControllingClient, group, group.GetFromItemID(), group.OwnerID);
- m_scene.DeleteSceneObject(group, false);
-
- return;
+ return;
+ }
}
}
}
@@ -687,28 +727,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
///
///
///
- ///
- ///
- public void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID)
+ private void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp)
{
- if (grp != null)
+ if (grp.HasGroupChanged || grp.ContainsScripts())
{
- if (!grp.HasGroupChanged)
- {
- m_log.DebugFormat(
- "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}",
- grp.UUID, grp.AttachmentPoint);
-
- return;
- }
-
m_log.DebugFormat(
"[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
grp.UUID, grp.AttachmentPoint);
string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
- InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
+ InventoryItemBase item = new InventoryItemBase(grp.GetFromItemID(), remoteClient.AgentId);
item = m_scene.InventoryService.GetItem(item);
if (item != null)
@@ -734,6 +763,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
remoteClient.SendInventoryItemCreateUpdate(item, 0);
}
}
+ else
+ {
+ m_log.DebugFormat(
+ "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}",
+ grp.UUID, grp.AttachmentPoint);
+ }
}
///
@@ -751,7 +786,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
private void AttachToAgent(
IScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
{
-// m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}",
+// m_log.DebugFormat(
+// "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}",
// so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos);
so.DetachFromBackup();
@@ -788,14 +824,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
}
///
- /// Add a scene object that was previously free in the scene as an attachment to an avatar.
+ /// Add a scene object as a new attachment in the user inventory.
///
///
///
/// The user inventory item created that holds the attachment.
- private InventoryItemBase AddSceneObjectAsAttachment(IClientAPI remoteClient, SceneObjectGroup grp)
+ private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IClientAPI remoteClient, SceneObjectGroup grp)
{
-// m_log.DebugFormat("[SCENE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2} {3} {4}", grp.Name, grp.LocalId, remoteClient.Name, remoteClient.AgentId, AgentId);
+// m_log.DebugFormat(
+// "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}",
+// grp.Name, grp.LocalId, remoteClient.Name);
Vector3 inventoryStoredPosition = new Vector3
(((grp.AbsolutePosition.X > (int)Constants.RegionSize)
@@ -879,4 +917,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
return item;
}
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index 363e2584aa..ff3358f4fe 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -58,12 +58,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
private AttachmentsModule m_attMod;
private ScenePresence m_presence;
- [SetUp]
- public void Init()
+ [TestFixtureSetUp]
+ public void FixtureInit()
{
// Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
Util.FireAndForgetMethod = FireAndForgetMethod.None;
+ }
+ [SetUp]
+ public void Init()
+ {
IConfigSource config = new IniConfigSource();
config.AddConfig("Modules");
config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
@@ -73,7 +77,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
SceneHelpers.SetupSceneModules(scene, config, m_attMod, new BasicInventoryAccessModule());
}
- [TearDown]
+ [TestFixtureTearDown]
public void TearDown()
{
// We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
@@ -150,6 +154,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
Assert.That(attSo.IsTemporary, Is.False);
// Check appearance status
+ Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(1));
Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest));
}
@@ -215,6 +220,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0));
}
+ ///
+ /// Test that attachments don't hang about in the scene when the agent is closed
+ ///
+ [Test]
+ public void TestRemoveAttachmentsOnAvatarExit()
+ {
+ TestHelpers.InMethod();
+// log4net.Config.XmlConfigurator.Configure();
+
+ UUID userId = TestHelpers.ParseTail(0x1);
+ UUID attItemId = TestHelpers.ParseTail(0x2);
+ UUID attAssetId = TestHelpers.ParseTail(0x3);
+ string attName = "att";
+
+ UserAccountHelpers.CreateUserWithInventory(scene, userId);
+ InventoryItemBase attItem
+ = UserInventoryHelpers.CreateInventoryItem(
+ scene, attName, attItemId, attAssetId, userId, InventoryType.Object);
+
+ AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
+ acd.Appearance = new AvatarAppearance();
+ acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
+ ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd);
+
+ SceneObjectGroup rezzedAtt = presence.GetAttachments()[0];
+
+ scene.IncomingCloseAgent(presence.UUID);
+
+ // Check that we can't retrieve this attachment from the scene.
+ Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null);
+ }
+
[Test]
public void TestRezAttachmentsOnAvatarEntrance()
{
@@ -246,6 +283,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
Assert.That(attSo.IsAttachment);
Assert.That(attSo.UsesPhysics, Is.False);
Assert.That(attSo.IsTemporary, Is.False);
+
+ // Check appearance status
+ List retreivedAttachments = presence.Appearance.GetAttachments();
+ Assert.That(retreivedAttachments.Count, Is.EqualTo(1));
+ Assert.That(retreivedAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest));
+ Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItemId));
+ Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attAssetId));
+ Assert.That(presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest));
}
// I'm commenting this test because scene setup NEEDS InventoryService to
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index faccab24a7..25d5e0e066 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -59,7 +59,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
get { return m_MaxTransferDistance; }
set { m_MaxTransferDistance = value; }
}
-
protected bool m_Enabled = false;
protected Scene m_aScene;
@@ -68,7 +67,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
private ExpiringCache> m_bannedRegions =
new ExpiringCache>();
-
#region ISharedRegionModule
public Type ReplaceableInterface
@@ -210,7 +208,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Teleport(position);
foreach (SceneObjectGroup grp in sp.GetAttachments())
- sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT);
+ {
+ if (grp.IsDeleted)
+ sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT);
+ }
}
else // Another region possibly in another simulator
{
@@ -328,10 +329,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.StandUp();
if (!sp.ValidateAttachments())
- {
- sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state");
- return;
- }
+ m_log.DebugFormat(
+ "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.",
+ sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName);
+
+// if (!sp.ValidateAttachments())
+// {
+// sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state");
+// return;
+// }
string reason;
string version;
@@ -955,7 +961,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// This Closes child agents on neighbouring regions
/// Calls an asynchronous method to do so.. so it doesn't lag the sim.
///
- protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version)
+ protected ScenePresence CrossAgentToNewRegionAsync(
+ ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion,
+ bool isFlying, string version)
{
ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
@@ -963,8 +971,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
Scene m_scene = agent.Scene;
- if (neighbourRegion != null && agent.ValidateAttachments())
+ if (neighbourRegion != null)
{
+ if (!agent.ValidateAttachments())
+ m_log.DebugFormat(
+ "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.",
+ agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName);
+
pos = pos + (agent.Velocity);
SetInTransit(agent.UUID);
@@ -1789,16 +1802,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
List m_attachments = sp.GetAttachments();
// Validate
- foreach (SceneObjectGroup gobj in m_attachments)
- {
- if (gobj == null || gobj.IsDeleted)
- return false;
- }
+// foreach (SceneObjectGroup gobj in m_attachments)
+// {
+// if (gobj == null || gobj.IsDeleted)
+// return false;
+// }
foreach (SceneObjectGroup gobj in m_attachments)
{
// If the prim group is null then something must have happened to it!
- if (gobj != null)
+ if (gobj != null && !gobj.IsDeleted)
{
// Set the parent localID to 0 so it transfers over properly.
gobj.RootPart.SetParentLocalId(0);
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index a4bb40ef93..f05b090b1e 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -726,8 +726,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
SceneObjectGroup group = null;
string xmlData = Utils.BytesToString(rezAsset.Data);
- List objlist =
- new List();
+ List objlist = new List();
List veclist = new List();
byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0);
Vector3 pos;
@@ -799,6 +798,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
m_log.Debug("[InventoryAccessModule]: Object has UUID.Zero! Position 3");
}
+ foreach (SceneObjectPart part in group.Parts)
+ {
+ // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset.
+ part.LastOwnerID = part.OwnerID;
+ part.OwnerID = remoteClient.AgentId;
+ }
+
if (!attachment)
{
// If it's rezzed in world, select it. Much easier to
@@ -839,7 +845,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
if (!attachment)
{
- if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
+ if (rootPart.Shape.PCode == (byte)PCode.Prim)
group.ClearPartAttachmentData();
// Fire on_rez
@@ -1017,11 +1023,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
if ((part.OwnerID != item.Owner) ||
(item.CurrentPermissions & 16) != 0)
{
- part.LastOwnerID = part.OwnerID;
- part.OwnerID = item.Owner;
part.Inventory.ChangeInventoryOwner(item.Owner);
part.GroupMask = 0; // DO NOT propagate here
}
+
part.EveryoneMask = item.EveryOnePermissions;
part.NextOwnerMask = item.NextPermissions;
}
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index b0b35e4d0d..bef0d69697 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -87,8 +87,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
"Show the bindings between user UUIDs and user names",
String.Empty,
HandleShowUsers);
-
-
}
public bool IsSharedModule
@@ -365,9 +363,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
lock (m_UserCache)
m_UserCache[user.Id] = user;
- m_log.DebugFormat(
- "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}",
- user.Id, user.FirstName, user.LastName, user.HomeURL);
+// m_log.DebugFormat(
+// "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}",
+// user.Id, user.FirstName, user.LastName, user.HomeURL);
}
//public void AddUser(UUID uuid, string userData)
diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
index b20a875139..a14a84b42a 100644
--- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
@@ -323,7 +323,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
List targets = new List();
foreach (SceneObjectGroup sog in attachments)
{
- targets.Add(sog.UUID);
+ if (!sog.IsDeleted)
+ targets.Add(sog.UUID);
}
// Need to check each attachment
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
index 72ae336352..0d121edb97 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
@@ -64,7 +64,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
get
{
if (m_UserManagement == null)
+ {
m_UserManagement = m_Scenes[0].RequestModuleInterface();
+
+ if (m_UserManagement == null)
+ m_log.ErrorFormat(
+ "[HG INVENTORY CONNECTOR]: Could not retrieve IUserManagement module from {0}",
+ m_Scenes[0].RegionInfo.RegionName);
+ }
+
return m_UserManagement;
}
}
@@ -140,8 +148,29 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
scene.RegisterModuleInterface(this);
- scene.EventManager.OnClientClosed += OnClientClosed;
+ if (m_Scenes.Count == 1)
+ {
+ // FIXME: The local connector needs the scene to extract the UserManager. However, it's not enabled so
+ // we can't just add the region. But this approach is super-messy.
+ if (m_LocalGridInventoryService is RemoteXInventoryServicesConnector)
+ {
+ m_log.DebugFormat(
+ "[HG INVENTORY BROKER]: Manually setting scene in RemoteXInventoryServicesConnector to {0}",
+ scene.RegionInfo.RegionName);
+ ((RemoteXInventoryServicesConnector)m_LocalGridInventoryService).Scene = scene;
+ }
+ else if (m_LocalGridInventoryService is LocalInventoryServicesConnector)
+ {
+ m_log.DebugFormat(
+ "[HG INVENTORY BROKER]: Manually setting scene in LocalInventoryServicesConnector to {0}",
+ scene.RegionInfo.RegionName);
+
+ ((LocalInventoryServicesConnector)m_LocalGridInventoryService).Scene = scene;
+ }
+
+ scene.EventManager.OnClientClosed += OnClientClosed;
+ }
}
public void RemoveRegion(Scene scene)
@@ -323,7 +352,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
}
- public List GetFolderItems(UUID userID, UUID folderID)
+ public List GetFolderItems(UUID userID, UUID folderID)
{
//m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderItems " + folderID);
@@ -338,7 +367,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
}
- public bool AddFolder(InventoryFolderBase folder)
+ public bool AddFolder(InventoryFolderBase folder)
{
if (folder == null)
return false;
@@ -355,7 +384,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
return connector.AddFolder(folder);
}
- public bool UpdateFolder(InventoryFolderBase folder)
+ public bool UpdateFolder(InventoryFolderBase folder)
{
if (folder == null)
return false;
@@ -372,7 +401,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
return connector.UpdateFolder(folder);
}
- public bool DeleteFolders(UUID ownerID, List folderIDs)
+ public bool DeleteFolders(UUID ownerID, List folderIDs)
{
if (folderIDs == null)
return false;
@@ -391,7 +420,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
return connector.DeleteFolders(ownerID, folderIDs);
}
- public bool MoveFolder(InventoryFolderBase folder)
+ public bool MoveFolder(InventoryFolderBase folder)
{
if (folder == null)
return false;
@@ -408,7 +437,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
return connector.MoveFolder(folder);
}
- public bool PurgeFolder(InventoryFolderBase folder)
+ public bool PurgeFolder(InventoryFolderBase folder)
{
if (folder == null)
return false;
@@ -442,7 +471,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
return connector.AddItem(item);
}
- public bool UpdateItem(InventoryItemBase item)
+ public bool UpdateItem(InventoryItemBase item)
{
if (item == null)
return false;
@@ -459,7 +488,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
return connector.UpdateItem(item);
}
- public bool MoveItems(UUID ownerID, List items)
+ public bool MoveItems(UUID ownerID, List items)
{
if (items == null)
return false;
@@ -478,7 +507,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
return connector.MoveItems(ownerID, items);
}
- public bool DeleteItems(UUID ownerID, List itemIDs)
+ public bool DeleteItems(UUID ownerID, List itemIDs)
{
//m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Delete {0} items for user {1}", itemIDs.Count, ownerID);
@@ -497,7 +526,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
return connector.DeleteItems(ownerID, itemIDs);
}
- public InventoryItemBase GetItem(InventoryItemBase item)
+ public InventoryItemBase GetItem(InventoryItemBase item)
{
if (item == null)
return null;
@@ -513,7 +542,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
return connector.GetItem(item);
}
- public InventoryFolderBase GetFolder(InventoryFolderBase folder)
+ public InventoryFolderBase GetFolder(InventoryFolderBase folder)
{
if (folder == null)
return null;
@@ -530,17 +559,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
return connector.GetFolder(folder);
}
- public bool HasInventoryForUser(UUID userID)
+ public bool HasInventoryForUser(UUID userID)
{
return false;
}
- public List GetActiveGestures(UUID userId)
+ public List GetActiveGestures(UUID userId)
{
return new List();
}
- public int GetAssetPermissions(UUID userID, UUID assetID)
+ public int GetAssetPermissions(UUID userID, UUID assetID)
{
//m_log.Debug("[HG INVENTORY CONNECTOR]: GetAssetPermissions " + assetID);
@@ -572,14 +601,21 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
string connectorType = new HeloServicesConnector(url).Helo();
m_log.DebugFormat("[HG INVENTORY SERVICE]: HELO returned {0}", connectorType);
if (connectorType == "opensim-simian")
+ {
connector = new SimianInventoryServiceConnector(url);
+ }
else
- connector = new RemoteXInventoryServicesConnector(url);
+ {
+ RemoteXInventoryServicesConnector rxisc = new RemoteXInventoryServicesConnector(url);
+ rxisc.Scene = m_Scenes[0];
+ connector = rxisc;
+ }
+
m_connectors.Add(url, connector);
}
}
+
return connector;
}
-
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
index 65e39c0c06..1c83f8eb49 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
@@ -47,9 +47,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
- private IInventoryService m_InventoryService;
+ ///
+ /// Scene used by this module. This currently needs to be publicly settable for HGInventoryBroker.
+ ///
+ public Scene Scene { get; set; }
- private Scene m_Scene;
+ private IInventoryService m_InventoryService;
private IUserManagement m_UserManager;
private IUserManagement UserManager
@@ -58,7 +61,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
{
if (m_UserManager == null)
{
- m_UserManager = m_Scene.RequestModuleInterface();
+ m_UserManager = Scene.RequestModuleInterface();
}
return m_UserManager;
}
@@ -131,8 +134,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
scene.RegisterModuleInterface(this);
- if (m_Scene == null)
- m_Scene = scene;
+ if (Scene == null)
+ Scene = scene;
}
public void RemoveRegion(Scene scene)
@@ -185,8 +188,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
Util.FireAndForget(delegate
{
if (UserManager != null)
- foreach (InventoryItemBase item in invCol.Items)
+ {
+ // Protect ourselves against the caller subsequently modifying the items list
+ foreach (InventoryItemBase item in new List(invCol.Items))
UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
+ }
});
return invCol;
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
index 8f1f25774a..c9c716cec7 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
@@ -45,19 +45,30 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+ ///
+ /// Scene used by this module. This currently needs to be publicly settable for HGInventoryBroker.
+ ///
+ public Scene Scene { get; set; }
+
private bool m_Enabled = false;
private Scene m_Scene;
private XInventoryServicesConnector m_RemoteConnector;
private IUserManagement m_UserManager;
- private IUserManagement UserManager
+ public IUserManagement UserManager
{
get
{
if (m_UserManager == null)
{
- m_UserManager = m_Scene.RequestModuleInterface();
+ m_UserManager = Scene.RequestModuleInterface();
+
+ if (m_UserManager == null)
+ m_log.ErrorFormat(
+ "[XINVENTORY CONNECTOR]: Could not retrieve IUserManagement module from {0}",
+ Scene.RegionInfo.RegionName);
}
+
return m_UserManager;
}
}
@@ -86,12 +97,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
Init(source);
}
- protected void Init(IConfigSource source)
+ protected void Init(IConfigSource source)
{
m_RemoteConnector = new XInventoryServicesConnector(source);
}
-
#region ISharedRegionModule
public void Initialise(IConfigSource source)
@@ -128,15 +138,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
scene.RegisterModuleInterface(this);
- if (m_Scene == null)
- m_Scene = scene;
+ if (Scene == null)
+ Scene = scene;
}
public void RemoveRegion(Scene scene)
{
if (!m_Enabled)
return;
-
}
public void RegionLoaded(Scene scene)
@@ -181,14 +190,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
return m_RemoteConnector.GetFolderForType(userID, type);
}
- public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
+ public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
{
InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID);
Util.FireAndForget(delegate
{
if (UserManager != null)
- foreach (InventoryItemBase item in invCol.Items)
+ {
+ // Protect ourselves against the caller subsequently modifying the items list
+ foreach (InventoryItemBase item in new List(invCol.Items))
UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
+ }
});
return invCol;
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index f85a91701c..238863ef23 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -284,8 +284,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
// And zap any troublesome sit target information
- part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
- part.SitTargetPosition = new Vector3(0, 0, 0);
+// part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
+// part.SitTargetPosition = new Vector3(0, 0, 0);
// Fix ownership/creator of inventory items
// Not doing so results in inventory items
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
index 10a83ee826..b895afe85d 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
@@ -127,6 +127,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
EntityBase[] entities = m_scene.GetEntities();
List sceneObjects = new List();
+
+ string checkPermissions = null;
+ int numObjectsSkippedPermissions = 0;
+ Object temp;
+ if (options.TryGetValue("checkPermissions", out temp))
+ checkPermissions = (string)temp;
// Filter entities so that we only have scene objects.
// FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
@@ -136,9 +142,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver
if (entity is SceneObjectGroup)
{
SceneObjectGroup sceneObject = (SceneObjectGroup)entity;
-
+
if (!sceneObject.IsDeleted && !sceneObject.IsAttachment)
- sceneObjects.Add((SceneObjectGroup)entity);
+ {
+ if (!CanUserArchiveObject(m_scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, checkPermissions))
+ {
+ // The user isn't allowed to copy/transfer this object, so it will not be included in the OAR.
+ ++numObjectsSkippedPermissions;
+ }
+ else
+ {
+ sceneObjects.Add(sceneObject);
+ }
+ }
}
}
@@ -159,7 +175,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
{
m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified");
}
-
+
+ if (numObjectsSkippedPermissions > 0)
+ {
+ m_log.DebugFormat(
+ "[ARCHIVER]: {0} scene objects skipped due to lack of permissions",
+ numObjectsSkippedPermissions);
+ }
+
// Make sure that we also request terrain texture assets
RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings;
@@ -210,6 +233,83 @@ namespace OpenSim.Region.CoreModules.World.Archiver
}
}
+ ///
+ /// Checks whether the user has permission to export an object group to an OAR.
+ ///
+ /// The user
+ /// The object group
+ /// Which permissions to check: "C" = Copy, "T" = Transfer
+ /// Whether the user is allowed to export the object to an OAR
+ private bool CanUserArchiveObject(UUID user, SceneObjectGroup objGroup, string checkPermissions)
+ {
+ if (checkPermissions == null)
+ return true;
+
+ IPermissionsModule module = m_scene.RequestModuleInterface();
+ if (module == null)
+ return true; // this shouldn't happen
+
+ // Check whether the user is permitted to export all of the parts in the SOG. If any
+ // part can't be exported then the entire SOG can't be exported.
+
+ bool permitted = true;
+ //int primNumber = 1;
+
+ foreach (SceneObjectPart obj in objGroup.Parts)
+ {
+ uint perm;
+ PermissionClass permissionClass = module.GetPermissionClass(user, obj);
+ switch (permissionClass)
+ {
+ case PermissionClass.Owner:
+ perm = obj.BaseMask;
+ break;
+ case PermissionClass.Group:
+ perm = obj.GroupMask | obj.EveryoneMask;
+ break;
+ case PermissionClass.Everyone:
+ default:
+ perm = obj.EveryoneMask;
+ break;
+ }
+
+ bool canCopy = (perm & (uint)PermissionMask.Copy) != 0;
+ bool canTransfer = (perm & (uint)PermissionMask.Transfer) != 0;
+
+ // Special case: if Everyone can copy the object then this implies it can also be
+ // Transferred.
+ // However, if the user is the Owner then we don't check EveryoneMask, because it seems that the mask
+ // always (incorrectly) includes the Copy bit set in this case. But that's a mistake: the viewer
+ // does NOT show that the object has Everyone-Copy permissions, and doesn't allow it to be copied.
+ if (permissionClass != PermissionClass.Owner)
+ {
+ canTransfer |= (obj.EveryoneMask & (uint)PermissionMask.Copy) != 0;
+ }
+
+
+ bool partPermitted = true;
+ if (checkPermissions.Contains("C") && !canCopy)
+ partPermitted = false;
+ if (checkPermissions.Contains("T") && !canTransfer)
+ partPermitted = false;
+
+ //string name = (objGroup.PrimCount == 1) ? objGroup.Name : string.Format("{0} ({1}/{2})", obj.Name, primNumber, objGroup.PrimCount);
+ //m_log.DebugFormat("[ARCHIVER]: Object permissions: {0}: Base={1:X4}, Owner={2:X4}, Everyone={3:X4}, permissionClass={4}, checkPermissions={5}, canCopy={6}, canTransfer={7}, permitted={8}",
+ // name, obj.BaseMask, obj.OwnerMask, obj.EveryoneMask,
+ // permissionClass, checkPermissions, canCopy, canTransfer, permitted);
+
+ if (!partPermitted)
+ {
+ permitted = false;
+ break;
+ }
+
+ //++primNumber;
+ }
+
+ return permitted;
+ }
+
///
/// Create the control file for the most up to date archive
///
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
index 08eb80cc2e..f44a3bac05 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
@@ -128,6 +128,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
// ops.Add("v|version=", delegate(string v) { options["version"] = v; });
ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; });
+ ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; });
List mainParams = ops.Parse(cmdparams);
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
index b185d9b7e6..e798e5e361 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
@@ -318,6 +318,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary()));
SceneObjectPart part1 = CreateSceneObjectPart1();
+
+ part1.SitTargetOrientation = new Quaternion(0.2f, 0.3f, 0.4f, 0.5f);
+ part1.SitTargetPosition = new Vector3(1, 2, 3);
+
SceneObjectGroup object1 = new SceneObjectGroup(part1);
// Let's put some inventory items into our object
@@ -390,6 +394,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal");
Assert.That(
object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal");
+ Assert.That(object1PartLoaded.SitTargetOrientation, Is.EqualTo(part1.SitTargetOrientation));
+ Assert.That(object1PartLoaded.SitTargetPosition, Is.EqualTo(part1.SitTargetPosition));
TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0];
Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null");
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index fb3228825e..321f6b6c31 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -992,6 +992,11 @@ namespace OpenSim.Region.CoreModules.World.Estate
args.terrainDetail2 = Scene.RegionInfo.RegionSettings.TerrainTexture3;
args.terrainDetail3 = Scene.RegionInfo.RegionSettings.TerrainTexture4;
+// m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 1 {0} for region {1}", args.terrainDetail0, Scene.RegionInfo.RegionName);
+// m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 2 {0} for region {1}", args.terrainDetail1, Scene.RegionInfo.RegionName);
+// m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 3 {0} for region {1}", args.terrainDetail2, Scene.RegionInfo.RegionName);
+// m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 4 {0} for region {1}", args.terrainDetail3, Scene.RegionInfo.RegionName);
+
remoteClient.SendRegionHandshake(Scene.RegionInfo,args);
}
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index afb641fc6d..2e877f0437 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -39,7 +39,7 @@ using OpenSim.Services.Interfaces;
namespace OpenSim.Region.CoreModules.World.Permissions
{
- public class PermissionsModule : IRegionModule
+ public class PermissionsModule : IRegionModule, IPermissionsModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -150,6 +150,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
else
m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks");
+ scene.RegisterModuleInterface(this);
+
//Register functions with Scene External Checks!
m_scene.Permissions.OnBypassPermissions += BypassPermissions;
m_scene.Permissions.OnSetBypassPermissions += SetBypassPermissions;
@@ -574,46 +576,18 @@ namespace OpenSim.Region.CoreModules.World.Permissions
if (objectOwner != UUID.Zero)
objectEveryoneMask |= (uint)PrimFlags.ObjectAnyOwner;
- if (m_bypassPermissions)
- return objectOwnerMask;
+ PermissionClass permissionClass = GetPermissionClass(user, task);
- // Object owners should be able to edit their own content
- if (user == objectOwner)
- return objectOwnerMask;
-
- if (IsFriendWithPerms(user, objectOwner))
+ switch (permissionClass)
{
- return objectOwnerMask;
- }
- // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set
- if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner))
- {
- return objectOwnerMask;
- }
-
- // Admin should be able to edit anything in the sim (including admin objects)
- if (IsAdministrator(user))
- {
- return objectOwnerMask;
- }
-
- // Users should be able to edit what is over their land.
- Vector3 taskPos = task.AbsolutePosition;
- ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y);
- if (parcel != null && parcel.LandData.OwnerID == user && m_ParcelOwnerIsGod)
- {
- // Admin objects should not be editable by the above
- if (!IsAdministrator(objectOwner))
- {
+ case PermissionClass.Owner:
return objectOwnerMask;
- }
+ case PermissionClass.Group:
+ return objectGroupMask | objectEveryoneMask;
+ case PermissionClass.Everyone:
+ default:
+ return objectEveryoneMask;
}
-
- // Group permissions
- if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0))
- return objectGroupMask | objectEveryoneMask;
-
- return objectEveryoneMask;
}
private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask)
@@ -644,6 +618,47 @@ namespace OpenSim.Region.CoreModules.World.Permissions
return objectFlagsMask;
}
+ public PermissionClass GetPermissionClass(UUID user, SceneObjectPart obj)
+ {
+ if (obj == null)
+ return PermissionClass.Everyone;
+
+ if (m_bypassPermissions)
+ return PermissionClass.Owner;
+
+ // Object owners should be able to edit their own content
+ UUID objectOwner = obj.OwnerID;
+ if (user == objectOwner)
+ return PermissionClass.Owner;
+
+ if (IsFriendWithPerms(user, objectOwner))
+ return PermissionClass.Owner;
+
+ // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set
+ if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner))
+ return PermissionClass.Owner;
+
+ // Admin should be able to edit anything in the sim (including admin objects)
+ if (IsAdministrator(user))
+ return PermissionClass.Owner;
+
+ // Users should be able to edit what is over their land.
+ Vector3 taskPos = obj.AbsolutePosition;
+ ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y);
+ if (parcel != null && parcel.LandData.OwnerID == user && m_ParcelOwnerIsGod)
+ {
+ // Admin objects should not be editable by the above
+ if (!IsAdministrator(objectOwner))
+ return PermissionClass.Owner;
+ }
+
+ // Group permissions
+ if ((obj.GroupID != UUID.Zero) && IsGroupMember(obj.GroupID, user, 0))
+ return PermissionClass.Group;
+
+ return PermissionClass.Everyone;
+ }
+
///
/// General permissions checks for any operation involving an object. These supplement more specific checks
/// implemented by callers.
diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
index 59c26e7a69..d1b7dc1b24 100644
--- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
@@ -89,18 +89,13 @@ namespace OpenSim.Region.Framework.Interfaces
ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt);
///
- /// Rez an attachment from user inventory
+ /// Rez an attachment from user inventory and change inventory status to match.
///
- ///
+ ///
///
///
- ///
- /// If true, we also update the user's inventory to show that the attachment is set. If false, we do not.
- /// False is required so that we don't attempt to update information when a user enters a scene with the
- /// attachment already correctly set up in inventory.
- /// The uuid of the scene object that was attached. Null if the scene object could not be found
- ISceneEntity RezSingleAttachmentFromInventory(
- IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus);
+ /// The scene object that was attached. Null if the scene object could not be found
+ ISceneEntity RezSingleAttachmentFromInventory(ScenePresence sp, UUID itemID, uint AttachmentPt);
// Same as above, but also load script states from a separate doc
ISceneEntity RezSingleAttachmentFromInventory(
@@ -146,13 +141,10 @@ namespace OpenSim.Region.Framework.Interfaces
///
void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient);
- ///
- /// Update the user inventory with a changed attachment
+ /// Update the position of an attachment.
///
- ///
- ///
- ///
- ///
- void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID);
+ ///
+ ///
+ void UpdateAttachmentPosition(SceneObjectGroup sog, Vector3 pos);
}
}
diff --git a/OpenSim/Region/Framework/Interfaces/IPermissionsModule.cs b/OpenSim/Region/Framework/Interfaces/IPermissionsModule.cs
new file mode 100644
index 0000000000..1ed978bb44
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IPermissionsModule.cs
@@ -0,0 +1,54 @@
+/*
+ * 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 OpenMetaverse;
+using OpenSim.Region.Framework.Scenes;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ ///
+ /// Which set of permissions a user has.
+ ///
+ public enum PermissionClass
+ {
+ Owner,
+ Group,
+ Everyone
+ };
+
+ public interface IPermissionsModule
+ {
+
+ ///
+ /// Returns the type of permissions that the user has over an object.
+ ///
+ /// The user
+ /// The object
+ /// The type of permissions the user has over the object
+ PermissionClass GetPermissionClass(UUID user, SceneObjectPart obj);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs
index 8913133404..ff39283b25 100644
--- a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs
+++ b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs
@@ -60,6 +60,14 @@ namespace OpenSim.Region.Framework.Interfaces
///
AvatarAppearance Appearance { get; set; }
+ ///
+ /// The AttachmentsModule synchronizes on this to avoid race conditions between commands to add and remove attachments.
+ ///
+ ///
+ /// All add and remove attachment operations must synchronize on this for the lifetime of their operations.
+ ///
+ Object AttachmentsSyncLock { get; }
+
///
/// The scene objects attached to this avatar.
///
diff --git a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs b/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs
index 2397f223b3..e715e706f2 100644
--- a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs
+++ b/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs
@@ -30,12 +30,21 @@ using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.Framework.Interfaces
{
+ ///
+ /// Sends scheduled updates to it's associated ScenePresence.
+ ///
public interface ISceneViewer
{
- void Reset();
+// void Reset();
void Close();
+
+ ///
+ /// Add the part to the queue of parts for which we need to send an update to the client
+ ///
+ ///
void QueuePartForUpdate(SceneObjectPart part);
+
void SendPrimUpdates();
int GetPendingObjectsCount();
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
index 641e226212..7dde586b8c 100644
--- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
@@ -54,5 +54,10 @@ namespace OpenSim.Region.Framework.Interfaces
bool HasScript(UUID itemID, out bool running);
void SaveAllState();
+
+ ///
+ /// Starts the processing threads.
+ ///
+ void StartProcessing();
}
}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 63dd5502c0..c2ec5d01f6 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -57,11 +57,11 @@ namespace OpenSim.Region.Framework.Scenes
protected AsyncInventorySender m_asyncInventorySender;
///
- /// Start all the scripts in the scene which should be started.
+ /// Creates all the scripts in the scene which should be started.
///
public void CreateScriptInstances()
{
- m_log.Info("[PRIM INVENTORY]: Starting scripts in scene");
+ m_log.Info("[PRIM INVENTORY]: Creating scripts in scene");
EntityBase[] entities = Entities.GetEntities();
foreach (EntityBase group in entities)
@@ -74,6 +74,26 @@ namespace OpenSim.Region.Framework.Scenes
}
}
+ ///
+ /// Lets the script engines start processing scripts.
+ ///
+ public void StartScripts()
+ {
+ m_log.Info("[PRIM INVENTORY]: Starting scripts in scene");
+
+ IScriptModule[] engines = RequestModuleInterfaces();
+ if (engines != null)
+ {
+ foreach (IScriptModule engine in engines)
+ {
+ if (engine != null)
+ {
+ engine.StartProcessing();
+ }
+ }
+ }
+ }
+
public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item)
{
IMoneyModule money = RequestModuleInterface();
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index a661ab8b55..c5bb2b285f 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -610,9 +610,42 @@ namespace OpenSim.Region.Framework.Scenes
#region Region Settings
// Load region settings
- m_regInfo.WindlightSettings = SimulationDataService.LoadRegionWindlightSettings(m_regInfo.RegionID);
+ // LoadRegionSettings creates new region settings in persistence if they don't already exist for this region.
+ // However, in this case, the default textures are not set in memory properly, so we need to do it here and
+ // resave.
+ // FIXME: It shouldn't be up to the database plugins to create this data - we should do it when a new
+ // region is set up and avoid these gyrations.
+ RegionSettings rs = simDataService.LoadRegionSettings(m_regInfo.RegionID);
+ bool updatedTerrainTextures = false;
+ if (rs.TerrainTexture1 == UUID.Zero)
+ {
+ rs.TerrainTexture1 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_1;
+ updatedTerrainTextures = true;
+ }
+
+ if (rs.TerrainTexture2 == UUID.Zero)
+ {
+ rs.TerrainTexture2 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_2;
+ updatedTerrainTextures = true;
+ }
+
+ if (rs.TerrainTexture3 == UUID.Zero)
+ {
+ rs.TerrainTexture3 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_3;
+ updatedTerrainTextures = true;
+ }
+
+ if (rs.TerrainTexture4 == UUID.Zero)
+ {
+ rs.TerrainTexture4 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_4;
+ updatedTerrainTextures = true;
+ }
+
+ if (updatedTerrainTextures)
+ rs.Save();
+
+ m_regInfo.RegionSettings = rs;
- m_regInfo.RegionSettings = simDataService.LoadRegionSettings(m_regInfo.RegionID);
if (estateDataService != null)
m_regInfo.EstateSettings = estateDataService.LoadEstateSettings(m_regInfo.RegionID, false);
@@ -645,7 +678,7 @@ namespace OpenSim.Region.Framework.Scenes
EventManager.OnLandObjectRemoved +=
new EventManager.LandObjectRemoved(simDataService.RemoveLandObject);
- m_sceneGraph = new SceneGraph(this, m_regInfo);
+ m_sceneGraph = new SceneGraph(this);
// If the scene graph has an Unrecoverable error, restart this sim.
// Currently the only thing that causes it to happen is two kinds of specific
@@ -1575,7 +1608,9 @@ namespace OpenSim.Region.Framework.Scenes
msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID;
msg.Position = Vector3.Zero;
msg.RegionID = RegionInfo.RegionID.Guid;
- msg.binaryBucket = new byte[0];
+
+ // We must fill in a null-terminated 'empty' string here since bytes[0] will crash viewer 3.
+ msg.binaryBucket = Util.StringToBytes256("\0");
if (ret.Value.count > 1)
msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
else
@@ -2492,14 +2527,16 @@ namespace OpenSim.Region.Framework.Scenes
/// False
public virtual bool IncomingCreateObject(UUID userID, UUID itemID)
{
- //m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID);
-
- ScenePresence sp = GetScenePresence(userID);
- if (sp != null && AttachmentsModule != null)
- {
- uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID);
- AttachmentsModule.RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, attPt);
- }
+ m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID);
+
+ // Commented out since this is as yet unused and is arguably not the appropriate place to do this, as
+ // attachments are being rezzed elsewhere in AddNewClient()
+// ScenePresence sp = GetScenePresence(userID);
+// if (sp != null && AttachmentsModule != null)
+// {
+// uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID);
+// AttachmentsModule.RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, attPt);
+// }
return false;
}
@@ -3272,8 +3309,8 @@ namespace OpenSim.Region.Framework.Scenes
if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
AttachmentsModule.SaveChangedAttachments(avatar);
- if (avatar != null && (!avatar.IsChildAgent))
- avatar.SaveChangedAttachments();
+ if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
+ AttachmentsModule.SaveChangedAttachments(avatar);
ForEachClient(
delegate(IClientAPI client)
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 42e2502e8f..d1ee990fbd 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -83,7 +83,6 @@ namespace OpenSim.Region.Framework.Scenes
protected internal EntityManager Entities = new EntityManager();
- protected RegionInfo m_regInfo;
protected Scene m_parentScene;
protected Dictionary m_updateList = new Dictionary();
protected int m_numRootAgents = 0;
@@ -117,10 +116,9 @@ namespace OpenSim.Region.Framework.Scenes
#endregion
- protected internal SceneGraph(Scene parent, RegionInfo regInfo)
+ protected internal SceneGraph(Scene parent)
{
m_parentScene = parent;
- m_regInfo = regInfo;
}
public PhysicsScene PhysicsScene
@@ -131,7 +129,6 @@ namespace OpenSim.Region.Framework.Scenes
// If we're not doing the initial set
// Then we've got to remove the previous
// event handler
-
if (_PhyScene != null)
_PhyScene.OnPhysicsCrash -= physicsBasedCrash;
@@ -413,12 +410,12 @@ namespace OpenSim.Region.Framework.Scenes
// "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}",
// sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName);
- SceneObjectPart[] children = sceneObject.Parts;
+ SceneObjectPart[] parts = sceneObject.Parts;
// Clamp child prim sizes and add child prims to the m_numPrim count
if (m_parentScene.m_clampPrimSize)
{
- foreach (SceneObjectPart part in children)
+ foreach (SceneObjectPart part in parts)
{
Vector3 scale = part.Shape.Scale;
@@ -432,7 +429,7 @@ namespace OpenSim.Region.Framework.Scenes
part.Shape.Scale = scale;
}
}
- m_numPrim += children.Length;
+ m_numPrim += parts.Length;
sceneObject.AttachToScene(m_parentScene);
@@ -452,15 +449,17 @@ namespace OpenSim.Region.Framework.Scenes
lock (SceneObjectGroupsByFullPartID)
{
- SceneObjectGroupsByFullPartID[sceneObject.UUID] = sceneObject;
- foreach (SceneObjectPart part in children)
+ foreach (SceneObjectPart part in parts)
SceneObjectGroupsByFullPartID[part.UUID] = sceneObject;
}
lock (SceneObjectGroupsByLocalPartID)
{
- SceneObjectGroupsByLocalPartID[sceneObject.LocalId] = sceneObject;
- foreach (SceneObjectPart part in children)
+// m_log.DebugFormat(
+// "[SCENE GRAPH]: Adding scene object {0} {1} {2} to SceneObjectGroupsByLocalPartID in {3}",
+// sceneObject.Name, sceneObject.UUID, sceneObject.LocalId, m_parentScene.RegionInfo.RegionName);
+
+ foreach (SceneObjectPart part in parts)
SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject;
}
@@ -473,6 +472,10 @@ namespace OpenSim.Region.Framework.Scenes
/// true if the object was deleted, false if there was no object to delete
public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked)
{
+// m_log.DebugFormat(
+// "[SCENE GRAPH]: Deleting scene object with uuid {0}, resultOfObjectLinked = {1}",
+// uuid, resultOfObjectLinked);
+
EntityBase entity;
if (!Entities.TryGetValue(uuid, out entity) || (!(entity is SceneObjectGroup)))
return false;
@@ -501,7 +504,6 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectPart[] parts = grp.Parts;
for (int i = 0; i < parts.Length; i++)
SceneObjectGroupsByFullPartID.Remove(parts[i].UUID);
- SceneObjectGroupsByFullPartID.Remove(grp.RootPart.UUID);
}
lock (SceneObjectGroupsByLocalPartID)
@@ -509,7 +511,6 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectPart[] parts = grp.Parts;
for (int i = 0; i < parts.Length; i++)
SceneObjectGroupsByLocalPartID.Remove(parts[i].LocalId);
- SceneObjectGroupsByLocalPartID.Remove(grp.RootPart.LocalId);
}
return Entities.Remove(uuid);
@@ -654,7 +655,7 @@ namespace OpenSim.Region.Framework.Scenes
ScenePresence newAvatar = null;
// ScenePresence always defaults to child agent
- newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance, type);
+ newAvatar = new ScenePresence(client, m_parentScene, appearance, type);
AddScenePresence(newAvatar);
@@ -721,7 +722,7 @@ namespace OpenSim.Region.Framework.Scenes
if (!Entities.Remove(agentID))
{
m_log.WarnFormat(
- "[SCENEGRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene Entities list",
+ "[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene Entities list",
agentID);
}
@@ -745,7 +746,7 @@ namespace OpenSim.Region.Framework.Scenes
}
else
{
- m_log.WarnFormat("[SCENEGRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
+ m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
}
}
finally
@@ -956,7 +957,8 @@ namespace OpenSim.Region.Framework.Scenes
if (Entities.TryGetValue(localID, out entity))
return entity as SceneObjectGroup;
- //m_log.DebugFormat("Entered GetGroupByPrim with localID {0}", localID);
+// m_log.DebugFormat("[SCENE GRAPH]: Entered GetGroupByPrim with localID {0}", localID);
+
SceneObjectGroup sog;
lock (SceneObjectGroupsByLocalPartID)
SceneObjectGroupsByLocalPartID.TryGetValue(localID, out sog);
@@ -964,8 +966,24 @@ namespace OpenSim.Region.Framework.Scenes
if (sog != null)
{
if (sog.HasChildPrim(localID))
+ {
+// m_log.DebugFormat(
+// "[SCENE GRAPH]: Found scene object {0} {1} {2} containing part with local id {3} in {4}. Returning.",
+// sog.Name, sog.UUID, sog.LocalId, localID, m_parentScene.RegionInfo.RegionName);
+
return sog;
- SceneObjectGroupsByLocalPartID.Remove(localID);
+ }
+ else
+ {
+ lock (SceneObjectGroupsByLocalPartID)
+ {
+ m_log.WarnFormat(
+ "[SCENE GRAPH]: Found scene object {0} {1} {2} via SceneObjectGroupsByLocalPartID index but it doesn't contain part with local id {3}. Removing from entry from index in {4}.",
+ sog.Name, sog.UUID, sog.LocalId, localID, m_parentScene.RegionInfo.RegionName);
+
+ SceneObjectGroupsByLocalPartID.Remove(localID);
+ }
+ }
}
EntityBase[] entityList = GetEntities();
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
index 9f0ac4fa34..6bd9183cb3 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
@@ -388,5 +388,18 @@ namespace OpenSim.Region.Framework.Scenes
for (int i = 0; i < parts.Length; i++)
parts[i].Inventory.ResumeScripts();
}
+
+ ///
+ /// Returns true if any part in the scene object contains scripts, false otherwise.
+ ///
+ ///
+ public bool ContainsScripts()
+ {
+ foreach (SceneObjectPart part in Parts)
+ if (part.Inventory.ContainsScripts())
+ return true;
+
+ return false;
+ }
}
}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 1f0840d88c..f6b690c4a3 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -1239,10 +1239,15 @@ namespace OpenSim.Region.Framework.Scenes
item.CurrentPermissions = perms;
item.BasePermissions = perms;
}
+
m_inventorySerial++;
HasInventoryChanged = true;
}
+ ///
+ /// Returns true if this part inventory contains any scripts. False otherwise.
+ ///
+ ///
public bool ContainsScripts()
{
foreach (TaskInventoryItem item in m_items.Values)
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 35a8df7d01..7a86f9867b 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -124,6 +124,8 @@ namespace OpenSim.Region.Framework.Scenes
protected List m_attachments = new List();
+ public Object AttachmentsSyncLock { get; private set; }
+
private Dictionary scriptedcontrols = new Dictionary();
private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO;
private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO;
@@ -199,7 +201,6 @@ namespace OpenSim.Region.Framework.Scenes
private float m_health = 100f;
- protected RegionInfo m_regionInfo;
protected ulong crossingFromRegion;
private readonly Vector3[] Dir_Vectors = new Vector3[11];
@@ -770,23 +771,24 @@ namespace OpenSim.Region.Framework.Scenes
#endregion
#region Constructor(s)
-
+
public ScenePresence(
- IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance, PresenceType type)
+ IClientAPI client, Scene world, AvatarAppearance appearance, PresenceType type)
{
+ AttachmentsSyncLock = new Object();
+
m_sendCourseLocationsMethod = SendCoarseLocationsDefault;
m_sceneViewer = new SceneViewer(this);
m_animator = new ScenePresenceAnimator(this);
PresenceType = type;
m_DrawDistance = world.DefaultDrawDistance;
- m_rootRegionHandle = reginfo.RegionHandle;
+ m_rootRegionHandle = world.RegionInfo.RegionHandle;
m_controllingClient = client;
m_firstname = m_controllingClient.FirstName;
m_lastname = m_controllingClient.LastName;
m_name = String.Format("{0} {1}", m_firstname, m_lastname);
m_scene = world;
m_uuid = client.AgentId;
- m_regionInfo = reginfo;
m_localId = m_scene.AllocateLocalId();
UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
@@ -1302,7 +1304,7 @@ namespace OpenSim.Region.Framework.Scenes
//m_log.DebugFormat("Completed movement");
- m_controllingClient.MoveAgentIntoRegion(m_regionInfo, AbsolutePosition, look);
+ m_controllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
SendInitialData();
// Create child agents in neighbouring regions
@@ -3226,8 +3228,8 @@ namespace OpenSim.Region.Framework.Scenes
///
protected int HaveNeighbor(Cardinals car, ref int[] fix)
{
- uint neighbourx = m_regionInfo.RegionLocX;
- uint neighboury = m_regionInfo.RegionLocY;
+ uint neighbourx = m_scene.RegionInfo.RegionLocX;
+ uint neighboury = m_scene.RegionInfo.RegionLocY;
int dir = (int)car;
@@ -3247,8 +3249,8 @@ namespace OpenSim.Region.Framework.Scenes
if (neighbourRegion == null)
{
- fix[0] = (int)(m_regionInfo.RegionLocX - neighbourx);
- fix[1] = (int)(m_regionInfo.RegionLocY - neighboury);
+ fix[0] = (int)(m_scene.RegionInfo.RegionLocX - neighbourx);
+ fix[1] = (int)(m_scene.RegionInfo.RegionLocY - neighboury);
return dir * (-1);
}
else
@@ -3494,26 +3496,30 @@ namespace OpenSim.Region.Framework.Scenes
catch { }
// Attachment objects
- if (m_attachments != null && m_attachments.Count > 0)
+ lock (m_attachments)
{
- cAgent.AttachmentObjects = new List();
- cAgent.AttachmentObjectStates = new List();
-// IScriptModule se = m_scene.RequestModuleInterface();
- m_InTransitScriptStates.Clear();
- foreach (SceneObjectGroup sog in m_attachments)
+ if (m_attachments.Count > 0)
{
- // We need to make a copy and pass that copy
- // because of transfers withn the same sim
- ISceneObject clone = sog.CloneForNewScene();
- // Attachment module assumes that GroupPosition holds the offsets...!
- ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
- ((SceneObjectGroup)clone).IsAttachment = false;
- cAgent.AttachmentObjects.Add(clone);
- string state = sog.GetStateSnapshot();
- cAgent.AttachmentObjectStates.Add(state);
- m_InTransitScriptStates.Add(state);
- // Let's remove the scripts of the original object here
- sog.RemoveScriptInstances(true);
+ cAgent.AttachmentObjects = new List();
+ cAgent.AttachmentObjectStates = new List();
+ // IScriptModule se = m_scene.RequestModuleInterface();
+ m_InTransitScriptStates.Clear();
+
+ foreach (SceneObjectGroup sog in m_attachments)
+ {
+ // We need to make a copy and pass that copy
+ // because of transfers withn the same sim
+ ISceneObject clone = sog.CloneForNewScene();
+ // Attachment module assumes that GroupPosition holds the offsets...!
+ ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
+ ((SceneObjectGroup)clone).IsAttachment = false;
+ cAgent.AttachmentObjects.Add(clone);
+ string state = sog.GetStateSnapshot();
+ cAgent.AttachmentObjectStates.Add(state);
+ m_InTransitScriptStates.Add(state);
+ // Let's remove the scripts of the original object here
+ sog.RemoveScriptInstances(true);
+ }
}
}
}
@@ -3931,7 +3937,8 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
public void Close()
{
- m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false);
+ if (!IsChildAgent)
+ m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false);
lock (m_knownChildRegions)
{
@@ -4035,8 +4042,13 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
m_attachments.Clear();
}
+ ///
+ /// This is currently just being done for information.
+ ///
public bool ValidateAttachments()
{
+ bool validated = true;
+
lock (m_attachments)
{
// Validate
@@ -4045,21 +4057,22 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
if (gobj == null)
{
m_log.WarnFormat(
- "[SCENE PRESENCE]: Failed to validate an attachment for {0} since it was null", Name);
- return false;
- }
+ "[SCENE PRESENCE]: Failed to validate an attachment for {0} since it was null. Continuing", Name);
- if (gobj.IsDeleted)
+ validated = false;
+ }
+ else if (gobj.IsDeleted)
{
m_log.WarnFormat(
- "[SCENE PRESENCE]: Failed to validate attachment {0} {1} for {2} since it had been deleted",
+ "[SCENE PRESENCE]: Failed to validate attachment {0} {1} for {2} since it had been deleted. Continuing",
gobj.Name, gobj.UUID, Name);
- return false;
+
+ validated = false;
}
}
}
- return true;
+ return validated;
}
///
@@ -4091,29 +4104,6 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
}
}
-
- public void initializeScenePresence(IClientAPI client, RegionInfo region, Scene scene)
- {
- m_controllingClient = client;
- m_regionInfo = region;
- m_scene = scene;
-
- RegisterToEvents();
-
- /*
- AbsolutePosition = client.StartPos;
-
- Animations = new AvatarAnimations();
- Animations.LoadAnims();
-
- m_animations = new List();
- m_animations.Add(Animations.AnimsUUID["STAND"]);
- m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber);
-
- SetDirectionVectors();
- */
- }
-
internal void PushForce(Vector3 impulse)
{
if (PhysicsActor != null)
@@ -4141,6 +4131,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
obj.ignoreControls = (ScriptControlled)controls;
obj.eventControls = (ScriptControlled)controls;
}
+
if (pass_on == 1 && accept == 1)
{
IgnoredControls = ScriptControlled.CONTROL_ZERO;
@@ -4161,6 +4152,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
scriptedcontrols[Script_item_UUID] = obj;
}
}
+
ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true);
}
@@ -4351,29 +4343,6 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
return(new Vector3(x,y,z));
}
- public void SaveChangedAttachments()
- {
- // Need to copy this list because DetachToInventoryPrep mods it
- List attachments = new List(GetAttachments().ToArray());
-
- IAttachmentsModule attachmentsModule = m_scene.AttachmentsModule;
- if (attachmentsModule != null)
- {
- foreach (SceneObjectGroup grp in attachments)
- {
- if (grp.HasGroupChanged) // Resizer scripts?
- {
- grp.IsAttachment = false;
- grp.AbsolutePosition = grp.RootPart.AttachedPos;
-// grp.DetachToInventoryPrep();
- attachmentsModule.UpdateKnownItem(ControllingClient,
- grp, grp.GetFromItemID(), grp.OwnerID);
- grp.IsAttachment = true;
- }
- }
- }
- }
-
private void CheckLandingPoint(ref Vector3 pos)
{
// Never constrain lures
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
index 501487aac9..8a0d288aaf 100644
--- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
@@ -38,27 +38,42 @@ namespace OpenSim.Region.Framework.Scenes
{
public class SceneViewer : ISceneViewer
{
+ ///
+ /// Is this scene viewer enabled?
+ ///
+ private bool IsEnabled { get; set; }
+
+ ///
+ /// The scene presence serviced by this viewer.
+ ///
protected ScenePresence m_presence;
+
+ ///
+ /// The queue of parts for which we need to send out updates.
+ ///
protected UpdateQueue m_partsUpdateQueue = new UpdateQueue();
+
+ ///
+ /// The queue of objects for which we need to send out updates.
+ ///
protected Queue m_pendingObjects;
+ ///
+ /// The last update assocated with a given part update.
+ ///
protected Dictionary m_updateTimes = new Dictionary();
- public SceneViewer()
- {
- }
-
public SceneViewer(ScenePresence presence)
{
m_presence = presence;
+ IsEnabled = true;
}
- ///
- /// Add the part to the queue of parts for which we need to send an update to the client
- ///
- ///
public void QueuePartForUpdate(SceneObjectPart part)
{
+ if (!IsEnabled)
+ return;
+
lock (m_partsUpdateQueue)
{
m_partsUpdateQueue.Enqueue(part);
@@ -87,6 +102,11 @@ namespace OpenSim.Region.Framework.Scenes
lock (m_pendingObjects)
{
+ // We must do this under lock so that we don't suffer a race condition if another thread closes the
+ // viewer
+ if (!IsEnabled)
+ return;
+
while (m_pendingObjects != null && m_pendingObjects.Count > 0)
{
SceneObjectGroup g = m_pendingObjects.Dequeue();
@@ -119,7 +139,6 @@ namespace OpenSim.Region.Framework.Scenes
// We deal with the possibility that two updates occur at
// the same unix time at the update point itself.
-
if ((update.LastFullUpdateTime < part.TimeStampFull) || part.ParentGroup.IsAttachment)
{
// m_log.DebugFormat(
@@ -135,9 +154,7 @@ namespace OpenSim.Region.Framework.Scenes
// this update. If this happened, then subsequent
// updates which occurred on the same tick or the
// next tick of the last update would be ignored.
-
update.LastFullUpdateTime = part.TimeStampFull;
-
}
else if (update.LastTerseUpdateTime <= part.TimeStampTerse)
{
@@ -176,38 +193,46 @@ namespace OpenSim.Region.Framework.Scenes
}
}
- public void Reset()
- {
- if (m_pendingObjects == null)
- return;
-
- lock (m_pendingObjects)
- {
- if (m_pendingObjects != null)
- {
- m_pendingObjects.Clear();
- m_pendingObjects = null;
- }
- }
- }
+// public void Reset()
+// {
+// if (m_pendingObjects == null)
+// return;
+//
+// lock (m_pendingObjects)
+// {
+// if (m_pendingObjects != null)
+// {
+// m_pendingObjects.Clear();
+// m_pendingObjects = null;
+// }
+// }
+// }
public void Close()
{
- lock (m_updateTimes)
+ lock (m_pendingObjects)
{
- m_updateTimes.Clear();
+ // We perform this under the m_pendingObjects lock in order to avoid a race condition with another
+ // thread on SendPrimUpdates()
+ IsEnabled = false;
+
+ lock (m_updateTimes)
+ {
+ m_updateTimes.Clear();
+ }
+
+ lock (m_partsUpdateQueue)
+ {
+ m_partsUpdateQueue.Clear();
+ }
}
- lock (m_partsUpdateQueue)
- {
- m_partsUpdateQueue.Clear();
- }
- Reset();
}
public int GetPendingObjectsCount()
{
if (m_pendingObjects != null)
- return m_pendingObjects.Count;
+ lock (m_pendingObjects)
+ return m_pendingObjects.Count;
return 0;
}
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
index 1ea2329b36..80f198d2d6 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
@@ -52,22 +52,25 @@ namespace OpenSim.Region.Framework.Scenes.Tests
TestHelpers.InMethod();
Scene scene = SceneHelpers.SetupScene();
+ int partsToTestCount = 3;
- string objName = "obj1";
- UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001");
+ SceneObjectGroup so
+ = SceneHelpers.CreateSceneObject(partsToTestCount, TestHelpers.ParseTail(0x1), "obj1", 0x10);
+ SceneObjectPart[] parts = so.Parts;
- SceneObjectPart part
- = new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero)
- { Name = objName, UUID = objUuid };
-
- Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part), false), Is.True);
-
- SceneObjectPart retrievedPart = scene.GetSceneObjectPart(objUuid);
+ Assert.That(scene.AddNewSceneObject(so, false), Is.True);
+ SceneObjectGroup retrievedSo = scene.GetSceneObjectGroup(so.UUID);
+ SceneObjectPart[] retrievedParts = retrievedSo.Parts;
//m_log.Debug("retrievedPart : {0}", retrievedPart);
// If the parts have the same UUID then we will consider them as one and the same
- Assert.That(retrievedPart.Name, Is.EqualTo(objName));
- Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid));
+ Assert.That(retrievedSo.PrimCount, Is.EqualTo(partsToTestCount));
+
+ for (int i = 0; i < partsToTestCount; i++)
+ {
+ Assert.That(retrievedParts[i].Name, Is.EqualTo(parts[i].Name));
+ Assert.That(retrievedParts[i].UUID, Is.EqualTo(parts[i].UUID));
+ }
}
[Test]
@@ -103,6 +106,39 @@ namespace OpenSim.Region.Framework.Scenes.Tests
Assert.That(retrievedPart.Name, Is.EqualTo(obj1Name));
Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid));
}
+
+ ///
+ /// Test retrieving a scene object via the local id of one of its parts.
+ ///
+ [Test]
+ public void TestGetSceneObjectByPartLocalId()
+ {
+ TestHelpers.InMethod();
+
+ Scene scene = SceneHelpers.SetupScene();
+ int partsToTestCount = 3;
+
+ SceneObjectGroup so
+ = SceneHelpers.CreateSceneObject(partsToTestCount, TestHelpers.ParseTail(0x1), "obj1", 0x10);
+ SceneObjectPart[] parts = so.Parts;
+
+ scene.AddNewSceneObject(so, false);
+
+ // Test getting via the root part's local id
+ Assert.That(scene.GetGroupByPrim(so.LocalId), Is.Not.Null);
+
+ // Test getting via a non root part's local id
+ Assert.That(scene.GetGroupByPrim(parts[partsToTestCount - 1].LocalId), Is.Not.Null);
+
+ // Test that we don't get back an object for a local id that doesn't exist
+ Assert.That(scene.GetGroupByPrim(999), Is.Null);
+
+ // Now delete the scene object and check again
+ scene.DeleteSceneObject(so, false);
+
+ Assert.That(scene.GetGroupByPrim(so.LocalId), Is.Null);
+ Assert.That(scene.GetGroupByPrim(parts[partsToTestCount - 1].LocalId), Is.Null);
+ }
///
/// Test deleting an object from a scene.
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index fdfbc7853f..8d41f000a8 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -43,11 +43,12 @@ namespace OpenSim.Region.Framework.Scenes
///
/// Gather uuids for a given entity.
///
- ///
+ ///
/// This does a deep inspection of the entity to retrieve all the assets it uses (whether as textures, as scripts
/// contained in inventory, as scripts contained in objects contained in another object's inventory, etc. Assets
/// are only retrieved when they are necessary to carry out the inspection (i.e. a serialized object needs to be
/// retrieved to work out which assets it references).
+ ///
public class UuidGatherer
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -76,11 +77,11 @@ namespace OpenSim.Region.Framework.Scenes
///
/// Gather all the asset uuids associated with the asset referenced by a given uuid
///
- ///
+ ///
/// This includes both those directly associated with
/// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
/// within this object).
- ///
+ ///
/// The uuid of the asset for which to gather referenced assets
/// The type of the asset for the uuid given
/// The assets gathered
@@ -119,11 +120,11 @@ namespace OpenSim.Region.Framework.Scenes
///
/// Gather all the asset uuids associated with a given object.
///
- ///
+ ///
/// This includes both those directly associated with
/// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
/// within this object).
- ///
+ ///
/// The scene object for which to gather assets
/// The assets gathered
public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary assetUuids)
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
index 78296a4e1f..246bc34219 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
@@ -26,6 +26,7 @@
*/
using System;
+using System.Collections.Generic;
using System.Reflection;
using log4net;
using Nini.Config;
@@ -33,7 +34,9 @@ using NUnit.Framework;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Communications;
+using OpenSim.Region.CoreModules.Avatar.Attachments;
using OpenSim.Region.CoreModules.Avatar.AvatarFactory;
+using OpenSim.Region.CoreModules.Framework.InventoryAccess;
using OpenSim.Region.CoreModules.Framework.UserManagement;
using OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar;
using OpenSim.Region.Framework.Interfaces;
@@ -47,21 +50,49 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
[TestFixture]
public class NPCModuleTests
{
+ private TestScene scene;
+ private AvatarFactoryModule afm;
+ private UserManagementModule umm;
+ private AttachmentsModule am;
+
+ [TestFixtureSetUp]
+ public void FixtureInit()
+ {
+ // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
+ Util.FireAndForgetMethod = FireAndForgetMethod.None;
+ }
+
+ [TestFixtureTearDown]
+ public void TearDown()
+ {
+ // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
+ // threads. Possibly, later tests should be rewritten not to worry about such things.
+ Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
+ }
+
+ [SetUp]
+ public void Init()
+ {
+ IConfigSource config = new IniConfigSource();
+ config.AddConfig("NPC");
+ config.Configs["NPC"].Set("Enabled", "true");
+ config.AddConfig("Modules");
+ config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
+
+ afm = new AvatarFactoryModule();
+ umm = new UserManagementModule();
+ am = new AttachmentsModule();
+
+ scene = SceneHelpers.SetupScene();
+ SceneHelpers.SetupSceneModules(scene, config, afm, umm, am, new BasicInventoryAccessModule(), new NPCModule());
+ }
+
[Test]
public void TestCreate()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
- IConfigSource config = new IniConfigSource();
- config.AddConfig("NPC");
- config.Configs["NPC"].Set("Enabled", "true");
-
- AvatarFactoryModule afm = new AvatarFactoryModule();
- UserManagementModule umm = new UserManagementModule();
-
- TestScene scene = SceneHelpers.SetupScene();
- SceneHelpers.SetupSceneModules(scene, config, afm, umm, new NPCModule());
ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
@@ -87,19 +118,54 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
Assert.That(umm.GetUserName(npc.UUID), Is.EqualTo(string.Format("{0} {1}", npc.Firstname, npc.Lastname)));
}
+ [Test]
+ public void TestAttachments()
+ {
+ TestHelpers.InMethod();
+// log4net.Config.XmlConfigurator.Configure();
+
+ UUID userId = TestHelpers.ParseTail(0x1);
+ UserAccountHelpers.CreateUserWithInventory(scene, userId);
+ ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId);
+
+ UUID attItemId = TestHelpers.ParseTail(0x2);
+ UUID attAssetId = TestHelpers.ParseTail(0x3);
+ string attName = "att";
+
+ UserInventoryHelpers.CreateInventoryItem(
+ scene, attName, attItemId, attAssetId, sp.UUID, InventoryType.Object);
+
+ am.RezSingleAttachmentFromInventory(
+ sp.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
+
+ INPCModule npcModule = scene.RequestModuleInterface();
+ UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, sp.Appearance);
+
+ ScenePresence npc = scene.GetScenePresence(npcId);
+
+ // Check scene presence status
+ Assert.That(npc.HasAttachments(), Is.True);
+ List attachments = npc.GetAttachments();
+ Assert.That(attachments.Count, Is.EqualTo(1));
+ SceneObjectGroup attSo = attachments[0];
+
+ // Just for now, we won't test the name since this is (wrongly) the asset part name rather than the item
+ // name. TODO: Do need to fix ultimately since the item may be renamed before being passed on to an NPC.
+// Assert.That(attSo.Name, Is.EqualTo(attName));
+
+ Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
+ Assert.That(attSo.IsAttachment);
+ Assert.That(attSo.UsesPhysics, Is.False);
+ Assert.That(attSo.IsTemporary, Is.False);
+ Assert.That(attSo.OwnerID, Is.EqualTo(npc.UUID));
+ }
+
[Test]
public void TestMove()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
- IConfigSource config = new IniConfigSource();
-
- config.AddConfig("NPC");
- config.Configs["NPC"].Set("Enabled", "true");
-
- TestScene scene = SceneHelpers.SetupScene();
- SceneHelpers.SetupSceneModules(scene, config, new NPCModule());
ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 6f341681e0..18c0dd29dc 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -7040,6 +7040,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
{
+ float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
return shapeBlock;
@@ -7123,8 +7124,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
twist.y = 1.0f;
}
- shapeBlock.PathTwistBegin = (sbyte)(100 * twist.x);
- shapeBlock.PathTwist = (sbyte)(100 * twist.y);
+ // A fairly large precision error occurs for some calculations,
+ // if a float or double is directly cast to a byte or sbyte
+ // variable, in both .Net and Mono. In .Net, coding
+ // "(sbyte)(float)(some expression)" corrects the precision
+ // errors. But this does not work for Mono. This longer coding
+ // form of creating a tempoary float variable from the
+ // expression first, then casting that variable to a byte or
+ // sbyte, works for both .Net and Mono. These types of
+ // assignments occur in SetPrimtiveBlockShapeParams and
+ // SetPrimitiveShapeParams in support of llSetPrimitiveParams.
+ tempFloat = (float)(100.0d * twist.x);
+ shapeBlock.PathTwistBegin = (sbyte)tempFloat;
+ tempFloat = (float)(100.0d * twist.y);
+ shapeBlock.PathTwist = (sbyte)tempFloat;
shapeBlock.ObjectLocalID = part.LocalId;
@@ -7138,6 +7151,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
return;
+ float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
ObjectShapePacket.ObjectDataBlock shapeBlock;
shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7158,8 +7172,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
taper_b.y = 2f;
}
- shapeBlock.PathScaleX = (byte)(100 * (2.0 - taper_b.x));
- shapeBlock.PathScaleY = (byte)(100 * (2.0 - taper_b.y));
+ tempFloat = (float)(100.0d * (2.0d - taper_b.x));
+ shapeBlock.PathScaleX = (byte)tempFloat;
+ tempFloat = (float)(100.0d * (2.0d - taper_b.y));
+ shapeBlock.PathScaleY = (byte)tempFloat;
if (topshear.x < -0.5f)
{
topshear.x = -0.5f;
@@ -7176,8 +7192,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
topshear.y = 0.5f;
}
- shapeBlock.PathShearX = (byte)(100 * topshear.x);
- shapeBlock.PathShearY = (byte)(100 * topshear.y);
+ tempFloat = (float)(100.0d * topshear.x);
+ shapeBlock.PathShearX = (byte)tempFloat;
+ tempFloat = (float)(100.0d * topshear.y);
+ shapeBlock.PathShearY = (byte)tempFloat;
part.Shape.SculptEntry = false;
part.UpdateShape(shapeBlock);
@@ -7233,6 +7251,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
return;
+ float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
ObjectShapePacket.ObjectDataBlock shapeBlock;
shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7257,8 +7276,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
holesize.y = 0.5f;
}
- shapeBlock.PathScaleX = (byte)(100 * (2 - holesize.x));
- shapeBlock.PathScaleY = (byte)(100 * (2 - holesize.y));
+ tempFloat = (float)(100.0d * (2.0d - holesize.x));
+ shapeBlock.PathScaleX = (byte)tempFloat;
+ tempFloat = (float)(100.0d * (2.0d - holesize.y));
+ shapeBlock.PathScaleY = (byte)tempFloat;
if (topshear.x < -0.5f)
{
topshear.x = -0.5f;
@@ -7275,8 +7296,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
topshear.y = 0.5f;
}
- shapeBlock.PathShearX = (byte)(100 * topshear.x);
- shapeBlock.PathShearY = (byte)(100 * topshear.y);
+ tempFloat = (float)(100.0d * topshear.x);
+ shapeBlock.PathShearX = (byte)tempFloat;
+ tempFloat = (float)(100.0d * topshear.y);
+ shapeBlock.PathShearY = (byte)tempFloat;
if (profilecut.x < 0f)
{
profilecut.x = 0f;
@@ -7320,8 +7343,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
taper_a.y = 1f;
}
- shapeBlock.PathTaperX = (sbyte)(100 * taper_a.x);
- shapeBlock.PathTaperY = (sbyte)(100 * taper_a.y);
+ tempFloat = (float)(100.0d * taper_a.x);
+ shapeBlock.PathTaperX = (sbyte)tempFloat;
+ tempFloat = (float)(100.0d * taper_a.y);
+ shapeBlock.PathTaperY = (sbyte)tempFloat;
if (revolutions < 1f)
{
revolutions = 1f;
@@ -7330,7 +7355,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
revolutions = 4f;
}
- shapeBlock.PathRevolutions = (byte)(66.666667 * (revolutions - 1.0));
+ tempFloat = 66.66667f * (revolutions - 1.0f);
+ shapeBlock.PathRevolutions = (byte)tempFloat;
// limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1
if (radiusoffset < 0f)
{
@@ -7340,7 +7366,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
radiusoffset = 1f;
}
- shapeBlock.PathRadiusOffset = (sbyte)(100 * radiusoffset);
+ tempFloat = 100.0f * radiusoffset;
+ shapeBlock.PathRadiusOffset = (sbyte)tempFloat;
if (skew < -0.95f)
{
skew = -0.95f;
@@ -7349,7 +7376,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
skew = 0.95f;
}
- shapeBlock.PathSkew = (sbyte)(100 * skew);
+ tempFloat = 100.0f * skew;
+ shapeBlock.PathSkew = (sbyte)tempFloat;
part.Shape.SculptEntry = false;
part.UpdateShape(shapeBlock);
@@ -8268,10 +8296,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0));
// float revolutions
- res.Add(new LSL_Float((Shape.PathRevolutions * 0.015) + 1.0)); // Slightly inaccurate, because an unsigned
- // byte is being used to represent the entire
- // range of floating-point values from 1.0
- // through 4.0 (which is how SL does it).
+ res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d);
+ // Slightly inaccurate, because an unsigned byte is being used to represent
+ // the entire range of floating-point values from 1.0 through 4.0 (which is how
+ // SL does it).
+ //
+ // Using these formulas to store and retrieve PathRevolutions, it is not
+ // possible to use all values between 1.00 and 4.00. For instance, you can't
+ // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you
+ // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them
+ // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar
+ // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11.
+ // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value
+ // such as 1.10. So, SL must store and retreive the actual user input rather
+ // than only storing the encoded value.
// float radiusoffset
res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0));
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 0c1da47f24..8f450f8988 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -712,9 +712,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
== World.LandChannel.GetLandObject(
presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
{
- World.RequestTeleportLocation(presence.ControllingClient, regionName,
- new Vector3((float)position.x, (float)position.y, (float)position.z),
- new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation);
+ // We will launch the teleport on a new thread so that when the script threads are terminated
+ // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
+ Util.FireAndForget(
+ o => World.RequestTeleportLocation(presence.ControllingClient, regionName,
+ new Vector3((float)position.x, (float)position.y, (float)position.z),
+ new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation));
ScriptSleep(5000);
}
@@ -750,9 +753,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
== World.LandChannel.GetLandObject(
presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
{
- World.RequestTeleportLocation(presence.ControllingClient, regionHandle,
- new Vector3((float)position.x, (float)position.y, (float)position.z),
- new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation);
+ // We will launch the teleport on a new thread so that when the script threads are terminated
+ // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
+ Util.FireAndForget(
+ o => World.RequestTeleportLocation(presence.ControllingClient, regionHandle,
+ new Vector3((float)position.x, (float)position.y, (float)position.z),
+ new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation));
+
ScriptSleep(5000);
}
}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
index 8cd1e84623..0cbad418bd 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
@@ -49,7 +49,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6;
private const double VECTOR_COMPONENT_ACCURACY = 0.0000005d;
- private const double FLOAT_ACCURACY = 0.00005d;
+ private const float FLOAT_ACCURACY = 0.00005f;
private LSL_Api m_lslApi;
[SetUp]
@@ -194,10 +194,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
ScriptBaseClass.PRIM_TYPE_SPHERE, // Prim type
ScriptBaseClass.PRIM_HOLE_DEFAULT, // Prim hole type
new LSL_Types.Vector3(0.0d, 0.075d, 0.0d), // Prim cut
- 0.80d, // Prim hollow
+ 0.80f, // Prim hollow
new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist
new LSL_Types.Vector3(0.32d, 0.76d, 0.0d), // Prim dimple
- 0.80d); // Prim hollow check
+ 0.80f); // Prim hollow check
// Test a prism.
CheckllSetPrimitiveParams(
@@ -206,11 +206,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type
ScriptBaseClass.PRIM_HOLE_CIRCLE, // Prim hole type
new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
- 0.90d, // Prim hollow
+ 0.90f, // Prim hollow
new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist
new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper
new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
- 0.90d); // Prim hollow check
+ 0.90f); // Prim hollow check
// Test a box.
CheckllSetPrimitiveParams(
@@ -219,11 +219,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
ScriptBaseClass.PRIM_TYPE_BOX, // Prim type
ScriptBaseClass.PRIM_HOLE_TRIANGLE, // Prim hole type
new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
- 0.95d, // Prim hollow
+ 0.95f, // Prim hollow
new LSL_Types.Vector3(1.0d, 0.0d, 0.0d), // Prim twist
new LSL_Types.Vector3(1.0d, 1.0d, 0.0d), // Prim taper
new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
- 0.95d); // Prim hollow check
+ 0.95f); // Prim hollow check
// Test a tube.
CheckllSetPrimitiveParams(
@@ -232,16 +232,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
ScriptBaseClass.PRIM_TYPE_TUBE, // Prim type
ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type
new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
- 0.00d, // Prim hollow
+ 0.00f, // Prim hollow
new LSL_Types.Vector3(1.0d, -1.0d, 0.0d), // Prim twist
- new LSL_Types.Vector3(1.0d, 0.5d, 0.0d), // Prim hole size
- new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
+ new LSL_Types.Vector3(1.0d, 0.05d, 0.0d), // Prim hole size
+ // Expression for y selected to test precision problems during byte
+ // cast in SetPrimitiveShapeParams.
+ new LSL_Types.Vector3(0.0d, 0.35d + 0.1d, 0.0d), // Prim shear
new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim profile cut
- new LSL_Types.Vector3(-1.0d, 1.0d, 0.0d), // Prim taper
- 1.0d, // Prim revolutions
- 1.0d, // Prim radius
- 0.0d, // Prim skew
- 0.00d); // Prim hollow check
+ // Expression for y selected to test precision problems during sbyte
+ // cast in SetPrimitiveShapeParams.
+ new LSL_Types.Vector3(-1.0d, 0.70d + 0.1d + 0.1d, 0.0d), // Prim taper
+ 1.11f, // Prim revolutions
+ 0.88f, // Prim radius
+ 0.95f, // Prim skew
+ 0.00f); // Prim hollow check
// Test a prism.
CheckllSetPrimitiveParams(
@@ -250,11 +254,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type
ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type
new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
- 0.95d, // Prim hollow
- new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist
- new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper
+ 0.95f, // Prim hollow
+ // Expression for x selected to test precision problems during sbyte
+ // cast in SetPrimitiveShapeBlockParams.
+ new LSL_Types.Vector3(0.7d + 0.2d, 0.0d, 0.0d), // Prim twist
+ // Expression for y selected to test precision problems during sbyte
+ // cast in SetPrimitiveShapeParams.
+ new LSL_Types.Vector3(2.0d, (1.3d + 0.1d), 0.0d), // Prim taper
new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
- 0.70d); // Prim hollow check
+ 0.70f); // Prim hollow check
// Test a sculpted prim.
CheckllSetPrimitiveParams(
@@ -268,8 +276,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
// Set prim params for a box, cylinder or prism and check results.
public void CheckllSetPrimitiveParams(string primTest,
LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
- double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primTaper, LSL_Types.Vector3 primShear,
- double primHollowCheck)
+ float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primTaper, LSL_Types.Vector3 primShear,
+ float primHollowCheck)
{
// Set the prim params.
m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
@@ -297,7 +305,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
// Set prim params for a sphere and check results.
public void CheckllSetPrimitiveParams(string primTest,
LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
- double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primDimple, double primHollowCheck)
+ float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primDimple, float primHollowCheck)
{
// Set the prim params.
m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
@@ -324,9 +332,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
// Set prim params for a torus, tube or ring and check results.
public void CheckllSetPrimitiveParams(string primTest,
LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
- double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primHoleSize,
+ float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primHoleSize,
LSL_Types.Vector3 primShear, LSL_Types.Vector3 primProfCut, LSL_Types.Vector3 primTaper,
- double primRev, double primRadius, double primSkew, double primHollowCheck)
+ float primRev, float primRadius, float primSkew, float primHollowCheck)
{
// Set the prim params.
m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
@@ -353,7 +361,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
CheckllSetPrimitiveParamsVector(primProfCut, m_lslApi.llList2Vector(primParams, 8), primTest + " prim profile cut");
CheckllSetPrimitiveParamsVector(primTaper, m_lslApi.llList2Vector(primParams, 9), primTest + " prim taper");
Assert.AreEqual(primRev, m_lslApi.llList2Float(primParams, 10), FLOAT_ACCURACY,
- "TestllSetPrimitiveParams " + primTest + " prim revolution fail");
+ "TestllSetPrimitiveParams " + primTest + " prim revolutions fail");
Assert.AreEqual(primRadius, m_lslApi.llList2Float(primParams, 11), FLOAT_ACCURACY,
"TestllSetPrimitiveParams " + primTest + " prim radius fail");
Assert.AreEqual(primSkew, m_lslApi.llList2Float(primParams, 12), FLOAT_ACCURACY,
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 9cb074aa72..975e9cca76 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -409,7 +409,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
m_ThreadPool.QueueWorkItem(new WorkItemCallback(this.DoBackup),
new Object[] { m_SaveTime });
}
+ }
+ public void StartProcessing()
+ {
m_ThreadPool.Start();
}
@@ -659,7 +662,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
if (part == null)
{
- m_log.Error("[Script] SceneObjectPart unavailable. Script NOT started.");
+ m_log.ErrorFormat("[Script]: SceneObjectPart with localID {0} unavailable. Script NOT started.", localID);
m_ScriptErrorMessage += "SceneObjectPart unavailable. Script NOT started.\n";
m_ScriptFailCount++;
return false;
diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
index 9c1f1585a1..2c36bf555d 100644
--- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
@@ -439,14 +439,14 @@ namespace OpenSim.Services.Connectors.Hypergrid
}
catch
{
- m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
+ m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for StatusNotification", m_ServerURL);
// reason = "Exception: " + e.Message;
return friendsOnline;
}
if (response.IsFault)
{
- m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
+ m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for StatusNotification returned an error: {1}", m_ServerURL, response.FaultString);
// reason = "XMLRPC Fault";
return friendsOnline;
}
@@ -510,14 +510,14 @@ namespace OpenSim.Services.Connectors.Hypergrid
}
catch
{
- m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
+ m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetOnlineFriends", m_ServerURL);
// reason = "Exception: " + e.Message;
return online;
}
if (response.IsFault)
{
- m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
+ m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetOnlineFriends returned an error: {1}", m_ServerURL, response.FaultString);
// reason = "XMLRPC Fault";
return online;
}
@@ -575,14 +575,14 @@ namespace OpenSim.Services.Connectors.Hypergrid
}
catch
{
- m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
+ m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetServerURLs", m_ServerURL);
// reason = "Exception: " + e.Message;
return serverURLs;
}
if (response.IsFault)
{
- m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
+ m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetServerURLs returned an error: {1}", m_ServerURL, response.FaultString);
// reason = "XMLRPC Fault";
return serverURLs;
}
@@ -639,14 +639,14 @@ namespace OpenSim.Services.Connectors.Hypergrid
}
catch
{
- m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
+ m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for LocateUser", m_ServerURL);
// reason = "Exception: " + e.Message;
return url;
}
if (response.IsFault)
{
- m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
+ m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for LocateUser returned an error: {1}", m_ServerURL, response.FaultString);
// reason = "XMLRPC Fault";
return url;
}
@@ -698,14 +698,14 @@ namespace OpenSim.Services.Connectors.Hypergrid
}
catch
{
- m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
+ m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetUUI", m_ServerURL);
// reason = "Exception: " + e.Message;
return uui;
}
if (response.IsFault)
{
- m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
+ m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetUUI returned an error: {1}", m_ServerURL, response.FaultString);
// reason = "XMLRPC Fault";
return uui;
}
@@ -746,14 +746,14 @@ namespace OpenSim.Services.Connectors.Hypergrid
}
catch (Exception e)
{
- m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
+ m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetBoolResponse", m_ServerURL);
reason = "Exception: " + e.Message;
return false;
}
if (response.IsFault)
{
- m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
+ m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetBoolResponse returned an error: {1}", m_ServerURL, response.FaultString);
reason = "XMLRPC Fault";
return false;
}
diff --git a/OpenSim/Services/Interfaces/IAvatarService.cs b/OpenSim/Services/Interfaces/IAvatarService.cs
index 0d5ab7db2e..cda7113a4f 100644
--- a/OpenSim/Services/Interfaces/IAvatarService.cs
+++ b/OpenSim/Services/Interfaces/IAvatarService.cs
@@ -262,7 +262,6 @@ namespace OpenSim.Services.Interfaces
UUID.Parse(Data["SkirtItem"]),
UUID.Parse(Data["SkirtAsset"]));
-
if (Data.ContainsKey("VisualParams"))
{
string[] vps = Data["VisualParams"].Split(new char[] {','});
@@ -291,7 +290,6 @@ namespace OpenSim.Services.Interfaces
}
}
-
// Attachments
Dictionary attchs = new Dictionary();
foreach (KeyValuePair _kvp in Data)
@@ -308,7 +306,7 @@ namespace OpenSim.Services.Interfaces
UUID uuid = UUID.Zero;
UUID.TryParse(_kvp.Value, out uuid);
- appearance.SetAttachment(point,uuid,UUID.Zero);
+ appearance.SetAttachment(point, uuid, UUID.Zero);
}
if (appearance.Wearables[AvatarWearable.BODY].Count == 0)
diff --git a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs
index 4e60ca9ed8..ceb79059cc 100644
--- a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs
@@ -88,8 +88,7 @@ namespace OpenSim.Tests.Common
if (type == InventoryType.Notecard)
asset = AssetHelpers.CreateAsset(scene, userId);
else if (type == InventoryType.Object)
- asset
- = AssetHelpers.CreateAsset(assetId, SceneHelpers.CreateSceneObject(1, userId));
+ asset = AssetHelpers.CreateAsset(assetId, SceneHelpers.CreateSceneObject(1, userId));
else
throw new Exception(string.Format("Inventory type {0} not supported", type));
diff --git a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs
index 2ea36da228..79bb9c2ce3 100644
--- a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs
+++ b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs
@@ -163,6 +163,10 @@ namespace OpenSim.Data.Null
{
RegionSettings rs = null;
m_regionSettings.TryGetValue(regionUUID, out rs);
+
+ if (rs == null)
+ rs = new RegionSettings();
+
return rs;
}
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index c36d2a4ea6..342bce6b59 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -740,7 +740,7 @@
;; "config-include/StandaloneCommon.ini.example" to "config-include/StandaloneCommon.ini" before
;; editing it to set the database and backend services that OpenSim will use.
;;
- ; Include-Architecture = "config-include/Standalone.ini"
+ Include-Architecture = "config-include/Standalone.ini"
; Include-Architecture = "config-include/StandaloneHypergrid.ini"
; Include-Architecture = "config-include/Grid.ini"
; Include-Architecture = "config-include/GridHypergrid.ini"