This commit is contained in:
Noah van der Aa 2024-10-23 23:12:09 +02:00
parent cb79de80c4
commit 1dc142534d
No known key found for this signature in database
GPG key ID: 547D90BC6FF753CF
44 changed files with 194 additions and 194 deletions

View file

@ -8,7 +8,7 @@ snow bucket didn't revert grass that became snowy because of the
placement.
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
index 8c9ae9ac38def29ae4cd8944395e566e434d46d0..9289faebce6b1546af71aeadc6569d2595b486e0 100644
index 8c9ae9ac38def29ae4cd8944395e566e434d46d0..a100c7a53b4b1dac0a01ee65418d44297bcdb93f 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
@@ -425,7 +425,7 @@ public final class ItemStack implements DataComponentHolder {
@ -25,7 +25,7 @@ index 8c9ae9ac38def29ae4cd8944395e566e434d46d0..9289faebce6b1546af71aeadc6569d25
if (blocks.size() > 1) {
placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(world, entityhuman, enumhand, blocks, blockposition.getX(), blockposition.getY(), blockposition.getZ());
- } else if (blocks.size() == 1) {
+ } else if (blocks.size() == 1 && item != Items.POWDER_SNOW_BUCKET) { // Paper - Fix cancelled powdered snow bucket placement
+ } else if (blocks.size() == 1 && item != Items.POWDER_SNOW_BUCKET) { // Paper - Fix cancelled powdered snow bucket placement
placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, enumhand, blocks.get(0), blockposition.getX(), blockposition.getY(), blockposition.getZ());
}

View file

