commit 6546eeb

uint  ·  2026-08-02 19:40:30 +0000 UTC
parent 44531aa
add packet reading headers
3 files changed,  +175, -0
+46, -0
 1@@ -0,0 +1,46 @@
 2+#ifndef PACKET_H
 3+#define PACKET_H
 4+
 5+#include <stddef.h>
 6+
 7+#include "types.h"
 8+
 9+typedef struct {
10+	const u8* data;
11+	size_t    size;
12+	size_t    cursor;
13+} PacketReader;
14+
15+/* initialize a packet reader */
16+PacketReader packet_reader_init(const void* data, size_t size);
17+
18+/* read an unsigned 8bit integer from the packet.
19+   returns 1 on success, 0 on failure */
20+i8 packet_read_u8(PacketReader* reader, u8* value);
21+
22+/* read an unsigned 16bit integer from the packet.
23+   returns 1 on success, 0 on failure */
24+i8 packet_read_u16(PacketReader* reader, u16* value);
25+
26+/* read a signed 32bit integer from the packet.
27+   returns 1 on success, 0 on failure */
28+i8 packet_read_i32(PacketReader* reader, i32* value);
29+
30+/* read an unsigned 64bit integer from the packet.
31+   returns 1 on success, 0 on failure */
32+i8 packet_read_u64(PacketReader* reader, u64* value);
33+
34+/* read a single precision float from the packet.
35+   returns 1 on success, 0 on failure */
36+i8 packet_read_f32(PacketReader* reader, float* value);
37+
38+/* read a double precision float from the packet.
39+   returns 1 on success, 0 on failure */
40+i8 packet_read_f64(PacketReader* reader, double* value);
41+
42+/* read a variable length integer from the packet.
43+   returns 1 on success, 0 on failure */
44+i8 packet_read_varint(PacketReader* reader, i32* value);
45+
46+#endif /* PACKET_H */
47+
+1, -0
1@@ -27,6 +27,7 @@ sources = [
2 	'source/mcproto/buffer.c',
3 	'source/mcproto/client.c',
4 	'source/mcproto/crypto.c',
5+	'source/mcproto/packet.c',
6 	'source/platform/platform.c',
7 	'vendor/stb_image_c89.c',
8 ]
+128, -0
  1@@ -0,0 +1,128 @@
  2+#include <string.h>
  3+
  4+#include "mcproto/packet.h"
  5+
  6+/* read a number of bytes from packet, copy them to output.
  7+   returns 1 on success, 0 on failure */
  8+static i8 packet_read(PacketReader* reader, void* output, size_t size);
  9+
 10+static i8 packet_read(PacketReader* reader, void* output, size_t size)
 11+{
 12+	if (reader->cursor > reader->size)
 13+		return 0;
 14+
 15+	if (size > reader->size - reader->cursor)
 16+		return 0;
 17+
 18+	memcpy(output, reader->data + reader->cursor, size);
 19+	reader->cursor += size;
 20+	return 1;
 21+}
 22+
 23+
 24+PacketReader packet_reader_init(const void* data, size_t size)
 25+{
 26+	PacketReader reader = { data, size, 0 };
 27+	return reader;
 28+}
 29+
 30+i8 packet_read_u8(PacketReader* reader, u8* value)
 31+{
 32+	return packet_read(reader, value, 1);
 33+}
 34+
 35+i8 packet_read_u16(PacketReader* reader, u16* value)
 36+{
 37+	u8 data[2];
 38+
 39+	if (!packet_read(reader, data, 2))
 40+		return 0;
 41+
 42+	*value =
 43+		((u16)data[0] << 8) |
 44+		(u16)data[1];
 45+
 46+	return 1;
 47+}
 48+
 49+i8 packet_read_i32(PacketReader* reader, i32* value)
 50+{
 51+	u8 data[4];
 52+	u32 result;
 53+
 54+	if (!packet_read(reader, data, 4))
 55+		return 0;
 56+
 57+	result =
 58+	    ((u32)data[0] << 24) |
 59+	    ((u32)data[1] << 16) |
 60+	    ((u32)data[2] << 8) |
 61+	    (u32)data[3];
 62+
 63+	*value = (i32)result;
 64+	return 1;
 65+}
 66+
 67+i8 packet_read_u64(PacketReader* reader, u64* value)
 68+{
 69+	u8 data[8];
 70+	u64 result;
 71+	i32 i;
 72+
 73+	if (!packet_read(reader, data, 8))
 74+		return 0;
 75+
 76+	result = 0;
 77+
 78+	for (i = 0; i < 8; i++)
 79+		result = (result << 8) | data[i];
 80+
 81+	*value = result;
 82+	return 1;
 83+}
 84+
 85+i8 packet_read_f32(PacketReader* reader, float* value)
 86+{
 87+	i32 bits;
 88+
 89+	if (!packet_read_i32(reader, &bits))
 90+		return 0;
 91+
 92+	memcpy(value, &bits, sizeof(*value));
 93+	return 1;
 94+}
 95+
 96+i8 packet_read_f64(PacketReader* reader, double* value)
 97+{
 98+	u64 bits;
 99+
100+	if (!packet_read_u64(reader, &bits))
101+		return 0;
102+
103+	memcpy(value, &bits, sizeof(*value));
104+	return 1;
105+}
106+
107+i8 packet_read_varint(PacketReader* reader, i32* value)
108+{
109+	u32 result;
110+	u8 byte;
111+	i32 shift;
112+
113+	result = 0;
114+
115+	for (shift = 0; shift < 7*5; shift += 7) { /* varints have max 5 bytes */
116+		if (!packet_read_u8(reader, &byte))
117+			return 0;
118+
119+		result |= (u32)(byte & 0x7f) << shift;
120+
121+		if (!(byte & 0x80)) { /* last byte */
122+			*value = (i32)result;
123+			return 1;
124+		}
125+	}
126+
127+	return 0;
128+}
129+