From: AeonLucid Date: Sun, 20 Sep 2020 22:13:49 +0000 (+0200) Subject: Added host migration, player disconnection and deletion of games X-Git-Tag: v1.0.0~13 X-Git-Url: https://git.deb.at/?a=commitdiff_plain;h=fff9fc459a4401d7088690cbcccdadf7b5a03b7a;p=rhonda%2Fimpostor.git Added host migration, player disconnection and deletion of games --- diff --git a/src/AmongUs.Server/Data/DisconnectMessages.cs b/src/AmongUs.Server/Data/DisconnectMessages.cs index 4f95954..ab3be88 100644 --- a/src/AmongUs.Server/Data/DisconnectMessages.cs +++ b/src/AmongUs.Server/Data/DisconnectMessages.cs @@ -5,5 +5,8 @@ public const string Error = "There was an internal server error. " + "Check the server console for more information. " + "Please report the issue on the AmongUsServer GitHub if it keeps happening."; + + public const string Destroyed = "The game you tried to join is being destroyed. " + + "Please create a new game."; } } \ No newline at end of file diff --git a/src/AmongUs.Server/Net/Client.cs b/src/AmongUs.Server/Net/Client.cs index 6f9db3d..273e564 100644 --- a/src/AmongUs.Server/Net/Client.cs +++ b/src/AmongUs.Server/Net/Client.cs @@ -193,10 +193,6 @@ namespace AmongUs.Server.Net break; } - // 101A3BA6 - case RequestFlag.JoinedGame: - break; - case RequestFlag.EndGame: { if (!IsPacketAllowed(message, true)) @@ -207,6 +203,24 @@ namespace AmongUs.Server.Net Player.Game.HandleEndGame(message); break; } + + case RequestFlag.AlterGame: + { + if (!IsPacketAllowed(message, true)) + { + return; + } + + if (message.ReadByte() != (byte) AlterGameTags.ChangePrivacy) + { + return; + } + + var isPublic = message.ReadByte() == 1; + + Player.Game.HandleAlterGame(message, Player, isPublic); + break; + } default: Logger.Warning("Server received unknown flag {0}.", flag); @@ -215,6 +229,7 @@ namespace AmongUs.Server.Net if (flag != RequestFlag.GameData && flag != RequestFlag.GameDataTo && + flag != RequestFlag.EndGame && message.Position < message.Length) { Logger.Warning("Server did not consume all bytes from {0} ({1} < {2}).", @@ -226,6 +241,18 @@ namespace AmongUs.Server.Net private void OnDisconnected(object sender, DisconnectedEventArgs e) { + try + { + if (Player.Game != null) + { + Player.Game.HandleRemovePlayer(Id, 0); + } + } + catch (Exception ex) + { + Logger.Error(ex, "Exception caught in client disconnection."); + } + _clientManager.Remove(this); } } diff --git a/src/AmongUs.Server/Net/Game.cs b/src/AmongUs.Server/Net/Game.cs index b6d348c..ea34650 100644 --- a/src/AmongUs.Server/Net/Game.cs +++ b/src/AmongUs.Server/Net/Game.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Concurrent; using System.Linq; +using AmongUs.Server.Data; using AmongUs.Server.Exceptions; using AmongUs.Server.Extensions; using AmongUs.Server.Net.Response; @@ -16,17 +17,20 @@ namespace AmongUs.Server.Net { private static readonly ILogger Logger = Log.ForContext(); + private readonly GameManager _gameManager; private readonly ConcurrentDictionary _players; - public Game(int code, GameOptionsData options) + public Game(GameManager gameManager, int code, GameOptionsData options) { + _gameManager = gameManager; + _players = new ConcurrentDictionary(); + Code = code; CodeStr = GameCode.IntToGameName(code); HostId = -1; GameState = GameStates.NotStarted; Options = options; - _players = new ConcurrentDictionary(); } public int Code { get; } @@ -79,19 +83,21 @@ namespace AmongUs.Server.Net } } - public void HandleJoinGame(ClientPlayer player) + public void HandleJoinGame(ClientPlayer sender) { switch (GameState) { case GameStates.NotStarted: - HandleJoinGameNew(player); + HandleJoinGameNew(sender); break; case GameStates.Ended: - HandleJoinGameNext(player); + HandleJoinGameNext(sender); break; case GameStates.Started: + sender.Client.Connection.Send(new Message1DisconnectReason(DisconnectReason.GameStarted)); + return; case GameStates.Destroyed: - player.Client.Connection.Send(new Message1DisconnectReason(DisconnectReason.GameStarted)); + sender.Client.Connection.Send(new Message1DisconnectReason(DisconnectReason.Custom, DisconnectMessages.Destroyed)); return; default: throw new ArgumentOutOfRangeException(); @@ -118,18 +124,48 @@ namespace AmongUs.Server.Net _players.Clear(); } - public void HandleRemovePlayer(int playerId, byte reason) + public void HandleAlterGame(MessageReader message, ClientPlayer sender, bool isPublic) { - _players.TryRemove(playerId, out var player); + IsPublic = isPublic; - // TODO: Host migration + using (var packet = MessageWriter.Get(SendOption.Reliable)) + { + packet.CopyFrom(message); + SendToAllExcept(packet, sender); + } + } + + public void HandleRemovePlayer(int playerId, byte reason) + { + if (_players.TryRemove(playerId, out var player)) + { + player.Game = null; + } + + // Game is empty, remove it. + if (_players.Count == 0) + { + GameState = GameStates.Destroyed; + + // Remove instance reference. + _gameManager.Remove(Code); + return; + } + + // Host migration. + if (HostId == playerId) + { + HostId = _players.First().Value.Client.Id; + } using (var packet = MessageWriter.Get(SendOption.Reliable)) { + packet.StartMessage((byte) RequestFlag.RemovePlayer); packet.Write(Code); packet.Write(playerId); packet.Write(HostId); packet.Write(reason); + packet.EndMessage(); SendToAllExcept(packet, player); } diff --git a/src/AmongUs.Server/Net/GameManager.cs b/src/AmongUs.Server/Net/GameManager.cs index e6fe541..0c2bc40 100644 --- a/src/AmongUs.Server/Net/GameManager.cs +++ b/src/AmongUs.Server/Net/GameManager.cs @@ -18,7 +18,7 @@ namespace AmongUs.Server.Net public Game Create(Client owner, GameOptionsData options) { var gameCode = GameCode.GenerateCode(6); - var game = new Game(gameCode, options); + var game = new Game(this, gameCode, options); if (_games.TryAdd(gameCode, game)) { diff --git a/src/AmongUs.Server/Program.cs b/src/AmongUs.Server/Program.cs index e2cfe0e..7857696 100644 --- a/src/AmongUs.Server/Program.cs +++ b/src/AmongUs.Server/Program.cs @@ -21,7 +21,11 @@ namespace AmongUs.Server // Configure logger. Log.Logger = new LoggerConfiguration() +#if DEBUG .MinimumLevel.Verbose() +#else + .MinimumLevel.Information() +#endif .WriteTo.Console() .CreateLogger();