From a8c722bead29e3bbb3eed432b48ad0c2c3735555 Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Wed, 16 Mar 2011 09:32:27 -0700 Subject: [PATCH 1/2] Added code to encode and decode all object properties, including those in Physics bucket, to sending and handling received NewObject sync message. Also, NewObject, RemoveObject, and LinkObject are now all sent out via SendSceneEventToRelevantSyncConnectors, that is, they are sent out on wire right away, not enqueue first. --- .../SymmetricSync/RegionSyncModule.cs | 407 ++++++++++-------- .../Framework/Scenes/Scene.Inventory.cs | 7 + OpenSim/Region/Framework/Scenes/Scene.cs | 10 +- .../Framework/Scenes/SceneObjectGroup.cs | 6 +- .../Framework/Scenes/SceneObjectPart.cs | 9 +- 5 files changed, 262 insertions(+), 177 deletions(-) diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index 5ee27bff5f..5fb8fdc49b 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -296,21 +296,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { if (primUpdates.ContainsKey(bucketName) && primUpdates[bucketName].Count > 0) { - /* - foreach (SceneObjectGroup sog in primUpdates[bucketName]) - { - - //If this is a relay node, or at least one part of the object has the last update caused by this actor, then send the update - sog.UpdateTaintedBucketSyncInfo(timeStamp); - if (m_isSyncRelay || (!sog.IsDeleted && CheckObjectForSendingUpdate(sog))) - { - //send - string sogxml = SceneObjectSerializer.ToXml2Format(sog); - SymmetricSyncMessage syncMsg = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.UpdatedObject, sogxml); - SendObjectUpdateToRelevantSyncConnectors(sog, syncMsg); - } - } - * */ //m_log.Debug(LogHeader + " calling update sender for bucket " + bucketName); m_primUpdatesPerBucketSender[bucketName](bucketName, primUpdates[bucketName]); } @@ -399,9 +384,23 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } //m_log.DebugFormat(LogHeader + "SendNewObject called for object {0}, {1}", sog.Name, sog.UUID); + //This is a new object (newly rezzed). Send out updates for all properties. + //For now, a complete list of object properties include properties + //in its xml serialization, plus the set of Physics properties as in Physics bucket + OSDMap data = new OSDMap(); string sogxml = SceneObjectSerializer.ToXml2Format(sog); - SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.NewObject, sogxml); - SendObjectUpdateToRelevantSyncConnectors(sog, rsm); + data["sogxml"] = OSD.FromString(sogxml); + OSDArray partArray = new OSDArray(); + foreach (SceneObjectPart part in sog.Parts){ + OSDMap partData = PhysicsBucketPropertiesEncoder(m_physicsBucketName, part); + partArray.Add(partData); + } + data["partPhysicsProperties"] = partArray; + //string sogxml = SceneObjectSerializer.ToXml2Format(sog); + SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.NewObject, OSDParser.SerializeJsonString(data)); + + //SendObjectUpdateToRelevantSyncConnectors(sog, rsm); + SendSceneEventToRelevantSyncConnectors(m_actorID, rsm, sog); } /// @@ -433,7 +432,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule data["softDelete"] = OSD.FromBoolean(softDelete); SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.RemovedObject, OSDParser.SerializeJsonString(data)); - SendObjectUpdateToRelevantSyncConnectors(sog, rsm); + //SendObjectUpdateToRelevantSyncConnectors(sog, rsm); + SendSceneEventToRelevantSyncConnectors(m_actorID, rsm, sog); } @@ -461,13 +461,16 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule string partTempID = "part"+partNum; data[partTempID] = OSD.FromUUID(part.UUID); partNum++; + + m_log.Debug("SendLinkObject to link " + part.ParentGroup.Name + "," + part.UUID + " with " + root.Name+","+root.UUID); } - m_log.Debug(LogHeader + " to SendLinkObject to link " + children.Count + " parts to " + root.Name); - m_log.Debug("LinkedObject: "+sogxml); + m_log.Debug(LogHeader + " to SendLinkObject to link " + children.Count + " parts to " + root.Name + "," + root.UUID); + //m_log.Debug("LinkedObject: "+sogxml); SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.LinkObject, OSDParser.SerializeJsonString(data)); - SendObjectUpdateToRelevantSyncConnectors(linkedGroup, rsm); + //SendObjectUpdateToRelevantSyncConnectors(linkedGroup, rsm); + SendSceneEventToRelevantSyncConnectors(m_actorID, rsm, linkedGroup); } public void SendDeLinkObject(List prims, List beforeDelinkGroups, List afterDelinkGroups) @@ -718,8 +721,20 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule private delegate void PrimUpdatePerBucketSender(string bucketName, List primUpdates); private Dictionary m_primUpdatesPerBucketSender = new Dictionary(); - //Timestamps that record the last time each any updates have been sent out for a given bucket - private Dictionary m_lastUpdateSentTime = new Dictionary(); + + /* + //The functions that encode properties in each bucket. For now, + //general bucket works on SOG, physics bucket works on SOP, so we define + //the arg to be of type Object to be general in the interface. + //TO DO: redesign the interface once the bucket encoders working on more + //consistent/specific arguments. + private delegate string UpdatePerBucketEncoder(string bucketName, Object arg); + private Dictionary m_updatePerBucketEncoder = new Dictionary(); + + //Decoders of properties in each bucket + private delegate void UpdatePerBucketDecoder(string bucketName, string encoding, out Object outData); + private Dictionary m_updatePerBucketDecoder = new Dictionary(); + * */ private object m_updateScenePresenceLock = new object(); private Dictionary m_presenceUpdates = new Dictionary(); @@ -756,8 +771,19 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule foreach (SceneObjectGroup sog in updatedObjects.Values) { sog.UpdateTaintedBucketSyncInfo(bucketName, timeStamp); //this update the timestamp and clear the taint info of the bucket - string sogxml = SceneObjectSerializer.ToXml2Format(sog); - SymmetricSyncMessage syncMsg = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.UpdatedObject, sogxml); + string sogGeneralBucketEncoding = SceneObjectSerializer.ToXml2Format(sog); + //string sogGeneralBucketEncoding = GeneralBucketPropertiesEncoder(bucketName, sog, null); + SymmetricSyncMessage syncMsg = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.UpdatedObject, sogGeneralBucketEncoding); + + //TEMP DEBUG + foreach (SceneObjectPart part in sog.Parts) + { + if (part.IsAttachment) + { + m_log.Debug(LogHeader + "PrimUpdatesGeneralBucketSender: part " + part.Name + "," + part.UUID + ", IsAttachment = true"); + } + } + lock (m_stats) m_statSOGBucketOut++; SendObjectUpdateToRelevantSyncConnectors(sog, syncMsg); @@ -771,53 +797,42 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //UpdateBucektLastSentTime(bucketName, timeStamp); } + private string GeneralBucketPropertiesEncoder(string bucketName, Object sog) + { + if (sog is SceneObjectGroup) + { + SceneObjectGroup group = (SceneObjectGroup)sog; + return SceneObjectSerializer.ToXml2Format(group); + } + else + return String.Empty; + } + + private void GeneralBucketPropertiesDecoder(string bucketName, string encoding, out Object sog) + { + SceneObjectGroup group = SceneObjectSerializer.FromXml2Format(encoding); + sog = (Object)group; + + } + private void PrimUpdatesPhysicsBucketSender(string bucketName, List primUpdates) { foreach (SceneObjectPart updatedPart in primUpdates) { updatedPart.UpdateTaintedBucketSyncInfo(bucketName, DateTime.Now.Ticks); - OSDMap data = new OSDMap(); - - data["UUID"] = OSD.FromUUID(updatedPart.UUID); - //data["UUID"] = OSD.FromUUID(pa.UUID); - data["Bucket"] = OSD.FromString(bucketName); - - data["GroupPosition"] = OSD.FromVector3(updatedPart.GroupPosition); - data["OffsetPosition"] = OSD.FromVector3(updatedPart.OffsetPosition); - data["Scale"] = OSD.FromVector3(updatedPart.Scale); - data["AngularVelocity"] = OSD.FromVector3(updatedPart.AngularVelocity); - data["RotationOffset"] = OSD.FromQuaternion(updatedPart.RotationOffset); - - Physics.Manager.PhysicsActor pa = updatedPart.PhysActor; - if (pa != null) - { - - data["Size"] = OSD.FromVector3(pa.Size); - data["Position"] = OSD.FromVector3(pa.Position); - data["Force"] = OSD.FromVector3(pa.Force); - data["Velocity"] = OSD.FromVector3(pa.Velocity); - data["RotationalVelocity"] = OSD.FromVector3(pa.RotationalVelocity); - data["PA_Acceleration"] = OSD.FromVector3(pa.Acceleration); - data["Torque"] = OSD.FromVector3(pa.Torque); - data["Orientation"] = OSD.FromQuaternion(pa.Orientation); - data["IsPhysical"] = OSD.FromBoolean(pa.IsPhysical); - data["Flying"] = OSD.FromBoolean(pa.Flying); - data["Kinematic"] = OSD.FromBoolean(pa.Kinematic); - data["Buoyancy"] = OSD.FromReal(pa.Buoyancy); - data["CollidingGround"] = OSD.FromBoolean(pa.CollidingGround); - data["IsColliding"] = OSD.FromBoolean(pa.IsColliding); - - m_log.DebugFormat("{0}: PhysBucketSender for {1}, pos={2}", LogHeader, updatedPart.UUID.ToString(), pa.Position.ToString()); - } - - data["LastUpdateTimeStamp"] = OSD.FromLong(updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp); - data["LastUpdateActorID"] = OSD.FromString(updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID); - - //m_log.Debug(LogHeader + " Send out Physics Bucket updates for " + updatedPart.Name + ","+updatedPart.UUID+ ". GroupPosition: " + updatedPart.GroupPosition.ToString()); - - SymmetricSyncMessage syncMsg = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.UpdatedBucketProperties, OSDParser.SerializeJsonString(data)); + //string partPhysicsBucketEncoding = PhysicsBucketPropertiesEncoder(bucketName, updatedPart); + OSDMap partData = PhysicsBucketPropertiesEncoder(bucketName, updatedPart); + SymmetricSyncMessage syncMsg = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.UpdatedBucketProperties, OSDParser.SerializeJsonString(partData)); //m_log.DebugFormat("{0}: PhysBucketSender for {1}, pos={2}", LogHeader, updatedPart.UUID.ToString(), pa.Position.ToString()); + + //TEMP DEBUG + if (updatedPart.IsAttachment) + { + m_log.Debug(LogHeader + "PrimUpdatesPhysicsBucketSender: part " + updatedPart.Name + "," + updatedPart.UUID + ", IsAttachment = true"); + } + + lock (m_stats) m_statPhysBucketOut++; SendObjectUpdateToRelevantSyncConnectors(updatedPart, syncMsg); @@ -828,13 +843,55 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //UpdateBucektLastSentTime(bucketName); } - /* - private void UpdateBucektLastSentTime(string bucketName) + private OSDMap PhysicsBucketPropertiesEncoder(string bucketName, SceneObjectPart updatedPart) { - long timeStamp = DateTime.Now.Ticks; - m_lastUpdateSentTime[bucketName] = timeStamp; + OSDMap data = new OSDMap(); + + data["UUID"] = OSD.FromUUID(updatedPart.UUID); + //data["UUID"] = OSD.FromUUID(pa.UUID); + data["Bucket"] = OSD.FromString(bucketName); + + data["GroupPosition"] = OSD.FromVector3(updatedPart.GroupPosition); + data["OffsetPosition"] = OSD.FromVector3(updatedPart.OffsetPosition); + data["Scale"] = OSD.FromVector3(updatedPart.Scale); + data["AngularVelocity"] = OSD.FromVector3(updatedPart.AngularVelocity); + data["RotationOffset"] = OSD.FromQuaternion(updatedPart.RotationOffset); + + Physics.Manager.PhysicsActor pa = updatedPart.PhysActor; + if (pa != null) + { + + data["Size"] = OSD.FromVector3(pa.Size); + data["Position"] = OSD.FromVector3(pa.Position); + data["Force"] = OSD.FromVector3(pa.Force); + data["Velocity"] = OSD.FromVector3(pa.Velocity); + data["RotationalVelocity"] = OSD.FromVector3(pa.RotationalVelocity); + data["PA_Acceleration"] = OSD.FromVector3(pa.Acceleration); + data["Torque"] = OSD.FromVector3(pa.Torque); + data["Orientation"] = OSD.FromQuaternion(pa.Orientation); + data["IsPhysical"] = OSD.FromBoolean(pa.IsPhysical); + data["Flying"] = OSD.FromBoolean(pa.Flying); + data["Kinematic"] = OSD.FromBoolean(pa.Kinematic); + data["Buoyancy"] = OSD.FromReal(pa.Buoyancy); + data["CollidingGround"] = OSD.FromBoolean(pa.CollidingGround); + data["IsColliding"] = OSD.FromBoolean(pa.IsColliding); + + //m_log.DebugFormat("{0}: PhysBucketSender for {1}, pos={2}", LogHeader, updatedPart.UUID.ToString(), pa.Position.ToString()); + } + + data["LastUpdateTimeStamp"] = OSD.FromLong(updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp); + data["LastUpdateActorID"] = OSD.FromString(updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID); + + //m_log.Debug(LogHeader + " Send out Physics Bucket updates for " + updatedPart.Name + ","+updatedPart.UUID+ ". GroupPosition: " + updatedPart.GroupPosition.ToString()); + + return data; + } + + private void PhysicsBucketPropertiesDecoder(string bucketName, SymmetricSyncMessage msg, out Object sog) + { + OSDMap data = DeserializeMessage(msg); + sog = (Object)data; } - */ private bool HaveUpdatesToSendoutForSync(SceneObjectPart part, string bucketName) { @@ -863,22 +920,31 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule * */ } + //by default, there are two property buckets: the "General" bucket and the "Physics" bucket. + private string m_generalBucketName = "General"; + private string m_physicsBucketName = "Physics"; //If nothing configured in the config file, this is the default settings for grouping properties into different bucket private void PopulatePropertyBuketMapByDefault() { - //by default, there are two property buckets: the "General" bucket and the "Physics" bucket. - string generalBucketName = "General"; - string physicsBucketName = "Physics"; - m_propertyBucketNames.Add(generalBucketName); - m_propertyBucketNames.Add(physicsBucketName); + + m_propertyBucketNames.Add(m_generalBucketName); + m_propertyBucketNames.Add(m_physicsBucketName); m_maxNumOfPropertyBuckets = m_propertyBucketNames.Count; //Linking each bucket with the sender function that serializes the properties in the bucket and send out sync message - m_primUpdatesPerBucketSender.Add("General", PrimUpdatesGeneralBucketSender); - m_primUpdatesPerBucketSender.Add("Physics", PrimUpdatesPhysicsBucketSender); + m_primUpdatesPerBucketSender.Add(m_generalBucketName, PrimUpdatesGeneralBucketSender); + m_primUpdatesPerBucketSender.Add(m_physicsBucketName, PrimUpdatesPhysicsBucketSender); - m_lastUpdateSentTime.Add("General", 0); - m_lastUpdateSentTime.Add("Physics", 0); + /* + m_updatePerBucketEncoder.Add(generalBucketName, GeneralBucketPropertiesEncoder); + m_updatePerBucketEncoder.Add(physicsBucketName, PhysicsBucketPropertiesEncoder); + + m_updatePerBucketDecoder.Add(generalBucketName, GeneralBucketPropertiesDecoder); + m_updatePerBucketDecoder.Add(physicsBucketName, PhysicsBucketPropertiesDecoder); + * */ + + //m_lastUpdateSentTime.Add("General", 0); + //m_lastUpdateSentTime.Add("Physics", 0); //Mapping properties to buckets. foreach (SceneObjectPartProperties property in Enum.GetValues(typeof(SceneObjectPartProperties))) @@ -904,11 +970,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule case SceneObjectPartProperties.Buoyancy: case SceneObjectPartProperties.IsCollidingGround: case SceneObjectPartProperties.IsColliding: - m_primPropertyBucketMap.Add(property, physicsBucketName); + m_primPropertyBucketMap.Add(property, m_physicsBucketName); break; default: //all other properties belong to the "General" bucket. - m_primPropertyBucketMap.Add(property, generalBucketName); + m_primPropertyBucketMap.Add(property, m_generalBucketName); break; } } @@ -980,9 +1046,10 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //Events are send out right away, without being put into the connector's outQueue first. //May need a better method for managing the outgoing messages (i.e. prioritizing object updates and events) - private void SendSceneEventToRelevantSyncConnectors(string init_actorID, SymmetricSyncMessage rsm) + private void SendSceneEventToRelevantSyncConnectors(string init_actorID, SymmetricSyncMessage rsm, SceneObjectGroup sog) { - List syncConnectors = GetSyncConnectorsForSceneEvents(init_actorID, rsm); + //TODO: need to pick connectors based on sog position (quark it resides in) + List syncConnectors = GetSyncConnectorsForSceneEvents(init_actorID, rsm, sog); foreach (SyncConnector connector in syncConnectors) { @@ -1036,6 +1103,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //in other parts as well, so we are sending to all connectors. ForEachSyncConnector(delegate(SyncConnector connector) { + //if(!connector.OtherSideActorID.Equals(sog.BucketSyncInfoUpdate[ syncConnectors.Add(connector); }); } @@ -1062,7 +1130,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule /// /// /// - private List GetSyncConnectorsForSceneEvents(string init_actorID, SymmetricSyncMessage rsm) + private List GetSyncConnectorsForSceneEvents(string init_actorID, SymmetricSyncMessage rsm, SceneObjectGroup sog) { List syncConnectors = new List(); if (m_isSyncRelay) @@ -1559,8 +1627,10 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { if (e is SceneObjectGroup) { - string sogxml = SceneObjectSerializer.ToXml2Format((SceneObjectGroup)e); - SendSyncMessage(SymmetricSyncMessage.MsgType.NewObject, sogxml); + //string sogxml = SceneObjectSerializer.ToXml2Format((SceneObjectGroup)e); + //SendSyncMessage(SymmetricSyncMessage.MsgType.NewObject, sogxml); + SceneObjectGroup sog = (SceneObjectGroup)e; + SendNewObject(sog); //m_log.Debug(LogHeader + ": " + sogxml); } @@ -1644,19 +1714,45 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule private void HandleAddNewObject(SymmetricSyncMessage msg, string senderActorID) { - string sogxml = Encoding.ASCII.GetString(msg.Data, 0, msg.Length); + + //string sogxml = Encoding.ASCII.GetString(msg.Data, 0, msg.Length); + //SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(sogxml); + OSDMap data = DeserializeMessage(msg); + + //First, create the object group and add it to Scene + string sogxml = data["sogxml"]; SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(sogxml); - - //m_log.DebugFormat("{0}: received NewObject sync message from {1}, for object {1}, {2}", LogHeader, senderActorID, sog.Name, sog.UUID); - Scene.ObjectUpdateResult updateResult = m_scene.AddOrUpdateObjectBySynchronization(sog); - //if this is a relay node, forwards the event + //if this is a relay node, forward the event if (m_isSyncRelay) { - //SendSceneEventToRelevantSyncConnectors(init_actorID, msg); - SendSceneEventToRelevantSyncConnectors(senderActorID, msg); + SendSceneEventToRelevantSyncConnectors(senderActorID, msg, sog); } + + //Second, update the physics properties of each prim in the object + OSDArray partArray = (OSDArray)data["partPhysicsProperties"]; + for (int i = 0; i < partArray.Count; i++) + { + OSDMap partData = (OSDMap)partArray[i]; + UUID partUUID = partData["UUID"].AsUUID(); + + string bucketName = partData["Bucket"].AsString(); + + //m_log.DebugFormat("{0}: HandleUpdatedBucketProperties from {1}: for {2}/{3}", LogHeader, senderActorID, partUUID.ToString(), bucketName); + + BucketSyncInfo rBucketSyncInfo = new BucketSyncInfo(bucketName); + rBucketSyncInfo.LastUpdateTimeStamp = partData["LastUpdateTimeStamp"].AsLong(); + rBucketSyncInfo.LastUpdateActorID = partData["LastUpdateActorID"].AsString(); + // updatedPart.BucketSyncInfoList.Add(bucketName, rBucketSyncInfo); + + 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 HandleAddOrUpdateObjectBySynchronization(SymmetricSyncMessage msg, string senderActorID) @@ -1683,6 +1779,14 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } else { + foreach (SceneObjectPart part in sog.Parts) + { + if (part.IsAttachment) + { + m_log.Debug(LogHeader + "HandleAddOrUpdateObjectBySynchronization: part " + part.Name + "," + part.UUID + ", IsAttachment = true"); + } + } + Scene.ObjectUpdateResult updateResult = m_scene.AddOrUpdateObjectBySynchronization(sog); //if (added) @@ -1721,40 +1825,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule string bucketName = data["Bucket"].AsString(); //m_log.DebugFormat("{0}: HandleUpdatedBucketProperties from {1}: for {2}/{3}", LogHeader, senderActorID, partUUID.ToString(), bucketName); - - /* Commented out since OSDMap is now passed all the way through to the unpacker. - * Previous implementation is to create a SOP and copy the values into same and copy them out later. - SceneObjectPart updatedPart = new SceneObjectPart(); - updatedPart.GroupPosition = data["GroupPosition"].AsVector3(); - updatedPart.OffsetPosition = data["OffsetPosition"].AsVector3(); - updatedPart.RotationOffset = data["RotationOffset"].AsQuaternion(); - updatedPart.Velocity = data["Velocity"].AsVector3(); - updatedPart.AngularVelocity = data["AngularVelocity"].AsVector3(); - //Scale is a bit complex, we need to have Shape first -- not a good solution, but leave it as is so that we can move on, - updatedPart.Shape = new PrimitiveBaseShape(); - updatedPart.Scale = data["Scale"].AsVector3(); - - Dictionary updatedProperties = new Dictionary(); - updatedProperties.Add("GroupPosition", (Object)data["GroupPosition"].AsVector3()); - updatedProperties.Add("OffsetPosition", (Object)data["OffsetPosition"].AsVector3()); - updatedProperties.Add("RotationOffset", (Object)data["RotationOffset"].AsQuaternion()); - updatedProperties.Add("Velocity", (Object)data["Velocity"].AsVector3()); - updatedProperties.Add("AngularVelocity", (Object)data["AngularVelocity"].AsVector3()); - updatedProperties.Add("Scale", (Object)data["Scale"].AsVector3()); - */ - //Other properties to be included - /* - "Position": - "Size": - "Force": - "RotationalVelocity": - "PA_Acceleration": - "Torque": - "Orientation": - "IsPhysical": - "Flying": - "Buoyancy": - * */ BucketSyncInfo rBucketSyncInfo = new BucketSyncInfo(bucketName); rBucketSyncInfo.LastUpdateTimeStamp = data["LastUpdateTimeStamp"].AsLong(); @@ -1832,6 +1902,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule SceneObjectGroup sog = m_scene.SceneGraph.GetGroupByPrim(sogUUID); + //if this is a relay node, forwards the event + if (m_isSyncRelay) + { + SendSceneEventToRelevantSyncConnectors(senderActorID, msg, sog); + } + + if (sog != null) { if (!softDelete) @@ -1846,12 +1923,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } } - //if this is a relay node, forwards the event - if (m_isSyncRelay) - { - //SendSceneEventToRelevantSyncConnectors(init_actorID, msg); - SendSceneEventToRelevantSyncConnectors(senderActorID, msg); - } + } private void HandleLinkObject(SymmetricSyncMessage msg, string senderActorID) @@ -1872,6 +1944,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule int partCount = data["partCount"].AsInteger(); List childrenIDs = new List(); + + //if this is a relay node, forwards the event + if (m_isSyncRelay) + { + SendSceneEventToRelevantSyncConnectors(senderActorID, msg, linkedGroup); + } + for (int i = 0; i < partCount; i++) { string partTempID = "part" + i; @@ -1881,18 +1960,28 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_log.Debug(LogHeader + " received LinkObject from " + senderActorID); //m_log.Debug("LinkedObject: " + sogxml); + //TEMP DEBUG + foreach (SceneObjectPart part in linkedGroup.Parts) + { + if (part.IsAttachment) + { + m_log.Debug(LogHeader + "HandleLinkObject: part " + part.Name + "," + part.UUID + " IsAttachment = true in incoming sync message"); + } + } + m_scene.LinkObjectBySync(linkedGroup, rootID, childrenIDs); - //if this is a relay node, forwards the event - if (m_isSyncRelay) - { - //SendSceneEventToRelevantSyncConnectors(init_actorID, msg); - SendSceneEventToRelevantSyncConnectors(senderActorID, msg); - } + } private void HandleDelinkObject(SymmetricSyncMessage msg, string senderActorID) { + //if this is a relay node, forwards the event + if (m_isSyncRelay) + { + SendSceneEventToRelevantSyncConnectors(senderActorID, msg, null); + } + OSDMap data = DeserializeMessage(msg); if (data == null) { @@ -1934,12 +2023,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule m_scene.DelinkObjectsBySync(delinkPrimIDs, beforeDelinkGroupIDs, incomingAfterDelinkGroups); - //if this is a relay node, forwards the event - if (m_isSyncRelay) - { - //SendSceneEventToRelevantSyncConnectors(init_actorID, msg); - SendSceneEventToRelevantSyncConnectors(senderActorID, msg); - } } /// @@ -1948,6 +2031,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule /// private void HandleRemoteEvent(SymmetricSyncMessage msg, string senderActorID) { + + //if this is a relay node, forwards the event + if (m_isSyncRelay) + { + SendSceneEventToRelevantSyncConnectors(senderActorID, msg, null); + } + OSDMap data = DeserializeMessage(msg); if (data == null) { @@ -1994,12 +2084,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule break; } - //if this is a relay node, forwards the event - if (m_isSyncRelay) - { - //SendSceneEventToRelevantSyncConnectors(init_actorID, msg); - SendSceneEventToRelevantSyncConnectors(senderActorID, msg); - } } /// @@ -2352,14 +2436,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule data["running"] = OSD.FromBoolean(isScriptRunning); data["assetID"] = OSD.FromUUID(newAssetID); - /* - data["actorID"] = OSD.FromString(m_actorID); - data["seqNum"] = OSD.FromULong(GetNextEventSeq()); - - SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.UpdateScript, OSDParser.SerializeJsonString(data)); - //send to actors who are interested in the event - SendSceneEventToRelevantSyncConnectors(m_actorID, rsm); - * */ SendSceneEvent(SymmetricSyncMessage.MsgType.UpdateScript, data); } @@ -2584,20 +2660,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //send to actors who are interested in the event lock (m_stats) m_statEventOut++; - SendSceneEventToRelevantSyncConnectors(m_actorID, rsm); + SendSceneEventToRelevantSyncConnectors(m_actorID, rsm, null); } - /* - private void PublishSceneEvent(OSDMap data) - { - data["actorID"] = OSD.FromString(m_actorID); - data["seqNum"] = OSD.FromULong(GetNextEventSeq()); - - SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.OnUpdateScript, OSDParser.SerializeJsonString(data)); - SendSceneEventToRelevantSyncConnectors(m_actorID, rsm); - } - * */ - private ulong GetNextEventSeq() { return m_eventSeq++; diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 6d086d6844..c1ea8a3340 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2203,6 +2203,13 @@ namespace OpenSim.Region.Framework.Scenes partnames += "(" + part.Name + ", " + part.UUID + ")"; } m_log.DebugFormat("[SCENE] RezObject {0} with InvItem name {1} at pos {2} with parts {3}", group.UUID.ToString(), item.Name, group.RootPart.GroupPosition.ToString(), partnames); + foreach (SceneObjectPart part in group.Parts) + { + if (part.IsAttachment) + { + m_log.Debug("[SCENE]: part " + part.Name + "," + part.UUID + ", IsAttachment = true"); + } + } // We can only call this after adding the scene object, since the scene object references the scene // to find out if scripts should be activated at all. diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 941988f750..8f1d9f6198 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -795,7 +795,7 @@ namespace OpenSim.Region.Framework.Scenes } //m_log.Debug("to link part " + part.DebugObjectPartProperties()); - m_log.Debug("to link part " + part.Name + "," + part.UUID + "; its SOG has " + part.ParentGroup.Parts + " parts"); + m_log.Debug("LinkObjectBySync: " + part.Name + "," + part.UUID + " with root "+root.Name+","+root.UUID+"; its SOG has " + part.ParentGroup.Parts + " parts"); children.Add(part); } @@ -805,7 +805,13 @@ namespace OpenSim.Region.Framework.Scenes //Leverage the LinkObject implementation to get the book keeping of Group and Parts relations right m_sceneGraph.LinkObjectsBySync(root, children); - + foreach (SceneObjectPart part in linkedGroup.Parts) + { + if (part.IsAttachment) + { + m_log.Debug("LinkObjectBySync: part " + part.Name + "," + part.UUID + " IsAttachment = true after linking"); + } + } //The properties of the newly linked object should be updated later with another UpdatedObject message. diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index a3ec2ecedf..f077318467 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2113,9 +2113,9 @@ namespace OpenSim.Region.Framework.Scenes // objectGroup.RootPart.SendScheduledUpdates(); //} - // m_log.DebugFormat( - // "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}", - // objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID); + m_log.DebugFormat( + "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}", + objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID); SceneObjectPart linkPart = objectGroup.m_rootPart; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 6d618588ad..06dd420676 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -5479,6 +5479,8 @@ namespace OpenSim.Region.Framework.Scenes localPart.TextureAnimation = updatedPart.TextureAnimation; localPart.ParticleSystem = updatedPart.ParticleSystem; + bool preIsAttachment = localPart.IsAttachment; + if (!localPart.AttachedAvatar.Equals(updatedPart.AttachedAvatar)) { localPart.AttachedAvatar = updatedPart.AttachedAvatar; @@ -5494,6 +5496,11 @@ namespace OpenSim.Region.Framework.Scenes // localPart.IsAttachment = updatedPart.IsAttachment; //} + if (localPart.IsAttachment) + { + m_log.Debug("GeneralBucketUpdateProcessor: part " + localPart.Name + "," + localPart.UUID + ", IsAttachment = true; previously, IsAttachment = " + preIsAttachment.ToString()); + } + localPart.AggregateScriptEvents = updatedPart.AggregateScriptEvents; m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp = updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp; @@ -5856,7 +5863,7 @@ namespace OpenSim.Region.Framework.Scenes { if (!m_bucketSyncInfoList[bucketName].LastUpdateActorID.Equals(rBucketSyncInfo.LastUpdateActorID)) { - m_log.Warn("Different actors modified SceneObjetPart " + Name + "," + UUID + ", bucket " + bucketName + ", with the same TimeStamp (" + m_log.Warn("UpdateBucketProperties: Different actors modified SceneObjetPart " + Name + "," + UUID + ", bucket " + bucketName + ", with the same TimeStamp (" + m_bucketSyncInfoList[bucketName].LastUpdateActorID + "," + rBucketSyncInfo.LastUpdateActorID + ", CONFLICT RESOLUTION TO BE IMPLEMENTED, PICK A WINNER!!!!"); From 271f460baef713b107b983317eee1e65d7df9f30 Mon Sep 17 00:00:00 2001 From: "Huaiyu (Kitty) Liu" Date: Wed, 16 Mar 2011 11:32:26 -0700 Subject: [PATCH 2/2] Handler of SymmetricSyncMessage.MsgType.UpdatedObject changed to HandleUpdateObjectBySynchronization, that is, since we add objects in scene by sending around NewObject, we no longer "add" objects after receiving UpdateObject. Also, ProcessBackup is now only executed by Persistece Actor (ScenePersistenceSyncModule, if configured to run, will set each SOG's ToPersistObjectState to true). --- .../SymmetricSync/RegionSyncModule.cs | 48 +++++++++++++++++-- .../ScenePersistenceSyncModule.cs | 23 +++++++-- OpenSim/Region/Framework/Scenes/Scene.cs | 13 +++-- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 46 ++++++++++++++++-- .../Framework/Scenes/SceneObjectGroup.cs | 17 ++++++- 5 files changed, 129 insertions(+), 18 deletions(-) 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);