diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3fd2069c3..beebc3a20 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -165,6 +165,9 @@ importers: '@types/node': specifier: ^22.5.2 version: 22.5.2 + nanoid: + specifier: ^5.0.7 + version: 5.0.7 devDependencies: tsx: specifier: ^4.19.0 @@ -2701,6 +2704,11 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + nanoid@5.0.7: + resolution: {integrity: sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==} + engines: {node: ^18 || >=20} + hasBin: true + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -6090,6 +6098,8 @@ snapshots: nanoid@3.3.7: {} + nanoid@5.0.7: {} + natural-compare@1.4.0: {} node-fetch@2.6.11: diff --git a/src/client/event/netEventController.ts b/src/client/event/netEventController.ts new file mode 100644 index 000000000..246379baa --- /dev/null +++ b/src/client/event/netEventController.ts @@ -0,0 +1,26 @@ +import { customAlphabet } from "nanoid"; + +function uniqueId() { + return customAlphabet("1234567890abcdef", 21); +} + +export function netEventController( + event: string, + ...args: any[] +): Promise { + // For now we just assume the world is perfect and we don't need to handle errors + // This will be fixed + return new Promise((resolve) => { + const eventId = uniqueId(); + const listenName = `${event}:${eventId}`; + + emitNet("removeEventListener", listenName, ...args); + + const eventListener = (data: TResponse) => { + removeEventListener(listenName, eventListener); + resolve(data); + }; + + onNet(listenName, eventListener); + }); +} diff --git a/src/client/handler/client-player.ts b/src/client/handler/client-player.ts new file mode 100644 index 000000000..a1d2818d2 --- /dev/null +++ b/src/client/handler/client-player.ts @@ -0,0 +1,12 @@ +import { netEventController } from "../event/netEventController"; + +type OpenPhoneData = { + message: string; +}; + +// asume this is an exported function +async function nuiProxyController(data: any) { + const resp = await netEventController("openPhone", data); + + console.log(resp.message); +} diff --git a/src/client/package.json b/src/client/package.json index b4d9c8830..b08aa5214 100644 --- a/src/client/package.json +++ b/src/client/package.json @@ -12,6 +12,7 @@ }, "dependencies": { "@citizenfx/client": "^2.0.4170-1", - "@types/node": "^22.5.2" + "@types/node": "^22.5.2", + "nanoid": "^5.0.7" } } diff --git a/src/server/event/context.ts b/src/server/event/context.ts new file mode 100644 index 000000000..ea0a573c7 --- /dev/null +++ b/src/server/event/context.ts @@ -0,0 +1,12 @@ +export type Context = { + source: number; +}; + +// We might be able to add a few more things here, like the phone number for example +export function getEventContext(): Context { + const _source = global.source; + + return { + source: _source, + }; +} diff --git a/src/server/event/eventController.ts b/src/server/event/eventController.ts index 0953d1104..625036608 100644 --- a/src/server/event/eventController.ts +++ b/src/server/event/eventController.ts @@ -1 +1,23 @@ -export function eventController() {} +import { type Context, getEventContext } from "./context"; + +type Event = { + body: T; + ctx: Context; +}; + +export function eventController( + event: string, + callback: (req: Event) => Promise, +) { + onNet(event, async (responseEvent: string, data: TData) => { + const ctx = getEventContext(); + + // TODO: Add status codes or something to the response + const response = await callback({ + body: data, + ctx: ctx, + }); + + return emitNet(responseEvent, ctx.source, response); + }); +} diff --git a/src/server/handler/player-handler.ts b/src/server/handler/player-handler.ts index 8b1378917..ce52fc9f8 100644 --- a/src/server/handler/player-handler.ts +++ b/src/server/handler/player-handler.ts @@ -1 +1,22 @@ +import { eventController } from "../event/eventController"; +type PlayerTest = { + name: string; + phoneNumber: string; +}; + +type PlayerTestResponse = { + message: string; +}; + +eventController( + "player:test", + async ({ ctx, body }) => { + console.log(ctx.source); + console.log(body.name, body.phoneNumber); + + return { + message: "Hello, World!", + }; + }, +);