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

@ -1,11 +1,10 @@
using MvvmCross.Core; using MvvmCross.Core;
using MvvmCross.Platforms.Wpf.Core; using MvvmCross.Platforms.Wpf.Core;
using MvvmCross.Platforms.Wpf.Views;
namespace auto_creamapi namespace auto_creamapi
{ {
/// <summary> /// <summary>
/// Interaction logic for App.xaml /// Interaction logic for App.xaml
/// </summary> /// </summary>
public partial class App public partial class App
{ {
@ -14,4 +13,4 @@ namespace auto_creamapi
this.RegisterSetupType<MvxWpfSetup<Core.App>>(); this.RegisterSetupType<MvxWpfSetup<Core.App>>();
} }
} }
} }

View File

@ -1,30 +1,40 @@
using System; using System;
using System.Collections.Generic; using System.Collections.ObjectModel;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using auto_creamapi.Models; using auto_creamapi.Models;
using auto_creamapi.Utils;
using MvvmCross.Converters; using MvvmCross.Converters;
using MvvmCross.Platforms.Wpf.Converters;
namespace auto_creamapi.Converters namespace auto_creamapi.Converters
{ {
public class ListOfDLcToStringConverter : MvxValueConverter<List<SteamApp>, string> public class ListOfDLcToStringNativeConverter : MvxNativeValueConverter<ListOfDLcToStringConverter>
{ {
protected override string Convert(List<SteamApp> value, Type targetType, object parameter, CultureInfo culture) }
public class ListOfDLcToStringConverter : MvxValueConverter<ObservableCollection<SteamApp>, string>
{
protected override string Convert(ObservableCollection<SteamApp> value, Type targetType, object parameter,
CultureInfo culture)
{ {
MyLogger.Log.Debug("ListOfDLcToStringConverter: Convert");
var dlcListToString = DlcListToString(value); var dlcListToString = DlcListToString(value);
return dlcListToString.GetType() == targetType ? dlcListToString : ""; return dlcListToString.GetType() == targetType ? dlcListToString : "";
} }
protected override List<SteamApp> ConvertBack(string value, Type targetType, object parameter, CultureInfo culture) protected override ObservableCollection<SteamApp> ConvertBack(string value, Type targetType, object parameter,
CultureInfo culture)
{ {
MyLogger.Log.Debug("ListOfDLcToStringConverter: ConvertBack");
var stringToDlcList = StringToDlcList(value); var stringToDlcList = StringToDlcList(value);
return stringToDlcList.GetType() == targetType ? stringToDlcList : new List<SteamApp>(); return stringToDlcList.GetType() == targetType ? stringToDlcList : new ObservableCollection<SteamApp>();
} }
private static List<SteamApp> StringToDlcList(string value) private static ObservableCollection<SteamApp> StringToDlcList(string value)
{ {
var result = new List<SteamApp>(); var result = new ObservableCollection<SteamApp>();
var expression = new Regex(@"(?<id>.*) *= *(?<name>.*)"); var expression = new Regex(@"(?<id>.*) *= *(?<name>.*)");
using var reader = new StringReader(value); using var reader = new StringReader(value);
string line; string line;
@ -32,22 +42,21 @@ namespace auto_creamapi.Converters
{ {
var match = expression.Match(line); var match = expression.Match(line);
if (match.Success) if (match.Success)
{
result.Add(new SteamApp result.Add(new SteamApp
{ {
AppId = int.Parse(match.Groups["id"].Value), AppId = int.Parse(match.Groups["id"].Value),
Name = match.Groups["name"].Value Name = match.Groups["name"].Value
}); });
}
} }
return result; return result;
} }
private static string DlcListToString(List<SteamApp> value) private static string DlcListToString(ObservableCollection<SteamApp> value)
{ {
var result = ""; var result = "";
value.ForEach(x => result += $"{x}\n"); //value.ForEach(x => result += $"{x}\n");
foreach (var steamApp in value) result += $"{steamApp}\n";
return result; return result;
} }
} }

View File

@ -1,6 +1,4 @@
using auto_creamapi.Services;
using auto_creamapi.ViewModels; using auto_creamapi.ViewModels;
using MvvmCross;
using MvvmCross.IoC; using MvvmCross.IoC;
using MvvmCross.ViewModels; using MvvmCross.ViewModels;

View File

@ -1,21 +0,0 @@
<Window x:Class="auto_creamapi.DownloadWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:auto_creamapi"
mc:Ignorable="d"
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="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"/>
</Grid>
</Window>

View File

@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using auto_creamapi.Utils;
namespace auto_creamapi
{
/// <summary>
/// Interaction logic for DownloadWindow.xaml
/// </summary>
public partial class DownloadWindow
{
public DownloadWindow()
{
WindowStartupLocation = WindowStartupLocation.CenterScreen;
InitializeComponent();
}
private void ProgressBar_OnValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
//MyLogger.Log.Information(ProgressBar.Value.ToString("N"));
}
}
}

View File

@ -1,6 +1,4 @@
using System.Windows;
using MvvmCross.Platforms.Wpf.Presenters.Attributes; using MvvmCross.Platforms.Wpf.Presenters.Attributes;
using MvvmCross.Platforms.Wpf.Views;
namespace auto_creamapi namespace auto_creamapi
{ {

View File

@ -0,0 +1,40 @@
using HttpProgress;
using MvvmCross.Plugin.Messenger;
namespace auto_creamapi.Messenger
{
public class ProgressMessage : MvxMessage
{
private readonly ICopyProgress _progress;
private double _percentProgress;
public ProgressMessage(object sender, string info, string filename, ICopyProgress progress) : base(sender)
{
Info = info;
Filename = filename;
_progress = progress;
}
public ProgressMessage(object sender, string info, string filename, double progress) : base(sender)
{
_progress = null;
Info = info;
Filename = filename;
PercentComplete = progress;
}
public string Info { get; }
public string Filename { get; }
public double PercentComplete
{
get => _progress?.PercentComplete ?? _percentProgress;
private set => _percentProgress = value;
}
// public long BytesTransferred => _progress.BytesTransferred;
// public long ExpectedBytes => _progress.ExpectedBytes;
// public long BytesPerSecond => _progress.BytesPerSecond;
// public TimeSpan TransferTime => _progress.TransferTime;
}
}

View File

@ -1,30 +1,23 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using auto_creamapi.Utils;
using IniParser;
using IniParser.Model;
namespace auto_creamapi.Models namespace auto_creamapi.Models
{ {
public class CreamConfig public class CreamConfig
{ {
public CreamConfig()
{
DlcList = new List<SteamApp>();
}
public int AppId { get; set; } public int AppId { get; set; }
public string Language { get; set; } public string Language { get; set; }
public bool UnlockAll { get; set; } public bool UnlockAll { get; set; }
public bool ExtraProtection { get; set; } public bool ExtraProtection { get; set; }
public bool ForceOffline { get; set; } public bool ForceOffline { get; set; }
public List<SteamApp> DlcList { get; set; } public List<SteamApp> DlcList { get; set; }
public CreamConfig()
{
DlcList = new List<SteamApp>();
}
} }
public sealed class CreamConfigModel public sealed class CreamConfigModel
{ {
} }
} }

View File

@ -1,18 +1,14 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Threading.Tasks;
using auto_creamapi.Services;
using auto_creamapi.Utils;
namespace auto_creamapi.Models namespace auto_creamapi.Models
{ {
internal class CreamDll internal class CreamDll
{ {
public readonly string Filename; public readonly string Filename;
public readonly string OrigFilename;
public readonly string Hash; public readonly string Hash;
public readonly string OrigFilename;
public CreamDll(string filename, string origFilename) public CreamDll(string filename, string origFilename)
{ {
@ -30,8 +26,8 @@ namespace auto_creamapi.Models
} }
} }
} }
public class CreamDllModel public class CreamDllModel
{ {
} }
} }

View File

@ -1,16 +1,13 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using MvvmCross.ViewModels;
namespace auto_creamapi.Models namespace auto_creamapi.Models
{ {
public class SteamApp public class SteamApp
{ {
[JsonPropertyName("appid")] [JsonPropertyName("appid")] public int AppId { get; set; }
public int AppId { get; set; }
[JsonPropertyName("name")] public string Name { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; }
public override string ToString() public override string ToString()
{ {
@ -26,13 +23,11 @@ namespace auto_creamapi.Models
public class AppList public class AppList
{ {
[JsonPropertyName("apps")] [JsonPropertyName("apps")] public List<SteamApp> Apps { get; set; }
public List<SteamApp> Apps { get; set; }
} }
public class SteamApps public class SteamApps
{ {
[JsonPropertyName("applist")] [JsonPropertyName("applist")] public AppList AppList { get; set; }
public AppList AppList { get; set; }
} }
} }

View File

@ -1,26 +0,0 @@
<Window x:Class="auto_creamapi.SearchResultWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:models="clr-namespace:auto_creamapi.Models"
mc:Ignorable="d"
Title="Search Results" Width="420" Height="540" MinWidth="420" MinHeight="540">
<Grid Margin="10,10,10,10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Content="Select a game..." HorizontalAlignment="Left" Margin="0,0,0,10" VerticalAlignment="Top"/>
<DataGrid Name="DgApps" Grid.Row="1" AutoGenerateColumns="False" IsReadOnly="True" SelectionMode="Single" d:DataContext="{d:DesignInstance models:SteamApp}" MouseDoubleClick="DgApps_OnMouseDoubleClick">
<DataGrid.Columns>
<DataGridTextColumn Header="AppID" Binding="{Binding AppId}"></DataGridTextColumn>
<DataGridTextColumn Header="Game Name" Binding="{Binding Name}"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
<Button Content="OK" HorizontalAlignment="Right" Margin="0,10,70,0" Grid.Row="2" VerticalAlignment="Top" Width="60" Click="OK_OnClick"/>
<Button Content="Cancel" HorizontalAlignment="Right" Margin="0,10,0,0" Grid.Row="2" VerticalAlignment="Top" Width="60" Click="Cancel_OnClick"/>
</Grid>
</Window>

View File

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

View File

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

View File

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

View File

@ -6,9 +6,10 @@ using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Threading; using auto_creamapi.Messenger;
using auto_creamapi.Utils; using auto_creamapi.Utils;
using HttpProgress; using HttpProgress;
using MvvmCross.Plugin.Messenger;
using SharpCompress.Archives; using SharpCompress.Archives;
using SharpCompress.Common; using SharpCompress.Common;
using SharpCompress.Readers; using SharpCompress.Readers;
@ -17,73 +18,26 @@ namespace auto_creamapi.Services
{ {
public interface IDownloadCreamApiService public interface IDownloadCreamApiService
{ {
public void Initialize(); /*public void Initialize();
// public Task InitializeAsync(); public Task InitializeAsync();*/
public Task DownloadAndExtract(string username, string password); public Task<string> Download(string username, string password);
public void Extract(string filename);
} }
public class DownloadCreamApiService : IDownloadCreamApiService public class DownloadCreamApiService : IDownloadCreamApiService
{ {
private const string ArchivePassword = "cs.rin.ru"; 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() public async Task<string> Download(string username, string password)
{
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)
{ {
MyLogger.Log.Debug("Download"); MyLogger.Log.Debug("Download");
var container = new CookieContainer(); 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..."); MyLogger.Log.Debug("Choosing first element from list...");
var (filename, url) = archiveFileList.FirstOrDefault(); var (filename, url) = archiveFileList.FirstOrDefault();
_filename = filename; //filename = filename;
if (File.Exists(_filename)) if (File.Exists(filename))
{ {
MyLogger.Log.Information($"{_filename} already exists, skipping download..."); MyLogger.Log.Information($"{filename} already exists, skipping download...");
return; return filename;
} }
MyLogger.Log.Information("Start download..."); 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>( var progress = new Progress<ICopyProgress>(
x => x => _messenger.Publish(new ProgressMessage(this, "Downloading...", filename, x)));
{ await using var fileStream = File.OpenWrite(filename);
/*_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 task = client.GetAsync(url, fileStream, progress);
var response = await task; var response = await task;
if (task.IsCompletedSuccessfully) if (task.IsCompletedSuccessfully)
{ _messenger.Publish(new ProgressMessage(this, "Downloading...", filename, 1.0));
/*_wnd.PercentLabel.Dispatcher.Invoke( MyLogger.Log.Information("Download done.");
() => _wnd.PercentLabel.Content = "100,00%", DispatcherPriority.Background); return filename;
_wnd.ProgressBar.Dispatcher.Invoke(
() => _wnd.ProgressBar.Value = 1, DispatcherPriority.Background);*/
}
} }
private static void Extract() public void Extract(string filename)
{ {
MyLogger.Log.Debug("Extract"); MyLogger.Log.Debug("Extract");
MyLogger.Log.Information("Start extraction..."); MyLogger.Log.Information($@"Start extraction of ""{filename}""...");
var options = new ReaderOptions {Password = ArchivePassword}; 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"); var expression1 = new Regex(@"nonlog_build\\steam_api(?:64)?\.dll");
/*await _wnd.ProgressBar.Dispatcher.InvokeAsync( _messenger.Publish(new ProgressMessage(this, "Extracting...", filename, 1.0));
() => _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) foreach (var entry in archive.Entries)
{
// ReSharper disable once InvertIf // ReSharper disable once InvertIf
if (!entry.IsDirectory && expression1.IsMatch(entry.Key)) if (!entry.IsDirectory && expression1.IsMatch(entry.Key))
{ {
@ -198,7 +119,6 @@ namespace auto_creamapi.Services
Overwrite = true Overwrite = true
}); });
} }
}
MyLogger.Log.Information("Extraction done!"); MyLogger.Log.Information("Extraction done!");
} }

View File

@ -0,0 +1,40 @@
using System.Collections.Generic;
namespace auto_creamapi.Utils
{
public class Misc
{
public static readonly List<string> DefaultLanguages = 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"
});
}
}

View File

@ -1,10 +1,10 @@
namespace auto_creamapi.Utils namespace auto_creamapi.Utils
{ {
/// <summary> /// <summary>
/// To use this: /// To use this:
/// Rename file Secrets.EXAMPLE.cs to Secrets.cs /// Rename file Secrets.EXAMPLE.cs to Secrets.cs
/// Rename class Secrets_REMOVETHIS to Secrets /// Rename class Secrets_REMOVETHIS to Secrets
/// Enter the relevant info below /// Enter the relevant info below
/// </summary> /// </summary>
public class Secrets_REMOVETHIS public class Secrets_REMOVETHIS
{ {

View File

@ -0,0 +1,87 @@
using System.Threading.Tasks;
using auto_creamapi.Messenger;
using auto_creamapi.Services;
using auto_creamapi.Utils;
using MvvmCross.Logging;
using MvvmCross.Navigation;
using MvvmCross.Plugin.Messenger;
using MvvmCross.ViewModels;
namespace auto_creamapi.ViewModels
{
public class DownloadViewModel : MvxNavigationViewModel
{
private readonly IDownloadCreamApiService _download;
private readonly IMvxNavigationService _navigationService;
private readonly MvxSubscriptionToken _token;
private string _filename;
private string _info;
private double _progress;
public DownloadViewModel(IMvxLogProvider logProvider, IMvxNavigationService navigationService,
IDownloadCreamApiService download, IMvxMessenger messenger) : base(logProvider, navigationService)
{
_navigationService = navigationService;
_download = download;
_token = messenger.Subscribe<ProgressMessage>(OnProgressMessage);
MyLogger.Log.Debug(messenger.CountSubscriptionsFor<ProgressMessage>().ToString());
}
public string InfoLabel
{
get => _info;
set
{
_info = value;
RaisePropertyChanged(() => InfoLabel);
}
}
public string FilenameLabel
{
get => _filename;
set
{
_filename = value;
RaisePropertyChanged(() => FilenameLabel);
}
}
public double Progress
{
get => _progress;
set
{
_progress = value;
RaisePropertyChanged(() => Progress);
RaisePropertyChanged(() => ProgressPercent);
}
}
public string ProgressPercent => _progress.ToString("P2");
public override async Task Initialize()
{
await base.Initialize();
InfoLabel = "Please wait...";
FilenameLabel = "";
Progress = 0.0;
var download = _download.Download(Secrets.ForumUsername, Secrets.ForumPassword);
var filename = await download;
/*var extract = _download.Extract(filename);
await extract;*/
await Task.Run(() => _download.Extract(filename));
_token.Dispose();
await _navigationService.Close(this);
}
private void OnProgressMessage(ProgressMessage obj)
{
//MyLogger.Log.Debug($"{obj.Filename}: {obj.BytesTransferred}");
InfoLabel = obj.Info;
FilenameLabel = obj.Filename;
Progress = obj.PercentComplete;
}
}
}

View File

@ -3,218 +3,68 @@ using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Threading;
using auto_creamapi.Models; using auto_creamapi.Models;
using auto_creamapi.Services; using auto_creamapi.Services;
using auto_creamapi.Utils; using auto_creamapi.Utils;
using auto_creamapi.Views;
using Microsoft.Win32; using Microsoft.Win32;
using MvvmCross.Commands; using MvvmCross.Commands;
using MvvmCross.Navigation;
using MvvmCross.ViewModels; using MvvmCross.ViewModels;
namespace auto_creamapi.ViewModels namespace auto_creamapi.ViewModels
{ {
public class MainViewModel : MvxViewModel public class MainViewModel : MvxViewModel
{ {
private const string DefaultLanguageSelection = "english";
private readonly ICacheService _cache; private readonly ICacheService _cache;
private readonly ICreamConfigService _config; private readonly ICreamConfigService _config;
private readonly ICreamDllService _dll; private readonly ICreamDllService _dll;
private readonly IDownloadCreamApiService _download; private readonly IMvxNavigationService _navigationService;
private bool _mainWindowEnabled;
private string _dllPath;
private string _gameName;
private int _appId; private int _appId;
private string _lang; private bool _configExists;
private bool _offline;
private bool _extraprotection;
private bool _unlockall;
private bool _useSteamDb;
private ObservableCollection<SteamApp> _dlcs; private ObservableCollection<SteamApp> _dlcs;
private bool _dllApplied; private bool _dllApplied;
private bool _configExists; private string _dllPath;
private string _status; private bool _extraprotection;
private string _gameName;
private string _lang;
private ObservableCollection<string> _languages; private ObservableCollection<string> _languages;
private const string DefaultLanguageSelection = "english";
private const string DlcRegexPattern = @"(?<id>.*) *= *(?<name>.*)"; //private readonly IDownloadCreamApiService _download;
private bool _mainWindowEnabled;
private bool _offline;
private string _status;
private bool _unlockall;
private bool _useSteamDb;
//private const string DlcRegexPattern = @"(?<id>.*) *= *(?<name>.*)";
public MainViewModel(ICacheService cache, ICreamConfigService config, ICreamDllService dll, public MainViewModel(ICacheService cache, ICreamConfigService config, ICreamDllService dll,
IDownloadCreamApiService download) IMvxNavigationService navigationService)
{ {
_navigationService = navigationService;
_cache = cache; _cache = cache;
_config = config; _config = config;
_dll = dll; _dll = dll;
_download = download; //_download = download;
}
public override async Task Initialize()
{
await base.Initialize();
Languages = new ObservableCollection<string>(_cache.Languages);
ResetForm();
_download.Initialize();
_dll.Initialize();
Lang = DefaultLanguageSelection;
UseSteamDb = true;
MainWindowEnabled = true;
Status = "Ready.";
} }
// // COMMANDS // // // // COMMANDS // //
public IMvxCommand OpenFileCommand => new MvxCommand(OpenFile); public IMvxCommand OpenFileCommand => new MvxCommand(OpenFile);
private void OpenFile() public IMvxCommand SearchCommand => new MvxAsyncCommand(async () => await Search()); //Command(Search);
{
Status = "Waiting for file...";
var dialog = new OpenFileDialog
{
Filter = "SteamAPI DLL|steam_api.dll;steam_api64.dll|" +
"All files (*.*)|*.*",
Multiselect = false,
Title = "Select SteamAPI DLL..."
};
if (dialog.ShowDialog() == true)
{
var filePath = dialog.FileName;
DllPath = filePath;
var dirPath = Path.GetDirectoryName(filePath);
if (dirPath != null)
{
_config.ReadFile(Path.Combine(dirPath, "cream_api.ini"));
ResetForm();
_dll.TargetPath = dirPath;
_dll.CheckIfDllExistsAtTarget();
CheckExistence();
Status = "Ready.";
}
}
}
public IMvxCommand SearchCommand => new MvxCommand(Search);
private void Search()
{
var app = _cache.GetAppByName(GameName);
if (app != null)
{
GameName = app.Name;
AppId = app.AppId;
}
/*else
{
var listOfAppsByName = _cache.GetListOfAppsByName(GameName);
var searchWindow = new SearchResultWindow(listOfAppsByName);
searchWindow.Show();
}*/
}
public IMvxCommand GetListOfDlcCommand => new MvxAsyncCommand(GetListOfDlc); public IMvxCommand GetListOfDlcCommand => new MvxAsyncCommand(GetListOfDlc);
private async Task GetListOfDlc()
{
Status = "Trying to get DLC...";
if (AppId > 0)
{
var app = new SteamApp() {AppId = AppId, Name = GameName};
var task = _cache.GetListOfDlc(app, UseSteamDb);
MainWindowEnabled = false;
var listOfDlc = await task;
var result = "";
if (task.IsCompletedSuccessfully)
{
listOfDlc.Sort((app1, app2) => app1.AppId.CompareTo(app2.AppId));
listOfDlc.ForEach(x => result += $"{x.AppId}={x.Name}\n");
Dlcs = result;
Status = $"Got DLC for AppID {AppId}";
}
else
{
Status = $"Could not get DLC for AppID {AppId}";
}
MainWindowEnabled = true;
}
else
{
Status = $"Could not get DLC for AppID {AppId}";
MyLogger.Log.Error($"GetListOfDlc: Invalid AppID {AppId}");
}
}
public IMvxCommand SaveCommand => new MvxCommand(Save); public IMvxCommand SaveCommand => new MvxCommand(Save);
private void Save()
{
Status = "Saving...";
_config.SetConfigData(
AppId,
Lang,
Unlockall,
Extraprotection,
Offline,
Dlcs
);
_config.SaveFile();
_dll.Save();
CheckExistence();
Status = "Saving successful.";
}
public IMvxCommand ResetFormCommand => new MvxCommand(ResetForm); public IMvxCommand ResetFormCommand => new MvxCommand(ResetForm);
private void ResetForm()
{
AppId = _config.Config.AppId;
Lang = _config.Config.Language;
Unlockall = _config.Config.UnlockAll;
Extraprotection = _config.Config.ExtraProtection;
Offline = _config.Config.ForceOffline;
var configDlcList = _config.Config.DlcList;
var result = "";
foreach (var x in configDlcList)
{
result += $"{x.AppId}={x.Name}\n";
}
Dlcs = result;
}
public IMvxCommand GoToForumThreadCommand => new MvxCommand(GoToForumThread); public IMvxCommand GoToForumThreadCommand => new MvxCommand(GoToForumThread);
private void GoToForumThread()
{
Status = "Opening URL...";
if (AppId > 0)
{
var searchTerm = AppId; //$"{GameName.Replace(" ", "+")}+{appId}";
var destinationUrl =
"https://cs.rin.ru/forum/search.php?keywords=" +
searchTerm +
"&terms=any&fid[]=10&sf=firstpost&sr=topics&submit=Search";
var uri = new Uri(destinationUrl);
var process = new ProcessStartInfo(uri.AbsoluteUri)
{
UseShellExecute = true
};
Process.Start(process);
}
else
{
MyLogger.Log.Error($"OpenURL: Invalid AppID {AppId}");
Status = $"Could not open URL: Invalid AppID {AppId}";
}
}
private void CheckExistence()
{
DllApplied = _dll.CreamApiApplied();
ConfigExists = _config.ConfigExists();
}
// // ATTRIBUTES // // // // ATTRIBUTES // //
public bool MainWindowEnabled public bool MainWindowEnabled
@ -259,12 +109,6 @@ namespace auto_creamapi.ViewModels
} }
} }
private void SetNameById()
{
var appById = _cache.GetAppById(_appId);
GameName = appById != null ? appById.Name : "";
}
public string Lang public string Lang
{ {
get => _lang; get => _lang;
@ -316,53 +160,14 @@ namespace auto_creamapi.ViewModels
} }
} }
/*public List<SteamApp> Dlcs public ObservableCollection<SteamApp> Dlcs
{ {
get => _dlcs; get => _dlcs;
set set
{ {
_dlcs = value; _dlcs = value;
RaisePropertyChanged(Dlcs); RaisePropertyChanged(() => Dlcs);
MyLogger.Log.Debug($"Dlcs: {value}");
} }
}*/
public string Dlcs
{
get => DlcListToString(_dlcs);
set
{
_dlcs = StringToDlcList(value);
RaisePropertyChanged();
//MyLogger.Log.Debug($"Dlcs: {DlcListToString(_dlcs)}");
}
}
private static ObservableCollection<SteamApp> StringToDlcList(string value)
{
var result = new List<SteamApp>();
var expression = new Regex(@"(?<id>.*) *= *(?<name>.*)");
using var reader = new StringReader(value);
string line;
while ((line = reader.ReadLine()) != null)
{
var match = expression.Match(line);
if (match.Success)
{
result.Add(new SteamApp
{
AppId = int.Parse(match.Groups["id"].Value),
Name = match.Groups["name"].Value
});
}
}
return new ObservableCollection<SteamApp>(result);
}
private static string DlcListToString(IEnumerable<SteamApp> value)
{
return value.Aggregate("", (current, steamApp) => current + $"{steamApp}\n");
} }
public bool DllApplied public bool DllApplied
@ -404,5 +209,179 @@ namespace auto_creamapi.ViewModels
RaisePropertyChanged(() => Languages); RaisePropertyChanged(() => Languages);
} }
} }
public override async Task Initialize()
{
_config.Initialize();
/*await base.Initialize();
await _cache.Initialize();
if (!File.Exists("steam_api.dll") | !File.Exists("steam_api64.dll"))
await _navigationService.Navigate<DownloadViewModel>();
await _dll.Initialize();*/
var tasks = new List<Task> {base.Initialize(), _cache.Initialize()};
if (!File.Exists("steam_api.dll") | !File.Exists("steam_api64.dll"))
tasks.Add(_navigationService.Navigate<DownloadViewModel>());
tasks.Add(_dll.Initialize());
await Task.WhenAll(tasks);
Languages = new ObservableCollection<string>(_cache.Languages);
ResetForm();
Lang = DefaultLanguageSelection;
UseSteamDb = true;
MainWindowEnabled = true;
Status = "Ready.";
}
private void OpenFile()
{
Status = "Waiting for file...";
var dialog = new OpenFileDialog
{
Filter = "SteamAPI DLL|steam_api.dll;steam_api64.dll|" +
"All files (*.*)|*.*",
Multiselect = false,
Title = "Select SteamAPI DLL..."
};
if (dialog.ShowDialog() == true)
{
var filePath = dialog.FileName;
DllPath = filePath;
var dirPath = Path.GetDirectoryName(filePath);
if (dirPath != null)
{
_config.ReadFile(Path.Combine(dirPath, "cream_api.ini"));
ResetForm();
_dll.TargetPath = dirPath;
_dll.CheckIfDllExistsAtTarget();
CheckExistence();
Status = "Ready.";
}
}
else
{
Status = "File selection canceled.";
}
}
private async Task Search()
{
if (!string.IsNullOrEmpty(GameName))
{
var app = _cache.GetAppByName(GameName);
if (app != null)
{
GameName = app.Name;
AppId = app.AppId;
}
else
{
var navigate = _navigationService.Navigate<SearchResultViewModel, IEnumerable<SteamApp>, SteamApp>(
_cache.GetListOfAppsByName(GameName));
await navigate;
var navigateResult = navigate.Result;
if (navigateResult != null)
{
GameName = navigateResult.Name;
AppId = navigateResult.AppId;
}
}
}
else
{
MyLogger.Log.Warning("Empty game name, cannot initiate search!");
}
}
private async Task GetListOfDlc()
{
Status = "Trying to get DLC...";
if (AppId > 0)
{
var app = new SteamApp {AppId = AppId, Name = GameName};
var task = _cache.GetListOfDlc(app, UseSteamDb);
MainWindowEnabled = false;
var listOfDlc = await task;
if (task.IsCompletedSuccessfully)
{
listOfDlc.Sort((app1, app2) => app1.AppId.CompareTo(app2.AppId));
Dlcs = new ObservableCollection<SteamApp>(listOfDlc);
Status = $"Got DLC for AppID {AppId}";
}
else
{
Status = $"Could not get DLC for AppID {AppId}";
}
MainWindowEnabled = true;
}
else
{
Status = $"Could not get DLC for AppID {AppId}";
MyLogger.Log.Error($"GetListOfDlc: Invalid AppID {AppId}");
}
}
private void Save()
{
Status = "Saving...";
_config.SetConfigData(
AppId,
Lang,
Unlockall,
Extraprotection,
Offline,
Dlcs
);
_config.SaveFile();
_dll.Save();
CheckExistence();
Status = "Saving successful.";
}
private void ResetForm()
{
AppId = _config.Config.AppId;
Lang = _config.Config.Language;
Unlockall = _config.Config.UnlockAll;
Extraprotection = _config.Config.ExtraProtection;
Offline = _config.Config.ForceOffline;
Dlcs = new ObservableCollection<SteamApp>(_config.Config.DlcList);
Status = "Changes have been reset.";
}
private void GoToForumThread()
{
Status = "Opening URL...";
if (AppId > 0)
{
var searchTerm = AppId; //$"{GameName.Replace(" ", "+")}+{appId}";
var destinationUrl =
"https://cs.rin.ru/forum/search.php?keywords=" +
searchTerm +
"&terms=any&fid[]=10&sf=firstpost&sr=topics&submit=Search";
var uri = new Uri(destinationUrl);
var process = new ProcessStartInfo(uri.AbsoluteUri)
{
UseShellExecute = true
};
Process.Start(process);
}
else
{
MyLogger.Log.Error($"OpenURL: Invalid AppID {AppId}");
Status = $"Could not open URL: Invalid AppID {AppId}";
}
}
private void CheckExistence()
{
DllApplied = _dll.CreamApiApplied();
ConfigExists = _config.ConfigExists();
}
private void SetNameById()
{
var appById = _cache.GetAppById(_appId);
GameName = appById != null ? appById.Name : "";
}
} }
} }

