29 using System.Collections;
30 using System.Collections.Generic;
32 using System.Reflection;
38 using OpenSim.Framework;
39 using OpenSim.Framework.Console;
40 using OpenSim.Framework.Servers;
41 using OpenSim.Framework.Servers.HttpServer;
42 using OpenSim.Region.Framework.Interfaces;
43 using OpenSim.Region.Framework.Scenes;
48 [Extension(Path =
"/OpenSim/RegionModules", NodeName =
"RegionModule", Id =
"CapabilitiesModule")]
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53 private string m_showCapsCommandFormat =
" {0,-38} {1,-60}\n";
60 protected Dictionary<uint, Caps> m_capsObjects =
new Dictionary<uint, Caps>();
62 protected Dictionary<UUID, string> m_capsPaths =
new Dictionary<UUID, string>();
64 protected Dictionary<UUID, Dictionary<ulong, string>> m_childrenSeeds
65 =
new Dictionary<UUID, Dictionary<ulong, string>>();
76 MainConsole.Instance.Commands.AddCommand(
77 "Comms",
false,
"show caps list",
79 "Shows list of registered capabilities for users.", HandleShowCapsListCommand);
81 MainConsole.Instance.Commands.AddCommand(
82 "Comms",
false,
"show caps stats by user",
83 "show caps stats by user [<first-name> <last-name>]",
84 "Shows statistics on capabilities use by user.",
85 "If a user name is given, then prints a detailed breakdown of caps use ordered by number of requests received.",
86 HandleShowCapsStatsByUserCommand);
88 MainConsole.Instance.Commands.AddCommand(
89 "Comms",
false,
"show caps stats by cap",
90 "show caps stats by cap [<cap-name>]",
91 "Shows statistics on capabilities use by capability.",
92 "If a capability name is given, then prints a detailed breakdown of use by each user.",
93 HandleShowCapsStatsByCapCommand);
113 get {
return "Capabilities Module"; }
116 public Type ReplaceableInterface
123 int ts = Util.EnvironmentTickCount();
134 String capsObjectPath = GetCapsPath(agentId);
138 if (m_capsObjects.ContainsKey(circuitCode))
140 Caps oldCaps = m_capsObjects[circuitCode];
143 if (capsObjectPath == oldCaps.CapsObjectPath)
146 "[CAPS]: Reusing caps for agent {0} in region {1}. Old caps path {2}, new caps path {3}. ",
147 agentId, m_scene.RegionInfo.RegionName, oldCaps.CapsObjectPath, capsObjectPath);
155 oldCaps.DeregisterHandlers();
159 m_capsObjects.Remove(circuitCode);
169 capsObjectPath, agentId, m_scene.RegionInfo.RegionName);
171 m_log.DebugFormat(
"[CreateCaps]: new caps agent {0}, circuit {1}, path {2}, time {3} ",agentId,
172 circuitCode,caps.CapsObjectPath, Util.EnvironmentTickCountSubtract(ts));
174 m_capsObjects[circuitCode] = caps;
176 m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps);
183 m_log.DebugFormat(
"[CAPS]: Remove caps for agent {0} in region {1}", agentId, m_scene.RegionInfo.RegionName);
184 lock (m_childrenSeeds)
186 if (m_childrenSeeds.ContainsKey(agentId))
188 m_childrenSeeds.Remove(agentId);
194 if (m_capsObjects.ContainsKey(circuitCode))
196 m_capsObjects[circuitCode].DeregisterHandlers();
197 m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[circuitCode]);
198 m_capsObjects.Remove(circuitCode);
202 foreach (KeyValuePair<uint, Caps> kvp
in m_capsObjects)
204 if (kvp.Value.AgentID == agentId)
206 kvp.Value.DeregisterHandlers();
207 m_scene.EventManager.TriggerOnDeregisterCaps(agentId, kvp.Value);
208 m_capsObjects.Remove(kvp.Key);
213 "[CAPS]: Received request to remove CAPS handler for root agent {0} in {1}, but no such CAPS handler found!",
214 agentId, m_scene.RegionInfo.RegionName);
223 if (m_capsObjects.ContainsKey(circuitCode))
225 return m_capsObjects[circuitCode];
236 if (m_capsObjects.ContainsKey(circuitCode))
238 m_capsObjects[circuitCode].Activate();
246 m_capsPaths[agent.AgentID] = agent.CapsPath;
248 lock (m_childrenSeeds)
249 m_childrenSeeds[agent.AgentID]
250 = ((agent.ChildrenCapSeeds == null) ?
new Dictionary<ulong, string>() : agent.ChildrenCapSeeds);
257 if (m_capsPaths.ContainsKey(agentId))
259 return m_capsPaths[agentId];
268 Dictionary<ulong, string> seeds = null;
270 lock (m_childrenSeeds)
271 if (m_childrenSeeds.TryGetValue(agentID, out seeds))
274 return new Dictionary<ulong, string>();
279 Dictionary<ulong, string> seeds;
281 lock (m_childrenSeeds)
283 if (m_childrenSeeds.TryGetValue(agentID, out seeds))
285 seeds.Remove(handle);
292 Dictionary<ulong, string> seeds;
295 lock (m_childrenSeeds)
297 if (m_childrenSeeds.TryGetValue(agentID, out seeds))
299 if (seeds.TryGetValue(handle, out returnval))
311 lock (m_childrenSeeds)
312 m_childrenSeeds[agentID] = seeds;
317 m_log.Info(
"================ ChildrenSeed "+m_scene.RegionInfo.RegionName+
" ================");
319 lock (m_childrenSeeds)
321 foreach (KeyValuePair<ulong, string> kvp
in m_childrenSeeds[agentID])
324 Util.RegionHandleToRegionLoc(kvp.Key, out x, out y);
325 m_log.Info(
" >> "+x+
", "+y+
": "+kvp.Value);
330 private void HandleShowCapsListCommand(
string module,
string[] cmdParams)
335 StringBuilder capsReport =
new StringBuilder();
336 capsReport.AppendFormat(
"Region {0}:\n", m_scene.RegionInfo.RegionName);
340 foreach (KeyValuePair<uint, Caps> kvp
in m_capsObjects)
342 capsReport.AppendFormat(
"** Circuit {0}:\n", kvp.Key);
343 Caps caps = kvp.Value;
345 for (IDictionaryEnumerator kvp2 = caps.CapsHandlers.GetCapsDetails(
false, null).GetEnumerator(); kvp2.MoveNext(); )
347 Uri uri =
new Uri(kvp2.Value.ToString());
348 capsReport.AppendFormat(m_showCapsCommandFormat, kvp2.Key, uri.PathAndQuery);
351 foreach (KeyValuePair<string, PollServiceEventArgs> kvp2
in caps.GetPollHandlers())
352 capsReport.AppendFormat(m_showCapsCommandFormat, kvp2.Key, kvp2.Value.Url);
354 foreach (KeyValuePair<string, string> kvp3
in caps.ExternalCapsHandlers)
355 capsReport.AppendFormat(m_showCapsCommandFormat, kvp3.Key, kvp3.Value);
359 MainConsole.Instance.Output(capsReport.ToString());
362 private void HandleShowCapsStatsByCapCommand(
string module,
string[] cmdParams)
367 if (cmdParams.Length != 5 && cmdParams.Length != 6)
369 MainConsole.Instance.Output(
"Usage: show caps stats by cap [<cap-name>]");
373 StringBuilder sb =
new StringBuilder();
374 sb.AppendFormat(
"Region {0}:\n", m_scene.Name);
376 if (cmdParams.Length == 5)
378 BuildSummaryStatsByCapReport(sb);
380 else if (cmdParams.Length == 6)
382 BuildDetailedStatsByCapReport(sb, cmdParams[5]);
385 MainConsole.Instance.Output(sb.ToString());
388 private void BuildDetailedStatsByCapReport(StringBuilder sb,
string capName)
439 private void BuildSummaryStatsByCapReport(StringBuilder sb)
501 private void HandleShowCapsStatsByUserCommand(
string module,
string[] cmdParams)
537 private void BuildDetailedStatsByUserReport(StringBuilder sb,
ScenePresence sp)
568 private void BuildSummaryStatsByUserReport(StringBuilder sb)
613 private class CapTableRow
615 public string Name {
get; set; }
616 public int RequestsReceived {
get; set; }
617 public int RequestsHandled {
get; set; }
619 public CapTableRow(
string name,
int requestsReceived,
int requestsHandled)
622 RequestsReceived = requestsReceived;
623 RequestsHandled = requestsHandled;
void DumpChildrenSeeds(UUID agentID)
Caps GetCapsForUser(uint circuitCode)
Will return null if the agent doesn't have a caps handler registered
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
void SetAgentCapsSeeds(AgentCircuitData agent)
string GetCapsPath(UUID agentId)
string GetChildSeed(UUID agentID, ulong handle)
static SceneManager Instance
OpenSim.Framework.Capabilities.Caps Caps
void Initialise(IConfigSource source)
This is called to initialize the region module. For shared modules, this is called exactly once...
Circuit data for an agent. Connection information shared between regions that accept UDP connections ...
OpenSim.Framework.Capabilities.Caps Caps
Manager for adding, closing and restarting scenes.
Scene CurrentScene
Scene selected from the console.
Interactive OpenSim region server
void RemoveCaps(UUID agentId, uint circuitCode)
Remove the caps handler for a given agent.
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
static BaseHttpServer Instance
Set the main HTTP server instance.
void DropChildSeed(UUID agentID, ulong handle)
void ActivateCaps(uint circuitCode)
Dictionary< ulong, string > GetChildrenSeeds(UUID agentID)
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
void CreateCaps(UUID agentId, uint circuitCode)
Add a caps handler for the given agent. If the CAPS handler already exists for this agent...
void SetChildrenSeed(UUID agentID, Dictionary< ulong, string > seeds)