From 25bd407b39b38132554b1f3fc4ea0f8c97e554fe Mon Sep 17 00:00:00 2001 From: rexx <67599507+r-ex@users.noreply.github.com> Date: Sat, 12 Aug 2023 22:41:48 +0100 Subject: [PATCH] add ScriptError script func --- r5dev/game/shared/vscript_shared.cpp | 21 +++++++ .../languages/squirrel_re/include/sqstate.h | 3 +- .../languages/squirrel_re/include/sqvm.h | 21 ++++--- .../languages/squirrel_re/squirrel/sqvm.cpp | 58 +++++++++---------- 4 files changed, 65 insertions(+), 38 deletions(-) diff --git a/r5dev/game/shared/vscript_shared.cpp b/r5dev/game/shared/vscript_shared.cpp index 493169cb..8dc435c2 100644 --- a/r5dev/game/shared/vscript_shared.cpp +++ b/r5dev/game/shared/vscript_shared.cpp @@ -70,6 +70,25 @@ namespace VScriptCode return SQ_OK; } + + SQRESULT ScriptError(HSQUIRRELVM v) + { + SQChar* pString = NULL; + SQInteger a4 = 0; + + if (SQVM_sprintf(v, 0, 1, &a4, &pString) < 0) + return SQ_ERROR; + + v_SQVM_ScriptError("%s", pString); + + // this should be moved to a wrapper for all script funcs + if (*reinterpret_cast(&v->_sharedstate->gap43b9[127])) + { + v_SQVM_ThrowError(*reinterpret_cast(&v->_sharedstate->gap43b9[111]), v); + } + + return SQ_ERROR; + } } } @@ -83,6 +102,8 @@ void Script_RegisterCommonAbstractions(CSquirrelVM* s) DEFINE_SHARED_SCRIPTFUNC_NAMED(s, GetAvailableMaps, "Gets an array of all available maps", "array< string >", ""); DEFINE_SHARED_SCRIPTFUNC_NAMED(s, GetAvailablePlaylists, "Gets an array of all available playlists", "array< string >", ""); + + DEFINE_SHARED_SCRIPTFUNC_NAMED(s, ScriptError, "", "void", "string format, ...") } //--------------------------------------------------------------------------------- diff --git a/r5dev/vscript/languages/squirrel_re/include/sqstate.h b/r5dev/vscript/languages/squirrel_re/include/sqstate.h index fcebb0a3..bbe0c0fe 100644 --- a/r5dev/vscript/languages/squirrel_re/include/sqstate.h +++ b/r5dev/vscript/languages/squirrel_re/include/sqstate.h @@ -11,7 +11,8 @@ struct SQSharedState #endif void* _printfunc; uint8_t gap4390[33]; - SQChar _contextname[7]; + SQChar _contextname[8]; + char gap43b9[135]; }; #pragma pack(pop) diff --git a/r5dev/vscript/languages/squirrel_re/include/sqvm.h b/r5dev/vscript/languages/squirrel_re/include/sqvm.h index 9f35aa6d..ffd6de85 100644 --- a/r5dev/vscript/languages/squirrel_re/include/sqvm.h +++ b/r5dev/vscript/languages/squirrel_re/include/sqvm.h @@ -51,7 +51,8 @@ struct SQVM void* _table; _BYTE gap003[14]; void* _callstack; - __int64 _unk; + int _unk; + int _bottom; SQInteger _stackbase; SQInteger unk5c; SQSharedState* _sharedstate; @@ -68,8 +69,8 @@ struct SQVM inline CMemory p_SQVM_PrintFunc; inline SQRESULT(*v_SQVM_PrintFunc)(HSQUIRRELVM v, SQChar* fmt, ...); -inline CMemory p_SQVM_WarningFunc; -inline SQRESULT(*v_SQVM_WarningFunc)(HSQUIRRELVM v, SQInteger a2, SQInteger a3, SQInteger* nStringSize, SQChar** ppString); +inline CMemory p_SQVM_sprintf; +inline SQRESULT(*v_SQVM_sprintf)(HSQUIRRELVM v, SQInteger a2, SQInteger a3, SQInteger* nStringSize, SQChar** ppString); inline CMemory p_SQVM_GetErrorLine; inline size_t(*v_SQVM_GetErrorLine)(const SQChar* pszFile, SQInteger nLine, SQChar* pszContextBuf, SQInteger nBufLen); @@ -89,8 +90,11 @@ inline SQInteger(*v_SQVM_ScriptError)(const SQChar* pszFormat, ...); inline CMemory p_SQVM_RaiseError; inline SQInteger(*v_SQVM_RaiseError)(HSQUIRRELVM v, const SQChar* pszFormat, ...); +inline CMemory p_SQVM_ThrowError; +inline SQBool(*v_SQVM_ThrowError)(__int64 a1, HSQUIRRELVM v); + SQRESULT SQVM_PrintFunc(HSQUIRRELVM v, SQChar* fmt, ...); -SQRESULT SQVM_WarningFunc(HSQUIRRELVM v, SQInteger a2, SQInteger a3, SQInteger* nStringSize, SQChar** ppString); +SQRESULT SQVM_sprintf(HSQUIRRELVM v, SQInteger a2, SQInteger a3, SQInteger* nStringSize, SQChar** ppString); void SQVM_CompileError(HSQUIRRELVM v, const SQChar* pszError, const SQChar* pszFile, SQUnsignedInteger nLine, SQInteger nColumn); const SQChar* SQVM_GetContextName(SQCONTEXT context); @@ -102,18 +106,19 @@ class VSquirrelVM : public IDetour virtual void GetAdr(void) const { LogFunAdr("SQVM_PrintFunc", p_SQVM_PrintFunc.GetPtr()); - LogFunAdr("SQVM_WarningFunc", p_SQVM_WarningFunc.GetPtr()); + LogFunAdr("SQVM_sprintf", p_SQVM_sprintf.GetPtr()); LogFunAdr("SQVM_GetErrorLine", p_SQVM_GetErrorLine.GetPtr()); LogFunAdr("SQVM_WarningCmd", p_SQVM_WarningCmd.GetPtr()); LogFunAdr("SQVM_CompileError", p_SQVM_CompileError.GetPtr()); LogFunAdr("SQVM_LogicError", p_SQVM_LogicError.GetPtr()); LogFunAdr("SQVM_ScriptError", p_SQVM_ScriptError.GetPtr()); LogFunAdr("SQVM_RaiseError", p_SQVM_RaiseError.GetPtr()); + LogFunAdr("SQVM_ThrowError", p_SQVM_ThrowError.GetPtr()); } virtual void GetFun(void) const { p_SQVM_PrintFunc = g_GameDll.FindPatternSIMD("48 8B C4 48 89 50 10 4C 89 40 18 4C 89 48 20 53 56 57 48 81 EC 30 08 ?? ?? 48 8B DA 48 8D 70 18 48 8B F9 E8 ?? ?? ?? FF 48 89 74 24 28 48 8D 54 24 30 33"); - p_SQVM_WarningFunc = g_GameDll.FindPatternSIMD("4C 89 4C 24 20 44 89 44 24 18 89 54 24 10 53 55 56 57 41 54 41 55 41 56 41 57 48 83 EC ?? 48 8B"); + p_SQVM_sprintf = g_GameDll.FindPatternSIMD("4C 89 4C 24 20 44 89 44 24 18 89 54 24 10 53 55 56 57 41 54 41 55 41 56 41 57 48 83 EC ?? 48 8B"); #if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) p_SQVM_GetErrorLine = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 55 41 54 41 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 83 65 90 FC"); p_SQVM_LogicError = g_GameDll.FindPatternSIMD("48 83 EC 48 F2 0F 10 05 ?? ?? ?? ??"); @@ -125,15 +130,17 @@ class VSquirrelVM : public IDetour p_SQVM_CompileError = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 81 EC ?? ?? ?? ?? 48 8B D9 4C 8B F2"); p_SQVM_ScriptError = g_GameDll.FindPatternSIMD("E9 ?? ?? ?? ?? F7 D2").FollowNearCallSelf(); p_SQVM_RaiseError = g_GameDll.FindPatternSIMD("48 89 54 24 ?? 4C 89 44 24 ?? 4C 89 4C 24 ?? 53 56 57 48 83 EC 40"); + p_SQVM_ThrowError = g_GameDll.FindPatternSIMD("E8 ? ? ? ? BB ? ? ? ? 8B C3").FollowNearCallSelf(); v_SQVM_PrintFunc = p_SQVM_PrintFunc.RCast(); /*48 8B C4 48 89 50 10 4C 89 40 18 4C 89 48 20 53 56 57 48 81 EC 30 08 00 00 48 8B DA 48 8D 70 18 48 8B F9 E8 ?? ?? ?? FF 48 89 74 24 28 48 8D 54 24 30 33*/ - v_SQVM_WarningFunc = p_SQVM_WarningFunc.RCast(); /*4C 89 4C 24 20 44 89 44 24 18 89 54 24 10 53 55 56 57 41 54 41 55 41 56 41 57 48 83 EC ?? 48 8B*/ + v_SQVM_sprintf = p_SQVM_sprintf.RCast(); /*4C 89 4C 24 20 44 89 44 24 18 89 54 24 10 53 55 56 57 41 54 41 55 41 56 41 57 48 83 EC ?? 48 8B*/ v_SQVM_GetErrorLine = p_SQVM_GetErrorLine.RCast(); /*48 8B C4 55 56 48 8D A8 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 83 65 90 FC*/ v_SQVM_WarningCmd = p_SQVM_WarningCmd.RCast(); /*40 53 48 83 EC 30 33 DB 48 8D 44 24 ?? 4C 8D 4C 24 ??*/ v_SQVM_CompileError = p_SQVM_CompileError.RCast(); /*48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 81 EC ?? ?? ?? ?? 48 8B D9 4C 8B F2*/ v_SQVM_LogicError = p_SQVM_LogicError.RCast(); /*48 83 EC 38 F2 0F 10 05 ?? ?? ?? ??*/ v_SQVM_ScriptError = p_SQVM_ScriptError.RCast(); /*E9 ?? ?? ?? ?? F7 D2*/ v_SQVM_RaiseError = p_SQVM_RaiseError.RCast(); /*E8 ?? ?? ?? ?? 32 C0 EB 3C*/ + v_SQVM_ThrowError = p_SQVM_ThrowError.RCast(); /*E8 ? ? ? ? BB ? ? ? ? 8B C3*/ } virtual void GetVar(void) const { } virtual void GetCon(void) const { } diff --git a/r5dev/vscript/languages/squirrel_re/squirrel/sqvm.cpp b/r5dev/vscript/languages/squirrel_re/squirrel/sqvm.cpp index 49377fc3..6bc30e2f 100644 --- a/r5dev/vscript/languages/squirrel_re/squirrel/sqvm.cpp +++ b/r5dev/vscript/languages/squirrel_re/squirrel/sqvm.cpp @@ -90,46 +90,44 @@ SQRESULT SQVM_PrintFunc(HSQUIRRELVM v, SQChar* fmt, ...) } //--------------------------------------------------------------------------------- -// Purpose: prints the warning output of each VM to the console +// Purpose: sprintf from SQVM stack // Input : *sqvm - // a2 - // a3 - // *nStringSize - // **ppString - //--------------------------------------------------------------------------------- -SQRESULT SQVM_WarningFunc(HSQUIRRELVM v, SQInteger a2, SQInteger a3, SQInteger* nStringSize, SQChar** ppString) +SQRESULT SQVM_sprintf(HSQUIRRELVM v, SQInteger a2, SQInteger a3, SQInteger* nStringSize, SQChar** ppString) { static void* retaddr = reinterpret_cast(p_SQVM_WarningCmd.Offset(0x10).FindPatternSelf("85 ?? ?? 99", CMemory::Direction::DOWN).GetPtr()); - SQRESULT result = v_SQVM_WarningFunc(v, a2, a3, nStringSize, ppString); + SQRESULT result = v_SQVM_sprintf(v, a2, a3, nStringSize, ppString); - if (retaddr != _ReturnAddress()) // Check if its SQVM_Warning calling. + if (retaddr == _ReturnAddress()) // Check if its SQVM_Warning calling. { - return result; + SQCONTEXT scriptContext = v->GetContext(); + eDLL_T remoteContext; + + switch (scriptContext) + { + case SQCONTEXT::SERVER: + remoteContext = eDLL_T::SCRIPT_SERVER; + break; + case SQCONTEXT::CLIENT: + remoteContext = eDLL_T::SCRIPT_CLIENT; + break; + case SQCONTEXT::UI: + remoteContext = eDLL_T::SCRIPT_UI; + break; + default: + remoteContext = eDLL_T::NONE; + break; + } + + std::string svConstructor(*ppString, *nStringSize); // Get string from memory via std::string constructor. + CoreMsg(LogType_t::SQ_WARNING, static_cast(script_show_warning->GetInt()), + remoteContext, NO_ERROR, "squirrel_re(warning)", "%s", svConstructor.c_str()); } - SQCONTEXT scriptContext = v->GetContext(); - eDLL_T remoteContext; - - switch (scriptContext) - { - case SQCONTEXT::SERVER: - remoteContext = eDLL_T::SCRIPT_SERVER; - break; - case SQCONTEXT::CLIENT: - remoteContext = eDLL_T::SCRIPT_CLIENT; - break; - case SQCONTEXT::UI: - remoteContext = eDLL_T::SCRIPT_UI; - break; - default: - remoteContext = eDLL_T::NONE; - break; - } - - std::string svConstructor(*ppString, *nStringSize); // Get string from memory via std::string constructor. - CoreMsg(LogType_t::SQ_WARNING, static_cast(script_show_warning->GetInt()), - remoteContext, NO_ERROR, "squirrel_re(warning)", "%s", svConstructor.c_str()); - return result; } @@ -213,7 +211,7 @@ const SQCONTEXT SQVM_GetContextIndex(HSQUIRRELVM v) void VSquirrelVM::Attach() const { DetourAttach((LPVOID*)&v_SQVM_PrintFunc, &SQVM_PrintFunc); - DetourAttach((LPVOID*)&v_SQVM_WarningFunc, &SQVM_WarningFunc); + DetourAttach((LPVOID*)&v_SQVM_sprintf, &SQVM_sprintf); DetourAttach((LPVOID*)&v_SQVM_CompileError, &SQVM_CompileError); DetourAttach((LPVOID*)&v_SQVM_LogicError, &SQVM_LogicError); } @@ -221,7 +219,7 @@ void VSquirrelVM::Attach() const void VSquirrelVM::Detach() const { DetourDetach((LPVOID*)&v_SQVM_PrintFunc, &SQVM_PrintFunc); - DetourDetach((LPVOID*)&v_SQVM_WarningFunc, &SQVM_WarningFunc); + DetourDetach((LPVOID*)&v_SQVM_sprintf, &SQVM_sprintf); DetourDetach((LPVOID*)&v_SQVM_CompileError, &SQVM_CompileError); DetourDetach((LPVOID*)&v_SQVM_LogicError, &SQVM_LogicError); }