diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index e0df2881ed..0fc467bc43 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -411,6 +411,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
///
/// Rez an object into the scene from the user's inventory
///
+ /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing
+ /// things to the scene. The caller should be doing that, I think.
///
///
///
@@ -500,13 +502,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
group.RootPart.IsAttachment = true;
}
- m_Scene.AddNewSceneObject(group, true);
+ // For attachments, we must make sure that only a single object update occurs after we've finished
+ // all the necessary operations.
+ m_Scene.AddNewSceneObject(group, true, false);
// m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z);
// if attachment we set it's asset id so object updates can reflect that
// if not, we set it's position in world.
if (!attachment)
{
+ group.ScheduleGroupForFullUpdate();
+
float offsetHeight = 0;
pos = m_Scene.GetNewRezLocation(
RayStart, RayEnd, RayTargetID, Quaternion.Identity,
@@ -562,6 +568,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
part.GroupMask = 0; // DO NOT propagate here
}
}
+
group.ApplyNextOwnerPermissions();
}
}
@@ -569,7 +576,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
foreach (SceneObjectPart part in partList)
{
if (part.OwnerID != item.Owner)
- {
+ {
part.LastOwnerID = part.OwnerID;
part.OwnerID = item.Owner;
part.Inventory.ChangeInventoryOwner(item.Owner);
@@ -591,10 +598,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
{
group.ClearPartAttachmentData();
}
- }
-
- if (!attachment)
- {
+
// Fire on_rez
group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 0);
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 6df25d6e29..5f3cd8cf4d 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -1842,9 +1842,18 @@ namespace OpenSim.Region.Framework.Scenes
EventManager.TriggerOnAttach(localID, itemID, avatarID);
}
- public UUID RezSingleAttachment(IClientAPI remoteClient, UUID itemID,
- uint AttachmentPt)
+ ///
+ /// Called when the client receives a request to rez a single attachment on to the avatar from inventory
+ /// (RezSingleAttachmentFromInv packet).
+ ///
+ ///
+ ///
+ ///
+ ///
+ public UUID RezSingleAttachment(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
{
+ m_log.DebugFormat("[USER INVENTORY]: Rezzing single attachment from item {0} for {1}", itemID, remoteClient.Name);
+
SceneObjectGroup att = m_sceneGraph.RezSingleAttachment(remoteClient, itemID, AttachmentPt);
if (att == null)
@@ -1856,9 +1865,20 @@ namespace OpenSim.Region.Framework.Scenes
return RezSingleAttachment(att, remoteClient, itemID, AttachmentPt);
}
- public UUID RezSingleAttachment(SceneObjectGroup att,
- IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
+ ///
+ /// Update the user inventory to reflect an attachment
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public UUID RezSingleAttachment(SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
{
+ m_log.DebugFormat(
+ "[USER INVENTORY]: Updating inventory of {0} to show attachment of {1} (item ID {2})",
+ remoteClient.Name, att.Name, itemID);
+
if (!att.IsDeleted)
AttachmentPt = att.RootPart.AttachmentPoint;
@@ -1897,8 +1917,19 @@ namespace OpenSim.Region.Framework.Scenes
return m_sceneGraph.AttachObject(controllingClient, localID, attachPoint, rot, pos, silent);
}
+ ///
+ /// This registers the item as attached in a user's inventory
+ ///
+ ///
+ ///
+ ///
+ ///
public void AttachObject(IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
{
+// m_log.DebugFormat(
+// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
+// att.Name, remoteClient.Name, AttachmentPt, itemID);
+
if (UUID.Zero == itemID)
{
m_log.Error("[SCENE INVENTORY]: Unable to save attachment. Error inventory item ID.");
@@ -1926,10 +1957,7 @@ namespace OpenSim.Region.Framework.Scenes
presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /* att.UUID */);
if (m_AvatarFactory != null)
- {
m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
- }
-
}
}
@@ -2012,6 +2040,7 @@ namespace OpenSim.Region.Framework.Scenes
{
sog.SetOwnerId(ownerID);
sog.SetGroup(groupID, remoteClient);
+ sog.ScheduleGroupForFullUpdate();
foreach (SceneObjectPart child in sog.Children.Values)
child.Inventory.ChangeInventoryOwner(ownerID);
@@ -2033,6 +2062,7 @@ namespace OpenSim.Region.Framework.Scenes
sog.SetOwnerId(groupID);
sog.ApplyNextOwnerPermissions();
}
+
}
foreach (uint localID in localIDs)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 5e5a52e981..a880fe7d59 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1906,14 +1906,22 @@ namespace OpenSim.Region.Framework.Scenes
//m_log.DebugFormat(
// "[SCENE]: Scene.AddNewPrim() pcode {0} called for {1} in {2}", shape.PCode, ownerID, RegionInfo.RegionName);
+ SceneObjectGroup sceneObject = null;
+
// If an entity creator has been registered for this prim type then use that
if (m_entityCreators.ContainsKey((PCode)shape.PCode))
- return m_entityCreators[(PCode)shape.PCode].CreateEntity(ownerID, groupID, pos, rot, shape);
+ {
+ sceneObject = m_entityCreators[(PCode)shape.PCode].CreateEntity(ownerID, groupID, pos, rot, shape);
+ }
+ else
+ {
+ // Otherwise, use this default creation code;
+ sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape);
+ AddNewSceneObject(sceneObject, true);
+ sceneObject.SetGroup(groupID, null);
+ }
- // Otherwise, use this default creation code;
- SceneObjectGroup sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape);
- AddNewSceneObject(sceneObject, true);
- sceneObject.SetGroup(groupID, null);
+ sceneObject.ScheduleGroupForFullUpdate();
return sceneObject;
}
@@ -1941,7 +1949,7 @@ namespace OpenSim.Region.Framework.Scenes
}
///
- /// Add a newly created object to the scene
+ /// Add a newly created object to the scene. Updates are also sent to viewers.
///
///
///
@@ -1950,8 +1958,25 @@ namespace OpenSim.Region.Framework.Scenes
///
public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup)
{
- return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup);
+ return AddNewSceneObject(sceneObject, attachToBackup, true);
}
+
+ ///
+ /// Add a newly created object to the scene
+ ///
+ ///
+ ///
+ /// If true, the object is made persistent into the scene.
+ /// If false, the object will not persist over server restarts
+ ///
+ ///
+ /// If true, updates for the new scene object are sent to all viewers in range.
+ /// If false, it is left to the caller to schedule the update
+ ///
+ public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
+ {
+ return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates);
+ }
///
/// Delete every object from the scene
@@ -3143,7 +3168,6 @@ namespace OpenSim.Region.Framework.Scenes
m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
m_sceneGridService.KiPrimitive += SendKillObject;
m_sceneGridService.OnGetLandData += GetLandData;
-
}
///
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index b7fcd7d558..22613e925f 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -229,7 +229,7 @@ namespace OpenSim.Region.Framework.Scenes
sceneObject.HasGroupChanged = true;
}
- return AddSceneObject(sceneObject, attachToBackup);
+ return AddSceneObject(sceneObject, attachToBackup, true);
}
///
@@ -244,12 +244,12 @@ namespace OpenSim.Region.Framework.Scenes
///
/// true if the object was added, false if an object with the same uuid was already in the scene
///
- protected internal bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup)
+ protected internal bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
{
// Ensure that we persist this new scene object
sceneObject.HasGroupChanged = true;
- return AddSceneObject(sceneObject, attachToBackup);
+ return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates);
}
///
@@ -261,12 +261,19 @@ namespace OpenSim.Region.Framework.Scenes
/// If true, the object is made persistent into the scene.
/// If false, the object will not persist over server restarts
///
- /// true if the object was added, false if an object with the same uuid was already in the scene
+ ///
+ /// If true, updates for the new scene object are sent to all viewers in range.
+ /// If false, it is left to the caller to schedule the update
+ ///
+ ///
+ /// true if the object was added, false if an object with the same uuid was already in the scene
///
- protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup)
+ protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
{
if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero)
return false;
+
+ bool alreadyExisted = false;
if (m_parentScene.m_clampPrimSize)
{
@@ -287,6 +294,9 @@ namespace OpenSim.Region.Framework.Scenes
sceneObject.AttachToScene(m_parentScene);
+ if (sendClientUpdates)
+ sceneObject.ScheduleGroupForFullUpdate();
+
lock (sceneObject)
{
if (!Entities.ContainsKey(sceneObject.UUID))
@@ -310,12 +320,14 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
}
}
-
- return true;
+ }
+ else
+ {
+ alreadyExisted = true;
}
}
- return false;
+ return alreadyExisted;
}
///
@@ -525,7 +537,10 @@ namespace OpenSim.Region.Framework.Scenes
itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
false, false, remoteClient.AgentId, true);
-
+// m_log.DebugFormat(
+// "[SCENE GRAPH]: Retrieved single object {0} for attachment to {1} on point {2}",
+// objatt.Name, remoteClient.Name, AttachmentPt);
+
if (objatt != null)
{
bool tainted = false;
@@ -533,7 +548,7 @@ namespace OpenSim.Region.Framework.Scenes
tainted = true;
AttachObject(remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false);
- objatt.ScheduleGroupForFullUpdate();
+ //objatt.ScheduleGroupForFullUpdate();
if (tainted)
objatt.HasGroupChanged = true;
@@ -544,8 +559,16 @@ namespace OpenSim.Region.Framework.Scenes
// Do this last so that event listeners have access to all the effects of the attachment
m_parentScene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId);
}
+ else
+ {
+ m_log.WarnFormat(
+ "[SCENE GRAPH]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
+ itemID, remoteClient.Name, AttachmentPt);
+ }
+
return objatt;
}
+
return null;
}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index c5a6171207..c14b39ad85 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -567,8 +567,10 @@ namespace OpenSim.Region.Framework.Scenes
}
ApplyPhysics(m_scene.m_physicalPrim);
-
- ScheduleGroupForFullUpdate();
+
+ // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled
+ // for the same object with very different properties. The caller must schedule the update.
+ //ScheduleGroupForFullUpdate();
}
public Vector3 GroupScale()
@@ -956,10 +958,11 @@ namespace OpenSim.Region.Framework.Scenes
// don't attach attachments to child agents
if (avatar.IsChildAgent) return;
+// m_log.DebugFormat("[SOG]: Adding attachment {0} to avatar {1}", Name, avatar.Name);
+
DetachFromBackup();
// Remove from database and parcel prim count
- //
m_scene.DeleteFromStorage(UUID);
m_scene.EventManager.TriggerParcelPrimCountTainted();
@@ -985,7 +988,6 @@ namespace OpenSim.Region.Framework.Scenes
SetAttachmentPoint(Convert.ToByte(attachmentpoint));
avatar.AddAttachment(this);
- m_log.Debug("[SOG]: Added attachment " + UUID + " to avatar " + avatar.UUID);
if (!silent)
{
@@ -1002,6 +1004,12 @@ namespace OpenSim.Region.Framework.Scenes
ScheduleGroupForFullUpdate();
}
}
+ else
+ {
+ m_log.WarnFormat(
+ "[SOG]: Tried to add attachment {0} to avatar with UUID {1} in region {2} but the avatar is not present",
+ UUID, agentID, Scene.RegionInfo.RegionName);
+ }
}
public byte GetAttachmentPoint()
@@ -1986,6 +1994,8 @@ namespace OpenSim.Region.Framework.Scenes
public void ScheduleFullUpdateToAvatar(ScenePresence presence)
{
+// m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1} just to avatar {2}", Name, UUID, presence.Name);
+
RootPart.AddFullUpdateToAvatar(presence);
lock (m_parts)
@@ -2000,6 +2010,8 @@ namespace OpenSim.Region.Framework.Scenes
public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
{
+// m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1} just to avatar {2}", Name, UUID, presence.Name);
+
lock (m_parts)
{
foreach (SceneObjectPart part in m_parts.Values)
@@ -2014,6 +2026,8 @@ namespace OpenSim.Region.Framework.Scenes
///
public void ScheduleGroupForFullUpdate()
{
+// m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, UUID);
+
checkAtTargets();
RootPart.ScheduleFullUpdate();
@@ -2032,6 +2046,8 @@ namespace OpenSim.Region.Framework.Scenes
///
public void ScheduleGroupForTerseUpdate()
{
+// m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID);
+
lock (m_parts)
{
foreach (SceneObjectPart part in m_parts.Values)
@@ -2045,9 +2061,11 @@ namespace OpenSim.Region.Framework.Scenes
/// Immediately send a full update for this scene object.
///
public void SendGroupFullUpdate()
- {
+ {
if (IsDeleted)
return;
+
+// m_log.DebugFormat("[SOG]: Sending immediate full group update for {0} {1}", Name, UUID);
RootPart.SendFullUpdateToAllClients();
@@ -2064,7 +2082,7 @@ namespace OpenSim.Region.Framework.Scenes
///
/// Immediately send an update for this scene object's root prim only.
/// This is for updates regarding the object as a whole, and none of its parts in particular.
- /// Note: this may not be cused by opensim (it probably should) but it's used by
+ /// Note: this may not be used by opensim (it probably should) but it's used by
/// external modules.
///
public void SendGroupRootTerseUpdate()
@@ -2079,6 +2097,7 @@ namespace OpenSim.Region.Framework.Scenes
{
if (m_scene == null) // Need to check here as it's null during object creation
return;
+
m_scene.SceneGraph.AddToUpdateList(this);
}
@@ -3557,7 +3576,9 @@ namespace OpenSim.Region.Framework.Scenes
HasGroupChanged = true;
}
- ScheduleGroupForFullUpdate();
+ // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled
+ // for the same object with very different properties. The caller must schedule the update.
+ //ScheduleGroupForFullUpdate();
}
public void TriggerScriptChangedEvent(Changed val)
diff --git a/bin/OpenSim.exe.config b/bin/OpenSim.exe.config
index 3c7adf5419..4e7ef51bd8 100755
--- a/bin/OpenSim.exe.config
+++ b/bin/OpenSim.exe.config
@@ -12,7 +12,7 @@
-
+
diff --git a/bin/config-include/Standalone.ini b/bin/config-include/Standalone.ini
index bf693a18ec..dc65ffd07f 100644
--- a/bin/config-include/Standalone.ini
+++ b/bin/config-include/Standalone.ini
@@ -31,14 +31,14 @@
[AvatarService]
LocalServiceModule = "OpenSim.Services.AvatarService.dll:AvatarService"
- ConnectionString = "URI=file:avatars.db,version=3"
+ ; ConnectionString = "URI=file:avatars.db,version=3"
[AuthorizationService]
LocalServiceModule = "OpenSim.Services.AuthorizationService.dll:AuthorizationService"
[AuthenticationService]
LocalServiceModule = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService"
- ConnectionString = "URI=file:auth.db,version=3"
+ ; ConnectionString = "URI=file:auth.db,version=3"
[GridService]
LocalServiceModule = "OpenSim.Services.GridService.dll:GridService"
@@ -51,7 +51,7 @@
[UserAccountService]
LocalServiceModule = "OpenSim.Services.UserAccountService.dll:UserAccountService"
- ConnectionString = "URI=file:userprofiles.db,version=3"
+ ; ConnectionString = "URI=file:userprofiles.db,version=3"
;; These are for creating new accounts
AuthenticationService = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService"
PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService"
@@ -60,7 +60,7 @@
[FriendsService]
LocalServiceModule = "OpenSim.Services.FriendsService.dll"
- ConnectionString = "URI=file:friends.db,version=3"
+ ; ConnectionString = "URI=file:friends.db,version=3"
[Friends]
Connector = "OpenSim.Services.FriendsService.dll"