Skip to content

Commit

Permalink
shared: add RPC
Browse files Browse the repository at this point in the history
  • Loading branch information
xLuxy committed Sep 29, 2023
1 parent 734647c commit eda208f
Show file tree
Hide file tree
Showing 8 changed files with 267 additions and 91 deletions.
236 changes: 146 additions & 90 deletions client/src/CV8Resource.cpp

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions client/src/CV8Resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class CV8ResourceImpl : public V8ResourceImpl, public IImportHandler
}
}

void HandleRPCAnswer(const alt::CServerScriptRPCAnswerEvent* ev);
std::vector<V8Helpers::EventCallback*> GetWebViewHandlers(alt::IWebView* view, const std::string& name);

void SubscribeWebSocketClient(alt::IWebSocketClient* webSocket, const std::string& evName, v8::Local<v8::Function> cb, V8Helpers::SourceLocation&& location)
Expand Down
21 changes: 21 additions & 0 deletions client/src/bindings/ClientBindingsMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,24 @@ static void EmitServer(const v8::FunctionCallbackInfo<v8::Value>& info)
alt::ICore::Instance().TriggerServerEvent(eventName, args);
}

static void EmitRPC(const v8::FunctionCallbackInfo<v8::Value>& info)
{
V8_GET_ISOLATE_CONTEXT_RESOURCE();

V8_CHECK_ARGS_LEN_MIN(1);
V8_ARG_TO_STRING(1, rpcName);

alt::MValueArgs args;
for(int i = 1; i < info.Length(); ++i)
args.emplace_back(V8Helpers::V8ToMValue(info[i], false));

auto answerId = alt::ICore::Instance().TriggerServerRPCEvent(rpcName, args);
auto persistent = V8Helpers::CPersistent<v8::Promise::Resolver>(isolate, v8::Promise::Resolver::New(ctx).ToLocalChecked());

V8ResourceImpl::rpcHandlers[answerId] = persistent;
V8_RETURN(persistent.Get(isolate)->GetPromise());
}

static void EmitServerRaw(const v8::FunctionCallbackInfo<v8::Value>& info)
{
V8_GET_ISOLATE_CONTEXT_RESOURCE();
Expand Down Expand Up @@ -1209,6 +1227,9 @@ extern V8Module altModule("alt",
V8Helpers::RegisterFunc(exports, "onceServer", &OnceServer);
V8Helpers::RegisterFunc(exports, "offServer", &OffServer);
V8Helpers::RegisterFunc(exports, "emitServer", &EmitServer);

V8Helpers::RegisterFunc(exports, "emitRpc", &EmitRPC);

V8Helpers::RegisterFunc(exports, "emitServerRaw", &EmitServerRaw);
V8Helpers::RegisterFunc(exports, "emitServerUnreliable", &EmitServerUnreliable);
V8Helpers::RegisterFunc(exports, "gameControlsEnabled", &GameControlsEnabled);
Expand Down
46 changes: 46 additions & 0 deletions server/src/CNodeResourceImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ bool CNodeResourceImpl::Stop()
uv_loop_close(uvLoop);
delete uvLoop;

vehiclePassengers.clear();
rpcHandlers.clear();

return true;
}

Expand Down Expand Up @@ -142,6 +145,11 @@ void CNodeResourceImpl::OnEvent(const alt::CEvent* e)

HandleVehiclePassengerSeatEvents(e);

if (e->GetType() == alt::CEvent::Type::CLIENT_SCRIPT_RPC_EVENT)
{
HandleClientRpcEvent((alt::CClientScriptRPCEvent*)e);
}

V8Helpers::EventHandler* handler = V8Helpers::EventHandler::Get(e);
if(!handler) return;

Expand Down Expand Up @@ -237,6 +245,44 @@ void CNodeResourceImpl::HandleVehiclePassengerSeatEvents(const alt::CEvent* ev)
}
}

void CNodeResourceImpl::HandleClientRpcEvent(alt::CClientScriptRPCEvent* ev)
{
auto handler = rpcHandlers.find(ev->GetName());

if (handler == rpcHandlers.end())
return;

auto context = GetContext();
auto isolate = GetIsolate();

std::vector<v8::Local<v8::Value>> args;
args.push_back(GetBaseObjectOrNull(ev->GetTarget()));
V8Helpers::MValueArgsToV8(ev->GetArgs(), args);

v8::TryCatch tryCatch(isolate);
auto result = V8Helpers::CallFunctionWithTimeout(handler->second.Get(isolate), context, args);

alt::MValue returnValue;

if (!result.IsEmpty())
returnValue = V8Helpers::V8ToMValue(result.ToLocalChecked());
else
returnValue = V8Helpers::V8ToMValue(v8::Undefined(isolate));

ev->WillAnswer();

std::string errorMessage;
if (tryCatch.HasCaught())
{
errorMessage = "Unknown error";

if (!tryCatch.Message().IsEmpty())
errorMessage = *v8::String::Utf8Value(isolate, tryCatch.Message()->Get());
}

alt::ICore::Instance().TriggerClientRPCAnswer(ev->GetTarget(), ev->GetAnswerID(), returnValue, errorMessage);
}

