Exemplo n.º 1
0
        public Manifest(string modId, IReadOnlyPackage package)
        {
            Id      = modId;
            Package = package;
            yaml    = new MiniYaml(null, MiniYaml.FromStream(package.GetStream("mod.yaml"), "mod.yaml")).ToDictionary();

            Metadata = FieldLoader.Load <ModMetadata>(yaml["Metadata"]);

            // TODO: Use fieldloader
            MapFolders = YamlDictionary(yaml, "MapFolders");

            MiniYaml packages;

            if (yaml.TryGetValue("Packages", out packages))
            {
                Packages = packages.ToDictionary(x => x.Value).AsReadOnly();
            }

            Rules          = YamlList(yaml, "Rules");
            Sequences      = YamlList(yaml, "Sequences");
            ModelSequences = YamlList(yaml, "ModelSequences");
            Cursors        = YamlList(yaml, "Cursors");
            Chrome         = YamlList(yaml, "Chrome");
            Assemblies     = YamlList(yaml, "Assemblies");
            ChromeLayout   = YamlList(yaml, "ChromeLayout");
            Weapons        = YamlList(yaml, "Weapons");
            Voices         = YamlList(yaml, "Voices");
            Notifications  = YamlList(yaml, "Notifications");
            Music          = YamlList(yaml, "Music");
            Translations   = YamlList(yaml, "Translations");
            TileSets       = YamlList(yaml, "TileSets");
            ChromeMetrics  = YamlList(yaml, "ChromeMetrics");
            Missions       = YamlList(yaml, "Missions");
            Hotkeys        = YamlList(yaml, "Hotkeys");

            ServerTraits = YamlList(yaml, "ServerTraits");

            if (!yaml.TryGetValue("LoadScreen", out LoadScreen))
            {
                throw new InvalidDataException("`LoadScreen` section is not defined.");
            }

            // Allow inherited mods to import parent maps.
            var compat = new List <string> {
                Id
            };

            if (yaml.ContainsKey("SupportsMapsFrom"))
            {
                compat.AddRange(yaml["SupportsMapsFrom"].Value.Split(',').Select(c => c.Trim()));
            }

            MapCompatibility = compat.ToArray();

            if (yaml.ContainsKey("PackageFormats"))
            {
                PackageFormats = FieldLoader.GetValue <string[]>("PackageFormats", yaml["PackageFormats"].Value);
            }

            if (yaml.ContainsKey("SoundFormats"))
            {
                SoundFormats = FieldLoader.GetValue <string[]>("SoundFormats", yaml["SoundFormats"].Value);
            }

            if (yaml.ContainsKey("SpriteFormats"))
            {
                SpriteFormats = FieldLoader.GetValue <string[]>("SpriteFormats", yaml["SpriteFormats"].Value);
            }
        }
Exemplo n.º 2
0
		/// <summary>
		/// Removes invalid mod registrations:
		/// * LaunchPath no longer exists
		/// * LaunchPath and mod id matches the active mod, but the version is different
		/// * Filename doesn't match internal key
		/// * Fails to parse as a mod registration
		/// </summary>
		internal void ClearInvalidRegistrations(ExternalMod activeMod, ModRegistration registration)
		{
			var sources = new List<string>();
			if (registration.HasFlag(ModRegistration.System))
				sources.Add(Platform.GetSupportDir(SupportDirType.System));

			if (registration.HasFlag(ModRegistration.User))
			{
				// User support dir may be using the modern or legacy value, or overridden by the user
				// Add all the possibilities and let the .Distinct() below ignore the duplicates
				sources.Add(Platform.GetSupportDir(SupportDirType.User));
				sources.Add(Platform.GetSupportDir(SupportDirType.ModernUser));
				sources.Add(Platform.GetSupportDir(SupportDirType.LegacyUser));
			}

			var activeModKey = ExternalMod.MakeKey(activeMod);
			foreach (var source in sources.Distinct())
			{
				var metadataPath = Path.Combine(source, "ModMetadata");
				if (!Directory.Exists(metadataPath))
					continue;

				foreach (var path in Directory.GetFiles(metadataPath, "*.yaml"))
				{
					string modKey = null;
					try
					{
						var yaml = MiniYaml.FromStream(File.OpenRead(path), path).First().Value;
						var m = FieldLoader.Load<ExternalMod>(yaml);
						modKey = ExternalMod.MakeKey(m);

						// Continue to the next entry if it is the active mod (even if the LaunchPath is bogus)
						if (modKey == activeModKey)
							continue;

						// Continue to the next entry if this one is valid
						if (File.Exists(m.LaunchPath) && Path.GetFileNameWithoutExtension(path) == modKey &&
							!(activeMod != null && m.LaunchPath == activeMod.LaunchPath && m.Id == activeMod.Id && m.Version != activeMod.Version))
							continue;
					}
					catch (Exception e)
					{
						Log.Write("debug", "Failed to parse mod metadata file '{0}'", path);
						Log.Write("debug", e.ToString());
					}

					// Remove from the ingame mod switcher
					if (Path.GetFileNameWithoutExtension(path) == modKey)
						mods.Remove(modKey);

					// Remove stale or corrupted metadata
					try
					{
						File.Delete(path);
						Log.Write("debug", "Removed invalid mod metadata file '{0}'", path);
					}
					catch (Exception e)
					{
						Log.Write("debug", "Failed to remove mod metadata file '{0}'", path);
						Log.Write("debug", e.ToString());
					}
				}
			}
		}
