Release 1.10.5.0 - Autumn Update 2025

This commit is contained in:
Regalis11
2025-09-17 13:44:21 +03:00
parent d13836ce87
commit caa0326cf8
120 changed files with 2584 additions and 635 deletions
@@ -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);
}
}
@@ -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)
@@ -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);