Client manager changes as of R@I
parent
9afa8b990d
commit
9ada2a1f34
|
@ -802,6 +802,11 @@ namespace OpenSim.Client.MXP.ClientStack
|
||||||
set { }
|
set { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public uint MaxCoarseLocations
|
||||||
|
{
|
||||||
|
get { return 0; }
|
||||||
|
}
|
||||||
|
|
||||||
public uint CircuitCode
|
public uint CircuitCode
|
||||||
{
|
{
|
||||||
get { return m_sessionID.CRC(); }
|
get { return m_sessionID.CRC(); }
|
||||||
|
|
|
@ -203,6 +203,11 @@ namespace OpenSim.Client.Sirikata.ClientStack
|
||||||
set { sendLogoutPacketWhenClosing = value; }
|
set { sendLogoutPacketWhenClosing = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public uint MaxCoarseLocations
|
||||||
|
{
|
||||||
|
get { return 0; }
|
||||||
|
}
|
||||||
|
|
||||||
public uint CircuitCode
|
public uint CircuitCode
|
||||||
{
|
{
|
||||||
get { return circuitCode; }
|
get { return circuitCode; }
|
||||||
|
|
|
@ -206,6 +206,11 @@ namespace OpenSim.Client.VWoHTTP.ClientStack
|
||||||
set { throw new System.NotImplementedException(); }
|
set { throw new System.NotImplementedException(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public uint MaxCoarseLocations
|
||||||
|
{
|
||||||
|
get { return 0; }
|
||||||
|
}
|
||||||
|
|
||||||
public uint CircuitCode
|
public uint CircuitCode
|
||||||
{
|
{
|
||||||
get { throw new System.NotImplementedException(); }
|
get { throw new System.NotImplementedException(); }
|
||||||
|
|
|
@ -29,6 +29,8 @@ using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
using System.Reflection;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
namespace OpenSim.Framework
|
namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
|
@ -361,7 +363,7 @@ namespace OpenSim.Framework
|
||||||
// This sets Visual Params with *less* weirder values then default. Instead of a ugly alien, it looks like a fat scientist
|
// This sets Visual Params with *less* weirder values then default. Instead of a ugly alien, it looks like a fat scientist
|
||||||
SetDefaultParams(m_visualparams);
|
SetDefaultParams(m_visualparams);
|
||||||
SetDefaultWearables();
|
SetDefaultWearables();
|
||||||
m_texture = GetDefaultTexture();
|
m_texture = null;//GetDefaultTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
public AvatarAppearance(UUID avatarID, AvatarWearable[] wearables, byte[] visualParams)
|
public AvatarAppearance(UUID avatarID, AvatarWearable[] wearables, byte[] visualParams)
|
||||||
|
@ -370,14 +372,17 @@ namespace OpenSim.Framework
|
||||||
m_serial = 1;
|
m_serial = 1;
|
||||||
m_wearables = wearables;
|
m_wearables = wearables;
|
||||||
m_visualparams = visualParams;
|
m_visualparams = visualParams;
|
||||||
m_texture = GetDefaultTexture();
|
m_texture = null;// GetDefaultTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set up appearance textures and avatar parameters, including a height calculation
|
/// Set up appearance textures and avatar parameters, including a height calculation
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
|
public virtual void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
|
||||||
{
|
{
|
||||||
|
//m_log.WarnFormat("[APPEARANCE] SetAppearance called ({0})", textureEntry == null ? " " : "te");
|
||||||
if (textureEntry != null)
|
if (textureEntry != null)
|
||||||
m_texture = textureEntry;
|
m_texture = textureEntry;
|
||||||
if (visualParams != null)
|
if (visualParams != null)
|
||||||
|
|
|
@ -677,6 +677,8 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
IPEndPoint RemoteEndPoint { get; }
|
IPEndPoint RemoteEndPoint { get; }
|
||||||
|
|
||||||
|
uint MaxCoarseLocations { get; }
|
||||||
|
|
||||||
event GenericMessage OnGenericMessage;
|
event GenericMessage OnGenericMessage;
|
||||||
|
|
||||||
// [Obsolete("LLClientView Specific - Replace with more bare-bones arguments.")]
|
// [Obsolete("LLClientView Specific - Replace with more bare-bones arguments.")]
|
||||||
|
|
|
@ -310,7 +310,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.Error(string.Format("[BASE HTTP SERVER]: OnRequest() failed with "), e);
|
m_log.Error(String.Format("[BASE HTTP SERVER]: OnRequest() failed with {0}", e.Message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -866,6 +866,7 @@ namespace OpenSim
|
||||||
String.Format("{0,-16}{1,-16}{2,-37}{3,-11}{4,-16}{5,-30}", "Firstname", "Lastname",
|
String.Format("{0,-16}{1,-16}{2,-37}{3,-11}{4,-16}{5,-30}", "Firstname", "Lastname",
|
||||||
"Agent ID", "Root/Child", "Region", "Position"));
|
"Agent ID", "Root/Child", "Region", "Position"));
|
||||||
|
|
||||||
|
bool missingTextures = false;
|
||||||
foreach (ScenePresence presence in agents)
|
foreach (ScenePresence presence in agents)
|
||||||
{
|
{
|
||||||
RegionInfo regionInfo = presence.Scene.RegionInfo;
|
RegionInfo regionInfo = presence.Scene.RegionInfo;
|
||||||
|
@ -880,17 +881,25 @@ namespace OpenSim
|
||||||
regionName = regionInfo.RegionName;
|
regionName = regionInfo.RegionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string te = "TE";
|
||||||
|
if (presence.Appearance.Texture == null)
|
||||||
|
{
|
||||||
|
te = "";
|
||||||
|
missingTextures = true;
|
||||||
|
}
|
||||||
MainConsole.Instance.Output(
|
MainConsole.Instance.Output(
|
||||||
String.Format(
|
String.Format(
|
||||||
"{0,-16}{1,-16}{2,-37}{3,-11}{4,-16}{5,-30}",
|
"{0,-16}{1,-16}{2,-37}{3,-11}{4,-16}{5,-30}{6,2}",
|
||||||
presence.Firstname,
|
presence.Firstname,
|
||||||
presence.Lastname,
|
presence.Lastname,
|
||||||
presence.UUID,
|
presence.UUID,
|
||||||
presence.IsChildAgent ? "Child" : "Root",
|
presence.IsChildAgent ? "Child" : "Root",
|
||||||
regionName,
|
regionName,
|
||||||
presence.AbsolutePosition.ToString()));
|
presence.AbsolutePosition.ToString(),
|
||||||
|
te));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MainConsole.Instance.Output(String.Empty);
|
MainConsole.Instance.Output(String.Empty);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -365,6 +365,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
private Timer m_propertiesPacketTimer;
|
private Timer m_propertiesPacketTimer;
|
||||||
private List<ObjectPropertiesPacket.ObjectDataBlock> m_propertiesBlocks = new List<ObjectPropertiesPacket.ObjectDataBlock>();
|
private List<ObjectPropertiesPacket.ObjectDataBlock> m_propertiesBlocks = new List<ObjectPropertiesPacket.ObjectDataBlock>();
|
||||||
|
|
||||||
|
private uint m_maxCoarseLocations = 60;
|
||||||
|
|
||||||
#endregion Class Members
|
#endregion Class Members
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
@ -412,6 +414,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } }
|
public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } }
|
||||||
|
|
||||||
|
public uint MaxCoarseLocations { get { return m_maxCoarseLocations; } }
|
||||||
|
|
||||||
#endregion Properties
|
#endregion Properties
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -3321,6 +3325,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
public void SendWearables(AvatarWearable[] wearables, int serial)
|
public void SendWearables(AvatarWearable[] wearables, int serial)
|
||||||
{
|
{
|
||||||
|
//m_log.WarnFormat("[LLCLIENTVIEW] Sending wearables to {0}", Name);
|
||||||
AgentWearablesUpdatePacket aw = (AgentWearablesUpdatePacket)PacketPool.Instance.GetPacket(PacketType.AgentWearablesUpdate);
|
AgentWearablesUpdatePacket aw = (AgentWearablesUpdatePacket)PacketPool.Instance.GetPacket(PacketType.AgentWearablesUpdate);
|
||||||
aw.AgentData.AgentID = AgentId;
|
aw.AgentData.AgentID = AgentId;
|
||||||
aw.AgentData.SerialNum = (uint)serial;
|
aw.AgentData.SerialNum = (uint)serial;
|
||||||
|
@ -3347,6 +3352,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
|
public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
|
||||||
{
|
{
|
||||||
|
ScenePresence sp;
|
||||||
|
string forName = "";
|
||||||
|
if (m_scene.TryGetScenePresence(agentID, out sp))
|
||||||
|
forName = sp.Name;
|
||||||
|
//m_log.WarnFormat("[LLCLIENTVIEW] Sending {0} appearance to {1}", forName, Name);
|
||||||
AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
|
AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
|
||||||
// TODO: don't create new blocks if recycling an old packet
|
// TODO: don't create new blocks if recycling an old packet
|
||||||
avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218];
|
avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218];
|
||||||
|
@ -3426,7 +3436,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
// Each packet can only hold around 62 avatar positions and the client clears the mini-map each time
|
// Each packet can only hold around 62 avatar positions and the client clears the mini-map each time
|
||||||
// a CoarseLocationUpdate packet is received. Oh well.
|
// a CoarseLocationUpdate packet is received. Oh well.
|
||||||
int total = Math.Min(CoarseLocations.Count, 60);
|
int total = Math.Min(CoarseLocations.Count, (int)MaxCoarseLocations);
|
||||||
|
|
||||||
CoarseLocationUpdatePacket.IndexBlock ib = new CoarseLocationUpdatePacket.IndexBlock();
|
CoarseLocationUpdatePacket.IndexBlock ib = new CoarseLocationUpdatePacket.IndexBlock();
|
||||||
|
|
||||||
|
@ -5556,6 +5566,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
private bool HandlerAgentWearablesRequest(IClientAPI sender, Packet Pack)
|
private bool HandlerAgentWearablesRequest(IClientAPI sender, Packet Pack)
|
||||||
{
|
{
|
||||||
|
//m_log.WarnFormat("[LLCLIENTVIEW] Received AgentWearablesRequest from {0}", sender.Name);
|
||||||
GenericCall2 handlerRequestWearables = OnRequestWearables;
|
GenericCall2 handlerRequestWearables = OnRequestWearables;
|
||||||
|
|
||||||
if (handlerRequestWearables != null)
|
if (handlerRequestWearables != null)
|
||||||
|
@ -5595,7 +5606,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// for the client session anyway, in order to protect ourselves against bad code in plugins
|
// for the client session anyway, in order to protect ourselves against bad code in plugins
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
byte[] visualparams = new byte[appear.VisualParam.Length];
|
byte[] visualparams = new byte[appear.VisualParam.Length];
|
||||||
for (int i = 0; i < appear.VisualParam.Length; i++)
|
for (int i = 0; i < appear.VisualParam.Length; i++)
|
||||||
visualparams[i] = appear.VisualParam[i].ParamValue;
|
visualparams[i] = appear.VisualParam[i].ParamValue;
|
||||||
|
@ -5604,10 +5614,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if (appear.ObjectData.TextureEntry.Length > 1)
|
if (appear.ObjectData.TextureEntry.Length > 1)
|
||||||
te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
|
te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
|
||||||
|
|
||||||
if (handlerSetAppearance != null)
|
// What would happen if we ignore any SetAppearance packet that does not include textures?
|
||||||
handlerSetAppearance(te, visualparams);
|
if (te == null)
|
||||||
|
{
|
||||||
|
//m_log.WarnFormat("[LLCLIENTVIEW] Received SetAppearance from {0} ( )", Name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//m_log.WarnFormat("[LLCLIENTVIEW] Received SetAppearance from {0} (TE)", Name);
|
||||||
if (handlerSetAppearanceRaw != null)
|
if (handlerSetAppearanceRaw != null)
|
||||||
handlerSetAppearanceRaw(this, AgentId, visualparams, te);
|
handlerSetAppearanceRaw(this, AgentId, visualparams, te);
|
||||||
|
if (handlerSetAppearance != null)
|
||||||
|
handlerSetAppearance(te, visualparams);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -856,7 +856,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
// m_scene.SendKillObject(m_localId);
|
// m_scene.SendKillObject(m_localId);
|
||||||
|
|
||||||
agent.Scene.NotifyMyCoarseLocationChange();
|
|
||||||
// the user may change their profile information in other region,
|
// the user may change their profile information in other region,
|
||||||
// so the userinfo in UserProfileCache is not reliable any more, delete it
|
// so the userinfo in UserProfileCache is not reliable any more, delete it
|
||||||
// REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
|
// REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
|
||||||
|
|
|
@ -33,7 +33,7 @@ using OpenMetaverse.Packets;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
|
||||||
namespace OpenSim.Region.Examples.RegionSyncModule
|
namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
{
|
{
|
||||||
public class RegionSyncAvatar : IClientAPI
|
public class RegionSyncAvatar : IClientAPI
|
||||||
{
|
{
|
||||||
|
@ -419,6 +419,11 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
set { }
|
set { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public uint MaxCoarseLocations
|
||||||
|
{
|
||||||
|
get { return 0; }
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void ActivateGesture(UUID assetId, UUID gestureId)
|
public virtual void ActivateGesture(UUID assetId, UUID gestureId)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Region.Framework.Scenes.Types;
|
using OpenSim.Region.Framework.Scenes.Types;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
|
||||||
namespace OpenSim.Region.Examples.RegionSyncModule
|
namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
{
|
{
|
||||||
// The RegionSyncClient has a receive thread to process messages from the RegionSyncServer.
|
// The RegionSyncClient has a receive thread to process messages from the RegionSyncServer.
|
||||||
public class RegionSyncClient
|
public class RegionSyncClient
|
||||||
|
@ -45,6 +45,16 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
Dictionary<UUID, RegionSyncAvatar> m_remoteAvatars = new Dictionary<UUID, RegionSyncAvatar>();
|
Dictionary<UUID, RegionSyncAvatar> m_remoteAvatars = new Dictionary<UUID, RegionSyncAvatar>();
|
||||||
Dictionary<UUID, IClientAPI> m_localAvatars = new Dictionary<UUID, IClientAPI>();
|
Dictionary<UUID, IClientAPI> m_localAvatars = new Dictionary<UUID, IClientAPI>();
|
||||||
|
|
||||||
|
private Dictionary<UUID, RegionSyncAvatar> RemoteAvatars
|
||||||
|
{
|
||||||
|
get { return m_remoteAvatars; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<UUID, IClientAPI> LocalAvatars
|
||||||
|
{
|
||||||
|
get { return m_localAvatars; }
|
||||||
|
}
|
||||||
|
|
||||||
// The logfile
|
// The logfile
|
||||||
private ILog m_log;
|
private ILog m_log;
|
||||||
|
|
||||||
|
@ -56,18 +66,20 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
// The client connection to the RegionSyncServer
|
// The client connection to the RegionSyncServer
|
||||||
private TcpClient m_client = new TcpClient();
|
private TcpClient m_client = new TcpClient();
|
||||||
|
|
||||||
// The queue of incoming messages which need handling
|
private string m_regionName;
|
||||||
//private Queue<string> m_inQ = new Queue<string>();
|
|
||||||
|
private System.Timers.Timer m_statsTimer = new System.Timers.Timer(30000);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
public RegionSyncClient(Scene scene, string addr, int port)
|
public RegionSyncClient(Scene scene, string addr, int port)
|
||||||
{
|
{
|
||||||
m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
//m_log.WarnFormat("{0} Constructed", LogHeader);
|
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
m_addr = IPAddress.Parse(addr);
|
m_addr = IPAddress.Parse(addr);
|
||||||
m_port = port;
|
m_port = port;
|
||||||
|
|
||||||
|
m_statsTimer.Elapsed += new System.Timers.ElapsedEventHandler(StatsTimerElapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the RegionSyncClient
|
// Start the RegionSyncClient
|
||||||
|
@ -91,6 +103,7 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
m_rcvLoop.Start();
|
m_rcvLoop.Start();
|
||||||
//m_log.WarnFormat("{0} Started", LogHeader);
|
//m_log.WarnFormat("{0} Started", LogHeader);
|
||||||
DoInitialSync();
|
DoInitialSync();
|
||||||
|
m_statsTimer.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disconnect from the RegionSyncServer and close the RegionSyncClient
|
// Disconnect from the RegionSyncServer and close the RegionSyncClient
|
||||||
|
@ -101,43 +114,66 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
ShutdownClient();
|
ShutdownClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ReportStatus()
|
||||||
|
{
|
||||||
|
Dictionary<UUID, IClientAPI> locals = LocalAvatars;
|
||||||
|
Dictionary<UUID, RegionSyncAvatar> remotes = RemoteAvatars;
|
||||||
|
|
||||||
|
m_log.WarnFormat("{0}: {1,4} Local avatars", LogHeader, locals.Count);
|
||||||
|
foreach (KeyValuePair<UUID, IClientAPI> kvp in locals)
|
||||||
|
{
|
||||||
|
ScenePresence sp;
|
||||||
|
bool inScene = m_scene.TryGetScenePresence(kvp.Value.AgentId, out sp);
|
||||||
|
m_log.WarnFormat("{0}: {1} {2} {3}", LogHeader, kvp.Value.AgentId, kvp.Value.Name, inScene ? "" : "(NOT IN SCENE)");
|
||||||
|
}
|
||||||
|
m_log.WarnFormat("{0}: {1,4} Remote avatars", LogHeader, remotes.Count);
|
||||||
|
foreach (KeyValuePair<UUID, RegionSyncAvatar> kvp in remotes)
|
||||||
|
{
|
||||||
|
ScenePresence sp;
|
||||||
|
bool inScene = m_scene.TryGetScenePresence(kvp.Value.AgentId, out sp);
|
||||||
|
m_log.WarnFormat("{0}: {1} {2} {3}", LogHeader, kvp.Value.AgentId, kvp.Value.Name, inScene ? "" : "(NOT IN SCENE)");
|
||||||
|
}
|
||||||
|
m_log.WarnFormat("{0}: ===================================================", LogHeader);
|
||||||
|
m_log.WarnFormat("{0} Synchronized to RegionSyncServer at {1}:{2}", LogHeader, m_addr, m_port);
|
||||||
|
m_log.WarnFormat("{0}: {1,4} Local avatars", LogHeader, locals.Count);
|
||||||
|
m_log.WarnFormat("{0}: {1,4} Remote avatars", LogHeader, remotes.Count);
|
||||||
|
}
|
||||||
|
|
||||||
private void ShutdownClient()
|
private void ShutdownClient()
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("{0} Disconnected from RegionSyncServer. Shutting down.", LogHeader);
|
m_log.WarnFormat("{0} Disconnected from RegionSyncServer. Shutting down.", LogHeader);
|
||||||
|
|
||||||
lock (m_syncRoot)
|
// Remove remote avatars from local scene
|
||||||
|
try
|
||||||
{
|
{
|
||||||
// Remove remote avatars from local scene
|
foreach (KeyValuePair<UUID, RegionSyncAvatar> kvp in RemoteAvatars)
|
||||||
try
|
|
||||||
{
|
{
|
||||||
List<UUID> remoteAvatars = new List<UUID>(m_remoteAvatars.Keys);
|
// This will cause a callback into RemoveLocalClient
|
||||||
foreach (UUID id in remoteAvatars)
|
m_scene.RemoveClient(kvp.Key);
|
||||||
{
|
|
||||||
m_scene.RemoveClient(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("Caught exception while removing remote avatars on Shutdown: {0}", e.Message);
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Remove local avatars from remote scene
|
|
||||||
List<KeyValuePair<UUID, IClientAPI>> localAvatars = new List<KeyValuePair<UUID, IClientAPI>>(m_localAvatars);
|
|
||||||
foreach (KeyValuePair<UUID, IClientAPI> kvp in localAvatars)
|
|
||||||
{
|
|
||||||
// Tell the remote scene to remove this client
|
|
||||||
RemoveLocalClient(kvp.Key, m_scene);
|
|
||||||
// Remove the agent update handler from the client
|
|
||||||
kvp.Value.OnAgentUpdateRaw -= HandleAgentUpdateRaw;
|
|
||||||
kvp.Value.OnSetAppearanceRaw -= HandleSetAppearanceRaw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("Caught exception while removing local avatars on Shutdown: {0}", e.Message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("Caught exception while removing remote avatars on Shutdown: {0}", e.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Remove local avatars from remote scene
|
||||||
|
foreach (KeyValuePair<UUID, IClientAPI> kvp in LocalAvatars)
|
||||||
|
{
|
||||||
|
// Tell the remote scene to remove this client
|
||||||
|
RemoveLocalClient(kvp.Key, m_scene);
|
||||||
|
// Remove the agent update handler from the client
|
||||||
|
kvp.Value.OnAgentUpdateRaw -= HandleAgentUpdateRaw;
|
||||||
|
kvp.Value.OnSetAppearanceRaw -= HandleSetAppearanceRaw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("Caught exception while removing local avatars on Shutdown: {0}", e.Message);
|
||||||
|
}
|
||||||
|
|
||||||
// Close the connection
|
// Close the connection
|
||||||
m_client.Client.Close();
|
m_client.Client.Close();
|
||||||
m_client.Close();
|
m_client.Close();
|
||||||
|
@ -167,29 +203,11 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
// Try handling the message
|
// Try handling the message
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string message;
|
HandleMessage(msg);
|
||||||
MsgHandlerStatus status;
|
|
||||||
lock(m_syncRoot)
|
|
||||||
status = HandleMessage(msg, out message);
|
|
||||||
switch (status)
|
|
||||||
{
|
|
||||||
case MsgHandlerStatus.Success:
|
|
||||||
//m_log.WarnFormat("{0} Handled {1}: {2}", LogHeader, msg.ToString(), message);
|
|
||||||
break;
|
|
||||||
case MsgHandlerStatus.Trivial:
|
|
||||||
m_log.WarnFormat("{0} Issue handling {1}: {2}", LogHeader, msg.ToString(), message);
|
|
||||||
break;
|
|
||||||
case MsgHandlerStatus.Warning:
|
|
||||||
m_log.WarnFormat("{0} Warning handling {1}: {2}", LogHeader, msg.ToString(), message);
|
|
||||||
break;
|
|
||||||
case MsgHandlerStatus.Error:
|
|
||||||
m_log.WarnFormat("{0} Error handling {1}: {2}", LogHeader, msg.ToString(), message);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("{0} Encountered an exception: {1}", LogHeader, e.Message);
|
m_log.WarnFormat("{0} Encountered an exception: {1} (MSGTYPE = {2})", LogHeader, e.Message, msg.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,155 +252,116 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
List<UUID> ids = new List<UUID>();
|
List<UUID> ids = new List<UUID>();
|
||||||
List<Vector3> locations = new List<Vector3>();
|
List<Vector3> locations = new List<Vector3>();
|
||||||
m_scene.GetCoarseLocations(out ids, out locations);
|
m_scene.GetCoarseLocations(out ids, out locations);
|
||||||
lock (m_syncRoot)
|
foreach (KeyValuePair<UUID, IClientAPI> kvp in LocalAvatars)
|
||||||
{
|
{
|
||||||
foreach (IClientAPI client in m_localAvatars.Values)
|
kvp.Value.SendCoarseLocationUpdate(ids, locations);
|
||||||
{
|
|
||||||
client.SendCoarseLocationUpdate(ids, locations);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HashSet<string> exceptions = new HashSet<string>();
|
|
||||||
private OSDMap DeserializeMessage(RegionSyncMessage msg)
|
|
||||||
{
|
|
||||||
OSDMap data = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
data = OSDParser.DeserializeJson(Encoding.ASCII.GetString(msg.Data)) as OSDMap;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
lock (exceptions)
|
|
||||||
// If this is a new message, then print the underlying data that caused it
|
|
||||||
if (!exceptions.Contains(e.Message))
|
|
||||||
m_log.Error(LogHeader + " " + Encoding.ASCII.GetString(msg.Data));
|
|
||||||
data = null;
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle an incoming message
|
// Handle an incoming message
|
||||||
// Returns true if the message was processed
|
|
||||||
// TODO: This should not be synchronous with the receive!
|
// TODO: This should not be synchronous with the receive!
|
||||||
// Instead, handle messages from the incoming Queue
|
// Instead, handle messages from an incoming Queue so server doesn't block sending
|
||||||
private MsgHandlerStatus HandleMessage(RegionSyncMessage msg, out string result)
|
private void HandleMessage(RegionSyncMessage msg)
|
||||||
{
|
{
|
||||||
switch (msg.Type)
|
switch (msg.Type)
|
||||||
{
|
{
|
||||||
|
case RegionSyncMessage.MsgType.RegionName:
|
||||||
|
{
|
||||||
|
m_regionName = Encoding.ASCII.GetString(msg.Data, 0, msg.Length);
|
||||||
|
RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Syncing to region \"{0}\"", m_regionName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
case RegionSyncMessage.MsgType.Terrain:
|
case RegionSyncMessage.MsgType.Terrain:
|
||||||
{
|
{
|
||||||
m_scene.Heightmap.LoadFromXmlString(Encoding.ASCII.GetString(msg.Data));
|
m_scene.Heightmap.LoadFromXmlString(Encoding.ASCII.GetString(msg.Data, 0, msg.Length));
|
||||||
result = "Synchronized terrain";
|
RegionSyncMessage.HandleSuccess(LogHeader, msg, "Synchronized terrain");
|
||||||
return MsgHandlerStatus.Success;
|
return;
|
||||||
}
|
}
|
||||||
case RegionSyncMessage.MsgType.NewObject:
|
case RegionSyncMessage.MsgType.NewObject:
|
||||||
case RegionSyncMessage.MsgType.UpdatedObject:
|
case RegionSyncMessage.MsgType.UpdatedObject:
|
||||||
{
|
{
|
||||||
SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(Encoding.ASCII.GetString(msg.Data));
|
SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(Encoding.ASCII.GetString(msg.Data, 0, msg.Length));
|
||||||
if (sog.IsDeleted)
|
if (sog.IsDeleted)
|
||||||
{
|
{
|
||||||
result = String.Format("Ignoring update on deleted LocalId {0}.", sog.LocalId.ToString());
|
RegionSyncMessage.HandleTrivial(LogHeader, msg, String.Format("Ignoring update on deleted LocalId {0}.", sog.LocalId.ToString()));
|
||||||
return MsgHandlerStatus.Trivial;
|
return;
|
||||||
}
|
}
|
||||||
if (m_scene.AddNewSceneObject(sog, true))
|
|
||||||
result = String.Format("Object \"{0}\" ({1}) ({1}) updated.", sog.Name, sog.UUID.ToString(), sog.LocalId.ToString());
|
if (m_scene.AddNewSceneObject(sog, true));
|
||||||
else
|
//RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Object \"{0}\" ({1}) ({1}) updated.", sog.Name, sog.UUID.ToString(), sog.LocalId.ToString()));
|
||||||
result = String.Format("Object \"{0}\" ({1}) ({1}) added.", sog.Name, sog.UUID.ToString(), sog.LocalId.ToString());
|
//else
|
||||||
|
//RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Object \"{0}\" ({1}) ({1}) added.", sog.Name, sog.UUID.ToString(), sog.LocalId.ToString()));
|
||||||
sog.ScheduleGroupForFullUpdate();
|
sog.ScheduleGroupForFullUpdate();
|
||||||
return MsgHandlerStatus.Success;
|
return;
|
||||||
}
|
}
|
||||||
// return HandlerSuccess(msg, "Updated avatar");
|
|
||||||
/*
|
|
||||||
case RegionSyncMessage.MsgType.SetObjectPosition: Attributes!
|
|
||||||
{
|
|
||||||
if (part.ParentGroup == null)
|
|
||||||
{
|
|
||||||
part.UpdateOffSet(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
|
|
||||||
}
|
|
||||||
else if (part.ParentGroup.RootPart == part)
|
|
||||||
{
|
|
||||||
part.parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
part.OffsetPosition = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z);
|
|
||||||
SceneObjectGroup parent = part.ParentGroup;
|
|
||||||
parent.HasGroupChanged = true;
|
|
||||||
parent.ScheduleGroupForTerseUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
* */
|
|
||||||
case RegionSyncMessage.MsgType.RemovedObject:
|
case RegionSyncMessage.MsgType.RemovedObject:
|
||||||
{
|
{
|
||||||
OSDMap data = DeserializeMessage(msg);
|
// Get the data from message and error check
|
||||||
if( data != null )
|
|
||||||
{
|
|
||||||
ulong regionHandle = data["regionHandle"].AsULong();
|
|
||||||
uint localID = data["localID"].AsUInteger();
|
|
||||||
|
|
||||||
// We get the UUID of the object to be deleted, find it in the scene
|
|
||||||
if (regionHandle != 0 && localID != 0 )
|
|
||||||
{
|
|
||||||
if (regionHandle == m_scene.RegionInfo.RegionHandle)
|
|
||||||
{
|
|
||||||
SceneObjectGroup sog = m_scene.SceneGraph.GetGroupByPrim(localID);
|
|
||||||
if (sog != null)
|
|
||||||
{
|
|
||||||
m_scene.DeleteSceneObject(sog, false);
|
|
||||||
result = String.Format("localID {0} deleted.", localID.ToString());
|
|
||||||
return MsgHandlerStatus.Success;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result = String.Format("ignoring delete request for non-local regionHandle {0}.", regionHandle.ToString());
|
|
||||||
return MsgHandlerStatus.Trivial;
|
|
||||||
}
|
|
||||||
result = String.Format("localID {0} not found.", localID.ToString());
|
|
||||||
return MsgHandlerStatus.Warning;
|
|
||||||
}
|
|
||||||
result = "Could not deserialize JSON data.";
|
|
||||||
return MsgHandlerStatus.Error;
|
|
||||||
}
|
|
||||||
case RegionSyncMessage.MsgType.NewAvatar:
|
|
||||||
{
|
|
||||||
OSDMap data = DeserializeMessage(msg);
|
OSDMap data = DeserializeMessage(msg);
|
||||||
if (data == null)
|
if (data == null)
|
||||||
{
|
{
|
||||||
result = "Could not deserialize JSON data.";
|
RegionSyncMessage.HandleError(LogHeader, msg, "Could not deserialize JSON data.");
|
||||||
return MsgHandlerStatus.Error;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the parameters from data
|
||||||
|
//ulong regionHandle = data["regionHandle"].AsULong();
|
||||||
|
uint localID = data["localID"].AsUInteger();
|
||||||
|
|
||||||
|
// Find the object in the scene
|
||||||
|
SceneObjectGroup sog = m_scene.SceneGraph.GetGroupByPrim(localID);
|
||||||
|
if (sog == null)
|
||||||
|
{
|
||||||
|
//RegionSyncMessage.HandleWarning(LogHeader, msg, String.Format("localID {0} not found.", localID.ToString()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the object from the scene
|
||||||
|
m_scene.DeleteSceneObject(sog, false);
|
||||||
|
RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("localID {0} deleted.", localID.ToString()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case RegionSyncMessage.MsgType.NewAvatar:
|
||||||
|
{
|
||||||
|
// Get the data from message and error check
|
||||||
|
OSDMap data = DeserializeMessage(msg);
|
||||||
|
if (data == null)
|
||||||
|
{
|
||||||
|
RegionSyncMessage.HandleError(LogHeader, msg, "Could not deserialize JSON data.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the parameters from data and error check
|
||||||
UUID agentID = data["agentID"].AsUUID();
|
UUID agentID = data["agentID"].AsUUID();
|
||||||
string first = data["first"].AsString();
|
string first = data["first"].AsString();
|
||||||
string last = data["last"].AsString();
|
string last = data["last"].AsString();
|
||||||
Vector3 startPos = data["startPos"].AsVector3();
|
Vector3 startPos = data["startPos"].AsVector3();
|
||||||
|
|
||||||
if (agentID == null || agentID == UUID.Zero || first == null || last == null || startPos == null)
|
if (agentID == null || agentID == UUID.Zero || first == null || last == null || startPos == null)
|
||||||
{
|
{
|
||||||
result = "Missing or invalid JSON data.";
|
RegionSyncMessage.HandleError(LogHeader, msg, "Missing or invalid JSON data.");
|
||||||
return MsgHandlerStatus.Error;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_remoteAvatars.ContainsKey(agentID))
|
if (m_remoteAvatars.ContainsKey(agentID))
|
||||||
{
|
{
|
||||||
result = String.Format("Attempted to add duplicate avatar \"{0} {1}\" ({2})", first, last, agentID.ToString());
|
RegionSyncMessage.HandleWarning(LogHeader, msg, String.Format("Attempted to add duplicate avatar \"{0} {1}\" ({2})", first, last, agentID.ToString()));
|
||||||
return MsgHandlerStatus.Warning;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScenePresence sp;
|
ScenePresence sp;
|
||||||
if (m_scene.TryGetScenePresence(agentID, out sp))
|
if (m_scene.TryGetScenePresence(agentID, out sp))
|
||||||
{
|
{
|
||||||
result = String.Format("Confirmation of new avatar \"{0}\" ({1})", sp.Name, sp.UUID.ToString());
|
//RegionSyncMessage.HandlerDebug(LogHeader, msg, String.Format("Confirmation of new avatar \"{0}\" ({1})", sp.Name, sp.UUID.ToString()));
|
||||||
HandlerDebug(msg, result);
|
RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Confirmation of new avatar \"{0}\" ({1})", sp.Name, sp.UUID.ToString()));
|
||||||
return MsgHandlerStatus.Success;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RegionSyncAvatar av = new RegionSyncAvatar(m_scene, agentID, first, last, startPos);
|
RegionSyncAvatar av = new RegionSyncAvatar(m_scene, agentID, first, last, startPos);
|
||||||
m_remoteAvatars.Add(agentID, av);
|
m_remoteAvatars.Add(agentID, av);
|
||||||
m_scene.AddNewClient(av);
|
m_scene.AddNewClient(av);
|
||||||
result = String.Format("Added new remote avatar \"{0}\" ({1})", first + " " + last, agentID);
|
//RegionSyncMessage.HandlerDebug(LogHeader, msg, String.Format("Added new remote avatar \"{0}\" ({1})", first + " " + last, agentID));
|
||||||
HandlerDebug(msg, result);
|
RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Added new remote avatar \"{0}\" ({1})", first + " " + last, agentID));
|
||||||
return MsgHandlerStatus.Success;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
case RegionSyncMessage.MsgType.UpdatedAvatar:
|
case RegionSyncMessage.MsgType.UpdatedAvatar:
|
||||||
|
@ -391,21 +370,37 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
OSDMap data = DeserializeMessage(msg);
|
OSDMap data = DeserializeMessage(msg);
|
||||||
if (data == null)
|
if (data == null)
|
||||||
{
|
{
|
||||||
result = "Could not deserialize JSON data.";
|
RegionSyncMessage.HandleError(LogHeader, msg, "Could not deserialize JSON data.");
|
||||||
return MsgHandlerStatus.Error;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the parameters from data and error check
|
// Get the parameters from data and error check
|
||||||
UUID agentID = data["id"].AsUUID();
|
UUID agentID = UUID.Zero;
|
||||||
Vector3 pos = data["pos"].AsVector3();
|
Vector3 pos = Vector3.Zero;
|
||||||
Vector3 vel = data["vel"].AsVector3();
|
Vector3 vel = Vector3.Zero;
|
||||||
Quaternion rot = data["rot"].AsQuaternion();
|
Quaternion rot = Quaternion.Identity;
|
||||||
bool flying = data["fly"].AsBoolean();
|
bool flying = false;
|
||||||
uint flags = data["flags"].AsUInteger();
|
string anim = "";
|
||||||
|
uint flags = 0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
agentID = data["id"].AsUUID();
|
||||||
|
pos = data["pos"].AsVector3();
|
||||||
|
vel = data["vel"].AsVector3();
|
||||||
|
rot = data["rot"].AsQuaternion();
|
||||||
|
flying = data["fly"].AsBoolean();
|
||||||
|
anim = data["anim"].AsString();
|
||||||
|
flags = data["flags"].AsUInteger();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("{0} Caught exception in UpdatedAvatar handler (Decoding JSON): {1}", LogHeader, e.Message);
|
||||||
|
}
|
||||||
if (agentID == null || agentID == UUID.Zero )
|
if (agentID == null || agentID == UUID.Zero )
|
||||||
{
|
{
|
||||||
result = "Missing or invalid JSON data.";
|
RegionSyncMessage.HandleError(LogHeader, msg, "Missing or invalid JSON data.");
|
||||||
return MsgHandlerStatus.Error;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the presence in the scene and error check
|
// Find the presence in the scene and error check
|
||||||
|
@ -413,12 +408,12 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
m_scene.TryGetScenePresence(agentID, out presence);
|
m_scene.TryGetScenePresence(agentID, out presence);
|
||||||
if (presence == null)
|
if (presence == null)
|
||||||
{
|
{
|
||||||
result = String.Format("agentID {0} not found.", agentID.ToString());
|
//RegionSyncMessage.HandleWarning(LogHeader, msg, String.Format("agentID {0} not found.", agentID.ToString()));
|
||||||
return MsgHandlerStatus.Warning;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
// Update the scene presence from parameters
|
// Update the scene presence from parameters
|
||||||
/*
|
|
||||||
bool updateAnimations = ((presence.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY ) != (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY ) ||
|
bool updateAnimations = ((presence.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY ) != (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY ) ||
|
||||||
(presence.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS ) != (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS ) ||
|
(presence.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS ) != (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS ) ||
|
||||||
(presence.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG ) != (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG ) ||
|
(presence.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG ) != (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG ) ||
|
||||||
|
@ -426,27 +421,56 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
(presence.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG ) != (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG ) ||
|
(presence.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG ) != (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG ) ||
|
||||||
(presence.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT ) != (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT ) ||
|
(presence.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT ) != (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT ) ||
|
||||||
(presence.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT ) != (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT ));
|
(presence.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT ) != (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT ));
|
||||||
* */
|
*/
|
||||||
presence.AgentControlFlags = flags;
|
try
|
||||||
presence.AbsolutePosition = pos;
|
{
|
||||||
presence.Velocity = vel;
|
presence.AgentControlFlags = flags;
|
||||||
presence.Rotation = rot;
|
presence.AbsolutePosition = pos;
|
||||||
bool updateAnimations =
|
presence.Velocity = vel;
|
||||||
presence.PhysicsActor.Flying = flying;
|
presence.Rotation = rot;
|
||||||
List<IClientAPI> locals;
|
// It seems the physics scene can drop an avatar if the avatar makes it angry
|
||||||
lock (m_syncRoot)
|
if (presence.PhysicsActor != null)
|
||||||
locals = new List<IClientAPI>(m_localAvatars.Values);
|
{
|
||||||
presence.SendTerseUpdateToClientList(locals);
|
presence.PhysicsActor.Flying = flying;
|
||||||
if(updateAnimations)
|
presence.PhysicsActor.CollidingGround = !flying;
|
||||||
presence.Animator.UpdateMovementAnimations();
|
}
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("{0} Caught exception in UpdatedAvatar handler (setting presence values) for {1}: {2}", LogHeader, presence.Name, e.Message);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
presence.SendTerseUpdateToAllClients();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("{0} Caught exception in UpdatedAvatar handler (SendTerseUpdateToAllClients): {1}", LogHeader, e.Message);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
foreach (KeyValuePair<UUID, IClientAPI> kvp in LocalAvatars)
|
||||||
|
{
|
||||||
|
presence.SendTerseUpdateToClient(kvp.Value);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// If the animation has changed, set the new animation
|
||||||
|
if (!presence.Animator.CurrentMovementAnimation.Equals(anim))
|
||||||
|
presence.Animator.TrySetMovementAnimation(anim);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("{0} Caught exception in UpdatedAvatar handler (TrySetMovementAnimation): {1}", LogHeader, e.Message);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* result = String.Format("Avatar \"{0}\" ({1}) ({2}) updated (pos:{3}, vel:{4}, rot:{5}, fly:{6})",
|
* result = String.Format("Avatar \"{0}\" ({1}) ({2}) updated (pos:{3}, vel:{4}, rot:{5}, fly:{6})",
|
||||||
presence.Name, presence.UUID.ToString(), presence.LocalId.ToString(),
|
presence.Name, presence.UUID.ToString(), presence.LocalId.ToString(),
|
||||||
presence.AbsolutePosition.ToString(), presence.Velocity.ToString(),
|
presence.AbsolutePosition.ToString(), presence.Velocity.ToString(),
|
||||||
presence.Rotation.ToString(), presence.PhysicsActor.Flying ? "Y" : "N");
|
presence.Rotation.ToString(), presence.PhysicsActor.Flying ? "Y" : "N");
|
||||||
|
HandleSuccess(msg, result);
|
||||||
* */
|
* */
|
||||||
result = ""; // For performance, skip creating that long string unless debugging
|
return;
|
||||||
return MsgHandlerStatus.Success;
|
|
||||||
}
|
}
|
||||||
case RegionSyncMessage.MsgType.RemovedAvatar:
|
case RegionSyncMessage.MsgType.RemovedAvatar:
|
||||||
{
|
{
|
||||||
|
@ -454,44 +478,74 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
OSDMap data = DeserializeMessage(msg);
|
OSDMap data = DeserializeMessage(msg);
|
||||||
if (data == null)
|
if (data == null)
|
||||||
{
|
{
|
||||||
result = "Could not deserialize JSON data.";
|
RegionSyncMessage.HandleError(LogHeader, msg, "Could not deserialize JSON data.");
|
||||||
return MsgHandlerStatus.Error;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the agentID from data and error check
|
// Get the agentID from data and error check
|
||||||
UUID agentID = data["agentID"].AsUUID();
|
UUID agentID = data["agentID"].AsUUID();
|
||||||
if (agentID == UUID.Zero)
|
if (agentID == UUID.Zero)
|
||||||
{
|
{
|
||||||
result = "Missing or invalid JSON data.";
|
RegionSyncMessage.HandleError(LogHeader, msg, "Missing or invalid JSON data.");
|
||||||
return MsgHandlerStatus.Error;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the presence in the scene and error check
|
// Try to get the presence from the scene
|
||||||
|
|
||||||
|
|
||||||
ScenePresence presence;
|
ScenePresence presence;
|
||||||
m_scene.TryGetScenePresence(agentID, out presence);
|
m_scene.TryGetScenePresence(agentID, out presence);
|
||||||
if(presence == null)
|
|
||||||
{
|
|
||||||
result = String.Format("agentID {0} not found.", agentID.ToString());
|
|
||||||
return MsgHandlerStatus.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the presence from the scene and if it's remote, then from the remote list too
|
// Local and Remote avatar dictionaries will only be modified under this lock
|
||||||
m_scene.RemoveClient(agentID);
|
// They can be read without locking as we are just going to swap refs atomically
|
||||||
if (m_remoteAvatars.ContainsKey(agentID))
|
lock (m_syncRoot)
|
||||||
{
|
{
|
||||||
result = String.Format("Remote avatar \"{0}\" removed from scene", presence.Name);
|
|
||||||
HandlerDebug(msg, result);
|
if (RemoteAvatars.ContainsKey(agentID))
|
||||||
return MsgHandlerStatus.Success;
|
{
|
||||||
|
Dictionary<UUID, RegionSyncAvatar> newremotes = new Dictionary<UUID, RegionSyncAvatar>(RemoteAvatars);
|
||||||
|
string name = newremotes[agentID].Name;
|
||||||
|
// Remove from list of remote avatars
|
||||||
|
newremotes.Remove(agentID);
|
||||||
|
m_remoteAvatars = newremotes;
|
||||||
|
|
||||||
|
// If this presence is in out remote list, then this message tells us to remove it from the
|
||||||
|
// local scene so we should find it there.
|
||||||
|
if (presence == null)
|
||||||
|
{
|
||||||
|
RegionSyncMessage.HandleError(LogHeader, msg, String.Format("Couldn't remove remote avatar \"{0}\" because it's not in local scene", name));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_scene.RemoveClient(agentID);
|
||||||
|
RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Remote avatar \"{0}\" removed from scene", name));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (LocalAvatars.ContainsKey(agentID))
|
||||||
|
{
|
||||||
|
Dictionary<UUID, IClientAPI> newlocals = new Dictionary<UUID, IClientAPI>(LocalAvatars);
|
||||||
|
string name = newlocals[agentID].Name;
|
||||||
|
// Remove from list of local avatars
|
||||||
|
newlocals.Remove(agentID);
|
||||||
|
m_localAvatars = newlocals;
|
||||||
|
|
||||||
|
// If this presence is in our local list, then this message is a confirmation from the server
|
||||||
|
// and the presence should not be in our scene at this time.
|
||||||
|
if (presence != null)
|
||||||
|
{
|
||||||
|
RegionSyncMessage.HandleError(LogHeader, msg, String.Format("Remove avatar confirmation received for \"{0}\" still in the local scene.", name));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Received confirmation of removed avatar \"{0}\"", name));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(m_localAvatars.ContainsKey(agentID))
|
// Getting here is always an error because we have been asked to remove and avatar
|
||||||
{
|
// so it should have been in either the local or remote collections
|
||||||
result = String.Format("Received confirmation of removed avatar \"{0}\" ({1})", presence.Name, presence.UUID.ToString());
|
if (presence == null)
|
||||||
HandlerDebug(msg, result);
|
RegionSyncMessage.HandleError(LogHeader, msg, String.Format("Avatar is not local OR remote and was not found in scene: \"{0}\" {1}", presence.Name, agentID.ToString()));
|
||||||
return MsgHandlerStatus.Success;
|
else
|
||||||
}
|
RegionSyncMessage.HandleError(LogHeader, msg, String.Format("Avatar is not local OR remote but was found in scene: {1}", agentID.ToString()));
|
||||||
result = String.Format("Avatar is not local OR remote but was found in scene: \"{0}\" ({1})", presence.Name, presence.UUID.ToString());
|
return;
|
||||||
HandlerDebug(msg, result);
|
|
||||||
return MsgHandlerStatus.Error;
|
|
||||||
}
|
}
|
||||||
case RegionSyncMessage.MsgType.ChatFromClient:
|
case RegionSyncMessage.MsgType.ChatFromClient:
|
||||||
{
|
{
|
||||||
|
@ -499,8 +553,8 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
OSDMap data = DeserializeMessage(msg);
|
OSDMap data = DeserializeMessage(msg);
|
||||||
if (data == null)
|
if (data == null)
|
||||||
{
|
{
|
||||||
result = "Could not deserialize JSON data.";
|
RegionSyncMessage.HandleError(LogHeader, msg, "Could not deserialize JSON data.");
|
||||||
return MsgHandlerStatus.Error;
|
return;
|
||||||
}
|
}
|
||||||
OSChatMessage args = new OSChatMessage();
|
OSChatMessage args = new OSChatMessage();
|
||||||
args.Channel = data["channel"].AsInteger();
|
args.Channel = data["channel"].AsInteger();
|
||||||
|
@ -519,26 +573,27 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
m_scene.EventManager.TriggerOnChatBroadcast(sp.ControllingClient, args);
|
m_scene.EventManager.TriggerOnChatBroadcast(sp.ControllingClient, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = String.Format("Received chat from \"{0}\"", args.From);
|
//RegionSyncMessage.HandlerDebug(LogHeader, msg, String.Format("Received chat from \"{0}\"", args.From));
|
||||||
HandlerDebug(msg, result);
|
RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Received chat from \"{0}\"", args.From));
|
||||||
return MsgHandlerStatus.Success;
|
return;
|
||||||
}
|
}
|
||||||
case RegionSyncMessage.MsgType.AvatarAppearance:
|
case RegionSyncMessage.MsgType.AvatarAppearance:
|
||||||
{
|
{
|
||||||
|
//m_log.WarnFormat("{0} START of AvatarAppearance handler", LogHeader);
|
||||||
// Get the data from message and error check
|
// Get the data from message and error check
|
||||||
OSDMap data = DeserializeMessage(msg);
|
OSDMap data = DeserializeMessage(msg);
|
||||||
if (data == null)
|
if (data == null)
|
||||||
{
|
{
|
||||||
result = "Could not deserialize JSON data.";
|
RegionSyncMessage.HandleError(LogHeader, msg, "Could not deserialize JSON data.");
|
||||||
return MsgHandlerStatus.Error;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the parameters from data and error check
|
// Get the parameters from data and error check
|
||||||
UUID agentID = data["id"].AsUUID();
|
UUID agentID = data["id"].AsUUID();
|
||||||
if (agentID == null || agentID == UUID.Zero)
|
if (agentID == null || agentID == UUID.Zero)
|
||||||
{
|
{
|
||||||
result = "Missing or invalid JSON data.";
|
RegionSyncMessage.HandleError(LogHeader, msg, "Missing or invalid JSON data.");
|
||||||
return MsgHandlerStatus.Error;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the presence in the scene
|
// Find the presence in the scene
|
||||||
|
@ -549,67 +604,70 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
Primitive.TextureEntry te = Primitive.TextureEntry.FromOSD(data["te"]);
|
Primitive.TextureEntry te = Primitive.TextureEntry.FromOSD(data["te"]);
|
||||||
byte[] vp = data["vp"].AsBinary();
|
byte[] vp = data["vp"].AsBinary();
|
||||||
|
|
||||||
|
bool missingBakes = false;
|
||||||
byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
|
byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
|
||||||
for (int i = 0; i < BAKE_INDICES.Length; i++)
|
for (int i = 0; i < BAKE_INDICES.Length; i++)
|
||||||
{
|
{
|
||||||
int j = BAKE_INDICES[i];
|
int j = BAKE_INDICES[i];
|
||||||
Primitive.TextureEntryFace face = te.FaceTextures[j];
|
Primitive.TextureEntryFace face = te.FaceTextures[j];
|
||||||
if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
|
if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
|
||||||
|
{
|
||||||
if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
|
if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
|
||||||
HandlerDebug(msg, "Missing baked texture " + face.TextureID + " (" + j + ") for avatar " + name);
|
{
|
||||||
|
RegionSyncMessage.HandlerDebug(LogHeader, msg, "Missing baked texture " + face.TextureID + " (" + j + ") for avatar " + name);
|
||||||
|
missingBakes = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//m_log.WarnFormat("{0} Calling presence.SetAppearance for {1} (\"{2}\") {3}", LogHeader, agentID, presence.Name, missingBakes ? "MISSING BAKES" : "GOT BAKES");
|
||||||
presence.SetAppearance(te, vp);
|
presence.SetAppearance(te, vp);
|
||||||
result = String.Format("Agent \"{0}\" ({1}) updated their appearance.", name, agentID);
|
RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Set appearance for {0}", name));
|
||||||
return MsgHandlerStatus.Success;
|
|
||||||
}
|
}
|
||||||
result = String.Format("Agent {0} not found in the scene.", agentID);
|
else
|
||||||
return MsgHandlerStatus.Warning;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
case RegionSyncMessage.MsgType.UpdateObject:
|
|
||||||
{
|
|
||||||
UUID uuid;
|
|
||||||
if (UUID.TryParse(Encoding.ASCII.GetString(msg.Data), out uuid))
|
|
||||||
{
|
{
|
||||||
// We get the UUID of the object to be updated, find it in the scene
|
RegionSyncMessage.HandleWarning(LogHeader, msg, String.Format("Agent {0} not found in the scene.", agentID));
|
||||||
SceneObjectGroup sog = m_scene.SceneGraph.GetGroupByPrim(uuid);
|
|
||||||
Vector3 v = new Vector3();
|
|
||||||
v.ToString();
|
|
||||||
if (sog != null)
|
|
||||||
{
|
|
||||||
//m_scene.DeleteSceneObject(sog, false);
|
|
||||||
return HandlerSuccess(msg, String.Format("UUID {0} updated.", uuid.ToString()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return HandlerFailure(msg, String.Format("UUID {0} not found.", uuid.ToString()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return HandlerFailure(msg, "Could not parse UUID");
|
//m_log.WarnFormat("{0} END of AvatarAppearance handler", LogHeader);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
* */
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
result = String.Format("{0} Unsupported message type: {1}", LogHeader, ((int)msg.Type).ToString());
|
RegionSyncMessage.HandleError(LogHeader, msg, String.Format("{0} Unsupported message type: {1}", LogHeader, ((int)msg.Type).ToString()));
|
||||||
return MsgHandlerStatus.Error;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool HandlerDebug(RegionSyncMessage msg, string handlerMessage)
|
|
||||||
|
HashSet<string> exceptions = new HashSet<string>();
|
||||||
|
private OSDMap DeserializeMessage(RegionSyncMessage msg)
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("{0} DBG ({1}): {2}", LogHeader, msg.ToString(), handlerMessage);
|
OSDMap data = null;
|
||||||
return true;
|
try
|
||||||
|
{
|
||||||
|
data = OSDParser.DeserializeJson(Encoding.ASCII.GetString(msg.Data, 0, msg.Length)) as OSDMap;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
lock (exceptions)
|
||||||
|
// If this is a new message, then print the underlying data that caused it
|
||||||
|
if (!exceptions.Contains(e.Message))
|
||||||
|
m_log.Error(LogHeader + " " + Encoding.ASCII.GetString(msg.Data, 0, msg.Length));
|
||||||
|
data = null;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DoInitialSync()
|
private void DoInitialSync()
|
||||||
{
|
{
|
||||||
m_scene.DeleteAllSceneObjects();
|
m_scene.DeleteAllSceneObjects();
|
||||||
|
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.RegionName, m_scene.RegionInfo.RegionName));
|
||||||
|
m_log.WarnFormat("Sending region name: \"{0}\"", m_scene.RegionInfo.RegionName);
|
||||||
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetTerrain));
|
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetTerrain));
|
||||||
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetObjects));
|
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetObjects));
|
||||||
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetAvatars));
|
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetAvatars));
|
||||||
|
|
||||||
// Register for events which will be forwarded to authoritative scene
|
// Register for events which will be forwarded to authoritative scene
|
||||||
m_scene.EventManager.OnNewClient += EventManager_OnNewClient;
|
m_scene.EventManager.OnNewClient += EventManager_OnNewClient;
|
||||||
m_scene.EventManager.OnClientClosed += new EventManager.ClientClosed(RemoveLocalClient);
|
m_scene.EventManager.OnClientClosed += new EventManager.ClientClosed(RemoveLocalClient);
|
||||||
|
@ -625,17 +683,18 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
{
|
{
|
||||||
// If this client was added in response to NewAvatar message from a synced server,
|
// If this client was added in response to NewAvatar message from a synced server,
|
||||||
// don't subscribe to events or send back to server
|
// don't subscribe to events or send back to server
|
||||||
lock (m_remoteAvatars)
|
if (RemoteAvatars.ContainsKey(client.AgentId))
|
||||||
{
|
|
||||||
if (m_remoteAvatars.ContainsKey(client.AgentId))
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
// Otherwise, it's a real local client connecting so track it locally
|
// Otherwise, it's a real local client connecting so track it locally
|
||||||
lock(m_syncRoot)
|
lock (m_syncRoot)
|
||||||
m_localAvatars.Add(client.AgentId, client);
|
{
|
||||||
|
Dictionary<UUID, IClientAPI> newlocals = new Dictionary<UUID, IClientAPI>(LocalAvatars);
|
||||||
|
newlocals.Add(client.AgentId, client);
|
||||||
|
m_localAvatars = newlocals;
|
||||||
|
}
|
||||||
m_log.WarnFormat("{0} New local client \"{1}\" ({2}) being added to remote scene.", LogHeader, client.Name, client.AgentId.ToString());
|
m_log.WarnFormat("{0} New local client \"{1}\" ({2}) being added to remote scene.", LogHeader, client.Name, client.AgentId.ToString());
|
||||||
// Let the auth sim know that a new agent has connected
|
// Let the auth sim know that a new agent has connected
|
||||||
OSDMap data = new OSDMap(1);
|
OSDMap data = new OSDMap(4);
|
||||||
data["agentID"] = OSD.FromUUID(client.AgentId);
|
data["agentID"] = OSD.FromUUID(client.AgentId);
|
||||||
data["first"] = OSD.FromString(client.FirstName);
|
data["first"] = OSD.FromString(client.FirstName);
|
||||||
data["last"] = OSD.FromString(client.LastName);
|
data["last"] = OSD.FromString(client.LastName);
|
||||||
|
@ -654,14 +713,24 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
lock (m_syncRoot)
|
lock (m_syncRoot)
|
||||||
{
|
{
|
||||||
// If the client to be removed is a local client, then send a message to the remote scene
|
// If the client to be removed is a local client, then send a message to the remote scene
|
||||||
if (m_localAvatars.ContainsKey(clientID))
|
if (LocalAvatars.ContainsKey(clientID))
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("{0} Local client ({1}) being removed from remote scene.", LogHeader, clientID.ToString());
|
// If we are still connected, let the auth sim know that an agent has disconnected
|
||||||
m_localAvatars.Remove(clientID);
|
if (m_client.Connected)
|
||||||
// Let the auth sim know that an agent has disconnected
|
{
|
||||||
OSDMap data = new OSDMap(1);
|
m_log.WarnFormat("{0} Local client ({1}) has left the scene. Notifying remote scene.", LogHeader, clientID.ToString());
|
||||||
data["agentID"] = OSD.FromUUID(clientID);
|
OSDMap data = new OSDMap(1);
|
||||||
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.AgentRemove, OSDParser.SerializeJsonString(data)));
|
data["agentID"] = OSD.FromUUID(clientID);
|
||||||
|
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.AgentRemove, OSDParser.SerializeJsonString(data)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("{0} Local client ({1}) has left the scene.", LogHeader, clientID.ToString());
|
||||||
|
// Remove it from our list of local avatars (we will never receive a confirmation since we are disconnected)
|
||||||
|
Dictionary<UUID, IClientAPI> newlocals = new Dictionary<UUID, IClientAPI>(LocalAvatars);
|
||||||
|
newlocals.Remove(clientID);
|
||||||
|
m_localAvatars = newlocals;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -676,11 +745,25 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
|
|
||||||
public void HandleSetAppearanceRaw(object sender, UUID agentID, byte[] vp, Primitive.TextureEntry te)
|
public void HandleSetAppearanceRaw(object sender, UUID agentID, byte[] vp, Primitive.TextureEntry te)
|
||||||
{
|
{
|
||||||
|
// Try to find the scene presence we want to set the appearance for
|
||||||
|
ScenePresence sp;
|
||||||
|
string name = "NOT FOUND";
|
||||||
|
if (m_scene.TryGetScenePresence(agentID, out sp))
|
||||||
|
name = sp.Name;
|
||||||
|
m_log.WarnFormat("{0} Received LLClientView.SetAppearance ({1,3},{2,2}) for {3} (\"{4}\")", LogHeader, vp.Length.ToString(), (te == null) ? "" : "te", agentID.ToString(), sp.Name);
|
||||||
|
if (sp == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Set the appearance on the presence. This will generate the needed exchange with the client if rebakes need to take place.
|
||||||
|
m_log.WarnFormat("{0} Setting appearance on ScenePresence {1} \"{2}\"", LogHeader, sp.UUID, sp.Name);
|
||||||
|
sp.SetAppearance(te, vp);
|
||||||
|
|
||||||
if (te != null)
|
if (te != null)
|
||||||
{
|
{
|
||||||
OSDMap data = new OSDMap(2);
|
//m_log.WarnFormat("{0} Sending appearance to server for {1} \"{2}\"", LogHeader, sp.UUID, sp.Name);
|
||||||
data["id"] = OSDUUID.FromUUID(agentID);
|
OSDMap data = new OSDMap(3);
|
||||||
data["vp"] = new OSDBinary(vp);
|
data["id"] = OSDUUID.FromUUID(sp.UUID);
|
||||||
|
data["vp"] = new OSDBinary(sp.Appearance.VisualParams);
|
||||||
data["te"] = te.GetOSD();
|
data["te"] = te.GetOSD();
|
||||||
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.AvatarAppearance, OSDParser.SerializeJsonString(data)));
|
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.AvatarAppearance, OSDParser.SerializeJsonString(data)));
|
||||||
}
|
}
|
||||||
|
@ -714,19 +797,23 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/*
|
|
||||||
// Should be part of the RegionSyncClient
|
private void StatsTimerElapsed(object source, System.Timers.ElapsedEventArgs e)
|
||||||
public string ReceiveMsg()
|
|
||||||
{
|
{
|
||||||
lock (m_outQ)
|
// Let the auth sim know about this client's POV Re: Client counts
|
||||||
|
int t, l, r;
|
||||||
|
lock (m_syncRoot)
|
||||||
{
|
{
|
||||||
if (m_outQ.Count > 0)
|
t = m_scene.SceneGraph.GetRootAgentCount();
|
||||||
{
|
l = LocalAvatars.Count;
|
||||||
return m_outQ.Dequeue();
|
r = RemoteAvatars.Count;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
OSDMap data = new OSDMap(3);
|
||||||
|
data["total"] = OSD.FromInteger(t);
|
||||||
|
data["local"] = OSD.FromInteger(l);
|
||||||
|
data["remote"] = OSD.FromInteger(r);
|
||||||
|
//m_log.WarnFormat("{0}: Sent stats: {1},{2},{3}", LogHeader, t, l, r);
|
||||||
|
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.RegionStatus, OSDParser.SerializeJsonString(data)));
|
||||||
}
|
}
|
||||||
* */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ using log4net;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
|
||||||
namespace OpenSim.Region.Examples.RegionSyncModule
|
namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
{
|
{
|
||||||
public class RegionSyncClientModule : IRegionModule, IRegionSyncClientModule, ICommandableModule
|
public class RegionSyncClientModule : IRegionModule, IRegionSyncClientModule, ICommandableModule
|
||||||
{
|
{
|
||||||
|
@ -72,8 +72,8 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
{
|
{
|
||||||
if (!m_active)
|
if (!m_active)
|
||||||
return;
|
return;
|
||||||
|
// Go ahead and try to sync right away
|
||||||
//m_log.Warn("[REGION SYNC CLIENT MODULE] Post-Initialised");
|
Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
|
@ -159,8 +159,11 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
//cmdSyncStop.AddArgument("server_address", "The IP address of the server to synchronize with", "String");
|
//cmdSyncStop.AddArgument("server_address", "The IP address of the server to synchronize with", "String");
|
||||||
//cmdSyncStop.AddArgument("server_port", "The port of the server to synchronize with", "Integer");
|
//cmdSyncStop.AddArgument("server_port", "The port of the server to synchronize with", "Integer");
|
||||||
|
|
||||||
|
Command cmdSyncStatus = new Command("status", CommandIntentions.COMMAND_HAZARDOUS, SyncStatus, "Displays synchronization status.");
|
||||||
|
|
||||||
m_commander.RegisterCommand("start", cmdSyncStart);
|
m_commander.RegisterCommand("start", cmdSyncStart);
|
||||||
m_commander.RegisterCommand("stop", cmdSyncStop);
|
m_commander.RegisterCommand("stop", cmdSyncStop);
|
||||||
|
m_commander.RegisterCommand("status", cmdSyncStatus);
|
||||||
|
|
||||||
lock (m_scene)
|
lock (m_scene)
|
||||||
{
|
{
|
||||||
|
@ -195,6 +198,12 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
|
|
||||||
private void SyncStart(Object[] args)
|
private void SyncStart(Object[] args)
|
||||||
{
|
{
|
||||||
|
Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
|
||||||
lock (m_client_lock)
|
lock (m_client_lock)
|
||||||
{
|
{
|
||||||
if (m_client != null)
|
if (m_client != null)
|
||||||
|
@ -224,6 +233,20 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
m_log.Warn("[REGION SYNC CLIENT MODULE] Stopping synchronization");
|
m_log.Warn("[REGION SYNC CLIENT MODULE] Stopping synchronization");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SyncStatus(Object[] args)
|
||||||
|
{
|
||||||
|
lock (m_client_lock)
|
||||||
|
{
|
||||||
|
if (m_client == null)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[REGION SYNC CLIENT MODULE] Not currently synchronized");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_log.WarnFormat("[REGION SYNC CLIENT MODULE] Synchronized");
|
||||||
|
m_client.ReportStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,18 @@ using OpenSim.Region.Framework.Scenes.Serialization;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
|
||||||
namespace OpenSim.Region.Examples.RegionSyncModule
|
namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
{
|
{
|
||||||
|
#region MsgHandlerStatus Enum
|
||||||
|
public enum MsgHandlerStatus
|
||||||
|
{
|
||||||
|
Success, // Everything went as expected
|
||||||
|
Trivial, // Minor issue, nothing to worry about
|
||||||
|
Warning, // Something went wrong, we can continue
|
||||||
|
Error // This should certainly not have happened! (A bug)
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
// The RegionSyncClientView acts as a thread on the RegionSyncServer to handle incoming
|
// The RegionSyncClientView acts as a thread on the RegionSyncServer to handle incoming
|
||||||
// messages from RegionSyncClients.
|
// messages from RegionSyncClients.
|
||||||
public class RegionSyncClientView
|
public class RegionSyncClientView
|
||||||
|
@ -23,10 +33,19 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
#region RegionSyncClientView members
|
#region RegionSyncClientView members
|
||||||
|
|
||||||
object stats = new object();
|
object stats = new object();
|
||||||
|
private DateTime lastStatTime;
|
||||||
|
private long queuedUpdates;
|
||||||
|
private long dequeuedUpdates;
|
||||||
private long msgsIn;
|
private long msgsIn;
|
||||||
private long msgsOut;
|
private long msgsOut;
|
||||||
private long bytesIn;
|
private long bytesIn;
|
||||||
private long bytesOut;
|
private long bytesOut;
|
||||||
|
private long pollBlocks;
|
||||||
|
private int lastTotalCount;
|
||||||
|
private int lastLocalCount;
|
||||||
|
private int lastRemoteCount;
|
||||||
|
|
||||||
|
private int msgCount = 0;
|
||||||
|
|
||||||
// The TcpClient this view uses to communicate with its RegionSyncClient
|
// The TcpClient this view uses to communicate with its RegionSyncClient
|
||||||
private TcpClient m_tcpclient;
|
private TcpClient m_tcpclient;
|
||||||
|
@ -36,32 +55,66 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
private int m_connection_number;
|
private int m_connection_number;
|
||||||
private Scene m_scene;
|
private Scene m_scene;
|
||||||
|
|
||||||
|
object m_syncRoot = new object();
|
||||||
Dictionary<UUID, RegionSyncAvatar> m_syncedAvatars = new Dictionary<UUID, RegionSyncAvatar>();
|
Dictionary<UUID, RegionSyncAvatar> m_syncedAvatars = new Dictionary<UUID, RegionSyncAvatar>();
|
||||||
|
|
||||||
// A queue for incoming and outgoing traffic
|
// A queue for incoming and outgoing traffic
|
||||||
private OpenMetaverse.BlockingQueue<RegionSyncMessage> inbox = new OpenMetaverse.BlockingQueue<RegionSyncMessage>();
|
//private OpenMetaverse.BlockingQueue<RegionSyncMessage> inbox = new OpenMetaverse.BlockingQueue<RegionSyncMessage>();
|
||||||
|
//private OpenMetaverse.BlockingQueue<RegionSyncMessage> outbox = new OpenMetaverse.BlockingQueue<RegionSyncMessage>();
|
||||||
|
|
||||||
|
private BlockingUpdateQueue m_outQ = new BlockingUpdateQueue();
|
||||||
|
|
||||||
private ILog m_log;
|
private ILog m_log;
|
||||||
|
|
||||||
private Thread m_receive_loop;
|
private Thread m_receive_loop;
|
||||||
private Thread m_handler;
|
private Thread m_send_loop;
|
||||||
|
private string m_regionName;
|
||||||
|
|
||||||
// A string of the format [REGION SYNC CLIENT VIEW #X] for use in log headers
|
// A string of the format [REGION SYNC CLIENT VIEW (regionname)] for use in log headers
|
||||||
private string LogHeader
|
private string LogHeader
|
||||||
{
|
{
|
||||||
get { return String.Format("[REGION SYNC CLIENT VIEW #{0}]", m_connection_number); }
|
get
|
||||||
|
{
|
||||||
|
if(m_regionName == null)
|
||||||
|
return String.Format("[REGION SYNC CLIENT VIEW #{0}]", m_connection_number);
|
||||||
|
return String.Format("[REGION SYNC CLIENT VIEW #{0} ({1:10})]", m_connection_number, m_regionName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A string of the format "RegionSyncClientView #X" for use in describing the object itself
|
// A string of the format "RegionSyncClientView #X" for use in describing the object itself
|
||||||
public string Description
|
public string Description
|
||||||
{
|
{
|
||||||
get { return String.Format("RegionSyncClientView #{0}", m_connection_number); }
|
get
|
||||||
|
{
|
||||||
|
if(m_regionName == null)
|
||||||
|
return String.Format("RegionSyncClientView #{0}", m_connection_number);
|
||||||
|
return String.Format("RegionSyncClientView #{0} ({1:10})", m_connection_number, m_regionName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetStats()
|
public string GetStats()
|
||||||
{
|
{
|
||||||
lock(stats)
|
int syncedAvCount;
|
||||||
return String.Format("{0},{1},{2},{3}", msgsIn, msgsOut, bytesIn, bytesOut);
|
string ret;
|
||||||
|
lock (m_syncRoot)
|
||||||
|
syncedAvCount = m_syncedAvatars.Count;
|
||||||
|
lock (stats)
|
||||||
|
{
|
||||||
|
double secondsSinceLastStats = DateTime.Now.Subtract(lastStatTime).TotalSeconds;
|
||||||
|
lastStatTime = DateTime.Now;
|
||||||
|
int totalAvCount = m_scene.SceneGraph.GetRootAgentCount();
|
||||||
|
ret = String.Format("[{0,4}/{1,4}], [{2,4}/{3,4}], [{4,4}/{5,4}], [{6,4} ({7,4})], [{8,8} ({9,8:00.00})], [{10,4} ({11,4})], [{12,8} ({13,8:00.00})], [{14,8},{15,8},{16,8}]",
|
||||||
|
lastTotalCount, totalAvCount, // TOTAL AVATARS
|
||||||
|
lastLocalCount, syncedAvCount, // LOCAL TO THIS CLIENT VIEW
|
||||||
|
lastRemoteCount, totalAvCount - syncedAvCount, // REMOTE (SHOULD = TOTAL - LOCAL)
|
||||||
|
msgsIn, (int)(msgsIn / secondsSinceLastStats),
|
||||||
|
bytesIn, 8 * (bytesIn / secondsSinceLastStats / 1000000), // IN
|
||||||
|
msgsOut, (int)(msgsOut / secondsSinceLastStats),
|
||||||
|
bytesOut, 8 * (bytesOut / secondsSinceLastStats / 1000000), // OUT
|
||||||
|
m_outQ.Count, (int)(queuedUpdates / secondsSinceLastStats), (int)(dequeuedUpdates/secondsSinceLastStats)); // QUEUE ACTIVITY
|
||||||
|
msgsIn = msgsOut = bytesIn = bytesOut = pollBlocks = queuedUpdates = dequeuedUpdates = 0;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the client is connected
|
// Check if the client is connected
|
||||||
|
@ -69,6 +122,7 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
{ get { return m_tcpclient.Connected; } }
|
{ get { return m_tcpclient.Connected; } }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
public RegionSyncClientView(int num, Scene scene, TcpClient client)
|
public RegionSyncClientView(int num, Scene scene, TcpClient client)
|
||||||
{
|
{
|
||||||
|
@ -83,21 +137,23 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
|
|
||||||
// Create a thread for the receive loop
|
// Create a thread for the receive loop
|
||||||
m_receive_loop = new Thread(new ThreadStart(delegate() { ReceiveLoop(); }));
|
m_receive_loop = new Thread(new ThreadStart(delegate() { ReceiveLoop(); }));
|
||||||
m_receive_loop.Name = Description;
|
m_receive_loop.Name = Description + " (ReceiveLoop)";
|
||||||
//m_log.WarnFormat("{0} Started thread: {1}", LogHeader, m_receive_loop.Name);
|
//m_log.WarnFormat("{0} Started thread: {1}", LogHeader, m_receive_loop.Name);
|
||||||
m_receive_loop.Start();
|
m_receive_loop.Start();
|
||||||
|
|
||||||
|
m_send_loop = new Thread(new ThreadStart(delegate() { SendLoop(); }));
|
||||||
|
m_send_loop.Name = Description + " (SendLoop)";
|
||||||
|
m_send_loop.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop the RegionSyncClientView, disconnecting the RegionSyncClient
|
// Stop the RegionSyncClientView, disconnecting the RegionSyncClient
|
||||||
public void Shutdown()
|
public void Shutdown()
|
||||||
{
|
{
|
||||||
m_scene.EventManager.OnChatFromClient -= EventManager_OnChatFromClient;
|
m_scene.EventManager.OnChatFromClient -= EventManager_OnChatFromClient;
|
||||||
// Abort ReceiveLoop Thread, close Socket and TcpClient
|
|
||||||
m_receive_loop.Abort();
|
|
||||||
m_tcpclient.Client.Close();
|
m_tcpclient.Client.Close();
|
||||||
m_tcpclient.Close();
|
m_tcpclient.Close();
|
||||||
//Logout any synced avatars
|
//Logout any synced avatars
|
||||||
lock (m_syncedAvatars)
|
lock (m_syncRoot)
|
||||||
{
|
{
|
||||||
foreach (UUID agentID in m_syncedAvatars.Keys)
|
foreach (UUID agentID in m_syncedAvatars.Keys)
|
||||||
{
|
{
|
||||||
|
@ -117,10 +173,15 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen for messages from a RegionSyncClient
|
// Listen for messages from a RegionSyncClient
|
||||||
// *** This is the main thread loop for each connected client
|
// *** This is the main receive loop thread for each connected client
|
||||||
private void ReceiveLoop()
|
private void ReceiveLoop()
|
||||||
{
|
{
|
||||||
m_scene.EventManager.OnChatFromClient += new EventManager.ChatFromClientEvent(EventManager_OnChatFromClient);
|
m_scene.EventManager.OnChatFromClient += new EventManager.ChatFromClientEvent(EventManager_OnChatFromClient);
|
||||||
|
|
||||||
|
// Reset stats and time
|
||||||
|
lastStatTime = DateTime.Now;
|
||||||
|
msgsIn = msgsOut = bytesIn = bytesOut = 0;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
|
@ -131,16 +192,49 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
msgsIn++;
|
msgsIn++;
|
||||||
bytesIn += msg.Length;
|
bytesIn += msg.Length;
|
||||||
}
|
}
|
||||||
HandleMessage(msg);
|
lock (m_syncRoot)
|
||||||
|
HandleMessage(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("{0} RegionSyncClient has disconnected: {1}", LogHeader, e.Message);
|
m_log.ErrorFormat("{0} RegionSyncClient has disconnected: {1} (ReceiveLoop)", LogHeader, e.Message);
|
||||||
|
}
|
||||||
|
Shutdown();
|
||||||
|
// Thread exits here
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send messages from the update Q as fast as we can DeQueue them
|
||||||
|
// *** This is the main send loop thread for each connected client
|
||||||
|
private void SendLoop()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
// Dequeue is thread safe
|
||||||
|
byte[] update = m_outQ.Dequeue();
|
||||||
|
lock (stats)
|
||||||
|
dequeuedUpdates++;
|
||||||
|
Send(update);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("{0} RegionSyncClient has disconnected: {1} (SendLoop)", LogHeader, e.Message);
|
||||||
}
|
}
|
||||||
Shutdown();
|
Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void EnqueuePresenceUpdate(UUID id, byte[] update)
|
||||||
|
{
|
||||||
|
lock (stats)
|
||||||
|
queuedUpdates++;
|
||||||
|
// Enqueue is thread safe
|
||||||
|
m_outQ.Enqueue(id, update);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void EventManager_OnChatFromClient(object sender, OSChatMessage chat)
|
void EventManager_OnChatFromClient(object sender, OSChatMessage chat)
|
||||||
{
|
{
|
||||||
OSDMap data = new OSDMap(5);
|
OSDMap data = new OSDMap(5);
|
||||||
|
@ -167,32 +261,42 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
OSDMap data = null;
|
OSDMap data = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
data = OSDParser.DeserializeJson(Encoding.ASCII.GetString(msg.Data)) as OSDMap;
|
data = OSDParser.DeserializeJson(Encoding.ASCII.GetString(msg.Data, 0, msg.Length)) as OSDMap;
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
lock(exceptions)
|
lock(exceptions)
|
||||||
// If this is a new message, then print the underlying data that caused it
|
// If this is a new message, then print the underlying data that caused it
|
||||||
if(!exceptions.Contains(e.Message))
|
if(!exceptions.Contains(e.Message))
|
||||||
m_log.Error(LogHeader + " " + Encoding.ASCII.GetString(msg.Data));
|
m_log.Error(LogHeader + " " + Encoding.ASCII.GetString(msg.Data, 0, msg.Length));
|
||||||
data = null;
|
data = null;
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Dictionary<UUID, System.Threading.Timer> m_appearanceTimers = new Dictionary<UUID, Timer>();
|
||||||
|
|
||||||
// Handle an incoming message
|
// Handle an incoming message
|
||||||
// *** Perhaps this should not be synchronous with the receive
|
// *** Perhaps this should not be synchronous with the receive
|
||||||
// We could handle messages from an incoming Queue
|
// We could handle messages from an incoming Queue
|
||||||
private bool HandleMessage(RegionSyncMessage msg)
|
private void HandleMessage(RegionSyncMessage msg)
|
||||||
{
|
{
|
||||||
|
msgCount++;
|
||||||
//string handlerMessage = "";
|
//string handlerMessage = "";
|
||||||
switch (msg.Type)
|
switch (msg.Type)
|
||||||
{
|
{
|
||||||
|
case RegionSyncMessage.MsgType.RegionName:
|
||||||
|
{
|
||||||
|
m_regionName = Encoding.ASCII.GetString(msg.Data, 0, msg.Length);
|
||||||
|
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.RegionName, m_scene.RegionInfo.RegionName));
|
||||||
|
RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Syncing to region \"{0}\"", m_regionName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
case RegionSyncMessage.MsgType.GetTerrain:
|
case RegionSyncMessage.MsgType.GetTerrain:
|
||||||
{
|
{
|
||||||
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.Terrain, m_scene.Heightmap.SaveToXmlString()));
|
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.Terrain, m_scene.Heightmap.SaveToXmlString()));
|
||||||
return HandlerSuccess(msg, "Terrain sent");
|
RegionSyncMessage.HandleSuccess(LogHeader, msg, "Terrain sent");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
case RegionSyncMessage.MsgType.GetObjects:
|
case RegionSyncMessage.MsgType.GetObjects:
|
||||||
{
|
{
|
||||||
|
@ -205,7 +309,8 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.NewObject, sogxml));
|
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.NewObject, sogxml));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return HandlerSuccess(msg, "Sent all scene objects");
|
RegionSyncMessage.HandleSuccess(LogHeader, msg, "Sent all scene objects");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
case RegionSyncMessage.MsgType.GetAvatars:
|
case RegionSyncMessage.MsgType.GetAvatars:
|
||||||
{
|
{
|
||||||
|
@ -219,7 +324,8 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
data["startPos"] = OSD.FromVector3(presence.ControllingClient.StartPos);
|
data["startPos"] = OSD.FromVector3(presence.ControllingClient.StartPos);
|
||||||
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.NewAvatar, OSDParser.SerializeJsonString(data)));
|
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.NewAvatar, OSDParser.SerializeJsonString(data)));
|
||||||
});
|
});
|
||||||
return HandlerSuccess(msg, "Sent all scene avatars");
|
RegionSyncMessage.HandleSuccess(LogHeader, msg, "Sent all scene avatars");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
case RegionSyncMessage.MsgType.AgentAdd:
|
case RegionSyncMessage.MsgType.AgentAdd:
|
||||||
{
|
{
|
||||||
|
@ -234,19 +340,22 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
if (agentID != null && first != null && last != null && startPos != null)
|
if (agentID != null && first != null && last != null && startPos != null)
|
||||||
{
|
{
|
||||||
RegionSyncAvatar av = new RegionSyncAvatar(m_scene, agentID, first, last, startPos);
|
RegionSyncAvatar av = new RegionSyncAvatar(m_scene, agentID, first, last, startPos);
|
||||||
lock (m_syncedAvatars)
|
lock (m_syncRoot)
|
||||||
{
|
{
|
||||||
if (m_syncedAvatars.ContainsKey(agentID))
|
if (m_syncedAvatars.ContainsKey(agentID))
|
||||||
{
|
{
|
||||||
return HandlerFailure(msg, String.Format( "Attempted to add duplicate avatar with agentID {0}", agentID));
|
RegionSyncMessage.HandleWarning(LogHeader, msg, String.Format("Attempted to add duplicate avatar with agentID {0}", agentID));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
m_syncedAvatars.Add(agentID, av);
|
m_syncedAvatars.Add(agentID, av);
|
||||||
}
|
}
|
||||||
m_scene.AddNewClient(av);
|
m_scene.AddNewClient(av);
|
||||||
return HandlerSuccess(msg, String.Format("Handled AddAgent for UUID {0}", agentID));
|
RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Handled AddAgent for UUID {0}", agentID));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return HandlerFailure(msg, "Could not deserialize JSON data.");
|
RegionSyncMessage.HandleError(LogHeader, msg, "Could not deserialize JSON data.");
|
||||||
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
case RegionSyncMessage.MsgType.AgentUpdate:
|
case RegionSyncMessage.MsgType.AgentUpdate:
|
||||||
|
@ -259,12 +368,15 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
|
|
||||||
RegionSyncAvatar av;
|
RegionSyncAvatar av;
|
||||||
bool found;
|
bool found;
|
||||||
lock (m_syncedAvatars)
|
lock (m_syncRoot)
|
||||||
{
|
{
|
||||||
found = m_syncedAvatars.TryGetValue(agentData.AgentID, out av);
|
found = m_syncedAvatars.TryGetValue(agentData.AgentID, out av);
|
||||||
}
|
}
|
||||||
if(!found)
|
if(!found)
|
||||||
return HandlerFailure(msg, String.Format("Received agent update for non-existent avatar with UUID {0}", agentData.AgentID));
|
{
|
||||||
|
RegionSyncMessage.HandleWarning(LogHeader, msg, String.Format("Received agent update for non-existent avatar with UUID {0}", agentData.AgentID));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
AgentUpdateArgs arg = new AgentUpdateArgs();
|
AgentUpdateArgs arg = new AgentUpdateArgs();
|
||||||
arg.AgentID = agentData.AgentID;
|
arg.AgentID = agentData.AgentID;
|
||||||
|
@ -281,9 +393,15 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
arg.State = agentData.State;
|
arg.State = agentData.State;
|
||||||
|
|
||||||
if( av.AgentUpdate(arg) )
|
if( av.AgentUpdate(arg) )
|
||||||
return HandlerSuccess(msg, String.Format("Handled AgentUpdate for UUID {0}", agentID));
|
{
|
||||||
|
//RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Handled AgentUpdate for UUID {0}", agentID));
|
||||||
|
return;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return HandlerFailure(msg, String.Format("Could not handle AgentUpdate UUID {0}", agentID));
|
{
|
||||||
|
RegionSyncMessage.HandleWarning(LogHeader, msg, String.Format("Could not handle AgentUpdate UUID {0}", agentID));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case RegionSyncMessage.MsgType.AgentRemove:
|
case RegionSyncMessage.MsgType.AgentRemove:
|
||||||
{
|
{
|
||||||
|
@ -291,17 +409,19 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
OSDMap data = DeserializeMessage(msg);
|
OSDMap data = DeserializeMessage(msg);
|
||||||
if (data == null)
|
if (data == null)
|
||||||
{
|
{
|
||||||
return HandlerFailure(msg, "Could not deserialize JSON data.");
|
RegionSyncMessage.HandleError(LogHeader, msg, "Could not deserialize JSON data.");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the parameters from data and error check
|
// Get the parameters from data and error check
|
||||||
UUID agentID = data["agentID"].AsUUID();
|
UUID agentID = data["agentID"].AsUUID();
|
||||||
if (agentID == null || agentID == UUID.Zero)
|
if (agentID == null || agentID == UUID.Zero)
|
||||||
{
|
{
|
||||||
return HandlerFailure(msg, "Missing or invalid JSON data.");
|
RegionSyncMessage.HandleError(LogHeader, msg, "Missing or invalid JSON data.");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (m_syncedAvatars)
|
lock (m_syncRoot)
|
||||||
{
|
{
|
||||||
if (m_syncedAvatars.ContainsKey(agentID))
|
if (m_syncedAvatars.ContainsKey(agentID))
|
||||||
{
|
{
|
||||||
|
@ -311,58 +431,99 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
if (m_scene.TryGetScenePresence(agentID, out presence))
|
if (m_scene.TryGetScenePresence(agentID, out presence))
|
||||||
{
|
{
|
||||||
string name = presence.Name;
|
string name = presence.Name;
|
||||||
|
m_scene.SceneGraph.DeleteSceneObject(UUID.Zero, true);
|
||||||
m_scene.RemoveClient(agentID);
|
m_scene.RemoveClient(agentID);
|
||||||
return HandlerSuccess(msg, String.Format("Agent \"{0}\" ({1}) was removed from scene.", name, agentID));
|
RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Agent \"{0}\" was removed from scene.", name));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return HandlerFailure(msg, String.Format("Agent {0} not found in the scene.", agentID));
|
RegionSyncMessage.HandleWarning(LogHeader, msg, String.Format("Agent {0} not found in the scene.", agentID));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return HandlerFailure(msg, String.Format("Agent {0} not in the list of synced avatars.", agentID));
|
RegionSyncMessage.HandleWarning(LogHeader, msg, String.Format("Agent {0} not in the list of synced avatars.", agentID));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case RegionSyncMessage.MsgType.AvatarAppearance:
|
case RegionSyncMessage.MsgType.AvatarAppearance:
|
||||||
{
|
{
|
||||||
|
int msgID = msgCount;
|
||||||
|
//m_log.WarnFormat("{0} START of AvatarAppearance handler <{1}>", LogHeader, msgID);
|
||||||
// Get the data from message and error check
|
// Get the data from message and error check
|
||||||
OSDMap data = DeserializeMessage(msg);
|
OSDMap data = DeserializeMessage(msg);
|
||||||
if (data == null)
|
if (data == null)
|
||||||
{
|
{
|
||||||
return HandlerFailure(msg, "Could not deserialize JSON data.");
|
RegionSyncMessage.HandleError(LogHeader, msg, "Could not deserialize JSON data.");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the parameters from data and error check
|
// Get the parameters from data and error check
|
||||||
UUID agentID = data["id"].AsUUID();
|
UUID agentID = data["id"].AsUUID();
|
||||||
if (agentID == null || agentID == UUID.Zero)
|
if (agentID == null || agentID == UUID.Zero)
|
||||||
{
|
{
|
||||||
return HandlerFailure(msg, "Missing or invalid JSON data.");
|
RegionSyncMessage.HandleError(LogHeader, msg, "Missing or invalid JSON data.");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the presence in the scene
|
|
||||||
ScenePresence presence;
|
ScenePresence presence;
|
||||||
if (m_scene.TryGetScenePresence(agentID, out presence))
|
if (m_scene.TryGetScenePresence(agentID, out presence))
|
||||||
{
|
{
|
||||||
|
int delay = 5000;
|
||||||
string name = presence.Name;
|
string name = presence.Name;
|
||||||
Primitive.TextureEntry te = Primitive.TextureEntry.FromOSD(data["te"]);
|
//m_log.WarnFormat("{0} Waiting {1}ms before setting appearance on presence {2} <{3}>", LogHeader, delay, name, msgID);
|
||||||
byte[] vp = data["vp"].AsBinary();
|
Timer appearanceSetter = new Timer(delegate(object obj)
|
||||||
|
{
|
||||||
|
//m_log.WarnFormat("{0} Ready to set appearance on presence {1} <{2}>", LogHeader, name, msgID);
|
||||||
|
Primitive.TextureEntry te = Primitive.TextureEntry.FromOSD(data["te"]);
|
||||||
|
byte[] vp = data["vp"].AsBinary();
|
||||||
|
|
||||||
byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
|
bool missingBakes = false;
|
||||||
for (int i = 0; i < BAKE_INDICES.Length; i++)
|
byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
|
||||||
{
|
for (int i = 0; i < BAKE_INDICES.Length; i++)
|
||||||
int j = BAKE_INDICES[i];
|
{
|
||||||
Primitive.TextureEntryFace face = te.FaceTextures[j];
|
int j = BAKE_INDICES[i];
|
||||||
if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
|
Primitive.TextureEntryFace face = te.FaceTextures[j];
|
||||||
if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
|
if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
|
||||||
HandlerDebug(msg, "Missing baked texture " + face.TextureID + " (" + j + ") for avatar " + name);
|
{
|
||||||
}
|
if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
|
||||||
|
{
|
||||||
|
RegionSyncMessage.HandlerDebug(LogHeader, msg, "Missing baked texture " + face.TextureID + " (" + j + ") for avatar " + name);
|
||||||
|
missingBakes = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
presence.SetAppearance(te, vp);
|
//m_log.WarnFormat("{0} {1} Calling presence.SetAppearance {2} <{3}>", LogHeader, name, (missingBakes ? "MISSING BAKES" : "GOT BAKES"), msgID);
|
||||||
return HandlerDebug(msg, String.Format("Agent \"{0}\" ({1}) updated their appearance.", name, agentID));
|
try
|
||||||
|
{
|
||||||
|
presence.SetAppearance(te, vp);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("{0} Caught exception setting appearance for {1} (probably was removed from scene): {2}", LogHeader, name, e.Message);
|
||||||
|
}
|
||||||
|
if (!missingBakes)
|
||||||
|
RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Set appearance for {0} <{1}>", name, msgID));
|
||||||
|
else
|
||||||
|
RegionSyncMessage.HandleWarning(LogHeader, msg, String.Format("Set appearance for {0} but has missing bakes. <{1}>", name, msgID));
|
||||||
|
//m_log.WarnFormat("{0} Calling RegionsSyncServerModule.SendAppearance for {1} {2} <{3}>", LogHeader, name, (missingBakes ? "MISSING BAKES" : "GOT BAKES"), msgID);
|
||||||
|
m_scene.RegionSyncServerModule.SendAppearance(presence.UUID, presence.Appearance.VisualParams, presence.Appearance.Texture);
|
||||||
|
lock (m_appearanceTimers)
|
||||||
|
m_appearanceTimers.Remove(agentID);
|
||||||
|
}, null, delay, Timeout.Infinite);
|
||||||
|
lock (m_appearanceTimers)
|
||||||
|
m_appearanceTimers[agentID] = appearanceSetter;
|
||||||
}
|
}
|
||||||
return HandlerFailure(msg, String.Format("Agent {0} not found in the scene.", agentID));
|
else
|
||||||
|
{
|
||||||
|
RegionSyncMessage.HandleWarning(LogHeader, msg, String.Format("Presence not found in the scene: {0} <{1}>", agentID, msgID));
|
||||||
|
}
|
||||||
|
//m_log.WarnFormat("{0} END of AvatarAppearance handler <{1}>", LogHeader, msgID);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
case RegionSyncMessage.MsgType.ChatFromClient:
|
case RegionSyncMessage.MsgType.ChatFromClient:
|
||||||
{
|
{
|
||||||
|
@ -370,7 +531,8 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
OSDMap data = DeserializeMessage(msg);
|
OSDMap data = DeserializeMessage(msg);
|
||||||
if (data == null)
|
if (data == null)
|
||||||
{
|
{
|
||||||
return HandlerFailure(msg, "Could not deserialize JSON data.");
|
RegionSyncMessage.HandleError(LogHeader, msg, "Could not deserialize JSON data.");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
OSChatMessage args = new OSChatMessage();
|
OSChatMessage args = new OSChatMessage();
|
||||||
args.Channel = data["channel"].AsInteger();
|
args.Channel = data["channel"].AsInteger();
|
||||||
|
@ -388,12 +550,31 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
args.SenderUUID = id;
|
args.SenderUUID = id;
|
||||||
m_scene.EventManager.TriggerOnChatFromClient(sp.ControllingClient,args);
|
m_scene.EventManager.TriggerOnChatFromClient(sp.ControllingClient,args);
|
||||||
}
|
}
|
||||||
return HandlerSuccess(msg, String.Format("Received chat from \"{0}\"", args.From));
|
RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Received chat from \"{0}\"", args.From));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case RegionSyncMessage.MsgType.RegionStatus:
|
||||||
|
{
|
||||||
|
// Get the data from message and error check
|
||||||
|
OSDMap data = DeserializeMessage(msg);
|
||||||
|
if (data == null)
|
||||||
|
{
|
||||||
|
RegionSyncMessage.HandleError(LogHeader, msg, "Could not deserialize JSON data.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int t = data["total"].AsInteger();
|
||||||
|
int l = data["local"].AsInteger();
|
||||||
|
int r = data["remote"].AsInteger();
|
||||||
|
lastTotalCount = t;
|
||||||
|
lastLocalCount = l;
|
||||||
|
lastRemoteCount = r;
|
||||||
|
//RegionSyncMessage.HandleSuccess(LogHeader, msg, String.Format("Received stats: {0},{1},{2}", t, l, r));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("{0} Unable to handle unsupported message type", LogHeader);
|
m_log.WarnFormat("{0} Unable to handle unsupported message type", LogHeader);
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -406,7 +587,7 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
|
|
||||||
private bool HandlerSuccess(RegionSyncMessage msg, string handlerMessage)
|
private bool HandlerSuccess(RegionSyncMessage msg, string handlerMessage)
|
||||||
{
|
{
|
||||||
//m_log.WarnFormat("{0} Handled {1}: {2}", LogHeader, msg.ToString(), handlerMessage);
|
m_log.WarnFormat("{0} Handled {1}: {2}", LogHeader, msg.ToString(), handlerMessage);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,8 +599,9 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
|
|
||||||
public void Send(RegionSyncMessage msg)
|
public void Send(RegionSyncMessage msg)
|
||||||
{
|
{
|
||||||
|
//if (msg.Type == RegionSyncMessage.MsgType.AvatarAppearance)
|
||||||
|
//m_log.WarnFormat("{0} Sending AvatarAppearance to client manager", LogHeader);
|
||||||
Send(msg.ToBytes());
|
Send(msg.ToBytes());
|
||||||
//m_log.WarnFormat("{0} Sent {1}", LogHeader, msg.ToString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Send(byte[] data)
|
private void Send(byte[] data)
|
||||||
|
@ -433,31 +615,46 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
msgsOut++;
|
msgsOut++;
|
||||||
bytesOut += data.Length;
|
bytesOut += data.Length;
|
||||||
}
|
}
|
||||||
m_tcpclient.GetStream().Write(data, 0, data.Length);
|
m_tcpclient.GetStream().BeginWrite(data, 0, data.Length, ar =>
|
||||||
|
{
|
||||||
|
if(m_tcpclient.Connected)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_tcpclient.GetStream().EndWrite(ar);
|
||||||
|
}
|
||||||
|
catch(Exception)
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
}, null);
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException)
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("{0} RegionSyncClient has disconnected.", LogHeader);
|
m_log.WarnFormat("{0} RegionSyncClient has disconnected.", LogHeader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region crud
|
public void ReportStatus()
|
||||||
// Should be part of the RegionSyncClient
|
|
||||||
/*
|
|
||||||
public string ReceiveMsg()
|
|
||||||
{
|
{
|
||||||
lock (m_outQ)
|
int syncedAvCount;
|
||||||
|
lock (m_syncRoot)
|
||||||
|
syncedAvCount = m_syncedAvatars.Count;
|
||||||
|
lock (stats)
|
||||||
{
|
{
|
||||||
if (m_outQ.Count > 0)
|
bool localcheck = true;
|
||||||
{
|
bool remotecheck = true;
|
||||||
return m_outQ.Dequeue();
|
bool totalcheck = true;
|
||||||
}
|
if (syncedAvCount != lastLocalCount)
|
||||||
|
localcheck = false;
|
||||||
|
if (m_scene.SceneGraph.GetRootAgentCount() != lastTotalCount)
|
||||||
|
totalcheck = false;
|
||||||
|
if (m_scene.SceneGraph.GetRootAgentCount() - syncedAvCount != lastRemoteCount)
|
||||||
|
remotecheck = false;
|
||||||
|
m_log.ErrorFormat("{0} Syncing {1,4} remote presences. Remote scene reporting {2,4} locals, {3,4} remotes, {4,4} total ({5},{6},{7})",
|
||||||
|
LogHeader, m_syncedAvatars.Count, lastLocalCount, lastRemoteCount, lastTotalCount, localcheck ? " " : "!", remotecheck ? " " : "!", totalcheck ? " " : "!");
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
* */
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ using System.IO;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
|
||||||
namespace OpenSim.Region.Examples.RegionSyncModule
|
namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A message for synchonization message between scenes
|
/// A message for synchonization message between scenes
|
||||||
|
@ -39,13 +39,16 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
ChatFromSim,
|
ChatFromSim,
|
||||||
// BIDIR
|
// BIDIR
|
||||||
EchoRequest,
|
EchoRequest,
|
||||||
EchoResponse
|
EchoResponse,
|
||||||
|
RegionName,
|
||||||
|
RegionStatus
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Member Data
|
#region Member Data
|
||||||
private MsgType m_type;
|
private MsgType m_type;
|
||||||
private byte[] m_data;
|
private byte[] m_data;
|
||||||
|
static ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
@ -58,7 +61,7 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
public RegionSyncMessage(MsgType type, string msg)
|
public RegionSyncMessage(MsgType type, string msg)
|
||||||
{
|
{
|
||||||
m_type = type;
|
m_type = type;
|
||||||
m_data = System.Text.Encoding.ASCII.GetBytes(msg + System.Environment.NewLine);
|
m_data = System.Text.Encoding.ASCII.GetBytes(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegionSyncMessage(MsgType type)
|
public RegionSyncMessage(MsgType type)
|
||||||
|
@ -131,5 +134,32 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
return String.Format("{0} ({1} bytes)", m_type.ToString(), m_data.Length.ToString());
|
return String.Format("{0} ({1} bytes)", m_type.ToString(), m_data.Length.ToString());
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
public static void HandleSuccess(string header, RegionSyncMessage msg, string message)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("{0} Handled {1}: {2}", header, msg.ToString(), message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void HandleTrivial(string header, RegionSyncMessage msg, string message)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("{0} Issue handling {1}: {2}", header, msg.ToString(), message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void HandleWarning(string header, RegionSyncMessage msg, string message)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("{0} Warning handling {1}: {2}", header, msg.ToString(), message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void HandleError(string header, RegionSyncMessage msg, string message)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("{0} Error handling {1}: {2}", header, msg.ToString(), message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool HandlerDebug(string header, RegionSyncMessage msg, string message)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("{0} DBG ({1}): {2}", header, msg.ToString(), message);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,10 @@ using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenMetaverse;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
|
||||||
namespace OpenSim.Region.Examples.RegionSyncModule
|
namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
{
|
{
|
||||||
// The RegionSyncServer has a listener thread which accepts connections from RegionSyncClients
|
// The RegionSyncServer has a listener thread which accepts connections from RegionSyncClients
|
||||||
// and an additional thread to process updates to/from each RegionSyncClient.
|
// and an additional thread to process updates to/from each RegionSyncClient.
|
||||||
|
@ -24,13 +25,6 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
|
|
||||||
// The local scene.
|
// The local scene.
|
||||||
private Scene m_scene;
|
private Scene m_scene;
|
||||||
|
|
||||||
// A queue for incoming and outgoing traffic
|
|
||||||
// Incoming stuff can be from any client
|
|
||||||
// Outgoing stuff will be multicast to all clients
|
|
||||||
private Queue<string> m_inQ = new Queue<string>();
|
|
||||||
private Queue<string> m_outQ = new Queue<string>();
|
|
||||||
|
|
||||||
private ILog m_log;
|
private ILog m_log;
|
||||||
|
|
||||||
// The listener and the thread which listens for connections from client managers
|
// The listener and the thread which listens for connections from client managers
|
||||||
|
@ -81,17 +75,34 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReportStats()
|
public void ReportStats(System.IO.TextWriter tw)
|
||||||
{
|
{
|
||||||
// We should be able to safely iterate over our reference to the list since
|
// We should be able to safely iterate over our reference to the list since
|
||||||
// the only places which change it will replace it with an updated version
|
// the only places which change it will replace it with an updated version
|
||||||
m_log.Error("SERVER, MSGIN, MSGOUT, BYTESIN, BYTESOUT");
|
HashSet<RegionSyncClientView> cvs = m_client_views;
|
||||||
foreach (RegionSyncClientView rscv in m_client_views)
|
tw.WriteLine("{0}: [REGION SYNC SERVER] TOTAL LOCAL REMOTE TO_SCENE FROM_SCENE", DateTime.Now.ToLongTimeString());
|
||||||
|
tw.WriteLine("{0}: [REGION SYNC SERVER] MSGS ( /s ) BYTES ( Mbps ) MSGS ( /s ) BYTES ( Mbps ) QUEUE", DateTime.Now.ToLongTimeString());
|
||||||
|
foreach (RegionSyncClientView cv in cvs)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("{0}: {1}", rscv.Description, rscv.GetStats());
|
tw.WriteLine("{0}: [{1}] {2}", DateTime.Now.ToLongTimeString(), cv.Description, cv.GetStats());
|
||||||
|
}
|
||||||
|
tw.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReportStatus()
|
||||||
|
{
|
||||||
|
lock (m_clientview_lock)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("[REGION SYNC SERVER] Connected to {0} remote client managers", m_client_views.Count);
|
||||||
|
m_log.ErrorFormat("[REGION SYNC SERVER] Local scene contains {0} presences", m_scene.SceneGraph.GetRootAgentCount());
|
||||||
|
foreach (RegionSyncClientView rscv in m_client_views)
|
||||||
|
{
|
||||||
|
rscv.ReportStatus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
|
@ -114,6 +125,8 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
//m_log.Warn("[REGION SYNC SERVER] Started");
|
//m_log.Warn("[REGION SYNC SERVER] Started");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Stop the server and disconnect all RegionSyncClients
|
// Stop the server and disconnect all RegionSyncClients
|
||||||
public void Shutdown()
|
public void Shutdown()
|
||||||
{
|
{
|
||||||
|
@ -190,5 +203,32 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
//m_client_views.Remove(rscv);
|
//m_client_views.Remove(rscv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Broadcast a message to all connected RegionSyncClients
|
||||||
|
public void EnqueuePresenceUpdate(UUID id, byte[] update)
|
||||||
|
{
|
||||||
|
List<RegionSyncClientView> closed = null;
|
||||||
|
foreach (RegionSyncClientView client in m_client_views)
|
||||||
|
{
|
||||||
|
// If connected, send the message.
|
||||||
|
if (client.Connected)
|
||||||
|
{
|
||||||
|
client.EnqueuePresenceUpdate(id, update);
|
||||||
|
}
|
||||||
|
// Else, remove the client view from the list
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (closed == null)
|
||||||
|
closed = new List<RegionSyncClientView>();
|
||||||
|
closed.Add(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (closed != null)
|
||||||
|
{
|
||||||
|
foreach (RegionSyncClientView rscv in closed)
|
||||||
|
RemoveSyncedClient(rscv);
|
||||||
|
//m_client_views.Remove(rscv);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,11 +38,12 @@ using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
using OpenSim.Region.Framework.Scenes.Serialization;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace OpenSim.Region.Examples.RegionSyncModule
|
namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
{
|
{
|
||||||
public class RegionSyncServerModule : IRegionModule, IRegionSyncServerModule, ICommandableModule
|
public class RegionSyncServerModule : IRegionModule, IRegionSyncServerModule, ICommandableModule
|
||||||
{
|
{
|
||||||
|
@ -93,9 +94,20 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
// Start the server and listen for RegionSyncClients
|
// Start the server and listen for RegionSyncClients
|
||||||
m_server = new RegionSyncServer(m_scene, m_serveraddr, m_serverport);
|
m_server = new RegionSyncServer(m_scene, m_serveraddr, m_serverport);
|
||||||
m_server.Start();
|
m_server.Start();
|
||||||
|
m_statsTimer.Elapsed += new System.Timers.ElapsedEventHandler(StatsTimerElapsed);
|
||||||
|
m_statsTimer.Start();
|
||||||
//m_log.Warn("[REGION SYNC SERVER MODULE] Post-Initialised");
|
//m_log.Warn("[REGION SYNC SERVER MODULE] Post-Initialised");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void StatsTimerElapsed(object source, System.Timers.ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
if (Synced)
|
||||||
|
{
|
||||||
|
TextWriter tw = File.AppendText("syncstats.txt");
|
||||||
|
m_server.ReportStats(tw);
|
||||||
|
tw.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void IRegionModule.Close()
|
void IRegionModule.Close()
|
||||||
{
|
{
|
||||||
|
@ -128,6 +140,8 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
private Dictionary<UUID, SceneObjectGroup> m_primUpdates = new Dictionary<UUID, SceneObjectGroup>();
|
private Dictionary<UUID, SceneObjectGroup> m_primUpdates = new Dictionary<UUID, SceneObjectGroup>();
|
||||||
private Dictionary<UUID, ScenePresence> m_presenceUpdates = new Dictionary<UUID, ScenePresence>();
|
private Dictionary<UUID, ScenePresence> m_presenceUpdates = new Dictionary<UUID, ScenePresence>();
|
||||||
|
|
||||||
|
private System.Timers.Timer m_statsTimer = new System.Timers.Timer(1000);
|
||||||
|
|
||||||
public void QueuePartForUpdate(SceneObjectPart part)
|
public void QueuePartForUpdate(SceneObjectPart part)
|
||||||
{
|
{
|
||||||
if (!Active || !Synced)
|
if (!Active || !Synced)
|
||||||
|
@ -189,24 +203,32 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
}
|
}
|
||||||
foreach (ScenePresence presence in presenceUpdates)
|
foreach (ScenePresence presence in presenceUpdates)
|
||||||
{
|
{
|
||||||
if (!presence.IsDeleted)
|
try
|
||||||
{
|
{
|
||||||
OSDMap data = new OSDMap(6);
|
if (!presence.IsDeleted)
|
||||||
data["id"] = OSD.FromUUID(presence.UUID);
|
{
|
||||||
// Do not include offset for appearance height. That will be handled by RegionSyncClient before sending to viewers
|
OSDMap data = new OSDMap(7);
|
||||||
if(presence.AbsolutePosition.IsFinite())
|
data["id"] = OSD.FromUUID(presence.UUID);
|
||||||
data["pos"] = OSD.FromVector3(presence.AbsolutePosition);
|
// Do not include offset for appearance height. That will be handled by RegionSyncClient before sending to viewers
|
||||||
else
|
if (presence.AbsolutePosition.IsFinite())
|
||||||
data["pos"] = OSD.FromVector3(Vector3.Zero);
|
data["pos"] = OSD.FromVector3(presence.AbsolutePosition);
|
||||||
if(presence.Velocity.IsFinite())
|
else
|
||||||
data["vel"] = OSD.FromVector3(presence.Velocity);
|
data["pos"] = OSD.FromVector3(Vector3.Zero);
|
||||||
else
|
if (presence.Velocity.IsFinite())
|
||||||
data["vel"] = OSD.FromVector3(Vector3.Zero);
|
data["vel"] = OSD.FromVector3(presence.Velocity);
|
||||||
data["rot"] = OSD.FromQuaternion(presence.Rotation);
|
else
|
||||||
data["fly"] = OSD.FromBoolean(presence.Flying);
|
data["vel"] = OSD.FromVector3(Vector3.Zero);
|
||||||
data["flags"] = OSD.FromUInteger((uint)presence.AgentControlFlags);
|
data["rot"] = OSD.FromQuaternion(presence.Rotation);
|
||||||
RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.UpdatedAvatar, OSDParser.SerializeJsonString(data));
|
data["fly"] = OSD.FromBoolean(presence.Flying);
|
||||||
m_server.Broadcast(rsm);
|
data["flags"] = OSD.FromUInteger((uint)presence.AgentControlFlags);
|
||||||
|
data["anim"] = OSD.FromString(presence.Animator.CurrentMovementAnimation);
|
||||||
|
RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.UpdatedAvatar, OSDParser.SerializeJsonString(data));
|
||||||
|
m_server.EnqueuePresenceUpdate(presence.UUID, rsm.ToBytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("[REGION SYNC SERVER MODULE] Caught exception sending presence updates for {0}", presence.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Indicate that the current batch of updates has been completed
|
// Indicate that the current batch of updates has been completed
|
||||||
|
@ -214,16 +236,35 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Dictionary<UUID, System.Threading.Timer> m_appearanceTimers = new Dictionary<UUID, Timer>();
|
||||||
|
|
||||||
public void SendAppearance(UUID agentID, byte[] vp, Primitive.TextureEntry te)
|
public void SendAppearance(UUID agentID, byte[] vp, Primitive.TextureEntry te)
|
||||||
{
|
{
|
||||||
if (te != null)
|
ScenePresence sp;
|
||||||
|
if (!m_scene.TryGetScenePresence(agentID, out sp))
|
||||||
{
|
{
|
||||||
OSDMap data = new OSDMap(2);
|
m_log.WarnFormat("[REGION SYNC SERVER MODULE] <{0}> {1} SendAppearance could not locate presence!", " ", agentID);
|
||||||
data["id"] = OSDUUID.FromUUID(agentID);
|
return;
|
||||||
data["vp"] = new OSDBinary(vp);
|
|
||||||
data["te"] = te.GetOSD();
|
|
||||||
m_server.Broadcast(new RegionSyncMessage(RegionSyncMessage.MsgType.AvatarAppearance, OSDParser.SerializeJsonString(data)));
|
|
||||||
}
|
}
|
||||||
|
//m_log.WarnFormat("[REGION SYNC SERVER MODULE] <{0}> {1} ScenePresence called SendAppearance ({2})", sp.Name, agentID, te == null ? " " : "te");
|
||||||
|
if(te == null)
|
||||||
|
return;
|
||||||
|
int delay = 1000;
|
||||||
|
//m_log.WarnFormat("[REGION SYNC SERVER MODULE] <{0}> {1} Waiting {2}ms before sending appearance to all client managers", sp.Name, agentID, delay);
|
||||||
|
OSDMap data = new OSDMap(3);
|
||||||
|
data["id"] = OSDUUID.FromUUID(agentID);
|
||||||
|
data["vp"] = new OSDBinary(vp);
|
||||||
|
data["te"] = te.GetOSD();
|
||||||
|
Timer appearanceSetter = new Timer(delegate(object obj)
|
||||||
|
{
|
||||||
|
//m_log.WarnFormat("[REGION SYNC SERVER MODULE] <{0}> {1} Broadcasting appearance to all client managers", sp.Name, agentID);
|
||||||
|
m_server.Broadcast(new RegionSyncMessage(RegionSyncMessage.MsgType.AvatarAppearance, OSDParser.SerializeJsonString(data)));
|
||||||
|
lock (m_appearanceTimers)
|
||||||
|
m_appearanceTimers.Remove(agentID);
|
||||||
|
}, null, delay, Timeout.Infinite);
|
||||||
|
// Just keeps a reference to this timer
|
||||||
|
lock (m_appearanceTimers)
|
||||||
|
m_appearanceTimers[agentID] = appearanceSetter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteObject(ulong regionHandle, uint localID)
|
public void DeleteObject(ulong regionHandle, uint localID)
|
||||||
|
@ -443,7 +484,7 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
|
|
||||||
void EventManager_OnAvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID)
|
void EventManager_OnAvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID)
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("[REGION SYNC SERVER MODULE] (OnAvatarEnteringNewParcel) Avatar \"{0}\" has joined the scene (1) {2} {3} {4}", avatar.Name, avatar.ControllingClient.AgentId.ToString(), avatar.UUID.ToString(), localLandID, regionID.ToString());
|
m_log.WarnFormat("[REGION SYNC SERVER MODULE] (OnAvatarEnteringNewParcel) Avatar \"{0}\" has joined the scene {1} {2} {3} {4}", avatar.Name, avatar.ControllingClient.AgentId.ToString(), avatar.UUID.ToString(), localLandID, regionID.ToString());
|
||||||
DebugSceneStats();
|
DebugSceneStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,7 +500,7 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
{
|
{
|
||||||
if (!Synced)
|
if (!Synced)
|
||||||
return;
|
return;
|
||||||
m_log.WarnFormat("[REGION SYNC SERVER MODULE] Agent \"{0}\" (1) has joined the scene", client.FirstName + " " + client.LastName, client.AgentId.ToString());
|
m_log.WarnFormat("[REGION SYNC SERVER MODULE] Agent \"{0}\" {1} has joined the scene", client.FirstName + " " + client.LastName, client.AgentId.ToString());
|
||||||
// Let the client managers know that a new agent has connected
|
// Let the client managers know that a new agent has connected
|
||||||
OSDMap data = new OSDMap(1);
|
OSDMap data = new OSDMap(1);
|
||||||
data["agentID"] = OSD.FromUUID(client.AgentId);
|
data["agentID"] = OSD.FromUUID(client.AgentId);
|
||||||
|
@ -477,7 +518,7 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
ScenePresence avatar;
|
ScenePresence avatar;
|
||||||
if (m_scene.TryGetScenePresence(agentID, out avatar))
|
if (m_scene.TryGetScenePresence(agentID, out avatar))
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("[REGION SYNC SERVER MODULE] Avatar \"{0}\" (1) {2} has left the scene", avatar.Firstname + " " + avatar.Lastname, agentID.ToString(), avatar.UUID.ToString());
|
m_log.WarnFormat("[REGION SYNC SERVER MODULE] Avatar \"{0}\" {1} {2} has left the scene", avatar.Firstname + " " + avatar.Lastname, agentID.ToString(), avatar.UUID.ToString());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -494,8 +535,8 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
#region Console Command Interface
|
#region Console Command Interface
|
||||||
private void InstallInterfaces()
|
private void InstallInterfaces()
|
||||||
{
|
{
|
||||||
Command cmdSyncStats = new Command("stats", CommandIntentions.COMMAND_HAZARDOUS, SyncStats, "Reports stats for the RegionSyncServer.");
|
Command cmdSyncStatus = new Command("status", CommandIntentions.COMMAND_HAZARDOUS, SyncStatus, "Reports current status of the RegionSyncServer.");
|
||||||
m_commander.RegisterCommand("stats", cmdSyncStats);
|
m_commander.RegisterCommand("status", cmdSyncStatus);
|
||||||
|
|
||||||
lock (m_scene)
|
lock (m_scene)
|
||||||
{
|
{
|
||||||
|
@ -528,16 +569,34 @@ namespace OpenSim.Region.Examples.RegionSyncModule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SyncStats(Object[] args)
|
private void SyncStatus(Object[] args)
|
||||||
{
|
{
|
||||||
if (Synced)
|
if (Synced)
|
||||||
m_server.ReportStats();
|
m_server.ReportStatus();
|
||||||
else if (m_server != null)
|
|
||||||
m_log.Error("No RegionSyncClients connected");
|
|
||||||
else
|
else
|
||||||
m_log.Error("The RegionSyncServer is not running!");
|
m_log.Error("No RegionSyncClients connected");
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
private static readonly Vector3 CenterOfRegion = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f),20);
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
internal void LocalChat(string msg, int channel)
|
||||||
|
{
|
||||||
|
OSChatMessage osm = new OSChatMessage();
|
||||||
|
osm.From = "RegionSyncServerModule";
|
||||||
|
osm.Message = msg;
|
||||||
|
osm.Type = ChatTypeEnum.Region;
|
||||||
|
osm.Position = CenterOfRegion;
|
||||||
|
osm.Sender = null;
|
||||||
|
osm.SenderUUID = OpenMetaverse.UUID.Zero; // Hmph! Still?
|
||||||
|
|
||||||
|
osm.Channel = channel;
|
||||||
|
|
||||||
|
m_log.DebugFormat("[REGION SYNC SERVER MODULE] LocalChat({0},{1})", msg, channel);
|
||||||
|
m_scene.EventManager.TriggerOnChatBroadcast(this, osm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -403,6 +403,11 @@ namespace OpenSim.Region.Examples.SimpleModule
|
||||||
set { }
|
set { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public uint MaxCoarseLocations
|
||||||
|
{
|
||||||
|
get { return 0; }
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void ActivateGesture(UUID assetId, UUID gestureId)
|
public virtual void ActivateGesture(UUID assetId, UUID gestureId)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,12 +44,5 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
void DeleteObject(ulong regionHandle, uint localID);
|
void DeleteObject(ulong regionHandle, uint localID);
|
||||||
void SendAppearance(UUID agentID, byte[] vp, Primitive.TextureEntry te);
|
void SendAppearance(UUID agentID, byte[] vp, Primitive.TextureEntry te);
|
||||||
|
|
||||||
//void SendPartFullUpdate(SceneObjectPart part);
|
|
||||||
|
|
||||||
//void SendPartTerseUpdate(SceneObjectPart part);
|
|
||||||
|
|
||||||
//void SendShutdownConnectionNotice(Scene scene);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
|
||||||
public string CurrentMovementAnimation
|
public string CurrentMovementAnimation
|
||||||
{
|
{
|
||||||
get { return m_movementAnimation; }
|
get { return m_movementAnimation; }
|
||||||
|
set { m_movementAnimation = value; }
|
||||||
}
|
}
|
||||||
protected string m_movementAnimation = "DEFAULT";
|
protected string m_movementAnimation = "DEFAULT";
|
||||||
|
|
||||||
|
|
|
@ -375,6 +375,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
private int m_update_backup = 200;
|
private int m_update_backup = 200;
|
||||||
private int m_update_terrain = 50;
|
private int m_update_terrain = 50;
|
||||||
private int m_update_land = 1;
|
private int m_update_land = 1;
|
||||||
|
private int m_update_coarse_locations = 25;
|
||||||
|
|
||||||
private int frameMS;
|
private int frameMS;
|
||||||
private int physicsMS2;
|
private int physicsMS2;
|
||||||
|
@ -1311,8 +1312,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
while (m_regInfo.EstateSettings.EstateOwner == UUID.Zero && MainConsole.Instance != null)
|
while (m_regInfo.EstateSettings.EstateOwner == UUID.Zero && MainConsole.Instance != null)
|
||||||
{
|
{
|
||||||
MainConsole.Instance.Output("The current estate has no owner set.");
|
MainConsole.Instance.Output("The current estate has no owner set.");
|
||||||
string first = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test");
|
string first = "Test";// MainConsole.Instance.CmdPrompt("Estate owner first name", "Test");
|
||||||
string last = MainConsole.Instance.CmdPrompt("Estate owner last name", "User");
|
string last = "User";// MainConsole.Instance.CmdPrompt("Estate owner last name", "User");
|
||||||
|
MainConsole.Instance.Output(String.Format("Setting estate owner to {0} {1}.", first, last));
|
||||||
|
|
||||||
UserAccount account = UserAccountService.GetUserAccount(m_regInfo.ScopeID, first, last);
|
UserAccount account = UserAccountService.GetUserAccount(m_regInfo.ScopeID, first, last);
|
||||||
|
|
||||||
|
@ -1472,6 +1474,23 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_regionSyncServerModule.SendUpdates();
|
m_regionSyncServerModule.SendUpdates();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The authoritative sim should not try to send coarse locations
|
||||||
|
// Leave this up to the client managers
|
||||||
|
if (!IsSyncedServer())
|
||||||
|
{
|
||||||
|
if (m_frame % m_update_coarse_locations == 0)
|
||||||
|
{
|
||||||
|
List<Vector3> coarseLocations;
|
||||||
|
List<UUID> avatarUUIDs;
|
||||||
|
SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60);
|
||||||
|
// Send coarse locations to clients
|
||||||
|
ForEachScenePresence(delegate(ScenePresence presence)
|
||||||
|
{
|
||||||
|
presence.SendCoarseLocations(coarseLocations, avatarUUIDs);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int tmpPhysicsMS2 = Util.EnvironmentTickCount();
|
int tmpPhysicsMS2 = Util.EnvironmentTickCount();
|
||||||
// Do not simulate physics locally if this is a synced client
|
// Do not simulate physics locally if this is a synced client
|
||||||
if (!IsSyncedClient())
|
if (!IsSyncedClient())
|
||||||
|
@ -3350,7 +3369,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
(childagentYN ? "child" : "root"), agentID, RegionInfo.RegionName);
|
(childagentYN ? "child" : "root"), agentID, RegionInfo.RegionName);
|
||||||
|
|
||||||
m_sceneGraph.removeUserCount(!childagentYN);
|
m_sceneGraph.removeUserCount(!childagentYN);
|
||||||
CapsModule.RemoveCapsHandler(agentID);
|
|
||||||
|
// If there is a CAPS handler, remove it now.
|
||||||
|
// A Synced server region will not have a CAPS handler for its presences
|
||||||
|
if(CapsModule.GetCapsHandlerForUser(agentID) != null)
|
||||||
|
CapsModule.RemoveCapsHandler(agentID);
|
||||||
|
|
||||||
// REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
|
// REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
|
||||||
// this method is doing is HORRIBLE!!!
|
// this method is doing is HORRIBLE!!!
|
||||||
|
@ -3381,7 +3404,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
// Don't try to send kills to clients if this is a synced server.
|
// Don't try to send kills to clients if this is a synced server.
|
||||||
// The client closed event will trigger the broadcast to client managers
|
// The client closed event will trigger the broadcast to client managers
|
||||||
//if(!IsSyncedServer())
|
if(!IsSyncedServer())
|
||||||
{
|
{
|
||||||
ForEachClient(
|
ForEachClient(
|
||||||
delegate(IClientAPI client)
|
delegate(IClientAPI client)
|
||||||
|
@ -3392,9 +3415,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
ForEachScenePresence(
|
|
||||||
delegate(ScenePresence presence) { presence.CoarseLocationChange(); });
|
|
||||||
|
|
||||||
IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
|
IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
|
||||||
if (agentTransactions != null)
|
if (agentTransactions != null)
|
||||||
{
|
{
|
||||||
|
@ -3447,15 +3467,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Inform all other ScenePresences on this Scene that someone else has changed position on the minimap.
|
|
||||||
/// </summary>
|
|
||||||
public void NotifyMyCoarseLocationChange()
|
|
||||||
{
|
|
||||||
// REGION SYNC (Need a better plan for coarse locations)
|
|
||||||
//ForEachScenePresence(delegate(ScenePresence presence) { presence.CoarseLocationChange(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Entities
|
#region Entities
|
||||||
|
|
|
@ -206,6 +206,43 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void GetCoarseLocations(out List<Vector3> coarseLocations, out List<UUID> avatarUUIDs, uint maxLocations)
|
||||||
|
{
|
||||||
|
coarseLocations = new List<Vector3>();
|
||||||
|
avatarUUIDs = new List<UUID>();
|
||||||
|
|
||||||
|
List<ScenePresence> presences = GetScenePresences();
|
||||||
|
for (int i = 0; i < Math.Min(presences.Count, maxLocations); ++i)
|
||||||
|
{
|
||||||
|
ScenePresence sp = presences[i];
|
||||||
|
// If this presence is a child agent, we don't want its coarse locations
|
||||||
|
if (sp.IsChildAgent)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (sp.ParentID != 0)
|
||||||
|
{
|
||||||
|
// sitting avatar
|
||||||
|
SceneObjectPart sop = m_parentScene.GetSceneObjectPart(sp.ParentID);
|
||||||
|
if (sop != null)
|
||||||
|
{
|
||||||
|
coarseLocations.Add(sop.AbsolutePosition + sp.AbsolutePosition);
|
||||||
|
avatarUUIDs.Add(sp.UUID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we can't find the parent.. ! arg!
|
||||||
|
coarseLocations.Add(sp.AbsolutePosition);
|
||||||
|
avatarUUIDs.Add(sp.UUID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
coarseLocations.Add(sp.AbsolutePosition);
|
||||||
|
avatarUUIDs.Add(sp.UUID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Entity Methods
|
#region Entity Methods
|
||||||
|
|
|
@ -65,7 +65,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public ScriptControlled eventControls;
|
public ScriptControlled eventControls;
|
||||||
}
|
}
|
||||||
|
|
||||||
public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence);
|
public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence, List<Vector3> coarseLocations, List<UUID> avatarUUIDs);
|
||||||
|
|
||||||
public class ScenePresence : EntityBase, ISceneEntity
|
public class ScenePresence : EntityBase, ISceneEntity
|
||||||
{
|
{
|
||||||
|
@ -173,8 +173,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public string JID = String.Empty;
|
public string JID = String.Empty;
|
||||||
|
|
||||||
// Agent moves with a PID controller causing a force to be exerted.
|
|
||||||
private bool m_newCoarseLocations = true;
|
|
||||||
private float m_health = 100f;
|
private float m_health = 100f;
|
||||||
|
|
||||||
// Default AV Height
|
// Default AV Height
|
||||||
|
@ -683,10 +681,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
CreateSceneViewer();
|
CreateSceneViewer();
|
||||||
m_animator = new ScenePresenceAnimator(this);
|
m_animator = new ScenePresenceAnimator(this);
|
||||||
|
|
||||||
|
/*
|
||||||
Primitive.TextureEntry te = AvatarAppearance.GetDefaultTexture();
|
Primitive.TextureEntry te = AvatarAppearance.GetDefaultTexture();
|
||||||
byte[] vp = AvatarAppearance.GetDefaultVisualParams();
|
byte[] vp = AvatarAppearance.GetDefaultVisualParams();
|
||||||
m_appearance = new AvatarAppearance(UUID);
|
m_appearance = new AvatarAppearance(UUID);
|
||||||
m_appearance.SetAppearance(te, vp);
|
m_appearance.SetAppearance(te, vp);
|
||||||
|
* */
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
|
private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
|
||||||
|
@ -722,7 +722,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
AdjustKnownSeeds();
|
AdjustKnownSeeds();
|
||||||
|
|
||||||
// TODO: I think, this won't send anything, as we are still a child here...
|
// TODO: I think, this won't send anything, as we are still a child here...
|
||||||
Animator.TrySetMovementAnimation("STAND");
|
//Animator.TrySetMovementAnimation("STAND");
|
||||||
|
|
||||||
// we created a new ScenePresence (a new child agent) in a fresh region.
|
// we created a new ScenePresence (a new child agent) in a fresh region.
|
||||||
// Request info about all the (root) agents in this region
|
// Request info about all the (root) agents in this region
|
||||||
|
@ -737,13 +737,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
AvatarWearable[] wearables)
|
AvatarWearable[] wearables)
|
||||||
: this(client, world, reginfo)
|
: this(client, world, reginfo)
|
||||||
{
|
{
|
||||||
//m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams);
|
m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance)
|
public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance)
|
||||||
: this(client, world, reginfo)
|
: this(client, world, reginfo)
|
||||||
{
|
{
|
||||||
//m_appearance = appearance;
|
m_appearance = appearance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateSceneViewer()
|
private void CreateSceneViewer()
|
||||||
|
@ -756,10 +756,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// REGION SYNC
|
// REGION SYNC
|
||||||
if (!m_scene.IsSyncedClient())
|
if (!m_scene.IsSyncedClient())
|
||||||
{
|
{
|
||||||
|
// These client messages will not be handled by client managers but instead
|
||||||
|
// they are caught by the RegionSyncClient module and passed up to the auth sim
|
||||||
m_controllingClient.OnAgentUpdate += HandleAgentUpdate;
|
m_controllingClient.OnAgentUpdate += HandleAgentUpdate;
|
||||||
|
m_controllingClient.OnSetAppearance += SetAppearance;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_controllingClient.OnSetAppearance += SetAppearance;
|
|
||||||
m_controllingClient.OnRequestWearables += SendWearables;
|
m_controllingClient.OnRequestWearables += SendWearables;
|
||||||
m_controllingClient.OnCompleteMovementToRegion += CompleteMovement;
|
m_controllingClient.OnCompleteMovementToRegion += CompleteMovement;
|
||||||
//m_controllingClient.OnCompleteMovementToRegion += SendInitialData;
|
//m_controllingClient.OnCompleteMovementToRegion += SendInitialData;
|
||||||
|
@ -2352,12 +2354,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
SendPrimUpdates();
|
SendPrimUpdates();
|
||||||
|
|
||||||
if (m_newCoarseLocations)
|
|
||||||
{
|
|
||||||
SendCoarseLocations();
|
|
||||||
m_newCoarseLocations = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_isChildAgent == false)
|
if (m_isChildAgent == false)
|
||||||
{
|
{
|
||||||
// PhysicsActor actor = m_physicsActor;
|
// PhysicsActor actor = m_physicsActor;
|
||||||
|
@ -2428,6 +2424,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendTerseUpdateToAllClients()
|
public void SendTerseUpdateToAllClients()
|
||||||
{
|
{
|
||||||
|
// REGION SYNC
|
||||||
|
// The server should not be doing anything via the ForEachScenePresence method
|
||||||
|
if (m_scene.IsSyncedServer())
|
||||||
|
return;
|
||||||
m_perfMonMS = Util.EnvironmentTickCount();
|
m_perfMonMS = Util.EnvironmentTickCount();
|
||||||
|
|
||||||
m_scene.ForEachClient(SendTerseUpdateToClient);
|
m_scene.ForEachClient(SendTerseUpdateToClient);
|
||||||
|
@ -2435,29 +2435,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
|
m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
|
||||||
/// Send a location/velocity/accelleration update to all agents in a list
|
|
||||||
/// </summary>
|
|
||||||
public void SendTerseUpdateToClientList(List<IClientAPI> clients)
|
|
||||||
{
|
{
|
||||||
m_perfMonMS = Util.EnvironmentTickCount();
|
|
||||||
foreach( IClientAPI client in clients)
|
|
||||||
{
|
|
||||||
SendTerseUpdateToClient(client);
|
|
||||||
}
|
|
||||||
m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendCoarseLocations()
|
|
||||||
{
|
|
||||||
SendCoarseLocationsDefault(m_scene.RegionInfo.originRegionID, this);
|
|
||||||
/*
|
|
||||||
SendCourseLocationsMethod d = m_sendCourseLocationsMethod;
|
SendCourseLocationsMethod d = m_sendCourseLocationsMethod;
|
||||||
if (d != null)
|
if (d != null)
|
||||||
{
|
{
|
||||||
d.Invoke(m_scene.RegionInfo.originRegionID, this);
|
d.Invoke(m_scene.RegionInfo.originRegionID, this, coarseLocations, avatarUUIDs);
|
||||||
}
|
}
|
||||||
* */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetSendCourseLocationMethod(SendCourseLocationsMethod d)
|
public void SetSendCourseLocationMethod(SendCourseLocationsMethod d)
|
||||||
|
@ -2466,23 +2450,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_sendCourseLocationsMethod = d;
|
m_sendCourseLocationsMethod = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p)
|
public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p, List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
|
||||||
{
|
{
|
||||||
m_perfMonMS = Util.EnvironmentTickCount();
|
m_perfMonMS = Util.EnvironmentTickCount();
|
||||||
List<UUID> AvatarUUIDs = new List<UUID>();
|
m_controllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations);
|
||||||
List<Vector3> CoarseLocations = new List<Vector3>();
|
|
||||||
// This is not cheap to compile this list of locations.
|
|
||||||
// It should ideally be done once and then sent to every client rather than compiled for each client
|
|
||||||
//m_scene.GetCoarseLocations(out AvatarUUIDs, out CoarseLocations);
|
|
||||||
AvatarUUIDs.Add(UUID);
|
|
||||||
CoarseLocations.Add(AbsolutePosition);
|
|
||||||
m_controllingClient.SendCoarseLocationUpdate(AvatarUUIDs, CoarseLocations);
|
|
||||||
m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
|
m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
|
||||||
}
|
|
||||||
|
|
||||||
public void CoarseLocationChange()
|
|
||||||
{
|
|
||||||
m_newCoarseLocations = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -2512,6 +2485,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendInitialFullUpdateToAllClients()
|
public void SendInitialFullUpdateToAllClients()
|
||||||
{
|
{
|
||||||
|
// REGION SYNC
|
||||||
|
// The server should not be doing anything via the ForEachScenePresence method
|
||||||
|
if (m_scene.IsSyncedServer())
|
||||||
|
return;
|
||||||
m_perfMonMS = Util.EnvironmentTickCount();
|
m_perfMonMS = Util.EnvironmentTickCount();
|
||||||
int avUpdates = 0;
|
int avUpdates = 0;
|
||||||
m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
|
m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
|
||||||
|
@ -2542,6 +2519,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public void SendFullUpdateToAllClients()
|
public void SendFullUpdateToAllClients()
|
||||||
{
|
{
|
||||||
|
// REGION SYNC
|
||||||
|
// The server should not be doing anything via the ForEachScenePresence method
|
||||||
|
if (m_scene.IsSyncedServer())
|
||||||
|
return;
|
||||||
m_perfMonMS = Util.EnvironmentTickCount();
|
m_perfMonMS = Util.EnvironmentTickCount();
|
||||||
|
|
||||||
// only send update from root agents to other clients; children are only "listening posts"
|
// only send update from root agents to other clients; children are only "listening posts"
|
||||||
|
@ -2592,16 +2573,23 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendAppearanceToAllOtherAgents()
|
public void SendAppearanceToAllOtherAgents()
|
||||||
{
|
{
|
||||||
|
// REGION SYNC
|
||||||
|
// The server should not be doing anything via the ForEachScenePresence method
|
||||||
|
if (m_scene.IsSyncedServer())
|
||||||
|
return;
|
||||||
|
if (Appearance.Texture == null)
|
||||||
|
return;
|
||||||
m_perfMonMS = Util.EnvironmentTickCount();
|
m_perfMonMS = Util.EnvironmentTickCount();
|
||||||
|
|
||||||
// REGION SYNC
|
// REGION SYNC
|
||||||
if(m_scene.IsSyncedServer())
|
//if(m_scene.IsSyncedServer())
|
||||||
m_scene.RegionSyncServerModule.SendAppearance(UUID, Appearance.VisualParams, Appearance.Texture);
|
//m_scene.RegionSyncServerModule.SendAppearance(UUID, Appearance.VisualParams, Appearance.Texture);
|
||||||
m_appearance.Owner = UUID; // Why does this need to be here?
|
m_appearance.Owner = UUID; // Why does this need to be here?
|
||||||
m_scene.ForEachClient(delegate(IClientAPI client)
|
m_scene.ForEachClient(delegate(IClientAPI client)
|
||||||
{
|
{
|
||||||
if(client.AgentId != ControllingClient.AgentId)
|
if(client.AgentId != ControllingClient.AgentId)
|
||||||
{
|
{
|
||||||
|
//m_log.WarnFormat("[SCENE PRESENCE] Sending {0} appearance to {1} (SendAppearanceToAllOtherAgents)", Name, client.Name);
|
||||||
client.SendAppearance(m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes());
|
client.SendAppearance(m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -2627,7 +2615,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <param name="avatar"></param>
|
/// <param name="avatar"></param>
|
||||||
public void SendAppearanceToOtherAgent(ScenePresence avatar)
|
public void SendAppearanceToOtherAgent(ScenePresence avatar)
|
||||||
{
|
{
|
||||||
|
if (Appearance.Texture == null)
|
||||||
|
return;
|
||||||
//m_log.WarnFormat("{0} sending appearance to {1}, owner={2}", UUID, avatar.UUID, m_appearance.Owner);
|
//m_log.WarnFormat("{0} sending appearance to {1}, owner={2}", UUID, avatar.UUID, m_appearance.Owner);
|
||||||
|
//m_log.WarnFormat("[SCENE PRESENCE] Sending {0} appearance to {1} (SendAppearanceToOtherAgent)", Name, avatar.Name);
|
||||||
m_appearance.Owner = UUID;
|
m_appearance.Owner = UUID;
|
||||||
avatar.ControllingClient.SendAppearance(
|
avatar.ControllingClient.SendAppearance(
|
||||||
m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes());
|
m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes());
|
||||||
|
@ -2640,6 +2631,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <param name="visualParam"></param>
|
/// <param name="visualParam"></param>
|
||||||
public void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
|
public void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
|
||||||
{
|
{
|
||||||
|
//m_log.WarnFormat("[SCENE PRESENCE] SetAppearance called for {0} ({1})", Name, textureEntry == null ? " " : "te");
|
||||||
if (m_physicsActor != null)
|
if (m_physicsActor != null)
|
||||||
{
|
{
|
||||||
if (!IsChildAgent)
|
if (!IsChildAgent)
|
||||||
|
@ -2704,6 +2696,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public void SetWearable(int wearableId, AvatarWearable wearable)
|
public void SetWearable(int wearableId, AvatarWearable wearable)
|
||||||
{
|
{
|
||||||
|
m_log.WarnFormat("[SCENE PRESENCE] SetWearable called for \"{0}\" (wearableID = {1})", Name, wearableId);
|
||||||
m_appearance.SetWearable(wearableId, wearable);
|
m_appearance.SetWearable(wearableId, wearable);
|
||||||
AvatarData adata = new AvatarData(m_appearance);
|
AvatarData adata = new AvatarData(m_appearance);
|
||||||
m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata);
|
m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata);
|
||||||
|
@ -2737,7 +2730,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
posLastSignificantMove = AbsolutePosition;
|
posLastSignificantMove = AbsolutePosition;
|
||||||
m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient);
|
m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient);
|
||||||
m_scene.NotifyMyCoarseLocationChange();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m
|
// Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m
|
||||||
|
|
|
@ -638,6 +638,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
||||||
set { }
|
set { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public uint MaxCoarseLocations
|
||||||
|
{
|
||||||
|
get { return 0; }
|
||||||
|
}
|
||||||
|
|
||||||
public uint CircuitCode
|
public uint CircuitCode
|
||||||
{
|
{
|
||||||
get { return (uint)Util.RandomClass.Next(0,int.MaxValue); }
|
get { return (uint)Util.RandomClass.Next(0,int.MaxValue); }
|
||||||
|
|
|
@ -131,6 +131,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
set { }
|
set { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public uint MaxCoarseLocations { get { return 0; } }
|
||||||
|
|
||||||
#region Internal Functions
|
#region Internal Functions
|
||||||
|
|
||||||
private void SendOnChatFromClient(string message, ChatTypeEnum chatType)
|
private void SendOnChatFromClient(string message, ChatTypeEnum chatType)
|
||||||
|
|
|
@ -696,7 +696,9 @@ namespace OpenSim.Region.RegionCombinerModule
|
||||||
presence.SetSendCourseLocationMethod(SendCourseLocationUpdates);
|
presence.SetSendCourseLocationMethod(SendCourseLocationUpdates);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendCourseLocationUpdates(UUID sceneId, ScenePresence presence)
|
// This delegate was refactored for non-combined regions.
|
||||||
|
// This combined region version will not use the pre-compiled lists of locations and ids
|
||||||
|
private void SendCourseLocationUpdates(UUID sceneId, ScenePresence presence, List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
|
||||||
{
|
{
|
||||||
RegionConnections connectiondata = null;
|
RegionConnections connectiondata = null;
|
||||||
lock (m_regions)
|
lock (m_regions)
|
||||||
|
|
|
@ -417,6 +417,11 @@ namespace OpenSim.Tests.Common.Mock
|
||||||
set { }
|
set { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public uint MaxCoarseLocations
|
||||||
|
{
|
||||||
|
get { return 0; }
|
||||||
|
}
|
||||||
|
|
||||||
private uint m_circuitCode;
|
private uint m_circuitCode;
|
||||||
|
|
||||||
public uint CircuitCode
|
public uint CircuitCode
|
||||||
|
|
Binary file not shown.
|
@ -1378,6 +1378,7 @@
|
||||||
|
|
||||||
<ReferencePath>../../../bin/</ReferencePath>
|
<ReferencePath>../../../bin/</ReferencePath>
|
||||||
<Reference name="System"/>
|
<Reference name="System"/>
|
||||||
|
<Reference name="System.Core"/>
|
||||||
<Reference name="System.Xml"/>
|
<Reference name="System.Xml"/>
|
||||||
<Reference name="System.Drawing"/>
|
<Reference name="System.Drawing"/>
|
||||||
<Reference name="System.Web"/>
|
<Reference name="System.Web"/>
|
||||||
|
|
Loading…
Reference in New Issue