|
6 | 6 | namespace libproxy; |
7 | 7 |
|
8 | 8 | use Error; |
9 | | -use ErrorException; |
10 | 9 | use Exception; |
11 | 10 | use libproxy\data\LatencyData; |
12 | 11 | use libproxy\data\TickSyncPacket; |
|
18 | 17 | use libproxy\protocol\ProxyPacketSerializer; |
19 | 18 | use pmmp\thread\Thread as NativeThread; |
20 | 19 | use pmmp\thread\ThreadSafeArray; |
21 | | -use pocketmine\network\mcpe\compression\DecompressionException; |
22 | 20 | use pocketmine\network\mcpe\compression\ZlibCompressor; |
23 | 21 | use pocketmine\network\mcpe\convert\TypeConverter; |
24 | 22 | use pocketmine\network\mcpe\EntityEventBroadcaster; |
25 | 23 | use pocketmine\network\mcpe\NetworkSession; |
26 | 24 | use pocketmine\network\mcpe\PacketBroadcaster; |
27 | | -use pocketmine\network\mcpe\protocol\PacketDecodeException; |
28 | 25 | use pocketmine\network\mcpe\protocol\PacketPool; |
29 | | -use pocketmine\network\mcpe\protocol\serializer\PacketBatch; |
30 | | -use pocketmine\network\mcpe\protocol\types\CompressionAlgorithm; |
31 | 26 | use pocketmine\network\mcpe\raklib\PthreadsChannelReader; |
32 | 27 | use pocketmine\network\mcpe\raklib\PthreadsChannelWriter; |
33 | 28 | use pocketmine\network\NetworkInterface; |
|
37 | 32 | use pocketmine\Server; |
38 | 33 | use pocketmine\snooze\SleeperHandlerEntry; |
39 | 34 | use pocketmine\thread\ThreadCrashException; |
40 | | -use pocketmine\timings\Timings; |
41 | 35 | use pocketmine\utils\Binary; |
42 | 36 | use pocketmine\utils\BinaryDataException; |
43 | | -use pocketmine\utils\BinaryStream; |
44 | 37 | use Socket; |
45 | 38 | use ThreadedArray; |
46 | 39 | use WeakMap; |
47 | 40 | use function base64_encode; |
48 | 41 | use function bin2hex; |
49 | | -use function ord; |
50 | 42 | use function socket_close; |
51 | 43 | use function socket_create_pair; |
52 | 44 | use function socket_last_error; |
|
55 | 47 | use function strlen; |
56 | 48 | use function substr; |
57 | 49 | use function trim; |
58 | | -use function zstd_uncompress; |
59 | 50 | use const AF_INET; |
60 | 51 | use const AF_UNIX; |
61 | 52 | use const SOCK_STREAM; |
@@ -148,8 +139,6 @@ public function __construct(PluginBase $plugin, int $port, ?string $composerPath |
148 | 139 | $this->sendBytes = 0; |
149 | 140 | $this->receiveBytes = 0; |
150 | 141 | }), 20, 20); |
151 | | - |
152 | | - $server->getPluginManager()->registerEvents(new ProxyListener(), $plugin); |
153 | 142 | } |
154 | 143 |
|
155 | 144 | public static function handleRawLatency(NetworkSession $session, int $upstream, int $downstream): void |
@@ -217,82 +206,28 @@ private function onPacketReceive(string $buffer): void |
217 | 206 | break; |
218 | 207 | case ForwardPacket::NETWORK_ID: |
219 | 208 | /** @var ForwardPacket $pk */ |
220 | | - if (($session = $this->getSession($socketId)) === null) { |
| 209 | + if (($session = $this->getSession($socketId)) === null || !(fn() => $this->connected)->call($session)) { |
221 | 210 | break; // might be data arriving from the client after the server has closed the connection |
222 | 211 | } |
223 | 212 |
|
224 | | - $this->handleEncoded($session, $pk->payload); |
225 | | - $this->receiveBytes += strlen($pk->payload); |
226 | | - break; |
227 | | - } |
228 | | - } catch (PacketHandlingException|BinaryDataException $exception) { |
229 | | - $this->close($socketId, 'Error handling a Packet (Server)'); |
230 | | - |
231 | | - $this->server->getLogger()->logException($exception); |
232 | | - } |
233 | | - } |
234 | | - |
235 | | - /** |
236 | | - * @throws PacketHandlingException |
237 | | - */ |
238 | | - public function handleEncoded(NetworkSession $session, string $payload): void |
239 | | - { |
240 | | - if (!(fn() => $this->connected)->call($session)) { |
241 | | - return; |
242 | | - } |
243 | | - |
244 | | - Timings::$playerNetworkReceive->startTiming(); |
245 | | - try { |
246 | | - (fn() => $this->packetBatchLimiter->decrement())->call($session); |
247 | | - |
248 | | - if (strlen($payload) < 1) { |
249 | | - throw new PacketHandlingException("No bytes in payload"); |
250 | | - } |
251 | | - |
252 | | - Timings::$playerNetworkReceiveDecompress->startTiming(); |
253 | | - $compressionType = ord($payload[0]); |
254 | | - $compressed = substr($payload, 1); |
255 | | - |
256 | | - try { |
257 | | - $decompressed = match ($compressionType) { |
258 | | - CompressionAlgorithm::NONE => $compressed, |
259 | | - CompressionAlgorithm::ZLIB => $session->getCompressor()->decompress($compressed), |
260 | | - CompressionAlgorithm::NONE - 1 => ($d = zstd_uncompress($compressed)) === false ? throw new DecompressionException("Failed to decompress packet") : $d, |
261 | | - default => throw new PacketHandlingException("Packet compressed with unexpected compression type $compressionType") |
262 | | - }; |
263 | | - } catch (ErrorException|DecompressionException $e) { |
264 | | - $session->getLogger()->debug("Failed to decompress packet: " . base64_encode($compressed)); |
265 | | - throw PacketHandlingException::wrap($e, "Compressed packet batch decode error"); |
266 | | - } finally { |
267 | | - Timings::$playerNetworkReceiveDecompress->stopTiming(); |
268 | | - } |
269 | | - |
270 | | - try { |
271 | | - $stream = new BinaryStream($decompressed); |
272 | | - $count = 0; |
273 | | - foreach (PacketBatch::decodeRaw($stream) as $buffer) { |
274 | | - (fn() => $this->gamePacketLimiter->decrement())->call($session); |
275 | | - if (++$count > 100) { |
276 | | - throw new PacketHandlingException("Too many packets in batch"); |
277 | | - } |
278 | | - $packet = PacketPool::getInstance()->getPacket($buffer); |
| 213 | + $packet = PacketPool::getInstance()->getPacket($pk->payload); |
279 | 214 | if ($packet === null) { |
280 | | - $session->getLogger()->debug("Unknown packet: " . base64_encode($buffer)); |
| 215 | + $session->getLogger()->debug("Unknown packet: " . base64_encode($pk->payload)); |
281 | 216 | throw new PacketHandlingException("Unknown packet received"); |
282 | 217 | } |
283 | 218 | try { |
284 | | - $session->handleDataPacket($packet, $buffer); |
| 219 | + $session->handleDataPacket($packet, $pk->payload); |
285 | 220 | } catch (PacketHandlingException $e) { |
286 | | - $session->getLogger()->debug($packet->getName() . ": " . base64_encode($buffer)); |
| 221 | + $session->getLogger()->debug($packet->getName() . ": " . base64_encode($pk->payload)); |
287 | 222 | throw PacketHandlingException::wrap($e, "Error processing " . $packet->getName()); |
288 | 223 | } |
289 | | - } |
290 | | - } catch (PacketDecodeException|BinaryDataException $e) { |
291 | | - $session->getLogger()->logException($e); |
292 | | - throw PacketHandlingException::wrap($e, "Packet batch decode error"); |
| 224 | + $this->receiveBytes += strlen($pk->payload); |
| 225 | + break; |
293 | 226 | } |
294 | | - } finally { |
295 | | - Timings::$playerNetworkReceive->stopTiming(); |
| 227 | + } catch (PacketHandlingException|BinaryDataException $exception) { |
| 228 | + $this->close($socketId, 'Error handling a Packet (Server)'); |
| 229 | + |
| 230 | + $this->server->getLogger()->logException($exception); |
296 | 231 | } |
297 | 232 | } |
298 | 233 |
|
|
0 commit comments