963
This commit is contained in:
parent
b2375286c9
commit
fc05430719
20 changed files with 260 additions and 325 deletions
File diff suppressed because it is too large
Load diff
|
@ -1,73 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: SoSeDiK <mrsosedik@gmail.com>
|
||||
Date: Wed, 1 May 2024 08:22:13 +0300
|
||||
Subject: [PATCH] More Chest Block API
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.level.block.ChestBlock isBlockedChestByBlock(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Z
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java b/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java
|
||||
index 5f9858ef8d0ec1a74d469ab4426eb1db068873fd..ca92d49ef2010ba00c623491671dcde8ebe697c1 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java
|
||||
@@ -83,7 +83,7 @@ public class EnderChestBlock extends AbstractChestBlock<EnderChestBlockEntity> i
|
||||
BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||
if (playerEnderChestContainer != null && blockEntity instanceof EnderChestBlockEntity) {
|
||||
BlockPos blockPos = pos.above();
|
||||
- if (world.getBlockState(blockPos).isRedstoneConductor(world, blockPos)) {
|
||||
+ if (world.getBlockState(blockPos).isRedstoneConductor(world, blockPos)) { // Paper - diff on change; make sure that EnderChest#isBlocked uses the same logic
|
||||
return InteractionResult.sidedSuccess(world.isClientSide);
|
||||
} else if (world.isClientSide) {
|
||||
return InteractionResult.SUCCESS;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java
|
||||
index 6e98a00d526b734992ce39b15768c5820dce4ca8..cc7bf4d39b834fba472bc163226a01a0cd4b6010 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java
|
||||
@@ -99,4 +99,29 @@ public class CraftChest extends CraftLootable<ChestBlockEntity> implements Chest
|
||||
return getTileEntity().openersCounter.opened;
|
||||
}
|
||||
// Paper end - More Lidded Block API
|
||||
+
|
||||
+ // Paper start - More Chest Block API
|
||||
+ @Override
|
||||
+ public boolean isBlocked() {
|
||||
+ // Method mimics vanilla logic in ChestBlock and DoubleBlockCombiner when trying to open chest's container
|
||||
+ if (!isPlaced()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ net.minecraft.world.level.LevelAccessor world = getWorldHandle();
|
||||
+ if (ChestBlock.isChestBlockedAt(world, getPosition())) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ if (ChestBlock.getBlockType(this.data) == net.minecraft.world.level.block.DoubleBlockCombiner.BlockType.SINGLE) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ net.minecraft.core.Direction direction = ChestBlock.getConnectedDirection(this.data);
|
||||
+ net.minecraft.core.BlockPos neighbourBlockPos = getPosition().relative(direction);
|
||||
+ BlockState neighbourBlockState = world.getBlockStateIfLoaded(neighbourBlockPos);
|
||||
+ return neighbourBlockState != null
|
||||
+ && neighbourBlockState.is(this.data.getBlock())
|
||||
+ && ChestBlock.getBlockType(neighbourBlockState) != net.minecraft.world.level.block.DoubleBlockCombiner.BlockType.SINGLE
|
||||
+ && ChestBlock.getConnectedDirection(neighbourBlockState) == direction.getOpposite()
|
||||
+ && ChestBlock.isChestBlockedAt(world, neighbourBlockPos);
|
||||
+ }
|
||||
+ // Paper end - More Chest Block API
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftEnderChest.java b/src/main/java/org/bukkit/craftbukkit/block/CraftEnderChest.java
|
||||
index b64adbba3e52d32d439e64a243cb74f3fbca2ce3..f45ee675a10729845bf376fa95e648b23b9aac12 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftEnderChest.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftEnderChest.java
|
||||
@@ -58,4 +58,13 @@ public class CraftEnderChest extends CraftBlockEntityState<EnderChestBlockEntity
|
||||
return getTileEntity().openersCounter.opened;
|
||||
}
|
||||
// Paper end - More Lidded Block API
|
||||
+
|
||||
+ // Paper start - More Chest Block API
|
||||
+ @Override
|
||||
+ public boolean isBlocked() {
|
||||
+ // Uses the same logic as EnderChestBlock's check for opening container
|
||||
+ final net.minecraft.core.BlockPos abovePos = this.getPosition().above();
|
||||
+ return this.isPlaced() && this.getWorldHandle().getBlockState(abovePos).isRedstoneConductor(this.getWorldHandle(), abovePos);
|
||||
+ }
|
||||
+ // Paper end - More Chest Block API
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <nassim@njahnke.dev>
|
||||
Date: Thu, 9 May 2024 15:11:34 +0200
|
||||
Subject: [PATCH] Print data component type on encoding error
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/core/component/DataComponentPatch.java b/src/main/java/net/minecraft/core/component/DataComponentPatch.java
|
||||
index 87dd1f570fd294daf826ef7e6403776e42ed4f61..cee4a0639b3c73e300a8450f8a831cb4a71958ba 100644
|
||||
--- a/src/main/java/net/minecraft/core/component/DataComponentPatch.java
|
||||
+++ b/src/main/java/net/minecraft/core/component/DataComponentPatch.java
|
||||
@@ -144,7 +144,13 @@ public final class DataComponentPatch {
|
||||
}
|
||||
|
||||
private static <T> void encodeComponent(RegistryFriendlyByteBuf buf, DataComponentType<T> type, Object value) {
|
||||
+ // Paper start - codec errors of random anonymous classes are useless
|
||||
+ try {
|
||||
type.streamCodec().encode(buf, (T) value); // CraftBukkit - decompile error
|
||||
+ } catch (final Exception e) {
|
||||
+ throw new RuntimeException("Error encoding component " + type, e);
|
||||
+ }
|
||||
+ // Paper end - codec errors of random anonymous classes are useless
|
||||
}
|
||||
};
|
||||
private static final String REMOVED_PREFIX = "!";
|
File diff suppressed because it is too large
Load diff
|
@ -1,118 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 12 May 2024 15:49:36 -0700
|
||||
Subject: [PATCH] Fix issues with Recipe API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
|
||||
index 63cf2b66f51df68aa3f6d98c69368ce454869d64..1bf54b0142fe41b29b21c8b97d3f52bb24a36a92 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
|
||||
@@ -90,7 +90,7 @@ public class ShapedRecipe extends io.papermc.paper.inventory.recipe.RecipeBookEx
|
||||
char c = 'a';
|
||||
for (Ingredient list : this.pattern.ingredients()) {
|
||||
RecipeChoice choice = CraftRecipe.toBukkit(list);
|
||||
- if (choice != null) {
|
||||
+ if (choice != RecipeChoice.empty()) { // Paper
|
||||
recipe.setIngredient(c, choice);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
|
||||
index 6ba29875d78ede4aa7978ff689e588f7fed11528..c76c78bb7757d407102271463e14716a1b012deb 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
|
||||
@@ -29,6 +29,10 @@ public interface CraftRecipe extends Recipe {
|
||||
} else if (bukkit instanceof RecipeChoice.ExactChoice) {
|
||||
stack = new Ingredient(((RecipeChoice.ExactChoice) bukkit).getChoices().stream().map((mat) -> new net.minecraft.world.item.crafting.Ingredient.ItemValue(CraftItemStack.asNMSCopy(mat))));
|
||||
stack.exact = true;
|
||||
+ // Paper start - support "empty" choices
|
||||
+ } else if (bukkit == RecipeChoice.empty()) {
|
||||
+ stack = Ingredient.EMPTY;
|
||||
+ // Paper end
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown recipe stack instance " + bukkit);
|
||||
}
|
||||
@@ -45,7 +49,7 @@ public interface CraftRecipe extends Recipe {
|
||||
list.getItems();
|
||||
|
||||
if (list.itemStacks.length == 0) {
|
||||
- return null;
|
||||
+ return RecipeChoice.empty(); // Paper - null breaks API contracts
|
||||
}
|
||||
|
||||
if (list.exact) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java
|
||||
index 37b39a2c696a59b0f52324cc222b83c0c9f341e6..3aec771478a6b17353d57e82baac53dd24779e7b 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java
|
||||
@@ -30,6 +30,6 @@ public class CraftSmithingTransformRecipe extends SmithingTransformRecipe implem
|
||||
public void addToCraftingManager() {
|
||||
ItemStack result = this.getResult();
|
||||
|
||||
- MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTransformRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false), CraftItemStack.asNMSCopy(result), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy
|
||||
+ MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTransformRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false), CraftItemStack.asNMSCopy(result), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy & support empty RecipeChoice
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java
|
||||
index 389fa313f811279091cace76faaabf8bdb0fc94c..61af2fe3534ff67f10310c6c7dec39cff0f93ee3 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java
|
||||
@@ -28,6 +28,6 @@ public class CraftSmithingTrimRecipe extends SmithingTrimRecipe implements Craft
|
||||
|
||||
@Override
|
||||
public void addToCraftingManager() {
|
||||
- MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTrimRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy
|
||||
+ MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTrimRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy & support empty RecipeChoice
|
||||
}
|
||||
}
|
||||
diff --git a/src/test/java/io/papermc/paper/inventory/recipe/TestRecipeChoice.java b/src/test/java/io/papermc/paper/inventory/recipe/TestRecipeChoice.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..45ab2b6d32b29cb663df848534e1aa68293dd613
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/inventory/recipe/TestRecipeChoice.java
|
||||
@@ -0,0 +1,25 @@
|
||||
+package io.papermc.paper.inventory.recipe;
|
||||
+
|
||||
+import java.util.Iterator;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.inventory.Recipe;
|
||||
+import org.bukkit.support.environment.AllFeatures;
|
||||
+import org.junit.jupiter.api.Test;
|
||||
+
|
||||
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
+import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
+
|
||||
+@AllFeatures
|
||||
+class TestRecipeChoice {
|
||||
+
|
||||
+ @Test
|
||||
+ void testRecipeChoices() {
|
||||
+ final Iterator<Recipe> iter = Bukkit.recipeIterator();
|
||||
+ boolean foundRecipes = false;
|
||||
+ while (iter.hasNext()) {
|
||||
+ foundRecipes = true;
|
||||
+ assertDoesNotThrow(iter::next, "Failed to convert a recipe to Bukkit recipe!");
|
||||
+ }
|
||||
+ assertTrue(foundRecipes, "No recipes found!");
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/test/java/org/bukkit/support/DummyServerHelper.java b/src/test/java/org/bukkit/support/DummyServerHelper.java
|
||||
index fb4b7625b4ea4b4918ade95829e10e98d1bac70f..cb2b39c562f609375b9e5b20cb5899780995373d 100644
|
||||
--- a/src/test/java/org/bukkit/support/DummyServerHelper.java
|
||||
+++ b/src/test/java/org/bukkit/support/DummyServerHelper.java
|
||||
@@ -92,6 +92,15 @@ public final class DummyServerHelper {
|
||||
// Paper end - testing additions
|
||||
|
||||
io.papermc.paper.configuration.GlobalConfigTestingBase.setupGlobalConfigForTest(); // Paper - configuration files - setup global configuration test base
|
||||
+
|
||||
+ // Paper start - add test for recipe conversion
|
||||
+ when(instance.recipeIterator()).thenAnswer(ignored ->
|
||||
+ com.google.common.collect.Iterators.transform(
|
||||
+ RegistryHelper.getDataPack().getRecipeManager().byType.entries().iterator(),
|
||||
+ input -> input.getValue().toBukkitRecipe()
|
||||
+ )
|
||||
+ );
|
||||
+ // Paper end - add test for recipe conversion
|
||||
return instance;
|
||||
}
|
||||
}
|
|
@ -1,136 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Wed, 22 May 2024 10:01:19 -0700
|
||||
Subject: [PATCH] Fix equipment slot and group API
|
||||
|
||||
Adds the following:
|
||||
- Add test for EquipmentSlotGroup
|
||||
- Expose LivingEntity#canUseSlot
|
||||
|
||||
Co-authored-by: SoSeDiK <mrsosedik@gmail.com>
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index fb6465bbb2a8bb7597c15d7ac8375f696b897e43..34641a6356876c46d05188a988c02835d0c06dc6 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -1211,4 +1211,11 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
this.getHandle().setYBodyRot(bodyYaw);
|
||||
}
|
||||
// Paper end - body yaw API
|
||||
+
|
||||
+ // Paper start - Expose canUseSlot
|
||||
+ @Override
|
||||
+ public boolean canUseEquipmentSlot(org.bukkit.inventory.EquipmentSlot slot) {
|
||||
+ return this.getHandle().canUseSlot(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot));
|
||||
+ }
|
||||
+ // Paper end - Expose canUseSlot
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java
|
||||
index 9d74577af071954e1e37201a96368c1360076209..eafa54c870c3e2aef30c3f9f96f516607a7cae24 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java
|
||||
@@ -135,6 +135,10 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i
|
||||
case HEAD:
|
||||
this.setHelmet(item);
|
||||
break;
|
||||
+ // Paper start
|
||||
+ case BODY:
|
||||
+ throw new IllegalArgumentException("BODY is not valid for players!");
|
||||
+ // Paper end
|
||||
default:
|
||||
throw new IllegalArgumentException("Not implemented. This is a bug");
|
||||
}
|
||||
@@ -162,6 +166,10 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i
|
||||
return java.util.Objects.requireNonNullElseGet(this.getChestplate(), () -> new ItemStack(org.bukkit.Material.AIR)); // Paper - make nonnull
|
||||
case HEAD:
|
||||
return java.util.Objects.requireNonNullElseGet(this.getHelmet(), () -> new ItemStack(org.bukkit.Material.AIR)); // Paper - make nonnull
|
||||
+ // Paper start
|
||||
+ case BODY:
|
||||
+ throw new IllegalArgumentException("BODY is not valid for players!");
|
||||
+ // Paper end
|
||||
default:
|
||||
throw new IllegalArgumentException("Not implemented. This is a bug");
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
index 88e1156510f3a43dd37e279205e5ed5dd120c1db..7f6f404f5a2be7876ae239355979e8c8a7a198ce 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
@@ -1450,7 +1450,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
if (this.attributeModifiers == null) return LinkedHashMultimap.create(); // Paper - don't change the components
|
||||
SetMultimap<Attribute, AttributeModifier> result = LinkedHashMultimap.create();
|
||||
for (Map.Entry<Attribute, AttributeModifier> entry : this.attributeModifiers.entries()) {
|
||||
- if (entry.getValue().getSlot() == null || entry.getValue().getSlot() == slot) {
|
||||
+ if (entry.getValue().getSlotGroup().test(slot)) { // Paper - correctly test slot against group
|
||||
result.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
@@ -1524,9 +1524,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<Attribute, AttributeModifier> entry = iter.next();
|
||||
- // Explicitly match against null because (as of MC 1.13) AttributeModifiers without a -
|
||||
- // set slot are active in any slot.
|
||||
- if (entry.getValue().getSlot() == null || entry.getValue().getSlot() == slot) {
|
||||
+ if (entry.getValue().getSlotGroup().test(slot)) { // Paper - correctly test slot against group
|
||||
iter.remove();
|
||||
++removed;
|
||||
}
|
||||
diff --git a/src/test/java/io/papermc/paper/inventory/item/EquipmentSlotGroupTest.java b/src/test/java/io/papermc/paper/inventory/item/EquipmentSlotGroupTest.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..a26dc8f4787276468417196440cb8f73670a56c7
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/inventory/item/EquipmentSlotGroupTest.java
|
||||
@@ -0,0 +1,53 @@
|
||||
+package io.papermc.paper.inventory.item;
|
||||
+
|
||||
+import java.lang.reflect.Field;
|
||||
+import java.lang.reflect.Modifier;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.List;
|
||||
+import net.minecraft.world.entity.EquipmentSlot;
|
||||
+import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
||||
+import org.bukkit.inventory.EquipmentSlotGroup;
|
||||
+import org.bukkit.support.environment.Normal;
|
||||
+import org.junit.jupiter.params.ParameterizedTest;
|
||||
+import org.junit.jupiter.params.provider.EnumSource;
|
||||
+import org.junit.jupiter.params.provider.MethodSource;
|
||||
+
|
||||
+import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
+import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
+
|
||||
+@Normal
|
||||
+class EquipmentSlotGroupTest {
|
||||
+
|
||||
+ static List<EquipmentSlotGroup> apiValues() throws ReflectiveOperationException {
|
||||
+ final List<EquipmentSlotGroup> apiValues = new ArrayList<>();
|
||||
+ for (final Field field : EquipmentSlotGroup.class.getDeclaredFields()) {
|
||||
+ if (!Modifier.isStatic(field.getModifiers()) || !Modifier.isFinal(field.getModifiers()) || !field.getType().equals(EquipmentSlotGroup.class)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ apiValues.add((EquipmentSlotGroup) field.get(null));
|
||||
+ }
|
||||
+ if (apiValues.isEmpty()) {
|
||||
+ throw new RuntimeException("Didn't find any api " + EquipmentSlotGroup.class.getSimpleName());
|
||||
+ }
|
||||
+ return apiValues;
|
||||
+ }
|
||||
+
|
||||
+ @ParameterizedTest
|
||||
+ @MethodSource("apiValues")
|
||||
+ void testBukkitToNms(final EquipmentSlotGroup slotGroup) {
|
||||
+ final net.minecraft.world.entity.EquipmentSlotGroup nmsGroup = CraftEquipmentSlot.getNMSGroup(slotGroup);
|
||||
+ assertNotNull(nmsGroup, "No nms slot group found for " + slotGroup);
|
||||
+ assertEquals(nmsGroup.getSerializedName(), slotGroup.toString(), "slot group name mismatch");
|
||||
+ for (final EquipmentSlot slot : EquipmentSlot.values()) {
|
||||
+ assertEquals(nmsGroup.test(slot), slotGroup.test(CraftEquipmentSlot.getSlot(slot)));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @ParameterizedTest
|
||||
+ @EnumSource(net.minecraft.world.entity.EquipmentSlotGroup.class)
|
||||
+ void testNmsToBukkit(final net.minecraft.world.entity.EquipmentSlotGroup slotGroup) {
|
||||
+ final EquipmentSlotGroup apiGroup = CraftEquipmentSlot.getSlot(slotGroup);
|
||||
+ assertNotNull(apiGroup, "No api slot group found for " + slotGroup);
|
||||
+ assertEquals(apiGroup.toString(), slotGroup.getSerializedName(), "slot group name mismatch");
|
||||
+ }
|
||||
+}
|
|
@ -1,130 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Tue, 21 May 2024 13:18:15 -0700
|
||||
Subject: [PATCH] Allow Bukkit plugin to use Paper PluginLoader API
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/loader/PaperClasspathBuilder.java b/src/main/java/io/papermc/paper/plugin/loader/PaperClasspathBuilder.java
|
||||
index f871a329eb52da077f58d0ceaaabd3349f84cad0..21a0a4e29c0eb1b4f7dc89ad3df481ca89dbf1a4 100644
|
||||
--- a/src/main/java/io/papermc/paper/plugin/loader/PaperClasspathBuilder.java
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/loader/PaperClasspathBuilder.java
|
||||
@@ -41,15 +41,7 @@ public class PaperClasspathBuilder implements PluginClasspathBuilder {
|
||||
}
|
||||
|
||||
public PaperPluginClassLoader buildClassLoader(Logger logger, Path source, JarFile jarFile, PaperPluginMeta configuration) {
|
||||
- PaperLibraryStore paperLibraryStore = new PaperLibraryStore();
|
||||
- for (ClassPathLibrary library : this.libraries) {
|
||||
- library.register(paperLibraryStore);
|
||||
- }
|
||||
-
|
||||
- List<Path> paths = paperLibraryStore.getPaths();
|
||||
- if (PluginInitializerManager.instance().pluginRemapper != null) {
|
||||
- paths = PluginInitializerManager.instance().pluginRemapper.remapLibraries(paths);
|
||||
- }
|
||||
+ List<Path> paths = this.buildLibraryPaths(true);
|
||||
URL[] urls = new URL[paths.size()];
|
||||
for (int i = 0; i < paths.size(); i++) {
|
||||
Path path = paths.get(i);
|
||||
@@ -69,4 +61,17 @@ public class PaperClasspathBuilder implements PluginClasspathBuilder {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
}
|
||||
+
|
||||
+ public List<Path> buildLibraryPaths(final boolean remap) {
|
||||
+ PaperLibraryStore paperLibraryStore = new PaperLibraryStore();
|
||||
+ for (ClassPathLibrary library : this.libraries) {
|
||||
+ library.register(paperLibraryStore);
|
||||
+ }
|
||||
+
|
||||
+ List<Path> paths = paperLibraryStore.getPaths();
|
||||
+ if (remap && PluginInitializerManager.instance().pluginRemapper != null) {
|
||||
+ paths = PluginInitializerManager.instance().pluginRemapper.remapLibraries(paths);
|
||||
+ }
|
||||
+ return paths;
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProvider.java b/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProvider.java
|
||||
index 75a2b687d58d76b94f8bec111df8613f120ff74b..0fd1040ed376f19c6d5326767baaf3048ce1bfb4 100644
|
||||
--- a/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProvider.java
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProvider.java
|
||||
@@ -40,15 +40,17 @@ public class SpigotPluginProvider implements PluginProvider<JavaPlugin>, Provide
|
||||
private final PluginDescriptionFile description;
|
||||
private final JarFile jarFile;
|
||||
private final Logger logger;
|
||||
+ private final List<Path> paperLibraryPaths;
|
||||
private final ComponentLogger componentLogger;
|
||||
private ProviderStatus status;
|
||||
private DependencyContext dependencyContext;
|
||||
|
||||
- SpigotPluginProvider(Path path, JarFile file, PluginDescriptionFile description) {
|
||||
+ SpigotPluginProvider(Path path, JarFile file, PluginDescriptionFile description, List<Path> paperLibraryPaths) {
|
||||
this.path = path;
|
||||
this.jarFile = file;
|
||||
this.description = description;
|
||||
this.logger = PaperPluginLogger.getLogger(description);
|
||||
+ this.paperLibraryPaths = paperLibraryPaths;
|
||||
this.componentLogger = ComponentLogger.logger(this.logger.getName());
|
||||
}
|
||||
|
||||
@@ -120,7 +122,7 @@ public class SpigotPluginProvider implements PluginProvider<JavaPlugin>, Provide
|
||||
|
||||
final PluginClassLoader loader;
|
||||
try {
|
||||
- loader = new PluginClassLoader(this.getClass().getClassLoader(), this.description, dataFolder, this.path.toFile(), LIBRARY_LOADER.createLoader(this.description), this.jarFile, this.dependencyContext); // Paper
|
||||
+ loader = new PluginClassLoader(this.getClass().getClassLoader(), this.description, dataFolder, this.path.toFile(), LIBRARY_LOADER.createLoader(this.description, this.paperLibraryPaths), this.jarFile, this.dependencyContext); // Paper
|
||||
} catch (InvalidPluginException ex) {
|
||||
throw ex;
|
||||
} catch (Throwable ex) {
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProviderFactory.java b/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProviderFactory.java
|
||||
index 1bf0fa1530b8e5f94d726d0313b7a00f675b500c..9edf79dffd2836b40d41da4437c18d6145853f89 100644
|
||||
--- a/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProviderFactory.java
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProviderFactory.java
|
||||
@@ -1,9 +1,18 @@
|
||||
package io.papermc.paper.plugin.provider.type.spigot;
|
||||
|
||||
+import com.destroystokyo.paper.utils.PaperPluginLogger;
|
||||
+import io.papermc.paper.plugin.bootstrap.PluginProviderContextImpl;
|
||||
import io.papermc.paper.plugin.entrypoint.classloader.BytecodeModifyingURLClassLoader;
|
||||
+import io.papermc.paper.plugin.entrypoint.classloader.PaperSimplePluginClassLoader;
|
||||
+import io.papermc.paper.plugin.loader.PaperClasspathBuilder;
|
||||
+import io.papermc.paper.plugin.loader.PluginLoader;
|
||||
import io.papermc.paper.plugin.provider.configuration.serializer.constraints.PluginConfigConstraints;
|
||||
import io.papermc.paper.plugin.provider.type.PluginTypeFactory;
|
||||
+import io.papermc.paper.plugin.provider.util.ProviderUtil;
|
||||
import io.papermc.paper.util.MappingEnvironment;
|
||||
+import java.util.List;
|
||||
+import java.util.logging.Logger;
|
||||
+import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
|
||||
import org.bukkit.plugin.InvalidDescriptionException;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.java.LibraryLoader;
|
||||
@@ -36,7 +45,28 @@ class SpigotPluginProviderFactory implements PluginTypeFactory<SpigotPluginProvi
|
||||
throw new InvalidDescriptionException("Restricted name, cannot use 0x20 (space character) in a plugin name.");
|
||||
}
|
||||
|
||||
- return new SpigotPluginProvider(source, file, configuration);
|
||||
+ final List<Path> paperLibraryPaths;
|
||||
+ if (configuration.getPaperPluginLoader() != null) {
|
||||
+ final Logger logger = PaperPluginLogger.getLogger(configuration);
|
||||
+ PaperClasspathBuilder builder = new PaperClasspathBuilder(PluginProviderContextImpl.create(
|
||||
+ configuration, ComponentLogger.logger(logger.getName()), source
|
||||
+ ));
|
||||
+
|
||||
+ try (
|
||||
+ PaperSimplePluginClassLoader simplePluginClassLoader = new PaperSimplePluginClassLoader(source, file, configuration, this.getClass().getClassLoader())
|
||||
+ ) {
|
||||
+ PluginLoader loader = ProviderUtil.loadClass(configuration.getPaperPluginLoader(), PluginLoader.class, simplePluginClassLoader);
|
||||
+ loader.classloader(builder);
|
||||
+ } catch (IOException e) {
|
||||
+ throw new RuntimeException(e);
|
||||
+ }
|
||||
+
|
||||
+ paperLibraryPaths = builder.buildLibraryPaths(false);
|
||||
+ } else {
|
||||
+ paperLibraryPaths = null;
|
||||
+ }
|
||||
+
|
||||
+ return new SpigotPluginProvider(source, file, configuration, paperLibraryPaths);
|
||||
}
|
||||
|
||||
@Override
|
|
@ -1,236 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <nassim@njahnke.dev>
|
||||
Date: Wed, 1 Dec 2021 12:36:25 +0100
|
||||
Subject: [PATCH] Prevent sending oversized item data in equipment and metadata
|
||||
|
||||
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/util/DataSanitizationUtil.java b/src/main/java/io/papermc/paper/util/DataSanitizationUtil.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..72483dedd3b1864fca3463d3ba3f6fad22680b97
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/util/DataSanitizationUtil.java
|
||||
@@ -0,0 +1,108 @@
|
||||
+package io.papermc.paper.util;
|
||||
+
|
||||
+import java.util.List;
|
||||
+import java.util.concurrent.atomic.AtomicBoolean;
|
||||
+import java.util.function.UnaryOperator;
|
||||
+import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
+import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
+import net.minecraft.network.codec.StreamCodec;
|
||||
+import net.minecraft.util.Mth;
|
||||
+import net.minecraft.world.item.ItemStack;
|
||||
+import net.minecraft.world.item.Items;
|
||||
+import net.minecraft.world.item.component.BundleContents;
|
||||
+import net.minecraft.world.item.component.ChargedProjectiles;
|
||||
+import net.minecraft.world.item.component.ItemContainerContents;
|
||||
+import org.apache.commons.lang3.math.Fraction;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public final class DataSanitizationUtil {
|
||||
+
|
||||
+ private static final ThreadLocal<DataSanitizer> DATA_SANITIZER = ThreadLocal.withInitial(DataSanitizer::new);
|
||||
+
|
||||
+ public static DataSanitizer start(final boolean sanitize) {
|
||||
+ final DataSanitizer sanitizer = DATA_SANITIZER.get();
|
||||
+ if (sanitize) {
|
||||
+ sanitizer.start();
|
||||
+ }
|
||||
+ return sanitizer;
|
||||
+ }
|
||||
+
|
||||
+ public static final StreamCodec<RegistryFriendlyByteBuf, ChargedProjectiles> CHARGED_PROJECTILES = codec(ChargedProjectiles.STREAM_CODEC, DataSanitizationUtil::sanitizeChargedProjectiles);
|
||||
+ public static final StreamCodec<RegistryFriendlyByteBuf, BundleContents> BUNDLE_CONTENTS = codec(BundleContents.STREAM_CODEC, DataSanitizationUtil::sanitizeBundleContents);
|
||||
+ public static final StreamCodec<RegistryFriendlyByteBuf, ItemContainerContents> CONTAINER = codec(ItemContainerContents.STREAM_CODEC, contents -> ItemContainerContents.EMPTY);
|
||||
+
|
||||
+ private static ChargedProjectiles sanitizeChargedProjectiles(final ChargedProjectiles projectiles) {
|
||||
+ if (projectiles.isEmpty()) {
|
||||
+ return projectiles;
|
||||
+ }
|
||||
+
|
||||
+ return ChargedProjectiles.of(List.of(
|
||||
+ new ItemStack(projectiles.contains(Items.FIREWORK_ROCKET) ? Items.FIREWORK_ROCKET : Items.ARROW)
|
||||
+ ));
|
||||
+ }
|
||||
+
|
||||
+ private static BundleContents sanitizeBundleContents(final BundleContents contents) {
|
||||
+ if (contents.isEmpty()) {
|
||||
+ return contents;
|
||||
+ }
|
||||
+
|
||||
+ // Bundles change their texture based on their fullness.
|
||||
+ // A bundles content weight may be anywhere from 0 to, basically, infinity.
|
||||
+ // A weight of 1 is the usual maximum case
|
||||
+ int sizeUsed = Mth.mulAndTruncate(contents.weight(), 64);
|
||||
+ // Early out, *most* bundles should not be overfilled above a weight of one.
|
||||
+ if (sizeUsed <= 64) return new BundleContents(List.of(new ItemStack(Items.PAPER, Math.max(1, sizeUsed))));
|
||||
+
|
||||
+ final List<ItemStack> sanitizedRepresentation = new ObjectArrayList<>(sizeUsed / 64 + 1);
|
||||
+ while (sizeUsed > 0) {
|
||||
+ final int stackCount = Math.min(64, sizeUsed);
|
||||
+ sanitizedRepresentation.add(new ItemStack(Items.PAPER, stackCount));
|
||||
+ sizeUsed -= stackCount;
|
||||
+ }
|
||||
+ // Now we add a single fake item that uses the same amount of slots as all other items.
|
||||
+ // Ensure that potentially overstacked bundles are not represented by empty (count=0) itemstacks.
|
||||
+ return new BundleContents(sanitizedRepresentation);
|
||||
+ }
|
||||
+
|
||||
+ private static <B, A> StreamCodec<B, A> codec(final StreamCodec<B, A> delegate, final UnaryOperator<A> sanitizer) {
|
||||
+ return new DataSanitizationCodec<>(delegate, sanitizer);
|
||||
+ }
|
||||
+
|
||||
+ private record DataSanitizationCodec<B, A>(StreamCodec<B, A> delegate, UnaryOperator<A> sanitizer) implements StreamCodec<B, A> {
|
||||
+
|
||||
+ @Override
|
||||
+ public @NonNull A decode(final @NonNull B buf) {
|
||||
+ return this.delegate.decode(buf);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void encode(final @NonNull B buf, final @NonNull A value) {
|
||||
+ if (!DATA_SANITIZER.get().value().get()) {
|
||||
+ this.delegate.encode(buf, value);
|
||||
+ } else {
|
||||
+ this.delegate.encode(buf, this.sanitizer.apply(value));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public record DataSanitizer(AtomicBoolean value) implements AutoCloseable {
|
||||
+
|
||||
+ public DataSanitizer() {
|
||||
+ this(new AtomicBoolean(false));
|
||||
+ }
|
||||
+
|
||||
+ public void start() {
|
||||
+ this.value.compareAndSet(false, true);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void close() {
|
||||
+ this.value.compareAndSet(true, false);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private DataSanitizationUtil() {
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/core/component/DataComponents.java b/src/main/java/net/minecraft/core/component/DataComponents.java
|
||||
index c9aef759c1485da753e820f9b509117ca50a31e4..60757f8df706cba92350d73503b73913cff3bcfc 100644
|
||||
--- a/src/main/java/net/minecraft/core/component/DataComponents.java
|
||||
+++ b/src/main/java/net/minecraft/core/component/DataComponents.java
|
||||
@@ -138,10 +138,10 @@ public class DataComponents {
|
||||
"map_post_processing", builder -> builder.networkSynchronized(MapPostProcessing.STREAM_CODEC)
|
||||
);
|
||||
public static final DataComponentType<ChargedProjectiles> CHARGED_PROJECTILES = register(
|
||||
- "charged_projectiles", builder -> builder.persistent(ChargedProjectiles.CODEC).networkSynchronized(ChargedProjectiles.STREAM_CODEC).cacheEncoding()
|
||||
+ "charged_projectiles", builder -> builder.persistent(ChargedProjectiles.CODEC).networkSynchronized(io.papermc.paper.util.DataSanitizationUtil.CHARGED_PROJECTILES).cacheEncoding() // Paper - sanitize charged projectiles
|
||||
);
|
||||
public static final DataComponentType<BundleContents> BUNDLE_CONTENTS = register(
|
||||
- "bundle_contents", builder -> builder.persistent(BundleContents.CODEC).networkSynchronized(BundleContents.STREAM_CODEC).cacheEncoding()
|
||||
+ "bundle_contents", builder -> builder.persistent(BundleContents.CODEC).networkSynchronized(io.papermc.paper.util.DataSanitizationUtil.BUNDLE_CONTENTS).cacheEncoding() // Paper - sanitize bundle contents
|
||||
);
|
||||
public static final DataComponentType<PotionContents> POTION_CONTENTS = register(
|
||||
"potion_contents", builder -> builder.persistent(PotionContents.CODEC).networkSynchronized(PotionContents.STREAM_CODEC).cacheEncoding()
|
||||
@@ -208,7 +208,7 @@ public class DataComponents {
|
||||
"pot_decorations", builder -> builder.persistent(PotDecorations.CODEC).networkSynchronized(PotDecorations.STREAM_CODEC).cacheEncoding()
|
||||
);
|
||||
public static final DataComponentType<ItemContainerContents> CONTAINER = register(
|
||||
- "container", builder -> builder.persistent(ItemContainerContents.CODEC).networkSynchronized(ItemContainerContents.STREAM_CODEC).cacheEncoding()
|
||||
+ "container", builder -> builder.persistent(ItemContainerContents.CODEC).networkSynchronized(io.papermc.paper.util.DataSanitizationUtil.CONTAINER).cacheEncoding() // Paper - sanitize container contents
|
||||
);
|
||||
public static final DataComponentType<BlockItemStateProperties> BLOCK_STATE = register(
|
||||
"block_state", builder -> builder.persistent(BlockItemStateProperties.CODEC).networkSynchronized(BlockItemStateProperties.STREAM_CODEC).cacheEncoding()
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java
|
||||
index 59c1c103545f04fd35e6932df64a9910a1d74cd7..56bde49e6b7790155b032d0be40961d566ab89e9 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java
|
||||
@@ -19,9 +19,11 @@ public record ClientboundSetEntityDataPacket(int id, List<SynchedEntityData.Data
|
||||
}
|
||||
|
||||
private static void pack(List<SynchedEntityData.DataValue<?>> trackedValues, RegistryFriendlyByteBuf buf) {
|
||||
+ try (var ignored = io.papermc.paper.util.DataSanitizationUtil.start(true)) { // Paper - data sanitization
|
||||
for (SynchedEntityData.DataValue<?> dataValue : trackedValues) {
|
||||
dataValue.write(buf);
|
||||
}
|
||||
+ } // Paper - data sanitization
|
||||
|
||||
buf.writeByte(255);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java
|
||||
index 2ea7e90d582866b4e29db80836e250163d811763..d152871142d3def2ac04f50037db53b0527f7894 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java
|
||||
@@ -19,6 +19,13 @@ public class ClientboundSetEquipmentPacket implements Packet<ClientGamePacketLis
|
||||
private final List<Pair<EquipmentSlot, ItemStack>> slots;
|
||||
|
||||
public ClientboundSetEquipmentPacket(int entityId, List<Pair<EquipmentSlot, ItemStack>> equipmentList) {
|
||||
+ // Paper start - data sanitization
|
||||
+ this(entityId, equipmentList, false);
|
||||
+ }
|
||||
+ private boolean sanitize;
|
||||
+ public ClientboundSetEquipmentPacket(int entityId, List<Pair<EquipmentSlot, ItemStack>> equipmentList, boolean sanitize) {
|
||||
+ this.sanitize = sanitize;
|
||||
+ // Paper end - data sanitization
|
||||
this.entity = entityId;
|
||||
this.slots = equipmentList;
|
||||
}
|
||||
@@ -41,6 +48,7 @@ public class ClientboundSetEquipmentPacket implements Packet<ClientGamePacketLis
|
||||
buf.writeVarInt(this.entity);
|
||||
int i = this.slots.size();
|
||||
|
||||
+ try (var ignored = io.papermc.paper.util.DataSanitizationUtil.start(this.sanitize)) { // Paper - data sanitization
|
||||
for (int j = 0; j < i; j++) {
|
||||
Pair<EquipmentSlot, ItemStack> pair = this.slots.get(j);
|
||||
EquipmentSlot equipmentSlot = pair.getFirst();
|
||||
@@ -49,6 +57,7 @@ public class ClientboundSetEquipmentPacket implements Packet<ClientGamePacketLis
|
||||
buf.writeByte(bl ? k | -128 : k);
|
||||
ItemStack.OPTIONAL_STREAM_CODEC.encode(buf, pair.getSecond());
|
||||
}
|
||||
+ } // Paper - data sanitization
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
index 0e7ace92522fbd4cef7b2c2b8a0f8b86c2cce192..1d849ce4e2c85f149af25318b8ffb6dcef6c6788 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -349,7 +349,7 @@ public class ServerEntity {
|
||||
}
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
- sender.accept(new ClientboundSetEquipmentPacket(this.entity.getId(), list));
|
||||
+ sender.accept(new ClientboundSetEquipmentPacket(this.entity.getId(), list, true)); // Paper - data sanitization
|
||||
}
|
||||
((LivingEntity) this.entity).detectEquipmentUpdatesPublic(); // CraftBukkit - SPIGOT-3789: sync again immediately after sending
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 5215783353021583e7a726d281e4d1734398f073..0fe4c3ff5dd855aea58292c16ba9a2f5d23c00f5 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -2731,7 +2731,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
entity.refreshEntityData(ServerGamePacketListenerImpl.this.player);
|
||||
// SPIGOT-7136 - Allays
|
||||
if (entity instanceof Allay || entity instanceof net.minecraft.world.entity.animal.horse.AbstractHorse) { // Paper - Fix horse armor desync
|
||||
- ServerGamePacketListenerImpl.this.send(new ClientboundSetEquipmentPacket(entity.getId(), Arrays.stream(net.minecraft.world.entity.EquipmentSlot.values()).map((slot) -> Pair.of(slot, ((LivingEntity) entity).getItemBySlot(slot).copy())).collect(Collectors.toList())));
|
||||
+ ServerGamePacketListenerImpl.this.send(new ClientboundSetEquipmentPacket(entity.getId(), Arrays.stream(net.minecraft.world.entity.EquipmentSlot.values()).map((slot) -> Pair.of(slot, ((LivingEntity) entity).getItemBySlot(slot).copy())).collect(Collectors.toList()), true)); // Paper - sanitize
|
||||
}
|
||||
|
||||
ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote(); // Paper - fix slot desync - always refresh player inventory
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index b1e894e9a9cd87f7259302d15d5b5b0e2b32c4ea..7b6d067eb8b22a8e0a82a2969c92ba243230733a 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3353,7 +3353,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
}
|
||||
|
||||
});
|
||||
- ((ServerLevel) this.level()).getChunkSource().broadcast(this, new ClientboundSetEquipmentPacket(this.getId(), list));
|
||||
+ ((ServerLevel) this.level()).getChunkSource().broadcast(this, new ClientboundSetEquipmentPacket(this.getId(), list, true)); // Paper - data sanitization
|
||||
}
|
||||
|
||||
private ItemStack getLastArmorItem(EquipmentSlot slot) {
|
|
@ -1,24 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 12 May 2024 21:57:23 -0700
|
||||
Subject: [PATCH] Prevent NPE if hooked entity was cleared
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
index 270f4c94912b16c7d4a2d62670847cbb5e011819..6ce65e5b336be9b49db84f1c4755c2e2ce7f8378 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
@@ -504,11 +504,13 @@ public class FishingHook extends Projectile {
|
||||
if (playerFishEvent.isCancelled()) {
|
||||
return 0;
|
||||
}
|
||||
+ if (this.hookedIn != null) { // Paper - re-check to see if there is a hooked entity
|
||||
// CraftBukkit end
|
||||
this.pullEntity(this.hookedIn);
|
||||
CriteriaTriggers.FISHING_ROD_HOOKED.trigger((ServerPlayer) entityhuman, usedItem, this, Collections.emptyList());
|
||||
this.level().broadcastEntityEvent(this, (byte) 31);
|
||||
i = this.hookedIn instanceof ItemEntity ? 3 : 5;
|
||||
+ } // Paper - re-check to see if there is a hooked entity
|
||||
} else if (this.nibble > 0) {
|
||||
LootParams lootparams = (new LootParams.Builder((ServerLevel) this.level())).withParameter(LootContextParams.ORIGIN, this.position()).withParameter(LootContextParams.TOOL, usedItem).withParameter(LootContextParams.THIS_ENTITY, this).withLuck((float) this.luck + entityhuman.getLuck()).create(LootContextParamSets.FISHING);
|
||||
LootTable loottable = this.level().getServer().reloadableRegistries().getLootTable(BuiltInLootTables.FISHING);
|
|
@ -1,47 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tamion <70228790+notTamion@users.noreply.github.com>
|
||||
Date: Thu, 23 May 2024 11:02:20 +0200
|
||||
Subject: [PATCH] Fix cancelling BlockPlaceEvent calling onRemove
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
index 58786dd7b51d17c1b602756c4c44840ab75ad0a7..96b24c1415af531feef7d8ab4724f7fed3ae8388 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -494,9 +494,11 @@ public final class ItemStack implements DataComponentHolder {
|
||||
world.capturedTileEntities.clear(); // Paper - Allow chests to be placed with NBT data; clear out block entities as chests and such will pop loot
|
||||
// revert back all captured blocks
|
||||
world.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710
|
||||
+ world.isBlockPlaceCancelled = true; // Paper - prevent calling cleanup logic when undoing a block place upon a cancelled BlockPlaceEvent
|
||||
for (BlockState blockstate : blocks) {
|
||||
blockstate.update(true, false);
|
||||
}
|
||||
+ world.isBlockPlaceCancelled = false; // Paper - prevent calling cleanup logic when undoing a block place upon a cancelled BlockPlaceEvent
|
||||
world.preventPoiUpdated = false;
|
||||
|
||||
// Brute force all possible updates
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index a2877f3eb206ab9ccb93e3606f1c9b3401def5d6..e5abde76c354c3dd9940dd4e5ae3fe8b6a2b4680 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -151,6 +151,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
public boolean preventPoiUpdated = false; // CraftBukkit - SPIGOT-5710
|
||||
public boolean captureBlockStates = false;
|
||||
public boolean captureTreeGeneration = false;
|
||||
+ public boolean isBlockPlaceCancelled = false; // Paper - prevent calling cleanup logic when undoing a block place upon a cancelled BlockPlaceEvent
|
||||
public Map<BlockPos, org.bukkit.craftbukkit.block.CraftBlockState> capturedBlockStates = new java.util.LinkedHashMap<>(); // Paper
|
||||
public Map<BlockPos, BlockEntity> capturedTileEntities = new java.util.LinkedHashMap<>(); // Paper - Retain block place order when capturing blockstates
|
||||
public List<ItemEntity> captureDrops;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 86eb9029969f4de3ada7be9e135e9764172b85f5..21946a93b6a2a3c79d15af1d6e7eabc537ba0125 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -345,7 +345,7 @@ public class LevelChunk extends ChunkAccess {
|
||||
|
||||
boolean flag3 = iblockdata1.hasBlockEntity();
|
||||
|
||||
- if (!this.level.isClientSide) {
|
||||
+ if (!this.level.isClientSide && !this.level.isBlockPlaceCancelled) { // Paper - prevent calling cleanup logic when undoing a block place upon a cancelled BlockPlaceEvent
|
||||
iblockdata1.onRemove(this.level, blockposition, iblockdata, flag);
|
||||
} else if (!iblockdata1.is(block) && flag3) {
|
||||
this.removeBlockEntity(blockposition);
|
|
@ -1,26 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: SoSeDiK <mrsosedik@gmail.com>
|
||||
Date: Wed, 1 May 2024 07:44:50 +0300
|
||||
Subject: [PATCH] Add missing fishing event state
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
index 6ce65e5b336be9b49db84f1c4755c2e2ce7f8378..1223c5d23d0ea6aed068bdf0f5725e2ad49fc82c 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
@@ -411,6 +411,15 @@ public class FishingHook extends Projectile {
|
||||
this.fishAngle = Mth.nextFloat(this.random, this.minLureAngle, this.maxLureAngle);
|
||||
this.timeUntilHooked = Mth.nextInt(this.random, this.minLureTime, this.maxLureTime);
|
||||
// CraftBukkit end
|
||||
+ // Paper start - Add missing fishing event state
|
||||
+ if (this.getPlayerOwner() != null) {
|
||||
+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.getPlayerOwner().getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.LURED);
|
||||
+ if (!playerFishEvent.callEvent()) {
|
||||
+ this.timeUntilHooked = 0;
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Add missing fishing event state
|
||||
}
|
||||
} else {
|
||||
// CraftBukkit start - logic to modify fishing wait time
|
|
@ -1,26 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sat, 25 May 2024 09:51:13 -0700
|
||||
Subject: [PATCH] Deprecate InvAction#HOTBAR_MOVE_AND_READD
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0fe4c3ff5dd855aea58292c16ba9a2f5d23c00f5..0034483685ba626e5883b857de96ffd36e57e150 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -2997,14 +2997,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
Slot clickedSlot = this.player.containerMenu.getSlot(packet.getSlotNum());
|
||||
if (clickedSlot.mayPickup(this.player)) {
|
||||
ItemStack hotbar = this.player.getInventory().getItem(packet.getButtonNum());
|
||||
- boolean canCleanSwap = hotbar.isEmpty() || (clickedSlot.container == this.player.getInventory() && clickedSlot.mayPlace(hotbar)); // the slot will accept the hotbar item
|
||||
- if (clickedSlot.hasItem()) {
|
||||
- if (canCleanSwap) {
|
||||
- action = InventoryAction.HOTBAR_SWAP;
|
||||
- } else {
|
||||
- action = InventoryAction.HOTBAR_MOVE_AND_READD;
|
||||
- }
|
||||
- } else if (!clickedSlot.hasItem() && !hotbar.isEmpty() && clickedSlot.mayPlace(hotbar)) {
|
||||
+ if ((!hotbar.isEmpty() && clickedSlot.mayPlace(hotbar)) || (hotbar.isEmpty() && clickedSlot.hasItem())) { // Paper - modernify this logic (no such thing as a "hotbar move and readd"
|
||||
action = InventoryAction.HOTBAR_SWAP;
|
||||
} else {
|
||||
action = InventoryAction.NOTHING;
|
|
@ -1,21 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Thu, 30 May 2024 18:46:15 +0100
|
||||
Subject: [PATCH] Fix sending disconnect packet in phases where it doesn't
|
||||
exist
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
|
||||
index 4b9da6e2140b14f1e56056f5e9e94b2169d85501..55848fa832d0f4d2d03f99df51e10c5fdfcd2ded 100644
|
||||
--- a/src/main/java/net/minecraft/network/Connection.java
|
||||
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||||
@@ -218,7 +218,8 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
if (player != null) player.quitReason = org.bukkit.event.player.PlayerQuitEvent.QuitReason.ERRONEOUS_STATE; // Paper - Add API for quit reason
|
||||
if (flag) {
|
||||
Connection.LOGGER.debug("Failed to sent packet", throwable);
|
||||
- if (this.getSending() == PacketFlow.CLIENTBOUND) {
|
||||
+ boolean doesDisconnectExist = this.packetListener.protocol() != ConnectionProtocol.STATUS && this.packetListener.protocol() != ConnectionProtocol.HANDSHAKING; // Paper
|
||||
+ if (this.getSending() == PacketFlow.CLIENTBOUND && doesDisconnectExist) { // Paper
|
||||
Packet<?> packet = this.sendLoginDisconnect ? new ClientboundLoginDisconnectPacket(ichatmutablecomponent) : new ClientboundDisconnectPacket(ichatmutablecomponent);
|
||||
|
||||
this.send((Packet) packet, PacketSendListener.thenRun(() -> {
|
|
@ -1,134 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Bjarne Koll <lynxplay101@gmail.com>
|
||||
Date: Thu, 13 Jun 2024 11:02:36 +0200
|
||||
Subject: [PATCH] Adopt MaterialRerouting
|
||||
|
||||
Adopts the paper-api to the material rerouting infrastructure introduced
|
||||
by upstream.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java b/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java
|
||||
index 3ff0f0e34356cee4c510fdd60af723b1c5df156a..6cc9d7a9e6d4bfdc27e52fc581b2bb832616f121 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java
|
||||
@@ -600,4 +600,82 @@ public class MaterialRerouting {
|
||||
public static void setBlocks(ToolComponent.ToolRule toolRule, Collection<Material> blocks) {
|
||||
toolRule.setBlocks(blocks.stream().map(MaterialRerouting::transformToBlockType).toList());
|
||||
}
|
||||
+
|
||||
+ // Paper start - register paper API specific material consumers in rerouting
|
||||
+ // A lot of these methods do *not* run through MaterialRerouting to avoid the overhead of a system that
|
||||
+ // currently is an effective noop.
|
||||
+ // The only downside is that upstream moved the handling of legacy materials into transformFromXType methods.
|
||||
+ // As such, methods introduced prior to 1.13 need to run through the transformation to make sure legacy material
|
||||
+ // constants still work.
|
||||
+
|
||||
+ // Utility method for constructing a set from an existing one after mapping each element.
|
||||
+ private static <I, O> Set<O> mapSet(final Set<I> input, final java.util.function.Function<I,O> mapper) {
|
||||
+ final Set<O> output = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(input.size());
|
||||
+ for (final I i : input) {
|
||||
+ output.add(mapper.apply(i));
|
||||
+ }
|
||||
+ return output;
|
||||
+ }
|
||||
+
|
||||
+ // Method added post-1.13, noop (https://github.com/PaperMC/Paper/pull/4965)
|
||||
+ public static org.bukkit.Material getMinecartMaterial(org.bukkit.entity.Minecart minecart, @InjectPluginVersion ApiVersion version) {
|
||||
+ return minecart.getMinecartMaterial();
|
||||
+ }
|
||||
+
|
||||
+ // Method added post-1.13, noop (https://github.com/PaperMC/Paper/pull/4965)
|
||||
+ public static Material getBoatMaterial(Boat boat, @InjectPluginVersion ApiVersion version) {
|
||||
+ return boat.getBoatMaterial();
|
||||
+ }
|
||||
+
|
||||
+ // Method added post-1.13, noop (https://github.com/PaperMC/Paper/pull/3807)
|
||||
+ public static Material getType(io.papermc.paper.event.player.PlayerItemCooldownEvent event, @InjectPluginVersion ApiVersion version) {
|
||||
+ return event.getType();
|
||||
+ }
|
||||
+
|
||||
+ // Method added post-1.13, noop (https://github.com/PaperMC/Paper/pull/3850)
|
||||
+ public static Collection<Material> getInfiniburn(World world, @InjectPluginVersion ApiVersion version) {
|
||||
+ return world.getInfiniburn();
|
||||
+ }
|
||||
+
|
||||
+ // Method added pre-1.13, needs legacy rerouting (https://github.com/PaperMC/Paper/commit/3438e96192)
|
||||
+ public static Set<Material> getTypes(
|
||||
+ final com.destroystokyo.paper.event.player.PlayerArmorChangeEvent.SlotType slotType,
|
||||
+ @InjectPluginVersion final ApiVersion apiVersion
|
||||
+ ) {
|
||||
+ if (apiVersion.isNewerThanOrSameAs(ApiVersion.FLATTENING)) return slotType.getTypes();
|
||||
+ else return mapSet(slotType.getTypes(), MaterialRerouting::transformToItemType); // Needed as pre-flattening is hanled by transformToItemType
|
||||
+ }
|
||||
+
|
||||
+ // Method added pre-1.13, needs legacy rerouting (https://github.com/PaperMC/Paper/commit/3438e96192)
|
||||
+ @RerouteStatic("com/destroystokyo/paper/event/player/PlayerArmorChangeEvent$SlotType")
|
||||
+ public static com.destroystokyo.paper.event.player.PlayerArmorChangeEvent.SlotType getByMaterial(
|
||||
+ final Material material
|
||||
+ ) {
|
||||
+ return com.destroystokyo.paper.event.player.PlayerArmorChangeEvent.SlotType.getByMaterial(MaterialRerouting.transformToItemType(material));
|
||||
+ }
|
||||
+
|
||||
+ // Method added pre-1.13, needs legacy rerouting (https://github.com/PaperMC/Paper/commit/3438e96192)
|
||||
+ @RerouteStatic("com/destroystokyo/paper/event/player/PlayerArmorChangeEvent$SlotType")
|
||||
+ public static boolean isEquipable(final Material material) {
|
||||
+ return com.destroystokyo.paper.event.player.PlayerArmorChangeEvent.SlotType.isEquipable(MaterialRerouting.transformToItemType(material));
|
||||
+ }
|
||||
+
|
||||
+ // Method added post 1.13, no-op (https://github.com/PaperMC/Paper/pull/1244)
|
||||
+ public static Material getMaterial(final com.destroystokyo.paper.event.block.AnvilDamagedEvent.DamageState damageState) {
|
||||
+ return damageState.getMaterial();
|
||||
+ }
|
||||
+
|
||||
+ // Method added post 1.13, no-op (https://github.com/PaperMC/Paper/pull/1244)
|
||||
+ @RerouteStatic("com/destroystokyo/paper/event/block/AnvilDamagedEvent$DamageState")
|
||||
+ public static com.destroystokyo.paper.event.block.AnvilDamagedEvent.DamageState getState(
|
||||
+ final Material material
|
||||
+ ) {
|
||||
+ return com.destroystokyo.paper.event.block.AnvilDamagedEvent.DamageState.getState(material);
|
||||
+ }
|
||||
+
|
||||
+ // Method added post 1.13, no-op (https://github.com/PaperMC/Paper/pull/10290)
|
||||
+ public static ItemStack withType(final ItemStack itemStack, final Material material) {
|
||||
+ return itemStack.withType(material);
|
||||
+ }
|
||||
+ // Paper end - register paper API specific material consumers in rerouting
|
||||
}
|
||||
diff --git a/src/test/java/org/bukkit/craftbukkit/legacy/MaterialReroutingTest.java b/src/test/java/org/bukkit/craftbukkit/legacy/MaterialReroutingTest.java
|
||||
index cd03ea1f726894161ca786e7e7d00d04716405d3..329eeb174180b5d90b071247dac5459e4ffe3be3 100644
|
||||
--- a/src/test/java/org/bukkit/craftbukkit/legacy/MaterialReroutingTest.java
|
||||
+++ b/src/test/java/org/bukkit/craftbukkit/legacy/MaterialReroutingTest.java
|
||||
@@ -56,6 +56,9 @@ public class MaterialReroutingTest {
|
||||
.filter(entry -> !entry.getName().endsWith("ItemType.class"))
|
||||
.filter(entry -> !entry.getName().endsWith("Registry.class"))
|
||||
.filter(entry -> !entry.getName().startsWith("org/bukkit/material"))
|
||||
+ // Paper start - types that cannot be translated to ItemType/BlockType
|
||||
+ .filter(entry -> !entry.getName().equals("com/destroystokyo/paper/MaterialSetTag.class"))
|
||||
+ // Paper end - types that cannot be translated to ItemType/BlockType
|
||||
.map(entry -> {
|
||||
try {
|
||||
return MaterialReroutingTest.jarFile.getInputStream(entry);
|
||||
@@ -93,6 +96,10 @@ public class MaterialReroutingTest {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
+ // Paper start - filter out more methods from rerouting test
|
||||
+ if (methodNode.name.startsWith("lambda$")) continue;
|
||||
+ if (isInternal(methodNode.invisibleAnnotations)) continue;
|
||||
+ // Paper end - filter out more methods from rerouting test
|
||||
|
||||
if (!Commodore.rerouteMethods(ApiVersion.CURRENT, MaterialReroutingTest.MATERIAL_METHOD_REROUTE, (methodNode.access & Opcodes.ACC_STATIC) != 0, classNode.name, methodNode.name, methodNode.desc, a -> { })) {
|
||||
missingReroute.add(methodNode.name + " " + methodNode.desc + " " + methodNode.signature);
|
||||
@@ -109,6 +116,13 @@ public class MaterialReroutingTest {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - filter out more methods from rerouting test
|
||||
+ private static boolean isInternal(final List<org.objectweb.asm.tree.AnnotationNode> annotationNodes) {
|
||||
+ return annotationNodes != null
|
||||
+ && annotationNodes.stream().anyMatch(a -> a.desc.equals("Lorg/jetbrains/annotations/ApiStatus$Internal;"));
|
||||
+ }
|
||||
+ // Paper end - filter out more methods from rerouting test
|
||||
+
|
||||
@AfterAll
|
||||
public static void clear() throws IOException {
|
||||
if (MaterialReroutingTest.jarFile != null) {
|
|
@ -1,231 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sun, 3 Mar 2024 19:43:40 +0100
|
||||
Subject: [PATCH] Suspicious Effect Entry API
|
||||
|
||||
Exposes a new suspicious effect entry type that properly represents
|
||||
storable effects in the context of suspicious effects as they only
|
||||
define the potion effect type and duration.
|
||||
|
||||
This differentiates them from the existing PotionEffect API found in
|
||||
bukkit and hence clarifies that storable values in the parts of the API
|
||||
in which it replaces PotionEffect.
|
||||
|
||||
Co-authored-by: Yannick Lamprecht <yannicklamprecht@live.de>
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java
|
||||
index 9cc81bcccbf1141f66fedada1359b7c0dfa8e22a..5c5b64bd058684520fa175bfd10622ff57856b7c 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java
|
||||
@@ -37,16 +37,24 @@ public class CraftMushroomCow extends CraftCow implements MushroomCow, io.paperm
|
||||
@Override
|
||||
public boolean addEffectToNextStew(PotionEffect potionEffect, boolean overwrite) {
|
||||
Preconditions.checkArgument(potionEffect != null, "PotionEffect cannot be null");
|
||||
- MobEffectInstance minecraftPotionEffect = CraftPotionUtil.fromBukkit(potionEffect);
|
||||
- if (!overwrite && this.hasEffectForNextStew(potionEffect.getType())) {
|
||||
+ // Paper start - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta
|
||||
+ return this.addEffectToNextStew(io.papermc.paper.potion.SuspiciousEffectEntry.create(potionEffect.getType(), potionEffect.getDuration()), overwrite);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean addEffectToNextStew(io.papermc.paper.potion.SuspiciousEffectEntry suspiciousEffectEntry, boolean overwrite) {
|
||||
+ Preconditions.checkArgument(suspiciousEffectEntry != null, "SuspiciousEffectEntry cannot be null");
|
||||
+ Holder<MobEffect> minecraftPotionEffect = CraftPotionEffectType.bukkitToMinecraftHolder(suspiciousEffectEntry.effect());
|
||||
+ // Paper end - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta
|
||||
+ if (!overwrite && this.hasEffectForNextStew(suspiciousEffectEntry.effect())) {
|
||||
return false;
|
||||
}
|
||||
SuspiciousStewEffects stewEffects = this.getHandle().stewEffects;
|
||||
if (stewEffects == null) {
|
||||
stewEffects = SuspiciousStewEffects.EMPTY;
|
||||
}
|
||||
- SuspiciousStewEffects.Entry recordSuspiciousEffect = new SuspiciousStewEffects.Entry(minecraftPotionEffect.getEffect(), minecraftPotionEffect.getDuration());
|
||||
- this.removeEffectFromNextStew(potionEffect.getType()); // Avoid duplicates of effects
|
||||
+ SuspiciousStewEffects.Entry recordSuspiciousEffect = new SuspiciousStewEffects.Entry(minecraftPotionEffect, suspiciousEffectEntry.duration()); // Paper - sus effect entry API
|
||||
+ this.removeEffectFromNextStew(suspiciousEffectEntry.effect()); // Avoid duplicates of effects // Paper - sus effect entry API
|
||||
this.getHandle().stewEffects = stewEffects.withEffectAdded(recordSuspiciousEffect);
|
||||
return true;
|
||||
}
|
||||
@@ -101,6 +109,43 @@ public class CraftMushroomCow extends CraftCow implements MushroomCow, io.paperm
|
||||
this.getHandle().setVariant(net.minecraft.world.entity.animal.MushroomCow.MushroomType.values()[variant.ordinal()]);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public List<io.papermc.paper.potion.SuspiciousEffectEntry> getStewEffects() {
|
||||
+ if (this.getHandle().stewEffects == null) {
|
||||
+ return List.of();
|
||||
+ }
|
||||
+
|
||||
+ final List<io.papermc.paper.potion.SuspiciousEffectEntry> effectEntries = new java.util.ArrayList<>(this.getHandle().stewEffects.effects().size());
|
||||
+ for (final SuspiciousStewEffects.Entry effect : this.getHandle().stewEffects.effects()) {
|
||||
+ effectEntries.add(io.papermc.paper.potion.SuspiciousEffectEntry.create(
|
||||
+ org.bukkit.craftbukkit.potion.CraftPotionEffectType.minecraftHolderToBukkit(effect.effect()),
|
||||
+ effect.duration()
|
||||
+ ));
|
||||
+ }
|
||||
+
|
||||
+ return java.util.Collections.unmodifiableList(effectEntries);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setStewEffects(final List<io.papermc.paper.potion.SuspiciousEffectEntry> effects) {
|
||||
+ if (effects.isEmpty()) {
|
||||
+ this.getHandle().stewEffects = null;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ List<SuspiciousStewEffects.Entry> nmsPairs = new java.util.ArrayList<>(effects.size());
|
||||
+ for (final io.papermc.paper.potion.SuspiciousEffectEntry effect : effects) {
|
||||
+ nmsPairs.add(new SuspiciousStewEffects.Entry(
|
||||
+ org.bukkit.craftbukkit.potion.CraftPotionEffectType.bukkitToMinecraftHolder(effect.effect()),
|
||||
+ effect.duration()
|
||||
+ ));
|
||||
+ }
|
||||
+
|
||||
+ this.getHandle().stewEffects = new SuspiciousStewEffects(nmsPairs);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftMushroomCow";
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSuspiciousStew.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSuspiciousStew.java
|
||||
index 7a43e326e51300306b9c5c23a16ffae92030bd2b..192cd33f6276ea4928e29ac2cd4e45bf8bf82dcb 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSuspiciousStew.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSuspiciousStew.java
|
||||
@@ -21,7 +21,7 @@ public class CraftMetaSuspiciousStew extends CraftMetaItem implements Suspicious
|
||||
|
||||
static final ItemMetaKeyType<SuspiciousStewEffects> EFFECTS = new ItemMetaKeyType<>(DataComponents.SUSPICIOUS_STEW_EFFECTS, "effects");
|
||||
|
||||
- private List<PotionEffect> customEffects;
|
||||
+ private List<io.papermc.paper.potion.SuspiciousEffectEntry> customEffects; // Paper - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta
|
||||
|
||||
CraftMetaSuspiciousStew(CraftMetaItem meta) {
|
||||
super(meta);
|
||||
@@ -47,7 +47,7 @@ public class CraftMetaSuspiciousStew extends CraftMetaItem implements Suspicious
|
||||
continue;
|
||||
}
|
||||
int duration = effect.duration();
|
||||
- this.customEffects.add(new PotionEffect(type, duration, 0));
|
||||
+ this.customEffects.add(io.papermc.paper.potion.SuspiciousEffectEntry.create(type, duration)); // Paper - use suspicious effect entry for suspicious stew meta
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -73,8 +73,8 @@ public class CraftMetaSuspiciousStew extends CraftMetaItem implements Suspicious
|
||||
if (this.customEffects != null) {
|
||||
List<SuspiciousStewEffects.Entry> effectList = new ArrayList<>();
|
||||
|
||||
- for (PotionEffect effect : this.customEffects) {
|
||||
- effectList.add(new net.minecraft.world.item.component.SuspiciousStewEffects.Entry(CraftPotionEffectType.bukkitToMinecraftHolder(effect.getType()), effect.getDuration()));
|
||||
+ for (io.papermc.paper.potion.SuspiciousEffectEntry effect : this.customEffects) {
|
||||
+ effectList.add(new net.minecraft.world.item.component.SuspiciousStewEffects.Entry(CraftPotionEffectType.bukkitToMinecraftHolder(effect.effect()), effect.duration())); // Paper - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta
|
||||
}
|
||||
tag.put(CraftMetaSuspiciousStew.EFFECTS, new SuspiciousStewEffects(effectList));
|
||||
}
|
||||
@@ -106,7 +106,7 @@ public class CraftMetaSuspiciousStew extends CraftMetaItem implements Suspicious
|
||||
@Override
|
||||
public List<PotionEffect> getCustomEffects() {
|
||||
if (this.hasCustomEffects()) {
|
||||
- return ImmutableList.copyOf(this.customEffects);
|
||||
+ return this.customEffects.stream().map(suspiciousEffectEntry -> suspiciousEffectEntry.effect().createEffect(suspiciousEffectEntry.duration(), 0)).toList(); // Paper - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta
|
||||
}
|
||||
return ImmutableList.of();
|
||||
}
|
||||
@@ -114,27 +114,47 @@ public class CraftMetaSuspiciousStew extends CraftMetaItem implements Suspicious
|
||||
@Override
|
||||
public boolean addCustomEffect(PotionEffect effect, boolean overwrite) {
|
||||
Preconditions.checkArgument(effect != null, "Potion effect cannot be null");
|
||||
+ return addCustomEffect(io.papermc.paper.potion.SuspiciousEffectEntry.create(effect.getType(), effect.getDuration()), overwrite); // Paper - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta
|
||||
+ }
|
||||
|
||||
- int index = this.indexOfEffect(effect.getType());
|
||||
- if (index != -1) {
|
||||
- if (overwrite) {
|
||||
- PotionEffect old = this.customEffects.get(index);
|
||||
- if (old.getDuration() == effect.getDuration()) {
|
||||
+ // Paper start - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta
|
||||
+ @Override
|
||||
+ public boolean addCustomEffect(final io.papermc.paper.potion.SuspiciousEffectEntry suspiciousEffectEntry, final boolean overwrite) {
|
||||
+ Preconditions.checkArgument(suspiciousEffectEntry != null, "Suspicious effect entry cannot be null");
|
||||
+ if (this.hasCustomEffects()) {
|
||||
+ final List<io.papermc.paper.potion.SuspiciousEffectEntry> matchingEffects = this.customEffects.stream().filter(
|
||||
+ entry -> entry.effect() == suspiciousEffectEntry.effect()
|
||||
+ ).toList();
|
||||
+ if (!matchingEffects.isEmpty()) {
|
||||
+ if (overwrite) {
|
||||
+ boolean foundMatchingDuration = false;
|
||||
+ boolean mutated = false;
|
||||
+ for (final io.papermc.paper.potion.SuspiciousEffectEntry matchingEffect : matchingEffects) {
|
||||
+ if (matchingEffect.duration() != suspiciousEffectEntry.duration()) {
|
||||
+ this.customEffects.remove(suspiciousEffectEntry);
|
||||
+ mutated = true;
|
||||
+ } else {
|
||||
+ foundMatchingDuration = true;
|
||||
+ }
|
||||
+ }
|
||||
+ if (foundMatchingDuration && !mutated) {
|
||||
+ return false;
|
||||
+ } else if (!foundMatchingDuration) {
|
||||
+ this.customEffects.add(suspiciousEffectEntry);
|
||||
+ }
|
||||
+ return true;
|
||||
+ } else {
|
||||
return false;
|
||||
}
|
||||
- this.customEffects.set(index, effect);
|
||||
- return true;
|
||||
- } else {
|
||||
- return false;
|
||||
}
|
||||
- } else {
|
||||
- if (this.customEffects == null) {
|
||||
- this.customEffects = new ArrayList<>();
|
||||
- }
|
||||
- this.customEffects.add(effect);
|
||||
- return true;
|
||||
}
|
||||
+ if (this.customEffects == null) {
|
||||
+ this.customEffects = new ArrayList<>();
|
||||
+ }
|
||||
+ this.customEffects.add(suspiciousEffectEntry);
|
||||
+ return true;
|
||||
}
|
||||
+ // Paper end - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta
|
||||
|
||||
@Override
|
||||
public boolean removeCustomEffect(PotionEffectType type) {
|
||||
@@ -145,10 +165,12 @@ public class CraftMetaSuspiciousStew extends CraftMetaItem implements Suspicious
|
||||
}
|
||||
|
||||
boolean changed = false;
|
||||
- Iterator<PotionEffect> iterator = this.customEffects.iterator();
|
||||
+ // Paper start - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta
|
||||
+ Iterator<io.papermc.paper.potion.SuspiciousEffectEntry> iterator = this.customEffects.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
- PotionEffect effect = iterator.next();
|
||||
- if (type.equals(effect.getType())) {
|
||||
+ io.papermc.paper.potion.SuspiciousEffectEntry effect = iterator.next();
|
||||
+ if (type.equals(effect.effect())) {
|
||||
+ // Paper end - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta
|
||||
iterator.remove();
|
||||
changed = true;
|
||||
}
|
||||
@@ -171,7 +193,7 @@ public class CraftMetaSuspiciousStew extends CraftMetaItem implements Suspicious
|
||||
}
|
||||
|
||||
for (int i = 0; i < this.customEffects.size(); i++) {
|
||||
- if (this.customEffects.get(i).getType().equals(type)) {
|
||||
+ if (this.customEffects.get(i).effect().equals(type)) { // Paper - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -216,7 +238,7 @@ public class CraftMetaSuspiciousStew extends CraftMetaItem implements Suspicious
|
||||
super.serialize(builder);
|
||||
|
||||
if (this.hasCustomEffects()) {
|
||||
- builder.put(CraftMetaSuspiciousStew.EFFECTS.BUKKIT, ImmutableList.copyOf(this.customEffects));
|
||||
+ builder.put(CraftMetaSuspiciousStew.EFFECTS.BUKKIT, ImmutableList.copyOf(com.google.common.collect.Lists.transform(this.customEffects, s -> new PotionEffect(s.effect(), s.duration(), 0)))); // Paper - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta - convert back to potion effect for bukkit legacy item serialisation to maintain backwards compatibility for the written format.
|
||||
}
|
||||
|
||||
return builder;
|
|
@ -1,19 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: granny <contact@granny.dev>
|
||||
Date: Sat, 24 Feb 2024 19:33:01 -0800
|
||||
Subject: [PATCH] check if itemstack is stackable first
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Inventory.java b/src/main/java/net/minecraft/world/entity/player/Inventory.java
|
||||
index a62e7354bf67a66bdf9cd7c8f5d2e8f6bcacc74f..6e66141dca61f777b354854b5d0bac2570b8bf3b 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Inventory.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Inventory.java
|
||||
@@ -111,7 +111,7 @@ public class Inventory implements Container, Nameable {
|
||||
}
|
||||
|
||||
private boolean hasRemainingSpaceForItem(ItemStack existingStack, ItemStack stack) {
|
||||
- return !existingStack.isEmpty() && ItemStack.isSameItemSameComponents(existingStack, stack) && existingStack.isStackable() && existingStack.getCount() < this.getMaxStackSize(existingStack);
|
||||
+ return !existingStack.isEmpty() && existingStack.isStackable() && existingStack.getCount() < this.getMaxStackSize(existingStack) && ItemStack.isSameItemSameComponents(existingStack, stack); // Paper - check if itemstack is stackable first
|
||||
}
|
||||
|
||||
// CraftBukkit start - Watch method above! :D
|
|
@ -1,41 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake <jake.m.potrebic@gmail.com>
|
||||
Date: Sat, 15 Jun 2024 18:50:18 +0100
|
||||
Subject: [PATCH] Fix removing recipes from RecipeIterator
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.item.crafting.RecipeManager byName
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java b/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java
|
||||
index 78a2afa981407de793ac940d6eb7315c5cd53b8f..33cd12d55786356dc89ab9d3872b2f7d266c3de2 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java
|
||||
@@ -9,6 +9,7 @@ import org.bukkit.inventory.Recipe;
|
||||
|
||||
public class RecipeIterator implements Iterator<Recipe> {
|
||||
private final Iterator<Map.Entry<RecipeType<?>, RecipeHolder<?>>> recipes;
|
||||
+ private Recipe currentRecipe; // Paper - fix removing recipes from RecipeIterator
|
||||
|
||||
public RecipeIterator() {
|
||||
this.recipes = MinecraftServer.getServer().getRecipeManager().byType.entries().iterator();
|
||||
@@ -21,11 +22,19 @@ public class RecipeIterator implements Iterator<Recipe> {
|
||||
|
||||
@Override
|
||||
public Recipe next() {
|
||||
- return this.recipes.next().getValue().toBukkitRecipe();
|
||||
+ // Paper start - fix removing recipes from RecipeIterator
|
||||
+ this.currentRecipe = this.recipes.next().getValue().toBukkitRecipe();
|
||||
+ return this.currentRecipe;
|
||||
+ // Paper end - fix removing recipes from RecipeIterator
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
+ // Paper start - fix removing recipes from RecipeIterator
|
||||
+ if (this.currentRecipe instanceof org.bukkit.Keyed keyed) {
|
||||
+ MinecraftServer.getServer().getRecipeManager().byName.remove(org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(keyed.getKey()));
|
||||
+ }
|
||||
+ // Paper end - fix removing recipes from RecipeIterator
|
||||
this.recipes.remove();
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Bjarne Koll <lynxplay101@gmail.com>
|
||||
Date: Thu, 13 Jun 2024 17:16:01 +0200
|
||||
Subject: [PATCH] Configurable damage tick when blocking with shield
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 7b6d067eb8b22a8e0a82a2969c92ba243230733a..5f1c585c819d25319a4fefd30abde3de7620cf6d 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -2411,7 +2411,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
CriteriaTriggers.PLAYER_HURT_ENTITY.trigger((ServerPlayer) damagesource.getEntity(), this, damagesource, originalDamage, f, true); // Paper - fix taken/dealt param order
|
||||
}
|
||||
|
||||
- return true;
|
||||
+ return !io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.skipVanillaDamageTickWhenShieldBlocked; // Paper - this should always return true, however expose an unsupported setting to flip this to false to enable "shield stunning".
|
||||
} else {
|
||||
return true; // Paper - return false ONLY if event was cancelled
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 8 Jun 2023 14:45:18 -0700
|
||||
Subject: [PATCH] Properly remove the experimental smithing inventory type
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftAbstractInventoryView.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftAbstractInventoryView.java
|
||||
index 149825642976124e852be9aef54a3cb4a8ac193d..71d3a5e5dc5630007cf46f4be3d39da4145dd431 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftAbstractInventoryView.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftAbstractInventoryView.java
|
||||
@@ -160,7 +160,6 @@ public abstract class CraftAbstractInventoryView implements InventoryView {
|
||||
type = InventoryType.SlotType.CRAFTING;
|
||||
break;
|
||||
case ANVIL:
|
||||
- case SMITHING:
|
||||
case CARTOGRAPHY:
|
||||
case GRINDSTONE:
|
||||
case MERCHANT:
|
||||
@@ -178,6 +177,7 @@ public abstract class CraftAbstractInventoryView implements InventoryView {
|
||||
}
|
||||
break;
|
||||
case LOOM:
|
||||
+ case SMITHING: // Paper - properly remove experimental smithing inventory
|
||||
case SMITHING_NEW:
|
||||
if (slot == 3) {
|
||||
type = InventoryType.SlotType.RESULT;
|
Loading…
Add table
Add a link
Reference in a new issue