Exemplo n.º 3
0
        public void UpdateFromMap(IReadOnlyPackage p, IReadOnlyPackage parent, MapClassification classification, string[] mapCompatibility, MapGridType gridType)
        {
            Dictionary <string, MiniYaml> yaml;

            using (var yamlStream = p.GetStream("map.yaml"))
            {
                if (yamlStream == null)
                {
                    throw new FileNotFoundException("Required file map.yaml not present in this map");
                }

                yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, "map.yaml")).ToDictionary();
            }

            Package       = p;
            parentPackage = parent;

            var newData = innerData.Clone();

            newData.GridType = gridType;
            newData.Class    = classification;

            MiniYaml temp;

            if (yaml.TryGetValue("MapFormat", out temp))
            {
                var format = FieldLoader.GetValue <int>("MapFormat", temp.Value);
                if (format != Map.SupportedMapFormat)
                {
                    throw new InvalidDataException("Map format {0} is not supported.".F(format));
                }
            }

            if (yaml.TryGetValue("Title", out temp))
            {
                newData.Title = temp.Value;
            }

            if (yaml.TryGetValue("Categories", out temp))
            {
                newData.Categories = FieldLoader.GetValue <string[]>("Categories", temp.Value);
            }

            if (yaml.TryGetValue("Tileset", out temp))
            {
                newData.TileSet = temp.Value;
            }

            if (yaml.TryGetValue("Author", out temp))
            {
                newData.Author = temp.Value;
            }

            if (yaml.TryGetValue("Bounds", out temp))
            {
                newData.Bounds = FieldLoader.GetValue <Rectangle>("Bounds", temp.Value);
            }

            if (yaml.TryGetValue("Visibility", out temp))
            {
                newData.Visibility = FieldLoader.GetValue <MapVisibility>("Visibility", temp.Value);
            }

            string requiresMod = string.Empty;

            if (yaml.TryGetValue("RequiresMod", out temp))
            {
                requiresMod = temp.Value;
            }

            newData.Status = mapCompatibility == null || mapCompatibility.Contains(requiresMod) ?
                             MapStatus.Available : MapStatus.Unavailable;

            try
            {
                // Actor definitions may change if the map format changes
                MiniYaml actorDefinitions;
                if (yaml.TryGetValue("Actors", out actorDefinitions))
                {
                    var spawns = new List <CPos>();
                    foreach (var kv in actorDefinitions.Nodes.Where(d => d.Value.Value == "mpspawn"))
                    {
                        var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
                        spawns.Add(s.InitDict.Get <LocationInit>().Value(null));
                    }

                    newData.SpawnPoints = spawns.ToArray();
                }
                else
                {
                    newData.SpawnPoints = new CPos[0];
                }
            }
            catch (Exception)
            {
                newData.SpawnPoints = new CPos[0];
                newData.Status      = MapStatus.Unavailable;
            }

            try
            {
                // Player definitions may change if the map format changes
                MiniYaml playerDefinitions;
                if (yaml.TryGetValue("Players", out playerDefinitions))
                {
                    newData.Players               = new MapPlayers(playerDefinitions.Nodes);
                    newData.PlayerCount           = newData.Players.Players.Count(x => x.Value.Playable);
                    newData.SuitableForInitialMap = EvaluateUserFriendliness(newData.Players.Players);
                }
            }
            catch (Exception)
            {
                newData.Status = MapStatus.Unavailable;
            }

            newData.SetRulesetGenerator(modData, () =>
            {
                var ruleDefinitions         = LoadRuleSection(yaml, "Rules");
                var weaponDefinitions       = LoadRuleSection(yaml, "Weapons");
                var voiceDefinitions        = LoadRuleSection(yaml, "Voices");
                var musicDefinitions        = LoadRuleSection(yaml, "Music");
                var notificationDefinitions = LoadRuleSection(yaml, "Notifications");
                var sequenceDefinitions     = LoadRuleSection(yaml, "Sequences");
                var rules = Ruleset.Load(modData, this, TileSet, ruleDefinitions, weaponDefinitions,
                                         voiceDefinitions, notificationDefinitions, musicDefinitions, sequenceDefinitions);
                var flagged = Ruleset.DefinesUnsafeCustomRules(modData, this, ruleDefinitions,
                                                               weaponDefinitions, voiceDefinitions, notificationDefinitions, sequenceDefinitions);
                return(Pair.New(rules, flagged));
            });

            if (p.Contains("map.png"))
            {
                using (var dataStream = p.GetStream("map.png"))
                    newData.Preview = new Bitmap(dataStream);
            }

            // Assign the new data atomically
            innerData = newData;
        }
