[Script] Add replaceFun
This commit is contained in:
parent
3cbe6e820c
commit
8cd3f2cad4
@ -9,6 +9,8 @@ namespace Components
|
||||
unsigned short Script::FunctionName;
|
||||
std::unordered_map<std::string, std::string> Script::ScriptStorage;
|
||||
std::unordered_map<int, std::string> Script::ScriptBaseProgramNum;
|
||||
std::unordered_map<const char*, const char*> Script::ReplacedFunctions;
|
||||
const char* Script::ReplacedPos = 0;
|
||||
int Script::LastFrameTime = -1;
|
||||
|
||||
Utils::Signal<Scheduler::Callback> Script::VMShutdownSignal;
|
||||
@ -397,6 +399,75 @@ namespace Components
|
||||
return Game::Scr_GetNumParam();
|
||||
}
|
||||
|
||||
const char* Script::GetCodePosForParam(int index)
|
||||
{
|
||||
return Game::scriptContainer->stack[index].u.codePosValue;
|
||||
}
|
||||
|
||||
void Script::GetReplacedPos(const char* pos)
|
||||
{
|
||||
if (Script::ReplacedFunctions.find(pos) != Script::ReplacedFunctions.end())
|
||||
{
|
||||
Script::ReplacedPos = Script::ReplacedFunctions[pos];;
|
||||
}
|
||||
}
|
||||
|
||||
void Script::SetReplacedPos(const char* what, const char* with)
|
||||
{
|
||||
// Warn if the function was already detoured
|
||||
if (Script::ReplacedFunctions.find(what) != Script::ReplacedFunctions.end())
|
||||
{
|
||||
Logger::Print("Warning: a function was already detoured by a script\n");
|
||||
}
|
||||
|
||||
Script::ReplacedFunctions[what] = with;
|
||||
}
|
||||
|
||||
__declspec(naked) void Script::VMExecuteInternalStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
pushad
|
||||
|
||||
push edx
|
||||
call Script::GetReplacedPos
|
||||
|
||||
pop edx
|
||||
popad
|
||||
|
||||
cmp Script::ReplacedPos, 0
|
||||
jne SetPos
|
||||
|
||||
movzx eax, byte ptr [edx]
|
||||
inc edx
|
||||
|
||||
Loc1:
|
||||
cmp eax, 0x8B
|
||||
|
||||
push ecx
|
||||
|
||||
mov ecx, 0x2045094
|
||||
mov [ecx], eax
|
||||
|
||||
mov ecx, 0x2040CD4
|
||||
mov [ecx], edx
|
||||
|
||||
pop ecx
|
||||
|
||||
push 0x061E944
|
||||
retn
|
||||
|
||||
SetPos:
|
||||
mov edx, Script::ReplacedPos
|
||||
mov Script::ReplacedPos, 0
|
||||
|
||||
movzx eax, byte ptr [edx]
|
||||
inc edx
|
||||
|
||||
jmp Loc1
|
||||
}
|
||||
}
|
||||
|
||||
Game::gentity_t* Script::getEntFromEntRef(Game::scr_entref_t entref)
|
||||
{
|
||||
Game::gentity_t* gentity = &Game::g_entities[entref];
|
||||
@ -414,6 +485,26 @@ namespace Components
|
||||
|
||||
void Script::AddFunctions()
|
||||
{
|
||||
Script::AddFunction("ReplaceFunc", [](Game::scr_entref_t) // gsc: ReplaceFunc(<function>,<function>)
|
||||
{
|
||||
if (Game::Scr_GetNumParam() != 2)
|
||||
{
|
||||
Game::Scr_Error("^1ReplaceFunc: Needs two parameters!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Game::Scr_GetType(0) != Game::VAR_FUNCTION || Game::Scr_GetType(1) != Game::VAR_FUNCTION)
|
||||
{
|
||||
Game::Scr_Error("^1ReplaceFunc: Needs function pointers as parameters!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto what = Script::GetCodePosForParam(0);
|
||||
const auto with = Script::GetCodePosForParam(-1);
|
||||
|
||||
Script::SetReplacedPos(what, with);
|
||||
});
|
||||
|
||||
// System time
|
||||
Script::AddFunction("GetSystemTime", [](Game::scr_entref_t) // gsc: GetSystemTime()
|
||||
{
|
||||
@ -562,6 +653,9 @@ namespace Components
|
||||
|
||||
Utils::Hook(0x5F41A3, Script::SetExpFogStub, HOOK_CALL).install()->quick();
|
||||
|
||||
Utils::Hook(0x61E92E, Script::VMExecuteInternalStub, HOOK_JUMP).install()->quick();
|
||||
Utils::Hook::Nop(0x61E933, 1);
|
||||
|
||||
Utils::Hook(0x47548B, Script::ScrShutdownSystemStub, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x4D06BA, Script::ScrShutdownSystemStub, HOOK_CALL).install()->quick();
|
||||
|
||||
@ -623,6 +717,7 @@ namespace Components
|
||||
Script::ScriptHandles.clear();
|
||||
Script::ScriptNameStack.clear();
|
||||
Script::ScriptFunctions.clear();
|
||||
Script::ReplacedFunctions.clear();
|
||||
Script::VMShutdownSignal.clear();
|
||||
|
||||
Script::ScriptStorage.clear();
|
||||
|
@ -40,6 +40,8 @@ namespace Components
|
||||
static unsigned short FunctionName;
|
||||
static std::unordered_map<std::string, std::string> ScriptStorage;
|
||||
static std::unordered_map<int, std::string> ScriptBaseProgramNum;
|
||||
static std::unordered_map<const char*, const char*> ReplacedFunctions;
|
||||
static const char* ReplacedPos;
|
||||
static int LastFrameTime;
|
||||
|
||||
static Utils::Signal<Scheduler::Callback> VMShutdownSignal;
|
||||
@ -70,6 +72,11 @@ namespace Components
|
||||
|
||||
static int SetExpFogStub();
|
||||
|
||||
static const char* GetCodePosForParam(int index);
|
||||
static void GetReplacedPos(const char* pos);
|
||||
static void SetReplacedPos(const char* what, const char* with);
|
||||
static void VMExecuteInternalStub();
|
||||
|
||||
static void AddFunctions();
|
||||
};
|
||||
}
|
||||
|
@ -660,7 +660,7 @@ namespace Game
|
||||
typedef unsigned int(__cdecl * Scr_GetObject_t)(int);
|
||||
extern Scr_GetObject_t Scr_GetObject;
|
||||
|
||||
typedef int(__cdecl * Scr_GetNumParam_t)();
|
||||
typedef unsigned int(__cdecl * Scr_GetNumParam_t)();
|
||||
extern Scr_GetNumParam_t Scr_GetNumParam;
|
||||
|
||||
typedef int(__cdecl * Scr_GetFunctionHandle_t)(const char*, const char*);
|
||||
@ -687,7 +687,7 @@ namespace Game
|
||||
typedef bool(__cdecl * Scr_IsSystemActive_t)();
|
||||
extern Scr_IsSystemActive_t Scr_IsSystemActive;
|
||||
|
||||
typedef int(__cdecl* Scr_GetType_t)(int);
|
||||
typedef int(__cdecl* Scr_GetType_t)(unsigned int);
|
||||
extern Scr_GetType_t Scr_GetType;
|
||||
|
||||
typedef void(__cdecl* Scr_Error_t)(const char*);
|
||||
|
@ -4886,7 +4886,7 @@ namespace Game
|
||||
struct VariableValue
|
||||
{
|
||||
VariableUnion u;
|
||||
int type;
|
||||
VariableType type;
|
||||
};
|
||||
|
||||
struct ScriptContainer
|
||||
|
Loading…
Reference in New Issue
Block a user