View File

@ -0,0 +1,80 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using auto_creamapi.Models;
using auto_creamapi.Utils;
using MvvmCross.Commands;
using MvvmCross.Logging;
using MvvmCross.Navigation;
using MvvmCross.ViewModels;
namespace auto_creamapi.ViewModels
{
public class SearchResultViewModel : MvxNavigationViewModel<IEnumerable<SteamApp>>,
IMvxViewModel<IEnumerable<SteamApp>, SteamApp>
{
private readonly IMvxNavigationService _navigationService;
private IEnumerable<SteamApp> _steamApps;
/*public override async Task Initialize()
{
await base.Initialize();
}*/
public SearchResultViewModel(IMvxLogProvider logProvider, IMvxNavigationService navigationService) : base(
logProvider, navigationService)
{
_navigationService = navigationService;
}
public IEnumerable<SteamApp> Apps
{
get => _steamApps;
set
{
_steamApps = value;
RaisePropertyChanged(() => Apps);
}
}
public SteamApp Selected
{
get;
set;
//RaisePropertyChanged(Selected);
}
public IMvxCommand SaveCommand => new MvxAsyncCommand(Save);
public IMvxCommand CloseCommand => new MvxCommand(Close);
public override void Prepare(IEnumerable<SteamApp> parameter)
{
Apps = parameter;
}
public TaskCompletionSource<object> CloseCompletionSource { get; set; }
public override void ViewDestroy(bool viewFinishing = true)
{
if (viewFinishing && CloseCompletionSource != null && !CloseCompletionSource.Task.IsCompleted &&
!CloseCompletionSource.Task.IsFaulted)
CloseCompletionSource?.TrySetCanceled();
base.ViewDestroy(viewFinishing);
}
private async Task Save()
{
if (Selected != null)
{
MyLogger.Log.Information($"Successfully got app {Selected}");
await _navigationService.Close(this, Selected);
}
}
private void Close()
{
//throw new System.NotImplementedException();
_navigationService.Close(this);
}
}
}