Exemplo n.º 4
0
        public void UpdateRemoteSearch(MapStatus status, MiniYaml yaml, Action <MapPreview> parseMetadata = null)
        {
            var newData = innerData.Clone();

            newData.Status = status;
            newData.Class  = MapClassification.Remote;

            if (status == MapStatus.DownloadAvailable)
            {
                try
                {
                    var r = FieldLoader.Load <RemoteMapData>(yaml);

                    // Map download has been disabled server side
                    if (!r.downloading)
                    {
                        newData.Status = MapStatus.Unavailable;
                        return;
                    }

                    newData.Title       = r.title;
                    newData.Categories  = r.categories;
                    newData.Author      = r.author;
                    newData.PlayerCount = r.players;
                    newData.Bounds      = r.bounds;
                    newData.TileSet     = r.tileset;

                    var spawns = new CPos[r.spawnpoints.Length / 2];
                    for (var j = 0; j < r.spawnpoints.Length; j += 2)
                    {
                        spawns[j / 2] = new CPos(r.spawnpoints[j], r.spawnpoints[j + 1]);
                    }
                    newData.SpawnPoints = spawns;
                    newData.GridType    = r.map_grid_type;
                    newData.Preview     = new Bitmap(new MemoryStream(Convert.FromBase64String(r.minimap)));

                    var playersString = Encoding.UTF8.GetString(Convert.FromBase64String(r.players_block));
                    newData.Players = new MapPlayers(MiniYaml.FromString(playersString));

                    newData.SetRulesetGenerator(modData, () =>
                    {
                        var rulesString             = Encoding.UTF8.GetString(Convert.FromBase64String(r.rules));
                        var rulesYaml               = new MiniYaml("", MiniYaml.FromString(rulesString)).ToDictionary();
                        var ruleDefinitions         = LoadRuleSection(rulesYaml, "Rules");
                        var weaponDefinitions       = LoadRuleSection(rulesYaml, "Weapons");
                        var voiceDefinitions        = LoadRuleSection(rulesYaml, "Voices");
                        var musicDefinitions        = LoadRuleSection(rulesYaml, "Music");
                        var notificationDefinitions = LoadRuleSection(rulesYaml, "Notifications");
                        var sequenceDefinitions     = LoadRuleSection(rulesYaml, "Sequences");
                        var rules = Ruleset.Load(modData, this, TileSet, ruleDefinitions, weaponDefinitions,
                                                 voiceDefinitions, notificationDefinitions, musicDefinitions, sequenceDefinitions);
                        var flagged = Ruleset.DefinesUnsafeCustomRules(modData, this, ruleDefinitions,
                                                                       weaponDefinitions, voiceDefinitions, notificationDefinitions, sequenceDefinitions);
                        return(Pair.New(rules, flagged));
                    });
                }
                catch (Exception) { }

                // Commit updated data before running the callbacks
                innerData = newData;

                if (innerData.Preview != null)
                {
                    cache.CacheMinimap(this);
                }

                if (parseMetadata != null)
                {
                    parseMetadata(this);
                }
            }

            // Update the status and class unconditionally
            innerData = newData;
        }
Exemplo n.º 5
0
 public PlayerReference(MiniYaml my)
 {
     FieldLoader.Load(this, my);
 }
