diff options
Diffstat (limited to 'OpenSim/Region/UserStatistics/WebStatsModule.cs')
-rw-r--r-- | OpenSim/Region/UserStatistics/WebStatsModule.cs | 225 |
1 files changed, 128 insertions, 97 deletions
diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index c11ea02..b08233c 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs | |||
@@ -43,15 +43,20 @@ using OpenSim.Framework.Servers.HttpServer; | |||
43 | using OpenSim.Region.Framework.Interfaces; | 43 | using OpenSim.Region.Framework.Interfaces; |
44 | using OpenSim.Region.Framework.Scenes; | 44 | using OpenSim.Region.Framework.Scenes; |
45 | using Mono.Data.SqliteClient; | 45 | using Mono.Data.SqliteClient; |
46 | using Mono.Addins; | ||
46 | 47 | ||
47 | using Caps = OpenSim.Framework.Capabilities.Caps; | 48 | using Caps = OpenSim.Framework.Capabilities.Caps; |
48 | 49 | ||
49 | using OSD = OpenMetaverse.StructuredData.OSD; | 50 | using OSD = OpenMetaverse.StructuredData.OSD; |
50 | using OSDMap = OpenMetaverse.StructuredData.OSDMap; | 51 | using OSDMap = OpenMetaverse.StructuredData.OSDMap; |
51 | 52 | ||
53 | [assembly: Addin("WebStats", "1.0")] | ||
54 | [assembly: AddinDependency("OpenSim", "0.5")] | ||
55 | |||
52 | namespace OpenSim.Region.UserStatistics | 56 | namespace OpenSim.Region.UserStatistics |
53 | { | 57 | { |
54 | public class WebStatsModule : IRegionModule | 58 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WebStatsModule")] |
59 | public class WebStatsModule : ISharedRegionModule | ||
55 | { | 60 | { |
56 | private static readonly ILog m_log = | 61 | private static readonly ILog m_log = |
57 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 62 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
@@ -61,7 +66,7 @@ namespace OpenSim.Region.UserStatistics | |||
61 | /// <summary> | 66 | /// <summary> |
62 | /// User statistics sessions keyed by agent ID | 67 | /// User statistics sessions keyed by agent ID |
63 | /// </summary> | 68 | /// </summary> |
64 | private Dictionary<UUID, UserSessionID> m_sessions = new Dictionary<UUID, UserSessionID>(); | 69 | private Dictionary<UUID, UserSession> m_sessions = new Dictionary<UUID, UserSession>(); |
65 | 70 | ||
66 | private List<Scene> m_scenes = new List<Scene>(); | 71 | private List<Scene> m_scenes = new List<Scene>(); |
67 | private Dictionary<string, IStatsController> reports = new Dictionary<string, IStatsController>(); | 72 | private Dictionary<string, IStatsController> reports = new Dictionary<string, IStatsController>(); |
@@ -74,59 +79,69 @@ namespace OpenSim.Region.UserStatistics | |||
74 | private string m_loglines = String.Empty; | 79 | private string m_loglines = String.Empty; |
75 | private volatile int lastHit = 12000; | 80 | private volatile int lastHit = 12000; |
76 | 81 | ||
77 | public virtual void Initialise(Scene scene, IConfigSource config) | 82 | #region ISharedRegionModule |
83 | |||
84 | public virtual void Initialise(IConfigSource config) | ||
78 | { | 85 | { |
79 | IConfig cnfg = config.Configs["WebStats"]; | 86 | IConfig cnfg = config.Configs["WebStats"]; |
80 | 87 | ||
81 | if (cnfg != null) | 88 | if (cnfg != null) |
82 | enabled = cnfg.GetBoolean("enabled", false); | 89 | enabled = cnfg.GetBoolean("enabled", false); |
83 | 90 | } | |
91 | |||
92 | public virtual void PostInitialise() | ||
93 | { | ||
94 | if (!enabled) | ||
95 | return; | ||
96 | |||
97 | AddEventHandlers(); | ||
98 | |||
99 | if (Util.IsWindows()) | ||
100 | Util.LoadArchSpecificWindowsDll("sqlite3.dll"); | ||
101 | |||
102 | //IConfig startupConfig = config.Configs["Startup"]; | ||
103 | |||
104 | dbConn = new SqliteConnection("URI=file:LocalUserStatistics.db,version=3"); | ||
105 | dbConn.Open(); | ||
106 | CreateTables(dbConn); | ||
107 | |||
108 | Prototype_distributor protodep = new Prototype_distributor(); | ||
109 | Updater_distributor updatedep = new Updater_distributor(); | ||
110 | ActiveConnectionsAJAX ajConnections = new ActiveConnectionsAJAX(); | ||
111 | SimStatsAJAX ajSimStats = new SimStatsAJAX(); | ||
112 | LogLinesAJAX ajLogLines = new LogLinesAJAX(); | ||
113 | Default_Report defaultReport = new Default_Report(); | ||
114 | Clients_report clientReport = new Clients_report(); | ||
115 | Sessions_Report sessionsReport = new Sessions_Report(); | ||
116 | |||
117 | reports.Add("prototype.js", protodep); | ||
118 | reports.Add("updater.js", updatedep); | ||
119 | reports.Add("activeconnectionsajax.html", ajConnections); | ||
120 | reports.Add("simstatsajax.html", ajSimStats); | ||
121 | reports.Add("activelogajax.html", ajLogLines); | ||
122 | reports.Add("default.report", defaultReport); | ||
123 | reports.Add("clients.report", clientReport); | ||
124 | reports.Add("sessions.report", sessionsReport); | ||
125 | |||
126 | //// | ||
127 | // Add Your own Reports here (Do Not Modify Lines here Devs!) | ||
128 | //// | ||
129 | |||
130 | //// | ||
131 | // End Own reports section | ||
132 | //// | ||
133 | |||
134 | MainServer.Instance.AddHTTPHandler("/SStats/", HandleStatsRequest); | ||
135 | MainServer.Instance.AddHTTPHandler("/CAPS/VS/", HandleUnknownCAPSRequest); | ||
136 | } | ||
137 | |||
138 | public virtual void AddRegion(Scene scene) | ||
139 | { | ||
84 | if (!enabled) | 140 | if (!enabled) |
85 | return; | 141 | return; |
86 | 142 | ||
87 | lock (m_scenes) | 143 | lock (m_scenes) |
88 | { | 144 | { |
89 | if (m_scenes.Count == 0) | ||
90 | { | ||
91 | if (Util.IsWindows()) | ||
92 | Util.LoadArchSpecificWindowsDll("sqlite3.dll"); | ||
93 | |||
94 | //IConfig startupConfig = config.Configs["Startup"]; | ||
95 | |||
96 | dbConn = new SqliteConnection("URI=file:LocalUserStatistics.db,version=3"); | ||
97 | dbConn.Open(); | ||
98 | CreateTables(dbConn); | ||
99 | |||
100 | Prototype_distributor protodep = new Prototype_distributor(); | ||
101 | Updater_distributor updatedep = new Updater_distributor(); | ||
102 | ActiveConnectionsAJAX ajConnections = new ActiveConnectionsAJAX(); | ||
103 | SimStatsAJAX ajSimStats = new SimStatsAJAX(); | ||
104 | LogLinesAJAX ajLogLines = new LogLinesAJAX(); | ||
105 | Default_Report defaultReport = new Default_Report(); | ||
106 | Clients_report clientReport = new Clients_report(); | ||
107 | Sessions_Report sessionsReport = new Sessions_Report(); | ||
108 | |||
109 | reports.Add("prototype.js", protodep); | ||
110 | reports.Add("updater.js", updatedep); | ||
111 | reports.Add("activeconnectionsajax.html", ajConnections); | ||
112 | reports.Add("simstatsajax.html", ajSimStats); | ||
113 | reports.Add("activelogajax.html", ajLogLines); | ||
114 | reports.Add("default.report", defaultReport); | ||
115 | reports.Add("clients.report", clientReport); | ||
116 | reports.Add("sessions.report", sessionsReport); | ||
117 | |||
118 | //// | ||
119 | // Add Your own Reports here (Do Not Modify Lines here Devs!) | ||
120 | //// | ||
121 | |||
122 | //// | ||
123 | // End Own reports section | ||
124 | //// | ||
125 | |||
126 | MainServer.Instance.AddHTTPHandler("/SStats/", HandleStatsRequest); | ||
127 | MainServer.Instance.AddHTTPHandler("/CAPS/VS/", HandleUnknownCAPSRequest); | ||
128 | } | ||
129 | |||
130 | m_scenes.Add(scene); | 145 | m_scenes.Add(scene); |
131 | if (m_simstatsCounters.ContainsKey(scene.RegionInfo.RegionID)) | 146 | if (m_simstatsCounters.ContainsKey(scene.RegionInfo.RegionID)) |
132 | m_simstatsCounters.Remove(scene.RegionInfo.RegionID); | 147 | m_simstatsCounters.Remove(scene.RegionInfo.RegionID); |
@@ -136,6 +151,39 @@ namespace OpenSim.Region.UserStatistics | |||
136 | } | 151 | } |
137 | } | 152 | } |
138 | 153 | ||
154 | public void RegionLoaded(Scene scene) | ||
155 | { | ||
156 | } | ||
157 | |||
158 | public void RemoveRegion(Scene scene) | ||
159 | { | ||
160 | } | ||
161 | |||
162 | public virtual void Close() | ||
163 | { | ||
164 | if (!enabled) | ||
165 | return; | ||
166 | |||
167 | dbConn.Close(); | ||
168 | dbConn.Dispose(); | ||
169 | m_sessions.Clear(); | ||
170 | m_scenes.Clear(); | ||
171 | reports.Clear(); | ||
172 | m_simstatsCounters.Clear(); | ||
173 | } | ||
174 | |||
175 | public virtual string Name | ||
176 | { | ||
177 | get { return "ViewerStatsModule"; } | ||
178 | } | ||
179 | |||
180 | public Type ReplaceableInterface | ||
181 | { | ||
182 | get { return null; } | ||
183 | } | ||
184 | |||
185 | #endregion | ||
186 | |||
139 | private void ReceiveClassicSimStatsPacket(SimStats stats) | 187 | private void ReceiveClassicSimStatsPacket(SimStats stats) |
140 | { | 188 | { |
141 | if (!enabled) | 189 | if (!enabled) |
@@ -251,37 +299,6 @@ namespace OpenSim.Region.UserStatistics | |||
251 | } | 299 | } |
252 | } | 300 | } |
253 | 301 | ||
254 | public virtual void PostInitialise() | ||
255 | { | ||
256 | if (!enabled) | ||
257 | return; | ||
258 | |||
259 | AddHandlers(); | ||
260 | } | ||
261 | |||
262 | public virtual void Close() | ||
263 | { | ||
264 | if (!enabled) | ||
265 | return; | ||
266 | |||
267 | dbConn.Close(); | ||
268 | dbConn.Dispose(); | ||
269 | m_sessions.Clear(); | ||
270 | m_scenes.Clear(); | ||
271 | reports.Clear(); | ||
272 | m_simstatsCounters.Clear(); | ||
273 | } | ||
274 | |||
275 | public virtual string Name | ||
276 | { | ||
277 | get { return "ViewerStatsModule"; } | ||
278 | } | ||
279 | |||
280 | public bool IsSharedModule | ||
281 | { | ||
282 | get { return true; } | ||
283 | } | ||
284 | |||
285 | private void OnRegisterCaps(UUID agentID, Caps caps) | 302 | private void OnRegisterCaps(UUID agentID, Caps caps) |
286 | { | 303 | { |
287 | // m_log.DebugFormat("[WEB STATS MODULE]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps); | 304 | // m_log.DebugFormat("[WEB STATS MODULE]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps); |
@@ -302,7 +319,7 @@ namespace OpenSim.Region.UserStatistics | |||
302 | { | 319 | { |
303 | } | 320 | } |
304 | 321 | ||
305 | protected virtual void AddHandlers() | 322 | protected virtual void AddEventHandlers() |
306 | { | 323 | { |
307 | lock (m_scenes) | 324 | lock (m_scenes) |
308 | { | 325 | { |
@@ -319,14 +336,18 @@ namespace OpenSim.Region.UserStatistics | |||
319 | 336 | ||
320 | private void OnMakeRootAgent(ScenePresence agent) | 337 | private void OnMakeRootAgent(ScenePresence agent) |
321 | { | 338 | { |
339 | // m_log.DebugFormat( | ||
340 | // "[WEB STATS MODULE]: Looking for session {0} for {1} in {2}", | ||
341 | // agent.ControllingClient.SessionId, agent.Name, agent.Scene.Name); | ||
342 | |||
322 | lock (m_sessions) | 343 | lock (m_sessions) |
323 | { | 344 | { |
324 | UserSessionID uid; | 345 | UserSession uid; |
325 | 346 | ||
326 | if (!m_sessions.ContainsKey(agent.UUID)) | 347 | if (!m_sessions.ContainsKey(agent.UUID)) |
327 | { | 348 | { |
328 | UserSessionData usd = UserSessionUtil.newUserSessionData(); | 349 | UserSessionData usd = UserSessionUtil.newUserSessionData(); |
329 | uid = new UserSessionID(); | 350 | uid = new UserSession(); |
330 | uid.name_f = agent.Firstname; | 351 | uid.name_f = agent.Firstname; |
331 | uid.name_l = agent.Lastname; | 352 | uid.name_l = agent.Lastname; |
332 | uid.session_data = usd; | 353 | uid.session_data = usd; |
@@ -411,9 +432,9 @@ namespace OpenSim.Region.UserStatistics | |||
411 | return String.Empty; | 432 | return String.Empty; |
412 | } | 433 | } |
413 | 434 | ||
414 | private UserSessionID ParseViewerStats(string request, UUID agentID) | 435 | private UserSession ParseViewerStats(string request, UUID agentID) |
415 | { | 436 | { |
416 | UserSessionID uid = new UserSessionID(); | 437 | UserSession uid = new UserSession(); |
417 | UserSessionData usd; | 438 | UserSessionData usd; |
418 | OSD message = OSDParser.DeserializeLLSDXml(request); | 439 | OSD message = OSDParser.DeserializeLLSDXml(request); |
419 | OSDMap mmap; | 440 | OSDMap mmap; |
@@ -425,22 +446,25 @@ namespace OpenSim.Region.UserStatistics | |||
425 | if (!m_sessions.ContainsKey(agentID)) | 446 | if (!m_sessions.ContainsKey(agentID)) |
426 | { | 447 | { |
427 | m_log.WarnFormat("[WEB STATS MODULE]: no session for stat disclosure for agent {0}", agentID); | 448 | m_log.WarnFormat("[WEB STATS MODULE]: no session for stat disclosure for agent {0}", agentID); |
428 | return new UserSessionID(); | 449 | return new UserSession(); |
429 | } | 450 | } |
451 | |||
430 | uid = m_sessions[agentID]; | 452 | uid = m_sessions[agentID]; |
453 | |||
454 | // m_log.DebugFormat("[WEB STATS MODULE]: Got session {0} for {1}", uid.session_id, agentID); | ||
431 | } | 455 | } |
432 | else | 456 | else |
433 | { | 457 | { |
434 | // parse through the beginning to locate the session | 458 | // parse through the beginning to locate the session |
435 | if (message.Type != OSDType.Map) | 459 | if (message.Type != OSDType.Map) |
436 | return new UserSessionID(); | 460 | return new UserSession(); |
437 | 461 | ||
438 | mmap = (OSDMap)message; | 462 | mmap = (OSDMap)message; |
439 | { | 463 | { |
440 | UUID sessionID = mmap["session_id"].AsUUID(); | 464 | UUID sessionID = mmap["session_id"].AsUUID(); |
441 | 465 | ||
442 | if (sessionID == UUID.Zero) | 466 | if (sessionID == UUID.Zero) |
443 | return new UserSessionID(); | 467 | return new UserSession(); |
444 | 468 | ||
445 | 469 | ||
446 | // search through each session looking for the owner | 470 | // search through each session looking for the owner |
@@ -459,7 +483,7 @@ namespace OpenSim.Region.UserStatistics | |||
459 | // can't find a session | 483 | // can't find a session |
460 | if (agentID == UUID.Zero) | 484 | if (agentID == UUID.Zero) |
461 | { | 485 | { |
462 | return new UserSessionID(); | 486 | return new UserSession(); |
463 | } | 487 | } |
464 | } | 488 | } |
465 | } | 489 | } |
@@ -468,12 +492,12 @@ namespace OpenSim.Region.UserStatistics | |||
468 | usd = uid.session_data; | 492 | usd = uid.session_data; |
469 | 493 | ||
470 | if (message.Type != OSDType.Map) | 494 | if (message.Type != OSDType.Map) |
471 | return new UserSessionID(); | 495 | return new UserSession(); |
472 | 496 | ||
473 | mmap = (OSDMap)message; | 497 | mmap = (OSDMap)message; |
474 | { | 498 | { |
475 | if (mmap["agent"].Type != OSDType.Map) | 499 | if (mmap["agent"].Type != OSDType.Map) |
476 | return new UserSessionID(); | 500 | return new UserSession(); |
477 | OSDMap agent_map = (OSDMap)mmap["agent"]; | 501 | OSDMap agent_map = (OSDMap)mmap["agent"]; |
478 | usd.agent_id = agentID; | 502 | usd.agent_id = agentID; |
479 | usd.name_f = uid.name_f; | 503 | usd.name_f = uid.name_f; |
@@ -493,17 +517,18 @@ namespace OpenSim.Region.UserStatistics | |||
493 | (float)agent_map["fps"].AsReal()); | 517 | (float)agent_map["fps"].AsReal()); |
494 | 518 | ||
495 | if (mmap["downloads"].Type != OSDType.Map) | 519 | if (mmap["downloads"].Type != OSDType.Map) |
496 | return new UserSessionID(); | 520 | return new UserSession(); |
497 | OSDMap downloads_map = (OSDMap)mmap["downloads"]; | 521 | OSDMap downloads_map = (OSDMap)mmap["downloads"]; |
498 | usd.d_object_kb = (float)downloads_map["object_kbytes"].AsReal(); | 522 | usd.d_object_kb = (float)downloads_map["object_kbytes"].AsReal(); |
499 | usd.d_texture_kb = (float)downloads_map["texture_kbytes"].AsReal(); | 523 | usd.d_texture_kb = (float)downloads_map["texture_kbytes"].AsReal(); |
500 | usd.d_world_kb = (float)downloads_map["workd_kbytes"].AsReal(); | 524 | usd.d_world_kb = (float)downloads_map["workd_kbytes"].AsReal(); |
501 | 525 | ||
526 | // m_log.DebugFormat("[WEB STATS MODULE]: mmap[\"session_id\"] = [{0}]", mmap["session_id"].AsUUID()); | ||
502 | 527 | ||
503 | usd.session_id = mmap["session_id"].AsUUID(); | 528 | usd.session_id = mmap["session_id"].AsUUID(); |
504 | 529 | ||
505 | if (mmap["system"].Type != OSDType.Map) | 530 | if (mmap["system"].Type != OSDType.Map) |
506 | return new UserSessionID(); | 531 | return new UserSession(); |
507 | OSDMap system_map = (OSDMap)mmap["system"]; | 532 | OSDMap system_map = (OSDMap)mmap["system"]; |
508 | 533 | ||
509 | usd.s_cpu = system_map["cpu"].AsString(); | 534 | usd.s_cpu = system_map["cpu"].AsString(); |
@@ -512,13 +537,13 @@ namespace OpenSim.Region.UserStatistics | |||
512 | usd.s_ram = system_map["ram"].AsInteger(); | 537 | usd.s_ram = system_map["ram"].AsInteger(); |
513 | 538 | ||
514 | if (mmap["stats"].Type != OSDType.Map) | 539 | if (mmap["stats"].Type != OSDType.Map) |
515 | return new UserSessionID(); | 540 | return new UserSession(); |
516 | 541 | ||
517 | OSDMap stats_map = (OSDMap)mmap["stats"]; | 542 | OSDMap stats_map = (OSDMap)mmap["stats"]; |
518 | { | 543 | { |
519 | 544 | ||
520 | if (stats_map["failures"].Type != OSDType.Map) | 545 | if (stats_map["failures"].Type != OSDType.Map) |
521 | return new UserSessionID(); | 546 | return new UserSession(); |
522 | OSDMap stats_failures = (OSDMap)stats_map["failures"]; | 547 | OSDMap stats_failures = (OSDMap)stats_map["failures"]; |
523 | usd.f_dropped = stats_failures["dropped"].AsInteger(); | 548 | usd.f_dropped = stats_failures["dropped"].AsInteger(); |
524 | usd.f_failed_resends = stats_failures["failed_resends"].AsInteger(); | 549 | usd.f_failed_resends = stats_failures["failed_resends"].AsInteger(); |
@@ -527,18 +552,18 @@ namespace OpenSim.Region.UserStatistics | |||
527 | usd.f_send_packet = stats_failures["send_packet"].AsInteger(); | 552 | usd.f_send_packet = stats_failures["send_packet"].AsInteger(); |
528 | 553 | ||
529 | if (stats_map["net"].Type != OSDType.Map) | 554 | if (stats_map["net"].Type != OSDType.Map) |
530 | return new UserSessionID(); | 555 | return new UserSession(); |
531 | OSDMap stats_net = (OSDMap)stats_map["net"]; | 556 | OSDMap stats_net = (OSDMap)stats_map["net"]; |
532 | { | 557 | { |
533 | if (stats_net["in"].Type != OSDType.Map) | 558 | if (stats_net["in"].Type != OSDType.Map) |
534 | return new UserSessionID(); | 559 | return new UserSession(); |
535 | 560 | ||
536 | OSDMap net_in = (OSDMap)stats_net["in"]; | 561 | OSDMap net_in = (OSDMap)stats_net["in"]; |
537 | usd.n_in_kb = (float)net_in["kbytes"].AsReal(); | 562 | usd.n_in_kb = (float)net_in["kbytes"].AsReal(); |
538 | usd.n_in_pk = net_in["packets"].AsInteger(); | 563 | usd.n_in_pk = net_in["packets"].AsInteger(); |
539 | 564 | ||
540 | if (stats_net["out"].Type != OSDType.Map) | 565 | if (stats_net["out"].Type != OSDType.Map) |
541 | return new UserSessionID(); | 566 | return new UserSession(); |
542 | OSDMap net_out = (OSDMap)stats_net["out"]; | 567 | OSDMap net_out = (OSDMap)stats_net["out"]; |
543 | 568 | ||
544 | usd.n_out_kb = (float)net_out["kbytes"].AsReal(); | 569 | usd.n_out_kb = (float)net_out["kbytes"].AsReal(); |
@@ -549,11 +574,18 @@ namespace OpenSim.Region.UserStatistics | |||
549 | 574 | ||
550 | uid.session_data = usd; | 575 | uid.session_data = usd; |
551 | m_sessions[agentID] = uid; | 576 | m_sessions[agentID] = uid; |
577 | |||
578 | // m_log.DebugFormat( | ||
579 | // "[WEB STATS MODULE]: Parse data for {0} {1}, session {2}", uid.name_f, uid.name_l, uid.session_id); | ||
580 | |||
552 | return uid; | 581 | return uid; |
553 | } | 582 | } |
554 | 583 | ||
555 | private void UpdateUserStats(UserSessionID uid, SqliteConnection db) | 584 | private void UpdateUserStats(UserSession uid, SqliteConnection db) |
556 | { | 585 | { |
586 | // m_log.DebugFormat( | ||
587 | // "[WEB STATS MODULE]: Updating user stats for {0} {1}, session {2}", uid.name_f, uid.name_l, uid.session_id); | ||
588 | |||
557 | if (uid.session_id == UUID.Zero) | 589 | if (uid.session_id == UUID.Zero) |
558 | return; | 590 | return; |
559 | 591 | ||
@@ -740,7 +772,6 @@ VALUES | |||
740 | s.min_ping = ArrayMin_f(__ping); | 772 | s.min_ping = ArrayMin_f(__ping); |
741 | s.max_ping = ArrayMax_f(__ping); | 773 | s.max_ping = ArrayMax_f(__ping); |
742 | s.mode_ping = ArrayMode_f(__ping); | 774 | s.mode_ping = ArrayMode_f(__ping); |
743 | |||
744 | } | 775 | } |
745 | 776 | ||
746 | #region Statistics | 777 | #region Statistics |
@@ -985,7 +1016,7 @@ VALUES | |||
985 | } | 1016 | } |
986 | #region structs | 1017 | #region structs |
987 | 1018 | ||
988 | public struct UserSessionID | 1019 | public class UserSession |
989 | { | 1020 | { |
990 | public UUID session_id; | 1021 | public UUID session_id; |
991 | public UUID region_id; | 1022 | public UUID region_id; |