From 968666b1d9773776b0d573400d0263488f1e9d89 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 16 Feb 2024 14:21:14 +0000 Subject: [PATCH] Properly handle netIDs of recipes, itemstacks, transactions and creative items these were all lumped into one previously (incorrectly), which caused various reading errors (which happened to work, but incorrectly), and also missed a decent amount of finesse (such as the request ID/server itemstack ID union stuff in the ItemStackRequest system). I omitted validation for these since what we really need is wrapper types, but that can wait for another time. --- src/InventoryTransactionPacket.php | 4 +- src/serializer/PacketSerializer.php | 54 ++++++++++++++++++- src/types/EnchantOption.php | 4 +- src/types/inventory/CreativeContentEntry.php | 4 +- src/types/inventory/ItemStackWrapper.php | 4 +- .../CraftRecipeAutoStackRequestAction.php | 4 +- .../CraftRecipeOptionalStackRequestAction.php | 4 +- .../CraftRecipeStackRequestAction.php | 4 +- .../CreativeCreateStackRequestAction.php | 4 +- .../GrindstoneStackRequestAction.php | 4 +- .../stackrequest/ItemStackRequest.php | 4 +- .../stackrequest/ItemStackRequestSlotInfo.php | 4 +- .../MineBlockStackRequestAction.php | 4 +- .../stackresponse/ItemStackResponse.php | 4 +- .../ItemStackResponseSlotInfo.php | 4 +- src/types/recipe/MultiRecipe.php | 4 +- src/types/recipe/ShapedRecipe.php | 4 +- src/types/recipe/ShapelessRecipe.php | 4 +- src/types/recipe/SmithingTransformRecipe.php | 4 +- src/types/recipe/SmithingTrimRecipe.php | 4 +- 20 files changed, 90 insertions(+), 40 deletions(-) diff --git a/src/InventoryTransactionPacket.php b/src/InventoryTransactionPacket.php index d3262fdd..22ab580f 100644 --- a/src/InventoryTransactionPacket.php +++ b/src/InventoryTransactionPacket.php @@ -54,7 +54,7 @@ public static function create(int $requestId, array $requestChangedSlots, Transa } protected function decodePayload(PacketSerializer $in) : void{ - $this->requestId = $in->readGenericTypeNetworkId(); + $this->requestId = $in->readLegacyItemStackRequestId(); $this->requestChangedSlots = []; if($this->requestId !== 0){ for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ @@ -77,7 +77,7 @@ protected function decodePayload(PacketSerializer $in) : void{ } protected function encodePayload(PacketSerializer $out) : void{ - $out->writeGenericTypeNetworkId($this->requestId); + $out->writeLegacyItemStackRequestId($this->requestId); if($this->requestId !== 0){ $out->putUnsignedVarInt(count($this->requestChangedSlots)); foreach($this->requestChangedSlots as $changedSlots){ diff --git a/src/serializer/PacketSerializer.php b/src/serializer/PacketSerializer.php index 08ddb3ee..a565b707 100644 --- a/src/serializer/PacketSerializer.php +++ b/src/serializer/PacketSerializer.php @@ -801,11 +801,61 @@ public function getNbtCompoundRoot() : CompoundTag{ } } - public function readGenericTypeNetworkId() : int{ + public function readRecipeNetId() : int{ + return $this->getUnsignedVarInt(); + } + + public function writeRecipeNetId(int $id) : void{ + $this->putUnsignedVarInt($id); + } + + public function readCreativeItemNetId() : int{ + return $this->getUnsignedVarInt(); + } + + public function writeCreativeItemNetId(int $id) : void{ + $this->putUnsignedVarInt($id); + } + + /** + * This is a union of ItemStackRequestId, LegacyItemStackRequestId, and ServerItemStackId, used in serverbound + * packets to allow the client to refer to server known items, or items which may have been modified by a previous + * as-yet unacknowledged request from the client. + */ + public function readItemStackNetIdVariant() : int{ + return $this->getVarInt(); + } + + /** + * This is a union of ItemStackRequestId, LegacyItemStackRequestId, and ServerItemStackId, used in serverbound + * packets to allow the client to refer to server known items, or items which may have been modified by a previous + * as-yet unacknowledged request from the client. + */ + public function writeItemStackNetIdVariant(int $id) : void{ + $this->putVarInt($id); + } + + public function readItemStackRequestId() : int{ + return $this->getVarInt(); + } + + public function writeItemStackRequestId(int $id) : void{ + $this->putVarInt($id); + } + + public function readLegacyItemStackRequestId() : int{ + return $this->getVarInt(); + } + + public function writeLegacyItemStackRequestId(int $id) : void{ + $this->putVarInt($id); + } + + public function readServerItemStackId() : int{ return $this->getVarInt(); } - public function writeGenericTypeNetworkId(int $id) : void{ + public function writeServerItemStackId(int $id) : void{ $this->putVarInt($id); } diff --git a/src/types/EnchantOption.php b/src/types/EnchantOption.php index 98648a8e..bd9b1a8b 100644 --- a/src/types/EnchantOption.php +++ b/src/types/EnchantOption.php @@ -80,7 +80,7 @@ public static function read(PacketSerializer $in) : self{ $selfActivatedEnchants = self::readEnchantList($in); $name = $in->getString(); - $optionId = $in->readGenericTypeNetworkId(); + $optionId = $in->readRecipeNetId(); return new self($cost, $slotFlags, $equipActivatedEnchants, $heldActivatedEnchants, $selfActivatedEnchants, $name, $optionId); } @@ -94,6 +94,6 @@ public function write(PacketSerializer $out) : void{ self::writeEnchantList($out, $this->selfActivatedEnchantments); $out->putString($this->name); - $out->writeGenericTypeNetworkId($this->optionId); + $out->writeRecipeNetId($this->optionId); } } diff --git a/src/types/inventory/CreativeContentEntry.php b/src/types/inventory/CreativeContentEntry.php index 007f7a11..e4714a13 100644 --- a/src/types/inventory/CreativeContentEntry.php +++ b/src/types/inventory/CreativeContentEntry.php @@ -27,13 +27,13 @@ public function getEntryId() : int{ return $this->entryId; } public function getItem() : ItemStack{ return $this->item; } public static function read(PacketSerializer $in) : self{ - $entryId = $in->readGenericTypeNetworkId(); + $entryId = $in->readCreativeItemNetId(); $item = $in->getItemStackWithoutStackId(); return new self($entryId, $item); } public function write(PacketSerializer $out) : void{ - $out->writeGenericTypeNetworkId($this->entryId); + $out->writeCreativeItemNetId($this->entryId); $out->putItemStackWithoutStackId($this->item); } } diff --git a/src/types/inventory/ItemStackWrapper.php b/src/types/inventory/ItemStackWrapper.php index d9fef8f3..77e7fef2 100644 --- a/src/types/inventory/ItemStackWrapper.php +++ b/src/types/inventory/ItemStackWrapper.php @@ -35,7 +35,7 @@ public static function read(PacketSerializer $in) : self{ $stack = $in->getItemStack(function(PacketSerializer $in) use (&$stackId) : void{ $hasNetId = $in->getBool(); if($hasNetId){ - $stackId = $in->readGenericTypeNetworkId(); + $stackId = $in->readServerItemStackId(); } }); return new self($stackId, $stack); @@ -45,7 +45,7 @@ public function write(PacketSerializer $out) : void{ $out->putItemStack($this->itemStack, function(PacketSerializer $out) : void{ $out->putBool($this->stackId !== 0); if($this->stackId !== 0){ - $out->writeGenericTypeNetworkId($this->stackId); + $out->writeServerItemStackId($this->stackId); } }); } diff --git a/src/types/inventory/stackrequest/CraftRecipeAutoStackRequestAction.php b/src/types/inventory/stackrequest/CraftRecipeAutoStackRequestAction.php index 41cce7da..25831c17 100644 --- a/src/types/inventory/stackrequest/CraftRecipeAutoStackRequestAction.php +++ b/src/types/inventory/stackrequest/CraftRecipeAutoStackRequestAction.php @@ -49,7 +49,7 @@ public function getRepetitions() : int{ return $this->repetitions; } public function getIngredients() : array{ return $this->ingredients; } public static function read(PacketSerializer $in) : self{ - $recipeId = $in->readGenericTypeNetworkId(); + $recipeId = $in->readRecipeNetId(); $repetitions = $in->getByte(); $ingredients = []; for($i = 0, $count = $in->getByte(); $i < $count; ++$i){ @@ -59,7 +59,7 @@ public static function read(PacketSerializer $in) : self{ } public function write(PacketSerializer $out) : void{ - $out->writeGenericTypeNetworkId($this->recipeId); + $out->writeRecipeNetId($this->recipeId); $out->putByte($this->repetitions); $out->putByte(count($this->ingredients)); foreach($this->ingredients as $ingredient){ diff --git a/src/types/inventory/stackrequest/CraftRecipeOptionalStackRequestAction.php b/src/types/inventory/stackrequest/CraftRecipeOptionalStackRequestAction.php index 19519473..c67eb391 100644 --- a/src/types/inventory/stackrequest/CraftRecipeOptionalStackRequestAction.php +++ b/src/types/inventory/stackrequest/CraftRecipeOptionalStackRequestAction.php @@ -39,13 +39,13 @@ public function getRecipeId() : int{ return $this->recipeId; } public function getFilterStringIndex() : int{ return $this->filterStringIndex; } public static function read(PacketSerializer $in) : self{ - $recipeId = $in->readGenericTypeNetworkId(); + $recipeId = $in->readRecipeNetId(); $filterStringIndex = $in->getLInt(); return new self($recipeId, $filterStringIndex); } public function write(PacketSerializer $out) : void{ - $out->writeGenericTypeNetworkId($this->recipeId); + $out->writeRecipeNetId($this->recipeId); $out->putLInt($this->filterStringIndex); } } diff --git a/src/types/inventory/stackrequest/CraftRecipeStackRequestAction.php b/src/types/inventory/stackrequest/CraftRecipeStackRequestAction.php index c497c074..272c9873 100644 --- a/src/types/inventory/stackrequest/CraftRecipeStackRequestAction.php +++ b/src/types/inventory/stackrequest/CraftRecipeStackRequestAction.php @@ -32,11 +32,11 @@ final public function __construct( public function getRecipeId() : int{ return $this->recipeId; } public static function read(PacketSerializer $in) : self{ - $recipeId = $in->readGenericTypeNetworkId(); + $recipeId = $in->readRecipeNetId(); return new self($recipeId); } public function write(PacketSerializer $out) : void{ - $out->writeGenericTypeNetworkId($this->recipeId); + $out->writeRecipeNetId($this->recipeId); } } diff --git a/src/types/inventory/stackrequest/CreativeCreateStackRequestAction.php b/src/types/inventory/stackrequest/CreativeCreateStackRequestAction.php index d14e7f84..2304991d 100644 --- a/src/types/inventory/stackrequest/CreativeCreateStackRequestAction.php +++ b/src/types/inventory/stackrequest/CreativeCreateStackRequestAction.php @@ -32,11 +32,11 @@ public function __construct( public function getCreativeItemId() : int{ return $this->creativeItemId; } public static function read(PacketSerializer $in) : self{ - $creativeItemId = $in->readGenericTypeNetworkId(); + $creativeItemId = $in->readCreativeItemNetId(); return new self($creativeItemId); } public function write(PacketSerializer $out) : void{ - $out->writeGenericTypeNetworkId($this->creativeItemId); + $out->writeCreativeItemNetId($this->creativeItemId); } } diff --git a/src/types/inventory/stackrequest/GrindstoneStackRequestAction.php b/src/types/inventory/stackrequest/GrindstoneStackRequestAction.php index 5994a555..39016ec1 100644 --- a/src/types/inventory/stackrequest/GrindstoneStackRequestAction.php +++ b/src/types/inventory/stackrequest/GrindstoneStackRequestAction.php @@ -36,14 +36,14 @@ public function getRecipeId() : int{ return $this->recipeId; } public function getRepairCost() : int{ return $this->repairCost; } public static function read(PacketSerializer $in) : self{ - $recipeId = $in->readGenericTypeNetworkId(); + $recipeId = $in->readRecipeNetId(); $repairCost = $in->getVarInt(); //WHY!!!! return new self($recipeId, $repairCost); } public function write(PacketSerializer $out) : void{ - $out->writeGenericTypeNetworkId($this->recipeId); + $out->writeRecipeNetId($this->recipeId); $out->putVarInt($this->repairCost); } } diff --git a/src/types/inventory/stackrequest/ItemStackRequest.php b/src/types/inventory/stackrequest/ItemStackRequest.php index 5e9dc60d..9e8c698e 100644 --- a/src/types/inventory/stackrequest/ItemStackRequest.php +++ b/src/types/inventory/stackrequest/ItemStackRequest.php @@ -76,7 +76,7 @@ private static function readAction(PacketSerializer $in, int $typeId) : ItemStac } public static function read(PacketSerializer $in) : self{ - $requestId = $in->readGenericTypeNetworkId(); + $requestId = $in->readItemStackRequestId(); $actions = []; for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ $typeId = $in->getByte(); @@ -91,7 +91,7 @@ public static function read(PacketSerializer $in) : self{ } public function write(PacketSerializer $out) : void{ - $out->writeGenericTypeNetworkId($this->requestId); + $out->writeItemStackRequestId($this->requestId); $out->putUnsignedVarInt(count($this->actions)); foreach($this->actions as $action){ $out->putByte($action->getTypeId()); diff --git a/src/types/inventory/stackrequest/ItemStackRequestSlotInfo.php b/src/types/inventory/stackrequest/ItemStackRequestSlotInfo.php index b567566e..64c9a879 100644 --- a/src/types/inventory/stackrequest/ItemStackRequestSlotInfo.php +++ b/src/types/inventory/stackrequest/ItemStackRequestSlotInfo.php @@ -32,13 +32,13 @@ public function getStackId() : int{ return $this->stackId; } public static function read(PacketSerializer $in) : self{ $containerId = $in->getByte(); $slotId = $in->getByte(); - $stackId = $in->readGenericTypeNetworkId(); + $stackId = $in->readItemStackNetIdVariant(); return new self($containerId, $slotId, $stackId); } public function write(PacketSerializer $out) : void{ $out->putByte($this->containerId); $out->putByte($this->slotId); - $out->writeGenericTypeNetworkId($this->stackId); + $out->writeItemStackNetIdVariant($this->stackId); } } diff --git a/src/types/inventory/stackrequest/MineBlockStackRequestAction.php b/src/types/inventory/stackrequest/MineBlockStackRequestAction.php index 4afde355..e794dfc2 100644 --- a/src/types/inventory/stackrequest/MineBlockStackRequestAction.php +++ b/src/types/inventory/stackrequest/MineBlockStackRequestAction.php @@ -37,13 +37,13 @@ public function getStackId() : int{ return $this->stackId; } public static function read(PacketSerializer $in) : self{ $hotbarSlot = $in->getVarInt(); $predictedDurability = $in->getVarInt(); - $stackId = $in->readGenericTypeNetworkId(); + $stackId = $in->readItemStackNetIdVariant(); return new self($hotbarSlot, $predictedDurability, $stackId); } public function write(PacketSerializer $out) : void{ $out->putVarInt($this->hotbarSlot); $out->putVarInt($this->predictedDurability); - $out->writeGenericTypeNetworkId($this->stackId); + $out->writeItemStackNetIdVariant($this->stackId); } } diff --git a/src/types/inventory/stackresponse/ItemStackResponse.php b/src/types/inventory/stackresponse/ItemStackResponse.php index 39d0263f..c698fa25 100644 --- a/src/types/inventory/stackresponse/ItemStackResponse.php +++ b/src/types/inventory/stackresponse/ItemStackResponse.php @@ -46,7 +46,7 @@ public function getContainerInfos() : array{ return $this->containerInfos; } public static function read(PacketSerializer $in) : self{ $result = $in->getByte(); - $requestId = $in->readGenericTypeNetworkId(); + $requestId = $in->readItemStackRequestId(); $containerInfos = []; if($result === self::RESULT_OK){ for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ @@ -58,7 +58,7 @@ public static function read(PacketSerializer $in) : self{ public function write(PacketSerializer $out) : void{ $out->putByte($this->result); - $out->writeGenericTypeNetworkId($this->requestId); + $out->writeItemStackRequestId($this->requestId); if($this->result === self::RESULT_OK){ $out->putUnsignedVarInt(count($this->containerInfos)); foreach($this->containerInfos as $containerInfo){ diff --git a/src/types/inventory/stackresponse/ItemStackResponseSlotInfo.php b/src/types/inventory/stackresponse/ItemStackResponseSlotInfo.php index fb24b3a1..7ddc2601 100644 --- a/src/types/inventory/stackresponse/ItemStackResponseSlotInfo.php +++ b/src/types/inventory/stackresponse/ItemStackResponseSlotInfo.php @@ -42,7 +42,7 @@ public static function read(PacketSerializer $in) : self{ $slot = $in->getByte(); $hotbarSlot = $in->getByte(); $count = $in->getByte(); - $itemStackId = $in->readGenericTypeNetworkId(); + $itemStackId = $in->readServerItemStackId(); $customName = $in->getString(); $durabilityCorrection = $in->getVarInt(); return new self($slot, $hotbarSlot, $count, $itemStackId, $customName, $durabilityCorrection); @@ -52,7 +52,7 @@ public function write(PacketSerializer $out) : void{ $out->putByte($this->slot); $out->putByte($this->hotbarSlot); $out->putByte($this->count); - $out->writeGenericTypeNetworkId($this->itemStackId); + $out->writeServerItemStackId($this->itemStackId); $out->putString($this->customName); $out->putVarInt($this->durabilityCorrection); } diff --git a/src/types/recipe/MultiRecipe.php b/src/types/recipe/MultiRecipe.php index 33d83119..f4091c5e 100644 --- a/src/types/recipe/MultiRecipe.php +++ b/src/types/recipe/MultiRecipe.php @@ -50,12 +50,12 @@ public function getRecipeNetId() : int{ public static function decode(int $typeId, PacketSerializer $in) : self{ $uuid = $in->getUUID(); - $recipeNetId = $in->readGenericTypeNetworkId(); + $recipeNetId = $in->readRecipeNetId(); return new self($typeId, $uuid, $recipeNetId); } public function encode(PacketSerializer $out) : void{ $out->putUUID($this->recipeId); - $out->writeGenericTypeNetworkId($this->recipeNetId); + $out->writeRecipeNetId($this->recipeNetId); } } diff --git a/src/types/recipe/ShapedRecipe.php b/src/types/recipe/ShapedRecipe.php index 4fe7a951..e51c33d0 100644 --- a/src/types/recipe/ShapedRecipe.php +++ b/src/types/recipe/ShapedRecipe.php @@ -112,7 +112,7 @@ public static function decode(int $recipeType, PacketSerializer $in) : self{ $uuid = $in->getUUID(); $block = $in->getString(); $priority = $in->getVarInt(); - $recipeNetId = $in->readGenericTypeNetworkId(); + $recipeNetId = $in->readRecipeNetId(); return new self($recipeType, $recipeId, $input, $output, $uuid, $block, $priority, $recipeNetId); } @@ -135,6 +135,6 @@ public function encode(PacketSerializer $out) : void{ $out->putUUID($this->uuid); $out->putString($this->blockName); $out->putVarInt($this->priority); - $out->writeGenericTypeNetworkId($this->recipeNetId); + $out->writeRecipeNetId($this->recipeNetId); } } diff --git a/src/types/recipe/ShapelessRecipe.php b/src/types/recipe/ShapelessRecipe.php index 6cc6288b..972844ca 100644 --- a/src/types/recipe/ShapelessRecipe.php +++ b/src/types/recipe/ShapelessRecipe.php @@ -84,7 +84,7 @@ public static function decode(int $recipeType, PacketSerializer $in) : self{ $uuid = $in->getUUID(); $block = $in->getString(); $priority = $in->getVarInt(); - $recipeNetId = $in->readGenericTypeNetworkId(); + $recipeNetId = $in->readRecipeNetId(); return new self($recipeType, $recipeId, $input, $output, $uuid, $block, $priority, $recipeNetId); } @@ -104,6 +104,6 @@ public function encode(PacketSerializer $out) : void{ $out->putUUID($this->uuid); $out->putString($this->blockName); $out->putVarInt($this->priority); - $out->writeGenericTypeNetworkId($this->recipeNetId); + $out->writeRecipeNetId($this->recipeNetId); } } diff --git a/src/types/recipe/SmithingTransformRecipe.php b/src/types/recipe/SmithingTransformRecipe.php index 3e9cb117..62cd4b46 100644 --- a/src/types/recipe/SmithingTransformRecipe.php +++ b/src/types/recipe/SmithingTransformRecipe.php @@ -53,7 +53,7 @@ public static function decode(int $typeId, PacketSerializer $in) : self{ $addition = $in->getRecipeIngredient(); $output = $in->getItemStackWithoutStackId(); $blockName = $in->getString(); - $recipeNetId = $in->readGenericTypeNetworkId(); + $recipeNetId = $in->readRecipeNetId(); return new self( $typeId, @@ -74,6 +74,6 @@ public function encode(PacketSerializer $out) : void{ $out->putRecipeIngredient($this->addition); $out->putItemStackWithoutStackId($this->output); $out->putString($this->blockName); - $out->writeGenericTypeNetworkId($this->recipeNetId); + $out->writeRecipeNetId($this->recipeNetId); } } diff --git a/src/types/recipe/SmithingTrimRecipe.php b/src/types/recipe/SmithingTrimRecipe.php index fc345ae9..bf2ae39a 100644 --- a/src/types/recipe/SmithingTrimRecipe.php +++ b/src/types/recipe/SmithingTrimRecipe.php @@ -48,7 +48,7 @@ public static function decode(int $typeId, PacketSerializer $in) : self{ $input = $in->getRecipeIngredient(); $addition = $in->getRecipeIngredient(); $blockName = $in->getString(); - $recipeNetId = $in->readGenericTypeNetworkId(); + $recipeNetId = $in->readRecipeNetId(); return new self( $typeId, @@ -67,6 +67,6 @@ public function encode(PacketSerializer $out) : void{ $out->putRecipeIngredient($this->input); $out->putRecipeIngredient($this->addition); $out->putString($this->blockName); - $out->writeGenericTypeNetworkId($this->recipeNetId); + $out->writeRecipeNetId($this->recipeNetId); } }