Merge pull request #730 from huiyadanli/feat-qqnt

安装 LiteLoaderQQNT 实现 QQNT 的防撤回
This commit is contained in:
辉鸭蛋 2024-06-15 09:22:18 +08:00 committed by GitHub
commit 193dec8810
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 378 additions and 36 deletions

File diff suppressed because one or more lines are too long

View File

@ -16,8 +16,8 @@ namespace RevokeMsgPatcher
return new Bag return new Bag
{ {
Apps = AppConfig(), Apps = AppConfig(),
LatestVersion = "1.7", LatestVersion = "1.8",
PatchVersion = 20240614, PatchVersion = 20240615,
Notice = "", Notice = "",
NoticeUrl = "", NoticeUrl = "",
}; };
@ -36,7 +36,8 @@ namespace RevokeMsgPatcher
{ "Wechat" , Wechat() }, { "Wechat" , Wechat() },
{ "QQ" , QQ() }, { "QQ" , QQ() },
{ "TIM" , TIM() }, { "TIM" , TIM() },
{ "QQLite" , QQLite() } { "QQLite" , QQLite() },
{ "QQNT" , QQNT() }
}; };
} }
@ -1344,5 +1345,49 @@ namespace RevokeMsgPatcher
} }
}; };
} }
public App QQNT()
{
return new App
{
Name = "QQNT",
FileTargetInfos = new Dictionary<string, TargetInfo>
{
{
"QQ.exe",
new TargetInfo
{
Name = "QQ.exe",
RelativePath = "QQ.exe"
}
}
},
FileCommonModifyInfos = new Dictionary<string, List<CommonModifyInfo>>
{
{
"QQ.exe",
new List<CommonModifyInfo>
{
new CommonModifyInfo
{
Name="QQ.exe",
StartVersion="9.9.10.00000",
EndVersion="",
ReplacePatterns = new List<ReplacePattern>
{
new ReplacePattern
{
Search = ByteUtil.HexStringToByteArray("48 89 CE 48 8B 11 4C 8B 41 08 49 29 D0 48 8B 49 18 E8 3F 3F 3F 3F"),
Replace = ByteUtil.HexStringToByteArray("48 89 CE 48 8B 11 4C 8B 41 08 49 29 D0 48 8B 49 18 B8 01 00 00 00"),
Category = "LiteLoaderQQNT+插件列表+防撤回"
}
}
}
}
}
}
};
}
} }
} }

View File

@ -95,6 +95,7 @@
<None Include="Data\1.5\patch.json" /> <None Include="Data\1.5\patch.json" />
<None Include="Data\1.6\patch.json" /> <None Include="Data\1.6\patch.json" />
<None Include="Data\1.7\patch.json" /> <None Include="Data\1.7\patch.json" />
<None Include="Data\1.8\patch.json" />
<None Include="Properties\Settings.settings"> <None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator> <Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput> <LastGenOutput>Settings.Designer.cs</LastGenOutput>

View File

