SearchResultView and DownloadView implemented;

Ignore whitespaces and special chars when looking for games;
This commit is contained in:
Jeddunk 2020-12-28 15:27:37 +01:00
parent aada82693d
commit 73baa27245
26 changed files with 783 additions and 642 deletions

View file

@ -4,6 +4,7 @@ using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using AngleSharp.Dom;
using AngleSharp.Html.Parser;
@ -17,7 +18,10 @@ namespace auto_creamapi.Services
public interface ICacheService
{
public List<string> Languages { get; }
public void UpdateCache();
public Task Initialize();
//public Task UpdateCache();
public IEnumerable<SteamApp> GetListOfAppsByName(string name);
public SteamApp GetAppByName(string name);
public SteamApp GetAppById(int appid);
@ -28,43 +32,14 @@ namespace auto_creamapi.Services
{
private const string CachePath = "steamapps.json";
private const string SteamUri = "https://api.steampowered.com/ISteamApps/GetAppList/v2/";
private const string UserAgent =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " +
"Chrome/87.0.4280.88 Safari/537.36";
private const string SpecialCharsRegex = "[^0-9a-zA-Z]+";
private List<SteamApp> _cache = new List<SteamApp>();
private readonly List<string> _languages = new List<string>(new[]
{
"arabic",
"bulgarian",
"schinese",
"tchinese",
"czech",
"danish",
"dutch",
"english",
"finnish",
"french",
"german",
"greek",
"hungarian",
"italian",
"japanese",
"koreana",
"norwegian",
"polish",
"portuguese",
"brazilian",
"romanian",
"russian",
"spanish",
"latam",
"swedish",
"thai",
"turkish",
"ukrainian",
"vietnamese"
});
/*private static readonly Lazy<CacheService> Lazy =
new Lazy<CacheService>(() => new CacheService());
@ -73,13 +48,18 @@ namespace auto_creamapi.Services
public CacheService()
{
Languages = _languages;
UpdateCache();
Languages = Misc.DefaultLanguages;
}
/*public async void Initialize()
{
//Languages = _defaultLanguages;
await UpdateCache();
}*/
public List<string> Languages { get; }
public void UpdateCache()
public async Task Initialize()
{
MyLogger.Log.Information("Updating cache...");
var updateNeeded = DateTime.Now.Subtract(File.GetLastWriteTimeUtc(CachePath)).TotalDays >= 1;
@ -89,20 +69,19 @@ namespace auto_creamapi.Services
MyLogger.Log.Information("Getting content from API...");
var client = new HttpClient();
var httpCall = client.GetAsync(SteamUri);
var response = httpCall.Result;
var response = await httpCall;
var readAsStringAsync = response.Content.ReadAsStringAsync();
var responseBody = readAsStringAsync.Result;
var responseBody = await readAsStringAsync;
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);
await File.WriteAllTextAsync(CachePath, responseBody, Encoding.UTF8);
cacheString = responseBody;
MyLogger.Log.Information("Cache written to file successfully.");
}
else
{
MyLogger.Log.Information("Cache already up to date!");
// ReSharper disable once MethodHasAsyncOverload
cacheString = File.ReadAllText(CachePath);
}
@ -122,7 +101,9 @@ namespace auto_creamapi.Services
public SteamApp GetAppByName(string name)
{
MyLogger.Log.Information($"Trying to get app {name}");
var app = _cache.Find(x => x.Name.ToLower().Equals(name.ToLower()));
var app = _cache.Find(x =>
Regex.Replace(x.Name, SpecialCharsRegex, "").ToLower()
.Equals(Regex.Replace(name, SpecialCharsRegex, "").ToLower()));
if (app != null) MyLogger.Log.Information($"Successfully got app {app}");
return app;
}
@ -194,10 +175,7 @@ namespace auto_creamapi.Services
var dlcId = element.GetAttribute("data-appid");
var dlcName = $"Unknown DLC {dlcId}";
var query3 = element.QuerySelectorAll("td");
if (query3 != null)
{
dlcName = query3[1].Text().Replace("\n", "").Trim();
}
if (query3 != null) dlcName = query3[1].Text().Replace("\n", "").Trim();
var dlcApp = new SteamApp {AppId = Convert.ToInt32(dlcId), Name = dlcName};
var i = dlcList.FindIndex(x => x.CompareId(dlcApp));
@ -222,7 +200,7 @@ namespace auto_creamapi.Services
}
else
{
MyLogger.Log.Error($"Could not get DLC: Invalid Steam App");
MyLogger.Log.Error("Could not get DLC: Invalid Steam App");
}
return dlcList;

