From 2c63e0791192f08fa2072843140bdb5705d2b61d Mon Sep 17 00:00:00 2001 From: copygirl Date: Fri, 14 May 2021 15:56:47 +0200 Subject: [PATCH] Fix error when opening/closing integrated server --- src/EscapeMenuMultiplayer.cs | 8 -------- src/Items/Weapon.cs | 4 ++-- src/Objects/Player.cs | 1 - src/Scenes/Client.cs | 21 +++++++++++++++++++++ src/Scenes/Server.cs | 14 ++++++-------- 5 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/EscapeMenuMultiplayer.cs b/src/EscapeMenuMultiplayer.cs index 913c19f..16850a6 100644 --- a/src/EscapeMenuMultiplayer.cs +++ b/src/EscapeMenuMultiplayer.cs @@ -59,7 +59,6 @@ public class EscapeMenuMultiplayer : Container break; } - ServerPort.Editable = server.IsRunning; ServerOpenClose.Disabled = !server.IsRunning; ServerOpenClose.Text = (server.IsRunning && !server.IsSingleplayer) ? "Close Server" : "Open Server"; @@ -105,8 +104,6 @@ public class EscapeMenuMultiplayer : Container server.Stop(); server.Start(port); client.Connect("127.0.0.1", port); - // TODO: Pause server processing (including packets, RPC, Sync) until client reconnects? - // If we're doing that, also make sure to re-map packet and RPC targets to point to new NetworkID. } else { client.Disconnect(); server.Stop(); @@ -127,10 +124,7 @@ public class EscapeMenuMultiplayer : Container server.Stop(); server.GetWorld().ClearPlayers(); server.GetWorld().ClearBlocks(); - client.Disconnect(); - this.GetWorld().ClearPlayers(); - this.GetWorld().ClearBlocks(); } if (client.Status == ConnectionStatus.Disconnected) { @@ -145,8 +139,6 @@ public class EscapeMenuMultiplayer : Container client.Connect(address, port); } else { client.Disconnect(); - this.GetWorld().ClearPlayers(); - this.GetWorld().ClearBlocks(); } } } diff --git a/src/Items/Weapon.cs b/src/Items/Weapon.cs index f8f1682..cbae3f9 100644 --- a/src/Items/Weapon.cs +++ b/src/Items/Weapon.cs @@ -163,7 +163,7 @@ public class Weapon : Sprite protected virtual bool FireInternal(float aimDirection, bool toRight, int seed) { - if ((_reloading != null) || (Rounds <= 0) || (_fireDelay > 0)) return false; + if (!Visible || (_reloading != null) || (Rounds <= 0) || (_fireDelay > 0)) return false; if (this.GetGame() is Client) GetNodeOrNull("Fire")?.Play(); @@ -209,7 +209,7 @@ public class Weapon : Sprite private bool ReloadInternal() { - if ((Rounds >= Capacity) || (_reloading != null)) return false; + if (!Visible || (Rounds >= Capacity) || (_reloading != null)) return false; // TODO: Play reload sound. _reloading = ReloadTime; return true; diff --git a/src/Objects/Player.cs b/src/Objects/Player.cs index 2080fc7..35c33b9 100644 --- a/src/Objects/Player.cs +++ b/src/Objects/Player.cs @@ -21,7 +21,6 @@ public class Player : KinematicBody2D, IInitializable Items = GetNode("Items"); RsetConfig("position", MultiplayerAPI.RPCMode.Puppetsync); - RsetConfig(nameof(NetworkID), MultiplayerAPI.RPCMode.Puppetsync); RsetConfig(nameof(DisplayName), MultiplayerAPI.RPCMode.Puppetsync); RsetConfig(nameof(Color), MultiplayerAPI.RPCMode.Puppetsync); } diff --git a/src/Scenes/Client.cs b/src/Scenes/Client.cs index fb3916e..908735d 100644 --- a/src/Scenes/Client.cs +++ b/src/Scenes/Client.cs @@ -13,6 +13,7 @@ public class Client : Game public NetworkedMultiplayerENet Peer => (NetworkedMultiplayerENet)Multiplayer.NetworkPeer; public ConnectionStatus Status => Peer?.GetConnectionStatus() ?? ConnectionStatus.Disconnected; public LocalPlayer LocalPlayer => (LocalPlayer)this.GetWorld().GetPlayer(GetTree().GetNetworkUniqueId()); + private LocalPlayer _storedLocalPlayer; public event Action Connected; public event Action Disconnected; @@ -53,12 +54,32 @@ public class Client : Game Peer.CloseConnection(); Multiplayer.NetworkPeer = null; + if (IntegratedServer.Server.IsRunning) { + foreach (var player in this.GetWorld().Players) { + // Store the local player for later restoration, but remove it from the scene. + if (player is LocalPlayer localPlayer) { + _storedLocalPlayer = localPlayer; + localPlayer.GetParent().RemoveChild(localPlayer); + // Do NOT call QueueFree - like RemoveFromParent does. + } else player.RemoveFromParent(); + } + } else { + this.GetWorld().ClearPlayers(); + this.GetWorld().ClearBlocks(); + } + Disconnected?.Invoke(); StatusChanged?.Invoke(Status); } private void OnConnectedToServer() { + if ((IntegratedServer.Server.IsRunning == true) && (_storedLocalPlayer != null)) { + this.GetWorld().PlayerContainer.AddChild(_storedLocalPlayer); + _storedLocalPlayer.NetworkID = GetTree().GetNetworkUniqueId(); + _storedLocalPlayer = null; + } + Connected?.Invoke(); StatusChanged?.Invoke(Status); } diff --git a/src/Scenes/Server.cs b/src/Scenes/Server.cs index 0ac39cd..5a5e277 100644 --- a/src/Scenes/Server.cs +++ b/src/Scenes/Server.cs @@ -1,11 +1,10 @@ using System; -using System.Linq; using Godot; // TODO: Allow for initially private integrated server to open itself up to the public. public class Server : Game { - private Player _localPlayer = null; + internal Player LocalPlayer { get; private set; } private bool _isLocalPlayerConnected = false; public NetworkedMultiplayerENet Peer => (NetworkedMultiplayerENet)Multiplayer.NetworkPeer; @@ -63,7 +62,7 @@ public class Server : Game _isLocalPlayerConnected = false; foreach (var player in this.GetWorld().Players) - if (player != _localPlayer) + if (player != LocalPlayer) player.RemoveFromParent(); } @@ -76,10 +75,9 @@ public class Server : Game Multiplayer.RefuseNewNetworkConnections = true; } - if ((_localPlayer != null) && !_isLocalPlayerConnected && + if ((LocalPlayer != null) && !_isLocalPlayerConnected && (Peer.GetPeerAddress(networkID) == "127.0.0.1")) { - _localPlayer.RsetId(networkID, nameof(Player.NetworkID), networkID); - _localPlayer.NetworkID = networkID; + LocalPlayer.NetworkID = networkID; _isLocalPlayerConnected = true; } else { var world = this.GetWorld(); @@ -102,7 +100,7 @@ public class Server : Game block.Color, block.Unbreakable); world.Rpc(nameof(World.SpawnPlayer), networkID, Vector2.Zero); - if (IsSingleplayer) _localPlayer = world.GetPlayer(networkID); + if (IsSingleplayer) LocalPlayer = world.GetPlayer(networkID); } } @@ -112,7 +110,7 @@ public class Server : Game var player = world.GetPlayer(networkID); // Local player stays around for reconnecting. - if (_localPlayer == player) return; + if (LocalPlayer == player) return; world.Rpc(nameof(World.Despawn), world.GetPathTo(player)); }