//
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
//
namespace MUnique.OpenMU.GameLogic.PlugIns;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using MUnique.OpenMU.PlugIns;
///
/// A plugin that limits the number of simultaneous active player sessions connected from the same IP address.
///
[PlugIn]
[Display(Name = "Maximum Connections Per IP", Description = "Limits the maximum number of parallel connections from the same IP address.")]
[Guid("2C779F5E-379E-4CE0-BFCC-CA6455D757B3")]
public class MaximumConnectionsPerIpPlugIn : IPlayerStateChangingPlugIn, ISupportCustomConfiguration, ISupportDefaultCustomConfiguration, IDisabledByDefault
{
///
public MaximumConnectionsPerIpPlugInConfiguration? Configuration { get; set; }
///
public async ValueTask PlayerStateChangingAsync(Player player, StateMachine.StateChangeEventArgs eventArgs)
{
if (eventArgs.NextState != PlayerState.Authenticated)
{
return;
}
var ipAddress = (player as IHasIpAddress)?.IpAddress;
if (string.IsNullOrEmpty(ipAddress))
{
return;
}
var config = this.Configuration ?? CreateDefaultConfiguration();
var players = await player.GameContext.GetPlayersAsync().ConfigureAwait(false);
var sameIpCount = players.Count(p =>
(p as IHasIpAddress)?.IpAddress == ipAddress
&& p != player
&& p.PlayerState.CurrentState != PlayerState.Initial
&& p.PlayerState.CurrentState != PlayerState.LoginScreen);
if (sameIpCount >= config.MaximumConnectionsPerIp)
{
player.Logger.LogWarning(
"Login request for IP '{IpAddress}' was cancelled. It exceeded the maximum connection limit of {Limit}.",
ipAddress,
config.MaximumConnectionsPerIp);
player.LoginResultOverride = Views.Login.LoginResult.ServerIsFull;
eventArgs.Cancel = true;
}
}
///
public object CreateDefaultConfig()
{
return CreateDefaultConfiguration();
}
private static MaximumConnectionsPerIpPlugInConfiguration CreateDefaultConfiguration()
{
return new MaximumConnectionsPerIpPlugInConfiguration();
}
}