GoldbergGUI/GoldbergGUI.Core/ViewModels/MainViewModel.cs

611 lines
20 KiB
C#
Raw Normal View History

2021-12-22 07:15:28 -05:00
using GoldbergGUI.Core.Models;
using GoldbergGUI.Core.Services;
using GoldbergGUI.Core.Utils;
2022-05-12 15:40:28 -04:00
using Microsoft.Extensions.Logging;
2021-12-22 07:15:28 -05:00
using Microsoft.Win32;
using MvvmCross.Commands;
using MvvmCross.Navigation;
using MvvmCross.ViewModels;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
2021-01-13 10:39:28 -05:00
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
2021-01-13 10:39:28 -05:00
using System.Windows;
namespace GoldbergGUI.Core.ViewModels
2021-01-08 12:36:57 -05:00
{
// ReSharper disable once ClassNeverInstantiated.Global
public class MainViewModel : MvxNavigationViewModel
2021-01-08 12:36:57 -05:00
{
private readonly IMvxNavigationService _navigationService;
2021-01-08 12:36:57 -05:00
private string _dllPath;
private string _gameName;
private int _appId;
//private SteamApp _currentGame;
private ObservableCollection<Achievement> _achievements;
private ObservableCollection<DlcApp> _dlcs;
2021-01-08 12:36:57 -05:00
private string _accountName;
private long _steamId;
private bool _offline;
private bool _disableNetworking;
private bool _disableOverlay;
2021-01-13 15:26:35 -05:00
private string _statusText;
2021-01-08 12:36:57 -05:00
private readonly ISteamService _steam;
private readonly IGoldbergService _goldberg;
2022-05-12 15:40:28 -04:00
private readonly ILogger<MainViewModel> _log;
2021-01-08 12:36:57 -05:00
private bool _mainWindowEnabled;
private bool _goldbergApplied;
private ObservableCollection<string> _steamLanguages;
private string _selectedLanguage;
2022-05-12 15:40:28 -04:00
private readonly ILoggerFactory _logProvider;
2021-01-08 12:36:57 -05:00
2022-05-12 15:40:28 -04:00
public MainViewModel(ISteamService steam, IGoldbergService goldberg, ILoggerFactory logProvider,
IMvxNavigationService navigationService) : base(logProvider, navigationService)
2021-01-08 12:36:57 -05:00
{
_steam = steam;
_goldberg = goldberg;
_logProvider = logProvider;
2022-05-12 15:40:28 -04:00
_log = logProvider.CreateLogger<MainViewModel>();
_navigationService = navigationService;
2021-01-08 12:36:57 -05:00
}
public override void Prepare()
{
base.Prepare();
Task.Run(async () =>
{
//var errorDuringInit = false;
2021-01-08 12:36:57 -05:00
MainWindowEnabled = false;
2021-01-13 16:15:00 -05:00
StatusText = "Initializing! Please wait...";
try
{
SteamLanguages = new ObservableCollection<string>(_goldberg.Languages());
ResetForm();
2022-05-12 15:40:28 -04:00
await _steam.Initialize(_logProvider.CreateLogger<SteamService>()).ConfigureAwait(false);
var globalConfiguration =
2022-05-12 15:40:28 -04:00
await _goldberg.Initialize(_logProvider.CreateLogger<GoldbergService>()).ConfigureAwait(false);
AccountName = globalConfiguration.AccountName;
SteamId = globalConfiguration.UserSteamId;
SelectedLanguage = globalConfiguration.Language;
}
catch (Exception e)
{
Console.WriteLine(e);
2022-05-12 15:40:28 -04:00
_log.LogError(e.Message);
throw;
}
2021-01-08 12:36:57 -05:00
MainWindowEnabled = true;
2021-01-13 16:15:00 -05:00
StatusText = "Ready.";
2021-01-08 12:36:57 -05:00
});
}
public override async Task Initialize()
{
await base.Initialize().ConfigureAwait(false);
}
// PROPERTIES //
2021-01-08 12:36:57 -05:00
public string DllPath
{
get => _dllPath;
private set
{
_dllPath = value;
RaisePropertyChanged(() => DllPath);
2021-01-13 16:15:00 -05:00
RaisePropertyChanged(() => DllSelected);
RaisePropertyChanged(() => SteamInterfacesTxtExists);
2021-01-08 12:36:57 -05:00
}
}
public string GameName
{
get => _gameName;
set
{
_gameName = value;
RaisePropertyChanged(() => GameName);
}
}
public int AppId
{
get => _appId;
set
{
_appId = value;
RaisePropertyChanged(() => AppId);
Task.Run(async () => await GetNameById().ConfigureAwait(false));
}
}
// ReSharper disable once InconsistentNaming
public ObservableCollection<DlcApp> DLCs
2021-01-08 12:36:57 -05:00
{
get => _dlcs;
2021-01-13 07:50:46 -05:00
set
2021-01-08 12:36:57 -05:00
{
_dlcs = value;
RaisePropertyChanged(() => DLCs);
2021-01-13 16:15:00 -05:00
/*RaisePropertyChanged(() => DllSelected);
RaisePropertyChanged(() => SteamInterfacesTxtExists);*/
2021-01-08 12:36:57 -05:00
}
}
public ObservableCollection<Achievement> Achievements
{
get => _achievements;
set
{
_achievements = value;
RaisePropertyChanged(() => Achievements);
}
}
2021-01-08 12:36:57 -05:00
public string AccountName
{
get => _accountName;
set
{
_accountName = value;
RaisePropertyChanged(() => AccountName);
}
}
public long SteamId
{
get => _steamId;
set
{
_steamId = value;
RaisePropertyChanged(() => SteamId);
}
}
public bool Offline
{
get => _offline;
set
{
_offline = value;
RaisePropertyChanged(() => Offline);
}
}
public bool DisableNetworking
{
get => _disableNetworking;
set
{
_disableNetworking = value;
RaisePropertyChanged(() => DisableNetworking);
}
}
public bool DisableOverlay
{
get => _disableOverlay;
set
{
_disableOverlay = value;
RaisePropertyChanged(() => DisableOverlay);
}
}
public bool MainWindowEnabled
{
get => _mainWindowEnabled;
set
{
_mainWindowEnabled = value;
RaisePropertyChanged(() => MainWindowEnabled);
}
}
public bool GoldbergApplied
{
get => _goldbergApplied;
set
{
_goldbergApplied = value;
RaisePropertyChanged(() => GoldbergApplied);
}
}
public bool SteamInterfacesTxtExists
{
get
{
var dllPathDirExists = GetDllPathDir(out var dirPath);
return dllPathDirExists && !File.Exists(Path.Combine(dirPath, "steam_interfaces.txt"));
}
}
public bool DllSelected
{
get
{
var value = !DllPath.Contains("Path to game's steam_api(64).dll");
2022-05-12 15:40:28 -04:00
if (!value) _log.LogWarning("No DLL selected! Skipping...");
return value;
}
}
public ObservableCollection<string> SteamLanguages
{
get => _steamLanguages;
set
{
_steamLanguages = value;
RaisePropertyChanged(() => SteamLanguages);
}
}
public string SelectedLanguage
{
get => _selectedLanguage;
set
{
_selectedLanguage = value;
RaisePropertyChanged(() => SelectedLanguage);
//MyLogger.Log.Debug($"Lang: {value}");
}
}
2021-01-13 15:26:35 -05:00
public string StatusText
{
get => _statusText;
set
{
_statusText = value;
RaisePropertyChanged(() => StatusText);
}
}
public static string AboutVersionText =>
FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion;
2021-12-22 07:15:28 -05:00
public static GlobalHelp G => new GlobalHelp();
// COMMANDS //
2021-01-08 12:36:57 -05:00
public IMvxCommand OpenFileCommand => new MvxAsyncCommand(OpenFile);
private async Task OpenFile()
{
2021-01-13 16:15:00 -05:00
MainWindowEnabled = false;
StatusText = "Please choose a file...";
2021-01-08 12:36:57 -05:00
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)
{
2021-01-13 16:15:00 -05:00
MainWindowEnabled = true;
2022-05-12 15:40:28 -04:00
_log.LogWarning("File selection canceled.");
2021-01-13 16:15:00 -05:00
StatusText = "No file selected! Ready.";
2021-01-08 12:36:57 -05:00
return;
}
2021-01-08 12:36:57 -05:00
DllPath = dialog.FileName;
await ReadConfig().ConfigureAwait(false);
2021-03-21 08:00:58 -04:00
if (!GoldbergApplied) await GetListOfDlc().ConfigureAwait(false);
2021-01-13 16:15:00 -05:00
MainWindowEnabled = true;
StatusText = "Ready.";
2021-01-08 12:36:57 -05:00
}
public IMvxCommand FindIdCommand => new MvxAsyncCommand(FindId);
2021-01-08 12:36:57 -05:00
private async Task FindId()
2021-01-08 12:36:57 -05:00
{
2021-01-13 15:26:35 -05:00
async Task FindIdInList(SteamApp[] steamApps)
{
var navigateTask = _navigationService
.Navigate<SearchResultViewModel, IEnumerable<SteamApp>, SteamApp>(steamApps);
var navigateResult = await navigateTask.ConfigureAwait(false);
if (navigateResult != null)
{
GameName = navigateResult.Name;
AppId = navigateResult.AppId;
}
}
2021-01-08 12:36:57 -05:00
if (GameName.Contains("Game name..."))
{
2022-05-12 15:40:28 -04:00
_log.LogError("No game name entered!");
2021-01-08 12:36:57 -05:00
return;
}
MainWindowEnabled = false;
2021-01-13 16:15:00 -05:00
StatusText = "Trying to find AppID...";
var appByName = await _steam.GetAppByName(_gameName).ConfigureAwait(false);
2021-01-08 12:36:57 -05:00
if (appByName != null)
{
GameName = appByName.Name;
AppId = appByName.AppId;
}
else
{
var list = await _steam.GetListOfAppsByName(GameName).ConfigureAwait(false);
var steamApps = list as SteamApp[] ?? list.ToArray();
if (steamApps.Length == 1)
{
var steamApp = steamApps[0];
if (steamApp != null)
{
GameName = steamApp.Name;
AppId = steamApp.AppId;
}
else
{
2021-01-13 15:26:35 -05:00
await FindIdInList(steamApps).ConfigureAwait(false);
}
}
else
{
2021-01-13 15:26:35 -05:00
await FindIdInList(steamApps).ConfigureAwait(false);
}
2021-01-08 12:36:57 -05:00
}
2021-03-21 08:00:58 -04:00
await GetListOfDlc().ConfigureAwait(false);
MainWindowEnabled = true;
2021-01-13 16:15:00 -05:00
StatusText = "Ready.";
2021-01-08 12:36:57 -05:00
}
//public IMvxCommand GetNameByIdCommand => new MvxAsyncCommand(GetNameById);
private async Task GetNameById()
{
if (AppId <= 0)
{
2022-05-12 15:40:28 -04:00
_log.LogError("Invalid Steam App!");
2021-01-08 12:36:57 -05:00
return;
}
var steamApp = await _steam.GetAppById(AppId).ConfigureAwait(false);
2021-01-08 12:36:57 -05:00
if (steamApp != null) GameName = steamApp.Name;
}
public IMvxCommand GetListOfAchievementsCommand => new MvxAsyncCommand(GetListOfAchievements);
private async Task GetListOfAchievements()
{
if (AppId <= 0)
{
2022-05-12 15:40:28 -04:00
_log.LogError("Invalid Steam App!");
return;
}
MainWindowEnabled = false;
StatusText = "Trying to get list of achievements...";
var listOfAchievements = await _steam.GetListOfAchievements(new SteamApp { AppId = AppId, Name = GameName });
Achievements = new MvxObservableCollection<Achievement>(listOfAchievements);
MainWindowEnabled = true;
if (Achievements.Count > 0)
{
var empty = Achievements.Count == 1 ? "" : "s";
StatusText = $"Successfully got {Achievements.Count} achievement{empty}! Ready.";
}
else
{
StatusText = "No achievements found! Ready.";
}
}
2021-01-08 12:36:57 -05:00
public IMvxCommand GetListOfDlcCommand => new MvxAsyncCommand(GetListOfDlc);
private async Task GetListOfDlc()
{
if (AppId <= 0)
{
2022-05-12 15:40:28 -04:00
_log.LogError("Invalid Steam App!");
2021-01-08 12:36:57 -05:00
return;
}
2021-01-08 12:36:57 -05:00
MainWindowEnabled = false;
2021-01-13 16:15:00 -05:00
StatusText = "Trying to get list of DLCs...";
2021-12-22 07:15:28 -05:00
var listOfDlc = await _steam.GetListOfDlc(new SteamApp { AppId = AppId, Name = GameName }, true)
.ConfigureAwait(false);
DLCs = new MvxObservableCollection<DlcApp>(listOfDlc);
2021-01-08 12:36:57 -05:00
MainWindowEnabled = true;
2021-01-13 16:15:00 -05:00
if (DLCs.Count > 0)
{
var empty = DLCs.Count == 1 ? "" : "s";
StatusText = $"Successfully got {DLCs.Count} DLC{empty}! Ready.";
}
else
{
StatusText = "No DLC found! Ready.";
}
2021-01-08 12:36:57 -05:00
}
public IMvxCommand SaveConfigCommand => new MvxAsyncCommand(SaveConfig);
private async Task SaveConfig()
{
2022-05-12 15:40:28 -04:00
_log.LogInformation("Saving global settings...");
var globalConfiguration = new GoldbergGlobalConfiguration
2021-01-08 12:36:57 -05:00
{
2021-12-22 07:15:28 -05:00
AccountName = AccountName,
UserSteamId = SteamId,
Language = SelectedLanguage
};
await _goldberg.SetGlobalSettings(globalConfiguration).ConfigureAwait(false);
if (!DllSelected) return;
2022-05-12 15:40:28 -04:00
_log.LogInformation("Saving Goldberg settings...");
2021-01-08 12:36:57 -05:00
if (!GetDllPathDir(out var dirPath)) return;
MainWindowEnabled = false;
2021-01-13 16:15:00 -05:00
StatusText = "Saving...";
await _goldberg.Save(dirPath, new GoldbergConfiguration
2021-12-22 07:15:28 -05:00
{
AppId = AppId,
Achievements = Achievements.ToList(),
2021-12-22 07:15:28 -05:00
DlcList = DLCs.ToList(),
Offline = Offline,
DisableNetworking = DisableNetworking,
DisableOverlay = DisableOverlay
}
).ConfigureAwait(false);
GoldbergApplied = _goldberg.GoldbergApplied(dirPath);
2021-01-08 12:36:57 -05:00
MainWindowEnabled = true;
2021-01-13 16:15:00 -05:00
StatusText = "Ready.";
2021-01-08 12:36:57 -05:00
}
public IMvxCommand ResetConfigCommand => new MvxAsyncCommand(ResetConfig);
private async Task ResetConfig()
{
var globalConfiguration = await _goldberg.GetGlobalSettings().ConfigureAwait(false);
AccountName = globalConfiguration.AccountName;
SteamId = globalConfiguration.UserSteamId;
SelectedLanguage = globalConfiguration.Language;
if (!DllSelected) return;
2022-05-12 15:40:28 -04:00
_log.LogInformation("Reset form...");
2021-01-08 12:36:57 -05:00
MainWindowEnabled = false;
2021-01-13 16:15:00 -05:00
StatusText = "Resetting...";
2021-01-08 12:36:57 -05:00
await ReadConfig().ConfigureAwait(false);
MainWindowEnabled = true;
2021-01-13 16:15:00 -05:00
StatusText = "Ready.";
2021-01-08 12:36:57 -05:00
}
2021-01-08 12:36:57 -05:00
public IMvxCommand GenerateSteamInterfacesCommand => new MvxAsyncCommand(GenerateSteamInterfaces);
private async Task GenerateSteamInterfaces()
{
if (!DllSelected) return;
2022-05-12 15:40:28 -04:00
_log.LogInformation("Generate steam_interfaces.txt...");
2021-01-08 12:36:57 -05:00
MainWindowEnabled = false;
2021-01-13 16:15:00 -05:00
StatusText = @"Generating ""steam_interfaces.txt"".";
GetDllPathDir(out var dirPath);
if (File.Exists(Path.Combine(dirPath, "steam_api_o.dll")))
await _goldberg.GenerateInterfacesFile(Path.Combine(dirPath, "steam_api_o.dll")).ConfigureAwait(false);
else if (File.Exists(Path.Combine(dirPath, "steam_api64_o.dll")))
await _goldberg.GenerateInterfacesFile(Path.Combine(dirPath, "steam_api64_o.dll"))
.ConfigureAwait(false);
else await _goldberg.GenerateInterfacesFile(DllPath).ConfigureAwait(false);
await RaisePropertyChanged(() => SteamInterfacesTxtExists).ConfigureAwait(false);
2021-01-08 12:36:57 -05:00
MainWindowEnabled = true;
2021-01-13 16:15:00 -05:00
StatusText = "Ready.";
2021-01-08 12:36:57 -05:00
}
2021-01-13 10:39:28 -05:00
public IMvxCommand PasteDlcCommand => new MvxCommand(() =>
{
2021-01-13 10:39:28 -05:00
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) return;
2022-05-12 15:40:28 -04:00
_log.LogInformation("Trying to paste DLC list...");
2021-01-13 10:39:28 -05:00
if (!(Clipboard.ContainsText(TextDataFormat.UnicodeText) || Clipboard.ContainsText(TextDataFormat.Text)))
{
2022-05-12 15:40:28 -04:00
_log.LogWarning("Invalid DLC list!");
2021-01-13 10:39:28 -05:00
}
else
{
var result = Clipboard.GetText();
var expression = new Regex(@"(?<id>.*) *= *(?<name>.*)");
2021-12-22 07:15:28 -05:00
var pastedDlc = (from line in result.Split(new[] { "\n", "\r\n" },
StringSplitOptions.RemoveEmptyEntries)
select expression.Match(line) into match
where match.Success
select new DlcApp
{
AppId = Convert.ToInt32(match.Groups["id"].Value),
Name = match.Groups["name"].Value
}).ToList();
2021-01-13 16:15:00 -05:00
if (pastedDlc.Count > 0)
{
DLCs.Clear();
DLCs = new ObservableCollection<DlcApp>(pastedDlc);
2021-02-17 08:27:54 -05:00
//var empty = DLCs.Count == 1 ? "" : "s";
//StatusText = $"Successfully got {DLCs.Count} DLC{empty} from clipboard! Ready.";
var statusTextCount = DLCs.Count == 1 ? "one DLC" : $"{DLCs.Count} DLCs";
StatusText = $"Successfully got {statusTextCount} from clipboard! Ready.";
2021-01-13 16:15:00 -05:00
}
else
{
StatusText = "No DLC found in clipboard! Ready.";
}
2021-01-13 10:39:28 -05:00
}
});
public IMvxCommand OpenGlobalSettingsFolderCommand => new MvxCommand(OpenGlobalSettingsFolder);
private void OpenGlobalSettingsFolder()
{
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
StatusText = "Can't open folder (Windows only)! Ready.";
return;
}
var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"Goldberg SteamEmu Saves", "settings");
var start = Process.Start("explorer.exe", path);
start?.Dispose();
}
2021-01-08 12:36:57 -05:00
// OTHER METHODS //
2021-01-08 12:36:57 -05:00
private void ResetForm()
{
DllPath = "Path to game's steam_api(64).dll...";
GameName = "Game name...";
AppId = -1;
Achievements = new ObservableCollection<Achievement>();
DLCs = new ObservableCollection<DlcApp>();
2021-01-08 12:36:57 -05:00
AccountName = "Account name...";
SteamId = -1;
Offline = false;
DisableNetworking = false;
DisableOverlay = false;
}
private async Task ReadConfig()
{
if (!GetDllPathDir(out var dirPath)) return;
var config = await _goldberg.Read(dirPath).ConfigureAwait(false);
SetFormFromConfig(config);
GoldbergApplied = _goldberg.GoldbergApplied(dirPath);
await RaisePropertyChanged(() => SteamInterfacesTxtExists).ConfigureAwait(false);
2021-01-08 12:36:57 -05:00
}
private void SetFormFromConfig(GoldbergConfiguration config)
{
AppId = config.AppId;
Achievements = new ObservableCollection<Achievement>(config.Achievements);
DLCs = new ObservableCollection<DlcApp>(config.DlcList);
Offline = config.Offline;
DisableNetworking = config.DisableNetworking;
DisableOverlay = config.DisableOverlay;
}
2021-01-08 12:36:57 -05:00
private bool GetDllPathDir(out string dirPath)
{
if (!DllSelected)
2021-01-08 12:36:57 -05:00
{
dirPath = null;
return false;
}
dirPath = Path.GetDirectoryName(DllPath);
if (dirPath != null) return true;
2022-05-12 15:40:28 -04:00
_log.LogError($"Invalid directory for {DllPath}.");
2021-01-08 12:36:57 -05:00
return false;
}
}
}