made the graphs load faster

fixed issues with stats page
made the pages json request faster
This commit is contained in:
RaidMax 2017-10-04 18:01:04 -05:00
parent 9758e72f6b
commit d8b19f289a
11 changed files with 137 additions and 129 deletions

View File

@ -54,6 +54,7 @@ namespace IW4MAdmin
if (requestedPage.content != null && requestedPage.content.GetType() != typeof(string)) if (requestedPage.content != null && requestedPage.content.GetType() != typeof(string))
requestedPage.content = Newtonsoft.Json.JsonConvert.SerializeObject(requestedPage.content); requestedPage.content = Newtonsoft.Json.JsonConvert.SerializeObject(requestedPage.content);
string maxAge = requestedPage.contentType == "application/json" ? "0" : "31536000";
var headers = new HttpResponseHead() var headers = new HttpResponseHead()
{ {
Status = "200 OK", Status = "200 OK",
@ -62,6 +63,7 @@ namespace IW4MAdmin
{ "Content-Type", requestedPage.contentType }, { "Content-Type", requestedPage.contentType },
{ "Content-Length", binaryContent ? requestedPage.BinaryContent.Length.ToString() : requestedPage.content.ToString().Length.ToString() }, { "Content-Length", binaryContent ? requestedPage.BinaryContent.Length.ToString() : requestedPage.content.ToString().Length.ToString() },
{ "Access-Control-Allow-Origin", "*" }, { "Access-Control-Allow-Origin", "*" },
{ "Cache-Control", $"public,max-age={maxAge}"}
} }
}; };

View File

