988
This commit is contained in:
parent
4140de28eb
commit
6d4e235784
45 changed files with 190 additions and 443 deletions
|
@ -6342,7 +6342,7 @@ index 5d4336210e11ee39521b4096a5f0874329053cdc..526d5b9bd6ce8eade59d3d3cf8bd7ad7
|
|||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 419a27a8bdc8adfeb6ea89e3bfe1838a80d75a33..ce0d22452171857e3cf070bf01450a7653ec7142 100644
|
||||
index 5b920beb39dad8d392b4e5e12a89880720e41942..319f51eb8adde7584c74780ac0539f4b8ef8fe7f 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -170,6 +170,62 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
|
|
@ -978,7 +978,7 @@ index d38ecbc208c34509eaf77751ac45d9ef51a5dce8..b51c3f8c485496734ea58c15377a1215
|
|||
// CraftBukkit end
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index ce0d22452171857e3cf070bf01450a7653ec7142..6581566ca4e4fac0691e4f5851f8895d9ac7a38f 100644
|
||||
index 319f51eb8adde7584c74780ac0539f4b8ef8fe7f..ddadb0f13b96a39ec89cdaeea7bc02ee62ef2a06 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1,8 +1,10 @@
|
||||
|
|
|
@ -19,10 +19,10 @@ index b24e8255ab18eb5b2e4968aa62aa3d72ef33f0eb..12b7d50f49a2184aaf220a4a50a137b2
|
|||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
index 4091d4d68b58bdefb2fdac1815e351d4f7c8a523..b7d0a48f38f0d8ae586012bb4e9a9faec21103c2 100644
|
||||
index 40f2f4d052add3b4270d29c843e49fb621e1bc8d..df099d4c7f101f50d40dae99b45c271b02712434 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
@@ -134,6 +134,11 @@ public class RegionFileStorage implements AutoCloseable {
|
||||
@@ -134,6 +134,11 @@ public final class RegionFileStorage implements AutoCloseable {
|
||||
|
||||
protected void write(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException {
|
||||
RegionFile regionfile = this.getRegionFile(pos, false); // CraftBukkit
|
||||
|
@ -34,7 +34,7 @@ index 4091d4d68b58bdefb2fdac1815e351d4f7c8a523..b7d0a48f38f0d8ae586012bb4e9a9fae
|
|||
|
||||
if (nbt == null) {
|
||||
regionfile.clear(pos);
|
||||
@@ -158,7 +163,18 @@ public class RegionFileStorage implements AutoCloseable {
|
||||
@@ -158,7 +163,18 @@ public final class RegionFileStorage implements AutoCloseable {
|
||||
dataoutputstream.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,10 +11,10 @@ The implementation uses a LinkedHashMap as an LRU cache (modified from HashMap).
|
|||
The maximum size of the RegionFileCache is also made configurable.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
index b7d0a48f38f0d8ae586012bb4e9a9faec21103c2..7d4aa3d375bde32e0d2606346202929d481acad0 100644
|
||||
index df099d4c7f101f50d40dae99b45c271b02712434..491035aaefff4ee96435ec5d3f9417e28eae0796 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
@@ -39,7 +39,7 @@ public class RegionFileStorage implements AutoCloseable {
|
||||
@@ -39,7 +39,7 @@ public final class RegionFileStorage implements AutoCloseable {
|
||||
if (regionfile != null) {
|
||||
return regionfile;
|
||||
} else {
|
||||
|
|
|
@ -9,7 +9,7 @@ from triggering monster spawns on a server.
|
|||
Also a highly more effecient way to blanket block spawns in a world
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 6581566ca4e4fac0691e4f5851f8895d9ac7a38f..c96346bd0207537899d266fe2c8f29a1663e10c3 100644
|
||||
index ddadb0f13b96a39ec89cdaeea7bc02ee62ef2a06..d04b69838c6f5fd1808782cacb31c6e00087bbac 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1101,7 +1101,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
|
|
@ -5,7 +5,7 @@ Subject: [PATCH] Add Debug Entities option to debug dupe uuid issues
|
|||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index c96346bd0207537899d266fe2c8f29a1663e10c3..e2f176d34443f0d1b00649efa45c65138042a015 100644
|
||||
index d04b69838c6f5fd1808782cacb31c6e00087bbac..96b7f0ac35a1e87c3f78a24180b207c32749fb71 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1321,6 +1321,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
|
|
@ -8,7 +8,7 @@ Sets tracking range of watermobs to animals instead of misc and simplifies code
|
|||
Also ignores Enderdragon, defaulting it to Mojang's setting
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index e2f176d34443f0d1b00649efa45c65138042a015..3784fbe3548727ab5ad8cfefef2d8d594a76123f 100644
|
||||
index 96b7f0ac35a1e87c3f78a24180b207c32749fb71..795c81c8f6fa59eded8b5a5084a8acb46d118fdb 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1613,6 +1613,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
|
|
@ -7,7 +7,7 @@ Suspected case would be around the technique used in .stopRiding
|
|||
Stack will identify any causer of this and warn instead of crashing.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 3784fbe3548727ab5ad8cfefef2d8d594a76123f..5732aded2e4dbeea84dbe6ebac71c2ad5ce4729a 100644
|
||||
index 795c81c8f6fa59eded8b5a5084a8acb46d118fdb..1709821c73362b2ae54681ec1d59b40bfa9335b3 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1308,6 +1308,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
|
|
@ -31,7 +31,7 @@ delays anymore.
|
|||
public net.minecraft.server.level.ChunkMap addEntity(Lnet/minecraft/world/entity/Entity;)V
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 5732aded2e4dbeea84dbe6ebac71c2ad5ce4729a..d1247df5c51b0d377a27ea7cc5b5a2d1f1bf9b32 100644
|
||||
index 1709821c73362b2ae54681ec1d59b40bfa9335b3..68a1cc5f4f7f5997dfb7d40647e3e027c23ffb14 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1315,6 +1315,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
|
|
@ -7,7 +7,7 @@ Reference2BooleanOpenHashMap is going to have
|
|||
better lookups than HashMap.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index d1247df5c51b0d377a27ea7cc5b5a2d1f1bf9b32..cf7c7813d528429a18dc25051df7fc06dc159930 100644
|
||||
index 68a1cc5f4f7f5997dfb7d40647e3e027c23ffb14..77f064fb4437c1d98cf91dde98d4d88b28afa7c8 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1529,7 +1529,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
|
|
@ -44,10 +44,10 @@ index 12b7d50f49a2184aaf220a4a50a137b217c57124..f1237f6fd6414900ffbad0caee31aa83
|
|||
public void close() throws IOException {
|
||||
ByteBuffer bytebuffer = ByteBuffer.wrap(this.buf, 0, this.count);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
index 7d4aa3d375bde32e0d2606346202929d481acad0..36e914b26de070035f195f67c65ee1df0d10daf0 100644
|
||||
index 491035aaefff4ee96435ec5d3f9417e28eae0796..4c1212c6ef48594e766fa9e35a6e15916602d587 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
@@ -147,10 +147,17 @@ public class RegionFileStorage implements AutoCloseable {
|
||||
@@ -147,10 +147,17 @@ public final class RegionFileStorage implements AutoCloseable {
|
||||
|
||||
try {
|
||||
NbtIo.write(nbt, (DataOutput) dataoutputstream);
|
||||
|
@ -66,7 +66,7 @@ index 7d4aa3d375bde32e0d2606346202929d481acad0..36e914b26de070035f195f67c65ee1df
|
|||
} catch (Throwable throwable1) {
|
||||
throwable.addSuppressed(throwable1);
|
||||
}
|
||||
@@ -158,10 +165,7 @@ public class RegionFileStorage implements AutoCloseable {
|
||||
@@ -158,10 +165,7 @@ public final class RegionFileStorage implements AutoCloseable {
|
||||
|
||||
throw throwable;
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ index 7d4aa3d375bde32e0d2606346202929d481acad0..36e914b26de070035f195f67c65ee1df
|
|||
}
|
||||
// Paper start - Chunk save reattempt
|
||||
return;
|
||||
@@ -208,4 +212,13 @@ public class RegionFileStorage implements AutoCloseable {
|
||||
@@ -208,4 +212,13 @@ public final class RegionFileStorage implements AutoCloseable {
|
||||
public RegionStorageInfo info() {
|
||||
return this.info;
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ index 6854ca4d4fec2b4fa541c3fabf63787665572609..e7b444a10b244828827b3c66c5346520
|
|||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index cf7c7813d528429a18dc25051df7fc06dc159930..ef46d904fa49a779c235971883380b3e33e6dba1 100644
|
||||
index 77f064fb4437c1d98cf91dde98d4d88b28afa7c8..ccbd527803a2a4e911a01f815cc9c7ab785af836 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1091,7 +1091,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
|
|
@ -5,7 +5,7 @@ Subject: [PATCH] Player Entity Tracking Events
|
|||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index ef46d904fa49a779c235971883380b3e33e6dba1..8eae75993ad60226a86456487f3b3a59999ab423 100644
|
||||
index ccbd527803a2a4e911a01f815cc9c7ab785af836..e2521e1a56df8dcb1de815e5973de952408d3b8b 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1601,7 +1601,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
|
|
@ -6,7 +6,7 @@ Subject: [PATCH] Configurable entity tracking range by Y coordinate
|
|||
Options to configure entity tracking by Y coordinate, also for each entity category.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 8eae75993ad60226a86456487f3b3a59999ab423..38df456d3646c384d17ae9aec60c18fcd0651b4b 100644
|
||||
index e2521e1a56df8dcb1de815e5973de952408d3b8b..6c5557aad2455b79bb2adf8939eb9a6127ccc3c3 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1593,6 +1593,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
|
|
@ -5,7 +5,7 @@ Subject: [PATCH] Don't check if we can see non-visible entities
|
|||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 38df456d3646c384d17ae9aec60c18fcd0651b4b..cf4517e57169856acd0782e5ced4eb8c045b8d78 100644
|
||||
index 6c5557aad2455b79bb2adf8939eb9a6127ccc3c3..469f1dcb22c06025681e727e281b5b53f2b21c1f 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1604,7 +1604,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
|
|
@ -18,7 +18,7 @@ index a043ac10834562d357ef0b5aded2e916e2a0d056..74276c368016fcc4dbf9579b2ecbadc9
|
|||
@VisibleForTesting
|
||||
static long encode(double value) {
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index cf4517e57169856acd0782e5ced4eb8c045b8d78..6129720c9da217745fcd281186de7894597c267c 100644
|
||||
index 469f1dcb22c06025681e727e281b5b53f2b21c1f..2ce7da9707d7c1a48b5609ae51a516d599d7aee8 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1587,10 +1587,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
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 69914a048987c21ee2ed2c489aab269862fda8f2..bff83fe413c7baef4ba56a3270ea4463a58c792f 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Explosion.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Explosion.java
|
||||
@@ -193,6 +193,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 4d6409875771413de7ae20def2aaad4049709c30..dd519eacd6d4bea5447bea471f0ac6540d9bb49c 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -449,6 +449,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 bf52c36f31992a01a7403d8c85151327c9e944c4..45704653310efe9cb755a644674b54b8722c2c84 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
@@ -89,6 +89,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 936b56c116de63b38a416d5bab4223a88d0469d0..6c4a339be29bb9c07b741a1ca12de2217c8687ba 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
|
||||
@@ -173,7 +173,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;
|
||||
|
||||
@@ -253,7 +253,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) {
|
||||
@@ -888,6 +888,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);
|
||||
}
|
||||
@@ -991,7 +997,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 5c4b2a33d4007c36aef68604bca40a4eba510b4e..fd04a50183ccb1f21fc6efa70256e1bb4db2d6d4 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java
|
||||
@@ -207,6 +207,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;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
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()) {
|
||||
- ;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
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 62271e74399a827a488159da234465ef18e15e6e..d3b4d492aee380dc17f4232d90eaae4f07bb9f86 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 f0127f1b55999aa4a841341ad02cbcde45702b50..e675f1e3e5b6f9e1aa0d928ebb9abe76458edb38 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 56f23d7c7b5838ff8761de8691e685dd59d2eaa2..bb2e7cee612dc1fafa042674a0b0d07d7165b54c 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java
|
||||
@@ -114,6 +114,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
|
||||
}
|
||||
}
|
45
patches/server/0964-Deep-clone-nbt-tags-in-PDC.patch
Normal file
45
patches/server/0964-Deep-clone-nbt-tags-in-PDC.patch
Normal file
|
@ -0,0 +1,45 @@
|
|||
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 758e01a05f5ca88f72ea3d54a7cdc49bbfadfaf5..737b325f87bcaa8871dbed5deec01215a1f11bf7 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
@@ -318,7 +318,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;
|
||||
|
||||
@@ -1641,7 +1641,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
|
||||
}
|
63
patches/server/0965-Support-old-UUID-format-for-NBT.patch
Normal file
63
patches/server/0965-Support-old-UUID-format-for-NBT.patch
Normal file
|
@ -0,0 +1,63 @@
|
|||
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())
|
22
patches/server/0966-Fix-shield-disable-inconsistency.patch
Normal file
22
patches/server/0966-Fix-shield-disable-inconsistency.patch
Normal file
|
@ -0,0 +1,22 @@
|
|||
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 d535bb7adff273c9d4cdaac73f7dfe5bbd663c15..890d453fa5ee4b167ec83cce8e2882e2e4585b14 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) {
|
||||
+ if (!damagesource.is(DamageTypeTags.IS_PROJECTILE) && entity instanceof LivingEntity) { // Paper - Fix shield disable inconsistency
|
||||
this.blockUsingShield((LivingEntity) entity);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
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 737b325f87bcaa8871dbed5deec01215a1f11bf7..8a5785565d71f3f74a9ce0179a26dbff5530023d 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
@@ -196,6 +196,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();
|
||||
}
|
||||
@@ -424,7 +431,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);
|
||||
}, () -> {
|
||||
@@ -832,9 +841,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;
|
|
@ -0,0 +1,135 @@
|
|||
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 a8dfe7a4b3d01bf75587be078f471d1ef1d7a667..ea16dfa718b526d6520d7fcfc21d28f972f1f2bf 100644
|
||||
--- a/src/main/java/net/minecraft/network/Connection.java
|
||||
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||||
@@ -176,6 +176,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 4c776c591dd0a7b36945a6487fdfe86d1187b4af..82fc12ffbd1585b4a8d09a025914830af77b0f8d 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 ec1cb034d840633240f2b379b09f7d2f1c8971a5..cf8fd671490863e126c059157e1ca234e6509d9f 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
|
||||
@@ -52,7 +52,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];
|
200
patches/server/0969-Fix-ItemFlags.patch
Normal file
200
patches/server/0969-Fix-ItemFlags.patch
Normal file
|
@ -0,0 +1,200 @@
|
|||
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 8a5785565d71f3f74a9ce0179a26dbff5530023d..dbcf9a27112ac525722fd9b80ec736797864bfdf 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
@@ -250,6 +250,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;
|
||||
@@ -330,6 +336,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) {
|
||||
@@ -428,6 +438,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) {
|
||||
@@ -622,7 +646,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);
|
||||
}
|
||||
@@ -840,6 +873,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);
|
||||
@@ -914,7 +956,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
|
||||
@@ -1583,6 +1625,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
&& (this.hasJukeboxPlayable() ? that.hasJukeboxPlayable() && this.jukebox.equals(that.jukebox) : !that.hasJukeboxPlayable())
|
||||
&& (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);
|
||||
}
|
||||
|
||||
@@ -1627,6 +1671,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;
|
||||
}
|
||||
@@ -1670,6 +1716,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);
|
||||
@@ -1787,6 +1841,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 {
|
||||
@@ -1797,6 +1861,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());
|
||||
@@ -1936,6 +2008,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,
|
|
@ -0,0 +1,21 @@
|
|||
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 0b1741cd68d5066114a35cc14ed08b57f4f08fb2..f769f249ada432ee400055deabdb5e4aeaa88c05 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -1213,7 +1213,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);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
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 890d453fa5ee4b167ec83cce8e2882e2e4585b14..81b70e2dcf31ef651256a0ddf928c6370458c3dd 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() {
|
|
@ -0,0 +1,806 @@
|
|||
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 f6e84cccb0e805f73efe2c9625986c94099bb0d4..3c0d3faddcfcba74d90e1d5fccb60b891ef7c458 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 dbcf9a27112ac525722fd9b80ec736797864bfdf..5cdb9e07f79355e4590984b32be554053754ef5b 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
@@ -342,7 +342,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;
|
||||
});
|
||||
@@ -453,11 +453,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);
|
||||
}, () -> {
|
||||
@@ -1983,68 +1990,75 @@ 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.JUKEBOX_PLAYABLE.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.JUKEBOX_PLAYABLE.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 8fc3cd507d333d2bdea759d7c102a56e88ad5f5a..f6b3798cf06f94d7e3e76d1b6e83236ded5b21e0 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()));
|
1494
patches/server/0973-General-ItemMeta-fixes.patch
Normal file
1494
patches/server/0973-General-ItemMeta-fixes.patch
Normal file
File diff suppressed because it is too large
Load diff
38
patches/server/0974-Expose-hasColor-to-leather-armor.patch
Normal file
38
patches/server/0974-Expose-hasColor-to-leather-armor.patch
Normal file
|
@ -0,0 +1,38 @@
|
|||
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
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
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 ea16dfa718b526d6520d7fcfc21d28f972f1f2bf..4b9da6e2140b14f1e56056f5e9e94b2169d85501 100644
|
||||
--- a/src/main/java/net/minecraft/network/Connection.java
|
||||
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||||
@@ -153,6 +153,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 96355e1da8feb6687ea0069dda4a82fcd7e25e8a..1f696644b958538e9f5d568a2e4bba69d74a191e 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
|
||||
@@ -138,6 +138,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 35ff3eae4f68fd1fe9bacbeacfd826a5022f8899..744ddef0ee833fc5caebe4036638812383f126f3 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -275,6 +275,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();
|
73
patches/server/0976-More-Chest-Block-API.patch
Normal file
73
patches/server/0976-More-Chest-Block-API.patch
Normal file
|
@ -0,0 +1,73 @@
|
|||
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
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <nassim@njahnke.dev>
|
||||
Date: Thu, 9 May 2024 15:11:34 +0200
|
||||
Subject: [PATCH] Print data component type on encoding error
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/core/component/DataComponentPatch.java b/src/main/java/net/minecraft/core/component/DataComponentPatch.java
|
||||
index 87dd1f570fd294daf826ef7e6403776e42ed4f61..cee4a0639b3c73e300a8450f8a831cb4a71958ba 100644
|
||||
--- a/src/main/java/net/minecraft/core/component/DataComponentPatch.java
|
||||
+++ b/src/main/java/net/minecraft/core/component/DataComponentPatch.java
|
||||
@@ -144,7 +144,13 @@ public final class DataComponentPatch {
|
||||
}
|
||||
|
||||
private static <T> void encodeComponent(RegistryFriendlyByteBuf buf, DataComponentType<T> type, Object value) {
|
||||
+ // Paper start - codec errors of random anonymous classes are useless
|
||||
+ try {
|
||||
type.streamCodec().encode(buf, (T) value); // CraftBukkit - decompile error
|
||||
+ } catch (final Exception e) {
|
||||
+ throw new RuntimeException("Error encoding component " + type, e);
|
||||
+ }
|
||||
+ // Paper end - codec errors of random anonymous classes are useless
|
||||
}
|
||||
};
|
||||
private static final String REMOVED_PREFIX = "!";
|
2831
patches/server/0978-Brigadier-based-command-API.patch
Normal file
2831
patches/server/0978-Brigadier-based-command-API.patch
Normal file
File diff suppressed because it is too large
Load diff
116
patches/server/0979-Fix-issues-with-Recipe-API.patch
Normal file
116
patches/server/0979-Fix-issues-with-Recipe-API.patch
Normal file
|
@ -0,0 +1,116 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 12 May 2024 15:49:36 -0700
|
||||
Subject: [PATCH] Fix issues with Recipe API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
|
||||
index 63cf2b66f51df68aa3f6d98c69368ce454869d64..1bf54b0142fe41b29b21c8b97d3f52bb24a36a92 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
|
||||
@@ -90,7 +90,7 @@ public class ShapedRecipe extends io.papermc.paper.inventory.recipe.RecipeBookEx
|
||||
char c = 'a';
|
||||
for (Ingredient list : this.pattern.ingredients()) {
|
||||
RecipeChoice choice = CraftRecipe.toBukkit(list);
|
||||
- if (choice != null) {
|
||||
+ if (choice != RecipeChoice.empty()) { // Paper
|
||||
recipe.setIngredient(c, choice);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
|
||||
index 6ba29875d78ede4aa7978ff689e588f7fed11528..c76c78bb7757d407102271463e14716a1b012deb 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
|
||||
@@ -29,6 +29,10 @@ public interface CraftRecipe extends Recipe {
|
||||
} else if (bukkit instanceof RecipeChoice.ExactChoice) {
|
||||
stack = new Ingredient(((RecipeChoice.ExactChoice) bukkit).getChoices().stream().map((mat) -> new net.minecraft.world.item.crafting.Ingredient.ItemValue(CraftItemStack.asNMSCopy(mat))));
|
||||
stack.exact = true;
|
||||
+ // Paper start - support "empty" choices
|
||||
+ } else if (bukkit == RecipeChoice.empty()) {
|
||||
+ stack = Ingredient.EMPTY;
|
||||
+ // Paper end
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown recipe stack instance " + bukkit);
|
||||
}
|
||||
@@ -45,7 +49,7 @@ public interface CraftRecipe extends Recipe {
|
||||
list.getItems();
|
||||
|
||||
if (list.itemStacks.length == 0) {
|
||||
- return null;
|
||||
+ return RecipeChoice.empty(); // Paper - null breaks API contracts
|
||||
}
|
||||
|
||||
if (list.exact) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java
|
||||
index 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);
|
114
patches/server/0980-Fix-equipment-slot-and-group-API.patch
Normal file
114
patches/server/0980-Fix-equipment-slot-and-group-API.patch
Normal file
|
@ -0,0 +1,114 @@
|
|||
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 31972619256c09bce46312b55153ddaef11cb236..bcd108cf3a4d10e6bf2058f84c7aa591addd5ced 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
@@ -1405,7 +1405,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());
|
||||
}
|
||||
}
|
||||
@@ -1473,9 +1473,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");
|
||||
+ }
|
||||
+}
|
|
@ -0,0 +1,130 @@
|
|||
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
|
|
@ -0,0 +1,228 @@
|
|||
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 c9aef759c1485da753e820f9b509117ca50a31e4..60757f8df706cba92350d73503b73913cff3bcfc 100644
|
||||
--- a/src/main/java/net/minecraft/core/component/DataComponents.java
|
||||
+++ b/src/main/java/net/minecraft/core/component/DataComponents.java
|
||||
@@ -138,10 +138,10 @@ public class DataComponents {
|
||||
"map_post_processing", builder -> builder.networkSynchronized(MapPostProcessing.STREAM_CODEC)
|
||||
);
|
||||
public static final DataComponentType<ChargedProjectiles> CHARGED_PROJECTILES = register(
|
||||
- "charged_projectiles", builder -> builder.persistent(ChargedProjectiles.CODEC).networkSynchronized(ChargedProjectiles.STREAM_CODEC).cacheEncoding()
|
||||
+ "charged_projectiles", builder -> builder.persistent(ChargedProjectiles.CODEC).networkSynchronized(io.papermc.paper.util.DataSanitizationUtil.CHARGED_PROJECTILES).cacheEncoding() // Paper - sanitize charged projectiles
|
||||
);
|
||||
public static final DataComponentType<BundleContents> BUNDLE_CONTENTS = register(
|
||||
- "bundle_contents", builder -> builder.persistent(BundleContents.CODEC).networkSynchronized(BundleContents.STREAM_CODEC).cacheEncoding()
|
||||
+ "bundle_contents", builder -> builder.persistent(BundleContents.CODEC).networkSynchronized(io.papermc.paper.util.DataSanitizationUtil.BUNDLE_CONTENTS).cacheEncoding() // Paper - sanitize bundle contents
|
||||
);
|
||||
public static final DataComponentType<PotionContents> POTION_CONTENTS = register(
|
||||
"potion_contents", builder -> builder.persistent(PotionContents.CODEC).networkSynchronized(PotionContents.STREAM_CODEC).cacheEncoding()
|
||||
@@ -208,7 +208,7 @@ public class DataComponents {
|
||||
"pot_decorations", builder -> builder.persistent(PotDecorations.CODEC).networkSynchronized(PotDecorations.STREAM_CODEC).cacheEncoding()
|
||||
);
|
||||
public static final DataComponentType<ItemContainerContents> CONTAINER = register(
|
||||
- "container", builder -> builder.persistent(ItemContainerContents.CODEC).networkSynchronized(ItemContainerContents.STREAM_CODEC).cacheEncoding()
|
||||
+ "container", builder -> builder.persistent(ItemContainerContents.CODEC).networkSynchronized(io.papermc.paper.util.DataSanitizationUtil.CONTAINER).cacheEncoding() // Paper - sanitize container contents
|
||||
);
|
||||
public static final DataComponentType<BlockItemStateProperties> BLOCK_STATE = register(
|
||||
"block_state", builder -> builder.persistent(BlockItemStateProperties.CODEC).networkSynchronized(BlockItemStateProperties.STREAM_CODEC).cacheEncoding()
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java
|
||||
index 59c1c103545f04fd35e6932df64a9910a1d74cd7..56bde49e6b7790155b032d0be40961d566ab89e9 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java
|
||||
@@ -19,9 +19,11 @@ public record ClientboundSetEntityDataPacket(int id, List<SynchedEntityData.Data
|
||||
}
|
||||
|
||||
private static void pack(List<SynchedEntityData.DataValue<?>> trackedValues, RegistryFriendlyByteBuf buf) {
|
||||
+ try (var ignored = io.papermc.paper.util.DataSanitizationUtil.start(true)) { // Paper - data sanitization
|
||||
for (SynchedEntityData.DataValue<?> dataValue : trackedValues) {
|
||||
dataValue.write(buf);
|
||||
}
|
||||
+ } // Paper - data sanitization
|
||||
|
||||
buf.writeByte(255);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java
|
||||
index 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 0e7ace92522fbd4cef7b2c2b8a0f8b86c2cce192..1d849ce4e2c85f149af25318b8ffb6dcef6c6788 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -349,7 +349,7 @@ public class ServerEntity {
|
||||
}
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
- sender.accept(new ClientboundSetEquipmentPacket(this.entity.getId(), list));
|
||||
+ sender.accept(new ClientboundSetEquipmentPacket(this.entity.getId(), list, true)); // Paper - data sanitization
|
||||
}
|
||||
((LivingEntity) this.entity).detectEquipmentUpdatesPublic(); // CraftBukkit - SPIGOT-3789: sync again immediately after sending
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index addf6f02980f0089763c8119623dff6c01259950..ea0fc33d12a2147db71347c88df1df6cddc52e84 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -2732,7 +2732,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 81b70e2dcf31ef651256a0ddf928c6370458c3dd..0a9fe513df3afc50baae656bf6a9b2a6122465c1 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3322,7 +3322,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) {
|
|
@ -0,0 +1,24 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 12 May 2024 21:57:23 -0700
|
||||
Subject: [PATCH] Prevent NPE if hooked entity was cleared
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
index 270f4c94912b16c7d4a2d62670847cbb5e011819..6ce65e5b336be9b49db84f1c4755c2e2ce7f8378 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
@@ -504,11 +504,13 @@ public class FishingHook extends Projectile {
|
||||
if (playerFishEvent.isCancelled()) {
|
||||
return 0;
|
||||
}
|
||||
+ if (this.hookedIn != null) { // Paper - re-check to see if there is a hooked entity
|
||||
// CraftBukkit end
|
||||
this.pullEntity(this.hookedIn);
|
||||
CriteriaTriggers.FISHING_ROD_HOOKED.trigger((ServerPlayer) entityhuman, usedItem, this, Collections.emptyList());
|
||||
this.level().broadcastEntityEvent(this, (byte) 31);
|
||||
i = this.hookedIn instanceof ItemEntity ? 3 : 5;
|
||||
+ } // Paper - re-check to see if there is a hooked entity
|
||||
} else if (this.nibble > 0) {
|
||||
LootParams lootparams = (new LootParams.Builder((ServerLevel) this.level())).withParameter(LootContextParams.ORIGIN, this.position()).withParameter(LootContextParams.TOOL, usedItem).withParameter(LootContextParams.THIS_ENTITY, this).withLuck((float) this.luck + entityhuman.getLuck()).create(LootContextParamSets.FISHING);
|
||||
LootTable loottable = this.level().getServer().reloadableRegistries().getLootTable(BuiltInLootTables.FISHING);
|
|
@ -0,0 +1,47 @@
|
|||
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 b800b03ae034b276740c3b41555a52b778ad9aad..86197725f0f2ac1e650297ae7a79907578e0e8f1 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -494,9 +494,11 @@ public final class ItemStack implements DataComponentHolder {
|
||||
world.capturedTileEntities.clear(); // Paper - Allow chests to be placed with NBT data; clear out block entities as chests and such will pop loot
|
||||
// revert back all captured blocks
|
||||
world.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710
|
||||
+ world.isBlockPlaceCancelled = true; // Paper - prevent calling cleanup logic when undoing a block place upon a cancelled BlockPlaceEvent
|
||||
for (BlockState blockstate : blocks) {
|
||||
blockstate.update(true, false);
|
||||
}
|
||||
+ world.isBlockPlaceCancelled = false; // Paper - prevent calling cleanup logic when undoing a block place upon a cancelled BlockPlaceEvent
|
||||
world.preventPoiUpdated = false;
|
||||
|
||||
// Brute force all possible updates
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index dd519eacd6d4bea5447bea471f0ac6540d9bb49c..6f822e9487bef5b9766d5ae86ebbd687e4eadc42 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -151,6 +151,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
public boolean preventPoiUpdated = false; // CraftBukkit - SPIGOT-5710
|
||||
public boolean captureBlockStates = false;
|
||||
public boolean captureTreeGeneration = false;
|
||||
+ public boolean isBlockPlaceCancelled = false; // Paper - prevent calling cleanup logic when undoing a block place upon a cancelled BlockPlaceEvent
|
||||
public Map<BlockPos, org.bukkit.craftbukkit.block.CraftBlockState> capturedBlockStates = new java.util.LinkedHashMap<>(); // Paper
|
||||
public Map<BlockPos, BlockEntity> capturedTileEntities = new java.util.LinkedHashMap<>(); // Paper - Retain block place order when capturing blockstates
|
||||
public List<ItemEntity> captureDrops;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 849efe41ff14be1fc95789b083e340363cbc93ab..f0e88f4613eb22d6685fe010da01daef573f8079 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -444,7 +444,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);
|
26
patches/server/0985-Add-missing-fishing-event-state.patch
Normal file
26
patches/server/0985-Add-missing-fishing-event-state.patch
Normal file
|
@ -0,0 +1,26 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: SoSeDiK <mrsosedik@gmail.com>
|
||||
Date: Wed, 1 May 2024 07:44:50 +0300
|
||||
Subject: [PATCH] Add missing fishing event state
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
index 6ce65e5b336be9b49db84f1c4755c2e2ce7f8378..1223c5d23d0ea6aed068bdf0f5725e2ad49fc82c 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
@@ -411,6 +411,15 @@ public class FishingHook extends Projectile {
|
||||
this.fishAngle = Mth.nextFloat(this.random, this.minLureAngle, this.maxLureAngle);
|
||||
this.timeUntilHooked = Mth.nextInt(this.random, this.minLureTime, this.maxLureTime);
|
||||
// CraftBukkit end
|
||||
+ // Paper start - Add missing fishing event state
|
||||
+ if (this.getPlayerOwner() != null) {
|
||||
+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.getPlayerOwner().getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.LURED);
|
||||
+ if (!playerFishEvent.callEvent()) {
|
||||
+ this.timeUntilHooked = 0;
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Add missing fishing event state
|
||||
}
|
||||
} else {
|
||||
// CraftBukkit start - logic to modify fishing wait time
|
|
@ -0,0 +1,26 @@
|
|||
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 ea0fc33d12a2147db71347c88df1df6cddc52e84..258d0193d23041fb4be0e5b4b1eb31d8a4011331 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -2998,14 +2998,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;
|
|
@ -0,0 +1,21 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Thu, 30 May 2024 18:46:15 +0100
|
||||
Subject: [PATCH] Fix sending disconnect packet in phases where it doesn't
|
||||
exist
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
|
||||
index 4b9da6e2140b14f1e56056f5e9e94b2169d85501..55848fa832d0f4d2d03f99df51e10c5fdfcd2ded 100644
|
||||
--- a/src/main/java/net/minecraft/network/Connection.java
|
||||
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||||
@@ -218,7 +218,8 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
if (player != null) player.quitReason = org.bukkit.event.player.PlayerQuitEvent.QuitReason.ERRONEOUS_STATE; // Paper - Add API for quit reason
|
||||
if (flag) {
|
||||
Connection.LOGGER.debug("Failed to sent packet", throwable);
|
||||
- if (this.getSending() == PacketFlow.CLIENTBOUND) {
|
||||
+ boolean doesDisconnectExist = this.packetListener.protocol() != ConnectionProtocol.STATUS && this.packetListener.protocol() != ConnectionProtocol.HANDSHAKING; // Paper
|
||||
+ if (this.getSending() == PacketFlow.CLIENTBOUND && doesDisconnectExist) { // Paper
|
||||
Packet<?> packet = this.sendLoginDisconnect ? new ClientboundLoginDisconnectPacket(ichatmutablecomponent) : new ClientboundDisconnectPacket(ichatmutablecomponent);
|
||||
|
||||
this.send((Packet) packet, PacketSendListener.thenRun(() -> {
|
134
patches/server/0988-Adopt-MaterialRerouting.patch
Normal file
134
patches/server/0988-Adopt-MaterialRerouting.patch
Normal file
|
@ -0,0 +1,134 @@
|
|||
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