From e9cef70f892bfbf4aad0e4471a958367766d849a Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Sat, 3 Jan 2009 03:30:03 +0000 Subject: * Updates the sim stats module. Cleans out some of the rot. * Adds a prototype web stats module which is disabled by default. It's functional with one report right now, however, the database structure may change, so I don't recommend enabling this to keep actual stats right now. I'll let you know when it's safe. * Adds Prototype for ajaxy web content * removed a warning or two. --- OpenSim/Region/UserStatistics/WebStatsModule.cs | 1083 +++++++++++++++++++++++ 1 file changed, 1083 insertions(+) create mode 100644 OpenSim/Region/UserStatistics/WebStatsModule.cs (limited to 'OpenSim/Region/UserStatistics/WebStatsModule.cs') diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs new file mode 100644 index 0000000..4eb8cb7 --- /dev/null +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs @@ -0,0 +1,1083 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Net; // to be used for REST-->Grid shortly +using System.Reflection; +using log4net; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Framework.Servers; +using OpenSim.Region.Environment.Interfaces; +using OpenSim.Region.Environment.Scenes; +using Mono.Data.SqliteClient; + + +using Caps = OpenSim.Framework.Communications.Capabilities.Caps; + +using OSD = OpenMetaverse.StructuredData.OSD; +using OSDMap = OpenMetaverse.StructuredData.OSDMap; + +namespace OpenSim.Region.UserStatistics +{ + public class WebStatsModule : IRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static SqliteConnection dbConn; + private Dictionary m_sessions = new Dictionary(); + private List m_scene = new List(); + private Dictionary reports = new Dictionary(); + private Dictionary m_simstatsCounters = new Dictionary(); + private const int updateStatsMod = 6; + private volatile int concurrencyCounter = 0; + private bool enabled = false; + + + public virtual void Initialise(Scene scene, IConfigSource config) + { + IConfig cnfg; + try + { + cnfg = config.Configs["WebStats"]; + enabled = cnfg.GetBoolean("enabled", false); + + } + catch (Exception) + { + enabled = false; + } + if (!enabled) + { + return; + } + + lock (m_scene) + { + if (m_scene.Count == 0) + { + IConfig startupConfig = config.Configs["Startup"]; + + dbConn = new SqliteConnection("URI=file:LocalUserStatistics.db,version=3"); + dbConn.Open(); + CheckAndUpdateDatabase(dbConn); + + Default_Report rep = new Default_Report(); + Prototype_distributor protodep = new Prototype_distributor(); + Updater_distributor updatedep = new Updater_distributor(); + ActiveConnectionsAJAX ajConnections = new ActiveConnectionsAJAX(); + SimStatsAJAX ajSimStats = new SimStatsAJAX(); + reports.Add("", rep); + reports.Add("index.aspx", rep); + reports.Add("prototype.js", protodep); + reports.Add("updater.js", updatedep); + reports.Add("activeconnectionsajax.ajax", ajConnections); + reports.Add("simstatsajax.ajax", ajSimStats); + + scene.CommsManager.HttpServer.AddHTTPHandler("/SStats/", HandleStatsRequest); + + + } + m_scene.Add(scene); + m_simstatsCounters.Add(scene.RegionInfo.RegionID, new USimStatsData(scene.RegionInfo.RegionID)); + scene.StatsReporter.OnSendStatsResult += ReceiveClassicSimStatsPacket; + } + + } + + public void ReceiveClassicSimStatsPacket(SimStats stats) + { + if (!enabled) + { + return; + } + + try + { + + if (concurrencyCounter > 0) + return; + + USimStatsData ss = m_simstatsCounters[stats.RegionUUID]; + + if ((++ss.StatsCounter % updateStatsMod) == 0) + { + ss.ConsumeSimStats(stats); + } + } + catch (KeyNotFoundException) + { + + } + } + + public Hashtable HandleStatsRequest(Hashtable request) + { + Hashtable responsedata = new Hashtable(); + string regpath = request["uri"].ToString(); + int response_code = 404; + string contenttype = "text/html"; + + string strOut = string.Empty; + + regpath = regpath.Remove(0, 8); + if (reports.ContainsKey(regpath)) + { + IStatsController rep = reports[regpath]; + Hashtable repParams = new Hashtable(); + + repParams["DatabaseConnection"] = dbConn; + repParams["Scenes"] = m_scene; + repParams["SimStats"] = m_simstatsCounters; + + concurrencyCounter++; + + strOut = rep.RenderView(rep.ProcessModel(repParams)); + + if (regpath.EndsWith("js")) + { + contenttype = "text/javascript"; + } + + concurrencyCounter--; + + response_code = 200; + + } + else + { + strOut = m_scene[0].CommsManager.HttpServer.GetHTTP404(""); + } + + + responsedata["int_response_code"] = response_code; + responsedata["content_type"] = contenttype; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = strOut; + + return responsedata; + } + + + + public void CheckAndUpdateDatabase(SqliteConnection db) + { + lock (db) + { + // TODO: FIXME: implement stats migrations + const string SQL = @"SELECT * FROM migrations LIMIT 1"; + + SqliteCommand cmd = new SqliteCommand(SQL, db); + + try + { + cmd.ExecuteNonQuery(); + } + catch (SqliteSyntaxException) + { + CreateTables(db); + } + } + + } + + public void CreateTables(SqliteConnection db) + { + SqliteCommand createcmd = new SqliteCommand(SQL_STATS_TABLE_CREATE, db); + createcmd.ExecuteNonQuery(); + + createcmd.CommandText = SQL_MIGRA_TABLE_CREATE; + createcmd.ExecuteNonQuery(); + } + + + + public virtual void PostInitialise() + { + if (!enabled) + { + return; + } + AddHandlers(); + } + + public virtual void Close() + { + if (!enabled) + { + return; + } + dbConn.Close(); + dbConn.Dispose(); + } + + public virtual string Name + { + get { return "ViewerStatsModule"; } + } + + public bool IsSharedModule + { + get { return true; } + } + + public void OnRegisterCaps(UUID agentID, Caps caps) + { + m_log.DebugFormat("[VC]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps); + string capsPath = "/CAPS/VS/" + UUID.Random(); + caps.RegisterHandler("ViewerStats", + new RestStreamHandler("POST", capsPath, + delegate(string request, string path, string param, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + return ViewerStatsReport(request, path, param, + agentID, caps); + })); + } + + public void OnDeRegisterCaps(UUID agentID, Caps caps) + { + + } + + protected virtual void AddHandlers() + { + lock (m_scene) + { + foreach (Scene scene in m_scene) + { + scene.EventManager.OnRegisterCaps += OnRegisterCaps; + scene.EventManager.OnDeregisterCaps += OnDeRegisterCaps; + scene.EventManager.OnClientClosed += OnClientClosed; + scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; + scene.EventManager.OnMakeChildAgent += OnMakeChildAgent; + } + } + } + + public void OnMakeRootAgent(ScenePresence agent) + { + UUID regionUUID = GetRegionUUIDFromHandle(agent.RegionHandle); + + lock (m_sessions) + { + if (!m_sessions.ContainsKey(agent.UUID)) + { + UserSessionData usd = UserSessionUtil.newUserSessionData(); + + UserSessionID uid = new UserSessionID(); + uid.name_f = agent.Firstname; + uid.name_l = agent.Lastname; + uid.region_id = regionUUID; + uid.session_id = agent.ControllingClient.SessionId; + uid.session_data = usd; + + m_sessions.Add(agent.UUID, uid); + } + else + { + UserSessionID uid = m_sessions[agent.UUID]; + uid.region_id = regionUUID; + uid.session_id = agent.ControllingClient.SessionId; + m_sessions[agent.UUID] = uid; + } + } + } + + + + + public void OnMakeChildAgent(ScenePresence agent) + { + lock (m_sessions) + { + if (m_sessions.ContainsKey(agent.UUID)) + { + if (m_sessions[agent.UUID].region_id == GetRegionUUIDFromHandle(agent.RegionHandle)) + { + m_sessions.Remove(agent.UUID); + } + } + } + } + + + public void OnClientClosed(UUID agentID) + { + lock (m_sessions) + { + if (m_sessions.ContainsKey(agentID)) + { + m_sessions.Remove(agentID); + } + } + + } + + public UUID GetRegionUUIDFromHandle(ulong regionhandle) + { + lock (m_scene) + { + foreach (Scene scene in m_scene) + { + if (scene.RegionInfo.RegionHandle == regionhandle) + return scene.RegionInfo.RegionID; + } + } + return UUID.Zero; + } + /// + /// Callback for a viewerstats cap + /// + /// + /// + /// + /// + /// + /// + public string ViewerStatsReport(string request, string path, string param, + UUID agentID, Caps caps) + { + m_log.Debug(request); + UserSessionID uid; + UserSessionData usd; + + lock (m_sessions) + { + if (!m_sessions.ContainsKey(agentID)) + { + m_log.Warn("[VS]: no session for stat disclosure"); + return string.Empty; + } + uid = m_sessions[agentID]; + } + + usd = uid.session_data; + + OSD message = OSDParser.DeserializeLLSDXml(request); + if (message.Type != OSDType.Map) + return String.Empty; + + OSDMap mmap = (OSDMap) message; + { + if (mmap["agent"].Type != OSDType.Map) + return String.Empty; + OSDMap agent_map = (OSDMap) mmap["agent"]; + usd.agent_id = agentID; + usd.name_f = uid.name_f; + usd.name_l = uid.name_l; + usd.region_id = uid.region_id; + usd.a_language = agent_map["language"].AsString(); + usd.mem_use = (float) agent_map["mem_use"].AsReal(); + usd.meters_traveled = (float) agent_map["meters_traveled"].AsReal(); + usd.regions_visited = agent_map["regions_visited"].AsInteger(); + usd.run_time = (float) agent_map["run_time"].AsReal(); + usd.start_time = (float) agent_map["start_time"].AsReal(); + usd.client_version = agent_map["version"].AsString(); + + UserSessionUtil.UpdateMultiItems(ref usd, agent_map["agents_in_view"].AsInteger(), + (float) agent_map["ping"].AsReal(), + (float) agent_map["sim_fps"].AsReal(), + (float) agent_map["fps"].AsReal()); + + if (mmap["downloads"].Type != OSDType.Map) + return String.Empty; + OSDMap downloads_map = (OSDMap) mmap["downloads"]; + usd.d_object_kb = (float) downloads_map["object_kbytes"].AsReal(); + usd.d_texture_kb = (float) downloads_map["texture_kbytes"].AsReal(); + usd.d_world_kb = (float) downloads_map["workd_kbytes"].AsReal(); + + + usd.session_id = mmap["session_id"].AsUUID(); + + if (mmap["system"].Type != OSDType.Map) + return String.Empty; + OSDMap system_map = (OSDMap) mmap["system"]; + + usd.s_cpu = system_map["cpu"].AsString(); + usd.s_gpu = system_map["gpu"].AsString(); + usd.s_os = system_map["os"].AsString(); + usd.s_ram = system_map["ram"].AsInteger(); + + if (mmap["stats"].Type != OSDType.Map) + return String.Empty; + + OSDMap stats_map = (OSDMap) mmap["stats"]; + { + if (mmap["failures"].Type != OSDType.Map) + return String.Empty; + OSDMap stats_failures = (OSDMap) stats_map["failures"]; + usd.f_dropped = stats_failures["dropped"].AsInteger(); + usd.f_failed_resends = stats_failures["failed_resends"].AsInteger(); + usd.f_invalid = stats_failures["invalid"].AsInteger(); + usd.f_resent = stats_failures["resent"].AsInteger(); + usd.f_send_packet = stats_failures["send_packet"].AsInteger(); + + if (mmap["net"].Type != OSDType.Map) + return String.Empty; + OSDMap stats_net = (OSDMap) stats_map["net"]; + { + if (mmap["in"].Type != OSDType.Map) + return String.Empty; + + OSDMap net_in = (OSDMap) stats_net["in"]; + usd.n_in_kb = (float) net_in["kbytes"].AsReal(); + usd.n_in_pk = net_in["packets"].AsInteger(); + + if (mmap["out"].Type != OSDType.Map) + return String.Empty; + OSDMap net_out = (OSDMap) stats_net["out"]; + + usd.n_out_kb = (float) net_out["kbytes"].AsReal(); + usd.n_out_pk = net_out["packets"].AsInteger(); + } + + + } + } + + uid.session_data = usd; + m_sessions[agentID] = uid; + UpdateUserStats(uid, dbConn); + + return String.Empty; + } + + public void UpdateUserStats(UserSessionID uid, SqliteConnection db) + { + lock (db) + { + SqliteCommand updatecmd = new SqliteCommand(SQL_STATS_TABLE_UPDATE, db); + updatecmd.Parameters.Add(new SqliteParameter(":session_id", uid.session_data.session_id.ToString())); + updatecmd.Parameters.Add(new SqliteParameter(":agent_id", uid.session_data.agent_id.ToString())); + updatecmd.Parameters.Add(new SqliteParameter(":region_id", uid.session_data.region_id.ToString())); + updatecmd.Parameters.Add(new SqliteParameter(":last_updated", (int) uid.session_data.last_updated)); + updatecmd.Parameters.Add(new SqliteParameter(":remote_ip", uid.session_data.remote_ip)); + updatecmd.Parameters.Add(new SqliteParameter(":name_f", uid.session_data.name_f)); + updatecmd.Parameters.Add(new SqliteParameter(":name_l", uid.session_data.name_l)); + updatecmd.Parameters.Add(new SqliteParameter(":avg_agents_in_view", uid.session_data.avg_agents_in_view)); + updatecmd.Parameters.Add(new SqliteParameter(":min_agents_in_view", + (int) uid.session_data.min_agents_in_view)); + updatecmd.Parameters.Add(new SqliteParameter(":max_agents_in_view", + (int) uid.session_data.max_agents_in_view)); + updatecmd.Parameters.Add(new SqliteParameter(":mode_agents_in_view", + (int) uid.session_data.mode_agents_in_view)); + updatecmd.Parameters.Add(new SqliteParameter(":avg_fps", uid.session_data.avg_fps)); + updatecmd.Parameters.Add(new SqliteParameter(":min_fps", uid.session_data.min_fps)); + updatecmd.Parameters.Add(new SqliteParameter(":max_fps", uid.session_data.max_fps)); + updatecmd.Parameters.Add(new SqliteParameter(":mode_fps", uid.session_data.mode_fps)); + updatecmd.Parameters.Add(new SqliteParameter(":a_language", uid.session_data.a_language)); + updatecmd.Parameters.Add(new SqliteParameter(":mem_use", uid.session_data.mem_use)); + updatecmd.Parameters.Add(new SqliteParameter(":meters_traveled", uid.session_data.meters_traveled)); + updatecmd.Parameters.Add(new SqliteParameter(":avg_ping", uid.session_data.avg_ping)); + updatecmd.Parameters.Add(new SqliteParameter(":min_ping", uid.session_data.min_ping)); + updatecmd.Parameters.Add(new SqliteParameter(":max_ping", uid.session_data.max_ping)); + updatecmd.Parameters.Add(new SqliteParameter(":mode_ping", uid.session_data.mode_ping)); + updatecmd.Parameters.Add(new SqliteParameter(":regions_visited", uid.session_data.regions_visited)); + updatecmd.Parameters.Add(new SqliteParameter(":run_time", uid.session_data.run_time)); + updatecmd.Parameters.Add(new SqliteParameter(":avg_sim_fps", uid.session_data.avg_sim_fps)); + updatecmd.Parameters.Add(new SqliteParameter(":min_sim_fps", uid.session_data.min_sim_fps)); + updatecmd.Parameters.Add(new SqliteParameter(":max_sim_fps", uid.session_data.max_sim_fps)); + updatecmd.Parameters.Add(new SqliteParameter(":mode_sim_fps", uid.session_data.mode_sim_fps)); + updatecmd.Parameters.Add(new SqliteParameter(":start_time", uid.session_data.start_time)); + updatecmd.Parameters.Add(new SqliteParameter(":client_version", uid.session_data.client_version)); + updatecmd.Parameters.Add(new SqliteParameter(":s_cpu", uid.session_data.s_cpu)); + updatecmd.Parameters.Add(new SqliteParameter(":s_gpu", uid.session_data.s_gpu)); + updatecmd.Parameters.Add(new SqliteParameter(":s_os", uid.session_data.s_os)); + updatecmd.Parameters.Add(new SqliteParameter(":s_ram", uid.session_data.s_ram)); + updatecmd.Parameters.Add(new SqliteParameter(":d_object_kb", uid.session_data.d_object_kb)); + updatecmd.Parameters.Add(new SqliteParameter(":d_texture_kb", uid.session_data.d_texture_kb)); + updatecmd.Parameters.Add(new SqliteParameter(":d_world_kb", uid.session_data.d_world_kb)); + updatecmd.Parameters.Add(new SqliteParameter(":n_in_kb", uid.session_data.n_in_kb)); + updatecmd.Parameters.Add(new SqliteParameter(":n_in_pk", uid.session_data.n_in_pk)); + updatecmd.Parameters.Add(new SqliteParameter(":n_out_kb", uid.session_data.n_out_kb)); + updatecmd.Parameters.Add(new SqliteParameter(":n_out_pk", uid.session_data.n_out_pk)); + updatecmd.Parameters.Add(new SqliteParameter(":f_dropped", uid.session_data.f_dropped)); + updatecmd.Parameters.Add(new SqliteParameter(":f_failed_resends", uid.session_data.f_failed_resends)); + updatecmd.Parameters.Add(new SqliteParameter(":f_invalid", uid.session_data.f_invalid)); + + updatecmd.Parameters.Add(new SqliteParameter(":f_off_circuit", uid.session_data.f_off_circuit)); + updatecmd.Parameters.Add(new SqliteParameter(":f_resent", uid.session_data.f_resent)); + updatecmd.Parameters.Add(new SqliteParameter(":f_send_packet", uid.session_data.f_send_packet)); + + updatecmd.Parameters.Add(new SqliteParameter(":session_key", uid.session_data.session_id.ToString())); + updatecmd.Parameters.Add(new SqliteParameter(":agent_key", uid.session_data.agent_id.ToString())); + updatecmd.Parameters.Add(new SqliteParameter(":region_key", uid.session_data.region_id.ToString())); + m_log.Debug("UPDATE"); + + int result = updatecmd.ExecuteNonQuery(); + + if (result == 0) + { + m_log.Debug("INSERT"); + updatecmd.CommandText = SQL_STATS_TABLE_INSERT; + updatecmd.ExecuteNonQuery(); + } + } + + } + + #region SQL + private const string SQL_MIGRA_TABLE_CREATE = @"create table migrations(name varchar(100), version int)"; + + private const string SQL_STATS_TABLE_CREATE = @"CREATE TABLE stats_session_data ( + session_id VARCHAR(36) NOT NULL PRIMARY KEY, + agent_id VARCHAR(36) NOT NULL DEFAULT '', + region_id VARCHAR(36) NOT NULL DEFAULT '', + last_updated INT NOT NULL DEFAULT '0', + remote_ip VARCHAR(16) NOT NULL DEFAULT '', + name_f VARCHAR(50) NOT NULL DEFAULT '', + name_l VARCHAR(50) NOT NULL DEFAULT '', + avg_agents_in_view FLOAT NOT NULL DEFAULT '0', + min_agents_in_view INT NOT NULL DEFAULT '0', + max_agents_in_view INT NOT NULL DEFAULT '0', + mode_agents_in_view INT NOT NULL DEFAULT '0', + avg_fps FLOAT NOT NULL DEFAULT '0', + min_fps FLOAT NOT NULL DEFAULT '0', + max_fps FLOAT NOT NULL DEFAULT '0', + mode_fps FLOAT NOT NULL DEFAULT '0', + a_language VARCHAR(25) NOT NULL DEFAULT '', + mem_use FLOAT NOT NULL DEFAULT '0', + meters_traveled FLOAT NOT NULL DEFAULT '0', + avg_ping FLOAT NOT NULL DEFAULT '0', + min_ping FLOAT NOT NULL DEFAULT '0', + max_ping FLOAT NOT NULL DEFAULT '0', + mode_ping FLOAT NOT NULL DEFAULT '0', + regions_visited INT NOT NULL DEFAULT '0', + run_time FLOAT NOT NULL DEFAULT '0', + avg_sim_fps FLOAT NOT NULL DEFAULT '0', + min_sim_fps FLOAT NOT NULL DEFAULT '0', + max_sim_fps FLOAT NOT NULL DEFAULT '0', + mode_sim_fps FLOAT NOT NULL DEFAULT '0', + start_time FLOAT NOT NULL DEFAULT '0', + client_version VARCHAR(255) NOT NULL DEFAULT '', + s_cpu VARCHAR(255) NOT NULL DEFAULT '', + s_gpu VARCHAR(255) NOT NULL DEFAULT '', + s_os VARCHAR(2255) NOT NULL DEFAULT '', + s_ram INT NOT NULL DEFAULT '0', + d_object_kb FLOAT NOT NULL DEFAULT '0', + d_texture_kb FLOAT NOT NULL DEFAULT '0', + d_world_kb FLOAT NOT NULL DEFAULT '0', + n_in_kb FLOAT NOT NULL DEFAULT '0', + n_in_pk INT NOT NULL DEFAULT '0', + n_out_kb FLOAT NOT NULL DEFAULT '0', + n_out_pk INT NOT NULL DEFAULT '0', + f_dropped INT NOT NULL DEFAULT '0', + f_failed_resends INT NOT NULL DEFAULT '0', + f_invalid INT NOT NULL DEFAULT '0', + f_off_circuit INT NOT NULL DEFAULT '0', + f_resent INT NOT NULL DEFAULT '0', + f_send_packet INT NOT NULL DEFAULT '0' + );"; + + private const string SQL_STATS_TABLE_INSERT = @"INSERT INTO stats_session_data ( +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, +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, +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, +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, +f_resent, f_send_packet +) +VALUES +( +: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, +: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, +: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, +: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, +:f_resent, :f_send_packet +) +"; + + private const string SQL_STATS_TABLE_UPDATE = @" +UPDATE stats_session_data +set session_id=:session_id, + agent_id=:agent_id, + region_id=:region_id, + last_updated=:last_updated, + remote_ip=:remote_ip, + name_f=:name_f, + name_l=:name_l, + avg_agents_in_view=:avg_agents_in_view, + min_agents_in_view=:min_agents_in_view, + max_agents_in_view=:max_agents_in_view, + mode_agents_in_view=:mode_agents_in_view, + avg_fps=:avg_fps, + min_fps=:min_fps, + max_fps=:max_fps, + mode_fps=:mode_fps, + a_language=:a_language, + mem_use=:mem_use, + meters_traveled=:meters_traveled, + avg_ping=:avg_ping, + min_ping=:min_ping, + max_ping=:max_ping, + mode_ping=:mode_ping, + regions_visited=:regions_visited, + run_time=:run_time, + avg_sim_fps=:avg_sim_fps, + min_sim_fps=:min_sim_fps, + max_sim_fps=:max_sim_fps, + mode_sim_fps=:mode_sim_fps, + start_time=:start_time, + client_version=:client_version, + s_cpu=:s_cpu, + s_gpu=:s_gpu, + s_os=:s_os, + s_ram=:s_ram, + d_object_kb=:d_object_kb, + d_texture_kb=:d_texture_kb, + d_world_kb=:d_world_kb, + n_in_kb=:n_in_kb, + n_in_pk=:n_in_pk, + n_out_kb=:n_out_kb, + n_out_pk=:n_out_pk, + f_dropped=:f_dropped, + f_failed_resends=:f_failed_resends, + f_invalid=:f_invalid, + f_off_circuit=:f_off_circuit, + f_resent=:f_resent, + f_send_packet=:f_send_packet +WHERE session_id=:session_key AND agent_id=:agent_key AND region_id=:region_key"; + #endregion + } + public static class UserSessionUtil + { + public static UserSessionData newUserSessionData() + { + UserSessionData obj = ZeroSession(new UserSessionData()); + return obj; + } + + public static void UpdateMultiItems(ref UserSessionData s, int agents_in_view, float ping, float sim_fps, float fps) + { + // don't insert zero values here or it'll skew the statistics. + if (agents_in_view == 0 && fps == 0 && sim_fps == 0 && ping == 0) + return; + s._agents_in_view.Add(agents_in_view); + s._fps.Add(fps); + s._sim_fps.Add(sim_fps); + s._ping.Add(ping); + + int[] __agents_in_view = s._agents_in_view.ToArray(); + + s.avg_agents_in_view = ArrayAvg_i(__agents_in_view); + s.min_agents_in_view = ArrayMin_i(__agents_in_view); + s.max_agents_in_view = ArrayMax_i(__agents_in_view); + s.mode_agents_in_view = ArrayMode_i(__agents_in_view); + + float[] __fps = s._fps.ToArray(); + s.avg_fps = ArrayAvg_f(__fps); + s.min_fps = ArrayMin_f(__fps); + s.max_fps = ArrayMax_f(__fps); + s.mode_fps = ArrayMode_f(__fps); + + float[] __sim_fps = s._sim_fps.ToArray(); + s.avg_sim_fps = ArrayAvg_f(__sim_fps); + s.min_sim_fps = ArrayMin_f(__sim_fps); + s.max_sim_fps = ArrayMax_f(__sim_fps); + s.mode_sim_fps = ArrayMode_f(__sim_fps); + + float[] __ping = s._ping.ToArray(); + s.avg_ping = ArrayAvg_f(__ping); + s.min_ping = ArrayMin_f(__ping); + s.max_ping = ArrayMax_f(__ping); + s.mode_ping = ArrayMode_f(__ping); + + } + + #region Statistics + + public static int ArrayMin_i(int[] arr) + { + int cnt = arr.Length; + if (cnt == 0) + return 0; + + Array.Sort(arr); + return arr[0]; + } + + public static int ArrayMax_i(int[] arr) + { + int cnt = arr.Length; + if (cnt == 0) + return 0; + + Array.Sort(arr); + return arr[cnt-1]; + } + + public static float ArrayMin_f(float[] arr) + { + int cnt = arr.Length; + if (cnt == 0) + return 0; + + Array.Sort(arr); + return arr[0]; + } + + public static float ArrayMax_f(float[] arr) + { + int cnt = arr.Length; + if (cnt == 0) + return 0; + + Array.Sort(arr); + return arr[cnt - 1]; + } + + public static float ArrayAvg_i(int[] arr) + { + int cnt = arr.Length; + + if (cnt == 0) + return 0; + + float result = arr[0]; + + for (int i = 1; i < cnt; i++) + result += arr[i]; + + return result / cnt; + } + + public static float ArrayAvg_f(float[] arr) + { + int cnt = arr.Length; + + if (cnt == 0) + return 0; + + float result = arr[0]; + + for (int i = 1; i < cnt; i++) + result += arr[i]; + + return result / cnt; + } + + + public static float ArrayMode_f(float[] arr) + { + List mode = new List(); + + float[] srtArr = new float[arr.Length]; + float[,] freq = new float[arr.Length, 2]; + Array.Copy(arr, srtArr, arr.Length); + Array.Sort(srtArr); + + float tmp = srtArr[0]; + int index = 0; + int i = 0; + while (i < srtArr.Length) + { + freq[index, 0] = tmp; + + while (tmp == srtArr[i]) + { + freq[index, 1]++; + i++; + + if (i > srtArr.Length - 1) + break; + } + + if (i < srtArr.Length) + { + tmp = srtArr[i]; + index++; + } + + } + + Array.Clear(srtArr, 0, srtArr.Length); + + for (i = 0; i < srtArr.Length; i++) + srtArr[i] = freq[i, 1]; + + Array.Sort(srtArr); + + if ((srtArr[srtArr.Length - 1]) == 0 || (srtArr[srtArr.Length - 1]) == 1) + return 0; + + float freqtest = (float)freq.Length / freq.Rank; + + for (i = 0; i < freqtest; i++) + { + if (freq[i, 1] == srtArr[index]) + mode.Add(freq[i, 0]); + + } + + return mode.ToArray()[0]; + + } + + + public static int ArrayMode_i(int[] arr) + { + List mode = new List(); + + int[] srtArr = new int[arr.Length]; + int[,] freq = new int[arr.Length, 2]; + Array.Copy(arr, srtArr, arr.Length); + Array.Sort(srtArr); + + int tmp = srtArr[0]; + int index = 0; + int i = 0; + while (i < srtArr.Length) + { + freq[index, 0] = tmp; + + while (tmp == srtArr[i]) + { + freq[index, 1]++; + i++; + + if (i > srtArr.Length - 1) + break; + } + + if (i < srtArr.Length) + { + tmp = srtArr[i]; + index++; + } + + } + + Array.Clear(srtArr, 0, srtArr.Length); + + for (i = 0; i < srtArr.Length; i++) + srtArr[i] = freq[i, 1]; + + Array.Sort(srtArr); + + if ((srtArr[srtArr.Length - 1]) == 0 || (srtArr[srtArr.Length - 1]) == 1) + return 0; + + float freqtest = (float)freq.Length / freq.Rank; + + for (i = 0; i < freqtest; i++) + { + if (freq[i, 1] == srtArr[index]) + mode.Add(freq[i, 0]); + + } + + return mode.ToArray()[0]; + + } + + #endregion + + private static UserSessionData ZeroSession(UserSessionData s) + { + s.session_id = UUID.Zero; + s.agent_id = UUID.Zero; + s.region_id = UUID.Zero; + s.last_updated = Util.UnixTimeSinceEpoch(); + s.remote_ip = ""; + s.name_f = ""; + s.name_l = ""; + s.avg_agents_in_view = 0; + s.min_agents_in_view = 0; + s.max_agents_in_view = 0; + s.mode_agents_in_view = 0; + s.avg_fps = 0; + s.min_fps = 0; + s.max_fps = 0; + s.mode_fps = 0; + s.a_language = ""; + s.mem_use = 0; + s.meters_traveled = 0; + s.avg_ping = 0; + s.min_ping = 0; + s.max_ping = 0; + s.mode_ping = 0; + s.regions_visited = 0; + s.run_time = 0; + s.avg_sim_fps = 0; + s.min_sim_fps = 0; + s.max_sim_fps = 0; + s.mode_sim_fps = 0; + s.start_time = 0; + s.client_version = ""; + s.s_cpu = ""; + s.s_gpu = ""; + s.s_os = ""; + s.s_ram = 0; + s.d_object_kb = 0; + s.d_texture_kb = 0; + s.d_world_kb = 0; + s.n_in_kb = 0; + s.n_in_pk = 0; + s.n_out_kb = 0; + s.n_out_pk = 0; + s.f_dropped = 0; + s.f_failed_resends = 0; + s.f_invalid = 0; + s.f_off_circuit = 0; + s.f_resent = 0; + s.f_send_packet = 0; + s._ping = new List(); + s._fps = new List(); + s._sim_fps = new List(); + s._agents_in_view = new List(); + return s; + } + } + #region structs + + public struct UserSessionID + { + public UUID session_id; + public UUID region_id; + public string name_f; + public string name_l; + public UserSessionData session_data; + } + + public struct UserSessionData + { + public UUID session_id; + public UUID agent_id; + public UUID region_id; + public float last_updated; + public string remote_ip; + public string name_f; + public string name_l; + public float avg_agents_in_view; + public float min_agents_in_view; + public float max_agents_in_view; + public float mode_agents_in_view; + public float avg_fps; + public float min_fps; + public float max_fps; + public float mode_fps; + public string a_language; + public float mem_use; + public float meters_traveled; + public float avg_ping; + public float min_ping; + public float max_ping; + public float mode_ping; + public int regions_visited; + public float run_time; + public float avg_sim_fps; + public float min_sim_fps; + public float max_sim_fps; + public float mode_sim_fps; + public float start_time; + public string client_version; + public string s_cpu; + public string s_gpu; + public string s_os; + public int s_ram; + public float d_object_kb; + public float d_texture_kb; + public float d_world_kb; + public float n_in_kb; + public int n_in_pk; + public float n_out_kb; + public int n_out_pk; + public int f_dropped; + public int f_failed_resends; + public int f_invalid; + public int f_off_circuit; + public int f_resent; + public int f_send_packet; + public List _ping; + public List _fps; + public List _sim_fps; + public List _agents_in_view; + } + + + #endregion + + public class USimStatsData + { + private UUID m_regionID = UUID.Zero; + private volatile int m_statcounter = 0; + private volatile float m_timeDilation; + private volatile float m_simFps; + private volatile float m_physicsFps; + private volatile float m_agentUpdates; + private volatile float m_rootAgents; + private volatile float m_childAgents; + private volatile float m_totalPrims; + private volatile float m_activePrims; + private volatile float m_totalFrameTime; + private volatile float m_netFrameTime; + private volatile float m_physicsFrameTime; + private volatile float m_otherFrameTime; + private volatile float m_imageFrameTime; + private volatile float m_inPacketsPerSecond; + private volatile float m_outPacketsPerSecond; + private volatile float m_unackedBytes; + private volatile float m_agentFrameTime; + private volatile float m_pendingDownloads; + private volatile float m_pendingUploads; + private volatile float m_activeScripts; + private volatile float m_scriptLinesPerSecond; + + public UUID RegionId { get { return m_regionID; } } + public int StatsCounter { get { return m_statcounter; } set { m_statcounter = value;}} + public float TimeDilation { get { return m_timeDilation; } } + public float SimFps { get { return m_simFps; } } + public float PhysicsFps { get { return m_physicsFps; } } + public float AgentUpdates { get { return m_agentUpdates; } } + public float RootAgents { get { return m_rootAgents; } } + public float ChildAgents { get { return m_childAgents; } } + public float TotalPrims { get { return m_totalPrims; } } + public float ActivePrims { get { return m_activePrims; } } + public float TotalFrameTime { get { return m_totalFrameTime; } } + public float NetFrameTime { get { return m_netFrameTime; } } + public float PhysicsFrameTime { get { return m_physicsFrameTime; } } + public float OtherFrameTime { get { return m_otherFrameTime; } } + public float ImageFrameTime { get { return m_imageFrameTime; } } + public float InPacketsPerSecond { get { return m_inPacketsPerSecond; } } + public float OutPacketsPerSecond { get { return m_outPacketsPerSecond; } } + public float UnackedBytes { get { return m_unackedBytes; } } + public float AgentFrameTime { get { return m_agentFrameTime; } } + public float PendingDownloads { get { return m_pendingDownloads; } } + public float PendingUploads { get { return m_pendingUploads; } } + public float ActiveScripts { get { return m_activeScripts; } } + public float ScriptLinesPerSecond { get { return m_scriptLinesPerSecond; } } + + public USimStatsData(UUID pRegionID) + { + m_regionID = pRegionID; + } + + public void ConsumeSimStats(SimStats stats) + { + m_regionID = stats.RegionUUID; + m_timeDilation = stats.StatsBlock[0].StatValue; + m_simFps = stats.StatsBlock[1].StatValue; + m_physicsFps = stats.StatsBlock[2].StatValue; + m_agentUpdates = stats.StatsBlock[3].StatValue; + m_rootAgents = stats.StatsBlock[4].StatValue; + m_childAgents = stats.StatsBlock[5].StatValue; + m_totalPrims = stats.StatsBlock[6].StatValue; + m_activePrims = stats.StatsBlock[7].StatValue; + m_totalFrameTime = stats.StatsBlock[8].StatValue; + m_netFrameTime = stats.StatsBlock[9].StatValue; + m_physicsFrameTime = stats.StatsBlock[10].StatValue; + m_otherFrameTime = stats.StatsBlock[11].StatValue; + m_imageFrameTime = stats.StatsBlock[12].StatValue; + m_inPacketsPerSecond = stats.StatsBlock[13].StatValue; + m_outPacketsPerSecond = stats.StatsBlock[14].StatValue; + m_unackedBytes = stats.StatsBlock[15].StatValue; + m_agentFrameTime = stats.StatsBlock[16].StatValue; + m_pendingDownloads = stats.StatsBlock[17].StatValue; + m_pendingUploads = stats.StatsBlock[18].StatValue; + m_activeScripts = stats.StatsBlock[19].StatValue; + m_scriptLinesPerSecond = stats.StatsBlock[20].StatValue; + } + } + +} -- cgit v1.1