[Script] Added Script Runtime Error printing when in Developer
This commit is contained in:
parent
8d1b06203e
commit
1176a15e71
@ -8,6 +8,7 @@ namespace Components
|
|||||||
std::vector<std::string> Script::ScriptNameStack;
|
std::vector<std::string> Script::ScriptNameStack;
|
||||||
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;
|
||||||
|
|
||||||
Utils::Signal<Scheduler::Callback> Script::VMShutdownSignal;
|
Utils::Signal<Scheduler::Callback> Script::VMShutdownSignal;
|
||||||
|
|
||||||
@ -282,15 +283,95 @@ namespace Components
|
|||||||
call Script::GetFunction
|
call Script::GetFunction
|
||||||
add esp, 0Ch
|
add esp, 0Ch
|
||||||
|
|
||||||
returnSafe:
|
returnSafe:
|
||||||
pop edi
|
pop edi
|
||||||
|
pop esi
|
||||||
|
retn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Script::StoreScriptBaseProgramNum()
|
||||||
|
{
|
||||||
|
Script::ScriptBaseProgramNum.insert_or_assign(Utils::Hook::Get<int>(0x1CFEEF8), Script::ScriptName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Script::Scr_PrintPrevCodePos(int scriptPos)
|
||||||
|
{
|
||||||
|
int bestCodePos = -1;
|
||||||
|
int nextCodePos = -1;
|
||||||
|
int offset = -1;
|
||||||
|
std::string file;
|
||||||
|
|
||||||
|
for (auto kv : Script::ScriptBaseProgramNum)
|
||||||
|
{
|
||||||
|
int codePos = kv.first;
|
||||||
|
|
||||||
|
if (codePos > scriptPos)
|
||||||
|
{
|
||||||
|
if (nextCodePos == -1 || codePos < nextCodePos)
|
||||||
|
nextCodePos = codePos;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (codePos < bestCodePos)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bestCodePos = codePos;
|
||||||
|
|
||||||
|
file = kv.second;
|
||||||
|
offset = scriptPos - bestCodePos;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestCodePos == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
float onehundred = 100.0;
|
||||||
|
|
||||||
|
Logger::Print(23, "\n@ %d (%d - %d)\n", scriptPos, bestCodePos, nextCodePos);
|
||||||
|
Logger::Print(23, "in %s (%.1f%% through the source)\n\n", file.c_str(), ((offset * onehundred) / (nextCodePos - bestCodePos)));
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(naked) void Script::Scr_PrintPrevCodePosStub()
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
push esi
|
||||||
|
call Script::Scr_PrintPrevCodePos
|
||||||
|
add esp, 4h
|
||||||
|
|
||||||
pop esi
|
pop esi
|
||||||
retn
|
retn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__declspec(naked) void Script::StoreScriptBaseProgramNumStub()
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
// execute our hook
|
||||||
|
pushad
|
||||||
|
pusha
|
||||||
|
|
||||||
|
call Script::StoreScriptBaseProgramNum
|
||||||
|
|
||||||
|
popa
|
||||||
|
popad
|
||||||
|
|
||||||
|
// execute overwritten code caused by the jump hook
|
||||||
|
sub eax, ds:201A460h // gScrVarPub_programBuffer
|
||||||
|
add esp, 0Ch
|
||||||
|
mov ds : 1CFEEF8h, eax // gScrCompilePub_programLen
|
||||||
|
|
||||||
|
// jump back to the original code
|
||||||
|
push 426C3Bh
|
||||||
|
retn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Script::OnVMShutdown(Utils::Slot<Scheduler::Callback> callback)
|
void Script::OnVMShutdown(Utils::Slot<Scheduler::Callback> callback)
|
||||||
{
|
{
|
||||||
|
Script::ScriptBaseProgramNum.clear();
|
||||||
Script::VMShutdownSignal.connect(callback);
|
Script::VMShutdownSignal.connect(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,121 +417,121 @@ namespace Components
|
|||||||
{
|
{
|
||||||
// System time
|
// System time
|
||||||
Script::AddFunction("GetSystemTime", [](Game::scr_entref_t) // gsc: GetSystemTime()
|
Script::AddFunction("GetSystemTime", [](Game::scr_entref_t) // gsc: GetSystemTime()
|
||||||
{
|
{
|
||||||
SYSTEMTIME time;
|
SYSTEMTIME time;
|
||||||
GetSystemTime(&time);
|
GetSystemTime(&time);
|
||||||
|
|
||||||
Game::Scr_AddInt(time.wSecond);
|
Game::Scr_AddInt(time.wSecond);
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("GetSystemMilliseconds", [](Game::scr_entref_t) // gsc: GetSystemMilliseconds()
|
Script::AddFunction("GetSystemMilliseconds", [](Game::scr_entref_t) // gsc: GetSystemMilliseconds()
|
||||||
{
|
{
|
||||||
SYSTEMTIME time;
|
SYSTEMTIME time;
|
||||||
GetSystemTime(&time);
|
GetSystemTime(&time);
|
||||||
|
|
||||||
Game::Scr_AddInt(time.wMilliseconds);
|
Game::Scr_AddInt(time.wMilliseconds);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Print to console, even without being in 'developer 1'.
|
// Print to console, even without being in 'developer 1'.
|
||||||
Script::AddFunction("PrintConsole", [](Game::scr_entref_t) // gsc: PrintConsole(<string>)
|
Script::AddFunction("PrintConsole", [](Game::scr_entref_t) // gsc: PrintConsole(<string>)
|
||||||
{
|
|
||||||
if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING)
|
|
||||||
{
|
{
|
||||||
Game::Scr_Error("^1PrintConsole: Needs one string parameter!\n");
|
if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||||
return;
|
{
|
||||||
}
|
Game::Scr_Error("^1PrintConsole: Needs one string parameter!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto str = Game::Scr_GetString(0);
|
auto str = Game::Scr_GetString(0);
|
||||||
|
|
||||||
Game::Com_Printf(0, str);
|
Game::Com_Printf(0, str);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Executes command to the console
|
// Executes command to the console
|
||||||
Script::AddFunction("Exec", [](Game::scr_entref_t) // gsc: Exec(<string>)
|
Script::AddFunction("Exec", [](Game::scr_entref_t) // gsc: Exec(<string>)
|
||||||
{
|
|
||||||
if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING)
|
|
||||||
{
|
{
|
||||||
Game::Scr_Error("^1Exec: Needs one string parameter!\n");
|
if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||||
return;
|
{
|
||||||
}
|
Game::Scr_Error("^1Exec: Needs one string parameter!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto str = Game::Scr_GetString(0);
|
auto str = Game::Scr_GetString(0);
|
||||||
|
|
||||||
Command::Execute(str, false);
|
Command::Execute(str, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// Script Storage Funcs
|
// Script Storage Funcs
|
||||||
Script::AddFunction("StorageSet", [](Game::scr_entref_t) // gsc: StorageSet(<str key>, <str data>);
|
Script::AddFunction("StorageSet", [](Game::scr_entref_t) // gsc: StorageSet(<str key>, <str data>);
|
||||||
{
|
|
||||||
if (Game::Scr_GetNumParam() != 2 || Game::Scr_GetType(0) != Game::VAR_STRING || Game::Scr_GetType(1) != Game::VAR_STRING)
|
|
||||||
{
|
{
|
||||||
Game::Scr_Error("^1StorageSet: Needs two string parameters!\n");
|
if (Game::Scr_GetNumParam() != 2 || Game::Scr_GetType(0) != Game::VAR_STRING || Game::Scr_GetType(1) != Game::VAR_STRING)
|
||||||
return;
|
{
|
||||||
}
|
Game::Scr_Error("^1StorageSet: Needs two string parameters!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::string key = Game::Scr_GetString(0);
|
std::string key = Game::Scr_GetString(0);
|
||||||
std::string data = Game::Scr_GetString(1);
|
std::string data = Game::Scr_GetString(1);
|
||||||
|
|
||||||
Script::ScriptStorage.insert_or_assign(key, data);
|
Script::ScriptStorage.insert_or_assign(key, data);
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("StorageRemove", [](Game::scr_entref_t) // gsc: StorageRemove(<str key>);
|
Script::AddFunction("StorageRemove", [](Game::scr_entref_t) // gsc: StorageRemove(<str key>);
|
||||||
{
|
|
||||||
if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING)
|
|
||||||
{
|
{
|
||||||
Game::Scr_Error("^1StorageRemove: Needs one string parameter!\n");
|
if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||||
return;
|
{
|
||||||
}
|
Game::Scr_Error("^1StorageRemove: Needs one string parameter!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::string key = Game::Scr_GetString(0);
|
std::string key = Game::Scr_GetString(0);
|
||||||
|
|
||||||
if (!Script::ScriptStorage.contains(key))
|
if (!Script::ScriptStorage.contains(key))
|
||||||
{
|
{
|
||||||
Game::Scr_Error(Utils::String::VA("^1StorageRemove: Store does not have key '%s'!\n", key.c_str()));
|
Game::Scr_Error(Utils::String::VA("^1StorageRemove: Store does not have key '%s'!\n", key.c_str()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Script::ScriptStorage.erase(key);
|
Script::ScriptStorage.erase(key);
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("StorageGet", [](Game::scr_entref_t) // gsc: StorageGet(<str key>);
|
Script::AddFunction("StorageGet", [](Game::scr_entref_t) // gsc: StorageGet(<str key>);
|
||||||
{
|
|
||||||
if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING)
|
|
||||||
{
|
{
|
||||||
Game::Scr_Error("^1StorageGet: Needs one string parameter!\n");
|
if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||||
return;
|
{
|
||||||
}
|
Game::Scr_Error("^1StorageGet: Needs one string parameter!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::string key = Game::Scr_GetString(0);
|
std::string key = Game::Scr_GetString(0);
|
||||||
|
|
||||||
if (!Script::ScriptStorage.contains(key))
|
if (!Script::ScriptStorage.contains(key))
|
||||||
{
|
{
|
||||||
Game::Scr_Error(Utils::String::VA("^1StorageGet: Store does not have key '%s'!\n", key.c_str()));
|
Game::Scr_Error(Utils::String::VA("^1StorageGet: Store does not have key '%s'!\n", key.c_str()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = Script::ScriptStorage.at(key);
|
auto data = Script::ScriptStorage.at(key);
|
||||||
Game::Scr_AddString(data.c_str());
|
Game::Scr_AddString(data.c_str());
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("StorageHas", [](Game::scr_entref_t) // gsc: StorageHas(<str key>);
|
Script::AddFunction("StorageHas", [](Game::scr_entref_t) // gsc: StorageHas(<str key>);
|
||||||
{
|
|
||||||
if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING)
|
|
||||||
{
|
{
|
||||||
Game::Scr_Error("^1StorageHas: Needs one string parameter!\n");
|
if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||||
return;
|
{
|
||||||
}
|
Game::Scr_Error("^1StorageHas: Needs one string parameter!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::string key = Game::Scr_GetString(0);
|
std::string key = Game::Scr_GetString(0);
|
||||||
|
|
||||||
Game::Scr_AddInt(Script::ScriptStorage.contains(key));
|
Game::Scr_AddInt(Script::ScriptStorage.contains(key));
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("StorageClear", [](Game::scr_entref_t) // gsc: StorageClear();
|
Script::AddFunction("StorageClear", [](Game::scr_entref_t) // gsc: StorageClear();
|
||||||
{
|
{
|
||||||
Script::ScriptStorage.clear();
|
Script::ScriptStorage.clear();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Script::Script()
|
Script::Script()
|
||||||
@ -458,6 +539,17 @@ namespace Components
|
|||||||
Utils::Hook(0x612DB0, Script::StoreFunctionNameStub, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x612DB0, Script::StoreFunctionNameStub, HOOK_JUMP).install()->quick();
|
||||||
Utils::Hook(0x427E71, Script::RestoreScriptNameStub, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x427E71, Script::RestoreScriptNameStub, HOOK_JUMP).install()->quick();
|
||||||
Utils::Hook(0x427DBC, Script::StoreScriptNameStub, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x427DBC, Script::StoreScriptNameStub, HOOK_JUMP).install()->quick();
|
||||||
|
Utils::Hook(0x426C2D, Script::StoreScriptBaseProgramNumStub, HOOK_JUMP).install()->quick();
|
||||||
|
Utils::Hook(0x42281B, Script::Scr_PrintPrevCodePosStub, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
|
// enable scr_error printing if in developer
|
||||||
|
Dvar::OnInit([]()
|
||||||
|
{
|
||||||
|
int developer = Dvar::Var("developer").get<int>();
|
||||||
|
|
||||||
|
if (developer > 0)
|
||||||
|
Utils::Hook::Set<BYTE>(0x48D8C7, 0x75);
|
||||||
|
});
|
||||||
|
|
||||||
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();
|
||||||
@ -475,9 +567,9 @@ namespace Components
|
|||||||
Utils::Hook(0x4D06BA, Script::ScrShutdownSystemStub, HOOK_CALL).install()->quick();
|
Utils::Hook(0x4D06BA, Script::ScrShutdownSystemStub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
Script::AddFunction("debugBox", [](Game::scr_entref_t)
|
Script::AddFunction("debugBox", [](Game::scr_entref_t)
|
||||||
{
|
{
|
||||||
MessageBoxA(nullptr, Game::Scr_GetString(0), "DEBUG", 0);
|
MessageBoxA(nullptr, Game::Scr_GetString(0), "DEBUG", 0);
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
Script::AddFunctions();
|
Script::AddFunctions();
|
||||||
|
|
||||||
@ -517,5 +609,6 @@ namespace Components
|
|||||||
Script::VMShutdownSignal.clear();
|
Script::VMShutdownSignal.clear();
|
||||||
|
|
||||||
Script::ScriptStorage.clear();
|
Script::ScriptStorage.clear();
|
||||||
|
Script::ScriptBaseProgramNum.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ namespace Components
|
|||||||
static std::vector<std::string> ScriptNameStack;
|
static std::vector<std::string> ScriptNameStack;
|
||||||
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> Script::ScriptBaseProgramNum;
|
||||||
|
|
||||||
static Utils::Signal<Scheduler::Callback> VMShutdownSignal;
|
static Utils::Signal<Scheduler::Callback> VMShutdownSignal;
|
||||||
|
|
||||||
@ -61,6 +62,10 @@ namespace Components
|
|||||||
static void GetFunctionStub();
|
static void GetFunctionStub();
|
||||||
|
|
||||||
static void ScrShutdownSystemStub(int);
|
static void ScrShutdownSystemStub(int);
|
||||||
|
static void StoreScriptBaseProgramNumStub();
|
||||||
|
static void StoreScriptBaseProgramNum();
|
||||||
|
static void Scr_PrintPrevCodePosStub();
|
||||||
|
static void Scr_PrintPrevCodePos(int);
|
||||||
|
|
||||||
static int SetExpFogStub();
|
static int SetExpFogStub();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user