]> git.deb.at Git - rhonda/impostor.git/commitdiff
Prevent players joining game on different versions
authorminiduikboot <mini@duikbo.at>
Sat, 27 Aug 2022 09:56:18 +0000 (11:56 +0200)
committerminiduikboot <mini@duikbo.at>
Mon, 29 Aug 2022 18:57:16 +0000 (20:57 +0200)
Now that our game version compatibility list is growing longer with
every game patch, we need a way to make sure people in a game run the
same version of the game. Mismatching game version can lead to weird
issues, especially if mods are involved.

src/Impostor.Api/Games/GameJoinError.cs
src/Impostor.Server/Config/DisconnectMessages.cs
src/Impostor.Server/Net/Client.cs
src/Impostor.Server/Net/Manager/GameManager.cs
src/Impostor.Server/Net/State/Game.Incoming.cs

index 7fcb0f9460e8d2a0781f4557ca081fe154c5a85f..7c445fa3f106e4bcc87b0be0018a9cf9ea6f0d4a 100644 (file)
         /// </summary>
         GameDestroyed,
 
+        /// <summary>
+        ///     The host has a newer version of the game and the client should update.
+        /// </summary>
+        ClientOutdated,
+
+        /// <summary>
+        ///     The host has an older version of the game and the client should downgrade.
+        /// </summary>
+        ClientTooNew,
+
         /// <summary>
         ///     Custom error by a plugin.
         /// </summary>
index 74e7a83bcdf92ce0234c51db92dda1c4d928e55f..3384f32be149643c136413b491e49d7eeae2e4c9 100644 (file)
@@ -6,6 +6,11 @@
                                     "Check the server console for more information. " +
                                     "Please report the issue on the Impostor GitHub if it keeps happening.";
 
+        public const string ClientOutdated = "Please update your game to play in this lobby.";
+
+        public const string ClientTooNew = "Your game version is too new for this lobby. " +
+                                           "If you want to join this lobby you need to downgrade your client.";
+
         public const string Destroyed = "The game you tried to join is being destroyed. " +
                                         "Please create a new game.";
 
index b3daed708ba3d5b568d2a37eee8b5174b0d33205..7a28371a02f5895e2fb400826f3d323cf5449a06 100644 (file)
@@ -121,6 +121,12 @@ namespace Impostor.Server.Net
                         case GameJoinError.GameDestroyed:
                             await DisconnectAsync(DisconnectReason.Custom, DisconnectMessages.Destroyed);
                             break;
+                        case GameJoinError.ClientOutdated:
+                            await DisconnectAsync(DisconnectReason.Custom, DisconnectMessages.ClientOutdated);
+                            break;
+                        case GameJoinError.ClientTooNew:
+                            await DisconnectAsync(DisconnectReason.Custom, DisconnectMessages.ClientTooNew);
+                            break;
                         case GameJoinError.Custom:
                             await DisconnectAsync(DisconnectReason.Custom, result.Message);
                             break;
@@ -356,7 +362,7 @@ namespace Impostor.Server.Net
         {
             using var message = MessageWriter.Get(MessageType.Reliable);
 
-            var games = _gameManager.FindListings((MapFlags)options.Map, options.NumImpostors, options.Keywords);
+            var games = _gameManager.FindListings((MapFlags)options.Map, options.NumImpostors, options.Keywords, this.GameVersion);
 
             Message16GetGameListS2C.Serialize(message, games);
 
index 528581b1a937ddfbfe6d20afc735c53ef6fafd8d..aa22873ea67e4f29448f2eaaebeed9c6cd2a528d 100644 (file)
@@ -51,7 +51,7 @@ namespace Impostor.Server.Net.Manager
             return game;
         }
 
-        public IEnumerable<Game> FindListings(MapFlags map, int impostorCount, GameKeywords language, int count = 10)
+        public IEnumerable<Game> FindListings(MapFlags map, int impostorCount, GameKeywords language, int gameVersion, int count = 10)
         {
             var results = 0;
 
@@ -59,7 +59,8 @@ namespace Impostor.Server.Net.Manager
             foreach (var (_, game) in _games.Where(x =>
                 x.Value.IsPublic &&
                 x.Value.GameState == GameStates.NotStarted &&
-                x.Value.PlayerCount < x.Value.Options.MaxPlayers))
+                x.Value.PlayerCount < x.Value.Options.MaxPlayers &&
+                x.Value.Host?.Client.GameVersion == gameVersion))
             {
                 // Check for options.
                 if (!map.HasFlag((MapFlags)(1 << (byte)game.Options.Map)))
index 116465f4e9e4eb19ae2b91dcce918228740a4869..af841af0f947b6054fe1684833e67469c6f1b9d1 100644 (file)
@@ -153,6 +153,19 @@ namespace Impostor.Server.Net.State
 
             var player = client.Player;
 
+            // Check if the player is running the same version as the host
+            if (this.Host != null && client.GameVersion != this.Host.Client.GameVersion)
+            {
+                if (client.GameVersion < this.Host.Client.GameVersion)
+                {
+                    return GameJoinResult.FromError(GameJoinError.ClientOutdated);
+                }
+                else
+                {
+                    return GameJoinResult.FromError(GameJoinError.ClientTooNew);
+                }
+            }
+
             // Check if;
             // - The player is already in this game.
             // - The game is full.