1
0
mirror of https://github.com/RaidMax/IW4M-Admin.git synced 2025-06-10 07:13:58 -05:00

more rcon tweaks, and starting on unit tests for commands bleh

This commit is contained in:
RaidMax
2018-09-29 21:49:12 -05:00
parent 1fc2d8e460
commit 4eea217e82
9 changed files with 123 additions and 102 deletions

View File

@ -69,12 +69,14 @@ namespace SharedLibraryCore.Commands
})
{ }
public override async Task ExecuteAsync(GameEvent E)
public override Task ExecuteAsync(GameEvent E)
{
if (!await E.Target.Warn(E.Data, E.Origin).WaitAsync())
if (E.Target.Warn(E.Data, E.Origin).Failed)
{
E.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_WARN_FAIL"]} {E.Target.Name}");
}
return Task.CompletedTask;
}
}
@ -91,12 +93,14 @@ namespace SharedLibraryCore.Commands
})
{ }
public override async Task ExecuteAsync(GameEvent E)
public override Task ExecuteAsync(GameEvent E)
{
if (await E.Target.WarnClear(E.Origin).WaitAsync())
if (!E.Target.WarnClear(E.Origin).Failed)
{
E.Owner.Broadcast($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_WARNCLEAR_SUCCESS"]} {E.Target.Name}");
}
return Task.CompletedTask;
}
}
@ -839,8 +843,6 @@ namespace SharedLibraryCore.Commands
else
{
commandEvent.Owner.Reports.Add(new Report(commandEvent.Target, commandEvent.Origin, commandEvent.Data));
Penalty newReport = new Penalty()
{
Type = Penalty.PenaltyType.Report,

View File

@ -128,6 +128,8 @@ namespace SharedLibraryCore.Objects
return e;
}
this.Warnings++;
CurrentServer.Manager.GetEventHandler().AddEvent(e);
return e;
}
@ -150,7 +152,7 @@ namespace SharedLibraryCore.Objects
Owner = this.CurrentServer
};
if (this.Level < sender.Level)
if (this.Level > sender.Level)
{
e.FailReason = GameEvent.EventFailReason.Permission;
return e;
@ -162,13 +164,14 @@ namespace SharedLibraryCore.Objects
return e;
}
if (CurrentServer.Reports.Count(rep => (rep.Origin == sender &&
if (CurrentServer.Reports.Count(rep => (rep.Origin.NetworkId == sender.NetworkId &&
rep.Target.NetworkId == this.NetworkId)) > 0)
{
e.FailReason = GameEvent.EventFailReason.Exception;
return e;
}
CurrentServer.Reports.Add(new Report(this, sender, reportReason));
CurrentServer.Manager.GetEventHandler().AddEvent(e);
return e;
}

View File

@ -17,6 +17,7 @@ namespace SharedLibraryCore.RCon
const int BufferSize = 4096;
public readonly byte[] ReceiveBuffer = new byte[BufferSize];
public readonly SemaphoreSlim OnComplete = new SemaphoreSlim(1, 1);
public DateTime LastQuery { get; set; } = DateTime.Now;
}
public class Connection
@ -42,9 +43,19 @@ namespace SharedLibraryCore.RCon
var connectionState = ActiveQueries[this.Endpoint];
var timeLeft = (DateTime.Now - connectionState.LastQuery).TotalMilliseconds;
if (timeLeft > 0)
{
await Task.Delay((int)timeLeft);
}
connectionState.LastQuery = DateTime.Now;
#if DEBUG == true
Log.WriteDebug($"Waiting for semaphore to be released [${this.Endpoint}]");
#endif
// enter the semaphore so only one query is sent at a time per server.
await connectionState.OnComplete.WaitAsync();
#if DEBUG == true
@ -73,40 +84,41 @@ namespace SharedLibraryCore.RCon
byte[] response = null;
retrySend:
#if DEBUG == true
Log.WriteDebug($"Sending {payload.Length} bytes to [${this.Endpoint}] ({connectionState.ConnectionAttempts++}/{StaticHelpers.AllowedConnectionFails})");
Log.WriteDebug($"Sending {payload.Length} bytes to [{this.Endpoint}] ({connectionState.ConnectionAttempts++}/{StaticHelpers.AllowedConnectionFails})");
#endif
try
{
response = await SendPayloadAsync(payload);
connectionState.OnComplete.Release(1);
}
catch (Exception ex)
{
if(connectionState.ConnectionAttempts < StaticHelpers.AllowedConnectionFails)
if (connectionState.ConnectionAttempts < StaticHelpers.AllowedConnectionFails)
{
connectionState.ConnectionAttempts++;
Log.WriteWarning($"{Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_COMMUNICATION"]} [{this.Endpoint}] ({connectionState.ConnectionAttempts++}/{StaticHelpers.AllowedConnectionFails})");
await Task.Delay(StaticHelpers.SocketTimeout.Milliseconds);
await Task.Delay(StaticHelpers.FloodProtectionInterval);
goto retrySend;
}
ActiveQueries.TryRemove(this.Endpoint, out _);
// the next thread can go ahead and enter
connectionState.OnComplete.Release(1);
Log.WriteDebug(ex.GetExceptionInfo());
throw new NetworkException($"{Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_COMMUNICATION"]} [{this.Endpoint}]");
}
ActiveQueries.TryRemove(this.Endpoint, out _);
connectionState.ConnectionAttempts = 0;
string responseString = Utilities.EncodingType.GetString(response, 0, response.Length).TrimEnd('\0') + '\n';
if (responseString.Contains("Invalid password"))
{
// todo: localize this
throw new NetworkException("RCON password is invalid");
throw new NetworkException(Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_RCON_INVALID"]);
}
if (responseString.ToString().Contains("rcon_password"))
{
throw new NetworkException("RCON password has not been set");
throw new NetworkException(Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_RCON_NOTSET"]);
}
string[] splitResponse = responseString.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)
@ -147,6 +159,10 @@ namespace SharedLibraryCore.RCon
if (!await connectionState.OnComplete.WaitAsync(StaticHelpers.SocketTimeout.Milliseconds))
{
// we no longer care about the data because the server is being too slow
incomingDataArgs.Completed -= OnDataReceived;
// the next thread can go ahead and make a query
connectionState.OnComplete.Release(1);
throw new NetworkException("Timed out waiting for response", rconSocket);
}
@ -159,7 +175,10 @@ namespace SharedLibraryCore.RCon
#if DEBUG == true
Log.WriteDebug($"Read {e.BytesTransferred} bytes from {e.RemoteEndPoint.ToString()}");
#endif
ActiveQueries[this.Endpoint].OnComplete.Release(1);
if (ActiveQueries[this.Endpoint].OnComplete.CurrentCount == 0)
{
ActiveQueries[this.Endpoint].OnComplete.Release(1);
}
}
private void OnDataSent(object sender, SocketAsyncEventArgs e)

View File

@ -39,7 +39,7 @@ namespace SharedLibraryCore.RCon
/// <summary>
/// timeout in seconds to wait for a socket send or receive before giving up
/// </summary>
public static readonly TimeSpan SocketTimeout = new TimeSpan(0, 0, 0, 0, 150);
public static readonly TimeSpan SocketTimeout = new TimeSpan(0, 0, 0, 0,150);
/// <summary>
/// interval in milliseconds to wait before sending the next RCon request
/// </summary>