Files
fivem-rpc/rpc/readme.md
T
2026-09-28 02:05:40 +01:00

385 lines
7.9 KiB
Markdown

# FiveM RPC
is an all-in-one package with asynchronous RPC implementation for FiveM servers in JS/TS
Installation, quick start and package overview: [main readme](../readme.md). Typed events: [shared-types](../shared-types/readme.md).
## Exports
Besides `createRPC` the package exports:
- `RPCError`, `RPCErrors`, `RPCErrorDetails` - see [Errors](#errors)
- `RPCConfig`, `RPCEnvironment` and the instance types `RPCInstanceServer`, `RPCInstanceClient`, `RPCInstanceWebview`
- native event types `RPCNativeServerEvents`, `RPCNativeClientEvents`, `RPCNativeClientNetworkEvents`, `RPCNativeClientNetworkEventsNames` and the lists `NATIVE_SERVER_EVENTS`, `NATIVE_CLIENT_EVENTS`, `NATIVE_CLIENT_NETWORK_EVENTS` accepted by the `onNative*` methods
## RPCConfig
```ts
type RPCConfig = {
env: 'server' | 'client' | 'webview'
debug?: boolean // default false, logs every registration, call and incoming payload
timeout?: number // default 5000, ms to wait for a response, 0 disables it
}
```
An unknown `env` makes `createRPC` throw `RPCError` with code `RPCErrors.UNKNOWN_ENVIRONMENT`
## Errors
Every error from this library is an `RPCError`. `code` is one of `RPCErrors`, `message` says what to fix, and `details` names the call when the error comes from one
```ts
enum RPCErrors {
EVENT_NOT_REGISTERED = 'Event not registered',
UNKNOWN_NATIVE = 'Unknown native event',
UNKNOWN_ENVIRONMENT = 'Unknown environment',
TIMEOUT = 'Timed out waiting for response',
HANDLER_ERROR = 'Listener threw an error',
}
```
### Example error
The server has no `onClient('buyItem', ...)` listener, so the call from the client rejects:
```ts
import { RPCError, RPCErrors } from '@entityseven/fivem-rpc'
try {
await rpc.emitServer('buyItem', 'water')
} catch (e) {
if (e instanceof RPCError && e.code === RPCErrors.EVENT_NOT_REGISTERED) {
e.message // 'No listener for "buyItem" on server. Register it with rpc.onClient("buyItem", ...) in server code.'
e.details // { event: 'buyItem', uuid: '<uuid>', from: 'client', to: 'server' }
}
}
```
## Server ([source](src/core/server.ts))
### onClient
Listens to client event
```ts
rpc.onClient('clientServerEvent', (player, arg1, arg2, ...rest) => {
// logic
return someData // this will be forwarded back to caller
})
```
### offClient
Stops listening to client event
```ts
rpc.offClient('clientServerEvent')
```
### emitClient
Sends event to specified client
```ts
const response = await rpc.emitClient(playerServerId, 'serverClientEvent', someData)
// response will come from client listener with returned data
```
### emitClientEveryone
Sends event to all clients. One-way: clients run their listener but do not answer
```ts
await rpc.emitClientEveryone('serverClientEvent', someData)
```
### onWebview
Listens to webview event
```ts
rpc.onWebview('webviewServerEvent', (player, arg1, arg2, ...rest) => {
// logic
return someData // this will be forwarded back to caller
})
```
### offWebview
Stops listening to webview event
```ts
rpc.offWebview('webviewServerEvent')
```
### emitWebview
Sends event to the webview of specified player
```ts
const response = await rpc.emitWebview(playerServerId, 'serverWebviewEvent', someData)
// response will come from webview listener with returned data
```
### onSelf
Listens to server event
```ts
rpc.onSelf('serverEvent', (arg1, arg2, ...rest) => {
// logic
return someData // this will be forwarded back to caller
})
```
### offSelf
Stops listening to server event
```ts
rpc.offSelf('serverEvent')
```
### emitSelf
Sends event to server
```ts
const response = await rpc.emitSelf('serverEvent', someData)
// response will come from server listener with returned data
```
### onCommand
Registers chat command. `args` are the raw strings typed after the command, validate them yourself. With `restricted` set to `true` only players with the ACE permission `command.<name>` can use it (defaults to `false`)
```ts
rpc.onCommand('serverCommand', (player, args, rawCommand) => {
// logic
}, true /* restricted */)
```
### onNativeEvent
Listens to native server event ([reference](https://docs.fivem.net/docs/scripting-reference/events/server-events/))
```ts
rpc.onNativeEvent('playerJoining', (source, oldId) => {
// logic
})
```
## Client ([source](src/core/client.ts))
### onServer
Listens to server event
```ts
rpc.onServer('serverClientEvent', (arg1, arg2, ...rest) => {
// logic
return someData // this will be forwarded back to caller
})
```
### offServer
Stops listening to server event
```ts
rpc.offServer('serverClientEvent')
```
### emitServer
Sends event to server
```ts
const response = await rpc.emitServer('clientServerEvent', someData)
// response will come from server listener with returned data
```
### onWebview
Listens to webview event
```ts
rpc.onWebview('webviewClientEvent', (arg1, arg2, ...rest) => {
// logic
return someData // this will be forwarded back to caller
})
```
### offWebview
Stops listening to webview event
```ts
rpc.offWebview('webviewClientEvent')
```
### emitWebview
Sends event to own webview
```ts
const response = await rpc.emitWebview('clientWebviewEvent', someData)
// response will come from webview listener with returned data
```
### onSelf
Listens to client event
```ts
rpc.onSelf('clientEvent', (arg1, arg2, ...rest) => {
// logic
return someData // this will be forwarded back to caller
})
```
### offSelf
Stops listening to client event
```ts
rpc.offSelf('clientEvent')
```
### emitSelf
Sends event to client
```ts
const response = await rpc.emitSelf('clientEvent', someData)
// response will come from client listener with returned data
```
### onCommand
Registers chat command. `args` are the raw strings typed after the command, validate them yourself
```ts
rpc.onCommand('clientCommand', (player, args, rawCommand) => {
// logic
})
```
### onNativeEvent
Listens to native client event ([reference](https://docs.fivem.net/docs/scripting-reference/events/client-events/))
```ts
rpc.onNativeEvent('entityDamaged', (victim, culprit, weapon, baseDamage) => {
// logic
})
```
### onNativeNetworkEvent
Listens to native client network event ([reference](https://docs.fivem.net/docs/game-references/game-events/))
```ts
rpc.onNativeNetworkEvent('CEventShockingCarCrash', (entities, eventEntity, data) => {
// logic
})
```
### setWebviewFocus
Sets or removes focus and cursor from own webview
```ts
rpc.setWebviewFocus(true /* focus */, true /* show cursor */)
```
## Webview ([source](src/core/webview.ts))
### onClient
Listens to client event
```ts
rpc.onClient('clientWebviewEvent', (arg1, arg2, ...rest) => {
// logic
return someData // this will be forwarded back to caller
})
```
### offClient
Stops listening to client event
```ts
rpc.offClient('clientWebviewEvent')
```
### emitClient
Sends event to own client
```ts
const response = await rpc.emitClient('webviewClientEvent', someData)
// response will come from client listener with returned data
```
### onServer
Listens to server event
```ts
rpc.onServer('serverWebviewEvent', (arg1, arg2, ...rest) => {
// logic
return someData // this will be forwarded back to caller
})
```
### offServer
Stops listening to server event
```ts
rpc.offServer('serverWebviewEvent')
```
### emitServer
Sends event to server
```ts
const response = await rpc.emitServer('webviewServerEvent', someData)
// response will come from server listener with returned data
```
### onSelf
Listens to webview event
```ts
rpc.onSelf('webviewEvent', (arg1, arg2, ...rest) => {
// logic
return someData // this will be forwarded back to caller
})
```
### offSelf
Stops listening to webview event
```ts
rpc.offSelf('webviewEvent')
```
### emitSelf
Sends event to webview
```ts
const response = await rpc.emitSelf('webviewEvent', someData)
// response will come from webview listener with returned data
```
## License
Licensed under Custom Attribution-NoDerivs Software License