@ -63,6 +63,7 @@
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.panelNotice = new System.Windows.Forms.Panel(); this.panelNotice = new System.Windows.Forms.Panel();
this.labelNotice = new System.Windows.Forms.Label(); this.labelNotice = new System.Windows.Forms.Label();
this.rbtQQNT = new System.Windows.Forms.RadioButton();
this.menuStrip1.SuspendLayout(); this.menuStrip1.SuspendLayout();
this.panelNotice.SuspendLayout(); this.panelNotice.SuspendLayout();
this.SuspendLayout(); this.SuspendLayout();
@ -185,7 +186,7 @@
// rbtQQ // rbtQQ
// //
this.rbtQQ.AutoSize = true; this.rbtQQ.AutoSize = true;
this.rbtQQ.Location = new System.Drawing.Point(142, 36); this.rbtQQ.Location = new System.Drawing.Point(190, 36);
this.rbtQQ.Name = "rbtQQ"; this.rbtQQ.Name = "rbtQQ";
this.rbtQQ.Size = new System.Drawing.Size(35, 16); this.rbtQQ.Size = new System.Drawing.Size(35, 16);
this.rbtQQ.TabIndex = 13; this.rbtQQ.TabIndex = 13;
@ -196,7 +197,7 @@
// rbtTIM // rbtTIM
// //
this.rbtTIM.AutoSize = true; this.rbtTIM.AutoSize = true;
this.rbtTIM.Location = new System.Drawing.Point(188, 36); this.rbtTIM.Location = new System.Drawing.Point(236, 36);
this.rbtTIM.Name = "rbtTIM"; this.rbtTIM.Name = "rbtTIM";
this.rbtTIM.Size = new System.Drawing.Size(41, 16); this.rbtTIM.Size = new System.Drawing.Size(41, 16);
this.rbtTIM.TabIndex = 14; this.rbtTIM.TabIndex = 14;
@ -216,7 +217,7 @@
// rbtQQLite // rbtQQLite
// //
this.rbtQQLite.AutoSize = true; this.rbtQQLite.AutoSize = true;
this.rbtQQLite.Location = new System.Drawing.Point(237, 36); this.rbtQQLite.Location = new System.Drawing.Point(285, 36);
this.rbtQQLite.Name = "rbtQQLite"; this.rbtQQLite.Name = "rbtQQLite";
this.rbtQQLite.Size = new System.Drawing.Size(71, 16); this.rbtQQLite.Size = new System.Drawing.Size(71, 16);
this.rbtQQLite.TabIndex = 18; this.rbtQQLite.TabIndex = 18;
@ -372,11 +373,23 @@
this.labelNotice.TabIndex = 0; this.labelNotice.TabIndex = 0;
this.labelNotice.Text = "测试测试测试测试"; this.labelNotice.Text = "测试测试测试测试";
// //
// rbtQQNT
//
this.rbtQQNT.AutoSize = true;
this.rbtQQNT.Location = new System.Drawing.Point(135, 36);
this.rbtQQNT.Name = "rbtQQNT";
this.rbtQQNT.Size = new System.Drawing.Size(47, 16);
this.rbtQQNT.TabIndex = 24;
this.rbtQQNT.Text = "QQNT";
this.rbtQQNT.UseVisualStyleBackColor = true;
this.rbtQQNT.CheckedChanged += new System.EventHandler(this.radioButtons_CheckedChanged);
//
// FormMain // FormMain
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(490, 169); this.ClientSize = new System.Drawing.Size(490, 169);
this.Controls.Add(this.rbtQQNT);
this.Controls.Add(this.panelNotice); this.Controls.Add(this.panelNotice);
this.Controls.Add(this.panelCategories); this.Controls.Add(this.panelCategories);
this.Controls.Add(this.lblCategory); this.Controls.Add(this.lblCategory);
@ -445,6 +458,7 @@
private System.Windows.Forms.ToolTip toolTip1; private System.Windows.Forms.ToolTip toolTip1;
private System.Windows.Forms.Panel panelNotice; private System.Windows.Forms.Panel panelNotice;
private System.Windows.Forms.Label labelNotice; private System.Windows.Forms.Label labelNotice;
private System.Windows.Forms.RadioButton rbtQQNT;
} }
} }

View File

