Disable main window until DLLs are ready

Other code changes
This commit is contained in:
Jeddunk 2020-12-23 19:13:52 +01:00
parent 092c8f3277
commit bf7f309ea6
8 changed files with 199 additions and 121 deletions

View File

@ -5,15 +5,15 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:auto_creamapi"
mc:Ignorable="d"
Title="DownloadWindow" Width="400" Height="200">
Title="Please wait..." Width="400" Height="200">
<Grid Margin="10,10,10,20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Content="Downloading..." HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top"/>
<Label Content="..." Name="FilenameLabel" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Grid.Row="1"/>
<Label Content="Please wait..." Name="InfoLabel" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top"/>
<Label Content="" Name="FilenameLabel" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Grid.Row="1"/>
<Label Content="00,00%" Name="PercentLabel" HorizontalAlignment="Right" Margin="0,0,0,0" VerticalAlignment="Top" Grid.Row="1"/>
<ProgressBar Name="ProgressBar" HorizontalAlignment="Stretch" Margin="0,10,0,10" VerticalAlignment="Top" Grid.Row="2" MinHeight="20" Height="20"
Minimum="0" Maximum="0.99" ValueChanged="ProgressBar_OnValueChanged" Value="0"/>

View File

@ -26,7 +26,7 @@ namespace auto_creamapi
private void ProgressBar_OnValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
MyLogger.Log.Information(ProgressBar.Value.ToString("N"));
//MyLogger.Log.Information(ProgressBar.Value.ToString("N"));
}
}
}

View File

@ -6,7 +6,7 @@
xmlns:wcl="clr-namespace:WatermarkControlsLib.Controls;assembly=WatermarkControlsLib"
mc:Ignorable="d"
Title="Auto-CreamAPI" Width="420" Height="540" MinWidth="420" MinHeight="540">
<Grid>
<Grid Name="MainWindowGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>

View File

@ -2,6 +2,7 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using auto_creamapi.Model;
@ -22,14 +23,29 @@ namespace auto_creamapi
private static CreamDllModel _dllModel;
public MainWindow()
{
PreInit();
InitializeComponent();
new Action(PostInit).Invoke();
}
private static void PreInit()
{
_cacheModel = CacheModel.Instance;
_configModel = CreamConfigModel.Instance;
_dllModel = CreamDllModel.Instance;
InitializeComponent();
}
private async void PostInit()
{
MainWindowGrid.IsEnabled = false;
var task = _dllModel.Initialize();
await task;
_cacheModel.Languages.ForEach(x => Lang.Items.Add(x));
Lang.SelectedItem = DefaultLangSelection;
SteamDb.IsChecked = true;
task.Wait();
MainWindowGrid.IsEnabled = true;
Status.Text = "Ready.";
}
@ -197,15 +213,15 @@ namespace auto_creamapi
}
else
{
Game.Text = "";
AppId.Text = "";
/*Game.Text = "";
AppId.Text = "";*/
MyLogger.Log.Error($"No app found for ID {appId}");
}
}
else
{
Game.Text = "";
AppId.Text = "";
/*Game.Text = "";
AppId.Text = "";*/
MyLogger.Log.Error($"SetNameById: Invalid AppID {appId}");
}
}
@ -213,7 +229,9 @@ namespace auto_creamapi
private void ResetFormData()
{
AppId.Text = _configModel.Config.AppId.ToString();
var configAppId = _configModel.Config.AppId;
AppId.Text = configAppId.ToString();
Game.Text = configAppId > 0 ? _cacheModel.GetAppById(configAppId).Name : "";
Lang.SelectedItem = _configModel.Config.Language;
UnlockAll.IsChecked = _configModel.Config.UnlockAll; // public bool UnlockAll;
ExtraProtection.IsChecked = _configModel.Config.ExtraProtection; // public bool ExtraProtection;
@ -229,7 +247,6 @@ namespace auto_creamapi
}
ListOfDlcs.Text = dlcListString;
SetNameById();
}
private void CheckExistance()

View File

