From 96b5b1fc660d929a39e88acefcea9ae5d627effe Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 13 Dec 2014 16:00:29 +1300 Subject: [PATCH] Automatically switch mods when connecting to a server / replay. --- OpenRA.Game/Network/OrderManager.cs | 11 +++++++++++ OpenRA.Game/Network/ReplayConnection.cs | 3 +++ OpenRA.Game/Network/UnitOrders.cs | 21 +++++++++++++++++++-- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/OpenRA.Game/Network/OrderManager.cs b/OpenRA.Game/Network/OrderManager.cs index 56f221af6e..b4dd17b7f1 100644 --- a/OpenRA.Game/Network/OrderManager.cs +++ b/OpenRA.Game/Network/OrderManager.cs @@ -51,6 +51,8 @@ namespace OpenRA.Network public readonly ReadOnlyList ChatCache; + bool disposed; + static void OutOfSync(int frame) { throw new InvalidOperationException("Out of sync in frame {0}.\n Compare syncreport.log with other players.".F(frame)); @@ -122,8 +124,16 @@ namespace OpenRA.Network }); foreach (var p in immediatePackets) + { foreach (var o in p.Second.ToOrderList(World)) + { UnitOrders.ProcessOrder(this, World, p.First, o); + + // A mod switch or other event has pulled the ground from beneath us + if (disposed) + return; + } + } } Dictionary syncForFrame = new Dictionary(); @@ -213,6 +223,7 @@ namespace OpenRA.Network public void Dispose() { + disposed = true; if (Connection != null) Connection.Dispose(); } diff --git a/OpenRA.Game/Network/ReplayConnection.cs b/OpenRA.Game/Network/ReplayConnection.cs index 32afbfad6a..5924ff7b6b 100755 --- a/OpenRA.Game/Network/ReplayConnection.cs +++ b/OpenRA.Game/Network/ReplayConnection.cs @@ -33,9 +33,12 @@ namespace OpenRA.Network public readonly int TickCount; public readonly bool IsValid; public readonly Session LobbyInfo; + public readonly string Filename; public ReplayConnection(string replayFilename) { + Filename = replayFilename; + // Parse replay data into a struct that can be fed to the game in chunks // to avoid issues with all immediate orders being resolved on the first tick. using (var rs = File.OpenRead(replayFilename)) diff --git a/OpenRA.Game/Network/UnitOrders.cs b/OpenRA.Game/Network/UnitOrders.cs index a7ff1e32a3..4a1d1d2818 100644 --- a/OpenRA.Game/Network/UnitOrders.cs +++ b/OpenRA.Game/Network/UnitOrders.cs @@ -119,10 +119,27 @@ namespace OpenRA.Network case "HandshakeRequest": { - // TODO: Switch to the server's mod if we have it - // Otherwise send the handshake with our current settings and let the server reject us + // Switch to the server's mod if we need and are able to var mod = Game.modData.Manifest.Mod; + var request = HandshakeRequest.Deserialize(order.TargetString); + ModMetadata serverMod; + if (request.Mod != mod.Id && + ModMetadata.AllMods.TryGetValue(request.Mod, out serverMod) && + serverMod.Version == request.Version) + { + var replay = orderManager.Connection as ReplayConnection; + var launchCommand = replay != null ? + "Launch.Replay=" + replay.Filename : + "Launch.Connect=" + orderManager.Host + ":" + orderManager.Port; + + Game.modData.LoadScreen.Display(); + Game.InitializeMod(request.Mod, new Arguments(launchCommand)); + + break; + } + + // Otherwise send the handshake with our current settings and let the server reject us var info = new Session.Client() { Name = Game.Settings.Player.Name,