From 199f80c8ed8b3e3372110d123c0d8a9c74e9fd24 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 13 Dec 2014 10:34:54 +1300 Subject: [PATCH] Cache GameServer joinable/compatible state across render frames. --- OpenRA.Game/Network/GameServer.cs | 50 +++++++------------ .../Widgets/Logic/ServerBrowserLogic.cs | 27 +++------- 2 files changed, 27 insertions(+), 50 deletions(-) diff --git a/OpenRA.Game/Network/GameServer.cs b/OpenRA.Game/Network/GameServer.cs index 4e6d565ea7..d5b2cb42ec 100644 --- a/OpenRA.Game/Network/GameServer.cs +++ b/OpenRA.Game/Network/GameServer.cs @@ -26,42 +26,30 @@ namespace OpenRA.Network public readonly bool Protected = false; public readonly string Started = null; - public bool CanJoin() + public readonly bool IsCompatible = false; + public readonly bool IsJoinable = false; + + public readonly string ModLabel = ""; + public readonly string ModVersion = ""; + + public GameServer(MiniYaml yaml) { - // "waiting for players" - if (State != 1) - return false; + FieldLoader.Load(this, yaml); - if (!CompatibleVersion()) - return false; - - // Don't have the map locally - // TODO: We allow joining, then drop on game start if the map isn't available - if (Game.modData.MapCache[Map].Status != MapStatus.Available && !Game.Settings.Game.AllowDownloading) - return false; - - return true; - } - - public bool CompatibleVersion() - { - // Invalid game listing - we require one entry of id@version + ModMetadata mod; var modVersion = Mods.Split('@'); - if (modVersion.Length != 2) - return false; + if (modVersion.Length == 2 && ModMetadata.AllMods.TryGetValue(modVersion[0], out mod)) + { + ModLabel = "{0} ({1})".F(mod.Title, modVersion[1]); + ModVersion = modVersion[1]; - var mod = Game.modData.Manifest.Mod; + IsCompatible = Game.Settings.Debug.IgnoreVersionMismatch || (mod.Id == Game.modData.Manifest.Mod.Id && ModVersion == Game.modData.Manifest.Mod.Version); + } + else + ModLabel = "Unknown mod: {0}".F(Mods); - // Different mod - // TODO: Allow mod switch when joining server - if (modVersion[0] != mod.Id) - return false; - - // Same mod, but different version - if (modVersion[1] != mod.Version && !Game.Settings.Debug.IgnoreVersionMismatch) - return false; - - return true; + var mapAvailable = Game.Settings.Game.AllowDownloading || Game.modData.MapCache[Map].Status == MapStatus.Available; + IsJoinable = IsCompatible && State == 1 && mapAvailable; } } } diff --git a/OpenRA.Mods.RA/Widgets/Logic/ServerBrowserLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ServerBrowserLogic.cs index 96bf17574f..9bbf0a2de8 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/ServerBrowserLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/ServerBrowserLogic.cs @@ -69,7 +69,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic panel.Get("CREATE_BUTTON").OnClick = OpenCreateServerPanel; var join = panel.Get("JOIN_BUTTON"); - join.IsDisabled = () => currentServer == null || !currentServer.CanJoin(); + join.IsDisabled = () => currentServer == null || !currentServer.IsJoinable; join.OnClick = () => Join(currentServer); panel.Get("BACK_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); }; @@ -151,7 +151,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic var data = Encoding.UTF8.GetString(i.Result); var yaml = MiniYaml.FromString(data); - var games = yaml.Select(a => FieldLoader.Load(a.Value)) + var games = yaml.Select(a => new GameServer(a.Value)) .Where(gs => gs.Address != null); RefreshServerListInner(games); @@ -168,14 +168,14 @@ namespace OpenRA.Mods.RA.Widgets.Logic var rows = new List(); - foreach (var loop in games.OrderByDescending(g => g.CanJoin()).ThenByDescending(g => g.Players)) + foreach (var loop in games.OrderByDescending(g => g.IsJoinable).ThenByDescending(g => g.Players)) { var game = loop; if (game == null) continue; - var canJoin = game.CanJoin(); - var compatible = game.CompatibleVersion(); + var canJoin = game.IsJoinable; + var compatible = game.IsCompatible; var item = ScrollItemWidget.Setup(serverTemplate, () => currentServer == game, () => currentServer = game, () => Join(game)); @@ -223,7 +223,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic var version = item.GetOrNull("VERSION"); if (version != null) { - version.GetText = () => GenerateModLabel(game); + version.GetText = () => game.ModLabel; version.IsVisible = () => !compatible; version.GetColor = () => !compatible ? Color.DarkGray : !canJoin ? Color.LightGray : version.TextColor; } @@ -300,7 +300,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic void Join(GameServer server) { - if (server == null || !server.CanJoin()) + if (server == null || !server.IsJoinable) return; var host = server.Address.Split(':')[0]; @@ -353,17 +353,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic return label.TextColor; } - public static string GenerateModLabel(GameServer s) - { - ModMetadata mod; - var modVersion = s.Mods.Split('@'); - - if (modVersion.Length == 2 && ModMetadata.AllMods.TryGetValue(modVersion[0], out mod)) - return "{0} ({1})".F(mod.Title, modVersion[1]); - - return "Unknown mod: {0}".F(s.Mods); - } - bool Filtered(GameServer game) { if ((game.State == (int)ServerState.GameStarted) && !showStarted) @@ -375,7 +364,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic if ((game.Players == 0) && !showEmpty) return true; - if (!game.CompatibleVersion() && !showIncompatible) + if (!game.IsCompatible && !showIncompatible) return true; if (game.Protected && !showProtected)