View file

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
@ -14,6 +15,7 @@ namespace auto_creamapi.Services
public interface ICreamConfigService
{
public CreamConfig Config { get; }
public void Initialize();
public void ReadFile(string configFilePath);
public void SaveFile();
@ -31,21 +33,31 @@ namespace auto_creamapi.Services
bool forceOffline,
List<SteamApp> dlcList);
public void SetConfigData(int appId,
string language,
bool unlockAll,
bool extraProtection,
bool forceOffline,
ObservableCollection<SteamApp> dlcList);
public bool ConfigExists();
}
public class CreamConfigService : ICreamConfigService
{
public CreamConfig Config { get; }
private string _configFilePath;
public CreamConfigService()
public CreamConfig Config { get; set; }
public void Initialize()
{
//await Task.Run(() =>
//{
//MyLogger.Log.Debug("CreamConfigService: init start");
Config = new CreamConfig();
ResetConfigData();
//MyLogger.Log.Debug("CreamConfigService: init end");
//});
}
public void ReadFile(string configFilePath)
@ -66,10 +78,8 @@ namespace auto_creamapi.Services
var dlcCollection = data["dlc"];
foreach (var item in dlcCollection)
{
//Config.DlcList.Add(int.Parse(item.KeyName), item.Value);
Config.DlcList.Add(new SteamApp{AppId = int.Parse(item.KeyName), Name = item.Value});
}
Config.DlcList.Add(new SteamApp {AppId = int.Parse(item.KeyName), Name = item.Value});
}
else
{
@ -99,16 +109,6 @@ namespace auto_creamapi.Services
parser.WriteFile(_configFilePath, data, Encoding.UTF8);
}
private void ResetConfigData()
{
Config.AppId = -1;
Config.Language = "";
Config.UnlockAll = false;
Config.ExtraProtection = false;
Config.ForceOffline = false;
Config.DlcList.Clear();
}
public void SetConfigData(int appId,
string language,
bool unlockAll,
@ -123,7 +123,7 @@ namespace auto_creamapi.Services
Config.ForceOffline = forceOffline;
SetDlcFromString(dlcList);
}
public void SetConfigData(int appId,
string language,
bool unlockAll,
@ -138,7 +138,37 @@ namespace auto_creamapi.Services
Config.ForceOffline = forceOffline;
Config.DlcList = dlcList;
}
public void SetConfigData(int appId,
string language,
bool unlockAll,
bool extraProtection,
bool forceOffline,
ObservableCollection<SteamApp> dlcList)
{
Config.AppId = appId;
Config.Language = language;
Config.UnlockAll = unlockAll;
Config.ExtraProtection = extraProtection;
Config.ForceOffline = forceOffline;
Config.DlcList = new List<SteamApp>(dlcList);
}
public bool ConfigExists()
{
return File.Exists(_configFilePath);
}
private void ResetConfigData()
{
Config.AppId = -1;
Config.Language = "";
Config.UnlockAll = false;
Config.ExtraProtection = false;
Config.ForceOffline = false;
Config.DlcList.Clear();
}
private void SetDlcFromString(string dlcList)
{
Config.DlcList.Clear();
@ -149,10 +179,8 @@ namespace auto_creamapi.Services
{
var match = expression.Match(line);
if (match.Success)
{
Config.DlcList.Add(
new SteamApp{AppId = int.Parse(match.Groups["id"].Value), Name = match.Groups["name"].Value});
}
new SteamApp {AppId = int.Parse(match.Groups["id"].Value), Name = match.Groups["name"].Value});
}
}
/*private void SetDlcFromAppList(List<SteamApp> dlcList)
@ -171,22 +199,15 @@ namespace auto_creamapi.Services
$"ForceOffline: {Config.ForceOffline}, " +
$"DLC ({Config.DlcList.Count}):\n[\n";
if (Config.DlcList.Count > 0)
{
str = Config.DlcList.Aggregate(str, (current, x) => current + $" {x.AppId}={x.Name},\n");
/*foreach (var (key, value) in Config.DlcList)
/*foreach (var (key, value) in Config.DlcList)
{
str += $" {key}={value},\n";
}*/
}
str += "]";
return str;
}
public bool ConfigExists()
{
return File.Exists(_configFilePath);
}
}
}

View file

