From 6cf7defdec2be4e777d7312fcc2034b08470949c Mon Sep 17 00:00:00 2001 From: Diavolo Date: Sat, 25 Jun 2022 14:22:13 +0200 Subject: [PATCH] [Script] Fix bug --- src/Components/Modules/Script.cpp | 96 ++++++++++++++++--------------- src/Components/Modules/Script.hpp | 14 +++-- src/Game/Functions.cpp | 1 + src/Game/Functions.hpp | 9 ++- 4 files changed, 66 insertions(+), 54 deletions(-) diff --git a/src/Components/Modules/Script.cpp b/src/Components/Modules/Script.cpp index 95d64240..1d9bd018 100644 --- a/src/Components/Modules/Script.cpp +++ b/src/Components/Modules/Script.cpp @@ -3,16 +3,19 @@ namespace Components { std::string Script::ScriptName; - std::vector Script::ScriptHandles; std::unordered_map Script::CustomScrFunctions; std::unordered_map Script::CustomScrMethods; std::vector Script::ScriptNameStack; unsigned short Script::FunctionName; std::unordered_map Script::ScriptStorage; std::unordered_map Script::ScriptBaseProgramNum; + int Script::LastFrameTime = -1; + std::unordered_map Script::ReplacedFunctions; const char* Script::ReplacedPos = nullptr; - int Script::LastFrameTime = -1; + + std::vector Script::ScriptMainHandles; + std::vector Script::ScriptInitHandles; void Script::FunctionError() { @@ -201,68 +204,70 @@ namespace Components Logger::Error(Game::ERR_SCRIPT_DROP, "script compile error\n{}\n{}\n(see console for actual details)\n", msgbuf, Script::ScriptName); } - int Script::LoadScriptAndLabel(const std::string& script, const std::string& label) + void Script::Scr_LoadGameType_Stub() { - Logger::Print("Loading script {}.gsc...\n", script); - - if (!Game::Scr_LoadScript(script.data())) + for (const auto& handle : Script::ScriptMainHandles) { - Logger::Print("Script {} encountered an error while loading. (doesn't exist?)", script); - Logger::Error(Game::ERR_DROP, "Could not find script '{}'", script); - } - else - { - Logger::Print("Script {}.gsc loaded successfully.\n", script); - } - - Logger::Debug("Finding script handle {}::{}...", script.data(), label.data()); - const auto handle = Game::Scr_GetFunctionHandle(script.data(), label.data()); - if (handle) - { - Logger::Print("Script handle {}::{} loaded successfully.\n", script, label); - return handle; - } - - Logger::Print("Script handle {}::{} couldn't be loaded. (file with no entry point?)\n", script, label); - return handle; - } - - void Script::LoadGameType() - { - for (const auto& handle : Script::ScriptHandles) - { - Game::Scr_FreeThread(Game::Scr_ExecThread(handle, 0)); + const auto id = Game::Scr_ExecThread(handle, 0); + Game::Scr_FreeThread(static_cast(id)); } Game::Scr_LoadGameType(); } - void Script::LoadGameTypeScript() + void Script::Scr_StartupGameType_Stub() { - Script::ScriptHandles.clear(); + for (const auto& handle : Script::ScriptInitHandles) + { + const auto id = Game::Scr_ExecThread(handle, 0); + Game::Scr_FreeThread(static_cast(id)); + } + + Game::Scr_StartupGameType(); + } + + void Script::GScr_LoadGameTypeScript_Stub() + { + // Clear handles (from previous GSC loading session) + Script::ScriptMainHandles.clear(); + Script::ScriptInitHandles.clear(); const auto list = FileSystem::GetFileList("scripts/", "gsc"); - for (auto file : list) + for (const auto& file : list) { - file.insert(0, "scripts/"); + std::string script = "scripts/" + file; - if (Utils::String::EndsWith(file, ".gsc")) + if (Utils::String::EndsWith(script, ".gsc")) { - file = file.substr(0, file.size() - 4); + script = script.substr(0, script.size() - 4); } - auto handle = Script::LoadScriptAndLabel(file, "init"); + Logger::Print("Loading script {}.gsc...\n", script); - if (handle) + if (!Game::Scr_LoadScript(script.data())) { - Script::ScriptHandles.push_back(handle); + Logger::Print("Script {} encountered an error while loading. (doesn't exist?)", script); + Logger::Error(Game::ERR_DROP, "Could not find script '{}'", script); + return; } - else + + Logger::Print("Script {}.gsc loaded successfully.\n", script); + Logger::Debug("Finding script handle main or init..."); + + const auto initHandle = Game::Scr_GetFunctionHandle(script.data(), "init"); + if (initHandle != 0) { - handle = Script::LoadScriptAndLabel(file, "main"); - if (handle) Script::ScriptHandles.push_back(handle); + Script::ScriptInitHandles.push_back(initHandle); } + + const auto mainHandle = Game::Scr_GetFunctionHandle(script.data(), "main"); + if (mainHandle != 0) + { + Script::ScriptMainHandles.push_back(mainHandle); + } + + // Allow scripts with no handles } Game::GScr_LoadGameTypeScript(); @@ -687,8 +692,9 @@ namespace Components Utils::Hook(0x612EA2, Script::FunctionError, HOOK_CALL).install()->quick(); Utils::Hook(0x434260, Script::CompileError, HOOK_JUMP).install()->quick(); - Utils::Hook(0x48EFFE, Script::LoadGameType, HOOK_CALL).install()->quick(); - Utils::Hook(0x45D44A, Script::LoadGameTypeScript, HOOK_CALL).install()->quick(); + Utils::Hook(0x48EFFE, Script::Scr_LoadGameType_Stub, HOOK_CALL).install()->quick(); + Utils::Hook(0x48F008, Script::Scr_StartupGameType_Stub, HOOK_CALL).install()->quick(); + Utils::Hook(0x45D44A, Script::GScr_LoadGameTypeScript_Stub, HOOK_CALL).install()->quick(); // Fetch custom functions Utils::Hook(0x44E72E, Script::BuiltIn_GetFunctionStub, HOOK_CALL).install()->quick(); // Scr_GetFunction diff --git a/src/Components/Modules/Script.hpp b/src/Components/Modules/Script.hpp index 8ef576ab..73cbfeab 100644 --- a/src/Components/Modules/Script.hpp +++ b/src/Components/Modules/Script.hpp @@ -8,8 +8,6 @@ namespace Components public: Script(); - static int LoadScriptAndLabel(const std::string& script, const std::string& label); - static void AddFunction(const char* name, Game::BuiltinFunction func, int type = 0); static void AddMethod(const char* name, Game::BuiltinMethod func, int type = 0); @@ -19,16 +17,19 @@ namespace Components private: static std::string ScriptName; - static std::vector ScriptHandles; static std::unordered_map CustomScrFunctions; static std::unordered_map CustomScrMethods; static std::vector ScriptNameStack; static unsigned short FunctionName; static std::unordered_map ScriptStorage; static std::unordered_map ScriptBaseProgramNum; + static int LastFrameTime; + + static std::vector ScriptMainHandles; + static std::vector ScriptInitHandles; + static std::unordered_map ReplacedFunctions; static const char* ReplacedPos; - static int LastFrameTime; static void CompileError(unsigned int offset, const char* message, ...); static void PrintSourcePos(const char* filename, unsigned int offset); @@ -43,8 +44,9 @@ namespace Components static void RestoreScriptName(); static void RestoreScriptNameStub(); - static void LoadGameType(); - static void LoadGameTypeScript(); + static void Scr_LoadGameType_Stub(); + static void Scr_StartupGameType_Stub(); + static void GScr_LoadGameTypeScript_Stub(); static Game::BuiltinFunction BuiltIn_GetFunctionStub(const char** pName, int* type); static Game::BuiltinMethod BuiltIn_GetMethod(const char** pName, int* type); diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 15c1be07..d5959113 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -274,6 +274,7 @@ namespace Game RemoveRefToObject_t RemoveRefToObject = RemoveRefToObject_t(0x437190); Scr_LoadGameType_t Scr_LoadGameType = Scr_LoadGameType_t(0x4D9520); + Scr_StartupGameType_t Scr_StartupGameType = Scr_StartupGameType_t(0x438720); Scr_LoadScript_t Scr_LoadScript = Scr_LoadScript_t(0x45D940); Scr_GetFunctionHandle_t Scr_GetFunctionHandle = Scr_GetFunctionHandle_t(0x4234F0); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index bec366d7..b244694b 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -717,9 +717,12 @@ namespace Game typedef void(__cdecl * Scr_ShutdownAllocNode_t)(); extern Scr_ShutdownAllocNode_t Scr_ShutdownAllocNode; - typedef int(__cdecl * Scr_LoadGameType_t)(); + typedef void(__cdecl * Scr_LoadGameType_t)(); extern Scr_LoadGameType_t Scr_LoadGameType; + typedef void(__cdecl * Scr_StartupGameType_t)(); + extern Scr_StartupGameType_t Scr_StartupGameType; + typedef int(__cdecl * Scr_LoadScript_t)(const char*); extern Scr_LoadScript_t Scr_LoadScript; @@ -750,13 +753,13 @@ namespace Game typedef int(__cdecl * Scr_GetFunctionHandle_t)(const char* filename, const char* name); extern Scr_GetFunctionHandle_t Scr_GetFunctionHandle; - typedef int(__cdecl * Scr_ExecThread_t)(int, int); + typedef int(__cdecl * Scr_ExecThread_t)(int handle, unsigned int paramcount); extern Scr_ExecThread_t Scr_ExecThread; typedef int(__cdecl * Scr_ExecEntThread_t)(gentity_s* ent, int handle, unsigned int paramcount); extern Scr_ExecEntThread_t Scr_ExecEntThread; - typedef int(__cdecl * Scr_FreeThread_t)(int); + typedef void(__cdecl * Scr_FreeThread_t)(unsigned __int16 handle); extern Scr_FreeThread_t Scr_FreeThread; typedef void(__cdecl * Scr_Notify_t)(gentity_t *ent, unsigned __int16 stringValue, unsigned int paramcount);