public static async void StartGame(bool isOffline = false) { var pname = Process.GetProcessesByName("spartan"); if (pname.Length > 0) { MsgBox.ShowMessage(@"Game already running!"); return; } //QuickGameScan if (!isOffline || InternetUtils.IsConnectedToInternet()) { try { var gameFilePath = !string.IsNullOrWhiteSpace(Program.UserConfig.GameFilesPath) ? Program.UserConfig.GameFilesPath : GameScannerManager.GetGameFilesRootPath(); using (var gameScannner = new GameScannerManager(gameFilePath, Program.UserConfig.IsSteamVersion)) { await gameScannner.InitializeFromCelesteManifest(); retry: if (!await gameScannner.Scan(true)) { bool success; using (var form = new MsgBoxYesNo( @"Error: Your game files are corrupted or outdated. Click ""Yes"" to run a ""Game Scan"" to fix your game files, or ""No"" to ignore the error (not recommended).") ) { var dr = form.ShowDialog(); if (dr == DialogResult.OK) { using (var form2 = new GameScan()) { form2.ShowDialog(); success = false; } } else { success = true; } } if (!success) { goto retry; } } } } catch (Exception ex) { MsgBox.ShowMessage( $"Warning: Error during quick scan. Error message: {ex.Message}", @"Celeste Fan Project", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } //isSteam if (!Program.UserConfig.IsSteamVersion) { var steamApiDll = Path.Combine(Program.UserConfig.GameFilesPath, "steam_api.dll"); if (File.Exists(steamApiDll)) { File.Delete(steamApiDll); } } //MpSettings if (!isOffline && Program.UserConfig.MpSettings != null) { if (Program.UserConfig.MpSettings.ConnectionType == ConnectionType.Wan) { Program.UserConfig.MpSettings.PublicIp = Program.CurrentUser.Ip; if (Program.UserConfig.MpSettings.PortMappingType == PortMappingType.Upnp) { try { await OpenNat.MapPortTask(1000, 1000); } catch (Exception) { Program.UserConfig.MpSettings.PortMappingType = PortMappingType.NatPunch; MsgBox.ShowMessage( "Error: Upnp device not found! \"UPnP Port Mapping\" has been disabled.", @"Celeste Fan Project", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
public static async Task StartGame(bool isOffline = false) { Logger.Information("Preparing to start game, is offline: {@isOffline}", isOffline); var pname = Process.GetProcessesByName("spartan"); if (pname.Length > 0) { Logger.Information("Game is already started with PID {@PID}", pname.Select(t => t.Id)); GenericMessageDialog.Show(Properties.Resources.GameAlreadyRunningError, DialogIcon.Warning); return; } //QuickGameScan if (!isOffline || InternetUtils.IsConnectedToInternet()) { Logger.Information("User is online, will perform game scan"); try { var success = false; while (!success) { Logger.Information("Starting quick game scan"); var gameFilePath = !string.IsNullOrWhiteSpace(LegacyBootstrapper.UserConfig.GameFilesPath) ? LegacyBootstrapper.UserConfig.GameFilesPath : GameScannerManager.GetGameFilesRootPath(); Logger.Information("Preparing games canner api"); var gameScannner = new GameScannerManager(gameFilePath, LegacyBootstrapper.UserConfig.IsSteamVersion); await gameScannner.InitializeFromCelesteManifest(); if (!await gameScannner.Scan(true)) { Logger.Information("Game scanner did not approve game files"); var dialogResult = GenericMessageDialog.Show( Properties.Resources.GameScannerDidNotPassQuickScan, DialogIcon.None, DialogOptions.YesNo); if (dialogResult.Value) { var gamePathSelectionWindow = new GamePathSelectionWindow(); gamePathSelectionWindow.ShowDialog(); } else { success = true; } } else { Logger.Information("Game files passed file scanner"); success = true; } } } catch (Exception ex) { Logger.Error(ex, ex.Message); GenericMessageDialog.Show(Properties.Resources.GameScannerScanError, DialogIcon.Warning); } } //isSteam if (!LegacyBootstrapper.UserConfig.IsSteamVersion) { var steamApiDll = Path.Combine(LegacyBootstrapper.UserConfig.GameFilesPath, "steam_api.dll"); if (File.Exists(steamApiDll)) { File.Delete(steamApiDll); } } //MpSettings if (!isOffline && LegacyBootstrapper.UserConfig.MpSettings != null) { if (LegacyBootstrapper.UserConfig.MpSettings.ConnectionType == ConnectionType.Wan) { LegacyBootstrapper.UserConfig.MpSettings.PublicIp = LegacyBootstrapper.CurrentUser.Ip; if (LegacyBootstrapper.UserConfig.MpSettings.PortMappingType == PortMappingType.Upnp) { try { await OpenNat.MapPortTask(1000, 1000); } catch (Exception ex) { Logger.Error(ex, ex.Message); LegacyBootstrapper.UserConfig.MpSettings.PortMappingType = PortMappingType.NatPunch; GenericMessageDialog.Show(Properties.Resources.UPnPDisabledError, DialogIcon.Error); } finally { NatDiscoverer.TraceSource.Close(); } } } } try { //Launch Game var gamePath = !string.IsNullOrWhiteSpace(LegacyBootstrapper.UserConfig.GameFilesPath) ? LegacyBootstrapper.UserConfig.GameFilesPath : GameScannerManager.GetGameFilesRootPath(); var spartanPath = Path.Combine(gamePath, "Spartan.exe"); if (!File.Exists(spartanPath)) { GenericMessageDialog.Show(Properties.Resources.GameScannerSpartanNotFound, DialogIcon.Error); return; } string lang; switch (LegacyBootstrapper.UserConfig.GameLanguage) { case GameLanguage.deDE: lang = "de-DE"; break; case GameLanguage.enUS: lang = "en-US"; break; case GameLanguage.esES: lang = "es-ES"; break; case GameLanguage.frFR: lang = "fr-FR"; break; case GameLanguage.itIT: lang = "it-IT"; break; case GameLanguage.zhCHT: lang = "zh-CHT"; break; case GameLanguage.ptBR: lang = "pt-BR"; break; default: throw new ArgumentOutOfRangeException(nameof(LegacyBootstrapper.UserConfig.GameLanguage), LegacyBootstrapper.UserConfig.GameLanguage, null); } try { if (LegacyBootstrapper.UserConfig.IsDiagnosticMode) { Logger.Information("Diagnostics mode is enabled"); // try { var killInfo = new ProcessStartInfo("cmd.exe", "/c taskkill /F /IM procdump.exe /T") { WorkingDirectory = gamePath, CreateNoWindow = true, UseShellExecute = false, RedirectStandardError = true, RedirectStandardOutput = true }; Logger.Information("Starting prcoess {@Proc} with args {@Procargs}", killInfo.FileName, killInfo.Arguments); Process.Start(killInfo); } catch (Exception ex) { Logger.Error(ex, ex.Message); } var procdumpFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "procdump.exe"); const int maxNumOfCrashDumps = 30; if (!File.Exists(procdumpFileName)) { Logger.Information("Could not find procdump.exe"); LegacyBootstrapper.UserConfig.IsDiagnosticMode = false; throw new FileNotFoundException( Properties.Resources.DiagnosticsModeMissingProcdump, procdumpFileName); } // First ensure that all directories are set var pathToCrashDumpFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), @"Spartan\MiniDumps"); Logger.Information("CrashDumpFolder is set to {@CrashDumpFolder}", pathToCrashDumpFolder); if (!Directory.Exists(pathToCrashDumpFolder)) { Directory.CreateDirectory(pathToCrashDumpFolder); } // Check for cleanup Directory.GetFiles(pathToCrashDumpFolder) .OrderByDescending(File.GetLastWriteTime) // Sort by age --> old one last .Skip(maxNumOfCrashDumps) // Skip max num crash dumps .ToList() .ForEach(File.Delete); // Remove the rest var excludeExceptions = new[] { "E0434F4D.COM", // .NET native exception "E06D7363.msc", "E06D7363.PAVEEFileLoadException@@", "E0434F4D.System.IO.FileNotFoundException" // .NET managed exception }; var excludeExcpetionsCmd = string.Join(" ", excludeExceptions.Select(elem => "-fx " + elem)); var fullCmdArgs = "-accepteula -mm -e 1 -n 10 " + excludeExcpetionsCmd + " -g -w Spartan.exe \"" + pathToCrashDumpFolder + "\""; var startInfo = new ProcessStartInfo(procdumpFileName, fullCmdArgs) { WorkingDirectory = gamePath, CreateNoWindow = true, UseShellExecute = false, RedirectStandardError = true, RedirectStandardOutput = true }; Logger.Information("Starting prcoess {@Proc} with args {@Procargs}", startInfo.FileName, startInfo.Arguments); Process.Start(startInfo); } } catch (Exception exception) { Logger.Error(exception, exception.Message); GenericMessageDialog.Show(Properties.Resources.DiagnosticsModeError, DialogIcon.Warning); } //SymLink CustomScn Folder var profileDir = Path.Combine(Environment.GetEnvironmentVariable("userprofile")); var customScnGamePath = Path.Combine(gamePath, "Scenario", "CustomScn"); var scenarioUserPath = Path.Combine(profileDir, "Documents", "Spartan", "Scenario"); Logger.Information("CustomScn directory: {@customScnPath}", customScnGamePath); Logger.Information("Scenario directory: {@scenarioPath}", scenarioUserPath); if (!Directory.Exists(scenarioUserPath)) { Directory.CreateDirectory(scenarioUserPath); } if (Directory.Exists(customScnGamePath) && (!Misc.IsSymLink(customScnGamePath, Misc.SymLinkFlag.Directory) || !string.Equals(Misc.GetRealPath(customScnGamePath), scenarioUserPath, StringComparison.OrdinalIgnoreCase))) { Directory.Delete(customScnGamePath, true); Misc.CreateSymbolicLink(customScnGamePath, scenarioUserPath, Misc.SymLinkFlag.Directory); } else { Misc.CreateSymbolicLink(customScnGamePath, scenarioUserPath, Misc.SymLinkFlag.Directory); } string arg; if (isOffline) { arg = $"--offline --ignore_rest LauncherLang={lang} LauncherLocale=1033"; } else if (LegacyBootstrapper.UserConfig?.MpSettings == null || LegacyBootstrapper.UserConfig.MpSettings.ConnectionType == ConnectionType.Wan) { arg = LegacyBootstrapper.UserConfig.MpSettings.PortMappingType == PortMappingType.NatPunch ? $"--email \"{CurrentEmail}\" --password \"{CurrentPassword.GetValue()}\" --ignore_rest LauncherLang={lang} LauncherLocale=1033" : $"--email \"{CurrentEmail}\" --password \"{CurrentPassword.GetValue()}\" --no-nat-punchthrough --ignore_rest LauncherLang={lang} LauncherLocale=1033"; } else { arg = $"--email \"{CurrentEmail}\" --password \"{CurrentPassword.GetValue()}\" --online-ip \"{LegacyBootstrapper.UserConfig.MpSettings.PublicIp}\" --ignore_rest LauncherLang={lang} LauncherLocale=1033"; } Logger.Information("Starting game {@GameExecutable} at {@GamePath}", spartanPath, gamePath); Process.Start(new ProcessStartInfo(spartanPath, arg) { WorkingDirectory = gamePath }); } catch (Exception exception) { Logger.Error(exception, exception.Message); GenericMessageDialog.Show(Properties.Resources.StartGameError, DialogIcon.Error); } }
private async void btn_Play_Click(object sender, EventArgs e) { var pname = Process.GetProcessesByName("spartan"); if (pname.Length > 0) { SkinHelper.ShowMessage(@"Game already runing!"); return; } //UserConfig if (Program.UserConfig != null) { //MpSettings try { if (Program.UserConfig.MpSettings != null) { if (Program.UserConfig.MpSettings.IsOnline) { Program.UserConfig.MpSettings.PublicIp = Program.RemoteUser.Ip; if (Program.UserConfig.MpSettings.AutoPortMapping) { var mapPortTask = OpenNat.MapPortTask(1000, 1000); try { await mapPortTask; NatDiscoverer.TraceSource.Close(); } catch (AggregateException ex) { NatDiscoverer.TraceSource.Close(); if (!(ex.InnerException is NatDeviceNotFoundException)) { throw; } SkinHelper.ShowMessage( "Error: Upnp device not found! Set \"Port mapping\" to manual in \"Mp Settings\" and configure your router.", @"Project Celeste", MessageBoxButtons.OK, MessageBoxIcon.Error); Enabled = true; return; } } } } } catch { SkinHelper.ShowMessage( "Error: Upnp device not found! Set \"Port mapping\" to manual in \"Mp Settings\" and configure your router.", @"Project Celeste", MessageBoxButtons.OK, MessageBoxIcon.Error); Enabled = true; return; } //Save UserConfig Program.UserConfig.GameLanguage = (GameLanguage)comboBox2.SelectedIndex; Program.UserConfig.Save(Program.UserConfigFilePath); } //Launch Game var path = $"{AppDomain.CurrentDomain.BaseDirectory}Spartan.exe"; Process.Start(path, $"LauncherLang={comboBox2.Text} LauncherLocale=1033"); }
private async void Btn_Play_Click(object sender, EventArgs e) { btn_Play.Enabled = false; var pname = Process.GetProcessesByName("spartan"); if (pname.Length > 0) { MsgBox.ShowMessage(@"Game already running!"); btn_Play.Enabled = true; return; } //QuickGameScan try { var gameFilePath = !string.IsNullOrWhiteSpace(Program.UserConfig.GameFilesPath) ? Program.UserConfig.GameFilesPath : GameScannnerApi.GetGameFilesRootPath(); var gameScannner = new GameScannnerApi(gameFilePath, Program.UserConfig.IsSteamVersion, Program.UserConfig.IsLegacyXLive); retry: if (!await gameScannner.QuickScan()) { bool success; using (var form = new MsgBoxYesNo( @"Error: Your game files are corrupted or outdated. Click ""Yes"" to run a ""Game Scan"" to fix your game files, or ""No"" to ignore the error (not recommended).") ) { var dr = form.ShowDialog(); if (dr == DialogResult.OK) { using (var form2 = new GameScan()) { form2.ShowDialog(); success = false; } } else { success = true; } } if (!success) { goto retry; } } } catch (Exception ex) { MsgBox.ShowMessage( $"Warning: Error during quick scan. Error message: {ex.Message}", @"Celeste Fan Project", MessageBoxButtons.OK, MessageBoxIcon.Warning); } //isSteam if (!Program.UserConfig.IsSteamVersion) { var steamApiDll = $"{Program.UserConfig.GameFilesPath}\\steam_api.dll"; if (File.Exists(steamApiDll)) { File.Delete(steamApiDll); } } //MpSettings try { if (Program.UserConfig.MpSettings != null) { if (Program.UserConfig.MpSettings.IsOnline) { Program.UserConfig.MpSettings.PublicIp = Program.CurrentUser.Ip; if (Program.UserConfig.MpSettings.AutoPortMapping) { var mapPortTask = OpenNat.MapPortTask(1000, 1000); try { await mapPortTask; NatDiscoverer.TraceSource.Close(); } catch (AggregateException ex) { NatDiscoverer.TraceSource.Close(); if (!(ex.InnerException is NatDeviceNotFoundException)) { throw; } MsgBox.ShowMessage( "Error: Upnp device not found! Set \"Port mapping\" to manual in \"Mp Settings\" and configure your router.", @"Celeste Fan Project", MessageBoxButtons.OK, MessageBoxIcon.Error); btn_Play.Enabled = true; return; } } } } } catch { MsgBox.ShowMessage( "Error: Upnp device not found! Set \"Port mapping\" to manual in \"Mp Settings\" and configure your router.", @"Celeste Fan Project", MessageBoxButtons.OK, MessageBoxIcon.Error); btn_Play.Enabled = true; return; } try { //Save UserConfig Program.UserConfig.Save(Program.UserConfigFilePath); } catch { // } try { //Launch Game var path = !string.IsNullOrEmpty(Program.UserConfig.GameFilesPath) ? Program.UserConfig.GameFilesPath : GameScannnerApi.GetGameFilesRootPath(); if (!path.EndsWith(Path.DirectorySeparatorChar.ToString())) { path += Path.DirectorySeparatorChar; } var spartanPath = Path.Combine(path, "Spartan.exe"); if (!File.Exists(spartanPath)) { throw new FileNotFoundException("Spartan.exe not found!", spartanPath); } string lang; switch (Program.UserConfig.GameLanguage) { case GameLanguage.deDE: lang = "de-DE"; break; case GameLanguage.enUS: lang = "en-US"; break; case GameLanguage.esES: lang = "es-ES"; break; case GameLanguage.frFR: lang = "fr-FR"; break; case GameLanguage.itIT: lang = "it-IT"; break; case GameLanguage.zhCHT: lang = "zh-CHT"; break; default: throw new ArgumentOutOfRangeException(); } try { if (Program.UserConfig.IsDiagnosticMode) { var procdumpFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "procdump.exe"); const int maxNumOfCrashDumps = 30; if (!File.Exists(procdumpFileName)) { throw new FileNotFoundException("Diagonstic Mode requires procdump.exe (File not Found)", procdumpFileName); } // First ensure that all directories are set var pathToCrashDumpFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), @"Spartan\MiniDumps"); if (!Directory.Exists(pathToCrashDumpFolder)) { Directory.CreateDirectory(pathToCrashDumpFolder); } // Check for cleanup Directory.GetFiles(pathToCrashDumpFolder) .OrderByDescending(File.GetLastWriteTime) // Sort by age --> old one last .Skip(maxNumOfCrashDumps) // Skip max num crash dumps .ToList() .ForEach(File.Delete); // Remove the rest var excludeExceptions = new[] { "E0434F4D.COM", // .NET native exception "E06D7363.msc", "E06D7363.PAVEEFileLoadException@@", "E0434F4D.System.IO.FileNotFoundException" // .NET managed exception }; var excludeExcpetionsCmd = string.Join(" ", excludeExceptions.Select(elem => "-fx " + elem)); var fullCmdArgs = "-accepteula -mm -e 1 -n 10 " + excludeExcpetionsCmd + " -g -w Spartan.exe \"" + pathToCrashDumpFolder + "\""; // MsgBox.ShowMessage(fullCmd); var startInfo = new ProcessStartInfo(procdumpFileName, fullCmdArgs) { WorkingDirectory = path, CreateNoWindow = true, UseShellExecute = false, RedirectStandardError = true, RedirectStandardOutput = true }; Process.Start(startInfo); } } catch (Exception exception) { MsgBox.ShowMessage( $"Warning: {exception.Message}", @"Celeste Fan Project", MessageBoxButtons.OK, MessageBoxIcon.Warning); } var arg = Program.UserConfig?.MpSettings == null || Program.UserConfig.MpSettings.IsOnline ? $"--email \"{Program.UserConfig.LoginInfo.Email}\" --password \"{Program.UserConfig.LoginInfo.Password}\" --ignore_rest LauncherLang={lang} LauncherLocale=1033" : $"--email \"{Program.UserConfig.LoginInfo.Email}\" --password \"{Program.UserConfig.LoginInfo.Password}\" --online-ip \"{Program.UserConfig.MpSettings.PublicIp}\" --ignore_rest LauncherLang={lang} LauncherLocale=1033"; Process.Start(new ProcessStartInfo(spartanPath, arg) { WorkingDirectory = path }); WindowState = FormWindowState.Minimized; } catch (Exception exception) { MsgBox.ShowMessage( $"Error: {exception.Message}", @"Celeste Fan Project", MessageBoxButtons.OK, MessageBoxIcon.Error); } btn_Play.Enabled = true; }