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+