Skip to content

Commit 4166d21

Browse files
committed
changes to launchdf to handle relocatable install
instead of assuming colocation, this version will (when both DF and DFHack are installed in Steam) automatically inject DFHack into DF environments where not both apps are installed in Steam are (hopefully) unaffected
1 parent 2d6d34e commit 4166d21

1 file changed

Lines changed: 67 additions & 7 deletions

File tree

package/launchdf.cpp

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include "steam_api.h"
1111

1212
#include <string>
13+
#include <filesystem>
14+
#include <fstream>
1315

1416
#define xstr(s) str(s)
1517
#define str(s) #s
@@ -245,14 +247,19 @@ int main(int argc, char* argv[]) {
245247
}
246248

247249
bool nowait = false;
250+
bool installmode = false;
248251
#ifdef WIN32
249252
std::wstring cmdline(lpCmdLine);
250253
if (cmdline.find(L"--nowait") != std::wstring::npos)
251254
nowait = true;
255+
if (cmdline.find(L"--install") != std::wstring::npos)
256+
installmode = true;
252257
#else
253258
for (int idx = 0; idx < argc; ++idx) {
254259
if (strcmp(argv[idx], "--nowait") == 0)
255260
nowait = true;
261+
if (strcmp(argv[idx], "--install") == 0)
262+
installmode = true;
256263
}
257264
#endif
258265

@@ -294,22 +301,75 @@ int main(int argc, char* argv[]) {
294301
char buf[2048] = "";
295302

296303
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) : "";
298305

299306
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) : "";
301308

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;
302324

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+
{
305345
#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);
307355
#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());
309365
#endif
310-
exit(1);
366+
exit(1);
367+
}
311368
}
312369

370+
if (installmode)
371+
exit(0);
372+
313373
if (!wrap_launch(launch_via_steam))
314374
exit(1);
315375

0 commit comments

Comments
 (0)