Merge branch 'prephysics' into dev

Conflicts:
	OpenSim/Region/Framework/Scenes/SceneGraph.cs
dsg
Robert Adams 2011-01-18 09:31:33 -08:00
commit 42563e77fa
22 changed files with 892 additions and 141 deletions

View File

@ -386,6 +386,14 @@ namespace OpenSim.Framework
public string RemotingAddress; public string RemotingAddress;
public UUID ScopeID = UUID.Zero; public UUID ScopeID = UUID.Zero;
//SYMMETRIC SYNC
//IP:port for the symmetric sync listener this actor is configured to connect to
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;
//end of SYMMETRIC SYNC
// Apparently, we're applying the same estatesettings regardless of whether it's local or remote. // Apparently, we're applying the same estatesettings regardless of whether it's local or remote.
@ -676,6 +684,25 @@ namespace OpenSim.Framework
get { return Util.UIntsToLong((RegionLocX * (uint) Constants.RegionSize), (RegionLocY * (uint) Constants.RegionSize)); } get { return Util.UIntsToLong((RegionLocX * (uint) Constants.RegionSize), (RegionLocY * (uint) Constants.RegionSize)); }
} }
//SYMMETRIC SYNC
public string SyncListenerAddress
{
get { return m_syncListenerAddr; }
}
public int SyncListenerPort
{
get { return m_syncListenerPort; }
}
public string ServerIPAddress
{
get { return m_serverAddr; }
}
public int ServerPort
{
get { return m_serverPort; }
}
//end of SYMMETRIC SYNC
public void SetEndPoint(string ipaddr, int port) public void SetEndPoint(string ipaddr, int port)
{ {
IPAddress tmpIP = IPAddress.Parse(ipaddr); IPAddress tmpIP = IPAddress.Parse(ipaddr);
@ -830,6 +857,21 @@ namespace OpenSim.Framework
// Multi-tenancy // Multi-tenancy
// //
ScopeID = new UUID(config.GetString("ScopeID", UUID.Zero.ToString())); ScopeID = new UUID(config.GetString("ScopeID", UUID.Zero.ToString()));
// SYMMETRIC SYNC
m_syncListenerAddr = config.GetString("SyncListenerIPAddress", 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;
// end of SYMMETRIC SYNC
} }
private void WriteNiniConfig(IConfigSource source) private void WriteNiniConfig(IConfigSource source)

View File

@ -71,7 +71,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
{ {
m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime))); m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime)));
m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime))); m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime)));
// m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime); m_log.WarnFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime);
} }
} }
@ -261,6 +261,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
m_sendqueue[agentid] = timestamp; m_sendqueue[agentid] = timestamp;
m_updateTimer.Start(); m_updateTimer.Start();
} }
m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0} at {1} (now is {2})", agentid, timestamp,DateTime.Now.Ticks);
} }
public void QueueAppearanceSave(UUID agentid) public void QueueAppearanceSave(UUID agentid)
@ -278,16 +279,37 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
public void RefreshAppearance(UUID agentid) public void RefreshAppearance(UUID agentid)
{ {
ScenePresence sp;
if(!m_scene.TryGetScenePresence(agentid, out sp))
{
m_log.WarnFormat("[AVFACTORY]: RefreshAppearance unable to find presence for {0}", agentid);
return;
}
m_log.DebugFormat("[AVFACTORY]: FireAndForget called for RefreshAppearance on agentid {0}", agentid); m_log.DebugFormat("[AVFACTORY]: FireAndForget called for RefreshAppearance on agentid {0}", agentid);
Util.FireAndForget(delegate(object o) Util.FireAndForget(delegate(object o)
{ {
AvatarAppearance appearance = m_scene.AvatarService.GetAppearance(agentid); int trycount = 20;
ScenePresence sp;
while (!m_scene.TryGetScenePresence(agentid, out sp))
{
m_log.WarnFormat("[AVFACTORY]: RefreshAppearance unable to find presence for {0}", agentid);
Thread.Sleep(500);
if (trycount-- <= 0)
return;
}
trycount = 5;
AvatarAppearance appearance = null;
while (appearance == null)
{
try
{
appearance = m_scene.AvatarService.GetAppearance(agentid);
}
catch (System.Net.WebException e)
{
if (trycount-- <= 0)
{
m_log.WarnFormat("[AVFACTORY]: RefreshAppearance failed to get appearance from AvatarService: {0}", e.Message);
return;
}
}
Thread.Sleep(500);
}
if (appearance.Texture != null && appearance.VisualParams != null) if (appearance.Texture != null && appearance.VisualParams != null)
{ {
sp.Appearance = appearance; sp.Appearance = appearance;
@ -333,7 +355,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
// m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid); // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid);
m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); // Disable saving of appearance for demonstrations
// m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
// REGION SYNC // REGION SYNC
// If this is a client manager, we have received new appearance from a client and saved // If this is a client manager, we have received new appearance from a client and saved
// it to the avatar service. Now let's tell the parent scene about it. // it to the avatar service. Now let's tell the parent scene about it.
@ -352,6 +375,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
{ {
if (kvp.Value < now) if (kvp.Value < now)
{ {
m_log.WarnFormat("[AVFACTORY]: send appearance for {0} at time {1}", kvp.Key, now);
Util.FireAndForget(delegate(object o) { HandleAppearanceSend(kvp.Key); }); Util.FireAndForget(delegate(object o) { HandleAppearanceSend(kvp.Key); });
m_sendqueue.Remove(kvp.Key); m_sendqueue.Remove(kvp.Key);
} }

View File

@ -177,7 +177,12 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue
{ {
Queue<OSD> queue = GetQueue(avatarID); Queue<OSD> queue = GetQueue(avatarID);
if (queue != null) if (queue != null)
queue.Enqueue(ev); {
lock (queue)
{
queue.Enqueue(ev);
}
}
} }
catch(NullReferenceException e) catch(NullReferenceException e)
{ {

View File

@ -829,7 +829,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
private void DoInitialSync() private void DoInitialSync()
{ {
m_scene.DeleteAllSceneObjects(); //m_scene.DeleteAllSceneObjects();
//KittyL: added to distinguish different actors //KittyL: added to distinguish different actors
//Send(new RegionSyncMessage(RegionSyncMessage.MsgType.ActorType, m_actorType.ToString())); //Send(new RegionSyncMessage(RegionSyncMessage.MsgType.ActorType, m_actorType.ToString()));
@ -891,13 +891,14 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
// Register for interesting client events which will be forwarded to auth sim // Register for interesting client events which will be forwarded to auth sim
// These are the raw packet data blocks from the client, intercepted and sent up to the sim // These are the raw packet data blocks from the client, intercepted and sent up to the sim
client.OnAgentUpdateRaw += HandleAgentUpdateRaw; client.OnAgentUpdateRaw += HandleAgentUpdateRaw;
//SYMMETRIC SYNC: do not subscribe to OnChatFromClientRaw, we may remove this event entirely later //SYMMETRIC SYNC: do not subscribe to OnChatFromClientRaw: RegionSyncModule + Scene.EventManager will handle this.
//client.OnChatFromClientRaw += HandleChatFromClientRaw; //client.OnChatFromClientRaw += HandleChatFromClientRaw;
client.OnAgentRequestSit += HandleAgentRequestSit; client.OnAgentRequestSit += HandleAgentRequestSit;
client.OnAgentSit += HandleAgentSit; client.OnAgentSit += HandleAgentSit;
client.OnGrabObject += HandleGrabObject; //SYMMETRIC SYNC: do not subscribe to OnGrabObject, OnGrabUpdate, and OnDeGrabObject: RegionSyncModule + Scene.EventManager will handle this.
client.OnGrabUpdate += HandleGrabUpdate; //client.OnGrabObject += HandleGrabObject;
client.OnDeGrabObject += HandleDeGrabObject; //client.OnGrabUpdate += HandleGrabUpdate;
//client.OnDeGrabObject += HandleDeGrabObject;
client.OnStartAnim += HandleStartAnim; client.OnStartAnim += HandleStartAnim;
client.OnStopAnim += HandleStopAnim; client.OnStopAnim += HandleStopAnim;
} }

View File

@ -69,10 +69,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
m_active = true; m_active = true;
m_scene.RegionSyncEnabled = true; m_scene.RegionSyncEnabled = true;
m_scene.RegionSyncMode = "client"; m_scene.RegionSyncMode = "client";
string serverAddrDefault = syncConfig.GetString("ServerIPAddress", "127.0.0.1");
m_serveraddr = syncConfig.GetString(scene.RegionInfo.RegionName+"_ServerIPAddress", serverAddrDefault); //string serverAddrDefault = syncConfig.GetString("ServerIPAddress", "127.0.0.1");
int serverPortDefault = syncConfig.GetInt("ServerPort", 13000); //m_serveraddr = syncConfig.GetString(scene.RegionInfo.RegionName+"_ServerIPAddress", serverAddrDefault);
m_serverport = syncConfig.GetInt(scene.RegionInfo.RegionName+"_ServerPort", serverPortDefault); //int serverPortDefault = syncConfig.GetInt("ServerPort", 13000);
//m_serverport = syncConfig.GetInt(scene.RegionInfo.RegionName+"_ServerPort", serverPortDefault);
m_scene.RegisterModuleInterface<IRegionSyncClientModule>(this); m_scene.RegisterModuleInterface<IRegionSyncClientModule>(this);
m_symsync = syncConfig.GetBoolean("SymSync", false); m_symsync = syncConfig.GetBoolean("SymSync", false);
@ -230,6 +232,15 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
private void Start() private void Start()
{ {
m_serveraddr = m_scene.RegionInfo.ServerIPAddress;
m_serverport = m_scene.RegionInfo.ServerPort;
if (m_serveraddr.Equals(String.Empty) || m_serverport == -1)
{
m_log.Warn("[REGION SYNC CLIENT MODULE] No IP or port of RegionSyncServer has been configured. Shut down.");
m_active = false;
return;
}
lock (m_client_lock) lock (m_client_lock)
{ {

View File

@ -101,10 +101,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
m_statsWriter = File.AppendText(syncstats); m_statsWriter = File.AppendText(syncstats);
//Get sync server info for Client Manager actors //Get sync server info for Client Manager actors
string serverAddr = scene.RegionInfo.RegionName + "_ServerIPAddress"; //string serverAddr = scene.RegionInfo.RegionName + "_ServerIPAddress";
m_serveraddr = syncConfig.GetString(serverAddr, IPAddrUnknown); //m_serveraddr = syncConfig.GetString(serverAddr, IPAddrUnknown);
string serverPort = scene.RegionInfo.RegionName + "_ServerPort"; //string serverPort = scene.RegionInfo.RegionName + "_ServerPort";
m_serverport = syncConfig.GetInt(serverPort, PortUnknown); //m_serverport = syncConfig.GetInt(serverPort, PortUnknown);
// Client manager load balancing // Client manager load balancing
m_maxClientsPerManager = syncConfig.GetInt("MaxClientsPerManager", 100); m_maxClientsPerManager = syncConfig.GetInt("MaxClientsPerManager", 100);
DefaultPort++; DefaultPort++;
@ -165,6 +166,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
} }
//end of SYMMETRIC SYNC //end of SYMMETRIC SYNC
// Start the server and listen for RegionSyncClients // Start the server and listen for RegionSyncClients
m_serveraddr = m_scene.RegionInfo.ServerIPAddress;
m_serverport = m_scene.RegionInfo.ServerPort;
m_log.Debug("[REGION SYNC SERVER MODULE] to start server on " + m_serveraddr + ":" + m_serverport);
if (!m_serveraddr.Equals(IPAddrUnknown) && m_serverport != PortUnknown) if (!m_serveraddr.Equals(IPAddrUnknown) && m_serverport != PortUnknown)
{ {
m_log.Warn("[REGION SYNC SERVER MODULE] Starting RegionSyncServer"); m_log.Warn("[REGION SYNC SERVER MODULE] Starting RegionSyncServer");
@ -327,7 +333,10 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
data["vel"] = OSD.FromVector3(presence.Velocity); data["vel"] = OSD.FromVector3(presence.Velocity);
else else
data["vel"] = OSD.FromVector3(Vector3.Zero); data["vel"] = OSD.FromVector3(Vector3.Zero);
data["rot"] = OSD.FromQuaternion(presence.Rotation); if(System.Single.IsNaN(presence.Rotation.X))
data["rot"] = OSD.FromQuaternion(Quaternion.Identity);
else
data["rot"] = OSD.FromQuaternion(presence.Rotation);
data["fly"] = OSD.FromBoolean(presence.Flying); data["fly"] = OSD.FromBoolean(presence.Flying);
data["flags"] = OSD.FromUInteger((uint)presence.AgentControlFlags); data["flags"] = OSD.FromUInteger((uint)presence.AgentControlFlags);
data["anim"] = OSD.FromString(presence.Animator.CurrentMovementAnimation); data["anim"] = OSD.FromString(presence.Animator.CurrentMovementAnimation);

View File

@ -72,7 +72,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//Called after Initialise() //Called after Initialise()
public void AddRegion(Scene scene) public void AddRegion(Scene scene)
{ {
m_log.Warn(LogHeader + " AddRegion() called"); //m_log.Warn(LogHeader + " AddRegion() called");
if (!m_active) if (!m_active)
return; return;
@ -89,17 +89,19 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//Register for local Scene events //Register for local Scene events
m_scene.EventManager.OnPostSceneCreation += OnPostSceneCreation; m_scene.EventManager.OnPostSceneCreation += OnPostSceneCreation;
m_scene.EventManager.OnObjectBeingRemovedFromScene += new EventManager.ObjectBeingRemovedFromScene(RegionSyncModule_OnObjectBeingRemovedFromScene); //m_scene.EventManager.OnObjectBeingRemovedFromScene += new EventManager.ObjectBeingRemovedFromScene(RegionSyncModule_OnObjectBeingRemovedFromScene);
LogHeader += "-" + scene.RegionInfo.RegionName;
} }
//Called after AddRegion() has been called for all region modules of the scene //Called after AddRegion() has been called for all region modules of the scene
public void RegionLoaded(Scene scene) public void RegionLoaded(Scene scene)
{ {
m_log.Warn(LogHeader + " RegionLoaded() called"); //m_log.Warn(LogHeader + " RegionLoaded() called");
/*
//If this one is configured to start a listener so that other actors can connect to form a overlay, start the listener. //If this one is configured to start a listener so that other actors can connect to form a overlay, start the listener.
//For now, we use start topology, and ScenePersistence actor is always the one to start the listener. //For now, we use the star topology, and ScenePersistence actor is always the one to start the listener.
if (m_isSyncListenerLocal) if (m_isSyncListenerLocal)
{ {
StartLocalSyncListener(); StartLocalSyncListener();
@ -108,7 +110,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
{ {
//Start connecting to the remote listener. TO BE IMPLEMENTED. //Start connecting to the remote listener. TO BE IMPLEMENTED.
//For now, the connection will be started by manually typing in "sync start". //For now, the connection will be started by manually typing in "sync start".
} }
* */
//Start symmetric synchronization initialization automatically
//SyncStart(null);
} }
@ -170,6 +177,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
} }
private RegionSyncListener m_localSyncListener = null; private RegionSyncListener m_localSyncListener = null;
private bool m_synced = false;
// Lock is used to synchronize access to the update status and update queues // Lock is used to synchronize access to the update status and update queues
private object m_updateSceneObjectPartLock = new object(); private object m_updateSceneObjectPartLock = new object();
@ -203,7 +211,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
// Existing value of 1 indicates that updates are currently being sent so skip updates this pass // Existing value of 1 indicates that updates are currently being sent so skip updates this pass
if (Interlocked.Exchange(ref m_sendingUpdates, 1) == 1) if (Interlocked.Exchange(ref m_sendingUpdates, 1) == 1)
{ {
m_log.WarnFormat("[REGION SYNC SERVER MODULE] SendUpdates(): An update thread is already running."); m_log.WarnFormat("[REGION SYNC MODULE] SendUpdates(): An update thread is already running.");
return; return;
} }
@ -281,7 +289,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[REGION SYNC SERVER MODULE] Caught exception sending presence updates for {0}: {1}", presence.Name, e.Message); m_log.ErrorFormat("[REGION SYNC MODULE] Caught exception sending presence updates for {0}: {1}", presence.Name, e.Message);
} }
} }
* */ * */
@ -369,7 +377,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
///////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////
private static int PortUnknown = -1; private static int PortUnknown = -1;
private static string IPAddrUnknown = ""; private static string IPAddrUnknown = String.Empty;
private ILog m_log; private ILog m_log;
//private bool m_active = true; //private bool m_active = true;
@ -528,6 +536,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
} }
m_actorType = m_scene.ActorSyncModule.ActorType; m_actorType = m_scene.ActorSyncModule.ActorType;
} }
//Start symmetric synchronization initialization automatically
SyncStart(null);
} }
private void StartLocalSyncListener() private void StartLocalSyncListener()
@ -552,8 +563,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
{ {
m_log.Debug(LogHeader + ": Reading in " + m_scene.RegionInfo.RegionName + "_SyncListenerIPAddress" + " and " + m_scene.RegionInfo.RegionName + "_SyncListenerPort"); m_log.Debug(LogHeader + ": Reading in " + m_scene.RegionInfo.RegionName + "_SyncListenerIPAddress" + " and " + m_scene.RegionInfo.RegionName + "_SyncListenerPort");
string addr = m_sysConfig.GetString(m_scene.RegionInfo.RegionName+"_SyncListenerIPAddress", IPAddrUnknown); //string addr = m_sysConfig.GetString(m_scene.RegionInfo.RegionName+"_SyncListenerIPAddress", IPAddrUnknown);
int port = m_sysConfig.GetInt(m_scene.RegionInfo.RegionName+"_SyncListenerPort", PortUnknown); //int port = m_sysConfig.GetInt(m_scene.RegionInfo.RegionName+"_SyncListenerPort", PortUnknown);
string addr = m_scene.RegionInfo.SyncListenerAddress;
int port = m_scene.RegionInfo.SyncListenerPort;
m_log.Warn(LogHeader + ": listener addr: " + addr + ", port: " + port); m_log.Warn(LogHeader + ": listener addr: " + addr + ", port: " + port);
@ -575,8 +589,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
{ {
//For now, we assume there is only one remote listener to connect to. Later on, //For now, we assume there is only one remote listener to connect to. Later on,
//we may need to modify the code to read in multiple listeners. //we may need to modify the code to read in multiple listeners.
string addr = m_sysConfig.GetString(m_scene.RegionInfo.RegionName + "_SyncListenerIPAddress", IPAddrUnknown); //string addr = m_sysConfig.GetString(m_scene.RegionInfo.RegionName + "_SyncListenerIPAddress", IPAddrUnknown);
int port = m_sysConfig.GetInt(m_scene.RegionInfo.RegionName + "_SyncListenerPort", PortUnknown); //int port = m_sysConfig.GetInt(m_scene.RegionInfo.RegionName + "_SyncListenerPort", PortUnknown);
string addr = m_scene.RegionInfo.SyncListenerAddress;
int port = m_scene.RegionInfo.SyncListenerPort;
if (!addr.Equals(IPAddrUnknown) && port != PortUnknown) if (!addr.Equals(IPAddrUnknown) && port != PortUnknown)
{ {
RegionSyncListenerInfo info = new RegionSyncListenerInfo(addr, port); RegionSyncListenerInfo info = new RegionSyncListenerInfo(addr, port);
@ -611,8 +629,10 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
{ {
GetRemoteSyncListenerInfo(); GetRemoteSyncListenerInfo();
} }
StartSyncConnections(); if (StartSyncConnections())
DoInitialSync(); {
DoInitialSync();
}
} }
} }
@ -623,18 +643,28 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
if (m_localSyncListener!=null && m_localSyncListener.IsListening) if (m_localSyncListener!=null && m_localSyncListener.IsListening)
{ {
m_localSyncListener.Shutdown(); m_localSyncListener.Shutdown();
//Trigger SyncStop event, ActorSyncModules can then take actor specific action if needed.
//For instance, script engine will save script states
//save script state and stop script instances
m_scene.EventManager.TriggerOnSymmetricSyncStop();
} }
} }
else else
{ {
//Shutdown all sync connectors //Shutdown all sync connectors
StopAllSyncConnectors(); if (m_synced)
{
StopAllSyncConnectors();
m_synced = false;
//Trigger SyncStop event, ActorSyncModules can then take actor specific action if needed.
//For instance, script engine will save script states
//save script state and stop script instances
m_scene.EventManager.TriggerOnSymmetricSyncStop();
}
} }
//Trigger SyncStop event, ActorSyncModules can then take actor specific action if needed.
//For instance, script engine will save script states
//save script state and stop script instances
m_scene.EventManager.TriggerOnSymmetricSyncStop();
} }
@ -646,12 +676,18 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//Start connections to each remote listener. //Start connections to each remote listener.
//For now, there is only one remote listener. //For now, there is only one remote listener.
private void StartSyncConnections() private bool StartSyncConnections()
{ {
if (m_remoteSyncListeners == null) if (m_remoteSyncListeners == null)
{ {
m_log.Error(LogHeader + " SyncListener's address or port has not been configured."); m_log.Error(LogHeader + " SyncListener's address or port has not been configured.");
return; return false;
}
if (m_synced)
{
m_log.Warn(LogHeader + ": Already synced.");
return false;
} }
foreach (RegionSyncListenerInfo remoteListener in m_remoteSyncListeners) foreach (RegionSyncListenerInfo remoteListener in m_remoteSyncListeners)
@ -663,6 +699,10 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
AddSyncConnector(syncConnector); AddSyncConnector(syncConnector);
} }
} }
m_synced = true;
return true;
} }
//To be called when a SyncConnector needs to be created by that the local listener receives a connection request //To be called when a SyncConnector needs to be created by that the local listener receives a connection request
@ -850,9 +890,14 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
return; return;
} }
//EVENTS PROCESSING //EVENTS PROCESSING
case SymmetricSyncMessage.MsgType.NewScript:
case SymmetricSyncMessage.MsgType.UpdateScript: case SymmetricSyncMessage.MsgType.UpdateScript:
case SymmetricSyncMessage.MsgType.ScriptReset: case SymmetricSyncMessage.MsgType.ScriptReset:
case SymmetricSyncMessage.MsgType.ChatFromClient: case SymmetricSyncMessage.MsgType.ChatFromClient:
case SymmetricSyncMessage.MsgType.ChatFromWorld:
case SymmetricSyncMessage.MsgType.ObjectGrab:
case SymmetricSyncMessage.MsgType.ObjectGrabbing:
case SymmetricSyncMessage.MsgType.ObjectDeGrab:
{ {
HandleRemoteEvent(msg); HandleRemoteEvent(msg);
return; return;
@ -910,7 +955,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
m_log.WarnFormat("[{0} Object \"{1}\" ({1}) ({2}) -- add or update ERROR.", LogHeader, sog.Name, sog.UUID.ToString(), sog.LocalId.ToString()); m_log.WarnFormat("[{0} Object \"{1}\" ({1}) ({2}) -- add or update ERROR.", LogHeader, sog.Name, sog.UUID.ToString(), sog.LocalId.ToString());
break; break;
case Scene.ObjectUpdateResult.Unchanged: 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()); //m_log.DebugFormat("[{0} Object \"{1}\" ({1}) ({2}) unchanged after receiving an update.", LogHeader, sog.Name, sog.UUID.ToString(), sog.LocalId.ToString());
break; break;
} }
} }
@ -931,29 +976,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
SendSyncMessage(SymmetricSyncMessage.MsgType.Terrain, OSDParser.SerializeJsonString(data)); SendSyncMessage(SymmetricSyncMessage.MsgType.Terrain, OSDParser.SerializeJsonString(data));
} }
private void HandleRemovedObject(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;
}
// Get the parameters from data
//ulong regionHandle = data["regionHandle"].AsULong();
//uint localID = data["UUID"].AsUInteger();
UUID sogUUID = data["UUID"].AsUUID();
SceneObjectGroup sog = m_scene.SceneGraph.GetGroupByPrim(sogUUID);
if (sog != null)
{
m_scene.DeleteSceneObjectBySynchronization(sog);
}
}
HashSet<string> exceptions = new HashSet<string>(); HashSet<string> exceptions = new HashSet<string>();
private OSDMap DeserializeMessage(SymmetricSyncMessage msg) private OSDMap DeserializeMessage(SymmetricSyncMessage msg)
@ -986,6 +1009,34 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
} }
} }
private void HandleRemovedObject(SymmetricSyncMessage msg)
{
// Get the data from message and error check
OSDMap data = DeserializeMessage(msg);
string init_actorID = data["actorID"].AsString();
if (data == null)
{
SymmetricSyncMessage.HandleError(LogHeader, msg, "Could not deserialize JSON data.");
return;
}
UUID sogUUID = data["UUID"].AsUUID();
SceneObjectGroup sog = m_scene.SceneGraph.GetGroupByPrim(sogUUID);
if (sog != null)
{
m_scene.DeleteSceneObjectBySynchronization(sog);
}
//if this is a relay node, forwards the event
if (m_isSyncRelay)
{
SendSceneEventToRelevantSyncConnectors(init_actorID, msg);
}
}
/// <summary> /// <summary>
/// The common actions for handling remote events (event initiated at other actors and propogated here) /// The common actions for handling remote events (event initiated at other actors and propogated here)
/// </summary> /// </summary>
@ -998,6 +1049,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
switch (msg.Type) switch (msg.Type)
{ {
case SymmetricSyncMessage.MsgType.NewScript:
HandleRemoteEvent_OnNewScript(init_actorID, evSeqNum, data);
break;
case SymmetricSyncMessage.MsgType.UpdateScript: case SymmetricSyncMessage.MsgType.UpdateScript:
HandleRemoteEvent_OnUpdateScript(init_actorID, evSeqNum, data); HandleRemoteEvent_OnUpdateScript(init_actorID, evSeqNum, data);
break; break;
@ -1007,6 +1061,18 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
case SymmetricSyncMessage.MsgType.ChatFromClient: case SymmetricSyncMessage.MsgType.ChatFromClient:
HandleRemoteEvent_OnChatFromClient(init_actorID, evSeqNum, data); HandleRemoteEvent_OnChatFromClient(init_actorID, evSeqNum, data);
break; break;
case SymmetricSyncMessage.MsgType.ChatFromWorld:
HandleRemoteEvent_OnChatFromWorld(init_actorID, evSeqNum, data);
break;
case SymmetricSyncMessage.MsgType.ObjectGrab:
HandleRemoteEvent_OnObjectGrab(init_actorID, evSeqNum, data);
break;
case SymmetricSyncMessage.MsgType.ObjectGrabbing:
HandleRemoteEvent_OnObjectGrabbing(init_actorID, evSeqNum, data);
break;
case SymmetricSyncMessage.MsgType.ObjectDeGrab:
HandleRemoteEvent_OnObjectDeGrab(init_actorID, evSeqNum, data);
break;
} }
//if this is a relay node, forwards the event //if this is a relay node, forwards the event
@ -1016,9 +1082,54 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
} }
} }
/// <summary>
///
/// </summary>
/// <param name="actorID">the ID of the actor that initiates the event</param>
/// <param name="evSeqNum">sequence num of the event from the actor</param>
/// <param name="data">OSDMap data of event args</param>
private void HandleRemoteEvent_OnNewScript(string actorID, ulong evSeqNum, OSDMap data)
{
m_log.Debug(LogHeader + ", " + m_actorID + ": received NewScript");
UUID agentID = data["agentID"].AsUUID();
UUID primID = data["primID"].AsUUID();
UUID itemID = data["itemID"].AsUUID();
string sogXml = data["sog"].AsString();
SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(sogXml);
SceneObjectPart part = null;
foreach (SceneObjectPart prim in sog.Parts)
{
if(prim.UUID.Equals(primID)){
part = prim;
break;
}
}
if(part == null)
{
m_log.Warn(LogHeader+": part "+primID+" not exist in the serialized object, do nothing");
return;
}
//Update the object first
Scene.ObjectUpdateResult updateResult = m_scene.AddOrUpdateObjectBySynchronization(sog);
if (updateResult == Scene.ObjectUpdateResult.Updated || updateResult == Scene.ObjectUpdateResult.New)
{
m_log.Debug(LogHeader + ": TriggerNewScriptLocally");
//Next, trigger creating the new script
SceneObjectPart localPart = m_scene.GetSceneObjectPart(primID);
m_scene.EventManager.TriggerNewScriptLocally(agentID, localPart, itemID);
}
}
/// <summary> /// <summary>
/// Special actions for remote event UpdateScript /// Special actions for remote event UpdateScript
/// </summary> /// </summary>
/// <param name="actorID">the ID of the actor that initiates the event</param>
/// <param name="evSeqNum">sequence num of the event from the actor</param>
/// <param name="data">OSDMap data of event args</param> /// <param name="data">OSDMap data of event args</param>
private void HandleRemoteEvent_OnUpdateScript(string actorID, ulong evSeqNum, OSDMap data) private void HandleRemoteEvent_OnUpdateScript(string actorID, ulong evSeqNum, OSDMap data)
{ {
@ -1035,7 +1146,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
} }
/// <summary> /// <summary>
/// Special actions for remote event UpdateScript /// Special actions for remote event ScriptReset
/// </summary> /// </summary>
/// <param name="data">OSDMap data of event args</param> /// <param name="data">OSDMap data of event args</param>
private void HandleRemoteEvent_OnScriptReset(string actorID, ulong evSeqNum, OSDMap data) private void HandleRemoteEvent_OnScriptReset(string actorID, ulong evSeqNum, OSDMap data)
@ -1075,62 +1186,187 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
ScenePresence sp; ScenePresence sp;
m_scene.TryGetScenePresence(id, out sp); m_scene.TryGetScenePresence(id, out sp);
m_scene.EventManager.TriggerOnChatFromClientLocally(sp, args); //Let WorldCommModule and other modules to catch the event
m_scene.EventManager.TriggerOnChatFromWorldLocally(sp, args); //This is to let ChatModule to get the event and deliver it to avatars
}
//m_scene.EventManager.TriggerOnChatFromClientLocally(sp, args); private void HandleRemoteEvent_OnChatFromWorld(string actorID, ulong evSeqNum, OSDMap data)
{
m_log.Debug(LogHeader + ", " + m_actorID + ": received ChatFromWorld from " + actorID + ", seq " + evSeqNum);
m_scene.EventManager.TriggerOnChatFromWorldLocally(sp, args); OSChatMessage args = new OSChatMessage();
/* args.Channel = data["channel"].AsInteger();
if (sp != null) args.Message = data["msg"].AsString();
{ args.Position = data["pos"].AsVector3();
args.Sender = sp.ControllingClient; args.From = data["name"].AsString();
args.SenderUUID = id; UUID id = data["id"].AsUUID();
m_scene.EventManager.TriggerOnChatBroadcastLocally(sp.ControllingClient, args); args.Scene = m_scene;
} //args.Type = ChatTypeEnum.Say;
else args.Type = (ChatTypeEnum)data["type"].AsInteger();
{ //ScenePresence sp;
args.Sender = null; //m_scene.TryGetScenePresence(id, out sp);
args.SenderUUID = id;
m_scene.EventManager.TriggerOnChatFromWorldLocally(null, args); m_scene.EventManager.TriggerOnChatFromWorldLocally(m_scene, args);
}
* */
//m_scene.EventManager
} }
/// <summary> /// <summary>
/// Send a sync message to remove the given objects in all connected actors, if this is a relay node. /// Special actions for remote event ChatFromClient
/// UUID is used for identified a removed object. /// </summary>
/// <param name="data">OSDMap data of event args</param>
private void HandleRemoteEvent_OnObjectGrab(string actorID, ulong evSeqNum, OSDMap data)
{
m_log.Debug(LogHeader + ", " + m_actorID + ": received GrabObject from " + actorID + ", seq " + evSeqNum);
UUID agentID = data["agentID"].AsUUID();
UUID primID = data["primID"].AsUUID();
UUID originalPrimID = data["originalPrimID"].AsUUID();
Vector3 offsetPos = data["offsetPos"].AsVector3();
SurfaceTouchEventArgs surfaceArgs = new SurfaceTouchEventArgs();
surfaceArgs.Binormal = data["binormal"].AsVector3();
surfaceArgs.FaceIndex = data["faceIndex"].AsInteger();
surfaceArgs.Normal = data["normal"].AsVector3();
surfaceArgs.Position = data["position"].AsVector3();
surfaceArgs.STCoord = data["stCoord"].AsVector3();
surfaceArgs.UVCoord = data["uvCoord"].AsVector3();
//Create an instance of IClientAPI to pass along agentID, see SOPObject.EventManager_OnObjectGrab()
//We don't really need RegionSyncAvatar's implementation here, just borrow it's IClientAPI interface.
//If we decide to remove RegionSyncAvatar later, we can simple just define a very simple class that implements
//ICleintAPI to be used here.
IClientAPI remoteClinet = new RegionSyncAvatar(m_scene, agentID, "", "", Vector3.Zero);
SceneObjectPart part = m_scene.GetSceneObjectPart(primID);
if (part == null)
{
m_log.Error(LogHeader + ": no prim with ID " + primID);
return;
}
uint originalID = 0;
if (originalPrimID != UUID.Zero)
{
SceneObjectPart originalPart = m_scene.GetSceneObjectPart(originalPrimID);
originalID = originalPart.LocalId;
}
m_scene.EventManager.TriggerObjectGrabLocally(part.LocalId, originalID, offsetPos, remoteClinet, surfaceArgs);
}
private void HandleRemoteEvent_OnObjectGrabbing(string actorID, ulong evSeqNum, OSDMap data)
{
m_log.Debug(LogHeader + ", " + m_actorID + ": received GrabObject from " + actorID + ", seq " + evSeqNum);
UUID agentID = data["agentID"].AsUUID();
UUID primID = data["primID"].AsUUID();
UUID originalPrimID = data["originalPrimID"].AsUUID();
Vector3 offsetPos = data["offsetPos"].AsVector3();
SurfaceTouchEventArgs surfaceArgs = new SurfaceTouchEventArgs();
surfaceArgs.Binormal = data["binormal"].AsVector3();
surfaceArgs.FaceIndex = data["faceIndex"].AsInteger();
surfaceArgs.Normal = data["normal"].AsVector3();
surfaceArgs.Position = data["position"].AsVector3();
surfaceArgs.STCoord = data["stCoord"].AsVector3();
surfaceArgs.UVCoord = data["uvCoord"].AsVector3();
//Create an instance of IClientAPI to pass along agentID, see SOPObject.EventManager_OnObjectGrab()
//We don't really need RegionSyncAvatar's implementation here, just borrow it's IClientAPI interface.
//If we decide to remove RegionSyncAvatar later, we can simple just define a very simple class that implements
//ICleintAPI to be used here.
IClientAPI remoteClinet = new RegionSyncAvatar(m_scene, agentID, "", "", Vector3.Zero);
SceneObjectPart part = m_scene.GetSceneObjectPart(primID);
if (part == null)
{
m_log.Error(LogHeader + ": no prim with ID " + primID);
return;
}
uint originalID = 0;
if (originalPrimID != UUID.Zero)
{
SceneObjectPart originalPart = m_scene.GetSceneObjectPart(originalPrimID);
originalID = originalPart.LocalId;
}
m_scene.EventManager.TriggerObjectGrabbingLocally(part.LocalId, originalID, offsetPos, remoteClinet, surfaceArgs);
}
private void HandleRemoteEvent_OnObjectDeGrab(string actorID, ulong evSeqNum, OSDMap data)
{
m_log.Debug(LogHeader + ", " + m_actorID + ": received GrabObject from " + actorID + ", seq " + evSeqNum);
UUID agentID = data["agentID"].AsUUID();
UUID primID = data["primID"].AsUUID();
UUID originalPrimID = data["originalPrimID"].AsUUID();
SurfaceTouchEventArgs surfaceArgs = new SurfaceTouchEventArgs();
surfaceArgs.Binormal = data["binormal"].AsVector3();
surfaceArgs.FaceIndex = data["faceIndex"].AsInteger();
surfaceArgs.Normal = data["normal"].AsVector3();
surfaceArgs.Position = data["position"].AsVector3();
surfaceArgs.STCoord = data["stCoord"].AsVector3();
surfaceArgs.UVCoord = data["uvCoord"].AsVector3();
//Create an instance of IClientAPI to pass along agentID, see SOPObject.EventManager_OnObjectGrab()
//We don't really need RegionSyncAvatar's implementation here, just borrow it's IClientAPI interface.
//If we decide to remove RegionSyncAvatar later, we can simple just define a very simple class that implements
//ICleintAPI to be used here.
IClientAPI remoteClinet = new RegionSyncAvatar(m_scene, agentID, "", "", Vector3.Zero);
SceneObjectPart part = m_scene.GetSceneObjectPart(primID);
if (part == null)
{
m_log.Error(LogHeader + ": no prim with ID " + primID);
return;
}
uint originalID = 0;
if (originalPrimID != UUID.Zero)
{
SceneObjectPart originalPart = m_scene.GetSceneObjectPart(originalPrimID);
originalID = originalPart.LocalId;
}
m_scene.EventManager.TriggerObjectDeGrabLocally(part.LocalId, originalID, remoteClinet, surfaceArgs);
}
/// <summary>
/// Send a sync message to remove the given objects in all connected actors.
/// UUID is used for identified a removed object. This function now should
/// only be triggered by an object removal that is initiated locally.
/// </summary> /// </summary>
/// <param name="sog"></param> /// <param name="sog"></param>
private void RegionSyncModule_OnObjectBeingRemovedFromScene(SceneObjectGroup sog) //private void RegionSyncModule_OnObjectBeingRemovedFromScene(SceneObjectGroup sog)
public void SendDeleteObject(SceneObjectGroup sog)
{ {
//m_log.DebugFormat("RegionSyncModule_OnObjectBeingRemovedFromScene called at time {0}:{1}:{2}", DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond); //m_log.DebugFormat("RegionSyncModule_OnObjectBeingRemovedFromScene called at time {0}:{1}:{2}", DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond);
//Only send the message out if this is a relay node for sync messages, or this actor caused deleting the object //Only send the message out if this is a relay node for sync messages, or this actor caused deleting the object
if (m_isSyncRelay || CheckObjectForSendingUpdate(sog)) //if (m_isSyncRelay || CheckObjectForSendingUpdate(sog))
{
OSDMap data = new OSDMap(1);
//data["regionHandle"] = OSD.FromULong(regionHandle);
//data["localID"] = OSD.FromUInteger(sog.LocalId);
data["UUID"] = OSD.FromUUID(sog.UUID);
SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.RemovedObject, OSDParser.SerializeJsonString(data));
SendObjectUpdateToRelevantSyncConnectors(sog, rsm);
}
OSDMap data = new OSDMap(1);
//data["regionHandle"] = OSD.FromULong(regionHandle);
//data["localID"] = OSD.FromUInteger(sog.LocalId);
data["UUID"] = OSD.FromUUID(sog.UUID);
data["actorID"] = OSD.FromString(m_actorID);
SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.RemovedObject, OSDParser.SerializeJsonString(data));
SendObjectUpdateToRelevantSyncConnectors(sog, rsm);
} }
public void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs) public void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs)
{ {
switch (ev) switch (ev)
{ {
case EventManager.EventNames.NewScript:
if (evArgs.Length < 3)
{
m_log.Error(LogHeader + " not enough event args for NewScript");
return;
}
OnLocalNewScript((UUID)evArgs[0], (SceneObjectPart)evArgs[1], (UUID)evArgs[2]);
return;
case EventManager.EventNames.UpdateScript: case EventManager.EventNames.UpdateScript:
if (evArgs.Length < 5) if (evArgs.Length < 5)
{ {
m_log.Error(LogHeader + " not enough event args for UpdateScript"); m_log.Error(LogHeader + " not enough event args for UpdateScript");
return; return;
} }
m_log.Debug(LogHeader + " PublishSceneEvent UpdateScript");
OnLocalUpdateScript((UUID)evArgs[0], (UUID)evArgs[1], (UUID)evArgs[2], (bool)evArgs[3], (UUID)evArgs[4]); OnLocalUpdateScript((UUID)evArgs[0], (UUID)evArgs[1], (UUID)evArgs[2], (bool)evArgs[3], (UUID)evArgs[4]);
return; return;
case EventManager.EventNames.ScriptReset: case EventManager.EventNames.ScriptReset:
@ -1149,11 +1385,54 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
} }
OnLocalChatFromClient(evArgs[0], (OSChatMessage)evArgs[1]); OnLocalChatFromClient(evArgs[0], (OSChatMessage)evArgs[1]);
return; return;
case EventManager.EventNames.ChatFromWorld:
if (evArgs.Length < 2)
{
m_log.Error(LogHeader + " not enough event args for ChatFromWorld");
return;
}
OnLocalChatFromWorld(evArgs[0], (OSChatMessage)evArgs[1]);
return;
case EventManager.EventNames.ObjectGrab:
OnLocalGrabObject((uint)evArgs[0], (uint)evArgs[1], (Vector3) evArgs[2], (IClientAPI) evArgs[3], (SurfaceTouchEventArgs)evArgs[4]);
return;
case EventManager.EventNames.ObjectGrabbing:
OnLocalObjectGrabbing((uint)evArgs[0], (uint)evArgs[1], (Vector3)evArgs[2], (IClientAPI)evArgs[3], (SurfaceTouchEventArgs)evArgs[4]);
return;
case EventManager.EventNames.ObjectDeGrab:
OnLocalDeGrabObject((uint)evArgs[0], (uint)evArgs[1], (IClientAPI)evArgs[2], (SurfaceTouchEventArgs)evArgs[3]);
return;
default: default:
return; return;
} }
} }
/// <summary>
/// The handler for (locally initiated) event OnNewScript: triggered by client's RezSript packet, publish it to other actors.
/// </summary>
/// <param name="clientID">ID of the client who creates the new script</param>
/// <param name="part">the prim that contains the new script</param>
private void OnLocalNewScript(UUID clientID, SceneObjectPart part, UUID itemID)
{
m_log.Debug(LogHeader + " RegionSyncModule_OnLocalNewScript");
SceneObjectGroup sog = part.ParentGroup;
if(sog==null){
m_log.Warn(LogHeader + ": part " + part.UUID + " not in an SceneObjectGroup yet. Will not propagating new script event");
//sog = new SceneObjectGroup(part);
return;
}
//For simplicity, we just leverage a SOP's serialization method to transmit the information of new inventory item for the script).
//This can certainly be optimized later (e.g. only sending serialization of the inventory item)
OSDMap data = new OSDMap();
data["agentID"] = OSD.FromUUID(clientID);
data["primID"] = OSD.FromUUID(part.UUID);
data["itemID"] = OSD.FromUUID(itemID); //id of the new inventory item of the part
data["sog"] = OSD.FromString(SceneObjectSerializer.ToXml2Format(sog));
SendSceneEvent(SymmetricSyncMessage.MsgType.NewScript, data);
}
/// <summary> /// <summary>
/// The handler for (locally initiated) event OnUpdateScript: publish it to other actors. /// The handler for (locally initiated) event OnUpdateScript: publish it to other actors.
/// </summary> /// </summary>
@ -1189,6 +1468,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//we will use the prim's UUID as the identifier, not the localID, to publish the event for the prim //we will use the prim's UUID as the identifier, not the localID, to publish the event for the prim
SceneObjectPart part = m_scene.GetSceneObjectPart(localID); SceneObjectPart part = m_scene.GetSceneObjectPart(localID);
if (part == null)
{
m_log.Warn(LogHeader + ": part with localID " + localID + " not exist");
return;
}
OSDMap data = new OSDMap(); OSDMap data = new OSDMap();
data["primID"] = OSD.FromUUID(part.UUID); data["primID"] = OSD.FromUUID(part.UUID);
data["itemID"] = OSD.FromUUID(itemID); data["itemID"] = OSD.FromUUID(itemID);
@ -1211,13 +1496,137 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
data["channel"] = OSD.FromInteger(chat.Channel); data["channel"] = OSD.FromInteger(chat.Channel);
data["msg"] = OSD.FromString(chat.Message); data["msg"] = OSD.FromString(chat.Message);
data["pos"] = OSD.FromVector3(chat.Position); data["pos"] = OSD.FromVector3(chat.Position);
//data["name"] = OSD.FromString(chat.From); data["name"] = OSD.FromString(avatar.Name); //note this is different from OnLocalChatFromWorld
data["name"] = OSD.FromString(avatar.Name);
data["id"] = OSD.FromUUID(chat.SenderUUID); data["id"] = OSD.FromUUID(chat.SenderUUID);
data["type"] = OSD.FromInteger((int)chat.Type); data["type"] = OSD.FromInteger((int)chat.Type);
SendSceneEvent(SymmetricSyncMessage.MsgType.ChatFromClient, data); SendSceneEvent(SymmetricSyncMessage.MsgType.ChatFromClient, data);
} }
private void OnLocalChatFromWorld(Object sender, OSChatMessage chat)
{
OSDMap data = new OSDMap();
data["channel"] = OSD.FromInteger(chat.Channel);
data["msg"] = OSD.FromString(chat.Message);
data["pos"] = OSD.FromVector3(chat.Position);
data["name"] = OSD.FromString(chat.From); //note this is different from OnLocalChatFromClient
data["id"] = OSD.FromUUID(chat.SenderUUID);
data["type"] = OSD.FromInteger((int)chat.Type);
SendSceneEvent(SymmetricSyncMessage.MsgType.ChatFromWorld, data);
}
private void OnLocalGrabObject(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
{
/*
//we will use the prim's UUID as the identifier, not the localID, to publish the event for the prim
SceneObjectPart part = m_scene.GetSceneObjectPart(localID);
if (part == null)
{
m_log.Warn(LogHeader + ": part with localID " + localID + " not exist");
return;
}
//this seems to be useful if the prim touched and the prim handling the touch event are different:
//i.e. a child part is touched, pass the event to root, and root handles the event. then root is the "part",
//and the child part is the "originalPart"
SceneObjectPart originalPart = null;
if (originalID != 0)
{
originalPart = m_scene.GetSceneObjectPart(originalID);
if (originalPart == null)
{
m_log.Warn(LogHeader + ": part with localID " + localID + " not exist");
return;
}
}
OSDMap data = new OSDMap();
data["agentID"] = OSD.FromUUID(remoteClient.AgentId);
data["primID"] = OSD.FromUUID(part.UUID);
if (originalID != 0)
{
data["originalPrimID"] = OSD.FromUUID(originalPart.UUID);
}
else
{
data["originalPrimID"] = OSD.FromUUID(UUID.Zero);
}
data["offsetPos"] = OSD.FromVector3(offsetPos);
data["binormal"] = OSD.FromVector3(surfaceArgs.Binormal);
data["faceIndex"] = OSD.FromInteger(surfaceArgs.FaceIndex);
data["normal"] = OSD.FromVector3(surfaceArgs.Normal);
data["position"] = OSD.FromVector3(surfaceArgs.Position);
data["stCoord"] = OSD.FromVector3(surfaceArgs.STCoord);
data["uvCoord"] = OSD.FromVector3(surfaceArgs.UVCoord);
* */
OSDMap data = PrepareObjectGrabArgs(localID, originalID, offsetPos, remoteClient, surfaceArgs);
SendSceneEvent(SymmetricSyncMessage.MsgType.ObjectGrab, data);
}
private void OnLocalObjectGrabbing(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
{
OSDMap data = PrepareObjectGrabArgs(localID, originalID, offsetPos, remoteClient, surfaceArgs);
if (data != null)
{
SendSceneEvent(SymmetricSyncMessage.MsgType.ObjectGrabbing, data);
}
}
private OSDMap PrepareObjectGrabArgs(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
{
//we will use the prim's UUID as the identifier, not the localID, to publish the event for the prim
SceneObjectPart part = m_scene.GetSceneObjectPart(localID);
if (part == null)
{
m_log.Warn(LogHeader + ": PrepareObjectGrabArgs - part with localID " + localID + " not exist");
return null;
}
//this seems to be useful if the prim touched and the prim handling the touch event are different:
//i.e. a child part is touched, pass the event to root, and root handles the event. then root is the "part",
//and the child part is the "originalPart"
SceneObjectPart originalPart = null;
if (originalID != 0)
{
originalPart = m_scene.GetSceneObjectPart(originalID);
if (originalPart == null)
{
m_log.Warn(LogHeader + ": PrepareObjectGrabArgs - part with localID " + localID + " not exist");
return null;
}
}
OSDMap data = new OSDMap();
data["agentID"] = OSD.FromUUID(remoteClient.AgentId);
data["primID"] = OSD.FromUUID(part.UUID);
if (originalID != 0)
{
data["originalPrimID"] = OSD.FromUUID(originalPart.UUID);
}
else
{
data["originalPrimID"] = OSD.FromUUID(UUID.Zero);
}
data["offsetPos"] = OSD.FromVector3(offsetPos);
data["binormal"] = OSD.FromVector3(surfaceArgs.Binormal);
data["faceIndex"] = OSD.FromInteger(surfaceArgs.FaceIndex);
data["normal"] = OSD.FromVector3(surfaceArgs.Normal);
data["position"] = OSD.FromVector3(surfaceArgs.Position);
data["stCoord"] = OSD.FromVector3(surfaceArgs.STCoord);
data["uvCoord"] = OSD.FromVector3(surfaceArgs.UVCoord);
return data;
}
private void OnLocalDeGrabObject(uint localID, uint originalID, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
{
}
private void SendSceneEvent(SymmetricSyncMessage.MsgType msgType, OSDMap data) private void SendSceneEvent(SymmetricSyncMessage.MsgType msgType, OSDMap data)
{ {
data["actorID"] = OSD.FromString(m_actorID); data["actorID"] = OSD.FromString(m_actorID);

View File

@ -89,8 +89,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//for local OnUpdateScript, we'll handle it the same way as a remove OnUpdateScript. //for local OnUpdateScript, we'll handle it the same way as a remove OnUpdateScript.
//RegionSyncModule will capture a locally initiated OnUpdateScript event and publish it to other actors. //RegionSyncModule will capture a locally initiated OnUpdateScript event and publish it to other actors.
m_scene.EventManager.OnNewScript += ScriptEngine_OnNewScript;
m_scene.EventManager.OnUpdateScript += ScriptEngine_OnUpdateScript; m_scene.EventManager.OnUpdateScript += ScriptEngine_OnUpdateScript;
//m_scene.EventManager.OnUpdateScriptBySync += ScriptEngine_OnUpdateScript; //m_scene.EventManager.OnUpdateScriptBySync += ScriptEngine_OnUpdateScript;
LogHeader += "-" + m_actorID + "-" + m_scene.RegionInfo.RegionName;
} }
//Called after AddRegion() has been called for all region modules of the scene. //Called after AddRegion() has been called for all region modules of the scene.
@ -182,6 +185,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
m_scene.DeleteAllSceneObjects(); m_scene.DeleteAllSceneObjects();
} }
public void ScriptEngine_OnNewScript(UUID agentID, SceneObjectPart part, UUID itemID)
{
m_log.Debug(LogHeader + " ScriptEngine_OnUpdateScript");
m_scene.SymSync_OnNewScript(agentID, itemID, part);
}
//Assumption, when this function is triggered, the new script asset has already been saved. //Assumption, when this function is triggered, the new script asset has already been saved.
public void ScriptEngine_OnUpdateScript(UUID agentID, UUID itemID, UUID primID, bool isScriptRunning, UUID newAssetID) public void ScriptEngine_OnUpdateScript(UUID agentID, UUID itemID, UUID primID, bool isScriptRunning, UUID newAssetID)
{ {

View File

@ -34,9 +34,14 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//RegionStatus, //RegionStatus,
ActorID, ActorID,
//events //events
NewScript,
UpdateScript, UpdateScript,
ScriptReset, ScriptReset,
ChatFromClient, ChatFromClient,
ChatFromWorld,
ObjectGrab,
ObjectGrabbing,
ObjectDeGrab,
} }
#endregion #endregion

View File

@ -34,8 +34,8 @@ using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
// using log4net; //using log4net;
// using System.Reflection; //using System.Reflection;
/***************************************************** /*****************************************************
@ -98,6 +98,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
private int m_saydistance = 30; private int m_saydistance = 30;
private int m_shoutdistance = 100; private int m_shoutdistance = 100;
//private ILog m_log;
#region IRegionModule Members #region IRegionModule Members
public void Initialise(Scene scene, IConfigSource config) public void Initialise(Scene scene, IConfigSource config)
@ -126,7 +128,9 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
m_scene.EventManager.OnChatFromClient += DeliverClientMessage; m_scene.EventManager.OnChatFromClient += DeliverClientMessage;
m_scene.EventManager.OnChatBroadcast += DeliverClientMessage; m_scene.EventManager.OnChatBroadcast += DeliverClientMessage;
//SYMMETRIC SYNC //SYMMETRIC SYNC
m_scene.EventManager.OnChatFromWorld += DeliverClientMessage; //m_scene.EventManager.OnChatFromWorld += DeliverClientMessage;
//Kitty: temp debug
//m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
//end SYMMETRIC SYNC //end SYMMETRIC SYNC
m_pendingQ = new Queue(); m_pendingQ = new Queue();
m_pending = Queue.Synchronized(m_pendingQ); m_pending = Queue.Synchronized(m_pendingQ);
@ -244,7 +248,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
/// <param name="msg">msg to sent</param> /// <param name="msg">msg to sent</param>
public void DeliverMessage(ChatTypeEnum type, int channel, string name, UUID id, string msg, Vector3 position) public void DeliverMessage(ChatTypeEnum type, int channel, string name, UUID id, string msg, Vector3 position)
{ {
// m_log.DebugFormat("[WorldComm] got[2] type {0}, channel {1}, name {2}, id {3}, msg {4}", //m_log.DebugFormat("[WorldComm] got[2] type {0}, channel {1}, name {2}, id {3}, msg {4}",
// type, channel, name, id, msg); // type, channel, name, id, msg);
// Determine which listen event filters match the given set of arguments, this results // Determine which listen event filters match the given set of arguments, this results

View File

@ -63,7 +63,7 @@ namespace OpenSim.Region.Framework.Interfaces
//void SendUpdatesToSynchronizeState(List<SceneObjectGroup> sog); //void SendUpdatesToSynchronizeState(List<SceneObjectGroup> sog);
void SendSceneUpdates(); void SendSceneUpdates();
void SendTerrainUpdates(string lastUpdateActorID); void SendTerrainUpdates(string lastUpdateActorID);
//void SendDeleteObject(SceneObjectGroup sog); void SendDeleteObject(SceneObjectGroup sog);
//For propogating scene events to other actors //For propogating scene events to other actors
void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs); void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs);

View File

@ -50,9 +50,15 @@ namespace OpenSim.Region.Framework.Scenes
//the events that we'll handle specially in sym-sync //the events that we'll handle specially in sym-sync
public enum EventNames public enum EventNames
{ {
NewScript,
UpdateScript, UpdateScript,
ScriptReset, ScriptReset,
ChatFromClient, ChatFromClient, //chats from avatars
ChatFromWorld, //chats from objects
ObjectGrab,
ObjectGrabbing,
ObjectDeGrab,
} }
public EventManager(Scene scene) public EventManager(Scene scene)
@ -60,6 +66,30 @@ namespace OpenSim.Region.Framework.Scenes
m_scene = scene; m_scene = scene;
} }
#region UpdateScript
//triggered by client.OnRezScript
public override void TriggerNewScript(UUID clientID, SceneObjectPart part, UUID itemID)
{
//publish the event to other actors who are intersted in it
if (m_scene.RegionSyncModule != null)
{
Object[] eventArgs = new Object[3];
eventArgs[0] = (Object)clientID;
eventArgs[1] = (Object)part;
eventArgs[2] = (Object)itemID;
m_scene.RegionSyncModule.PublishSceneEvent(EventNames.NewScript, eventArgs);
}
//trigger event locally,
TriggerNewScriptLocally(clientID, part, itemID);
}
//public void TriggerNewScriptLocally(UUID clientID, UUID itemId, UUID primId, UUID newAssetID)
public void TriggerNewScriptLocally(UUID clientID, SceneObjectPart part, UUID itemID)
{
base.TriggerNewScript(clientID, part, itemID);
}
#endregion //UpdateScript
#region UpdateScript #region UpdateScript
public override void TriggerUpdateScript(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID) public override void TriggerUpdateScript(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID)
{ {
@ -75,7 +105,7 @@ namespace OpenSim.Region.Framework.Scenes
m_scene.RegionSyncModule.PublishSceneEvent(EventNames.UpdateScript, eventArgs); m_scene.RegionSyncModule.PublishSceneEvent(EventNames.UpdateScript, eventArgs);
} }
//trigger event locally, as the legacy code does //trigger event locally,
TriggerUpdateScriptLocally(clientId, itemId, primId, isScriptRunning, newAssetID); TriggerUpdateScriptLocally(clientId, itemId, primId, isScriptRunning, newAssetID);
} }
public void TriggerUpdateScriptLocally(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID) public void TriggerUpdateScriptLocally(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID)
@ -128,10 +158,87 @@ namespace OpenSim.Region.Framework.Scenes
base.TriggerOnChatBroadcast(sender, chat); base.TriggerOnChatBroadcast(sender, chat);
} }
#region ChatFromWorld
public override void TriggerOnChatFromWorld(Object sender, OSChatMessage chat)
{
if (m_scene.RegionSyncModule != null)
{
Object[] eventArgs = new Object[2];
eventArgs[0] = sender;
eventArgs[1] = (Object)chat;
m_scene.RegionSyncModule.PublishSceneEvent(EventNames.ChatFromWorld, eventArgs);
}
TriggerOnChatFromWorldLocally(sender, chat);
}
public void TriggerOnChatFromWorldLocally(Object sender, OSChatMessage chat) public void TriggerOnChatFromWorldLocally(Object sender, OSChatMessage chat)
{ {
base.TriggerOnChatFromWorld(sender, chat); base.TriggerOnChatFromWorld(sender, chat);
} }
#endregion //ChatFromWorld
#region ObjectGrab, ObjectGrabbing, ObjectDeGrab
public override void TriggerObjectGrab(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
{
if (m_scene.RegionSyncModule != null)
{
Object[] eventArgs = new Object[5];
eventArgs[0] = (Object)localID;
eventArgs[1] = (Object)originalID;
eventArgs[2] = (Object)offsetPos;
eventArgs[3] = (Object)remoteClient;
eventArgs[4] = (Object)surfaceArgs;
m_scene.RegionSyncModule.PublishSceneEvent(EventNames.ObjectGrab, eventArgs);
}
TriggerObjectGrabLocally(localID, originalID, offsetPos, remoteClient, surfaceArgs);
}
public void TriggerObjectGrabLocally(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
{
base.TriggerObjectGrab(localID, originalID, offsetPos, remoteClient, surfaceArgs);
}
public override void TriggerObjectGrabbing(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
{
if (m_scene.RegionSyncModule != null)
{
Object[] eventArgs = new Object[5];
eventArgs[0] = (Object)localID;
eventArgs[1] = (Object)originalID;
eventArgs[2] = (Object)offsetPos;
eventArgs[3] = (Object)remoteClient;
eventArgs[4] = (Object)surfaceArgs;
m_scene.RegionSyncModule.PublishSceneEvent(EventNames.ObjectGrabbing, eventArgs);
}
TriggerObjectGrabbingLocally(localID, originalID, offsetPos, remoteClient, surfaceArgs);
}
public void TriggerObjectGrabbingLocally(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
{
base.TriggerObjectGrabbing(localID, originalID, offsetPos, remoteClient, surfaceArgs);
}
public override void TriggerObjectDeGrab(uint localID, uint originalID, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
{
if (m_scene.RegionSyncModule != null)
{
Object[] eventArgs = new Object[4];
eventArgs[0] = (Object)localID;
eventArgs[1] = (Object)originalID;
eventArgs[2] = (Object)remoteClient;
eventArgs[3] = (Object)surfaceArgs;
m_scene.RegionSyncModule.PublishSceneEvent(EventNames.ObjectDeGrab, eventArgs);
}
TriggerObjectDeGrabLocally(localID, originalID, remoteClient, surfaceArgs);
}
public void TriggerObjectDeGrabLocally(uint localID, uint originalID, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
{
base.TriggerObjectDeGrab(localID, originalID, remoteClient, surfaceArgs);
}
#endregion //GrabObject
} }
/// <summary> /// <summary>
@ -938,7 +1045,9 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public void TriggerObjectGrab(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) //SYMMETRIC SYNC: overridden at new EventManager class
//public void TriggerObjectGrab(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
public virtual void TriggerObjectGrab(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
{ {
ObjectGrabDelegate handlerObjectGrab = OnObjectGrab; ObjectGrabDelegate handlerObjectGrab = OnObjectGrab;
if (handlerObjectGrab != null) if (handlerObjectGrab != null)
@ -959,7 +1068,9 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public void TriggerObjectGrabbing(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) //SYMMETRIC SYNC: overridden at new EventManager class
//public void TriggerObjectGrabbing(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
public virtual void TriggerObjectGrabbing(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
{ {
ObjectGrabDelegate handlerObjectGrabbing = OnObjectGrabbing; ObjectGrabDelegate handlerObjectGrabbing = OnObjectGrabbing;
if (handlerObjectGrabbing != null) if (handlerObjectGrabbing != null)
@ -980,7 +1091,9 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public void TriggerObjectDeGrab(uint localID, uint originalID, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) //SYMMETRIC SYNC: overridden at new EventManager class
//public void TriggerObjectDeGrab(uint localID, uint originalID, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
public virtual void TriggerObjectDeGrab(uint localID, uint originalID, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
{ {
ObjectDeGrabDelegate handlerObjectDeGrab = OnObjectDeGrab; ObjectDeGrabDelegate handlerObjectDeGrab = OnObjectDeGrab;
if (handlerObjectDeGrab != null) if (handlerObjectDeGrab != null)
@ -1670,7 +1783,9 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public void TriggerOnChatFromWorld(Object sender, OSChatMessage chat) //SYMMETRIC SYNC: the function is overridden in new EventManager
//public void TriggerOnChatFromWorld(Object sender, OSChatMessage chat)
public virtual void TriggerOnChatFromWorld(Object sender, OSChatMessage chat)
{ {
ChatFromWorldEvent handlerChatFromWorld = OnChatFromWorld; ChatFromWorldEvent handlerChatFromWorld = OnChatFromWorld;
if (handlerChatFromWorld != null) if (handlerChatFromWorld != null)
@ -2289,7 +2404,31 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
//OnUpdateTaskInventoryScriptAsset: triggered after Scene receives client's upload of updated script and stores it as asset public delegate void NewScript(UUID clientID, SceneObjectPart part, UUID itemID);
public event NewScript OnNewScript;
public virtual void TriggerNewScript(UUID clientID, SceneObjectPart part, UUID itemID)
{
NewScript handlerNewScript = OnNewScript;
if (handlerNewScript != null)
{
foreach (NewScript d in handlerNewScript.GetInvocationList())
{
try
{
d(clientID, part, itemID);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[EVENT MANAGER]: Delegate for TriggerNewScript failed - continuing. {0} {1}",
e.Message, e.StackTrace);
}
}
}
}
//TriggerUpdateScript: triggered after Scene receives client's upload of updated script and stores it as asset
public delegate void UpdateScript(UUID clientID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID); public delegate void UpdateScript(UUID clientID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID);
public event UpdateScript OnUpdateScript; public event UpdateScript OnUpdateScript;
public virtual void TriggerUpdateScript(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID) public virtual void TriggerUpdateScript(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID)

View File

@ -310,7 +310,7 @@ namespace OpenSim.Region.Framework.Scenes
* */ * */
//SYMMETRIC SYNC: Distributed Scene Graph implementation //SYMMETRIC SYNC: Distributed Scene Graph implementation
m_log.Debug("Scene.Inventory: to call EventManager.TriggerUpdateTaskInventoryScriptAsset, agentID: " + remoteClient.AgentId); m_log.Debug("Scene.Inventory: to call EventManager.TriggerUpdateScript, agentID: " + remoteClient.AgentId);
//Trigger OnUpdateScript event. //Trigger OnUpdateScript event.
EventManager.TriggerUpdateScript(remoteClient.AgentId, itemId, primId, isScriptRunning, item.AssetID); EventManager.TriggerUpdateScript(remoteClient.AgentId, itemId, primId, isScriptRunning, item.AssetID);
@ -369,6 +369,14 @@ namespace OpenSim.Region.Framework.Scenes
#endregion #endregion
#region SYMMETRIC SYNC #region SYMMETRIC SYNC
public void SymSync_OnNewScript(UUID avatarID, UUID itemID, SceneObjectPart part)
{
TaskInventoryItem item = part.Inventory.GetInventoryItem(itemID);
part.Inventory.CreateScriptInstance(item, 0, false, DefaultScriptEngine, 0);
part.ParentGroup.ResumeScripts();
}
//only a script engine actor is supposed to call this function //only a script engine actor is supposed to call this function
public ArrayList SymSync_OnUpdateScript(UUID avatarID, UUID itemID, UUID primID, bool isScriptRunning, UUID newAssetID) public ArrayList SymSync_OnUpdateScript(UUID avatarID, UUID itemID, UUID primID, bool isScriptRunning, UUID newAssetID)
{ {
@ -376,6 +384,17 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectPart part = GetSceneObjectPart(primID); SceneObjectPart part = GetSceneObjectPart(primID);
SceneObjectGroup group = part.ParentGroup; SceneObjectGroup group = part.ParentGroup;
if (null == group)
{
m_log.ErrorFormat(
"[PRIM INVENTORY]: " +
"Prim inventory update requested for item ID {0} in prim ID {1} but this prim does not exist",
itemID, primID);
return new ArrayList();
}
if (isScriptRunning) if (isScriptRunning)
{ {
m_log.Debug("To RemoveScriptInstance"); m_log.Debug("To RemoveScriptInstance");
@ -385,6 +404,16 @@ namespace OpenSim.Region.Framework.Scenes
// Retrieve item // Retrieve item
TaskInventoryItem item = group.GetInventoryItem(part.LocalId, itemID); TaskInventoryItem item = group.GetInventoryItem(part.LocalId, itemID);
if (null == item)
{
m_log.ErrorFormat(
"[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for caps script update "
+ " but the item does not exist in this inventory",
itemID, part.Name, part.UUID);
return new ArrayList();
}
// Update item with new asset // Update item with new asset
item.AssetID = newAssetID; item.AssetID = newAssetID;
group.UpdateInventoryItem(item); group.UpdateInventoryItem(item);
@ -1642,6 +1671,10 @@ namespace OpenSim.Region.Framework.Scenes
return; return;
part.ParentGroup.AddInventoryItem(remoteClient, localID, item, copyID); part.ParentGroup.AddInventoryItem(remoteClient, localID, item, copyID);
part.GetProperties(remoteClient);
//SYMMETRIC SYNC
/* Original OpenSim code, commented out
// TODO: switch to posting on_rez here when scripts // TODO: switch to posting on_rez here when scripts
// have state in inventory // have state in inventory
part.Inventory.CreateScriptInstance(copyID, 0, false, DefaultScriptEngine, 0); part.Inventory.CreateScriptInstance(copyID, 0, false, DefaultScriptEngine, 0);
@ -1649,8 +1682,26 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.InfoFormat("[PRIMINVENTORY]: " + // m_log.InfoFormat("[PRIMINVENTORY]: " +
// "Rezzed script {0} into prim local ID {1} for user {2}", // "Rezzed script {0} into prim local ID {1} for user {2}",
// item.inventoryName, localID, remoteClient.Name); // item.inventoryName, localID, remoteClient.Name);
part.GetProperties(remoteClient); //part.GetProperties(remoteClient);
part.ParentGroup.ResumeScripts(); part.ParentGroup.ResumeScripts();
* */
if (RegionSyncModule != null)
{
part.SyncInfoUpdate();
EventManager.TriggerNewScript(remoteClient.AgentId, part, copyID);
}
else
{
part.Inventory.CreateScriptInstance(copyID, 0, false, DefaultScriptEngine, 0);
// m_log.InfoFormat("[PRIMINVENTORY]: " +
// "Rezzed script {0} into prim local ID {1} for user {2}",
// item.inventoryName, localID, remoteClient.Name);
//part.GetProperties(remoteClient);
part.ParentGroup.ResumeScripts();
}
//end of SYMMETRIC SYNC
} }
else else
{ {
@ -1709,8 +1760,25 @@ namespace OpenSim.Region.Framework.Scenes
part.Inventory.AddInventoryItem(taskItem, false); part.Inventory.AddInventoryItem(taskItem, false);
part.GetProperties(remoteClient); part.GetProperties(remoteClient);
part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0); //SYMMETRIC SYNC
part.ParentGroup.ResumeScripts(); //part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0);
//part.ParentGroup.ResumeScripts();
if (RegionSyncModule != null)
{
part.SyncInfoUpdate();
EventManager.TriggerNewScript(remoteClient.AgentId, part, taskItem.ItemID);
}
else
{
part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0);
// m_log.InfoFormat("[PRIMINVENTORY]: " +
// "Rezzed script {0} into prim local ID {1} for user {2}",
// item.inventoryName, localID, remoteClient.Name);
//part.GetProperties(remoteClient);
part.ParentGroup.ResumeScripts();
}
//end of SYMMETRIC SYNC
} }
} }

