[Script]: Load scripts from multiple dirs (#859)

This commit is contained in:
Edo 2023-03-21 11:59:31 +00:00 committed by GitHub
parent 65b095afcb
commit 9ff7dd81f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 12 deletions

View File

@ -34,14 +34,14 @@ namespace Components
bool Console::SkipShutdown = false;
COLORREF Console::TextColor =
#if _DEBUG
#ifdef _DEBUG
RGB(255, 200, 117);
#else
RGB(120, 237, 122);
#endif
COLORREF Console::BackgroundColor =
#if _DEBUG
#ifdef _DEBUG
RGB(35, 21, 0);
#else
RGB(25, 32, 25);
@ -383,6 +383,7 @@ namespace Components
RefreshOutput();
#ifdef _DEBUG
if (IsDebuggerPresent())
{
while (true)
@ -390,6 +391,7 @@ namespace Components
std::this_thread::sleep_for(5s);
}
}
#endif
TerminateProcess(GetCurrentProcess(), EXIT_FAILURE);
}
@ -894,7 +896,7 @@ namespace Components
Utils::Hook(0x64DC6B, 0x64DCC2, HOOK_JUMP).install()->quick();
#ifdef _DEBUG
Console::AddConsoleCommand();
AddConsoleCommand();
#endif
if (Dedicated::IsEnabled() && !ZoneBuilder::IsEnabled())

View File

@ -35,24 +35,23 @@ namespace Components::GSC
Game::Scr_StartupGameType();
}
// Do not use C++ objects because Scr_LoadScript may longjmp
void Script::GScr_LoadGameTypeScript_Stub()
void Script::LoadCustomScriptsFromFolder(const char* dir)
{
// Clear handles (from previous GSC loading session)
ScriptMainHandles.clear();
ScriptInitHandles.clear();
char path[MAX_OSPATH]{};
char searchPath[MAX_OSPATH]{};
char path[MAX_PATH]{};
strncpy_s(searchPath, dir, _TRUNCATE);
strncat_s(searchPath, "/", _TRUNCATE);
auto numFiles = 0;
const auto** files = Game::FS_ListFiles("scripts/", "gsc", Game::FS_LIST_ALL, &numFiles, 10);
const auto** files = Game::FS_ListFiles(searchPath, "gsc", Game::FS_LIST_ALL, &numFiles, 10);
for (auto i = 0; i < numFiles; ++i)
{
const auto* scriptFile = files[i];
Logger::Print("Loading script {}...\n", scriptFile);
const auto len = sprintf_s(path, "%s/%s", "scripts", scriptFile);
const auto len = sprintf_s(path, "%s/%s", dir, scriptFile);
if (len == -1)
{
continue;
@ -63,7 +62,7 @@ namespace Components::GSC
if (!Game::Scr_LoadScript(path))
{
Logger::Print("Script {} encountered an error while loading. (doesn't exist?)", path);
Logger::Print("Script {} encountered an error while loading. A compilation error is the most likely cause\n", path);
continue;
}
@ -72,12 +71,14 @@ namespace Components::GSC
const auto initHandle = Game::Scr_GetFunctionHandle(path, "init");
if (initHandle != 0)
{
Logger::Debug("Loaded '{}::init'", path);
ScriptInitHandles.insert_or_assign(path, initHandle);
}
const auto mainHandle = Game::Scr_GetFunctionHandle(path, "main");
if (mainHandle != 0)
{
Logger::Debug("Loaded '{}::main'", path);
ScriptMainHandles.insert_or_assign(path, mainHandle);
}
@ -85,6 +86,34 @@ namespace Components::GSC
}
Game::FS_FreeFileList(files, 10);
}
void Script::LoadCustomScripts()
{
LoadCustomScriptsFromFolder("scripts");
// Game specific
const auto* gameDir = "scripts/mp";
LoadCustomScriptsFromFolder(gameDir);
// Map specific
const auto* mapDir = Utils::String::Format("scripts/mp/{}", (*Game::sv_mapname)->current.string);
LoadCustomScriptsFromFolder(mapDir);
// Mode specific
const auto modeDir = Utils::String::Format("scripts/mp/{}", (*Game::g_gametype)->current.string);
LoadCustomScriptsFromFolder(modeDir);
}
// Do not use C++ objects because Scr_LoadScript may longjmp and crash or leak memory
void Script::GScr_LoadGameTypeScript_Stub()
{
// Clear handles (from previous GSC loading session)
ScriptMainHandles.clear();
ScriptInitHandles.clear();
LoadCustomScripts();
Game::GScr_LoadGameTypeScript();
}

View File

@ -39,6 +39,9 @@ namespace Components::GSC
static std::unordered_map<std::string, int> ScriptMainHandles;
static std::unordered_map<std::string, int> ScriptInitHandles;
static void LoadCustomScriptsFromFolder(const char* dir);
static void LoadCustomScripts();
static void Scr_LoadGameType_Stub();
static void Scr_StartupGameType_Stub();
static void GScr_LoadGameTypeScript_Stub();