diff --git a/client/src/bindings/WebView.cpp b/client/src/bindings/WebView.cpp index d59b4744c..86b3521ac 100644 --- a/client/src/bindings/WebView.cpp +++ b/client/src/bindings/WebView.cpp @@ -124,69 +124,209 @@ static void Constructor(const v8::FunctionCallbackInfo& info) V8_CHECK_CONSTRUCTOR(); V8_CHECK_ARGS_LEN_MIN_MAX(1, 4); - V8_ARG_TO_STRING(1, url); - alt::IResource* altres = V8ResourceImpl::GetResource(isolate->GetEnteredOrMicrotaskContext()); V8_CHECK(altres, "invalid resource"); alt::IWebView* view = nullptr; - if(info.Length() == 4) + if (info.Length() == 1 && info[0]->IsObject()) { - V8_ARG_TO_BOOLEAN(2, isOverlayBool); - V8_ARG_TO_OBJECT(3, pos); - V8_ARG_TO_OBJECT(4, size); - - V8_OBJECT_GET_INT(pos, "x", posX); - V8_OBJECT_GET_INT(pos, "y", posY); + V8_ARG_TO_OBJECT(1, params); + using values_t = std::unordered_map>; + std::optional values = V8Helpers::CppValue>(params); + V8_CHECK(values.has_value(), "Params are empty"); + V8_CHECK(!values->empty(), "Params are empty"); + + alt::WebViewHeaders headers; + std::vector cookies; + int posX = 0; + int posY = 0; + int sizeX = 0; + int sizeY = 0; + int drawableHash = 0; + std::string targetTextureStr; + bool isOverlay = false; + bool onTextureView = false; + V8_TO_STRING(values->at("url"), url); + + if (values->contains("pos")) + { + V8_TO_OBJECT(values->at("pos"), pos); + V8_OBJECT_GET_INT(pos, "x", v8posX); + V8_OBJECT_GET_INT(pos, "y", v8posY); + posX = v8posX; + posY = v8posY; + } + if (values->contains("size")) + { + V8_TO_OBJECT(values->at("size"), size); + V8_OBJECT_GET_INT(size, "x", v8sizeX); + V8_OBJECT_GET_INT(size, "y", v8sizeY); + sizeX = v8sizeX; + sizeY = v8sizeY; + } + if (values->contains("isOverlay")) + { + V8_TO_BOOLEAN(values->at("isOverlay"), v8isOverlay); + isOverlay = v8isOverlay; + } + if (values->contains("drawableHash")) + { + V8_CHECK(values->contains("targetTexture"), "targetTexture should be specified for drawableHash"); + V8_TO_INTEGER(values->at("drawableHash"), v8drawableHash); + drawableHash = v8drawableHash; + onTextureView = true; + } + if (values->contains("targetTexture")) + { + V8_CHECK(values->contains("drawableHash"), "drawableHash should be specified for targetTexture"); + V8_TO_STRING(values->at("targetTexture"), v8targetTexture); + targetTextureStr = v8targetTexture; + } + if (values->contains("headers")) + { + V8_TO_OBJECT(values->at("headers"), v8headers); + auto headers_opt = V8Helpers::CppValue(v8headers); + V8_CHECK(headers_opt.has_value(), "headers object is empty"); + headers = std::move(headers_opt).value(); + } + if (values->contains("cookies")) + { + V8_TO_ARRAY(values->at("cookies"), v8cookies); + auto cookies_opt = V8Helpers::CppValue>(v8cookies); + V8_CHECK(cookies_opt.has_value(), "cookies array is empty"); + for (auto& cookie: cookies_opt.value()) + { + + V8_TO_OBJECT(cookie, v8cookie); + auto cookie_opt = V8Helpers::CppValue>(v8cookie); + V8_CHECK(cookie_opt.has_value(), "cookie object is empty"); + + V8_OBJECT_GET_STRING(v8cookie, "url", cookie_url); + V8_OBJECT_GET_STRING(v8cookie, "name", cookie_name); + V8_OBJECT_GET_STRING(v8cookie, "value", cookie_value); + + V8_CHECK(cookie_name.find("__altv_") == 0, "Cookie name should start with '__altv_'"); + WebViewCookie new_cookie {}; + new_cookie.url = std::move(cookie_url); + new_cookie.name = std::move(cookie_name); + new_cookie.value = std::move(cookie_value); + if (cookie_opt->contains("httpOnly")) + { + V8_TO_BOOLEAN(cookie_opt->at("httpOnly"), v8http_only); + new_cookie.httpOnly = v8http_only; + } + if (cookie_opt->contains("secure")) + { + V8_TO_BOOLEAN(cookie_opt->at("secure"), v8secure); + new_cookie.secure = v8secure; + } + if (cookie_opt->contains("domain")) + { + V8_TO_STRING(cookie_opt->at("domain"), v8domain); + new_cookie.domain = std::move(v8domain); + } + if (cookie_opt->contains("path")) + { + V8_TO_STRING(cookie_opt->at("path"), v8path); + new_cookie.path = std::move(v8path); + } + if (cookie_opt->contains("sameSite")) + { + V8_TO_STRING(cookie_opt->at("sameSite"), v8same_site); + V8_CHECK(v8same_site == "NO_RESTRICTION" || v8same_site == "LAX_MODE" || v8same_site == "STRICT_MODE", + "sameSite value should be one of ['NO_RESTRICTION', 'LAX_MODE', 'STRICT_MODE']"); + new_cookie.sameSite = std::move(v8same_site); + } + if (cookie_opt->contains("priority")) + { + V8_TO_STRING(cookie_opt->at("priority"), v8priority); + V8_CHECK(v8priority == "LOW" || v8priority == "MEDIUM" || v8priority == "HIGH", "priority value should be one of ['LOW', 'MEDIUM', 'HIGH']"); + new_cookie.priority = std::move(v8priority); + } + if (cookie_opt->contains("expires")) + { + V8_TO_INTEGER(cookie_opt->at("expires"), v8expires); + new_cookie.expires = v8expires; + } + + V8_CHECK(!(new_cookie.httpOnly && new_cookie.secure), "HTTP only and secure cannot be combined"); + + cookies.emplace_back(std::move(new_cookie)); + } + } - V8_OBJECT_GET_INT(size, "x", sizeX); - V8_OBJECT_GET_INT(size, "y", sizeY); + if (onTextureView) + { + auto texture = alt::ICore::Instance().GetTextureFromDrawable(drawableHash, targetTextureStr); + V8_CHECK(texture != nullptr, "Texture not found"); - view = alt::ICore::Instance().CreateWebView(url, { posX, posY }, { sizeX, sizeY }, true, isOverlayBool, altres); - } - else if(info.Length() == 3 && info[2]->IsObject()) + view = alt::ICore::Instance().CreateWebView(url, (uint32_t)drawableHash, targetTextureStr, altres, headers, cookies); + V8_CHECK(view, "Interactive WebView cannot be created"); + } else + { + view = alt::ICore::Instance().CreateWebView(url, { posX, posY }, { sizeX, sizeY }, true, isOverlay, altres, headers, cookies); + } + } else { - V8_ARG_TO_OBJECT(2, pos); - V8_ARG_TO_OBJECT(3, size); + V8_ARG_TO_STRING(1, url); + if(info.Length() == 4) + { + V8_ARG_TO_BOOLEAN(2, isOverlayBool); + V8_ARG_TO_OBJECT(3, pos); + V8_ARG_TO_OBJECT(4, size); - V8_OBJECT_GET_INT(pos, "x", posX); - V8_OBJECT_GET_INT(pos, "y", posY); + V8_OBJECT_GET_INT(pos, "x", posX); + V8_OBJECT_GET_INT(pos, "y", posY); - V8_OBJECT_GET_INT(size, "x", sizeX); - V8_OBJECT_GET_INT(size, "y", sizeY); + V8_OBJECT_GET_INT(size, "x", sizeX); + V8_OBJECT_GET_INT(size, "y", sizeY); - view = alt::ICore::Instance().CreateWebView(url, { posX, posY }, { sizeX, sizeY }, true, false, altres); - } - else if(info.Length() == 3) - { - V8_ARG_TO_INT(2, drawableHash); - V8_ARG_TO_STRING(3, targetTextureStr); + view = alt::ICore::Instance().CreateWebView(url, { posX, posY }, { sizeX, sizeY }, true, isOverlayBool, altres); + } + else if(info.Length() == 3 && info[2]->IsObject()) + { + V8_ARG_TO_OBJECT(2, pos); + V8_ARG_TO_OBJECT(3, size); - auto texture = alt::ICore::Instance().GetTextureFromDrawable(drawableHash, targetTextureStr); - V8_CHECK(texture != nullptr, "Texture not found"); + V8_OBJECT_GET_INT(pos, "x", posX); + V8_OBJECT_GET_INT(pos, "y", posY); - view = alt::ICore::Instance().CreateWebView(url, (uint32_t)drawableHash, targetTextureStr, altres); - V8_CHECK(view, "Interactive WebView cannot be created"); - } - else if(info.Length() == 2 && info[1]->IsObject()) - { - V8_ARG_TO_OBJECT(2, pos); + V8_OBJECT_GET_INT(size, "x", sizeX); + V8_OBJECT_GET_INT(size, "y", sizeY); - V8_OBJECT_GET_INT(pos, "x", posX); - V8_OBJECT_GET_INT(pos, "y", posY); + view = alt::ICore::Instance().CreateWebView(url, { posX, posY }, { sizeX, sizeY }, true, false, altres); + } + else if(info.Length() == 3) + { + V8_ARG_TO_INT(2, drawableHash); + V8_ARG_TO_STRING(3, targetTextureStr); - view = alt::ICore::Instance().CreateWebView(url, { posX, posY }, { 0, 0 }, true, false, altres); - } - else if(info.Length() == 2) - { - V8_ARG_TO_BOOLEAN(2, isOverlayBool); + auto texture = alt::ICore::Instance().GetTextureFromDrawable(drawableHash, targetTextureStr); + V8_CHECK(texture != nullptr, "Texture not found"); - view = alt::ICore::Instance().CreateWebView(url, { 0, 0 }, { 0, 0 }, true, isOverlayBool, altres); - } - else - { - view = alt::ICore::Instance().CreateWebView(url, { 0, 0 }, { 0, 0 }, true, false, altres); + view = alt::ICore::Instance().CreateWebView(url, (uint32_t)drawableHash, targetTextureStr, altres); + V8_CHECK(view, "Interactive WebView cannot be created"); + } + else if(info.Length() == 2 && info[1]->IsObject()) + { + V8_ARG_TO_OBJECT(2, pos); + + V8_OBJECT_GET_INT(pos, "x", posX); + V8_OBJECT_GET_INT(pos, "y", posY); + + view = alt::ICore::Instance().CreateWebView(url, { posX, posY }, { 0, 0 }, true, false, altres); + } + else if(info.Length() == 2) + { + V8_ARG_TO_BOOLEAN(2, isOverlayBool); + + view = alt::ICore::Instance().CreateWebView(url, { 0, 0 }, { 0, 0 }, true, isOverlayBool, altres); + } + else + { + view = alt::ICore::Instance().CreateWebView(url, { 0, 0 }, { 0, 0 }, true, false, altres); + } } V8_BIND_BASE_OBJECT(view, "Failed to create WebView"); @@ -205,6 +345,68 @@ static void SetExtraHeader(const v8::FunctionCallbackInfo& info) view->SetExtraHeader(name, value); } +static void SetCookie(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT(); + + V8_GET_THIS_BASE_OBJECT(view, alt::IWebView); + + V8_CHECK_ARGS_LEN(1); + V8_ARG_TO_OBJECT(1, cookie); + + auto cookie_opt = V8Helpers::CppValue>(cookie); + V8_CHECK(cookie_opt.has_value(), "cookie object is empty"); + + V8_OBJECT_GET_STRING(cookie, "url", cookie_url); + V8_OBJECT_GET_STRING(cookie, "name", cookie_name); + V8_OBJECT_GET_STRING(cookie, "value", cookie_value); + + V8_CHECK(cookie_name.find("__altv_") == 0, "Cookie name should start with '__altv_'"); + WebViewCookie new_cookie {}; + new_cookie.url = std::move(cookie_url); + new_cookie.name = std::move(cookie_name); + new_cookie.value = std::move(cookie_value); + if (cookie_opt->contains("httpOnly")) + { + V8_TO_BOOLEAN(cookie_opt->at("httpOnly"), v8http_only); + new_cookie.httpOnly = v8http_only; + } + if (cookie_opt->contains("secure")) + { + V8_TO_BOOLEAN(cookie_opt->at("secure"), v8secure); + new_cookie.secure = v8secure; + } + if (cookie_opt->contains("domain")) + { + V8_TO_STRING(cookie_opt->at("domain"), v8domain); + new_cookie.domain = std::move(v8domain); + } + if (cookie_opt->contains("path")) + { + V8_TO_STRING(cookie_opt->at("path"), v8path); + new_cookie.path = std::move(v8path); + } + if (cookie_opt->contains("sameSite")) + { + V8_TO_STRING(cookie_opt->at("sameSite"), v8same_site); + new_cookie.sameSite = std::move(v8same_site); + } + if (cookie_opt->contains("priority")) + { + V8_TO_STRING(cookie_opt->at("priority"), v8priority); + new_cookie.priority = std::move(v8priority); + } + if (cookie_opt->contains("expires")) + { + V8_TO_INTEGER(cookie_opt->at("expires"), v8expires); + new_cookie.expires = v8expires; + } + + V8_CHECK(!(new_cookie.httpOnly && new_cookie.secure), "HTTP only and secure cannot be combined"); + + view->SetCookie(new_cookie); +} + static void SetZoomLevel(const v8::FunctionCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); @@ -345,6 +547,7 @@ extern V8Class v8WebView("WebView", V8Helpers::SetMethod(isolate, tpl, "unfocus"); V8Helpers::SetMethod(isolate, tpl, "setExtraHeader", &SetExtraHeader); + V8Helpers::SetMethod(isolate, tpl, "setCookie", &SetCookie); V8Helpers::SetMethod(isolate, tpl, "setZoomLevel", &SetZoomLevel); V8Helpers::SetMethod(isolate, tpl, "reload", &Reload); diff --git a/server/src/CNodeScriptRuntime.h b/server/src/CNodeScriptRuntime.h index b81a37e41..121edff0d 100644 --- a/server/src/CNodeScriptRuntime.h +++ b/server/src/CNodeScriptRuntime.h @@ -72,7 +72,7 @@ class CNodeScriptRuntime : public alt::IScriptRuntime, public IRuntimeEventHandl return platform.get(); } - std::unordered_set GetResources() + std::unordered_set& GetResources() { return resources; } diff --git a/server/src/bindings/ConnectionInfo.cpp b/server/src/bindings/ConnectionInfo.cpp index c831a62a9..4aed7ff39 100644 --- a/server/src/bindings/ConnectionInfo.cpp +++ b/server/src/bindings/ConnectionInfo.cpp @@ -33,6 +33,13 @@ static void HwidExHashGetter(v8::Local, const v8::PropertyCallbackIn V8_RETURN_STRING(std::to_string(con->GetHwIdExHash())); } +static void HwId3Getter(v8::Local, const v8::PropertyCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT_RESOURCE(); + V8_GET_THIS_BASE_OBJECT(con, alt::IConnectionInfo); + V8_RETURN_STRING(con->GetHwid3()); +} + static void AuthTokenGetter(v8::Local, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT_RESOURCE(); diff --git a/server/src/bindings/Main.cpp b/server/src/bindings/Main.cpp index 5d66483d2..b17295fba 100644 --- a/server/src/bindings/Main.cpp +++ b/server/src/bindings/Main.cpp @@ -841,6 +841,12 @@ static void HasBenefit(const v8::FunctionCallbackInfo& info) V8_ARG_TO_UINT(1, benefit); V8_RETURN_BOOLEAN(alt::ICore::Instance().HasBenefit((alt::Benefit)benefit)); +} + +static void PrintHealth(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT_RESOURCE(); + resource->PrintHealth(); } extern V8Class v8Player, v8Vehicle, v8Blip, v8AreaBlip, v8RadiusBlip, v8PointBlip, v8Checkpoint, v8VoiceChannel, v8Colshape, v8ColshapeCylinder, v8ColshapeSphere, v8ColshapeCircle, @@ -935,7 +941,9 @@ extern V8Module V8Helpers::RegisterFunc(exports, "getMigrationDistance", &GetMigrationDistance); V8Helpers::RegisterFunc(exports, "setMigrationDistance", &SetMigrationDistance); - V8Helpers::RegisterFunc(exports, "hasBenefit", &HasBenefit); + V8Helpers::RegisterFunc(exports, "hasBenefit", &HasBenefit); + + V8Helpers::RegisterFunc(exports, "printHealth", &PrintHealth); V8_OBJECT_SET_STRING(exports, "rootDir", alt::ICore::Instance().GetRootDirectory()); }); diff --git a/server/src/bindings/Player.cpp b/server/src/bindings/Player.cpp index 37de52c56..063527a1e 100644 --- a/server/src/bindings/Player.cpp +++ b/server/src/bindings/Player.cpp @@ -218,6 +218,13 @@ static void HwidExHashGetter(v8::Local name, const v8::PropertyCallb V8_RETURN_STRING(std::to_string(_this->GetHwidExHash())); } +static void HwId3Getter(v8::Local name, const v8::PropertyCallbackInfo& info) +{ + V8_GET_ISOLATE(); + V8_GET_THIS_BASE_OBJECT(_this, IPlayer); + V8_RETURN_STRING(_this->GetHwid3()); +} + static void SetClothes(const v8::FunctionCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); @@ -1513,6 +1520,7 @@ extern V8Class v8Player("Player", V8Helpers::SetAccessor(isolate, tpl, "socialID", &SocialIDGetter); V8Helpers::SetAccessor(isolate, tpl, "hwidHash", &HwidHashGetter); V8Helpers::SetAccessor(isolate, tpl, "hwidExHash", &HwidExHashGetter); + V8Helpers::SetAccessor(isolate, tpl, "hwid3", &HwId3Getter); V8Helpers::SetAccessor(isolate, tpl, "socialClubName"); V8Helpers::SetAccessor(isolate, tpl, "authToken"); diff --git a/server/src/events/Player.cpp b/server/src/events/Player.cpp index 50086dbf3..63deb5e49 100644 --- a/server/src/events/Player.cpp +++ b/server/src/events/Player.cpp @@ -16,8 +16,6 @@ #include "cpp-sdk/events/CPlayerWeaponChangeEvent.h" #include "cpp-sdk/events/CLocalMetaDataChangeEvent.h" #include "cpp-sdk/events/CPlayerRequestControlEvent.h" -#include "cpp-sdk/events/CPlayerChangeInteriorEvent.h" -#include "cpp-sdk/events/CPlayerDimensionChangeEvent.h" using alt::CEvent; using EventType = CEvent::Type; @@ -186,30 +184,6 @@ V8_LOCAL_EVENT_HANDLER requestControl(EventType::PLAYER_REQUEST_CONTROL, args.push_back(resource->GetBaseObjectOrNull(ev->GetTarget())); }); -V8_LOCAL_EVENT_HANDLER playerInteriorChange(EventType::PLAYER_CHANGE_INTERIOR_EVENT, - "playerInteriorChange", - [](V8ResourceImpl* resource, const alt::CEvent* e, std::vector>& args) - { - auto ev = static_cast(e); - v8::Isolate* isolate = resource->GetIsolate(); - - args.push_back(resource->GetBaseObjectOrNull(ev->GetTarget())); - args.push_back(V8Helpers::JSValue(ev->GetOldInteriorLocation())); - args.push_back(V8Helpers::JSValue(ev->GetNewInteriorLocation())); - }); - -V8_LOCAL_EVENT_HANDLER playerDimensionChange(EventType::PLAYER_DIMENSION_CHANGE, - "playerDimensionChange", - [](V8ResourceImpl* resource, const alt::CEvent* e, std::vector>& args) - { - auto ev = static_cast(e); - v8::Isolate* isolate = resource->GetIsolate(); - - args.push_back(resource->GetBaseObjectOrNull(ev->GetTarget())); - args.push_back(V8Helpers::JSValue(ev->GetOldDimension())); - args.push_back(V8Helpers::JSValue(ev->GetNewDimension())); - }); - V8_LOCAL_EVENT_HANDLER playerSpawn(EventType::PLAYER_SPAWN, "playerSpawn", [](V8ResourceImpl* resource, const alt::CEvent* e, std::vector>& args) diff --git a/server/src/node-module.cpp b/server/src/node-module.cpp index 67569047c..cb0842546 100644 --- a/server/src/node-module.cpp +++ b/server/src/node-module.cpp @@ -76,6 +76,13 @@ static void CommandHandler(const std::vector& args) Log::Colored << " ~ly~--help ~w~- this message." << Log::Endl; Log::Colored << " ~ly~--version ~w~- version info." << Log::Endl; } + else if (args[0] == "--health") + { + auto& runtime = CNodeScriptRuntime::Instance(); + auto& resources = runtime.GetResources(); + + for(auto resource : resources) resource->PrintHealth(); + } } static void TimersCommand(const std::vector&) diff --git a/shared/V8ResourceImpl.cpp b/shared/V8ResourceImpl.cpp index 1181a8bfe..884c67026 100644 --- a/shared/V8ResourceImpl.cpp +++ b/shared/V8ResourceImpl.cpp @@ -77,7 +77,16 @@ void V8ResourceImpl::OnTick() for(auto& nextTickCb : nextTickCallbacks) nextTickCb(); nextTickCallbacks.clear(); - for(auto& id : oldTimers) timers.erase(id); + for(auto& id : oldTimers) + { + auto it = timers.find(id); + if(it == timers.end()) + continue; + + auto timer = it->second; + timers.erase(it); + delete timer; + } oldTimers.clear(); @@ -629,6 +638,18 @@ void V8ResourceImpl::InvokeEventHandlers(const alt::CEvent* ev, const std::vecto } } +void V8ResourceImpl::PrintHealth() +{ + Log::Info << "Resource health: " << resource->GetName() << Log::Endl; + Log::Info << " - Entities: " << entities.size() << Log::Endl; + Log::Info << " - Timers: " << timers.size() << Log::Endl; + Log::Info << " - Timer benchmarks: " << benchmarkTimers.size() << Log::Endl; + +#ifdef ALT_SERVER_API + Log::Info << " - Vehicle passengers: " << vehiclePassengers.size() << Log::Endl; +#endif // ALT_SERVER_API +} + // Internal script globals static void SetLogFunction(const v8::FunctionCallbackInfo& info) { diff --git a/shared/V8ResourceImpl.h b/shared/V8ResourceImpl.h index 8978fc23f..7650db38e 100644 --- a/shared/V8ResourceImpl.h +++ b/shared/V8ResourceImpl.h @@ -424,5 +424,7 @@ class V8ResourceImpl : public alt::IResource::Impl ObjectKey AKey{ this, "a" }; ObjectKey PosKey{ this, "pos" }; - ObjectKey WeaponKey{ this, "weapon" }; + ObjectKey WeaponKey{ this, "weapon" }; + + void PrintHealth(); }; diff --git a/shared/deps/cpp-sdk b/shared/deps/cpp-sdk index f18e52bbb..550772723 160000 --- a/shared/deps/cpp-sdk +++ b/shared/deps/cpp-sdk @@ -1 +1 @@ -Subproject commit f18e52bbb7fd9cc57efa66f6c40449b41cdc13a0 +Subproject commit 5507727239d5665e75828a7bec3f44bff245f3c8 diff --git a/shared/events/Player.cpp b/shared/events/Player.cpp index c94a2859b..4ea54a04d 100644 --- a/shared/events/Player.cpp +++ b/shared/events/Player.cpp @@ -2,17 +2,45 @@ #include "../V8Helpers.h" #include "cpp-sdk/events/CPlayerChangeAnimationEvent.h" +#include "cpp-sdk/events/CPlayerChangeInteriorEvent.h" +#include "cpp-sdk/events/CPlayerDimensionChangeEvent.h" using EventType = alt::CEvent::Type; -V8_LOCAL_EVENT_HANDLER -animationChange(EventType::PLAYER_CHANGE_ANIMATION_EVENT, "playerAnimationChange", [](V8ResourceImpl* resource, const alt::CEvent* e, std::vector>& args) { - auto ev = static_cast(e); - v8::Isolate* isolate = resource->GetIsolate(); - - args.push_back(resource->GetBaseObjectOrNull(ev->GetTarget())); - args.push_back(V8Helpers::JSValue(ev->GetOldAnimationDict())); - args.push_back(V8Helpers::JSValue(ev->GetNewAnimationDict())); - args.push_back(V8Helpers::JSValue(ev->GetOldAnimationName())); - args.push_back(V8Helpers::JSValue(ev->GetNewAnimationName())); -}); +V8_LOCAL_EVENT_HANDLER animationChange(EventType::PLAYER_CHANGE_ANIMATION_EVENT, + "playerAnimationChange", + [](V8ResourceImpl* resource, const alt::CEvent* e, std::vector>& args) + { + auto ev = static_cast(e); + v8::Isolate* isolate = resource->GetIsolate(); + + args.emplace_back(resource->GetBaseObjectOrNull(ev->GetTarget())); + args.emplace_back(V8Helpers::JSValue(ev->GetOldAnimationDict())); + args.emplace_back(V8Helpers::JSValue(ev->GetNewAnimationDict())); + args.emplace_back(V8Helpers::JSValue(ev->GetOldAnimationName())); + args.emplace_back(V8Helpers::JSValue(ev->GetNewAnimationName())); + }); + +V8_LOCAL_EVENT_HANDLER playerInteriorChange(EventType::PLAYER_CHANGE_INTERIOR_EVENT, + "playerInteriorChange", + [](V8ResourceImpl* resource, const alt::CEvent* e, std::vector>& args) + { + auto ev = static_cast(e); + v8::Isolate* isolate = resource->GetIsolate(); + + args.emplace_back(resource->GetBaseObjectOrNull(ev->GetTarget())); + args.emplace_back(V8Helpers::JSValue(ev->GetOldInteriorLocation())); + args.emplace_back(V8Helpers::JSValue(ev->GetNewInteriorLocation())); + }); + +V8_LOCAL_EVENT_HANDLER playerDimensionChange(EventType::PLAYER_DIMENSION_CHANGE, + "playerDimensionChange", + [](V8ResourceImpl* resource, const alt::CEvent* e, std::vector>& args) + { + auto ev = static_cast(e); + v8::Isolate* isolate = resource->GetIsolate(); + + args.push_back(resource->GetBaseObjectOrNull(ev->GetTarget())); + args.push_back(V8Helpers::JSValue(ev->GetOldDimension())); + args.push_back(V8Helpers::JSValue(ev->GetNewDimension())); + }); diff --git a/shared/helpers/Macros.h b/shared/helpers/Macros.h index 68d21e3e2..2f67a2d3a 100644 --- a/shared/helpers/Macros.h +++ b/shared/helpers/Macros.h @@ -126,6 +126,10 @@ v8::Local val; \ V8_CHECK(V8Helpers::SafeToObject((v8Val), ctx, val), "Failed to convert value to object") +#define V8_TO_ARRAY(v8Val, val) \ + v8::Local val; \ + V8_CHECK(V8Helpers::SafeToArray((v8Val), ctx, val), "Failed to convert value to array") + #define V8_TO_VECTOR3(v8Val, val) \ alt::Vector3f val; \ V8_CHECK(V8Helpers::SafeToVector3((v8Val), ctx, val), "Failed to convert value to Vector3") diff --git a/shared/helpers/Serialization.cpp b/shared/helpers/Serialization.cpp index 5275f9053..7f16b8d2d 100644 --- a/shared/helpers/Serialization.cpp +++ b/shared/helpers/Serialization.cpp @@ -528,7 +528,10 @@ alt::MValueByteArray V8Helpers::V8ToRawBytes(v8::Local val) if(!serializer.WriteValue(ctx, val).To(&result) || !result) return alt::MValueByteArray(); std::pair serialized = serializer.Release(); - return alt::ICore::Instance().CreateMValueByteArray(serialized.first, serialized.second); + auto mvArray = alt::ICore::Instance().CreateMValueByteArray(serialized.first, serialized.second); + + delegate.FreeBufferMemory(serialized.first); + return mvArray; } // Converts a MValue byte array to a JS value