Merge branch 'master' into bullet-2.82
commit
7ba3b88fb6
|
@ -4201,6 +4201,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
}
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[LLCLIENTVIEW]: Sent {0} updates in ProcessEntityUpdates() for {1} {2} in {3}",
|
||||
// updatesThisCall, Name, SceneAgent.IsChildAgent ? "child" : "root", Scene.Name);
|
||||
//
|
||||
#endregion Packet Sending
|
||||
}
|
||||
|
||||
|
@ -12337,6 +12341,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
/// provide your own method.</param>
|
||||
protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method)
|
||||
{
|
||||
if (m_outPacketsToDrop != null)
|
||||
if (m_outPacketsToDrop.Contains(packet.Type.ToString()))
|
||||
return;
|
||||
|
||||
if (DebugPacketLevel > 0)
|
||||
{
|
||||
bool logPacket = true;
|
||||
|
@ -12395,6 +12403,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
/// <param name="Pack">OpenMetaverse.packet</param>
|
||||
public void ProcessInPacket(Packet packet)
|
||||
{
|
||||
if (m_inPacketsToDrop != null)
|
||||
if (m_inPacketsToDrop.Contains(packet.Type.ToString()))
|
||||
return;
|
||||
|
||||
if (DebugPacketLevel > 0)
|
||||
{
|
||||
bool logPacket = true;
|
||||
|
@ -13119,5 +13131,51 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
eq.Enqueue(BuildEvent("BulkUpdateInventory",
|
||||
llsd), AgentId);
|
||||
}
|
||||
|
||||
private HashSet<string> m_outPacketsToDrop;
|
||||
|
||||
public bool AddOutPacketToDropSet(string packetName)
|
||||
{
|
||||
if (m_outPacketsToDrop == null)
|
||||
m_outPacketsToDrop = new HashSet<string>();
|
||||
|
||||
return m_outPacketsToDrop.Add(packetName);
|
||||
}
|
||||
|
||||
public bool RemoveOutPacketFromDropSet(string packetName)
|
||||
{
|
||||
if (m_outPacketsToDrop == null)
|
||||
return false;
|
||||
|
||||
return m_outPacketsToDrop.Remove(packetName);
|
||||
}
|
||||
|
||||
public HashSet<string> GetOutPacketDropSet()
|
||||
{
|
||||
return new HashSet<string>(m_outPacketsToDrop);
|
||||
}
|
||||
|
||||
private HashSet<string> m_inPacketsToDrop;
|
||||
|
||||
public bool AddInPacketToDropSet(string packetName)
|
||||
{
|
||||
if (m_inPacketsToDrop == null)
|
||||
m_inPacketsToDrop = new HashSet<string>();
|
||||
|
||||
return m_inPacketsToDrop.Add(packetName);
|
||||
}
|
||||
|
||||
public bool RemoveInPacketFromDropSet(string packetName)
|
||||
{
|
||||
if (m_inPacketsToDrop == null)
|
||||
return false;
|
||||
|
||||
return m_inPacketsToDrop.Remove(packetName);
|
||||
}
|
||||
|
||||
public HashSet<string> GetInPacketDropSet()
|
||||
{
|
||||
return new HashSet<string>(m_inPacketsToDrop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -650,8 +650,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
if (HasUpdates(m_categories))
|
||||
{
|
||||
// Asynchronously run the callback
|
||||
Util.FireAndForget(FireQueueEmpty, categories);
|
||||
if (!m_udpServer.OqrEngine.IsRunning)
|
||||
{
|
||||
// Asynchronously run the callback
|
||||
Util.FireAndForget(FireQueueEmpty, categories);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_udpServer.OqrEngine.QueueRequest(this, categories);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -670,8 +677,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
/// <param name="o">Throttle categories to fire the callback for,
|
||||
/// stored as an object to match the WaitCallback delegate
|
||||
/// signature</param>
|
||||
private void FireQueueEmpty(object o)
|
||||
public void FireQueueEmpty(object o)
|
||||
{
|
||||
// m_log.DebugFormat("[LLUDPCLIENT]: FireQueueEmpty for {0} in {1}", AgentID, m_udpServer.Scene.Name);
|
||||
|
||||
// int start = Environment.TickCount & Int32.MaxValue;
|
||||
// const int MIN_CALLBACK_MS = 30;
|
||||
|
||||
|
|
|
@ -250,7 +250,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
private AgentCircuitManager m_circuitManager;
|
||||
|
||||
/// <summary>Reference to the scene this UDP server is attached to</summary>
|
||||
protected Scene m_scene;
|
||||
public Scene Scene { get; private set; }
|
||||
|
||||
/// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary>
|
||||
private Location m_location;
|
||||
|
@ -355,6 +355,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
/// </summary>
|
||||
private IClientAPI m_currentIncomingClient;
|
||||
|
||||
/// <summary>
|
||||
/// Experimental facility to run queue empty processing within a controlled number of threads rather than
|
||||
/// requiring massive numbers of short-lived threads from the threadpool when there are a high number of
|
||||
/// connections.
|
||||
/// </summary>
|
||||
public OutgoingQueueRefillEngine OqrEngine { get; private set; }
|
||||
|
||||
public LLUDPServer(
|
||||
IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port,
|
||||
IConfigSource configSource, AgentCircuitManager circuitManager)
|
||||
|
@ -432,6 +439,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
if (usePools)
|
||||
EnablePools();
|
||||
|
||||
OqrEngine = new OutgoingQueueRefillEngine(this);
|
||||
}
|
||||
|
||||
public void Start()
|
||||
|
@ -453,7 +462,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
// This thread will process the packets received that are placed on the packetInbox
|
||||
Watchdog.StartThread(
|
||||
IncomingPacketHandler,
|
||||
string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName),
|
||||
string.Format("Incoming Packets ({0})", Scene.Name),
|
||||
ThreadPriority.Normal,
|
||||
false,
|
||||
true,
|
||||
|
@ -469,7 +478,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
Watchdog.StartThread(
|
||||
OutgoingPacketHandler,
|
||||
string.Format("Outgoing Packets ({0})", m_scene.RegionInfo.RegionName),
|
||||
string.Format("Outgoing Packets ({0})", Scene.Name),
|
||||
ThreadPriority.Normal,
|
||||
false,
|
||||
true,
|
||||
|
@ -479,7 +488,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
public void Stop()
|
||||
{
|
||||
m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName);
|
||||
m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + Scene.Name);
|
||||
base.StopOutbound();
|
||||
base.StopInbound();
|
||||
}
|
||||
|
@ -527,7 +536,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
"The number of objects currently stored within the UDPPacketBuffer pool",
|
||||
"",
|
||||
"clientstack",
|
||||
m_scene.Name,
|
||||
Scene.Name,
|
||||
StatType.Pull,
|
||||
stat => stat.Value = Pool.Count,
|
||||
StatVerbosity.Debug);
|
||||
|
@ -541,7 +550,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
"The number of objects currently stored within the incoming packet pool",
|
||||
"",
|
||||
"clientstack",
|
||||
m_scene.Name,
|
||||
Scene.Name,
|
||||
StatType.Pull,
|
||||
stat => stat.Value = m_incomingPacketPool.Count,
|
||||
StatVerbosity.Debug);
|
||||
|
@ -585,7 +594,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
public void AddScene(IScene scene)
|
||||
{
|
||||
if (m_scene != null)
|
||||
if (Scene != null)
|
||||
{
|
||||
m_log.Error("[LLUDPSERVER]: AddScene() called on an LLUDPServer that already has a scene");
|
||||
return;
|
||||
|
@ -597,8 +606,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
return;
|
||||
}
|
||||
|
||||
m_scene = (Scene)scene;
|
||||
m_location = new Location(m_scene.RegionInfo.RegionHandle);
|
||||
Scene = (Scene)scene;
|
||||
m_location = new Location(Scene.RegionInfo.RegionHandle);
|
||||
|
||||
StatsManager.RegisterStat(
|
||||
new Stat(
|
||||
|
@ -621,7 +630,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
"Packets reused",
|
||||
"Number of packets reused out of all requests to the packet pool",
|
||||
"clientstack",
|
||||
m_scene.Name,
|
||||
Scene.Name,
|
||||
StatType.Pull,
|
||||
stat =>
|
||||
{ PercentageStat pstat = (PercentageStat)stat;
|
||||
|
@ -635,7 +644,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
"Packet data blocks reused",
|
||||
"Number of data blocks reused out of all requests to the packet pool",
|
||||
"clientstack",
|
||||
m_scene.Name,
|
||||
Scene.Name,
|
||||
StatType.Pull,
|
||||
stat =>
|
||||
{ PercentageStat pstat = (PercentageStat)stat;
|
||||
|
@ -650,7 +659,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
"The number of objects currently stored within the packet pool",
|
||||
"",
|
||||
"clientstack",
|
||||
m_scene.Name,
|
||||
Scene.Name,
|
||||
StatType.Pull,
|
||||
stat => stat.Value = PacketPool.Instance.PacketsPooled,
|
||||
StatVerbosity.Debug));
|
||||
|
@ -662,7 +671,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
"The number of objects currently stored within the packet data block pool",
|
||||
"",
|
||||
"clientstack",
|
||||
m_scene.Name,
|
||||
Scene.Name,
|
||||
StatType.Pull,
|
||||
stat => stat.Value = PacketPool.Instance.BlocksPooled,
|
||||
StatVerbosity.Debug));
|
||||
|
@ -688,6 +697,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
+ "If an avatar name is given then only packets from that avatar are logged.",
|
||||
HandlePacketCommand);
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(
|
||||
"Debug", false, "debug lludp drop",
|
||||
"debug lludp drop <in|out> <add|remove> <packet-name>",
|
||||
"Drop all in or outbound packets that match the given name",
|
||||
"For test purposes.",
|
||||
HandleDropCommand);
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(
|
||||
"Debug",
|
||||
false,
|
||||
|
@ -739,7 +755,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
private void HandlePacketCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
|
||||
return;
|
||||
|
||||
bool setAsDefaultLevel = false;
|
||||
|
@ -775,15 +791,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Packet debug for {0} clients set to {1} in {2}",
|
||||
(setAll ? "all" : "future"), DefaultClientPacketDebugLevel, m_scene.Name);
|
||||
(setAll ? "all" : "future"), DefaultClientPacketDebugLevel, Scene.Name);
|
||||
|
||||
if (setAll)
|
||||
{
|
||||
m_scene.ForEachScenePresence(sp =>
|
||||
Scene.ForEachScenePresence(sp =>
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Packet debug for {0} ({1}) set to {2} in {3}",
|
||||
sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, m_scene.Name);
|
||||
sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, Scene.Name);
|
||||
|
||||
sp.ControllingClient.DebugPacketLevel = newDebug;
|
||||
});
|
||||
|
@ -791,13 +807,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
}
|
||||
else
|
||||
{
|
||||
m_scene.ForEachScenePresence(sp =>
|
||||
Scene.ForEachScenePresence(sp =>
|
||||
{
|
||||
if (name == null || sp.Name == name)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Packet debug for {0} ({1}) set to {2} in {3}",
|
||||
sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, m_scene.Name);
|
||||
sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, Scene.Name);
|
||||
|
||||
sp.ControllingClient.DebugPacketLevel = newDebug;
|
||||
}
|
||||
|
@ -811,9 +827,60 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
}
|
||||
}
|
||||
|
||||
private void HandleDropCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
|
||||
return;
|
||||
|
||||
if (args.Length != 6)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug lludp drop <in|out> <add|remove> <packet-name>");
|
||||
return;
|
||||
}
|
||||
|
||||
string direction = args[3];
|
||||
string subCommand = args[4];
|
||||
string packetName = args[5];
|
||||
|
||||
if (subCommand == "add")
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Adding packet {0} to {1} drop list for all connections in {2}", direction, packetName, Scene.Name);
|
||||
|
||||
Scene.ForEachScenePresence(
|
||||
sp =>
|
||||
{
|
||||
LLClientView llcv = (LLClientView)sp.ControllingClient;
|
||||
|
||||
if (direction == "in")
|
||||
llcv.AddInPacketToDropSet(packetName);
|
||||
else if (direction == "out")
|
||||
llcv.AddOutPacketToDropSet(packetName);
|
||||
}
|
||||
);
|
||||
}
|
||||
else if (subCommand == "remove")
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Removing packet {0} from {1} drop list for all connections in {2}", direction, packetName, Scene.Name);
|
||||
|
||||
Scene.ForEachScenePresence(
|
||||
sp =>
|
||||
{
|
||||
LLClientView llcv = (LLClientView)sp.ControllingClient;
|
||||
|
||||
if (direction == "in")
|
||||
llcv.RemoveInPacketFromDropSet(packetName);
|
||||
else if (direction == "out")
|
||||
llcv.RemoveOutPacketFromDropSet(packetName);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleStartCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
|
||||
return;
|
||||
|
||||
if (args.Length != 4)
|
||||
|
@ -833,7 +900,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
private void HandleStopCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
|
||||
return;
|
||||
|
||||
if (args.Length != 4)
|
||||
|
@ -853,7 +920,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
private void HandlePoolCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
|
||||
return;
|
||||
|
||||
if (args.Length != 4)
|
||||
|
@ -869,7 +936,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
if (EnablePools())
|
||||
{
|
||||
EnablePoolStats();
|
||||
MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_scene.Name);
|
||||
MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", Scene.Name);
|
||||
}
|
||||
}
|
||||
else if (enabled == "off")
|
||||
|
@ -877,7 +944,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
if (DisablePools())
|
||||
{
|
||||
DisablePoolStats();
|
||||
MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_scene.Name);
|
||||
MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", Scene.Name);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -890,27 +957,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
private void HandleAgentUpdateCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
|
||||
return;
|
||||
|
||||
m_discardAgentUpdates = !m_discardAgentUpdates;
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Discard AgentUpdates now {0} for {1}", m_discardAgentUpdates, m_scene.Name);
|
||||
"Discard AgentUpdates now {0} for {1}", m_discardAgentUpdates, Scene.Name);
|
||||
}
|
||||
|
||||
private void HandleStatusCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
|
||||
return;
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"IN LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningInbound ? "enabled" : "disabled");
|
||||
"IN LLUDP packet processing for {0} is {1}", Scene.Name, IsRunningInbound ? "enabled" : "disabled");
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"OUT LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningOutbound ? "enabled" : "disabled");
|
||||
"OUT LLUDP packet processing for {0} is {1}", Scene.Name, IsRunningOutbound ? "enabled" : "disabled");
|
||||
|
||||
MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_scene.Name, UsePools ? "on" : "off");
|
||||
MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", Scene.Name, UsePools ? "on" : "off");
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Packet debug level for new clients is {0}", DefaultClientPacketDebugLevel);
|
||||
|
@ -1420,7 +1487,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
// Determine which agent this packet came from
|
||||
IClientAPI client;
|
||||
if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
|
||||
if (!Scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
|
||||
{
|
||||
//m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
|
||||
|
||||
|
@ -1715,7 +1782,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} to {1} from IP {2}",
|
||||
uccp.CircuitCode.Code, m_scene.RegionInfo.RegionName, endPoint);
|
||||
uccp.CircuitCode.Code, Scene.RegionInfo.RegionName, endPoint);
|
||||
|
||||
AuthenticateResponse sessionInfo;
|
||||
if (IsClientAuthorized(uccp, out sessionInfo))
|
||||
|
@ -1737,7 +1804,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
// We only want to send initial data to new clients, not ones which are being converted from child to root.
|
||||
if (client != null)
|
||||
{
|
||||
AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code);
|
||||
AgentCircuitData aCircuit = Scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code);
|
||||
bool tp = (aCircuit.teleportFlags > 0);
|
||||
// Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from
|
||||
if (!tp && !client.SceneAgent.SentInitialDataToClient)
|
||||
|
@ -1749,7 +1816,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
// Don't create clients for unauthorized requesters.
|
||||
m_log.WarnFormat(
|
||||
"[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
|
||||
uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
|
||||
uccp.CircuitCode.ID, Scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
|
@ -1781,7 +1848,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
CompleteAgentMovementPacket packet = (CompleteAgentMovementPacket)array[1];
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: Handling CompleteAgentMovement request from {0} in {1}", endPoint, m_scene.Name);
|
||||
"[LLUDPSERVER]: Handling CompleteAgentMovement request from {0} in {1}", endPoint, Scene.Name);
|
||||
|
||||
// Determine which agent this packet came from
|
||||
// We need to wait here because in when using the OpenSimulator V2 teleport protocol to travel to a destination
|
||||
|
@ -1792,7 +1859,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
int count = 40;
|
||||
while (count-- > 0)
|
||||
{
|
||||
if (m_scene.TryGetClient(endPoint, out client))
|
||||
if (Scene.TryGetClient(endPoint, out client))
|
||||
{
|
||||
if (!client.IsActive)
|
||||
{
|
||||
|
@ -1801,7 +1868,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
// not yet been established).
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client is not active yet. Waiting.",
|
||||
endPoint, client.Name, m_scene.Name);
|
||||
endPoint, client.Name, Scene.Name);
|
||||
}
|
||||
else if (client.SceneAgent == null)
|
||||
{
|
||||
|
@ -1813,7 +1880,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
// the client manager
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client SceneAgent not set yet. Waiting.",
|
||||
endPoint, client.Name, m_scene.Name);
|
||||
endPoint, client.Name, Scene.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1824,7 +1891,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
{
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} in {1} but no client exists yet. Waiting.",
|
||||
endPoint, m_scene.Name);
|
||||
endPoint, Scene.Name);
|
||||
}
|
||||
|
||||
Thread.Sleep(200);
|
||||
|
@ -1834,7 +1901,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
{
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: No client found for CompleteAgentMovement from {0} in {1} after wait. Dropping.",
|
||||
endPoint, m_scene.Name);
|
||||
endPoint, Scene.Name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1846,7 +1913,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
// purposes.
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client is not active after wait. Dropping.",
|
||||
endPoint, client.Name, m_scene.Name);
|
||||
endPoint, client.Name, Scene.Name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1941,11 +2008,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
// consistently, this lock could probably be removed.
|
||||
lock (this)
|
||||
{
|
||||
if (!m_scene.TryGetClient(agentID, out client))
|
||||
if (!Scene.TryGetClient(agentID, out client))
|
||||
{
|
||||
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
|
||||
|
||||
client = new LLClientView(m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
|
||||
client = new LLClientView(Scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
|
||||
client.OnLogout += LogoutHandler;
|
||||
client.DebugPacketLevel = DefaultClientPacketDebugLevel;
|
||||
|
||||
|
@ -1975,13 +2042,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
m_log.WarnFormat(
|
||||
"[LLUDPSERVER]: No packets received from {0} agent of {1} for {2}ms in {3}. Disconnecting.",
|
||||
client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, timeoutTicks, m_scene.Name);
|
||||
client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, timeoutTicks, Scene.Name);
|
||||
|
||||
if (!client.SceneAgent.IsChildAgent)
|
||||
client.Kick("Simulator logged you out due to connection timeout.");
|
||||
}
|
||||
|
||||
m_scene.CloseAgent(client.AgentId, true);
|
||||
Scene.CloseAgent(client.AgentId, true);
|
||||
}
|
||||
|
||||
private void IncomingPacketHandler()
|
||||
|
@ -2093,7 +2160,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
// Handle outgoing packets, resends, acknowledgements, and pings for each
|
||||
// client. m_packetSent will be set to true if a packet is sent
|
||||
m_scene.ForEachClient(clientPacketHandler);
|
||||
Scene.ForEachClient(clientPacketHandler);
|
||||
|
||||
m_currentOutgoingClient = null;
|
||||
|
||||
|
@ -2260,7 +2327,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
watch1.Reset();
|
||||
|
||||
// reuse this -- it's every ~100ms
|
||||
if (m_scene.EmergencyMonitoring && nticks % 100 == 0)
|
||||
if (Scene.EmergencyMonitoring && nticks % 100 == 0)
|
||||
{
|
||||
m_log.InfoFormat("[LLUDPSERVER]: avg processing ticks: {0} avg unacked: {1} avg acks: {2} avg ping: {3} avg dequeue: {4} (TickCountRes: {5} sent: {6} notsent: {7})",
|
||||
avgProcessingTicks, avgResendUnackedTicks, avgSendAcksTicks, avgSendPingTicks, avgDequeueTicks, TickCountResolution, npacksSent, npackNotSent);
|
||||
|
@ -2309,7 +2376,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
{
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
|
||||
packet.Type, client.Name, m_scene.RegionInfo.RegionName);
|
||||
packet.Type, client.Name, Scene.RegionInfo.RegionName);
|
||||
}
|
||||
|
||||
IncomingPacketsProcessed++;
|
||||
|
@ -2322,7 +2389,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
if (!client.IsLoggingOut)
|
||||
{
|
||||
client.IsLoggingOut = true;
|
||||
m_scene.CloseAgent(client.AgentId, false);
|
||||
Scene.CloseAgent(client.AgentId, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,286 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Monitoring;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
public struct RefillRequest
|
||||
{
|
||||
public LLUDPClient Client;
|
||||
public ThrottleOutPacketTypeFlags Categories;
|
||||
|
||||
public RefillRequest(LLUDPClient client, ThrottleOutPacketTypeFlags categories)
|
||||
{
|
||||
Client = client;
|
||||
Categories = categories;
|
||||
}
|
||||
}
|
||||
|
||||
public class OutgoingQueueRefillEngine
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public bool IsRunning { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The timeout in milliseconds to wait for at least one event to be written when the recorder is stopping.
|
||||
/// </summary>
|
||||
public int RequestProcessTimeoutOnStop { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controls whether we need to warn in the log about exceeding the max queue size.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is flipped to false once queue max has been exceeded and back to true when it falls below max, in
|
||||
/// order to avoid spamming the log with lots of warnings.
|
||||
/// </remarks>
|
||||
private bool m_warnOverMaxQueue = true;
|
||||
|
||||
private BlockingCollection<RefillRequest> m_requestQueue;
|
||||
|
||||
private CancellationTokenSource m_cancelSource = new CancellationTokenSource();
|
||||
|
||||
private LLUDPServer m_udpServer;
|
||||
|
||||
private Stat m_oqreRequestsWaitingStat;
|
||||
|
||||
/// <summary>
|
||||
/// Used to signal that we are ready to complete stop.
|
||||
/// </summary>
|
||||
private ManualResetEvent m_finishedProcessingAfterStop = new ManualResetEvent(false);
|
||||
|
||||
public OutgoingQueueRefillEngine(LLUDPServer server)
|
||||
{
|
||||
RequestProcessTimeoutOnStop = 5000;
|
||||
m_udpServer = server;
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(
|
||||
"Debug",
|
||||
false,
|
||||
"debug lludp oqre",
|
||||
"debug lludp oqre <start|stop|status>",
|
||||
"Start, stop or get status of OutgoingQueueRefillEngine.",
|
||||
"Experimental.",
|
||||
HandleOqreCommand);
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (IsRunning)
|
||||
return;
|
||||
|
||||
IsRunning = true;
|
||||
|
||||
m_finishedProcessingAfterStop.Reset();
|
||||
|
||||
m_requestQueue = new BlockingCollection<RefillRequest>(new ConcurrentQueue<RefillRequest>(), 5000);
|
||||
|
||||
m_oqreRequestsWaitingStat =
|
||||
new Stat(
|
||||
"OQRERequestsWaiting",
|
||||
"Number of outgong queue refill requests waiting for processing.",
|
||||
"",
|
||||
"",
|
||||
"clientstack",
|
||||
m_udpServer.Scene.Name,
|
||||
StatType.Pull,
|
||||
MeasuresOfInterest.None,
|
||||
stat => stat.Value = m_requestQueue.Count,
|
||||
StatVerbosity.Debug);
|
||||
|
||||
StatsManager.RegisterStat(m_oqreRequestsWaitingStat);
|
||||
|
||||
Watchdog.StartThread(
|
||||
ProcessRequests,
|
||||
String.Format("OutgoingQueueRefillEngineThread ({0})", m_udpServer.Scene.Name),
|
||||
ThreadPriority.Normal,
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
int.MaxValue);
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!IsRunning)
|
||||
return;
|
||||
|
||||
IsRunning = false;
|
||||
|
||||
int requestsLeft = m_requestQueue.Count;
|
||||
|
||||
if (requestsLeft <= 0)
|
||||
{
|
||||
m_cancelSource.Cancel();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.InfoFormat("[OUTGOING QUEUE REFILL ENGINE]: Waiting to write {0} events after stop.", requestsLeft);
|
||||
|
||||
while (requestsLeft > 0)
|
||||
{
|
||||
if (!m_finishedProcessingAfterStop.WaitOne(RequestProcessTimeoutOnStop))
|
||||
{
|
||||
// After timeout no events have been written
|
||||
if (requestsLeft == m_requestQueue.Count)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[OUTGOING QUEUE REFILL ENGINE]: No requests processed after {0} ms wait. Discarding remaining {1} requests",
|
||||
RequestProcessTimeoutOnStop, requestsLeft);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
requestsLeft = m_requestQueue.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_cancelSource.Dispose();
|
||||
StatsManager.DeregisterStat(m_oqreRequestsWaitingStat);
|
||||
m_oqreRequestsWaitingStat = null;
|
||||
m_requestQueue = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool QueueRequest(LLUDPClient client, ThrottleOutPacketTypeFlags categories)
|
||||
{
|
||||
if (m_requestQueue.Count < m_requestQueue.BoundedCapacity)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[OUTGOING QUEUE REFILL ENGINE]: Adding request for categories {0} for {1} in {2}",
|
||||
// categories, client.AgentID, m_udpServer.Scene.Name);
|
||||
|
||||
m_requestQueue.Add(new RefillRequest(client, categories));
|
||||
|
||||
if (!m_warnOverMaxQueue)
|
||||
m_warnOverMaxQueue = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_warnOverMaxQueue)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[OUTGOING QUEUE REFILL ENGINE]: Request queue at maximum capacity, not recording request from {0} in {1}",
|
||||
client.AgentID, m_udpServer.Scene.Name);
|
||||
|
||||
m_warnOverMaxQueue = false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessRequests()
|
||||
{
|
||||
try
|
||||
{
|
||||
while (IsRunning || m_requestQueue.Count > 0)
|
||||
{
|
||||
RefillRequest req = m_requestQueue.Take(m_cancelSource.Token);
|
||||
|
||||
// QueueEmpty callback = req.Client.OnQueueEmpty;
|
||||
//
|
||||
// if (callback != null)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// callback(req.Categories);
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// m_log.Error("[OUTGOING QUEUE REFILL ENGINE]: ProcessRequests(" + req.Categories + ") threw an exception: " + e.Message, e);
|
||||
// }
|
||||
// }
|
||||
|
||||
req.Client.FireQueueEmpty(req.Categories);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
}
|
||||
|
||||
m_finishedProcessingAfterStop.Set();
|
||||
}
|
||||
|
||||
private void HandleOqreCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
|
||||
return;
|
||||
|
||||
if (args.Length != 4)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug lludp oqre <stop|start|status>");
|
||||
return;
|
||||
}
|
||||
|
||||
string subCommand = args[3];
|
||||
|
||||
if (subCommand == "stop")
|
||||
{
|
||||
Stop();
|
||||
MainConsole.Instance.OutputFormat("Stopped OQRE for {0}", m_udpServer.Scene.Name);
|
||||
}
|
||||
else if (subCommand == "start")
|
||||
{
|
||||
Start();
|
||||
MainConsole.Instance.OutputFormat("Started OQRE for {0}", m_udpServer.Scene.Name);
|
||||
}
|
||||
else if (subCommand == "status")
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("OQRE in {0}", m_udpServer.Scene.Name);
|
||||
MainConsole.Instance.OutputFormat("Running: {0}", IsRunning);
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Requests waiting: {0}", IsRunning ? m_requestQueue.Count.ToString() : "n/a");
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("Unrecognized OQRE subcommand {0}", subCommand);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -690,7 +690,14 @@ namespace pCampBot
|
|||
{
|
||||
lock (m_bots)
|
||||
{
|
||||
m_bots.ForEach(b => b.SitOnGround());
|
||||
foreach (Bot bot in m_bots)
|
||||
{
|
||||
if (bot.ConnectionState == ConnectionState.Connected)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("Sitting bot {0} on ground.", bot.Name);
|
||||
bot.SitOnGround();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -698,7 +705,14 @@ namespace pCampBot
|
|||
{
|
||||
lock (m_bots)
|
||||
{
|
||||
m_bots.ForEach(b => b.Stand());
|
||||
foreach (Bot bot in m_bots)
|
||||
{
|
||||
if (bot.ConnectionState == ConnectionState.Connected)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("Standing bot {0} from ground.", bot.Name);
|
||||
bot.Stand();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue