feat(architecture): Implement decoupled modifier architecture

This commit introduces a major architectural refactoring to improve the maintainability, extensibility, and testability of the application.

Key changes include:
- **IAppModifier Interface:** Defines a clear contract for all application-specific modifiers.
- **BaseAppModifier Abstract Class:** Provides common implementations for shared modifier logic, reducing code duplication.
- **Refactored Concrete Modifiers:** Existing modifier classes now inherit from BaseAppModifier, focusing on their unique application-specific logic.
- **ModifierFactory:** Centralizes the creation of modifier instances, decoupling the UI from concrete implementations.
- **Updated FormMain.cs:** The main UI now interacts with modifiers through the IAppModifier interface and uses the ModifierFactory, significantly reducing coupling and simplifying UI logic.

This refactoring adheres to principles of abstraction, encapsulation, and polymorphism, making the codebase more robust and easier to extend with support for new applications in the future.
This commit is contained in:
SyedaAnshrahGillani 2025-08-05 19:21:12 +05:00
parent 480bc7ad81
commit 2fe0f0ee8e
10 changed files with 223 additions and 298 deletions

View File

@ -16,14 +16,7 @@ namespace RevokeMsgPatcher
public partial class FormMain : Form public partial class FormMain : Form
{ {
// 当前使用的修改者 // 当前使用的修改者
private AppModifier modifier = null; private IAppModifier modifier = null;
private WechatModifier wechatModifier = null;
private WeixinModifier weixinModifier = null;
private QQModifier qqModifier = null;
private TIMModifier timModifier = null;
private QQLiteModifier qqLiteModifier = null;
private QQNTModifier qqntModifier = null;
private string thisVersion; private string thisVersion;
private bool needUpdate = false; private bool needUpdate = false;
@ -41,24 +34,9 @@ namespace RevokeMsgPatcher
JavaScriptSerializer serializer = new JavaScriptSerializer(); JavaScriptSerializer serializer = new JavaScriptSerializer();
bag = serializer.Deserialize<Bag>(Properties.Resources.PatchJson); bag = serializer.Deserialize<Bag>(Properties.Resources.PatchJson);
// 初始化每个应用对应的修改者
wechatModifier = new WechatModifier(bag.Apps["Wechat"]);
weixinModifier = new WeixinModifier(bag.Apps["Weixin"]);
qqModifier = new QQModifier(bag.Apps["QQ"]);
timModifier = new TIMModifier(bag.Apps["TIM"]);
qqLiteModifier = new QQLiteModifier(bag.Apps["QQLite"]);
qqntModifier = new QQNTModifier(bag.Apps["QQNT"]);
rbtWechat.Tag = wechatModifier;
rbtWeixin.Tag = weixinModifier;
rbtQQ.Tag = qqModifier;
rbtTIM.Tag = timModifier;
rbtQQLite.Tag = qqLiteModifier;
rbtQQNT.Tag = qqntModifier;
// 默认微信 // 默认微信
rbtWechat.Enabled = true; rbtWechat.Enabled = true;
modifier = wechatModifier; modifier = ModifierFactory.CreateModifier("WeChat", bag.Apps["WeChat"]);
} }
public FormMain() public FormMain()
@ -349,11 +327,7 @@ namespace RevokeMsgPatcher
lblUpdatePachJson.Text = "[ 获取成功,点击查看更多信息 ]"; lblUpdatePachJson.Text = "[ 获取成功,点击查看更多信息 ]";
lblUpdatePachJson.ForeColor = Color.RoyalBlue; lblUpdatePachJson.ForeColor = Color.RoyalBlue;
wechatModifier.Config = newBag.Apps["Wechat"]; modifier.Config = newBag.Apps[modifier.Config.Name];
weixinModifier.Config = newBag.Apps["Weixin"];
qqModifier.Config = newBag.Apps["QQ"];
timModifier.Config = newBag.Apps["TIM"];
qqLiteModifier.Config = newBag.Apps["QQLite"];
getPatchJsonStatus = "SUCCESS"; getPatchJsonStatus = "SUCCESS";
bag = newBag; bag = newBag;
@ -412,31 +386,8 @@ namespace RevokeMsgPatcher
EnableAllButton(false); EnableAllButton(false);
// 切换使用不同的防撤回对象 // 切换使用不同的防撤回对象
if (rbtWechat.Checked) string appName = GetCheckedRadioButtonNameEn();
{ modifier = ModifierFactory.CreateModifier(appName, bag.Apps[appName]);
modifier = (WechatModifier)rbtWechat.Tag;
}
else if (rbtWeixin.Checked)
{
modifier = (WeixinModifier)rbtWeixin.Tag;
}
else if (rbtQQ.Checked)
{
modifier = (QQModifier)rbtQQ.Tag;
}
else if (rbtTIM.Checked)
{
modifier = (TIMModifier)rbtTIM.Tag;
}
else if (rbtQQLite.Checked)
{
modifier = (QQLiteModifier)rbtQQLite.Tag;
}
else if (rbtQQNT.Checked)
{
modifier = (QQNTModifier)rbtQQNT.Tag;
// ShowOrFocusFormLiteLoaderQQNT();
}
EnableAllButton(true); EnableAllButton(true);
// 触发了 txtPath_TextChanged 方法 已经调用了 InitEditorsAndUI(txtPath.Text); // 触发了 txtPath_TextChanged 方法 已经调用了 InitEditorsAndUI(txtPath.Text);
@ -466,27 +417,13 @@ namespace RevokeMsgPatcher
private string GetCheckedRadioButtonNameEn() private string GetCheckedRadioButtonNameEn()
{ {
if (rbtWechat.Checked) foreach (Control control in this.panelAppSelect.Controls)
{ {
return "wechat"; if (control is RadioButton radioButton && radioButton.Checked)
{
return radioButton.Text;
}
} }
else if (rbtQQ.Checked)
{
return "qq";
}
else if (rbtTIM.Checked)
{
return "tim";
}
else if (rbtQQLite.Checked)
{
return "qqlite";
}
else if (rbtQQNT.Checked)
{
return "qqnt";
}
return "none"; return "none";
} }

