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

think I finished reworking the event system

added http log reading support for debugging remotely
started working on unit test framework
This commit is contained in:
RaidMax
2018-08-28 16:32:59 -05:00
parent 10c8b5b6c6
commit b6f37035a1
23 changed files with 543 additions and 296 deletions

View File

@ -0,0 +1,61 @@
using IW4MAdmin.Application;
using SharedLibraryCore.Configuration;
using SharedLibraryCore.Interfaces;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace Tests
{
public class ManagerFixture : IDisposable
{
public ApplicationManager Manager { get; private set; }
public ManagerFixture()
{
File.WriteAllText("test_mp.log", "TEST_LOG_FILE");
Manager = Program.ServerManager;
var config = new ApplicationConfiguration
{
Servers = new List<ServerConfiguration>()
{
new ServerConfiguration()
{
AutoMessages = new List<string>(),
IPAddress = "127.0.0.1",
Password = "test",
Port = 28963,
Rules = new List<string>(),
ManualLogPath = "https://raidmax.org/IW4MAdmin/getlog.php"
}
},
AutoMessages = new List<string>(),
GlobalRules = new List<string>(),
Maps = new List<MapConfiguration>(),
RConPollRate = 10000
};
Manager.ConfigHandler = new BaseConfigurationHandler<ApplicationConfiguration>("Test.json");
Manager.ConfigHandler.Set(config);
Manager.Init().Wait();
Task.Run(() => Manager.Start());
}
public void Dispose()
{
Manager.Stop();
}
}
[CollectionDefinition("ManagerCollection")]
public class ManagerCollection : ICollectionFixture<ManagerFixture>
{
}
}

View File

@ -0,0 +1,194 @@
using IW4MAdmin.Application;
using SharedLibraryCore;
using SharedLibraryCore.Interfaces;
using SharedLibraryCore.Objects;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using Xunit;
namespace Tests
{
[Collection("ManagerCollection")]
public class ManagerTests
{
readonly ApplicationManager Manager;
public ManagerTests(ManagerFixture fixture)
{
Manager = fixture.Manager;
}
[Fact]
public void AreCommandNamesUnique()
{
bool test = Manager.GetCommands().Count == Manager.GetCommands().Select(c => c.Name).Distinct().Count();
Assert.True(test, "command names are not unique");
}
[Fact]
public void AreCommandAliasesUnique()
{
var mgr = IW4MAdmin.Application.Program.ServerManager;
bool test = mgr.GetCommands().Count == mgr.GetCommands().Select(c => c.Alias).Distinct().Count();
Assert.True(test, "command aliases are not unique");
}
[Fact]
public void AddAndRemoveClientsViaJoinShouldSucceed()
{
var server = Manager.GetServers().First();
var waiters = new Queue<ManualResetEventSlim>();
int clientStartIndex = 4;
int clientNum = 10;
for (int i = clientStartIndex; i < clientStartIndex + clientNum; i++)
{
var e = new GameEvent()
{
Type = GameEvent.EventType.Join,
Origin = new Player()
{
Name = $"Player{i}",
NetworkId = i,
ClientNumber = i - 1
},
Owner = server
};
server.Manager.GetEventHandler().AddEvent(e);
waiters.Enqueue(e.OnProcessed);
}
while (waiters.Count > 0)
{
waiters.Dequeue().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 Player()
{
Name = $"Player{i}",
NetworkId = i,
ClientNumber = i - 1
},
Owner = server
};
server.Manager.GetEventHandler().AddEvent(e);
waiters.Enqueue(e.OnProcessed);
}
while (waiters.Count > 0)
{
waiters.Dequeue().Wait();
}
Assert.True(server.ClientNum == 0, "there are still clients connected");
}
[Fact]
public void AddAndRemoveClientsViaRconShouldSucceed()
{
var server = Manager.GetServers().First();
var waiters = new Queue<ManualResetEventSlim>();
int clientIndexStart = 1;
int clientNum = 8;
for (int i = clientIndexStart; i < clientNum + clientIndexStart; i++)
{
var e = new GameEvent()
{
Type = GameEvent.EventType.Connect,
Origin = new Player()
{
Name = $"Player{i}",
NetworkId = i,
ClientNumber = i - 1,
IPAddress = i,
Ping = 50,
CurrentServer = server
},
Owner = server,
};
Manager.GetEventHandler().AddEvent(e);
waiters.Enqueue(e.OnProcessed);
}
while (waiters.Count > 0)
{
waiters.Dequeue().Wait();
}
int actualClientNum = server.GetPlayersAsList().Count(p => p.State == Player.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 Player()
{
Name = $"Player{i}",
NetworkId = i,
ClientNumber = i - 1,
IPAddress = i,
Ping = 50,
CurrentServer = server
},
Owner = server,
};
Manager.GetEventHandler().AddEvent(e);
waiters.Enqueue(e.OnProcessed);
}
while (waiters.Count > 0)
{
waiters.Dequeue().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);
}
}
}