Exemplo n.º 6
0
        public Settings(string file, Arguments args)
        {
            settingsFile = file;
            Sections     = new Dictionary <string, object>()
            {
                { "Player", Player },
                { "Game", Game },
                { "Sound", Sound },
                { "Graphics", Graphics },
                { "Server", Server },
                { "Debug", Debug },
            };

            // Override fieldloader to ignore invalid entries
            var err1 = FieldLoader.UnknownFieldAction;
            var err2 = FieldLoader.InvalidValueAction;

            try
            {
                FieldLoader.UnknownFieldAction = (s, f) => Console.WriteLine("Ignoring unknown field `{0}` on `{1}`".F(s, f.Name));

                if (File.Exists(settingsFile))
                {
                    yamlCache = MiniYaml.FromFile(settingsFile, false);
                    foreach (var yamlSection in yamlCache)
                    {
                        if (yamlSection.Key != null && Sections.TryGetValue(yamlSection.Key, out var settingsSection))
                        {
                            LoadSectionYaml(yamlSection.Value, settingsSection);
                        }
                    }

                    var keysNode = yamlCache.FirstOrDefault(n => n.Key == "Keys");
                    if (keysNode != null)
                    {
                        foreach (var node in keysNode.Value.Nodes)
                        {
                            if (node.Key != null)
                            {
                                Keys[node.Key] = FieldLoader.GetValue <Hotkey>(node.Key, node.Value.Value);
                            }
                        }
                    }
                }

                // Override with commandline args
                foreach (var kv in Sections)
                {
                    foreach (var f in kv.Value.GetType().GetFields())
                    {
                        if (args.Contains(kv.Key + "." + f.Name))
                        {
                            FieldLoader.LoadField(kv.Value, f.Name, args.GetValue(kv.Key + "." + f.Name, ""));
                        }
                    }
                }
            }
            finally
            {
                FieldLoader.UnknownFieldAction = err1;
                FieldLoader.InvalidValueAction = err2;
            }
        }
Exemplo n.º 7
0
 public virtual void Initialize(MiniYaml yaml)
 {
     Initialize((T)FieldLoader.GetValue(nameof(value), typeof(T), yaml.Value));
 }
Exemplo n.º 8
0
        // Support upgrading format 5 maps to a more
        // recent version by defining upgradeForMod.
        public Map(string path, string upgradeForMod)
        {
            Path      = path;
            Container = GlobalFileSystem.OpenPackage(path, null, int.MaxValue);

            AssertExists("map.yaml");
            AssertExists("map.bin");

            var yaml = new MiniYaml(null, MiniYaml.FromStream(Container.GetContent("map.yaml")));

            FieldLoader.Load(this, yaml);

            // Support for formats 1-3 dropped 2011-02-11.
            // Use release-20110207 to convert older maps to format 4
            // Use release-20110511 to convert older maps to format 5
            if (MapFormat < 5)
            {
                throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, path));
            }

            // Format 5 -> 6 enforces the use of RequiresMod
            if (MapFormat == 5)
            {
                if (upgradeForMod == null)
                {
                    throw new InvalidDataException("Map format {0} is not supported, but can be upgraded.\n File: {1}".F(MapFormat, path));
                }

                Console.WriteLine("Upgrading {0} from Format 5 to Format 6", path);

                // TODO: This isn't very nice, but there is no other consistent way
                // of finding the mod early during the engine initialization.
                RequiresMod = upgradeForMod;
            }

            // Load players
            foreach (var kv in yaml.NodesDict["Players"].NodesDict)
            {
                var player = new PlayerReference(kv.Value);
                Players.Add(player.Name, player);
            }

            Actors = Exts.Lazy(() =>
            {
                var ret = new Dictionary <string, ActorReference>();
                foreach (var kv in yaml.NodesDict["Actors"].NodesDict)
                {
                    ret.Add(kv.Key, new ActorReference(kv.Value.Value, kv.Value.NodesDict));
                }
                return(ret);
            });

            // Smudges
            Smudges = Exts.Lazy(() =>
            {
                var ret = new List <SmudgeReference>();
                foreach (var kv in yaml.NodesDict["Smudges"].NodesDict)
                {
                    var vals = kv.Key.Split(' ');
                    var loc  = vals[1].Split(',');
                    ret.Add(new SmudgeReference(vals[0], new int2(
                                                    Exts.ParseIntegerInvariant(loc[0]),
                                                    Exts.ParseIntegerInvariant(loc[1])),
                                                Exts.ParseIntegerInvariant(vals[2])));
                }

                return(ret);
            });

            RuleDefinitions          = MiniYaml.NodesOrEmpty(yaml, "Rules");
            SequenceDefinitions      = MiniYaml.NodesOrEmpty(yaml, "Sequences");
            VoxelSequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "VoxelSequences");
            WeaponDefinitions        = MiniYaml.NodesOrEmpty(yaml, "Weapons");
            VoiceDefinitions         = MiniYaml.NodesOrEmpty(yaml, "Voices");
            NotificationDefinitions  = MiniYaml.NodesOrEmpty(yaml, "Notifications");
            TranslationDefinitions   = MiniYaml.NodesOrEmpty(yaml, "Translations");

            CustomTerrain = new string[MapSize.X, MapSize.Y];

            MapTiles     = Exts.Lazy(() => LoadMapTiles());
            MapResources = Exts.Lazy(() => LoadResourceTiles());

            // The Uid is calculated from the data on-disk, so
            // format changes must be flushed to disk.
            // TODO: this isn't very nice
            if (MapFormat < 6)
            {
                Save(path);
            }

            Uid = ComputeHash();

            if (Container.Exists("map.png"))
            {
                CustomPreview = new Bitmap(Container.GetContent("map.png"));
            }

            PostInit();
        }
