More more more more more more more more more more more patches

This commit is contained in:
Nassim Jahnke 2022-06-08 15:36:56 +02:00
parent beab8a32c1
commit 55d7f562b8
No known key found for this signature in database
GPG key ID: 6BE3B555EBC5982B
45 changed files with 160 additions and 196 deletions

View file

@ -1,40 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: EpicKnarvik97 <kristian.knarvik@knett.no>
Date: Sat, 5 Mar 2022 20:58:46 +0100
Subject: [PATCH] Expose furnace minecart push values
Adds methods for getting and setting a furnace minecart's push values
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java
index 49ceb730b6e68b7c70799fca80dc32da4a12c545..b8378d5f3c2a08ab565dcb8cb200822b581c7dba 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java
@@ -28,6 +28,28 @@ public class CraftMinecartFurnace extends CraftMinecart implements PoweredMineca
this.getHandle().fuel = fuel;
}
+ // Paper start
+ @Override
+ public double getPushX() {
+ return getHandle().xPush;
+ }
+
+ @Override
+ public double getPushZ() {
+ return getHandle().zPush;
+ }
+
+ @Override
+ public void setPushX(double xPush) {
+ getHandle().xPush = xPush;
+ }
+
+ @Override
+ public void setPushZ(double zPush) {
+ getHandle().zPush = zPush;
+ }
+ // Paper end
+
@Override
public String toString() {
return "CraftMinecartFurnace";

View file

@ -1,37 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sat, 19 Feb 2022 19:05:59 -0800
Subject: [PATCH] Fix cancelling ProjectileHitEvent for piercing arrows
Piercing arrows search for multiple entities inside a while
loop that is checking the projectile entity's removed state.
If the hit event is cancelled on the first entity, the event will
be called over and over again inside that while loop until the event
is not cancelled. The solution here, is to make use of an
already-existing field on AbstractArrow for tracking entities hit by
piercing arrows to avoid duplicate damage being applied.
diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
index 3d3dcb47720055f550d17d1f106a2c0e59de2919..53d0024daf6963ac4dab575666b0d6a74a39a958 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
@@ -299,6 +299,19 @@ public abstract class AbstractArrow extends Projectile {
}
}
+ // Paper start
+ @Override
+ protected void preOnHit(HitResult hitResult) {
+ super.preOnHit(hitResult);
+ if (hitResult instanceof EntityHitResult entityHitResult && this.hitCancelled && this.getPierceLevel() > 0) {
+ if (this.piercingIgnoreEntityIds == null) {
+ this.piercingIgnoreEntityIds = new IntOpenHashSet(5);
+ }
+ this.piercingIgnoreEntityIds.add(entityHitResult.getEntity().getId());
+ }
+ }
+ // Paper end
+
private boolean shouldFall() {
return this.inGround && this.level.noCollision((new AABB(this.position(), this.position())).inflate(0.06D));
}

View file

