hook runtimerror for the win
This commit is contained in:
parent
7794a12b95
commit
805be6bb01
@ -45,6 +45,39 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Script::RuntimeError(const char* codePos, unsigned int index, const char* msg, const char* dialogMessage)
|
||||||
|
{
|
||||||
|
const auto developer = Dvar::Var("developer").get<int>();
|
||||||
|
|
||||||
|
// Allow error messages to be printed if developer mode is on
|
||||||
|
// Should check scrVarPub.developer but it's absent in this version of the game
|
||||||
|
if (!Game::scrVmPub->terminal_error && !developer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If were are developing let's just print a brief message
|
||||||
|
// scrVmPub->debugCode seems to be always false
|
||||||
|
if (Game::scrVmPub->debugCode || Game::scrVarPub->developer_script)
|
||||||
|
{
|
||||||
|
Logger::Print(23, "%s\n", msg);
|
||||||
|
|
||||||
|
if (!Game::scrVmPub->terminal_error)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Game::RuntimeErrorInternal(23, codePos, index, msg);
|
||||||
|
// Let's not throw error unless we have to
|
||||||
|
if (!Game::scrVmPub->abort_on_error && !Game::scrVmPub->terminal_error)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dialogMessage == nullptr)
|
||||||
|
dialogMessage = "";
|
||||||
|
|
||||||
|
const auto errorLevel = (Game::scrVmPub->terminal_error) ? Game::ERR_SCRIPT_DROP : Game::ERR_SCRIPT;
|
||||||
|
Logger::Error(errorLevel, "\x15script runtime error\n(see console for details)\n%s\n%s", msg, dialogMessage);
|
||||||
|
}
|
||||||
|
|
||||||
void Script::StoreScriptName(const char* name)
|
void Script::StoreScriptName(const char* name)
|
||||||
{
|
{
|
||||||
Script::ScriptNameStack.push_back(Script::ScriptName);
|
Script::ScriptNameStack.push_back(Script::ScriptName);
|
||||||
@ -629,20 +662,9 @@ namespace Components
|
|||||||
Utils::Hook(0x426C2D, Script::StoreScriptBaseProgramNumStub, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x426C2D, Script::StoreScriptBaseProgramNumStub, HOOK_JUMP).install()->quick();
|
||||||
Utils::Hook(0x42281B, Script::Scr_PrintPrevCodePosStub, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x42281B, Script::Scr_PrintPrevCodePosStub, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
// Enable scr_error printing if in developer
|
Utils::Hook(0x61E3AD, Script::RuntimeError, HOOK_CALL).install()->quick();
|
||||||
Dvar::OnInit([]()
|
Utils::Hook(0x621976, Script::RuntimeError, HOOK_CALL).install()->quick();
|
||||||
{
|
Utils::Hook(0x62246E, Script::RuntimeError, HOOK_CALL).install()->quick();
|
||||||
const auto developer = Dvar::Var("developer").get<int>();
|
|
||||||
const auto developer_script = Dvar::Var("developer_script").get<bool>();
|
|
||||||
|
|
||||||
if (developer > 0)
|
|
||||||
Utils::Hook::Set<BYTE>(0x48D8C7, 0x75);
|
|
||||||
|
|
||||||
// Seems to always be false, if set to true
|
|
||||||
// it will not call Com_Error (Useful for debugging)
|
|
||||||
if (developer_script)
|
|
||||||
Game::scrVmPub->debugCode = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
Utils::Hook(0x612E8D, Script::FunctionError, HOOK_CALL).install()->quick();
|
Utils::Hook(0x612E8D, Script::FunctionError, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x612EA2, Script::FunctionError, HOOK_CALL).install()->quick();
|
Utils::Hook(0x612EA2, Script::FunctionError, HOOK_CALL).install()->quick();
|
||||||
|
@ -51,6 +51,7 @@ namespace Components
|
|||||||
|
|
||||||
static void FunctionError();
|
static void FunctionError();
|
||||||
static void StoreFunctionNameStub();
|
static void StoreFunctionNameStub();
|
||||||
|
static void RuntimeError(const char*, unsigned int, const char*, const char*);
|
||||||
|
|
||||||
static void StoreScriptName(const char* name);
|
static void StoreScriptName(const char* name);
|
||||||
static void StoreScriptNameStub();
|
static void StoreScriptNameStub();
|
||||||
|
@ -468,6 +468,7 @@ namespace Game
|
|||||||
unsigned short* db_hashTable = reinterpret_cast<unsigned short*>(0x12412B0);
|
unsigned short* db_hashTable = reinterpret_cast<unsigned short*>(0x12412B0);
|
||||||
|
|
||||||
scrVmPub_t* scrVmPub = reinterpret_cast<scrVmPub_t*>(0x2040CF0);
|
scrVmPub_t* scrVmPub = reinterpret_cast<scrVmPub_t*>(0x2040CF0);
|
||||||
|
scrVarPub_t* scrVarPub = reinterpret_cast<scrVarPub_t*>(0x201A408);
|
||||||
|
|
||||||
clientstate_t* clcState = reinterpret_cast<clientstate_t*>(0xB2C540);
|
clientstate_t* clcState = reinterpret_cast<clientstate_t*>(0xB2C540);
|
||||||
|
|
||||||
@ -705,6 +706,28 @@ namespace Game
|
|||||||
Game::SV_GameSendServerCommand(clientNum, 0, Utils::String::VA("%c \"%s\"", 0x67, message.data()));
|
Game::SV_GameSendServerCommand(clientNum, 0, Utils::String::VA("%c \"%s\"", 0x67, message.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IncInParam()
|
||||||
|
{
|
||||||
|
Scr_ClearOutParams();
|
||||||
|
|
||||||
|
if (scrVmPub->top == scrVmPub->maxStack)
|
||||||
|
{
|
||||||
|
Sys_Error("Internal script stack overflow");
|
||||||
|
}
|
||||||
|
|
||||||
|
scrVmPub->top++;
|
||||||
|
scrVmPub->inparamcount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scr_AddBool(int value)
|
||||||
|
{
|
||||||
|
assert(value == 0 || value == 1);
|
||||||
|
|
||||||
|
IncInParam();
|
||||||
|
scrVmPub->top->type = VAR_INTEGER;
|
||||||
|
scrVmPub->top->u.intValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
int FS_FOpenFileReadCurrentThread(const char* file, int* fh)
|
int FS_FOpenFileReadCurrentThread(const char* file, int* fh)
|
||||||
{
|
{
|
||||||
if (GetCurrentThreadId() == *reinterpret_cast<DWORD*>(0x1CDE7FC))
|
if (GetCurrentThreadId() == *reinterpret_cast<DWORD*>(0x1CDE7FC))
|
||||||
@ -1019,28 +1042,6 @@ namespace Game
|
|||||||
return GraphGetValueFromFraction(graph->knotCount, graph->knots, fraction) * graph->scale;
|
return GraphGetValueFromFraction(graph->knotCount, graph->knots, fraction) * graph->scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IncInParam()
|
|
||||||
{
|
|
||||||
Scr_ClearOutParams();
|
|
||||||
|
|
||||||
if (scrVmPub->top == scrVmPub->maxStack)
|
|
||||||
{
|
|
||||||
Sys_Error("Internal script stack overflow");
|
|
||||||
}
|
|
||||||
|
|
||||||
scrVmPub->top++;
|
|
||||||
scrVmPub->inparamcount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scr_AddBool(int value)
|
|
||||||
{
|
|
||||||
assert(value == 0 || value == 1);
|
|
||||||
|
|
||||||
IncInParam();
|
|
||||||
scrVmPub->top->type = VAR_INTEGER;
|
|
||||||
scrVmPub->top->u.intValue = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma optimize("", off)
|
#pragma optimize("", off)
|
||||||
__declspec(naked) float UI_GetScoreboardLeft(void* /*a1*/)
|
__declspec(naked) float UI_GetScoreboardLeft(void* /*a1*/)
|
||||||
{
|
{
|
||||||
@ -1211,6 +1212,27 @@ namespace Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__declspec(naked) void RuntimeErrorInternal(int /*channel*/, const char* /*codePos*/, unsigned int /*index*/, const char* /*msg*/)
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
pushad
|
||||||
|
|
||||||
|
mov eax, [esp + 0x10 + 0x20]
|
||||||
|
mov edi, [esp + 0x4 + 0x20]
|
||||||
|
|
||||||
|
push [esp + 0xC + 0x20]
|
||||||
|
push [esp + 0xC + 0x20]
|
||||||
|
|
||||||
|
mov edx, 0x61ABE0
|
||||||
|
call edx
|
||||||
|
add esp, 0x8
|
||||||
|
|
||||||
|
popad
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
__declspec(naked) void IN_KeyUp(kbutton_t* /*button*/)
|
__declspec(naked) void IN_KeyUp(kbutton_t* /*button*/)
|
||||||
{
|
{
|
||||||
__asm
|
__asm
|
||||||
|
@ -991,6 +991,7 @@ namespace Game
|
|||||||
extern unsigned short* db_hashTable;
|
extern unsigned short* db_hashTable;
|
||||||
|
|
||||||
extern scrVmPub_t* scrVmPub;
|
extern scrVmPub_t* scrVmPub;
|
||||||
|
extern scrVarPub_t* scrVarPub;
|
||||||
|
|
||||||
extern clientstate_t* clcState;
|
extern clientstate_t* clcState;
|
||||||
|
|
||||||
@ -1053,6 +1054,7 @@ namespace Game
|
|||||||
void SV_KickClient(client_t* client, const char* reason);
|
void SV_KickClient(client_t* client, const char* reason);
|
||||||
void SV_KickClientError(client_t* client, const std::string& reason);
|
void SV_KickClientError(client_t* client, const std::string& reason);
|
||||||
|
|
||||||
|
void RuntimeErrorInternal(int channel, const char* codePos, unsigned int index, const char* msg);
|
||||||
void IncInParam();
|
void IncInParam();
|
||||||
|
|
||||||
void Scr_iPrintLn(int clientNum, const std::string& message);
|
void Scr_iPrintLn(int clientNum, const std::string& message);
|
||||||
|
@ -4959,6 +4959,15 @@ namespace Game
|
|||||||
VariableValue stack[2048];
|
VariableValue stack[2048];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct scrVarPub_t
|
||||||
|
{
|
||||||
|
const char* fieldBuffer;
|
||||||
|
unsigned __int16 canonicalStrCount;
|
||||||
|
bool developer_script;
|
||||||
|
bool evaluate;
|
||||||
|
const char* error_message;
|
||||||
|
}; // Incomplete
|
||||||
|
|
||||||
enum UILocalVarType
|
enum UILocalVarType
|
||||||
{
|
{
|
||||||
UILOCALVAR_INT = 0x0,
|
UILOCALVAR_INT = 0x0,
|
||||||
|
Loading…
Reference in New Issue
Block a user