From 8daf27f6b7cc2193d430f118dbf17e83517ee099 Mon Sep 17 00:00:00 2001 From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com> Date: Sat, 8 Aug 2026 22:12:55 -0500 Subject: [PATCH] fixed console commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All console commands were failing because their JavaScript handlers were still executing on the console input thread. The fix now queues JavaScript console commands and executes them from UOX3’s main thread, where SpiderMonkey is safely running. --- source/cConsole.cpp | 33 +++++++++++++++++++++++---------- source/cConsole.h | 1 + source/cThreadQueue.h | 1 + source/uox3.cpp | 3 +++ 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/source/cConsole.cpp b/source/cConsole.cpp index a70a8700c..c321176f5 100644 --- a/source/cConsole.cpp +++ b/source/cConsole.cpp @@ -992,16 +992,7 @@ auto CConsole::Process(std::int32_t c) -> void { if( toFind->second.isEnabled ) { - cScript *toExecute = JSMapping->GetScript( toFind->second.scriptId ); - if( toExecute ) - { - // All commands that execute are of the form: command_commandname (to avoid possible clashes) -#if defined( UOX_DEBUG_MODE ) - Print( oldstrutil::format( "Executing JS keystroke %c %s\n", c, toFind->second.cmdName.c_str() )); -#endif - JS::Value eventRetVal; - [[maybe_unused]] bool retVal = toExecute->CallParticularEvent( toFind->second.cmdName.c_str(), nullptr, 0, &eventRetVal ); - } + messageLoop.NewMessage( MSG_CONSOLEJS, oldstrutil::number( c )); return; } } @@ -1393,6 +1384,28 @@ auto CConsole::DisplaySettings() -> void (*this) << " -MessageBoards: " << cwmWorldState->ServerData()->Directory( CSDDP_MSGBOARD ) << myendl; } +//o------------------------------------------------------------------------------------------------o +//| Function - CConsole::ExecuteJSCommand() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Executes a registered JavaScript console command on the main server thread +//o------------------------------------------------------------------------------------------------o +auto CConsole::ExecuteJSCommand( SI32 key ) -> void +{ + auto toFind = JSKeyHandler.find( key ); + if( toFind == JSKeyHandler.end() || !toFind->second.isEnabled ) + return; + + cScript *toExecute = JSMapping->GetScript( toFind->second.scriptId ); + if( toExecute != nullptr ) + { +#if defined( UOX_DEBUG_MODE ) + Print( oldstrutil::format( "Executing JS keystroke %c %s\n", key, toFind->second.cmdName.c_str() )); +#endif + JS::Value eventRetVal; + [[maybe_unused]] bool retVal = toExecute->CallParticularEvent( toFind->second.cmdName.c_str(), nullptr, 0, &eventRetVal ); + } +} + //o------------------------------------------------------------------------------------------------o //| Function - void RegisterKey() //o------------------------------------------------------------------------------------------------o diff --git a/source/cConsole.h b/source/cConsole.h index ba54f48ae..2de010d6f 100644 --- a/source/cConsole.h +++ b/source/cConsole.h @@ -92,6 +92,7 @@ class CConsole auto SetKeyStatus( std::int32_t key, bool isEnabled ) -> void; auto SetFuncStatus( const std::string &key, bool isEnabled ) -> void; auto Registration() -> void; + auto ExecuteJSCommand( std::int32_t key ) -> void; private: auto Reset() -> void; diff --git a/source/cThreadQueue.h b/source/cThreadQueue.h index 68113d315..020cbf533 100644 --- a/source/cThreadQueue.h +++ b/source/cThreadQueue.h @@ -19,6 +19,7 @@ enum MessageType MSG_SECTIONBEGIN, MSG_RELOAD, MSG_RESTART, + MSG_CONSOLEJS, MSG_COUNT }; diff --git a/source/uox3.cpp b/source/uox3.cpp index 6f2ae4efb..563b91d01 100644 --- a/source/uox3.cpp +++ b/source/uox3.cpp @@ -941,6 +941,9 @@ auto DoMessageLoop() -> void g_bPerformRestart = true; cwmWorldState->SetKeepRun( false ); // This triggers the main loop to exit break; + case MSG_CONSOLEJS: + Console.ExecuteJSCommand( oldstrutil::value( tVal.data )); + break; case MSG_COUNT: break; case MSG_WORLDSAVE: cwmWorldState->SetOldTime( 0 ); break; case MSG_PRINT: Console << tVal.data << myendl; break;