Skip to content
Browse files

Remove runtime mod merging. Closes #3421.

  • Loading branch information...
1 parent 4d893cb commit 6d6d1e230b6cbad87653f7417424bcf59608c5e3 @pchote pchote committed Oct 6, 2013
Showing with 143 additions and 186 deletions.
  1. +3 −0 CHANGELOG
  2. +2 −2 INSTALL
  3. +2 −2 OpenRA.Editor/Form1.cs
  4. +8 −6 OpenRA.FileFormats/Manifest.cs
  5. +0 −8 OpenRA.FileFormats/Mod.cs
  6. +19 −28 OpenRA.Game/Game.cs
  7. +1 −1 OpenRA.Game/GameRules/Settings.cs
  8. +4 −6 OpenRA.Game/ModData.cs
  9. +26 −28 OpenRA.Game/Network/GameServer.cs
  10. +5 −3 OpenRA.Game/Network/Handshake.cs
  11. +1 −1 OpenRA.Game/Network/OrderManager.cs
  12. +2 −1 OpenRA.Game/Network/ReplayRecorderConnection.cs
  13. +3 −10 OpenRA.Game/Network/Session.cs
  14. +1 −1 OpenRA.Game/Network/SyncReport.cs
  15. +8 −2 OpenRA.Game/Network/UnitOrders.cs
  16. +13 −22 OpenRA.Game/Server/Server.cs
  17. +2 −2 OpenRA.Game/Support/Program.cs
  18. +0 −18 OpenRA.Game/Widgets/WidgetUtils.cs
  19. +1 −3 OpenRA.Irc/IrcClient.cs
  20. +2 −2 OpenRA.Lint/YamlChecker.cs
  21. +3 −2 OpenRA.Mods.Cnc/CncLoadScreen.cs
  22. +1 −1 OpenRA.Mods.Cnc/Widgets/Logic/CncIngameMenuLogic.cs
  23. +1 −1 OpenRA.Mods.Cnc/Widgets/Logic/CncInstallMusicLogic.cs
  24. +1 −1 OpenRA.Mods.Cnc/Widgets/Logic/CncMenuLogic.cs
  25. +1 −1 OpenRA.Mods.RA/DefaultLoadScreen.cs
  26. +2 −1 OpenRA.Mods.RA/NullLoadScreen.cs
  27. +3 −3 OpenRA.Mods.RA/ServerTraits/MasterServerPinger.cs
  28. +8 −6 OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs
  29. +1 −1 OpenRA.Mods.RA/Widgets/Logic/DownloadPackagesLogic.cs
  30. +1 −1 OpenRA.Mods.RA/Widgets/Logic/MainMenuButtonsLogic.cs
  31. +3 −5 OpenRA.Mods.RA/Widgets/Logic/ModBrowserLogic.cs
  32. +3 −3 OpenRA.Mods.RA/Widgets/Logic/ReplayBrowserLogic.cs
  33. +7 −9 OpenRA.Mods.RA/Widgets/Logic/ServerBrowserLogic.cs
  34. +4 −4 OpenRA.Utility/Command.cs
  35. +1 −1 launch-dedicated.sh
