hopefully finished with RCon changes.
added more tests. fixed issues from event changes (there's most definitely still issues related to that)
This commit is contained in:
parent
7fa0b52543
commit
f4ac815d07
@ -76,6 +76,12 @@ namespace IW4MAdmin.Application
|
|||||||
|
|
||||||
var newEvent = args.Event;
|
var newEvent = args.Event;
|
||||||
|
|
||||||
|
// the event has failed already
|
||||||
|
if (newEvent.Failed)
|
||||||
|
{
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// if the origin client is not in an authorized state (detected by RCon) don't execute the event
|
// if the origin client is not in an authorized state (detected by RCon) don't execute the event
|
||||||
@ -161,26 +167,32 @@ namespace IW4MAdmin.Application
|
|||||||
// this happens if a plugin requires login
|
// this happens if a plugin requires login
|
||||||
catch (AuthorizationException ex)
|
catch (AuthorizationException ex)
|
||||||
{
|
{
|
||||||
|
newEvent.FailReason = GameEvent.EventFailReason.Permission;
|
||||||
newEvent.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMAND_NOTAUTHORIZED"]} - {ex.Message}");
|
newEvent.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMAND_NOTAUTHORIZED"]} - {ex.Message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (NetworkException ex)
|
catch (NetworkException ex)
|
||||||
{
|
{
|
||||||
|
newEvent.FailReason = GameEvent.EventFailReason.Exception;
|
||||||
Logger.WriteError(ex.Message);
|
Logger.WriteError(ex.Message);
|
||||||
Logger.WriteDebug(ex.GetExceptionInfo());
|
Logger.WriteDebug(ex.GetExceptionInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (ServerException ex)
|
catch (ServerException ex)
|
||||||
{
|
{
|
||||||
|
newEvent.FailReason = GameEvent.EventFailReason.Exception;
|
||||||
Logger.WriteWarning(ex.Message);
|
Logger.WriteWarning(ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
newEvent.FailReason = GameEvent.EventFailReason.Exception;
|
||||||
Logger.WriteError($"{Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_EXCEPTION"]} {newEvent.Owner}");
|
Logger.WriteError($"{Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_EXCEPTION"]} {newEvent.Owner}");
|
||||||
Logger.WriteDebug(ex.GetExceptionInfo());
|
Logger.WriteDebug(ex.GetExceptionInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skip:
|
||||||
|
|
||||||
// tell anyone waiting for the output that we're done
|
// tell anyone waiting for the output that we're done
|
||||||
newEvent.OnProcessed.Set();
|
newEvent.OnProcessed.Set();
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,7 @@ namespace IW4MAdmin
|
|||||||
{
|
{
|
||||||
player.Level = Player.Permission.User;
|
player.Level = Player.Permission.User;
|
||||||
}
|
}
|
||||||
|
#if DEBUG == false
|
||||||
if (currentBan != null)
|
if (currentBan != null)
|
||||||
{
|
{
|
||||||
Logger.WriteInfo($"Banned client {player} trying to connect...");
|
Logger.WriteInfo($"Banned client {player} trying to connect...");
|
||||||
@ -243,16 +243,17 @@ namespace IW4MAdmin
|
|||||||
Players[player.ClientNumber] = null;
|
Players[player.ClientNumber] = null;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
player.State = Player.ClientState.Connected;
|
player.State = Player.ClientState.Connected;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception E)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Manager.GetLogger().WriteError($"{loc["SERVER_ERROR_ADDPLAYER"]} {polledPlayer.Name}::{polledPlayer.NetworkId}");
|
Manager.GetLogger().WriteError($"{loc["SERVER_ERROR_ADDPLAYER"]} {polledPlayer.Name}::{polledPlayer.NetworkId}");
|
||||||
Manager.GetLogger().WriteDebug(E.Message);
|
Manager.GetLogger().WriteDebug(ex.Message);
|
||||||
Manager.GetLogger().WriteDebug(E.StackTrace);
|
Manager.GetLogger().WriteDebug(ex.StackTrace);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -376,6 +377,61 @@ namespace IW4MAdmin
|
|||||||
await OnPlayerJoined(E.Origin);
|
await OnPlayerJoined(E.Origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (E.Type == GameEvent.EventType.Flag)
|
||||||
|
{
|
||||||
|
Penalty newPenalty = new Penalty()
|
||||||
|
{
|
||||||
|
Type = Penalty.PenaltyType.Flag,
|
||||||
|
Expires = DateTime.UtcNow,
|
||||||
|
Offender = E.Target,
|
||||||
|
Offense = E.Data,
|
||||||
|
Punisher = E.Origin,
|
||||||
|
Active = true,
|
||||||
|
When = DateTime.UtcNow,
|
||||||
|
Link = E.Target.AliasLink
|
||||||
|
};
|
||||||
|
|
||||||
|
var addedPenalty = await Manager.GetPenaltyService().Create(newPenalty);
|
||||||
|
E.Target.ReceivedPenalties.Add(addedPenalty);
|
||||||
|
|
||||||
|
await Manager.GetClientService().Update(E.Target);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (E.Type == GameEvent.EventType.Unflag)
|
||||||
|
{
|
||||||
|
await Manager.GetClientService().Update(E.Target);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (E.Type == GameEvent.EventType.Report)
|
||||||
|
{
|
||||||
|
this.Reports.Add(new Report()
|
||||||
|
{
|
||||||
|
Origin = E.Origin,
|
||||||
|
Target = E.Target,
|
||||||
|
Reason = E.Data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (E.Type == GameEvent.EventType.TempBan)
|
||||||
|
{
|
||||||
|
await TempBan(E.Data, (TimeSpan)E.Extra, E.Target, E.Origin); ;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (E.Type == GameEvent.EventType.Ban)
|
||||||
|
{
|
||||||
|
await Ban(E.Data, E.Target, E.Origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (E.Type == GameEvent.EventType.Unban)
|
||||||
|
{
|
||||||
|
await Unban(E.Data, E.Target, E.Origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (E.Type == GameEvent.EventType.Kick)
|
||||||
|
{
|
||||||
|
await Kick(E.Data, E.Target, E.Origin);
|
||||||
|
}
|
||||||
|
|
||||||
else if (E.Type == GameEvent.EventType.Quit)
|
else if (E.Type == GameEvent.EventType.Quit)
|
||||||
{
|
{
|
||||||
var origin = Players.FirstOrDefault(p => p != null && p.NetworkId == E.Origin.NetworkId);
|
var origin = Players.FirstOrDefault(p => p != null && p.NetworkId == E.Origin.NetworkId);
|
||||||
@ -874,7 +930,7 @@ namespace IW4MAdmin
|
|||||||
await Manager.GetPenaltyService().Create(newPenalty);
|
await Manager.GetPenaltyService().Create(newPenalty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Kick(String Reason, Player Target, Player Origin)
|
protected override async Task Kick(String Reason, Player Target, Player Origin)
|
||||||
{
|
{
|
||||||
// ensure player gets kicked if command not performed on them in game
|
// ensure player gets kicked if command not performed on them in game
|
||||||
if (Target.ClientNumber < 0)
|
if (Target.ClientNumber < 0)
|
||||||
@ -915,7 +971,7 @@ namespace IW4MAdmin
|
|||||||
await Manager.GetPenaltyService().Create(newPenalty);
|
await Manager.GetPenaltyService().Create(newPenalty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task TempBan(String Reason, TimeSpan length, Player Target, Player Origin)
|
protected override async Task TempBan(String Reason, TimeSpan length, Player Target, Player Origin)
|
||||||
{
|
{
|
||||||
// ensure player gets banned if command not performed on them in game
|
// ensure player gets banned if command not performed on them in game
|
||||||
if (Target.ClientNumber < 0)
|
if (Target.ClientNumber < 0)
|
||||||
@ -954,7 +1010,7 @@ namespace IW4MAdmin
|
|||||||
await Manager.GetPenaltyService().Create(newPenalty);
|
await Manager.GetPenaltyService().Create(newPenalty);
|
||||||
}
|
}
|
||||||
|
|
||||||
override public async Task Ban(String Message, Player Target, Player Origin)
|
override protected async Task Ban(String Message, Player Target, Player Origin)
|
||||||
{
|
{
|
||||||
// ensure player gets banned if command not performed on them in game
|
// ensure player gets banned if command not performed on them in game
|
||||||
if (Target.ClientNumber < 0)
|
if (Target.ClientNumber < 0)
|
||||||
@ -978,18 +1034,6 @@ namespace IW4MAdmin
|
|||||||
// this is set only because they're still in the server.
|
// this is set only because they're still in the server.
|
||||||
Target.Level = Player.Permission.Banned;
|
Target.Level = Player.Permission.Banned;
|
||||||
|
|
||||||
var e = new GameEvent()
|
|
||||||
{
|
|
||||||
Type = GameEvent.EventType.Ban,
|
|
||||||
Data = Message,
|
|
||||||
Origin = Origin,
|
|
||||||
Target = Target,
|
|
||||||
Owner = this
|
|
||||||
};
|
|
||||||
|
|
||||||
// let the api know that a ban occured
|
|
||||||
Manager.GetEventHandler().AddEvent(e);
|
|
||||||
|
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
string formattedString = String.Format(RconParser.GetCommandPrefixes().Kick, Target.ClientNumber, $"{loc["SERVER_BAN_TEXT"]} - ^5{Message} ^7({loc["SERVER_BAN_APPEAL"]} {Website})^7");
|
string formattedString = String.Format(RconParser.GetCommandPrefixes().Kick, Target.ClientNumber, $"{loc["SERVER_BAN_TEXT"]} - ^5{Message} ^7({loc["SERVER_BAN_APPEAL"]} {Website})^7");
|
||||||
await Target.CurrentServer.ExecuteCommandAsync(formattedString);
|
await Target.CurrentServer.ExecuteCommandAsync(formattedString);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using IW4MAdmin.Application;
|
using IW4MAdmin.Application;
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
|
using SharedLibraryCore.Commands;
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -14,7 +15,7 @@ namespace Tests
|
|||||||
public class ClientTests
|
public class ClientTests
|
||||||
{
|
{
|
||||||
readonly ApplicationManager Manager;
|
readonly ApplicationManager Manager;
|
||||||
const int TestTimeout = 5000;
|
const int TestTimeout = 10000;
|
||||||
|
|
||||||
public ClientTests(ManagerFixture fixture)
|
public ClientTests(ManagerFixture fixture)
|
||||||
{
|
{
|
||||||
@ -40,7 +41,7 @@ namespace Tests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void WarnPlayerShouldSucceed()
|
public void WarnClientShouldSucceed()
|
||||||
{
|
{
|
||||||
while (!Manager.IsInitialized)
|
while (!Manager.IsInitialized)
|
||||||
{
|
{
|
||||||
@ -51,21 +52,31 @@ namespace Tests
|
|||||||
|
|
||||||
Assert.False(client == null, "no client found to warn");
|
Assert.False(client == null, "no client found to warn");
|
||||||
|
|
||||||
var warnEvent = client.Warn("test warn", new Player() { ClientId = 1, Level = Player.Permission.Console });
|
var warnEvent = client.Warn("test warn", new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer });
|
||||||
warnEvent.OnProcessed.Wait(TestTimeout);
|
warnEvent.OnProcessed.Wait(TestTimeout);
|
||||||
|
|
||||||
Assert.True(client.Warnings == 1 ||
|
Assert.True(client.Warnings == 1 ||
|
||||||
warnEvent.Failed, "warning did not get applied");
|
warnEvent.Failed, "warning did not get applied");
|
||||||
|
|
||||||
warnEvent = client.Warn("test warn", new Player() { ClientId = 1, Level = Player.Permission.Banned });
|
warnEvent = client.Warn("test warn", new Player() { ClientId = 1, Level = Player.Permission.Banned, CurrentServer = client.CurrentServer });
|
||||||
warnEvent.OnProcessed.Wait(TestTimeout);
|
warnEvent.OnProcessed.Wait(TestTimeout);
|
||||||
|
|
||||||
Assert.True(warnEvent.FailReason == GameEvent.EventFailReason.Permission &&
|
Assert.True(warnEvent.FailReason == GameEvent.EventFailReason.Permission &&
|
||||||
client.Warnings == 1, "warning was applied without proper permissions");
|
client.Warnings == 1, "warning was applied without proper permissions");
|
||||||
|
|
||||||
|
// warn clear
|
||||||
|
var warnClearEvent = client.WarnClear(new Player { ClientId = 1, Level = Player.Permission.Banned, CurrentServer = client.CurrentServer });
|
||||||
|
|
||||||
|
Assert.True(warnClearEvent.FailReason == GameEvent.EventFailReason.Permission &&
|
||||||
|
client.Warnings == 1, "warning was removed without proper permissions");
|
||||||
|
|
||||||
|
warnClearEvent = client.WarnClear(new Player { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer });
|
||||||
|
|
||||||
|
Assert.True(!warnClearEvent.Failed && client.Warnings == 0, "warning was not cleared");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ReportPlayerShouldSucceed()
|
public void ReportClientShouldSucceed()
|
||||||
{
|
{
|
||||||
while (!Manager.IsInitialized)
|
while (!Manager.IsInitialized)
|
||||||
{
|
{
|
||||||
@ -73,21 +84,21 @@ namespace Tests
|
|||||||
}
|
}
|
||||||
|
|
||||||
var client = Manager.Servers.First().GetPlayersAsList().FirstOrDefault();
|
var client = Manager.Servers.First().GetPlayersAsList().FirstOrDefault();
|
||||||
|
|
||||||
Assert.False(client == null, "no client found to report");
|
Assert.False(client == null, "no client found to report");
|
||||||
|
|
||||||
// succeed
|
// succeed
|
||||||
var reportEvent = client.Report("test report", new Player() { ClientId = 1, Level = Player.Permission.Console });
|
var reportEvent = client.Report("test report", new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer });
|
||||||
reportEvent.OnProcessed.Wait(TestTimeout);
|
reportEvent.OnProcessed.Wait(TestTimeout);
|
||||||
|
|
||||||
Assert.True(!reportEvent.Failed &&
|
Assert.True(!reportEvent.Failed &&
|
||||||
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 1, $"report was not applied [{reportEvent.FailReason.ToString()}]");
|
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 1, $"report was not applied [{reportEvent.FailReason.ToString()}]");
|
||||||
|
|
||||||
// fail
|
// fail
|
||||||
reportEvent = client.Report("test report", new Player() { ClientId = 2, Level = Player.Permission.Banned });
|
reportEvent = client.Report("test report", new Player() { ClientId = 1, NetworkId = 1, Level = Player.Permission.Banned, CurrentServer = client.CurrentServer });
|
||||||
|
|
||||||
Assert.True(reportEvent.FailReason == GameEvent.EventFailReason.Permission &&
|
Assert.True(reportEvent.FailReason == GameEvent.EventFailReason.Permission &&
|
||||||
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 1, $"report was applied without proper permission");
|
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 1,
|
||||||
|
$"report was applied without proper permission [{reportEvent.FailReason.ToString()},{ client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId)}]");
|
||||||
|
|
||||||
// fail
|
// fail
|
||||||
reportEvent = client.Report("test report", client);
|
reportEvent = client.Report("test report", client);
|
||||||
@ -96,10 +107,146 @@ namespace Tests
|
|||||||
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 1, $"report was applied to self");
|
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 1, $"report was applied to self");
|
||||||
|
|
||||||
// fail
|
// fail
|
||||||
reportEvent = client.Report("test report", new Player() { ClientId = 1, Level = Player.Permission.Console});
|
reportEvent = client.Report("test report", new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer });
|
||||||
|
|
||||||
Assert.True(reportEvent.FailReason == GameEvent.EventFailReason.Exception &&
|
Assert.True(reportEvent.FailReason == GameEvent.EventFailReason.Exception &&
|
||||||
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 1, $"duplicate report was applied");
|
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 1, $"duplicate report was applied");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void FlagClientShouldSucceed()
|
||||||
|
{
|
||||||
|
while (!Manager.IsInitialized)
|
||||||
|
{
|
||||||
|
Thread.Sleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
var client = Manager.Servers.First().GetPlayersAsList().FirstOrDefault();
|
||||||
|
Assert.False(client == null, "no client found to flag");
|
||||||
|
|
||||||
|
var flagEvent = client.Flag("test flag", new Player { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer });
|
||||||
|
flagEvent.OnProcessed.Wait();
|
||||||
|
|
||||||
|
// succeed
|
||||||
|
Assert.True(!flagEvent.Failed &&
|
||||||
|
client.Level == Player.Permission.Flagged, $"player is not flagged [{flagEvent.FailReason.ToString()}]");
|
||||||
|
Assert.False(client.ReceivedPenalties.FirstOrDefault(p => p.Offense == "test flag") == null, "flag was not applied");
|
||||||
|
|
||||||
|
flagEvent = client.Flag("test flag", new Player { ClientId = 1, Level = Player.Permission.Banned, CurrentServer = client.CurrentServer });
|
||||||
|
flagEvent.OnProcessed.Wait();
|
||||||
|
|
||||||
|
// fail
|
||||||
|
Assert.True(client.ReceivedPenalties.Count == 1, "flag was applied without permisions");
|
||||||
|
|
||||||
|
flagEvent = client.Flag("test flag", new Player { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer });
|
||||||
|
flagEvent.OnProcessed.Wait();
|
||||||
|
|
||||||
|
// fail
|
||||||
|
Assert.True(client.ReceivedPenalties.Count == 1, "duplicate flag was applied");
|
||||||
|
|
||||||
|
var unflagEvent = client.Unflag("test unflag", new Player { ClientId = 1, Level = Player.Permission.Banned, CurrentServer = client.CurrentServer });
|
||||||
|
unflagEvent.OnProcessed.Wait();
|
||||||
|
|
||||||
|
// fail
|
||||||
|
Assert.False(client.Level == Player.Permission.User, "user was unflagged without permissions");
|
||||||
|
|
||||||
|
unflagEvent = client.Unflag("test unflag", new Player { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer });
|
||||||
|
unflagEvent.OnProcessed.Wait();
|
||||||
|
|
||||||
|
// succeed
|
||||||
|
Assert.True(client.Level == Player.Permission.User, "user was not unflagged");
|
||||||
|
|
||||||
|
unflagEvent = client.Unflag("test unflag", new Player { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer });
|
||||||
|
unflagEvent.OnProcessed.Wait();
|
||||||
|
|
||||||
|
// succeed
|
||||||
|
Assert.True(unflagEvent.FailReason == GameEvent.EventFailReason.Invalid, "user was not flagged");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
void KickClientShouldSucceed()
|
||||||
|
{
|
||||||
|
while (!Manager.IsInitialized)
|
||||||
|
{
|
||||||
|
Thread.Sleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
var client = Manager.Servers.First().GetPlayersAsList().FirstOrDefault();
|
||||||
|
Assert.False(client == null, "no client found to kick");
|
||||||
|
|
||||||
|
var kickEvent = client.Kick("test kick", new Player() { ClientId = 1, Level = Player.Permission.Banned, CurrentServer = client.CurrentServer });
|
||||||
|
kickEvent.OnProcessed.Wait();
|
||||||
|
|
||||||
|
Assert.True(kickEvent.FailReason == GameEvent.EventFailReason.Permission, "client was kicked without permission");
|
||||||
|
|
||||||
|
kickEvent = client.Kick("test kick", new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer });
|
||||||
|
kickEvent.OnProcessed.Wait();
|
||||||
|
|
||||||
|
Assert.True(Manager.Servers.First().GetPlayersAsList().FirstOrDefault(c => c.NetworkId == client.NetworkId) == null, "client was not kicked");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
void TempBanClientShouldSucceed()
|
||||||
|
{
|
||||||
|
while (!Manager.IsInitialized)
|
||||||
|
{
|
||||||
|
Thread.Sleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
var client = Manager.Servers.First().GetPlayersAsList().FirstOrDefault();
|
||||||
|
Assert.False(client == null, "no client found to tempban");
|
||||||
|
|
||||||
|
var tbCommand = new CTempBan();
|
||||||
|
tbCommand.ExecuteAsync(new GameEvent()
|
||||||
|
{
|
||||||
|
Origin = new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer },
|
||||||
|
Target = client,
|
||||||
|
Data = "5days test tempban",
|
||||||
|
Type = GameEvent.EventType.Command,
|
||||||
|
Owner = client.CurrentServer
|
||||||
|
}).Wait();
|
||||||
|
|
||||||
|
Assert.True(Manager.GetPenaltyService().GetActivePenaltiesAsync(client.AliasLinkId).Result.Count(p => p.Type == Penalty.PenaltyType.TempBan) == 1,
|
||||||
|
"tempban was not added");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
void BanUnbanClientShouldSucceed()
|
||||||
|
{
|
||||||
|
while (!Manager.IsInitialized)
|
||||||
|
{
|
||||||
|
Thread.Sleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
var client = Manager.Servers.First().GetPlayersAsList().FirstOrDefault();
|
||||||
|
Assert.False(client == null, "no client found to ban");
|
||||||
|
|
||||||
|
var banCommand = new CBan();
|
||||||
|
banCommand.ExecuteAsync(new GameEvent()
|
||||||
|
{
|
||||||
|
Origin = new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer },
|
||||||
|
Target = client,
|
||||||
|
Data = "test ban",
|
||||||
|
Type = GameEvent.EventType.Command,
|
||||||
|
Owner = client.CurrentServer
|
||||||
|
}).Wait();
|
||||||
|
|
||||||
|
Assert.True(Manager.GetPenaltyService().GetActivePenaltiesAsync(client.AliasLinkId).Result.Count(p => p.Type == Penalty.PenaltyType.Ban) == 1,
|
||||||
|
"ban was not added");
|
||||||
|
|
||||||
|
var unbanCommand = new CUnban();
|
||||||
|
unbanCommand.ExecuteAsync(new GameEvent()
|
||||||
|
{
|
||||||
|
Origin = new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer },
|
||||||
|
Target = Manager.GetClientService().Find(c => c.NetworkId == client.NetworkId).Result.First().AsPlayer(),
|
||||||
|
Data = "test unban",
|
||||||
|
Type = GameEvent.EventType.Command,
|
||||||
|
Owner = client.CurrentServer
|
||||||
|
}).Wait();
|
||||||
|
|
||||||
|
Assert.True(Manager.GetPenaltyService().GetActivePenaltiesAsync(client.AliasLinkId).Result.Count(p => p.Type == Penalty.PenaltyType.Ban) == 0,
|
||||||
|
"ban was not removed");
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ namespace Tests
|
|||||||
|
|
||||||
public ManagerFixture()
|
public ManagerFixture()
|
||||||
{
|
{
|
||||||
File.WriteAllText("test_mp.log", "TEST_LOG_FILE");
|
File.WriteAllText("test_mp.log", "test_log_file");
|
||||||
|
|
||||||
Manager = Program.ServerManager;
|
Manager = Program.ServerManager;
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ namespace Tests
|
|||||||
Maps = new List<MapConfiguration>(),
|
Maps = new List<MapConfiguration>(),
|
||||||
RConPollRate = 10000
|
RConPollRate = 10000
|
||||||
};
|
};
|
||||||
Manager.ConfigHandler = new BaseConfigurationHandler<ApplicationConfiguration>("Test.json");
|
Manager.ConfigHandler = new BaseConfigurationHandler<ApplicationConfiguration>("test.json");
|
||||||
Manager.ConfigHandler.Set(config);
|
Manager.ConfigHandler.Set(config);
|
||||||
|
|
||||||
Manager.Init().Wait();
|
Manager.Init().Wait();
|
||||||
|
@ -124,7 +124,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
|
|
||||||
public override async Task ExecuteAsync(GameEvent E)
|
public override async Task ExecuteAsync(GameEvent E)
|
||||||
{
|
{
|
||||||
var _ = await E.Target.Kick(E.Data, E.Origin).WaitAsync() ?
|
var _ = !(await E.Target.Kick(E.Data, E.Origin).WaitAsync()).Failed ?
|
||||||
E.Origin.Tell($"^5{E.Target} ^7{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_KICK_SUCCESS"]}") :
|
E.Origin.Tell($"^5{E.Target} ^7{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_KICK_SUCCESS"]}") :
|
||||||
E.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_KICK_FAIL"]} {E.Target.Name}");
|
E.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_KICK_FAIL"]} {E.Target.Name}");
|
||||||
}
|
}
|
||||||
@ -173,16 +173,20 @@ namespace SharedLibraryCore.Commands
|
|||||||
})
|
})
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
private static readonly string TempBanRegex = @"([0-9]+\w+)\ (.+)";
|
||||||
|
|
||||||
public override async Task ExecuteAsync(GameEvent E)
|
public override async Task ExecuteAsync(GameEvent E)
|
||||||
{
|
{
|
||||||
String Message = Utilities.RemoveWords(E.Data, 1).Trim();
|
var match = Regex.Match(E.Data, TempBanRegex);
|
||||||
var length = E.Data.Split(' ')[0].ToLower().ParseTimespan();
|
if (match.Success)
|
||||||
if (length.TotalHours >= 1 && length.TotalHours < 2)
|
{
|
||||||
Message = E.Data.Replace("1h", "").Replace("1H", "");
|
string tempbanReason = match.Groups[2].ToString();
|
||||||
|
var length = match.Groups[1].ToString().ParseTimespan();
|
||||||
|
|
||||||
var _ = await E.Target.TempBan(Message, length, E.Origin).WaitAsync() ?
|
var _ = !(await E.Target.TempBan(tempbanReason, length, E.Origin).WaitAsync()).Failed ?
|
||||||
E.Origin.Tell($"^5{E.Target} ^7{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_TEMPBAN_SUCCESS"]} ^5{length.TimeSpanText()}") :
|
E.Origin.Tell($"^5{E.Target} ^7{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_TEMPBAN_SUCCESS"]} ^5{length.TimeSpanText()}") :
|
||||||
E.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_TEMPBAN_FAIL"]} {E.Target.Name}");
|
E.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_TEMPBAN_FAIL"]} {E.Target.Name}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +210,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
|
|
||||||
public override async Task ExecuteAsync(GameEvent E)
|
public override async Task ExecuteAsync(GameEvent E)
|
||||||
{
|
{
|
||||||
var _ = await E.Target.Ban(E.Data, E.Origin).WaitAsync() ?
|
var _ = !(await E.Target.Ban(E.Data, E.Origin).WaitAsync()).Failed ?
|
||||||
E.Origin.Tell($"^5{E.Target} ^7{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BAN_SUCCESS"]}") :
|
E.Origin.Tell($"^5{E.Target} ^7{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BAN_SUCCESS"]}") :
|
||||||
E.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BAN_FAIL"]} {E.Target.Name}");
|
E.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BAN_FAIL"]} {E.Target.Name}");
|
||||||
}
|
}
|
||||||
@ -721,11 +725,10 @@ namespace SharedLibraryCore.Commands
|
|||||||
})
|
})
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public override async Task ExecuteAsync(GameEvent E)
|
public override Task ExecuteAsync(GameEvent E)
|
||||||
{
|
{
|
||||||
var flagEvent = E.Target.Flag(E.Data, E.Origin);
|
var flagEvent = E.Target.Flag(E.Data, E.Origin);
|
||||||
|
|
||||||
|
|
||||||
if (E.FailReason == GameEvent.EventFailReason.Permission)
|
if (E.FailReason == GameEvent.EventFailReason.Permission)
|
||||||
{
|
{
|
||||||
E.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_FLAG_FAIL"]} ^5{E.Target.Name}");
|
E.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_FLAG_FAIL"]} ^5{E.Target.Name}");
|
||||||
@ -738,25 +741,11 @@ namespace SharedLibraryCore.Commands
|
|||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
E.Target.Level = Player.Permission.Flagged;
|
|
||||||
|
|
||||||
Penalty newPenalty = new Penalty()
|
|
||||||
{
|
|
||||||
Type = Penalty.PenaltyType.Flag,
|
|
||||||
Expires = DateTime.UtcNow,
|
|
||||||
Offender = E.Target,
|
|
||||||
Offense = E.Data,
|
|
||||||
Punisher = E.Origin,
|
|
||||||
Active = true,
|
|
||||||
When = DateTime.UtcNow,
|
|
||||||
Link = E.Target.AliasLink
|
|
||||||
};
|
|
||||||
|
|
||||||
await E.Owner.Manager.GetPenaltyService().Create(newPenalty);
|
|
||||||
|
|
||||||
E.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_FLAG_SUCCESS"]} ^5{E.Target.Name}");
|
E.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_FLAG_SUCCESS"]} ^5{E.Target.Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -843,6 +832,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// todo: move into server
|
||||||
Penalty newReport = new Penalty()
|
Penalty newReport = new Penalty()
|
||||||
{
|
{
|
||||||
Type = Penalty.PenaltyType.Report,
|
Type = Penalty.PenaltyType.Report,
|
||||||
|
@ -24,11 +24,9 @@ namespace SharedLibraryCore.Database
|
|||||||
public DbSet<EFMeta> EFMeta { get; set; }
|
public DbSet<EFMeta> EFMeta { get; set; }
|
||||||
public DbSet<EFChangeHistory> EFChangeHistory { get; set; }
|
public DbSet<EFChangeHistory> EFChangeHistory { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// this only works if there's one connection string
|
static string _ConnectionString;
|
||||||
/// </summary>
|
static string _provider;
|
||||||
private static string _ConnectionString;
|
|
||||||
private static string _provider;
|
|
||||||
|
|
||||||
public DatabaseContext(DbContextOptions<DatabaseContext> opt) : base(opt) { }
|
public DatabaseContext(DbContextOptions<DatabaseContext> opt) : base(opt) { }
|
||||||
|
|
||||||
@ -63,12 +61,12 @@ namespace SharedLibraryCore.Database
|
|||||||
var connectionStringBuilder = new SqliteConnectionStringBuilder { DataSource = $"{currentPath}{Path.DirectorySeparatorChar}Database.db".Substring(6) };
|
var connectionStringBuilder = new SqliteConnectionStringBuilder { DataSource = $"{currentPath}{Path.DirectorySeparatorChar}Database.db".Substring(6) };
|
||||||
var connectionString = connectionStringBuilder.ToString();
|
var connectionString = connectionStringBuilder.ToString();
|
||||||
var connection = new SqliteConnection(connectionString);
|
var connection = new SqliteConnection(connectionString);
|
||||||
#if DEBUG == true
|
//#if DEBUG == true
|
||||||
optionsBuilder.UseMySql("UserId=root;Password=dev;Host=127.0.0.1;port=3306;Database=IW4MAdmin");
|
//optionsBuilder.UseMySql("UserId=root;Password=dev;Host=127.0.0.1;port=3306;Database=IW4MAdmin");
|
||||||
// optionsBuilder.UseNpgsql("UserId=dev;Password=dev;Host=127.0.0.1;port=5432;Database=IW4MAdmin");
|
// optionsBuilder.UseNpgsql("UserId=dev;Password=dev;Host=127.0.0.1;port=5432;Database=IW4MAdmin");
|
||||||
#else
|
//#else
|
||||||
optionsBuilder.UseSqlite(connection);
|
optionsBuilder.UseSqlite(connection);
|
||||||
#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -181,10 +181,10 @@ namespace SharedLibraryCore
|
|||||||
/// asynchronously wait for GameEvent to be processed
|
/// asynchronously wait for GameEvent to be processed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>waitable task </returns>
|
/// <returns>waitable task </returns>
|
||||||
public Task<bool> WaitAsync(int timeOut = int.MaxValue) => Task.Run(() =>
|
public Task<GameEvent> WaitAsync(int timeOut = int.MaxValue) => Task.Run(() =>
|
||||||
{
|
{
|
||||||
OnProcessed.Wait(timeOut);
|
OnProcessed.Wait(timeOut);
|
||||||
return !Failed;
|
return this;
|
||||||
});
|
});
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -214,7 +214,7 @@ namespace SharedLibraryCore
|
|||||||
/// <returns>true if event should be delayed, false otherwise</returns>
|
/// <returns>true if event should be delayed, false otherwise</returns>
|
||||||
public static bool ShouldTargetEventBeDelayed(GameEvent queuedEvent)
|
public static bool ShouldTargetEventBeDelayed(GameEvent queuedEvent)
|
||||||
{
|
{
|
||||||
return queuedEvent.Target != null &&
|
return (queuedEvent.Target != null && queuedEvent.Target.ClientNumber != -1) &&
|
||||||
(queuedEvent.Target.State != Player.ClientState.Connected &&
|
(queuedEvent.Target.State != Player.ClientState.Connected &&
|
||||||
queuedEvent.Target.NetworkId != 0);
|
queuedEvent.Target.NetworkId != 0);
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ namespace SharedLibraryCore.Objects
|
|||||||
Data = message
|
Data = message
|
||||||
};
|
};
|
||||||
|
|
||||||
CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
this.CurrentServer?.Manager.GetEventHandler().AddEvent(e);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ namespace SharedLibraryCore.Objects
|
|||||||
Message = warnReason,
|
Message = warnReason,
|
||||||
Origin = sender,
|
Origin = sender,
|
||||||
Target = this,
|
Target = this,
|
||||||
Owner = this.CurrentServer
|
Owner = sender.CurrentServer
|
||||||
};
|
};
|
||||||
|
|
||||||
// enforce level restrictions
|
// enforce level restrictions
|
||||||
@ -130,7 +130,36 @@ namespace SharedLibraryCore.Objects
|
|||||||
|
|
||||||
this.Warnings++;
|
this.Warnings++;
|
||||||
|
|
||||||
CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
sender.CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// clear all warnings for a client
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">client performing the warn clear</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public GameEvent WarnClear(Player sender)
|
||||||
|
{
|
||||||
|
var e = new GameEvent()
|
||||||
|
{
|
||||||
|
Type = GameEvent.EventType.WarnClear,
|
||||||
|
Origin = sender,
|
||||||
|
Target = this,
|
||||||
|
Owner = sender.CurrentServer
|
||||||
|
};
|
||||||
|
|
||||||
|
// enforce level restrictions
|
||||||
|
if (sender.Level <= this.Level)
|
||||||
|
{
|
||||||
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Warnings = 0;
|
||||||
|
|
||||||
|
sender.CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,58 +178,26 @@ namespace SharedLibraryCore.Objects
|
|||||||
Data = reportReason,
|
Data = reportReason,
|
||||||
Origin = sender,
|
Origin = sender,
|
||||||
Target = this,
|
Target = this,
|
||||||
Owner = this.CurrentServer
|
Owner = sender.CurrentServer
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.Level > sender.Level)
|
if (this.Level > sender.Level)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Permission;
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
||||||
return e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this == sender)
|
else if (this.Equals(sender))
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Invalid;
|
e.FailReason = GameEvent.EventFailReason.Invalid;
|
||||||
return e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CurrentServer.Reports.Count(rep => (rep.Origin.NetworkId == sender.NetworkId &&
|
else if (CurrentServer.Reports.Count(report => (report.Origin.NetworkId == sender.NetworkId &&
|
||||||
rep.Target.NetworkId == this.NetworkId)) > 0)
|
report.Target.NetworkId == this.NetworkId)) > 0)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Exception;
|
e.FailReason = GameEvent.EventFailReason.Exception;
|
||||||
return e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentServer.Reports.Add(new Report(this, sender, reportReason));
|
sender.CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
||||||
CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// clear all warnings for a client
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender">client performing the warn clear</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public GameEvent WarnClear(Player sender)
|
|
||||||
{
|
|
||||||
var e = new GameEvent()
|
|
||||||
{
|
|
||||||
Type = GameEvent.EventType.WarnClear,
|
|
||||||
Origin = sender,
|
|
||||||
Target = this,
|
|
||||||
Owner = this.CurrentServer
|
|
||||||
};
|
|
||||||
|
|
||||||
// enforce level restrictions
|
|
||||||
if (sender.Level <= this.Level)
|
|
||||||
{
|
|
||||||
e.FailReason = GameEvent.EventFailReason.Permission;
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.Warnings = 0;
|
|
||||||
|
|
||||||
CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,22 +215,26 @@ namespace SharedLibraryCore.Objects
|
|||||||
Origin = sender,
|
Origin = sender,
|
||||||
Data = flagReason,
|
Data = flagReason,
|
||||||
Message = flagReason,
|
Message = flagReason,
|
||||||
Owner = this.CurrentServer
|
Target = this,
|
||||||
|
Owner = sender.CurrentServer
|
||||||
};
|
};
|
||||||
|
|
||||||
if (sender.Level <= this.Level)
|
if (this.Level >= sender.Level)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Permission;
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
||||||
return e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.Level == Player.Permission.Flagged)
|
else if (this.Level == Player.Permission.Flagged)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Invalid;
|
e.FailReason = GameEvent.EventFailReason.Invalid;
|
||||||
return e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
else
|
||||||
|
{
|
||||||
|
this.Level = Player.Permission.Flagged;
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,26 +250,28 @@ namespace SharedLibraryCore.Objects
|
|||||||
{
|
{
|
||||||
Type = GameEvent.EventType.Unflag,
|
Type = GameEvent.EventType.Unflag,
|
||||||
Origin = sender,
|
Origin = sender,
|
||||||
|
Target = this,
|
||||||
Data = unflagReason,
|
Data = unflagReason,
|
||||||
Message = unflagReason,
|
Message = unflagReason,
|
||||||
Owner = this.CurrentServer
|
Owner = sender.CurrentServer
|
||||||
};
|
};
|
||||||
|
|
||||||
if (sender.Level <= this.Level)
|
if (sender.Level <= this.Level)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Permission;
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
||||||
return e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.Level != Player.Permission.Flagged)
|
else if (this.Level != Player.Permission.Flagged)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Invalid;
|
e.FailReason = GameEvent.EventFailReason.Invalid;
|
||||||
return e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Level = Permission.User;
|
else
|
||||||
|
{
|
||||||
|
this.Level = Permission.User;
|
||||||
|
}
|
||||||
|
|
||||||
CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
sender.CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,17 +289,16 @@ namespace SharedLibraryCore.Objects
|
|||||||
Target = this,
|
Target = this,
|
||||||
Origin = sender,
|
Origin = sender,
|
||||||
Data = kickReason,
|
Data = kickReason,
|
||||||
Owner = this.CurrentServer
|
Owner = sender.CurrentServer
|
||||||
};
|
};
|
||||||
|
|
||||||
// enforce level restrictions
|
// enforce level restrictions
|
||||||
if (sender.Level <= this.Level)
|
if (this.Level > sender.Level)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Permission;
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
||||||
return e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
sender.CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,10 +314,11 @@ namespace SharedLibraryCore.Objects
|
|||||||
{
|
{
|
||||||
Type = GameEvent.EventType.TempBan,
|
Type = GameEvent.EventType.TempBan,
|
||||||
Message = tempbanReason,
|
Message = tempbanReason,
|
||||||
|
Data = tempbanReason,
|
||||||
Origin = sender,
|
Origin = sender,
|
||||||
Target = this,
|
Target = this,
|
||||||
Extra = banLength,
|
Extra = banLength,
|
||||||
Owner = this.CurrentServer
|
Owner = sender.CurrentServer
|
||||||
};
|
};
|
||||||
|
|
||||||
// enforce level restrictions
|
// enforce level restrictions
|
||||||
@ -325,7 +328,7 @@ namespace SharedLibraryCore.Objects
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
sender.CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,9 +343,10 @@ namespace SharedLibraryCore.Objects
|
|||||||
{
|
{
|
||||||
Type = GameEvent.EventType.Ban,
|
Type = GameEvent.EventType.Ban,
|
||||||
Message = banReason,
|
Message = banReason,
|
||||||
|
Data = banReason,
|
||||||
Origin = sender,
|
Origin = sender,
|
||||||
Target = this,
|
Target = this,
|
||||||
Owner = this.CurrentServer
|
Owner = sender.CurrentServer
|
||||||
};
|
};
|
||||||
|
|
||||||
// enforce level restrictions
|
// enforce level restrictions
|
||||||
@ -352,7 +356,7 @@ namespace SharedLibraryCore.Objects
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
sender.CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,17 +375,16 @@ namespace SharedLibraryCore.Objects
|
|||||||
Data = unbanReason,
|
Data = unbanReason,
|
||||||
Origin = sender,
|
Origin = sender,
|
||||||
Target = this,
|
Target = this,
|
||||||
Owner = this.CurrentServer
|
Owner = sender.CurrentServer
|
||||||
};
|
};
|
||||||
|
|
||||||
// enforce level restrictions
|
// enforce level restrictions
|
||||||
if (sender.Level <= this.Level)
|
if (this.Level > sender.Level)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Permission;
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
||||||
return e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
sender.CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,7 +435,7 @@ namespace SharedLibraryCore.Objects
|
|||||||
|
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
{
|
{
|
||||||
return ((Player)obj).NetworkId == NetworkId;
|
return ((Player)obj).NetworkId == this.NetworkId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetHashCode() => (int)NetworkId;
|
public override int GetHashCode() => (int)NetworkId;
|
||||||
|
@ -8,15 +8,8 @@ namespace SharedLibraryCore.Objects
|
|||||||
{
|
{
|
||||||
public class Report
|
public class Report
|
||||||
{
|
{
|
||||||
public Report(Player T, Player O, String R)
|
public Player Target { get; set; }
|
||||||
{
|
public Player Origin { get; set; }
|
||||||
Target = T;
|
public String Reason { get; set; }
|
||||||
Origin = O;
|
|
||||||
Reason = R;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Player Target { get; private set; }
|
|
||||||
public Player Origin { get; private set; }
|
|
||||||
public String Reason { get; private set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,10 @@ namespace SharedLibraryCore.RCon
|
|||||||
const int BufferSize = 4096;
|
const int BufferSize = 4096;
|
||||||
public readonly byte[] ReceiveBuffer = new byte[BufferSize];
|
public readonly byte[] ReceiveBuffer = new byte[BufferSize];
|
||||||
public readonly SemaphoreSlim OnComplete = new SemaphoreSlim(1, 1);
|
public readonly SemaphoreSlim OnComplete = new SemaphoreSlim(1, 1);
|
||||||
|
public readonly ManualResetEventSlim OnSentData = new ManualResetEventSlim(false);
|
||||||
|
public readonly ManualResetEventSlim OnReceivedData = new ManualResetEventSlim(false);
|
||||||
|
public SocketAsyncEventArgs SendEventArgs { get; set; } = new SocketAsyncEventArgs();
|
||||||
|
public SocketAsyncEventArgs ReceiveEventArgs { get; set; } = new SocketAsyncEventArgs();
|
||||||
public DateTime LastQuery { get; set; } = DateTime.Now;
|
public DateTime LastQuery { get; set; } = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,23 +47,24 @@ namespace SharedLibraryCore.RCon
|
|||||||
|
|
||||||
var connectionState = ActiveQueries[this.Endpoint];
|
var connectionState = ActiveQueries[this.Endpoint];
|
||||||
|
|
||||||
var timeLeft = (DateTime.Now - connectionState.LastQuery).TotalMilliseconds;
|
#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 (timeLeft > 0)
|
var timeSinceLastQuery = (DateTime.Now - connectionState.LastQuery).TotalMilliseconds;
|
||||||
|
|
||||||
|
if (timeSinceLastQuery < StaticHelpers.FloodProtectionInterval)
|
||||||
{
|
{
|
||||||
await Task.Delay((int)timeLeft);
|
await Task.Delay(StaticHelpers.FloodProtectionInterval - (int)timeSinceLastQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
connectionState.LastQuery = DateTime.Now;
|
connectionState.LastQuery = DateTime.Now;
|
||||||
|
|
||||||
#if DEBUG == true
|
#if DEBUG == true
|
||||||
Log.WriteDebug($"Waiting for semaphore to be released [${this.Endpoint}]");
|
Log.WriteDebug($"Semaphore has been released [{this.Endpoint}]");
|
||||||
#endif
|
Log.WriteDebug($"Query [{this.Endpoint},{type.ToString()},{parameters}]");
|
||||||
// enter the semaphore so only one query is sent at a time per server.
|
|
||||||
await connectionState.OnComplete.WaitAsync();
|
|
||||||
|
|
||||||
#if DEBUG == true
|
|
||||||
Log.WriteDebug($"Semaphore has been released [${this.Endpoint}]");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
byte[] payload = null;
|
byte[] payload = null;
|
||||||
@ -82,33 +87,41 @@ namespace SharedLibraryCore.RCon
|
|||||||
}
|
}
|
||||||
|
|
||||||
byte[] response = null;
|
byte[] response = null;
|
||||||
|
|
||||||
retrySend:
|
retrySend:
|
||||||
|
connectionState.SendEventArgs.UserToken = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
|
||||||
|
{
|
||||||
|
DontFragment = true,
|
||||||
|
Ttl = 42,
|
||||||
|
ExclusiveAddressUse = true,
|
||||||
|
};
|
||||||
|
connectionState.OnSentData.Reset();
|
||||||
|
connectionState.OnReceivedData.Reset();
|
||||||
|
connectionState.ConnectionAttempts++;
|
||||||
#if DEBUG == true
|
#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
|
#endif
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
response = await SendPayloadAsync(payload);
|
response = await SendPayloadAsync(payload);
|
||||||
connectionState.OnComplete.Release(1);
|
connectionState.OnComplete.Release(1);
|
||||||
|
connectionState.ConnectionAttempts = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception ex)
|
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})");
|
||||||
Log.WriteWarning($"{Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_COMMUNICATION"]} [{this.Endpoint}] ({connectionState.ConnectionAttempts++}/{StaticHelpers.AllowedConnectionFails})");
|
|
||||||
await Task.Delay(StaticHelpers.FloodProtectionInterval);
|
await Task.Delay(StaticHelpers.FloodProtectionInterval);
|
||||||
goto retrySend;
|
goto retrySend;
|
||||||
}
|
}
|
||||||
// the next thread can go ahead and enter
|
|
||||||
connectionState.OnComplete.Release(1);
|
|
||||||
|
|
||||||
|
connectionState.OnComplete.Release(1);
|
||||||
Log.WriteDebug(ex.GetExceptionInfo());
|
Log.WriteDebug(ex.GetExceptionInfo());
|
||||||
throw new NetworkException($"{Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_COMMUNICATION"]} [{this.Endpoint}]");
|
throw new NetworkException($"{Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_COMMUNICATION"]} [{this.Endpoint}]");
|
||||||
}
|
}
|
||||||
|
|
||||||
connectionState.ConnectionAttempts = 0;
|
|
||||||
string responseString = Utilities.EncodingType.GetString(response, 0, response.Length).TrimEnd('\0') + '\n';
|
string responseString = Utilities.EncodingType.GetString(response, 0, response.Length).TrimEnd('\0') + '\n';
|
||||||
|
|
||||||
if (responseString.Contains("Invalid password"))
|
if (responseString.Contains("Invalid password"))
|
||||||
@ -128,45 +141,54 @@ namespace SharedLibraryCore.RCon
|
|||||||
|
|
||||||
private async Task<byte[]> SendPayloadAsync(byte[] payload)
|
private async Task<byte[]> SendPayloadAsync(byte[] payload)
|
||||||
{
|
{
|
||||||
var rconSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
|
|
||||||
{
|
|
||||||
DontFragment = true,
|
|
||||||
Ttl = 42,
|
|
||||||
ExclusiveAddressUse = true
|
|
||||||
};
|
|
||||||
|
|
||||||
var connectionState = ActiveQueries[this.Endpoint];
|
var connectionState = ActiveQueries[this.Endpoint];
|
||||||
|
var rconSocket = (Socket)connectionState.SendEventArgs.UserToken;
|
||||||
|
|
||||||
var outgoingDataArgs = new SocketAsyncEventArgs()
|
if (connectionState.ReceiveEventArgs.RemoteEndPoint == null &&
|
||||||
|
connectionState.SendEventArgs.RemoteEndPoint == null)
|
||||||
{
|
{
|
||||||
RemoteEndPoint = this.Endpoint
|
// setup the event handlers only once because we're reusing the event args
|
||||||
};
|
connectionState.SendEventArgs.Completed += OnDataSent;
|
||||||
outgoingDataArgs.SetBuffer(payload);
|
connectionState.ReceiveEventArgs.Completed += OnDataReceived;
|
||||||
outgoingDataArgs.Completed += OnDataSent;
|
connectionState.SendEventArgs.RemoteEndPoint = this.Endpoint;
|
||||||
|
connectionState.ReceiveEventArgs.RemoteEndPoint = this.Endpoint;
|
||||||
// send the data to the server
|
connectionState.ReceiveEventArgs.DisconnectReuseSocket = true;
|
||||||
bool sendDataPending = rconSocket.SendToAsync(outgoingDataArgs);
|
connectionState.SendEventArgs.DisconnectReuseSocket = true;
|
||||||
|
|
||||||
var incomingDataArgs = new SocketAsyncEventArgs()
|
|
||||||
{
|
|
||||||
RemoteEndPoint = this.Endpoint
|
|
||||||
};
|
|
||||||
incomingDataArgs.SetBuffer(connectionState.ReceiveBuffer);
|
|
||||||
incomingDataArgs.Completed += OnDataReceived;
|
|
||||||
|
|
||||||
// get our response back
|
|
||||||
rconSocket.ReceiveFromAsync(incomingDataArgs);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] response = connectionState.ReceiveBuffer;
|
connectionState.SendEventArgs.SetBuffer(payload);
|
||||||
|
|
||||||
|
// send the data to the server
|
||||||
|
bool sendDataPending = rconSocket.SendToAsync(connectionState.SendEventArgs);
|
||||||
|
|
||||||
|
if (sendDataPending)
|
||||||
|
{
|
||||||
|
// the send has not been completed asyncronously
|
||||||
|
if (!await Task.Run(() => connectionState.OnSentData.Wait(StaticHelpers.SocketTimeout)))
|
||||||
|
{
|
||||||
|
rconSocket.Close();
|
||||||
|
throw new NetworkException("Timed out sending data", rconSocket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
connectionState.ReceiveEventArgs.SetBuffer(connectionState.ReceiveBuffer);
|
||||||
|
|
||||||
|
// get our response back
|
||||||
|
bool receiveDataPending = rconSocket.ReceiveFromAsync(connectionState.ReceiveEventArgs);
|
||||||
|
|
||||||
|
if (receiveDataPending)
|
||||||
|
{
|
||||||
|
if (!await Task.Run(() => connectionState.OnReceivedData.Wait(StaticHelpers.SocketTimeout)))
|
||||||
|
{
|
||||||
|
rconSocket.Close();
|
||||||
|
throw new NetworkException("Timed out waiting for response", rconSocket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] response = connectionState.ReceiveBuffer
|
||||||
|
.Take(connectionState.ReceiveEventArgs.BytesTransferred)
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,10 +197,7 @@ namespace SharedLibraryCore.RCon
|
|||||||
#if DEBUG == true
|
#if DEBUG == true
|
||||||
Log.WriteDebug($"Read {e.BytesTransferred} bytes from {e.RemoteEndPoint.ToString()}");
|
Log.WriteDebug($"Read {e.BytesTransferred} bytes from {e.RemoteEndPoint.ToString()}");
|
||||||
#endif
|
#endif
|
||||||
if (ActiveQueries[this.Endpoint].OnComplete.CurrentCount == 0)
|
ActiveQueries[this.Endpoint].OnReceivedData.Set();
|
||||||
{
|
|
||||||
ActiveQueries[this.Endpoint].OnComplete.Release(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDataSent(object sender, SocketAsyncEventArgs e)
|
private void OnDataSent(object sender, SocketAsyncEventArgs e)
|
||||||
@ -186,6 +205,7 @@ namespace SharedLibraryCore.RCon
|
|||||||
#if DEBUG == true
|
#if DEBUG == true
|
||||||
Log.WriteDebug($"Sent {e.Buffer.Length} bytes to {e.ConnectSocket.RemoteEndPoint.ToString()}");
|
Log.WriteDebug($"Sent {e.Buffer.Length} bytes to {e.ConnectSocket.RemoteEndPoint.ToString()}");
|
||||||
#endif
|
#endif
|
||||||
|
ActiveQueries[this.Endpoint].OnSentData.Set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,11 +39,11 @@ namespace SharedLibraryCore.RCon
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// timeout in seconds to wait for a socket send or receive before giving up
|
/// timeout in seconds to wait for a socket send or receive before giving up
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly TimeSpan SocketTimeout = new TimeSpan(0, 0, 0, 0,150);
|
public static readonly int SocketTimeout = 1000;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// interval in milliseconds to wait before sending the next RCon request
|
/// interval in milliseconds to wait before sending the next RCon request
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly int FloodProtectionInterval = 350;
|
public static readonly int FloodProtectionInterval = 635;
|
||||||
public static readonly int AllowedConnectionFails = 3;
|
public static readonly int AllowedConnectionFails = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,14 +192,14 @@ namespace SharedLibraryCore
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="Reason">Reason for kicking</param>
|
/// <param name="Reason">Reason for kicking</param>
|
||||||
/// <param name="Target">Player to kick</param>
|
/// <param name="Target">Player to kick</param>
|
||||||
abstract public Task Kick(String Reason, Player Target, Player Origin);
|
abstract protected Task Kick(String Reason, Player Target, Player Origin);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Temporarily ban a player ( default 1 hour ) from the server
|
/// Temporarily ban a player ( default 1 hour ) from the server
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="Reason">Reason for banning the player</param>
|
/// <param name="Reason">Reason for banning the player</param>
|
||||||
/// <param name="Target">The player to ban</param>
|
/// <param name="Target">The player to ban</param>
|
||||||
abstract public Task TempBan(String Reason, TimeSpan length, Player Target, Player Origin);
|
abstract protected Task TempBan(String Reason, TimeSpan length, Player Target, Player Origin);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Perm ban a player from the server
|
/// Perm ban a player from the server
|
||||||
@ -207,7 +207,7 @@ namespace SharedLibraryCore
|
|||||||
/// <param name="Reason">The reason for the ban</param>
|
/// <param name="Reason">The reason for the ban</param>
|
||||||
/// <param name="Target">The person to ban</param>
|
/// <param name="Target">The person to ban</param>
|
||||||
/// <param name="Origin">The person who banned the target</param>
|
/// <param name="Origin">The person who banned the target</param>
|
||||||
abstract public Task Ban(String Reason, Player Target, Player Origin);
|
abstract protected Task Ban(String Reason, Player Target, Player Origin);
|
||||||
|
|
||||||
abstract public Task Warn(String Reason, Player Target, Player Origin);
|
abstract public Task Warn(String Reason, Player Target, Player Origin);
|
||||||
|
|
||||||
|
@ -322,13 +322,13 @@ namespace SharedLibraryCore
|
|||||||
|
|
||||||
public static TimeSpan ParseTimespan(this string input)
|
public static TimeSpan ParseTimespan(this string input)
|
||||||
{
|
{
|
||||||
var expressionMatch = Regex.Match(input, @"[0-9]+.\b");
|
var expressionMatch = Regex.Match(input, @"([0-9]+)(\w+)");
|
||||||
|
|
||||||
if (!expressionMatch.Success) // fallback to default tempban length of 1 hour
|
if (!expressionMatch.Success) // fallback to default tempban length of 1 hour
|
||||||
return new TimeSpan(1, 0, 0);
|
return new TimeSpan(1, 0, 0);
|
||||||
|
|
||||||
char lengthDenote = expressionMatch.Value.ToLower()[expressionMatch.Value.Length - 1];
|
char lengthDenote = expressionMatch.Groups[2].ToString()[0];
|
||||||
int length = Int32.Parse(expressionMatch.Value.Substring(0, expressionMatch.Value.Length - 1));
|
int length = Int32.Parse(expressionMatch.Groups[1].ToString());
|
||||||
|
|
||||||
var loc = CurrentLocalization.LocalizationIndex;
|
var loc = CurrentLocalization.LocalizationIndex;
|
||||||
|
|
||||||
@ -337,22 +337,22 @@ namespace SharedLibraryCore
|
|||||||
return new TimeSpan(0, length, 0);
|
return new TimeSpan(0, length, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lengthDenote == char.ToLower(loc["GLOBAL_TIME_HOURS"].First()))
|
if (lengthDenote == char.ToLower(loc["GLOBAL_TIME_HOURS"][0]))
|
||||||
{
|
{
|
||||||
return new TimeSpan(length, 0, 0);
|
return new TimeSpan(length, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lengthDenote == char.ToLower(loc["GLOBAL_TIME_DAYS"].First()))
|
if (lengthDenote == char.ToLower(loc["GLOBAL_TIME_DAYS"][0]))
|
||||||
{
|
{
|
||||||
return new TimeSpan(length, 0, 0, 0);
|
return new TimeSpan(length, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lengthDenote == char.ToLower(loc["GLOBAL_TIME_WEEKS"].First()))
|
if (lengthDenote == char.ToLower(loc["GLOBAL_TIME_WEEKS"][0]))
|
||||||
{
|
{
|
||||||
return new TimeSpan(length * 7, 0, 0, 0);
|
return new TimeSpan(length * 7, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lengthDenote == char.ToLower(loc["GLOBAL_TIME_YEARS"].First()))
|
if (lengthDenote == char.ToLower(loc["GLOBAL_TIME_YEARS"][0]))
|
||||||
{
|
{
|
||||||
return new TimeSpan(length * 365, 0, 0, 0);
|
return new TimeSpan(length * 365, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -50,22 +50,24 @@ namespace WebfrontCore.Controllers
|
|||||||
{
|
{
|
||||||
string duration = string.Empty;
|
string duration = string.Empty;
|
||||||
|
|
||||||
|
var loc = Utilities.CurrentLocalization.LocalizationIndex;
|
||||||
|
|
||||||
switch (Duration)
|
switch (Duration)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
duration = "1h";
|
duration = $"1{loc["GLOBAL_TIME_HOURS"][0]}";
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
duration = "6h";
|
duration = $"6{loc["GLOBAL_TIME_HOURS"][0]}";
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
duration = "1d";
|
duration = $"1{loc["GLOBAL_TIME_DAYS"][0]}";
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
duration = "2d";
|
duration = $"2{loc["GLOBAL_TIME_DAYS"][0]}";
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
duration = "1w";
|
duration = $"1{loc["GLOBAL_TIME_WEEKS"][0]}";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ namespace WebfrontCore.Controllers
|
|||||||
Manager.GetEventHandler().AddEvent(remoteEvent);
|
Manager.GetEventHandler().AddEvent(remoteEvent);
|
||||||
List<CommandResponseInfo> response;
|
List<CommandResponseInfo> response;
|
||||||
// wait for the event to process
|
// wait for the event to process
|
||||||
if (await remoteEvent.WaitAsync(60 * 1000))
|
if (!(await remoteEvent.WaitAsync(60 * 1000)).Failed)
|
||||||
{
|
{
|
||||||
response = server.CommandResult.Where(c => c.ClientId == client.ClientId).ToList();
|
response = server.CommandResult.Where(c => c.ClientId == client.ClientId).ToList();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user