-
Notifications
You must be signed in to change notification settings - Fork 3
/
mod.ts
126 lines (114 loc) · 5.05 KB
/
mod.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import * as serverbound_location_v1 from './packets/serverbound/v1/location'
import * as serverbound_party_info_v1 from './packets/serverbound/v1/party_info'
import * as serverbound_ping_v1 from './packets/serverbound/v1/ping'
import * as serverbound_player_info_v1 from './packets/serverbound/v1/player_info'
import * as clientbound_location_v1 from './packets/clientbound/v1/location'
import * as clientbound_party_info_v1 from './packets/clientbound/v1/party_info'
import * as clientbound_ping_v1 from './packets/clientbound/v1/ping'
import * as clientbound_player_info_v1 from './packets/clientbound/v1/player_info'
import { PacketReader, PacketWriter } from '@lilithmod/unborn-mcproto'
import { PacketError, PacketErrorId, getPacketErrorFromId, packetErrorToId } from './enums'
/**
* The base packet interface implemented by all packets.
* The version number is used to version the API on a per-packet basis.
*/
export interface VersionedPacket {
version: number
}
/**
* Represents a failed packet, which is returned when a packet is not successful.
* The numeric id is automatically converted to a string representation.
*/
export interface FailedPacket {
error: PacketError
}
/**
* Represents a packet utility, which reads and writes packets from a buffer.
*/
export interface PacketUtils<T> {
read(buffer: Buffer): T
write(packet: T): Buffer
}
export * from './enums'
/**
* A record of all serverbound packets, indexed by version number.
*/
export const serverboundPackets: Record<number, Record<string, PacketUtils<VersionedPacket>>> = {
1: {
location: serverbound_location_v1,
party_info: serverbound_party_info_v1,
ping: serverbound_ping_v1,
player_info: serverbound_player_info_v1
}
}
/**
* A record of all clientbound packets, indexed by version number.
* Using `readClientboundPacket` and `writeClientboundPacket` is recommended for reading and writing packets, especially for success byte and error handling in clientbound packets.
*/
export const clientboundPackets: Record<number, Record<string, PacketUtils<VersionedPacket>>> = {
1: {
location: clientbound_location_v1,
party_info: clientbound_party_info_v1,
ping: clientbound_ping_v1,
player_info: clientbound_player_info_v1
}
}
/**
* Reads a clientbound packet from a buffer.
* @param name This should be the plugin message name, minus the `hypixel:` prefix.
* @param buffer A buffer containing the entire packet data from the plugin message. The success byte should be the first entry in the buffer.
* @returns The packet read from the buffer, or a failed packet with an error if the packet was not successful.
*/
export function readClientboundPacket<T extends VersionedPacket>(name: string, buffer: Buffer): T | FailedPacket {
const success = buffer[0] === 1
const reader = new PacketReader(buffer.subarray(1))
const varint = reader.id
// If the packet was not successful, return an error instead of reading
if (!success) return { error: getPacketErrorFromId(varint) } as FailedPacket
return clientboundPackets[varint][name].read(buffer.subarray(1)) as T
}
/** Writes a clientbound packet to a buffer, assuming a true success byte.
* @param name This should be the plugin message name, minus the `hypixel:` prefix.
* @param packet The packet to write.
* @returns A buffer containing the packet data.
*/
export function writeClientboundPacket<T extends VersionedPacket>(name: string, packet: T): Buffer {
const buffer = clientboundPackets[packet.version][name].write(packet)
// Add a success byte to the start of the buffer
const newBuffer = Buffer.alloc(buffer.length + 1)
newBuffer[0] = 1
newBuffer.set(buffer, 1)
return newBuffer
}
/**
* Writes an unsuccessful clientbound packet to a buffer.
* @param error The error message to write.
* @returns
*/
export function writeClientboundError(error: PacketError | PacketErrorId): Buffer {
const writer = new PacketWriter(typeof error === 'number' ? error : packetErrorToId(error))
const buffer = Buffer.alloc(writer.buffer.length + 1)
buffer[0] = 0
buffer.set(writer.buffer, 1)
return buffer
}
/**
* Reads a serverbound packet from a buffer.
* @param name This should be the plugin message name, minus the `hypixel:` prefix.
* @param buffer A buffer containing the entire packet data from the plugin message. The version number should be the first entry in the buffer.
* @returns The packet read from the buffer.
*/
export function readServerboundPacket<T extends VersionedPacket>(name: string, buffer: Buffer): T {
const reader = new PacketReader(buffer)
const version = reader.id
return serverboundPackets[version][name].read(buffer) as T
}
/**
* Writes a serverbound packet to a buffer.
* @param name This should be the plugin message name, minus the `hypixel:` prefix.
* @param packet The packet to write.
* @returns A buffer containing the packet data.
*/
export function writeServerboundPacket<T extends VersionedPacket>(name: string, packet: T): Buffer {
return serverboundPackets[packet.version][name].write(packet)
}