-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.cpp
More file actions
144 lines (117 loc) · 3.76 KB
/
Copy pathconfig.cpp
File metadata and controls
144 lines (117 loc) · 3.76 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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include "pch.h"
#include "config.h"
#include <algorithm>
#include <cctype>
#include <fstream>
#include <optional>
#include <string>
#include <vector>
namespace mapupdater::config {
namespace {
std::string TrimCopy(const std::string &value) {
const auto is_space = [](unsigned char ch) { return std::isspace(ch) != 0; };
auto begin = value.begin();
while (begin != value.end() && is_space(static_cast<unsigned char>(*begin))) {
++begin;
}
auto end = value.end();
while (end != begin && is_space(static_cast<unsigned char>(*(end - 1)))) {
--end;
}
return std::string(begin, end);
}
std::string ToLowerAscii(std::string value) {
std::transform(value.begin(), value.end(), value.begin(),
[](unsigned char ch) {
return static_cast<char>(std::tolower(ch));
});
return value;
}
std::optional<bool> ParseBool(std::string value) {
value = ToLowerAscii(TrimCopy(value));
if (value == "true" || value == "1" || value == "yes" || value == "on") {
return true;
}
if (value == "false" || value == "0" || value == "no" || value == "off") {
return false;
}
return std::nullopt;
}
void WriteDefaultConfig(const std::filesystem::path &path) {
std::ofstream out(path, std::ios::trunc);
if (!out.is_open()) {
return;
}
out << "[Settings]\n";
out << "debug = false\n";
out << "autoupdate = true\n";
out << "checksize = true\n";
out << "dota = true\n";
out << "lod = false\n";
out << "# Relative path from the Warcraft III root directory where MPQ files should be placed (e.g. mpq/).\n";
out << "# If empty or not set, files will be downloaded to the root Warcraft III directory.\n";
out << "# Note: Ordinary players do NOT need to change these settings. They are only intended for developers.\n";
out << "dota_files_folder =\n";
out << "lod_files_folder =\n";
}
} // namespace
std::filesystem::path SelectConfigFile(const std::filesystem::path &base_dir) {
static const std::vector<std::string> config_files = {
"MapUpdater.ini", "DotaUpdater.ini", "LodUpdater.ini"};
for (const auto &name : config_files) {
const auto candidate = base_dir / name;
std::error_code ec;
if (std::filesystem::exists(candidate, ec) && !ec) {
return candidate;
}
}
return base_dir / "MapUpdater.ini";
}
AppConfig LoadConfig(const std::filesystem::path &path) {
AppConfig config;
std::ifstream file(path);
if (!file.is_open()) {
WriteDefaultConfig(path);
return config;
}
std::string line;
while (std::getline(file, line)) {
const size_t comment_pos = line.find_first_of(";#");
if (comment_pos != std::string::npos) {
line.erase(comment_pos);
}
line = TrimCopy(line);
if (line.empty() || line.front() == '[') {
continue;
}
const size_t eq_pos = line.find('=');
if (eq_pos == std::string::npos) {
continue;
}
const std::string key = ToLowerAscii(TrimCopy(line.substr(0, eq_pos)));
const std::string raw_value = TrimCopy(line.substr(eq_pos + 1));
if (key == "dota_files_folder") {
config.dota_files_folder = raw_value;
} else if (key == "lod_files_folder") {
config.lod_files_folder = raw_value;
} else {
const auto bool_value = ParseBool(raw_value);
if (!bool_value.has_value()) {
continue;
}
if (key == "debug") {
config.debug_enabled = *bool_value;
} else if (key == "autoupdate") {
config.autoupdate_enabled = *bool_value;
} else if (key == "checksize") {
config.checksize_enabled = *bool_value;
} else if (key == "dota") {
config.dota_enabled = *bool_value;
} else if (key == "lod") {
config.lod_enabled = *bool_value;
}
}
}
return config;
}
} // namespace mapupdater::config