@ -15,7 +15,8 @@ namespace IW4MAdmin
{ {
class ApplicationManager : IManager class ApplicationManager : IManager
{ {
public List<Server> Servers { get; private set; } private List<Server> _servers;
public List<Server> Servers => _servers.OrderByDescending(s => s.ClientNum).ToList();
public ILogger Logger { get; private set; } public ILogger Logger { get; private set; }
public bool Running { get; private set; } public bool Running { get; private set; }
@ -38,7 +39,7 @@ namespace IW4MAdmin
private ApplicationManager() private ApplicationManager()
{ {
Logger = new Logger("Logs/IW4MAdmin.log"); Logger = new Logger("Logs/IW4MAdmin.log");
Servers = new List<Server>(); _servers = new List<Server>();
Commands = new List<Command>(); Commands = new List<Command>();
TaskStatuses = new List<AsyncStatus>(); TaskStatuses = new List<AsyncStatus>();
MessageTokens = new List<MessageToken>(); MessageTokens = new List<MessageToken>();
@ -113,9 +114,9 @@ namespace IW4MAdmin
var ServerInstance = new IW4MServer(this, Conf); var ServerInstance = new IW4MServer(this, Conf);
await ServerInstance.Initialize(); await ServerInstance.Initialize();
lock (Servers) lock (_servers)
{ {
Servers.Add(ServerInstance); _servers.Add(ServerInstance);
} }
Logger.WriteVerbose($"Now monitoring {ServerInstance.Hostname}"); Logger.WriteVerbose($"Now monitoring {ServerInstance.Hostname}");
@ -210,7 +211,7 @@ namespace IW4MAdmin
foreach (var S in Servers) foreach (var S in Servers)
S.Broadcast("^1IW4MAdmin going offline!"); S.Broadcast("^1IW4MAdmin going offline!");
#endif #endif
Servers.Clear(); _servers.Clear();
WebThread.Abort(); WebThread.Abort();
webServiceTask.Stop(); webServiceTask.Stop();
} }
@ -250,7 +251,7 @@ namespace IW4MAdmin
{ {
var ActiveClients = new List<Player>(); var ActiveClients = new List<Player>();
foreach (var server in Servers) foreach (var server in _servers)
ActiveClients.AddRange(server.Players.Where(p => p != null)); ActiveClients.AddRange(server.Players.Where(p => p != null));
return ActiveClients; return ActiveClients;

View File

@ -206,8 +206,6 @@ namespace IW4MAdmin
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers) public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{ {
var info = new List<ServerInfo>(); var info = new List<ServerInfo>();
int i = 0;
foreach (Server S in ApplicationManager.GetInstance().Servers) foreach (Server S in ApplicationManager.GetInstance().Servers)
{ {
ServerInfo eachServer = new ServerInfo() ServerInfo eachServer = new ServerInfo()
@ -220,11 +218,9 @@ namespace IW4MAdmin
currentPlayers = S.GetPlayersAsList().Count, currentPlayers = S.GetPlayersAsList().Count,
chatHistory = S.ChatHistory, chatHistory = S.ChatHistory,
players = new List<PlayerInfo>(), players = new List<PlayerInfo>(),
ID = i PlayerHistory = S.PlayerHistory.ToArray()
}; };
i++;
bool authed = ApplicationManager.GetInstance().GetPrivilegedClients() bool authed = ApplicationManager.GetInstance().GetPrivilegedClients()
.Where(x => x.IP == querySet["IP"]) .Where(x => x.IP == querySet["IP"])
.Where(x => x.Level > Player.Permission.Trusted).Count() > 0 .Where(x => x.Level > Player.Permission.Trusted).Count() > 0
@ -253,7 +249,7 @@ namespace IW4MAdmin
return resp; return resp;
} }
public string GetContentType() public string GetContentType()
{ {
return "application/json"; return "application/json";
} }
@ -701,26 +697,18 @@ namespace IW4MAdmin
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers) public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{ {
List<PageInfo> pages = new List<PageInfo>();
var pages = SharedLibrary.WebService.PageList.Select(p => new
foreach (var p in SharedLibrary.WebService.PageList.Where(x => x.Visible()))
{ {
if (p == this) pagePath = p.GetPath(),
continue; pageName = p.GetName(),
visible = p.Visible(),
PageInfo pi = new PageInfo() });
{
pagePath = p.GetPath(),
pageName = p.GetName(),
visible = p.Visible()
};
pages.Add(pi);
}
HttpResponse resp = new HttpResponse() HttpResponse resp = new HttpResponse()
{ {
contentType = GetContentType(), contentType = GetContentType(),
content = Newtonsoft.Json.JsonConvert.SerializeObject(pages), content = Newtonsoft.Json.JsonConvert.SerializeObject(pages.ToArray()),
additionalHeaders = new Dictionary<string, string>() additionalHeaders = new Dictionary<string, string>()
}; };
return resp; return resp;
@ -846,6 +834,7 @@ namespace IW4MAdmin
public int maxPlayers; public int maxPlayers;
public List<Chat> chatHistory; public List<Chat> chatHistory;
public List<PlayerInfo> players; public List<PlayerInfo> players;
public SharedLibrary.Helpers.PlayerHistory[] PlayerHistory;
public int ID; public int ID;
} }

Binary file not shown.

View File

@ -1,6 +1,7 @@
</div> </div>
<div id="footer">&copy; RaidMax</div> <div id="footer">&copy; RaidMax</div>
</body> </body>
<script src="https://use.fontawesome.com/9c581fe29b.js"></script>
<script> <script>
getPages(); getPages();
</script> </script>

View File

@ -7,7 +7,6 @@
<link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'> <link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://use.fontawesome.com/9c581fe29b.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/canvasjs/1.7.0/canvasjs.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/canvasjs/1.7.0/canvasjs.min.js"></script>
<link rel="stylesheet" type="text/css" href="/webfront/main.css"/> <link rel="stylesheet" type="text/css" href="/webfront/main.css"/>

View File

@ -1,101 +1,99 @@
<script> <script>
var chartsRendered = false; function getPlayerHistoryChart(playerHistory, i) {
///////////////////////////////////////
return new CanvasJS.Chart(`graph-player-history-${i}`, {
backgroundColor: "#191919",
height: 100,
animationEnabled: true,
function renderPlayerHistory(id) { toolTip: {
$.getJSON("/_playerhistory?server=" + id, function (playerHistory) { contentFormatter: function (e) {
var date = new Date(e.entries[0].dataPoint.x * 1000);
return date.toLocaleTimeString('en-US', { timeZone: 'America/New_York', hour12: true }) + " - " + e.entries[0].dataPoint.y + " players";
}
},
var i = id; axisX: {
if ($("#server-" + i).children().length > 1) interval: 1,
return false; gridThickness: 0,
lineThickness: 0,
tickThickness: 0,
margin: 0,
valueFormatString: " ",
},
$("#server-" + i).append("<div class='player-history' id='graph-player-history-" + i + "'></div><hr/><br/><br/>"); axisY: {
gridThickness: 0,
lineThickness: 0,
tickThickness: 0,
minimum: 0,
margin: 0,
valueFormatString: " ",
labelMaxWidth: 0,
},
/////////////////////////////////////// legend: {
var chart = new CanvasJS.Chart("graph-player-history-" + i, maxWidth: 0,
{ maxHeight: 0,
backgroundColor: "#191919", dockInsidePlotArea: true,
height: 100, },
animationEnabled: true,
toolTip: { data: [{
contentFormatter: function (e) { showInLegend: false,
var date = new Date(e.entries[0].dataPoint.x * 1000); type: "splineArea",
return date.toLocaleTimeString('en-US', { timeZone: 'America/New_York', hour12: true }) + " - " + e.entries[0].dataPoint.y + " players"; color: "rgba(0, 122, 204, 0.432)",
} markerSize: 0,
}, dataPoints: playerHistory,
}]
axisX: {
interval: 1,
gridThickness: 0,
lineThickness: 0,
tickThickness: 0,
margin: 0,
valueFormatString: " ",
},
axisY: {
gridThickness: 0,
lineThickness: 0,
tickThickness: 0,
minimum: 0,
margin: 0,
valueFormatString: " ",
labelMaxWidth: 0,
},
legend: {
maxWidth: 0,
maxHeight: 0,
dockInsidePlotArea: true,
},
data: [{
showInLegend: false,
type: "splineArea",
color: "rgba(0, 122, 204, 0.432)",
markerSize: 0,
dataPoints: playerHistory,
}]
});
chart.render();
//////////////////////////////////////
}); });
//////////////////////////////////////
} }
function getServers() { function getServers() {
$.getJSON("/_servers", function (result) { $.getJSON("/_servers", function (result) {
result = result.sort(function (a, b) { return a.currentPlayers < b.currentPlayers });
$.each(result, function (i, server) { $.each(result, function (i, server) {
var selectedServer = $(`#server-${i}`);
if ($('#server-' + i).length < 1) if (selectedServer.length < 1) {
$('#serverList').append("<div id='server-" + i + "'></div>") $('#serverList').append(`<div id="server-${i}"><div class="serverContainer"></div></div>`);
selectedServer = $(`#server-${i}`);
selectedServer.append(`<div class="player-history" id="graph-player-history-${i}"></div><hr/><br/><br/>`)
}
$('#server-' + i + ' .serverContainer').remove();
$('#server-' + i).prepend("<div class='serverContainer'> \ var template =
<div class='serverInfo table'> \ `
<div class='serverTitle tableCell'>" + server['serverName'] + "</div> \ <div class ="serverInfo table">
<div class='serverMap tableCell'>" + server['mapName'] + "</div> \ <div class ="serverTitle tableCell">${server.serverName}</div>
<div class='serverPlayers tableCell'>" + server['currentPlayers'] + "/" + server['maxPlayers'] + "</div> \ <div class ="serverMap tableCell">${server.mapName}</div>
</div> \ <div class ="serverPlayers tableCell">${server.currentPlayers}/${server.maxPlayers}</div>
<div class='serverChatList table'>" + </div>
formatMessages(server['chatHistory']) <div class ="serverChatList table">${formatMessages(server.chatHistory)}</div>
+ "</div> \ <div class ="serverPlayerList table">${formatPlayers(server.players)}</div>
<div class='serverPlayerList table'>" + <div style="clear:both;"></div>
formatPlayers(server['players']) <hr/>`;
+ "</div> \
<div style='clear: both;'></div><hr/></div> \ selectedServer.find('.serverContainer').html(template);
</div>"
); if (!selectedServer.find(`#graph-player-history-${i}`).children().length) {
renderPlayerHistory(i); var historyGraph = getPlayerHistoryChart(server.PlayerHistory, i);
$(document).trigger("graphready", [historyGraph]);
}
}); });
}); });
} }
$(document).ready(function () { $(document).ready(function () {
getServers(); getServers();
setInterval(getServers, 1000) setInterval(getServers, 1000);
}); });
$(document).on("graphready", function (e, graph) {
// why is this so slow I have to call it async?
setTimeout(graph.render, 1);
})
</script> </script>
<div id="serverList"> <div id="serverList">
</div> </div>

View File

@ -7,6 +7,7 @@
<script> <script>
var killsList = []; var killsList = [];
var refreshInterval = 250;
function drawCircle(context, x, y, color) { function drawCircle(context, x, y, color) {
context.beginPath(); context.beginPath();
@ -100,7 +101,10 @@
checkCanvasSize(canvas, canvas[0].getContext("2d"), minimap, server.Minimap[0]); checkCanvasSize(canvas, canvas[0].getContext("2d"), minimap, server.Minimap[0]);
var furthestKill = 0; var furthestKill = 0;
$.each(newKills, function (i, kill) { $.each(newKills, function (i, kill) {
if (kill.Distance > furthestKill)
furthestKill = kill.Distance;
drawKill('1', canvas, server, kill); drawKill('1', canvas, server, kill);
}); });
@ -112,23 +116,31 @@
var html = '<span>' + server.ServerInfo.Uptime + ' of uptime</span><br/><span>Round started ' + server.ServerInfo.ElapsedRoundTime + '</span><br/>'; var html = '<span>' + server.ServerInfo.Uptime + ' of uptime</span><br/><span>Round started ' + server.ServerInfo.ElapsedRoundTime + '</span><br/>';
html += '<span>Furthest kill from ' + Math.round(furthestKill * 10) / 10 + ' meters</span><br/>'; html += '<span>Furthest kill from ' + Math.round(furthestKill * 10) / 10 + ' meters</span><br/>';
if (newKills.length > 0) if (newKills.length > 0) {
html += '<span class="last-kill">' + newKills[0].KillerPlayer + ' killed ' + newKills[0].VictimPlayer + '</span><br/>'; if (newKills[0].KillerPlayer != null)
html += '<span class="last-kill">' + newKills[0].KillerPlayer + ' killed ' + newKills[0].VictimPlayer + '</span><br/>';
else
html += `<span class="last-kill">Kill information pulled from database</span><br/>`;
}
else else
html += '<span class="last-kill">' + $('#stats-container-' + i).find('.last-kill').text() + '</span><br/>'; html += '<span class="last-kill">' + $('#stats-container-' + i).find('.last-kill').text() + '</span><br/>';
$('#stats-container-' + i + ' .stats-serverinfo').html(html); $('#stats-container-' + i + ' .stats-serverinfo').html(html);
}); });
}); });
setTimeout(loadKills, refreshInterval)
} }
$(document).ready(function () { $(document).ready(function () {
$('#KillEventCount').on('input change', function () { $('#KillEventCount').on('input change', function () {
$(this).next().text('Showing ' + $(this).val() + ' Kills'); $(this).next().text('Showing ' + $(this).val() + ' Kills');
if ($(this).val() > 300)
refreshInterval = 500;
else
refreshInterval = 250;
}); });
loadKills(); loadKills();
setInterval(loadKills, 1000);
}); });
</script> </script>

