From 8e11ec5dfb04cb229efffec8ca6880845c6a9da6 Mon Sep 17 00:00:00 2001 From: Denis Ahmatovic <37641046+Andosius@users.noreply.github.com> Date: Wed, 14 Feb 2024 16:09:31 +0100 Subject: [PATCH] add option to prevent filterscript callback calls on (un)load --- Server/Components/Pawn/Manager/Manager.cpp | 55 +++++++++++++--------- Server/Source/core_impl.hpp | 1 + 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/Server/Components/Pawn/Manager/Manager.cpp b/Server/Components/Pawn/Manager/Manager.cpp index 09405a131..6c1189262 100644 --- a/Server/Components/Pawn/Manager/Manager.cpp +++ b/Server/Components/Pawn/Manager/Manager.cpp @@ -533,9 +533,13 @@ void PawnManager::openAMX(PawnScript& script, bool isEntryScript) // cache public pointers. // Call `OnPlayerConnect` (can be after caching). - for (auto p : players->entries()) + // https://github.com/openmultiplayer/open.mp/issues/807 + if (isEntryScript || config->getBool("game.use_filterscript_load_events")) { - script.Call("OnPlayerConnect", DefaultReturnValue_True, p->getID()); + for (auto p : players->entries()) + { + script.Call("OnPlayerConnect", DefaultReturnValue_True, p->getID()); + } } } @@ -593,40 +597,45 @@ bool PawnManager::Load(std::string const& name, bool isEntryScript) void PawnManager::closeAMX(PawnScript& script, bool isEntryScript) { - AMX* amx = script.GetAMX(); - int idx; - bool once = true; - // Reason 4, to match fixes.inc. Why was it not 3? I don't know. - if (amx_FindPublic(amx, "OnPlayerDisconnect", &idx) == AMX_ERR_NONE) + // https://github.com/openmultiplayer/open.mp/issues/807 + if (isEntryScript || config->getBool("game.use_filterscript_load_events")) { - for (auto const p : players->entries()) + AMX* amx = script.GetAMX(); + int idx; + bool once = true; + // Reason 4, to match fixes.inc. Why was it not 3? I don't know. + if (amx_FindPublic(amx, "OnPlayerDisconnect", &idx) == AMX_ERR_NONE) { - cell ret = 1; - int err = script.CallChecked(idx, ret, p->getID(), PeerDisconnectReason_ModeEnd); - switch (err) + for (auto const p : players->entries()) { - case AMX_ERR_NONE: - break; - case AMX_ERR_BOUNDS: - // Test the `OP_BOUNDS` parameter and the current index. - if (once && (*(cell*)((uintptr_t)amx->base + (((AMX_HEADER*)amx->base)->cod + amx->cip - sizeof(cell)))) == 2) // && amx->pri == 4) + cell ret = 1; + int err = script.CallChecked(idx, ret, p->getID(), PeerDisconnectReason_ModeEnd); + switch (err) { - core->printLn(R"( + case AMX_ERR_NONE: + break; + case AMX_ERR_BOUNDS: + // Test the `OP_BOUNDS` parameter and the current index. + if (once && (*(cell*)((uintptr_t)amx->base + (((AMX_HEADER*)amx->base)->cod + amx->cip - sizeof(cell)))) == 2) // && amx->pri == 4) + { + core->printLn(R"( Array out-of-bounds encountered during `OnPlayerDisconnect` with reason `4` (script exit). This may be due to old code assuming the highest possible reason is `2`. )"); - // Only show the error once, don't spam it. - once = false; + // Only show the error once, don't spam it. + once = false; + break; + } + // Fallthrough + default: + core->logLn(LogLevel::Error, "%s", aux_StrError(err)); break; } - // Fallthrough - default: - core->logLn(LogLevel::Error, "%s", aux_StrError(err)); - break; } } } + if (isEntryScript) { script.Call("OnGameModeExit", DefaultReturnValue_False); diff --git a/Server/Source/core_impl.hpp b/Server/Source/core_impl.hpp index e7c49df08..e9832c531 100644 --- a/Server/Source/core_impl.hpp +++ b/Server/Source/core_impl.hpp @@ -87,6 +87,7 @@ static const std::map Defaults { { "game.use_all_animations", true }, { "game.lag_compensation_mode", LagCompMode_Enabled }, { "game.group_player_objects", false }, + { "game.use_filterscript_load_events", true }, // logging { "logging.enable", true }, { "logging.file", String("log.txt") },