988
This commit is contained in:
parent
4140de28eb
commit
6d4e235784
45 changed files with 190 additions and 443 deletions
|
@ -1,169 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 13 May 2020 23:01:26 -0400
|
||||
Subject: [PATCH] Protect Bedrock and End Portal/Frames from being destroyed
|
||||
|
||||
This fixes exploits that let players destroy bedrock by Pistons, explosions
|
||||
and Mushrooom/Tree generation.
|
||||
|
||||
These blocks are designed to not be broken except by creative players/commands.
|
||||
So protect them from a multitude of methods of destroying them.
|
||||
|
||||
A config is provided if you rather let players use these exploits, and let
|
||||
them destroy the worlds End Portals and get on top of the nether easy.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
|
||||
index 4107756fb31e4ad99f643184118d877aef09e9f4..ef40b996864c81d7e8fbb0727ea0a96f866c725f 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Explosion.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Explosion.java
|
||||
@@ -192,6 +192,7 @@ public class Explosion {
|
||||
for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) {
|
||||
BlockPos blockposition = BlockPos.containing(d4, d5, d6);
|
||||
BlockState iblockdata = this.level.getBlockState(blockposition);
|
||||
+ if (!iblockdata.isDestroyable()) continue; // Paper - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
FluidState fluid = iblockdata.getFluidState(); // Paper - Perf: Optimize call to getFluid for explosions
|
||||
|
||||
if (!this.level.isInWorldBounds(blockposition)) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index ee49f59ba8ce5708fc5e244eba7b1f910cf69263..d3d7abb2d31e8ce9f9c53eca66a83a1c28fec792 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -533,6 +533,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
public boolean setBlock(BlockPos pos, BlockState state, int flags, int maxUpdateDepth) {
|
||||
// CraftBukkit start - tree generation
|
||||
if (this.captureTreeGeneration) {
|
||||
+ // Paper start - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
+ BlockState type = getBlockState(pos);
|
||||
+ if (!type.isDestroyable()) return false;
|
||||
+ // Paper end - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
CraftBlockState blockstate = this.capturedBlockStates.get(pos);
|
||||
if (blockstate == null) {
|
||||
blockstate = CapturedBlockState.getTreeBlockState(this, pos, flags);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
index 7f0c0ca49e7575c18935b71e3180d112440289f7..054593fc0b8d13f6bf449cc20a1f7ddfd5f1d1f0 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
@@ -90,6 +90,19 @@ public class Block extends BlockBehaviour implements ItemLike {
|
||||
protected final StateDefinition<Block, BlockState> stateDefinition;
|
||||
private BlockState defaultBlockState;
|
||||
// Paper start
|
||||
+ public final boolean isDestroyable() {
|
||||
+ return io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits ||
|
||||
+ this != Blocks.BEDROCK &&
|
||||
+ this != Blocks.END_PORTAL_FRAME &&
|
||||
+ this != Blocks.END_PORTAL &&
|
||||
+ this != Blocks.END_GATEWAY &&
|
||||
+ this != Blocks.COMMAND_BLOCK &&
|
||||
+ this != Blocks.REPEATING_COMMAND_BLOCK &&
|
||||
+ this != Blocks.CHAIN_COMMAND_BLOCK &&
|
||||
+ this != Blocks.BARRIER &&
|
||||
+ this != Blocks.STRUCTURE_BLOCK &&
|
||||
+ this != Blocks.JIGSAW;
|
||||
+ }
|
||||
public co.aikar.timings.Timing timing;
|
||||
public co.aikar.timings.Timing getTiming() {
|
||||
if (timing == null) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
||||
index e6bfbe2588e0c2a1be14e38d654e889d392ad4db..e0c62227b279a5fe0f3868fbf9ce8c78c515a09c 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
||||
@@ -213,6 +213,12 @@ public class PistonBaseBlock extends DirectionalBlock {
|
||||
@Override
|
||||
protected boolean triggerEvent(BlockState state, Level world, BlockPos pos, int type, int data) {
|
||||
Direction enumdirection = (Direction) state.getValue(PistonBaseBlock.FACING);
|
||||
+ // Paper start - Protect Bedrock and End Portal/Frames from being destroyed; prevent retracting when we're facing the wrong way (we were replaced before retraction could occur)
|
||||
+ Direction directionQueuedAs = Direction.from3DDataValue(data & 7); // Paper - copied from below
|
||||
+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits && enumdirection != directionQueuedAs) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper end - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
BlockState iblockdata1 = (BlockState) state.setValue(PistonBaseBlock.EXTENDED, true);
|
||||
|
||||
if (!world.isClientSide) {
|
||||
@@ -253,7 +259,7 @@ public class PistonBaseBlock extends DirectionalBlock {
|
||||
}
|
||||
// Paper end - Fix sticky pistons and BlockPistonRetractEvent
|
||||
world.setBlock(pos, iblockdata2, 20);
|
||||
- world.setBlockEntity(MovingPistonBlock.newMovingBlockEntity(pos, iblockdata2, (BlockState) this.defaultBlockState().setValue(PistonBaseBlock.FACING, Direction.from3DDataValue(data & 7)), enumdirection, false, true));
|
||||
+ world.setBlockEntity(MovingPistonBlock.newMovingBlockEntity(pos, iblockdata2, (BlockState) this.defaultBlockState().setValue(PistonBaseBlock.FACING, Direction.from3DDataValue(data & 7)), enumdirection, false, true)); // Paper - Protect Bedrock and End Portal/Frames from being destroyed; diff on change
|
||||
world.blockUpdated(pos, iblockdata2.getBlock());
|
||||
iblockdata2.updateNeighbourShapes(world, pos, 2);
|
||||
if (this.isSticky) {
|
||||
@@ -289,7 +295,14 @@ public class PistonBaseBlock extends DirectionalBlock {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
- world.removeBlock(pos.relative(enumdirection), false);
|
||||
+ // Paper start - Protect Bedrock and End Portal/Frames from being destroyed; fix headless pistons breaking blocks
|
||||
+ BlockPos headPos = pos.relative(enumdirection);
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits || world.getBlockState(headPos) == Blocks.PISTON_HEAD.defaultBlockState().setValue(FACING, enumdirection)) { // double check to make sure we're not a headless piston.
|
||||
+ world.removeBlock(headPos, false);
|
||||
+ } else {
|
||||
+ ((ServerLevel) world).getChunkSource().blockChanged(headPos); // ... fix client desync
|
||||
+ }
|
||||
+ // Paper end - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
}
|
||||
|
||||
world.playSound((Player) null, pos, SoundEvents.PISTON_CONTRACT, SoundSource.BLOCKS, 0.5F, world.random.nextFloat() * 0.15F + 0.6F);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
index c7da359c525522b55763e594a1db0c26a026b73f..55efd0d379bac79935f62446cd3479d1e59361a4 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
@@ -174,7 +174,7 @@ public abstract class BlockBehaviour implements FeatureElement {
|
||||
}
|
||||
|
||||
protected void onExplosionHit(BlockState state, Level world, BlockPos pos, Explosion explosion, BiConsumer<ItemStack, BlockPos> stackMerger) {
|
||||
- if (!state.isAir() && explosion.getBlockInteraction() != Explosion.BlockInteraction.TRIGGER_BLOCK) {
|
||||
+ if (!state.isAir() && explosion.getBlockInteraction() != Explosion.BlockInteraction.TRIGGER_BLOCK && state.isDestroyable()) { // Paper - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
Block block = state.getBlock();
|
||||
boolean flag = explosion.getIndirectSourceEntity() instanceof Player;
|
||||
|
||||
@@ -254,7 +254,7 @@ public abstract class BlockBehaviour implements FeatureElement {
|
||||
}
|
||||
|
||||
protected boolean canBeReplaced(BlockState state, BlockPlaceContext context) {
|
||||
- return state.canBeReplaced() && (context.getItemInHand().isEmpty() || !context.getItemInHand().is(this.asItem()));
|
||||
+ return state.canBeReplaced() && (context.getItemInHand().isEmpty() || !context.getItemInHand().is(this.asItem())) && (state.isDestroyable() || (context.getPlayer() != null && context.getPlayer().getAbilities().instabuild)); // Paper - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
}
|
||||
|
||||
protected boolean canBeReplaced(BlockState state, Fluid fluid) {
|
||||
@@ -896,6 +896,12 @@ public abstract class BlockBehaviour implements FeatureElement {
|
||||
return this.legacySolid;
|
||||
}
|
||||
|
||||
+ // Paper start - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
+ public final boolean isDestroyable() {
|
||||
+ return getBlock().isDestroyable();
|
||||
+ }
|
||||
+ // Paper end - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
+
|
||||
public boolean isValidSpawn(BlockGetter world, BlockPos pos, EntityType<?> type) {
|
||||
return this.getBlock().properties.isValidSpawn.test(this.asState(), world, pos, type);
|
||||
}
|
||||
@@ -999,7 +1005,7 @@ public abstract class BlockBehaviour implements FeatureElement {
|
||||
}
|
||||
|
||||
public PushReaction getPistonPushReaction() {
|
||||
- return this.pushReaction;
|
||||
+ return !this.isDestroyable() ? PushReaction.BLOCK : this.pushReaction; // Paper - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
}
|
||||
|
||||
public boolean isSolidRender(BlockGetter world, BlockPos pos) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java
|
||||
index 03dd833d61d5152af3032f23dd1fc4c75da9bc4f..a61959700d5e00739a79eaa617ac383160335f26 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java
|
||||
@@ -221,6 +221,13 @@ public class PortalForcer {
|
||||
for (int j = -1; j < 3; ++j) {
|
||||
for (int k = -1; k < 4; ++k) {
|
||||
temp.setWithOffset(pos, portalDirection.getStepX() * j + enumdirection1.getStepX() * distanceOrthogonalToPortal, k, portalDirection.getStepZ() * j + enumdirection1.getStepZ() * distanceOrthogonalToPortal);
|
||||
+ // Paper start - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits) {
|
||||
+ if (!this.level.getBlockState(temp).isDestroyable()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
if (k < 0 && !this.level.getBlockState(temp).isSolid()) {
|
||||
return false;
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: DungeonDev <dungeondevtn@gmail.com>
|
||||
Date: Sun, 2 Jul 2023 02:34:54 +0100
|
||||
Subject: [PATCH] Fix tripwire disarming not working as intended
|
||||
|
||||
Fixes MC-129055
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java b/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java
|
||||
index 8614fad5b3df7a6030384b108b1689bf6b9f1209..76aca266d3f3222502ff4c196228f08fcd88c5f8 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java
|
||||
@@ -202,9 +202,8 @@ public class TripWireHookBlock extends Block {
|
||||
BlockState iblockdata4 = aiblockdata[l];
|
||||
|
||||
if (iblockdata4 != null) {
|
||||
+ if (world.getBlockState(blockposition2).is(Blocks.TRIPWIRE) || io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowTripwireDisarmingExploits) { // Paper - Fix tripwire disarming not working as intended
|
||||
world.setBlock(blockposition2, (BlockState) iblockdata4.trySetValue(TripWireHookBlock.ATTACHED, flag4), 3);
|
||||
- if (!world.getBlockState(blockposition2).isAir()) {
|
||||
- ;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Wed, 2 Dec 2020 21:03:02 -0800
|
||||
Subject: [PATCH] Add config for mobs immune to default effects
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
index c23d4ee0a16d1ae7168b2496d97189a14256bdcc..7ddca52f7fe3f289b4b867e134326b1ead1a2aee 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
@@ -604,7 +604,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
|
||||
|
||||
@Override
|
||||
public boolean canBeAffected(MobEffectInstance effect) {
|
||||
- return effect.is(MobEffects.WITHER) ? false : super.canBeAffected(effect);
|
||||
+ return effect.is(MobEffects.WITHER) && this.level().paperConfig().entities.mobEffects.immuneToWitherEffect.wither ? false : super.canBeAffected(effect); // Paper - Add config for mobs immune to default effects
|
||||
}
|
||||
|
||||
private class WitherDoNothingGoal extends Goal {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Spider.java b/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
index ef8911f7bcf6a97496675abb4689bb09cf322e85..fa0316e9d2a4cf213982994dc8bf310299cca984 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
||||
@@ -126,7 +126,7 @@ public class Spider extends Monster {
|
||||
|
||||
@Override
|
||||
public boolean canBeAffected(MobEffectInstance effect) {
|
||||
- return effect.is(MobEffects.POISON) ? false : super.canBeAffected(effect);
|
||||
+ return effect.is(MobEffects.POISON) && this.level().paperConfig().entities.mobEffects.spidersImmuneToPoisonEffect ? false : super.canBeAffected(effect); // Paper - Add config for mobs immune to default effects
|
||||
}
|
||||
|
||||
public boolean isClimbing() {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java
|
||||
index 05e9b083f7e49bd7a24f04fd2c46acef6d011e48..3f1191795e58f31b7e2fe34ef2774df13b9a789f 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java
|
||||
@@ -113,6 +113,6 @@ public class WitherSkeleton extends AbstractSkeleton {
|
||||
|
||||
@Override
|
||||
public boolean canBeAffected(MobEffectInstance effect) {
|
||||
- return effect.is(MobEffects.WITHER) ? false : super.canBeAffected(effect);
|
||||
+ return effect.is(MobEffects.WITHER) && this.level().paperConfig().entities.mobEffects.immuneToWitherEffect.witherSkeleton ? false : super.canBeAffected(effect); // Paper - Add config for mobs immune to default effects
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: SoSeDiK <mrsosedik@gmail.com>
|
||||
Date: Thu, 26 May 2022 03:30:05 +0300
|
||||
Subject: [PATCH] Deep clone nbt tags in PDC
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
index e3ac829ae4f2b39c103e5626180ec9220c2b1f33..2b131cc6f511416d4c8964848caff373a9c6325d 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
@@ -307,7 +307,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
this.damage = meta.damage;
|
||||
this.maxDamage = meta.maxDamage;
|
||||
this.unhandledTags = meta.unhandledTags;
|
||||
- this.persistentDataContainer.putAll(meta.persistentDataContainer.getRaw());
|
||||
+ this.persistentDataContainer.putAll(meta.persistentDataContainer.getTagsCloned()); // Paper - deep clone NBT tags
|
||||
|
||||
this.customTag = meta.customTag;
|
||||
|
||||
@@ -1601,7 +1601,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
if (this.customTag != null) {
|
||||
clone.customTag = this.customTag.copy();
|
||||
}
|
||||
- clone.persistentDataContainer = new CraftPersistentDataContainer(this.persistentDataContainer.getRaw(), CraftMetaItem.DATA_TYPE_REGISTRY);
|
||||
+ clone.persistentDataContainer = new CraftPersistentDataContainer(this.persistentDataContainer.getTagsCloned(), CraftMetaItem.DATA_TYPE_REGISTRY); // Paper - deep clone NBT tags
|
||||
clone.hideFlag = this.hideFlag;
|
||||
clone.hideTooltip = this.hideTooltip;
|
||||
clone.unbreakable = this.unbreakable;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
|
||||
index 5a4e7e7150b7c137b077e0b393f17ed35b5aec34..f55fdd57ced259ad5a95878840e98ffaa3db2e05 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
|
||||
@@ -207,4 +207,12 @@ public class CraftPersistentDataContainer implements PersistentDataContainer {
|
||||
}
|
||||
}
|
||||
// Paper end - byte array serialization
|
||||
+
|
||||
+ // Paper start - deep clone tags
|
||||
+ public Map<String, Tag> getTagsCloned() {
|
||||
+ final Map<String, Tag> tags = new HashMap<>();
|
||||
+ this.customDataTags.forEach((key, tag) -> tags.put(key, tag.copy()));
|
||||
+ return tags;
|
||||
+ }
|
||||
+ // Paper end - deep clone tags
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 29 Jun 2020 03:26:17 -0400
|
||||
Subject: [PATCH] Support old UUID format for NBT
|
||||
|
||||
We have stored UUID in plenty of places that did not get DFU'd
|
||||
|
||||
So just look for old format and load it if it exists.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/nbt/CompoundTag.java b/src/main/java/net/minecraft/nbt/CompoundTag.java
|
||||
index df246d69591e1a5822a0109c99b0f67996da71fa..4e005b7b062e3231f564d284887ea1c2783a4e7d 100644
|
||||
--- a/src/main/java/net/minecraft/nbt/CompoundTag.java
|
||||
+++ b/src/main/java/net/minecraft/nbt/CompoundTag.java
|
||||
@@ -232,6 +232,12 @@ public class CompoundTag implements Tag {
|
||||
}
|
||||
|
||||
public void putUUID(String key, UUID value) {
|
||||
+ // Paper start - Support old UUID format
|
||||
+ if (this.contains(key + "Most", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC) && this.contains(key + "Least", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC)) {
|
||||
+ this.tags.remove(key + "Most");
|
||||
+ this.tags.remove(key + "Least");
|
||||
+ }
|
||||
+ // Paper end - Support old UUID format
|
||||
this.tags.put(key, NbtUtils.createUUID(value));
|
||||
}
|
||||
|
||||
@@ -240,10 +246,20 @@ public class CompoundTag implements Tag {
|
||||
* You must use {@link #hasUUID(String)} before or else it <b>will</b> throw an NPE.
|
||||
*/
|
||||
public UUID getUUID(String key) {
|
||||
+ // Paper start - Support old UUID format
|
||||
+ if (!contains(key, 11) && this.contains(key + "Most", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC) && this.contains(key + "Least", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC)) {
|
||||
+ return new UUID(this.getLong(key + "Most"), this.getLong(key + "Least"));
|
||||
+ }
|
||||
+ // Paper end - Support old UUID format
|
||||
return NbtUtils.loadUUID(this.get(key));
|
||||
}
|
||||
|
||||
public boolean hasUUID(String key) {
|
||||
+ // Paper start - Support old UUID format
|
||||
+ if (this.contains(key + "Most", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC) && this.contains(key + "Least", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end - Support old UUID format
|
||||
Tag tag = this.get(key);
|
||||
return tag != null && tag.getType() == IntArrayTag.TYPE && ((IntArrayTag)tag).getAsIntArray().length == 4;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/component/ResolvableProfile.java b/src/main/java/net/minecraft/world/item/component/ResolvableProfile.java
|
||||
index 78863e72239a0f3535bc85758479da84d58c11c1..38bbe39a5cd96710b208d70ed78619057bb6e6fa 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/component/ResolvableProfile.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/component/ResolvableProfile.java
|
||||
@@ -20,9 +20,10 @@ public record ResolvableProfile(Optional<String> name, Optional<UUID> id, Proper
|
||||
instance -> instance.group(
|
||||
ExtraCodecs.PLAYER_NAME.optionalFieldOf("name").forGetter(ResolvableProfile::name),
|
||||
UUIDUtil.CODEC.optionalFieldOf("id").forGetter(ResolvableProfile::id),
|
||||
+ UUIDUtil.STRING_CODEC.lenientOptionalFieldOf("Id").forGetter($ -> Optional.empty()), // Paper
|
||||
ExtraCodecs.PROPERTY_MAP.optionalFieldOf("properties", new PropertyMap()).forGetter(ResolvableProfile::properties)
|
||||
)
|
||||
- .apply(instance, ResolvableProfile::new)
|
||||
+ .apply(instance, (s, uuid, uuid2, propertyMap) -> new ResolvableProfile(s, uuid2.or(() -> uuid), propertyMap)) // Paper
|
||||
);
|
||||
public static final Codec<ResolvableProfile> CODEC = Codec.withAlternative(
|
||||
FULL_CODEC, ExtraCodecs.PLAYER_NAME, name -> new ResolvableProfile(Optional.of(name), Optional.empty(), new PropertyMap())
|
|
@ -1,22 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Fri, 26 Apr 2024 19:08:37 -0700
|
||||
Subject: [PATCH] Fix shield disable inconsistency
|
||||
|
||||
In vanilla, if the damage source is tagged as a projectile,
|
||||
it will not disable the shield if the attacker is holding
|
||||
an axe item.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 4928dc3c879ddad0fe8c377b1b26e543a1c40cca..6118de380a95b0c927a239ac3e288780f114289e 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -2325,7 +2325,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
this.hurtCurrentlyUsedShield((float) -event.getDamage(DamageModifier.BLOCKING));
|
||||
Entity entity = damagesource.getDirectEntity();
|
||||
|
||||
- if (entity instanceof LivingEntity && entity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper - Improve boat collision performance
|
||||
+ if (!damagesource.is(DamageTypeTags.IS_PROJECTILE) && entity instanceof LivingEntity && entity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper - Improve boat collision performance
|
||||
this.blockUsingShield((LivingEntity) entity);
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Fri, 26 Apr 2024 21:33:20 -0700
|
||||
Subject: [PATCH] Don't lose removed data components in ItemMeta
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
index 2b131cc6f511416d4c8964848caff373a9c6325d..b525bfbab2c4a5ea408981287f477a8b35d699ca 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
@@ -191,6 +191,13 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
return this;
|
||||
}
|
||||
|
||||
+ // Paper start - support removing component types
|
||||
+ <T> Applicator remove(DataComponentType<T> type) {
|
||||
+ this.builder.remove(type);
|
||||
+ return this;
|
||||
+ }
|
||||
+ // Paper end - support removing component types
|
||||
+
|
||||
DataComponentPatch build() {
|
||||
return this.builder.build();
|
||||
}
|
||||
@@ -410,7 +417,9 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
|
||||
Set<Map.Entry<DataComponentType<?>, Optional<?>>> keys = tag.entrySet();
|
||||
for (Map.Entry<DataComponentType<?>, Optional<?>> key : keys) {
|
||||
- if (!CraftMetaItem.getHandledTags().contains(key.getKey())) {
|
||||
+ if (key.getValue().isEmpty()) {
|
||||
+ this.unhandledTags.remove(key.getKey());
|
||||
+ } else if (!CraftMetaItem.getHandledTags().contains(key.getKey())) {
|
||||
key.getValue().ifPresentOrElse((value) -> {
|
||||
this.unhandledTags.set((DataComponentType) key.getKey(), value);
|
||||
}, () -> {
|
||||
@@ -809,9 +818,9 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
}
|
||||
|
||||
for (Map.Entry<DataComponentType<?>, Optional<?>> e : this.unhandledTags.build().entrySet()) {
|
||||
- e.getValue().ifPresent((value) -> {
|
||||
+ e.getValue().ifPresentOrElse((value) -> {
|
||||
itemTag.builder.set((DataComponentType) e.getKey(), value);
|
||||
- });
|
||||
+ }, () -> itemTag.remove(e.getKey()));
|
||||
}
|
||||
|
||||
CompoundTag customTag = (this.customTag != null) ? this.customTag.copy() : null;
|
|
@ -1,255 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Fri, 26 Apr 2024 23:15:27 -0700
|
||||
Subject: [PATCH] Add experimental improved give command
|
||||
|
||||
Supports removing data components from itemstacks
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/commands/arguments/item/ItemArgument.java b/src/main/java/net/minecraft/commands/arguments/item/ItemArgument.java
|
||||
index d76296c6d53065aecb010d8ea682c9acd7365f17..9314a94764786982eff0974411f8341bb0353ecf 100644
|
||||
--- a/src/main/java/net/minecraft/commands/arguments/item/ItemArgument.java
|
||||
+++ b/src/main/java/net/minecraft/commands/arguments/item/ItemArgument.java
|
||||
@@ -16,7 +16,12 @@ public class ItemArgument implements ArgumentType<ItemInput> {
|
||||
private final ItemParser parser;
|
||||
|
||||
public ItemArgument(CommandBuildContext commandRegistryAccess) {
|
||||
- this.parser = new ItemParser(commandRegistryAccess);
|
||||
+ // Paper start - support component removals
|
||||
+ this(commandRegistryAccess, false);
|
||||
+ }
|
||||
+ public ItemArgument(CommandBuildContext commandRegistryAccess, boolean allowRemovals) {
|
||||
+ this.parser = new ItemParser(commandRegistryAccess, allowRemovals);
|
||||
+ // Paper end - support component removals
|
||||
}
|
||||
|
||||
public static ItemArgument item(CommandBuildContext commandRegistryAccess) {
|
||||
@@ -25,7 +30,7 @@ public class ItemArgument implements ArgumentType<ItemInput> {
|
||||
|
||||
public ItemInput parse(StringReader stringReader) throws CommandSyntaxException {
|
||||
ItemParser.ItemResult itemResult = this.parser.parse(stringReader);
|
||||
- return new ItemInput(itemResult.item(), itemResult.components());
|
||||
+ return new ItemInput(itemResult.item(), itemResult.components(), itemResult.patch()); // Paper - support component removals
|
||||
}
|
||||
|
||||
public static <S> ItemInput getItem(CommandContext<S> context, String name) {
|
||||
diff --git a/src/main/java/net/minecraft/commands/arguments/item/ItemInput.java b/src/main/java/net/minecraft/commands/arguments/item/ItemInput.java
|
||||
index 3d24fbca90bc7d8bdbac1be2176555c15ae75039..94ea5f0b1913ffa03794d231a6768dd786dc9697 100644
|
||||
--- a/src/main/java/net/minecraft/commands/arguments/item/ItemInput.java
|
||||
+++ b/src/main/java/net/minecraft/commands/arguments/item/ItemInput.java
|
||||
@@ -25,8 +25,15 @@ public class ItemInput {
|
||||
);
|
||||
private final Holder<Item> item;
|
||||
private final DataComponentMap components;
|
||||
+ @javax.annotation.Nullable private final net.minecraft.core.component.DataComponentPatch patch; // Paper
|
||||
|
||||
public ItemInput(Holder<Item> item, DataComponentMap components) {
|
||||
+ // Paper start
|
||||
+ this(item, components, null);
|
||||
+ }
|
||||
+ public ItemInput(Holder<Item> item, DataComponentMap components, @javax.annotation.Nullable final net.minecraft.core.component.DataComponentPatch patch) {
|
||||
+ this.patch = patch;
|
||||
+ // Paper end
|
||||
this.item = item;
|
||||
this.components = components;
|
||||
}
|
||||
@@ -37,7 +44,13 @@ public class ItemInput {
|
||||
|
||||
public ItemStack createItemStack(int amount, boolean checkOverstack) throws CommandSyntaxException {
|
||||
ItemStack itemStack = new ItemStack(this.item, amount);
|
||||
- itemStack.applyComponents(this.components);
|
||||
+ // Paper start - support component removals
|
||||
+ if (this.patch != null) {
|
||||
+ itemStack.applyComponents(this.patch);
|
||||
+ } else {
|
||||
+ itemStack.applyComponents(this.components);
|
||||
+ }
|
||||
+ // Paper end - support component removals
|
||||
if (checkOverstack && amount > itemStack.getMaxStackSize()) {
|
||||
throw ERROR_STACK_TOO_BIG.create(this.getItemName(), itemStack.getMaxStackSize());
|
||||
} else {
|
||||
diff --git a/src/main/java/net/minecraft/commands/arguments/item/ItemParser.java b/src/main/java/net/minecraft/commands/arguments/item/ItemParser.java
|
||||
index 5347a96be3bfbbd2963747ba4b5f222215d80371..fa431de18de902c580855e9c4419125519b6176b 100644
|
||||
--- a/src/main/java/net/minecraft/commands/arguments/item/ItemParser.java
|
||||
+++ b/src/main/java/net/minecraft/commands/arguments/item/ItemParser.java
|
||||
@@ -59,8 +59,15 @@ public class ItemParser {
|
||||
static final Function<SuggestionsBuilder, CompletableFuture<Suggestions>> SUGGEST_NOTHING = SuggestionsBuilder::buildFuture;
|
||||
final HolderLookup.RegistryLookup<Item> items;
|
||||
final DynamicOps<Tag> registryOps;
|
||||
+ final boolean allowRemoves; // Paper - support component removals
|
||||
|
||||
public ItemParser(HolderLookup.Provider registriesLookup) {
|
||||
+ // Paper start - support component removals
|
||||
+ this(registriesLookup, false);
|
||||
+ }
|
||||
+ public ItemParser(HolderLookup.Provider registriesLookup, boolean allowRemoves) {
|
||||
+ this.allowRemoves = allowRemoves;
|
||||
+ // Paper end - support component removals
|
||||
this.items = registriesLookup.lookupOrThrow(Registries.ITEM);
|
||||
this.registryOps = registriesLookup.createSerializationContext(NbtOps.INSTANCE);
|
||||
}
|
||||
@@ -68,6 +75,7 @@ public class ItemParser {
|
||||
public ItemParser.ItemResult parse(StringReader reader) throws CommandSyntaxException {
|
||||
final MutableObject<Holder<Item>> mutableObject = new MutableObject<>();
|
||||
final DataComponentMap.Builder builder = DataComponentMap.builder();
|
||||
+ final net.minecraft.core.component.DataComponentPatch.Builder patchBuilder = net.minecraft.core.component.DataComponentPatch.builder(); // Paper - support component removals
|
||||
this.parse(reader, new ItemParser.Visitor() {
|
||||
@Override
|
||||
public void visitItem(Holder<Item> item) {
|
||||
@@ -77,12 +85,19 @@ public class ItemParser {
|
||||
@Override
|
||||
public <T> void visitComponent(DataComponentType<T> type, T value) {
|
||||
builder.set(type, value);
|
||||
+ // Paper start - support component removals
|
||||
+ patchBuilder.set(type, value);
|
||||
+ }
|
||||
+ @Override
|
||||
+ public <T> void visitComponentRemove(final DataComponentType<T> type) {
|
||||
+ patchBuilder.remove(type);
|
||||
+ // Paper end - support component removals
|
||||
}
|
||||
});
|
||||
Holder<Item> holder = Objects.requireNonNull(mutableObject.getValue(), "Parser gave no item");
|
||||
DataComponentMap dataComponentMap = builder.build();
|
||||
validateComponents(reader, holder, dataComponentMap);
|
||||
- return new ItemParser.ItemResult(holder, dataComponentMap);
|
||||
+ return new ItemParser.ItemResult(holder, dataComponentMap, this.allowRemoves ? patchBuilder.build() : null); // Paper - support component removals
|
||||
}
|
||||
|
||||
private static void validateComponents(StringReader reader, Holder<Item> item, DataComponentMap components) throws CommandSyntaxException {
|
||||
@@ -116,7 +131,7 @@ public class ItemParser {
|
||||
return suggestionsVisitor.resolveSuggestions(builder, stringReader);
|
||||
}
|
||||
|
||||
- public static record ItemResult(Holder<Item> item, DataComponentMap components) {
|
||||
+ public static record ItemResult(Holder<Item> item, DataComponentMap components, @javax.annotation.Nullable net.minecraft.core.component.DataComponentPatch patch) { // Paper
|
||||
}
|
||||
|
||||
class State {
|
||||
@@ -154,17 +169,28 @@ public class ItemParser {
|
||||
|
||||
while (this.reader.canRead() && this.reader.peek() != ']') {
|
||||
this.reader.skipWhitespace();
|
||||
+ boolean removing = ItemParser.this.allowRemoves && this.reader.canRead() && this.reader.peek() == '!';
|
||||
+ if (removing) {
|
||||
+ this.reader.skip();
|
||||
+ this.visitor.visitSuggestions(builder -> this.suggestComponentAssignment(builder, false));
|
||||
+ }
|
||||
DataComponentType<?> dataComponentType = readComponentType(this.reader);
|
||||
if (!set.add(dataComponentType)) {
|
||||
throw ItemParser.ERROR_REPEATED_COMPONENT.create(dataComponentType);
|
||||
}
|
||||
|
||||
+ // Paper start - support component removals
|
||||
+ if (removing) {
|
||||
+ this.visitor.visitComponentRemove(dataComponentType);
|
||||
+ } else {
|
||||
+ // Paper end - support component removals
|
||||
this.visitor.visitSuggestions(this::suggestAssignment);
|
||||
this.reader.skipWhitespace();
|
||||
this.reader.expect('=');
|
||||
this.visitor.visitSuggestions(ItemParser.SUGGEST_NOTHING);
|
||||
this.reader.skipWhitespace();
|
||||
this.readComponent(dataComponentType);
|
||||
+ } // Paper - support component removals
|
||||
this.reader.skipWhitespace();
|
||||
this.visitor.visitSuggestions(this::suggestNextOrEndComponents);
|
||||
if (!this.reader.canRead() || this.reader.peek() != ',') {
|
||||
@@ -239,12 +265,18 @@ public class ItemParser {
|
||||
}
|
||||
|
||||
private CompletableFuture<Suggestions> suggestComponentAssignment(SuggestionsBuilder builder) {
|
||||
+ // Paper start - support component removals
|
||||
+ return this.suggestComponentAssignment(builder, true);
|
||||
+ }
|
||||
+ private CompletableFuture<Suggestions> suggestComponentAssignment(SuggestionsBuilder builder, boolean suggestRemove) {
|
||||
String string = builder.getRemaining().toLowerCase(Locale.ROOT);
|
||||
+ if (suggestRemove && string.isBlank()) builder.suggest("!", Component.literal("Remove a data component"));
|
||||
+ // Paper end - support component removals
|
||||
SharedSuggestionProvider.filterResources(BuiltInRegistries.DATA_COMPONENT_TYPE.entrySet(), string, entry -> entry.getKey().location(), entry -> {
|
||||
DataComponentType<?> dataComponentType = entry.getValue();
|
||||
if (dataComponentType.codec() != null) {
|
||||
ResourceLocation resourceLocation = entry.getKey().location();
|
||||
- builder.suggest(resourceLocation.toString() + "=");
|
||||
+ builder.suggest(resourceLocation.toString() + (suggestRemove ? "=" : "")); // Paper - support component removals
|
||||
}
|
||||
});
|
||||
return builder.buildFuture();
|
||||
@@ -270,6 +302,7 @@ public class ItemParser {
|
||||
|
||||
default <T> void visitComponent(DataComponentType<T> type, T value) {
|
||||
}
|
||||
+ default <T> void visitComponentRemove(DataComponentType<T> type) {} // Paper
|
||||
|
||||
default void visitSuggestions(Function<SuggestionsBuilder, CompletableFuture<Suggestions>> suggestor) {
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/commands/GiveCommand.java b/src/main/java/net/minecraft/server/commands/GiveCommand.java
|
||||
index 0d9de4c61c7b26a6ff37c12fde629161fd0c3d5a..47355158e5e762540a10dc67b23092a0fc53bce3 100644
|
||||
--- a/src/main/java/net/minecraft/server/commands/GiveCommand.java
|
||||
+++ b/src/main/java/net/minecraft/server/commands/GiveCommand.java
|
||||
@@ -34,6 +34,38 @@ public class GiveCommand {
|
||||
})).then(net.minecraft.commands.Commands.argument("count", IntegerArgumentType.integer(1)).executes((commandcontext) -> {
|
||||
return GiveCommand.giveItem((CommandSourceStack) commandcontext.getSource(), ItemArgument.getItem(commandcontext, "item"), EntityArgument.getPlayers(commandcontext, "targets"), IntegerArgumentType.getInteger(commandcontext, "count"));
|
||||
})))));
|
||||
+ // Paper start - support component removals with a custom pgive command
|
||||
+ final com.mojang.brigadier.tree.CommandNode<net.minecraft.commands.CommandSourceStack> node = net.minecraft.commands.Commands
|
||||
+ .literal("pgive").requires((css) -> css.hasPermission(2))
|
||||
+ .then(net.minecraft.commands.Commands.argument("targets", EntityArgument.players())
|
||||
+ .then(net.minecraft.commands.Commands.argument("item", new ItemArgument(commandRegistryAccess, true)).executes((ctx) -> {
|
||||
+ return GiveCommand.giveItem(ctx.getSource(), ItemArgument.getItem(ctx, "item"), EntityArgument.getPlayers(ctx, "targets"), 1);
|
||||
+ })
|
||||
+ .then(net.minecraft.commands.Commands.argument("count", IntegerArgumentType.integer(1)).executes((ctx) -> {
|
||||
+ return GiveCommand.giveItem(ctx.getSource(), ItemArgument.getItem(ctx, "item"), EntityArgument.getPlayers(ctx, "targets"), IntegerArgumentType.getInteger(ctx, "count"));
|
||||
+ }))
|
||||
+ )
|
||||
+ ).build();
|
||||
+ setClientNodes(node);
|
||||
+ dispatcher.getRoot().addChild(node);
|
||||
+ }
|
||||
+ static void setClientNodes(com.mojang.brigadier.tree.CommandNode<net.minecraft.commands.CommandSourceStack> node) {
|
||||
+ if (node instanceof com.mojang.brigadier.tree.ArgumentCommandNode<net.minecraft.commands.CommandSourceStack,?> argumentNode) {
|
||||
+ if (argumentNode.getType() instanceof ItemArgument) {
|
||||
+ node.clientNode = new com.mojang.brigadier.tree.ArgumentCommandNode<>(
|
||||
+ argumentNode.getName(),
|
||||
+ com.mojang.brigadier.arguments.StringArgumentType.greedyString(),
|
||||
+ argumentNode.getCommand(),
|
||||
+ argumentNode.getRequirement(),
|
||||
+ argumentNode.getRedirect(),
|
||||
+ argumentNode.getRedirectModifier(),
|
||||
+ argumentNode.isFork(),
|
||||
+ (ctx, builder) -> builder.buildFuture()
|
||||
+ );
|
||||
+ }
|
||||
+ }
|
||||
+ node.getChildren().forEach(GiveCommand::setClientNodes);
|
||||
+ // Paper end - support component removals with a custom pgive command
|
||||
}
|
||||
|
||||
private static int giveItem(CommandSourceStack source, ItemInput item, Collection<ServerPlayer> targets, int count) throws CommandSyntaxException {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
|
||||
index 2ee33c55890fa659f6d251e486264c85d9e89802..dd1507f65a7f1d84bc7f236f81a60ac1302a13b8 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
|
||||
@@ -96,6 +96,9 @@ public final class VanillaCommandWrapper extends BukkitCommand {
|
||||
vanillaCommand = vanillaCommand.getRedirect();
|
||||
}
|
||||
final String commandName = vanillaCommand.getName();
|
||||
+ if ("pgive".equals(stripDefaultNamespace(commandName))) {
|
||||
+ return "bukkit.command.paper.pgive";
|
||||
+ }
|
||||
return "minecraft.command." + stripDefaultNamespace(commandName);
|
||||
}
|
||||
|
||||
diff --git a/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java b/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java
|
||||
index ca71c688b37ce2c8b712a4f9216cf872c8edf78e..2f3ff50bf3f70b6b404d02d5ffcc079162a63bc1 100644
|
||||
--- a/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java
|
||||
+++ b/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java
|
||||
@@ -45,6 +45,9 @@ public class MinecraftCommandPermissionsTest extends AbstractTestingBase {
|
||||
Set<String> foundPerms = new HashSet<>();
|
||||
for (CommandNode<CommandSourceStack> child : root.getChildren()) {
|
||||
final String vanillaPerm = VanillaCommandWrapper.getPermission(child);
|
||||
+ if ("bukkit.command.paper.pgive".equals(vanillaPerm)) { // skip our custom give command
|
||||
+ continue;
|
||||
+ }
|
||||
if (!perms.contains(vanillaPerm)) {
|
||||
missing.add("Missing permission for " + child.getName() + " (" + vanillaPerm + ") command");
|
||||
} else {
|
|
@ -1,135 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 27 Nov 2018 21:18:06 -0500
|
||||
Subject: [PATCH] Handle Large Packets disconnecting client
|
||||
|
||||
If a players inventory is too big to send in a single packet,
|
||||
split the inventory set into multiple packets instead.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
|
||||
index 7fb162fa031fd76aa9a94f5fdaa3e32ceb9b9abc..58d28b6c1cc7da7d786f78308db971f7502ad844 100644
|
||||
--- a/src/main/java/net/minecraft/network/Connection.java
|
||||
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||||
@@ -180,6 +180,21 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
}
|
||||
|
||||
public void exceptionCaught(ChannelHandlerContext channelhandlercontext, Throwable throwable) {
|
||||
+ // Paper start - Handle large packets disconnecting client
|
||||
+ if (throwable instanceof io.netty.handler.codec.EncoderException && throwable.getCause() instanceof PacketEncoder.PacketTooLargeException packetTooLargeException) {
|
||||
+ final Packet<?> packet = packetTooLargeException.getPacket();
|
||||
+ if (packet.packetTooLarge(this)) {
|
||||
+ ProtocolSwapHandler.handleOutboundTerminalPacket(channelhandlercontext, packet);
|
||||
+ return;
|
||||
+ } else if (packet.isSkippable()) {
|
||||
+ Connection.LOGGER.debug("Skipping packet due to errors", throwable.getCause());
|
||||
+ ProtocolSwapHandler.handleOutboundTerminalPacket(channelhandlercontext, packet);
|
||||
+ return;
|
||||
+ } else {
|
||||
+ throwable = throwable.getCause();
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Handle large packets disconnecting client
|
||||
if (throwable instanceof SkipPacketException) {
|
||||
Connection.LOGGER.debug("Skipping packet due to errors", throwable.getCause());
|
||||
} else {
|
||||
diff --git a/src/main/java/net/minecraft/network/PacketEncoder.java b/src/main/java/net/minecraft/network/PacketEncoder.java
|
||||
index 046bfc212b640de174b300e7a05cc30bb3cac93e..af3ec112e142a2c91c46882dad6180b18f39eec2 100644
|
||||
--- a/src/main/java/net/minecraft/network/PacketEncoder.java
|
||||
+++ b/src/main/java/net/minecraft/network/PacketEncoder.java
|
||||
@@ -40,7 +40,33 @@ public class PacketEncoder<T extends PacketListener> extends MessageToByteEncode
|
||||
|
||||
throw var9;
|
||||
} finally {
|
||||
+ // Paper start - Handle large packets disconnecting client
|
||||
+ int packetLength = byteBuf.readableBytes();
|
||||
+ if (packetLength > MAX_PACKET_SIZE || (packetLength > MAX_FINAL_PACKET_SIZE && packet.hasLargePacketFallback())) {
|
||||
+ throw new PacketTooLargeException(packet, packetLength);
|
||||
+ }
|
||||
+ // Paper end - Handle large packets disconnecting client
|
||||
ProtocolSwapHandler.handleOutboundTerminalPacket(channelHandlerContext, packet);
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ // packet size is encoded into 3-byte varint
|
||||
+ private static final int MAX_FINAL_PACKET_SIZE = (1 << 21) - 1;
|
||||
+ // Vanilla Max size for the encoder (before compression)
|
||||
+ private static final int MAX_PACKET_SIZE = 8388608;
|
||||
+
|
||||
+ public static class PacketTooLargeException extends RuntimeException {
|
||||
+ private final Packet<?> packet;
|
||||
+
|
||||
+ PacketTooLargeException(Packet<?> packet, int packetLength) {
|
||||
+ super("PacketTooLarge - " + packet.getClass().getSimpleName() + " is " + packetLength + ". Max is " + MAX_PACKET_SIZE);
|
||||
+ this.packet = packet;
|
||||
+ }
|
||||
+
|
||||
+ public Packet<?> getPacket() {
|
||||
+ return this.packet;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/Packet.java b/src/main/java/net/minecraft/network/protocol/Packet.java
|
||||
index 5ee2ba1225fb7e4f02152b45adeb66f79ed1650d..c9d283b7fc9ede79dc6cbc39dfc9e7ae986a6a47 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/Packet.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/Packet.java
|
||||
@@ -11,6 +11,19 @@ public interface Packet<T extends PacketListener> {
|
||||
|
||||
void handle(T listener);
|
||||
|
||||
+ // Paper start
|
||||
+ default boolean hasLargePacketFallback() {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * override {@link #hasLargePacketFallback()} to return true when overriding in subclasses
|
||||
+ */
|
||||
+ default boolean packetTooLarge(net.minecraft.network.Connection manager) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
default boolean isSkippable() {
|
||||
return false;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java
|
||||
index 7e555ece0555b3d2a983ab2c39c5e7ec23fc7e88..8cca2ac616a2c80268c96b9f95e33f834a0fc8fd 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java
|
||||
@@ -36,6 +36,21 @@ public class ClientboundContainerSetContentPacket implements Packet<ClientGamePa
|
||||
this.carriedItem = ItemStack.OPTIONAL_STREAM_CODEC.decode(buf);
|
||||
}
|
||||
|
||||
+ // Paper start - Handle large packets disconnecting client
|
||||
+ @Override
|
||||
+ public boolean hasLargePacketFallback() {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean packetTooLarge(net.minecraft.network.Connection manager) {
|
||||
+ for (int i = 0 ; i < this.items.size() ; i++) {
|
||||
+ manager.send(new ClientboundContainerSetSlotPacket(this.containerId, this.stateId, i, this.items.get(i)));
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end - Handle large packets disconnecting client
|
||||
+
|
||||
private void write(RegistryFriendlyByteBuf buf) {
|
||||
buf.writeByte(this.containerId);
|
||||
buf.writeVarInt(this.stateId);
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
index 2501fbaf497d226051800c53d60a39bbc80db91c..0a8d07bf68b0ceabd13c70196d357fce79dcc2c3 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
@@ -80,7 +80,7 @@ public class ClientboundLevelChunkPacketData {
|
||||
throw new RuntimeException("Can't read heightmap in packet for [" + x + ", " + z + "]");
|
||||
} else {
|
||||
int i = buf.readVarInt();
|
||||
- if (i > 2097152) {
|
||||
+ if (i > 2097152) { // Paper - diff on change - if this changes, update PacketEncoder
|
||||
throw new RuntimeException("Chunk Packet trying to allocate too much memory on read.");
|
||||
} else {
|
||||
this.buffer = new byte[i];
|
|
@ -1,200 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sat, 27 Apr 2024 12:16:38 -0700
|
||||
Subject: [PATCH] Fix ItemFlags
|
||||
|
||||
Re-adds missing functionality for HIDE_DESTROYS and
|
||||
HIDE_PLACED_ON. Also adds new flag in HIDE_STORED_ENCHANTS
|
||||
which was split from HIDE_ADDITIONAL_TOOLTIP.
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.item.AdventureModePredicate predicates
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java
|
||||
index fca0cfba14dd2cc6f24b56eaf269594b2d87fd04..8734f0b777432cd8639094b75a3da1b9595823ed 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java
|
||||
@@ -39,7 +39,7 @@ class CraftMetaEnchantedBook extends CraftMetaItem implements EnchantmentStorage
|
||||
getOrEmpty(tag, CraftMetaEnchantedBook.STORED_ENCHANTMENTS).ifPresent((itemEnchantments) -> {
|
||||
this.enchantments = buildEnchantments(itemEnchantments);
|
||||
if (!itemEnchantments.showInTooltip) {
|
||||
- this.addItemFlags(ItemFlag.HIDE_ADDITIONAL_TOOLTIP);
|
||||
+ this.addItemFlags(ItemFlag.HIDE_STORED_ENCHANTS); // Paper - new ItemFlag
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -54,7 +54,7 @@ class CraftMetaEnchantedBook extends CraftMetaItem implements EnchantmentStorage
|
||||
void applyToItem(CraftMetaItem.Applicator itemTag) {
|
||||
super.applyToItem(itemTag);
|
||||
|
||||
- this.applyEnchantments(this.enchantments, itemTag, CraftMetaEnchantedBook.STORED_ENCHANTMENTS, ItemFlag.HIDE_ADDITIONAL_TOOLTIP);
|
||||
+ this.applyEnchantments(this.enchantments, itemTag, CraftMetaEnchantedBook.STORED_ENCHANTMENTS, ItemFlag.HIDE_STORED_ENCHANTS);
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
index b525bfbab2c4a5ea408981287f477a8b35d699ca..43a4a76d3829fb2ed7b5635d804fd826484c16db 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
@@ -243,6 +243,12 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
static final ItemMetaKeyType<Unit> HIDE_ADDITIONAL_TOOLTIP = new ItemMetaKeyType(DataComponents.HIDE_ADDITIONAL_TOOLTIP);
|
||||
@Specific(Specific.To.NBT)
|
||||
static final ItemMetaKeyType<CustomData> CUSTOM_DATA = new ItemMetaKeyType<>(DataComponents.CUSTOM_DATA);
|
||||
+ // Paper start - fix ItemFlags
|
||||
+ static final ItemMetaKeyType<net.minecraft.world.item.AdventureModePredicate> CAN_PLACE_ON = new ItemMetaKeyType<>(DataComponents.CAN_PLACE_ON);
|
||||
+ static final ItemMetaKeyType<net.minecraft.world.item.AdventureModePredicate> CAN_BREAK = new ItemMetaKeyType<>(DataComponents.CAN_BREAK);
|
||||
+ private List<net.minecraft.advancements.critereon.BlockPredicate> canPlaceOnPredicates;
|
||||
+ private List<net.minecraft.advancements.critereon.BlockPredicate> canBreakPredicates;
|
||||
+ // Paper end - fix ItemFlags
|
||||
|
||||
// We store the raw original JSON representation of all text data. See SPIGOT-5063, SPIGOT-5656, SPIGOT-5304
|
||||
private Component displayName;
|
||||
@@ -319,6 +325,10 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
this.customTag = meta.customTag;
|
||||
|
||||
this.version = meta.version;
|
||||
+ // Paper start
|
||||
+ this.canPlaceOnPredicates = meta.canPlaceOnPredicates;
|
||||
+ this.canBreakPredicates = meta.canBreakPredicates;
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
CraftMetaItem(DataComponentPatch tag) {
|
||||
@@ -414,6 +424,20 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
this.customTag = null;
|
||||
}
|
||||
});
|
||||
+ // Paper start - fix ItemFlags
|
||||
+ CraftMetaItem.getOrEmpty(tag, CraftMetaItem.CAN_PLACE_ON).ifPresent(data -> {
|
||||
+ this.canPlaceOnPredicates = List.copyOf(data.predicates);
|
||||
+ if (!data.showInTooltip()) {
|
||||
+ this.addItemFlags(ItemFlag.HIDE_PLACED_ON);
|
||||
+ }
|
||||
+ });
|
||||
+ CraftMetaItem.getOrEmpty(tag, CraftMetaItem.CAN_BREAK).ifPresent(data -> {
|
||||
+ this.canBreakPredicates = List.copyOf(data.predicates);
|
||||
+ if (!data.showInTooltip()) {
|
||||
+ this.addItemFlags(ItemFlag.HIDE_DESTROYS);
|
||||
+ }
|
||||
+ });
|
||||
+ // Paper end - fix ItemFlags
|
||||
|
||||
Set<Map.Entry<DataComponentType<?>, Optional<?>>> keys = tag.entrySet();
|
||||
for (Map.Entry<DataComponentType<?>, Optional<?>> key : keys) {
|
||||
@@ -603,7 +627,16 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
ByteArrayInputStream buf = new ByteArrayInputStream(Base64.getDecoder().decode(unhandled));
|
||||
try {
|
||||
CompoundTag unhandledTag = NbtIo.readCompressed(buf, NbtAccounter.unlimitedHeap());
|
||||
- this.unhandledTags.copy(DataComponentPatch.CODEC.parse(MinecraftServer.getDefaultRegistryAccess().createSerializationContext(NbtOps.INSTANCE), unhandledTag).result().get());
|
||||
+ // Paper start
|
||||
+ final net.minecraft.core.component.DataComponentPatch patch = net.minecraft.core.component.DataComponentPatch.CODEC.parse(net.minecraft.server.MinecraftServer.getDefaultRegistryAccess().createSerializationContext(net.minecraft.nbt.NbtOps.INSTANCE), unhandledTag).result().get();
|
||||
+ CraftMetaItem.getOrEmpty(patch, CraftMetaItem.CAN_PLACE_ON).ifPresent(data -> {
|
||||
+ this.canPlaceOnPredicates = List.copyOf(data.predicates);
|
||||
+ });
|
||||
+ CraftMetaItem.getOrEmpty(patch, CraftMetaItem.CAN_BREAK).ifPresent(data -> {
|
||||
+ this.canBreakPredicates = List.copyOf(data.predicates);
|
||||
+ });
|
||||
+ this.unhandledTags.copy(patch.forget(type -> type == CraftMetaItem.CAN_PLACE_ON.TYPE || type == CraftMetaItem.CAN_BREAK.TYPE));
|
||||
+ // Paper end
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
@@ -817,6 +850,15 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
itemTag.put(CraftMetaItem.MAX_DAMAGE, this.maxDamage);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ if (this.canPlaceOnPredicates != null && !this.canPlaceOnPredicates.isEmpty()) {
|
||||
+ itemTag.put(CraftMetaItem.CAN_PLACE_ON, new net.minecraft.world.item.AdventureModePredicate(this.canPlaceOnPredicates, !this.hasItemFlag(ItemFlag.HIDE_PLACED_ON)));
|
||||
+ }
|
||||
+ if (this.canBreakPredicates != null && !this.canBreakPredicates.isEmpty()) {
|
||||
+ itemTag.put(CraftMetaItem.CAN_BREAK, new net.minecraft.world.item.AdventureModePredicate(this.canBreakPredicates, !this.hasItemFlag(ItemFlag.HIDE_DESTROYS)));
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
for (Map.Entry<DataComponentType<?>, Optional<?>> e : this.unhandledTags.build().entrySet()) {
|
||||
e.getValue().ifPresentOrElse((value) -> {
|
||||
itemTag.builder.set((DataComponentType) e.getKey(), value);
|
||||
@@ -891,7 +933,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
|
||||
@Overridden
|
||||
boolean isEmpty() {
|
||||
- return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasTool() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null);
|
||||
+ return !(this.hasDisplayName() || this.hasItemName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.build().isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isHideTooltip() || this.isUnbreakable() || this.hasEnchantmentGlintOverride() || this.isFireResistant() || this.hasMaxStackSize() || this.hasRarity() || this.hasFood() || this.hasTool() || this.hasDamage() || this.hasMaxDamage() || this.hasAttributeModifiers() || this.customTag != null || this.canPlaceOnPredicates != null || this.canBreakPredicates != null); // Paper
|
||||
}
|
||||
|
||||
// Paper start
|
||||
@@ -1544,6 +1586,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
&& (this.hasTool() ? that.hasTool() && this.tool.equals(that.tool) : !that.hasTool())
|
||||
&& (this.hasDamage() ? that.hasDamage() && this.damage == that.damage : !that.hasDamage())
|
||||
&& (this.hasMaxDamage() ? that.hasMaxDamage() && this.maxDamage.equals(that.maxDamage) : !that.hasMaxDamage())
|
||||
+ && (this.canPlaceOnPredicates != null ? that.canPlaceOnPredicates != null && this.canPlaceOnPredicates.equals(that.canPlaceOnPredicates) : that.canPlaceOnPredicates == null) // Paper
|
||||
+ && (this.canBreakPredicates != null ? that.canBreakPredicates != null && this.canBreakPredicates.equals(that.canBreakPredicates) : that.canBreakPredicates == null) // Paper
|
||||
&& (this.version == that.version);
|
||||
}
|
||||
|
||||
@@ -1587,6 +1631,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
hash = 61 * hash + (this.hasDamage() ? this.damage : 0);
|
||||
hash = 61 * hash + (this.hasMaxDamage() ? 1231 : 1237);
|
||||
hash = 61 * hash + (this.hasAttributeModifiers() ? this.attributeModifiers.hashCode() : 0);
|
||||
+ hash = 61 * hash + (this.canPlaceOnPredicates != null ? this.canPlaceOnPredicates.hashCode() : 0); // Paper
|
||||
+ hash = 61 * hash + (this.canBreakPredicates != null ? this.canBreakPredicates.hashCode() : 0); // Paper
|
||||
hash = 61 * hash + this.version;
|
||||
return hash;
|
||||
}
|
||||
@@ -1627,6 +1673,14 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
clone.damage = this.damage;
|
||||
clone.maxDamage = this.maxDamage;
|
||||
clone.version = this.version;
|
||||
+ // Paper start
|
||||
+ if (this.canPlaceOnPredicates != null) {
|
||||
+ clone.canPlaceOnPredicates = List.copyOf(this.canPlaceOnPredicates);
|
||||
+ }
|
||||
+ if (this.canBreakPredicates != null) {
|
||||
+ clone.canBreakPredicates = List.copyOf(this.canBreakPredicates);
|
||||
+ }
|
||||
+ // Paper end
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new Error(e);
|
||||
@@ -1740,6 +1794,16 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ final boolean canBreakAddToUnhandled = this.canBreakPredicates != null && !this.canBreakPredicates.isEmpty();
|
||||
+ if (canBreakAddToUnhandled) {
|
||||
+ this.unhandledTags.set(DataComponents.CAN_BREAK, new net.minecraft.world.item.AdventureModePredicate(this.canBreakPredicates, !this.hasItemFlag(ItemFlag.HIDE_DESTROYS)));
|
||||
+ }
|
||||
+ final boolean canPlaceOnAddToUnhandled = this.canPlaceOnPredicates != null && !this.canPlaceOnPredicates.isEmpty();
|
||||
+ if (canPlaceOnAddToUnhandled) {
|
||||
+ this.unhandledTags.set(DataComponents.CAN_PLACE_ON, new net.minecraft.world.item.AdventureModePredicate(this.canPlaceOnPredicates, !this.hasItemFlag(ItemFlag.HIDE_PLACED_ON)));
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (!this.unhandledTags.isEmpty()) {
|
||||
Tag unhandled = DataComponentPatch.CODEC.encodeStart(MinecraftServer.getDefaultRegistryAccess().createSerializationContext(NbtOps.INSTANCE), this.unhandledTags.build()).getOrThrow(IllegalStateException::new);
|
||||
try {
|
||||
@@ -1750,6 +1814,14 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
+ // Paper start
|
||||
+ if (canBreakAddToUnhandled) {
|
||||
+ this.unhandledTags.clear(DataComponents.CAN_BREAK);
|
||||
+ }
|
||||
+ if (canPlaceOnAddToUnhandled) {
|
||||
+ this.unhandledTags.clear(DataComponents.CAN_PLACE_ON);
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
if (!this.persistentDataContainer.isEmpty()) { // Store custom tags, wrapped in their compound
|
||||
builder.put(CraftMetaItem.BUKKIT_CUSTOM_TAG.BUKKIT, this.persistentDataContainer.serialize());
|
||||
@@ -1888,6 +1960,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
CraftMetaItem.MAX_DAMAGE.TYPE,
|
||||
CraftMetaItem.CUSTOM_DATA.TYPE,
|
||||
CraftMetaItem.ATTRIBUTES.TYPE,
|
||||
+ CraftMetaItem.CAN_PLACE_ON.TYPE, // Paper
|
||||
+ CraftMetaItem.CAN_BREAK.TYPE, // Paper
|
||||
CraftMetaArmor.TRIM.TYPE,
|
||||
CraftMetaArmorStand.ENTITY_TAG.TYPE,
|
||||
CraftMetaBanner.PATTERNS.TYPE,
|
|
@ -1,21 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
Date: Sat, 27 Apr 2024 21:51:58 +0200
|
||||
Subject: [PATCH] Fix helmet damage reduction inconsistencies
|
||||
|
||||
Affect the falling stalactite damage type where the
|
||||
reduction is not applied like in Vanilla
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 96070da795755f71e99979288e32b7d7e2d869fb..dfbe0914ab2771ac632fd064719878ac47559e9f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -1212,7 +1212,7 @@ public class CraftEventFactory {
|
||||
Map<DamageModifier, Function<? super Double, Double>> modifierFunctions = new EnumMap<>(DamageModifier.class);
|
||||
modifiers.put(DamageModifier.BASE, rawDamage);
|
||||
modifierFunctions.put(DamageModifier.BASE, CraftEventFactory.ZERO);
|
||||
- if (source.is(DamageTypes.FALLING_BLOCK) || source.is(DamageTypes.FALLING_ANVIL)) {
|
||||
+ if (source.is(DamageTypeTags.DAMAGES_HELMET)) { // Paper
|
||||
modifiers.put(DamageModifier.HARD_HAT, hardHatModifier);
|
||||
modifierFunctions.put(DamageModifier.HARD_HAT, hardHat);
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sat, 27 Apr 2024 09:44:53 -0700
|
||||
Subject: [PATCH] Revert to vanilla handling of LivingEntity#actuallyHurt
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 6118de380a95b0c927a239ac3e288780f114289e..d0b6ade676d94e768c92432dc6cee9f200acf5f2 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -2210,7 +2210,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
}
|
||||
|
||||
// CraftBukkit start
|
||||
- protected boolean actuallyHurt(final DamageSource damagesource, float f) { // void -> boolean, add final
|
||||
+ protected boolean actuallyHurt(final DamageSource damagesource, float f) { // void -> boolean, add final // Paper - return false ONLY if event cancelled
|
||||
if (!this.isInvulnerableTo(damagesource)) {
|
||||
final boolean human = this instanceof net.minecraft.world.entity.player.Player;
|
||||
float originalDamage = f;
|
||||
@@ -2382,12 +2382,12 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
|
||||
return true;
|
||||
} else {
|
||||
- return originalDamage > 0;
|
||||
+ return true; // Paper - return false ONLY if event was cancelled
|
||||
}
|
||||
// CraftBukkit end
|
||||
}
|
||||
}
|
||||
- return false; // CraftBukkit
|
||||
+ return true; // CraftBukkit // Paper - return false ONLY if event was cancelled
|
||||
}
|
||||
|
||||
public CombatTracker getCombatTracker() {
|
|
@ -1,804 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Mon, 10 Jul 2023 16:10:15 -0700
|
||||
Subject: [PATCH] improve checking handled tags in itemmeta
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
index 7249ff939dfa786395595f687338315b779e0931..c0bf7efac56e558052992d2ce2455fccff4d9897 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
@@ -156,10 +156,11 @@ public final class CraftItemStack extends ItemStack {
|
||||
} else if (this.handle == null) {
|
||||
this.handle = new net.minecraft.world.item.ItemStack(CraftItemType.bukkitToMinecraft(type), 1);
|
||||
} else {
|
||||
+ final Material oldType = CraftMagicNumbers.getMaterial(this.handle.getItem()); // Paper
|
||||
this.handle.setItem(CraftItemType.bukkitToMinecraft(type));
|
||||
if (this.hasItemMeta()) {
|
||||
// This will create the appropriate item meta, which will contain all the data we intend to keep
|
||||
- CraftItemStack.setItemMeta(this.handle, CraftItemStack.getItemMeta(this.handle));
|
||||
+ this.adjustTagForItemMeta(oldType); // Paper
|
||||
}
|
||||
}
|
||||
this.setData(null);
|
||||
@@ -312,6 +313,19 @@ public final class CraftItemStack extends ItemStack {
|
||||
public ItemMeta getItemMeta() {
|
||||
return CraftItemStack.getItemMeta(this.handle);
|
||||
}
|
||||
+ // Paper start - improve handled tags on type change
|
||||
+ public void adjustTagForItemMeta(final Material oldType) {
|
||||
+ final CraftMetaItem oldMeta = (CraftMetaItem) CraftItemFactory.instance().getItemMeta(oldType);
|
||||
+ final ItemMeta newMeta;
|
||||
+ if (oldMeta == null) {
|
||||
+ newMeta = getItemMeta(this.handle);
|
||||
+ } else {
|
||||
+ final java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts = new java.util.HashSet<>(CraftMetaItem.getTopLevelHandledDcts(oldMeta.getClass()));
|
||||
+ newMeta = getItemMeta(this.handle, CraftItemStack.getType(this.handle), extraHandledDcts);
|
||||
+ }
|
||||
+ this.setItemMeta(newMeta);
|
||||
+ }
|
||||
+ // Paper end - improve handled tags on type change
|
||||
// Paper start
|
||||
public static void applyMetaToItem(net.minecraft.world.item.ItemStack itemStack, ItemMeta itemMeta) {
|
||||
final CraftMetaItem.Applicator tag = new CraftMetaItem.Applicator();
|
||||
@@ -324,14 +338,19 @@ public final class CraftItemStack extends ItemStack {
|
||||
}
|
||||
public static ItemMeta getItemMeta(net.minecraft.world.item.ItemStack item, Material material) {
|
||||
// Paper end
|
||||
+ // Paper start - handled tags on type change
|
||||
+ return getItemMeta(item, material, null);
|
||||
+ }
|
||||
+ public static ItemMeta getItemMeta(net.minecraft.world.item.ItemStack item, Material material, final java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) {
|
||||
+ // Paper end - handled tags on type change
|
||||
if (!CraftItemStack.hasItemMeta(item)) {
|
||||
return CraftItemFactory.instance().getItemMeta(material); // Paper
|
||||
}
|
||||
switch (material) { // Paper
|
||||
case WRITTEN_BOOK:
|
||||
- return new CraftMetaBookSigned(item.getComponentsPatch());
|
||||
+ return new CraftMetaBookSigned(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case WRITABLE_BOOK:
|
||||
- return new CraftMetaBook(item.getComponentsPatch());
|
||||
+ return new CraftMetaBook(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case CREEPER_HEAD:
|
||||
case CREEPER_WALL_HEAD:
|
||||
case DRAGON_HEAD:
|
||||
@@ -346,7 +365,7 @@ public final class CraftItemStack extends ItemStack {
|
||||
case WITHER_SKELETON_WALL_SKULL:
|
||||
case ZOMBIE_HEAD:
|
||||
case ZOMBIE_WALL_HEAD:
|
||||
- return new CraftMetaSkull(item.getComponentsPatch());
|
||||
+ return new CraftMetaSkull(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case CHAINMAIL_HELMET:
|
||||
case CHAINMAIL_CHESTPLATE:
|
||||
case CHAINMAIL_LEGGINGS:
|
||||
@@ -368,28 +387,28 @@ public final class CraftItemStack extends ItemStack {
|
||||
case NETHERITE_LEGGINGS:
|
||||
case NETHERITE_BOOTS:
|
||||
case TURTLE_HELMET:
|
||||
- return new CraftMetaArmor(item.getComponentsPatch());
|
||||
+ return new CraftMetaArmor(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case LEATHER_HELMET:
|
||||
case LEATHER_CHESTPLATE:
|
||||
case LEATHER_LEGGINGS:
|
||||
case LEATHER_BOOTS:
|
||||
case WOLF_ARMOR:
|
||||
- return new CraftMetaColorableArmor(item.getComponentsPatch());
|
||||
+ return new CraftMetaColorableArmor(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case LEATHER_HORSE_ARMOR:
|
||||
- return new CraftMetaLeatherArmor(item.getComponentsPatch());
|
||||
+ return new CraftMetaLeatherArmor(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case POTION:
|
||||
case SPLASH_POTION:
|
||||
case LINGERING_POTION:
|
||||
case TIPPED_ARROW:
|
||||
- return new CraftMetaPotion(item.getComponentsPatch());
|
||||
+ return new CraftMetaPotion(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case FILLED_MAP:
|
||||
- return new CraftMetaMap(item.getComponentsPatch());
|
||||
+ return new CraftMetaMap(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case FIREWORK_ROCKET:
|
||||
- return new CraftMetaFirework(item.getComponentsPatch());
|
||||
+ return new CraftMetaFirework(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case FIREWORK_STAR:
|
||||
- return new CraftMetaCharge(item.getComponentsPatch());
|
||||
+ return new CraftMetaCharge(item.getComponentsPatch(), extraHandledDcts); // Paper;
|
||||
case ENCHANTED_BOOK:
|
||||
- return new CraftMetaEnchantedBook(item.getComponentsPatch());
|
||||
+ return new CraftMetaEnchantedBook(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case BLACK_BANNER:
|
||||
case BLACK_WALL_BANNER:
|
||||
case BLUE_BANNER:
|
||||
@@ -422,7 +441,7 @@ public final class CraftItemStack extends ItemStack {
|
||||
case WHITE_WALL_BANNER:
|
||||
case YELLOW_BANNER:
|
||||
case YELLOW_WALL_BANNER:
|
||||
- return new CraftMetaBanner(item.getComponentsPatch());
|
||||
+ return new CraftMetaBanner(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case ARMADILLO_SPAWN_EGG:
|
||||
case ALLAY_SPAWN_EGG:
|
||||
case AXOLOTL_SPAWN_EGG:
|
||||
@@ -503,11 +522,11 @@ public final class CraftItemStack extends ItemStack {
|
||||
case ZOMBIE_SPAWN_EGG:
|
||||
case ZOMBIE_VILLAGER_SPAWN_EGG:
|
||||
case ZOMBIFIED_PIGLIN_SPAWN_EGG:
|
||||
- return new CraftMetaSpawnEgg(item.getComponentsPatch());
|
||||
+ return new CraftMetaSpawnEgg(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case ARMOR_STAND:
|
||||
- return new CraftMetaArmorStand(item.getComponentsPatch());
|
||||
+ return new CraftMetaArmorStand(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case KNOWLEDGE_BOOK:
|
||||
- return new CraftMetaKnowledgeBook(item.getComponentsPatch());
|
||||
+ return new CraftMetaKnowledgeBook(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case FURNACE:
|
||||
case CHEST:
|
||||
case TRAPPED_CHEST:
|
||||
@@ -609,15 +628,15 @@ public final class CraftItemStack extends ItemStack {
|
||||
case CRAFTER:
|
||||
case TRIAL_SPAWNER:
|
||||
case VAULT:
|
||||
- return new CraftMetaBlockState(item.getComponentsPatch(), CraftItemType.minecraftToBukkit(item.getItem()));
|
||||
+ return new CraftMetaBlockState(item.getComponentsPatch(), CraftItemType.minecraftToBukkit(item.getItem()), extraHandledDcts); // Paper
|
||||
case TROPICAL_FISH_BUCKET:
|
||||
- return new CraftMetaTropicalFishBucket(item.getComponentsPatch());
|
||||
+ return new CraftMetaTropicalFishBucket(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case AXOLOTL_BUCKET:
|
||||
- return new CraftMetaAxolotlBucket(item.getComponentsPatch());
|
||||
+ return new CraftMetaAxolotlBucket(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case CROSSBOW:
|
||||
- return new CraftMetaCrossbow(item.getComponentsPatch());
|
||||
+ return new CraftMetaCrossbow(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case SUSPICIOUS_STEW:
|
||||
- return new CraftMetaSuspiciousStew(item.getComponentsPatch());
|
||||
+ return new CraftMetaSuspiciousStew(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case COD_BUCKET:
|
||||
case PUFFERFISH_BUCKET:
|
||||
case SALMON_BUCKET:
|
||||
@@ -625,17 +644,17 @@ public final class CraftItemStack extends ItemStack {
|
||||
case ITEM_FRAME:
|
||||
case GLOW_ITEM_FRAME:
|
||||
case PAINTING:
|
||||
- return new CraftMetaEntityTag(item.getComponentsPatch());
|
||||
+ return new CraftMetaEntityTag(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case COMPASS:
|
||||
- return new CraftMetaCompass(item.getComponentsPatch());
|
||||
+ return new CraftMetaCompass(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case BUNDLE:
|
||||
- return new CraftMetaBundle(item.getComponentsPatch());
|
||||
+ return new CraftMetaBundle(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case GOAT_HORN:
|
||||
- return new CraftMetaMusicInstrument(item.getComponentsPatch());
|
||||
+ return new CraftMetaMusicInstrument(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
case OMINOUS_BOTTLE:
|
||||
- return new CraftMetaOminousBottle(item.getComponentsPatch());
|
||||
+ return new CraftMetaOminousBottle(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
default:
|
||||
- return new CraftMetaItem(item.getComponentsPatch());
|
||||
+ return new CraftMetaItem(item.getComponentsPatch(), extraHandledDcts); // Paper
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java
|
||||
index 13b91cddffbe8ae6f07ce5c0ae45beba151e1aca..569f7157a625b981bff43650e9dd0a8c1831a29d 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmor.java
|
||||
@@ -65,8 +65,8 @@ public class CraftMetaArmor extends CraftMetaItem implements ArmorMeta {
|
||||
}
|
||||
}
|
||||
|
||||
- CraftMetaArmor(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaArmor(DataComponentPatch tag, java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
|
||||
getOrEmpty(tag, CraftMetaArmor.TRIM).ifPresent((trimCompound) -> {
|
||||
TrimMaterial trimMaterial = org.bukkit.craftbukkit.CraftRegistry.unwrapAndConvertHolder(io.papermc.paper.registry.RegistryKey.TRIM_MATERIAL, trimCompound.material()).orElse(null); // Paper - fix upstream not being correct
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java
|
||||
index 59bdac414e8205ed608f79ef0d1502acd826d216..53df7e876c9f3e67aa2326fa1a5ce5e90ab7efd6 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java
|
||||
@@ -47,8 +47,8 @@ public class CraftMetaArmorStand extends CraftMetaItem implements com.destroysto
|
||||
this.entityTag = armorStand.entityTag;
|
||||
}
|
||||
|
||||
- CraftMetaArmorStand(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaArmorStand(DataComponentPatch tag, final java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
|
||||
getOrEmpty(tag, CraftMetaArmorStand.ENTITY_TAG).ifPresent((nbt) -> {
|
||||
this.entityTag = nbt.copyTag();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaAxolotlBucket.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaAxolotlBucket.java
|
||||
index 3377fdd445db33b2ee1735942b391c6bfa92ab91..44d8aa7123ac22cf9a22720ecadc8c5f63bafc0a 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaAxolotlBucket.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaAxolotlBucket.java
|
||||
@@ -37,8 +37,8 @@ public class CraftMetaAxolotlBucket extends CraftMetaItem implements AxolotlBuck
|
||||
this.bucketEntityTag = bucket.bucketEntityTag;
|
||||
}
|
||||
|
||||
- CraftMetaAxolotlBucket(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaAxolotlBucket(DataComponentPatch tag, final java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
|
||||
getOrEmpty(tag, CraftMetaAxolotlBucket.ENTITY_TAG).ifPresent((nbt) -> {
|
||||
this.entityTag = nbt.copyTag();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java
|
||||
index d53df6f114c285b880167385807775e400c80fc9..1ac3bec02fce28d5ce698305a7482a9eccbb1867 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java
|
||||
@@ -72,8 +72,8 @@ public class CraftMetaBanner extends CraftMetaItem implements BannerMeta {
|
||||
this.patterns = new ArrayList<Pattern>(banner.patterns);
|
||||
}
|
||||
|
||||
- CraftMetaBanner(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaBanner(DataComponentPatch tag, final java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
|
||||
getOrEmpty(tag, CraftMetaBanner.PATTERNS).ifPresent((entityTag) -> {
|
||||
List<BannerPatternLayers.Layer> patterns = entityTag.layers();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java
|
||||
index 9034905aabf057f387b65957a254d056b12e0519..12911233c01d0ac1af9adbd157d56d28361fc76f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java
|
||||
@@ -161,8 +161,8 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta
|
||||
this.blockEntityTag = te.blockEntityTag;
|
||||
}
|
||||
|
||||
- CraftMetaBlockState(DataComponentPatch tag, Material material) {
|
||||
- super(tag);
|
||||
+ CraftMetaBlockState(DataComponentPatch tag, Material material, final Set<DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
this.material = material;
|
||||
|
||||
getOrEmpty(tag, CraftMetaBlockState.BLOCK_ENTITY_TAG).ifPresent((nbt) -> {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java
|
||||
index 4da38ebb7fdbdb0f8fa422ebcd2e3eec2b2be846..a395c7ce952f4a60a5edf80e8731afa6388d18ea 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java
|
||||
@@ -64,8 +64,8 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta, WritableBo
|
||||
}
|
||||
}
|
||||
|
||||
- CraftMetaBook(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaBook(DataComponentPatch tag, java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
|
||||
getOrEmpty(tag, CraftMetaBook.BOOK_CONTENT).ifPresent((writable) -> {
|
||||
List<Filterable<String>> pages = writable.pages();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java
|
||||
index c7360e2b2d6e50abc371c21b09cdadd63892f439..3f78a0935d738854182254b345064e3c225dcd5f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java
|
||||
@@ -78,8 +78,8 @@ public class CraftMetaBookSigned extends CraftMetaItem implements BookMeta {
|
||||
}
|
||||
}
|
||||
|
||||
- CraftMetaBookSigned(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaBookSigned(DataComponentPatch tag, java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
|
||||
getOrEmpty(tag, CraftMetaBookSigned.BOOK_CONTENT).ifPresent((written) -> {
|
||||
this.title = written.title().raw();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBundle.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBundle.java
|
||||
index dfaec374cf35107714b6f49d58c508dba94e7d3d..f8c02fe01fd95aa5de8523c9ad452d91f5d3c16f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBundle.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBundle.java
|
||||
@@ -35,8 +35,8 @@ public class CraftMetaBundle extends CraftMetaItem implements BundleMeta {
|
||||
}
|
||||
}
|
||||
|
||||
- CraftMetaBundle(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaBundle(DataComponentPatch tag, java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
|
||||
getOrEmpty(tag, CraftMetaBundle.ITEMS).ifPresent((bundle) -> {
|
||||
bundle.items().forEach((item) -> {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCharge.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCharge.java
|
||||
index 40d55374a78bcbaa958cf0010c46071c6dc833f9..12d128e0246e66aa4e53fef870ee9125fa1687bf 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCharge.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCharge.java
|
||||
@@ -30,8 +30,8 @@ class CraftMetaCharge extends CraftMetaItem implements FireworkEffectMeta {
|
||||
this.setEffect(SerializableMeta.getObject(FireworkEffect.class, map, CraftMetaCharge.EXPLOSION.BUKKIT, true));
|
||||
}
|
||||
|
||||
- CraftMetaCharge(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaCharge(DataComponentPatch tag, java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
|
||||
getOrEmpty(tag, CraftMetaCharge.EXPLOSION).ifPresent((f) -> {
|
||||
try {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java
|
||||
index c74d597633d023bd12c10bd4801bc103eb2beef1..2c9ca54267579a210d4ea192517fc0fbce8e467a 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java
|
||||
@@ -29,8 +29,8 @@ public class CraftMetaColorableArmor extends CraftMetaArmor implements Colorable
|
||||
CraftMetaLeatherArmor.readColor(this, meta);
|
||||
}
|
||||
|
||||
- CraftMetaColorableArmor(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaColorableArmor(DataComponentPatch tag, java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
CraftMetaLeatherArmor.readColor(this, tag);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCompass.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCompass.java
|
||||
index 820b4e611342fb62c61a8b3b19e19967da35cbe0..bbca26f5debb263b04516e68f6e49f68a38fa5b1 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCompass.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCompass.java
|
||||
@@ -51,8 +51,8 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta {
|
||||
this.tracked = compassMeta.tracked;
|
||||
}
|
||||
|
||||
- CraftMetaCompass(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaCompass(DataComponentPatch tag, java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
getOrEmpty(tag, CraftMetaCompass.LODESTONE_TARGET).ifPresent((lodestoneTarget) -> {
|
||||
lodestoneTarget.target().ifPresent((target) -> {
|
||||
this.lodestoneWorld = target.dimension();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCrossbow.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCrossbow.java
|
||||
index de7b06f9da17418cf0065249438a4182043160e6..a3fa95377e083e51ad7596d21eeb08172bdb18b2 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCrossbow.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCrossbow.java
|
||||
@@ -36,8 +36,8 @@ public class CraftMetaCrossbow extends CraftMetaItem implements CrossbowMeta {
|
||||
}
|
||||
}
|
||||
|
||||
- CraftMetaCrossbow(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaCrossbow(DataComponentPatch tag, java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
|
||||
getOrEmpty(tag, CraftMetaCrossbow.CHARGED_PROJECTILES).ifPresent((p) -> {
|
||||
List<net.minecraft.world.item.ItemStack> list = p.getItems();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java
|
||||
index 8734f0b777432cd8639094b75a3da1b9595823ed..eb80239949e54c0a698ad4e2d9262242ecb28e41 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java
|
||||
@@ -33,8 +33,8 @@ class CraftMetaEnchantedBook extends CraftMetaItem implements EnchantmentStorage
|
||||
}
|
||||
}
|
||||
|
||||
- CraftMetaEnchantedBook(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaEnchantedBook(DataComponentPatch tag, java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
|
||||
getOrEmpty(tag, CraftMetaEnchantedBook.STORED_ENCHANTMENTS).ifPresent((itemEnchantments) -> {
|
||||
this.enchantments = buildEnchantments(itemEnchantments);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEntityTag.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEntityTag.java
|
||||
index 3ff0340c40e9dc9a6e690de15ccade7a0c4e8f02..3f6c5cbbf63631e4b72dc43558651ea94f31ca78 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEntityTag.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEntityTag.java
|
||||
@@ -39,8 +39,8 @@ public class CraftMetaEntityTag extends CraftMetaItem {
|
||||
this.entityTag = entity.entityTag;
|
||||
}
|
||||
|
||||
- CraftMetaEntityTag(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaEntityTag(DataComponentPatch tag, final java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
|
||||
getOrEmpty(tag, CraftMetaEntityTag.ENTITY_TAG).ifPresent((nbt) -> {
|
||||
this.entityTag = nbt.copyTag();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java
|
||||
index b444bd26d6c3def3494d3cc0520e462408272be3..8e0dd4b7a7a25a8beb27b507047bc48d8227627c 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java
|
||||
@@ -60,8 +60,8 @@ class CraftMetaFirework extends CraftMetaItem implements FireworkMeta {
|
||||
}
|
||||
}
|
||||
|
||||
- CraftMetaFirework(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaFirework(DataComponentPatch tag, java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
|
||||
getOrEmpty(tag, CraftMetaFirework.FIREWORKS).ifPresent((fireworks) -> {
|
||||
this.power = fireworks.flightDuration();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
index 43a4a76d3829fb2ed7b5635d804fd826484c16db..5d86861a0df7308ae9b8440e5d9136fa7c8f1835 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
@@ -331,7 +331,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
// Paper end
|
||||
}
|
||||
|
||||
- CraftMetaItem(DataComponentPatch tag) {
|
||||
+ CraftMetaItem(DataComponentPatch tag, Set<DataComponentType<?>> extraHandledTags) { // Paper - improve handled tags on type changes
|
||||
CraftMetaItem.getOrEmpty(tag, CraftMetaItem.NAME).ifPresent((component) -> {
|
||||
this.displayName = component;
|
||||
});
|
||||
@@ -439,11 +439,18 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
});
|
||||
// Paper end - fix ItemFlags
|
||||
|
||||
+ // Paper start - improve checking handled data component types
|
||||
+ Set<DataComponentType<?>> handledTags = getTopLevelHandledDcts(this.getClass());
|
||||
+ if (extraHandledTags != null) {
|
||||
+ extraHandledTags.addAll(handledTags);
|
||||
+ handledTags = extraHandledTags;
|
||||
+ }
|
||||
+ // Paper end - improve checking handled data component types
|
||||
Set<Map.Entry<DataComponentType<?>, Optional<?>>> keys = tag.entrySet();
|
||||
for (Map.Entry<DataComponentType<?>, Optional<?>> key : keys) {
|
||||
if (key.getValue().isEmpty()) {
|
||||
this.unhandledTags.remove(key.getKey());
|
||||
- } else if (!CraftMetaItem.getHandledTags().contains(key.getKey())) {
|
||||
+ } else if (!handledTags.contains(key.getKey())) { // Paper - improve checking handled data component types
|
||||
key.getValue().ifPresentOrElse((value) -> {
|
||||
this.unhandledTags.set((DataComponentType) key.getKey(), value);
|
||||
}, () -> {
|
||||
@@ -1936,67 +1943,74 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
- public static Set<DataComponentType> getHandledTags() {
|
||||
- synchronized (CraftMetaItem.HANDLED_TAGS) {
|
||||
- if (CraftMetaItem.HANDLED_TAGS.isEmpty()) {
|
||||
- CraftMetaItem.HANDLED_TAGS.addAll(Arrays.asList(
|
||||
- CraftMetaItem.NAME.TYPE,
|
||||
- CraftMetaItem.ITEM_NAME.TYPE,
|
||||
- CraftMetaItem.LORE.TYPE,
|
||||
- CraftMetaItem.CUSTOM_MODEL_DATA.TYPE,
|
||||
- CraftMetaItem.BLOCK_DATA.TYPE,
|
||||
- CraftMetaItem.REPAIR.TYPE,
|
||||
- CraftMetaItem.ENCHANTMENTS.TYPE,
|
||||
- CraftMetaItem.HIDE_ADDITIONAL_TOOLTIP.TYPE,
|
||||
- CraftMetaItem.HIDE_TOOLTIP.TYPE,
|
||||
- CraftMetaItem.UNBREAKABLE.TYPE,
|
||||
- CraftMetaItem.ENCHANTMENT_GLINT_OVERRIDE.TYPE,
|
||||
- CraftMetaItem.FIRE_RESISTANT.TYPE,
|
||||
- CraftMetaItem.MAX_STACK_SIZE.TYPE,
|
||||
- CraftMetaItem.RARITY.TYPE,
|
||||
- CraftMetaItem.FOOD.TYPE,
|
||||
- CraftMetaItem.TOOL.TYPE,
|
||||
- CraftMetaItem.DAMAGE.TYPE,
|
||||
- CraftMetaItem.MAX_DAMAGE.TYPE,
|
||||
- CraftMetaItem.CUSTOM_DATA.TYPE,
|
||||
- CraftMetaItem.ATTRIBUTES.TYPE,
|
||||
- CraftMetaItem.CAN_PLACE_ON.TYPE, // Paper
|
||||
- CraftMetaItem.CAN_BREAK.TYPE, // Paper
|
||||
- CraftMetaArmor.TRIM.TYPE,
|
||||
- CraftMetaArmorStand.ENTITY_TAG.TYPE,
|
||||
- CraftMetaBanner.PATTERNS.TYPE,
|
||||
- CraftMetaEntityTag.ENTITY_TAG.TYPE,
|
||||
- CraftMetaLeatherArmor.COLOR.TYPE,
|
||||
- CraftMetaMap.MAP_POST_PROCESSING.TYPE,
|
||||
- CraftMetaMap.MAP_COLOR.TYPE,
|
||||
- CraftMetaMap.MAP_ID.TYPE,
|
||||
- CraftMetaPotion.POTION_CONTENTS.TYPE,
|
||||
- CraftMetaSkull.SKULL_PROFILE.TYPE,
|
||||
- CraftMetaSkull.NOTE_BLOCK_SOUND.TYPE,
|
||||
- CraftMetaSpawnEgg.ENTITY_TAG.TYPE,
|
||||
- CraftMetaBlockState.BLOCK_ENTITY_TAG.TYPE,
|
||||
- CraftMetaBook.BOOK_CONTENT.TYPE,
|
||||
- CraftMetaBookSigned.BOOK_CONTENT.TYPE,
|
||||
- CraftMetaFirework.FIREWORKS.TYPE,
|
||||
- CraftMetaEnchantedBook.STORED_ENCHANTMENTS.TYPE,
|
||||
- CraftMetaCharge.EXPLOSION.TYPE,
|
||||
- CraftMetaBlockState.BLOCK_ENTITY_TAG.TYPE,
|
||||
- CraftMetaKnowledgeBook.BOOK_RECIPES.TYPE,
|
||||
- CraftMetaTropicalFishBucket.ENTITY_TAG.TYPE,
|
||||
- CraftMetaTropicalFishBucket.BUCKET_ENTITY_TAG.TYPE,
|
||||
- CraftMetaAxolotlBucket.ENTITY_TAG.TYPE,
|
||||
- CraftMetaAxolotlBucket.BUCKET_ENTITY_TAG.TYPE,
|
||||
- CraftMetaCrossbow.CHARGED_PROJECTILES.TYPE,
|
||||
- CraftMetaSuspiciousStew.EFFECTS.TYPE,
|
||||
- CraftMetaCompass.LODESTONE_TARGET.TYPE,
|
||||
- CraftMetaBundle.ITEMS.TYPE,
|
||||
- CraftMetaMusicInstrument.GOAT_HORN_INSTRUMENT.TYPE,
|
||||
- CraftMetaOminousBottle.OMINOUS_BOTTLE_AMPLIFIER.TYPE
|
||||
- ));
|
||||
- }
|
||||
- return CraftMetaItem.HANDLED_TAGS;
|
||||
+ // Paper start - improve checking handled tags
|
||||
+ @org.jetbrains.annotations.VisibleForTesting
|
||||
+ public static final Map<Class<? extends CraftMetaItem>, Set<DataComponentType<?>>> HANDLED_DCTS_PER_TYPE = new HashMap<>();
|
||||
+ private static final Set<DataComponentType<?>> DEFAULT_HANDLED_DCTS = Set.of(
|
||||
+ CraftMetaItem.NAME.TYPE,
|
||||
+ CraftMetaItem.ITEM_NAME.TYPE,
|
||||
+ CraftMetaItem.LORE.TYPE,
|
||||
+ CraftMetaItem.CUSTOM_MODEL_DATA.TYPE,
|
||||
+ CraftMetaItem.BLOCK_DATA.TYPE,
|
||||
+ CraftMetaItem.REPAIR.TYPE,
|
||||
+ CraftMetaItem.ENCHANTMENTS.TYPE,
|
||||
+ CraftMetaItem.HIDE_ADDITIONAL_TOOLTIP.TYPE,
|
||||
+ CraftMetaItem.HIDE_TOOLTIP.TYPE,
|
||||
+ CraftMetaItem.UNBREAKABLE.TYPE,
|
||||
+ CraftMetaItem.ENCHANTMENT_GLINT_OVERRIDE.TYPE,
|
||||
+ CraftMetaItem.FIRE_RESISTANT.TYPE,
|
||||
+ CraftMetaItem.MAX_STACK_SIZE.TYPE,
|
||||
+ CraftMetaItem.RARITY.TYPE,
|
||||
+ CraftMetaItem.FOOD.TYPE,
|
||||
+ CraftMetaItem.TOOL.TYPE,
|
||||
+ CraftMetaItem.DAMAGE.TYPE,
|
||||
+ CraftMetaItem.MAX_DAMAGE.TYPE,
|
||||
+ CraftMetaItem.CUSTOM_DATA.TYPE,
|
||||
+ CraftMetaItem.ATTRIBUTES.TYPE,
|
||||
+ CraftMetaItem.CAN_PLACE_ON.TYPE, // Paper
|
||||
+ CraftMetaItem.CAN_BREAK.TYPE // Paper
|
||||
+ );
|
||||
+ public static Set<DataComponentType<?>> getTopLevelHandledDcts(final Class<? extends CraftMetaItem> clazz) {
|
||||
+ synchronized (HANDLED_DCTS_PER_TYPE) {
|
||||
+ if (HANDLED_DCTS_PER_TYPE.isEmpty()) {
|
||||
+ final Map<Class<? extends CraftMetaItem>, Set<DataComponentType<?>>> map = new HashMap<>();
|
||||
+ map.put(CraftMetaArmor.class, Set.of(CraftMetaArmor.TRIM.TYPE));
|
||||
+ map.put(CraftMetaArmorStand.class, Set.of(CraftMetaArmorStand.ENTITY_TAG.TYPE));
|
||||
+ map.put(CraftMetaAxolotlBucket.class, Set.of(CraftMetaAxolotlBucket.ENTITY_TAG.TYPE, CraftMetaAxolotlBucket.BUCKET_ENTITY_TAG.TYPE));
|
||||
+ map.put(CraftMetaBanner.class, Set.of(/*CraftMetaBlockState.BLOCK_ENTITY_TAG.NBT, */CraftMetaBanner.PATTERNS.TYPE)); // banner uses same tag as block state
|
||||
+ map.put(CraftMetaBlockState.class, Set.of(CraftMetaBlockState.BLOCK_ENTITY_TAG.TYPE));
|
||||
+ map.put(CraftMetaBook.class, Set.of(CraftMetaBook.BOOK_CONTENT.TYPE));
|
||||
+ map.put(CraftMetaBookSigned.class, Set.of(CraftMetaBookSigned.BOOK_CONTENT.TYPE));
|
||||
+ map.put(CraftMetaBundle.class, Set.of(CraftMetaBundle.ITEMS.TYPE));
|
||||
+ map.put(CraftMetaCharge.class, Set.of(CraftMetaCharge.EXPLOSION.TYPE));
|
||||
+ map.put(CraftMetaColorableArmor.class, Set.of(CraftMetaArmor.TRIM.TYPE, CraftMetaLeatherArmor.COLOR.TYPE));
|
||||
+ map.put(CraftMetaCompass.class, Set.of(CraftMetaCompass.LODESTONE_TARGET.TYPE));
|
||||
+ map.put(CraftMetaCrossbow.class, Set.of(CraftMetaCrossbow.CHARGED_PROJECTILES.TYPE));
|
||||
+ map.put(CraftMetaEnchantedBook.class, Set.of(CraftMetaEnchantedBook.STORED_ENCHANTMENTS.TYPE));
|
||||
+ map.put(CraftMetaEntityTag.class, Set.of(CraftMetaEntityTag.ENTITY_TAG.TYPE));
|
||||
+ map.put(CraftMetaFirework.class, Set.of(CraftMetaFirework.FIREWORKS.TYPE));
|
||||
+ map.put(CraftMetaKnowledgeBook.class, Set.of(CraftMetaKnowledgeBook.BOOK_RECIPES.TYPE));
|
||||
+ map.put(CraftMetaLeatherArmor.class, Set.of(CraftMetaLeatherArmor.COLOR.TYPE));
|
||||
+ map.put(CraftMetaMap.class, Set.of(CraftMetaMap.MAP_COLOR.TYPE, CraftMetaMap.MAP_POST_PROCESSING.TYPE, CraftMetaMap.MAP_ID.TYPE));
|
||||
+ map.put(CraftMetaMusicInstrument.class, Set.of(CraftMetaMusicInstrument.GOAT_HORN_INSTRUMENT.TYPE));
|
||||
+ map.put(CraftMetaOminousBottle.class, Set.of(CraftMetaOminousBottle.OMINOUS_BOTTLE_AMPLIFIER.TYPE));
|
||||
+ map.put(CraftMetaPotion.class, Set.of(CraftMetaPotion.POTION_CONTENTS.TYPE));
|
||||
+ map.put(CraftMetaSkull.class, Set.of(CraftMetaSkull.SKULL_PROFILE.TYPE, CraftMetaSkull.NOTE_BLOCK_SOUND.TYPE));
|
||||
+ map.put(CraftMetaSpawnEgg.class, Set.of(CraftMetaSpawnEgg.ENTITY_TAG.TYPE));
|
||||
+ map.put(CraftMetaSuspiciousStew.class, Set.of(CraftMetaSuspiciousStew.EFFECTS.TYPE));
|
||||
+ map.put(CraftMetaTropicalFishBucket.class, Set.of(CraftMetaTropicalFishBucket.ENTITY_TAG.TYPE, CraftMetaTropicalFishBucket.BUCKET_ENTITY_TAG.TYPE));
|
||||
+
|
||||
+ for (final Map.Entry<Class<? extends CraftMetaItem>, Set<DataComponentType<?>>> entry : map.entrySet()) {
|
||||
+ final ArrayList<DataComponentType<?>> topLevelTags = new ArrayList<>(entry.getValue());
|
||||
+ // add tags common to CraftMetaItem to all
|
||||
+ topLevelTags.addAll(DEFAULT_HANDLED_DCTS);
|
||||
+ HANDLED_DCTS_PER_TYPE.put(entry.getKey(), Set.copyOf(topLevelTags));
|
||||
+ }
|
||||
+ }
|
||||
+ return HANDLED_DCTS_PER_TYPE.getOrDefault(clazz, DEFAULT_HANDLED_DCTS);
|
||||
}
|
||||
}
|
||||
+ // Paper end - improve checking handled data component types
|
||||
|
||||
protected static <T> Optional<? extends T> getOrEmpty(DataComponentPatch tag, ItemMetaKeyType<T> type) {
|
||||
Optional<? extends T> result = tag.get(type.TYPE);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java
|
||||
index bd44481a7d794943cb8695bea2a773a4562f0fae..20638aa593e0a6c78e4bfdb936e69f3d36e18f4e 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java
|
||||
@@ -31,8 +31,8 @@ public class CraftMetaKnowledgeBook extends CraftMetaItem implements KnowledgeBo
|
||||
}
|
||||
}
|
||||
|
||||
- CraftMetaKnowledgeBook(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaKnowledgeBook(DataComponentPatch tag, java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
|
||||
getOrEmpty(tag, CraftMetaKnowledgeBook.BOOK_RECIPES).ifPresent((pages) -> {
|
||||
for (int i = 0; i < pages.size(); i++) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java
|
||||
index b97e9a8f163adbb30d2e7db16aeb99544fcb2916..157a7b7351f48e68d2923c72ed3bbe3dcae21383 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java
|
||||
@@ -35,8 +35,8 @@ class CraftMetaLeatherArmor extends CraftMetaItem implements LeatherArmorMeta {
|
||||
CraftMetaLeatherArmor.readColor(this, meta);
|
||||
}
|
||||
|
||||
- CraftMetaLeatherArmor(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaLeatherArmor(DataComponentPatch tag, java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
CraftMetaLeatherArmor.readColor(this, tag);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java
|
||||
index 6b34a8d33faa49ffa9082995e67af10d3cb38c03..d829f4da371b44e7480896118547734be400a314 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java
|
||||
@@ -45,8 +45,8 @@ class CraftMetaMap extends CraftMetaItem implements MapMeta {
|
||||
this.color = map.color;
|
||||
}
|
||||
|
||||
- CraftMetaMap(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaMap(DataComponentPatch tag, java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
|
||||
getOrEmpty(tag, CraftMetaMap.MAP_ID).ifPresent((mapId) -> {
|
||||
this.mapId = mapId.id();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMusicInstrument.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMusicInstrument.java
|
||||
index 4eb2993903f5fa9fb9fd65282a42f26b3aa1e7bd..f33f1d250a3a4068df79cd1eb37baffda981aab3 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMusicInstrument.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMusicInstrument.java
|
||||
@@ -27,8 +27,8 @@ public class CraftMetaMusicInstrument extends CraftMetaItem implements MusicInst
|
||||
}
|
||||
}
|
||||
|
||||
- CraftMetaMusicInstrument(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaMusicInstrument(DataComponentPatch tag, java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
|
||||
getOrEmpty(tag, CraftMetaMusicInstrument.GOAT_HORN_INSTRUMENT).ifPresent((instrument) -> {
|
||||
this.instrument = org.bukkit.craftbukkit.CraftRegistry.unwrapAndConvertHolder(org.bukkit.Registry.INSTRUMENT, instrument).orElse(null); // Paper - fix upstream not handling custom instruments
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java
|
||||
index 19f1425ae86e1b8b8fd46a5c6a193d1b77aeefe9..7197c4f5698fd041c4db6d0f6a80c55f77661789 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaOminousBottle.java
|
||||
@@ -24,8 +24,8 @@ public class CraftMetaOminousBottle extends CraftMetaItem implements OminousBott
|
||||
this.ominousBottleAmplifier = bottleMeta.ominousBottleAmplifier;
|
||||
}
|
||||
|
||||
- CraftMetaOminousBottle(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaOminousBottle(DataComponentPatch tag, java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
getOrEmpty(tag, CraftMetaOminousBottle.OMINOUS_BOTTLE_AMPLIFIER).ifPresent((amplifier) -> {
|
||||
this.ominousBottleAmplifier = amplifier;
|
||||
});
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java
|
||||
index e2aa305dcaf94d76fa3b74fc33b4d8bbc6d92b2b..db7f71af22d904de08d4badaa7f66d1286d5bf16 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java
|
||||
@@ -61,8 +61,8 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta {
|
||||
}
|
||||
}
|
||||
|
||||
- CraftMetaPotion(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaPotion(DataComponentPatch tag, java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
getOrEmpty(tag, CraftMetaPotion.POTION_CONTENTS).ifPresent((potionContents) -> {
|
||||
potionContents.potion().ifPresent((potion) -> {
|
||||
this.type = CraftPotionType.minecraftHolderToBukkit(potion);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java
|
||||
index a08c57770c658bb289c96b69b966d98af72eef67..7bdc94c3ba7d8a0d74c2d88edbb32112a90c5980 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java
|
||||
@@ -69,8 +69,8 @@ class CraftMetaSkull extends CraftMetaItem implements SkullMeta {
|
||||
this.noteBlockSound = skullMeta.noteBlockSound;
|
||||
}
|
||||
|
||||
- CraftMetaSkull(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaSkull(DataComponentPatch tag, java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
|
||||
getOrEmpty(tag, CraftMetaSkull.SKULL_PROFILE).ifPresent((resolvableProfile) -> {
|
||||
this.setProfile(resolvableProfile.gameProfile());
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java
|
||||
index 1c2b0407b51906a255e6d240fab969578743938e..b98e656c0bb382667bd186a500c5505f1ed3f7cd 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java
|
||||
@@ -119,8 +119,8 @@ public class CraftMetaSpawnEgg extends CraftMetaItem implements SpawnEggMeta {
|
||||
this.entityTag = egg.entityTag;
|
||||
}
|
||||
|
||||
- CraftMetaSpawnEgg(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaSpawnEgg(DataComponentPatch tag, java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
|
||||
getOrEmpty(tag, CraftMetaSpawnEgg.ENTITY_TAG).ifPresent((nbt) -> {
|
||||
this.entityTag = nbt.copyTag();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSuspiciousStew.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSuspiciousStew.java
|
||||
index 14e944b4e83b80e0fc6d81e346cc305ab00561c5..39cab624de062514358a2a2942aea0e58cbd6e3e 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSuspiciousStew.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSuspiciousStew.java
|
||||
@@ -34,8 +34,8 @@ public class CraftMetaSuspiciousStew extends CraftMetaItem implements Suspicious
|
||||
}
|
||||
}
|
||||
|
||||
- CraftMetaSuspiciousStew(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaSuspiciousStew(DataComponentPatch tag, java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
getOrEmpty(tag, CraftMetaSuspiciousStew.EFFECTS).ifPresent((suspiciousStewEffects) -> {
|
||||
List<SuspiciousStewEffects.Entry> list = suspiciousStewEffects.effects();
|
||||
int length = list.size();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaTropicalFishBucket.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaTropicalFishBucket.java
|
||||
index 911bdce0795a6b11cd1d5ad5211202456e5225d4..b5392a3a6f6f3d0a54549e6bb93f28590ee048f0 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaTropicalFishBucket.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaTropicalFishBucket.java
|
||||
@@ -39,8 +39,8 @@ class CraftMetaTropicalFishBucket extends CraftMetaItem implements TropicalFishB
|
||||
this.bucketEntityTag = bucket.bucketEntityTag;
|
||||
}
|
||||
|
||||
- CraftMetaTropicalFishBucket(DataComponentPatch tag) {
|
||||
- super(tag);
|
||||
+ CraftMetaTropicalFishBucket(DataComponentPatch tag, java.util.Set<net.minecraft.core.component.DataComponentType<?>> extraHandledDcts) { // Paper
|
||||
+ super(tag, extraHandledDcts); // Paper
|
||||
|
||||
getOrEmpty(tag, CraftMetaTropicalFishBucket.ENTITY_TAG).ifPresent((nbt) -> {
|
||||
this.entityTag = nbt.copyTag();
|
||||
diff --git a/src/test/java/org/bukkit/craftbukkit/inventory/DeprecatedItemMetaCustomValueTest.java b/src/test/java/org/bukkit/craftbukkit/inventory/DeprecatedItemMetaCustomValueTest.java
|
||||
index 51e2acf125bdff2ba6d8fd8af9f22e233d7c74a7..6bed0a5c8d9f1ca72678cdf4699128e441a24541 100644
|
||||
--- a/src/test/java/org/bukkit/craftbukkit/inventory/DeprecatedItemMetaCustomValueTest.java
|
||||
+++ b/src/test/java/org/bukkit/craftbukkit/inventory/DeprecatedItemMetaCustomValueTest.java
|
||||
@@ -96,7 +96,7 @@ public class DeprecatedItemMetaCustomValueTest extends AbstractTestingBase {
|
||||
CraftMetaItem.Applicator compound = new CraftMetaItem.Applicator();
|
||||
itemMeta.applyToItem(compound);
|
||||
|
||||
- assertEquals(itemMeta, new CraftMetaItem(compound.build()));
|
||||
+ assertEquals(itemMeta, new CraftMetaItem(compound.build(), null)); // Paper
|
||||
}
|
||||
|
||||
@Test
|
||||
diff --git a/src/test/java/org/bukkit/craftbukkit/inventory/MetaHandledTagsTest.java b/src/test/java/org/bukkit/craftbukkit/inventory/MetaHandledTagsTest.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..d9692972e3ad089885d43711b6a7fb3e96da59b1
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/org/bukkit/craftbukkit/inventory/MetaHandledTagsTest.java
|
||||
@@ -0,0 +1,32 @@
|
||||
+package org.bukkit.craftbukkit.inventory;
|
||||
+
|
||||
+import io.github.classgraph.ClassGraph;
|
||||
+import io.github.classgraph.ClassInfo;
|
||||
+import io.github.classgraph.ClassInfoList;
|
||||
+import io.github.classgraph.ScanResult;
|
||||
+import org.bukkit.support.AbstractTestingBase;
|
||||
+import org.junit.jupiter.api.Test;
|
||||
+
|
||||
+import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
+import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
+
|
||||
+// in cb package because of package-private stuff
|
||||
+class MetaHandledTagsTest extends AbstractTestingBase {
|
||||
+
|
||||
+ @Test
|
||||
+ public void checkAllMetasHaveHandledTags() {
|
||||
+ try (final ScanResult result = new ClassGraph()
|
||||
+ .whitelistPackages("org.bukkit.craftbukkit.inventory")
|
||||
+ .enableAllInfo().scan()) {
|
||||
+ final ClassInfoList subclasses = result.getSubclasses(CraftMetaItem.class.getName());
|
||||
+ assertFalse(subclasses.isEmpty(), "found 0 sub types");
|
||||
+ for (final ClassInfo subclass : subclasses) {
|
||||
+ final Class<CraftMetaItem> clazz = subclass.loadClass(CraftMetaItem.class);
|
||||
+ CraftMetaItem.getTopLevelHandledDcts(clazz); // load into map
|
||||
+ assertTrue(CraftMetaItem.HANDLED_DCTS_PER_TYPE.containsKey(clazz), subclass.getName() + " not found in handled tags map");
|
||||
+ }
|
||||
+ } catch (Exception e) {
|
||||
+ throw new RuntimeException(e);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/test/java/org/bukkit/craftbukkit/inventory/PersistentDataContainerTest.java b/src/test/java/org/bukkit/craftbukkit/inventory/PersistentDataContainerTest.java
|
||||
index 30da18cbc878fb1ac2a134f3bcbfcb8d7bec3938..6f94c7a19f2f598a836ec7db30332dd95f8675a6 100644
|
||||
--- a/src/test/java/org/bukkit/craftbukkit/inventory/PersistentDataContainerTest.java
|
||||
+++ b/src/test/java/org/bukkit/craftbukkit/inventory/PersistentDataContainerTest.java
|
||||
@@ -130,7 +130,7 @@ public class PersistentDataContainerTest extends AbstractTestingBase {
|
||||
CraftMetaItem.Applicator compound = new CraftMetaItem.Applicator();
|
||||
itemMeta.applyToItem(compound);
|
||||
|
||||
- assertEquals(itemMeta, new CraftMetaItem(compound.build()));
|
||||
+ assertEquals(itemMeta, new CraftMetaItem(compound.build(), null)); // Paper
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -463,7 +463,7 @@ public class PersistentDataContainerTest extends AbstractTestingBase {
|
||||
|
||||
@Test
|
||||
public void testEmptyListApplicationToAnyType() throws IOException {
|
||||
- final CraftMetaItem craftItem = new CraftMetaItem(DataComponentPatch.EMPTY);
|
||||
+ final CraftMetaItem craftItem = new CraftMetaItem(DataComponentPatch.EMPTY, null); // Paper
|
||||
final PersistentDataContainer container = craftItem.getPersistentDataContainer();
|
||||
|
||||
container.set(PersistentDataContainerTest.requestKey("list"), PersistentDataType.LIST.strings(), List.of());
|
||||
@@ -476,7 +476,7 @@ public class PersistentDataContainerTest extends AbstractTestingBase {
|
||||
final CraftMetaItem.Applicator storage = new CraftMetaItem.Applicator();
|
||||
craftItem.applyToItem(storage);
|
||||
|
||||
- final CraftMetaItem readItem = new CraftMetaItem(storage.build());
|
||||
+ final CraftMetaItem readItem = new CraftMetaItem(storage.build(), null); // Paper
|
||||
final PersistentDataContainer readContainer = readItem.getPersistentDataContainer();
|
||||
|
||||
assertTrue(readContainer.has(PersistentDataContainerTest.requestKey("list"), PersistentDataType.LIST.strings()));
|
File diff suppressed because it is too large
Load diff
|
@ -1,38 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: SoSeDiK <mrsosedik@gmail.com>
|
||||
Date: Wed, 1 May 2024 10:58:50 +0300
|
||||
Subject: [PATCH] Expose #hasColor to leather armor
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java
|
||||
index 4e423c4790d7b03c283c9a5fa94bce4a1153445e..1e8a76f6dd54931eec261653a7bd51b6d18d3c68 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaColorableArmor.java
|
||||
@@ -134,4 +134,11 @@ public class CraftMetaColorableArmor extends CraftMetaArmor implements Colorable
|
||||
}
|
||||
return original != hash ? CraftMetaColorableArmor.class.hashCode() ^ hash : hash;
|
||||
}
|
||||
+
|
||||
+ // Paper start - Expose #hasColor to leather armor
|
||||
+ @Override
|
||||
+ public boolean isDyed() {
|
||||
+ return hasColor();
|
||||
+ }
|
||||
+ // Paper end - Expose #hasColor to leather armor
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java
|
||||
index 70c0d4cc85c045d040a35cd406f3f7ce9b6a58fa..0860d85fb9c6d0567f678569efb3c560f58612a9 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java
|
||||
@@ -183,4 +183,11 @@ class CraftMetaLeatherArmor extends CraftMetaItem implements LeatherArmorMeta {
|
||||
builder.put(CraftMetaLeatherArmor.COLOR.BUKKIT, meta.getColor());
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Paper start - Expose #hasColor to leather armor
|
||||
+ @Override
|
||||
+ public boolean isDyed() {
|
||||
+ return hasColor();
|
||||
+ }
|
||||
+ // Paper end - Expose #hasColor to leather armor
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: nostalfinals <yuu8583@proton.me>
|
||||
Date: Mon, 8 Apr 2024 23:24:38 +0800
|
||||
Subject: [PATCH] Added API to get player ha proxy address
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
|
||||
index 58d28b6c1cc7da7d786f78308db971f7502ad844..02833deaa2bb7e5abc655bc1bdbe15c4b3ac7119 100644
|
||||
--- a/src/main/java/net/minecraft/network/Connection.java
|
||||
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||||
@@ -157,6 +157,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
this.stopReadingPackets = true;
|
||||
}
|
||||
// Paper end - packet limiter
|
||||
+ @Nullable public SocketAddress haProxyAddress; // Paper - Add API to get player's proxy address
|
||||
|
||||
public Connection(PacketFlow side) {
|
||||
this.receiving = side;
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
|
||||
index 52f537b7bfbdeaad9d17c0e88a1ed1c8925a833f..8aff5129f85ab5729b3da2e465871be62d15bdf2 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
|
||||
@@ -146,6 +146,13 @@ public class ServerConnectionListener {
|
||||
|
||||
Connection connection = (Connection) channel.pipeline().get("packet_handler");
|
||||
connection.address = socketaddr;
|
||||
+
|
||||
+ // Paper start - Add API to get player's proxy address
|
||||
+ final String proxyAddress = message.destinationAddress();
|
||||
+ final int proxyPort = message.destinationPort();
|
||||
+
|
||||
+ connection.haProxyAddress = new java.net.InetSocketAddress(proxyAddress, proxyPort);
|
||||
+ // Paper end - Add API to get player's proxy address
|
||||
}
|
||||
} else {
|
||||
super.channelRead(ctx, msg);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 815bcfd90218b932ca004c0f18db8b4de5d35c19..40155cc70ba959eea8011626a30e26f44298c99d 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -273,6 +273,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Add API to get player's proxy address
|
||||
+ @Override
|
||||
+ public @Nullable InetSocketAddress getHAProxyAddress() {
|
||||
+ if (this.getHandle().connection == null) return null;
|
||||
+
|
||||
+ return this.getHandle().connection.connection.haProxyAddress instanceof final InetSocketAddress inetSocketAddress ? inetSocketAddress : null;
|
||||
+ }
|
||||
+ // Paper end - Add API to get player's proxy address
|
||||
+
|
||||
public interface TransferCookieConnection {
|
||||
|
||||
boolean isTransferred();
|
|
@ -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 33340e8ebe23a1a9ce587be34551fb929c41d0fd..b8977749d35dd7343021425f477445bec470d46b 100644
|
||||
--- a/src/main/java/net/minecraft/core/component/DataComponentPatch.java
|
||||
+++ b/src/main/java/net/minecraft/core/component/DataComponentPatch.java
|
||||
@@ -143,7 +143,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,116 +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 482d7b12b80328fba97a01bcfeb974b7ac4bcdb7..fb4c8a2a15e8e3e26454b7da920454e9861336c6 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
|
||||
@@ -91,7 +91,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 38690b28b6f67624d68877c1e89ebe30b402b233..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(), true), this.toNMS(this.getBase(), true), this.toNMS(this.getAddition(), true), 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 5d7782b168138383c606a2c52fbdebe1732364ac..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(), true), this.toNMS(this.getBase(), true), this.toNMS(this.getAddition(), true), 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..b6816485a2360b936c049b398183658ee18813ec
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/inventory/recipe/TestRecipeChoice.java
|
||||
@@ -0,0 +1,24 @@
|
||||
+package io.papermc.paper.inventory.recipe;
|
||||
+
|
||||
+import java.util.Iterator;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.inventory.Recipe;
|
||||
+import org.bukkit.support.AbstractTestingBase;
|
||||
+import org.junit.jupiter.api.Test;
|
||||
+
|
||||
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
+import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
+
|
||||
+class TestRecipeChoice extends AbstractTestingBase {
|
||||
+
|
||||
+ @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/DummyServer.java b/src/test/java/org/bukkit/support/DummyServer.java
|
||||
index d7e24766f383f75ed46123fff1bd0ec926a635b4..a73c16bb7923957113e688fa6fe46cbd68837d3e 100644
|
||||
--- a/src/test/java/org/bukkit/support/DummyServer.java
|
||||
+++ b/src/test/java/org/bukkit/support/DummyServer.java
|
||||
@@ -56,6 +56,14 @@ public final class DummyServer {
|
||||
when(instance.getTag(anyString(), any(org.bukkit.NamespacedKey.class), any())).thenAnswer(ignored -> new io.papermc.paper.util.EmptyTag());
|
||||
// paper end - testing additions
|
||||
|
||||
+ // Paper start - add test for recipe conversion
|
||||
+ when(instance.recipeIterator()).thenAnswer(ignored -> {
|
||||
+ return com.google.common.collect.Iterators.transform(
|
||||
+ AbstractTestingBase.DATA_PACK.getRecipeManager().byType.entries().iterator(),
|
||||
+ input -> input.getValue().toBukkitRecipe());
|
||||
+ });
|
||||
+ // Paper end - add test for recipe conversion
|
||||
+
|
||||
Bukkit.setServer(instance);
|
||||
} catch (Throwable t) {
|
||||
throw new Error(t);
|
|
@ -1,114 +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
|
||||
|
||||
Add test for EquipmentSlotGroup
|
||||
|
||||
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 60aa9dd1617d302c3b49af21d581a32313c171cc..b6cd6897844aa9c8b9a94e41c56c4cfe4ac78780 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
@@ -1367,7 +1367,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());
|
||||
}
|
||||
}
|
||||
@@ -1435,9 +1435,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..ee0bfe4edb134d7ea3a3b97f5102a7f3122c3b99
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/inventory/item/EquipmentSlotGroupTest.java
|
||||
@@ -0,0 +1,51 @@
|
||||
+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.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;
|
||||
+
|
||||
+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 f9d4b33050a6fe8c2dabe8e5eec075d95dc513e0..dc106685ecb483c33c06e4f83eda27be58251aad 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 fdb52ad85cfaa1d53aadcad72cec3d3c8c12c058..38075b7348ad7ca3cfece2bfae63e0cce827c694 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,228 +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..e9436f8a73ee0a02096d66e14d73edaae28d5a41
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/util/DataSanitizationUtil.java
|
||||
@@ -0,0 +1,100 @@
|
||||
+package io.papermc.paper.util;
|
||||
+
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.List;
|
||||
+import java.util.concurrent.atomic.AtomicBoolean;
|
||||
+import java.util.function.UnaryOperator;
|
||||
+import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
+import net.minecraft.network.codec.StreamCodec;
|
||||
+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.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;
|
||||
+ }
|
||||
+ final List<ItemStack> items = projectiles.getItems();
|
||||
+ final List<ItemStack> sanitized = new ArrayList<>();
|
||||
+ for (int i = 0; i < Math.min(items.size(), 3); i++) {
|
||||
+ // we want to preserve item type as vanilla client can change visuals based on type
|
||||
+ sanitized.add(new ItemStack(items.get(i).getItemHolder()));
|
||||
+ }
|
||||
+ return ChargedProjectiles.of(sanitized);
|
||||
+ }
|
||||
+
|
||||
+ private static BundleContents sanitizeBundleContents(final BundleContents contents) {
|
||||
+ // Bundles change their texture based on their fullness.
|
||||
+ int sizeUsed = 0;
|
||||
+ for (final ItemStack item : contents.items()) {
|
||||
+ final int scale = 64 / item.getMaxStackSize();
|
||||
+ sizeUsed += scale * item.getCount();
|
||||
+ }
|
||||
+ // Now we add a single fake item that uses the same amount of slots as all other items.
|
||||
+ final List<ItemStack> items = new ArrayList<>();
|
||||
+ items.add(new ItemStack(Items.PAPER, sizeUsed));
|
||||
+ return new BundleContents(items);
|
||||
+ }
|
||||
+
|
||||
+ 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 5632974af9c603d333ffc30a5a1b1e851821a3bb..9b2a209cda955ef3e5d8ff3ed1b2249888c7d139 100644
|
||||
--- a/src/main/java/net/minecraft/core/component/DataComponents.java
|
||||
+++ b/src/main/java/net/minecraft/core/component/DataComponents.java
|
||||
@@ -139,10 +139,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()
|
||||
@@ -206,7 +206,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 e092a486c4041ab1cfe9e29c88d0d94528a6e9a6..3945ca04ede578121b370592482ac917f2d4cf96 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 id, List<Pair<EquipmentSlot, ItemStack>> equipmentList) {
|
||||
+ // Paper start - data sanitization
|
||||
+ this(id, equipmentList, false);
|
||||
+ }
|
||||
+ private boolean sanitize = false;
|
||||
+ public ClientboundSetEquipmentPacket(int id, List<Pair<EquipmentSlot, ItemStack>> equipmentList, boolean sanitize) {
|
||||
+ this.sanitize = sanitize;
|
||||
+ // Paper end - data sanitization
|
||||
this.entity = id;
|
||||
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 f16a69775332a08ed0e87d27acd0fc959359694c..a2279262c93408c11f5d2290b48fd794975e8cfe 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -361,7 +361,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 b9b3277c8ed94e0cd30b20b9c00a33eaad48e5ac..c450447585af4c8cdc87abe871c229ff895c3e53 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -2788,7 +2788,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
entity.refreshEntityData(ServerGamePacketListenerImpl.this.player);
|
||||
// SPIGOT-7136 - Allays
|
||||
if (entity instanceof Allay) {
|
||||
- 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();
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index d0b6ade676d94e768c92432dc6cee9f200acf5f2..21e61bb75ac7ce468bc757633ce678b21bcb9deb 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3302,7 +3302,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 9962d50ea342cd47428a814519b2d54f547753a4..6ea34a76707d9f60076b7423ac0bb1de200308ae 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
@@ -503,11 +503,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 7c7b9b1e0b604b0164b431873e6753b60421f970..f8589837070039b4911a9532b92fa959c7af6352 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -473,9 +473,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 0a8eeebb2d702ebcefd9f26cc0f41d1eab497902..14281a4e72f49dc4eb2ca3da8479c1f81a3a175d 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -150,6 +150,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 2a8609e33716949ff1877b6d10f64a9d7a7c81e9..14ee7b5b9b804bebd4e2a846b238547a28a36035 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -452,7 +452,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 6ea34a76707d9f60076b7423ac0bb1de200308ae..7dd5e0b935d98d552c916f8412569ff4aa0e9b04 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
@@ -410,6 +410,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 c450447585af4c8cdc87abe871c229ff895c3e53..4ae88bfcead40cd05f9514a48a922a37767cb3cf 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -3054,14 +3054,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 02833deaa2bb7e5abc655bc1bdbe15c4b3ac7119..f40420a6841f03983b0837e177ea2ae7c3a37ca1 100644
|
||||
--- a/src/main/java/net/minecraft/network/Connection.java
|
||||
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||||
@@ -214,7 +214,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..9c004e7cb46841d874ab997bf2e3b63ae763aec7 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)1
|
||||
+ 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)1
|
||||
+ @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 26208ca74688be062584824de5d074321b33f1b1..946cd46f3389a4d4ceda86e0115c59c5725a8a0a 100644
|
||||
--- a/src/test/java/org/bukkit/craftbukkit/legacy/MaterialReroutingTest.java
|
||||
+++ b/src/test/java/org/bukkit/craftbukkit/legacy/MaterialReroutingTest.java
|
||||
@@ -55,6 +55,9 @@ public class MaterialReroutingTest extends AbstractTestingBase {
|
||||
.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);
|
||||
@@ -92,6 +95,10 @@ public class MaterialReroutingTest extends AbstractTestingBase {
|
||||
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(Collections.emptySet(), 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);
|
||||
@@ -108,6 +115,13 @@ public class MaterialReroutingTest extends AbstractTestingBase {
|
||||
}
|
||||
}
|
||||
|
||||
+ // 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) {
|
Loading…
Add table
Add a link
Reference in a new issue