WebStatsModule.cs 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253
  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. using System;
  28. using System.Collections;
  29. using System.Collections.Generic;
  30. using System.IO;
  31. using System.Net; // to be used for REST-->Grid shortly
  32. using System.Reflection;
  33. using System.Text;
  34. using System.Threading;
  35. using log4net;
  36. using Nini.Config;
  37. using OpenMetaverse;
  38. using OpenMetaverse.StructuredData;
  39. using OpenSim.Framework;
  40. using OpenSim.Framework.Servers;
  41. using OpenSim.Region.Framework.Interfaces;
  42. using OpenSim.Region.Framework.Scenes;
  43. using Mono.Data.SqliteClient;
  44. using Caps = OpenSim.Framework.Communications.Capabilities.Caps;
  45. using OSD = OpenMetaverse.StructuredData.OSD;
  46. using OSDMap = OpenMetaverse.StructuredData.OSDMap;
  47. namespace OpenSim.Region.UserStatistics
  48. {
  49. public class WebStatsModule : IRegionModule
  50. {
  51. private static readonly ILog m_log =
  52. LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  53. private static SqliteConnection dbConn;
  54. private Dictionary<UUID, UserSessionID> m_sessions = new Dictionary<UUID, UserSessionID>();
  55. private List<Scene> m_scene = new List<Scene>();
  56. private Dictionary<string, IStatsController> reports = new Dictionary<string, IStatsController>();
  57. private Dictionary<UUID, USimStatsData> m_simstatsCounters = new Dictionary<UUID, USimStatsData>();
  58. private const int updateStatsMod = 6;
  59. private int updateLogMod = 1;
  60. private volatile int updateLogCounter = 0;
  61. private volatile int concurrencyCounter = 0;
  62. private bool enabled = false;
  63. private string m_loglines = String.Empty;
  64. private volatile int lastHit = 12000;
  65. public virtual void Initialise(Scene scene, IConfigSource config)
  66. {
  67. IConfig cnfg;
  68. try
  69. {
  70. cnfg = config.Configs["WebStats"];
  71. enabled = cnfg.GetBoolean("enabled", false);
  72. }
  73. catch (Exception)
  74. {
  75. enabled = false;
  76. }
  77. if (!enabled)
  78. {
  79. return;
  80. }
  81. lock (m_scene)
  82. {
  83. if (m_scene.Count == 0)
  84. {
  85. //IConfig startupConfig = config.Configs["Startup"];
  86. dbConn = new SqliteConnection("URI=file:LocalUserStatistics.db,version=3");
  87. dbConn.Open();
  88. CheckAndUpdateDatabase(dbConn);
  89. Default_Report rep = new Default_Report();
  90. Prototype_distributor protodep = new Prototype_distributor();
  91. Updater_distributor updatedep = new Updater_distributor();
  92. ActiveConnectionsAJAX ajConnections = new ActiveConnectionsAJAX();
  93. SimStatsAJAX ajSimStats = new SimStatsAJAX();
  94. LogLinesAJAX ajLogLines = new LogLinesAJAX();
  95. Clients_report clientReport = new Clients_report();
  96. Sessions_Report sessionsReport = new Sessions_Report();
  97. reports.Add("", rep);
  98. reports.Add("prototype.js", protodep);
  99. reports.Add("updater.js", updatedep);
  100. reports.Add("activeconnectionsajax.ajax", ajConnections);
  101. reports.Add("simstatsajax.ajax", ajSimStats);
  102. reports.Add("activelogajax.ajax", ajLogLines);
  103. reports.Add("clients.report", clientReport);
  104. reports.Add("sessions.report", sessionsReport);
  105. ////
  106. // Add Your own Reports here (Do Not Modify Lines here Devs!)
  107. ////
  108. ////
  109. // End Own reports section
  110. ////
  111. scene.CommsManager.HttpServer.AddHTTPHandler("/SStats/", HandleStatsRequest);
  112. scene.CommsManager.HttpServer.AddHTTPHandler("/CAPS/VS/", HandleUnknownCAPSRequest);
  113. }
  114. m_scene.Add(scene);
  115. m_simstatsCounters.Add(scene.RegionInfo.RegionID, new USimStatsData(scene.RegionInfo.RegionID));
  116. scene.StatsReporter.OnSendStatsResult += ReceiveClassicSimStatsPacket;
  117. }
  118. }
  119. public void ReceiveClassicSimStatsPacket(SimStats stats)
  120. {
  121. if (!enabled)
  122. {
  123. return;
  124. }
  125. try
  126. {
  127. // Ignore the update if there's a report running right now
  128. // ignore the update if there hasn't been a hit in 30 seconds.
  129. if (concurrencyCounter > 0 || System.Environment.TickCount - lastHit > 30000)
  130. return;
  131. if ((updateLogCounter++ % updateLogMod) == 0)
  132. {
  133. m_loglines = readLogLines(10);
  134. if (updateLogCounter > 10000) updateLogCounter = 1;
  135. }
  136. USimStatsData ss = m_simstatsCounters[stats.RegionUUID];
  137. if ((++ss.StatsCounter % updateStatsMod) == 0)
  138. {
  139. ss.ConsumeSimStats(stats);
  140. }
  141. }
  142. catch (KeyNotFoundException)
  143. {
  144. }
  145. }
  146. public Hashtable HandleUnknownCAPSRequest(Hashtable request)
  147. {
  148. //string regpath = request["uri"].ToString();
  149. int response_code = 200;
  150. string contenttype = "text/html";
  151. UpdateUserStats(ParseViewerStats(request["body"].ToString(), UUID.Zero), dbConn);
  152. Hashtable responsedata = new Hashtable();
  153. responsedata["int_response_code"] = response_code;
  154. responsedata["content_type"] = contenttype;
  155. responsedata["keepalive"] = false;
  156. responsedata["str_response_string"] = string.Empty;
  157. return responsedata;
  158. }
  159. public Hashtable HandleStatsRequest(Hashtable request)
  160. {
  161. lastHit = System.Environment.TickCount;
  162. Hashtable responsedata = new Hashtable();
  163. string regpath = request["uri"].ToString();
  164. int response_code = 404;
  165. string contenttype = "text/html";
  166. string strOut = string.Empty;
  167. regpath = regpath.Remove(0, 8);
  168. if (reports.ContainsKey(regpath))
  169. {
  170. IStatsController rep = reports[regpath];
  171. Hashtable repParams = new Hashtable();
  172. if (request.ContainsKey("requestvars"))
  173. repParams["RequestVars"] = request["requestvars"];
  174. else
  175. repParams["RequestVars"] = new Hashtable();
  176. if (request.ContainsKey("querystringkeys"))
  177. repParams["QueryStringKeys"] = request["querystringkeys"];
  178. else
  179. repParams["QueryStringKeys"] = new string[0];
  180. repParams["DatabaseConnection"] = dbConn;
  181. repParams["Scenes"] = m_scene;
  182. repParams["SimStats"] = m_simstatsCounters;
  183. repParams["LogLines"] = m_loglines;
  184. repParams["Reports"] = reports;
  185. concurrencyCounter++;
  186. strOut = rep.RenderView(rep.ProcessModel(repParams));
  187. if (regpath.EndsWith("js"))
  188. {
  189. contenttype = "text/javascript";
  190. }
  191. concurrencyCounter--;
  192. response_code = 200;
  193. }
  194. else
  195. {
  196. strOut = m_scene[0].CommsManager.HttpServer.GetHTTP404("");
  197. }
  198. responsedata["int_response_code"] = response_code;
  199. responsedata["content_type"] = contenttype;
  200. responsedata["keepalive"] = false;
  201. responsedata["str_response_string"] = strOut;
  202. return responsedata;
  203. }
  204. public void CheckAndUpdateDatabase(SqliteConnection db)
  205. {
  206. lock (db)
  207. {
  208. // TODO: FIXME: implement stats migrations
  209. const string SQL = @"SELECT * FROM migrations LIMIT 1";
  210. SqliteCommand cmd = new SqliteCommand(SQL, db);
  211. try
  212. {
  213. cmd.ExecuteNonQuery();
  214. }
  215. catch (SqliteSyntaxException)
  216. {
  217. CreateTables(db);
  218. }
  219. }
  220. }
  221. public void CreateTables(SqliteConnection db)
  222. {
  223. SqliteCommand createcmd = new SqliteCommand(SQL_STATS_TABLE_CREATE, db);
  224. createcmd.ExecuteNonQuery();
  225. createcmd.CommandText = SQL_MIGRA_TABLE_CREATE;
  226. createcmd.ExecuteNonQuery();
  227. }
  228. public virtual void PostInitialise()
  229. {
  230. if (!enabled)
  231. {
  232. return;
  233. }
  234. AddHandlers();
  235. }
  236. public virtual void Close()
  237. {
  238. if (!enabled)
  239. {
  240. return;
  241. }
  242. dbConn.Close();
  243. dbConn.Dispose();
  244. }
  245. public virtual string Name
  246. {
  247. get { return "ViewerStatsModule"; }
  248. }
  249. public bool IsSharedModule
  250. {
  251. get { return true; }
  252. }
  253. public void OnRegisterCaps(UUID agentID, Caps caps)
  254. {
  255. m_log.DebugFormat("[VC]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps);
  256. string capsPath = "/CAPS/VS/" + UUID.Random();
  257. caps.RegisterHandler("ViewerStats",
  258. new RestStreamHandler("POST", capsPath,
  259. delegate(string request, string path, string param,
  260. OSHttpRequest httpRequest, OSHttpResponse httpResponse)
  261. {
  262. return ViewerStatsReport(request, path, param,
  263. agentID, caps);
  264. }));
  265. }
  266. public void OnDeRegisterCaps(UUID agentID, Caps caps)
  267. {
  268. }
  269. protected virtual void AddHandlers()
  270. {
  271. lock (m_scene)
  272. {
  273. updateLogMod = m_scene.Count * 2;
  274. foreach (Scene scene in m_scene)
  275. {
  276. scene.EventManager.OnRegisterCaps += OnRegisterCaps;
  277. scene.EventManager.OnDeregisterCaps += OnDeRegisterCaps;
  278. scene.EventManager.OnClientClosed += OnClientClosed;
  279. scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
  280. scene.EventManager.OnMakeChildAgent += OnMakeChildAgent;
  281. }
  282. }
  283. }
  284. public void OnMakeRootAgent(ScenePresence agent)
  285. {
  286. UUID regionUUID = GetRegionUUIDFromHandle(agent.RegionHandle);
  287. lock (m_sessions)
  288. {
  289. if (!m_sessions.ContainsKey(agent.UUID))
  290. {
  291. UserSessionData usd = UserSessionUtil.newUserSessionData();
  292. UserSessionID uid = new UserSessionID();
  293. uid.name_f = agent.Firstname;
  294. uid.name_l = agent.Lastname;
  295. uid.region_id = regionUUID;
  296. uid.session_id = agent.ControllingClient.SessionId;
  297. uid.session_data = usd;
  298. m_sessions.Add(agent.UUID, uid);
  299. }
  300. else
  301. {
  302. UserSessionID uid = m_sessions[agent.UUID];
  303. uid.region_id = regionUUID;
  304. uid.session_id = agent.ControllingClient.SessionId;
  305. m_sessions[agent.UUID] = uid;
  306. }
  307. }
  308. }
  309. public void OnMakeChildAgent(ScenePresence agent)
  310. {
  311. }
  312. public void OnClientClosed(UUID agentID)
  313. {
  314. lock (m_sessions)
  315. {
  316. if (m_sessions.ContainsKey(agentID))
  317. {
  318. m_sessions.Remove(agentID);
  319. }
  320. }
  321. }
  322. public string readLogLines( int amount)
  323. {
  324. Encoding encoding = Encoding.ASCII;
  325. int sizeOfChar = encoding.GetByteCount("\n");
  326. byte[] buffer = encoding.GetBytes("\n");
  327. string logfile = Util.logDir() + "/" + "OpenSim.log";
  328. FileStream fs = new FileStream(logfile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
  329. Int64 tokenCount = 0;
  330. Int64 endPosition = fs.Length / sizeOfChar;
  331. for (Int64 position = sizeOfChar; position < endPosition; position += sizeOfChar)
  332. {
  333. fs.Seek(-position, SeekOrigin.End);
  334. fs.Read(buffer, 0, buffer.Length);
  335. if (encoding.GetString(buffer) == "\n")
  336. {
  337. tokenCount++;
  338. if (tokenCount == amount)
  339. {
  340. byte[] returnBuffer = new byte[fs.Length - fs.Position];
  341. fs.Read(returnBuffer, 0, returnBuffer.Length);
  342. fs.Close();
  343. fs.Dispose();
  344. return encoding.GetString(returnBuffer);
  345. }
  346. }
  347. }
  348. // handle case where number of tokens in file is less than numberOfTokens
  349. fs.Seek(0, SeekOrigin.Begin);
  350. buffer = new byte[fs.Length];
  351. fs.Read(buffer, 0, buffer.Length);
  352. fs.Close();
  353. fs.Dispose();
  354. return encoding.GetString(buffer);
  355. }
  356. public UUID GetRegionUUIDFromHandle(ulong regionhandle)
  357. {
  358. lock (m_scene)
  359. {
  360. foreach (Scene scene in m_scene)
  361. {
  362. if (scene.RegionInfo.RegionHandle == regionhandle)
  363. return scene.RegionInfo.RegionID;
  364. }
  365. }
  366. return UUID.Zero;
  367. }
  368. /// <summary>
  369. /// Callback for a viewerstats cap
  370. /// </summary>
  371. /// <param name="request"></param>
  372. /// <param name="path"></param>
  373. /// <param name="param"></param>
  374. /// <param name="agentID"></param>
  375. /// <param name="caps"></param>
  376. /// <returns></returns>
  377. public string ViewerStatsReport(string request, string path, string param,
  378. UUID agentID, Caps caps)
  379. {
  380. //m_log.Debug(request);
  381. UpdateUserStats(ParseViewerStats(request,agentID), dbConn);
  382. return String.Empty;
  383. }
  384. public UserSessionID ParseViewerStats(string request, UUID agentID)
  385. {
  386. UserSessionID uid = new UserSessionID();
  387. UserSessionData usd;
  388. OSD message = OSDParser.DeserializeLLSDXml(request);
  389. OSDMap mmap;
  390. lock (m_sessions)
  391. {
  392. if (agentID != UUID.Zero)
  393. {
  394. if (!m_sessions.ContainsKey(agentID))
  395. {
  396. m_log.Warn("[VS]: no session for stat disclosure");
  397. return new UserSessionID();
  398. }
  399. uid = m_sessions[agentID];
  400. }
  401. else
  402. {
  403. // parse through the beginning to locate the session
  404. if (message.Type != OSDType.Map)
  405. return new UserSessionID();
  406. mmap = (OSDMap)message;
  407. {
  408. UUID sessionID = mmap["session_id"].AsUUID();
  409. if (sessionID == UUID.Zero)
  410. return new UserSessionID();
  411. // search through each session looking for the owner
  412. foreach (UUID usersessionid in m_sessions.Keys)
  413. {
  414. // got it!
  415. if (m_sessions[usersessionid].session_id == sessionID)
  416. {
  417. agentID = usersessionid;
  418. uid = m_sessions[usersessionid];
  419. break;
  420. }
  421. }
  422. // can't find a session
  423. if (agentID == UUID.Zero)
  424. {
  425. return new UserSessionID();
  426. }
  427. }
  428. }
  429. }
  430. usd = uid.session_data;
  431. if (message.Type != OSDType.Map)
  432. return new UserSessionID();
  433. mmap = (OSDMap)message;
  434. {
  435. if (mmap["agent"].Type != OSDType.Map)
  436. return new UserSessionID();
  437. OSDMap agent_map = (OSDMap)mmap["agent"];
  438. usd.agent_id = agentID;
  439. usd.name_f = uid.name_f;
  440. usd.name_l = uid.name_l;
  441. usd.region_id = uid.region_id;
  442. usd.a_language = agent_map["language"].AsString();
  443. usd.mem_use = (float)agent_map["mem_use"].AsReal();
  444. usd.meters_traveled = (float)agent_map["meters_traveled"].AsReal();
  445. usd.regions_visited = agent_map["regions_visited"].AsInteger();
  446. usd.run_time = (float)agent_map["run_time"].AsReal();
  447. usd.start_time = (float)agent_map["start_time"].AsReal();
  448. usd.client_version = agent_map["version"].AsString();
  449. UserSessionUtil.UpdateMultiItems(ref usd, agent_map["agents_in_view"].AsInteger(),
  450. (float)agent_map["ping"].AsReal(),
  451. (float)agent_map["sim_fps"].AsReal(),
  452. (float)agent_map["fps"].AsReal());
  453. if (mmap["downloads"].Type != OSDType.Map)
  454. return new UserSessionID();
  455. OSDMap downloads_map = (OSDMap)mmap["downloads"];
  456. usd.d_object_kb = (float)downloads_map["object_kbytes"].AsReal();
  457. usd.d_texture_kb = (float)downloads_map["texture_kbytes"].AsReal();
  458. usd.d_world_kb = (float)downloads_map["workd_kbytes"].AsReal();
  459. usd.session_id = mmap["session_id"].AsUUID();
  460. if (mmap["system"].Type != OSDType.Map)
  461. return new UserSessionID();
  462. OSDMap system_map = (OSDMap)mmap["system"];
  463. usd.s_cpu = system_map["cpu"].AsString();
  464. usd.s_gpu = system_map["gpu"].AsString();
  465. usd.s_os = system_map["os"].AsString();
  466. usd.s_ram = system_map["ram"].AsInteger();
  467. if (mmap["stats"].Type != OSDType.Map)
  468. return new UserSessionID();
  469. OSDMap stats_map = (OSDMap)mmap["stats"];
  470. {
  471. if (stats_map["failures"].Type != OSDType.Map)
  472. return new UserSessionID();
  473. OSDMap stats_failures = (OSDMap)stats_map["failures"];
  474. usd.f_dropped = stats_failures["dropped"].AsInteger();
  475. usd.f_failed_resends = stats_failures["failed_resends"].AsInteger();
  476. usd.f_invalid = stats_failures["invalid"].AsInteger();
  477. usd.f_resent = stats_failures["resent"].AsInteger();
  478. usd.f_send_packet = stats_failures["send_packet"].AsInteger();
  479. if (stats_map["net"].Type != OSDType.Map)
  480. return new UserSessionID();
  481. OSDMap stats_net = (OSDMap)stats_map["net"];
  482. {
  483. if (stats_net["in"].Type != OSDType.Map)
  484. return new UserSessionID();
  485. OSDMap net_in = (OSDMap)stats_net["in"];
  486. usd.n_in_kb = (float)net_in["kbytes"].AsReal();
  487. usd.n_in_pk = net_in["packets"].AsInteger();
  488. if (stats_net["out"].Type != OSDType.Map)
  489. return new UserSessionID();
  490. OSDMap net_out = (OSDMap)stats_net["out"];
  491. usd.n_out_kb = (float)net_out["kbytes"].AsReal();
  492. usd.n_out_pk = net_out["packets"].AsInteger();
  493. }
  494. }
  495. }
  496. uid.session_data = usd;
  497. m_sessions[agentID] = uid;
  498. return uid;
  499. }
  500. public void UpdateUserStats(UserSessionID uid, SqliteConnection db)
  501. {
  502. if (uid.session_id == UUID.Zero)
  503. return;
  504. lock (db)
  505. {
  506. SqliteCommand updatecmd = new SqliteCommand(SQL_STATS_TABLE_UPDATE, db);
  507. updatecmd.Parameters.Add(new SqliteParameter(":session_id", uid.session_data.session_id.ToString()));
  508. updatecmd.Parameters.Add(new SqliteParameter(":agent_id", uid.session_data.agent_id.ToString()));
  509. updatecmd.Parameters.Add(new SqliteParameter(":region_id", uid.session_data.region_id.ToString()));
  510. updatecmd.Parameters.Add(new SqliteParameter(":last_updated", (int) uid.session_data.last_updated));
  511. updatecmd.Parameters.Add(new SqliteParameter(":remote_ip", uid.session_data.remote_ip));
  512. updatecmd.Parameters.Add(new SqliteParameter(":name_f", uid.session_data.name_f));
  513. updatecmd.Parameters.Add(new SqliteParameter(":name_l", uid.session_data.name_l));
  514. updatecmd.Parameters.Add(new SqliteParameter(":avg_agents_in_view", uid.session_data.avg_agents_in_view));
  515. updatecmd.Parameters.Add(new SqliteParameter(":min_agents_in_view",
  516. (int) uid.session_data.min_agents_in_view));
  517. updatecmd.Parameters.Add(new SqliteParameter(":max_agents_in_view",
  518. (int) uid.session_data.max_agents_in_view));
  519. updatecmd.Parameters.Add(new SqliteParameter(":mode_agents_in_view",
  520. (int) uid.session_data.mode_agents_in_view));
  521. updatecmd.Parameters.Add(new SqliteParameter(":avg_fps", uid.session_data.avg_fps));
  522. updatecmd.Parameters.Add(new SqliteParameter(":min_fps", uid.session_data.min_fps));
  523. updatecmd.Parameters.Add(new SqliteParameter(":max_fps", uid.session_data.max_fps));
  524. updatecmd.Parameters.Add(new SqliteParameter(":mode_fps", uid.session_data.mode_fps));
  525. updatecmd.Parameters.Add(new SqliteParameter(":a_language", uid.session_data.a_language));
  526. updatecmd.Parameters.Add(new SqliteParameter(":mem_use", uid.session_data.mem_use));
  527. updatecmd.Parameters.Add(new SqliteParameter(":meters_traveled", uid.session_data.meters_traveled));
  528. updatecmd.Parameters.Add(new SqliteParameter(":avg_ping", uid.session_data.avg_ping));
  529. updatecmd.Parameters.Add(new SqliteParameter(":min_ping", uid.session_data.min_ping));
  530. updatecmd.Parameters.Add(new SqliteParameter(":max_ping", uid.session_data.max_ping));
  531. updatecmd.Parameters.Add(new SqliteParameter(":mode_ping", uid.session_data.mode_ping));
  532. updatecmd.Parameters.Add(new SqliteParameter(":regions_visited", uid.session_data.regions_visited));
  533. updatecmd.Parameters.Add(new SqliteParameter(":run_time", uid.session_data.run_time));
  534. updatecmd.Parameters.Add(new SqliteParameter(":avg_sim_fps", uid.session_data.avg_sim_fps));
  535. updatecmd.Parameters.Add(new SqliteParameter(":min_sim_fps", uid.session_data.min_sim_fps));
  536. updatecmd.Parameters.Add(new SqliteParameter(":max_sim_fps", uid.session_data.max_sim_fps));
  537. updatecmd.Parameters.Add(new SqliteParameter(":mode_sim_fps", uid.session_data.mode_sim_fps));
  538. updatecmd.Parameters.Add(new SqliteParameter(":start_time", uid.session_data.start_time));
  539. updatecmd.Parameters.Add(new SqliteParameter(":client_version", uid.session_data.client_version));
  540. updatecmd.Parameters.Add(new SqliteParameter(":s_cpu", uid.session_data.s_cpu));
  541. updatecmd.Parameters.Add(new SqliteParameter(":s_gpu", uid.session_data.s_gpu));
  542. updatecmd.Parameters.Add(new SqliteParameter(":s_os", uid.session_data.s_os));
  543. updatecmd.Parameters.Add(new SqliteParameter(":s_ram", uid.session_data.s_ram));
  544. updatecmd.Parameters.Add(new SqliteParameter(":d_object_kb", uid.session_data.d_object_kb));
  545. updatecmd.Parameters.Add(new SqliteParameter(":d_texture_kb", uid.session_data.d_texture_kb));
  546. updatecmd.Parameters.Add(new SqliteParameter(":d_world_kb", uid.session_data.d_world_kb));
  547. updatecmd.Parameters.Add(new SqliteParameter(":n_in_kb", uid.session_data.n_in_kb));
  548. updatecmd.Parameters.Add(new SqliteParameter(":n_in_pk", uid.session_data.n_in_pk));
  549. updatecmd.Parameters.Add(new SqliteParameter(":n_out_kb", uid.session_data.n_out_kb));
  550. updatecmd.Parameters.Add(new SqliteParameter(":n_out_pk", uid.session_data.n_out_pk));
  551. updatecmd.Parameters.Add(new SqliteParameter(":f_dropped", uid.session_data.f_dropped));
  552. updatecmd.Parameters.Add(new SqliteParameter(":f_failed_resends", uid.session_data.f_failed_resends));
  553. updatecmd.Parameters.Add(new SqliteParameter(":f_invalid", uid.session_data.f_invalid));
  554. updatecmd.Parameters.Add(new SqliteParameter(":f_off_circuit", uid.session_data.f_off_circuit));
  555. updatecmd.Parameters.Add(new SqliteParameter(":f_resent", uid.session_data.f_resent));
  556. updatecmd.Parameters.Add(new SqliteParameter(":f_send_packet", uid.session_data.f_send_packet));
  557. updatecmd.Parameters.Add(new SqliteParameter(":session_key", uid.session_data.session_id.ToString()));
  558. updatecmd.Parameters.Add(new SqliteParameter(":agent_key", uid.session_data.agent_id.ToString()));
  559. updatecmd.Parameters.Add(new SqliteParameter(":region_key", uid.session_data.region_id.ToString()));
  560. m_log.Debug("UPDATE");
  561. int result = updatecmd.ExecuteNonQuery();
  562. if (result == 0)
  563. {
  564. m_log.Debug("INSERT");
  565. updatecmd.CommandText = SQL_STATS_TABLE_INSERT;
  566. updatecmd.ExecuteNonQuery();
  567. }
  568. }
  569. }
  570. #region SQL
  571. private const string SQL_MIGRA_TABLE_CREATE = @"create table migrations(name varchar(100), version int)";
  572. private const string SQL_STATS_TABLE_CREATE = @"CREATE TABLE stats_session_data (
  573. session_id VARCHAR(36) NOT NULL PRIMARY KEY,
  574. agent_id VARCHAR(36) NOT NULL DEFAULT '',
  575. region_id VARCHAR(36) NOT NULL DEFAULT '',
  576. last_updated INT NOT NULL DEFAULT '0',
  577. remote_ip VARCHAR(16) NOT NULL DEFAULT '',
  578. name_f VARCHAR(50) NOT NULL DEFAULT '',
  579. name_l VARCHAR(50) NOT NULL DEFAULT '',
  580. avg_agents_in_view FLOAT NOT NULL DEFAULT '0',
  581. min_agents_in_view INT NOT NULL DEFAULT '0',
  582. max_agents_in_view INT NOT NULL DEFAULT '0',
  583. mode_agents_in_view INT NOT NULL DEFAULT '0',
  584. avg_fps FLOAT NOT NULL DEFAULT '0',
  585. min_fps FLOAT NOT NULL DEFAULT '0',
  586. max_fps FLOAT NOT NULL DEFAULT '0',
  587. mode_fps FLOAT NOT NULL DEFAULT '0',
  588. a_language VARCHAR(25) NOT NULL DEFAULT '',
  589. mem_use FLOAT NOT NULL DEFAULT '0',
  590. meters_traveled FLOAT NOT NULL DEFAULT '0',
  591. avg_ping FLOAT NOT NULL DEFAULT '0',
  592. min_ping FLOAT NOT NULL DEFAULT '0',
  593. max_ping FLOAT NOT NULL DEFAULT '0',
  594. mode_ping FLOAT NOT NULL DEFAULT '0',
  595. regions_visited INT NOT NULL DEFAULT '0',
  596. run_time FLOAT NOT NULL DEFAULT '0',
  597. avg_sim_fps FLOAT NOT NULL DEFAULT '0',
  598. min_sim_fps FLOAT NOT NULL DEFAULT '0',
  599. max_sim_fps FLOAT NOT NULL DEFAULT '0',
  600. mode_sim_fps FLOAT NOT NULL DEFAULT '0',
  601. start_time FLOAT NOT NULL DEFAULT '0',
  602. client_version VARCHAR(255) NOT NULL DEFAULT '',
  603. s_cpu VARCHAR(255) NOT NULL DEFAULT '',
  604. s_gpu VARCHAR(255) NOT NULL DEFAULT '',
  605. s_os VARCHAR(2255) NOT NULL DEFAULT '',
  606. s_ram INT NOT NULL DEFAULT '0',
  607. d_object_kb FLOAT NOT NULL DEFAULT '0',
  608. d_texture_kb FLOAT NOT NULL DEFAULT '0',
  609. d_world_kb FLOAT NOT NULL DEFAULT '0',
  610. n_in_kb FLOAT NOT NULL DEFAULT '0',
  611. n_in_pk INT NOT NULL DEFAULT '0',
  612. n_out_kb FLOAT NOT NULL DEFAULT '0',
  613. n_out_pk INT NOT NULL DEFAULT '0',
  614. f_dropped INT NOT NULL DEFAULT '0',
  615. f_failed_resends INT NOT NULL DEFAULT '0',
  616. f_invalid INT NOT NULL DEFAULT '0',
  617. f_off_circuit INT NOT NULL DEFAULT '0',
  618. f_resent INT NOT NULL DEFAULT '0',
  619. f_send_packet INT NOT NULL DEFAULT '0'
  620. );";
  621. private const string SQL_STATS_TABLE_INSERT = @"INSERT INTO stats_session_data (
  622. session_id, agent_id, region_id, last_updated, remote_ip, name_f, name_l, avg_agents_in_view, min_agents_in_view, max_agents_in_view,
  623. mode_agents_in_view, avg_fps, min_fps, max_fps, mode_fps, a_language, mem_use, meters_traveled, avg_ping, min_ping, max_ping, mode_ping,
  624. regions_visited, run_time, avg_sim_fps, min_sim_fps, max_sim_fps, mode_sim_fps, start_time, client_version, s_cpu, s_gpu, s_os, s_ram,
  625. d_object_kb, d_texture_kb, n_in_kb, n_in_pk, n_out_kb, n_out_pk, f_dropped, f_failed_resends, f_invalid, f_invalid, f_off_circuit,
  626. f_resent, f_send_packet
  627. )
  628. VALUES
  629. (
  630. :session_id, :agent_id, :region_id, :last_updated, :remote_ip, :name_f, :name_l, :avg_agents_in_view, :min_agents_in_view, :max_agents_in_view,
  631. :mode_agents_in_view, :avg_fps, :min_fps, :max_fps, :mode_fps, :a_language, :mem_use, :meters_traveled, :avg_ping, :min_ping, :max_ping, :mode_ping,
  632. :regions_visited, :run_time, :avg_sim_fps, :min_sim_fps, :max_sim_fps, :mode_sim_fps, :start_time, :client_version, :s_cpu, :s_gpu, :s_os, :s_ram,
  633. :d_object_kb, :d_texture_kb, :n_in_kb, :n_in_pk, :n_out_kb, :n_out_pk, :f_dropped, :f_failed_resends, :f_invalid, :f_invalid, :f_off_circuit,
  634. :f_resent, :f_send_packet
  635. )
  636. ";
  637. private const string SQL_STATS_TABLE_UPDATE = @"
  638. UPDATE stats_session_data
  639. set session_id=:session_id,
  640. agent_id=:agent_id,
  641. region_id=:region_id,
  642. last_updated=:last_updated,
  643. remote_ip=:remote_ip,
  644. name_f=:name_f,
  645. name_l=:name_l,
  646. avg_agents_in_view=:avg_agents_in_view,
  647. min_agents_in_view=:min_agents_in_view,
  648. max_agents_in_view=:max_agents_in_view,
  649. mode_agents_in_view=:mode_agents_in_view,
  650. avg_fps=:avg_fps,
  651. min_fps=:min_fps,
  652. max_fps=:max_fps,
  653. mode_fps=:mode_fps,
  654. a_language=:a_language,
  655. mem_use=:mem_use,
  656. meters_traveled=:meters_traveled,
  657. avg_ping=:avg_ping,
  658. min_ping=:min_ping,
  659. max_ping=:max_ping,
  660. mode_ping=:mode_ping,
  661. regions_visited=:regions_visited,
  662. run_time=:run_time,
  663. avg_sim_fps=:avg_sim_fps,
  664. min_sim_fps=:min_sim_fps,
  665. max_sim_fps=:max_sim_fps,
  666. mode_sim_fps=:mode_sim_fps,
  667. start_time=:start_time,
  668. client_version=:client_version,
  669. s_cpu=:s_cpu,
  670. s_gpu=:s_gpu,
  671. s_os=:s_os,
  672. s_ram=:s_ram,
  673. d_object_kb=:d_object_kb,
  674. d_texture_kb=:d_texture_kb,
  675. d_world_kb=:d_world_kb,
  676. n_in_kb=:n_in_kb,
  677. n_in_pk=:n_in_pk,
  678. n_out_kb=:n_out_kb,
  679. n_out_pk=:n_out_pk,
  680. f_dropped=:f_dropped,
  681. f_failed_resends=:f_failed_resends,
  682. f_invalid=:f_invalid,
  683. f_off_circuit=:f_off_circuit,
  684. f_resent=:f_resent,
  685. f_send_packet=:f_send_packet
  686. WHERE session_id=:session_key AND agent_id=:agent_key AND region_id=:region_key";
  687. #endregion
  688. }
  689. public static class UserSessionUtil
  690. {
  691. public static UserSessionData newUserSessionData()
  692. {
  693. UserSessionData obj = ZeroSession(new UserSessionData());
  694. return obj;
  695. }
  696. public static void UpdateMultiItems(ref UserSessionData s, int agents_in_view, float ping, float sim_fps, float fps)
  697. {
  698. // don't insert zero values here or it'll skew the statistics.
  699. if (agents_in_view == 0 && fps == 0 && sim_fps == 0 && ping == 0)
  700. return;
  701. s._agents_in_view.Add(agents_in_view);
  702. s._fps.Add(fps);
  703. s._sim_fps.Add(sim_fps);
  704. s._ping.Add(ping);
  705. int[] __agents_in_view = s._agents_in_view.ToArray();
  706. s.avg_agents_in_view = ArrayAvg_i(__agents_in_view);
  707. s.min_agents_in_view = ArrayMin_i(__agents_in_view);
  708. s.max_agents_in_view = ArrayMax_i(__agents_in_view);
  709. s.mode_agents_in_view = ArrayMode_i(__agents_in_view);
  710. float[] __fps = s._fps.ToArray();
  711. s.avg_fps = ArrayAvg_f(__fps);
  712. s.min_fps = ArrayMin_f(__fps);
  713. s.max_fps = ArrayMax_f(__fps);
  714. s.mode_fps = ArrayMode_f(__fps);
  715. float[] __sim_fps = s._sim_fps.ToArray();
  716. s.avg_sim_fps = ArrayAvg_f(__sim_fps);
  717. s.min_sim_fps = ArrayMin_f(__sim_fps);
  718. s.max_sim_fps = ArrayMax_f(__sim_fps);
  719. s.mode_sim_fps = ArrayMode_f(__sim_fps);
  720. float[] __ping = s._ping.ToArray();
  721. s.avg_ping = ArrayAvg_f(__ping);
  722. s.min_ping = ArrayMin_f(__ping);
  723. s.max_ping = ArrayMax_f(__ping);
  724. s.mode_ping = ArrayMode_f(__ping);
  725. }
  726. #region Statistics
  727. public static int ArrayMin_i(int[] arr)
  728. {
  729. int cnt = arr.Length;
  730. if (cnt == 0)
  731. return 0;
  732. Array.Sort(arr);
  733. return arr[0];
  734. }
  735. public static int ArrayMax_i(int[] arr)
  736. {
  737. int cnt = arr.Length;
  738. if (cnt == 0)
  739. return 0;
  740. Array.Sort(arr);
  741. return arr[cnt-1];
  742. }
  743. public static float ArrayMin_f(float[] arr)
  744. {
  745. int cnt = arr.Length;
  746. if (cnt == 0)
  747. return 0;
  748. Array.Sort(arr);
  749. return arr[0];
  750. }
  751. public static float ArrayMax_f(float[] arr)
  752. {
  753. int cnt = arr.Length;
  754. if (cnt == 0)
  755. return 0;
  756. Array.Sort(arr);
  757. return arr[cnt - 1];
  758. }
  759. public static float ArrayAvg_i(int[] arr)
  760. {
  761. int cnt = arr.Length;
  762. if (cnt == 0)
  763. return 0;
  764. float result = arr[0];
  765. for (int i = 1; i < cnt; i++)
  766. result += arr[i];
  767. return result / cnt;
  768. }
  769. public static float ArrayAvg_f(float[] arr)
  770. {
  771. int cnt = arr.Length;
  772. if (cnt == 0)
  773. return 0;
  774. float result = arr[0];
  775. for (int i = 1; i < cnt; i++)
  776. result += arr[i];
  777. return result / cnt;
  778. }
  779. public static float ArrayMode_f(float[] arr)
  780. {
  781. List<float> mode = new List<float>();
  782. float[] srtArr = new float[arr.Length];
  783. float[,] freq = new float[arr.Length, 2];
  784. Array.Copy(arr, srtArr, arr.Length);
  785. Array.Sort(srtArr);
  786. float tmp = srtArr[0];
  787. int index = 0;
  788. int i = 0;
  789. while (i < srtArr.Length)
  790. {
  791. freq[index, 0] = tmp;
  792. while (tmp == srtArr[i])
  793. {
  794. freq[index, 1]++;
  795. i++;
  796. if (i > srtArr.Length - 1)
  797. break;
  798. }
  799. if (i < srtArr.Length)
  800. {
  801. tmp = srtArr[i];
  802. index++;
  803. }
  804. }
  805. Array.Clear(srtArr, 0, srtArr.Length);
  806. for (i = 0; i < srtArr.Length; i++)
  807. srtArr[i] = freq[i, 1];
  808. Array.Sort(srtArr);
  809. if ((srtArr[srtArr.Length - 1]) == 0 || (srtArr[srtArr.Length - 1]) == 1)
  810. return 0;
  811. float freqtest = (float)freq.Length / freq.Rank;
  812. for (i = 0; i < freqtest; i++)
  813. {
  814. if (freq[i, 1] == srtArr[index])
  815. mode.Add(freq[i, 0]);
  816. }
  817. return mode.ToArray()[0];
  818. }
  819. public static int ArrayMode_i(int[] arr)
  820. {
  821. List<int> mode = new List<int>();
  822. int[] srtArr = new int[arr.Length];
  823. int[,] freq = new int[arr.Length, 2];
  824. Array.Copy(arr, srtArr, arr.Length);
  825. Array.Sort(srtArr);
  826. int tmp = srtArr[0];
  827. int index = 0;
  828. int i = 0;
  829. while (i < srtArr.Length)
  830. {
  831. freq[index, 0] = tmp;
  832. while (tmp == srtArr[i])
  833. {
  834. freq[index, 1]++;
  835. i++;
  836. if (i > srtArr.Length - 1)
  837. break;
  838. }
  839. if (i < srtArr.Length)
  840. {
  841. tmp = srtArr[i];
  842. index++;
  843. }
  844. }
  845. Array.Clear(srtArr, 0, srtArr.Length);
  846. for (i = 0; i < srtArr.Length; i++)
  847. srtArr[i] = freq[i, 1];
  848. Array.Sort(srtArr);
  849. if ((srtArr[srtArr.Length - 1]) == 0 || (srtArr[srtArr.Length - 1]) == 1)
  850. return 0;
  851. float freqtest = (float)freq.Length / freq.Rank;
  852. for (i = 0; i < freqtest; i++)
  853. {
  854. if (freq[i, 1] == srtArr[index])
  855. mode.Add(freq[i, 0]);
  856. }
  857. return mode.ToArray()[0];
  858. }
  859. #endregion
  860. private static UserSessionData ZeroSession(UserSessionData s)
  861. {
  862. s.session_id = UUID.Zero;
  863. s.agent_id = UUID.Zero;
  864. s.region_id = UUID.Zero;
  865. s.last_updated = Util.UnixTimeSinceEpoch();
  866. s.remote_ip = "";
  867. s.name_f = "";
  868. s.name_l = "";
  869. s.avg_agents_in_view = 0;
  870. s.min_agents_in_view = 0;
  871. s.max_agents_in_view = 0;
  872. s.mode_agents_in_view = 0;
  873. s.avg_fps = 0;
  874. s.min_fps = 0;
  875. s.max_fps = 0;
  876. s.mode_fps = 0;
  877. s.a_language = "";
  878. s.mem_use = 0;
  879. s.meters_traveled = 0;
  880. s.avg_ping = 0;
  881. s.min_ping = 0;
  882. s.max_ping = 0;
  883. s.mode_ping = 0;
  884. s.regions_visited = 0;
  885. s.run_time = 0;
  886. s.avg_sim_fps = 0;
  887. s.min_sim_fps = 0;
  888. s.max_sim_fps = 0;
  889. s.mode_sim_fps = 0;
  890. s.start_time = 0;
  891. s.client_version = "";
  892. s.s_cpu = "";
  893. s.s_gpu = "";
  894. s.s_os = "";
  895. s.s_ram = 0;
  896. s.d_object_kb = 0;
  897. s.d_texture_kb = 0;
  898. s.d_world_kb = 0;
  899. s.n_in_kb = 0;
  900. s.n_in_pk = 0;
  901. s.n_out_kb = 0;
  902. s.n_out_pk = 0;
  903. s.f_dropped = 0;
  904. s.f_failed_resends = 0;
  905. s.f_invalid = 0;
  906. s.f_off_circuit = 0;
  907. s.f_resent = 0;
  908. s.f_send_packet = 0;
  909. s._ping = new List<float>();
  910. s._fps = new List<float>();
  911. s._sim_fps = new List<float>();
  912. s._agents_in_view = new List<int>();
  913. return s;
  914. }
  915. }
  916. #region structs
  917. public struct UserSessionID
  918. {
  919. public UUID session_id;
  920. public UUID region_id;
  921. public string name_f;
  922. public string name_l;
  923. public UserSessionData session_data;
  924. }
  925. public struct UserSessionData
  926. {
  927. public UUID session_id;
  928. public UUID agent_id;
  929. public UUID region_id;
  930. public float last_updated;
  931. public string remote_ip;
  932. public string name_f;
  933. public string name_l;
  934. public float avg_agents_in_view;
  935. public float min_agents_in_view;
  936. public float max_agents_in_view;
  937. public float mode_agents_in_view;
  938. public float avg_fps;
  939. public float min_fps;
  940. public float max_fps;
  941. public float mode_fps;
  942. public string a_language;
  943. public float mem_use;
  944. public float meters_traveled;
  945. public float avg_ping;
  946. public float min_ping;
  947. public float max_ping;
  948. public float mode_ping;
  949. public int regions_visited;
  950. public float run_time;
  951. public float avg_sim_fps;
  952. public float min_sim_fps;
  953. public float max_sim_fps;
  954. public float mode_sim_fps;
  955. public float start_time;
  956. public string client_version;
  957. public string s_cpu;
  958. public string s_gpu;
  959. public string s_os;
  960. public int s_ram;
  961. public float d_object_kb;
  962. public float d_texture_kb;
  963. public float d_world_kb;
  964. public float n_in_kb;
  965. public int n_in_pk;
  966. public float n_out_kb;
  967. public int n_out_pk;
  968. public int f_dropped;
  969. public int f_failed_resends;
  970. public int f_invalid;
  971. public int f_off_circuit;
  972. public int f_resent;
  973. public int f_send_packet;
  974. public List<float> _ping;
  975. public List<float> _fps;
  976. public List<float> _sim_fps;
  977. public List<int> _agents_in_view;
  978. }
  979. #endregion
  980. public class USimStatsData
  981. {
  982. private UUID m_regionID = UUID.Zero;
  983. private volatile int m_statcounter = 0;
  984. private volatile float m_timeDilation;
  985. private volatile float m_simFps;
  986. private volatile float m_physicsFps;
  987. private volatile float m_agentUpdates;
  988. private volatile float m_rootAgents;
  989. private volatile float m_childAgents;
  990. private volatile float m_totalPrims;
  991. private volatile float m_activePrims;
  992. private volatile float m_totalFrameTime;
  993. private volatile float m_netFrameTime;
  994. private volatile float m_physicsFrameTime;
  995. private volatile float m_otherFrameTime;
  996. private volatile float m_imageFrameTime;
  997. private volatile float m_inPacketsPerSecond;
  998. private volatile float m_outPacketsPerSecond;
  999. private volatile float m_unackedBytes;
  1000. private volatile float m_agentFrameTime;
  1001. private volatile float m_pendingDownloads;
  1002. private volatile float m_pendingUploads;
  1003. private volatile float m_activeScripts;
  1004. private volatile float m_scriptLinesPerSecond;
  1005. public UUID RegionId { get { return m_regionID; } }
  1006. public int StatsCounter { get { return m_statcounter; } set { m_statcounter = value;}}
  1007. public float TimeDilation { get { return m_timeDilation; } }
  1008. public float SimFps { get { return m_simFps; } }
  1009. public float PhysicsFps { get { return m_physicsFps; } }
  1010. public float AgentUpdates { get { return m_agentUpdates; } }
  1011. public float RootAgents { get { return m_rootAgents; } }
  1012. public float ChildAgents { get { return m_childAgents; } }
  1013. public float TotalPrims { get { return m_totalPrims; } }
  1014. public float ActivePrims { get { return m_activePrims; } }
  1015. public float TotalFrameTime { get { return m_totalFrameTime; } }
  1016. public float NetFrameTime { get { return m_netFrameTime; } }
  1017. public float PhysicsFrameTime { get { return m_physicsFrameTime; } }
  1018. public float OtherFrameTime { get { return m_otherFrameTime; } }
  1019. public float ImageFrameTime { get { return m_imageFrameTime; } }
  1020. public float InPacketsPerSecond { get { return m_inPacketsPerSecond; } }
  1021. public float OutPacketsPerSecond { get { return m_outPacketsPerSecond; } }
  1022. public float UnackedBytes { get { return m_unackedBytes; } }
  1023. public float AgentFrameTime { get { return m_agentFrameTime; } }
  1024. public float PendingDownloads { get { return m_pendingDownloads; } }
  1025. public float PendingUploads { get { return m_pendingUploads; } }
  1026. public float ActiveScripts { get { return m_activeScripts; } }
  1027. public float ScriptLinesPerSecond { get { return m_scriptLinesPerSecond; } }
  1028. public USimStatsData(UUID pRegionID)
  1029. {
  1030. m_regionID = pRegionID;
  1031. }
  1032. public void ConsumeSimStats(SimStats stats)
  1033. {
  1034. m_regionID = stats.RegionUUID;
  1035. m_timeDilation = stats.StatsBlock[0].StatValue;
  1036. m_simFps = stats.StatsBlock[1].StatValue;
  1037. m_physicsFps = stats.StatsBlock[2].StatValue;
  1038. m_agentUpdates = stats.StatsBlock[3].StatValue;
  1039. m_rootAgents = stats.StatsBlock[4].StatValue;
  1040. m_childAgents = stats.StatsBlock[5].StatValue;
  1041. m_totalPrims = stats.StatsBlock[6].StatValue;
  1042. m_activePrims = stats.StatsBlock[7].StatValue;
  1043. m_totalFrameTime = stats.StatsBlock[8].StatValue;
  1044. m_netFrameTime = stats.StatsBlock[9].StatValue;
  1045. m_physicsFrameTime = stats.StatsBlock[10].StatValue;
  1046. m_otherFrameTime = stats.StatsBlock[11].StatValue;
  1047. m_imageFrameTime = stats.StatsBlock[12].StatValue;
  1048. m_inPacketsPerSecond = stats.StatsBlock[13].StatValue;
  1049. m_outPacketsPerSecond = stats.StatsBlock[14].StatValue;
  1050. m_unackedBytes = stats.StatsBlock[15].StatValue;
  1051. m_agentFrameTime = stats.StatsBlock[16].StatValue;
  1052. m_pendingDownloads = stats.StatsBlock[17].StatValue;
  1053. m_pendingUploads = stats.StatsBlock[18].StatValue;
  1054. m_activeScripts = stats.StatsBlock[19].StatValue;
  1055. m_scriptLinesPerSecond = stats.StatsBlock[20].StatValue;
  1056. }
  1057. }
  1058. }