diff --git a/Spigot-Server-Patches/0004-MC-Utils.patch b/Spigot-Server-Patches/0004-MC-Utils.patch index 54f3332d1..3d434e22e 100644 --- a/Spigot-Server-Patches/0004-MC-Utils.patch +++ b/Spigot-Server-Patches/0004-MC-Utils.patch @@ -1,4 +1,4 @@ -From 9dddbd86ae3f6a9a51b05a9a406e1a33c0d5839e Mon Sep 17 00:00:00 2001 +From 39fe4c93947820526f380f39715181ba25f3996e Mon Sep 17 00:00:00 2001 From: Aikar Date: Mon, 28 Mar 2016 20:55:47 -0400 Subject: [PATCH] MC Utils @@ -6,7 +6,7 @@ Subject: [PATCH] MC Utils diff --git a/src/main/java/com/destroystokyo/paper/util/concurrent/WeakSeqLock.java b/src/main/java/com/destroystokyo/paper/util/concurrent/WeakSeqLock.java new file mode 100644 -index 000000000..4029dc68c +index 0000000000..4029dc68cf --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/util/concurrent/WeakSeqLock.java @@ -0,0 +1,68 @@ @@ -80,7 +80,7 @@ index 000000000..4029dc68c +} diff --git a/src/main/java/com/destroystokyo/paper/util/map/QueuedChangesMapLong2Int.java b/src/main/java/com/destroystokyo/paper/util/map/QueuedChangesMapLong2Int.java new file mode 100644 -index 000000000..968c9ed32 +index 0000000000..968c9ed328 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/util/map/QueuedChangesMapLong2Int.java @@ -0,0 +1,156 @@ @@ -242,7 +242,7 @@ index 000000000..968c9ed32 +} diff --git a/src/main/java/com/destroystokyo/paper/util/map/QueuedChangesMapLong2Object.java b/src/main/java/com/destroystokyo/paper/util/map/QueuedChangesMapLong2Object.java new file mode 100644 -index 000000000..07685b6bd +index 0000000000..07685b6bd5 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/util/map/QueuedChangesMapLong2Object.java @@ -0,0 +1,172 @@ @@ -420,7 +420,7 @@ index 000000000..07685b6bd +} diff --git a/src/main/java/com/destroystokyo/paper/util/maplist/ChunkList.java b/src/main/java/com/destroystokyo/paper/util/maplist/ChunkList.java new file mode 100644 -index 000000000..4ec248adb +index 0000000000..4ec248adb6 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/util/maplist/ChunkList.java @@ -0,0 +1,127 @@ @@ -553,7 +553,7 @@ index 000000000..4ec248adb +} diff --git a/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java b/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java new file mode 100644 -index 000000000..f3cb346c9 +index 0000000000..f3cb346c9d --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java @@ -0,0 +1,126 @@ @@ -685,7 +685,7 @@ index 000000000..f3cb346c9 +} diff --git a/src/main/java/com/destroystokyo/paper/util/maplist/IBlockDataList.java b/src/main/java/com/destroystokyo/paper/util/maplist/IBlockDataList.java new file mode 100644 -index 000000000..c2f7e4ca0 +index 0000000000..c2f7e4ca0f --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/util/maplist/IBlockDataList.java @@ -0,0 +1,126 @@ @@ -817,7 +817,7 @@ index 000000000..c2f7e4ca0 +} diff --git a/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java b/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java new file mode 100644 -index 000000000..5a44bc644 +index 0000000000..5a44bc644b --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java @@ -0,0 +1,389 @@ @@ -1212,7 +1212,7 @@ index 000000000..5a44bc644 +} diff --git a/src/main/java/com/destroystokyo/paper/util/misc/PlayerAreaMap.java b/src/main/java/com/destroystokyo/paper/util/misc/PlayerAreaMap.java new file mode 100644 -index 000000000..8a552a87a +index 0000000000..8a552a87ab --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/util/misc/PlayerAreaMap.java @@ -0,0 +1,27 @@ @@ -1245,7 +1245,7 @@ index 000000000..8a552a87a +} diff --git a/src/main/java/com/destroystokyo/paper/util/misc/PooledLinkedHashSets.java b/src/main/java/com/destroystokyo/paper/util/misc/PooledLinkedHashSets.java new file mode 100644 -index 000000000..5f2d88797 +index 0000000000..5f2d88797d --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/util/misc/PooledLinkedHashSets.java @@ -0,0 +1,289 @@ @@ -1540,7 +1540,7 @@ index 000000000..5f2d88797 +} diff --git a/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java b/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java new file mode 100644 -index 000000000..4d74a7a90 +index 0000000000..4d74a7a908 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java @@ -0,0 +1,65 @@ @@ -1610,7 +1610,7 @@ index 000000000..4d74a7a90 + } +} diff --git a/src/main/java/net/minecraft/server/BlockAccessAir.java b/src/main/java/net/minecraft/server/BlockAccessAir.java -index eff6ebcd3..30cbfc8ea 100644 +index eff6ebcd30..30cbfc8eac 100644 --- a/src/main/java/net/minecraft/server/BlockAccessAir.java +++ b/src/main/java/net/minecraft/server/BlockAccessAir.java @@ -14,6 +14,18 @@ public enum BlockAccessAir implements IBlockAccess { @@ -1633,7 +1633,7 @@ index eff6ebcd3..30cbfc8ea 100644 public IBlockData getType(BlockPosition blockposition) { return Blocks.AIR.getBlockData(); diff --git a/src/main/java/net/minecraft/server/BlockDataAbstract.java b/src/main/java/net/minecraft/server/BlockDataAbstract.java -index 1cf97cefc..2040f1834 100644 +index 1cf97cefc9..2040f18349 100644 --- a/src/main/java/net/minecraft/server/BlockDataAbstract.java +++ b/src/main/java/net/minecraft/server/BlockDataAbstract.java @@ -78,6 +78,7 @@ public abstract class BlockDataAbstract implements IBlockDataHolder { @@ -1645,7 +1645,7 @@ index 1cf97cefc..2040f1834 100644 return this.d.containsKey(iblockstate); } diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java -index c88a62f6b..5dbd3e60f 100644 +index c88a62f6b7..5dbd3e60fe 100644 --- a/src/main/java/net/minecraft/server/BlockPosition.java +++ b/src/main/java/net/minecraft/server/BlockPosition.java @@ -120,6 +120,7 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali @@ -1700,7 +1700,7 @@ index c88a62f6b..5dbd3e60f 100644 this.d = i; } diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 55373cae0..af10c18d4 100644 +index 55373cae07..af10c18d44 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java @@ -25,7 +25,7 @@ import org.apache.logging.log4j.Logger; @@ -1802,7 +1802,7 @@ index 55373cae0..af10c18d4 100644 // CraftBukkit end diff --git a/src/main/java/net/minecraft/server/ChunkCache.java b/src/main/java/net/minecraft/server/ChunkCache.java -index 11c4d23ba..53c15c1c0 100644 +index 11c4d23ba9..53c15c1c0b 100644 --- a/src/main/java/net/minecraft/server/ChunkCache.java +++ b/src/main/java/net/minecraft/server/ChunkCache.java @@ -8,7 +8,7 @@ public class ChunkCache implements IBlockAccess, ICollisionAccess { @@ -1836,7 +1836,7 @@ index 11c4d23ba..53c15c1c0 100644 @Override public TileEntity getTileEntity(BlockPosition blockposition) { diff --git a/src/main/java/net/minecraft/server/ChunkCoordIntPair.java b/src/main/java/net/minecraft/server/ChunkCoordIntPair.java -index 260644bf0..f2a19acd8 100644 +index 260644bf0b..f2a19acd84 100644 --- a/src/main/java/net/minecraft/server/ChunkCoordIntPair.java +++ b/src/main/java/net/minecraft/server/ChunkCoordIntPair.java @@ -31,7 +31,9 @@ public class ChunkCoordIntPair { @@ -1851,7 +1851,7 @@ index 260644bf0..f2a19acd8 100644 } diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index 41eac3588..a5f2468a6 100644 +index 41eac3588e..a5f2468a66 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -23,7 +23,7 @@ public class ChunkProviderServer extends IChunkProvider { @@ -2003,7 +2003,7 @@ index 41eac3588..a5f2468a6 100644 @Override public IChunkAccess getChunkAt(int i, int j, ChunkStatus chunkstatus, boolean flag) { diff --git a/src/main/java/net/minecraft/server/DataBits.java b/src/main/java/net/minecraft/server/DataBits.java -index 7ca3a1d0c..2edd9b871 100644 +index 7ca3a1d0c5..2edd9b8714 100644 --- a/src/main/java/net/minecraft/server/DataBits.java +++ b/src/main/java/net/minecraft/server/DataBits.java @@ -83,6 +83,7 @@ public class DataBits { @@ -2015,7 +2015,7 @@ index 7ca3a1d0c..2edd9b871 100644 return this.a; } diff --git a/src/main/java/net/minecraft/server/DataPalette.java b/src/main/java/net/minecraft/server/DataPalette.java -index 75ba69886..45403fbe3 100644 +index 75ba698868..45403fbe30 100644 --- a/src/main/java/net/minecraft/server/DataPalette.java +++ b/src/main/java/net/minecraft/server/DataPalette.java @@ -4,10 +4,12 @@ import javax.annotation.Nullable; @@ -2032,7 +2032,7 @@ index 75ba69886..45403fbe3 100644 T a(int i); diff --git a/src/main/java/net/minecraft/server/DataPaletteBlock.java b/src/main/java/net/minecraft/server/DataPaletteBlock.java -index 774a8f543..d5f5a5187 100644 +index 774a8f5434..d5f5a51872 100644 --- a/src/main/java/net/minecraft/server/DataPaletteBlock.java +++ b/src/main/java/net/minecraft/server/DataPaletteBlock.java @@ -11,7 +11,7 @@ import java.util.stream.Collectors; @@ -2074,7 +2074,7 @@ index 774a8f543..d5f5a5187 100644 this.a(); packetdataserializer.writeByte(this.i); diff --git a/src/main/java/net/minecraft/server/EntityCreature.java b/src/main/java/net/minecraft/server/EntityCreature.java -index fe69161e5..b40c8d2f8 100644 +index fe69161e5b..b40c8d2f83 100644 --- a/src/main/java/net/minecraft/server/EntityCreature.java +++ b/src/main/java/net/minecraft/server/EntityCreature.java @@ -6,6 +6,8 @@ import org.bukkit.event.entity.EntityUnleashEvent; @@ -2087,7 +2087,7 @@ index fe69161e5..b40c8d2f8 100644 super(entitytypes, world); } diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java -index bdfb17385..0b06fa2b6 100644 +index bdfb173853..0b06fa2b66 100644 --- a/src/main/java/net/minecraft/server/EntityInsentient.java +++ b/src/main/java/net/minecraft/server/EntityInsentient.java @@ -146,6 +146,7 @@ public abstract class EntityInsentient extends EntityLiving { @@ -2099,7 +2099,7 @@ index bdfb17385..0b06fa2b6 100644 // CraftBukkit start - fire event setGoalTarget(entityliving, EntityTargetEvent.TargetReason.UNKNOWN, true); diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index 3b1bcf349..1f350e335 100644 +index 3b1bcf3495..1f350e3352 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java @@ -129,6 +129,7 @@ public abstract class EntityLiving extends Entity { @@ -2111,7 +2111,7 @@ index 3b1bcf349..1f350e335 100644 @Override public float getBukkitYaw() { diff --git a/src/main/java/net/minecraft/server/EntityMonster.java b/src/main/java/net/minecraft/server/EntityMonster.java -index 00c3b666d..e5322fbae 100644 +index 00c3b666d7..e5322fbae5 100644 --- a/src/main/java/net/minecraft/server/EntityMonster.java +++ b/src/main/java/net/minecraft/server/EntityMonster.java @@ -5,6 +5,7 @@ import java.util.function.Predicate; @@ -2123,7 +2123,7 @@ index 00c3b666d..e5322fbae 100644 super(entitytypes, world); this.f = 5; diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index ce4821092..57ce9bde6 100644 +index ce48210922..57ce9bde64 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java @@ -87,6 +87,8 @@ public class EntityPlayer extends EntityHuman implements ICrafting { @@ -2145,7 +2145,7 @@ index ce4821092..57ce9bde6 100644 this.displayName = this.getName(); this.canPickUpLoot = true; diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java -index f937b7294..cbf0c2f25 100644 +index f937b72945..cbf0c2f25d 100644 --- a/src/main/java/net/minecraft/server/EntityTypes.java +++ b/src/main/java/net/minecraft/server/EntityTypes.java @@ -4,6 +4,7 @@ import com.mojang.datafixers.DataFixUtils; @@ -2168,7 +2168,7 @@ index f937b7294..cbf0c2f25 100644 } diff --git a/src/main/java/net/minecraft/server/IAsyncTaskHandler.java b/src/main/java/net/minecraft/server/IAsyncTaskHandler.java -index 1890c760f..7e5ece9d5 100644 +index 1890c760f9..7e5ece9d50 100644 --- a/src/main/java/net/minecraft/server/IAsyncTaskHandler.java +++ b/src/main/java/net/minecraft/server/IAsyncTaskHandler.java @@ -68,6 +68,15 @@ public abstract class IAsyncTaskHandler implements Mailbox h = new CompletableFuture(); diff --git a/src/main/java/net/minecraft/server/IWorldReader.java b/src/main/java/net/minecraft/server/IWorldReader.java -index ba315131e..cbe2aa4c0 100644 +index ba315131e1..cbe2aa4c0a 100644 --- a/src/main/java/net/minecraft/server/IWorldReader.java +++ b/src/main/java/net/minecraft/server/IWorldReader.java @@ -4,6 +4,7 @@ import javax.annotation.Nullable; @@ -2242,7 +2242,7 @@ index ba315131e..cbe2aa4c0 100644 IChunkAccess getChunkAt(int i, int j, ChunkStatus chunkstatus, boolean flag); diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java -index 75308712d..aa7501d36 100644 +index 75308712d0..aa7501d366 100644 --- a/src/main/java/net/minecraft/server/ItemStack.java +++ b/src/main/java/net/minecraft/server/ItemStack.java @@ -37,10 +37,19 @@ import org.bukkit.event.world.StructureGrowEvent; @@ -2302,10 +2302,10 @@ index 75308712d..aa7501d36 100644 // CraftBukkit end diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java new file mode 100644 -index 000000000..9fa88d79d +index 0000000000..de2bc8f6a6 --- /dev/null +++ b/src/main/java/net/minecraft/server/MCUtil.java -@@ -0,0 +1,386 @@ +@@ -0,0 +1,384 @@ +package net.minecraft.server; + +import com.destroystokyo.paper.block.TargetBlockInfo; @@ -2387,15 +2387,13 @@ index 000000000..9fa88d79d + } + + // assumes the sets have the same comparator, and if this comparator is null then assume T is Comparable -+ public static void mergeSortedSets(final java.util.function.Consumer consumer, final java.util.SortedSet...sets) { -+ java.util.Comparator comparator = sets[0].comparator(); -+ if (comparator == null) { -+ comparator = (java.util.Comparator)java.util.Comparator.naturalOrder(); -+ } ++ public static void mergeSortedSets(final java.util.function.Consumer consumer, final java.util.Comparator comparator, final java.util.SortedSet...sets) { + final it.unimi.dsi.fastutil.objects.ObjectRBTreeSet all = new it.unimi.dsi.fastutil.objects.ObjectRBTreeSet<>(comparator); + // note: this is done in log(n!) ~ nlogn time. It could be improved if it were to mimic what mergesort does. + for (java.util.SortedSet set : sets) { -+ all.addAll(all); ++ if (set != null) { ++ all.addAll(set); ++ } + } + all.forEach(consumer); + } @@ -2693,7 +2691,7 @@ index 000000000..9fa88d79d + } +} diff --git a/src/main/java/net/minecraft/server/NBTTagCompound.java b/src/main/java/net/minecraft/server/NBTTagCompound.java -index e85b24a32..75604dbc6 100644 +index e85b24a327..75604dbc69 100644 --- a/src/main/java/net/minecraft/server/NBTTagCompound.java +++ b/src/main/java/net/minecraft/server/NBTTagCompound.java @@ -60,7 +60,7 @@ public class NBTTagCompound implements NBTBase { @@ -2722,7 +2720,7 @@ index e85b24a32..75604dbc6 100644 return new UUID(this.getLong(s + "Most"), this.getLong(s + "Least")); } diff --git a/src/main/java/net/minecraft/server/NetworkManager.java b/src/main/java/net/minecraft/server/NetworkManager.java -index 6700582e3..3ccf16636 100644 +index 6700582e36..3ccf166366 100644 --- a/src/main/java/net/minecraft/server/NetworkManager.java +++ b/src/main/java/net/minecraft/server/NetworkManager.java @@ -159,6 +159,7 @@ public class NetworkManager extends SimpleChannelInboundHandler> { @@ -2754,7 +2752,7 @@ index 6700582e3..3ccf16636 100644 public QueuedPacket(Packet packet, @Nullable GenericFutureListener> genericfuturelistener) { this.a = packet; diff --git a/src/main/java/net/minecraft/server/PacketDataSerializer.java b/src/main/java/net/minecraft/server/PacketDataSerializer.java -index 81b6f4581..d9574a9ac 100644 +index 81b6f4581f..d9574a9ace 100644 --- a/src/main/java/net/minecraft/server/PacketDataSerializer.java +++ b/src/main/java/net/minecraft/server/PacketDataSerializer.java @@ -33,6 +33,7 @@ public class PacketDataSerializer extends ByteBuf { @@ -2766,7 +2764,7 @@ index 81b6f4581..d9574a9ac 100644 for (int j = 1; j < 5; ++j) { if ((i & -1 << j * 7) == 0) { diff --git a/src/main/java/net/minecraft/server/PacketEncoder.java b/src/main/java/net/minecraft/server/PacketEncoder.java -index 90223deae..63c4dbd32 100644 +index 90223deae3..63c4dbd327 100644 --- a/src/main/java/net/minecraft/server/PacketEncoder.java +++ b/src/main/java/net/minecraft/server/PacketEncoder.java @@ -42,6 +42,7 @@ public class PacketEncoder extends MessageToByteEncoder> { @@ -2778,7 +2776,7 @@ index 90223deae..63c4dbd32 100644 throw new SkipEncodeException(throwable); } else { diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java -index 677e3e5f6..3a1d0deb0 100644 +index 677e3e5f68..3a1d0deb0d 100644 --- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java @@ -17,7 +17,7 @@ public class PacketPlayOutMapChunk implements Packet { @@ -2799,7 +2797,7 @@ index 677e3e5f6..3a1d0deb0 100644 int j = 0; ChunkSection[] achunksection = chunk.getSections(); diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java -index 5c5bf010d..c4bbee7d6 100644 +index 5c5bf010d0..c4bbee7d6a 100644 --- a/src/main/java/net/minecraft/server/PlayerChunk.java +++ b/src/main/java/net/minecraft/server/PlayerChunk.java @@ -19,9 +19,9 @@ public class PlayerChunk { @@ -2971,7 +2969,7 @@ index 5c5bf010d..c4bbee7d6 100644 } diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 7ad30548e..93d838ec2 100644 +index 7ad30548e2..93d838ec2d 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -99,6 +99,35 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -3020,7 +3018,7 @@ index 7ad30548e..93d838ec2 100644 @Override diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -index 0c496ee0a..6a681d694 100644 +index 0c496ee0a0..6a681d694e 100644 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java @@ -67,9 +67,9 @@ public class PlayerConnection implements PacketListenerPlayIn { @@ -3037,7 +3035,7 @@ index 0c496ee0a..6a681d694 100644 private volatile int chatThrottle; private static final AtomicIntegerFieldUpdater chatSpamField = AtomicIntegerFieldUpdater.newUpdater(PlayerConnection.class, "chatThrottle"); diff --git a/src/main/java/net/minecraft/server/PlayerInventory.java b/src/main/java/net/minecraft/server/PlayerInventory.java -index 08768a3c8..d103cfaac 100644 +index 08768a3c87..d103cfaace 100644 --- a/src/main/java/net/minecraft/server/PlayerInventory.java +++ b/src/main/java/net/minecraft/server/PlayerInventory.java @@ -17,7 +17,7 @@ public class PlayerInventory implements IInventory, INamableTileEntity { @@ -3050,7 +3048,7 @@ index 08768a3c8..d103cfaac 100644 public final EntityHuman player; private ItemStack carried; diff --git a/src/main/java/net/minecraft/server/PotionUtil.java b/src/main/java/net/minecraft/server/PotionUtil.java -index b3824898d..bf4172be5 100644 +index b3824898da..bf4172be52 100644 --- a/src/main/java/net/minecraft/server/PotionUtil.java +++ b/src/main/java/net/minecraft/server/PotionUtil.java @@ -110,6 +110,7 @@ public class PotionUtil { @@ -3062,7 +3060,7 @@ index b3824898d..bf4172be5 100644 MinecraftKey minecraftkey = IRegistry.POTION.getKey(potionregistry); diff --git a/src/main/java/net/minecraft/server/ProtoChunk.java b/src/main/java/net/minecraft/server/ProtoChunk.java -index 6e65306a2..39339fa27 100644 +index 6e65306a27..39339fa275 100644 --- a/src/main/java/net/minecraft/server/ProtoChunk.java +++ b/src/main/java/net/minecraft/server/ProtoChunk.java @@ -80,6 +80,18 @@ public class ProtoChunk implements IChunkAccess { @@ -3085,7 +3083,7 @@ index 6e65306a2..39339fa27 100644 public IBlockData getType(BlockPosition blockposition) { int i = blockposition.getY(); diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java -index 7b6e0e86b..187c4e0f5 100644 +index 7b6e0e86b0..187c4e0f58 100644 --- a/src/main/java/net/minecraft/server/RegionFile.java +++ b/src/main/java/net/minecraft/server/RegionFile.java @@ -88,6 +88,7 @@ public class RegionFile implements AutoCloseable { @@ -3097,7 +3095,7 @@ index 7b6e0e86b..187c4e0f5 100644 public synchronized DataInputStream a(ChunkCoordIntPair chunkcoordintpair) throws IOException { int i = this.getOffset(chunkcoordintpair); diff --git a/src/main/java/net/minecraft/server/RegionLimitedWorldAccess.java b/src/main/java/net/minecraft/server/RegionLimitedWorldAccess.java -index 8c123f265..9d0e8c2d4 100644 +index 8c123f265e..9d0e8c2d43 100644 --- a/src/main/java/net/minecraft/server/RegionLimitedWorldAccess.java +++ b/src/main/java/net/minecraft/server/RegionLimitedWorldAccess.java @@ -108,6 +108,26 @@ public class RegionLimitedWorldAccess implements GeneratorAccess { @@ -3128,7 +3126,7 @@ index 8c123f265..9d0e8c2d4 100644 public IBlockData getType(BlockPosition blockposition) { return this.getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4).getType(blockposition); diff --git a/src/main/java/net/minecraft/server/RegistryBlockID.java b/src/main/java/net/minecraft/server/RegistryBlockID.java -index 4efcb8b59..60948afa4 100644 +index 4efcb8b595..60948afa4e 100644 --- a/src/main/java/net/minecraft/server/RegistryBlockID.java +++ b/src/main/java/net/minecraft/server/RegistryBlockID.java @@ -57,6 +57,7 @@ public class RegistryBlockID implements Registry { @@ -3140,7 +3138,7 @@ index 4efcb8b59..60948afa4 100644 return this.b.size(); } diff --git a/src/main/java/net/minecraft/server/SystemUtils.java b/src/main/java/net/minecraft/server/SystemUtils.java -index 7b92ecfff..7e224ebef 100644 +index 7b92ecfff9..7e224ebeff 100644 --- a/src/main/java/net/minecraft/server/SystemUtils.java +++ b/src/main/java/net/minecraft/server/SystemUtils.java @@ -58,7 +58,7 @@ public class SystemUtils { @@ -3153,7 +3151,7 @@ index 7b92ecfff..7e224ebef 100644 public static long getTimeMillis() { diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 177e2af68..6861711c2 100644 +index 177e2af68d..6861711c29 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java @@ -22,6 +22,7 @@ import org.bukkit.craftbukkit.SpigotTimings; // Spigot @@ -3217,7 +3215,7 @@ index 177e2af68..6861711c2 100644 return this.setTypeAndData(blockposition, fluid.getBlockData(), 3 | (flag ? 64 : 0)); diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index d5014abc9..8a5ac6f69 100644 +index d5014abc9d..8a5ac6f69b 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -973,6 +973,7 @@ public class WorldServer extends World { @@ -3237,7 +3235,7 @@ index d5014abc9..8a5ac6f69 100644 this.getScoreboard().a(entity); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -index e181df6f4..4a9132c70 100644 +index e181df6f4d..4a9132c701 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java @@ -85,6 +85,7 @@ public final class CraftItemStack extends ItemStack { @@ -3249,7 +3247,7 @@ index e181df6f4..4a9132c70 100644 /** * Mirror diff --git a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java -index d8358a0f0..d0b813008 100644 +index d8358a0f03..d0b813008c 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java +++ b/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java @@ -196,4 +196,22 @@ public class DummyGeneratorAccess implements GeneratorAccess { @@ -3276,7 +3274,7 @@ index d8358a0f0..d0b813008 100644 + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java b/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java -index 1aec70a1f..f72c13bed 100644 +index 1aec70a1f1..f72c13beda 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java +++ b/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java @@ -17,7 +17,7 @@ import java.util.RandomAccess; @@ -3289,5 +3287,5 @@ index 1aec70a1f..f72c13bed 100644 private int initialCapacity; -- -2.25.0 +2.25.1 diff --git a/Spigot-Server-Patches/0135-String-based-Action-Bar-API.patch b/Spigot-Server-Patches/0135-String-based-Action-Bar-API.patch index 96fe1de9c..7580be202 100644 --- a/Spigot-Server-Patches/0135-String-based-Action-Bar-API.patch +++ b/Spigot-Server-Patches/0135-String-based-Action-Bar-API.patch @@ -1,11 +1,11 @@ -From f0e1f1fa1e613324eec3095d858a8cf79f02b85c Mon Sep 17 00:00:00 2001 +From 87036dca71606ff58cac12d21de6c58606923392 Mon Sep 17 00:00:00 2001 From: Aikar Date: Tue, 27 Dec 2016 15:02:42 -0500 Subject: [PATCH] String based Action Bar API diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java -index 9fa88d79d8..ee2174a9ca 100644 +index de2bc8f6a6..e42dc05504 100644 --- a/src/main/java/net/minecraft/server/MCUtil.java +++ b/src/main/java/net/minecraft/server/MCUtil.java @@ -2,6 +2,7 @@ package net.minecraft.server; @@ -16,7 +16,7 @@ index 9fa88d79d8..ee2174a9ca 100644 import org.bukkit.Location; import org.bukkit.block.BlockFace; import org.bukkit.craftbukkit.CraftWorld; -@@ -94,6 +95,24 @@ public final class MCUtil { +@@ -92,6 +93,24 @@ public final class MCUtil { private MCUtil() {} @@ -65,5 +65,5 @@ index 447ecf636d..3a2a886180 100644 public void setPlayerListHeaderFooter(BaseComponent[] header, BaseComponent[] footer) { if (header != null) { -- -2.25.0.windows.1 +2.25.1 diff --git a/Spigot-Server-Patches/0156-Basic-PlayerProfile-API.patch b/Spigot-Server-Patches/0156-Basic-PlayerProfile-API.patch index e4fd57022..daec78c1e 100644 --- a/Spigot-Server-Patches/0156-Basic-PlayerProfile-API.patch +++ b/Spigot-Server-Patches/0156-Basic-PlayerProfile-API.patch @@ -1,4 +1,4 @@ -From 026d149a2059a4f00647f08440325276834191a3 Mon Sep 17 00:00:00 2001 +From 5de8db67726252bb14d83e1e3a82f5b3351013a5 Mon Sep 17 00:00:00 2001 From: Aikar Date: Mon, 15 Jan 2018 22:11:48 -0500 Subject: [PATCH] Basic PlayerProfile API @@ -7,7 +7,7 @@ Establishes base extension of profile systems for future edits too diff --git a/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java b/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java new file mode 100644 -index 000000000..b151a13c1 +index 0000000000..b151a13c1b --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java @@ -0,0 +1,280 @@ @@ -293,7 +293,7 @@ index 000000000..b151a13c1 +} diff --git a/src/main/java/com/destroystokyo/paper/profile/PaperAuthenticationService.java b/src/main/java/com/destroystokyo/paper/profile/PaperAuthenticationService.java new file mode 100644 -index 000000000..25836b975 +index 0000000000..25836b975b --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/profile/PaperAuthenticationService.java @@ -0,0 +1,30 @@ @@ -329,7 +329,7 @@ index 000000000..25836b975 +} diff --git a/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java b/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java new file mode 100644 -index 000000000..3bcdb8f93 +index 0000000000..3bcdb8f93f --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java @@ -0,0 +1,17 @@ @@ -352,7 +352,7 @@ index 000000000..3bcdb8f93 +} diff --git a/src/main/java/com/destroystokyo/paper/profile/PaperMinecraftSessionService.java b/src/main/java/com/destroystokyo/paper/profile/PaperMinecraftSessionService.java new file mode 100644 -index 000000000..4b2a67423 +index 0000000000..4b2a67423f --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/profile/PaperMinecraftSessionService.java @@ -0,0 +1,29 @@ @@ -387,7 +387,7 @@ index 000000000..4b2a67423 +} diff --git a/src/main/java/com/destroystokyo/paper/profile/PaperUserAuthentication.java b/src/main/java/com/destroystokyo/paper/profile/PaperUserAuthentication.java new file mode 100644 -index 000000000..3aceb0ea8 +index 0000000000..3aceb0ea8a --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/profile/PaperUserAuthentication.java @@ -0,0 +1,11 @@ @@ -403,7 +403,7 @@ index 000000000..3aceb0ea8 + } +} diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java -index ee2174a9c..2a22bc6f3 100644 +index e42dc05504..ddd7277162 100644 --- a/src/main/java/net/minecraft/server/MCUtil.java +++ b/src/main/java/net/minecraft/server/MCUtil.java @@ -1,7 +1,10 @@ @@ -417,7 +417,7 @@ index ee2174a9c..2a22bc6f3 100644 import org.apache.commons.lang.exception.ExceptionUtils; import org.bukkit.Location; import org.bukkit.block.BlockFace; -@@ -228,6 +231,10 @@ public final class MCUtil { +@@ -226,6 +229,10 @@ public final class MCUtil { return run.get(); } @@ -429,7 +429,7 @@ index ee2174a9c..2a22bc6f3 100644 * Calculates distance between 2 entities * @param e1 diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 7016dac2d..c15ca642d 100644 +index 7016dac2d7..c15ca642d0 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1296,7 +1296,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant Date: Sat, 22 Sep 2018 15:56:59 -0400 Subject: [PATCH] Catch JsonParseException in Entity and TE names @@ -13,7 +13,7 @@ Shulkers) may need to be changed in order for it to re-save properly No more crashing though. diff --git a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java -index 786712297..ef2a496ed 100644 +index 7867122974..ef2a496eda 100644 --- a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java +++ b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java @@ -59,7 +59,7 @@ public abstract class CommandBlockListenerAbstract implements ICommandListener { @@ -26,7 +26,7 @@ index 786712297..ef2a496ed 100644 if (nbttagcompound.hasKeyOfType("TrackOutput", 1)) { diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index e8b70a5ca..9a2338060 100644 +index e8b70a5ca5..9a23380600 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java @@ -1679,7 +1679,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke @@ -39,10 +39,10 @@ index e8b70a5ca..9a2338060 100644 this.setCustomNameVisible(nbttagcompound.getBoolean("CustomNameVisible")); diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java -index 2a22bc6f3..3a482466e 100644 +index ddd7277162..bfddeb7cdb 100644 --- a/src/main/java/net/minecraft/server/MCUtil.java +++ b/src/main/java/net/minecraft/server/MCUtil.java -@@ -409,4 +409,19 @@ public final class MCUtil { +@@ -407,4 +407,19 @@ public final class MCUtil { return null; } } @@ -63,7 +63,7 @@ index 2a22bc6f3..3a482466e 100644 + } } diff --git a/src/main/java/net/minecraft/server/TileEntityBanner.java b/src/main/java/net/minecraft/server/TileEntityBanner.java -index 93911a825..d35604edb 100644 +index 93911a8251..d35604edb2 100644 --- a/src/main/java/net/minecraft/server/TileEntityBanner.java +++ b/src/main/java/net/minecraft/server/TileEntityBanner.java @@ -60,7 +60,7 @@ public class TileEntityBanner extends TileEntity implements INamableTileEntity { @@ -76,7 +76,7 @@ index 93911a825..d35604edb 100644 if (this.hasWorld()) { diff --git a/src/main/java/net/minecraft/server/TileEntityContainer.java b/src/main/java/net/minecraft/server/TileEntityContainer.java -index 473ec2cbd..ab6b86e4e 100644 +index 473ec2cbde..ab6b86e4e9 100644 --- a/src/main/java/net/minecraft/server/TileEntityContainer.java +++ b/src/main/java/net/minecraft/server/TileEntityContainer.java @@ -17,7 +17,7 @@ public abstract class TileEntityContainer extends TileEntity implements IInvento diff --git a/Spigot-Server-Patches/0379-Chunk-debug-command.patch b/Spigot-Server-Patches/0379-Chunk-debug-command.patch index 217963110..56fe035a2 100644 --- a/Spigot-Server-Patches/0379-Chunk-debug-command.patch +++ b/Spigot-Server-Patches/0379-Chunk-debug-command.patch @@ -1,4 +1,4 @@ -From 7f0f866dcc2328087c840fda7b35f9e3622b45ff Mon Sep 17 00:00:00 2001 +From eb45d133eb10487b47f530501f6bb699d999fa8f Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Sat, 1 Jun 2019 13:00:55 -0700 Subject: [PATCH] Chunk debug command @@ -32,7 +32,7 @@ https://bugs.mojang.com/browse/MC-141484?focusedCommentId=528273&page=com.atlass https://bugs.mojang.com/browse/MC-141484?focusedCommentId=528577&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-528577 diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java -index d704fc79c..09efbf725 100644 +index d704fc79c0..09efbf7250 100644 --- a/src/main/java/com/destroystokyo/paper/PaperCommand.java +++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java @@ -28,14 +28,14 @@ public class PaperCommand extends Command { @@ -185,7 +185,7 @@ index d704fc79c..09efbf725 100644 * Ported from MinecraftForge - author: LexManos - License: LGPLv2.1 */ diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index 71db32bdd..b18d07b76 100644 +index 71db32bddd..b18d07b760 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -22,7 +22,7 @@ import org.apache.logging.log4j.Logger; @@ -198,7 +198,7 @@ index 71db32bdd..b18d07b76 100644 public final ChunkGenerator chunkGenerator; private final WorldServer world; diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java -index 3a482466e..b6aeca05f 100644 +index bfddeb7cdb..047a0c6591 100644 --- a/src/main/java/net/minecraft/server/MCUtil.java +++ b/src/main/java/net/minecraft/server/MCUtil.java @@ -4,7 +4,13 @@ import com.destroystokyo.paper.block.TargetBlockInfo; @@ -227,7 +227,7 @@ index 3a482466e..b6aeca05f 100644 import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; -@@ -424,4 +434,170 @@ public final class MCUtil { +@@ -422,4 +432,170 @@ public final class MCUtil { return null; } @@ -399,7 +399,7 @@ index 3a482466e..b6aeca05f 100644 + } } diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java -index c4bbee7d6..b6d387006 100644 +index c4bbee7d6a..b6d3870063 100644 --- a/src/main/java/net/minecraft/server/PlayerChunk.java +++ b/src/main/java/net/minecraft/server/PlayerChunk.java @@ -26,7 +26,7 @@ public class PlayerChunk { @@ -412,7 +412,7 @@ index c4bbee7d6..b6d387006 100644 private int dirtyCount; private int r; diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 8c6cd4cd6..7033d3a91 100644 +index 8c6cd4cd6e..7033d3a91f 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -58,7 +58,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -434,7 +434,7 @@ index 8c6cd4cd6..7033d3a91 100644 private final DefinedStructureManager definedStructureManager; private final File w; diff --git a/src/main/java/net/minecraft/server/Ticket.java b/src/main/java/net/minecraft/server/Ticket.java -index 77bb6b092..7a8397815 100644 +index 77bb6b092a..7a8397815a 100644 --- a/src/main/java/net/minecraft/server/Ticket.java +++ b/src/main/java/net/minecraft/server/Ticket.java @@ -6,8 +6,8 @@ public final class Ticket implements Comparable> { diff --git a/Spigot-Server-Patches/0392-Asynchronous-chunk-IO-and-loading.patch b/Spigot-Server-Patches/0392-Asynchronous-chunk-IO-and-loading.patch index 172bbdfb4..16867ee74 100644 --- a/Spigot-Server-Patches/0392-Asynchronous-chunk-IO-and-loading.patch +++ b/Spigot-Server-Patches/0392-Asynchronous-chunk-IO-and-loading.patch @@ -1,4 +1,4 @@ -From 9230461b781103d626bf071caa58adf12290f385 Mon Sep 17 00:00:00 2001 +From 5c3c318bcec00aae58e6b5e4585b50eb4d0b281d Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Sat, 13 Jul 2019 09:23:10 -0700 Subject: [PATCH] Asynchronous chunk IO and loading @@ -121,7 +121,7 @@ tasks required to be executed by the chunk load task (i.e lighting and some poi tasks). diff --git a/src/main/java/co/aikar/timings/WorldTimingsHandler.java b/src/main/java/co/aikar/timings/WorldTimingsHandler.java -index e41083f14..8a3f30c36 100644 +index e41083f14c..8a3f30c36f 100644 --- a/src/main/java/co/aikar/timings/WorldTimingsHandler.java +++ b/src/main/java/co/aikar/timings/WorldTimingsHandler.java @@ -62,6 +62,17 @@ public class WorldTimingsHandler { @@ -161,7 +161,7 @@ index e41083f14..8a3f30c36 100644 public static Timing getTickList(WorldServer worldserver, String timingsType) { diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java -index 546a1cfe0..1d7d1ffbf 100644 +index 546a1cfe0a..1d7d1ffbf7 100644 --- a/src/main/java/com/destroystokyo/paper/PaperConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java @@ -1,5 +1,6 @@ @@ -237,7 +237,7 @@ index 546a1cfe0..1d7d1ffbf 100644 + } } diff --git a/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java b/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java -index 23626bef3..1edcecd2e 100644 +index 23626bef3a..1edcecd2ee 100644 --- a/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java +++ b/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java @@ -9,6 +9,7 @@ import java.util.concurrent.Executors; @@ -318,7 +318,7 @@ index 23626bef3..1edcecd2e 100644 diff --git a/src/main/java/com/destroystokyo/paper/io/IOUtil.java b/src/main/java/com/destroystokyo/paper/io/IOUtil.java new file mode 100644 -index 000000000..5af0ac3d9 +index 0000000000..5af0ac3d9e --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/IOUtil.java @@ -0,0 +1,62 @@ @@ -386,7 +386,7 @@ index 000000000..5af0ac3d9 +} diff --git a/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java b/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java new file mode 100644 -index 000000000..4f10a8311 +index 0000000000..4f10a8311e --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java @@ -0,0 +1,661 @@ @@ -1053,7 +1053,7 @@ index 000000000..4f10a8311 +} diff --git a/src/main/java/com/destroystokyo/paper/io/PrioritizedTaskQueue.java b/src/main/java/com/destroystokyo/paper/io/PrioritizedTaskQueue.java new file mode 100644 -index 000000000..78bd238f4 +index 0000000000..78bd238f4c --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/PrioritizedTaskQueue.java @@ -0,0 +1,276 @@ @@ -1335,7 +1335,7 @@ index 000000000..78bd238f4 +} diff --git a/src/main/java/com/destroystokyo/paper/io/QueueExecutorThread.java b/src/main/java/com/destroystokyo/paper/io/QueueExecutorThread.java new file mode 100644 -index 000000000..ee906b594 +index 0000000000..ee906b594b --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/QueueExecutorThread.java @@ -0,0 +1,241 @@ @@ -1582,7 +1582,7 @@ index 000000000..ee906b594 +} diff --git a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkLoadTask.java b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkLoadTask.java new file mode 100644 -index 000000000..305da4786 +index 0000000000..305da47868 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkLoadTask.java @@ -0,0 +1,149 @@ @@ -1737,7 +1737,7 @@ index 000000000..305da4786 +} diff --git a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkSaveTask.java b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkSaveTask.java new file mode 100644 -index 000000000..60312b85f +index 0000000000..60312b85f9 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkSaveTask.java @@ -0,0 +1,112 @@ @@ -1855,7 +1855,7 @@ index 000000000..60312b85f +} diff --git a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTask.java b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTask.java new file mode 100644 -index 000000000..1dfa8abfd +index 0000000000..1dfa8abfd8 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTask.java @@ -0,0 +1,40 @@ @@ -1901,7 +1901,7 @@ index 000000000..1dfa8abfd +} diff --git a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java new file mode 100644 -index 000000000..715a2dd8d +index 0000000000..715a2dd8d2 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java @@ -0,0 +1,455 @@ @@ -2361,7 +2361,7 @@ index 000000000..715a2dd8d + +} diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index 21498da29..eb9bf1516 100644 +index 21498da29c..eb9bf1516a 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -218,11 +218,137 @@ public class ChunkProviderServer extends IChunkProvider { @@ -2531,7 +2531,7 @@ index 21498da29..eb9bf1516 100644 } finally { playerChunkMap.callbackExecutor.run(); diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java -index a950ad801..26f1a4b09 100644 +index a950ad801d..26f1a4b095 100644 --- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java +++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java @@ -6,6 +6,7 @@ import it.unimi.dsi.fastutil.longs.LongOpenHashSet; @@ -2800,7 +2800,7 @@ index a950ad801..26f1a4b09 100644 nbttagcompound1.set("PostProcessing", a(ichunkaccess.l())); diff --git a/src/main/java/net/minecraft/server/ChunkStatus.java b/src/main/java/net/minecraft/server/ChunkStatus.java -index 134a4f0b7..88f167461 100644 +index 134a4f0b7d..88f1674616 100644 --- a/src/main/java/net/minecraft/server/ChunkStatus.java +++ b/src/main/java/net/minecraft/server/ChunkStatus.java @@ -153,6 +153,7 @@ public class ChunkStatus { @@ -2812,7 +2812,7 @@ index 134a4f0b7..88f167461 100644 return ChunkStatus.r.getInt(chunkstatus.c()); } diff --git a/src/main/java/net/minecraft/server/IAsyncTaskHandler.java b/src/main/java/net/minecraft/server/IAsyncTaskHandler.java -index 7e5ece9d5..cfe43e882 100644 +index 7e5ece9d50..cfe43e882e 100644 --- a/src/main/java/net/minecraft/server/IAsyncTaskHandler.java +++ b/src/main/java/net/minecraft/server/IAsyncTaskHandler.java @@ -91,7 +91,7 @@ public abstract class IAsyncTaskHandler implements Mailbox { @@ -3844,7 +3844,7 @@ index 1d1b267f3..4b87ca2ec 100644 public static TicketType a(String s, Comparator comparator) { return new TicketType<>(s, comparator, 0L); diff --git a/src/main/java/net/minecraft/server/VillagePlace.java b/src/main/java/net/minecraft/server/VillagePlace.java -index c999f8c9b..b59ef1a63 100644 +index c999f8c9bf..b59ef1a633 100644 --- a/src/main/java/net/minecraft/server/VillagePlace.java +++ b/src/main/java/net/minecraft/server/VillagePlace.java @@ -24,8 +24,16 @@ public class VillagePlace extends RegionFileSection { @@ -3933,7 +3933,7 @@ index c999f8c9b..b59ef1a63 100644 HAS_SPACE(VillagePlaceRecord::d), IS_OCCUPIED(VillagePlaceRecord::e), ANY((villageplacerecord) -> { diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 27dcc2528..6506daeec 100644 +index 27dcc25284..6506daeecd 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -82,6 +82,79 @@ public class WorldServer extends World { @@ -4026,7 +4026,7 @@ index 27dcc2528..6506daeec 100644 // CraftBukkit start diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 7ae9f8ab5..defee6722 100644 +index 7ae9f8ab56..defee67226 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -550,22 +550,23 @@ public class CraftWorld implements World { @@ -4088,7 +4088,7 @@ index 7ae9f8ab5..defee6722 100644 @Override public int getViewDistance() { diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java -index 07936eeba..5bdcdcf9e 100644 +index 07936eeba2..5bdcdcf9e8 100644 --- a/src/main/java/org/spigotmc/WatchdogThread.java +++ b/src/main/java/org/spigotmc/WatchdogThread.java @@ -6,6 +6,7 @@ import java.lang.management.ThreadInfo; diff --git a/Spigot-Server-Patches/0441-Make-the-GUI-graph-fancier.patch b/Spigot-Server-Patches/0441-Make-the-GUI-graph-fancier.patch index d64b770b1..067bdfa8f 100644 --- a/Spigot-Server-Patches/0441-Make-the-GUI-graph-fancier.patch +++ b/Spigot-Server-Patches/0441-Make-the-GUI-graph-fancier.patch @@ -1,4 +1,4 @@ -From acb8b4829d3f5080de2aaa913180729945bf140d Mon Sep 17 00:00:00 2001 +From 088a3692ecc5649e56ec9136532dd3eed4c97c73 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 2 Feb 2020 04:00:40 -0600 Subject: [PATCH] Make the GUI graph fancier @@ -6,7 +6,7 @@ Subject: [PATCH] Make the GUI graph fancier diff --git a/src/main/java/com/destroystokyo/paper/gui/GraphColor.java b/src/main/java/com/destroystokyo/paper/gui/GraphColor.java new file mode 100644 -index 000000000..a4e641fdc +index 0000000000..a4e641fdcc --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/gui/GraphColor.java @@ -0,0 +1,44 @@ @@ -56,7 +56,7 @@ index 000000000..a4e641fdc +} diff --git a/src/main/java/com/destroystokyo/paper/gui/GraphData.java b/src/main/java/com/destroystokyo/paper/gui/GraphData.java new file mode 100644 -index 000000000..186fc7229 +index 0000000000..186fc72296 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/gui/GraphData.java @@ -0,0 +1,47 @@ @@ -109,7 +109,7 @@ index 000000000..186fc7229 +} diff --git a/src/main/java/com/destroystokyo/paper/gui/GuiStatsComponent.java b/src/main/java/com/destroystokyo/paper/gui/GuiStatsComponent.java new file mode 100644 -index 000000000..0f29ad583 +index 0000000000..0f29ad583e --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/gui/GuiStatsComponent.java @@ -0,0 +1,41 @@ @@ -156,7 +156,7 @@ index 000000000..0f29ad583 +} diff --git a/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java b/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java new file mode 100644 -index 000000000..e463a86a6 +index 0000000000..e463a86a6a --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java @@ -0,0 +1,74 @@ @@ -236,7 +236,7 @@ index 000000000..e463a86a6 +} diff --git a/src/main/java/com/destroystokyo/paper/gui/RAMGraph.java b/src/main/java/com/destroystokyo/paper/gui/RAMGraph.java new file mode 100644 -index 000000000..c3e54da4a +index 0000000000..c3e54da4ab --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/gui/RAMGraph.java @@ -0,0 +1,144 @@ @@ -385,7 +385,7 @@ index 000000000..c3e54da4a + } +} diff --git a/src/main/java/net/minecraft/server/GuiStatsComponent.java b/src/main/java/net/minecraft/server/GuiStatsComponent.java -index c21db8e6b..7b6e93525 100644 +index c21db8e6b7..7b6e935257 100644 --- a/src/main/java/net/minecraft/server/GuiStatsComponent.java +++ b/src/main/java/net/minecraft/server/GuiStatsComponent.java @@ -12,7 +12,7 @@ import javax.swing.Timer; @@ -398,7 +398,7 @@ index c21db8e6b..7b6e93525 100644 }); private final int[] b = new int[256]; diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 346664cee..c9deaffc4 100644 +index 346664cee0..c9deaffc4a 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -105,7 +105,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant Date: Fri, 21 Feb 2020 18:44:28 +0000 Subject: [PATCH] Backport fix for MC-167561 diff --git a/src/main/java/net/minecraft/server/EntityWolf.java b/src/main/java/net/minecraft/server/EntityWolf.java -index db15d5e0a..eec1e26b6 100644 +index db15d5e0a2..eec1e26b6e 100644 --- a/src/main/java/net/minecraft/server/EntityWolf.java +++ b/src/main/java/net/minecraft/server/EntityWolf.java @@ -296,7 +296,14 @@ public class EntityWolf extends EntityTameableAnimal { diff --git a/Spigot-Server-Patches/0443-add-hand-to-BlockMultiPlaceEvent.patch b/Spigot-Server-Patches/0443-add-hand-to-BlockMultiPlaceEvent.patch index a9e507598..26a4c01ce 100644 --- a/Spigot-Server-Patches/0443-add-hand-to-BlockMultiPlaceEvent.patch +++ b/Spigot-Server-Patches/0443-add-hand-to-BlockMultiPlaceEvent.patch @@ -1,11 +1,11 @@ -From 883d0f9fd8dd2ef2e16af07723acd3c5b3295419 Mon Sep 17 00:00:00 2001 +From 09dc724042f30bfc000ce10de47de57648cf0429 Mon Sep 17 00:00:00 2001 From: Trigary Date: Sun, 1 Mar 2020 22:43:24 +0100 Subject: [PATCH] add hand to BlockMultiPlaceEvent diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 39ce40bd5..1f5d15bb4 100644 +index 39ce40bd58..1f5d15bb49 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -296,13 +296,18 @@ public class CraftEventFactory { diff --git a/Spigot-Server-Patches/0444-Prevent-teleporting-dead-entities.patch b/Spigot-Server-Patches/0444-Prevent-teleporting-dead-entities.patch index de02bfb41..3314263e0 100644 --- a/Spigot-Server-Patches/0444-Prevent-teleporting-dead-entities.patch +++ b/Spigot-Server-Patches/0444-Prevent-teleporting-dead-entities.patch @@ -1,11 +1,11 @@ -From f0461b91e85db450812eac347d37c71d95d29738 Mon Sep 17 00:00:00 2001 +From dc82016f09e94d03fac768d35e0461fd5c09685b Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Tue, 3 Mar 2020 05:26:40 +0000 Subject: [PATCH] Prevent teleporting dead entities diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -index 108377d76..7929fcc80 100644 +index 108377d76e..7929fcc800 100644 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java @@ -1209,6 +1209,10 @@ public class PlayerConnection implements PacketListenerPlayIn { diff --git a/Spigot-Server-Patches/0445-Validate-tripwire-hook-placement-before-update.patch b/Spigot-Server-Patches/0445-Validate-tripwire-hook-placement-before-update.patch index 174d45e20..8a59c98ea 100644 --- a/Spigot-Server-Patches/0445-Validate-tripwire-hook-placement-before-update.patch +++ b/Spigot-Server-Patches/0445-Validate-tripwire-hook-placement-before-update.patch @@ -1,11 +1,11 @@ -From 9bdb7295ce6b3b2376502e001978df49ac31c7de Mon Sep 17 00:00:00 2001 +From b06f9114c5701daac5b6024b995439564d891f16 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Sat, 7 Mar 2020 00:07:51 +0000 Subject: [PATCH] Validate tripwire hook placement before update diff --git a/src/main/java/net/minecraft/server/BlockTripwireHook.java b/src/main/java/net/minecraft/server/BlockTripwireHook.java -index 1b9d889af..a5e6e94fe 100644 +index 1b9d889af6..a5e6e94fe0 100644 --- a/src/main/java/net/minecraft/server/BlockTripwireHook.java +++ b/src/main/java/net/minecraft/server/BlockTripwireHook.java @@ -149,6 +149,7 @@ public class BlockTripwireHook extends Block { diff --git a/Spigot-Server-Patches/0446-Add-option-to-allow-iron-golems-to-spawn-in-air.patch b/Spigot-Server-Patches/0446-Add-option-to-allow-iron-golems-to-spawn-in-air.patch index 395058124..9fbd0f93f 100644 --- a/Spigot-Server-Patches/0446-Add-option-to-allow-iron-golems-to-spawn-in-air.patch +++ b/Spigot-Server-Patches/0446-Add-option-to-allow-iron-golems-to-spawn-in-air.patch @@ -1,11 +1,11 @@ -From eb930f97967edb19d0a494c7ed443f7bb76b882e Mon Sep 17 00:00:00 2001 +From 932a3ee4d342eda39ded873838fbd4325d91971e Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sat, 13 Apr 2019 16:50:58 -0500 Subject: [PATCH] Add option to allow iron golems to spawn in air diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index 7d408542e..c7cde1d0a 100644 +index 7d408542e7..c7cde1d0a0 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java @@ -415,6 +415,11 @@ public class PaperWorldConfig { @@ -21,7 +21,7 @@ index 7d408542e..c7cde1d0a 100644 private void bedSearchRadius() { bedSearchRadius = getInt("bed-search-radius", 1); diff --git a/src/main/java/net/minecraft/server/EntityIronGolem.java b/src/main/java/net/minecraft/server/EntityIronGolem.java -index 2f764776b..7f6a56776 100644 +index 2f764776b2..7f6a567760 100644 --- a/src/main/java/net/minecraft/server/EntityIronGolem.java +++ b/src/main/java/net/minecraft/server/EntityIronGolem.java @@ -221,7 +221,7 @@ public class EntityIronGolem extends EntityGolem { diff --git a/Spigot-Server-Patches/0447-Configurable-chance-of-villager-zombie-infection.patch b/Spigot-Server-Patches/0447-Configurable-chance-of-villager-zombie-infection.patch index 8aab0ac16..304a78fe8 100644 --- a/Spigot-Server-Patches/0447-Configurable-chance-of-villager-zombie-infection.patch +++ b/Spigot-Server-Patches/0447-Configurable-chance-of-villager-zombie-infection.patch @@ -1,4 +1,4 @@ -From d572eec96c1bbcfd76021524de3524527650cc46 Mon Sep 17 00:00:00 2001 +From fe2815aff32618c12cccab8686133b7d974eff39 Mon Sep 17 00:00:00 2001 From: Zero Date: Sat, 22 Feb 2020 16:10:31 -0500 Subject: [PATCH] Configurable chance of villager zombie infection @@ -8,7 +8,7 @@ This allows you to solve an issue in vanilla behavior where: * On normal difficulty they will have a 50% of getting infected or dying. diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index c7cde1d0a..7ca67a4aa 100644 +index c7cde1d0a0..7ca67a4aa5 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java @@ -663,4 +663,9 @@ public class PaperWorldConfig { @@ -22,7 +22,7 @@ index c7cde1d0a..7ca67a4aa 100644 + } } diff --git a/src/main/java/net/minecraft/server/EntityZombie.java b/src/main/java/net/minecraft/server/EntityZombie.java -index 8635d4f40..07ebc1d81 100644 +index 8635d4f40c..07ebc1d816 100644 --- a/src/main/java/net/minecraft/server/EntityZombie.java +++ b/src/main/java/net/minecraft/server/EntityZombie.java @@ -455,10 +455,14 @@ public class EntityZombie extends EntityMonster { diff --git a/Spigot-Server-Patches/0448-Call-BlockRedstoneEvent-for-fence-gates.patch b/Spigot-Server-Patches/0448-Call-BlockRedstoneEvent-for-fence-gates.patch index 1a9e83d68..3c121433c 100644 --- a/Spigot-Server-Patches/0448-Call-BlockRedstoneEvent-for-fence-gates.patch +++ b/Spigot-Server-Patches/0448-Call-BlockRedstoneEvent-for-fence-gates.patch @@ -1,11 +1,11 @@ -From 67d2b841f8deca1a3a786cdbedc4ba4ffdaee08c Mon Sep 17 00:00:00 2001 +From 2683d17019e4a67b114868db084a31c5673a436a Mon Sep 17 00:00:00 2001 From: Jan Boerman Date: Sat, 14 Mar 2020 14:17:35 +0100 Subject: [PATCH] Call BlockRedstoneEvent for fence gates diff --git a/src/main/java/net/minecraft/server/BlockFenceGate.java b/src/main/java/net/minecraft/server/BlockFenceGate.java -index 432e47bb9..583eb6883 100644 +index 432e47bb99..583eb68837 100644 --- a/src/main/java/net/minecraft/server/BlockFenceGate.java +++ b/src/main/java/net/minecraft/server/BlockFenceGate.java @@ -103,6 +103,17 @@ public class BlockFenceGate extends BlockFacingHorizontal { diff --git a/Spigot-Server-Patches/0449-Optimise-TickListServer-by-rewriting-it.patch b/Spigot-Server-Patches/0449-Optimise-TickListServer-by-rewriting-it.patch new file mode 100644 index 000000000..738ea9134 --- /dev/null +++ b/Spigot-Server-Patches/0449-Optimise-TickListServer-by-rewriting-it.patch @@ -0,0 +1,1152 @@ +From 72eedab01e66ef317741baa2e60d627d34305ef3 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Fri, 14 Feb 2020 01:24:39 -0800 +Subject: [PATCH] Optimise TickListServer by rewriting it + +In my profiling TickListServer showed up as +~10% for saving chunks and ~5% for the scheduling +of items on a server with ~90 players at +view distance = 5. Most of the performance +loss is unneccessary. + +TickListServer has numerous performance issues: + 1. Handling scheduled items is O(nlogn) + 2. Getting scheduled items for a chunk is O(n), + with n being the the number of scheduled items + for all chunks (hits saving very hard) + 3. Checking if an item is scheduled for the current tick is O(n), + with n being the number of items scheduled for current tick + 4. Items not in ticking chunks are churned in the scheduler + +The biggest issues are 4 & 2. + +We solve 1 by splitting up scheduled items into short and long scheduled, +where we expect the vast majority of our entries to be in the short scheduled +set. Handling short scheduled items is O(n) due to how the comparison +process is reduced to mapping. See TickListServerInterval. However, +this isn't memory-efficient - which is why long scheduled exists. +Long scheduled is handled the same as TickListServer. + +2 is solved by mapping what entries are in what chunks. + +3 is solved by mapping what blocks have what scheduled for them. + +4 is solved by moving the items that are not in ticking chunks +into a map of entries for that chunk. Once the chunk is moved +to ticking, the items are re-scheduled. + +diff --git a/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java b/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java +new file mode 100644 +index 0000000000..666f49fe96 +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java +@@ -0,0 +1,602 @@ ++package com.destroystokyo.paper.server.ticklist; ++ ++import net.minecraft.server.MCUtil; ++import net.minecraft.server.MinecraftServer; ++import it.unimi.dsi.fastutil.longs.Long2ObjectMap; ++import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; ++import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet; ++import net.minecraft.server.BaseBlockPosition; ++import net.minecraft.server.BlockPosition; ++import net.minecraft.server.ChunkCoordIntPair; ++import net.minecraft.server.ChunkProviderServer; ++import net.minecraft.server.CrashReport; ++import net.minecraft.server.CrashReportSystemDetails; ++import net.minecraft.server.IBlockData; ++import net.minecraft.server.MinecraftKey; ++import net.minecraft.server.NBTTagList; ++import net.minecraft.server.NextTickListEntry; ++import net.minecraft.server.ReportedException; ++import net.minecraft.server.StructureBoundingBox; ++import net.minecraft.server.TickListPriority; ++import net.minecraft.server.TickListServer; ++import net.minecraft.server.WorldServer; ++import java.util.ArrayDeque; ++import java.util.ArrayList; ++import java.util.Collections; ++import java.util.Comparator; ++import java.util.Iterator; ++import java.util.List; ++import java.util.function.Consumer; ++import java.util.function.Function; ++import java.util.function.Predicate; ++import java.util.stream.Stream; ++ ++public final class PaperTickList extends TickListServer { // extend to avoid breaking ABI ++ ++ // in the order the state is expected to change (mostly) ++ public static final int STATE_UNSCHEDULED = 1 << 0; ++ public static final int STATE_SCHEDULED = 1 << 1; // scheduled for some tick ++ public static final int STATE_PENDING_TICK = 1 << 2; // for this tick ++ public static final int STATE_TICKING = 1 << 3; ++ public static final int STATE_TICKED = 1 << 4; // after this, it gets thrown back to unscheduled ++ public static final int STATE_CANCELLED_TICK = 1 << 5; // still gets moved to unscheduled after tick ++ ++ private static final int SHORT_SCHEDULE_TICK_THRESHOLD = 20 * 5 + 1; // 5 seconds ++ ++ private final WorldServer world; ++ private final Predicate excludeFromScheduling; ++ private final Function getMinecraftKeyFrom; ++ private final Function getObjectFronMinecraftKey; ++ private final Consumer> tickFunction; ++ ++ private final co.aikar.timings.Timing timingCleanup; // Paper ++ private final co.aikar.timings.Timing timingTicking; // Paper ++ private final co.aikar.timings.Timing timingFinished; ++ ++ // note: remove ops / add ops suck on fastutil, a chained hashtable implementation would work better, but Long... ++ // try to alleviate with a very small load factor ++ private final Long2ObjectOpenHashMap>> entriesByBlock = new Long2ObjectOpenHashMap<>(1024, 0.25f); ++ private final Long2ObjectOpenHashMap>> entriesByChunk = new Long2ObjectOpenHashMap<>(1024, 0.25f); ++ private final Long2ObjectOpenHashMap>> pendingChunkTickLoad = new Long2ObjectOpenHashMap<>(1024, 0.5f); ++ ++ // fastutil has O(1) first/last while TreeMap/TreeSet are log(n) ++ private final ObjectRBTreeSet> longScheduled = new ObjectRBTreeSet<>(TickListServerInterval.ENTRY_COMPARATOR); ++ ++ private final ArrayDeque> toTickThisTick = new ArrayDeque<>(); ++ ++ private final TickListServerInterval[] shortScheduled = new TickListServerInterval[SHORT_SCHEDULE_TICK_THRESHOLD]; ++ { ++ for (int i = 0, len = this.shortScheduled.length; i < len; ++i) { ++ this.shortScheduled[i] = new TickListServerInterval<>(); ++ } ++ } ++ private int shortScheduledIndex; ++ ++ private long nextTick; ++ ++ // assume index < length ++ private static int getWrappedIndex(final int start, final int length, final int index) { ++ final int next = start + index; ++ return next < length ? next : next - length; ++ } ++ ++ private static int getNextIndex(final int curr, final int length) { ++ final int next = curr + 1; ++ return next < length ? next : 0; ++ } ++ ++ public PaperTickList(final WorldServer world, final Predicate excludeFromScheduling, final Function getMinecraftKeyFrom, ++ final Function getObjectFronMinecraftKey, final Consumer> tickFunction, final String timingsType) { ++ super(world, excludeFromScheduling, getMinecraftKeyFrom, getObjectFronMinecraftKey, tickFunction, timingsType); ++ this.world = world; ++ this.excludeFromScheduling = excludeFromScheduling; ++ this.getMinecraftKeyFrom = getMinecraftKeyFrom; ++ this.getObjectFronMinecraftKey = getObjectFronMinecraftKey; ++ this.tickFunction = tickFunction; ++ this.timingCleanup = co.aikar.timings.WorldTimingsHandler.getTickList(world, timingsType + " - Cleanup"); // Paper ++ this.timingTicking = co.aikar.timings.WorldTimingsHandler.getTickList(world, timingsType + " - Ticking"); // Paper ++ this.timingFinished = co.aikar.timings.WorldTimingsHandler.getTickList(world, timingsType + " - Finish"); ++ this.nextTick = this.world.getTime(); ++ } ++ ++ private void queueEntryForTick(final NextTickListEntry entry, final ChunkProviderServer chunkProvider) { ++ if (entry.tickState == STATE_SCHEDULED) { ++ if (chunkProvider.isTickingReadyMainThread(entry.getPosition())) { ++ this.toTickThisTick.add(entry); ++ entry.tickState = STATE_PENDING_TICK; ++ } else { ++ // we dump them to a map to avoid constantly re-scheduling them ++ this.addToNotTickingReady(entry); ++ } ++ } ++ } ++ ++ private void addToNotTickingReady(final NextTickListEntry entry) { ++ this.pendingChunkTickLoad.computeIfAbsent(MCUtil.getCoordinateKey(entry.getPosition()), (long keyInMap) -> { ++ return new ArrayList<>(); ++ }).add(entry); ++ } ++ ++ private void addToSchedule(final NextTickListEntry entry) { ++ long delay = entry.getTargetTick() - this.nextTick; ++ if (delay < SHORT_SCHEDULE_TICK_THRESHOLD) { ++ if (delay < 0) { ++ // longScheduled orders by tick time, short scheduled does not ++ this.longScheduled.add(entry); ++ } else { ++ this.shortScheduled[getWrappedIndex(this.shortScheduledIndex, SHORT_SCHEDULE_TICK_THRESHOLD, (int)delay)].addEntryLast(entry); ++ } ++ } else { ++ this.longScheduled.add(entry); ++ } ++ } ++ ++ private void removeEntry(final NextTickListEntry entry) { ++ entry.tickState = STATE_CANCELLED_TICK; ++ // short/long scheduled will skip the entry ++ ++ final BlockPosition pos = entry.getPosition(); ++ final long blockKey = MCUtil.getBlockKey(pos); ++ ++ final ArrayList> currentEntries = this.entriesByBlock.get(blockKey); ++ ++ if (currentEntries.size() == 1) { ++ // it should contain our entry ++ this.entriesByBlock.remove(blockKey); ++ } else { ++ // it's more likely that this entry is at the start of the list than the end ++ for (int i = 0, len = currentEntries.size(); i < len; ++i) { ++ final NextTickListEntry currentEntry = currentEntries.get(i); ++ if (currentEntry == entry) { ++ currentEntries.remove(i); ++ break; ++ } ++ } ++ } ++ ++ final long chunkKey = MCUtil.getCoordinateKey(entry.getPosition()); ++ ++ ObjectRBTreeSet> set = this.entriesByChunk.get(chunkKey); ++ ++ set.remove(entry); ++ ++ if (set.isEmpty()) { ++ this.entriesByChunk.remove(chunkKey); ++ } ++ ++ ArrayList> pendingTickingLoad = this.pendingChunkTickLoad.get(chunkKey); ++ ++ if (pendingTickingLoad != null) { ++ for (int i = 0, len = pendingTickingLoad.size(); i < len; ++i) { ++ if (pendingTickingLoad.get(i) == entry) { ++ pendingTickingLoad.remove(i); ++ break; ++ } ++ } ++ ++ if (pendingTickingLoad.isEmpty()) { ++ this.pendingChunkTickLoad.remove(chunkKey); ++ } ++ } ++ } ++ ++ public void onChunkSetTicking(final int chunkX, final int chunkZ) { ++ final ArrayList> pending = this.pendingChunkTickLoad.remove(MCUtil.getCoordinateKey(chunkX, chunkZ)); ++ if (pending == null) { ++ return; ++ } ++ ++ for (int i = 0, size = pending.size(); i < size; ++i) { ++ final NextTickListEntry entry = pending.get(i); ++ // already in all the relevant reference maps, just need to add to longScheduled or shortScheduled ++ this.addToSchedule(entry); ++ } ++ } ++ ++ private void prepare() { ++ final long currentTick = this.world.getTime(); ++ ++ final ChunkProviderServer chunkProvider = this.world.getChunkProvider(); ++ ++ // here we setup what's going to tick ++ ++ // we don't remove items from shortScheduled (but do from longScheduled) because they're cleared at the end of ++ // this tick ++ if (this.longScheduled.isEmpty() || this.longScheduled.first().getTargetTick() > currentTick) { ++ // nothing in longScheduled to worry about ++ final TickListServerInterval interval = this.shortScheduled[this.shortScheduledIndex]; ++ for (int i = 0, len = interval.byPriority.length; i < len; ++i) { ++ for (final Iterator> iterator = interval.byPriority[i].iterator(); iterator.hasNext();) { ++ this.queueEntryForTick(iterator.next(), chunkProvider); ++ } ++ } ++ } else { ++ final TickListServerInterval interval = this.shortScheduled[this.shortScheduledIndex]; ++ ++ // combine interval and longScheduled, keeping order ++ final Comparator> comparator = (Comparator)TickListServerInterval.ENTRY_COMPARATOR; ++ final Iterator> longScheduledIterator = this.longScheduled.iterator(); ++ NextTickListEntry longCurrent = longScheduledIterator.next(); ++ ++ for (int i = 0, len = interval.byPriority.length; i < len; ++i) { ++ for (final Iterator> iterator = interval.byPriority[i].iterator(); iterator.hasNext();) { ++ final NextTickListEntry shortCurrent = iterator.next(); ++ if (longCurrent != null) { ++ // drain longCurrent until we can add shortCurrent ++ while (comparator.compare(longCurrent, shortCurrent) <= 0) { ++ this.queueEntryForTick(longCurrent, chunkProvider); ++ longScheduledIterator.remove(); ++ if (longScheduledIterator.hasNext()) { ++ longCurrent = longScheduledIterator.next(); ++ if (longCurrent.getTargetTick() > currentTick) { ++ longCurrent = null; ++ break; ++ } ++ } else { ++ longCurrent = null; ++ break; ++ } ++ } ++ } ++ this.queueEntryForTick(shortCurrent, chunkProvider); ++ } ++ } ++ ++ // add remaining from long scheduled ++ for (;;) { ++ if (longCurrent == null || longCurrent.getTargetTick() > currentTick) { ++ break; ++ } ++ longScheduledIterator.remove(); ++ this.queueEntryForTick(longCurrent, chunkProvider); ++ ++ if (longScheduledIterator.hasNext()) { ++ longCurrent = longScheduledIterator.next(); ++ } else { ++ break; ++ } ++ } ++ } ++ } ++ ++ @Override ++ public void tick() { ++ final ChunkProviderServer chunkProvider = this.world.getChunkProvider(); ++ ++ this.world.getMethodProfiler().enter("cleaning"); ++ this.timingCleanup.startTiming(); ++ ++ this.prepare(); ++ ++ // this must be done here in case something schedules in the tick code ++ this.shortScheduled[this.shortScheduledIndex].clear(); ++ this.shortScheduledIndex = getNextIndex(this.shortScheduledIndex, SHORT_SCHEDULE_TICK_THRESHOLD); ++ this.nextTick = this.world.getTime() + 1; ++ ++ this.timingCleanup.stopTiming(); ++ this.world.getMethodProfiler().exitEnter("ticking"); ++ this.timingTicking.startTiming(); ++ ++ for (final NextTickListEntry toTick : this.toTickThisTick) { ++ if (toTick.tickState != STATE_PENDING_TICK) { ++ // onTickEnd gets called at end of tick ++ continue; ++ } ++ try { ++ if (chunkProvider.isTickingReadyMainThread(toTick.getPosition())) { ++ toTick.tickState = STATE_TICKING; ++ this.tickFunction.accept(toTick); ++ toTick.tickState = STATE_TICKED; ++ } else { ++ // re-schedule eventually ++ toTick.tickState = STATE_SCHEDULED; ++ this.addToNotTickingReady(toTick); ++ } ++ } catch (final Throwable thr) { ++ // start copy from TickListServer // TODO check on update ++ CrashReport crashreport = CrashReport.a(thr, "Exception while ticking"); ++ CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Block being ticked"); ++ ++ CrashReportSystemDetails.a(crashreportsystemdetails, toTick.getPosition(), (IBlockData) null); ++ throw new ReportedException(crashreport); ++ // end copy from TickListServer ++ } ++ } ++ ++ this.timingTicking.stopTiming(); ++ this.world.getMethodProfiler().exit(); ++ this.timingFinished.startTiming(); ++ ++ // finished ticking, actual cleanup time ++ for (int i = 0, len = this.toTickThisTick.size(); i < len; ++i) { ++ final NextTickListEntry entry = this.toTickThisTick.poll(); ++ if (entry.tickState != STATE_SCHEDULED) { ++ // some entries get re-scheduled due to their chunk not being loaded/at correct status, so do not ++ // call onTickEnd for them ++ this.onTickEnd(entry); ++ } ++ } ++ ++ this.timingFinished.stopTiming(); ++ } ++ ++ private void onTickEnd(final NextTickListEntry entry) { ++ entry.tickState = STATE_UNSCHEDULED; ++ ++ final BlockPosition pos = entry.getPosition(); ++ final long blockKey = MCUtil.getBlockKey(pos); ++ ++ final ArrayList> currentEntries = this.entriesByBlock.get(blockKey); ++ ++ if (currentEntries.size() == 1) { ++ // it should contain our entry ++ this.entriesByBlock.remove(blockKey); ++ } else { ++ // it's more likely that this entry is at the start of the list than the end ++ for (int i = 0, len = currentEntries.size(); i < len; ++i) { ++ final NextTickListEntry currentEntry = currentEntries.get(i); ++ if (currentEntry == entry) { ++ currentEntries.remove(i); ++ break; ++ } ++ } ++ } ++ ++ final long chunkKey = MCUtil.getCoordinateKey(entry.getPosition()); ++ ++ ObjectRBTreeSet> set = this.entriesByChunk.get(chunkKey); ++ ++ set.remove(entry); ++ ++ if (set.isEmpty()) { ++ this.entriesByChunk.remove(chunkKey); ++ } ++ ++ // already removed from longScheduled or shortScheduled ++ } ++ ++ @Override ++ public boolean isPendingTickThisTick(final BlockPosition blockposition, final T data) { ++ final ArrayList> entries = this.entriesByBlock.get(MCUtil.getBlockKey(blockposition)); ++ ++ if (entries == null) { ++ return false; ++ } ++ ++ for (int i = 0, size = entries.size(); i < size; ++i) { ++ final NextTickListEntry entry = entries.get(i); ++ if (entry.getData() == data && entry.tickState == STATE_PENDING_TICK) { ++ return true; ++ } ++ } ++ ++ return false; ++ } ++ ++ @Override ++ public boolean isScheduledForTick(final BlockPosition blockposition, final T data) { ++ final ArrayList> entries = this.entriesByBlock.get(MCUtil.getBlockKey(blockposition)); ++ ++ if (entries == null) { ++ return false; ++ } ++ ++ for (int i = 0, size = entries.size(); i < size; ++i) { ++ final NextTickListEntry entry = entries.get(i); ++ if (entry.getData() == data && entry.tickState == STATE_SCHEDULED) { ++ return true; ++ } ++ } ++ ++ return false; ++ } ++ ++ @Override ++ public void schedule(BlockPosition blockPosition, T t, int i, TickListPriority tickListPriority) { ++ this.schedule(blockPosition, t, i + this.world.getTime(), tickListPriority); ++ } ++ ++ public void schedule(final NextTickListEntry entry) { ++ this.schedule(entry.getPosition(), entry.getData(), entry.getTargetTick(), entry.getPriority()); ++ } ++ ++ public void schedule(final BlockPosition pos, final T data, final long targetTick, final TickListPriority priority) { ++ final NextTickListEntry entry = new NextTickListEntry<>(pos, data, targetTick, priority); ++ if (this.excludeFromScheduling.test(entry.getData())) { ++ return; ++ } ++ ++ final long blockKey = MCUtil.getBlockKey(pos); ++ ++ final ArrayList> currentEntries = this.entriesByBlock.computeIfAbsent(blockKey, (long keyInMap) -> new ArrayList<>(3)); ++ ++ if (currentEntries.isEmpty()) { ++ currentEntries.add(entry); ++ } else { ++ for (int i = 0, size = currentEntries.size(); i < size; ++i) { ++ final NextTickListEntry currentEntry = currentEntries.get(i); ++ ++ // entries are only blocked from scheduling if currentEntry.equals(toSchedule) && currentEntry is scheduled to tick (NOT including pending) ++ if (currentEntry.getData() == entry.getData() && currentEntry.tickState == STATE_SCHEDULED) { ++ // can't add ++ return; ++ } ++ } ++ currentEntries.add(entry); ++ } ++ ++ entry.tickState = STATE_SCHEDULED; ++ ++ this.entriesByChunk.computeIfAbsent(MCUtil.getCoordinateKey(entry.getPosition()), (final long keyInMap) -> { ++ return new ObjectRBTreeSet<>(TickListServerInterval.ENTRY_COMPARATOR); ++ }).add(entry); ++ ++ this.addToSchedule(entry); ++ } ++ ++ @Override ++ public void scheduleAll(final Stream> stream) { ++ this.scheduleAll(stream.iterator()); ++ } ++ public void scheduleAll(final Iterator> iterator) { ++ while (iterator.hasNext()) { ++ this.schedule(iterator.next()); ++ } ++ } ++ ++ // this is not the standard interception calculation, but it's the one vanilla uses ++ // i.e the y value is ignored? the x, z calc isn't correct? ++ // however for the copy op they use the correct intersection, after using this one of course... ++ private static boolean isBlockInSortof(final StructureBoundingBox boundingBox, final BlockPosition pos) { ++ return pos.getX() >= boundingBox.getMinX() && pos.getX() < boundingBox.getMaxX() && pos.getZ() >= boundingBox.getMinZ() && pos.getZ() < boundingBox.getMaxZ(); ++ } ++ ++ @Override ++ public List> getEntriesInBoundingBox(final StructureBoundingBox structureboundingbox, final boolean removeReturned, final boolean excludeTicked) { ++ if (structureboundingbox.getMinX() == structureboundingbox.getMaxX() || structureboundingbox.getMinZ() == structureboundingbox.getMaxZ()) { ++ return Collections.emptyList(); // vanilla behaviour, check isBlockInSortof above ++ } ++ ++ final int lowerChunkX = structureboundingbox.getMinX() >> 4; ++ final int upperChunkX = (structureboundingbox.getMaxX() - 1) >> 4; // subtract 1 since maxX is exclusive ++ final int lowerChunkZ = structureboundingbox.getMinZ() >> 4; ++ final int upperChunkZ = (structureboundingbox.getMaxZ() - 1) >> 4; // subtract 1 since maxZ is exclusive ++ ++ final int xChunksLength = (upperChunkX - lowerChunkX + 1); ++ final int zChunksLength = (upperChunkZ - lowerChunkZ + 1); ++ ++ final ObjectRBTreeSet>[] containingChunks = new ObjectRBTreeSet[xChunksLength * zChunksLength]; ++ ++ final int offset = (xChunksLength * -lowerChunkZ - lowerChunkX); ++ int totalEntries = 0; ++ for (int currChunkX = lowerChunkX; currChunkX <= upperChunkX; ++currChunkX) { ++ for (int currChunkZ = lowerChunkZ; currChunkZ <= upperChunkZ; ++currChunkZ) { ++ // todo optimize ++ //final int index = (currChunkX - lowerChunkX) + xChunksLength * (currChunkZ - lowerChunkZ); ++ final int index = offset + currChunkX + xChunksLength * currChunkZ; ++ final ObjectRBTreeSet> set = containingChunks[index] = this.entriesByChunk.get(MCUtil.getCoordinateKey(currChunkX, currChunkZ)); ++ if (set != null) { ++ totalEntries += set.size(); ++ } ++ } ++ } ++ ++ final List> ret = new ArrayList<>(totalEntries); ++ ++ final int matchOne = (STATE_SCHEDULED | STATE_PENDING_TICK) | (excludeTicked ? 0 : (STATE_TICKING | STATE_TICKED)); ++ ++ MCUtil.mergeSortedSets((NextTickListEntry entry) -> { ++ if (!isBlockInSortof(structureboundingbox, entry.getPosition())) { ++ return; ++ } ++ final int tickState = entry.tickState; ++ if ((tickState & matchOne) == 0) { ++ return; ++ } ++ ++ ret.add(entry); ++ return; ++ }, TickListServerInterval.ENTRY_COMPARATOR, containingChunks); ++ ++ if (removeReturned) { ++ for (NextTickListEntry entry : ret) { ++ this.removeEntry(entry); ++ } ++ } ++ ++ return ret; ++ } ++ ++ @Override ++ public void copy(StructureBoundingBox structureboundingbox, BlockPosition blockposition) { ++ // start copy from TickListServer // TODO check on update ++ List> list = this.getEntriesInBoundingBox(structureboundingbox, false, false); ++ Iterator> iterator = list.iterator(); ++ ++ while (iterator.hasNext()) { ++ NextTickListEntry nextticklistentry = iterator.next(); ++ ++ if (structureboundingbox.hasPoint( nextticklistentry.getPosition())) { ++ BlockPosition blockposition1 = nextticklistentry.getPosition().add(blockposition); ++ T t0 = nextticklistentry.getData(); ++ ++ this.schedule(new NextTickListEntry<>(blockposition1, t0, nextticklistentry.getTargetTick(), nextticklistentry.getPriority())); ++ } ++ } ++ // end copy from TickListServer ++ } ++ ++ @Override ++ public List> getEntriesInChunk(ChunkCoordIntPair chunkPos, boolean removeReturned, boolean excludeTicked) { ++ // Vanilla DOES get the entries 2 blocks out of the chunk too, but that doesn't matter since we ignore chunks ++ // not at ticking status, and ticking status requires neighbours loaded ++ // so with this method we will reduce scheduler churning ++ final int matchOne = (STATE_SCHEDULED | STATE_PENDING_TICK) | (excludeTicked ? 0 : (STATE_TICKING | STATE_TICKED)); ++ ++ final ObjectRBTreeSet> entries = this.entriesByChunk.get(MCUtil.getCoordinateKey(chunkPos)); ++ ++ if (entries == null) { ++ return Collections.emptyList(); ++ } ++ ++ final List> ret = new ArrayList<>(entries.size()); ++ ++ for (NextTickListEntry entry : entries) { ++ if ((entry.tickState & matchOne) == 0) { ++ continue; ++ } ++ ret.add(entry); ++ } ++ ++ if (removeReturned) { ++ for (NextTickListEntry entry : ret) { ++ this.removeEntry(entry); ++ } ++ } ++ ++ return ret; ++ } ++ ++ @Override ++ public NBTTagList serialize(ChunkCoordIntPair chunkcoordintpair) { ++ // start copy from TickListServer // TODO check on update ++ List> list = this.getEntriesInChunk(chunkcoordintpair, false, true); ++ ++ return TickListServer.serialize(this.getMinecraftKeyFrom, list, this.world.getTime()); ++ // end copy from TickListServer ++ } ++ ++ @Override ++ public int getTotalScheduledEntries() { ++ // good thing this is only used in debug reports // TODO check on update ++ int ret = 0; ++ ++ for (NextTickListEntry entry : this.longScheduled) { ++ if (entry.tickState == STATE_SCHEDULED) { ++ ++ret; ++ } ++ } ++ ++ for (Iterator>>> iterator = this.pendingChunkTickLoad.long2ObjectEntrySet().iterator(); iterator.hasNext();) { ++ ArrayList> list = iterator.next().getValue(); ++ ++ for (NextTickListEntry entry : list) { ++ if (entry.tickState == STATE_SCHEDULED) { ++ ++ret; ++ } ++ } ++ } ++ ++ for (TickListServerInterval interval : this.shortScheduled) { ++ for (Iterable> set : interval.byPriority) { ++ for (NextTickListEntry entry : set) { ++ if (entry.tickState == STATE_SCHEDULED) { ++ ++ret; ++ } ++ } ++ } ++ } ++ ++ return ret; ++ } ++} +diff --git a/src/main/java/com/destroystokyo/paper/server/ticklist/TickListServerInterval.java b/src/main/java/com/destroystokyo/paper/server/ticklist/TickListServerInterval.java +new file mode 100644 +index 0000000000..13cf1a55a9 +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/server/ticklist/TickListServerInterval.java +@@ -0,0 +1,41 @@ ++package com.destroystokyo.paper.server.ticklist; ++ ++import com.destroystokyo.paper.util.set.LinkedSortedSet; ++import net.minecraft.server.NextTickListEntry; ++import net.minecraft.server.TickListPriority; ++import java.util.Comparator; ++ ++// represents a set of entries to tick at a specified time ++public final class TickListServerInterval { ++ ++ public static final int TOTAL_PRIORITIES = TickListPriority.values().length; ++ public static final Comparator> ENTRY_COMPARATOR_BY_ID = (entry1, entry2) -> { ++ return Long.compare(entry1.getId(), entry2.getId()); ++ }; ++ public static final Comparator> ENTRY_COMPARATOR = (Comparator)NextTickListEntry.comparator(); ++ ++ // we do not record the interval, this class is meant to be used on a ring buffer ++ ++ // inlined enum map for TickListPriority ++ public final LinkedSortedSet>[] byPriority = new LinkedSortedSet[TOTAL_PRIORITIES]; ++ ++ { ++ for (int i = 0, len = this.byPriority.length; i < len; ++i) { ++ this.byPriority[i] = new LinkedSortedSet<>(ENTRY_COMPARATOR_BY_ID); ++ } ++ } ++ ++ public void addEntryLast(final NextTickListEntry entry) { ++ this.byPriority[entry.getPriority().ordinal()].addLast(entry); ++ } ++ ++ public void addEntryFirst(final NextTickListEntry entry) { ++ this.byPriority[entry.getPriority().ordinal()].addFirst(entry); ++ } ++ ++ public void clear() { ++ for (int i = 0, len = this.byPriority.length; i < len; ++i) { ++ this.byPriority[i].clear(); // O(1) clear ++ } ++ } ++} +diff --git a/src/main/java/com/destroystokyo/paper/util/set/LinkedSortedSet.java b/src/main/java/com/destroystokyo/paper/util/set/LinkedSortedSet.java +new file mode 100644 +index 0000000000..118988c39e +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/util/set/LinkedSortedSet.java +@@ -0,0 +1,142 @@ ++package com.destroystokyo.paper.util.set; ++ ++import java.util.Comparator; ++import java.util.Iterator; ++import java.util.NoSuchElementException; ++ ++public final class LinkedSortedSet implements Iterable { ++ ++ public final Comparator comparator; ++ ++ protected Link head; ++ protected Link tail; ++ ++ public LinkedSortedSet() { ++ this((Comparator)Comparator.naturalOrder()); ++ } ++ ++ public LinkedSortedSet(final Comparator comparator) { ++ this.comparator = comparator; ++ } ++ ++ public void clear() { ++ this.head = this.tail = null; ++ } ++ ++ @Override ++ public Iterator iterator() { ++ return new Iterator() { ++ ++ Link next = LinkedSortedSet.this.head; ++ ++ @Override ++ public boolean hasNext() { ++ return this.next != null; ++ } ++ ++ @Override ++ public E next() { ++ final Link next = this.next; ++ if (next == null) { ++ throw new NoSuchElementException(); ++ } ++ this.next = next.next; ++ return next.element; ++ } ++ }; ++ } ++ ++ public boolean addLast(final E element) { ++ final Comparator comparator = this.comparator; ++ ++ Link curr = this.tail; ++ if (curr != null) { ++ int compare; ++ ++ while ((compare = comparator.compare(element, curr.element)) < 0) { ++ Link prev = curr; ++ curr = curr.prev; ++ if (curr != null) { ++ continue; ++ } ++ this.head = prev.prev = new Link<>(element, null, prev); ++ return true; ++ } ++ ++ if (compare != 0) { ++ // insert after curr ++ final Link next = curr.next; ++ final Link insert = new Link<>(element, curr, next); ++ curr.next = insert; ++ ++ if (next == null) { ++ this.tail = insert; ++ } else { ++ next.prev = insert; ++ } ++ return true; ++ } ++ ++ return false; ++ } else { ++ this.head = this.tail = new Link<>(element); ++ return true; ++ } ++ } ++ ++ public boolean addFirst(final E element) { ++ final Comparator comparator = this.comparator; ++ ++ Link curr = this.head; ++ if (curr != null) { ++ int compare; ++ ++ while ((compare = comparator.compare(element, curr.element)) > 0) { ++ Link prev = curr; ++ curr = curr.next; ++ if (curr != null) { ++ continue; ++ } ++ this.tail = prev.next = new Link<>(element, prev, null); ++ return true; ++ } ++ ++ if (compare != 0) { ++ // insert before curr ++ final Link prev = curr.prev; ++ final Link insert = new Link<>(element, prev, curr); ++ curr.prev = insert; ++ ++ if (prev == null) { ++ this.head = insert; ++ } else { ++ prev.next = insert; ++ } ++ return true; ++ } ++ ++ return false; ++ } else { ++ this.head = this.tail = new Link<>(element); ++ return true; ++ } ++ } ++ ++ protected static final class Link { ++ public E element; ++ public Link prev; ++ public Link next; ++ ++ public Link() {} ++ ++ public Link(final E element) { ++ this.element = element; ++ } ++ ++ public Link(final E element, final Link prev, final Link next) { ++ this.element = element; ++ this.prev = prev; ++ this.next = next; ++ } ++ } ++} +diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java +index e650a2e48d..2d07d350d2 100644 +--- a/src/main/java/net/minecraft/server/BlockPosition.java ++++ b/src/main/java/net/minecraft/server/BlockPosition.java +@@ -125,6 +125,7 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali + return i == 0 && j == 0 && k == 0 ? this : new BlockPosition(this.getX() + i, this.getY() + j, this.getZ() + k); + } + ++ public final BlockPosition add(BaseBlockPosition baseblockposition) { return this.a(baseblockposition); } // Paper - OBFHELPER + public BlockPosition a(BaseBlockPosition baseblockposition) { + return this.b(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ()); + } +diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java +index cf9021d605..00a83aa7c6 100644 +--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java ++++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java +@@ -119,6 +119,13 @@ public class ChunkProviderServer extends IChunkProvider { + } + // Paper + ++ // Paper start - rewrite ticklistserver ++ public final boolean isTickingReadyMainThread(BlockPosition pos) { ++ PlayerChunk chunk = this.playerChunkMap.getUpdatingChunk(MCUtil.getCoordinateKey(pos)); ++ return chunk != null && chunk.isTickingReady(); ++ } ++ // Paper end - rewrite ticklistserver ++ + + public ChunkProviderServer(WorldServer worldserver, File file, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, ChunkGenerator chunkgenerator, int i, WorldLoadListener worldloadlistener, Supplier supplier) { + this.world = worldserver; +diff --git a/src/main/java/net/minecraft/server/NextTickListEntry.java b/src/main/java/net/minecraft/server/NextTickListEntry.java +index 33cfeabdee..2287e47d1b 100644 +--- a/src/main/java/net/minecraft/server/NextTickListEntry.java ++++ b/src/main/java/net/minecraft/server/NextTickListEntry.java +@@ -5,11 +5,13 @@ import java.util.Comparator; + public class NextTickListEntry { + + private static final java.util.concurrent.atomic.AtomicLong COUNTER = new java.util.concurrent.atomic.AtomicLong(); // Paper - async chunk loading +- private final T e; +- public final BlockPosition a; +- public final long b; +- public final TickListPriority c; +- private final long f; ++ private final T e; public final T getData() { return this.e; } // Paper - OBFHELPER ++ public final BlockPosition a; public final BlockPosition getPosition() { return this.a; } // Paper - OBFHELPER ++ public final long b; public final long getTargetTick() { return this.b; } // Paper - OBFHELPER ++ public final TickListPriority c; public final TickListPriority getPriority() { return this.c; } // Paper - OBFHELPER ++ private final long f; public final long getId() { return this.f; } // Paper - OBFHELPER ++ private final int hash; // Paper ++ public int tickState; // Paper + + public NextTickListEntry(BlockPosition blockposition, T t0) { + this(blockposition, t0, 0L, TickListPriority.NORMAL); +@@ -21,6 +23,7 @@ public class NextTickListEntry { + this.e = t0; + this.b = i; + this.c = ticklistpriority; ++ this.hash = this.computeHash(); // Paper + } + + public boolean equals(Object object) { +@@ -33,19 +36,31 @@ public class NextTickListEntry { + } + } + ++ // Paper start - optimize hashcode ++ @Override + public int hashCode() { ++ return this.hash; ++ } ++ public final int computeHash() { ++ // Paper end - optimize hashcode + return this.a.hashCode(); + } + +- public static Comparator a() { // Paper - decompile fix +- return Comparator.comparingLong((nextticklistentry) -> { +- return ((NextTickListEntry) nextticklistentry).b; // Paper - decompile fix +- }).thenComparing((nextticklistentry) -> { +- return ((NextTickListEntry) nextticklistentry).c; // Paper - decompile fix +- }).thenComparingLong((nextticklistentry) -> { +- return ((NextTickListEntry) nextticklistentry).f; // Paper - decompile fix +- }); ++ // Paper start - let's not use more functional code for no reason. ++ public static Comparator comparator() { return NextTickListEntry.a(); } // Paper - OBFHELPER ++ public static Comparator a() { ++ return (Comparator)(Comparator)(NextTickListEntry nextticklistentry, NextTickListEntry nextticklistentry1) -> { ++ int i = Long.compare(nextticklistentry.getTargetTick(), nextticklistentry1.getTargetTick()); ++ ++ if (i != 0) { ++ return i; ++ } else { ++ i = nextticklistentry.getPriority().compareTo(nextticklistentry1.getPriority()); ++ return i != 0 ? i : Long.compare(nextticklistentry.getId(), nextticklistentry1.getId()); ++ } ++ }; + } ++ // Paper end - let's not use more functional code for no reason. + + public String toString() { + return this.e + ": " + this.a + ", " + this.b + ", " + this.c + ", " + this.f; +diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java +index b38bc67758..9f8818c2d4 100644 +--- a/src/main/java/net/minecraft/server/PlayerChunk.java ++++ b/src/main/java/net/minecraft/server/PlayerChunk.java +@@ -474,7 +474,9 @@ public class PlayerChunk { + PlayerChunk.this.isTickingReady = true; + + +- ++ // Paper start - rewrite ticklistserver ++ PlayerChunk.this.chunkMap.world.onChunkSetTicking(PlayerChunk.this.location.x, PlayerChunk.this.location.z); ++ // Paper end - rewrite ticklistserver + + } + }); +diff --git a/src/main/java/net/minecraft/server/StructureBoundingBox.java b/src/main/java/net/minecraft/server/StructureBoundingBox.java +index dbb565e74d..185658e230 100644 +--- a/src/main/java/net/minecraft/server/StructureBoundingBox.java ++++ b/src/main/java/net/minecraft/server/StructureBoundingBox.java +@@ -4,12 +4,12 @@ import com.google.common.base.MoreObjects; + + public class StructureBoundingBox { + +- public int a; +- public int b; +- public int c; +- public int d; +- public int e; +- public int f; ++ public int a; public final int getMinX() { return this.a; } // Paper - OBFHELPER ++ public int b; public final int getMinY() { return this.b; } // Paper - OBFHELPER ++ public int c; public final int getMinZ() { return this.c; } // Paper - OBFHELPER ++ public int d; public final int getMaxX() { return this.d; } // Paper - OBFHELPER ++ public int e; public final int getMaxY() { return this.e; } // Paper - OBFHELPER ++ public int f; public final int getMaxZ() { return this.f; } // Paper - OBFHELPER + + public StructureBoundingBox() {} + +@@ -84,6 +84,7 @@ public class StructureBoundingBox { + this.e = 512; + } + ++ public final boolean intersects(StructureBoundingBox boundingBox) { return this.b(boundingBox); } // Paper - OBFHELPER + public boolean b(StructureBoundingBox structureboundingbox) { + return this.d >= structureboundingbox.a && this.a <= structureboundingbox.d && this.f >= structureboundingbox.c && this.c <= structureboundingbox.f && this.e >= structureboundingbox.b && this.b <= structureboundingbox.e; + } +@@ -114,6 +115,7 @@ public class StructureBoundingBox { + return new StructureBoundingBox(this.a + i, this.b + j, this.c + k, this.d + i, this.e + j, this.f + k); + } + ++ public final boolean hasPoint(BaseBlockPosition baseblockposition) { return this.b(baseblockposition); } // Paper - OBFHELPER + public boolean b(BaseBlockPosition baseblockposition) { + return baseblockposition.getX() >= this.a && baseblockposition.getX() <= this.d && baseblockposition.getZ() >= this.c && baseblockposition.getZ() <= this.f && baseblockposition.getY() >= this.b && baseblockposition.getY() <= this.e; + } +diff --git a/src/main/java/net/minecraft/server/TickListServer.java b/src/main/java/net/minecraft/server/TickListServer.java +index f533860bbe..3f1aa5ced6 100644 +--- a/src/main/java/net/minecraft/server/TickListServer.java ++++ b/src/main/java/net/minecraft/server/TickListServer.java +@@ -42,6 +42,11 @@ public class TickListServer implements TickList { + // Paper end + + public void b() { ++ // Paper start - allow overriding ++ this.tick(); ++ } ++ public void tick() { ++ // Paper end + int i = this.nextTickList.size(); + + if (false) { // CraftBukkit +@@ -109,15 +114,30 @@ public class TickListServer implements TickList { + + @Override + public boolean b(BlockPosition blockposition, T t0) { ++ // Paper start - allow overriding ++ return this.isPendingTickThisTick(blockposition, t0); ++ } ++ public boolean isPendingTickThisTick(BlockPosition blockposition, T t0) { ++ // Paper end + return this.g.contains(new NextTickListEntry<>(blockposition, t0)); + } + + @Override + public void a(Stream> stream) { ++ // Paper start - allow overriding ++ this.scheduleAll(stream); ++ } ++ public void scheduleAll(Stream> stream) { ++ // Paper end + stream.forEach(this::a); + } + + public List> a(ChunkCoordIntPair chunkcoordintpair, boolean flag, boolean flag1) { ++ // Paper start - allow overriding ++ return this.getEntriesInChunk(chunkcoordintpair, flag, flag1); ++ } ++ public List> getEntriesInChunk(ChunkCoordIntPair chunkcoordintpair, boolean flag, boolean flag1) { ++ // Paper end + int i = (chunkcoordintpair.x << 4) - 2; + int j = i + 16 + 2; + int k = (chunkcoordintpair.z << 4) - 2; +@@ -127,6 +147,11 @@ public class TickListServer implements TickList { + } + + public List> a(StructureBoundingBox structureboundingbox, boolean flag, boolean flag1) { ++ // Paper start - allow overriding ++ return this.getEntriesInBoundingBox(structureboundingbox, flag, flag1); ++ } ++ public List> getEntriesInBoundingBox(StructureBoundingBox structureboundingbox, boolean flag, boolean flag1) { ++ // Paper end + List> list = this.a((List) null, this.nextTickList, structureboundingbox, flag); + + if (flag && list != null) { +@@ -166,6 +191,11 @@ public class TickListServer implements TickList { + } + + public void a(StructureBoundingBox structureboundingbox, BlockPosition blockposition) { ++ // Paper start - allow overriding ++ this.copy(structureboundingbox, blockposition); ++ } ++ public void copy(StructureBoundingBox structureboundingbox, BlockPosition blockposition) { ++ // Paper end + List> list = this.a(structureboundingbox, false, false); + Iterator iterator = list.iterator(); + +@@ -183,11 +213,17 @@ public class TickListServer implements TickList { + } + + public NBTTagList a(ChunkCoordIntPair chunkcoordintpair) { ++ // Paper start - allow overriding ++ return this.serialize(chunkcoordintpair); ++ } ++ public NBTTagList serialize(ChunkCoordIntPair chunkcoordintpair) { ++ // Paper end + List> list = this.a(chunkcoordintpair, false, true); + + return a(this.b, list, this.f.getTime()); + } + ++ public static NBTTagList serialize(Function function, Iterable> iterable, long i) { return TickListServer.a(function, iterable, i); } // Paper - OBFHELPER + public static NBTTagList a(Function function, Iterable> iterable, long i) { + NBTTagList nbttaglist = new NBTTagList(); + Iterator iterator = iterable.iterator(); +@@ -210,11 +246,21 @@ public class TickListServer implements TickList { + + @Override + public boolean a(BlockPosition blockposition, T t0) { ++ // Paper start - allow overriding ++ return this.isScheduledForTick(blockposition, t0); ++ } ++ public boolean isScheduledForTick(BlockPosition blockposition, T t0) { ++ // Paper end + return this.nextTickListHash.contains(new NextTickListEntry<>(blockposition, t0)); + } + + @Override + public void a(BlockPosition blockposition, T t0, int i, TickListPriority ticklistpriority) { ++ // Paper start - allow overriding ++ this.schedule(blockposition, t0, i, ticklistpriority); ++ } ++ public void schedule(BlockPosition blockposition, T t0, int i, TickListPriority ticklistpriority) { ++ // Paper end + if (!this.a.test(t0)) { + this.a(new NextTickListEntry<>(blockposition, t0, (long) i + this.f.getTime(), ticklistpriority)); + } +@@ -230,6 +276,11 @@ public class TickListServer implements TickList { + } + + public int a() { ++ // Paper start - allow overriding ++ return this.getTotalScheduledEntries(); ++ } ++ public int getTotalScheduledEntries() { ++ // Paper end + return this.nextTickListHash.size(); + } + } +diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java +index c74b85917a..3e5ed2bd4e 100644 +--- a/src/main/java/net/minecraft/server/WorldServer.java ++++ b/src/main/java/net/minecraft/server/WorldServer.java +@@ -170,6 +170,13 @@ public class WorldServer extends World { + } + // Paper end + ++ // Paper start - rewrite ticklistserver ++ void onChunkSetTicking(int chunkX, int chunkZ) { ++ ((com.destroystokyo.paper.server.ticklist.PaperTickList)this.nextTickListBlock).onChunkSetTicking(chunkX, chunkZ); ++ ((com.destroystokyo.paper.server.ticklist.PaperTickList)this.nextTickListFluid).onChunkSetTicking(chunkX, chunkZ); ++ } ++ // Paper end - rewrite ticklistserver ++ + // Add env and gen to constructor + public WorldServer(MinecraftServer minecraftserver, Executor executor, WorldNBTStorage worldnbtstorage, WorldData worlddata, DimensionManager dimensionmanager, GameProfilerFiller gameprofilerfiller, WorldLoadListener worldloadlistener, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { + super(worlddata, dimensionmanager, (world, worldprovider) -> { +@@ -190,10 +197,10 @@ public class WorldServer extends World { + this.pvpMode = minecraftserver.getPVP(); + worlddata.world = this; + // CraftBukkit end +- this.nextTickListBlock = new TickListServer<>(this, (block) -> { ++ this.nextTickListBlock = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (block) -> { // Paper - optimise TickListServer + return block == null || block.getBlockData().isAir(); + }, IRegistry.BLOCK::getKey, IRegistry.BLOCK::get, this::b, "Blocks"); // Paper - Timings +- this.nextTickListFluid = new TickListServer<>(this, (fluidtype) -> { ++ this.nextTickListFluid = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (fluidtype) -> { // Paper - optimise TickListServer + return fluidtype == null || fluidtype == FluidTypes.EMPTY; + }, IRegistry.FLUID::getKey, IRegistry.FLUID::get, this::a, "Fluids"); // Paper - Timings + this.navigators = Sets.newHashSet(); +-- +2.25.1 +