Add Duplicate Connection

This commit is contained in:
linmeideli committed 2026-10-02 23:15:30 +08:00
1 parent 977f60789e
commit cf9c137f7e
5 files changed
+45 -2

No files matched your search

@@ -38,6 +38,8 @@ namespace Empostor.Api.Config
public bool EnableRateLimits { get; set; } = true;
public bool EnableDuplicateLoginCheck { get; set; } = true;
public bool ForbidProtocolExtensions { get; set; } = true;
public bool EnablePacketSizeChecks { get; set; } = true;
+5
View File
@@ -54,5 +54,10 @@
/// A custom message can be set in <see cref="GameJoinResult.Message" />.
/// </remarks>
Custom,
/// <summary>
/// The same account is already playing in this game.
/// </summary>
DuplicateConnection,
}
}
+3
View File
@@ -221,6 +221,9 @@ namespace Empostor.Server.Net
case GameJoinError.Custom:
await DisconnectAsync(DisconnectReason.Custom, result.Message);
break;
case GameJoinError.DuplicateConnection:
await DisconnectAsync(DisconnectReason.DuplicateConnectionDetected);
break;
default:
await DisconnectAsync(DisconnectReason.Custom, "Unknown error.");
break;
+34 -2
View File
@@ -2,6 +2,7 @@ using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Empostor.Api.Config;
using Empostor.Api.Games;
using Empostor.Api.Net;
using Next.Hazel;
@@ -118,8 +119,7 @@ namespace Empostor.Server.Net.State
return GameJoinResult.FromError(GameJoinError.InvalidClient);
}
private async ValueTask HandleJoinGameNew(ClientPlayer sender, bool isNew)
{
private async ValueTask HandleJoinGameNew(ClientPlayer sender, bool isNew) {
var client = sender.Client;
var authority = client.GameVersion.HasDisableServerAuthorityFlag ? "true" : "false";
var version = client.GameVersion.ToString();
@@ -155,6 +155,29 @@ namespace Empostor.Server.Net.State
}
}
private bool IsDuplicateAccount(ClientBase client)
{
if (string.IsNullOrEmpty(client.ProductUserId))
{
return false;
}
foreach (var other in _players.Values)
{
if (other.Client == client)
{
continue;
}
if (string.Equals(other.Client.ProductUserId, client.ProductUserId, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
private async ValueTask<GameJoinResult> AddClientSafeAsync(ClientBase client)
{
if (_bannedIps.Contains(client.Connection.EndPoint.Address))
@@ -163,6 +186,15 @@ namespace Empostor.Server.Net.State
}
var player = client.Player;
if (AntiCheat.Config.EnableDuplicateLoginCheck && IsDuplicateAccount(client))
{
_logger.LogWarning(
"#{Id} {Name} rejected: account {Puid} is already playing in this game",
client.Id, client.Name, client.ProductUserId);
return GameJoinResult.FromError(GameJoinError.DuplicateConnection);
}
if (_compatibilityConfig.AllowVersionMixing == false &&
this.Host != null && client.GameVersion != this.Host.Client.GameVersion)
{
+1
View File
@@ -32,6 +32,7 @@
"EnableMeetingChecks": true,
"EnableVotingChecks": true,
"EnableRateLimits": true,
"EnableDuplicateLoginCheck": true,
"ForbidProtocolExtensions": true,
"EnablePacketSizeChecks": true,
"PacketSizeLimit": 1203