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 }, { "Keys", Keys }, { "Irc", Irc } }; // Override fieldloader to ignore invalid entries var err1 = FieldLoader.UnknownFieldAction; var err2 = FieldLoader.InvalidValueAction; FieldLoader.UnknownFieldAction = (s, f) => Console.WriteLine("Ignoring unknown field `{0}` on `{1}`".F(s, f.Name)); if (File.Exists(settingsFile)) { var yaml = MiniYaml.DictFromFile(settingsFile); foreach (var kv in Sections) { if (yaml.ContainsKey(kv.Key)) { LoadSectionYaml(yaml[kv.Key], kv.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, "")); } } } FieldLoader.UnknownFieldAction = err1; FieldLoader.InvalidValueAction = err2; }
public LaunchArguments(Arguments args) { if (args == null) { return; } foreach (var f in GetType().GetFields()) { if (args.Contains("Launch" + "." + f.Name)) { FieldLoader.LoadField(this, f.Name, args.GetValue("Launch" + "." + f.Name, "")); } } }
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 }, { "Keys", Keys }, { "Irc", Irc } }; // 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)) { var yaml = MiniYaml.DictFromFile(settingsFile); foreach (var kv in Sections) if (yaml.ContainsKey(kv.Key)) LoadSectionYaml(yaml[kv.Key], kv.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; } }
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"); Sound = new Sound(); Renderer = new Renderer(Settings.Graphics); 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); }
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) { object settingsSection; if (yamlSection.Key != null && Sections.TryGetValue(yamlSection.Key, out 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; } }
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(); }
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); string customModPath = null; if (modArgument != null && (File.Exists(modArgument) || Directory.Exists(modArgument))) { customModPath = 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(); Mods = new InstalledMods(customModPath); Console.WriteLine("Available mods:"); foreach (var mod in Mods) { Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Metadata.Title, mod.Value.Metadata.Version); } InitializeMod(Settings.Game.Mod, args); }
public static void InitializeMod(string mod, Arguments args) { // Clear static state if we have switched mods LobbyInfoChanged = () => { }; AddChatLine = (a, b, c) => { }; ConnectionStateChanged = om => { }; BeforeGameStart = () => { }; Ui.ResetAll(); worldRenderer = null; if (server != null) { server.Shutdown(); } if (orderManager != null) { orderManager.Dispose(); } // Fall back to default if the mod doesn't exist if (!ModMetadata.AllMods.ContainsKey(mod)) { mod = new GameSettings().Mod; } Console.WriteLine("Loading mod: {0}", mod); Settings.Game.Mod = mod; Sound.StopMusic(); Sound.StopVideo(); Sound.Initialize(); modData = new ModData(mod); Renderer.InitializeFonts(modData.Manifest); modData.InitializeLoaders(); using (new PerfTimer("LoadMaps")) modData.MapCache.LoadMaps(); PerfHistory.items["render"].hasNormalTick = false; PerfHistory.items["batches"].hasNormalTick = false; PerfHistory.items["render_widgets"].hasNormalTick = false; PerfHistory.items["render_flip"].hasNormalTick = false; JoinLocal(); if (Settings.Server.Dedicated) { while (true) { Settings.Server.Map = WidgetUtils.ChooseInitialMap(Settings.Server.Map); Settings.Save(); CreateServer(new ServerSettings(Settings.Server)); while (true) { System.Threading.Thread.Sleep(100); if (server.State == Server.ServerState.GameStarted && server.Conns.Count < 1) { Console.WriteLine("No one is playing, shutting down..."); server.Shutdown(); break; } } if (Settings.Server.DedicatedLoop) { Console.WriteLine("Starting a new server instance..."); modData.MapCache.LoadMaps(); continue; } break; } Environment.Exit(0); } else { var window = args != null?args.GetValue("Launch.Window", null) : null; if (!string.IsNullOrEmpty(window)) { var installData = modData.Manifest.ContentInstaller; if (installData.InstallerBackgroundWidget != null) { Ui.LoadWidget(installData.InstallerBackgroundWidget, Ui.Root, new WidgetArgs()); } Widgets.Ui.OpenWindow(window, new WidgetArgs()); } else { modData.LoadScreen.StartGame(); Settings.Save(); var replay = args != null?args.GetValue("Launch.Replay", null) : null; if (!string.IsNullOrEmpty(replay)) { Game.JoinReplay(replay); } } } }
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); }
public static void InitializeMod(string mod, Arguments args) { // Clear static state if we have switched mods LobbyInfoChanged = () => { }; ConnectionStateChanged = om => { }; BeforeGameStart = () => { }; OnRemoteDirectConnect = (a, b) => { }; delayedActions = new ActionQueue(); Ui.ResetAll(); if (worldRenderer != null) { worldRenderer.Dispose(); } worldRenderer = null; if (server != null) { server.Shutdown(); } if (OrderManager != null) { OrderManager.Dispose(); } if (ModData != null) { ModData.ModFiles.UnmountAll(); ModData.Dispose(); } ModData = null; // Fall back to default if the mod doesn't exist or has missing prerequisites. if (mod == null || !IsModInstalled(mod)) { mod = args.GetValue("Engine.DefaultMod", "modchooser"); } Console.WriteLine("Loading mod: {0}", mod); Settings.Game.Mod = mod; Sound.StopVideo(); ModData = new ModData(Mods[mod], Mods, true); ExternalMods.Register(ModData.Manifest); if (!ModData.LoadScreen.BeforeLoad()) { return; } using (new PerfTimer("LoadMaps")) ModData.MapCache.LoadMaps(); ModData.InitializeLoaders(ModData.DefaultFileSystem); Renderer.InitializeFonts(ModData); var grid = ModData.Manifest.Contains <MapGrid>() ? ModData.Manifest.Get <MapGrid>() : null; Renderer.InitializeDepthBuffer(grid); if (Cursor != null) { Cursor.Dispose(); } if (Settings.Graphics.HardwareCursors) { try { Cursor = new HardwareCursor(ModData.CursorProvider); } catch (Exception e) { Log.Write("debug", "Failed to initialize hardware cursors. Falling back to software cursors."); Log.Write("debug", "Error was: " + e.Message); Console.WriteLine("Failed to initialize hardware cursors. Falling back to software cursors."); Console.WriteLine("Error was: " + e.Message); Cursor = new SoftwareCursor(ModData.CursorProvider); } } else { Cursor = new SoftwareCursor(ModData.CursorProvider); } PerfHistory.Items["render"].HasNormalTick = false; PerfHistory.Items["batches"].HasNormalTick = false; PerfHistory.Items["render_widgets"].HasNormalTick = false; PerfHistory.Items["render_flip"].HasNormalTick = false; JoinLocal(); try { if (discoverNat != null) { discoverNat.Wait(); } } catch (Exception e) { Console.WriteLine("NAT discovery failed: {0}", e.Message); Log.Write("nat", e.ToString()); Settings.Server.AllowPortForward = false; } ModData.LoadScreen.StartGame(args); }
internal static void Initialize(Arguments args) { Console.WriteLine("Platform is {0}", Platform.CurrentPlatform); AppDomain.CurrentDomain.AssemblyResolve += GlobalFileSystem.ResolveAssembly; Settings = new Settings(Platform.SupportDir + "settings.yaml", args); Log.LogPath = Platform.SupportDir + "Logs" + Path.DirectorySeparatorChar; Log.AddChannel("perf", "perf.log"); Log.AddChannel("debug", "debug.log"); Log.AddChannel("sync", "syncreport.log"); Log.AddChannel("server", "server.log"); Log.AddChannel("sound", "sound.log"); Log.AddChannel("graphics", "graphics.log"); Log.AddChannel("geoip", "geoip.log"); if (Settings.Server.DiscoverNatDevices) { UPnP.TryNatDiscovery(); } else { Settings.Server.NatDeviceAvailable = false; Settings.Server.AllowPortForward = false; } try { GeoIpDatabase = new DatabaseReader("GeoLite2-Country.mmdb"); } catch (Exception e) { Log.Write("geoip", "DatabaseReader failed: {0}", e); } GlobalFileSystem.Mount("."); // Needed to access shaders var renderers = new[] { Settings.Graphics.Renderer, "Sdl2", null }; foreach (var r in renderers) { if (r == null) { throw new InvalidOperationException("No suitable renderers were found. Check graphics.log for details."); } Settings.Graphics.Renderer = r; try { Renderer.Initialize(Settings.Graphics.Mode); break; } catch (Exception e) { Log.Write("graphics", "{0}", e); Console.WriteLine("Renderer initialization failed. Fallback in place. Check graphics.log for details."); } } Renderer = new Renderer(); try { Sound.Create(Settings.Sound.Engine); } catch (Exception e) { Log.Write("sound", "{0}", e); Console.WriteLine("Creating the sound engine failed. Fallback in place. Check sound.log for details."); Settings.Sound.Engine = "Null"; Sound.Create(Settings.Sound.Engine); } Console.WriteLine("Available mods:"); foreach (var mod in ModMetadata.AllMods) { Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Title, mod.Value.Version); } InitializeWithMod(Settings.Game.Mod, args.GetValue("Launch.Replay", null)); if (Settings.Server.DiscoverNatDevices) { RunAfterDelay(Settings.Server.NatDiscoveryTimeout, UPnP.TryStoppingNatDiscovery); } }