|
10 | 10 | #include "steam_api.h" |
11 | 11 |
|
12 | 12 | #include <string> |
| 13 | +#include <filesystem> |
| 14 | +#include <fstream> |
13 | 15 |
|
14 | 16 | #define xstr(s) str(s) |
15 | 17 | #define str(s) #s |
@@ -245,14 +247,19 @@ int main(int argc, char* argv[]) { |
245 | 247 | } |
246 | 248 |
|
247 | 249 | bool nowait = false; |
| 250 | + bool installmode = false; |
248 | 251 | #ifdef WIN32 |
249 | 252 | std::wstring cmdline(lpCmdLine); |
250 | 253 | if (cmdline.find(L"--nowait") != std::wstring::npos) |
251 | 254 | nowait = true; |
| 255 | + if (cmdline.find(L"--install") != std::wstring::npos) |
| 256 | + installmode = true; |
252 | 257 | #else |
253 | 258 | for (int idx = 0; idx < argc; ++idx) { |
254 | 259 | if (strcmp(argv[idx], "--nowait") == 0) |
255 | 260 | nowait = true; |
| 261 | + if (strcmp(argv[idx], "--install") == 0) |
| 262 | + installmode = true; |
256 | 263 | } |
257 | 264 | #endif |
258 | 265 |
|
@@ -294,22 +301,75 @@ int main(int argc, char* argv[]) { |
294 | 301 | char buf[2048] = ""; |
295 | 302 |
|
296 | 303 | int b1 = SteamApps()->GetAppInstallDir(DFHACK_STEAM_APPID, (char*)&buf, 2048); |
297 | | - std::string dfhack_install_folder = (b1 != -1) ? std::string(buf) : ""; |
| 304 | + std::filesystem::path dfhack_install_folder = (b1 != -1) ? std::string(buf) : ""; |
298 | 305 |
|
299 | 306 | int b2 = SteamApps()->GetAppInstallDir(DF_STEAM_APPID, (char*)&buf, 2048); |
300 | | - std::string df_install_folder = (b2 != -1) ? std::string(buf) : ""; |
| 307 | + std::filesystem::path df_install_folder = (b2 != -1) ? std::string(buf) : ""; |
301 | 308 |
|
| 309 | + if (df_install_folder != dfhack_install_folder) |
| 310 | + { |
| 311 | +#ifdef WIN32 |
| 312 | + constexpr auto dfhooks_dll_name = "dfhooks.dll"; |
| 313 | + constexpr auto dfhook_dfhack_dll_name = "dfhooks_dfhack.dll"; |
| 314 | +#else |
| 315 | + constexpr auto dfhooks_dll_name = "libdfhooks.so"; |
| 316 | + constexpr auto dfhook_dfhack_dll_name = "libdfhooks_dfhack.so"; |
| 317 | +#endif |
| 318 | + // DF and DFHack are not co-installed (modern case) |
| 319 | + // inject dfhooks.dll and dfhooks_dfhack.ini into DF install folder |
| 320 | + std::filesystem::path dfhooks_dll_src = dfhack_install_folder / dfhooks_dll_name; |
| 321 | + std::filesystem::path dfhooks_dll_dst = df_install_folder / dfhooks_dll_name; |
| 322 | + std::filesystem::path dfhooks_ini_dst = df_install_folder / "dfhooks_dfhack.ini"; |
| 323 | + std::filesystem::path dfhooks_dfhack_dll_src = dfhack_install_folder / "hack" / dfhook_dfhack_dll_name; |
302 | 324 |
|
303 | | - if (df_install_folder != dfhack_install_folder) { |
304 | | - // DF and DFHack are not installed in the same library |
| 325 | + std::error_code ec; |
| 326 | + |
| 327 | + std::filesystem::copy(dfhooks_dll_src, dfhooks_dll_dst, std::filesystem::copy_options::update_existing, ec); |
| 328 | + if (!ec) |
| 329 | + { |
| 330 | + std::string indirection; |
| 331 | + if (std::filesystem::exists(dfhooks_ini_dst)) |
| 332 | + { |
| 333 | + std::ifstream ini(dfhooks_ini_dst); |
| 334 | + std::getline(ini, indirection); |
| 335 | + } |
| 336 | + |
| 337 | + if (indirection != dfhooks_dfhack_dll_src.string()) |
| 338 | + { |
| 339 | + std::ofstream ini(dfhooks_ini_dst); |
| 340 | + ini << dfhooks_dfhack_dll_src.string() << std::endl; |
| 341 | + } |
| 342 | + } |
| 343 | + else |
| 344 | + { |
305 | 345 | #ifdef WIN32 |
306 | | - MessageBoxW(NULL, L"DFHack and Dwarf Fortress must be installed in the same Steam library.\nAborting.", NULL, 0); |
| 346 | + std::wstring message{ |
| 347 | + L"Failed to inject DFHack into Dwarf Fortress\n\n" |
| 348 | + L"Details:\n" + std::filesystem::relative(dfhooks_dll_src).wstring() + |
| 349 | + L" -> " + std::filesystem::relative(dfhooks_dll_dst).wstring() + |
| 350 | + L"\n\nError code: " + std::to_wstring(ec.value()) + |
| 351 | + L"\nError message: " + std::filesystem::relative(ec.message()).wstring() |
| 352 | + }; |
| 353 | + |
| 354 | + MessageBoxW(NULL, message.c_str(), NULL, 0); |
307 | 355 | #else |
308 | | - notify("DFHack and Dwarf Fortress must be installed in the same Steam library.\nAborting."); |
| 356 | + std::string message{ |
| 357 | + "Failed to inject DFHack into Dwarf Fortress\n\n" |
| 358 | + "Details:\n" + std::filesystem::relative(dfhooks_dll_src).string() + |
| 359 | + " -> " + std::filesystem::relative(dfhooks_dll_dst).string() + |
| 360 | + "\n\nError code: " + std::to_string(ec.value()) + |
| 361 | + "\nError message: " + std::filesystem::relative(ec.message()).string() |
| 362 | + }; |
| 363 | + |
| 364 | + notify(message.c_str()); |
309 | 365 | #endif |
310 | | - exit(1); |
| 366 | + exit(1); |
| 367 | + } |
311 | 368 | } |
312 | 369 |
|
| 370 | + if (installmode) |
| 371 | + exit(0); |
| 372 | + |
313 | 373 | if (!wrap_launch(launch_via_steam)) |
314 | 374 | exit(1); |
315 | 375 |
|
|
0 commit comments