Exemplo n.º 9
0
 public ModPackage(MiniYaml yaml)
 {
     Title = yaml.Value;
     FieldLoader.Load(this, yaml);
 }
Exemplo n.º 10
0
 public ModDownload(MiniYaml yaml)
 {
     Title = yaml.Value;
     FieldLoader.Load(this, yaml);
 }
Exemplo n.º 11
0
        internal static void Initialize(Arguments args)
        {
            Console.WriteLine("Platform is {0}", Platform.CurrentPlatform);

            // Special case handling of Game.Mod argument: if it matches a real filesystem path
            // then we use this to override the mod search path, and replace it with the mod id
            var modID            = args.GetValue("Game.Mod", null);
            var explicitModPaths = new string[0];

            if (modID != null && (File.Exists(modID) || Directory.Exists(modID)))
            {
                explicitModPaths = new[] { modID };
                modID            = Path.GetFileNameWithoutExtension(modID);
            }

            InitializeSettings(args);

            Log.AddChannel("perf", "perf.log");
            Log.AddChannel("debug", "debug.log");
            Log.AddChannel("server", "server.log");
            Log.AddChannel("sound", "sound.log");
            Log.AddChannel("graphics", "graphics.log");
            Log.AddChannel("geoip", "geoip.log");
            Log.AddChannel("irc", "irc.log");
            Log.AddChannel("nat", "nat.log");

            var platforms = new[] { Settings.Game.Platform, "Default", null };

            foreach (var p in platforms)
            {
                if (p == null)
                {
                    throw new InvalidOperationException("Failed to initialize platform-integration library. Check graphics.log for details.");
                }

                Settings.Game.Platform = p;
                try
                {
                    var rendererPath = Platform.ResolvePath(Path.Combine(".", "OpenRA.Platforms." + p + ".dll"));
                    var assembly     = Assembly.LoadFile(rendererPath);

                    var platformType = assembly.GetTypes().SingleOrDefault(t => typeof(IPlatform).IsAssignableFrom(t));
                    if (platformType == null)
                    {
                        throw new InvalidOperationException("Platform dll must include exactly one IPlatform implementation.");
                    }

                    var platform = (IPlatform)platformType.GetConstructor(Type.EmptyTypes).Invoke(null);
                    Renderer = new Renderer(platform, Settings.Graphics);
                    Sound    = new Sound(platform, Settings.Sound);

                    break;
                }
                catch (Exception e)
                {
                    Log.Write("graphics", "{0}", e);
                    Console.WriteLine("Renderer initialization failed. Check graphics.log for details.");

                    if (Renderer != null)
                    {
                        Renderer.Dispose();
                    }

                    if (Sound != null)
                    {
                        Sound.Dispose();
                    }
                }
            }

            GeoIP.Initialize();

            if (!Settings.Server.DiscoverNatDevices)
            {
                Settings.Server.AllowPortForward = false;
            }
            else
            {
                discoverNat = UPnP.DiscoverNatDevices(Settings.Server.NatDiscoveryTimeout);
                Settings.Server.AllowPortForward = true;
            }

            GlobalChat = new GlobalChat();

            var modSearchArg   = args.GetValue("Engine.ModSearchPaths", null);
            var modSearchPaths = modSearchArg != null?
                                 FieldLoader.GetValue <string[]>("Engine.ModsPath", modSearchArg) :
                                     new[] { Path.Combine(".", "mods") };

            Mods = new InstalledMods(modSearchPaths, explicitModPaths);
            Console.WriteLine("Internal mods:");
            foreach (var mod in Mods)
            {
                Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Metadata.Title, mod.Value.Metadata.Version);
            }

            var launchPath = args.GetValue("Engine.LaunchPath", Assembly.GetEntryAssembly().Location);

            ExternalMods = new ExternalMods(launchPath);
            Console.WriteLine("External mods:");
            foreach (var mod in ExternalMods)
            {
                Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Title, mod.Value.Version);
            }

            InitializeMod(modID, args);
        }
