diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs
index 2f67eec957..1bcc664136 100755
--- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs
+++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/RegionSyncModule.cs
@@ -289,7 +289,15 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
});
}
-
+ public void SendTerrainUpdates(string lastUpdateActorID)
+ {
+ if(m_isSyncRelay || m_actorID.Equals(lastUpdateActorID))
+ {
+ //m_scene.Heightmap should have been updated already by the caller, send it out
+ //SendSyncMessage(SymmetricSyncMessage.MsgType.Terrain, m_scene.Heightmap.SaveToXmlString());
+ SendTerrainUpdateMessage();
+ }
+ }
#endregion //IRegionSyncModule
@@ -713,6 +721,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
}
}
+
+
///
/// The handler for processing incoming sync messages.
///
@@ -723,13 +733,19 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
{
case SymmetricSyncMessage.MsgType.GetTerrain:
{
- SendSyncMessage(SymmetricSyncMessage.MsgType.Terrain, m_scene.Heightmap.SaveToXmlString());
+ //SendSyncMessage(SymmetricSyncMessage.MsgType.Terrain, m_scene.Heightmap.SaveToXmlString());
+ SendTerrainUpdateMessage();
return;
}
case SymmetricSyncMessage.MsgType.Terrain:
{
+ /*
m_scene.Heightmap.LoadFromXmlString(Encoding.ASCII.GetString(msg.Data, 0, msg.Length));
+ //Inform the terrain module that terrain has been updated
+ m_scene.RequestModuleInterface().TaintTerrain();
m_log.Debug(LogHeader+": Synchronized terrain");
+ * */
+ HandleTerrainUpdateMessage(msg);
return;
}
case SymmetricSyncMessage.MsgType.GetObjects:
@@ -764,7 +780,28 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
}
}
- public void HandleAddOrUpdateObjectBySynchronization(SymmetricSyncMessage msg)
+ private void HandleTerrainUpdateMessage(SymmetricSyncMessage msg)
+ {
+ // Get the data from message and error check
+ OSDMap data = DeserializeMessage(msg);
+
+ if (data == null)
+ {
+ SymmetricSyncMessage.HandleError(LogHeader, msg, "Could not deserialize JSON data.");
+ return;
+ }
+
+ string msgData = data["terrain"].AsString();
+ long lastUpdateTimeStamp = data["actorID"].AsLong();
+ string lastUpdateActorID = data["timeStamp"].AsString();
+
+ //set new terrain
+ m_scene.Heightmap.LoadFromXmlString(msgData);
+ m_scene.RequestModuleInterface().TaintTerrianBySynchronization(lastUpdateTimeStamp, lastUpdateActorID); ;
+ m_log.Debug(LogHeader + ": Synchronized terrain");
+ }
+
+ private void HandleAddOrUpdateObjectBySynchronization(SymmetricSyncMessage msg)
{
string sogxml = Encoding.ASCII.GetString(msg.Data, 0, msg.Length);
SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(sogxml);
@@ -797,6 +834,21 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
}
}
+ private void SendTerrainUpdateMessage()
+ {
+ string msgData = m_scene.Heightmap.SaveToXmlString();
+ long lastUpdateTimeStamp;
+ string lastUpdateActorID;
+ m_scene.RequestModuleInterface().GetSyncInfo(out lastUpdateTimeStamp, out lastUpdateActorID);
+
+ OSDMap data = new OSDMap(3);
+ data["terrain"] = OSD.FromString(msgData);
+ data["actorID"] = OSD.FromString(lastUpdateActorID);
+ data["timeStamp"] = OSD.FromLong(lastUpdateTimeStamp);
+
+ SendSyncMessage(SymmetricSyncMessage.MsgType.Terrain, OSDParser.SerializeJsonString(data));
+ }
+
private void HandleRemovedObject(SymmetricSyncMessage msg)
{
// Get the data from message and error check
diff --git a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/SymmetricSyncMessage.cs b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/SymmetricSyncMessage.cs
index c4a1d79c74..b4b960ace1 100755
--- a/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/SymmetricSyncMessage.cs
+++ b/OpenSim/Region/CoreModules/RegionSync/RegionSyncModule/SymmetricSync/SymmetricSyncMessage.cs
@@ -30,7 +30,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
NewObject, // objects
UpdatedObject, // objects
RemovedObject, // objects
-
// BIDIR
//EchoRequest,
//EchoResponse,
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index 25d73c2c0f..276fcfe9a2 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -589,6 +589,56 @@ namespace OpenSim.Region.CoreModules.World.Terrain
client.OnUnackedTerrain += client_OnUnackedTerrain;
}
+ //SYMMETRIC SYNC
+ private long m_lastUpdateTimeStamp = DateTime.Now.Ticks;
+ public long LastUpdateTimeStamp
+ {
+ get { return m_lastUpdateTimeStamp; }
+ set { m_lastUpdateTimeStamp = value; }
+ }
+
+ private string m_lastUpdateActorID;
+ public string LastUpdateActorID
+ {
+ get { return m_lastUpdateActorID; }
+ set { m_lastUpdateActorID = value; }
+ }
+
+ private void SyncInfoUpdate(long timeStamp, string actorID)
+ {
+ m_lastUpdateTimeStamp = timeStamp;
+ m_lastUpdateActorID = actorID;
+ }
+
+ /*
+ public void CheckForTerrainUpdatesBySynchronization(long timeStamp, string actorID)
+ {
+ SyncInfoUpdate(timeStamp, actorID);
+ CheckForTerrainUpdates(false);
+ }
+ * */
+
+ public void TaintTerrianBySynchronization(long timeStamp, string actorID)
+ {
+ SyncInfoUpdate(timeStamp, actorID);
+ CheckForTerrainUpdates(false, timeStamp, actorID);
+ }
+
+ public bool TerrianModifiedLocally(string localActorID)
+ {
+ if (localActorID == m_lastUpdateActorID)
+ return true;
+ return false;
+ }
+
+ public void GetSyncInfo(out long lastUpdateTimeStamp, out string lastUpdateActorID)
+ {
+ lastUpdateTimeStamp = m_lastUpdateTimeStamp;
+ lastUpdateActorID = m_lastUpdateActorID;
+ }
+
+ //end of SYMMETRIC SYNC
+
///
/// Checks to see if the terrain has been modified since last check
/// but won't attempt to limit those changes to the limits specified in the estate settings
@@ -596,7 +646,21 @@ namespace OpenSim.Region.CoreModules.World.Terrain
///
private void CheckForTerrainUpdates()
{
- CheckForTerrainUpdates(false);
+ //SYMMETRIC SYNC
+
+ //Assumption: Thus function is only called when the terrain is updated by the local actor.
+ // Updating terrain during receiving sync messages from another actor will call CheckForTerrainUpdates.
+
+ //Update the timestamp to the current time tick, and set the LastUpdateActorID to be self
+ long currentTimeTick = DateTime.Now.Ticks;
+ string localActorID = m_scene.GetSyncActorID();
+ SyncInfoUpdate(currentTimeTick, localActorID);
+ //Check if the terrain has been modified and send out sync message if modified.
+ CheckForTerrainUpdates(false, currentTimeTick, localActorID);
+
+ //end of SYMMETRIC SYNC
+
+ //CheckForTerrainUpdates(false);
}
///
@@ -607,7 +671,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain
/// currently invoked by client_OnModifyTerrain only and not the Commander interfaces
/// should height map deltas be limited to the estate settings limits
///
- private void CheckForTerrainUpdates(bool respectEstateSettings)
+ //private void CheckForTerrainUpdates(bool respectEstateSettings)
+ //SYMMETRIC SYNC: Change the interface, to input the right sync information for the most recent update
+ private void CheckForTerrainUpdates(bool respectEstateSettings, long lastUpdateTimeStamp, string lastUpdateActorID)
+ //end of SYMMETRIC SYNC
{
bool shouldTaint = false;
float[] serialised = m_channel.GetFloatsSerialised();
@@ -636,6 +703,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain
if (shouldTaint)
{
m_tainted = true;
+ //SYMMETRIC SYNC
+ //Terrain has been modified, send out sync message if needed
+ if (m_scene.RegionSyncModule != null)
+ {
+ m_scene.RegionSyncModule.SendTerrainUpdates(m_lastUpdateActorID);
+ }
+ //end of SYMMETRIC SYNC
}
}
@@ -748,7 +822,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain
m_painteffects[(StandardTerrainEffects) action].PaintEffect(
m_channel, allowMask, west, south, height, size, seconds);
- CheckForTerrainUpdates(!god); //revert changes outside estate limits
+ //CheckForTerrainUpdates(!god); //revert changes outside estate limits
+ //SYMMETRIC SYNC
+ CheckForTerrainUpdates(!god, DateTime.Now.Ticks, m_scene.GetSyncActorID());
+ //end of SYMMETRIC SYNC
}
}
else
@@ -789,7 +866,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain
m_floodeffects[(StandardTerrainEffects) action].FloodEffect(
m_channel, fillArea, size);
- CheckForTerrainUpdates(!god); //revert changes outside estate limits
+ //CheckForTerrainUpdates(!god); //revert changes outside estate limits
+ //SYMMETRIC SYNC
+ CheckForTerrainUpdates(!god, DateTime.Now.Ticks, m_scene.GetSyncActorID());
+ //end of SYMMETRIC SYNC
}
}
else
diff --git a/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs b/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs
index 5947afb927..8f7606bbc7 100644
--- a/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs
@@ -64,5 +64,11 @@ namespace OpenSim.Region.Framework.Interfaces
void InstallPlugin(string name, ITerrainEffect plug);
void UndoTerrain(ITerrainChannel channel);
+
+ //SYMMETRIC SYNC
+ void TaintTerrianBySynchronization(long timeStamp, string actorID);
+ bool TerrianModifiedLocally(string localActorID);
+ void GetSyncInfo(out long lastUpdateTimeStamp, out string lastUpdateActorID);
+ //end of SYMMETRIC SYNC
}
}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 36d99d78a7..8476ff6b82 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -612,6 +612,15 @@ namespace OpenSim.Region.Framework.Scenes
Error //Errors happen during processing the message, e.g. the entity with the given UUID is not of type SceneObjectGroup
}
+ public string GetSyncActorID()
+ {
+ if (m_DSGActorSyncModule != null)
+ {
+ return m_DSGActorSyncModule.ActorID;
+ }
+ return "";
+ }
+
//This function should only be called by an actor who's local Scene is just a cache of the authorative Scene.
//If the object already exists, use the new copy to replace it.
//Return true if added, false if just updated
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 178f2b7e71..fd92853775 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -4928,11 +4928,11 @@ namespace OpenSim.Region.Framework.Scenes
//The ID the identifies which actor has caused the most recent update to the prim.
//We use type "string" for the ID only to make it human-readable.
- private string m_lastUpdateByActorID;
+ private string m_lastUpdateActorID;
public string LastUpdateActorID
{
- get { return m_lastUpdateByActorID; }
- set { m_lastUpdateByActorID = value; }
+ get { return m_lastUpdateActorID; }
+ set { m_lastUpdateActorID = value; }
}
public void UpdateTimestamp()
@@ -4944,7 +4944,7 @@ namespace OpenSim.Region.Framework.Scenes
{
if (m_parentGroup != null)
{
- m_lastUpdateByActorID = m_parentGroup.Scene.ActorSyncModule.ActorID;
+ m_lastUpdateActorID = m_parentGroup.Scene.ActorSyncModule.ActorID;
}
else
{
@@ -4960,7 +4960,7 @@ namespace OpenSim.Region.Framework.Scenes
if (m_parentGroup != null)
{
UpdateTimestamp();
- m_lastUpdateByActorID = m_parentGroup.Scene.ActorSyncModule.ActorID;
+ m_lastUpdateActorID = m_parentGroup.Scene.ActorSyncModule.ActorID;
}
}
@@ -4994,7 +4994,7 @@ namespace OpenSim.Region.Framework.Scenes
if (m_lastUpdateTimeStamp == updatedPart.LastUpdateTimeStamp)
{
//if (m_parentGroup.Scene.GetActorID() != updatedPart.LastUpdatedByActorID)
- if (m_lastUpdateByActorID != updatedPart.LastUpdateActorID)
+ if (m_lastUpdateActorID != updatedPart.LastUpdateActorID)
{
m_log.Warn("Different actors modified SceneObjetPart " + UUID + " with the same TimeStamp, CONFLICT RESOLUTION TO BE IMPLEMENTED!!!!");
return Scene.ObjectUpdateResult.Unchanged;
@@ -5067,7 +5067,7 @@ namespace OpenSim.Region.Framework.Scenes
this.ParticleSystem = updatedPart.ParticleSystem;
//Update the timestamp and LastUpdatedByActorID first.
- this.m_lastUpdateByActorID = updatedPart.LastUpdateActorID;
+ this.m_lastUpdateActorID = updatedPart.LastUpdateActorID;
this.m_lastUpdateTimeStamp = updatedPart.LastUpdateTimeStamp;