Exemple #1
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();
        }
Exemple #2
0
        static void Run(string[] args)
        {
            var arguments = new Arguments(args);

            var engineDirArg = arguments.GetValue("Engine.EngineDir", null);

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

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

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

            Log.AddChannel("debug", "dedicated-debug.log", true);
            Log.AddChannel("perf", "dedicated-perf.log", true);
            Log.AddChannel("server", "dedicated-server.log", true);
            Log.AddChannel("nat", "dedicated-nat.log", true);
            Log.AddChannel("geoip", "dedicated-geoip.log", true);

            // 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            = arguments.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);
            }

            if (modID == null)
            {
                throw new InvalidOperationException("Game.Mod argument missing or mod could not be found.");
            }

            // HACK: The engine code assumes that Game.Settings is set.
            // This isn't nearly as bad as ModData, but is still not very nice.
            Game.InitializeSettings(arguments);
            var settings = Game.Settings.Server;

            Nat.Initialize();

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

            var mods = new InstalledMods(modSearchPaths, explicitModPaths);

            Console.WriteLine("[{0}] Starting dedicated server for mod: {1}", DateTime.Now.ToString(settings.TimestampFormat), modID);
            while (true)
            {
                // HACK: The engine code *still* assumes that Game.ModData is set
                var modData = Game.ModData = new ModData(mods[modID], mods);
                modData.MapCache.LoadMaps();

                settings.Map = modData.MapCache.ChooseInitialMap(settings.Map, new MersenneTwister());

                var endpoints = new List <IPEndPoint> {
                    new IPEndPoint(IPAddress.IPv6Any, settings.ListenPort), new IPEndPoint(IPAddress.Any, settings.ListenPort)
                };
                var server = new Server(endpoints, settings, modData, ServerType.Dedicated);

                GC.Collect();
                while (true)
                {
                    Thread.Sleep(1000);
                    if (server.State == ServerState.GameStarted && server.Conns.Count < 1)
                    {
                        Console.WriteLine("[{0}] No one is playing, shutting down...", DateTime.Now.ToString(settings.TimestampFormat));
                        server.Shutdown();
                        break;
                    }
                }

                modData.Dispose();
                Console.WriteLine("[{0}] Starting a new server instance...", DateTime.Now.ToString(settings.TimestampFormat));
            }
        }