From 309e2d2987fcd2ceb3e5d2b5356c3b9bb2089860 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sat, 13 May 2017 12:09:58 +0200 Subject: [PATCH] [Script] Allow adding custom script functions --- src/Components/Modules/Script.cpp | 72 +++++++++++++++++++++++++++++-- src/Components/Modules/Script.hpp | 21 +++++++++ src/Game/Functions.cpp | 1 + src/Game/Functions.hpp | 3 ++ src/Game/Structs.hpp | 3 ++ 5 files changed, 97 insertions(+), 3 deletions(-) diff --git a/src/Components/Modules/Script.cpp b/src/Components/Modules/Script.cpp index 6b770516..05a3a60b 100644 --- a/src/Components/Modules/Script.cpp +++ b/src/Components/Modules/Script.cpp @@ -4,6 +4,7 @@ namespace Components { std::string Script::ScriptName; std::vector Script::ScriptHandles; + std::vector Script::ScriptFunctions; std::vector Script::ScriptNameStack; unsigned short Script::FunctionName; @@ -217,16 +218,78 @@ namespace Components } int handle = Script::LoadScriptAndLabel(file, "init"); - - if (handle) + if (handle) Script::ScriptHandles.push_back(handle); + else { - Script::ScriptHandles.push_back(handle); + handle = Script::LoadScriptAndLabel(file, "main"); + if (handle) Script::ScriptHandles.push_back(handle); } } Game::GScr_LoadGameTypeScript(); } + void Script::AddFunction(std::string name, Game::scr_function_t function, bool isDev) + { + for(auto i = Script::ScriptFunctions.begin(); i != Script::ScriptFunctions.end();) + { + if(i->getName() == name) + { + i = Script::ScriptFunctions.erase(i); + continue; + } + + ++i; + } + + Script::ScriptFunctions.push_back({ name, function, isDev }); + } + + Game::scr_function_t Script::GetFunction(const char** name, int* isDev) + { + if (name && *name) OutputDebugStringA(*name); + + for (auto& function : Script::ScriptFunctions) + { + if (name) + { + if(std::string(*name) == function.getName()) + { + *name = function.getName(); + *isDev = function.isDev(); + return function.getFunction(); + } + } + else + { + Game::Scr_RegisterFunction(function.getFunction()); + } + } + + return nullptr; + } + + __declspec(naked) void Script::GetFunctionStub() + { + __asm + { + push [esp + 8h] + push [esp + 8h] + + mov eax, 5FA2B0h + call eax + + test eax, eax + jnz returnSafe + + call Script::GetFunction + + returnSafe: + add esp, 8h + retn + } + } + int Script::SetExpFogStub() { if(Game::Scr_GetNumParam() == 6) @@ -259,6 +322,8 @@ namespace Components Utils::Hook(0x48EFFE, Script::LoadGameType, HOOK_CALL).install()->quick(); Utils::Hook(0x45D44A, Script::LoadGameTypeScript, HOOK_CALL).install()->quick(); + Utils::Hook(0x44E72E, Script::GetFunctionStub, HOOK_CALL).install()->quick(); + Utils::Hook(0x5F41A3, Script::SetExpFogStub, HOOK_CALL).install()->quick(); } @@ -267,5 +332,6 @@ namespace Components Script::ScriptName.clear(); Script::ScriptHandles.clear(); Script::ScriptNameStack.clear(); + Script::ScriptFunctions.clear(); } } diff --git a/src/Components/Modules/Script.hpp b/src/Components/Modules/Script.hpp index d7f55e39..4ecab648 100644 --- a/src/Components/Modules/Script.hpp +++ b/src/Components/Modules/Script.hpp @@ -1,10 +1,26 @@ #pragma once +#include "Game/Structs.hpp" namespace Components { class Script : public Component { public: + class Function + { + public: + Function(std::string _name, Game::scr_function_t _callback, bool _dev) : name(_name), callback(_callback), dev(_dev) {} + + const char* getName() const { return this->name.data(); } + bool isDev() const { return this->dev; } + Game::scr_function_t getFunction() const { return this->callback; } + + private: + std::string name; + Game::scr_function_t callback; + bool dev; + }; + Script(); ~Script(); @@ -13,10 +29,12 @@ namespace Components #endif static int LoadScriptAndLabel(std::string script, std::string label); + static void AddFunction(std::string name, Game::scr_function_t function, bool isDev = false); private: static std::string ScriptName; static std::vector ScriptHandles; + static std::vector ScriptFunctions; static std::vector ScriptNameStack; static unsigned short FunctionName; @@ -35,6 +53,9 @@ namespace Components static void LoadGameType(); static void LoadGameTypeScript(); + static Game::scr_function_t GetFunction(const char** name, int* isDev); + static void GetFunctionStub(); + static int SetExpFogStub(); }; } diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index a4b5f112..0eb16be5 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -216,6 +216,7 @@ namespace Game Scr_AddFloat_t Scr_AddFloat = Scr_AddFloat_t(0x61E860); Scr_Notify_t Scr_Notify = Scr_Notify_t(0x4A4750); + Scr_RegisterFunction_t Scr_RegisterFunction = Scr_RegisterFunction_t(0x492D50); Scr_ShutdownAllocNode_t Scr_ShutdownAllocNode = Scr_ShutdownAllocNode_t(0x441650); Script_Alloc_t Script_Alloc = Script_Alloc_t(0x422E70); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 44e45867..b48ffd5b 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -541,6 +541,9 @@ namespace Game typedef void(__cdecl * Scr_Notify_t)(gentity_t *ent, unsigned __int16 stringValue, unsigned int paramcount); extern Scr_Notify_t Scr_Notify; + typedef void(__cdecl * Scr_RegisterFunction_t)(scr_function_t function); + extern Scr_RegisterFunction_t Scr_RegisterFunction; + typedef script_t* (__cdecl * Script_Alloc_t)(int length); extern Script_Alloc_t Script_Alloc; diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 83620e6d..f40cab63 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -18,6 +18,9 @@ namespace Game typedef vec_t vec3_t[3]; typedef vec_t vec4_t[4]; + typedef int scr_entref_t; + typedef void(__cdecl * scr_function_t)(scr_entref_t); + typedef enum { ASSET_TYPE_PHYSPRESET = 0,