diff --git a/patches/api-unmapped/Ability-to-get-Tile-Entities-from-a-chunk-without-sn.patch b/patches/api/Ability-to-get-Tile-Entities-from-a-chunk-without-sn.patch similarity index 100% rename from patches/api-unmapped/Ability-to-get-Tile-Entities-from-a-chunk-without-sn.patch rename to patches/api/Ability-to-get-Tile-Entities-from-a-chunk-without-sn.patch diff --git a/patches/api-unmapped/Add-More-Creeper-API.patch b/patches/api/Add-More-Creeper-API.patch similarity index 100% rename from patches/api-unmapped/Add-More-Creeper-API.patch rename to patches/api/Add-More-Creeper-API.patch diff --git a/patches/api-unmapped/Add-PhantomPreSpawnEvent.patch b/patches/api/Add-PhantomPreSpawnEvent.patch similarity index 100% rename from patches/api-unmapped/Add-PhantomPreSpawnEvent.patch rename to patches/api/Add-PhantomPreSpawnEvent.patch diff --git a/patches/api-unmapped/Add-TNTPrimeEvent.patch b/patches/api/Add-TNTPrimeEvent.patch similarity index 100% rename from patches/api-unmapped/Add-TNTPrimeEvent.patch rename to patches/api/Add-TNTPrimeEvent.patch diff --git a/patches/api-unmapped/Add-hand-to-bucket-events.patch b/patches/api/Add-hand-to-bucket-events.patch similarity index 100% rename from patches/api-unmapped/Add-hand-to-bucket-events.patch rename to patches/api/Add-hand-to-bucket-events.patch diff --git a/patches/api-unmapped/Add-source-block-to-BlockPhysicsEvent.patch b/patches/api/Add-source-block-to-BlockPhysicsEvent.patch similarity index 100% rename from patches/api-unmapped/Add-source-block-to-BlockPhysicsEvent.patch rename to patches/api/Add-source-block-to-BlockPhysicsEvent.patch diff --git a/patches/api-unmapped/Allow-Blocks-to-be-accessed-via-a-long-key.patch b/patches/api/Allow-Blocks-to-be-accessed-via-a-long-key.patch similarity index 100% rename from patches/api-unmapped/Allow-Blocks-to-be-accessed-via-a-long-key.patch rename to patches/api/Allow-Blocks-to-be-accessed-via-a-long-key.patch diff --git a/patches/api-unmapped/Allow-disabling-armour-stand-ticking.patch b/patches/api/Allow-disabling-armour-stand-ticking.patch similarity index 100% rename from patches/api-unmapped/Allow-disabling-armour-stand-ticking.patch rename to patches/api/Allow-disabling-armour-stand-ticking.patch diff --git a/patches/api-unmapped/AnvilDamageEvent.patch b/patches/api/AnvilDamageEvent.patch similarity index 100% rename from patches/api-unmapped/AnvilDamageEvent.patch rename to patches/api/AnvilDamageEvent.patch diff --git a/patches/api-unmapped/Don-t-use-snapshots-for-Timings-Tile-Entity-reports.patch b/patches/api/Don-t-use-snapshots-for-Timings-Tile-Entity-reports.patch similarity index 100% rename from patches/api-unmapped/Don-t-use-snapshots-for-Timings-Tile-Entity-reports.patch rename to patches/api/Don-t-use-snapshots-for-Timings-Tile-Entity-reports.patch diff --git a/patches/api-unmapped/EntityTransformedEvent.patch b/patches/api/EntityTransformedEvent.patch similarity index 100% rename from patches/api-unmapped/EntityTransformedEvent.patch rename to patches/api/EntityTransformedEvent.patch diff --git a/patches/api-unmapped/Expand-ArmorStand-API.patch b/patches/api/Expand-ArmorStand-API.patch similarity index 100% rename from patches/api-unmapped/Expand-ArmorStand-API.patch rename to patches/api/Expand-ArmorStand-API.patch diff --git a/patches/api-unmapped/Expand-Location-Manipulation-API.patch b/patches/api/Expand-Location-Manipulation-API.patch similarity index 100% rename from patches/api-unmapped/Expand-Location-Manipulation-API.patch rename to patches/api/Expand-Location-Manipulation-API.patch diff --git a/patches/api-unmapped/Inventory-removeItemAnySlot.patch b/patches/api/Inventory-removeItemAnySlot.patch similarity index 100% rename from patches/api-unmapped/Inventory-removeItemAnySlot.patch rename to patches/api/Inventory-removeItemAnySlot.patch diff --git a/patches/api-unmapped/Make-EnderDragon-extend-Mob.patch b/patches/api/Make-EnderDragon-extend-Mob.patch similarity index 100% rename from patches/api-unmapped/Make-EnderDragon-extend-Mob.patch rename to patches/api/Make-EnderDragon-extend-Mob.patch diff --git a/patches/api-unmapped/Provide-Chunk-Coordinates-as-a-Long-API.patch b/patches/api/Provide-Chunk-Coordinates-as-a-Long-API.patch similarity index 100% rename from patches/api-unmapped/Provide-Chunk-Coordinates-as-a-Long-API.patch rename to patches/api/Provide-Chunk-Coordinates-as-a-Long-API.patch diff --git a/patches/api-unmapped/Remove-deadlock-risk-in-firing-async-events.patch b/patches/api/Remove-deadlock-risk-in-firing-async-events.patch similarity index 88% rename from patches/api-unmapped/Remove-deadlock-risk-in-firing-async-events.patch rename to patches/api/Remove-deadlock-risk-in-firing-async-events.patch index fdbc0b68a..2728bd55c 100644 --- a/patches/api-unmapped/Remove-deadlock-risk-in-firing-async-events.patch +++ b/patches/api/Remove-deadlock-risk-in-firing-async-events.patch @@ -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 { // 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 diff --git a/patches/api-unmapped/SkeletonHorse-Additions.patch b/patches/api/SkeletonHorse-Additions.patch similarity index 100% rename from patches/api-unmapped/SkeletonHorse-Additions.patch rename to patches/api/SkeletonHorse-Additions.patch diff --git a/patches/api-unmapped/Slime-Pathfinder-Events.patch b/patches/api/Slime-Pathfinder-Events.patch similarity index 100% rename from patches/api-unmapped/Slime-Pathfinder-Events.patch rename to patches/api/Slime-Pathfinder-Events.patch diff --git a/patches/api-unmapped/isChunkGenerated-API.patch b/patches/api/isChunkGenerated-API.patch similarity index 95% rename from patches/api-unmapped/isChunkGenerated-API.patch rename to patches/api/isChunkGenerated-API.patch index fcf1dded4..c2284fe9c 100644 --- a/patches/api-unmapped/isChunkGenerated-API.patch +++ b/patches/api/isChunkGenerated-API.patch @@ -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 diff --git a/patches/server-remapped/Add-hand-to-bucket-events.patch b/patches/server-remapped/Add-hand-to-bucket-events.patch deleted file mode 100644 index 5fd21606b..000000000 --- a/patches/server-remapped/Add-hand-to-bucket-events.patch +++ /dev/null @@ -1,341 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: BillyGalbreath -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 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())); - } - diff --git a/patches/server-remapped/Add-some-Debug-to-Chunk-Entity-slices.patch b/patches/server-remapped/Add-some-Debug-to-Chunk-Entity-slices.patch deleted file mode 100644 index 3ce100c2c..000000000 --- a/patches/server-remapped/Add-some-Debug-to-Chunk-Entity-slices.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -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 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 nextSlice = this.entitySlices[k]; // the next list to be added to -+ List 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); diff --git a/patches/server-remapped/Ignore-Dead-Entities-in-entityList-iteration.patch b/patches/server-remapped/Ignore-Dead-Entities-in-entityList-iteration.patch deleted file mode 100644 index cc017f7f2..000000000 --- a/patches/server-remapped/Ignore-Dead-Entities-in-entityList-iteration.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -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 entities = world.entitiesById.values(); - entities.forEach(e -> { - ResourceLocation key = e.getMinecraftKey(); -+ if (e.shouldBeRemoved) return; // Paper - - MutablePair> 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) { diff --git a/patches/server-remapped/MC-135506-Experience-should-save-as-Integers.patch b/patches/server-remapped/MC-135506-Experience-should-save-as-Integers.patch deleted file mode 100644 index c3f24cbcd..000000000 --- a/patches/server-remapped/MC-135506-Experience-should-save-as-Integers.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -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 - } - diff --git a/patches/server-remapped/Mark-chunk-dirty-anytime-entities-change-to-guarante.patch b/patches/server-remapped/Mark-chunk-dirty-anytime-entities-change-to-guarante.patch deleted file mode 100644 index d7c02ac9d..000000000 --- a/patches/server-remapped/Mark-chunk-dirty-anytime-entities-change-to-guarante.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -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 - } diff --git a/patches/server-remapped/Optimize-RegistryMaterials.patch b/patches/server-remapped/Optimize-RegistryMaterials.patch deleted file mode 100644 index 9ec51a481..000000000 --- a/patches/server-remapped/Optimize-RegistryMaterials.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -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 extends WritableRegistry { - - protected static final Logger LOGGER = LogManager.getLogger(); - private final ObjectList byId = new ObjectArrayList(256); -- private final Object2IntMap toId = new Object2IntOpenCustomHashMap(Util.identityStrategy()); -+ private final Reference2IntOpenHashMap bg = new Reference2IntOpenHashMap(2048);// Paper - use bigger expected size to reduce collisions and direct intent for FastUtil to be identity map - private final BiMap storage; - private final BiMap, T> keyStorage; - private final Map lifecycles; -@@ -0,0 +0,0 @@ public class MappedRegistry extends WritableRegistry { - - public MappedRegistry(ResourceKey> 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 extends WritableRegistry { - 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 extends WritableRegistry { - 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 extends WritableRegistry { - - @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 extends WritableRegistry { - 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 Codec> networkCodec(ResourceKey> resourcekey, Lifecycle lifecycle, Codec entryCodec) { -@@ -0,0 +0,0 @@ public class MappedRegistry extends WritableRegistry { - 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)); - } diff --git a/patches/server-remapped/Prevent-Saving-Bad-entities-to-chunks.patch b/patches/server-remapped/Prevent-Saving-Bad-entities-to-chunks.patch deleted file mode 100644 index 38331a00a..000000000 --- a/patches/server-remapped/Prevent-Saving-Bad-entities-to-chunks.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -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 toMoveChunks = new java.util.ArrayList<>(); // Paper - for (int j = 0; j < i; ++j) { - List 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 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) { diff --git a/patches/server-remapped/Ability-to-get-Tile-Entities-from-a-chunk-without-sn.patch b/patches/server/Ability-to-get-Tile-Entities-from-a-chunk-without-sn.patch similarity index 79% rename from patches/server-remapped/Ability-to-get-Tile-Entities-from-a-chunk-without-sn.patch rename to patches/server/Ability-to-get-Tile-Entities-from-a-chunk-without-sn.patch index d6116decf..722548d1f 100644 --- a/patches/server-remapped/Ability-to-get-Tile-Entities-from-a-chunk-without-sn.patch +++ b/patches/server/Ability-to-get-Tile-Entities-from-a-chunk-without-sn.patch @@ -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 getTileEntities(Predicate 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() { diff --git a/patches/server-remapped/Add-Early-Warning-Feature-to-WatchDog.patch b/patches/server/Add-Early-Warning-Feature-to-WatchDog.patch similarity index 84% rename from patches/server-remapped/Add-Early-Warning-Feature-to-WatchDog.patch rename to patches/server/Add-Early-Warning-Feature-to-WatchDog.patch index ada8bdfcc..384813dfb 100644 --- a/patches/server-remapped/Add-Early-Warning-Feature-to-WatchDog.patch +++ b/patches/server/Add-Early-Warning-Feature-to-WatchDog.patch @@ -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(); } diff --git a/patches/server-remapped/Add-More-Creeper-API.patch b/patches/server/Add-More-Creeper-API.patch similarity index 94% rename from patches/server-remapped/Add-More-Creeper-API.patch rename to patches/server/Add-More-Creeper-API.patch index d5fdf1140..201a06863 100644 --- a/patches/server-remapped/Add-More-Creeper-API.patch +++ b/patches/server/Add-More-Creeper-API.patch @@ -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(); + } diff --git a/patches/server-remapped/Add-PhantomPreSpawnEvent.patch b/patches/server/Add-PhantomPreSpawnEvent.patch similarity index 90% rename from patches/server-remapped/Add-PhantomPreSpawnEvent.patch rename to patches/server/Add-PhantomPreSpawnEvent.patch index 051e4f5ab..edd0466eb 100644 --- a/patches/server-remapped/Add-PhantomPreSpawnEvent.patch +++ b/patches/server/Add-PhantomPreSpawnEvent.patch @@ -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(); + } diff --git a/patches/server-remapped/Add-TNTPrimeEvent.patch b/patches/server/Add-TNTPrimeEvent.patch similarity index 65% rename from patches/server-remapped/Add-TNTPrimeEvent.patch rename to patches/server/Add-TNTPrimeEvent.patch index 910ce0693..572c31d92 100644 --- a/patches/server-remapped/Add-TNTPrimeEvent.patch +++ b/patches/server/Add-TNTPrimeEvent.patch @@ -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); } diff --git a/patches/server/Add-hand-to-bucket-events.patch b/patches/server/Add-hand-to-bucket-events.patch new file mode 100644 index 000000000..3e29e8b86 --- /dev/null +++ b/patches/server/Add-hand-to-bucket-events.patch @@ -0,0 +1,196 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: BillyGalbreath +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())); + } + diff --git a/patches/server-remapped/Allow-disabling-armour-stand-ticking.patch b/patches/server/Allow-disabling-armour-stand-ticking.patch similarity index 75% rename from patches/server-remapped/Allow-disabling-armour-stand-ticking.patch rename to patches/server/Allow-disabling-armour-stand-ticking.patch index 75eac66a8..dde5613bf 100644 --- a/patches/server-remapped/Allow-disabling-armour-stand-ticking.patch +++ b/patches/server/Allow-disabling-armour-stand-ticking.patch @@ -37,8 +37,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public ArmorStand(EntityType 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 diff --git a/patches/server-remapped/AnvilDamageEvent.patch b/patches/server/AnvilDamageEvent.patch similarity index 92% rename from patches/server-remapped/AnvilDamageEvent.patch rename to patches/server/AnvilDamageEvent.patch index 21f09365e..403d8b8b9 100644 --- a/patches/server-remapped/AnvilDamageEvent.patch +++ b/patches/server/AnvilDamageEvent.patch @@ -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()) { diff --git a/patches/server-remapped/Break-up-and-make-tab-spam-limits-configurable.patch b/patches/server/Break-up-and-make-tab-spam-limits-configurable.patch similarity index 80% rename from patches/server-remapped/Break-up-and-make-tab-spam-limits-configurable.patch rename to patches/server/Break-up-and-make-tab-spam-limits-configurable.patch index 79475adbb..7be0c7ef6 100644 --- a/patches/server-remapped/Break-up-and-make-tab-spam-limits-configurable.patch +++ b/patches/server/Break-up-and-make-tab-spam-limits-configurable.patch @@ -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; } diff --git a/patches/server-remapped/Configurable-speed-for-water-flowing-over-lava.patch b/patches/server/Configurable-speed-for-water-flowing-over-lava.patch similarity index 78% rename from patches/server-remapped/Configurable-speed-for-water-flowing-over-lava.patch rename to patches/server/Configurable-speed-for-water-flowing-over-lava.patch index 03357ba23..27d6888dd 100644 --- a/patches/server-remapped/Configurable-speed-for-water-flowing-over-lava.patch +++ b/patches/server/Configurable-speed-for-water-flowing-over-lava.patch @@ -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 } } diff --git a/patches/server-remapped/Don-t-call-getItemMeta-on-hasItemMeta.patch b/patches/server/Don-t-call-getItemMeta-on-hasItemMeta.patch similarity index 88% rename from patches/server-remapped/Don-t-call-getItemMeta-on-hasItemMeta.patch rename to patches/server/Don-t-call-getItemMeta-on-hasItemMeta.patch index c9cbb6c67..9b5e95309 100644 --- a/patches/server-remapped/Don-t-call-getItemMeta-on-hasItemMeta.patch +++ b/patches/server/Don-t-call-getItemMeta-on-hasItemMeta.patch @@ -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) { diff --git a/patches/server-remapped/Fix-client-rendering-skulls-from-same-user.patch b/patches/server/Fix-client-rendering-skulls-from-same-user.patch similarity index 75% rename from patches/server-remapped/Fix-client-rendering-skulls-from-same-user.patch rename to patches/server/Fix-client-rendering-skulls-from-same-user.patch index f1bb4a527..30e25f3a3 100644 --- a/patches/server-remapped/Fix-client-rendering-skulls-from-same-user.patch +++ b/patches/server/Fix-client-rendering-skulls-from-same-user.patch @@ -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 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() { diff --git a/patches/server-remapped/Implement-Expanded-ArmorStand-API.patch b/patches/server/Implement-Expanded-ArmorStand-API.patch similarity index 92% rename from patches/server-remapped/Implement-Expanded-ArmorStand-API.patch rename to patches/server/Implement-Expanded-ArmorStand-API.patch index 309527123..312fdf9fe 100644 --- a/patches/server-remapped/Implement-Expanded-ArmorStand-API.patch +++ b/patches/server/Implement-Expanded-ArmorStand-API.patch @@ -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; diff --git a/patches/server-remapped/Inventory-removeItemAnySlot.patch b/patches/server/Inventory-removeItemAnySlot.patch similarity index 89% rename from patches/server-remapped/Inventory-removeItemAnySlot.patch rename to patches/server/Inventory-removeItemAnySlot.patch index c9b419fec..1550c9a9f 100644 --- a/patches/server-remapped/Inventory-removeItemAnySlot.patch +++ b/patches/server/Inventory-removeItemAnySlot.patch @@ -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 diff --git a/patches/server/MC-135506-Experience-should-save-as-Integers.patch b/patches/server/MC-135506-Experience-should-save-as-Integers.patch new file mode 100644 index 000000000..45d369091 --- /dev/null +++ b/patches/server/MC-135506-Experience-should-save-as-Integers.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +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 + } diff --git a/patches/server-remapped/Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch b/patches/server/Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch similarity index 76% rename from patches/server-remapped/Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch rename to patches/server/Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch index 042ca1eb5..1a744c2c6 100644 --- a/patches/server-remapped/Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch +++ b/patches/server/Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch @@ -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) { diff --git a/patches/server-remapped/Make-EnderDragon-implement-Mob.patch b/patches/server/Make-EnderDragon-implement-Mob.patch similarity index 100% rename from patches/server-remapped/Make-EnderDragon-implement-Mob.patch rename to patches/server/Make-EnderDragon-implement-Mob.patch diff --git a/patches/server-remapped/Optimize-BlockPosition-helper-methods.patch b/patches/server/Optimize-BlockPosition-helper-methods.patch similarity index 89% rename from patches/server-remapped/Optimize-BlockPosition-helper-methods.patch rename to patches/server/Optimize-BlockPosition-helper-methods.patch index 132bb6d6b..202a43456 100644 --- a/patches/server-remapped/Optimize-BlockPosition-helper-methods.patch +++ b/patches/server/Optimize-BlockPosition-helper-methods.patch @@ -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 } diff --git a/patches/server-remapped/Optimize-CraftBlockData-Creation.patch b/patches/server/Optimize-CraftBlockData-Creation.patch similarity index 95% rename from patches/server-remapped/Optimize-CraftBlockData-Creation.patch rename to patches/server/Optimize-CraftBlockData-Creation.patch index e58b40c25..8eda4656f 100644 --- a/patches/server-remapped/Optimize-CraftBlockData-Creation.patch +++ b/patches/server/Optimize-CraftBlockData-Creation.patch @@ -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); } diff --git a/patches/server/Optimize-MappedRegistry.patch b/patches/server/Optimize-MappedRegistry.patch new file mode 100644 index 000000000..e2fee4660 --- /dev/null +++ b/patches/server/Optimize-MappedRegistry.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +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 extends WritableRegistry { + protected static final Logger LOGGER = LogManager.getLogger(); + private final ObjectList byId = new ObjectArrayList<>(256); +- private final Object2IntMap toId = new Object2IntOpenCustomHashMap<>(Util.identityStrategy()); ++ private final it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap toId = new it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap(2048);// Paper - use bigger expected size to reduce collisions and direct intent for FastUtil to be identity map + private final BiMap storage; + private final BiMap, T> keyStorage; + private final Map lifecycles; +@@ -0,0 +0,0 @@ public class MappedRegistry extends WritableRegistry { + public MappedRegistry(ResourceKey> 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; + } + diff --git a/patches/server-remapped/Restore-vanlla-default-mob-spawn-range-and-water-ani.patch b/patches/server/Restore-vanlla-default-mob-spawn-range-and-water-ani.patch similarity index 83% rename from patches/server-remapped/Restore-vanlla-default-mob-spawn-range-and-water-ani.patch rename to patches/server/Restore-vanlla-default-mob-spawn-range-and-water-ani.patch index d207708d6..749d0e558 100644 --- a/patches/server-remapped/Restore-vanlla-default-mob-spawn-range-and-water-ani.patch +++ b/patches/server/Restore-vanlla-default-mob-spawn-range-and-water-ani.patch @@ -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 diff --git a/patches/server-remapped/SkeletonHorse-Additions.patch b/patches/server/SkeletonHorse-Additions.patch similarity index 64% rename from patches/server-remapped/SkeletonHorse-Additions.patch rename to patches/server/SkeletonHorse-Additions.patch index ca8ccafa0..916eed361 100644 --- a/patches/server-remapped/SkeletonHorse-Additions.patch +++ b/patches/server/SkeletonHorse-Additions.patch @@ -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 ATTACK_ALLOWED = (entity) -> { - return !(entity instanceof Player) || !entity.isSpectator() && !((Player) entity).isCreative() && entity.level.getDifficulty() != Difficulty.PEACEFUL; - }; -+ public static Predicate notSpectator() { return NO_SPECTATORS; } // Paper - OBFHELPER - public static final Predicate 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 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 eligiblePlayers; // Paper ++ private java.util.List 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 findNearbyBukkitPlayers(double x, double y, double z, double radius, boolean notSpectator) { -+ return findNearbyBukkitPlayers(x, y, z, radius, notSpectator ? EntitySelector.notSpectator() : EntitySelector.canAITarget()); ++ default List 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 findNearbyBukkitPlayers(double x, double y, double z, double radius, @Nullable Predicate predicate) { -+ ImmutableList.Builder builder = ImmutableList.builder(); ++ default List findNearbyBukkitPlayers(double x, double y, double z, double radius, @Nullable Predicate predicate) { ++ com.google.common.collect.ImmutableList.Builder 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 diff --git a/patches/server-remapped/Slime-Pathfinder-Events.patch b/patches/server/Slime-Pathfinder-Events.patch similarity index 56% rename from patches/server-remapped/Slime-Pathfinder-Events.patch rename to patches/server/Slime-Pathfinder-Events.patch index 6132bc9b8..71f7298b2 100644 --- a/patches/server-remapped/Slime-Pathfinder-Events.patch +++ b/patches/server/Slime-Pathfinder-Events.patch @@ -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 slimes = new ArrayList<>(j); -+ List 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); + } diff --git a/patches/server-remapped/Use-ConcurrentHashMap-in-JsonList.patch b/patches/server/Use-ConcurrentHashMap-in-JsonList.patch similarity index 93% rename from patches/server-remapped/Use-ConcurrentHashMap-in-JsonList.patch rename to patches/server/Use-ConcurrentHashMap-in-JsonList.patch index 4dba57026..e31648784 100644 --- a/patches/server-remapped/Use-ConcurrentHashMap-in-JsonList.patch +++ b/patches/server/Use-ConcurrentHashMap-in-JsonList.patch @@ -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 stream = this.map.values().stream().map((jsonlistentry) -> { // CraftBukkit - decompile error + JsonObject jsonobject = new JsonObject(); diff --git a/patches/server-remapped/Use-a-Queue-for-Queueing-Commands.patch b/patches/server/Use-a-Queue-for-Queueing-Commands.patch similarity index 94% rename from patches/server-remapped/Use-a-Queue-for-Queueing-Commands.patch rename to patches/server/Use-a-Queue-for-Queueing-Commands.patch index 659264ce7..7aa41a394 100644 --- a/patches/server-remapped/Use-a-Queue-for-Queueing-Commands.patch +++ b/patches/server/Use-a-Queue-for-Queueing-Commands.patch @@ -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 = Collections.synchronizedList(Lists.newArrayList()); + private final java.util.Queue serverCommandQueue = new java.util.concurrent.ConcurrentLinkedQueue<>(); // Paper - use a proper queue