pull/85/merge
Kyle 2 years ago committed by GitHub
commit c4a7de647a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -40,7 +40,7 @@ namespace UWPHook
if (args?.Length > 1)
{
// When length is 1, the only argument is the path where the app is installed
_ = LauncherAsync(args); // Launches the requested game
_ = LauncherAsync(args); // Launches the requested game
}
else
@ -210,7 +210,7 @@ namespace UWPHook
stream.Close();
client.Dispose();
}
});
});
}
/// <summary>
@ -218,16 +218,16 @@ namespace UWPHook
/// </summary>
/// <param name="user">The user path to copy images to</param>
private void CopyTempGridImagesToSteamUser(string user)
{
{
string tmpGridDirectory = Path.GetTempPath() + "UWPHook\\tmp_grid\\";
string userGridDirectory = user + "\\config\\grid\\";
// No images were downloaded, maybe the key is invalid or no app had an image
if (!Directory.Exists(tmpGridDirectory))
{
return;
}
string[] images = Directory.GetFiles(tmpGridDirectory);
if (!Directory.Exists(userGridDirectory))
@ -273,7 +273,7 @@ namespace UWPHook
{
throw;
}
if (games != null)
{
var game = games[0];
@ -348,7 +348,7 @@ namespace UWPHook
{
var users = SteamManager.GetUsers(steam_folder);
var selected_apps = Apps.Entries.Where(app => app.Selected);
var exePath = @"""" + System.Reflection.Assembly.GetExecutingAssembly().Location + @"""";
var exePath = GenerateExePath();
var exeDir = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
List<Task> gridImagesDownloadTasks = new List<Task>();
@ -370,89 +370,8 @@ namespace UWPHook
// Export the selected apps and the downloaded images to each user
// in the steam folder by modifying it's VDF file
foreach (var user in users)
{
try
{
VDFEntry[] shortcuts = new VDFEntry[0];
try
{
shortcuts = SteamManager.ReadShortcuts(user);
}
catch (Exception ex)
{
//If it's a short VDF, let's just overwrite it
if (ex.GetType() != typeof(VDFTooShortException))
{
throw new Exception("Error: Program failed to load existing Steam shortcuts." + Environment.NewLine + ex.Message);
}
}
if (shortcuts != null)
{
foreach (var app in selected_apps)
{
VDFEntry newApp = new VDFEntry()
{
AppName = app.Name,
Exe = exePath,
StartDir = exeDir,
LaunchOptions = app.Aumid,
AllowDesktopConfig = 1,
AllowOverlay = 1,
Icon = app.Icon,
Index = shortcuts.Length,
IsHidden = 0,
OpenVR = 0,
ShortcutPath = "",
Tags = tags,
Devkit = 0,
DevkitGameID = "",
LastPlayTime = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
};
Boolean isFound = false;
for (int i = 0; i < shortcuts.Length; i++)
{
Debug.WriteLine(shortcuts[i].ToString());
if (shortcuts[i].AppName == app.Name)
{
isFound = true;
Debug.WriteLine(app.Name + " already added to Steam. Updating existing shortcut.");
shortcuts[i] = newApp;
}
}
if (!isFound)
{
//Resize this array so it fits the new entries
Array.Resize(ref shortcuts, shortcuts.Length + 1);
shortcuts[shortcuts.Length - 1] = newApp;
}
}
try
{
if (!Directory.Exists(user + @"\\config\\"))
{
Directory.CreateDirectory(user + @"\\config\\");
}
//Write the file with all the shortcuts
File.WriteAllBytes(user + @"\\config\\shortcuts.vdf", VDFSerializer.Serialize(shortcuts));
}
catch (Exception ex)
{
throw new Exception("Error: Program failed while trying to write your Steam shortcuts" + Environment.NewLine + ex.Message);
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error: Program failed exporting your games:" + Environment.NewLine + ex.Message + ex.StackTrace);
}
}
ExportAppsToSteamShortcuts(tags, users, selected_apps, exePath, exeDir);
ExportAppsToShieldShortcuts(selected_apps, exePath, exeDir);
if (gridImagesDownloadTasks.Count > 0)
{
@ -463,6 +382,7 @@ namespace UWPHook
foreach (var user in users)
{
CopyTempGridImagesToSteamUser(user);
CopyTempGridImagesToShieldStreamingAssets(selected_apps);
}
RemoveTempGridImages();
@ -470,7 +390,7 @@ namespace UWPHook
}
}
if(restartSteam)
if (restartSteam)
{
Func<Process> getSteam = () => Process.GetProcessesByName("steam").SingleOrDefault();
@ -517,6 +437,103 @@ namespace UWPHook
return true;
}
/// <summary>
/// Extracted method to simplify the complexity of the ExportGames method.
///
/// This method updates and existing steam vdf file to add or update shortcuts for the selected windows apps.
/// </summary>
/// <param name="tags"></param>
/// <param name="users"></param>
/// <param name="selected_apps"></param>
/// <param name="exePath"></param>
/// <param name="exeDir"></param>
private static void ExportAppsToSteamShortcuts(string[] tags, string[] users, IEnumerable<AppEntry> selected_apps, string exePath, string exeDir)
{
foreach (var user in users)
{
try
{
VDFEntry[] shortcuts = new VDFEntry[0];
try
{
shortcuts = SteamManager.ReadShortcuts(user);
}
catch (Exception ex)
{
//If it's a short VDF, let's just overwrite it
if (ex.GetType() != typeof(VDFTooShortException))
{
throw new Exception("Error: Program failed to load existing Steam shortcuts." + Environment.NewLine + ex.Message);
}
}
if (shortcuts != null)
{
foreach (var app in selected_apps)
{
VDFEntry newApp = new VDFEntry()
{
AppName = app.Name,
Exe = exePath,
StartDir = exeDir,
LaunchOptions = app.Aumid,
AllowDesktopConfig = 1,
AllowOverlay = 1,
Icon = app.Icon,
Index = shortcuts.Length,
IsHidden = 0,
OpenVR = 0,
ShortcutPath = "",
Tags = tags,
Devkit = 0,
DevkitGameID = "",
LastPlayTime = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
};
Boolean isFound = false;
for (int i = 0; i < shortcuts.Length; i++)
{
Debug.WriteLine(shortcuts[i].ToString());
if (shortcuts[i].AppName == app.Name)
{
isFound = true;
Debug.WriteLine(app.Name + " already added to Steam. Updating existing shortcut.");
shortcuts[i] = newApp;
}
}
if (!isFound)
{
//Resize this array so it fits the new entries
Array.Resize(ref shortcuts, shortcuts.Length + 1);
shortcuts[shortcuts.Length - 1] = newApp;
}
}
try
{
if (!Directory.Exists(user + @"\\config\\"))
{
Directory.CreateDirectory(user + @"\\config\\");
}
//Write the file with all the shortcuts
File.WriteAllBytes(user + @"\\config\\shortcuts.vdf", VDFSerializer.Serialize(shortcuts));
}
catch (Exception ex)
{
throw new Exception("Error: Program failed while trying to write your Steam shortcuts" + Environment.NewLine + ex.Message);
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error: Program failed exporting your games:" + Environment.NewLine + ex.Message + ex.StackTrace);
}
}
}
public static void ClearAllShortcuts()
{
Debug.WriteLine("DBG: Clearing all elements in shortcuts.vdf");
@ -695,5 +712,140 @@ namespace UWPHook
}
}
}
/// <summary>
/// Generates the exe path used by Steam and NVIDIA Shield to call UWPHook
/// </summary>
/// <returns></returns>
private static string GenerateExePath()
{
return @"""" + System.Reflection.Assembly.GetExecutingAssembly().Location + @"""";
}
/// <summary>
/// Iterates through the selected apps and creates windwos shortcut files for each inside the NVIDIA Shield Apps directory.
/// Will place an NVIDIA required placeholder box-art.png file inside the StreamingAssets/{app-name} dir.
/// </summary>
/// <param name="selected_apps"></param>
/// <param name="exePath"></param>
/// <param name="exeDir"></param>
private static void ExportAppsToShieldShortcuts(IEnumerable<AppEntry> selected_apps, string exePath, string exeDir)
{
string shieldAppsDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "NVIDIA Corporation", "Shield Apps");
string streamingAssetsDir = Path.Combine(shieldAppsDir, "StreamingAssets");
if (!Directory.Exists(streamingAssetsDir))
{
DirectoryInfo di = Directory.CreateDirectory(streamingAssetsDir);
di.Attributes = FileAttributes.Directory | FileAttributes.Hidden;
}
foreach (AppEntry app in selected_apps)
{
string scrubbedAppName = app.Name;
foreach (char c in Path.GetInvalidFileNameChars())
{
scrubbedAppName = scrubbedAppName.Replace(c, '_');
}
string shortcutFile = Path.Combine(shieldAppsDir, scrubbedAppName + ".lnk");
Debug.WriteLine("Creating NVIDIA Shield shortcut: " + shortcutFile);
IWshRuntimeLibrary.IWshShell3 wsh = new IWshRuntimeLibrary.IWshShell_Class();
IWshRuntimeLibrary.IWshShortcut shortcut = wsh.CreateShortcut(shortcutFile);
shortcut.Arguments = app.Aumid;
shortcut.TargetPath = exePath;
// not sure about what this is for
shortcut.WindowStyle = 1;
shortcut.Description = "test link for " + app.Name;
shortcut.WorkingDirectory = exeDir;
//shortcut.IconLocation = "specify icon location";
shortcut.Save();
// Copy over placeholder box-art.png (required by NVIDIA)
string boxArtDir = Path.Combine(streamingAssetsDir, scrubbedAppName);
string boxArtFile = Path.Combine(streamingAssetsDir, scrubbedAppName, "box-art.png");
if (!Directory.Exists(boxArtDir))
{
Debug.WriteLine("creating directory for game streaming assets: " + boxArtDir);
try
{
Directory.CreateDirectory(boxArtDir);
}
catch (Exception e)
{
Console.Error.WriteLine("unable to create game streaming assets dir: {0}", e);
}
}
try
{
Debug.WriteLine("copying placeholder box-art to " + boxArtFile);
Properties.Resources.box_art.Save(boxArtFile);
}
catch (Exception e)
{
Console.Error.WriteLine("unable to copy placeholder box-art: {0}", e);
}
}
}
/// <summary>
/// Copies all temporary images to the {drive}:/Users/{user}/Appdata/Local/NVIDIA Corporation/Shield Apps/StreamingAssets/{scrubbed game name} dirs
/// </summary>
/// <param name="selectedApps">Selected app entrys to copy images for</param>
private void CopyTempGridImagesToShieldStreamingAssets(IEnumerable<AppEntry> selectedApps)
{
string tmpGridDirectory = Path.Combine(Path.GetTempPath(), "UWPHook", "tmp_grid");
string streamingAssetsDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "NVIDIA Corporation", "Shield Apps", "StreamingAssets");
// No images were downloaded, maybe the key is invalid or no app had an image
if (!Directory.Exists(tmpGridDirectory))
{
return;
}
if (!Directory.Exists(streamingAssetsDirectory))
{
DirectoryInfo di = Directory.CreateDirectory(streamingAssetsDirectory);
di.Attributes = FileAttributes.Directory | FileAttributes.Hidden;
}
foreach (AppEntry app in selectedApps)
{
string scrubbedAppName = app.Name;
foreach (char c in Path.GetInvalidFileNameChars())
{
scrubbedAppName = scrubbedAppName.Replace(c, '_');
}
ulong gameId = GenerateSteamGridAppId(app.Name, GenerateExePath());
string srcFile = Path.Combine(tmpGridDirectory, string.Format("{0}p.png", gameId));
string destDir = Path.Combine(streamingAssetsDirectory, scrubbedAppName);
string destFile = Path.Combine(destDir, "box-art.png");
if (!Directory.Exists(destDir))
{
try
{
Debug.WriteLine("Creating directory: ", destDir);
_ = Directory.CreateDirectory(destDir);
}
catch (Exception e)
{
Console.Error.WriteLine("unable to create directory: ", e);
}
}
try
{
Debug.WriteLine("Copying box-art image from {0} to {1}", new object[] { srcFile, destFile });
File.Copy(srcFile, destFile, true);
}
catch (Exception e)
{
Console.Error.WriteLine("unable to copy box-art: ", e);
}
}
}
}
}

@ -60,6 +60,16 @@ namespace UWPHook.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
public static System.Drawing.Bitmap box_art {
get {
object obj = ResourceManager.GetObject("box_art", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>

@ -118,6 +118,9 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="box_art" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\box-art.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="GetAUMIDScript" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\GetAUMIDScript.ps1;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

@ -92,7 +92,6 @@
<ToggleButton x:Name="change_resolution_toggle" Style="{StaticResource MaterialDesignSwitchToggleButton}" VerticalAlignment="Top" Margin="0,9,0,0" ToolTip="MaterialDesignSwitchToggleButton" IsChecked="False" Height="18" Grid.Row="3" />
<Label ToolTip="Change the host computer resolution on launch, return to previous after." x:Name="label1_Copy8" Content="Change host resolution to:" Margin="5,3,0,0" VerticalAlignment="Top" Height="29" Grid.Column="1" Grid.Row="3"/>
<ComboBox x:Name="seconds_comboBox_Copy" Margin="0,3,10,0" VerticalAlignment="Top" Height="31" Grid.Column="2" HorizontalAlignment="Right" Width="217" Grid.Row="3" Grid.ColumnSpan="2"/>
<Button x:Name="test2" Content="Save" HorizontalAlignment="Right" VerticalAlignment="Top" Width="93" Click="test_Click" Grid.Column="1" Grid.Row="6" Margin="0,10,10,0"/>
</Grid>
<Grid Margin="10,88,9,35" Grid.Column="1" Grid.RowSpan="2">
<Grid.ColumnDefinitions>

@ -98,13 +98,5 @@ namespace UWPHook
System.Diagnostics.Process.Start("https://www.steamgriddb.com/profile/preferences/api");
}
private void test()
{
FixHeight = 1280;
FixWidth = 1024;
Resolution.CResolution ChangeRes1024 = new Resolution.CResolution(FixHeight, FixWidth);
}
}
}

@ -33,7 +33,8 @@ namespace UWPHook.SteamGridDb
/// <returns>Array of games corresponding to the provided name</returns>
public async Task<GameResponse[]> SearchGame(string gameName)
{
string path = $"search/autocomplete/{gameName}";
// remove any forward slashes in the gameName to allow Games like FINAL FANTASY X/X-2 HD Remaster to be found
string path = $"search/autocomplete/{gameName.Replace('/', ' ')}";
GameResponse[] games = null;
HttpResponseMessage response = await httpClient.GetAsync(path);

@ -67,9 +67,8 @@
<HintPath>..\packages\MaterialDesignColors.2.0.4\lib\net452\MaterialDesignColors.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="MaterialDesignThemes.Wpf, Version=4.3.0.3, Culture=neutral, PublicKeyToken=df2a72020bd7962a, processorArchitecture=MSIL">
<HintPath>..\packages\MaterialDesignThemes.4.3.0\lib\net452\MaterialDesignThemes.Wpf.dll</HintPath>
<Private>True</Private>
<Reference Include="MaterialDesignThemes.Wpf, Version=4.1.0.2556, Culture=neutral, PublicKeyToken=df2a72020bd7962a, processorArchitecture=MSIL">
<HintPath>..\packages\MaterialDesignThemes.4.1.0\lib\net452\MaterialDesignThemes.Wpf.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
@ -216,6 +215,9 @@
<ItemGroup>
<Resource Include="Resources\square.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\box-art.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\MaterialDesignThemes.4.1.0\build\MaterialDesignThemes.targets" Condition="Exists('..\packages\MaterialDesignThemes.4.1.0\build\MaterialDesignThemes.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
@ -223,9 +225,7 @@
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\MaterialDesignThemes.4.1.0\build\MaterialDesignThemes.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MaterialDesignThemes.4.1.0\build\MaterialDesignThemes.targets'))" />
<Error Condition="!Exists('..\packages\MaterialDesignThemes.4.3.0\build\MaterialDesignThemes.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MaterialDesignThemes.4.3.0\build\MaterialDesignThemes.targets'))" />
</Target>
<Import Project="..\packages\MaterialDesignThemes.4.3.0\build\MaterialDesignThemes.targets" Condition="Exists('..\packages\MaterialDesignThemes.4.3.0\build\MaterialDesignThemes.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">

@ -2,7 +2,7 @@
<packages>
<package id="Crc32.NET" version="1.2.0" targetFramework="net462" />
<package id="MaterialDesignColors" version="2.0.4" targetFramework="net462" />
<package id="MaterialDesignThemes" version="4.3.0" targetFramework="net462" />
<package id="MaterialDesignThemes" version="4.1.0" targetFramework="net462" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.7" targetFramework="net462" />
<package id="Microsoft.PowerShell.5.ReferenceAssemblies" version="1.1.0" targetFramework="net462" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net462" />

Loading…
Cancel
Save