-added back player history graphs (past 12 hours every 15 minutes)
-fixed issue with configurationmanager files and threading -servers on webfront listed in descending player count -fixed resolution of tempban times from console feedback -Added tests plugin to simulate functionality
This commit is contained in:
parent
9227335d25
commit
8d52d7ddc5
@ -174,9 +174,6 @@
|
|||||||
<Content Include="webfront\footer.html">
|
<Content Include="webfront\footer.html">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="webfront\graph.html">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="webfront\header.html">
|
<Content Include="webfront\header.html">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
@ -187,7 +184,7 @@
|
|||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="webfront\main.html">
|
<Content Include="webfront\main.html">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="webfront\mobile.css">
|
<Content Include="webfront\mobile.css">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
@ -69,7 +69,10 @@ namespace IW4MAdmin
|
|||||||
|
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
ApplicationManager.GetInstance().Logger.WriteError($"Webfront error during request: {e.Message}");
|
ApplicationManager.GetInstance().Logger.WriteError($"Webfront error during request");
|
||||||
|
ApplicationManager.GetInstance().Logger.WriteDebug($"Message: {e.Message}");
|
||||||
|
ApplicationManager.GetInstance().Logger.WriteDebug($"Stack Trace: {e.StackTrace}");
|
||||||
|
|
||||||
response.OnResponse(new HttpResponseHead()
|
response.OnResponse(new HttpResponseHead()
|
||||||
{
|
{
|
||||||
Status = "500 Internal Server Error",
|
Status = "500 Internal Server Error",
|
||||||
|
@ -28,6 +28,7 @@ namespace IW4MAdmin
|
|||||||
List<MessageToken> MessageTokens;
|
List<MessageToken> MessageTokens;
|
||||||
Kayak.IScheduler webServiceTask;
|
Kayak.IScheduler webServiceTask;
|
||||||
Thread WebThread;
|
Thread WebThread;
|
||||||
|
List<Player> PrivilegedClients;
|
||||||
#if FTP_LOG
|
#if FTP_LOG
|
||||||
const int UPDATE_FREQUENCY = 15000;
|
const int UPDATE_FREQUENCY = 15000;
|
||||||
#else
|
#else
|
||||||
@ -179,11 +180,17 @@ namespace IW4MAdmin
|
|||||||
WebThread.Start();
|
WebThread.Start();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region ADMINS
|
||||||
|
PrivilegedClients = GetClientDatabase().GetAdmins();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
Running = true;
|
Running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
|
var a = Utilities.DateTimeSQLite(DateTime.MinValue);
|
||||||
while (Running)
|
while (Running)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < TaskStatuses.Count; i++)
|
for (int i = 0; i < TaskStatuses.Count; i++)
|
||||||
@ -197,7 +204,7 @@ namespace IW4MAdmin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread.Sleep(300);
|
Thread.Sleep(UPDATE_FREQUENCY);
|
||||||
}
|
}
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
foreach (var S in Servers)
|
foreach (var S in Servers)
|
||||||
@ -277,6 +284,11 @@ namespace IW4MAdmin
|
|||||||
return allAliases;
|
return allAliases;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IList<Player> GetPrivilegedClients()
|
||||||
|
{
|
||||||
|
return PrivilegedClients;
|
||||||
|
}
|
||||||
|
|
||||||
private void GetAliases(List<Aliases> returnAliases, Aliases currentAlias)
|
private void GetAliases(List<Aliases> returnAliases, Aliases currentAlias)
|
||||||
{
|
{
|
||||||
foreach (String IP in currentAlias.IPS)
|
foreach (String IP in currentAlias.IPS)
|
||||||
|
@ -291,6 +291,9 @@ namespace IW4MAdmin
|
|||||||
|
|
||||||
async Task<int> PollPlayersAsync()
|
async Task<int> PollPlayersAsync()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
return Players.Where(p => p != null).Count();
|
||||||
|
#endif
|
||||||
var CurrentPlayers = await this.GetStatusAsync();
|
var CurrentPlayers = await this.GetStatusAsync();
|
||||||
|
|
||||||
for (int i = 0; i < Players.Count; i++)
|
for (int i = 0; i < Players.Count; i++)
|
||||||
@ -357,15 +360,15 @@ namespace IW4MAdmin
|
|||||||
tickTime = DateTime.Now;
|
tickTime = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((lastCount - playerCountStart).TotalMinutes > 4)
|
if ((lastCount - playerCountStart).TotalMinutes >= 15)
|
||||||
{
|
{
|
||||||
while (PlayerHistory.Count > 144) // 12 times a minute for 12 hours
|
while (PlayerHistory.Count > 48) // 4 times a hour for 12 hours
|
||||||
PlayerHistory.Dequeue();
|
PlayerHistory.Dequeue();
|
||||||
PlayerHistory.Enqueue(new SharedLibrary.Helpers.PlayerHistory(lastCount, ClientNum));
|
PlayerHistory.Enqueue(new SharedLibrary.Helpers.PlayerHistory(ClientNum));
|
||||||
playerCountStart = DateTime.Now;
|
playerCountStart = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LastMessage.TotalSeconds > MessageTime && BroadcastMessages.Count > 0 /*&& ClientNum > 0*/)
|
if (LastMessage.TotalSeconds > MessageTime && BroadcastMessages.Count > 0 && ClientNum > 0)
|
||||||
{
|
{
|
||||||
await Broadcast(Utilities.ProcessMessageToken(Manager.GetMessageTokens(), BroadcastMessages[NextMessage]));
|
await Broadcast(Utilities.ProcessMessageToken(Manager.GetMessageTokens(), BroadcastMessages[NextMessage]));
|
||||||
NextMessage = NextMessage == (BroadcastMessages.Count - 1) ? 0 : NextMessage + 1;
|
NextMessage = NextMessage == (BroadcastMessages.Count - 1) ? 0 : NextMessage + 1;
|
||||||
@ -489,7 +492,7 @@ namespace IW4MAdmin
|
|||||||
}
|
}
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
basepath.Value = (GameName == Game.IW4) ?
|
basepath.Value = (GameName == Game.IW4) ?
|
||||||
@"\\tsclient\K\MW2" :
|
@"\\tsclient\J\WIN7_10.25\MW2" :
|
||||||
@"\\tsclient\G\Program Files (x86)\Steam\SteamApps\common\Call of Duty 4";
|
@"\\tsclient\G\Program Files (x86)\Steam\SteamApps\common\Call of Duty 4";
|
||||||
#endif
|
#endif
|
||||||
string mainPath = (GameName == Game.IW4) ? "userraw" : "main";
|
string mainPath = (GameName == Game.IW4) ? "userraw" : "main";
|
||||||
|
@ -22,6 +22,7 @@ namespace IW4MAdmin
|
|||||||
SharedLibrary.WebService.PageList.Add(new Pages());
|
SharedLibrary.WebService.PageList.Add(new Pages());
|
||||||
SharedLibrary.WebService.PageList.Add(new Homepage());
|
SharedLibrary.WebService.PageList.Add(new Homepage());
|
||||||
SharedLibrary.WebService.PageList.Add(new ServersJSON());
|
SharedLibrary.WebService.PageList.Add(new ServersJSON());
|
||||||
|
SharedLibrary.WebService.PageList.Add(new PlayerHistoryJSON());
|
||||||
SharedLibrary.WebService.PageList.Add(new Penalties());
|
SharedLibrary.WebService.PageList.Add(new Penalties());
|
||||||
SharedLibrary.WebService.PageList.Add(new PenaltiesJSON());
|
SharedLibrary.WebService.PageList.Add(new PenaltiesJSON());
|
||||||
SharedLibrary.WebService.PageList.Add(new Players());
|
SharedLibrary.WebService.PageList.Add(new Players());
|
||||||
@ -196,6 +197,7 @@ namespace IW4MAdmin
|
|||||||
{
|
{
|
||||||
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()
|
||||||
@ -207,10 +209,16 @@ namespace IW4MAdmin
|
|||||||
gameType = Utilities.GetLocalizedGametype(S.Gametype),
|
gameType = Utilities.GetLocalizedGametype(S.Gametype),
|
||||||
currentPlayers = S.GetPlayersAsList().Count,
|
currentPlayers = S.GetPlayersAsList().Count,
|
||||||
chatHistory = S.ChatHistory,
|
chatHistory = S.ChatHistory,
|
||||||
players = new List<PlayerInfo>()
|
players = new List<PlayerInfo>(),
|
||||||
|
ID = i
|
||||||
};
|
};
|
||||||
bool authed = ApplicationManager.GetInstance().GetClientDatabase().GetAdmins().FindAll(x => x.IP == querySet["IP"] && x.Level > Player.Permission.Trusted).Count > 0
|
|
||||||
|| querySet["IP"] == "127.0.0.1";
|
i++;
|
||||||
|
|
||||||
|
bool authed = ApplicationManager.GetInstance().GetPrivilegedClients()
|
||||||
|
.Where(x => x.IP == querySet["IP"])
|
||||||
|
.Where(x => x.Level > Player.Permission.Trusted).Count() > 0
|
||||||
|
|| querySet["IP"] == "127.0.0.1";
|
||||||
|
|
||||||
foreach (Player P in S.GetPlayersAsList())
|
foreach (Player P in S.GetPlayersAsList())
|
||||||
{
|
{
|
||||||
@ -226,7 +234,6 @@ namespace IW4MAdmin
|
|||||||
info.Add(eachServer);
|
info.Add(eachServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HttpResponse resp = new HttpResponse()
|
HttpResponse resp = new HttpResponse()
|
||||||
{
|
{
|
||||||
contentType = GetContentType(),
|
contentType = GetContentType(),
|
||||||
@ -247,6 +254,54 @@ namespace IW4MAdmin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class PlayerHistoryJSON : IPage
|
||||||
|
{
|
||||||
|
public string GetName()
|
||||||
|
{
|
||||||
|
return "Player History";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetPath()
|
||||||
|
{
|
||||||
|
return "/_playerhistory";
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
|
||||||
|
{
|
||||||
|
|
||||||
|
var history = new SharedLibrary.Helpers.PlayerHistory[0];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int id = Int32.Parse(querySet["server"]);
|
||||||
|
history = ApplicationManager.GetInstance().GetServers()[id].PlayerHistory.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpResponse resp = new HttpResponse()
|
||||||
|
{
|
||||||
|
contentType = GetContentType(),
|
||||||
|
content = Newtonsoft.Json.JsonConvert.SerializeObject(history),
|
||||||
|
additionalHeaders = new Dictionary<string, string>()
|
||||||
|
};
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetContentType()
|
||||||
|
{
|
||||||
|
return "application/json";
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Visible()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class Info : IPage
|
class Info : IPage
|
||||||
{
|
{
|
||||||
public string GetName()
|
public string GetName()
|
||||||
@ -412,7 +467,8 @@ namespace IW4MAdmin
|
|||||||
penaltyTime = Utilities.GetTimePassed(p.When),
|
penaltyTime = Utilities.GetTimePassed(p.When),
|
||||||
penaltyType = p.BType.ToString(),
|
penaltyType = p.BType.ToString(),
|
||||||
playerName = penalized.Name,
|
playerName = penalized.Name,
|
||||||
playerID = penalized.DatabaseID
|
playerID = penalized.DatabaseID,
|
||||||
|
Expires = p.Expires > DateTime.Now ? (p.Expires - DateTime.Now).TimeSpanText() : ""
|
||||||
};
|
};
|
||||||
|
|
||||||
if (admin.NetworkID == penalized.NetworkID)
|
if (admin.NetworkID == penalized.NetworkID)
|
||||||
@ -718,7 +774,7 @@ namespace IW4MAdmin
|
|||||||
|
|
||||||
else if (querySet["recent"] != null)
|
else if (querySet["recent"] != null)
|
||||||
{
|
{
|
||||||
matchedPlayers = ApplicationManager.GetInstance().GetClientDatabase().GetRecentPlayers();
|
matchedPlayers = ApplicationManager.GetInstance().GetClientDatabase().GetRecentPlayers();
|
||||||
recent = true;
|
recent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -780,6 +836,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 int ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
@ -825,6 +882,7 @@ namespace IW4MAdmin
|
|||||||
public string penaltyType;
|
public string penaltyType;
|
||||||
public string penaltyReason;
|
public string penaltyReason;
|
||||||
public string penaltyTime;
|
public string penaltyTime;
|
||||||
|
public string Expires;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
|
Binary file not shown.
@ -1,4 +1,11 @@
|
|||||||
VERSION 1.4
|
Versino 1.5
|
||||||
|
CHANGELOG:
|
||||||
|
-added back player history graphs (past 12 hours every 15 minutes)
|
||||||
|
-fixed issue with configurationmanager files and threading
|
||||||
|
-servers on webfront listed in descending player count
|
||||||
|
-fixed resolution of tempban times from console feedback
|
||||||
|
|
||||||
|
VERSION 1.4
|
||||||
CHANGELOG:
|
CHANGELOG:
|
||||||
-works: with COD, WaW, MW3, BO1 (preliminary without extensive testing)
|
-works: with COD, WaW, MW3, BO1 (preliminary without extensive testing)
|
||||||
-fixed the issue with webfront chat history
|
-fixed the issue with webfront chat history
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
<script type="text/javascript" src="//www.google.com/jsapi"></script>
|
|
||||||
<script>
|
|
||||||
|
|
||||||
google.load('visualization', '1', { callback: drawChart, packages: ['corechart'] });
|
|
||||||
google.setOnLoadCallback(drawChart);
|
|
||||||
|
|
||||||
function drawChart() {
|
|
||||||
|
|
||||||
var data = new google.visualization.DataTable();
|
|
||||||
data.addColumn('datetime', 'Time');
|
|
||||||
data.addColumn('number', 'Players');
|
|
||||||
|
|
||||||
data.addRows(players);
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
//curveType: 'function', still haven't decided on this
|
|
||||||
height: 300,
|
|
||||||
legend: {position: 'none'},
|
|
||||||
enableInteractivity: true,
|
|
||||||
chartArea: {
|
|
||||||
width: '93%'
|
|
||||||
},
|
|
||||||
vAxis: {
|
|
||||||
title: 'Players',
|
|
||||||
gridlines: { count: 7 },
|
|
||||||
viewWindowMode: 'explicit',
|
|
||||||
viewWindow: {
|
|
||||||
min: 0,
|
|
||||||
max: 18 // for iw4
|
|
||||||
},
|
|
||||||
},
|
|
||||||
hAxis: {
|
|
||||||
viewWindow: {
|
|
||||||
//min: players[0][0], no longer needed as timeline adjusts automatically
|
|
||||||
//max: players[players.length-1][0] // ditto
|
|
||||||
},
|
|
||||||
gridlines: {
|
|
||||||
count: 12,
|
|
||||||
units: {
|
|
||||||
days: {format: ["MMM dd"]},
|
|
||||||
hours: {format: ["HH:mm", "ha"]},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
minorGridlines: {
|
|
||||||
count: 5,
|
|
||||||
units: {
|
|
||||||
hours: {format: ["hh:mm:ss a", "ha"]},
|
|
||||||
minutes: {format: ["HH:mm a Z", ":mm"]}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
|
|
||||||
chart.draw(data, options);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
{{GRAPH}}
|
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
<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://use.fontawesome.com/9c581fe29b.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"/>
|
||||||
<link rel="stylesheet" type="text/css" href="/webfront/mobile.css"/>
|
<link rel="stylesheet" type="text/css" href="/webfront/mobile.css"/>
|
||||||
|
@ -15,7 +15,7 @@ div#header #navContainer .navEntry a { padding: 1.2vw; width: 4vw; }
|
|||||||
div#header #navContainer .navEntry:hover { background-color: rgb(34, 34, 34); }
|
div#header #navContainer .navEntry:hover { background-color: rgb(34, 34, 34); }
|
||||||
|
|
||||||
div#content { margin: 3em 10%; }
|
div#content { margin: 3em 10%; }
|
||||||
div#content .serverContainer { background-color: #191919; margin: 2em 0; font-size: 1.25vw; }
|
div#content .serverContainer { background-color: #191919; margin-top 0; margin-bottom: 0; font-size: 1.25vw; padding-bottom: 100px; }
|
||||||
div#content hr { border-width: 0; height: 0.25em; background-color: #007ACC; }
|
div#content hr { border-width: 0; height: 0.25em; background-color: #007ACC; }
|
||||||
div#content .serverInfo { width: 100%; }
|
div#content .serverInfo { width: 100%; }
|
||||||
div#content .serverInfo .tableCell { padding: 0 0.5em; }
|
div#content .serverInfo .tableCell { padding: 0 0.5em; }
|
||||||
@ -31,13 +31,15 @@ div#content .chatPlayerName { font-weight: bold; font-size: 1.1vw; color:#fff; p
|
|||||||
div#content .chatPlayerMessage {font-size: 1.1vw; color: #fff; opacity: 1; }
|
div#content .chatPlayerMessage {font-size: 1.1vw; color: #fff; opacity: 1; }
|
||||||
|
|
||||||
div#content .playerPenalty, div#content .playerInfo { margin: 0 auto; padding: 1em 10px; background-color: #181818; width: calc(100% - 20px); }
|
div#content .playerPenalty, div#content .playerInfo { margin: 0 auto; padding: 1em 10px; background-color: #181818; width: calc(100% - 20px); }
|
||||||
div#content .penaltyName { width: 14.28%; }
|
div#content .penaltyName { width: 15%; }
|
||||||
div#content .penaltyName a:link, div#content .penaltyName a:visited, div#content .playerInfo a:link, div#content .playerInfo a:visited { color: rgb(0, 122, 204) !important; }
|
div#content .penaltyName a:link, div#content .penaltyName a:visited, div#content .playerInfo a:link, div#content .playerInfo a:visited { color: rgb(0, 122, 204) !important; }
|
||||||
div#content .penaltyName a:hover, div#content .playerInfo a:hover { color: rgb(255, 255, 255) !important; opacity: 0.75; }
|
div#content .penaltyName a:hover, div#content .playerInfo a:hover { color: rgb(255, 255, 255) !important; opacity: 0.75; }
|
||||||
div#content .penaltyTime { text-align: right; width: 12.5%; }
|
div#content .penaltyTime { text-align: left; width:8%; }
|
||||||
|
div#content .penaltyOrigin {width: 12%;}
|
||||||
|
div#content .penaltyRemaining { text-align: right; width: 10%:}
|
||||||
div#content .playerPenalty .penaltyTime { opacity: 0.5; }
|
div#content .playerPenalty .penaltyTime { opacity: 0.5; }
|
||||||
div#content .penaltyType { width: 12.5%; }
|
div#content .penaltyType { width: 10%; }
|
||||||
div#content .penaltyReason { width: 50%; }
|
div#content .penaltyReason { width: 45%; }
|
||||||
div#content .playerPenalty .tableCell { }
|
div#content .playerPenalty .tableCell { }
|
||||||
div#content .penaltyHeader, div#content .contentHeader { width: calc(100% - 20px); background-color: #007ACC; font-size: 15pt; padding: 0.5em 10px; }
|
div#content .penaltyHeader, div#content .contentHeader { width: calc(100% - 20px); background-color: #007ACC; font-size: 15pt; padding: 0.5em 10px; }
|
||||||
div#content .alternate_1 { background-color: rgb(34, 34, 34); }
|
div#content .alternate_1 { background-color: rgb(34, 34, 34); }
|
||||||
@ -199,3 +201,5 @@ div#footer { position: fixed; bottom: 0.5em; right: 0.5em; opacity: 0.5; }
|
|||||||
.admin-name a { font-size: 14pt; color: #007ACC !important; }
|
.admin-name a { font-size: 14pt; color: #007ACC !important; }
|
||||||
.admin-name a:hover { color: #fff !important; }
|
.admin-name a:hover { color: #fff !important; }
|
||||||
.clients { margin: 0.5em; }
|
.clients { margin: 0.5em; }
|
||||||
|
.canvasjs-chart-credit { display: none; }
|
||||||
|
.player-history { margin-top: -100px; height: 100px; }
|
@ -1,31 +1,101 @@
|
|||||||
<script>
|
<script>
|
||||||
function getServers()
|
var chartsRendered = false;
|
||||||
{
|
|
||||||
$.getJSON("/_servers", function(result){
|
function renderPlayerHistory(id) {
|
||||||
$("#serverList").html("");
|
$.getJSON("/_playerhistory?server=" + id, function (playerHistory) {
|
||||||
$.each(result, function(i, server){
|
|
||||||
$("#serverList").append("<div class=serverContainer> \
|
var i = id;
|
||||||
|
if ($("#server-" + i).children().length > 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
$("#server-" + i).append("<div class='player-history' id='graph-player-history-" + i + "'></div><hr/><br/><br/>");
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
var chart = new CanvasJS.Chart("graph-player-history-" + i,
|
||||||
|
{
|
||||||
|
backgroundColor: "#191919",
|
||||||
|
height: 100,
|
||||||
|
animationEnabled: true,
|
||||||
|
|
||||||
|
toolTip: {
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
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() {
|
||||||
|
$.getJSON("/_servers", function (result) {
|
||||||
|
result = result.sort(function (a, b) { return a.currentPlayers < b.currentPlayers });
|
||||||
|
$.each(result, function (i, server) {
|
||||||
|
|
||||||
|
if ($('#server-' + i).length < 1)
|
||||||
|
$('#serverList').append("<div id='server-" + i + "'></div>")
|
||||||
|
|
||||||
|
$('#server-' + i + ' .serverContainer').remove();
|
||||||
|
|
||||||
|
$('#server-' + i).prepend("<div class='serverContainer'> \
|
||||||
<div class='serverInfo table'> \
|
<div class='serverInfo table'> \
|
||||||
<div class='serverTitle tableCell'>" + server['serverName'] + "</div> \
|
<div class='serverTitle tableCell'>" + server['serverName'] + "</div> \
|
||||||
<div class='serverMap tableCell'>" + server['mapName'] + "</div> \
|
<div class='serverMap tableCell'>" + server['mapName'] + "</div> \
|
||||||
<div class='serverPlayers tableCell'>" + server['currentPlayers'] + "/" + server['maxPlayers'] + "</div> \
|
<div class='serverPlayers tableCell'>" + server['currentPlayers'] + "/" + server['maxPlayers'] + "</div> \
|
||||||
</div> \
|
</div> \
|
||||||
<div class='serverChatList table'>" +
|
<div class='serverChatList table'>" +
|
||||||
formatMessages(server['chatHistory'])
|
formatMessages(server['chatHistory'])
|
||||||
+ "</div> \
|
+ "</div> \
|
||||||
<div class='serverPlayerList table'>" +
|
<div class='serverPlayerList table'>" +
|
||||||
formatPlayers(server['players'])
|
formatPlayers(server['players'])
|
||||||
+ "</div> \
|
+ "</div> \
|
||||||
<div style='clear: both;'></div><hr/></div>"
|
<div style='clear: both;'></div><hr/></div> \
|
||||||
);
|
</div>"
|
||||||
});
|
);
|
||||||
});
|
renderPlayerHistory(i);
|
||||||
}
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
$( document ).ready(function() {
|
$(document).ready(function () {
|
||||||
getServers();
|
getServers();
|
||||||
setInterval(getServers, 1000)
|
setInterval(getServers, 1000)
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<div id="serverList">
|
<div id="serverList">
|
||||||
</div>
|
</div>
|
||||||
|
@ -34,6 +34,7 @@ function getPenalties(from)
|
|||||||
<div class=\"penaltyReason tableCell\">"+ penalty['penaltyReason'] + "</div> \
|
<div class=\"penaltyReason tableCell\">"+ penalty['penaltyReason'] + "</div> \
|
||||||
<div class=\"penaltyOrigin tableCell\">"+ getColorForLevel(penalty['adminLevel'], penalty['adminName']) + "</div> \
|
<div class=\"penaltyOrigin tableCell\">"+ getColorForLevel(penalty['adminLevel'], penalty['adminName']) + "</div> \
|
||||||
<div class=\"penaltyTime tableCell\">"+ penalty['penaltyTime'] + "</div> \
|
<div class=\"penaltyTime tableCell\">"+ penalty['penaltyTime'] + "</div> \
|
||||||
|
<div class=\" penaltyRemaining tableCell\">" + penalty['Expires'] + "</div> \
|
||||||
</div>"
|
</div>"
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
@ -51,6 +52,7 @@ $( document ).ready(function() {
|
|||||||
<div class="penaltyReason tableCell">Reason</div>
|
<div class="penaltyReason tableCell">Reason</div>
|
||||||
<div class="penaltyOrigin tableCell">Admin</div>
|
<div class="penaltyOrigin tableCell">Admin</div>
|
||||||
<div class="penaltyTime tableCell">Time</div>
|
<div class="penaltyTime tableCell">Time</div>
|
||||||
|
<div class="penaltyRemaining tableCell">Remaining</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="penaltyList">
|
<div id="penaltyList">
|
||||||
</div>
|
</div>
|
||||||
|
@ -39,6 +39,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||||||
README.md = README.md
|
README.md = README.md
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Plugins\Tests\Tests.csproj", "{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -303,6 +305,38 @@ Global
|
|||||||
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|x64.Build.0 = Release|Any CPU
|
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|x64.Build.0 = Release|Any CPU
|
||||||
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|x86.ActiveCfg = Release|Any CPU
|
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|x86.ActiveCfg = Release|Any CPU
|
||||||
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|x86.Build.0 = Release|Any CPU
|
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|x86.Build.0 = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Nightly|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Nightly|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Nightly|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Nightly|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Nightly|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Nightly|x64.Build.0 = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Nightly|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Nightly|x86.Build.0 = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Stable|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Stable|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Stable|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Stable|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Stable|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Stable|x64.Build.0 = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Stable|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Stable|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@ -314,5 +348,6 @@ Global
|
|||||||
{E46C85BD-A99C-484E-BCCE-0F1831C5925E} = {26E8B310-269E-46D4-A612-24601F16065F}
|
{E46C85BD-A99C-484E-BCCE-0F1831C5925E} = {26E8B310-269E-46D4-A612-24601F16065F}
|
||||||
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650} = {26E8B310-269E-46D4-A612-24601F16065F}
|
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650} = {26E8B310-269E-46D4-A612-24601F16065F}
|
||||||
{1479DE87-ACB5-4046-81C8-A0BA5041227D} = {26E8B310-269E-46D4-A612-24601F16065F}
|
{1479DE87-ACB5-4046-81C8-A0BA5041227D} = {26E8B310-269E-46D4-A612-24601F16065F}
|
||||||
|
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1} = {26E8B310-269E-46D4-A612-24601F16065F}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
78
Plugins/Tests/Plugin.cs
Normal file
78
Plugins/Tests/Plugin.cs
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#if DEBUG
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using SharedLibrary;
|
||||||
|
using SharedLibrary.Interfaces;
|
||||||
|
using SharedLibrary.Helpers;
|
||||||
|
|
||||||
|
namespace IW4MAdmin.Plugins
|
||||||
|
{
|
||||||
|
public class Tests : IPlugin
|
||||||
|
{
|
||||||
|
public string Name => "Dev Tests";
|
||||||
|
|
||||||
|
public float Version => 0.1f;
|
||||||
|
|
||||||
|
public string Author => "RaidMax";
|
||||||
|
|
||||||
|
private static DateTime Interval;
|
||||||
|
|
||||||
|
public async Task OnEventAsync(Event E, Server S)
|
||||||
|
{
|
||||||
|
if (E.Type == Event.GType.Start)
|
||||||
|
{
|
||||||
|
#region PLAYER_HISTORY
|
||||||
|
var rand = new Random(GetHashCode());
|
||||||
|
var time = DateTime.UtcNow;
|
||||||
|
|
||||||
|
await Task.Run(() =>
|
||||||
|
{
|
||||||
|
if (S.PlayerHistory.Count > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (S.PlayerHistory.Count < 48)
|
||||||
|
{
|
||||||
|
S.PlayerHistory.Enqueue(new PlayerHistory(time, rand.Next(7, 18)));
|
||||||
|
time = time.AddMinutes(15);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task OnLoadAsync()
|
||||||
|
{
|
||||||
|
Interval = DateTime.Now;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task OnTickAsync(Server S)
|
||||||
|
{
|
||||||
|
if ((DateTime.Now - Interval).TotalSeconds > 5)
|
||||||
|
{
|
||||||
|
var rand = new Random();
|
||||||
|
int index = rand.Next(0, 17);
|
||||||
|
var p = new Player($"Test_{index}", "_test", index, (int)Player.Permission.User)
|
||||||
|
{
|
||||||
|
Ping = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
p.SetIP("127.0.0.1");
|
||||||
|
|
||||||
|
if (S.Players.ElementAt(index) != null)
|
||||||
|
await S.RemovePlayer(index);
|
||||||
|
await S.AddPlayer(p);
|
||||||
|
|
||||||
|
Interval = DateTime.Now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task OnUnloadAsync()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
36
Plugins/Tests/Properties/AssemblyInfo.cs
Normal file
36
Plugins/Tests/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("Tests")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("Tests")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("b8c2a759-8663-4f6f-9ba4-19595f5e12c1")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
56
Plugins/Tests/Tests.csproj
Normal file
56
Plugins/Tests/Tests.csproj
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>Tests</RootNamespace>
|
||||||
|
<AssemblyName>Tests</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Plugin.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\SharedLibrary\SharedLibrary.csproj">
|
||||||
|
<Project>{d51eeceb-438a-47da-870f-7d7b41bc24d6}</Project>
|
||||||
|
<Name>SharedLibrary</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<PostBuildEvent>copy /Y "$(TargetDir)$(TargetName).dll" "$(SolutionDir)BUILD\plugins\"</PostBuildEvent>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
@ -1,35 +1,38 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace SharedLibrary.Helpers
|
namespace SharedLibrary.Helpers
|
||||||
{
|
{
|
||||||
public class ConfigurationManager
|
public class ConfigurationManager
|
||||||
{
|
{
|
||||||
Dictionary<string, Dictionary<string, object>> ConfigurationSet;
|
ConcurrentDictionary<string, Dictionary<string, object>> ConfigurationSet;
|
||||||
Type PluginType;
|
Type PluginType;
|
||||||
|
|
||||||
public ConfigurationManager(Type PluginType)
|
public ConfigurationManager(Type PluginType)
|
||||||
{
|
{
|
||||||
ConfigurationSet = new Dictionary<string, Dictionary<string, object>>();
|
ConfigurationSet = new ConcurrentDictionary<string, Dictionary<string, object>>();
|
||||||
this.PluginType = PluginType;
|
this.PluginType = PluginType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddConfiguration(Server S)
|
public void AddConfiguration(Server S)
|
||||||
{
|
{
|
||||||
|
/* if (ConfigurationSet.ContainsKey(S.ToString()))
|
||||||
|
{
|
||||||
|
S.Logger.WriteWarning($"not adding server configuration for {S} as it already exists");
|
||||||
|
return;
|
||||||
|
}*/
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var Config = Interfaces.Serialize<Dictionary<string, object>>.Read($"config/{PluginType.ToString()}_{S.ToString()}.cfg");
|
var Config = Interfaces.Serialize<Dictionary<string, object>>.Read($"config/{PluginType.ToString()}_{S.ToString()}.cfg");
|
||||||
lock (ConfigurationSet)
|
ConfigurationSet.TryAdd(S.ToString(), Config);
|
||||||
{
|
|
||||||
ConfigurationSet.Add(S.ToString(), Config);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exceptions.SerializeException)
|
catch (Exceptions.SerializeException)
|
||||||
{
|
{
|
||||||
ConfigurationSet.Add(S.ToString(), new Dictionary<string, object>());
|
ConfigurationSet.TryAdd(S.ToString(), new Dictionary<string, object>());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddProperty(Server S, KeyValuePair<string, object> Property)
|
public void AddProperty(Server S, KeyValuePair<string, object> Property)
|
||||||
|
@ -4,12 +4,45 @@ namespace SharedLibrary.Helpers
|
|||||||
{
|
{
|
||||||
public class PlayerHistory
|
public class PlayerHistory
|
||||||
{
|
{
|
||||||
public PlayerHistory(DateTime w, int cNum)
|
public PlayerHistory(int cNum)
|
||||||
{
|
{
|
||||||
When = w;
|
DateTime t = DateTime.UtcNow;
|
||||||
Players = cNum;
|
When = new DateTime(t.Year, t.Month, t.Day, t.Hour, 5 * (int)Math.Round(t.Minute / 5.0), 0);
|
||||||
|
PlayerCount = cNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
public PlayerHistory(DateTime t, int cNum)
|
||||||
|
{
|
||||||
|
When = new DateTime(t.Year, t.Month, t.Day, t.Hour, 15 * (int)Math.Round(t.Minute / 15.0), 0);
|
||||||
|
PlayerCount = cNum;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private DateTime When;
|
||||||
|
private int PlayerCount;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used by CanvasJS as a point on the x axis
|
||||||
|
/// </summary>
|
||||||
|
public double x
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (When - DateTime.MinValue).TotalSeconds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used by CanvasJS as a point on the y axis
|
||||||
|
/// </summary>
|
||||||
|
public int y
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return PlayerCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public DateTime When { get; private set; }
|
|
||||||
public int Players { get; private set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,5 +17,6 @@ namespace SharedLibrary.Interfaces
|
|||||||
IList<Player> GetActiveClients();
|
IList<Player> GetActiveClients();
|
||||||
IList<Player> GetAliasClients(Player player);
|
IList<Player> GetAliasClients(Player player);
|
||||||
IList<Aliases> GetAliases(Player player);
|
IList<Aliases> GetAliases(Player player);
|
||||||
|
IList<Player> GetPrivilegedClients();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ namespace SharedLibrary.Network
|
|||||||
|
|
||||||
if (LineSplit.Length != 3)
|
if (LineSplit.Length != 3)
|
||||||
{
|
{
|
||||||
var e = new Exceptions.DvarException("DVAR does not exist");
|
var e = new Exceptions.DvarException($"DVAR \"{dvarName}\" does not exist");
|
||||||
e.Data["dvar_name"] = dvarName;
|
e.Data["dvar_name"] = dvarName;
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
@ -293,16 +293,18 @@ namespace SharedLibrary
|
|||||||
|
|
||||||
public static string TimeSpanText(this TimeSpan span)
|
public static string TimeSpanText(this TimeSpan span)
|
||||||
{
|
{
|
||||||
if (span.TotalMinutes < 6)
|
if (span.TotalMinutes < 60)
|
||||||
return $"{span.Minutes} minutes";
|
return $"{span.Minutes} minute(s)";
|
||||||
else if (span.TotalHours < 24)
|
else if (span.Hours >= 1 && span.TotalHours < 24)
|
||||||
return $"{span.Hours} hours";
|
return $"{span.Hours} hour(s)";
|
||||||
else if (span.TotalDays < 7)
|
else if (span.TotalDays >= 1 && span.TotalDays < 7)
|
||||||
return $"{span.Days} days";
|
return $"{span.Days} day(s)";
|
||||||
else if (span.TotalDays > 7 && span.TotalDays < 365)
|
else if (span.TotalDays >= 7 && span.TotalDays < 365)
|
||||||
return $"{Math.Ceiling(span.Days / 7.0)} weeks";
|
return $"{Math.Ceiling(span.Days / 7.0)} week(s)";
|
||||||
else if (span.TotalDays >= 365)
|
else if (span.TotalDays >= 365 && span.TotalDays < 36500)
|
||||||
return $"{Math.Ceiling(span.Days / 365.0)} years";
|
return $"{Math.Ceiling(span.Days / 365.0)} year(s)";
|
||||||
|
else if (span.TotalDays >= 36500)
|
||||||
|
return "Forever";
|
||||||
|
|
||||||
return "1 hour";
|
return "1 hour";
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user