diff --git a/.github/workflows/build-deploy.yml b/.github/workflows/build-deploy.yml index b0bd1769..771a7faf 100644 --- a/.github/workflows/build-deploy.yml +++ b/.github/workflows/build-deploy.yml @@ -4,9 +4,9 @@ on: branches-ignore: - '**' tags: - - 'dev/*.*-dev*' - - 'rc/*.*-rc*' - - 'release/*.*' + - 'dev/*.*.*-dev.*' + - 'rc/*.*.*-rc.*' + - 'release/*.*.*' jobs: build-windows: diff --git a/client/src/bindings/AudioFilter.cpp b/client/src/bindings/AudioFilter.cpp index 9a6d2c03..66e7ca96 100644 --- a/client/src/bindings/AudioFilter.cpp +++ b/client/src/bindings/AudioFilter.cpp @@ -91,11 +91,18 @@ static void AddVolumeEffect(const v8::FunctionCallbackInfo& info) V8_GET_THIS_BASE_OBJECT(filter, alt::IAudioFilter); - V8_CHECK_ARGS_LEN(2); + V8_CHECK_ARGS_LEN2(2, 3); V8_ARG_TO_NUMBER(1, fVolume); V8_ARG_TO_INT(2, priority); - V8_RETURN_UINT(filter->AddVolumeEffect(fVolume, priority)); + int channel = -1; + if (info.Length() > 2) + { + V8_TO_UINT(info[2], channel2); + channel = channel2; + } + + V8_RETURN_UINT(filter->AddVolumeEffect(fVolume, priority, channel)); } static void AddPeakeqEffect(const v8::FunctionCallbackInfo& info) diff --git a/client/src/bindings/ClientBindingsMain.cpp b/client/src/bindings/ClientBindingsMain.cpp index 0e4e5ec0..4e445435 100644 --- a/client/src/bindings/ClientBindingsMain.cpp +++ b/client/src/bindings/ClientBindingsMain.cpp @@ -384,6 +384,13 @@ static void GetMsPerGameMinute(const v8::FunctionCallbackInfo& info) V8_RETURN_INT(ICore::Instance().GetMsPerGameMinute()); } +static void GetServerTime(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE(); + + V8_RETURN_NUMBER(ICore::Instance().GetServerTime()); +} + static void SetMsPerGameMinute(const v8::FunctionCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); @@ -1203,6 +1210,152 @@ static void IsFullScreen(const v8::FunctionCallbackInfo& info) V8_RETURN_BOOLEAN(alt::ICore::Instance().IsFullScreen()); } +static void GetPoolSize(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT(); + V8_CHECK_ARGS_LEN(1); + V8_ARG_TO_STRING(1, pool); + + V8_RETURN_UINT(alt::ICore::Instance().GetPoolSize(pool)); +} + +static void GetPoolCount(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT(); + V8_CHECK_ARGS_LEN(1); + V8_ARG_TO_STRING(1, pool); + + V8_RETURN_UINT(alt::ICore::Instance().GetPoolCount(pool)); +} + +static void GetPoolEntities(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT(); + V8_CHECK_ARGS_LEN(1); + V8_ARG_TO_STRING(1, pool); + + auto entities = alt::ICore::Instance().GetPoolEntities(pool); + v8::Local arr = v8::Array::New(isolate, entities.size()); + + for (uint32_t i = 0; i < entities.size(); ++i) + arr->Set(ctx, i, v8::Integer::NewFromUnsigned(isolate, entities[i])); + + V8_RETURN(arr); +} + +static void GetVoicePlayers(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT(); + + auto players = alt::ICore::Instance().GetVoicePlayers(); + v8::Local arr = v8::Array::New(isolate, players.size()); + + for (uint32_t i = 0; i < players.size(); ++i) + arr->Set(ctx, i, v8::Integer::NewFromUnsigned(isolate, players[i])); + + V8_RETURN(arr); +} + +static void RemoveVoicePlayer(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT(); + V8_CHECK_ARGS_LEN(1); + + V8_ARG_TO_INT(1, playerId); + + alt::ICore::Instance().RemoveVoicePlayer(playerId); +} + +static void GetVoiceSpatialVolume(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT(); + V8_CHECK_ARGS_LEN(1); + + V8_ARG_TO_INT(1, playerId); + + V8_RETURN_NUMBER(alt::ICore::Instance().GetVoiceSpatialVolume(playerId)); +} + +static void SetVoiceSpatialVolume(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT(); + V8_CHECK_ARGS_LEN(2); + + V8_ARG_TO_INT(1, playerId); + V8_ARG_TO_NUMBER(2, value); + + alt::ICore::Instance().SetVoiceSpatialVolume(playerId, value); +} + +static void GetVoiceNonSpatialVolume(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT(); + V8_CHECK_ARGS_LEN(1); + + V8_ARG_TO_INT(1, playerId); + + V8_RETURN_NUMBER(alt::ICore::Instance().GetVoiceNonSpatialVolume(playerId)); +} + +static void SetVoiceNonSpatialVolume(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT(); + V8_CHECK_ARGS_LEN(2); + + V8_ARG_TO_INT(1, playerId); + V8_ARG_TO_NUMBER(2, value); + + alt::ICore::Instance().SetVoiceNonSpatialVolume(playerId, value); +} + +static void AddVoiceFilter(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT_RESOURCE(); + V8_CHECK_ARGS_LEN(2); + + V8_ARG_TO_INT(1, playerId); + V8_ARG_TO_BASE_OBJECT(2, filter, alt::IAudioFilter, "AudioFilter"); + + alt::ICore::Instance().AddVoiceFilter(playerId, filter); +} + +static void RemoveVoiceFilter(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT_RESOURCE(); + V8_CHECK_ARGS_LEN(1); + + V8_ARG_TO_INT(1, playerId); + + alt::ICore::Instance().RemoveVoiceFilter(playerId); +} + +static void GetVoiceFilter(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT_RESOURCE(); + V8_CHECK_ARGS_LEN(1); + + V8_ARG_TO_INT(1, playerId); + + V8_RETURN_BASE_OBJECT(alt::ICore::Instance().GetVoiceFilter(playerId)); +} + +static void UpdateClipContext(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT(); + V8_CHECK_ARGS_LEN(1); + V8_CHECK(!info[0]->IsNullOrUndefined() && info[0]->IsObject(), "Argument 1 must be an object"); + + auto dict = V8Helpers::CppValue>(info[0].As()); + std::unordered_map context; + + if(dict.has_value()) + { + for(auto& [key, value] : dict.value()) V8Helpers::SafeToString(value, isolate, ctx, context[key]); + } + + alt::ICore::Instance().UpdateClipContext(context); +} + extern V8Module sharedModule; extern V8Class v8Player, v8Player, v8Vehicle, v8WebView, v8HandlingData, v8LocalStorage, v8MemoryBuffer, v8MapZoomData, v8Discord, v8Voice, v8WebSocketClient, v8Checkpoint, v8HttpClient, v8Audio, v8LocalPlayer, v8Profiler, v8Worker, v8RmlDocument, v8RmlElement, v8WeaponData, v8FocusData, v8LocalObject, v8TextEncoder, v8TextDecoder, v8Object, v8VirtualEntityGroup, @@ -1299,6 +1452,7 @@ extern V8Module altModule("alt", // Time managements functions V8Helpers::RegisterFunc(exports, "setMsPerGameMinute", &SetMsPerGameMinute); V8Helpers::RegisterFunc(exports, "getMsPerGameMinute", &GetMsPerGameMinute); + V8Helpers::RegisterFunc(exports, "getServerTime", &GetServerTime); // CEF rendering on texture V8Helpers::RegisterFunc(exports, "isTextureExistInArchetype", &IsTextureExistInArchetype); @@ -1390,4 +1544,23 @@ extern V8Module altModule("alt", V8Helpers::RegisterFunc(exports, "evalModule", &EvalModule); V8Helpers::RegisterFunc(exports, "isFullScreen", &IsFullScreen); + + V8Helpers::RegisterFunc(exports, "getPoolSize", &GetPoolSize); + V8Helpers::RegisterFunc(exports, "getPoolCount", &GetPoolCount); + V8Helpers::RegisterFunc(exports, "getPoolEntities", &GetPoolEntities); + + // Voice related functions + V8Helpers::RegisterFunc(exports, "getVoicePlayers", &GetVoicePlayers); + V8Helpers::RegisterFunc(exports, "removeVoicePlayer", &RemoveVoicePlayer); + + V8Helpers::RegisterFunc(exports, "getVoiceSpatialVolume", &GetVoiceSpatialVolume); + V8Helpers::RegisterFunc(exports, "setVoiceSpatialVolume", &SetVoiceSpatialVolume); + + V8Helpers::RegisterFunc(exports, "getVoiceNonSpatialVolume", &GetVoiceNonSpatialVolume); + V8Helpers::RegisterFunc(exports, "setVoiceNonSpatialVolume", &SetVoiceNonSpatialVolume); + + V8Helpers::RegisterFunc(exports, "addVoiceFilter", &AddVoiceFilter); + V8Helpers::RegisterFunc(exports, "removeVoiceFilter", &RemoveVoiceFilter); + V8Helpers::RegisterFunc(exports, "getVoiceFilter", &GetVoiceFilter); + V8Helpers::RegisterFunc(exports, "updateClipContext", &UpdateClipContext); }); diff --git a/client/src/bindings/TextLabel.cpp b/client/src/bindings/TextLabel.cpp index 7a5ac2a1..337b407e 100644 --- a/client/src/bindings/TextLabel.cpp +++ b/client/src/bindings/TextLabel.cpp @@ -21,16 +21,15 @@ static void Constructor(const v8::FunctionCallbackInfo& info) V8_ARG_TO_BOOLEAN_OPT(10, useStreaming, false); V8_ARG_TO_UINT_OPT(11, streamingDistance, 0); - auto textLabel = - alt::ICore::Instance().CreateTextLabel(text, fontName, fontSize, scale, pos, rot, color, outlineWidth, outlineColor, useStreaming, streamingDistance, resource->GetResource()); + auto textLabel = alt::ICore::Instance().CreateTextLabel(text, fontName, fontSize, scale, pos, rot, color, outlineWidth, outlineColor, useStreaming, streamingDistance, resource->GetResource()); V8_BIND_BASE_OBJECT(textLabel, "Failed to create textlabel"); } -// static void AllGetter(v8::Local name, const v8::PropertyCallbackInfo& info) -// { -// V8_GET_ISOLATE_CONTEXT_RESOURCE(); -// V8_RETURN(resource->GetAllTextLabel()); -// } +static void AllGetter(v8::Local name, const v8::PropertyCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT_RESOURCE(); + V8_RETURN(resource->GetAllTextLabels()); +} static void StaticGetByID(const v8::FunctionCallbackInfo& info) { @@ -51,6 +50,24 @@ static void StaticGetByID(const v8::FunctionCallbackInfo& info) } } +static void AlignGetter(v8::Local, const v8::PropertyCallbackInfo& info) +{ + V8_GET_ISOLATE(); + + V8_GET_THIS_BASE_OBJECT(label, alt::ITextLabel); + + V8_RETURN_NUMBER(label->GetAlign()); +} + +static void AlignSetter(v8::Local, v8::Local val, const v8::PropertyCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT(); + V8_GET_THIS_BASE_OBJECT(label, alt::ITextLabel); + + V8_TO_NUMBER(val, align); + label->SetAlign((alt::ITextLabel::Alignment) align); +} + extern V8Class v8WorldObject; extern V8Class v8TextLabel("TextLabel", v8WorldObject, @@ -60,7 +77,7 @@ extern V8Class v8TextLabel("TextLabel", using namespace alt; v8::Isolate* isolate = v8::Isolate::GetCurrent(); - // V8Helpers::SetStaticAccessor(isolate, tpl, "all", &AllGetter); + V8Helpers::SetStaticAccessor(isolate, tpl, "all", &AllGetter); V8Helpers::SetStaticMethod(isolate, tpl, "getByID", StaticGetByID); V8Helpers::SetAccessor(isolate, tpl, "isStreamedIn"); @@ -69,6 +86,12 @@ extern V8Class v8TextLabel("TextLabel", V8Helpers::SetAccessor(isolate, tpl, "target"); V8Helpers::SetAccessor(isolate, tpl, "visible"); V8Helpers::SetAccessor(isolate, tpl, "color"); + V8Helpers::SetAccessor(isolate, tpl, "outlineColor"); + V8Helpers::SetAccessor(isolate, tpl, "outlineWidth"); + V8Helpers::SetAccessor(isolate, tpl, "fontSize"); + V8Helpers::SetAccessor(isolate, tpl, "align", &AlignGetter, &AlignSetter); + V8Helpers::SetAccessor(isolate, tpl, "text"); + V8Helpers::SetAccessor(isolate, tpl, "font"); V8Helpers::SetAccessor(isolate, tpl, "scale"); V8Helpers::SetAccessor(isolate, tpl, "rot"); V8Helpers::SetAccessor(isolate, tpl, "faceCamera"); diff --git a/client/src/bindings/V8Natives.cpp b/client/src/bindings/V8Natives.cpp index eb539bac..a2d7b888 100644 --- a/client/src/bindings/V8Natives.cpp +++ b/client/src/bindings/V8Natives.cpp @@ -92,7 +92,7 @@ inline void ShowNativeArgParseErrorMsg(V8ResourceImpl* resource, v8::LocalGetName() << ")"; - Log::Error << source.ToString() << " " << errorMsg.str() << Log::Endl; + Log::Error << source.ToString(isolate) << " " << errorMsg.str() << Log::Endl; Log::Error << "Check the documentation for the needed arguments of this native." << Log::Endl; resource->DispatchErrorEvent(errorMsg.str(), source.GetFileName(), source.GetLineNumber(), V8Helpers::GetStackTrace(errorMsg.str())); @@ -109,7 +109,7 @@ inline void ShowNativeArgMismatchErrorMsg(V8ResourceImpl* resource, alt::INative std::stringstream errorMsg; errorMsg << "Native argument size mismatch. Expected: " << expected << ", Received: " << received << " (" << native->GetName() << ")"; - Log::Error << source.ToString() << " " << errorMsg.str() << Log::Endl; + Log::Error << source.ToString(isolate) << " " << errorMsg.str() << Log::Endl; Log::Error << "Check the documentation for the needed arguments of this native." << Log::Endl; resource->DispatchErrorEvent(errorMsg.str(), source.GetFileName(), source.GetLineNumber(), V8Helpers::GetStackTrace(errorMsg.str())); diff --git a/client/src/workers/CWorker.cpp b/client/src/workers/CWorker.cpp index f5abb6d7..2c76b9db 100644 --- a/client/src/workers/CWorker.cpp +++ b/client/src/workers/CWorker.cpp @@ -135,14 +135,14 @@ void CWorker::SetupIsolate() case v8::kPromiseRejectAfterResolved: { std::ostringstream stream; - stream << location.ToString() << " Promise rejected after being resolved (" << *v8::String::Utf8Value(isolate, value->ToString(ctx).ToLocalChecked()) << ")"; + stream << location.ToString(isolate) << " Promise rejected after being resolved (" << *v8::String::Utf8Value(isolate, value->ToString(ctx).ToLocalChecked()) << ")"; worker->EmitError(stream.str()); break; } case v8::kPromiseResolveAfterResolved: { std::ostringstream stream; - stream << location.ToString() << " Promise resolved after being resolved (" << *v8::String::Utf8Value(isolate, value->ToString(ctx).ToLocalChecked()) << ")"; + stream << location.ToString(isolate) << " Promise resolved after being resolved (" << *v8::String::Utf8Value(isolate, value->ToString(ctx).ToLocalChecked()) << ")"; worker->EmitError(stream.str()); break; } diff --git a/server/src/CNodeResourceImpl.cpp b/server/src/CNodeResourceImpl.cpp index 3255d029..a7a1d220 100644 --- a/server/src/CNodeResourceImpl.cpp +++ b/server/src/CNodeResourceImpl.cpp @@ -26,19 +26,20 @@ static const char bootstrap_code[] = #include "bootstrap.js.gen" ; -CNodeResourceImpl::CNodeResourceImpl(CNodeScriptRuntime* _runtime, v8::Isolate* isolate, alt::IResource* resource) : V8ResourceImpl(isolate, resource), runtime(_runtime) +CNodeResourceImpl::CNodeResourceImpl(CNodeScriptRuntime* _runtime, alt::IResource* resource) : V8ResourceImpl(nullptr, resource), runtime(_runtime) { + uvLoop = new uv_loop_t; + uv_loop_init(uvLoop); + + auto allocator = node::CreateArrayBufferAllocator(); + isolate = node::NewIsolate(allocator, uvLoop, runtime->GetPlatform()); + nodeData = node::CreateIsolateData(isolate, uvLoop, runtime->GetPlatform(), allocator); + v8::Locker locker(isolate); v8::Isolate::Scope isolateScope(isolate); v8::HandleScope handleScope(isolate); - v8::Local global = v8::ObjectTemplate::New(isolate); - - v8::Local resourceName = V8Helpers::JSValue(resource->GetName()); - - v8::Local _context = node::NewContext(isolate, global); - v8::Context::Scope scope(_context); - + v8::Local _context = node::NewContext(isolate); _context->SetAlignedPointerInEmbedderData(1, resource); context.Reset(isolate, _context); } @@ -48,29 +49,28 @@ bool CNodeResourceImpl::Start() v8::Locker locker(isolate); v8::Isolate::Scope isolateScope(isolate); v8::HandleScope handleScope(isolate); - v8::Local _context = GetContext(); + + auto _context = GetContext(); v8::Context::Scope scope(_context); _context->Global()->Set(_context, V8Helpers::JSValue("__resourceLoaded"), v8::Function::New(_context, &ResourceLoaded).ToLocalChecked()); _context->Global()->Set(_context, V8Helpers::JSValue("__internal_bindings_code"), V8Helpers::JSValue(JSBindings::GetBindingsCode())); + V8Class::LoadAll(isolate); V8ResourceImpl::Start(); V8ResourceImpl::SetupScriptGlobals(); - node::EnvironmentFlags::Flags flags = (node::EnvironmentFlags::Flags)(node::EnvironmentFlags::kOwnsProcessState & node::EnvironmentFlags::kNoCreateInspector); - - uvLoop = new uv_loop_t; - uv_loop_init(uvLoop); + node::ThreadId threadId = node::AllocateEnvironmentThreadId(); + auto flags = static_cast(node::EnvironmentFlags::kNoFlags); + auto inspector = node::GetInspectorParentHandle(runtime->GetParentEnv(), threadId, resource->GetName().c_str()); - nodeData = node::CreateIsolateData(isolate, uvLoop, runtime->GetPlatform()); - std::vector argv = { "altv-resource" }; - env = node::CreateEnvironment(nodeData, _context, argv, argv, flags); - - node::IsolateSettings is; - node::SetIsolateUpForNode(isolate, is); + std::vector args{ resource->GetName() }; + std::vector execArgs{ }; + env = node::CreateEnvironment(nodeData, _context, args, execArgs, flags, threadId, std::move(inspector)); node::LoadEnvironment(env, bootstrap_code); + // Not sure it's needed anymore asyncResource.Reset(isolate, v8::Object::New(isolate)); asyncContext = node::EmitAsyncInit(isolate, asyncResource.Get(isolate), "CNodeResourceImpl"); @@ -80,6 +80,7 @@ bool CNodeResourceImpl::Start() OnTick(); } + Log::Debug << "Started" << Log::Endl; DispatchStartEvent(startError); return !startError; @@ -91,6 +92,8 @@ bool CNodeResourceImpl::Stop() v8::Isolate::Scope isolateScope(isolate); v8::HandleScope handleScope(isolate); + Log::Debug << "Before stop" << Log::Endl; + { v8::Context::Scope scope(GetContext()); DispatchStopEvent(); @@ -99,6 +102,8 @@ bool CNodeResourceImpl::Stop() asyncResource.Reset(); } + Log::Debug << "After stop" << Log::Endl; + node::EmitProcessBeforeExit(env); node::EmitProcessExit(env); @@ -357,6 +362,7 @@ void CNodeResourceImpl::OnTick() v8::Context::Scope scope(GetContext()); node::CallbackScope callbackScope(isolate, asyncResource.Get(isolate), asyncContext); + runtime->GetPlatform()->DrainTasks(isolate); uv_run(uvLoop, UV_RUN_NOWAIT); V8ResourceImpl::OnTick(); } diff --git a/server/src/CNodeResourceImpl.h b/server/src/CNodeResourceImpl.h index 4601fd79..9ef032b4 100644 --- a/server/src/CNodeResourceImpl.h +++ b/server/src/CNodeResourceImpl.h @@ -17,7 +17,7 @@ class CNodeScriptRuntime; class CNodeResourceImpl : public V8ResourceImpl { public: - CNodeResourceImpl(CNodeScriptRuntime* _runtime, v8::Isolate* isolate, alt::IResource* resource); + CNodeResourceImpl(CNodeScriptRuntime* _runtime, alt::IResource* resource); CNodeResourceImpl(const CNodeResourceImpl&) = delete; diff --git a/server/src/CNodeScriptRuntime.cpp b/server/src/CNodeScriptRuntime.cpp index 4b0bb8dd..7d8fbc41 100644 --- a/server/src/CNodeScriptRuntime.cpp +++ b/server/src/CNodeScriptRuntime.cpp @@ -6,34 +6,45 @@ bool CNodeScriptRuntime::Init() { ProcessConfigOptions(); - std::vector argv = GetNodeArgs(); - std::vector execArgv; - std::vector errors; - node::InitializeNodeWithArgs(&argv, &execArgv, &errors); - if(errors.size() > 0) + auto result = node::InitializeOncePerProcess(GetNodeArgs()); + + if (result->early_return()) { - for(std::string& error : errors) + for (auto& error : result->errors()) { Log::Error << "Error while initializing node: " << error << Log::Endl; } + return false; } - platform = node::MultiIsolatePlatform::Create(4); - v8::V8::InitializePlatform(platform.get()); - v8::V8::Initialize(); + platform.reset(result->platform()); - isolate = node::NewIsolate(node::CreateArrayBufferAllocator(), uv_default_loop(), platform.get()); + auto allocator = node::CreateArrayBufferAllocator(); + isolate = node::NewIsolate(allocator, uv_default_loop(), platform.get()); + node::IsolateData* nodeData = node::CreateIsolateData(isolate, uv_default_loop(), platform.get(), allocator); + + // node::IsolateSettings is; + // node::SetIsolateUpForNode(isolate, is); // IsWorker data slot - isolate->SetData(v8::Isolate::GetNumberOfDataSlots() - 1, new bool(false)); + // isolate->SetData(v8::Isolate::GetNumberOfDataSlots() - 1, new bool(false)); { v8::Locker locker(isolate); v8::Isolate::Scope isolate_scope(isolate); v8::HandleScope handle_scope(isolate); - V8Class::LoadAll(isolate); + context.Reset(isolate, node::NewContext(isolate)); + v8::Context::Scope scope(context.Get(isolate)); + + parentEnv = node::CreateEnvironment(nodeData, context.Get(isolate), result->args(), result->exec_args()); + + /* + Load here only needs for debugging as this environment only used as a parent for real environments + */ + + // node::LoadEnvironment(parentEnv, "console.log('PARENT INIT'); setInterval(() => {}, 1000);"); } IRuntimeEventHandler::Start(); @@ -45,7 +56,7 @@ bool CNodeScriptRuntime::Init() alt::IResource::Impl* CNodeScriptRuntime::CreateImpl(alt::IResource* resource) { - auto res = new CNodeResourceImpl{ this, isolate, resource }; + auto res = new CNodeResourceImpl{ this, resource }; resources.insert(res); return res; } @@ -54,8 +65,10 @@ void CNodeScriptRuntime::OnTick() { v8::Locker locker(isolate); v8::Isolate::Scope isolateScope(isolate); - v8::SealHandleScope seal(isolate); + v8::HandleScope seal(isolate); + v8::Context::Scope scope(context.Get(isolate)); + uv_run(uv_default_loop(), UV_RUN_NOWAIT); platform->DrainTasks(isolate); UpdateMetrics(); @@ -89,6 +102,9 @@ std::vector CNodeScriptRuntime::GetNodeArgs() Config::Value::ValuePtr moduleConfig = alt::ICore::Instance().GetServerConfig()["js-module"]; if(!moduleConfig->IsDict()) return args; + /* + * Not working as expected anyway + * // https://nodejs.org/api/cli.html#--inspecthostport Config::Value::ValuePtr inspector = moduleConfig["inspector"]; if(!inspector->IsNone()) @@ -97,6 +113,7 @@ std::vector CNodeScriptRuntime::GetNodeArgs() int inspectorPort = inspector["port"]->AsNumber(9229); args.push_back("--inspect=" + inspectorHost + ":" + std::to_string(inspectorPort)); } + */ // https://nodejs.org/api/cli.html#--enable-source-maps Config::Value::ValuePtr enableSourceMaps = moduleConfig["source-maps"]; diff --git a/server/src/CNodeScriptRuntime.h b/server/src/CNodeScriptRuntime.h index 8406109c..b81a37e4 100644 --- a/server/src/CNodeScriptRuntime.h +++ b/server/src/CNodeScriptRuntime.h @@ -10,6 +10,9 @@ class CNodeScriptRuntime : public alt::IScriptRuntime, public IRuntimeEventHandler { v8::Isolate* isolate; + V8Helpers::CPersistent context; + node::Environment* parentEnv; + std::unique_ptr platform; std::unordered_set resources; @@ -34,9 +37,19 @@ class CNodeScriptRuntime : public alt::IScriptRuntime, public IRuntimeEventHandl CNodeScriptRuntime() = default; bool Init(); - v8::Isolate* GetIsolate() + /*v8::Isolate* GetIsolate() { return isolate; + }*/ + + node::Environment* GetParentEnv() const + { + return parentEnv; + } + + v8::Local GetContext() + { + return context.Get(isolate); } alt::IResource::Impl* CreateImpl(alt::IResource* resource) override; diff --git a/server/src/bindings/ConnectionInfo.cpp b/server/src/bindings/ConnectionInfo.cpp index 81938659..4e178cee 100644 --- a/server/src/bindings/ConnectionInfo.cpp +++ b/server/src/bindings/ConnectionInfo.cpp @@ -55,10 +55,26 @@ static void BranchGetter(v8::Local, const v8::PropertyCallbackInfo, const v8::PropertyCallbackInfo& info) +{ + V8_DEPRECATE("ConnectionInfo build", "versionMajor & versionMinor"); + + V8_GET_ISOLATE_CONTEXT_RESOURCE(); + V8_GET_THIS_BASE_OBJECT(con, alt::IConnectionInfo); + V8_RETURN_UINT(con->GetVersionMajor()); +} + +static void VersionMajorGetter(v8::Local, const v8::PropertyCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT_RESOURCE(); + V8_GET_THIS_BASE_OBJECT(con, alt::IConnectionInfo); + V8_RETURN_UINT(con->GetVersionMajor()); +} + +static void VersionMinorGetter(v8::Local, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT_RESOURCE(); V8_GET_THIS_BASE_OBJECT(con, alt::IConnectionInfo); - V8_RETURN_UINT(con->GetBuild()); + V8_RETURN_UINT(con->GetVersionMinor()); } static void CdnUrlGetter(v8::Local, const v8::PropertyCallbackInfo& info) @@ -216,6 +232,8 @@ extern V8Class v8ConnectionInfo("ConnectionInfo", V8Helpers::SetAccessor(isolate, tpl, "isDebug", &IsDebugGetter); V8Helpers::SetAccessor(isolate, tpl, "branch", &BranchGetter); V8Helpers::SetAccessor(isolate, tpl, "build", &BuildGetter); + V8Helpers::SetAccessor(isolate, tpl, "versionMajor", &VersionMajorGetter); + V8Helpers::SetAccessor(isolate, tpl, "versionMinor", &VersionMinorGetter); V8Helpers::SetAccessor(isolate, tpl, "cdnUrl", &CdnUrlGetter); V8Helpers::SetAccessor(isolate, tpl, "passwordHash", &PasswordHashGetter); V8Helpers::SetAccessor(isolate, tpl, "ip", &IpGetter); diff --git a/server/src/bindings/Main.cpp b/server/src/bindings/Main.cpp index 5aba46c2..fd23028e 100644 --- a/server/src/bindings/Main.cpp +++ b/server/src/bindings/Main.cpp @@ -418,6 +418,7 @@ static void GetVehicleModelByHash(const v8::FunctionCallbackInfo& inf const alt::VehicleModelInfo& modelInfo = alt::ICore::Instance().GetVehicleModelByHash(hash); V8_NEW_OBJECT(infoObj); + infoObj->Set(ctx, V8Helpers::JSValue("modelHash"), V8Helpers::JSValue(modelInfo.modelHash)); infoObj->Set(ctx, V8Helpers::JSValue("title"), V8Helpers::JSValue(modelInfo.title)); infoObj->Set(ctx, V8Helpers::JSValue("type"), V8Helpers::JSValue((int)modelInfo.modelType)); infoObj->Set(ctx, V8Helpers::JSValue("wheelsCount"), V8Helpers::JSValue(modelInfo.wheelsCount)); @@ -573,7 +574,7 @@ static void GetWeaponModelByHash(const v8::FunctionCallbackInfo& info infoObj->Set(ctx, V8Helpers::JSValue("hash"), V8Helpers::JSValue(modelInfo.hash)); infoObj->Set(ctx, V8Helpers::JSValue("name"), V8Helpers::JSValue(modelInfo.name)); - infoObj->Set(ctx, V8Helpers::JSValue("modelName"), V8Helpers::JSValue(modelInfo.modelName)); + infoObj->Set(ctx, V8Helpers::JSValue("modelName"), V8Helpers::JSValue(modelInfo.model)); infoObj->Set(ctx, V8Helpers::JSValue("modelHash"), V8Helpers::JSValue(modelInfo.modelHash)); infoObj->Set(ctx, V8Helpers::JSValue("ammoTypeHash"), V8Helpers::JSValue(modelInfo.ammoTypeHash)); infoObj->Set(ctx, V8Helpers::JSValue("ammoType"), V8Helpers::JSValue(modelInfo.ammoType)); diff --git a/server/src/bindings/Object.cpp b/server/src/bindings/Object.cpp index 858d487d..8019606b 100644 --- a/server/src/bindings/Object.cpp +++ b/server/src/bindings/Object.cpp @@ -66,6 +66,25 @@ static void CountGetter(v8::Local name, const v8::PropertyCallbackIn V8_RETURN_UINT(alt::ICore::Instance().GetBaseObjects(alt::IBaseObject::Type::OBJECT).size()); } +static void StaticGetByID(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT_RESOURCE(); + V8_CHECK_ARGS_LEN(1); + + V8_ARG_TO_INT(1, id); + + alt::IBaseObject* entity = alt::ICore::Instance().GetBaseObjectByID(alt::IBaseObject::Type::OBJECT, id); + + if(entity) + { + V8_RETURN_BASE_OBJECT(entity); + } + else + { + V8_RETURN_NULL(); + } +} + // clang-format off extern V8Class v8Entity; extern V8Class v8Object("Object", v8Entity, Constructor, [](v8::Local tpl) @@ -74,6 +93,7 @@ extern V8Class v8Object("Object", v8Entity, Constructor, [](v8::Local(isolate, tpl, "activatePhysics"); V8Helpers::SetMethod(isolate, tpl, "placeOnGroundProperly"); diff --git a/server/src/bindings/Player.cpp b/server/src/bindings/Player.cpp index 5bd46b57..37de52c5 100644 --- a/server/src/bindings/Player.cpp +++ b/server/src/bindings/Player.cpp @@ -300,6 +300,17 @@ static void GetDlcClothes(const v8::FunctionCallbackInfo& info) V8_RETURN(clothes); } +static void ClearClothes(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT(); + V8_GET_THIS_BASE_OBJECT(player, IPlayer); + + V8_CHECK_ARGS_LEN(1); + V8_ARG_TO_UINT(1, component); + + player->ClearClothes(component); +} + static void SetProps(const v8::FunctionCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); @@ -627,6 +638,14 @@ static void GetHeadBlendPaletteColor(const v8::FunctionCallbackInfo& V8_RETURN_RGBA(player->GetHeadBlendPaletteColor(id)); } +static void RemoveHeadBlendPaletteColor(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE(); + V8_GET_THIS_BASE_OBJECT(player, IPlayer); + + player->RemoveHeadBlendPaletteColor(); +} + static void SetHeadBlendData(const v8::FunctionCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); @@ -1316,7 +1335,7 @@ static void SetAmmoMax100(const v8::FunctionCallbackInfo& info) static void AddDecoration(const v8::FunctionCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_CHECK_ARGS_LEN(2); + V8_CHECK_ARGS_LEN_MIN_MAX(2, 3); V8_GET_THIS_BASE_OBJECT(player, IPlayer); uint32_t collectionHash; @@ -1343,7 +1362,14 @@ static void AddDecoration(const v8::FunctionCallbackInfo& info) overlayHash = alt::ICore::Instance().Hash(overlay); } - player->AddDecoration(collectionHash, overlayHash); + uint8_t count = 1; + if (info[2]->IsNumber()) + { + V8_ARG_TO_UINT(3, _count); + count = _count; + } + + player->AddDecoration(collectionHash, overlayHash, count); } static void RemoveDecoration(const v8::FunctionCallbackInfo& info) @@ -1401,6 +1427,7 @@ static void GetDecorations(const v8::FunctionCallbackInfo& info) V8_NEW_OBJECT(decorationsObj); V8_OBJECT_SET_UINT(decorationsObj, "collection", decoration.collection); V8_OBJECT_SET_UINT(decorationsObj, "overlay", decoration.overlay); + V8_OBJECT_SET_INT(decorationsObj, "count", decoration.count); decorationsArr->Set(ctx, i, decorationsObj); } @@ -1535,6 +1562,7 @@ extern V8Class v8Player("Player", V8Helpers::SetMethod(isolate, tpl, "setDlcClothes", &SetDlcClothes); V8Helpers::SetMethod(isolate, tpl, "getClothes", &GetClothes); V8Helpers::SetMethod(isolate, tpl, "getDlcClothes", &GetDlcClothes); + V8Helpers::SetMethod(isolate, tpl, "clearClothes", &ClearClothes); V8Helpers::SetMethod(isolate, tpl, "setProp", &SetProps); V8Helpers::SetMethod(isolate, tpl, "setDlcProp", &SetDlcProps); @@ -1564,6 +1592,7 @@ extern V8Class v8Player("Player", V8Helpers::SetMethod(isolate, tpl, "removeFaceFeature", &RemoveFaceFeature); V8Helpers::SetMethod(isolate, tpl, "setHeadBlendPaletteColor", &SetHeadBlendPaletteColor); V8Helpers::SetMethod(isolate, tpl, "getHeadBlendPaletteColor", &GetHeadBlendPaletteColor); + V8Helpers::SetMethod(isolate, tpl, "removeHeadBlendPaletteColor", &RemoveHeadBlendPaletteColor); V8Helpers::SetMethod(isolate, tpl, "setHeadBlendData", &SetHeadBlendData); V8Helpers::SetMethod(isolate, tpl, "removeHeadBlendData", &RemoveHeadBlendData); V8Helpers::SetMethod(isolate, tpl, "getHeadBlendData", &GetHeadBlendData); diff --git a/server/src/bindings/Vehicle.cpp b/server/src/bindings/Vehicle.cpp index 8c747eb6..71c9e1b0 100644 --- a/server/src/bindings/Vehicle.cpp +++ b/server/src/bindings/Vehicle.cpp @@ -252,6 +252,61 @@ static void GetPassengers(v8::Local, const v8::PropertyCallbackInfo< V8_RETURN(obj); } +static void SetBadge(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT(); + V8_CHECK_ARGS_LEN_MIN_MAX(3, 6); + V8_GET_THIS_BASE_OBJECT(_this, IVehicle); + + uint32_t textureDictionary; + if (info[0]->IsString()) + { + V8_ARG_TO_STRING(1, textureDictionaryName); + textureDictionary = alt::ICore::Instance().Hash(textureDictionaryName); + } + else + { + V8_ARG_TO_UINT(1, _textureDictionary); + textureDictionary = _textureDictionary; + } + + uint32_t texture; + if (info[1]->IsString()) + { + V8_ARG_TO_STRING(2, textureName); + texture = alt::ICore::Instance().Hash(textureName); + } + else + { + V8_ARG_TO_UINT(2, _texture); + texture = _texture; + } + + alt::VehicleBadgePosition positions[4]; + for (int i = 0; i < 4; i++) + { + if (!info[i + 2]->IsObject()) break; + + V8_ARG_TO_OBJECT(i + 3, dict); + + if (dict.IsEmpty()) break; + + V8_TO_BOOLEAN(V8Helpers::Get(ctx, dict, "active"), active); + V8_TO_NUMBER(V8Helpers::Get(ctx, dict, "size"), size); + V8_TO_INT32(V8Helpers::Get(ctx, dict, "boneIndex"), boneIndex); + V8_TO_INT32(V8Helpers::Get(ctx, dict, "alpha"), alpha); + + V8_TO_VECTOR3(V8Helpers::Get(ctx, dict, "offset"), offset); + V8_TO_VECTOR3(V8Helpers::Get(ctx, dict, "direction"), direction); + V8_TO_VECTOR3(V8Helpers::Get(ctx, dict, "side"), side); + + positions[i] = alt::VehicleBadgePosition((uint8_t)alpha, (float)size, (int16_t)boneIndex, offset, direction, side); + positions[i].active = active; + } + + _this->SetBadge(textureDictionary, texture, positions); +} + extern V8Class v8Entity; extern V8Class v8Vehicle("Vehicle", v8Entity, @@ -439,4 +494,5 @@ extern V8Class v8Vehicle("Vehicle", V8Helpers::SetMethod(isolate, tpl, "setWeaponCapacity", &SetWeaponCapacity); V8Helpers::SetAccessor(isolate, tpl, "hybridExtraActive"); V8Helpers::SetAccessor(isolate, tpl, "hybridExtraState"); + V8Helpers::SetMethod(isolate, tpl, "setBadge", &SetBadge); }); diff --git a/server/src/bootstrap.js b/server/src/bootstrap.js index a3196f66..2beabb17 100644 --- a/server/src/bootstrap.js +++ b/server/src/bootstrap.js @@ -6,6 +6,7 @@ const path = require("path"); const alt = process._linkedBinding("alt"); const dns = require('dns'); const url = require("url"); +const inspector = require("inspector"); (async () => { const resource = alt.Resource.current; @@ -29,6 +30,15 @@ const url = require("url"); new Function("alt", "__global", __internal_bindings_code)(alt, bindingsGlobal); __setLogFunction(bindingsGlobal.genericLog); + const config = alt.Resource.current.config; + if (config.inspector) { + const host = config.inspector.host ?? '127.0.0.1'; + const port = config.inspector.port ?? 9229; + const wait = config.inspector.wait ?? false; + + inspector.open(port, host, wait); + } + const extraBootstrapFile = __getExtraBootstrapFile(); if(extraBootstrapFile.length !== 0) new Function("alt", extraBootstrapFile)(alt); diff --git a/server/src/events/Main.cpp b/server/src/events/Main.cpp index e11d3d29..d7d54d86 100644 --- a/server/src/events/Main.cpp +++ b/server/src/events/Main.cpp @@ -88,8 +88,8 @@ V8Helpers::LocalEventHandler fireEvent(EventType::FIRE_EVENT, for(int i = 0; i < fires.size(); ++i) { v8::Local v8fire = v8::Object::New(isolate); - v8fire->Set(resource->GetContext(), V8Helpers::Fire_PosKey(isolate), resource->CreateVector3(fires[i].position)); - v8fire->Set(resource->GetContext(), V8Helpers::Fire_WeaponKey(isolate), V8Helpers::JSValue(fires[i].weaponHash)); + v8fire->Set(resource->GetContext(), resource->PosKey(), resource->CreateVector3(fires[i].position)); + v8fire->Set(resource->GetContext(), resource->WeaponKey(), V8Helpers::JSValue(fires[i].weaponHash)); v8fires->Set(resource->GetContext(), i, v8fire); } diff --git a/server/src/events/Player.cpp b/server/src/events/Player.cpp index e1af453f..50086dbf 100644 --- a/server/src/events/Player.cpp +++ b/server/src/events/Player.cpp @@ -44,7 +44,8 @@ V8Helpers::LocalEventHandler playerConnectDenied(EventType::PLAYER_CONNECT_DENIE args.push_back(V8Helpers::JSValue(ev->GetPasswordHash())); args.push_back(V8Helpers::JSValue(ev->IsDebug())); args.push_back(V8Helpers::JSValue(ev->GetBranch())); - args.push_back(V8Helpers::JSValue(ev->GetMajorVersion())); + args.push_back(V8Helpers::JSValue(ev->GetVersionMajor())); + // TODO: no idea where to put version minor to not break backward compatibility, not sure it's needed at all args.push_back(V8Helpers::JSValue(ev->GetCdnUrl())); args.push_back(V8Helpers::JSValue(ev->GetDiscordId())); }); diff --git a/shared/Log.cpp b/shared/Log.cpp index 6f48e8dd..2df79e32 100644 --- a/shared/Log.cpp +++ b/shared/Log.cpp @@ -12,8 +12,9 @@ Log& Log::Endl(Log& log) #ifdef ALT_CLIENT_API isolate = CV8ScriptRuntime::Instance().GetIsolate(); #else - isolate = CNodeScriptRuntime::Instance().GetIsolate(); + isolate = v8::Isolate::GetCurrent(); #endif + v8::Local ctx; if(isolate) ctx = isolate->GetEnteredOrMicrotaskContext(); V8ResourceImpl* v8Resource = !ctx.IsEmpty() ? V8ResourceImpl::Get(ctx) : nullptr; diff --git a/shared/V8Helpers.cpp b/shared/V8Helpers.cpp index d20d1da7..a4014d16 100644 --- a/shared/V8Helpers.cpp +++ b/shared/V8Helpers.cpp @@ -189,17 +189,18 @@ V8Helpers::SourceLocation::SourceLocation(std::string&& _fileName, int _line, v8 context.Reset(ctx->GetIsolate(), ctx); } -std::string V8Helpers::SourceLocation::ToString() +std::string V8Helpers::SourceLocation::ToString(v8::Isolate* isolate) { - auto isolate = v8::Isolate::GetCurrent(); - std::stringstream stream; stream << "["; + // Check if not inside a worker - if(!(*static_cast(isolate->GetData(v8::Isolate::GetNumberOfDataSlots() - 1)))) + bool* isWorker = static_cast(isolate->GetData(v8::Isolate::GetNumberOfDataSlots() - 1)); + if (!isWorker || !(*isWorker)) { - stream << V8ResourceImpl::Get(context.Get(v8::Isolate::GetCurrent()))->GetResource()->GetName() << ":"; + stream << V8ResourceImpl::Get(context.Get(isolate))->GetResource()->GetName() << ":"; } + stream << fileName << ":" << line << "]"; return stream.str(); } @@ -257,97 +258,6 @@ void V8Helpers::StackTrace::Print(v8::Isolate* isolate) trace.Print(); } -v8::Local V8Helpers::Vector3_XKey(v8::Isolate* isolate) -{ - static v8::Persistent xKey{ isolate, v8::String::NewFromUtf8(isolate, "x", v8::NewStringType::kInternalized).ToLocalChecked() }; - - return xKey.Get(isolate); -} - -v8::Local V8Helpers::Vector3_YKey(v8::Isolate* isolate) -{ - static v8::Persistent yKey{ isolate, v8::String::NewFromUtf8(isolate, "y", v8::NewStringType::kInternalized).ToLocalChecked() }; - - return yKey.Get(isolate); -} - -v8::Local V8Helpers::Vector3_ZKey(v8::Isolate* isolate) -{ - static v8::Persistent zKey{ isolate, v8::String::NewFromUtf8(isolate, "z", v8::NewStringType::kInternalized).ToLocalChecked() }; - - return zKey.Get(isolate); -} - -v8::Local V8Helpers::Quaternion_XKey(v8::Isolate* isolate) -{ - static v8::Persistent xKey{ isolate, v8::String::NewFromUtf8(isolate, "x", v8::NewStringType::kInternalized).ToLocalChecked() }; - - return xKey.Get(isolate); -} - -v8::Local V8Helpers::Quaternion_YKey(v8::Isolate* isolate) -{ - static v8::Persistent yKey{ isolate, v8::String::NewFromUtf8(isolate, "y", v8::NewStringType::kInternalized).ToLocalChecked() }; - - return yKey.Get(isolate); -} - -v8::Local V8Helpers::Quaternion_ZKey(v8::Isolate* isolate) -{ - static v8::Persistent zKey{ isolate, v8::String::NewFromUtf8(isolate, "z", v8::NewStringType::kInternalized).ToLocalChecked() }; - - return zKey.Get(isolate); -} - -v8::Local V8Helpers::Quaternion_WKey(v8::Isolate* isolate) -{ - static v8::Persistent wKey{ isolate, v8::String::NewFromUtf8(isolate, "w", v8::NewStringType::kInternalized).ToLocalChecked() }; - - return wKey.Get(isolate); -} - -v8::Local V8Helpers::RGBA_RKey(v8::Isolate* isolate) -{ - static v8::Persistent rKey{ isolate, v8::String::NewFromUtf8(isolate, "r", v8::NewStringType::kInternalized).ToLocalChecked() }; - - return rKey.Get(isolate); -} - -v8::Local V8Helpers::RGBA_GKey(v8::Isolate* isolate) -{ - static v8::Persistent gKey{ isolate, v8::String::NewFromUtf8(isolate, "g", v8::NewStringType::kInternalized).ToLocalChecked() }; - - return gKey.Get(isolate); -} - -v8::Local V8Helpers::RGBA_BKey(v8::Isolate* isolate) -{ - static v8::Persistent bKey{ isolate, v8::String::NewFromUtf8(isolate, "b", v8::NewStringType::kInternalized).ToLocalChecked() }; - - return bKey.Get(isolate); -} - -v8::Local V8Helpers::RGBA_AKey(v8::Isolate* isolate) -{ - static v8::Persistent aKey{ isolate, v8::String::NewFromUtf8(isolate, "a", v8::NewStringType::kInternalized).ToLocalChecked() }; - - return aKey.Get(isolate); -} - -v8::Local V8Helpers::Fire_PosKey(v8::Isolate* isolate) -{ - static v8::Persistent aKey{ isolate, v8::String::NewFromUtf8(isolate, "pos", v8::NewStringType::kInternalized).ToLocalChecked() }; - - return aKey.Get(isolate); -} - -v8::Local V8Helpers::Fire_WeaponKey(v8::Isolate* isolate) -{ - static v8::Persistent aKey{ isolate, v8::String::NewFromUtf8(isolate, "weapon", v8::NewStringType::kInternalized).ToLocalChecked() }; - - return aKey.Get(isolate); -} - std::vector V8Helpers::EventHandler::GetCallbacks(V8ResourceImpl* impl, const alt::CEvent* e) { return callbacksGetter(impl, e); diff --git a/shared/V8Helpers.h b/shared/V8Helpers.h index 768aeb69..4c835c62 100644 --- a/shared/V8Helpers.h +++ b/shared/V8Helpers.h @@ -59,7 +59,7 @@ namespace V8Helpers return line; } - std::string ToString(); + std::string ToString(v8::Isolate* isolate); static SourceLocation GetCurrent(v8::Isolate* isolate, V8ResourceImpl* resource = nullptr); @@ -171,24 +171,6 @@ namespace V8Helpers v8::GenericNamedPropertyEnumeratorCallback enumerator = nullptr, v8::GenericNamedPropertyQueryCallback query = nullptr); - // TODO: create c++ classes for v8 classes and move there - v8::Local Vector3_XKey(v8::Isolate* isolate); - v8::Local Vector3_YKey(v8::Isolate* isolate); - v8::Local Vector3_ZKey(v8::Isolate* isolate); - - v8::Local Quaternion_XKey(v8::Isolate* isolate); - v8::Local Quaternion_YKey(v8::Isolate* isolate); - v8::Local Quaternion_ZKey(v8::Isolate* isolate); - v8::Local Quaternion_WKey(v8::Isolate* isolate); - - v8::Local RGBA_RKey(v8::Isolate* isolate); - v8::Local RGBA_GKey(v8::Isolate* isolate); - v8::Local RGBA_BKey(v8::Isolate* isolate); - v8::Local RGBA_AKey(v8::Isolate* isolate); - - v8::Local Fire_PosKey(v8::Isolate* isolate); - v8::Local Fire_WeaponKey(v8::Isolate* isolate); - std::string Stringify(v8::Local ctx, v8::Local val); std::string GetJSValueTypeName(v8::Local val); diff --git a/shared/V8ResourceImpl.cpp b/shared/V8ResourceImpl.cpp index a47d58ee..0ac0851a 100644 --- a/shared/V8ResourceImpl.cpp +++ b/shared/V8ResourceImpl.cpp @@ -277,7 +277,7 @@ void V8ResourceImpl::OnRemoveBaseObject(alt::IBaseObject* handle) if(!ent) return; auto entityType = handle->GetType(); - if(entityType == alt::IBaseObject::Type::PLAYER || entityType == alt::IBaseObject::Type::LOCAL_PLAYER || entityType == alt::IBaseObject::Type::VEHICLE) + if(entityType == alt::IBaseObject::Type::PLAYER || entityType == alt::IBaseObject::Type::LOCAL_PLAYER || entityType == alt::IBaseObject::Type::VEHICLE || entityType == alt::IBaseObject::Type::PED || entityType == alt::IBaseObject::Type::OBJECT) { std::vector handlers = GetLocalHandlers("removeEntity"); std::vector> args{ ent->GetJSVal(isolate) }; @@ -490,6 +490,17 @@ v8::Local V8ResourceImpl::GetAllObjects() return jsAll; } +v8::Local V8ResourceImpl::GetAllTextLabels() +{ + std::vector all = ICore::Instance().GetBaseObjects(alt::IBaseObject::Type::TEXT_LABEL); + v8::Local jsAll = v8::Array::New(isolate, all.size()); + + for(uint32_t i = 0; i < all.size(); ++i) jsAll->Set(GetContext(), i, GetBaseObjectOrNull(all[i])); + + jsAll->SetIntegrityLevel(GetContext(), v8::IntegrityLevel::kFrozen); + return jsAll; +} + std::vector V8ResourceImpl::GetLocalHandlers(const std::string& name) { std::vector handlers; diff --git a/shared/V8ResourceImpl.h b/shared/V8ResourceImpl.h index d4bb2d56..01f1c6e2 100644 --- a/shared/V8ResourceImpl.h +++ b/shared/V8ResourceImpl.h @@ -86,7 +86,7 @@ class V8ResourceImpl : public alt::IResource::Impl if(!anyHandlerRemoved) { - Log::Warning << location.ToString() << " alt.off was called for event \"" << ev << "\" with function reference that was not subscribed" << Log::Endl; + Log::Warning << location.ToString(isolate) << " alt.off was called for event \"" << ev << "\" with function reference that was not subscribed" << Log::Endl; return; } @@ -259,6 +259,7 @@ class V8ResourceImpl : public alt::IResource::Impl v8::Local GetAllWeaponObjects(); #endif v8::Local GetAllObjects(); + v8::Local GetAllTextLabels(); std::vector GetLocalHandlers(const std::string& name); std::vector GetRemoteHandlers(const std::string& name); @@ -394,4 +395,34 @@ class V8ResourceImpl : public alt::IResource::Impl } void InvokeEventHandlers(const alt::CEvent* ev, const std::vector& handlers, std::vector>& args, bool waitForPromiseResolve = false); + +public: + struct ObjectKey + { + ObjectKey(V8ResourceImpl* _resource, const char* _key) : resource(_resource), keyStr(_key) {} + + v8::Local operator()() + { + if(key.IsEmpty()) key.Reset(resource->GetIsolate(), v8::String::NewFromUtf8(resource->GetIsolate(), keyStr, v8::NewStringType::kInternalized).ToLocalChecked()); + return key.Get(resource->GetIsolate()); + } + + private: + V8ResourceImpl* resource; + const char* keyStr; + v8::Persistent key; + }; + + ObjectKey XKey{ this, "x" }; + ObjectKey YKey{ this, "y" }; + ObjectKey ZKey{ this, "z" }; + ObjectKey WKey{ this, "w" }; + + ObjectKey RKey{ this, "r" }; + ObjectKey GKey{ this, "g" }; + ObjectKey BKey{ this, "b" }; + ObjectKey AKey{ this, "a" }; + + ObjectKey PosKey{ this, "pos" }; + ObjectKey WeaponKey{ this, "weapon" }; }; diff --git a/shared/bindings/Entity.cpp b/shared/bindings/Entity.cpp index 77852688..3450903f 100644 --- a/shared/bindings/Entity.cpp +++ b/shared/bindings/Entity.cpp @@ -225,6 +225,44 @@ static void IsSpawnedGetter(v8::Local, const v8::PropertyCallbackInf V8_RETURN_BOOLEAN(entity->GetScriptID() != 0); } +static void GetSyncInfo(const v8::FunctionCallbackInfo& info) +{ + V8_GET_ISOLATE_CONTEXT(); + V8_GET_THIS_BASE_OBJECT(entity, alt::IEntity); + + auto syncInfo = entity->GetSyncInfo(); + + v8::Local result = v8::Object::New(isolate); + V8_OBJECT_SET_BOOLEAN(result, "active", syncInfo.active > 0); + V8_OBJECT_SET_UINT(result, "receivedTick", syncInfo.receivedTick); + V8_OBJECT_SET_UINT(result, "fullyReceivedTick", syncInfo.fullyReceivedTick); + V8_OBJECT_SET_UINT(result, "sendTick", syncInfo.sendTick); + V8_OBJECT_SET_UINT(result, "ackedSendTick", syncInfo.ackedSendTick); + V8_OBJECT_SET_NUMBER(result, "propertyCount", syncInfo.propertyCount); + V8_OBJECT_SET_NUMBER(result, "componentCount", syncInfo.componentCount); + + const v8::Local componentPropertyIndex = v8::Array::New(isolate, syncInfo.componentCount); + uint32_t lastPropertyIdx = 0; + for(uint32_t i = 0; i < syncInfo.componentCount; i++) + { + const uint32_t endIdx = i == syncInfo.componentCount - 1 + ? syncInfo.propertyCount + : syncInfo.componentPropertyIndex[i]; + const v8::Local propertiesUpdateTick = v8::Array::New(isolate, static_cast(endIdx - lastPropertyIdx)); + for (uint32_t j = lastPropertyIdx; j < endIdx; j++) + { + propertiesUpdateTick->Set(ctx, j - lastPropertyIdx, V8Helpers::JSValue(syncInfo.propertiesUpdateTick[j])); + } + componentPropertyIndex->Set(ctx, i, propertiesUpdateTick); + lastPropertyIdx = endIdx; + } + + // 2d array of property update ticks grouped per component + result->Set(ctx, v8::String::NewFromUtf8(isolate, "propertyUpdateTicks").ToLocalChecked(), componentPropertyIndex); + + V8_RETURN(result); +} + static void StaticGetByScriptID(const v8::FunctionCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT_RESOURCE(); @@ -299,5 +337,6 @@ extern V8Class v8Entity("Entity", V8Helpers::SetAccessor(isolate, tpl, "visible"); V8Helpers::SetAccessor(isolate, tpl, "isSpawned", &IsSpawnedGetter); + V8Helpers::SetMethod(isolate, tpl, "getSyncInfo", &GetSyncInfo); #endif // ALT_CLIENT_API }); diff --git a/shared/bindings/Quaternion.cpp b/shared/bindings/Quaternion.cpp index 3b28ee5b..848337e8 100644 --- a/shared/bindings/Quaternion.cpp +++ b/shared/bindings/Quaternion.cpp @@ -1,4 +1,4 @@ -#include +#include #include "../V8Class.h" #include "../V8Helpers.h" @@ -6,7 +6,7 @@ static void Constructor(const v8::FunctionCallbackInfo& info) { - V8_GET_ISOLATE_CONTEXT(); + V8_GET_ISOLATE_CONTEXT_RESOURCE(); V8_CHECK_CONSTRUCTOR(); V8_CHECK_ARGS_LEN2(1, 4); @@ -38,10 +38,10 @@ static void Constructor(const v8::FunctionCallbackInfo& info) { v8::Local obj = val.As(); - x = obj->Get(ctx, V8Helpers::Quaternion_XKey(isolate)).ToLocalChecked(); - y = obj->Get(ctx, V8Helpers::Quaternion_YKey(isolate)).ToLocalChecked(); - z = obj->Get(ctx, V8Helpers::Quaternion_ZKey(isolate)).ToLocalChecked(); - w = obj->Get(ctx, V8Helpers::Quaternion_WKey(isolate)).ToLocalChecked(); + x = obj->Get(ctx, resource->XKey()).ToLocalChecked(); + y = obj->Get(ctx, resource->YKey()).ToLocalChecked(); + z = obj->Get(ctx, resource->ZKey()).ToLocalChecked(); + w = obj->Get(ctx, resource->WKey()).ToLocalChecked(); V8_CHECK(x->IsNumber(), "Argument must be an array of 4 numbers"); V8_CHECK(y->IsNumber(), "Argument must be an array of 4 numbers"); @@ -74,10 +74,10 @@ static void Constructor(const v8::FunctionCallbackInfo& info) w = info[3]; } - V8Helpers::DefineOwnProperty(isolate, ctx, _this, V8Helpers::Quaternion_XKey(isolate), x, v8::PropertyAttribute::ReadOnly); - V8Helpers::DefineOwnProperty(isolate, ctx, _this, V8Helpers::Quaternion_YKey(isolate), y, v8::PropertyAttribute::ReadOnly); - V8Helpers::DefineOwnProperty(isolate, ctx, _this, V8Helpers::Quaternion_ZKey(isolate), z, v8::PropertyAttribute::ReadOnly); - V8Helpers::DefineOwnProperty(isolate, ctx, _this, V8Helpers::Quaternion_WKey(isolate), w, v8::PropertyAttribute::ReadOnly); + V8Helpers::DefineOwnProperty(isolate, ctx, _this, resource->XKey(), x, v8::PropertyAttribute::ReadOnly); + V8Helpers::DefineOwnProperty(isolate, ctx, _this, resource->YKey(), y, v8::PropertyAttribute::ReadOnly); + V8Helpers::DefineOwnProperty(isolate, ctx, _this, resource->ZKey(), z, v8::PropertyAttribute::ReadOnly); + V8Helpers::DefineOwnProperty(isolate, ctx, _this, resource->WKey(), w, v8::PropertyAttribute::ReadOnly); } extern V8Class v8Quaternion("Quaternion", diff --git a/shared/bindings/RGBA.cpp b/shared/bindings/RGBA.cpp index b3d1a0c7..9a838214 100644 --- a/shared/bindings/RGBA.cpp +++ b/shared/bindings/RGBA.cpp @@ -5,7 +5,7 @@ static void Constructor(const v8::FunctionCallbackInfo& info) { - V8_GET_ISOLATE_CONTEXT(); + V8_GET_ISOLATE_CONTEXT_RESOURCE(); V8_CHECK_ARGS_LEN_MIN_MAX(1, 4); @@ -60,10 +60,10 @@ static void Constructor(const v8::FunctionCallbackInfo& info) V8_CHECK(b >= 0 && b < 256, "Invalid RGBA B value. Allowed is 0 - 255"); V8_CHECK(a >= 0 && a < 256, "Invalid RGBA A value. Allowed is 0 - 255"); - V8Helpers::DefineOwnProperty(isolate, ctx, info.This(), V8Helpers::RGBA_RKey(isolate), V8Helpers::JSValue(r), v8::PropertyAttribute::ReadOnly); - V8Helpers::DefineOwnProperty(isolate, ctx, info.This(), V8Helpers::RGBA_GKey(isolate), V8Helpers::JSValue(g), v8::PropertyAttribute::ReadOnly); - V8Helpers::DefineOwnProperty(isolate, ctx, info.This(), V8Helpers::RGBA_BKey(isolate), V8Helpers::JSValue(b), v8::PropertyAttribute::ReadOnly); - V8Helpers::DefineOwnProperty(isolate, ctx, info.This(), V8Helpers::RGBA_AKey(isolate), V8Helpers::JSValue(a), v8::PropertyAttribute::ReadOnly); + V8Helpers::DefineOwnProperty(isolate, ctx, info.This(), resource->RKey(), V8Helpers::JSValue(r), v8::PropertyAttribute::ReadOnly); + V8Helpers::DefineOwnProperty(isolate, ctx, info.This(), resource->GKey(), V8Helpers::JSValue(g), v8::PropertyAttribute::ReadOnly); + V8Helpers::DefineOwnProperty(isolate, ctx, info.This(), resource->BKey(), V8Helpers::JSValue(b), v8::PropertyAttribute::ReadOnly); + V8Helpers::DefineOwnProperty(isolate, ctx, info.This(), resource->AKey(), V8Helpers::JSValue(a), v8::PropertyAttribute::ReadOnly); } extern V8Class v8RGBA("RGBA", diff --git a/shared/bindings/Vector2.cpp b/shared/bindings/Vector2.cpp index 76bfc3d0..40925ee8 100644 --- a/shared/bindings/Vector2.cpp +++ b/shared/bindings/Vector2.cpp @@ -8,12 +8,12 @@ constexpr double PI = 3.141592653589793238463; static void ToString(const v8::FunctionCallbackInfo& info) { - V8_GET_ISOLATE_CONTEXT(); + V8_GET_ISOLATE_CONTEXT_RESOURCE(); v8::Local _this = info.This(); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_XKey(isolate)), x); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_YKey(isolate)), y); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->XKey()), x); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->YKey()), y); std::ostringstream ss; ss << std::fixed << std::setprecision(4) << "Vector2{ x: " << x << ", y: " << y << " }"; @@ -23,12 +23,12 @@ static void ToString(const v8::FunctionCallbackInfo& info) static void ToArray(const v8::FunctionCallbackInfo& info) { - V8_GET_ISOLATE_CONTEXT(); + V8_GET_ISOLATE_CONTEXT_RESOURCE(); v8::Local _this = info.This(); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_XKey(isolate)), x); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_YKey(isolate)), y); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->XKey()), x); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->YKey()), y); v8::Local arr = v8::Array::New(isolate, 2); arr->Set(ctx, 0, V8Helpers::JSValue(x)); @@ -39,12 +39,12 @@ static void ToArray(const v8::FunctionCallbackInfo& info) static void Length(v8::Local, const v8::PropertyCallbackInfo& info) { - V8_GET_ISOLATE_CONTEXT(); + V8_GET_ISOLATE_CONTEXT_RESOURCE(); v8::Local _this = info.This(); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_XKey(isolate)), x); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_YKey(isolate)), y); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->XKey()), x); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->YKey()), y); double length = sqrt(x * x + y * y); @@ -59,8 +59,8 @@ static void Add(const v8::FunctionCallbackInfo& info) v8::Local _this = info.This(); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_XKey(isolate)), x); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_YKey(isolate)), y); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->XKey()), x); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->YKey()), y); if(info.Length() == 2) { @@ -90,8 +90,8 @@ static void Add(const v8::FunctionCallbackInfo& info) { v8::Local obj = arg.As(); - V8_TO_NUMBER(obj->Get(ctx, V8Helpers::Vector3_XKey(isolate)).ToLocalChecked(), x2); - V8_TO_NUMBER(obj->Get(ctx, V8Helpers::Vector3_YKey(isolate)).ToLocalChecked(), y2); + V8_TO_NUMBER(obj->Get(ctx, resource->XKey()).ToLocalChecked(), x2); + V8_TO_NUMBER(obj->Get(ctx, resource->YKey()).ToLocalChecked(), y2); V8_RETURN(resource->CreateVector2({ x + x2, y + y2 })); } @@ -110,8 +110,8 @@ static void Sub(const v8::FunctionCallbackInfo& info) v8::Local _this = info.This(); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_XKey(isolate)), x); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_YKey(isolate)), y); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->XKey()), x); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->YKey()), y); if(info.Length() == 2) { @@ -141,8 +141,8 @@ static void Sub(const v8::FunctionCallbackInfo& info) { v8::Local obj = arg.As(); - V8_TO_NUMBER(obj->Get(ctx, V8Helpers::Vector3_XKey(isolate)).ToLocalChecked(), x2); - V8_TO_NUMBER(obj->Get(ctx, V8Helpers::Vector3_YKey(isolate)).ToLocalChecked(), y2); + V8_TO_NUMBER(obj->Get(ctx, resource->XKey()).ToLocalChecked(), x2); + V8_TO_NUMBER(obj->Get(ctx, resource->YKey()).ToLocalChecked(), y2); V8_RETURN(resource->CreateVector2({ x - x2, y - y2 })); } @@ -161,8 +161,8 @@ static void Divide(const v8::FunctionCallbackInfo& info) v8::Local _this = info.This(); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_XKey(isolate)), x); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_YKey(isolate)), y); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->XKey()), x); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->YKey()), y); if(info.Length() == 2) { @@ -195,8 +195,8 @@ static void Divide(const v8::FunctionCallbackInfo& info) { v8::Local obj = arg.As(); - V8_TO_NUMBER(obj->Get(ctx, V8Helpers::Vector3_XKey(isolate)).ToLocalChecked(), x2); - V8_TO_NUMBER(obj->Get(ctx, V8Helpers::Vector3_YKey(isolate)).ToLocalChecked(), y2); + V8_TO_NUMBER(obj->Get(ctx, resource->XKey()).ToLocalChecked(), x2); + V8_TO_NUMBER(obj->Get(ctx, resource->YKey()).ToLocalChecked(), y2); V8_CHECK(x2 != 0 && y2 != 0, "Division by zero"); V8_RETURN(resource->CreateVector2({ x / x2, y / y2 })); } @@ -215,8 +215,8 @@ static void Multiply(const v8::FunctionCallbackInfo& info) v8::Local _this = info.This(); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_XKey(isolate)), x); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_YKey(isolate)), y); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->XKey()), x); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->YKey()), y); if(info.Length() == 2) { @@ -246,8 +246,8 @@ static void Multiply(const v8::FunctionCallbackInfo& info) { v8::Local obj = arg.As(); - V8_TO_NUMBER(obj->Get(ctx, V8Helpers::Vector3_XKey(isolate)).ToLocalChecked(), x2); - V8_TO_NUMBER(obj->Get(ctx, V8Helpers::Vector3_YKey(isolate)).ToLocalChecked(), y2); + V8_TO_NUMBER(obj->Get(ctx, resource->XKey()).ToLocalChecked(), x2); + V8_TO_NUMBER(obj->Get(ctx, resource->YKey()).ToLocalChecked(), y2); V8_RETURN(resource->CreateVector2({ x * x2, y * y2 })); } @@ -266,8 +266,8 @@ static void Dot(const v8::FunctionCallbackInfo& info) v8::Local _this = info.This(); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_XKey(isolate)), x); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_YKey(isolate)), y); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->XKey()), x); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->YKey()), y); if(info.Length() == 2) { @@ -299,8 +299,8 @@ static void Dot(const v8::FunctionCallbackInfo& info) { v8::Local obj = arg.As(); - V8_TO_NUMBER(obj->Get(ctx, V8Helpers::Vector3_XKey(isolate)).ToLocalChecked(), x2); - V8_TO_NUMBER(obj->Get(ctx, V8Helpers::Vector3_YKey(isolate)).ToLocalChecked(), y2); + V8_TO_NUMBER(obj->Get(ctx, resource->XKey()).ToLocalChecked(), x2); + V8_TO_NUMBER(obj->Get(ctx, resource->YKey()).ToLocalChecked(), y2); V8_RETURN_NUMBER(x * x2 + y * y2); } @@ -317,8 +317,8 @@ static void Negative(const v8::FunctionCallbackInfo& info) v8::Local _this = info.This(); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_XKey(isolate)), x); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_YKey(isolate)), y); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->XKey()), x); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->YKey()), y); V8_RETURN(resource->CreateVector2({ -x, -y })); } @@ -329,8 +329,8 @@ static void Normalize(const v8::FunctionCallbackInfo& info) v8::Local _this = info.This(); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_XKey(isolate)), x); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_YKey(isolate)), y); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->XKey()), x); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->YKey()), y); double length = sqrt(x * x + y * y); @@ -344,13 +344,13 @@ static void DistanceTo(const v8::FunctionCallbackInfo& info) v8::Local _this = info.This(); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_XKey(isolate)), x); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_YKey(isolate)), y); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->XKey()), x); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->YKey()), y); V8_ARG_TO_OBJECT(1, vec); - V8_TO_NUMBER(vec->Get(ctx, V8Helpers::Vector3_XKey(isolate)).ToLocalChecked(), x2); - V8_TO_NUMBER(vec->Get(ctx, V8Helpers::Vector3_YKey(isolate)).ToLocalChecked(), y2); + V8_TO_NUMBER(vec->Get(ctx, resource->XKey()).ToLocalChecked(), x2); + V8_TO_NUMBER(vec->Get(ctx, resource->YKey()).ToLocalChecked(), y2); double xFinal = x - x2; double yFinal = y - y2; @@ -366,13 +366,13 @@ static void AngleTo(const v8::FunctionCallbackInfo& info) v8::Local _this = info.This(); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_XKey(isolate)), x); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_YKey(isolate)), y); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->XKey()), x); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->YKey()), y); V8_ARG_TO_OBJECT(1, vec); - V8_TO_NUMBER(vec->Get(ctx, V8Helpers::Vector3_XKey(isolate)).ToLocalChecked(), x2); - V8_TO_NUMBER(vec->Get(ctx, V8Helpers::Vector3_YKey(isolate)).ToLocalChecked(), y2); + V8_TO_NUMBER(vec->Get(ctx, resource->XKey()).ToLocalChecked(), x2); + V8_TO_NUMBER(vec->Get(ctx, resource->YKey()).ToLocalChecked(), y2); double xy = x * x2 + y * y2; double posALength = sqrt(std::pow(x, 2) + std::pow(y, 2)); @@ -398,13 +398,13 @@ static void AngleToDegrees(const v8::FunctionCallbackInfo& info) v8::Local _this = info.This(); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_XKey(isolate)), x); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_YKey(isolate)), y); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->XKey()), x); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->YKey()), y); V8_ARG_TO_OBJECT(1, vec); - V8_TO_NUMBER(vec->Get(ctx, V8Helpers::Vector3_XKey(isolate)).ToLocalChecked(), x2); - V8_TO_NUMBER(vec->Get(ctx, V8Helpers::Vector3_YKey(isolate)).ToLocalChecked(), y2); + V8_TO_NUMBER(vec->Get(ctx, resource->XKey()).ToLocalChecked(), x2); + V8_TO_NUMBER(vec->Get(ctx, resource->YKey()).ToLocalChecked(), y2); double xy = x * x2 + y * y2; double posALength = sqrt(std::pow(x, 2) + std::pow(y, 2)); @@ -429,8 +429,8 @@ static void ToDegrees(const v8::FunctionCallbackInfo& info) v8::Local _this = info.This(); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_XKey(isolate)), x); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_YKey(isolate)), y); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->XKey()), x); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->YKey()), y); double x2 = (x * 180) / PI; double y2 = (y * 180) / PI; @@ -444,8 +444,8 @@ static void ToRadians(const v8::FunctionCallbackInfo& info) v8::Local _this = info.This(); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_XKey(isolate)), x); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_YKey(isolate)), y); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->XKey()), x); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->YKey()), y); double x2 = (x * PI) / 180; double y2 = (y * PI) / 180; @@ -461,14 +461,14 @@ static void IsInRange(const v8::FunctionCallbackInfo& info) v8::Local _this = info.This(); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_XKey(isolate)), x); - V8_TO_NUMBER(V8Helpers::Get(ctx, _this, V8Helpers::Vector3_YKey(isolate)), y); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->XKey()), x); + V8_TO_NUMBER(V8Helpers::Get(ctx, _this, resource->YKey()), y); V8_ARG_TO_OBJECT(1, vec); V8_ARG_TO_NUMBER(2, range); - V8_TO_NUMBER(vec->Get(ctx, V8Helpers::Vector3_XKey(isolate)).ToLocalChecked(), x2); - V8_TO_NUMBER(vec->Get(ctx, V8Helpers::Vector3_YKey(isolate)).ToLocalChecked(), y2); + V8_TO_NUMBER(vec->Get(ctx, resource->XKey()).ToLocalChecked(), x2); + V8_TO_NUMBER(vec->Get(ctx, resource->YKey()).ToLocalChecked(), y2); double dx = abs(x - x2); double dy = abs(y - y2); @@ -498,7 +498,7 @@ static void Lerp(const v8::FunctionCallbackInfo& info) static void Constructor(const v8::FunctionCallbackInfo& info) { - V8_GET_ISOLATE_CONTEXT(); + V8_GET_ISOLATE_CONTEXT_RESOURCE(); V8_CHECK_CONSTRUCTOR(); V8_CHECK_ARGS_LEN2(1, 2); @@ -534,8 +534,8 @@ static void Constructor(const v8::FunctionCallbackInfo& info) { v8::Local obj = val.As(); - x = obj->Get(ctx, V8Helpers::Vector3_XKey(isolate)).ToLocalChecked(); - y = obj->Get(ctx, V8Helpers::Vector3_YKey(isolate)).ToLocalChecked(); + x = obj->Get(ctx, resource->XKey()).ToLocalChecked(); + y = obj->Get(ctx, resource->YKey()).ToLocalChecked(); V8_CHECK(x->IsNumber(), "x must be a number"); V8_CHECK(y->IsNumber(), "y must be a number"); @@ -552,8 +552,8 @@ static void Constructor(const v8::FunctionCallbackInfo& info) } } - V8Helpers::DefineOwnProperty(isolate, ctx, _this, V8Helpers::Vector3_XKey(isolate), x, v8::PropertyAttribute::ReadOnly); - V8Helpers::DefineOwnProperty(isolate, ctx, _this, V8Helpers::Vector3_YKey(isolate), y, v8::PropertyAttribute::ReadOnly); + V8Helpers::DefineOwnProperty(isolate, ctx, _this, resource->XKey(), x, v8::PropertyAttribute::ReadOnly); + V8Helpers::DefineOwnProperty(isolate, ctx, _this, resource->YKey(), y, v8::PropertyAttribute::ReadOnly); } extern V8Class v8Vector2("Vector2", diff --git a/shared/bindings/Vector3.cpp b/shared/bindings/Vector3.cpp index 3d7a6720..8df6c17b 100644 --- a/shared/bindings/Vector3.cpp +++ b/shared/bindings/Vector3.cpp @@ -79,7 +79,7 @@ static void AngleToDegrees(const v8::FunctionCallbackInfo& info) static void Constructor(const v8::FunctionCallbackInfo& info) { - V8_GET_ISOLATE_CONTEXT(); + V8_GET_ISOLATE_CONTEXT_RESOURCE(); V8_CHECK_CONSTRUCTOR(); V8_CHECK_ARGS_LEN2(1, 3); @@ -119,9 +119,9 @@ static void Constructor(const v8::FunctionCallbackInfo& info) { v8::Local obj = val.As(); - x = obj->Get(ctx, V8Helpers::Vector3_XKey(isolate)).ToLocalChecked(); - y = obj->Get(ctx, V8Helpers::Vector3_YKey(isolate)).ToLocalChecked(); - z = obj->Get(ctx, V8Helpers::Vector3_ZKey(isolate)).ToLocalChecked(); + x = obj->Get(ctx, resource->XKey()).ToLocalChecked(); + y = obj->Get(ctx, resource->YKey()).ToLocalChecked(); + z = obj->Get(ctx, resource->ZKey()).ToLocalChecked(); V8_CHECK(x->IsNumber(), "x must be a number"); V8_CHECK(y->IsNumber(), "y must be a number"); @@ -140,9 +140,9 @@ static void Constructor(const v8::FunctionCallbackInfo& info) } } - V8Helpers::DefineOwnProperty(isolate, ctx, _this, V8Helpers::Vector3_XKey(isolate), x, v8::PropertyAttribute::ReadOnly); - V8Helpers::DefineOwnProperty(isolate, ctx, _this, V8Helpers::Vector3_YKey(isolate), y, v8::PropertyAttribute::ReadOnly); - V8Helpers::DefineOwnProperty(isolate, ctx, _this, V8Helpers::Vector3_ZKey(isolate), z, v8::PropertyAttribute::ReadOnly); + V8Helpers::DefineOwnProperty(isolate, ctx, _this, resource->XKey(), x, v8::PropertyAttribute::ReadOnly); + V8Helpers::DefineOwnProperty(isolate, ctx, _this, resource->YKey(), y, v8::PropertyAttribute::ReadOnly); + V8Helpers::DefineOwnProperty(isolate, ctx, _this, resource->ZKey(), z, v8::PropertyAttribute::ReadOnly); } extern V8Class v8Vector3("Vector3", diff --git a/shared/deps/cpp-sdk b/shared/deps/cpp-sdk index fb89bd99..afb16ada 160000 --- a/shared/deps/cpp-sdk +++ b/shared/deps/cpp-sdk @@ -1 +1 @@ -Subproject commit fb89bd99dc254c04ccdf3490ed06855849ec8c96 +Subproject commit afb16ada599fe835a61d1b7f27e964493bc50c04 diff --git a/shared/events/Resource.cpp b/shared/events/Resource.cpp index 42b4cffc..e8e2769d 100644 --- a/shared/events/Resource.cpp +++ b/shared/events/Resource.cpp @@ -25,7 +25,17 @@ V8_EVENT_HANDLER anyResourceStop( for(alt::IResource* res : alt::ICore::Instance().GetAllResources()) { if(res->GetType() != "js" || !res->IsStarted()) continue; - static_cast(res->GetImpl())->DeleteResourceObject(resource->GetResource()); + + auto targetRes = static_cast(res->GetImpl()); + v8::Isolate* resIsolate = targetRes->GetIsolate(); + + { + v8::Locker locker(resIsolate); + v8::Isolate::Scope isolateScope(resIsolate); + v8::HandleScope handleScope(resIsolate); + + targetRes->DeleteResourceObject(resource->GetResource()); + } } return resource->GetLocalHandlers("anyResourceStop"); }, diff --git a/shared/helpers/Macros.h b/shared/helpers/Macros.h index b5517b92..f21cac6f 100644 --- a/shared/helpers/Macros.h +++ b/shared/helpers/Macros.h @@ -377,6 +377,6 @@ { \ V8_GET_ISOLATE(); \ V8_GET_RESOURCE(); \ - Log::Warning << V8Helpers::SourceLocation::GetCurrent(isolate, resource).ToString() << " " << oldName << " is deprecated and will be removed in future versions. Consider using " \ + Log::Warning << V8Helpers::SourceLocation::GetCurrent(isolate, resource).ToString(isolate) << " " << oldName << " is deprecated and will be removed in future versions. Consider using " \ << newName << " instead" << Log::Endl; \ } diff --git a/shared/helpers/Serialization.cpp b/shared/helpers/Serialization.cpp index 0af0ca34..dabce201 100644 --- a/shared/helpers/Serialization.cpp +++ b/shared/helpers/Serialization.cpp @@ -56,7 +56,7 @@ alt::MValue V8Helpers::V8ToMValue(v8::Local val, bool allowFunction) { if(!allowFunction) { - Log::Error << V8Helpers::SourceLocation::GetCurrent(isolate).ToString() << " " + Log::Error << V8Helpers::SourceLocation::GetCurrent(isolate).ToString(isolate) << " " << "Cannot convert function to MValue" << Log::Endl; return core.CreateMValueNone(); } @@ -106,27 +106,27 @@ alt::MValue V8Helpers::V8ToMValue(v8::Local val, bool allowFunction) if(resource->IsVector3(v8Obj)) { v8::Local x, y, z; - V8_CHECK_RETN(v8Obj->Get(ctx, V8Helpers::Vector3_XKey(isolate)).ToLocal(&x), "Failed to convert Vector3 to MValue", core.CreateMValueNil()); - V8_CHECK_RETN(v8Obj->Get(ctx, V8Helpers::Vector3_YKey(isolate)).ToLocal(&y), "Failed to convert Vector3 to MValue", core.CreateMValueNil()); - V8_CHECK_RETN(v8Obj->Get(ctx, V8Helpers::Vector3_ZKey(isolate)).ToLocal(&z), "Failed to convert Vector3 to MValue", core.CreateMValueNil()); + V8_CHECK_RETN(v8Obj->Get(ctx, resource->XKey()).ToLocal(&x), "Failed to convert Vector3 to MValue", core.CreateMValueNil()); + V8_CHECK_RETN(v8Obj->Get(ctx, resource->YKey()).ToLocal(&y), "Failed to convert Vector3 to MValue", core.CreateMValueNil()); + V8_CHECK_RETN(v8Obj->Get(ctx, resource->ZKey()).ToLocal(&z), "Failed to convert Vector3 to MValue", core.CreateMValueNil()); return core.CreateMValueVector3(alt::Vector3f{ x.As()->Value(), y.As()->Value(), z.As()->Value() }); } else if(resource->IsVector2(v8Obj)) { v8::Local x, y; - V8_CHECK_RETN(v8Obj->Get(ctx, V8Helpers::Vector3_XKey(isolate)).ToLocal(&x), "Failed to convert Vector2 to MValue", core.CreateMValueNil()); - V8_CHECK_RETN(v8Obj->Get(ctx, V8Helpers::Vector3_YKey(isolate)).ToLocal(&y), "Failed to convert Vector2 to MValue", core.CreateMValueNil()); + V8_CHECK_RETN(v8Obj->Get(ctx, resource->XKey()).ToLocal(&x), "Failed to convert Vector2 to MValue", core.CreateMValueNil()); + V8_CHECK_RETN(v8Obj->Get(ctx, resource->YKey()).ToLocal(&y), "Failed to convert Vector2 to MValue", core.CreateMValueNil()); return core.CreateMValueVector2(alt::Vector2f{ x.As()->Value(), y.As()->Value() }); } else if(resource->IsRGBA(v8Obj)) { v8::Local r, g, b, a; - V8_CHECK_RETN(v8Obj->Get(ctx, V8Helpers::RGBA_RKey(isolate)).ToLocal(&r), "Failed to convert RGBA to MValue", core.CreateMValueNil()); - V8_CHECK_RETN(v8Obj->Get(ctx, V8Helpers::RGBA_GKey(isolate)).ToLocal(&g), "Failed to convert RGBA to MValue", core.CreateMValueNil()); - V8_CHECK_RETN(v8Obj->Get(ctx, V8Helpers::RGBA_BKey(isolate)).ToLocal(&b), "Failed to convert RGBA to MValue", core.CreateMValueNil()); - V8_CHECK_RETN(v8Obj->Get(ctx, V8Helpers::RGBA_AKey(isolate)).ToLocal(&a), "Failed to convert RGBA to MValue", core.CreateMValueNil()); + V8_CHECK_RETN(v8Obj->Get(ctx, resource->RKey()).ToLocal(&r), "Failed to convert RGBA to MValue", core.CreateMValueNil()); + V8_CHECK_RETN(v8Obj->Get(ctx, resource->GKey()).ToLocal(&g), "Failed to convert RGBA to MValue", core.CreateMValueNil()); + V8_CHECK_RETN(v8Obj->Get(ctx, resource->BKey()).ToLocal(&b), "Failed to convert RGBA to MValue", core.CreateMValueNil()); + V8_CHECK_RETN(v8Obj->Get(ctx, resource->AKey()).ToLocal(&a), "Failed to convert RGBA to MValue", core.CreateMValueNil()); 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() });