diff --git a/UWPHook/App.config b/UWPHook/App.config index c80186b..f9ab9ff 100644 --- a/UWPHook/App.config +++ b/UWPHook/App.config @@ -14,7 +14,7 @@ False - + 5 @@ -22,6 +22,9 @@ False + + + diff --git a/UWPHook/GamesWindow.xaml.cs b/UWPHook/GamesWindow.xaml.cs index c35f409..1baa8df 100644 --- a/UWPHook/GamesWindow.xaml.cs +++ b/UWPHook/GamesWindow.xaml.cs @@ -1,13 +1,19 @@ -using SharpSteam; +using Force.Crc32; +using SharpSteam; using System; using System.Collections.Generic; using System.ComponentModel; +using System.Drawing; +using System.Drawing.Imaging; using System.Globalization; using System.IO; using System.Linq; +using System.Net; +using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; +using UWPHook.SteamGridDb; using VDFParser; using VDFParser.Models; @@ -104,36 +110,157 @@ namespace UWPHook } } - private void ExportButton_Click(object sender, RoutedEventArgs e) + private UInt64 GenerateSteamGridAppId(string appName, string appTarget) { - bwrSave = new BackgroundWorker(); - bwrSave.DoWork += BwrSave_DoWork; - bwrSave.RunWorkerCompleted += BwrSave_RunWorkerCompleted; - grid.IsEnabled = false; - progressBar.Visibility = Visibility.Visible; + byte[] nameTargetBytes = Encoding.UTF8.GetBytes(appTarget + appName + ""); + UInt64 crc = Crc32Algorithm.Compute(nameTargetBytes); + UInt64 gameId = crc | 0x80000000; - bwrSave.RunWorkerAsync(); + return gameId; } - private void BwrSave_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + private async void ExportButton_Click(object sender, RoutedEventArgs e) { + grid.IsEnabled = false; + progressBar.Visibility = Visibility.Visible; + + await ExportGames(); + grid.IsEnabled = true; progressBar.Visibility = Visibility.Collapsed; MessageBox.Show("Your apps were successfuly exported, please restart Steam in order to see your apps.", "UWPHook", MessageBoxButton.OK, MessageBoxImage.Information); } - private void BwrSave_DoWork(object sender, DoWorkEventArgs e) + private async Task SaveImage(string imageUrl, string destinationFilename, ImageFormat format) + { + await Task.Run(() => + { + WebClient client = new WebClient(); + Stream stream = client.OpenRead(imageUrl); + Bitmap bitmap; bitmap = new Bitmap(stream); + + if (bitmap != null) + { + bitmap.Save(destinationFilename, format); + } + + stream.Flush(); + stream.Close(); + client.Dispose(); + }); + } + + private void CopyTempGridImagesToSteamUser(string user) + { + string tmpGridDirectory = Path.GetTempPath() + "UWPHook\\tmp_grid\\"; + string userGridDirectory = user + "\\config\\grid\\"; + string[] images = Directory.GetFiles(tmpGridDirectory); + + if (!Directory.Exists(userGridDirectory)) + { + Directory.CreateDirectory(userGridDirectory); + } + + foreach (string image in images) + { + string destFile = userGridDirectory + Path.GetFileName(image); + File.Copy(image, destFile, true); + } + } + + private void RemoveTempGridImages() + { + string tmpGridDirectory = Path.GetTempPath() + "UWPHook\\tmp_grid\\"; + Directory.Delete(tmpGridDirectory, true); + } + + private async Task DownloadTempGridImages(string appName, string appTarget) + { + SteamGridDbApi api = new SteamGridDbApi(Properties.Settings.Default.SteamGridDbApiKey); + string tmpGridDirectory = Path.GetTempPath() + "UWPHook\\tmp_grid\\"; + + var games = await api.SearchGame(appName); + + if (games != null) + { + var game = games[0]; + UInt64 gameId = GenerateSteamGridAppId(appName, appTarget); + + if (!Directory.Exists(tmpGridDirectory)) + { + Directory.CreateDirectory(tmpGridDirectory); + } + + var gameGridsVertical = api.GetGameGrids(game.Id, "600x900", "static"); + var gameGridsHorizontal = api.GetGameGrids(game.Id, "460x215", "static"); + var gameHeroes = api.GetGameHeroes(game.Id, "static"); + var gameLogos = api.GetGameLogos(game.Id, "static"); + + await Task.WhenAll( + gameGridsVertical, + gameGridsHorizontal, + gameHeroes, + gameLogos + ); + + var gridsVertical = await gameGridsVertical; + var gridsHorizontal = await gameGridsHorizontal; + var heroes = await gameHeroes; + var logos = await gameLogos; + + List saveImagesTasks = new List(); + + if (gridsHorizontal != null && gridsHorizontal.Length > 0) + { + var grid = gridsHorizontal[0]; + saveImagesTasks.Add(SaveImage(grid.Url, $"{tmpGridDirectory}\\{gameId}.png", ImageFormat.Png)); + } + + if (gridsVertical != null && gridsVertical.Length > 0) + { + var grid = gridsVertical[0]; + saveImagesTasks.Add(SaveImage(grid.Url, $"{tmpGridDirectory}\\{gameId}p.png", ImageFormat.Png)); + } + + if (heroes != null && heroes.Length > 0) + { + var hero = heroes[0]; + saveImagesTasks.Add(SaveImage(hero.Url, $"{tmpGridDirectory}\\{gameId}_hero.png", ImageFormat.Png)); + } + + if (logos != null && logos.Length > 0) + { + var logo = logos[0]; + saveImagesTasks.Add(SaveImage(logo.Url, $"{tmpGridDirectory}\\{gameId}_logo.png", ImageFormat.Png)); + } + + await Task.WhenAll(saveImagesTasks); + + } + } + + private async Task ExportGames() { string steam_folder = SteamManager.GetSteamFolder(); if (Directory.Exists(steam_folder)) { var users = SteamManager.GetUsers(steam_folder); var selected_apps = Apps.Entries.Where(app => app.Selected); + var exePath = @"""" + System.Reflection.Assembly.GetExecutingAssembly().Location + @""""; + var exeDir = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); + + List gridImagesDownloadTasks = new List(); + bool downloadGridImages = !String.IsNullOrEmpty(Properties.Settings.Default.SteamGridDbApiKey); - //To make things faster, decide icons before looping users + //To make things faster, decide icons and download grid images before looping users foreach (var app in selected_apps) { app.Icon = app.widestSquareIcon(); + + if (downloadGridImages) + { + gridImagesDownloadTasks.Add(DownloadTempGridImages(app.Name, exePath)); + } } foreach (var user in users) @@ -156,8 +283,7 @@ namespace UWPHook if (shortcuts != null) { - var exePath = @"""" + System.Reflection.Assembly.GetExecutingAssembly().Location + @""""; - var exeDir = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); + foreach (var app in selected_apps) { VDFEntry newApp = new VDFEntry() @@ -204,6 +330,21 @@ namespace UWPHook MessageBox.Show("Error: Program failed exporting your games:" + Environment.NewLine + ex.Message + ex.StackTrace); } } + + if (gridImagesDownloadTasks.Count > 0) + { + await Task.WhenAll(gridImagesDownloadTasks); + + await Task.Run(() => + { + foreach (var user in users) + { + CopyTempGridImagesToSteamUser(user); + } + + RemoveTempGridImages(); + }); + } } } diff --git a/UWPHook/Properties/Settings.Designer.cs b/UWPHook/Properties/Settings.Designer.cs index 7a982ca..fc330f9 100644 --- a/UWPHook/Properties/Settings.Designer.cs +++ b/UWPHook/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace UWPHook.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.6.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.7.0.0")] public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -70,5 +70,17 @@ namespace UWPHook.Properties { this["StreamMode"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string SteamGridDbApiKey { + get { + return ((string)(this["SteamGridDbApiKey"])); + } + set { + this["SteamGridDbApiKey"] = value; + } + } } } diff --git a/UWPHook/Properties/Settings.settings b/UWPHook/Properties/Settings.settings index 6aed1ad..339d33b 100644 --- a/UWPHook/Properties/Settings.settings +++ b/UWPHook/Properties/Settings.settings @@ -14,5 +14,8 @@ False + + + \ No newline at end of file diff --git a/UWPHook/SettingsWindow.xaml b/UWPHook/SettingsWindow.xaml index 582b481..a5124ce 100644 --- a/UWPHook/SettingsWindow.xaml +++ b/UWPHook/SettingsWindow.xaml @@ -26,9 +26,12 @@ - - - + + + + + + @@ -39,16 +42,19 @@ - -