QQNT 防撤回使用新的方案

This commit is contained in:
辉鸭蛋 2025-08-04 00:53:43 +08:00
parent aec635dc39
commit 65c1e419e9
12 changed files with 132 additions and 119 deletions

File diff suppressed because one or more lines are too long

View File

@ -16,8 +16,8 @@ namespace RevokeMsgPatcher
return new Bag
{
Apps = AppConfig(),
LatestVersion = "2.0",
PatchVersion = 20241107,
LatestVersion = "2.1",
PatchVersion = 20250803,
Notice = "",
NoticeUrl = "",
};
@ -1377,32 +1377,33 @@ namespace RevokeMsgPatcher
FileTargetInfos = new Dictionary<string, TargetInfo>
{
{
"QQ.exe",
"wrapper.node",
new TargetInfo
{
Name = "QQ.exe",
RelativePath = "QQ.exe"
Name = "wrapper.node",
RelativePath = @"versions\{version}\resources\app\wrapper.node",
RelativePathForVersion = "QQ.exe"
}
}
},
FileCommonModifyInfos = new Dictionary<string, List<CommonModifyInfo>>
{
{
"QQ.exe",
"wrapper.node",
new List<CommonModifyInfo>
{
new CommonModifyInfo
{
Name="QQ.exe",
StartVersion="9.9.10.00000",
EndVersion="9.9.15.00000",
Name="wrapper.node",
StartVersion="9.8.0.19000",
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"
Search = ByteUtil.HexStringToByteArray("48 8B 95 3F 3F 3F 3F 4C 8B 85 3F 3F 3F 3F 4C 89 C0 48 29 D0 48 83 F8 07 0F 87"),
Replace = ByteUtil.HexStringToByteArray("48 8B 95 3F 3F 3F 3F 4C 8B 85 3F 3F 3F 3F 4C 89 C0 48 29 D0 48 83 F8 07 0F 86"),
Category = "群聊防撤回"
}
}
}

View File

@ -98,6 +98,7 @@
<None Include="Data\1.8\patch.json" />
<None Include="Data\1.9\patch.json" />
<None Include="Data\2.0\patch.json" />
<None Include="Data\2.1\patch.json" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>

View File

@ -435,7 +435,7 @@ namespace RevokeMsgPatcher
else if (rbtQQNT.Checked)
{
modifier = (QQNTModifier)rbtQQNT.Tag;
ShowOrFocusFormLiteLoaderQQNT();
// ShowOrFocusFormLiteLoaderQQNT();
}
EnableAllButton(true);

View File

@ -17,6 +17,7 @@ namespace RevokeMsgPatcher.Model
public List<ReplacePattern> ReplacePatterns { get; set; }
public CommonModifyInfo Clone()
{
CommonModifyInfo o = new CommonModifyInfo();

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -18,6 +19,11 @@ namespace RevokeMsgPatcher.Model
public string EndVersion { get; set; }
/// <summary>
/// 使用其他文件的版本作为版本号
/// </summary>
public string RelativePathForVersion { get; set; }
public TargetInfo Clone()
{
TargetInfo o = new TargetInfo();
@ -26,5 +32,61 @@ namespace RevokeMsgPatcher.Model
o.Memo = Memo;
return o;
}
public string GetAbsolutePath(string installPath)
{
if (RelativePath.Contains("{version}"))
{
// 获取{version}之前的路径部分
var versionIndex = RelativePath.IndexOf("{version}");
var prefixPath = RelativePath.Substring(0, versionIndex);
var suffixPath = RelativePath.Substring(versionIndex + "{version}".Length);
// 构建搜索目录路径
var searchDirectory = Path.Combine(installPath, prefixPath);
if (!Directory.Exists(searchDirectory))
{
throw new DirectoryNotFoundException($"Directory not found: {searchDirectory}");
}
// 获取所有子目录
var directories = Directory.GetDirectories(searchDirectory);
// 筛选包含至少三个点的目录名,并解析为版本号
var validVersions = new List<Tuple<string, Version>>();
foreach (var directory in directories)
{
var dirName = Path.GetFileName(directory);
// 检查是否包含至少两个点
if (dirName.Count(c => c == '.') >= 2)
{
// 尝试解析为版本号
if (Version.TryParse(dirName.Replace("-","."), out Version version))
{
validVersions.Add(new Tuple<string, Version>(dirName, version));
}
}
}
if (validVersions.Count == 0)
{
throw new InvalidOperationException($"No valid version directories found in: {searchDirectory}");
}
// 找到版本号最大的目录
var maxVersionDir = validVersions.OrderByDescending(v => v.Item2).First().Item1;
// 构建完整路径
var fullRelativePath = RelativePath.Replace("{version}", maxVersionDir);
return Path.Combine(installPath, fullRelativePath);
}
else
{
return Path.Combine(installPath, RelativePath);
}
}
}
}

View File