Exemplo n.º 12
0
        public Map(string path)
        {
            Path      = path;
            Container = FileSystem.OpenPackage(path, int.MaxValue);

            AssertExists("map.yaml");
            AssertExists("map.bin");

            var yaml = new MiniYaml(null, MiniYaml.FromStream(Container.GetContent("map.yaml")));

            FieldLoader.Load(this, yaml);
            Uid = ComputeHash();

            // Support for formats 1-3 dropped 2011-02-11.
            // Use release-20110207 to convert older maps to format 4
            // Use release-20110511 to convert older maps to format 5
            if (MapFormat < 5)
            {
                throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, path));
            }

            // Load players
            foreach (var kv in yaml.NodesDict["Players"].NodesDict)
            {
                var player = new PlayerReference(kv.Value);
                Players.Add(player.Name, player);
            }

            Actors = Lazy.New(() =>
            {
                var ret = new Dictionary <string, ActorReference>();
                foreach (var kv in yaml.NodesDict["Actors"].NodesDict)
                {
                    ret.Add(kv.Key, new ActorReference(kv.Value.Value, kv.Value.NodesDict));
                }
                return(ret);
            });

            // Smudges
            Smudges = Lazy.New(() =>
            {
                var ret = new List <SmudgeReference>();
                foreach (var kv in yaml.NodesDict["Smudges"].NodesDict)
                {
                    var vals = kv.Key.Split(' ');
                    var loc  = vals[1].Split(',');
                    ret.Add(new SmudgeReference(vals[0], new int2(int.Parse(loc[0]), int.Parse(loc[1])), int.Parse(vals[2])));
                }

                return(ret);
            });

            Rules         = NodesOrEmpty(yaml, "Rules");
            Sequences     = NodesOrEmpty(yaml, "Sequences");
            Weapons       = NodesOrEmpty(yaml, "Weapons");
            Voices        = NodesOrEmpty(yaml, "Voices");
            Notifications = NodesOrEmpty(yaml, "Notifications");

            CustomTerrain = new string[MapSize.X, MapSize.Y];

            MapTiles     = Lazy.New(() => LoadMapTiles());
            MapResources = Lazy.New(() => LoadResourceTiles());
        }
Exemplo n.º 13
0
        /// <summary>
        /// Removes invalid mod registrations:
        /// * LaunchPath no longer exists
        /// * LaunchPath and mod id matches the active mod, but the version is different
        /// * Filename doesn't match internal key
        /// * Fails to parse as a mod registration
        /// </summary>
        internal void ClearInvalidRegistrations(ExternalMod activeMod, ModRegistration registration)
        {
            var sources = new List <string>();

            if (registration.HasFlag(ModRegistration.System))
            {
                sources.Add(Platform.SystemSupportDir);
            }

            if (registration.HasFlag(ModRegistration.User))
            {
                sources.Add(Platform.SupportDir);
            }

            foreach (var source in sources.Distinct())
            {
                var metadataPath = Path.Combine(source, "ModMetadata");
                if (!Directory.Exists(metadataPath))
                {
                    continue;
                }

                foreach (var path in Directory.GetFiles(metadataPath, "*.yaml"))
                {
                    string modKey = null;
                    try
                    {
                        var yaml = MiniYaml.FromStream(File.OpenRead(path), path).First().Value;
                        var m    = FieldLoader.Load <ExternalMod>(yaml);
                        modKey = ExternalMod.MakeKey(m);

                        // Continue to the next entry if this one is valid
                        if (File.Exists(m.LaunchPath) && Path.GetFileNameWithoutExtension(path) == modKey &&
                            !(activeMod != null && m.LaunchPath == activeMod.LaunchPath && m.Id == activeMod.Id && m.Version != activeMod.Version))
                        {
                            continue;
                        }
                    }
                    catch (Exception e)
                    {
                        Log.Write("debug", "Failed to parse mod metadata file '{0}'", path);
                        Log.Write("debug", e.ToString());
                    }

                    // Remove from the ingame mod switcher
                    if (Path.GetFileNameWithoutExtension(path) == modKey)
                    {
                        mods.Remove(modKey);
                    }

                    // Remove stale or corrupted metadata
                    try
                    {
                        File.Delete(path);
                        Log.Write("debug", "Removed invalid mod metadata file '{0}'", path);
                    }
                    catch (Exception e)
                    {
                        Log.Write("debug", "Failed to remove mod metadata file '{0}'", path);
                        Log.Write("debug", e.ToString());
                    }
                }
            }
        }
Exemplo n.º 14
0
 public TerrainTypeInfo(MiniYaml my)
 {
     FieldLoader.Load(this, my);
 }
Exemplo n.º 15
0
 public virtual void Initialize(MiniYaml yaml)
 {
     FieldLoader.Load(this, yaml);
 }