@ -1,74 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sat, 5 Mar 2022 17:12:52 -0800
Subject: [PATCH] Fix save problems on shutdown
- Save level.dat first, in case the shutdown is killed later
- Force run minecraftserver tasks and the chunk source tasks
while waiting for the chunk system to empty, as there's simply
too much trash that could prevent them from executing during
the chunk source tick (i.e "time left in tick" logic).
- Set forceTicks to true, so that player packets are always
processed so that the main process queue can be drained
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 583d2deffa819c1aa25e1937a7f709d0d6bab294..c8d56947305c981a3268ce4ae3e975db350ceff2 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -996,6 +996,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
}
+ // Paper start - let's be a little more intelligent around crashes
+ // make sure level.dat saves
+ for (ServerLevel level : this.getAllLevels()) {
+ level.saveLevelDat();
+ }
+ // Paper end - let's be a little more intelligent around crashes
+
while (this.levels.values().stream().anyMatch((worldserver1) -> {
return worldserver1.getChunkSource().chunkMap.hasWork();
})) {
@@ -1008,9 +1015,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
worldserver.getChunkSource().tick(() -> {
return true;
}, false);
+ while (worldserver.getChunkSource().pollTask()); // Paper - drain tasks
}
- this.waitUntilNextTick();
+ this.forceTicks = true; // Paper
+ while (this.pollTask()); // Paper - drain tasks
}
this.saveAllChunks(false, true, false);
@@ -1306,6 +1315,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
private boolean haveTime() {
+ // Paper start
+ if (this.forceTicks) {
+ return true;
+ }
+ // Paper end
// CraftBukkit start
if (isOversleep) return canOversleep();// Paper - because of our changes, this logic is broken
return this.forceTicks || this.runningTask() || Util.getMillis() < (this.mayHaveDelayedTasks ? this.delayedTasksMaxNextTickTime : this.nextTickTime);
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 00e6f60e13f50c727530de37ab9692ad3683c11b..50fd3419deb668dda64b1056f03fb66da55e6960 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1258,7 +1258,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
}
+ // Paper start
+ this.saveLevelDat();
+ }
+ public void saveLevelDat() {
+ this.saveLevelData();
+ // Paper end
// CraftBukkit start - moved from MinecraftServer.saveChunks
ServerLevel worldserver1 = this;

View file

@ -1,192 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Tue, 22 Jun 2021 23:41:11 -0400
Subject: [PATCH] More Projectile API
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
index be86114eac3975b82ca74d4d6ed3f0402a642e8a..93fd9e87de3078f50431b5d80540d4335d7c79e5 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
@@ -14,24 +14,26 @@ import org.bukkit.inventory.meta.FireworkMeta;
public class CraftFirework extends CraftProjectile implements Firework {
private final Random random = new Random();
- private final CraftItemStack item;
+ //private CraftItemStack item; // Paper - Remove usage, not accurate representation of current item.
public CraftFirework(CraftServer server, FireworkRocketEntity entity) {
super(server, entity);
- ItemStack item = this.getHandle().getEntityData().get(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM);
-
- if (item.isEmpty()) {
- item = new ItemStack(Items.FIREWORK_ROCKET);
- this.getHandle().getEntityData().set(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM, item);
- }
-
- this.item = CraftItemStack.asCraftMirror(item);
-
- // Ensure the item is a firework...
- if (this.item.getType() != Material.FIREWORK_ROCKET) {
- this.item.setType(Material.FIREWORK_ROCKET);
- }
+// Paper Start - Expose firework item directly
+// ItemStack item = this.getHandle().getEntityData().get(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM);
+//
+// if (item.isEmpty()) {
+// item = new ItemStack(Items.FIREWORK_ROCKET);
+// this.getHandle().getEntityData().set(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM, item);
+// }
+//
+// this.item = CraftItemStack.asCraftMirror(item);
+//
+// // Ensure the item is a firework...
+// if (this.item.getType() != Material.FIREWORK_ROCKET) {
+// this.item.setType(Material.FIREWORK_ROCKET);
+// }
+ // Paper End - Expose firework item directly
}
@Override
@@ -51,12 +53,12 @@ public class CraftFirework extends CraftProjectile implements Firework {
@Override
public FireworkMeta getFireworkMeta() {
- return (FireworkMeta) this.item.getItemMeta();
+ return (FireworkMeta) CraftItemStack.getItemMeta(this.getHandle().getEntityData().get(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM), Material.FIREWORK_ROCKET); // Paper - Expose firework item directly
}
@Override
public void setFireworkMeta(FireworkMeta meta) {
- this.item.setItemMeta(meta);
+ applyFireworkEffect(meta); // Paper - Expose firework item directly
// Copied from EntityFireworks constructor, update firework lifetime/power
this.getHandle().lifetime = 10 * (1 + meta.getPower()) + this.random.nextInt(6) + this.random.nextInt(7);
@@ -91,4 +93,46 @@ public class CraftFirework extends CraftProjectile implements Firework {
return boostedEntity != null ? (org.bukkit.entity.LivingEntity) boostedEntity.getBukkitEntity() : null;
}
// Paper end
+ // Paper start - Expose firework item directly + manually setting flight
+ @Override
+ public org.bukkit.inventory.ItemStack getItem() {
+ return CraftItemStack.asBukkitCopy(this.getHandle().getItem());
+ }
+
+ @Override
+ public void setItem(org.bukkit.inventory.ItemStack itemStack) {
+ FireworkMeta meta = getFireworkMeta();
+ ItemStack nmsItem = itemStack == null ? ItemStack.EMPTY : CraftItemStack.asNMSCopy(itemStack);
+ this.getHandle().getEntityData().set(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM, nmsItem);
+
+ applyFireworkEffect(meta);
+ }
+
+ @Override
+ public int getTicksFlown() {
+ return this.getHandle().life;
+ }
+
+ @Override
+ public void setTicksFlown(int ticks) {
+ this.getHandle().life = ticks;
+ }
+
+ @Override
+ public int getTicksToDetonate() {
+ return this.getHandle().lifetime;
+ }
+
+ @Override
+ public void setTicksToDetonate(int ticks) {
+ this.getHandle().lifetime = ticks;
+ }
+
+ void applyFireworkEffect(FireworkMeta meta) {
+ ItemStack item = this.getHandle().getItem();
+ CraftItemStack.applyMetaToItem(item, meta);
+
+ this.getHandle().getEntityData().set(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM, item);
+ }
+ // Paper end - Expose firework item directly + manually setting flight
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java
index 6bfa984781a483d048ef4318761203c701d8a632..5e0c2c5094e1578162d1a50d50701fbd25e6d961 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java
@@ -119,4 +119,15 @@ public class CraftFishHook extends CraftProjectile implements FishHook {
public HookState getState() {
return HookState.values()[this.getHandle().currentState.ordinal()];
}
+ // Paper start - More FishHook API
+ @Override
+ public int getWaitTime() {
+ return this.getHandle().timeUntilLured;
+ }
+
+ @Override
+ public void setWaitTime(int ticks) {
+ this.getHandle().timeUntilLured = ticks;
+ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java
index b08739dd1ffd041f0885af6c1f57dca9027763b6..c1594f62c06a49ba2d0c2c6e6befcda7d1fe6e1b 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java
@@ -39,11 +39,26 @@ public class CraftThrownPotion extends CraftProjectile implements ThrownPotion {
Validate.notNull(item, "ItemStack cannot be null.");
// The ItemStack must be a potion.
- Validate.isTrue(item.getType() == Material.LINGERING_POTION || item.getType() == Material.SPLASH_POTION, "ItemStack must be a lingering or splash potion. This item stack was " + item.getType() + ".");
+ //Validate.isTrue(item.getType() == Material.LINGERING_POTION || item.getType() == Material.SPLASH_POTION, "ItemStack must be a lingering or splash potion. This item stack was " + item.getType() + "."); // Paper - Projectile API
+ org.bukkit.inventory.meta.PotionMeta meta = (item.getType() == Material.LINGERING_POTION || item.getType() == Material.SPLASH_POTION) ? null : this.getPotionMeta(); // Paper - Projectile API
this.getHandle().setItem(CraftItemStack.asNMSCopy(item));
+ if (meta != null) this.setPotionMeta(meta); // Paper - Projectile API
}
+ // Paper start - Projectile API
+ @Override
+ public org.bukkit.inventory.meta.PotionMeta getPotionMeta() {
+ return (org.bukkit.inventory.meta.PotionMeta) CraftItemStack.getItemMeta(this.getHandle().getItemRaw(), Material.SPLASH_POTION);
+ }
+
+ @Override
+ public void setPotionMeta(org.bukkit.inventory.meta.PotionMeta meta) {
+ net.minecraft.world.item.ItemStack item = this.getHandle().getItem();
+ CraftItemStack.applyMetaToItem(item, meta);
+ this.getHandle().setItem(item); // Reset item
+ }
+ // Paper end
@Override
public net.minecraft.world.entity.projectile.ThrownPotion getHandle() {
return (net.minecraft.world.entity.projectile.ThrownPotion) entity;
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
index 14da2997b5fff4434b1fe8d5a1b3109dde143740..226d9ac01c601fc8954a88bea93a521cdce79eda 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
@@ -274,12 +274,20 @@ public final class CraftItemStack extends ItemStack {
public ItemMeta getItemMeta() {
return CraftItemStack.getItemMeta(this.handle);
}
+ // Paper start
+ public static void applyMetaToItem(net.minecraft.world.item.ItemStack itemStack, ItemMeta meta) {
+ ((org.bukkit.craftbukkit.inventory.CraftMetaItem) meta).applyToItem(itemStack.getOrCreateTag());
+ }
public static ItemMeta getItemMeta(net.minecraft.world.item.ItemStack item) {
+ return getItemMeta(item, CraftItemStack.getType(item));
+ }
+ public static ItemMeta getItemMeta(net.minecraft.world.item.ItemStack item, Material material) {
+ // Paper end
if (!CraftItemStack.hasItemMeta(item)) {
- return CraftItemFactory.instance().getItemMeta(CraftItemStack.getType(item));
+ return CraftItemFactory.instance().getItemMeta(material); // Paper
}
- switch (CraftItemStack.getType(item)) {
+ switch (material) { // Paper
case WRITTEN_BOOK:
return new CraftMetaBookSigned(item.getTag());
case WRITABLE_BOOK:

View file

@ -1,56 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sat, 12 Mar 2022 06:31:13 -0800
Subject: [PATCH] Fix swamp hut cat generation deadlock
The worldgen thread will attempt to get structure references
via the world's getChunkAt method, which is fine if the gen is
not cancelled - but if the chunk was unloaded, the call will block
indefinitely. Instead of using the world state, we use the already
supplied generatoraccess which will always have the chunk available.
diff --git a/src/main/java/net/minecraft/world/entity/animal/Cat.java b/src/main/java/net/minecraft/world/entity/animal/Cat.java
index 5f7c394f9cc178c9cb06c90b91296b979d61239b..e4eac546836b73b5e9c8fd68ca0d32c01148313e 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Cat.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Cat.java
@@ -392,7 +392,7 @@ public class Cat extends TamableAnimal {
Registry<ConfiguredStructureFeature<?, ?>> iregistry = worldserver1.registryAccess().registryOrThrow(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY);
if (ChunkGenerator.allConfigurations(iregistry, StructureFeature.SWAMP_HUT).anyMatch((structurefeature) -> {
- return worldserver1.structureFeatureManager().getStructureWithPieceAt(this.blockPosition(), structurefeature).isValid();
+ return worldserver1.structureFeatureManager().getStructureWithPieceAt(this.blockPosition(), structurefeature, world).isValid(); // Paper - fix deadlock
})) {
this.setCatType(10);
this.setPersistenceRequired();
diff --git a/src/main/java/net/minecraft/world/level/StructureFeatureManager.java b/src/main/java/net/minecraft/world/level/StructureFeatureManager.java
index 2825975e5b33ea13f199008c7a4abc72ebf990b3..56c4f849d92b38537602fd77e481ee60a25bc84b 100644
--- a/src/main/java/net/minecraft/world/level/StructureFeatureManager.java
+++ b/src/main/java/net/minecraft/world/level/StructureFeatureManager.java
@@ -56,7 +56,12 @@ public class StructureFeatureManager {
}
public List<StructureStart> startsForFeature(SectionPos sectionPos, ConfiguredStructureFeature<?, ?> configuredStructureFeature) {
- LongSet longSet = this.level.getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES).getReferencesForFeature(configuredStructureFeature);
+ // Paper start - add world option
+ return this.startsForFeature(sectionPos, configuredStructureFeature, (ServerLevelAccessor)null);
+ }
+ public List<StructureStart> startsForFeature(SectionPos sectionPos, ConfiguredStructureFeature<?, ?> configuredStructureFeature, ServerLevelAccessor world) {
+ LongSet longSet = (world == null ? this.level : world).getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES).getReferencesForFeature(configuredStructureFeature);
+ // Paper end - add world option
ImmutableList.Builder<StructureStart> builder = ImmutableList.builder();
this.fillStartsForFeature(configuredStructureFeature, longSet, builder::add);
return builder.build();
@@ -106,7 +111,12 @@ public class StructureFeatureManager {
}
public StructureStart getStructureWithPieceAt(BlockPos pos, ConfiguredStructureFeature<?, ?> configuredStructureFeature) {
- for(StructureStart structureStart : this.startsForFeature(SectionPos.of(pos), configuredStructureFeature)) {
+ // Paper start - add world option
+ return this.getStructureWithPieceAt(pos, configuredStructureFeature, (ServerLevelAccessor)null);
+ }
+ public StructureStart getStructureWithPieceAt(BlockPos pos, ConfiguredStructureFeature<?, ?> configuredStructureFeature, ServerLevelAccessor world) {
+ // Paper end - add world option
+ for(StructureStart structureStart : this.startsForFeature(SectionPos.of(pos), configuredStructureFeature, world)) { // Paper - add world option
if (this.structureHasPieceAt(pos, structureStart)) {
return structureStart;
}

View file

@ -1,25 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 14 Mar 2022 12:35:37 -0700
Subject: [PATCH] Don't allow vehicle movement from players while teleporting
Bring the vehicle move packet behavior in line with the
regular player move packet.
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index b42d4224d7f5c5de7e9fa8d6278af10f84d81245..3bfd0fc8e2d068657183e4ebd4f632c94c3908b2 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -517,6 +517,12 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
} else {
Entity entity = this.player.getRootVehicle();
+ // Paper start
+ if (this.awaitingPositionFromClient != null || this.player.isImmobile() || entity.isRemoved()) {
+ return;
+ }
+ // Paper end
+
if (entity != this.player && entity.getControllingPassenger() == this.player && entity == this.lastVehicle) {
ServerLevel worldserver = this.player.getLevel();
double d0 = entity.getX();final double fromX = d0; // Paper - OBFHELPER

View file

@ -1,61 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Mon, 14 Mar 2022 22:46:05 -0700
Subject: [PATCH] Implement getComputedBiome API
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
index 6e827ed6212915b187e4c610acf6c34037c9c994..81a2a4f9ca0cb94cfd0680f57be4157dfb2fff57 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
@@ -204,6 +204,13 @@ public abstract class CraftRegionAccessor implements RegionAccessor {
return CraftBlock.biomeBaseToBiome(this.getHandle().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), this.getHandle().getNoiseBiome(x >> 2, y >> 2, z >> 2));
}
+ // Paper start
+ @Override
+ public Biome getComputedBiome(int x, int y, int z) {
+ return CraftBlock.biomeBaseToBiome(this.getHandle().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), this.getHandle().getBiome(new BlockPos(x, y, z)));
+ }
+ // Paper end
+
@Override
public void setBiome(Location location, Biome biome) {
this.setBiome(location.getBlockX(), location.getBlockY(), location.getBlockZ(), biome);
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 0030ac394d44acddcd2fc716277ae2b509a378af..22356c2380741dd811810420127e247e46b0b8e2 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -341,6 +341,13 @@ public class CraftBlock implements Block {
return this.getWorld().getBiome(this.getX(), this.getY(), this.getZ());
}
+ // Paper start
+ @Override
+ public Biome getComputedBiome() {
+ return this.getWorld().getComputedBiome(this.getX(), this.getY(), this.getZ());
+ }
+ // Paper end
+
@Override
public void setBiome(Biome bio) {
this.getWorld().setBiome(this.getX(), this.getY(), this.getZ(), bio);
diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java
index 392701b0022e05d0fd03ee5836fd18f00502f028..b01904021bd4f485aaf03d1d7634b56f134d3099 100644
--- a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java
+++ b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java
@@ -166,6 +166,14 @@ public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRe
return super.getBiome(x, y, z);
}
+ // Paper start
+ @Override
+ public Biome getComputedBiome(int x, int y, int z) {
+ Preconditions.checkArgument(this.isInRegion(x, y, z), "Coordinates %s, %s, %s are not in the region", x, y, z);
+ return super.getComputedBiome(x, y, z);
+ }
+ // Paper end
+
@Override
public void setBiome(int x, int y, int z, Holder<net.minecraft.world.level.biome.Biome> biomeBase) {
Preconditions.checkArgument(this.isInRegion(x, y, z), "Coordinates %s, %s, %s are not in the region", x, y, z);

View file

@ -1,28 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Tue, 15 Mar 2022 01:38:15 -0700
Subject: [PATCH] Make some itemstacks nonnull
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java
index d6a228473ca6f425757683a4b17b035a53ab117f..8801d3f7ff6d2ff810f3e34a821dfb659c03f844 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java
@@ -156,13 +156,13 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i
case OFF_HAND:
return this.getItemInOffHand();
case FEET:
- return this.getBoots();
+ return java.util.Objects.requireNonNullElseGet(this.getBoots(), () -> new ItemStack(org.bukkit.Material.AIR)); // Paper - make nonnull
case LEGS:
- return this.getLeggings();
+ return java.util.Objects.requireNonNullElseGet(this.getLeggings(), () -> new ItemStack(org.bukkit.Material.AIR)); // Paper - make nonnull
case CHEST:
- return this.getChestplate();
+ return java.util.Objects.requireNonNullElseGet(this.getChestplate(), () -> new ItemStack(org.bukkit.Material.AIR)); // Paper - make nonnull
case HEAD:
- return this.getHelmet();
+ return java.util.Objects.requireNonNullElseGet(this.getHelmet(), () -> new ItemStack(org.bukkit.Material.AIR)); // Paper - make nonnull
default:
throw new IllegalArgumentException("Not implemented. This is a bug");
}

View file

@ -1,63 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Sat, 26 Feb 2022 13:27:31 -0700
Subject: [PATCH] Add debug for invalid GameProfiles on skull blocks/items
Improves the error message for placed in world skull blocks by default,
also adds 'Paper.debugInvalidSkullProfiles' system property which can be
set to 'true' for extra debug info (trace of updateGameprofile caller).
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
index 118472b83a21a250f398c088c91ac4560c19c749..5840cf6d22029cf1599ae9460b4498d5c8c5ae7d 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
@@ -142,13 +142,28 @@ public class SkullBlockEntity extends BlockEntity {
updateGameprofile(this.owner, (owner) -> {
this.owner = owner;
this.setChanged();
+ // Paper start
+ }, () -> {
+ final @Nullable Level level = this.getLevel();
+ return "SkullBlockEntity at " + this.getBlockPos() + (level == null ? "" : (" in level: " + level.dimension().location()));
+ // Paper end
});
}
public static void updateGameprofile(@Nullable GameProfile owner, Consumer<GameProfile> callback) {
+ // Paper start
+ updateGameprofile(owner, callback, null);
+ }
+
+ private static final boolean DEBUG_INVALID_SKULL_PROFILES = Boolean.getBoolean("Paper.debugInvalidSkullProfiles");
+
+ public static void updateGameprofile(@Nullable GameProfile owner, Consumer<GameProfile> callback, final @Nullable java.util.function.Supplier<String> debugInfo) {
if (owner != null && !StringUtil.isNullOrEmpty(owner.getName()) && (!owner.isComplete() || !owner.getProperties().containsKey("textures")) && profileCache != null && sessionService != null) {
+ final @Nullable Throwable trace = DEBUG_INVALID_SKULL_PROFILES ? new Throwable("updateGameprofile caller debug trace") : null;
profileCache.getAsync(owner.getName(), (profile) -> {
Util.PROFILE_EXECUTOR.execute(() -> { // Paper - not a good idea to use BLOCKING OPERATIONS on the worldgen executor
+ try {
+ // Paper end
Util.ifElse(profile, (profilex) -> {
Property property = Iterables.getFirst(profilex.getProperties().get("textures"), (Property)null);
if (property == null) {
@@ -165,6 +180,20 @@ public class SkullBlockEntity extends BlockEntity {
callback.accept(owner);
});
});
+ // Paper start
+ } catch (final Exception ex) {
+ if (trace != null) {
+ ex.addSuppressed(trace);
+ }
+ final String ownerMessage = "Original profile: '" + owner + "'";
+ final String debugMessage = " Run with -DPaper.debugInvalidSkullProfiles=true for further debug information.";
+ final String message = ownerMessage + (trace == null ? debugMessage : "");
+ if (debugInfo == null) {
+ throw new RuntimeException(message, ex);
+ }
+ throw new RuntimeException(debugInfo.get() + " " + message, ex);
+ }
+ // Paper end
});
});
} else {

View file

@ -1,32 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Wed, 16 Mar 2022 20:35:21 -0700
Subject: [PATCH] Implement enchantWithLevels API
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
index 697d6d8387d1451ac3158d35bbaa00229dcfcbc6..d5daabdcd5b5f50d1ada52b420517a901aa8fa41 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
@@ -370,6 +370,21 @@ public final class CraftItemFactory implements ItemFactory {
}
// Paper start
+ @Override
+ public ItemStack enchantWithLevels(ItemStack itemStack, int levels, boolean allowTreasure, java.util.Random random) {
+ Validate.notNull(itemStack, "Argument 'itemStack' must not be null");
+ Validate.isTrue(itemStack.getType() != Material.AIR, "Argument 'itemStack' must not be of type AIR");
+ Validate.isTrue(itemStack.getAmount() > 0, "Argument 'itemStack' amount must be greater than 0");
+ Validate.isTrue(levels > 0 && levels <= 30, "Argument 'levels' must be in range [1, 30] (attempted " + levels + ")");
+ Validate.notNull(random, "Argument 'random' must not be null");
+ final net.minecraft.world.item.ItemStack internalStack = CraftItemStack.asNMSCopy(itemStack);
+ if (internalStack.tag != null) {
+ internalStack.tag.remove(net.minecraft.world.item.ItemStack.TAG_ENCH);
+ }
+ final net.minecraft.world.item.ItemStack enchanted = net.minecraft.world.item.enchantment.EnchantmentHelper.enchantItem(random, internalStack, levels, allowTreasure);
+ return CraftItemStack.asCraftMirror(enchanted);
+ }
+
@Override
public net.kyori.adventure.text.event.HoverEvent<net.kyori.adventure.text.event.HoverEvent.ShowItem> asHoverEvent(final ItemStack item, final java.util.function.UnaryOperator<net.kyori.adventure.text.event.HoverEvent.ShowItem> op) {
final net.minecraft.nbt.CompoundTag tag = CraftItemStack.asNMSCopy(item).getTag();

View file

@ -1,20 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Philip Kelley <philip@thoriumcube.org>
Date: Wed, 16 Mar 2022 12:05:59 +0000
Subject: [PATCH] Fix saving in unloadWorld
Change savingDisabled to false to ensure ServerLevel's saving logic gets called when unloadWorld is called with save = true
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 6333688c49b8c9dd2476634ad3968b468b3d5147..12c1728084d5f1af2a0c242b271939198c7fbea5 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1303,7 +1303,7 @@ public final class CraftServer implements Server {
try {
if (save) {
- handle.save(null, true, true);
+ handle.save(null, true, false); // Paper - don't disable saving
}
handle.getChunkSource().close(save);

View file

@ -1,42 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
Date: Sat, 19 Mar 2022 12:12:22 +0000
Subject: [PATCH] Buffer OOB setBlock calls
lets debug mode throw a trace in order to potentially see where
such calls are cascading from easier, but, generally, if you see one setBlock
call, you're gonna see more, and this just potentially causes a flood of logs
which can cause issues for slower terminals, etc.
We can limit the flood by just allowing one for a single gen region,
we'll also only gen a trace for the first one, I see no real pressing need
to generate more, given that that would *massively* negate this patch otherwise
diff --git a/src/main/java/net/minecraft/server/level/WorldGenRegion.java b/src/main/java/net/minecraft/server/level/WorldGenRegion.java
index a24f605bd033f249a374e83ba094880106260eee..1e656438d9ee89b97c660f3b3ec671be6546c6b7 100644
--- a/src/main/java/net/minecraft/server/level/WorldGenRegion.java
+++ b/src/main/java/net/minecraft/server/level/WorldGenRegion.java
@@ -266,6 +266,7 @@ public class WorldGenRegion implements WorldGenLevel {
}
}
+ private boolean hasSetFarWarned = false; // Paper
@Override
public boolean ensureCanWrite(BlockPos pos) {
int i = SectionPos.blockToSectionCoord(pos.getX());
@@ -285,7 +286,15 @@ public class WorldGenRegion implements WorldGenLevel {
return true;
} else {
+ // Paper start
+ if (!hasSetFarWarned) {
Util.logAndPauseIfInIde("Detected setBlock in a far chunk [" + i + ", " + j + "], pos: " + pos + ", status: " + this.generatingStatus + (this.currentlyGenerating == null ? "" : ", currently generating: " + (String) this.currentlyGenerating.get()));
+ hasSetFarWarned = true;
+ if (this.getServer() != null && this.getServer().isDebugging()) {
+ io.papermc.paper.util.TraceUtil.dumpTraceForThread("far setBlock call");
+ }
+ }
+ // Paper end
return false;
}
}

View file

@ -1,23 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Mon, 21 Jun 2021 21:24:45 -0400
Subject: [PATCH] Add TameableDeathMessageEvent
diff --git a/src/main/java/net/minecraft/world/entity/TamableAnimal.java b/src/main/java/net/minecraft/world/entity/TamableAnimal.java
index 7e67c47434d1f29cc87f3af926f3efc920c87829..de95bfd6e5a97257cb4915ce0a7a704784f110df 100644
--- a/src/main/java/net/minecraft/world/entity/TamableAnimal.java
+++ b/src/main/java/net/minecraft/world/entity/TamableAnimal.java
@@ -209,7 +209,11 @@ public abstract class TamableAnimal extends Animal implements OwnableEntity {
@Override
public void die(DamageSource source) {
if (!this.level.isClientSide && this.level.getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES) && this.getOwner() instanceof ServerPlayer) {
- this.getOwner().sendMessage(this.getCombatTracker().getDeathMessage(), Util.NIL_UUID);
+ // Paper start - TameableDeathMessageEvent
+ io.papermc.paper.event.entity.TameableDeathMessageEvent event = new io.papermc.paper.event.entity.TameableDeathMessageEvent((org.bukkit.entity.Tameable) getBukkitEntity(), io.papermc.paper.adventure.PaperAdventure.asAdventure(this.getCombatTracker().getDeathMessage()));
+ if (event.callEvent()) {
+ this.getOwner().sendMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.deathMessage()), Util.NIL_UUID);
+ } // Paper end - TameableDeathMessageEvent
}
super.die(source);

View file

@ -1,20 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: SoSeDiK <mrsosedik@gmail.com>
Date: Mon, 21 Mar 2022 20:00:53 +0200
Subject: [PATCH] Fix new block data for EntityChangeBlockEvent when sheep eats
grass block
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java
index 14ed3f0524773e22a792efb8b41a9217bad50f27..99044ebe2c37ce951566e3463ddbfaeec46d2b3c 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java
@@ -81,7 +81,7 @@ public class EatBlockGoal extends Goal {
if (this.level.getBlockState(blockposition1).is(Blocks.GRASS_BLOCK)) {
// CraftBukkit
- if (!CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition1, Blocks.AIR.defaultBlockState(), !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)).isCancelled()) {
+ if (!CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition1, Blocks.DIRT.defaultBlockState(), !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)).isCancelled()) { // Paper - Fix wrong block state
this.level.levelEvent(2001, blockposition1, Block.getId(Blocks.GRASS_BLOCK.defaultBlockState()));
this.level.setBlock(blockposition1, Blocks.DIRT.defaultBlockState(), 2);
}

View file

@ -1,25 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Tue, 22 Mar 2022 09:50:40 -0700
Subject: [PATCH] fix player loottables running when mob loot gamerule is false
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 5e10a22c19ca1d5208dcfbe93436f5fdc3172c69..a6edf5117d4ae03d8294e7bb74dd2d77048895a5 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -851,12 +851,14 @@ public class ServerPlayer extends Player {
}
}
}
+ if (this.shouldDropLoot() && this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Paper - preserve this check from vanilla
// SPIGOT-5071: manually add player loot tables (SPIGOT-5195 - ignores keepInventory rule)
this.dropFromLootTable(source, this.lastHurtByPlayerTime > 0);
for (org.bukkit.inventory.ItemStack item : this.drops) {
loot.add(item);
}
this.drops.clear(); // SPIGOT-5188: make sure to clear
+ } // Paper
Component defaultMessage = this.getCombatTracker().getDeathMessage();

View file

@ -1,24 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Thu, 31 Mar 2022 05:11:37 -0700
Subject: [PATCH] Ensure entity passenger world matches ridden entity
Bad plugins doing this would cause some obvious problems...
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index ede2f5f00b59893cca354e5626938360347b0a36..2e5cf8575e7a30d2199c77e70d82732b74ae70a7 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -2584,6 +2584,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
}
protected boolean addPassenger(Entity entity) { // CraftBukkit
+ // Paper start
+ if (entity.level != this.level) {
+ LOGGER.error("Entity passenger world must match, cannot add " + entity + " as passenger to " + this, new Throwable());
+ return false;
+ }
+ // Paper end
if (entity == this) throw new IllegalArgumentException("Entities cannot become a passenger of themselves"); // Paper - issue 572
if (entity.getVehicle() != this) {
throw new IllegalStateException("Use x.startRiding(y), not y.addPassenger(x)");

View file

@ -1,45 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Thu, 31 Mar 2022 05:18:28 -0700
Subject: [PATCH] Guard against invalid entity positions
Anything not finite should be blocked and logged
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 2e5cf8575e7a30d2199c77e70d82732b74ae70a7..86a2eddf344503cbe75a5243a114f6fe1578185f 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -4085,11 +4085,33 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
return this.getZ((2.0D * this.random.nextDouble() - 1.0D) * widthScale);
}
+ // Paper start - block invalid positions
+ public static boolean checkPosition(Entity entity, double newX, double newY, double newZ) {
+ if (Double.isFinite(newX) && Double.isFinite(newY) && Double.isFinite(newZ)) {
+ return true;
+ }
+
+ String entityInfo = null;
+ try {
+ entityInfo = entity.toString();
+ } catch (Exception ex) {
+ entityInfo = "[Entity info unavailable] ";
+ }
+ LOGGER.error("New entity position is invalid! Tried to set invalid position (" + newX + "," + newY + "," + newZ + ") for entity " + entity.getClass().getName() + " located at " + entity.position + ", entity info: " + entityInfo, new Throwable());
+ return false;
+ }
+ // Paper end - block invalid positions
+
public final void setPosRaw(double x, double y, double z) {
// Paper start
this.setPosRaw(x, y, z, false);
}
public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) {
+ // Paper start - block invalid positions
+ if (!checkPosition(this, x, y, z)) {
+ return;
+ }
+ // Paper end - block invalid positions
// Paper end
// Paper start - fix MC-4
if (this instanceof ItemEntity) {

View file

@ -1,57 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sun, 20 Mar 2022 22:06:47 -0700
Subject: [PATCH] cache resource keys
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 22356c2380741dd811810420127e247e46b0b8e2..bfe9dc935c87e01fb435d8b46ce413b84ca74856 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -366,12 +366,13 @@ public class CraftBlock implements Block {
return (biome == null) ? Biome.CUSTOM : biome;
}
+ private static final java.util.Map<org.bukkit.block.Biome, net.minecraft.resources.ResourceKey<net.minecraft.world.level.biome.Biome>> BIOME_KEY_CACHE = Collections.synchronizedMap(new java.util.EnumMap<>(Biome.class)); // Paper
public static Holder<net.minecraft.world.level.biome.Biome> biomeToBiomeBase(net.minecraft.core.Registry<net.minecraft.world.level.biome.Biome> registry, Biome bio) {
if (bio == null || bio == Biome.CUSTOM) {
return null;
}
- return registry.getHolderOrThrow(ResourceKey.create(net.minecraft.core.Registry.BIOME_REGISTRY, CraftNamespacedKey.toMinecraft(bio.getKey())));
+ return registry.getHolderOrThrow(BIOME_KEY_CACHE.computeIfAbsent(bio, b -> ResourceKey.create(net.minecraft.core.Registry.BIOME_REGISTRY, CraftNamespacedKey.toMinecraft(b.getKey())))); // Paper - cache key
}
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/tag/CraftEntityTag.java b/src/main/java/org/bukkit/craftbukkit/tag/CraftEntityTag.java
index 393bb27648501c6f25cf846e929f4c95b1a0b11f..979f82d589e378b9e52417d20b48d66f077f5dfd 100644
--- a/src/main/java/org/bukkit/craftbukkit/tag/CraftEntityTag.java
+++ b/src/main/java/org/bukkit/craftbukkit/tag/CraftEntityTag.java
@@ -16,9 +16,10 @@ public class CraftEntityTag extends CraftTag<net.minecraft.world.entity.EntityTy
super(registry, tag);
}
+ private static final java.util.Map<org.bukkit.entity.EntityType, net.minecraft.resources.ResourceKey<net.minecraft.world.entity.EntityType<?>>> KEY_CACHE = Collections.synchronizedMap(new java.util.EnumMap<>(EntityType.class)); // Paper
@Override
public boolean isTagged(EntityType entity) {
- return registry.getHolderOrThrow(ResourceKey.create(net.minecraft.core.Registry.ENTITY_TYPE_REGISTRY, CraftNamespacedKey.toMinecraft(entity.getKey()))).is(tag);
+ return registry.getHolderOrThrow(KEY_CACHE.computeIfAbsent(entity, type -> ResourceKey.create(net.minecraft.core.Registry.ENTITY_TYPE_REGISTRY, CraftNamespacedKey.toMinecraft(type.getKey())))).is(tag); // Paper - cache key
}
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/tag/CraftFluidTag.java b/src/main/java/org/bukkit/craftbukkit/tag/CraftFluidTag.java
index cdd474e9b0363641839a66d3e61fec46c735879a..3611e3e9d33a0f1d82a78a27ea5c2c649225f564 100644
--- a/src/main/java/org/bukkit/craftbukkit/tag/CraftFluidTag.java
+++ b/src/main/java/org/bukkit/craftbukkit/tag/CraftFluidTag.java
@@ -14,9 +14,10 @@ public class CraftFluidTag extends CraftTag<net.minecraft.world.level.material.F
super(registry, tag);
}
+ private static final java.util.Map<Fluid, net.minecraft.resources.ResourceKey<net.minecraft.world.level.material.Fluid>> KEY_CACHE = Collections.synchronizedMap(new java.util.EnumMap<>(Fluid.class)); // Paper
@Override
public boolean isTagged(Fluid fluid) {
- return registry.getHolderOrThrow(net.minecraft.resources.ResourceKey.create(net.minecraft.core.Registry.FLUID_REGISTRY, org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(fluid.getKey()))).is(tag); // Paper
+ return registry.getHolderOrThrow(KEY_CACHE.computeIfAbsent(fluid, f -> net.minecraft.resources.ResourceKey.create(net.minecraft.core.Registry.FLUID_REGISTRY, org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(f.getKey())))).is(tag); // Paper - cache key
}
@Override

View file

@ -1,151 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Doc <nachito94@msn.com>
Date: Sun, 3 Apr 2022 11:31:42 -0400
Subject: [PATCH] Allow to change the podium for the EnderDragon
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
index 1eb76c456790b81b657090377dd5ea547898f9a5..8c4db2f0e5158872879da52a96bc592145e52e13 100644
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
@@ -100,6 +100,10 @@ public class EnderDragon extends Mob implements Enemy {
private final int[] nodeAdjacency = new int[24];
private final BinaryHeap openSet = new BinaryHeap();
private Explosion explosionSource = new Explosion(null, this, null, null, Double.NaN, Double.NaN, Double.NaN, Float.NaN, true, Explosion.BlockInteraction.DESTROY); // CraftBukkit - reusable source for CraftTNTPrimed.getSource()
+ // Paper start - add var for save custom podium
+ @Nullable
+ private BlockPos podium;
+ // Paper end
public EnderDragon(EntityType<? extends EnderDragon> entitytypes, Level world) {
super(EntityType.ENDER_DRAGON, world);
@@ -120,6 +124,19 @@ public class EnderDragon extends Mob implements Enemy {
return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 200.0D);
}
+ // Paper start
+ public BlockPos getPodium() {
+ if (this.podium == null) {
+ return EndPodiumFeature.END_PODIUM_LOCATION;
+ }
+ return this.podium;
+ }
+
+ public void setPodium(@Nullable BlockPos blockPos) {
+ this.podium = blockPos;
+ }
+ // Paper end
+
@Override
public boolean isFlapping() {
float f = Mth.cos(this.flapTime * 6.2831855F);
@@ -947,7 +964,7 @@ public class EnderDragon extends Mob implements Enemy {
d0 = segment2[1] - segment1[1];
}
} else {
- BlockPos blockposition = this.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.END_PODIUM_LOCATION);
+ BlockPos blockposition = this.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.getPodium()); // Paper - use custom podium
double d1 = Math.max(Math.sqrt(blockposition.distToCenterSqr(this.position())) / 4.0D, 1.0D);
d0 = (double) segmentOffset / d1;
@@ -974,7 +991,7 @@ public class EnderDragon extends Mob implements Enemy {
vec3d = this.getViewVector(tickDelta);
}
} else {
- BlockPos blockposition = this.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.END_PODIUM_LOCATION);
+ BlockPos blockposition = this.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.getPodium()); // Paper - use custom podium
f1 = Math.max((float) Math.sqrt(blockposition.distToCenterSqr(this.position())) / 4.0F, 1.0F);
float f3 = 6.0F / f1;
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonDeathPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonDeathPhase.java
index a64ee433e34538ce2b52207b6183999ae611e5dd..0f78e1ab090bb1df7b863c90b3c7465a3ce28c8c 100644
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonDeathPhase.java
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonDeathPhase.java
@@ -32,7 +32,7 @@ public class DragonDeathPhase extends AbstractDragonPhaseInstance {
public void doServerTick() {
++this.time;
if (this.targetLocation == null) {
- BlockPos blockPos = this.dragon.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, EndPodiumFeature.END_PODIUM_LOCATION);
+ BlockPos blockPos = this.dragon.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, this.dragon.getPodium()); // Paper - use custom podium
this.targetLocation = Vec3.atBottomCenterOf(blockPos);
}
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonHoldingPatternPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonHoldingPatternPhase.java
index e58f608e424e384606289d9ff27bf8f9c63aeeb2..4c338d7f3d5274a36db768e4a1cdedca130127d4 100644
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonHoldingPatternPhase.java
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonHoldingPatternPhase.java
@@ -55,7 +55,7 @@ public class DragonHoldingPatternPhase extends AbstractDragonPhaseInstance {
private void findNewTarget() {
if (this.currentPath != null && this.currentPath.isDone()) {
- BlockPos blockPos = this.dragon.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, new BlockPos(EndPodiumFeature.END_PODIUM_LOCATION));
+ BlockPos blockPos = this.dragon.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium()); // Paper - use custom podium
int i = this.dragon.getDragonFight() == null ? 0 : this.dragon.getDragonFight().getCrystalsAlive();
if (this.dragon.getRandom().nextInt(i + 3) == 0) {
this.dragon.getPhaseManager().setPhase(EnderDragonPhase.LANDING_APPROACH);
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingApproachPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingApproachPhase.java
index fdfdd42a30d752b11d18f2cefe84c1e9ddec41a2..5fca7c4e1d1d9da6f29ad70f1b5703c7f092d851 100644
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingApproachPhase.java
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingApproachPhase.java
@@ -52,7 +52,7 @@ public class DragonLandingApproachPhase extends AbstractDragonPhaseInstance {
private void findNewTarget() {
if (this.currentPath == null || this.currentPath.isDone()) {
int i = this.dragon.findClosestNode();
- BlockPos blockPos = this.dragon.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.END_PODIUM_LOCATION);
+ BlockPos blockPos = this.dragon.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium()); // Paper - use custom podium
Player player = this.dragon.level.getNearestPlayer(NEAR_EGG_TARGETING, this.dragon, (double)blockPos.getX(), (double)blockPos.getY(), (double)blockPos.getZ());
int j;
if (player != null) {
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingPhase.java
index c3eb04fa31a8e767c737091c2e1a3f858589e16b..1ee3ba970e33e20e5c72bc2f4153889b60c0e77e 100644
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingPhase.java
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonLandingPhase.java
@@ -39,7 +39,7 @@ public class DragonLandingPhase extends AbstractDragonPhaseInstance {
@Override
public void doServerTick() {
if (this.targetLocation == null) {
- this.targetLocation = Vec3.atBottomCenterOf(this.dragon.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.END_PODIUM_LOCATION));
+ this.targetLocation = Vec3.atBottomCenterOf(this.dragon.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium())); // Paper - use custom podium
}
if (this.targetLocation.distanceToSqr(this.dragon.getX(), this.dragon.getY(), this.dragon.getZ()) < 1.0D) {
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonTakeoffPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonTakeoffPhase.java
index 0ae65d0fa03d12486f48b0274b6e2d4eea169caf..ffe89d8c1f22f672d145fedb3bb102589dc31656 100644
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonTakeoffPhase.java
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonTakeoffPhase.java
@@ -24,7 +24,7 @@ public class DragonTakeoffPhase extends AbstractDragonPhaseInstance {
@Override
public void doServerTick() {
if (!this.firstTick && this.currentPath != null) {
- BlockPos blockPos = this.dragon.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.END_PODIUM_LOCATION);
+ BlockPos blockPos = this.dragon.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, this.dragon.getPodium()); // Paper - use custom podium
if (!blockPos.closerToCenterThan(this.dragon.position(), 10.0D)) {
this.dragon.getPhaseManager().setPhase(EnderDragonPhase.HOLDING_PATTERN);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java
index cd487bd68f9a8177ae3e015b3a5d1bc469743f48..eeb6d48da156602c046db891cac0ccb4fa639473 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java
@@ -79,4 +79,22 @@ public class CraftEnderDragon extends CraftMob implements EnderDragon {
public int getDeathAnimationTicks() {
return this.getHandle().dragonDeathTime;
}
+
+ // Paper start
+ @Override
+ public org.bukkit.Location getPodium() {
+ net.minecraft.core.BlockPos blockPosOrigin = this.getHandle().getPodium();
+ return new org.bukkit.Location(getWorld(), blockPosOrigin.getX(), blockPosOrigin.getY(), blockPosOrigin.getZ());
+ }
+
+ @Override
+ public void setPodium(org.bukkit.Location location) {
+ if (location == null) {
+ this.getHandle().setPodium(null);
+ } else {
+ org.apache.commons.lang.Validate.isTrue(location.getWorld() == null || location.getWorld().equals(getWorld()), "You cannot set a podium in a different world to where the dragon is");
+ this.getHandle().setPodium(new net.minecraft.core.BlockPos(location.getX(), location.getY(), location.getZ()));
+ }
+ }
+ // Paper end
}

View file

@ -1,40 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: etil2jz <blanchot.arthur@protonmail.ch>
Date: Sat, 2 Apr 2022 23:29:24 +0200
Subject: [PATCH] Fix NBT pieces overriding a block entity during worldgen
deadlock
By checking if the world passed into StructureTemplate's placeInWorld
is not a WorldGenRegion, we can bypass the deadlock entirely.
See https://bugs.mojang.com/browse/MC-246262
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
index c5827e4d870a0bba483649d54cae23072eab2b18..332d080ad722a0252d2ae8eb83f7697c1323b4ce 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
@@ -265,7 +265,11 @@ public class StructureTemplate {
if (definedstructure_blockinfo.nbt != null) {
tileentity = world.getBlockEntity(blockposition2);
- Clearable.tryClear(tileentity);
+ // Paper start - Fix NBT pieces overriding a block entity during worldgen deadlock
+ if (!(world instanceof net.minecraft.world.level.WorldGenLevel)) {
+ Clearable.tryClear(tileentity);
+ }
+ // Paper end
world.setBlock(blockposition2, Blocks.BARRIER.defaultBlockState(), 20);
}
@@ -380,7 +384,11 @@ public class StructureTemplate {
if (pair1.getSecond() != null) {
tileentity = world.getBlockEntity(blockposition6);
if (tileentity != null) {
- tileentity.setChanged();
+ // Paper start - Fix NBT pieces overriding a block entity during worldgen deadlock
+ if (!(world instanceof net.minecraft.world.level.WorldGenLevel)) {
+ tileentity.setChanged();
+ }
+ // Paper end
}
}
}

View file

@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Tue, 12 Apr 2022 16:36:15 -0700
Subject: [PATCH] Fix StructureGrowEvent species for RED_MUSHROOM
diff --git a/src/main/java/net/minecraft/world/level/block/MushroomBlock.java b/src/main/java/net/minecraft/world/level/block/MushroomBlock.java
index dd9446abb8b701b29dbb770c4d8e80f9ba5441cd..8f69073c4aec074a17791bceb91e7df608558c63 100644
--- a/src/main/java/net/minecraft/world/level/block/MushroomBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/MushroomBlock.java
@@ -85,7 +85,7 @@ public class MushroomBlock extends BushBlock implements BonemealableBlock {
public boolean growMushroom(ServerLevel world, BlockPos pos, BlockState state, Random random) {
world.removeBlock(pos, false);
- SaplingBlock.treeType = (this == Blocks.BROWN_MUSHROOM) ? TreeType.BROWN_MUSHROOM : TreeType.BROWN_MUSHROOM; // CraftBukkit
+ SaplingBlock.treeType = (this == Blocks.BROWN_MUSHROOM) ? TreeType.BROWN_MUSHROOM : TreeType.RED_MUSHROOM; // CraftBukkit // Paper
if (((ConfiguredFeature) ((Holder) this.featureSupplier.get()).value()).place(world, world.getChunkSource().getGenerator(), random, pos)) {
return true;
} else {

View file

@ -1,24 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
Date: Wed, 13 Apr 2022 08:25:42 +0100
Subject: [PATCH] Prevent tile entity copies loading chunks
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 3bfd0fc8e2d068657183e4ebd4f632c94c3908b2..4e3ee857b7c328d857aee8ff066758b19ef81da2 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2995,7 +2995,12 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
if (!itemstack.isEmpty() && nbttagcompound != null && nbttagcompound.contains("x") && nbttagcompound.contains("y") && nbttagcompound.contains("z") && this.player.getBukkitEntity().hasPermission("minecraft.nbt.copy")) { // Spigot
BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound);
- BlockEntity tileentity = this.player.level.getBlockEntity(blockposition);
+ // Paper start
+ BlockEntity tileentity = null;
+ if (this.player.distanceToSqr(blockposition.getX(), blockposition.getY(), blockposition.getZ()) < 32 * 32 && this.player.getLevel().isLoadedAndInBounds(blockposition)) {
+ tileentity = this.player.level.getBlockEntity(blockposition);
+ }
+ // Paper end
if (tileentity != null) {
tileentity.saveToItem(itemstack);

View file

@ -1,20 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Doc <nachito94@msn.com>
Date: Fri, 15 Apr 2022 17:40:30 -0400
Subject: [PATCH] Use username instead of display name in
PlayerList#getPlayerStats
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 2a8c3082d07244f8f00d644e01e875b81264324d..624946f48f0811c94d05174f28d0b1fc6d5e6a00 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -1414,7 +1414,7 @@ public abstract class PlayerList {
// CraftBukkit start
public ServerStatsCounter getPlayerStats(ServerPlayer entityhuman) {
ServerStatsCounter serverstatisticmanager = entityhuman.getStats();
- return serverstatisticmanager == null ? this.getPlayerStats(entityhuman.getUUID(), entityhuman.getDisplayName().getString()) : serverstatisticmanager;
+ return serverstatisticmanager == null ? this.getPlayerStats(entityhuman.getUUID(), entityhuman.getGameProfile().getName()) : serverstatisticmanager; // Paper - use username and not display name
}
public ServerStatsCounter getPlayerStats(UUID uuid, String displayName) {

View file

@ -1,24 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 15 Apr 2022 17:09:28 -0700
Subject: [PATCH] Fix slime spawners not spawning outside slime chunks
Fixes MC-50647 by just checking if the spawn type is a SPAWNER
and then bypassing the spawn check logic if on slimes if it is.
diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java
index b6e78e8145ea78d532f22707c7525829c5778076..2e819d32915941bd77034ce599eb787610a6d666 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Slime.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java
@@ -325,6 +325,11 @@ public class Slime extends Mob implements Enemy {
public static boolean checkSlimeSpawnRules(EntityType<Slime> type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, Random random) {
if (world.getDifficulty() != Difficulty.PEACEFUL) {
+ // Paper start - fix slime spawners; Fixes MC-50647
+ if (spawnReason == MobSpawnType.SPAWNER) {
+ return random.nextInt(10) == 0;
+ }
+ // Paper end
// Paper start - Replace rules for Height in Swamp Biome
final double maxHeightSwamp = world.getMinecraftWorld().paperConfig.slimeMaxSpawnHeightInSwamp;
final double minHeightSwamp = world.getMinecraftWorld().paperConfig.slimeMinSpawnHeightInSwamp;

View file

@ -1,181 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Sun, 27 Mar 2022 13:51:09 -0400
Subject: [PATCH] Pass ServerLevel for gamerule callbacks
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index e28e09aae1d95d9bed50a137e999e6d457e62478..257c94f7c1cb00c9a91ab82e311dfd8eca29c538 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -319,7 +319,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
//DedicatedServer.LOGGER.info("Done ({})! For help, type \"help\"", s); // Paper moved to after init
if (dedicatedserverproperties.announcePlayerAchievements != null) {
- ((GameRules.BooleanValue) this.getGameRules().getRule(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)).set(dedicatedserverproperties.announcePlayerAchievements, this);
+ ((GameRules.BooleanValue) this.getGameRules().getRule(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)).set(dedicatedserverproperties.announcePlayerAchievements, null); // Paper
}
if (dedicatedserverproperties.enableQuery) {
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 4e3ee857b7c328d857aee8ff066758b19ef81da2..1169149f0316e683ba5ac3b1e95a8a00a3c2dafa 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2604,7 +2604,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
this.player = this.server.getPlayerList().respawn(this.player, false);
if (this.server.isHardcore()) {
this.player.setGameMode(GameType.SPECTATOR, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.HARDCORE_DEATH, null); // Paper
- ((GameRules.BooleanValue) this.player.getLevel().getGameRules().getRule(GameRules.RULE_SPECTATORSGENERATECHUNKS)).set(false, this.server);
+ ((GameRules.BooleanValue) this.player.getLevel().getGameRules().getRule(GameRules.RULE_SPECTATORSGENERATECHUNKS)).set(false, this.player.getLevel()); // Paper
}
}
break;
diff --git a/src/main/java/net/minecraft/world/level/GameRules.java b/src/main/java/net/minecraft/world/level/GameRules.java
index 798afc145c54306fcf0838d8daef2bdf17763da9..22feab6477bad023c2d6cc9ac99d392d0afe0a31 100644
--- a/src/main/java/net/minecraft/world/level/GameRules.java
+++ b/src/main/java/net/minecraft/world/level/GameRules.java
@@ -51,7 +51,7 @@ public class GameRules {
public static final GameRules.Key<GameRules.BooleanValue> RULE_SENDCOMMANDFEEDBACK = GameRules.register("sendCommandFeedback", GameRules.Category.CHAT, GameRules.BooleanValue.create(true));
public static final GameRules.Key<GameRules.BooleanValue> RULE_REDUCEDDEBUGINFO = GameRules.register("reducedDebugInfo", GameRules.Category.MISC, GameRules.BooleanValue.create(false, (minecraftserver, gamerules_gameruleboolean) -> {
int i = gamerules_gameruleboolean.get() ? 22 : 23;
- Iterator iterator = minecraftserver.getPlayerList().getPlayers().iterator();
+ Iterator iterator = minecraftserver.players().iterator(); // Paper
while (iterator.hasNext()) {
ServerPlayer entityplayer = (ServerPlayer) iterator.next();
@@ -71,7 +71,7 @@ public class GameRules {
public static final GameRules.Key<GameRules.BooleanValue> RULE_DISABLE_RAIDS = GameRules.register("disableRaids", GameRules.Category.MOBS, GameRules.BooleanValue.create(false));
public static final GameRules.Key<GameRules.BooleanValue> RULE_DOINSOMNIA = GameRules.register("doInsomnia", GameRules.Category.SPAWNING, GameRules.BooleanValue.create(true));
public static final GameRules.Key<GameRules.BooleanValue> RULE_DO_IMMEDIATE_RESPAWN = GameRules.register("doImmediateRespawn", GameRules.Category.PLAYER, GameRules.BooleanValue.create(false, (minecraftserver, gamerules_gameruleboolean) -> {
- Iterator iterator = minecraftserver.getPlayerList().getPlayers().iterator();
+ Iterator iterator = minecraftserver.players().iterator(); // Paper
while (iterator.hasNext()) {
ServerPlayer entityplayer = (ServerPlayer) iterator.next();
@@ -156,13 +156,13 @@ public class GameRules {
((GameRules.Type<T>) type).callVisitor(consumer, (GameRules.Key<T>) key); // CraftBukkit - decompile error
}
- public void assignFrom(GameRules rules, @Nullable MinecraftServer server) {
+ public void assignFrom(GameRules rules, @Nullable net.minecraft.server.level.ServerLevel server) { // Paper
rules.rules.keySet().forEach((gamerules_gamerulekey) -> {
this.assignCap(gamerules_gamerulekey, rules, server);
});
}
- private <T extends GameRules.Value<T>> void assignCap(GameRules.Key<T> key, GameRules rules, @Nullable MinecraftServer server) {
+ private <T extends GameRules.Value<T>> void assignCap(GameRules.Key<T> key, GameRules rules, @Nullable net.minecraft.server.level.ServerLevel server) { // Paper
T t0 = rules.getRule(key);
this.getRule(key).setFrom(t0, server);
@@ -230,10 +230,10 @@ public class GameRules {
private final Supplier<ArgumentType<?>> argument;
private final Function<GameRules.Type<T>, T> constructor;
- final BiConsumer<MinecraftServer, T> callback;
+ final BiConsumer<net.minecraft.server.level.ServerLevel, T> callback; // Paper
private final GameRules.VisitorCaller<T> visitorCaller;
- Type(Supplier<ArgumentType<?>> argumentType, Function<GameRules.Type<T>, T> ruleFactory, BiConsumer<MinecraftServer, T> changeCallback, GameRules.VisitorCaller<T> ruleAcceptor) {
+ Type(Supplier<ArgumentType<?>> argumentType, Function<GameRules.Type<T>, T> ruleFactory, BiConsumer<net.minecraft.server.level.ServerLevel, T> changeCallback, GameRules.VisitorCaller<T> ruleAcceptor) { // Paper
this.argument = argumentType;
this.constructor = ruleFactory;
this.callback = changeCallback;
@@ -265,10 +265,10 @@ public class GameRules {
public void setFromArgument(CommandContext<CommandSourceStack> context, String name, GameRules.Key<T> gameRuleKey) { // Paper
this.updateFromArgument(context, name, gameRuleKey); // Paper
- this.onChanged(((CommandSourceStack) context.getSource()).getServer());
+ this.onChanged(((CommandSourceStack) context.getSource()).getLevel()); // Paper
}
- public void onChanged(@Nullable MinecraftServer server) {
+ public void onChanged(@Nullable net.minecraft.server.level.ServerLevel server) { // Paper
if (server != null) {
this.type.callback.accept(server, this.getSelf());
}
@@ -289,7 +289,7 @@ public class GameRules {
protected abstract T copy();
- public abstract void setFrom(T rule, @Nullable MinecraftServer server);
+ public abstract void setFrom(T rule, @Nullable net.minecraft.server.level.ServerLevel level); // Paper
}
public interface GameRuleTypeVisitor {
@@ -305,7 +305,7 @@ public class GameRules {
private boolean value;
- static GameRules.Type<GameRules.BooleanValue> create(boolean initialValue, BiConsumer<MinecraftServer, GameRules.BooleanValue> changeCallback) {
+ static GameRules.Type<GameRules.BooleanValue> create(boolean initialValue, BiConsumer<net.minecraft.server.level.ServerLevel, GameRules.BooleanValue> changeCallback) { // Paper
return new GameRules.Type<>(BoolArgumentType::bool, (gamerules_gameruledefinition) -> {
return new GameRules.BooleanValue(gamerules_gameruledefinition, initialValue);
}, changeCallback, GameRules.GameRuleTypeVisitor::visitBoolean);
@@ -333,7 +333,7 @@ public class GameRules {
return this.value;
}
- public void set(boolean value, @Nullable MinecraftServer server) {
+ public void set(boolean value, @Nullable net.minecraft.server.level.ServerLevel server) { // Paper
this.value = value;
this.onChanged(server);
}
@@ -363,7 +363,7 @@ public class GameRules {
return new GameRules.BooleanValue(this.type, this.value);
}
- public void setFrom(GameRules.BooleanValue rule, @Nullable MinecraftServer server) {
+ public void setFrom(GameRules.BooleanValue rule, @Nullable net.minecraft.server.level.ServerLevel server) { // Paper
this.value = rule.value;
this.onChanged(server);
}
@@ -373,7 +373,7 @@ public class GameRules {
private int value;
- private static GameRules.Type<GameRules.IntegerValue> create(int initialValue, BiConsumer<MinecraftServer, GameRules.IntegerValue> changeCallback) {
+ private static GameRules.Type<GameRules.IntegerValue> create(int initialValue, BiConsumer<net.minecraft.server.level.ServerLevel, GameRules.IntegerValue> changeCallback) { // Paper
return new GameRules.Type<>(IntegerArgumentType::integer, (gamerules_gameruledefinition) -> {
return new GameRules.IntegerValue(gamerules_gameruledefinition, initialValue);
}, changeCallback, GameRules.GameRuleTypeVisitor::visitInteger);
@@ -401,7 +401,7 @@ public class GameRules {
return this.value;
}
- public void set(int value, @Nullable MinecraftServer server) {
+ public void set(int value, @Nullable net.minecraft.server.level.ServerLevel server) { // Paper
this.value = value;
this.onChanged(server);
}
@@ -452,7 +452,7 @@ public class GameRules {
return new GameRules.IntegerValue(this.type, this.value);
}
- public void setFrom(GameRules.IntegerValue rule, @Nullable MinecraftServer server) {
+ public void setFrom(GameRules.IntegerValue rule, @Nullable net.minecraft.server.level.ServerLevel server) { // Paper
this.value = rule.value;
this.onChanged(server);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index f5a6250350a5f0b6236c1fe0f149b1190de34880..43244a479a112786539a905a22cb12e3cf55b2dd 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -1915,7 +1915,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
// Paper end
GameRules.Value<?> handle = this.getHandle().getGameRules().getRule(CraftWorld.getGameRulesNMS().get(rule));
handle.deserialize(event.getValue()); // Paper
- handle.onChanged(this.getHandle().getServer());
+ handle.onChanged(this.getHandle()); // Paper
return true;
}
@@ -1955,7 +1955,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
// Paper end
GameRules.Value<?> handle = this.getHandle().getGameRules().getRule(CraftWorld.getGameRulesNMS().get(rule.getName()));
handle.deserialize(event.getValue()); // Paper
- handle.onChanged(this.getHandle().getServer());
+ handle.onChanged(this.getHandle()); // Paper
return true;
}

View file

@ -1,23 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: HexedHero <6012891+HexedHero@users.noreply.github.com>
Date: Sun, 10 Apr 2022 06:26:32 +0100
Subject: [PATCH] Add pre-unbreaking amount to PlayerItemDamageEvent
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
index dc4639f905fb71435daf29c61f64621a3e2cc533..6837c965592d4584cfc958a1008b98791a0fc780 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
@@ -551,10 +551,11 @@ public final class ItemStack {
}
}
+ int originalDamage = amount; // Paper
amount -= k;
// CraftBukkit start
if (player instanceof ServerPlayer serverPlayer) { // Paper
- PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount); // Paper
+ PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount, originalDamage); // Paper
event.getPlayer().getServer().getPluginManager().callEvent(event);
if (amount != event.getDamage() || event.isCancelled()) {

View file

@ -1,18 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
Date: Sat, 3 Jul 2021 21:18:28 +0100
Subject: [PATCH] WorldCreator#keepSpawnLoaded
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 12c1728084d5f1af2a0c242b271939198c7fbea5..c3f15ee7505e82418d9659ba3cee4f807546e0db 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1262,6 +1262,7 @@ public final class CraftServer implements Server {
internal.setSpawnSettings(true, true);
// Paper - move up
+ internal.keepSpawnInMemory = creator.keepSpawnLoaded().toBooleanOrElse(internal.getWorld().getKeepSpawnInMemory()); // Paper
this.getServer().prepareLevels(internal.getChunkSource().chunkMap.progressListener, internal);
internal.entityManager.tick(); // SPIGOT-6526: Load pending entities so they are available to the API

View file

@ -1,22 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sun, 27 Mar 2022 16:00:28 -0700
Subject: [PATCH] Fix NPE for BlockDataMeta#getBlockData
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
index 1fe46049cc33c24db04fbfcde36ab275c03177bf..5607dc10dc1c9d2dbf4e3007890e5e89a175605e 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
@@ -1093,7 +1093,10 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
@Override
public BlockData getBlockData(Material material) {
- return CraftBlockData.fromData(BlockItem.getBlockState(CraftMagicNumbers.getBlock(material).defaultBlockState(), blockData));
+ // Paper start - fix NPE if this.blockData is null
+ final net.minecraft.world.level.block.state.BlockState defaultBlockState = CraftMagicNumbers.getBlock(material).defaultBlockState();
+ return CraftBlockData.fromData(this.blockData == null ? defaultBlockState : BlockItem.getBlockState(defaultBlockState, blockData));
+ // Paper end
}
@Override

View file

@ -1,54 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 2 Feb 2022 13:50:06 -0800
Subject: [PATCH] Trigger bee_nest_destroyed trigger in the correct place
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
index 891199d02539fa46454cd0aa7c133637e5dc8235..415b6c2bbf11c5a2ac75d18f52b93f80b9e14fe4 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
@@ -458,12 +458,16 @@ public class ServerPlayerGameMode {
block.destroy(this.level, pos, iblockdata);
}
+ ItemStack mainHandStack = null; // Paper
+ boolean isCorrectTool = false; // Paper
if (this.isCreative()) {
// return true; // CraftBukkit
} else {
ItemStack itemstack = this.player.getMainHandItem();
ItemStack itemstack1 = itemstack.copy();
boolean flag1 = this.player.hasCorrectToolForDrops(iblockdata);
+ mainHandStack = itemstack1; // Paper
+ isCorrectTool = flag1; // Paper
itemstack.mineBlock(this.level, iblockdata, pos, this.player);
if (flag && flag1 && event.isDropItems()) { // CraftBukkit - Check if block should drop items
@@ -484,6 +488,13 @@ public class ServerPlayerGameMode {
if (flag && event != null) {
iblockdata.getBlock().popExperience(this.level, pos, event.getExpToDrop(), this.player); // Paper
}
+ // Paper start - trigger after items are dropped (check impls of block#playerDestroy)
+ if (mainHandStack != null) {
+ if (flag && isCorrectTool && event.isDropItems() && block instanceof net.minecraft.world.level.block.BeehiveBlock && tileentity instanceof net.minecraft.world.level.block.entity.BeehiveBlockEntity beehiveBlockEntity) { // simulates the guard on block#playerDestroy above
+ CriteriaTriggers.BEE_NEST_DESTROYED.trigger(player, iblockdata, mainHandStack, beehiveBlockEntity.getOccupantCount());
+ }
+ }
+ // Paper end
return true;
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java
index e9974415e8f016f50a93a5eea117afe25a6b735d..a510ec076ff91bb5e06ebfca0b00e6f82a92e8cd 100644
--- a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java
@@ -88,7 +88,7 @@ public class BeehiveBlock extends BaseEntityBlock {
this.angerNearbyBees(world, pos);
}
- CriteriaTriggers.BEE_NEST_DESTROYED.trigger((ServerPlayer) player, state, stack, tileentitybeehive.getOccupantCount());
+ // CriteriaTriggers.BEE_NEST_DESTROYED.trigger((ServerPlayer) player, state, stack, tileentitybeehive.getOccupantCount()); // Paper - moved until after items are dropped
}
}

View file

@ -1,42 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 18 Mar 2022 21:15:55 -0700
Subject: [PATCH] Add EntityDyeEvent and CollarColorable interface
diff --git a/src/main/java/net/minecraft/world/entity/animal/Cat.java b/src/main/java/net/minecraft/world/entity/animal/Cat.java
index e4eac546836b73b5e9c8fd68ca0d32c01148313e..9f5180271ca8a790aa52763ac46d31b905c9d477 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Cat.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Cat.java
@@ -432,6 +432,13 @@ public class Cat extends TamableAnimal {
DyeColor enumcolor = ((DyeItem) item).getDyeColor();
if (enumcolor != this.getCollarColor()) {
+ // Paper start
+ final io.papermc.paper.event.entity.EntityDyeEvent event = new io.papermc.paper.event.entity.EntityDyeEvent(this.getBukkitEntity(), org.bukkit.DyeColor.getByWoolData((byte) enumcolor.getId()), ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity());
+ if (!event.callEvent()) {
+ return InteractionResult.FAIL;
+ }
+ enumcolor = DyeColor.byId(event.getColor().getWoolData());
+ // Paper end
this.setCollarColor(enumcolor);
if (!player.getAbilities().instabuild) {
itemstack.shrink(1);
diff --git a/src/main/java/net/minecraft/world/entity/animal/Wolf.java b/src/main/java/net/minecraft/world/entity/animal/Wolf.java
index aaf7096835bab3a42d617553dd83e048e4a83766..249ef89342d2811614507090b79250adf78e33ce 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Wolf.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Wolf.java
@@ -393,6 +393,13 @@ public class Wolf extends TamableAnimal implements NeutralMob {
DyeColor enumcolor = ((DyeItem) item).getDyeColor();
if (enumcolor != this.getCollarColor()) {
+ // Paper start
+ final io.papermc.paper.event.entity.EntityDyeEvent event = new io.papermc.paper.event.entity.EntityDyeEvent(this.getBukkitEntity(), org.bukkit.DyeColor.getByWoolData((byte) enumcolor.getId()), ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity());
+ if (!event.callEvent()) {
+ return InteractionResult.FAIL;
+ }
+ enumcolor = DyeColor.byId(event.getColor().getWoolData());
+ // Paper end
this.setCollarColor(enumcolor);
if (!player.getAbilities().instabuild) {
itemstack.shrink(1);

View file

@ -1,68 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Tue, 29 Mar 2022 13:46:23 -0700
Subject: [PATCH] Fire CauldronLevelChange on initial fill
Also don't fire level events or game events if stalactite
drip is cancelled
diff --git a/src/main/java/net/minecraft/world/level/block/CauldronBlock.java b/src/main/java/net/minecraft/world/level/block/CauldronBlock.java
index dbae4f3b56d0290c6d28b9beaaa3b459754d43e3..18f4c422e8277b2f673202a598d81eabf5eea712 100644
--- a/src/main/java/net/minecraft/world/level/block/CauldronBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/CauldronBlock.java
@@ -36,10 +36,18 @@ public class CauldronBlock extends AbstractCauldronBlock {
public void handlePrecipitation(BlockState state, Level world, BlockPos pos, Biome.Precipitation precipitation) {
if (CauldronBlock.shouldHandlePrecipitation(world, precipitation)) {
if (precipitation == Biome.Precipitation.RAIN) {
- world.setBlockAndUpdate(pos, Blocks.WATER_CAULDRON.defaultBlockState());
+ // Paper start - call event for initial fill
+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, Blocks.WATER_CAULDRON.defaultBlockState(), null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL)) {
+ return;
+ }
+ // Paper end
world.gameEvent((Entity) null, GameEvent.FLUID_PLACE, pos);
} else if (precipitation == Biome.Precipitation.SNOW) {
- world.setBlockAndUpdate(pos, Blocks.POWDER_SNOW_CAULDRON.defaultBlockState());
+ // Paper start - call event for initial fill
+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, Blocks.POWDER_SNOW_CAULDRON.defaultBlockState(), null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL)) {
+ return;
+ }
+ // Paper end
world.gameEvent((Entity) null, GameEvent.FLUID_PLACE, pos);
}
@@ -54,11 +62,19 @@ public class CauldronBlock extends AbstractCauldronBlock {
@Override
protected void receiveStalactiteDrip(BlockState state, Level world, BlockPos pos, Fluid fluid) {
if (fluid == Fluids.WATER) {
- LayeredCauldronBlock.changeLevel(state, world, pos, Blocks.WATER_CAULDRON.defaultBlockState(), null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL); // CraftBukkit
+ // Paper start - don't send level event or game event if cancelled
+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, Blocks.WATER_CAULDRON.defaultBlockState(), null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL)) { // CraftBukkit
+ return;
+ }
+ // Paper end
world.levelEvent(1047, pos, 0);
world.gameEvent((Entity) null, GameEvent.FLUID_PLACE, pos);
} else if (fluid == Fluids.LAVA) {
- LayeredCauldronBlock.changeLevel(state, world, pos, Blocks.LAVA_CAULDRON.defaultBlockState(), null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL); // CraftBukkit
+ // Paper start - don't send level event or game event if cancelled
+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, Blocks.LAVA_CAULDRON.defaultBlockState(), null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL)) { // CraftBukkit
+ return;
+ }
+ // Paper end
world.levelEvent(1046, pos, 0);
world.gameEvent((Entity) null, GameEvent.FLUID_PLACE, pos);
}
diff --git a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
index e6ea389350cf391a87c4c388ed9a6325bdceb90d..c21b0e7265488f26179810ddb6a8a6992a2a4807 100644
--- a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
@@ -89,7 +89,7 @@ public class LayeredCauldronBlock extends AbstractCauldronBlock {
}
// CraftBukkit start
- public static boolean changeLevel(BlockState iblockdata, Level world, BlockPos blockposition, BlockState newBlock, Entity entity, CauldronLevelChangeEvent.ChangeReason reason) {
+ public static boolean changeLevel(BlockState iblockdata, Level world, BlockPos blockposition, BlockState newBlock, @javax.annotation.Nullable Entity entity, CauldronLevelChangeEvent.ChangeReason reason) { // Paper - entity is nullable
CraftBlockState newState = CraftBlockStates.getBlockState(world, blockposition);
newState.setData(newBlock);

View file

@ -1,56 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Thu, 30 Dec 2021 14:02:13 -0800
Subject: [PATCH] fix powder snow cauldrons not turning to water
Powder snow cauldrons should turn to water when
extinguishing an entity
diff --git a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
index c21b0e7265488f26179810ddb6a8a6992a2a4807..95946623bc4673363a008fea7a4b1eeae6e1dfdb 100644
--- a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
@@ -63,7 +63,7 @@ public class LayeredCauldronBlock extends AbstractCauldronBlock {
if (!world.isClientSide && entity.isOnFire() && this.isEntityInsideContent(state, pos, entity)) {
// CraftBukkit start
if (entity.mayInteract(world, pos)) {
- if (!LayeredCauldronBlock.lowerFillLevel(state, world, pos, entity, CauldronLevelChangeEvent.ChangeReason.EXTINGUISH)) {
+ if (!this.handleEntityOnFireInsideWithEvent(state, world, pos, entity)) { // Paper - fix powdered snow cauldron extinguishing entities
return;
}
}
@@ -73,9 +73,15 @@ public class LayeredCauldronBlock extends AbstractCauldronBlock {
}
+ @Deprecated // Paper - use #handleEntityOnFireInsideWithEvent
protected void handleEntityOnFireInside(BlockState state, Level world, BlockPos pos) {
LayeredCauldronBlock.lowerFillLevel(state, world, pos);
}
+ // Paper start
+ protected boolean handleEntityOnFireInsideWithEvent(BlockState state, Level world, BlockPos pos, Entity entity) {
+ return LayeredCauldronBlock.lowerFillLevel(state, world, pos, entity, CauldronLevelChangeEvent.ChangeReason.EXTINGUISH);
+ }
+ // Paper end
public static void lowerFillLevel(BlockState state, Level world, BlockPos pos) {
// CraftBukkit start
diff --git a/src/main/java/net/minecraft/world/level/block/PowderSnowCauldronBlock.java b/src/main/java/net/minecraft/world/level/block/PowderSnowCauldronBlock.java
index 54c8f2ccadd685b43d7ee032a95bfcf193357ce9..7f6b240bbbb773ca49e0e6290169cc81f5529af5 100644
--- a/src/main/java/net/minecraft/world/level/block/PowderSnowCauldronBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/PowderSnowCauldronBlock.java
@@ -16,7 +16,14 @@ public class PowderSnowCauldronBlock extends LayeredCauldronBlock {
}
@Override
+ @Deprecated // Paper - use #handleEntityOnFireInsideWithEvent
protected void handleEntityOnFireInside(BlockState state, Level world, BlockPos pos) {
lowerFillLevel(Blocks.WATER_CAULDRON.defaultBlockState().setValue(LEVEL, state.getValue(LEVEL)), world, pos);
}
+ // Paper - replace powdered snow with water (taken from #handleEntityOnFireInside)
+ @Override
+ protected boolean handleEntityOnFireInsideWithEvent(BlockState state, Level world, BlockPos pos, net.minecraft.world.entity.Entity entity) {
+ return super.handleEntityOnFireInsideWithEvent(Blocks.WATER_CAULDRON.defaultBlockState().setValue(LEVEL, state.getValue(LEVEL)), world, pos, entity);
+ }
+ // Paper end
}

View file

@ -1,38 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
Date: Sat, 30 Apr 2022 00:38:57 +0100
Subject: [PATCH] Sign cleanup filtering
TODO: This logic here should be moved into a DataFixer in the next MC release
noting to ensure to apply the cleanup logic here, and clean up the added
tags
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
index 6371176fba41218a209ea59b4cafe5b2d4a685fd..d5bcc81a809e3c733c6fc11309bcf0913860edf6 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
@@ -72,6 +72,7 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
}
// CraftBukkit end
+ nbt.putBoolean("Paper.cleanedFiltered", true); // Paper
nbt.putString("Color", this.color.getName());
nbt.putBoolean("GlowingText", this.hasGlowingText);
}
@@ -88,6 +89,7 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
boolean oldSign = Boolean.getBoolean("convertLegacySigns") && !nbt.getBoolean("Bukkit.isConverted");
// CraftBukkit end
+ boolean cleanedFiltered = nbt.getBoolean("Paper.cleanedFiltered"); // Paper
for (int i = 0; i < 4; ++i) {
String s = nbt.getString(SignBlockEntity.RAW_TEXT_FIELD_NAMES[i]);
// CraftBukkit start
@@ -105,7 +107,7 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
this.messages[i] = ichatbasecomponent;
String s1 = SignBlockEntity.FILTERED_TEXT_FIELD_NAMES[i];
- if (nbt.contains(s1, 8)) {
+ if (cleanedFiltered && nbt.contains(s1, 8)) { // Paper
this.filteredMessages[i] = this.loadLine(nbt.getString(s1));
} else {
this.filteredMessages[i] = ichatbasecomponent;

View file

@ -1,18 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: u9g <git@u9g.dev>
Date: Tue, 3 May 2022 20:41:37 -0400
Subject: [PATCH] Add PlayerStopUsingItemEvent
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index c17b8c77b1a4d65afaefd9c4b32219d898882410..d6ef140bcc35b10f78f2ec2f10c8a153395fc9df 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -3868,6 +3868,7 @@ public abstract class LivingEntity extends Entity {
public void releaseUsingItem() {
if (!this.useItem.isEmpty()) {
+ if (this instanceof ServerPlayer) new io.papermc.paper.event.player.PlayerStopUsingItemEvent((Player) getBukkitEntity(), useItem.asBukkitMirror(), getTicksUsingItem()).callEvent(); // Paper
this.useItem.releaseUsing(this.level, this, this.getUseItemRemainingTicks());
if (this.useItem.useOnRelease()) {
this.updatingUsingItem();

View file

@ -1,68 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Sun, 5 Dec 2021 14:58:17 -0500
Subject: [PATCH] FallingBlock auto expire setting
diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
index 46102c28d10b11ecbafd3dda2de66982eaed8a00..318ea6ebf4c13a984b3815f00bf6cb3856ff6fe0 100644
--- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
+++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
@@ -61,6 +61,7 @@ public class FallingBlockEntity extends Entity {
@Nullable
public CompoundTag blockData;
protected static final EntityDataAccessor<BlockPos> DATA_START_POS = SynchedEntityData.defineId(FallingBlockEntity.class, EntityDataSerializers.BLOCK_POS);
+ public boolean autoExpire = true; // Paper - Auto expire setting
public FallingBlockEntity(EntityType<? extends FallingBlockEntity> type, Level world) {
super(type, world);
@@ -175,7 +176,7 @@ public class FallingBlockEntity extends Entity {
}
if (!this.onGround && !flag1) {
- if (!this.level.isClientSide && (this.time > 100 && (blockposition.getY() <= this.level.getMinBuildHeight() || blockposition.getY() > this.level.getMaxBuildHeight()) || this.time > 600)) {
+ if (!this.level.isClientSide && ((this.time > 100 && autoExpire) && (blockposition.getY() <= this.level.getMinBuildHeight() || blockposition.getY() > this.level.getMaxBuildHeight()) || (this.time > 600 && autoExpire))) { // Paper - Auto expire setting
if (this.dropItem && this.level.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) {
this.spawnAtLocation((ItemLike) block);
}
@@ -321,6 +322,7 @@ public class FallingBlockEntity extends Entity {
if (this.blockData != null) {
nbt.put("TileEntityData", this.blockData);
}
+ if (!autoExpire) {nbt.putBoolean("Paper.AutoExpire", false);} // Paper - AutoExpire setting
}
@@ -367,6 +369,10 @@ public class FallingBlockEntity extends Entity {
int srcZ = nbt.getInt("SourceLoc_z");
this.setOrigin(new org.bukkit.Location(level.getWorld(), srcX, srcY, srcZ));
}
+
+ if (nbt.contains("Paper.AutoExpire")) {
+ this.autoExpire = nbt.getBoolean("Paper.AutoExpire");
+ }
// Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFallingBlock.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFallingBlock.java
index 0de415236fe9997fc3ffedba20b8df68647cb822..87c413c2f3b59ae9ef36e5becc10b29a81348022 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFallingBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFallingBlock.java
@@ -58,6 +58,17 @@ public class CraftFallingBlock extends CraftEntity implements FallingBlock {
public void setHurtEntities(boolean hurtEntities) {
this.getHandle().hurtEntities = hurtEntities;
}
+ // Paper Start - Auto expire setting
+ @Override
+ public boolean doesAutoExpire() {
+ return this.getHandle().autoExpire;
+ }
+
+ @Override
+ public void shouldAutoExpire(boolean autoExpires) {
+ this.getHandle().autoExpire = autoExpires;
+ }
+ // Paper End - Auto expire setting
@Override
public void setTicksLived(int value) {

View file

@ -1,48 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Noah van der Aa <ndvdaa@gmail.com>
Date: Fri, 7 Jan 2022 11:58:26 +0100
Subject: [PATCH] Don't tick markers
Fixes https://github.com/PaperMC/Paper/issues/7276 by not adding markers to the entity
tick list at all and ignoring them in Spigot's activation range checks. The entity tick
list is only used in the tick and tickPassenger methods, so we can safely not add the
markers to it.
diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java
index 5f079cf06b0d1505bfb3fda5c326b2d7fd4f0e48..febb35091d32735ae2fe846170bd2c46d1449723 100644
--- a/src/main/java/com/destroystokyo/paper/PaperCommand.java
+++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
@@ -629,7 +629,7 @@ public class PaperCommand extends Command {
ChunkPos chunk = e.chunkPosition();
info.left++;
info.right.put(chunk, info.right.getOrDefault(chunk, 0) + 1);
- if (!chunkProviderServer.isPositionTicking(e)) {
+ if (!chunkProviderServer.isPositionTicking(e) || e instanceof net.minecraft.world.entity.Marker) { // Markers aren't ticked.
nonEntityTicking.merge(key, Integer.valueOf(1), Integer::sum);
}
});
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 50fd3419deb668dda64b1056f03fb66da55e6960..62ec40de8ed8acb293ef21c8d2c624060d51cfe8 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -2418,6 +2418,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
public void onTickingStart(Entity entity) {
+ if (entity instanceof net.minecraft.world.entity.Marker) return; // Paper - Don't tick markers
ServerLevel.this.entityTickList.add(entity);
ServerLevel.this.entityManager.addNavigatorsIfPathingToRegion(entity); // Paper - optimise notify
}
diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java
index 5bffc9a0f6ef9d54abb359565d07509b177c2b82..1a1a1f4d0ac025daccc2d3f84faf6592819f4d5c 100644
--- a/src/main/java/org/spigotmc/ActivationRange.java
+++ b/src/main/java/org/spigotmc/ActivationRange.java
@@ -211,7 +211,7 @@ public class ActivationRange
// Paper end
// Paper start
- java.util.List<Entity> entities = world.getEntities((Entity)null, maxBB, null);
+ java.util.List<Entity> entities = world.getEntities((Entity)null, maxBB, (e) -> !(e instanceof net.minecraft.world.entity.Marker)); // Don't tick markers
for (int i = 0; i < entities.size(); i++) {
Entity entity = entities.get(i);
ActivationRange.activateEntity(entity);

View file

@ -1,24 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sat, 7 May 2022 14:58:53 -0700
Subject: [PATCH] Do not accept invalid client settings
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 1169149f0316e683ba5ac3b1e95a8a00a3c2dafa..0b7923f67d27549f41c0d398d1b99737f0c8a746 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -3170,6 +3170,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
@Override
public void handleClientInformation(ServerboundClientInformationPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel());
+ // Paper start - do not accept invalid information
+ if (packet.viewDistance() < 0) {
+ LOGGER.warn("Disconnecting " + this.player.getScoreboardName() + " for invalid view distance: " + packet.viewDistance());
+ this.disconnect("Invalid client settings", PlayerKickEvent.Cause.ILLEGAL_ACTION);
+ return;
+ }
+ // Paper end - do not accept invalid information
this.player.updateOptions(packet);
}

View file

@ -1,68 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: PanSzelescik <panszelescik@gmail.com>
Date: Thu, 7 Apr 2022 16:13:39 +0200
Subject: [PATCH] Add support for Proxy Protocol
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index 1ac6cf51f2682d5eb14fe19646e79f6617d492dd..fafbebbb5e8c1a381b673f97f1fa210687b52823 100644
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -688,4 +688,9 @@ public class PaperConfig {
private static void useDimensionTypeForCustomSpawners() {
useDimensionTypeForCustomSpawners = getBoolean("settings.use-dimension-type-for-custom-spawners", false);
}
+
+ public static boolean useProxyProtocol;
+ private static void useProxyProtocol() {
+ useProxyProtocol = getBoolean("settings.proxy-protocol", false);
+ }
}
diff --git a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
index 058fb3696c7ece4a7b6971886b1760b26add733b..98286dd27fc3562ca55ec44cc6e5eb5157269942 100644
--- a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
+++ b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
@@ -109,6 +109,12 @@ public class ServerConnectionListener {
ServerConnectionListener.LOGGER.info("Paper: Using " + com.velocitypowered.natives.util.Natives.cipher.getLoadedVariant() + " cipher from Velocity.");
// Paper end
+ // Paper start - indicate Proxy Protocol usage
+ if (com.destroystokyo.paper.PaperConfig.useProxyProtocol) {
+ ServerConnectionListener.LOGGER.info("Paper: Using Proxy Protocol");
+ }
+ // Paper end
+
this.channels.add(((ServerBootstrap) ((ServerBootstrap) (new ServerBootstrap()).channel(oclass)).childHandler(new ChannelInitializer<Channel>() {
protected void initChannel(Channel channel) {
try {
@@ -122,6 +128,30 @@ public class ServerConnectionListener {
int j = ServerConnectionListener.this.server.getRateLimitPacketsPerSecond();
Object object = j > 0 ? new RateKickingConnection(j) : new Connection(PacketFlow.SERVERBOUND);
+ // Paper start - Add support for Proxy Protocol
+ if (com.destroystokyo.paper.PaperConfig.useProxyProtocol) {
+ channel.pipeline().addAfter("timeout", "haproxy-decoder", new io.netty.handler.codec.haproxy.HAProxyMessageDecoder());
+ channel.pipeline().addAfter("haproxy-decoder", "haproxy-handler", new ChannelInboundHandlerAdapter() {
+ @Override
+ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+ if (msg instanceof io.netty.handler.codec.haproxy.HAProxyMessage message) {
+ if (message.command() == io.netty.handler.codec.haproxy.HAProxyCommand.PROXY) {
+ String realaddress = message.sourceAddress();
+ int realport = message.sourcePort();
+
+ SocketAddress socketaddr = new java.net.InetSocketAddress(realaddress, realport);
+
+ Connection connection = (Connection) channel.pipeline().get("packet_handler");
+ connection.address = socketaddr;
+ }
+ } else {
+ super.channelRead(ctx, msg);
+ }
+ }
+ });
+ }
+ // Paper end
+
// ServerConnectionListener.this.connections.add((Connection) object); // CraftBukkit - decompile error
pending.add((Connection) object); // Paper
channel.pipeline().addLast("packet_handler", (ChannelHandler) object);

View file

@ -1,46 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Mon, 30 May 2022 16:03:36 -0700
Subject: [PATCH] Fix OfflinePlayer#getBedSpawnLocation
When calling getBedSpawnLocation on an
instance of CraftOfflinePlayer the world was incorrect
due to the logic for reading the NBT not being up-to-date.
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
index 1f2bc88d4570c6ef00e67a772b745e0b0c98e051..50927403d07954f3b930b39046866899a1b289e6 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
@@ -28,6 +28,7 @@ import org.bukkit.profile.PlayerProfile;
@SerializableAs("Player")
public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializable {
+ private static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger(); // Paper
private final GameProfile profile;
private final CraftServer server;
private final PlayerDataStorage storage;
@@ -308,11 +309,20 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa
if (data == null) return null;
if (data.contains("SpawnX") && data.contains("SpawnY") && data.contains("SpawnZ")) {
- String spawnWorld = data.getString("SpawnWorld");
- if (spawnWorld.equals("")) {
- spawnWorld = this.server.getWorlds().get(0).getName();
+ // Paper start - fix wrong world
+ final float respawnAngle = data.getFloat("SpawnAngle");
+ org.bukkit.World spawnWorld = this.server.getWorld(data.getString("SpawnWorld")); // legacy
+ if (data.contains("SpawnDimension")) {
+ com.mojang.serialization.DataResult<net.minecraft.resources.ResourceKey<net.minecraft.world.level.Level>> result = net.minecraft.world.level.Level.RESOURCE_KEY_CODEC.parse(net.minecraft.nbt.NbtOps.INSTANCE, data.get("SpawnDimension"));
+ net.minecraft.resources.ResourceKey<net.minecraft.world.level.Level> levelKey = result.resultOrPartial(LOGGER::error).orElse(net.minecraft.world.level.Level.OVERWORLD);
+ net.minecraft.server.level.ServerLevel level = this.server.console.getLevel(levelKey);
+ spawnWorld = level != null ? level.getWorld() : spawnWorld;
}
- return new Location(this.server.getWorld(spawnWorld), data.getInt("SpawnX"), data.getInt("SpawnY"), data.getInt("SpawnZ"));
+ if (spawnWorld == null) {
+ return null;
+ }
+ return new Location(spawnWorld, data.getInt("SpawnX"), data.getInt("SpawnY"), data.getInt("SpawnZ"), respawnAngle, 0);
+ // Paper end
}
return null;
}

View file

@ -1,49 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sat, 1 Jan 2022 23:11:26 -0800
Subject: [PATCH] Fix FurnaceInventory for smokers and blast furnaces
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftTileInventoryConverter.java b/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftTileInventoryConverter.java
index 54e61b9b058bee2167461aaaf828ed7a00949c29..53421f780ac8bc2a67f64671fcad632fcdb8bede 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftTileInventoryConverter.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftTileInventoryConverter.java
@@ -65,7 +65,7 @@ public abstract class CraftTileInventoryConverter implements CraftInventoryCreat
return new CraftInventory(tileEntity);
}
- public static class Furnace extends CraftTileInventoryConverter {
+ public static class Furnace extends AbstractFurnaceInventoryConverter { // Paper - Furnace, BlastFurnace, and Smoker are pretty much identical
@Override
public Container getTileEntity() {
@@ -73,6 +73,11 @@ public abstract class CraftTileInventoryConverter implements CraftInventoryCreat
return furnace;
}
+ // Paper start - abstract furnace converter to apply to all 3 furnaces
+ }
+
+ public static abstract class AbstractFurnaceInventoryConverter extends CraftTileInventoryConverter {
+ // Paper end
// Paper start
@Override
public Inventory createInventory(InventoryHolder owner, InventoryType type, net.kyori.adventure.text.Component title) {
@@ -170,7 +175,7 @@ public abstract class CraftTileInventoryConverter implements CraftInventoryCreat
}
}
- public static class BlastFurnace extends CraftTileInventoryConverter {
+ public static class BlastFurnace extends AbstractFurnaceInventoryConverter { // Paper - Furnace, BlastFurnace, and Smoker are pretty much identical
@Override
public Container getTileEntity() {
@@ -186,7 +191,7 @@ public abstract class CraftTileInventoryConverter implements CraftInventoryCreat
}
}
- public static class Smoker extends CraftTileInventoryConverter {
+ public static class Smoker extends AbstractFurnaceInventoryConverter { // Paper - Furnace, BlastFurnace, and Smoker are pretty much identical
@Override
public Container getTileEntity() {

View file

@ -1,48 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Fri, 3 Dec 2021 16:55:50 -0500
Subject: [PATCH] Sanitize Sent BlockEntity NBT
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundBlockEntityDataPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundBlockEntityDataPacket.java
index 43220caaa331eade5b183f68f09d94542b4bc3db..8c87020e422acfb6b862d9d77e74114770f1b342 100644
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundBlockEntityDataPacket.java
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundBlockEntityDataPacket.java
@@ -17,7 +17,7 @@ public class ClientboundBlockEntityDataPacket implements Packet<ClientGamePacket
private final CompoundTag tag;
public static ClientboundBlockEntityDataPacket create(BlockEntity blockEntity, Function<BlockEntity, CompoundTag> nbtGetter) {
- return new ClientboundBlockEntityDataPacket(blockEntity.getBlockPos(), blockEntity.getType(), nbtGetter.apply(blockEntity));
+ return new ClientboundBlockEntityDataPacket(blockEntity.getBlockPos(), blockEntity.getType(), blockEntity.sanitizeSentNbt(nbtGetter.apply(blockEntity))); // Paper - Sanitize sent data
}
public static ClientboundBlockEntityDataPacket create(BlockEntity blockEntity) {
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 52f68d7611862b0e904305f8a16f04422b2b5b3f..07b64291c3b0390b746433dd42c32534a2b05018 100644
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
@@ -184,6 +184,7 @@ public class ClientboundLevelChunkPacketData {
BlockPos blockPos = blockEntity.getBlockPos();
if (blockEntity instanceof net.minecraft.world.level.block.entity.SkullBlockEntity) { net.minecraft.world.level.block.entity.SkullBlockEntity.sanitizeTileEntityUUID(compoundTag); } // Paper
int i = SectionPos.sectionRelative(blockPos.getX()) << 4 | SectionPos.sectionRelative(blockPos.getZ());
+ blockEntity.sanitizeSentNbt(compoundTag); // Paper - Sanitize sent data
return new ClientboundLevelChunkPacketData.BlockEntityInfo(i, blockPos.getY(), blockEntity.getType(), compoundTag.isEmpty() ? null : compoundTag);
}
}
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
index d62181bd8bccfcfdd7da8f635bdf7ebc36294705..b96d57b0bcf21508f8e03e96b7553eb486fdf212 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
@@ -256,4 +256,12 @@ public abstract class BlockEntity {
return null;
}
// CraftBukkit end
+ // Paper start
+ public CompoundTag sanitizeSentNbt(CompoundTag tag) {
+ tag.remove("PublicBukkitValues");
+
+ return tag;
+ }
+ // Paper end
+
}

View file

@ -1,69 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Sun, 6 Mar 2022 11:09:09 -0500
Subject: [PATCH] Prevent entity loading causing async lookups
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 86a2eddf344503cbe75a5243a114f6fe1578185f..dfd1f37757af1bd808cc2e2d8bf97123adf638bb 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -725,6 +725,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
public void baseTick() {
this.level.getProfiler().push("entityBaseTick");
+ if (firstTick && this instanceof net.minecraft.world.entity.NeutralMob neutralMob) neutralMob.tickInitialPersistentAnger(level); // Paper - Update last hurt when ticking
this.feetBlockState = null;
if (this.isPassenger() && this.getVehicle().isRemoved()) {
this.stopRiding();
diff --git a/src/main/java/net/minecraft/world/entity/NeutralMob.java b/src/main/java/net/minecraft/world/entity/NeutralMob.java
index dedf76de5d6f46b9626ca4a98cfffe125b90dd0c..78632fd681049fbd49d0030c23ed204dbc515a44 100644
--- a/src/main/java/net/minecraft/world/entity/NeutralMob.java
+++ b/src/main/java/net/minecraft/world/entity/NeutralMob.java
@@ -42,18 +42,7 @@ public interface NeutralMob {
UUID uuid = nbt.getUUID("AngryAt");
this.setPersistentAngerTarget(uuid);
- Entity entity = ((ServerLevel) world).getEntity(uuid);
-
- if (entity != null) {
- if (entity instanceof Mob) {
- this.setLastHurtByMob((Mob) entity);
- }
-
- if (entity.getType() == EntityType.PLAYER) {
- this.setLastHurtByPlayer((Player) entity);
- }
-
- }
+ // Paper - Moved diff to separate method
}
}
}
@@ -127,4 +116,26 @@ public interface NeutralMob {
@Nullable
LivingEntity getTarget();
+
+ // Paper start - Update last hurt when ticking
+ default void tickInitialPersistentAnger(Level level) {
+ UUID target = getPersistentAngerTarget();
+ if (target == null) {
+ return;
+ }
+
+ Entity entity = ((ServerLevel) level).getEntity(target);
+
+ if (entity != null) {
+ if (entity instanceof Mob) {
+ this.setLastHurtByMob((Mob) entity);
+ }
+
+ if (entity.getType() == EntityType.PLAYER) {
+ this.setLastHurtByPlayer((Player) entity);
+ }
+
+ }
+ }
+ // Paper end
}

View file

@ -1,70 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nassim Jahnke <jahnke.nassim@gmail.com>
Date: Thu, 2 Jun 2022 20:35:58 +0200
Subject: [PATCH] Disable component selector resolving in books by default
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index fafbebbb5e8c1a381b673f97f1fa210687b52823..8379c6313f06ab3eeaf02bad41d8b835d50e093f 100644
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -693,4 +693,9 @@ public class PaperConfig {
private static void useProxyProtocol() {
useProxyProtocol = getBoolean("settings.proxy-protocol", false);
}
+
+ public static boolean resolveSelectorsInBooks;
+ private static void resolveSelectorsInBooks() {
+ resolveSelectorsInBooks = getBoolean("settings.resolve-selectors-in-books", false);
+ }
}
diff --git a/src/main/java/net/minecraft/world/item/WrittenBookItem.java b/src/main/java/net/minecraft/world/item/WrittenBookItem.java
index 0600bfcc3a4f9043324c046b6c0d2b579ab151cb..26a9a15cc630113cd8d2c8287c6b0f1067ce53f0 100644
--- a/src/main/java/net/minecraft/world/item/WrittenBookItem.java
+++ b/src/main/java/net/minecraft/world/item/WrittenBookItem.java
@@ -113,25 +113,42 @@ public class WrittenBookItem extends Item {
public static boolean resolveBookComponents(ItemStack book, @Nullable CommandSourceStack commandSource, @Nullable Player player) {
CompoundTag compoundTag = book.getTag();
- if (compoundTag != null && !compoundTag.getBoolean("resolved")) {
+ if (com.destroystokyo.paper.PaperConfig.resolveSelectorsInBooks && compoundTag != null && !compoundTag.getBoolean("resolved")) { // Paper
compoundTag.putBoolean("resolved", true);
if (!makeSureTagIsValid(compoundTag)) {
return false;
} else {
ListTag listTag = compoundTag.getList("pages", 8);
+ // Paper start - backport length limit
+ ListTag newPages = new ListTag();
for(int i = 0; i < listTag.size(); ++i) {
- listTag.set(i, (Tag)StringTag.valueOf(resolvePage(commandSource, player, listTag.getString(i))));
+ String resolvedPage = resolvePage(commandSource, player, listTag.getString(i));
+ if (resolvedPage.length() > 32767) {
+ return false;
+ }
+
+ newPages.add(i, StringTag.valueOf(resolvedPage));
}
if (compoundTag.contains("filtered_pages", 10)) {
CompoundTag compoundTag2 = compoundTag.getCompound("filtered_pages");
+ CompoundTag newFilteredPages = new CompoundTag();
for(String string : compoundTag2.getAllKeys()) {
- compoundTag2.putString(string, resolvePage(commandSource, player, compoundTag2.getString(string)));
+ String resolvedPage = resolvePage(commandSource, player, compoundTag2.getString(string));
+ if (resolvedPage.length() > 32767) {
+ return false;
+ }
+
+ newFilteredPages.putString(string, resolvedPage);
}
+
+ compoundTag.put("filtered_pages", newFilteredPages);
}
+ compoundTag.put("pages", newPages);
+ // Paper end
return true;
}
} else {

View file

@ -1,48 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Tue, 22 Mar 2022 12:44:30 -0700
Subject: [PATCH] Throw exception on world create while being ticked
There are no plans to support creating worlds while worlds are
being ticked themselvess.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index c8d56947305c981a3268ce4ae3e975db350ceff2..da15a224b8b974e78b9d8d5f514229b3b2a5a63e 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -308,6 +308,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public volatile Thread shutdownThread; // Paper
public volatile boolean abnormalExit = false; // Paper
+ public boolean isIteratingOverLevels = false; // Paper
public static <S extends MinecraftServer> S spin(Function<Thread, S> serverFactory) {
AtomicReference<S> atomicreference = new AtomicReference();
@@ -1567,6 +1568,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Paper end
MinecraftTimings.timeUpdateTimer.stopTiming(); // Spigot // Paper
+ this.isIteratingOverLevels = true; // Paper
while (iterator.hasNext()) {
ServerLevel worldserver = (ServerLevel) iterator.next();
worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
@@ -1614,6 +1616,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.profiler.pop();
worldserver.explosionDensityCache.clear(); // Paper - Optimize explosions
}
+ this.isIteratingOverLevels = false; // Paper
this.profiler.popPush("connection");
MinecraftTimings.connectionTimer.startTiming(); // Spigot
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index c3f15ee7505e82418d9659ba3cee4f807546e0db..8a248e34fce1e04de4460f98b7627df495c66af1 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1135,6 +1135,7 @@ public final class CraftServer implements Server {
@Override
public World createWorld(WorldCreator creator) {
Preconditions.checkState(!console.levels.isEmpty(), "Cannot create additional worlds on STARTUP");
+ Preconditions.checkState(!this.console.isIteratingOverLevels, "Cannot create a world while worlds are being ticked"); // Paper
Validate.notNull(creator, "Creator may not be null");
String name = creator.name();