Adding steam grid images download when exporting games

pull/50/head
Allex Rodrigues 4 years ago
parent dd8ec6df0c
commit 0c692abf29

@ -5,8 +5,6 @@ VisualStudioVersion = 15.0.27703.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UWPHook", "UWPHook\UWPHook.csproj", "{AFE09BCF-28A4-48EE-876B-FEF080D04D5F}"
EndProject
Project("{840C416C-B8F3-42BC-B0DD-F6BB14C9F8CB}") = "Setup", "Setup\Setup.aiproj", "{F63C6051-9812-47BE-87F2-ECA8F2E89EC0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -20,12 +18,6 @@ Global
{AFE09BCF-28A4-48EE-876B-FEF080D04D5F}.DefaultBuild|Any CPU.Build.0 = Debug|Any CPU
{AFE09BCF-28A4-48EE-876B-FEF080D04D5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AFE09BCF-28A4-48EE-876B-FEF080D04D5F}.Release|Any CPU.Build.0 = Release|Any CPU
{F63C6051-9812-47BE-87F2-ECA8F2E89EC0}.Debug|Any CPU.ActiveCfg = DefaultBuild
{F63C6051-9812-47BE-87F2-ECA8F2E89EC0}.Debug|Any CPU.Build.0 = DefaultBuild
{F63C6051-9812-47BE-87F2-ECA8F2E89EC0}.DefaultBuild|Any CPU.ActiveCfg = DefaultBuild
{F63C6051-9812-47BE-87F2-ECA8F2E89EC0}.DefaultBuild|Any CPU.Build.0 = DefaultBuild
{F63C6051-9812-47BE-87F2-ECA8F2E89EC0}.Release|Any CPU.ActiveCfg = DefaultBuild
{F63C6051-9812-47BE-87F2-ECA8F2E89EC0}.Release|Any CPU.Build.0 = DefaultBuild
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

@ -0,0 +1,48 @@
using System;
namespace UWPHook
{
public class Crc32
{
uint[] table;
public uint ComputeChecksum(byte[] bytes)
{
uint crc = 0xffffffff;
for (int i = 0; i < bytes.Length; ++i)
{
byte index = (byte)(((crc) & 0xff) ^ bytes[i]);
crc = (uint)((crc >> 8) ^ table[index]);
}
return ~crc;
}
public byte[] ComputeChecksumBytes(byte[] bytes)
{
return BitConverter.GetBytes(ComputeChecksum(bytes));
}
public Crc32()
{
uint poly = 0xedb88320;
table = new uint[256];
uint temp = 0;
for (uint i = 0; i < table.Length; ++i)
{
temp = i;
for (int j = 8; j > 0; --j)
{
if ((temp & 1) == 1)
{
temp = (uint)((temp >> 1) ^ poly);
}
else
{
temp >>= 1;
}
}
table[i] = temp;
}
}
}
}

