mirror of
https://github.com/SteamAutoCracks/Steam-auto-crack.git
synced 2025-05-12 19:05:40 +02:00
618 lines
No EOL
21 KiB
C#
618 lines
No EOL
21 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Diagnostics;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Input;
|
|
using System.Windows.Navigation;
|
|
using Antelcat.I18N.Attributes;
|
|
using Microsoft.Win32;
|
|
using Serilog;
|
|
using Serilog.Events;
|
|
using SteamAutoCrack.Core.Config;
|
|
using SteamAutoCrack.Core.Utils;
|
|
using SteamAutoCrack.Properties;
|
|
using SteamAutoCrack.Utils;
|
|
using SteamAutoCrack.ViewModels;
|
|
using SteamAutoCrack.Views;
|
|
using WPFCustomMessageBox;
|
|
|
|
namespace SteamAutoCrack;
|
|
|
|
//Auto generated class should be partial
|
|
[ResourceKeysOf(typeof(Resources))]
|
|
public partial class LangKeys
|
|
{
|
|
}
|
|
|
|
public partial class MainWindow
|
|
{
|
|
private readonly ILogger _log;
|
|
|
|
private readonly MainWindowViewModel viewModel = new();
|
|
private bool bAboutOpened;
|
|
private bool bAppIDFinderOpened;
|
|
|
|
private bool bSettingsOpened;
|
|
private bool bStarted;
|
|
private CancellationTokenSource cts = new();
|
|
|
|
private enum UIState
|
|
{
|
|
Idle,
|
|
Processing,
|
|
ProcessingNoStop,
|
|
AnotherWindowOpened,
|
|
}
|
|
|
|
private UIState _currentUIState = UIState.Idle;
|
|
private class UIStates
|
|
{
|
|
public bool _init { get; set; } = false; // Indicate if the UI state is initialized or not
|
|
public bool GenerateEMUGameInfo { get; set; } = true;
|
|
public bool GenerateEMUConfig { get; set; } = true;
|
|
public bool Unpack { get; set; } = true;
|
|
public bool ApplyEMU { get; set; } = true;
|
|
public bool GenerateCrackOnly { get; set; } = false;
|
|
}
|
|
private UIStates _prevuiStates = new()
|
|
{
|
|
GenerateEMUGameInfo = true,
|
|
GenerateEMUConfig = true,
|
|
Unpack = true,
|
|
ApplyEMU = true,
|
|
GenerateCrackOnly = false
|
|
};
|
|
|
|
/// <summary>
|
|
/// UI State Machine
|
|
/// </summary>
|
|
private void UpdateUIState(UIState newState, bool set_restore = false)
|
|
{
|
|
_currentUIState = newState;
|
|
Dispatcher.Invoke(() =>
|
|
{
|
|
switch (newState)
|
|
{
|
|
case UIState.Idle:
|
|
Start.IsEnabled = true;
|
|
AppIDFinder.IsEnabled = true;
|
|
Settings.IsEnabled = true;
|
|
GenerateEMUGameInfoGrid.IsEnabled = true;
|
|
GenerateEMUConfigGrid.IsEnabled = true;
|
|
UnpackGrid.IsEnabled = true;
|
|
ApplyEMUGrid.IsEnabled = true;
|
|
GenerateCrackOnlyGrid.IsEnabled = true;
|
|
// Allow other areas when not enabled restore
|
|
if (set_restore && _prevuiStates._init)
|
|
{
|
|
if (viewModel.Restore)
|
|
{
|
|
_prevuiStates.GenerateEMUGameInfo = viewModel.GenerateEMUGameInfo;
|
|
_prevuiStates.GenerateEMUConfig = viewModel.GenerateEMUConfig;
|
|
_prevuiStates.Unpack = viewModel.Unpack;
|
|
_prevuiStates.ApplyEMU = viewModel.ApplyEMU;
|
|
_prevuiStates.GenerateCrackOnly = viewModel.GenerateCrackOnly;
|
|
|
|
viewModel.GenerateEMUGameInfo = false;
|
|
viewModel.GenerateEMUConfig = false;
|
|
viewModel.Unpack = false;
|
|
viewModel.ApplyEMU = false;
|
|
viewModel.GenerateCrackOnly = false;
|
|
}
|
|
else
|
|
{
|
|
viewModel.GenerateEMUGameInfo = _prevuiStates.GenerateEMUGameInfo;
|
|
viewModel.GenerateEMUConfig = _prevuiStates.GenerateEMUConfig;
|
|
viewModel.Unpack = _prevuiStates.Unpack;
|
|
viewModel.ApplyEMU = _prevuiStates.ApplyEMU;
|
|
viewModel.GenerateCrackOnly = _prevuiStates.GenerateCrackOnly;
|
|
}
|
|
|
|
}
|
|
_prevuiStates._init = true;
|
|
GenerateEMUGameInfo.IsEnabled = !viewModel.Restore;
|
|
GenerateEMUConfig.IsEnabled = !viewModel.Restore;
|
|
Unpack.IsEnabled = !viewModel.Restore;
|
|
ApplyEMU.IsEnabled = !viewModel.Restore;
|
|
GenerateCrackOnly.IsEnabled = !viewModel.Restore;
|
|
Restore.IsEnabled = true;
|
|
InputPath.IsEnabled = true;
|
|
Select.IsEnabled = true;
|
|
viewModel.StartBtnString = Properties.Resources.Start;
|
|
break;
|
|
case UIState.Processing:
|
|
Start.IsEnabled = true;
|
|
AppIDFinder.IsEnabled = false;
|
|
Settings.IsEnabled = false;
|
|
GenerateEMUGameInfoGrid.IsEnabled = false;
|
|
GenerateEMUConfigGrid.IsEnabled = false;
|
|
UnpackGrid.IsEnabled = false;
|
|
ApplyEMUGrid.IsEnabled = false;
|
|
GenerateCrackOnlyGrid.IsEnabled = false;
|
|
GenerateEMUGameInfo.IsEnabled = false;
|
|
GenerateEMUConfig.IsEnabled = false;
|
|
Unpack.IsEnabled = false;
|
|
ApplyEMU.IsEnabled = false;
|
|
GenerateCrackOnly.IsEnabled = false;
|
|
Restore.IsEnabled = false;
|
|
InputPath.IsEnabled = false;
|
|
Select.IsEnabled = false;
|
|
viewModel.StartBtnString = Properties.Resources.Stop;
|
|
break;
|
|
case UIState.ProcessingNoStop:
|
|
Start.IsEnabled = false;
|
|
AppIDFinder.IsEnabled = false;
|
|
Settings.IsEnabled = false;
|
|
GenerateEMUGameInfoGrid.IsEnabled = false;
|
|
GenerateEMUConfigGrid.IsEnabled = false;
|
|
UnpackGrid.IsEnabled = false;
|
|
ApplyEMUGrid.IsEnabled = false;
|
|
GenerateCrackOnlyGrid.IsEnabled = false;
|
|
GenerateEMUGameInfo.IsEnabled = false;
|
|
GenerateEMUConfig.IsEnabled = false;
|
|
Unpack.IsEnabled = false;
|
|
ApplyEMU.IsEnabled = false;
|
|
GenerateCrackOnly.IsEnabled = false;
|
|
Restore.IsEnabled = false;
|
|
InputPath.IsEnabled = false;
|
|
Select.IsEnabled = false;
|
|
break;
|
|
case UIState.AnotherWindowOpened:
|
|
Start.IsEnabled = false;
|
|
AppIDFinder.IsEnabled = false;
|
|
Settings.IsEnabled = false;
|
|
break;
|
|
}
|
|
});
|
|
}
|
|
|
|
public MainWindow()
|
|
{
|
|
if (Config.SaveCrackConfig) Config.LoadConfig();
|
|
Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(Config.GetLanguage());
|
|
InitializeComponent();
|
|
if (Config.LogToFile)
|
|
Log.Logger = new LoggerConfiguration()
|
|
.Enrich.WithProperty("SourceContext", null)
|
|
.MinimumLevel.ControlledBy(Config.loggingLevelSwitch)
|
|
.WriteTo.ListViewSink(LogBox)
|
|
.WriteTo.File("error.log", LogEventLevel.Error,
|
|
"[{Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}", shared: true)
|
|
.WriteTo.File("log.log",
|
|
outputTemplate: "[{Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}", shared: true)
|
|
.CreateLogger();
|
|
else
|
|
Log.Logger = new LoggerConfiguration()
|
|
.Enrich.WithProperty("SourceContext", null)
|
|
.MinimumLevel.ControlledBy(Config.loggingLevelSwitch)
|
|
.WriteTo.ListViewSink(LogBox)
|
|
.WriteTo.File("error.log", LogEventLevel.Error,
|
|
"[{Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}", shared: true)
|
|
.CreateLogger();
|
|
_log = Log.ForContext<MainWindow>();
|
|
DataContext = viewModel;
|
|
viewModel.StartBtnString = Properties.Resources.Start;
|
|
Config.OnLanguageChanged += newLanguage =>
|
|
{
|
|
I18NExtension.Culture = new CultureInfo(Config.GetLanguage());
|
|
viewModel.StartBtnString = Properties.Resources.Start;
|
|
};
|
|
Loaded += MainWindow_Loaded;
|
|
Task.Run(async () => { await SteamAppList.Initialize().ConfigureAwait(false); });
|
|
Task.Run(() => { CheckGoldberg(); });
|
|
}
|
|
|
|
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
|
|
{
|
|
SteamAPICheckBypassMode_SelectionChanged(null, null);
|
|
UpdateUIState(UIState.Idle);
|
|
}
|
|
|
|
private void MainWindow_Closing(object sender, CancelEventArgs e)
|
|
{
|
|
Environment.Exit(0);
|
|
}
|
|
|
|
#region GenCrackOnly
|
|
|
|
private void SelectOutpath_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
var selector = new OpenFolderDialog();
|
|
selector.Multiselect = false;
|
|
if (selector.ShowDialog() == true) viewModel.OutputPath = selector.FolderName;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region SteamStubUnpacker
|
|
|
|
private void SteamAPICheckBypassMode_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
{
|
|
if (SteamAPICheckBypassNthTime == null)
|
|
return;
|
|
if (viewModel.SteamAPICheckBypassMode == SteamStubUnpackerConfig.SteamAPICheckBypassModes.Disabled ||
|
|
viewModel.SteamAPICheckBypassMode == SteamStubUnpackerConfig.SteamAPICheckBypassModes.All)
|
|
SteamAPICheckBypassNthTime.IsEnabled = false;
|
|
else
|
|
SteamAPICheckBypassNthTime.IsEnabled = true;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Basic
|
|
|
|
private void Start_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
Task.Run(async () =>
|
|
{
|
|
if (bStarted)
|
|
{
|
|
Dispatcher.Invoke(() => { Start.IsEnabled = false; });
|
|
cts.Cancel();
|
|
return;
|
|
}
|
|
|
|
UpdateUIState(UIState.ProcessingNoStop);
|
|
|
|
cts = new CancellationTokenSource();
|
|
|
|
if (viewModel.GenerateEMUGameInfo && viewModel.AppID == string.Empty && viewModel.InputPath != string.Empty)
|
|
{
|
|
_log.Information(Properties.Resources.EmptyAppIDPleaseSelectOneUsingAppIDFinder);
|
|
if (!bAppIDFinderOpened)
|
|
Dispatcher.Invoke(() =>
|
|
{
|
|
bAppIDFinderOpened = true;
|
|
var finder = new AppIDFinder(GetAppName());
|
|
finder.ClosingEvent += AppIDFinderClosedStart;
|
|
finder.OKEvent += AppIDFinderOKStart;
|
|
finder.Show();
|
|
});
|
|
|
|
return;
|
|
}
|
|
|
|
UpdateUIState(UIState.Processing);
|
|
|
|
bStarted = true;
|
|
await new Processor().ProcessFileGUI(cts.Token).ConfigureAwait(false);
|
|
UpdateUIState(UIState.Idle);
|
|
bStarted = false;
|
|
});
|
|
}
|
|
|
|
private void AppIDFinderClosedStart()
|
|
{
|
|
if (bStarted) return;
|
|
Task.Run(() =>
|
|
{
|
|
bAppIDFinderOpened = false;
|
|
UpdateUIState(UIState.Idle);
|
|
});
|
|
}
|
|
|
|
private void AppIDFinderOKStart(uint appid)
|
|
{
|
|
bStarted = true;
|
|
Task.Run(async () =>
|
|
{
|
|
viewModel.AppID = appid.ToString();
|
|
bAppIDFinderOpened = false;
|
|
UpdateUIState(UIState.Processing);
|
|
|
|
await new Processor().ProcessFileGUI(cts.Token).ConfigureAwait(false);
|
|
UpdateUIState(UIState.Idle);
|
|
bStarted = false;
|
|
});
|
|
}
|
|
|
|
private void Clear_Log_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
LogBox.Items.Clear();
|
|
}
|
|
|
|
private void InputPath_PreviewDragOver(object sender, RoutedEventArgs e)
|
|
{
|
|
e.Handled = true;
|
|
}
|
|
|
|
private void InputPath_PreviewDrop(object sender, DragEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
var file = (string[])e.Data.GetData(DataFormats.FileDrop);
|
|
if (file.Length == 1 && (File.Exists(file[0]) || Directory.Exists(file[0]))) viewModel.InputPath = file[0];
|
|
e.Handled = true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_log.Error(ex, "");
|
|
}
|
|
}
|
|
|
|
private void Select_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
var result = CustomMessageBox.ShowYesNoCancel(Properties.Resources.SelectFolderOrFile,
|
|
Properties.Resources.SelectFolderOrFile, Properties.Resources.Folder, Properties.Resources.File,
|
|
Properties.Resources.Cancel);
|
|
if (result == MessageBoxResult.Yes)
|
|
{
|
|
var selector = new OpenFolderDialog();
|
|
selector.Multiselect = false;
|
|
if (selector.ShowDialog() == true) viewModel.InputPath = selector.FolderName;
|
|
}
|
|
|
|
if (result == MessageBoxResult.No)
|
|
{
|
|
var selector = new OpenFileDialog();
|
|
selector.Multiselect = false;
|
|
selector.Filter = "Game Files|*.exe;steam_api.dll;steam_api64.dll" +
|
|
"|All Files|*.*";
|
|
if (selector.ShowDialog() == true) viewModel.InputPath = selector.FileName;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_log.Error(ex, Properties.Resources.ErrorWhenSelectingFile);
|
|
}
|
|
}
|
|
|
|
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri) { UseShellExecute = true });
|
|
e.Handled = true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_log.Error(ex, "");
|
|
}
|
|
}
|
|
|
|
private void Exit_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
Environment.Exit(0);
|
|
}
|
|
|
|
private void Settings_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (!bSettingsOpened)
|
|
{
|
|
bSettingsOpened = true;
|
|
UpdateUIState(UIState.AnotherWindowOpened);
|
|
var settings = new Settings();
|
|
settings.ClosingEvent += SettingClosed;
|
|
settings.ReloadValueEvent += viewModel.ReloadValue;
|
|
settings.ReloadValueEvent += settings.ReloadValue;
|
|
settings.Show();
|
|
}
|
|
}
|
|
|
|
private void AppIDFinder_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (!bAppIDFinderOpened)
|
|
{
|
|
bAppIDFinderOpened = true;
|
|
UpdateUIState(UIState.AnotherWindowOpened);
|
|
var finder = new AppIDFinder(GetAppName());
|
|
finder.ClosingEvent += AppIDFinderClosed;
|
|
finder.OKEvent += AppIDFinderOK;
|
|
finder.Show();
|
|
}
|
|
}
|
|
|
|
private void About_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (!bAboutOpened)
|
|
{
|
|
bAboutOpened = true;
|
|
|
|
var about = new About();
|
|
about.ClosingEvent += AboutClosed;
|
|
about.Show();
|
|
}
|
|
}
|
|
|
|
private string GetAppName()
|
|
{
|
|
try
|
|
{
|
|
if (viewModel.InputPath != string.Empty)
|
|
{
|
|
var path = Path.GetRelativePath(Path.Combine(viewModel.InputPath, ".."), viewModel.InputPath);
|
|
if (path[path.Length - 1].ToString() == @"\") path = path.Substring(0, path.Length - 1);
|
|
|
|
return path;
|
|
}
|
|
|
|
return string.Empty;
|
|
;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_log.Information(ex, Properties.Resources.CannotGetAppNameFromInputPath);
|
|
return string.Empty;
|
|
}
|
|
}
|
|
|
|
private void AppIDFinderClosed()
|
|
{
|
|
bAppIDFinderOpened = false;
|
|
UpdateUIState(UIState.Idle);
|
|
}
|
|
|
|
private void AppIDFinderOK(uint appid)
|
|
{
|
|
viewModel.AppID = appid.ToString();
|
|
bAppIDFinderOpened = false;
|
|
UpdateUIState(UIState.Idle);
|
|
}
|
|
|
|
private void AboutClosed()
|
|
{
|
|
bAboutOpened = false;
|
|
}
|
|
|
|
private void SettingClosed()
|
|
{
|
|
bSettingsOpened = false;
|
|
UpdateUIState(UIState.Idle);
|
|
}
|
|
|
|
public void CheckGoldberg()
|
|
{
|
|
if (!GoldbergStatus())
|
|
Application.Current.Dispatcher.Invoke((Action)(() =>
|
|
{
|
|
var result = CustomMessageBox.ShowYesNo(
|
|
Properties.Resources.GoldbergEmulatorFileIsMissingNDownloadGoldbergEmulator1 + "\n" +
|
|
Properties.Resources.GoldbergEmulatorFileIsMissingNDownloadGoldbergEmulator2,
|
|
Properties.Resources.GoldbergEmulatorFileIsMissingNDownloadGoldbergEmulator2,
|
|
Properties.Resources.Download, Properties.Resources.Cancel);
|
|
if (result == MessageBoxResult.Yes)
|
|
Task.Run(async () =>
|
|
{
|
|
var updater = new EMUUpdater();
|
|
await updater.Init().ConfigureAwait(false);
|
|
await updater.Download(true).ConfigureAwait(false);
|
|
});
|
|
}));
|
|
}
|
|
|
|
public bool GoldbergStatus()
|
|
{
|
|
try
|
|
{
|
|
_log.Debug(Properties.Resources.CheckingAllGoldbergEmulatorFileExistsOrNot);
|
|
if (!Directory.Exists(Config.GoldbergPath)) return false;
|
|
var filelist = new List<string>
|
|
{
|
|
Path.Combine(Config.GoldbergPath, "x64", "steam_api64.dll"),
|
|
Path.Combine(Config.GoldbergPath, "x32", "steam_api.dll"),
|
|
Path.Combine(Config.GoldbergPath, "experimental", "x64", "steam_api64.dll"),
|
|
Path.Combine(Config.GoldbergPath, "experimental", "x32", "steam_api.dll")
|
|
};
|
|
foreach (var file in filelist)
|
|
if (!File.Exists(file))
|
|
return false;
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_log.Error(ex, Properties.Resources.FailedToCheckGoldbergEmulator);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region GenerateEMUGameInfo
|
|
|
|
private void AppID_PreviewTextInput(object sender, TextCompositionEventArgs e)
|
|
{
|
|
e.Handled = !uint.TryParse(AppID.Text + e.Text, out _);
|
|
}
|
|
|
|
private void AppID_Pasting(object sender, DataObjectPastingEventArgs e)
|
|
{
|
|
if (e.DataObject.GetDataPresent(typeof(string)))
|
|
{
|
|
var text = (string)e.DataObject.GetData(typeof(string));
|
|
if (!uint.TryParse(text, out _)) e.CancelCommand();
|
|
}
|
|
else
|
|
{
|
|
e.CancelCommand();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region GenerateEMUConfig
|
|
|
|
private void SteamID_PreviewTextInput(object sender, TextCompositionEventArgs e)
|
|
{
|
|
e.Handled = !ulong.TryParse(AppID.Text + e.Text, out _);
|
|
}
|
|
|
|
private void SteamID_Pasting(object sender, DataObjectPastingEventArgs e)
|
|
{
|
|
if (e.DataObject.GetDataPresent(typeof(string)))
|
|
{
|
|
var text = (string)e.DataObject.GetData(typeof(string));
|
|
if (!ulong.TryParse(text, out _)) e.CancelCommand();
|
|
}
|
|
else
|
|
{
|
|
e.CancelCommand();
|
|
}
|
|
}
|
|
|
|
private void ListenPort_PreviewTextInput(object sender, TextCompositionEventArgs e)
|
|
{
|
|
e.Handled = !ushort.TryParse(AppID.Text + e.Text, out var i);
|
|
}
|
|
|
|
private void ListenPort_Pasting(object sender, DataObjectPastingEventArgs e)
|
|
{
|
|
if (e.DataObject.GetDataPresent(typeof(string)))
|
|
{
|
|
var text = (string)e.DataObject.GetData(typeof(string));
|
|
if (!ushort.TryParse(text, out _)) e.CancelCommand();
|
|
}
|
|
else
|
|
{
|
|
e.CancelCommand();
|
|
}
|
|
}
|
|
|
|
private void OpenExample_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (Directory.Exists(Path.Combine(Config.GoldbergPath, "steam_settings.EXAMPLE")))
|
|
Process.Start("explorer.exe", Path.Combine(Config.GoldbergPath, "steam_settings.EXAMPLE"));
|
|
else
|
|
_log.Error("Goldberg Steam Emulator Config EXAMPLE folder missing.");
|
|
e.Handled = true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_log.Error(ex, "");
|
|
}
|
|
}
|
|
|
|
private void OpenConfigFolder_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (Directory.Exists(Config.EMUConfigPath))
|
|
Process.Start("explorer.exe", Config.EMUConfigPath);
|
|
else
|
|
_log.Information("Goldberg Steam Emulator Config EXAMPLE folder not exist.");
|
|
e.Handled = true;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Restore
|
|
|
|
private void Restore_Checked(object sender, RoutedEventArgs e)
|
|
{
|
|
UpdateUIState(UIState.Idle, true);
|
|
}
|
|
|
|
private void Restore_Unchecked(object sender, RoutedEventArgs e)
|
|
{
|
|
UpdateUIState(UIState.Idle, true);
|
|
}
|
|
|
|
#endregion
|
|
} |