| 429 | template <ScriptContext context> void (*SQCompileError)(HSQUIRRELVM sqvm, const char* error, const char* file, int line, int column); |
| 430 | template <ScriptContext context> |
| 431 | void __fastcall ScriptCompileErrorHook(HSQUIRRELVM sqvm, const char* error, const char* file, int line, int column) |
| 432 | { |
| 433 | bool bIsFatalError = g_pSquirrel[context]->m_bFatalCompilationErrors; |
| 434 | ScriptContext realContext = context; // ui and client use the same function so we use this for prints |
| 435 | if (IsUIVM(context, sqvm)) |
| 436 | { |
| 437 | realContext = ScriptContext::UI; |
| 438 | bIsFatalError = g_pSquirrel[ScriptContext::UI]->m_bFatalCompilationErrors; |
| 439 | } |
| 440 | |
| 441 | auto logger = getSquirrelLoggerByContext(realContext); |
| 442 | |
| 443 | const char* ownerName = "Vanilla"; |
| 444 | std::string filePath = g_pModManager->NormaliseModFilePath(fs::path("scripts/vscripts") / file); |
| 445 | auto it = g_pModManager->m_ModFiles.find(filePath); |
| 446 | if (it != g_pModManager->m_ModFiles.end()) |
| 447 | { |
| 448 | ModOverrideFile& modFile = it->second; |
| 449 | ownerName = modFile.m_pOwningMod ? modFile.m_pOwningMod->Name.c_str() : "Unknown"; |
| 450 | } |
| 451 | |
| 452 | logger->error("COMPILE ERROR {}", error); |
| 453 | logger->error("{} line [{}] column [{}]", file, line, column); |
| 454 | logger->error("This can be caused by a broken mod, or incompatibilities between mods."); |
| 455 | logger->error("{} belongs to {}", file, ownerName); |
| 456 | |
| 457 | // use disconnect to display an error message for the compile error, but only if the compilation error was fatal |
| 458 | // todo, we could get this from sqvm itself probably, rather than hooking sq_compiler_create |
| 459 | if (bIsFatalError) |
| 460 | { |
| 461 | // kill dedicated server if we hit this |
| 462 | if (IsDedicatedServer()) |
| 463 | { |
| 464 | logger->error("Exiting dedicated server, compile error is fatal"); |
| 465 | // flush the logger before we exit so debug things get saved to log file |
| 466 | logger->flush(); |
| 467 | exit(EXIT_FAILURE); |
| 468 | } |
| 469 | else |
| 470 | { |
| 471 | Cbuf_AddText( |
| 472 | Cbuf_GetCurrentPlayer(), |
| 473 | fmt::format("disconnect \"Encountered {} script compilation error, see console for details.\"", GetContextName(realContext)) |
| 474 | .c_str(), |
| 475 | cmd_source_t::kCommandSrcCode); |
| 476 | |
| 477 | // likely temp: show console so user can see any errors, as error message wont display if ui is dead |
| 478 | // maybe we could disable all mods other than the coremods and try a reload before doing this? |
| 479 | // could also maybe do some vgui bullshit to show something visually rather than console |
| 480 | if (realContext == ScriptContext::UI) |
| 481 | Cbuf_AddText(Cbuf_GetCurrentPlayer(), "showconsole", cmd_source_t::kCommandSrcCode); |
| 482 | } |
| 483 | } |
| 484 | |
| 485 | // dont call the original function since it kills game lol |
| 486 | } |
| 487 | |
| 488 | template <ScriptContext context> int64_t (*RegisterSquirrelFunction)(CSquirrelVM* sqvm, SQFuncRegistration* funcReg, char unknown); |
nothing calls this directly
no test coverage detected