View File

@ -268,7 +268,7 @@ namespace StatsPlugin
CalculateAndSaveSkill(P, statLists.Find(x => x.Port == S.GetPort())); CalculateAndSaveSkill(P, statLists.Find(x => x.Port == S.GetPort()));
ResetCounters(P.ClientID, S.GetPort()); ResetCounters(P.ClientID, S.GetPort());
E.Owner.Logger.WriteInfo("Updated skill for client #" + P.DatabaseID); E.Owner.Logger.WriteInfo($"Updated skill for {P}");
//E.Owner.Log.Write(String.Format("\r\nJoin: {0}\r\nInactive Minutes: {1}\r\nnewPlayTime: {2}\r\nnewSPM: {3}\r\nkdrWeight: {4}\r\nMultiplier: {5}\r\nscoreWeight: {6}\r\nnewSkillFactor: {7}\r\nprojectedNewSkill: {8}\r\nKills: {9}\r\nDeaths: {10}", connectionTime[P.clientID].ToShortTimeString(), inactiveMinutes[P.clientID], newPlayTime, newSPM, kdrWeight, Multiplier, scoreWeight, newSkillFactor, disconnectStats.Skill, disconnectStats.Kills, disconnectStats.Deaths)); //E.Owner.Log.Write(String.Format("\r\nJoin: {0}\r\nInactive Minutes: {1}\r\nnewPlayTime: {2}\r\nnewSPM: {3}\r\nkdrWeight: {4}\r\nMultiplier: {5}\r\nscoreWeight: {6}\r\nnewSkillFactor: {7}\r\nprojectedNewSkill: {8}\r\nKills: {9}\r\nDeaths: {10}", connectionTime[P.clientID].ToShortTimeString(), inactiveMinutes[P.clientID], newPlayTime, newSPM, kdrWeight, Multiplier, scoreWeight, newSkillFactor, disconnectStats.Skill, disconnectStats.Kills, disconnectStats.Deaths));
} }
} }
@ -311,6 +311,7 @@ namespace StatsPlugin
ServerStats[S.GetPort()].GetKillQueue().Enqueue(killEvent); ServerStats[S.GetPort()].GetKillQueue().Enqueue(killEvent);
//S.Logger.WriteInfo($"{E.Origin.Name} killed {E.Target.Name} with a {killEvent.Weapon} from a distance of {Vector3.Distance(killEvent.KillOrigin, killEvent.DeathOrigin)} with {killEvent.Damage} damage, at {killEvent.HitLoc}"); //S.Logger.WriteInfo($"{E.Origin.Name} killed {E.Target.Name} with a {killEvent.Weapon} from a distance of {Vector3.Distance(killEvent.KillOrigin, killEvent.DeathOrigin)} with {killEvent.Damage} damage, at {killEvent.HitLoc}");
curServer.playerStats.AddKill(killEvent); curServer.playerStats.AddKill(killEvent);
S.Logger.WriteInfo(killEvent.ID.ToString());
return; return;
} }
@ -521,10 +522,10 @@ namespace StatsPlugin
return resultList; return resultList;
} }
public List<Stats.KillInfo> GetKillsByMap(Map map) public List<Stats.KillInfo> GetKillsByMap(Map map, int count)
{ {
var mapID = ParseEnum<IW4Info.MapName>.Get(map.Name, typeof(IW4Info.MapName)); var mapID = ParseEnum<IW4Info.MapName>.Get(map.Name, typeof(IW4Info.MapName));
var queryResult = GetDataTable($"select * from KILLS where MapID == {(int)mapID} LIMIT 500 OFFSET (SELECT COUNT(*) FROM KILLS)-500"); //GetDataTable("KILLS", new KeyValuePair<string, object>("MapID", mapID)); var queryResult = GetDataTable($"select * from KILLS where MapID == {(int)mapID} LIMIT {count} OFFSET (SELECT COUNT(*) FROM KILLS)-500"); //GetDataTable("KILLS", new KeyValuePair<string, object>("MapID", mapID));
var resultList = new List<Stats.KillInfo>(); var resultList = new List<Stats.KillInfo>();
if (queryResult?.Rows.Count > 0) if (queryResult?.Rows.Count > 0)

View File

@ -55,8 +55,9 @@ namespace StatsPlugin
ServerMap = s.CurrentMap.Alias, ServerMap = s.CurrentMap.Alias,
ServerInfo = Stats.ServerStats[s.GetPort()], ServerInfo = Stats.ServerStats[s.GetPort()],
Minimap = MinimapConfig.Read(@"Config\minimaps.cfg").MapInfo.Where(m => m.MapName == s.CurrentMap.Name), Minimap = MinimapConfig.Read(@"Config\minimaps.cfg").MapInfo.Where(m => m.MapName == s.CurrentMap.Name),
MapKills = Stats.ServerStats[s.GetPort()].GetKillQueue().ToArray() MapKills = selectCount < 300 ? Stats.ServerStats[s.GetPort()].GetKillQueue().ToArray()
.Skip(Math.Min(Stats.MAX_KILLEVENTS - selectCount, Stats.ServerStats[s.GetPort()].GetKillQueue().Count - selectCount)) .Skip(Math.Min(Stats.MAX_KILLEVENTS - selectCount, Stats.ServerStats[s.GetPort()].GetKillQueue().Count - selectCount)) :
Stats.statLists.FirstOrDefault(x => x.Port == s.GetPort()).playerStats.GetKillsByMap(s.CurrentMap, selectCount)
}) })
}, },
additionalHeaders = new Dictionary<string, string>() additionalHeaders = new Dictionary<string, string>()