@ -22,6 +22,7 @@ namespace RevokeMsgPatcher
private QQModifier qqModifier = null; private QQModifier qqModifier = null;
private TIMModifier timModifier = null; private TIMModifier timModifier = null;
private QQLiteModifier qqLiteModifier = null; private QQLiteModifier qqLiteModifier = null;
private QQNTModifier qqntModifier = null;
private string thisVersion; private string thisVersion;
private bool needUpdate = false; private bool needUpdate = false;
@ -42,11 +43,13 @@ namespace RevokeMsgPatcher
qqModifier = new QQModifier(bag.Apps["QQ"]); qqModifier = new QQModifier(bag.Apps["QQ"]);
timModifier = new TIMModifier(bag.Apps["TIM"]); timModifier = new TIMModifier(bag.Apps["TIM"]);
qqLiteModifier = new QQLiteModifier(bag.Apps["QQLite"]); qqLiteModifier = new QQLiteModifier(bag.Apps["QQLite"]);
qqntModifier = new QQNTModifier(bag.Apps["QQNT"]);
rbtWechat.Tag = wechatModifier; rbtWechat.Tag = wechatModifier;
rbtQQ.Tag = qqModifier; rbtQQ.Tag = qqModifier;
rbtTIM.Tag = timModifier; rbtTIM.Tag = timModifier;
rbtQQLite.Tag = qqLiteModifier; rbtQQLite.Tag = qqLiteModifier;
rbtQQNT.Tag = qqntModifier;
// 默认微信 // 默认微信
rbtWechat.Enabled = true; rbtWechat.Enabled = true;
@ -168,7 +171,7 @@ namespace RevokeMsgPatcher
{ {
DialogResult result = MessageBox.Show(@"防撤回(老) 和 防撤回带提示(新) 两个功能二选一即可! DialogResult result = MessageBox.Show(@"防撤回(老) 和 防撤回带提示(新) 两个功能二选一即可!
1. () 1. () ()
2. () 2. ()
a. a.
@ -218,7 +221,7 @@ namespace RevokeMsgPatcher
{ {
modifier.Patch(); modifier.Patch();
ga.RequestPageView($"{enName}/{version}/patch/succ", "补丁安装成功"); ga.RequestPageView($"{enName}/{version}/patch/succ", "补丁安装成功");
MessageBox.Show("补丁安装成功!"); MessageBox.Show("补丁安装成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
} }
catch (BusinessException ex) catch (BusinessException ex)
{ {
@ -277,7 +280,16 @@ namespace RevokeMsgPatcher
EnableAllButton(false); EnableAllButton(false);
try try
{ {
bool succ = modifier.Restore(); bool succ;
if (rbtQQNT.Checked)
{
succ = qqntModifier.Restore();
}
else
{
succ = modifier.Restore();
}
if (succ) if (succ)
{ {
MessageBox.Show("还原成功!"); MessageBox.Show("还原成功!");
@ -368,6 +380,7 @@ namespace RevokeMsgPatcher
tips += "支持以下版本" + Environment.NewLine; tips += "支持以下版本" + Environment.NewLine;
tips += " ➯ 微信:" + wechatModifier.Config.GetSupportVersionStr() + Environment.NewLine; tips += " ➯ 微信:" + wechatModifier.Config.GetSupportVersionStr() + Environment.NewLine;
tips += " ➯ QQNT" + qqntModifier.Config.GetSupportVersionStr() + Environment.NewLine;
tips += " ➯ QQ" + qqModifier.Config.GetSupportVersionStr() + Environment.NewLine; tips += " ➯ QQ" + qqModifier.Config.GetSupportVersionStr() + Environment.NewLine;
tips += " ➯ QQ轻聊版" + qqLiteModifier.Config.GetSupportVersionStr() + Environment.NewLine; tips += " ➯ QQ轻聊版" + qqLiteModifier.Config.GetSupportVersionStr() + Environment.NewLine;
tips += " ➯ TIM" + timModifier.Config.GetSupportVersionStr() + Environment.NewLine; tips += " ➯ TIM" + timModifier.Config.GetSupportVersionStr() + Environment.NewLine;
@ -406,6 +419,10 @@ namespace RevokeMsgPatcher
{ {
modifier = (QQLiteModifier)rbtQQLite.Tag; modifier = (QQLiteModifier)rbtQQLite.Tag;
} }
else if (rbtQQNT.Checked)
{
modifier = (QQNTModifier)rbtQQNT.Tag;
}
EnableAllButton(true); EnableAllButton(true);
// 触发了 txtPath_TextChanged 方法 已经调用了 InitEditorsAndUI(txtPath.Text); // 触发了 txtPath_TextChanged 方法 已经调用了 InitEditorsAndUI(txtPath.Text);
@ -433,6 +450,10 @@ namespace RevokeMsgPatcher
{ {
return "qqlite"; return "qqlite";
} }
else if (rbtQQNT.Checked)
{
return "qqnt";
}
return "none"; return "none";
} }

View File

@ -22,7 +22,11 @@ namespace RevokeMsgPatcher.Modifier
{ {
protected App config; protected App config;
public App Config { set { config = value; } get { return config; } } public App Config
{
set { config = value; }
get { return config; }
}
protected List<FileHexEditor> editors; protected List<FileHexEditor> editors;
@ -56,18 +60,22 @@ namespace RevokeMsgPatcher.Modifier
foreach (FileHexEditor editor in editors) // 多种文件 foreach (FileHexEditor editor in editors) // 多种文件
{ {
// 精确版本匹配 // 精确版本匹配
bool haven = false; if (config.FileModifyInfos != null && config.FileModifyInfos.Count > 0)
foreach (ModifyInfo modifyInfo in config.FileModifyInfos[editor.FileName]) // 多个版本信息
{ {
if (editor.FileVersion == modifyInfo.Version) bool haven = false;
foreach (ModifyInfo modifyInfo in config.FileModifyInfos[editor.FileName]) // 多个版本信息
{ {
haven = true; if (editor.FileVersion == modifyInfo.Version)
break; {
haven = true;
break;
}
}
if (haven)
{
i++;
} }
}
if (haven)
{
i++;
} }
} }
@ -102,16 +110,19 @@ namespace RevokeMsgPatcher.Modifier
categories.Add(c); categories.Add(c);
} }
} }
// 获取已经安装过的功能类型 // 获取已经安装过的功能类型
SortedSet<string> replaced = ModifyFinder.FindReplacedFunction(editor.FilePath, commonModifyInfo.ReplacePatterns); SortedSet<string> replaced = ModifyFinder.FindReplacedFunction(editor.FilePath, commonModifyInfo.ReplacePatterns);
foreach (string c in replaced) foreach (string c in replaced)
{ {
installed.Add(c); installed.Add(c);
} }
inRange = true; inRange = true;
break; break;
} }
} }
if (inRange) if (inRange)
{ {
j++; j++;
@ -123,6 +134,12 @@ namespace RevokeMsgPatcher.Modifier
if (j == editors.Count) if (j == editors.Count)
{ {
label.Text = version + "(支持特征防撤回)"; label.Text = version + "(支持特征防撤回)";
// QQNT 特殊处理
if (config.Name == "QQNT")
{
label.Text = version + "支持LiteLoader";
}
label.ForeColor = Color.LimeGreen; label.ForeColor = Color.LimeGreen;
UIController.AddCategoryCheckBoxToPanel(panel, categories.ToArray(), installed.ToArray()); UIController.AddCategoryCheckBoxToPanel(panel, categories.ToArray(), installed.ToArray());
} }
@ -132,7 +149,6 @@ namespace RevokeMsgPatcher.Modifier
label.ForeColor = Color.Red; label.ForeColor = Color.Red;
UIController.AddMsgToPanel(panel, "无功能选项"); UIController.AddMsgToPanel(panel, "无功能选项");
} }
} }
/// <summary> /// <summary>
@ -146,6 +162,7 @@ namespace RevokeMsgPatcher.Modifier
{ {
return false; return false;
} }
int success = 0, count = 0; int success = 0, count = 0;
foreach (TargetInfo info in config.FileTargetInfos.Values) foreach (TargetInfo info in config.FileTargetInfos.Values)
{ {
@ -159,6 +176,7 @@ namespace RevokeMsgPatcher.Modifier
} }
} }
} }
if (success == count && success >= 1) if (success == count && success >= 1)
{ {
return true; return true;
@ -189,6 +207,7 @@ namespace RevokeMsgPatcher.Modifier
{ {
Console.WriteLine("判断版本范围时出错:" + e.Message); Console.WriteLine("判断版本范围时出错:" + e.Message);
} }
return false; return false;
} }
@ -207,6 +226,7 @@ namespace RevokeMsgPatcher.Modifier
return commonModifyInfo; return commonModifyInfo;
} }
} }
return null; return null;
} }
@ -225,6 +245,7 @@ namespace RevokeMsgPatcher.Modifier
break; break;
} }
} }
if (i == editors.Count) if (i == editors.Count)
{ {
return true; return true;
@ -241,6 +262,8 @@ namespace RevokeMsgPatcher.Modifier
/// <param name="installPath">APP安装路径</param> /// <param name="installPath">APP安装路径</param>
public bool InitEditors(string installPath) public bool InitEditors(string installPath)
{ {
InstallPath = null;
// 初始化文件修改器 // 初始化文件修改器
editors = new List<FileHexEditor>(); editors = new List<FileHexEditor>();
foreach (TargetInfo info in config.FileTargetInfos.Values) foreach (TargetInfo info in config.FileTargetInfos.Values)
@ -253,11 +276,15 @@ namespace RevokeMsgPatcher.Modifier
editors.Add(editor); editors.Add(editor);
} }
} }
if (editors.Count == 0) if (editors.Count == 0)
{ {
MessageBox.Show("当前版本没有对应的文件修改信息,请确认补丁信息是否正常!"); MessageBox.Show("当前版本没有对应的文件修改信息,请确认补丁信息是否正常!");
return false; return false;
} }
InstallPath = installPath;
return true; return true;
} }
@ -272,26 +299,30 @@ namespace RevokeMsgPatcher.Modifier
{ {
// 通过SHA1和文件版本判断是否可以打补丁 根据不同结果返回不同的提示 // 通过SHA1和文件版本判断是否可以打补丁 根据不同结果返回不同的提示
ModifyInfo matchingSHA1Before = null, matchingSHA1After = null, matchingVersion = null; ModifyInfo matchingSHA1Before = null, matchingSHA1After = null, matchingVersion = null;
foreach (ModifyInfo modifyInfo in config.FileModifyInfos[editor.FileName]) // 多个版本信息 if (config.FileModifyInfos != null && config.FileModifyInfos.Count > 0)
{ {
if (modifyInfo.Name == editor.FileName) // 保险用的无用判断 foreach (ModifyInfo modifyInfo in config.FileModifyInfos[editor.FileName]) // 多个版本信息
{ {
if (editor.FileSHA1 == modifyInfo.SHA1After) if (modifyInfo.Name == editor.FileName) // 保险用的无用判断
{ {
matchingSHA1After = modifyInfo; if (editor.FileSHA1 == modifyInfo.SHA1After)
} {
else if (editor.FileSHA1 == modifyInfo.SHA1Before) matchingSHA1After = modifyInfo;
{ }
matchingSHA1Before = modifyInfo; else if (editor.FileSHA1 == modifyInfo.SHA1Before)
} {
matchingSHA1Before = modifyInfo;
}
if (editor.FileVersion == modifyInfo.Version) if (editor.FileVersion == modifyInfo.Version)
{ {
matchingVersion = modifyInfo; matchingVersion = modifyInfo;
}
} }
} }
} }
// 补丁前SHA1匹配上肯定是正确的dll // 补丁前SHA1匹配上肯定是正确的dll
if (matchingSHA1Before != null) if (matchingSHA1Before != null)
{ {
@ -299,6 +330,7 @@ namespace RevokeMsgPatcher.Modifier
editor.TargetChanges = matchingSHA1Before.Changes; editor.TargetChanges = matchingSHA1Before.Changes;
continue; continue;
} }
// 补丁后SHA1匹配上肯定已经打过补丁 // 补丁后SHA1匹配上肯定已经打过补丁
if (matchingSHA1After != null) if (matchingSHA1After != null)
{ {
@ -324,6 +356,7 @@ namespace RevokeMsgPatcher.Modifier
{ {
replacePatterns = editor.FileCommonModifyInfo.ReplacePatterns.Where(info => categories.Contains(info.Category)).ToList(); replacePatterns = editor.FileCommonModifyInfo.ReplacePatterns.Where(info => categories.Contains(info.Category)).ToList();
} }
// 如果能顺利得到 TargetChanges 不报错则可以使用特征替换方式 // 如果能顺利得到 TargetChanges 不报错则可以使用特征替换方式
editor.TargetChanges = ModifyFinder.FindChanges(editor.FilePath, replacePatterns); editor.TargetChanges = ModifyFinder.FindChanges(editor.FilePath, replacePatterns);
continue; continue;
@ -335,6 +368,7 @@ namespace RevokeMsgPatcher.Modifier
{ {
throw new BusinessException("not_support", $"不支持的文件:名称 {editor.FileName} 版本 {editor.FileVersion}"); throw new BusinessException("not_support", $"不支持的文件:名称 {editor.FileName} 版本 {editor.FileVersion}");
} }
// SHA1不匹配但是版本匹配可能dll已经被其他补丁程序修改过 // SHA1不匹配但是版本匹配可能dll已经被其他补丁程序修改过
if (matchingVersion != null) if (matchingVersion != null)
{ {
@ -357,6 +391,7 @@ namespace RevokeMsgPatcher.Modifier
{ {
throw new Exception("补丁安装失败,原因:无对应的文件修改器"); throw new Exception("补丁安装失败,原因:无对应的文件修改器");
} }
foreach (FileHexEditor editor in editors) foreach (FileHexEditor editor in editors)
{ {
if (editor == null) if (editor == null)
@ -364,11 +399,13 @@ namespace RevokeMsgPatcher.Modifier
throw new Exception("补丁安装失败,原因:文件修改器初始化失败!"); throw new Exception("补丁安装失败,原因:文件修改器初始化失败!");
} }
} }
// 再备份所有文件 // 再备份所有文件
foreach (FileHexEditor editor in editors) foreach (FileHexEditor editor in editors)
{ {
editor.Backup(); editor.Backup();
} }
// 打补丁! // 打补丁!
List<FileHexEditor> done = new List<FileHexEditor>(); // 已经打上补丁的 List<FileHexEditor> done = new List<FileHexEditor>(); // 已经打上补丁的
try try
@ -386,6 +423,8 @@ namespace RevokeMsgPatcher.Modifier
done.Add(editor); done.Add(editor);
} }
} }
AfterPatchSuccess();
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -394,8 +433,11 @@ namespace RevokeMsgPatcher.Modifier
{ {
editor.Restore(); editor.Restore();
} }
AfterPatchFail();
throw ex; throw ex;
} }
return true; return true;
} }
@ -408,6 +450,7 @@ namespace RevokeMsgPatcher.Modifier
return false; return false;
} }
} }
return true; return true;
} }
@ -440,6 +483,7 @@ namespace RevokeMsgPatcher.Modifier
editor.Restore(); editor.Restore();
} }
} }
return true; return true;
} }
else else
@ -447,5 +491,9 @@ namespace RevokeMsgPatcher.Modifier
throw new Exception("备份文件不存在,还原失败!"); throw new Exception("备份文件不存在,还原失败!");
} }
} }
public abstract void AfterPatchSuccess();
public abstract void AfterPatchFail();
} }
} }