View File

@ -0,0 +1,27 @@
<views:MvxWindow x:Class="auto_creamapi.Views.DownloadView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="clr-namespace:MvvmCross.Platforms.Wpf.Views;assembly=MvvmCross.Platforms.Wpf"
xmlns:viewModels="clr-namespace:auto_creamapi.ViewModels"
d:DataContext="{d:DesignInstance Type=viewModels:DownloadViewModel}"
mc:Ignorable="d"
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="{Binding InfoLabel}" Name="InfoLabel" HorizontalAlignment="Left" Margin="0,0,0,0"
VerticalAlignment="Top" />
<Label Content="{Binding FilenameLabel}" Name="FilenameLabel" HorizontalAlignment="Left" Margin="0,0,0,0"
VerticalAlignment="Top" Grid.Row="1" />
<Label Content="{Binding ProgressPercent}" 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="1.0" Value="{Binding Progress}" />
</Grid>
</views:MvxWindow>

View File

@ -0,0 +1,23 @@
using System.Windows;
using MvvmCross.Platforms.Wpf.Presenters.Attributes;
namespace auto_creamapi.Views
{
/// <summary>
/// Interaction logic for DownloadWindow.xaml
/// </summary>
[MvxWindowPresentation(Identifier = nameof(DownloadView), Modal = true)]
public partial class DownloadView
{
public DownloadView()
{
WindowStartupLocation = WindowStartupLocation.CenterScreen;
InitializeComponent();
}
/*private void ProgressBar_OnValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
//MyLogger.Log.Information(ProgressBar.Value.ToString("N"));
}*/
}
}

