mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-07 18:32:55 +00:00
Deglobalize ItemTypeDictionary usage, at least for the protocol
while this is a bit hacky outside of the protocol namespace, it makes it much easier to use the protocol library for alternative purposes, such as for a client or MITM proxy. It also removes all but one remaining core dependency of the protocol library, making it very close to being able to be separated from the server core entirely.
This commit is contained in:
@ -42,8 +42,8 @@ class PacketBatch{
|
||||
* @phpstan-return \Generator<int, array{Packet, string}, void, void>
|
||||
* @throws PacketDecodeException
|
||||
*/
|
||||
public function getPackets(PacketPool $packetPool, int $max) : \Generator{
|
||||
$serializer = new PacketSerializer($this->buffer);
|
||||
public function getPackets(PacketPool $packetPool, PacketSerializerContext $decoderContext, int $max) : \Generator{
|
||||
$serializer = PacketSerializer::decoder($this->buffer, 0, $decoderContext);
|
||||
for($c = 0; $c < $max and !$serializer->feof(); ++$c){
|
||||
try{
|
||||
$buffer = $serializer->getString();
|
||||
@ -64,10 +64,10 @@ class PacketBatch{
|
||||
*
|
||||
* @return PacketBatch
|
||||
*/
|
||||
public static function fromPackets(Packet ...$packets) : self{
|
||||
$serializer = new PacketSerializer();
|
||||
public static function fromPackets(PacketSerializerContext $context, Packet ...$packets) : self{
|
||||
$serializer = PacketSerializer::encoder($context);
|
||||
foreach($packets as $packet){
|
||||
$subSerializer = new PacketSerializer();
|
||||
$subSerializer = PacketSerializer::encoder($context);
|
||||
$packet->encode($subSerializer);
|
||||
$serializer->putString($subSerializer->getBuffer());
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ use pocketmine\nbt\LittleEndianNbtSerializer;
|
||||
use pocketmine\nbt\NbtDataException;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\TreeRoot;
|
||||
use pocketmine\network\mcpe\convert\GlobalItemTypeDictionary;
|
||||
use pocketmine\network\mcpe\protocol\PacketDecodeException;
|
||||
use pocketmine\network\mcpe\protocol\types\BoolGameRule;
|
||||
use pocketmine\network\mcpe\protocol\types\command\CommandOriginData;
|
||||
@ -71,10 +70,20 @@ use function substr;
|
||||
class PacketSerializer extends BinaryStream{
|
||||
|
||||
private int $shieldItemRuntimeId;
|
||||
private PacketSerializerContext $context;
|
||||
|
||||
public function __construct(string $buffer = "", int $offset = 0){
|
||||
protected function __construct(PacketSerializerContext $context, string $buffer = "", int $offset = 0){
|
||||
parent::__construct($buffer, $offset);
|
||||
$this->shieldItemRuntimeId = GlobalItemTypeDictionary::getInstance()->getDictionary()->fromStringId("minecraft:shield");
|
||||
$this->context = $context;
|
||||
$this->shieldItemRuntimeId = $context->getItemDictionary()->fromStringId("minecraft:shield");
|
||||
}
|
||||
|
||||
public static function encoder(PacketSerializerContext $context) : self{
|
||||
return new self($context);
|
||||
}
|
||||
|
||||
public static function decoder(string $buffer, int $offset, PacketSerializerContext $context) : self{
|
||||
return new self($context, $buffer, $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -248,9 +257,8 @@ class PacketSerializer extends BinaryStream{
|
||||
$readExtraCrapInTheMiddle($this);
|
||||
|
||||
$blockRuntimeId = $this->getVarInt();
|
||||
$extraData = new PacketSerializer($this->getString());
|
||||
$shieldItemRuntimeId = $this->shieldItemRuntimeId;
|
||||
return (static function() use ($extraData, $id, $meta, $count, $blockRuntimeId, $shieldItemRuntimeId) : ItemStack{
|
||||
$extraData = self::decoder($this->getString(), 0, $this->context);
|
||||
return (static function() use ($extraData, $id, $meta, $count, $blockRuntimeId) : ItemStack{
|
||||
$nbtLen = $extraData->getLShort();
|
||||
|
||||
/** @var CompoundTag|null $compound */
|
||||
@ -283,7 +291,7 @@ class PacketSerializer extends BinaryStream{
|
||||
}
|
||||
|
||||
$shieldBlockingTick = null;
|
||||
if($id === $shieldItemRuntimeId){
|
||||
if($id === $extraData->shieldItemRuntimeId){
|
||||
$shieldBlockingTick = $extraData->getLLong();
|
||||
}
|
||||
|
||||
@ -312,9 +320,9 @@ class PacketSerializer extends BinaryStream{
|
||||
$writeExtraCrapInTheMiddle($this);
|
||||
|
||||
$this->putVarInt($item->getBlockRuntimeId());
|
||||
$shieldItemRuntimeId = $this->shieldItemRuntimeId;
|
||||
$this->putString((static function() use ($item, $shieldItemRuntimeId) : string{
|
||||
$extraData = new PacketSerializer();
|
||||
$context = $this->context;
|
||||
$this->putString((static function() use ($item, $context) : string{
|
||||
$extraData = PacketSerializer::encoder($context);
|
||||
|
||||
$nbt = $item->getNbt();
|
||||
if($nbt !== null){
|
||||
@ -337,7 +345,7 @@ class PacketSerializer extends BinaryStream{
|
||||
}
|
||||
|
||||
$blockingTick = $item->getShieldBlockingTick();
|
||||
if($item->getId() === $shieldItemRuntimeId){
|
||||
if($item->getId() === $extraData->shieldItemRuntimeId){
|
||||
$extraData->putLLong($blockingTick ?? 0);
|
||||
}
|
||||
return $extraData->getBuffer();
|
||||
|
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe\protocol\serializer;
|
||||
|
||||
/**
|
||||
* Contains information for a packet serializer specific to a given game session needed for packet encoding and decoding,
|
||||
* such as a dictionary of item runtime IDs to their internal string IDs.
|
||||
*/
|
||||
final class PacketSerializerContext{
|
||||
|
||||
private ItemTypeDictionary $itemDictionary;
|
||||
|
||||
public function __construct(ItemTypeDictionary $itemDictionary){
|
||||
$this->itemDictionary = $itemDictionary;
|
||||
}
|
||||
|
||||
public function getItemDictionary() : ItemTypeDictionary{ return $this->itemDictionary; }
|
||||
}
|
Reference in New Issue
Block a user