@ -2,12 +2,17 @@
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;
@ -96,7 +101,7 @@ namespace UWPHook
{
if (Properties.Settings.Default.ChangeLanguage && !String.IsNullOrEmpty(Properties.Settings.Default.TargetLanguage))
{
ScriptManager.RunScript("Set - WinUILanguageOverride " + currentLanguage);
ScriptManager.RunScript("Set-WinUILanguageOverride " + currentLanguage);
}
//The user has probably finished using the app, so let's close UWPHook to keep the experience clean
@ -104,25 +109,97 @@ 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 = new Crc32().ComputeChecksum(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 void SaveImage(string imageUrl, string destinationFilename, ImageFormat format)
{
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 async Task DownloadGridImages(string userId, string appName, string appTarget)
{
// Generate app id for grid images
SteamGridDbApi api = new SteamGridDbApi("0973373b2cec3120ce673d06747d506c");
string gridDirectory = userId + @"\\config\\grid\\";
var games = await api.SearchGame(appName);
if (games != null)
{
var game = games[0];
UInt64 gameId = GenerateSteamGridAppId(appName, appTarget);
if (!Directory.Exists(gridDirectory))
{
Directory.CreateDirectory(gridDirectory);
}
var gameGrids = api.GetGameGrids(game.Id, "600x900", "static");
var gameHeroes = api.GetGameHeroes(game.Id, "static");
var gameLogos = api.GetGameLogos(game.Id, "static");
await Task.WhenAll(
gameGrids,
gameHeroes,
gameLogos
);
var grids = await gameGrids;
var heroes = await gameHeroes;
var logos = await gameLogos;
if (grids != null)
{
var grid = grids[0];
SaveImage(grid.Url, $"{gridDirectory}\\{gameId}p.png", ImageFormat.Png);
}
if (heroes != null)
{
var hero = heroes[0];
SaveImage(hero.Url, $"{gridDirectory}\\{gameId}_hero.png", ImageFormat.Png);
}
if (logos != null)
{
var logo = logos[0];
SaveImage(logo.Url, $"{gridDirectory}\\{gameId}_logo.png", ImageFormat.Png);
}
}
}
private async Task ExportGames()
{
string steam_folder = SteamManager.GetSteamFolder();
if (Directory.Exists(steam_folder))
@ -158,10 +235,12 @@ namespace UWPHook
{
foreach (var app in selected_apps)
{
string appTarget = @"""" + System.Reflection.Assembly.GetExecutingAssembly().Location + @""" " + app.Aumid;
VDFEntry newApp = new VDFEntry()
{
AppName = app.Name,
Exe = @"""" + System.Reflection.Assembly.GetExecutingAssembly().Location + @""" " + app.Aumid,
Exe = appTarget,
StartDir = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location),
AllowDesktopConfig = 1,
Icon = app.Icon,
@ -178,6 +257,9 @@ namespace UWPHook
//Resize this array so it fits the new entries
Array.Resize(ref shortcuts, shortcuts.Length + 1);
shortcuts[shortcuts.Length - 1] = newApp;
// TODO: Check if api key setting exist
await DownloadGridImages(user, app.Name, appTarget);
}
try

@ -0,0 +1,10 @@
namespace UWPHook.SteamGridDb
{
class GameResponse
{
public int Id { get; set; }
public string Name { get; set; }
}
}

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UWPHook.SteamGridDb
{
class GridResponse
{
public string Url { get; set; }
}
}

@ -0,0 +1,7 @@
namespace UWPHook.SteamGridDb
{
public class HeroResponse
{
public string Url { get; set; }
}
}

@ -0,0 +1,7 @@
namespace UWPHook.SteamGridDb
{
public class LogoResponse
{
public string Url { get; set; }
}
}

@ -0,0 +1,111 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
namespace UWPHook.SteamGridDb
{
class SteamGridDbApi
{
private const string BASE_URL = "https://www.steamgriddb.com/api/v2/";
private HttpClient httpClient;
public SteamGridDbApi(string apiKey)
{
httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(BASE_URL);
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
}
public async Task<GameResponse[]> SearchGame(string gameName)
{
string path = $"search/autocomplete/{gameName}";
GameResponse[] games = null;
HttpResponseMessage response = await httpClient.GetAsync(path);
if(response.IsSuccessStatusCode)
{
var parsedResponse = await response.Content.ReadAsAsync<ResponseWrapper<GameResponse>>();
games = parsedResponse.Data;
}
return games;
}
public async Task<GridResponse[]> GetGameGrids(
int gameId,
string dimensions = null,
string types = null,
string styles = null,
string nsfw = "any",
string humor = "any")
{
string path = $"grids/game/{gameId}";
GridResponse[] grids = null;
HttpResponseMessage response = await httpClient.GetAsync(path);
if (response.IsSuccessStatusCode)
{
var parsedResponse = await response.Content.ReadAsAsync<ResponseWrapper<GridResponse>>();
grids = parsedResponse.Data;
}
return grids;
}
public async Task<HeroResponse[]> GetGameHeroes(
int gameId,
string types = null,
string dimensions = null,
string styles = null,
string nsfw = "any",
string humor = "any")
{
string path = $"heroes/game/{gameId}";
HeroResponse[] heroes = null;
HttpResponseMessage response = await httpClient.GetAsync(path);
if (response.IsSuccessStatusCode)
{
var parsedResponse = await response.Content.ReadAsAsync<ResponseWrapper<HeroResponse>>();
heroes = parsedResponse.Data;
}
return heroes;
}
public async Task<LogoResponse[]> GetGameLogos(
int gameId,
string types = null,
string styles = null,
string nsfw = "any",
string humor = "any")
{
string path = $"logos/game/{gameId}";
LogoResponse[] logos = null;
HttpResponseMessage response = await httpClient.GetAsync(path);
if (response.IsSuccessStatusCode)
{
var parsedResponse = await response.Content.ReadAsAsync<ResponseWrapper<LogoResponse>>();
logos = parsedResponse.Data;
}
return logos;
}
private class ResponseWrapper<T>
{
public bool Success { get; set; }
public T[] Data { get; set; }
}
}
}

@ -65,6 +65,9 @@
<Reference Include="MaterialDesignThemes.Wpf, Version=3.1.3.1513, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MaterialDesignThemes.3.1.3\lib\net45\MaterialDesignThemes.Wpf.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="SharpSteam">
<HintPath>..\..\SharpSteam\SharpSteam\bin\Release\SharpSteam.dll</HintPath>
</Reference>
@ -74,6 +77,9 @@
<Reference Include="System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.PowerShell.5.ReferenceAssemblies.1.1.0\lib\net4\System.Management.Automation.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.Formatting, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.7\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
@ -97,6 +103,7 @@
</ApplicationDefinition>
<Compile Include="AppEntry.cs" />
<Compile Include="AppEntryModel.cs" />
<Compile Include="Crc32.cs" />
<Compile Include="FullScreenLauncher.xaml.cs">
<DependentUpon>FullScreenLauncher.xaml</DependentUpon>
</Compile>
@ -108,6 +115,11 @@
<Compile Include="SettingsWindow.xaml.cs">
<DependentUpon>SettingsWindow.xaml</DependentUpon>
</Compile>
<Compile Include="SteamGridDb\GameResponse.cs" />
<Compile Include="SteamGridDb\GridResponse.cs" />
<Compile Include="SteamGridDb\HeroResponse.cs" />
<Compile Include="SteamGridDb\LogoResponse.cs" />
<Compile Include="SteamGridDb\SteamGridDbApi.cs" />
<Page Include="FullScreenLauncher.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>

@ -2,6 +2,8 @@
<packages>
<package id="MaterialDesignColors" version="1.2.6" targetFramework="net461" />
<package id="MaterialDesignThemes" version="3.1.3" targetFramework="net461" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.7" targetFramework="net461" />
<package id="Microsoft.PowerShell.5.ReferenceAssemblies" version="1.1.0" targetFramework="net461" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net461" />
<package id="System.Management.Automation" version="7.0.1" targetFramework="net461" />
</packages>
Loading…
Cancel
Save