void CNodeResourceImpl::OnTick()
{
v8::Locker locker(isolate);
Expand Down
2 changes: 2 additions & 0 deletions server/src/CNodeResourceImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class CNodeResourceImpl : public V8ResourceImpl

void OnEvent(const alt::CEvent* ev) override;
void HandleVehiclePassengerSeatEvents(const alt::CEvent* ev);
void HandleClientRpcEvent(alt::CClientScriptRPCEvent* ev);

void OnTick() override;

bool MakeClient(alt::IResource::CreationInfo* info, std::vector<std::string>) override;
Expand Down
39 changes: 39 additions & 0 deletions server/src/bindings/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,43 @@ static void EmitAllClientsUnreliable(const v8::FunctionCallbackInfo<v8::Value>&
ICore::Instance().TriggerClientEventUnreliableForAll(eventName, args);
}

static void OnRpc(const v8::FunctionCallbackInfo<v8::Value>& info)
{
V8_GET_ISOLATE_CONTEXT();
V8_CHECK_ARGS_LEN(2);

V8_ARG_TO_STRING(1, rpcName);
V8_ARG_TO_FUNCTION(2, callback);

V8_CHECK(!V8ResourceImpl::rpcHandlers.contains(rpcName), "Handler already registered");

V8ResourceImpl::rpcHandlers[rpcName] = v8::Global<v8::Function>(isolate, callback);
}

static void OffRpc(const v8::FunctionCallbackInfo<v8::Value>& info)
{
V8_GET_ISOLATE_CONTEXT_RESOURCE();
V8_CHECK_ARGS_LEN_MIN_MAX(1, 2);

V8_ARG_TO_STRING(1, rpcName);

if (V8ResourceImpl::rpcHandlers.contains(rpcName))
{
if (info[1]->IsFunction())
{
V8_ARG_TO_FUNCTION(2, callback);

if(V8ResourceImpl::rpcHandlers[rpcName].Get(isolate)->StrictEquals(callback))
V8ResourceImpl::rpcHandlers.erase(rpcName);

return;
}

V8ResourceImpl::rpcHandlers.erase(rpcName);
}

}

static void SetSyncedMeta(const v8::FunctionCallbackInfo<v8::Value>& info)
{
V8_GET_ISOLATE_CONTEXT();
Expand Down Expand Up @@ -802,6 +839,8 @@ extern V8Module
V8Helpers::RegisterFunc(exports, "emitClientUnreliable", &EmitClientUnreliable);
V8Helpers::RegisterFunc(exports, "emitAllClientsUnreliable", &EmitAllClientsUnreliable);

V8Helpers::RegisterFunc(exports, "onRpc", &OnRpc);
V8Helpers::RegisterFunc(exports, "offRpc", &OffRpc);
V8Helpers::RegisterFunc(exports, "setSyncedMeta", &SetSyncedMeta);
V8Helpers::RegisterFunc(exports, "deleteSyncedMeta", &DeleteSyncedMeta);

Expand Down
7 changes: 6 additions & 1 deletion shared/IRuntimeEventHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ class IRuntimeEventHandler
EventType::CONNECTION_COMPLETE, EventType::DISCONNECT_EVENT, EventType::GAME_ENTITY_CREATE, EventType::GAME_ENTITY_DESTROY, EventType::RESOURCE_STOP
#ifdef ALT_SERVER_API
// required for vehicle seat stuff
, EventType::PLAYER_ENTER_VEHICLE, EventType::PLAYER_LEAVE_VEHICLE, EventType::PLAYER_CHANGE_VEHICLE_SEAT
, EventType::PLAYER_ENTER_VEHICLE, EventType::PLAYER_LEAVE_VEHICLE, EventType::PLAYER_CHANGE_VEHICLE_SEAT,

// RPC events
EventType::CLIENT_SCRIPT_RPC_EVENT
#else
, EventType::SERVER_SCRIPT_RPC_ANSWER_EVENT
#endif
};

Expand Down
6 changes: 6 additions & 0 deletions shared/V8ResourceImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,13 @@ class V8ResourceImpl : public alt::IResource::Impl
}

#ifdef ALT_SERVER_API
// Vehicle passengers
static inline std::unordered_map<alt::IVehicle*, std::unordered_map<uint8_t, alt::IPlayer*>> vehiclePassengers{};

// rpcs
static inline std::unordered_map<std::string, v8::Global<v8::Function>> rpcHandlers{};
#else
static inline std::unordered_map<uint16_t, V8Helpers::CPersistent<v8::Promise::Resolver>> rpcHandlers{};
#endif

protected:
Expand Down

0 comments on commit eda208f

Please sign in to comment.