Beispiel #1
0
        static void Initialize(Arguments args)
        {
            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(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", 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 = 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.");

                    Renderer?.Dispose();

                    Sound?.Dispose();
                }
            }

            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);
            }

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

            ExternalMods = new ExternalMods();

            if (modID != null && Mods.TryGetValue(modID, out _))
            {
                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);

                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);
        }
Beispiel #2
0
        public ModData(Manifest mod, InstalledMods mods, bool useLoadScreen = false)
        {
            Languages = new string[0];

            // Take a local copy of the manifest
            Manifest       = new Manifest(mod.Id, mod.Package);
            ObjectCreator  = new ObjectCreator(Manifest, mods);
            PackageLoaders = ObjectCreator.GetLoaders <IPackageLoader>(Manifest.PackageFormats, "package");

            ModFiles = new FS(mod.Id, mods, PackageLoaders);
            ModFiles.LoadFromManifest(Manifest);
            Manifest.LoadCustomData(ObjectCreator);

            if (useLoadScreen)
            {
                LoadScreen = ObjectCreator.CreateObject <ILoadScreen>(Manifest.LoadScreen.Value);
                LoadScreen.Init(this, Manifest.LoadScreen.ToDictionary(my => my.Value));
                LoadScreen.Display();
            }

            WidgetLoader = new WidgetLoader(this);
            MapCache     = new MapCache(this);

            SoundLoaders  = ObjectCreator.GetLoaders <ISoundLoader>(Manifest.SoundFormats, "sound");
            SpriteLoaders = ObjectCreator.GetLoaders <ISpriteLoader>(Manifest.SpriteFormats, "sprite");
            VideoLoaders  = ObjectCreator.GetLoaders <IVideoLoader>(Manifest.VideoFormats, "video");

            var terrainFormat = Manifest.Get <TerrainFormat>();
            var terrainLoader = ObjectCreator.FindType(terrainFormat.Type + "Loader");
            var terrainCtor   = terrainLoader?.GetConstructor(new[] { typeof(ModData) });

            if (terrainLoader == null || !terrainLoader.GetInterfaces().Contains(typeof(ITerrainLoader)) || terrainCtor == null)
            {
                throw new InvalidOperationException($"Unable to find a terrain loader for type '{terrainFormat.Type}'.");
            }

            TerrainLoader = (ITerrainLoader)terrainCtor.Invoke(new[] { this });

            var sequenceFormat = Manifest.Get <SpriteSequenceFormat>();
            var sequenceLoader = ObjectCreator.FindType(sequenceFormat.Type + "Loader");
            var sequenceCtor   = sequenceLoader != null?sequenceLoader.GetConstructor(new[] { typeof(ModData) }) : null;

            if (sequenceLoader == null || !sequenceLoader.GetInterfaces().Contains(typeof(ISpriteSequenceLoader)) || sequenceCtor == null)
            {
                throw new InvalidOperationException($"Unable to find a sequence loader for type '{sequenceFormat.Type}'.");
            }

            SpriteSequenceLoader = (ISpriteSequenceLoader)sequenceCtor.Invoke(new[] { this });

            var modelFormat = Manifest.Get <ModelSequenceFormat>();
            var modelLoader = ObjectCreator.FindType(modelFormat.Type + "Loader");
            var modelCtor   = modelLoader != null?modelLoader.GetConstructor(new[] { typeof(ModData) }) : null;

            if (modelLoader == null || !modelLoader.GetInterfaces().Contains(typeof(IModelSequenceLoader)) || modelCtor == null)
            {
                throw new InvalidOperationException($"Unable to find a model loader for type '{modelFormat.Type}'.");
            }

            ModelSequenceLoader = (IModelSequenceLoader)modelCtor.Invoke(new[] { this });
            ModelSequenceLoader.OnMissingModelError = s => Log.Write("debug", s);

            Hotkeys = new HotkeyManager(ModFiles, Game.Settings.Keys, Manifest);

            defaultRules       = Exts.Lazy(() => Ruleset.LoadDefaults(this));
            defaultTerrainInfo = Exts.Lazy(() =>
            {
                var items = new Dictionary <string, ITerrainInfo>();

                foreach (var file in Manifest.TileSets)
                {
                    var t = TerrainLoader.ParseTerrain(DefaultFileSystem, file);
                    items.Add(t.Id, t);
                }

                return((IReadOnlyDictionary <string, ITerrainInfo>)(new ReadOnlyDictionary <string, ITerrainInfo>(items)));
            });

            defaultSequences = Exts.Lazy(() =>
            {
                var items = DefaultTerrainInfo.ToDictionary(t => t.Key, t => new SequenceProvider(DefaultFileSystem, this, t.Key, null));
                return((IReadOnlyDictionary <string, SequenceProvider>)(new ReadOnlyDictionary <string, SequenceProvider>(items)));
            });

            initialThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;
        }
        static void Main(string[] args)
        {
            Log.AddChannel("perf", null);
            Log.AddChannel("debug", null);

            Game.InitializeSettings(Arguments.Empty);

            var envModSearchPaths = Environment.GetEnvironmentVariable("MOD_SEARCH_PATHS");
            var modSearchPaths    = !string.IsNullOrWhiteSpace(envModSearchPaths) ?
                                    FieldLoader.GetValue <string[]>("MOD_SEARCH_PATHS", envModSearchPaths) :
                                    new[] { Path.Combine(".", "mods") };

            if (args.Length == 0)
            {
                PrintUsage(new InstalledMods(modSearchPaths, new string[0]), null);
                return;
            }

            var modId            = args[0];
            var explicitModPaths = new string[0];

            if (File.Exists(modId) || Directory.Exists(modId))
            {
                explicitModPaths = new[] { modId };
                modId            = Path.GetFileNameWithoutExtension(modId);
            }

            var mods = new InstalledMods(modSearchPaths, explicitModPaths);

            if (!mods.Keys.Contains(modId))
            {
                PrintUsage(mods, null);
                return;
            }

            var modData = new ModData(mods[modId], mods);
            var utility = new Utility(modData, mods);

            args = args.Skip(1).ToArray();
            var actions = new UtilityActions();

            foreach (var commandType in modData.ObjectCreator.GetTypesImplementing <IUtilityCommand>())
            {
                var command = (IUtilityCommand)Activator.CreateInstance(commandType);
                var kvp     = new KeyValuePair <Action <Utility, string[]>, Func <string[], bool> >(command.Run, command.ValidateArguments);
                actions.Add(command.Name, kvp);
            }

            if (args.Length == 0)
            {
                PrintUsage(mods, actions);
                return;
            }

            try
            {
                var command = args[0];
                if (!actions.ContainsKey(command))
                {
                    throw new NoSuchCommandException(command);
                }

                var action             = actions[command].Key;
                var validateActionArgs = actions[command].Value;

                if (validateActionArgs.Invoke(args))
                {
                    action.Invoke(utility, args);
                }
                else
                {
                    Console.WriteLine("Invalid arguments for '{0}'", command);
                    GetActionUsage(command, action);
                }
            }
            catch (Exception e)
            {
                Log.AddChannel("utility", "utility.log");
                Log.Write("utility", "Received args: {0}", args.JoinWith(" "));
                Log.Write("utility", "{0}", e);

                if (e is NoSuchCommandException)
                {
                    Console.WriteLine(e.Message);
                }
                else
                {
                    Console.WriteLine("Error: Utility application crashed. See utility.log for details");
                    throw;
                }
            }
        }
