diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index ae396b2131..8e1bd50801 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -163,28 +163,7 @@ namespace OpenRA internal static void SyncLobbyInfo(string data) { - var session = new Session(); - session.GlobalSettings.Mods = Settings.InitialMods; - - var ys = MiniYaml.FromString(data); - foreach (var y in ys) - { - if (y.Key == "GlobalSettings") - { - FieldLoader.Load(session.GlobalSettings, y.Value); - continue; - } - - int index; - if (!int.TryParse(y.Key, out index)) - continue; // not a player. - - var client = new Session.Client(); - FieldLoader.Load(client, y.Value); - session.Clients.Add(client); - } - - LobbyInfo = session; + LobbyInfo = Session.Deserialize(data); if( !world.GameHasStarted ) world.SharedRandom = new XRandom( LobbyInfo.GlobalSettings.RandomSeed ); diff --git a/OpenRA.Game/Network/Session.cs b/OpenRA.Game/Network/Session.cs index 34b0a2da57..7c0c970e68 100644 --- a/OpenRA.Game/Network/Session.cs +++ b/OpenRA.Game/Network/Session.cs @@ -10,16 +10,14 @@ using System.Collections.Generic; using System.Drawing; +using OpenRA.FileFormats; namespace OpenRA.Network { - // todo: ship most of this back to the Game assembly; - // it was only in FileFormats due to the original server model, - // in a sep. process. - public class Session { public List Clients = new List(); + public List Slots = new List(); public Global GlobalSettings = new Global(); public enum ClientState @@ -40,6 +38,15 @@ namespace OpenRA.Network public int Team; } + public class Slot + { + public int Index; + public string Bot; // trait name of the bot to initialize in this slot, or null otherwise. + public bool Closed; // host has explicitly closed this slot. + + // todo: more stuff? + } + public class Global { public string Map; @@ -49,5 +56,49 @@ namespace OpenRA.Network public bool LockTeams = false; // don't allow team changes after game start. public bool AllowCheats = false; } + + public string Serialize() + { + var clientData = new Dictionary(); + + foreach (var client in Clients) + clientData["Client@{0}".F(client.Index)] = FieldSaver.Save(client); + + foreach (var slot in Slots) + clientData["Slot@{0}".F(slot.Index)] = FieldSaver.Save(slot); + + clientData["GlobalSettings"] = FieldSaver.Save(GlobalSettings); + + return clientData.WriteToString(); + } + + public static Session Deserialize(string data) + { + var session = new Session(); + session.GlobalSettings.Mods = Game.Settings.InitialMods; + + var ys = MiniYaml.FromString(data); + foreach (var y in ys) + { + var yy = y.Key.Split('@'); + + switch( yy[0] ) + { + case "GlobalSettings": + FieldLoader.Load(session.GlobalSettings, y.Value); + break; + + case "Client": + session.Clients.Add(FieldLoader.Load(y.Value)); + break; + + case "Slot": + session.Slots.Add(FieldLoader.Load(y.Value )); + break; + } + } + + return session; + } } } diff --git a/OpenRA.Game/Server/ProtocolVersion.cs b/OpenRA.Game/Server/ProtocolVersion.cs index 99aeaf4916..b187d4ddfb 100644 --- a/OpenRA.Game/Server/ProtocolVersion.cs +++ b/OpenRA.Game/Server/ProtocolVersion.cs @@ -13,6 +13,6 @@ namespace OpenRA.Server public static class ProtocolVersion { // you *must* increment this whenever you make an incompatible protocol change - public static readonly int Version = 5; + public static readonly int Version = 6; } } diff --git a/OpenRA.Game/Server/Server.cs b/OpenRA.Game/Server/Server.cs index ceb7ab8eb0..a8e6e723b9 100644 --- a/OpenRA.Game/Server/Server.cs +++ b/OpenRA.Game/Server/Server.cs @@ -450,14 +450,8 @@ namespace OpenRA.Server static void SyncLobbyInfo() { - var clientData = lobbyInfo.Clients.ToDictionary( - a => a.Index.ToString(), - a => FieldSaver.Save(a)); - - clientData["GlobalSettings"] = FieldSaver.Save(lobbyInfo.GlobalSettings); - DispatchOrders(null, 0, - new ServerOrder("SyncInfo", clientData.WriteToString()).Serialize()); + new ServerOrder("SyncInfo", lobbyInfo.Serialize()).Serialize()); PingMasterServer(); }