@ -11,8 +11,7 @@ namespace auto_creamapi.Services
public interface ICreamDllService
{
public string TargetPath { get; set; }
public void Initialize();
//public Task InitializeAsync();
public Task Initialize();
public void Save();
public void CheckIfDllExistsAtTarget();
public bool CreamApiApplied();
@ -20,28 +19,18 @@ namespace auto_creamapi.Services
public class CreamDllService : ICreamDllService
{
private readonly IDownloadCreamApiService _downloadService;
public string TargetPath { get; set; }
private readonly Dictionary<string, CreamDll> _creamDlls = new Dictionary<string, CreamDll>();
private static readonly string HashPath = Path.Combine(Directory.GetCurrentDirectory(), "cream_api.md5");
private const string X86Arch = "x86";
private const string X64Arch = "x64";
private static readonly string HashPath = Path.Combine(Directory.GetCurrentDirectory(), "cream_api.md5");
private bool _x86Exists;
private readonly Dictionary<string, CreamDll> _creamDlls = new Dictionary<string, CreamDll>();
private bool _x64Exists;
public CreamDllService(IDownloadCreamApiService downloadService)
{
_downloadService = downloadService;
}
private bool _x86Exists;
public Task InitializeAsync()
{
return Task.Run(Initialize);
}
public string TargetPath { get; set; }
public void Initialize()
public async Task Initialize()
{
MyLogger.Log.Debug("CreamDllService: Initialize begin");
@ -51,11 +40,12 @@ namespace auto_creamapi.Services
if (!File.Exists(HashPath))
{
MyLogger.Log.Information("Writing md5sum file...");
File.WriteAllLines(HashPath, new[]
{
$"{_creamDlls[X86Arch].Hash} {_creamDlls[X86Arch].Filename}",
$"{_creamDlls[X64Arch].Hash} {_creamDlls[X64Arch].Filename}"
});
await File.WriteAllLinesAsync(HashPath,
new[]
{
$"{_creamDlls[X86Arch].Hash} {_creamDlls[X86Arch].Filename}",
$"{_creamDlls[X64Arch].Hash} {_creamDlls[X64Arch].Filename}"
});
}
MyLogger.Log.Debug("CreamDllService: Initialize end");
@ -67,6 +57,23 @@ namespace auto_creamapi.Services
if (_x64Exists) CopyDll(X64Arch);
}
public void CheckIfDllExistsAtTarget()
{
var x86file = Path.Combine(TargetPath, "steam_api.dll");
var x64file = Path.Combine(TargetPath, "steam_api64.dll");
_x86Exists = File.Exists(x86file);
_x64Exists = File.Exists(x64file);
if (_x86Exists) MyLogger.Log.Information($"x86 SteamAPI DLL found: {x86file}");
if (_x64Exists) MyLogger.Log.Information($"x64 SteamAPI DLL found: {x64file}");
}
public bool CreamApiApplied()
{
var a = CreamApiApplied("x86");
var b = CreamApiApplied("x64");
return a | b;
}
private void CopyDll(string arch)
{
var sourceSteamApiDll = _creamDlls[arch].Filename;
@ -84,30 +91,13 @@ namespace auto_creamapi.Services
File.Copy(sourceSteamApiDll, targetSteamApiDll, true);
}
public void CheckIfDllExistsAtTarget()
{
var x86file = Path.Combine(TargetPath, "steam_api.dll");
var x64file = Path.Combine(TargetPath, "steam_api64.dll");
_x86Exists = File.Exists(x86file);
_x64Exists = File.Exists(x64file);
if (_x86Exists) MyLogger.Log.Information($"x86 SteamAPI DLL found: {x86file}");
if (_x64Exists) MyLogger.Log.Information($"x64 SteamAPI DLL found: {x64file}");
}
public bool CreamApiApplied(string arch)
{
bool a = File.Exists(Path.Combine(TargetPath, _creamDlls[arch].OrigFilename));
bool b = GetHash(Path.Combine(TargetPath, _creamDlls[arch].Filename)).Equals(_creamDlls[arch].Hash);
var a = File.Exists(Path.Combine(TargetPath, _creamDlls[arch].OrigFilename));
var b = GetHash(Path.Combine(TargetPath, _creamDlls[arch].Filename)).Equals(_creamDlls[arch].Hash);
return a & b;
}
public bool CreamApiApplied()
{
bool a = CreamApiApplied("x86");
bool b = CreamApiApplied("x64");
return a | b;
}
private string GetHash(string filename)
{
if (File.Exists(filename))
@ -118,10 +108,8 @@ namespace auto_creamapi.Services
.ToString(md5.ComputeHash(stream))
.Replace("-", string.Empty);
}
else
{
return "";
}
return "";
}
}
}

