bump version to 1.0.5.0, refactor patching logic, remove unused code

This commit is contained in:
kitbyte
2025-11-30 19:01:19 +02:00
parent 13e26c3a70
commit a5583fd4f7
15 changed files with 190 additions and 977 deletions
+44 -50
View File
@@ -1,6 +1,7 @@
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Forms;
using WeModPatcher.Core;
@@ -12,15 +13,14 @@ using Application = System.Windows.Application;
namespace WeModPatcher.View.MainWindow
{
public class MainWindowVm : ObservableObject
{
private readonly MainWindow _view;
public ObservableCollection<LogEntry> LogList { get; set; } = new ObservableCollection<LogEntry>();
private static Updater _updater = new Updater();
private WeModConfig _weModConfig;
public WeModConfig WeModInfo
{
get => _weModConfig;
@@ -28,15 +28,17 @@ namespace WeModPatcher.View.MainWindow
{
SetProperty(ref _weModConfig, value);
if (value == null) return;
Log($"WeMod directory found at '{_weModConfig}' ({_weModConfig.ExecutableName})", ELogType.Success);
if (File.Exists(Path.Combine(_weModConfig.RootDirectory, "resources", "app.asar.backup")))
{
Log("WeMod already patched. If you want to patch again, please restore the backup first.", ELogType.Warn);
Log("WeMod already patched. If you want to patch again, please restore the backup first.",
ELogType.Warn);
IsPatchEnabled = false;
AlreadyPatched = true;
return;
}
Log("Ready for patching.", ELogType.Info);
IsPatchEnabled = true;
}
@@ -49,26 +51,28 @@ namespace WeModPatcher.View.MainWindow
get => _isPatchEnabled;
set => SetProperty(ref _isPatchEnabled, value);
}
private bool _alreadyPatched;
public bool AlreadyPatched
{
get => _alreadyPatched;
set => SetProperty(ref _alreadyPatched, value);
}
private bool _isUpdateAvailable;
public bool IsUpdateAvailable
{
get => _isUpdateAvailable;
set => SetProperty(ref _isUpdateAvailable, value);
}
public RelayCommand SetFolderPathCommand { get; }
public RelayCommand ApplyPatchCommand { get; }
public RelayCommand RestoreBackupCommand { get; }
public AsyncRelayCommand UpdateCommand { get; }
public RelayCommand UpdateCommand { get; }
private void OnFolderPathSelection(object obj)
{
using (var dialog = new FolderBrowserDialog())
@@ -80,7 +84,7 @@ namespace WeModPatcher.View.MainWindow
if (dialog.ShowDialog() != DialogResult.OK) return;
string selectedPath = dialog.SelectedPath;
string fileName = Path.GetFileName(selectedPath);
var info = Extensions.CheckWeModPath(selectedPath);
if (info != null)
@@ -99,37 +103,25 @@ namespace WeModPatcher.View.MainWindow
private void OnBackupRestoring(object param)
{
var backupPath = Path.Combine(WeModInfo.RootDirectory, "resources", "app.asar.backup");
if (!File.Exists(backupPath))
{
Log("Backup not found. Please dont delete it manually", ELogType.Error);
return;
}
try
{
// Try to lock the file to see if it's in use
using (File.Open(backupPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
}
// This shit doesn't look at the hash and verify() always returns true
//using X509Certificate2 cert = new X509Certificate2(X509Certificate.CreateFromSignedFile(filePath));
var restoreExeResult = MemoryUtils.PatchFile(
WeModInfo.ExecutablePath,
Constants.ExePatchSignature,
Constants.ExePatchSignature.OriginalBytes
);
if (restoreExeResult == -1)
var proxyDllPath = Path.Combine(WeModInfo.RootDirectory, "version.dll");
if(File.Exists(proxyDllPath))
{
Log("Failed to restore the backup. Please close the WeMod and try again.", ELogType.Error);
}
else
{
Log(restoreExeResult == 0 ?
"Signature exe is original, does not require restoration"
: $"{WeModInfo.ExecutableName} restored successfully", ELogType.Success);
File.Delete(proxyDllPath);
}
}
catch
@@ -137,7 +129,7 @@ namespace WeModPatcher.View.MainWindow
Log("Backup file is locked. Please close the WeMod and try again.", ELogType.Error);
return;
}
File.Copy(backupPath, Path.Combine(WeModInfo.RootDirectory, "resources", "app.asar"), true);
File.Delete(backupPath);
Log("Backup restored successfully.", ELogType.Success);
@@ -152,8 +144,8 @@ namespace WeModPatcher.View.MainWindow
Log("Can't be done. Please specify the directory first.", ELogType.Warn);
return;
}
MainWindow.Instance.OpenPopup(new PatchVectorsPopup( async config =>
MainWindow.Instance.OpenPopup(new PatchVectorsPopup(async config =>
{
MainWindow.Instance.ClosePopup();
IsPatchEnabled = false;
@@ -161,7 +153,7 @@ namespace WeModPatcher.View.MainWindow
{
try
{
new StaticPatcher(WeModInfo, Log, config).Patch();
new Patcher(WeModInfo, Log, config).Patch();
AlreadyPatched = true;
}
catch (Exception e)
@@ -170,7 +162,6 @@ namespace WeModPatcher.View.MainWindow
IsPatchEnabled = true;
}
});
}), "What are we gonna patch?");
}
@@ -190,24 +181,27 @@ namespace WeModPatcher.View.MainWindow
});
}
private async Task OnUpdate(object param)
private void OnUpdate(object param)
{
await Task.Run(async () =>
MainWindow.Instance.OpenPopup(new UpdatePopup(() =>
{
try
Task.Run(async () =>
{
await _updater.Update();
}
catch (Exception e)
{
Log($"Failed to update: {e.Message}", ELogType.Error);
return;
}
Log("WeModPatcher updated successfully. Restarting...", ELogType.Success);
});
try
{
await _updater.Update();
}
catch (Exception e)
{
Log($"Failed to update: {e.Message}", ELogType.Error);
return;
}
Log("WeModPatcher updated successfully. Restarting...", ELogType.Success);
});
}), "Update available!");
}
public MainWindowVm(MainWindow view)
{
Task.Run(async () => IsUpdateAvailable = await _updater.CheckForUpdates());
@@ -215,8 +209,8 @@ namespace WeModPatcher.View.MainWindow
SetFolderPathCommand = new RelayCommand(OnFolderPathSelection);
ApplyPatchCommand = new RelayCommand(OnPatching);
RestoreBackupCommand = new RelayCommand(OnBackupRestoring);
UpdateCommand = new AsyncRelayCommand(OnUpdate);
UpdateCommand = new RelayCommand(OnUpdate);
WeModInfo = Extensions.FindWeMod();
if (WeModInfo == null)
{
+27 -114
View File
@@ -11,124 +11,37 @@
Foreground="{DynamicResource MutedForeground}"
FontWeight="Medium"
FontSize="13">
<UserControl.Resources>
<Button x:Key="BackButton" Click="BackClicked" VerticalAlignment="Bottom" Padding="3"
Margin="0 0 15 0"
Width="35" Height="23" Style="{StaticResource IconButton}"
Tag="{StaticResource ArrowLeft}"/>
</UserControl.Resources>
<Grid>
<Grid x:Name="PatchVectors" Visibility="Visible" Margin="0 0 5 0">
<Grid Visibility="Visible" Margin="0 0 5 0">
<Grid.RowDefinitions>
<RowDefinition Height="27"/>
<RowDefinition Height="27"/>
<RowDefinition Height="27"/>
<RowDefinition Height="37"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="27" />
<RowDefinition Height="27" />
<RowDefinition Height="27" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" VerticalAlignment="Center" Text="Activate WeMod Pro"/>
<CheckBox Grid.Row="0" x:Name="ActivateProBox" HorizontalAlignment="Right" VerticalAlignment="Center" IsChecked="True"/>
<TextBlock Grid.Row="1" VerticalAlignment="Center" Text="Disable telemetry"/>
<CheckBox Grid.Row="1" x:Name="DisableTelemetryBox" HorizontalAlignment="Right" VerticalAlignment="Center"/>
<TextBlock Grid.Row="2" VerticalAlignment="Center" Text="Disable updates"/>
<CheckBox Grid.Row="2" x:Name="DisableUpdateBox" HorizontalAlignment="Right" VerticalAlignment="Center"/>
<TextBlock ToolTip="Disable if you want to use older versions separately and manage versions manually via different shortcuts"
ToolTipService.InitialShowDelay="300"
Grid.Row="3" VerticalAlignment="Center">
Apply the patch to new versions <LineBreak/> automatically (hover to see more)
<TextBlock Grid.Row="0" VerticalAlignment="Center" Text="Activate WeMod Pro" />
<CheckBox Grid.Row="0" x:Name="ActivateProBox" HorizontalAlignment="Right" VerticalAlignment="Center"
IsChecked="True" />
<TextBlock Grid.Row="1" VerticalAlignment="Center" Text="Disable telemetry" />
<CheckBox Grid.Row="1" x:Name="DisableTelemetryBox" HorizontalAlignment="Right" VerticalAlignment="Center" />
<TextBlock Grid.Row="2" VerticalAlignment="Center" Text="Disable updates" />
<CheckBox Grid.Row="2" x:Name="DisableUpdateBox" HorizontalAlignment="Right" VerticalAlignment="Center" />
<!--<TextBlock
ToolTip="Disable if you want to use older versions separately and manage versions manually via different shortcuts"
ToolTipService.InitialShowDelay="300"
Grid.Row="3" VerticalAlignment="Center">
Apply the patch to new versions <LineBreak /> automatically (hover to see more)
</TextBlock>
<CheckBox Grid.Row="3" x:Name="AutoUpdates" HorizontalAlignment="Right" VerticalAlignment="Center" IsChecked="True"/>
<Button Grid.Row="4" Padding="0 5 0 5" Margin="0 15 0 0" Content="Continue"
Click="NextClicked"/>
</Grid>
<Grid x:Name="PatchMethod" Visibility="Collapsed" Width="650">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid>
<Border Background="{DynamicResource Muted}" HorizontalAlignment="Right" Width="2"
CornerRadius="10"/>
<StackPanel>
<TextBlock FontSize="16" Text="Static" Foreground="{DynamicResource Foreground}" HorizontalAlignment="Center" Margin="0 0 0 10"/>
<controls:InfoItem
IconColor="SpringGreen"
IconData="{StaticResource CheckDecagram}"
Text="Starting WeMod without this program" />
<controls:InfoItem
Margin="0 15 0 0"
IconColor="PaleVioletRed"
IconData="{StaticResource AlertDecagram}"
Text="Violation of WeMod digital signature (possibly marked by antiviruses, anti-cheats)" />
<controls:InfoItem
Margin="0 10 0 0"
IconColor="PaleVioletRed"
IconData="{StaticResource AlertDecagram}"
Text="Auto-patching after WeMod updates is not available" />
<controls:InfoItem
Margin="0 10 0 0"
IconColor="PaleVioletRed"
IconData="{StaticResource AlertDecagram}"
Text="Hotkeys will be broken" />
</StackPanel>
</Grid>
<Grid Grid.Row="0" Grid.Column="1">
<StackPanel Margin="10 0 0 0">
<TextBlock FontSize="16" Text="Runtime" Foreground="{DynamicResource Foreground}"
HorizontalAlignment="Center" Margin="-10 0 0 10"/>
<controls:InfoItem
IconColor="SpringGreen"
IconData="{StaticResource CheckDecagram}"
Text="Hotkeys still work" />
<controls:InfoItem Margin="0 10 0 0"
IconColor="SpringGreen"
IconData="{StaticResource CheckDecagram}"
Text="Does not break the digital signature (does not make changes to the original .exe)" />
<controls:InfoItem Margin="0 10 0 0"
IconColor="SpringGreen"
IconData="{StaticResource CheckDecagram}"
Text="Automatically applies patches to new versions (referring to your current selection)" />
<controls:InfoItem
Margin="0 10 0 0"
IconColor="Yellow"
IconData="{StaticResource AlertDecagram}"
Text="The WeMod startup process is controlled by the patcher. (Don't worry, you will no longer see this window. You will run WeMod as usual but using the shortcut that will be created after choosing this method). So you will want to keep this program. Make sure it's in a safe directory (not Temp, Downloads, etc)." />
<controls:InfoItem Margin="0 10 0 0"
IconColor="PaleVioletRed"
IconData="{StaticResource AlertDecagram}"
Text="Running WeMod directly through official WeMod.exe is not possible until you restore patch backup" />
</StackPanel>
</Grid>
<Button Grid.Column="0" Grid.Row="1" VerticalAlignment="Bottom" HorizontalAlignment="Center"
Padding="10 5" Margin="0 15 0 0"
Click="OnStaticSelected"
Content="Use static"/>
<Button Grid.Column="1" Grid.Row="1" VerticalAlignment="Bottom" HorizontalAlignment="Center"
Padding="10 5" Margin="0 15 0 0"
Click="OnRuntimeSelected"
Content="Use runtime"/>
<CheckBox Grid.Row="3" x:Name="AutoUpdates" HorizontalAlignment="Right" VerticalAlignment="Center"
IsChecked="True" />-->
<Button Grid.Row="3" Padding="0 5 0 5" Margin="0 15 0 0" Content="Start"
Click="OnPatchButtonClick" />
</Grid>
</Grid>
</UserControl>
</UserControl>
@@ -7,42 +7,24 @@ using WeModPatcher.View.Controls;
namespace WeModPatcher.View.Popups
{
public partial class PatchVectorsPopup : UserControl, IDisposable
public partial class PatchVectorsPopup : UserControl
{
private readonly Action<PatchConfig> _onApply;
private readonly StackPanel _popupTitleContainer;
private string _originalTitle;
private readonly TextBlock _titleTextBlock;
public PatchVectorsPopup(Action<PatchConfig> onApply)
{
_onApply = onApply;
InitializeComponent();
_popupTitleContainer = MainWindow.MainWindow.Instance.PopupHost.TitleContainer;
_titleTextBlock = _popupTitleContainer.Children[0] as TextBlock;
}
private void BackClicked(object sender, RoutedEventArgs e)
{
Dispose();
PatchMethod.Visibility = Visibility.Collapsed;
PatchVectors.Visibility = Visibility.Visible;
}
private void OnRuntimeSelected(object sender, RoutedEventArgs e)
=> RaiseCallback(EPatchProcessMethod.Runtime);
private void OnStaticSelected(object sender, RoutedEventArgs e)
=> RaiseCallback(EPatchProcessMethod.Static);
private void RaiseCallback(EPatchProcessMethod method)
private void OnPatchButtonClick(object sender, RoutedEventArgs e)
{
if (ActivateProBox.IsChecked != true && DisableUpdateBox.IsChecked != true &&
DisableTelemetryBox.IsChecked != true)
{
return;
}
var result = new HashSet<EPatchType>();
if (ActivateProBox.IsChecked == true)
{
@@ -57,27 +39,8 @@ namespace WeModPatcher.View.Popups
_onApply(new PatchConfig
{
PatchTypes = result,
PatchMethod = method,
AutoApplyPatches = AutoUpdates.IsChecked == true
AutoApplyPatches =/* AutoUpdates.IsChecked == true*/ false
});
}
private void NextClicked(object sender, RoutedEventArgs e)
{
_popupTitleContainer.Children.Insert(0, FindResource("BackButton") as Button);
_originalTitle = _titleTextBlock.Text;
_titleTextBlock.Text = "Patch method";
PatchMethod.Visibility = Visibility.Visible;
PatchVectors.Visibility = Visibility.Collapsed;
}
public void Dispose()
{
if (PatchVectors.Visibility == Visibility.Collapsed)
{
_popupTitleContainer.Children.RemoveAt(0);
_titleTextBlock.Text = _originalTitle;
}
}
}
}
+20
View File
@@ -0,0 +1,20 @@
<UserControl x:Class="WeModPatcher.View.Popups.UpdatePopup"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WeModPatcher.View.Popups"
mc:Ignorable="d"
d:DesignHeight="Auto" d:DesignWidth="Auto"
Background="{DynamicResource Background}"
Foreground="{DynamicResource MutedForeground}"
FontWeight="Medium"
FontSize="13">
<StackPanel>
<TextBlock Foreground="Red" MaxWidth="320" TextAlignment="Center" Text="Before updating, it is strongly recommended to roll back patches if they have been applied" TextWrapping="Wrap" />
<Button Padding="0 5 0 5" Margin="0 15 0 0" Content="Update now"
Click="OnUpdateClick" />
</StackPanel>
</UserControl>
@@ -0,0 +1,22 @@
using System;
using System.Windows;
using System.Windows.Controls;
namespace WeModPatcher.View.Popups
{
public partial class UpdatePopup : UserControl
{
private readonly Action _onUpdate;
public UpdatePopup(Action onUpdate)
{
_onUpdate = onUpdate;
InitializeComponent();
}
private void OnUpdateClick(object sender, RoutedEventArgs e)
{
_onUpdate();
}
}
}