Compare commits

..

4 Commits

17 changed files with 449 additions and 107 deletions
+30
View File
@@ -0,0 +1,30 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: k1tbyte
---
**WeMod version**: X.X.X
**Patcher version**: X.X.X
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.
+20
View File
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
+111
View File
@@ -0,0 +1,111 @@
# Contributing to WeMod Patcher
Thank you for your interest in the WeMod Patcher project! This document provides guidelines for contributing to the project.
## Table of Contents
- [Development Environment Setup](#development-environment-setup)
- [Bug Reports](#bug-reports)
- [Feature Suggestions](#feature-suggestions)
- [Creating a Pull Request](#creating-a-pull-request)
- [Code Style](#code-style)
- [Testing](#testing)
- [License](#license)
## Code of Conduct
By participating in this project, you commit to maintaining respectful interactions with all community members. Any form of insults, harassment, or other unacceptable behavior will not be tolerated.
## Project Structure
The project consists of the following main components:
- **WeModPatcher** - Main project containing the patcher logic and user interface
- **AsarSharp** - Library for working with ASAR archives (used for unpacking and modifying WeMod files)
- **Core** - Core of the patcher, including static and dynamic patching
- **Models** - Data models used in the project
- **View** - User interface components
## Development Environment Setup
1. Clone the repository:
```
git clone https://github.com/k1tbyte/Wemod-Patcher.git
```
2. Open the solution `Wemod-Patcher.sln` in Visual Studio or JetBrains Rider.
3. Restore NuGet packages.
4. Build the project.
## Bug Reports
If you've found a bug, please create an Issue with a detailed description:
- WeMod Patcher version
- WeMod version where the problem occurred
- Detailed steps to reproduce the bug
- Expected and actual behavior
- Screenshots or error logs (if available)
## Feature Suggestions
Suggestions for new features or improvements are welcome! Create an Issue describing your idea, explaining:
- What problem the proposed improvement solves
- How you envision implementing this feature
- Potential alternatives you've considered
## Creating a Pull Request
1. Fork the repository.
2. Create a branch with a descriptive name:
```
git checkout -b feature/feature-name
```
or
```
git checkout -b fix/fix-name
```
3. Make the necessary changes and commit with clear, descriptive messages.
4. Ensure your code follows the project's style.
5. Push the branch to your fork:
```
git push origin your-branch-name
```
6. Create a Pull Request to the main repository.
7. In the Pull Request description, explain the changes made and why they're necessary.
## Code Style
- Use C# naming conventions:
- PascalCase for class, method, and property names
- camelCase for local variables and parameters
- _camelCase for private fields
- Add comments for complex code sections or patching methods
- Follow SOLID and DRY principles
## Testing
Before submitting a Pull Request, ensure that:
1. Your code compiles without errors
2. You've manually tested the functionality
3. The patch works with the current version of WeMod
4. Changes don't break existing functionality
## License
By contributing, you agree that your contributions will be licensed under the [Apache License 2.0](LICENSE.md).
---
Thank you for contributing to the WeMod Patcher project!
+2
View File
@@ -8,8 +8,10 @@ namespace WeModPatcher
{
public const string RepoName = "Wemod-Patcher";
public const string Owner = "k1tbyte";
/*public const string PatchRegistryName = "patchRegistry.json";*/
public static readonly string RepositoryUrl = $"https://github.com/{Owner}/{RepoName}";
public static readonly Version Version;
public static readonly string[] WeModBrandNames = { "Wand", "WeMod" };
// cmp dword ptr [rdx], 0
// jnz loc_XXXXXXXX
+13 -42
View File
@@ -3,8 +3,6 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using WeModPatcher.Models;
using WeModPatcher.Utils;
using WeModPatcher.Utils.Win32;
@@ -15,24 +13,24 @@ namespace WeModPatcher.Core
public class RuntimePatcher
{
private readonly string _exePath;
private readonly WeModConfig _config;
public RuntimePatcher(string exePath)
public RuntimePatcher(WeModConfig config)
{
_exePath = exePath;
_config = config;
}
public void StartProcess()
{
if(string.IsNullOrEmpty(_exePath))
if(string.IsNullOrEmpty(_config?.ExecutablePath))
{
throw new Exception("Path is not specified");
}
KillWeMod();
Common.TryKillProcess(_config.BrandName);
var startupInfo = new Imports.StartupInfo { cb = Marshal.SizeOf(typeof(Imports.StartupInfo)) };
if(!Imports.CreateProcessA(_exePath,
if(!Imports.CreateProcessA(_config.ExecutablePath,
null,
IntPtr.Zero,
IntPtr.Zero,
@@ -118,56 +116,29 @@ namespace WeModPatcher.Core
public static void Patch(PatchConfig config, Action<string, ELogType> logger)
{
if (config.Path == null)
if (config.AppProps == null)
{
throw new Exception("Path is not specified");
}
var parent = Directory.GetParent(config.Path)?.FullName ?? config.Path;
var latestPath = Extensions.FindLatestWeMod(parent) ?? config.Path;
var parent = Directory.GetParent(config.AppProps.RootDirectory)?.FullName ?? config.AppProps.RootDirectory;
var latestWeModConfig = config.AutoApplyPatches ? Extensions.FindLatestWeMod(parent) ?? config.AppProps : config.AppProps;
if (!Extensions.CheckWeModPath(latestPath))
if (Extensions.CheckWeModPath(latestWeModConfig.RootDirectory) == null)
{
throw new Exception("Invalid WeMod path");
}
if(!File.Exists(Path.Combine(latestPath, "resources", "app.asar.backup")))
if(!File.Exists(Path.Combine(latestWeModConfig.RootDirectory, "resources", "app.asar.backup")))
{
config.PatchMethod = EPatchProcessMethod.None;
new StaticPatcher(latestPath, logger, config).Patch();
new StaticPatcher(latestWeModConfig, logger, config).Patch();
}
new RuntimePatcher(Path.Combine(latestPath, "WeMod.exe"))
new RuntimePatcher(latestWeModConfig)
.StartProcess();
}
public static void KillWeMod()
{
Process[] processes = Process.GetProcessesByName("WeMod");
for (int i = 0; processes.Length > i || i < 5; i++)
{
foreach (var process in processes)
{
try
{
process.Kill();
}
catch
{
// ignored
}
}
processes = Process.GetProcessesByName("WeMod");
Thread.Sleep(250);
}
if (processes.Length > 0)
{
throw new Exception("Failed to kill WeMod");
}
}
}
}
+24 -17
View File
@@ -46,25 +46,23 @@ namespace WeModPatcher.Core
}
};
private readonly string _weModRootFolder;
private readonly WeModConfig _weModConfig;
private readonly Action<string, ELogType> _logger;
private readonly PatchConfig _config;
private readonly string _asarPath;
private readonly string _backupPath;
private readonly string _unpackedPath;
private int _sumOfPatches = 0;
private readonly string _exePath;
public StaticPatcher(string weModRootFolder, Action<string, ELogType> logger, PatchConfig config)
public StaticPatcher(WeModConfig weModConfig, Action<string, ELogType> logger, PatchConfig config)
{
_weModRootFolder = weModRootFolder;
_weModConfig = weModConfig;
_logger = logger;
_config = config;
_asarPath = Path.Combine(weModRootFolder, "resources", "app.asar");
_unpackedPath = Path.Combine(weModRootFolder, "resources", "app.asar.unpacked");
_backupPath = Path.Combine(weModRootFolder, "resources", "app.asar.backup");
_exePath = Path.Combine(_weModRootFolder, "WeMod.exe");
_asarPath = Path.Combine(weModConfig.RootDirectory, "resources", "app.asar");
_unpackedPath = Path.Combine(weModConfig.RootDirectory, "resources", "app.asar.unpacked");
_backupPath = Path.Combine(weModConfig.RootDirectory, "resources", "app.asar.backup");
}
private static string GetFetchFieldName(string targetFunction)
@@ -143,7 +141,11 @@ namespace WeModPatcher.Core
private void PatchPe()
{
_logger("[PATCHER] Patching PE...", ELogType.Info);
var patchResult = MemoryUtils.PatchFile(_exePath,Constants.ExePatchSignature, Constants.ExePatchSignature.PatchBytes);
var patchResult = MemoryUtils.PatchFile(
_weModConfig.ExecutablePath,
Constants.ExePatchSignature,
Constants.ExePatchSignature.PatchBytes
);
if(patchResult == -1)
{
_logger("[PATCHER] Failed to patch PE", ELogType.Error);
@@ -161,24 +163,29 @@ namespace WeModPatcher.Core
CheckPathExists = true,
AddExtension = true,
SupportMultiDottedExtensions = false,
FileName = "WeMod",
FileName = _weModConfig.BrandName,
};
if(fileDialog.ShowDialog() != DialogResult.OK)
{
return;
}
_config.Path = _weModRootFolder;
var json = JsonConvert.SerializeObject(_config, Formatting.None);
_config.Path = _weModConfig.RootDirectory;
var json = JsonConvert.SerializeObject(_config, new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
DefaultValueHandling = DefaultValueHandling.Ignore,
Formatting = Formatting.None
});
Utils.Win32.Shortcut.CreateShortcut(
fileName: fileDialog.FileName + ".lnk",
targetPath: Assembly.GetExecutingAssembly().Location,
arguments: Extensions.Base64Encode(json),
workingDirectory: Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
workingDirectory: Common.GetCurrentDir(),
description: null,
iconPath: _exePath
iconPath: _weModConfig.ExecutablePath
);
_logger("[PATCHER] The shortcut has been created, now you should only run WeMod through this shortcut", ELogType.Success);
@@ -186,7 +193,7 @@ namespace WeModPatcher.Core
public void Patch()
{
RuntimePatcher.KillWeMod();
Common.TryKillProcess(_weModConfig.BrandName);
if (!File.Exists(_backupPath))
{
_logger("[PATCHER] Creating backup...", ELogType.Info);
+102 -3
View File
@@ -1,4 +1,8 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using WeModPatcher.Utils;
namespace WeModPatcher.Models
{
@@ -16,11 +20,106 @@ namespace WeModPatcher.Models
Runtime = 1,
Static = 2
}
public sealed class PatchConfig
/*public sealed class PatchConfigOld
{
public HashSet<EPatchType> PatchTypes { get; set; }
public EPatchProcessMethod PatchMethod { get; set; }
public string Path { get; set; }
}*/
public sealed class PatchConfig
{
private string _path;
public HashSet<EPatchType> PatchTypes { get; set; }
public EPatchProcessMethod PatchMethod { get; set; }
[JsonProperty("u")]
public bool AutoApplyPatches { get; set; }
[JsonIgnore]
public WeModConfig AppProps { get; private set; }
public string Path
{
get => _path;
set
{
_path = value;
AppProps = Extensions.CheckWeModPath(_path) ?? throw new Exception("Invalid WeMod path");
}
}
/*public static void PushConfig(PatchConfig config)
{
var hash = GetConfigHash(config);
var registry = _getRegistry();
registry[hash] = config;
_stashRegistry(registry);
}
public static void ActualizeRegistry()
{
var registry = _getRegistry();
foreach (var entry in registry)
{
if(Extensions.CheckWeModPath(entry.Value.AppProps.RootDirectory) == null)
{
registry.Remove(entry.Key);
break;
}
}
_stashRegistry(registry);
}
public static PatchConfig GetConfig(string hash)
{
var registry = _getRegistry();
return registry.TryGetValue(hash, out var config) ? config : null;
}
public static string GetConfigHash(PatchConfig config)
{
return Common.ComputeSha256Hash(config.AppProps.ExecutablePath);
}
private static Dictionary<string, PatchConfig> _getRegistry()
{
var currentDir = Common.GetCurrentDir();
var registryPath = Path.Combine(currentDir, Constants.PatchRegistryName);
try
{
return JsonConvert.DeserializeObject<Dictionary<string, PatchConfig>>(
File.ReadAllText(registryPath)
);
}
catch
{
// ignored
}
return new Dictionary<string, PatchConfig>();
}
private static void _stashRegistry(Dictionary<string, PatchConfig> registry)
{
var currentDir = Common.GetCurrentDir();
var registryPath = Path.Combine(currentDir, Constants.PatchRegistryName);
if(registry.Count == 0)
{
if(File.Exists(registryPath))
{
File.Delete(registryPath);
}
return;
}
var json = JsonConvert.SerializeObject(registry, Formatting.Indented);
File.WriteAllText(registryPath, json);
}*/
}
}
+19
View File
@@ -0,0 +1,19 @@
using Newtonsoft.Json;
namespace WeModPatcher.Models
{
public class WeModConfig
{
public string BrandName { get; set; }
public string ExecutableName { get; set; }
public string RootDirectory { get; set; }
[JsonIgnore]
public string ExecutablePath => System.IO.Path.Combine(RootDirectory, ExecutableName);
public override string ToString()
{
return RootDirectory;
}
}
}
+2
View File
@@ -2,6 +2,8 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Forms;
using Newtonsoft.Json;
+2 -2
View File
@@ -51,5 +51,5 @@ using System.Windows;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.2.0")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyVersion("1.0.4.0")]
[assembly: AssemblyFileVersion("1.0.4.0")]
+54
View File
@@ -0,0 +1,54 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Threading;
namespace WeModPatcher.Utils
{
public static class Common
{
public static void TryKillProcess(string processName)
{
Process[] processes = Process.GetProcessesByName(processName);
for (int i = 0; processes.Length > i || i < 5; i++)
{
foreach (var process in processes)
{
try
{
process.Kill();
}
catch
{
// ignored
}
}
processes = Process.GetProcessesByName(processName);
Thread.Sleep(250);
}
if (processes.Length > 0)
{
throw new Exception("Failed to kill WeMod");
}
}
public static string GetCurrentDir()
{
var assemblyLocation = Assembly.GetExecutingAssembly().Location;
return Path.GetDirectoryName(assemblyLocation) ?? throw new InvalidOperationException();
}
public static string ComputeSha256Hash(string input)
{
using (var sha256 = System.Security.Cryptography.SHA256.Create())
{
var bytes = System.Text.Encoding.UTF8.GetBytes(input);
var hashBytes = sha256.ComputeHash(bytes);
return BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
}
}
}
}
+34 -18
View File
@@ -2,36 +2,54 @@
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using WeModPatcher.Models;
namespace WeModPatcher.Utils
{
public static class Extensions
{
public static bool CheckWeModPath(string root)
public static WeModConfig CheckWeModPath(string versionRoot)
{
try
{
return File.Exists(Path.Combine(root, "WeMod.exe")) &&
File.Exists(Path.Combine(root, "resources", "app.asar"));
foreach (var name in Constants.WeModBrandNames)
{
var exeName = $"{name}.exe";
var path = Path.Combine(versionRoot, exeName);
if (File.Exists(path) && File.Exists(Path.Combine(versionRoot, "resources", "app.asar")))
{
return new WeModConfig
{
BrandName = name,
ExecutableName = exeName,
RootDirectory = versionRoot
};
}
}
}
catch
{
return false;
// ignored
}
return null;
}
public static string FindWeModDirectory()
public static WeModConfig FindWeMod()
{
string localAppDataPath = Environment.GetEnvironmentVariable("LOCALAPPDATA");
string defaultDir = Path.Combine(localAppDataPath ?? "", "WeMod");
if (!Directory.Exists(defaultDir))
foreach (var folder in Constants.WeModBrandNames)
{
return null;
var weModDir = Path.Combine(localAppDataPath ?? "", folder);
if(Directory.Exists(weModDir))
{
return FindLatestWeMod(weModDir);
}
}
return FindLatestWeMod(defaultDir);
return null;
}
public static string Base64Decode(string base64EncodedData)
@@ -46,7 +64,7 @@ namespace WeModPatcher.Utils
return System.Convert.ToBase64String(plainTextBytes);
}
public static string FindLatestWeMod(string root)
public static WeModConfig FindLatestWeMod(string root)
{
var appFolders = Directory.EnumerateDirectories(root)
.Select(folderPath => new DirectoryInfo(folderPath))
@@ -59,13 +77,11 @@ namespace WeModPatcher.Utils
})
.OrderByDescending(item => item.LastModified)
.ToList();
return (
from folder
in appFolders
where CheckWeModPath(folder.Path)
select folder.Path
).FirstOrDefault();
return appFolders
.Select(folder => CheckWeModPath(folder.Path))
.FirstOrDefault(config => config != null);
}
}
}
+1 -1
View File
@@ -90,7 +90,7 @@
<Grid Margin="10" Cursor="Hand" Background="Transparent">
<TextBox Style="{StaticResource TitledTextBox}"
Uid="Folder path" IsReadOnly="True"
Text="{Binding WeModPath}"
Text="{Binding WeModInfo.RootDirectory, Mode=OneWay}"
VerticalAlignment="Center" Tag="Folder not found">
</TextBox>
<Grid.InputBindings>
+22 -22
View File
@@ -1,13 +1,8 @@
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Threading;
using AsarSharp;
using WeModPatcher.Core;
using WeModPatcher.Models;
using WeModPatcher.ReactiveUICore;
@@ -24,18 +19,18 @@ namespace WeModPatcher.View.MainWindow
public ObservableCollection<LogEntry> LogList { get; set; } = new ObservableCollection<LogEntry>();
private static Updater _updater = new Updater();
private string _weModPath;
private WeModConfig _weModConfig;
public string WeModPath
public WeModConfig WeModInfo
{
get => _weModPath;
get => _weModConfig;
set
{
SetProperty(ref _weModPath, value);
SetProperty(ref _weModConfig, value);
if (value == null) return;
Log($"WeMod directory found at '{_weModPath}'", ELogType.Success);
if (File.Exists(Path.Combine(_weModPath, "resources", "app.asar.backup")))
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);
IsPatchEnabled = false;
@@ -85,10 +80,12 @@ 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 (Extensions.CheckWeModPath(selectedPath))
if (info != null)
{
WeModPath = selectedPath;
WeModInfo = info;
return;
}
@@ -103,7 +100,7 @@ namespace WeModPatcher.View.MainWindow
private void OnBackupRestoring(object param)
{
var backupPath = Path.Combine(WeModPath, "resources", "app.asar.backup");
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);
@@ -119,8 +116,11 @@ namespace WeModPatcher.View.MainWindow
// 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( Path.Combine( WeModPath, "WeMod.exe"),
Constants.ExePatchSignature, Constants.ExePatchSignature.OriginalBytes);
var restoreExeResult = MemoryUtils.PatchFile(
WeModInfo.ExecutablePath,
Constants.ExePatchSignature,
Constants.ExePatchSignature.OriginalBytes
);
if (restoreExeResult == -1)
{
Log("Failed to restore the backup. Please close the WeMod and try again.", ELogType.Error);
@@ -129,7 +129,7 @@ namespace WeModPatcher.View.MainWindow
{
Log(restoreExeResult == 0 ?
"Signature exe is original, does not require restoration"
: "WeMod.exe restored successfully", ELogType.Success);
: $"{WeModInfo.ExecutableName} restored successfully", ELogType.Success);
}
}
catch
@@ -138,7 +138,7 @@ namespace WeModPatcher.View.MainWindow
return;
}
File.Copy(backupPath, Path.Combine(WeModPath, "resources", "app.asar"), true);
File.Copy(backupPath, Path.Combine(WeModInfo.RootDirectory, "resources", "app.asar"), true);
File.Delete(backupPath);
Log("Backup restored successfully.", ELogType.Success);
AlreadyPatched = false;
@@ -147,7 +147,7 @@ namespace WeModPatcher.View.MainWindow
private void OnPatching(object param)
{
if (WeModPath == null)
if (WeModInfo == null)
{
Log("Can't be done. Please specify the directory first.", ELogType.Warn);
return;
@@ -161,7 +161,7 @@ namespace WeModPatcher.View.MainWindow
{
try
{
new StaticPatcher(WeModPath, Log, config).Patch();
new StaticPatcher(WeModInfo, Log, config).Patch();
AlreadyPatched = true;
}
catch (Exception e)
@@ -217,8 +217,8 @@ namespace WeModPatcher.View.MainWindow
RestoreBackupCommand = new RelayCommand(OnBackupRestoring);
UpdateCommand = new AsyncRelayCommand(OnUpdate);
WeModPath = Extensions.FindWeModDirectory();
if (WeModPath == null)
WeModInfo = Extensions.FindWeMod();
if (WeModInfo == null)
{
Log("WeMod directory not found.", ELogType.Error);
}
@@ -23,6 +23,7 @@
<RowDefinition Height="27"/>
<RowDefinition Height="27"/>
<RowDefinition Height="27"/>
<RowDefinition Height="37"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
@@ -34,8 +35,15 @@
<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="3" Padding="0 5 0 5" Margin="0 15 0 0" Content="Continue"
<Button Grid.Row="4" Padding="0 5 0 5" Margin="0 15 0 0" Content="Continue"
Click="NextClicked"/>
</Grid>
@@ -57,7 +57,8 @@ namespace WeModPatcher.View.Popups
_onApply(new PatchConfig
{
PatchTypes = result,
PatchMethod = method
PatchMethod = method,
AutoApplyPatches = AutoUpdates.IsChecked == true
});
}
+2
View File
@@ -67,12 +67,14 @@
<Compile Include="Converters\ToVisibilityConverter.cs" />
<Compile Include="Core\RuntimePatcher.cs" />
<Compile Include="Core\StaticPatcher.cs" />
<Compile Include="Models\WeModConfig.cs" />
<Compile Include="Models\PatchConfig.cs" />
<Compile Include="Models\Signature.cs" />
<Compile Include="Program.cs" />
<Compile Include="ReactiveUICore\AsyncRelayCommand.cs" />
<Compile Include="ReactiveUICore\ObservableObject.cs" />
<Compile Include="ReactiveUICore\RelayCommand.cs" />
<Compile Include="Utils\Common.cs" />
<Compile Include="Utils\Extensions.cs" />
<Compile Include="Utils\MemoryUtils.cs" />
<Compile Include="Utils\Updater.cs" />