├── Example ├── DnupDemo.exe └── Example.dnup ├── DotNetUniversalPatcher ├── Logo.ico ├── Utilities │ ├── LoggerLevel.cs │ ├── ILogger.cs │ ├── Constants.cs │ ├── Logger.cs │ └── Helpers.cs ├── Models │ ├── ActionMethod.cs │ ├── ILCode.cs │ ├── PatcherOptions.cs │ ├── TargetInfo.cs │ ├── Patch.cs │ ├── PatcherScript.cs │ ├── PatcherInfo.cs │ └── Target.cs ├── Exceptions │ ├── PatcherException.cs │ ├── ValidatePatchException.cs │ └── ValidatePatchAndTargetException.cs ├── Engine │ ├── IScriptEngine.cs │ ├── ScriptEngineBase.cs │ ├── ScriptEngine.cs │ ├── ScriptEngineHelpers.cs │ └── Patcher.cs ├── Program.cs ├── Extensions │ ├── ListExtensions.cs │ ├── DataGridViewExtensions.cs │ └── StringExtensions.cs ├── DotNetUniversalPatcher.csproj ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.zh-Hans.resx │ └── Resources.resx └── UI │ ├── FrmAbout.cs │ ├── FrmAbout.Designer.cs │ ├── FrmMain.cs │ ├── FrmPatcherOptions.cs │ ├── FrmAddTarget.cs │ ├── FrmMain.Designer.cs │ └── FrmAddTarget.Designer.cs ├── dnSpy-Extension ├── README.md └── DotNet Universal Patcher Helper (dnSpy Extension).zip ├── LICENSE ├── DotNetUniversalPatcher.sln ├── README.md └── .gitignore /Example/DnupDemo.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobile46/DotNetUniversalPatcher/HEAD/Example/DnupDemo.exe -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobile46/DotNetUniversalPatcher/HEAD/DotNetUniversalPatcher/Logo.ico -------------------------------------------------------------------------------- /dnSpy-Extension/README.md: -------------------------------------------------------------------------------- 1 | # DotNet Universal Patcher Helper (dnSpy Extension) 2 | 3 | Copy "Extension" folder to the "dnSpy/bin" folder. 4 | -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Utilities/LoggerLevel.cs: -------------------------------------------------------------------------------- 1 | namespace DotNetUniversalPatcher.Utilities 2 | { 3 | public enum LoggerLevel 4 | { 5 | None, 6 | Info, 7 | Error 8 | } 9 | } -------------------------------------------------------------------------------- /dnSpy-Extension/DotNet Universal Patcher Helper (dnSpy Extension).zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobile46/DotNetUniversalPatcher/HEAD/dnSpy-Extension/DotNet Universal Patcher Helper (dnSpy Extension).zip -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Utilities/ILogger.cs: -------------------------------------------------------------------------------- 1 | namespace DotNetUniversalPatcher.Utilities 2 | { 3 | public interface ILogger 4 | { 5 | void Log(string text, LoggerLevel loggerEvent); 6 | } 7 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Models/ActionMethod.cs: -------------------------------------------------------------------------------- 1 | namespace DotNetUniversalPatcher.Models 2 | { 3 | public enum ActionMethod 4 | { 5 | Patch, 6 | Insert, 7 | Replace, 8 | Remove, 9 | EmptyBody, 10 | ReturnBody 11 | } 12 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Exceptions/PatcherException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DotNetUniversalPatcher.Exceptions 4 | { 5 | internal class PatcherException : Exception 6 | { 7 | internal PatcherException(string message, string fullName) : base($"{message} -> {fullName}") 8 | { 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Models/ILCode.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | 3 | namespace DotNetUniversalPatcher.Models 4 | { 5 | public class ILCode 6 | { 7 | [DefaultValue("")] 8 | public string OpCode { get; set; } 9 | 10 | [DefaultValue("")] 11 | public string Operand { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Exceptions/ValidatePatchException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DotNetUniversalPatcher.Exceptions 4 | { 5 | internal class ValidatePatchException : Exception 6 | { 7 | internal ValidatePatchException(string message, int patchIndex) : base($"{message} -> Patch index: {patchIndex}") 8 | { 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Models/PatcherOptions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace DotNetUniversalPatcher.Models 4 | { 5 | public class PatcherOptions 6 | { 7 | public PatcherInfo PatcherInfo { get; set; } = new PatcherInfo(); 8 | public Dictionary Placeholders { get; set; } = new Dictionary(); 9 | } 10 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Models/TargetInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | 4 | namespace DotNetUniversalPatcher.Models 5 | { 6 | public class TargetInfo 7 | { 8 | public List TargetFiles { get; set; } = new List(); 9 | 10 | [DefaultValue(false)] 11 | public bool KeepOldMaxStack { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Exceptions/ValidatePatchAndTargetException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DotNetUniversalPatcher.Exceptions 4 | { 5 | internal class ValidatePatchAndTargetException : Exception 6 | { 7 | internal ValidatePatchAndTargetException(string message, int patchIndex, int targetIndex) : base($"{message} -> Patch/Target index: {patchIndex}/{targetIndex}") 8 | { 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Engine/IScriptEngine.cs: -------------------------------------------------------------------------------- 1 | using DotNetUniversalPatcher.Models; 2 | using System.Collections.Generic; 3 | 4 | namespace DotNetUniversalPatcher.Engine 5 | { 6 | internal interface IScriptEngine 7 | { 8 | List LoadedScripts { get; set; } 9 | PatcherScript CurrentScript { get; set; } 10 | bool IsLoadingError { get; set; } 11 | 12 | void LoadAndParseScripts(); 13 | 14 | void ChangeScript(); 15 | 16 | void Process(); 17 | 18 | string[] GetSoftwareNames(); 19 | } 20 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Models/Patch.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.Collections.Generic; 3 | 4 | namespace DotNetUniversalPatcher.Models 5 | { 6 | public class Patch 7 | { 8 | [JsonIgnore] 9 | public string Name { get; set; } 10 | 11 | public Patch(string name) 12 | { 13 | Name = name; 14 | } 15 | 16 | public TargetInfo TargetInfo { get; set; } = new TargetInfo(); 17 | public List TargetList { get; set; } = new List(); 18 | 19 | public override string ToString() 20 | { 21 | return Name; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Models/PatcherScript.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.Collections.Generic; 3 | 4 | namespace DotNetUniversalPatcher.Models 5 | { 6 | public class PatcherScript 7 | { 8 | public PatcherOptions PatcherOptions { get; set; } = new PatcherOptions(); 9 | public List PatchList { get; set; } = new List(); 10 | 11 | [JsonIgnore] 12 | public List TargetFilesText { get; set; } = new List(); 13 | 14 | [JsonIgnore] 15 | public int TargetFilesCount { get; set; } 16 | 17 | [JsonIgnore] 18 | public string TargetFilesTip { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Engine/ScriptEngineBase.cs: -------------------------------------------------------------------------------- 1 | using DotNetUniversalPatcher.Models; 2 | using System.Collections.Generic; 3 | 4 | namespace DotNetUniversalPatcher.Engine 5 | { 6 | internal abstract class ScriptEngineBase : IScriptEngine 7 | { 8 | public List LoadedScripts { get; set; } 9 | public PatcherScript CurrentScript { get; set; } 10 | public bool IsLoadingError { get; set; } 11 | 12 | public abstract void LoadAndParseScripts(); 13 | 14 | public abstract void ChangeScript(); 15 | 16 | public abstract void Process(); 17 | 18 | public abstract string[] GetSoftwareNames(); 19 | } 20 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Models/PatcherInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | namespace DotNetUniversalPatcher.Models 5 | { 6 | public class PatcherInfo 7 | { 8 | public string Software { get; set; } 9 | 10 | [DefaultValue("")] 11 | public string Author { get; set; } 12 | 13 | [DefaultValue("")] 14 | public string Website { get; set; } 15 | 16 | public DateTime? ReleaseDate { get; set; } 17 | 18 | [DefaultValue("")] 19 | public string ReleaseInfo { get; set; } 20 | 21 | [DefaultValue("")] 22 | public string AboutText { get; set; } 23 | 24 | [DefaultValue(false)] 25 | public bool MakeBackup { get; set; } 26 | } 27 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Program.cs: -------------------------------------------------------------------------------- 1 | using DotNetUniversalPatcher.UI; 2 | using DotNetUniversalPatcher.Utilities; 3 | using System; 4 | using System.Windows.Forms; 5 | 6 | namespace DotNetUniversalPatcher 7 | { 8 | internal static class Program 9 | { 10 | internal static bool IsDebugModeEnabled; 11 | 12 | /// 13 | /// The main entry point for the application. 14 | /// 15 | [STAThread] 16 | private static void Main() 17 | { 18 | Application.EnableVisualStyles(); 19 | Application.SetCompatibleTextRenderingDefault(false); 20 | Helpers.CreatePatcherDirIfNotExists(); 21 | Helpers.SetDebugMode(); 22 | FrmMain.Instance = new FrmMain(); 23 | Application.Run(FrmMain.Instance); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Models/Target.cs: -------------------------------------------------------------------------------- 1 | using dnlib.DotNet.Emit; 2 | using Newtonsoft.Json; 3 | using Newtonsoft.Json.Converters; 4 | using System.Collections.Generic; 5 | using System.ComponentModel; 6 | 7 | namespace DotNetUniversalPatcher.Models 8 | { 9 | public class Target 10 | { 11 | public string FullName { get; set; } 12 | 13 | [JsonIgnore] 14 | public Instruction[] Instructions { get; set; } 15 | 16 | [JsonProperty("Instructions")] 17 | public List ILCodes { get; set; } = new List(); 18 | 19 | public List Indices { get; set; } = new List(); 20 | 21 | [JsonConverter(typeof(StringEnumConverter))] 22 | public ActionMethod? Action { get; set; } 23 | 24 | [DefaultValue("")] 25 | public string Optional { get; set; } 26 | } 27 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Extensions/ListExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace DotNetUniversalPatcher.Extensions 4 | { 5 | public static class ListExtensions 6 | { 7 | internal static void MoveUp(this List list, int index) 8 | { 9 | if (index == 0) 10 | { 11 | return; 12 | } 13 | 14 | var temp = list[index - 1]; 15 | list[index - 1] = list[index]; 16 | list[index] = temp; 17 | } 18 | 19 | internal static void MoveDown(this List list, int index) 20 | { 21 | int count = list.Count; 22 | 23 | if (index == count - 1) 24 | { 25 | return; 26 | } 27 | 28 | var temp = list[index + 1]; 29 | list[index + 1] = list[index]; 30 | list[index] = temp; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Mobile46 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /DotNetUniversalPatcher/DotNetUniversalPatcher.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net461 4 | WinExe 5 | false 6 | false 7 | true 8 | true 9 | 10 | 11 | none 12 | 13 | 14 | Logo.ico 15 | 16 | 17 | LocalIntranet 18 | 19 | 20 | false 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /DotNetUniversalPatcher.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29201.188 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetUniversalPatcher", "DotNetUniversalPatcher\DotNetUniversalPatcher.csproj", "{1746C06C-60F8-4BCB-8CE6-8430D1392B2E}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {1746C06C-60F8-4BCB-8CE6-8430D1392B2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {1746C06C-60F8-4BCB-8CE6-8430D1392B2E}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {1746C06C-60F8-4BCB-8CE6-8430D1392B2E}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {1746C06C-60F8-4BCB-8CE6-8430D1392B2E}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {3449FFFD-244C-4A35-A811-2314984D8D98} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Utilities/Constants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Reflection; 4 | 5 | namespace DotNetUniversalPatcher.Utilities 6 | { 7 | internal static class Constants 8 | { 9 | internal static readonly string MainDir = AppDomain.CurrentDomain.BaseDirectory; 10 | 11 | internal static readonly string PatchersDirName = "Patchers"; 12 | internal static readonly string PatchersDir = Path.Combine(MainDir, PatchersDirName); 13 | 14 | internal static readonly string Title = Assembly.GetExecutingAssembly().GetCustomAttribute().Title; 15 | internal static readonly string Version = Assembly.GetExecutingAssembly().GetCustomAttribute().Version; 16 | 17 | internal static readonly string TitleAndVersion = $"{Title} v{Version.Substring(0, Version.IndexOf('.', 2))}"; 18 | 19 | internal static readonly string ScriptFileExtension = "dnup"; 20 | 21 | internal static readonly char DefaultSeparator = '|'; 22 | internal static readonly string RangeExpressionSeparator = "..."; 23 | internal static readonly string RangeExpressionRegexPattern = @"\.\.\."; 24 | 25 | internal static readonly string PlaceholderPattern = "(? 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmAbout)); 32 | this.btnOK = new System.Windows.Forms.Button(); 33 | this.rtbAboutText = new System.Windows.Forms.RichTextBox(); 34 | this.btnShowAboutText = new System.Windows.Forms.Button(); 35 | this.SuspendLayout(); 36 | // 37 | // btnOK 38 | // 39 | this.btnOK.DialogResult = System.Windows.Forms.DialogResult.Cancel; 40 | this.btnOK.Location = new System.Drawing.Point(302, 135); 41 | this.btnOK.Name = "btnOK"; 42 | this.btnOK.Size = new System.Drawing.Size(80, 30); 43 | this.btnOK.TabIndex = 1; 44 | this.btnOK.Text = "OK"; 45 | this.btnOK.UseVisualStyleBackColor = true; 46 | this.btnOK.Click += new System.EventHandler(this.BtnOK_Click); 47 | // 48 | // rtbAboutText 49 | // 50 | this.rtbAboutText.BackColor = System.Drawing.Color.White; 51 | this.rtbAboutText.BorderStyle = System.Windows.Forms.BorderStyle.None; 52 | this.rtbAboutText.Location = new System.Drawing.Point(12, 9); 53 | this.rtbAboutText.Name = "rtbAboutText"; 54 | this.rtbAboutText.ReadOnly = true; 55 | this.rtbAboutText.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.ForcedVertical; 56 | this.rtbAboutText.Size = new System.Drawing.Size(370, 120); 57 | this.rtbAboutText.TabIndex = 0; 58 | this.rtbAboutText.Text = ""; 59 | this.rtbAboutText.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(this.RtbAboutText_LinkClicked); 60 | // 61 | // btnShowAboutText 62 | // 63 | this.btnShowAboutText.Location = new System.Drawing.Point(12, 135); 64 | this.btnShowAboutText.Name = "btnShowAboutText"; 65 | this.btnShowAboutText.Size = new System.Drawing.Size(110, 30); 66 | this.btnShowAboutText.TabIndex = 2; 67 | this.btnShowAboutText.Text = "About DNUP"; 68 | this.btnShowAboutText.UseVisualStyleBackColor = true; 69 | this.btnShowAboutText.Visible = false; 70 | this.btnShowAboutText.Click += new System.EventHandler(this.BtnShowAboutText_Click); 71 | // 72 | // FrmAbout 73 | // 74 | this.AcceptButton = this.btnOK; 75 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; 76 | this.CancelButton = this.btnOK; 77 | this.ClientSize = new System.Drawing.Size(394, 176); 78 | this.Controls.Add(this.btnShowAboutText); 79 | this.Controls.Add(this.rtbAboutText); 80 | this.Controls.Add(this.btnOK); 81 | this.Font = new System.Drawing.Font("Segoe UI", 9.75F); 82 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 83 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 84 | this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 85 | this.MaximizeBox = false; 86 | this.MinimizeBox = false; 87 | this.Name = "FrmAbout"; 88 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 89 | this.Text = "About"; 90 | this.Load += new System.EventHandler(this.FrmAbout_Load); 91 | this.ResumeLayout(false); 92 | 93 | } 94 | 95 | #endregion 96 | private System.Windows.Forms.Button btnOK; 97 | private System.Windows.Forms.RichTextBox rtbAboutText; 98 | private System.Windows.Forms.Button btnShowAboutText; 99 | } 100 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Utilities/Helpers.cs: -------------------------------------------------------------------------------- 1 | using dnlib.DotNet.Emit; 2 | using DotNetUniversalPatcher.Exceptions; 3 | using System; 4 | using System.Diagnostics; 5 | using System.IO; 6 | using System.Reflection; 7 | using System.Security.Principal; 8 | using System.Text; 9 | using System.Text.RegularExpressions; 10 | using System.Windows.Forms; 11 | using DotNetUniversalPatcher.Properties; 12 | 13 | namespace DotNetUniversalPatcher.Utilities 14 | { 15 | internal static class Helpers 16 | { 17 | internal static bool CreatePatcherDirIfNotExists() 18 | { 19 | bool result = false; 20 | 21 | try 22 | { 23 | if (!Directory.Exists(Constants.PatchersDir)) 24 | { 25 | Directory.CreateDirectory(Constants.PatchersDir); 26 | File.WriteAllText(Path.Combine(Constants.PatchersDir, Resources.Helpers_CreatePatcherDirIfNotExists_FileName), Resources.Helpers_CreatePatcherDirIfNotExists_FileContent); 27 | 28 | result = true; 29 | } 30 | } 31 | catch 32 | { 33 | result = false; 34 | } 35 | 36 | return result; 37 | } 38 | 39 | internal static void SetDebugMode() 40 | { 41 | #if DEBUG 42 | Program.IsDebugModeEnabled = true; 43 | #else 44 | string[] args = Environment.GetCommandLineArgs(); 45 | 46 | if (args.Length == 2 && string.Equals(args[1], "/debug", StringComparison.InvariantCultureIgnoreCase)) 47 | { 48 | Program.IsDebugModeEnabled = true; 49 | } 50 | #endif 51 | } 52 | 53 | internal static bool IsAdministrator() 54 | { 55 | bool result; 56 | try 57 | { 58 | using (var current = WindowsIdentity.GetCurrent()) 59 | { 60 | result = new WindowsPrincipal(current).IsInRole(WindowsBuiltInRole.Administrator); 61 | } 62 | } 63 | catch 64 | { 65 | result = false; 66 | } 67 | return result; 68 | } 69 | 70 | internal static string BuildTitle() 71 | { 72 | StringBuilder sb = new StringBuilder(); 73 | 74 | sb.Append(Constants.TitleAndVersion); 75 | 76 | if (Program.IsDebugModeEnabled) 77 | { 78 | sb.Append(" (Debug)"); 79 | } 80 | 81 | if (Helpers.IsAdministrator()) 82 | { 83 | sb.Append(" (Administrator)"); 84 | } 85 | 86 | return sb.ToString(); 87 | } 88 | 89 | internal static string GetProgramFilesPath(bool getX86 = false) 90 | { 91 | if (!getX86 && Environment.Is64BitOperatingSystem) 92 | { 93 | return Environment.ExpandEnvironmentVariables("%ProgramW6432%"); 94 | } 95 | 96 | return Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); 97 | } 98 | 99 | internal static string GetCommonProgramFilesPath(bool getX86 = false) 100 | { 101 | if (!getX86 && Environment.Is64BitOperatingSystem) 102 | { 103 | return Environment.ExpandEnvironmentVariables("%CommonProgramW6432%"); 104 | } 105 | 106 | return Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles); 107 | } 108 | 109 | internal static OpCode GetOpCodeFromString(string name) 110 | { 111 | var opCode = (OpCode)typeof(OpCodes).GetField(name.Replace('.', '_'), BindingFlags.Public | BindingFlags.Static | BindingFlags.IgnoreCase)?.GetValue(null); 112 | 113 | if (opCode == null) 114 | { 115 | throw new PatcherException("Invalid OpCode", name); 116 | } 117 | 118 | return opCode; 119 | } 120 | 121 | internal static void VisitWebsite(string url) 122 | { 123 | try 124 | { 125 | if (string.IsNullOrWhiteSpace(url)) return; 126 | 127 | if (!Regex.IsMatch(url, "^https?://", RegexOptions.IgnoreCase)) 128 | { 129 | url = $"http://{url}"; 130 | } 131 | 132 | Process.Start(url); 133 | } 134 | catch 135 | { 136 | // ignored 137 | } 138 | } 139 | 140 | internal static DialogResult CustomMessageBox(string text, bool error = false) 141 | { 142 | if (error) 143 | { 144 | return MessageBox.Show(text, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 145 | } 146 | 147 | return MessageBox.Show(text, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); 148 | } 149 | 150 | internal static DialogResult ExceptionMessageBox(Exception ex) 151 | { 152 | return MessageBox.Show($"{ex.Message}{(Program.IsDebugModeEnabled ? $"\r\n\r\nStack Trace:\r\n{ex.StackTrace}" : string.Empty)}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 153 | } 154 | 155 | internal static void CopyTextToClipboard(string text) 156 | { 157 | try 158 | { 159 | Clipboard.SetText(text); 160 | } 161 | catch 162 | { 163 | // ignored 164 | } 165 | } 166 | } 167 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Extensions/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | using DotNetUniversalPatcher.Engine; 2 | using DotNetUniversalPatcher.Exceptions; 3 | using DotNetUniversalPatcher.Utilities; 4 | using System.Collections.Generic; 5 | using System.Globalization; 6 | using System.Text.RegularExpressions; 7 | 8 | namespace DotNetUniversalPatcher.Extensions 9 | { 10 | internal static class StringExtensions 11 | { 12 | private const string HexPrefix = "0x"; 13 | 14 | internal static string MultipleReplace(this string text) 15 | { 16 | return MultipleReplace(text, Constants.PlaceholderPattern, ScriptEngine.Placeholders); 17 | } 18 | 19 | internal static string MultipleReplace(this string text, string pattern, Dictionary replacements) 20 | { 21 | int loopLimit = 5; 22 | 23 | while (loopLimit != 0) 24 | { 25 | MatchCollection matches = Regex.Matches(text, pattern, RegexOptions.IgnoreCase); 26 | 27 | if (matches.Count > 0) 28 | { 29 | var matchedKeys = new Dictionary(); 30 | 31 | foreach (Match match in matches) 32 | { 33 | string value; 34 | 35 | if (match.Success) 36 | { 37 | value = match.Value; 38 | text = Regex.Replace(text, value, value.ToUpperInvariant()); 39 | } 40 | else 41 | { 42 | break; 43 | } 44 | 45 | if (!matchedKeys.ContainsKey(value)) 46 | { 47 | if (replacements.ContainsKey(value)) 48 | { 49 | matchedKeys.Add(value.ToUpperInvariant(), replacements[value]); 50 | } 51 | else 52 | { 53 | throw new PatcherException("Placeholder not found", value); 54 | } 55 | } 56 | } 57 | 58 | foreach (string key in matchedKeys.Keys) 59 | { 60 | text = Regex.Replace(text, $"(? -1) 36 | { 37 | btnPatch.Enabled = false; 38 | 39 | SetLogVisible(true); 40 | 41 | Logger.Log("---START PATCHING---"); 42 | Logger.Log(); 43 | 44 | Engine.Process(); 45 | 46 | Logger.Log(); 47 | Logger.Log("---PATCHING DONE---"); 48 | 49 | btnPatch.Enabled = true; 50 | } 51 | } 52 | 53 | private void BtnAbout_Click(object sender, EventArgs e) 54 | { 55 | FrmAbout.Instance.AboutScriptText = Engine.CurrentScript.PatcherOptions?.PatcherInfo.AboutText; 56 | FrmAbout.Instance.ShowDialog(); 57 | } 58 | 59 | private void BtnExit_Click(object sender, EventArgs e) 60 | { 61 | Application.Exit(); 62 | } 63 | 64 | private void TxtWebsite_MouseDoubleClick(object sender, MouseEventArgs e) 65 | { 66 | Helpers.VisitWebsite(txtWebsite.Text); 67 | } 68 | 69 | private void CmbSoftware_SelectedIndexChanged(object sender, EventArgs e) 70 | { 71 | if (cmbSoftware.SelectedIndex > -1) 72 | { 73 | Engine.ChangeScript(); 74 | 75 | txtAuthor.Text = Engine.CurrentScript.PatcherOptions.PatcherInfo.Author; 76 | txtWebsite.Text = Engine.CurrentScript.PatcherOptions.PatcherInfo.Website; 77 | 78 | txtReleaseDate.Text = Engine.CurrentScript.PatcherOptions.PatcherInfo.ReleaseDate != null ? ((DateTime)Engine.CurrentScript.PatcherOptions.PatcherInfo.ReleaseDate).ToString("d") : string.Empty; 79 | txtReleaseInfo.Text = Engine.CurrentScript.PatcherOptions.PatcherInfo.ReleaseInfo; 80 | 81 | txtTargetFiles.Clear(); 82 | txtTargetFiles.Text += string.Join(", ", Engine.CurrentScript.TargetFilesText); 83 | 84 | chkMakeBackup.Checked = Convert.ToBoolean(Engine.CurrentScript.PatcherOptions.PatcherInfo.MakeBackup); 85 | 86 | SetLogVisible(Engine.IsLoadingError, Engine.IsLoadingError); 87 | } 88 | } 89 | 90 | private void ChkMakeBackup_CheckedChanged(object sender, EventArgs e) 91 | { 92 | if (cmbSoftware.Items.Count > 0) 93 | { 94 | Engine.CurrentScript.PatcherOptions.PatcherInfo.MakeBackup = chkMakeBackup.Checked; 95 | } 96 | } 97 | 98 | private void TxtTargetFiles_MouseHover(object sender, EventArgs e) 99 | { 100 | if (tipLogItem.GetToolTip(txtTargetFiles) != Engine.CurrentScript.TargetFilesTip) 101 | { 102 | tipTargetFiles.SetToolTip(txtTargetFiles, Engine.CurrentScript.TargetFilesTip); 103 | } 104 | } 105 | 106 | private void LstLog_MouseMove(object sender, MouseEventArgs e) 107 | { 108 | int index = lstLog.IndexFromPoint(e.Location); 109 | 110 | if (index != -1) 111 | { 112 | string tip = lstLog.Items[index].ToString(); 113 | 114 | if (tipLogItem.GetToolTip(lstLog) != tip) 115 | { 116 | tipLogItem.SetToolTip(lstLog, tip); 117 | } 118 | } 119 | } 120 | 121 | private void LstLog_MouseLeave(object sender, EventArgs e) 122 | { 123 | tipLogItem.SetToolTip(lstLog, string.Empty); 124 | } 125 | 126 | private void LstLog_KeyDown(object sender, KeyEventArgs e) 127 | { 128 | if (e.Control && e.KeyCode == Keys.C && lstLog.Items.Count > 0) 129 | { 130 | Helpers.CopyTextToClipboard(lstLog.Items[lstLog.SelectedIndex].ToString()); 131 | } 132 | } 133 | 134 | private void TsmiScriptEditor_Click(object sender, EventArgs e) 135 | { 136 | FrmScriptEditor.Instance.ShowDialog(); 137 | } 138 | 139 | private void TsmiRefresh_Click(object sender, EventArgs e) 140 | { 141 | RefreshScripts(); 142 | } 143 | 144 | private void TsmiAbout_Click(object sender, EventArgs e) 145 | { 146 | FrmAbout.Instance.AboutScriptText = null; 147 | FrmAbout.Instance.ShowDialog(); 148 | } 149 | 150 | private void RefreshScripts() 151 | { 152 | Engine.LoadedScripts = new List(); 153 | Engine.CurrentScript = new PatcherScript(); 154 | 155 | Engine.LoadAndParseScripts(); 156 | 157 | cmbSoftware.Items.Clear(); 158 | 159 | cmbSoftware.Items.AddRange(Engine.GetSoftwareNames()); 160 | 161 | if (cmbSoftware.Items.Count > 0) 162 | { 163 | cmbSoftware.SelectedIndex = 0; 164 | } 165 | else 166 | { 167 | SetLogVisible(Engine.IsLoadingError, Engine.IsLoadingError); 168 | } 169 | } 170 | 171 | private void SetLogVisible(bool trueOrFalse, bool error = false) 172 | { 173 | if (error && lstLog.Items.Count > 0) 174 | { 175 | Engine.IsLoadingError = false; 176 | } 177 | else 178 | { 179 | Logger.ClearLogs(); 180 | } 181 | 182 | if (trueOrFalse) 183 | { 184 | grpReleaseInfo.Text = Resources.FrmMain_SetLogVisible_Log_Text; 185 | lstLog.Visible = true; 186 | } 187 | else 188 | { 189 | grpReleaseInfo.Text = Resources.FrmMain_Release_Info_Text; 190 | lstLog.Visible = false; 191 | } 192 | } 193 | } 194 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015/2017 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # Visual Studio 2017 auto generated files 33 | Generated\ Files/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | **/Properties/launchSettings.json 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_i.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *.log 81 | *.vspscc 82 | *.vssscc 83 | .builds 84 | *.pidb 85 | *.svclog 86 | *.scc 87 | 88 | # Chutzpah Test files 89 | _Chutzpah* 90 | 91 | # Visual C++ cache files 92 | ipch/ 93 | *.aps 94 | *.ncb 95 | *.opendb 96 | *.opensdf 97 | *.sdf 98 | *.cachefile 99 | *.VC.db 100 | *.VC.VC.opendb 101 | 102 | # Visual Studio profiler 103 | *.psess 104 | *.vsp 105 | *.vspx 106 | *.sap 107 | 108 | # Visual Studio Trace Files 109 | *.e2e 110 | 111 | # TFS 2012 Local Workspace 112 | $tf/ 113 | 114 | # Guidance Automation Toolkit 115 | *.gpState 116 | 117 | # ReSharper is a .NET coding add-in 118 | _ReSharper*/ 119 | *.[Rr]e[Ss]harper 120 | *.DotSettings.user 121 | 122 | # JustCode is a .NET coding add-in 123 | .JustCode 124 | 125 | # TeamCity is a build add-in 126 | _TeamCity* 127 | 128 | # DotCover is a Code Coverage Tool 129 | *.dotCover 130 | 131 | # AxoCover is a Code Coverage Tool 132 | .axoCover/* 133 | !.axoCover/settings.json 134 | 135 | # Visual Studio code coverage results 136 | *.coverage 137 | *.coveragexml 138 | 139 | # NCrunch 140 | _NCrunch_* 141 | .*crunch*.local.xml 142 | nCrunchTemp_* 143 | 144 | # MightyMoose 145 | *.mm.* 146 | AutoTest.Net/ 147 | 148 | # Web workbench (sass) 149 | .sass-cache/ 150 | 151 | # Installshield output folder 152 | [Ee]xpress/ 153 | 154 | # DocProject is a documentation generator add-in 155 | DocProject/buildhelp/ 156 | DocProject/Help/*.HxT 157 | DocProject/Help/*.HxC 158 | DocProject/Help/*.hhc 159 | DocProject/Help/*.hhk 160 | DocProject/Help/*.hhp 161 | DocProject/Help/Html2 162 | DocProject/Help/html 163 | 164 | # Click-Once directory 165 | publish/ 166 | 167 | # Publish Web Output 168 | *.[Pp]ublish.xml 169 | *.azurePubxml 170 | # Note: Comment the next line if you want to checkin your web deploy settings, 171 | # but database connection strings (with potential passwords) will be unencrypted 172 | *.pubxml 173 | *.publishproj 174 | 175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 176 | # checkin your Azure Web App publish settings, but sensitive information contained 177 | # in these scripts will be unencrypted 178 | PublishScripts/ 179 | 180 | # NuGet Packages 181 | *.nupkg 182 | # The packages folder can be ignored because of Package Restore 183 | **/[Pp]ackages/* 184 | # except build/, which is used as an MSBuild target. 185 | !**/[Pp]ackages/build/ 186 | # Uncomment if necessary however generally it will be regenerated when needed 187 | #!**/[Pp]ackages/repositories.config 188 | # NuGet v3's project.json files produces more ignorable files 189 | *.nuget.props 190 | *.nuget.targets 191 | 192 | # Microsoft Azure Build Output 193 | csx/ 194 | *.build.csdef 195 | 196 | # Microsoft Azure Emulator 197 | ecf/ 198 | rcf/ 199 | 200 | # Windows Store app package directories and files 201 | AppPackages/ 202 | BundleArtifacts/ 203 | Package.StoreAssociation.xml 204 | _pkginfo.txt 205 | *.appx 206 | 207 | # Visual Studio cache files 208 | # files ending in .cache can be ignored 209 | *.[Cc]ache 210 | # but keep track of directories ending in .cache 211 | !*.[Cc]ache/ 212 | 213 | # Others 214 | ClientBin/ 215 | ~$* 216 | *~ 217 | *.dbmdl 218 | *.dbproj.schemaview 219 | *.jfm 220 | *.pfx 221 | *.publishsettings 222 | orleans.codegen.cs 223 | 224 | # Including strong name files can present a security risk 225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 226 | #*.snk 227 | 228 | # Since there are multiple workflows, uncomment next line to ignore bower_components 229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 230 | #bower_components/ 231 | 232 | # RIA/Silverlight projects 233 | Generated_Code/ 234 | 235 | # Backup & report files from converting an old project file 236 | # to a newer Visual Studio version. Backup files are not needed, 237 | # because we have git ;-) 238 | _UpgradeReport_Files/ 239 | Backup*/ 240 | UpgradeLog*.XML 241 | UpgradeLog*.htm 242 | ServiceFabricBackup/ 243 | *.rptproj.bak 244 | 245 | # SQL Server files 246 | *.mdf 247 | *.ldf 248 | *.ndf 249 | 250 | # Business Intelligence projects 251 | *.rdl.data 252 | *.bim.layout 253 | *.bim_*.settings 254 | *.rptproj.rsuser 255 | 256 | # Microsoft Fakes 257 | FakesAssemblies/ 258 | 259 | # GhostDoc plugin setting file 260 | *.GhostDoc.xml 261 | 262 | # Node.js Tools for Visual Studio 263 | .ntvs_analysis.dat 264 | node_modules/ 265 | 266 | # Visual Studio 6 build log 267 | *.plg 268 | 269 | # Visual Studio 6 workspace options file 270 | *.opt 271 | 272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 273 | *.vbw 274 | 275 | # Visual Studio LightSwitch build output 276 | **/*.HTMLClient/GeneratedArtifacts 277 | **/*.DesktopClient/GeneratedArtifacts 278 | **/*.DesktopClient/ModelManifest.xml 279 | **/*.Server/GeneratedArtifacts 280 | **/*.Server/ModelManifest.xml 281 | _Pvt_Extensions 282 | 283 | # Paket dependency manager 284 | .paket/paket.exe 285 | paket-files/ 286 | 287 | # FAKE - F# Make 288 | .fake/ 289 | 290 | # JetBrains Rider 291 | .idea/ 292 | *.sln.iml 293 | 294 | # CodeRush 295 | .cr/ 296 | 297 | # Python Tools for Visual Studio (PTVS) 298 | __pycache__/ 299 | *.pyc 300 | 301 | # Cake - Uncomment if you are using it 302 | # tools/** 303 | # !tools/packages.config 304 | 305 | # Tabs Studio 306 | *.tss 307 | 308 | # Telerik's JustMock configuration file 309 | *.jmconfig 310 | 311 | # BizTalk build output 312 | *.btp.cs 313 | *.btm.cs 314 | *.odx.cs 315 | *.xsd.cs 316 | 317 | # OpenCover UI analysis results 318 | OpenCover/ 319 | 320 | # Azure Stream Analytics local run output 321 | ASALocalRun/ 322 | 323 | # MSBuild Binary and Structured Log 324 | *.binlog 325 | 326 | # NVidia Nsight GPU debugger configuration file 327 | *.nvuser 328 | 329 | # MFractors (Xamarin productivity tool) working folder 330 | .mfractor/ 331 | *.DotSettings 332 | -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Engine/ScriptEngine.cs: -------------------------------------------------------------------------------- 1 | using dnlib.DotNet; 2 | using DotNetUniversalPatcher.Models; 3 | using DotNetUniversalPatcher.UI; 4 | using DotNetUniversalPatcher.Utilities; 5 | using Newtonsoft.Json; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.IO; 9 | using System.Linq; 10 | using System.Windows.Forms; 11 | using DotNetUniversalPatcher.Properties; 12 | 13 | namespace DotNetUniversalPatcher.Engine 14 | { 15 | internal class ScriptEngine : ScriptEngineBase 16 | { 17 | internal static Dictionary Placeholders { get; set; } = new Dictionary(StringComparer.InvariantCultureIgnoreCase); 18 | 19 | public override string[] GetSoftwareNames() 20 | { 21 | string[] softwareNames = new string[LoadedScripts.Count]; 22 | 23 | for (int i = 0; i < LoadedScripts.Count; i++) 24 | { 25 | softwareNames[i] = LoadedScripts[i].PatcherOptions.PatcherInfo.Software; 26 | } 27 | 28 | return softwareNames; 29 | } 30 | 31 | public override void LoadAndParseScripts() 32 | { 33 | try 34 | { 35 | Logger.ClearLogs(); 36 | 37 | string[] scriptFiles = Directory.GetFiles(Constants.PatchersDir, Constants.ScriptFilePattern, SearchOption.TopDirectoryOnly).Select(Path.GetFullPath).ToArray(); 38 | 39 | foreach (string file in scriptFiles) 40 | { 41 | try 42 | { 43 | var script = JsonConvert.DeserializeObject(File.ReadAllText(file), new JsonSerializerSettings 44 | { 45 | DefaultValueHandling = DefaultValueHandling.Ignore, 46 | NullValueHandling = NullValueHandling.Ignore, 47 | DateFormatString = "dd.MM.yyyy" 48 | }); 49 | 50 | if (ScriptEngineHelpers.ValidateScript(script)) 51 | { 52 | ScriptEngineHelpers.AddPlaceholders(script); 53 | ScriptEngineHelpers.ParsePlaceholders(script); 54 | ScriptEngineHelpers.AddTargetFilesText(script); 55 | 56 | LoadedScripts.Add(script); 57 | } 58 | } 59 | catch (Exception ex) 60 | { 61 | Logger.Error(string.Format(Resources.ScriptEngine_LoadAndParseScripts_Exception_Msg, 62 | Path.GetFileName(file), Program.IsDebugModeEnabled ? "\r\n" : string.Empty, ex.Message, 63 | Program.IsDebugModeEnabled ? string.Format("\r\n{0}", ex.StackTrace) : string.Empty)); 64 | IsLoadingError = true; 65 | FrmMain.Instance.grpReleaseInfo.Enabled = true; 66 | } 67 | } 68 | } 69 | catch (DirectoryNotFoundException ex) 70 | { 71 | Logger.Error(string.Format(Resources.ScriptEngine_LoadAndParseScripts__DirectoryNotFoundException_Msg, 72 | Program.IsDebugModeEnabled ? "\r\n" : string.Empty, ex.Message, 73 | Program.IsDebugModeEnabled ? string.Format("\r\n{0}", ex.StackTrace) : string.Empty)); 74 | IsLoadingError = true; 75 | FrmMain.Instance.grpReleaseInfo.Enabled = true; 76 | } 77 | catch 78 | { 79 | // ignored 80 | } 81 | 82 | if (LoadedScripts.Count > 0) 83 | { 84 | FrmMain.Instance.grpPatcherInfo.Enabled = true; 85 | FrmMain.Instance.grpReleaseInfo.Enabled = true; 86 | FrmMain.Instance.txtReleaseInfo.Enabled = true; 87 | FrmMain.Instance.chkMakeBackup.Enabled = true; 88 | FrmMain.Instance.btnPatch.Enabled = true; 89 | } 90 | else 91 | { 92 | FrmMain.Instance.grpPatcherInfo.Enabled = false; 93 | FrmMain.Instance.txtReleaseInfo.Enabled = false; 94 | FrmMain.Instance.chkMakeBackup.Enabled = false; 95 | FrmMain.Instance.btnPatch.Enabled = false; 96 | 97 | FrmMain.Instance.txtTargetFiles.Clear(); 98 | FrmMain.Instance.txtAuthor.Clear(); 99 | FrmMain.Instance.txtWebsite.Clear(); 100 | FrmMain.Instance.txtReleaseDate.Clear(); 101 | FrmMain.Instance.txtReleaseInfo.Clear(); 102 | 103 | FrmMain.Instance.chkMakeBackup.Checked = false; 104 | 105 | RefreshTargetFilesText(); 106 | } 107 | } 108 | 109 | public override void ChangeScript() 110 | { 111 | CurrentScript = LoadedScripts[FrmMain.Instance.cmbSoftware.SelectedIndex]; 112 | 113 | RefreshTargetFilesText(); 114 | } 115 | 116 | public override void Process() 117 | { 118 | int patchedFileCount = 0; 119 | 120 | try 121 | { 122 | foreach (var patch in CurrentScript.PatchList) 123 | { 124 | foreach (string path in patch.TargetInfo.TargetFiles) 125 | { 126 | string filePath = path; 127 | 128 | if (!File.Exists(filePath)) 129 | { 130 | Logger.Error(string.Format(Resources.ScriptEngine_Process_File_not_found_Msg, filePath)); 131 | 132 | using (var ofd = new OpenFileDialog()) 133 | { 134 | ofd.FileName = Path.GetFileName(filePath); 135 | ofd.Filter = Resources.ScriptEngine_Process_Filter_ExtName; 136 | ofd.CheckFileExists = true; 137 | 138 | string directoryName = Path.GetDirectoryName(filePath); 139 | 140 | if (Directory.Exists(directoryName)) 141 | { 142 | ofd.InitialDirectory = directoryName; 143 | } 144 | else 145 | { 146 | ofd.RestoreDirectory = true; 147 | } 148 | 149 | if (ofd.ShowDialog() == DialogResult.OK) 150 | { 151 | filePath = ofd.FileName; 152 | } 153 | else 154 | { 155 | Logger.Log(Resources.ScriptEngine_Process__Skipping_file_Msg); 156 | Logger.Log(); 157 | continue; 158 | } 159 | } 160 | } 161 | 162 | bool keepOldMaxStack = patch.TargetInfo.KeepOldMaxStack; 163 | 164 | using (var p = new Patcher(filePath, keepOldMaxStack)) 165 | { 166 | Logger.Log(string.Format(Resources.ScriptEngine_Process__File_Path_Msg, filePath, 167 | keepOldMaxStack ? "-> KeepOldMaxStack: True" : string.Empty)); 168 | 169 | foreach (var target in patch.TargetList) 170 | { 171 | ProcessInternal(p, target); 172 | } 173 | 174 | p.Save(Convert.ToBoolean(CurrentScript.PatcherOptions.PatcherInfo.MakeBackup)); 175 | } 176 | 177 | patchedFileCount++; 178 | 179 | Logger.Log(string.Format(Resources.ScriptEngine_Process__File_Patched_Msg, filePath)); 180 | Logger.Log(); 181 | } 182 | 183 | Logger.Log(); 184 | } 185 | } 186 | catch (Exception ex) 187 | { 188 | Logger.Error(string.Format("{0}{1}", ex.Message, 189 | Program.IsDebugModeEnabled ? string.Format("\r\n{0}", ex.StackTrace) : string.Empty)); 190 | Logger.Log(); 191 | } 192 | 193 | Logger.Info(patchedFileCount > 0 ? string.Format(Resources.ScriptEngine_Process_Patching_process_finished_Msg, 194 | patchedFileCount) 195 | : Resources.ScriptEngine_Process_Nothing_patched_Msg); 196 | } 197 | 198 | internal void ProcessInternal(Patcher p, Target target) 199 | { 200 | p.Method = p.FindMethod(target.FullName).ResolveMethodDef(); 201 | p.Instructions = p.Method.Body.Instructions; 202 | 203 | if (target.ILCodes != null && target.ILCodes.Count > 0) 204 | { 205 | ScriptEngineHelpers.ParseILCodes(p, target); 206 | } 207 | 208 | ScriptEngineHelpers.PatchTarget(p, target); 209 | 210 | ScriptEngineHelpers.WriteActionToLog(target); 211 | } 212 | 213 | private void RefreshTargetFilesText() 214 | { 215 | FrmMain.Instance.lblTargetFiles.Text = string.Format(Resources.FrmMain_Target_Files_Text, CurrentScript.TargetFilesCount); 216 | } 217 | } 218 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/UI/FrmPatcherOptions.cs: -------------------------------------------------------------------------------- 1 | using DotNetUniversalPatcher.Engine; 2 | using DotNetUniversalPatcher.Extensions; 3 | using DotNetUniversalPatcher.Models; 4 | using DotNetUniversalPatcher.Utilities; 5 | using System; 6 | using System.Windows.Forms; 7 | using DotNetUniversalPatcher.Properties; 8 | 9 | namespace DotNetUniversalPatcher.UI 10 | { 11 | public partial class FrmPatcherOptions : Form 12 | { 13 | internal static FrmPatcherOptions Instance { get; } = new FrmPatcherOptions(); 14 | 15 | private int _selectedPlaceholderIndex; 16 | 17 | public FrmPatcherOptions() 18 | { 19 | InitializeComponent(); 20 | } 21 | 22 | private void FrmPatcherOptions_Load(object sender, EventArgs e) 23 | { 24 | tabPatcherOptions.SelectedTab = tpPatcherOptions; 25 | 26 | var patcherInfo = FrmScriptEditor.Instance.Script.PatcherOptions.PatcherInfo; 27 | 28 | if (patcherInfo != null) 29 | { 30 | txtSoftwareName.Text = patcherInfo.Software; 31 | txtAuthor.Text = patcherInfo.Author; 32 | txtWebsite.Text = patcherInfo.Website; 33 | 34 | dtpReleaseDate.Value = patcherInfo.ReleaseDate != null ? Convert.ToDateTime(patcherInfo.ReleaseDate) : DateTime.Now; 35 | 36 | txtReleaseInfo.Text = patcherInfo.ReleaseInfo; 37 | txtAboutText.Text = patcherInfo.AboutText; 38 | chkMakeBackup.Checked = Convert.ToBoolean(patcherInfo.MakeBackup); 39 | } 40 | 41 | dgvPlaceholders.Rows.Clear(); 42 | 43 | var placeholders = FrmScriptEditor.Instance.Script.PatcherOptions.Placeholders; 44 | 45 | if (placeholders != null) 46 | { 47 | foreach (var placeholder in placeholders) 48 | { 49 | dgvPlaceholders.Rows.Add(placeholder.Key, placeholder.Value); 50 | } 51 | } 52 | 53 | if (dgvReservedPlaceholders.Rows.Count == 0) 54 | { 55 | foreach (var placeholder in ScriptEngineHelpers.ReservedPlaceholders) 56 | { 57 | dgvReservedPlaceholders.Rows.Add(placeholder.Key, placeholder.Value); 58 | } 59 | } 60 | 61 | txtPlaceholderKey.Text = string.Empty; 62 | txtPlaceholderValue.Text = string.Empty; 63 | 64 | btnAddPlaceholder.Text = Resources.FrmPatcherOptions_Add_Text; 65 | _selectedPlaceholderIndex = -1; 66 | } 67 | 68 | private void BtnVisit_Click(object sender, EventArgs e) 69 | { 70 | Helpers.VisitWebsite(txtWebsite.Text); 71 | } 72 | 73 | private void BtnToday_Click(object sender, EventArgs e) 74 | { 75 | dtpReleaseDate.Value = DateTime.Today; 76 | } 77 | 78 | private void BtnAddPlaceholder_Click(object sender, EventArgs e) 79 | { 80 | if (string.IsNullOrWhiteSpace(txtPlaceholderKey.Text)) 81 | { 82 | Helpers.CustomMessageBox(Resources.FrmPatcherOptions_BtnAddPlaceholder_Placeholder_Key_is_empty_Msg); 83 | return; 84 | } 85 | 86 | if (string.IsNullOrWhiteSpace(txtPlaceholderValue.Text)) 87 | { 88 | Helpers.CustomMessageBox(Resources.FrmPatcherOptions_BtnAddPlaceholder_Placeholder_Value_is_empty_Msg); 89 | return; 90 | } 91 | 92 | if (btnAddPlaceholder.Text == Resources.FrmPatcherOptions_Add_Text) 93 | { 94 | dgvPlaceholders.Rows.Add(txtPlaceholderKey.Text.EmptyIfNull(), txtPlaceholderValue.Text.EmptyIfNull()); 95 | } 96 | else if (btnAddPlaceholder.Text == Resources.FrmPatcherOptions_BtnAddPlaceholder_Update_Text) 97 | { 98 | dgvPlaceholders.Rows[_selectedPlaceholderIndex].Cells[0].Value = txtPlaceholderKey.Text.EmptyIfNull(); 99 | dgvPlaceholders.Rows[_selectedPlaceholderIndex].Cells[1].Value = txtPlaceholderValue.Text.EmptyIfNull(); 100 | 101 | _selectedPlaceholderIndex = -1; 102 | 103 | btnAddPlaceholder.Text = Resources.FrmPatcherOptions_Add_Text; 104 | } 105 | } 106 | 107 | private void BtnClear_Click(object sender, EventArgs e) 108 | { 109 | if (txtPlaceholderKey.TextLength > 0 || txtPlaceholderValue.TextLength > 0) 110 | { 111 | txtPlaceholderKey.Text = string.Empty; 112 | txtPlaceholderValue.Text = string.Empty; 113 | } 114 | } 115 | 116 | private void BtnCancel_Click(object sender, EventArgs e) 117 | { 118 | Close(); 119 | } 120 | 121 | private void BtnSave_Click(object sender, EventArgs e) 122 | { 123 | if (string.IsNullOrWhiteSpace(txtSoftwareName.Text)) 124 | { 125 | Helpers.CustomMessageBox(Resources.FrmPatcherOptions_BtnSave_Software_Name_is_empty_Msg); 126 | 127 | if (tabPatcherOptions.SelectedIndex != 0) 128 | { 129 | tabPatcherOptions.SelectedTab = tpPatcherOptions; 130 | } 131 | 132 | txtSoftwareName.Focus(); 133 | return; 134 | } 135 | 136 | FrmScriptEditor.Instance.Script.PatcherOptions = new PatcherOptions 137 | { 138 | PatcherInfo = new PatcherInfo 139 | { 140 | Software = txtSoftwareName.Text, 141 | Author = txtAuthor.Text, 142 | Website = txtWebsite.Text, 143 | ReleaseDate = dtpReleaseDate.Value, 144 | ReleaseInfo = txtReleaseInfo.Text, 145 | AboutText = txtAboutText.Text, 146 | MakeBackup = chkMakeBackup.Checked 147 | } 148 | }; 149 | 150 | FrmScriptEditor.Instance.Script.PatcherOptions.Placeholders.Clear(); 151 | 152 | foreach (DataGridViewRow dgvr in dgvPlaceholders.Rows) 153 | { 154 | string key = dgvr.Cells[0].Value?.ToString().Replace("#", string.Empty); 155 | 156 | if (!FrmScriptEditor.Instance.Script.PatcherOptions.Placeholders.ContainsKey(key)) 157 | { 158 | FrmScriptEditor.Instance.Script.PatcherOptions.Placeholders.Add(key, dgvr.Cells[1].Value?.ToString()); 159 | } 160 | else 161 | { 162 | Helpers.CustomMessageBox(string.Format(Resources.FrmPatcherOptions_BtnSave_Placeholder_already_exists_Msg, key)); 163 | 164 | if (tabPatcherOptions.SelectedIndex != 1) 165 | { 166 | tabPatcherOptions.SelectedTab = tpPlaceholders; 167 | } 168 | 169 | FrmScriptEditor.Instance.Script.PatcherOptions.Placeholders.Clear(); 170 | return; 171 | } 172 | } 173 | 174 | FrmScriptEditor.Instance.CheckChanges(); 175 | 176 | Helpers.CustomMessageBox(Resources.FrmPatcherOptions_BtnSave_Patcher_Options_are_successfully_saved_Msg); 177 | } 178 | 179 | private void TsmiEditPlaceholder_Click(object sender, EventArgs e) 180 | { 181 | if (dgvPlaceholders.SelectedRows.Count > 0) 182 | { 183 | _selectedPlaceholderIndex = dgvPlaceholders.SelectedRows[0].Index; 184 | 185 | txtPlaceholderKey.Text = dgvPlaceholders.Rows[_selectedPlaceholderIndex].Cells[0].Value?.ToString().EmptyIfNull(); 186 | txtPlaceholderValue.Text = dgvPlaceholders.Rows[_selectedPlaceholderIndex].Cells[1].Value?.ToString().EmptyIfNull(); 187 | 188 | btnAddPlaceholder.Text = Resources.FrmPatcherOptions_BtnAddPlaceholder_Update_Text; 189 | } 190 | } 191 | 192 | private void TsmiRemovePlaceholder_Click(object sender, EventArgs e) 193 | { 194 | if (dgvPlaceholders.SelectedRows.Count > 0) 195 | { 196 | dgvPlaceholders.Rows.RemoveAt(dgvPlaceholders.SelectedRows[0].Index); 197 | 198 | if (btnAddPlaceholder.Text == Resources.FrmPatcherOptions_BtnAddPlaceholder_Update_Text) 199 | { 200 | btnAddPlaceholder.Text = Resources.FrmPatcherOptions_Add_Text; 201 | _selectedPlaceholderIndex = -1; 202 | } 203 | } 204 | } 205 | 206 | private void TsmiMoveUpPlaceholder_Click(object sender, EventArgs e) 207 | { 208 | if (dgvPlaceholders.SelectedRows.Count > 0) 209 | { 210 | dgvPlaceholders.MoveUp(); 211 | 212 | ResetAddPlaceholder(); 213 | } 214 | } 215 | 216 | private void TsmiMoveDownPlaceholder_Click(object sender, EventArgs e) 217 | { 218 | if (dgvPlaceholders.SelectedRows.Count > 0) 219 | { 220 | dgvPlaceholders.MoveDown(); 221 | 222 | ResetAddPlaceholder(); 223 | } 224 | } 225 | 226 | private void ResetAddPlaceholder() 227 | { 228 | if (btnAddPlaceholder.Text == Resources.FrmPatcherOptions_BtnAddPlaceholder_Update_Text) 229 | { 230 | btnAddPlaceholder.Text = Resources.FrmPatcherOptions_Add_Text; 231 | _selectedPlaceholderIndex = -1; 232 | } 233 | } 234 | 235 | private void DgvReservedPlaceholders_MouseDoubleClick(object sender, MouseEventArgs e) 236 | { 237 | Helpers.CopyTextToClipboard(dgvReservedPlaceholders.SelectedRows[0].Cells[0].Value.ToString()); 238 | } 239 | } 240 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/UI/FrmAddTarget.cs: -------------------------------------------------------------------------------- 1 | using dnlib.DotNet.Emit; 2 | using DotNetUniversalPatcher.Extensions; 3 | using DotNetUniversalPatcher.Models; 4 | using DotNetUniversalPatcher.Utilities; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Reflection; 9 | using System.Windows.Forms; 10 | using DotNetUniversalPatcher.Properties; 11 | 12 | namespace DotNetUniversalPatcher.UI 13 | { 14 | public partial class FrmAddTarget : Form 15 | { 16 | internal static FrmAddTarget Instance { get; } = new FrmAddTarget(); 17 | 18 | private static List _opCodes; 19 | 20 | private int _selectedActionMethod; 21 | private int _selectedInstructionIndex; 22 | private OpCode _selectedOpCode; 23 | 24 | internal int SelectedTargetId; 25 | 26 | public FrmAddTarget() 27 | { 28 | InitializeComponent(); 29 | } 30 | 31 | private void FrmAddTarget_Load(object sender, EventArgs e) 32 | { 33 | if (cmbActionMethod.Items.Count == 0) 34 | { 35 | foreach (var action in Enum.GetNames(typeof(ActionMethod))) 36 | { 37 | cmbActionMethod.Items.Add(action); 38 | } 39 | } 40 | 41 | if (cmbOpCodes.Items.Count == 0) 42 | { 43 | LoadOpCodes(); 44 | cmbOpCodes.Items.AddRange(_opCodes.ToArray()); 45 | } 46 | 47 | txtFullName.Text = string.Empty; 48 | cmbActionMethod.SelectedIndex = -1; 49 | cmbOptional.SelectedIndex = -1; 50 | 51 | ClearControls(); 52 | 53 | if (dgvInstructions.Rows.Count > 0) 54 | { 55 | dgvInstructions.Rows.Clear(); 56 | } 57 | 58 | btnAddTarget.Text = Resources.FrmAddTarget_TsmiRemoveInstruction_AddTarget_Text; 59 | 60 | if (Text == Resources.FrmAddTarget_Edit_Target_Text) 61 | { 62 | var selectedPatchIndex = FrmScriptEditor.Instance.cmbPatchList.SelectedIndex; 63 | 64 | var target = FrmScriptEditor.Instance.PatchList[selectedPatchIndex].TargetList[SelectedTargetId]; 65 | 66 | txtFullName.Text = target.FullName; 67 | 68 | if (target.Action != null) 69 | { 70 | cmbActionMethod.SelectedIndex = (int)target.Action; 71 | } 72 | else 73 | { 74 | cmbActionMethod.SelectedIndex = -1; 75 | } 76 | 77 | switch (target.Optional?.ToLowerInvariant()) 78 | { 79 | case "true": 80 | cmbOptional.SelectedIndex = 0; 81 | break; 82 | 83 | case "false": 84 | cmbOptional.SelectedIndex = 1; 85 | break; 86 | 87 | default: 88 | cmbOptional.SelectedIndex = -1; 89 | break; 90 | } 91 | 92 | for (var i = 0; i < target.ILCodes?.Count; i++) 93 | { 94 | var ilCode = target.ILCodes?[i]; 95 | 96 | dgvInstructions.Rows.Add(target.Indices?.Count > 0 ? target.Indices[i] : string.Empty, ilCode.OpCode, ilCode.Operand); 97 | } 98 | } 99 | } 100 | 101 | private void BtnAddTarget_Click(object sender, EventArgs e) 102 | { 103 | if (_selectedActionMethod == -1) 104 | { 105 | Helpers.CustomMessageBox("Action Method is empty!"); 106 | cmbActionMethod.Focus(); 107 | return; 108 | } 109 | 110 | switch (_selectedActionMethod) 111 | { 112 | case (int)ActionMethod.Insert: 113 | case (int)ActionMethod.Replace: 114 | case (int)ActionMethod.Remove: 115 | { 116 | if (string.IsNullOrWhiteSpace(txtIndex.Text)) 117 | { 118 | Helpers.CustomMessageBox("Index is empty!"); 119 | txtIndex.Focus(); 120 | return; 121 | } 122 | 123 | break; 124 | } 125 | } 126 | 127 | switch (_selectedActionMethod) 128 | { 129 | case (int)ActionMethod.Patch: 130 | case (int)ActionMethod.Insert: 131 | case (int)ActionMethod.Replace: 132 | { 133 | if (cmbOpCodes.SelectedIndex == -1) 134 | { 135 | Helpers.CustomMessageBox("OpCode is empty!"); 136 | cmbOpCodes.Focus(); 137 | return; 138 | } 139 | 140 | break; 141 | } 142 | } 143 | 144 | if (btnAddTarget.Text == Resources.FrmAddTarget_TsmiRemoveInstruction_AddTarget_Text) 145 | { 146 | string[] cells = new string[3]; 147 | 148 | cells[0] = txtIndex.Text.EmptyIfNull(); 149 | cells[1] = cmbOpCodes.Text.EmptyIfNull(); 150 | 151 | if (_selectedOpCode != null) 152 | { 153 | switch (_selectedOpCode.OperandType) 154 | { 155 | case OperandType.InlineNone: 156 | case OperandType.InlinePhi: 157 | case OperandType.NOT_USED_8: 158 | cells[2] = string.Empty; 159 | break; 160 | 161 | default: 162 | cells[2] = txtOperand.Text.EmptyIfNull(); 163 | break; 164 | } 165 | } 166 | 167 | dgvInstructions.Rows.Add(cells); 168 | } 169 | else if (btnAddTarget.Text == Resources.FrmAddTarget_TsmiEditInstruction_Update_Text) 170 | { 171 | dgvInstructions.Rows[_selectedInstructionIndex].Cells[0].Value = txtIndex.Text.EmptyIfNull(); 172 | dgvInstructions.Rows[_selectedInstructionIndex].Cells[1].Value = cmbOpCodes.Text.EmptyIfNull(); 173 | 174 | if (_selectedOpCode != null) 175 | { 176 | switch (_selectedOpCode.OperandType) 177 | { 178 | case OperandType.InlineNone: 179 | case OperandType.InlinePhi: 180 | case OperandType.NOT_USED_8: 181 | dgvInstructions.Rows[_selectedInstructionIndex].Cells[2].Value = string.Empty; 182 | break; 183 | 184 | default: 185 | dgvInstructions.Rows[_selectedInstructionIndex].Cells[2].Value = txtOperand.Text.EmptyIfNull(); 186 | break; 187 | } 188 | } 189 | 190 | btnAddTarget.Text = Resources.FrmAddTarget_TsmiRemoveInstruction_AddTarget_Text; 191 | } 192 | } 193 | 194 | private void BtnClear_Click(object sender, EventArgs e) 195 | { 196 | if (txtIndex.TextLength > 0 || cmbOpCodes.SelectedIndex != -1 || txtOperand.TextLength > 0) 197 | { 198 | ClearControls(); 199 | } 200 | } 201 | 202 | private void BtnCancel_Click(object sender, EventArgs e) 203 | { 204 | Close(); 205 | } 206 | 207 | private void BtnSave_Click(object sender, EventArgs e) 208 | { 209 | if (string.IsNullOrWhiteSpace(txtFullName.Text)) 210 | { 211 | Helpers.CustomMessageBox("Full Name is empty!"); 212 | txtFullName.Focus(); 213 | return; 214 | } 215 | 216 | if (_selectedActionMethod == (int)ActionMethod.ReturnBody && cmbOptional.SelectedIndex == -1) 217 | { 218 | Helpers.CustomMessageBox("Optional is empty!"); 219 | cmbOptional.Focus(); 220 | return; 221 | } 222 | 223 | var selectedPatchIndex = FrmScriptEditor.Instance.cmbPatchList.SelectedIndex; 224 | 225 | List ilCodes = new List(); 226 | List indices = new List(); 227 | 228 | foreach (DataGridViewRow dgvInstructionsRow in dgvInstructions.Rows) 229 | { 230 | indices.Add(dgvInstructionsRow.Cells[0].Value?.ToString().EmptyIfNull()); 231 | ilCodes.Add(new ILCode { OpCode = dgvInstructionsRow.Cells[1].Value?.ToString().EmptyIfNull(), Operand = dgvInstructionsRow.Cells[2].Value?.ToString().EmptyIfNull() }); 232 | } 233 | 234 | if (btnSave.Text == Resources.FrmAddTarget_Save_Text) 235 | { 236 | FrmScriptEditor.Instance.PatchList[selectedPatchIndex].TargetList.Add(new Target 237 | { 238 | FullName = txtFullName.Text, 239 | Action = (ActionMethod)cmbActionMethod.SelectedIndex, 240 | Optional = cmbOptional.Text, 241 | ILCodes = ilCodes, 242 | Indices = indices 243 | }); 244 | 245 | FrmScriptEditor.Instance.dgvTargetList.Rows.Add($"[{cmbActionMethod.Text}]", txtFullName.Text); 246 | 247 | SelectedTargetId = FrmScriptEditor.Instance.PatchList[selectedPatchIndex].TargetList.Count - 1; 248 | 249 | btnSave.Text = Resources.FrmAddTarget_BtnSave_Update_Text; 250 | } 251 | else if (btnSave.Text == Resources.FrmAddTarget_BtnSave_Update_Text) 252 | { 253 | var selectedTarget = FrmScriptEditor.Instance.PatchList[selectedPatchIndex].TargetList[SelectedTargetId]; 254 | 255 | selectedTarget.FullName = txtFullName.Text; 256 | selectedTarget.Action = (ActionMethod)cmbActionMethod.SelectedIndex; 257 | selectedTarget.Optional = cmbOptional.Text; 258 | selectedTarget.ILCodes = ilCodes; 259 | selectedTarget.Indices = indices; 260 | 261 | FrmScriptEditor.Instance.dgvTargetList.Rows[SelectedTargetId].Cells[0].Value = $"[{cmbActionMethod.Text}]"; 262 | FrmScriptEditor.Instance.dgvTargetList.Rows[SelectedTargetId].Cells[1].Value = txtFullName.Text; 263 | } 264 | 265 | FrmScriptEditor.Instance.CheckChanges(); 266 | } 267 | 268 | private void CmbActionMethod_SelectedIndexChanged(object sender, EventArgs e) 269 | { 270 | _selectedActionMethod = cmbActionMethod.SelectedIndex; 271 | 272 | cmbOptional.Enabled = cmbActionMethod.SelectedIndex == (int)ActionMethod.ReturnBody; 273 | 274 | txtIndex.Enabled = _selectedActionMethod != (int)ActionMethod.Patch; 275 | 276 | if (_selectedActionMethod == (int)ActionMethod.Remove) 277 | { 278 | cmbOpCodes.Enabled = false; 279 | txtOperand.Enabled = false; 280 | } 281 | else if (_selectedActionMethod == (int)ActionMethod.Insert || _selectedActionMethod == (int)ActionMethod.Replace) 282 | { 283 | cmbOpCodes.Enabled = true; 284 | txtOperand.Enabled = true; 285 | } 286 | 287 | if (_selectedActionMethod == (int)ActionMethod.EmptyBody || _selectedActionMethod == (int)ActionMethod.ReturnBody) 288 | { 289 | grpInstructions.Enabled = false; 290 | grpAddInstruction.Enabled = false; 291 | } 292 | else 293 | { 294 | grpInstructions.Enabled = true; 295 | grpAddInstruction.Enabled = true; 296 | } 297 | } 298 | 299 | private void CmbOpCodes_SelectedIndexChanged(object sender, EventArgs e) 300 | { 301 | if (cmbOpCodes.SelectedIndex != -1) 302 | { 303 | _selectedOpCode = (OpCode)cmbOpCodes.SelectedItem; 304 | 305 | switch (_selectedOpCode.OperandType) 306 | { 307 | case OperandType.InlineNone: 308 | case OperandType.InlinePhi: 309 | case OperandType.NOT_USED_8: 310 | txtOperand.Enabled = false; 311 | break; 312 | 313 | default: 314 | txtOperand.Enabled = true; 315 | break; 316 | } 317 | } 318 | } 319 | 320 | private void TsmiEditInstruction_Click(object sender, EventArgs e) 321 | { 322 | if (dgvInstructions.SelectedRows.Count > 0) 323 | { 324 | _selectedInstructionIndex = dgvInstructions.SelectedRows[0].Index; 325 | 326 | txtIndex.Text = dgvInstructions.Rows[_selectedInstructionIndex].Cells[0].Value?.ToString().EmptyIfNull(); 327 | cmbOpCodes.Text = dgvInstructions.Rows[_selectedInstructionIndex].Cells[1].Value?.ToString().EmptyIfNull(); 328 | txtOperand.Text = dgvInstructions.Rows[_selectedInstructionIndex].Cells[2].Value?.ToString().EmptyIfNull(); 329 | 330 | btnAddTarget.Text = Resources.FrmAddTarget_TsmiEditInstruction_Update_Text; 331 | } 332 | } 333 | 334 | private void TsmiRemoveInstruction_Click(object sender, EventArgs e) 335 | { 336 | if (dgvInstructions.SelectedRows.Count > 0) 337 | { 338 | dgvInstructions.Rows.RemoveAt(dgvInstructions.SelectedRows[0].Index); 339 | 340 | if (btnAddTarget.Text == Resources.FrmAddTarget_TsmiEditInstruction_Update_Text) 341 | { 342 | btnAddTarget.Text = Resources.FrmAddTarget_TsmiRemoveInstruction_AddTarget_Text; 343 | _selectedInstructionIndex = -1; 344 | } 345 | } 346 | } 347 | 348 | private void TsmiMoveUpInstruction_Click(object sender, EventArgs e) 349 | { 350 | if (dgvInstructions.SelectedRows.Count > 0) 351 | { 352 | dgvInstructions.MoveUp(); 353 | 354 | ResetAddTarget(); 355 | } 356 | } 357 | 358 | private void TsmiMoveDownInstruction_Click(object sender, EventArgs e) 359 | { 360 | if (dgvInstructions.SelectedRows.Count > 0) 361 | { 362 | dgvInstructions.MoveDown(); 363 | 364 | ResetAddTarget(); 365 | } 366 | } 367 | 368 | public void LoadOpCodes() 369 | { 370 | _opCodes = new List(); 371 | 372 | var type = typeof(OpCodes); 373 | var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static); 374 | foreach (var field in fields) 375 | { 376 | if (field.FieldType.Name == "OpCode") 377 | { 378 | var opCode = (OpCode)type.InvokeMember(field.Name, BindingFlags.Public | BindingFlags.Static | BindingFlags.GetField, null, null, null); 379 | _opCodes.Add(opCode); 380 | } 381 | } 382 | 383 | _opCodes = _opCodes.OrderBy(x => x.Name).ToList(); 384 | } 385 | 386 | private void ClearControls() 387 | { 388 | txtIndex.Text = string.Empty; 389 | cmbOpCodes.SelectedIndex = -1; 390 | txtOperand.Text = string.Empty; 391 | } 392 | 393 | private void ResetAddTarget() 394 | { 395 | if (btnAddTarget.Text == Resources.FrmAddTarget_TsmiEditInstruction_Update_Text) 396 | { 397 | btnAddTarget.Text = Resources.FrmAddTarget_TsmiRemoveInstruction_AddTarget_Text; 398 | _selectedInstructionIndex = -1; 399 | } 400 | } 401 | } 402 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Engine/ScriptEngineHelpers.cs: -------------------------------------------------------------------------------- 1 | using dnlib.DotNet; 2 | using dnlib.DotNet.Emit; 3 | using DotNetUniversalPatcher.Exceptions; 4 | using DotNetUniversalPatcher.Extensions; 5 | using DotNetUniversalPatcher.Models; 6 | using DotNetUniversalPatcher.Utilities; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.IO; 10 | using System.Linq; 11 | using System.Text; 12 | using DotNetUniversalPatcher.Properties; 13 | 14 | namespace DotNetUniversalPatcher.Engine 15 | { 16 | internal static class ScriptEngineHelpers 17 | { 18 | internal static readonly ModuleDefMD MscorelibModule = ModuleDefMD.Load(typeof(void).Module); 19 | 20 | internal static readonly Dictionary ReservedPlaceholders = new Dictionary(StringComparer.InvariantCultureIgnoreCase); 21 | 22 | public static bool ValidateScript(PatcherScript script) 23 | { 24 | if (string.IsNullOrWhiteSpace(script.PatcherOptions?.PatcherInfo?.Software)) 25 | { 26 | throw new Exception(Resources.ScriptEngineHelpers_ValidateScript_Software_Name_is_empty_Msg); 27 | } 28 | 29 | for (var i = 0; i < script.PatchList.Count; i++) 30 | { 31 | var patch = script.PatchList[i]; 32 | 33 | if (patch.TargetInfo != null) 34 | { 35 | if (patch.TargetInfo.TargetFiles == null || patch.TargetInfo?.TargetFiles?.Count == 0) 36 | { 37 | throw new ValidatePatchException("TargetFiles is empty!", i); 38 | } 39 | } 40 | else 41 | { 42 | throw new ValidatePatchException("TargetInfo is empty!", i); 43 | } 44 | 45 | if (patch.TargetList != null) 46 | { 47 | for (var j = 0; j < patch.TargetList.Count; j++) 48 | { 49 | var target = patch.TargetList[j]; 50 | 51 | if (string.IsNullOrWhiteSpace(target?.FullName) || string.IsNullOrWhiteSpace(target.Action?.ToString())) 52 | { 53 | throw new ValidatePatchAndTargetException("FullName or Action Method are empty!", i, j); 54 | } 55 | 56 | if (target.Action != ActionMethod.EmptyBody && target.ILCodes == null && target.Indices == null && target.Optional == null) 57 | { 58 | throw new ValidatePatchAndTargetException("Instructions, Indices or Optional are empty!", i, j); 59 | } 60 | } 61 | } 62 | else 63 | { 64 | throw new ValidatePatchException("TargetList is empty", i); 65 | } 66 | } 67 | 68 | return true; 69 | } 70 | 71 | internal static void ParseILCodes(Patcher p, Target target) 72 | { 73 | target.Instructions = new Instruction[target.ILCodes.Count]; 74 | 75 | for (int i = 0; i < target.Instructions.Length; i++) 76 | { 77 | string opcode = target.ILCodes[i].OpCode; 78 | 79 | if (opcode == null) throw new PatcherException("OpCode is empty", target.FullName); 80 | 81 | target.Instructions[i] = new Instruction(Helpers.GetOpCodeFromString(opcode.Replace('_', '.'))); 82 | } 83 | 84 | for (int i = 0; i < target.Instructions.Length; i++) 85 | { 86 | string operand = target.ILCodes[i].Operand; 87 | 88 | if (operand != null) 89 | { 90 | switch (target.Instructions[i].OpCode.OperandType) 91 | { 92 | case OperandType.InlineBrTarget: 93 | case OperandType.ShortInlineBrTarget: 94 | if (target.Action == ActionMethod.Patch) 95 | { 96 | target.Instructions[i].Operand = p.GetInstruction(target, operand.ToInt()); 97 | } 98 | else 99 | { 100 | target.Instructions[i].Operand = p.GetInstruction(operand.ToInt()); 101 | } 102 | break; 103 | 104 | case OperandType.InlineField: 105 | target.Instructions[i].Operand = p.FindField(operand); 106 | break; 107 | 108 | case OperandType.InlineI: 109 | target.Instructions[i].Operand = operand.ToInt(); 110 | break; 111 | 112 | case OperandType.InlineI8: 113 | target.Instructions[i].Operand = operand.ToLong(); 114 | break; 115 | 116 | case OperandType.InlineMethod: 117 | target.Instructions[i].Operand = p.FindMethod(operand); 118 | break; 119 | 120 | case OperandType.InlineNone: 121 | case OperandType.InlinePhi: 122 | case OperandType.NOT_USED_8: 123 | target.Instructions[i].Operand = null; 124 | break; 125 | 126 | case OperandType.InlineR: 127 | target.Instructions[i].Operand = operand.ToDouble(); 128 | break; 129 | 130 | case OperandType.InlineSig: 131 | target.Instructions[i].Operand = p.FindMethod(operand).MethodSig; 132 | break; 133 | 134 | case OperandType.InlineString: 135 | target.Instructions[i].Operand = operand; 136 | break; 137 | 138 | case OperandType.InlineSwitch: 139 | string[] array = operand.Split(Constants.DefaultSeparator); 140 | 141 | Instruction[] instructions = new Instruction[array.Length]; 142 | 143 | for (var j = 0; j < array.Length; j++) 144 | { 145 | if (target.Action == ActionMethod.Patch) 146 | { 147 | instructions[j] = p.GetInstruction(target, array[j].ToInt()); 148 | } 149 | else 150 | { 151 | instructions[j] = p.GetInstruction(array[j].ToInt()); 152 | } 153 | } 154 | 155 | target.Instructions[i].Operand = instructions; 156 | break; 157 | 158 | case OperandType.InlineTok: 159 | target.Instructions[i].Operand = p.FindMethodFieldOrType(operand); 160 | break; 161 | 162 | case OperandType.InlineType: 163 | target.Instructions[i].Operand = p.FindType(operand); 164 | break; 165 | 166 | case OperandType.InlineVar: 167 | target.Instructions[i].Operand = p.Method.Parameters[operand.ToInt()]; 168 | break; 169 | 170 | case OperandType.ShortInlineI: 171 | target.Instructions[i].Operand = target.Instructions[i].OpCode.Code == Code.Ldc_I4_S ? (object)operand.ToSByte() : operand.ToByte(); 172 | break; 173 | 174 | case OperandType.ShortInlineR: 175 | target.Instructions[i].Operand = operand.ToFloat(); 176 | break; 177 | 178 | case OperandType.ShortInlineVar: 179 | target.Instructions[i].Operand = p.Method.Parameters[operand.ToInt()]; 180 | break; 181 | } 182 | } 183 | } 184 | 185 | target.ILCodes = null; //We don't need that anymore. 186 | } 187 | 188 | internal static void PatchTarget(Patcher p, Target target) 189 | { 190 | p.BackupExceptionHandlersIndices(); 191 | 192 | switch (target.Action) 193 | { 194 | case ActionMethod.Patch: 195 | p.Patch(target); 196 | break; 197 | 198 | case ActionMethod.Insert: 199 | p.Insert(target); 200 | break; 201 | 202 | case ActionMethod.Replace: 203 | p.Replace(target); 204 | break; 205 | 206 | case ActionMethod.Remove: 207 | p.Remove(target); 208 | break; 209 | 210 | case ActionMethod.EmptyBody: 211 | p.EmptyBody(target); 212 | break; 213 | 214 | case ActionMethod.ReturnBody: 215 | p.ReturnBody(target, Convert.ToBoolean(target.Optional)); 216 | break; 217 | 218 | default: 219 | throw new PatcherException("Invalid action method", target.FullName); 220 | } 221 | 222 | p.FixOffsets(); 223 | p.FixExceptionHandlers(); 224 | p.FixBranches(); 225 | } 226 | 227 | internal static void WriteActionToLog(Target target) 228 | { 229 | string logText = $"[{target.Action}] -> {target.FullName}"; 230 | 231 | switch (target.Action) 232 | { 233 | case ActionMethod.Patch: 234 | case ActionMethod.Replace: 235 | case ActionMethod.Remove: 236 | Logger.Log(logText); 237 | break; 238 | 239 | case ActionMethod.EmptyBody: 240 | case ActionMethod.ReturnBody: 241 | Logger.Log(target.Optional != null ? $"{logText} -> {target.Optional}" : logText); 242 | break; 243 | } 244 | } 245 | 246 | internal static void AddPlaceholders(PatcherScript script) 247 | { 248 | foreach (var placeholder in script.PatcherOptions.Placeholders) 249 | { 250 | string placeholderKey = $"#{placeholder.Key.Replace("#", string.Empty).ToUpperInvariant()}#"; 251 | 252 | if (!ReservedPlaceholders.ContainsKey(placeholderKey)) 253 | { 254 | if (!ScriptEngine.Placeholders.ContainsKey(placeholderKey)) 255 | { 256 | ScriptEngine.Placeholders.Add(placeholderKey, placeholder.Value); 257 | } 258 | else 259 | { 260 | ScriptEngine.Placeholders[placeholderKey] = placeholder.Value; 261 | } 262 | } 263 | else 264 | { 265 | throw new PatcherException("Reserved placeholder cannot be changed!", placeholderKey); 266 | } 267 | } 268 | } 269 | 270 | internal static void AddSpecialFoldersToPlaceholders() 271 | { 272 | foreach (string name in Enum.GetNames(typeof(Environment.SpecialFolder))) 273 | { 274 | if (name == Environment.SpecialFolder.MyComputer.ToString() || name == Environment.SpecialFolder.LocalizedResources.ToString() || name == Environment.SpecialFolder.CommonOemLinks.ToString()) 275 | { 276 | continue; 277 | } 278 | 279 | string placeholder = $"#{name.Replace("#", string.Empty).ToUpperInvariant()}#"; 280 | 281 | if (!ReservedPlaceholders.Keys.Contains(placeholder)) 282 | { 283 | if (name == Environment.SpecialFolder.ProgramFiles.ToString()) 284 | { 285 | ReservedPlaceholders.Add(placeholder, Helpers.GetProgramFilesPath()); 286 | continue; 287 | } 288 | 289 | if (name == Environment.SpecialFolder.ProgramFilesX86.ToString()) 290 | { 291 | ReservedPlaceholders.Add(placeholder, Helpers.GetProgramFilesPath(true)); 292 | continue; 293 | } 294 | 295 | if (name == Environment.SpecialFolder.CommonProgramFiles.ToString()) 296 | { 297 | ReservedPlaceholders.Add(placeholder, Helpers.GetCommonProgramFilesPath()); 298 | continue; 299 | } 300 | 301 | if (name == Environment.SpecialFolder.CommonProgramFilesX86.ToString()) 302 | { 303 | ReservedPlaceholders.Add(placeholder, Helpers.GetCommonProgramFilesPath(true)); 304 | continue; 305 | } 306 | 307 | ReservedPlaceholders.Add(placeholder, Environment.GetFolderPath((Environment.SpecialFolder)Enum.Parse(typeof(Environment.SpecialFolder), name))); 308 | } 309 | } 310 | 311 | foreach (var folder in ReservedPlaceholders) 312 | { 313 | ScriptEngine.Placeholders.Add(folder.Key, folder.Value); 314 | } 315 | } 316 | 317 | internal static void ParsePlaceholders(PatcherScript script) 318 | { 319 | foreach (var patch in script.PatchList) 320 | { 321 | if (patch.TargetInfo.TargetFiles.Count > 0 && patch.TargetList.Count > 0) 322 | { 323 | for (int i = 0; i < patch.TargetInfo.TargetFiles.Count; i++) 324 | { 325 | patch.TargetInfo.TargetFiles[i] = patch.TargetInfo.TargetFiles[i].MultipleReplace(); 326 | } 327 | } 328 | 329 | foreach (var target in patch.TargetList) 330 | { 331 | target.FullName = target.FullName.MultipleReplace(); 332 | 333 | if (target.Indices != null) 334 | { 335 | for (int i = 0; i < target.Indices.Count; i++) 336 | { 337 | var index = target.Indices[i].MultipleReplace(); 338 | 339 | if (index.Contains(Constants.RangeExpressionSeparator)) 340 | { 341 | target.Indices[i] = index; 342 | } 343 | else 344 | { 345 | target.Indices[i] = index.ToInt().ToString(); 346 | } 347 | } 348 | } 349 | 350 | if (target.ILCodes != null) 351 | { 352 | foreach (var instruction in target.ILCodes) 353 | { 354 | if (instruction.OpCode != null) 355 | { 356 | instruction.OpCode = instruction.OpCode.MultipleReplace(); 357 | } 358 | 359 | if (instruction.Operand != null) 360 | { 361 | instruction.Operand = instruction.Operand.MultipleReplace(); 362 | } 363 | } 364 | } 365 | 366 | if (target.Optional != null) 367 | { 368 | target.Optional = target.Optional.MultipleReplace(); 369 | } 370 | } 371 | } 372 | } 373 | 374 | internal static void AddTargetFilesText(PatcherScript script) 375 | { 376 | StringBuilder sb = new StringBuilder(); 377 | 378 | foreach (var patch in script.PatchList) 379 | { 380 | foreach (string filePath in patch.TargetInfo.TargetFiles) 381 | { 382 | sb.AppendLine(filePath); 383 | 384 | script.TargetFilesText.Add(Path.GetFileName(filePath)); 385 | } 386 | } 387 | 388 | script.TargetFilesCount = script.TargetFilesText.Count; 389 | script.TargetFilesText = script.TargetFilesText.Distinct().ToList(); 390 | script.TargetFilesTip = sb.ToString(); 391 | } 392 | } 393 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/UI/FrmMain.Designer.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Windows.Forms; 3 | using DotNetUniversalPatcher.Properties; 4 | 5 | namespace DotNetUniversalPatcher.UI 6 | { 7 | partial class FrmMain 8 | { 9 | /// 10 | /// Required designer variable. 11 | /// 12 | private IContainer components = null; 13 | 14 | /// 15 | /// Clean up any resources being used. 16 | /// 17 | /// true if managed resources should be disposed; otherwise, false. 18 | protected override void Dispose(bool disposing) 19 | { 20 | if (disposing && (components != null)) 21 | { 22 | components.Dispose(); 23 | } 24 | base.Dispose(disposing); 25 | } 26 | 27 | #region Windows Form Designer generated code 28 | 29 | /// 30 | /// Required method for Designer support - do not modify 31 | /// the contents of this method with the code editor. 32 | /// 33 | private void InitializeComponent() 34 | { 35 | this.components = new System.ComponentModel.Container(); 36 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmMain)); 37 | this.flpMain = new System.Windows.Forms.FlowLayoutPanel(); 38 | this.grpPatcherInfo = new System.Windows.Forms.GroupBox(); 39 | this.lblSoftware = new System.Windows.Forms.Label(); 40 | this.cmbSoftware = new System.Windows.Forms.ComboBox(); 41 | this.txtReleaseDate = new System.Windows.Forms.TextBox(); 42 | this.lblAuthor = new System.Windows.Forms.Label(); 43 | this.lblReleaseDate = new System.Windows.Forms.Label(); 44 | this.txtAuthor = new System.Windows.Forms.TextBox(); 45 | this.txtTargetFiles = new System.Windows.Forms.TextBox(); 46 | this.txtWebsite = new System.Windows.Forms.TextBox(); 47 | this.lblTargetFiles = new System.Windows.Forms.Label(); 48 | this.lblWebsite = new System.Windows.Forms.Label(); 49 | this.grpReleaseInfo = new System.Windows.Forms.GroupBox(); 50 | this.lstLog = new System.Windows.Forms.ListBox(); 51 | this.txtReleaseInfo = new System.Windows.Forms.TextBox(); 52 | this.chkMakeBackup = new System.Windows.Forms.CheckBox(); 53 | this.btnPatch = new System.Windows.Forms.Button(); 54 | this.btnAbout = new System.Windows.Forms.Button(); 55 | this.btnExit = new System.Windows.Forms.Button(); 56 | this.tipLogItem = new System.Windows.Forms.ToolTip(this.components); 57 | this.tipTargetFiles = new System.Windows.Forms.ToolTip(this.components); 58 | this.msMain = new System.Windows.Forms.MenuStrip(); 59 | this.tsmiScriptEditor = new System.Windows.Forms.ToolStripMenuItem(); 60 | this.tsmiRefresh = new System.Windows.Forms.ToolStripMenuItem(); 61 | this.tsmiAbout = new System.Windows.Forms.ToolStripMenuItem(); 62 | this.tsmiExit = new System.Windows.Forms.ToolStripMenuItem(); 63 | this.flpMain.SuspendLayout(); 64 | this.grpPatcherInfo.SuspendLayout(); 65 | this.grpReleaseInfo.SuspendLayout(); 66 | this.msMain.SuspendLayout(); 67 | this.SuspendLayout(); 68 | // 69 | // flpMain 70 | // 71 | this.flpMain.Controls.Add(this.grpPatcherInfo); 72 | this.flpMain.Controls.Add(this.grpReleaseInfo); 73 | this.flpMain.Controls.Add(this.chkMakeBackup); 74 | this.flpMain.Controls.Add(this.btnPatch); 75 | this.flpMain.Controls.Add(this.btnAbout); 76 | this.flpMain.Controls.Add(this.btnExit); 77 | this.flpMain.Dock = System.Windows.Forms.DockStyle.Fill; 78 | this.flpMain.Location = new System.Drawing.Point(0, 24); 79 | this.flpMain.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); 80 | this.flpMain.Name = "flpMain"; 81 | this.flpMain.Padding = new System.Windows.Forms.Padding(8, 0, 8, 7); 82 | this.flpMain.Size = new System.Drawing.Size(454, 361); 83 | this.flpMain.TabIndex = 0; 84 | // 85 | // grpPatcherInfo 86 | // 87 | this.grpPatcherInfo.Controls.Add(this.lblSoftware); 88 | this.grpPatcherInfo.Controls.Add(this.cmbSoftware); 89 | this.grpPatcherInfo.Controls.Add(this.txtReleaseDate); 90 | this.grpPatcherInfo.Controls.Add(this.lblAuthor); 91 | this.grpPatcherInfo.Controls.Add(this.lblReleaseDate); 92 | this.grpPatcherInfo.Controls.Add(this.txtAuthor); 93 | this.grpPatcherInfo.Controls.Add(this.txtTargetFiles); 94 | this.grpPatcherInfo.Controls.Add(this.txtWebsite); 95 | this.grpPatcherInfo.Controls.Add(this.lblTargetFiles); 96 | this.grpPatcherInfo.Controls.Add(this.lblWebsite); 97 | this.grpPatcherInfo.Enabled = false; 98 | this.grpPatcherInfo.Location = new System.Drawing.Point(11, 3); 99 | this.grpPatcherInfo.Name = "grpPatcherInfo"; 100 | this.grpPatcherInfo.Size = new System.Drawing.Size(430, 175); 101 | this.grpPatcherInfo.TabIndex = 0; 102 | this.grpPatcherInfo.TabStop = false; 103 | this.grpPatcherInfo.Text = Resources.FrmMain_Patcher_Info_Text; 104 | // 105 | // lblSoftware 106 | // 107 | this.lblSoftware.AutoSize = true; 108 | this.lblSoftware.Location = new System.Drawing.Point(6, 24); 109 | this.lblSoftware.Name = "lblSoftware"; 110 | this.lblSoftware.Size = new System.Drawing.Size(62, 17); 111 | this.lblSoftware.TabIndex = 0; 112 | this.lblSoftware.Text = Resources.FrmMain_Software_Text; 113 | // 114 | // cmbSoftware 115 | // 116 | this.cmbSoftware.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend; 117 | this.cmbSoftware.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems; 118 | this.cmbSoftware.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 119 | this.cmbSoftware.FormattingEnabled = true; 120 | this.cmbSoftware.Location = new System.Drawing.Point(112, 21); 121 | this.cmbSoftware.Name = "cmbSoftware"; 122 | this.cmbSoftware.Size = new System.Drawing.Size(308, 25); 123 | this.cmbSoftware.TabIndex = 1; 124 | this.cmbSoftware.SelectedIndexChanged += new System.EventHandler(this.CmbSoftware_SelectedIndexChanged); 125 | // 126 | // txtReleaseDate 127 | // 128 | this.txtReleaseDate.Location = new System.Drawing.Point(112, 140); 129 | this.txtReleaseDate.Name = "txtReleaseDate"; 130 | this.txtReleaseDate.ReadOnly = true; 131 | this.txtReleaseDate.Size = new System.Drawing.Size(308, 25); 132 | this.txtReleaseDate.TabIndex = 9; 133 | // 134 | // lblAuthor 135 | // 136 | this.lblAuthor.AutoSize = true; 137 | this.lblAuthor.Location = new System.Drawing.Point(6, 85); 138 | this.lblAuthor.Name = "lblAuthor"; 139 | this.lblAuthor.Size = new System.Drawing.Size(50, 17); 140 | this.lblAuthor.TabIndex = 4; 141 | this.lblAuthor.Text = Resources.FrmMain_Author_Text; 142 | // 143 | // lblReleaseDate 144 | // 145 | this.lblReleaseDate.AutoSize = true; 146 | this.lblReleaseDate.Location = new System.Drawing.Point(6, 143); 147 | this.lblReleaseDate.Name = "lblReleaseDate"; 148 | this.lblReleaseDate.Size = new System.Drawing.Size(87, 17); 149 | this.lblReleaseDate.TabIndex = 8; 150 | this.lblReleaseDate.Text = Resources.FrmMain_Release_Date_Text; 151 | // 152 | // txtAuthor 153 | // 154 | this.txtAuthor.Location = new System.Drawing.Point(112, 82); 155 | this.txtAuthor.Name = "txtAuthor"; 156 | this.txtAuthor.ReadOnly = true; 157 | this.txtAuthor.Size = new System.Drawing.Size(308, 25); 158 | this.txtAuthor.TabIndex = 5; 159 | // 160 | // txtTargetFiles 161 | // 162 | this.txtTargetFiles.Location = new System.Drawing.Point(112, 52); 163 | this.txtTargetFiles.Name = "txtTargetFiles"; 164 | this.txtTargetFiles.ReadOnly = true; 165 | this.txtTargetFiles.Size = new System.Drawing.Size(308, 25); 166 | this.txtTargetFiles.TabIndex = 3; 167 | this.txtTargetFiles.MouseHover += new System.EventHandler(this.TxtTargetFiles_MouseHover); 168 | // 169 | // txtWebsite 170 | // 171 | this.txtWebsite.Location = new System.Drawing.Point(112, 111); 172 | this.txtWebsite.Name = "txtWebsite"; 173 | this.txtWebsite.ReadOnly = true; 174 | this.txtWebsite.Size = new System.Drawing.Size(308, 25); 175 | this.txtWebsite.TabIndex = 7; 176 | this.txtWebsite.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.TxtWebsite_MouseDoubleClick); 177 | // 178 | // lblTargetFiles 179 | // 180 | this.lblTargetFiles.AutoSize = true; 181 | this.lblTargetFiles.Location = new System.Drawing.Point(6, 55); 182 | this.lblTargetFiles.Name = "lblTargetFiles"; 183 | this.lblTargetFiles.Size = new System.Drawing.Size(96, 17); 184 | this.lblTargetFiles.TabIndex = 2; 185 | this.lblTargetFiles.Text = Resources.FrmMain_Target_Files_Text; 186 | // 187 | // lblWebsite 188 | // 189 | this.lblWebsite.AutoSize = true; 190 | this.lblWebsite.Location = new System.Drawing.Point(6, 114); 191 | this.lblWebsite.Name = "lblWebsite"; 192 | this.lblWebsite.Size = new System.Drawing.Size(57, 17); 193 | this.lblWebsite.TabIndex = 6; 194 | this.lblWebsite.Text = Resources.FrmMain_Website_Text; 195 | // 196 | // grpReleaseInfo 197 | // 198 | this.grpReleaseInfo.Controls.Add(this.lstLog); 199 | this.grpReleaseInfo.Controls.Add(this.txtReleaseInfo); 200 | this.grpReleaseInfo.Enabled = false; 201 | this.grpReleaseInfo.Location = new System.Drawing.Point(11, 184); 202 | this.grpReleaseInfo.Name = "grpReleaseInfo"; 203 | this.grpReleaseInfo.Size = new System.Drawing.Size(430, 125); 204 | this.grpReleaseInfo.TabIndex = 1; 205 | this.grpReleaseInfo.TabStop = false; 206 | this.grpReleaseInfo.Text = Resources.FrmMain_Release_Info_Text; 207 | // 208 | // lstLog 209 | // 210 | this.lstLog.FormattingEnabled = true; 211 | this.lstLog.ItemHeight = 17; 212 | this.lstLog.Location = new System.Drawing.Point(9, 24); 213 | this.lstLog.Name = "lstLog"; 214 | this.lstLog.ScrollAlwaysVisible = true; 215 | this.lstLog.Size = new System.Drawing.Size(411, 89); 216 | this.lstLog.TabIndex = 1; 217 | this.lstLog.Visible = false; 218 | this.lstLog.KeyDown += new System.Windows.Forms.KeyEventHandler(this.LstLog_KeyDown); 219 | this.lstLog.MouseLeave += new System.EventHandler(this.LstLog_MouseLeave); 220 | this.lstLog.MouseMove += new System.Windows.Forms.MouseEventHandler(this.LstLog_MouseMove); 221 | // 222 | // txtReleaseInfo 223 | // 224 | this.txtReleaseInfo.Enabled = false; 225 | this.txtReleaseInfo.Location = new System.Drawing.Point(9, 24); 226 | this.txtReleaseInfo.Multiline = true; 227 | this.txtReleaseInfo.Name = "txtReleaseInfo"; 228 | this.txtReleaseInfo.ReadOnly = true; 229 | this.txtReleaseInfo.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; 230 | this.txtReleaseInfo.Size = new System.Drawing.Size(411, 89); 231 | this.txtReleaseInfo.TabIndex = 0; 232 | // 233 | // chkMakeBackup 234 | // 235 | this.chkMakeBackup.AutoSize = true; 236 | this.chkMakeBackup.Enabled = false; 237 | this.chkMakeBackup.Location = new System.Drawing.Point(14, 321); 238 | this.chkMakeBackup.Margin = new System.Windows.Forms.Padding(6, 9, 2, 5); 239 | this.chkMakeBackup.Name = "chkMakeBackup"; 240 | this.chkMakeBackup.Size = new System.Drawing.Size(104, 21); 241 | this.chkMakeBackup.TabIndex = 2; 242 | this.chkMakeBackup.Text = Resources.FrmMain_Make_Backup_Text; 243 | this.chkMakeBackup.UseVisualStyleBackColor = true; 244 | this.chkMakeBackup.CheckedChanged += new System.EventHandler(this.ChkMakeBackup_CheckedChanged); 245 | // 246 | // btnPatch 247 | // 248 | this.btnPatch.Enabled = false; 249 | this.btnPatch.Location = new System.Drawing.Point(123, 314); 250 | this.btnPatch.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); 251 | this.btnPatch.Name = "btnPatch"; 252 | this.btnPatch.Size = new System.Drawing.Size(102, 34); 253 | this.btnPatch.TabIndex = 3; 254 | this.btnPatch.Text = Resources.FrmMain_Patch_Text; 255 | this.btnPatch.UseVisualStyleBackColor = true; 256 | this.btnPatch.Click += new System.EventHandler(this.BtnPatch_Click); 257 | // 258 | // btnAbout 259 | // 260 | this.btnAbout.Location = new System.Drawing.Point(231, 314); 261 | this.btnAbout.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); 262 | this.btnAbout.Name = "btnAbout"; 263 | this.btnAbout.Size = new System.Drawing.Size(102, 34); 264 | this.btnAbout.TabIndex = 4; 265 | this.btnAbout.Text = Resources.FrmMain_About_Text; 266 | this.btnAbout.UseVisualStyleBackColor = true; 267 | this.btnAbout.Click += new System.EventHandler(this.BtnAbout_Click); 268 | // 269 | // btnExit 270 | // 271 | this.btnExit.DialogResult = System.Windows.Forms.DialogResult.Cancel; 272 | this.btnExit.Location = new System.Drawing.Point(339, 314); 273 | this.btnExit.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); 274 | this.btnExit.Name = "btnExit"; 275 | this.btnExit.Size = new System.Drawing.Size(102, 34); 276 | this.btnExit.TabIndex = 5; 277 | this.btnExit.Text = Resources.FrmMain_Exit_Text; 278 | this.btnExit.UseVisualStyleBackColor = true; 279 | this.btnExit.Click += new System.EventHandler(this.BtnExit_Click); 280 | // 281 | // msMain 282 | // 283 | this.msMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 284 | this.tsmiScriptEditor, 285 | this.tsmiRefresh, 286 | this.tsmiAbout, 287 | this.tsmiExit}); 288 | this.msMain.Location = new System.Drawing.Point(0, 0); 289 | this.msMain.Name = "msMain"; 290 | this.msMain.Size = new System.Drawing.Size(454, 24); 291 | this.msMain.TabIndex = 1; 292 | this.msMain.Text = "menuStrip1"; 293 | // 294 | // tsmiScriptEditor 295 | // 296 | this.tsmiScriptEditor.Name = "tsmiScriptEditor"; 297 | this.tsmiScriptEditor.Size = new System.Drawing.Size(83, 20); 298 | this.tsmiScriptEditor.Text = Resources.FrmMain_Script_Editor_Text; 299 | this.tsmiScriptEditor.Click += new System.EventHandler(this.TsmiScriptEditor_Click); 300 | // 301 | // tsmiRefresh 302 | // 303 | this.tsmiRefresh.Name = "tsmiRefresh"; 304 | this.tsmiRefresh.ShortcutKeys = System.Windows.Forms.Keys.F5; 305 | this.tsmiRefresh.Size = new System.Drawing.Size(58, 20); 306 | this.tsmiRefresh.Text = Resources.FrmMain_Refresh_Text; 307 | this.tsmiRefresh.Click += new System.EventHandler(this.TsmiRefresh_Click); 308 | // 309 | // tsmiAbout 310 | // 311 | this.tsmiAbout.Name = "tsmiAbout"; 312 | this.tsmiAbout.Size = new System.Drawing.Size(52, 20); 313 | this.tsmiAbout.Text = Resources.FrmMain_About_Text; 314 | this.tsmiAbout.Click += new System.EventHandler(this.TsmiAbout_Click); 315 | // 316 | // tsmiExit 317 | // 318 | this.tsmiExit.Name = "tsmiExit"; 319 | this.tsmiExit.Size = new System.Drawing.Size(38, 20); 320 | this.tsmiExit.Text = Resources.FrmMain_Exit_Text; 321 | this.tsmiExit.Click += new System.EventHandler(this.BtnExit_Click); 322 | // 323 | // FrmMain 324 | // 325 | this.AcceptButton = this.btnPatch; 326 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit; 327 | this.ClientSize = new System.Drawing.Size(454, 385); 328 | this.Controls.Add(this.flpMain); 329 | this.Controls.Add(this.msMain); 330 | this.Font = new System.Drawing.Font("Segoe UI", 9.75F); 331 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 332 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 333 | this.Margin = new System.Windows.Forms.Padding(4); 334 | this.MaximizeBox = false; 335 | this.Name = "FrmMain"; 336 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 337 | this.Text = "DotNet Universal Patcher"; 338 | this.Load += new System.EventHandler(this.FrmMain_Load); 339 | this.flpMain.ResumeLayout(false); 340 | this.flpMain.PerformLayout(); 341 | this.grpPatcherInfo.ResumeLayout(false); 342 | this.grpPatcherInfo.PerformLayout(); 343 | this.grpReleaseInfo.ResumeLayout(false); 344 | this.grpReleaseInfo.PerformLayout(); 345 | this.msMain.ResumeLayout(false); 346 | this.msMain.PerformLayout(); 347 | this.ResumeLayout(false); 348 | this.PerformLayout(); 349 | 350 | } 351 | 352 | #endregion 353 | 354 | private FlowLayoutPanel flpMain; 355 | private Label lblSoftware; 356 | private Label lblAuthor; 357 | internal TextBox txtAuthor; 358 | private Label lblWebsite; 359 | internal TextBox txtWebsite; 360 | private Label lblReleaseDate; 361 | internal TextBox txtReleaseDate; 362 | internal TextBox txtReleaseInfo; 363 | private Button btnAbout; 364 | private Button btnExit; 365 | internal CheckBox chkMakeBackup; 366 | internal GroupBox grpReleaseInfo; 367 | internal TextBox txtTargetFiles; 368 | internal Label lblTargetFiles; 369 | internal ListBox lstLog; 370 | private ToolTip tipLogItem; 371 | private ToolTip tipTargetFiles; 372 | internal ComboBox cmbSoftware; 373 | internal GroupBox grpPatcherInfo; 374 | internal Button btnPatch; 375 | private MenuStrip msMain; 376 | private ToolStripMenuItem tsmiAbout; 377 | private ToolStripMenuItem tsmiExit; 378 | private ToolStripMenuItem tsmiScriptEditor; 379 | private ToolStripMenuItem tsmiRefresh; 380 | } 381 | } 382 | 383 | -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Properties/Resources.zh-Hans.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 动作: 122 | 123 | 124 | 添加指令 125 | 126 | 127 | 添加目标 128 | 129 | 130 | 添加 131 | 132 | 133 | 取消 134 | 135 | 136 | 清除 137 | 138 | 139 | 编辑 140 | 141 | 142 | 全名: 143 | 144 | 145 | Index 146 | 147 | 148 | Index: 149 | 150 | 151 | 命令 152 | 153 | 154 | 下移 155 | 156 | 157 | 上移 158 | 159 | 160 | 操作码 161 | 162 | 163 | 操作码: 164 | 165 | 166 | 操作数 167 | 168 | 169 | 操作数: 170 | 171 | 172 | 可选: 173 | 174 | 175 | 移除 176 | 177 | 178 | 保存 179 | 180 | 181 | 目标 182 | 183 | 184 | 关于 185 | 186 | 187 | 作者: 188 | 189 | 190 | 退出 191 | 192 | 193 | 备份 194 | 195 | 196 | 补丁 197 | 198 | 199 | 补丁信息 200 | 201 | 202 | 刷新 203 | 204 | 205 | 发布日期: 206 | 207 | 208 | 发布信息 209 | 210 | 211 | 脚本编辑器 212 | 213 | 214 | 日志 215 | 216 | 217 | 软件: 218 | 219 | 220 | 目标文件({0}): 221 | 222 | 223 | 网站: 224 | 225 | 226 | 关于文本: 227 | 228 | 229 | 添加占位符 230 | 231 | 232 | 添加 233 | 234 | 235 | 作者: 236 | 237 | 238 | 取消 239 | 240 | 241 | 清除 242 | 243 | 244 | 编辑 245 | 246 | 247 | 备份 248 | 249 | 250 | 下移 251 | 252 | 253 | 上移 254 | 255 | 256 | 选项 257 | 258 | 259 | 补丁信息 260 | 261 | 262 | 补丁选项 263 | 264 | 265 | 占位符键 266 | 267 | 268 | 占位符键: 269 | 270 | 271 | 占位符值 272 | 273 | 274 | 占位符值: 275 | 276 | 277 | 占位符 278 | 279 | 280 | 发布日期: 281 | 282 | 283 | 发布信息: 284 | 285 | 286 | 移除 287 | 288 | 289 | 保留占位符 290 | 291 | 292 | 保存 293 | 294 | 295 | 软件: 296 | 297 | 298 | 今天 299 | 300 | 301 | 访问 302 | 303 | 304 | 网站: 305 | 306 | 307 | 关于 308 | 309 | 310 | 动作方法 311 | 312 | 313 | 添加目标文件 314 | 315 | 316 | 添加 317 | 318 | 319 | 添加 320 | 321 | 322 | 关闭 323 | 324 | 325 | 编辑 326 | 327 | 328 | 编辑 329 | 330 | 331 | 文件路径 332 | 333 | 334 | 文件 335 | 336 | 337 | 全名 338 | 339 | 340 | 保留旧的MaxStack值 341 | 342 | 343 | 下移 344 | 345 | 346 | 上移 347 | 348 | 349 | 新建 350 | 351 | 352 | 打开 353 | 354 | 355 | 选项 356 | 357 | 358 | 补丁程序列表 359 | 360 | 361 | 补丁程序选项 362 | 363 | 364 | 移除 365 | 366 | 367 | 移除 368 | 369 | 370 | 另存为... 371 | 372 | 373 | 保存 374 | 375 | 376 | 脚本编辑器 377 | 378 | 379 | 目标文件 380 | 381 | 382 | 目标信息 383 | 384 | 385 | 目标清单 386 | 387 | 388 | 目标选项 389 | 390 | 391 | 更新 392 | 393 | 394 | 更新 395 | 396 | 397 | 更新 398 | 399 | 400 | 更新 401 | 402 | 403 | 编辑目标 404 | 405 | 406 | 添加 407 | 408 | 409 | 更新 410 | 411 | 412 | 编辑目标 413 | 414 | 415 | 备份文件已存在 -> {0} 416 | 417 | 418 | 找不到补丁程序文件夹。 419 | {0}{1}{2} 420 | 421 | 422 | 加载脚本文件 -> ({0}) 时出错 423 | {1}{2}{3} 424 | 425 | 426 | [文件已修补] -> {0} 427 | 428 | 429 | [文件路径] -> {0}{1} 430 | 431 | 432 | [正在跳过文件] 433 | 434 | 435 | 找不到文件 -> {0} 436 | 437 | 438 | 可执行文件 (.exe;*.dll)|*.exe;*.dll|所有文件 (*.*)|*.* 439 | 440 | 441 | 没有修补! 442 | 443 | 444 | 修补已完成![{0}个文件已修补] 445 | 446 | 447 | 软件名为空! 448 | 449 | 450 | 在偏移量{0}处找不到指令 451 | 452 | 453 | 索引为空!-> {0} 454 | 455 | 456 | 指令是空的! 457 | 目标 -> {0} 458 | 459 | 460 | 补丁列表是空的! 461 | 462 | 463 | 占位符键为空! 464 | 占位符值->“{0}” 465 | 466 | 467 | 目标列表是空的! 468 | 469 | 470 | 补丁 {0} 471 | 472 | 473 | 是否要在关闭脚本文件之前保存更改? 474 | 475 | 476 | 确定要删除“{0}”吗? 477 | 478 | 479 | 目标文件路径为空! 480 | 481 | 482 | 软件名为空! 483 | 484 | 485 | “{0}”占位符已存在! 486 | 487 | 488 | 补丁程序选项已成功保存! 489 | 490 | 491 | 占位符值为空! 492 | 493 | 494 | 占位符键为空! 495 | 496 | 497 | 将DNUP脚本文件移到这里! 498 | 499 | 500 | 删除我。 501 | 502 | -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Author: 122 | 123 | 124 | Patcher Info 125 | 126 | 127 | Software: 128 | 129 | 130 | Release Date: 131 | 132 | 133 | Target Files ({0}): 134 | 135 | 136 | Website: 137 | 138 | 139 | Release Info 140 | 141 | 142 | Make Backup 143 | 144 | 145 | Patch 146 | 147 | 148 | About 149 | 150 | 151 | Exit 152 | 153 | 154 | Script Editor 155 | 156 | 157 | Refresh 158 | 159 | 160 | Log 161 | 162 | 163 | Action: 164 | 165 | 166 | Full Name: 167 | 168 | 169 | Index: 170 | 171 | 172 | OpCode: 173 | 174 | 175 | Edit 176 | 177 | 178 | Remove 179 | 180 | 181 | Move Up 182 | 183 | 184 | Move Down 185 | 186 | 187 | Operand: 188 | 189 | 190 | Optional: 191 | 192 | 193 | Add Instruction 194 | 195 | 196 | Clear 197 | 198 | 199 | Add 200 | 201 | 202 | Target 203 | 204 | 205 | Instructions 206 | 207 | 208 | Index 209 | 210 | 211 | OpCode 212 | 213 | 214 | Operand 215 | 216 | 217 | Cancel 218 | 219 | 220 | Save 221 | 222 | 223 | Add Target 224 | 225 | 226 | Patcher Options 227 | 228 | 229 | Options 230 | 231 | 232 | Make Backup 233 | 234 | 235 | Patcher Info 236 | 237 | 238 | About Text: 239 | 240 | 241 | Release Info: 242 | 243 | 244 | Visit 245 | 246 | 247 | Today 248 | 249 | 250 | Author: 251 | 252 | 253 | Release Date: 254 | 255 | 256 | Website: 257 | 258 | 259 | Software: 260 | 261 | 262 | Placeholders 263 | 264 | 265 | Add Placeholder 266 | 267 | 268 | Clear 269 | 270 | 271 | Placeholder Value: 272 | 273 | 274 | Placeholder Key: 275 | 276 | 277 | Add 278 | 279 | 280 | Placeholder Key 281 | 282 | 283 | Placeholder Value 284 | 285 | 286 | Edit 287 | 288 | 289 | Remove 290 | 291 | 292 | Move Up 293 | 294 | 295 | Move Down 296 | 297 | 298 | Reserved Placeholders 299 | 300 | 301 | Cancel 302 | 303 | 304 | Save 305 | 306 | 307 | File 308 | 309 | 310 | New 311 | 312 | 313 | Open 314 | 315 | 316 | Save 317 | 318 | 319 | Save As... 320 | 321 | 322 | Close 323 | 324 | 325 | About 326 | 327 | 328 | Add 329 | 330 | 331 | Edit 332 | 333 | 334 | Remove 335 | 336 | 337 | Move Up 338 | 339 | 340 | Move Down 341 | 342 | 343 | Patch List 344 | 345 | 346 | Patcher Options 347 | 348 | 349 | Target Options 350 | 351 | 352 | Target List 353 | 354 | 355 | Action Method 356 | 357 | 358 | Full Name 359 | 360 | 361 | Target Info 362 | 363 | 364 | Add Target File 365 | 366 | 367 | Add 368 | 369 | 370 | Options 371 | 372 | 373 | Keep Old MaxStack Value 374 | 375 | 376 | Target Files 377 | 378 | 379 | File Path 380 | 381 | 382 | Edit 383 | 384 | 385 | Remove 386 | 387 | 388 | Script Editor 389 | 390 | 391 | Update 392 | 393 | 394 | Update 395 | 396 | 397 | Add 398 | 399 | 400 | Edit Target 401 | 402 | 403 | Update 404 | 405 | 406 | Edit Target 407 | 408 | 409 | Update 410 | 411 | 412 | Update 413 | 414 | 415 | Backup file already exists -> {0} 416 | 417 | 418 | Patching process finished! [{0} file(s) patched] 419 | 420 | 421 | Nothing patched! 422 | 423 | 424 | [File Patched] -> {0} 425 | 426 | 427 | [File Path] -> {0} {1} 428 | 429 | 430 | [Skipping file] 431 | 432 | 433 | File not found -> {0} 434 | 435 | 436 | Executable files (.exe;*.dll)|*.exe;*.dll|All files (*.*)|*.* 437 | 438 | 439 | Error while loading the script file -> ({0}) 440 | {1}{2}{3} 441 | 442 | 443 | Patchers folder not found. 444 | {0}{1}{2} 445 | 446 | 447 | Instruction not found at offset {0} 448 | 449 | 450 | Software Name is empty! 451 | 452 | 453 | Placeholder Key is empty! 454 | Placeholder Value -> "{0}" 455 | 456 | 457 | Patch List is Empty! 458 | 459 | 460 | Target List is Empty! 461 | 462 | 463 | Instructions are Empty! 464 | Target -> {0} 465 | 466 | 467 | Indices are empty! -> {0} 468 | 469 | 470 | Do you want to save changes before closing the script file? 471 | 472 | 473 | Patch {0} 474 | 475 | 476 | Placeholder Key is empty! 477 | 478 | 479 | Placeholder Value is empty! 480 | 481 | 482 | Software Name is empty! 483 | 484 | 485 | Patcher Options are successfully saved! 486 | 487 | 488 | "{0}" Placeholder already exists! 489 | 490 | 491 | Target File Path is empty! 492 | 493 | 494 | Are you sure you want to remove "{0}"? 495 | 496 | 497 | Move Your DNUP Script Files Here! 498 | 499 | 500 | Delete me. 501 | 502 | -------------------------------------------------------------------------------- /DotNetUniversalPatcher/Engine/Patcher.cs: -------------------------------------------------------------------------------- 1 | using dnlib.DotNet; 2 | using dnlib.DotNet.Emit; 3 | using dnlib.DotNet.Writer; 4 | using DotNetUniversalPatcher.Exceptions; 5 | using DotNetUniversalPatcher.Extensions; 6 | using DotNetUniversalPatcher.Models; 7 | using DotNetUniversalPatcher.Utilities; 8 | using System; 9 | using System.Collections.Generic; 10 | using System.IO; 11 | using System.Linq; 12 | using System.Text.RegularExpressions; 13 | using DotNetUniversalPatcher.Properties; 14 | 15 | namespace DotNetUniversalPatcher.Engine 16 | { 17 | internal class Patcher : IDisposable 18 | { 19 | public MethodDef Method { get; set; } 20 | public IList Instructions { get; set; } 21 | 22 | internal readonly ModuleDefMD Module; 23 | 24 | private readonly string _file; 25 | private readonly bool _keepOldMaxStack; 26 | private readonly List _exceptionHandlersIndices = new List(); 27 | 28 | internal Patcher(string file, bool keepOldMaxStack) 29 | { 30 | _file = file; 31 | Module = ModuleDefMD.Load(file); 32 | _keepOldMaxStack = keepOldMaxStack; 33 | } 34 | 35 | internal void Patch(Target target) 36 | { 37 | if (target.Instructions != null) 38 | { 39 | PatchAndClear(target); 40 | } 41 | else if (target.Instructions == null) 42 | { 43 | throw new PatcherException("No Instructions specified", target.FullName); 44 | } 45 | } 46 | 47 | internal void PatchAndClear(Target target) 48 | { 49 | Method.Body.ExceptionHandlers.Clear(); 50 | Instructions.Clear(); 51 | 52 | for (int i = 0; i < target.Instructions.Length; i++) 53 | { 54 | Instructions.Insert(i, target.Instructions[i]); 55 | } 56 | } 57 | 58 | internal void Insert(Target target) 59 | { 60 | if (target.Indices != null && target.Instructions != null) 61 | { 62 | if (target.Indices.Count == target.Instructions.Length) 63 | { 64 | for (int i = 0; i < target.Indices.Count; i++) 65 | { 66 | if (target.Indices[i].Contains(Constants.RangeExpressionSeparator)) 67 | { 68 | string[] startAndEnd = Regex.Split(target.Indices[i], Constants.RangeExpressionRegexPattern); 69 | 70 | int start = startAndEnd[0].ToInt(); 71 | int end = startAndEnd[1].ToInt(); 72 | 73 | if (startAndEnd.Length == 2 && start <= end) 74 | { 75 | uint offset = 0; 76 | 77 | for (int j = start; j <= end; j++) 78 | { 79 | Instructions.Insert(j, Instruction.Create(OpCodes.Nop)); 80 | 81 | Instructions[j].OpCode = target.Instructions[i].OpCode; 82 | 83 | if (Instructions[j].Operand != null) 84 | { 85 | Instructions[j].Operand = target.Instructions[i].Operand; 86 | } 87 | 88 | offset += (uint)Instructions[j].GetSize(); 89 | Instructions[j].Offset = offset; 90 | } 91 | } 92 | else 93 | { 94 | throw new PatcherException("Index Range format is incorrect (Correct format is startIndex...endIndex)", target.FullName); 95 | } 96 | } 97 | else 98 | { 99 | Instructions.Insert(target.Indices[i].ToInt(), target.Instructions[i]); 100 | } 101 | } 102 | } 103 | else 104 | { 105 | throw new PatcherException("Instructions and Indices count must be equal", target.FullName); 106 | } 107 | } 108 | else if (target.Instructions == null) 109 | { 110 | throw new PatcherException("No Instructions specified", target.FullName); 111 | } 112 | else if (target.Indices == null) 113 | { 114 | throw new PatcherException("No Indices specified", target.FullName); 115 | } 116 | } 117 | 118 | internal void Replace(Target target) 119 | { 120 | if (target.Indices != null && target.Instructions != null) 121 | { 122 | if (target.Indices.Count == target.Instructions.Length) 123 | { 124 | for (int i = 0; i < target.Indices.Count; i++) 125 | { 126 | if (target.Indices[i].Contains(Constants.RangeExpressionSeparator)) 127 | { 128 | string[] startAndEnd = Regex.Split(target.Indices[i], Constants.RangeExpressionRegexPattern); 129 | 130 | int start = startAndEnd[0].ToInt(); 131 | int end = startAndEnd[1].ToInt(); 132 | 133 | if (startAndEnd.Length == 2 && start <= end) 134 | { 135 | uint offset = 0; 136 | 137 | for (int j = start; j <= end; j++) 138 | { 139 | Instructions[j].OpCode = target.Instructions[i].OpCode; 140 | 141 | if (Instructions[j].Operand != null) 142 | { 143 | Instructions[j].Operand = target.Instructions[i].Operand; 144 | } 145 | 146 | offset += (uint)Instructions[j].GetSize(); 147 | Instructions[j].Offset = offset; 148 | } 149 | } 150 | else 151 | { 152 | throw new PatcherException("Index Range format is incorrect (Correct format is startIndex...endIndex)", target.FullName); 153 | } 154 | } 155 | else 156 | { 157 | Instructions[target.Indices[i].ToInt()] = target.Instructions[i]; 158 | } 159 | } 160 | } 161 | else 162 | { 163 | throw new PatcherException("Instructions and Indices count must be equal", target.FullName); 164 | } 165 | } 166 | else if (target.Indices == null) 167 | { 168 | throw new PatcherException("No Indices specified", target.FullName); 169 | } 170 | else if (target.Instructions == null) 171 | { 172 | throw new PatcherException("No instructions specified", target.FullName); 173 | } 174 | } 175 | 176 | internal void Remove(Target target) 177 | { 178 | if (target.Indices != null) 179 | { 180 | foreach (string index in target.Indices.OrderByDescending(x => x)) 181 | { 182 | if (index.Contains(Constants.RangeExpressionSeparator)) 183 | { 184 | string[] startAndEnd = Regex.Split(input: index, Constants.RangeExpressionRegexPattern); 185 | 186 | int start = startAndEnd[0].ToInt(); 187 | int end = startAndEnd[1].ToInt(); 188 | 189 | if (startAndEnd.Length == 2 && start <= end) 190 | { 191 | var range = Enumerable.Range(start, end + 1 - start).OrderByDescending(x => x); 192 | 193 | foreach (int j in range) 194 | { 195 | Instructions.RemoveAt(j); 196 | } 197 | } 198 | else 199 | { 200 | throw new PatcherException("Index Range format is incorrect (Correct format is startIndex...endIndex)", target.FullName); 201 | } 202 | } 203 | else 204 | { 205 | Instructions.RemoveAt(int.Parse(index)); 206 | } 207 | } 208 | } 209 | else 210 | { 211 | throw new PatcherException("No Indices specified", target.FullName); 212 | } 213 | } 214 | 215 | internal void EmptyBody(Target target) 216 | { 217 | target.Instructions = new[] { Instruction.Create(OpCodes.Ret) }; 218 | PatchAndClear(target); 219 | } 220 | 221 | internal void ReturnBody(Target target, bool trueOrFalse) 222 | { 223 | if (trueOrFalse) 224 | { 225 | target.Instructions = new[] 226 | { 227 | Instruction.Create(OpCodes.Ldc_I4_1), 228 | Instruction.Create(OpCodes.Ret) 229 | }; 230 | } 231 | else 232 | { 233 | target.Instructions = new[] 234 | { 235 | Instruction.Create(OpCodes.Ldc_I4_0), 236 | Instruction.Create(OpCodes.Ret) 237 | }; 238 | } 239 | 240 | PatchAndClear(target); 241 | } 242 | 243 | internal void Save(bool backup) 244 | { 245 | string tempFile = string.Format("{0}.tmp", _file); 246 | string backupFile = string.Format("{0}.bak", _file); 247 | 248 | if (Module.IsILOnly) 249 | { 250 | if (_keepOldMaxStack) 251 | { 252 | Module.Write(tempFile, new ModuleWriterOptions(Module) 253 | { 254 | MetadataOptions = { Flags = MetadataFlags.KeepOldMaxStack } 255 | }); 256 | } 257 | else 258 | { 259 | Module.Write(tempFile); 260 | } 261 | } 262 | else 263 | { 264 | if (_keepOldMaxStack) 265 | { 266 | Module.NativeWrite(tempFile, new NativeModuleWriterOptions(Module, false) 267 | { 268 | MetadataOptions = 269 | { 270 | Flags = MetadataFlags.KeepOldMaxStack 271 | } 272 | }); 273 | } 274 | else 275 | { 276 | Module.NativeWrite(tempFile); 277 | } 278 | } 279 | 280 | Module?.Dispose(); 281 | 282 | if (backup) 283 | { 284 | if (!File.Exists(backupFile)) 285 | { 286 | File.Move(_file, backupFile); 287 | } 288 | else 289 | { 290 | Logger.Info(string.Format(Resources.Patcher_Save_Backup_file_already_exists_Msg, backupFile)); 291 | } 292 | } 293 | 294 | File.Delete(_file); 295 | File.Move(tempFile, _file); 296 | } 297 | 298 | internal IMethod FindMethod(string fullName) 299 | { 300 | foreach (var module in Module.Assembly.Modules) 301 | { 302 | foreach (var type in module.GetTypes()) 303 | { 304 | foreach (var method in type.Methods) 305 | { 306 | if (string.Equals(method.FullName, fullName, StringComparison.InvariantCultureIgnoreCase)) 307 | { 308 | return method; 309 | } 310 | } 311 | } 312 | } 313 | 314 | LoadCustomModule(ref fullName, out ModuleDefMD customModule); 315 | 316 | foreach (var module in customModule.Assembly.Modules) 317 | { 318 | foreach (var type in module.GetTypes()) 319 | { 320 | foreach (var method in type.Methods) 321 | { 322 | if (string.Equals(method.FullName, fullName, StringComparison.InvariantCultureIgnoreCase)) 323 | { 324 | return Module.Import(method); 325 | } 326 | } 327 | } 328 | } 329 | 330 | throw new PatcherException("Method not found", fullName); 331 | } 332 | 333 | internal IField FindField(string fullName) 334 | { 335 | foreach (var module in Module.Assembly.Modules) 336 | { 337 | foreach (var type in module.GetTypes()) 338 | { 339 | foreach (var field in type.Fields) 340 | { 341 | if (string.Equals(field.FullName, fullName, StringComparison.InvariantCultureIgnoreCase)) 342 | { 343 | return field; 344 | } 345 | } 346 | } 347 | } 348 | 349 | LoadCustomModule(ref fullName, out ModuleDefMD customModule); 350 | 351 | foreach (var module in customModule.Assembly.Modules) 352 | { 353 | foreach (var type in module.GetTypes()) 354 | { 355 | foreach (var field in type.Fields) 356 | { 357 | if (string.Equals(field.FullName, fullName, StringComparison.InvariantCultureIgnoreCase)) 358 | { 359 | return Module.Import(field); 360 | } 361 | } 362 | } 363 | } 364 | 365 | throw new PatcherException("Field not found", fullName); 366 | } 367 | 368 | internal IType FindType(string fullName) 369 | { 370 | foreach (var module in Module.Assembly.Modules) 371 | { 372 | foreach (var type in module.GetTypes()) 373 | { 374 | if (string.Equals(type.FullName, fullName, StringComparison.InvariantCultureIgnoreCase)) 375 | { 376 | return type; 377 | } 378 | } 379 | } 380 | 381 | LoadCustomModule(ref fullName, out ModuleDefMD customModule); 382 | 383 | foreach (var module in customModule.Assembly.Modules) 384 | { 385 | foreach (var type in module.GetTypes()) 386 | { 387 | if (string.Equals(type.FullName, fullName, StringComparison.InvariantCultureIgnoreCase)) 388 | { 389 | return Module.Import(type); 390 | } 391 | } 392 | } 393 | 394 | throw new PatcherException("Type not found", fullName); 395 | } 396 | 397 | internal IMemberRef FindMethodFieldOrType(string fullName) 398 | { 399 | foreach (var module in Module.Assembly.Modules) 400 | { 401 | foreach (var type in module.GetTypes()) 402 | { 403 | if (string.Equals(type.FullName, fullName, StringComparison.InvariantCultureIgnoreCase)) 404 | { 405 | return type; 406 | } 407 | 408 | foreach (var method in type.Methods) 409 | { 410 | if (string.Equals(method.FullName, fullName, StringComparison.InvariantCultureIgnoreCase)) 411 | { 412 | return method; 413 | } 414 | } 415 | 416 | foreach (var field in type.Fields) 417 | { 418 | if (string.Equals(field.FullName, fullName, StringComparison.InvariantCultureIgnoreCase)) 419 | { 420 | return field; 421 | } 422 | } 423 | } 424 | } 425 | 426 | LoadCustomModule(ref fullName, out ModuleDefMD customModule); 427 | 428 | foreach (var module in customModule.Assembly.Modules) 429 | { 430 | foreach (var type in module.GetTypes()) 431 | { 432 | if (string.Equals(type.FullName, fullName, StringComparison.InvariantCultureIgnoreCase)) 433 | { 434 | return Module.Import(type); 435 | } 436 | 437 | foreach (var method in type.Methods) 438 | { 439 | if (string.Equals(method.FullName, fullName, StringComparison.InvariantCultureIgnoreCase)) 440 | { 441 | return Module.Import(method); 442 | } 443 | } 444 | 445 | foreach (var field in type.Fields) 446 | { 447 | if (string.Equals(field.FullName, fullName, StringComparison.InvariantCultureIgnoreCase)) 448 | { 449 | return Module.Import(field); 450 | } 451 | } 452 | } 453 | } 454 | 455 | throw new PatcherException("Method, Field or Type not found", fullName); 456 | } 457 | 458 | internal void LoadCustomModule(ref string fullName, out ModuleDefMD customModule) 459 | { 460 | customModule = null; 461 | 462 | if (fullName.Contains(Constants.DefaultSeparator)) 463 | { 464 | string[] custom = fullName.Split(Constants.DefaultSeparator); 465 | 466 | if (custom.Length == 2) 467 | { 468 | if (!File.Exists(custom[0])) 469 | { 470 | custom[0] = Type.GetType(custom[0], false, true)?.Module.FullyQualifiedName; 471 | } 472 | 473 | customModule = ModuleDefMD.Load(custom[0]); 474 | fullName = custom[1]; 475 | } 476 | } 477 | else 478 | { 479 | customModule = ScriptEngineHelpers.MscorelibModule; 480 | } 481 | } 482 | 483 | internal void BackupExceptionHandlersIndices() 484 | { 485 | foreach (var exception in Method.Body.ExceptionHandlers) 486 | { 487 | _exceptionHandlersIndices.Add(string.Format("{0}|{1}|{2}|{3}|{4}", 488 | Instructions.IndexOf(exception.TryStart), Instructions.IndexOf(exception.TryEnd), 489 | Instructions.IndexOf(exception.HandlerStart), Instructions.IndexOf(exception.HandlerEnd), 490 | Instructions.IndexOf(exception.FilterStart))); 491 | } 492 | } 493 | 494 | internal void FixOffsets() 495 | { 496 | uint offset = 0; 497 | 498 | foreach (var instruction in Instructions) 499 | { 500 | instruction.Offset = offset; 501 | offset += (uint)instruction.GetSize(); 502 | } 503 | } 504 | 505 | internal void FixBranches() 506 | { 507 | foreach (var instruction in Instructions) 508 | { 509 | switch (instruction.OpCode.OperandType) 510 | { 511 | case OperandType.InlineBrTarget: 512 | case OperandType.ShortInlineBrTarget: 513 | var operand = (Instruction)instruction.Operand; 514 | 515 | if (operand != null) 516 | { 517 | instruction.Operand = GetInstruction(operand.Offset); 518 | } 519 | break; 520 | 521 | case OperandType.InlineSwitch: 522 | if (instruction.Operand is Instruction[] instructions) 523 | { 524 | var array = new Instruction[instructions.Length]; 525 | 526 | for (int j = 0; j < instructions.Length; j++) 527 | { 528 | array[j] = GetInstruction(instructions[j].Offset); 529 | } 530 | 531 | instruction.Operand = array; 532 | } 533 | break; 534 | } 535 | } 536 | } 537 | 538 | internal void FixExceptionHandlers() 539 | { 540 | for (var i = Method.Body.ExceptionHandlers.Count - 1; i >= 0; i--) 541 | { 542 | string[] indices = _exceptionHandlersIndices[i].Split('|'); 543 | 544 | var exception = Method.Body.ExceptionHandlers[i]; 545 | 546 | exception.TryStart = GetInstruction(int.Parse(indices[0])); 547 | exception.TryEnd = GetInstruction(int.Parse(indices[1])); 548 | 549 | exception.HandlerStart = GetInstruction(int.Parse(indices[2])); 550 | exception.HandlerEnd = GetInstruction(int.Parse(indices[3])); 551 | 552 | exception.FilterStart = GetInstruction(int.Parse(indices[0])); 553 | 554 | if (exception.TryStart == null || exception.TryEnd == null || exception.HandlerStart == null || exception.HandlerEnd == null) 555 | { 556 | Method.Body.ExceptionHandlers.RemoveAt(i); 557 | } 558 | } 559 | } 560 | 561 | internal Instruction GetInstruction(uint offset) 562 | { 563 | var instruction = Instructions.First(x => x.Offset == offset); 564 | 565 | if (instruction != null) 566 | { 567 | return instruction; 568 | } 569 | 570 | throw new Exception(string.Format(Resources.Patcher_GetInstruction_Instruction_not_found_Msg, offset)); 571 | } 572 | 573 | internal Instruction GetInstruction(int index) 574 | { 575 | if (index > -1 && index < Instructions.Count) 576 | { 577 | return Instructions[index]; 578 | } 579 | 580 | return null; 581 | } 582 | 583 | internal Instruction GetInstruction(Target target, int index) 584 | { 585 | if (index > -1 && index < target.Instructions.Length) 586 | { 587 | return target.Instructions[index]; 588 | } 589 | 590 | return null; 591 | } 592 | 593 | public void Dispose() 594 | { 595 | Module?.Dispose(); 596 | } 597 | } 598 | } -------------------------------------------------------------------------------- /DotNetUniversalPatcher/UI/FrmAddTarget.Designer.cs: -------------------------------------------------------------------------------- 1 | using DotNetUniversalPatcher.Properties; 2 | 3 | namespace DotNetUniversalPatcher.UI 4 | { 5 | partial class FrmAddTarget 6 | { 7 | /// 8 | /// Required designer variable. 9 | /// 10 | private System.ComponentModel.IContainer components = null; 11 | 12 | /// 13 | /// Clean up any resources being used. 14 | /// 15 | /// true if managed resources should be disposed; otherwise, false. 16 | protected override void Dispose(bool disposing) 17 | { 18 | if (disposing && (components != null)) 19 | { 20 | components.Dispose(); 21 | } 22 | base.Dispose(disposing); 23 | } 24 | 25 | #region Windows Form Designer generated code 26 | 27 | /// 28 | /// Required method for Designer support - do not modify 29 | /// the contents of this method with the code editor. 30 | /// 31 | private void InitializeComponent() 32 | { 33 | this.components = new System.ComponentModel.Container(); 34 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmAddTarget)); 35 | this.cmbActionMethod = new System.Windows.Forms.ComboBox(); 36 | this.lblAction = new System.Windows.Forms.Label(); 37 | this.txtFullName = new System.Windows.Forms.TextBox(); 38 | this.lblFullName = new System.Windows.Forms.Label(); 39 | this.lblIndex = new System.Windows.Forms.Label(); 40 | this.txtIndex = new System.Windows.Forms.TextBox(); 41 | this.lblOpCode = new System.Windows.Forms.Label(); 42 | this.cmsInstructions = new System.Windows.Forms.ContextMenuStrip(this.components); 43 | this.tsmiEditInstruction = new System.Windows.Forms.ToolStripMenuItem(); 44 | this.tsmiRemoveInstruction = new System.Windows.Forms.ToolStripMenuItem(); 45 | this.tsmiMoveUpInstruction = new System.Windows.Forms.ToolStripMenuItem(); 46 | this.tsmiMoveDownInstruction = new System.Windows.Forms.ToolStripMenuItem(); 47 | this.lblOperand = new System.Windows.Forms.Label(); 48 | this.txtOperand = new System.Windows.Forms.TextBox(); 49 | this.cmbOpCodes = new System.Windows.Forms.ComboBox(); 50 | this.lblOptional = new System.Windows.Forms.Label(); 51 | this.grpAddInstruction = new System.Windows.Forms.GroupBox(); 52 | this.btnClear = new System.Windows.Forms.Button(); 53 | this.btnAddTarget = new System.Windows.Forms.Button(); 54 | this.grpTarget = new System.Windows.Forms.GroupBox(); 55 | this.cmbOptional = new System.Windows.Forms.ComboBox(); 56 | this.grpInstructions = new System.Windows.Forms.GroupBox(); 57 | this.dgvInstructions = new System.Windows.Forms.DataGridView(); 58 | this.dgvcIndex = new System.Windows.Forms.DataGridViewTextBoxColumn(); 59 | this.dgvcOpCode = new System.Windows.Forms.DataGridViewTextBoxColumn(); 60 | this.dgvcOperand = new System.Windows.Forms.DataGridViewTextBoxColumn(); 61 | this.flpMain = new System.Windows.Forms.FlowLayoutPanel(); 62 | this.btnCancel = new System.Windows.Forms.Button(); 63 | this.btnSave = new System.Windows.Forms.Button(); 64 | this.cmsInstructions.SuspendLayout(); 65 | this.grpAddInstruction.SuspendLayout(); 66 | this.grpTarget.SuspendLayout(); 67 | this.grpInstructions.SuspendLayout(); 68 | ((System.ComponentModel.ISupportInitialize)(this.dgvInstructions)).BeginInit(); 69 | this.flpMain.SuspendLayout(); 70 | this.SuspendLayout(); 71 | // 72 | // cmbActionMethod 73 | // 74 | this.cmbActionMethod.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend; 75 | this.cmbActionMethod.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems; 76 | this.cmbActionMethod.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 77 | this.cmbActionMethod.FormattingEnabled = true; 78 | this.cmbActionMethod.Location = new System.Drawing.Point(89, 52); 79 | this.cmbActionMethod.Name = "cmbActionMethod"; 80 | this.cmbActionMethod.Size = new System.Drawing.Size(328, 25); 81 | this.cmbActionMethod.TabIndex = 3; 82 | this.cmbActionMethod.SelectedIndexChanged += new System.EventHandler(this.CmbActionMethod_SelectedIndexChanged); 83 | // 84 | // lblAction 85 | // 86 | this.lblAction.AutoSize = true; 87 | this.lblAction.Location = new System.Drawing.Point(8, 55); 88 | this.lblAction.Name = "lblAction"; 89 | this.lblAction.Size = new System.Drawing.Size(47, 17); 90 | this.lblAction.TabIndex = 2; 91 | this.lblAction.Text = Resources.FrmAddTarget_Action_Text; 92 | // 93 | // txtFullName 94 | // 95 | this.txtFullName.Location = new System.Drawing.Point(89, 21); 96 | this.txtFullName.Name = "txtFullName"; 97 | this.txtFullName.Size = new System.Drawing.Size(328, 25); 98 | this.txtFullName.TabIndex = 1; 99 | // 100 | // lblFullName 101 | // 102 | this.lblFullName.AutoSize = true; 103 | this.lblFullName.Location = new System.Drawing.Point(6, 24); 104 | this.lblFullName.Name = "lblFullName"; 105 | this.lblFullName.Size = new System.Drawing.Size(69, 17); 106 | this.lblFullName.TabIndex = 0; 107 | this.lblFullName.Text = Resources.FrmAddTarget_Full_Name_Text; 108 | // 109 | // lblIndex 110 | // 111 | this.lblIndex.AutoSize = true; 112 | this.lblIndex.Location = new System.Drawing.Point(6, 24); 113 | this.lblIndex.Name = "lblIndex"; 114 | this.lblIndex.Size = new System.Drawing.Size(42, 17); 115 | this.lblIndex.TabIndex = 0; 116 | this.lblIndex.Text = Resources.FrmAddTarget_Index_Text; 117 | // 118 | // txtIndex 119 | // 120 | this.txtIndex.Location = new System.Drawing.Point(89, 21); 121 | this.txtIndex.Name = "txtIndex"; 122 | this.txtIndex.Size = new System.Drawing.Size(328, 25); 123 | this.txtIndex.TabIndex = 1; 124 | // 125 | // lblOpCode 126 | // 127 | this.lblOpCode.AutoSize = true; 128 | this.lblOpCode.Location = new System.Drawing.Point(6, 55); 129 | this.lblOpCode.Name = "lblOpCode"; 130 | this.lblOpCode.Size = new System.Drawing.Size(60, 17); 131 | this.lblOpCode.TabIndex = 2; 132 | this.lblOpCode.Text = Resources.FrmAddTarget_OpCode_Text; 133 | // 134 | // cmsInstructions 135 | // 136 | this.cmsInstructions.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 137 | this.tsmiEditInstruction, 138 | this.tsmiRemoveInstruction, 139 | this.tsmiMoveUpInstruction, 140 | this.tsmiMoveDownInstruction}); 141 | this.cmsInstructions.Name = "cmsInstructions"; 142 | this.cmsInstructions.Size = new System.Drawing.Size(200, 92); 143 | // 144 | // tsmiEditInstruction 145 | // 146 | this.tsmiEditInstruction.Name = "tsmiEditInstruction"; 147 | this.tsmiEditInstruction.ShortcutKeys = System.Windows.Forms.Keys.F2; 148 | this.tsmiEditInstruction.Size = new System.Drawing.Size(199, 22); 149 | this.tsmiEditInstruction.Text = Resources.FrmAddTarget_Edit_Text; 150 | this.tsmiEditInstruction.Click += new System.EventHandler(this.TsmiEditInstruction_Click); 151 | // 152 | // tsmiRemoveInstruction 153 | // 154 | this.tsmiRemoveInstruction.Name = "tsmiRemoveInstruction"; 155 | this.tsmiRemoveInstruction.ShortcutKeys = System.Windows.Forms.Keys.Delete; 156 | this.tsmiRemoveInstruction.Size = new System.Drawing.Size(199, 22); 157 | this.tsmiRemoveInstruction.Text = Resources.FrmAddTarget_Remove_Text; 158 | this.tsmiRemoveInstruction.Click += new System.EventHandler(this.TsmiRemoveInstruction_Click); 159 | // 160 | // tsmiMoveUpInstruction 161 | // 162 | this.tsmiMoveUpInstruction.Name = "tsmiMoveUpInstruction"; 163 | this.tsmiMoveUpInstruction.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.Up))); 164 | this.tsmiMoveUpInstruction.Size = new System.Drawing.Size(199, 22); 165 | this.tsmiMoveUpInstruction.Text = Resources.FrmAddTarget_Move_Up_Text; 166 | this.tsmiMoveUpInstruction.Click += new System.EventHandler(this.TsmiMoveUpInstruction_Click); 167 | // 168 | // tsmiMoveDownInstruction 169 | // 170 | this.tsmiMoveDownInstruction.Name = "tsmiMoveDownInstruction"; 171 | this.tsmiMoveDownInstruction.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.Down))); 172 | this.tsmiMoveDownInstruction.Size = new System.Drawing.Size(199, 22); 173 | this.tsmiMoveDownInstruction.Text = Resources.FrmAddTarget_Move_Down_Text; 174 | this.tsmiMoveDownInstruction.Click += new System.EventHandler(this.TsmiMoveDownInstruction_Click); 175 | // 176 | // lblOperand 177 | // 178 | this.lblOperand.AutoSize = true; 179 | this.lblOperand.Location = new System.Drawing.Point(6, 86); 180 | this.lblOperand.Name = "lblOperand"; 181 | this.lblOperand.Size = new System.Drawing.Size(63, 17); 182 | this.lblOperand.TabIndex = 4; 183 | this.lblOperand.Text = Resources.FrmAddTarget_Operand_Text; 184 | // 185 | // txtOperand 186 | // 187 | this.txtOperand.Location = new System.Drawing.Point(89, 83); 188 | this.txtOperand.Name = "txtOperand"; 189 | this.txtOperand.Size = new System.Drawing.Size(328, 25); 190 | this.txtOperand.TabIndex = 5; 191 | // 192 | // cmbOpCodes 193 | // 194 | this.cmbOpCodes.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend; 195 | this.cmbOpCodes.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems; 196 | this.cmbOpCodes.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 197 | this.cmbOpCodes.FormattingEnabled = true; 198 | this.cmbOpCodes.Location = new System.Drawing.Point(89, 52); 199 | this.cmbOpCodes.Name = "cmbOpCodes"; 200 | this.cmbOpCodes.Size = new System.Drawing.Size(328, 25); 201 | this.cmbOpCodes.TabIndex = 3; 202 | this.cmbOpCodes.SelectedIndexChanged += new System.EventHandler(this.CmbOpCodes_SelectedIndexChanged); 203 | // 204 | // lblOptional 205 | // 206 | this.lblOptional.AutoSize = true; 207 | this.lblOptional.Location = new System.Drawing.Point(8, 87); 208 | this.lblOptional.Name = "lblOptional"; 209 | this.lblOptional.Size = new System.Drawing.Size(61, 17); 210 | this.lblOptional.TabIndex = 4; 211 | this.lblOptional.Text = Resources.FrmAddTarget_Optional_Text; 212 | // 213 | // grpAddInstruction 214 | // 215 | this.grpAddInstruction.Controls.Add(this.btnClear); 216 | this.grpAddInstruction.Controls.Add(this.txtIndex); 217 | this.grpAddInstruction.Controls.Add(this.btnAddTarget); 218 | this.grpAddInstruction.Controls.Add(this.lblIndex); 219 | this.grpAddInstruction.Controls.Add(this.lblOpCode); 220 | this.grpAddInstruction.Controls.Add(this.cmbOpCodes); 221 | this.grpAddInstruction.Controls.Add(this.lblOperand); 222 | this.grpAddInstruction.Controls.Add(this.txtOperand); 223 | this.grpAddInstruction.Location = new System.Drawing.Point(11, 128); 224 | this.grpAddInstruction.Name = "grpAddInstruction"; 225 | this.grpAddInstruction.Size = new System.Drawing.Size(430, 148); 226 | this.grpAddInstruction.TabIndex = 2; 227 | this.grpAddInstruction.TabStop = false; 228 | this.grpAddInstruction.Text = Resources.FrmAddTarget_Add_Instruction_Text; 229 | // 230 | // btnClear 231 | // 232 | this.btnClear.Location = new System.Drawing.Point(256, 115); 233 | this.btnClear.Name = "btnClear"; 234 | this.btnClear.Size = new System.Drawing.Size(161, 27); 235 | this.btnClear.TabIndex = 7; 236 | this.btnClear.Text = Resources.FrmAddTarget_Clear_Text; 237 | this.btnClear.UseVisualStyleBackColor = true; 238 | this.btnClear.Click += new System.EventHandler(this.BtnClear_Click); 239 | // 240 | // btnAddTarget 241 | // 242 | this.btnAddTarget.Location = new System.Drawing.Point(89, 115); 243 | this.btnAddTarget.Name = "btnAddTarget"; 244 | this.btnAddTarget.Size = new System.Drawing.Size(161, 27); 245 | this.btnAddTarget.TabIndex = 6; 246 | this.btnAddTarget.Text = Resources.FrmAddTarget_Add_Text; 247 | this.btnAddTarget.UseVisualStyleBackColor = true; 248 | this.btnAddTarget.Click += new System.EventHandler(this.BtnAddTarget_Click); 249 | // 250 | // grpTarget 251 | // 252 | this.grpTarget.Controls.Add(this.cmbOptional); 253 | this.grpTarget.Controls.Add(this.lblAction); 254 | this.grpTarget.Controls.Add(this.cmbActionMethod); 255 | this.grpTarget.Controls.Add(this.lblOptional); 256 | this.grpTarget.Controls.Add(this.txtFullName); 257 | this.grpTarget.Controls.Add(this.lblFullName); 258 | this.grpTarget.Location = new System.Drawing.Point(11, 3); 259 | this.grpTarget.Name = "grpTarget"; 260 | this.grpTarget.Size = new System.Drawing.Size(430, 119); 261 | this.grpTarget.TabIndex = 1; 262 | this.grpTarget.TabStop = false; 263 | this.grpTarget.Text = Resources.FrmAddTarget_Target_Text; 264 | // 265 | // cmbOptional 266 | // 267 | this.cmbOptional.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend; 268 | this.cmbOptional.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems; 269 | this.cmbOptional.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 270 | this.cmbOptional.Enabled = false; 271 | this.cmbOptional.FormattingEnabled = true; 272 | this.cmbOptional.Items.AddRange(new object[] { 273 | "True", 274 | "False"}); 275 | this.cmbOptional.Location = new System.Drawing.Point(89, 84); 276 | this.cmbOptional.Name = "cmbOptional"; 277 | this.cmbOptional.Size = new System.Drawing.Size(328, 25); 278 | this.cmbOptional.TabIndex = 5; 279 | // 280 | // grpInstructions 281 | // 282 | this.grpInstructions.Controls.Add(this.dgvInstructions); 283 | this.grpInstructions.Location = new System.Drawing.Point(11, 282); 284 | this.grpInstructions.Name = "grpInstructions"; 285 | this.grpInstructions.Size = new System.Drawing.Size(430, 199); 286 | this.grpInstructions.TabIndex = 3; 287 | this.grpInstructions.TabStop = false; 288 | this.grpInstructions.Text = Resources.FrmAddTarget_Instructions_Text; 289 | // 290 | // dgvInstructions 291 | // 292 | this.dgvInstructions.AllowUserToAddRows = false; 293 | this.dgvInstructions.AllowUserToDeleteRows = false; 294 | this.dgvInstructions.AllowUserToResizeRows = false; 295 | this.dgvInstructions.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill; 296 | this.dgvInstructions.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.AllCells; 297 | this.dgvInstructions.BackgroundColor = System.Drawing.Color.White; 298 | this.dgvInstructions.BorderStyle = System.Windows.Forms.BorderStyle.None; 299 | this.dgvInstructions.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 300 | this.dgvInstructions.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { 301 | this.dgvcIndex, 302 | this.dgvcOpCode, 303 | this.dgvcOperand}); 304 | this.dgvInstructions.ContextMenuStrip = this.cmsInstructions; 305 | this.dgvInstructions.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically; 306 | this.dgvInstructions.Location = new System.Drawing.Point(9, 20); 307 | this.dgvInstructions.MultiSelect = false; 308 | this.dgvInstructions.Name = "dgvInstructions"; 309 | this.dgvInstructions.RowHeadersVisible = false; 310 | this.dgvInstructions.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; 311 | this.dgvInstructions.Size = new System.Drawing.Size(408, 173); 312 | this.dgvInstructions.TabIndex = 0; 313 | // 314 | // dgvcIndex 315 | // 316 | this.dgvcIndex.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; 317 | this.dgvcIndex.HeaderText = Resources.FrmAddTarget_Index_HeaderText; 318 | this.dgvcIndex.Name = "dgvcIndex"; 319 | this.dgvcIndex.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; 320 | this.dgvcIndex.Width = 45; 321 | // 322 | // dgvcOpCode 323 | // 324 | this.dgvcOpCode.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; 325 | this.dgvcOpCode.HeaderText = Resources.FrmAddTarget_OpCode_HeaderText; 326 | this.dgvcOpCode.Name = "dgvcOpCode"; 327 | this.dgvcOpCode.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; 328 | this.dgvcOpCode.Width = 63; 329 | // 330 | // dgvcOperand 331 | // 332 | this.dgvcOperand.HeaderText = Resources.FrmAddTarget_Operand_HeaderText; 333 | this.dgvcOperand.Name = "dgvcOperand"; 334 | this.dgvcOperand.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; 335 | // 336 | // flpMain 337 | // 338 | this.flpMain.Controls.Add(this.grpTarget); 339 | this.flpMain.Controls.Add(this.grpAddInstruction); 340 | this.flpMain.Controls.Add(this.grpInstructions); 341 | this.flpMain.Controls.Add(this.btnCancel); 342 | this.flpMain.Controls.Add(this.btnSave); 343 | this.flpMain.Dock = System.Windows.Forms.DockStyle.Fill; 344 | this.flpMain.Location = new System.Drawing.Point(0, 0); 345 | this.flpMain.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); 346 | this.flpMain.Name = "flpMain"; 347 | this.flpMain.Padding = new System.Windows.Forms.Padding(8, 0, 8, 7); 348 | this.flpMain.Size = new System.Drawing.Size(454, 524); 349 | this.flpMain.TabIndex = 0; 350 | // 351 | // btnCancel 352 | // 353 | this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; 354 | this.btnCancel.Location = new System.Drawing.Point(11, 487); 355 | this.btnCancel.Name = "btnCancel"; 356 | this.btnCancel.Size = new System.Drawing.Size(212, 27); 357 | this.btnCancel.TabIndex = 4; 358 | this.btnCancel.Text = Resources.FrmAddTarget_Cancel_Text; 359 | this.btnCancel.UseVisualStyleBackColor = true; 360 | this.btnCancel.Click += new System.EventHandler(this.BtnCancel_Click); 361 | // 362 | // btnSave 363 | // 364 | this.btnSave.Location = new System.Drawing.Point(229, 487); 365 | this.btnSave.Name = "btnSave"; 366 | this.btnSave.Size = new System.Drawing.Size(212, 27); 367 | this.btnSave.TabIndex = 0; 368 | this.btnSave.Text = Resources.FrmAddTarget_Save_Text; 369 | this.btnSave.UseVisualStyleBackColor = true; 370 | this.btnSave.Click += new System.EventHandler(this.BtnSave_Click); 371 | // 372 | // FrmAddTarget 373 | // 374 | this.AcceptButton = this.btnSave; 375 | this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); 376 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 377 | this.ClientSize = new System.Drawing.Size(454, 524); 378 | this.Controls.Add(this.flpMain); 379 | this.Font = new System.Drawing.Font("Segoe UI", 9.75F); 380 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 381 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 382 | this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); 383 | this.MaximizeBox = false; 384 | this.Name = "FrmAddTarget"; 385 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 386 | this.Text = Resources.FrmAddTarget_Add_Target_Text; 387 | this.Load += new System.EventHandler(this.FrmAddTarget_Load); 388 | this.cmsInstructions.ResumeLayout(false); 389 | this.grpAddInstruction.ResumeLayout(false); 390 | this.grpAddInstruction.PerformLayout(); 391 | this.grpTarget.ResumeLayout(false); 392 | this.grpTarget.PerformLayout(); 393 | this.grpInstructions.ResumeLayout(false); 394 | ((System.ComponentModel.ISupportInitialize)(this.dgvInstructions)).EndInit(); 395 | this.flpMain.ResumeLayout(false); 396 | this.ResumeLayout(false); 397 | 398 | } 399 | 400 | #endregion 401 | 402 | private System.Windows.Forms.ComboBox cmbActionMethod; 403 | private System.Windows.Forms.Label lblAction; 404 | private System.Windows.Forms.TextBox txtFullName; 405 | private System.Windows.Forms.Label lblFullName; 406 | private System.Windows.Forms.Label lblIndex; 407 | private System.Windows.Forms.TextBox txtIndex; 408 | private System.Windows.Forms.Label lblOpCode; 409 | private System.Windows.Forms.Label lblOperand; 410 | private System.Windows.Forms.TextBox txtOperand; 411 | private System.Windows.Forms.ComboBox cmbOpCodes; 412 | private System.Windows.Forms.Label lblOptional; 413 | private System.Windows.Forms.GroupBox grpAddInstruction; 414 | private System.Windows.Forms.GroupBox grpTarget; 415 | private System.Windows.Forms.GroupBox grpInstructions; 416 | private System.Windows.Forms.Button btnAddTarget; 417 | private System.Windows.Forms.FlowLayoutPanel flpMain; 418 | private System.Windows.Forms.Button btnClear; 419 | private System.Windows.Forms.ContextMenuStrip cmsInstructions; 420 | private System.Windows.Forms.ToolStripMenuItem tsmiRemoveInstruction; 421 | private System.Windows.Forms.ComboBox cmbOptional; 422 | private System.Windows.Forms.ToolStripMenuItem tsmiEditInstruction; 423 | private System.Windows.Forms.Button btnCancel; 424 | internal System.Windows.Forms.Button btnSave; 425 | private System.Windows.Forms.DataGridView dgvInstructions; 426 | private System.Windows.Forms.DataGridViewTextBoxColumn dgvcIndex; 427 | private System.Windows.Forms.DataGridViewTextBoxColumn dgvcOpCode; 428 | private System.Windows.Forms.DataGridViewTextBoxColumn dgvcOperand; 429 | private System.Windows.Forms.ToolStripMenuItem tsmiMoveUpInstruction; 430 | private System.Windows.Forms.ToolStripMenuItem tsmiMoveDownInstruction; 431 | } 432 | } --------------------------------------------------------------------------------