mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
custom native ui & client script functions (#52)
* custom native ui & client script functions * spacing is hard * sq_pushbool, sq_pushstring, sq_getstring, sq_getinteger * sq_pushinteger, sq_newarray, sq_arrayappend, sq_newtable, sq_newslot * Re-factored code. Co-authored-by: IcePixelx <41352111+PixieCore@users.noreply.github.com>
This commit is contained in:
parent
b42e85b1f4
commit
25c5a5c9af
@ -456,6 +456,33 @@ struct Interface
|
||||
__int64* NextInterfacePtr;
|
||||
};
|
||||
|
||||
struct SQFuncRegistration
|
||||
{
|
||||
const char* scriptName; // 00
|
||||
const char* nativeName; // 08
|
||||
const char* helpString; // 10
|
||||
const char* retValType; // 18
|
||||
const char* argTypes; // 20
|
||||
int16_t unk28; // 28
|
||||
int16_t padding1; // 2A
|
||||
int32_t unk2c; // 2C
|
||||
int64_t unk30; // 30
|
||||
int32_t unk38; // 38
|
||||
int32_t padding2; // 3C
|
||||
int64_t unk40; // 40
|
||||
int64_t unk48; // 48
|
||||
int64_t unk50; // 50
|
||||
int32_t unk58; // 58
|
||||
int32_t padding3; // 5C
|
||||
void* funcPtr; // 60
|
||||
|
||||
SQFuncRegistration()
|
||||
{
|
||||
memset(this, 0, sizeof(SQFuncRegistration));
|
||||
this->padding2 = 6;
|
||||
}
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Initialize Game Globals
|
||||
|
||||
@ -474,11 +501,17 @@ namespace GameGlobals
|
||||
ConVar* CreateCustomConVar(const char* name, const char* defaultValue, int flags, const char* helpString, bool bMin, float fMin, bool bMax, float fMax, void* callback, void* unk);
|
||||
void* CreateCustomConCommand(const char* name, const char* helpString, int flags, void* callback, void* callbackAfterExecution);
|
||||
|
||||
// Script
|
||||
void Script_RegisterFunction(void* sqvm, const char* name, const char* helpString, const char* retValType, const char* argTypes, void* funcPtr);
|
||||
void RegisterUIScriptFunctions(void* sqvm);
|
||||
void RegisterClientScriptFunctions(void* sqvm);
|
||||
|
||||
// Init
|
||||
void InitGameGlobals();
|
||||
void InitAllCommandVariations();
|
||||
void InitPlaylist();
|
||||
|
||||
|
||||
extern std::vector<std::string> allPlaylists;
|
||||
extern bool IsInitialized;
|
||||
|
||||
|
@ -25,6 +25,7 @@ namespace Hooks
|
||||
__int64 SQVM_Warning(void* sqvm, int a2, int a3, int* stringSize, void** string);
|
||||
__int64 SQVM_LoadRson(const char* rson_name);
|
||||
bool SQVM_LoadScript(void* sqvm, const char* script_path, const char* script_name, int flag);
|
||||
void SQVM_RegisterOriginFuncs(void* sqvm);
|
||||
|
||||
using SQVM_WarningFn = __int64(*)(void*, int, int, int*, void**);
|
||||
extern SQVM_WarningFn originalSQVM_Warning;
|
||||
@ -34,6 +35,9 @@ namespace Hooks
|
||||
|
||||
using SQVM_LoadScriptFn = bool(*)(void*, const char*, const char*, int);
|
||||
extern SQVM_LoadScriptFn originalSQVM_LoadScript;
|
||||
|
||||
using SQVM_RegisterOriginFuncsFn = void(*)(void*);
|
||||
extern SQVM_RegisterOriginFuncsFn originalSQVM_RegisterOriginFuncs;
|
||||
#pragma endregion
|
||||
|
||||
#pragma region CServer
|
||||
|
@ -29,6 +29,27 @@ namespace
|
||||
/*0x140B1E55*/
|
||||
FUNC_AT_ADDRESS(addr_SQVM_Warning_ReturnAddr, void*, r5_patterns.PatternSearch("E8 ? ? ? ? 85 C0 0F 99 C3").OffsetSelf(0x5).GetPtr());
|
||||
|
||||
/*0x141061A50*/
|
||||
FUNC_AT_ADDRESS(addr_sq_pushstring, void(*)(void*, char*, __int64), r5_patterns.PatternSearch("E8 ? ? ? ? 8D 55 FE").FollowNearCall().GetPtr());
|
||||
|
||||
/*0x141061CD0*/
|
||||
FUNC_AT_ADDRESS(addr_sq_pushbool, void(*)(void*, int), r5_patterns.PatternSearch("E8 ? ? ? ? 41 0F B6 17").FollowNearCall().GetPtr());
|
||||
|
||||
/*0x141061C70*/
|
||||
FUNC_AT_ADDRESS(addr_sq_pushinteger, void(*)(void*, int), r5_patterns.PatternSearch("E8 ? ? ? ? 41 0F B7 17").FollowNearCall().GetPtr());
|
||||
|
||||
/*0x141062040*/
|
||||
FUNC_AT_ADDRESS(addr_sq_newarray, void(*)(void*, int), r5_patterns.PatternSearch("E8 ? ? ? ? 49 63 F5").FollowNearCall().GetPtr());
|
||||
|
||||
/*0x1410621F0*/
|
||||
FUNC_AT_ADDRESS(addr_sq_arrayappend, __int64(*)(void*, int), r5_patterns.PatternSearch("E8 ? ? ? ? 49 63 46 38").FollowNearCall().GetPtr());
|
||||
|
||||
/*0x141061FB0*/
|
||||
FUNC_AT_ADDRESS(addr_sq_newtable, void(*)(void*), r5_patterns.PatternSearch("E8 ? ? ? ? 83 C6 04").FollowNearCall().GetPtr());
|
||||
|
||||
/*0x141064250*/
|
||||
FUNC_AT_ADDRESS(addr_sq_newslot, __int64(*)(void*, int), r5_patterns.PatternSearch("E8 ? ? ? ? 49 63 46 18").FollowNearCall().GetPtr());
|
||||
|
||||
//DWORD64 p_SQVM_LoadScript = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x89\x5C\x24\x10\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x48\x89\x4C\x24\x08\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\x6C", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); // For S0 and S1
|
||||
|
||||
/*0x141055630*/
|
||||
@ -37,6 +58,9 @@ namespace
|
||||
|
||||
/*0x140C957E0*/
|
||||
FUNC_AT_ADDRESS(addr_SQVM_LoadRson, int(*)(const char*), r5_patterns.PatternSearch("4C 8B DC 49 89 5B 08 57 48 81 EC A0 00 00 00 33").GetPtr());
|
||||
|
||||
/*0x140834A00*/
|
||||
FUNC_AT_ADDRESS(addr_SQVM_RegisterOriginFuncs, void(*)(void*), r5_patterns.PatternSearch("E8 ? ? ? ? 48 8B 0D ? ? ? ? 48 8D 15 ? ? ? ? E8 ? ? ? ? 48 8B 05 ? ? ? ? C7 05 ? ? ? ? ? ? ? ?").FollowNearCall().GetPtr());
|
||||
#pragma endregion
|
||||
|
||||
#pragma region NetChannel
|
||||
@ -56,7 +80,6 @@ namespace
|
||||
MemoryAddress addr_NetChan_EncKeyPtr = MemoryAddress(0x160686DC0);
|
||||
char* addr_NetChan_EncKey = addr_NetChan_EncKeyPtr.Offset(4816).RCast<char*>();
|
||||
|
||||
|
||||
/*0x140263E70*/
|
||||
FUNC_AT_ADDRESS(addr_NetChan_SetEncKey, void(*)(uintptr_t, const char*), MemoryAddress(0x140263E70).GetPtr());
|
||||
|
||||
@ -132,18 +155,32 @@ namespace
|
||||
PRINT_ADDRESS("SQVM_LoadRson", addr_SQVM_LoadRson);
|
||||
PRINT_ADDRESS("SQVM_Warning", addr_SQVM_Warning);
|
||||
PRINT_ADDRESS("SQVM_Warning_ReturnAddr", addr_SQVM_Warning_ReturnAddr);
|
||||
PRINT_ADDRESS("SQVM_RegisterOriginFuncs", addr_SQVM_RegisterOriginFuncs);
|
||||
PRINT_ADDRESS("sq_arrayappend", addr_sq_arrayappend);
|
||||
PRINT_ADDRESS("sq_newarray", addr_sq_newarray);
|
||||
PRINT_ADDRESS("sq_newslot", addr_sq_newslot);
|
||||
PRINT_ADDRESS("sq_newtable", addr_sq_newtable);
|
||||
PRINT_ADDRESS("sq_pushbool", addr_sq_pushbool);
|
||||
PRINT_ADDRESS("sq_pushinteger", addr_sq_pushinteger);
|
||||
PRINT_ADDRESS("sq_pushstring", addr_sq_pushstring);
|
||||
PRINT_ADDRESS("NET_PrintFunc", addr_NET_PrintFunc);
|
||||
PRINT_ADDRESS("NET_ReceiveDatagram", addr_NET_ReceiveDatagram);
|
||||
PRINT_ADDRESS("NET_SendDatagram ", addr_NET_SendDatagram);
|
||||
PRINT_ADDRESS("CClientState::m_bRestrictServerCommands", addr_m_bRestrictServerCommands);
|
||||
PRINT_ADDRESS("CClient::Clear", addr_CClient_Clear);
|
||||
PRINT_ADDRESS("INetChannel::Shutdown", addr_NetChan_Shutdown);
|
||||
PRINT_ADDRESS("INetChannel::SetEncryptionKey", addr_NetChan_SetEncKey);
|
||||
PRINT_ADDRESS("INetChannel::EncryptionKey", addr_NetChan_EncKey)
|
||||
PRINT_ADDRESS("CHLClient::FrameStageNotify", addr_CHLClient_FrameStageNotify);
|
||||
PRINT_ADDRESS("CVEngineServer::IsPersistenceDataAvailable", addr_CVEngineServer_IsPersistenceDataAvailable);
|
||||
PRINT_ADDRESS("CServer::ConnectClient", addr_CServer_ConnectClient);
|
||||
PRINT_ADDRESS("CServer::RejectConnection", addr_CServer_RejectConnection);
|
||||
PRINT_ADDRESS("CBaseFileSystem::FileSystemWarning", addr_CBaseFileSystem_FileSystemWarning);
|
||||
PRINT_ADDRESS("MSG_EngineError", addr_MSG_EngineError);
|
||||
PRINT_ADDRESS("LoadPlaylist", addr_LoadPlaylist);
|
||||
PRINT_ADDRESS("MapVPKCache", addr_MapVPKCache);
|
||||
PRINT_ADDRESS("MemAlloc_Wrapper", addr_MemAlloc_Wrapper);
|
||||
PRINT_ADDRESS("KeyValues::FindKey", addr_KeyValues_FindKey);
|
||||
std::cout << "+--------------------------------------------------------+" << std::endl;
|
||||
// TODO implement error handling when sigscan fails or result is 0
|
||||
}
|
||||
|
14
r5dev/include/squirrel.h
Normal file
14
r5dev/include/squirrel.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
char* sq_getstring(void* sqvm, int i);
|
||||
int sq_getinteger(void* sqvm, int i);
|
||||
|
||||
void sq_pushbool(void* sqvm, int val);
|
||||
void sq_pushstring(void* sqvm, char* string, int len);
|
||||
void sq_pushinteger(void* sqvm, int val);
|
||||
|
||||
void sq_newarray(void* sqvm, int size);
|
||||
void sq_arrayappend(void* sqvm, int idx);
|
||||
|
||||
void sq_newtable(void* sqvm);
|
||||
void sq_newslot(void* sqvm, int idx);
|
@ -328,6 +328,7 @@ if not EXIST $(SolutionDir)r5net\lib\$(Configuration)\r5net.lib (
|
||||
<ClInclude Include="include\patterns.h" />
|
||||
<ClInclude Include="include\pch.h" />
|
||||
<ClInclude Include="include\r5dev.h" />
|
||||
<ClInclude Include="include\squirrel.h" />
|
||||
<ClInclude Include="include\structs.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
@ -413,6 +414,10 @@ if not EXIST $(SolutionDir)r5net\lib\$(Configuration)\r5net.lib (
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\squirrel.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="r5dev.def" />
|
||||
|
@ -201,6 +201,9 @@
|
||||
<ClCompile Include="src\hooks\connectclient.cpp">
|
||||
<Filter>hooks\src\cserver</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\squirrel.cpp">
|
||||
<Filter>r5-sdk\src</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\external\imgui\include\imgui_impl_win32.h">
|
||||
@ -573,6 +576,9 @@
|
||||
<ClInclude Include="..\shared\include\banlist.h">
|
||||
<Filter>shared\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\squirrel.h">
|
||||
<Filter>r5-sdk\include</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="r5dev.def">
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "gameclasses.h"
|
||||
#include "id3dx.h"
|
||||
#include "cgameconsole.h"
|
||||
#include "squirrel.h"
|
||||
|
||||
// Need this for a re-factor later.
|
||||
// Interface* interfaces = *reinterpret_cast<Interface**>(0x167F4FA48);
|
||||
@ -460,6 +461,39 @@ namespace GameGlobals
|
||||
return allocatedConvar; // Return allocated ConVar.
|
||||
}
|
||||
|
||||
void Script_RegisterFunction(void* sqvm, const char* name, const char* helpString, const char* retValType, const char* argTypes, void* funcPtr)
|
||||
{
|
||||
static MemoryAddress Script_RegisterFunction = MemoryAddress(0x141056040);
|
||||
|
||||
SQFuncRegistration* func = new SQFuncRegistration();
|
||||
|
||||
func->scriptName = name;
|
||||
func->nativeName = name;
|
||||
func->helpString = helpString;
|
||||
func->retValType = retValType;
|
||||
func->argTypes = argTypes;
|
||||
func->funcPtr = funcPtr;
|
||||
|
||||
Script_RegisterFunction.RCast<void(*)(void*, SQFuncRegistration*, char unk)>()(sqvm, func, 1);
|
||||
}
|
||||
|
||||
int Script_NativeTest(void* sqvm)
|
||||
{
|
||||
// function code goes here
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void RegisterUIScriptFunctions(void* sqvm)
|
||||
{
|
||||
// Script_RegisterFunction(sqvm, "UINativeTest", "native ui function", "void", "", &Script_NativeTest);
|
||||
}
|
||||
|
||||
void RegisterClientScriptFunctions(void* sqvm)
|
||||
{
|
||||
// Script_RegisterFunction(sqvm, "ClientNativeTest", "native client function", "void", "", &Script_NativeTest);
|
||||
}
|
||||
|
||||
void DisconnectClient(CClient* client, const char* reason, unsigned __int8 unk1, char unk2)
|
||||
{
|
||||
if (!client) // Client valid?
|
||||
|
@ -21,6 +21,7 @@ void Hooks::InstallHooks()
|
||||
MH_CreateHook(addr_SQVM_Warning, &Hooks::SQVM_Warning, reinterpret_cast<void**>(&originalSQVM_Warning));
|
||||
MH_CreateHook(addr_SQVM_LoadRson, &Hooks::SQVM_LoadRson, reinterpret_cast<void**>(&originalSQVM_LoadRson));
|
||||
MH_CreateHook(addr_SQVM_LoadScript, &Hooks::SQVM_LoadScript, reinterpret_cast<void**>(&originalSQVM_LoadScript));
|
||||
MH_CreateHook(addr_SQVM_RegisterOriginFuncs, &Hooks::SQVM_RegisterOriginFuncs, reinterpret_cast<void**>(&originalSQVM_RegisterOriginFuncs));
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Hook Game Functions
|
||||
@ -77,6 +78,7 @@ void Hooks::InstallHooks()
|
||||
MH_EnableHook(addr_SQVM_Warning);
|
||||
MH_EnableHook(addr_SQVM_LoadRson);
|
||||
MH_EnableHook(addr_SQVM_LoadScript);
|
||||
MH_EnableHook(addr_SQVM_RegisterOriginFuncs);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Enable Game hooks
|
||||
@ -111,6 +113,7 @@ void Hooks::RemoveHooks()
|
||||
MH_RemoveHook(addr_SQVM_Print);
|
||||
MH_RemoveHook(addr_SQVM_LoadRson);
|
||||
MH_RemoveHook(addr_SQVM_LoadScript);
|
||||
MH_RemoveHook(addr_SQVM_RegisterOriginFuncs);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Unhook Game Functions
|
||||
|
@ -6,6 +6,7 @@ namespace Hooks
|
||||
SQVM_WarningFn originalSQVM_Warning = nullptr;
|
||||
SQVM_LoadRsonFn originalSQVM_LoadRson = nullptr;
|
||||
SQVM_LoadScriptFn originalSQVM_LoadScript = nullptr;
|
||||
SQVM_RegisterOriginFuncsFn originalSQVM_RegisterOriginFuncs = nullptr;
|
||||
}
|
||||
|
||||
static std::ostringstream oss_print;
|
||||
@ -178,4 +179,17 @@ bool Hooks::SQVM_LoadScript(void* sqvm, const char* script_path, const char* scr
|
||||
}
|
||||
|
||||
return originalSQVM_LoadScript(sqvm, script_path, script_name, flag);
|
||||
}
|
||||
|
||||
void Hooks::SQVM_RegisterOriginFuncs(void* sqvm) {
|
||||
static MemoryAddress UIVM = MemoryAddress(0x14D4151F0);
|
||||
|
||||
originalSQVM_RegisterOriginFuncs(sqvm);
|
||||
|
||||
if (sqvm == *(UIVM.RCast<void**>())) {
|
||||
GameGlobals::RegisterUIScriptFunctions(sqvm);
|
||||
}
|
||||
else {
|
||||
GameGlobals::RegisterClientScriptFunctions(sqvm);
|
||||
}
|
||||
}
|
51
r5dev/src/squirrel.cpp
Normal file
51
r5dev/src/squirrel.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
#include "pch.h"
|
||||
#include "patterns.h"
|
||||
|
||||
char* sq_getstring(void* sqvm, int i)
|
||||
{
|
||||
std::uintptr_t thisptr = reinterpret_cast<std::uintptr_t>(sqvm);
|
||||
|
||||
return *(char**)(*(__int64*)(thisptr + 0x58) + 0x10 * i + 0x8) + 0x40;
|
||||
}
|
||||
|
||||
int sq_getinteger(void* sqvm, int i)
|
||||
{
|
||||
std::uintptr_t thisptr = reinterpret_cast<std::uintptr_t>(sqvm);
|
||||
|
||||
return *(int*)(*(__int64*)(thisptr + 0x58) + 0x10 * i + 0x8);
|
||||
}
|
||||
|
||||
void sq_pushbool(void* sqvm, int val)
|
||||
{
|
||||
addr_sq_pushbool(sqvm, val);
|
||||
}
|
||||
|
||||
void sq_pushstring(void* sqvm, char* string, int len)
|
||||
{
|
||||
addr_sq_pushstring(sqvm, string, len);
|
||||
}
|
||||
|
||||
void sq_pushinteger(void* sqvm, int val)
|
||||
{
|
||||
addr_sq_pushinteger(sqvm, val);
|
||||
}
|
||||
|
||||
void sq_newarray(void* sqvm, int size)
|
||||
{
|
||||
addr_sq_newarray(sqvm, size);
|
||||
}
|
||||
|
||||
void sq_arrayappend(void* sqvm, int idx)
|
||||
{
|
||||
addr_sq_arrayappend(sqvm, idx);
|
||||
}
|
||||
|
||||
void sq_newtable(void* sqvm)
|
||||
{
|
||||
addr_sq_newtable(sqvm);
|
||||
}
|
||||
|
||||
void sq_newslot(void* sqvm, int idx)
|
||||
{
|
||||
addr_sq_newslot(sqvm, idx);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user