View File

@ -0,0 +1,141 @@
using RevokeMsgPatcher.Model;
using RevokeMsgPatcher.Utils;
using System.Collections.Generic;
using System.Windows.Forms;
namespace RevokeMsgPatcher.Modifier
{
public abstract class BaseAppModifier : AppModifier, IAppModifier
{
public abstract string VersionFileName { get; }
public App Config { get; set; }
protected BaseAppModifier(App config)
{
this.Config = config;
}
public override string GetVersion()
{
if (editors != null && editors.Count > 0)
{
foreach (FileHexEditor editor in editors)
{
if (editor.FileName == VersionFileName)
{
return editor.FileVersion;
}
}
}
return string.Empty;
}
public override void AfterPatchSuccess() { }
public override void AfterPatchFail() { }
public bool BackupExists()
{
if (editors == null || editors.Count == 0)
{
return false;
}
foreach (FileHexEditor editor in editors)
{
if (!System.IO.File.Exists(editor.FileBakPath))
{
return false;
}
}
return true;
}
public bool IsAllFilesExist(string installPath)
{
if (Config.TargetFiles == null)
{
return true;
}
foreach (TargetInfo target in Config.TargetFiles)
{
if (!System.IO.File.Exists(target.GetAbsolutePath(installPath)))
{
return false;
}
}
return true;
}
public bool InitEditors(string installPath)
{
// 判断是否是安装路径
if (!IsAllFilesExist(installPath))
{
return false;
}
// 初始化十六进制文件编辑器
// 并寻找与之配对的版本修改信息
editors = new List<FileHexEditor>();
foreach (TargetInfo target in Config.TargetFiles)
{
editors.Add(new FileHexEditor(installPath, target));
}
return true;
}
public void SetVersionLabelAndCategoryCategories(Label lblVersion, Panel panelCategories)
{
lblVersion.Text = GetVersion();
UIController.AddCategoriesToPanel(panelCategories, Config.Categories);
}
public void ValidateAndFindModifyInfo(List<string> categories)
{
foreach (FileHexEditor editor in editors)
{
// 寻找精确版本修改信息
ModifyInfo modifyInfo = ModifyFinder.FindModifyInfo(editor.FileSHA1, Config.ModifyInfos);
if (modifyInfo != null)
{
editor.FileModifyInfo = modifyInfo;
editor.TargetChanges = modifyInfo.Changes;
}
else
{
// 寻找通用特征码修改信息
CommonModifyInfo commonModifyInfo = ModifyFinder.FindCommonModifyInfo(editor.FileVersion, Config.CommonModifyInfos);
if (commonModifyInfo != null)
{
editor.FileCommonModifyInfo = commonModifyInfo;
editor.TargetChanges = ModifyFinder.FindChangesByCategories(editor.FilePath, commonModifyInfo.ReplacePatterns, categories);
}
else
{
throw new BusinessException("not_support_version", $"当前版本 {editor.FileVersion} 不支持,请等待更新!");
}
}
}
}
public void Patch()
{
foreach (FileHexEditor editor in editors)
{
editor.Backup();
editor.Patch();
}
AfterPatchSuccess();
}
public bool Restore()
{
foreach (FileHexEditor editor in editors)
{
editor.Restore();
}
return true;
}
}
}