Beispiel #4
0
 public Utility(ModData modData, InstalledMods mods)
 {
     ModData = modData;
     Mods    = mods;
 }
Beispiel #5
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 modArgument      = args.GetValue("Game.Mod", null);
            var explicitModPaths = new string[0];

            if (modArgument != null && (File.Exists(modArgument) || Directory.Exists(modArgument)))
            {
                explicitModPaths = new[] { modArgument };
                args.ReplaceValue("Game.Mod", Path.GetFileNameWithoutExtension(modArgument));
            }

            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"), 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(Settings.Game.Mod, args);
        }
Beispiel #6
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 {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 {EngineVersion}");
            Console.WriteLine($"Runtime: {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 = Array.Empty <string>();

            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 NET5_0_OR_GREATER
                    var loader       = new AssemblyLoader(rendererPath);
                    var platformType = loader.LoadDefaultAssembly().GetTypes().SingleOrDefault(t => typeof(IPlatform).IsAssignableFrom(t));
#else
                    // NOTE: This is currently the only use of System.Reflection in this file, so would give an unused using error if we import it above
                    var assembly     = System.Reflection.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", $"{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{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);
                }

                // Metadata registration requires an explicit launch path
                if (launchPath != null)
                {
                    ExternalMods.Register(Mods[modID], launchPath, launchArgs, ModRegistration.User);
                }

                ExternalMods.ClearInvalidRegistrations(ModRegistration.User);
            }

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

            InitializeMod(modID, args);
        }