Exemplo n.º 16
0
        static void Initialize(Arguments args)
        {
            var engineDirArg = args.GetValue("Engine.EngineDir", null);

            if (!string.IsNullOrEmpty(engineDirArg))
            {
                Platform.OverrideEngineDir(engineDirArg);
            }

            var supportDirArg = args.GetValue("Engine.SupportDir", null);

            if (!string.IsNullOrEmpty(supportDirArg))
            {
                Platform.OverrideSupportDir(supportDirArg);
            }

            Console.WriteLine("Platform is {0}", Platform.CurrentPlatform);

            // Load the engine version as early as possible so it can be written to exception logs
            try
            {
                EngineVersion = File.ReadAllText(Path.Combine(Platform.EngineDir, "VERSION")).Trim();
            }
            catch { }

            if (string.IsNullOrEmpty(EngineVersion))
            {
                EngineVersion = "Unknown";
            }

            Console.WriteLine("Engine version is {0}", EngineVersion);
            Console.WriteLine("Runtime: {0}", Platform.RuntimeVersion);

            // Special case handling of Game.Mod argument: if it matches a real filesystem path
            // then we use this to override the mod search path, and replace it with the mod id
            var modID            = args.GetValue("Game.Mod", null);
            var explicitModPaths = new string[0];

            if (modID != null && (File.Exists(modID) || Directory.Exists(modID)))
            {
                explicitModPaths = new[] { modID };
                modID            = Path.GetFileNameWithoutExtension(modID);
            }

            InitializeSettings(args);

            Log.AddChannel("perf", "perf.log");
            Log.AddChannel("debug", "debug.log");
            Log.AddChannel("server", "server.log", true);
            Log.AddChannel("sound", "sound.log");
            Log.AddChannel("graphics", "graphics.log");
            Log.AddChannel("geoip", "geoip.log");
            Log.AddChannel("nat", "nat.log");
            Log.AddChannel("client", "client.log");

            var platforms = new[] { Settings.Game.Platform, "Default", null };

            foreach (var p in platforms)
            {
                if (p == null)
                {
                    throw new InvalidOperationException("Failed to initialize platform-integration library. Check graphics.log for details.");
                }

                Settings.Game.Platform = p;
                try
                {
                    var rendererPath = Path.Combine(Platform.BinDir, "OpenRA.Platforms." + p + ".dll");

#if !MONO
                    var loader       = new AssemblyLoader(rendererPath);
                    var platformType = loader.LoadDefaultAssembly().GetTypes().SingleOrDefault(t => typeof(IPlatform).IsAssignableFrom(t));
#else
                    var assembly     = Assembly.LoadFile(rendererPath);
                    var platformType = assembly.GetTypes().SingleOrDefault(t => typeof(IPlatform).IsAssignableFrom(t));
#endif

                    if (platformType == null)
                    {
                        throw new InvalidOperationException("Platform dll must include exactly one IPlatform implementation.");
                    }

                    var platform = (IPlatform)platformType.GetConstructor(Type.EmptyTypes).Invoke(null);
                    Renderer = new Renderer(platform, Settings.Graphics);
                    Sound    = new Sound(platform, Settings.Sound);

                    break;
                }
                catch (Exception e)
                {
                    Log.Write("graphics", "{0}", e);
                    Console.WriteLine("Renderer initialization failed. Check graphics.log for details.");

                    Renderer?.Dispose();

                    Sound?.Dispose();
                }
            }

            Nat.Initialize();

            var modSearchArg   = args.GetValue("Engine.ModSearchPaths", null);
            var modSearchPaths = modSearchArg != null?
                                 FieldLoader.GetValue <string[]>("Engine.ModsPath", modSearchArg) :
                                     new[] { Path.Combine(Platform.EngineDir, "mods") };

            Mods = new InstalledMods(modSearchPaths, explicitModPaths);
            Console.WriteLine("Internal mods:");
            foreach (var mod in Mods)
            {
                Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Metadata.Title, mod.Value.Metadata.Version);
            }

            modLaunchWrapper = args.GetValue("Engine.LaunchWrapper", null);

            ExternalMods = new ExternalMods();

            if (modID != null && Mods.TryGetValue(modID, out _))
            {
                var launchPath = args.GetValue("Engine.LaunchPath", null);
                var launchArgs = new List <string>();

                // Sanitize input from platform-specific launchers
                // Process.Start requires paths to not be quoted, even if they contain spaces
                if (launchPath != null && launchPath.First() == '"' && launchPath.Last() == '"')
                {
                    launchPath = launchPath.Substring(1, launchPath.Length - 2);
                }

                if (launchPath == null)
                {
                    // When launching the assembly directly we must propagate the Engine.EngineDir argument if defined
                    // Platform-specific launchers are expected to manage this internally.
                    launchPath = Assembly.GetEntryAssembly().Location;
                    if (!string.IsNullOrEmpty(engineDirArg))
                    {
                        launchArgs.Add("Engine.EngineDir=\"" + engineDirArg + "\"");
                    }
                }

                ExternalMods.Register(Mods[modID], launchPath, launchArgs, ModRegistration.User);

                if (ExternalMods.TryGetValue(ExternalMod.MakeKey(Mods[modID]), out var activeMod))
                {
                    ExternalMods.ClearInvalidRegistrations(activeMod, ModRegistration.User);
                }
            }

            Console.WriteLine("External mods:");
            foreach (var mod in ExternalMods)
            {
                Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Title, mod.Value.Version);
            }

            InitializeMod(modID, args);
            Ui.InitializeTranslation();
        }
