[Script] Add replaceFun
This commit is contained in:
parent
3cbe6e820c
commit
8cd3f2cad4
@ -9,6 +9,8 @@ namespace Components
|
|||||||
unsigned short Script::FunctionName;
|
unsigned short Script::FunctionName;
|
||||||
std::unordered_map<std::string, std::string> Script::ScriptStorage;
|
std::unordered_map<std::string, std::string> Script::ScriptStorage;
|
||||||
std::unordered_map<int, std::string> Script::ScriptBaseProgramNum;
|
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;
|
int Script::LastFrameTime = -1;
|
||||||
|
|
||||||
Utils::Signal<Scheduler::Callback> Script::VMShutdownSignal;
|
Utils::Signal<Scheduler::Callback> Script::VMShutdownSignal;
|
||||||
@ -397,6 +399,75 @@ namespace Components
|
|||||||
return Game::Scr_GetNumParam();
|
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* Script::getEntFromEntRef(Game::scr_entref_t entref)
|
||||||
{
|
{
|
||||||
Game::gentity_t* gentity = &Game::g_entities[entref];
|
Game::gentity_t* gentity = &Game::g_entities[entref];
|
||||||
@ -414,6 +485,26 @@ namespace Components
|
|||||||
|
|
||||||
void Script::AddFunctions()
|
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
|
// System time
|
||||||
Script::AddFunction("GetSystemTime", [](Game::scr_entref_t) // gsc: GetSystemTime()
|
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(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(0x47548B, Script::ScrShutdownSystemStub, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x4D06BA, 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::ScriptHandles.clear();
|
||||||
Script::ScriptNameStack.clear();
|
Script::ScriptNameStack.clear();
|
||||||
Script::ScriptFunctions.clear();
|
Script::ScriptFunctions.clear();
|
||||||
|
Script::ReplacedFunctions.clear();
|
||||||
Script::VMShutdownSignal.clear();
|
Script::VMShutdownSignal.clear();
|
||||||
|
|
||||||
Script::ScriptStorage.clear();
|
Script::ScriptStorage.clear();
|
||||||
|
@ -40,6 +40,8 @@ namespace Components
|
|||||||
static unsigned short FunctionName;
|
static unsigned short FunctionName;
|
||||||
static std::unordered_map<std::string, std::string> ScriptStorage;
|
static std::unordered_map<std::string, std::string> ScriptStorage;
|
||||||
static std::unordered_map<int, std::string> ScriptBaseProgramNum;
|
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 int LastFrameTime;
|
||||||
|
|
||||||
static Utils::Signal<Scheduler::Callback> VMShutdownSignal;
|
static Utils::Signal<Scheduler::Callback> VMShutdownSignal;
|
||||||
@ -70,6 +72,11 @@ namespace Components
|
|||||||
|
|
||||||
static int SetExpFogStub();
|
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();
|
static void AddFunctions();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -660,7 +660,7 @@ namespace Game
|
|||||||
typedef unsigned int(__cdecl * Scr_GetObject_t)(int);
|
typedef unsigned int(__cdecl * Scr_GetObject_t)(int);
|
||||||
extern Scr_GetObject_t Scr_GetObject;
|
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;
|
extern Scr_GetNumParam_t Scr_GetNumParam;
|
||||||
|
|
||||||
typedef int(__cdecl * Scr_GetFunctionHandle_t)(const char*, const char*);
|
typedef int(__cdecl * Scr_GetFunctionHandle_t)(const char*, const char*);
|
||||||
@ -687,7 +687,7 @@ namespace Game
|
|||||||
typedef bool(__cdecl * Scr_IsSystemActive_t)();
|
typedef bool(__cdecl * Scr_IsSystemActive_t)();
|
||||||
extern Scr_IsSystemActive_t Scr_IsSystemActive;
|
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;
|
extern Scr_GetType_t Scr_GetType;
|
||||||
|
|
||||||
typedef void(__cdecl* Scr_Error_t)(const char*);
|
typedef void(__cdecl* Scr_Error_t)(const char*);
|
||||||
|
@ -4886,7 +4886,7 @@ namespace Game
|
|||||||
struct VariableValue
|
struct VariableValue
|
||||||
{
|
{
|
||||||
VariableUnion u;
|
VariableUnion u;
|
||||||
int type;
|
VariableType type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ScriptContainer
|
struct ScriptContainer
|
||||||
|
Loading…
Reference in New Issue
Block a user