network
The network component handles all communication between the client and the server. It includes low-level socket management, binary encoding/decoding via ByteBuffer and a novel anti-bot mechanism.
NetworkAdapter private
Methods
constructor()
function constructor(): voidInitializes a new EventEmitter as this.emitter and sets up a default handler for PACKET_BLEND.
sendEnterWorld()
function sendEnterWorld(data: object): voidSends a PACKET_ENTER_WORLD packet.
sendEnterWorld2()
function sendEnterWorld2(): voidSends a PACKET_ENTER_WORLD2 packet. No data is passed to this function.
sendInput()
function sendInput(data: Record<string, number>): voidSends a PACKET_INPUT packet containing player inputs. See inputPacketCreator for a list of possible input data.
sendPing()
function sendPing(data: object): voidSends a PACKET_PING packet.
sendRpc()
function sendRpc(data: CLIENT_RPC_DATA): voidSends a PACKET_RPC packet.
addEnterWorldHandler()
function addEnterWorldHandler(callback: (data: ENTER_WORLD_DATA) => void): voidRegisters a handler for PACKET_ENTER_WORLD responses.
addPreEnterWorldHandler()
function addPreEnterWorldHandler(callback: Function): voidRegisters a handler for PACKET_PRE_ENTER_WORLD responses.
addEntityUpdateHandler()
function addEntityUpdateHandler(callback: (data: ENTITY_UPDATE_DATA) => void): voidRegisters a handler for PACKET_ENTITY_UPDATE packets.
addPingHandler()
function addPingHandler(callback: (data: PING_DATA) => void): voidRegisters a handler for PACKET_PING packets.
addRpcHandler()
function addRpcHandler(name: string, callback: (data: SERVER_RPC_DATA) => void): voidRegisters a handler for a specific RPC response by name.
addConnectHandler()
function addConnectHandler(callback: Function): voidRegisters a handler for the connected WebSocket event.
addCloseHandler()
function addCloseHandler(callback: Function): voidRegisters a handler for the close WebSocket event.
addErrorHandler()
function addErrorHandler(callback: Function): voidRegisters a handler for the error WebSocket event.
addPacketHandler()
function addPacketHandler(event: number, callback: Function): voidRegisters a raw packet handler using the PacketId.
BinNetworkAdapter public
Bounded to game as game.network. Extends NetworkAdapter, alias: game.networkType
Properties
| Properties | Type | Description |
|---|---|---|
pingStart | Date \| null | The timestamp when the last ping was sent. |
pingCompletion | Date \| null | The timestamp when the last ping response was received. |
ping | number | The current round-trip time divided by 2 (latency). |
connected | boolean | Whether the socket is currently connected. |
connecting | boolean | Whether the socket is currently in the process of connecting. |
codec | BinCodec | The codec used for encoding and decoding binary packets. |
socket | WebSocket | The underlying WebSocket instance. |
connectionOptions | object | The options used for the current connection (hostname, port, etc.). |
Methods
connect()
function connect(options: object): voidInitiates a WebSocket connection to wss://{options.hostname}:{options.port}.
bindEventListeners()
function bindEventListeners(): voidBinds WebSocket events (open, message, close, error) to the internal emitter.
disconnect()
function disconnect(): voidCloses the WebSocket connection.
reconnect()
function reconnect(): voidAttempts to reconnect using the last used connectionOptions.
getPing()
function getPing(): numberReturns the current ping value.
sendPacket()
function sendPacket(event: number, data: object): voidEncodes the data using the codec and sends it over the WebSocket.
onMessage()
function onMessage(event: MessageEvent): voidHandles incoming WebSocket messages, decodes them, and emits the corresponding packet event.
sendPingIfNecessary()
function sendPingIfNecessary(): voidSends a ping packet if 5 seconds have passed since the last ping completion.
onPing()
function onPing(): voidCalculates the latency when a ping response is received.
Enumerations
PacketIds private
PacketIds is a set of constants representing the different types of packets sent and received by the network (each type of packet is referred to as a PacketId).
| Constant | Value | Description |
|---|---|---|
PACKET_ENTITY_UPDATE | 0 | Received every 50ms to update world entities. |
PACKET_PLAYER_COUNTER_UPDATE | 1 | Currently unused. |
PACKET_SET_WORLD_DIMENSIONS | 2 | Currently unused. |
PACKET_INPUT | 3 | Sent to the server containing player input. |
PACKET_ENTER_WORLD | 4 | Sent to request entry to the world & used by the anti-bot mechanism; also received as an enter world response. |
PACKET_PRE_ENTER_WORLD | 5 | Received before entering the world. |
PACKET_ENTER_WORLD2 | 6 | Used by the anti-bot mechanism. Is sent to the server after entering world. |
PACKET_PING | 7 | Used for latency measurement. |
| (no name set) | 8 | Supposedly used for skill points. See Skill Points. |
PACKET_RPC | 9 | Used for Remote Procedure Calls (RPC). |
PACKET_BLEND | 10 | Used by the anti-bot mechanism. Is received and sent at irregular intervals while in world. |
Data Interfaces
These are not present in the source code, but are inferred from the packets sent by the server.
Packet Interfaces
ENTER_WORLD_DATA
interface ENTER_WORLD_DATA {
allowed: boolean,
uid: string,
startingTick: number,
tickRate: number,
effectiveTickRate: number,
players: number,
maxPlayers: number,
chatChannel: number,
effectiveDisplayName: string,
x1: number,
y1: number,
x2: number,
y2: number,
opcode: number
}INFO
ENTER_WORLD_DATA also populates BinCodec's internal attributeMaps, entityTypeNames, sortedUidsByType, and rpcMaps / rpcMapsByName tables. These are not returned directly but are used by subsequent decodeEntityUpdate and decodeRpc calls.
ENTITY_UPDATE_DATA
interface ENTITY_UPDATE_DATA {
opcode: number,
tick: number,
entities: Record<string, ENTITY_DATA | true>,
byteSize: number
}TIP
When an entity is present in the update but has no changed attributes, it is stored as true instead of a full ENTITY_DATA object. This signals that the entity still exists but can reuse its previous tick data.
ENTITY_DATA
The shape of this object is dynamic as its keys are determined by the entity's attributeMap received during ENTER_WORLD_DATA. All entities include a uid field; the remaining fields depend on the entity type.
interface ENTITY_DATA {
uid: number,
[attributeName: string]: number | string | Vector2 | Vector2[] | number[]
}PING_DATA
interface PING_DATA {
opcode: number
}INFO
The ping response carries no payload as it is an empty object. The opcode field is added by the top-level decode() method.
RPC_DATA
interface SERVER_RPC_DATA {
opcode: number,
name: string,
response: Record<string, any> | Record<string, any>[]
}INFO
If the RPC is defined as an array type (isArray), response will be an array of objects. Otherwise it will be a single object.
interface CLIENT_RPC_DATA {
name: string,
[parameter: string]: string | number
}TIP
The shape of each RPC is determined by the RPC's parameters from rpcMaps. If the RPC is client-side, parameters will be injected directly into the RPC object. If it is a server-side RPC, parameters will be inside of response.