From 9a3b9534787434129bc738282b8fcc2364e4d693 Mon Sep 17 00:00:00 2001 From: ineedbots Date: Wed, 30 Jun 2021 12:47:54 -0600 Subject: [PATCH] Completed custom script loading --- src/Components/Modules/Script.cpp | 59 +++++++++++++++++++++++++------ src/Game/Game.cpp | 42 ++++++++++++++++++++-- src/Game/Game.hpp | 5 ++- 3 files changed, 93 insertions(+), 13 deletions(-) diff --git a/src/Components/Modules/Script.cpp b/src/Components/Modules/Script.cpp index a102ad4..61bc081 100644 --- a/src/Components/Modules/Script.cpp +++ b/src/Components/Modules/Script.cpp @@ -35,16 +35,6 @@ namespace Components return got->second.call; } - void Script::GScr_LoadGameTypeScript_Hook() - { - Game::GScr_LoadGameTypeScript(); - } - - void Script::G_LoadStructs_Hook() - { - Game::G_LoadStructs(); - } - Game::xfunction_t Script::Scr_GetFunction_Hook(const char** name, int* isDev) { auto got = CustomScrFunctions.find(*name); @@ -56,6 +46,55 @@ namespace Components return got->second.call; } + void Script::GScr_LoadGameTypeScript_Hook() + { + CustomScrHandles.clear(); + + Game::FS_ForEachFile("scripts", "gsc", [](char* filename) + { + std::string file = filename; + std::string label = "init"; + + file = "scripts/" + file; + + if (Utils::String::EndsWith(file, ".gsc")) + file = file.substr(0, file.size() - 4); + + Game::Com_Printf("Loading script %s.gsc...\n", file.data()); + + if (!Game::Scr_LoadScript(file.data())) + { + Game::Com_Printf("Script %s encountered an error while loading. (doesn't exist?)", file.data()); + return; + } + + Game::Com_Printf("Script %s.gsc loaded successfully.\n", file.data()); + Game::Com_Printf("Finding script handle %s::%s...\n", file.data(), label.data()); + + unsigned int handle = Game::Scr_GetFunctionHandle(file.data(), label.data()); + if (!handle) + { + Game::Com_Printf("Script handle %s::%s couldn't be loaded. (file with no entry point?)\n", file.data(), label.data()); + return; + } + + CustomScrHandles.push_back(handle); + Game::Com_Printf("Script handle %s::%s loaded successfully.\n", file.data(), label.data()); + }); + + Game::GScr_LoadGameTypeScript(); + } + + void Script::G_LoadStructs_Hook() + { + for (auto handle : CustomScrHandles) + { + Game::RemoveRefToObject(Game::Scr_ExecThread(handle, 0)); + } + + Game::G_LoadStructs(); + } + Script::Script() { // custom gsc calls diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index ec92e34..06a6319 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -92,7 +92,7 @@ namespace Game bgs_ptr = ASSIGN(bgs_s**, 0x19A1C78); } - unsigned int Scr_GetFunctionHandle(char* filename, const char* funcHandle) + unsigned int Scr_GetFunctionHandle(const char* filename, const char* funcHandle) { int func_loc = 0x474950; unsigned int answer; @@ -109,15 +109,17 @@ namespace Game return answer; } - __int16 Scr_ExecThread(int handle) + __int16 Scr_ExecThread(int handle, int numParam) { int func_loc = 0x482080; __int16 answer; __asm { + push numParam; mov eax, handle; call func_loc; + add esp, 4; mov answer, ax; } @@ -135,6 +137,42 @@ namespace Game } } + int FS_ForEachFile(const char* folder, const char* extention, void(callback)(char*)) + { + char buff[0x4000]; + int numberFiles = FS_GetFileList(folder, extention, 1, buff, 0x4000); + int cursor = 0; + + for (int i = 0; i < numberFiles; i++) + { + callback(buff + cursor); + + cursor += strlen(buff + cursor) + 1; + } + + return numberFiles; + } + + int FS_GetFileList(const char* folder, const char* ext, int flags, char* buff, size_t _size) + { + int func_loc = 0x424230; + int answer; + + __asm + { + push _size; + push buff; + push flags; + push ext; + mov eax, folder; + call func_loc; + add esp, 0x10; + mov answer, eax; + } + + return answer; + } + const char* Scr_GetString(unsigned int slot) { int func_loc = 0x482FF0; diff --git a/src/Game/Game.hpp b/src/Game/Game.hpp index b4f00ad..f344365 100644 --- a/src/Game/Game.hpp +++ b/src/Game/Game.hpp @@ -58,7 +58,7 @@ namespace Game extern Dvar_RegisterBool_t* Dvar_RegisterBool; extern unsigned int Scr_GetFunctionHandle(const char*, const char*); - extern __int16 Scr_ExecThread(int); + extern __int16 Scr_ExecThread(int, int); extern void RemoveRefToObject(int); typedef Game::xmethod_t (Player_GetMethod_t)(const char**); @@ -81,6 +81,9 @@ namespace Game //double __usercall sub_482DB0@(unsigned int a1@) getfloat //char __usercall sub_483160@(unsigned int a1@, _DWORD *a2@) get vector + extern int FS_GetFileList(const char*, const char*, int, char*, size_t); + extern int FS_ForEachFile(const char*, const char*, void(char*)); + extern const char* Scr_GetString(unsigned int); extern int Scr_GetInt(unsigned int); extern void G_SelectWeaponIndex(int, int);