View File

@ -74,14 +74,17 @@ namespace IW4MAdmin.Plugins
string[] eventLine = null; string[] eventLine = null;
if (S.GameName == Server.Game.IW4) for (int i = 0; i < 1; i++)
{ {
// attackerID ; victimID ; attackerOrigin ; victimOrigin ; Damage ; Weapon ; hitLocation ; meansOfDeath if (S.GameName == Server.Game.IW4)
var minimapInfo = StatsPlugin.MinimapConfig.IW4Minimaps().MapInfo.FirstOrDefault(m => m.MapName == S.CurrentMap.Name);
if (minimapInfo == null)
return;
eventLine = new string[]
{ {
// attackerID ; victimID ; attackerOrigin ; victimOrigin ; Damage ; Weapon ; hitLocation ; meansOfDeath
var minimapInfo = StatsPlugin.MinimapConfig.IW4Minimaps().MapInfo.FirstOrDefault(m => m.MapName == S.CurrentMap.Name);
if (minimapInfo == null)
return;
eventLine = new string[]
{
"ScriptKill", "ScriptKill",
attackerPlayer.NetworkID, attackerPlayer.NetworkID,
victimPlayer.NetworkID, victimPlayer.NetworkID,
@ -91,13 +94,13 @@ namespace IW4MAdmin.Plugins
((StatsPlugin.IW4Info.WeaponName)rand.Next(0, Enum.GetValues(typeof(StatsPlugin.IW4Info.WeaponName)).Length - 1)).ToString(), ((StatsPlugin.IW4Info.WeaponName)rand.Next(0, Enum.GetValues(typeof(StatsPlugin.IW4Info.WeaponName)).Length - 1)).ToString(),
((StatsPlugin.IW4Info.HitLocation)rand.Next(0, Enum.GetValues(typeof(StatsPlugin.IW4Info.HitLocation)).Length - 1)).ToString(), ((StatsPlugin.IW4Info.HitLocation)rand.Next(0, Enum.GetValues(typeof(StatsPlugin.IW4Info.HitLocation)).Length - 1)).ToString(),
((StatsPlugin.IW4Info.MeansOfDeath)rand.Next(0, Enum.GetValues(typeof(StatsPlugin.IW4Info.MeansOfDeath)).Length - 1)).ToString() ((StatsPlugin.IW4Info.MeansOfDeath)rand.Next(0, Enum.GetValues(typeof(StatsPlugin.IW4Info.MeansOfDeath)).Length - 1)).ToString()
}; };
}
else }
{ else
eventLine = new string[] {
{ eventLine = new string[]
{
"K", "K",
victimPlayer.NetworkID, victimPlayer.NetworkID,
victimPlayer.ClientID.ToString(), victimPlayer.ClientID.ToString(),
@ -111,11 +114,12 @@ namespace IW4MAdmin.Plugins
rand.Next(50, 105).ToString(), // Damage rand.Next(50, 105).ToString(), // Damage
((StatsPlugin.IW4Info.MeansOfDeath)rand.Next(0, Enum.GetValues(typeof(StatsPlugin.IW4Info.MeansOfDeath)).Length - 1)).ToString(), // Means of Death ((StatsPlugin.IW4Info.MeansOfDeath)rand.Next(0, Enum.GetValues(typeof(StatsPlugin.IW4Info.MeansOfDeath)).Length - 1)).ToString(), // Means of Death
((StatsPlugin.IW4Info.HitLocation)rand.Next(0, Enum.GetValues(typeof(StatsPlugin.IW4Info.HitLocation)).Length - 1)).ToString(), // Hit Location ((StatsPlugin.IW4Info.HitLocation)rand.Next(0, Enum.GetValues(typeof(StatsPlugin.IW4Info.HitLocation)).Length - 1)).ToString(), // Hit Location
}; };
} }
var _event = Event.ParseEventString(eventLine, S); var _event = Event.ParseEventString(eventLine, S);
await S.ExecuteEvent(_event); await S.ExecuteEvent(_event);
}
} }
} }