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:
parent
2952e307b2
commit
a0c1d9b1bc
@ -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,17 +167,30 @@ namespace SharedLibrary.RCon
|
|||||||
}
|
}
|
||||||
|
|
||||||
byte[] payload = Encoding.Default.GetBytes(queryString);
|
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++;
|
retrySend:
|
||||||
if (FailedConnections < 4)
|
ServerConnection.BeginSend(payload, 0, payload.Length, 0, new AsyncCallback(OnSentCallback), ServerConnection);
|
||||||
goto retrySend;
|
bool success = await Task.FromResult(OnSent.WaitOne(StaticHelpers.SocketTimeout));
|
||||||
else
|
|
||||||
throw new NetworkException($"Could not send data to server - {new SocketException((int)SocketError.TimedOut).Message}");
|
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
|
var connectionState = new ConnectionState
|
||||||
@ -195,21 +198,36 @@ namespace SharedLibrary.RCon
|
|||||||
Client = ServerConnection
|
Client = ServerConnection
|
||||||
};
|
};
|
||||||
|
|
||||||
retryReceive:
|
try
|
||||||
ServerConnection.BeginReceive(connectionState.Buffer, 0, connectionState.Buffer.Length, 0,
|
|
||||||
new AsyncCallback(OnReceivedCallback), connectionState);
|
|
||||||
success = await Task.FromResult(OnReceived.WaitOne(StaticHelpers.SocketTimeout));
|
|
||||||
|
|
||||||
if (!success)
|
|
||||||
{
|
{
|
||||||
FailedConnections++;
|
retryReceive:
|
||||||
if (FailedConnections < 4)
|
ServerConnection.BeginReceive(connectionState.Buffer, 0, connectionState.Buffer.Length, 0,
|
||||||
goto retryReceive;
|
new AsyncCallback(OnReceivedCallback), connectionState);
|
||||||
else
|
bool success = await Task.FromResult(OnReceived.WaitOne(StaticHelpers.SocketTimeout));
|
||||||
throw new NetworkException($"Could not send data to server - {new SocketException((int)SocketError.TimedOut).Message}");
|
|
||||||
|
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"))
|
if (queryResponse.Contains("Invalid password"))
|
||||||
throw new NetworkException("RCON password is invalid");
|
throw new NetworkException("RCON password is invalid");
|
||||||
|
@ -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]);
|
||||||
|
@ -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
|
||||||
|
@ -57,13 +57,16 @@ 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)
|
||||||
Key = "AliasEvent",
|
.Select(a => a.First())
|
||||||
Value = $"Connected with name {a.Name}",
|
.Select(a => new ProfileMeta()
|
||||||
Sensitive = true,
|
{
|
||||||
When = a.DateAdded
|
Key = "AliasEvent",
|
||||||
}));
|
Value = $"Connected with name {a.Name}",
|
||||||
|
Sensitive = true,
|
||||||
|
When = a.DateAdded
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
clientDto.Meta.AddRange(Authorized ? meta : meta.Where(m => !m.Sensitive));
|
clientDto.Meta.AddRange(Authorized ? meta : meta.Where(m => !m.Sensitive));
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
@ -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: {
|
||||||
@ -86,4 +86,4 @@ function refreshClientActivity() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setInterval(refreshClientActivity, 2000);
|
setInterval(refreshClientActivity, 2000);
|
||||||
|
Loading…
Reference in New Issue
Block a user