View File

@ -1,192 +0,0 @@
#if DEBUG
using System;
using System.Linq;
using System.Threading.Tasks;
using SharedLibraryCore;
using SharedLibraryCore.Interfaces;
using SharedLibraryCore.Helpers;
using SharedLibraryCore.Objects;
namespace IW4MAdmin.Plugins
{
public class Tests : IPlugin
{
public string Name => "Dev Tests";
public float Version => 0.1f;
public string Author => "RaidMax";
public async Task OnEventAsync(GameEvent E, Server S)
{
return;
if (E.Type == GameEvent.EventType.Start)
{
#region UNIT_TEST_LOG_CONNECT
for (int i = 1; i <= 8; i++)
{
var e = new GameEvent()
{
Type = GameEvent.EventType.Join,
Origin = new Player()
{
Name = $"Player{i}",
NetworkId = i,
ClientNumber = i - 1
},
Owner = S
};
S.Manager.GetEventHandler().AddEvent(e);
e.OnProcessed.Wait();
}
S.Logger.WriteAssert(S.ClientNum == 8, "UNIT_TEST_LOG_CONNECT failed client num check");
#endregion
#region UNIT_TEST_RCON_AUTHENTICATE
for (int i = 1; i <= 8; i++)
{
var e = new GameEvent()
{
Type = GameEvent.EventType.Connect,
Origin = new Player()
{
Name = $"Player{i}",
NetworkId = i,
ClientNumber = i - 1,
IPAddress = i,
Ping = 50,
CurrentServer = S
},
Owner = S,
};
S.Manager.GetEventHandler().AddEvent(e);
e.OnProcessed.Wait();
}
S.Logger.WriteAssert(S.GetPlayersAsList().Count(p => p.State == Player.ClientState.Connected) == 8,
"UNIT_TEST_RCON_AUTHENTICATE failed client num connected state check");
#endregion
}
//if (E.Type == GameEvent.EventType.Start)
//{
// #region PLAYER_HISTORY
// var rand = new Random(GetHashCode());
// var time = DateTime.UtcNow;
// await Task.Run(() =>
// {
// if (S.PlayerHistory.Count > 0)
// return;
// while (S.PlayerHistory.Count < 144)
// {
// S.PlayerHistory.Enqueue(new PlayerHistory(time, rand.Next(7, 18)));
// time = time.AddMinutes(PlayerHistory.UpdateInterval);
// }
// });
// #endregion
// #region PLUGIN_INFO
// Console.WriteLine("|Name |Alias|Description |Requires Target|Syntax |Required Level|");
// Console.WriteLine("|--------------| -----| --------------------------------------------------------| -----------------| -------------| ----------------|");
// foreach (var command in S.Manager.GetCommands().OrderByDescending(c => c.Permission).ThenBy(c => c.Name))
// {
// Console.WriteLine($"|{command.Name}|{command.Alias}|{command.Description}|{command.RequiresTarget}|{command.Syntax.Substring(8).EscapeMarkdown()}|{command.Permission}|");
// }
// #endregion
//}
}
public Task OnLoadAsync(IManager manager) => Task.CompletedTask;
public Task OnTickAsync(Server S)
{
return Task.CompletedTask;
/*
if ((DateTime.Now - Interval).TotalSeconds > 1)
{
var rand = new Random();
int index = rand.Next(0, 17);
var p = new Player()
{
Name = $"Test_{index}",
NetworkId = (long)$"_test_{index}".GetHashCode(),
ClientNumber = index,
Ping = 1,
IPAddress = $"127.0.0.{index}".ConvertToIP()
};
if (S.Players.ElementAt(index) != null)
await S.RemovePlayer(index);
// await S.AddPlayer(p);
Interval = DateTime.Now;
if (S.ClientNum > 0)
{
var victimPlayer = S.Players.Where(pl => pl != null).ToList()[rand.Next(0, S.ClientNum - 1)];
var attackerPlayer = S.Players.Where(pl => pl != null).ToList()[rand.Next(0, S.ClientNum - 1)];
await S.ExecuteEvent(new Event(Event.GType.Say, $"test_{attackerPlayer.ClientNumber}", victimPlayer, attackerPlayer, S));
string[] eventLine = null;
for (int i = 0; i < 1; i++)
{
if (S.GameName == Server.Game.IW4)
{
// attackerID ; victimID ; attackerOrigin ; victimOrigin ; Damage ; Weapon ; hitLocation ; meansOfDeath
var minimapInfo = StatsPlugin.MinimapConfig.IW4Minimaps().MapInfo.FirstOrDefault(m => m.MapName == S.CurrentMap.Name);
if (minimapInfo == null)
return;
eventLine = new string[]
{
"ScriptKill",
attackerPlayer.NetworkId.ToString(),
victimPlayer.NetworkId.ToString(),
new Vector3(rand.Next(minimapInfo.MaxRight, minimapInfo.MaxLeft), rand.Next(minimapInfo.MaxBottom, minimapInfo.MaxTop), rand.Next(0, 100)).ToString(),
new Vector3(rand.Next(minimapInfo.MaxRight, minimapInfo.MaxLeft), rand.Next(minimapInfo.MaxBottom, minimapInfo.MaxTop), rand.Next(0, 100)).ToString(),
rand.Next(50, 105).ToString(),
((StatsPlugin.IW4Info.WeaponName)rand.Next(0, Enum.GetValues(typeof(StatsPlugin.IW4Info.WeaponName)).Length - 1)).ToString(),
((StatsPlugin.IW4Info.HitLocation)rand.Next(0, Enum.GetValues(typeof(StatsPlugin.IW4Info.HitLocation)).Length - 1)).ToString(),
((StatsPlugin.IW4Info.MeansOfDeath)rand.Next(0, Enum.GetValues(typeof(StatsPlugin.IW4Info.MeansOfDeath)).Length - 1)).ToString()
};
}
else
{
eventLine = new string[]
{
"K",
victimPlayer.NetworkId.ToString(),
victimPlayer.ClientNumber.ToString(),
rand.Next(0, 1) == 0 ? "allies" : "axis",
victimPlayer.Name,
attackerPlayer.NetworkId.ToString(),
attackerPlayer.ClientNumber.ToString(),
rand.Next(0, 1) == 0 ? "allies" : "axis",
attackerPlayer.Name.ToString(),
((StatsPlugin.IW4Info.WeaponName)rand.Next(0, Enum.GetValues(typeof(StatsPlugin.IW4Info.WeaponName)).Length - 1)).ToString(), // Weapon
rand.Next(50, 105).ToString(), // Damage
((StatsPlugin.IW4Info.MeansOfDeath)rand.Next(0, Enum.GetValues(typeof(StatsPlugin.IW4Info.MeansOfDeath)).Length - 1)).ToString(), // Means of Death
((StatsPlugin.IW4Info.HitLocation)rand.Next(0, Enum.GetValues(typeof(StatsPlugin.IW4Info.HitLocation)).Length - 1)).ToString(), // Hit Location
};
}
var _event = Event.ParseEventString(eventLine, S);
await S.ExecuteEvent(_event);
}
}
}
*/
}
public Task OnUnloadAsync() => Task.CompletedTask;
}
}
#endif

View File

@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Tests
{
class ServerTests
{
}
}

View File

@ -11,16 +11,18 @@
<DefineConstants>TRACE;DEBUG;NETCOREAPP2_0</DefineConstants>
</PropertyGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="copy &quot;$(TargetPath)&quot; &quot;$(SolutionDir)BUILD\Plugins&quot;" />
</Target>
<ItemGroup>
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Application\Application.csproj" />
<ProjectReference Include="..\..\SharedLibraryCore\SharedLibraryCore.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="Microsoft.NETCore.App"/>
<PackageReference Update="Microsoft.NETCore.App" />
</ItemGroup>
</Project>