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