mirror of
https://github.com/Sunnyyoung/WeChatTweak-macOS.git
synced 2026-01-17 15:35:39 +08:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9970a1ee5 | ||
|
|
0ded215c3f | ||
|
|
bfbfe1bb29 | ||
|
|
19f1c446a6 | ||
|
|
c51ccc8ac9 |
1
.ruby-version
Normal file
1
.ruby-version
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
2.7.8
|
||||||
5
CONTRIBUTING.md
Normal file
5
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
# Contributing
|
||||||
|
|
||||||
|
This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
|
||||||
|
|
||||||
|
[](https://github.com/Sunnyyoung/WeChatTweak-macOS/graphs/contributors)
|
||||||
23
README.md
23
README.md
|
|
@ -1,10 +1,7 @@
|
||||||
# WeChatTweak
|
# WeChatTweak
|
||||||
|
|
||||||
[](https://github.com/sunnyyoung/WeChatTweak)
|
[](LICENSE)
|
||||||
[](https://t.me/wechattweak)
|
[](https://t.me/wechattweak)
|
||||||
[](https://github.com/sunnyyoung/WeChatTweak/wiki/FAQ)
|
|
||||||
|
|
||||||
A command-line tool for tweaking WeChat.
|
|
||||||
|
|
||||||
## 功能
|
## 功能
|
||||||
|
|
||||||
|
|
@ -12,20 +9,16 @@ A command-line tool for tweaking WeChat.
|
||||||
- 阻止自动更新
|
- 阻止自动更新
|
||||||
- 客户端多开
|
- 客户端多开
|
||||||
|
|
||||||
## 安装&使用
|
## 安装
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 安装
|
|
||||||
brew install sunnyyoung/tap/wechattweak
|
brew install sunnyyoung/tap/wechattweak
|
||||||
|
```
|
||||||
|
|
||||||
# 更新
|
## 使用
|
||||||
brew upgrade wechattweak
|
|
||||||
|
|
||||||
# 执行 Patch
|
```bash
|
||||||
wechattweak patch
|
wechattweak patch
|
||||||
|
|
||||||
# 查看所有支持的 WeChat 版本
|
|
||||||
wechattweak versions
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
@ -36,9 +29,9 @@ wechattweak versions
|
||||||
|
|
||||||
## 贡献者
|
## 贡献者
|
||||||
|
|
||||||
This project exists thanks to all the people who contribute.
|
This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
|
||||||
|
|
||||||
[](https://github.com/sunnyyoung/WeChatTweak/graphs/contributors)
|
[](https://github.com/Sunnyyoung/WeChatTweak-macOS/graphs/contributors)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ struct Config: Decodable {
|
||||||
let version: String
|
let version: String
|
||||||
let targets: [Target]
|
let targets: [Target]
|
||||||
|
|
||||||
static func load(url: URL) async throws -> [Config] {
|
static func load(from url: URL) async throws -> [Config] {
|
||||||
if url.isFileURL {
|
if url.isFileURL {
|
||||||
return try JSONDecoder().decode(
|
return try JSONDecoder().decode(
|
||||||
[Config].self,
|
[Config].self,
|
||||||
|
|
|
||||||
|
|
@ -8,64 +8,7 @@ import Foundation
|
||||||
import Dispatch
|
import Dispatch
|
||||||
import ArgumentParser
|
import ArgumentParser
|
||||||
|
|
||||||
// MARK: Versions
|
struct Patch: AsyncParsableCommand {
|
||||||
extension Tweak {
|
|
||||||
struct Versions: AsyncParsableCommand {
|
|
||||||
static let configuration = CommandConfiguration(abstract: "List all supported WeChat versions")
|
|
||||||
|
|
||||||
@OptionGroup
|
|
||||||
var options: Tweak.Options
|
|
||||||
|
|
||||||
mutating func run() async throws {
|
|
||||||
print("------ Current version ------")
|
|
||||||
print(try await Command.version(app: options.app) ?? "unknown")
|
|
||||||
print("------ Supported versions ------")
|
|
||||||
try await Config.load(url: options.config).forEach({ print($0.version) })
|
|
||||||
Darwin.exit(EXIT_SUCCESS)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: Patch
|
|
||||||
extension Tweak {
|
|
||||||
struct Patch: AsyncParsableCommand {
|
|
||||||
static let configuration = CommandConfiguration(abstract: "Patch WeChat.app")
|
|
||||||
|
|
||||||
@OptionGroup
|
|
||||||
var options: Tweak.Options
|
|
||||||
|
|
||||||
mutating func run() async throws {
|
|
||||||
print("------ Version ------")
|
|
||||||
let version = try await Command.version(app: options.app)
|
|
||||||
print("WeChat version: \(version ?? "unknown")")
|
|
||||||
|
|
||||||
print("------ Config ------")
|
|
||||||
guard let config = (try await Config.load(url: options.config)).first(where: { $0.version == version }) else {
|
|
||||||
throw Error.unsupportedVersion
|
|
||||||
}
|
|
||||||
print("Matched config: \(config)")
|
|
||||||
|
|
||||||
print("------ Patch ------")
|
|
||||||
try await Command.patch(
|
|
||||||
app: options.app,
|
|
||||||
config: config
|
|
||||||
)
|
|
||||||
print("Done!")
|
|
||||||
|
|
||||||
print("------ Resign ------")
|
|
||||||
try await Command.resign(
|
|
||||||
app: options.app
|
|
||||||
)
|
|
||||||
print("Done!")
|
|
||||||
|
|
||||||
Darwin.exit(EXIT_SUCCESS)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: Tweak
|
|
||||||
struct Tweak: AsyncParsableCommand {
|
|
||||||
enum Error: LocalizedError {
|
enum Error: LocalizedError {
|
||||||
case invalidApp
|
case invalidApp
|
||||||
case invalidConfig
|
case invalidConfig
|
||||||
|
|
@ -86,49 +29,82 @@ struct Tweak: AsyncParsableCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Options: ParsableArguments {
|
static let configuration = CommandConfiguration(abstract: "Patch WeChat.app")
|
||||||
@Option(
|
|
||||||
name: .shortAndLong,
|
@Option(
|
||||||
help: "Path of WeChat.app",
|
name: .shortAndLong,
|
||||||
transform: {
|
help: "Path of WeChat.app",
|
||||||
guard FileManager.default.fileExists(atPath: $0) else {
|
transform: {
|
||||||
throw Error.invalidApp
|
guard FileManager.default.fileExists(atPath: $0) else {
|
||||||
}
|
throw Error.invalidApp
|
||||||
|
}
|
||||||
|
return URL(fileURLWithPath: $0)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
var app: URL = URL(fileURLWithPath: "/Applications/WeChat.app", isDirectory: true)
|
||||||
|
|
||||||
|
@Option(
|
||||||
|
name: .shortAndLong,
|
||||||
|
help: "Local path or Remote URL of config.json",
|
||||||
|
transform: {
|
||||||
|
if FileManager.default.fileExists(atPath: $0) {
|
||||||
return URL(fileURLWithPath: $0)
|
return URL(fileURLWithPath: $0)
|
||||||
}
|
} else {
|
||||||
)
|
guard let url = URL(string: $0) else {
|
||||||
var app: URL = URL(fileURLWithPath: "/Applications/WeChat.app", isDirectory: true)
|
throw Error.invalidConfig
|
||||||
|
|
||||||
@Option(
|
|
||||||
name: .shortAndLong,
|
|
||||||
help: "Local path or Remote URL of config.json",
|
|
||||||
transform: {
|
|
||||||
if FileManager.default.fileExists(atPath: $0) {
|
|
||||||
return URL(fileURLWithPath: $0)
|
|
||||||
} else {
|
|
||||||
guard let url = URL(string: $0) else {
|
|
||||||
throw Error.invalidConfig
|
|
||||||
}
|
|
||||||
return url
|
|
||||||
}
|
}
|
||||||
|
return url
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
var config: URL = URL(string:"https://raw.githubusercontent.com/sunnyyoung/WeChatTweak/refs/heads/master/config.json")!
|
)
|
||||||
}
|
var config: URL = URL(string: "https://raw.githubusercontent.com/sunnyyoung/WeChatTweak/refs/heads/feature/2.0/config.json")!
|
||||||
|
|
||||||
|
mutating func run() async throws {
|
||||||
|
do {
|
||||||
|
print("------ Version ------")
|
||||||
|
guard let version = try await Command.version(app: self.app) else {
|
||||||
|
throw Error.invalidVersion
|
||||||
|
}
|
||||||
|
print("\(version)")
|
||||||
|
|
||||||
|
print("------ Config ------")
|
||||||
|
guard let config = (try await Config.load(from: self.config)).first(where: { $0.version == version }) else {
|
||||||
|
throw Error.unsupportedVersion
|
||||||
|
}
|
||||||
|
print("\(config)")
|
||||||
|
|
||||||
|
print("------ Patch ------")
|
||||||
|
try await Command.patch(
|
||||||
|
app: self.app,
|
||||||
|
config: config
|
||||||
|
)
|
||||||
|
print("Done!")
|
||||||
|
|
||||||
|
print("------ Resign ------")
|
||||||
|
try await Command.resign(
|
||||||
|
app: self.app
|
||||||
|
)
|
||||||
|
print("Done!")
|
||||||
|
|
||||||
|
print("------🎉 Done!------")
|
||||||
|
Darwin.exit(EXIT_SUCCESS)
|
||||||
|
} catch {
|
||||||
|
print("------🚨 Error------")
|
||||||
|
print("\(error.localizedDescription)")
|
||||||
|
Darwin.exit(EXIT_FAILURE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Tweak: AsyncParsableCommand {
|
||||||
static let configuration = CommandConfiguration(
|
static let configuration = CommandConfiguration(
|
||||||
commandName: "wechattweak",
|
commandName: "wechattweak",
|
||||||
abstract: "A command-line tool for tweaking WeChat.",
|
abstract: "A command-line tool for tweaking WeChat.",
|
||||||
subcommands: [
|
subcommands: [
|
||||||
Versions.self,
|
|
||||||
Patch.self
|
Patch.self
|
||||||
]
|
],
|
||||||
|
defaultSubcommand: Self.self
|
||||||
)
|
)
|
||||||
|
|
||||||
mutating func run() async throws {
|
|
||||||
print(Tweak.helpMessage())
|
|
||||||
Darwin.exit(EXIT_SUCCESS)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Task {
|
Task {
|
||||||
|
|
|
||||||
110
config.json
110
config.json
|
|
@ -168,115 +168,5 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "32288",
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"identifier": "revoke",
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"arch": "arm64",
|
|
||||||
"addr": "103db34c0",
|
|
||||||
"asm": "00008052C0035FD6"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identifier": "startUpdater",
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"arch": "arm64",
|
|
||||||
"addr": "1001e9ed0",
|
|
||||||
"asm": "00008052C0035FD6"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identifier": "startBackgroundUpdatesCheck",
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"arch": "arm64",
|
|
||||||
"addr": "1001ecb10",
|
|
||||||
"asm": "00008052C0035FD6"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identifier": "checkForUpdates",
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"arch": "arm64",
|
|
||||||
"addr": "1001ec73c",
|
|
||||||
"asm": "00008052C0035FD6"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identifier": "enableAutoUpdate",
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"arch": "arm64",
|
|
||||||
"addr": "1001ecfc0",
|
|
||||||
"asm": "00008052C0035FD6"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identifier": "automaticallyDownloadsUpdates",
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"arch": "arm64",
|
|
||||||
"addr": "1001f59e0",
|
|
||||||
"asm": "00008052C0035FD6"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identifier": "canCheckForUpdate",
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"arch": "arm64",
|
|
||||||
"addr": "1001f59e0",
|
|
||||||
"asm": "00008052C0035FD6"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identifier": "multiInstance",
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"arch": "arm64",
|
|
||||||
"addr": "1001e1a74",
|
|
||||||
"asm": "20008052C0035FD6"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "31960",
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"identifier": "revoke",
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"arch": "arm64",
|
|
||||||
"addr": "10408a408",
|
|
||||||
"asm": "00008052C0035FD6"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identifier": "multiInstance",
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"arch": "arm64",
|
|
||||||
"addr": "1001e4a38",
|
|
||||||
"asm": "20008052C0035FD6"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user