10 {
"camera_distance", 1200 },
12 {
"fow_client_nofiltering", 0 },
13 {
"set_rendering_enabled", 0 },
14 {
"allow_rc_update", 0 },
15 {
"visible_by_enemy", 0 },
16 {
"illusions_detection", 0 },
22 config_entries[
"camera_distance"] = ask_for_int(
"[~] Enter camera distance [default is 1200]: ", 1200, 1500);
23 config_entries[
"fog_enabled"] = ask_for_bool(
"[~] Disable fog? [y/n or 1/0]: ");
24 config_entries[
"fow_client_nofiltering"] = ask_for_bool(
"[~] Remove FoG anti-aliasing? (fow_client_nofiltering) [y/n or 1/0]: ");
25 config_entries[
"set_rendering_enabled"] = ask_for_bool(
"[~] Show hidden particles? [y/n or 1/0]: ");
26 config_entries[
"allow_rc_update"] = ask_for_bool(
"[~] Check for BETA update? [y/n or 1/0]: ");
28 config_entries[
"visible_by_enemy"] = ask_for_bool(
"[~] Visible By Enemy [y/n or 1/0]: ");
29 config_entries[
"illusions_detection"] = ask_for_bool(
"[~] Illusions Detection [y/n or 1/0]: ");
44 std::cin.ignore(10,
'\n');
45 config_entries[
"cl_weather"] = ask_for_int(
"[~] Enter Weather number: ", 1, 10) - 1;
61 config_entries[
"river_vial"] = ask_for_int(
"[~] Enter River type: ", 1, 8) - 1;
68 <<
"[~] Current settings:\n"
69 <<
"[~] Camera distance: " <<
config_entries[
"camera_distance"] <<
"\n"
70 <<
"[~] Fog disabled: " << std::boolalpha << (bool)
config_entries[
"fog_enabled"] <<
"\n"
71 <<
"[~] Remove FoG anti-aliasing: " << std::boolalpha << (
bool)
config_entries[
"fow_client_nofiltering"] <<
"\n"
72 <<
"[~] Show hidden particles: " << std::boolalpha << (bool)
config_entries[
"set_rendering_enabled"] <<
"\n"
73 <<
"[~] Check for BETA update: " << std::boolalpha << (
bool)
config_entries[
"allow_rc_update"] <<
"\n"
75 <<
"[~] Visible By Enemy: " << std::boolalpha << (bool)
config_entries[
"visible_by_enemy"] <<
"\n"
76 <<
"[~] Illusions Detection: " << std::boolalpha << (
bool)
config_entries[
"illusions_detection"] <<
"\n"
83 if (
auto path = app_data_path())
84 config_patch = *path +
"\\Dota2Patcher.json";
86 LOG::CRITICAL(
"Failed to get AppData path");
90 std::ifstream file(config_patch);
91 if (!file.is_open()) {
92 LOG::ERR(
"Config file not found! Creating a new one.");
101 if (config_file.contains(key))
104 LOG::ERR(
"Config missing key '{}'. Requesting user input.", key);
109 catch (
const std::exception& e) {
110 LOG::ERR(
"Error parsing config file: {}", e.what());
116 config_file = nlohmann::json::object();
119 config_file[key] = value;
122 std::ofstream out_file(config_patch);
124 LOG::ERR(
"Failed to open config file for writing: {}", config_patch);
128 out_file << config_file.dump(4);
133 static inline nlohmann::json config_file;
134 static inline string config_patch;
148 default:
return "Default";
152 static string int_to_river(
DOTA_RIVER river) {
162 default:
return "Default";
166 static optional <string> app_data_path() {
167 PWSTR path =
nullptr;
168 if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0,
nullptr, &path))) {
169 char charPath[MAX_PATH];
170 wcstombs(charPath, path, MAX_PATH);
172 return string(charPath);
178 static int ask_for_int(
const string& prompt,
const optional<int> min_value = nullopt,
const optional<int> max_value = nullopt) {
183 std::getline(std::cin, input);
186 value = std::stoi(input);
188 if (!min_value.has_value() || !max_value.has_value())
191 if (value < min_value.value() || value > max_value.value()) {
192 LOG::ERR(
"Input must be between {} and {}", std::to_string(min_value.value()), std::to_string(max_value.value()));
199 LOG::ERR(
"Invalid input!\n");
205 static bool ask_for_bool(
const string& prompt) {
212 if (input ==
"y" || input ==
"1") {
216 else if (input ==
"n" || input ==
"0") {
221 LOG::ERR(
"Invalid input!\n");