From 1a703c344f810ec289a42dddba9add8277c5ff75 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Mon, 15 May 2023 17:33:57 -0700 Subject: [PATCH 1/5] support disabling DFHack with --disable-dfhack --- docs/Core.rst | 19 ++++++++++++++++++- docs/changelog.txt | 1 + library/Core.cpp | 30 +++++++++++++++++------------- library/Hooks.cpp | 22 +++++++++++++++++++++- library/include/Core.h | 3 ++- 5 files changed, 59 insertions(+), 16 deletions(-) diff --git a/docs/Core.rst b/docs/Core.rst index 5decd668d..62b91c19c 100644 --- a/docs/Core.rst +++ b/docs/Core.rst @@ -53,7 +53,7 @@ double quotes. To include a double quote character, use ``\"``. If the first non-whitespace character is ``:``, the command is parsed in an alternative mode. The non-whitespace characters following the ``:`` are the command name, and the remaining part of the line is used verbatim as -the first argument. This is very useful for the `lua` and `rb` commands. +the first argument. This is very useful for the `lua` command. As an example, the following two command lines are exactly equivalent:: :foo a b "c d" e f @@ -306,6 +306,23 @@ the root DF folder. Note that ``script-paths.txt`` is only read at startup, but the paths can also be modified programmatically at any time through the `Lua API `. +Commandline options +=================== + +In addition to `Using an OS terminal`_ to execute commands on startup, DFHack +also recognizes a single commandline option that can be specified on the +commandline: + +- ``--disable-dfhack``: If this option is passed on the Dwarf Fortress + commandline, then DFHack will be disabled for the session. You will have to + restart Dwarf Fortress without specifying this option in order to use DFHack. + If you are launching Dwarf Fortress from Steam, you can enter the option in + the "Launch Options" text box in the properties for the Dwarf Fortress app. + Note that if you do this, DFHack will be disabled regardless of whether you + run Dwarf Fortress from its own app or DFHack's. You will have to clear the + DF Launch Options in order to use DFHack again. Note that even if DFHack is + disabled, :file:`stdout.txt` and :file:`stderr.txt` will still be redirected + to :file:`stdout.log` and :file:`stderr.log`, respectively. .. _env-vars: diff --git a/docs/changelog.txt b/docs/changelog.txt index fc706cdba..d602ed93a 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -48,6 +48,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## Misc Improvements - Terminal console no longer appears in front of the game window on startup - `gui/design`: Improved performance for drawing shapes +- ``Core``: For debugging purposes, you can now pass ``--disable-dfhack`` on the Dwarf Fortress commandline to disable DFHack for the session. ## Documentation diff --git a/library/Core.cpp b/library/Core.cpp index 9ff6976d5..256493dce 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -1471,16 +1471,8 @@ std::string Core::getHackPath() #endif } -bool Core::Init() -{ - if(started) - return true; - if(errorstate) - return false; - - // Lock the CoreSuspendMutex until the thread exits or call Core::Shutdown - // Core::Update will temporary unlock when there is any commands queued - MainThread::suspend().lock(); +bool Core::InitMainThread() { + Filesystem::init(); // Re-route stdout and stderr again - DF seems to set up stdout and // stderr.txt on Windows as of 0.43.05. Also, log before switching files to @@ -1496,8 +1488,6 @@ bool Core::Init() if (!freopen("stderr.log", "w", stderr)) std::cerr << "Could not redirect stderr to stderr.log" << std::endl; - Filesystem::init(); - std::cerr << "DFHack build: " << Version::git_description() << "\n" << "Starting with working directory: " << Filesystem::getcwd() << std::endl; @@ -1566,6 +1556,20 @@ bool Core::Init() // Init global object pointers df::global::InitGlobals(); + return true; +} + +bool Core::InitSimulationThread() +{ + if(started) + return true; + if(errorstate) + return false; + + // Lock the CoreSuspendMutex until the thread exits or call Core::Shutdown + // Core::Update will temporary unlock when there is any commands queued + MainThread::suspend().lock(); + std::cerr << "Initializing Console.\n"; // init the console. bool is_text_mode = (init && init->display.flag.is_set(init_display_flags::TEXT)); @@ -1965,7 +1969,7 @@ int Core::Update() if(!started) { // Initialize the core - Init(); + InitSimulationThread(); if(errorstate) return -1; } diff --git a/library/Hooks.cpp b/library/Hooks.cpp index c241e4875..1976d60d7 100644 --- a/library/Hooks.cpp +++ b/library/Hooks.cpp @@ -1,31 +1,49 @@ #include "Core.h" #include "Export.h" +#include "df/gamest.h" + +static bool disabled = false; + // called from the main thread before the simulation thread is started // and the main event loop is initiated DFhackCExport void dfhooks_init() { - // TODO: initialize things we need to do while still in the main thread + if (!DFHack::Core::getInstance().InitMainThread() || !df::global::game) + return; + const std::string & cmdline = df::global::game->command_line.original; + if (cmdline.find("--disable-dfhack") != std::string::npos) { + fprintf(stdout, "dfhack: --disable-dfhack specified on commandline; disabling\n"); + disabled = true; + } } // called from the main thread after the main event loops exits DFhackCExport void dfhooks_shutdown() { + if (disabled) + return; DFHack::Core::getInstance().Shutdown(); } // called from the simulation thread in the main event loop DFhackCExport void dfhooks_update() { + if (disabled) + return; DFHack::Core::getInstance().Update(); } // called from the simulation thread just before adding the macro // recording/playback overlay DFhackCExport void dfhooks_prerender() { + if (disabled) + return; // TODO: render overlay widgets that are not attached to a viewscreen } // called from the main thread for each SDL event. if true is returned, then // the event has been consumed and further processing shouldn't happen DFhackCExport bool dfhooks_sdl_event(SDL::Event* event) { + if (disabled) + return false; return DFHack::Core::getInstance().DFH_SDL_Event(event); } @@ -34,5 +52,7 @@ DFhackCExport bool dfhooks_sdl_event(SDL::Event* event) { // if true is returned, then the event has been consumed and further processing // shouldn't happen DFhackCExport bool dfhooks_ncurses_key(int key) { + if (disabled) + return false; return DFHack::Core::getInstance().DFH_ncurses_key(key); } diff --git a/library/include/Core.h b/library/include/Core.h index 386769fcb..696be4ead 100644 --- a/library/include/Core.h +++ b/library/include/Core.h @@ -191,7 +191,8 @@ namespace DFHack struct Private; std::unique_ptr d; - bool Init(); + bool InitMainThread(); + bool InitSimulationThread(); int Update (void); int Shutdown (void); bool DFH_SDL_Event(SDL::Event* event); From 9f997eaade3776997379a440af0018c6980aa8f2 Mon Sep 17 00:00:00 2001 From: Myk Date: Mon, 15 May 2023 17:54:45 -0700 Subject: [PATCH 2/5] Update docs/changelog.txt Co-authored-by: Alan --- docs/changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index d602ed93a..529eebfff 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -48,7 +48,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## Misc Improvements - Terminal console no longer appears in front of the game window on startup - `gui/design`: Improved performance for drawing shapes -- ``Core``: For debugging purposes, you can now pass ``--disable-dfhack`` on the Dwarf Fortress commandline to disable DFHack for the session. +- Core: For debugging purposes, you can now pass ``--disable-dfhack`` on the Dwarf Fortress commandline to disable DFHack for the session. ## Documentation From a62993b90b6c21f0f1f93dbd685e3fd19f158b73 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Mon, 15 May 2023 18:15:46 -0700 Subject: [PATCH 3/5] add DFHACK_DISABLE env var --- docs/Core.rst | 5 +++++ library/Hooks.cpp | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/docs/Core.rst b/docs/Core.rst index 62b91c19c..0e333702f 100644 --- a/docs/Core.rst +++ b/docs/Core.rst @@ -336,6 +336,11 @@ on UNIX-like systems: DFHACK_SOME_VAR=1 ./dfhack +- ``DFHACK_DISABLE``: if set, DFHack will not initialize, not even to redirect + :file:`stdout.txt` or :file:`stderr.txt`. This is provided as an alternative + to the ``--disable-dfhack`` commandline parameter above for when environment + variables are more convenient. + - ``DFHACK_PORT``: the port to use for the RPC server (used by ``dfhack-run`` and `remotefortressreader` among others) instead of the default ``5000``. As with the default, if this port cannot be used, the server is not started. diff --git a/library/Hooks.cpp b/library/Hooks.cpp index 1976d60d7..4e339e768 100644 --- a/library/Hooks.cpp +++ b/library/Hooks.cpp @@ -8,6 +8,13 @@ static bool disabled = false; // called from the main thread before the simulation thread is started // and the main event loop is initiated DFhackCExport void dfhooks_init() { + if (getenv("DFHACK_DISABLE")) { + fprintf(stdout, "dfhack: DFHACK_DISABLE detected in environment; disabling\n"); + disabled = true; + return; + } + + // we need to init DF globals before we can check the commandline if (!DFHack::Core::getInstance().InitMainThread() || !df::global::game) return; const std::string & cmdline = df::global::game->command_line.original; From b845ea15b8050758797c0694380dc163106d85d5 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Mon, 15 May 2023 18:34:43 -0700 Subject: [PATCH 4/5] update changelog --- docs/changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index 529eebfff..80d07eff4 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -48,7 +48,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## Misc Improvements - Terminal console no longer appears in front of the game window on startup - `gui/design`: Improved performance for drawing shapes -- Core: For debugging purposes, you can now pass ``--disable-dfhack`` on the Dwarf Fortress commandline to disable DFHack for the session. +- Core: For debugging purposes, you can now pass ``--disable-dfhack`` on the Dwarf Fortress commandline or specify ``DFHACK_DISABLE=1`` in the environment to disable DFHack for the current session. ## Documentation From 6b2c805d5f813b193f959758afdb5431f42fedc9 Mon Sep 17 00:00:00 2001 From: Myk Date: Mon, 15 May 2023 22:12:12 -0700 Subject: [PATCH 5/5] Update docs/Core.rst Co-authored-by: Alan --- docs/Core.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Core.rst b/docs/Core.rst index 0e333702f..763858b61 100644 --- a/docs/Core.rst +++ b/docs/Core.rst @@ -337,7 +337,7 @@ on UNIX-like systems: DFHACK_SOME_VAR=1 ./dfhack - ``DFHACK_DISABLE``: if set, DFHack will not initialize, not even to redirect - :file:`stdout.txt` or :file:`stderr.txt`. This is provided as an alternative + standard output or standard error. This is provided as an alternative to the ``--disable-dfhack`` commandline parameter above for when environment variables are more convenient.