Unstable v0.19.5.0
This commit is contained in:
@@ -71,6 +71,12 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
expirationTime = parsedTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
string error = $"Failed to parse the ban duration of \"{name}\" ({separatedLine[2]}) from the legacy ban list file (text file which has now been changed to XML). Considering the ban permanent.";
|
||||
DebugConsole.ThrowError(error);
|
||||
GameServer.AddPendingMessageToOwner(error, ChatMessageType.Error);
|
||||
}
|
||||
}
|
||||
string reason = separatedLine.Length > 3 ? string.Join(",", separatedLine.Skip(3)) : "";
|
||||
|
||||
@@ -156,6 +162,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
public void BanPlayer(string name, Either<Address, AccountId> addressOrAccountId, string reason, TimeSpan? duration)
|
||||
{
|
||||
if (addressOrAccountId.TryGet(out Address address) && address.IsLocalHost) { return; }
|
||||
|
||||
var existingBan = bannedPlayers.Find(bp => bp.AddressOrAccountId == addressOrAccountId);
|
||||
if (existingBan != null) { bannedPlayers.Remove(existingBan); }
|
||||
|
||||
|
||||
@@ -224,27 +224,55 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset what this client has voted for and the kick votes given to this client
|
||||
/// </summary>
|
||||
public void ResetVotes(bool resetKickVotes)
|
||||
{
|
||||
for (int i = 0; i < votes.Length; i++)
|
||||
{
|
||||
votes[i] = null;
|
||||
}
|
||||
if (resetKickVotes)
|
||||
{
|
||||
kickVoters.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void SetPermissions(ClientPermissions permissions, IEnumerable<DebugConsole.Command> permittedConsoleCommands)
|
||||
{
|
||||
this.Permissions = permissions;
|
||||
this.PermittedConsoleCommands.Clear();
|
||||
this.PermittedConsoleCommands.UnionWith(permittedConsoleCommands);
|
||||
Permissions = permissions;
|
||||
PermittedConsoleCommands.Clear();
|
||||
PermittedConsoleCommands.UnionWith(permittedConsoleCommands);
|
||||
if (Permissions.HasFlag(ClientPermissions.ManageSettings))
|
||||
{
|
||||
//ensure the client has the up-to-date server settings
|
||||
GameMain.Server?.ServerSettings?.ForcePropertyUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public void GivePermission(ClientPermissions permission)
|
||||
{
|
||||
if (!this.Permissions.HasFlag(permission)) this.Permissions |= permission;
|
||||
if (!Permissions.HasFlag(permission))
|
||||
{
|
||||
Permissions |= permission;
|
||||
if (permission.HasFlag(ClientPermissions.ManageSettings))
|
||||
{
|
||||
//ensure the client has the up-to-date server settings
|
||||
GameMain.Server?.ServerSettings?.ForcePropertyUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemovePermission(ClientPermissions permission)
|
||||
{
|
||||
this.Permissions &= ~permission;
|
||||
Permissions &= ~permission;
|
||||
}
|
||||
|
||||
public bool HasPermission(ClientPermissions permission)
|
||||
{
|
||||
return this.Permissions.HasFlag(permission);
|
||||
return Permissions.HasFlag(permission);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace Barotrauma.Networking
|
||||
string resultFileName
|
||||
= dir.StartsWith(ContentPackage.LocalModsDir)
|
||||
? $"Local_{mod.Name}"
|
||||
: $"Workshop_{mod.Name}_{mod.SteamWorkshopId}";
|
||||
: $"Workshop_{mod.Name}_{(mod.UgcId.TryUnwrap(out var ugcId) ? ugcId.ToString() : "NULL")}";
|
||||
resultFileName = ToolBox.RemoveInvalidFileNameChars(resultFileName.Replace('\\', '_').Replace('/', '_'));
|
||||
resultFileName = $"{resultFileName}{Extension}";
|
||||
return Path.Combine(UploadFolder, resultFileName);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -246,7 +246,7 @@ namespace Barotrauma.Networking
|
||||
" (created " + (Timing.TotalTime - firstEventToResend.CreateTime).ToString("0.##") + " s ago, " +
|
||||
(lastSentToAnyoneTime - firstEventToResend.CreateTime).ToString("0.##") + " s older than last event sent to anyone)" +
|
||||
" Events queued: " + events.Count + ", last sent to all: " + lastSentToAll, ServerLog.MessageType.Error);
|
||||
server.DisconnectClient(c, "", DisconnectReason.ExcessiveDesyncOldEvent + "/ServerMessage.ExcessiveDesyncOldEvent");
|
||||
server.DisconnectClient(c, PeerDisconnectPacket.WithReason(DisconnectReason.ExcessiveDesyncOldEvent));
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -260,7 +260,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
DebugConsole.NewMessage(c.Name + " was kicked because they were expecting a removed network event (" + (c.LastRecvEntityEventID + 1).ToString() + ", last available is " + events[0].ID.ToString() + ")", Color.Red);
|
||||
GameServer.Log(GameServer.ClientLogName(c) + " was kicked because they were expecting a removed network event (" + (c.LastRecvEntityEventID + 1).ToString() + ", last available is " + events[0].ID.ToString() + ")", ServerLog.MessageType.Error);
|
||||
server.DisconnectClient(c, "", DisconnectReason.ExcessiveDesyncRemovedEvent + "/ServerMessage.ExcessiveDesyncRemovedEvent");
|
||||
server.DisconnectClient(c, PeerDisconnectPacket.WithReason(DisconnectReason.ExcessiveDesyncRemovedEvent));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -269,7 +269,7 @@ namespace Barotrauma.Networking
|
||||
foreach (Client timedOutClient in timedOutClients)
|
||||
{
|
||||
GameServer.Log("Disconnecting client " + GameServer.ClientLogName(timedOutClient) + ". Syncing the client with the server took too long.", ServerLog.MessageType.Error);
|
||||
GameMain.Server.DisconnectClient(timedOutClient, "", DisconnectReason.SyncTimeout + "/ServerMessage.SyncTimeout");
|
||||
GameMain.Server.DisconnectClient(timedOutClient, PeerDisconnectPacket.WithReason(DisconnectReason.SyncTimeout));
|
||||
}
|
||||
|
||||
bufferedEvents.RemoveAll(b => b.IsProcessed);
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Barotrauma.Networking
|
||||
if (Sender != null && c.InGame)
|
||||
{
|
||||
msg.WriteUInt16(Sender.ID);
|
||||
}
|
||||
}
|
||||
msg.WriteBoolean(false); //text color (no custom text colors for order messages)
|
||||
msg.WritePadBits();
|
||||
WriteOrder(msg);
|
||||
|
||||
+28
-32
@@ -15,7 +15,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
private readonly List<NetIncomingMessage> incomingLidgrenMessages;
|
||||
|
||||
public LidgrenServerPeer(Option<int> ownKey, ServerSettings settings)
|
||||
public LidgrenServerPeer(Option<int> ownKey, ServerSettings settings, Callbacks callbacks) : base(callbacks)
|
||||
{
|
||||
serverSettings = settings;
|
||||
|
||||
@@ -68,21 +68,21 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
public override void Close(string? msg = null)
|
||||
public override void Close()
|
||||
{
|
||||
if (netServer == null) { return; }
|
||||
|
||||
for (int i = pendingClients.Count - 1; i >= 0; i--)
|
||||
{
|
||||
RemovePendingClient(pendingClients[i], DisconnectReason.ServerShutdown, msg);
|
||||
RemovePendingClient(pendingClients[i], PeerDisconnectPacket.WithReason(DisconnectReason.ServerShutdown));
|
||||
}
|
||||
|
||||
for (int i = connectedClients.Count - 1; i >= 0; i--)
|
||||
{
|
||||
Disconnect(connectedClients[i], msg ?? DisconnectReason.ServerShutdown.ToString());
|
||||
Disconnect(connectedClients[i], PeerDisconnectPacket.WithReason(DisconnectReason.ServerShutdown));
|
||||
}
|
||||
|
||||
netServer.Shutdown(msg ?? DisconnectReason.ServerShutdown.ToString());
|
||||
netServer.Shutdown(PeerDisconnectPacket.WithReason(DisconnectReason.ServerShutdown).ToLidgrenStringRepresentation());
|
||||
|
||||
pendingClients.Clear();
|
||||
connectedClients.Clear();
|
||||
@@ -91,7 +91,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
Steamworks.SteamServer.OnValidateAuthTicketResponse -= OnAuthChange;
|
||||
|
||||
OnShutdown?.Invoke();
|
||||
callbacks.OnShutdown.Invoke();
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
@@ -100,12 +100,6 @@ namespace Barotrauma.Networking
|
||||
|
||||
ToolBox.ThrowIfNull(incomingLidgrenMessages);
|
||||
|
||||
if (OnOwnerDetermined != null && OwnerConnection != null)
|
||||
{
|
||||
OnOwnerDetermined?.Invoke(OwnerConnection);
|
||||
OnOwnerDetermined = null;
|
||||
}
|
||||
|
||||
netServer.ReadMessages(incomingLidgrenMessages);
|
||||
|
||||
//process incoming connections first
|
||||
@@ -193,14 +187,14 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (connectedClients.Count >= serverSettings.MaxPlayers)
|
||||
{
|
||||
inc.SenderConnection.Deny(DisconnectReason.ServerFull.ToString());
|
||||
inc.SenderConnection.Deny(PeerDisconnectPacket.WithReason(DisconnectReason.ServerFull).ToLidgrenStringRepresentation());
|
||||
return;
|
||||
}
|
||||
|
||||
if (serverSettings.BanList.IsBanned(new LidgrenEndpoint(inc.SenderConnection.RemoteEndPoint), out string banReason))
|
||||
{
|
||||
//IP banned: deny immediately
|
||||
inc.SenderConnection.Deny($"{DisconnectReason.Banned}/ {banReason}");
|
||||
inc.SenderConnection.Deny(PeerDisconnectPacket.Banned(banReason).ToLidgrenStringRepresentation());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -235,12 +229,12 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (pendingClient != null)
|
||||
{
|
||||
RemovePendingClient(pendingClient, DisconnectReason.AuthenticationRequired, "Received data message from unauthenticated client");
|
||||
RemovePendingClient(pendingClient, PeerDisconnectPacket.WithReason(DisconnectReason.AuthenticationRequired));
|
||||
}
|
||||
else if (lidgrenMsg.SenderConnection.Status != NetConnectionStatus.Disconnected &&
|
||||
lidgrenMsg.SenderConnection.Status != NetConnectionStatus.Disconnecting)
|
||||
{
|
||||
lidgrenMsg.SenderConnection.Disconnect($"{DisconnectReason.AuthenticationRequired}/ Received data message from unauthenticated client");
|
||||
lidgrenMsg.SenderConnection.Disconnect(PeerDisconnectPacket.WithReason(DisconnectReason.AuthenticationRequired).ToLidgrenStringRepresentation());
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -252,12 +246,12 @@ namespace Barotrauma.Networking
|
||||
|| (conn.AccountInfo.AccountId.TryUnwrap(out var accountId) && serverSettings.BanList.IsBanned(accountId, out banReason))
|
||||
|| conn.AccountInfo.OtherMatchingIds.Any(id => serverSettings.BanList.IsBanned(id, out banReason)))
|
||||
{
|
||||
Disconnect(conn, $"{DisconnectReason.Banned}/ {banReason}");
|
||||
Disconnect(conn, PeerDisconnectPacket.Banned(banReason));
|
||||
return;
|
||||
}
|
||||
|
||||
var packet = INetSerializableStruct.Read<PeerPacketMessage>(inc);
|
||||
OnMessageReceived?.Invoke(conn, packet.GetReadMessage(packetHeader.IsCompressed(), conn));
|
||||
callbacks.OnMessageReceived.Invoke(conn, packet.GetReadMessage(packetHeader.IsCompressed(), conn));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,12 +269,11 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
DebugConsole.NewMessage("Owner disconnected: closing the server...");
|
||||
GameServer.Log("Owner disconnected: closing the server...", ServerLog.MessageType.ServerMessage);
|
||||
Close($"{DisconnectReason.ServerShutdown}/ Owner disconnected");
|
||||
Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
#warning TODO: kill off disconnect in layer 1
|
||||
Disconnect(conn, $"ServerMessage.HasDisconnected~[client]={GameMain.Server.ConnectedClients.First(c => c.Connection == conn).Name}");
|
||||
Disconnect(conn, PeerDisconnectPacket.WithReason(DisconnectReason.Disconnected));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -288,7 +281,7 @@ namespace Barotrauma.Networking
|
||||
PendingClient? pendingClient = pendingClients.Find(c => c.Connection is LidgrenConnection l && l.NetConnection == inc.SenderConnection);
|
||||
if (pendingClient != null)
|
||||
{
|
||||
RemovePendingClient(pendingClient, DisconnectReason.Unknown, $"ServerMessage.HasDisconnected~[client]={pendingClient.Name}");
|
||||
RemovePendingClient(pendingClient, PeerDisconnectPacket.WithReason(DisconnectReason.Disconnected));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,9 +305,11 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (status == Steamworks.AuthResponse.OK) { return; }
|
||||
|
||||
if (connectedClients.Find(c => c.AccountInfo.AccountId is Some<AccountId> { Value: SteamId id } && id.Value == steamId) is LidgrenConnection connection)
|
||||
if (connectedClients.Find(c
|
||||
=> c.AccountInfo.AccountId is Some<AccountId> { Value: SteamId id } && id.Value == steamId)
|
||||
is LidgrenConnection connection)
|
||||
{
|
||||
Disconnect(connection, $"{DisconnectReason.SteamAuthenticationFailed}/ Steam authentication status changed: {status}");
|
||||
Disconnect(connection, PeerDisconnectPacket.SteamAuthError(status));
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -325,7 +320,7 @@ namespace Barotrauma.Networking
|
||||
|| serverSettings.BanList.IsBanned(new SteamId(steamId), out banReason)
|
||||
|| serverSettings.BanList.IsBanned(new SteamId(ownerId), out banReason))
|
||||
{
|
||||
RemovePendingClient(pendingClient, DisconnectReason.Banned, banReason);
|
||||
RemovePendingClient(pendingClient, PeerDisconnectPacket.Banned(banReason));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -337,7 +332,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else
|
||||
{
|
||||
RemovePendingClient(pendingClient, DisconnectReason.SteamAuthenticationFailed, $"Steam authentication failed: {status}");
|
||||
RemovePendingClient(pendingClient, PeerDisconnectPacket.SteamAuthError(status));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,7 +369,7 @@ namespace Barotrauma.Networking
|
||||
SendMsgInternal(conn, headers, body);
|
||||
}
|
||||
|
||||
public override void Disconnect(NetworkConnection conn, string? msg = null)
|
||||
public override void Disconnect(NetworkConnection conn, PeerDisconnectPacket peerDisconnectPacket)
|
||||
{
|
||||
if (netServer == null) { return; }
|
||||
|
||||
@@ -384,11 +379,11 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
lidgrenConn.Status = NetworkConnectionStatus.Disconnected;
|
||||
connectedClients.Remove(lidgrenConn);
|
||||
OnDisconnect?.Invoke(conn, msg);
|
||||
callbacks.OnDisconnect.Invoke(conn, peerDisconnectPacket);
|
||||
if (conn.AccountInfo.AccountId is Some<AccountId> { Value: SteamId steamId }) { SteamManager.StopAuthSession(steamId); }
|
||||
}
|
||||
|
||||
lidgrenConn.NetConnection.Disconnect(msg ?? "Disconnected");
|
||||
lidgrenConn.NetConnection.Disconnect(peerDisconnectPacket.ToLidgrenStringRepresentation());
|
||||
}
|
||||
|
||||
protected override void SendMsgInternal(NetworkConnection conn, PeerPacketHeaders headers, INetSerializableStruct? body)
|
||||
@@ -413,6 +408,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
ownerKey = Option<int>.None();
|
||||
OwnerConnection = pendingClient.Connection;
|
||||
callbacks.OnOwnerDetermined.Invoke(OwnerConnection);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,7 +436,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (requireSteamAuth)
|
||||
{
|
||||
RemovePendingClient(pendingClient, DisconnectReason.SteamAuthenticationFailed, "Steam auth session failed to start: Steam ID not provided");
|
||||
RemovePendingClient(pendingClient, PeerDisconnectPacket.WithReason(DisconnectReason.SteamAuthenticationFailed));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -451,7 +447,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (requireSteamAuth)
|
||||
{
|
||||
RemovePendingClient(pendingClient, DisconnectReason.SteamAuthenticationFailed, $"Steam auth session failed to start: {authSessionStartState}");
|
||||
RemovePendingClient(pendingClient, PeerDisconnectPacket.SteamAuthError(authSessionStartState));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -471,7 +467,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (pendingClient.AccountInfo.AccountId != packet.SteamId.Select(uid => (AccountId)uid))
|
||||
{
|
||||
RemovePendingClient(pendingClient, DisconnectReason.SteamAuthenticationFailed, "SteamID mismatch");
|
||||
RemovePendingClient(pendingClient, PeerDisconnectPacket.WithReason(DisconnectReason.SteamAuthenticationFailed));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+36
-30
@@ -9,26 +9,31 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
internal abstract class ServerPeer
|
||||
{
|
||||
public delegate void MessageCallback(NetworkConnection connection, IReadMessage message);
|
||||
public readonly record struct Callbacks(
|
||||
Callbacks.MessageCallback OnMessageReceived,
|
||||
Callbacks.DisconnectCallback OnDisconnect,
|
||||
Callbacks.InitializationCompleteCallback OnInitializationComplete,
|
||||
Callbacks.ShutdownCallback OnShutdown,
|
||||
Callbacks.OwnerDeterminedCallback OnOwnerDetermined)
|
||||
{
|
||||
public delegate void MessageCallback(NetworkConnection connection, IReadMessage message);
|
||||
public delegate void DisconnectCallback(NetworkConnection connection, PeerDisconnectPacket peerDisconnectPacket);
|
||||
public delegate void InitializationCompleteCallback(NetworkConnection connection, string? clientName);
|
||||
public delegate void ShutdownCallback();
|
||||
public delegate void OwnerDeterminedCallback(NetworkConnection connection);
|
||||
}
|
||||
|
||||
public delegate void DisconnectCallback(NetworkConnection connection, string? reason);
|
||||
|
||||
public delegate void InitializationCompleteCallback(NetworkConnection connection, string? clientName);
|
||||
|
||||
public delegate void ShutdownCallback();
|
||||
|
||||
public delegate void OwnerDeterminedCallback(NetworkConnection connection);
|
||||
|
||||
public MessageCallback? OnMessageReceived;
|
||||
public DisconnectCallback? OnDisconnect;
|
||||
public InitializationCompleteCallback? OnInitializationComplete;
|
||||
public ShutdownCallback? OnShutdown;
|
||||
public OwnerDeterminedCallback? OnOwnerDetermined;
|
||||
protected readonly Callbacks callbacks;
|
||||
|
||||
protected ServerPeer(Callbacks callbacks)
|
||||
{
|
||||
this.callbacks = callbacks;
|
||||
}
|
||||
|
||||
public abstract void InitializeSteamServerCallbacks();
|
||||
|
||||
public abstract void Start();
|
||||
public abstract void Close(string? msg = null);
|
||||
public abstract void Close();
|
||||
public abstract void Update(float deltaTime);
|
||||
|
||||
protected sealed class PendingClient
|
||||
@@ -84,15 +89,16 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (!Client.IsValidName(authPacket.Name, serverSettings))
|
||||
{
|
||||
RemovePendingClient(pendingClient, DisconnectReason.InvalidName, "");
|
||||
RemovePendingClient(pendingClient, PeerDisconnectPacket.WithReason(DisconnectReason.InvalidName));
|
||||
return;
|
||||
}
|
||||
|
||||
bool isCompatibleVersion = NetworkMember.IsCompatible(authPacket.GameVersion, GameMain.Version.ToString()) ?? false;
|
||||
bool isCompatibleVersion =
|
||||
Version.TryParse(authPacket.GameVersion, out var remoteVersion)
|
||||
&& NetworkMember.IsCompatible(remoteVersion, GameMain.Version);
|
||||
if (!isCompatibleVersion)
|
||||
{
|
||||
RemovePendingClient(pendingClient, DisconnectReason.InvalidVersion,
|
||||
$"DisconnectMessage.InvalidVersion~[version]={GameMain.Version}~[clientversion]={authPacket.GameVersion}");
|
||||
RemovePendingClient(pendingClient, PeerDisconnectPacket.InvalidVersion());
|
||||
|
||||
GameServer.Log($"{authPacket.Name} ({authPacket.SteamId}) couldn't join the server (incompatible game version)", ServerLog.MessageType.Error);
|
||||
DebugConsole.NewMessage($"{authPacket.Name} ({authPacket.SteamId}) couldn't join the server (incompatible game version)", Microsoft.Xna.Framework.Color.Red);
|
||||
@@ -104,7 +110,7 @@ namespace Barotrauma.Networking
|
||||
Client nameTaken = GameMain.Server.ConnectedClients.Find(c => Homoglyphs.Compare(c.Name.ToLower(), authPacket.Name.ToLower()));
|
||||
if (nameTaken != null)
|
||||
{
|
||||
RemovePendingClient(pendingClient, DisconnectReason.NameTaken, "");
|
||||
RemovePendingClient(pendingClient, PeerDisconnectPacket.WithReason(DisconnectReason.NameTaken));
|
||||
GameServer.Log($"{authPacket.Name} ({authPacket.SteamId}) couldn't join the server (name too similar to the name of the client \"" + nameTaken.Name + "\").", ServerLog.MessageType.Error);
|
||||
return;
|
||||
}
|
||||
@@ -135,7 +141,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
const string banMsg = "Failed to enter correct password too many times";
|
||||
BanPendingClient(pendingClient, banMsg, null);
|
||||
RemovePendingClient(pendingClient, DisconnectReason.Banned, banMsg);
|
||||
RemovePendingClient(pendingClient, PeerDisconnectPacket.Banned(banMsg));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -190,13 +196,13 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (IsPendingClientBanned(pendingClient, out string? banReason))
|
||||
{
|
||||
RemovePendingClient(pendingClient, DisconnectReason.Banned, banReason);
|
||||
RemovePendingClient(pendingClient, PeerDisconnectPacket.Banned(banReason));
|
||||
return;
|
||||
}
|
||||
|
||||
if (connectedClients.Count >= serverSettings.MaxPlayers)
|
||||
{
|
||||
RemovePendingClient(pendingClient, DisconnectReason.ServerFull, "");
|
||||
RemovePendingClient(pendingClient, PeerDisconnectPacket.WithReason(DisconnectReason.ServerFull));
|
||||
}
|
||||
|
||||
if (pendingClient.InitializationStep == ConnectionInitialization.Success)
|
||||
@@ -205,15 +211,15 @@ namespace Barotrauma.Networking
|
||||
connectedClients.Add(newConnection);
|
||||
pendingClients.Remove(pendingClient);
|
||||
|
||||
CheckOwnership(pendingClient);
|
||||
callbacks.OnInitializationComplete.Invoke(newConnection, pendingClient.Name);
|
||||
|
||||
OnInitializationComplete?.Invoke(newConnection, pendingClient.Name);
|
||||
CheckOwnership(pendingClient);
|
||||
}
|
||||
|
||||
pendingClient.TimeOut -= Timing.Step;
|
||||
if (pendingClient.TimeOut < 0.0)
|
||||
{
|
||||
RemovePendingClient(pendingClient, DisconnectReason.Unknown, Lidgren.Network.NetConnection.NoResponseMessage);
|
||||
RemovePendingClient(pendingClient, PeerDisconnectPacket.WithReason(DisconnectReason.Timeout));
|
||||
}
|
||||
|
||||
if (Timing.TotalTime < pendingClient.UpdateTime) { return; }
|
||||
@@ -237,7 +243,7 @@ namespace Barotrauma.Networking
|
||||
structToSend = new ServerPeerContentPackageOrderPacket
|
||||
{
|
||||
ServerName = GameMain.Server.ServerName,
|
||||
ContentPackages = ContentPackageManager.EnabledPackages.All.Where(cp => cp.HasMultiplayerSyncedContent)
|
||||
ContentPackages = ContentPackageManager.EnabledPackages.All.Where(cp => cp.HasMultiplayerSyncedContent || cp.Files.All(f => f is SubmarineFile))
|
||||
.Select(contentPackage => new ServerContentPackage(contentPackage, timeNow))
|
||||
.ToImmutableArray()
|
||||
};
|
||||
@@ -267,11 +273,11 @@ namespace Barotrauma.Networking
|
||||
|
||||
protected virtual void CheckOwnership(PendingClient pendingClient) { }
|
||||
|
||||
protected void RemovePendingClient(PendingClient pendingClient, DisconnectReason reason, string? msg)
|
||||
protected void RemovePendingClient(PendingClient pendingClient, PeerDisconnectPacket peerDisconnectPacket)
|
||||
{
|
||||
if (pendingClients.Contains(pendingClient))
|
||||
{
|
||||
Disconnect(pendingClient.Connection, $"{reason}/{msg}");
|
||||
Disconnect(pendingClient.Connection, peerDisconnectPacket);
|
||||
|
||||
pendingClients.Remove(pendingClient);
|
||||
|
||||
@@ -285,6 +291,6 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
public abstract void Send(IWriteMessage msg, NetworkConnection conn, DeliveryMethod deliveryMethod, bool compressPastThreshold = true);
|
||||
public abstract void Disconnect(NetworkConnection conn, string? msg = null);
|
||||
public abstract void Disconnect(NetworkConnection conn, PeerDisconnectPacket peerDisconnectPacket);
|
||||
}
|
||||
}
|
||||
+27
-45
@@ -2,6 +2,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
@@ -16,7 +17,7 @@ namespace Barotrauma.Networking
|
||||
private SteamId ReadSteamId(IReadMessage inc) => new SteamId(inc.ReadUInt64() ^ ownerKey64);
|
||||
private void WriteSteamId(IWriteMessage msg, SteamId val) => msg.WriteUInt64(val.Value ^ ownerKey64);
|
||||
|
||||
public SteamP2PServerPeer(SteamId steamId, int ownerKey, ServerSettings settings)
|
||||
public SteamP2PServerPeer(SteamId steamId, int ownerKey, ServerSettings settings, Callbacks callbacks) : base(callbacks)
|
||||
{
|
||||
serverSettings = settings;
|
||||
|
||||
@@ -43,7 +44,7 @@ namespace Barotrauma.Networking
|
||||
started = true;
|
||||
}
|
||||
|
||||
public override void Close(string? msg = null)
|
||||
public override void Close()
|
||||
{
|
||||
if (!started) { return; }
|
||||
|
||||
@@ -51,12 +52,12 @@ namespace Barotrauma.Networking
|
||||
|
||||
for (int i = pendingClients.Count - 1; i >= 0; i--)
|
||||
{
|
||||
RemovePendingClient(pendingClients[i], DisconnectReason.ServerShutdown, msg);
|
||||
RemovePendingClient(pendingClients[i], PeerDisconnectPacket.WithReason(DisconnectReason.ServerShutdown));
|
||||
}
|
||||
|
||||
for (int i = connectedClients.Count - 1; i >= 0; i--)
|
||||
{
|
||||
Disconnect(connectedClients[i], msg ?? DisconnectReason.ServerShutdown.ToString());
|
||||
Disconnect(connectedClients[i], PeerDisconnectPacket.WithReason(DisconnectReason.ServerShutdown));
|
||||
}
|
||||
|
||||
pendingClients.Clear();
|
||||
@@ -64,19 +65,13 @@ namespace Barotrauma.Networking
|
||||
|
||||
ChildServerRelay.ShutDown();
|
||||
|
||||
OnShutdown?.Invoke();
|
||||
callbacks.OnShutdown.Invoke();
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
if (!started) { return; }
|
||||
|
||||
if (OnOwnerDetermined != null && OwnerConnection != null)
|
||||
{
|
||||
OnOwnerDetermined?.Invoke(OwnerConnection);
|
||||
OnOwnerDetermined = null;
|
||||
}
|
||||
|
||||
//backwards for loop so we can remove elements while iterating
|
||||
for (int i = connectedClients.Count - 1; i >= 0; i--)
|
||||
{
|
||||
@@ -84,7 +79,7 @@ namespace Barotrauma.Networking
|
||||
conn.Decay(deltaTime);
|
||||
if (conn.Timeout < 0.0)
|
||||
{
|
||||
Disconnect(conn, "Timed out");
|
||||
Disconnect(conn, PeerDisconnectPacket.WithReason(DisconnectReason.Timeout));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,24 +144,22 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (pendingClient != null)
|
||||
{
|
||||
RemovePendingClient(pendingClient, DisconnectReason.Banned, banReason);
|
||||
RemovePendingClient(pendingClient, PeerDisconnectPacket.Banned(banReason));
|
||||
}
|
||||
else if (connectedClient != null)
|
||||
{
|
||||
Disconnect(connectedClient, $"{DisconnectReason.Banned}/ {banReason}");
|
||||
Disconnect(connectedClient, PeerDisconnectPacket.Banned(banReason));
|
||||
}
|
||||
}
|
||||
else if (packetHeader.IsDisconnectMessage())
|
||||
{
|
||||
if (pendingClient != null)
|
||||
{
|
||||
string disconnectMsg = $"ServerMessage.HasDisconnected~[client]={pendingClient.Name}";
|
||||
RemovePendingClient(pendingClient, DisconnectReason.Unknown, disconnectMsg);
|
||||
RemovePendingClient(pendingClient, PeerDisconnectPacket.WithReason(DisconnectReason.Disconnected));
|
||||
}
|
||||
else if (connectedClient != null)
|
||||
{
|
||||
string disconnectMsg = $"ServerMessage.HasDisconnected~[client]={GameMain.Server.ConnectedClients.First(c => c.Connection == connectedClient).Name}";
|
||||
Disconnect(connectedClient, disconnectMsg, false);
|
||||
Disconnect(connectedClient, PeerDisconnectPacket.WithReason(DisconnectReason.Disconnected));
|
||||
}
|
||||
}
|
||||
else if (packetHeader.IsHeartbeatMessage())
|
||||
@@ -176,28 +169,27 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else if (packetHeader.IsConnectionInitializationStep())
|
||||
{
|
||||
if (!initialization.HasValue) { return; }
|
||||
ConnectionInitialization initializationStep = initialization.Value;
|
||||
|
||||
if (pendingClient != null)
|
||||
{
|
||||
pendingClient.Connection.SetAccountInfo(new AccountInfo(senderSteamId, sentOwnerSteamId));
|
||||
ReadConnectionInitializationStep(
|
||||
pendingClient,
|
||||
new ReadWriteMessage(inc.Buffer, inc.BitPosition, inc.LengthBits, false),
|
||||
initialization ?? throw new Exception("Initialization step missing"));
|
||||
initializationStep);
|
||||
}
|
||||
else if (initialization.HasValue)
|
||||
else if (initializationStep == ConnectionInitialization.ConnectionStarted)
|
||||
{
|
||||
ConnectionInitialization initializationStep = initialization.Value;
|
||||
if (initializationStep == ConnectionInitialization.ConnectionStarted)
|
||||
{
|
||||
pendingClients.Add(new PendingClient(new SteamP2PConnection(senderSteamId)));
|
||||
}
|
||||
pendingClients.Add(new PendingClient(new SteamP2PConnection(senderSteamId)));
|
||||
}
|
||||
}
|
||||
else if (connectedClient != null)
|
||||
{
|
||||
var packet = INetSerializableStruct.Read<PeerPacketMessage>(inc);
|
||||
IReadMessage msg = new ReadOnlyMessage(packet.Buffer, packetHeader.IsCompressed(), 0, packet.Length, connectedClient);
|
||||
OnMessageReceived?.Invoke(connectedClient, msg);
|
||||
callbacks.OnMessageReceived.Invoke(connectedClient, msg);
|
||||
}
|
||||
}
|
||||
else //sender is owner
|
||||
@@ -227,7 +219,8 @@ namespace Barotrauma.Networking
|
||||
};
|
||||
OwnerConnection.SetAccountInfo(new AccountInfo(ownerSteamId, ownerSteamId));
|
||||
|
||||
OnInitializationComplete?.Invoke(OwnerConnection, packet.OwnerName);
|
||||
callbacks.OnInitializationComplete.Invoke(OwnerConnection, packet.OwnerName);
|
||||
callbacks.OnOwnerDetermined.Invoke(OwnerConnection);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -241,7 +234,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
var packet = INetSerializableStruct.Read<PeerPacketMessage>(inc);
|
||||
IReadMessage msg = new ReadOnlyMessage(packet.Buffer, packetHeader.IsCompressed(), 0, packet.Length, OwnerConnection);
|
||||
OnMessageReceived?.Invoke(OwnerConnection!, msg);
|
||||
callbacks.OnMessageReceived.Invoke(OwnerConnection!, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -281,27 +274,21 @@ namespace Barotrauma.Networking
|
||||
SendMsgInternal(steamP2PConn, headers, body);
|
||||
}
|
||||
|
||||
private void SendDisconnectMessage(SteamId steamId, string? msg)
|
||||
private void SendDisconnectMessage(SteamId steamId, PeerDisconnectPacket peerDisconnectPacket)
|
||||
{
|
||||
if (!started) { return; }
|
||||
|
||||
if (string.IsNullOrWhiteSpace(msg)) { return; }
|
||||
|
||||
var headers = new PeerPacketHeaders
|
||||
{
|
||||
DeliveryMethod = DeliveryMethod.Reliable,
|
||||
PacketHeader = PacketHeader.IsDisconnectMessage | PacketHeader.IsServerMessage,
|
||||
Initialization = null
|
||||
};
|
||||
var packet = new PeerDisconnectPacket
|
||||
{
|
||||
Message = msg
|
||||
};
|
||||
|
||||
SendMsgInternal(steamId, headers, packet);
|
||||
SendMsgInternal(steamId, headers, peerDisconnectPacket);
|
||||
}
|
||||
|
||||
private void Disconnect(NetworkConnection conn, string? msg, bool sendDisconnectMessage)
|
||||
public override void Disconnect(NetworkConnection conn, PeerDisconnectPacket peerDisconnectPacket)
|
||||
{
|
||||
if (!started) { return; }
|
||||
|
||||
@@ -309,26 +296,21 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (!conn.AccountInfo.AccountId.TryUnwrap(out var connAccountId) || !(connAccountId is SteamId connSteamId)) { return; }
|
||||
|
||||
if (sendDisconnectMessage) { SendDisconnectMessage(connSteamId, msg); }
|
||||
SendDisconnectMessage(connSteamId, peerDisconnectPacket);
|
||||
|
||||
if (connectedClients.Contains(steamp2pConn))
|
||||
{
|
||||
steamp2pConn.Status = NetworkConnectionStatus.Disconnected;
|
||||
connectedClients.Remove(steamp2pConn);
|
||||
OnDisconnect?.Invoke(conn, msg);
|
||||
callbacks.OnDisconnect.Invoke(conn, peerDisconnectPacket);
|
||||
Steam.SteamManager.StopAuthSession(connSteamId);
|
||||
}
|
||||
else if (steamp2pConn == OwnerConnection)
|
||||
{
|
||||
//TODO: fix?
|
||||
throw new InvalidOperationException("Cannot disconnect owner peer");
|
||||
}
|
||||
}
|
||||
|
||||
public override void Disconnect(NetworkConnection conn, string? msg = null)
|
||||
{
|
||||
Disconnect(conn, msg, true);
|
||||
}
|
||||
|
||||
protected override void SendMsgInternal(NetworkConnection conn, PeerPacketHeaders headers, INetSerializableStruct? body)
|
||||
{
|
||||
var connSteamId = conn is SteamP2PConnection { Endpoint: SteamP2PEndpoint { SteamId: var id } } ? id : null;
|
||||
|
||||
@@ -505,9 +505,10 @@ namespace Barotrauma.Networking
|
||||
var characterData = campaign?.GetClientCharacterData(clients[i]);
|
||||
if (characterData != null && Level.Loaded?.Type != LevelData.LevelType.Outpost && characterData.HasSpawned)
|
||||
{
|
||||
//we need to reapply the previous respawn penalty affliction or successive deaths won't make it stack
|
||||
characterData.ApplyHealthData(character, (AfflictionPrefab ap) => ap == GetRespawnPenaltyAfflictionPrefab());
|
||||
GiveRespawnPenaltyAffliction(character);
|
||||
}
|
||||
|
||||
if (characterData == null || characterData.HasSpawned)
|
||||
{
|
||||
//give the character the items they would've gotten if they had spawned in the main sub
|
||||
@@ -555,7 +556,7 @@ namespace Barotrauma.Networking
|
||||
foreach (Skill skill in characterInfo.Job.GetSkills())
|
||||
{
|
||||
var skillPrefab = characterInfo.Job.Prefab.Skills.Find(s => skill.Identifier == s.Identifier);
|
||||
if (skillPrefab == null) { continue; }
|
||||
if (skillPrefab == null || skill.Level < skillPrefab.LevelRange.End) { continue; }
|
||||
skill.Level = MathHelper.Lerp(skill.Level, skillPrefab.LevelRange.End, SkillReductionOnDeath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,14 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (!PropEquals(lastSyncedValue, Value))
|
||||
{
|
||||
LastUpdateID = (UInt16)(GameMain.NetLobbyScreen.LastUpdateID);
|
||||
LastUpdateID = GameMain.NetLobbyScreen.LastUpdateID;
|
||||
lastSyncedValue = Value;
|
||||
}
|
||||
}
|
||||
public void ForceUpdate()
|
||||
{
|
||||
LastUpdateID = GameMain.NetLobbyScreen.LastUpdateID++;
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly string ClientPermissionsFile = "Data" + Path.DirectorySeparatorChar + "clientpermissions.xml";
|
||||
@@ -54,6 +58,15 @@ namespace Barotrauma.Networking
|
||||
LoadClientPermissions();
|
||||
}
|
||||
|
||||
public void ForcePropertyUpdate()
|
||||
{
|
||||
UpdateFlag(NetFlags.Properties);
|
||||
foreach (NetPropertyData property in netProperties.Values)
|
||||
{
|
||||
property.ForceUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteNetProperties(IWriteMessage outMsg, Client c)
|
||||
{
|
||||
foreach (UInt32 key in netProperties.Keys)
|
||||
@@ -197,27 +210,32 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
int orBits = incMsg.ReadRangedInteger(0, (int)Barotrauma.MissionType.All) & (int)Barotrauma.MissionType.All;
|
||||
int andBits = incMsg.ReadRangedInteger(0, (int)Barotrauma.MissionType.All) & (int)Barotrauma.MissionType.All;
|
||||
GameMain.NetLobbyScreen.MissionType = (Barotrauma.MissionType)(((int)GameMain.NetLobbyScreen.MissionType | orBits) & andBits);
|
||||
GameMain.NetLobbyScreen.MissionType = (MissionType)(((int)GameMain.NetLobbyScreen.MissionType | orBits) & andBits);
|
||||
|
||||
int traitorSetting = (int)TraitorsEnabled + incMsg.ReadByte() - 1;
|
||||
if (traitorSetting < 0) traitorSetting = 2;
|
||||
if (traitorSetting > 2) traitorSetting = 0;
|
||||
if (traitorSetting < 0) { traitorSetting = 2; }
|
||||
if (traitorSetting > 2) { traitorSetting = 0; }
|
||||
TraitorsEnabled = (YesNoMaybe)traitorSetting;
|
||||
|
||||
int botCount = BotCount + incMsg.ReadByte() - 1;
|
||||
if (botCount < 0) botCount = MaxBotCount;
|
||||
if (botCount > MaxBotCount) botCount = 0;
|
||||
if (botCount < 0) { botCount = MaxBotCount; }
|
||||
if (botCount > MaxBotCount) { botCount = 0; }
|
||||
BotCount = botCount;
|
||||
|
||||
int botSpawnMode = (int)BotSpawnMode + incMsg.ReadByte() - 1;
|
||||
if (botSpawnMode < 0) botSpawnMode = 1;
|
||||
if (botSpawnMode > 1) botSpawnMode = 0;
|
||||
if (botSpawnMode < 0) { botSpawnMode = 1; }
|
||||
if (botSpawnMode > 1) { botSpawnMode = 0; }
|
||||
BotSpawnMode = (BotSpawnMode)botSpawnMode;
|
||||
|
||||
float levelDifficulty = incMsg.ReadSingle();
|
||||
if (levelDifficulty >= 0.0f) SelectedLevelDifficulty = levelDifficulty;
|
||||
if (levelDifficulty >= 0.0f) { SelectedLevelDifficulty = levelDifficulty; }
|
||||
|
||||
UseRespawnShuttle = incMsg.ReadBoolean();
|
||||
bool changedUseRespawnShuttle = incMsg.ReadBoolean();
|
||||
bool useRespawnShuttle = incMsg.ReadBoolean();
|
||||
if (changedUseRespawnShuttle)
|
||||
{
|
||||
UseRespawnShuttle = useRespawnShuttle;
|
||||
}
|
||||
|
||||
bool changedAutoRestart = incMsg.ReadBoolean();
|
||||
bool autoRestart = incMsg.ReadBoolean();
|
||||
|
||||
@@ -216,6 +216,14 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetVotes(IEnumerable<Client> connectedClients, bool resetKickVotes)
|
||||
{
|
||||
foreach (Client client in connectedClients)
|
||||
{
|
||||
client.ResetVotes(resetKickVotes);
|
||||
}
|
||||
}
|
||||
|
||||
public void ServerRead(IReadMessage inc, Client sender)
|
||||
{
|
||||
if (GameMain.Server == null || sender == null) { return; }
|
||||
|
||||
Reference in New Issue
Block a user