From 66b4d860a949de8d2f6510685975011e70631d6b Mon Sep 17 00:00:00 2001 From: miniduikboot Date: Tue, 13 Jul 2021 22:48:24 +0200 Subject: [PATCH] Improve error when client version is unsupported (#432) * Improve error when client version is unsupported In the default message that was used previously the user is asked to upgrade his game. This is not always correct, as sometimes the Impostor server is too old and should be updated instead. Therefore custom disconnect messages are used that blames either the user or the server operator, which is hopefully more accurate. I've chosen not to include the game version that is supported by the server in this message because the network version rarely matches the advertised version in the main menu. * Rewrite versionCompare switch case Co-authored-by: js6pak Co-authored-by: js6pak --- .../Config/DisconnectMessages.cs | 8 ++- .../Net/Manager/ClientManager.cs | 53 +++++++++++++++++-- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/Impostor.Server/Config/DisconnectMessages.cs b/src/Impostor.Server/Config/DisconnectMessages.cs index 6bf8e72..74e7a83 100644 --- a/src/Impostor.Server/Config/DisconnectMessages.cs +++ b/src/Impostor.Server/Config/DisconnectMessages.cs @@ -4,7 +4,7 @@ { 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."; + "Please report the issue on the Impostor GitHub if it keeps happening."; public const string Destroyed = "The game you tried to join is being destroyed. " + "Please create a new game."; @@ -15,5 +15,11 @@ public const string UsernameLength = "Your username is too long, please make it shorter."; public const string UsernameIllegalCharacters = "Your username contains illegal characters, please remove them."; + + public const string VersionClientTooOld = "Please update your game to play on this server."; + + public const string VersionServerTooOld = "Your client is too new, please update your Impostor server to play."; + + public const string VersionUnsupported = "Your client version is unsupported, please update your Game and/or Impostor server."; } } diff --git a/src/Impostor.Server/Net/Manager/ClientManager.cs b/src/Impostor.Server/Net/Manager/ClientManager.cs index db9edea..39e5132 100644 --- a/src/Impostor.Server/Net/Manager/ClientManager.cs +++ b/src/Impostor.Server/Net/Manager/ClientManager.cs @@ -1,4 +1,5 @@ -using System.Collections.Concurrent; +using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -18,7 +19,8 @@ namespace Impostor.Server.Net.Manager { internal partial class ClientManager { - private static readonly HashSet SupportedVersions = new HashSet + // NOTE: when updating this array, keep the versions ordered from old to new, otherwise the version compare logic doesn't work properly + private static readonly int[] SupportedVersions = { GameVersion.GetVersion(2021, 4, 25), // 2021.6.15 }; @@ -37,6 +39,14 @@ namespace Impostor.Server.Net.Manager _clients = new ConcurrentDictionary(); } + private enum VersionCompareResult + { + Compatible, + ClientTooOld, + ServerTooOld, + Unknown, + } + public IEnumerable Clients => _clients.Values; public int NextId() @@ -57,13 +67,24 @@ namespace Impostor.Server.Net.Manager public async ValueTask RegisterConnectionAsync(IHazelConnection connection, string name, int clientVersion) { - if (!SupportedVersions.Contains(clientVersion)) + var versionCompare = CompareVersion(clientVersion); + if (versionCompare != VersionCompareResult.Compatible) { GameVersion.ParseVersion(clientVersion, out var year, out var month, out var day, out var revision); _logger.LogTrace("Client connected using unsupported version: {clientVersion} ({version})", clientVersion, $"{year}.{month}.{day}{(revision == 0 ? string.Empty : "." + revision)}"); using var packet = MessageWriter.Get(MessageType.Reliable); - Message01JoinGameS2C.SerializeError(packet, false, DisconnectReason.IncorrectVersion); + + var message = versionCompare switch + { + VersionCompareResult.ClientTooOld => DisconnectMessages.VersionClientTooOld, + VersionCompareResult.ServerTooOld => DisconnectMessages.VersionServerTooOld, + VersionCompareResult.Unknown => DisconnectMessages.VersionUnsupported, + _ => throw new ArgumentOutOfRangeException(), + }; + + Message01JoinGameS2C.SerializeError(packet, false, DisconnectReason.Custom, message); + await connection.SendAsync(packet); return; } @@ -106,5 +127,29 @@ namespace Impostor.Server.Net.Manager && _clients.TryGetValue(client.Id, out var registeredClient) && ReferenceEquals(client, registeredClient); } + + private VersionCompareResult CompareVersion(int clientVersion) + { + foreach (var serverVersion in SupportedVersions) + { + if (clientVersion == serverVersion) + { + return VersionCompareResult.Compatible; + } + } + + if (clientVersion < SupportedVersions[0]) + { + return VersionCompareResult.ClientTooOld; + } + + if (clientVersion > SupportedVersions.Last()) + { + return VersionCompareResult.ServerTooOld; + } + + // This may happen in the very rare case that version X is supported, X+2 is as well, but X+1 is not. + return VersionCompareResult.Unknown; + } } } -- 2.39.5