-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathruntime.cpp
More file actions
122 lines (96 loc) · 3 KB
/
runtime.cpp
File metadata and controls
122 lines (96 loc) · 3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include "pch.h"
#include "runtime.h"
#include "config.h"
#include <cstdio>
#include <filesystem>
#include <iostream>
#include <mutex>
#include <optional>
namespace mapupdater::runtime {
namespace {
HMODULE g_module_handle = nullptr;
std::once_flag g_init_once;
bool g_debug_console_enabled = false;
RuntimeState g_runtime_state;
std::optional<std::filesystem::path> GetModuleDirectory() {
if (g_module_handle == nullptr) {
return std::nullopt;
}
wchar_t buffer[MAX_PATH] = {};
const DWORD len = GetModuleFileNameW(g_module_handle, buffer, MAX_PATH);
if (len == 0 || len >= MAX_PATH) {
return std::nullopt;
}
return std::filesystem::path(buffer).parent_path();
}
void EnableDebugConsole() {
if (g_debug_console_enabled) {
return;
}
if (!AllocConsole() && GetLastError() != ERROR_ACCESS_DENIED) {
return;
}
SetConsoleOutputCP(CP_UTF8);
SetConsoleTitleA("MapUpdater Debug");
FILE *fp = nullptr;
freopen_s(&fp, "CONOUT$", "w", stdout);
freopen_s(&fp, "CONOUT$", "w", stderr);
g_debug_console_enabled = true;
std::cout << "[Debug] Debug console enabled" << std::endl;
}
void InitializeRuntime() {
std::filesystem::path base_dir;
if (const auto module_dir = GetModuleDirectory(); module_dir.has_value()) {
base_dir = *module_dir;
} else {
std::error_code ec;
base_dir = std::filesystem::current_path(ec);
if (ec) {
base_dir = ".";
}
}
g_runtime_state.module_dir = base_dir;
g_runtime_state.config_path = config::SelectConfigFile(base_dir);
g_runtime_state.config = config::LoadConfig(g_runtime_state.config_path);
if (g_runtime_state.config.debug_enabled) {
EnableDebugConsole();
std::cout << "[Debug] Config used: " << g_runtime_state.config_path.string()
<< std::endl;
}
}
} // namespace
void RegisterModuleHandle(HMODULE module_handle) { g_module_handle = module_handle; }
const RuntimeState &GetRuntimeState() {
std::call_once(g_init_once, InitializeRuntime);
return g_runtime_state;
}
std::string WideToUtf8(const std::wstring &value) {
if (value.empty()) {
return {};
}
const int size = WideCharToMultiByte(
CP_UTF8, 0, value.data(), static_cast<int>(value.size()), nullptr, 0,
nullptr, nullptr);
if (size <= 0) {
return {};
}
std::string result(static_cast<size_t>(size), '\0');
WideCharToMultiByte(CP_UTF8, 0, value.data(), static_cast<int>(value.size()),
result.data(), size, nullptr, nullptr);
return result;
}
std::wstring Utf8ToWide(const std::string &value) {
if (value.empty()) {
return {};
}
const int size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, value.data(),
static_cast<int>(value.size()), nullptr, 0);
if (size <= 0) {
return {};
}
std::wstring result(static_cast<size_t>(size), L'\0');
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, value.data(),
static_cast<int>(value.size()), result.data(), size);
return result;
}
} // namespace mapupdater::runtime