View File

@ -11,73 +11,102 @@
xmlns:converters="clr-namespace:auto_creamapi.Converters" xmlns:converters="clr-namespace:auto_creamapi.Converters"
mc:Ignorable="d"> mc:Ignorable="d">
<views:MvxWpfView.Resources> <views:MvxWpfView.Resources>
<converters:ListOfDLcToStringConverter x:Key="DlcConv"/> <converters:ListOfDLcToStringNativeConverter x:Key="DlcConv" />
</views:MvxWpfView.Resources> </views:MvxWpfView.Resources>
<Grid IsEnabled="{Binding MainWindowEnabled, Mode=TwoWay}"> <Grid IsEnabled="{Binding MainWindowEnabled, Mode=TwoWay}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto" />
<RowDefinition Height="*"/> <RowDefinition Height="*" />
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<wcl:WatermarkTextBox x:Name="DllPath" Text="{Binding DllPath}" Watermark="Path to game's steam_api(64).dll..." Margin="10,11,55,0" TextWrapping="NoWrap" VerticalAlignment="Top" Padding="0" Grid.Row="0" IsReadOnly="True" IsReadOnlyCaretVisible="True"> <wcl:WatermarkTextBox x:Name="DllPath" Text="{Binding DllPath}" Watermark="Path to game's steam_api(64).dll..."
Margin="10,11,55,0" TextWrapping="NoWrap" VerticalAlignment="Top" Padding="0"
Grid.Row="0" IsReadOnly="True" IsReadOnlyCaretVisible="True">
<!--MouseDoubleClick="{Binding Path=OpenFileCommand}"--> <!--MouseDoubleClick="{Binding Path=OpenFileCommand}"-->
<wcl:WatermarkTextBox.InputBindings> <wcl:WatermarkTextBox.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{Binding OpenFileCommand}"></MouseBinding> <MouseBinding Gesture="LeftDoubleClick" Command="{Binding OpenFileCommand}" />
</wcl:WatermarkTextBox.InputBindings> </wcl:WatermarkTextBox.InputBindings>
</wcl:WatermarkTextBox> </wcl:WatermarkTextBox>
<Button Content="&#xE1A5;" HorizontalAlignment="Right" Margin="0,10,10,0" VerticalAlignment="Top" FontFamily="Segoe UI Symbol" Width="40" Command="{Binding OpenFileCommand}" ToolTip="Select DLL file." Grid.Row="0"/> <Button Content="&#xE1A5;" HorizontalAlignment="Right" Margin="0,10,10,0" VerticalAlignment="Top"
<wcl:WatermarkTextBox Text="{Binding GameName, Mode=TwoWay}" x:Name="Game" Margin="10,10,180,0" Watermark="Game Name" TextWrapping="Wrap" VerticalAlignment="Top" Padding="0" Grid.Row="1"/> FontFamily="Segoe UI Symbol" Width="40" Command="{Binding OpenFileCommand}" ToolTip="Select DLL file."
<Button Content="&#xE11A;" HorizontalAlignment="Right" Margin="0,9,135,0" VerticalAlignment="Top" FontFamily="Segoe UI Symbol" Width="40" Command="{Binding SearchCommand}" ToolTip="Find AppID." Grid.Row="1"/> Grid.Row="0" />
<wcl:WatermarkTextBox Text="{Binding AppId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" x:Name="AppId" HorizontalAlignment="Right" Margin="0,10,10,0" Watermark="AppID" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Padding="0" Grid.Row="1" /> <wcl:WatermarkTextBox Text="{Binding GameName, Mode=TwoWay}" x:Name="Game" Margin="10,10,180,0"
Watermark="Game Name" TextWrapping="Wrap" VerticalAlignment="Top" Padding="0"
Grid.Row="1" />
<Button Content="&#xE11A;" HorizontalAlignment="Right" Margin="0,9,135,0" VerticalAlignment="Top"
FontFamily="Segoe UI Symbol" Width="40" Command="{Binding SearchCommand}" ToolTip="Find AppID."
Grid.Row="1" />
<wcl:WatermarkTextBox Text="{Binding AppId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" x:Name="AppId"
HorizontalAlignment="Right" Margin="0,10,10,0" Watermark="AppID" TextWrapping="Wrap"
VerticalAlignment="Top" Width="120" Padding="0" Grid.Row="1" />
<TextBlock Grid.Row="2" Margin="10,10,10,0"> <TextBlock Grid.Row="2" Margin="10,10,10,0">
<Hyperlink Command="{Binding GoToForumThreadCommand}">Search for cs.rin.ru thread</Hyperlink> <Hyperlink Command="{Binding GoToForumThreadCommand}">Search for cs.rin.ru thread</Hyperlink>
</TextBlock> </TextBlock>
<ComboBox x:Name="Lang" ItemsSource="{Binding Path=Languages}" SelectedItem="{Binding Path=Lang, Mode=TwoWay}" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="120" Grid.Row="3"/> <ComboBox x:Name="Lang" ItemsSource="{Binding Path=Languages}" SelectedItem="{Binding Path=Lang, Mode=TwoWay}"
<CheckBox x:Name="ForceOffline" Content="Force offline mode" IsChecked="{Binding Offline, Mode=TwoWay}" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" ToolTip="offlinemode" Grid.Row="4"/> HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="120" Grid.Row="3" />
<CheckBox x:Name="ExtraProtection" Content="Try to bypass game-specific protection" IsChecked="{Binding Extraprotection, Mode=TwoWay}" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" ToolTip="extraprotection" Grid.Row="5"/> <CheckBox x:Name="ForceOffline" Content="Force offline mode" IsChecked="{Binding Offline, Mode=TwoWay}"
HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" ToolTip="offlinemode"
Grid.Row="4" />
<CheckBox x:Name="ExtraProtection" Content="Try to bypass game-specific protection"
IsChecked="{Binding Extraprotection, Mode=TwoWay}" HorizontalAlignment="Left" Margin="10,10,0,0"
VerticalAlignment="Top" ToolTip="extraprotection" Grid.Row="5" />
<Grid Margin="10,10,10,0" Grid.Row="6"> <Grid Margin="10,10,10,0" Grid.Row="6">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="*"/> <RowDefinition Height="*" />
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<GroupBox Header="DLC" Grid.Row="0" VerticalAlignment="Stretch"> <GroupBox Header="DLC" Grid.Row="0" VerticalAlignment="Stretch">
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto" />
<RowDefinition Height="*"/> <RowDefinition Height="*" />
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<CheckBox x:Name="UnlockAll" Content="Unlock all DLCs (if possible)" IsChecked="{Binding Unlockall, Mode=TwoWay}" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" ToolTip="unlockall"/> <CheckBox x:Name="UnlockAll" Content="Unlock all DLCs (if possible)"
<CheckBox x:Name="SteamDb" Content="Additionally use SteamDB for DLCs" IsChecked="{Binding UseSteamDb, Mode=TwoWay}" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Grid.Row="1"/> IsChecked="{Binding Unlockall, Mode=TwoWay}" HorizontalAlignment="Left"
Margin="10,10,0,0" VerticalAlignment="Top" ToolTip="unlockall" />
<CheckBox x:Name="SteamDb" Content="Additionally use SteamDB for DLCs"
IsChecked="{Binding UseSteamDb, Mode=TwoWay}" HorizontalAlignment="Left"
Margin="10,10,0,0" VerticalAlignment="Top" Grid.Row="1" />
<!-- Text="{Binding Dlcs, Converter={StaticResource DlcConv}, Mode=TwoWay}"--> <!-- Text="{Binding Dlcs, Converter={StaticResource DlcConv}, Mode=TwoWay}"-->
<!-- Text="{Binding DlcsString, Mode=TwoWay}"--> <!-- Text="{Binding DlcsString, Mode=TwoWay}"-->
<wcl:WatermarkTextBox x:Name="ListOfDlcs" Text="{Binding Dlcs, Mode=TwoWay}" Margin="10,10,10,0" Watermark="List of DLCs...&#xA;0000 = DLC Name" TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Visible" Padding="0" FontFamily="./#Courier Prime" Grid.Row="2"/> <wcl:WatermarkTextBox x:Name="ListOfDlcs"
<Button Content="Get DLCs for AppID" Margin="0,10,10,10" Height="19.96" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="108" Command="{Binding GetListOfDlcCommand}" Grid.Row="3"/> Text="{Binding Dlcs, Converter={StaticResource DlcConv}, Mode=TwoWay}"
Margin="10,10,10,0" Watermark="List of DLCs...&#xA;0000 = DLC Name"
TextWrapping="Wrap" AcceptsReturn="True"
VerticalScrollBarVisibility="Visible" Padding="0"
FontFamily="./#Courier Prime" Grid.Row="2" />
<Button Content="Get DLCs for AppID" Margin="0,10,10,10" Height="19.96" HorizontalAlignment="Right"
VerticalAlignment="Bottom" Width="108" Command="{Binding GetListOfDlcCommand}" Grid.Row="3" />
</Grid> </Grid>
</GroupBox> </GroupBox>
<GroupBox Header="Status" Grid.Row="1" VerticalAlignment="Bottom" IsEnabled="False"> <GroupBox Header="Status" Grid.Row="1" VerticalAlignment="Bottom" IsEnabled="False">
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<CheckBox x:Name="CreamApiApplied" Content="CreamAPI DLL applied" Margin="10,10,0,10" Grid.Column="0" IsChecked="{Binding DllApplied, Mode=TwoWay}"/> <CheckBox x:Name="CreamApiApplied" Content="CreamAPI DLL applied" Margin="10,10,0,10"
<CheckBox x:Name="ConfigExists" Content="CreamAPI Config exists" Margin="10,10,0,10" Grid.Column="1" IsChecked="{Binding ConfigExists, Mode=TwoWay}"/> Grid.Column="0" IsChecked="{Binding DllApplied, Mode=TwoWay}" />
<CheckBox x:Name="ConfigExists" Content="CreamAPI Config exists" Margin="10,10,0,10"
Grid.Column="1" IsChecked="{Binding ConfigExists, Mode=TwoWay}" />
</Grid> </Grid>
</GroupBox> </GroupBox>
</Grid> </Grid>
<Button Content="Save" Command="{Binding SaveCommand}" Margin="0,10,55,10" HorizontalAlignment="Right" Width="40" Height="20" VerticalAlignment="Bottom" Grid.Row="7"/> <Button Content="Save" Command="{Binding SaveCommand}" Margin="0,10,55,10" HorizontalAlignment="Right"
<Button Content="Reset" Command="{Binding ResetFormCommand}" Margin="0,10,10,10" Height="20" VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="40" Grid.Row="7"/> Width="40" Height="20" VerticalAlignment="Bottom" Grid.Row="7" />
<Button Content="Reset" Command="{Binding ResetFormCommand}" Margin="0,10,10,10" Height="20"
VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="40" Grid.Row="7" />
<StatusBar Grid.Row="8"> <StatusBar Grid.Row="8">
<StatusBarItem Height="30" Margin="0,0,0,0"> <StatusBarItem Height="30" Margin="0,0,0,0">
<TextBlock x:Name="Status" Text="{Binding Status, Mode=TwoWay}"/> <TextBlock x:Name="Status" Text="{Binding Status, Mode=TwoWay}" />
</StatusBarItem> </StatusBarItem>
</StatusBar> </StatusBar>
</Grid> </Grid>

