From 30664df8e9af073afc3b34e2f6331c6dfdbe7b22 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 25 Jun 2023 23:49:44 +0100 Subject: [PATCH] Fix #14853: [Plug-in] Subscribing to a non-existing event crashes game --- .../scripting/bindings/game/ScContext.hpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/openrct2/scripting/bindings/game/ScContext.hpp b/src/openrct2/scripting/bindings/game/ScContext.hpp index c8a71a02bc..a40c26e8a7 100644 --- a/src/openrct2/scripting/bindings/game/ScContext.hpp +++ b/src/openrct2/scripting/bindings/game/ScContext.hpp @@ -301,6 +301,19 @@ namespace OpenRCT2::Scripting return 1; } +# ifdef _MSC_VER + // HACK workaround to resolve issue #14853 + // The exception thrown in duk_error was causing a crash when RAII kicked in for this lambda. + // Only ensuring it was not in the same generated method fixed it. + __declspec(noinline) +# endif + std::shared_ptr CreateSubscription(HOOK_TYPE hookType, const DukValue& callback) + { + auto owner = _execInfo.GetCurrentPlugin(); + auto cookie = _hookEngine.Subscribe(hookType, owner, callback); + return std::make_shared([this, hookType, cookie]() { _hookEngine.Unsubscribe(hookType, cookie); }); + } + std::shared_ptr subscribe(const std::string& hook, const DukValue& callback) { auto& scriptEngine = GetContext()->GetScriptEngine(); @@ -328,8 +341,7 @@ namespace OpenRCT2::Scripting duk_error(ctx, DUK_ERR_ERROR, "Hook type not available for this plugin type."); } - auto cookie = _hookEngine.Subscribe(hookType, owner, callback); - return std::make_shared([this, hookType, cookie]() { _hookEngine.Unsubscribe(hookType, cookie); }); + return CreateSubscription(hookType, callback); } void queryAction(const std::string& action, const DukValue& args, const DukValue& callback)