mirror of
https://github.com/huiyadanli/RevokeMsgPatcher.git
synced 2025-08-23 20:16:07 +08:00
QQNT 防撤回使用新的方案
This commit is contained in:
parent
aec635dc39
commit
65c1e419e9
1
RevokeMsgPatcher.Assistant/Data/2.1/patch.json
Normal file
1
RevokeMsgPatcher.Assistant/Data/2.1/patch.json
Normal file
File diff suppressed because one or more lines are too long
|
@ -16,8 +16,8 @@ namespace RevokeMsgPatcher
|
||||||
return new Bag
|
return new Bag
|
||||||
{
|
{
|
||||||
Apps = AppConfig(),
|
Apps = AppConfig(),
|
||||||
LatestVersion = "2.0",
|
LatestVersion = "2.1",
|
||||||
PatchVersion = 20241107,
|
PatchVersion = 20250803,
|
||||||
Notice = "",
|
Notice = "",
|
||||||
NoticeUrl = "",
|
NoticeUrl = "",
|
||||||
};
|
};
|
||||||
|
@ -1377,32 +1377,33 @@ namespace RevokeMsgPatcher
|
||||||
FileTargetInfos = new Dictionary<string, TargetInfo>
|
FileTargetInfos = new Dictionary<string, TargetInfo>
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"QQ.exe",
|
"wrapper.node",
|
||||||
new TargetInfo
|
new TargetInfo
|
||||||
{
|
{
|
||||||
Name = "QQ.exe",
|
Name = "wrapper.node",
|
||||||
RelativePath = "QQ.exe"
|
RelativePath = @"versions\{version}\resources\app\wrapper.node",
|
||||||
|
RelativePathForVersion = "QQ.exe"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
FileCommonModifyInfos = new Dictionary<string, List<CommonModifyInfo>>
|
FileCommonModifyInfos = new Dictionary<string, List<CommonModifyInfo>>
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"QQ.exe",
|
"wrapper.node",
|
||||||
new List<CommonModifyInfo>
|
new List<CommonModifyInfo>
|
||||||
{
|
{
|
||||||
new CommonModifyInfo
|
new CommonModifyInfo
|
||||||
{
|
{
|
||||||
Name="QQ.exe",
|
Name="wrapper.node",
|
||||||
StartVersion="9.9.10.00000",
|
StartVersion="9.8.0.19000",
|
||||||
EndVersion="9.9.15.00000",
|
EndVersion="",
|
||||||
ReplacePatterns = new List<ReplacePattern>
|
ReplacePatterns = new List<ReplacePattern>
|
||||||
{
|
{
|
||||||
new 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"),
|
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 89 CE 48 8B 11 4C 8B 41 08 49 29 D0 48 8B 49 18 B8 01 00 00 00"),
|
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 = "请在新窗口内安装LiteLoaderQQNT"
|
Category = "群聊防撤回"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,7 @@
|
||||||
<None Include="Data\1.8\patch.json" />
|
<None Include="Data\1.8\patch.json" />
|
||||||
<None Include="Data\1.9\patch.json" />
|
<None Include="Data\1.9\patch.json" />
|
||||||
<None Include="Data\2.0\patch.json" />
|
<None Include="Data\2.0\patch.json" />
|
||||||
|
<None Include="Data\2.1\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>
|
||||||
|
|
|
@ -435,7 +435,7 @@ namespace RevokeMsgPatcher
|
||||||
else if (rbtQQNT.Checked)
|
else if (rbtQQNT.Checked)
|
||||||
{
|
{
|
||||||
modifier = (QQNTModifier)rbtQQNT.Tag;
|
modifier = (QQNTModifier)rbtQQNT.Tag;
|
||||||
ShowOrFocusFormLiteLoaderQQNT();
|
// ShowOrFocusFormLiteLoaderQQNT();
|
||||||
}
|
}
|
||||||
|
|
||||||
EnableAllButton(true);
|
EnableAllButton(true);
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace RevokeMsgPatcher.Model
|
||||||
|
|
||||||
public List<ReplacePattern> ReplacePatterns { get; set; }
|
public List<ReplacePattern> ReplacePatterns { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public CommonModifyInfo Clone()
|
public CommonModifyInfo Clone()
|
||||||
{
|
{
|
||||||
CommonModifyInfo o = new CommonModifyInfo();
|
CommonModifyInfo o = new CommonModifyInfo();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -18,6 +19,11 @@ namespace RevokeMsgPatcher.Model
|
||||||
|
|
||||||
public string EndVersion { get; set; }
|
public string EndVersion { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用其他文件的版本作为版本号
|
||||||
|
/// </summary>
|
||||||
|
public string RelativePathForVersion { get; set; }
|
||||||
|
|
||||||
public TargetInfo Clone()
|
public TargetInfo Clone()
|
||||||
{
|
{
|
||||||
TargetInfo o = new TargetInfo();
|
TargetInfo o = new TargetInfo();
|
||||||
|
@ -26,5 +32,61 @@ namespace RevokeMsgPatcher.Model
|
||||||
o.Memo = Memo;
|
o.Memo = Memo;
|
||||||
return o;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,11 +134,11 @@ namespace RevokeMsgPatcher.Modifier
|
||||||
if (j == editors.Count)
|
if (j == editors.Count)
|
||||||
{
|
{
|
||||||
label.Text = version + "(支持特征防撤回)";
|
label.Text = version + "(支持特征防撤回)";
|
||||||
// QQNT 特殊处理
|
// // QQNT 特殊处理
|
||||||
if (config.Name == "QQNT")
|
// if (config.Name == "QQNT")
|
||||||
{
|
// {
|
||||||
label.Text = version + "(支持LiteLoader)";
|
// 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());
|
||||||
|
@ -166,7 +166,7 @@ namespace RevokeMsgPatcher.Modifier
|
||||||
int success = 0, count = 0;
|
int success = 0, count = 0;
|
||||||
foreach (TargetInfo info in config.FileTargetInfos.Values)
|
foreach (TargetInfo info in config.FileTargetInfos.Values)
|
||||||
{
|
{
|
||||||
string filePath = Path.Combine(installPath, info.RelativePath);
|
string filePath = info.GetAbsolutePath(installPath);
|
||||||
if (info.Name != "WeChat.exe")
|
if (info.Name != "WeChat.exe")
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
|
|
|
@ -20,6 +20,7 @@ namespace RevokeMsgPatcher.Modifier
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
// version 可能被构造函数初始化,请注意!
|
||||||
if (version == null)
|
if (version == null)
|
||||||
{
|
{
|
||||||
version = FileUtil.GetFileVersion(FilePath);
|
version = FileUtil.GetFileVersion(FilePath);
|
||||||
|
@ -70,9 +71,13 @@ namespace RevokeMsgPatcher.Modifier
|
||||||
{
|
{
|
||||||
FileTargetInfo = target.Clone();
|
FileTargetInfo = target.Clone();
|
||||||
FileName = FileTargetInfo.Name;
|
FileName = FileTargetInfo.Name;
|
||||||
FilePath = Path.Combine(installPath, FileTargetInfo.RelativePath);
|
FilePath = FileTargetInfo.GetAbsolutePath(installPath);
|
||||||
FileBakPath = FilePath + ".h.bak";
|
FileBakPath = FilePath + ".h.bak";
|
||||||
fileReplacedPath = FilePath + ".h.process";
|
fileReplacedPath = FilePath + ".h.process";
|
||||||
|
// if (target.RelativePathForVersion != null)
|
||||||
|
// {
|
||||||
|
// version = FileUtil.GetFileVersion(Path.Combine(installPath, target.RelativePathForVersion));
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -22,42 +22,41 @@ namespace RevokeMsgPatcher.Modifier
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public override string FindInstallPath()
|
public override string FindInstallPath()
|
||||||
{
|
{
|
||||||
return "请在新弹出的窗口内进行 LiteLoaderQQNT 的安装与更新!";
|
try
|
||||||
// try
|
{
|
||||||
// {
|
string installPath = PathUtil.FindInstallPathFromRegistryWOW6432Node("QQ");
|
||||||
// string installPath = PathUtil.FindInstallPathFromRegistryWOW6432Node("QQ");
|
if (!string.IsNullOrEmpty(installPath))
|
||||||
// if (!string.IsNullOrEmpty(installPath))
|
{
|
||||||
// {
|
installPath = Path.GetDirectoryName(installPath);
|
||||||
// installPath = Path.GetDirectoryName(installPath);
|
if (IsAllFilesExist(installPath))
|
||||||
// if (IsAllFilesExist(installPath))
|
{
|
||||||
// {
|
return installPath;
|
||||||
// return installPath;
|
}
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
//
|
installPath = PathUtil.FindInstallPathFromRegistry("QQNT");
|
||||||
// installPath = PathUtil.FindInstallPathFromRegistry("QQNT");
|
if (!IsAllFilesExist(installPath))
|
||||||
// if (!IsAllFilesExist(installPath))
|
{
|
||||||
// {
|
List<string> defaultPathList = PathUtil.GetDefaultInstallPaths(@"Tencent\QQNT");
|
||||||
// List<string> defaultPathList = PathUtil.GetDefaultInstallPaths(@"Tencent\QQNT");
|
foreach (string defaultPath in defaultPathList)
|
||||||
// foreach (string defaultPath in defaultPathList)
|
{
|
||||||
// {
|
if (IsAllFilesExist(defaultPath))
|
||||||
// if (IsAllFilesExist(defaultPath))
|
{
|
||||||
// {
|
return defaultPath;
|
||||||
// return defaultPath;
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
else
|
||||||
// else
|
{
|
||||||
// {
|
return installPath;
|
||||||
// return installPath;
|
}
|
||||||
// }
|
}
|
||||||
// }
|
catch (Exception e)
|
||||||
// catch (Exception e)
|
{
|
||||||
// {
|
Console.WriteLine(e.Message);
|
||||||
// Console.WriteLine(e.Message);
|
}
|
||||||
// }
|
|
||||||
//
|
return null;
|
||||||
// return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -70,80 +69,23 @@ namespace RevokeMsgPatcher.Modifier
|
||||||
{
|
{
|
||||||
foreach (FileHexEditor editor in editors)
|
foreach (FileHexEditor editor in editors)
|
||||||
{
|
{
|
||||||
if (editor.FileName == "QQ.exe")
|
if (editor.FileName == "wrapper.node")
|
||||||
{
|
{
|
||||||
return editor.FileVersion;
|
return editor.FileVersion;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
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()
|
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()
|
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()
|
public new bool Restore()
|
||||||
|
|
|
@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||||
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
||||||
// 方法是按如下所示使用“*”: :
|
// 方法是按如下所示使用“*”: :
|
||||||
//[assembly: AssemblyVersion("1.0.*")]
|
//[assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("2.0")]
|
[assembly: AssemblyVersion("2.1")]
|
||||||
[assembly: AssemblyFileVersion("2.0")]
|
[assembly: AssemblyFileVersion("2.1")]
|
||||||
|
|
|
@ -61,7 +61,7 @@ namespace RevokeMsgPatcher.Properties {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 {"Apps":{"Wechat":{"Name":"WeChat","FileTargetInfos":{"WeChatWin.dll":{"Name":"WeChatWin.dll","RelativePath":"WeChatWin.dll","Memo":null,"StartVersion":"1.0.0.0","EndVersion":null},"WeChat.exe":{"Name":"WeChat.exe","RelativePath":"../WeChat.exe","Memo":null,"StartVersion":"3.7.0.0","EndVersion":"3.7.0.26"}},"FileModifyInfos":{"WeChat.exe":[],"WeChatWin.dll":[{"Name":"WeChatWin.dll","Version":"3.3.5.25","SHA1Before":"3e94753ccbc2799d98f3c741377e99bdae33b4cf","SHA1After":"ab98f83fc16674ac4911380882c79c3ca4c2f [字符串的其余部分被截断]"; 的本地化字符串。
|
/// 查找类似 {"Apps":{"Wechat":{"Name":"WeChat","FileTargetInfos":{"WeChatWin.dll":{"Name":"WeChatWin.dll","RelativePath":"WeChatWin.dll","Memo":null,"StartVersion":"1.0.0.0","EndVersion":null,"RelativePathForVersion":null},"WeChat.exe":{"Name":"WeChat.exe","RelativePath":"../WeChat.exe","Memo":null,"StartVersion":"3.7.0.0","EndVersion":"3.7.0.26","RelativePathForVersion":null}},"FileModifyInfos":{"WeChat.exe":[],"WeChatWin.dll":[{"Name":"WeChatWin.dll","Version":"3.3.5.25","SHA1Before":"3e94753ccbc2799d98f3c741377e99bd [字符串的其余部分被截断]"; 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string PatchJson {
|
internal static string PatchJson {
|
||||||
get {
|
get {
|
||||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user