View
3 CHANGELOG
@@ -76,11 +76,13 @@ NEW:
Added modifier support to hotkeys.
Fixed a desync related to projectile contrails.
Fixed corrupted replays (which would immediately desync).
+ Removed runtime mod merging.
Build system and packages:
Added GeoIP to Makefile so it is installed properly.
Added desktop shortcut creation support to the Makefile and Windows installer.
COPYING and CHANGELOG are now shipped on all platforms.
Fixed 'make docs' crashing when the game assets are not installed.
+ Renamed Game.Mods launch argument to Game.Mod.
Mod / Custom map compatibility:
Mods can now include traits from TD and D2K in RA.
New sections MapFolders and Translations added to mod.yaml.
@@ -99,6 +101,7 @@ NEW:
Removed traits from World: SpatialBins.
Added InvalidTargets property to weapons.
Added modifier support for build palette hotkeys.
+ The Requires: option for inheriting from a parent mod has been removed. Mods can directly reference the parent mod files instead.
20130915:
All mods:
View
4 INSTALL
@@ -29,8 +29,8 @@ or build it from the command-line with MSBuild.
Copy both the native DLLs from .\packaging\windows
and the CLI images from .\thirdparty to the main folder.
-Run the game with `OpenRA.Game.exe Game.Mods=ra` for Red Alert
-or `OpenRA.Game.exe Game.Mods=cnc` for Command & Conquer
+Run the game with `OpenRA.Game.exe Game.Mod=ra` for Red Alert
+or `OpenRA.Game.exe Game.Mod=cnc` for Command & Conquer
Debian/Ubuntu
-------------
View
4 OpenRA.Editor/Form1.cs
@@ -50,8 +50,8 @@ public Form1(string[] args)
FileSystem.LoadFromManifest(Game.modData.Manifest);
Rules.LoadRules(Game.modData.Manifest, new Map());
- var mod = Game.modData.Manifest.Mods[0];
- Text = "{0} Mod Version: {1} - OpenRA Editor".F(Mod.AllMods[mod].Title, Mod.AllMods[mod].Version);
+ var mod = Game.modData.Manifest.Mod;
+ Text = "{0} Mod Version: {1} - OpenRA Editor".F(mod.Title, mod.Version);
loadedMapName = null;
};
View
14 OpenRA.FileFormats/Manifest.cs
@@ -18,8 +18,9 @@ namespace OpenRA.FileFormats
public class Manifest
{
+ public readonly Mod Mod;
public readonly string[]
- Mods, Folders, MapFolders, Rules, ServerTraits,
+ Folders, MapFolders, Rules, ServerTraits,
Sequences, VoxelSequences, Cursors, Chrome, Assemblies, ChromeLayout,
Weapons, Voices, Notifications, Music, Movies, Translations, TileSets,
ChromeMetrics, PackageContents;
@@ -30,12 +31,13 @@ public class Manifest
public readonly Dictionary<string, Pair<string,int>> Fonts;
public readonly int TileSize = 24;
- public Manifest(string[] mods)
+ public Manifest(string mod)
{
- Mods = mods;
- var yaml = new MiniYaml(null, mods
- .Select(m => MiniYaml.FromFile("mods{0}{1}{0}mod.yaml".F(Path.DirectorySeparatorChar, m)))
- .Aggregate(MiniYaml.MergeLiberal)).NodesDict;
+ var path = new [] { "mods", mod, "mod.yaml" }.Aggregate(Path.Combine);
+ var yaml = new MiniYaml(null, MiniYaml.FromFile(path)).NodesDict;
+
+ Mod = FieldLoader.Load<Mod>(yaml["Metadata"]);
+ Mod.Id = mod;
// TODO: Use fieldloader
Folders = YamlList(yaml, "Folders");
View
8 OpenRA.FileFormats/Mod.cs
@@ -21,7 +21,6 @@ public class Mod
public string Description;
public string Version;
public string Author;
- public string Requires;
public static readonly Dictionary<string, Mod> AllMods = ValidateMods(Directory.GetDirectories("mods").Select(x => x.Substring(5)).ToArray());
@@ -45,12 +44,5 @@ public class Mod
}
return ret;
}
-
- public string[] WithPrerequisites()
- {
- return Id.Iterate(m => AllMods[m].Requires)
- .TakeWhile(m => m != null)
- .ToArray();
- }
}
}
View
47 OpenRA.Game/Game.cs
@@ -255,18 +255,6 @@ public static bool IsHost
}
}
- public static Dictionary<String, Mod> CurrentMods
- {
- get
- {
- // Initialization hasn't completed yet
- if (Mod.AllMods == null || modData == null)
- return null;
-
- return Mod.AllMods.Where(k => modData.Manifest.Mods.Contains(k.Key)).ToDictionary(k => k.Key, k => k.Value);
- }
- }
-
static Modifiers modifiers;
public static Modifiers GetModifierKeys() { return modifiers; }
internal static void HandleModifierKeys(Modifiers mods) { modifiers = mods; }
@@ -328,7 +316,8 @@ internal static void Initialize(Arguments args)
Console.WriteLine("Available mods:");
foreach(var mod in Mod.AllMods)
Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Title, mod.Value.Version);
- InitializeWithMods(Settings.Game.Mods);
+
+ InitializeWithMod(Settings.Game.Mod);
if (Settings.Server.DiscoverNatDevices)
{
@@ -338,7 +327,7 @@ internal static void Initialize(Arguments args)
}
}
- public static void InitializeWithMods(string[] mods)
+ public static void InitializeWithMod(string mod)
{
// Clear static state if we have switched mods
LobbyInfoChanged = () => {};
@@ -353,17 +342,18 @@ public static void InitializeWithMods(string[] mods)
if (orderManager != null)
orderManager.Dispose();
- // Discard any invalid mods, set RA as default
- var mm = mods.Where( m => Mod.AllMods.ContainsKey( m ) ).ToArray();
- if (mm.Length == 0) mm = new[] { "ra" };
- Console.WriteLine("Loading mods: {0}", mm.JoinWith(","));
- Settings.Game.Mods = mm;
+ // Fall back to RA if the mod doesn't exist
+ if (!Mod.AllMods.ContainsKey(mod))
+ mod = "ra";
+
+ Console.WriteLine("Loading mod: {0}", mod);
+ Settings.Game.Mod = mod;
Sound.StopMusic();
Sound.StopVideo();
Sound.Initialize();
- modData = new ModData(mm);
+ modData = new ModData(mod);
Renderer.InitializeFonts(modData.Manifest);
modData.InitializeLoaders();
@@ -480,8 +470,7 @@ public static T CreateObject<T>( string name )
public static void CreateServer(ServerSettings settings)
{
- server = new Server.Server(new IPEndPoint(IPAddress.Any, settings.ListenPort),
- Settings.Game.Mods, settings, modData);
+ server = new Server.Server(new IPEndPoint(IPAddress.Any, settings.ListenPort), settings, modData);
}
public static int CreateLocalServer(string map)
@@ -494,8 +483,7 @@ public static int CreateLocalServer(string map)
AllowPortForward = false
};
- server = new Server.Server(new IPEndPoint(IPAddress.Loopback, 0),
- Settings.Game.Mods, settings, modData);
+ server = new Server.Server(new IPEndPoint(IPAddress.Loopback, 0), settings, modData);
return server.Port;
}
@@ -509,16 +497,19 @@ public static bool DownloadMap(string mapHash)
{
try
{
- var mod = CurrentMods.First().Value.Id;
- var dirPath = "{1}maps{0}{2}".F(Path.DirectorySeparatorChar, Platform.SupportDir, mod);
- if(!Directory.Exists(dirPath))
+ var mod = Game.modData.Manifest.Mod;
+ var dirPath = new [] { Platform.SupportDir, "maps", mod.Id }.Aggregate(Path.Combine);
+ if (!Directory.Exists(dirPath))
Directory.CreateDirectory(dirPath);
- var mapPath = "{1}{0}{2}".F(Path.DirectorySeparatorChar, dirPath, mapHash+".oramap");
+
+ var mapPath = Path.Combine(dirPath, mapHash+".oramap");
Console.Write("Trying to download map to {0} ... ".F(mapPath));
+
WebClient webClient = new WebClient();
webClient.DownloadFile(Game.Settings.Game.MapRepository + mapHash, mapPath);
Game.modData.AvailableMaps.Add(mapHash, new Map(mapPath));
Console.WriteLine("done");
+
return true;
}
catch (WebException e)
View
2 OpenRA.Game/GameRules/Settings.cs
@@ -124,7 +124,7 @@ public class PlayerSettings
public class GameSettings
{
- public string[] Mods = { "ra" };
+ public string Mod = "ra";
public bool ShowShellmap = true;
View
10 OpenRA.Game/ModData.cs
@@ -50,13 +50,13 @@ public static IEnumerable<string> FindMapsIn(string dir)
return dirsWithMaps.Concat(Directory.GetFiles(dir, "*.oramap"));
}
- public ModData(params string[] mods)
+ public ModData(string mod)
{
Languages = new string[0];
- Manifest = new Manifest(mods);
+ Manifest = new Manifest(mod);
ObjectCreator = new ObjectCreator(Manifest);
LoadScreen = ObjectCreator.CreateObject<ILoadScreen>(Manifest.LoadScreen.Value);
- LoadScreen.Init(Manifest.LoadScreen.NodesDict.ToDictionary(x => x.Key, x => x.Value.Value));
+ LoadScreen.Init(Manifest, Manifest.LoadScreen.NodesDict.ToDictionary(x => x.Key, x => x.Value.Value));
LoadScreen.Display();
WidgetLoader = new WidgetLoader(this);
@@ -149,9 +149,7 @@ public Map PrepareMap(string uid)
Dictionary<string, Map> FindMaps()
{
var paths = Manifest.MapFolders.SelectMany(f => FindMapsIn(f));
-
var ret = new Dictionary<string, Map>();
-
foreach (var path in paths)
{
try
@@ -177,7 +175,7 @@ public Map FindMapByUid(string uid)
public interface ILoadScreen
{
- void Init(Dictionary<string, string> info);
+ void Init(Manifest m, Dictionary<string, string> info);
void Display();
void StartGame();
}
View
54 OpenRA.Game/Network/GameServer.cs
@@ -21,49 +21,47 @@ public class GameServer
public readonly int State = 0;
public readonly int Players = 0;
public readonly string Map = null;
- public readonly string[] Mods = { };
- public readonly int TTL = 0;
-
- public Dictionary<string, string> UsefulMods
- {
- get
- {
- return Mods
- .Where(v => v.Contains('@'))
- .ToDictionary(v => v.Split('@')[0], v => v.Split('@')[1]);
- }
- }
- static bool AreVersionsCompatible(string a, string b)
- {
- if (Game.Settings.Debug.IgnoreVersionMismatch)
- return true;
-
- return a == b;
- }
+ // Retained name compatibility with the master server
+ public readonly string Mods = "";
+ public readonly int TTL = 0;
public bool CanJoin()
{
- //"waiting for players"
+ // "waiting for players"
if (State != 1)
return false;
- // Mods won't match if there are a different number
- if (Game.CurrentMods.Count != Mods.Count())
+ if (!CompatibleVersion())
return false;
// Don't have the map locally
- if (!Game.modData.AvailableMaps.ContainsKey(Map))
- if (!Game.Settings.Game.AllowDownloading)
- return false;
+ // TODO: We allow joining, then drop on game start if the map isn't available
+ if (!Game.modData.AvailableMaps.ContainsKey(Map) && !Game.Settings.Game.AllowDownloading)
+ return false;
- return CompatibleVersion();
+ return true;
}
public bool CompatibleVersion()
{
- return UsefulMods.All(m => Game.CurrentMods.ContainsKey(m.Key)
- && AreVersionsCompatible(m.Value, Game.CurrentMods[m.Key].Version));
+ // Invalid game listing - we require one entry of id@version
+ var modVersion = Mods.Split('@');
+ if (modVersion.Length != 2)
+ return false;
+
+ var mod = Game.modData.Manifest.Mod;
+
+ // 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;
}
}
}
View
8 OpenRA.Game/Network/Handshake.cs
@@ -16,7 +16,8 @@ namespace OpenRA.Network
{
public class HandshakeRequest
{
- public string[] Mods;
+ public string Mod;
+ public string Version;
public string Map;
public string Serialize()
@@ -36,15 +37,16 @@ public static HandshakeRequest Deserialize(string data)
public class HandshakeResponse
{
- public string[] Mods;
+ public string Mod;
+ public string Version;
public string Password;
[FieldLoader.Ignore] public Session.Client Client;
public string Serialize()
{
var data = new List<MiniYamlNode>();
data.Add( new MiniYamlNode( "Handshake", null,
- new string[]{ "Mods", "Password" }.Select( p => FieldSaver.SaveField(this, p) ).ToList() ) );
+ new string[]{ "Mod", "Version", "Password" }.Select( p => FieldSaver.SaveField(this, p) ).ToList() ) );
data.Add(new MiniYamlNode("Client", FieldSaver.Save(Client)));
return data.WriteToString();
View
2 OpenRA.Game/Network/OrderManager.cs
@@ -20,7 +20,7 @@ public class OrderManager : IDisposable
readonly SyncReport syncReport;
readonly FrameData frameData = new FrameData();
- public Session LobbyInfo = new Session(Game.Settings.Game.Mods);
+ public Session LobbyInfo = new Session();
public Session.Client LocalClient { get { return LobbyInfo.ClientWithIndex(Connection.LocalClientId); } }
public World world;
View
3 OpenRA.Game/Network/ReplayRecorderConnection.cs
@@ -34,7 +34,8 @@ public ReplayRecorderConnection(IConnection inner, Func<string> chooseFilename)
void StartSavingReplay(byte[] initialContent)
{
var filename = chooseFilename();
- var dir = new[] { Platform.SupportDir, "Replays", WidgetUtils.ActiveModId(), WidgetUtils.ActiveModVersion() }.Aggregate(Path.Combine);
+ var mod = Game.modData.Manifest.Mod;
+ var dir = new[] { Platform.SupportDir, "Replays", mod.Id, mod.Version }.Aggregate(Path.Combine);
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
View
13 OpenRA.Game/Network/Session.cs
@@ -28,7 +28,7 @@ public static Session Deserialize(string data)
{
try
{
- var session = new Session(Game.Settings.Game.Mods);
+ var session = new Session();
var ys = MiniYaml.FromString(data);
foreach (var y in ys)
@@ -123,10 +123,9 @@ public class Global
{
public string ServerName;
public string Map;
- public string[] Mods = { "ra" }; // mod names
- public int OrderLatency = 3; // net tick frames (x 120 = ms)
+ public int OrderLatency = 3; // net tick frames (x 120 = ms)
public int RandomSeed = 0;
- public bool FragileAlliances = false; // Allow diplomatic stance changes after game start.
+ public bool FragileAlliances = false; // Allow diplomatic stance changes after game start.
public bool AllowCheats = false;
public bool Dedicated;
public string Difficulty;
@@ -140,12 +139,6 @@ public class Global
public string GameUid;
}
- public Session(string[] mods)
- {
- this.GlobalSettings.Mods = mods.ToArray();
- this.GlobalSettings.GameUid = Guid.NewGuid().ToString();
- }
-
public string Serialize()
{
var clientData = new List<MiniYamlNode>();
View
2 OpenRA.Game/Network/SyncReport.cs
@@ -178,8 +178,8 @@ internal void DumpSyncReport(int frame)
{
if (r.Frame == frame)
{
+ var mod = Game.modData.Manifest.Mod;
Log.Write("sync", "Player: {0} ({1} {2} {3})", Game.Settings.Player.Name, Platform.CurrentPlatform, Environment.OSVersion, Platform.RuntimeVersion);
- var mod = Game.CurrentMods.First().Value;
Log.Write("sync", "Game ID: {0} (Mod: {1} at Version {2})", orderManager.LobbyInfo.GlobalSettings.GameUid, mod.Title, mod.Version);
Log.Write("sync", "Sync for net frame {0} -------------", r.Frame);
Log.Write("sync", "SharedRandom: {0} (#{1})", r.SyncedRandom, r.TotalCount);
View
10 OpenRA.Game/Network/UnitOrders.cs
@@ -119,9 +119,14 @@ public static void ProcessOrder(OrderManager orderManager, World world, int clie
case "HandshakeRequest":
{
var request = HandshakeRequest.Deserialize(order.TargetString);
- var localMods = orderManager.LobbyInfo.GlobalSettings.Mods.Select(m => "{0}@{1}".F(m, Mod.AllMods[m].Version)).ToArray();
+
+ // 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
+ var mod = Game.modData.Manifest.Mod;
// Check that the map exists on the client
+ // TODO: This will behave badly if joining a server with a different mod
+ // This needs to occur *after* joining the server
if (!Game.modData.AvailableMaps.ContainsKey(request.Map))
{
if (Game.Settings.Game.AllowDownloading)
@@ -144,7 +149,8 @@ public static void ProcessOrder(OrderManager orderManager, World world, int clie
var response = new HandshakeResponse()
{
Client = info,
- Mods = localMods,
+ Mod = mod.Id,
+ Version = mod.Version,
Password = orderManager.Password
};
View
35 OpenRA.Game/Server/Server.cs
@@ -95,7 +95,7 @@ public void EndGame()
t.GameEnded(this);
}
- public Server(IPEndPoint endpoint, string[] mods, ServerSettings settings, ModData modData)
+ public Server(IPEndPoint endpoint, ServerSettings settings, ModData modData)
{
Log.AddChannel("server", "server.log");
@@ -117,7 +117,7 @@ public Server(IPEndPoint endpoint, string[] mods, ServerSettings settings, ModDa
foreach (var trait in modData.Manifest.ServerTraits)
serverTraits.Add(modData.ObjectCreator.CreateObject<ServerTrait>(trait));
- LobbyInfo = new Session(mods);
+ LobbyInfo = new Session();
LobbyInfo.GlobalSettings.RandomSeed = randomSeed;
LobbyInfo.GlobalSettings.Map = settings.Map;
LobbyInfo.GlobalSettings.ServerName = settings.Name;
@@ -127,10 +127,7 @@ public Server(IPEndPoint endpoint, string[] mods, ServerSettings settings, ModDa
foreach (var t in serverTraits.WithInterface<INotifyServerStart>())
t.ServerStarted(this);
- Log.Write("server", "Initial mods: ");
- foreach (var m in LobbyInfo.GlobalSettings.Mods)
- Log.Write("server", "- {0}", m);
-
+ Log.Write("server", "Initial mod: {0}", ModData.Manifest.Mod.Id);
Log.Write("server", "Initial map: {0}", LobbyInfo.GlobalSettings.Map);
new Thread(_ =>
@@ -226,9 +223,11 @@ void AcceptConnection()
// Dispatch a handshake order
var request = new HandshakeRequest()
{
- Map = LobbyInfo.GlobalSettings.Map,
- Mods = LobbyInfo.GlobalSettings.Mods.Select(m => "{0}@{1}".F(m, Mod.AllMods[m].Version)).ToArray()
+ Mod = ModData.Manifest.Mod.Id,
+ Version = ModData.Manifest.Mod.Version,
+ Map = LobbyInfo.GlobalSettings.Map
};
+
DispatchOrdersToClient(newConn, 0, 0, new ServerOrder("HandshakeRequest", request.Serialize()).Serialize());
}
catch (Exception e)
@@ -282,13 +281,7 @@ void ValidateClient(Connection newConn, string data)
else
client.Color = HSLColor.FromRGB(255, 255, 255);
- // Check that the client has compatible mods
- var mods = handshake.Mods;
- var validMod = mods.All(m => m.Contains('@')) && // valid format
- mods.Count() == Game.CurrentMods.Count() && // same number
- mods.Select(m => Pair.New(m.Split('@')[0], m.Split('@')[1])).All(kv => Game.CurrentMods.ContainsKey(kv.First));
-
- if (!validMod)
+ if (ModData.Manifest.Mod.Id != handshake.Mod)
{
Log.Write("server", "Rejected connection from {0}; mods do not match.",
newConn.socket.RemoteEndPoint);
@@ -298,10 +291,7 @@ void ValidateClient(Connection newConn, string data)
return;
}
- var validVersion = mods.Select(m => Pair.New(m.Split('@')[0], m.Split('@')[1])).All(
- kv => kv.Second == Game.CurrentMods[kv.First].Version);
-
- if (!validVersion && !LobbyInfo.GlobalSettings.AllowVersionMismatch)
+ if (ModData.Manifest.Mod.Version != handshake.Version && !LobbyInfo.GlobalSettings.AllowVersionMismatch)
{
Log.Write("server", "Rejected connection from {0}; Not running the same version.",
newConn.socket.RemoteEndPoint);
@@ -338,13 +328,14 @@ void ValidateClient(Connection newConn, string data)
// Send initial ping
SendOrderTo(newConn, "Ping", Environment.TickCount.ToString());
- if (File.Exists("{0}motd_{1}.txt".F(Platform.SupportDir, LobbyInfo.GlobalSettings.Mods[0])))
+ var motdPath = Path.Combine(Platform.SupportDir, "motd_{0}.txt".F(ModData.Manifest.Mod.Id));
+ if (File.Exists(motdPath))
{
- var motd = File.ReadAllText("{0}motd_{1}.txt".F(Platform.SupportDir, LobbyInfo.GlobalSettings.Mods[0]));
+ var motd = System.IO.File.ReadAllText(motdPath);
SendOrderTo(newConn, "Message", motd);
}
- if (mods.Any(m => m.Contains("{DEV_VERSION}")))
+ if (handshake.Mod == "{DEV_VERSION}")
SendMessage("{0} is running an unversioned development build, ".F(client.Name) +
"and may desynchronize the game state if they have incompatible rules.");
View
4 OpenRA.Game/Support/Program.cs
@@ -47,9 +47,9 @@ static void FatalError(Exception e)
{
Log.AddChannel("exception", "exception.log");
- if (Game.CurrentMods != null)
+ if (Game.modData != null)
{
- var mod = Game.CurrentMods.First().Value;
+ var mod = Game.modData.Manifest.Mod;
Log.Write("exception", "{0} Mod at Version {1}", mod.Title, mod.Version);
}
View
18 OpenRA.Game/Widgets/WidgetUtils.cs
@@ -225,24 +225,6 @@ public static string WrapText(string text, int width, SpriteFont font)
public static Action Once( Action a ) { return () => { if (a != null) { a(); a = null; } }; }
- public static string ActiveModVersion()
- {
- var mod = Game.modData.Manifest.Mods[0];
- return Mod.AllMods[mod].Version;
- }
-
- public static string ActiveModTitle()
- {
- var mod = Game.modData.Manifest.Mods[0];
- return Mod.AllMods[mod].Title;
- }
-
- public static string ActiveModId()
- {
- var mod = Game.modData.Manifest.Mods[0];
- return Mod.AllMods[mod].Id;
- }
-
public static string ChooseInitialMap(string map)
{
var availableMaps = Game.modData.AvailableMaps;
View
4 OpenRA.Irc/IrcClient.cs
@@ -70,9 +70,7 @@ static void InstanceInitialize()
var command = split[0];
if (command.EqualsIC("VERSION"))
{
- var mod = Game.CurrentMods.Values.FirstOrDefault();
- if (mod == null)
- return;
+ var mod = Game.modData.Manifest.Mod;
Instance.CtcpRespond(l.Prefix.Nickname, command, "{0}: {1}".F(mod.Title, mod.Version));
}
};
View
4 OpenRA.Lint/YamlChecker.cs
@@ -35,7 +35,7 @@ static int Main(string[] args)
try
{
var options = args.Where(a => a.StartsWith("-"));
- var mods = args.Where(a => !options.Contains(a)).ToArray();
+ var mod = args.Where(a => !options.Contains(a)).First();
var verbose = options.Contains("-v") || options.Contains("--verbose");
@@ -44,7 +44,7 @@ static int Main(string[] args)
FieldLoader.UnknownFieldAction = (s, f) => EmitError("FieldLoader: Missing field `{0}` on `{1}`".F(s, f.Name));
AppDomain.CurrentDomain.AssemblyResolve += FileSystem.ResolveAssembly;
- Game.modData = new ModData(mods);
+ Game.modData = new ModData(mod);
Rules.LoadRules(Game.modData.Manifest, new Map());
foreach (var customPassType in Game.modData.ObjectCreator
View
5 OpenRA.Mods.Cnc/CncLoadScreen.cs
@@ -29,7 +29,7 @@ public class CncLoadScreen : ILoadScreen
Renderer r;
NullInputHandler nih = new NullInputHandler();
- public void Init(Dictionary<string, string> info)
+ public void Init(Manifest m, Dictionary<string, string> info)
{
loadInfo = info;
@@ -63,6 +63,8 @@ public void Init(Dictionary<string, string> info)
brightBlock = new Sprite(s, new Rectangle(320, 0, 16, 35), TextureChannel.Alpha);
dimBlock = new Sprite(s, new Rectangle(336, 0, 16, 35), TextureChannel.Alpha);
+
+ versionText = m.Mod.Version;
}
bool setup;
@@ -93,7 +95,6 @@ public void Display()
loadingPos = new float2((bounds.Width - loadingFont.Measure(loadingText).X) / 2, barY);
versionFont = r.Fonts["Regular"];
- versionText = WidgetUtils.ActiveModVersion();
var versionSize = versionFont.Measure(versionText);
versionPos = new float2(bounds.Width - 107 - versionSize.X / 2, 115 - versionSize.Y / 2);
View
2 OpenRA.Mods.Cnc/Widgets/Logic/CncIngameMenuLogic.cs
@@ -30,7 +30,7 @@ public CncIngameMenuLogic(Widget widget, World world, Action onExit, WorldRender
var mpe = world.WorldActor.Trait<CncMenuPaletteEffect>();
mpe.Fade(CncMenuPaletteEffect.EffectType.Desaturated);
- menu.Get<LabelWidget>("VERSION_LABEL").GetText = WidgetUtils.ActiveModVersion;
+ menu.Get<LabelWidget>("VERSION_LABEL").Text = Game.modData.Manifest.Mod.Version;
bool hideButtons = false;
menu.Get("MENU_BUTTONS").IsVisible = () => !hideButtons;
View
2 OpenRA.Mods.Cnc/Widgets/Logic/CncInstallMusicLogic.cs
@@ -29,7 +29,7 @@ public CncInstallMusicLogic(Widget widget, Action onExit)
{
try
{
- var path = new string[] { Platform.SupportDir, "Content", WidgetUtils.ActiveModId() }.Aggregate(Path.Combine);
+ var path = new string[] { Platform.SupportDir, "Content", Game.modData.Manifest.Mod.Id }.Aggregate(Path.Combine);
FileSystem.Mount(Path.Combine(path, "scores.mix"));
FileSystem.Mount(Path.Combine(path, "transit.mix"));
View
2 OpenRA.Mods.Cnc/Widgets/Logic/CncMenuLogic.cs
@@ -28,7 +28,7 @@ public CncMenuLogic(Widget widget, World world)
.Fade(CncMenuPaletteEffect.EffectType.Desaturated);
rootMenu = widget.Get("MENU_BACKGROUND");
- rootMenu.Get<LabelWidget>("VERSION_LABEL").GetText = WidgetUtils.ActiveModVersion;
+ rootMenu.Get<LabelWidget>("VERSION_LABEL").Text = Game.modData.Manifest.Mod.Version;
// Menu buttons
var mainMenu = widget.Get("MAIN_MENU");
View
2 OpenRA.Mods.RA/DefaultLoadScreen.cs
@@ -28,7 +28,7 @@ public class DefaultLoadScreen : ILoadScreen
Sprite stripe, logo;
string[] messages;
- public void Init(Dictionary<string, string> info)
+ public void Init(Manifest m, Dictionary<string, string> info)
{
this.info = info;
View
3 OpenRA.Mods.RA/NullLoadScreen.cs
@@ -9,13 +9,14 @@
#endregion
using System.Collections.Generic;
+using OpenRA.FileFormats;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA
{
public class NullLoadScreen : ILoadScreen
{
- public void Init(Dictionary<string, string> info) {}
+ public void Init(Manifest m, Dictionary<string, string> info) {}
public void Display()
{
View
6 OpenRA.Mods.RA/ServerTraits/MasterServerPinger.cs
@@ -50,6 +50,7 @@ public void PingMasterServer(S server)
lastPing = Environment.TickCount;
isBusy = true;
+ var mod = server.ModData.Manifest.Mod;
Action a = () =>
{
try
@@ -60,14 +61,13 @@ public void PingMasterServer(S server)
using (var wc = new WebClient())
{
wc.Proxy = null;
-
- wc.DownloadData(
+ wc.DownloadData(
server.Settings.MasterServer + url.F(
server.Settings.ExternalPort, Uri.EscapeUriString(server.Settings.Name),
(int)server.State,
server.LobbyInfo.Clients.Where(c1 => c1.Bot == null).Count(),
server.LobbyInfo.Clients.Where(c1 => c1.Bot != null).Count(),
- Game.CurrentMods.Select(f => "{0}@{1}".F(f.Key, f.Value.Version)).JoinWith(","),
+ "{0}@{1}".F(mod.Id, mod.Version),
server.LobbyInfo.GlobalSettings.Map,
server.Map.PlayerCount));
View
14 OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs
@@ -99,14 +99,16 @@ public AssetBrowserLogic(Widget widget, Action onExit, World world)
template = panel.Get<ScrollItemWidget>("ASSET_TEMPLATE");
PopulateAssetList();
- var palette = (WidgetUtils.ActiveModId() == "d2k") ? "d2k.pal" : "egopal.pal";
+ // TODO: Horrible hack
+ var modID = Game.modData.Manifest.Mod.Id;
+ var palette = (modID == "d2k") ? "d2k.pal" : "egopal.pal";
panel.Get<ButtonWidget>("EXPORT_BUTTON").OnClick = () =>
{
var ExtractGameFiles = new string[][]
{
- new string[] {"--extract", WidgetUtils.ActiveModId(), palette, "--userdir"},
- new string[] {"--extract", WidgetUtils.ActiveModId(), "{0}.shp".F(spriteImage.Image), "--userdir"},
+ new string[] {"--extract", modID, palette, "--userdir"},
+ new string[] {"--extract", modID, "{0}.shp".F(spriteImage.Image), "--userdir"},
};
var ExportToPng = new string[][]
@@ -131,11 +133,11 @@ public AssetBrowserLogic(Widget widget, Action onExit, World world)
var ExtractGameFilesList = new List<string[]>();
var ExportToPngList = new List<string[]>();
- ExtractGameFilesList.Add(new string[] { "--extract", WidgetUtils.ActiveModId(), palette, "--userdir"} );
+ ExtractGameFilesList.Add(new string[] { "--extract", modID, palette, "--userdir"} );
foreach (var shp in AvailableShps)
{
- ExtractGameFilesList.Add(new string[] { "--extract", WidgetUtils.ActiveModId(), shp, "--userdir" } );
+ ExtractGameFilesList.Add(new string[] { "--extract", modID, shp, "--userdir" } );
ExportToPngList.Add(new string[] { "--png", Platform.SupportDir+shp, Platform.SupportDir+palette } );
Console.WriteLine(Platform.SupportDir+shp);
}
@@ -148,7 +150,7 @@ public AssetBrowserLogic(Widget widget, Action onExit, World world)
{
{ "ExtractGameFiles", ExtractGameFiles },
{ "ExportToPng", ExportToPng },
- { "ImportFromPng", ImportFromPng}
+ { "ImportFromPng", ImportFromPng }
};
Ui.OpenWindow("CONVERT_ASSETS_PANEL", args);
View
2 OpenRA.Mods.RA/Widgets/Logic/DownloadPackagesLogic.cs
@@ -51,7 +51,7 @@ void ShowDownloadDialog()
// Save the package to a temp file
var file = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
- var dest = new string[] { Platform.SupportDir, "Content", Game.modData.Manifest.Mods[0] }.Aggregate(Path.Combine);
+ var dest = new string[] { Platform.SupportDir, "Content", Game.modData.Manifest.Mod.Id }.Aggregate(Path.Combine);
Action<DownloadProgressChangedEventArgs> onDownloadProgress = i =>
{
View
2 OpenRA.Mods.RA/Widgets/Logic/MainMenuButtonsLogic.cs
@@ -27,7 +27,7 @@ public MainMenuButtonsLogic(Widget widget)
var versionLabel = Ui.Root.GetOrNull<LabelWidget>("VERSION_LABEL");
if (versionLabel != null)
- versionLabel.GetText = WidgetUtils.ActiveModVersion;
+ versionLabel.Text = Game.modData.Manifest.Mod.Version;
widget.Get<ButtonWidget>("MAINMENU_BUTTON_JOIN").OnClick = () => OpenGamePanel("JOINSERVER_BG");
widget.Get<ButtonWidget>("MAINMENU_BUTTON_CREATE").OnClick = () => OpenGamePanel("CREATESERVER_BG");
View
8 OpenRA.Mods.RA/Widgets/Logic/ModBrowserLogic.cs
@@ -26,10 +26,10 @@ public ModBrowserLogic(Widget widget, Action onSwitch, Action onExit)
var modList = panel.Get<ScrollPanelWidget>("MOD_LIST");
var loadButton = panel.Get<ButtonWidget>("LOAD_BUTTON");
loadButton.OnClick = () => LoadMod(currentMod.Id, onSwitch);
- loadButton.IsDisabled = () => currentMod.Id == Game.CurrentMods.Keys.First();
+ loadButton.IsDisabled = () => currentMod.Id == Game.modData.Manifest.Mod.Id;
panel.Get<ButtonWidget>("BACK_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); };
- currentMod = Mod.AllMods[Game.modData.Manifest.Mods[0]];
+ currentMod = Game.modData.Manifest.Mod;
// Mod list
var modTemplate = modList.Get<ScrollItemWidget>("MOD_TEMPLATE");
@@ -47,13 +47,11 @@ public ModBrowserLogic(Widget widget, Action onSwitch, Action onExit)
void LoadMod(string mod, Action onSwitch)
{
- var mods = Mod.AllMods[mod].WithPrerequisites();
-
Game.RunAfterTick(() =>
{
Ui.CloseWindow();
onSwitch();
- Game.InitializeWithMods(mods);
+ Game.InitializeWithMod(mod);
});
}
}
View
6 OpenRA.Mods.RA/Widgets/Logic/ReplayBrowserLogic.cs
@@ -28,11 +28,11 @@ public ReplayBrowserLogic(Widget widget, Action onExit, Action onStart)
panel.Get<ButtonWidget>("CANCEL_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); };
var rl = panel.Get<ScrollPanelWidget>("REPLAY_LIST");
-
- var dir = new[] { Platform.SupportDir, "Replays", WidgetUtils.ActiveModId(), WidgetUtils.ActiveModVersion() }.Aggregate(Path.Combine);
-
var template = panel.Get<ScrollItemWidget>("REPLAY_TEMPLATE");
+ var mod = Game.modData.Manifest.Mod;
+ var dir = new[] { Platform.SupportDir, "Replays", mod.Id, mod.Version }.Aggregate(Path.Combine);
+
rl.RemoveChildren();
if (Directory.Exists(dir))
{
View
16 OpenRA.Mods.RA/Widgets/Logic/ServerBrowserLogic.cs
@@ -149,17 +149,15 @@ Map GetMapPreview(GameServer game)
return (game == null) ? null : Game.modData.FindMapByUid(game.Map);
}
- static string GenerateModLabel(KeyValuePair<string,string> mod)
+ public static string GenerateModLabel(GameServer s)
{
- if (Mod.AllMods.ContainsKey(mod.Key))
- return "{0} ({1})".F(Mod.AllMods[mod.Key].Title, mod.Value);
+ Mod mod;
+ var modVersion = s.Mods.Split('@');
- return "Unknown Mod: {0}".F(mod.Key);
- }
+ if (modVersion.Length == 2 && Mod.AllMods.TryGetValue(modVersion[0], out mod))
+ return "{0} ({1})".F(mod.Title, modVersion[1]);
- public static string GenerateModsLabel(GameServer s)
- {
- return s.UsefulMods.Select(m => GenerateModLabel(m)).JoinWith("\n");
+ return "Unknown mod: {0}".F(s.Mods);
}
bool Filtered(GameServer game)
@@ -237,7 +235,7 @@ public void RefreshServerList(Widget panel, IEnumerable<GameServer> games)
ip.GetText = () => game.Address;
var version = item.Get<LabelWidget>("VERSION");
- version.GetText = () => GenerateModsLabel(game);
+ version.GetText = () => GenerateModLabel(game);
version.IsVisible = () => !game.CompatibleVersion();
var location = item.Get<LabelWidget>("LOCATION");
View
8 OpenRA.Utility/Command.cs
@@ -176,12 +176,12 @@ public static void ConvertR8ToPng(string[] args)
public static void ConvertTmpToPng(string[] args)
{
- var mods = args[1].Split(',');
+ var mod = args[1];
var theater = args[2];
var templateNames = args.Skip(3);
var shadowIndex = new int[] { 3, 4 };
- var manifest = new Manifest(mods);
+ var manifest = new Manifest(mod);
FileSystem.LoadFromManifest(manifest);
var tileset = manifest.TileSets.Select(a => new TileSet(a))
@@ -225,10 +225,10 @@ public static void ConvertFormat2ToFormat80(string[] args)
public static void ExtractFiles(string[] args)
{
- var mods = args[1].Split(',');
+ var mod = args[1];
var files = args.Skip(2);
- var manifest = new Manifest(mods);
+ var manifest = new Manifest(mod);
FileSystem.LoadFromManifest(manifest);
foreach (var f in files)
View
2 launch-dedicated.sh
@@ -9,7 +9,7 @@ AdvertiseOnline="False"
Map="ba403f6bcb4cae934335b78be42f714992b3a71a"
while true; do
- mono --debug OpenRA.Game.exe Game.Mods=$Mod Server.Dedicated=$Dedicated Server.DedicatedLoop=$DedicatedLoop \
+ mono --debug OpenRA.Game.exe Game.Mod=$Mod Server.Dedicated=$Dedicated Server.DedicatedLoop=$DedicatedLoop \
Server.Name=$Name Server.ListenPort=$ListenPort Server.ExternalPort=$ExternalPort \
Server.AdvertiseOnline=$AdvertiseOnline Server.Map=$Map
done

0 comments on commit 6d6d1e2

Please sign in to comment.
Something went wrong with that request. Please try again.