View file

@ -6,9 +6,10 @@ using System.Net;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Threading;
using auto_creamapi.Messenger;
using auto_creamapi.Utils;
using HttpProgress;
using MvvmCross.Plugin.Messenger;
using SharpCompress.Archives;
using SharpCompress.Common;
using SharpCompress.Readers;
@ -17,73 +18,26 @@ namespace auto_creamapi.Services
{
public interface IDownloadCreamApiService
{
public void Initialize();
// public Task InitializeAsync();
public Task DownloadAndExtract(string username, string password);
/*public void Initialize();
public Task InitializeAsync();*/
public Task<string> Download(string username, string password);
public void Extract(string filename);
}
public class DownloadCreamApiService : IDownloadCreamApiService
{
private const string ArchivePassword = "cs.rin.ru";
private static string _filename;
//private static DownloadWindow _wnd;
public DownloadCreamApiService()
//private string _filename;
private readonly IMvxMessenger _messenger;
//private DownloadWindow _wnd;
public DownloadCreamApiService(IMvxMessenger messenger)
{
_messenger = messenger;
}
public void Initialize()
{
MyLogger.Log.Debug("DownloadCreamApiService: Initialize begin");
if (File.Exists("steam_api.dll") && File.Exists("steam_api64.dll"))
{
MyLogger.Log.Information("Skipping download...");
}
else
{
MyLogger.Log.Information("Missing files, trying to download...");
DownloadAndExtract(Secrets.ForumUsername, Secrets.ForumPassword).Start();
}
//await creamDllService.InitializeAsync();
MyLogger.Log.Debug("DownloadCreamApiService: Initialize end");
}
public async Task InitializeAsync()
{
MyLogger.Log.Debug("DownloadCreamApiService: Initialize begin");
if (File.Exists("steam_api.dll") && File.Exists("steam_api64.dll"))
{
MyLogger.Log.Information("Skipping download...");
}
else
{
MyLogger.Log.Information("Missing files, trying to download...");
var downloadAndExtract = DownloadAndExtract(Secrets.ForumUsername, Secrets.ForumPassword);
await downloadAndExtract;
downloadAndExtract.Wait();
}
//await creamDllService.InitializeAsync();
MyLogger.Log.Debug("DownloadCreamApiService: Initialize end");
}
public async Task DownloadAndExtract(string username, string password)
{
MyLogger.Log.Debug("DownloadAndExtract");
//_wnd = new DownloadWindow();
//_wnd.Show();
var download = Download(username, password);
await download;
download.Wait();
/*var extract = Extract();
await extract;
extract.Wait();*/
var extract = Task.Run(Extract);
await extract;
extract.Wait();
//_wnd.Close();
}
private static async Task Download(string username, string password)
public async Task<string> Download(string username, string password)
{
MyLogger.Log.Debug("Download");
var container = new CookieContainer();
@ -125,69 +79,36 @@ namespace auto_creamapi.Services
}
}
/*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))
//filename = filename;
if (File.Exists(filename))
{
MyLogger.Log.Information($"{_filename} already exists, skipping download...");
return;
MyLogger.Log.Information($"{filename} already exists, skipping download...");
return filename;
}
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);
x => _messenger.Publish(new ProgressMessage(this, "Downloading...", filename, x)));
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);*/
}
_messenger.Publish(new ProgressMessage(this, "Downloading...", filename, 1.0));
MyLogger.Log.Information("Download done.");
return filename;
}
private static void Extract()
public void Extract(string filename)
{
MyLogger.Log.Debug("Extract");
MyLogger.Log.Information("Start extraction...");
MyLogger.Log.Information($@"Start extraction of ""{filename}""...");
var options = new ReaderOptions {Password = ArchivePassword};
var archive = ArchiveFactory.Open(_filename, options);
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);*/
_messenger.Publish(new ProgressMessage(this, "Extracting...", filename, 1.0));
foreach (var entry in archive.Entries)
{
// ReSharper disable once InvertIf
if (!entry.IsDirectory && expression1.IsMatch(entry.Key))
{
@ -198,7 +119,6 @@ namespace auto_creamapi.Services
Overwrite = true
});
}
}
MyLogger.Log.Information("Extraction done!");
}