@ -68,21 +68,24 @@ namespace auto_creamapi.Model
private static void UpdateCache()
{
MyLogger.Log.Information("Updating cache...");
var updateNeeded = DateTime.Now.Subtract(File.GetCreationTimeUtc(CachePath)).TotalDays >= 1;
string cacheString;
if (updateNeeded)
{
MyLogger.Log.Information("Updating cache...");
MyLogger.Log.Information("Getting content from API...");
var client = new HttpClient();
var httpCall = client.GetAsync(SteamUri);
var response = httpCall.Result;
var readAsStringAsync = response.Content.ReadAsStringAsync();
var responseBody = readAsStringAsync.Result;
MyLogger.Log.Information("Got content from API successfully. Writing to file...");
/*var writeAllTextAsync = File.WriteAllTextAsync(CachePath, responseBody, Encoding.UTF8);
writeAllTextAsync.RunSynchronously();*/
File.WriteAllText(CachePath, responseBody, Encoding.UTF8);
cacheString = responseBody;
MyLogger.Log.Information("Cache written to file successfully.");
}
else
{
@ -205,7 +208,7 @@ namespace auto_creamapi.Model
}
else
{
MyLogger.Log.Error($"Could not find game: {steamApp}");
MyLogger.Log.Error($"Could not get DLC: Invalid Steam App");
}
return dlcList;

View File

@ -92,7 +92,7 @@ namespace auto_creamapi.Model
private void ResetConfigData()
{
Config.AppId = 0;
Config.AppId = -1;
Config.Language = "";
Config.UnlockAll = false;
Config.ExtraProtection = false;

View File

@ -8,6 +8,7 @@ using System.Security.Cryptography;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Threading;
using auto_creamapi.Services;
using auto_creamapi.Utils;
using SharpCompress.Archives;
using SharpCompress.Common;
@ -55,20 +56,19 @@ namespace auto_creamapi.Model
private bool _x64Exists;
private CreamDllModel()
{
}
public async Task Initialize()
{
if (!(File.Exists("steam_api.dll") && File.Exists("steam_api64.dll")))
{
MyLogger.Log.Information("Missing files, trying to download...");
new Action(async() => await DownloadDll(Secrets.ForumUsername, Secrets.ForumPassword))();
var task = DownloadCreamApiService.DownloadAndExtract(Secrets.ForumUsername, Secrets.ForumPassword);
await task;
task.Wait();
}
else
{
Init();
}
}
private void Init()
{
_creamDlls.Add(X86Arch, new CreamDll("steam_api.dll", "steam_api_o.dll"));
_creamDlls.Add(X64Arch, new CreamDll("steam_api64.dll", "steam_api64_o.dll"));
@ -83,103 +83,6 @@ namespace auto_creamapi.Model
}
}
private async Task DownloadDll(string username, string password)
{
var wnd = new DownloadWindow();
wnd.Show();
var container = new CookieContainer();
var handler = new HttpClientHandler {CookieContainer = container};
var client = new HttpClient(handler);
var formContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("username", username),
new KeyValuePair<string, string>("password", password),
new KeyValuePair<string, string>("redirect", "./ucp.php?mode=login"),
new KeyValuePair<string, string>("login", "login")
});
var response1 = await client.PostAsync("https://cs.rin.ru/forum/ucp.php?mode=login", formContent);
MyLogger.Log.Debug($"Login Status Code: {response1.EnsureSuccessStatusCode().StatusCode.ToString()}");
var cookie = container.GetCookies(new Uri("https://cs.rin.ru/forum/ucp.php?mode=login"))
.FirstOrDefault(c => c.Name.Contains("_sid"));
MyLogger.Log.Debug($"Login Cookie: {cookie}");
var response2 = await client.GetAsync("https://cs.rin.ru/forum/viewtopic.php?t=70576");
MyLogger.Log.Debug(
$"Download Page Status Code: {response2.EnsureSuccessStatusCode().StatusCode.ToString()}");
var content = response2.Content.ReadAsStringAsync();
var contentResult = await content;
var expression =
new Regex(".*<a href=\"\\.(?<url>\\/download\\/file\\.php\\?id=.*)\">(?<filename>.*)<\\/a>.*");
using var reader = new StringReader(contentResult);
string line;
var archiveFileList = new Dictionary<string, string>();
while ((line = await reader.ReadLineAsync()) != null)
{
var match = expression.Match(line);
// ReSharper disable once InvertIf
if (match.Success)
{
archiveFileList.Add(match.Groups["filename"].Value,
$"https://cs.rin.ru/forum{match.Groups["url"].Value}");
MyLogger.Log.Debug(archiveFileList.LastOrDefault().Key);
}
}
/*foreach (var (filename, url) in archiveFileList)
{
MyLogger.Log.Information($"Downloading file: {filename}");
var fileResponse = await client.GetAsync(url);
var download = fileResponse.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync(filename, await download);
}*/
MyLogger.Log.Debug("Choosing first element from list...");
var (filename, url) = archiveFileList.FirstOrDefault();
MyLogger.Log.Information("Start download...");
wnd.FilenameLabel.Content = filename;
/*var fileResponse = await client.GetAsync(url);
var download = fileResponse.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync(filename, await download);
MyLogger.Log.Information($"Download success? {download.IsCompletedSuccessfully}");*/
var progress = new Progress<ICopyProgress>(
x =>
{
wnd.PercentLabel.Content = x.PercentComplete.ToString("P");
wnd.ProgressBar.Dispatcher.Invoke(() => wnd.ProgressBar.Value = x.PercentComplete,
DispatcherPriority.Background);
});
await using (var fileStream = File.OpenWrite(filename))
{
var task = client.GetAsync(url, fileStream, progress);
var response = await task;
/*if (task.IsCompletedSuccessfully)
{
wnd.PercentLabel.Content = "100,00%";
wnd.ProgressBar.Value = 1;
}*/
}
MyLogger.Log.Information("Start extraction...");
var options = new ReaderOptions {Password = "cs.rin.ru"};
var archive = ArchiveFactory.Open(filename, options);
var expression1 = new Regex(@"nonlog_build\\steam_api(?:64)?\.dll");
foreach (var entry in archive.Entries)
{
// ReSharper disable once InvertIf
if (!entry.IsDirectory && expression1.IsMatch(entry.Key))
{
MyLogger.Log.Debug(entry.Key);
entry.WriteToDirectory(Directory.GetCurrentDirectory(), new ExtractionOptions
{
ExtractFullPath = false,
Overwrite = true
});
}
}
MyLogger.Log.Information("Extraction done!");
wnd.Close();
Init();
}
public void Save()
{
if (_x86Exists) CopyDll(X86Arch);

View File

@ -0,0 +1,155 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Threading;
using auto_creamapi.Model;
using auto_creamapi.Utils;
using HttpProgress;
using SharpCompress.Archives;
using SharpCompress.Common;
using SharpCompress.Readers;
namespace auto_creamapi.Services
{
public static class DownloadCreamApiService
{
private const string ArchivePassword = "cs.rin.ru";
private static string _filename;
private static DownloadWindow _wnd;
public static async Task DownloadAndExtract(string username, string password)
{
_wnd = new DownloadWindow();
_wnd.Show();
var download = Download(username, password);
await download;
download.Wait();
var extract = Extract();
await extract;
extract.Wait();
_wnd.Close();
}
private static async Task Download(string username, string password)
{
var container = new CookieContainer();
var handler = new HttpClientHandler {CookieContainer = container};
var client = new HttpClient(handler);
var formContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("username", username),
new KeyValuePair<string, string>("password", password),
new KeyValuePair<string, string>("redirect", "./ucp.php?mode=login"),
new KeyValuePair<string, string>("login", "login")
});
var response1 = await client.PostAsync("https://cs.rin.ru/forum/ucp.php?mode=login", formContent);
MyLogger.Log.Debug($"Login Status Code: {response1.EnsureSuccessStatusCode().StatusCode.ToString()}");
var cookie = container.GetCookies(new Uri("https://cs.rin.ru/forum/ucp.php?mode=login"))
.FirstOrDefault(c => c.Name.Contains("_sid"));
MyLogger.Log.Debug($"Login Cookie: {cookie}");
var response2 = await client.GetAsync("https://cs.rin.ru/forum/viewtopic.php?t=70576");
MyLogger.Log.Debug(
$"Download Page Status Code: {response2.EnsureSuccessStatusCode().StatusCode.ToString()}");
var content = response2.Content.ReadAsStringAsync();
var contentResult = await content;
var expression =
new Regex(".*<a href=\"\\.(?<url>\\/download\\/file\\.php\\?id=.*)\">(?<filename>.*)<\\/a>.*");
using var reader = new StringReader(contentResult);
string line;
var archiveFileList = new Dictionary<string, string>();
while ((line = await reader.ReadLineAsync()) != null)
{
var match = expression.Match(line);
// ReSharper disable once InvertIf
if (match.Success)
{
archiveFileList.Add(match.Groups["filename"].Value,
$"https://cs.rin.ru/forum{match.Groups["url"].Value}");
MyLogger.Log.Debug(archiveFileList.LastOrDefault().Key);
}
}
/*foreach (var (filename, url) in archiveFileList)
{
MyLogger.Log.Information($"Downloading file: {filename}");
var fileResponse = await client.GetAsync(url);
var download = fileResponse.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync(filename, await download);
}*/
MyLogger.Log.Debug("Choosing first element from list...");
var (filename, url) = archiveFileList.FirstOrDefault();
_filename = filename;
if (File.Exists(_filename))
{
MyLogger.Log.Information($"{_filename} already exists, skipping download...");
return;
}
MyLogger.Log.Information("Start download...");
await _wnd.FilenameLabel.Dispatcher.InvokeAsync(
() => _wnd.FilenameLabel.Content = _filename, DispatcherPriority.Background);
await _wnd.InfoLabel.Dispatcher.InvokeAsync(
() => _wnd.InfoLabel.Content = "Downloading...", DispatcherPriority.Background);
/*var fileResponse = await client.GetAsync(url);
var download = fileResponse.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync(filename, await download);
MyLogger.Log.Information($"Download success? {download.IsCompletedSuccessfully}");*/
var progress = new Progress<ICopyProgress>(
x =>
{
_wnd.PercentLabel.Dispatcher.Invoke(
() => _wnd.PercentLabel.Content = x.PercentComplete.ToString("P"),
DispatcherPriority.Background);
_wnd.ProgressBar.Dispatcher.Invoke(
() => _wnd.ProgressBar.Value = x.PercentComplete, DispatcherPriority.Background);
});
await using var fileStream = File.OpenWrite(_filename);
var task = client.GetAsync(url, fileStream, progress);
var response = await task;
if (task.IsCompletedSuccessfully)
{
_wnd.PercentLabel.Dispatcher.Invoke(
() => _wnd.PercentLabel.Content = "100,00%", DispatcherPriority.Background);
_wnd.ProgressBar.Dispatcher.Invoke(
() => _wnd.ProgressBar.Value = 1, DispatcherPriority.Background);
}
}
private static async Task Extract()
{
MyLogger.Log.Information("Start extraction...");
var options = new ReaderOptions {Password = ArchivePassword};
var archive = ArchiveFactory.Open(_filename, options);
var expression1 = new Regex(@"nonlog_build\\steam_api(?:64)?\.dll");
await _wnd.ProgressBar.Dispatcher.InvokeAsync(
() => _wnd.ProgressBar.IsIndeterminate = true, DispatcherPriority.ContextIdle);
await _wnd.FilenameLabel.Dispatcher.InvokeAsync(
() => _wnd.FilenameLabel.Content = _filename, DispatcherPriority.ContextIdle);
await _wnd.InfoLabel.Dispatcher.InvokeAsync(
() => _wnd.InfoLabel.Content = "Extracting...", DispatcherPriority.ContextIdle);
await _wnd.PercentLabel.Dispatcher.InvokeAsync(
() => _wnd.PercentLabel.Content = "100%", DispatcherPriority.ContextIdle);
foreach (var entry in archive.Entries)
{
// ReSharper disable once InvertIf
if (!entry.IsDirectory && expression1.IsMatch(entry.Key))
{
MyLogger.Log.Debug(entry.Key);
entry.WriteToDirectory(Directory.GetCurrentDirectory(), new ExtractionOptions
{
ExtractFullPath = false,
Overwrite = true
});
}
}
MyLogger.Log.Information("Extraction done!");
}
}
}