diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index addfe5d1af..e8f8e012de 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -451,6 +451,14 @@ namespace OpenSim.Framework return (x + y - (min >> 1) - (min >> 2) + (min >> 4)); } + /// + /// Are the co-ordinates of the new region visible from the old region? + /// + /// Old region x-coord + /// New region x-coord + /// Old region y-coord + /// New region y-coord + /// public static bool IsOutsideView(uint oldx, uint newx, uint oldy, uint newy) { // Eventually this will be a function of the draw distance / camera position too. diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index f80cb342af..2c920f6e0a 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -30,6 +30,7 @@ using System.Collections; using System.Collections.Generic; using System.IO; using System.Reflection; +using System.Text; using System.Timers; using log4net; using Nini.Config; @@ -285,16 +286,15 @@ namespace OpenSim m_console.Commands.AddCommand("region", false, "show users", "show users [full]", - "Show user data", HandleShow); + "Show user data for users currently on the region", + "Without the 'full' option, only users actually on the region are shown." + + " With the 'full' option child agents of users in neighbouring regions are also shown.", + HandleShow); m_console.Commands.AddCommand("region", false, "show connections", "show connections", "Show connection data", HandleShow); - m_console.Commands.AddCommand("region", false, "show users full", - "show users full", - String.Empty, HandleShow); - m_console.Commands.AddCommand("region", false, "show modules", "show modules", "Show module data", HandleShow); @@ -304,8 +304,12 @@ namespace OpenSim "Show region data", HandleShow); m_console.Commands.AddCommand("region", false, "show queues", - "show queues", - "Show queue data", HandleShow); + "show queues [full]", + "Show queue data for each client", + "Without the 'full' option, only users actually on the region are shown." + + " With the 'full' option child agents of users in neighbouring regions are also shown.", + HandleShow); + m_console.Commands.AddCommand("region", false, "show ratings", "show ratings", "Show rating data", HandleShow); @@ -876,7 +880,7 @@ namespace OpenSim { agents = m_sceneManager.GetCurrentSceneAvatars(); } - + MainConsole.Instance.Output(String.Format("\nAgents connected: {0}\n", agents.Count)); MainConsole.Instance.Output( @@ -953,7 +957,7 @@ namespace OpenSim break; case "queues": - Notice(GetQueuesReport()); + Notice(GetQueuesReport(showParams)); break; case "ratings": @@ -983,43 +987,91 @@ namespace OpenSim } /// - /// print UDP Queue data for each client + /// Generate UDP Queue data report for each client /// + /// /// - private string GetQueuesReport() + private string GetQueuesReport(string[] showParams) { - string report = String.Empty; + bool showChildren = false; + + if (showParams.Length > 1 && showParams[1] == "full") + showChildren = true; + + StringBuilder report = new StringBuilder(); + + int columnPadding = 2; + int maxNameLength = 18; + int maxRegionNameLength = 14; + int maxTypeLength = 4; + int totalInfoFieldsLength = maxNameLength + columnPadding + maxRegionNameLength + columnPadding + maxTypeLength + columnPadding; + + report.AppendFormat("{0,-" + maxNameLength + "}{1,-" + columnPadding + "}", "User", ""); + report.AppendFormat("{0,-" + maxRegionNameLength + "}{1,-" + columnPadding + "}", "Region", ""); + report.AppendFormat("{0,-" + maxTypeLength + "}{1,-" + columnPadding + "}", "Type", ""); + + report.AppendFormat( + "{0,9} {1,9} {2,9} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7} {10,7}\n", + "Packets", + "Packets", + "Bytes", + "Bytes", + "Bytes", + "Bytes", + "Bytes", + "Bytes", + "Bytes", + "Bytes", + "Bytes"); + + report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", ""); + report.AppendFormat( + "{0,9} {1,9} {2,9} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7} {10,7}\n", + "Out", + "In", + "Unacked", + "Resend", + "Land", + "Wind", + "Cloud", + "Task", + "Texture", + "Asset", + "State"); + + m_sceneManager.ForEachScene( + delegate(Scene scene) + { + scene.ForEachClient( + delegate(IClientAPI client) + { + if (client is IStatsCollector) + { + bool isChild = scene.PresenceChildStatus(client.AgentId); + if (isChild && !showChildren) + return; + + string name = client.Name; + string regionName = scene.RegionInfo.RegionName; + + report.AppendFormat( + "{0,-" + maxNameLength + "}{1,-" + columnPadding + "}", + name.Length > maxNameLength ? name.Substring(0, maxNameLength) : name, ""); + report.AppendFormat( + "{0,-" + maxRegionNameLength + "}{1,-" + columnPadding + "}", + regionName.Length > maxRegionNameLength ? regionName.Substring(0, maxRegionNameLength) : regionName, ""); + report.AppendFormat( + "{0,-" + maxTypeLength + "}{1,-" + columnPadding + "}", + isChild ? "Cd" : "Rt", ""); - m_sceneManager.ForEachScene(delegate(Scene scene) - { - scene.ForEachClient(delegate(IClientAPI client) - { - if (client is IStatsCollector) - { - report = report + client.FirstName + - " " + client.LastName; + IStatsCollector stats = (IStatsCollector)client; + + report.AppendLine(stats.Report()); + } + }); + }); - IStatsCollector stats = - (IStatsCollector) client; - - report = report + string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}\n", - "Send", - "In", - "Out", - "Resend", - "Land", - "Wind", - "Cloud", - "Task", - "Texture", - "Asset"); - report = report + stats.Report() + - "\n"; - } - }); - }); - - return report; + return report.ToString(); } /// diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index ca5a7bdc4b..c4db5da2da 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs @@ -246,11 +246,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP throw new NotImplementedException(); } + /// + /// Return statistics information about client packet queues. + /// + /// + /// FIXME: This should really be done in a more sensible manner rather than sending back a formatted string. + /// + /// public string GetStats() { - // TODO: ??? - return string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}", - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + return string.Format( + "{0,9} {1,9} {2,9} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7} {10,7}", + PacketsSent, + PacketsReceived, + UnackedBytes, + m_throttleCategories[(int)ThrottleOutPacketType.Resend].Content, + m_throttleCategories[(int)ThrottleOutPacketType.Land].Content, + m_throttleCategories[(int)ThrottleOutPacketType.Wind].Content, + m_throttleCategories[(int)ThrottleOutPacketType.Cloud].Content, + m_throttleCategories[(int)ThrottleOutPacketType.Task].Content, + m_throttleCategories[(int)ThrottleOutPacketType.Texture].Content, + m_throttleCategories[(int)ThrottleOutPacketType.Asset].Content, + m_throttleCategories[(int)ThrottleOutPacketType.State].Content); } public void SendPacketStats() diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index b5cab84e67..f02a9228e5 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1228,11 +1228,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } m_log.Debug("[ENTITY TRANSFER MODULE]: Completed inform client about neighbour " + endPoint.ToString()); - } - } + /// + /// Return the list of regions that are considered to be neighbours to the given scene. + /// + /// + /// + /// + /// protected List RequestNeighbours(Scene pScene, uint pRegionLocX, uint pRegionLocY) { RegionInfo m_regionInfo = pScene.RegionInfo;