OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
ActiveConnectionsAJAX.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using System;
29 using System.Collections;
30 using System.Collections.Generic;
31 using System.Reflection;
32 using System.Text;
33 using Mono.Data.SqliteClient;
34 using OpenMetaverse;
35 using OpenMetaverse.StructuredData;
36 using OpenSim.Framework;
37 using OpenSim.Region.Framework.Scenes;
38 using OpenSim.Framework.Monitoring;
39 
40 namespace OpenSim.Region.UserStatistics
41 {
43  {
44  private Vector3 DefaultNeighborPosition = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 70);
45 
46  #region IStatsController Members
47 
48  public string ReportName
49  {
50  get { return ""; }
51  }
52 
53  public Hashtable ProcessModel(Hashtable pParams)
54  {
55  List<Scene> m_scene = (List<Scene>)pParams["Scenes"];
56 
57  Hashtable nh = new Hashtable();
58  nh.Add("hdata", m_scene);
59 
60  return nh;
61  }
62 
63  public string RenderView(Hashtable pModelResult)
64  {
65  List<Scene> all_scenes = (List<Scene>) pModelResult["hdata"];
66 
67  StringBuilder output = new StringBuilder();
68  HTMLUtil.OL_O(ref output, "");
69  foreach (Scene scene in all_scenes)
70  {
71  HTMLUtil.LI_O(ref output, String.Empty);
72  output.Append(scene.RegionInfo.RegionName);
73  HTMLUtil.OL_O(ref output, String.Empty);
74  scene.ForEachScenePresence(delegate(ScenePresence av)
75  {
76  Dictionary<string, string> queues = new Dictionary<string, string>();
78  {
79  IStatsCollector isClient = (IStatsCollector)av.ControllingClient;
80  queues = decodeQueueReport(isClient.Report());
81  }
82  HTMLUtil.LI_O(ref output, String.Empty);
83  output.Append(av.Name);
84  output.Append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
85  output.Append((av.IsChildAgent ? "Child" : "Root"));
86  if (av.AbsolutePosition == DefaultNeighborPosition)
87  {
88  output.Append("<br />Position: ?");
89  }
90  else
91  {
92  output.Append(string.Format("<br /><NOBR>Position: <{0},{1},{2}></NOBR>", (int)av.AbsolutePosition.X,
93  (int)av.AbsolutePosition.Y,
94  (int)av.AbsolutePosition.Z));
95  }
96  Dictionary<string, int> throttles = DecodeClientThrottles(av.ControllingClient.GetThrottlesPacked(1));
97 
98  HTMLUtil.UL_O(ref output, String.Empty);
99 
100  foreach (string throttlename in throttles.Keys)
101  {
102  HTMLUtil.LI_O(ref output, String.Empty);
103  output.Append(throttlename);
104  output.Append(":");
105  output.Append(throttles[throttlename].ToString());
106  if (queues.ContainsKey(throttlename))
107  {
108  output.Append("/");
109  output.Append(queues[throttlename]);
110  }
111  HTMLUtil.LI_C(ref output);
112  }
113  if (queues.ContainsKey("Incoming") && queues.ContainsKey("Outgoing"))
114  {
115  HTMLUtil.LI_O(ref output, "red");
116  output.Append("SEND:");
117  output.Append(queues["Outgoing"]);
118  output.Append("/");
119  output.Append(queues["Incoming"]);
120  HTMLUtil.LI_C(ref output);
121  }
122 
123  HTMLUtil.UL_C(ref output);
124  HTMLUtil.LI_C(ref output);
125  });
126  HTMLUtil.OL_C(ref output);
127  }
128  HTMLUtil.OL_C(ref output);
129  return output.ToString();
130  }
131 
154  public string RenderJson(Hashtable pModelResult)
155  {
156  List<Scene> all_scenes = (List<Scene>) pModelResult["hdata"];
157 
158  OSDMap regionInfo = new OSDMap();
159  foreach (Scene scene in all_scenes)
160  {
161  OSDMap sceneInfo = new OpenMetaverse.StructuredData.OSDMap();
162  List<ScenePresence> avatarInScene = scene.GetScenePresences();
163  foreach (ScenePresence av in avatarInScene)
164  {
165  OSDMap presenceInfo = new OSDMap();
166  presenceInfo.Add("Name", new OSDString(av.Name));
167 
168  Dictionary<string,string> queues = new Dictionary<string, string>();
170  {
171  IStatsCollector isClient = (IStatsCollector) av.ControllingClient;
172  queues = decodeQueueReport(isClient.Report());
173  }
174  OSDMap queueInfo = new OpenMetaverse.StructuredData.OSDMap();
175  foreach (KeyValuePair<string, string> kvp in queues) {
176  queueInfo.Add(kvp.Key, new OSDString(kvp.Value));
177  }
178  sceneInfo.Add("queues", queueInfo);
179 
180  if (av.IsChildAgent)
181  presenceInfo.Add("isRoot", new OSDString("false"));
182  else
183  presenceInfo.Add("isRoot", new OSDString("true"));
184 
185  if (av.AbsolutePosition == DefaultNeighborPosition)
186  {
187  presenceInfo.Add("position", new OSDString("<0, 0, 0>"));
188  }
189  else
190  {
191  presenceInfo.Add("position", new OSDString(string.Format("<{0},{1},{2}>",
192  (int)av.AbsolutePosition.X,
193  (int) av.AbsolutePosition.Y,
194  (int) av.AbsolutePosition.Z)) );
195  }
196 
197  Dictionary<string, int> throttles = DecodeClientThrottles(av.ControllingClient.GetThrottlesPacked(1));
198  OSDMap throttleInfo = new OpenMetaverse.StructuredData.OSDMap();
199  foreach (string throttlename in throttles.Keys)
200  {
201  throttleInfo.Add(throttlename, new OSDString(throttles[throttlename].ToString()));
202  }
203  presenceInfo.Add("throttle", throttleInfo);
204 
205  sceneInfo.Add(av.Name, presenceInfo);
206  }
207  regionInfo.Add(scene.RegionInfo.RegionName, sceneInfo);
208  }
209  return regionInfo.ToString();
210  }
211 
212  public Dictionary<string, int> DecodeClientThrottles(byte[] throttle)
213  {
214  Dictionary<string, int> returndict = new Dictionary<string, int>();
215  // From mantis http://opensimulator.org/mantis/view.php?id=1374
216  // it appears that sometimes we are receiving empty throttle byte arrays.
217  // TODO: Investigate this behaviour
218  if (throttle.Length == 0)
219  {
220  return new Dictionary<string, int>();
221  }
222 
223  int tResend = -1;
224  int tLand = -1;
225  int tWind = -1;
226  int tCloud = -1;
227  int tTask = -1;
228  int tTexture = -1;
229  int tAsset = -1;
230  int tall = -1;
231  const int singlefloat = 4;
232 
233  //Agent Throttle Block contains 7 single floatingpoint values.
234  int j = 0;
235 
236  // Some Systems may be big endian...
237  // it might be smart to do this check more often...
238  if (!BitConverter.IsLittleEndian)
239  for (int i = 0; i < 7; i++)
240  Array.Reverse(throttle, j + i * singlefloat, singlefloat);
241 
242  // values gotten from OpenMetaverse.org/wiki/Throttle. Thanks MW_
243  // bytes
244  // Convert to integer, since.. the full fp space isn't used.
245  tResend = (int)BitConverter.ToSingle(throttle, j);
246  returndict.Add("Resend", tResend);
247  j += singlefloat;
248  tLand = (int)BitConverter.ToSingle(throttle, j);
249  returndict.Add("Land", tLand);
250  j += singlefloat;
251  tWind = (int)BitConverter.ToSingle(throttle, j);
252  returndict.Add("Wind", tWind);
253  j += singlefloat;
254  tCloud = (int)BitConverter.ToSingle(throttle, j);
255  returndict.Add("Cloud", tCloud);
256  j += singlefloat;
257  tTask = (int)BitConverter.ToSingle(throttle, j);
258  returndict.Add("Task", tTask);
259  j += singlefloat;
260  tTexture = (int)BitConverter.ToSingle(throttle, j);
261  returndict.Add("Texture", tTexture);
262  j += singlefloat;
263  tAsset = (int)BitConverter.ToSingle(throttle, j);
264  returndict.Add("Asset", tAsset);
265 
266  tall = tResend + tLand + tWind + tCloud + tTask + tTexture + tAsset;
267  returndict.Add("All", tall);
268 
269  return returndict;
270  }
271  public Dictionary<string,string> decodeQueueReport(string rep)
272  {
273  Dictionary<string, string> returndic = new Dictionary<string, string>();
274  if (rep.Length == 79)
275  {
276  int pos = 1;
277  returndic.Add("All", rep.Substring((6 * pos), 8)); pos++;
278  returndic.Add("Incoming", rep.Substring((7 * pos), 8)); pos++;
279  returndic.Add("Outgoing", rep.Substring((7 * pos) , 8)); pos++;
280  returndic.Add("Resend", rep.Substring((7 * pos) , 8)); pos++;
281  returndic.Add("Land", rep.Substring((7 * pos) , 8)); pos++;
282  returndic.Add("Wind", rep.Substring((7 * pos) , 8)); pos++;
283  returndic.Add("Cloud", rep.Substring((7 * pos) , 8)); pos++;
284  returndic.Add("Task", rep.Substring((7 * pos) , 8)); pos++;
285  returndic.Add("Texture", rep.Substring((7 * pos), 8)); pos++;
286  returndic.Add("Asset", rep.Substring((7 * pos), 8));
287  /*
288  * return string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}",
289  SendQueue.Count(),
290  IncomingPacketQueue.Count,
291  OutgoingPacketQueue.Count,
292  ResendOutgoingPacketQueue.Count,
293  LandOutgoingPacketQueue.Count,
294  WindOutgoingPacketQueue.Count,
295  CloudOutgoingPacketQueue.Count,
296  TaskOutgoingPacketQueue.Count,
297  TextureOutgoingPacketQueue.Count,
298  AssetOutgoingPacketQueue.Count);
299  */
300  }
301 
302 
303 
304  return returndic;
305  }
306  #endregion
307  }
308 }
Implemented by classes which collect up non-viewer statistical information
OpenMetaverse.StructuredData.OSDMap OSDMap
string Report()
Report back collected statistical information.
byte[] GetThrottlesPacked(float multiplier)
override Vector3 AbsolutePosition
Position of this avatar relative to the region the avatar is in
string RenderJson(Hashtable pModelResult)
Convert active connections information to JSON string. Returns a structure:
Interactive OpenSim region server
Definition: OpenSim.cs:55
Dictionary< string, string > decodeQueueReport(string rep)
virtual string Name
The name of this entity
Definition: EntityBase.cs:65
Dictionary< string, int > DecodeClientThrottles(byte[] throttle)