View File

@ -12,6 +12,14 @@ namespace RevokeMsgPatcher.Modifier
this.config = config; this.config = config;
} }
public override void AfterPatchSuccess()
{
}
public override void AfterPatchFail()
{
}
/// <summary> /// <summary>
/// 自动寻找获取微信安装路径 /// 自动寻找获取微信安装路径
/// </summary> /// </summary>

View File

@ -12,6 +12,14 @@ namespace RevokeMsgPatcher.Modifier
this.config = config; this.config = config;
} }
public override void AfterPatchSuccess()
{
}
public override void AfterPatchFail()
{
}
/// <summary> /// <summary>
/// 自动寻找获取微信安装路径 /// 自动寻找获取微信安装路径
/// </summary> /// </summary>

View File

@ -0,0 +1,154 @@
using RevokeMsgPatcher.Model;
using RevokeMsgPatcher.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace RevokeMsgPatcher.Modifier
{
class QQNTModifier : AppModifier
{
public QQNTModifier(App config)
{
this.config = config;
}
/// <summary>
/// 自动寻找获取微信安装路径
/// </summary>
/// <returns></returns>
public override string FindInstallPath()
{
try
{
string installPath = PathUtil.FindInstallPathFromRegistryWOW6432Node("QQ");
if (!string.IsNullOrEmpty(installPath))
{
installPath = Path.GetDirectoryName(installPath);
if (IsAllFilesExist(installPath))
{
return installPath;
}
}
installPath = PathUtil.FindInstallPathFromRegistry("QQNT");
if (!IsAllFilesExist(installPath))
{
List<string> defaultPathList = PathUtil.GetDefaultInstallPaths(@"Tencent\QQNT");
foreach (string defaultPath in defaultPathList)
{
if (IsAllFilesExist(defaultPath))
{
return defaultPath;
}
}
}
else
{
return installPath;
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
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 == "QQ.exe")
{
return editor.FileVersion;
}
}
}
return "";
}
public string GetIndexJsPath()
{
if (string.IsNullOrEmpty(InstallPath))
{
throw new Exception("未获取到QQNT安装路径或者QQNT安装路径不合法");
}
string indexPath = Path.Combine(InstallPath, @"resources\app\app_launcher\index.js");
if (!File.Exists(indexPath))
{
throw new Exception("未找到index.js文件");
}
return indexPath;
}
public string GetLiteLoaderPath()
{
return Path.Combine(Application.StartupPath, @"LiteLoaderQQNT");
}
public override void AfterPatchSuccess()
{
string indexPath = GetIndexJsPath();
string content = File.ReadAllText(indexPath);
// 正则 require\(String.raw`.*`\);
string pattern = @"require\(String.raw`.*`\);";
string liteLoaderPath = GetLiteLoaderPath();
if (!File.Exists(liteLoaderPath))
{
MessageBox.Show("LiteLoaderQQNT文件夹不存在仅安装QQNT去验证补丁", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
string replacement = $"require(String.raw`{liteLoaderPath}`);";
if (Regex.IsMatch(content, pattern))
{
content = Regex.Replace(content, pattern, replacement);
}
else
{
content = replacement + "\n" + content;
}
File.WriteAllText(indexPath, content);
}
public override void AfterPatchFail()
{
try
{
string indexPath = GetIndexJsPath();
string content = File.ReadAllText(indexPath);
string pattern = @"require\(String.raw`.*`\);\n";
if (Regex.IsMatch(content, pattern))
{
content = Regex.Replace(content, pattern, "");
File.WriteAllText(indexPath, content);
}
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}
public new bool Restore()
{
AfterPatchFail();
return base.Restore();
}
}
}

View File

@ -10,6 +10,15 @@ namespace RevokeMsgPatcher.Modifier
{ {
this.config = config; this.config = config;
} }
public override void AfterPatchSuccess()
{
}
public override void AfterPatchFail()
{
}
/// <summary> /// <summary>
/// 自动寻找获取微信安装路径 /// 自动寻找获取微信安装路径
/// </summary> /// </summary>

View File

@ -14,6 +14,14 @@ namespace RevokeMsgPatcher.Modifier
this.config = config; this.config = config;
} }
public override void AfterPatchSuccess()
{
}
public override void AfterPatchFail()
{
}
/// <summary> /// <summary>
/// 自动寻找获取微信安装路径 /// 自动寻找获取微信安装路径
/// </summary> /// </summary>