View File

@ -2464,9 +2464,18 @@ namespace OpenSim.Region.Framework.Scenes
//SYMMETRIC SYNC //SYMMETRIC SYNC
//Set the ActorID and TimeStamp info for this latest update //Set the ActorID and TimeStamp info for this latest update
/*
foreach (SceneObjectPart part in group.Parts) foreach (SceneObjectPart part in group.Parts)
{ {
part.SyncInfoUpdate(); part.SyncInfoUpdate();
}
*
* */
//Propagate the RemovedObject message
if (RegionSyncModule != null)
{
RegionSyncModule.SendDeleteObject(group);
} }
//end of SYMMETRIC SYNC //end of SYMMETRIC SYNC
@ -3111,12 +3120,13 @@ namespace OpenSim.Region.Framework.Scenes
client.OnUpdatePrimFlags += m_sceneGraph.UpdatePrimFlags; client.OnUpdatePrimFlags += m_sceneGraph.UpdatePrimFlags;
client.OnRequestObjectPropertiesFamily += m_sceneGraph.RequestObjectPropertiesFamily; client.OnRequestObjectPropertiesFamily += m_sceneGraph.RequestObjectPropertiesFamily;
client.OnObjectPermissions += HandleObjectPermissionsUpdate; client.OnObjectPermissions += HandleObjectPermissionsUpdate;
if (IsSyncedServer()) //SYMMETRIC SYNC: return the code back to its original OpenSim version
{ //if (IsSyncedServer())
//{
client.OnGrabObject += ProcessObjectGrab; client.OnGrabObject += ProcessObjectGrab;
client.OnGrabUpdate += ProcessObjectGrabUpdate; client.OnGrabUpdate += ProcessObjectGrabUpdate;
client.OnDeGrabObject += ProcessObjectDeGrab; client.OnDeGrabObject += ProcessObjectDeGrab;
} //}
client.OnUndo += m_sceneGraph.HandleUndo; client.OnUndo += m_sceneGraph.HandleUndo;
client.OnRedo += m_sceneGraph.HandleRedo; client.OnRedo += m_sceneGraph.HandleRedo;
client.OnObjectDescription += m_sceneGraph.PrimDescription; client.OnObjectDescription += m_sceneGraph.PrimDescription;
@ -3629,9 +3639,12 @@ namespace OpenSim.Region.Framework.Scenes
ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); }); ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); });
//SYMMETRIC SYNC: object remove should be handled through RegionSyncModule
// REGION SYNC // REGION SYNC
/*
if( IsSyncedServer() ) if( IsSyncedServer() )
RegionSyncServerModule.DeleteObject(m_regionHandle, localID, part); RegionSyncServerModule.DeleteObject(m_regionHandle, localID, part);
* */
} }
#endregion #endregion

