diff --git a/Spigot-Server-Patches/Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch b/Spigot-Server-Patches/Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch index e52b325210..14047cb0b4 100644 --- a/Spigot-Server-Patches/Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch +++ b/Spigot-Server-Patches/Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch @@ -16,7 +16,7 @@ intent to remove) and replace it with two new methods, clearly named and documented as to their purpose. diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index 64992e139..ad600c318 100644 +index 635be7ccc..a9ea2fd87 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { @@ -106,7 +106,7 @@ index c1ef1c950..3824180ee 100644 public Location getBedSpawnLocation() { NBTTagCompound data = getData(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 05f380023..67a960616 100644 +index 73a7cc7fd..14695d1a1 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/Spigot-Server-Patches/Add-option-to-disable-pillager-patrols.patch b/Spigot-Server-Patches/Add-option-to-disable-pillager-patrols.patch index be7d8395a2..29c80fa43d 100644 --- a/Spigot-Server-Patches/Add-option-to-disable-pillager-patrols.patch +++ b/Spigot-Server-Patches/Add-option-to-disable-pillager-patrols.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add option to disable pillager patrols diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index 8648d9e3d..917dc6253 100644 +index c0af1aaf3..dbc645ebb 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java @@ -0,0 +0,0 @@ public class PaperWorldConfig { diff --git a/Spigot-Server-Patches/Add-option-to-prevent-players-from-moving-into-unloa.patch b/Spigot-Server-Patches/Add-option-to-prevent-players-from-moving-into-unloa.patch index 3499269758..aee122a470 100644 --- a/Spigot-Server-Patches/Add-option-to-prevent-players-from-moving-into-unloa.patch +++ b/Spigot-Server-Patches/Add-option-to-prevent-players-from-moving-into-unloa.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Add option to prevent players from moving into unloaded diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index fe3e78f36..4bcba0a2b 100644 +index 7dda0803c..dd5e263d7 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java @@ -0,0 +0,0 @@ public class PaperWorldConfig { diff --git a/Spigot-Server-Patches/Add-sun-related-API.patch b/Spigot-Server-Patches/Add-sun-related-API.patch index 8ee2817b5d..0671eeab49 100644 --- a/Spigot-Server-Patches/Add-sun-related-API.patch +++ b/Spigot-Server-Patches/Add-sun-related-API.patch @@ -29,7 +29,7 @@ index 7a9159252..3e4632425 100644 return this.worldProvider.getDimensionManager() == DimensionManager.OVERWORLD && this.c < 4; } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 182322752..578fe8d19 100644 +index 8a0675037..aec657952 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -0,0 +0,0 @@ public class CraftWorld implements World { diff --git a/Spigot-Server-Patches/Allow-chests-to-be-placed-with-NBT-data.patch b/Spigot-Server-Patches/Allow-chests-to-be-placed-with-NBT-data.patch index 38d103fed9..3cbf7bbbd8 100644 --- a/Spigot-Server-Patches/Allow-chests-to-be-placed-with-NBT-data.patch +++ b/Spigot-Server-Patches/Allow-chests-to-be-placed-with-NBT-data.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Allow chests to be placed with NBT data diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java -index 627fa465c..df85f9df0 100644 +index 33d9cac4d..d891e7b0e 100644 --- a/src/main/java/net/minecraft/server/ItemStack.java +++ b/src/main/java/net/minecraft/server/ItemStack.java @@ -0,0 +0,0 @@ public final class ItemStack { diff --git a/Spigot-Server-Patches/Anti-Xray.patch b/Spigot-Server-Patches/Anti-Xray.patch index 786161c27c..098c11d25d 100644 --- a/Spigot-Server-Patches/Anti-Xray.patch +++ b/Spigot-Server-Patches/Anti-Xray.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Anti-Xray diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index f5ed0a698..363676348 100644 +index 99f1541b9..6634ef923 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java @@ -0,0 +0,0 @@ diff --git a/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch b/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch index 7cad0d5025..a5575bc70e 100644 --- a/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch +++ b/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch @@ -2962,7 +2962,7 @@ index 25a87c2d3..c02c53b50 100644 + } } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 8e15aba7f..edb3a6035 100644 +index f63269157..664c48d68 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant -Date: Wed, 27 Apr 2016 22:09:52 -0400 -Subject: [PATCH] Optimize Hoppers - -* Removes unnecessary extra calls to .update() that are very expensive -* Lots of itemstack cloning removed. Only clone if the item is actually moved -* Return true when a plugin cancels inventory move item event instead of false, as false causes pulls to cycle through all items. - However, pushes do not exhibit the same behavior, so this is not something plugins could of been relying on. -* Add option (Default on) to cooldown hoppers when they fail to move an item due to full inventory -* Skip subsequent InventoryMoveItemEvents if a plugin does not use the item after first event fire for an iteration - -diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index 42d14fac2..80d66c647 100644 ---- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -@@ -0,0 +0,0 @@ public class PaperWorldConfig { - this.armorStandTick = this.getBoolean("armor-stands-tick", this.armorStandTick); - log("ArmorStand ticking is " + (this.armorStandTick ? "enabled" : "disabled") + " by default"); - } -+ -+ public boolean cooldownHopperWhenFull = true; -+ public boolean disableHopperMoveEvents = false; -+ private void hopperOptimizations() { -+ cooldownHopperWhenFull = getBoolean("hopper.cooldown-when-full", cooldownHopperWhenFull); -+ log("Cooldown Hoppers when Full: " + (cooldownHopperWhenFull ? "enabled" : "disabled")); -+ disableHopperMoveEvents = getBoolean("hopper.disable-move-event", disableHopperMoveEvents); -+ log("Hopper Move Item Events: " + (disableHopperMoveEvents ? "disabled" : "enabled")); -+ } - } -diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java -index 33d9cac4d..627fa465c 100644 ---- a/src/main/java/net/minecraft/server/ItemStack.java -+++ b/src/main/java/net/minecraft/server/ItemStack.java -@@ -0,0 +0,0 @@ public final class ItemStack { - return this.getItem().a(this, entityhuman, entityliving, enumhand); - } - -- public ItemStack cloneItemStack() { -+ public ItemStack cloneItemStack() { return cloneItemStack(false); } // Paper -+ public ItemStack cloneItemStack(boolean origItem) { // Paper - if (this.isEmpty()) { - return ItemStack.a; - } else { -- ItemStack itemstack = new ItemStack(this.getItem(), this.count); -+ ItemStack itemstack = new ItemStack(origItem ? this.item : this.getItem(), this.count); // Paper - - itemstack.d(this.C()); - if (this.tag != null) { -diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index dd2d8712e..206a4ad64 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant 0; // Paper -+ TileEntityHopper.skipHopperEvents = worldserver.paperConfig.disableHopperMoveEvents || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - if (true || worldserver.worldProvider.getDimensionManager() == DimensionManager.OVERWORLD || this.getAllowNether()) { // CraftBukkit - this.methodProfiler.a(() -> { - return worldserver.getWorldData().getName() + " " + IRegistry.DIMENSION_TYPE.getKey(worldserver.worldProvider.getDimensionManager()); -diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java -index 958279249..a8e64dfda 100644 ---- a/src/main/java/net/minecraft/server/TileEntity.java -+++ b/src/main/java/net/minecraft/server/TileEntity.java -@@ -0,0 +0,0 @@ public abstract class TileEntity implements KeyedObject { // Paper - public void setCurrentChunk(Chunk chunk) { - this.currentChunk = chunk != null ? new java.lang.ref.WeakReference<>(chunk) : null; - } -+ static boolean IGNORE_TILE_UPDATES = false; - // Paper end - - @Nullable -@@ -0,0 +0,0 @@ public abstract class TileEntity implements KeyedObject { // Paper - - public void update() { - if (this.world != null) { -+ if (IGNORE_TILE_UPDATES) return; // Paper - this.c = this.world.getType(this.position); - this.world.b(this.position, this); - if (!this.c.isAir()) { -diff --git a/src/main/java/net/minecraft/server/TileEntityHopper.java b/src/main/java/net/minecraft/server/TileEntityHopper.java -index e08faf538..e7cf14d10 100644 ---- a/src/main/java/net/minecraft/server/TileEntityHopper.java -+++ b/src/main/java/net/minecraft/server/TileEntityHopper.java -@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi - return false; - } - -+ // Paper start - Optimize Hoppers -+ private static boolean skipPullModeEventFire = false; -+ private static boolean skipPushModeEventFire = false; -+ static boolean skipHopperEvents = false; -+ -+ private boolean hopperPush(IInventory iinventory, EnumDirection enumdirection) { -+ skipPushModeEventFire = skipHopperEvents; -+ boolean foundItem = false; -+ for (int i = 0; i < this.getSize(); ++i) { -+ if (!this.getItem(i).isEmpty()) { -+ foundItem = true; -+ ItemStack origItemStack = this.getItem(i); -+ ItemStack itemstack = origItemStack; -+ -+ final int origCount = origItemStack.getCount(); -+ final int moved = Math.min(world.spigotConfig.hopperAmount, origCount); -+ origItemStack.setCount(moved); -+ -+ // We only need to fire the event once to give protection plugins a chance to cancel this event -+ // Because nothing uses getItem, every event call should end up the same result. -+ if (!skipPushModeEventFire) { -+ itemstack = callPushMoveEvent(iinventory, itemstack); -+ if (itemstack == null) { // cancelled -+ origItemStack.setCount(origCount); -+ return false; -+ } -+ } -+ final ItemStack itemstack2 = addItem(this, iinventory, itemstack, enumdirection); -+ final int remaining = itemstack2.getCount(); -+ if (remaining != moved) { -+ origItemStack = origItemStack.cloneItemStack(true); -+ if (!origItemStack.isEmpty()) { -+ origItemStack.setCount(origCount - moved + remaining); -+ } -+ this.setItem(i, origItemStack); -+ iinventory.update(); -+ return true; -+ } -+ origItemStack.setCount(origCount); -+ } -+ } -+ if (foundItem && world.paperConfig.cooldownHopperWhenFull) { // Inventory was full - cooldown -+ this.setCooldown(world.spigotConfig.hopperTransfer); -+ } -+ return false; -+ } -+ -+ private static boolean hopperPull(IHopper ihopper, IInventory iinventory, int i) { -+ ItemStack origItemStack = iinventory.getItem(i); -+ ItemStack itemstack = origItemStack; -+ final int origCount = origItemStack.getCount(); -+ final World world = ihopper.getWorld(); -+ final int moved = Math.min(world.spigotConfig.hopperAmount, origCount); -+ itemstack.setCount(moved); -+ -+ if (!skipPullModeEventFire) { -+ itemstack = callPullMoveEvent(ihopper, iinventory, itemstack); -+ if (itemstack == null) { // cancelled -+ origItemStack.setCount(origCount); -+ // Drastically improve performance by returning true. -+ // No plugin could of relied on the behavior of false as the other call -+ // site for IMIE did not exhibit the same behavior -+ return true; -+ } -+ } -+ -+ final ItemStack itemstack2 = addItem(iinventory, ihopper, itemstack, null); -+ final int remaining = itemstack2.getCount(); -+ if (remaining != moved) { -+ origItemStack = origItemStack.cloneItemStack(true); -+ if (!origItemStack.isEmpty()) { -+ origItemStack.setCount(origCount - moved + remaining); -+ } -+ IGNORE_TILE_UPDATES = true; -+ iinventory.setItem(i, origItemStack); -+ IGNORE_TILE_UPDATES = false; -+ iinventory.update(); -+ return true; -+ } -+ origItemStack.setCount(origCount); -+ -+ if (world.paperConfig.cooldownHopperWhenFull) { -+ cooldownHopper(ihopper); -+ } -+ -+ return false; -+ } -+ -+ private ItemStack callPushMoveEvent(IInventory iinventory, ItemStack itemstack) { -+ Inventory destinationInventory = getInventory(iinventory); -+ InventoryMoveItemEvent event = new InventoryMoveItemEvent(this.getOwner(false).getInventory(), -+ CraftItemStack.asCraftMirror(itemstack), destinationInventory, true); -+ boolean result = event.callEvent(); -+ if (!event.calledGetItem && !event.calledSetItem) { -+ skipPushModeEventFire = true; -+ } -+ if (!result) { -+ cooldownHopper(this); -+ return null; -+ } -+ -+ if (event.calledSetItem) { -+ return CraftItemStack.asNMSCopy(event.getItem()); -+ } else { -+ return itemstack; -+ } -+ } -+ -+ private static ItemStack callPullMoveEvent(IHopper hopper, IInventory iinventory, ItemStack itemstack) { -+ Inventory sourceInventory = getInventory(iinventory); -+ Inventory destination = getInventory(hopper); -+ -+ InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, -+ // Mirror is safe as we no plugins ever use this item -+ CraftItemStack.asCraftMirror(itemstack), destination, false); -+ boolean result = event.callEvent(); -+ if (!event.calledGetItem && !event.calledSetItem) { -+ skipPullModeEventFire = true; -+ } -+ if (!result) { -+ cooldownHopper(hopper); -+ return null; -+ } -+ -+ if (event.calledSetItem) { -+ return CraftItemStack.asNMSCopy(event.getItem()); -+ } else { -+ return itemstack; -+ } -+ } -+ -+ private static Inventory getInventory(IInventory iinventory) { -+ Inventory sourceInventory;// Have to special case large chests as they work oddly -+ if (iinventory instanceof InventoryLargeChest) { -+ sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory); -+ } else if (iinventory instanceof TileEntity) { -+ sourceInventory = ((TileEntity) iinventory).getOwner(false).getInventory(); -+ } else { -+ sourceInventory = iinventory.getOwner().getInventory(); -+ } -+ return sourceInventory; -+ } -+ -+ private static void cooldownHopper(IHopper hopper) { -+ if (hopper instanceof TileEntityHopper) { -+ ((TileEntityHopper) hopper).setCooldown(hopper.getWorld().spigotConfig.hopperTransfer); -+ } else if (hopper instanceof EntityMinecartHopper) { -+ ((EntityMinecartHopper) hopper).setCooldown(hopper.getWorld().spigotConfig.hopperTransfer / 2); -+ } -+ } -+ // Paper end -+ - private boolean j() { - IInventory iinventory = this.k(); - -@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi - if (this.b(iinventory, enumdirection)) { - return false; - } else { -+ return hopperPush(iinventory, enumdirection); /* // Paper - disable rest - for (int i = 0; i < this.getSize(); ++i) { - if (!this.getItem(i).isEmpty()) { - ItemStack itemstack = this.getItem(i).cloneItemStack(); -@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi - } - } - -- return false; -+ return false;*/ // Paper - end commenting out replaced block for Hopper Optimizations - } - } - } -@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi - EnumDirection enumdirection = EnumDirection.DOWN; - - return c(iinventory, enumdirection) ? false : a(iinventory, enumdirection).anyMatch((i) -> { -+ skipPullModeEventFire = skipHopperEvents; // Paper - return a(ihopper, iinventory, i, enumdirection); - }); - } else { -@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi - ItemStack itemstack = iinventory.getItem(i); - - if (!itemstack.isEmpty() && b(iinventory, itemstack, i, enumdirection)) { -+ return hopperPull(ihopper, iinventory, i); /* // Paper - disable rest - ItemStack itemstack1 = itemstack.cloneItemStack(); - // ItemStack itemstack2 = addItem(iinventory, ihopper, iinventory.splitStack(i, 1), (EnumDirection) null); - // CraftBukkit start - Call event on collection of items from inventories into the hopper -@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi - } - - itemstack1.subtract(origCount - itemstack2.getCount()); // Spigot -- iinventory.setItem(i, itemstack1); -+ iinventory.setItem(i, itemstack1);*/ // Paper - end commenting out replaced block for Hopper Optimizations - } - - return false; -@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi - public static boolean a(IInventory iinventory, EntityItem entityitem) { - boolean flag = false; - // CraftBukkit start -- InventoryPickupItemEvent event = new InventoryPickupItemEvent(iinventory.getOwner().getInventory(), (org.bukkit.entity.Item) entityitem.getBukkitEntity()); -+ InventoryPickupItemEvent event = new InventoryPickupItemEvent(getInventory(iinventory), (org.bukkit.entity.Item) entityitem.getBukkitEntity()); // Paper - use getInventory() to avoid snapshot creation - entityitem.world.getServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - return false; -@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi - boolean flag1 = iinventory1.isNotEmpty(); - - if (itemstack1.isEmpty()) { -+ IGNORE_TILE_UPDATES = true; // Paper - iinventory1.setItem(i, itemstack); -+ IGNORE_TILE_UPDATES = false; // Paper - itemstack = ItemStack.a; - flag = true; - } else if (a(itemstack1, itemstack)) { --- \ No newline at end of file diff --git a/Spigot-Server-Patches/Optimize-Server-World-Map.patch b/Spigot-Server-Patches/Optimize-Server-World-Map.patch index 6ac5b80ef1..770c0b49ee 100644 --- a/Spigot-Server-Patches/Optimize-Server-World-Map.patch +++ b/Spigot-Server-Patches/Optimize-Server-World-Map.patch @@ -217,7 +217,7 @@ index 000000000..6bb2f98b4 + } +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index ec575bc8f..3120f91de 100644 +index 7fd040409..553014b79 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant