155 lines
5.1 KiB
C++
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;
|
|
}
|
|
}
|