Add configurable scheme hook
Signed-off-by: Sean Du <do4suki@gmail.com>
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
**用途**
|
**用途**
|
||||||
- 转发 `UnityPlayer.dll` 实际导入的少量 `version.dll` 导出函数
|
- 转发 `UnityPlayer.dll` 实际导入的少量 `version.dll` 导出函数
|
||||||
- 等待 IL2CPP 运行时初始化稳定
|
- 等待 IL2CPP 运行时初始化稳定
|
||||||
- 运行时 hook `Stage.NetworkUtil.GetSchemeType()`,强制返回 `0`
|
- 可选地 hook `Stage.NetworkUtil.GetSchemeType()`,在需要时强制切到 `http`
|
||||||
- 支持通过 `config.json` 覆盖 `api_url` 和 `asset_url`
|
- 支持通过 `config.json` 覆盖 `api_url` 和 `asset_url`
|
||||||
|
|
||||||
**目录结构**
|
**目录结构**
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
- `GameAssembly.dll` 出现时,IL2CPP runtime 可能还不能安全访问,因此 hook 线程会额外等待一小段时间
|
- `GameAssembly.dll` 出现时,IL2CPP runtime 可能还不能安全访问,因此 hook 线程会额外等待一小段时间
|
||||||
- 运行时日志会写到游戏目录下的 `cgss-http-hook.log`
|
- 运行时日志会写到游戏目录下的 `cgss-http-hook.log`
|
||||||
- 生成的 DLL 包含 Windows 版本资源,定义在 `src/version.rc`
|
- 生成的 DLL 包含 Windows 版本资源,定义在 `src/version.rc`
|
||||||
|
- 支持通过 `force_http` 控制是否 hook scheme,默认 `true`
|
||||||
- `config.json` 中的 URL 会自动规范化:若写了 `http://` 或 `https://` 会自动去掉,若末尾缺少 `/` 会自动补上
|
- `config.json` 中的 URL 会自动规范化:若写了 `http://` 或 `https://` 会自动去掉,若末尾缺少 `/` 会自动补上
|
||||||
|
|
||||||
**构建**
|
**构建**
|
||||||
@@ -33,12 +34,14 @@ cmake --build build
|
|||||||
**config.json**
|
**config.json**
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
"force_http": true,
|
||||||
"api_url": "apis.game.starlight-stage.jp/",
|
"api_url": "apis.game.starlight-stage.jp/",
|
||||||
"asset_url": "asset-starlight-stage.akamaized.net/"
|
"asset_url": "asset-starlight-stage.akamaized.net/"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
字段说明:
|
字段说明:
|
||||||
|
- `force_http`:是否强制将 scheme 改成 `http`。默认 `true`
|
||||||
- `api_url`:API 主机名,按原始字段格式填写,不带 scheme
|
- `api_url`:API 主机名,按原始字段格式填写,不带 scheme
|
||||||
- `asset_url`:资源主机名,按原始字段格式填写,不带 scheme
|
- `asset_url`:资源主机名,按原始字段格式填写,不带 scheme
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"force_http": true,
|
||||||
"api_url": "apis.game.starlight-stage.jp/",
|
"api_url": "apis.game.starlight-stage.jp/",
|
||||||
"asset_url": "asset-starlight-stage.akamaized.net/"
|
"asset_url": "asset-starlight-stage.akamaized.net/"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,13 @@ namespace config {
|
|||||||
}
|
}
|
||||||
out = normalize_base_url(document[key].GetString());
|
out = normalize_base_url(document[key].GetString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void read_bool(const rapidjson::Document& document, const char* key, bool& out) {
|
||||||
|
if (!document.HasMember(key) || !document[key].IsBool()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
out = document[key].GetBool();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void load() {
|
void load() {
|
||||||
@@ -88,9 +95,12 @@ namespace config {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
read_bool(document, "force_http", g_urls.force_http);
|
||||||
read_string(document, "api_url", g_urls.api_url);
|
read_string(document, "api_url", g_urls.api_url);
|
||||||
read_string(document, "asset_url", g_urls.asset_url);
|
read_string(document, "asset_url", g_urls.asset_url);
|
||||||
|
|
||||||
|
hook_logf("[cgss-http-hook] force_http=%s", g_urls.force_http ? "true" : "false");
|
||||||
|
|
||||||
if (!g_urls.api_url.empty()) {
|
if (!g_urls.api_url.empty()) {
|
||||||
hook_logf("[cgss-http-hook] normalized api_url=%s", g_urls.api_url.c_str());
|
hook_logf("[cgss-http-hook] normalized api_url=%s", g_urls.api_url.c_str());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace config {
|
namespace config {
|
||||||
struct OverrideUrls {
|
struct OverrideUrls {
|
||||||
|
bool force_http = true;
|
||||||
std::string api_url;
|
std::string api_url;
|
||||||
std::string asset_url;
|
std::string asset_url;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -43,6 +43,12 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void patch_custom_preference_scheme() {
|
void patch_custom_preference_scheme() {
|
||||||
|
const auto& urls = config::get();
|
||||||
|
if (!urls.force_http) {
|
||||||
|
hook_log("[cgss-http-hook] force_http disabled, skipping CustomPreference scheme patch");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto custom_preference = il2cpp_symbols::get_class(
|
auto custom_preference = il2cpp_symbols::get_class(
|
||||||
"Assembly-CSharp.dll", "Cute", "CustomPreference"
|
"Assembly-CSharp.dll", "Cute", "CustomPreference"
|
||||||
);
|
);
|
||||||
@@ -111,6 +117,8 @@ namespace {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto& urls = config::get();
|
||||||
|
if (urls.force_http) {
|
||||||
auto create_status = MH_CreateHook(
|
auto create_status = MH_CreateHook(
|
||||||
reinterpret_cast<void*>(addr),
|
reinterpret_cast<void*>(addr),
|
||||||
reinterpret_cast<void*>(&get_scheme_type_hook),
|
reinterpret_cast<void*>(&get_scheme_type_hook),
|
||||||
@@ -126,6 +134,9 @@ namespace {
|
|||||||
hook_log("[cgss-http-hook] MH_EnableHook failed");
|
hook_log("[cgss-http-hook] MH_EnableHook failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
hook_log("[cgss-http-hook] force_http disabled, keeping original scheme");
|
||||||
|
}
|
||||||
|
|
||||||
if (get_application_server_url_addr) {
|
if (get_application_server_url_addr) {
|
||||||
auto create_status = MH_CreateHook(
|
auto create_status = MH_CreateHook(
|
||||||
@@ -156,8 +167,10 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
InterlockedExchange(&g_hook_installed, 1);
|
InterlockedExchange(&g_hook_installed, 1);
|
||||||
|
if (urls.force_http) {
|
||||||
hook_log("[cgss-http-hook] hooked Stage.NetworkUtil.GetSchemeType");
|
hook_log("[cgss-http-hook] hooked Stage.NetworkUtil.GetSchemeType");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DWORD WINAPI init_thread(void*) {
|
DWORD WINAPI init_thread(void*) {
|
||||||
for (int i = 0; i < kHookPollMaxAttempts; ++i) {
|
for (int i = 0; i < kHookPollMaxAttempts; ++i) {
|
||||||
|
|||||||
Reference in New Issue
Block a user