View File

@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 // 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
// 方法是按如下所示使用“*”: : // 方法是按如下所示使用“*”: :
//[assembly: AssemblyVersion("1.0.*")] //[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.7")] [assembly: AssemblyVersion("1.8")]
[assembly: AssemblyFileVersion("1.7")] [assembly: AssemblyFileVersion("1.8")]

File diff suppressed because one or more lines are too long

View File

@ -81,6 +81,7 @@
<Compile Include="Modifier\AppModifier.cs" /> <Compile Include="Modifier\AppModifier.cs" />
<Compile Include="Modifier\FileHexEditor.cs" /> <Compile Include="Modifier\FileHexEditor.cs" />
<Compile Include="Modifier\QQLiteModifier.cs" /> <Compile Include="Modifier\QQLiteModifier.cs" />
<Compile Include="Modifier\QQNTModifier.cs" />
<Compile Include="Modifier\QQModifier.cs" /> <Compile Include="Modifier\QQModifier.cs" />
<Compile Include="Modifier\TIMModifier.cs" /> <Compile Include="Modifier\TIMModifier.cs" />
<Compile Include="Modifier\WechatModifier.cs" /> <Compile Include="Modifier\WechatModifier.cs" />

View File

@ -57,6 +57,30 @@ namespace RevokeMsgPatcher.Utils
return null; return null;
} }
public static string FindInstallPathFromRegistryWOW6432Node(string uninstallKeyName)
{
try
{
RegistryKey key = Registry.LocalMachine.OpenSubKey($@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{uninstallKeyName}");
if (key == null)
{
return null;
}
object installLocation = key.GetValue("UninstallString");
key.Close();
if (installLocation != null && !string.IsNullOrEmpty(installLocation.ToString()))
{
return installLocation.ToString();
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return null;
}
/// <summary> /// <summary>
/// 获取所有可能的默认安装路径 /// 获取所有可能的默认安装路径
/// </summary> /// </summary>