/// <summary> /// Creates the update script on disk. /// </summary> /// <returns>ProcessStartInfo for the update script.</returns> public static ProcessStartInfo CreateUpdateScript() { try { var updateScriptPath = GetUpdateScriptPath(); var updateScriptSource = GetUpdateScriptSource(); File.WriteAllText(updateScriptPath, updateScriptSource); if (PlatformHelpers.IsRunningOnUnix()) { var chmod = Process.Start("chmod", $"+x {updateScriptPath}"); chmod?.WaitForExit(); } var updateShellProcess = new ProcessStartInfo { FileName = updateScriptPath, UseShellExecute = false, RedirectStandardOutput = false, CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Normal }; return(updateShellProcess); } catch (IOException ioex) { Log.Warn("Failed to create update script (IOException): " + ioex.Message); return(null); } }
/// <summary> /// Gets the name of the embedded update script. /// </summary> private static string GetUpdateScriptPath() { if (PlatformHelpers.IsRunningOnUnix()) { return(Path.Combine(Path.GetTempPath(), "launchpad_update.sh")); } return(Path.Combine(Path.GetTempPath(), "launchpad_update.bat")); }
/// <summary> /// Attempts to parse an entry from a raw input. /// The input is expected to be in [path]:[hash]:[size] format. Note that the file path is case sensitive, /// but the hash is not. /// </summary> /// <returns><c>true</c>, if the input was successfully parse, <c>false</c> otherwise.</returns> /// <param name="rawInput">Raw input.</param> /// <param name="inEntry">The resulting entry.</param> public static bool TryParse(string rawInput, out ManifestEntry inEntry) { // Clear out the entry for the new data inEntry = new ManifestEntry(); if (string.IsNullOrEmpty(rawInput)) { return(false); } var cleanInput = rawInput.RemoveLineSeparatorsAndNulls(); // Split the string into its three components - file, hash and size var entryElements = cleanInput.Split(':'); // If we have three elements (which we should always have), set them in the provided entry if (entryElements.Length != 3) { return(false); } // Sanitize the manifest path, converting \ to / on unix and / to \ on Windows. if (PlatformHelpers.IsRunningOnUnix()) { inEntry.RelativePath = entryElements[0].Replace('\\', '/'); } else { inEntry.RelativePath = entryElements[0].Replace('/', '\\'); } // Hashes must be exactly 32 characters if (entryElements[1].Length != 32) { return(false); } // Set the hash to the second element inEntry.Hash = entryElements[1]; // Attempt to parse the final element as a long-type byte count. if (!long.TryParse(entryElements[2], out var parsedSize)) { // Oops. The parsing failed, so this entry is invalid. return(false); } // Negative sizes are not allowed if (parsedSize < 0) { return(false); } inEntry.Size = parsedSize; return(true); }
/// <summary> /// Gets the name of the embedded update script. /// </summary> private static string GetUpdateScriptPath() { if (PlatformHelpers.IsRunningOnUnix()) { return($@"{Path.GetTempPath()}launchpad_update.sh"); } else { return($@"{Path.GetTempPath()}launchpad_update.bat"); } }
/// <summary> /// Gets the name of the embedded update script. /// </summary> private static string GetUpdateScriptResourceName() { if (PlatformHelpers.IsRunningOnUnix()) { return("Launchpad.Launcher.Resources.launchpad_update.sh"); } else { return("Launchpad.Launcher.Resources.launchpad_update.bat"); } }
/// <summary> /// Initializes a new instance of the <see cref="Changelog"/> class. /// </summary> /// <param name="parentContainer">The parent GTK container where the changelog should be added.</param> public Changelog(Container parentContainer) { if (!PlatformHelpers.IsRunningOnUnix()) { this.WindowsBrowser = new WindowsBrowser(parentContainer); this.WidgetHandle = this.WindowsBrowser.WidgetHandle; this.WindowsBrowser.Browser.Navigating += OnWindowsBrowserNavigating; } else { this.UnixBrowser = new WebView(); this.WidgetHandle = this.UnixBrowser; this.UnixBrowser.NavigationRequested += OnUnixBrowserNavigating; parentContainer.Add(this.WidgetHandle); } }
/// <summary> /// Launches the game. /// </summary> public void LaunchGame() { try { var executable = Path.Combine(DirectoryHelpers.GetLocalGameDirectory(), Configuration.ExecutablePath); if (!File.Exists(executable)) { throw new FileNotFoundException($"Game executable at path (\"{executable}\") not found."); } var executableDir = Path.GetDirectoryName(executable) ?? DirectoryHelpers.GetLocalLauncherDirectory(); // Do not move the argument assignment inside the gameStartInfo initializer. // It causes a TargetInvocationException crash through black magic. var gameArguments = string.Join(" ", this.GameArgumentService.GetGameArguments()); var gameStartInfo = new ProcessStartInfo { FileName = executable, Arguments = gameArguments, WorkingDirectory = executableDir }; Log.Info($"Launching game. \n\tExecutable path: {gameStartInfo.FileName}"); var gameProcess = new Process { StartInfo = gameStartInfo, EnableRaisingEvents = true }; gameProcess.Exited += (sender, args) => { if (gameProcess.ExitCode != 0) { Log.Info ( $"The game exited with an exit code of {gameProcess.ExitCode}. " + "There may have been issues during runtime, or the game may not have started at all." ); } OnGameExited(gameProcess.ExitCode); // Manual disposing gameProcess.Dispose(); }; // Make sure the game executable is flagged as such on Unix if (PlatformHelpers.IsRunningOnUnix()) { Process.Start("chmod", $"+x {gameStartInfo.FileName}"); } gameProcess.Start(); } catch (FileNotFoundException fex) { Log.Warn($"Game launch failed (FileNotFoundException): {fex.Message}"); Log.Warn("If the game executable is there, try overriding the executable name in the configuration file."); OnGameLaunchFailed(); } catch (IOException ioex) { Log.Warn($"Game launch failed (IOException): {ioex.Message}"); OnGameLaunchFailed(); } }
/// <summary> /// Installs the dependencies. /// </summary> protected override void InstallDependencies() { try { var executable = Path.Combine(DirectoryHelpers.GetLocalGameDirectory(), "Engine/Extras/Redist/en-us/UE4PrereqSetup_x64.exe"); Log.Info($"executable {executable}"); if (!File.Exists(executable)) { throw new FileNotFoundException($"Game executable at path (\"{executable}\") not found."); } var executableDir = Path.GetDirectoryName(executable) ?? DirectoryHelpers.GetLocalLauncherDirectory(); // Do not move the argument assignment inside the gameStartInfo initializer. // It causes a TargetInvocationException crash through black magic. var gameStartInfo = new ProcessStartInfo { FileName = executable, Arguments = string.Empty, WorkingDirectory = executableDir }; Log.Info($"Launching game. \n\tExecutable path: {gameStartInfo.FileName}"); var gameProcess = new Process { StartInfo = gameStartInfo, EnableRaisingEvents = true }; gameProcess.Exited += (sender, args) => { if (gameProcess.ExitCode != 0) { Log.Info ( $"The game exited with an exit code of {gameProcess.ExitCode}. " + "There may have been issues during runtime, or the game may not have started at all." ); } // Manual disposing gameProcess.Dispose(); }; // Make sure the game executable is flagged as such on Unix if (PlatformHelpers.IsRunningOnUnix()) { Process.Start("chmod", $"+x {gameStartInfo.FileName}"); } gameProcess.Start(); } catch (FileNotFoundException fex) { Log.Warn($"Dependencies installation failed (FileNotFoundException): {fex.Message}"); Log.Warn("Check for the UE4 installation."); } catch (IOException ioex) { Log.Warn($"Dependencies installation failed (IOException): {ioex.Message}"); } }