Added functions to sync terrain updates. Either script engine or Scene can update terrain

and the other will be updated.
dsg
Huaiyu (Kitty) Liu 2010-12-29 13:41:51 -08:00
parent 994d70f9d8
commit 2ce7d982fa
6 changed files with 161 additions and 15 deletions

View File

@ -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 #endregion //IRegionSyncModule
@ -713,6 +721,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
} }
} }
/// <summary> /// <summary>
/// The handler for processing incoming sync messages. /// The handler for processing incoming sync messages.
/// </summary> /// </summary>
@ -723,13 +733,19 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
{ {
case SymmetricSyncMessage.MsgType.GetTerrain: case SymmetricSyncMessage.MsgType.GetTerrain:
{ {
SendSyncMessage(SymmetricSyncMessage.MsgType.Terrain, m_scene.Heightmap.SaveToXmlString()); //SendSyncMessage(SymmetricSyncMessage.MsgType.Terrain, m_scene.Heightmap.SaveToXmlString());
SendTerrainUpdateMessage();
return; return;
} }
case SymmetricSyncMessage.MsgType.Terrain: case SymmetricSyncMessage.MsgType.Terrain:
{ {
/*
m_scene.Heightmap.LoadFromXmlString(Encoding.ASCII.GetString(msg.Data, 0, msg.Length)); m_scene.Heightmap.LoadFromXmlString(Encoding.ASCII.GetString(msg.Data, 0, msg.Length));
//Inform the terrain module that terrain has been updated
m_scene.RequestModuleInterface<ITerrainModule>().TaintTerrain();
m_log.Debug(LogHeader+": Synchronized terrain"); m_log.Debug(LogHeader+": Synchronized terrain");
* */
HandleTerrainUpdateMessage(msg);
return; return;
} }
case SymmetricSyncMessage.MsgType.GetObjects: 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<ITerrainModule>().TaintTerrianBySynchronization(lastUpdateTimeStamp, lastUpdateActorID); ;
m_log.Debug(LogHeader + ": Synchronized terrain");
}
private void HandleAddOrUpdateObjectBySynchronization(SymmetricSyncMessage msg)
{ {
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); 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<ITerrainModule>().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) private void HandleRemovedObject(SymmetricSyncMessage msg)
{ {
// Get the data from message and error check // Get the data from message and error check

View File

@ -30,7 +30,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
NewObject, // objects NewObject, // objects
UpdatedObject, // objects UpdatedObject, // objects
RemovedObject, // objects RemovedObject, // objects
// BIDIR // BIDIR
//EchoRequest, //EchoRequest,
//EchoResponse, //EchoResponse,

View File

@ -589,6 +589,56 @@ namespace OpenSim.Region.CoreModules.World.Terrain
client.OnUnackedTerrain += client_OnUnackedTerrain; 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
/// <summary> /// <summary>
/// Checks to see if the terrain has been modified since last check /// 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 /// 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
/// </summary> /// </summary>
private void CheckForTerrainUpdates() 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);
} }
/// <summary> /// <summary>
@ -607,7 +671,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain
/// currently invoked by client_OnModifyTerrain only and not the Commander interfaces /// currently invoked by client_OnModifyTerrain only and not the Commander interfaces
/// <param name="respectEstateSettings">should height map deltas be limited to the estate settings limits</param> /// <param name="respectEstateSettings">should height map deltas be limited to the estate settings limits</param>
/// </summary> /// </summary>
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; bool shouldTaint = false;
float[] serialised = m_channel.GetFloatsSerialised(); float[] serialised = m_channel.GetFloatsSerialised();
@ -636,6 +703,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain
if (shouldTaint) if (shouldTaint)
{ {
m_tainted = true; 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_painteffects[(StandardTerrainEffects) action].PaintEffect(
m_channel, allowMask, west, south, height, size, seconds); 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 else
@ -789,7 +866,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain
m_floodeffects[(StandardTerrainEffects) action].FloodEffect( m_floodeffects[(StandardTerrainEffects) action].FloodEffect(
m_channel, fillArea, size); 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 else

View File

@ -64,5 +64,11 @@ namespace OpenSim.Region.Framework.Interfaces
void InstallPlugin(string name, ITerrainEffect plug); void InstallPlugin(string name, ITerrainEffect plug);
void UndoTerrain(ITerrainChannel channel); 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
} }
} }

View File

@ -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 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. //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. //If the object already exists, use the new copy to replace it.
//Return true if added, false if just updated //Return true if added, false if just updated

View File

@ -4928,11 +4928,11 @@ namespace OpenSim.Region.Framework.Scenes
//The ID the identifies which actor has caused the most recent update to the prim. //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. //We use type "string" for the ID only to make it human-readable.
private string m_lastUpdateByActorID; private string m_lastUpdateActorID;
public string LastUpdateActorID public string LastUpdateActorID
{ {
get { return m_lastUpdateByActorID; } get { return m_lastUpdateActorID; }
set { m_lastUpdateByActorID = value; } set { m_lastUpdateActorID = value; }
} }
public void UpdateTimestamp() public void UpdateTimestamp()
@ -4944,7 +4944,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (m_parentGroup != null) if (m_parentGroup != null)
{ {
m_lastUpdateByActorID = m_parentGroup.Scene.ActorSyncModule.ActorID; m_lastUpdateActorID = m_parentGroup.Scene.ActorSyncModule.ActorID;
} }
else else
{ {
@ -4960,7 +4960,7 @@ namespace OpenSim.Region.Framework.Scenes
if (m_parentGroup != null) if (m_parentGroup != null)
{ {
UpdateTimestamp(); 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_lastUpdateTimeStamp == updatedPart.LastUpdateTimeStamp)
{ {
//if (m_parentGroup.Scene.GetActorID() != updatedPart.LastUpdatedByActorID) //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!!!!"); m_log.Warn("Different actors modified SceneObjetPart " + UUID + " with the same TimeStamp, CONFLICT RESOLUTION TO BE IMPLEMENTED!!!!");
return Scene.ObjectUpdateResult.Unchanged; return Scene.ObjectUpdateResult.Unchanged;
@ -5067,7 +5067,7 @@ namespace OpenSim.Region.Framework.Scenes
this.ParticleSystem = updatedPart.ParticleSystem; this.ParticleSystem = updatedPart.ParticleSystem;
//Update the timestamp and LastUpdatedByActorID first. //Update the timestamp and LastUpdatedByActorID first.
this.m_lastUpdateByActorID = updatedPart.LastUpdateActorID; this.m_lastUpdateActorID = updatedPart.LastUpdateActorID;
this.m_lastUpdateTimeStamp = updatedPart.LastUpdateTimeStamp; this.m_lastUpdateTimeStamp = updatedPart.LastUpdateTimeStamp;