diff --git a/FrostyModManager/FrostyModManager.csproj b/FrostyModManager/FrostyModManager.csproj index b5b424afc..9267e349c 100644 --- a/FrostyModManager/FrostyModManager.csproj +++ b/FrostyModManager/FrostyModManager.csproj @@ -291,6 +291,7 @@ + PreserveNewest @@ -301,6 +302,17 @@ PreserveNewest + + + {F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} + 1 + 0 + 0 + tlbimp + False + True + + diff --git a/FrostyModManager/Images/SaveAs.png b/FrostyModManager/Images/SaveAs.png new file mode 100644 index 000000000..9e3b79641 Binary files /dev/null and b/FrostyModManager/Images/SaveAs.png differ diff --git a/FrostyModManager/Windows/ManageModDataWindow.xaml b/FrostyModManager/Windows/ManageModDataWindow.xaml index dbb15930e..77d612dd2 100644 --- a/FrostyModManager/Windows/ManageModDataWindow.xaml +++ b/FrostyModManager/Windows/ManageModDataWindow.xaml @@ -30,6 +30,8 @@ ResizeMode="NoResize" WindowStartupLocation="CenterOwner"> + + @@ -39,7 +41,10 @@ ResizeMode="NoResize" WindowStartupLocation="CenterOwner"> - + diff --git a/FrostyModManager/Windows/ManageModDataWindow.xaml.cs b/FrostyModManager/Windows/ManageModDataWindow.xaml.cs index be2edcb36..c8379f12a 100644 --- a/FrostyModManager/Windows/ManageModDataWindow.xaml.cs +++ b/FrostyModManager/Windows/ManageModDataWindow.xaml.cs @@ -1,11 +1,17 @@ -using System.Diagnostics; +using System; +using System.Diagnostics; using System.IO; +using System.Linq; +using System.Threading; using System.Windows; using System.Windows.Controls; using Frosty.Controls; using Frosty.Core; +using Frosty.Core.Controls; +using Frosty.Core.Windows; using Frosty.ModSupport; using FrostySdk; +using IWshRuntimeLibrary; namespace FrostyModManager { @@ -122,9 +128,125 @@ private void openModData_Click(object sender, RoutedEventArgs e) /// Method launchModData_Click Attempts to launch game with existing ModData pack folder /// private void launchModData_Click(object sender, RoutedEventArgs e) + { + // setup ability to cancel the process + CancellationTokenSource cancelToken = new CancellationTokenSource(); + + Pack selectedPack = ((Button)sender).DataContext as Pack; + string modDirName = "ModData\\" + selectedPack.Name; + string modDataPath = getModDataPath() + $"\\{selectedPack.Name}\\"; + + try + { + // run mod applying process + FrostyTaskWindow.Show("Launching", "", (task) => + { + App.Logger.Log("Launching"); + try + { + foreach (var executionAction in App.PluginManager.ExecutionActions) + executionAction.PreLaunchAction(task.TaskLogger, PluginManagerType.ModManager, cancelToken.Token); + + FrostyModExecutor.LaunchGame(Config.Get("GamePath", "", ConfigScope.Game, ProfilesLibrary.ProfileName) + "\\", modDirName, modDataPath, Config.Get("CommandLineArgs", "", ConfigScope.Game)); + + App.Logger.Log("Done"); + } + catch (OperationCanceledException) + { + // process was cancelled + App.Logger.Log("Launch Cancelled"); + } + catch (Exception ex) + { + App.Logger.Log("Error Launching Game: " + ex); + } + + }, showCancelButton: true, cancelCallback: (task) => cancelToken.Cancel()); + } + catch (OperationCanceledException) + { + // process was cancelled + App.Logger.Log("Launch Cancelled"); + } + + } + + /// + /// Method createShortcutToModData_Click Attempts to create shortcut to launch game with ModData + /// + private void createShortcutToModData_Click(object sender, RoutedEventArgs e) { Pack selectedPack = ((Button)sender).DataContext as Pack; - FrostyModExecutor.ExecuteProcess($"{Path.GetDirectoryName(getModDataPath())}\\{ProfilesLibrary.ProfileName}.exe", $"-dataPath \"{selectedPack.Path.Trim('\\')}\""); + string basePath = Config.Get("GamePath", "", ConfigScope.Game, ProfilesLibrary.ProfileName) + '\\'; + string modDirName = "ModData\\" + selectedPack.Name; + string modDataPath = getModDataPath() + $"\\{selectedPack.Name}\\"; + string additionalArgs = Config.Get("CommandLineArgs", "", ConfigScope.Game); + + string steamAppIdPath = $"{basePath}steam_appid.txt"; + if (System.IO.File.Exists(steamAppIdPath)) + { + FrostySaveFileDialog dialog = new FrostySaveFileDialog("Create Shortcut", "Steam Shortcut|*.url", "Shortcut", $"{ProfilesLibrary.DisplayName}_{selectedPack.Name}") + { + InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + }; + + if (dialog.ShowDialog()) + { + try + { + string steamAppId = System.IO.File.ReadAllLines(steamAppIdPath).First(); + string arguments = $"-dataPath \"{modDirName.Replace('\\', '/')}\" {additionalArgs}".Trim(); + string url = Uri.EscapeDataString(arguments); + App.Logger.Log($"Launch: {arguments}"); + App.Logger.Log($"Encoded: {url}"); + using (StreamWriter writer = new StreamWriter(dialog.FileName)) + { + writer.WriteLine("Prop3=19,0"); + writer.WriteLine("[InternetShortcut]"); + writer.WriteLine($"URL=steam://run/{steamAppId}//{url}/"); + + App.Logger.Log($"Steam shortcut write to: {dialog.FileName}"); + } + } + catch (Exception ex) + { + if (System.IO.File.Exists(dialog.FileName)) + { + System.IO.File.Delete(dialog.FileName); + } + FrostyExceptionBox.Show(ex, "Create Shortcut failed"); + } + } + } + else + { + FrostySaveFileDialog dialog = new FrostySaveFileDialog("Create Shortcut", "Shortcut|*.lnk", "Shortcut", $"{ProfilesLibrary.DisplayName.Replace("™", "")}_{selectedPack.Name}") + { + InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + }; + + if (dialog.ShowDialog()) + { + try + { + WshShell shell = new WshShell(); + IWshShortcut shortcut = shell.CreateShortcut(dialog.FileName.Replace("™", "")) as IWshShortcut; + shortcut.TargetPath = $"{basePath + ProfilesLibrary.ProfileName}.exe"; + shortcut.Arguments = $"-dataPath \"{modDataPath.Trim('\\')}\" {additionalArgs}"; + shortcut.Save(); + + App.Logger.Log($"Shortcut write to: {dialog.FileName}"); + } + catch (Exception ex) + { + if (System.IO.File.Exists(dialog.FileName)) + { + System.IO.File.Delete(dialog.FileName); + } + FrostyExceptionBox.Show(ex, "Create Shortcut failed"); + } + } + } } } } \ No newline at end of file diff --git a/FrostyModSupport/FrostyModExecutor.cs b/FrostyModSupport/FrostyModExecutor.cs index 70924ca9d..16de971c3 100644 --- a/FrostyModSupport/FrostyModExecutor.cs +++ b/FrostyModSupport/FrostyModExecutor.cs @@ -1814,21 +1814,7 @@ public int Run(FileSystem inFs, CancellationToken cancelToken, ILogger inLogger, try { - string steamAppIdPath = $"{fs.BasePath}steam_appid.txt"; - if (File.Exists(steamAppIdPath)) - { - string steamAppId = File.ReadAllLines(steamAppIdPath).First(); - string arguments = $"-dataPath \"{modDirName.Replace('\\', '/')}\" {additionalArgs}".Trim(); - string url = Uri.EscapeDataString(arguments); - App.Logger.Log($"Launch: {arguments}"); - App.Logger.Log($"Encoded: {url}"); - Process.Start($"steam://run/{steamAppId}//{url}/"); - } - else - { - ExecuteProcess($"{fs.BasePath + ProfilesLibrary.ProfileName}.exe", $"-dataPath \"{modDataPath.Trim('\\')}\" {additionalArgs}"); - } - + LaunchGame(fs.BasePath, modDirName, modDataPath, additionalArgs); } catch (Exception ex) { @@ -1841,6 +1827,24 @@ public int Run(FileSystem inFs, CancellationToken cancelToken, ILogger inLogger, return 0; } + public static void LaunchGame(string basePath, string modDirName, string modDataPath, string additionalArgs) + { + string steamAppIdPath = $"{basePath}steam_appid.txt"; + if (File.Exists(steamAppIdPath)) + { + string steamAppId = File.ReadAllLines(steamAppIdPath).First(); + string arguments = $"-dataPath \"{modDirName.Replace('\\', '/')}\" {additionalArgs}".Trim(); + string url = Uri.EscapeDataString(arguments); + App.Logger.Log($"Launch: {arguments}"); + App.Logger.Log($"Encoded: {url}"); + Process.Start($"steam://run/{steamAppId}//{url}/"); + } + else + { + ExecuteProcess($"{basePath + ProfilesLibrary.ProfileName}.exe", $"-dataPath \"{modDataPath.Trim('\\')}\" {additionalArgs}"); + } + } + private List GenerateModInfoList(string[] modPaths, string rootPath) { List modInfoList = new List();