Installer FGD entries, fixed copyfiles
[tar-legacy.git] / AutoRadar_installer / main.cpp
1 #include "../MCDV/vdf.hpp"
2 #include "../MCDV/wc.hpp"
3 #include "../MCDV/util.h"
4
5 #include <windows.h>
6 #include <ShlObj_core.h>
7 #include <iostream>
8 #include <io.h>
9 #include <fstream>
10
11 #include "ConColor.h"
12
13 #include "FileSystemHelper.h"
14
15 std::string steam_install_path = "C:\\Program Files (x86)\\Steam\\";
16 std::string csgo_sdk_bin_path = "";
17
18 int exit() {
19 cc::reset();
20 system("PAUSE");
21 return -1;
22 }
23
24 int main(){
25 cc::setup();
26
27 /* Load install configuration */
28 std::ifstream ifs_vinfo("versioninfo.vdf");
29 if (!ifs_vinfo) {
30 cc::error();
31 std::cout << "versioninfo.vdf not found!!!" << std::endl;
32 return exit();
33 }
34
35 cc::info();
36
37 std::string vinfo_str((std::istreambuf_iterator<char>(ifs_vinfo)), std::istreambuf_iterator<char>());
38 kv::FileData vinfo(vinfo_str);
39 kv::DataBlock vinfodata = vinfo.headNode.SubBlocks[0];
40
41 cc::fancy(); std::cout << "Installing version: " << vinfodata.Values["version"] << "\n";
42
43 #pragma region sdk_detect
44 /* Get steam installation path */
45
46 cc::info(); std::cout << "Getting steam installation path from windows registry\n";
47
48 HKEY hKey = NULL;
49 char buffer[1024];
50
51 bool regReadSuccess = true;
52
53 if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Valve\\Steam", NULL, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS){
54 DWORD size;
55 if (RegQueryValueEx(hKey, "SteamPath", NULL, NULL, (LPBYTE)buffer, &size) == ERROR_SUCCESS){
56 steam_install_path = buffer;
57 steam_install_path += "\\";
58 }
59 else regReadSuccess = false;
60 }
61 else regReadSuccess = false;
62
63 RegCloseKey(hKey);
64
65 if (!regReadSuccess) {
66 cc::warning();
67 std::cout << "Failed to read registry key: 'Software\\Valve\\Steam\\SteamPath'\nDefaulting to C:\\Program Files (x86)\\Steam\\ installation...\n";
68 }
69
70 cc::info();
71 std::cout << "Reading steam library folders\n";
72
73 /* Read library folders file */
74
75 std::vector<std::string> libraryFolders;
76 libraryFolders.push_back(steam_install_path + "steammapps\\common\\");
77
78 std::ifstream ifs(steam_install_path + "steamapps\\libraryfolders.vdf");
79 if (!ifs) {
80 std::cout << "Libraryfolders.vdf not found. Skipping search...\n" << std::endl;
81 }
82 else {
83 std::string str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
84 kv::FileData libFolders(str);
85
86 kv::DataBlock* libFoldersDB = libFolders.headNode.GetFirstByName("\"LibraryFolders\"");
87
88 if (libFoldersDB != NULL) {
89 int index = 0;
90 while (libFoldersDB->Values.count(std::to_string(++index))) libraryFolders.push_back(libFoldersDB->Values[std::to_string(index)] + "\\steamapps\\common\\");
91 }
92 }
93
94 if (libraryFolders.size() == 0) std::cout << "No library folders found, defaulting to steamapps common folder...\n";
95
96 /* Scan for csgo sdk installations */
97
98 std::cout << "Scanning for SDK installation\n";
99
100 for (auto && folder : libraryFolders) {
101 if (_access_s((folder + "Counter-Strike Global Offensive\\bin\\SDKLauncher.exe").c_str(), 0) == 0) {
102 csgo_sdk_bin_path = folder + "Counter-Strike Global Offensive\\bin\\";
103 }
104 }
105
106 if (csgo_sdk_bin_path == "") {
107 cc::error();
108 std::cout << "Failed to find CS:GO SDK bin.\n";
109 return exit();
110 }
111
112 #pragma endregion
113
114 /* Start doing the heavy work */
115 std::cout << "Copying files\n________________________________________________________\n\n";
116
117 // Copy folders
118 for (auto && folder : vinfodata.GetAllByName("folder")){
119 std::string source_folder = kv::tryGetStringValue(folder.Values, "path");
120 std::string target_folder = kv::tryGetStringValue(folder.Values, "target");
121
122 if ((source_folder == "") || (target_folder == "")) {
123 cc::warning(); std::cout << "Missing source/destination paths. Skipping...\n";
124 continue;
125 }
126
127 cc::info();
128 std::cout << "Copying folder: " << source_folder << "\n";
129
130 source_folder = source_folder + "\\";
131 target_folder = csgo_sdk_bin_path + target_folder + "\\";
132
133 std::vector<std::string> files = fs::getFilesInDirectoryRecursive(source_folder);
134
135 for (auto && f : files) {
136 std::string fDstFolder = target_folder + fs::getDirName(f);
137
138 if (_access_s(fDstFolder.c_str(), 0)) {
139 std::cout << "mkdr " << fs::getDirName(f) << "\n";
140 SHCreateDirectoryExA(NULL, fDstFolder.c_str(), NULL);
141 }
142
143 std::cout << "copy " << f << "\n";
144
145 fs::copyFile(source_folder + f, target_folder + f);
146 }
147
148 std::cout << "\n";
149 }
150
151 // Install command sequences
152 std::cout << "Installing command sequences\n________________________________________________________\n\n";
153
154 for (auto && seqH : vinfodata.GetAllByName("CommandSequenceFile")) {
155 std::string target_file = kv::tryGetStringValue(seqH.Values, "target");
156
157 if (target_file == "") {
158 cc::warning(); std::cout << "Missing target file. Skipping CommandSeq...\n";
159 continue;
160 }
161
162 cc::info();
163
164 target_file = csgo_sdk_bin_path + target_file;
165
166 fs::copyFile(target_file, target_file + ".bak");
167
168 wc::filedata WcFile(target_file);
169
170 std::cout << "Writing to: " << kv::tryGetStringValue(seqH.Values, "target") << "\n";
171
172 for (auto && seqS : seqH.GetAllByName("Sequence")) {
173 std::cout << "Installing sequence: " << kv::tryGetStringValue(seqS.Values, "name", "error-name") << "\n";
174 std::string name = kv::tryGetStringValue(seqS.Values, "name", "error-name");
175
176 for (auto && seq : WcFile.sequences) {
177 if (strstr(seq.name, name.c_str()) != NULL) {
178 seq.write_enable = false;
179 }
180 }
181
182 wc::Sequence seq_new = wc::Sequence();
183 strcpy_s(seq_new.name, name.c_str());
184
185 for (auto && cmd : seqS.GetAllByName("Command"))
186 {
187 wc::Command command_build = wc::Command();
188 command_build.is_enabled = kv::tryGetValue(cmd.Values, "is_enabled", 0);
189 command_build.special = kv::tryGetValue(cmd.Values, "special", 0);
190 command_build.is_long_filename = kv::tryGetValue(cmd.Values, "is_long_filename", 0);
191 command_build.ensure_check = kv::tryGetValue(cmd.Values, "ensure_check", 0);
192 command_build.use_proc_win = kv::tryGetValue(cmd.Values, "use_proc_win", 0);
193 command_build.no_wait = kv::tryGetValue(cmd.Values, "no_wait", 0);;
194
195 std::string executable = kv::tryGetStringValue(cmd.Values, "executable", "error-executable");
196
197 strcpy_s(command_build.executable, executable.c_str());
198
199 std::string args = kv::tryGetStringValue(cmd.Values, "args", "error-args");
200 strcpy_s(command_build.args, args.c_str());
201
202 seq_new.commands.push_back(command_build);
203 }
204
205 WcFile.sequences.push_back(seq_new);
206 }
207
208 WcFile.serialize(target_file);
209 }
210
211 // Install custom entities
212 std::cout << "\nInstalling custom entity entries\n________________________________________________________\n\n";
213
214 std::ifstream ifs_gameconfig(csgo_sdk_bin_path + "GameConfig.txt");
215 if (!ifs_gameconfig) {
216 cc::error();
217 std::cout << "GameConfig.txt not found. custom entites will not be installed...\n" << std::endl;
218 }
219 else {
220 cc::info();
221 std::cout << "Adding GameConfig.cfg FGD entries\n";
222 fs::copyFile(csgo_sdk_bin_path + "GameConfig.txt", csgo_sdk_bin_path + "GameConfig.txt.bak");
223
224 std::string str_gameconfig((std::istreambuf_iterator<char>(ifs_gameconfig)), std::istreambuf_iterator<char>());
225 kv::FileData gameConfig(str_gameconfig);
226
227 kv::DataBlock* hammerBlock = gameConfig.headNode.SubBlocks[0].GetFirstByName("\"Games\"")->GetFirstByName("\"Counter-Strike: Global Offensive\"")->GetFirstByName("\"Hammer\"");
228 int freeIndex = -1;
229
230 for (auto && newEntry : vinfodata.GetAllByName("HammerVGDRegistry")){
231 // Check if entry exists
232 int i = -1;
233 bool matched = false;
234 while (hammerBlock->Values.count("GameData" + std::to_string(++i))) {
235 if (csgo_sdk_bin_path + newEntry.Values["source"] == hammerBlock->Values["GameData" + std::to_string(i)]) {
236 matched = true;
237 break;
238 }
239 }
240
241 if (matched) continue;
242
243 while (hammerBlock->Values.count("GameData" + std::to_string(++freeIndex)));
244 hammerBlock->Values.insert({ "GameData" + std::to_string(freeIndex), csgo_sdk_bin_path + newEntry.Values["source"]});
245 }
246
247 std::cout << "Saving GameConfig.cfg\n";
248 std::ofstream out(std::string(csgo_sdk_bin_path + "GameConfig.txt").c_str());
249 gameConfig.headNode.SubBlocks[0].Serialize(out);
250 }
251
252 cc::success(); std::cout << "\nCompleted setup!\n";
253
254 /* Small wait to auto close */
255 for (int i = 10; i > 0; i--) {
256 cc::info();
257 std::cout << "Closing in " << i << " seconds...\r";
258 Sleep(1000);
259 }
260
261 cc::reset();
262 std::cout << "\n";
263 return 0;
264 }