View File

@ -457,7 +457,7 @@ namespace OpenSim.Region.Framework.Scenes
lock (m_updateList) lock (m_updateList)
{ {
m_updateList[obj.UUID] = obj; m_updateList[obj.UUID] = obj;
// m_log.Debug("added " + obj.UUID + " to m_updateList"); //m_log.Debug("added " + obj.UUID + " to m_updateList");
} }
} }
@ -478,10 +478,12 @@ namespace OpenSim.Region.Framework.Scenes
{ {
updates = new List<SceneObjectGroup>(m_updateList.Values); updates = new List<SceneObjectGroup>(m_updateList.Values);
/*
if (updates.Count > 0) if (updates.Count > 0)
{ {
m_log.Debug("SceneGraph: " + updates.Count + " objects to send updates for"); m_log.Debug("SceneGraph: " + updates.Count + " objects to send updates for");
} }
* */
m_updateList.Clear(); m_updateList.Clear();

View File

@ -1155,12 +1155,16 @@ namespace OpenSim.Region.Framework.Scenes
{ {
SceneObjectPart part = parts[i]; SceneObjectPart part = parts[i];
//SYMMETRIC SYNC: object remove should be handled through RegionSyncModule
/*
// REGION SYNC // REGION SYNC
if (Scene.IsSyncedServer()) if (Scene.IsSyncedServer())
{ {
Scene.RegionSyncServerModule.DeleteObject(part.RegionHandle, part.LocalId, part); Scene.RegionSyncServerModule.DeleteObject(part.RegionHandle, part.LocalId, part);
//return; //return;
} }
* */
//end of SYMMETRIC SYNC
Scene.ForEachScenePresence(delegate(ScenePresence avatar) Scene.ForEachScenePresence(delegate(ScenePresence avatar)
{ {

View File

@ -4922,7 +4922,7 @@ 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_lastUpdateActorID; private string m_lastUpdateActorID="";
public string LastUpdateActorID public string LastUpdateActorID
{ {
get { return m_lastUpdateActorID; } get { return m_lastUpdateActorID; }
@ -4948,12 +4948,12 @@ namespace OpenSim.Region.Framework.Scenes
public void SyncInfoUpdate() public void SyncInfoUpdate()
{ {
if (m_parentGroup.Scene.ActorSyncModule == null || m_parentGroup.Scene.ActorSyncModule.ActorID == null) //if (m_parentGroup == null || m_parentGroup.Scene==null || m_parentGroup.Scene.ActorSyncModule == null || m_parentGroup.Scene.ActorSyncModule.ActorID == null)
return; // return;
//Trick: calling UpdateTimestamp here makes sure that when an object was received and de-serialized, before //Trick: calling UpdateTimestamp here makes sure that when an object was received and de-serialized, before
// its parts are linked together, neither TimeStamp or ActorID will be modified. This is because during de-serialization, // its parts are linked together, neither TimeStamp or ActorID will be modified. This is because during de-serialization,
// ScheduleFullUpdate() is called when m_parentGroup == null // ScheduleFullUpdate() is called when m_parentGroup == null
if (m_parentGroup != null) if (m_parentGroup != null && m_parentGroup.Scene != null && m_parentGroup.Scene.ActorSyncModule!=null)
{ {
UpdateTimestamp(); UpdateTimestamp();
m_lastUpdateActorID = m_parentGroup.Scene.ActorSyncModule.ActorID; m_lastUpdateActorID = m_parentGroup.Scene.ActorSyncModule.ActorID;
@ -5066,14 +5066,6 @@ namespace OpenSim.Region.Framework.Scenes
this.m_lastUpdateActorID = updatedPart.LastUpdateActorID; this.m_lastUpdateActorID = updatedPart.LastUpdateActorID;
this.m_lastUpdateTimeStamp = updatedPart.LastUpdateTimeStamp; this.m_lastUpdateTimeStamp = updatedPart.LastUpdateTimeStamp;
/*
this.m_inventory.Items = (TaskInventoryDictionary)updatedPart.m_inventory.Items.Clone();
//update shape information, for now, only update fileds in Shape whose set functions are defined in PrimitiveBaseShape
this.Shape = updatedPart.Shape.Copy();
this.Shape.TextureEntry = updatedPart.Shape.TextureEntry;
* */
return partUpdateResult; return partUpdateResult;
} }
@ -5083,7 +5075,7 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
public void ScheduleFullUpdate_SyncInfoUnchanged() public void ScheduleFullUpdate_SyncInfoUnchanged()
{ {
m_log.DebugFormat("[SCENE OBJECT PART]: ScheduleFullUpdate_SyncInfoUnchanged for {0} {1}", Name, LocalId); //m_log.DebugFormat("[SCENE OBJECT PART]: ScheduleFullUpdate_SyncInfoUnchanged for {0} {1}", Name, LocalId);
if (m_parentGroup != null) if (m_parentGroup != null)
{ {

View File

@ -539,6 +539,9 @@ namespace OpenSim.Region.Framework.Scenes
//m_inventorySerial += 2; //m_inventorySerial += 2;
HasInventoryChanged = true; HasInventoryChanged = true;
m_part.ParentGroup.HasGroupChanged = true; m_part.ParentGroup.HasGroupChanged = true;
//SYMMETRIC SYNC: add ScheduleFullUpdate to enable synchronization across actors
m_part.ScheduleFullUpdate();
} }
/// <summary> /// <summary>

View File

@ -2517,7 +2517,7 @@ namespace OpenSim.Region.Framework.Scenes
// If the avatars baked textures are all in the cache, then we have a // If the avatars baked textures are all in the cache, then we have a
// complete appearance... send it out, if not, then we'll send it when // complete appearance... send it out, if not, then we'll send it when
// the avatar finishes updating its appearance // the avatar finishes updating its appearance
SendAppearanceToAllOtherAgents(); m_scene.AvatarFactory.QueueAppearanceSend(UUID);
} }
} }

View File

@ -1174,7 +1174,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
writer.WriteElementString("GroupMask", sop.GroupMask.ToString()); writer.WriteElementString("GroupMask", sop.GroupMask.ToString());
writer.WriteElementString("EveryoneMask", sop.EveryoneMask.ToString()); writer.WriteElementString("EveryoneMask", sop.EveryoneMask.ToString());
writer.WriteElementString("NextOwnerMask", sop.NextOwnerMask.ToString()); writer.WriteElementString("NextOwnerMask", sop.NextOwnerMask.ToString());
WriteFlags(writer, "Flags", sop.Flags.ToString(), options); //SYMMETRIC SYNC: also serialize SceneObjectPart:LocalFlags, so that it can be propogated across actors
//WriteFlags(writer, "Flags", sop.Flags.ToString(), options);
WriteFlags(writer, "Flags", sop.GetEffectiveObjectFlags().ToString(), options);
//end SYMMETRIC SYNC
WriteUUID(writer, "CollisionSound", sop.CollisionSound, options); WriteUUID(writer, "CollisionSound", sop.CollisionSound, options);
writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString()); writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString());
if (sop.MediaUrl != null) if (sop.MediaUrl != null)

View File

@ -169,7 +169,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
sp.Appearance.SetTextureEntries(x.Texture); sp.Appearance.SetTextureEntries(x.Texture);
sp.Appearance.SetVisualParams((byte[])x.VisualParams.Clone()); sp.Appearance.SetVisualParams((byte[])x.VisualParams.Clone());
sp.SendAppearanceToAllOtherAgents(); p_scene.AvatarFactory.QueueAppearanceSend(sp.UUID);
} }
m_avatars.Add(npcAvatar.AgentId, npcAvatar); m_avatars.Add(npcAvatar.AgentId, npcAvatar);

View File

@ -51,6 +51,8 @@ using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
using OpenSim.Region.ScriptEngine.Shared.CodeTools; using OpenSim.Region.ScriptEngine.Shared.CodeTools;
using OpenSim.Region.ScriptEngine.Interfaces; using OpenSim.Region.ScriptEngine.Interfaces;
using log4net;
namespace OpenSim.Region.ScriptEngine.Shared.Instance namespace OpenSim.Region.ScriptEngine.Shared.Instance
{ {
public class ScriptInstance : MarshalByRefObject, IScriptInstance public class ScriptInstance : MarshalByRefObject, IScriptInstance
@ -214,12 +216,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
get { return m_thisScriptTask; } get { return m_thisScriptTask; }
} }
private ILog m_log;
public ScriptInstance(IScriptEngine engine, SceneObjectPart part, public ScriptInstance(IScriptEngine engine, SceneObjectPart part,
UUID itemID, UUID assetID, string assembly, UUID itemID, UUID assetID, string assembly,
AppDomain dom, string primName, string scriptName, AppDomain dom, string primName, string scriptName,
int startParam, bool postOnRez, StateSource stateSource, int startParam, bool postOnRez, StateSource stateSource,
int maxScriptQueue) int maxScriptQueue)
{ {
//Kitty: temp debug
m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
m_Engine = engine; m_Engine = engine;
m_LocalID = part.LocalId; m_LocalID = part.LocalId;
@ -732,7 +739,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
} }
catch (Exception e) catch (Exception e)
{ {
// m_log.DebugFormat("[SCRIPT] Exception: {0}", e.Message); m_log.DebugFormat("[SCRIPT] Exception: {0}", e.Message);
m_InEvent = false; m_InEvent = false;
m_CurrentEvent = String.Empty; m_CurrentEvent = String.Empty;