From b951e89d72bfc4cead60ad0c03d4eb94ff41829c Mon Sep 17 00:00:00 2001 From: xLuxy <67131061+xLuxy@users.noreply.github.com> Date: Sun, 17 Mar 2024 23:56:02 +0100 Subject: [PATCH 01/14] ci: Fix upload tool --- .github/workflows/build-deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-deploy.yml b/.github/workflows/build-deploy.yml index 771a7faf..e4592cc8 100644 --- a/.github/workflows/build-deploy.yml +++ b/.github/workflows/build-deploy.yml @@ -132,7 +132,7 @@ jobs: rm dist-linux/sdk.version - name: Install upload tool - run: npm i @altmp/upload-tool@latest + run: npm i @altmp/upload-tool@latest fast-xml-parser@4.3.6 - name: Deploy windows artifacts to cdn run: npx alt-upload dist-windows js-module/$BRANCH/x64_win32 $VERSION $SDK_VERSION @@ -161,7 +161,7 @@ jobs: BRANCH: ${{ steps.version.outputs.BRANCH }} VERSION: ${{ steps.version.outputs.VERSION }} SDK_VERSION: ${{ steps.version.outputs.SDK_VERSION }} - + build-docker: name: Trigger Docker image build runs-on: ubuntu-latest From f87467d982266f39bfaabede446da3aee8828d88 Mon Sep 17 00:00:00 2001 From: Vadim Zubkov Date: Mon, 18 Mar 2024 14:56:23 +0300 Subject: [PATCH 02/14] feat: mvalue & serialization optimizations --- server/src/CNodeResourceImpl.cpp | 8 ++- server/src/bindings/ConnectionInfo.cpp | 2 - shared/V8Class.h | 20 +++++++ shared/V8Entity.h | 7 +-- shared/V8Helpers.cpp | 16 ++++++ shared/V8Helpers.h | 3 ++ shared/V8ResourceImpl.cpp | 75 +++++++++++++------------- shared/V8ResourceImpl.h | 4 +- shared/bindings/BaseObject.cpp | 2 +- shared/bindings/Blip.cpp | 8 ++- shared/bindings/Quaternion.cpp | 5 +- shared/bindings/RGBA.cpp | 5 +- shared/bindings/Resource.cpp | 26 ++++----- shared/bindings/Vector2.cpp | 5 +- shared/bindings/Vector3.cpp | 5 +- shared/deps/cpp-sdk | 2 +- shared/helpers/Serialization.cpp | 61 ++++++++++++--------- 17 files changed, 153 insertions(+), 101 deletions(-) diff --git a/server/src/CNodeResourceImpl.cpp b/server/src/CNodeResourceImpl.cpp index a7a1d220..cbb4ff42 100644 --- a/server/src/CNodeResourceImpl.cpp +++ b/server/src/CNodeResourceImpl.cpp @@ -132,8 +132,12 @@ void CNodeResourceImpl::Started(v8::Local _exports) { if(!_exports->IsNullOrUndefined()) { - alt::MValueDict exports = std::dynamic_pointer_cast(V8Helpers::V8ToMValue(_exports)); - resource->SetExports(exports); + auto exports = V8Helpers::V8ToMValue(_exports); + if(exports->GetType() == alt::IMValue::Type::DICT) + resource->SetExports(std::static_pointer_cast(exports)); + else + Log::Warning << "Only object export is supported" << Log::Endl; + envStarted = true; } else diff --git a/server/src/bindings/ConnectionInfo.cpp b/server/src/bindings/ConnectionInfo.cpp index 4e178cee..c831a62a 100644 --- a/server/src/bindings/ConnectionInfo.cpp +++ b/server/src/bindings/ConnectionInfo.cpp @@ -215,8 +215,6 @@ extern V8Class v8ConnectionInfo("ConnectionInfo", { v8::Isolate* isolate = v8::Isolate::GetCurrent(); - tpl->InstanceTemplate()->SetInternalFieldCount(1); - V8Helpers::SetStaticMethod(isolate, tpl, "getByID", StaticGetByID); V8Helpers::SetStaticAccessor(isolate, tpl, "all", AllGetter); diff --git a/shared/V8Class.h b/shared/V8Class.h index ecd48c9f..36f46275 100644 --- a/shared/V8Class.h +++ b/shared/V8Class.h @@ -17,6 +17,26 @@ class V8Class std::unordered_map>> tplMap; public: + enum class InternalFields + { + OBJECT_CLASS, + BASE_OBJECT, + RESOURCE, + + COUNT + }; + + enum class ObjectClass + { + NONE, + RESOURCE, + BASE_OBJECT, + VECTOR2, + VECTOR3, + RGBA, + QUATERNION, + }; + static auto& All() { static std::unordered_map _All; diff --git a/shared/V8Entity.h b/shared/V8Entity.h index d79d2934..4affadc6 100644 --- a/shared/V8Entity.h +++ b/shared/V8Entity.h @@ -16,7 +16,8 @@ class V8Entity V8Entity(v8::Local ctx, V8Class* __class, v8::Local obj, alt::IBaseObject* _handle) : _class(__class), handle(_handle) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); - obj->SetInternalField(0, v8::External::New(isolate, this)); + V8Helpers::SetObjectClass(isolate, obj, V8Class::ObjectClass::BASE_OBJECT); + obj->SetInternalField(static_cast(V8Class::InternalFields::BASE_OBJECT), v8::External::New(isolate, this)); jsVal.Reset(isolate, obj); } @@ -40,9 +41,9 @@ class V8Entity if(!val->IsObject()) return nullptr; v8::Local obj = val.As(); - if(obj->InternalFieldCount() != 1) return nullptr; + if(obj->InternalFieldCount() <= static_cast(V8Class::InternalFields::BASE_OBJECT)) return nullptr; - v8::Local i = obj->GetInternalField(0); + v8::Local i = obj->GetInternalField(static_cast(V8Class::InternalFields::BASE_OBJECT)); if(!i->IsExternal()) return nullptr; return static_cast(i.As()->Value()); diff --git a/shared/V8Helpers.cpp b/shared/V8Helpers.cpp index a4014d16..5f0d7d11 100644 --- a/shared/V8Helpers.cpp +++ b/shared/V8Helpers.cpp @@ -373,6 +373,22 @@ std::string V8Helpers::GetJSValueTypeName(v8::Local val) return "unknown"; } +void V8Helpers::SetObjectClass(v8::Isolate* isolate, v8::Local obj, V8Class::ObjectClass cls) +{ + obj->SetInternalField( + static_cast(V8Class::InternalFields::OBJECT_CLASS), v8::External::New(isolate, reinterpret_cast(cls)) + ); +} + +V8Class::ObjectClass V8Helpers::GetObjectClass(v8::Local obj) +{ + if(obj->InternalFieldCount() <= static_cast(V8Class::InternalFields::OBJECT_CLASS)) + return V8Class::ObjectClass::NONE; + + void* cls = obj->GetInternalField(static_cast(V8Class::InternalFields::OBJECT_CLASS)).As()->Value(); + return *reinterpret_cast(&cls); +} + v8::MaybeLocal V8Helpers::CallFunctionWithTimeout(v8::Local fn, v8::Local ctx, std::vector>& args, uint32_t timeout) { v8::Isolate* isolate = ctx->GetIsolate(); diff --git a/shared/V8Helpers.h b/shared/V8Helpers.h index 4c835c62..78f24c31 100644 --- a/shared/V8Helpers.h +++ b/shared/V8Helpers.h @@ -174,6 +174,9 @@ namespace V8Helpers std::string Stringify(v8::Local ctx, v8::Local val); std::string GetJSValueTypeName(v8::Local val); + void SetObjectClass(v8::Isolate* isolate, v8::Local obj, V8Class::ObjectClass cls); + V8Class::ObjectClass GetObjectClass(v8::Local obj); + inline std::string GetStackTrace(const std::string errorMsg) { auto isolate = v8::Isolate::GetCurrent(); diff --git a/shared/V8ResourceImpl.cpp b/shared/V8ResourceImpl.cpp index 0ac0851a..7136a70e 100644 --- a/shared/V8ResourceImpl.cpp +++ b/shared/V8ResourceImpl.cpp @@ -218,40 +218,40 @@ v8::Local V8ResourceImpl::CreateRGBA(alt::RGBA rgba) return V8Helpers::New(isolate, GetContext(), rgbaClass.Get(isolate), args); } -bool V8ResourceImpl::IsVector3(v8::Local val) -{ - bool result = false; - val->InstanceOf(GetContext(), vector3Class.Get(isolate)).To(&result); - return result; -} - -bool V8ResourceImpl::IsVector2(v8::Local val) -{ - bool result = false; - val->InstanceOf(GetContext(), vector2Class.Get(isolate)).To(&result); - return result; -} - -bool V8ResourceImpl::IsQuaternion(v8::Local val) -{ - bool result = false; - val->InstanceOf(GetContext(), quaternionClass.Get(isolate)).To(&result); - return result; -} - -bool V8ResourceImpl::IsRGBA(v8::Local val) -{ - bool result = false; - val->InstanceOf(GetContext(), rgbaClass.Get(isolate)).To(&result); - return result; -} - -bool V8ResourceImpl::IsBaseObject(v8::Local val) -{ - bool result = false; - val->InstanceOf(GetContext(), baseObjectClass.Get(isolate)).To(&result); - return result; -} +//bool V8ResourceImpl::IsVector3(v8::Local val) +//{ +// bool result = false; +// val->InstanceOf(GetContext(), vector3Class.Get(isolate)).To(&result); +// return result; +//} +// +//bool V8ResourceImpl::IsVector2(v8::Local val) +//{ +// bool result = false; +// val->InstanceOf(GetContext(), vector2Class.Get(isolate)).To(&result); +// return result; +//} +// +//bool V8ResourceImpl::IsQuaternion(v8::Local val) +//{ +// bool result = false; +// val->InstanceOf(GetContext(), quaternionClass.Get(isolate)).To(&result); +// return result; +//} +// +//bool V8ResourceImpl::IsRGBA(v8::Local val) +//{ +// bool result = false; +// val->InstanceOf(GetContext(), rgbaClass.Get(isolate)).To(&result); +// return result; +//} +// +//bool V8ResourceImpl::IsBaseObject(v8::Local val) +//{ +// bool result = false; +// val->InstanceOf(GetContext(), baseObjectClass.Get(isolate)).To(&result); +// return result; +//} void V8ResourceImpl::OnCreateBaseObject(alt::IBaseObject* handle) { @@ -285,7 +285,7 @@ void V8ResourceImpl::OnRemoveBaseObject(alt::IBaseObject* handle) } entities.erase(handle); - ent->GetJSVal(isolate)->SetInternalField(0, v8::External::New(isolate, nullptr)); + ent->GetJSVal(isolate)->SetInternalField(static_cast(V8Class::InternalFields::BASE_OBJECT), v8::External::New(isolate, nullptr)); delete ent; } @@ -538,7 +538,8 @@ v8::Local V8ResourceImpl::GetOrCreateResourceObject(alt::IResource* if(resourceObjects.count(resource) != 0) return resourceObjects.at(resource).Get(isolate); // Create instance v8::Local obj = v8Resource.CreateInstance(GetContext()); - obj->SetInternalField(0, v8::External::New(isolate, resource)); + V8Helpers::SetObjectClass(isolate, obj, V8Class::ObjectClass::RESOURCE); + obj->SetInternalField(static_cast(V8Class::InternalFields::RESOURCE), v8::External::New(isolate, resource)); resourceObjects.insert({ resource, V8Helpers::CPersistent(isolate, obj) }); return obj; } @@ -547,7 +548,7 @@ void V8ResourceImpl::DeleteResourceObject(alt::IResource* resource) { if(resourceObjects.count(resource) == 0) return; v8::Local obj = resourceObjects.at(resource).Get(isolate); - obj->SetInternalField(0, v8::External::New(isolate, nullptr)); + obj->SetInternalField(static_cast(V8Class::InternalFields::RESOURCE), v8::External::New(isolate, nullptr)); resourceObjects.erase(resource); } diff --git a/shared/V8ResourceImpl.h b/shared/V8ResourceImpl.h index 01f1c6e2..d921c2f9 100644 --- a/shared/V8ResourceImpl.h +++ b/shared/V8ResourceImpl.h @@ -189,11 +189,11 @@ class V8ResourceImpl : public alt::IResource::Impl v8::Local CreateQuaternion(alt::Quaternion quat); v8::Local CreateRGBA(alt::RGBA rgba); - bool IsVector3(v8::Local val); + /*bool IsVector3(v8::Local val); bool IsVector2(v8::Local val); bool IsQuaternion(v8::Local val); bool IsRGBA(v8::Local val); - bool IsBaseObject(v8::Local val); + bool IsBaseObject(v8::Local val);*/ void OnCreateBaseObject(alt::IBaseObject* handle) override; void OnRemoveBaseObject(alt::IBaseObject* handle) override; diff --git a/shared/bindings/BaseObject.cpp b/shared/bindings/BaseObject.cpp index a3ffa5ac..ad7fbb8e 100644 --- a/shared/bindings/BaseObject.cpp +++ b/shared/bindings/BaseObject.cpp @@ -224,7 +224,7 @@ extern V8Class v8BaseObject("BaseObject", { v8::Isolate* isolate = v8::Isolate::GetCurrent(); - tpl->InstanceTemplate()->SetInternalFieldCount(1); + tpl->InstanceTemplate()->SetInternalFieldCount(static_cast(V8Class::InternalFields::COUNT)); V8Helpers::SetStaticMethod(isolate, tpl, "getByID", StaticGetById); diff --git a/shared/bindings/Blip.cpp b/shared/bindings/Blip.cpp index 7c3f711b..d1fa896d 100644 --- a/shared/bindings/Blip.cpp +++ b/shared/bindings/Blip.cpp @@ -114,13 +114,17 @@ static void ConstructorPointBlip(const v8::FunctionCallbackInfo& info else if(info.Length() == 2) { - if(resource->IsVector3(info[0])) + V8Class::ObjectClass cls = V8Class::ObjectClass::NONE; + if(info[0]->IsObject()) + cls = V8Helpers::GetObjectClass(info[0].As()); + + if(cls == V8Class::ObjectClass::VECTOR3) // TODO: we should allow IVector3 { V8_ARG_TO_VECTOR3(1, pos); V8_ARG_TO_BOOLEAN(2, global); blip = ICore::Instance().CreateBlip(global, alt::IBlip::BlipType::DESTINATION, pos); } - else if(resource->IsBaseObject(info[0])) + else if(cls == V8Class::ObjectClass::BASE_OBJECT) { V8_ARG_TO_BASE_OBJECT(1, ent, IEntity, "entity"); V8_ARG_TO_BOOLEAN(2, global); diff --git a/shared/bindings/Quaternion.cpp b/shared/bindings/Quaternion.cpp index 848337e8..7b9e5eba 100644 --- a/shared/bindings/Quaternion.cpp +++ b/shared/bindings/Quaternion.cpp @@ -12,6 +12,7 @@ static void Constructor(const v8::FunctionCallbackInfo& info) V8_CHECK_ARGS_LEN2(1, 4); v8::Local _this = info.This(); + V8Helpers::SetObjectClass(isolate, _this, V8Class::ObjectClass::QUATERNION); v8::Local x, y, z, w; @@ -84,7 +85,5 @@ extern V8Class v8Quaternion("Quaternion", Constructor, [](v8::Local tpl) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); // !! Needs to be set so V8 knows its a custom class !! + tpl->InstanceTemplate()->SetInternalFieldCount(static_cast(V8Class::InternalFields::COUNT)); }); diff --git a/shared/bindings/RGBA.cpp b/shared/bindings/RGBA.cpp index 9a838214..e6be1b35 100644 --- a/shared/bindings/RGBA.cpp +++ b/shared/bindings/RGBA.cpp @@ -9,6 +9,7 @@ static void Constructor(const v8::FunctionCallbackInfo& info) V8_CHECK_ARGS_LEN_MIN_MAX(1, 4); + V8Helpers::SetObjectClass(isolate, info.This(), V8Class::ObjectClass::QUATERNION); int32_t r = 0, g = 0, b = 0, a = 255; if(info.Length() == 1) @@ -70,7 +71,5 @@ extern V8Class v8RGBA("RGBA", &Constructor, [](v8::Local tpl) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); // !! Needs to be set so V8 knows its a custom class !! + tpl->InstanceTemplate()->SetInternalFieldCount(static_cast(V8Class::InternalFields::COUNT)); }); diff --git a/shared/bindings/Resource.cpp b/shared/bindings/Resource.cpp index d5ccb8f3..3837f1f1 100644 --- a/shared/bindings/Resource.cpp +++ b/shared/bindings/Resource.cpp @@ -7,7 +7,7 @@ extern V8Class v8Resource; static void IsStartedGetter(v8::Local, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); V8_RETURN(resource->IsStarted()); } @@ -15,7 +15,7 @@ static void IsStartedGetter(v8::Local, const v8::PropertyCallbackInf static void TypeGetter(v8::Local, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); V8_RETURN_STRING(resource->GetType()); } @@ -23,7 +23,7 @@ static void TypeGetter(v8::Local, const v8::PropertyCallbackInfo, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); V8_RETURN_STRING(resource->GetName()); } @@ -31,7 +31,7 @@ static void NameGetter(v8::Local, const v8::PropertyCallbackInfo, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); V8_RETURN_STRING(resource->GetMain()); } @@ -39,7 +39,7 @@ static void MainGetter(v8::Local, const v8::PropertyCallbackInfo, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); V8_RETURN(V8Helpers::MValueToV8(resource->GetExports())); } @@ -47,7 +47,7 @@ static void ExportsGetter(v8::Local, const v8::PropertyCallbackInfo< static void DependenciesGetter(v8::Local, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); const std::vector deps = resource->GetDependencies(); @@ -62,7 +62,7 @@ static void DependenciesGetter(v8::Local, const v8::PropertyCallback static void DependantsGetter(v8::Local, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); const std::vector deps = resource->GetDependants(); @@ -77,7 +77,7 @@ static void DependantsGetter(v8::Local, const v8::PropertyCallbackIn static void RequiredPermissionsGetter(v8::Local, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); const std::vector perms = resource->GetRequiredPermissions(); @@ -92,7 +92,7 @@ static void RequiredPermissionsGetter(v8::Local, const v8::PropertyC static void OptionalPermissionsGetter(v8::Local, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); const std::vector perms = resource->GetOptionalPermissions(); @@ -107,7 +107,7 @@ static void OptionalPermissionsGetter(v8::Local, const v8::PropertyC static void ValidGetter(v8::Local, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_RETURN_BOOLEAN(resource != nullptr); } @@ -115,7 +115,7 @@ static void ValidGetter(v8::Local, const v8::PropertyCallbackInfo, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); V8_RETURN_STRING(resource->GetPath()); } @@ -124,7 +124,7 @@ static void PathGetter(v8::Local, const v8::PropertyCallbackInfo, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); auto config = resource->GetConfig(); @@ -174,7 +174,7 @@ extern V8Class v8Resource("Resource", { v8::Isolate* isolate = v8::Isolate::GetCurrent(); - tpl->InstanceTemplate()->SetInternalFieldCount(2); // Set it to 2, so that our check for V8 entities works (as this isn't a base object) + tpl->InstanceTemplate()->SetInternalFieldCount(static_cast(V8Class::InternalFields::COUNT)); V8Helpers::SetAccessor(isolate, tpl, "isStarted", &IsStartedGetter); V8Helpers::SetAccessor(isolate, tpl, "type", &TypeGetter); diff --git a/shared/bindings/Vector2.cpp b/shared/bindings/Vector2.cpp index 40925ee8..4ca5095f 100644 --- a/shared/bindings/Vector2.cpp +++ b/shared/bindings/Vector2.cpp @@ -504,6 +504,7 @@ static void Constructor(const v8::FunctionCallbackInfo& info) V8_CHECK_ARGS_LEN2(1, 2); v8::Local _this = info.This(); + V8Helpers::SetObjectClass(isolate, _this, V8Class::ObjectClass::VECTOR2); v8::Local x, y; @@ -560,7 +561,5 @@ extern V8Class v8Vector2("Vector2", Constructor, [](v8::Local tpl) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); // !! Needs to be set so V8 knows its a custom class !! + tpl->InstanceTemplate()->SetInternalFieldCount(static_cast(V8Class::InternalFields::COUNT)); }); diff --git a/shared/bindings/Vector3.cpp b/shared/bindings/Vector3.cpp index 8df6c17b..dffb8a03 100644 --- a/shared/bindings/Vector3.cpp +++ b/shared/bindings/Vector3.cpp @@ -85,6 +85,7 @@ static void Constructor(const v8::FunctionCallbackInfo& info) V8_CHECK_ARGS_LEN2(1, 3); v8::Local _this = info.This(); + V8Helpers::SetObjectClass(isolate, _this, V8Class::ObjectClass::VECTOR3); v8::Local x, y, z; @@ -149,7 +150,5 @@ extern V8Class v8Vector3("Vector3", Constructor, [](v8::Local tpl) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); // !! Needs to be set so V8 knows its a custom class !! + tpl->InstanceTemplate()->SetInternalFieldCount(static_cast(V8Class::InternalFields::COUNT)); }); diff --git a/shared/deps/cpp-sdk b/shared/deps/cpp-sdk index 5f49d656..7fe1c8af 160000 --- a/shared/deps/cpp-sdk +++ b/shared/deps/cpp-sdk @@ -1 +1 @@ -Subproject commit 5f49d6564312e8f6f07e5f509f95ba73799cbf6d +Subproject commit 7fe1c8af77fd916a4a3174e947dc0b121022e39e diff --git a/shared/helpers/Serialization.cpp b/shared/helpers/Serialization.cpp index dabce201..6858bf13 100644 --- a/shared/helpers/Serialization.cpp +++ b/shared/helpers/Serialization.cpp @@ -2,10 +2,11 @@ #include "V8ResourceImpl.h" #include "Bindings.h" #include "CProfiler.h" +#include "V8Helpers.h" alt::MValue V8Helpers::V8ToMValue(v8::Local val, bool allowFunction) { - CProfiler::Sample _("V8Helpers::V8ToMValue", true); + // CProfiler::Sample _("V8Helpers::V8ToMValue", true); alt::ICore& core = alt::ICore::Instance(); v8::Isolate* isolate = v8::Isolate::GetCurrent(); @@ -100,10 +101,11 @@ alt::MValue V8Helpers::V8ToMValue(v8::Local val, bool allowFunction) else { V8ResourceImpl* resource = V8ResourceImpl::Get(ctx); - v8::Local v8Obj = val.As(); + auto v8Obj = val.As(); + auto cls = V8Helpers::GetObjectClass(v8Obj); - // if (v8Obj->InstanceOf(ctx, v8Vector3->JSValue(isolate, ctx)).ToChecked()) - if(resource->IsVector3(v8Obj)) + //// if (v8Obj->InstanceOf(ctx, v8Vector3->JSValue(isolate, ctx)).ToChecked()) + if(cls == V8Class::ObjectClass::VECTOR3) { v8::Local x, y, z; V8_CHECK_RETN(v8Obj->Get(ctx, resource->XKey()).ToLocal(&x), "Failed to convert Vector3 to MValue", core.CreateMValueNil()); @@ -112,7 +114,7 @@ alt::MValue V8Helpers::V8ToMValue(v8::Local val, bool allowFunction) return core.CreateMValueVector3(alt::Vector3f{ x.As()->Value(), y.As()->Value(), z.As()->Value() }); } - else if(resource->IsVector2(v8Obj)) + if(cls == V8Class::ObjectClass::VECTOR2) { v8::Local x, y; V8_CHECK_RETN(v8Obj->Get(ctx, resource->XKey()).ToLocal(&x), "Failed to convert Vector2 to MValue", core.CreateMValueNil()); @@ -120,7 +122,7 @@ alt::MValue V8Helpers::V8ToMValue(v8::Local val, bool allowFunction) return core.CreateMValueVector2(alt::Vector2f{ x.As()->Value(), y.As()->Value() }); } - else if(resource->IsRGBA(v8Obj)) + else if(cls == V8Class::ObjectClass::RGBA) { v8::Local r, g, b, a; V8_CHECK_RETN(v8Obj->Get(ctx, resource->RKey()).ToLocal(&r), "Failed to convert RGBA to MValue", core.CreateMValueNil()); @@ -131,7 +133,7 @@ alt::MValue V8Helpers::V8ToMValue(v8::Local val, bool allowFunction) return core.CreateMValueRGBA( alt::RGBA{ (uint8_t)r.As()->Value(), (uint8_t)g.As()->Value(), (uint8_t)b.As()->Value(), (uint8_t)a.As()->Value() }); } - else if(resource->IsBaseObject(v8Obj)) + else if(cls == V8Class::ObjectClass::BASE_OBJECT) { V8Entity* ent = V8Entity::Get(v8Obj); @@ -152,7 +154,7 @@ alt::MValue V8Helpers::V8ToMValue(v8::Local val, bool allowFunction) V8_CHECK_RETN(v8Obj->Get(ctx, v8Key).ToLocal(&value), "Failed to convert object to MValue", core.CreateMValueNil()); if(value->IsUndefined()) continue; - std::string key = *v8::String::Utf8Value(isolate, v8Key); + auto key = *v8::String::Utf8Value(isolate, v8Key); dict->Set(key, V8ToMValue(value, allowFunction)); } @@ -177,10 +179,10 @@ v8::Local V8Helpers::MValueToV8(alt::MValueConst val) { case alt::IMValue::Type::NONE: return v8::Undefined(isolate); case alt::IMValue::Type::NIL: return V8Helpers::JSValue(nullptr); - case alt::IMValue::Type::BOOL: return V8Helpers::JSValue(std::dynamic_pointer_cast(val)->Value()); + case alt::IMValue::Type::BOOL: return V8Helpers::JSValue(std::static_pointer_cast(val)->Value()); case alt::IMValue::Type::INT: { - int64_t _val = std::dynamic_pointer_cast(val)->Value(); + int64_t _val = std::static_pointer_cast(val)->Value(); if(_val >= JS_MIN_SAFE_INTEGER && _val <= JS_MAX_SAFE_INTEGER) return V8Helpers::JSValue((double)_val); @@ -188,17 +190,17 @@ v8::Local V8Helpers::MValueToV8(alt::MValueConst val) } case alt::IMValue::Type::UINT: { - uint64_t _val = std::dynamic_pointer_cast(val)->Value(); + uint64_t _val = std::static_pointer_cast(val)->Value(); if(_val <= JS_MAX_SAFE_INTEGER) return V8Helpers::JSValue((double)_val); return V8Helpers::JSValue(_val); } - case alt::IMValue::Type::DOUBLE: return V8Helpers::JSValue(std::dynamic_pointer_cast(val)->Value()); - case alt::IMValue::Type::STRING: return V8Helpers::JSValue(std::dynamic_pointer_cast(val)->Value()); + case alt::IMValue::Type::DOUBLE: return V8Helpers::JSValue(std::static_pointer_cast(val)->Value()); + case alt::IMValue::Type::STRING: return V8Helpers::JSValue(std::static_pointer_cast(val)->Value()); case alt::IMValue::Type::LIST: { - alt::MValueListConst list = std::dynamic_pointer_cast(val); + alt::MValueListConst list = std::static_pointer_cast(val); v8::Local v8Arr = v8::Array::New(isolate, (int)list->GetSize()); for(uint32_t i = 0; i < list->GetSize(); ++i) v8Arr->Set(ctx, i, MValueToV8(list->Get(i))); @@ -207,7 +209,7 @@ v8::Local V8Helpers::MValueToV8(alt::MValueConst val) } case alt::IMValue::Type::DICT: { - alt::MValueDictConst dict = std::dynamic_pointer_cast(val); + alt::MValueDictConst dict = std::static_pointer_cast(val); v8::Local v8Obj = v8::Object::New(isolate); for(auto it = dict->Begin(); it != dict->End(); ++it) @@ -219,24 +221,24 @@ v8::Local V8Helpers::MValueToV8(alt::MValueConst val) } case alt::IMValue::Type::BASE_OBJECT: { - alt::IBaseObject* ref = std::dynamic_pointer_cast(val)->RawValue(); + alt::IBaseObject* ref = std::static_pointer_cast(val)->RawValue(); return V8ResourceImpl::Get(ctx)->GetBaseObjectOrNull(ref); } case alt::IMValue::Type::FUNCTION: { - alt::MValueFunctionConst fn = std::dynamic_pointer_cast(val); + alt::MValueFunctionConst fn = std::static_pointer_cast(val); v8::Local extFn = v8::External::New(isolate, new alt::MValueFunctionConst(fn)); v8::Local func; V8_CHECK_RETN(v8::Function::New(ctx, V8Helpers::FunctionCallback, extFn).ToLocal(&func), "Failed to convert MValue to function", v8::Undefined(isolate)); return func; } - case alt::IMValue::Type::VECTOR3: return V8ResourceImpl::Get(ctx)->CreateVector3(std::dynamic_pointer_cast(val)->Value()); - case alt::IMValue::Type::VECTOR2: return V8ResourceImpl::Get(ctx)->CreateVector2(std::dynamic_pointer_cast(val)->Value()); - case alt::IMValue::Type::RGBA: return V8ResourceImpl::Get(ctx)->CreateRGBA(std::dynamic_pointer_cast(val)->Value()); + case alt::IMValue::Type::VECTOR3: return V8ResourceImpl::Get(ctx)->CreateVector3(std::static_pointer_cast(val)->Value()); + case alt::IMValue::Type::VECTOR2: return V8ResourceImpl::Get(ctx)->CreateVector2(std::static_pointer_cast(val)->Value()); + case alt::IMValue::Type::RGBA: return V8ResourceImpl::Get(ctx)->CreateRGBA(std::static_pointer_cast(val)->Value()); case alt::IMValue::Type::BYTE_ARRAY: { - alt::MValueByteArrayConst buffer = std::dynamic_pointer_cast(val); + alt::MValueByteArrayConst buffer = std::static_pointer_cast(val); // Check if the buffer is a raw JS value buffer v8::MaybeLocal jsVal = RawBytesToV8(buffer); if(!jsVal.IsEmpty()) return jsVal.ToLocalChecked(); @@ -283,11 +285,18 @@ static inline RawValueType GetValueType(v8::Local ctx, v8::LocalIsVector3(val)) return RawValueType::VECTOR3; - if(resource->IsVector2(val)) return RawValueType::VECTOR2; - if(resource->IsRGBA(val)) return RawValueType::RGBA; - else - return RawValueType::GENERIC; + + if(val->IsObject()) + { + switch(V8Helpers::GetObjectClass(val.As())) + { + case V8Class::ObjectClass::VECTOR3: return RawValueType::VECTOR3; + case V8Class::ObjectClass::VECTOR2: return RawValueType::VECTOR2; + case V8Class::ObjectClass::RGBA: return RawValueType::RGBA; + } + } + + return RawValueType::GENERIC; } static inline bool WriteRawValue(v8::Local ctx, v8::ValueSerializer& serializer, RawValueType type, v8::Local val) From d6e5b97021b90dcef636667e7770c0b7aa9ad15f Mon Sep 17 00:00:00 2001 From: Vadim Zubkov Date: Mon, 18 Mar 2024 15:15:30 +0300 Subject: [PATCH 03/14] chore: fix build --- shared/V8Entity.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/V8Entity.h b/shared/V8Entity.h index 4affadc6..f8c7fe29 100644 --- a/shared/V8Entity.h +++ b/shared/V8Entity.h @@ -16,7 +16,7 @@ class V8Entity V8Entity(v8::Local ctx, V8Class* __class, v8::Local obj, alt::IBaseObject* _handle) : _class(__class), handle(_handle) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); - V8Helpers::SetObjectClass(isolate, obj, V8Class::ObjectClass::BASE_OBJECT); + obj->SetInternalField(static_cast(V8Class::InternalFields::OBJECT_CLASS), v8::External::New(isolate, reinterpret_cast(V8Class::ObjectClass::BASE_OBJECT))); obj->SetInternalField(static_cast(V8Class::InternalFields::BASE_OBJECT), v8::External::New(isolate, this)); jsVal.Reset(isolate, obj); } From e445b99150a170c106e6d89202eb2640bdab0036 Mon Sep 17 00:00:00 2001 From: Vadim Zubkov Date: Mon, 18 Mar 2024 19:44:53 +0300 Subject: [PATCH 04/14] fix(client): mvalue casts --- client/src/CV8Resource.cpp | 2 +- client/src/bindings/Audio.cpp | 4 ++-- client/src/bindings/FocusData.cpp | 9 +++++++-- client/src/bindings/HttpClient.cpp | 20 ++++++++++---------- client/src/bindings/WebSocketClient.cpp | 3 +-- client/src/bindings/WebView.cpp | 4 ++-- 6 files changed, 23 insertions(+), 19 deletions(-) diff --git a/client/src/CV8Resource.cpp b/client/src/CV8Resource.cpp index 94a72011..7c80142e 100644 --- a/client/src/CV8Resource.cpp +++ b/client/src/CV8Resource.cpp @@ -62,7 +62,7 @@ void StartFile(const v8::FunctionCallbackInfo& info) V8_CHECK(!maybeMod.IsEmpty(), "Failed to start file"); auto mod = maybeMod.ToLocalChecked(); static_cast(resource)->InstantiateModule(mod); - const alt::MValueDict& exports = std::dynamic_pointer_cast( + const alt::MValueDict& exports = std::static_pointer_cast( V8Helpers::V8ToMValue(mod->GetModuleNamespace())); resource->GetResource()->SetExports(exports); } diff --git a/client/src/bindings/Audio.cpp b/client/src/bindings/Audio.cpp index e7df7cd0..ea29b65d 100644 --- a/client/src/bindings/Audio.cpp +++ b/client/src/bindings/Audio.cpp @@ -101,11 +101,11 @@ static void GetOutputs(const v8::FunctionCallbackInfo& info) auto val = list->Get(i); if(val->GetType() == alt::IMValue::Type::BASE_OBJECT) { - auto baseObj = resource->GetBaseObjectOrNull(std::dynamic_pointer_cast(val)->RawValue()); + auto baseObj = resource->GetBaseObjectOrNull(std::static_pointer_cast(val)->RawValue()); arr->Set(ctx, i, baseObj); } else if(val->GetType() == alt::IMValue::Type::UINT) - arr->Set(ctx, i, v8::Integer::NewFromUnsigned(isolate, std::dynamic_pointer_cast(val)->Value())); + arr->Set(ctx, i, v8::Integer::NewFromUnsigned(isolate, std::static_pointer_cast(val)->Value())); } V8_RETURN(arr); diff --git a/client/src/bindings/FocusData.cpp b/client/src/bindings/FocusData.cpp index ec87abfe..a924db5d 100644 --- a/client/src/bindings/FocusData.cpp +++ b/client/src/bindings/FocusData.cpp @@ -31,7 +31,12 @@ static void OverrideFocus(const v8::FunctionCallbackInfo& info) V8_GET_ISOLATE_CONTEXT_RESOURCE(); V8_CHECK_ARGS_LEN2(1, 2); - if(resource->IsVector3(info[0])) + + auto cls = V8Class::ObjectClass::NONE; + if(info[0]->IsObject()) + V8Helpers::GetObjectClass(info[0].As()); + + if(cls == V8Class::ObjectClass::VECTOR3) { V8_ARG_TO_VECTOR3(1, pos); alt::Vector3f offset = { 0, 0, 0 }; @@ -42,7 +47,7 @@ static void OverrideFocus(const v8::FunctionCallbackInfo& info) } alt::ICore::Instance().OverrideFocusPosition(pos, offset); } - else if(resource->IsBaseObject(info[0])) + else if(cls == V8Class::ObjectClass::BASE_OBJECT) { V8_ARG_TO_BASE_OBJECT(1, entity, alt::IEntity, "Entity"); alt::ICore::Instance().OverrideFocusEntity(entity); diff --git a/client/src/bindings/HttpClient.cpp b/client/src/bindings/HttpClient.cpp index d95a9528..0f621916 100644 --- a/client/src/bindings/HttpClient.cpp +++ b/client/src/bindings/HttpClient.cpp @@ -25,7 +25,7 @@ static void GetExtraHeaders(const v8::FunctionCallbackInfo& info) V8_NEW_OBJECT(headers); for(auto it = dict->Begin(); it != dict->End(); ++it) { - headers->Set(ctx, V8Helpers::JSValue(it->first.c_str()), V8Helpers::JSValue(std::dynamic_pointer_cast(it->second)->Value().c_str())); + headers->Set(ctx, V8Helpers::JSValue(it->first), V8Helpers::JSValue(std::static_pointer_cast(it->second)->Value().c_str())); } V8_RETURN(headers); @@ -71,7 +71,7 @@ static void Get(const v8::FunctionCallbackInfo& info) V8_NEW_OBJECT(headers); for(auto it = response.headers->Begin(); it != response.headers->End(); ++it) { - headers->Set(ctx, V8Helpers::JSValue(it->first.c_str()), V8Helpers::JSValue(std::dynamic_pointer_cast(it->second)->Value().c_str())); + headers->Set(ctx, V8Helpers::JSValue(it->first), V8Helpers::JSValue(std::static_pointer_cast(it->second)->Value().c_str())); } responseObj->Set(ctx, V8Helpers::JSValue("headers"), headers); resolver->Resolve(resolver->GetCreationContext().ToLocalChecked(), responseObj); @@ -114,7 +114,7 @@ static void Head(const v8::FunctionCallbackInfo& info) V8_NEW_OBJECT(headers); for(auto it = response.headers->Begin(); it != response.headers->End(); ++it) { - headers->Set(ctx, V8Helpers::JSValue(it->first.c_str()), V8Helpers::JSValue(std::dynamic_pointer_cast(it->second)->Value().c_str())); + headers->Set(ctx, V8Helpers::JSValue(it->first), V8Helpers::JSValue(std::static_pointer_cast(it->second)->Value().c_str())); } responseObj->Set(ctx, V8Helpers::JSValue("headers"), headers); resolver->Resolve(resolver->GetCreationContext().ToLocalChecked(), responseObj); @@ -158,7 +158,7 @@ static void Post(const v8::FunctionCallbackInfo& info) V8_NEW_OBJECT(headers); for(auto it = response.headers->Begin(); it != response.headers->End(); ++it) { - headers->Set(ctx, V8Helpers::JSValue(it->first.c_str()), V8Helpers::JSValue(std::dynamic_pointer_cast(it->second)->Value().c_str())); + headers->Set(ctx, V8Helpers::JSValue(it->first), V8Helpers::JSValue(std::static_pointer_cast(it->second)->Value().c_str())); } responseObj->Set(ctx, V8Helpers::JSValue("headers"), headers); resolver->Resolve(resolver->GetCreationContext().ToLocalChecked(), responseObj); @@ -202,7 +202,7 @@ static void Put(const v8::FunctionCallbackInfo& info) V8_NEW_OBJECT(headers); for(auto it = response.headers->Begin(); it != response.headers->End(); ++it) { - headers->Set(ctx, V8Helpers::JSValue(it->first.c_str()), V8Helpers::JSValue(std::dynamic_pointer_cast(it->second)->Value().c_str())); + headers->Set(ctx, V8Helpers::JSValue(it->first), V8Helpers::JSValue(std::static_pointer_cast(it->second)->Value().c_str())); } responseObj->Set(ctx, V8Helpers::JSValue("headers"), headers); resolver->Resolve(resolver->GetCreationContext().ToLocalChecked(), responseObj); @@ -246,7 +246,7 @@ static void Delete(const v8::FunctionCallbackInfo& info) V8_NEW_OBJECT(headers); for(auto it = response.headers->Begin(); it != response.headers->End(); ++it) { - headers->Set(ctx, V8Helpers::JSValue(it->first.c_str()), V8Helpers::JSValue(std::dynamic_pointer_cast(it->second)->Value().c_str())); + headers->Set(ctx, V8Helpers::JSValue(it->first), V8Helpers::JSValue(std::static_pointer_cast(it->second)->Value().c_str())); } responseObj->Set(ctx, V8Helpers::JSValue("headers"), headers); resolver->Resolve(resolver->GetCreationContext().ToLocalChecked(), responseObj); @@ -290,7 +290,7 @@ static void Connect(const v8::FunctionCallbackInfo& info) V8_NEW_OBJECT(headers); for(auto it = response.headers->Begin(); it != response.headers->End(); ++it) { - headers->Set(ctx, V8Helpers::JSValue(it->first.c_str()), V8Helpers::JSValue(std::dynamic_pointer_cast(it->second)->Value().c_str())); + headers->Set(ctx, V8Helpers::JSValue(it->first), V8Helpers::JSValue(std::static_pointer_cast(it->second)->Value().c_str())); } responseObj->Set(ctx, V8Helpers::JSValue("headers"), headers); resolver->Resolve(resolver->GetCreationContext().ToLocalChecked(), responseObj); @@ -334,7 +334,7 @@ static void Options(const v8::FunctionCallbackInfo& info) V8_NEW_OBJECT(headers); for(auto it = response.headers->Begin(); it != response.headers->End(); ++it) { - headers->Set(ctx, V8Helpers::JSValue(it->first.c_str()), V8Helpers::JSValue(std::dynamic_pointer_cast(it->second)->Value().c_str())); + headers->Set(ctx, V8Helpers::JSValue(it->first), V8Helpers::JSValue(std::static_pointer_cast(it->second)->Value().c_str())); } responseObj->Set(ctx, V8Helpers::JSValue("headers"), headers); resolver->Resolve(resolver->GetCreationContext().ToLocalChecked(), responseObj); @@ -378,7 +378,7 @@ static void Trace(const v8::FunctionCallbackInfo& info) V8_NEW_OBJECT(headers); for(auto it = response.headers->Begin(); it != response.headers->End(); ++it) { - headers->Set(ctx, V8Helpers::JSValue(it->first.c_str()), V8Helpers::JSValue(std::dynamic_pointer_cast(it->second)->Value().c_str())); + headers->Set(ctx, V8Helpers::JSValue(it->first), V8Helpers::JSValue(std::static_pointer_cast(it->second)->Value().c_str())); } responseObj->Set(ctx, V8Helpers::JSValue("headers"), headers); resolver->Resolve(resolver->GetCreationContext().ToLocalChecked(), responseObj); @@ -422,7 +422,7 @@ static void Patch(const v8::FunctionCallbackInfo& info) V8_NEW_OBJECT(headers); for(auto it = response.headers->Begin(); it != response.headers->End(); ++it) { - headers->Set(ctx, V8Helpers::JSValue(it->first.c_str()), V8Helpers::JSValue(std::dynamic_pointer_cast(it->second)->Value().c_str())); + headers->Set(ctx, V8Helpers::JSValue(it->first), V8Helpers::JSValue(std::static_pointer_cast(it->second)->Value().c_str())); } responseObj->Set(ctx, V8Helpers::JSValue("headers"), headers); resolver->Resolve(resolver->GetCreationContext().ToLocalChecked(), responseObj); diff --git a/client/src/bindings/WebSocketClient.cpp b/client/src/bindings/WebSocketClient.cpp index 9ccd2a33..3ff62ea0 100644 --- a/client/src/bindings/WebSocketClient.cpp +++ b/client/src/bindings/WebSocketClient.cpp @@ -133,8 +133,7 @@ static void GetExtraHeaders(const v8::FunctionCallbackInfo& info) for(auto it = extraHeaders->Begin(); it != extraHeaders->End(); ++it) { - std::string key = it->first; - V8_OBJECT_SET_STRING(headersObject, key.c_str(), std::dynamic_pointer_cast(extraHeaders->Get(key))->Value()); + V8_OBJECT_SET_STRING(headersObject, it->first, std::static_pointer_cast(extraHeaders->Get(it->first))->Value()); } V8_RETURN(headersObject); diff --git a/client/src/bindings/WebView.cpp b/client/src/bindings/WebView.cpp index 41152f7a..d59b4744 100644 --- a/client/src/bindings/WebView.cpp +++ b/client/src/bindings/WebView.cpp @@ -303,11 +303,11 @@ static void GetOutputs(const v8::FunctionCallbackInfo& info) auto val = list->Get(i); if (val->GetType() == alt::IMValue::Type::BASE_OBJECT) { - auto baseObj = resource->GetBaseObjectOrNull(std::dynamic_pointer_cast(val)->RawValue()); + auto baseObj = resource->GetBaseObjectOrNull(std::static_pointer_cast(val)->RawValue()); arr->Set(ctx, i, baseObj); } else if (val->GetType() == alt::IMValue::Type::UINT) - arr->Set(ctx, i, v8::Integer::NewFromUnsigned(isolate, std::dynamic_pointer_cast(val)->Value())); + arr->Set(ctx, i, v8::Integer::NewFromUnsigned(isolate, std::static_pointer_cast(val)->Value())); } V8_RETURN(arr); From 48bdc3cd5fa4fda2a2e239d815a98fc732fe1300 Mon Sep 17 00:00:00 2001 From: Vadim Zubkov Date: Mon, 18 Mar 2024 21:42:28 +0300 Subject: [PATCH 05/14] fix: internal field macros --- shared/V8ResourceImpl.cpp | 1 + shared/helpers/Macros.h | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/shared/V8ResourceImpl.cpp b/shared/V8ResourceImpl.cpp index 7136a70e..e5fb5732 100644 --- a/shared/V8ResourceImpl.cpp +++ b/shared/V8ResourceImpl.cpp @@ -539,6 +539,7 @@ v8::Local V8ResourceImpl::GetOrCreateResourceObject(alt::IResource* // Create instance v8::Local obj = v8Resource.CreateInstance(GetContext()); V8Helpers::SetObjectClass(isolate, obj, V8Class::ObjectClass::RESOURCE); + Log::Info << "Create resource " << (void*)resource << Log::Endl; obj->SetInternalField(static_cast(V8Class::InternalFields::RESOURCE), v8::External::New(isolate, resource)); resourceObjects.insert({ resource, V8Helpers::CPersistent(isolate, obj) }); return obj; diff --git a/shared/helpers/Macros.h b/shared/helpers/Macros.h index f21cac6f..44af24ad 100644 --- a/shared/helpers/Macros.h +++ b/shared/helpers/Macros.h @@ -51,19 +51,19 @@ // idx starts with 1 #define V8_GET_THIS_INTERNAL_FIELD_OBJECT(idx, val) \ V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \ - auto val = info.This()->GetInternalField((idx)-1)->ToObject(isolate->GetEnteredOrMicrotaskContext()).ToLocalChecked(); + auto val = info.This()->GetInternalField(idx)->ToObject(isolate->GetEnteredOrMicrotaskContext()).ToLocalChecked(); // idx starts with 1 #define V8_GET_THIS_INTERNAL_FIELD_V8ENTITY(idx, val) \ V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \ - auto val = V8Entity::Get(info.This()->GetInternalField((idx)-1)->ToObject(isolate->GetEnteredOrMicrotaskContext()).ToLocalChecked()); + auto val = V8Entity::Get(info.This()->GetInternalField(idx)->ToObject(isolate->GetEnteredOrMicrotaskContext()).ToLocalChecked()); // idx starts with 1 #define V8_GET_THIS_INTERNAL_FIELD_ENTITY(idx, val, type) \ type* val; \ { \ V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \ - V8Entity* __val = V8Entity::Get(info.This()->GetInternalField((idx)-1)->ToObject(isolate->GetEnteredOrMicrotaskContext()).ToLocalChecked()); \ + V8Entity* __val = V8Entity::Get(info.This()->GetInternalField(idx)->ToObject(isolate->GetEnteredOrMicrotaskContext()).ToLocalChecked()); \ V8_CHECK(__val, "baseobject is invalid"); \ val = dynamic_cast(__val->GetHandle()); \ V8_CHECK(val, "baseobject is not of type " #type); \ @@ -72,27 +72,27 @@ // idx starts with 1 #define V8_GET_THIS_INTERNAL_FIELD_INTEGER(idx, val) \ V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \ - auto val = info.This()->GetInternalField((idx)-1)->IntegerValue(ctx).ToChecked(); + auto val = info.This()->GetInternalField(idx)->IntegerValue(ctx).ToChecked(); // idx starts with 1 #define V8_GET_THIS_INTERNAL_FIELD_UINT32(idx, val) \ V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \ - auto val = info.This()->GetInternalField((idx)-1)->Uint32Value(ctx).ToChecked(); + auto val = info.This()->GetInternalField(idx)->Uint32Value(ctx).ToChecked(); // idx starts with 1 #define V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(idx, val, type) \ V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \ - auto val = static_cast(info.This()->GetInternalField((idx)-1).As()->Value()); + auto val = static_cast(info.This()->GetInternalField(idx).As()->Value()); // idx starts with 1 #define V8_GET_THIS_INTERNAL_FIELD_PTR(idx, val, type) \ V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \ - auto val = static_cast(info.This()->GetAlignedPointerFromInternalField((idx)-1)); + auto val = static_cast(info.This()->GetAlignedPointerFromInternalField(idx)); // idx starts with 1 #define V8_GET_THIS_INTERNAL_FIELD_STRING(idx, val) \ V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \ - auto intVal = info.This()->GetInternalField(0).As(); \ + auto intVal = info.This()->GetInternalField(idx).As(); \ auto val = *v8::String::Utf8Value(isolate, intVal); #define V8_CHECK_CONSTRUCTOR() V8_CHECK(info.IsConstructCall(), "function can't be called without new") From dd67e5ba50d956760c5d72e11d2253c6b4ed6270 Mon Sep 17 00:00:00 2001 From: xLuxy <67131061+xLuxy@users.noreply.github.com> Date: Mon, 18 Mar 2024 20:32:04 +0100 Subject: [PATCH 06/14] chore(shared): Remove left-over debug log --- shared/V8ResourceImpl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shared/V8ResourceImpl.cpp b/shared/V8ResourceImpl.cpp index e5fb5732..56817c11 100644 --- a/shared/V8ResourceImpl.cpp +++ b/shared/V8ResourceImpl.cpp @@ -536,11 +536,12 @@ v8::Local V8ResourceImpl::GetOrCreateResourceObject(alt::IResource* { // If already created return instance if(resourceObjects.count(resource) != 0) return resourceObjects.at(resource).Get(isolate); + // Create instance v8::Local obj = v8Resource.CreateInstance(GetContext()); V8Helpers::SetObjectClass(isolate, obj, V8Class::ObjectClass::RESOURCE); - Log::Info << "Create resource " << (void*)resource << Log::Endl; obj->SetInternalField(static_cast(V8Class::InternalFields::RESOURCE), v8::External::New(isolate, resource)); + resourceObjects.insert({ resource, V8Helpers::CPersistent(isolate, obj) }); return obj; } From ee87748319e7b2494fee0ec34cc1ecb745d85d77 Mon Sep 17 00:00:00 2001 From: Vadim Zubkov Date: Tue, 19 Mar 2024 13:54:11 +0300 Subject: [PATCH 07/14] chore: bump sdk --- shared/deps/cpp-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/deps/cpp-sdk b/shared/deps/cpp-sdk index 7fe1c8af..95a2cfad 160000 --- a/shared/deps/cpp-sdk +++ b/shared/deps/cpp-sdk @@ -1 +1 @@ -Subproject commit 7fe1c8af77fd916a4a3174e947dc0b121022e39e +Subproject commit 95a2cfadc2ba1de018c8c55c72b21984067b6181 From a168b92e36e0c904b7007acf3b146d31906f958a Mon Sep 17 00:00:00 2001 From: Vadim Zubkov Date: Tue, 19 Mar 2024 13:55:51 +0300 Subject: [PATCH 08/14] chore(client): fix build --- client/src/bindings/WebSocketClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/bindings/WebSocketClient.cpp b/client/src/bindings/WebSocketClient.cpp index 3ff62ea0..47f68663 100644 --- a/client/src/bindings/WebSocketClient.cpp +++ b/client/src/bindings/WebSocketClient.cpp @@ -133,7 +133,7 @@ static void GetExtraHeaders(const v8::FunctionCallbackInfo& info) for(auto it = extraHeaders->Begin(); it != extraHeaders->End(); ++it) { - V8_OBJECT_SET_STRING(headersObject, it->first, std::static_pointer_cast(extraHeaders->Get(it->first))->Value()); + V8_OBJECT_SET_STRING(headersObject, it->first.c_str(), std::static_pointer_cast(extraHeaders->Get(it->first))->Value()); } V8_RETURN(headersObject); From ce39d395c5674d458b057d00275f4590aadb056d Mon Sep 17 00:00:00 2001 From: Vadim Zubkov Date: Wed, 20 Mar 2024 00:01:54 +0300 Subject: [PATCH 09/14] fix(client): internal fields --- client/src/bindings/AudioCategory.cpp | 5 +++-- client/src/bindings/Handling.cpp | 5 +++-- client/src/bindings/HandlingData.cpp | 8 +++++--- client/src/bindings/MapZoomData.cpp | 8 +++++--- client/src/bindings/MemoryBuffer.cpp | 12 +++++++----- client/src/bindings/WeaponData.cpp | 6 ++++-- client/src/bindings/Worker.cpp | 8 ++++++-- shared/V8Class.h | 12 +++++++++++- 8 files changed, 44 insertions(+), 20 deletions(-) diff --git a/client/src/bindings/AudioCategory.cpp b/client/src/bindings/AudioCategory.cpp index 757c0f64..1f81f6cf 100644 --- a/client/src/bindings/AudioCategory.cpp +++ b/client/src/bindings/AudioCategory.cpp @@ -18,7 +18,8 @@ static void Constructor(const v8::FunctionCallbackInfo& info) auto audioCategory = alt::ICore::Instance().GetAudioCategory(audioCategoryStr); V8_CHECK(audioCategory, "Audio category not found"); - info.This()->SetInternalField(0, v8::String::NewFromUtf8(isolate, audioCategoryStr.c_str()).ToLocalChecked()); + V8Helpers::SetObjectClass(info.GetIsolate(), info.This(), V8Class::ObjectClass::AUDIO_CATEGORY); + info.This()->SetInternalField(1, v8::String::NewFromUtf8(isolate, audioCategoryStr.c_str()).ToLocalChecked()); } // Getters @@ -356,7 +357,7 @@ extern V8Class v8AudioCategory("AudioCategory", [](v8::Local tpl) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); - tpl->InstanceTemplate()->SetInternalFieldCount(1); + tpl->InstanceTemplate()->SetInternalFieldCount(static_cast(V8Class::InternalFields::COUNT)); V8Helpers::SetStaticMethod(isolate, tpl, "getForName", &GetForName); diff --git a/client/src/bindings/Handling.cpp b/client/src/bindings/Handling.cpp index 01719cac..ce119d60 100644 --- a/client/src/bindings/Handling.cpp +++ b/client/src/bindings/Handling.cpp @@ -13,7 +13,8 @@ static void Constructor(const v8::FunctionCallbackInfo& info) V8_CHECK_ARGS_LEN(1); V8_ARG_TO_OBJECT(1, vehicle); - info.This()->SetInternalField(0, vehicle); + V8Helpers::SetObjectClass(info.GetIsolate(), info.This(), V8Class::ObjectClass::HANDLING); + info.This()->SetInternalField(1, vehicle); } static void IsModified(const v8::FunctionCallbackInfo& info) @@ -1213,7 +1214,7 @@ extern V8Class v8Handling("Handling", Constructor, [](v8::Local proto = tpl->PrototypeTemplate(); - tpl->InstanceTemplate()->SetInternalFieldCount(1); + tpl->InstanceTemplate()->SetInternalFieldCount(static_cast(V8Class::InternalFields::COUNT)); V8Helpers::SetMethod(isolate, tpl, "isModified", &IsModified); V8Helpers::SetMethod(isolate, tpl, "reset", &Reset); diff --git a/client/src/bindings/HandlingData.cpp b/client/src/bindings/HandlingData.cpp index f219ca58..71e264a2 100644 --- a/client/src/bindings/HandlingData.cpp +++ b/client/src/bindings/HandlingData.cpp @@ -13,7 +13,9 @@ static void Constructor(const v8::FunctionCallbackInfo& info) auto handling = alt::ICore::Instance().GetHandlingData(modelHash); V8_CHECK(handling, "model doesn't exist"); - info.This()->SetInternalField(0, info[0]); + + V8Helpers::SetObjectClass(info.GetIsolate(), info.This(), V8Class::ObjectClass::HANDLING_DATA); + info.This()->SetInternalField(1, info[0]); } static void GetForHandlingName(const v8::FunctionCallbackInfo& info) @@ -1731,8 +1733,8 @@ static void DamageFlagsSetter(v8::Local, v8::Local val, c extern V8Class v8HandlingData("HandlingData", Constructor, [](v8::Local tpl) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); + + tpl->InstanceTemplate()->SetInternalFieldCount(static_cast(V8Class::InternalFields::COUNT)); V8Helpers::SetStaticMethod(isolate, tpl, "getForHandlingName", &GetForHandlingName); diff --git a/client/src/bindings/MapZoomData.cpp b/client/src/bindings/MapZoomData.cpp index f3980fc1..3bf1eb2e 100644 --- a/client/src/bindings/MapZoomData.cpp +++ b/client/src/bindings/MapZoomData.cpp @@ -12,13 +12,15 @@ static void Constructor(const v8::FunctionCallbackInfo& info) V8_CHECK(info[0]->IsNumber() || info[0]->IsString(), "zoomDataId must be a number or string"); + + V8Helpers::SetObjectClass(info.GetIsolate(), info.This(), V8Class::ObjectClass::MAP_ZOOM_DATA); if(info[0]->IsNumber()) { V8_ARG_TO_UINT(1, zoomDataId); auto data = alt::ICore::Instance().GetMapData(zoomDataId); V8_CHECK(data, "zoomData with this id not found"); - info.This()->SetInternalField(0, info[0]); + info.This()->SetInternalField(1, info[0]); } else { @@ -28,7 +30,7 @@ static void Constructor(const v8::FunctionCallbackInfo& info) V8_CHECK(data, "zoomData with this id not found"); uint8_t id = alt::ICore::Instance().GetMapDataIDFromAlias(zoomDataAlias); - info.This()->SetInternalField(0, V8Helpers::JSValue(id)); + info.This()->SetInternalField(1, V8Helpers::JSValue(id)); } } @@ -176,7 +178,7 @@ extern V8Class v8MapZoomData("MapZoomData", Constructor, [](v8::Local proto = tpl->PrototypeTemplate(); - tpl->InstanceTemplate()->SetInternalFieldCount(1); + tpl->InstanceTemplate()->SetInternalFieldCount(static_cast(V8Class::InternalFields::COUNT)); V8Helpers::SetStaticMethod(isolate, tpl, "get", &Get); V8Helpers::SetStaticMethod(isolate, tpl, "resetAll", &ResetAll); diff --git a/client/src/bindings/MemoryBuffer.cpp b/client/src/bindings/MemoryBuffer.cpp index 037c995a..a839d2ba 100644 --- a/client/src/bindings/MemoryBuffer.cpp +++ b/client/src/bindings/MemoryBuffer.cpp @@ -21,6 +21,8 @@ static void Constructor(const v8::FunctionCallbackInfo& info) V8_CHECK_CONSTRUCTOR(); V8_CHECK_ARGS_LEN(1); + V8Helpers::SetObjectClass(info.GetIsolate(), info.This(), V8Class::ObjectClass::MEMORY_BUFFER); + // Ask alt:V to add pattern searching to C++ SDK if you want this available // if(info[0]->IsString()) // { @@ -38,16 +40,16 @@ static void Constructor(const v8::FunctionCallbackInfo& info) V8_ARG_TO_UINT(1, size); if(size == 0) { - info.This()->SetAlignedPointerInInternalField(0, nullptr); - info.This()->SetInternalField(1, V8Helpers::JSValue(0)); + info.This()->SetAlignedPointerInInternalField(1, nullptr); + info.This()->SetInternalField(2, V8Helpers::JSValue(0)); return; } V8_CHECK(size <= 1024, "You can't allocate > 1KB"); uint8_t* allocatedMemory = new uint8_t[size]; memset(allocatedMemory, 0, size); - info.This()->SetAlignedPointerInInternalField(0, allocatedMemory); - info.This()->SetInternalField(1, V8Helpers::JSValue(size)); + info.This()->SetAlignedPointerInInternalField(1, allocatedMemory); + info.This()->SetInternalField(2, V8Helpers::JSValue(size)); } /*v8::Global persistent(isolate, info.This()); @@ -170,7 +172,7 @@ static void GetDataOfType(const v8::FunctionCallbackInfo& info) extern V8Class v8MemoryBuffer("MemoryBuffer", Constructor, [](v8::Local tpl) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); - tpl->InstanceTemplate()->SetInternalFieldCount(2); + tpl->InstanceTemplate()->SetInternalFieldCount(3); V8Helpers::SetAccessor(isolate, tpl, "size", SizeGetter); V8Helpers::SetAccessor(isolate, tpl, "address", AddressGetter); diff --git a/client/src/bindings/WeaponData.cpp b/client/src/bindings/WeaponData.cpp index 9c73f7e6..25ef4f6d 100644 --- a/client/src/bindings/WeaponData.cpp +++ b/client/src/bindings/WeaponData.cpp @@ -26,7 +26,8 @@ static void Constructor(const v8::FunctionCallbackInfo& info) auto weaponData = alt::ICore::Instance().GetWeaponData(weaponHash); V8_CHECK(weaponData, "Weapon data not found"); - info.This()->SetInternalField(0, v8::Integer::NewFromUnsigned(isolate, weaponHash)); + V8Helpers::SetObjectClass(info.GetIsolate(), info.This(), V8Class::ObjectClass::WEAPON_DATA); + info.This()->SetInternalField(1, v8::Integer::NewFromUnsigned(isolate, weaponHash)); } // Getters @@ -336,7 +337,8 @@ extern V8Class v8WeaponData("WeaponData", [](v8::Local tpl) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); - tpl->InstanceTemplate()->SetInternalFieldCount(1); + + tpl->InstanceTemplate()->SetInternalFieldCount(static_cast(V8Class::InternalFields::COUNT)); V8Helpers::SetStaticMethod(isolate, tpl, "getForHash", &GetForHash); V8Helpers::SetStaticAccessor(isolate, tpl, "allHashes", &GetAllHashes); diff --git a/client/src/bindings/Worker.cpp b/client/src/bindings/Worker.cpp index 8d7bdc88..2b752b62 100644 --- a/client/src/bindings/Worker.cpp +++ b/client/src/bindings/Worker.cpp @@ -29,7 +29,10 @@ static void Constructor(const v8::FunctionCallbackInfo& info) std::string filePath = pathInfo.prefix + pathInfo.fileName; CWorker* worker = new CWorker(filePath, static_cast(resource)); - info.This()->SetInternalField(0, v8::External::New(isolate, worker)); + + V8Helpers::SetObjectClass(info.GetIsolate(), info.This(), V8Class::ObjectClass::WORKER); + info.This()->SetInternalField(1, v8::External::New(isolate, worker)); + static_cast(resource)->AddWorker(worker); } @@ -212,7 +215,8 @@ extern V8Class v8Worker("Worker", [](v8::Local tpl) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); - tpl->InstanceTemplate()->SetInternalFieldCount(1); + + tpl->InstanceTemplate()->SetInternalFieldCount(static_cast(V8Class::InternalFields::COUNT)); tpl->Set(V8Helpers::JSValue("maxWorkers"), V8Helpers::JSValue(MAX_WORKERS), v8::PropertyAttribute::ReadOnly); V8Helpers::SetStaticAccessor(isolate, tpl, "activeWorkers", &ActiveWorkersGetter); diff --git a/shared/V8Class.h b/shared/V8Class.h index 36f46275..4bda0eb1 100644 --- a/shared/V8Class.h +++ b/shared/V8Class.h @@ -29,12 +29,22 @@ class V8Class enum class ObjectClass { NONE, - RESOURCE, + BASE_OBJECT, VECTOR2, VECTOR3, RGBA, QUATERNION, + MEMORY_BUFFER, + + RESOURCE, + WORKER, + + AUDIO_CATEGORY, + HANDLING, + HANDLING_DATA, + MAP_ZOOM_DATA, + WEAPON_DATA }; static auto& All() From 59f5263ae2cfe35d94e5fa8aee7e1e53566893d2 Mon Sep 17 00:00:00 2001 From: Vadim Zubkov Date: Wed, 20 Mar 2024 14:34:26 +0300 Subject: [PATCH 10/14] fix: string lifetime --- shared/helpers/Serialization.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/shared/helpers/Serialization.cpp b/shared/helpers/Serialization.cpp index 6858bf13..9bd23f80 100644 --- a/shared/helpers/Serialization.cpp +++ b/shared/helpers/Serialization.cpp @@ -35,7 +35,11 @@ alt::MValue V8Helpers::V8ToMValue(v8::Local val, bool allowFunction) if(val->IsNumber()) return core.CreateMValueDouble(val->NumberValue(ctx).ToChecked()); - if(val->IsString()) return core.CreateMValueString(*v8::String::Utf8Value(isolate, val)); + if(val->IsString()) + { + auto jsStr = v8::String::Utf8Value(isolate, val); + return core.CreateMValueString(*jsStr); + } if(val->IsObject()) { @@ -154,8 +158,8 @@ alt::MValue V8Helpers::V8ToMValue(v8::Local val, bool allowFunction) V8_CHECK_RETN(v8Obj->Get(ctx, v8Key).ToLocal(&value), "Failed to convert object to MValue", core.CreateMValueNil()); if(value->IsUndefined()) continue; - auto key = *v8::String::Utf8Value(isolate, v8Key); - dict->Set(key, V8ToMValue(value, allowFunction)); + auto key = v8::String::Utf8Value(isolate, v8Key); + dict->Set(*key, V8ToMValue(value, allowFunction)); } return dict; From 8ab7deac47c632050fe79568e0df974d4a89aadc Mon Sep 17 00:00:00 2001 From: Vadim Zubkov Date: Wed, 20 Mar 2024 17:48:51 +0300 Subject: [PATCH 11/14] fix: RGBA class --- shared/bindings/RGBA.cpp | 2 +- shared/helpers/Macros.h | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/shared/bindings/RGBA.cpp b/shared/bindings/RGBA.cpp index e6be1b35..cc811edb 100644 --- a/shared/bindings/RGBA.cpp +++ b/shared/bindings/RGBA.cpp @@ -9,7 +9,7 @@ static void Constructor(const v8::FunctionCallbackInfo& info) V8_CHECK_ARGS_LEN_MIN_MAX(1, 4); - V8Helpers::SetObjectClass(isolate, info.This(), V8Class::ObjectClass::QUATERNION); + V8Helpers::SetObjectClass(isolate, info.This(), V8Class::ObjectClass::RGBA); int32_t r = 0, g = 0, b = 0, a = 255; if(info.Length() == 1) diff --git a/shared/helpers/Macros.h b/shared/helpers/Macros.h index 44af24ad..6271f393 100644 --- a/shared/helpers/Macros.h +++ b/shared/helpers/Macros.h @@ -48,17 +48,14 @@ V8_CHECK(val, "baseobject is not of type " #type); \ } -// idx starts with 1 #define V8_GET_THIS_INTERNAL_FIELD_OBJECT(idx, val) \ V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \ auto val = info.This()->GetInternalField(idx)->ToObject(isolate->GetEnteredOrMicrotaskContext()).ToLocalChecked(); -// idx starts with 1 #define V8_GET_THIS_INTERNAL_FIELD_V8ENTITY(idx, val) \ V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \ auto val = V8Entity::Get(info.This()->GetInternalField(idx)->ToObject(isolate->GetEnteredOrMicrotaskContext()).ToLocalChecked()); -// idx starts with 1 #define V8_GET_THIS_INTERNAL_FIELD_ENTITY(idx, val, type) \ type* val; \ { \ @@ -69,27 +66,22 @@ V8_CHECK(val, "baseobject is not of type " #type); \ } -// idx starts with 1 #define V8_GET_THIS_INTERNAL_FIELD_INTEGER(idx, val) \ V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \ auto val = info.This()->GetInternalField(idx)->IntegerValue(ctx).ToChecked(); -// idx starts with 1 #define V8_GET_THIS_INTERNAL_FIELD_UINT32(idx, val) \ V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \ auto val = info.This()->GetInternalField(idx)->Uint32Value(ctx).ToChecked(); -// idx starts with 1 #define V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(idx, val, type) \ V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \ auto val = static_cast(info.This()->GetInternalField(idx).As()->Value()); -// idx starts with 1 #define V8_GET_THIS_INTERNAL_FIELD_PTR(idx, val, type) \ V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \ auto val = static_cast(info.This()->GetAlignedPointerFromInternalField(idx)); -// idx starts with 1 #define V8_GET_THIS_INTERNAL_FIELD_STRING(idx, val) \ V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \ auto intVal = info.This()->GetInternalField(idx).As(); \ From 1714dcbc08b03cddd4696037078b6ac8a8660ae2 Mon Sep 17 00:00:00 2001 From: xshady <54737754+xxshady@users.noreply.github.com> Date: Sun, 24 Mar 2024 02:29:06 +0300 Subject: [PATCH 12/14] feat(client): add `alt.Object.streamedIn` (#313) --- client/src/CV8ScriptRuntime.cpp | 13 +++++++++++++ client/src/CV8ScriptRuntime.h | 12 ++++++++---- client/src/bindings/Object.cpp | 18 ++++++++++++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/client/src/CV8ScriptRuntime.cpp b/client/src/CV8ScriptRuntime.cpp index 2a1a6146..46694fd3 100644 --- a/client/src/CV8ScriptRuntime.cpp +++ b/client/src/CV8ScriptRuntime.cpp @@ -413,6 +413,12 @@ void CV8ScriptRuntime::OnEntityStreamIn(alt::IEntity* entity) streamedInPeds.insert({ entity->GetID(), dynamic_cast(entity) }); break; } + case alt::IEntity::Type::LOCAL_OBJECT: + case alt::IEntity::Type::OBJECT: + { + streamedInObjects.insert({ entity->GetID(), dynamic_cast(entity) }); + break; + } } } @@ -437,6 +443,12 @@ void CV8ScriptRuntime::OnEntityStreamOut(alt::IEntity* entity) streamedInPeds.erase(entity->GetID()); break; } + case alt::IEntity::Type::LOCAL_OBJECT: + case alt::IEntity::Type::OBJECT: + { + streamedInObjects.erase(entity->GetID()); + break; + } } } void CV8ScriptRuntime::OnDisconnect() @@ -444,5 +456,6 @@ void CV8ScriptRuntime::OnDisconnect() streamedInPlayers.clear(); streamedInVehicles.clear(); streamedInPeds.clear(); + streamedInObjects.clear(); resourcesLoaded = false; } diff --git a/client/src/CV8ScriptRuntime.h b/client/src/CV8ScriptRuntime.h index 1050373f..dbb80712 100644 --- a/client/src/CV8ScriptRuntime.h +++ b/client/src/CV8ScriptRuntime.h @@ -27,9 +27,10 @@ class CV8ScriptRuntime : public alt::IScriptRuntime, public IRuntimeEventHandler v8::CpuProfiler* profiler; uint32_t profilerSamplingInterval = 100; - std::unordered_map streamedInPlayers; - std::unordered_map streamedInVehicles; - std::unordered_map streamedInPeds; + std::unordered_map streamedInPlayers; + std::unordered_map streamedInVehicles; + std::unordered_map streamedInPeds; + std::unordered_map streamedInObjects; uint32_t activeWorkers = 0; @@ -218,7 +219,10 @@ class CV8ScriptRuntime : public alt::IScriptRuntime, public IRuntimeEventHandler { return streamedInPeds; } - + auto GetStreamedInObjects() + { + return streamedInObjects; + } void OnDisconnect(); }; diff --git a/client/src/bindings/Object.cpp b/client/src/bindings/Object.cpp index af9daf99..f2b4fb03 100644 --- a/client/src/bindings/Object.cpp +++ b/client/src/bindings/Object.cpp @@ -1,5 +1,6 @@ #include "V8Helpers.h" #include "helpers/BindHelpers.h" +#include "../CV8ScriptRuntime.h" static void AllGetter(v8::Local name, const v8::PropertyCallbackInfo& info) { @@ -25,6 +26,22 @@ static void CountGetter(v8::Local name, const v8::PropertyCallbackIn V8_RETURN_UINT(alt::ICore::Instance().GetBaseObjects(alt::IBaseObject::Type::OBJECT).size()); } +static void StreamedInGetter(v8::Local name, const v8::PropertyCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT_RESOURCE(); + + auto streamedIn = CV8ScriptRuntime::Instance().GetStreamedInObjects(); + auto arr = v8::Array::New(isolate, streamedIn.size()); + int i = 0; + for(auto kv : streamedIn) + { + arr->Set(ctx, i, resource->GetOrCreateEntity(kv.second, "Object")->GetJSVal(isolate)); + i++; + } + + V8_RETURN(arr); +} + static void StaticGetByScriptID(const v8::FunctionCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT_RESOURCE(); @@ -94,6 +111,7 @@ extern V8Class v8Object("Object", v8Entity, [](v8::Local t V8Helpers::SetStaticAccessor(isolate, tpl, "all", &AllGetter); V8Helpers::SetStaticAccessor(isolate, tpl, "count", &CountGetter); + V8Helpers::SetStaticAccessor(isolate, tpl, "streamedIn", &StreamedInGetter); V8Helpers::SetAccessor(isolate, tpl, "alpha"); V8Helpers::SetAccessor(isolate, tpl, "textureVariation"); From e30f4e31247f21e27bc31ceaac588a373806a6ec Mon Sep 17 00:00:00 2001 From: xLuxy <67131061+xLuxy@users.noreply.github.com> Date: Fri, 29 Mar 2024 17:21:46 +0100 Subject: [PATCH 13/14] chore(client): increase .all property performance by not creating a copy on an already frozen instance --- client/src/bindings/AudioOutput.cpp | 2 +- client/src/bindings/Player.cpp | 2 +- client/src/bindings/Vehicle.cpp | 2 +- shared/bindings/Blip.cpp | 2 +- shared/bindings/ColShape.cpp | 2 +- shared/bindings/Marker.cpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/src/bindings/AudioOutput.cpp b/client/src/bindings/AudioOutput.cpp index 3330b10e..d7585f38 100644 --- a/client/src/bindings/AudioOutput.cpp +++ b/client/src/bindings/AudioOutput.cpp @@ -19,7 +19,7 @@ static void AllAudioOutputGetter(v8::Local name, const v8::PropertyC { V8_GET_ISOLATE_CONTEXT_RESOURCE(); - V8_RETURN(resource->GetAllAudioOutputs()->Clone()); + V8_RETURN(resource->GetAllAudioOutputs()); } static void AudioOutputCountGetter(v8::Local name, const v8::PropertyCallbackInfo& info) diff --git a/client/src/bindings/Player.cpp b/client/src/bindings/Player.cpp index 78f84116..5587aecb 100644 --- a/client/src/bindings/Player.cpp +++ b/client/src/bindings/Player.cpp @@ -39,7 +39,7 @@ static void AllGetter(v8::Local name, const v8::PropertyCallbackInfo { V8_GET_ISOLATE_CONTEXT_RESOURCE(); - V8_RETURN(resource->GetAllPlayers()->Clone()); + V8_RETURN(resource->GetAllPlayers()); } static void CountGetter(v8::Local name, const v8::PropertyCallbackInfo& info) diff --git a/client/src/bindings/Vehicle.cpp b/client/src/bindings/Vehicle.cpp index 9c206b07..9c3a03ed 100644 --- a/client/src/bindings/Vehicle.cpp +++ b/client/src/bindings/Vehicle.cpp @@ -66,7 +66,7 @@ static void AllGetter(v8::Local name, const v8::PropertyCallbackInfo { V8_GET_ISOLATE_CONTEXT_RESOURCE(); - V8_RETURN(resource->GetAllVehicles()->Clone()); + V8_RETURN(resource->GetAllVehicles()); } static void CountGetter(v8::Local name, const v8::PropertyCallbackInfo& info) diff --git a/shared/bindings/Blip.cpp b/shared/bindings/Blip.cpp index d1fa896d..7bf394f1 100644 --- a/shared/bindings/Blip.cpp +++ b/shared/bindings/Blip.cpp @@ -199,7 +199,7 @@ static void AllGetter(v8::Local name, const v8::PropertyCallbackInfo { V8_GET_ISOLATE_CONTEXT_RESOURCE(); - V8_RETURN(resource->GetAllBlips()->Clone()); + V8_RETURN(resource->GetAllBlips()); } static void CountGetter(v8::Local name, const v8::PropertyCallbackInfo& info) diff --git a/shared/bindings/ColShape.cpp b/shared/bindings/ColShape.cpp index 36fc1d93..ecfbea6f 100644 --- a/shared/bindings/ColShape.cpp +++ b/shared/bindings/ColShape.cpp @@ -36,7 +36,7 @@ static void AllGetter(v8::Local name, const v8::PropertyCallbackInfo { V8_GET_ISOLATE_CONTEXT_RESOURCE(); - V8_RETURN(resource->GetAllColshapes()->Clone()); + V8_RETURN(resource->GetAllColshapes()); } static void StaticGetByID(const v8::FunctionCallbackInfo& info) diff --git a/shared/bindings/Marker.cpp b/shared/bindings/Marker.cpp index c2785546..8f728d46 100644 --- a/shared/bindings/Marker.cpp +++ b/shared/bindings/Marker.cpp @@ -33,7 +33,7 @@ static void AllGetter(v8::Local name, const v8::PropertyCallbackInfo { V8_GET_ISOLATE_CONTEXT_RESOURCE(); - V8_RETURN(resource->GetAllMarkers()->Clone()); + V8_RETURN(resource->GetAllMarkers()); } static void TypeGetter(v8::Local, const v8::PropertyCallbackInfo& info) From feafa53071d711faeb464cf2ec4fd0aa882decc6 Mon Sep 17 00:00:00 2001 From: xshady <54737754+xxshady@users.noreply.github.com> Date: Sat, 30 Mar 2024 18:13:27 +0300 Subject: [PATCH 14/14] fix(client): add missing assignment --- client/src/bindings/FocusData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/bindings/FocusData.cpp b/client/src/bindings/FocusData.cpp index a924db5d..9bd1f9cc 100644 --- a/client/src/bindings/FocusData.cpp +++ b/client/src/bindings/FocusData.cpp @@ -34,7 +34,7 @@ static void OverrideFocus(const v8::FunctionCallbackInfo& info) auto cls = V8Class::ObjectClass::NONE; if(info[0]->IsObject()) - V8Helpers::GetObjectClass(info[0].As()); + cls = V8Helpers::GetObjectClass(info[0].As()); if(cls == V8Class::ObjectClass::VECTOR3) {