diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index 857d811d23..0ef52b184f 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs @@ -391,8 +391,10 @@ namespace OpenSim.Framework private string m_syncListenerAddr = String.Empty; private int m_syncListenerPort; //IP:port for the avatar sync server this actor is configured to connect to - private string m_serverAddr = String.Empty; - private int m_serverPort; + private string m_avatarSyncServerAddr = String.Empty; + private int m_avatarSyncServerPort; + private uint m_quarkLocX; + private uint m_quarkLocY; //end of SYMMETRIC SYNC // Apparently, we're applying the same estatesettings regardless of whether it's local or remote. @@ -693,13 +695,25 @@ namespace OpenSim.Framework { get { return m_syncListenerPort; } } - public string ServerIPAddress + public string AvatarSyncServerAddress { - get { return m_serverAddr; } + get { return m_avatarSyncServerAddr; } } - public int ServerPort + public int AvatarSyncServerPort { - get { return m_serverPort; } + get { return m_avatarSyncServerPort; } + } + + public uint SyncQuarkLocationX + { + get { return m_quarkLocX; } + set { m_quarkLocX = value; } + } + + public uint SyncQuarkLocationY + { + get { return m_quarkLocY; } + set { m_quarkLocY = value; } } //end of SYMMETRIC SYNC @@ -859,16 +873,24 @@ namespace OpenSim.Framework ScopeID = new UUID(config.GetString("ScopeID", UUID.Zero.ToString())); // SYMMETRIC SYNC - m_syncListenerAddr = config.GetString("SyncListenerIPAddress", String.Empty); + m_syncListenerAddr = config.GetString("SyncListenerAddress", String.Empty); m_syncListenerPort = config.GetInt("SyncListenerPort", -1); //if either IP or port is not configured, we set IP to empty to raise warning later if (m_syncListenerPort == -1) m_syncListenerAddr = String.Empty; - m_serverAddr = config.GetString("ServerIPAddress", String.Empty); - m_serverPort = config.GetInt("ServerPort", -1); - if (m_serverPort == -1) - m_serverAddr = String.Empty; + m_avatarSyncServerAddr = config.GetString("AvatarSyncServerAddress", String.Empty); + m_avatarSyncServerPort = config.GetInt("AvatarSyncServerPort", -1); + if (m_avatarSyncServerPort == -1) + m_avatarSyncServerAddr = String.Empty; + + string quarkLocation = config.GetString("SyncQuarkLocation", String.Empty); + + string[] quarkLocElements = location.Split(new char[] { ',' }); + + m_quarkLocX = Convert.ToUInt32(quarkLocElements[0]); + m_quarkLocY = Convert.ToUInt32(quarkLocElements[1]); + // end of SYMMETRIC SYNC diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClientModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClientModule.cs index c0bd54ca56..cb4c079c0c 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClientModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncClientModule.cs @@ -232,8 +232,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule private void Start() { - m_serveraddr = m_scene.RegionInfo.ServerIPAddress; - m_serverport = m_scene.RegionInfo.ServerPort; + m_serveraddr = m_scene.RegionInfo.AvatarSyncServerAddress; + m_serverport = m_scene.RegionInfo.AvatarSyncServerPort; if (m_serveraddr.Equals(String.Empty) || m_serverport == -1) { diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs index 0dab1b4205..0345136f4b 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/RegionSyncServerModule.cs @@ -166,8 +166,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } //end of SYMMETRIC SYNC // Start the server and listen for RegionSyncClients - m_serveraddr = m_scene.RegionInfo.ServerIPAddress; - m_serverport = m_scene.RegionInfo.ServerPort; + m_serveraddr = m_scene.RegionInfo.AvatarSyncServerAddress; + m_serverport = m_scene.RegionInfo.AvatarSyncServerPort; m_log.Debug("[REGION SYNC SERVER MODULE] to start server on " + m_serveraddr + ":" + m_serverport); diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs index 9ff693bc9b..3a9bc7da31 100644 --- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs +++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs @@ -1013,7 +1013,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule { // Get the data from message and error check OSDMap data = DeserializeMessage(msg); - string init_actorID = data["actorID"].AsString(); if (data == null) { @@ -1023,11 +1022,20 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule } UUID sogUUID = data["UUID"].AsUUID(); + string init_actorID = data["actorID"].AsString(); + bool softDelete = data["softDelete"].AsBoolean(); SceneObjectGroup sog = m_scene.SceneGraph.GetGroupByPrim(sogUUID); if (sog != null) { - m_scene.DeleteSceneObjectBySynchronization(sog); + if (!softDelete) + { + m_scene.DeleteSceneObjectBySynchronization(sog); + } + else + { + m_scene.UnlinkSceneObject(sog, true); + } } //if this is a relay node, forwards the event @@ -1331,7 +1339,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule /// /// //private void RegionSyncModule_OnObjectBeingRemovedFromScene(SceneObjectGroup sog) - public void SendDeleteObject(SceneObjectGroup sog) + public void SendDeleteObject(SceneObjectGroup sog, bool softDelete) { //m_log.DebugFormat("RegionSyncModule_OnObjectBeingRemovedFromScene called at time {0}:{1}:{2}", DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond); @@ -1344,6 +1352,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule //data["localID"] = OSD.FromUInteger(sog.LocalId); data["UUID"] = OSD.FromUUID(sog.UUID); data["actorID"] = OSD.FromString(m_actorID); + data["softDelete"] = OSD.FromBoolean(softDelete); SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.RemovedObject, OSDParser.SerializeJsonString(data)); SendObjectUpdateToRelevantSyncConnectors(sog, rsm); diff --git a/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs index 8709d4cd46..5048434859 100755 --- a/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IRegionSyncModule.cs @@ -63,7 +63,7 @@ namespace OpenSim.Region.Framework.Interfaces //void SendUpdatesToSynchronizeState(List sog); void SendSceneUpdates(); void SendTerrainUpdates(string lastUpdateActorID); - void SendDeleteObject(SceneObjectGroup sog); + void SendDeleteObject(SceneObjectGroup sog, bool softDelete); //For propogating scene events to other actors void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 030144b76b..6c7aade51f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -709,6 +709,15 @@ namespace OpenSim.Region.Framework.Scenes } + public void AddNewSceneObjectPart(SceneObjectPart newPart, SceneObjectGroup parentGroup) + { + //assign a local ID. + newPart.LocalId = AllocateLocalId(); + //add it to SceneGraph's record. + m_sceneGraph.AddNewSceneObjectPart(newPart, parentGroup); + } + + #endregion //SYMMETRIC SYNC public ICapabilitiesModule CapsModule @@ -2475,7 +2484,7 @@ namespace OpenSim.Region.Framework.Scenes //Propagate the RemovedObject message if (RegionSyncModule != null) { - RegionSyncModule.SendDeleteObject(group); + RegionSyncModule.SendDeleteObject(group, false); } //end of SYMMETRIC SYNC diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 8666fe8ab9..af789e78f1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1945,7 +1945,7 @@ namespace OpenSim.Region.Framework.Scenes if (entity is SceneObjectGroup) { SceneObjectGroup localSog = (SceneObjectGroup)entity; - Scene.ObjectUpdateResult updateResult = localSog.UpdateObjectAllProperties(updatedSog); + Scene.ObjectUpdateResult updateResult = localSog.UpdateObjectGroupBySync(updatedSog); return updateResult; } else @@ -2027,6 +2027,26 @@ namespace OpenSim.Region.Framework.Scenes return true; } + public void AddNewSceneObjectPart(SceneObjectPart newPart, SceneObjectGroup parentGroup) + { + SceneObjectPart[] children = parentGroup.Parts; + + lock (SceneObjectGroupsByFullID) + { + SceneObjectGroupsByFullID[parentGroup.UUID] = parentGroup; + foreach (SceneObjectPart part in children) + SceneObjectGroupsByFullID[newPart.UUID] = parentGroup; + } + + lock (SceneObjectGroupsByLocalID) + { + SceneObjectGroupsByLocalID[parentGroup.LocalId] = parentGroup; + foreach (SceneObjectPart part in children) + SceneObjectGroupsByLocalID[newPart.LocalId] = parentGroup; + } + } + + #endregion //SYMMETRIC SYNC } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 044af42cb8..175b37567b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2041,9 +2041,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; @@ -2112,9 +2112,9 @@ namespace OpenSim.Region.Framework.Scenes objectGroup.m_isDeleted = true; objectGroup.m_parts.Clear(); - + // Can't do this yet since backup still makes use of the root part without any synchronization -// objectGroup.m_rootPart = null; + // objectGroup.m_rootPart = null; AttachToBackup(); @@ -2125,6 +2125,12 @@ namespace OpenSim.Region.Framework.Scenes //HasGroupChanged = true; //ScheduleGroupForFullUpdate(); + + //SYMMETRIC SYNC + if (m_scene.RegionSyncModule != null) + m_scene.RegionSyncModule.SendDeleteObject(objectGroup, true); + //end of SYMMETRIC SYNC + } /// @@ -3474,10 +3480,11 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// - public Scene.ObjectUpdateResult UpdateObjectAllProperties(SceneObjectGroup updatedSog) + public Scene.ObjectUpdateResult UpdateObjectGroupBySync(SceneObjectGroup updatedSog) { - if (!this.GroupID.Equals(updatedSog.GroupID)) - return Scene.ObjectUpdateResult.Error; + //This GroupID check should be done by the actor who initiates the object update + //if (!this.GroupID.Equals(updatedSog.GroupID)) + // return Scene.ObjectUpdateResult.Error; //////////////////////////////////////////////////////////////////////////////////////////////////// //NOTE!!! @@ -3494,16 +3501,84 @@ namespace OpenSim.Region.Framework.Scenes bool partsRemoved = false; //has any old part been removed? bool rootPartChanged = false; //has the rootpart be changed to a different prim? - lock (m_parts) + lock (m_parts.SyncRoot) { //update rootpart, if changed + /* if (m_rootPart.UUID != updatedSog.RootPart.UUID) { m_rootPart = updatedSog.RootPart; rootPartChanged = true; } + * */ //foreach (KeyValuePair pair in updatedSog.Parts) + Dictionary remainedParts = new Dictionary(); + Dictionary removedParts = new Dictionary(); + Dictionary newParts = new Dictionary(); + + //Compare the parts in updatedSog and sort them into remained/removed/newParts groups + foreach (SceneObjectPart updatedPart in updatedSog.Parts) + { + UUID partUUID = updatedPart.UUID; + if (ContainsPart(partUUID)) + { + SceneObjectPart localPart = GetChildPart(partUUID); + remainedParts.Add(partUUID, localPart); + } + else + { + //in case the part is in the SceneGraph already + SceneObjectPart localPart = m_scene.GetSceneObjectPart(partUUID); + if(localPart!=null) + newParts.Add(partUUID, localPart); + else + newParts.Add(partUUID, updatedPart); + } + } + + foreach (SceneObjectPart localPart in this.Parts) + { + if (!remainedParts.ContainsKey(localPart.UUID)) + removedParts.Add(localPart.UUID, localPart); + } + + //Add in new parts + foreach (SceneObjectPart newPart in newParts.Values) + { + //AddPart(newPart); + AddNewPart(newPart); + } + + //remove parts that are no longer in the group -- !!!!! need to further test how to do correct book-keeping and synchornized with other actors !!!!!!!! + foreach (SceneObjectPart rmPart in removedParts.Values) + { + DelinkFromGroup(rmPart, true); + } + + if (newParts.Count > 0 || removedParts.Count > 0) + { + groupUpdateResult = Scene.ObjectUpdateResult.Updated; + } + + //now update properties of the parts + foreach (SceneObjectPart part in this.Parts) + { + Scene.ObjectUpdateResult partUpdateResult = Scene.ObjectUpdateResult.Unchanged; + SceneObjectPart updatedPart = updatedSog.GetChildPart(part.UUID); + partUpdateResult = part.UpdateAllProperties(updatedPart); + + if (partUpdateResult != Scene.ObjectUpdateResult.Unchanged) + { + groupUpdateResult = partUpdateResult; + } + } + + //Just to make sure the parts each has the right localID of the rootpart + UpdateParentIDs(); + + /* + //old code below foreach (SceneObjectPart updatedPart in updatedSog.Parts) { UUID partUUID = updatedPart.UUID; @@ -3547,27 +3622,9 @@ namespace OpenSim.Region.Framework.Scenes { UpdateParentIDs(); } + * */ } - if (partsRemoved) - { - groupUpdateResult = Scene.ObjectUpdateResult.Updated; - } - - /* - //update the authoritative scene that this object is located, which is identified by (LocX, LocY) - if (this.m_locX != updatedSog.LocX) - { - this.m_locX = updatedSog.LocX; - groupUpdateResult = Scene.ObjectUpdateResult.Updated; - } - if (this.m_locY != updatedSog.LocY) - { - this.m_locY = updatedSog.LocY; - groupUpdateResult = Scene.ObjectUpdateResult.Updated; - } - * */ - //Schedule updates to be sent out, if the local copy has just been updated //(1) if we are debugging the actor with a viewer attaching to it, //we need to schedule updates to be sent to the viewer. @@ -3581,6 +3638,14 @@ namespace OpenSim.Region.Framework.Scenes return groupUpdateResult; } + private void AddNewPart(SceneObjectPart newPart) + { + //set the parent relationship + AddPart(newPart); + + m_scene.AddNewSceneObjectPart(newPart, this); + } + public void ScheduleGroupForFullUpdate_SyncInfoUnchanged() { if (IsAttachment)