View File

@ -0,0 +1,34 @@
<views:MvxWindow x:Class="auto_creamapi.Views.SearchResultView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="clr-namespace:MvvmCross.Platforms.Wpf.Views;assembly=MvvmCross.Platforms.Wpf"
xmlns:viewModels="clr-namespace:auto_creamapi.ViewModels"
d:DataContext="{d:DesignInstance Type=viewModels:SearchResultViewModel}"
mc:Ignorable="d"
Title="Search Results" Width="420" Height="540" MinWidth="420" MinHeight="540">
<Grid Margin="10,10,10,10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label Content="Select a game..." HorizontalAlignment="Left" Margin="0,0,0,10" VerticalAlignment="Top" />
<!-- d:DataContext="{d:DesignInstance models:SteamApp}" MouseDoubleClick="DgApps_OnMouseDoubleClick" -->
<DataGrid Name="DgApps" Grid.Row="1" AutoGenerateColumns="False" IsReadOnly="True" SelectionMode="Single"
ItemsSource="{Binding Apps}" SelectedItem="{Binding Selected}">
<DataGrid.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{Binding SaveCommand}" />
</DataGrid.InputBindings>
<DataGrid.Columns>
<DataGridTextColumn Header="AppID" Binding="{Binding AppId}" />
<DataGridTextColumn Header="Game Name" Binding="{Binding Name}" />
</DataGrid.Columns>
</DataGrid>
<Button Content="OK" Command="{Binding SaveCommand}" HorizontalAlignment="Right" Margin="0,10,70,0"
Grid.Row="2" VerticalAlignment="Top" Width="60" />
<Button Content="Cancel" Command="{Binding CloseCommand}" HorizontalAlignment="Right" Margin="0,10,0,0"
Grid.Row="2" VerticalAlignment="Top" Width="60" />
</Grid>
</views:MvxWindow>

