more patches (#5811)

This commit is contained in:
Jake Potrebic 2021-06-12 16:45:00 -07:00
parent 1d0d3ecceb
commit 10882402df
52 changed files with 500 additions and 1243 deletions

View File

@ -15,19 +15,6 @@ which results in a hard crash.
This change removes the synchronize and adds some protection around enable/disable
diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/entity/Entity.java
+++ b/src/main/java/org/bukkit/entity/Entity.java
@@ -0,0 +0,0 @@ import org.jetbrains.annotations.Nullable;
*/
public interface Entity extends Metadatable, CommandSender, Nameable, PersistentDataHolder, net.kyori.adventure.text.event.HoverEventSource<net.kyori.adventure.text.event.HoverEvent.ShowEntity> { // Paper
- /**
+ /*
* Gets the entity's current position
*
* @return a new copy of Location containing the position of this entity
diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java

View File

@ -38,9 +38,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/bukkit/World.java
+++ b/src/main/java/org/bukkit/World.java
@@ -0,0 +0,0 @@ public interface World extends PluginMessageRecipient, Metadatable, net.kyori.ad
public default Chunk getChunkAt(long chunkKey) {
return getChunkAt((int) chunkKey, (int) (chunkKey >> 32));
}
+
+ /**
+ * Checks if a {@link Chunk} has been generated at the specified chunk key,
+ * which is the X and Z packed into a long.
@ -51,7 +52,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public default boolean isChunkGenerated(long chunkKey) {
+ return isChunkGenerated((int) chunkKey, (int) (chunkKey >> 32));
+ }
+
// Paper end
/**
* This is the Legacy API before Java 8 was supported. Java 8 Consumer is provided,
* as well as future support

View File

@ -1,341 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: BillyGalbreath <Blake.Galbreath@GMail.com>
Date: Thu, 2 Aug 2018 08:44:35 -0500
Subject: [PATCH] Add hand to bucket events
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// CraftBukkit end
MinecraftServer.LOGGER.info("Preparing start region for dimension {}", worldserver.dimension().location());
- BlockPos blockposition = worldserver.getSharedSpawnPos();
+ BlockPos blockposition = worldserver.getSpawn();
worldloadlistener.updateSpawnPos(new ChunkPos(blockposition));
ServerChunkCache chunkproviderserver = worldserver.getChunkSource();
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public CommandSourceStack createCommandSourceStack() {
ServerLevel worldserver = this.overworld();
- return new CommandSourceStack(this, worldserver == null ? Vec3.ZERO : Vec3.atLowerCornerOf((Vec3i) worldserver.getSharedSpawnPos()), Vec2.ZERO, worldserver, 4, "Server", new TextComponent("Server"), this, (Entity) null);
+ return new CommandSourceStack(this, worldserver == null ? Vec3.ZERO : Vec3.atLowerCornerOf((Vec3i) worldserver.getSpawn()), Vec2.ZERO, worldserver, 4, "Server", new TextComponent("Server"), this, (Entity) null);
}
@Override
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
} else if (this.getSpawnProtectionRadius() <= 0) {
return false;
} else {
- BlockPos blockposition1 = world.getSharedSpawnPos();
+ BlockPos blockposition1 = world.getSpawn();
int i = Mth.abs(pos.getX() - blockposition1.getX());
int j = Mth.abs(pos.getZ() - blockposition1.getZ());
int k = Math.max(i, j);
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
this.getServer().getPlayerList().broadcastAll(new ClientboundSetDefaultSpawnPositionPacket(pos, angle));
}
- public BlockPos getSharedSpawnPos() {
- BlockPos blockposition = new BlockPos(this.levelData.getXSpawn(), this.levelData.getYSpawn(), this.levelData.getZSpawn());
-
- if (!this.getWorldBorder().isWithinBounds(blockposition)) {
- blockposition = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, new BlockPos(this.getWorldBorder().getCenterX(), 0.0D, this.getWorldBorder().getCenterZ()));
- }
-
- return blockposition;
- }
+ // Paper - moved up to World
+ //public BlockPosition getSpawn() {
+ // BlockPosition blockposition = new BlockPosition(this.worldData.a(), this.worldData.b(), this.worldData.c());
+ //
+ // if (!this.getWorldBorder().a(blockposition)) {
+ // blockposition = this.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, new BlockPosition(this.getWorldBorder().getCenterX(), 0.0D, this.getWorldBorder().getCenterZ()));
+ // }
+ //
+ // return blockposition;
+ //}
+ // Paper end
public float getSharedSpawnAngle() {
return this.levelData.getSpawnAngle();
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener {
public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> cachedSingleHashSet; // Paper
public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ServerPlayerGameMode interactionManager) {
- super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile);
+ super(world, world.getSpawn(), world.getSharedSpawnAngle(), profile);
this.respawnDimension = Level.OVERWORLD;
interactionManager.player = this;
this.gameMode = interactionManager;
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener {
// Yes, this doesn't match Vanilla, but it's the best we can do for now.
// If this is an issue, PRs are welcome
public final BlockPos getSpawnPoint(ServerLevel worldserver) {
- BlockPos blockposition = worldserver.getSharedSpawnPos();
+ BlockPos blockposition = worldserver.getSpawn();
if (worldserver.dimensionType().hasSkyLight() && worldserver.worldDataServer.getGameType() != GameType.ADVENTURE) {
int i = Math.max(0, this.server.getSpawnRadius(worldserver));
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener {
// CraftBukkit end
private void fudgeSpawnLocation(ServerLevel world) {
- BlockPos blockposition = world.getSharedSpawnPos();
+ BlockPos blockposition = world.getSpawn();
if (world.dimensionType().hasSkyLight() && world.worldDataServer.getGameType() != GameType.ADVENTURE) { // CraftBukkit
int i = Math.max(0, this.server.getSpawnRadius(world));
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener {
}
if (world == null || position == null) {
world = ((CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle();
- position = Vec3.atCenterOf(((ServerLevel) world).getSharedSpawnPos());
+ position = Vec3.atCenterOf(((ServerLevel) world).getSpawn());
}
this.level = world;
this.setPos(position.x(), position.y(), position.z());
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -0,0 +0,0 @@ public abstract class PlayerList {
entityplayer1.setShiftKeyDown(false);
// entityplayer1.playerConnection.a(entityplayer1.locX(), entityplayer1.locY(), entityplayer1.locZ(), entityplayer1.yaw, entityplayer1.pitch);
- entityplayer1.connection.send(new ClientboundSetDefaultSpawnPositionPacket(worldserver1.getSharedSpawnPos(), worldserver1.getSharedSpawnAngle()));
+ entityplayer1.connection.send(new ClientboundSetDefaultSpawnPositionPacket(worldserver1.getSpawn(), worldserver1.getSharedSpawnAngle()));
entityplayer1.connection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked()));
entityplayer1.connection.send(new ClientboundSetExperiencePacket(entityplayer1.experienceProgress, entityplayer1.totalExperience, entityplayer1.experienceLevel));
this.sendLevelInfo(entityplayer1, worldserver1);
@@ -0,0 +0,0 @@ public abstract class PlayerList {
player.connection.send(new ClientboundSetBorderPacket(worldborder, ClientboundSetBorderPacket.Type.INITIALIZE));
player.connection.send(new ClientboundSetTimePacket(world.getGameTime(), world.getDayTime(), world.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)));
- player.connection.send(new ClientboundSetDefaultSpawnPositionPacket(world.getSharedSpawnPos(), world.getSharedSpawnAngle()));
+ player.connection.send(new ClientboundSetDefaultSpawnPositionPacket(world.getSpawn(), world.getSharedSpawnAngle()));
if (world.isRaining()) {
// CraftBukkit start - handle player weather
// entityplayer.playerConnection.sendPacket(new PacketPlayOutGameStateChange(PacketPlayOutGameStateChange.b, 0.0F));
diff --git a/src/main/java/net/minecraft/server/rcon/RconConsoleSource.java b/src/main/java/net/minecraft/server/rcon/RconConsoleSource.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/rcon/RconConsoleSource.java
+++ b/src/main/java/net/minecraft/server/rcon/RconConsoleSource.java
@@ -0,0 +0,0 @@ public class RconConsoleSource implements CommandSource {
public CommandSourceStack createCommandSourceStack() {
ServerLevel worldserver = this.server.overworld();
- return new CommandSourceStack(this, Vec3.atLowerCornerOf((Vec3i) worldserver.getSharedSpawnPos()), Vec2.ZERO, worldserver, 4, "Rcon", RconConsoleSource.RCON_COMPONENT, this.server, (Entity) null);
+ return new CommandSourceStack(this, Vec3.atLowerCornerOf((Vec3i) worldserver.getSpawn()), Vec2.ZERO, worldserver, 4, "Rcon", RconConsoleSource.RCON_COMPONENT, this.server, (Entity) null);
}
// CraftBukkit start - Send a String
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
if (flag1) {
blockposition1 = ServerLevel.END_SPAWN_POINT;
} else {
- blockposition1 = destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, destination.getSharedSpawnPos());
+ blockposition1 = destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, destination.getSpawn());
}
// CraftBukkit start
CraftPortalEvent event = callPortalEvent(this, destination, blockposition1, PlayerTeleportEvent.TeleportCause.END_PORTAL, 0, 0);
diff --git a/src/main/java/net/minecraft/world/entity/animal/Cow.java b/src/main/java/net/minecraft/world/entity/animal/Cow.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Cow.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Cow.java
@@ -0,0 +0,0 @@ public class Cow extends Animal {
if (itemstack.getItem() == Items.BUCKET && !this.isBaby()) {
// CraftBukkit start - Got milk?
- org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level, player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET);
+ org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level, player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, hand); // Paper - add enumHand
if (event.isCancelled()) {
return InteractionResult.PASS;
diff --git a/src/main/java/net/minecraft/world/item/BucketItem.java b/src/main/java/net/minecraft/world/item/BucketItem.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/item/BucketItem.java
+++ b/src/main/java/net/minecraft/world/item/BucketItem.java
@@ -0,0 +0,0 @@ public class BucketItem extends Item {
if (iblockdata.getBlock() instanceof BucketPickup) {
// CraftBukkit start
Fluid dummyFluid = ((BucketPickup) iblockdata.getBlock()).takeLiquid(DummyGeneratorAccess.INSTANCE, blockposition, iblockdata);
- PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) world, user, blockposition, blockposition, movingobjectpositionblock.getDirection(), itemstack, dummyFluid.getBucket());
+ PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) world, user, blockposition, blockposition, movingobjectpositionblock.getDirection(), itemstack, dummyFluid.getBucket(), hand); // Paper - add enumhand
if (event.isCancelled()) {
((ServerPlayer) user).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-5163 (see PlayerInteractManager)
@@ -0,0 +0,0 @@ public class BucketItem extends Item {
iblockdata = world.getBlockState(blockposition);
BlockPos blockposition2 = iblockdata.getBlock() instanceof LiquidBlockContainer && this.content == Fluids.WATER ? blockposition : blockposition1;
- if (this.a(user, world, blockposition2, movingobjectpositionblock1, movingobjectpositionblock1.getDirection(), blockposition, itemstack)) { // CraftBukkit
+ if (this.a(user, world, blockposition2, movingobjectpositionblock1, movingobjectpositionblock1.getDirection(), blockposition, itemstack, hand)) { // CraftBukkit // Paper - add enumhand
this.checkExtraContent(world, itemstack, blockposition2);
if (user instanceof ServerPlayer) {
CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayer) user, blockposition2, itemstack);
@@ -0,0 +0,0 @@ public class BucketItem extends Item {
public void checkExtraContent(Level world, ItemStack stack, BlockPos pos) {}
public boolean emptyBucket(@Nullable Player player, Level world, BlockPos pos, @Nullable BlockHitResult movingobjectpositionblock) {
- return a(player, world, pos, movingobjectpositionblock, null, null, null);
+ // Paper start - add enumHand
+ return a(player, world, pos, movingobjectpositionblock, null, null, null, null);
}
- public boolean a(Player entityhuman, Level world, BlockPos blockposition, @Nullable BlockHitResult movingobjectpositionblock, Direction enumdirection, BlockPos clicked, ItemStack itemstack) {
+ public boolean a(Player entityhuman, Level world, BlockPos blockposition, @Nullable BlockHitResult movingobjectpositionblock, Direction enumdirection, BlockPos clicked, ItemStack itemstack, InteractionHand enumhand) {
+ // Paper end
// CraftBukkit end
if (!(this.content instanceof FlowingFluid)) {
return false;
@@ -0,0 +0,0 @@ public class BucketItem extends Item {
// CraftBukkit start
if (flag1 && entityhuman != null) {
- PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent((ServerLevel) world, entityhuman, blockposition, clicked, enumdirection, itemstack);
+ PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent((ServerLevel) world, entityhuman, blockposition, clicked, enumdirection, itemstack, enumhand); // Paper - add enumhand
if (event.isCancelled()) {
((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-4238: needed when looking through entity
((ServerPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-4541
@@ -0,0 +0,0 @@ public class BucketItem extends Item {
}
// CraftBukkit end
if (!flag1) {
- return movingobjectpositionblock != null && this.a(entityhuman, world, movingobjectpositionblock.getBlockPos().relative(movingobjectpositionblock.getDirection()), (BlockHitResult) null, enumdirection, clicked, itemstack); // CraftBukkit
+ return movingobjectpositionblock != null && this.a(entityhuman, world, movingobjectpositionblock.getBlockPos().relative(movingobjectpositionblock.getDirection()), (BlockHitResult) null, enumdirection, clicked, itemstack, enumhand); // CraftBukkit // Paper - add enumhand
} else if (world.dimensionType().ultraWarm() && this.content.is((Tag) FluidTags.WATER)) {
int i = blockposition.getX();
int j = blockposition.getY();
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
}
// Paper end
+ // Paper start - moved up from WorldServer
+ public BlockPos getSpawn() {
+ BlockPos blockposition = new BlockPos(this.levelData.getXSpawn(), this.levelData.getYSpawn(), this.levelData.getZSpawn());
+
+ if (!this.getWorldBorder().isWithinBounds(blockposition)) {
+ blockposition = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, new BlockPos(this.getWorldBorder().getCenterX(), 0.0D, this.getWorldBorder().getCenterZ()));
+ }
+
+ return blockposition;
+ }
+ // Paper end
@Override
public boolean isClientSide() {
return this.isClientSide;
diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
@@ -0,0 +0,0 @@ public final class NaturalSpawner {
private static boolean isRightDistanceToPlayerAndSpawnPoint(ServerLevel world, ChunkAccess chunk, BlockPos.MutableBlockPos pos, double squaredDistance) {
if (squaredDistance <= 576.0D) {
return false;
- } else if (world.getSharedSpawnPos().closerThan((Position) (new Vec3((double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D)), 24.0D)) {
+ } else if (world.getSpawn().closerThan((Position) (new Vec3((double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D)), 24.0D)) {
return false;
} else {
ChunkPos chunkcoordintpair = new ChunkPos(pos);
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -0,0 +0,0 @@ public class CraftWorld implements World {
@Override
public Location getSpawnLocation() {
- BlockPos spawn = world.getSharedSpawnPos();
+ BlockPos spawn = world.getSpawn();
return new Location(this, spawn.getX(), spawn.getY(), spawn.getZ());
}
@@ -0,0 +0,0 @@ public class CraftWorld implements World {
public void setKeepSpawnInMemory(boolean keepLoaded) {
world.keepSpawnInMemory = keepLoaded;
// Grab the worlds spawn chunk
- BlockPos chunkcoordinates = this.world.getSharedSpawnPos();
+ BlockPos chunkcoordinates = this.world.getSpawn();
if (keepLoaded) {
world.getChunkSource().addRegionTicket(TicketType.START, new ChunkPos(chunkcoordinates), 11, Unit.INSTANCE);
} else {
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -0,0 +0,0 @@ public class CraftEventFactory {
public static Entity entityDamage; // For use in EntityDamageByEntityEvent
// helper methods
- private static boolean canBuild(ServerLevel world, Player player, int x, int z) {
+ private static boolean canBuild(Level world, Player player, int x, int z) {
int spawnSize = Bukkit.getServer().getSpawnRadius();
if (world.dimension() != Level.OVERWORLD) return true;
@@ -0,0 +0,0 @@ public class CraftEventFactory {
if (((CraftServer) Bukkit.getServer()).getHandle().getOps().isEmpty()) return true;
if (player.isOp()) return true;
- BlockPos chunkcoordinates = world.getSharedSpawnPos();
+ BlockPos chunkcoordinates = world.getSpawn();
int distanceFromSpawn = Math.max(Math.abs(x - chunkcoordinates.getX()), Math.abs(z - chunkcoordinates.getZ()));
return distanceFromSpawn > spawnSize;
@@ -0,0 +0,0 @@ public class CraftEventFactory {
}
private static PlayerEvent getPlayerBucketEvent(boolean isFilling, ServerLevel world, net.minecraft.world.entity.player.Player who, BlockPos changed, BlockPos clicked, Direction clickedFace, ItemStack itemstack, net.minecraft.world.item.Item item) {
+ // Paper start - add enumHand
+ return getPlayerBucketEvent(isFilling, world, who, changed, clicked, clickedFace, itemstack, item, null);
+ }
+
+ public static PlayerBucketEmptyEvent callPlayerBucketEmptyEvent(Level world, net.minecraft.world.entity.player.Player who, BlockPos changed, BlockPos clicked, Direction clickedFace, ItemStack itemstack, InteractionHand enumHand) {
+ return (PlayerBucketEmptyEvent) getPlayerBucketEvent(false, world, who, changed, clicked, clickedFace, itemstack, Items.BUCKET, enumHand);
+ }
+
+ public static PlayerBucketFillEvent callPlayerBucketFillEvent(Level world, net.minecraft.world.entity.player.Player who, BlockPos changed, BlockPos clicked, Direction clickedFace, ItemStack itemInHand, net.minecraft.world.item.Item bucket, InteractionHand enumHand) {
+ return (PlayerBucketFillEvent) getPlayerBucketEvent(true, world, who, clicked, changed, clickedFace, itemInHand, bucket, enumHand);
+ }
+
+ private static PlayerEvent getPlayerBucketEvent(boolean isFilling, Level world, net.minecraft.world.entity.player.Player who, BlockPos changed, BlockPos clicked, Direction clickedFace, ItemStack itemstack, net.minecraft.world.item.Item item, InteractionHand enumHand) {
+ // Paper end
Player player = (Player) who.getBukkitEntity();
CraftItemStack itemInHand = CraftItemStack.asNewCraftStack(item);
Material bucket = CraftMagicNumbers.getMaterial(itemstack.getItem());
@@ -0,0 +0,0 @@ public class CraftEventFactory {
PlayerEvent event;
if (isFilling) {
- event = new PlayerBucketFillEvent(player, block, blockClicked, blockFace, bucket, itemInHand);
+ event = new PlayerBucketFillEvent(player, block, blockClicked, blockFace, bucket, itemInHand, enumHand == null ? null : enumHand == InteractionHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND); // Paper - add enumHand
((PlayerBucketFillEvent) event).setCancelled(!canBuild(world, player, changed.getX(), changed.getZ()));
} else {
- event = new PlayerBucketEmptyEvent(player, block, blockClicked, blockFace, bucket, itemInHand);
+ event = new PlayerBucketEmptyEvent(player, block, blockClicked, blockFace, bucket, itemInHand, enumHand == null ? null : enumHand == InteractionHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND); // Paper - add enumHand
((PlayerBucketEmptyEvent) event).setCancelled(!canBuild(world, player, changed.getX(), changed.getZ()));
}

View File

@ -1,99 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 23 Jul 2018 22:44:23 -0400
Subject: [PATCH] Add some Debug to Chunk Entity slices
If we detect unexpected state, log and try to recover
This should hopefully avoid duplicate entities ever being created
if the entity was to end up in 2 different chunk slices
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
}
}
};
+ public List<Entity> entitySlice = null;
// Paper end
public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
@@ -0,0 +0,0 @@ import net.minecraft.ReportedException;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
import net.minecraft.nbt.CompoundTag;
+import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ChunkHolder;
+import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
if (k >= this.entitySlices.length) {
k = this.entitySlices.length - 1;
}
+ // Paper - remove from any old list if its in one
+ List<Entity> nextSlice = this.entitySlices[k]; // the next list to be added to
+ List<Entity> currentSlice = entity.entitySlice;
+ if (nextSlice == currentSlice) {
+ if (Level.DEBUG_ENTITIES) MinecraftServer.LOGGER.warn("Entity was already in this chunk!" + entity, new Throwable());
+ return; // ??? silly plugins
+ }
+ if (currentSlice != null && currentSlice.contains(entity)) {
+ // Still in an old chunk...
+ if (Level.DEBUG_ENTITIES) MinecraftServer.LOGGER.warn("Entity is still in another chunk!" + entity, new Throwable());
+ LevelChunk chunk = entity.getCurrentChunk();
+ if (chunk != null) {
+ chunk.removeEntity(entity);
+ } else {
+ removeEntity(entity);
+ }
+ currentSlice.remove(entity); // Just incase the above did not remove from the previous slice
+ }
+ // Paper end
if (!entity.inChunk || entity.getCurrentChunk() != this) entityCounts.increment(entity.getMinecraftKeyString()); // Paper
entity.inChunk = true;
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
entity.zChunk = this.chunkPos.z;
this.entities.add(entity); // Paper - per chunk entity list
this.entitySlices[k].add(entity);
+ entity.entitySlice = this.entitySlices[k]; // Paper
this.markUnsaved(); // Paper
}
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
// Paper start
if (entity.currentChunk != null && entity.currentChunk.get() == this) entity.setCurrentChunk(null);
+ if (entitySlices[section] == entity.entitySlice) {
+ entity.entitySlice = null;
+ entity.inChunk = false;
+ }
if (!this.entitySlices[section].remove(entity)) {
return;
}
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
// Paper start - neighbour cache
int chunkX = this.chunkPos.x;
int chunkZ = this.chunkPos.z;
- ChunkProviderServer chunkProvider = ((ServerLevel)this.world).getChunkSource();
+ ServerChunkCache chunkProvider = ((ServerLevel)this.world).getChunkSource();
for (int dx = -NEIGHBOUR_CACHE_RADIUS; dx <= NEIGHBOUR_CACHE_RADIUS; ++dx) {
for (int dz = -NEIGHBOUR_CACHE_RADIUS; dz <= NEIGHBOUR_CACHE_RADIUS; ++dz) {
LevelChunk neighbour = chunkProvider.getChunkAtIfLoadedMainThreadNoCache(chunkX + dx, chunkZ + dz);
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
// Paper start - neighbour cache
int chunkX = this.chunkPos.x;
int chunkZ = this.chunkPos.z;
- ChunkProviderServer chunkProvider = ((ServerLevel)this.world).getChunkSource();
+ ServerChunkCache chunkProvider = ((ServerLevel)this.world).getChunkSource();
for (int dx = -NEIGHBOUR_CACHE_RADIUS; dx <= NEIGHBOUR_CACHE_RADIUS; ++dx) {
for (int dz = -NEIGHBOUR_CACHE_RADIUS; dz <= NEIGHBOUR_CACHE_RADIUS; ++dz) {
LevelChunk neighbour = chunkProvider.getChunkAtIfLoadedMainThreadNoCache(chunkX + dx, chunkZ + dz);

View File

@ -1,120 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sat, 28 Jul 2018 12:18:27 -0400
Subject: [PATCH] Ignore Dead Entities in entityList iteration
A spigot change delays removal of entities from the entity list.
This causes a change in behavior from Vanilla where getEntities type
methods will return dead entities that they shouldn't otherwise be doing.
This will ensure that dead entities are skipped from iteration since
they shouldn't of been in the list in the first place.
diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/com/destroystokyo/paper/PaperCommand.java
+++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
@@ -0,0 +0,0 @@ public class PaperCommand extends Command {
Collection<Entity> entities = world.entitiesById.values();
entities.forEach(e -> {
ResourceLocation key = e.getMinecraftKey();
+ if (e.shouldBeRemoved) return; // Paper
MutablePair<Integer, Map<ChunkPos, Integer>> info = list.computeIfAbsent(key, k -> MutablePair.of(0, Maps.newHashMap()));
ChunkPos chunk = new ChunkPos(e.xChunk, e.zChunk);
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
entity.origin = entity.getBukkitEntity().getLocation();
}
// Paper end
+ entity.shouldBeRemoved = false; // Paper - shouldn't be removed after being re-added
new com.destroystokyo.paper.event.entity.EntityAddToWorldEvent(entity.getBukkitEntity()).callEvent(); // Paper - fire while valid
}
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
this.removeFromChunk(entity);
this.entitiesById.remove(entity.getId());
this.onEntityRemoved(entity);
+ entity.shouldBeRemoved = true; // Paper
}
}
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
protected int numCollisions = 0; // Paper
public void inactiveTick() { }
// Spigot end
+ public boolean shouldBeRemoved; // Paper
public float getBukkitYaw() {
return this.yRot;
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
for (int i1 = 0; i1 < l; ++i1) {
Entity entity1 = (Entity) list1.get(i1);
+ if (entity1.shouldBeRemoved) continue; // Paper
if (entity1.getBoundingBox().intersects(box) && entity1 != except) {
if (predicate == null || predicate.test(entity1)) {
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
while (iterator.hasNext()) {
T entity = (T) iterator.next(); // CraftBukkit - decompile error
+ if (entity.shouldBeRemoved) continue; // Paper
if ((type == null || entity.getType() == type) && entity.getBoundingBox().intersects(box) && predicate.test(entity)) {
result.add(entity);
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
while (iterator.hasNext()) {
T t0 = (T) iterator.next(); // CraftBukkit - decompile error
+ if (t0.shouldBeRemoved) continue; // Paper
if (entityClass.isInstance(t0) && t0.getBoundingBox().intersects(box) && (predicate == null || predicate.test(t0))) { // Spigot - instance check
result.add(t0);
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -0,0 +0,0 @@ public class CraftWorld implements World {
for (Object o : world.entitiesById.values()) {
if (o instanceof net.minecraft.world.entity.Entity) {
net.minecraft.world.entity.Entity mcEnt = (net.minecraft.world.entity.Entity) o;
+ if (mcEnt.shouldBeRemoved) continue; // Paper
Entity bukkitEntity = mcEnt.getBukkitEntity();
// Assuming that bukkitEntity isn't null
@@ -0,0 +0,0 @@ public class CraftWorld implements World {
for (Object o : world.entitiesById.values()) {
if (o instanceof net.minecraft.world.entity.Entity) {
net.minecraft.world.entity.Entity mcEnt = (net.minecraft.world.entity.Entity) o;
+ if (mcEnt.shouldBeRemoved) continue; // Paper
Entity bukkitEntity = mcEnt.getBukkitEntity();
// Assuming that bukkitEntity isn't null
@@ -0,0 +0,0 @@ public class CraftWorld implements World {
for (Object entity: world.entitiesById.values()) {
if (entity instanceof net.minecraft.world.entity.Entity) {
+ if (((net.minecraft.world.entity.Entity) entity).shouldBeRemoved) continue; // Paper
Entity bukkitEntity = ((net.minecraft.world.entity.Entity) entity).getBukkitEntity();
if (bukkitEntity == null) {
@@ -0,0 +0,0 @@ public class CraftWorld implements World {
for (Object entity: world.entitiesById.values()) {
if (entity instanceof net.minecraft.world.entity.Entity) {
+ if (((net.minecraft.world.entity.Entity) entity).shouldBeRemoved) continue; // Paper
Entity bukkitEntity = ((net.minecraft.world.entity.Entity) entity).getBukkitEntity();
if (bukkitEntity == null) {

View File

@ -1,28 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Fri, 3 Aug 2018 00:04:54 -0400
Subject: [PATCH] MC-135506: Experience should save as Integers
diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
+++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
@@ -0,0 +0,0 @@ public class ExperienceOrb extends Entity {
public void addAdditionalSaveData(CompoundTag tag) {
tag.putShort("Health", (short) this.health);
tag.putShort("Age", (short) this.age);
- tag.putShort("Value", (short) this.value);
+ tag.putInt("Value", this.value); // Paper - save as Integer
this.savePaperNBT(tag); // Paper
}
@@ -0,0 +0,0 @@ public class ExperienceOrb extends Entity {
public void readAdditionalSaveData(CompoundTag tag) {
this.health = tag.getShort("Health");
this.age = tag.getShort("Age");
- this.value = tag.getShort("Value");
+ this.value = tag.getInt("Value"); // Paper - load as Integer
this.loadPaperNBT(tag); // Paper
}

View File

@ -1,27 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 23 Jul 2018 22:18:31 -0400
Subject: [PATCH] Mark chunk dirty anytime entities change to guarantee it
saves
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
entity.zChunk = this.chunkPos.z;
this.entities.add(entity); // Paper - per chunk entity list
this.entitySlices[k].add(entity);
+ this.markUnsaved(); // Paper
}
@Override
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
return;
}
entityCounts.decrement(entity.getMinecraftKeyString());
+ this.markUnsaved(); // Paper
// Paper end
this.entities.remove(entity); // Paper
}

View File

@ -1,96 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 26 Aug 2018 20:49:50 -0400
Subject: [PATCH] Optimize RegistryMaterials
Use larger initial sizes to increase bucket capacity on the BiMap
BiMap.get was seen to be using a good bit of CPU time.
diff --git a/src/main/java/net/minecraft/core/MappedRegistry.java b/src/main/java/net/minecraft/core/MappedRegistry.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/core/MappedRegistry.java
+++ b/src/main/java/net/minecraft/core/MappedRegistry.java
@@ -0,0 +0,0 @@ import net.minecraft.Util;
import net.minecraft.resources.RegistryDataPackCodec;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
+import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; // Paper
import org.apache.commons.lang3.Validate;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -0,0 +0,0 @@ public class MappedRegistry<T> extends WritableRegistry<T> {
protected static final Logger LOGGER = LogManager.getLogger();
private final ObjectList<T> byId = new ObjectArrayList(256);
- private final Object2IntMap<T> toId = new Object2IntOpenCustomHashMap(Util.identityStrategy());
+ private final Reference2IntOpenHashMap<T> bg = new Reference2IntOpenHashMap<T>(2048);// Paper - use bigger expected size to reduce collisions and direct intent for FastUtil to be identity map
private final BiMap<ResourceLocation, T> storage;
private final BiMap<ResourceKey<T>, T> keyStorage;
private final Map<T, Lifecycle> lifecycles;
@@ -0,0 +0,0 @@ public class MappedRegistry<T> extends WritableRegistry<T> {
public MappedRegistry(ResourceKey<? extends Registry<T>> key, Lifecycle lifecycle) {
super(key, lifecycle);
- this.toId.defaultReturnValue(-1);
- this.storage = HashBiMap.create();
- this.keyStorage = HashBiMap.create();
- this.lifecycles = Maps.newIdentityHashMap();
+ this.bg.defaultReturnValue(-1);
+ this.storage = HashBiMap.create(2048); // Paper - use bigger expected size to reduce collisions
+ this.keyStorage = HashBiMap.create(2048); // Paper - use bigger expected size to reduce collisions
+ this.lifecycles = new java.util.IdentityHashMap<>(2048); // Paper - use bigger expected size to reduce collisions
this.elementsLifecycle = lifecycle;
}
@@ -0,0 +0,0 @@ public class MappedRegistry<T> extends WritableRegistry<T> {
Validate.notNull(entry);
this.byId.size(Math.max(this.byId.size(), rawId + 1));
this.byId.set(rawId, entry);
- this.toId.put(entry, rawId);
+ this.bg.put(entry, rawId);
this.randomCache = null;
if (checkDuplicateKeys && this.keyStorage.containsKey(key)) {
MappedRegistry.LOGGER.debug("Adding duplicate key '{}' to registry", key);
@@ -0,0 +0,0 @@ public class MappedRegistry<T> extends WritableRegistry<T> {
if (t0 == null) {
i = rawId.isPresent() ? rawId.getAsInt() : this.nextId;
} else {
- i = this.toId.getInt(t0);
+ i = this.bg.getInt(t0);
if (rawId.isPresent() && rawId.getAsInt() != i) {
throw new IllegalStateException("ID mismatch");
}
- this.toId.removeInt(t0);
+ this.bg.removeInt(t0);
this.lifecycles.remove(t0);
}
@@ -0,0 +0,0 @@ public class MappedRegistry<T> extends WritableRegistry<T> {
@Override
public int getId(@Nullable T entry) {
- return this.toId.getInt(entry);
+ return this.bg.getInt(entry);
}
@Nullable
@@ -0,0 +0,0 @@ public class MappedRegistry<T> extends WritableRegistry<T> {
this.randomCache = collection.toArray(new Object[collection.size()]);
}
- return Util.getRandom(this.randomCache, random);
+ return (T) Util.getRandom(this.randomCache, random); // Paper - Decompile fix
}
public static <T> Codec<MappedRegistry<T>> networkCodec(ResourceKey<? extends Registry<T>> resourcekey, Lifecycle lifecycle, Codec<T> entryCodec) {
@@ -0,0 +0,0 @@ public class MappedRegistry<T> extends WritableRegistry<T> {
Iterator iterator = registrymaterials.iterator();
while (iterator.hasNext()) {
- T t0 = iterator.next();
+ T t0 = (T) iterator.next(); // Paper - Decompile fix
builder.add(new MappedRegistry.RegistryEntry<>((ResourceKey) registrymaterials.getResourceKey(t0).get(), registrymaterials.getId(t0), t0));
}

View File

@ -1,127 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Thu, 26 Jul 2018 00:11:12 -0400
Subject: [PATCH] Prevent Saving Bad entities to chunks
See https://github.com/PaperMC/Paper/issues/1223
Minecraft is saving invalid entities to the chunk files.
Avoid saving bad data, and also make improvements to handle
loading these chunks. Any invalid entity will be instant killed,
so lets avoid adding it to the world...
This lets us be safer about the dupe UUID resolver too, as now
we can ignore instant killed entities and avoid risk of duplicating
an invalid entity.
This should reduce log occurrences of dupe uuid messages.
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
List[] aentityslice = chunk.getEntitySlices(); // Spigot
int i = aentityslice.length;
+ java.util.List<Entity> toMoveChunks = new java.util.ArrayList<>(); // Paper
for (int j = 0; j < i; ++j) {
List<Entity> entityslice = aentityslice[j]; // Spigot
Iterator iterator = entityslice.iterator();
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
throw (IllegalStateException) Util.pauseInIde((Throwable) (new IllegalStateException("Removing entity while ticking!")));
}
+ // Paper start - move out entities that shouldn't be in this chunk before it unloads
+ if (!entity.removed && (int) Math.floor(entity.getX()) >> 4 != chunk.getPos().x || (int) Math.floor(entity.getZ()) >> 4 != chunk.getPos().z) {
+ toMoveChunks.add(entity);
+ continue;
+ }
+ // Paper end
+
this.entitiesById.remove(entity.getId());
this.onEntityRemoved(entity);
+
+ if (entity.removed) iterator.remove(); // Paper - don't save dead entities during unload
}
}
}
+ // Paper start - move out entities that shouldn't be in this chunk before it unloads
+ for (Entity entity : toMoveChunks) {
+ this.updateChunkPos(entity);
+ }
+ // Paper end
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
@@ -0,0 +0,0 @@ import net.minecraft.nbt.LongArrayTag;
import net.minecraft.nbt.ShortTag;
import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.level.ThreadedLevelLightEngine;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
@@ -0,0 +0,0 @@ public class ChunkSerializer {
nbttagcompound1.put("TileEntities", nbttaglist1);
ListTag nbttaglist2 = new ListTag();
+ java.util.List<Entity> toUpdate = new java.util.ArrayList<>(); // Paper
if (chunk.getStatus().getChunkType() == ChunkStatus.ChunkType.LEVELCHUNK) {
LevelChunk chunk1 = (LevelChunk) chunk;
@@ -0,0 +0,0 @@ public class ChunkSerializer {
while (iterator1.hasNext()) {
Entity entity = (Entity) iterator1.next();
CompoundTag nbttagcompound4 = new CompoundTag();
-
+ // Paper start
+ if ((int) Math.floor(entity.getX()) >> 4 != chunk1.getPos().x || (int) Math.floor(entity.getZ()) >> 4 != chunk1.getPos().z) {
+ toUpdate.add(entity);
+ continue;
+ }
+ if (entity.removed || hasPlayerPassenger(entity)) {
+ continue;
+ }
+ // Paper end
if (entity.save(nbttagcompound4)) {
chunk1.setLastSaveHadEntities(true);
nbttaglist2.add(nbttagcompound4);
}
}
}
+
+ // Paper start - move entities to the correct chunk
+ for (Entity entity : toUpdate) {
+ world.updateChunkPos(entity);
+ }
+ // Paper end
+
} else {
ProtoChunk protochunk = (ProtoChunk) chunk;
@@ -0,0 +0,0 @@ public class ChunkSerializer {
nbttagcompound1.put("Structures", packStructureData(chunkcoordintpair, chunk.getAllStarts(), chunk.getAllReferences()));
return nbttagcompound;
}
+ // Paper start - this is saved with the player
+ private static boolean hasPlayerPassenger(Entity entity) {
+ for (Entity passenger : entity.passengers) {
+ if (passenger instanceof ServerPlayer) {
+ return true;
+ }
+ if (hasPlayerPassenger(passenger)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ // Paper end
public static ChunkStatus.ChunkType getChunkTypeFromTag(@Nullable CompoundTag tag) {
if (tag != null) {

View File

@ -29,25 +29,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ @Override
+ public BlockState[] getTileEntities(boolean useSnapshot) {
if (!isLoaded()) {
getWorld().getChunkAt(x, z); // Transient load for this tick
}
+ // Paper end
int index = 0;
net.minecraft.world.level.chunk.LevelChunk chunk = getHandle();
if (!this.isLoaded()) {
this.getWorld().getChunkAt(x, z); // Transient load for this tick
}
@@ -0,0 +0,0 @@ public class CraftChunk implements Chunk {
}
BlockPos position = (BlockPos) obj;
- entities[index++] = worldServer.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()).getState();
+ entities[index++] = worldServer.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()).getState(useSnapshot); // Paper
- entities[index++] = this.worldServer.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()).getState();
+ // Paper start
+ entities[index++] = this.worldServer.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()).getState(useSnapshot);
+ }
+
+ return entities;
+ }
+
+ // Paper start
+ @Override
+ public Collection<BlockState> getTileEntities(Predicate<Block> blockPredicate, boolean useSnapshot) {
+ Preconditions.checkNotNull(blockPredicate, "blockPredicate");
@ -63,11 +60,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (blockPredicate.test(block)) {
+ entities.add(block.getState(useSnapshot));
+ }
+ // Paper end
}
return entities;
}
+ // Paper end
@Override
public boolean isLoaded() {

View File

@ -56,13 +56,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public void reload() {
+ org.spigotmc.WatchdogThread.hasStarted = false; // Paper - Disable watchdog early timeout on reload
reloadCount++;
configuration = YamlConfiguration.loadConfiguration(getConfigFile());
commandsConfiguration = YamlConfiguration.loadConfiguration(getCommandsConfigFile());
this.reloadCount++;
this.configuration = YamlConfiguration.loadConfiguration(this.getConfigFile());
this.commandsConfiguration = YamlConfiguration.loadConfiguration(this.getCommandsConfigFile());
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
enablePlugins(PluginLoadOrder.STARTUP);
enablePlugins(PluginLoadOrder.POSTWORLD);
getPluginManager().callEvent(new ServerLoadEvent(ServerLoadEvent.LoadType.RELOAD));
this.enablePlugins(PluginLoadOrder.STARTUP);
this.enablePlugins(PluginLoadOrder.POSTWORLD);
this.getPluginManager().callEvent(new ServerLoadEvent(ServerLoadEvent.LoadType.RELOAD));
+ org.spigotmc.WatchdogThread.hasStarted = true; // Paper - Disable watchdog early timeout on reload
}
@ -72,9 +72,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -0,0 +0,0 @@ public class SpigotConfig
restartScript = getString( "settings.restart-script", restartScript );
restartMessage = transform( getString( "messages.restart", "Server is restarting" ) );
commands.put( "restart", new RestartCommand( "restart" ) );
SpigotConfig.restartScript = SpigotConfig.getString( "settings.restart-script", SpigotConfig.restartScript );
SpigotConfig.restartMessage = SpigotConfig.transform( SpigotConfig.getString( "messages.restart", "Server is restarting" ) );
SpigotConfig.commands.put( "restart", new RestartCommand( "restart" ) );
- WatchdogThread.doStart( timeoutTime, restartOnCrash );
+ //WatchdogThread.doStart( timeoutTime, restartOnCrash ); // Paper - moved to PaperConfig
}
@ -113,15 +113,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private static long monotonicMillis()
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
{
while ( !stopping )
while ( !this.stopping )
{
- //
- if ( lastTick != 0 && timeoutTime > 0 && monotonicMillis() > lastTick + timeoutTime && !Boolean.getBoolean("disable.watchdog")) // Paper - Add property to disable
//
- if ( this.lastTick != 0 && this.timeoutTime > 0 && WatchdogThread.monotonicMillis() > this.lastTick + this.timeoutTime && !Boolean.getBoolean("disable.watchdog")) // Paper - Add property to disable
+ // Paper start
+ Logger log = Bukkit.getServer().getLogger();
+ long currentTime = monotonicMillis();
+ if ( lastTick != 0 && timeoutTime > 0 && currentTime > lastTick + earlyWarningEvery && !Boolean.getBoolean("disable.watchdog") )
+ long currentTime = WatchdogThread.monotonicMillis();
+ if ( this.lastTick != 0 && this.timeoutTime > 0 && currentTime > this.lastTick + this.earlyWarningEvery && !Boolean.getBoolean("disable.watchdog")) // Paper - Add property to disable
{
- Logger log = Bukkit.getServer().getLogger();
+ boolean isLongTimeout = currentTime > lastTick + timeoutTime;
@ -146,7 +145,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end - Different message for short timeout
log.log( Level.SEVERE, "------------------------------" );
log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
log.log( Level.SEVERE, "------------------------------" );
//
+ // Paper start - Only print full dump on long timeouts
@ -156,18 +155,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads( true, true );
for ( ThreadInfo thread : threads )
{
dumpThread( thread, log );
WatchdogThread.dumpThread( thread, log );
}
+ } else {
+ log.log(Level.SEVERE, "--- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH ---");
+ }
+
+
log.log( Level.SEVERE, "------------------------------" );
+ if ( isLongTimeout )
+ {
if ( restart && !MinecraftServer.getServer().hasStopped() )
if ( this.restart && !MinecraftServer.getServer().hasStopped() )
{
RestartCommand.restart();
}

View File

@ -8,7 +8,7 @@ diff --git a/src/main/java/net/minecraft/world/entity/monster/Creeper.java b/src
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
@@ -0,0 +0,0 @@ public class Creeper extends Monster {
@@ -0,0 +0,0 @@ public class Creeper extends Monster implements PowerableMob {
}
public void ignite() {
@ -38,10 +38,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
+
+ // Paper start
+ @Override
+ public void setIgnited(boolean ignited) {
+ getHandle().setIgnited(ignited);
+ }
+
+ @Override
+ public boolean isIgnited() {
+ return getHandle().isIgnited();
+ }

View File

@ -11,22 +11,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public class Phantom extends FlyingMob implements Enemy {
}
this.setPhantomSize(tag.getInt("Size"));
this.setPhantomSize(nbt.getInt("Size"));
+ // Paper start
+ if (tag.hasUUID("Paper.SpawningEntity")) {
+ this.spawningEntity = tag.getUUID("Paper.SpawningEntity");
+ if (nbt.hasUUID("Paper.SpawningEntity")) {
+ this.spawningEntity = nbt.getUUID("Paper.SpawningEntity");
+ }
+ // Paper end
}
@Override
@@ -0,0 +0,0 @@ public class Phantom extends FlyingMob implements Enemy {
tag.putInt("AY", this.anchorPoint.getY());
tag.putInt("AZ", this.anchorPoint.getZ());
tag.putInt("Size", this.getPhantomSize());
nbt.putInt("AY", this.anchorPoint.getY());
nbt.putInt("AZ", this.anchorPoint.getZ());
nbt.putInt("Size", this.getPhantomSize());
+ // Paper start
+ if (this.spawningEntity != null) {
+ tag.setUUID("Paper.SpawningEntity", this.spawningEntity);
+ nbt.setUUID("Paper.SpawningEntity", this.spawningEntity);
+ }
+ // Paper end
}
@ -44,10 +44,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ public void setSpawningEntity(java.util.UUID entity) { this.spawningEntity = entity; }
+ // Paper end
+
class PhantomAttackPlayerTargetGoal extends Goal {
private static enum AttackPhase {
private final TargetingConditions attackTargeting;
CIRCLE, SWOOP;
diff --git a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
@ -89,6 +88,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
+
+ // Paper start
+ @Override
+ public java.util.UUID getSpawningEntity() {
+ return getHandle().getSpawningEntity();
+ }

View File

@ -8,21 +8,13 @@ diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDrag
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
@@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.block.CraftBlock;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent;
// CraftBukkit end
+import com.destroystokyo.paper.event.block.TNTPrimeEvent; // Paper - TNTPrimeEvent
public class EnderDragon extends Mob implements Enemy {
@@ -0,0 +0,0 @@ public class EnderDragon extends Mob implements Enemy {
});
craftBlock.getNMS().spawnAfterBreak((ServerLevel) level, blockposition, ItemStack.EMPTY);
}
+ // Paper start - TNTPrimeEvent
+ org.bukkit.block.Block tntBlock = level.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ());
+ if(!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.EXPLOSION, explosionSource.getSourceMob().getBukkitEntity()).callEvent())
+ if(!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.EXPLOSION, explosionSource.getSourceMob().getBukkitEntity()).callEvent())
+ continue;
+ // Paper end
nmsBlock.wasExploded(level, blockposition, explosionSource);
@ -32,22 +24,6 @@ diff --git a/src/main/java/net/minecraft/world/level/block/FireBlock.java b/src/
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/FireBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/FireBlock.java
@@ -0,0 +0,0 @@ package net.minecraft.world.level.block;
import com.google.common.collect.ImmutableMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
+import com.destroystokyo.paper.event.block.TNTPrimeEvent; // Paper - TNTPrimeEvent
import java.util.Map;
import java.util.Random;
import java.util.function.Function;
@@ -0,0 +0,0 @@ import net.minecraft.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Vec3i;
+import net.minecraft.server.MCUtil;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
@@ -0,0 +0,0 @@ public class FireBlock extends BaseFireBlock {
world.setBlock(blockposition, this.getStateWithAge(world, blockposition, l), 3);
@ -62,8 +38,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
TntBlock blocktnt = (TntBlock) block;
+ // Paper start - TNTPrimeEvent
+ org.bukkit.block.Block tntBlock = MCUtil.toBukkitBlock(world, blockposition);
+ if (!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.FIRE, null).callEvent()) {
+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, blockposition);
+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.FIRE, null).callEvent()) {
+ return;
+ }
+ world.setAir(blockposition, false);
@ -75,24 +51,16 @@ diff --git a/src/main/java/net/minecraft/world/level/block/TntBlock.java b/src/m
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/TntBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/TntBlock.java
@@ -0,0 +0,0 @@ import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.phys.BlockHitResult;
+import com.destroystokyo.paper.event.block.TNTPrimeEvent; // Paper - TNTPrimeEvent
public class TntBlock extends Block {
@@ -0,0 +0,0 @@ public class TntBlock extends Block {
public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) {
if (!oldState.is(state.getBlock())) {
if (world.hasNeighborSignal(pos)) {
+ // Paper start - TNTPrimeEvent
+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, pos);;
+ if(!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent())
+ if(!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent())
+ return;
+ // Paper end
explode(world, pos);
TntBlock.explode(world, pos);
world.removeBlock(pos, false);
}
@@ -0,0 +0,0 @@ public class TntBlock extends Block {
@ -101,10 +69,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (world.hasNeighborSignal(pos)) {
+ // Paper start - TNTPrimeEvent
+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, pos);;
+ if(!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent())
+ if(!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent())
+ return;
+ // Paper end
explode(world, pos);
TntBlock.explode(world, pos);
world.removeBlock(pos, false);
}
@@ -0,0 +0,0 @@ public class TntBlock extends Block {
@ -114,35 +82,34 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper start - TNTPrimeEvent
+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, pos);
+ org.bukkit.entity.Entity source = explosion.source != null ? explosion.source.getBukkitEntity() : null;
+ if(!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.EXPLOSION, source).callEvent())
+ if(!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.EXPLOSION, source).callEvent())
+ return;
+ // Paper end
PrimedTnt entitytntprimed = new PrimedTnt(world, (double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D, explosion.getSourceMob());
int i = entitytntprimed.getFuse();
entitytntprimed.setFuse((short) (world.random.nextInt(entitytntprimed.getLife() / 4) + entitytntprimed.getLife() / 8));
@@ -0,0 +0,0 @@ public class TntBlock extends Block {
if (item != Items.FLINT_AND_STEEL && item != Items.FIRE_CHARGE) {
if (!itemstack.is(Items.FLINT_AND_STEEL) && !itemstack.is(Items.FIRE_CHARGE)) {
return super.use(state, world, pos, player, hand, hit);
} else {
+ // Paper start - TNTPrimeEvent
+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, pos);
+ if(!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.ITEM, player.getBukkitEntity()).callEvent())
+ if(!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.ITEM, player.getBukkitEntity()).callEvent())
+ return InteractionResult.FAIL;
+ // Paper end
explode(world, pos, (LivingEntity) player);
TntBlock.explode(world, pos, (LivingEntity) player);
world.setBlock(pos, Blocks.AIR.defaultBlockState(), 11);
if (!player.isCreative()) {
Item item = itemstack.getItem();
@@ -0,0 +0,0 @@ public class TntBlock extends Block {
return;
}
// CraftBukkit end
+ // Paper start - TNTPrimeEvent
+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, blockposition);
+ if (!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.PROJECTILE, projectile.getBukkitEntity()).callEvent()) {
+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.PROJECTILE, projectile.getBukkitEntity()).callEvent()) {
+ return;
+ }
+ // Paper end
+
explode(world, blockposition, entity instanceof LivingEntity ? (LivingEntity) entity : null);
TntBlock.explode(world, blockposition, entity instanceof LivingEntity ? (LivingEntity) entity : null);
world.removeBlock(blockposition, false);
}

View File

@ -0,0 +1,196 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: BillyGalbreath <Blake.Galbreath@GMail.com>
Date: Thu, 2 Aug 2018 08:44:35 -0500
Subject: [PATCH] Add hand to bucket events
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
this.getServer().getPlayerList().broadcastAll(new ClientboundSetDefaultSpawnPositionPacket(pos, angle));
}
- public BlockPos getSharedSpawnPos() {
- BlockPos blockposition = new BlockPos(this.levelData.getXSpawn(), this.levelData.getYSpawn(), this.levelData.getZSpawn());
-
- if (!this.getWorldBorder().isWithinBounds(blockposition)) {
- blockposition = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, new BlockPos(this.getWorldBorder().getCenterX(), 0.0D, this.getWorldBorder().getCenterZ()));
- }
-
- return blockposition;
- }
+ // Paper - moved up to Level
+ //public BlockPosition getSpawn() {
+ // BlockPosition blockposition = new BlockPosition(this.worldData.a(), this.worldData.b(), this.worldData.c());
+ //
+ // if (!this.getWorldBorder().a(blockposition)) {
+ // blockposition = this.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, new BlockPosition(this.getWorldBorder().getCenterX(), 0.0D, this.getWorldBorder().getCenterZ()));
+ // }
+ //
+ // return blockposition;
+ //}
+ // Paper end
public float getSharedSpawnAngle() {
return this.levelData.getSpawnAngle();
diff --git a/src/main/java/net/minecraft/world/entity/animal/Cow.java b/src/main/java/net/minecraft/world/entity/animal/Cow.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Cow.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Cow.java
@@ -0,0 +0,0 @@ public class Cow extends Animal {
if (itemstack.is(Items.BUCKET) && !this.isBaby()) {
// CraftBukkit start - Got milk?
- org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level, player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET);
+ org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level, player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, hand); // Paper - add enumHand
if (event.isCancelled()) {
return InteractionResult.PASS;
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
@@ -0,0 +0,0 @@ public class Goat extends Animal {
if (itemstack.is(Items.BUCKET) && !this.isBaby()) {
// CraftBukkit start - Got milk?
- org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level, player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET);
+ org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level, player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, hand); // Paper - add enumHand
if (event.isCancelled()) {
return InteractionResult.PASS;
diff --git a/src/main/java/net/minecraft/world/item/BucketItem.java b/src/main/java/net/minecraft/world/item/BucketItem.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/item/BucketItem.java
+++ b/src/main/java/net/minecraft/world/item/BucketItem.java
@@ -0,0 +0,0 @@ public class BucketItem extends Item implements DispensibleContainerItem {
BucketPickup ifluidsource = (BucketPickup) iblockdata.getBlock();
// CraftBukkit start
ItemStack dummyFluid = ifluidsource.pickupBlock(DummyGeneratorAccess.INSTANCE, blockposition, iblockdata);
- PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) world, user, blockposition, blockposition, movingobjectpositionblock.getDirection(), itemstack, dummyFluid.getItem());
+ PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) world, user, blockposition, blockposition, movingobjectpositionblock.getDirection(), itemstack, dummyFluid.getItem(), hand); // Paper - add enumhand
if (event.isCancelled()) {
((ServerPlayer) user).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-5163 (see PlayerInteractManager)
@@ -0,0 +0,0 @@ public class BucketItem extends Item implements DispensibleContainerItem {
iblockdata = world.getBlockState(blockposition);
BlockPos blockposition2 = iblockdata.getBlock() instanceof LiquidBlockContainer && this.content == Fluids.WATER ? blockposition : blockposition1;
- if (this.a(user, world, blockposition2, movingobjectpositionblock, movingobjectpositionblock.getDirection(), blockposition, itemstack)) { // CraftBukkit
+ if (this.emptyContents(user, world, blockposition2, movingobjectpositionblock, movingobjectpositionblock.getDirection(), blockposition, itemstack, hand)) { // CraftBukkit // Paper - add enumhand
this.checkExtraContent(user, world, itemstack, blockposition2);
if (user instanceof ServerPlayer) {
CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayer) user, blockposition2, itemstack);
@@ -0,0 +0,0 @@ public class BucketItem extends Item implements DispensibleContainerItem {
@Override
public boolean emptyContents(@Nullable Player player, Level world, BlockPos pos, @Nullable BlockHitResult hitResult) {
- return this.a(player, world, pos, hitResult, null, null, null);
+ // Paper start - add enumHand
+ return emptyContents(player, world, pos, hitResult, null, null, null, null);
}
- public boolean a(Player entityhuman, Level world, BlockPos blockposition, @Nullable BlockHitResult movingobjectpositionblock, Direction enumdirection, BlockPos clicked, ItemStack itemstack) {
+ public boolean emptyContents(Player entityhuman, Level world, BlockPos blockposition, @Nullable BlockHitResult movingobjectpositionblock, Direction enumdirection, BlockPos clicked, ItemStack itemstack, InteractionHand enumhand) {
+ // Paper end
// CraftBukkit end
if (!(this.content instanceof FlowingFluid)) {
return false;
@@ -0,0 +0,0 @@ public class BucketItem extends Item implements DispensibleContainerItem {
// CraftBukkit start
if (flag1 && entityhuman != null) {
- PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent((ServerLevel) world, entityhuman, blockposition, clicked, enumdirection, itemstack);
+ PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent((ServerLevel) world, entityhuman, blockposition, clicked, enumdirection, itemstack, enumhand); // Paper - add enumhand
if (event.isCancelled()) {
((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-4238: needed when looking through entity
((ServerPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-4541
@@ -0,0 +0,0 @@ public class BucketItem extends Item implements DispensibleContainerItem {
}
// CraftBukkit end
if (!flag1) {
- return movingobjectpositionblock != null && this.a(entityhuman, world, movingobjectpositionblock.getBlockPos().relative(movingobjectpositionblock.getDirection()), (BlockHitResult) null, enumdirection, clicked, itemstack); // CraftBukkit
+ return movingobjectpositionblock != null && this.emptyContents(entityhuman, world, movingobjectpositionblock.getBlockPos().relative(movingobjectpositionblock.getDirection()), (BlockHitResult) null, enumdirection, clicked, itemstack, enumhand); // CraftBukkit // Paper - add enumhand
} else if (world.dimensionType().ultraWarm() && this.content.is((Tag) FluidTags.WATER)) {
int i = blockposition.getX();
int j = blockposition.getY();
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
return true;
}
// Paper end
+ // Paper start - moved up from ServerLevel
+ public BlockPos getSharedSpawnPos() {
+ BlockPos blockposition = new BlockPos(this.levelData.getXSpawn(), this.levelData.getYSpawn(), this.levelData.getZSpawn());
+
+ if (!this.getWorldBorder().isWithinBounds(blockposition)) {
+ blockposition = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, new BlockPos(this.getWorldBorder().getCenterX(), 0.0D, this.getWorldBorder().getCenterZ()));
+ }
+
+ return blockposition;
+ }
+ // Paper end
@Override
public boolean isClientSide() {
return this.isClientSide;
diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
@@ -0,0 +0,0 @@ public final class NaturalSpawner {
void run(Mob entity, ChunkAccess chunk);
}
}
+
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -0,0 +0,0 @@ public class CraftEventFactory {
public static Entity entityDamage; // For use in EntityDamageByEntityEvent
// helper methods
- private static boolean canBuild(ServerLevel world, Player player, int x, int z) {
+ private static boolean canBuild(Level world, Player player, int x, int z) {
int spawnSize = Bukkit.getServer().getSpawnRadius();
if (world.dimension() != Level.OVERWORLD) return true;
@@ -0,0 +0,0 @@ public class CraftEventFactory {
}
private static PlayerEvent getPlayerBucketEvent(boolean isFilling, ServerLevel world, net.minecraft.world.entity.player.Player who, BlockPos changed, BlockPos clicked, Direction clickedFace, ItemStack itemstack, net.minecraft.world.item.Item item) {
+ // Paper start - add enumHand
+ return getPlayerBucketEvent(isFilling, world, who, changed, clicked, clickedFace, itemstack, item, null);
+ }
+
+ public static PlayerBucketEmptyEvent callPlayerBucketEmptyEvent(Level world, net.minecraft.world.entity.player.Player who, BlockPos changed, BlockPos clicked, Direction clickedFace, ItemStack itemstack, InteractionHand enumHand) {
+ return (PlayerBucketEmptyEvent) getPlayerBucketEvent(false, world, who, changed, clicked, clickedFace, itemstack, Items.BUCKET, enumHand);
+ }
+
+ public static PlayerBucketFillEvent callPlayerBucketFillEvent(Level world, net.minecraft.world.entity.player.Player who, BlockPos changed, BlockPos clicked, Direction clickedFace, ItemStack itemInHand, net.minecraft.world.item.Item bucket, InteractionHand enumHand) {
+ return (PlayerBucketFillEvent) getPlayerBucketEvent(true, world, who, clicked, changed, clickedFace, itemInHand, bucket, enumHand);
+ }
+
+ private static PlayerEvent getPlayerBucketEvent(boolean isFilling, Level world, net.minecraft.world.entity.player.Player who, BlockPos changed, BlockPos clicked, Direction clickedFace, ItemStack itemstack, net.minecraft.world.item.Item item, InteractionHand enumHand) {
+ // Paper end
Player player = (Player) who.getBukkitEntity();
CraftItemStack itemInHand = CraftItemStack.asNewCraftStack(item);
Material bucket = CraftMagicNumbers.getMaterial(itemstack.getItem());
@@ -0,0 +0,0 @@ public class CraftEventFactory {
PlayerEvent event;
if (isFilling) {
- event = new PlayerBucketFillEvent(player, block, blockClicked, blockFace, bucket, itemInHand);
+ event = new PlayerBucketFillEvent(player, block, blockClicked, blockFace, bucket, itemInHand, enumHand == null ? null : enumHand == InteractionHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND); // Paper - add enumHand
((PlayerBucketFillEvent) event).setCancelled(!CraftEventFactory.canBuild(world, player, changed.getX(), changed.getZ()));
} else {
- event = new PlayerBucketEmptyEvent(player, block, blockClicked, blockFace, bucket, itemInHand);
+ event = new PlayerBucketEmptyEvent(player, block, blockClicked, blockFace, bucket, itemInHand, enumHand == null ? null : enumHand == InteractionHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND); // Paper - add enumHand
((PlayerBucketEmptyEvent) event).setCancelled(!CraftEventFactory.canBuild(world, player, changed.getX(), changed.getZ()));
}

View File

@ -37,8 +37,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public ArmorStand(EntityType<? extends ArmorStand> type, Level world) {
super(type, world);
+ if (world != null) this.canTick = world.paperConfig.armorStandTick; // Paper - armour stand ticking
this.handItems = NonNullList.a(2, ItemStack.EMPTY);
this.armorItems = NonNullList.a(4, ItemStack.EMPTY);
this.handItems = NonNullList.withSize(2, ItemStack.EMPTY);
this.armorItems = NonNullList.withSize(4, ItemStack.EMPTY);
this.headPose = ArmorStand.DEFAULT_HEAD_POSE;
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
this.armorItems.set(enumitemslot.getIndex(), itemstack);
@ -51,22 +51,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
}
tag.put("Pose", this.writePose());
+ if (this.canTickSetByAPI) tag.putBoolean("Paper.CanTickOverride", this.canTick); // Paper - persist no tick setting
nbt.put("Pose", this.writePose());
+ if (this.canTickSetByAPI) nbt.putBoolean("Paper.CanTickOverride", this.canTick); // Paper - persist no tick setting
}
@Override
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
this.setNoBasePlate(tag.getBoolean("NoBasePlate"));
this.setMarker(tag.getBoolean("Marker"));
this.setNoBasePlate(nbt.getBoolean("NoBasePlate"));
this.setMarker(nbt.getBoolean("Marker"));
this.noPhysics = !this.hasPhysics();
+ // Paper start - persist no tick
+ if (tag.contains("Paper.CanTickOverride")) {
+ this.canTick = tag.getBoolean("Paper.CanTickOverride");
+ if (nbt.contains("Paper.CanTickOverride")) {
+ this.canTick = nbt.getBoolean("Paper.CanTickOverride");
+ this.canTickSetByAPI = true;
+ }
+ // Paper end
CompoundTag nbttagcompound1 = tag.getCompound("Pose");
CompoundTag nbttagcompound1 = nbt.getCompound("Pose");
this.readPose(nbttagcompound1);
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
@ -100,49 +100,50 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (!this.headPose.equals(vector3f)) {
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
public void setHeadPose(Rotations vector3f) {
this.headPose = vector3f;
this.entityData.set(ArmorStand.DATA_HEAD_POSE, vector3f);
public void setHeadPose(Rotations angle) {
this.headPose = angle;
this.entityData.set(ArmorStand.DATA_HEAD_POSE, angle);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public void setBodyPose(Rotations vector3f) {
this.bodyPose = vector3f;
this.entityData.set(ArmorStand.DATA_BODY_POSE, vector3f);
public void setBodyPose(Rotations angle) {
this.bodyPose = angle;
this.entityData.set(ArmorStand.DATA_BODY_POSE, angle);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public void setLeftArmPose(Rotations vector3f) {
this.leftArmPose = vector3f;
this.entityData.set(ArmorStand.DATA_LEFT_ARM_POSE, vector3f);
public void setLeftArmPose(Rotations angle) {
this.leftArmPose = angle;
this.entityData.set(ArmorStand.DATA_LEFT_ARM_POSE, angle);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public void setRightArmPose(Rotations vector3f) {
this.rightArmPose = vector3f;
this.entityData.set(ArmorStand.DATA_RIGHT_ARM_POSE, vector3f);
public void setRightArmPose(Rotations angle) {
this.rightArmPose = angle;
this.entityData.set(ArmorStand.DATA_RIGHT_ARM_POSE, angle);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
}
public void setLeftLegPose(Rotations vector3f) {
public void setLeftLegPose(Rotations angle) {
this.leftLegPose = angle;
this.entityData.set(ArmorStand.DATA_LEFT_LEG_POSE, angle);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
this.leftLegPose = vector3f;
this.entityData.set(ArmorStand.DATA_LEFT_LEG_POSE, vector3f);
+
}
public void setRightLegPose(Rotations vector3f) {
public void setRightLegPose(Rotations angle) {
this.rightLegPose = angle;
this.entityData.set(ArmorStand.DATA_RIGHT_LEG_POSE, angle);
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
this.rightLegPose = vector3f;
this.entityData.set(ArmorStand.DATA_RIGHT_LEG_POSE, vector3f);
}
public Rotations getHeadPose() {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
@@ -0,0 +0,0 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
public boolean isSlotDisabled(org.bukkit.inventory.EquipmentSlot slot) {
return getHandle().isSlotDisabled(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot));
public void setCanMove(boolean move) {
getHandle().canMove = move;
}
+
+ @Override

View File

@ -9,10 +9,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
+++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
@@ -0,0 +0,0 @@ public class AnvilMenu extends ItemCombinerMenu {
if (!player.abilities.instabuild && iblockdata.is((Tag) BlockTags.ANVIL) && player.getRandom().nextFloat() < 0.12F) {
if (!player.getAbilities().instabuild && iblockdata.is((Tag) BlockTags.ANVIL) && player.getRandom().nextFloat() < 0.12F) {
BlockState iblockdata1 = AnvilBlock.damage(iblockdata);
-
+ // Paper start
+ com.destroystokyo.paper.event.block.AnvilDamagedEvent event = new com.destroystokyo.paper.event.block.AnvilDamagedEvent(getBukkitView(), iblockdata1 != null ? org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(iblockdata1) : null);
+ if (!event.callEvent()) {

View File

@ -48,28 +48,28 @@ diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListener
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
private long keepAliveChallenge;
// CraftBukkit start - multithreaded fields
private volatile int chatSpamTickCount;
private static final AtomicIntegerFieldUpdater chatSpamField = AtomicIntegerFieldUpdater.newUpdater(ServerGamePacketListenerImpl.class, "chatThrottle");
private AtomicInteger chatSpamTickCount = new AtomicInteger();
+ private final java.util.concurrent.atomic.AtomicInteger tabSpamLimiter = new java.util.concurrent.atomic.AtomicInteger(); // Paper - configurable tab spam limits
// CraftBukkit end
private int dropSpamTickCount;
private final Int2ShortMap expectedAcks = new Int2ShortOpenHashMap();
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
private double firstGoodX;
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
this.server.getProfiler().pop();
// CraftBukkit start
for (int spam; (spam = this.chatSpamTickCount) > 0 && !chatSpamField.compareAndSet(this, spam, spam - 1); ) ;
for (int spam; (spam = this.chatSpamTickCount.get()) > 0 && !this.chatSpamTickCount.compareAndSet(spam, spam - 1); ) ;
+ if (tabSpamLimiter.get() > 0) tabSpamLimiter.getAndDecrement(); // Paper - split to seperate variable
/* Use thread-safe field access instead
if (this.chatThrottle > 0) {
--this.chatThrottle;
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
if (this.chatSpamTickCount > 0) {
--this.chatSpamTickCount;
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) {
// PlayerConnectionUtils.ensureMainThread(packetplayintabcomplete, this, this.player.getWorldServer()); // Paper - run this async
// CraftBukkit start
- if (chatSpamField.addAndGet(this, 1) > 500 && !this.server.getPlayerList().isOp(this.player.getGameProfile())) {
+ if (tabSpamLimiter.addAndGet(com.destroystokyo.paper.PaperConfig.tabSpamIncrement) > com.destroystokyo.paper.PaperConfig.tabSpamLimit && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { // Paper start - split and make configurable
- if (this.chatSpamTickCount.addAndGet(1) > 500 && !this.server.getPlayerList().isOp(this.player.getGameProfile())) {
+ if (this.chatSpamTickCount.addAndGet(com.destroystokyo.paper.PaperConfig.tabSpamIncrement) > com.destroystokyo.paper.PaperConfig.tabSpamLimit && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { // Paper start - split and make configurable
server.scheduleOnMain(() -> this.disconnect(new TranslatableComponent("disconnect.spam", new Object[0]))); // Paper
return;
}

View File

@ -23,10 +23,10 @@ diff --git a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java b/sr
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
@@ -0,0 +0,0 @@ import net.minecraft.world.level.material.FlowingFluid;
@@ -0,0 +0,0 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty;
import net.minecraft.world.level.material.FlowingFluid;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
+import net.minecraft.world.level.material.Material;
import net.minecraft.world.level.pathfinder.PathComputationType;
import net.minecraft.world.level.storage.loot.LootContext;
@ -35,8 +35,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) {
if (this.shouldSpreadLiquid(world, pos, state)) {
- world.getLiquidTicks().a(pos, state.getFluidState().getType(), this.fluid.getTickDelay((LevelReader) world));
+ world.getLiquidTicks().a(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper
- world.getLiquidTicks().scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay((LevelReader) world));
+ world.getLiquidTicks().scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper
}
}
@ -56,17 +56,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return this.fluid.getTickDelay(world);
+ }
+ // Paper end
+
+
@Override
public BlockState updateShape(BlockState state, Direction direction, BlockState newState, LevelAccessor world, BlockPos pos, BlockPos posFrom) {
if (state.getFluidState().isSource() || newState.getFluidState().isSource()) {
public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
if (state.getFluidState().isSource() || neighborState.getFluidState().isSource()) {
@@ -0,0 +0,0 @@ public class LiquidBlock extends Block implements BucketPickup {
@Override
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean notify) {
if (this.shouldSpreadLiquid(world, pos, state)) {
- world.getLiquidTicks().a(pos, state.getFluidState().getType(), this.fluid.getTickDelay((LevelReader) world));
+ world.getLiquidTicks().a(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper
- world.getLiquidTicks().scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay((LevelReader) world));
+ world.getLiquidTicks().scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper
}
}

View File

@ -18,8 +18,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public boolean hasItemMeta() {
- return hasItemMeta(handle) && !CraftItemFactory.instance().equals(getItemMeta(), null);
+ return hasItemMeta(handle) && (handle.getDamageValue() != 0 || (handle.getTag() != null && handle.getTag().tags.size() >= (handle.getTag().contains(CraftMetaItem.DAMAGE.NBT) ? 2 : 1))); // Paper - keep 1.12 CraftBukkit behavior without calling getItemMeta
- return CraftItemStack.hasItemMeta(this.handle) && !CraftItemFactory.instance().equals(this.getItemMeta(), null);
+ return CraftItemStack.hasItemMeta(this.handle) && (this.handle.getDamageValue() != 0 || (this.handle.getTag() != null && this.handle.getTag().tags.size() >= (this.handle.getTag().contains(CraftMetaItem.DAMAGE.NBT) ? 2 : 1))); // Paper - keep 1.12 CraftBukkit behavior without calling getItemMeta
}
static boolean hasItemMeta(net.minecraft.world.item.ItemStack item) {

View File

@ -15,28 +15,20 @@ diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java
+++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
@@ -0,0 +0,0 @@ import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.level.block.entity.SkullBlockEntity;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import org.bukkit.craftbukkit.inventory.CraftItemStack; // CraftBukkit
@@ -0,0 +0,0 @@ public class FriendlyByteBuf extends ByteBuf {
if (item.canBeDepleted() || item.shouldOverrideMultiplayerNbt()) {
// Spigot start - filter
itemstack = itemstack.copy();
- CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack));
+ //CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); // Paper - This is no longer needed due to NBT being supported
stack = stack.copy();
- CraftItemStack.setItemMeta(stack, CraftItemStack.getItemMeta(stack));
+ // CraftItemStack.setItemMeta(stack, CraftItemStack.getItemMeta(stack)); // Paper - This is no longer needed due to NBT being supported
// Spigot end
nbttagcompound = itemstack.getTag();
nbttagcompound = stack.getTag();
+ // Paper start
+ if (nbttagcompound != null && nbttagcompound.contains("SkullOwner", 10)) {
+ CompoundTag owner = nbttagcompound.getCompound("SkullOwner");
+ if (owner.hasUUID("Id")) {
+ nbttagcompound.setUUID("SkullOwnerOrig", owner.getUUID("Id"));
+ SkullBlockEntity.sanitizeUUID(owner);
+ net.minecraft.world.level.block.entity.SkullBlockEntity.sanitizeUUID(owner);
+ }
+ }
+ // Paper end
@ -65,22 +57,14 @@ diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelC
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacket.java
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacket.java
@@ -0,0 +0,0 @@ import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.protocol.Packet;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.world.level.block.entity.SkullBlockEntity;
import net.minecraft.world.level.chunk.ChunkBiomeContainer;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.LevelChunkSection;
@@ -0,0 +0,0 @@ public class ClientboundLevelChunkPacket implements Packet<ClientGamePacketListe
for(Entry<BlockPos, BlockEntity> entry2 : chunk.getBlockEntities().entrySet()) {
BlockEntity blockEntity = entry2.getValue();
CompoundTag compoundTag = blockEntity.getUpdateTag();
+ if (blockEntity instanceof net.minecraft.world.level.block.entity.SkullBlockEntity) { net.minecraft.world.level.block.entity.SkullBlockEntity.sanitizeTileEntityUUID(compoundTag); } // Paper
this.blockEntitiesTags.add(compoundTag);
}
if (this.isFullChunk() || (includedSectionsMask & 1 << j) != 0) {
CompoundTag nbttagcompound = tileentity.getUpdateTag();
+ if (tileentity instanceof SkullBlockEntity) { SkullBlockEntity.sanitizeTileEntityUUID(nbttagcompound); } // Paper
this.blockEntitiesTags.add(nbttagcompound);
}
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
@ -98,15 +82,15 @@ diff --git a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEnti
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
@@ -0,0 +0,0 @@ import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
@@ -0,0 +0,0 @@ import java.util.function.Consumer;
import javax.annotation.Nullable;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
+import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.server.MinecraftServer;
@@ -0,0 +0,0 @@ public class SkullBlockEntity extends BlockEntity /*implements ITickable*/ { //
import net.minecraft.server.players.GameProfileCache;
@@ -0,0 +0,0 @@ public class SkullBlockEntity extends BlockEntity {
@Nullable
@Override
public ClientboundBlockEntityDataPacket getUpdatePacket() {

View File

@ -15,19 +15,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return enumitemslot;
}
+ public final boolean isSlotDisabled(net.minecraft.world.entity.EquipmentSlot slot) { return this.isDisabled(slot); } // Paper - OBFHELPER
private boolean isDisabled(net.minecraft.world.entity.EquipmentSlot slot) {
- private boolean isDisabled(net.minecraft.world.entity.EquipmentSlot slot) {
+ public boolean isDisabled(net.minecraft.world.entity.EquipmentSlot slot) { // Paper - private -> public
return (this.disabledSlots & 1 << slot.getFilterFlag()) != 0 || slot.getType() == net.minecraft.world.entity.EquipmentSlot.Type.HAND && !this.isShowArms();
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
@@ -0,0 +0,0 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
public void setCanMove(boolean move) {
getHandle().canMove = move;
}
+
+ @Override
+ public ItemStack getItem(org.bukkit.inventory.EquipmentSlot slot) {
+ com.google.common.base.Preconditions.checkNotNull(slot, "slot");
@ -98,7 +98,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ @Override
+ public boolean isSlotDisabled(org.bukkit.inventory.EquipmentSlot slot) {
+ return getHandle().isSlotDisabled(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot));
+ return getHandle().isDisabled(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot));
+ }
// Paper end
}
+
@Override
public boolean canTick() {
return this.getHandle().canTick;

View File

@ -21,8 +21,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (item == null) {
return -1;
}
- ItemStack[] inventory = getStorageContents();
+ //ItemStack[] inventory = getStorageContents(); // Paper - let param deal
- ItemStack[] inventory = this.getStorageContents();
+ // ItemStack[] inventory = this.getStorageContents(); // Paper - let param deal
for (int i = 0; i < inventory.length; i++) {
if (inventory[i] == null) continue;
@ -48,10 +48,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
int toDelete = item.getAmount();
while (true) {
- int first = first(item, false);
- int first = this.first(item, false);
+ // Paper start - Allow searching entire contents
+ ItemStack[] toSearch = searchEntire ? getContents() : getStorageContents();
+ int first = first(item, false, toSearch);
+ int first = this.first(item, false, toSearch);
+ // Paper end
// Drat! we don't have this type in the inventory

View File

@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Fri, 3 Aug 2018 00:04:54 -0400
Subject: [PATCH] MC-135506: Experience should save as Integers
diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
+++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
@@ -0,0 +0,0 @@ public class ExperienceOrb extends Entity {
public void addAdditionalSaveData(CompoundTag nbt) {
nbt.putShort("Health", (short) this.health);
nbt.putShort("Age", (short) this.age);
- nbt.putShort("Value", (short) this.value);
+ nbt.putInt("Value", this.value); // Paper - save as Integer
nbt.putInt("Count", this.count);
this.savePaperNBT(nbt); // Paper
}
@@ -0,0 +0,0 @@ public class ExperienceOrb extends Entity {
public void readAdditionalSaveData(CompoundTag nbt) {
this.health = nbt.getShort("Health");
this.age = nbt.getShort("Age");
- this.value = nbt.getShort("Value");
+ this.value = nbt.getInt("Value"); // Paper - load as Integer
this.count = Math.max(nbt.getInt("Count"), 1);
this.loadPaperNBT(nbt); // Paper
}

View File

@ -13,8 +13,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public boolean loadChunk(int x, int z, boolean generate) {
org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
- ChunkAccess chunk = world.getChunkSource().getChunk(x, z, generate ? ChunkStatus.FULL : ChunkStatus.EMPTY, true);
+ ChunkAccess chunk = world.getChunkSource().getChunk(x, z, generate || isChunkGenerated(x, z) ? ChunkStatus.FULL : ChunkStatus.EMPTY, true); // Paper
- ChunkAccess chunk = this.world.getChunkSource().getChunk(x, z, generate ? ChunkStatus.FULL : ChunkStatus.EMPTY, true);
+ 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.
if (chunk instanceof ImposterProtoChunk) {

View File

@ -30,53 +30,61 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
@Override
public BlockPos below(int distance) {
- return this.relative(Direction.DOWN, distance);
+ return distance == 0 ? this : new BlockPos(this.getX(), this.getY() - distance, this.getZ()); // Paper - Optimize BlockPosition
public BlockPos below(int i) {
- return this.relative(Direction.DOWN, i);
+ return i == 0 ? this : new BlockPos(this.getX(), this.getY() - i, this.getZ()); // Paper - Optimize BlockPosition
}
@Override
public BlockPos north() {
- return this.relative(Direction.NORTH);
+ return new BlockPos(this.getX(), this.getY(), this.getZ() - 1); // Paper - Optimize BlockPosition
}
@Override
public BlockPos north(int distance) {
- return this.relative(Direction.NORTH, distance);
+ return distance == 0 ? this : new BlockPos(this.getX(), this.getY(), this.getZ() - distance); // Paper - Optimize BlockPosition
}
@Override
public BlockPos south() {
- return this.relative(Direction.SOUTH);
+ return new BlockPos(this.getX(), this.getY(), this.getZ() + 1); // Paper - Optimize BlockPosition
}
@Override
public BlockPos south(int distance) {
- return this.relative(Direction.SOUTH, distance);
+ return distance == 0 ? this : new BlockPos(this.getX(), this.getY(), this.getZ() + distance); // Paper - Optimize BlockPosition
}
@Override
public BlockPos west() {
- return this.relative(Direction.WEST);
+ return new BlockPos(this.getX() - 1, this.getY(), this.getZ()); // Paper - Optimize BlockPosition
}
@Override
public BlockPos west(int distance) {
- return this.relative(Direction.WEST, distance);
+ return distance == 0 ? this : new BlockPos(this.getX() - distance, this.getY(), this.getZ()); // Paper - Optimize BlockPosition
}
@Override
public BlockPos east() {
- return this.relative(Direction.EAST);
+ return new BlockPos(this.getX() + 1, this.getY(), this.getZ()); // Paper - Optimize BlockPosition
}
@Override
public BlockPos east(int distance) {
- return this.relative(Direction.EAST, distance);
+ return distance == 0 ? this : new BlockPos(this.getX() + distance, this.getY(), this.getZ()); // Paper - Optimize BlockPosition
}
@Override
public BlockPos relative(Direction direction) {
- return new BlockPos(this.getX() + direction.getStepX(), this.getY() + direction.getStepY(), this.getZ() + direction.getStepZ());
+ // Paper Start - Optimize BlockPosition
+ switch(direction) {
+ case UP:
@ -92,7 +100,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ case EAST:
+ return new BlockPos(this.getX() + 1, this.getY(), this.getZ());
+ default:
+ return new BlockPos(this.getX() + direction.getStepX(), this.getY() + direction.getStepY(), this.getZ() + direction.getStepZ());
return new BlockPos(this.getX() + direction.getStepX(), this.getY() + direction.getStepY(), this.getZ() + direction.getStepZ());
+ }
+ // Paper End
}

View File

@ -44,6 +44,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ public static CraftBlockData createData(BlockState data) {
+ // Paper end
return MAP.getOrDefault(data.getBlock().getClass(), CraftBlockData::new).apply(data);
return CraftBlockData.MAP.getOrDefault(data.getBlock().getClass(), CraftBlockData::new).apply(data);
}

View File

@ -0,0 +1,35 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 26 Aug 2018 20:49:50 -0400
Subject: [PATCH] Optimize MappedRegistry
Use larger initial sizes to increase bucket capacity on the BiMap
BiMap.get was seen to be using a good bit of CPU time.
diff --git a/src/main/java/net/minecraft/core/MappedRegistry.java b/src/main/java/net/minecraft/core/MappedRegistry.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/core/MappedRegistry.java
+++ b/src/main/java/net/minecraft/core/MappedRegistry.java
@@ -0,0 +0,0 @@ import org.apache.logging.log4j.Logger;
public class MappedRegistry<T> extends WritableRegistry<T> {
protected static final Logger LOGGER = LogManager.getLogger();
private final ObjectList<T> byId = new ObjectArrayList<>(256);
- private final Object2IntMap<T> toId = new Object2IntOpenCustomHashMap<>(Util.identityStrategy());
+ private final it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap<T> toId = new it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap<T>(2048);// Paper - use bigger expected size to reduce collisions and direct intent for FastUtil to be identity map
private final BiMap<ResourceLocation, T> storage;
private final BiMap<ResourceKey<T>, T> keyStorage;
private final Map<T, Lifecycle> lifecycles;
@@ -0,0 +0,0 @@ public class MappedRegistry<T> extends WritableRegistry<T> {
public MappedRegistry(ResourceKey<? extends Registry<T>> key, Lifecycle lifecycle) {
super(key, lifecycle);
this.toId.defaultReturnValue(-1);
- this.storage = HashBiMap.create();
- this.keyStorage = HashBiMap.create();
- this.lifecycles = Maps.newIdentityHashMap();
+ this.storage = HashBiMap.create(2048); // Paper - use bigger expected size to reduce collisions
+ this.keyStorage = HashBiMap.create(2048); // Paper - use bigger expected size to reduce collisions
+ this.lifecycles = new java.util.IdentityHashMap<>(2048); // Paper - use bigger expected size to reduce collisions
this.elementsLifecycle = lifecycle;
}

View File

@ -13,9 +13,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public byte mobSpawnRange;
private void mobSpawnRange()
{
- mobSpawnRange = (byte) getInt( "mob-spawn-range", 6 );
+ mobSpawnRange = (byte) getInt( "mob-spawn-range", 8 ); // Paper - Vanilla
log( "Mob Spawn Range: " + mobSpawnRange );
- this.mobSpawnRange = (byte) this.getInt( "mob-spawn-range", 6 );
+ this.mobSpawnRange = (byte) getInt( "mob-spawn-range", 8 ); // Paper - Vanilla
this.log( "Mob Spawn Range: " + this.mobSpawnRange );
}
diff --git a/src/main/resources/configurations/bukkit.yml b/src/main/resources/configurations/bukkit.yml

View File

@ -4,60 +4,28 @@ Date: Fri, 27 Jul 2018 22:36:31 -0500
Subject: [PATCH] SkeletonHorse Additions
diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/EntitySelector.java
+++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java
@@ -0,0 +0,0 @@ public final class EntitySelector {
public static final Predicate<Entity> ATTACK_ALLOWED = (entity) -> {
return !(entity instanceof Player) || !entity.isSpectator() && !((Player) entity).isCreative() && entity.level.getDifficulty() != Difficulty.PEACEFUL;
};
+ public static Predicate<Entity> notSpectator() { return NO_SPECTATORS; } // Paper - OBFHELPER
public static final Predicate<Entity> NO_SPECTATORS = (entity) -> {
return !entity.isSpectator();
};
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonHorse.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonHorse.java
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonHorse.java
@@ -0,0 +0,0 @@ public class SkeletonHorse extends AbstractHorse {
private final SkeletonTrapGoal skeletonTrapGoal = new SkeletonTrapGoal(this);
private static final int TRAP_MAX_LIFE = 18000;
private boolean isTrap;
- private int trapTime;
+ private int trapTime; public int getTrapTime() { return this.trapTime; } // Paper - OBFHELPER
+ public int trapTime; // Paper private -> public
public SkeletonHorse(EntityType<? extends SkeletonHorse> type, Level world) {
super(type, world);
@@ -0,0 +0,0 @@ public class SkeletonHorse extends AbstractHorse {
return 0.96F;
}
+ public boolean isTrap() { return this.isTrap(); } // Paper - OBFHELPER
public boolean isTrap() {
return this.isTrap;
}
+ public void setTrap(boolean trap) { this.setTrap(trap); } // Paper - OBFHELPER
public void setTrap(boolean trapped) {
if (trapped != this.isTrap) {
this.isTrap = trapped;
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java
@@ -0,0 +0,0 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.level.Level;
+import org.bukkit.entity.HumanEntity;
+
+import java.util.List;
@@ -0,0 +0,0 @@ import net.minecraft.world.level.Level;
public class SkeletonTrapGoal extends Goal {
private final SkeletonHorse horse;
+ private List<HumanEntity> eligiblePlayers; // Paper
+ private java.util.List<org.bukkit.entity.HumanEntity> eligiblePlayers; // Paper
public SkeletonTrapGoal(SkeletonHorse skeletonHorse) {
this.horse = skeletonHorse;
@ -80,27 +48,17 @@ diff --git a/src/main/java/net/minecraft/world/level/EntityGetter.java b/src/mai
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/EntityGetter.java
+++ b/src/main/java/net/minecraft/world/level/EntityGetter.java
@@ -0,0 +0,0 @@
package net.minecraft.world.level;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
+import org.bukkit.entity.HumanEntity;
+
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
@@ -0,0 +0,0 @@ public interface EntityGetter {
return entityhuman;
return player;
}
+ // Paper start
+ default List<HumanEntity> findNearbyBukkitPlayers(double x, double y, double z, double radius, boolean notSpectator) {
+ return findNearbyBukkitPlayers(x, y, z, radius, notSpectator ? EntitySelector.notSpectator() : EntitySelector.canAITarget());
+ default List<org.bukkit.entity.HumanEntity> findNearbyBukkitPlayers(double x, double y, double z, double radius, boolean notSpectator) {
+ return findNearbyBukkitPlayers(x, y, z, radius, notSpectator ? EntitySelector.NO_SPECTATORS : net.minecraft.world.entity.EntitySelector.NO_CREATIVE_OR_SPECTATOR);
+ }
+
+ default List<HumanEntity> findNearbyBukkitPlayers(double x, double y, double z, double radius, @Nullable Predicate<Entity> predicate) {
+ ImmutableList.Builder<HumanEntity> builder = ImmutableList.builder();
+ default List<org.bukkit.entity.HumanEntity> findNearbyBukkitPlayers(double x, double y, double z, double radius, @Nullable Predicate<Entity> predicate) {
+ com.google.common.collect.ImmutableList.Builder<org.bukkit.entity.HumanEntity> builder = com.google.common.collect.ImmutableList.builder();
+
+ for (Player human : this.players()) {
+ if (predicate == null || predicate.test(human)) {
@ -136,7 +94,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ @Override
+ public int getTrapTime() {
+ return getHandle().getTrapTime();
+ return getHandle().trapTime;
+ }
+
+ @Override

View File

@ -8,106 +8,39 @@ diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/m
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Slime.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java
@@ -0,0 +0,0 @@ import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.entity.EntityType;
-import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.entity.Pose;
@@ -0,0 +0,0 @@ import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.biome.Biomes;
@@ -0,0 +0,0 @@ import net.minecraft.world.level.biome.Biomes;
import net.minecraft.world.level.levelgen.WorldgenRandom;
import net.minecraft.world.level.storage.loot.BuiltInLootTables;
import net.minecraft.world.phys.Vec3;
+// Paper start
+import com.destroystokyo.paper.event.entity.SlimeChangeDirectionEvent;
+import com.destroystokyo.paper.event.entity.SlimeSwimEvent;
+import com.destroystokyo.paper.event.entity.SlimeTargetLivingEntityEvent;
+import com.destroystokyo.paper.event.entity.SlimeWanderEvent;
+import org.bukkit.entity.LivingEntity;
+// Paper end
// CraftBukkit start
import java.util.ArrayList;
import java.util.List;
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
@Override
public void addAdditionalSaveData(CompoundTag tag) {
super.addAdditionalSaveData(tag);
+ tag.putBoolean("Paper.canWander", this.canWander); // Paper
tag.putInt("Size", this.getSize() - 1);
tag.putBoolean("wasOnGround", this.wasOnGround);
public void addAdditionalSaveData(CompoundTag nbt) {
super.addAdditionalSaveData(nbt);
+ nbt.putBoolean("Paper.canWander", this.canWander); // Paper
nbt.putInt("Size", this.getSize() - 1);
nbt.putBoolean("wasOnGround", this.wasOnGround);
}
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
this.setSize(i + 1, false);
super.readAdditionalSaveData(tag);
public void readAdditionalSaveData(CompoundTag nbt) {
this.setSize(nbt.getInt("Size") + 1, false);
super.readAdditionalSaveData(nbt);
+ // Paper start - check exists before loading or this will be loaded as false
+ if (tag.contains("Paper.canWander")) {
+ this.canWander = tag.getBoolean("Paper.canWander");
+ if (nbt.contains("Paper.canWander")) {
+ this.canWander = nbt.getBoolean("Paper.canWander");
+ }
+ // Paper end
this.wasOnGround = tag.getBoolean("wasOnGround");
this.wasOnGround = nbt.getBoolean("wasOnGround");
}
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
super.remove();
return;
}
- List<LivingEntity> slimes = new ArrayList<>(j);
+ List<net.minecraft.world.entity.LivingEntity> slimes = new ArrayList<>(j);
// CraftBukkit end
for (int l = 0; l < k; ++l) {
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
if (CraftEventFactory.callEntityTransformEvent(this, slimes, EntityTransformEvent.TransformReason.SPLIT).isCancelled()) {
return;
}
- for (LivingEntity living : slimes) {
+ for (net.minecraft.world.entity.LivingEntity living : slimes) {
this.level.addEntity(living, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SLIME_SPLIT); // CraftBukkit - SpawnReason
}
// CraftBukkit end
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
public void push(Entity entity) {
super.push(entity);
if (entity instanceof IronGolem && this.isDealsDamage()) {
- this.dealDamage((LivingEntity) entity);
+ this.dealDamage((net.minecraft.world.entity.LivingEntity) entity);
}
}
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
@Override
public void playerTouch(Player player) {
if (this.isDealsDamage()) {
- this.dealDamage((LivingEntity) player);
+ this.dealDamage((net.minecraft.world.entity.LivingEntity) player);
}
}
- protected void dealDamage(LivingEntity target) {
+ protected void dealDamage(net.minecraft.world.entity.LivingEntity target) {
if (this.isAlive()) {
int i = this.getSize();
if (this.distanceToSqr((Entity) target) < 0.6D * (double) i * 0.6D * (double) i && this.canSee(target) && target.hurt(DamageSource.mobAttack(this), this.getAttackDamage())) {
this.playSound(SoundEvents.SLIME_ATTACK, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F);
- this.doEnchantDamageEffects((LivingEntity) this, (Entity) target);
+ this.doEnchantDamageEffects((net.minecraft.world.entity.LivingEntity) this, (Entity) target);
}
}
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
@Override
public boolean canUse() {
- return !this.slime.isPassenger();
+ return !this.slime.isPassenger() && this.slime.canWander && new SlimeWanderEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity()).callEvent(); // Paper
}
@Override
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
@Override
@ -118,6 +51,54 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
public boolean canUse() {
LivingEntity entityliving = this.slime.getTarget();
- return entityliving == null ? false : (!this.slime.canAttack(entityliving) ? false : this.slime.getMoveControl() instanceof Slime.SlimeMoveControl);
+ // Paper start
+ if (entityliving == null || !entityliving.isAlive()) {
+ return false;
+ }
+ if (!this.slime.canAttack(entityliving)) {
+ return false;
+ }
+ return this.slime.getMoveControl() instanceof Slime.SlimeMoveControl && this.slime.canWander && new SlimeTargetLivingEntityEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), (org.bukkit.entity.LivingEntity) entityliving.getBukkitEntity()).callEvent();
+ // Paper end
}
@Override
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
public boolean canContinueToUse() {
LivingEntity entityliving = this.slime.getTarget();
- return entityliving == null ? false : (!this.slime.canAttack(entityliving) ? false : --this.growTiredTimer > 0);
+ // Paper start
+ if (entityliving == null || !entityliving.isAlive()) {
+ return false;
+ }
+ if (!this.slime.canAttack(entityliving)) {
+ return false;
+ }
+ return --this.growTiredTimer > 0 && this.slime.canWander && new SlimeTargetLivingEntityEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), (org.bukkit.entity.LivingEntity) entityliving.getBukkitEntity()).callEvent();
+ // Paper end
}
@Override
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
this.slime.lookAt((Entity) this.slime.getTarget(), 10.0F, 10.0F);
((Slime.SlimeMoveControl) this.slime.getMoveControl()).setDirection(this.slime.getYRot(), this.slime.isDealsDamage());
}
+
+ // Paper start - clear timer and target when goal resets
+ public void stop() {
+ this.growTiredTimer = 0;
+ this.slime.setTarget(null);
+ }
+ // Paper end
}
private static class SlimeRandomDirectionGoal extends Goal {
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
@Override
public boolean canUse() {
@ -142,58 +123,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public boolean canUse() {
- LivingEntity entityliving = this.slime.getTarget();
+ net.minecraft.world.entity.LivingEntity entityliving = this.slime.getTarget();
- return entityliving == null ? false : (!entityliving.isAlive() ? false : (entityliving instanceof Player && ((Player) entityliving).abilities.invulnerable ? false : this.slime.getMoveControl() instanceof Slime.SlimeMoveControl));
+ // Paper start
+ if (entityliving == null || !entityliving.isAlive()) {
+ return false;
+ }
+ if (entityliving instanceof Player && ((Player) entityliving).abilities.invulnerable) {
+ return false;
+ }
+ return this.slime.getMoveControl() instanceof Slime.SlimeMoveControl && this.slime.canWander && new SlimeTargetLivingEntityEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), (LivingEntity) entityliving.getBukkitEntity()).callEvent();
+ // Paper end
- return !this.slime.isPassenger();
+ return !this.slime.isPassenger() && this.slime.canWander && new SlimeWanderEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity()).callEvent(); // Paper
}
@Override
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
@Override
public boolean canContinueToUse() {
- LivingEntity entityliving = this.slime.getTarget();
+ net.minecraft.world.entity.LivingEntity entityliving = this.slime.getTarget();
- return entityliving == null ? false : (!entityliving.isAlive() ? false : (entityliving instanceof Player && ((Player) entityliving).abilities.invulnerable ? false : --this.growTiredTimer > 0));
+ // Paper start
+ if (entityliving == null || !entityliving.isAlive()) {
+ return false;
+ }
+ if (entityliving instanceof Player && ((Player) entityliving).abilities.invulnerable) {
+ return false;
+ }
+ return --this.growTiredTimer > 0 && this.slime.canWander && new SlimeTargetLivingEntityEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), (LivingEntity) entityliving.getBukkitEntity()).callEvent();
+ // Paper end
}
@Override
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
this.slime.lookAt((Entity) this.slime.getTarget(), 10.0F, 10.0F);
((Slime.SlimeMoveControl) this.slime.getMoveControl()).setDirection(this.slime.yRot, this.slime.isDealsDamage());
}
+
+ // Paper start - clear timer and target when goal resets
+ public void stop() {
+ this.growTiredTimer = 0;
+ this.slime.setTarget(null);
+ }
+ // Paper end
}
static class SlimeMoveControl extends MoveControl {
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
}
((Slime.SlimeMoveControl) this.slime.getMoveControl()).setWantedMovement(1.0D);
}
}
+
@ -218,10 +154,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
+
+ // Paper start
+ @Override
+ public boolean canWander() {
+ return getHandle().canWander();
+ }
+
+ @Override
+ public void setWander(boolean canWander) {
+ getHandle().setWander(canWander);
+ }

View File

@ -32,8 +32,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} else if (!this.isWhitelisted(gameprofile, event)) { // Paper
//chatmessage = new ChatMessage("multiplayer.disconnect.not_whitelisted"); // Paper
//event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig.whitelistMessage); // Spigot // Paper - moved to isWhitelisted
- } else if (getIpBans().isBanned(socketaddress) && !getIpBans().get(socketaddress).hasExpired()) {
+ } else if (getIpBans().isBanned(socketaddress) && getIpBans().get(socketaddress) != null && !getIpBans().get(socketaddress).hasExpired()) { // Paper - fix NPE with temp ip bans
- } else if (this.getIpBans().isBanned(socketaddress) && !this.getIpBans().get(socketaddress).hasExpired()) {
+ } else if (this.getIpBans().isBanned(socketaddress) && getIpBans().get(socketaddress) != null && !this.getIpBans().get(socketaddress).hasExpired()) { // Paper - fix NPE with temp ip bans
IpBanListEntry ipbanentry = this.ipBans.get(socketaddress);
chatmessage = new TranslatableComponent("multiplayer.disconnect.banned_ip.reason", new Object[]{ipbanentry.getReason()});
@ -143,5 +143,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public void save() throws IOException {
+ this.removeStaleEntries(); // Paper - remove expired values before saving
JsonArray jsonarray = new JsonArray();
this.map.values().stream().map((jsonlistentry) -> {
Stream<JsonObject> stream = this.map.values().stream().map((jsonlistentry) -> { // CraftBukkit - decompile error
JsonObject jsonobject = new JsonObject();

View File

@ -10,8 +10,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
private static final Logger LOGGER = LogManager.getLogger();
private static final int CONVERSION_RETRY_DELAY_MS = 5000;
private static final int CONVERSION_RETRIES = 2;
private static final Pattern SHA1 = Pattern.compile("^[a-fA-F0-9]{40}$");
- private final List<ConsoleInput> consoleInput = Collections.synchronizedList(Lists.newArrayList());
+ private final java.util.Queue<ConsoleInput> serverCommandQueue = new java.util.concurrent.ConcurrentLinkedQueue<>(); // Paper - use a proper queue