Release 1.10.5.0 - Autumn Update 2025
This commit is contained in:
@@ -3716,7 +3716,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
UpdateVoteStatus();
|
||||
|
||||
SendChatMessage(peerDisconnectPacket.ChatMessage(client).Value, ChatMessageType.Server, changeType: peerDisconnectPacket.ConnectionChangeType);
|
||||
SendChatMessage(peerDisconnectPacket.ChatMessage(client.Name).Value, ChatMessageType.Server, changeType: peerDisconnectPacket.ConnectionChangeType);
|
||||
|
||||
UpdateCrewFrame();
|
||||
|
||||
@@ -4234,13 +4234,14 @@ namespace Barotrauma.Networking
|
||||
serverPeer.Send(msg, client.Connection, DeliveryMethod.Reliable);
|
||||
}
|
||||
|
||||
public void UnlockRecipe(Identifier identifier)
|
||||
public void UnlockRecipe(CharacterTeamType team, Identifier identifier)
|
||||
{
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
msg.WriteByte((byte)ServerPacketHeader.UNLOCKRECIPE);
|
||||
msg.WriteByte((byte)team);
|
||||
msg.WriteIdentifier(identifier);
|
||||
foreach (var client in connectedClients)
|
||||
{
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
msg.WriteByte((byte)ServerPacketHeader.UNLOCKRECIPE);
|
||||
msg.WriteIdentifier(identifier);
|
||||
serverPeer.Send(msg, client.Connection, DeliveryMethod.Reliable);
|
||||
}
|
||||
}
|
||||
|
||||
+50
-2
@@ -137,6 +137,10 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
Disconnect(connectedClient.Connection, PeerDisconnectPacket.Banned(banReason));
|
||||
}
|
||||
else
|
||||
{
|
||||
SendDisconnectMessage(senderEndpoint, PeerDisconnectPacket.Banned(banReason));
|
||||
}
|
||||
}
|
||||
else if (packetHeader.IsDisconnectMessage())
|
||||
{
|
||||
@@ -149,9 +153,10 @@ namespace Barotrauma.Networking
|
||||
Disconnect(connectedClient.Connection, PeerDisconnectPacket.WithReason(DisconnectReason.Disconnected));
|
||||
}
|
||||
}
|
||||
else if (packetHeader.IsHeartbeatMessage())
|
||||
else if (packetHeader.IsHeartbeatMessage() || packetHeader.IsDoSProtectionMessage())
|
||||
{
|
||||
//message exists solely as a heartbeat, ignore its contents
|
||||
// ignore these messages, heartbeat messages just need to be acknowledged,
|
||||
// and only the owner should be sending DoS protection messages
|
||||
return;
|
||||
}
|
||||
else if (packetHeader.IsConnectionInitializationStep())
|
||||
@@ -206,6 +211,49 @@ namespace Barotrauma.Networking
|
||||
return;
|
||||
}
|
||||
|
||||
if (packetHeader.IsDoSProtectionMessage())
|
||||
{
|
||||
var packet = INetSerializableStruct.Read<DoSProtectionPacket>(inc);
|
||||
var disconnectPacket = INetSerializableStruct.Read<PeerDisconnectPacket>(inc);
|
||||
|
||||
if (packet.Endpoint.TryUnwrap(out var endpoint))
|
||||
{
|
||||
PendingClient? pendingClient = pendingClients.Find(c => c.Connection.Endpoint == endpoint);
|
||||
ClientConnectionData? connectedClientData = connectedClients.Find(c => c.Connection.Endpoint == endpoint);
|
||||
string? clientName;
|
||||
|
||||
if (pendingClient != null)
|
||||
{
|
||||
clientName = pendingClient.Name;
|
||||
if (packet.ShouldBan)
|
||||
{
|
||||
BanPendingClient(pendingClient, disconnectPacket.AdditionalInformation, duration: null);
|
||||
}
|
||||
RemovePendingClient(pendingClient, disconnectPacket);
|
||||
}
|
||||
else if (connectedClientData != null)
|
||||
{
|
||||
clientName = connectedClientData.TryGetClientName();
|
||||
if (packet.ShouldBan)
|
||||
{
|
||||
connectedClientData.BanClient(serverSettings, disconnectPacket.AdditionalInformation, duration: null);
|
||||
}
|
||||
Disconnect(connectedClientData.Connection, disconnectPacket);
|
||||
}
|
||||
else
|
||||
{
|
||||
string errorMsg = $"Unable to remove client {endpoint} for triggering DoS protection, client not found in pending or connected clients";
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
GameServer.Log(errorMsg, ServerLog.MessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
GameServer.Log($"Client {clientName ?? endpoint.ToString()} {(packet.ShouldBan ? "banned" : "disconnected")} due to DoS protection (Sending too many packets).", ServerLog.MessageType.DoSProtection);
|
||||
GameMain.Server?.SendChatMessage(disconnectPacket.ChatMessage(clientName).Value, ChatMessageType.Server, changeType: disconnectPacket.ConnectionChangeType);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (packetHeader.IsConnectionInitializationStep())
|
||||
{
|
||||
if (OwnerConnection is null)
|
||||
|
||||
+47
-11
@@ -13,7 +13,7 @@ namespace Barotrauma.Networking
|
||||
protected ServerPeer(Callbacks callbacks, ServerSettings serverSettings) : base(callbacks)
|
||||
{
|
||||
this.serverSettings = serverSettings;
|
||||
this.connectedClients = new List<ConnectedClient>();
|
||||
this.connectedClients = new List<ClientConnectionData>();
|
||||
this.pendingClients = new List<PendingClient>();
|
||||
|
||||
List<ContentPackage> contentPackageList = new List<ContentPackage>();
|
||||
@@ -65,21 +65,57 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
protected sealed class ConnectedClient
|
||||
protected sealed class ClientConnectionData(TConnection connection)
|
||||
{
|
||||
public readonly TConnection Connection;
|
||||
public readonly MessageFragmenter Fragmenter;
|
||||
public readonly MessageDefragmenter Defragmenter;
|
||||
public readonly TConnection Connection = connection;
|
||||
public readonly MessageFragmenter Fragmenter = new();
|
||||
public readonly MessageDefragmenter Defragmenter = new();
|
||||
|
||||
public ConnectedClient(TConnection connection)
|
||||
/// <summary>
|
||||
/// Attempts to retrieve the name of the client associated with this connection
|
||||
/// from a higher layer.
|
||||
/// </summary>
|
||||
/// <returns>Name of the client if found, null otherwise.</returns>
|
||||
public string? TryGetClientName()
|
||||
{
|
||||
Connection = connection;
|
||||
Fragmenter = new();
|
||||
Defragmenter = new();
|
||||
if (GameMain.Server?.ConnectedClients is { } connClients)
|
||||
{
|
||||
foreach (Client? client in connClients)
|
||||
{
|
||||
if (client?.Connection is not { } clientConnection) { continue; }
|
||||
|
||||
if (clientConnection.EndpointMatches(Connection.Endpoint) )
|
||||
{
|
||||
return client.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void BanClient(ServerSettings settings, string banReason, TimeSpan? duration)
|
||||
{
|
||||
string clientName = TryGetClientName() ?? "Player";
|
||||
|
||||
Connection.AccountInfo.OtherMatchingIds.ForEach(BanAccountId);
|
||||
|
||||
if (Connection.AccountInfo.AccountId.TryUnwrap(out var accountId))
|
||||
{
|
||||
BanAccountId(accountId);
|
||||
}
|
||||
else
|
||||
{
|
||||
settings.BanList.BanPlayer(clientName, Connection.Endpoint, banReason, duration);
|
||||
}
|
||||
return;
|
||||
|
||||
void BanAccountId(AccountId id)
|
||||
=> settings.BanList.BanPlayer(clientName, id, banReason, duration);
|
||||
}
|
||||
}
|
||||
|
||||
protected readonly List<ConnectedClient> connectedClients;
|
||||
protected readonly List<ClientConnectionData> connectedClients;
|
||||
protected readonly List<PendingClient> pendingClients;
|
||||
protected readonly ServerSettings serverSettings;
|
||||
|
||||
@@ -235,7 +271,7 @@ namespace Barotrauma.Networking
|
||||
if (pendingClient.InitializationStep == ConnectionInitialization.Success)
|
||||
{
|
||||
TConnection newConnection = pendingClient.Connection;
|
||||
connectedClients.Add(new ConnectedClient(newConnection));
|
||||
connectedClients.Add(new ClientConnectionData(newConnection));
|
||||
pendingClients.Remove(pendingClient);
|
||||
|
||||
callbacks.OnInitializationComplete.Invoke(newConnection, pendingClient.Name);
|
||||
|
||||
Reference in New Issue
Block a user