1 #include "../MCDV/vdf.hpp"
2 #include "../MCDV/wc.hpp"
3 #include "../MCDV/util.h"
6 #include <ShlObj_core.h>
13 #include "FileSystemHelper.h"
15 std::string steam_install_path
= "C:\\Program Files (x86)\\Steam\\";
16 std::string csgo_sdk_bin_path
= "";
27 /* Load install configuration */
28 std::ifstream
ifs_vinfo("versioninfo.vdf");
31 std::cout
<< "versioninfo.vdf not found!!!" << std::endl
;
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];
41 cc::fancy(); std::cout
<< "Installing version: " << vinfodata
.Values
["version"] << "\n";
43 #pragma region sdk_detect
44 /* Get steam installation path */
46 cc::info(); std::cout
<< "Getting steam installation path from windows registry\n";
51 bool regReadSuccess
= true;
53 if (RegOpenKeyEx(HKEY_CURRENT_USER
, "Software\\Valve\\Steam", NULL
, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
){
55 if (RegQueryValueEx(hKey
, "SteamPath", NULL
, NULL
, (LPBYTE
)buffer
, &size
) == ERROR_SUCCESS
){
56 steam_install_path
= buffer
;
57 steam_install_path
+= "\\";
59 else regReadSuccess
= false;
61 else regReadSuccess
= false;
65 if (!regReadSuccess
) {
67 std::cout
<< "Failed to read registry key: 'Software\\Valve\\Steam\\SteamPath'\nDefaulting to C:\\Program Files (x86)\\Steam\\ installation...\n";
71 std::cout
<< "Reading steam library folders\n";
73 /* Read library folders file */
75 std::vector
<std::string
> libraryFolders
;
76 libraryFolders
.push_back(steam_install_path
+ "steammapps\\common\\");
78 std::ifstream
ifs(steam_install_path
+ "steamapps\\libraryfolders.vdf");
80 std::cout
<< "Libraryfolders.vdf not found. Skipping search...\n" << std::endl
;
83 std::string
str((std::istreambuf_iterator
<char>(ifs
)), std::istreambuf_iterator
<char>());
84 kv::FileData
libFolders(str
);
86 kv::DataBlock
* libFoldersDB
= libFolders
.headNode
.GetFirstByName("\"LibraryFolders\"");
88 if (libFoldersDB
!= NULL
) {
90 while (libFoldersDB
->Values
.count(std::to_string(++index
))) libraryFolders
.push_back(libFoldersDB
->Values
[std::to_string(index
)] + "\\steamapps\\common\\");
94 if (libraryFolders
.size() == 0) std::cout
<< "No library folders found, defaulting to steamapps common folder...\n";
96 /* Scan for csgo sdk installations */
98 std::cout
<< "Scanning for SDK installation\n";
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\\";
106 if (csgo_sdk_bin_path
== "") {
108 std::cout
<< "Failed to find CS:GO SDK bin.\n";
114 /* Start doing the heavy work */
115 std::cout
<< "Copying files\n________________________________________________________\n\n";
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");
122 if ((source_folder
== "") || (target_folder
== "")) {
123 cc::warning(); std::cout
<< "Missing source/destination paths. Skipping...\n";
128 std::cout
<< "Copying folder: " << source_folder
<< "\n";
130 source_folder
= source_folder
+ "\\";
131 target_folder
= csgo_sdk_bin_path
+ target_folder
+ "\\";
133 std::vector
<std::string
> files
= fs::getFilesInDirectoryRecursive(source_folder
);
135 for (auto && f
: files
) {
136 std::string fDstFolder
= target_folder
+ fs::getDirName(f
);
138 if (_access_s(fDstFolder
.c_str(), 0)) {
139 std::cout
<< "mkdr " << fs::getDirName(f
) << "\n";
140 SHCreateDirectoryExA(NULL
, fDstFolder
.c_str(), NULL
);
143 std::cout
<< "copy " << f
<< "\n";
145 fs::copyFile(source_folder
+ f
, target_folder
+ f
);
151 // Install command sequences
152 std::cout
<< "Installing command sequences\n________________________________________________________\n\n";
154 for (auto && seqH
: vinfodata
.GetAllByName("CommandSequenceFile")) {
155 std::string target_file
= kv::tryGetStringValue(seqH
.Values
, "target");
157 if (target_file
== "") {
158 cc::warning(); std::cout
<< "Missing target file. Skipping CommandSeq...\n";
164 target_file
= csgo_sdk_bin_path
+ target_file
;
166 fs::copyFile(target_file
, target_file
+ ".bak");
168 wc::filedata
WcFile(target_file
);
170 std::cout
<< "Writing to: " << kv::tryGetStringValue(seqH
.Values
, "target") << "\n";
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");
176 for (auto && seq
: WcFile
.sequences
) {
177 if (strstr(seq
.name
, name
.c_str()) != NULL
) {
178 seq
.write_enable
= false;
182 wc::Sequence seq_new
= wc::Sequence();
183 strcpy_s(seq_new
.name
, name
.c_str());
185 for (auto && cmd
: seqS
.GetAllByName("Command"))
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);;
195 std::string executable
= kv::tryGetStringValue(cmd
.Values
, "executable", "error-executable");
197 strcpy_s(command_build
.executable
, executable
.c_str());
199 std::string args
= kv::tryGetStringValue(cmd
.Values
, "args", "error-args");
200 strcpy_s(command_build
.args
, args
.c_str());
202 seq_new
.commands
.push_back(command_build
);
205 WcFile
.sequences
.push_back(seq_new
);
208 WcFile
.serialize(target_file
);
211 // Install custom entities
212 std::cout
<< "\nInstalling custom entity entries\n________________________________________________________\n\n";
214 std::ifstream
ifs_gameconfig(csgo_sdk_bin_path
+ "GameConfig.txt");
215 if (!ifs_gameconfig
) {
217 std::cout
<< "GameConfig.txt not found. custom entites will not be installed...\n" << std::endl
;
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");
224 std::string
str_gameconfig((std::istreambuf_iterator
<char>(ifs_gameconfig
)), std::istreambuf_iterator
<char>());
225 kv::FileData
gameConfig(str_gameconfig
);
227 kv::DataBlock
* hammerBlock
= gameConfig
.headNode
.SubBlocks
[0].GetFirstByName("\"Games\"")->GetFirstByName("\"Counter-Strike: Global Offensive\"")->GetFirstByName("\"Hammer\"");
230 for (auto && newEntry
: vinfodata
.GetAllByName("HammerVGDRegistry")){
231 // Check if entry exists
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
)]) {
241 if (matched
) continue;
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"]});
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
);
252 cc::success(); std::cout
<< "\nCompleted setup!\n";
254 /* Small wait to auto close */
255 for (int i
= 10; i
> 0; i
--) {
257 std::cout
<< "Closing in " << i
<< " seconds...\r";