PocketMine-MP 5.23.3 git-f7687af337d001ddbcc47b8e773f014a33faa662
Loading...
Searching...
No Matches
AcknowledgePacket.php
1<?php
2
3/*
4 * This file is part of RakLib.
5 * Copyright (C) 2014-2022 PocketMine Team <https://github.com/pmmp/RakLib>
6 *
7 * RakLib is not affiliated with Jenkins Software LLC nor RakNet.
8 *
9 * RakLib is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 */
14
15declare(strict_types=1);
16
17namespace raklib\protocol;
18
20use function chr;
21use function count;
22use function sort;
23use const SORT_NUMERIC;
24
25abstract class AcknowledgePacket extends Packet{
26 private const RECORD_TYPE_RANGE = 0;
27 private const RECORD_TYPE_SINGLE = 1;
28
30 public array $packets = [];
31
32 protected function encodePayload(PacketSerializer $out) : void{
33 $payload = "";
34 sort($this->packets, SORT_NUMERIC);
35 $count = count($this->packets);
36 $records = 0;
37
38 if($count > 0){
39 $pointer = 1;
40 $start = $this->packets[0];
41 $last = $this->packets[0];
42
43 while($pointer < $count){
44 $current = $this->packets[$pointer++];
45 $diff = $current - $last;
46 if($diff === 1){
47 $last = $current;
48 }elseif($diff > 1){ //Forget about duplicated packets (bad queues?)
49 if($start === $last){
50 $payload .= chr(self::RECORD_TYPE_SINGLE);
51 $payload .= Binary::writeLTriad($start);
52 $start = $last = $current;
53 }else{
54 $payload .= chr(self::RECORD_TYPE_RANGE);
55 $payload .= Binary::writeLTriad($start);
56 $payload .= Binary::writeLTriad($last);
57 $start = $last = $current;
58 }
59 ++$records;
60 }
61 }
62
63 if($start === $last){
64 $payload .= chr(self::RECORD_TYPE_SINGLE);
65 $payload .= Binary::writeLTriad($start);
66 }else{
67 $payload .= chr(self::RECORD_TYPE_RANGE);
68 $payload .= Binary::writeLTriad($start);
69 $payload .= Binary::writeLTriad($last);
70 }
71 ++$records;
72 }
73
74 $out->putShort($records);
75 $out->put($payload);
76 }
77
78 protected function decodePayload(PacketSerializer $in) : void{
79 $count = $in->getShort();
80 $this->packets = [];
81 $cnt = 0;
82 for($i = 0; $i < $count and !$in->feof() and $cnt < 4096; ++$i){
83 if($in->getByte() === self::RECORD_TYPE_RANGE){
84 $start = $in->getLTriad();
85 $end = $in->getLTriad();
86 if(($end - $start) > 512){
87 $end = $start + 512;
88 }
89 for($c = $start; $c <= $end; ++$c){
90 $this->packets[$cnt++] = $c;
91 }
92 }else{
93 $this->packets[$cnt++] = $in->getLTriad();
94 }
95 }
96 }
97}