Rpc integration + type fixes #3
							
								
								
									
										5
									
								
								rpc/src-old/events.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								rpc/src-old/events.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | export const EVENT_LISTENER = '__rpc:listener' | ||||||
|  | export const EVENT_RESPONSE = '__rpc:response' | ||||||
|  | export const CEF_EVENT_LISTENER = '__rpc:cef_listener' | ||||||
|  | 
 | ||||||
|  | export const CLIENT_ROUTER_LISTENER = '__rpc:clientRouter' | ||||||
							
								
								
									
										76
									
								
								rpc/src-old/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								rpc/src-old/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,76 @@ | |||||||
|  | import { Environment, utils } from './utils' | ||||||
|  | import { EVENT_LISTENER } from './events' | ||||||
|  | 
 | ||||||
|  | import { client } from './modules/client' | ||||||
|  | import { server } from './modules/server' | ||||||
|  | import { cef } from './modules/cef' | ||||||
|  | 
 | ||||||
|  | const environment = utils.getEnvironment() | ||||||
|  | 
 | ||||||
|  | const state = environment === Environment.CEF ? window : global | ||||||
|  | 
 | ||||||
|  | class rpc { | ||||||
|  |     constructor() { | ||||||
|  |         if (environment === Environment.UNKNOWN) return | ||||||
|  | 
 | ||||||
|  |         mp.events.add(EVENT_LISTENER, async (player: any, request: string) => { | ||||||
|  |             switch (environment) { | ||||||
|  |                 case Environment.SERVER: | ||||||
|  |                     await server.listenEvent(player, request) | ||||||
|  |                     break | ||||||
|  | 
 | ||||||
|  |                 case Environment.CLIENT: | ||||||
|  |                     request = player | ||||||
|  | 
 | ||||||
|  |                     await client.listenEvent(request) | ||||||
|  |                     break | ||||||
|  | 
 | ||||||
|  |                 case Environment.CEF: | ||||||
|  |                     request = player | ||||||
|  | 
 | ||||||
|  |                     await cef | ||||||
|  |             } | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public register<Callback extends any[] = unknown[], Return = unknown>( | ||||||
|  |         eventName: string, | ||||||
|  |         cb: (...args: Callback) => Return, | ||||||
|  |     ) { | ||||||
|  |         if (environment === Environment.UNKNOWN) return | ||||||
|  |         state[eventName] = cb | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public async callClient<Args extends any[] = unknown[], Return = unknown>( | ||||||
|  |         player: any, | ||||||
|  |         eventName: string, | ||||||
|  |         ...args: Args | ||||||
|  |     ): Promise<Return | unknown> { | ||||||
|  |         if (environment === Environment.UNKNOWN) return | ||||||
|  |         if (environment === Environment.SERVER) { | ||||||
|  |             return client.executeClient(player, eventName, args) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public async callServer<Args extends any[] = unknown[], Return = unknown>( | ||||||
|  |         eventName: string, | ||||||
|  |         ...args: Args | ||||||
|  |     ): Promise<Return | unknown> { | ||||||
|  |         switch (environment) { | ||||||
|  |             case Environment.UNKNOWN: | ||||||
|  |                 return | ||||||
|  | 
 | ||||||
|  |             case Environment.SERVER: | ||||||
|  |                 return | ||||||
|  | 
 | ||||||
|  |             case Environment.CEF: | ||||||
|  |                 return client | ||||||
|  | 
 | ||||||
|  |             case Environment.CLIENT: | ||||||
|  |                 return server.executeServer(eventName, args) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const testRpc = new rpc() | ||||||
|  | export { testRpc } | ||||||
							
								
								
									
										63
									
								
								rpc/src-old/utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								rpc/src-old/utils.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,63 @@ | |||||||
|  | import { EVENT_RESPONSE } from './events' | ||||||
|  | 
 | ||||||
|  | export enum Environment { | ||||||
|  |     CEF = 'CEF', | ||||||
|  |     CLIENT = 'CLIENT', | ||||||
|  |     SERVER = 'SERVER', | ||||||
|  |     UNKNOWN = 'UNKNOWN', | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export enum Errors { | ||||||
|  |     EVENT_NOT_REGISTERED = 'Event not registered', | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export type RPCState = { | ||||||
|  |     eventName: string | ||||||
|  |     uuid: string | ||||||
|  |     knownError?: string | ||||||
|  |     data?: any | ||||||
|  |     calledFrom: Environment | ||||||
|  |     calledTo: Environment | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class Utils { | ||||||
|  |     public getEnvironment(): Environment { | ||||||
|  |         if (mp.joaat) return Environment.SERVER | ||||||
|  |         if (mp.game && mp.game.joaat) return Environment.CLIENT | ||||||
|  |         if ('mp' in window) return Environment.CEF | ||||||
|  |         return Environment.UNKNOWN | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public prepareForExecute(data: string): RPCState { | ||||||
|  |         return JSON.parse(data) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public prepareForTransfer(data: RPCState): string { | ||||||
|  |         return JSON.stringify(data) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public generateUUID(): string { | ||||||
|  |         let uuid = '', | ||||||
|  |             random | ||||||
|  | 
 | ||||||
|  |         for (let i = 0; i < 32; i++) { | ||||||
|  |             random = (Math.random() * 16) | 0 | ||||||
|  | 
 | ||||||
|  |             if (i === 8 || i === 12 || i === 16 || i === 20) { | ||||||
|  |                 uuid += '-' | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             uuid += ( | ||||||
|  |                 i === 12 ? 4 : i === 16 ? (random & 3) | 8 : random | ||||||
|  |             ).toString(16) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return uuid | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public generateResponseEventName(uuid: string): string { | ||||||
|  |         return `${EVENT_RESPONSE}_${uuid}` | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export const utils = new Utils() | ||||||
							
								
								
									
										44
									
								
								rpc/src/client.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								rpc/src/client.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | |||||||
|  | import { utils } from './utils' | ||||||
|  | import type { RPCData } from './types' | ||||||
|  | 
 | ||||||
|  | export class Client { | ||||||
|  |     public async listen(data: string) { | ||||||
|  |         const parsedData = utils.parseData(data) | ||||||
|  |         await this.transferTo(parsedData) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private transferTo(data: RPCData) { | ||||||
|  |         switch (data.to) { | ||||||
|  |             case utils.environment.CLIENT: | ||||||
|  |                 return this.executeLocal(data) | ||||||
|  |             case utils.environment.CEF: | ||||||
|  |             // todo transfer to cef
 | ||||||
|  |             case utils.environment.SERVER: | ||||||
|  |             // todo transfer to server
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private async executeLocal(data: RPCData) { | ||||||
|  |         const state = | ||||||
|  |             utils.getEnvironment() === utils.environment.CEF | ||||||
|  |                 ? window.rpcEvents | ||||||
|  |                 : global.rpcEvents | ||||||
|  |         const fnResponse = await state[data.eventName](...data.data) | ||||||
|  | 
 | ||||||
|  |         const response = { | ||||||
|  |             data: fnResponse, | ||||||
|  |             ...data, | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         this.sendResponseToServer(response) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private sendResponseToServer(data: RPCData) { | ||||||
|  |         const eventName = utils.generateResponseEventName(data.uuid) | ||||||
|  |         const prepareForTransfer = utils.stringifyData(data) | ||||||
|  | 
 | ||||||
|  |         mp.events.callRemote(eventName, prepareForTransfer) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export const client = new Client() | ||||||
| @ -1,5 +1,3 @@ | |||||||
| export const EVENT_LISTENER = '__rpc:listener' | export const RPC_LISTENER = 'rpc::listener' | ||||||
| export const EVENT_RESPONSE = '__rpc:response' |  | ||||||
| export const CEF_EVENT_LISTENER = '__rpc:cef_listener' |  | ||||||
| 
 | 
 | ||||||
| export const CLIENT_ROUTER_LISTENER = '__rpc:clientRouter' | export const CLIENT_ROUTER_LISTENER = 'rpc::clientRouterListener' | ||||||
							
								
								
									
										122
									
								
								rpc/src/index.ts
									
									
									
									
									
								
							
							
						
						
									
										122
									
								
								rpc/src/index.ts
									
									
									
									
									
								
							| @ -1,76 +1,104 @@ | |||||||
|  | import { RPC_LISTENER } from './events' | ||||||
| import { Environment, utils } from './utils' | import { Environment, utils } from './utils' | ||||||
| import { EVENT_LISTENER } from './events' |  | ||||||
| 
 | 
 | ||||||
| import { client } from './modules/client' | import { client } from './client' | ||||||
| import { server } from './modules/server' | import { server } from './server' | ||||||
| import { cef } from './modules/cef' | import type { RPCData } from './types.ts' | ||||||
| 
 | 
 | ||||||
| const environment = utils.getEnvironment() | class FrameworkRpc { | ||||||
|  |     private readonly _environment: Environment | ||||||
|  |     private readonly _environmentGlobal: Record<string, Function> | ||||||
| 
 | 
 | ||||||
| const state = environment === Environment.CEF ? window : global |  | ||||||
| 
 |  | ||||||
| class rpc { |  | ||||||
|     constructor() { |     constructor() { | ||||||
|         if (environment === Environment.UNKNOWN) return |         this._environment = utils.getEnvironment() | ||||||
|  |         this._environmentGlobal = | ||||||
|  |             utils.getEnvironment() === utils.environment.CEF | ||||||
|  |                 ? window.rpcEvents | ||||||
|  |                 : global.rpcEvents | ||||||
| 
 | 
 | ||||||
|         mp.events.add(EVENT_LISTENER, async (player: any, request: string) => { |         mp.events.add(RPC_LISTENER, async (player: any, data: string) => { | ||||||
|             switch (environment) { |             switch (this._environment) { | ||||||
|                 case Environment.SERVER: |                 case utils.environment.UNKNOWN: | ||||||
|                     await server.listenEvent(player, request) |                     return | ||||||
|                     break |  | ||||||
| 
 | 
 | ||||||
|                 case Environment.CLIENT: |                 case utils.environment.CLIENT: | ||||||
|                     request = player |                     player = data | ||||||
|  |                     return client.listen(player) | ||||||
| 
 | 
 | ||||||
|                     await client.listenEvent(request) |                 case utils.environment.SERVER: | ||||||
|                     break |                     return server.listen(player, data) | ||||||
| 
 | 
 | ||||||
|                 case Environment.CEF: |                 case utils.environment.CEF: | ||||||
|                     request = player |  | ||||||
| 
 |  | ||||||
|                     await cef |  | ||||||
|             } |             } | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public register<Callback extends any[] = unknown[], Return = unknown>( |     public register<Args extends any[] = unknown[], Return = unknown>( | ||||||
|         eventName: string, |         eventName: string, | ||||||
|         cb: (...args: Callback) => Return, |         cb: (...args: Args) => Return, | ||||||
|     ) { |     ) { | ||||||
|         if (environment === Environment.UNKNOWN) return |         if (this._environment === utils.environment.UNKNOWN) return | ||||||
|         state[eventName] = cb |         this._environmentGlobal[eventName] = cb | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public async callClient<Args extends any[] = unknown[], Return = unknown>( |     public callClient<Args extends any[] = unknown[], Return = unknown>( | ||||||
|         player: any, |         player: any, | ||||||
|         eventName: string, |         eventName: string, | ||||||
|         ...args: Args |         ...args: Args | ||||||
|     ): Promise<Return | unknown> { |     ): Promise<Return | unknown> { | ||||||
|         if (environment === Environment.UNKNOWN) return |         return new Promise((resolve, _reject) => { | ||||||
|         if (environment === Environment.SERVER) { |             const uuid = utils.generateUUID() | ||||||
|             return client.executeClient(player, eventName, args) | 
 | ||||||
|         } |             const data: RPCData = { | ||||||
|  |                 uuid, | ||||||
|  |                 eventName, | ||||||
|  |                 from: this._environment, | ||||||
|  |                 to: utils.environment.CLIENT, | ||||||
|  |                 data: args, | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|     public async callServer<Args extends any[] = unknown[], Return = unknown>( |             player.call(RPC_LISTENER, [utils.stringifyData(data)]) | ||||||
|  | 
 | ||||||
|  |             const responseEventName = utils.generateResponseEventName(uuid) | ||||||
|  | 
 | ||||||
|  |             const handler = (_player: any, data: string) => { | ||||||
|  |                 resolve(utils.parseData(data).data) | ||||||
|  |                 mp.events.remove(responseEventName) | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             mp.events.add(responseEventName, handler) | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public callServer<Args extends any[] = unknown[], Return = unknown>( | ||||||
|         eventName: string, |         eventName: string, | ||||||
|         ...args: Args |         ...args: Args | ||||||
|     ): Promise<Return | unknown> { |     ): Promise<Return | unknown> { | ||||||
|         switch (environment) { |         return new Promise((resolve, _reject) => { | ||||||
|             case Environment.UNKNOWN: |             const uuid = utils.generateUUID() | ||||||
|                 return |  | ||||||
| 
 | 
 | ||||||
|             case Environment.SERVER: |             const data: RPCData = { | ||||||
|                 return |                 uuid, | ||||||
| 
 |                 eventName, | ||||||
|             case Environment.CEF: |                 from: this._environment, | ||||||
|                 return client |                 to: utils.environment.CLIENT, | ||||||
| 
 |                 data: args, | ||||||
|             case Environment.CLIENT: |  | ||||||
|                 return server.executeServer(eventName, args) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
| const testRpc = new rpc() |             mp.events.callRemote(RPC_LISTENER, utils.stringifyData(data)) | ||||||
| export { testRpc } | 
 | ||||||
|  |             const responseEventName = utils.generateResponseEventName(uuid) | ||||||
|  | 
 | ||||||
|  |             const handler = (_player: any, data: string) => { | ||||||
|  |                 resolve(utils.parseData(data).data) | ||||||
|  |                 mp.events.remove(responseEventName) | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             mp.events.add(responseEventName, handler) | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const rpc = new FrameworkRpc() | ||||||
|  | 
 | ||||||
|  | export { rpc } | ||||||
|  | |||||||
							
								
								
									
										33
									
								
								rpc/src/server.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								rpc/src/server.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | |||||||
|  | import { utils } from './utils' | ||||||
|  | import type { RPCData } from './types' | ||||||
|  | 
 | ||||||
|  | export class Server { | ||||||
|  |     public async listen(player: any, data: string) { | ||||||
|  |         const parsedData = utils.parseData(data) | ||||||
|  |         await this.executeLocal(player, parsedData) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private async executeLocal(player: any, data: RPCData) { | ||||||
|  |         const state = | ||||||
|  |             utils.getEnvironment() === utils.environment.CEF | ||||||
|  |                 ? window.rpcEvents | ||||||
|  |                 : global.rpcEvents | ||||||
|  |         const fnResponse = await state[data.eventName](...data.data) | ||||||
|  | 
 | ||||||
|  |         const response = { | ||||||
|  |             data: fnResponse, | ||||||
|  |             ...data, | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         this.sendResponseToClient(player, response) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private sendResponseToClient(player: any, data: RPCData) { | ||||||
|  |         const eventName = utils.generateResponseEventName(data.uuid) | ||||||
|  |         const prepareForTransfer = utils.stringifyData(data) | ||||||
|  | 
 | ||||||
|  |         player.call(eventName, prepareForTransfer) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export const server = new Server() | ||||||
							
								
								
									
										9
									
								
								rpc/src/types.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								rpc/src/types.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | import { Environment } from './utils' | ||||||
|  | 
 | ||||||
|  | export type RPCData = { | ||||||
|  |     data?: any | ||||||
|  |     from: Environment | ||||||
|  |     to: Environment | ||||||
|  |     eventName: string | ||||||
|  |     uuid: string | ||||||
|  | } | ||||||
| @ -1,4 +1,5 @@ | |||||||
| import { EVENT_RESPONSE } from './events' | import type { RPCData } from './types' | ||||||
|  | import { RPC_LISTENER } from './events' | ||||||
| 
 | 
 | ||||||
| export enum Environment { | export enum Environment { | ||||||
|     CEF = 'CEF', |     CEF = 'CEF', | ||||||
| @ -7,36 +8,7 @@ export enum Environment { | |||||||
|     UNKNOWN = 'UNKNOWN', |     UNKNOWN = 'UNKNOWN', | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export enum Errors { | function generateUUID(): string { | ||||||
|     EVENT_NOT_REGISTERED = 'Event not registered', |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export type RPCState = { |  | ||||||
|     eventName: string |  | ||||||
|     uuid: string |  | ||||||
|     knownError?: string |  | ||||||
|     data?: any |  | ||||||
|     calledFrom: Environment |  | ||||||
|     calledTo: Environment |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| class Utils { |  | ||||||
|     public getEnvironment(): Environment { |  | ||||||
|         if (mp.joaat) return Environment.SERVER |  | ||||||
|         if (mp.game && mp.game.joaat) return Environment.CLIENT |  | ||||||
|         if ('mp' in window) return Environment.CEF |  | ||||||
|         return Environment.UNKNOWN |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public prepareForExecute(data: string): RPCState { |  | ||||||
|         return JSON.parse(data) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public prepareForTransfer(data: RPCState): string { |  | ||||||
|         return JSON.stringify(data) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public generateUUID(): string { |  | ||||||
|     let uuid = '', |     let uuid = '', | ||||||
|         random |         random | ||||||
| 
 | 
 | ||||||
| @ -47,17 +19,24 @@ class Utils { | |||||||
|             uuid += '-' |             uuid += '-' | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|             uuid += ( |         uuid += (i === 12 ? 4 : i === 16 ? (random & 3) | 8 : random).toString( | ||||||
|                 i === 12 ? 4 : i === 16 ? (random & 3) | 8 : random |             16, | ||||||
|             ).toString(16) |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return uuid |     return uuid | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|     public generateResponseEventName(uuid: string): string { | export const utils = { | ||||||
|         return `${EVENT_RESPONSE}_${uuid}` |     environment: Environment, | ||||||
|  |     getEnvironment: () => { | ||||||
|  |         if (mp.joaat) return Environment.SERVER | ||||||
|  |         if (mp.game && mp.game.joaat) return Environment.CLIENT | ||||||
|  |         if ('mp' in window) return Environment.CEF | ||||||
|  |         return Environment.UNKNOWN | ||||||
|  |     }, | ||||||
|  |     parseData: (data: string): RPCData => JSON.parse(data), | ||||||
|  |     stringifyData: (data: RPCData): string => JSON.stringify(data), | ||||||
|  |     generateResponseEventName: (uuid: string) => `${RPC_LISTENER}_${uuid}`, | ||||||
|  |     generateUUID, | ||||||
| } | } | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export const utils = new Utils() |  | ||||||
|  | |||||||
| @ -13,10 +13,11 @@ | |||||||
| 
 | 
 | ||||||
|     "strict": true, |     "strict": true, | ||||||
|     "forceConsistentCasingInFileNames": true, |     "forceConsistentCasingInFileNames": true, | ||||||
|     "noImplicitAny": true |     "noImplicitAny": true, | ||||||
|   }, |   }, | ||||||
|   "include": [ |   "include": [ | ||||||
|     "src/**/*" |     "src/**/*", | ||||||
|  |     "./types.d.ts" | ||||||
|   ], |   ], | ||||||
|   "exclude": [ |   "exclude": [ | ||||||
|     "node_modules" |     "node_modules" | ||||||
|  | |||||||
							
								
								
									
										13
									
								
								rpc/types.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								rpc/types.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | |||||||
|  | declare const mp: any | ||||||
|  | declare const console: any | ||||||
|  | 
 | ||||||
|  | declare const setTimeout: (fn: Function, time: number) => number | ||||||
|  | declare const clearTimeout: (id: number) => void | ||||||
|  | 
 | ||||||
|  | declare const global: { | ||||||
|  |     rpcEvents: Record<string, (...args: any[]) => unknown> | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | declare const window: { | ||||||
|  |     rpcEvents: Record<string, (...args: any[]) => unknown> | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user