]> git.localhorst.tv Git - blank.git/blob - tst/net/PacketTest.cpp
3f47d0f9c4132085b420072a119397a0c1fc3207
[blank.git] / tst / net / PacketTest.cpp
1 #include "PacketTest.hpp"
2
3 #include "model/CompositeModel.hpp"
4 #include "world/Entity.hpp"
5
6 #include <limits>
7
8 CPPUNIT_TEST_SUITE_REGISTRATION(blank::test::PacketTest);
9
10 using namespace std;
11
12 namespace blank {
13 namespace test {
14
15 void PacketTest::setUp() {
16         udp_pack.data = new Uint8[sizeof(Packet)];
17         udp_pack.maxlen = sizeof(Packet);
18 }
19
20 void PacketTest::tearDown() {
21         delete[] udp_pack.data;
22 }
23
24 namespace {
25
26 static constexpr uint32_t TEST_TAG = 0xFB1AB1AF;
27
28 }
29
30 void PacketTest::testControl() {
31         Packet::TControl ctrl;
32         ctrl.ack = 10;
33
34         CPPUNIT_ASSERT_MESSAGE(
35                 "TControl should ack the packet in the ack field",
36                 ctrl.Acks(10)
37         );
38         CPPUNIT_ASSERT_MESSAGE(
39                 "TControl should ack the packet in the future",
40                 !ctrl.Acks(11)
41         );
42         CPPUNIT_ASSERT_MESSAGE(
43                 "TControl should not ack a packet in the distant past",
44                 !ctrl.Acks(-30)
45         );
46         CPPUNIT_ASSERT_MESSAGE(
47                 "TControl should not ack the previous packet if the bitfield is 0",
48                 !ctrl.Acks(9)
49         );
50         CPPUNIT_ASSERT_EQUAL_MESSAGE(
51                 "TControl's acks should begin at the packet in the ack field",
52                 uint16_t(10), ctrl.AckBegin()
53         );
54         CPPUNIT_ASSERT_EQUAL_MESSAGE(
55                 "TControl's acks should end 33 packets before the one in the ack field",
56                 uint16_t(-23), ctrl.AckEnd()
57         );
58         ctrl.hist = 1;
59         CPPUNIT_ASSERT_MESSAGE(
60                 "TControl should ack the previous packet if the bitfield is 1",
61                 ctrl.Acks(9)
62         );
63         ctrl.hist = 2;
64         CPPUNIT_ASSERT_MESSAGE(
65                 "TControl should not ack the previous packet if the bitfield is 2",
66                 !ctrl.Acks(9)
67         );
68         CPPUNIT_ASSERT_MESSAGE(
69                 "TControl should ack the packet before the previous one if the bitfield is 2",
70                 ctrl.Acks(8)
71         );
72 }
73
74 void PacketTest::testPing() {
75         auto pack = Packet::Make<Packet::Ping>(udp_pack);
76         AssertPacket("Ping", 0, 0, pack);
77 }
78
79 void PacketTest::testLogin() {
80         auto pack = Packet::Make<Packet::Login>(udp_pack);
81         AssertPacket("Login", 1, 0, 32, pack);
82
83         string write_name = "test";
84         string read_name;
85         pack.WritePlayerName(write_name);
86         pack.ReadPlayerName(read_name);
87         CPPUNIT_ASSERT_EQUAL_MESSAGE(
88                 "player name not correctly transported in Login packet",
89                 write_name, read_name
90         );
91
92         write_name = "0123456789012345678901234567890123456789";
93         pack.WritePlayerName(write_name);
94         pack.ReadPlayerName(read_name);
95         CPPUNIT_ASSERT_EQUAL_MESSAGE(
96                 "player name not correctly truncated in Login packet",
97                 write_name.substr(0, 32), read_name
98         );
99 }
100
101 void PacketTest::testJoin() {
102         auto pack = Packet::Make<Packet::Join>(udp_pack);
103         AssertPacket("Join", 2, 68, 100, pack);
104
105         Entity write_entity;
106         write_entity.ID(534574);
107         write_entity.GetState().chunk_pos = { 7, 2, -3 };
108         write_entity.GetState().block_pos = { 1.5f, 0.9f, 12.0f };
109         write_entity.GetState().velocity = { 0.025f, 0.001f, 0.0f };
110         write_entity.GetState().orient = { 1.0f, 0.0f, 0.0f, 0.0f };
111         write_entity.GetState().ang_vel = { 0.01f, 0.00302f, 0.0985f };
112         uint32_t read_id = 0;
113         EntityState read_state;
114         pack.WritePlayer(write_entity);
115
116         pack.ReadPlayerID(read_id);
117         CPPUNIT_ASSERT_EQUAL_MESSAGE(
118                 "player entity ID not correctly transported in Join packet",
119                 write_entity.ID(), read_id
120         );
121         pack.ReadPlayerState(read_state);
122         AssertEqual(
123                 "player entity state not correctly transported in Join packet",
124                 write_entity.GetState(), read_state
125         );
126
127         string write_name = "test";
128         string read_name;
129         pack.WriteWorldName(write_name);
130         pack.ReadWorldName(read_name);
131         CPPUNIT_ASSERT_EQUAL_MESSAGE(
132                 "world name not correctly transported in Join packet",
133                 write_name, read_name
134         );
135
136         write_name = "0123456789012345678901234567890123456789";
137         pack.WriteWorldName(write_name);
138         pack.ReadWorldName(read_name);
139         CPPUNIT_ASSERT_EQUAL_MESSAGE(
140                 "world name not correctly truncated in Join packet",
141                 write_name.substr(0, 32), read_name
142         );
143 }
144
145 void PacketTest::testPart() {
146         auto pack = Packet::Make<Packet::Part>(udp_pack);
147         AssertPacket("Part", 3, 0, pack);
148 }
149
150 void PacketTest::testPlayerUpdate() {
151         auto pack = Packet::Make<Packet::PlayerUpdate>(udp_pack);
152         AssertPacket("PlayerUpdate", 4, 64, pack);
153
154         Entity write_entity;
155         write_entity.ID(534574);
156         write_entity.GetState().chunk_pos = { 7, 2, -3 };
157         write_entity.GetState().block_pos = { 1.5f, 0.9f, 12.0f };
158         write_entity.GetState().velocity = { 0.025f, 0.001f, 0.0f };
159         write_entity.GetState().orient = { 1.0f, 0.0f, 0.0f, 0.0f };
160         write_entity.GetState().ang_vel = { 0.01f, 0.00302f, 0.0985f };
161         EntityState read_state;
162         pack.WritePlayer(write_entity);
163
164         pack.ReadPlayerState(read_state);
165         AssertEqual(
166                 "player entity state not correctly transported in PlayerUpdate packet",
167                 write_entity.GetState(), read_state
168         );
169 }
170
171 void PacketTest::testSpawnEntity() {
172         auto pack = Packet::Make<Packet::SpawnEntity>(udp_pack);
173         AssertPacket("SpawnEntity", 5, 100, 132, pack);
174
175         Entity write_entity;
176         write_entity.ID(534574);
177         CompositeModel model;
178         model.ID(23);
179         model.Instantiate(write_entity.GetModel());
180         write_entity.GetState().chunk_pos = { 7, 2, -3 };
181         write_entity.GetState().block_pos = { 1.5f, 0.9f, 12.0f };
182         write_entity.GetState().velocity = { 0.025f, 0.001f, 0.0f };
183         write_entity.GetState().orient = { 1.0f, 0.0f, 0.0f, 0.0f };
184         write_entity.GetState().ang_vel = { 0.01f, 0.00302f, 0.0985f };
185         write_entity.Bounds({{ -1, -1, -1 }, { 1, 1, 1 }});
186         write_entity.WorldCollidable(true);
187         write_entity.Name("blah");
188         pack.WriteEntity(write_entity);
189
190         uint32_t entity_id;
191         uint32_t skeleton_id;
192         Entity read_entity;
193         pack.ReadEntityID(entity_id);
194         pack.ReadSkeletonID(skeleton_id);
195         pack.ReadEntity(read_entity);
196
197         CPPUNIT_ASSERT_EQUAL_MESSAGE(
198                 "entity ID not correctly transported in SpawnEntity packet",
199                 write_entity.ID(), entity_id
200         );
201         CPPUNIT_ASSERT_EQUAL_MESSAGE(
202                 "skeleton ID not correctly transported in SpawnEntity packet",
203                 write_entity.GetModel().GetModel().ID(), skeleton_id
204         );
205         AssertEqual(
206                 "entity state not correctly transported in PlayerUpdate packet",
207                 write_entity.GetState(), read_entity.GetState()
208         );
209         AssertEqual(
210                 "entity bounds not correctly transported in PlayerUpdate packet",
211                 write_entity.Bounds(), read_entity.Bounds()
212         );
213         CPPUNIT_ASSERT_MESSAGE(
214                 "entity flags not correctly transported in SpawnEntity packet",
215                 read_entity.WorldCollidable()
216         );
217         CPPUNIT_ASSERT_EQUAL_MESSAGE(
218                 "entity name not correctly transported in SpawnEntity packet",
219                 write_entity.Name(), read_entity.Name()
220         );
221 }
222
223 void PacketTest::testDespawnEntity() {
224         auto pack = Packet::Make<Packet::DespawnEntity>(udp_pack);
225         AssertPacket("DespawnEntity", 6, 4, pack);
226
227         uint32_t write_id = 5437;
228         uint32_t read_id;
229         pack.WriteEntityID(write_id);
230         pack.ReadEntityID(read_id);
231
232         CPPUNIT_ASSERT_EQUAL_MESSAGE(
233                 "entity ID not correctly transported in DespawnEntity packet",
234                 write_id, read_id
235         );
236 }
237
238 void PacketTest::testEntityUpdate() {
239         auto pack = Packet::Make<Packet::EntityUpdate>(udp_pack);
240         AssertPacket("EntityUpdate", 7, 4, 452, pack);
241
242         pack.length = Packet::EntityUpdate::GetSize(3);
243         CPPUNIT_ASSERT_EQUAL_MESSAGE(
244                 "length not correctly set in DespawnEntity packet",
245                 size_t(4 + 3 * 68), pack.length
246         );
247
248         uint32_t write_count = 3;
249         uint32_t read_count;
250         pack.WriteEntityCount(write_count);
251         pack.ReadEntityCount(read_count);
252         CPPUNIT_ASSERT_EQUAL_MESSAGE(
253                 "entity count not correctly transported in EntityUpdate packet",
254                 write_count, read_count
255         );
256
257         Entity write_entity;
258         write_entity.ID(8567234);
259         write_entity.GetState().chunk_pos = { 7, 2, -3 };
260         write_entity.GetState().block_pos = { 1.5f, 0.9f, 12.0f };
261         write_entity.GetState().velocity = { 0.025f, 0.001f, 0.0f };
262         write_entity.GetState().orient = { 1.0f, 0.0f, 0.0f, 0.0f };
263         write_entity.GetState().ang_vel = { 0.01f, 0.00302f, 0.0985f };
264         pack.WriteEntity(write_entity, 1);
265         pack.WriteEntity(write_entity, 0);
266         pack.WriteEntity(write_entity, 2);
267
268         uint32_t read_id;
269         EntityState read_state;
270         pack.ReadEntityID(read_id, 1);
271         pack.ReadEntityState(read_state, 1);
272         CPPUNIT_ASSERT_EQUAL_MESSAGE(
273                 "entity ID not correctly transported in EntityUpdate packet",
274                 write_entity.ID(), read_id
275         );
276         AssertEqual(
277                 "entity state not correctly transported in EntityUpdate packet",
278                 write_entity.GetState(), read_state
279         );
280 }
281
282 void PacketTest::testPlayerCorrection() {
283         auto pack = Packet::Make<Packet::PlayerCorrection>(udp_pack);
284         AssertPacket("PlayerCorrection", 8, 66, pack);
285
286         uint16_t write_seq = 50050;
287         uint16_t read_seq;
288         pack.WritePacketSeq(write_seq);
289         pack.ReadPacketSeq(read_seq);
290         CPPUNIT_ASSERT_EQUAL_MESSAGE(
291                 "packet sequence not correctly transported in PlayerCorrection packet",
292                 write_seq, read_seq
293         );
294
295         Entity write_entity;
296         write_entity.GetState().chunk_pos = { 7, 2, -3 };
297         write_entity.GetState().block_pos = { 1.5f, 0.9f, 12.0f };
298         write_entity.GetState().velocity = { 0.025f, 0.001f, 0.0f };
299         write_entity.GetState().orient = { 1.0f, 0.0f, 0.0f, 0.0f };
300         write_entity.GetState().ang_vel = { 0.01f, 0.00302f, 0.0985f };
301         pack.WritePlayer(write_entity);
302
303         EntityState read_state;
304         pack.ReadPlayerState(read_state);
305         AssertEqual(
306                 "entity state not correctly transported in PlayerCorrection packet",
307                 write_entity.GetState(), read_state
308         );
309 }
310
311 void PacketTest::testChunkBegin() {
312         auto pack = Packet::Make<Packet::ChunkBegin>(udp_pack);
313         AssertPacket("ChunkBegin", 9, 24, pack);
314
315         uint32_t write_id = 532;
316         uint32_t write_flags = 9864328;
317         glm::ivec3 write_pos = { -6, 15, 38 };
318         uint32_t write_size = 4097;
319
320         pack.WriteTransmissionId(write_id);
321         pack.WriteFlags(write_flags);
322         pack.WriteChunkCoords(write_pos);
323         pack.WriteDataSize(write_size);
324
325         uint32_t read_id;
326         uint32_t read_flags;
327         glm::ivec3 read_pos;
328         uint32_t read_size;
329
330         pack.ReadTransmissionId(read_id);
331         pack.ReadFlags(read_flags);
332         pack.ReadChunkCoords(read_pos);
333         pack.ReadDataSize(read_size);
334
335         CPPUNIT_ASSERT_EQUAL_MESSAGE(
336                 "transmission ID not correctly transported in ChunkBegin packet",
337                 write_id, read_id
338         );
339         CPPUNIT_ASSERT_EQUAL_MESSAGE(
340                 "flags not correctly transported in ChunkBegin packet",
341                 write_flags, read_flags
342         );
343         AssertEqual(
344                 "chunk coordinates not correctly transported in ChunkBegin packet",
345                 write_pos, read_pos
346         );
347         CPPUNIT_ASSERT_EQUAL_MESSAGE(
348                 "data size not correctly transported in ChunkBegin packet",
349                 write_size, read_size
350         );
351 }
352
353 void PacketTest::testChunkData() {
354         auto pack = Packet::Make<Packet::ChunkData>(udp_pack);
355         AssertPacket("ChunkData", 10, 12, 484, pack);
356
357         constexpr size_t block_size = 97;
358
359         uint32_t write_id = 6743124;
360         uint32_t write_offset = 8583;
361         uint32_t write_size = block_size;
362         uint8_t write_data[block_size];
363         memset(write_data, 'X', block_size);
364
365         pack.WriteTransmissionId(write_id);
366         pack.WriteDataOffset(write_offset);
367         pack.WriteDataSize(write_size);
368         pack.WriteData(write_data, write_size);
369
370         uint32_t read_id;
371         uint32_t read_offset;
372         uint32_t read_size;
373         uint8_t read_data[block_size];
374
375         pack.ReadTransmissionId(read_id);
376         pack.ReadDataOffset(read_offset);
377         pack.ReadDataSize(read_size);
378         pack.ReadData(read_data, read_size);
379
380         CPPUNIT_ASSERT_EQUAL_MESSAGE(
381                 "transmission ID not correctly transported in ChunkData packet",
382                 write_id, read_id
383         );
384         CPPUNIT_ASSERT_EQUAL_MESSAGE(
385                 "data offset not correctly transported in ChunkData packet",
386                 write_offset, read_offset
387         );
388         CPPUNIT_ASSERT_EQUAL_MESSAGE(
389                 "data size not correctly transported in ChunkData packet",
390                 write_size, read_size
391         );
392         CPPUNIT_ASSERT_EQUAL_MESSAGE(
393                 "raw data not correctly transported in ChunkData packet",
394                 string(write_data, write_data + write_size), string(read_data, read_data + read_size)
395         );
396 }
397
398
399 void PacketTest::AssertPacket(
400         const string &name,
401         uint8_t expected_type,
402         size_t expected_length,
403         const Packet::Payload &actual
404 ) {
405         CPPUNIT_ASSERT_EQUAL_MESSAGE(
406                 name + " packet not correctly tagged",
407                 TEST_TAG, actual.GetHeader().tag
408         );
409         CPPUNIT_ASSERT_EQUAL_MESSAGE(
410                 "wrong type code for " + name + " packet",
411                 int(expected_type), int(actual.GetHeader().type)
412         );
413         CPPUNIT_ASSERT_EQUAL_MESSAGE(
414                 "bad payload length for " + name + " packet",
415                 expected_length, actual.length
416         );
417 }
418
419 void PacketTest::AssertPacket(
420         const string &name,
421         uint8_t expected_type,
422         size_t min_length,
423         size_t max_length,
424         const Packet::Payload &actual
425 ) {
426         CPPUNIT_ASSERT_EQUAL_MESSAGE(
427                 name + " packet not correctly tagged",
428                 TEST_TAG, actual.GetHeader().tag
429         );
430         CPPUNIT_ASSERT_EQUAL_MESSAGE(
431                 "wrong type code for " + name + " packet",
432                 expected_type, actual.GetHeader().type
433         );
434         CPPUNIT_ASSERT_MESSAGE(
435                 "bad payload length for " + name + " packet",
436                 actual.length >= min_length && actual.length <= max_length
437         );
438 }
439
440 void PacketTest::AssertEqual(
441         const string &message,
442         const EntityState &expected,
443         const EntityState &actual
444 ) {
445         AssertEqual(
446                 message + ": bad chunk position",
447                 expected.chunk_pos, actual.chunk_pos
448         );
449         AssertEqual(
450                 message + ": bad block position",
451                 expected.block_pos, actual.block_pos
452         );
453         AssertEqual(
454                 message + ": bad velocity",
455                 expected.velocity, actual.velocity
456         );
457         AssertEqual(
458                 message + ": bad orientation",
459                 expected.orient, actual.orient
460         );
461         AssertEqual(
462                 message + ": bad angular velocity",
463                 expected.ang_vel, actual.ang_vel
464         );
465 }
466
467 void PacketTest::AssertEqual(
468         const string &message,
469         const AABB &expected,
470         const AABB &actual
471 ) {
472         AssertEqual(
473                 message + ": bad lower bound",
474                 expected.min, actual.min
475         );
476         AssertEqual(
477                 message + ": bad upper bound",
478                 expected.max, actual.max
479         );
480 }
481
482 void PacketTest::AssertEqual(
483         const string &message,
484         const glm::ivec3 &expected,
485         const glm::ivec3 &actual
486 ) {
487         CPPUNIT_ASSERT_EQUAL_MESSAGE(
488                 message + " (X component)",
489                 expected.x, actual.x
490         );
491         CPPUNIT_ASSERT_EQUAL_MESSAGE(
492                 message + " (Y component)",
493                 expected.y, actual.y
494         );
495         CPPUNIT_ASSERT_EQUAL_MESSAGE(
496                 message + " (Z component)",
497                 expected.z, actual.z
498         );
499 }
500
501 void PacketTest::AssertEqual(
502         const string &message,
503         const glm::vec3 &expected,
504         const glm::vec3 &actual
505 ) {
506         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
507                 message + " (X component)",
508                 expected.x, actual.x, numeric_limits<float>::epsilon()
509         );
510         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
511                 message + " (Y component)",
512                 expected.y, actual.y, numeric_limits<float>::epsilon()
513         );
514         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
515                 message + " (Z component)",
516                 expected.z, actual.z, numeric_limits<float>::epsilon()
517         );
518 }
519
520 void PacketTest::AssertEqual(
521         const string &message,
522         const glm::quat &expected,
523         const glm::quat &actual
524 ) {
525         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
526                 message + " (W component)",
527                 expected.w, actual.w, numeric_limits<float>::epsilon()
528         );
529         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
530                 message + " (X component)",
531                 expected.x, actual.x, numeric_limits<float>::epsilon()
532         );
533         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
534                 message + " (Y component)",
535                 expected.y, actual.y, numeric_limits<float>::epsilon()
536         );
537         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(
538                 message + " (Z component)",
539                 expected.z, actual.z, numeric_limits<float>::epsilon()
540         );
541 }
542
543 }
544 }