From: miniduikboot Date: Sat, 27 Aug 2022 09:56:18 +0000 (+0200) Subject: Prevent players joining game on different versions X-Git-Tag: v1.7.2~5 X-Git-Url: https://git.deb.at/?a=commitdiff_plain;h=59cb4a18e804e5b0dff5fe425e497c3a8dbcb6b3;p=rhonda%2Fimpostor.git Prevent players joining game on different versions 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. --- diff --git a/src/Impostor.Api/Games/GameJoinError.cs b/src/Impostor.Api/Games/GameJoinError.cs index 7fcb0f9..7c445fa 100644 --- a/src/Impostor.Api/Games/GameJoinError.cs +++ b/src/Impostor.Api/Games/GameJoinError.cs @@ -37,6 +37,16 @@ /// GameDestroyed, + /// + /// The host has a newer version of the game and the client should update. + /// + ClientOutdated, + + /// + /// The host has an older version of the game and the client should downgrade. + /// + ClientTooNew, + /// /// Custom error by a plugin. /// diff --git a/src/Impostor.Server/Config/DisconnectMessages.cs b/src/Impostor.Server/Config/DisconnectMessages.cs index 74e7a83..3384f32 100644 --- a/src/Impostor.Server/Config/DisconnectMessages.cs +++ b/src/Impostor.Server/Config/DisconnectMessages.cs @@ -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."; diff --git a/src/Impostor.Server/Net/Client.cs b/src/Impostor.Server/Net/Client.cs index b3daed7..7a28371 100644 --- a/src/Impostor.Server/Net/Client.cs +++ b/src/Impostor.Server/Net/Client.cs @@ -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); diff --git a/src/Impostor.Server/Net/Manager/GameManager.cs b/src/Impostor.Server/Net/Manager/GameManager.cs index 528581b..aa22873 100644 --- a/src/Impostor.Server/Net/Manager/GameManager.cs +++ b/src/Impostor.Server/Net/Manager/GameManager.cs @@ -51,7 +51,7 @@ namespace Impostor.Server.Net.Manager return game; } - public IEnumerable FindListings(MapFlags map, int impostorCount, GameKeywords language, int count = 10) + public IEnumerable 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))) diff --git a/src/Impostor.Server/Net/State/Game.Incoming.cs b/src/Impostor.Server/Net/State/Game.Incoming.cs index 116465f..af841af 100644 --- a/src/Impostor.Server/Net/State/Game.Incoming.cs +++ b/src/Impostor.Server/Net/State/Game.Incoming.cs @@ -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.