diff --git a/apps/cef/src/App.tsx b/apps/cef/src/App.tsx index c95e5af..16c6cef 100644 --- a/apps/cef/src/App.tsx +++ b/apps/cef/src/App.tsx @@ -5,7 +5,7 @@ function App() { const [data, setData] = useState('') useEffect(() => { - rpc.callClient('cefReady', []) + rpc.callClient('cefReady') rpc.register('customCefEvent', args => setData(args)) }, []) diff --git a/apps/rpc/index.d.ts b/apps/rpc/index.d.ts index 3ac3864..e5d2117 100644 --- a/apps/rpc/index.d.ts +++ b/apps/rpc/index.d.ts @@ -1,8 +1,22 @@ -import '@ragempcommunity/types-cef' -import '@ragempcommunity/types-client' -import '@ragempcommunity/types-server' +export {} -declare const mp: Mp -declare const global: Record unknown> -declare const window: Record unknown> -declare const console: { log: (...args: any[]) => void } +interface Mp { + trigger(event: string, data?: any): void + events: { + add(event: string, data: any): void + call(event: string, data: any): void + callRemote(event: string, data: any): void + } + joaat?: unknown + game: { + joaat?: unknown + } +} + +declare global { + const mp: Mp + const global: Record unknown> + interface Window { + [p: string]: any + } +} diff --git a/apps/rpc/package.json b/apps/rpc/package.json index 55859b4..10913d3 100644 --- a/apps/rpc/package.json +++ b/apps/rpc/package.json @@ -12,9 +12,6 @@ ], "devDependencies": { "@microsoft/api-extractor": "^7.47.9", - "@ragempcommunity/types-client": "^2.1.8", - "@ragempcommunity/types-server": "^2.1.8", - "@ragempcommunity/types-cef": "^2.1.8", "prettier": "^3.3.2", "tsup": "^8.3.0" }, diff --git a/apps/rpc/src/index.ts b/apps/rpc/src/index.ts index de2dbe0..e5b7982 100644 --- a/apps/rpc/src/index.ts +++ b/apps/rpc/src/index.ts @@ -1,6 +1,12 @@ import { Wrapper } from './wrapper' -import type { Player, PlayerServer } from './utils' -import { Environment, Errors, Events, RPCState, Utils } from './utils' +import { + Environment, + Errors, + Events, + RPCState, + Utils, + type PlayerMp, +} from './utils' import { server } from './server' import { client } from './client' @@ -19,10 +25,13 @@ class Rpc extends Wrapper { mp.events.add( Events.LOCAL_EVENT_LISTENER, - async (player: Player, dataRaw: string) => { + async (player: PlayerMp | string, dataRaw: string) => { switch (this.environment_) { case Environment.SERVER: - server.resolveEmitDestination(player, dataRaw) + server.resolveEmitDestination( + player as PlayerMp, + dataRaw, + ) break case Environment.CLIENT: @@ -43,28 +52,49 @@ class Rpc extends Wrapper { ) } - public register( - eventName: string, - cb: (...args: unknown[]) => unknown, + public register< + CallbackArguments extends unknown[] = unknown[], + CallbackReturn extends unknown = unknown, + EventName extends string = string, + >( + eventName: EventName, + cb: (...args: CallbackArguments) => CallbackReturn, ): void { Utils.errorUnknownEnvironment(this.environment_) this.state_[eventName] = cb } - public unregister(eventName: string): void { + public unregister( + eventName: EventName, + ): void { Utils.errorUnknownEnvironment(this.environment_) delete this.state_[eventName] } + public callClient< + Arguments extends unknown[] = unknown[], + EventName extends string = string, + >(eventName: EventName, args?: Arguments): void + public callClient< + Arguments extends unknown[] = unknown[], + EventName extends string = string, + >(player: PlayerMp, eventName: EventName, args?: Arguments): void public callClient( - playerOrEventName: Player, - eventNameOrArgs: string | unknown[], + playerOrEventName: PlayerMp | string, + eventNameOrArgs?: string | unknown[], args?: unknown[], - ) { + ): void { Utils.errorUnknownEnvironment(this.environment_) + function _is1StParamPlayer(x: unknown): x is PlayerMp { + return typeof x === 'object' + } + function _is2NdParamEventName(x: unknown): x is string { + return !Array.isArray(x) && typeof x === 'string' + } + // client if (this.environment_ === Environment.CLIENT) { this.call(playerOrEventName as string, args as unknown[]) @@ -72,10 +102,14 @@ class Rpc extends Wrapper { } // server - if (this.environment_ === Environment.SERVER) { + if ( + this.environment_ === Environment.SERVER && + _is1StParamPlayer(playerOrEventName) && + _is2NdParamEventName(eventNameOrArgs) + ) { const state: RPCState = { uuid: Utils.generateUUID(), - eventName: eventNameOrArgs as string, + eventName: eventNameOrArgs, calledTo: Environment.CLIENT, calledFrom: this.environment_, knownError: undefined, @@ -84,22 +118,23 @@ class Rpc extends Wrapper { const dataRaw = Utils.prepareTransfer(state) - ;(playerOrEventName as PlayerServer).call( - Events.LOCAL_EVENT_LISTENER, - [dataRaw], - ) + playerOrEventName.call(Events.LOCAL_EVENT_LISTENER, [dataRaw]) return } // browser - if (this.environment_ === Environment.BROWSER) { + if ( + this.environment_ === Environment.BROWSER && + !_is1StParamPlayer(playerOrEventName) && + !_is2NdParamEventName(eventNameOrArgs) + ) { const state: RPCState = { uuid: Utils.generateUUID(), - eventName: playerOrEventName as string, + eventName: playerOrEventName, calledTo: Environment.CLIENT, calledFrom: this.environment_, knownError: undefined, - data: eventNameOrArgs as unknown[], + data: eventNameOrArgs, } const dataRaw = Utils.prepareTransfer(state) @@ -109,7 +144,10 @@ class Rpc extends Wrapper { } } - public callServer(eventName: string, args: unknown[]) { + public callServer< + Arguments extends unknown[] = unknown[], + EventName extends string = string, + >(eventName: EventName, args?: Arguments) { Utils.errorUnknownEnvironment(this.environment_) const state: RPCState = { @@ -130,7 +168,10 @@ class Rpc extends Wrapper { } } - public callBrowser(eventName: string, args: unknown[]) { + public callBrowser< + Arguments extends unknown[] = unknown[], + EventName extends string = string, + >(eventName: EventName, args?: Arguments) { Utils.errorUnknownEnvironment(this.environment_) const state: RPCState = { @@ -151,7 +192,10 @@ class Rpc extends Wrapper { } } - public call(eventName: string, args: unknown[]) { + public call< + Arguments extends unknown[] = unknown[], + EventName extends string = string, + >(eventName: EventName, args?: Arguments) { Utils.errorUnknownEnvironment(this.environment_) let state: RPCState = { diff --git a/apps/rpc/src/server.ts b/apps/rpc/src/server.ts index 58a4b3f..c453d3a 100644 --- a/apps/rpc/src/server.ts +++ b/apps/rpc/src/server.ts @@ -1,6 +1,5 @@ import { Wrapper } from './wrapper' -import type { Player, PlayerServer } from './utils' -import { Environment, Events, Utils } from './utils' +import { Environment, Events, Utils, type PlayerMp } from './utils' class Server extends Wrapper { constructor() { @@ -8,13 +7,13 @@ class Server extends Wrapper { mp.events.add( Events.SERVER_EVENT_LISTENER, - async (player: PlayerServer, dataRaw: string) => { + async (player: PlayerMp, dataRaw: string) => { this.emit(player, dataRaw) }, ) } - public resolveEmitDestination(player: Player, dataRaw: string) { + public resolveEmitDestination(player: PlayerMp, dataRaw: string) { let state = Utils.prepareExecution(dataRaw) switch (state.calledTo) { @@ -23,16 +22,16 @@ class Server extends Wrapper { break default: - this.emitClient(player as PlayerServer, dataRaw) + this.emitClient(player as PlayerMp, dataRaw) break } } - private emitClient(player: PlayerServer, dataRaw: string) { + private emitClient(player: PlayerMp, dataRaw: string) { player.call(Events.LOCAL_EVENT_LISTENER, [dataRaw]) } - private emit(player: Player, dataRaw: string) { + private emit(player: PlayerMp, dataRaw: string) { let state = Utils.prepareExecution(dataRaw) state = this.verifyEvent_(state) diff --git a/apps/rpc/src/utils.ts b/apps/rpc/src/utils.ts index fffb575..958a703 100644 --- a/apps/rpc/src/utils.ts +++ b/apps/rpc/src/utils.ts @@ -22,9 +22,12 @@ export enum Errors { export class Utils { public static getEnvironment(): Environment { if ('joaat' in mp) return Environment.SERVER - if ('game' in mp && 'joaat' in (mp.game as { joaat?: unknown })) + if ( + 'game' in mp && + 'joaat' in (mp as { game: { joaat?: unknown } }).game + ) return Environment.CLIENT - if ('mp' in window) return Environment.BROWSER + if (window && 'mp' in window) return Environment.BROWSER return Environment.UNKNOWN } @@ -74,7 +77,6 @@ export type RPCState = { calledTo: Environment } -export interface Player {} -export interface PlayerServer extends Player { - call(eventName: string, args: unknown[]): void +export type PlayerMp = { + call(event: string, args?: unknown[]): void } diff --git a/apps/rpc/tsconfig.json b/apps/rpc/tsconfig.json index f6ed9e9..7f0dfdc 100644 --- a/apps/rpc/tsconfig.json +++ b/apps/rpc/tsconfig.json @@ -3,7 +3,10 @@ "target": "es6", "module": "commonjs", "moduleResolution": "node", - "lib": ["ES6"], + "lib": [ + "ES6", + "dom" + ], "declaration": true, "declarationMap": true, "sourceMap": true, @@ -20,6 +23,7 @@ "./index.d.ts" ], "exclude": [ - "node_modules" + "node_modules", + "dist" ] } \ No newline at end of file diff --git a/apps/server/src/index.ts b/apps/server/src/index.ts index 5a3870e..6cf6673 100644 --- a/apps/server/src/index.ts +++ b/apps/server/src/index.ts @@ -1,10 +1,10 @@ import { rpc } from 'rpc' -rpc.register('playerJoin', async player => { +rpc.register('playerJoin', async (player: PlayerMp) => { console.log(`Connected: ${player.socialClub}`) }) -rpc.register('customServerEvent', (player, data) => { +rpc.register('customServerEvent', (player: PlayerMp, data) => { console.log(player, data) rpc.callClient(player, 'customClientEvent', ['server to client'])