Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ModSupport & ModManager] Edit launch logic and create shortcut button #314

Merged
merged 12 commits into from
Sep 29, 2023
12 changes: 12 additions & 0 deletions FrostyModManager/FrostyModManager.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@
<Resource Include="Images\PrimaryActionAdd.png" />
<Resource Include="Images\PrimaryActionMerge.png" />
<Resource Include="Images\Open.png" />
<Resource Include="Images\SaveAs.png" />
<Content Include="ThirdParty\Newtonsoft.Json.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
Expand All @@ -301,6 +302,17 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
wannkunstbeikor marked this conversation as resolved.
Show resolved Hide resolved
<COMReference Include="IWshRuntimeLibrary">
<Guid>{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
Expand Down
Binary file added FrostyModManager/Images/SaveAs.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 6 additions & 1 deletion FrostyModManager/Windows/ManageModDataWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ ResizeMode="NoResize" WindowStartupLocation="CenterOwner">
<ColumnDefinition Width="16"/>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="16"/>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="16"/>
</Grid.ColumnDefinitions>

<TextBlock Grid.Column="0" Text="{Binding Name}" VerticalAlignment="Center"/>
Expand All @@ -39,7 +41,10 @@ ResizeMode="NoResize" WindowStartupLocation="CenterOwner">
<Button x:Name="openModData" Grid.Column="3" Click="openModData_Click" ToolTip="Open Folder">
<Image Source="/FrostyModManager;component/Images/Open.png"/>
</Button>
<Button x:Name="deleteModData" Grid.Column="5" Click="deleteModData_Click" ToolTip="Delete Folder">
<Button x:Name="createShortcutToModData" Grid.Column="5" Click="createShortcutToModData_Click" ToolTip="Create shortcut to launch game with ModData">
<Image Source="/FrostyModManager;component/Images/SaveAs.png"/>
</Button>
<Button x:Name="deleteModData" Grid.Column="7" Click="deleteModData_Click" ToolTip="Delete Folder">
<Image Source="/FrostyModManager;component/Images/Remove.png"/>
</Button>
</Grid>
Expand Down
126 changes: 124 additions & 2 deletions FrostyModManager/Windows/ManageModDataWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -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
{
Expand Down Expand Up @@ -122,9 +128,125 @@ private void openModData_Click(object sender, RoutedEventArgs e)
/// Method <c>launchModData_Click</c> Attempts to launch game with existing ModData pack folder
/// </summary>
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<string>("GamePath", "", ConfigScope.Game, ProfilesLibrary.ProfileName) + "\\", modDirName, modDataPath, Config.Get<string>("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");
}

}

/// <summary>
/// Method <c>createShortcutToModData_Click</c> Attempts to create shortcut to launch game with ModData
/// </summary>
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<string>("GamePath", "", ConfigScope.Game, ProfilesLibrary.ProfileName) + '\\';
string modDirName = "ModData\\" + selectedPack.Name;
string modDataPath = getModDataPath() + $"\\{selectedPack.Name}\\";
string additionalArgs = Config.Get<string>("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");
}
}
}
}
}
}
34 changes: 19 additions & 15 deletions FrostyModSupport/FrostyModExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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<ModInfo> GenerateModInfoList(string[] modPaths, string rootPath)
{
List<ModInfo> modInfoList = new List<ModInfo>();
Expand Down