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