View File

@ -1,35 +1,20 @@
using System; using MvvmCross.Platforms.Wpf.Presenters.Attributes;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using auto_creamapi.Models;
using auto_creamapi.Utils;
using NinjaNye.SearchExtensions;
using NinjaNye.SearchExtensions.Models;
namespace auto_creamapi namespace auto_creamapi.Views
{ {
/// <summary> /// <summary>
/// Interaction logic for SearchResultWindow.xaml /// Interaction logic for SearchResultWindow.xaml
/// </summary> /// </summary>
public partial class SearchResultWindow [MvxWindowPresentation(Identifier = nameof(SearchResultView), Modal = false)]
public partial class SearchResultView
{ {
public SearchResultWindow(IEnumerable<SteamApp> list) public SearchResultView()
{ {
InitializeComponent(); InitializeComponent();
DgApps.ItemsSource = list; //DgApps.ItemsSource = list;
} }
private void OK_OnClick(object sender, RoutedEventArgs e) /*private void OK_OnClick(object sender, RoutedEventArgs e)
{ {
GetSelectedApp(); GetSelectedApp();
} }
@ -58,6 +43,6 @@ namespace auto_creamapi
} }
Close(); Close();
} }*/
} }
} }

View File

@ -14,6 +14,7 @@
<PackageReference Include="ini-parser-netstandard" Version="2.5.2" /> <PackageReference Include="ini-parser-netstandard" Version="2.5.2" />
<PackageReference Include="MvvmCross" Version="7.1.2" /> <PackageReference Include="MvvmCross" Version="7.1.2" />
<PackageReference Include="MvvmCross.Platforms.Wpf" Version="7.1.2" /> <PackageReference Include="MvvmCross.Platforms.Wpf" Version="7.1.2" />
<PackageReference Include="MvvmCross.Plugin.Messenger" Version="7.1.2" />
<PackageReference Include="NinjaNye.SearchExtensions" Version="3.0.1" /> <PackageReference Include="NinjaNye.SearchExtensions" Version="3.0.1" />
<PackageReference Include="Serilog" Version="2.10.0" /> <PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />