diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index 5fb8fdc49b..3f7e9f90c2 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -1631,8 +1631,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //SendSyncMessage(SymmetricSyncMessage.MsgType.NewObject, sogxml); SceneObjectGroup sog = (SceneObjectGroup)e; SendNewObject(sog); - - //m_log.Debug(LogHeader + ": " + sogxml); } } return; @@ -1642,8 +1640,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule break; case SymmetricSyncMessage.MsgType.UpdatedObject: { - HandleAddOrUpdateObjectBySynchronization(msg, senderActorID); - //HandleAddNewObject(sog); + //HandleAddOrUpdateObjectBySynchronization(msg, senderActorID); + HandleUpdateObjectBySynchronization(msg, senderActorID); return; } case SymmetricSyncMessage.MsgType.UpdatedBucketProperties: @@ -1722,7 +1720,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //First, create the object group and add it to Scene string sogxml = data["sogxml"]; SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(sogxml); - Scene.ObjectUpdateResult updateResult = m_scene.AddOrUpdateObjectBySynchronization(sog); + //Scene.ObjectUpdateResult updateResult = m_scene.AddOrUpdateObjectBySynchronization(sog); + + Scene.ObjectUpdateResult updateResult = m_scene.AddNewSceneObjectBySync(sog); //if this is a relay node, forward the event if (m_isSyncRelay) @@ -1749,9 +1749,47 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_scene.UpdateObjectPartBucketProperties(bucketName, partUUID, data, rBucketSyncInfo); } //m_log.DebugFormat("{0}: received NewObject sync message from {1}, for object {1}, {2}", LogHeader, senderActorID, sog.Name, sog.UUID); + } + private void HandleUpdateObjectBySynchronization(SymmetricSyncMessage msg, string senderActorID) + { + string sogxml = Encoding.ASCII.GetString(msg.Data, 0, msg.Length); + SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(sogxml); + lock (m_stats) m_statSOGBucketIn++; + if (sog.IsDeleted) + { + SymmetricSyncMessage.HandleTrivial(LogHeader, msg, String.Format("Ignoring update on deleted object, UUID: {0}.", sog.UUID)); + return; + } + else + { + foreach (SceneObjectPart part in sog.Parts) + { + if (part.IsAttachment) + { + m_log.Debug(LogHeader + "HandleUpdateObjectBySynchronization: part " + part.Name + "," + part.UUID + ", IsAttachment = true"); + } + } + Scene.ObjectUpdateResult updateResult = m_scene.UpdateObjectBySynchronization(sog); + + switch (updateResult) + { + case Scene.ObjectUpdateResult.New: + m_log.DebugFormat("[{0} Object \"{1}\" ({1}) ({2}) added.", LogHeader, sog.Name, sog.UUID.ToString(), sog.LocalId.ToString()); + break; + case Scene.ObjectUpdateResult.Updated: + m_log.DebugFormat("[{0} Object \"{1}\" ({1}) ({2}) updated.", LogHeader, sog.Name, sog.UUID.ToString(), sog.LocalId.ToString()); + break; + case Scene.ObjectUpdateResult.Error: + m_log.WarnFormat("[{0} Object \"{1}\" ({1}) ({2}) -- add or update ERROR.", LogHeader, sog.Name, sog.UUID.ToString(), sog.LocalId.ToString()); + break; + case Scene.ObjectUpdateResult.Unchanged: + //m_log.DebugFormat("[{0} Object \"{1}\" ({1}) ({2}) unchanged after receiving an update.", LogHeader, sog.Name, sog.UUID.ToString(), sog.LocalId.ToString()); + break; + } + } } diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/ScenePersistenceSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/ScenePersistenceSyncModule.cs index 5d6512b359..23dffef326 100755 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/ScenePersistenceSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/ScenePersistenceSyncModule.cs @@ -89,7 +89,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //m_scene.EventManager.OnPostSceneCreation += OnPostSceneCreation; //Register for Scene/SceneGraph events - //m_scene.SceneGraph.OnObjectCreate += new ObjectCreateDelegate(ScenePersistence_OnObjectCreate); + m_scene.SceneGraph.OnObjectCreate += new ObjectCreateDelegate(ScenePersistence_OnObjectCreate); m_scene.SceneGraph.OnObjectCreateBySync += new ObjectCreateBySyncDelegate(ScenePersistence_OnObjectCreateBySync); } @@ -164,16 +164,33 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule /// /// ScenePersistence's actions upon an object is added to the local scene. /// - private void ScenePersistence_OnObjectCreateBySync(EntityBase entity) + private void ScenePersistence_OnObjectCreate(EntityBase entity) { if (entity is SceneObjectGroup) { - m_log.Warn(LogHeader + ": link to backup for " + entity.UUID); + //m_log.Warn(LogHeader + ":OnObjectCreate -- link to backup for " + entity.UUID); SceneObjectGroup sog = (SceneObjectGroup)entity; //probably what we should do here is to set some variable sog.SyncToBackup to true, and sog.ProcessBackup will only run if that value is true, //then we do not need to worry about where an object is attach-to-backup and modify all those lines. + sog.ToPersistObjectState = true; + sog.AttachToBackup(); + } + } + /// + /// ScenePersistence's actions upon an object is added to the local scene. + /// + private void ScenePersistence_OnObjectCreateBySync(EntityBase entity) + { + if (entity is SceneObjectGroup) + { + //m_log.Warn(LogHeader + ":OnObjectCreateBySync -- link to backup for " + entity.UUID); + SceneObjectGroup sog = (SceneObjectGroup)entity; + + //probably what we should do here is to set some variable sog.SyncToBackup to true, and sog.ProcessBackup will only run if that value is true, + //then we do not need to worry about where an object is attach-to-backup and modify all those lines. + sog.ToPersistObjectState = true; sog.AttachToBackup(); } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 8f1d9f6198..5efd6d545f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -684,6 +684,11 @@ namespace OpenSim.Region.Framework.Scenes return m_sceneGraph.AddOrUpdateObjectBySynchronization(sog); } + public ObjectUpdateResult UpdateObjectBySynchronization(SceneObjectGroup sog) + { + return m_sceneGraph.UpdateObjectBySynchronization(sog); + } + //Similar to DeleteSceneObject, except that this does not change LastUpdateActorID and LastUpdateTimeStamp public void DeleteSceneObjectBySynchronization(SceneObjectGroup group) { @@ -732,12 +737,12 @@ namespace OpenSim.Region.Framework.Scenes m_sceneGraph.AddNewSceneObjectPart(newPart, parentGroup); } - public void AddNewSceneObjectBySync(SceneObjectGroup group, bool attachToBackup) + public ObjectUpdateResult AddNewSceneObjectBySync(SceneObjectGroup group) { - if(attachToBackup) - group.HasGroupChanged = true; + //if(attachToBackup) + // group.HasGroupChanged = true; - m_sceneGraph.AddSceneObjectByStateSynch(group); + return m_sceneGraph.AddNewSceneObjectBySync(group); } public void DebugSceneObjectGroups() diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index c8b58c62f5..3534179f31 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -2002,6 +2002,37 @@ namespace OpenSim.Region.Framework.Scenes #region SYMMETRIC SYNC + public Scene.ObjectUpdateResult UpdateObjectBySynchronization(SceneObjectGroup updatedSog) + { + UUID sogID = updatedSog.UUID; + Scene.ObjectUpdateResult updateResult = Scene.ObjectUpdateResult.Unchanged; + + if (Entities.ContainsKey(sogID)) + { + //update the object + EntityBase entity = Entities[sogID]; + if (entity is SceneObjectGroup) + { + SceneObjectGroup localSog = (SceneObjectGroup)entity; + updateResult = localSog.UpdateObjectGroupBySync(updatedSog); + } + else + { + m_log.WarnFormat("{0}: Entity with {1} is not of type SceneObjectGroup: {2}", + "[SCENE GRAPH]", sogID, entity.GetType().ToString()); + //return false; + updateResult = Scene.ObjectUpdateResult.Error; + } + } + else + { + //An object no longer in Entity list, probably linked to other objects, or handed over to another quark. + m_log.WarnFormat("[SCENE GRAPH] UpdateObjectBySynchronization: received update for an object {0}, {1} no longer in local Entity list. Ignore update.", updatedSog.Name, updatedSog.UUID); + } + + return updateResult; + } + public Scene.ObjectUpdateResult AddOrUpdateObjectBySynchronization(SceneObjectGroup updatedSog) { UUID sogID = updatedSog.UUID; @@ -2027,7 +2058,7 @@ namespace OpenSim.Region.Framework.Scenes else { //m_log.Debug(updatedSog.Name+" "+updatedSog.UUID+" not found in Entities list. Need to add"); - AddSceneObjectByStateSynch(updatedSog); + AddNewSceneObjectBySync(updatedSog); updateResult = Scene.ObjectUpdateResult.New; } @@ -2040,13 +2071,18 @@ namespace OpenSim.Region.Framework.Scenes //This is called when an object is added due to receiving a state synchronization message from Scene or an actor. Do similar things as the original AddSceneObject(), //but call ScheduleGroupForFullUpdate_TimeStampUnchanged() instead, so as not to modify the timestamp or actorID, since the object was not created locally. - public bool AddSceneObjectByStateSynch(SceneObjectGroup sceneObject) + public Scene.ObjectUpdateResult AddNewSceneObjectBySync(SceneObjectGroup sceneObject) { + Scene.ObjectUpdateResult updateResult = Scene.ObjectUpdateResult.New; + if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero) - return false; + return Scene.ObjectUpdateResult.Error; if (Entities.ContainsKey(sceneObject.UUID)) - return false; + { + m_log.WarnFormat("[SCENE GRAPH] AddNewSceneObjectBySync: Already has object {0}, {1} in local Entity list.", sceneObject.Name, sceneObject.UUID); + return Scene.ObjectUpdateResult.Error; + } SceneObjectPart[] children = sceneObject.Parts; @@ -2111,7 +2147,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; } - return true; + return updateResult; } public void AddNewSceneObjectPart(SceneObjectPart newPart, SceneObjectGroup parentGroup) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index f077318467..a1fde883ec 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1372,6 +1372,14 @@ namespace OpenSim.Region.Framework.Scenes return; } + //SYMMETRIC SYNC + //if we are doing sync across different sync nodes, and are not told to persist the state, don't do anything (only persistence actor will do it) + if (m_scene.RegionSyncModule != null && !ToPersistObjectState) + { + return; + } + //end of SYMMETRIC SYNC + // Since this is the top of the section of call stack for backing up a particular scene object, don't let // any exception propogate upwards. try @@ -3556,6 +3564,13 @@ namespace OpenSim.Region.Framework.Scenes #region SYMMETRIC SYNC + private bool m_toPersistObjectState = false; + public bool ToPersistObjectState + { + get { return m_toPersistObjectState; } + set { m_toPersistObjectState = value; } + } + //update the existing copy of the object with updated properties in 'updatedSog' //NOTE: updates on script content are handled seperately (e.g. user edited the script and saved it) -- SESyncServerOnUpdateScript(), a handler of EventManager.OnUpdateScript //public void UpdateObjectProperties(SceneObjectGroup updatedSog) @@ -3847,7 +3862,7 @@ namespace OpenSim.Region.Framework.Scenes bool newGroupBySync = true; SceneObjectGroup objectGroup = new SceneObjectGroup(delinkPart, newGroupBySync); - m_scene.AddNewSceneObjectBySync(objectGroup, true); + m_scene.AddNewSceneObjectBySync(objectGroup); if (sendEvents) linkPart.TriggerScriptChangedEvent(Changed.LINK);