]> git.deb.at Git - rhonda/impostor.git/commitdiff
Added host migration, player disconnection and deletion of games
authorAeonLucid <aeonlucid@gmail.com>
Sun, 20 Sep 2020 22:13:49 +0000 (00:13 +0200)
committerAeonLucid <aeonlucid@gmail.com>
Sun, 20 Sep 2020 22:13:49 +0000 (00:13 +0200)
src/AmongUs.Server/Data/DisconnectMessages.cs
src/AmongUs.Server/Net/Client.cs
src/AmongUs.Server/Net/Game.cs
src/AmongUs.Server/Net/GameManager.cs
src/AmongUs.Server/Program.cs

index 4f959545754626d72d42a5a29bc35ee221704f17..ab3be881bf45d6d993a3191477185a463cb9deb8 100644 (file)
@@ -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
index 6f9db3d7b120fc59ad0c2d94785656a370353f6c..273e564f9a5cbb2a1102caedc2e4be7840dd0336 100644 (file)
@@ -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);
         }
     }
index b6d348cf89c606d13d53cf9597eafb67efbf0475..ea346500b67c5f07ad22834a70864c46373003fe 100644 (file)
@@ -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<Game>();
         
+        private readonly GameManager _gameManager;
         private readonly ConcurrentDictionary<int, ClientPlayer> _players;
 
-        public Game(int code, GameOptionsData options)
+        public Game(GameManager gameManager, int code, GameOptionsData options)
         {
+            _gameManager = gameManager;
+            _players = new ConcurrentDictionary<int, ClientPlayer>();
+            
             Code = code;
             CodeStr = GameCode.IntToGameName(code);
             HostId = -1;
             GameState = GameStates.NotStarted;
             Options = options;
 
-            _players = new ConcurrentDictionary<int, ClientPlayer>();
         }
         
         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);
             }
index e6fe541bb8051557c727c0bd2c0feb38829d4b5a..0c2bc400709b75de101ce400704d311e69250706 100644 (file)
@@ -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))
             {
index e2cfe0e0f25b55bd965251016bd6ce0b494f99da..7857696cdb451dc8b96ffc29d09f1382687536cf 100644 (file)
@@ -21,7 +21,11 @@ namespace AmongUs.Server
             
             // Configure logger.
             Log.Logger = new LoggerConfiguration()
+#if DEBUG
                 .MinimumLevel.Verbose()
+#else
+                .MinimumLevel.Information()
+#endif
                 .WriteTo.Console()
                 .CreateLogger();