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
This commit is contained in:
RaidMax 2018-04-02 22:11:19 -05:00
parent 2952e307b2
commit a0c1d9b1bc
7 changed files with 98 additions and 60 deletions

View File

@ -14,12 +14,7 @@ namespace SharedLibrary.RCon
public Socket Client { get; set; } public Socket Client { get; set; }
public const int BufferSize = 8192; public const int BufferSize = 8192;
public byte[] Buffer = new byte[BufferSize]; public byte[] Buffer = new byte[BufferSize];
public StringBuilder ResponseString { get; set; } public readonly StringBuilder ResponseString = new StringBuilder();
public ConnectionState()
{
ResponseString = new StringBuilder();
}
} }
public class Connection public class Connection
@ -28,9 +23,9 @@ namespace SharedLibrary.RCon
string RConPassword; string RConPassword;
Socket ServerConnection; Socket ServerConnection;
ILogger Log; ILogger Log;
int FailedConnections; int FailedSends;
int FailedReceives;
DateTime LastQuery; DateTime LastQuery;
string Response;
ManualResetEvent OnConnected; ManualResetEvent OnConnected;
ManualResetEvent OnSent; ManualResetEvent OnSent;
@ -52,7 +47,7 @@ namespace SharedLibrary.RCon
ServerConnection.BeginConnect(Endpoint, new AsyncCallback(OnConnectedCallback), ServerConnection); ServerConnection.BeginConnect(Endpoint, new AsyncCallback(OnConnectedCallback), ServerConnection);
if (!OnConnected.WaitOne(StaticHelpers.SocketTimeout)) if (!OnConnected.WaitOne(StaticHelpers.SocketTimeout))
throw new SocketException((int)SocketError.TimedOut); throw new SocketException((int)SocketError.TimedOut);
FailedConnections = 0; FailedSends = 0;
} }
catch (SocketException e) catch (SocketException e)
@ -83,7 +78,7 @@ namespace SharedLibrary.RCon
catch (SocketException e) 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 try
{ {
int sentByteNum = serverConnection.EndSend(ar); int sentByteNum = serverConnection.EndSend(ar);
FailedConnections = 0;
#if DEBUG #if DEBUG
Log.WriteDebug($"Sent {sentByteNum} bytes to server"); Log.WriteDebug($"Sent {sentByteNum} bytes to {ServerConnection.RemoteEndPoint}");
#endif #endif
FailedSends = 0;
OnSent.Set(); OnSent.Set();
} }
catch (Exception e) catch (Exception e)
{ {
FailedConnections++; FailedSends++;
if (FailedConnections < 1)
Log.WriteWarning($"Could not send RCon data to server - {e.Message}"); Log.WriteWarning($"Could not send RCon data to server - {e.Message}");
//throw new NetworkException($"Could not send RCon message to server - {e.Message}");
} }
} }
@ -118,12 +111,11 @@ namespace SharedLibrary.RCon
try try
{ {
int bytesRead = serverConnection.EndReceive(ar); int bytesRead = serverConnection.EndReceive(ar);
FailedConnections = 0;
if (bytesRead > 0) if (bytesRead > 0)
{ {
#if DEBUG #if DEBUG
Log.WriteDebug($"Received {bytesRead} bytes from server"); Log.WriteDebug($"Received {bytesRead} bytes from {ServerConnection.RemoteEndPoint}");
#endif #endif
connectionState.ResponseString.Append(Encoding.UTF7.GetString(connectionState.Buffer, 0, bytesRead).TrimEnd('\0')); connectionState.ResponseString.Append(Encoding.UTF7.GetString(connectionState.Buffer, 0, bytesRead).TrimEnd('\0'));
@ -134,7 +126,7 @@ namespace SharedLibrary.RCon
} }
else else
{ {
Response = connectionState.ResponseString.ToString(); FailedReceives = 0;
OnReceived.Set(); OnReceived.Set();
} }
} }
@ -144,20 +136,18 @@ namespace SharedLibrary.RCon
} }
} }
catch (Exception e) catch (Exception)
{ {
FailedConnections++; FailedReceives++;
if (FailedConnections < 1)
Log.WriteWarning($"Could not receive data from server - {e.Message}");
//throw new NetworkException($"Could not recieve message from server - {e.Message}");
} }
} }
public async Task<string[]> SendQueryAsync(StaticHelpers.QueryType type, string parameters = "") public async Task<string[]> 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; LastQuery = DateTime.Now;
} }
@ -177,39 +167,67 @@ namespace SharedLibrary.RCon
} }
byte[] payload = Encoding.Default.GetBytes(queryString); byte[] payload = Encoding.Default.GetBytes(queryString);
try
{
retrySend: retrySend:
ServerConnection.BeginSend(payload, 0, payload.Length, 0, new AsyncCallback(OnSentCallback), ServerConnection); ServerConnection.BeginSend(payload, 0, payload.Length, 0, new AsyncCallback(OnSentCallback), ServerConnection);
bool success = await Task.FromResult(OnSent.WaitOne(StaticHelpers.SocketTimeout)); bool success = await Task.FromResult(OnSent.WaitOne(StaticHelpers.SocketTimeout));
if (!success) if (!success)
{ {
FailedConnections++; #if DEBUG
if (FailedConnections < 4) Log.WriteDebug($"{FailedSends} failed sends to {ServerConnection.RemoteEndPoint.ToString()}");
#endif
if (FailedSends < 4)
goto retrySend; goto retrySend;
else else
throw new NetworkException($"Could not send data to server - {new SocketException((int)SocketError.TimedOut).Message}"); 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 var connectionState = new ConnectionState
{ {
Client = ServerConnection Client = ServerConnection
}; };
try
{
retryReceive: retryReceive:
ServerConnection.BeginReceive(connectionState.Buffer, 0, connectionState.Buffer.Length, 0, ServerConnection.BeginReceive(connectionState.Buffer, 0, connectionState.Buffer.Length, 0,
new AsyncCallback(OnReceivedCallback), connectionState); new AsyncCallback(OnReceivedCallback), connectionState);
success = await Task.FromResult(OnReceived.WaitOne(StaticHelpers.SocketTimeout)); bool success = await Task.FromResult(OnReceived.WaitOne(StaticHelpers.SocketTimeout));
if (!success) if (!success)
{ {
FailedConnections++; #if DEBUG
if (FailedConnections < 4) Log.WriteDebug($"{FailedReceives} failed receives from {ServerConnection.RemoteEndPoint.ToString()}");
#endif
FailedReceives++;
if (FailedReceives < 4)
goto retryReceive; goto retryReceive;
else if (FailedReceives == 4)
Log.WriteError($"Failed to receive data from {ServerConnection.RemoteEndPoint}");
else else
throw new NetworkException($"Could not send data to server - {new SocketException((int)SocketError.TimedOut).Message}"); 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")) if (queryResponse.Contains("Invalid password"))
throw new NetworkException("RCON password is invalid"); throw new NetworkException("RCON password is invalid");

View File

@ -70,6 +70,10 @@ namespace SharedLibrary
long npID = Regex.Match(responseLine, @"([a-z]|[0-9]){16}", RegexOptions.IgnoreCase).Value.ConvertLong(); long npID = Regex.Match(responseLine, @"([a-z]|[0-9]){16}", RegexOptions.IgnoreCase).Value.ConvertLong();
int.TryParse(playerInfo[0], out cID); int.TryParse(playerInfo[0], out cID);
var regex = Regex.Match(responseLine, @"\d+\.\d+\.\d+.\d+\:\d{1,5}"); var regex = Regex.Match(responseLine, @"\d+\.\d+\.\d+.\d+\:\d{1,5}");
#if DEBUG
Ping = 1;
#endif
int cIP = regex.Value.Split(':')[0].ConvertToIP(); int cIP = regex.Value.Split(':')[0].ConvertToIP();
regex = Regex.Match(responseLine, @"[0-9]{1,2}\s+[0-9]+\s+"); regex = Regex.Match(responseLine, @"[0-9]{1,2}\s+[0-9]+\s+");
int score = Int32.Parse(regex.Value.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[1]); int score = Int32.Parse(regex.Value.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[1]);

View File

@ -167,7 +167,7 @@ namespace IW4MAdmin
else if (e.GetType() == typeof(NetworkException)) else if (e.GetType() == typeof(NetworkException))
{ {
Logger.WriteDebug(e.Message); 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 // throw the exception to the main method to stop before instantly exiting

View File

@ -57,7 +57,10 @@ namespace WebfrontCore.Controllers
if (Authorized) if (Authorized)
{ {
clientDto.Meta.AddRange(client.AliasLink.Children.Select(a => new ProfileMeta() clientDto.Meta.AddRange(client.AliasLink.Children
.GroupBy(a => a.Name)
.Select(a => a.First())
.Select(a => new ProfileMeta()
{ {
Key = "AliasEvent", Key = "AliasEvent",
Value = $"Connected with name {a.Name}", Value = $"Connected with name {a.Name}",
@ -89,6 +92,7 @@ namespace WebfrontCore.Controllers
.Where(a => a.Active) .Where(a => a.Active)
.OrderByDescending(a => a.Level); .OrderByDescending(a => a.Level);
var adminsDict = new Dictionary<SharedLibrary.Objects.Player.Permission, IList<ClientInfo>>(); var adminsDict = new Dictionary<SharedLibrary.Objects.Player.Permission, IList<ClientInfo>>();
foreach (var admin in admins) foreach (var admin in admins)
{ {
if (!adminsDict.ContainsKey(admin.Level)) if (!adminsDict.ContainsKey(admin.Level))
@ -123,7 +127,7 @@ namespace WebfrontCore.Controllers
}) })
.ToList(); .ToList();
ViewBag.Title = $"Clients Matching \"{clientName}\""; ViewBag.Title = $"{clientsDto.Count} Clients Matching \"{clientName}\"";
return View("Find/Index", clientsDto); return View("Find/Index", clientsDto);
} }
} }

View File

@ -14,7 +14,7 @@ by editing this MSBuild file. In order to learn more about this please visit htt
<ExcludeApp_Data>False</ExcludeApp_Data> <ExcludeApp_Data>False</ExcludeApp_Data>
<ProjectGuid>65340d7d-5831-406c-acad-b13ba634bde2</ProjectGuid> <ProjectGuid>65340d7d-5831-406c-acad-b13ba634bde2</ProjectGuid>
<publishUrl>D:\IW4M-Admin\Publish</publishUrl> <publishUrl>D:\IW4M-Admin\Publish</publishUrl>
<DeleteExistingFiles>False</DeleteExistingFiles> <DeleteExistingFiles>True</DeleteExistingFiles>
<TargetFramework>net452</TargetFramework> <TargetFramework>net452</TargetFramework>
<RuntimeIdentifier>win7-x86</RuntimeIdentifier> <RuntimeIdentifier>win7-x86</RuntimeIdentifier>
</PropertyGroup> </PropertyGroup>

View File

@ -19,6 +19,12 @@
<OutputPath>bin\x86\Debug\</OutputPath> <OutputPath>bin\x86\Debug\</OutputPath>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<Content Remove="bower.json" />
<Content Remove="bundleconfig.json" />
<Content Remove="compilerconfig.json" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<None Update="wwwroot\**\*"> <None Update="wwwroot\**\*">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
@ -54,6 +60,12 @@
<DotNetCliToolReference Include="BundlerMinifier.Core" Version="2.2.301" /> <DotNetCliToolReference Include="BundlerMinifier.Core" Version="2.2.301" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="bower.json" />
<None Include="bundleconfig.json" />
<None Include="compilerconfig.json" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\SharedLibrary\SharedLibrary.csproj"> <ProjectReference Include="..\SharedLibrary\SharedLibrary.csproj">
<Private>true</Private> <Private>true</Private>

View File

@ -12,8 +12,8 @@
animationEnabled: true, animationEnabled: true,
toolTip: { toolTip: {
contentFormatter: function (e) { contentFormatter: function (e) {
var date = new Date(e.entries[0].dataPoint.x); const date = moment.utc(e.entries[0].dataPoint.x);
return date.toLocaleTimeString('en-US', { timeZone: 'America/New_York', hour12: true }) + " - " + e.entries[0].dataPoint.y + " players"; return date.local().format('h:mm A') + " - " + e.entries[0].dataPoint.y + " players";
} }
}, },
axisX: { axisX: {