@ -10,23 +10,23 @@ so we do not need that. The client only needs the chunk it is currently in to
be loaded to close the loading screen, so we just send an empty one.
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index f34cad30c982f2bb563f0deab030111720858fa8..f65b583057d37ec64a7cd9ed3ec09448064576db 100644
index f34cad30c982f2bb563f0deab030111720858fa8..f64a4693855899409a0ba7ec15ca0b0351febdd3 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -179,6 +179,16 @@ public abstract class PlayerList {
this.registries = registryManager;
this.maxPlayers = maxPlayers;
this.playerIo = saveHandler;
@@ -407,6 +407,16 @@ public abstract class PlayerList {
}
// Paper end - Configurable player collision
PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), s1, player.getId(), worldserver1.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ());
+ // Paper start - Send empty chunk, so players aren't stuck in the world loading screen with our chunk system not sending chunks when dead
+ if (player.isDeadOrDying()) {
+ net.minecraft.core.Holder<net.minecraft.world.level.biome.Biome> plains = worldserver1.registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.BIOME)
+ .getHolderOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS);
+ net.minecraft.core.Holder<net.minecraft.world.level.biome.Biome> plains = worldserver1.registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.BIOME)
+ .getHolderOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS);
+ player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket(
+ new net.minecraft.world.level.chunk.EmptyLevelChunk(worldserver1, player.chunkPosition(), plains),
+ worldserver1.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null)
+ new net.minecraft.world.level.chunk.EmptyLevelChunk(worldserver1, player.chunkPosition(), plains),
+ worldserver1.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null)
+ );
+ }
+ // Paper end - Send empty chunk
}
abstract public void loadAndSaveFiles(); // Paper - fix converting txt to json file; moved from DedicatedPlayerList constructor
public void updateEntireScoreboard(ServerScoreboard scoreboard, ServerPlayer player) {

View file

@ -6,7 +6,7 @@ Subject: [PATCH] Use username instead of display name in
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index f65b583057d37ec64a7cd9ed3ec09448064576db..b36edfa81b504107c4225234e3a1d48984e1d241 100644
index f64a4693855899409a0ba7ec15ca0b0351febdd3..f0ce0041497d038c55019e0f5a8e8b8619cec398 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -1354,7 +1354,7 @@ public abstract class PlayerList {

View file

@ -5,7 +5,7 @@ Subject: [PATCH] Expand PlayerItemDamageEvent
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
index 9289faebce6b1546af71aeadc6569d2595b486e0..fd49ff4ec22e4bdd3cd1aff0a6a2d2178d773bf2 100644
index a100c7a53b4b1dac0a01ee65418d44297bcdb93f..bcb3a45166e5dd75dd727adf92304b3a75399c8d 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
@@ -693,10 +693,11 @@ public final class ItemStack implements DataComponentHolder {

View file

@ -0,0 +1,54 @@
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 e000a918230187f6841b03b7b0dd73687f3cc15e..5c3e5c348e6fececccd8097355f423b9e7ad982b 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
@@ -427,12 +427,16 @@ public class ServerPlayerGameMode {
block.destroy(this.level, pos, iblockdata1);
}
+ ItemStack mainHandStack = null; // Paper - Trigger bee_nest_destroyed trigger in the correct place
+ boolean isCorrectTool = false; // Paper - Trigger bee_nest_destroyed trigger in the correct place
if (this.isCreative()) {
// return true; // CraftBukkit
} else {
ItemStack itemstack = this.player.getMainHandItem();
ItemStack itemstack1 = itemstack.copy();
boolean flag1 = this.player.hasCorrectToolForDrops(iblockdata1);
+ mainHandStack = itemstack1; // Paper - Trigger bee_nest_destroyed trigger in the correct place
+ isCorrectTool = flag1; // Paper - Trigger bee_nest_destroyed trigger in the correct place
itemstack.mineBlock(this.level, iblockdata1, pos, this.player);
if (flag && flag1 && event.isDropItems()) { // CraftBukkit - Check if block should drop items
@@ -453,6 +457,13 @@ public class ServerPlayerGameMode {
if (flag && event != null) {
iblockdata.getBlock().popExperience(this.level, pos, event.getExpToDrop(), this.player); // Paper
}
+ // Paper start - Trigger bee_nest_destroyed trigger in the correct place (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 - Trigger bee_nest_destroyed trigger in the correct place
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 a5b84e6844e16cf1fdfb6f45efb8a7a165757d1c..90f69a0c4d0707fd2319db71aea7dfdc14636d82 100644
--- a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java
@@ -103,7 +103,7 @@ public class BeehiveBlock extends BaseEntityBlock {
this.angerNearbyBees(world, pos);
}
- CriteriaTriggers.BEE_NEST_DESTROYED.trigger((ServerPlayer) player, state, tool, tileentitybeehive.getOccupantCount());
+ // CriteriaTriggers.BEE_NEST_DESTROYED.trigger((ServerPlayer) player, state, tool, tileentitybeehive.getOccupantCount()); // Paper - Trigger bee_nest_destroyed trigger in the correct place; moved until after items are dropped
}
}

View file

@ -0,0 +1,43 @@
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 5a86530c65d7d83e4608600a04ffd931bf59dc4a..bffc7c21727a6e5ff13a498aa51f6797e4d6d596 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Cat.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Cat.java
@@ -387,6 +387,13 @@ public class Cat extends TamableAnimal implements VariantHolder<Holder<CatVarian
DyeColor enumcolor = itemdye.getDyeColor();
if (enumcolor != this.getCollarColor()) {
+ // Paper start - Add EntityDyeEvent and CollarColorable interface
+ 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 - Add EntityDyeEvent and CollarColorable interface
if (!this.level().isClientSide()) {
this.setCollarColor(enumcolor);
itemstack.consume(1, player);
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 456eb5776fd15b14b68f02a0ae84610410c11d07..fc19bd326f00d1e8bd08ef6cc430c555337a6e3d 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Wolf.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Wolf.java
@@ -432,6 +432,14 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder<Hol
DyeColor enumcolor = itemdye.getDyeColor();
if (enumcolor != this.getCollarColor()) {
+ // Paper start - Add EntityDyeEvent and CollarColorable interface
+ 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 - Add EntityDyeEvent and CollarColorable interface
+
this.setCollarColor(enumcolor);
itemstack.consume(1, player);
return InteractionResult.SUCCESS;

View file

@ -0,0 +1,122 @@
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/core/cauldron/CauldronInteraction.java b/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java
index 637fef0d3cabc867cf861b507b90221e27a711d1..df76185d42075834a39c79515917e03beb938a06 100644
--- a/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java
+++ b/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java
@@ -74,7 +74,7 @@ public interface CauldronInteraction {
if (potioncontents != null && potioncontents.is(Potions.WATER)) {
if (!world.isClientSide) {
// CraftBukkit start
- if (!LayeredCauldronBlock.changeLevel(iblockdata, world, blockposition, Blocks.WATER_CAULDRON.defaultBlockState(), entityhuman, CauldronLevelChangeEvent.ChangeReason.BOTTLE_EMPTY)) {
+ if (!LayeredCauldronBlock.changeLevel(iblockdata, world, blockposition, Blocks.WATER_CAULDRON.defaultBlockState(), entityhuman, CauldronLevelChangeEvent.ChangeReason.BOTTLE_EMPTY, false)) { // Paper - Call CauldronLevelChangeEvent
return InteractionResult.SUCCESS;
}
// CraftBukkit end
@@ -129,7 +129,7 @@ public interface CauldronInteraction {
if (potioncontents != null && potioncontents.is(Potions.WATER)) {
if (!world.isClientSide) {
// CraftBukkit start
- if (!LayeredCauldronBlock.changeLevel(iblockdata, world, blockposition, iblockdata.cycle(LayeredCauldronBlock.LEVEL), entityhuman, CauldronLevelChangeEvent.ChangeReason.BOTTLE_EMPTY)) {
+ if (!LayeredCauldronBlock.changeLevel(iblockdata, world, blockposition, iblockdata.cycle(LayeredCauldronBlock.LEVEL), entityhuman, CauldronLevelChangeEvent.ChangeReason.BOTTLE_EMPTY, false)) { // Paper - Call CauldronLevelChangeEvent
return InteractionResult.SUCCESS;
}
// CraftBukkit end
@@ -215,7 +215,7 @@ public interface CauldronInteraction {
} else {
if (!world.isClientSide) {
// CraftBukkit start
- if (!LayeredCauldronBlock.changeLevel(state, world, pos, Blocks.CAULDRON.defaultBlockState(), player, CauldronLevelChangeEvent.ChangeReason.BUCKET_FILL)) {
+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, Blocks.CAULDRON.defaultBlockState(), player, CauldronLevelChangeEvent.ChangeReason.BUCKET_FILL, false)) { // Paper - Call CauldronLevelChangeEvent
return InteractionResult.SUCCESS;
}
// CraftBukkit end
@@ -236,7 +236,7 @@ public interface CauldronInteraction {
static InteractionResult emptyBucket(Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, BlockState state, SoundEvent soundEvent) {
if (!world.isClientSide) {
// CraftBukkit start
- if (!LayeredCauldronBlock.changeLevel(state, world, pos, state, player, CauldronLevelChangeEvent.ChangeReason.BUCKET_EMPTY)) {
+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, state, player, CauldronLevelChangeEvent.ChangeReason.BUCKET_EMPTY, false)) { // Paper - Call CauldronLevelChangeEvent
return InteractionResult.SUCCESS;
}
// CraftBukkit end
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 8d5ad9848d9652b4fd7179c425c47a683ee169ef..c9968934f4ecaa8d81e545f279b3001c7b1ce545 100644
--- a/src/main/java/net/minecraft/world/level/block/CauldronBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/CauldronBlock.java
@@ -44,9 +44,19 @@ 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) {
+ // Paper start - Call CauldronLevelChangeEvent
+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, Blocks.WATER_CAULDRON.defaultBlockState(), null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL, false)) { // avoid duplicate game event
+ return;
+ }
+ // Paper end - Call CauldronLevelChangeEvent
world.setBlockAndUpdate(pos, Blocks.WATER_CAULDRON.defaultBlockState());
world.gameEvent((Entity) null, (Holder) GameEvent.BLOCK_CHANGE, pos);
} else if (precipitation == Biome.Precipitation.SNOW) {
+ // Paper start - Call CauldronLevelChangeEvent
+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, Blocks.POWDER_SNOW_CAULDRON.defaultBlockState(), null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL, false)) { // avoid duplicate game event
+ return;
+ }
+ // Paper end - Call CauldronLevelChangeEvent
world.setBlockAndUpdate(pos, Blocks.POWDER_SNOW_CAULDRON.defaultBlockState());
world.gameEvent((Entity) null, (Holder) GameEvent.BLOCK_CHANGE, pos);
}
@@ -65,11 +75,19 @@ public class CauldronBlock extends AbstractCauldronBlock {
if (fluid == Fluids.WATER) {
iblockdata1 = Blocks.WATER_CAULDRON.defaultBlockState();
- LayeredCauldronBlock.changeLevel(state, world, pos, iblockdata1, null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL); // CraftBukkit
+ // Paper start - Call CauldronLevelChangeEvent; don't send level event or game event if cancelled
+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, iblockdata1, null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL)) { // CraftBukkit
+ return;
+ }
+ // Paper end - Call CauldronLevelChangeEvent
world.levelEvent(1047, pos, 0);
} else if (fluid == Fluids.LAVA) {
iblockdata1 = Blocks.LAVA_CAULDRON.defaultBlockState();
- LayeredCauldronBlock.changeLevel(state, world, pos, iblockdata1, null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL); // CraftBukkit
+ // Paper start - Call CauldronLevelChangeEvent; don't send level event or game event if cancelled
+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, iblockdata1, null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL)) { // CraftBukkit
+ return;
+ }
+ // Paper end - Call CauldronLevelChangeEvent
world.levelEvent(1046, pos, 0);
}
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 4ab73a083eba2ad3e12526af0a0dbcfba5cf6c14..806d18689126d0a971665a33d7fc91102ec76db5 100644
--- a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
@@ -107,7 +107,13 @@ public class LayeredCauldronBlock extends AbstractCauldronBlock {
}
// CraftBukkit start
- public static boolean changeLevel(BlockState iblockdata, Level world, BlockPos blockposition, BlockState newBlock, Entity entity, CauldronLevelChangeEvent.ChangeReason reason) {
+ // Paper start - Call CauldronLevelChangeEvent
+ public static boolean changeLevel(BlockState iblockdata, Level world, BlockPos blockposition, BlockState newBlock, @javax.annotation.Nullable Entity entity, CauldronLevelChangeEvent.ChangeReason reason) { // Paper - entity is nullable
+ return changeLevel(iblockdata, world, blockposition, newBlock, entity, reason, true);
+ }
+
+ public static boolean changeLevel(BlockState iblockdata, Level world, BlockPos blockposition, BlockState newBlock, @javax.annotation.Nullable Entity entity, CauldronLevelChangeEvent.ChangeReason reason, boolean sendGameEvent) { // Paper - entity is nullable
+ // Paper end - Call CauldronLevelChangeEvent
CraftBlockState newState = CraftBlockStates.getBlockState(world, blockposition);
newState.setData(newBlock);
@@ -120,7 +126,7 @@ public class LayeredCauldronBlock extends AbstractCauldronBlock {
return false;
}
newState.update(true);
- world.gameEvent((Holder) GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(newBlock));
+ if (sendGameEvent) world.gameEvent((Holder) GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(newBlock)); // Paper - Call CauldronLevelChangeEvent
return true;
}
// CraftBukkit end

View file

@ -0,0 +1,45 @@
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 806d18689126d0a971665a33d7fc91102ec76db5..7dd6b7c0ea472cfbc7ece55bc64bc5d85be4a6c0 100644
--- a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
@@ -73,7 +73,7 @@ public class LayeredCauldronBlock extends AbstractCauldronBlock {
// CraftBukkit start - moved down
// entity.clearFire();
if (entity.mayInteract(worldserver, pos)) {
- if (this.handleEntityOnFireInside(state, world, pos, entity)) {
+ if (this.handleEntityOnFireInsideWithEvent(state, world, pos, entity)) { // Paper - fix powdered snow cauldron extinguishing entities
entity.clearFire();
}
// CraftBukkit end
@@ -84,6 +84,7 @@ public class LayeredCauldronBlock extends AbstractCauldronBlock {
}
// CraftBukkit start
+ @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper - fix powdered snow cauldron extinguishing entities; use #handleEntityOnFireInsideWithEvent
private boolean handleEntityOnFireInside(BlockState iblockdata, Level world, BlockPos blockposition, Entity entity) {
if (this.precipitationType == Biome.Precipitation.SNOW) {
return LayeredCauldronBlock.lowerFillLevel((BlockState) Blocks.WATER_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, (Integer) iblockdata.getValue(LayeredCauldronBlock.LEVEL)), world, blockposition, entity, CauldronLevelChangeEvent.ChangeReason.EXTINGUISH);
@@ -93,6 +94,15 @@ public class LayeredCauldronBlock extends AbstractCauldronBlock {
}
}
+ // Paper start - fix powdered snow cauldron extinguishing entities
+ protected boolean handleEntityOnFireInsideWithEvent(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (this.precipitationType == Biome.Precipitation.SNOW) {
+ return LayeredCauldronBlock.lowerFillLevel((BlockState) Blocks.WATER_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, (Integer) state.getValue(LayeredCauldronBlock.LEVEL)), world, pos, entity, CauldronLevelChangeEvent.ChangeReason.EXTINGUISH);
+ } else {
+ return LayeredCauldronBlock.lowerFillLevel(state, world, pos, entity, CauldronLevelChangeEvent.ChangeReason.EXTINGUISH);
+ }
+ }
+ // Paper end - fix powdered snow cauldron extinguishing entities
public static void lowerFillLevel(BlockState state, Level world, BlockPos pos) {
// CraftBukkit start

View file

@ -0,0 +1,18 @@
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 6598f119edc5d890dcc9d065478e7c52ac5a5183..682d0399b9b3729d16978eca258c55c2150afec7 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -4204,6 +4204,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
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 - Add PlayerStopUsingItemEvent
this.useItem.releaseUsing(this.level(), this, this.getUseItemRemainingTicks());
if (this.useItem.useOnRelease()) {
this.updatingUsingItem();

View file

@ -0,0 +1,36 @@
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 and https://github.com/PaperMC/Paper/issues/8118
by using a config option that, when set to false, does not add markers to the entity
tick list at all and ignores 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. When the config option is set to true, markers are ticked as normal.
diff --git a/src/main/java/io/papermc/paper/command/subcommands/EntityCommand.java b/src/main/java/io/papermc/paper/command/subcommands/EntityCommand.java
index 67fcba634f8183bb33834ac3b2c3dcfb8d87129e..777b789fdcdf297309cfb36fc7f77e3fdb6327ca 100644
--- a/src/main/java/io/papermc/paper/command/subcommands/EntityCommand.java
+++ b/src/main/java/io/papermc/paper/command/subcommands/EntityCommand.java
@@ -109,7 +109,7 @@ public final class EntityCommand implements PaperSubcommand {
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 && !world.paperConfig().entities.markers.tick)) { // Paper - Configurable marker ticking
nonEntityTicking.merge(key, 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 f46393f68ce7ff45302d6aef78b33b18fd10339b..d226b51933d25f9a31f285d7715d162302835b02 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -2249,6 +2249,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
}
public void onTickingStart(Entity entity) {
+ if (entity instanceof net.minecraft.world.entity.Marker && !paperConfig().entities.markers.tick) return; // Paper - Configurable marker ticking
ServerLevel.this.entityTickList.add(entity);
}

View file

@ -0,0 +1,107 @@
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] Expand FallingBlock API
- add auto expire setting
- add setter for block data
- add accessors for block state
== AT ==
public net.minecraft.world.entity.item.FallingBlockEntity blockState
Co-authored-by: Lukas Planz <lukas.planz@web.de>
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 84d9ae7be1bc9b2c4940cc69de24abf7e4c228b3..c228ca3ee911d25932932564b73e182840963e7d 100644
--- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
+++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
@@ -71,6 +71,7 @@ public class FallingBlockEntity extends Entity {
public CompoundTag blockData;
public boolean forceTickAfterTeleportToDuplicate;
protected static final EntityDataAccessor<BlockPos> DATA_START_POS = SynchedEntityData.defineId(FallingBlockEntity.class, EntityDataSerializers.BLOCK_POS);
+ public boolean autoExpire = true; // Paper - Expand FallingBlock API
public FallingBlockEntity(EntityType<? extends FallingBlockEntity> type, Level world) {
super(type, world);
@@ -191,7 +192,7 @@ public class FallingBlockEntity extends Entity {
}
if (!this.onGround() && !flag1) {
- if (this.time > 100 && (blockposition.getY() <= this.level().getMinY() || blockposition.getY() > this.level().getMaxY()) || this.time > 600) {
+ if ((this.time > 100 && autoExpire) && (blockposition.getY() <= this.level().getMinY() || blockposition.getY() > this.level().getMaxY()) || (this.time > 600 && autoExpire)) { // Paper - Expand FallingBlock API
if (this.dropItem && worldserver.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) {
this.spawnAtLocation(worldserver, (ItemLike) block);
}
@@ -338,6 +339,7 @@ public class FallingBlockEntity extends Entity {
}
nbt.putBoolean("CancelDrop", this.cancelDrop);
+ if (!autoExpire) {nbt.putBoolean("Paper.AutoExpire", false);} // Paper - Expand FallingBlock API
}
@Override
@@ -365,6 +367,11 @@ public class FallingBlockEntity extends Entity {
this.blockState = Blocks.SAND.defaultBlockState();
}
+ // Paper start - Expand FallingBlock API
+ if (nbt.contains("Paper.AutoExpire")) {
+ this.autoExpire = nbt.getBoolean("Paper.AutoExpire");
+ }
+ // Paper end - Expand FallingBlock API
}
public void setHurtsEntities(float fallHurtAmount, int fallHurtMax) {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFallingBlock.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFallingBlock.java
index a7a3f74b846112d752fe04162b30805961457b11..1359d25a32b4a5d5e8e68ce737bd19f7b5afaf69 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFallingBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFallingBlock.java
@@ -33,6 +33,31 @@ public class CraftFallingBlock extends CraftEntity implements FallingBlock {
public BlockData getBlockData() {
return CraftBlockData.fromData(this.getHandle().getBlockState());
}
+ // Paper start - Expand FallingBlock API
+ @Override
+ public void setBlockData(final BlockData blockData) {
+ Preconditions.checkArgument(blockData != null, "blockData");
+ final net.minecraft.world.level.block.state.BlockState oldState = this.getHandle().blockState, newState = ((CraftBlockData) blockData).getState();
+ this.getHandle().blockState = newState;
+ this.getHandle().blockData = null;
+
+ if (oldState != newState) this.update();
+ }
+
+ @Override
+ public org.bukkit.block.BlockState getBlockState() {
+ return org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(this.getHandle().blockState, this.getHandle().blockData);
+ }
+
+ @Override
+ public void setBlockState(final org.bukkit.block.BlockState blockState) {
+ Preconditions.checkArgument(blockState != null, "blockState");
+ // Calls #update if needed, the block data compound tag is not synced with the client and hence can be mutated after the sync with clients.
+ // The call also clears any potential old block data.
+ this.setBlockData(blockState.getBlockData());
+ if (blockState instanceof final org.bukkit.craftbukkit.block.CraftBlockEntityState<?> tileEntity) this.getHandle().blockData = tileEntity.getSnapshotNBT();
+ }
+ // Paper end - Expand FallingBlock API
@Override
public boolean getDropItem() {
@@ -101,4 +126,15 @@ public class CraftFallingBlock extends CraftEntity implements FallingBlock {
this.setHurtEntities(true);
}
}
+ // Paper start - Expand FallingBlock API
+ @Override
+ public boolean doesAutoExpire() {
+ return this.getHandle().autoExpire;
+ }
+
+ @Override
+ public void shouldAutoExpire(boolean autoExpires) {
+ this.getHandle().autoExpire = autoExpires;
+ }
+ // Paper end - Expand FallingBlock API
}

View file

@ -0,0 +1,65 @@
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/build.gradle.kts b/build.gradle.kts
index 38585b7f0b8e1e287b37820924a1b0d464fe9e99..25001d6cf4f70bd01ab304625b49ec45f5b1f525 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -28,6 +28,7 @@ dependencies {
log4jPlugins.annotationProcessorConfigurationName("org.apache.logging.log4j:log4j-core:2.19.0") // Paper - Needed to generate meta for our Log4j plugins
runtimeOnly(log4jPlugins.output)
alsoShade(log4jPlugins.output)
+ implementation("io.netty:netty-codec-haproxy:4.1.97.Final") // Paper - Add support for proxy protocol
// Paper end
implementation("org.apache.logging.log4j:log4j-iostreams:2.22.1") // Paper - remove exclusion
implementation("org.ow2.asm:asm-commons:9.7.1")
diff --git a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
index c63c194c44646e6bc1a59426552787011fc2ced5..c62df32af11636ad408b584fcc590590ce4fb0d0 100644
--- a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
+++ b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
@@ -104,6 +104,12 @@ public class ServerConnectionListener {
ServerConnectionListener.LOGGER.info("Using default channel type");
}
+ // Paper start - Warn people with console access that HAProxy is in use.
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.proxyProtocol) {
+ ServerConnectionListener.LOGGER.warn("Using HAProxy, please ensure the server port is adequately firewalled.");
+ }
+ // Paper end - Warn people with console access that HAProxy is in use.
+
this.channels.add(((ServerBootstrap) ((ServerBootstrap) (new ServerBootstrap()).channel(oclass)).childHandler(new ChannelInitializer<Channel>() {
protected void initChannel(Channel channel) {
try {
@@ -123,6 +129,29 @@ public class ServerConnectionListener {
Connection object = j > 0 ? new RateKickingConnection(j) : new Connection(PacketFlow.SERVERBOUND); // CraftBukkit - decompile error
//ServerConnectionListener.this.connections.add(object); // Paper
+ // Paper start - Add support for Proxy Protocol
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.proxyProtocol) {
+ 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 - Add support for proxy protocol
pending.add(object); // Paper - prevent blocking on adding a new connection while the server is ticking
((Connection) object).configurePacketHandler(channelpipeline);
((Connection) object).setListenerForServerboundHandshake(new ServerHandshakePacketListenerImpl(ServerConnectionListener.this.server, (Connection) object));

View file

@ -0,0 +1,46 @@
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 e0d342a0ddd140b342f7af138c71596c6d718788..30c1c203022c2ed777dcddfd68ef2e3752c62ea1 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
@@ -37,6 +37,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;
@@ -361,11 +362,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

@ -0,0 +1,49 @@
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 a6c758c5c5da2fb3f2d251bc109f72a5d8b0eb14..ad2cb9a1352abd855bf11a390c9788835857380a 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 - abstract furnace converter to apply to all 3 furnaces
// 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

@ -0,0 +1,50 @@
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 4f3ba61f13dbe5773034a19e749b7c4f5dc3d291..5d3e739d28d394ed59fe0003245cc55ac62e6087 100644
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundBlockEntityDataPacket.java
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundBlockEntityDataPacket.java
@@ -29,7 +29,7 @@ public class ClientboundBlockEntityDataPacket implements Packet<ClientGamePacket
public static ClientboundBlockEntityDataPacket create(BlockEntity blockEntity, BiFunction<BlockEntity, RegistryAccess, CompoundTag> nbtGetter) {
RegistryAccess registryAccess = blockEntity.getLevel().registryAccess();
- return new ClientboundBlockEntityDataPacket(blockEntity.getBlockPos(), blockEntity.getType(), nbtGetter.apply(blockEntity, registryAccess));
+ return new ClientboundBlockEntityDataPacket(blockEntity.getBlockPos(), blockEntity.getType(), blockEntity.sanitizeSentNbt(nbtGetter.apply(blockEntity, registryAccess))); // 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 ac900dfdc5c90e9e60d47efa734be8f0a5b20dca..ec1cb034d840633240f2b379b09f7d2f1c8971a5 100644
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
@@ -154,6 +154,7 @@ public class ClientboundLevelChunkPacketData {
CompoundTag compoundTag = blockEntity.getUpdateTag(blockEntity.getLevel().registryAccess());
BlockPos blockPos = blockEntity.getBlockPos();
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 3de01d92e1c97e287a1f0d1f8de81b4f530b4a84..63e234fb72952dcede4eeaa5d3d3390d137d88a2 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
@@ -395,6 +395,14 @@ public abstract class BlockEntity {
}
// CraftBukkit end
+ // Paper start - Sanitize sent data
+ public CompoundTag sanitizeSentNbt(CompoundTag tag) {
+ tag.remove("PublicBukkitValues");
+
+ return tag;
+ }
+ // Paper end - Sanitize sent data
+
private static class ComponentHelper {
public static final Codec<DataComponentMap> COMPONENTS_CODEC = DataComponentMap.CODEC.optionalFieldOf("components", DataComponentMap.EMPTY).codec();

View file

@ -0,0 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nassim Jahnke <nassim@njahnke.dev>
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/net/minecraft/world/item/WrittenBookItem.java b/src/main/java/net/minecraft/world/item/WrittenBookItem.java
index a282c1cbbdf8e5ebac547b45a58116f9b4b2d49e..0c54100fb72b79e0eb4bad8f6851648e084d9260 100644
--- a/src/main/java/net/minecraft/world/item/WrittenBookItem.java
+++ b/src/main/java/net/minecraft/world/item/WrittenBookItem.java
@@ -41,7 +41,7 @@ public class WrittenBookItem extends Item {
public static boolean resolveBookComponents(ItemStack book, CommandSourceStack commandSource, @Nullable Player player) {
WrittenBookContent writtenBookContent = book.get(DataComponents.WRITTEN_BOOK_CONTENT);
- if (writtenBookContent != null && !writtenBookContent.resolved()) {
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().itemValidation.resolveSelectorsInBooks && writtenBookContent != null && !writtenBookContent.resolved()) { // Paper - Disable component selector resolving in books by default
WrittenBookContent writtenBookContent2 = writtenBookContent.resolve(commandSource, player);
if (writtenBookContent2 != null) {
book.set(DataComponents.WRITTEN_BOOK_CONTENT, writtenBookContent2);

View file

@ -0,0 +1,81 @@
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 325c8b178dfb39727107190e74663113ebb4ab54..71efd269ea055f13e3ca898bad045448e24f73da 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -724,6 +724,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
ProfilerFiller gameprofilerfiller = Profiler.get();
gameprofilerfiller.push("entityBaseTick");
+ if (firstTick && this instanceof net.minecraft.world.entity.NeutralMob neutralMob) neutralMob.tickInitialPersistentAnger(level); // Paper - Prevent entity loading causing async lookups
this.inBlockState = 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 bf577b06707ff197f13f0b5e16620c09d4a69fa8..053d947c4cc00096dae422df36fb8351b3266215 100644
--- a/src/main/java/net/minecraft/world/entity/NeutralMob.java
+++ b/src/main/java/net/minecraft/world/entity/NeutralMob.java
@@ -45,24 +45,11 @@ public interface NeutralMob {
UUID uuid = nbt.getUUID("AngryAt");
this.setPersistentAngerTarget(uuid);
- Entity entity = ((ServerLevel) world).getEntity(uuid);
-
- if (entity != null) {
- if (entity instanceof Mob) {
- Mob entityinsentient = (Mob) entity;
-
- this.setTarget(entityinsentient, EntityTargetEvent.TargetReason.UNKNOWN, false); // CraftBukkit
- this.setLastHurtByMob(entityinsentient);
- }
-
- if (entity instanceof Player) {
- Player entityhuman = (Player) entity;
-
- this.setTarget(entityhuman, EntityTargetEvent.TargetReason.UNKNOWN, false); // CraftBukkit
- this.setLastHurtByPlayer(entityhuman);
- }
-
- }
+ // Paper - Prevent entity loading causing async lookups; Moved diff to separate method
+ // If this entity already survived its first tick, e.g. is loaded and ticked in sync, actively
+ // tick the initial persistent anger.
+ // If not, let the first tick on the baseTick call the method later down the line.
+ if (this instanceof Entity entity && !entity.firstTick) this.tickInitialPersistentAnger(world);
}
}
}
@@ -136,4 +123,28 @@ public interface NeutralMob {
@Nullable
LivingEntity getTarget();
+
+ // Paper start - Prevent entity loading causing async lookups
+ // 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 mob) {
+ this.setTarget(mob, EntityTargetEvent.TargetReason.UNKNOWN, false); // CraftBukkit
+ this.setLastHurtByMob(mob);
+ }
+
+ if (entity instanceof Player player) {
+ this.setTarget(player, EntityTargetEvent.TargetReason.UNKNOWN, false); // CraftBukkit
+ this.setLastHurtByPlayer(player);
+ }
+ }
+ }
+ // Paper end - Prevent entity loading causing async lookups
}

View file

@ -0,0 +1,78 @@
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 0b9f4541cc0d0f27e811c1a6798d6758a2687b0c..2101c0a3b000a60733ceada248c202e2c4783af5 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -328,6 +328,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public final double[] recentTps = new double[ 3 ];
// Spigot end
public final io.papermc.paper.configuration.PaperConfigurations paperConfigurations; // Paper - add paper configuration files
+ public boolean isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked
public static <S extends MinecraftServer> S spin(Function<Thread, S> serverFactory) {
AtomicReference<S> atomicreference = new AtomicReference();
@@ -1658,7 +1659,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.getFunctions().tick();
MinecraftTimings.commandFunctionsTimer.stopTiming(); // Spigot // Paper
gameprofilerfiller.popPush("levels");
- Iterator iterator = this.getAllLevels().iterator();
+ //Iterator iterator = this.getAllLevels().iterator(); // Paper - Throw exception on world create while being ticked; moved down
// CraftBukkit start
// Run tasks that are waiting on processing
@@ -1690,6 +1691,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Paper end - Perf: Optimize time updates
MinecraftTimings.timeUpdateTimer.stopTiming(); // Spigot // Paper
+ this.isIteratingOverLevels = true; // Paper - Throw exception on world create while being ticked
+ Iterator iterator = this.getAllLevels().iterator(); // Paper - Throw exception on world create while being ticked; move down
while (iterator.hasNext()) {
ServerLevel worldserver = (ServerLevel) iterator.next();
worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - BlockPhysicsEvent
@@ -1724,6 +1727,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
gameprofilerfiller.pop();
gameprofilerfiller.pop();
}
+ this.isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked
gameprofilerfiller.popPush("connection");
MinecraftTimings.connectionTimer.startTiming(); // Spigot // Paper
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index b31f3013ff63bb6ece80a9d10e51641a7e93f3df..9921c1e03a9e4eb2153fd88d2932f7f4867e0a03 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -920,6 +920,11 @@ public final class CraftServer implements Server {
return new ArrayList<World>(this.worlds.values());
}
+ @Override
+ public boolean isTickingWorlds() {
+ return console.isIteratingOverLevels;
+ }
+
public DedicatedPlayerList getHandle() {
return this.playerList;
}
@@ -1183,6 +1188,7 @@ public final class CraftServer implements Server {
@Override
public World createWorld(WorldCreator creator) {
Preconditions.checkState(this.console.getAllLevels().iterator().hasNext(), "Cannot create additional worlds on STARTUP");
+ //Preconditions.checkState(!this.console.isIteratingOverLevels, "Cannot create a world while worlds are being ticked"); // Paper - Cat - Temp disable. We'll see how this goes.
Preconditions.checkArgument(creator != null, "WorldCreator cannot be null");
String name = creator.name();
@@ -1359,6 +1365,7 @@ public final class CraftServer implements Server {
@Override
public boolean unloadWorld(World world, boolean save) {
+ //Preconditions.checkState(!this.console.isIteratingOverLevels, "Cannot unload a world while worlds are being ticked"); // Paper - Cat - Temp disable. We'll see how this goes.
if (world == null) {
return false;
}

View file

@ -0,0 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Wed, 8 Jun 2022 11:04:47 -0400
Subject: [PATCH] Dont resent entity on art update
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java
index dd02cec9a82794a6b001c3b64f031f78d5fbb812..bcac1359c667ef1ee46384f9c7a5adf4010d2b08 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java
@@ -36,7 +36,7 @@ public class CraftPainting extends CraftHanging implements Painting {
painting.setDirection(painting.getDirection());
return false;
}
- this.update();
+ //this.update(); Paper - Don't resent entity on art update
return true;
}

View file

@ -0,0 +1,39 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: nopjar <code.nopjar@gmail.com>
Date: Sun, 12 Jun 2022 02:26:04 +0200
Subject: [PATCH] Add WardenAngerChangeEvent
diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/AngerManagement.java b/src/main/java/net/minecraft/world/entity/monster/warden/AngerManagement.java
index 27e52ee93ab591e97f37705de64cb5b62c06e253..3d792957f27fd4bdfad8d76262a8e2a2012bf35f 100644
--- a/src/main/java/net/minecraft/world/entity/monster/warden/AngerManagement.java
+++ b/src/main/java/net/minecraft/world/entity/monster/warden/AngerManagement.java
@@ -146,7 +146,7 @@ public class AngerManagement {
public int increaseAnger(Entity entity, int amount) {
boolean bl = !this.angerBySuspect.containsKey(entity);
- int i = this.angerBySuspect.computeInt(entity, (suspect, anger) -> Math.min(150, (anger == null ? 0 : anger) + amount));
+ int i = this.angerBySuspect.computeInt(entity, (suspect, anger) -> Math.min(150, (anger == null ? 0 : anger) + amount)); // Paper - diff on change (Warden#increaseAngerAt WardenAngerChangeEvent)
if (bl) {
int j = this.angerByUuid.removeInt(entity.getUUID());
i += j;
diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java
index 71311d30459d495c57e6fcf0115e4f34a232f1ad..6180019da58b19d2595da508aed3196af922d587 100644
--- a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java
+++ b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java
@@ -482,6 +482,15 @@ public class Warden extends Monster implements VibrationSystem {
@VisibleForTesting
public void increaseAngerAt(@Nullable Entity entity, int amount, boolean listening) {
if (!this.isNoAi() && this.canTargetEntity(entity)) {
+ // Paper start - Add WardenAngerChangeEvent
+ int activeAnger = this.angerManagement.getActiveAnger(entity);
+ io.papermc.paper.event.entity.WardenAngerChangeEvent event = new io.papermc.paper.event.entity.WardenAngerChangeEvent((org.bukkit.entity.Warden) this.getBukkitEntity(), entity.getBukkitEntity(), activeAnger, Math.min(150, activeAnger + amount));
+ this.level().getCraftServer().getPluginManager().callEvent(event);
+ if (event.isCancelled()) {
+ return;
+ }
+ amount = event.getNewAnger() - activeAnger;
+ // Paper end - Add WardenAngerChangeEvent
WardenAi.setDigCooldown(this);
boolean flag1 = !(this.getTarget() instanceof Player);
int j = this.angerManagement.increaseAnger(entity, amount);

View file

@ -0,0 +1,42 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sun, 12 Jun 2022 11:47:24 -0700
Subject: [PATCH] Add option for strict advancement dimension checks
Craftbukkit attempts to translate worlds that use the
same generation as the Overworld, The Nether, or The End
to use those dimensions when checking the `changed_dimension`
criteria trigger, or whether to trigger the `NETHER_TRAVEL`
distance trigger. This adds a config option to ignore that
and use the exact dimension key of the worlds involved.
diff --git a/src/main/java/net/minecraft/advancements/critereon/LocationPredicate.java b/src/main/java/net/minecraft/advancements/critereon/LocationPredicate.java
index 01b8f7024fbc965bc6a7f97f79ba3dec964ef769..801823d003a8e28a13fe90db4604cd0938899c6d 100644
--- a/src/main/java/net/minecraft/advancements/critereon/LocationPredicate.java
+++ b/src/main/java/net/minecraft/advancements/critereon/LocationPredicate.java
@@ -44,7 +44,7 @@ public record LocationPredicate(
public boolean matches(ServerLevel world, double x, double y, double z) {
if (this.position.isPresent() && !this.position.get().matches(x, y, z)) {
return false;
- } else if (this.dimension.isPresent() && this.dimension.get() != world.dimension()) {
+ } else if (this.dimension.isPresent() && this.dimension.get() != (io.papermc.paper.configuration.GlobalConfiguration.get().misc.strictAdvancementDimensionCheck ? world.dimension() : org.bukkit.craftbukkit.util.CraftDimensionUtil.getMainDimensionKey(world))) { // Paper - Add option for strict advancement dimension checks
return false;
} else {
BlockPos blockPos = BlockPos.containing(x, y, z);
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 84f4913c06bf9068a3a4d7400055031c474a4f7e..f87f12666d4708b7fb7ede3eff03570fed8d1f40 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -1655,6 +1655,12 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
ResourceKey<Level> maindimensionkey = CraftDimensionUtil.getMainDimensionKey(origin);
ResourceKey<Level> maindimensionkey1 = CraftDimensionUtil.getMainDimensionKey(this.level());
+ // Paper start - Add option for strict advancement dimension checks
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.strictAdvancementDimensionCheck) {
+ maindimensionkey = resourcekey;
+ maindimensionkey1 = resourcekey1;
+ }
+ // Paper end - Add option for strict advancement dimension checks
CriteriaTriggers.CHANGED_DIMENSION.trigger(this, maindimensionkey, maindimensionkey1);
if (maindimensionkey != resourcekey || maindimensionkey1 != resourcekey1) {
CriteriaTriggers.CHANGED_DIMENSION.trigger(this, resourcekey, resourcekey1);

View file

@ -0,0 +1,73 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Sun, 12 Jun 2022 13:25:52 -0400
Subject: [PATCH] Add missing important BlockStateListPopulator methods
Without these methods it causes exceptions due to these being used by certain feature generators.
diff --git a/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java b/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java
index 072d105f05f3b535d53cfbf8538d1716f9cfcd0e..4d6d637188ef4010a71ea2eb6ea0310aea820511 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java
@@ -129,7 +129,7 @@ public class BlockStateListPopulator extends DummyGeneratorAccess {
@Override
public boolean isFluidAtPosition(BlockPos pos, Predicate<FluidState> state) {
- return this.world.isFluidAtPosition(pos, state);
+ return state.test(this.getFluidState(pos)); // Paper - fix
}
@Override
@@ -152,4 +152,33 @@ public class BlockStateListPopulator extends DummyGeneratorAccess {
public long nextSubTickCount() {
return this.world.nextSubTickCount();
}
+
+ // Paper start
+ @Override
+ public <T extends BlockEntity> java.util.Optional<T> getBlockEntity(BlockPos pos, net.minecraft.world.level.block.entity.BlockEntityType<T> type) {
+ BlockEntity tileentity = this.getBlockEntity(pos);
+
+ return tileentity != null && tileentity.getType() == type ? (java.util.Optional<T>) java.util.Optional.of(tileentity) : java.util.Optional.empty();
+ }
+
+ @Override
+ public BlockPos getHeightmapPos(net.minecraft.world.level.levelgen.Heightmap.Types heightmap, BlockPos pos) {
+ return world.getHeightmapPos(heightmap, pos);
+ }
+
+ @Override
+ public int getHeight(net.minecraft.world.level.levelgen.Heightmap.Types heightmap, int x, int z) {
+ return world.getHeight(heightmap, x, z);
+ }
+
+ @Override
+ public int getRawBrightness(BlockPos pos, int ambientDarkness) {
+ return world.getRawBrightness(pos, ambientDarkness);
+ }
+
+ @Override
+ public int getBrightness(net.minecraft.world.level.LightLayer type, BlockPos pos) {
+ return world.getBrightness(type, pos);
+ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java
index 4705aed1dd98378c146bf9e346df1a17f719ad36..daf3c26fce7569761951bfd5594c6726d854a9ff 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java
@@ -258,4 +258,14 @@ public class DummyGeneratorAccess implements WorldGenLevel {
public boolean destroyBlock(BlockPos pos, boolean drop, Entity breakingEntity, int maxUpdateDepth) {
return false; // SPIGOT-6515
}
+
+ // Paper start - add more methods
+ public void scheduleTick(BlockPos pos, Fluid fluid, int delay) {}
+
+ @Override
+ public void scheduleTick(BlockPos pos, Block block, int delay, net.minecraft.world.ticks.TickPriority priority) {}
+
+ @Override
+ public void scheduleTick(BlockPos pos, Fluid fluid, int delay, net.minecraft.world.ticks.TickPriority priority) {}
+ // Paper end - add more methods
}

View file

@ -0,0 +1,50 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Thu, 7 Apr 2022 17:49:25 -0400
Subject: [PATCH] Nameable Banner API
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java
index 01521f38871d821762ff7ac2d39927f8c6b861bf..98bc87fe5d153cc4927f7e1b4a02f61d9dd019a0 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java
@@ -29,7 +29,7 @@ public class BannerBlockEntity extends BlockEntity implements Nameable {
public static final int MAX_PATTERNS = 6;
private static final String TAG_PATTERNS = "patterns";
@Nullable
- private Component name;
+ public Component name; // Paper - public
public DyeColor baseColor;
private BannerPatternLayers patterns;
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBanner.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBanner.java
index 5635230fc288fe5280bf785b42c862b8f111afb0..afed8bdb9bd6a135e9b5f7bd9bfc61964cb240f7 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBanner.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBanner.java
@@ -112,4 +112,26 @@ public class CraftBanner extends CraftBlockEntityState<BannerBlockEntity> implem
public CraftBanner copy(Location location) {
return new CraftBanner(this, location);
}
+
+ // Paper start
+ @Override
+ public net.kyori.adventure.text.Component customName() {
+ return io.papermc.paper.adventure.PaperAdventure.asAdventure(this.getSnapshot().getCustomName());
+ }
+
+ @Override
+ public void customName(net.kyori.adventure.text.Component customName) {
+ this.getSnapshot().name = io.papermc.paper.adventure.PaperAdventure.asVanilla(customName);
+ }
+
+ @Override
+ public String getCustomName() {
+ return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serializeOrNull(this.customName());
+ }
+
+ @Override
+ public void setCustomName(String name) {
+ this.customName(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserializeOrNull(name));
+ }
+ // Paper end
}

View file

@ -0,0 +1,34 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Thu, 16 Jun 2022 14:22:56 -0700
Subject: [PATCH] Don't broadcast messages to command blocks
Previously the broadcast method would update the last output
in command blocks, and if called asynchronously, would throw
an error
diff --git a/src/main/java/net/minecraft/world/level/BaseCommandBlock.java b/src/main/java/net/minecraft/world/level/BaseCommandBlock.java
index a0e59b236dff1f861a0e987764a77ee203504412..5cb39f95bd2d45b6c18554605f01d2ebf6473428 100644
--- a/src/main/java/net/minecraft/world/level/BaseCommandBlock.java
+++ b/src/main/java/net/minecraft/world/level/BaseCommandBlock.java
@@ -178,6 +178,7 @@ public abstract class BaseCommandBlock implements CommandSource {
@Override
public void sendSystemMessage(Component message) {
if (this.trackOutput) {
+ org.spigotmc.AsyncCatcher.catchOp("sendSystemMessage to a command block"); // Paper - Don't broadcast messages to command blocks
SimpleDateFormat simpledateformat = BaseCommandBlock.TIME_FORMAT;
Date date = new Date();
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 9921c1e03a9e4eb2153fd88d2932f7f4867e0a03..284ffa47223595b42d115533551821f379de6663 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1929,7 +1929,7 @@ public final class CraftServer implements Server {
// Paper end
Set<CommandSender> recipients = new HashSet<>();
for (Permissible permissible : this.getPluginManager().getPermissionSubscriptions(permission)) {
- if (permissible instanceof CommandSender && permissible.hasPermission(permission)) {
+ if (permissible instanceof CommandSender && !(permissible instanceof org.bukkit.command.BlockCommandSender) && permissible.hasPermission(permission)) { // Paper - Don't broadcast messages to command blocks
recipients.add((CommandSender) permissible);
}
}

View file

@ -0,0 +1,20 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Wed, 15 Jun 2022 21:52:57 -0400
Subject: [PATCH] Prevent empty items from being added to world
The previous solution caused a bunch of bandaid fixes inorder to resolve edge cases where minecraft/the api might spawn items that are air.
Just simply prevent them from being added to the world instead.
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index d226b51933d25f9a31f285d7715d162302835b02..100661b77466152a651d22daa7df992c28fbbecb 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1230,6 +1230,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
// WorldServer.LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityTypes.getKey(entity.getType())); // CraftBukkit
return false;
} else {
+ if (entity instanceof net.minecraft.world.entity.item.ItemEntity itemEntity && itemEntity.getItem().isEmpty()) return false; // Paper - Prevent empty items from being added
// Paper start - capture all item additions to the world
if (captureDrops != null && entity instanceof net.minecraft.world.entity.item.ItemEntity) {
captureDrops.add((net.minecraft.world.entity.item.ItemEntity) entity);

View file

@ -0,0 +1,21 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Thu, 21 Apr 2022 18:18:02 -0700
Subject: [PATCH] Fix CCE for SplashPotion and LingeringPotion spawning
Remove in 1.19 along with the SplashPotion and
LingeringPotion interfaces
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java
index f6fa6f1ac50b757dd3bc9a8dee9f6085446182c8..65b6de9d21da6843d7c7087f0dea98d3b75f24cf 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java
@@ -14,7 +14,7 @@ import org.bukkit.entity.ThrownPotion;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
-public class CraftThrownPotion extends CraftThrowableProjectile implements ThrownPotion {
+public class CraftThrownPotion extends CraftThrowableProjectile implements ThrownPotion, org.bukkit.entity.SplashPotion, org.bukkit.entity.LingeringPotion { // Paper - implement other classes to avoid violating spawn method generic contracts
public CraftThrownPotion(CraftServer server, net.minecraft.world.entity.projectile.ThrownPotion entity) {
super(server, entity);
}

View file

@ -0,0 +1,26 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: u9g <git@u9g.dev>
Date: Tue, 14 Jun 2022 19:36:10 -0400
Subject: [PATCH] Add Player#getFishHook
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
index 1e49eae80730aa9d2e49cd92759d899deb49fb90..df9d02eb1ffc3cc669e835e2c08d951283871db3 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
@@ -160,6 +160,15 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
return new Location(worldServer.getWorld(), bed.getX(), bed.getY(), bed.getZ());
}
// Paper end
+ // Paper start
+ @Override
+ public org.bukkit.entity.FishHook getFishHook() {
+ if (getHandle().fishing == null) {
+ return null;
+ }
+ return (org.bukkit.entity.FishHook) getHandle().fishing.getBukkitEntity();
+ }
+ // Paper end
@Override
public boolean sleep(Location location, boolean force) {
Preconditions.checkArgument(location != null, "Location cannot be null");

View file

@ -0,0 +1,29 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sun, 3 Jul 2022 22:31:37 -0700
Subject: [PATCH] Do not sync load chunk for dynamic game event listener
registration
These can be called while an entity is being added to the world,
and if the entity is being added from a chunk load context the
sync load will block indefinitely (because the chunk load context
is for completing the chunk to FULL).
This does raise questions about the current system for these
dynamic registrations, as it looks like there is _zero_ logic
to account for the case where the chunk is _not_ currently loaded
and then later loaded.
diff --git a/src/main/java/net/minecraft/world/level/gameevent/DynamicGameEventListener.java b/src/main/java/net/minecraft/world/level/gameevent/DynamicGameEventListener.java
index af9437bddf69546a1a78eca7e858ac8d2e68ed0a..134b4ceec0ec5a2475881e739d6579fa5984c3dd 100644
--- a/src/main/java/net/minecraft/world/level/gameevent/DynamicGameEventListener.java
+++ b/src/main/java/net/minecraft/world/level/gameevent/DynamicGameEventListener.java
@@ -41,7 +41,7 @@ public class DynamicGameEventListener<T extends GameEventListener> {
private static void ifChunkExists(LevelReader world, @Nullable SectionPos sectionPos, Consumer<GameEventListenerRegistry> dispatcherConsumer) {
if (sectionPos != null) {
- ChunkAccess chunkAccess = world.getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.FULL, false);
+ ChunkAccess chunkAccess = world.getChunkIfLoadedImmediately(sectionPos.getX(), sectionPos.getZ()); // Paper - Perf: can cause sync loads while completing a chunk, resulting in deadlock
if (chunkAccess != null) {
dispatcherConsumer.accept(chunkAccess.getListenerRegistry(sectionPos.y()));
}

View file

@ -0,0 +1,109 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Tue, 20 Jul 2021 21:35:47 -0700
Subject: [PATCH] Add various missing EntityDropItemEvent calls
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 71efd269ea055f13e3ca898bad045448e24f73da..44f585b9dc9e3940193f07a2df1205907b4800ba 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -2672,6 +2672,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
stack.setCount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe
entityitem.setDefaultPickUpDelay();
+ // Paper start - Call EntityDropItemEvent
+ return this.spawnAtLocation(entityitem);
+ }
+ }
+ @Nullable
+ public ItemEntity spawnAtLocation(ItemEntity entityitem) {
+ {
+ // Paper end - Call EntityDropItemEvent
// CraftBukkit start
EntityDropItemEvent event = new EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity());
Bukkit.getPluginManager().callEvent(event);
diff --git a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java
index 33170f2f1d3f030fbf342e44a1baa109a34c31a7..b99e5878b3094ba25084b756c058510bc39f941a 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java
@@ -604,7 +604,7 @@ public class Dolphin extends AgeableWaterCreature {
float f2 = 0.02F * Dolphin.this.random.nextFloat();
entityitem.setDeltaMovement((double) (0.3F * -Mth.sin(Dolphin.this.getYRot() * 0.017453292F) * Mth.cos(Dolphin.this.getXRot() * 0.017453292F) + Mth.cos(f1) * f2), (double) (0.3F * Mth.sin(Dolphin.this.getXRot() * 0.017453292F) * 1.5F), (double) (0.3F * Mth.cos(Dolphin.this.getYRot() * 0.017453292F) * Mth.cos(Dolphin.this.getXRot() * 0.017453292F) + Mth.sin(f1) * f2));
- Dolphin.this.level().addFreshEntity(entityitem);
+ Dolphin.this.spawnAtLocation(entityitem); // Paper - Call EntityDropItemEvent
}
}
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/Fox.java b/src/main/java/net/minecraft/world/entity/animal/Fox.java
index 205aefd38a185fa411ff17cfb0155769de8fc2fd..ca45a8ccf7f4593d557d157470603e4d233d948d 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Fox.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Fox.java
@@ -492,14 +492,14 @@ public class Fox extends Animal implements VariantHolder<Fox.Variant> {
entityitem.setPickUpDelay(40);
entityitem.setThrower(this);
this.playSound(SoundEvents.FOX_SPIT, 1.0F, 1.0F);
- this.level().addFreshEntity(entityitem);
+ this.spawnAtLocation(entityitem); // Paper - Call EntityDropItemEvent
}
}
private void dropItemStack(ItemStack stack) {
ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), stack);
- this.level().addFreshEntity(entityitem);
+ this.spawnAtLocation(entityitem); // Paper - Call EntityDropItemEvent
}
@Override
diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
index 14e02f9b0169db8388c515a68315ad5cc3f13d22..dbcf14f5af9c9c0655a82529ee99450a8da14525 100644
--- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
+++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
@@ -365,8 +365,7 @@ public class Goat extends Animal {
double d2 = (double) Mth.randomBetween(this.random, -0.2F, 0.2F);
ItemEntity entityitem = new ItemEntity(this.level(), vec3d.x(), vec3d.y(), vec3d.z(), itemstack, d0, d1, d2);
- this.level().addFreshEntity(entityitem);
- return true;
+ return this.spawnAtLocation(entityitem) != null; // Paper - Call EntityDropItemEvent
}
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java
index 5e586f174ff4b610a2584f28c9ffdd445ad58bea..0395b120590552518a85f36a46b68532e936de49 100644
--- a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java
+++ b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java
@@ -345,8 +345,9 @@ public class Sniffer extends Animal {
entityitem.setDefaultPickUpDelay();
this.finalizeSpawnChildFromBreeding(world, other, (AgeableMob) null);
+ if (this.spawnAtLocation(entityitem) != null) { // Paper - Call EntityDropItemEvent
this.playSound(SoundEvents.SNIFFER_EGG_PLOP, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 0.5F);
- world.addFreshEntity(entityitem);
+ } // Paper - Call EntityDropItemEvent
}
@Override
diff --git a/src/main/java/net/minecraft/world/item/ItemUtils.java b/src/main/java/net/minecraft/world/item/ItemUtils.java
index f4fc17e029407be5df3cfe2dcb6fb2f88234b066..0c4074ed8b4fd9d6fcb838e8843d66f6f286ed5d 100644
--- a/src/main/java/net/minecraft/world/item/ItemUtils.java
+++ b/src/main/java/net/minecraft/world/item/ItemUtils.java
@@ -41,7 +41,15 @@ public class ItemUtils {
public static void onContainerDestroyed(ItemEntity itemEntity, Iterable<ItemStack> contents) {
Level level = itemEntity.level();
if (!level.isClientSide) {
- contents.forEach(stack -> level.addFreshEntity(new ItemEntity(level, itemEntity.getX(), itemEntity.getY(), itemEntity.getZ(), stack)));
+ // Paper start - call EntityDropItemEvent
+ contents.forEach(stack -> {
+ ItemEntity droppedItem = new ItemEntity(level, itemEntity.getX(), itemEntity.getY(), itemEntity.getZ(), stack);
+ org.bukkit.event.entity.EntityDropItemEvent event = new org.bukkit.event.entity.EntityDropItemEvent(itemEntity.getBukkitEntity(), (org.bukkit.entity.Item) droppedItem.getBukkitEntity());
+ if (event.callEvent()) {
+ level.addFreshEntity(droppedItem);
+ }
+ });
+ // Paper end - call EntityDropItemEvent
}
}
}

View file

@ -0,0 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 6 Jul 2022 14:59:38 -0700
Subject: [PATCH] Fix Bee flower NPE
diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java
index 63e068c1a2d98c9c07dbabd1fa574d6b44e1a2fb..3f775aeed0afb5c4f19cbb17bf7bd9f7cfdc3adb 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Bee.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java
@@ -940,7 +940,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
Bee.this.dropFlower();
this.pollinating = false;
Bee.this.remainingCooldownBeforeLocatingNewFlower = 200;
- } else {
+ } else if (Bee.this.savedFlowerPos != null) { // Paper - add null check since API can manipulate this
Vec3 vec3d = Vec3.atBottomCenterOf(Bee.this.savedFlowerPos).add(0.0D, 0.6000000238418579D, 0.0D);
if (vec3d.distanceTo(Bee.this.position()) > 1.0D) {

View file

@ -0,0 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Doc <nachito94@msn.com>
Date: Sun, 17 Jul 2022 11:49:43 -0400
Subject: [PATCH] Fix Spigot Config not using commands.spam-exclusions
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index ffd8e7a537fd8c6276674f5e0034412bb93ca82c..84132f9642f51e1774d6c242330deebc6dfa163a 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2394,7 +2394,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
// Spigot end
// this.chatSpamThrottler.increment();
- if (!this.chatSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) {
+ if (counted && !this.chatSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - exclude from SpigotConfig.spamExclusions
// CraftBukkit end
this.disconnect((Component) Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause
}

View file

@ -0,0 +1,269 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Sun, 5 Sep 2021 12:15:59 -0400
Subject: [PATCH] More Teleport API
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 84132f9642f51e1774d6c242330deebc6dfa163a..60d3a3497a49c26120650016ffff04123efa1caf 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1577,11 +1577,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
return true; // CraftBukkit - Return event status
}
- PlayerTeleportEvent event = new PlayerTeleportEvent(player, from.clone(), to.clone(), cause);
+ // Paper start - Teleport API
+ Set<io.papermc.paper.entity.TeleportFlag.Relative> relativeFlags = java.util.EnumSet.noneOf(io.papermc.paper.entity.TeleportFlag.Relative.class);
+ for (RelativeMovement relativeArgument : set) {
+ relativeFlags.add(org.bukkit.craftbukkit.entity.CraftPlayer.toApiRelativeFlag(relativeArgument));
+ }
+ PlayerTeleportEvent event = new PlayerTeleportEvent(player, from.clone(), to.clone(), cause, java.util.Set.copyOf(relativeFlags));
+ // Paper end - Teleport API
this.cserver.getPluginManager().callEvent(event);
if (event.isCancelled() || !to.equals(event.getTo())) {
- set = Collections.emptySet(); // Can't relative teleport
+ // set = Collections.emptySet(); // Can't relative teleport // Paper - Teleport API; Now you can!
to = event.isCancelled() ? event.getFrom() : event.getTo();
positionmoverotation = new PositionMoveRotation(CraftLocation.toVec3D(to), Vec3.ZERO, to.getYaw(), to.getPitch());
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index 4e6afa243d6108cb946a8a7cf96c4036a3c2ac0c..43786eacc72cdf3bb209d3dfb1808ea9d021a52e 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -222,15 +222,36 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
@Override
public boolean teleport(Location location, TeleportCause cause) {
+ // Paper start - Teleport passenger API
+ return teleport(location, cause, new io.papermc.paper.entity.TeleportFlag[0]);
+ }
+
+ @Override
+ public boolean teleport(Location location, TeleportCause cause, io.papermc.paper.entity.TeleportFlag... flags) {
+ // Paper end
Preconditions.checkArgument(location != null, "location cannot be null");
location.checkFinite();
+ // Paper start - Teleport passenger API
+ Set<io.papermc.paper.entity.TeleportFlag> flagSet = Set.of(flags);
+ boolean dismount = !flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_VEHICLE);
+ boolean ignorePassengers = flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS);
+ // Don't allow teleporting between worlds while keeping passengers
+ if (flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS) && this.entity.isVehicle() && location.getWorld() != this.getWorld()) {
+ return false;
+ }
+
+ // Don't allow to teleport between worlds if remaining on vehicle
+ if (!dismount && this.entity.isPassenger() && location.getWorld() != this.getWorld()) {
+ return false;
+ }
+ // Paper end
- if (this.entity.isVehicle() || this.entity.isRemoved()) {
+ if ((!ignorePassengers && this.entity.isVehicle()) || this.entity.isRemoved()) { // Paper - Teleport passenger API
return false;
}
// If this entity is riding another entity, we must dismount before teleporting.
- this.entity.stopRiding();
+ if (dismount) this.entity.stopRiding(); // Paper - Teleport passenger API
// Let the server handle cross world teleports
if (location.getWorld() != null && !location.getWorld().equals(this.getWorld())) {
@@ -976,6 +997,39 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
return CraftEntity.perm;
}
+ // Paper start - more teleport API / async chunk API
+ @Override
+ public java.util.concurrent.CompletableFuture<Boolean> teleportAsync(final Location location, final TeleportCause cause, final io.papermc.paper.entity.TeleportFlag... teleportFlags) {
+ Preconditions.checkArgument(location != null, "location");
+ location.checkFinite();
+ Location locationClone = location.clone(); // clone so we don't need to worry about mutations after this call.
+
+ net.minecraft.server.level.ServerLevel world = ((CraftWorld)locationClone.getWorld()).getHandle();
+ java.util.concurrent.CompletableFuture<Boolean> ret = new java.util.concurrent.CompletableFuture<>();
+
+ world.loadChunksForMoveAsync(getHandle().getBoundingBoxAt(locationClone.getX(), locationClone.getY(), locationClone.getZ()),
+ this instanceof CraftPlayer ? ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHER : ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL, (list) -> {
+ net.minecraft.server.level.ServerChunkCache chunkProviderServer = world.getChunkSource();
+ for (net.minecraft.world.level.chunk.ChunkAccess chunk : list) {
+ chunkProviderServer.addTicketAtLevel(net.minecraft.server.level.TicketType.POST_TELEPORT, chunk.getPos(), 33, CraftEntity.this.getEntityId());
+ }
+ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> {
+ try {
+ ret.complete(CraftEntity.this.teleport(locationClone, cause, teleportFlags) ? Boolean.TRUE : Boolean.FALSE);
+ } catch (Throwable throwable) {
+ if (throwable instanceof ThreadDeath) {
+ throw (ThreadDeath)throwable;
+ }
+ net.minecraft.server.MinecraftServer.LOGGER.error("Failed to teleport entity " + CraftEntity.this, throwable);
+ ret.completeExceptionally(throwable);
+ }
+ });
+ });
+
+ return ret;
+ }
+ // Paper end - more teleport API / async chunk API
+
// Spigot start
private final org.bukkit.entity.Entity.Spigot spigot = new org.bukkit.entity.Entity.Spigot()
{
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 2347e260780d4703cff01b84a7971861fd924b20..884b02409968c22b8d0926ffb195ba050f51f9bc 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1299,13 +1299,101 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override
public void setRotation(float yaw, float pitch) {
- throw new UnsupportedOperationException("Cannot set rotation of players. Consider teleporting instead.");
+ // Paper start - Teleport API
+ Location targetLocation = this.getEyeLocation();
+ targetLocation.setYaw(yaw);
+ targetLocation.setPitch(pitch);
+
+ org.bukkit.util.Vector direction = targetLocation.getDirection();
+ direction.multiply(9999999); // We need to move the target block.. FAR out
+ targetLocation.add(direction);
+ this.lookAt(targetLocation, io.papermc.paper.entity.LookAnchor.EYES);
+ // Paper end
}
@Override
public boolean teleport(Location location, PlayerTeleportEvent.TeleportCause cause) {
+ // Paper start - Teleport API
+ return this.teleport(location, cause, new io.papermc.paper.entity.TeleportFlag[0]);
+ }
+
+ @Override
+ public void lookAt(@NotNull org.bukkit.entity.Entity entity, @NotNull io.papermc.paper.entity.LookAnchor playerAnchor, @NotNull io.papermc.paper.entity.LookAnchor entityAnchor) {
+ this.getHandle().lookAt(toNmsAnchor(playerAnchor), ((CraftEntity) entity).getHandle(), toNmsAnchor(entityAnchor));
+ }
+
+ @Override
+ public void lookAt(double x, double y, double z, @NotNull io.papermc.paper.entity.LookAnchor playerAnchor) {
+ this.getHandle().lookAt(toNmsAnchor(playerAnchor), new net.minecraft.world.phys.Vec3(x, y, z));
+ }
+
+ public static net.minecraft.commands.arguments.EntityAnchorArgument.Anchor toNmsAnchor(io.papermc.paper.entity.LookAnchor nmsAnchor) {
+ return switch (nmsAnchor) {
+ case EYES -> net.minecraft.commands.arguments.EntityAnchorArgument.Anchor.EYES;
+ case FEET -> net.minecraft.commands.arguments.EntityAnchorArgument.Anchor.FEET;
+ };
+ }
+
+ public static io.papermc.paper.entity.LookAnchor toApiAnchor(net.minecraft.commands.arguments.EntityAnchorArgument.Anchor playerAnchor) {
+ return switch (playerAnchor) {
+ case EYES -> io.papermc.paper.entity.LookAnchor.EYES;
+ case FEET -> io.papermc.paper.entity.LookAnchor.FEET;
+ };
+ }
+
+ public static net.minecraft.world.entity.RelativeMovement toNmsRelativeFlag(io.papermc.paper.entity.TeleportFlag.Relative apiFlag) {
+ return switch (apiFlag) {
+ case X -> net.minecraft.world.entity.RelativeMovement.X;
+ case Y -> net.minecraft.world.entity.RelativeMovement.Y;
+ case Z -> net.minecraft.world.entity.RelativeMovement.Z;
+ case PITCH -> net.minecraft.world.entity.RelativeMovement.X_ROT;
+ case YAW -> net.minecraft.world.entity.RelativeMovement.Y_ROT;
+ };
+ }
+
+ public static io.papermc.paper.entity.TeleportFlag.Relative toApiRelativeFlag(net.minecraft.world.entity.RelativeMovement nmsFlag) {
+ return switch (nmsFlag) {
+ case X -> io.papermc.paper.entity.TeleportFlag.Relative.X;
+ case Y -> io.papermc.paper.entity.TeleportFlag.Relative.Y;
+ case Z -> io.papermc.paper.entity.TeleportFlag.Relative.Z;
+ case X_ROT -> io.papermc.paper.entity.TeleportFlag.Relative.PITCH;
+ case Y_ROT -> io.papermc.paper.entity.TeleportFlag.Relative.YAW;
+ };
+ }
+
+ @Override
+ public boolean teleport(Location location, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause cause, io.papermc.paper.entity.TeleportFlag... flags) {
+ Set<io.papermc.paper.entity.TeleportFlag.Relative> relativeArguments;
+ Set<io.papermc.paper.entity.TeleportFlag> allFlags;
+ if (flags.length == 0) {
+ relativeArguments = Set.of();
+ allFlags = Set.of();
+ } else {
+ relativeArguments = java.util.EnumSet.noneOf(io.papermc.paper.entity.TeleportFlag.Relative.class);
+ allFlags = new HashSet<>();
+ for (io.papermc.paper.entity.TeleportFlag flag : flags) {
+ if (flag instanceof final io.papermc.paper.entity.TeleportFlag.Relative relativeTeleportFlag) {
+ relativeArguments.add(relativeTeleportFlag);
+ }
+ allFlags.add(flag);
+ }
+ }
+ boolean dismount = !allFlags.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_VEHICLE);
+ boolean ignorePassengers = allFlags.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS);
+ // Paper end - Teleport API
Preconditions.checkArgument(location != null, "location");
Preconditions.checkArgument(location.getWorld() != null, "location.world");
+ // Paper start - Teleport passenger API
+ // Don't allow teleporting between worlds while keeping passengers
+ if (ignorePassengers && entity.isVehicle() && location.getWorld() != this.getWorld()) {
+ return false;
+ }
+
+ // Don't allow to teleport between worlds if remaining on vehicle
+ if (!dismount && entity.isPassenger() && location.getWorld() != this.getWorld()) {
+ return false;
+ }
+ // Paper end
location.checkFinite();
ServerPlayer entity = this.getHandle();
@@ -1318,7 +1406,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
return false;
}
- if (entity.isVehicle()) {
+ if (entity.isVehicle() && !ignorePassengers) { // Paper - Teleport API
return false;
}
@@ -1327,7 +1415,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
// To = Players new Location if Teleport is Successful
Location to = location;
// Create & Call the Teleport Event.
- PlayerTeleportEvent event = new PlayerTeleportEvent(this, from, to, cause);
+ PlayerTeleportEvent event = new PlayerTeleportEvent(this, from, to, cause, Set.copyOf(relativeArguments)); // Paper - Teleport API
this.server.getPluginManager().callEvent(event);
// Return False to inform the Plugin that the Teleport was unsuccessful/cancelled.
@@ -1336,7 +1424,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
}
// If this player is riding another entity, we must dismount before teleporting.
- entity.stopRiding();
+ if (dismount) entity.stopRiding(); // Paper - Teleport API
// SPIGOT-5509: Wakeup, similar to riding
if (this.isSleeping()) {
@@ -1352,13 +1440,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
ServerLevel toWorld = ((CraftWorld) to.getWorld()).getHandle();
// Close any foreign inventory
- if (this.getHandle().containerMenu != this.getHandle().inventoryMenu) {
+ if (this.getHandle().containerMenu != this.getHandle().inventoryMenu && !allFlags.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_OPEN_INVENTORY)) { // Paper
this.getHandle().closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.TELEPORT); // Paper - Inventory close reason
}
// Check if the fromWorld and toWorld are the same.
if (fromWorld == toWorld) {
- entity.connection.teleport(to);
+ // Paper start - Teleport API
+ final Set<net.minecraft.world.entity.RelativeMovement> nms = java.util.EnumSet.noneOf(net.minecraft.world.entity.RelativeMovement.class);
+ for (final io.papermc.paper.entity.TeleportFlag.Relative bukkit : relativeArguments) {
+ nms.add(toNmsRelativeFlag(bukkit));
+ }
+ entity.connection.internalTeleport(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch(), nms);
+ // Paper end - Teleport API
} else {
entity.portalProcess = null; // SPIGOT-7785: there is no need to carry this over as it contains the old world/location and we might run into trouble if there is a portal in the same spot in both worlds
// The respawn reason should never be used if the passed location is non null.

View file

@ -0,0 +1,25 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 12 May 2021 04:30:42 -0700
Subject: [PATCH] Add EntityPortalReadyEvent
diff --git a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
index c00507fa7af579263caed67dafc2ea9eba09512b..fb361eac03c16ecee02219ff0524cce2292c7976 100644
--- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
@@ -141,6 +141,14 @@ public class NetherPortalBlock extends Block implements Portal {
// CraftBukkit start
ResourceKey<Level> resourcekey = world.getTypeKey() == LevelStem.NETHER ? Level.OVERWORLD : Level.NETHER;
ServerLevel worldserver1 = world.getServer().getLevel(resourcekey);
+ // Paper start - Add EntityPortalReadyEvent
+ io.papermc.paper.event.entity.EntityPortalReadyEvent portalReadyEvent = new io.papermc.paper.event.entity.EntityPortalReadyEvent(entity.getBukkitEntity(), worldserver1 == null ? null : worldserver1.getWorld(), org.bukkit.PortalType.NETHER);
+ if (!portalReadyEvent.callEvent()) {
+ entity.portalProcess = null;
+ return null;
+ }
+ worldserver1 = portalReadyEvent.getTargetWorld() == null ? null : ((org.bukkit.craftbukkit.CraftWorld) portalReadyEvent.getTargetWorld()).getHandle();
+ // Paper end - Add EntityPortalReadyEvent
if (worldserver1 == null) {
return new TeleportTransition(PlayerTeleportEvent.TeleportCause.NETHER_PORTAL); // always fire event in case plugins wish to change it

View file

@ -0,0 +1,41 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sun, 10 Jul 2022 14:13:22 -0700
Subject: [PATCH] Don't use level random in entity constructors
Paper makes the entity random thread-safe
and constructing an entity off the main thread
should be supported. Some entities (for whatever
reason) use the level's random in some places.
diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
index 6b19689a19465554b943470fc6f959e48169ac5b..aa41c4cf8d3ae291c4147118c96190ff0bb807b2 100644
--- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
+++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
@@ -72,7 +72,12 @@ public class ItemEntity extends Entity implements TraceableEntity {
}
public ItemEntity(Level world, double x, double y, double z, ItemStack stack) {
- this(world, x, y, z, stack, world.random.nextDouble() * 0.2D - 0.1D, 0.2D, world.random.nextDouble() * 0.2D - 0.1D);
+ // Paper start - Don't use level random in entity constructors (to make them thread-safe)
+ this(EntityType.ITEM, world);
+ this.setPos(x, y, z);
+ this.setDeltaMovement(this.random.nextDouble() * 0.2D - 0.1D, 0.2D, this.random.nextDouble() * 0.2D - 0.1D);
+ this.setItem(stack);
+ // Paper end - Don't use level random in entity constructors
}
public ItemEntity(Level world, double x, double y, double z, ItemStack stack, double velocityX, double velocityY, double velocityZ) {
diff --git a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
index f45a466120291103e4501276b3d8f97d79070360..96453be982623c7eb210a828404122e1d0f78b5d 100644
--- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
+++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
@@ -68,7 +68,7 @@ public class PrimedTnt extends Entity implements TraceableEntity {
public PrimedTnt(Level world, double x, double y, double z, @Nullable LivingEntity igniter) {
this(EntityType.TNT, world);
this.setPos(x, y, z);
- double d3 = world.random.nextDouble() * 6.2831854820251465D;
+ double d3 = this.random.nextDouble() * 6.2831854820251465D; // Paper - Don't use level random in entity constructors
this.setDeltaMovement(-Math.sin(d3) * 0.02D, 0.20000000298023224D, -Math.cos(d3) * 0.02D);
this.setFuse(80);

View file

@ -0,0 +1,91 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Sat, 25 Jun 2022 19:45:20 -0400
Subject: [PATCH] Send block entities after destroy prediction
Minecraft's prediction system does not handle block entities, so if we are manually sending block entities during
block breaking we need to set it after the prediction is finished. This fixes block entities not showing when cancelling the BlockBreakEvent.
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
index 5c3e5c348e6fececccd8097355f423b9e7ad982b..064a7a3e1c4d192010e072a5e985a54135748d87 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
@@ -61,6 +61,8 @@ public class ServerPlayerGameMode {
private BlockPos delayedDestroyPos;
private int delayedTickStart;
private int lastSentState;
+ public boolean captureSentBlockEntities = false; // Paper - Send block entities after destroy prediction
+ public boolean capturedBlockEntity = false; // Paper - Send block entities after destroy prediction
public ServerPlayerGameMode(ServerPlayer player) {
this.gameModeForPlayer = GameType.DEFAULT_MODE;
@@ -191,10 +193,7 @@ public class ServerPlayerGameMode {
this.player.connection.send(new ClientboundBlockUpdatePacket(pos, this.level.getBlockState(pos)));
this.debugLogging(pos, false, sequence, "may not interact");
// Update any tile entity data for this block
- BlockEntity tileentity = this.level.getBlockEntity(pos);
- if (tileentity != null) {
- this.player.connection.send(tileentity.getUpdatePacket());
- }
+ capturedBlockEntity = true; // Paper - Send block entities after destroy prediction
// CraftBukkit end
return;
}
@@ -205,10 +204,7 @@ public class ServerPlayerGameMode {
// Let the client know the block still exists
this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
// Update any tile entity data for this block
- BlockEntity tileentity = this.level.getBlockEntity(pos);
- if (tileentity != null) {
- this.player.connection.send(tileentity.getUpdatePacket());
- }
+ capturedBlockEntity = true; // Paper - Send block entities after destroy prediction
return;
}
// CraftBukkit end
@@ -393,10 +389,12 @@ public class ServerPlayerGameMode {
}
// Update any tile entity data for this block
+ if (!captureSentBlockEntities) { // Paper - Send block entities after destroy prediction
BlockEntity tileentity = this.level.getBlockEntity(pos);
if (tileentity != null) {
this.player.connection.send(tileentity.getUpdatePacket());
}
+ } else {capturedBlockEntity = true;} // Paper - Send block entities after destroy prediction
return false;
}
}
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 60d3a3497a49c26120650016ffff04123efa1caf..5f567d6a8ac93113c2f57d38736c4891c5f9ae19 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1715,8 +1715,28 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
return;
}
// Paper end - Don't allow digging into unloaded chunks
+ // Paper start - Send block entities after destroy prediction
+ this.player.gameMode.capturedBlockEntity = false;
+ this.player.gameMode.captureSentBlockEntities = true;
+ // Paper end - Send block entities after destroy prediction
this.player.gameMode.handleBlockBreakAction(blockposition, packetplayinblockdig_enumplayerdigtype, packet.getDirection(), this.player.level().getMaxY(), packet.getSequence());
this.player.connection.ackBlockChangesUpTo(packet.getSequence());
+ // Paper start - Send block entities after destroy prediction
+ this.player.gameMode.captureSentBlockEntities = false;
+ // If a block entity was modified speedup the block change ack to avoid the block entity
+ // being overriden.
+ if (this.player.gameMode.capturedBlockEntity) {
+ // manually tick
+ this.send(new ClientboundBlockChangedAckPacket(this.ackBlockChangesUpTo));
+ this.player.connection.ackBlockChangesUpTo = -1;
+
+ this.player.gameMode.capturedBlockEntity = false;
+ BlockEntity tileentity = this.player.level().getBlockEntity(blockposition);
+ if (tileentity != null) {
+ this.player.connection.send(tileentity.getUpdatePacket());
+ }
+ }
+ // Paper end - Send block entities after destroy prediction
return;
default:
throw new IllegalArgumentException("Invalid player action");

View file

@ -0,0 +1,96 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Fri, 29 Jul 2022 12:35:19 -0400
Subject: [PATCH] Warn on plugins accessing faraway chunks
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 8269bf24f5e17f9e3936659aa0cbc9d4f95fb665..a6f538372830f3f80740ef503733736e0561d1bd 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -339,7 +339,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
}
private static boolean isInWorldBoundsHorizontal(BlockPos pos) {
- return pos.getX() >= -30000000 && pos.getZ() >= -30000000 && pos.getX() < 30000000 && pos.getZ() < 30000000;
+ return pos.getX() >= -30000000 && pos.getZ() >= -30000000 && pos.getX() < 30000000 && pos.getZ() < 30000000; // Diff on change warnUnsafeChunk()
}
private static boolean isOutsideSpawnableHeight(int y) {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 9ea74d52112ab4feea3f4bafd82351a72088cbc5..03cef3e33de1cf2a1ad4c7a5ba9a65ee3b69ee52 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -309,9 +309,24 @@ public class CraftWorld extends CraftRegionAccessor implements World {
public boolean setSpawnLocation(int x, int y, int z) {
return this.setSpawnLocation(x, y, z, 0.0F);
}
+ // Paper start
+ private static void warnUnsafeChunk(String reason, int x, int z) {
+ // if any chunk coord is outside of 30 million blocks
+ if (x > 1875000 || z > 1875000 || x < -1875000 || z < -1875000) {
+ Plugin plugin = io.papermc.paper.util.StackWalkerUtil.getFirstPluginCaller();
+ if (plugin != null) {
+ plugin.getLogger().warning("Plugin is %s at (%s, %s), this might cause issues.".formatted(reason, x, z));
+ }
+ if (net.minecraft.server.MinecraftServer.getServer().isDebugging()) {
+ io.papermc.paper.util.TraceUtil.dumpTraceForThread("Dangerous chunk retrieval");
+ }
+ }
+ }
+ // Paper end
@Override
public Chunk getChunkAt(int x, int z) {
+ warnUnsafeChunk("getting a faraway chunk", x, z); // Paper
// Paper start - add ticket to hold chunk for a little while longer if plugin accesses it
net.minecraft.world.level.chunk.LevelChunk chunk = this.world.getChunkSource().getChunkAtIfLoadedImmediately(x, z);
if (chunk == null) {
@@ -419,6 +434,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
if (!unloadChunk0(x, z, false)) {
return false;
}
+ warnUnsafeChunk("regenerating a faraway chunk", x, z); // Paper
final long chunkKey = ChunkCoordIntPair.pair(x, z);
world.getChunkProvider().unloadQueue.remove(chunkKey);
@@ -492,6 +508,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public boolean loadChunk(int x, int z, boolean generate) {
org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
+ warnUnsafeChunk("loading a faraway chunk", x, z); // Paper
ChunkAccess chunk = this.world.getChunkSource().getChunk(x, z, generate || isChunkGenerated(x, z) ? ChunkStatus.FULL : ChunkStatus.EMPTY, true); // Paper
// If generate = false, but the chunk already exists, we will get this back.
@@ -524,6 +541,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public boolean addPluginChunkTicket(int x, int z, Plugin plugin) {
+ warnUnsafeChunk("adding a faraway chunk ticket", x, z); // Paper
Preconditions.checkArgument(plugin != null, "null plugin");
Preconditions.checkArgument(plugin.isEnabled(), "plugin is not enabled");
@@ -624,6 +642,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public void setChunkForceLoaded(int x, int z, boolean forced) {
+ warnUnsafeChunk("forceloading a faraway chunk", x, z); // Paper
this.getHandle().setChunkForced(x, z, forced);
}
@@ -958,6 +977,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public int getHighestBlockYAt(int x, int z, org.bukkit.HeightMap heightMap) {
+ warnUnsafeChunk("getting a faraway chunk", x >> 4, z >> 4); // Paper
// Transient load for this tick
return this.world.getChunk(x >> 4, z >> 4).getHeight(CraftHeightMap.toNMS(heightMap), x, z);
}
@@ -2358,6 +2378,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
// Spigot end
// Paper start
public java.util.concurrent.CompletableFuture<Chunk> getChunkAtAsync(int x, int z, boolean gen, boolean urgent) {
+ warnUnsafeChunk("getting a faraway chunk async", x, z); // Paper
if (Bukkit.isPrimaryThread()) {
net.minecraft.world.level.chunk.LevelChunk immediate = this.world.getChunkSource().getChunkAtIfLoadedImmediately(x, z);
if (immediate != null) {

View file

@ -0,0 +1,35 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Sat, 30 Jul 2022 11:23:05 -0400
Subject: [PATCH] Custom Chat Completion Suggestions API
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 884b02409968c22b8d0926ffb195ba050f51f9bc..025c392f2ca89a87f6301d4af64c4d7daec58409 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -704,6 +704,24 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
}
// Paper end - Add sendOpLevel API
+ // Paper start - custom chat completions API
+ @Override
+ public void addAdditionalChatCompletions(@NotNull Collection<String> completions) {
+ this.getHandle().connection.send(new net.minecraft.network.protocol.game.ClientboundCustomChatCompletionsPacket(
+ net.minecraft.network.protocol.game.ClientboundCustomChatCompletionsPacket.Action.ADD,
+ new ArrayList<>(completions)
+ ));
+ }
+
+ @Override
+ public void removeAdditionalChatCompletions(@NotNull Collection<String> completions) {
+ this.getHandle().connection.send(new net.minecraft.network.protocol.game.ClientboundCustomChatCompletionsPacket(
+ net.minecraft.network.protocol.game.ClientboundCustomChatCompletionsPacket.Action.REMOVE,
+ new ArrayList<>(completions)
+ ));
+ }
+ // Paper end - custom chat completions API
+
@Override
public void setCompassTarget(Location loc) {
Preconditions.checkArgument(loc != null, "Location cannot be null");

View file

@ -0,0 +1,71 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Thu, 21 Jul 2022 12:07:54 -0400
Subject: [PATCH] Add and fix missing BlockFadeEvents
Beyond calling the BlockFadeEvent in more places, this patch also aims
to pass the proper replacement state to the event, specifically for
potentially waterlogged block states fading.
Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
diff --git a/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java b/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java
index 34be6b349722240e99f91d28067578aa0b4bd1fe..4f53f25d7565eb930f6ae27ca24a6aa0cca571a2 100644
--- a/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java
@@ -102,6 +102,11 @@ public class FrogspawnBlock extends Block {
}
private void hatchFrogspawn(ServerLevel world, BlockPos pos, RandomSource random) {
+ // Paper start - Call BlockFadeEvent
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, Blocks.AIR.defaultBlockState()).isCancelled()) {
+ return;
+ }
+ // Paper end - Call BlockFadeEvent
this.destroyBlock(world, pos);
world.playSound(null, pos, SoundEvents.FROGSPAWN_HATCH, SoundSource.BLOCKS, 1.0F, 1.0F);
this.spawnTadpoles(world, pos, random);
diff --git a/src/main/java/net/minecraft/world/level/block/ScaffoldingBlock.java b/src/main/java/net/minecraft/world/level/block/ScaffoldingBlock.java
index fc49230d6b2c13b009724d28081f5e77537d5ab8..2d3f425778302490dd3654d487cfa3cfed6fb9e8 100644
--- a/src/main/java/net/minecraft/world/level/block/ScaffoldingBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/ScaffoldingBlock.java
@@ -103,7 +103,7 @@ public class ScaffoldingBlock extends Block implements SimpleWaterloggedBlock {
int i = ScaffoldingBlock.getDistance(world, pos);
BlockState iblockdata1 = (BlockState) ((BlockState) state.setValue(ScaffoldingBlock.DISTANCE, i)).setValue(ScaffoldingBlock.BOTTOM, this.isBottom(world, pos, i));
- if ((Integer) iblockdata1.getValue(ScaffoldingBlock.DISTANCE) == 7 && !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, Blocks.AIR.defaultBlockState()).isCancelled()) { // CraftBukkit - BlockFadeEvent
+ if ((Integer) iblockdata1.getValue(ScaffoldingBlock.DISTANCE) == 7 && !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, iblockdata1.getFluidState().createLegacyBlock()).isCancelled()) { // CraftBukkit - BlockFadeEvent // Paper - fix wrong block state
if ((Integer) state.getValue(ScaffoldingBlock.DISTANCE) == 7) {
FallingBlockEntity.fall(world, pos, iblockdata1);
} else {
diff --git a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java
index 4f8224841865f956aaa969ab7f543c80b3c24319..2df28caefff893f319924ae5fd376c8aeb0a2158 100644
--- a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java
@@ -61,12 +61,26 @@ public class SnifferEggBlock extends Block {
return this.getHatchLevel(state) == 2;
}
+ // Paper start - Call BlockFadeEvent
+ private void rescheduleTick(ServerLevel world, BlockPos pos) {
+ int baseDelay = hatchBoost(world, pos) ? BOOSTED_HATCH_TIME_TICKS : REGULAR_HATCH_TIME_TICKS;
+ world.scheduleTick(pos, this, (baseDelay / 3) + world.random.nextInt(RANDOM_HATCH_OFFSET_TICKS));
+ // reschedule to avoid being stuck here and behave like the other calls (see #onPlace)
+ }
+ // Paper end - Call BlockFadeEvent
+
@Override
public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
if (!this.isReadyToHatch(state)) {
world.playSound(null, pos, SoundEvents.SNIFFER_EGG_CRACK, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F);
world.setBlock(pos, state.setValue(HATCH, Integer.valueOf(this.getHatchLevel(state) + 1)), 2);
} else {
+ // Paper start - Call BlockFadeEvent
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, state.getFluidState().createLegacyBlock()).isCancelled()) {
+ this.rescheduleTick(world, pos);
+ return;
+ }
+ // Paper end - Call BlockFadeEvent
world.playSound(null, pos, SoundEvents.SNIFFER_EGG_HATCH, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F);
world.destroyBlock(pos, false);
Sniffer sniffer = EntityType.SNIFFER.create(world, EntitySpawnReason.BREEDING);

View file

@ -0,0 +1,48 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Wed, 6 Oct 2021 20:10:44 -0400
Subject: [PATCH] Collision API
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
index 244cff4f84792fd0efe146e6faf47db0b0a0dc87..6baa06dc0f102fe83b10015dbbe1410066961c82 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
@@ -543,5 +543,12 @@ public abstract class CraftRegionAccessor implements RegionAccessor {
return this.getHandle().clip(new net.minecraft.world.level.ClipContext(start, end, net.minecraft.world.level.ClipContext.Block.COLLIDER, net.minecraft.world.level.ClipContext.Fluid.NONE, net.minecraft.world.phys.shapes.CollisionContext.empty())).getType() == net.minecraft.world.phys.HitResult.Type.MISS;
}
+
+ @Override
+ public boolean hasCollisionsIn(@org.jetbrains.annotations.NotNull org.bukkit.util.BoundingBox boundingBox) {
+ net.minecraft.world.phys.AABB aabb = new net.minecraft.world.phys.AABB(boundingBox.getMinX(), boundingBox.getMinY(), boundingBox.getMinZ(), boundingBox.getMaxX(), boundingBox.getMaxY(), boundingBox.getMaxZ());
+
+ return !this.getHandle().noCollision(aabb);
+ }
// Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index 43786eacc72cdf3bb209d3dfb1808ea9d021a52e..775675483c1f90fbe8e9e5eadab7d791e81983f5 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -1194,4 +1194,20 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
return this.getHandle().noPhysics;
}
// Paper end - missing entity api
+
+ // Paper start - Collision API
+ @Override
+ public boolean collidesAt(@org.jetbrains.annotations.NotNull Location location) {
+ net.minecraft.world.phys.AABB aabb = this.getHandle().getBoundingBoxAt(location.getX(), location.getY(), location.getZ());
+
+ return !this.getHandle().level().noCollision(this.getHandle(), aabb);
+ }
+
+ @Override
+ public boolean wouldCollideUsing(@org.jetbrains.annotations.NotNull BoundingBox boundingBox) {
+ net.minecraft.world.phys.AABB aabb = new AABB(boundingBox.getMinX(), boundingBox.getMinY(), boundingBox.getMinZ(), boundingBox.getMaxX(), boundingBox.getMaxY(), boundingBox.getMaxZ());
+
+ return !this.getHandle().level().noCollision(this.getHandle(), aabb);
+ }
+ // Paper end - Collision API
}

View file

@ -0,0 +1,20 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: chickeneer <emcchickeneer@gmail.com>
Date: Mon, 1 Aug 2022 20:13:02 -0500
Subject: [PATCH] Fix suggest command message for brigadier syntax exceptions
This is a bug accidentally introduced in upstream CB
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
index bee79fab7f8195e14f6bd22d9cd59bfc704bf903..fd12046fab797fd845ad8521f94147480dfba5da 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -391,7 +391,7 @@ public class Commands {
if (commandsyntaxexception.getInput() != null && commandsyntaxexception.getCursor() >= 0) {
int i = Math.min(commandsyntaxexception.getInput().length(), commandsyntaxexception.getCursor());
MutableComponent ichatmutablecomponent = Component.empty().withStyle(ChatFormatting.GRAY).withStyle((chatmodifier) -> {
- return chatmodifier.withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, label)); // CraftBukkit
+ return chatmodifier.withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/" + label)); // CraftBukkit // Paper
});
if (i > 10) {

View file

@ -0,0 +1,63 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Sun, 26 Dec 2021 13:23:46 -0500
Subject: [PATCH] Block Ticking API
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 68fcec085334383808b2117a49220f4d8239220b..490a4f023491aaabd3966cb67901335c2b02bb52 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -78,6 +78,12 @@ public class CraftBlock implements Block {
return this.world.getBlockState(this.position);
}
+ // Paper start
+ public net.minecraft.world.level.material.FluidState getNMSFluid() {
+ return this.world.getFluidState(this.position);
+ }
+ // Paper end
+
public BlockPos getPosition() {
return this.position;
}
@@ -709,5 +715,23 @@ public class CraftBlock implements Block {
public boolean isValidTool(ItemStack itemStack) {
return getDrops(itemStack).size() != 0;
}
+
+ @Override
+ public void tick() {
+ final ServerLevel level = this.world.getMinecraftWorld();
+ this.getNMS().tick(level, this.position, level.random);
+ }
+
+
+ @Override
+ public void fluidTick() {
+ this.getNMSFluid().tick(this.world.getMinecraftWorld(), this.position);
+ }
+
+ @Override
+ public void randomTick() {
+ final ServerLevel level = this.world.getMinecraftWorld();
+ this.getNMS().randomTick(level, this.position, level.random);
+ }
// Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
index a17c1d1651d4d36c40ef97c1cf0b1e0d61f53418..3ec64c995dcb59a758741e32b886925983a8be56 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
@@ -756,4 +756,11 @@ public class CraftBlockData implements BlockData {
return speed;
}
// Paper end - destroy speed API
+
+ // Paper start - Block tick API
+ @Override
+ public boolean isRandomlyTicked() {
+ return this.state.isRandomlyTicking();
+ }
+ // Paper end - Block tick API
}

View file

@ -0,0 +1,242 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andrew Steinborn <git@steinborn.me>
Date: Mon, 8 Oct 2018 14:36:14 -0400
Subject: [PATCH] Add Velocity IP Forwarding Support
While Velocity supports BungeeCord-style IP forwarding, it is not secure. Users
have a lot of problems setting up firewalls or setting up plugins like IPWhitelist.
Further, the BungeeCord IP forwarding protocol still retains essentially its original
form, when there is brand new support for custom login plugin messages in 1.13.
Velocity's modern IP forwarding uses an HMAC-SHA256 code to ensure authenticity
of messages, is packed into a binary format that is smaller than BungeeCord's
forwarding, and is integrated into the Minecraft login process by using the 1.13
login plugin message packet.
diff --git a/src/main/java/com/destroystokyo/paper/proxy/VelocityProxy.java b/src/main/java/com/destroystokyo/paper/proxy/VelocityProxy.java
new file mode 100644
index 0000000000000000000000000000000000000000..1b797955357612a4319452de7461ba044cbb88d6
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/proxy/VelocityProxy.java
@@ -0,0 +1,86 @@
+package com.destroystokyo.paper.proxy;
+
+import io.papermc.paper.configuration.GlobalConfiguration;
+import com.google.common.net.InetAddresses;
+import com.mojang.authlib.GameProfile;
+import com.mojang.authlib.properties.Property;
+import java.net.InetAddress;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.UUID;
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import net.minecraft.network.FriendlyByteBuf;
+import net.minecraft.network.protocol.login.custom.CustomQueryPayload;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.world.entity.player.ProfilePublicKey;
+
+/**
+ * While Velocity supports BungeeCord-style IP forwarding, it is not secure. Users
+ * have a lot of problems setting up firewalls or setting up plugins like IPWhitelist.
+ * Further, the BungeeCord IP forwarding protocol still retains essentially its original
+ * form, when there is brand-new support for custom login plugin messages in 1.13.
+ * <p>
+ * Velocity's modern IP forwarding uses an HMAC-SHA256 code to ensure authenticity
+ * of messages, is packed into a binary format that is smaller than BungeeCord's
+ * forwarding, and is integrated into the Minecraft login process by using the 1.13
+ * login plugin message packet.
+ */
+public class VelocityProxy {
+ private static final int SUPPORTED_FORWARDING_VERSION = 1;
+ public static final int MODERN_FORWARDING_WITH_KEY = 2;
+ public static final int MODERN_FORWARDING_WITH_KEY_V2 = 3;
+ public static final int MODERN_LAZY_SESSION = 4;
+ public static final byte MAX_SUPPORTED_FORWARDING_VERSION = MODERN_LAZY_SESSION;
+ public static final ResourceLocation PLAYER_INFO_CHANNEL = ResourceLocation.fromNamespaceAndPath("velocity", "player_info");
+
+ public static boolean checkIntegrity(final FriendlyByteBuf buf) {
+ final byte[] signature = new byte[32];
+ buf.readBytes(signature);
+
+ final byte[] data = new byte[buf.readableBytes()];
+ buf.getBytes(buf.readerIndex(), data);
+
+ try {
+ final Mac mac = Mac.getInstance("HmacSHA256");
+ mac.init(new SecretKeySpec(GlobalConfiguration.get().proxies.velocity.secret.getBytes(java.nio.charset.StandardCharsets.UTF_8), "HmacSHA256"));
+ final byte[] mySignature = mac.doFinal(data);
+ if (!MessageDigest.isEqual(signature, mySignature)) {
+ return false;
+ }
+ } catch (final InvalidKeyException | NoSuchAlgorithmException e) {
+ throw new AssertionError(e);
+ }
+
+ return true;
+ }
+
+ public static InetAddress readAddress(final FriendlyByteBuf buf) {
+ return InetAddresses.forString(buf.readUtf(Short.MAX_VALUE));
+ }
+
+ public static GameProfile createProfile(final FriendlyByteBuf buf) {
+ final GameProfile profile = new GameProfile(buf.readUUID(), buf.readUtf(16));
+ readProperties(buf, profile);
+ return profile;
+ }
+
+ private static void readProperties(final FriendlyByteBuf buf, final GameProfile profile) {
+ final int properties = buf.readVarInt();
+ for (int i1 = 0; i1 < properties; i1++) {
+ final String name = buf.readUtf(Short.MAX_VALUE);
+ final String value = buf.readUtf(Short.MAX_VALUE);
+ final String signature = buf.readBoolean() ? buf.readUtf(Short.MAX_VALUE) : null;
+ profile.getProperties().put(name, new Property(name, value, signature));
+ }
+ }
+
+ public static ProfilePublicKey.Data readForwardedKey(FriendlyByteBuf buf) {
+ return new ProfilePublicKey.Data(buf);
+ }
+
+ public static UUID readSignerUuidOrElse(FriendlyByteBuf buf, UUID orElse) {
+ return buf.readBoolean() ? buf.readUUID() : orElse;
+ }
+}
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index 3c3be48b29fcd38c5dea1bfca8d8690850aa948e..4037a1057ebc87e3df6333e0d546fc85b5148d2a 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -290,13 +290,20 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.STARTUP);
// CraftBukkit end
+ // Paper start - Add Velocity IP Forwarding Support
+ boolean usingProxy = org.spigotmc.SpigotConfig.bungee || io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled;
+ String proxyFlavor = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "Velocity" : "BungeeCord";
+ String proxyLink = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "https://docs.papermc.io/velocity/security" : "http://www.spigotmc.org/wiki/firewall-guide/";
+ // Paper end - Add Velocity IP Forwarding Support
if (!this.usesAuthentication()) {
DedicatedServer.LOGGER.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!");
DedicatedServer.LOGGER.warn("The server will make no attempt to authenticate usernames. Beware.");
// Spigot start
- if (org.spigotmc.SpigotConfig.bungee) {
- DedicatedServer.LOGGER.warn("Whilst this makes it possible to use BungeeCord, unless access to your server is properly restricted, it also opens up the ability for hackers to connect with any username they choose.");
- DedicatedServer.LOGGER.warn("Please see http://www.spigotmc.org/wiki/firewall-guide/ for further information.");
+ // Paper start - Add Velocity IP Forwarding Support
+ if (usingProxy) {
+ DedicatedServer.LOGGER.warn("Whilst this makes it possible to use " + proxyFlavor + ", unless access to your server is properly restricted, it also opens up the ability for hackers to connect with any username they choose.");
+ DedicatedServer.LOGGER.warn("Please see " + proxyLink + " for further information.");
+ // Paper end - Add Velocity IP Forwarding Support
} else {
DedicatedServer.LOGGER.warn("While this makes the game possible to play without internet access, it also opens up the ability for hackers to connect with any username they choose.");
}
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
index cb5dd77892283a1aaec45434fb99bb7f08ee5394..4a89b73d972f366e70f4d2bd96c6ee413593baba 100644
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
@@ -91,6 +91,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
private final boolean transferred;
private ServerPlayer player; // CraftBukkit
public boolean iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation = false; // Paper - username validation overriding
+ private int velocityLoginMessageId = -1; // Paper - Add Velocity IP Forwarding Support
public ServerLoginPacketListenerImpl(MinecraftServer server, Connection connection, boolean transferred) {
this.state = ServerLoginPacketListenerImpl.State.HELLO;
@@ -189,6 +190,16 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
this.state = ServerLoginPacketListenerImpl.State.KEY;
this.connection.send(new ClientboundHelloPacket("", this.server.getKeyPair().getPublic().getEncoded(), this.challenge, true));
} else {
+ // Paper start - Add Velocity IP Forwarding Support
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) {
+ this.velocityLoginMessageId = java.util.concurrent.ThreadLocalRandom.current().nextInt();
+ net.minecraft.network.FriendlyByteBuf buf = new net.minecraft.network.FriendlyByteBuf(io.netty.buffer.Unpooled.buffer());
+ buf.writeByte(com.destroystokyo.paper.proxy.VelocityProxy.MAX_SUPPORTED_FORWARDING_VERSION);
+ net.minecraft.network.protocol.login.ClientboundCustomQueryPacket packet1 = new net.minecraft.network.protocol.login.ClientboundCustomQueryPacket(this.velocityLoginMessageId, new net.minecraft.network.protocol.login.ClientboundCustomQueryPacket.PlayerInfoChannelPayload(com.destroystokyo.paper.proxy.VelocityProxy.PLAYER_INFO_CHANNEL, buf));
+ this.connection.send(packet1);
+ return;
+ }
+ // Paper end - Add Velocity IP Forwarding Support
// CraftBukkit start
// Paper start - Cache authenticator threads
authenticatorPool.execute(new Runnable() {
@@ -341,6 +352,12 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
// CraftBukkit start
private GameProfile callPlayerPreLoginEvents(GameProfile gameprofile) throws Exception { // Paper - Add more fields to AsyncPlayerPreLoginEvent
+ // Paper start - Add Velocity IP Forwarding Support
+ if (ServerLoginPacketListenerImpl.this.velocityLoginMessageId == -1 && io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) {
+ disconnect("This server requires you to connect with Velocity.");
+ return gameprofile;
+ }
+ // Paper end - Add Velocity IP Forwarding Support
String playerName = gameprofile.getName();
java.net.InetAddress address = ((java.net.InetSocketAddress) this.connection.getRemoteAddress()).getAddress();
java.util.UUID uniqueId = gameprofile.getId();
@@ -386,6 +403,51 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
@Override
public void handleCustomQueryPacket(ServerboundCustomQueryAnswerPacket packet) {
+ // Paper start - Add Velocity IP Forwarding Support
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled && packet.transactionId() == this.velocityLoginMessageId) {
+ ServerboundCustomQueryAnswerPacket.QueryAnswerPayload payload = (ServerboundCustomQueryAnswerPacket.QueryAnswerPayload)packet.payload();
+ if (payload == null) {
+ this.disconnect("This server requires you to connect with Velocity.");
+ return;
+ }
+
+ net.minecraft.network.FriendlyByteBuf buf = payload.buffer;
+
+ if (!com.destroystokyo.paper.proxy.VelocityProxy.checkIntegrity(buf)) {
+ this.disconnect("Unable to verify player details");
+ return;
+ }
+
+ int version = buf.readVarInt();
+ if (version > com.destroystokyo.paper.proxy.VelocityProxy.MAX_SUPPORTED_FORWARDING_VERSION) {
+ throw new IllegalStateException("Unsupported forwarding version " + version + ", wanted upto " + com.destroystokyo.paper.proxy.VelocityProxy.MAX_SUPPORTED_FORWARDING_VERSION);
+ }
+
+ java.net.SocketAddress listening = this.connection.getRemoteAddress();
+ int port = 0;
+ if (listening instanceof java.net.InetSocketAddress) {
+ port = ((java.net.InetSocketAddress) listening).getPort();
+ }
+ this.connection.address = new java.net.InetSocketAddress(com.destroystokyo.paper.proxy.VelocityProxy.readAddress(buf), port);
+
+ this.authenticatedProfile = com.destroystokyo.paper.proxy.VelocityProxy.createProfile(buf);
+
+ //TODO Update handling for lazy sessions, might not even have to do anything?
+
+ // Proceed with login
+ authenticatorPool.execute(() -> {
+ try {
+ final GameProfile gameprofile = this.callPlayerPreLoginEvents(this.authenticatedProfile);
+ ServerLoginPacketListenerImpl.LOGGER.info("UUID of player {} is {}", gameprofile.getName(), gameprofile.getId());
+ ServerLoginPacketListenerImpl.this.startClientVerification(gameprofile);
+ } catch (Exception ex) {
+ disconnect("Failed to verify username!");
+ server.server.getLogger().log(java.util.logging.Level.WARNING, "Exception verifying " + this.authenticatedProfile.getName(), ex);
+ }
+ });
+ return;
+ }
+ // Paper end - Add Velocity IP Forwarding Support
this.disconnect(ServerCommonPacketListenerImpl.DISCONNECT_UNEXPECTED_QUERY);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 284ffa47223595b42d115533551821f379de6663..f89cbdb157cb56b1b3e0658d80de48695734138d 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -849,7 +849,7 @@ public final class CraftServer implements Server {
@Override
public long getConnectionThrottle() {
// Spigot Start - Automatically set connection throttle for bungee configurations
- if (org.spigotmc.SpigotConfig.bungee) {
+ if (org.spigotmc.SpigotConfig.bungee || io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) { // Paper - Add Velocity IP Forwarding Support
return -1;
} else {
return this.configuration.getInt("settings.connection-throttle");

View file

@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Josh Roy <10731363+JRoy@users.noreply.github.com>
Date: Sun, 14 Aug 2022 12:23:11 -0400
Subject: [PATCH] Add NamespacedKey biome methods
Co-authored-by: Thonk <30448663+ExcessiveAmountsOfZombies@users.noreply.github.com>
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
index 98bbbdbf8fd067df936655334ad5ea25ec07daef..a5a3a0f0460252415c243dfe3019d103b9589c5b 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -584,6 +584,21 @@ public final class CraftMagicNumbers implements UnsafeValues {
}
// Paper end
+ // Paper start - namespaced key biome methods
+ @Override
+ public org.bukkit.NamespacedKey getBiomeKey(org.bukkit.RegionAccessor accessor, int x, int y, int z) {
+ org.bukkit.craftbukkit.CraftRegionAccessor cra = (org.bukkit.craftbukkit.CraftRegionAccessor) accessor;
+ return org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(cra.getHandle().registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.BIOME).getKey(cra.getHandle().getBiome(new net.minecraft.core.BlockPos(x, y, z)).value()));
+ }
+
+ @Override
+ public void setBiomeKey(org.bukkit.RegionAccessor accessor, int x, int y, int z, org.bukkit.NamespacedKey biomeKey) {
+ org.bukkit.craftbukkit.CraftRegionAccessor cra = (org.bukkit.craftbukkit.CraftRegionAccessor) accessor;
+ net.minecraft.core.Holder<net.minecraft.world.level.biome.Biome> biomeBase = cra.getHandle().registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.BIOME).getHolderOrThrow(net.minecraft.resources.ResourceKey.create(net.minecraft.core.registries.Registries.BIOME, org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(biomeKey)));
+ cra.setBiome(x, y, z, biomeBase);
+ }
+ // Paper end - namespaced key biome methods
+
@Override
public String get(Class<?> aClass, String s) {
if (aClass == Enchantment.class) {