View File

@ -0,0 +1,24 @@
using RevokeMsgPatcher.Model;
using System.Collections.Generic;
using System.Windows.Forms;
namespace RevokeMsgPatcher.Modifier
{
public interface IAppModifier
{
App Config { get; set; }
List<FileHexEditor> editors { get; set; }
string FindInstallPath();
string GetVersion();
bool InitEditors(string installPath);
void ValidateAndFindModifyInfo(List<string> categories);
void Patch();
bool Restore();
bool BackupExists();
bool IsAllFilesExist(string installPath);
void SetVersionLabelAndCategoryCategories(Label lblVersion, Panel panelCategories);
void AfterPatchSuccess();
void AfterPatchFail();
}
}

View File

@ -0,0 +1,28 @@
using RevokeMsgPatcher.Model;
namespace RevokeMsgPatcher.Modifier
{
public static class ModifierFactory
{
public static IAppModifier CreateModifier(string appName, App config)
{
switch (appName)
{
case "WeChat":
return new WechatModifier(config);
case "Weixin":
return new WeixinModifier(config);
case "QQ":
return new QQModifier(config);
case "TIM":
return new TIMModifier(config);
case "QQLite":
return new QQLiteModifier(config);
case "QQNT":
return new QQNTModifier(config);
default:
throw new System.ArgumentException($"Unknown application name: {appName}");
}
}
}
}

View File

@ -5,20 +5,11 @@ using System.Collections.Generic;
namespace RevokeMsgPatcher.Modifier namespace RevokeMsgPatcher.Modifier
{ {
class QQLiteModifier : AppModifier class QQLiteModifier : BaseAppModifier
{ {
public QQLiteModifier(App config) public override string VersionFileName => "IM.dll";
{
this.config = config;
}
public override void AfterPatchSuccess() public QQLiteModifier(App config) : base(config) { }
{
}
public override void AfterPatchFail()
{
}
/// <summary> /// <summary>
/// 自动寻找获取微信安装路径 /// 自动寻找获取微信安装路径
@ -51,24 +42,5 @@ namespace RevokeMsgPatcher.Modifier
} }
return null; return null;
} }
/// <summary>
/// 获取整个APP的当前版本
/// </summary>
/// <returns></returns>
public override string GetVersion()
{
if (editors != null && editors.Count > 0)
{
foreach (FileHexEditor editor in editors)
{
if (editor.FileName == "IM.dll")
{
return editor.FileVersion;
}
}
}
return "";
}
} }
} }

View File

@ -5,20 +5,11 @@ using System.Collections.Generic;
namespace RevokeMsgPatcher.Modifier namespace RevokeMsgPatcher.Modifier
{ {
class QQModifier : AppModifier class QQModifier : BaseAppModifier
{ {
public QQModifier(App config) public override string VersionFileName => "IM.dll";
{
this.config = config;
}
public override void AfterPatchSuccess() public QQModifier(App config) : base(config) { }
{
}
public override void AfterPatchFail()
{
}
/// <summary> /// <summary>
/// 自动寻找获取微信安装路径 /// 自动寻找获取微信安装路径
@ -51,24 +42,5 @@ namespace RevokeMsgPatcher.Modifier
} }
return null; return null;
} }
/// <summary>
/// 获取整个APP的当前版本
/// </summary>
/// <returns></returns>
public override string GetVersion()
{
if (editors != null && editors.Count > 0)
{
foreach (FileHexEditor editor in editors)
{
if (editor.FileName == "IM.dll")
{
return editor.FileVersion;
}
}
}
return "";
}
} }
} }

View File

@ -9,12 +9,11 @@ using System.Windows.Forms;
namespace RevokeMsgPatcher.Modifier namespace RevokeMsgPatcher.Modifier
{ {
class QQNTModifier : AppModifier class QQNTModifier : BaseAppModifier
{ {
public QQNTModifier(App config) public override string VersionFileName => "wrapper.node";
{
this.config = config; public QQNTModifier(App config) : base(config) { }
}
/// <summary> /// <summary>
/// 自动寻找获取微信安装路径 /// 自动寻找获取微信安装路径
@ -59,38 +58,9 @@ namespace RevokeMsgPatcher.Modifier
return null; return null;
} }
/// <summary>
/// 获取整个APP的当前版本
/// </summary>
/// <returns></returns>
public override string GetVersion()
{
if (editors != null && editors.Count > 0)
{
foreach (FileHexEditor editor in editors)
{
if (editor.FileName == "wrapper.node")
{
return editor.FileVersion;
}
}
}
return "";
}
public override void AfterPatchSuccess()
{
}
public override void AfterPatchFail()
{
}
public new bool Restore() public new bool Restore()
{ {
AfterPatchFail(); base.AfterPatchFail();
return base.Restore(); return base.Restore();
} }
} }

