//
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
//
namespace MUnique.OpenMU.Tests;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
using NUnit.Framework;
using MUnique.OpenMU.AttributeSystem;
using MUnique.OpenMU.DataModel.Configuration;
using MUnique.OpenMU.DataModel.Configuration.Items;
using MUnique.OpenMU.DataModel.Entities;
using MUnique.OpenMU.GameLogic;
using MUnique.OpenMU.GameLogic.Attributes;
using MUnique.OpenMU.GameLogic.PlugIns;
using MUnique.OpenMU.Persistence.InMemory;
using MUnique.OpenMU.PlugIns;
///
/// Unit tests for the .
///
[TestFixture]
public class MaximumConnectionsPerIpPlugInTests
{
private GameContext _gameContext = null!;
private MaximumConnectionsPerIpPlugIn _plugin = null!;
[SetUp]
public async Task SetUp()
{
var dummyPlayer = await PlayerTestHelper.CreatePlayerAsync().ConfigureAwait(false);
this._gameContext = (GameContext)dummyPlayer.GameContext;
this._plugin = new MaximumConnectionsPerIpPlugIn
{
Configuration = new MaximumConnectionsPerIpPlugInConfiguration
{
MaximumConnectionsPerIp = 3
}
};
}
[Test]
public async ValueTask UnderLimitSucceedsAsync()
{
// Arrange
var player1 = new TestPlayer(this._gameContext);
player1.SetIpAddress("127.0.0.1");
await player1.PlayerState.TryAdvanceToAsync(PlayerState.LoginScreen).ConfigureAwait(false);
await player1.PlayerState.TryAdvanceToAsync(PlayerState.Authenticated).ConfigureAwait(false);
await this._gameContext.AddPlayerAsync(player1).ConfigureAwait(false);
var player2 = new TestPlayer(this._gameContext);
player2.SetIpAddress("127.0.0.1");
await player2.PlayerState.TryAdvanceToAsync(PlayerState.LoginScreen).ConfigureAwait(false);
await player2.PlayerState.TryAdvanceToAsync(PlayerState.Authenticated).ConfigureAwait(false);
await this._gameContext.AddPlayerAsync(player2).ConfigureAwait(false);
var joiningPlayer = new TestPlayer(this._gameContext);
joiningPlayer.SetIpAddress("127.0.0.1");
await joiningPlayer.PlayerState.TryAdvanceToAsync(PlayerState.LoginScreen).ConfigureAwait(false);
var eventArgs = new StateMachine.StateChangeEventArgs { NextState = PlayerState.Authenticated };
// Act
await this._plugin.PlayerStateChangingAsync(joiningPlayer, eventArgs).ConfigureAwait(false);
// Assert
Assert.That(eventArgs.Cancel, Is.False);
}
[Test]
public async ValueTask AtLimitCancelsTransitionAsync()
{
// Arrange
var player1 = new TestPlayer(this._gameContext);
player1.SetIpAddress("127.0.0.1");
await player1.PlayerState.TryAdvanceToAsync(PlayerState.LoginScreen).ConfigureAwait(false);
await player1.PlayerState.TryAdvanceToAsync(PlayerState.Authenticated).ConfigureAwait(false);
await this._gameContext.AddPlayerAsync(player1).ConfigureAwait(false);
var player2 = new TestPlayer(this._gameContext);
player2.SetIpAddress("127.0.0.1");
await player2.PlayerState.TryAdvanceToAsync(PlayerState.LoginScreen).ConfigureAwait(false);
await player2.PlayerState.TryAdvanceToAsync(PlayerState.Authenticated).ConfigureAwait(false);
await this._gameContext.AddPlayerAsync(player2).ConfigureAwait(false);
var player3 = new TestPlayer(this._gameContext);
player3.SetIpAddress("127.0.0.1");
await player3.PlayerState.TryAdvanceToAsync(PlayerState.LoginScreen).ConfigureAwait(false);
await player3.PlayerState.TryAdvanceToAsync(PlayerState.Authenticated).ConfigureAwait(false);
await this._gameContext.AddPlayerAsync(player3).ConfigureAwait(false);
var joiningPlayer = new TestPlayer(this._gameContext);
joiningPlayer.SetIpAddress("127.0.0.1");
await joiningPlayer.PlayerState.TryAdvanceToAsync(PlayerState.LoginScreen).ConfigureAwait(false);
var eventArgs = new StateMachine.StateChangeEventArgs { NextState = PlayerState.Authenticated };
// Act
await this._plugin.PlayerStateChangingAsync(joiningPlayer, eventArgs).ConfigureAwait(false);
// Assert
Assert.That(eventArgs.Cancel, Is.True);
Assert.That(joiningPlayer.LoginResultOverride, Is.EqualTo(GameLogic.Views.Login.LoginResult.ServerIsFull));
}
[Test]
public async ValueTask DifferentIpDoesNotCountAsync()
{
// Arrange
var player1 = new TestPlayer(this._gameContext);
player1.SetIpAddress("127.0.0.1");
await player1.PlayerState.TryAdvanceToAsync(PlayerState.LoginScreen).ConfigureAwait(false);
await player1.PlayerState.TryAdvanceToAsync(PlayerState.Authenticated).ConfigureAwait(false);
await this._gameContext.AddPlayerAsync(player1).ConfigureAwait(false);
var player2 = new TestPlayer(this._gameContext);
player2.SetIpAddress("127.0.0.1");
await player2.PlayerState.TryAdvanceToAsync(PlayerState.LoginScreen).ConfigureAwait(false);
await player2.PlayerState.TryAdvanceToAsync(PlayerState.Authenticated).ConfigureAwait(false);
await this._gameContext.AddPlayerAsync(player2).ConfigureAwait(false);
var player3 = new TestPlayer(this._gameContext);
player3.SetIpAddress("127.0.0.1");
await player3.PlayerState.TryAdvanceToAsync(PlayerState.LoginScreen).ConfigureAwait(false);
await player3.PlayerState.TryAdvanceToAsync(PlayerState.Authenticated).ConfigureAwait(false);
await this._gameContext.AddPlayerAsync(player3).ConfigureAwait(false);
var joiningPlayer = new TestPlayer(this._gameContext);
joiningPlayer.SetIpAddress(new System.Net.IPAddress(new byte[] { 192, 168, 1, 100 }).ToString());
await joiningPlayer.PlayerState.TryAdvanceToAsync(PlayerState.LoginScreen).ConfigureAwait(false);
var eventArgs = new StateMachine.StateChangeEventArgs { NextState = PlayerState.Authenticated };
// Act
await this._plugin.PlayerStateChangingAsync(joiningPlayer, eventArgs).ConfigureAwait(false);
// Assert
Assert.That(eventArgs.Cancel, Is.False);
}
[Test]
public async ValueTask LoginScreenAndInitialPlayersDoNotCountAsync()
{
// Arrange
var player1 = new TestPlayer(this._gameContext);
player1.SetIpAddress("127.0.0.1");
await player1.PlayerState.TryAdvanceToAsync(PlayerState.LoginScreen).ConfigureAwait(false);
await player1.PlayerState.TryAdvanceToAsync(PlayerState.Authenticated).ConfigureAwait(false);
await this._gameContext.AddPlayerAsync(player1).ConfigureAwait(false);
var player2 = new TestPlayer(this._gameContext);
player2.SetIpAddress("127.0.0.1");
await player2.PlayerState.TryAdvanceToAsync(PlayerState.LoginScreen).ConfigureAwait(false);
await player2.PlayerState.TryAdvanceToAsync(PlayerState.Authenticated).ConfigureAwait(false);
await this._gameContext.AddPlayerAsync(player2).ConfigureAwait(false);
// This player is only at the login screen
var player3 = new TestPlayer(this._gameContext);
player3.SetIpAddress("127.0.0.1");
await player3.PlayerState.TryAdvanceToAsync(PlayerState.LoginScreen).ConfigureAwait(false);
await this._gameContext.AddPlayerAsync(player3).ConfigureAwait(false);
var joiningPlayer = new TestPlayer(this._gameContext);
joiningPlayer.SetIpAddress("127.0.0.1");
await joiningPlayer.PlayerState.TryAdvanceToAsync(PlayerState.LoginScreen).ConfigureAwait(false);
var eventArgs = new StateMachine.StateChangeEventArgs { NextState = PlayerState.Authenticated };
// Act
await this._plugin.PlayerStateChangingAsync(joiningPlayer, eventArgs).ConfigureAwait(false);
// Assert
Assert.That(eventArgs.Cancel, Is.False);
}
private class TestPlayer : Player, IHasIpAddress
{
private string? _ipAddress;
public TestPlayer(IGameContext gameContext)
: base(gameContext)
{
}
///
public string? IpAddress => this._ipAddress;
/// Sets the IP address for testing purposes.
public void SetIpAddress(string? ip) => this._ipAddress = ip;
protected override ICustomPlugInContainer CreateViewPlugInContainer()
{
return new MockViewPlugInContainer();
}
}
}