Exemplo n.º 17
0
        static void Initialize(Arguments args)
        {
            Console.WriteLine("Platform is {0}", Platform.CurrentPlatform);

            // Load the engine version as early as possible so it can be written to exception logs
            try
            {
                EngineVersion = File.ReadAllText(Platform.ResolvePath(Path.Combine(".", "VERSION"))).Trim();
            }
            catch { }

            if (string.IsNullOrEmpty(EngineVersion))
            {
                EngineVersion = "Unknown";
            }

            Console.WriteLine("Engine version is {0}", EngineVersion);

            // Special case handling of Game.Mod argument: if it matches a real filesystem path
            // then we use this to override the mod search path, and replace it with the mod id
            var modID            = args.GetValue("Game.Mod", null);
            var explicitModPaths = new string[0];

            if (modID != null && (File.Exists(modID) || Directory.Exists(modID)))
            {
                explicitModPaths = new[] { modID };
                modID            = Path.GetFileNameWithoutExtension(modID);
            }

            InitializeSettings(args);

            Log.AddChannel("perf", "perf.log");
            Log.AddChannel("debug", "debug.log");
            Log.AddChannel("server", "server.log");
            Log.AddChannel("sound", "sound.log");
            Log.AddChannel("graphics", "graphics.log");
            Log.AddChannel("geoip", "geoip.log");
            Log.AddChannel("irc", "irc.log");
            Log.AddChannel("nat", "nat.log");

            var platforms = new[] { Settings.Game.Platform, "Default", null };

            foreach (var p in platforms)
            {
                if (p == null)
                {
                    throw new InvalidOperationException("Failed to initialize platform-integration library. Check graphics.log for details.");
                }

                Settings.Game.Platform = p;
                try
                {
                    var rendererPath = Platform.ResolvePath(Path.Combine(".", "OpenRA.Platforms." + p + ".dll"));
                    var assembly     = Assembly.LoadFile(rendererPath);

                    var platformType = assembly.GetTypes().SingleOrDefault(t => typeof(IPlatform).IsAssignableFrom(t));
                    if (platformType == null)
                    {
                        throw new InvalidOperationException("Platform dll must include exactly one IPlatform implementation.");
                    }

                    var platform = (IPlatform)platformType.GetConstructor(Type.EmptyTypes).Invoke(null);
                    Renderer = new Renderer(platform, Settings.Graphics);
                    Sound    = new Sound(platform, Settings.Sound);

                    break;
                }
                catch (Exception e)
                {
                    Log.Write("graphics", "{0}", e);
                    Console.WriteLine("Renderer initialization failed. Check graphics.log for details.");

                    if (Renderer != null)
                    {
                        Renderer.Dispose();
                    }

                    if (Sound != null)
                    {
                        Sound.Dispose();
                    }
                }
            }

            GeoIP.Initialize();

            if (Settings.Server.DiscoverNatDevices)
            {
                discoverNat = UPnP.DiscoverNatDevices(Settings.Server.NatDiscoveryTimeout);
            }

            var modSearchArg   = args.GetValue("Engine.ModSearchPaths", null);
            var modSearchPaths = modSearchArg != null?
                                 FieldLoader.GetValue <string[]>("Engine.ModsPath", modSearchArg) :
                                     new[] { Path.Combine(".", "mods") };

            Mods = new InstalledMods(modSearchPaths, explicitModPaths);
            Console.WriteLine("Internal mods:");
            foreach (var mod in Mods)
            {
                Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Metadata.Title, mod.Value.Metadata.Version);
            }

            ExternalMods = new ExternalMods();

            Manifest currentMod;

            if (modID != null && Mods.TryGetValue(modID, out currentMod))
            {
                var launchPath = args.GetValue("Engine.LaunchPath", Assembly.GetEntryAssembly().Location);

                // Sanitize input from platform-specific launchers
                // Process.Start requires paths to not be quoted, even if they contain spaces
                if (launchPath.First() == '"' && launchPath.Last() == '"')
                {
                    launchPath = launchPath.Substring(1, launchPath.Length - 2);
                }

                ExternalMods.Register(Mods[modID], launchPath, ModRegistration.User);

                ExternalMod activeMod;
                if (ExternalMods.TryGetValue(ExternalMod.MakeKey(Mods[modID]), out activeMod))
                {
                    ExternalMods.ClearInvalidRegistrations(activeMod, ModRegistration.User);
                }
            }

            Console.WriteLine("External mods:");
            foreach (var mod in ExternalMods)
            {
                Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Title, mod.Value.Version);
            }

            InitializeMod(modID, args);
        }