Files
cgss-http-hook/src/config.cpp
T
2026-06-23 20:51:38 +08:00

155 lines
5.1 KiB
C++

#include "stdinclude.hpp"
#include "config.hpp"
namespace config {
namespace {
OverrideUrls g_urls;
bool g_loaded = false;
constexpr const wchar_t* kConfigErrorTitleW = L"cgss-dmm-hook";
constexpr const wchar_t* kApiUrlRequiredMessageW =
L"config.json \u4E2D\u5FC5\u987B\u8BBE\u7F6E\u975E\u7A7A api_url\u3002";
constexpr const char* kDefaultAssetUrl = "asset-starlight-stage.akamaized.net/";
std::string get_config_path() {
char path[MAX_PATH] = {};
DWORD len = GetModuleFileNameA(nullptr, path, MAX_PATH);
if (len == 0 || len >= MAX_PATH) {
return {};
}
char* last_sep = path;
for (char* p = path; *p != '\0'; ++p) {
if (*p == '\\' || *p == '/') {
last_sep = p;
}
}
*last_sep = '\0';
lstrcatA(path, "\\config.json");
return path;
}
std::string normalize_base_url(std::string value) {
if (value.empty()) {
return value;
}
constexpr const char* kHttp = "http://";
constexpr const char* kHttps = "https://";
if (value.rfind(kHttp, 0) == 0) {
value.erase(0, lstrlenA(kHttp));
} else if (value.rfind(kHttps, 0) == 0) {
value.erase(0, lstrlenA(kHttps));
}
while (!value.empty() && value.front() == '/') {
value.erase(value.begin());
}
if (value.empty()) {
return value;
}
if (value.back() != '/') {
value.push_back('/');
}
return value;
}
std::string make_default_config_json() {
return
"{\r\n"
" \"force_http\": true,\r\n"
" \"api_url\": \"\",\r\n"
" \"asset_url\": \"asset-starlight-stage.akamaized.net/\",\r\n"
" \"launch_borderless_helper\": true\r\n"
"}\r\n";
}
void read_string(const rapidjson::Document& document, const char* key, std::string& out) {
if (!document.HasMember(key) || !document[key].IsString()) {
return;
}
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();
}
}
bool load() {
if (g_loaded) {
return !g_urls.api_url.empty();
}
g_loaded = true;
const auto config_path = get_config_path();
if (config_path.empty()) {
hook_log("[cgss-dmm-hook] failed to resolve config.json path");
return false;
}
std::ifstream config_stream(config_path);
if (!config_stream.is_open()) {
std::ofstream output_stream(config_path, std::ios::binary);
if (output_stream.is_open()) {
output_stream << make_default_config_json();
output_stream.close();
hook_log("[cgss-dmm-hook] config.json not found, generated default config.json");
} else {
hook_log("[cgss-dmm-hook] config.json not found, failed to generate default config.json");
}
return false;
}
rapidjson::IStreamWrapper wrapper(config_stream);
rapidjson::Document document;
document.ParseStream(wrapper);
if (document.HasParseError() || !document.IsObject()) {
hook_log("[cgss-dmm-hook] failed to parse config.json");
return false;
}
read_bool(document, "force_http", g_urls.force_http);
read_string(document, "api_url", g_urls.api_url);
read_string(document, "asset_url", g_urls.asset_url);
read_bool(document, "launch_borderless_helper", g_urls.launch_borderless_helper);
hook_logf("[cgss-dmm-hook] force_http=%s", g_urls.force_http ? "true" : "false");
hook_logf(
"[cgss-dmm-hook] launch_borderless_helper=%s",
g_urls.launch_borderless_helper ? "true" : "false"
);
if (!g_urls.api_url.empty()) {
hook_logf("[cgss-dmm-hook] normalized api_url=%s", g_urls.api_url.c_str());
} else {
hook_log("[cgss-dmm-hook] api_url is empty");
MessageBoxW(
nullptr,
kApiUrlRequiredMessageW,
kConfigErrorTitleW,
MB_OK | MB_ICONERROR | MB_TOPMOST
);
return false;
}
if (g_urls.asset_url.empty()) {
g_urls.asset_url = kDefaultAssetUrl;
hook_logf("[cgss-dmm-hook] asset_url is empty, fallback to %s", g_urls.asset_url.c_str());
} else {
hook_logf("[cgss-dmm-hook] normalized asset_url=%s", g_urls.asset_url.c_str());
}
return true;
}
const OverrideUrls& get() {
return g_urls;
}
}