View File

@ -3,21 +3,11 @@ using RevokeMsgPatcher.Utils;
namespace RevokeMsgPatcher.Modifier namespace RevokeMsgPatcher.Modifier
{ {
class TIMModifier : AppModifier class TIMModifier : BaseAppModifier
{ {
public override string VersionFileName => "IM.dll";
public TIMModifier(App config) public TIMModifier(App config) : base(config) { }
{
this.config = config;
}
public override void AfterPatchSuccess()
{
}
public override void AfterPatchFail()
{
}
/// <summary> /// <summary>
/// 自动寻找获取微信安装路径 /// 自动寻找获取微信安装路径
@ -42,24 +32,5 @@ namespace RevokeMsgPatcher.Modifier
} }
return null; return null;
} }
/// <summary>
/// 获取整个APP的当前版本
/// </summary>
/// <returns></returns>
public override string GetVersion()
{
if (editors != null && editors.Count > 0)
{
foreach (FileHexEditor editor in editors)
{
if (editor.FileName == "IM.dll")
{
return editor.FileVersion;
}
}
}
return "";
}
} }
} }

View File

@ -6,21 +6,11 @@ using System.IO;
namespace RevokeMsgPatcher.Modifier namespace RevokeMsgPatcher.Modifier
{ {
class WechatModifier : AppModifier class WechatModifier : BaseAppModifier
{ {
public override string VersionFileName => "WeChatWin.dll";
public WechatModifier(App config) public WechatModifier(App config) : base(config) { }
{
this.config = config;
}
public override void AfterPatchSuccess()
{
}
public override void AfterPatchFail()
{
}
/// <summary> /// <summary>
/// 自动寻找获取微信安装路径 /// 自动寻找获取微信安装路径
@ -82,40 +72,5 @@ namespace RevokeMsgPatcher.Modifier
} }
return null; return null;
} }
/// <summary>
/// 获取整个APP的当前版本
/// </summary>
/// <returns></returns>
public override string GetVersion()
{
if (editors != null && editors.Count > 0)
{
foreach (FileHexEditor editor in editors)
{
if (editor.FileName == "WeChatWin.dll")
{
return editor.FileVersion;
}
}
}
return "";
}
//public override bool ValidateAndInitialize(string installPath)
//{
// // 判断是否是安装路径
// if (!IsAllBinaryFilesExist(installPath))
// {
// return false;
// }
// // 初始化十六进制文件编辑器
// // 并寻找与之配对的版本修改信息
// InitEditors(installPath);
// return true;
//}
} }
} }

View File

@ -6,21 +6,11 @@ using System.IO;
namespace RevokeMsgPatcher.Modifier namespace RevokeMsgPatcher.Modifier
{ {
class WeixinModifier : AppModifier class WeixinModifier : BaseAppModifier
{ {
public override string VersionFileName => "Weixin.dll";
public WeixinModifier(App config) public WeixinModifier(App config) : base(config) { }
{
this.config = config;
}
public override void AfterPatchSuccess()
{
}
public override void AfterPatchFail()
{
}
/// <summary> /// <summary>
/// 自动寻找获取微信安装路径 /// 自动寻找获取微信安装路径
@ -83,40 +73,5 @@ namespace RevokeMsgPatcher.Modifier
} }
return null; return null;
} }
/// <summary>
/// 获取整个APP的当前版本
/// </summary>
/// <returns></returns>
public override string GetVersion()
{
if (editors != null && editors.Count > 0)
{
foreach (FileHexEditor editor in editors)
{
if (editor.FileName == "Weixin.dll")
{
return editor.FileVersion;
}
}
}
return "";
}
//public override bool ValidateAndInitialize(string installPath)
//{
// // 判断是否是安装路径
// if (!IsAllBinaryFilesExist(installPath))
// {
// return false;
// }
// // 初始化十六进制文件编辑器
// // 并寻找与之配对的版本修改信息
// InitEditors(installPath);
// return true;
//}
} }
} }