allow reports to be filed against anyone

fix rare issue with alias (maybe)
update some tests
This commit is contained in:
RaidMax 2019-06-24 11:01:34 -05:00
parent cb80def122
commit 253c7c8721
16 changed files with 336 additions and 229 deletions

View File

@ -32,7 +32,7 @@
<PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection>
<TieredCompilation>true</TieredCompilation>
<AssemblyVersion>2.2.7.6</AssemblyVersion>
<AssemblyVersion>2.2.7.7</AssemblyVersion>
<FileVersion>2.2.7.7</FileVersion>
<LangVersion>7.1</LangVersion>
</PropertyGroup>

View File

@ -30,7 +30,9 @@ namespace IW4MAdmin.Application.IO
{
while (!_server.Manager.CancellationToken.IsCancellationRequested)
{
#if !DEBUG
if (_server.IsInitialized)
#endif
{
try
{

View File

@ -585,6 +585,13 @@ namespace IW4MAdmin
try
{
#if DEBUG
if (Manager.GetApplicationSettings().Configuration().RConPollRate == int.MaxValue)
{
return true;
}
#endif
var polledClients = await PollPlayersAsync();
var waiterList = new List<GameEvent>();
@ -766,7 +773,8 @@ namespace IW4MAdmin
if (version?.Value?.Length != 0)
{
RconParser = Manager.AdditionalRConParsers.FirstOrDefault(_parser => _parser.Version == version.Value) ?? RconParser;
var matchedRconParser = Manager.AdditionalRConParsers.FirstOrDefault(_parser => _parser.Version == version.Value);
RconParser.Configuration = matchedRconParser != null ? matchedRconParser.Configuration : RconParser.Configuration;
EventParser = Manager.AdditionalEventParsers.FirstOrDefault(_parser => _parser.Version == version.Value) ?? EventParser;
Version = RconParser.Version;
}
@ -1011,11 +1019,9 @@ namespace IW4MAdmin
#endif
}
// this should link evading clients
if (isEvade)
{
Logger.WriteInfo($"updating alias for banned client {targetClient}");
await Manager.GetClientService().UpdateAlias(targetClient);
}
EFPenalty newPenalty = new EFPenalty()

View File

@ -1,6 +1,7 @@
using SharedLibraryCore;
using SharedLibraryCore.Interfaces;
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
@ -73,10 +74,12 @@ namespace IW4MAdmin.Application
// lets keep it simple and dispose of everything quickly as logging wont be that much (relatively)
Console.WriteLine(LogLine);
File.AppendAllText(FileName, LogLine + Environment.NewLine);
Debug.WriteLine(msg);
#else
if (type == LogType.Error || type == LogType.Verbose)
{
Console.WriteLine(LogLine);
//if (type != LogType.Debug)
}
File.AppendAllText(FileName, $"{LogLine}{Environment.NewLine}");
#endif
}

View File

@ -12,7 +12,11 @@ using static SharedLibraryCore.Server;
namespace IW4MAdmin.Application.RconParsers
{
#if DEBUG
public class BaseRConParser : IRConParser
#else
class BaseRConParser : IRConParser
#endif
{
public BaseRConParser()
{
@ -52,7 +56,7 @@ namespace IW4MAdmin.Application.RconParsers
public IRConParserConfiguration Configuration { get; set; }
public string Version { get; set; } = "CoD";
public virtual string Version { get; set; } = "CoD";
public Game GameName { get; set; } = Game.COD;
public bool CanGenerateLogPath { get; set; } = true;
@ -89,7 +93,7 @@ namespace IW4MAdmin.Application.RconParsers
};
}
public async Task<List<EFClient>> GetStatusAsync(Connection connection)
public virtual async Task<List<EFClient>> GetStatusAsync(Connection connection)
{
string[] response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND_STATUS);
return ClientsFromStatus(response);

View File

@ -34,8 +34,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "Plugins\Tests\Test
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IW4ScriptCommands", "Plugins\IW4ScriptCommands\IW4ScriptCommands.csproj", "{6C706CE5-A206-4E46-8712-F8C48D526091}"
EndProject
Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "DiscordWebhook", "DiscordWebhook\DiscordWebhook.pyproj", "{15A81D6E-7502-46CE-8530-0647A380B5F4}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ScriptPlugins", "ScriptPlugins", "{3F9ACC27-26DB-49FA-BCD2-50C54A49C9FA}"
ProjectSection(SolutionItems) = preProject
Plugins\ScriptPlugins\ParserCoD4x.js = Plugins\ScriptPlugins\ParserCoD4x.js
@ -309,18 +307,6 @@ Global
{6C706CE5-A206-4E46-8712-F8C48D526091}.Release|x64.Build.0 = Release|Any CPU
{6C706CE5-A206-4E46-8712-F8C48D526091}.Release|x86.ActiveCfg = Release|Any CPU
{6C706CE5-A206-4E46-8712-F8C48D526091}.Release|x86.Build.0 = Release|Any CPU
{15A81D6E-7502-46CE-8530-0647A380B5F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{15A81D6E-7502-46CE-8530-0647A380B5F4}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{15A81D6E-7502-46CE-8530-0647A380B5F4}.Debug|x64.ActiveCfg = Debug|Any CPU
{15A81D6E-7502-46CE-8530-0647A380B5F4}.Debug|x86.ActiveCfg = Debug|Any CPU
{15A81D6E-7502-46CE-8530-0647A380B5F4}.Prerelease|Any CPU.ActiveCfg = Prerelease|Any CPU
{15A81D6E-7502-46CE-8530-0647A380B5F4}.Prerelease|Mixed Platforms.ActiveCfg = Release|Any CPU
{15A81D6E-7502-46CE-8530-0647A380B5F4}.Prerelease|x64.ActiveCfg = Release|Any CPU
{15A81D6E-7502-46CE-8530-0647A380B5F4}.Prerelease|x86.ActiveCfg = Release|Any CPU
{15A81D6E-7502-46CE-8530-0647A380B5F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{15A81D6E-7502-46CE-8530-0647A380B5F4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{15A81D6E-7502-46CE-8530-0647A380B5F4}.Release|x64.ActiveCfg = Release|Any CPU
{15A81D6E-7502-46CE-8530-0647A380B5F4}.Release|x86.ActiveCfg = Release|Any CPU
{42EFDA12-10D3-4C40-A210-9483520116BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{42EFDA12-10D3-4C40-A210-9483520116BC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{42EFDA12-10D3-4C40-A210-9483520116BC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU

View File

@ -133,6 +133,8 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
var weightedSessionAverage = HitLocationCount.Where(_hit => _hit.Value.Count > 0)
.Sum(_hit => _hit.Value.Offset * _hit.Value.Count) / totalSessionHits;
AngleDifferenceAverage = weightedSessionAverage;
if (weightedSessionAverage > Thresholds.MaxOffset(totalSessionHits) &&
totalSessionHits > 40)
{

View File

@ -2,11 +2,13 @@
using SharedLibraryCore;
using SharedLibraryCore.Commands;
using SharedLibraryCore.Database.Models;
using SharedLibraryCore.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace Tests
@ -14,12 +16,12 @@ namespace Tests
[Collection("ManagerCollection")]
public class ClientTests
{
readonly ApplicationManager Manager;
private readonly ApplicationManager _manager;
const int TestTimeout = 10000;
public ClientTests(ManagerFixture fixture)
{
Manager = fixture.Manager;
_manager = fixture.Manager;
}
[Fact]
@ -41,38 +43,122 @@ namespace Tests
}
[Fact]
public void WarnClientShouldSucceed()
public void BanEvasionShouldLink()
{
while (!Manager.IsInitialized)
var server = _manager.Servers[0];
var waiter = new ManualResetEventSlim();
_manager.GetApplicationSettings().Configuration().RConPollRate = 5000;
while (!server.IsInitialized)
{
Thread.Sleep(100);
}
var client = Manager.Servers.First().GetClientsAsList().FirstOrDefault();
var e = new GameEvent()
{
Type = GameEvent.EventType.PreConnect,
Owner = server,
Origin = new EFClient()
{
NetworkId = 1337,
ClientNumber = 0,
CurrentAlias = new EFAlias()
{
Name = "Ban Me",
IPAddress = 1337
}
}
};
Assert.False(client == null, "no client found to warn");
_manager.GetEventHandler().AddEvent(e);
e.OnProcessed.Wait();
var warnEvent = client.Warn("test warn", new EFClient() { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer });
warnEvent.OnProcessed.Wait();
e = new GameEvent()
{
Type = GameEvent.EventType.PreConnect,
Owner = server,
Origin = new EFClient()
{
NetworkId = 1338,
ClientNumber = 1,
CurrentAlias = new EFAlias()
{
Name = "Ban Me",
IPAddress = null
}
}
};
//Assert.True((client.Warnings == 1 ||
// warnEvent.Failed) &&
// Manager.GetPenaltyService().GetClientPenaltiesAsync(client.ClientId).Result.Count(p => p.Type == Penalty.PenaltyType.Warning) == 1,
// "warning did not get applied");
_manager.GetEventHandler().AddEvent(e);
e.OnProcessed.Wait();
e = new GameEvent()
{
Type = GameEvent.EventType.Update,
Owner = server,
Origin = new EFClient()
{
NetworkId = 1338,
ClientNumber = 1,
CurrentAlias = new EFAlias()
{
Name = "Ban Me",
IPAddress = 1337
}
}
};
_manager.GetEventHandler().AddEvent(e);
e.OnProcessed.Wait();
}
[Fact]
public void WarnClientShouldSucceed()
{
var onJoined = new ManualResetEventSlim();
var server = _manager.Servers[0];
while (!server.IsInitialized)
{
Thread.Sleep(100);
}
_manager.OnServerEvent += (sender, eventArgs) =>
{
if (eventArgs.Event.Type == GameEvent.EventType.Connect)
{
onJoined.Set();
}
};
server.EmulateClientJoinLog();
onJoined.Wait();
var client = server.Clients[0];
var warnEvent = client.Warn("test warn", Utilities.IW4MAdminClient(server));
warnEvent.OnProcessed.Wait(5000);
Assert.False(warnEvent.Failed);
warnEvent = client.Warn("test warn", new EFClient() { ClientId = 1, Level = EFClient.Permission.Banned, CurrentServer = client.CurrentServer });
warnEvent.OnProcessed.Wait();
warnEvent.OnProcessed.Wait(5000);
Assert.True(warnEvent.FailReason == GameEvent.EventFailReason.Permission &&
client.Warnings == 1, "warning was applied without proper permissions");
// warn clear
var warnClearEvent = client.WarnClear(new EFClient { ClientId = 1, Level = EFClient.Permission.Banned, CurrentServer = client.CurrentServer });
warnClearEvent.OnProcessed.Wait(5000);
Assert.True(warnClearEvent.FailReason == GameEvent.EventFailReason.Permission &&
client.Warnings == 1, "warning was removed without proper permissions");
warnClearEvent = client.WarnClear(new EFClient { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer });
warnClearEvent = client.WarnClear(Utilities.IW4MAdminClient(server));
warnClearEvent.OnProcessed.Wait(5000);
Assert.True(!warnClearEvent.Failed && client.Warnings == 0, "warning was not cleared");
}
@ -80,12 +166,12 @@ namespace Tests
[Fact]
public void ReportClientShouldSucceed()
{
while (!Manager.IsInitialized)
while (!_manager.IsInitialized)
{
Thread.Sleep(100);
}
var client = Manager.Servers.First().GetClientsAsList().FirstOrDefault();
var client = _manager.Servers.First().GetClientsAsList().FirstOrDefault();
Assert.False(client == null, "no client found to report");
// fail
@ -127,12 +213,12 @@ namespace Tests
[Fact]
public void FlagClientShouldSucceed()
{
while (!Manager.IsInitialized)
while (!_manager.IsInitialized)
{
Thread.Sleep(100);
}
var client = Manager.Servers.First().GetClientsAsList().FirstOrDefault();
var client = _manager.Servers.First().GetClientsAsList().FirstOrDefault();
Assert.False(client == null, "no client found to flag");
var flagEvent = client.Flag("test flag", new EFClient { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer });
@ -177,12 +263,12 @@ namespace Tests
[Fact]
void KickClientShouldSucceed()
{
while (!Manager.IsInitialized)
while (!_manager.IsInitialized)
{
Thread.Sleep(100);
}
var client = Manager.Servers.First().GetClientsAsList().FirstOrDefault();
var client = _manager.Servers.First().GetClientsAsList().FirstOrDefault();
Assert.False(client == null, "no client found to kick");
var kickEvent = client.Kick("test kick", new EFClient() { ClientId = 1, Level = EFClient.Permission.Banned, CurrentServer = client.CurrentServer });
@ -193,18 +279,18 @@ namespace Tests
kickEvent = client.Kick("test kick", new EFClient() { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer });
kickEvent.OnProcessed.Wait();
Assert.True(Manager.Servers.First().GetClientsAsList().FirstOrDefault(c => c.NetworkId == client.NetworkId) == null, "client was not kicked");
Assert.True(_manager.Servers.First().GetClientsAsList().FirstOrDefault(c => c.NetworkId == client.NetworkId) == null, "client was not kicked");
}
[Fact]
void TempBanClientShouldSucceed()
{
while (!Manager.IsInitialized)
while (!_manager.IsInitialized)
{
Thread.Sleep(100);
}
var client = Manager.Servers.First().GetClientsAsList().FirstOrDefault();
var client = _manager.Servers.First().GetClientsAsList().FirstOrDefault();
Assert.False(client == null, "no client found to tempban");
var tbCommand = new CTempBan();
@ -217,19 +303,19 @@ namespace Tests
Owner = client.CurrentServer
}).Wait();
Assert.True(Manager.GetPenaltyService().GetActivePenaltiesAsync(client.AliasLinkId).Result.Count(p => p.Type == EFPenalty.PenaltyType.TempBan) == 1,
Assert.True(_manager.GetPenaltyService().GetActivePenaltiesAsync(client.AliasLinkId).Result.Count(p => p.Type == EFPenalty.PenaltyType.TempBan) == 1,
"tempban was not added");
}
[Fact]
void BanUnbanClientShouldSucceed()
{
while (!Manager.IsInitialized)
while (!_manager.IsInitialized)
{
Thread.Sleep(100);
}
var client = Manager.Servers.First().GetClientsAsList().FirstOrDefault();
var client = _manager.Servers.First().GetClientsAsList().FirstOrDefault();
Assert.False(client == null, "no client found to ban");
var banCommand = new CBan();
@ -242,7 +328,7 @@ namespace Tests
Owner = client.CurrentServer
}).Wait();
Assert.True(Manager.GetPenaltyService().GetActivePenaltiesAsync(client.AliasLinkId).Result.Count(p => p.Type == EFPenalty.PenaltyType.Ban) == 1,
Assert.True(_manager.GetPenaltyService().GetActivePenaltiesAsync(client.AliasLinkId).Result.Count(p => p.Type == EFPenalty.PenaltyType.Ban) == 1,
"ban was not added");
var unbanCommand = new CUnban();
@ -255,7 +341,7 @@ namespace Tests
Owner = client.CurrentServer
}).Wait();
Assert.True(Manager.GetPenaltyService().GetActivePenaltiesAsync(client.AliasLinkId).Result.Count(p => p.Type == EFPenalty.PenaltyType.Ban) == 0,
Assert.True(_manager.GetPenaltyService().GetActivePenaltiesAsync(client.AliasLinkId).Result.Count(p => p.Type == EFPenalty.PenaltyType.Ban) == 0,
"ban was not removed");
}

View File

@ -16,9 +16,9 @@ namespace Tests
public ManagerFixture()
{
File.WriteAllText("test_mp.log", "test_log_file");
string logFile = @"X:\IW4MAdmin\Plugins\Tests\bin\Debug\netcoreapp2.2\test_mp.log";
//IW4MAdmin.Application.Localization.Configure.Initialize("en-US");
File.WriteAllText(logFile, Environment.NewLine);
Manager = ApplicationManager.GetInstance();
@ -31,18 +31,22 @@ namespace Tests
AutoMessages = new List<string>(),
IPAddress = "127.0.0.1",
Password = "test",
Port = 28963,
Port = 28960,
Rules = new List<string>(),
ManualLogPath = "http://google.com"
RConParserVersion = "test",
EventParserVersion = "IW4x (v0.6.0)",
ManualLogPath = logFile
}
},
AutoMessages = new List<string>(),
GlobalRules = new List<string>(),
Maps = new List<MapConfiguration>(),
RConPollRate = 10000
RConPollRate = int.MaxValue
};
Manager.ConfigHandler = new BaseConfigurationHandler<ApplicationConfiguration>("test");
Manager.ConfigHandler.Set(config);
Manager.AdditionalRConParsers.Add(new TestRconParser());
Manager.Init().Wait();

View File

@ -1,7 +1,6 @@
using IW4MAdmin.Application;
using SharedLibraryCore;
using SharedLibraryCore.Database.Models;
using SharedLibraryCore.Interfaces;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@ -33,162 +32,17 @@ namespace Tests
[Fact]
public void AreCommandAliasesUnique()
{
var mgr = Program.ServerManager;
var mgr = Manager;
bool test = mgr.GetCommands().Count == mgr.GetCommands().Select(c => c.Alias).Distinct().Count();
foreach (var duplicate in mgr.GetCommands().GroupBy(_cmd => _cmd.Alias).Where(_grp => _grp.Count() > 1).Select(_grp => new { Command = _grp.First().Name, Alias = _grp.Key }))
{
Debug.WriteLine($"{duplicate.Command}: {duplicate.Alias}");
}
Assert.True(test, "command aliases are not unique");
}
[Fact]
public void AddAndRemoveClientsViaJoinShouldSucceed()
{
var server = Manager.GetServers().First();
var waiters = new Queue<GameEvent>();
int clientStartIndex = 4;
int clientNum = 10;
for (int i = clientStartIndex; i < clientStartIndex + clientNum; i++)
{
var e = new GameEvent()
{
Type = GameEvent.EventType.Join,
Origin = new EFClient()
{
Name = $"Player{i}",
NetworkId = i,
ClientNumber = i - 1
},
Owner = server
};
server.Manager.GetEventHandler().AddEvent(e);
waiters.Enqueue(e);
}
while (waiters.Count > 0)
{
waiters.Dequeue().OnProcessed.Wait();
}
Assert.True(server.ClientNum == clientNum, $"client num does not match added client num [{server.ClientNum}:{clientNum}]");
for (int i = clientStartIndex; i < clientStartIndex + clientNum; i++)
{
var e = new GameEvent()
{
Type = GameEvent.EventType.Disconnect,
Origin = new EFClient()
{
Name = $"Player{i}",
NetworkId = i,
ClientNumber = i - 1
},
Owner = server
};
server.Manager.GetEventHandler().AddEvent(e);
waiters.Enqueue(e);
}
while (waiters.Count > 0)
{
waiters.Dequeue().OnProcessed.Wait();
}
Assert.True(server.ClientNum == 0, "there are still clients connected");
}
[Fact]
public void AddAndRemoveClientsViaRconShouldSucceed()
{
var server = Manager.GetServers().First();
var waiters = new Queue<GameEvent>();
int clientIndexStart = 1;
int clientNum = 8;
for (int i = clientIndexStart; i < clientNum + clientIndexStart; i++)
{
var e = new GameEvent()
{
Type = GameEvent.EventType.Connect,
Origin = new EFClient()
{
Name = $"Player{i}",
NetworkId = i,
ClientNumber = i - 1,
IPAddress = i,
Ping = 50,
CurrentServer = server
},
Owner = server,
};
Manager.GetEventHandler().AddEvent(e);
waiters.Enqueue(e);
}
while (waiters.Count > 0)
{
waiters.Dequeue().OnProcessed.Wait();
}
int actualClientNum = server.GetClientsAsList().Count(p => p.State == EFClient.ClientState.Connected);
Assert.True(actualClientNum == clientNum, $"client connected states don't match [{actualClientNum}:{clientNum}");
for (int i = clientIndexStart; i < clientNum + clientIndexStart; i++)
{
var e = new GameEvent()
{
Type = GameEvent.EventType.Disconnect,
Origin = new EFClient()
{
Name = $"Player{i}",
NetworkId = i,
ClientNumber = i - 1,
IPAddress = i,
Ping = 50,
CurrentServer = server
},
Owner = server,
};
Manager.GetEventHandler().AddEvent(e);
waiters.Enqueue(e);
}
while (waiters.Count > 0)
{
waiters.Dequeue().OnProcessed.Wait();
}
actualClientNum = server.ClientNum;
Assert.True(actualClientNum == 0, "there are clients still connected");
}
[Fact]
public void AddClientViaLog()
{
var resetEvent = new ManualResetEventSlim();
resetEvent.Reset();
Manager.OnServerEvent += (sender, eventArgs) =>
{
if (eventArgs.Event.Type == GameEvent.EventType.Join)
{
eventArgs.Event.OnProcessed.Wait();
Assert.True(false);
}
};
File.AppendAllText("test_mp.log", " 2:33 J;224b3d0bc64ab4f9;0;goober");
resetEvent.Wait(5000);
}
[Fact]
public void PrintCommands()
{

View File

@ -1,10 +1,113 @@
using System;
using IW4MAdmin.Application;
using SharedLibraryCore;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using Xunit;
namespace Tests
{
class ServerTests
[Collection("ManagerCollection")]
public class ServerTests
{
private readonly ApplicationManager _manager;
public ServerTests(ManagerFixture fixture)
{
_manager = fixture.Manager;
}
[Fact]
public void AddAndRemoveClientViaLog()
{
var resetEvent = new ManualResetEventSlim();
var server = _manager.Servers[0];
var currentClientCount = server.ClientNum;
int eventsProcessed = 0;
_manager.OnServerEvent += (sender, eventArgs) =>
{
if (eventArgs.Event.Type == GameEvent.EventType.Connect)
{
eventArgs.Event.OnProcessed.Wait();
Assert.False(eventArgs.Event.Failed, "connect event was not processed");
Assert.True(server.ClientNum == currentClientCount + 1, "client count was not incremented");
eventsProcessed++;
resetEvent.Set();
}
if (eventArgs.Event.Type == GameEvent.EventType.Disconnect)
{
eventArgs.Event.OnProcessed.Wait();
Assert.False(eventArgs.Event.Failed, "disconnect event was not processed");
Assert.True(server.ClientNum == currentClientCount, "client count was not decremented");
eventsProcessed++;
resetEvent.Set();
}
};
server.EmulateClientJoinLog();
resetEvent.Wait(15000);
resetEvent.Reset();
Assert.Equal(1, eventsProcessed);
server.EmulateClientQuitLog();
resetEvent.Wait(15000);
Assert.Equal(2, eventsProcessed);
}
[Fact]
public void AddAndRemoveClientViaRcon()
{
var resetEvent = new ManualResetEventSlim();
var server = _manager.Servers[0];
var currentClientCount = server.ClientNum;
int eventsProcessed = 0;
_manager.GetApplicationSettings().Configuration().RConPollRate = 5000;
_manager.OnServerEvent += (sender, eventArgs) =>
{
if (eventArgs.Event.Type == GameEvent.EventType.Connect)
{
eventArgs.Event.OnProcessed.Wait();
Assert.False(eventArgs.Event.Failed, "connect event was not processed");
Assert.True(server.ClientNum == currentClientCount + 1, "client count was not incremented");
eventsProcessed++;
resetEvent.Set();
}
if (eventArgs.Event.Type == GameEvent.EventType.Disconnect)
{
eventArgs.Event.OnProcessed.Wait();
Assert.False(eventArgs.Event.Failed, "disconnect event was not processed");
Assert.True(server.ClientNum == currentClientCount, "client count was not decremented");
eventsProcessed++;
resetEvent.Set();
}
};
(server.RconParser as TestRconParser).FakeClientCount = 1;
resetEvent.Wait(15000);
resetEvent.Reset();
Assert.Equal(1, eventsProcessed);
(server.RconParser as TestRconParser).FakeClientCount = 0;
resetEvent.Wait(15000);
Assert.Equal(2, eventsProcessed);
_manager.GetApplicationSettings().Configuration().RConPollRate = int.MaxValue;
}
}
}

View File

@ -0,0 +1,24 @@
using IW4MAdmin.Application;
using SharedLibraryCore;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Tests
{
internal static class TestHelpers
{
internal static void EmulateClientJoinLog(this Server svr)
{
long guid = svr.ClientNum + 1;
File.AppendAllText(svr.LogPath, $"0:00 J;{guid};{svr.ClientNum};test_client_{svr.ClientNum}\r\n");
}
internal static void EmulateClientQuitLog(this Server svr)
{
long guid = Math.Max(1, svr.ClientNum);
File.AppendAllText(svr.LogPath, $"0:00 Q;{guid};{svr.ClientNum};test_client_{svr.ClientNum}\r\n");
}
}
}

View File

@ -0,0 +1,38 @@
using SharedLibraryCore.Database.Models;
using SharedLibraryCore.RCon;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace Tests
{
class TestRconParser : IW4MAdmin.Application.RconParsers.BaseRConParser
{
public int FakeClientCount { get; set; }
public List<EFClient> FakeClients { get; set; } = new List<EFClient>();
public override string Version => "test";
public override async Task<List<EFClient>> GetStatusAsync(Connection connection)
{
var clientList = new List<EFClient>();
for (int i = 0; i < FakeClientCount; i++)
{
clientList.Add(new EFClient()
{
ClientNumber = i,
NetworkId = i + 1,
CurrentAlias = new EFAlias()
{
Name = $"test_bot_{i}",
IPAddress = i + 1
}
});
}
return clientList.Count > 0 ? clientList : FakeClients;
}
}
}

View File

@ -31,7 +31,7 @@ namespace SharedLibraryCore.Commands
public class CRestart : Command
{
public CRestart() :
base("restart", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_RESTART_DESC"], "rs", EFClient.Permission.Owner, false)
base("restart", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_RESTART_DESC"], "res", EFClient.Permission.Owner, false)
{ }
public override Task ExecuteAsync(GameEvent E)

View File

@ -205,12 +205,7 @@ namespace SharedLibraryCore.Database.Models
int reportCount = sender.GetAdditionalProperty<int>("_reportCount");
if (Level > sender.Level)
{
e.FailReason = GameEvent.EventFailReason.Permission;
}
else if (Equals(sender))
if (Equals(sender))
{
e.FailReason = GameEvent.EventFailReason.Invalid;
}

View File

@ -110,14 +110,6 @@ namespace SharedLibraryCore.Services
#endif
var aliases = await iqAliases.ToListAsync();
// update each of the aliases where this is no IP but the name is identical
foreach (var alias in aliases.Where(_alias => (_alias.IPAddress == null || _alias.IPAddress == 0)))
{
alias.IPAddress = ip;
}
await context.SaveChangesAsync();
// see if they have a matching IP + Name but new NetworkId
var existingExactAlias = aliases.FirstOrDefault(a => a.Name == name && a.IPAddress == ip);
bool hasExactAliasMatch = existingExactAlias != null;
@ -125,13 +117,21 @@ namespace SharedLibraryCore.Services
// if existing alias matches link them
var newAliasLink = existingExactAlias?.Link;
// if no exact matches find the first IP or LinkId that matches
newAliasLink = newAliasLink ?? aliases.FirstOrDefault()?.Link;
newAliasLink = newAliasLink ?? aliases.OrderBy(_alias => _alias.LinkId).FirstOrDefault()?.Link;
// if no matches are found, use our current one ( it will become permanent )
newAliasLink = newAliasLink ?? entity.AliasLink;
bool hasExistingAlias = aliases.Count > 0;
bool isAliasLinkUpdated = newAliasLink.AliasLinkId != entity.AliasLink.AliasLinkId;
// update each of the aliases where this is no IP but the name is identical
foreach (var alias in aliases.Where(_alias => (_alias.IPAddress == null || _alias.IPAddress == 0)))
{
alias.IPAddress = ip;
}
await context.SaveChangesAsync();
// this happens when the link we found is different than the one we create before adding an IP
if (isAliasLinkUpdated)
{