Fix version proxy initialization

Fix high CPU and GPU usage.

Signed-off-by: Sean Du <do4suki@gmail.com>
This commit is contained in:
2026-06-23 20:51:38 +08:00
parent c234838635
commit d80e5bfc44
5 changed files with 299 additions and 363 deletions
+1 -1
View File
@@ -57,7 +57,7 @@ namespace config {
std::string make_default_config_json() { std::string make_default_config_json() {
return return
"{\r\n" "{\r\n"
" \"force_http\": false,\r\n" " \"force_http\": true,\r\n"
" \"api_url\": \"apis.game.starlight-stage.jp/\",\r\n" " \"api_url\": \"apis.game.starlight-stage.jp/\",\r\n"
" \"asset_url\": \"asset-starlight-stage.akamaized.net/\",\r\n" " \"asset_url\": \"asset-starlight-stage.akamaized.net/\",\r\n"
" \"launch_borderless_helper\": true\r\n" " \"launch_borderless_helper\": true\r\n"
+9 -1
View File
@@ -17,6 +17,7 @@ namespace {
HWND g_main_window = nullptr; HWND g_main_window = nullptr;
bool g_borderless_active = false; bool g_borderless_active = false;
bool g_saved_state_valid = false; bool g_saved_state_valid = false;
bool g_borderless_drift_logged = false;
RECT g_saved_window_rect = {}; RECT g_saved_window_rect = {};
LONG_PTR g_saved_style = 0; LONG_PTR g_saved_style = 0;
LONG_PTR g_saved_exstyle = 0; LONG_PTR g_saved_exstyle = 0;
@@ -298,11 +299,13 @@ namespace {
if (g_borderless_active) { if (g_borderless_active) {
g_borderless_active = false; g_borderless_active = false;
g_borderless_drift_logged = false;
restore_window(hwnd); restore_window(hwnd);
return; return;
} }
g_borderless_active = true; g_borderless_active = true;
g_borderless_drift_logged = false;
helper_logf( helper_logf(
"[cgss-borderless-helper] borderless enabled monitor=%ls rect=(%ld,%ld)-(%ld,%ld)", "[cgss-borderless-helper] borderless enabled monitor=%ls rect=(%ld,%ld)-(%ld,%ld)",
monitor_info.szDevice, monitor_info.szDevice,
@@ -370,8 +373,13 @@ int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
DWORD now = GetTickCount(); DWORD now = GetTickCount();
if (g_borderless_active && now - last_maintain_tick >= kMaintainIntervalMs) { if (g_borderless_active && now - last_maintain_tick >= kMaintainIntervalMs) {
if (needs_borderless_reapply(g_main_window)) { if (needs_borderless_reapply(g_main_window)) {
helper_logf("[cgss-borderless-helper] detected borderless drift, reapplying"); if (!g_borderless_drift_logged) {
helper_logf("[cgss-borderless-helper] detected borderless drift, reapplying");
g_borderless_drift_logged = true;
}
apply_borderless_once(g_main_window); apply_borderless_once(g_main_window);
} else {
g_borderless_drift_logged = false;
} }
last_maintain_tick = now; last_maintain_tick = now;
} }
+62 -339
View File
@@ -5,7 +5,6 @@
namespace { namespace {
using GetSchemeTypeFn = int (*)(const MethodInfo*); using GetSchemeTypeFn = int (*)(const MethodInfo*);
using GetStringFn = void* (*)(const MethodInfo*);
using SetStringFn = void (*)(void*, const MethodInfo*); using SetStringFn = void (*)(void*, const MethodInfo*);
using SetSchemeModeFn = void (*)(int, const MethodInfo*); using SetSchemeModeFn = void (*)(int, const MethodInfo*);
constexpr int kHttpSchemeType = 0; constexpr int kHttpSchemeType = 0;
@@ -15,36 +14,33 @@ namespace {
volatile LONG g_hook_installed = 0; volatile LONG g_hook_installed = 0;
GetSchemeTypeFn g_orig_get_scheme_type = nullptr; GetSchemeTypeFn g_orig_get_scheme_type = nullptr;
GetStringFn g_orig_get_application_server_url = nullptr;
GetStringFn g_orig_get_tele_scope_server_url = nullptr;
GetStringFn g_orig_get_concert_server_url = nullptr;
GetStringFn g_orig_get_resource_server_url = nullptr;
GetStringFn g_orig_custom_preference_get_application_server_url = nullptr;
GetStringFn g_orig_custom_preference_get_tele_scope_server_url = nullptr;
GetStringFn g_orig_custom_preference_get_concert_server_url = nullptr;
GetStringFn g_orig_custom_preference_get_resource_server_url = nullptr;
SetStringFn g_orig_custom_preference_set_application_server_url = nullptr;
SetStringFn g_orig_custom_preference_set_tele_scope_server_url = nullptr;
SetStringFn g_orig_custom_preference_set_concert_server_url = nullptr;
SetStringFn g_orig_custom_preference_set_resource_server_url = nullptr;
SetSchemeModeFn g_orig_custom_preference_set_scheme_mode = nullptr; SetSchemeModeFn g_orig_custom_preference_set_scheme_mode = nullptr;
volatile LONG g_logged_gameassembly = 0; volatile LONG g_logged_gameassembly = 0;
volatile LONG g_exports_state = 0; volatile LONG g_exports_state = 0;
ULONGLONG g_gameassembly_seen_tick = 0; ULONGLONG g_gameassembly_seen_tick = 0;
volatile LONG g_scheme_hook_called = 0; volatile LONG g_scheme_hook_called = 0;
volatile LONG g_application_hook_called = 0;
volatile LONG g_tele_scope_hook_called = 0;
volatile LONG g_concert_hook_called = 0;
volatile LONG g_resource_hook_called = 0;
volatile LONG g_cp_application_hook_called = 0;
volatile LONG g_cp_tele_scope_hook_called = 0;
volatile LONG g_cp_concert_hook_called = 0;
volatile LONG g_cp_resource_hook_called = 0;
volatile LONG g_cp_set_application_hook_called = 0;
volatile LONG g_cp_set_tele_scope_hook_called = 0;
volatile LONG g_cp_set_concert_hook_called = 0;
volatile LONG g_cp_set_resource_hook_called = 0;
volatile LONG g_cp_set_scheme_hook_called = 0; volatile LONG g_cp_set_scheme_hook_called = 0;
void* g_cached_api_url_string = nullptr;
void* g_cached_asset_url_string = nullptr;
void prepare_cached_override_strings() {
const auto& urls = config::get();
if (urls.api_url.empty() && urls.asset_url.empty()) {
return;
}
if (!urls.api_url.empty() && !g_cached_api_url_string) {
g_cached_api_url_string = il2cpp_symbols::new_string(urls.api_url.c_str());
if (!g_cached_api_url_string) {
hook_log("[cgss-dmm-hook] failed to cache api_url string");
}
}
if (!urls.asset_url.empty() && !g_cached_asset_url_string) {
g_cached_asset_url_string = il2cpp_symbols::new_string(urls.asset_url.c_str());
if (!g_cached_asset_url_string) {
hook_log("[cgss-dmm-hook] failed to cache asset_url string");
}
}
}
int get_scheme_type_hook(const MethodInfo*) { int get_scheme_type_hook(const MethodInfo*) {
if (InterlockedCompareExchange(&g_scheme_hook_called, 1, 0) == 0) { if (InterlockedCompareExchange(&g_scheme_hook_called, 1, 0) == 0) {
@@ -53,154 +49,6 @@ namespace {
return kHttpSchemeType; return kHttpSchemeType;
} }
void* get_application_server_url_hook(const MethodInfo* method) {
const auto& urls = config::get();
if (InterlockedCompareExchange(&g_application_hook_called, 1, 0) == 0) {
hook_log("[cgss-dmm-hook] GetApplicationServerUrl hook invoked");
}
if (!urls.api_url.empty()) {
return il2cpp_symbols::new_string(urls.api_url.c_str());
}
return g_orig_get_application_server_url ? g_orig_get_application_server_url(method) : nullptr;
}
void* get_tele_scope_server_url_hook(const MethodInfo* method) {
const auto& urls = config::get();
if (InterlockedCompareExchange(&g_tele_scope_hook_called, 1, 0) == 0) {
hook_log("[cgss-dmm-hook] GetTeleScopeServerUrl hook invoked");
}
if (!urls.api_url.empty()) {
return il2cpp_symbols::new_string(urls.api_url.c_str());
}
return g_orig_get_tele_scope_server_url ? g_orig_get_tele_scope_server_url(method) : nullptr;
}
void* get_concert_server_url_hook(const MethodInfo* method) {
const auto& urls = config::get();
if (InterlockedCompareExchange(&g_concert_hook_called, 1, 0) == 0) {
hook_log("[cgss-dmm-hook] GetConcertServerUrl hook invoked");
}
if (!urls.api_url.empty()) {
return il2cpp_symbols::new_string(urls.api_url.c_str());
}
return g_orig_get_concert_server_url ? g_orig_get_concert_server_url(method) : nullptr;
}
void* get_resource_server_url_hook(const MethodInfo* method) {
const auto& urls = config::get();
if (InterlockedCompareExchange(&g_resource_hook_called, 1, 0) == 0) {
hook_log("[cgss-dmm-hook] GetResourceServerUrl hook invoked");
}
if (!urls.asset_url.empty()) {
return il2cpp_symbols::new_string(urls.asset_url.c_str());
}
return g_orig_get_resource_server_url ? g_orig_get_resource_server_url(method) : nullptr;
}
void* custom_preference_get_application_server_url_hook(const MethodInfo* method) {
const auto& urls = config::get();
if (InterlockedCompareExchange(&g_cp_application_hook_called, 1, 0) == 0) {
hook_log("[cgss-dmm-hook] Cute.CustomPreference.GetApplicationServerURL hook invoked");
}
if (!urls.api_url.empty()) {
return il2cpp_symbols::new_string(urls.api_url.c_str());
}
return g_orig_custom_preference_get_application_server_url
? g_orig_custom_preference_get_application_server_url(method)
: nullptr;
}
void* custom_preference_get_tele_scope_server_url_hook(const MethodInfo* method) {
const auto& urls = config::get();
if (InterlockedCompareExchange(&g_cp_tele_scope_hook_called, 1, 0) == 0) {
hook_log("[cgss-dmm-hook] Cute.CustomPreference.GetTeleScopeServerURL hook invoked");
}
if (!urls.api_url.empty()) {
return il2cpp_symbols::new_string(urls.api_url.c_str());
}
return g_orig_custom_preference_get_tele_scope_server_url
? g_orig_custom_preference_get_tele_scope_server_url(method)
: nullptr;
}
void* custom_preference_get_concert_server_url_hook(const MethodInfo* method) {
const auto& urls = config::get();
if (InterlockedCompareExchange(&g_cp_concert_hook_called, 1, 0) == 0) {
hook_log("[cgss-dmm-hook] Cute.CustomPreference.GetConcertServerURL hook invoked");
}
if (!urls.api_url.empty()) {
return il2cpp_symbols::new_string(urls.api_url.c_str());
}
return g_orig_custom_preference_get_concert_server_url
? g_orig_custom_preference_get_concert_server_url(method)
: nullptr;
}
void* custom_preference_get_resource_server_url_hook(const MethodInfo* method) {
const auto& urls = config::get();
if (InterlockedCompareExchange(&g_cp_resource_hook_called, 1, 0) == 0) {
hook_log("[cgss-dmm-hook] Cute.CustomPreference.GetResourceServerURL hook invoked");
}
if (!urls.asset_url.empty()) {
return il2cpp_symbols::new_string(urls.asset_url.c_str());
}
return g_orig_custom_preference_get_resource_server_url
? g_orig_custom_preference_get_resource_server_url(method)
: nullptr;
}
void custom_preference_set_application_server_url_hook(void* value, const MethodInfo* method) {
const auto& urls = config::get();
if (InterlockedCompareExchange(&g_cp_set_application_hook_called, 1, 0) == 0) {
hook_log("[cgss-dmm-hook] Cute.CustomPreference.SetApplicationServerURL hook invoked");
}
if (g_orig_custom_preference_set_application_server_url) {
if (!urls.api_url.empty()) {
value = il2cpp_symbols::new_string(urls.api_url.c_str());
}
g_orig_custom_preference_set_application_server_url(value, method);
}
}
void custom_preference_set_tele_scope_server_url_hook(void* value, const MethodInfo* method) {
const auto& urls = config::get();
if (InterlockedCompareExchange(&g_cp_set_tele_scope_hook_called, 1, 0) == 0) {
hook_log("[cgss-dmm-hook] Cute.CustomPreference.SetTeleScopeServerURL hook invoked");
}
if (g_orig_custom_preference_set_tele_scope_server_url) {
if (!urls.api_url.empty()) {
value = il2cpp_symbols::new_string(urls.api_url.c_str());
}
g_orig_custom_preference_set_tele_scope_server_url(value, method);
}
}
void custom_preference_set_concert_server_url_hook(void* value, const MethodInfo* method) {
const auto& urls = config::get();
if (InterlockedCompareExchange(&g_cp_set_concert_hook_called, 1, 0) == 0) {
hook_log("[cgss-dmm-hook] Cute.CustomPreference.SetConcertServerURL hook invoked");
}
if (g_orig_custom_preference_set_concert_server_url) {
if (!urls.api_url.empty()) {
value = il2cpp_symbols::new_string(urls.api_url.c_str());
}
g_orig_custom_preference_set_concert_server_url(value, method);
}
}
void custom_preference_set_resource_server_url_hook(void* value, const MethodInfo* method) {
const auto& urls = config::get();
if (InterlockedCompareExchange(&g_cp_set_resource_hook_called, 1, 0) == 0) {
hook_log("[cgss-dmm-hook] Cute.CustomPreference.SetResourceServerURL hook invoked");
}
if (g_orig_custom_preference_set_resource_server_url) {
if (!urls.asset_url.empty()) {
value = il2cpp_symbols::new_string(urls.asset_url.c_str());
}
g_orig_custom_preference_set_resource_server_url(value, method);
}
}
void custom_preference_set_scheme_mode_hook(int scheme_type, const MethodInfo* method) { void custom_preference_set_scheme_mode_hook(int scheme_type, const MethodInfo* method) {
if (InterlockedCompareExchange(&g_cp_set_scheme_hook_called, 1, 0) == 0) { if (InterlockedCompareExchange(&g_cp_set_scheme_hook_called, 1, 0) == 0) {
hook_log("[cgss-dmm-hook] Cute.CustomPreference.SetScemeMode hook invoked"); hook_log("[cgss-dmm-hook] Cute.CustomPreference.SetScemeMode hook invoked");
@@ -213,8 +61,7 @@ namespace {
} }
void patch_custom_preference_scheme() { void patch_custom_preference_scheme() {
const auto& urls = config::get(); if (!config::get().force_http) {
if (!urls.force_http) {
hook_log("[cgss-dmm-hook] force_http disabled, skipping CustomPreference scheme patch"); hook_log("[cgss-dmm-hook] force_http disabled, skipping CustomPreference scheme patch");
return; return;
} }
@@ -235,6 +82,11 @@ namespace {
} }
void apply_custom_preference_url_overrides() { void apply_custom_preference_url_overrides() {
const auto& urls = config::get();
if (urls.api_url.empty() && urls.asset_url.empty()) {
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"
); );
@@ -244,9 +96,9 @@ namespace {
} }
il2cpp_symbols::il2cpp_runtime_class_init(custom_preference); il2cpp_symbols::il2cpp_runtime_class_init(custom_preference);
prepare_cached_override_strings();
const auto& urls = config::get(); if (config::get().force_http) {
if (urls.force_http) {
auto set_scheme_mode_addr = il2cpp_symbols::get_method_pointer( auto set_scheme_mode_addr = il2cpp_symbols::get_method_pointer(
"Assembly-CSharp.dll", "Cute", "CustomPreference", "SetScemeMode", 1 "Assembly-CSharp.dll", "Cute", "CustomPreference", "SetScemeMode", 1
); );
@@ -267,7 +119,7 @@ namespace {
auto set_concert_addr = il2cpp_symbols::get_method_pointer( auto set_concert_addr = il2cpp_symbols::get_method_pointer(
"Assembly-CSharp.dll", "Cute", "CustomPreference", "SetConcertServerURL", 1 "Assembly-CSharp.dll", "Cute", "CustomPreference", "SetConcertServerURL", 1
); );
auto api_value = il2cpp_symbols::new_string(urls.api_url.c_str()); auto api_value = g_cached_api_url_string;
if (set_application_addr && api_value) { if (set_application_addr && api_value) {
reinterpret_cast<SetStringFn>(set_application_addr)(api_value, nullptr); reinterpret_cast<SetStringFn>(set_application_addr)(api_value, nullptr);
hook_log("[cgss-dmm-hook] applied Cute.CustomPreference.SetApplicationServerURL"); hook_log("[cgss-dmm-hook] applied Cute.CustomPreference.SetApplicationServerURL");
@@ -286,7 +138,7 @@ namespace {
auto set_resource_addr = il2cpp_symbols::get_method_pointer( auto set_resource_addr = il2cpp_symbols::get_method_pointer(
"Assembly-CSharp.dll", "Cute", "CustomPreference", "SetResourceServerURL", 1 "Assembly-CSharp.dll", "Cute", "CustomPreference", "SetResourceServerURL", 1
); );
auto asset_value = il2cpp_symbols::new_string(urls.asset_url.c_str()); auto asset_value = g_cached_asset_url_string;
if (set_resource_addr && asset_value) { if (set_resource_addr && asset_value) {
reinterpret_cast<SetStringFn>(set_resource_addr)(asset_value, nullptr); reinterpret_cast<SetStringFn>(set_resource_addr)(asset_value, nullptr);
hook_log("[cgss-dmm-hook] applied Cute.CustomPreference.SetResourceServerURL"); hook_log("[cgss-dmm-hook] applied Cute.CustomPreference.SetResourceServerURL");
@@ -324,55 +176,28 @@ namespace {
hook_log("[cgss-dmm-hook] il2cpp exports ready"); hook_log("[cgss-dmm-hook] il2cpp exports ready");
} }
patch_custom_preference_scheme(); if (config::get().force_http) {
patch_custom_preference_scheme();
}
const auto& urls = config::get();
if (!urls.api_url.empty() || !urls.asset_url.empty()) {
prepare_cached_override_strings();
apply_custom_preference_url_overrides();
}
auto addr = il2cpp_symbols::get_method_pointer( if (!urls.force_http) {
"Assembly-CSharp.dll", "Stage", "NetworkUtil", "GetSchemeType", 0 InterlockedExchange(&g_hook_installed, 1);
); hook_log("[cgss-dmm-hook] force_http disabled, keeping original scheme");
if (!addr) {
hook_log("[cgss-dmm-hook] failed to resolve Stage.NetworkUtil.GetSchemeType");
return; return;
} }
auto get_application_server_url_addr = il2cpp_symbols::get_method_pointer( auto get_scheme_type_addr = il2cpp_symbols::get_method_pointer(
"Assembly-CSharp.dll", "Stage", "NetworkUtil", "GetApplicationServerUrl", 0 "Assembly-CSharp.dll", "Stage", "NetworkUtil", "GetSchemeType", 0
);
auto get_tele_scope_server_url_addr = il2cpp_symbols::get_method_pointer(
"Assembly-CSharp.dll", "Stage", "NetworkUtil", "GetTeleScopeServerUrl", 0
);
auto get_concert_server_url_addr = il2cpp_symbols::get_method_pointer(
"Assembly-CSharp.dll", "Stage", "NetworkUtil", "GetConcertServerUrl", 0
);
auto get_resource_server_url_addr = il2cpp_symbols::get_method_pointer(
"Assembly-CSharp.dll", "Stage", "NetworkUtil", "GetResourceServerUrl", 0
);
auto cp_get_application_server_url_addr = il2cpp_symbols::get_method_pointer(
"Assembly-CSharp.dll", "Cute", "CustomPreference", "GetApplicationServerURL", 0
);
auto cp_get_tele_scope_server_url_addr = il2cpp_symbols::get_method_pointer(
"Assembly-CSharp.dll", "Cute", "CustomPreference", "GetTeleScopeServerURL", 0
);
auto cp_get_concert_server_url_addr = il2cpp_symbols::get_method_pointer(
"Assembly-CSharp.dll", "Cute", "CustomPreference", "GetConcertServerURL", 0
);
auto cp_get_resource_server_url_addr = il2cpp_symbols::get_method_pointer(
"Assembly-CSharp.dll", "Cute", "CustomPreference", "GetResourceServerURL", 0
);
auto cp_set_application_server_url_addr = il2cpp_symbols::get_method_pointer(
"Assembly-CSharp.dll", "Cute", "CustomPreference", "SetApplicationServerURL", 1
);
auto cp_set_tele_scope_server_url_addr = il2cpp_symbols::get_method_pointer(
"Assembly-CSharp.dll", "Cute", "CustomPreference", "SetTeleScopeServerURL", 1
);
auto cp_set_concert_server_url_addr = il2cpp_symbols::get_method_pointer(
"Assembly-CSharp.dll", "Cute", "CustomPreference", "SetConcertServerURL", 1
);
auto cp_set_resource_server_url_addr = il2cpp_symbols::get_method_pointer(
"Assembly-CSharp.dll", "Cute", "CustomPreference", "SetResourceServerURL", 1
);
auto cp_set_scheme_mode_addr = il2cpp_symbols::get_method_pointer(
"Assembly-CSharp.dll", "Cute", "CustomPreference", "SetScemeMode", 1
); );
if (!get_scheme_type_addr) {
hook_log("[cgss-dmm-hook] failed to resolve Stage.NetworkUtil.GetSchemeType");
return;
}
auto mh_status = MH_Initialize(); auto mh_status = MH_Initialize();
if (mh_status != MH_OK && mh_status != MH_ERROR_ALREADY_INITIALIZED) { if (mh_status != MH_OK && mh_status != MH_ERROR_ALREADY_INITIALIZED) {
@@ -380,126 +205,24 @@ namespace {
return; return;
} }
const auto& urls = config::get(); auto create_status = MH_CreateHook(
if (urls.force_http) { reinterpret_cast<void*>(get_scheme_type_addr),
auto create_status = MH_CreateHook( reinterpret_cast<void*>(&get_scheme_type_hook),
reinterpret_cast<void*>(addr), reinterpret_cast<void**>(&g_orig_get_scheme_type)
reinterpret_cast<void*>(&get_scheme_type_hook), );
reinterpret_cast<void**>(&g_orig_get_scheme_type) if (create_status != MH_OK && create_status != MH_ERROR_ALREADY_CREATED) {
); hook_log("[cgss-dmm-hook] MH_CreateHook failed");
if (create_status != MH_OK && create_status != MH_ERROR_ALREADY_CREATED) { return;
hook_log("[cgss-dmm-hook] MH_CreateHook failed");
return;
}
auto enable_status = MH_EnableHook(reinterpret_cast<void*>(addr));
if (enable_status != MH_OK && enable_status != MH_ERROR_ENABLED) {
hook_log("[cgss-dmm-hook] MH_EnableHook failed");
return;
}
} else {
hook_log("[cgss-dmm-hook] force_http disabled, keeping original scheme");
} }
auto hook_method = [](uintptr_t address, void* detour, void** original, const char* name) { auto enable_status = MH_EnableHook(reinterpret_cast<void*>(get_scheme_type_addr));
if (!address) { if (enable_status != MH_OK && enable_status != MH_ERROR_ENABLED) {
return; hook_log("[cgss-dmm-hook] MH_EnableHook failed");
} return;
auto create_status = MH_CreateHook(reinterpret_cast<void*>(address), detour, original); }
if (create_status != MH_OK && create_status != MH_ERROR_ALREADY_CREATED) {
return;
}
auto enable_status = MH_EnableHook(reinterpret_cast<void*>(address));
if (enable_status == MH_OK || enable_status == MH_ERROR_ENABLED) {
hook_logf("[cgss-dmm-hook] hooked %s", name);
}
};
hook_method(
get_application_server_url_addr,
reinterpret_cast<void*>(&get_application_server_url_hook),
reinterpret_cast<void**>(&g_orig_get_application_server_url),
"Stage.NetworkUtil.GetApplicationServerUrl"
);
hook_method(
get_resource_server_url_addr,
reinterpret_cast<void*>(&get_resource_server_url_hook),
reinterpret_cast<void**>(&g_orig_get_resource_server_url),
"Stage.NetworkUtil.GetResourceServerUrl"
);
hook_method(
get_tele_scope_server_url_addr,
reinterpret_cast<void*>(&get_tele_scope_server_url_hook),
reinterpret_cast<void**>(&g_orig_get_tele_scope_server_url),
"Stage.NetworkUtil.GetTeleScopeServerUrl"
);
hook_method(
get_concert_server_url_addr,
reinterpret_cast<void*>(&get_concert_server_url_hook),
reinterpret_cast<void**>(&g_orig_get_concert_server_url),
"Stage.NetworkUtil.GetConcertServerUrl"
);
hook_method(
cp_get_application_server_url_addr,
reinterpret_cast<void*>(&custom_preference_get_application_server_url_hook),
reinterpret_cast<void**>(&g_orig_custom_preference_get_application_server_url),
"Cute.CustomPreference.GetApplicationServerURL"
);
hook_method(
cp_get_tele_scope_server_url_addr,
reinterpret_cast<void*>(&custom_preference_get_tele_scope_server_url_hook),
reinterpret_cast<void**>(&g_orig_custom_preference_get_tele_scope_server_url),
"Cute.CustomPreference.GetTeleScopeServerURL"
);
hook_method(
cp_get_concert_server_url_addr,
reinterpret_cast<void*>(&custom_preference_get_concert_server_url_hook),
reinterpret_cast<void**>(&g_orig_custom_preference_get_concert_server_url),
"Cute.CustomPreference.GetConcertServerURL"
);
hook_method(
cp_get_resource_server_url_addr,
reinterpret_cast<void*>(&custom_preference_get_resource_server_url_hook),
reinterpret_cast<void**>(&g_orig_custom_preference_get_resource_server_url),
"Cute.CustomPreference.GetResourceServerURL"
);
hook_method(
cp_set_application_server_url_addr,
reinterpret_cast<void*>(&custom_preference_set_application_server_url_hook),
reinterpret_cast<void**>(&g_orig_custom_preference_set_application_server_url),
"Cute.CustomPreference.SetApplicationServerURL"
);
hook_method(
cp_set_tele_scope_server_url_addr,
reinterpret_cast<void*>(&custom_preference_set_tele_scope_server_url_hook),
reinterpret_cast<void**>(&g_orig_custom_preference_set_tele_scope_server_url),
"Cute.CustomPreference.SetTeleScopeServerURL"
);
hook_method(
cp_set_concert_server_url_addr,
reinterpret_cast<void*>(&custom_preference_set_concert_server_url_hook),
reinterpret_cast<void**>(&g_orig_custom_preference_set_concert_server_url),
"Cute.CustomPreference.SetConcertServerURL"
);
hook_method(
cp_set_resource_server_url_addr,
reinterpret_cast<void*>(&custom_preference_set_resource_server_url_hook),
reinterpret_cast<void**>(&g_orig_custom_preference_set_resource_server_url),
"Cute.CustomPreference.SetResourceServerURL"
);
hook_method(
cp_set_scheme_mode_addr,
reinterpret_cast<void*>(&custom_preference_set_scheme_mode_hook),
reinterpret_cast<void**>(&g_orig_custom_preference_set_scheme_mode),
"Cute.CustomPreference.SetScemeMode"
);
apply_custom_preference_url_overrides();
InterlockedExchange(&g_hook_installed, 1); InterlockedExchange(&g_hook_installed, 1);
if (urls.force_http) { hook_log("[cgss-dmm-hook] hooked Stage.NetworkUtil.GetSchemeType");
hook_log("[cgss-dmm-hook] hooked Stage.NetworkUtil.GetSchemeType");
}
} }
DWORD WINAPI init_thread(void*) { DWORD WINAPI init_thread(void*) {
+214 -22
View File
@@ -3,36 +3,178 @@
#include "config.hpp" #include "config.hpp"
#include "hook.hpp" #include "hook.hpp"
namespace {
void load_original_version_dll();
void ensure_runtime_init_started();
template <typename Result, typename Fn, typename... Args>
Result forward_version_export(void*& original, Result failure_result, Args... args) {
if (!original) {
load_original_version_dll();
}
if (!original) {
SetLastError(ERROR_PROC_NOT_FOUND);
return failure_result;
}
Result result = reinterpret_cast<Fn>(original)(args...);
ensure_runtime_init_started();
return result;
}
}
extern "C" { extern "C" {
void* GetFileVersionInfoA_Original = nullptr; void* GetFileVersionInfoA_Original = nullptr;
void* GetFileVersionInfoW_Original = nullptr;
void* GetFileVersionInfoExA_Original = nullptr;
void* GetFileVersionInfoExW_Original = nullptr;
void* GetFileVersionInfoSizeA_Original = nullptr; void* GetFileVersionInfoSizeA_Original = nullptr;
void* GetFileVersionInfoSizeW_Original = nullptr;
void* GetFileVersionInfoSizeExA_Original = nullptr;
void* GetFileVersionInfoSizeExW_Original = nullptr;
void* VerQueryValueA_Original = nullptr; void* VerQueryValueA_Original = nullptr;
void* VerQueryValueW_Original = nullptr;
void* VerFindFileA_Original = nullptr;
void* VerFindFileW_Original = nullptr;
void* VerInstallFileA_Original = nullptr;
void* VerInstallFileW_Original = nullptr;
void* VerLanguageNameA_Original = nullptr;
void* VerLanguageNameW_Original = nullptr;
BOOL WINAPI GetFileVersionInfoA_EXPORT(LPCSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData) { BOOL WINAPI GetFileVersionInfoA_EXPORT(LPCSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData) {
using Fn = BOOL(WINAPI*)(LPCSTR, DWORD, DWORD, LPVOID); using Fn = BOOL(WINAPI*)(LPCSTR, DWORD, DWORD, LPVOID);
if (!GetFileVersionInfoA_Original) { return forward_version_export<BOOL, Fn>(
SetLastError(ERROR_PROC_NOT_FOUND); GetFileVersionInfoA_Original, FALSE, lptstrFilename, dwHandle, dwLen, lpData
return FALSE; );
} }
return reinterpret_cast<Fn>(GetFileVersionInfoA_Original)(lptstrFilename, dwHandle, dwLen, lpData);
BOOL WINAPI GetFileVersionInfoW_EXPORT(LPCWSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData) {
using Fn = BOOL(WINAPI*)(LPCWSTR, DWORD, DWORD, LPVOID);
return forward_version_export<BOOL, Fn>(
GetFileVersionInfoW_Original, FALSE, lptstrFilename, dwHandle, dwLen, lpData
);
}
BOOL WINAPI GetFileVersionInfoExA_EXPORT(
DWORD dwFlags, LPCSTR lpwstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData
) {
using Fn = BOOL(WINAPI*)(DWORD, LPCSTR, DWORD, DWORD, LPVOID);
return forward_version_export<BOOL, Fn>(
GetFileVersionInfoExA_Original, FALSE, dwFlags, lpwstrFilename, dwHandle, dwLen, lpData
);
}
BOOL WINAPI GetFileVersionInfoExW_EXPORT(
DWORD dwFlags, LPCWSTR lpwstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData
) {
using Fn = BOOL(WINAPI*)(DWORD, LPCWSTR, DWORD, DWORD, LPVOID);
return forward_version_export<BOOL, Fn>(
GetFileVersionInfoExW_Original, FALSE, dwFlags, lpwstrFilename, dwHandle, dwLen, lpData
);
} }
DWORD WINAPI GetFileVersionInfoSizeA_EXPORT(LPCSTR lptstrFilename, LPDWORD lpdwHandle) { DWORD WINAPI GetFileVersionInfoSizeA_EXPORT(LPCSTR lptstrFilename, LPDWORD lpdwHandle) {
using Fn = DWORD(WINAPI*)(LPCSTR, LPDWORD); using Fn = DWORD(WINAPI*)(LPCSTR, LPDWORD);
if (!GetFileVersionInfoSizeA_Original) { return forward_version_export<DWORD, Fn>(
SetLastError(ERROR_PROC_NOT_FOUND); GetFileVersionInfoSizeA_Original, 0, lptstrFilename, lpdwHandle
return 0; );
} }
return reinterpret_cast<Fn>(GetFileVersionInfoSizeA_Original)(lptstrFilename, lpdwHandle);
DWORD WINAPI GetFileVersionInfoSizeW_EXPORT(LPCWSTR lptstrFilename, LPDWORD lpdwHandle) {
using Fn = DWORD(WINAPI*)(LPCWSTR, LPDWORD);
return forward_version_export<DWORD, Fn>(
GetFileVersionInfoSizeW_Original, 0, lptstrFilename, lpdwHandle
);
}
DWORD WINAPI GetFileVersionInfoSizeExA_EXPORT(DWORD dwFlags, LPCSTR lpwstrFilename, LPDWORD lpdwHandle) {
using Fn = DWORD(WINAPI*)(DWORD, LPCSTR, LPDWORD);
return forward_version_export<DWORD, Fn>(
GetFileVersionInfoSizeExA_Original, 0, dwFlags, lpwstrFilename, lpdwHandle
);
}
DWORD WINAPI GetFileVersionInfoSizeExW_EXPORT(DWORD dwFlags, LPCWSTR lpwstrFilename, LPDWORD lpdwHandle) {
using Fn = DWORD(WINAPI*)(DWORD, LPCWSTR, LPDWORD);
return forward_version_export<DWORD, Fn>(
GetFileVersionInfoSizeExW_Original, 0, dwFlags, lpwstrFilename, lpdwHandle
);
} }
BOOL WINAPI VerQueryValueA_EXPORT(LPCVOID pBlock, LPCSTR lpSubBlock, LPVOID* lplpBuffer, PUINT puLen) { BOOL WINAPI VerQueryValueA_EXPORT(LPCVOID pBlock, LPCSTR lpSubBlock, LPVOID* lplpBuffer, PUINT puLen) {
using Fn = BOOL(WINAPI*)(LPCVOID, LPCSTR, LPVOID*, PUINT); using Fn = BOOL(WINAPI*)(LPCVOID, LPCSTR, LPVOID*, PUINT);
if (!VerQueryValueA_Original) { return forward_version_export<BOOL, Fn>(
SetLastError(ERROR_PROC_NOT_FOUND); VerQueryValueA_Original, FALSE, pBlock, lpSubBlock, lplpBuffer, puLen
return FALSE; );
} }
return reinterpret_cast<Fn>(VerQueryValueA_Original)(pBlock, lpSubBlock, lplpBuffer, puLen);
BOOL WINAPI VerQueryValueW_EXPORT(LPCVOID pBlock, LPCWSTR lpSubBlock, LPVOID* lplpBuffer, PUINT puLen) {
using Fn = BOOL(WINAPI*)(LPCVOID, LPCWSTR, LPVOID*, PUINT);
return forward_version_export<BOOL, Fn>(
VerQueryValueW_Original, FALSE, pBlock, lpSubBlock, lplpBuffer, puLen
);
}
DWORD WINAPI VerFindFileA_EXPORT(
DWORD uFlags, LPSTR szFileName, LPSTR szWinDir, LPSTR szAppDir,
LPSTR szCurDir, PUINT lpuCurDirLen, LPSTR szDestDir, PUINT lpuDestDirLen
) {
using Fn = DWORD(WINAPI*)(DWORD, LPSTR, LPSTR, LPSTR, LPSTR, PUINT, LPSTR, PUINT);
return forward_version_export<DWORD, Fn>(
VerFindFileA_Original,
0,
uFlags, szFileName, szWinDir, szAppDir, szCurDir, lpuCurDirLen, szDestDir, lpuDestDirLen
);
}
DWORD WINAPI VerFindFileW_EXPORT(
DWORD uFlags, LPWSTR szFileName, LPWSTR szWinDir, LPWSTR szAppDir,
LPWSTR szCurDir, PUINT lpuCurDirLen, LPWSTR szDestDir, PUINT lpuDestDirLen
) {
using Fn = DWORD(WINAPI*)(DWORD, LPWSTR, LPWSTR, LPWSTR, LPWSTR, PUINT, LPWSTR, PUINT);
return forward_version_export<DWORD, Fn>(
VerFindFileW_Original,
0,
uFlags, szFileName, szWinDir, szAppDir, szCurDir, lpuCurDirLen, szDestDir, lpuDestDirLen
);
}
DWORD WINAPI VerInstallFileA_EXPORT(
DWORD uFlags, LPSTR szSrcFileName, LPSTR szDestFileName, LPSTR szSrcDir,
LPSTR szDestDir, LPSTR szCurDir, LPSTR szTmpFile, PUINT lpuTmpFileLen
) {
using Fn = DWORD(WINAPI*)(DWORD, LPSTR, LPSTR, LPSTR, LPSTR, LPSTR, LPSTR, PUINT);
return forward_version_export<DWORD, Fn>(
VerInstallFileA_Original,
0,
uFlags, szSrcFileName, szDestFileName, szSrcDir, szDestDir, szCurDir, szTmpFile, lpuTmpFileLen
);
}
DWORD WINAPI VerInstallFileW_EXPORT(
DWORD uFlags, LPWSTR szSrcFileName, LPWSTR szDestFileName, LPWSTR szSrcDir,
LPWSTR szDestDir, LPWSTR szCurDir, LPWSTR szTmpFile, PUINT lpuTmpFileLen
) {
using Fn = DWORD(WINAPI*)(DWORD, LPWSTR, LPWSTR, LPWSTR, LPWSTR, LPWSTR, LPWSTR, PUINT);
return forward_version_export<DWORD, Fn>(
VerInstallFileW_Original,
0,
uFlags, szSrcFileName, szDestFileName, szSrcDir, szDestDir, szCurDir, szTmpFile, lpuTmpFileLen
);
}
DWORD WINAPI VerLanguageNameA_EXPORT(DWORD wLang, LPSTR szLang, DWORD nSize) {
using Fn = DWORD(WINAPI*)(DWORD, LPSTR, DWORD);
return forward_version_export<DWORD, Fn>(
VerLanguageNameA_Original, 0, wLang, szLang, nSize
);
}
DWORD WINAPI VerLanguageNameW_EXPORT(DWORD wLang, LPWSTR szLang, DWORD nSize) {
using Fn = DWORD(WINAPI*)(DWORD, LPWSTR, DWORD);
return forward_version_export<DWORD, Fn>(
VerLanguageNameW_Original, 0, wLang, szLang, nSize
);
} }
} }
@@ -42,11 +184,19 @@ namespace {
constexpr const char* kGameExeName = "imascgstage.exe"; constexpr const char* kGameExeName = "imascgstage.exe";
HMODULE g_original = nullptr; HMODULE g_original = nullptr;
volatile LONG g_helper_started = 0; volatile LONG g_helper_started = 0;
volatile LONG g_runtime_init_started = 0;
volatile LONG g_process_type = 0;
bool is_game_process() { bool is_game_process() {
LONG process_type = InterlockedCompareExchange(&g_process_type, 0, 0);
if (process_type != 0) {
return process_type == 1;
}
char path[MAX_PATH] = {}; char path[MAX_PATH] = {};
DWORD len = GetModuleFileNameA(nullptr, path, MAX_PATH); DWORD len = GetModuleFileNameA(nullptr, path, MAX_PATH);
if (len == 0 || len >= MAX_PATH) { if (len == 0 || len >= MAX_PATH) {
InterlockedCompareExchange(&g_process_type, -1, 0);
return false; return false;
} }
@@ -56,7 +206,9 @@ namespace {
base_name = p + 1; base_name = p + 1;
} }
} }
return lstrcmpiA(base_name, kGameExeName) == 0; bool is_game = lstrcmpiA(base_name, kGameExeName) == 0;
InterlockedCompareExchange(&g_process_type, is_game ? 1 : -1, 0);
return is_game;
} }
std::string get_game_directory() { std::string get_game_directory() {
@@ -81,9 +233,13 @@ namespace {
return; return;
} }
char system_dir[MAX_PATH] = {};
GetSystemDirectoryA(system_dir, MAX_PATH);
char path[MAX_PATH] = {}; char path[MAX_PATH] = {};
char system_dir[MAX_PATH] = {};
UINT system_dir_len = GetSystemDirectoryA(system_dir, MAX_PATH);
if (system_dir_len == 0 || system_dir_len >= MAX_PATH) {
hook_log("[cgss-dmm-hook] failed to resolve system directory");
return;
}
lstrcpynA(path, system_dir, MAX_PATH); lstrcpynA(path, system_dir, MAX_PATH);
lstrcatA(path, "\\version.dll"); lstrcatA(path, "\\version.dll");
@@ -94,10 +250,30 @@ namespace {
} }
GetFileVersionInfoA_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "GetFileVersionInfoA")); GetFileVersionInfoA_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "GetFileVersionInfoA"));
GetFileVersionInfoW_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "GetFileVersionInfoW"));
GetFileVersionInfoExA_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "GetFileVersionInfoExA"));
GetFileVersionInfoExW_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "GetFileVersionInfoExW"));
GetFileVersionInfoSizeA_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "GetFileVersionInfoSizeA")); GetFileVersionInfoSizeA_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "GetFileVersionInfoSizeA"));
GetFileVersionInfoSizeW_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "GetFileVersionInfoSizeW"));
GetFileVersionInfoSizeExA_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "GetFileVersionInfoSizeExA"));
GetFileVersionInfoSizeExW_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "GetFileVersionInfoSizeExW"));
VerQueryValueA_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "VerQueryValueA")); VerQueryValueA_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "VerQueryValueA"));
VerQueryValueW_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "VerQueryValueW"));
VerFindFileA_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "VerFindFileA"));
VerFindFileW_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "VerFindFileW"));
VerInstallFileA_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "VerInstallFileA"));
VerInstallFileW_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "VerInstallFileW"));
VerLanguageNameA_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "VerLanguageNameA"));
VerLanguageNameW_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "VerLanguageNameW"));
if (!GetFileVersionInfoA_Original || !GetFileVersionInfoSizeA_Original || !VerQueryValueA_Original) { if (!GetFileVersionInfoA_Original || !GetFileVersionInfoW_Original ||
!GetFileVersionInfoExA_Original || !GetFileVersionInfoExW_Original ||
!GetFileVersionInfoSizeA_Original || !GetFileVersionInfoSizeW_Original ||
!GetFileVersionInfoSizeExA_Original || !GetFileVersionInfoSizeExW_Original ||
!VerQueryValueA_Original || !VerQueryValueW_Original ||
!VerFindFileA_Original || !VerFindFileW_Original ||
!VerInstallFileA_Original || !VerInstallFileW_Original ||
!VerLanguageNameA_Original || !VerLanguageNameW_Original) {
hook_log("[cgss-dmm-hook] failed to resolve version exports"); hook_log("[cgss-dmm-hook] failed to resolve version exports");
return; return;
} }
@@ -164,22 +340,38 @@ namespace {
DWORD WINAPI init_thread(void*) { DWORD WINAPI init_thread(void*) {
Sleep(kProxyInitDelayMs); Sleep(kProxyInitDelayMs);
if (!is_game_process()) { if (!is_game_process()) {
load_original_version_dll();
hook_log("[cgss-dmm-hook] non-game process detected, skipping hook/helper startup"); hook_log("[cgss-dmm-hook] non-game process detected, skipping hook/helper startup");
return 0; return 0;
} }
config::load(); config::load();
load_original_version_dll();
start_borderless_helper(); start_borderless_helper();
start_hook_thread(); start_hook_thread();
return 0; return 0;
} }
void ensure_runtime_init_started() {
if (!is_game_process()) {
return;
}
if (InterlockedCompareExchange(&g_runtime_init_started, 1, 0) != 0) {
return;
}
HANDLE thread = CreateThread(nullptr, 0, init_thread, nullptr, 0, nullptr);
if (!thread) {
hook_logf(
"[cgss-dmm-hook] failed to create init thread, error=%lu",
static_cast<unsigned long>(GetLastError())
);
return;
}
CloseHandle(thread);
}
} }
BOOL WINAPI DllMain(HINSTANCE module, DWORD reason, LPVOID) { BOOL WINAPI DllMain(HINSTANCE module, DWORD reason, LPVOID) {
if (reason == DLL_PROCESS_ATTACH) { if (reason == DLL_PROCESS_ATTACH) {
DisableThreadLibraryCalls(module); DisableThreadLibraryCalls(module);
CreateThread(nullptr, 0, init_thread, nullptr, 0, nullptr);
} }
return TRUE; return TRUE;
} }
+13
View File
@@ -1,4 +1,17 @@
EXPORTS EXPORTS
GetFileVersionInfoA=GetFileVersionInfoA_EXPORT GetFileVersionInfoA=GetFileVersionInfoA_EXPORT
GetFileVersionInfoW=GetFileVersionInfoW_EXPORT
GetFileVersionInfoExA=GetFileVersionInfoExA_EXPORT
GetFileVersionInfoExW=GetFileVersionInfoExW_EXPORT
GetFileVersionInfoSizeA=GetFileVersionInfoSizeA_EXPORT GetFileVersionInfoSizeA=GetFileVersionInfoSizeA_EXPORT
GetFileVersionInfoSizeW=GetFileVersionInfoSizeW_EXPORT
GetFileVersionInfoSizeExA=GetFileVersionInfoSizeExA_EXPORT
GetFileVersionInfoSizeExW=GetFileVersionInfoSizeExW_EXPORT
VerQueryValueA=VerQueryValueA_EXPORT VerQueryValueA=VerQueryValueA_EXPORT
VerQueryValueW=VerQueryValueW_EXPORT
VerFindFileA=VerFindFileA_EXPORT
VerFindFileW=VerFindFileW_EXPORT
VerInstallFileA=VerInstallFileA_EXPORT
VerInstallFileW=VerInstallFileW_EXPORT
VerLanguageNameA=VerLanguageNameA_EXPORT
VerLanguageNameW=VerLanguageNameW_EXPORT