actually fix the session score concurrency issue
fix rare bug with shared guid kicker plugin allow hiding of the connection lost notification
This commit is contained in:
parent
9e74dac5ed
commit
92a26600af
@ -236,10 +236,13 @@ namespace IW4MAdmin
|
|||||||
if (E.Type == GameEvent.EventType.ConnectionLost)
|
if (E.Type == GameEvent.EventType.ConnectionLost)
|
||||||
{
|
{
|
||||||
var exception = E.Extra as Exception;
|
var exception = E.Extra as Exception;
|
||||||
Logger.WriteError(exception.Message);
|
if (!Manager.GetApplicationSettings().Configuration().IgnoreServerConnectionLost)
|
||||||
if (exception.Data["internal_exception"] != null)
|
|
||||||
{
|
{
|
||||||
Logger.WriteDebug($"Internal Exception: {exception.Data["internal_exception"]}");
|
Logger.WriteError(exception.Message);
|
||||||
|
if (exception.Data["internal_exception"] != null)
|
||||||
|
{
|
||||||
|
Logger.WriteDebug($"Internal Exception: {exception.Data["internal_exception"]}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Logger.WriteInfo("Connection lost to server, so we are throttling the poll rate");
|
Logger.WriteInfo("Connection lost to server, so we are throttling the poll rate");
|
||||||
Throttled = true;
|
Throttled = true;
|
||||||
@ -730,6 +733,7 @@ namespace IW4MAdmin
|
|||||||
|
|
||||||
override public async Task<bool> ProcessUpdatesAsync(CancellationToken cts)
|
override public async Task<bool> ProcessUpdatesAsync(CancellationToken cts)
|
||||||
{
|
{
|
||||||
|
bool notifyDisconnects = !Manager.GetApplicationSettings().Configuration().IgnoreServerConnectionLost;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (cts.IsCancellationRequested)
|
if (cts.IsCancellationRequested)
|
||||||
@ -796,7 +800,7 @@ namespace IW4MAdmin
|
|||||||
Manager.GetEventHandler().AddEvent(e);
|
Manager.GetEventHandler().AddEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ConnectionErrors > 0)
|
if (ConnectionErrors > 0 && notifyDisconnects)
|
||||||
{
|
{
|
||||||
var _event = new GameEvent()
|
var _event = new GameEvent()
|
||||||
{
|
{
|
||||||
@ -816,7 +820,7 @@ namespace IW4MAdmin
|
|||||||
catch (NetworkException e)
|
catch (NetworkException e)
|
||||||
{
|
{
|
||||||
ConnectionErrors++;
|
ConnectionErrors++;
|
||||||
if (ConnectionErrors == 3)
|
if (ConnectionErrors == 3 && notifyDisconnects)
|
||||||
{
|
{
|
||||||
var _event = new GameEvent()
|
var _event = new GameEvent()
|
||||||
{
|
{
|
||||||
|
@ -35,12 +35,12 @@ namespace IW4MAdmin.Application.Misc
|
|||||||
private readonly SemaphoreSlim _onProcessing;
|
private readonly SemaphoreSlim _onProcessing;
|
||||||
private bool successfullyLoaded;
|
private bool successfullyLoaded;
|
||||||
|
|
||||||
public ScriptPlugin(string filename)
|
public ScriptPlugin(string filename, string workingDirectory = null)
|
||||||
{
|
{
|
||||||
_fileName = filename;
|
_fileName = filename;
|
||||||
Watcher = new FileSystemWatcher()
|
Watcher = new FileSystemWatcher()
|
||||||
{
|
{
|
||||||
Path = $"{Utilities.OperatingDirectory}Plugins{Path.DirectorySeparatorChar}",
|
Path = workingDirectory == null ? $"{Utilities.OperatingDirectory}Plugins{Path.DirectorySeparatorChar}" : workingDirectory,
|
||||||
NotifyFilter = NotifyFilters.Size,
|
NotifyFilter = NotifyFilters.Size,
|
||||||
Filter = _fileName.Split(Path.DirectorySeparatorChar).Last()
|
Filter = _fileName.Split(Path.DirectorySeparatorChar).Last()
|
||||||
};
|
};
|
||||||
|
@ -82,36 +82,24 @@ namespace IW4MAdmin.Plugins.Stats.Models
|
|||||||
KillStreak = 0;
|
KillStreak = 0;
|
||||||
DeathStreak = 0;
|
DeathStreak = 0;
|
||||||
LastScore = 0;
|
LastScore = 0;
|
||||||
lock (SessionScores)
|
SessionScores.Add(0);
|
||||||
{
|
|
||||||
SessionScores.Add(0);
|
|
||||||
}
|
|
||||||
Team = IW4Info.Team.None;
|
Team = IW4Info.Team.None;
|
||||||
}
|
}
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public int SessionScore
|
public int SessionScore
|
||||||
{
|
{
|
||||||
set
|
set => SessionScores[SessionScores.Count - 1] = value;
|
||||||
{
|
|
||||||
SessionScores[SessionScores.Count - 1] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
lock (SessionScores)
|
lock (SessionScores)
|
||||||
{
|
{
|
||||||
return SessionScores.Sum();
|
return new List<int>(SessionScores).Sum();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public int RoundScore
|
public int RoundScore => SessionScores[SessionScores.Count - 1];
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return SessionScores[SessionScores.Count - 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
private readonly List<int> SessionScores = new List<int>() { 0 };
|
private readonly List<int> SessionScores = new List<int>() { 0 };
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
|
@ -96,6 +96,8 @@ namespace SharedLibraryCore.Configuration
|
|||||||
public QuickMessageConfiguration[] QuickMessages { get; set; }
|
public QuickMessageConfiguration[] QuickMessages { get; set; }
|
||||||
[ConfigurationIgnore]
|
[ConfigurationIgnore]
|
||||||
public string WebfrontUrl => string.IsNullOrEmpty(ManualWebfrontUrl) ? WebfrontBindUrl?.Replace("0.0.0.0", "127.0.0.1") : ManualWebfrontUrl;
|
public string WebfrontUrl => string.IsNullOrEmpty(ManualWebfrontUrl) ? WebfrontBindUrl?.Replace("0.0.0.0", "127.0.0.1") : ManualWebfrontUrl;
|
||||||
|
[ConfigurationIgnore]
|
||||||
|
public bool IgnoreServerConnectionLost { get; set; }
|
||||||
|
|
||||||
public IBaseConfiguration Generate()
|
public IBaseConfiguration Generate()
|
||||||
{
|
{
|
||||||
|
@ -285,7 +285,7 @@ namespace SharedLibraryCore
|
|||||||
public List<Report> Reports { get; set; }
|
public List<Report> Reports { get; set; }
|
||||||
public List<ChatInfo> ChatHistory { get; protected set; }
|
public List<ChatInfo> ChatHistory { get; protected set; }
|
||||||
public Queue<PlayerHistory> ClientHistory { get; private set; }
|
public Queue<PlayerHistory> ClientHistory { get; private set; }
|
||||||
public Game GameName { get; protected set; }
|
public Game GameName { get; set; }
|
||||||
|
|
||||||
// Info
|
// Info
|
||||||
public string Hostname { get; protected set; }
|
public string Hostname { get; protected set; }
|
||||||
|
@ -374,6 +374,7 @@ namespace SharedLibraryCore.Services
|
|||||||
EF.CompileAsyncQuery((DatabaseContext context, long networkId) =>
|
EF.CompileAsyncQuery((DatabaseContext context, long networkId) =>
|
||||||
context.Clients
|
context.Clients
|
||||||
.Include(c => c.CurrentAlias)
|
.Include(c => c.CurrentAlias)
|
||||||
|
.Include(c => c.AliasLink)
|
||||||
.Select(_client => new EFClient()
|
.Select(_client => new EFClient()
|
||||||
{
|
{
|
||||||
ClientId = _client.ClientId,
|
ClientId = _client.ClientId,
|
||||||
@ -389,7 +390,7 @@ namespace SharedLibraryCore.Services
|
|||||||
.FirstOrDefault(c => c.NetworkId == networkId)
|
.FirstOrDefault(c => c.NetworkId == networkId)
|
||||||
);
|
);
|
||||||
|
|
||||||
public async Task<EFClient> GetUnique(long entityAttribute)
|
public virtual async Task<EFClient> GetUnique(long entityAttribute)
|
||||||
{
|
{
|
||||||
using (var context = new DatabaseContext(true))
|
using (var context = new DatabaseContext(true))
|
||||||
{
|
{
|
||||||
|
37
Tests/ApplicationTests/DepedencyInjectionExtensions.cs
Normal file
37
Tests/ApplicationTests/DepedencyInjectionExtensions.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using ApplicationTests.Fixtures;
|
||||||
|
using FakeItEasy;
|
||||||
|
using IW4MAdmin;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using SharedLibraryCore.Interfaces;
|
||||||
|
using SharedLibraryCore.Services;
|
||||||
|
|
||||||
|
namespace ApplicationTests
|
||||||
|
{
|
||||||
|
static class DepedencyInjectionExtensions
|
||||||
|
{
|
||||||
|
public static IServiceCollection BuildBase(this IServiceCollection serviceCollection)
|
||||||
|
{
|
||||||
|
var manager = A.Fake<IManager>();
|
||||||
|
var logger = A.Fake<ILogger>();
|
||||||
|
A.CallTo(() => manager.GetLogger(A<long>.Ignored))
|
||||||
|
.Returns(logger);
|
||||||
|
|
||||||
|
serviceCollection.AddSingleton(logger)
|
||||||
|
.AddSingleton(manager)
|
||||||
|
.AddSingleton(A.Fake<IRConConnectionFactory>())
|
||||||
|
.AddSingleton(A.Fake<IRConConnection>())
|
||||||
|
.AddSingleton(A.Fake<ITranslationLookup>())
|
||||||
|
.AddSingleton(A.Fake<IRConParser>())
|
||||||
|
.AddSingleton(A.Fake<IParserRegexFactory>())
|
||||||
|
.AddSingleton(A.Fake<ClientService>());
|
||||||
|
|
||||||
|
serviceCollection.AddSingleton(_sp => new IW4MServer(_sp.GetRequiredService<IManager>(), ConfigurationGenerators.CreateServerConfiguration(),
|
||||||
|
_sp.GetRequiredService<ITranslationLookup>(), _sp.GetRequiredService<IRConConnectionFactory>())
|
||||||
|
{
|
||||||
|
RconParser = _sp.GetRequiredService<IRConParser>()
|
||||||
|
});
|
||||||
|
|
||||||
|
return serviceCollection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,17 +8,35 @@ namespace ApplicationTests.Fixtures
|
|||||||
{
|
{
|
||||||
public class ClientGenerators
|
public class ClientGenerators
|
||||||
{
|
{
|
||||||
public static EFClient CreateBasicClient(Server currentServer, bool isIngame = true) => new EFClient()
|
public static EFClient CreateBasicClient(Server currentServer, bool isIngame = true, bool hasIp = true, EFClient.ClientState clientState = EFClient.ClientState.Connected) => new EFClient()
|
||||||
{
|
{
|
||||||
ClientId = 1,
|
ClientId = 1,
|
||||||
CurrentAlias = new EFAlias()
|
CurrentAlias = new EFAlias()
|
||||||
{
|
{
|
||||||
Name = "BasicClient",
|
Name = "BasicClient",
|
||||||
IPAddress = "127.0.0.1".ConvertToIP(),
|
IPAddress = hasIp ? "127.0.0.1".ConvertToIP() : null,
|
||||||
},
|
},
|
||||||
Level = EFClient.Permission.User,
|
Level = EFClient.Permission.User,
|
||||||
ClientNumber = isIngame ? 0 : -1,
|
ClientNumber = isIngame ? 0 : -1,
|
||||||
CurrentServer = currentServer
|
CurrentServer = currentServer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static EFClient CreateDatabaseClient(bool hasIp = true) => new EFClient()
|
||||||
|
{
|
||||||
|
ClientId = 1,
|
||||||
|
ClientNumber = -1,
|
||||||
|
AliasLinkId = 1,
|
||||||
|
Level = EFClient.Permission.User,
|
||||||
|
Connections = 1,
|
||||||
|
FirstConnection = DateTime.UtcNow.AddDays(-1),
|
||||||
|
LastConnection = DateTime.UtcNow,
|
||||||
|
NetworkId = 1,
|
||||||
|
TotalConnectionTime = 100,
|
||||||
|
CurrentAlias = new EFAlias()
|
||||||
|
{
|
||||||
|
Name = "BasicDatabaseClient",
|
||||||
|
IPAddress = hasIp ? "127.0.0.1".ConvertToIP() : null,
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,9 @@ using SharedLibraryCore.Database.Models;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using ApplicationTests.Mocks;
|
using ApplicationTests.Mocks;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using SharedLibraryCore;
|
||||||
|
using SharedLibraryCore.Exceptions;
|
||||||
|
using SharedLibraryCore.Configuration;
|
||||||
|
|
||||||
namespace ApplicationTests
|
namespace ApplicationTests
|
||||||
{
|
{
|
||||||
@ -27,29 +30,28 @@ namespace ApplicationTests
|
|||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
fakeLogger = A.Fake<ILogger>();
|
serviceProvider = new ServiceCollection().BuildBase().BuildServiceProvider();
|
||||||
fakeManager = A.Fake<IManager>();
|
|
||||||
fakeRConConnection = A.Fake<IRConConnection>();
|
fakeLogger = serviceProvider.GetRequiredService<ILogger>();
|
||||||
var rconConnectionFactory = A.Fake<IRConConnectionFactory>();
|
fakeManager = serviceProvider.GetRequiredService<IManager>();
|
||||||
|
fakeRConConnection = serviceProvider.GetRequiredService<IRConConnection>();
|
||||||
|
fakeRConParser = serviceProvider.GetRequiredService<IRConParser>();
|
||||||
|
|
||||||
|
var rconConnectionFactory = serviceProvider.GetRequiredService<IRConConnectionFactory>();
|
||||||
|
|
||||||
A.CallTo(() => rconConnectionFactory.CreateConnection(A<string>.Ignored, A<int>.Ignored, A<string>.Ignored))
|
A.CallTo(() => rconConnectionFactory.CreateConnection(A<string>.Ignored, A<int>.Ignored, A<string>.Ignored))
|
||||||
.Returns(fakeRConConnection);
|
.Returns(fakeRConConnection);
|
||||||
var fakeTranslationLookup = A.Fake<ITranslationLookup>();
|
|
||||||
fakeRConParser = A.Fake<IRConParser>();
|
|
||||||
A.CallTo(() => fakeRConParser.Configuration)
|
A.CallTo(() => fakeRConParser.Configuration)
|
||||||
.Returns(ConfigurationGenerators.CreateRConParserConfiguration(A.Fake<IParserRegexFactory>()));
|
.Returns(ConfigurationGenerators.CreateRConParserConfiguration(serviceProvider.GetRequiredService<IParserRegexFactory>()));
|
||||||
|
|
||||||
|
|
||||||
mockEventHandler = new MockEventHandler();
|
mockEventHandler = new MockEventHandler();
|
||||||
A.CallTo(() => fakeManager.GetEventHandler())
|
A.CallTo(() => fakeManager.GetEventHandler())
|
||||||
.Returns(mockEventHandler);
|
.Returns(mockEventHandler);
|
||||||
|
|
||||||
serviceProvider = new ServiceCollection()
|
|
||||||
.AddSingleton(new IW4MServer(fakeManager, ConfigurationGenerators.CreateServerConfiguration(), fakeTranslationLookup, rconConnectionFactory)
|
|
||||||
{
|
|
||||||
RconParser = fakeRConParser
|
|
||||||
})
|
|
||||||
.BuildServiceProvider();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region LOG
|
||||||
[Test]
|
[Test]
|
||||||
public void Test_GenerateLogPath_Basic()
|
public void Test_GenerateLogPath_Basic()
|
||||||
{
|
{
|
||||||
@ -176,6 +178,7 @@ namespace ApplicationTests
|
|||||||
|
|
||||||
Assert.AreEqual(expected, generated);
|
Assert.AreEqual(expected, generated);
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region BAN
|
#region BAN
|
||||||
[Test]
|
[Test]
|
||||||
@ -508,5 +511,65 @@ namespace ApplicationTests
|
|||||||
.MustHaveHappened();
|
.MustHaveHappened();
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_ConnectionLostNotificationDisabled()
|
||||||
|
{
|
||||||
|
var server = serviceProvider.GetService<IW4MServer>();
|
||||||
|
var fakeConfigHandler = A.Fake<IConfigurationHandler<ApplicationConfiguration>>();
|
||||||
|
|
||||||
|
A.CallTo(() => fakeManager.GetApplicationSettings())
|
||||||
|
.Returns(fakeConfigHandler);
|
||||||
|
|
||||||
|
A.CallTo(() => fakeConfigHandler.Configuration())
|
||||||
|
.Returns(new ApplicationConfiguration() { IgnoreServerConnectionLost = true });
|
||||||
|
|
||||||
|
A.CallTo(() => fakeRConParser.GetStatusAsync(A<IRConConnection>.Ignored))
|
||||||
|
.ThrowsAsync(new NetworkException("err"));
|
||||||
|
|
||||||
|
// simulate failed connection attempts
|
||||||
|
for (int i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
await server.ProcessUpdatesAsync(new System.Threading.CancellationToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
A.CallTo(() => fakeLogger.WriteError(A<string>.Ignored))
|
||||||
|
.MustNotHaveHappened();
|
||||||
|
Assert.IsEmpty(mockEventHandler.Events);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_ConnectionLostNotificationEnabled()
|
||||||
|
{
|
||||||
|
var server = serviceProvider.GetService<IW4MServer>();
|
||||||
|
var fakeConfigHandler = A.Fake<IConfigurationHandler<ApplicationConfiguration>>();
|
||||||
|
|
||||||
|
A.CallTo(() => fakeManager.GetApplicationSettings())
|
||||||
|
.Returns(fakeConfigHandler);
|
||||||
|
|
||||||
|
A.CallTo(() => fakeConfigHandler.Configuration())
|
||||||
|
.Returns(new ApplicationConfiguration() { IgnoreServerConnectionLost = false });
|
||||||
|
|
||||||
|
A.CallTo(() => fakeRConParser.GetStatusAsync(A<IRConConnection>.Ignored))
|
||||||
|
.ThrowsAsync(new NetworkException("err"));
|
||||||
|
|
||||||
|
// simulate failed connection attempts
|
||||||
|
for (int i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
await server.ProcessUpdatesAsync(new System.Threading.CancellationToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute the connection lost event
|
||||||
|
foreach(var e in mockEventHandler.Events.ToList())
|
||||||
|
{
|
||||||
|
await server.ExecuteEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
A.CallTo(() => fakeLogger.WriteError(A<string>.Ignored))
|
||||||
|
.MustHaveHappenedOnceExactly();
|
||||||
|
|
||||||
|
Assert.IsNotEmpty(mockEventHandler.Events);
|
||||||
|
Assert.AreEqual("err", (mockEventHandler.Events[0].Extra as NetworkException).Message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
86
Tests/ApplicationTests/PluginTests.cs
Normal file
86
Tests/ApplicationTests/PluginTests.cs
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
using ApplicationTests.Fixtures;
|
||||||
|
using ApplicationTests.Mocks;
|
||||||
|
using FakeItEasy;
|
||||||
|
using IW4MAdmin;
|
||||||
|
using IW4MAdmin.Application.Misc;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using SharedLibraryCore;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
|
using SharedLibraryCore.Interfaces;
|
||||||
|
using SharedLibraryCore.Services;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace ApplicationTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class PluginTests
|
||||||
|
{
|
||||||
|
private static string PLUGIN_DIR = @"X:\IW4MAdmin\Plugins\ScriptPlugins";
|
||||||
|
private IServiceProvider serviceProvider;
|
||||||
|
private IManager fakeManager;
|
||||||
|
private MockEventHandler mockEventHandler;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
serviceProvider = new ServiceCollection().BuildBase().BuildServiceProvider();
|
||||||
|
fakeManager = serviceProvider.GetRequiredService<IManager>();
|
||||||
|
mockEventHandler = new MockEventHandler();
|
||||||
|
A.CallTo(() => fakeManager.GetEventHandler())
|
||||||
|
.Returns(mockEventHandler);
|
||||||
|
|
||||||
|
var rconConnectionFactory = serviceProvider.GetRequiredService<IRConConnectionFactory>();
|
||||||
|
|
||||||
|
A.CallTo(() => rconConnectionFactory.CreateConnection(A<string>.Ignored, A<int>.Ignored, A<string>.Ignored))
|
||||||
|
.Returns(serviceProvider.GetRequiredService<IRConConnection>());
|
||||||
|
|
||||||
|
A.CallTo(() => serviceProvider.GetRequiredService<IRConParser>().Configuration)
|
||||||
|
.Returns(ConfigurationGenerators.CreateRConParserConfiguration(serviceProvider.GetRequiredService<IParserRegexFactory>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_GenericGuidClientIsKicked()
|
||||||
|
{
|
||||||
|
var plugin = new ScriptPlugin(Path.Join(PLUGIN_DIR, "SharedGUIDKick.js"), PLUGIN_DIR);
|
||||||
|
var server = serviceProvider.GetRequiredService<IW4MServer>();
|
||||||
|
server.GameName = Server.Game.IW4;
|
||||||
|
var client = ClientGenerators.CreateBasicClient(server, hasIp: false, clientState: EFClient.ClientState.Connecting);
|
||||||
|
client.NetworkId = -1168897558496584395;
|
||||||
|
var databaseClient = ClientGenerators.CreateDatabaseClient(hasIp: false);
|
||||||
|
databaseClient.NetworkId = client.NetworkId;
|
||||||
|
|
||||||
|
var fakeClientService = serviceProvider.GetRequiredService<ClientService>();
|
||||||
|
A.CallTo(() => fakeClientService.GetUnique(A<long>.Ignored))
|
||||||
|
.Returns(Task.FromResult(databaseClient));
|
||||||
|
A.CallTo(() => fakeManager.GetClientService())
|
||||||
|
.Returns(fakeClientService);
|
||||||
|
|
||||||
|
await plugin.Initialize(serviceProvider.GetRequiredService<IManager>());
|
||||||
|
|
||||||
|
var gameEvent = new GameEvent()
|
||||||
|
{
|
||||||
|
Origin = client,
|
||||||
|
Owner = server,
|
||||||
|
Type = GameEvent.EventType.PreConnect,
|
||||||
|
IsBlocking = true
|
||||||
|
};
|
||||||
|
|
||||||
|
await server.ExecuteEvent(gameEvent);
|
||||||
|
|
||||||
|
// connect
|
||||||
|
var e = mockEventHandler.Events[0];
|
||||||
|
await server.ExecuteEvent(e);
|
||||||
|
await plugin.OnEventAsync(e, server);
|
||||||
|
|
||||||
|
// kick
|
||||||
|
e = mockEventHandler.Events[1];
|
||||||
|
await server.ExecuteEvent(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user