allow reports to be filed against anyone
fix rare issue with alias (maybe) update some tests
This commit is contained in:
parent
cb80def122
commit
253c7c8721
@ -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>
|
||||
|
@ -30,7 +30,9 @@ namespace IW4MAdmin.Application.IO
|
||||
{
|
||||
while (!_server.Manager.CancellationToken.IsCancellationRequested)
|
||||
{
|
||||
#if !DEBUG
|
||||
if (_server.IsInitialized)
|
||||
#endif
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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");
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
24
Plugins/Tests/TestHelpers.cs
Normal file
24
Plugins/Tests/TestHelpers.cs
Normal 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");
|
||||
}
|
||||
}
|
||||
}
|
38
Plugins/Tests/TestRconParser.cs
Normal file
38
Plugins/Tests/TestRconParser.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user