From a0c1d9b1bc0229ec948985eac4f3482f199062e2 Mon Sep 17 00:00:00 2001 From: RaidMax Date: Mon, 2 Apr 2018 22:11:19 -0500 Subject: [PATCH] changed the player history to reflect correct timezone added result count to find clients only show unique aliases on profile page some rcon socket changes --- SharedLibrary/RCon/Connection.cs | 112 ++++++++++-------- SharedLibrary/Utilities.cs | 4 + WebfrontCore/Application/Manager.cs | 2 +- WebfrontCore/Controllers/ClientController.cs | 20 ++-- .../PublishProfiles/USBPublish.pubxml | 2 +- WebfrontCore/WebfrontCore.csproj | 12 ++ WebfrontCore/wwwroot/js/server.js | 6 +- 7 files changed, 98 insertions(+), 60 deletions(-) diff --git a/SharedLibrary/RCon/Connection.cs b/SharedLibrary/RCon/Connection.cs index 0b978c088..d60e38dcd 100644 --- a/SharedLibrary/RCon/Connection.cs +++ b/SharedLibrary/RCon/Connection.cs @@ -14,12 +14,7 @@ namespace SharedLibrary.RCon public Socket Client { get; set; } public const int BufferSize = 8192; public byte[] Buffer = new byte[BufferSize]; - public StringBuilder ResponseString { get; set; } - - public ConnectionState() - { - ResponseString = new StringBuilder(); - } + public readonly StringBuilder ResponseString = new StringBuilder(); } public class Connection @@ -28,9 +23,9 @@ namespace SharedLibrary.RCon string RConPassword; Socket ServerConnection; ILogger Log; - int FailedConnections; + int FailedSends; + int FailedReceives; DateTime LastQuery; - string Response; ManualResetEvent OnConnected; ManualResetEvent OnSent; @@ -52,7 +47,7 @@ namespace SharedLibrary.RCon ServerConnection.BeginConnect(Endpoint, new AsyncCallback(OnConnectedCallback), ServerConnection); if (!OnConnected.WaitOne(StaticHelpers.SocketTimeout)) throw new SocketException((int)SocketError.TimedOut); - FailedConnections = 0; + FailedSends = 0; } catch (SocketException e) @@ -83,7 +78,7 @@ namespace SharedLibrary.RCon catch (SocketException e) { - throw new NetworkException($"Could not connect to RCon - {e.Message}"); + throw new NetworkException($"Could not initialize socket for RCon - {e.Message}"); } } @@ -94,19 +89,17 @@ namespace SharedLibrary.RCon try { int sentByteNum = serverConnection.EndSend(ar); - FailedConnections = 0; #if DEBUG - Log.WriteDebug($"Sent {sentByteNum} bytes to server"); + Log.WriteDebug($"Sent {sentByteNum} bytes to {ServerConnection.RemoteEndPoint}"); #endif + FailedSends = 0; OnSent.Set(); } catch (Exception e) { - FailedConnections++; - if (FailedConnections < 1) - Log.WriteWarning($"Could not send RCon data to server - {e.Message}"); - //throw new NetworkException($"Could not send RCon message to server - {e.Message}"); + FailedSends++; + Log.WriteWarning($"Could not send RCon data to server - {e.Message}"); } } @@ -118,12 +111,11 @@ namespace SharedLibrary.RCon try { int bytesRead = serverConnection.EndReceive(ar); - FailedConnections = 0; if (bytesRead > 0) { #if DEBUG - Log.WriteDebug($"Received {bytesRead} bytes from server"); + Log.WriteDebug($"Received {bytesRead} bytes from {ServerConnection.RemoteEndPoint}"); #endif connectionState.ResponseString.Append(Encoding.UTF7.GetString(connectionState.Buffer, 0, bytesRead).TrimEnd('\0')); @@ -134,7 +126,7 @@ namespace SharedLibrary.RCon } else { - Response = connectionState.ResponseString.ToString(); + FailedReceives = 0; OnReceived.Set(); } } @@ -144,20 +136,18 @@ namespace SharedLibrary.RCon } } - catch (Exception e) + catch (Exception) { - FailedConnections++; - if (FailedConnections < 1) - Log.WriteWarning($"Could not receive data from server - {e.Message}"); - //throw new NetworkException($"Could not recieve message from server - {e.Message}"); + FailedReceives++; } } public async Task SendQueryAsync(StaticHelpers.QueryType type, string parameters = "") { - if ((DateTime.Now - LastQuery).TotalMilliseconds < 150) + // will this really prevent flooding? + if ((DateTime.Now - LastQuery).TotalMilliseconds < 300) { - await Task.Delay(150); + await Task.Delay(300); LastQuery = DateTime.Now; } @@ -177,17 +167,30 @@ namespace SharedLibrary.RCon } byte[] payload = Encoding.Default.GetBytes(queryString); - retrySend: - ServerConnection.BeginSend(payload, 0, payload.Length, 0, new AsyncCallback(OnSentCallback), ServerConnection); - bool success = await Task.FromResult(OnSent.WaitOne(StaticHelpers.SocketTimeout)); - if (!success) + try { - FailedConnections++; - if (FailedConnections < 4) - goto retrySend; - else - throw new NetworkException($"Could not send data to server - {new SocketException((int)SocketError.TimedOut).Message}"); + retrySend: + ServerConnection.BeginSend(payload, 0, payload.Length, 0, new AsyncCallback(OnSentCallback), ServerConnection); + bool success = await Task.FromResult(OnSent.WaitOne(StaticHelpers.SocketTimeout)); + + if (!success) + { +#if DEBUG + Log.WriteDebug($"{FailedSends} failed sends to {ServerConnection.RemoteEndPoint.ToString()}"); +#endif + if (FailedSends < 4) + goto retrySend; + else + throw new NetworkException($"Could not send data to server - {new SocketException((int)SocketError.TimedOut).Message}"); + } + } + + catch (SocketException e) + { + // this result is normal if the server is not listening + if (e.HResult != (int)SocketError.ConnectionReset) + throw new NetworkException($"Unexpected error while sending data to server - {e.Message}"); } var connectionState = new ConnectionState @@ -195,21 +198,36 @@ namespace SharedLibrary.RCon Client = ServerConnection }; - retryReceive: - ServerConnection.BeginReceive(connectionState.Buffer, 0, connectionState.Buffer.Length, 0, - new AsyncCallback(OnReceivedCallback), connectionState); - success = await Task.FromResult(OnReceived.WaitOne(StaticHelpers.SocketTimeout)); - - if (!success) + try { - FailedConnections++; - if (FailedConnections < 4) - goto retryReceive; - else - throw new NetworkException($"Could not send data to server - {new SocketException((int)SocketError.TimedOut).Message}"); + retryReceive: + ServerConnection.BeginReceive(connectionState.Buffer, 0, connectionState.Buffer.Length, 0, + new AsyncCallback(OnReceivedCallback), connectionState); + bool success = await Task.FromResult(OnReceived.WaitOne(StaticHelpers.SocketTimeout)); + + if (!success) + { +#if DEBUG + Log.WriteDebug($"{FailedReceives} failed receives from {ServerConnection.RemoteEndPoint.ToString()}"); +#endif + FailedReceives++; + if (FailedReceives < 4) + goto retryReceive; + else if (FailedReceives == 4) + Log.WriteError($"Failed to receive data from {ServerConnection.RemoteEndPoint}"); + else + throw new NetworkException($"Could not receive data from the server - {new SocketException((int)SocketError.TimedOut).Message}"); + } } - string queryResponse = Response;//connectionState.ResponseString.ToString(); + catch (SocketException e) + { + // this result is normal if the server is not listening + if (e.HResult != (int)SocketError.ConnectionReset) + throw new NetworkException($"Unexpected error while receiving data from server - {e.Message}"); + } + + string queryResponse = connectionState.ResponseString.ToString(); if (queryResponse.Contains("Invalid password")) throw new NetworkException("RCON password is invalid"); diff --git a/SharedLibrary/Utilities.cs b/SharedLibrary/Utilities.cs index aabf8aff3..b02c1ace5 100644 --- a/SharedLibrary/Utilities.cs +++ b/SharedLibrary/Utilities.cs @@ -70,6 +70,10 @@ namespace SharedLibrary long npID = Regex.Match(responseLine, @"([a-z]|[0-9]){16}", RegexOptions.IgnoreCase).Value.ConvertLong(); int.TryParse(playerInfo[0], out cID); var regex = Regex.Match(responseLine, @"\d+\.\d+\.\d+.\d+\:\d{1,5}"); +#if DEBUG + Ping = 1; +#endif + int cIP = regex.Value.Split(':')[0].ConvertToIP(); regex = Regex.Match(responseLine, @"[0-9]{1,2}\s+[0-9]+\s+"); int score = Int32.Parse(regex.Value.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[1]); diff --git a/WebfrontCore/Application/Manager.cs b/WebfrontCore/Application/Manager.cs index 16c5e8794..c3238d14e 100644 --- a/WebfrontCore/Application/Manager.cs +++ b/WebfrontCore/Application/Manager.cs @@ -167,7 +167,7 @@ namespace IW4MAdmin else if (e.GetType() == typeof(NetworkException)) { Logger.WriteDebug(e.Message); - Logger.WriteDebug($"Internal Exception: {e.Data["internal_exception"]}"); + //Logger.WriteDebug($"Internal Exception: {e.Data["internal_exception"]}"); } // throw the exception to the main method to stop before instantly exiting diff --git a/WebfrontCore/Controllers/ClientController.cs b/WebfrontCore/Controllers/ClientController.cs index 910aa6ebd..6ec0390f7 100644 --- a/WebfrontCore/Controllers/ClientController.cs +++ b/WebfrontCore/Controllers/ClientController.cs @@ -57,13 +57,16 @@ namespace WebfrontCore.Controllers if (Authorized) { - clientDto.Meta.AddRange(client.AliasLink.Children.Select(a => new ProfileMeta() - { - Key = "AliasEvent", - Value = $"Connected with name {a.Name}", - Sensitive = true, - When = a.DateAdded - })); + clientDto.Meta.AddRange(client.AliasLink.Children + .GroupBy(a => a.Name) + .Select(a => a.First()) + .Select(a => new ProfileMeta() + { + Key = "AliasEvent", + Value = $"Connected with name {a.Name}", + Sensitive = true, + When = a.DateAdded + })); } clientDto.Meta.AddRange(Authorized ? meta : meta.Where(m => !m.Sensitive)); @@ -89,6 +92,7 @@ namespace WebfrontCore.Controllers .Where(a => a.Active) .OrderByDescending(a => a.Level); var adminsDict = new Dictionary>(); + foreach (var admin in admins) { if (!adminsDict.ContainsKey(admin.Level)) @@ -123,7 +127,7 @@ namespace WebfrontCore.Controllers }) .ToList(); - ViewBag.Title = $"Clients Matching \"{clientName}\""; + ViewBag.Title = $"{clientsDto.Count} Clients Matching \"{clientName}\""; return View("Find/Index", clientsDto); } } diff --git a/WebfrontCore/Properties/PublishProfiles/USBPublish.pubxml b/WebfrontCore/Properties/PublishProfiles/USBPublish.pubxml index 821234054..5f1ad3a00 100644 --- a/WebfrontCore/Properties/PublishProfiles/USBPublish.pubxml +++ b/WebfrontCore/Properties/PublishProfiles/USBPublish.pubxml @@ -14,7 +14,7 @@ by editing this MSBuild file. In order to learn more about this please visit htt False 65340d7d-5831-406c-acad-b13ba634bde2 D:\IW4M-Admin\Publish - False + True net452 win7-x86 diff --git a/WebfrontCore/WebfrontCore.csproj b/WebfrontCore/WebfrontCore.csproj index f5099b959..b39a60237 100644 --- a/WebfrontCore/WebfrontCore.csproj +++ b/WebfrontCore/WebfrontCore.csproj @@ -19,6 +19,12 @@ bin\x86\Debug\ + + + + + + PreserveNewest @@ -54,6 +60,12 @@ + + + + + + true diff --git a/WebfrontCore/wwwroot/js/server.js b/WebfrontCore/wwwroot/js/server.js index 085a1fd3a..b54f99727 100644 --- a/WebfrontCore/wwwroot/js/server.js +++ b/WebfrontCore/wwwroot/js/server.js @@ -12,8 +12,8 @@ animationEnabled: true, toolTip: { contentFormatter: function (e) { - var date = new Date(e.entries[0].dataPoint.x); - return date.toLocaleTimeString('en-US', { timeZone: 'America/New_York', hour12: true }) + " - " + e.entries[0].dataPoint.y + " players"; + const date = moment.utc(e.entries[0].dataPoint.x); + return date.local().format('h:mm A') + " - " + e.entries[0].dataPoint.y + " players"; } }, axisX: { @@ -86,4 +86,4 @@ function refreshClientActivity() { }); } -setInterval(refreshClientActivity, 2000); \ No newline at end of file +setInterval(refreshClientActivity, 2000);