Merge 'minor-next' into 'major-next'

Automatic merge performed by: https://github.com/pmmp/RestrictedActions/actions/runs/16867858213
This commit is contained in:
pmmp-admin-bot[bot] 2025-08-11 00:03:30 +00:00
commit cd6199ad62
2 changed files with 16 additions and 6 deletions

View File

@ -56,6 +56,12 @@ final class CraftingDataCache{
*/ */
private array $caches = []; private array $caches = [];
/**
* The client doesn't like recipes with ID 0 (as of 1.21.100) and complains about them in the content log
* This doesn't actually affect the function of the recipe, but it is annoying, so this offset fixes it
*/
public const RECIPE_ID_OFFSET = 1;
public function getCache(CraftingManager $manager) : CraftingDataPacket{ public function getCache(CraftingManager $manager) : CraftingDataPacket{
$id = spl_object_id($manager); $id = spl_object_id($manager);
if(!isset($this->caches[$id])){ if(!isset($this->caches[$id])){
@ -82,6 +88,8 @@ final class CraftingDataCache{
$noUnlockingRequirement = new RecipeUnlockingRequirement(null); $noUnlockingRequirement = new RecipeUnlockingRequirement(null);
foreach($manager->getCraftingRecipeIndex() as $index => $recipe){ foreach($manager->getCraftingRecipeIndex() as $index => $recipe){
//the client doesn't like recipes with an ID of 0, so we need to offset them
$recipeNetId = $index + self::RECIPE_ID_OFFSET;
if($recipe instanceof ShapelessRecipe){ if($recipe instanceof ShapelessRecipe){
$typeTag = match($recipe->getType()){ $typeTag = match($recipe->getType()){
ShapelessRecipeType::CRAFTING => CraftingRecipeBlockName::CRAFTING_TABLE, ShapelessRecipeType::CRAFTING => CraftingRecipeBlockName::CRAFTING_TABLE,
@ -91,14 +99,14 @@ final class CraftingDataCache{
}; };
$recipesWithTypeIds[] = new ProtocolShapelessRecipe( $recipesWithTypeIds[] = new ProtocolShapelessRecipe(
CraftingDataPacket::ENTRY_SHAPELESS, CraftingDataPacket::ENTRY_SHAPELESS,
Binary::writeInt($index), Binary::writeInt($recipeNetId),
array_map($converter->coreRecipeIngredientToNet(...), $recipe->getIngredientList()), array_map($converter->coreRecipeIngredientToNet(...), $recipe->getIngredientList()),
array_map($converter->coreItemStackToNet(...), $recipe->getResults()), array_map($converter->coreItemStackToNet(...), $recipe->getResults()),
$nullUUID, $nullUUID,
$typeTag, $typeTag,
50, 50,
$noUnlockingRequirement, $noUnlockingRequirement,
$index $recipeNetId
); );
}elseif($recipe instanceof ShapedRecipe){ }elseif($recipe instanceof ShapedRecipe){
$inputs = []; $inputs = [];
@ -110,7 +118,7 @@ final class CraftingDataCache{
} }
$recipesWithTypeIds[] = $r = new ProtocolShapedRecipe( $recipesWithTypeIds[] = $r = new ProtocolShapedRecipe(
CraftingDataPacket::ENTRY_SHAPED, CraftingDataPacket::ENTRY_SHAPED,
Binary::writeInt($index), Binary::writeInt($recipeNetId),
$inputs, $inputs,
array_map($converter->coreItemStackToNet(...), $recipe->getResults()), array_map($converter->coreItemStackToNet(...), $recipe->getResults()),
$nullUUID, $nullUUID,
@ -118,7 +126,7 @@ final class CraftingDataCache{
50, 50,
true, true,
$noUnlockingRequirement, $noUnlockingRequirement,
$index, $recipeNetId,
); );
}else{ }else{
//TODO: probably special recipe types //TODO: probably special recipe types

View File

@ -35,6 +35,7 @@ use pocketmine\inventory\transaction\TransactionBuilder;
use pocketmine\inventory\transaction\TransactionBuilderInventory; use pocketmine\inventory\transaction\TransactionBuilderInventory;
use pocketmine\item\Durable; use pocketmine\item\Durable;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\network\mcpe\cache\CraftingDataCache;
use pocketmine\network\mcpe\InventoryManager; use pocketmine\network\mcpe\InventoryManager;
use pocketmine\network\mcpe\protocol\types\inventory\ContainerUIIds; use pocketmine\network\mcpe\protocol\types\inventory\ContainerUIIds;
use pocketmine\network\mcpe\protocol\types\inventory\FullContainerName; use pocketmine\network\mcpe\protocol\types\inventory\FullContainerName;
@ -238,9 +239,10 @@ class ItemStackRequestExecutor{
throw new ItemStackRequestProcessException("Cannot craft a recipe more than 256 times"); throw new ItemStackRequestProcessException("Cannot craft a recipe more than 256 times");
} }
$craftingManager = $this->player->getServer()->getCraftingManager(); $craftingManager = $this->player->getServer()->getCraftingManager();
$recipe = $craftingManager->getCraftingRecipeFromIndex($recipeId); $recipeIndex = $recipeId - CraftingDataCache::RECIPE_ID_OFFSET;
$recipe = $craftingManager->getCraftingRecipeFromIndex($recipeIndex);
if($recipe === null){ if($recipe === null){
throw new ItemStackRequestProcessException("No such crafting recipe index: $recipeId"); throw new ItemStackRequestProcessException("No such crafting recipe index: $recipeIndex");
} }
$this->specialTransaction = new CraftingTransaction($this->player, $craftingManager, [], $recipe, $repetitions); $this->specialTransaction = new CraftingTransaction($this->player, $craftingManager, [], $recipe, $repetitions);