@ -134,11 +134,11 @@ namespace RevokeMsgPatcher.Modifier
if (j == editors.Count)
{
label.Text = version + "(支持特征防撤回)";
// QQNT 特殊处理
if (config.Name == "QQNT")
{
label.Text = version + "支持LiteLoader";
}
// // QQNT 特殊处理
// if (config.Name == "QQNT")
// {
// label.Text = version + "支持LiteLoader";
// }
label.ForeColor = Color.LimeGreen;
UIController.AddCategoryCheckBoxToPanel(panel, categories.ToArray(), installed.ToArray());
@ -166,7 +166,7 @@ namespace RevokeMsgPatcher.Modifier
int success = 0, count = 0;
foreach (TargetInfo info in config.FileTargetInfos.Values)
{
string filePath = Path.Combine(installPath, info.RelativePath);
string filePath = info.GetAbsolutePath(installPath);
if (info.Name != "WeChat.exe")
{
count++;

View File

@ -20,6 +20,7 @@ namespace RevokeMsgPatcher.Modifier
{
get
{
// version 可能被构造函数初始化,请注意!
if (version == null)
{
version = FileUtil.GetFileVersion(FilePath);
@ -70,9 +71,13 @@ namespace RevokeMsgPatcher.Modifier
{
FileTargetInfo = target.Clone();
FileName = FileTargetInfo.Name;
FilePath = Path.Combine(installPath, FileTargetInfo.RelativePath);
FilePath = FileTargetInfo.GetAbsolutePath(installPath);
FileBakPath = FilePath + ".h.bak";
fileReplacedPath = FilePath + ".h.process";
// if (target.RelativePathForVersion != null)
// {
// version = FileUtil.GetFileVersion(Path.Combine(installPath, target.RelativePathForVersion));
// }
}
/// <summary>

View File

@ -22,42 +22,41 @@ namespace RevokeMsgPatcher.Modifier
/// <returns></returns>
public override string FindInstallPath()
{
return "请在新弹出的窗口内进行 LiteLoaderQQNT 的安装与更新!";
// 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;
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>
@ -70,80 +69,23 @@ namespace RevokeMsgPatcher.Modifier
{
foreach (FileHexEditor editor in editors)
{
if (editor.FileName == "QQ.exe")
if (editor.FileName == "wrapper.node")
{
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 (!Directory.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()

View File

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

View File

@ -61,7 +61,7 @@ namespace RevokeMsgPatcher.Properties {
}
/// <summary>
/// 查找类似 {&quot;Apps&quot;:{&quot;Wechat&quot;:{&quot;Name&quot;:&quot;WeChat&quot;,&quot;FileTargetInfos&quot;:{&quot;WeChatWin.dll&quot;:{&quot;Name&quot;:&quot;WeChatWin.dll&quot;,&quot;RelativePath&quot;:&quot;WeChatWin.dll&quot;,&quot;Memo&quot;:null,&quot;StartVersion&quot;:&quot;1.0.0.0&quot;,&quot;EndVersion&quot;:null},&quot;WeChat.exe&quot;:{&quot;Name&quot;:&quot;WeChat.exe&quot;,&quot;RelativePath&quot;:&quot;../WeChat.exe&quot;,&quot;Memo&quot;:null,&quot;StartVersion&quot;:&quot;3.7.0.0&quot;,&quot;EndVersion&quot;:&quot;3.7.0.26&quot;}},&quot;FileModifyInfos&quot;:{&quot;WeChat.exe&quot;:[],&quot;WeChatWin.dll&quot;:[{&quot;Name&quot;:&quot;WeChatWin.dll&quot;,&quot;Version&quot;:&quot;3.3.5.25&quot;,&quot;SHA1Before&quot;:&quot;3e94753ccbc2799d98f3c741377e99bdae33b4cf&quot;,&quot;SHA1After&quot;:&quot;ab98f83fc16674ac4911380882c79c3ca4c2f [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// 查找类似 {&quot;Apps&quot;:{&quot;Wechat&quot;:{&quot;Name&quot;:&quot;WeChat&quot;,&quot;FileTargetInfos&quot;:{&quot;WeChatWin.dll&quot;:{&quot;Name&quot;:&quot;WeChatWin.dll&quot;,&quot;RelativePath&quot;:&quot;WeChatWin.dll&quot;,&quot;Memo&quot;:null,&quot;StartVersion&quot;:&quot;1.0.0.0&quot;,&quot;EndVersion&quot;:null,&quot;RelativePathForVersion&quot;:null},&quot;WeChat.exe&quot;:{&quot;Name&quot;:&quot;WeChat.exe&quot;,&quot;RelativePath&quot;:&quot;../WeChat.exe&quot;,&quot;Memo&quot;:null,&quot;StartVersion&quot;:&quot;3.7.0.0&quot;,&quot;EndVersion&quot;:&quot;3.7.0.26&quot;,&quot;RelativePathForVersion&quot;:null}},&quot;FileModifyInfos&quot;:{&quot;WeChat.exe&quot;:[],&quot;WeChatWin.dll&quot;:[{&quot;Name&quot;:&quot;WeChatWin.dll&quot;,&quot;Version&quot;:&quot;3.3.5.25&quot;,&quot;SHA1Before&quot;:&quot;3e94753ccbc2799d98f3c741377e99bd [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary>
internal static string PatchJson {
get {

File diff suppressed because one or more lines are too long