From 83ce6724ca1770c90f8039847c9e9f3a9dab3d0e Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 12 Apr 2014 14:18:37 +1000 Subject: [PATCH] Stage 1 --- Bukkit | 2 +- Bukkit-Patches/0001-POM-Changes.patch | 8 +- ...cation-on-some-player-lookup-methods.patch | 20 +- CraftBukkit | 2 +- CraftBukkit-Patches/0001-POM-Changes.patch | 8 +- .../0003-Skeleton-API-Implementations.patch | 8 +- .../0004-Spigot-Configuration.patch | 20 +- .../0005-Better-Chunk-Tick-Selection.patch | 22 +- ...0007-More-Efficient-Chunk-Save-Queue.patch | 14 +- .../0008-Merge-tweaks-and-configuration.patch | 8 +- .../0010-Async-Operation-Catching.patch | 18 +- CraftBukkit-Patches/0011-View-Distance.patch | 12 +- .../0012-Compressed-Nibble-Arrays.patch | 6 +- ...0013-Sync-Free-Chunk-Reference-Cache.patch | 8 +- .../0014-Improved-Timings-System.patch | 68 +-- .../0016-Handle-Null-Tile-Entities.patch | 8 +- .../0017-Entity-Activation-Range.patch | 14 +- .../0025-Close-Unloaded-Save-Files.patch | 6 +- .../0030-Prevent-Shutdown-Hang.patch | 10 +- ...3-Allow-Disabling-of-Command-Logging.patch | 42 ++ ...low-Disabling-of-Command-TabComplete.patch | 53 +++ .../0035-Configurable-Messages.patch | 107 +++++ ...Disabling-of-Random-Lighting-Updates.patch | 51 +++ ...ory.getItem-use-both-containers.-Fix.patch | 57 +++ .../0038-Properly-Close-Inventories.patch | 63 +++ .../0039-Disallow-Interaction-With-Self.patch | 27 ++ .../0040-Lower-Chunk-Compression.patch | 36 ++ ...041-Entity-Mount-and-Dismount-Events.patch | 51 +++ ...vent-Ghost-Players-Caused-by-Plugins.patch | 26 ++ .../0043-Entity-ticking-chunk-caching.patch | 66 +++ .../0044-Plug-World-Unload-Memory-Leak.patch | 22 + .../0045-Player-Collision-API.patch | 85 ++++ ...ly-Disable-Snooper-When-Not-Required.patch | 27 ++ ...dd-Getter-for-Entity-Invulnerability.patch | 25 ++ .../0048-Cap-Minimum-Player-Speed.patch | 31 ++ ...-and-Health-for-PlayerConsumeItemEve.patch | 24 ++ ...eBlockEvent-for-Fire-Arrows-hitting-.patch | 35 ++ ...-Disabling-of-1.6.3-Structure-Saving.patch | 50 +++ .../0052-Item-Despawn-Rate.patch | 38 ++ ...0053-Don-t-Special-Case-X-Move-Value.patch | 49 +++ .../0054-Implement-respawn-API.patch | 29 ++ ...x-BrewingStands-Removing-NBT-Potions.patch | 28 ++ .../0056-Arrow-Despawn-Rate.patch | 38 ++ .../0057-Watchdog-Thread.patch | 291 +++++++++++++ .../0058-Fix-packed-ice-generation.patch | 38 ++ .../0059-Clear-Flower-Pot-on-Drop.patch | 21 + ...-chunks-not-being-sent-to-the-client.patch | 30 ++ .../0061-Fix-Broken-Async-Chat.patch | 40 ++ ...portation-of-Vehicles-and-Passengers.patch | 40 ++ ...Remove-OS-X-Special-Chars-from-Signs.patch | 21 + CraftBukkit-Patches/0064-Orebfuscator.patch | 397 ++++++++++++++++++ .../0065-Optimize-DataWatcher.patch | 134 ++++++ ...Fire-PreLogin-Events-in-Offline-Mode.patch | 159 +++++++ .../0067-BungeeCord-Support.patch | 133 ++++++ ...Disabling-Zombie-Villager-Aggression.patch | 48 +++ ...Configurable-Amount-of-Netty-Threads.patch | 57 +++ .../0070-Prevent-Mineshaft-Saving.patch | 22 + ...1-Log-Cause-of-Unexpected-Exceptions.patch | 26 ++ CraftBukkit-Patches/0072-Particle-API.patch | 175 ++++++++ .../0073-Fix-Biome-Decoration-Crashes.patch | 111 +++++ .../0074-Save-ticks-lived-to-nbttag.patch | 30 ++ .../0075-More-Efficient-GetCubes.patch | 68 +++ ...d-Option-to-Nerf-Mobs-from-Spawner-s.patch | 84 ++++ ...-Warn-if-PermGen-may-be-insufficient.patch | 36 ++ ...ble-Connected-Check-on-setScoreboard.patch | 22 + .../0079-Add-Late-Bind-Option.patch | 63 +++ ...hest-Animation-when-Cancelling-Event.patch | 117 ++++++ ...-Hand-when-BlockPlaceEvent-Cancelled.patch | 35 ++ ...low-statistics-to-be-disabled-forced.patch | 94 +++++ .../0083-Fix-anvil-collisions.patch | 29 ++ .../0084-Fix-ItemStack-Unbreakable-Code.patch | 28 ++ ...Try-and-Debug-Crash-Reports-Crashing.patch | 41 ++ .../0086-Replace-AutoSave-Mechanism.patch | 32 ++ ...ck-data-values-that-crash-the-client.patch | 61 +++ ...vanilla-s-direction-tag-on-fireballs.patch | 36 ++ .../0089-Support-non-prefixed-URLs.patch | 41 ++ ...ing-on-corrupted-map-data-NBT-arrays.patch | 33 ++ ...1-Reduce-memory-of-hiddenPlayers-map.patch | 22 + ...f-ZombiePigmen-spawning-in-portal-bl.patch | 38 ++ ...trees-replace-any-block-when-growing.patch | 27 ++ .../0094-Highly-Optimized-Tick-Loop.patch | 165 ++++++++ .../0095-Add-Spigot-Links.patch | 79 ++++ .../0096-Configurable-Ping-Sample-Size.patch | 43 ++ .../0097-Add-Optional-Tick-Shuffling.patch | 43 ++ ...-Allow-Configuring-Chunks-per-Packet.patch | 38 ++ ...-Implement-Locale-Getter-for-Players.patch | 39 ++ .../0100-Cap-Entity-Collisions.patch | 66 +++ ...one-meal-not-having-the-correct-data.patch | 22 + .../0102-Spam-Filter-Exclusions.patch | 60 +++ ...tion-to-Silence-CommandBlock-Console.patch | 37 ++ ...-support-for-fetching-hidden-players.patch | 26 ++ ...Allow-Disabling-Creative-Item-Filter.patch | 37 ++ .../0106-Cap-Channel-Registrations.patch | 21 + ...mmands-to-be-the-main-version-of-a-c.patch | 174 ++++++++ ...-the-isDisconnected-method-by-bukkit.patch | 23 + ...-Implement-Silenceable-Lightning-API.patch | 105 +++++ ...spaces-on-when-reading-a-chat-packet.patch | 35 ++ ...rmissibleBase-for-all-Command-Blocks.patch | 33 ++ ...-Prevent-hoppers-from-loading-chunks.patch | 21 + .../0113-Guard-Entity-List.patch | 79 ++++ ...dificationException-while-being-idle.patch | 54 +++ ...ancellable-WitherSkull-potion-effect.patch | 36 ++ .../0116-Optimize-Player-Lookup.patch | 188 +++++++++ ...riptive-kick-reasons-instead-of-Nope.patch | 53 +++ ...nchanting-tables-to-enchant-any-item.patch | 34 ++ ...-lastChunkAccessed-if-it-is-unloaded.patch | 60 +++ ...ly-prefixed-commands-or-commands-tha.patch | 29 ++ ...-names-to-prevent-client-disconnects.patch | 21 + .../0122-Enable-Improved-Ping-Sending.patch | 65 +++ ...getOfflinePlayer-UUID-on-main-thread.patch | 21 + ...dragon-death-and-wither-spawn-sounds.patch | 70 +++ ...-getting-ticked-after-being-queued-f.patch | 38 ++ ...n-client-crashes-server-lists-and-Mo.patch | 23 + 113 files changed, 5701 insertions(+), 139 deletions(-) create mode 100644 CraftBukkit-Patches/0033-Allow-Disabling-of-Command-Logging.patch create mode 100644 CraftBukkit-Patches/0034-Allow-Disabling-of-Command-TabComplete.patch create mode 100644 CraftBukkit-Patches/0035-Configurable-Messages.patch create mode 100644 CraftBukkit-Patches/0036-Allow-Disabling-of-Random-Lighting-Updates.patch create mode 100644 CraftBukkit-Patches/0037-Make-AnvilInventory.getItem-use-both-containers.-Fix.patch create mode 100644 CraftBukkit-Patches/0038-Properly-Close-Inventories.patch create mode 100644 CraftBukkit-Patches/0039-Disallow-Interaction-With-Self.patch create mode 100644 CraftBukkit-Patches/0040-Lower-Chunk-Compression.patch create mode 100644 CraftBukkit-Patches/0041-Entity-Mount-and-Dismount-Events.patch create mode 100644 CraftBukkit-Patches/0042-Prevent-Ghost-Players-Caused-by-Plugins.patch create mode 100644 CraftBukkit-Patches/0043-Entity-ticking-chunk-caching.patch create mode 100644 CraftBukkit-Patches/0044-Plug-World-Unload-Memory-Leak.patch create mode 100644 CraftBukkit-Patches/0045-Player-Collision-API.patch create mode 100644 CraftBukkit-Patches/0046-Fully-Disable-Snooper-When-Not-Required.patch create mode 100644 CraftBukkit-Patches/0047-Add-Getter-for-Entity-Invulnerability.patch create mode 100644 CraftBukkit-Patches/0048-Cap-Minimum-Player-Speed.patch create mode 100644 CraftBukkit-Patches/0049-Update-Inventory-and-Health-for-PlayerConsumeItemEve.patch create mode 100644 CraftBukkit-Patches/0050-Call-EntityChangeBlockEvent-for-Fire-Arrows-hitting-.patch create mode 100644 CraftBukkit-Patches/0051-Allow-Disabling-of-1.6.3-Structure-Saving.patch create mode 100644 CraftBukkit-Patches/0052-Item-Despawn-Rate.patch create mode 100644 CraftBukkit-Patches/0053-Don-t-Special-Case-X-Move-Value.patch create mode 100644 CraftBukkit-Patches/0054-Implement-respawn-API.patch create mode 100644 CraftBukkit-Patches/0055-Fix-BrewingStands-Removing-NBT-Potions.patch create mode 100644 CraftBukkit-Patches/0056-Arrow-Despawn-Rate.patch create mode 100644 CraftBukkit-Patches/0057-Watchdog-Thread.patch create mode 100644 CraftBukkit-Patches/0058-Fix-packed-ice-generation.patch create mode 100644 CraftBukkit-Patches/0059-Clear-Flower-Pot-on-Drop.patch create mode 100644 CraftBukkit-Patches/0060-Fix-some-chunks-not-being-sent-to-the-client.patch create mode 100644 CraftBukkit-Patches/0061-Fix-Broken-Async-Chat.patch create mode 100644 CraftBukkit-Patches/0062-Allow-Teleportation-of-Vehicles-and-Passengers.patch create mode 100644 CraftBukkit-Patches/0063-Remove-OS-X-Special-Chars-from-Signs.patch create mode 100644 CraftBukkit-Patches/0064-Orebfuscator.patch create mode 100644 CraftBukkit-Patches/0065-Optimize-DataWatcher.patch create mode 100644 CraftBukkit-Patches/0066-Fire-PreLogin-Events-in-Offline-Mode.patch create mode 100644 CraftBukkit-Patches/0067-BungeeCord-Support.patch create mode 100644 CraftBukkit-Patches/0068-Allow-Disabling-Zombie-Villager-Aggression.patch create mode 100644 CraftBukkit-Patches/0069-Configurable-Amount-of-Netty-Threads.patch create mode 100644 CraftBukkit-Patches/0070-Prevent-Mineshaft-Saving.patch create mode 100644 CraftBukkit-Patches/0071-Log-Cause-of-Unexpected-Exceptions.patch create mode 100644 CraftBukkit-Patches/0072-Particle-API.patch create mode 100644 CraftBukkit-Patches/0073-Fix-Biome-Decoration-Crashes.patch create mode 100644 CraftBukkit-Patches/0074-Save-ticks-lived-to-nbttag.patch create mode 100644 CraftBukkit-Patches/0075-More-Efficient-GetCubes.patch create mode 100644 CraftBukkit-Patches/0076-Add-Option-to-Nerf-Mobs-from-Spawner-s.patch create mode 100644 CraftBukkit-Patches/0077-Warn-if-PermGen-may-be-insufficient.patch create mode 100644 CraftBukkit-Patches/0078-Disable-Connected-Check-on-setScoreboard.patch create mode 100644 CraftBukkit-Patches/0079-Add-Late-Bind-Option.patch create mode 100644 CraftBukkit-Patches/0080-Update-Chest-Animation-when-Cancelling-Event.patch create mode 100644 CraftBukkit-Patches/0081-Update-Client-s-Hand-when-BlockPlaceEvent-Cancelled.patch create mode 100644 CraftBukkit-Patches/0082-Allow-statistics-to-be-disabled-forced.patch create mode 100644 CraftBukkit-Patches/0083-Fix-anvil-collisions.patch create mode 100644 CraftBukkit-Patches/0084-Fix-ItemStack-Unbreakable-Code.patch create mode 100644 CraftBukkit-Patches/0085-Try-and-Debug-Crash-Reports-Crashing.patch create mode 100644 CraftBukkit-Patches/0086-Replace-AutoSave-Mechanism.patch create mode 100644 CraftBukkit-Patches/0087-Block-data-values-that-crash-the-client.patch create mode 100644 CraftBukkit-Patches/0088-Support-vanilla-s-direction-tag-on-fireballs.patch create mode 100644 CraftBukkit-Patches/0089-Support-non-prefixed-URLs.patch create mode 100644 CraftBukkit-Patches/0090-Catch-stalling-on-corrupted-map-data-NBT-arrays.patch create mode 100644 CraftBukkit-Patches/0091-Reduce-memory-of-hiddenPlayers-map.patch create mode 100644 CraftBukkit-Patches/0092-Allow-toggling-of-ZombiePigmen-spawning-in-portal-bl.patch create mode 100644 CraftBukkit-Patches/0093-Don-t-let-trees-replace-any-block-when-growing.patch create mode 100644 CraftBukkit-Patches/0094-Highly-Optimized-Tick-Loop.patch create mode 100644 CraftBukkit-Patches/0095-Add-Spigot-Links.patch create mode 100644 CraftBukkit-Patches/0096-Configurable-Ping-Sample-Size.patch create mode 100644 CraftBukkit-Patches/0097-Add-Optional-Tick-Shuffling.patch create mode 100644 CraftBukkit-Patches/0098-Allow-Configuring-Chunks-per-Packet.patch create mode 100644 CraftBukkit-Patches/0099-Implement-Locale-Getter-for-Players.patch create mode 100644 CraftBukkit-Patches/0100-Cap-Entity-Collisions.patch create mode 100644 CraftBukkit-Patches/0101-Fix-dispensing-bone-meal-not-having-the-correct-data.patch create mode 100644 CraftBukkit-Patches/0102-Spam-Filter-Exclusions.patch create mode 100644 CraftBukkit-Patches/0103-Add-Option-to-Silence-CommandBlock-Console.patch create mode 100644 CraftBukkit-Patches/0104-Add-support-for-fetching-hidden-players.patch create mode 100644 CraftBukkit-Patches/0105-Allow-Disabling-Creative-Item-Filter.patch create mode 100644 CraftBukkit-Patches/0106-Cap-Channel-Registrations.patch create mode 100644 CraftBukkit-Patches/0107-Allow-vanilla-commands-to-be-the-main-version-of-a-c.patch create mode 100644 CraftBukkit-Patches/0108-Unfinalize-the-isDisconnected-method-by-bukkit.patch create mode 100644 CraftBukkit-Patches/0109-Implement-Silenceable-Lightning-API.patch create mode 100644 CraftBukkit-Patches/0110-Normalize-spaces-on-when-reading-a-chat-packet.patch create mode 100644 CraftBukkit-Patches/0111-Use-one-PermissibleBase-for-all-Command-Blocks.patch create mode 100644 CraftBukkit-Patches/0112-Prevent-hoppers-from-loading-chunks.patch create mode 100644 CraftBukkit-Patches/0113-Guard-Entity-List.patch create mode 100644 CraftBukkit-Patches/0114-Fix-ConcurrentModificationException-while-being-idle.patch create mode 100644 CraftBukkit-Patches/0115-Cancellable-WitherSkull-potion-effect.patch create mode 100644 CraftBukkit-Patches/0116-Optimize-Player-Lookup.patch create mode 100644 CraftBukkit-Patches/0117-Descriptive-kick-reasons-instead-of-Nope.patch create mode 100644 CraftBukkit-Patches/0118-Allow-enchanting-tables-to-enchant-any-item.patch create mode 100644 CraftBukkit-Patches/0119-Remove-the-lastChunkAccessed-if-it-is-unloaded.patch create mode 100644 CraftBukkit-Patches/0120-Check-for-manually-prefixed-commands-or-commands-tha.patch create mode 100644 CraftBukkit-Patches/0121-Cap-window-names-to-prevent-client-disconnects.patch create mode 100644 CraftBukkit-Patches/0122-Enable-Improved-Ping-Sending.patch create mode 100644 CraftBukkit-Patches/0123-Prevent-getOfflinePlayer-UUID-on-main-thread.patch create mode 100644 CraftBukkit-Patches/0124-Configurable-dragon-death-and-wither-spawn-sounds.patch create mode 100644 CraftBukkit-Patches/0125-Fix-TileEntities-getting-ticked-after-being-queued-f.patch create mode 100644 CraftBukkit-Patches/0126-Display-Spigot-in-client-crashes-server-lists-and-Mo.patch diff --git a/Bukkit b/Bukkit index 5011115726..8c0271cf92 160000 --- a/Bukkit +++ b/Bukkit @@ -1 +1 @@ -Subproject commit 50111157262d31a3b8cd5e63f5478db8139b843a +Subproject commit 8c0271cf92140cd4789750426858beb39a1dd89a diff --git a/Bukkit-Patches/0001-POM-Changes.patch b/Bukkit-Patches/0001-POM-Changes.patch index 614a1b353a..d8593cdeaf 100644 --- a/Bukkit-Patches/0001-POM-Changes.patch +++ b/Bukkit-Patches/0001-POM-Changes.patch @@ -1,11 +1,11 @@ -From beab590a7013a5a335792c7dea8fc8569c304be5 Mon Sep 17 00:00:00 2001 +From 2a8bbf154f5283abc9ed94eabf0c47dfa54c07c7 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 2 Jun 2013 10:36:24 +1000 Subject: [PATCH] POM Changes diff --git a/pom.xml b/pom.xml -index a14b55e..b2f4efb 100644 +index ec3d67d..cc5863e 100644 --- a/pom.xml +++ b/pom.xml @@ -1,43 +1,23 @@ @@ -23,7 +23,7 @@ index a14b55e..b2f4efb 100644 + + org.spigotmc + spigot-api - 1.7.5-R0.1-SNAPSHOT + 1.7.8-R0.1-SNAPSHOT - Bukkit - http://www.bukkit.org + Spigot-API @@ -65,5 +65,5 @@ index a14b55e..b2f4efb 100644 -- -1.8.5.2.msysgit.0 +1.8.3.2 diff --git a/Bukkit-Patches/0025-Remove-deprecation-on-some-player-lookup-methods.patch b/Bukkit-Patches/0025-Remove-deprecation-on-some-player-lookup-methods.patch index 31fd3fbc31..d259af7ca3 100644 --- a/Bukkit-Patches/0025-Remove-deprecation-on-some-player-lookup-methods.patch +++ b/Bukkit-Patches/0025-Remove-deprecation-on-some-player-lookup-methods.patch @@ -1,4 +1,4 @@ -From e82a54ab86950b4d22601fc3bda15c2df118142c Mon Sep 17 00:00:00 2001 +From 41d28d22d8a37fe2c9f24c0decf7cf34d863ac26 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 30 Mar 2014 15:58:22 +1100 Subject: [PATCH] Remove deprecation on some player lookup methods @@ -25,24 +25,8 @@ index 6b9c9f3..7d8736e 100644 public static List matchPlayer(String name) { return server.matchPlayer(name); } -diff --git a/src/main/java/org/bukkit/OfflinePlayer.java b/src/main/java/org/bukkit/OfflinePlayer.java -index cbf8746..d726cd6 100644 ---- a/src/main/java/org/bukkit/OfflinePlayer.java -+++ b/src/main/java/org/bukkit/OfflinePlayer.java -@@ -20,11 +20,8 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio - /** - * Returns the name of this player - * -- * @deprecated Use {@link #getUniqueId()} as player names are no longer -- * guaranteed to be unique - * @return Player name - */ -- @Deprecated - public String getName(); - - /** diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index d2cb517..d745dfb 100644 +index 22dc74a..6b21ea1 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java @@ -268,23 +268,17 @@ public interface Server extends PluginMessageRecipient { diff --git a/CraftBukkit b/CraftBukkit index 8f8716c3b7..3762cc2694 160000 --- a/CraftBukkit +++ b/CraftBukkit @@ -1 +1 @@ -Subproject commit 8f8716c3b73776664ddaf30adf2b7288ffe3ef04 +Subproject commit 3762cc269480697083ad9f6bbed99a0551f17979 diff --git a/CraftBukkit-Patches/0001-POM-Changes.patch b/CraftBukkit-Patches/0001-POM-Changes.patch index 632040a5c0..6cb96b4b46 100644 --- a/CraftBukkit-Patches/0001-POM-Changes.patch +++ b/CraftBukkit-Patches/0001-POM-Changes.patch @@ -1,11 +1,11 @@ -From ed66642c321aa6ad8376ccafed67c0da3d4ae331 Mon Sep 17 00:00:00 2001 +From 0201039c8f4f9a6a4cefc836b6d5866a4e10fae0 Mon Sep 17 00:00:00 2001 From: md_5 Date: Tue, 2 Jul 2013 13:07:39 +1000 Subject: [PATCH] POM Changes diff --git a/pom.xml b/pom.xml -index 9f81af0..c8285e0 100644 +index 3d4395d..2b14bef 100644 --- a/pom.xml +++ b/pom.xml @@ -1,12 +1,20 @@ @@ -25,7 +25,7 @@ index 9f81af0..c8285e0 100644 + org.spigotmc + spigot jar - 1.7.5-R0.1-SNAPSHOT + 1.7.8-R0.1-SNAPSHOT - CraftBukkit - http://www.bukkit.org + Spigot @@ -142,7 +142,7 @@ index 9f81af0..c8285e0 100644 package diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 2b5aa31..9c81339 100644 +index 748d887..adeab3f 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -303,7 +303,7 @@ public final class CraftServer implements Server { diff --git a/CraftBukkit-Patches/0003-Skeleton-API-Implementations.patch b/CraftBukkit-Patches/0003-Skeleton-API-Implementations.patch index 7d795a1e40..842f99ec39 100644 --- a/CraftBukkit-Patches/0003-Skeleton-API-Implementations.patch +++ b/CraftBukkit-Patches/0003-Skeleton-API-Implementations.patch @@ -1,4 +1,4 @@ -From e8ce89003cc2749ce11e09334e83f57a4b568f3e Mon Sep 17 00:00:00 2001 +From 5e6467660d83b7174501637b4196fb749aead8cd Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 2 Jun 2013 15:10:56 +1000 Subject: [PATCH] Skeleton API Implementations @@ -64,10 +64,10 @@ index fe0f200..e026c1f 100644 + // Spigot end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 17c16dc..3fbbb06 100644 +index b5a54c8..c1d3118 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1275,4 +1275,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1285,4 +1285,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } collection.add(new AttributeModifiable(getHandle().bb(), (new AttributeRanged("generic.maxHealth", scaledHealth ? healthScale : getMaxHealth(), 0.0D, Float.MAX_VALUE)).a("Max Health").a(true))); } @@ -84,5 +84,5 @@ index 17c16dc..3fbbb06 100644 + // Spigot end } -- -1.8.5.2.msysgit.0 +1.8.3.2 diff --git a/CraftBukkit-Patches/0004-Spigot-Configuration.patch b/CraftBukkit-Patches/0004-Spigot-Configuration.patch index 5c4c9a87ce..92bcbae26b 100644 --- a/CraftBukkit-Patches/0004-Spigot-Configuration.patch +++ b/CraftBukkit-Patches/0004-Spigot-Configuration.patch @@ -1,15 +1,15 @@ -From bac9d8f7fd5947eac549d30f8354f34e74919248 Mon Sep 17 00:00:00 2001 +From 3f08230723b80338c17bb46ad0eaaa2b4ef184a4 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 7 Jul 2013 09:32:53 +1000 Subject: [PATCH] Spigot Configuration diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java -index 1b05fbf..7946703 100644 +index 9cef53f..74e28cc 100644 --- a/src/main/java/net/minecraft/server/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/DedicatedServer.java @@ -109,6 +109,11 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer - if (this.K() < 0) { + if (this.L() < 0) { this.setPort(this.propertyManager.getInt("server-port", 25565)); } + // Spigot start @@ -18,7 +18,7 @@ index 1b05fbf..7946703 100644 + org.spigotmc.SpigotConfig.registerCommands(); + // Spigot end - h.info("Generating keypair"); + i.info("Generating keypair"); this.a(MinecraftEncryption.b()); @@ -123,7 +128,11 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer return false; @@ -32,12 +32,12 @@ index 1b05fbf..7946703 100644 + // Spigot End if (!this.getOnlineMode()) { - h.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!"); + i.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!"); diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 2f514b5..96a3eb8 100644 +index 0f97f78..13c0500 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -106,6 +106,7 @@ public abstract class World implements IBlockAccess { +@@ -107,6 +107,7 @@ public abstract class World implements IBlockAccess { int lastXAccessed = Integer.MIN_VALUE; int lastZAccessed = Integer.MIN_VALUE; final Object chunkLock = new Object(); @@ -45,7 +45,7 @@ index 2f514b5..96a3eb8 100644 public CraftWorld getWorld() { return this.world; -@@ -117,6 +118,7 @@ public abstract class World implements IBlockAccess { +@@ -118,6 +119,7 @@ public abstract class World implements IBlockAccess { // Changed signature - added gen and env public World(IDataManager idatamanager, String s, WorldSettings worldsettings, WorldProvider worldprovider, MethodProfiler methodprofiler, ChunkGenerator gen, org.bukkit.World.Environment env) { @@ -54,7 +54,7 @@ index 2f514b5..96a3eb8 100644 this.world = new CraftWorld((WorldServer) this, gen, env); this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 9c81339..aa76abe 100644 +index adeab3f..3a72f25 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -309,8 +309,10 @@ public final class CraftServer implements Server { @@ -72,7 +72,7 @@ index 9c81339..aa76abe 100644 public boolean getCommandBlockOverride(String command) { @@ -736,6 +738,7 @@ public final class CraftServer implements Server { playerList.getIPBans().load(); - playerList.getNameBans().load(); + playerList.getProfileBans().load(); + org.spigotmc.SpigotConfig.init(); // Spigot for (WorldServer world : console.worlds) { diff --git a/CraftBukkit-Patches/0005-Better-Chunk-Tick-Selection.patch b/CraftBukkit-Patches/0005-Better-Chunk-Tick-Selection.patch index f9c5fc1296..82f71246ed 100644 --- a/CraftBukkit-Patches/0005-Better-Chunk-Tick-Selection.patch +++ b/CraftBukkit-Patches/0005-Better-Chunk-Tick-Selection.patch @@ -1,14 +1,14 @@ -From 8fe65d8a9c999b2ebca1f63634de6a03d83d2f39 Mon Sep 17 00:00:00 2001 +From b532ab301efdcaa616bdfb70ab71cf81f838f2e3 Mon Sep 17 00:00:00 2001 From: md_5 Date: Tue, 11 Jun 2013 12:56:02 +1000 Subject: [PATCH] Better Chunk Tick Selection diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 96a3eb8..9dc2d73 100644 +index 13c0500..9d275b3 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -60,7 +60,7 @@ public abstract class World implements IBlockAccess { +@@ -61,7 +61,7 @@ public abstract class World implements IBlockAccess { public Scoreboard scoreboard = new Scoreboard(); // CraftBukkit - protected -> public public boolean isStatic; // CraftBukkit start - public, longhashset @@ -17,7 +17,7 @@ index 96a3eb8..9dc2d73 100644 private int K; public boolean allowMonsters; public boolean allowAnimals; -@@ -75,6 +75,30 @@ public abstract class World implements IBlockAccess { +@@ -76,6 +76,30 @@ public abstract class World implements IBlockAccess { private boolean M; int[] I; @@ -48,7 +48,7 @@ index 96a3eb8..9dc2d73 100644 public BiomeBase getBiome(int i, int j) { if (this.isLoaded(i, 0, j)) { Chunk chunk = this.getChunkAtWorldCoords(i, j); -@@ -124,6 +148,11 @@ public abstract class World implements IBlockAccess { +@@ -125,6 +149,11 @@ public abstract class World implements IBlockAccess { this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit this.ticksPerMonsterSpawns = this.getServer().getTicksPerMonsterSpawns(); // CraftBukkit // CraftBukkit end @@ -60,7 +60,7 @@ index 96a3eb8..9dc2d73 100644 this.K = this.random.nextInt(12000); this.allowMonsters = true; -@@ -1914,24 +1943,44 @@ public abstract class World implements IBlockAccess { +@@ -1915,24 +1944,44 @@ public abstract class World implements IBlockAccess { int k; int l; @@ -116,10 +116,10 @@ index 96a3eb8..9dc2d73 100644 this.methodProfiler.b(); diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 4e0861e..acb0be1 100644 +index 843761a..01d7105 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -306,10 +306,20 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate +@@ -307,10 +307,20 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate // CraftBukkit start // Iterator iterator = this.chunkTickList.iterator(); @@ -143,7 +143,7 @@ index 4e0861e..acb0be1 100644 int k = chunkX * 16; int l = chunkZ * 16; -@@ -400,6 +410,7 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate +@@ -401,6 +411,7 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate if (block.isTicking()) { ++i; @@ -151,7 +151,7 @@ index 4e0861e..acb0be1 100644 block.a(this, k2 + k, i3 + chunksection.getYPosition(), l2 + l, this.random); } } -@@ -408,6 +419,12 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate +@@ -409,6 +420,12 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate this.methodProfiler.b(); } @@ -185,5 +185,5 @@ index 961ddb4..90a227f 100644 + } } -- -1.8.5.2.msysgit.0 +1.8.3.2 diff --git a/CraftBukkit-Patches/0007-More-Efficient-Chunk-Save-Queue.patch b/CraftBukkit-Patches/0007-More-Efficient-Chunk-Save-Queue.patch index 5f023a998f..a811890ff3 100644 --- a/CraftBukkit-Patches/0007-More-Efficient-Chunk-Save-Queue.patch +++ b/CraftBukkit-Patches/0007-More-Efficient-Chunk-Save-Queue.patch @@ -1,14 +1,14 @@ -From 7411c0dc59ef739de9b28c5d526962c65f39692c Mon Sep 17 00:00:00 2001 +From 4b8464a3c11cd4f4180df88a50d805e6aad0b7b9 Mon Sep 17 00:00:00 2001 From: md_5 Date: Tue, 11 Jun 2013 12:09:45 +1000 Subject: [PATCH] More Efficient Chunk Save Queue diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java -index d5cf88d..1e1499e 100644 +index 26bafe0..49acc9a 100644 --- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java +++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java -@@ -16,6 +16,7 @@ import org.apache.logging.log4j.Logger; +@@ -15,6 +15,7 @@ import org.apache.logging.log4j.Logger; public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { @@ -16,7 +16,7 @@ index d5cf88d..1e1499e 100644 private static final Logger a = LogManager.getLogger(); private List b = new ArrayList(); private Set c = new HashSet(); -@@ -31,13 +32,11 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { +@@ -30,13 +31,11 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j); synchronized (this.d) { @@ -35,7 +35,7 @@ index d5cf88d..1e1499e 100644 } return RegionFileCache.a(this.e, i, j).chunkExists(i & 31, j & 31); -@@ -64,14 +63,12 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { +@@ -63,14 +62,12 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { Object object = this.d; synchronized (this.d) { @@ -55,7 +55,7 @@ index d5cf88d..1e1499e 100644 } if (nbttagcompound == null) { -@@ -151,17 +148,11 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { +@@ -150,17 +147,11 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { Object object = this.d; synchronized (this.d) { @@ -77,7 +77,7 @@ index d5cf88d..1e1499e 100644 FileIOThread.a.a(this); } } -@@ -171,12 +162,14 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { +@@ -170,12 +161,14 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { Object object = this.d; synchronized (this.d) { diff --git a/CraftBukkit-Patches/0008-Merge-tweaks-and-configuration.patch b/CraftBukkit-Patches/0008-Merge-tweaks-and-configuration.patch index d411d81623..1de031bd94 100644 --- a/CraftBukkit-Patches/0008-Merge-tweaks-and-configuration.patch +++ b/CraftBukkit-Patches/0008-Merge-tweaks-and-configuration.patch @@ -1,4 +1,4 @@ -From 518136605c7088117a448666a234b09d6e40b60f Mon Sep 17 00:00:00 2001 +From 3c8d3ae7d02a158f91498a5dd3bcf32283938fb8 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 23 Mar 2013 09:46:33 +1100 Subject: [PATCH] Merge tweaks and configuration @@ -41,10 +41,10 @@ index 8343ac9..95beb11 100644 } } else { diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 9dc2d73..d023889 100644 +index 9d275b3..edf229b 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -931,6 +931,23 @@ public abstract class World implements IBlockAccess { +@@ -932,6 +932,23 @@ public abstract class World implements IBlockAccess { // Not all projectiles extend EntityProjectile, so check for Bukkit interface instead event = CraftEventFactory.callProjectileLaunchEvent(entity); } @@ -92,5 +92,5 @@ index 7e79ba5..1545a61 100644 + } } -- -1.8.5.2.msysgit.0 +1.8.3.2 diff --git a/CraftBukkit-Patches/0010-Async-Operation-Catching.patch b/CraftBukkit-Patches/0010-Async-Operation-Catching.patch index a62ab22e11..5b8e178647 100644 --- a/CraftBukkit-Patches/0010-Async-Operation-Catching.patch +++ b/CraftBukkit-Patches/0010-Async-Operation-Catching.patch @@ -1,4 +1,4 @@ -From b89dc9528c1550605eb17523a2789b50e7ae2ac7 Mon Sep 17 00:00:00 2001 +From 4507c064694b49ed2a2e7594d0efe82e882c5f8d Mon Sep 17 00:00:00 2001 From: md_5 Date: Tue, 25 Mar 2014 16:10:01 +1100 Subject: [PATCH] Async Operation Catching @@ -26,7 +26,7 @@ index 51f8279..aaead32 100644 public int a(Random random) { return 1; diff --git a/src/main/java/net/minecraft/server/EntityTracker.java b/src/main/java/net/minecraft/server/EntityTracker.java -index af440b9..8f291c2 100644 +index 1af0e67..70b0181 100644 --- a/src/main/java/net/minecraft/server/EntityTracker.java +++ b/src/main/java/net/minecraft/server/EntityTracker.java @@ -91,6 +91,7 @@ public class EntityTracker { @@ -66,10 +66,10 @@ index c148c4d..a2b54a4 100644 this.trackedPlayers.remove(entityplayer); entityplayer.d(this.tracker); diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index d023889..19654b4 100644 +index edf229b..146285f 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -900,6 +900,7 @@ public abstract class World implements IBlockAccess { +@@ -901,6 +901,7 @@ public abstract class World implements IBlockAccess { } public boolean addEntity(Entity entity, SpawnReason spawnReason) { // Changed signature, added SpawnReason @@ -77,7 +77,7 @@ index d023889..19654b4 100644 if (entity == null) return false; // CraftBukkit end -@@ -1006,6 +1007,7 @@ public abstract class World implements IBlockAccess { +@@ -1007,6 +1008,7 @@ public abstract class World implements IBlockAccess { } public void removeEntity(Entity entity) { @@ -85,7 +85,7 @@ index d023889..19654b4 100644 entity.die(); if (entity instanceof EntityHuman) { this.players.remove(entity); -@@ -2390,6 +2392,7 @@ public abstract class World implements IBlockAccess { +@@ -2391,6 +2393,7 @@ public abstract class World implements IBlockAccess { } public void a(List list) { @@ -122,10 +122,10 @@ index d9fbd00..bfa8c23 100644 if (generate) { // Use the default variant of loadChunk when generate == true. diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 3fbbb06..3fee3e8 100644 +index c1d3118..8a09d97 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -232,6 +232,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -238,6 +238,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void kickPlayer(String message) { @@ -169,5 +169,5 @@ index 0000000..4b3aa85 + } +} -- -1.8.5.2.msysgit.0 +1.8.3.2 diff --git a/CraftBukkit-Patches/0011-View-Distance.patch b/CraftBukkit-Patches/0011-View-Distance.patch index f84e2412b8..049ca7ad94 100644 --- a/CraftBukkit-Patches/0011-View-Distance.patch +++ b/CraftBukkit-Patches/0011-View-Distance.patch @@ -1,4 +1,4 @@ -From b91e5c3c9cede186bb62220412d219e11635edd3 Mon Sep 17 00:00:00 2001 +From e4c6f8043272f1445be4b11e8fdf061804736330 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 23 Mar 2013 09:52:41 +1100 Subject: [PATCH] View Distance @@ -6,7 +6,7 @@ Subject: [PATCH] View Distance This commit allows the user to select per world view distances, and view distances below 3. Be wary of the issues selecting a view distance of 1 or 2 may cause! diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 90776db..cc1b095 100644 +index ae53635..cc1b095 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -26,9 +26,9 @@ public class PlayerChunkMap { @@ -16,16 +16,16 @@ index 90776db..cc1b095 100644 - public PlayerChunkMap(WorldServer worldserver) { + public PlayerChunkMap(WorldServer worldserver, int viewDistance /* Spigot */) { this.world = worldserver; -- this.a(worldserver.getMinecraftServer().getPlayerList().o()); +- this.a(worldserver.getMinecraftServer().getPlayerList().s()); + this.a(viewDistance); // Spigot } public WorldServer a() { diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index acb0be1..0c24d9a 100644 +index 01d7105..0192dc5 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -54,7 +54,7 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate +@@ -55,7 +55,7 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate // CraftBukkit end this.server = minecraftserver; this.tracker = new EntityTracker(this); @@ -51,5 +51,5 @@ index 1545a61..6cc3a91 100644 + } } -- -1.8.5.2.msysgit.0 +1.8.3.2 diff --git a/CraftBukkit-Patches/0012-Compressed-Nibble-Arrays.patch b/CraftBukkit-Patches/0012-Compressed-Nibble-Arrays.patch index 387d1b6bc3..f433449b38 100644 --- a/CraftBukkit-Patches/0012-Compressed-Nibble-Arrays.patch +++ b/CraftBukkit-Patches/0012-Compressed-Nibble-Arrays.patch @@ -1,4 +1,4 @@ -From 0a13c4fb7028e62e617345314f93e3c2f06e4971 Mon Sep 17 00:00:00 2001 +From 11ccd89a600d948d769e7f16fd841d0e7bee04c4 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Sun, 13 Jan 2013 03:49:07 -0800 Subject: [PATCH] Compressed Nibble Arrays @@ -12,10 +12,10 @@ Finish up NibbleArray lightening work - use for Snapshots, reduce copies Fix nibble handling with NBT - arrays aren't copied by NBTByteArray diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java -index 1e1499e..76b081a 100644 +index 49acc9a..ce7a8bf 100644 --- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java +++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java -@@ -225,15 +225,15 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { +@@ -224,15 +224,15 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { nbttagcompound1.setByte("Y", (byte) (chunksection.getYPosition() >> 4 & 255)); nbttagcompound1.setByteArray("Blocks", chunksection.getIdArray()); if (chunksection.getExtendedIdArray() != null) { diff --git a/CraftBukkit-Patches/0013-Sync-Free-Chunk-Reference-Cache.patch b/CraftBukkit-Patches/0013-Sync-Free-Chunk-Reference-Cache.patch index 7d695ed3fb..7200c79910 100644 --- a/CraftBukkit-Patches/0013-Sync-Free-Chunk-Reference-Cache.patch +++ b/CraftBukkit-Patches/0013-Sync-Free-Chunk-Reference-Cache.patch @@ -1,14 +1,14 @@ -From e35b3899f68a3f8d2563a5c31d4d4370d57c0e54 Mon Sep 17 00:00:00 2001 +From 20d63175f20fd319c840616a9de5bf917030e184 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Wed, 16 Jan 2013 15:27:22 -0600 Subject: [PATCH] Sync Free Chunk Reference Cache diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 1ed1e27..d2679dc 100644 +index 146285f..5ea860f 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -291,20 +291,18 @@ public abstract class World implements IBlockAccess { +@@ -292,20 +292,18 @@ public abstract class World implements IBlockAccess { return this.getChunkAt(i >> 4, j >> 4); } @@ -38,5 +38,5 @@ index 1ed1e27..d2679dc 100644 public boolean setTypeAndData(int i, int j, int k, Block block, int l, int i1) { if (i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000) { -- -1.8.5.2.msysgit.0 +1.8.3.2 diff --git a/CraftBukkit-Patches/0014-Improved-Timings-System.patch b/CraftBukkit-Patches/0014-Improved-Timings-System.patch index 5f6b54c0b6..ca3a2318e2 100644 --- a/CraftBukkit-Patches/0014-Improved-Timings-System.patch +++ b/CraftBukkit-Patches/0014-Improved-Timings-System.patch @@ -1,4 +1,4 @@ -From 27707ff83ec487195342dfbc2aef269f265be531 Mon Sep 17 00:00:00 2001 +From 804169785fae027e5c3fb669fd06ab046b4d0a02 Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 10 Jan 2013 00:18:11 -0500 Subject: [PATCH] Improved Timings System @@ -6,10 +6,10 @@ Subject: [PATCH] Improved Timings System Tracks nearly every point of minecraft internals and plugin events to give a good quick overview on what is causing TPS loss. diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index 5b3c821..7f19bec 100644 +index 1b22934..b669d05 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java -@@ -132,6 +132,7 @@ public class ChunkProviderServer implements IChunkProvider { +@@ -133,6 +133,7 @@ public class ChunkProviderServer implements IChunkProvider { boolean newChunk = false; if (chunk == null) { @@ -17,7 +17,7 @@ index 5b3c821..7f19bec 100644 chunk = this.loadChunk(i, j); if (chunk == null) { if (this.chunkProvider == null) { -@@ -167,6 +168,7 @@ public class ChunkProviderServer implements IChunkProvider { +@@ -168,6 +169,7 @@ public class ChunkProviderServer implements IChunkProvider { } // CraftBukkit end chunk.a(this, this, i, j); @@ -65,10 +65,10 @@ index 9d933cb..491ef6b 100644 protected String G() { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 6788c5d..8f61474 100644 +index 00bb455..ac2aad8 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -36,6 +36,7 @@ import jline.console.ConsoleReader; +@@ -37,6 +37,7 @@ import jline.console.ConsoleReader; import joptsimple.OptionSet; import org.bukkit.World.Environment; @@ -76,7 +76,7 @@ index 6788c5d..8f61474 100644 import org.bukkit.craftbukkit.util.Waitable; import org.bukkit.event.server.RemoteServerCommandEvent; import org.bukkit.event.world.WorldSaveEvent; -@@ -535,6 +536,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo +@@ -545,6 +546,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo protected void t() {} protected void u() throws ExceptionWorldConflict { // CraftBukkit - added throws @@ -84,7 +84,7 @@ index 6788c5d..8f61474 100644 long i = System.nanoTime(); ++this.ticks; -@@ -586,6 +588,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo +@@ -596,6 +598,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo public void v() { this.methodProfiler.a("levels"); @@ -92,7 +92,7 @@ index 6788c5d..8f61474 100644 // CraftBukkit start this.server.getScheduler().mainThreadHeartbeat(this.ticks); -@@ -594,7 +597,10 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo +@@ -604,7 +607,10 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo processQueue.remove().run(); } @@ -103,7 +103,7 @@ index 6788c5d..8f61474 100644 // Send time updates to everyone, it will get the right time from the world the player is in. if (this.ticks % 20 == 0) { -@@ -645,7 +651,9 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo +@@ -655,7 +661,9 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo this.methodProfiler.b(); this.methodProfiler.a("tracker"); @@ -113,22 +113,22 @@ index 6788c5d..8f61474 100644 this.methodProfiler.b(); this.methodProfiler.b(); // } // CraftBukkit -@@ -654,16 +662,24 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo +@@ -664,16 +672,24 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo } this.methodProfiler.c("connection"); + SpigotTimings.connectionTimer.startTiming(); // Spigot - this.ah().c(); + this.ai().c(); + SpigotTimings.connectionTimer.stopTiming(); // Spigot this.methodProfiler.c("players"); + SpigotTimings.playerListTimer.startTiming(); // Spigot - this.t.tick(); + this.u.tick(); + SpigotTimings.playerListTimer.stopTiming(); // Spigot this.methodProfiler.c("tickables"); + SpigotTimings.tickablesTimer.startTiming(); // Spigot - for (i = 0; i < this.m.size(); ++i) { - ((IUpdatePlayerListBox) this.m.get(i)).a(); + for (i = 0; i < this.n.size(); ++i) { + ((IUpdatePlayerListBox) this.n.get(i)).a(); } + SpigotTimings.tickablesTimer.stopTiming(); // Spigot @@ -139,10 +139,10 @@ index 6788c5d..8f61474 100644 public boolean getAllowNether() { diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -index 10c2ee7..22c75f9 100644 +index 946681d..f34fd03 100644 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java -@@ -937,6 +937,7 @@ public class PlayerConnection implements PacketPlayInListener { +@@ -938,6 +938,7 @@ public class PlayerConnection implements PacketPlayInListener { // CraftBukkit end private void handleCommand(String s) { @@ -150,7 +150,7 @@ index 10c2ee7..22c75f9 100644 // CraftBukkit start - whole method CraftPlayer player = this.getPlayer(); -@@ -944,19 +945,23 @@ public class PlayerConnection implements PacketPlayInListener { +@@ -945,19 +946,23 @@ public class PlayerConnection implements PacketPlayInListener { this.server.getPluginManager().callEvent(event); if (event.isCancelled()) { @@ -192,10 +192,10 @@ index 2a3d647..78e17d7 100644 private static Map i = new HashMap(); private static Map j = new HashMap(); diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index d2679dc..7360dfc 100644 +index 5ea860f..7ead630 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -14,6 +14,7 @@ import java.util.concurrent.Callable; +@@ -15,6 +15,7 @@ import java.util.concurrent.Callable; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.craftbukkit.util.LongHashSet; @@ -203,7 +203,7 @@ index d2679dc..7360dfc 100644 import org.bukkit.generator.ChunkGenerator; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.CraftWorld; -@@ -132,6 +133,8 @@ public abstract class World implements IBlockAccess { +@@ -133,6 +134,8 @@ public abstract class World implements IBlockAccess { final Object chunkLock = new Object(); public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot @@ -212,7 +212,7 @@ index d2679dc..7360dfc 100644 public CraftWorld getWorld() { return this.world; } -@@ -211,6 +214,7 @@ public abstract class World implements IBlockAccess { +@@ -212,6 +215,7 @@ public abstract class World implements IBlockAccess { this.a(); this.getServer().addWorld(this.world); // CraftBukkit @@ -220,7 +220,7 @@ index d2679dc..7360dfc 100644 } protected abstract IChunkProvider j(); -@@ -1236,6 +1240,7 @@ public abstract class World implements IBlockAccess { +@@ -1237,6 +1241,7 @@ public abstract class World implements IBlockAccess { this.f.clear(); this.methodProfiler.c("regular"); @@ -228,7 +228,7 @@ index d2679dc..7360dfc 100644 // CraftBukkit start - Use field for loop variable for (this.tickPosition = 0; this.tickPosition < this.entityList.size(); ++this.tickPosition) { entity = (Entity) this.entityList.get(this.tickPosition); -@@ -1259,7 +1264,9 @@ public abstract class World implements IBlockAccess { +@@ -1260,7 +1265,9 @@ public abstract class World implements IBlockAccess { this.methodProfiler.a("tick"); if (!entity.dead) { try { @@ -238,7 +238,7 @@ index d2679dc..7360dfc 100644 } catch (Throwable throwable1) { crashreport = CrashReport.a(throwable1, "Ticking entity"); crashreportsystemdetails = crashreport.a("Entity being ticked"); -@@ -1284,7 +1291,9 @@ public abstract class World implements IBlockAccess { +@@ -1285,7 +1292,9 @@ public abstract class World implements IBlockAccess { this.methodProfiler.b(); } @@ -248,7 +248,7 @@ index d2679dc..7360dfc 100644 this.M = true; Iterator iterator = this.tileEntityList.iterator(); -@@ -1299,8 +1308,11 @@ public abstract class World implements IBlockAccess { +@@ -1300,8 +1309,11 @@ public abstract class World implements IBlockAccess { if (!tileentity.r() && tileentity.o() && this.isLoaded(tileentity.x, tileentity.y, tileentity.z)) { try { @@ -260,7 +260,7 @@ index d2679dc..7360dfc 100644 crashreport = CrashReport.a(throwable2, "Ticking block entity"); crashreportsystemdetails = crashreport.a("Block entity being ticked"); tileentity.a(crashreportsystemdetails); -@@ -1320,6 +1332,8 @@ public abstract class World implements IBlockAccess { +@@ -1321,6 +1333,8 @@ public abstract class World implements IBlockAccess { } } @@ -269,7 +269,7 @@ index d2679dc..7360dfc 100644 this.M = false; if (!this.b.isEmpty()) { this.tileEntityList.removeAll(this.b); -@@ -1358,6 +1372,7 @@ public abstract class World implements IBlockAccess { +@@ -1359,6 +1373,7 @@ public abstract class World implements IBlockAccess { this.a.clear(); } @@ -277,7 +277,7 @@ index d2679dc..7360dfc 100644 this.methodProfiler.b(); this.methodProfiler.b(); } -@@ -1380,6 +1395,7 @@ public abstract class World implements IBlockAccess { +@@ -1381,6 +1396,7 @@ public abstract class World implements IBlockAccess { byte b0 = 32; if (!flag || this.b(i - b0, 0, j - b0, i + b0, 0, j + b0)) { @@ -285,7 +285,7 @@ index d2679dc..7360dfc 100644 entity.S = entity.locX; entity.T = entity.locY; entity.U = entity.locZ; -@@ -1441,6 +1457,7 @@ public abstract class World implements IBlockAccess { +@@ -1442,6 +1458,7 @@ public abstract class World implements IBlockAccess { entity.passenger = null; } } @@ -294,10 +294,10 @@ index d2679dc..7360dfc 100644 } diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 0c24d9a..6307686 100644 +index 0192dc5..a5e0e13 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -184,10 +184,13 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate +@@ -185,10 +185,13 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate // CraftBukkit start - Only call spawner if we have players online and the world allows for mobs or animals long time = this.worldData.getTime(); if (this.getGameRules().getBoolean("doMobSpawning") && (this.allowMonsters || this.allowAnimals) && (this instanceof WorldServer && this.players.size() > 0)) { @@ -311,7 +311,7 @@ index 0c24d9a..6307686 100644 this.methodProfiler.c("chunkSource"); this.chunkProvider.unloadChunks(); int j = this.a(1.0F); -@@ -201,21 +204,36 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate +@@ -202,21 +205,36 @@ public class WorldServer extends World implements org.bukkit.BlockChangeDelegate this.worldData.setDayTime(this.worldData.getDayTime() + 1L); } @@ -539,5 +539,5 @@ index 55db3ff..7d294c0 100644 } -- -1.8.5.2.msysgit.0 +1.8.3.2 diff --git a/CraftBukkit-Patches/0016-Handle-Null-Tile-Entities.patch b/CraftBukkit-Patches/0016-Handle-Null-Tile-Entities.patch index 42439ef284..efdd5f3ec1 100644 --- a/CraftBukkit-Patches/0016-Handle-Null-Tile-Entities.patch +++ b/CraftBukkit-Patches/0016-Handle-Null-Tile-Entities.patch @@ -1,14 +1,14 @@ -From d7110a904d1cd3aa8579a8156c932aa411ec8159 Mon Sep 17 00:00:00 2001 +From dad597ee08d239117fb2bbd565d097d3b2524b88 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 3 Feb 2013 09:20:19 +1100 Subject: [PATCH] Handle Null Tile Entities diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 7360dfc..9b3f3e5 100644 +index 7ead630..d9f987c 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -1299,6 +1299,13 @@ public abstract class World implements IBlockAccess { +@@ -1300,6 +1300,13 @@ public abstract class World implements IBlockAccess { while (iterator.hasNext()) { TileEntity tileentity = (TileEntity) iterator.next(); @@ -23,5 +23,5 @@ index 7360dfc..9b3f3e5 100644 ChunkProviderServer chunkProviderServer = ((WorldServer) this).chunkProviderServer; if (chunkProviderServer.unloadQueue.contains(tileentity.x >> 4, tileentity.z >> 4)) { -- -1.8.5.2.msysgit.0 +1.8.3.2 diff --git a/CraftBukkit-Patches/0017-Entity-Activation-Range.patch b/CraftBukkit-Patches/0017-Entity-Activation-Range.patch index 6851f793e6..6670782204 100644 --- a/CraftBukkit-Patches/0017-Entity-Activation-Range.patch +++ b/CraftBukkit-Patches/0017-Entity-Activation-Range.patch @@ -1,4 +1,4 @@ -From 41e82cb66847e6ecbcd1406cb621eb2bdcbb4a3d Mon Sep 17 00:00:00 2001 +From b3dd79c393ff2bfb2f6053a108de09fa1cf2bca3 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 3 Feb 2013 05:10:21 -0500 Subject: [PATCH] Entity Activation Range @@ -85,7 +85,7 @@ index 36ed831..7ddca48 100644 super(world); } diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java/net/minecraft/server/EntityArrow.java -index b263d82..c33d564 100644 +index 3628774..c2afb17 100644 --- a/src/main/java/net/minecraft/server/EntityArrow.java +++ b/src/main/java/net/minecraft/server/EntityArrow.java @@ -15,7 +15,7 @@ public class EntityArrow extends Entity implements IProjectile { @@ -98,7 +98,7 @@ index b263d82..c33d564 100644 public int shake; public Entity shooter; diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index af5deb9..57157ef 100644 +index f90e2a3..3758411 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java @@ -78,6 +78,13 @@ public abstract class EntityLiving extends Entity { @@ -116,10 +116,10 @@ index af5deb9..57157ef 100644 public EntityLiving(World world) { super(world); diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 9b3f3e5..a2ca914 100644 +index d9f987c..7d9d325 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -1240,6 +1240,7 @@ public abstract class World implements IBlockAccess { +@@ -1241,6 +1241,7 @@ public abstract class World implements IBlockAccess { this.f.clear(); this.methodProfiler.c("regular"); @@ -127,7 +127,7 @@ index 9b3f3e5..a2ca914 100644 timings.entityTick.startTiming(); // Spigot // CraftBukkit start - Use field for loop variable for (this.tickPosition = 0; this.tickPosition < this.entityList.size(); ++this.tickPosition) { -@@ -1401,7 +1402,11 @@ public abstract class World implements IBlockAccess { +@@ -1402,7 +1403,11 @@ public abstract class World implements IBlockAccess { int j = MathHelper.floor(entity.locZ); byte b0 = 32; @@ -477,5 +477,5 @@ index 46249d7..ed2836a 100644 + } } -- -1.8.5.2.msysgit.0 +1.8.3.2 diff --git a/CraftBukkit-Patches/0025-Close-Unloaded-Save-Files.patch b/CraftBukkit-Patches/0025-Close-Unloaded-Save-Files.patch index 2a79408df4..16619d49a3 100644 --- a/CraftBukkit-Patches/0025-Close-Unloaded-Save-Files.patch +++ b/CraftBukkit-Patches/0025-Close-Unloaded-Save-Files.patch @@ -1,4 +1,4 @@ -From 538ce23bbf917e057f339ee8179c77ab0d936ede Mon Sep 17 00:00:00 2001 +From cf8cf9db76559a65905429d8e266b43786de6872 Mon Sep 17 00:00:00 2001 From: Antony Riley Date: Wed, 27 Mar 2013 01:41:54 +0200 Subject: [PATCH] Close Unloaded Save Files @@ -18,10 +18,10 @@ index 900ed68..829f4a3 100644 public static synchronized RegionFile a(File file1, int i, int j) { File file2 = new File(file1, "region"); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index aa76abe..f23636d 100644 +index 3a72f25..7c5db94 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -82,6 +82,8 @@ import net.minecraft.server.MinecraftServer; +@@ -81,6 +81,8 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.MobEffectList; import net.minecraft.server.PropertyManager; import net.minecraft.server.ServerCommand; diff --git a/CraftBukkit-Patches/0030-Prevent-Shutdown-Hang.patch b/CraftBukkit-Patches/0030-Prevent-Shutdown-Hang.patch index 99fb1d886e..16d8d01851 100644 --- a/CraftBukkit-Patches/0030-Prevent-Shutdown-Hang.patch +++ b/CraftBukkit-Patches/0030-Prevent-Shutdown-Hang.patch @@ -1,4 +1,4 @@ -From 4f70801d7449858686bdfd5628f871ab08c0e2bf Mon Sep 17 00:00:00 2001 +From 0911b5dd80e900a7c4c8fa7f4a5599ab3ee06592 Mon Sep 17 00:00:00 2001 From: md_5 Date: Tue, 11 Jun 2013 11:54:32 +1000 Subject: [PATCH] Prevent Shutdown Hang @@ -6,13 +6,13 @@ Subject: [PATCH] Prevent Shutdown Hang Prevents server hanging if players disconnect during the shutdown sequence. diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java -index 5b0590e..1fb24f7 100644 +index 7c01595..4977ea1 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java -@@ -1110,8 +1110,15 @@ public abstract class PlayerList { +@@ -1152,8 +1152,15 @@ public abstract class PlayerList { } - public void r() { + public void u() { - for (int i = 0; i < this.players.size(); ++i) { - ((EntityPlayer) this.players.get(i)).playerConnection.disconnect(this.server.server.getShutdownMessage()); // CraftBukkit - add custom shutdown message + while (!this.players.isEmpty()) { @@ -28,5 +28,5 @@ index 5b0590e..1fb24f7 100644 } -- -1.8.5.2.msysgit.0 +1.8.3.2 diff --git a/CraftBukkit-Patches/0033-Allow-Disabling-of-Command-Logging.patch b/CraftBukkit-Patches/0033-Allow-Disabling-of-Command-Logging.patch new file mode 100644 index 0000000000..23a62eac17 --- /dev/null +++ b/CraftBukkit-Patches/0033-Allow-Disabling-of-Command-Logging.patch @@ -0,0 +1,42 @@ +From cf5a9716d8ddb2da8634724201bcc8316d359a93 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Fri, 21 Jun 2013 18:01:29 +1000 +Subject: [PATCH] Allow Disabling of Command Logging + + +diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java +index f34fd03..7826074 100644 +--- a/src/main/java/net/minecraft/server/PlayerConnection.java ++++ b/src/main/java/net/minecraft/server/PlayerConnection.java +@@ -951,7 +951,12 @@ public class PlayerConnection implements PacketPlayInListener { + } + + try { +- this.c.info(event.getPlayer().getName() + " issued server command: " + event.getMessage()); ++ // Spigot Start ++ if ( org.spigotmc.SpigotConfig.logCommands ) ++ { ++ this.c.info(event.getPlayer().getName() + " issued server command: " + event.getMessage()); ++ } ++ // Spigot end + if (this.server.dispatchCommand(event.getPlayer(), event.getMessage().substring(1))) { + org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot + return; +diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java +index 98fcb47..afd6b56 100644 +--- a/src/main/java/org/spigotmc/SpigotConfig.java ++++ b/src/main/java/org/spigotmc/SpigotConfig.java +@@ -130,4 +130,10 @@ public class SpigotConfig + config.addDefault( path, def ); + return config.getString( path, config.getString( path ) ); + } ++ ++ public static boolean logCommands; ++ private static void logCommands() ++ { ++ logCommands = getBoolean( "commands.log", true ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0034-Allow-Disabling-of-Command-TabComplete.patch b/CraftBukkit-Patches/0034-Allow-Disabling-of-Command-TabComplete.patch new file mode 100644 index 0000000000..71333613f9 --- /dev/null +++ b/CraftBukkit-Patches/0034-Allow-Disabling-of-Command-TabComplete.patch @@ -0,0 +1,53 @@ +From ebcb0fc76e2b4cb6978aae5ca4d8adbb47212ca3 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Fri, 21 Jun 2013 18:05:54 +1000 +Subject: [PATCH] Allow Disabling of Command TabComplete + + +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +index 7c5db94..4cb78fd 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -1583,6 +1583,13 @@ public final class CraftServer implements Server { + } + + public List tabCompleteCommand(Player player, String message) { ++ // Spigot Start ++ if ( (org.spigotmc.SpigotConfig.tabComplete < 0 || message.length() <= org.spigotmc.SpigotConfig.tabComplete) && !message.contains( " " ) ) ++ { ++ return ImmutableList.of(); ++ } ++ // Spigot End ++ + List completions = null; + try { + completions = getCommandMap().tabComplete(player, message.substring(1)); +diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java +index afd6b56..20634f1 100644 +--- a/src/main/java/org/spigotmc/SpigotConfig.java ++++ b/src/main/java/org/spigotmc/SpigotConfig.java +@@ -136,4 +136,21 @@ public class SpigotConfig + { + logCommands = getBoolean( "commands.log", true ); + } ++ ++ public static int tabComplete; ++ private static void tabComplete() ++ { ++ if ( version < 6 ) ++ { ++ boolean oldValue = getBoolean( "commands.tab-complete", true ); ++ if ( oldValue ) ++ { ++ set( "commands.tab-complete", 0 ); ++ } else ++ { ++ set( "commands.tab-complete", -1 ); ++ } ++ } ++ tabComplete = getInt( "commands.tab-complete", 0 ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0035-Configurable-Messages.patch b/CraftBukkit-Patches/0035-Configurable-Messages.patch new file mode 100644 index 0000000000..28c751c3b8 --- /dev/null +++ b/CraftBukkit-Patches/0035-Configurable-Messages.patch @@ -0,0 +1,107 @@ +From 1788feaf265d532b6ffd95afd64380cc7be7fbeb Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Fri, 21 Jun 2013 19:21:58 +1000 +Subject: [PATCH] Configurable Messages + + +diff --git a/src/main/java/net/minecraft/server/HandshakeListener.java b/src/main/java/net/minecraft/server/HandshakeListener.java +index 17e69db..b98079c 100644 +--- a/src/main/java/net/minecraft/server/HandshakeListener.java ++++ b/src/main/java/net/minecraft/server/HandshakeListener.java +@@ -64,11 +64,11 @@ public class HandshakeListener implements PacketHandshakingInListener { + // CraftBukkit end + + if (packethandshakinginsetprotocol.d() > 5) { +- chatcomponenttext = new ChatComponentText("Outdated server! I\'m still on 1.7.8"); ++ chatcomponenttext = new ChatComponentText( org.spigotmc.SpigotConfig.outdatedServerMessage ); // Spigot + this.b.handle(new PacketLoginOutDisconnect(chatcomponenttext), new GenericFutureListener[0]); + this.b.close(chatcomponenttext); + } else if (packethandshakinginsetprotocol.d() < 5) { +- chatcomponenttext = new ChatComponentText("Outdated client! Please use 1.7.8"); ++ chatcomponenttext = new ChatComponentText( org.spigotmc.SpigotConfig.outdatedClientMessage ); // Spigot + this.b.handle(new PacketLoginOutDisconnect(chatcomponenttext), new GenericFutureListener[0]); + this.b.close(chatcomponenttext); + } else { +diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java +index 4977ea1..0208191 100644 +--- a/src/main/java/net/minecraft/server/PlayerList.java ++++ b/src/main/java/net/minecraft/server/PlayerList.java +@@ -365,7 +365,7 @@ public abstract class PlayerList { + event.disallow(PlayerLoginEvent.Result.KICK_BANNED, s); + } else if (!this.isWhitelisted(gameprofile)) { + // return "You are not white-listed on this server!"; +- event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, "You are not white-listed on this server!"); ++event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig.whitelistMessage); // Spigot + } else if (this.k.isBanned(socketaddress)) { + IpBanEntry ipbanentry = this.k.get(socketaddress); + +@@ -379,7 +379,7 @@ public abstract class PlayerList { + } else { + // return this.players.size() >= this.maxPlayers ? "The server is full!" : null; + if (this.players.size() >= this.maxPlayers) { +- event.disallow(PlayerLoginEvent.Result.KICK_FULL, "The server is full!"); ++ event.disallow(PlayerLoginEvent.Result.KICK_FULL, org.spigotmc.SpigotConfig.serverFullMessage); // Spigot + } + } + +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +index 4cb78fd..674acb9 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -701,11 +701,7 @@ public final class CraftServer implements Server { + return true; + } + +- if (sender instanceof Player) { +- sender.sendMessage("Unknown command. Type \"/help\" for help."); +- } else { +- sender.sendMessage("Unknown command. Type \"help\" for help."); +- } ++ sender.sendMessage(org.spigotmc.SpigotConfig.unknownCommandMessage); + + return false; + } +diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java +index 20634f1..efcd193 100644 +--- a/src/main/java/org/spigotmc/SpigotConfig.java ++++ b/src/main/java/org/spigotmc/SpigotConfig.java +@@ -12,6 +12,7 @@ import java.util.Map; + import java.util.logging.Level; + import net.minecraft.server.MinecraftServer; + import org.bukkit.Bukkit; ++import org.bukkit.ChatColor; + import org.bukkit.command.Command; + import org.bukkit.configuration.file.YamlConfiguration; + +@@ -153,4 +154,28 @@ public class SpigotConfig + } + tabComplete = getInt( "commands.tab-complete", 0 ); + } ++ ++ public static String whitelistMessage; ++ public static String unknownCommandMessage; ++ public static String serverFullMessage; ++ public static String outdatedClientMessage = "Outdated client! Please use {}"; ++ public static String outdatedServerMessage = "Outdated server! I\'m still on {0}"; ++ private static String transform(String s) ++ { ++ return ChatColor.translateAlternateColorCodes( '&', s ).replaceAll( "\\n", "\n" ); ++ } ++ private static void messages() ++ { ++ if (version < 4) ++ { ++ set( "messages.outdated-client", outdatedClientMessage ); ++ set( "messages.outdated-server", outdatedServerMessage ); ++ } ++ ++ whitelistMessage = transform( getString( "messages.whitelist", "You are not whitelisted on this server!" ) ); ++ unknownCommandMessage = transform( getString( "messages.unknown-command", "Unknown command. Type \"/help\" for help." ) ); ++ serverFullMessage = transform( getString( "messages.server-full", "The server is full!" ) ); ++ outdatedClientMessage = transform( getString( "messages.outdated-client", outdatedClientMessage ) ); ++ outdatedServerMessage = transform( getString( "messages.outdated-server", outdatedServerMessage ) ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0036-Allow-Disabling-of-Random-Lighting-Updates.patch b/CraftBukkit-Patches/0036-Allow-Disabling-of-Random-Lighting-Updates.patch new file mode 100644 index 0000000000..92fc1af2ef --- /dev/null +++ b/CraftBukkit-Patches/0036-Allow-Disabling-of-Random-Lighting-Updates.patch @@ -0,0 +1,51 @@ +From b939e07cf00e75eee84fea4f308ba858c86691ea Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sat, 22 Jun 2013 16:12:02 +1000 +Subject: [PATCH] Allow Disabling of Random Lighting Updates + + +diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java +index 0110120..96974b4 100644 +--- a/src/main/java/net/minecraft/server/Chunk.java ++++ b/src/main/java/net/minecraft/server/Chunk.java +@@ -906,7 +906,7 @@ public class Chunk { + } + + this.m = true; +- if (!this.lit && this.done) { ++ if (!this.lit && this.done && this.world.spigotConfig.randomLightUpdates) { // Spigot - also use random light updates setting to determine if we should relight + this.p(); + } + } +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index 7d9d325..96b5bc7 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -2036,7 +2036,7 @@ public abstract class World implements IBlockAccess { + } + + this.methodProfiler.a("playerCheckLight"); +- if (!this.players.isEmpty()) { ++ if (spigotConfig.randomLightUpdates && !this.players.isEmpty()) { // Spigot + i = this.random.nextInt(this.players.size()); + entityhuman = (EntityHuman) this.players.get(i); + j = MathHelper.floor(entityhuman.locX) + this.random.nextInt(11) - 5; +diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java +index 827e6f9..adebd03 100644 +--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java ++++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java +@@ -177,4 +177,11 @@ public class SpigotWorldConfig + hopperCheck = getInt( "ticks-per.hopper-check", hopperTransfer ); + log( "Hopper Transfer: " + hopperTransfer + " Hopper Check: " + hopperCheck ); + } ++ ++ public boolean randomLightUpdates; ++ private void lightUpdates() ++ { ++ randomLightUpdates = getBoolean( "random-light-updates", false ); ++ log( "Random Lighting Updates: " + randomLightUpdates ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0037-Make-AnvilInventory.getItem-use-both-containers.-Fix.patch b/CraftBukkit-Patches/0037-Make-AnvilInventory.getItem-use-both-containers.-Fix.patch new file mode 100644 index 0000000000..c42e1a8a9a --- /dev/null +++ b/CraftBukkit-Patches/0037-Make-AnvilInventory.getItem-use-both-containers.-Fix.patch @@ -0,0 +1,57 @@ +From df5a15e53159fdd78e0d441d0a780e7948597869 Mon Sep 17 00:00:00 2001 +From: Andre LeBlanc +Date: Sat, 6 Apr 2013 12:00:31 -0400 +Subject: [PATCH] Make AnvilInventory.getItem() use both containers. Fixes + BUKKIT-2788 + +The AnvilInventory reports its size as the sum of the ingredient and +result inventories, but when trying to access the slots, only the ingredient +inventory is used, leading to an ArrayIndexOutOfBounds exception. + +This change overrides getItem(I) and setItem(I) to use both inventories, +with the slot number adjusted based on their size. + +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java +index a91d81a..46a1d38 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java +@@ -1,7 +1,9 @@ + package org.bukkit.craftbukkit.inventory; + + import net.minecraft.server.IInventory; ++ + import org.bukkit.inventory.AnvilInventory; ++import org.bukkit.inventory.ItemStack; + + public class CraftInventoryAnvil extends CraftInventory implements AnvilInventory { + private final IInventory resultInventory; +@@ -20,6 +22,26 @@ public class CraftInventoryAnvil extends CraftInventory implements AnvilInventor + } + + @Override ++ public ItemStack getItem(int slot) { ++ if (slot < getIngredientsInventory().getSize()) { ++ net.minecraft.server.ItemStack item = getIngredientsInventory().getItem(slot); ++ return item == null ? null : CraftItemStack.asCraftMirror(item); ++ } else { ++ net.minecraft.server.ItemStack item = getResultInventory().getItem(slot - getIngredientsInventory().getSize()); ++ return item == null ? null : CraftItemStack.asCraftMirror(item); ++ } ++ } ++ ++ @Override ++ public void setItem(int index, ItemStack item) { ++ if (index < getIngredientsInventory().getSize()) { ++ getIngredientsInventory().setItem(index, (item == null ? null : CraftItemStack.asNMSCopy(item))); ++ } else { ++ getResultInventory().setItem((index - getIngredientsInventory().getSize()), (item == null ? null : CraftItemStack.asNMSCopy(item))); ++ } ++ } ++ ++ @Override + public int getSize() { + return getResultInventory().getSize() + getIngredientsInventory().getSize(); + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0038-Properly-Close-Inventories.patch b/CraftBukkit-Patches/0038-Properly-Close-Inventories.patch new file mode 100644 index 0000000000..06e9092c52 --- /dev/null +++ b/CraftBukkit-Patches/0038-Properly-Close-Inventories.patch @@ -0,0 +1,63 @@ +From 331e7dbd06a41d3af1c9d66c885fbd258607dc57 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Thu, 27 Jun 2013 17:26:09 +1000 +Subject: [PATCH] Properly Close Inventories + +Properly close inventories when unloading and switching worlds. + +diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java +index 96974b4..3fc83e5 100644 +--- a/src/main/java/net/minecraft/server/Chunk.java ++++ b/src/main/java/net/minecraft/server/Chunk.java +@@ -760,6 +760,15 @@ public class Chunk { + + while (iterator.hasNext()) { + TileEntity tileentity = (TileEntity) iterator.next(); ++ // Spigot Start ++ if ( tileentity instanceof IInventory ) ++ { ++ for ( org.bukkit.craftbukkit.entity.CraftHumanEntity h : new ArrayList( (List) ( (IInventory) tileentity ).getViewers() ) ) ++ { ++ h.getHandle().closeInventory(); ++ } ++ } ++ // Spigot End + + this.world.a(tileentity); + } +@@ -769,6 +778,15 @@ public class Chunk { + java.util.Iterator iter = this.entitySlices[i].iterator(); + while (iter.hasNext()) { + Entity entity = (Entity) iter.next(); ++ // Spigot Start ++ if ( entity instanceof IInventory ) ++ { ++ for ( org.bukkit.craftbukkit.entity.CraftHumanEntity h : new ArrayList( (List) ( (IInventory) entity ).getViewers() ) ) ++ { ++ h.getHandle().closeInventory(); ++ } ++ } ++ // Spigot End + + // Do not pass along players, as doing so can get them stuck outside of time. + // (which for example disables inventory icon updates and prevents block breaking) +diff --git a/src/main/java/net/minecraft/server/EntityMinecartContainer.java b/src/main/java/net/minecraft/server/EntityMinecartContainer.java +index 9f3f196..439cf2e 100644 +--- a/src/main/java/net/minecraft/server/EntityMinecartContainer.java ++++ b/src/main/java/net/minecraft/server/EntityMinecartContainer.java +@@ -149,6 +149,12 @@ public abstract class EntityMinecartContainer extends EntityMinecartAbstract imp + } + + public void b(int i) { ++ // Spigot Start ++ for ( HumanEntity human : new java.util.ArrayList( transaction ) ) ++ { ++ human.closeInventory(); ++ } ++ // Spigot End + this.b = false; + super.b(i); + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0039-Disallow-Interaction-With-Self.patch b/CraftBukkit-Patches/0039-Disallow-Interaction-With-Self.patch new file mode 100644 index 0000000000..eecfbd69b1 --- /dev/null +++ b/CraftBukkit-Patches/0039-Disallow-Interaction-With-Self.patch @@ -0,0 +1,27 @@ +From 0120877b54f169b974c110ce3ea34ca6897da8d8 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Fri, 28 Jun 2013 19:52:54 +1000 +Subject: [PATCH] Disallow Interaction With Self + + +diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java +index 7826074..917a587 100644 +--- a/src/main/java/net/minecraft/server/PlayerConnection.java ++++ b/src/main/java/net/minecraft/server/PlayerConnection.java +@@ -1058,6 +1058,13 @@ public class PlayerConnection implements PacketPlayInListener { + if (this.player.dead) return; // CraftBukkit + WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); + Entity entity = packetplayinuseentity.a((World) worldserver); ++ // Spigot Start ++ if ( entity == player ) ++ { ++ disconnect( "Cannot interact with self!" ); ++ return; ++ } ++ // Spigot End + + this.player.v(); + if (entity != null) { +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0040-Lower-Chunk-Compression.patch b/CraftBukkit-Patches/0040-Lower-Chunk-Compression.patch new file mode 100644 index 0000000000..7be0b5c9e8 --- /dev/null +++ b/CraftBukkit-Patches/0040-Lower-Chunk-Compression.patch @@ -0,0 +1,36 @@ +From 08c35cccfe2109d16122a5633f94d14217d5e3d6 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Tue, 2 Jul 2013 09:07:54 +1000 +Subject: [PATCH] Lower Chunk Compression + +Use a chunk compression level of 4 - this provides an optimal balance between speed and compression. + +diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java +index 856e825..09b34e9 100644 +--- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java ++++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java +@@ -24,7 +24,7 @@ public class PacketPlayOutMapChunk extends Packet { + this.b = chunk.locZ; + this.inflatedBuffer = flag; + ChunkMap chunkmap = a(chunk, flag, i); +- Deflater deflater = new Deflater(-1); ++ Deflater deflater = new Deflater(4); // Spigot + + this.d = chunkmap.c; + this.c = chunkmap.b; +diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java +index 3eac231..bf3a139 100644 +--- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java ++++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java +@@ -22,7 +22,7 @@ public class PacketPlayOutMapChunkBulk extends Packet { + @Override + protected Deflater initialValue() { + // Don't use higher compression level, slows things down too much +- return new Deflater(6); ++ return new Deflater(4); // Spigot 6 -> 4 + } + }; + // CraftBukkit end +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0041-Entity-Mount-and-Dismount-Events.patch b/CraftBukkit-Patches/0041-Entity-Mount-and-Dismount-Events.patch new file mode 100644 index 0000000000..b2d310eac2 --- /dev/null +++ b/CraftBukkit-Patches/0041-Entity-Mount-and-Dismount-Events.patch @@ -0,0 +1,51 @@ +From a4e61e2c3fef0f754763e903a94e331c9c7990b1 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Tue, 2 Jul 2013 20:32:49 +1000 +Subject: [PATCH] Entity Mount and Dismount Events + + +diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java +index 621f593..b13968d 100644 +--- a/src/main/java/net/minecraft/server/Entity.java ++++ b/src/main/java/net/minecraft/server/Entity.java +@@ -1452,6 +1452,7 @@ public abstract class Entity { + } + } + // CraftBukkit end ++ pluginManager.callEvent( new org.spigotmc.event.entity.EntityDismountEvent( this.getBukkitEntity(), this.vehicle.getBukkitEntity() ) ); // Spigot + + this.setPositionRotation(this.vehicle.locX, this.vehicle.boundingBox.b + (double) this.vehicle.length, this.vehicle.locZ, this.yaw, this.pitch); + this.vehicle.passenger = null; +@@ -1487,6 +1488,17 @@ public abstract class Entity { + } + } + // CraftBukkit end ++ // Spigot Start ++ if ( entity.world.isChunkLoaded( (int) entity.locX >> 4, (int) entity.locZ >> 4 ) ) ++ { ++ org.spigotmc.event.entity.EntityMountEvent event = new org.spigotmc.event.entity.EntityMountEvent( this.getBukkitEntity(), entity.getBukkitEntity() ); ++ pluginManager.callEvent( event ); ++ if ( event.isCancelled() ) ++ { ++ return; ++ } ++ } ++ // Spigot End + + if (this.vehicle != null) { + this.vehicle.passenger = null; +diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java +index eb4793d..e2e7b9c 100644 +--- a/src/main/java/net/minecraft/server/EntityHuman.java ++++ b/src/main/java/net/minecraft/server/EntityHuman.java +@@ -323,6 +323,7 @@ public abstract class EntityHuman extends EntityLiving implements ICommandListen + public void setPassengerOf(Entity entity) { + // CraftBukkit end + if (this.vehicle != null && entity == null) { ++ world.getServer().getPluginManager().callEvent( new org.spigotmc.event.entity.EntityDismountEvent( this.getBukkitEntity(), this.vehicle.getBukkitEntity() ) ); // Spigot + // CraftBukkit start - use parent method instead to correctly fire VehicleExitEvent + Entity originalVehicle = this.vehicle; + // First statement moved down, second statement handled in parent method. +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0042-Prevent-Ghost-Players-Caused-by-Plugins.patch b/CraftBukkit-Patches/0042-Prevent-Ghost-Players-Caused-by-Plugins.patch new file mode 100644 index 0000000000..e1476d3b9b --- /dev/null +++ b/CraftBukkit-Patches/0042-Prevent-Ghost-Players-Caused-by-Plugins.patch @@ -0,0 +1,26 @@ +From 6403bc23c4e6b66b0bafaa5703762a695daf23a7 Mon Sep 17 00:00:00 2001 +From: Alex Ciuba +Date: Tue, 11 Jun 2013 15:23:03 -0400 +Subject: [PATCH] Prevent Ghost Players Caused by Plugins + +Check if the player is still connected after firing event. Fixes BUKKIT-4327 + +diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java +index 0208191..9c98a62 100644 +--- a/src/main/java/net/minecraft/server/PlayerList.java ++++ b/src/main/java/net/minecraft/server/PlayerList.java +@@ -492,6 +492,11 @@ event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig + Player respawnPlayer = this.cserver.getPlayer(entityplayer1); + PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(respawnPlayer, location, isBedSpawn); + this.cserver.getPluginManager().callEvent(respawnEvent); ++ // Spigot Start ++ if (entityplayer.playerConnection.isDisconnected()) { ++ return entityplayer; ++ } ++ // Spigot End + + location = respawnEvent.getRespawnLocation(); + entityplayer.reset(); +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0043-Entity-ticking-chunk-caching.patch b/CraftBukkit-Patches/0043-Entity-ticking-chunk-caching.patch new file mode 100644 index 0000000000..28b026a3b8 --- /dev/null +++ b/CraftBukkit-Patches/0043-Entity-ticking-chunk-caching.patch @@ -0,0 +1,66 @@ +From 78f07fc5afe8f2620fcdaf65bfbbdeff0f38d793 Mon Sep 17 00:00:00 2001 +From: Ammar Askar +Date: Tue, 16 Jul 2013 03:32:32 +0500 +Subject: [PATCH] Entity ticking chunk caching + +Cache known loaded chunks so we avoid making a potentially expensive contains call for every single entity in exchange for some simple arithmetic. Best case scenario, this cuts down contains call to once per chunk, worst case it adds on some simple arithmetic operations + +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index 96b5bc7..b0b9757 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -1186,6 +1186,7 @@ public abstract class World implements IBlockAccess { + CrashReport crashreport; + CrashReportSystemDetails crashreportsystemdetails; + ++ long lastChunk = Long.MIN_VALUE; // Spigot - cache chunk x, z cords for unload queue + for (i = 0; i < this.i.size(); ++i) { + entity = (Entity) this.i.get(i); + // CraftBukkit start - Fixed an NPE, don't process entities in chunks queued for unload +@@ -1194,10 +1195,15 @@ public abstract class World implements IBlockAccess { + } + + ChunkProviderServer chunkProviderServer = ((WorldServer) this).chunkProviderServer; +- if (chunkProviderServer.unloadQueue.contains(MathHelper.floor(entity.locX) >> 4, MathHelper.floor(entity.locZ) >> 4)) { +- continue; ++ // Spigot start - check last chunk to see if this loaded (fast cache) ++ long chunk = org.bukkit.craftbukkit.util.LongHash.toLong(MathHelper.floor(entity.locX) >> 4, MathHelper.floor(entity.locZ) >> 4); ++ if (lastChunk != chunk) { ++ if (chunkProviderServer.unloadQueue.contains(chunk)) { // Spigot end ++ continue; ++ } + } + // CraftBukkit end ++ lastChunk = chunk; // Spigot + + try { + ++entity.ticksLived; +@@ -1218,6 +1224,7 @@ public abstract class World implements IBlockAccess { + this.i.remove(i--); + } + } ++ lastChunk = Long.MIN_VALUE; // Spigot + + this.methodProfiler.c("remove"); + this.entityList.removeAll(this.f); +@@ -1249,10 +1256,15 @@ public abstract class World implements IBlockAccess { + + // Don't tick entities in chunks queued for unload + ChunkProviderServer chunkProviderServer = ((WorldServer) this).chunkProviderServer; +- if (chunkProviderServer.unloadQueue.contains(MathHelper.floor(entity.locX) >> 4, MathHelper.floor(entity.locZ) >> 4)) { +- continue; ++ // Spigot start - check last chunk to see if this loaded (fast cache) ++ long chunk = org.bukkit.craftbukkit.util.LongHash.toLong(MathHelper.floor(entity.locX) >> 4, MathHelper.floor(entity.locZ) >> 4); ++ if (lastChunk != chunk) { ++ if (chunkProviderServer.unloadQueue.contains(chunk)) { // Spigot end ++ continue; ++ } + } + // CraftBukkit end ++ lastChunk = Long.MIN_VALUE; // Spigot + + if (entity.vehicle != null) { + if (!entity.vehicle.dead && entity.vehicle.passenger == entity) { +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0044-Plug-World-Unload-Memory-Leak.patch b/CraftBukkit-Patches/0044-Plug-World-Unload-Memory-Leak.patch new file mode 100644 index 0000000000..faa135b501 --- /dev/null +++ b/CraftBukkit-Patches/0044-Plug-World-Unload-Memory-Leak.patch @@ -0,0 +1,22 @@ +From 2a46d3d0f7423526558466e9cb9db6e3a43d0b92 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sat, 3 Aug 2013 19:02:59 +1000 +Subject: [PATCH] Plug World Unload Memory Leak + + +diff --git a/src/main/java/net/minecraft/server/BlockRedstoneTorch.java b/src/main/java/net/minecraft/server/BlockRedstoneTorch.java +index 8e01414..e0469bb 100644 +--- a/src/main/java/net/minecraft/server/BlockRedstoneTorch.java ++++ b/src/main/java/net/minecraft/server/BlockRedstoneTorch.java +@@ -11,7 +11,7 @@ import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit + public class BlockRedstoneTorch extends BlockTorch { + + private boolean isOn; +- private static Map b = new HashMap(); ++ private static Map b = new java.util.WeakHashMap(); // Spigot + + private boolean a(World world, int i, int j, int k, boolean flag) { + if (!b.containsKey(world)) { +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0045-Player-Collision-API.patch b/CraftBukkit-Patches/0045-Player-Collision-API.patch new file mode 100644 index 0000000000..f30c3acc18 --- /dev/null +++ b/CraftBukkit-Patches/0045-Player-Collision-API.patch @@ -0,0 +1,85 @@ +From 4f191736ede09810d6a941c601d2ebe74c793797 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sat, 3 Aug 2013 19:27:07 +1000 +Subject: [PATCH] Player Collision API + + +diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java +index e2e7b9c..5b50df0 100644 +--- a/src/main/java/net/minecraft/server/EntityHuman.java ++++ b/src/main/java/net/minecraft/server/EntityHuman.java +@@ -430,7 +430,7 @@ public abstract class EntityHuman extends EntityLiving implements ICommandListen + + List list = this.world.getEntities(this, axisalignedbb); + +- if (list != null) { ++ if (list != null && this.R()) { // Spigot: Add this.R() condition + for (int i = 0; i < list.size(); ++i) { + Entity entity = (Entity) list.get(i); + +diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java +index 3758411..90c0e82 100644 +--- a/src/main/java/net/minecraft/server/EntityLiving.java ++++ b/src/main/java/net/minecraft/server/EntityLiving.java +@@ -1490,7 +1490,7 @@ public abstract class EntityLiving extends Entity { + protected void bn() { + List list = this.world.getEntities(this, this.boundingBox.grow(0.20000000298023224D, 0.0D, 0.20000000298023224D)); + +- if (list != null && !list.isEmpty()) { ++ if (this.R() && list != null && !list.isEmpty()) { // Spigot: Add this.R() condition + for (int i = 0; i < list.size(); ++i) { + Entity entity = (Entity) list.get(i); + +diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java +index 9b80aef..b519903 100644 +--- a/src/main/java/net/minecraft/server/EntityPlayer.java ++++ b/src/main/java/net/minecraft/server/EntityPlayer.java +@@ -63,6 +63,21 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + public double maxHealthCache; + public boolean joining = true; + // CraftBukkit end ++ // Spigot start ++ public boolean collidesWithEntities = true; ++ ++ @Override ++ public boolean Q() ++ { ++ return this.collidesWithEntities && super.Q(); ++ } ++ ++ @Override ++ public boolean R() ++ { ++ return this.collidesWithEntities && super.R(); ++ } ++ // Spigot end + + public EntityPlayer(MinecraftServer minecraftserver, WorldServer worldserver, GameProfile gameprofile, PlayerInteractManager playerinteractmanager) { + super(worldserver, gameprofile); +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index 8a09d97..0c1d655 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -1290,6 +1290,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + // Spigot start + private final Player.Spigot spigot = new Player.Spigot() + { ++ ++ @Override ++ public boolean getCollidesWithEntities() ++ { ++ return getHandle().collidesWithEntities; ++ } ++ ++ @Override ++ public void setCollidesWithEntities(boolean collides) ++ { ++ getHandle().collidesWithEntities = collides; ++ getHandle().k = collides; // First boolean of Entity ++ } + }; + + public Player.Spigot spigot() +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0046-Fully-Disable-Snooper-When-Not-Required.patch b/CraftBukkit-Patches/0046-Fully-Disable-Snooper-When-Not-Required.patch new file mode 100644 index 0000000000..961a2d3755 --- /dev/null +++ b/CraftBukkit-Patches/0046-Fully-Disable-Snooper-When-Not-Required.patch @@ -0,0 +1,27 @@ +From 48935cd26211ad88fb22037bab50630219a63577 Mon Sep 17 00:00:00 2001 +From: agentk20 +Date: Sat, 3 Aug 2013 19:28:48 +1000 +Subject: [PATCH] Fully Disable Snooper When Not Required + + +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index ac2aad8..16e3596 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -583,11 +583,11 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo + this.g[this.ticks % 100] = System.nanoTime() - i; + this.methodProfiler.b(); + this.methodProfiler.a("snooper"); +- if (!this.l.d() && this.ticks > 100) { ++ if (getSnooperEnabled() && !this.l.d() && this.ticks > 100) { // Spigot + this.l.a(); + } + +- if (this.ticks % 6000 == 0) { ++ if (getSnooperEnabled() && this.ticks % 6000 == 0) { // Spigot + this.l.b(); + } + +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0047-Add-Getter-for-Entity-Invulnerability.patch b/CraftBukkit-Patches/0047-Add-Getter-for-Entity-Invulnerability.patch new file mode 100644 index 0000000000..d9f8741900 --- /dev/null +++ b/CraftBukkit-Patches/0047-Add-Getter-for-Entity-Invulnerability.patch @@ -0,0 +1,25 @@ +From 3d306ebf3a969328046d70d8ef0e7299ec33a2d2 Mon Sep 17 00:00:00 2001 +From: DerFlash +Date: Sat, 3 Aug 2013 19:53:48 +1000 +Subject: [PATCH] Add Getter for Entity Invulnerability + + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +index e026c1f..96d763b 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +@@ -403,6 +403,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { + // Spigot start + private final Spigot spigot = new Spigot() + { ++ @Override ++ public boolean isInvulnerable() ++ { ++ return getHandle().isInvulnerable(); ++ } + }; + + public Spigot spigot() +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0048-Cap-Minimum-Player-Speed.patch b/CraftBukkit-Patches/0048-Cap-Minimum-Player-Speed.patch new file mode 100644 index 0000000000..2f33ad57ac --- /dev/null +++ b/CraftBukkit-Patches/0048-Cap-Minimum-Player-Speed.patch @@ -0,0 +1,31 @@ +From f3cedd8dc2ab7b9e476b4b80c974dd34e094094a Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Mon, 5 Aug 2013 20:17:20 +1000 +Subject: [PATCH] Cap Minimum Player Speed + + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index 0c1d655..e47af0d 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -1162,7 +1162,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + public void setFlySpeed(float value) { + validateSpeed(value); + EntityPlayer player = getHandle(); +- player.abilities.flySpeed = value / 2f; ++ player.abilities.flySpeed = Math.max( value, 0.0001f ) / 2f; // Spigot + player.updateAbilities(); + + } +@@ -1170,7 +1170,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + public void setWalkSpeed(float value) { + validateSpeed(value); + EntityPlayer player = getHandle(); +- player.abilities.walkSpeed = value / 2f; ++ player.abilities.walkSpeed = Math.max( value, 0.0001f ) / 2f; // Spigot + player.updateAbilities(); + } + +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0049-Update-Inventory-and-Health-for-PlayerConsumeItemEve.patch b/CraftBukkit-Patches/0049-Update-Inventory-and-Health-for-PlayerConsumeItemEve.patch new file mode 100644 index 0000000000..6a6ec35363 --- /dev/null +++ b/CraftBukkit-Patches/0049-Update-Inventory-and-Health-for-PlayerConsumeItemEve.patch @@ -0,0 +1,24 @@ +From 743480f0ba5ff6d024d38cb4b825a6753cf14039 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sat, 14 Sep 2013 10:16:38 +1000 +Subject: [PATCH] Update Inventory and Health for PlayerConsumeItemEvent + + +diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java +index 5b50df0..bc55fcc 100644 +--- a/src/main/java/net/minecraft/server/EntityHuman.java ++++ b/src/main/java/net/minecraft/server/EntityHuman.java +@@ -277,6 +277,10 @@ public abstract class EntityHuman extends EntityLiving implements ICommandListen + // Update client + if (this instanceof EntityPlayer) { + ((EntityPlayer) this).playerConnection.sendPacket(new PacketPlayOutSetSlot((byte) 0, activeContainer.a((IInventory) this.inventory, this.inventory.itemInHandIndex).index, this.f)); ++ // Spigot Start ++ ((EntityPlayer) this).getBukkitEntity().updateInventory(); ++ ((EntityPlayer) this).getBukkitEntity().updateScaledHealth(); ++ // Spigot End + } + return; + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0050-Call-EntityChangeBlockEvent-for-Fire-Arrows-hitting-.patch b/CraftBukkit-Patches/0050-Call-EntityChangeBlockEvent-for-Fire-Arrows-hitting-.patch new file mode 100644 index 0000000000..1ed024ba54 --- /dev/null +++ b/CraftBukkit-Patches/0050-Call-EntityChangeBlockEvent-for-Fire-Arrows-hitting-.patch @@ -0,0 +1,35 @@ +From 10449310a86a7232158caf1d0ae880d984d65e51 Mon Sep 17 00:00:00 2001 +From: BlackHole +Date: Tue, 16 Jul 2013 22:34:50 +0200 +Subject: [PATCH] Call EntityChangeBlockEvent for Fire Arrows hitting TNT + +Adds BUKKIT-4355 + +diff --git a/src/main/java/net/minecraft/server/BlockTNT.java b/src/main/java/net/minecraft/server/BlockTNT.java +index e943676..7320a88 100644 +--- a/src/main/java/net/minecraft/server/BlockTNT.java ++++ b/src/main/java/net/minecraft/server/BlockTNT.java +@@ -54,7 +54,7 @@ public class BlockTNT extends Block { + + public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) { + if (entityhuman.bE() != null && entityhuman.bE().getItem() == Items.FLINT_AND_STEEL) { +- this.a(world, i, j, k, 1, entityhuman); ++ this.a(world, i, j, k, 1, (EntityLiving) entityhuman); // Spigot - Fix decompile error! + world.setAir(i, j, k); + entityhuman.bE().damage(1, entityhuman); + return true; +@@ -68,6 +68,11 @@ public class BlockTNT extends Block { + EntityArrow entityarrow = (EntityArrow) entity; + + if (entityarrow.isBurning()) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entityarrow, i, j, k, Blocks.AIR, 0).isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + this.a(world, i, j, k, 1, entityarrow.shooter instanceof EntityLiving ? (EntityLiving) entityarrow.shooter : null); + world.setAir(i, j, k); + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0051-Allow-Disabling-of-1.6.3-Structure-Saving.patch b/CraftBukkit-Patches/0051-Allow-Disabling-of-1.6.3-Structure-Saving.patch new file mode 100644 index 0000000000..7cc004016c --- /dev/null +++ b/CraftBukkit-Patches/0051-Allow-Disabling-of-1.6.3-Structure-Saving.patch @@ -0,0 +1,50 @@ +From d8d5fe8e4c5673b64cb5822a6ef16cca8ecdfad0 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sat, 21 Sep 2013 12:33:09 +1000 +Subject: [PATCH] Allow Disabling of 1.6.3 Structure Saving + + +diff --git a/src/main/java/net/minecraft/server/StructureGenerator.java b/src/main/java/net/minecraft/server/StructureGenerator.java +index 97308d0..4d336d8 100644 +--- a/src/main/java/net/minecraft/server/StructureGenerator.java ++++ b/src/main/java/net/minecraft/server/StructureGenerator.java +@@ -178,7 +178,15 @@ public abstract class StructureGenerator extends WorldGenBase { + + private void a(World world) { + if (this.e == null) { ++ // Spigot Start ++ if ( world.spigotConfig.saveStructureInfo ) ++ { + this.e = (PersistentStructure) world.a(PersistentStructure.class, this.a()); ++ } else ++ { ++ this.e = new PersistentStructure( this.a() ); ++ } ++ // Spigot End + if (this.e == null) { + this.e = new PersistentStructure(this.a()); + world.a(this.a(), (PersistentBase) this.e); +diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java +index adebd03..9586c44 100644 +--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java ++++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java +@@ -184,4 +184,16 @@ public class SpigotWorldConfig + randomLightUpdates = getBoolean( "random-light-updates", false ); + log( "Random Lighting Updates: " + randomLightUpdates ); + } ++ ++ public boolean saveStructureInfo; ++ private void structureInfo() ++ { ++ saveStructureInfo = getBoolean( "save-structure-info", true ); ++ log( "Structure Info Saving: " + saveStructureInfo ); ++ if ( !saveStructureInfo ) ++ { ++ log( "*** WARNING *** You have selected to NOT save structure info. This may cause structures such as fortresses to not spawn mobs when updating to 1.7!" ); ++ log( "*** WARNING *** Please use this option with caution, SpigotMC is not responsible for any issues this option may cause in the future!" ); ++ } ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0052-Item-Despawn-Rate.patch b/CraftBukkit-Patches/0052-Item-Despawn-Rate.patch new file mode 100644 index 0000000000..def7f0a4c6 --- /dev/null +++ b/CraftBukkit-Patches/0052-Item-Despawn-Rate.patch @@ -0,0 +1,38 @@ +From cd876340b86e6271abadd7e4319fe79ac301d0ac Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sun, 22 Sep 2013 19:10:53 +1000 +Subject: [PATCH] Item Despawn Rate + + +diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java +index 95beb11..0f1bcc7 100644 +--- a/src/main/java/net/minecraft/server/EntityItem.java ++++ b/src/main/java/net/minecraft/server/EntityItem.java +@@ -104,7 +104,7 @@ public class EntityItem extends Entity { + } + + // ++this.age; // CraftBukkit - Moved up +- if (!this.world.isStatic && this.age >= 6000) { ++ if (!this.world.isStatic && this.age >= world.spigotConfig.itemDespawnRate) { // Spigot + // CraftBukkit start - fire ItemDespawnEvent + if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemDespawnEvent(this).isCancelled()) { + this.age = 0; +diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java +index 9586c44..82d59e7 100644 +--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java ++++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java +@@ -196,4 +196,11 @@ public class SpigotWorldConfig + log( "*** WARNING *** Please use this option with caution, SpigotMC is not responsible for any issues this option may cause in the future!" ); + } + } ++ ++ public int itemDespawnRate; ++ private void itemDespawnRate() ++ { ++ itemDespawnRate = getInt( "item-despawn-rate", 6000 ); ++ log( "Item Despawn Rate: " + itemDespawnRate ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0053-Don-t-Special-Case-X-Move-Value.patch b/CraftBukkit-Patches/0053-Don-t-Special-Case-X-Move-Value.patch new file mode 100644 index 0000000000..77c43b0440 --- /dev/null +++ b/CraftBukkit-Patches/0053-Don-t-Special-Case-X-Move-Value.patch @@ -0,0 +1,49 @@ +From 5c6e16695c9ffc3378284ca10e0b80598d95cc00 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sun, 6 Oct 2013 17:36:28 +1100 +Subject: [PATCH] Don't Special Case X Move Value + + +diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java +index 917a587..c1ddb33 100644 +--- a/src/main/java/net/minecraft/server/PlayerConnection.java ++++ b/src/main/java/net/minecraft/server/PlayerConnection.java +@@ -106,6 +106,7 @@ public class PlayerConnection implements PacketPlayInListener { + private float lastPitch = Float.MAX_VALUE; + private float lastYaw = Float.MAX_VALUE; + private boolean justTeleported = false; ++ private boolean hasMoved; // Spigot + + // For the PacketPlayOutBlockPlace hack :( + Long lastPacket; +@@ -202,6 +203,18 @@ public class PlayerConnection implements PacketPlayInListener { + + // CraftBukkit start - fire PlayerMoveEvent + Player player = this.getPlayer(); ++ // Spigot Start ++ if ( !hasMoved ) ++ { ++ Location curPos = player.getLocation(); ++ lastPosX = curPos.getX(); ++ lastPosY = curPos.getY(); ++ lastPosZ = curPos.getZ(); ++ lastYaw = curPos.getYaw(); ++ lastPitch = curPos.getPitch(); ++ hasMoved = true; ++ } ++ // Spigot End + Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location. + Location to = player.getLocation().clone(); // Start off the To location as the Players current location. + +@@ -230,7 +243,7 @@ public class PlayerConnection implements PacketPlayInListener { + this.lastPitch = to.getPitch(); + + // Skip the first time we do this +- if (from.getX() != Double.MAX_VALUE) { ++ if (true) { // Spigot - don't skip any move events + PlayerMoveEvent event = new PlayerMoveEvent(player, from, to); + this.server.getPluginManager().callEvent(event); + +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0054-Implement-respawn-API.patch b/CraftBukkit-Patches/0054-Implement-respawn-API.patch new file mode 100644 index 0000000000..5c29cf06d6 --- /dev/null +++ b/CraftBukkit-Patches/0054-Implement-respawn-API.patch @@ -0,0 +1,29 @@ +From 82923f38300b6c62d55ba4e61b10a45d2510ef50 Mon Sep 17 00:00:00 2001 +From: ninja- +Date: Tue, 8 Oct 2013 14:34:49 +0200 +Subject: [PATCH] Implement respawn API. + + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index e47af0d..af2ee8c 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -1303,6 +1303,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + getHandle().collidesWithEntities = collides; + getHandle().k = collides; // First boolean of Entity + } ++ ++ @Override ++ public void respawn() ++ { ++ if ( getHealth() <= 0 && isOnline() ) ++ { ++ server.getServer().getPlayerList().moveToWorld( getHandle(), 0, false ); ++ } ++ } + }; + + public Player.Spigot spigot() +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0055-Fix-BrewingStands-Removing-NBT-Potions.patch b/CraftBukkit-Patches/0055-Fix-BrewingStands-Removing-NBT-Potions.patch new file mode 100644 index 0000000000..02352b9ae3 --- /dev/null +++ b/CraftBukkit-Patches/0055-Fix-BrewingStands-Removing-NBT-Potions.patch @@ -0,0 +1,28 @@ +From acca141f0ca29a93cbb236c490997fb0338cb15f Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Wed, 9 Oct 2013 18:20:05 +1100 +Subject: [PATCH] Fix BrewingStands Removing NBT / Potions + + +diff --git a/src/main/java/net/minecraft/server/BlockBrewingStand.java b/src/main/java/net/minecraft/server/BlockBrewingStand.java +index 3287d77..eabea5a 100644 +--- a/src/main/java/net/minecraft/server/BlockBrewingStand.java ++++ b/src/main/java/net/minecraft/server/BlockBrewingStand.java +@@ -86,7 +86,13 @@ public class BlockBrewingStand extends BlockContainer { + entityitem.motX = (double) ((float) this.a.nextGaussian() * f3); + entityitem.motY = (double) ((float) this.a.nextGaussian() * f3 + 0.2F); + entityitem.motZ = (double) ((float) this.a.nextGaussian() * f3); +- world.addEntity(entityitem); ++ // Spigot Start ++ if ( itemstack.hasTag() ) ++ { ++ entityitem.getItemStack().setTag( (NBTTagCompound) itemstack.getTag().clone() ); ++ } ++ // Spigot End ++ world.addEntity( entityitem ); + } + } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0056-Arrow-Despawn-Rate.patch b/CraftBukkit-Patches/0056-Arrow-Despawn-Rate.patch new file mode 100644 index 0000000000..f0fe009439 --- /dev/null +++ b/CraftBukkit-Patches/0056-Arrow-Despawn-Rate.patch @@ -0,0 +1,38 @@ +From 277c9ec5a89466241ff3af7b171bd6b3db75ec5c Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Mon, 14 Oct 2013 19:20:10 +1100 +Subject: [PATCH] Arrow Despawn Rate + + +diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java/net/minecraft/server/EntityArrow.java +index c2afb17..08232d5 100644 +--- a/src/main/java/net/minecraft/server/EntityArrow.java ++++ b/src/main/java/net/minecraft/server/EntityArrow.java +@@ -144,7 +144,7 @@ public class EntityArrow extends Entity implements IProjectile { + + if (block == this.g && i == this.h) { + ++this.at; +- if (this.at == 1200) { ++ if (this.at == world.spigotConfig.arrowDespawnRate) { + this.die(); + } + } else { +diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java +index 82d59e7..2ec047c 100644 +--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java ++++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java +@@ -203,4 +203,11 @@ public class SpigotWorldConfig + itemDespawnRate = getInt( "item-despawn-rate", 6000 ); + log( "Item Despawn Rate: " + itemDespawnRate ); + } ++ ++ public int arrowDespawnRate; ++ private void arrowDespawnRate() ++ { ++ arrowDespawnRate = getInt( "arrow-despawn-rate", 1200 ); ++ log( "Arrow Despawn Rate: " + arrowDespawnRate ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0057-Watchdog-Thread.patch b/CraftBukkit-Patches/0057-Watchdog-Thread.patch new file mode 100644 index 0000000000..117663204d --- /dev/null +++ b/CraftBukkit-Patches/0057-Watchdog-Thread.patch @@ -0,0 +1,291 @@ +From e09cbea98b0a13596e4c88b797bddeed8bf1a883 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sat, 23 Feb 2013 12:33:20 +1100 +Subject: [PATCH] Watchdog Thread. + + +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 16e3596..883c3b5 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -498,6 +498,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo + this.a(crashreport); + } finally { + try { ++ org.spigotmc.WatchdogThread.doStop(); + this.stop(); + this.isStopped = true; + } catch (Throwable throwable1) { +@@ -688,6 +689,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo + SpigotTimings.tickablesTimer.stopTiming(); // Spigot + + this.methodProfiler.b(); ++ org.spigotmc.WatchdogThread.tick(); // Spigot + SpigotTimings.serverTickTimer.stopTiming(); // Spigot + org.spigotmc.CustomTimingsHandler.tick(); // Spigot + } +diff --git a/src/main/java/org/spigotmc/RestartCommand.java b/src/main/java/org/spigotmc/RestartCommand.java +new file mode 100644 +index 0000000..2d330fc +--- /dev/null ++++ b/src/main/java/org/spigotmc/RestartCommand.java +@@ -0,0 +1,110 @@ ++package org.spigotmc; ++ ++import java.io.File; ++import java.util.List; ++import net.minecraft.server.EntityPlayer; ++import net.minecraft.server.MinecraftServer; ++import org.bukkit.command.Command; ++import org.bukkit.command.CommandSender; ++ ++public class RestartCommand extends Command ++{ ++ ++ public RestartCommand(String name) ++ { ++ super( name ); ++ this.description = "Restarts the server"; ++ this.usageMessage = "/restart"; ++ this.setPermission( "bukkit.command.restart" ); ++ } ++ ++ @Override ++ public boolean execute(CommandSender sender, String currentAlias, String[] args) ++ { ++ if ( testPermission( sender ) ) ++ { ++ restart(); ++ } ++ return true; ++ } ++ ++ public static void restart() ++ { ++ AsyncCatcher.enabled = false; // Disable async catcher incase it interferes with us ++ try ++ { ++ final File file = new File( SpigotConfig.restartScript ); ++ if ( file.isFile() ) ++ { ++ System.out.println( "Attempting to restart with " + SpigotConfig.restartScript ); ++ ++ // Kick all players ++ for ( EntityPlayer p : (List< EntityPlayer>) MinecraftServer.getServer().getPlayerList().players ) ++ { ++ p.playerConnection.disconnect(SpigotConfig.restartMessage); ++ } ++ // Give the socket a chance to send the packets ++ try ++ { ++ Thread.sleep( 100 ); ++ } catch ( InterruptedException ex ) ++ { ++ } ++ // Close the socket so we can rebind with the new process ++ MinecraftServer.getServer().ah().b(); ++ ++ // Give time for it to kick in ++ try ++ { ++ Thread.sleep( 100 ); ++ } catch ( InterruptedException ex ) ++ { ++ } ++ ++ // Actually shutdown ++ try ++ { ++ MinecraftServer.getServer().stop(); ++ } catch ( Throwable t ) ++ { ++ } ++ ++ // This will be done AFTER the server has completely halted ++ Thread shutdownHook = new Thread() ++ { ++ @Override ++ public void run() ++ { ++ try ++ { ++ String os = System.getProperty( "os.name" ).toLowerCase(); ++ if ( os.contains( "win" ) ) ++ { ++ Runtime.getRuntime().exec( "cmd /c start " + file.getPath() ); ++ } else ++ { ++ Runtime.getRuntime().exec( new String[] ++ { ++ "sh", file.getPath() ++ } ); ++ } ++ } catch ( Exception e ) ++ { ++ e.printStackTrace(); ++ } ++ } ++ }; ++ ++ shutdownHook.setDaemon( true ); ++ Runtime.getRuntime().addShutdownHook( shutdownHook ); ++ } else ++ { ++ System.out.println( "Startup script '" + SpigotConfig.restartScript + "' does not exist! Stopping server." ); ++ } ++ System.exit( 0 ); ++ } catch ( Exception ex ) ++ { ++ ex.printStackTrace(); ++ } ++ } ++} +diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java +index efcd193..2b499fe 100644 +--- a/src/main/java/org/spigotmc/SpigotConfig.java ++++ b/src/main/java/org/spigotmc/SpigotConfig.java +@@ -178,4 +178,18 @@ public class SpigotConfig + outdatedClientMessage = transform( getString( "messages.outdated-client", outdatedClientMessage ) ); + outdatedServerMessage = transform( getString( "messages.outdated-server", outdatedServerMessage ) ); + } ++ ++ public static int timeoutTime = 60; ++ public static boolean restartOnCrash = true; ++ public static String restartScript = "./start.sh"; ++ public static String restartMessage; ++ private static void watchdog() ++ { ++ timeoutTime = getInt( "settings.timeout-time", timeoutTime ); ++ restartOnCrash = getBoolean( "settings.restart-on-crash", restartOnCrash ); ++ restartScript = getString( "settings.restart-script", restartScript ); ++ restartMessage = transform( getString( "messages.restart", "Server is restarting" ) ); ++ commands.put( "restart", new RestartCommand( "restart" ) ); ++ WatchdogThread.doStart( timeoutTime, restartOnCrash ); ++ } + } +diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java +new file mode 100644 +index 0000000..de08ad6 +--- /dev/null ++++ b/src/main/java/org/spigotmc/WatchdogThread.java +@@ -0,0 +1,117 @@ ++package org.spigotmc; ++ ++import java.lang.management.ManagementFactory; ++import java.lang.management.MonitorInfo; ++import java.lang.management.ThreadInfo; ++import java.util.logging.Level; ++import java.util.logging.Logger; ++import net.minecraft.server.MinecraftServer; ++import org.bukkit.Bukkit; ++ ++public class WatchdogThread extends Thread ++{ ++ ++ private static WatchdogThread instance; ++ private final long timeoutTime; ++ private final boolean restart; ++ private volatile long lastTick; ++ private volatile boolean stopping; ++ ++ private WatchdogThread(long timeoutTime, boolean restart) ++ { ++ super( "Spigot Watchdog Thread" ); ++ this.timeoutTime = timeoutTime; ++ this.restart = restart; ++ } ++ ++ public static void doStart(int timeoutTime, boolean restart) ++ { ++ if ( instance == null ) ++ { ++ instance = new WatchdogThread( timeoutTime * 1000L, restart ); ++ instance.start(); ++ } ++ } ++ ++ public static void tick() ++ { ++ instance.lastTick = System.currentTimeMillis(); ++ } ++ ++ public static void doStop() ++ { ++ if ( instance != null ) ++ { ++ instance.stopping = true; ++ } ++ } ++ ++ @Override ++ public void run() ++ { ++ while ( !stopping ) ++ { ++ // ++ if ( lastTick != 0 && System.currentTimeMillis() > lastTick + timeoutTime ) ++ { ++ Logger log = Bukkit.getServer().getLogger(); ++ log.log( Level.SEVERE, "The server has stopped responding!" ); ++ log.log( Level.SEVERE, "Please report this to http://www.spigotmc.org/" ); ++ log.log( Level.SEVERE, "Be sure to include ALL relevant console errors and Minecraft crash reports" ); ++ log.log( Level.SEVERE, "Spigot version: " + Bukkit.getServer().getVersion() ); ++ // ++ log.log( Level.SEVERE, "------------------------------" ); ++ log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Spigot!):" ); ++ dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().primaryThread.getId(), Integer.MAX_VALUE ), log ); ++ log.log( Level.SEVERE, "------------------------------" ); ++ // ++ log.log( Level.SEVERE, "Entire Thread Dump:" ); ++ ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads( true, true ); ++ for ( ThreadInfo thread : threads ) ++ { ++ dumpThread( thread, log ); ++ } ++ log.log( Level.SEVERE, "------------------------------" ); ++ ++ if ( restart ) ++ { ++ RestartCommand.restart(); ++ } ++ break; ++ } ++ ++ try ++ { ++ sleep( 10000 ); ++ } catch ( InterruptedException ex ) ++ { ++ interrupt(); ++ } ++ } ++ } ++ ++ private static void dumpThread(ThreadInfo thread, Logger log) ++ { ++ log.log( Level.SEVERE, "------------------------------" ); ++ // ++ log.log( Level.SEVERE, "Current Thread: " + thread.getThreadName() ); ++ log.log( Level.SEVERE, "\tPID: " + thread.getThreadId() ++ + " | Suspended: " + thread.isSuspended() ++ + " | Native: " + thread.isInNative() ++ + " | State: " + thread.getThreadState() ); ++ if ( thread.getLockedMonitors().length != 0 ) ++ { ++ log.log( Level.SEVERE, "\tThread is waiting on monitor(s):" ); ++ for ( MonitorInfo monitor : thread.getLockedMonitors() ) ++ { ++ log.log( Level.SEVERE, "\t\tLocked on:" + monitor.getLockedStackFrame() ); ++ } ++ } ++ log.log( Level.SEVERE, "\tStack:" ); ++ // ++ for ( StackTraceElement stack : thread.getStackTrace() ) ++ { ++ log.log( Level.SEVERE, "\t\t" + stack ); ++ } ++ } ++} +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0058-Fix-packed-ice-generation.patch b/CraftBukkit-Patches/0058-Fix-packed-ice-generation.patch new file mode 100644 index 0000000000..58a0c57467 --- /dev/null +++ b/CraftBukkit-Patches/0058-Fix-packed-ice-generation.patch @@ -0,0 +1,38 @@ +From 781e41cf5b3935d4d4b314f7baf475f3cf81056a Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sun, 1 Dec 2013 17:52:14 +1100 +Subject: [PATCH] Fix packed ice generation + + +diff --git a/src/main/java/net/minecraft/server/WorldGenPackedIce2.java b/src/main/java/net/minecraft/server/WorldGenPackedIce2.java +index c0db754..a830758 100644 +--- a/src/main/java/net/minecraft/server/WorldGenPackedIce2.java ++++ b/src/main/java/net/minecraft/server/WorldGenPackedIce2.java +@@ -41,13 +41,13 @@ public class WorldGenPackedIce2 extends WorldGenerator { + Block block = world.getType(i + l1, j + j1, k + i2); + + if (block.getMaterial() == Material.AIR || block == Blocks.DIRT || block == Blocks.SNOW_BLOCK || block == Blocks.ICE) { +- this.setType(world, i + l1, j + j1, k + i2, Blocks.PACKED_ICE); ++ world.setTypeUpdate(i + l1, j + j1, k + i2, Blocks.PACKED_ICE); // Spigot + } + + if (j1 != 0 && k1 > 1) { + block = world.getType(i + l1, j - j1, k + i2); + if (block.getMaterial() == Material.AIR || block == Blocks.DIRT || block == Blocks.SNOW_BLOCK || block == Blocks.ICE) { +- this.setType(world, i + l1, j - j1, k + i2, Blocks.PACKED_ICE); ++ world.setTypeUpdate(i + l1, j - j1, k + i2, Blocks.PACKED_ICE); // Spigot + } + } + } +@@ -78,7 +78,7 @@ public class WorldGenPackedIce2 extends WorldGenerator { + Block block1 = world.getType(i + j2, l1, k + k1); + + if (block1.getMaterial() == Material.AIR || block1 == Blocks.DIRT || block1 == Blocks.SNOW_BLOCK || block1 == Blocks.ICE || block1 == Blocks.PACKED_ICE) { +- this.setType(world, i + j2, l1, k + k1, Blocks.PACKED_ICE); ++ world.setTypeUpdate(i + j2, l1, k + k1, Blocks.PACKED_ICE); // Spigot + --l1; + --k2; + if (k2 <= 0) { +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0059-Clear-Flower-Pot-on-Drop.patch b/CraftBukkit-Patches/0059-Clear-Flower-Pot-on-Drop.patch new file mode 100644 index 0000000000..fbd8aed061 --- /dev/null +++ b/CraftBukkit-Patches/0059-Clear-Flower-Pot-on-Drop.patch @@ -0,0 +1,21 @@ +From f420cf9bcad51dfc93bcd6fef52d278f0db1a85b Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Tue, 3 Dec 2013 11:07:48 +1100 +Subject: [PATCH] Clear Flower Pot on Drop + + +diff --git a/src/main/java/net/minecraft/server/BlockFlowerPot.java b/src/main/java/net/minecraft/server/BlockFlowerPot.java +index ca6f4f0..0fa90b4 100644 +--- a/src/main/java/net/minecraft/server/BlockFlowerPot.java ++++ b/src/main/java/net/minecraft/server/BlockFlowerPot.java +@@ -90,6 +90,7 @@ public class BlockFlowerPot extends BlockContainer { + + if (tileentityflowerpot != null && tileentityflowerpot.a() != null) { + this.a(world, i, j, k, new ItemStack(tileentityflowerpot.a(), 1, tileentityflowerpot.b())); ++ tileentityflowerpot.a( null, 0 ); // Spigot + } + + super.remove(world, i, j, k, block, l); +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0060-Fix-some-chunks-not-being-sent-to-the-client.patch b/CraftBukkit-Patches/0060-Fix-some-chunks-not-being-sent-to-the-client.patch new file mode 100644 index 0000000000..9516964e30 --- /dev/null +++ b/CraftBukkit-Patches/0060-Fix-some-chunks-not-being-sent-to-the-client.patch @@ -0,0 +1,30 @@ +From ea80c509c6b04cf606dc0b2b8d55abcd082fea31 Mon Sep 17 00:00:00 2001 +From: Thinkofdeath +Date: Mon, 2 Dec 2013 23:42:09 +0000 +Subject: [PATCH] Fix some chunks not being sent to the client + + +diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java +index 3fc83e5..3712009 100644 +--- a/src/main/java/net/minecraft/server/Chunk.java ++++ b/src/main/java/net/minecraft/server/Chunk.java +@@ -930,7 +930,15 @@ public class Chunk { + } + + public boolean k() { +- return this.m && this.done && this.lit; ++ // Spigot Start ++ /* ++ * As of 1.7, Mojang added a check to make sure that only chunks which have been lit are sent to the client. ++ * Unfortunately this interferes with our modified chunk ticking algorithm, which will only tick chunks distant from the player on a very infrequent basis. ++ * We cannot unfortunately do this lighting stage during chunk gen as it appears to put a lot more noticeable load on the server, than when it is done at play time. ++ * For now at least we will simply send all chunks, in accordance with pre 1.7 behaviour. ++ */ ++ return true; ++ // Spigot End + } + + public ChunkCoordIntPair l() { +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0061-Fix-Broken-Async-Chat.patch b/CraftBukkit-Patches/0061-Fix-Broken-Async-Chat.patch new file mode 100644 index 0000000000..617aa081b5 --- /dev/null +++ b/CraftBukkit-Patches/0061-Fix-Broken-Async-Chat.patch @@ -0,0 +1,40 @@ +From 26d428354a8730f2ddd51c761aa5226c1f8150a3 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Thu, 5 Dec 2013 13:55:53 +1100 +Subject: [PATCH] Fix Broken Async Chat + + +diff --git a/src/main/java/net/minecraft/server/PacketPlayInChat.java b/src/main/java/net/minecraft/server/PacketPlayInChat.java +index 604a7af..d419f0f 100644 +--- a/src/main/java/net/minecraft/server/PacketPlayInChat.java ++++ b/src/main/java/net/minecraft/server/PacketPlayInChat.java +@@ -43,7 +43,25 @@ public class PacketPlayInChat extends Packet { + } + // CraftBukkit end + +- public void handle(PacketListener packetlistener) { ++ // Spigot Start ++ private static final java.util.concurrent.ExecutorService executors = java.util.concurrent.Executors.newCachedThreadPool( ++ new com.google.common.util.concurrent.ThreadFactoryBuilder().setDaemon( true ).setNameFormat( "Async Chat Thread - #%d" ).build() ); ++ public void handle(final PacketListener packetlistener) ++ { ++ if ( a() ) ++ { ++ executors.submit( new Runnable() ++ { ++ ++ @Override ++ public void run() ++ { ++ PacketPlayInChat.this.a( (PacketPlayInListener) packetlistener ); ++ } ++ } ); ++ return; ++ } ++ // Spigot End + this.a((PacketPlayInListener) packetlistener); + } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0062-Allow-Teleportation-of-Vehicles-and-Passengers.patch b/CraftBukkit-Patches/0062-Allow-Teleportation-of-Vehicles-and-Passengers.patch new file mode 100644 index 0000000000..d53cef0eca --- /dev/null +++ b/CraftBukkit-Patches/0062-Allow-Teleportation-of-Vehicles-and-Passengers.patch @@ -0,0 +1,40 @@ +From 939807f8187bbeddaad80e17a6f9b5aff5d37b26 Mon Sep 17 00:00:00 2001 +From: ItsHarry +Date: Thu, 5 Dec 2013 21:58:11 +0100 +Subject: [PATCH] Allow Teleportation of Vehicles and Passengers + + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index af2ee8c..217d5dd 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -459,9 +459,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + return false; + } + +- if (entity.vehicle != null || entity.passenger != null) { +- return false; +- } ++ // Spigot Start ++ // if (entity.vehicle != null || entity.passenger != null) { ++ // return false; ++ // } ++ // Spigot End + + // From = Players current Location + Location from = this.getLocation(); +@@ -475,6 +477,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + if (event.isCancelled()) { + return false; + } ++ ++ // Spigot Start ++ eject(); ++ leaveVehicle(); ++ // Spigot End + + // Update the From Location + from = event.getFrom(); +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0063-Remove-OS-X-Special-Chars-from-Signs.patch b/CraftBukkit-Patches/0063-Remove-OS-X-Special-Chars-from-Signs.patch new file mode 100644 index 0000000000..c7bfe0602f --- /dev/null +++ b/CraftBukkit-Patches/0063-Remove-OS-X-Special-Chars-from-Signs.patch @@ -0,0 +1,21 @@ +From 7cb3708727460f4851ac82174340ec5cf6cfa2c5 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sun, 8 Dec 2013 16:52:42 +1100 +Subject: [PATCH] Remove OS X Special Chars from Signs + + +diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java +index c1ddb33..9f3b1a8 100644 +--- a/src/main/java/net/minecraft/server/PlayerConnection.java ++++ b/src/main/java/net/minecraft/server/PlayerConnection.java +@@ -1584,6 +1584,7 @@ public class PlayerConnection implements PacketPlayInListener { + + for (j = 0; j < 4; ++j) { + boolean flag = true; ++ packetplayinupdatesign.f()[j] = packetplayinupdatesign.f()[j].replaceAll( "\uF700", "" ).replaceAll( "\uF701", "" ); // Spigot - Mac OSX sends weird chars + + if (packetplayinupdatesign.f()[j].length() > 15) { + flag = false; +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0064-Orebfuscator.patch b/CraftBukkit-Patches/0064-Orebfuscator.patch new file mode 100644 index 0000000000..30674117a5 --- /dev/null +++ b/CraftBukkit-Patches/0064-Orebfuscator.patch @@ -0,0 +1,397 @@ +From a0f89c1e4ffcf797b4d4754a4eb1953325f0f365 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Thu, 16 May 2013 18:51:05 +1000 +Subject: [PATCH] Orebfuscator + + +diff --git a/src/main/java/net/minecraft/server/EntityFallingBlock.java b/src/main/java/net/minecraft/server/EntityFallingBlock.java +index bc51217..8335e89 100644 +--- a/src/main/java/net/minecraft/server/EntityFallingBlock.java ++++ b/src/main/java/net/minecraft/server/EntityFallingBlock.java +@@ -86,6 +86,7 @@ public class EntityFallingBlock extends Entity { + } + + this.world.setAir(i, j, k); ++ world.spigotConfig.antiXrayInstance.updateNearbyBlocks(world, i, j, k); // Spigot + } + + if (this.onGround) { +@@ -101,6 +102,7 @@ public class EntityFallingBlock extends Entity { + } + this.world.setTypeAndData(i, j, k, this.id, this.data, 3); + // CraftBukkit end ++ world.spigotConfig.antiXrayInstance.updateNearbyBlocks(world, i, j, k); // Spigot + + if (this.id instanceof BlockFalling) { + ((BlockFalling) this.id).a(this.world, i, j, k, this.data); +diff --git a/src/main/java/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java +index d6ac728..229b296 100644 +--- a/src/main/java/net/minecraft/server/Explosion.java ++++ b/src/main/java/net/minecraft/server/Explosion.java +@@ -239,6 +239,7 @@ public class Explosion { + j = chunkposition.y; + k = chunkposition.z; + block = this.world.getType(i, j, k); ++ world.spigotConfig.antiXrayInstance.updateNearbyBlocks(world, i, j, k); // Spigot + if (flag) { + double d0 = (double) ((float) i + this.world.random.nextFloat()); + double d1 = (double) ((float) j + this.world.random.nextFloat()); +diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java +index 09b34e9..3006712 100644 +--- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java ++++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java +@@ -28,6 +28,7 @@ public class PacketPlayOutMapChunk extends Packet { + + this.d = chunkmap.c; + this.c = chunkmap.b; ++ chunk.world.spigotConfig.antiXrayInstance.obfuscateSync(chunk.locX, chunk.locZ, i, chunkmap.a, chunk.world); // Spigot + + try { + this.buffer = chunkmap.a; +diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java +index bf3a139..30bf8a7 100644 +--- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java ++++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java +@@ -26,6 +26,7 @@ public class PacketPlayOutMapChunkBulk extends Packet { + } + }; + // CraftBukkit end ++ private World world; // Spigot + + public PacketPlayOutMapChunkBulk() {} + +@@ -44,6 +45,9 @@ public class PacketPlayOutMapChunkBulk extends Packet { + Chunk chunk = (Chunk) list.get(k); + ChunkMap chunkmap = PacketPlayOutMapChunk.a(chunk, true, '\uffff'); + ++ // Spigot start ++ world = chunk.world; ++ /* + if (buildBuffer.length < j + chunkmap.a.length) { + byte[] abyte = new byte[j + chunkmap.a.length]; + +@@ -52,6 +56,8 @@ public class PacketPlayOutMapChunkBulk extends Packet { + } + + System.arraycopy(chunkmap.a, 0, buildBuffer, j, chunkmap.a.length); ++ */ ++ // Spigot end + j += chunkmap.a.length; + this.a[k] = chunk.locX; + this.b[k] = chunk.locZ; +@@ -79,6 +85,22 @@ public class PacketPlayOutMapChunkBulk extends Packet { + if (this.buffer != null) { + return; + } ++ // Spigot start ++ int finalBufferSize = 0; ++ // Obfuscate all sections ++ for (int i = 0; i < a.length; i++) { ++ world.spigotConfig.antiXrayInstance.obfuscate(a[i], b[i], c[i], inflatedBuffers[i], world); ++ finalBufferSize += inflatedBuffers[i].length; ++ } ++ ++ // Now it's time to efficiently copy the chunk to the build buffer ++ buildBuffer = new byte[finalBufferSize]; ++ int bufferLocation = 0; ++ for (int i = 0; i < a.length; i++) { ++ System.arraycopy(inflatedBuffers[i], 0, buildBuffer, bufferLocation, inflatedBuffers[i].length); ++ bufferLocation += inflatedBuffers[i].length; ++ } ++ // Spigot end + + Deflater deflater = localDeflater.get(); + deflater.reset(); +diff --git a/src/main/java/net/minecraft/server/PlayerInteractManager.java b/src/main/java/net/minecraft/server/PlayerInteractManager.java +index 2db45ad..97fe53c 100644 +--- a/src/main/java/net/minecraft/server/PlayerInteractManager.java ++++ b/src/main/java/net/minecraft/server/PlayerInteractManager.java +@@ -173,6 +173,7 @@ public class PlayerInteractManager { + this.o = i1; + } + } ++ world.spigotConfig.antiXrayInstance.updateNearbyBlocks(world, i, j, k); // Spigot + } + } + +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index b0b9757..98900ed 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -471,6 +471,7 @@ public abstract class World implements IBlockAccess { + this.e(i, j + 1, k, block); + this.e(i, j, k - 1, block); + this.e(i, j, k + 1, block); ++ spigotConfig.antiXrayInstance.updateNearbyBlocks(this, i, j, k); // Spigot + } + + public void b(int i, int j, int k, Block block, int l) { +diff --git a/src/main/java/org/spigotmc/AntiXray.java b/src/main/java/org/spigotmc/AntiXray.java +new file mode 100644 +index 0000000..8e69bff +--- /dev/null ++++ b/src/main/java/org/spigotmc/AntiXray.java +@@ -0,0 +1,212 @@ ++package org.spigotmc; ++ ++import gnu.trove.set.TByteSet; ++import gnu.trove.set.hash.TByteHashSet; ++import net.minecraft.server.Block; ++import net.minecraft.server.Blocks; ++import net.minecraft.server.World; ++ ++public class AntiXray ++{ ++ ++ private static final CustomTimingsHandler update = new CustomTimingsHandler( "xray - update" ); ++ private static final CustomTimingsHandler obfuscate = new CustomTimingsHandler( "xray - obfuscate" ); ++ /*========================================================================*/ ++ // Used to keep track of which blocks to obfuscate ++ private final boolean[] obfuscateBlocks = new boolean[ Short.MAX_VALUE ]; ++ // Used to select a random replacement ore ++ private final byte[] replacementOres; ++ ++ public AntiXray(SpigotWorldConfig config) ++ { ++ // Set all listed blocks as true to be obfuscated ++ for ( int id : ( config.engineMode == 1 ) ? config.hiddenBlocks : config.replaceBlocks ) ++ { ++ obfuscateBlocks[id] = true; ++ } ++ ++ // For every block ++ TByteSet blocks = new TByteHashSet(); ++ for ( Integer i : config.hiddenBlocks ) ++ { ++ Block block = Block.e( i ); ++ // Check it exists and is not a tile entity ++ if ( block != null && !block.isTileEntity() ) ++ { ++ // Add it to the set of replacement blocks ++ blocks.add( (byte) (int) i ); ++ } ++ } ++ // Bake it to a flat array of replacements ++ replacementOres = blocks.toArray(); ++ } ++ ++ /** ++ * Starts the timings handler, then updates all blocks within the set radius ++ * of the given coordinate, revealing them if they are hidden ores. ++ */ ++ public void updateNearbyBlocks(World world, int x, int y, int z) ++ { ++ if ( world.spigotConfig.antiXray ) ++ { ++ update.startTiming(); ++ updateNearbyBlocks( world, x, y, z, 2, false ); // 2 is the radius, we shouldn't change it as that would make it exponentially slower ++ update.stopTiming(); ++ } ++ } ++ ++ /** ++ * Starts the timings handler, and then removes all non exposed ores from ++ * the chunk buffer. ++ */ ++ public void obfuscateSync(int chunkX, int chunkY, int bitmask, byte[] buffer, World world) ++ { ++ if ( world.spigotConfig.antiXray ) ++ { ++ obfuscate.startTiming(); ++ obfuscate( chunkX, chunkY, bitmask, buffer, world ); ++ obfuscate.stopTiming(); ++ } ++ } ++ ++ /** ++ * Removes all non exposed ores from the chunk buffer. ++ */ ++ public void obfuscate(int chunkX, int chunkY, int bitmask, byte[] buffer, World world) ++ { ++ // If the world is marked as obfuscated ++ if ( world.spigotConfig.antiXray ) ++ { ++ // Initial radius to search around for air ++ int initialRadius = 1; ++ // Which block in the buffer we are looking at, anywhere from 0 to 16^4 ++ int index = 0; ++ // The iterator marking which random ore we should use next ++ int randomOre = 0; ++ ++ // Chunk corner X and Z blocks ++ int startX = chunkX << 4; ++ int startZ = chunkY << 4; ++ ++ // Chunks can have up to 16 sections ++ for ( int i = 0; i < 16; i++ ) ++ { ++ // If the bitmask indicates this chunk is sent... ++ if ( ( bitmask & 1 << i ) != 0 ) ++ { ++ // Work through all blocks in the chunk, y,z,x ++ for ( int y = 0; y < 16; y++ ) ++ { ++ for ( int z = 0; z < 16; z++ ) ++ { ++ for ( int x = 0; x < 16; x++ ) ++ { ++ // For some reason we can get too far ahead of ourselves (concurrent modification on bulk chunks?) so if we do, just abort and move on ++ if ( index >= buffer.length ) ++ { ++ index++; ++ continue; ++ } ++ // Grab the block ID in the buffer. ++ // TODO: extended IDs are not yet supported ++ int blockId = buffer[index] & 0xFF; ++ // Check if the block should be obfuscated ++ if ( obfuscateBlocks[blockId] ) ++ { ++ // The world isn't loaded, bail out ++ if ( !isLoaded( world, startX + x, ( i << 4 ) + y, startZ + z, initialRadius ) ) ++ { ++ index++; ++ continue; ++ } ++ // On the otherhand, if radius is 0, or the nearby blocks are all non air, we can obfuscate ++ if ( !hasTransparentBlockAdjacent( world, startX + x, ( i << 4 ) + y, startZ + z, initialRadius ) ) ++ { ++ switch ( world.spigotConfig.engineMode ) ++ { ++ case 1: ++ // Replace with stone ++ buffer[index] = 1; ++ break; ++ case 2: ++ // Replace with random ore. ++ if ( randomOre >= replacementOres.length ) ++ { ++ randomOre = 0; ++ } ++ buffer[index] = replacementOres[randomOre++]; ++ break; ++ } ++ } ++ } ++ ++ index++; ++ } ++ } ++ } ++ } ++ } ++ } ++ } ++ ++ private void updateNearbyBlocks(World world, int x, int y, int z, int radius, boolean updateSelf) ++ { ++ // If the block in question is loaded ++ if ( world.isLoaded( x, y, z ) ) ++ { ++ // Get block id ++ Block block = world.getType(x, y, z); ++ ++ // See if it needs update ++ if ( updateSelf && obfuscateBlocks[Block.b(block)] ) ++ { ++ // Send the update ++ world.notify( x, y, z ); ++ } ++ ++ // Check other blocks for updates ++ if ( radius > 0 ) ++ { ++ updateNearbyBlocks( world, x + 1, y, z, radius - 1, true ); ++ updateNearbyBlocks( world, x - 1, y, z, radius - 1, true ); ++ updateNearbyBlocks( world, x, y + 1, z, radius - 1, true ); ++ updateNearbyBlocks( world, x, y - 1, z, radius - 1, true ); ++ updateNearbyBlocks( world, x, y, z + 1, radius - 1, true ); ++ updateNearbyBlocks( world, x, y, z - 1, radius - 1, true ); ++ } ++ } ++ } ++ ++ private static boolean isLoaded(World world, int x, int y, int z, int radius) ++ { ++ return world.isLoaded( x, y, z ) ++ && ( radius == 0 || ++ ( isLoaded( world, x + 1, y, z, radius - 1 ) ++ && isLoaded( world, x - 1, y, z, radius - 1 ) ++ && isLoaded( world, x, y + 1, z, radius - 1 ) ++ && isLoaded( world, x, y - 1, z, radius - 1 ) ++ && isLoaded( world, x, y, z + 1, radius - 1 ) ++ && isLoaded( world, x, y, z - 1, radius - 1 ) ) ); ++ } ++ ++ private static boolean hasTransparentBlockAdjacent(World world, int x, int y, int z, int radius) ++ { ++ return !isSolidBlock(world.getType(x, y, z)) /* isSolidBlock */ ++ || ( radius > 0 ++ && ( hasTransparentBlockAdjacent( world, x + 1, y, z, radius - 1 ) ++ || hasTransparentBlockAdjacent( world, x - 1, y, z, radius - 1 ) ++ || hasTransparentBlockAdjacent( world, x, y + 1, z, radius - 1 ) ++ || hasTransparentBlockAdjacent( world, x, y - 1, z, radius - 1 ) ++ || hasTransparentBlockAdjacent( world, x, y, z + 1, radius - 1 ) ++ || hasTransparentBlockAdjacent( world, x, y, z - 1, radius - 1 ) ) ); ++ } ++ ++ private static boolean isSolidBlock(Block block) { ++ // Mob spawners are treated as solid blocks as far as the ++ // game is concerned for lighting and other tasks but for ++ // rendering they can be seen through therefor we special ++ // case them so that the antixray doesn't show the fake ++ // blocks around them. ++ return block.r() && block != Blocks.MOB_SPAWNER; ++ } ++} +diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java +index 2ec047c..2c0501d 100644 +--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java ++++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java +@@ -1,5 +1,6 @@ + package org.spigotmc; + ++import java.util.Arrays; + import java.util.List; + import org.bukkit.Bukkit; + import org.bukkit.configuration.file.YamlConfiguration; +@@ -210,4 +211,36 @@ public class SpigotWorldConfig + arrowDespawnRate = getInt( "arrow-despawn-rate", 1200 ); + log( "Arrow Despawn Rate: " + arrowDespawnRate ); + } ++ ++ public boolean antiXray; ++ public int engineMode; ++ public List hiddenBlocks; ++ public List replaceBlocks; ++ public AntiXray antiXrayInstance; ++ private void antiXray() ++ { ++ antiXray = getBoolean( "anti-xray.enabled", true ); ++ log( "Anti X-Ray: " + antiXray ); ++ ++ engineMode = getInt( "anti-xray.engine-mode", 1 ); ++ log( "\tEngine Mode: " + engineMode ); ++ ++ if ( SpigotConfig.version < 5 ) ++ { ++ set( "anti-xray.blocks", null ); ++ } ++ hiddenBlocks = getList( "anti-xray.hide-blocks", Arrays.asList( new Integer[] ++ { ++ 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130 ++ } ) ); ++ log( "\tHidden Blocks: " + hiddenBlocks ); ++ ++ replaceBlocks = getList( "anti-xray.replace-blocks", Arrays.asList( new Integer[] ++ { ++ 1, 5 ++ } ) ); ++ log( "\tReplace Blocks: " + replaceBlocks ); ++ ++ antiXrayInstance = new AntiXray( this ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0065-Optimize-DataWatcher.patch b/CraftBukkit-Patches/0065-Optimize-DataWatcher.patch new file mode 100644 index 0000000000..88439b1c94 --- /dev/null +++ b/CraftBukkit-Patches/0065-Optimize-DataWatcher.patch @@ -0,0 +1,134 @@ +From 1ec055e01968b90c4098480749669240324766f8 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Fri, 13 Dec 2013 11:45:47 +1100 +Subject: [PATCH] Optimize DataWatcher + +Use primitive orientated collections, as well as more effective copies across collections. + +diff --git a/src/main/java/net/minecraft/server/DataWatcher.java b/src/main/java/net/minecraft/server/DataWatcher.java +index 90a2a80..cca6bd9 100644 +--- a/src/main/java/net/minecraft/server/DataWatcher.java ++++ b/src/main/java/net/minecraft/server/DataWatcher.java +@@ -14,8 +14,13 @@ public class DataWatcher { + + private final Entity a; + private boolean b = true; +- private static final HashMap c = new HashMap(); +- private final Map d = new HashMap(); ++ // Spigot Start ++ private static final gnu.trove.map.TObjectIntMap classToId = new gnu.trove.map.hash.TObjectIntHashMap( 10, 0.5f, -1 ); ++ private final gnu.trove.map.TIntObjectMap dataValues = new gnu.trove.map.hash.TIntObjectHashMap( 10, 0.5f, -1 ); ++ // These exist as an attempt at backwards compatability for (broken) NMS plugins ++ private static final Map c = gnu.trove.TDecorators.wrap( classToId ); ++ private final Map d = gnu.trove.TDecorators.wrap( dataValues ); ++ // Spigot End + private boolean e; + private ReadWriteLock f = new ReentrantReadWriteLock(); + +@@ -24,19 +29,19 @@ public class DataWatcher { + } + + public void a(int i, Object object) { +- Integer integer = (Integer) c.get(object.getClass()); ++ int integer = classToId.get(object.getClass()); // Spigot + +- if (integer == null) { ++ if (integer == -1) { // Spigot + throw new IllegalArgumentException("Unknown data type: " + object.getClass()); + } else if (i > 31) { + throw new IllegalArgumentException("Data value id is too big with " + i + "! (Max is " + 31 + ")"); +- } else if (this.d.containsKey(Integer.valueOf(i))) { ++ } else if (this.dataValues.containsKey(i)) { // Spigot + throw new IllegalArgumentException("Duplicate id value for " + i + "!"); + } else { +- WatchableObject watchableobject = new WatchableObject(integer.intValue(), i, object); ++ WatchableObject watchableobject = new WatchableObject(integer, i, object); // Spigot + + this.f.writeLock().lock(); +- this.d.put(Integer.valueOf(i), watchableobject); ++ this.dataValues.put(i, watchableobject); // Spigot + this.f.writeLock().unlock(); + this.b = false; + } +@@ -46,7 +51,7 @@ public class DataWatcher { + WatchableObject watchableobject = new WatchableObject(j, i, null); + + this.f.writeLock().lock(); +- this.d.put(Integer.valueOf(i), watchableobject); ++ this.dataValues.put(i, watchableobject); // Spigot + this.f.writeLock().unlock(); + this.b = false; + } +@@ -81,7 +86,7 @@ public class DataWatcher { + WatchableObject watchableobject; + + try { +- watchableobject = (WatchableObject) this.d.get(Integer.valueOf(i)); ++ watchableobject = (WatchableObject) this.dataValues.get(i); // Spigot + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Getting synched entity data"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Synched entity data"); +@@ -133,7 +138,7 @@ public class DataWatcher { + + if (this.e) { + this.f.readLock().lock(); +- Iterator iterator = this.d.values().iterator(); ++ Iterator iterator = this.dataValues.valueCollection().iterator(); // Spigot + + while (iterator.hasNext()) { + WatchableObject watchableobject = (WatchableObject) iterator.next(); +@@ -157,7 +162,7 @@ public class DataWatcher { + + public void a(PacketDataSerializer packetdataserializer) { + this.f.readLock().lock(); +- Iterator iterator = this.d.values().iterator(); ++ Iterator iterator = this.dataValues.valueCollection().iterator(); // Spigot + + while (iterator.hasNext()) { + WatchableObject watchableobject = (WatchableObject) iterator.next(); +@@ -170,18 +175,11 @@ public class DataWatcher { + } + + public List c() { +- ArrayList arraylist = null; ++ ArrayList arraylist = new ArrayList(); // Spigot + + this.f.readLock().lock(); + +- WatchableObject watchableobject; +- +- for (Iterator iterator = this.d.values().iterator(); iterator.hasNext(); arraylist.add(watchableobject)) { +- watchableobject = (WatchableObject) iterator.next(); +- if (arraylist == null) { +- arraylist = new ArrayList(); +- } +- } ++ arraylist.addAll(this.dataValues.valueCollection()); // Spigot + + this.f.readLock().unlock(); + return arraylist; +@@ -295,12 +293,14 @@ public class DataWatcher { + } + + static { +- c.put(Byte.class, Integer.valueOf(0)); +- c.put(Short.class, Integer.valueOf(1)); +- c.put(Integer.class, Integer.valueOf(2)); +- c.put(Float.class, Integer.valueOf(3)); +- c.put(String.class, Integer.valueOf(4)); +- c.put(ItemStack.class, Integer.valueOf(5)); +- c.put(ChunkCoordinates.class, Integer.valueOf(6)); ++ // Spigot Start - remove valueOf ++ classToId.put(Byte.class, 0); ++ classToId.put(Short.class, 1); ++ classToId.put(Integer.class, 2); ++ classToId.put(Float.class, 3); ++ classToId.put(String.class, 4); ++ classToId.put(ItemStack.class, 5); ++ classToId.put(ChunkCoordinates.class, 6); ++ // Spigot End + } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0066-Fire-PreLogin-Events-in-Offline-Mode.patch b/CraftBukkit-Patches/0066-Fire-PreLogin-Events-in-Offline-Mode.patch new file mode 100644 index 0000000000..c198bef14b --- /dev/null +++ b/CraftBukkit-Patches/0066-Fire-PreLogin-Events-in-Offline-Mode.patch @@ -0,0 +1,159 @@ +From b3766c829b07913655f7238d91b865fe3884be2f Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Wed, 18 Dec 2013 13:32:10 +1100 +Subject: [PATCH] Fire PreLogin Events in Offline Mode + + +diff --git a/src/main/java/net/minecraft/server/LoginListener.java b/src/main/java/net/minecraft/server/LoginListener.java +index 8f982f1..eb227bc 100644 +--- a/src/main/java/net/minecraft/server/LoginListener.java ++++ b/src/main/java/net/minecraft/server/LoginListener.java +@@ -59,10 +59,23 @@ public class LoginListener implements PacketLoginInListener { + } + } + ++ // Spigot start ++ public void initUUID() ++ { ++ String uuid = UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + this.i.getName() ).getBytes( Charsets.UTF_8 ) ).toString().replaceAll( "-", "" ); ++ ++ this.i = new GameProfile( uuid, this.i.getName() ); ++ } ++ // Spigot end ++ + public void c() { ++ // Spigot start - Moved to initUUID ++ /* + if (!this.i.isComplete()) { + this.i = this.a(this.i); + } ++ */ ++ // Spigot end + + // CraftBukkit start - fire PlayerLoginEvent + EntityPlayer s = this.server.getPlayerList().attemptLogin(this, this.i, this.hostname); +@@ -97,7 +110,7 @@ public class LoginListener implements PacketLoginInListener { + this.g = EnumProtocolState.KEY; + this.networkManager.handle(new PacketLoginOutEncryptionBegin(this.j, this.server.K().getPublic(), this.e), new GenericFutureListener[0]); + } else { +- this.g = EnumProtocolState.READY_TO_ACCEPT; ++ (new ThreadPlayerLookupUUID(this, "User Authenticator #" + b.incrementAndGet())).start(); // Spigot + } + } + +diff --git a/src/main/java/net/minecraft/server/ThreadPlayerLookupUUID.java b/src/main/java/net/minecraft/server/ThreadPlayerLookupUUID.java +index 6b91be7..b41ed2f 100644 +--- a/src/main/java/net/minecraft/server/ThreadPlayerLookupUUID.java ++++ b/src/main/java/net/minecraft/server/ThreadPlayerLookupUUID.java +@@ -25,50 +25,19 @@ class ThreadPlayerLookupUUID extends Thread { + GameProfile gameprofile = LoginListener.a(this.a); + + try { ++ // Spigot Start ++ if ( !LoginListener.b( this.a ).getOnlineMode() ) ++ { ++ a.initUUID(); ++ fireLoginEvents(); ++ return; ++ } ++ // Spigot End + String s = (new BigInteger(MinecraftEncryption.a(LoginListener.b(this.a), LoginListener.c(this.a).K().getPublic(), LoginListener.d(this.a)))).toString(16); + + LoginListener.a(this.a, LoginListener.c(this.a).av().hasJoinedServer(new GameProfile((UUID) null, gameprofile.getName()), s)); + if (LoginListener.a(this.a) != null) { +- // CraftBukkit start - fire PlayerPreLoginEvent +- if (!this.a.networkManager.isConnected()) { +- return; +- } +- +- String playerName = LoginListener.a(this.a).getName(); +- java.net.InetAddress address = ((java.net.InetSocketAddress) a.networkManager.getSocketAddress()).getAddress(); +- java.util.UUID uniqueId = LoginListener.a(this.a).getId(); +- final org.bukkit.craftbukkit.CraftServer server = LoginListener.c(this.a).server; +- +- AsyncPlayerPreLoginEvent asyncEvent = new AsyncPlayerPreLoginEvent(playerName, address, uniqueId); +- server.getPluginManager().callEvent(asyncEvent); +- +- if (PlayerPreLoginEvent.getHandlerList().getRegisteredListeners().length != 0) { +- final PlayerPreLoginEvent event = new PlayerPreLoginEvent(playerName, address, uniqueId); +- if (asyncEvent.getResult() != PlayerPreLoginEvent.Result.ALLOWED) { +- event.disallow(asyncEvent.getResult(), asyncEvent.getKickMessage()); +- } +- Waitable waitable = new Waitable() { +- @Override +- protected PlayerPreLoginEvent.Result evaluate() { +- server.getPluginManager().callEvent(event); +- return event.getResult(); +- }}; +- +- LoginListener.c(this.a).processQueue.add(waitable); +- if (waitable.get() != PlayerPreLoginEvent.Result.ALLOWED) { +- this.a.disconnect(event.getKickMessage()); +- return; +- } +- } else { +- if (asyncEvent.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) { +- this.a.disconnect(asyncEvent.getKickMessage()); +- return; +- } +- } +- // CraftBukkit end +- +- LoginListener.e().info("UUID of player " + LoginListener.a(this.a).getName() + " is " + LoginListener.a(this.a).getId()); +- LoginListener.a(this.a, EnumProtocolState.READY_TO_ACCEPT); ++ fireLoginEvents(); // Spigot + } else if (LoginListener.c(this.a).N()) { + LoginListener.e().warn("Failed to verify username but will let them in anyway!"); + LoginListener.a(this.a, this.a.a(gameprofile)); +@@ -93,4 +62,48 @@ class ThreadPlayerLookupUUID extends Thread { + // CraftBukkit end + } + } ++ ++ private void fireLoginEvents() throws Exception ++ { ++ // CraftBukkit start - fire PlayerPreLoginEvent ++ if (!this.a.networkManager.isConnected()) { ++ return; ++ } ++ ++ String playerName = LoginListener.a(this.a).getName(); ++ java.net.InetAddress address = ((java.net.InetSocketAddress) a.networkManager.getSocketAddress()).getAddress(); ++ java.util.UUID uniqueId = LoginListener.a(this.a).getId(); ++ final org.bukkit.craftbukkit.CraftServer server = LoginListener.c(this.a).server; ++ ++ AsyncPlayerPreLoginEvent asyncEvent = new AsyncPlayerPreLoginEvent(playerName, address, uniqueId); ++ server.getPluginManager().callEvent(asyncEvent); ++ ++ if (PlayerPreLoginEvent.getHandlerList().getRegisteredListeners().length != 0) { ++ final PlayerPreLoginEvent event = new PlayerPreLoginEvent(playerName, address, uniqueId); ++ if (asyncEvent.getResult() != PlayerPreLoginEvent.Result.ALLOWED) { ++ event.disallow(asyncEvent.getResult(), asyncEvent.getKickMessage()); ++ } ++ Waitable waitable = new Waitable() { ++ @Override ++ protected PlayerPreLoginEvent.Result evaluate() { ++ server.getPluginManager().callEvent(event); ++ return event.getResult(); ++ }}; ++ ++ LoginListener.c(this.a).processQueue.add(waitable); ++ if (waitable.get() != PlayerPreLoginEvent.Result.ALLOWED) { ++ this.a.disconnect(event.getKickMessage()); ++ return; ++ } ++ } else { ++ if (asyncEvent.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) { ++ this.a.disconnect(asyncEvent.getKickMessage()); ++ return; ++ } ++ } ++ // CraftBukkit end ++ ++ LoginListener.e().info("UUID of player " + LoginListener.a(this.a).getName() + " is " + LoginListener.a(this.a).getId()); ++ LoginListener.a(this.a, EnumProtocolState.READY_TO_ACCEPT); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0067-BungeeCord-Support.patch b/CraftBukkit-Patches/0067-BungeeCord-Support.patch new file mode 100644 index 0000000000..c70aff56a7 --- /dev/null +++ b/CraftBukkit-Patches/0067-BungeeCord-Support.patch @@ -0,0 +1,133 @@ +From 7a40301085d45e555e5d980b663a03fc7215870e Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sun, 1 Dec 2013 18:18:41 +1100 +Subject: [PATCH] BungeeCord Support + +Provides support for IP forwarding via BungeeCord. + +diff --git a/src/main/java/net/minecraft/server/HandshakeListener.java b/src/main/java/net/minecraft/server/HandshakeListener.java +index b98079c..0542db3 100644 +--- a/src/main/java/net/minecraft/server/HandshakeListener.java ++++ b/src/main/java/net/minecraft/server/HandshakeListener.java +@@ -73,6 +73,22 @@ public class HandshakeListener implements PacketHandshakingInListener { + this.b.close(chatcomponenttext); + } else { + this.b.a((PacketListener) (new LoginListener(this.a, this.b))); ++ // Spigot Start ++ if (org.spigotmc.SpigotConfig.bungee) { ++ String[] split = packethandshakinginsetprotocol.b.split("\00"); ++ if ( split.length == 3 ) { ++ packethandshakinginsetprotocol.b = split[0]; ++ b.n = new java.net.InetSocketAddress(split[1], ((java.net.InetSocketAddress) b.getSocketAddress()).getPort()); ++ b.spoofedUUID = split[2]; ++ } else ++ { ++ chatcomponenttext = new ChatComponentText("If you wish to use IP forwarding, please enable it in your BungeeCord config as well!"); ++ this.b.handle(new PacketLoginOutDisconnect(chatcomponenttext), new GenericFutureListener[0]); ++ this.b.close(chatcomponenttext); ++ return; ++ } ++ } ++ // Spigot End + ((LoginListener) this.b.getPacketListener()).hostname = packethandshakinginsetprotocol.b + ":" + packethandshakinginsetprotocol.c; // CraftBukkit - set hostname + } + break; +diff --git a/src/main/java/net/minecraft/server/LoginListener.java b/src/main/java/net/minecraft/server/LoginListener.java +index eb227bc..04d9f73 100644 +--- a/src/main/java/net/minecraft/server/LoginListener.java ++++ b/src/main/java/net/minecraft/server/LoginListener.java +@@ -62,8 +62,14 @@ public class LoginListener implements PacketLoginInListener { + // Spigot start + public void initUUID() + { +- String uuid = UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + this.i.getName() ).getBytes( Charsets.UTF_8 ) ).toString().replaceAll( "-", "" ); +- ++ String uuid; ++ if ( networkManager.spoofedUUID != null ) ++ { ++ uuid = networkManager.spoofedUUID; ++ } else ++ { ++ uuid = UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + this.i.getName() ).getBytes( Charsets.UTF_8 ) ).toString().replaceAll("-", ""); ++ } + this.i = new GameProfile( uuid, this.i.getName() ); + } + // Spigot end +diff --git a/src/main/java/net/minecraft/server/NetworkManager.java b/src/main/java/net/minecraft/server/NetworkManager.java +index 1dd2227..c4a86bf 100644 +--- a/src/main/java/net/minecraft/server/NetworkManager.java ++++ b/src/main/java/net/minecraft/server/NetworkManager.java +@@ -36,7 +36,8 @@ public class NetworkManager extends SimpleChannelInboundHandler { + private final Queue k = Queues.newConcurrentLinkedQueue(); + private final Queue l = Queues.newConcurrentLinkedQueue(); + private Channel m; +- private SocketAddress n; ++ public SocketAddress n; // Spigot ++ public String spoofedUUID; // Spigot + private PacketListener o; + private EnumProtocol p; + private IChatBaseComponent q; +@@ -198,4 +199,11 @@ public class NetworkManager extends SimpleChannelInboundHandler { + static Channel a(NetworkManager networkmanager) { + return networkmanager.m; + } ++ ++ // Spigot Start ++ public SocketAddress getRawAddress() ++ { ++ return this.m.remoteAddress(); ++ } ++ // Spigot End + } +diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java +index 9c98a62..d2a378e 100644 +--- a/src/main/java/net/minecraft/server/PlayerList.java ++++ b/src/main/java/net/minecraft/server/PlayerList.java +@@ -350,7 +350,7 @@ public abstract class PlayerList { + + EntityPlayer entity = new EntityPlayer(this.server, this.server.getWorldServer(0), gameprofile, new PlayerInteractManager(this.server.getWorldServer(0))); + Player player = entity.getBukkitEntity(); +- PlayerLoginEvent event = new PlayerLoginEvent(player, hostname, ((java.net.InetSocketAddress) socketaddress).getAddress()); ++ PlayerLoginEvent event = new PlayerLoginEvent(player, hostname, ((java.net.InetSocketAddress) socketaddress).getAddress(), ((java.net.InetSocketAddress) loginlistener.networkManager.getRawAddress()).getAddress()); + String s; + + if (this.j.isBanned(gameprofile)) { +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index 217d5dd..7655b65 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -1299,6 +1299,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + { + + @Override ++ public InetSocketAddress getRawAddress() ++ { ++ return (InetSocketAddress) getHandle().playerConnection.networkManager.getRawAddress(); ++ } ++ ++ @Override + public boolean getCollidesWithEntities() + { + return getHandle().collidesWithEntities; +diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java +index 2b499fe..8bfffa5 100644 +--- a/src/main/java/org/spigotmc/SpigotConfig.java ++++ b/src/main/java/org/spigotmc/SpigotConfig.java +@@ -192,4 +192,14 @@ public class SpigotConfig + commands.put( "restart", new RestartCommand( "restart" ) ); + WatchdogThread.doStart( timeoutTime, restartOnCrash ); + } ++ ++ public static boolean bungee; ++ private static void bungee() { ++ if ( version < 4 ) ++ { ++ set( "settings.bungeecord", false ); ++ System.out.println( "Oudated config, disabling BungeeCord support!" ); ++ } ++ bungee = getBoolean( "settings.bungeecord", false ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0068-Allow-Disabling-Zombie-Villager-Aggression.patch b/CraftBukkit-Patches/0068-Allow-Disabling-Zombie-Villager-Aggression.patch new file mode 100644 index 0000000000..f42f6aa6ce --- /dev/null +++ b/CraftBukkit-Patches/0068-Allow-Disabling-Zombie-Villager-Aggression.patch @@ -0,0 +1,48 @@ +From 9a5885281074f60ef4292ee59dcddc60cef45bba Mon Sep 17 00:00:00 2001 +From: Dylan Xaldin +Date: Thu, 12 Dec 2013 18:05:03 -0600 +Subject: [PATCH] Allow Disabling Zombie Villager Aggression + +Ability to configure if Zombies will be aggressive towards Villagers. + +diff --git a/src/main/java/net/minecraft/server/EntityZombie.java b/src/main/java/net/minecraft/server/EntityZombie.java +index a0b6f62..9098bfb 100644 +--- a/src/main/java/net/minecraft/server/EntityZombie.java ++++ b/src/main/java/net/minecraft/server/EntityZombie.java +@@ -28,7 +28,7 @@ public class EntityZombie extends EntityMonster { + this.getNavigation().b(true); + this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, EntityHuman.class, 1.0D, false)); +- this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, EntityVillager.class, 1.0D, true)); ++ if ( world.spigotConfig.zombieAggressiveTowardsVillager ) { this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, EntityVillager.class, 1.0D, true)); } // Spigot + this.goalSelector.a(5, new PathfinderGoalMoveTowardsRestriction(this, 1.0D)); + this.goalSelector.a(6, new PathfinderGoalMoveThroughVillage(this, 1.0D, false)); + this.goalSelector.a(7, new PathfinderGoalRandomStroll(this, 1.0D)); +@@ -36,7 +36,7 @@ public class EntityZombie extends EntityMonster { + this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true)); + this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, 0, true)); +- this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityVillager.class, 0, false)); ++ if ( world.spigotConfig.zombieAggressiveTowardsVillager ) { this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityVillager.class, 0, false)); } // Spigot + this.a(0.6F, 1.8F); + } + +diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java +index 2c0501d..042280d 100644 +--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java ++++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java +@@ -243,4 +243,11 @@ public class SpigotWorldConfig + + antiXrayInstance = new AntiXray( this ); + } ++ ++ public boolean zombieAggressiveTowardsVillager; ++ private void zombieAggressiveTowardsVillager() ++ { ++ zombieAggressiveTowardsVillager = getBoolean( "zombie-aggressive-towards-villager", true ); ++ log( "Zombie Aggressive Towards Villager: " + zombieAggressiveTowardsVillager ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0069-Configurable-Amount-of-Netty-Threads.patch b/CraftBukkit-Patches/0069-Configurable-Amount-of-Netty-Threads.patch new file mode 100644 index 0000000000..b1a9d75522 --- /dev/null +++ b/CraftBukkit-Patches/0069-Configurable-Amount-of-Netty-Threads.patch @@ -0,0 +1,57 @@ +From ad25620d462d5fe70065feced92acd4e7f8ac4d4 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Fri, 13 Dec 2013 11:58:58 +1100 +Subject: [PATCH] Configurable Amount of Netty Threads + +This brings back the option that the Spigot version of netty saw. By default Netty will try and use cores*2 threads, however if running multiple servers on the same machine, this can be too many threads. Additionally some people have 16 core servers. If 32 Netty threads are allowed in this setup, then the lock contention, and thus blocking between threads becomes much greater, leading to decreased performance. + +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 883c3b5..3053053 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -54,7 +54,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo + private final List n = new ArrayList(); + private final ICommandHandler o; + public final MethodProfiler methodProfiler = new MethodProfiler(); +- private final ServerConnection p; ++ private ServerConnection p; // Spigot + private final ServerPing q = new ServerPing(); + private final Random r = new Random(); + private String serverIp; +@@ -113,7 +113,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo + j = this; + this.d = proxy; + // this.universe = file1; // CraftBukkit +- this.p = new ServerConnection(this); ++ // this.p = new ServerConnection(this); // Spigot + this.o = new CommandDispatcher(); + // this.convertable = new WorldLoaderServer(file1); // CraftBukkit - moved to DedicatedServer.init + this.T = new YggdrasilAuthenticationService(proxy, UUID.randomUUID().toString()); +@@ -1244,7 +1244,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo + } + + public ServerConnection ai() { +- return this.p; ++ return ( this.p ) == null ? this.p = new ServerConnection( this ) : this.p; // Spigot + } + + public boolean ak() { +diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java +index 8bfffa5..b3278fd 100644 +--- a/src/main/java/org/spigotmc/SpigotConfig.java ++++ b/src/main/java/org/spigotmc/SpigotConfig.java +@@ -202,4 +202,11 @@ public class SpigotConfig + } + bungee = getBoolean( "settings.bungeecord", false ); + } ++ ++ private static void nettyThreads() ++ { ++ int count = getInt( "settings.netty-threads", 4 ); ++ System.setProperty( "io.netty.eventLoopThreads", Integer.toString( count ) ); ++ Bukkit.getLogger().log( Level.INFO, "Using {0} threads for Netty based IO", count ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0070-Prevent-Mineshaft-Saving.patch b/CraftBukkit-Patches/0070-Prevent-Mineshaft-Saving.patch new file mode 100644 index 0000000000..f6e5f48786 --- /dev/null +++ b/CraftBukkit-Patches/0070-Prevent-Mineshaft-Saving.patch @@ -0,0 +1,22 @@ +From f2e587d7c13c76078d412cb7c61ac9dc8e4660f1 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Fri, 13 Dec 2013 15:21:02 +1100 +Subject: [PATCH] Prevent Mineshaft Saving + + +diff --git a/src/main/java/net/minecraft/server/StructureGenerator.java b/src/main/java/net/minecraft/server/StructureGenerator.java +index 4d336d8..f835b01 100644 +--- a/src/main/java/net/minecraft/server/StructureGenerator.java ++++ b/src/main/java/net/minecraft/server/StructureGenerator.java +@@ -179,7 +179,7 @@ public abstract class StructureGenerator extends WorldGenBase { + private void a(World world) { + if (this.e == null) { + // Spigot Start +- if ( world.spigotConfig.saveStructureInfo ) ++ if ( world.spigotConfig.saveStructureInfo && !this.a().equals( "Mineshaft" ) ) + { + this.e = (PersistentStructure) world.a(PersistentStructure.class, this.a()); + } else +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0071-Log-Cause-of-Unexpected-Exceptions.patch b/CraftBukkit-Patches/0071-Log-Cause-of-Unexpected-Exceptions.patch new file mode 100644 index 0000000000..00839517ed --- /dev/null +++ b/CraftBukkit-Patches/0071-Log-Cause-of-Unexpected-Exceptions.patch @@ -0,0 +1,26 @@ +From 8332b116219b32b6ac8eb349934b5353cc4dac1e Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Wed, 18 Dec 2013 13:39:14 +1100 +Subject: [PATCH] Log Cause of Unexpected Exceptions + + +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 3053053..95eb0c0 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -479,6 +479,12 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo + } + } catch (Throwable throwable) { + i.error("Encountered an unexpected exception", throwable); ++ // Spigot Start ++ if ( throwable.getCause() != null ) ++ { ++ i.error( "\tCause of unexpected exception was", throwable.getCause() ); ++ } ++ // Spigot End + CrashReport crashreport = null; + + if (throwable instanceof ReportedException) { +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0072-Particle-API.patch b/CraftBukkit-Patches/0072-Particle-API.patch new file mode 100644 index 0000000000..2131dee337 --- /dev/null +++ b/CraftBukkit-Patches/0072-Particle-API.patch @@ -0,0 +1,175 @@ +From 376b021ec1cfa26a6fad36a00976ab87f4506ae8 Mon Sep 17 00:00:00 2001 +From: Thinkofdeath +Date: Fri, 20 Dec 2013 21:36:06 +0000 +Subject: [PATCH] Particle API + + +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftEffect.java b/src/main/java/org/bukkit/craftbukkit/CraftEffect.java +index 7de0de5..7eca388 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftEffect.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftEffect.java +@@ -55,6 +55,8 @@ public class CraftEffect { + Validate.isTrue(((Material) data).isBlock(), "Material is not a block!"); + datavalue = ((Material) data).getId(); + break; ++ case ITEM_BREAK: ++ datavalue = ((Material) data).getId(); + default: + datavalue = 0; + } +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +index bfa8c23..827ec16 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +@@ -779,28 +779,18 @@ public class CraftWorld implements World { + Validate.isTrue(effect.getData() == null, "Wrong kind of data for this effect!"); + } + +- int datavalue = data == null ? 0 : CraftEffect.getDataValue(effect, data); +- playEffect(loc, effect, datavalue, radius); ++ if (data != null && data.getClass().equals( org.bukkit.material.MaterialData.class )) { ++ org.bukkit.material.MaterialData materialData = (org.bukkit.material.MaterialData) data; ++ Validate.isTrue( materialData.getItemType().isBlock(), "Material must be block" ); ++ spigot().playEffect( loc, effect, materialData.getItemType().getId(), materialData.getData(), 0, 0, 0, 1, 1, radius ); ++ } else { ++ int dataValue = data == null ? 0 : CraftEffect.getDataValue( effect, data ); ++ playEffect( loc, effect, dataValue, radius ); ++ } + } + + public void playEffect(Location location, Effect effect, int data, int radius) { +- Validate.notNull(location, "Location cannot be null"); +- Validate.notNull(effect, "Effect cannot be null"); +- Validate.notNull(location.getWorld(), "World cannot be null"); +- int packetData = effect.getId(); +- PacketPlayOutWorldEvent packet = new PacketPlayOutWorldEvent(packetData, location.getBlockX(), location.getBlockY(), location.getBlockZ(), data, false); +- int distance; +- radius *= radius; +- +- for (Player player : getPlayers()) { +- if (((CraftPlayer) player).getHandle().playerConnection == null) continue; +- if (!location.getWorld().equals(player.getWorld())) continue; +- +- distance = (int) player.getLocation().distanceSquared(location); +- if (distance <= radius) { +- ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); +- } +- } ++ spigot().playEffect( location, effect, data, 0, 0, 0, 0, 1, 1, radius ); + } + + public T spawn(Location location, Class clazz) throws IllegalArgumentException { +@@ -1286,6 +1276,56 @@ public class CraftWorld implements World { + // Spigot start + private final Spigot spigot = new Spigot() + { ++ @Override ++ public void playEffect( Location location, Effect effect, int id, int data, float offsetX, float offsetY, float offsetZ, float speed, int particleCount, int radius ) ++ { ++ Validate.notNull( location, "Location cannot be null" ); ++ Validate.notNull( effect, "Effect cannot be null" ); ++ Validate.notNull( location.getWorld(), "World cannot be null" ); ++ Packet packet; ++ if ( effect.getType() != Effect.Type.PARTICLE ) ++ { ++ int packetData = effect.getId(); ++ packet = new PacketPlayOutWorldEvent( packetData, location.getBlockX(), location.getBlockY(), location.getBlockZ(), id, false ); ++ } else ++ { ++ StringBuilder particleFullName = new StringBuilder(); ++ particleFullName.append( effect.getName() ); ++ if ( effect.getData() != null && ( effect.getData().equals( Material.class ) || effect.getData().equals( org.bukkit.material.MaterialData.class ) ) ) ++ { ++ particleFullName.append( '_' ).append( id ); ++ } ++ if ( effect.getData() != null && effect.getData().equals( org.bukkit.material.MaterialData.class ) ) ++ { ++ particleFullName.append( '_' ).append( data ); ++ } ++ packet = new PacketPlayOutWorldParticles( particleFullName.toString(), (float) location.getX(), (float) location.getY(), (float) location.getZ(), offsetX, offsetY, offsetZ, speed, particleCount ); ++ } ++ int distance; ++ radius *= radius; ++ for ( Player player : getPlayers() ) ++ { ++ if ( ( (CraftPlayer) player ).getHandle().playerConnection == null ) ++ { ++ continue; ++ } ++ if ( !location.getWorld().equals( player.getWorld() ) ) ++ { ++ continue; ++ } ++ distance = (int) player.getLocation().distanceSquared( location ); ++ if ( distance <= radius ) ++ { ++ ( (CraftPlayer) player ).getHandle().playerConnection.sendPacket( packet ); ++ } ++ } ++ } ++ ++ @Override ++ public void playEffect( Location location, Effect effect ) ++ { ++ CraftWorld.this.playEffect( location, effect, 0 ); ++ } + }; + + public Spigot spigot() +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index 7655b65..5726302 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -1325,6 +1325,49 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + server.getServer().getPlayerList().moveToWorld( getHandle(), 0, false ); + } + } ++ ++ @Override ++ public void playEffect( Location location, Effect effect, int id, int data, float offsetX, float offsetY, float offsetZ, float speed, int particleCount, int radius ) ++ { ++ Validate.notNull( location, "Location cannot be null" ); ++ Validate.notNull( effect, "Effect cannot be null" ); ++ Validate.notNull( location.getWorld(), "World cannot be null" ); ++ Packet packet; ++ if ( effect.getType() != Effect.Type.PARTICLE ) ++ { ++ int packetData = effect.getId(); ++ packet = new PacketPlayOutWorldEvent( packetData, location.getBlockX(), location.getBlockY(), location.getBlockZ(), id, false ); ++ } else ++ { ++ StringBuilder particleFullName = new StringBuilder(); ++ particleFullName.append( effect.getName() ); ++ if ( effect.getData() != null && ( effect.getData().equals( Material.class ) || effect.getData().equals( org.bukkit.material.MaterialData.class ) ) ) ++ { ++ particleFullName.append( '_' ).append( id ); ++ } ++ if ( effect.getData() != null && effect.getData().equals( org.bukkit.material.MaterialData.class ) ) ++ { ++ particleFullName.append( '_' ).append( data ); ++ } ++ packet = new PacketPlayOutWorldParticles( particleFullName.toString(), (float) location.getX(), (float) location.getY(), (float) location.getZ(), offsetX, offsetY, offsetZ, speed, particleCount ); ++ } ++ int distance; ++ radius *= radius; ++ if ( getHandle().playerConnection == null ) ++ { ++ return; ++ } ++ if ( !location.getWorld().equals( getWorld() ) ) ++ { ++ return; ++ } ++ ++ distance = (int) getLocation().distanceSquared( location ); ++ if ( distance <= radius ) ++ { ++ getHandle().playerConnection.sendPacket( packet ); ++ } ++ } + }; + + public Player.Spigot spigot() +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0073-Fix-Biome-Decoration-Crashes.patch b/CraftBukkit-Patches/0073-Fix-Biome-Decoration-Crashes.patch new file mode 100644 index 0000000000..2772d712e4 --- /dev/null +++ b/CraftBukkit-Patches/0073-Fix-Biome-Decoration-Crashes.patch @@ -0,0 +1,111 @@ +From 588665caa81c35531fe1d8d487f883dd796c4965 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sun, 5 Jan 2014 09:35:01 +1100 +Subject: [PATCH] Fix Biome Decoration Crashes + +We don't really know what affect this will have on the terrain generation, but its better than crashing and not having terrain generate at all! + +diff --git a/src/main/java/net/minecraft/server/BiomeDecorator.java b/src/main/java/net/minecraft/server/BiomeDecorator.java +index b048d6c..962d719 100644 +--- a/src/main/java/net/minecraft/server/BiomeDecorator.java ++++ b/src/main/java/net/minecraft/server/BiomeDecorator.java +@@ -147,7 +147,7 @@ public class BiomeDecorator { + for (j = 0; j < this.z; ++j) { + k = this.c + this.b.nextInt(16) + 8; + l = this.d + this.b.nextInt(16) + 8; +- i1 = this.b.nextInt(this.a.getHighestBlockYAt(k, l) * 2); ++ i1 = this.b.nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot + WorldGenerator worldgenerator = biomebase.b(this.b); + + worldgenerator.a(this.a, this.b, k, i1, l); +@@ -156,7 +156,7 @@ public class BiomeDecorator { + for (j = 0; j < this.A; ++j) { + k = this.c + this.b.nextInt(16) + 8; + l = this.d + this.b.nextInt(16) + 8; +- i1 = this.b.nextInt(this.a.getHighestBlockYAt(k, l) * 2); ++ i1 = this.b.nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot + (new WorldGenDeadBush(Blocks.DEAD_BUSH)).a(this.a, this.b, k, i1, l); + } + +@@ -164,7 +164,7 @@ public class BiomeDecorator { + k = this.c + this.b.nextInt(16) + 8; + l = this.d + this.b.nextInt(16) + 8; + +- for (i1 = this.b.nextInt(this.a.getHighestBlockYAt(k, l) * 2); i1 > 0 && this.a.isEmpty(k, i1 - 1, l); --i1) { ++ for (i1 = this.b.nextInt(this.getHighestBlockYAt(k, l) * 2); i1 > 0 && this.a.isEmpty(k, i1 - 1, l); --i1) { // Spigot + ; + } + +@@ -182,7 +182,7 @@ public class BiomeDecorator { + if (this.b.nextInt(8) == 0) { + k = this.c + this.b.nextInt(16) + 8; + l = this.d + this.b.nextInt(16) + 8; +- i1 = this.b.nextInt(this.a.getHighestBlockYAt(k, l) * 2); ++ i1 = this.b.nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot + this.r.a(this.a, this.b, k, i1, l); + } + } +@@ -190,42 +190,42 @@ public class BiomeDecorator { + if (this.b.nextInt(4) == 0) { + j = this.c + this.b.nextInt(16) + 8; + k = this.d + this.b.nextInt(16) + 8; +- l = this.b.nextInt(this.a.getHighestBlockYAt(j, k) * 2); ++ l = this.b.nextInt(this.getHighestBlockYAt(j, k) * 2); // Spigot + this.q.a(this.a, this.b, j, l, k); + } + + if (this.b.nextInt(8) == 0) { + j = this.c + this.b.nextInt(16) + 8; + k = this.d + this.b.nextInt(16) + 8; +- l = this.b.nextInt(this.a.getHighestBlockYAt(j, k) * 2); ++ l = this.b.nextInt(this.getHighestBlockYAt(j, k) * 2); // Spigot + this.r.a(this.a, this.b, j, l, k); + } + + for (j = 0; j < this.C; ++j) { + k = this.c + this.b.nextInt(16) + 8; + l = this.d + this.b.nextInt(16) + 8; +- i1 = this.b.nextInt(this.a.getHighestBlockYAt(k, l) * 2); ++ i1 = this.b.nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot + this.t.a(this.a, this.b, k, i1, l); + } + + for (j = 0; j < 10; ++j) { + k = this.c + this.b.nextInt(16) + 8; + l = this.d + this.b.nextInt(16) + 8; +- i1 = this.b.nextInt(this.a.getHighestBlockYAt(k, l) * 2); ++ i1 = this.b.nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot + this.t.a(this.a, this.b, k, i1, l); + } + + if (this.b.nextInt(32) == 0) { + j = this.c + this.b.nextInt(16) + 8; + k = this.d + this.b.nextInt(16) + 8; +- l = this.b.nextInt(this.a.getHighestBlockYAt(j, k) * 2); ++ l = this.b.nextInt(this.getHighestBlockYAt(j, k) * 2); // Spigot + (new WorldGenPumpkin()).a(this.a, this.b, j, l, k); + } + + for (j = 0; j < this.D; ++j) { + k = this.c + this.b.nextInt(16) + 8; + l = this.d + this.b.nextInt(16) + 8; +- i1 = this.b.nextInt(this.a.getHighestBlockYAt(k, l) * 2); ++ i1 = this.b.nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot + this.u.a(this.a, this.b, k, i1, l); + } + +@@ -276,4 +276,11 @@ public class BiomeDecorator { + this.a(1, this.n, 0, 16); + this.b(1, this.o, 16, 16); + } ++ ++ // Spigot Start ++ private int getHighestBlockYAt(int x, int z) ++ { ++ return Math.max( 1, this.a.getHighestBlockYAt( x, z ) ); ++ } ++ // Spigot End + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0074-Save-ticks-lived-to-nbttag.patch b/CraftBukkit-Patches/0074-Save-ticks-lived-to-nbttag.patch new file mode 100644 index 0000000000..58e1901198 --- /dev/null +++ b/CraftBukkit-Patches/0074-Save-ticks-lived-to-nbttag.patch @@ -0,0 +1,30 @@ +From 98fffaa1f249dc2b18d7f7348141961e7fa51e7d Mon Sep 17 00:00:00 2001 +From: DerFlash +Date: Tue, 9 Jul 2013 00:11:12 +0200 +Subject: [PATCH] Save ticks lived to nbttag + + +diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java +index b13968d..27b0a25 100644 +--- a/src/main/java/net/minecraft/server/Entity.java ++++ b/src/main/java/net/minecraft/server/Entity.java +@@ -1132,6 +1132,7 @@ public abstract class Entity { + nbttagcompound.setLong("WorldUUIDLeast", this.world.getDataManager().getUUID().getLeastSignificantBits()); + nbttagcompound.setLong("WorldUUIDMost", this.world.getDataManager().getUUID().getMostSignificantBits()); + nbttagcompound.setInt("Bukkit.updateLevel", CURRENT_LEVEL); ++ nbttagcompound.setInt("Spigot.ticksLived", this.ticksLived); + // CraftBukkit end + this.b(nbttagcompound); + if (this.vehicle != null) { +@@ -1200,6 +1201,8 @@ public abstract class Entity { + if (this instanceof EntityLiving) { + EntityLiving entity = (EntityLiving) this; + ++ this.ticksLived = nbttagcompound.getInt("Spigot.ticksLived"); ++ + // Reset the persistence for tamed animals + if (entity instanceof EntityTameableAnimal && !isLevelAtLeast(nbttagcompound, 2) && !nbttagcompound.getBoolean("PersistenceRequired")) { + EntityInsentient entityinsentient = (EntityInsentient) entity; +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0075-More-Efficient-GetCubes.patch b/CraftBukkit-Patches/0075-More-Efficient-GetCubes.patch new file mode 100644 index 0000000000..288682415d --- /dev/null +++ b/CraftBukkit-Patches/0075-More-Efficient-GetCubes.patch @@ -0,0 +1,68 @@ +From b4e5810cb71e98485b6c6acf2792e42e15c3daf8 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Tue, 11 Jun 2013 12:17:37 +1000 +Subject: [PATCH] More Efficient GetCubes + + +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index 98900ed..c0a4bea 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -1051,23 +1051,42 @@ public abstract class World implements IBlockAccess { + int i1 = MathHelper.floor(axisalignedbb.c); + int j1 = MathHelper.floor(axisalignedbb.f + 1.0D); + +- for (int k1 = i; k1 < j; ++k1) { +- for (int l1 = i1; l1 < j1; ++l1) { +- if (this.isLoaded(k1, 64, l1)) { +- for (int i2 = k - 1; i2 < l; ++i2) { +- Block block; +- +- if (k1 >= -30000000 && k1 < 30000000 && l1 >= -30000000 && l1 < 30000000) { +- block = this.getType(k1, i2, l1); +- } else { +- block = Blocks.STONE; ++ // Spigot start ++ int ystart = ( ( k - 1 ) < 0 ) ? 0 : ( k - 1 ); ++ for ( int chunkx = ( i >> 4 ); chunkx <= ( ( j - 1 ) >> 4 ); chunkx++ ) ++ { ++ int cx = chunkx << 4; ++ for ( int chunkz = ( i1 >> 4 ); chunkz <= ( ( j1 - 1 ) >> 4 ); chunkz++ ) ++ { ++ if ( !this.isChunkLoaded( chunkx, chunkz ) ) ++ { ++ continue; ++ } ++ int cz = chunkz << 4; ++ Chunk chunk = this.getChunkAt( chunkx, chunkz ); ++ // Compute ranges within chunk ++ int xstart = ( i < cx ) ? cx : i; ++ int xend = ( j < ( cx + 16 ) ) ? j : ( cx + 16 ); ++ int zstart = ( i1 < cz ) ? cz : i1; ++ int zend = ( j1 < ( cz + 16 ) ) ? j1 : ( cz + 16 ); ++ // Loop through blocks within chunk ++ for ( int x = xstart; x < xend; x++ ) ++ { ++ for ( int z = zstart; z < zend; z++ ) ++ { ++ for ( int y = ystart; y < l; y++ ) ++ { ++ Block block = chunk.getType(x - cx, y, z - cz ); ++ if ( block != null ) ++ { ++ block.a( this, x, y, z, axisalignedbb, this.L, entity ); ++ } + } +- +- block.a(this, k1, i2, l1, axisalignedbb, this.L, entity); + } + } + } + } ++ // Spigot end + + double d0 = 0.25D; + List list = this.getEntities(entity, axisalignedbb.grow(d0, d0, d0)); +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0076-Add-Option-to-Nerf-Mobs-from-Spawner-s.patch b/CraftBukkit-Patches/0076-Add-Option-to-Nerf-Mobs-from-Spawner-s.patch new file mode 100644 index 0000000000..a0f099ddf5 --- /dev/null +++ b/CraftBukkit-Patches/0076-Add-Option-to-Nerf-Mobs-from-Spawner-s.patch @@ -0,0 +1,84 @@ +From 8c22f674aff9a23cc32cc20204ffbd3c077565df Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sun, 2 Feb 2014 16:55:46 +0000 +Subject: [PATCH] Add Option to Nerf Mobs from Spawner's + + +diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java +index 27b0a25..0ec07c2 100644 +--- a/src/main/java/net/minecraft/server/Entity.java ++++ b/src/main/java/net/minecraft/server/Entity.java +@@ -118,6 +118,7 @@ public abstract class Entity { + public final byte activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this); + public final boolean defaultActivationState; + public long activatedTick = 0; ++ public boolean fromMobSpawner; + public void inactiveTick() { } + // Spigot end + +diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java +index 7079ed7..ef81600 100644 +--- a/src/main/java/net/minecraft/server/EntityInsentient.java ++++ b/src/main/java/net/minecraft/server/EntityInsentient.java +@@ -417,6 +417,12 @@ public abstract class EntityInsentient extends EntityLiving { + this.world.methodProfiler.a("checkDespawn"); + this.w(); + this.world.methodProfiler.b(); ++ // Spigot Start ++ if ( this.fromMobSpawner ) ++ { ++ return; ++ } ++ // Spigot End + this.world.methodProfiler.a("sensing"); + this.bq.a(); + this.world.methodProfiler.b(); +diff --git a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java +index b97ac4b..23f09f7 100644 +--- a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java ++++ b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java +@@ -136,6 +136,12 @@ public abstract class MobSpawnerAbstract { + SpawnerSpawnEvent event = CraftEventFactory.callSpawnerSpawnEvent(entity, this.b(), this.c(), this.d()); + if (!event.isCancelled()) { + entity.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit ++ // Spigot Start ++ if ( entity.world.spigotConfig.nerfSpawnerMobs ) ++ { ++ entity.fromMobSpawner = true; ++ } ++ // Spigot End + } + // CraftBukkit end + } +@@ -181,6 +187,12 @@ public abstract class MobSpawnerAbstract { + SpawnerSpawnEvent event = CraftEventFactory.callSpawnerSpawnEvent(entity, this.b(), this.c(), this.d()); + if (!event.isCancelled()) { + this.a().addEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit ++ // Spigot Start ++ if ( entity.world.spigotConfig.nerfSpawnerMobs ) ++ { ++ entity.fromMobSpawner = true; ++ } ++ // Spigot End + } + // CraftBukkit end + } +diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java +index 042280d..558e9cd 100644 +--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java ++++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java +@@ -250,4 +250,11 @@ public class SpigotWorldConfig + zombieAggressiveTowardsVillager = getBoolean( "zombie-aggressive-towards-villager", true ); + log( "Zombie Aggressive Towards Villager: " + zombieAggressiveTowardsVillager ); + } ++ ++ public boolean nerfSpawnerMobs; ++ private void nerfSpawnerMobs() ++ { ++ nerfSpawnerMobs = getBoolean( "nerf-spawner-mobs", false ); ++ log( "Nerfing mobs spawned from spawners: " + nerfSpawnerMobs ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0077-Warn-if-PermGen-may-be-insufficient.patch b/CraftBukkit-Patches/0077-Warn-if-PermGen-may-be-insufficient.patch new file mode 100644 index 0000000000..9b4173018d --- /dev/null +++ b/CraftBukkit-Patches/0077-Warn-if-PermGen-may-be-insufficient.patch @@ -0,0 +1,36 @@ +From 9fade57b306688afd24a2f9cb671a1ac254618a2 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Mon, 23 Dec 2013 14:07:41 +1100 +Subject: [PATCH] Warn if PermGen may be insufficient + + +diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java +index 8d127fb..008e037 100644 +--- a/src/main/java/org/bukkit/craftbukkit/Main.java ++++ b/src/main/java/org/bukkit/craftbukkit/Main.java +@@ -155,6 +155,22 @@ public class Main { + useConsole = false; + } + ++ // Spigot Start ++ int maxPermGen = 0; // In kb ++ for ( String s : java.lang.management.ManagementFactory.getRuntimeMXBean().getInputArguments() ) ++ { ++ if ( s.startsWith( "-XX:MaxPermSize" ) ) ++ { ++ maxPermGen = Integer.parseInt( s.replaceAll( "[^\\d]", "" ) ); ++ maxPermGen <<= 10 * ("kmg".indexOf( Character.toLowerCase( s.charAt( s.length() - 1 ) ) ) ); ++ } ++ } ++ if ( Float.parseFloat( System.getProperty( "java.class.version" ) ) < 52 && maxPermGen < ( 128 << 10 ) ) // 128mb ++ { ++ System.out.println( "Warning, your max perm gen size is not set or less than 128mb. It is recommended you restart Java with the following argument: -XX:MaxPermSize=128M" ); ++ System.out.println( "Please see http://www.spigotmc.org/wiki/changing-permgen-size/ for more details and more in-depth instructions." ); ++ } ++ // Spigot End + System.out.println("Loading libraries, please wait..."); + MinecraftServer.main(options); + } catch (Throwable t) { +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0078-Disable-Connected-Check-on-setScoreboard.patch b/CraftBukkit-Patches/0078-Disable-Connected-Check-on-setScoreboard.patch new file mode 100644 index 0000000000..289330f1a7 --- /dev/null +++ b/CraftBukkit-Patches/0078-Disable-Connected-Check-on-setScoreboard.patch @@ -0,0 +1,22 @@ +From 195e2747739ba50bbb38cbb6520136631e992054 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Mon, 23 Dec 2013 15:57:57 +1100 +Subject: [PATCH] Disable Connected Check on setScoreboard + + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index 5726302..2c129ac 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -1225,7 +1225,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + throw new IllegalStateException("Cannot set scoreboard yet"); + } + if (playerConnection.isDisconnected()) { +- throw new IllegalStateException("Cannot set scoreboard for invalid CraftPlayer"); ++ // throw new IllegalStateException("Cannot set scoreboard for invalid CraftPlayer"); // Spigot - remove this as Mojang's semi asynchronous Netty implementation can lead to races + } + + this.server.getScoreboardManager().setPlayerBoard(this, scoreboard); +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0079-Add-Late-Bind-Option.patch b/CraftBukkit-Patches/0079-Add-Late-Bind-Option.patch new file mode 100644 index 0000000000..9eb162205b --- /dev/null +++ b/CraftBukkit-Patches/0079-Add-Late-Bind-Option.patch @@ -0,0 +1,63 @@ +From 14989e29d31c4e7f5e58368caa64a150867e2566 Mon Sep 17 00:00:00 2001 +From: slide23 +Date: Fri, 20 Dec 2013 20:15:33 -0600 +Subject: [PATCH] Add Late Bind Option + +Add late-bind config option to delay binding until loading is done. + +diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java +index 74e28cc..befcdbd 100644 +--- a/src/main/java/net/minecraft/server/DedicatedServer.java ++++ b/src/main/java/net/minecraft/server/DedicatedServer.java +@@ -119,6 +119,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer + this.a(MinecraftEncryption.b()); + i.info("Starting Minecraft server on " + (this.getServerIp().length() == 0 ? "*" : this.getServerIp()) + ":" + this.L()); + ++ if (!org.spigotmc.SpigotConfig.lateBind) { + try { + this.ai().a(inetaddress, this.L()); + } catch (Throwable ioexception) { // CraftBukkit - IOException -> Throwable +@@ -127,6 +128,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer + i.warn("Perhaps a server is already running on that port?"); + return false; + } ++ } + + // Spigot Start - Move DedicatedPlayerList up and bring plugin loading from CraftServer to here + // this.a((PlayerList) (new DedicatedPlayerList(this))); +@@ -193,6 +195,18 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer + String s3 = String.format("%.3fs", new Object[] { Double.valueOf((double) i1 / 1.0E9D)}); + + i.info("Done (" + s3 + ")! For help, type \"help\" or \"?\""); ++ ++ if (org.spigotmc.SpigotConfig.lateBind) { ++ try { ++ this.ai().a(inetaddress, this.L()); ++ } catch (Throwable ioexception) { // CraftBukkit - IOException -> Throwable ++ i.warn("**** FAILED TO BIND TO PORT!"); ++ i.warn("The exception was: {}", new Object[] { ioexception.toString()}); ++ i.warn("Perhaps a server is already running on that port?"); ++ return false; ++ } ++ } ++ + if (this.propertyManager.getBoolean("enable-query", false)) { + i.info("Starting GS4 status listener"); + this.k = new RemoteStatusListener(this); +diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java +index b3278fd..af73544 100644 +--- a/src/main/java/org/spigotmc/SpigotConfig.java ++++ b/src/main/java/org/spigotmc/SpigotConfig.java +@@ -209,4 +209,9 @@ public class SpigotConfig + System.setProperty( "io.netty.eventLoopThreads", Integer.toString( count ) ); + Bukkit.getLogger().log( Level.INFO, "Using {0} threads for Netty based IO", count ); + } ++ ++ public static boolean lateBind; ++ private static void lateBind() { ++ lateBind = getBoolean( "settings.late-bind", false ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0080-Update-Chest-Animation-when-Cancelling-Event.patch b/CraftBukkit-Patches/0080-Update-Chest-Animation-when-Cancelling-Event.patch new file mode 100644 index 0000000000..cf19c4791a --- /dev/null +++ b/CraftBukkit-Patches/0080-Update-Chest-Animation-when-Cancelling-Event.patch @@ -0,0 +1,117 @@ +From bb4a9f701952be7e06e70fa583f41c8e2dc8382e Mon Sep 17 00:00:00 2001 +From: bloodshot +Date: Mon, 6 Jan 2014 16:29:51 -0500 +Subject: [PATCH] Update Chest Animation when Cancelling Event + +Update chest animation after cancelling InventoryOpenEvent. Fixes BUKKIT-1440 + +Currently if a plugin cancels an InventoryOpenEvent for vanilla chests, +the chest animation for clients is stuck in the open state since +IInventory's closeChest method is never called. To fix the issue, closeChest +is called before exiting the display GUI method. +More info can be found here +https://bukkit.atlassian.net/browse/BUKKIT-1440 + +diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java +index b519903..9411132 100644 +--- a/src/main/java/net/minecraft/server/EntityPlayer.java ++++ b/src/main/java/net/minecraft/server/EntityPlayer.java +@@ -634,7 +634,10 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + + // CraftBukkit start - Inventory open hook + Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerChest(this.inventory, iinventory)); +- if(container == null) return; ++ if(container == null) { ++ iinventory.l_(); ++ return; ++ } + // CraftBukkit end + + this.nextContainerCounter(); +@@ -647,7 +650,10 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + public void openHopper(TileEntityHopper tileentityhopper) { + // CraftBukkit start - Inventory open hook + Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerHopper(this.inventory, tileentityhopper)); +- if(container == null) return; ++ if(container == null) { ++ tileentityhopper.l_(); ++ return; ++ } + // CraftBukkit end + + this.nextContainerCounter(); +@@ -660,7 +666,10 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + public void openMinecartHopper(EntityMinecartHopper entityminecarthopper) { + // CraftBukkit start - Inventory open hook + Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerHopper(this.inventory, entityminecarthopper)); +- if(container == null) return; ++ if(container == null) { ++ entityminecarthopper.l_(); ++ return; ++ } + // CraftBukkit end + + this.nextContainerCounter(); +@@ -673,7 +682,10 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + public void openFurnace(TileEntityFurnace tileentityfurnace) { + // CraftBukkit start - Inventory open hook + Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerFurnace(this.inventory, tileentityfurnace)); +- if(container == null) return; ++ if(container == null) { ++ tileentityfurnace.l_(); ++ return; ++ } + // CraftBukkit end + + this.nextContainerCounter(); +@@ -686,7 +698,10 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + public void openDispenser(TileEntityDispenser tileentitydispenser) { + // CraftBukkit start - Inventory open hook + Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerDispenser(this.inventory, tileentitydispenser)); +- if(container == null) return; ++ if(container == null) { ++ tileentitydispenser.l_(); ++ return; ++ } + // CraftBukkit end + + this.nextContainerCounter(); +@@ -699,7 +714,10 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + public void openBrewingStand(TileEntityBrewingStand tileentitybrewingstand) { + // CraftBukkit start - Inventory open hook + Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerBrewingStand(this.inventory, tileentitybrewingstand)); +- if(container == null) return; ++ if(container == null) { ++ tileentitybrewingstand.l_(); ++ return; ++ } + // CraftBukkit end + + this.nextContainerCounter(); +@@ -712,7 +730,10 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + public void openBeacon(TileEntityBeacon tileentitybeacon) { + // CraftBukkit start - Inventory open hook + Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerBeacon(this.inventory, tileentitybeacon)); +- if(container == null) return; ++ if(container == null) { ++ tileentitybeacon.l_(); ++ return; ++ } + // CraftBukkit end + + this.nextContainerCounter(); +@@ -755,7 +776,10 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + public void openHorseInventory(EntityHorse entityhorse, IInventory iinventory) { + // CraftBukkit start - Inventory open hook + Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerHorse(this.inventory, iinventory, entityhorse)); +- if(container == null) return; ++ if(container == null) { ++ iinventory.l_(); ++ return; ++ } + // CraftBukkit end + + if (this.activeContainer != this.defaultContainer) { +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0081-Update-Client-s-Hand-when-BlockPlaceEvent-Cancelled.patch b/CraftBukkit-Patches/0081-Update-Client-s-Hand-when-BlockPlaceEvent-Cancelled.patch new file mode 100644 index 0000000000..15b2a96959 --- /dev/null +++ b/CraftBukkit-Patches/0081-Update-Client-s-Hand-when-BlockPlaceEvent-Cancelled.patch @@ -0,0 +1,35 @@ +From 77949ed9e8839d26726aa6faab8a295cd66e88fb Mon Sep 17 00:00:00 2001 +From: bloodshot +Date: Mon, 6 Jan 2014 18:02:01 -0500 +Subject: [PATCH] Update Client's Hand when BlockPlaceEvent Cancelled + +Send a Packet103SetSlot to client when a BlockPlaceEvent is cancelled. + +Fixes BUKKIT-5284 + +Currently, whenever a player places a block in a protected area the +equipped itemstack size on client is never updated properly since the +client thinks the block was placed. The reason this happens is because +ItemStack.matches returns true since the server does not decrement stack +size if a BlockPlaceEvent is cancelled. This causes +PlayerConnection.a(handlePlace) not to send the appropriate packet to +client which causes the bug. + +diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java +index 9f3b1a8..629e360 100644 +--- a/src/main/java/net/minecraft/server/PlayerConnection.java ++++ b/src/main/java/net/minecraft/server/PlayerConnection.java +@@ -639,7 +639,9 @@ public class PlayerConnection implements PacketPlayInListener { + return; + } + +- this.player.playerInteractManager.interact(this.player, worldserver, itemstack, i, j, k, l, packetplayinblockplace.h(), packetplayinblockplace.i(), packetplayinblockplace.j()); ++ if (!this.player.playerInteractManager.interact(this.player, worldserver, itemstack, i, j, k, l, packetplayinblockplace.h(), packetplayinblockplace.i(), packetplayinblockplace.j())) { ++ always = true; // force Packet103SetSlot to be sent to client to update ItemStack count ++ } + // CraftBukkit end + + flag = true; +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0082-Allow-statistics-to-be-disabled-forced.patch b/CraftBukkit-Patches/0082-Allow-statistics-to-be-disabled-forced.patch new file mode 100644 index 0000000000..cf9ca3e0ca --- /dev/null +++ b/CraftBukkit-Patches/0082-Allow-statistics-to-be-disabled-forced.patch @@ -0,0 +1,94 @@ +From 3ad41519d19e0a3df1fd7d7f4afc777a6308202a Mon Sep 17 00:00:00 2001 +From: Thinkofdeath +Date: Tue, 7 Jan 2014 15:56:26 +0000 +Subject: [PATCH] Allow statistics to be disabled/forced + + +diff --git a/src/main/java/net/minecraft/server/ServerStatisticManager.java b/src/main/java/net/minecraft/server/ServerStatisticManager.java +index 0becb94..b868d08 100644 +--- a/src/main/java/net/minecraft/server/ServerStatisticManager.java ++++ b/src/main/java/net/minecraft/server/ServerStatisticManager.java +@@ -32,6 +32,14 @@ public class ServerStatisticManager extends StatisticManager { + public ServerStatisticManager(MinecraftServer minecraftserver, File file1) { + this.c = minecraftserver; + this.d = file1; ++ // Spigot start ++ for ( String name : org.spigotmc.SpigotConfig.forcedStats.keySet() ) ++ { ++ StatisticWrapper wrapper = new StatisticWrapper(); ++ wrapper.a( org.spigotmc.SpigotConfig.forcedStats.get( name ) ); ++ a.put( StatisticList.getStatistic( name ), wrapper ); ++ } ++ // Spigot end + } + + public void a() { +@@ -48,6 +56,7 @@ public class ServerStatisticManager extends StatisticManager { + } + + public void b() { ++ if ( org.spigotmc.SpigotConfig.disableStatSaving ) return; // Spigot + try { + FileUtils.writeStringToFile(this.d, a(this.a)); + } catch (IOException ioexception) { +@@ -56,6 +65,7 @@ public class ServerStatisticManager extends StatisticManager { + } + + public void setStatistic(EntityHuman entityhuman, Statistic statistic, int i) { ++ if ( org.spigotmc.SpigotConfig.disableStatSaving ) return; // Spigot + int j = statistic.d() ? this.getStatisticValue(statistic) : 0; + + super.setStatistic(entityhuman, statistic, i); +diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java +index af73544..54d9117 100644 +--- a/src/main/java/org/spigotmc/SpigotConfig.java ++++ b/src/main/java/org/spigotmc/SpigotConfig.java +@@ -10,10 +10,13 @@ import java.util.HashMap; + import java.util.List; + import java.util.Map; + import java.util.logging.Level; ++ ++import gnu.trove.map.hash.TObjectIntHashMap; + import net.minecraft.server.MinecraftServer; + import org.bukkit.Bukkit; + import org.bukkit.ChatColor; + import org.bukkit.command.Command; ++import org.bukkit.configuration.ConfigurationSection; + import org.bukkit.configuration.file.YamlConfiguration; + + public class SpigotConfig +@@ -214,4 +217,31 @@ public class SpigotConfig + private static void lateBind() { + lateBind = getBoolean( "settings.late-bind", false ); + } ++ ++ public static boolean disableStatSaving; ++ public static TObjectIntHashMap forcedStats = new TObjectIntHashMap(); ++ private static void stats() ++ { ++ disableStatSaving = getBoolean( "stats.disable-saving", false ); ++ ++ if ( !config.contains( "stats.forced-stats" ) ) { ++ config.createSection( "stats.forced-stats" ); ++ } ++ ++ ConfigurationSection section = config.getConfigurationSection( "stats.forced-stats" ); ++ for ( String name : section.getKeys( true ) ) ++ { ++ if ( section.isInt( name ) ) ++ { ++ forcedStats.put( name, section.getInt( name ) ); ++ } ++ } ++ ++ if ( disableStatSaving && section.getInt( "achievement.openInventory", 0 ) < 1 ) ++ { ++ Bukkit.getLogger().warning( "*** WARNING *** stats.disable-saving is true but stats.forced-stats.achievement.openInventory" + ++ " isn't set to 1. Disabling stat saving without forcing the achievement may cause it to get stuck on the player's " + ++ "screen." ); ++ } ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0083-Fix-anvil-collisions.patch b/CraftBukkit-Patches/0083-Fix-anvil-collisions.patch new file mode 100644 index 0000000000..471be92055 --- /dev/null +++ b/CraftBukkit-Patches/0083-Fix-anvil-collisions.patch @@ -0,0 +1,29 @@ +From c0b4750afc88f8497a430b94dba3e6a8da431b61 Mon Sep 17 00:00:00 2001 +From: Thinkofdeath +Date: Thu, 9 Jan 2014 14:19:12 +0000 +Subject: [PATCH] Fix anvil collisions + + +diff --git a/src/main/java/net/minecraft/server/BlockAnvil.java b/src/main/java/net/minecraft/server/BlockAnvil.java +index 9e1ce2f..1fa14c5 100644 +--- a/src/main/java/net/minecraft/server/BlockAnvil.java ++++ b/src/main/java/net/minecraft/server/BlockAnvil.java +@@ -11,6 +11,15 @@ public class BlockAnvil extends BlockFalling { + this.a(CreativeModeTab.c); + } + ++ // Spigot start ++ @Override ++ public AxisAlignedBB a( World world, int i, int j, int k ) ++ { ++ updateShape( world, i, j, k ); ++ return super.a( world, i, j, k ); ++ } ++ // Spigot end ++ + public boolean d() { + return false; + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0084-Fix-ItemStack-Unbreakable-Code.patch b/CraftBukkit-Patches/0084-Fix-ItemStack-Unbreakable-Code.patch new file mode 100644 index 0000000000..34dceb578f --- /dev/null +++ b/CraftBukkit-Patches/0084-Fix-ItemStack-Unbreakable-Code.patch @@ -0,0 +1,28 @@ +From 9eaee04d07cfd72ceacd2f04c43878a73fda0e11 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Fri, 10 Jan 2014 15:15:50 +1100 +Subject: [PATCH] Fix ItemStack Unbreakable Code + + +diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java +index cc18816..a535479 100644 +--- a/src/main/java/net/minecraft/server/ItemStack.java ++++ b/src/main/java/net/minecraft/server/ItemStack.java +@@ -130,7 +130,13 @@ public final class ItemStack { + } + + public boolean g() { +- return this.item.getMaxDurability() <= 0 ? false : !this.hasTag() || !this.getTag().getBoolean("Unbreakable"); ++ // Spigot Start ++ if ( this.item.getMaxDurability() <= 0 ) ++ { ++ return false; ++ } ++ return ( !hasTag() ) || ( !getTag().getBoolean( "Unbreakable" ) ); ++ // Spigot End + } + + public boolean usesData() { +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0085-Try-and-Debug-Crash-Reports-Crashing.patch b/CraftBukkit-Patches/0085-Try-and-Debug-Crash-Reports-Crashing.patch new file mode 100644 index 0000000000..6c50ad2b21 --- /dev/null +++ b/CraftBukkit-Patches/0085-Try-and-Debug-Crash-Reports-Crashing.patch @@ -0,0 +1,41 @@ +From 947176491e5e4aadd682085aff84a04aadc8cac4 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sun, 12 Jan 2014 20:56:41 +1100 +Subject: [PATCH] Try and Debug Crash Reports Crashing + + +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 95eb0c0..ba9bddd 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -653,7 +653,13 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo + try { + worldserver.doTick(); + } catch (Throwable throwable) { ++ // Spigot Start ++ try { + crashreport = CrashReport.a(throwable, "Exception ticking world"); ++ } catch (Throwable t){ ++ throw new RuntimeException("Error generating crash report", t); ++ } ++ // Spigot End + worldserver.a(crashreport); + throw new ReportedException(crashreport); + } +@@ -661,7 +667,13 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo + try { + worldserver.tickEntities(); + } catch (Throwable throwable1) { ++ // Spigot Start ++ try { + crashreport = CrashReport.a(throwable1, "Exception ticking world entities"); ++ } catch (Throwable t){ ++ throw new RuntimeException("Error generating crash report", t); ++ } ++ // Spigot End + worldserver.a(crashreport); + throw new ReportedException(crashreport); + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0086-Replace-AutoSave-Mechanism.patch b/CraftBukkit-Patches/0086-Replace-AutoSave-Mechanism.patch new file mode 100644 index 0000000000..c0c0b73d5e --- /dev/null +++ b/CraftBukkit-Patches/0086-Replace-AutoSave-Mechanism.patch @@ -0,0 +1,32 @@ +From fe064f684461fc2ab2ac02c4fe2e958ac50f624e Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sun, 12 Jan 2014 21:07:18 +1100 +Subject: [PATCH] Replace AutoSave Mechanism + +The problem here is that MinecraftServer.save(..), will attempt to sleep whilst all pending chunks are written to disk, however due to various and complicated bugs, it will wait for an incorrect amount of chunks, which may cause it to sleep for an overly long amount of time. Instead we will mimic the save-all command in its behaviour, which is both safe and performant. + +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index ba9bddd..5e6b2e0 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -582,7 +582,16 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo + if ((this.autosavePeriod > 0) && ((this.ticks % this.autosavePeriod) == 0)) { // CraftBukkit + this.methodProfiler.a("save"); + this.u.savePlayers(); +- this.saveChunks(true); ++ // Spigot Start ++ // We replace this with saving each individual world as this.saveChunks(...) is broken, ++ // and causes the main thread to sleep for random amounts of time depending on chunk activity ++ server.playerCommandState = true; ++ for (World world : worlds) { ++ world.getWorld().save(); ++ } ++ server.playerCommandState = false; ++ // this.saveChunks(true); ++ // Spigot End + this.methodProfiler.b(); + } + +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0087-Block-data-values-that-crash-the-client.patch b/CraftBukkit-Patches/0087-Block-data-values-that-crash-the-client.patch new file mode 100644 index 0000000000..510158ca7b --- /dev/null +++ b/CraftBukkit-Patches/0087-Block-data-values-that-crash-the-client.patch @@ -0,0 +1,61 @@ +From 53172a9b135a389798ac03f2ca0c4a3ac7360196 Mon Sep 17 00:00:00 2001 +From: Thinkofdeath +Date: Wed, 15 Jan 2014 21:52:47 +0000 +Subject: [PATCH] Block data values that crash the client + + +diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java +index 3712009..90f32ed 100644 +--- a/src/main/java/net/minecraft/server/Chunk.java ++++ b/src/main/java/net/minecraft/server/Chunk.java +@@ -115,7 +115,7 @@ public class Chunk { + } + + this.sections[l1].setTypeId(l, j1 & 15, i1, block); +- this.sections[l1].setData(l, j1 & 15, i1, abyte[k1]); ++ this.sections[l1].setData(l, j1 & 15, i1, checkData( block, abyte[k1] ) ); + } + } + } +@@ -398,6 +398,17 @@ public class Chunk { + } + } + ++ // Spigot start - prevent invalid data values ++ private static int checkData( Block block, int l ) ++ { ++ if (block == Block.b( "minecraft:double_plant" ) ) ++ { ++ return l == 7 ? 0 : l; ++ } ++ return l; ++ } ++ // Spigot end ++ + public boolean a(int i, int j, int k, Block block, int l) { + int i1 = k << 4 | i; + +@@ -452,7 +463,7 @@ public class Chunk { + if (chunksection.getTypeId(i, j & 15, k) != block) { + return false; + } else { +- chunksection.setData(i, j & 15, k, l); ++ chunksection.setData(i, j & 15, k, checkData( block, l ) ); + if (flag) { + this.initLighting(); + } else { +@@ -522,8 +533,9 @@ public class Chunk { + return false; + } else { + this.n = true; +- chunksection.setData(i, j & 15, k, l); +- if (chunksection.getTypeId(i, j & 15, k) instanceof IContainer) { ++ Block block = chunksection.getTypeId( i, j & 15, k ); ++ chunksection.setData(i, j & 15, k, checkData( block, l ) ); ++ if (block instanceof IContainer) { + TileEntity tileentity = this.e(i, j, k); + + if (tileentity != null) { +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0088-Support-vanilla-s-direction-tag-on-fireballs.patch b/CraftBukkit-Patches/0088-Support-vanilla-s-direction-tag-on-fireballs.patch new file mode 100644 index 0000000000..268918b387 --- /dev/null +++ b/CraftBukkit-Patches/0088-Support-vanilla-s-direction-tag-on-fireballs.patch @@ -0,0 +1,36 @@ +From 997e88554d0c0405c4356b94a3983d39773e13d3 Mon Sep 17 00:00:00 2001 +From: Thinkofdeath +Date: Sat, 18 Jan 2014 14:27:03 +0000 +Subject: [PATCH] Support vanilla's direction tag on fireballs + + +diff --git a/src/main/java/net/minecraft/server/EntityFireball.java b/src/main/java/net/minecraft/server/EntityFireball.java +index 0eecaad..b14c73e 100644 +--- a/src/main/java/net/minecraft/server/EntityFireball.java ++++ b/src/main/java/net/minecraft/server/EntityFireball.java +@@ -199,6 +199,8 @@ public abstract class EntityFireball extends Entity { + nbttagcompound.setByte("inGround", (byte) (this.i ? 1 : 0)); + // CraftBukkit - Fix direction being mismapped to invalid variables + nbttagcompound.set("power", this.a(new double[] { this.dirX, this.dirY, this.dirZ})); ++ // Spigot - Support vanilla's direction tag ++ nbttagcompound.set("direction", this.a(new double[] { this.motX, this.motY, this.motZ})); + } + + public void a(NBTTagCompound nbttagcompound) { +@@ -215,6 +217,13 @@ public abstract class EntityFireball extends Entity { + this.dirY = nbttaglist.d(1); + this.dirZ = nbttaglist.d(2); + // CraftBukkit end ++ } else if (nbttagcompound.hasKeyOfType("direction", 9)) { // Spigot - Support vanilla's direction tag ++ NBTTagList nbttaglist = nbttagcompound.getList("direction", 6); ++ ++ this.motX = nbttaglist.d(0); ++ this.motY = nbttaglist.d(1); ++ this.motZ = nbttaglist.d(2); ++ + } else { + this.die(); + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0089-Support-non-prefixed-URLs.patch b/CraftBukkit-Patches/0089-Support-non-prefixed-URLs.patch new file mode 100644 index 0000000000..0cdba986f6 --- /dev/null +++ b/CraftBukkit-Patches/0089-Support-non-prefixed-URLs.patch @@ -0,0 +1,41 @@ +From a93c00b173afaded138716b8c9984615ba4c4a39 Mon Sep 17 00:00:00 2001 +From: Thinkofdeath +Date: Sat, 18 Jan 2014 19:32:42 +0000 +Subject: [PATCH] Support non-prefixed URLs + + +diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java +index 2b57bf8..a3de612 100644 +--- a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java ++++ b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java +@@ -19,7 +19,7 @@ import com.google.common.collect.ImmutableMap.Builder; + public final class CraftChatMessage { + private static class StringMessage { + private static final Map formatMap; +- private static final Pattern INCREMENTAL_PATTERN = Pattern.compile("(" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + "[0-9a-fk-or])|(\\n)|(?:(https?://[^ ][^ ]*?)(?=[\\.\\?!,;:]?(?:[ \\n]|$)))", Pattern.CASE_INSENSITIVE); ++ private static final Pattern INCREMENTAL_PATTERN = Pattern.compile("(" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + "[0-9a-fk-or])|(\\n)|((?:(?:https?)://)?(?:[-\\w_\\.]{2,}\\.[a-z]{2,4}.*?(?=[\\.\\?!,;:]?(?:[ \\n]|$))))", Pattern.CASE_INSENSITIVE); + + static { + Builder builder = ImmutableMap.builder(); +@@ -85,6 +85,9 @@ public final class CraftChatMessage { + currentChatComponent = null; + break; + case 3: ++ if ( !( match.startsWith( "http://" ) || match.startsWith( "https://" ) ) ) { ++ match = "http://" + match; ++ } + modifier.setChatClickable(new ChatClickable(EnumClickAction.OPEN_URL, match)); + appendNewComponent(matcher.end(groupId)); + modifier.setChatClickable((ChatClickable) null); +@@ -96,7 +99,7 @@ public final class CraftChatMessage { + appendNewComponent(message.length()); + } + +- output = list.toArray(new IChatBaseComponent[0]); ++ output = list.toArray(new IChatBaseComponent[list.size()]); + } + + private void appendNewComponent(int index) { +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0090-Catch-stalling-on-corrupted-map-data-NBT-arrays.patch b/CraftBukkit-Patches/0090-Catch-stalling-on-corrupted-map-data-NBT-arrays.patch new file mode 100644 index 0000000000..ee16008cdc --- /dev/null +++ b/CraftBukkit-Patches/0090-Catch-stalling-on-corrupted-map-data-NBT-arrays.patch @@ -0,0 +1,33 @@ +From 5435dff5b0701d0df40e1d1259226800c7c62d2e Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Mon, 20 Jan 2014 13:44:07 +1100 +Subject: [PATCH] Catch stalling on corrupted map data / NBT arrays. + + +diff --git a/src/main/java/net/minecraft/server/NBTTagByteArray.java b/src/main/java/net/minecraft/server/NBTTagByteArray.java +index 916d935..c2e81cb 100644 +--- a/src/main/java/net/minecraft/server/NBTTagByteArray.java ++++ b/src/main/java/net/minecraft/server/NBTTagByteArray.java +@@ -22,6 +22,7 @@ public class NBTTagByteArray extends NBTBase { + + void load(DataInput datainput, int i) throws IOException { + int j = datainput.readInt(); ++ com.google.common.base.Preconditions.checkArgument( j < 1 << 24); + + this.data = new byte[j]; + datainput.readFully(this.data); +diff --git a/src/main/java/net/minecraft/server/NBTTagIntArray.java b/src/main/java/net/minecraft/server/NBTTagIntArray.java +index 49b3f14..4d6a9da 100644 +--- a/src/main/java/net/minecraft/server/NBTTagIntArray.java ++++ b/src/main/java/net/minecraft/server/NBTTagIntArray.java +@@ -25,6 +25,7 @@ public class NBTTagIntArray extends NBTBase { + + void load(DataInput datainput, int i) throws IOException { + int j = datainput.readInt(); ++ com.google.common.base.Preconditions.checkArgument( j < 1 << 24); + + this.data = new int[j]; + +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0091-Reduce-memory-of-hiddenPlayers-map.patch b/CraftBukkit-Patches/0091-Reduce-memory-of-hiddenPlayers-map.patch new file mode 100644 index 0000000000..c1738b061e --- /dev/null +++ b/CraftBukkit-Patches/0091-Reduce-memory-of-hiddenPlayers-map.patch @@ -0,0 +1,22 @@ +From 74249e2ee71bdc4a02aa1f0d484f12d48686311a Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Mon, 20 Jan 2014 13:50:32 +1100 +Subject: [PATCH] Reduce memory of hiddenPlayers map. + + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index 2c129ac..1d6d1ba 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -66,7 +66,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + private boolean hasPlayedBefore = false; + private final ConversationTracker conversationTracker = new ConversationTracker(); + private final Set channels = new HashSet(); +- private final Set hiddenPlayers = new HashSet(); ++ private final Map hiddenPlayers = new MapMaker().weakValues().makeMap(); // Spigot - soft -> weak + private int hash = 0; + private double health = 20; + private boolean scaledHealth = false; +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0092-Allow-toggling-of-ZombiePigmen-spawning-in-portal-bl.patch b/CraftBukkit-Patches/0092-Allow-toggling-of-ZombiePigmen-spawning-in-portal-bl.patch new file mode 100644 index 0000000000..f6b3e7f714 --- /dev/null +++ b/CraftBukkit-Patches/0092-Allow-toggling-of-ZombiePigmen-spawning-in-portal-bl.patch @@ -0,0 +1,38 @@ +From f57374062ecd85de9558aa42a4cfca174451d78f Mon Sep 17 00:00:00 2001 +From: Dmck2b +Date: Mon, 20 Jan 2014 20:18:23 +0000 +Subject: [PATCH] Allow toggling of ZombiePigmen spawning in portal blocks + + +diff --git a/src/main/java/net/minecraft/server/BlockPortal.java b/src/main/java/net/minecraft/server/BlockPortal.java +index 1356f13..b361775 100644 +--- a/src/main/java/net/minecraft/server/BlockPortal.java ++++ b/src/main/java/net/minecraft/server/BlockPortal.java +@@ -15,7 +15,7 @@ public class BlockPortal extends BlockHalfTransparent { + + public void a(World world, int i, int j, int k, Random random) { + super.a(world, i, j, k, random); +- if (world.worldProvider.d() && world.getGameRules().getBoolean("doMobSpawning") && random.nextInt(2000) < world.difficulty.a()) { ++ if (world.spigotConfig.enableZombiePigmenPortalSpawns && world.worldProvider.d() && world.getGameRules().getBoolean("doMobSpawning") && random.nextInt(2000) < world.difficulty.a()) { // Spigot + int l; + + for (l = j; !World.a((IBlockAccess) world, i, l, k) && l > 0; --l) { +diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java +index 558e9cd..ffdb33e 100644 +--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java ++++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java +@@ -257,4 +257,11 @@ public class SpigotWorldConfig + nerfSpawnerMobs = getBoolean( "nerf-spawner-mobs", false ); + log( "Nerfing mobs spawned from spawners: " + nerfSpawnerMobs ); + } ++ ++ public boolean enableZombiePigmenPortalSpawns; ++ private void enableZombiePigmenPortalSpawns() ++ { ++ enableZombiePigmenPortalSpawns = getBoolean( "enable-zombie-pigmen-portal-spawns", true ); ++ log( "Allow Zombie Pigmen to spawn from portal blocks: " + enableZombiePigmenPortalSpawns ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0093-Don-t-let-trees-replace-any-block-when-growing.patch b/CraftBukkit-Patches/0093-Don-t-let-trees-replace-any-block-when-growing.patch new file mode 100644 index 0000000000..c14f1cc7d4 --- /dev/null +++ b/CraftBukkit-Patches/0093-Don-t-let-trees-replace-any-block-when-growing.patch @@ -0,0 +1,27 @@ +From ecd2a9040b87a1ad4f9c595474364ec03e144465 Mon Sep 17 00:00:00 2001 +From: Thinkofdeath +Date: Mon, 20 Jan 2014 20:42:28 +0000 +Subject: [PATCH] Don't let trees replace any block when growing + + +diff --git a/src/main/java/net/minecraft/server/WorldGenForestTree.java b/src/main/java/net/minecraft/server/WorldGenForestTree.java +index 71ce973..caaac9a 100644 +--- a/src/main/java/net/minecraft/server/WorldGenForestTree.java ++++ b/src/main/java/net/minecraft/server/WorldGenForestTree.java +@@ -132,7 +132,12 @@ public class WorldGenForestTree extends WorldGenTreeAbstract implements BlockSap + int k3; + + for (k3 = 0; k3 < j3; ++k3) { +- this.setTypeAndData(world, i + l2, k2 - k3 - 1, k + i3, Blocks.LOG2, 1); ++ Block block = world.getType(i + l2, k2 - k3 - 1, k + i3); ++ ++ if (block.getMaterial() == Material.AIR || block.getMaterial() == Material.LEAVES) ++ { ++ this.setTypeAndData(world, i + l2, k2 - k3 - 1, k + i3, Blocks.LOG2, 1); ++ } + } + + int l3; +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0094-Highly-Optimized-Tick-Loop.patch b/CraftBukkit-Patches/0094-Highly-Optimized-Tick-Loop.patch new file mode 100644 index 0000000000..2cb0b87533 --- /dev/null +++ b/CraftBukkit-Patches/0094-Highly-Optimized-Tick-Loop.patch @@ -0,0 +1,165 @@ +From de8ae04deda9f654974e5fdffacff684cb572bac Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sat, 25 Jan 2014 14:08:35 +1100 +Subject: [PATCH] Highly Optimized Tick Loop + + +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 5e6b2e0..408b25d 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -107,6 +107,12 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo + public java.util.Queue processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); + public int autosavePeriod; + // CraftBukkit end ++ // Spigot start ++ private static final int TPS = 20; ++ private static final int TICK_TIME = 1000000000 / TPS; ++ private static final int SAMPLE_INTERVAL = 100; ++ public final double[] recentTps = new double[ 3 ]; ++ // Spigot end + + public MinecraftServer(OptionSet options, Proxy proxy) { // CraftBukkit - signature file -> OptionSet + this.X = new UserCache(this, a); +@@ -432,6 +438,13 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo + this.isRunning = false; + } + ++ // Spigot Start ++ private static double calcTps(double avg, double exp, double tps) ++ { ++ return ( avg * exp ) + ( tps * ( 1 - exp ) ); ++ } ++ // Spigot End ++ + public void run() { + try { + if (this.init()) { +@@ -442,38 +455,34 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo + this.q.setServerInfo(new ServerPingServerData("1.7.8", 5)); + this.a(this.q); + ++ // Spigot start ++ Arrays.fill( recentTps, 20 ); ++ long lastTick = System.nanoTime(), catchupTime = 0, curTime, wait, tickSection = lastTick; + while (this.isRunning) { +- long k = ar(); +- long l = k - i; +- +- if (l > 2000L && i - this.P >= 15000L) { +- if (this.server.getWarnOnOverload()) // CraftBukkit - Added option to suppress warning messages +- MinecraftServer.i.warn("Can\'t keep up! Did the system time change, or is the server overloaded? Running {}ms behind, skipping {} tick(s)", new Object[] { Long.valueOf(l), Long.valueOf(l / 50L)}); +- l = 2000L; +- this.P = i; +- } +- +- if (l < 0L) { +- MinecraftServer.i.warn("Time ran backwards! Did the system time change?"); +- l = 0L; ++ curTime = System.nanoTime(); ++ wait = TICK_TIME - (curTime - lastTick) - catchupTime; ++ if (wait > 0) { ++ Thread.sleep(wait / 1000000); ++ catchupTime = 0; ++ continue; ++ } else { ++ catchupTime = Math.min(1000000000, Math.abs(wait)); + } + +- j += l; +- i = k; +- if (this.worlds.get(0).everyoneDeeplySleeping()) { // CraftBukkit +- this.u(); +- j = 0L; +- } else { +- while (j > 50L) { +- MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit +- j -= 50L; +- this.u(); +- } ++ if ( MinecraftServer.currentTick++ % SAMPLE_INTERVAL == 0 ) ++ { ++ double currentTps = 1E9 / ( curTime - tickSection ) * SAMPLE_INTERVAL; ++ recentTps[0] = calcTps( recentTps[0], 0.92, currentTps ); // 1/exp(5sec/1min) ++ recentTps[1] = calcTps( recentTps[1], 0.9835, currentTps ); // 1/exp(5sec/5min) ++ recentTps[2] = calcTps( recentTps[2], 0.9945, currentTps ); // 1/exp(5sec/15min) ++ tickSection = curTime; + } ++ lastTick = curTime; + +- Thread.sleep(Math.max(1L, 50L - j)); ++ this.u(); + this.O = true; + } ++ // Spigot end + } else { + this.a((CrashReport) null); + } +diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java +index 54d9117..2baed09 100644 +--- a/src/main/java/org/spigotmc/SpigotConfig.java ++++ b/src/main/java/org/spigotmc/SpigotConfig.java +@@ -244,4 +244,9 @@ public class SpigotConfig + "screen." ); + } + } ++ ++ private static void tpsCommand() ++ { ++ commands.put( "tps", new TicksPerSecondCommand( "tps" ) ); ++ } + } +diff --git a/src/main/java/org/spigotmc/TicksPerSecondCommand.java b/src/main/java/org/spigotmc/TicksPerSecondCommand.java +new file mode 100644 +index 0000000..2b8343d +--- /dev/null ++++ b/src/main/java/org/spigotmc/TicksPerSecondCommand.java +@@ -0,0 +1,45 @@ ++package org.spigotmc; ++ ++import com.google.common.base.Joiner; ++import net.minecraft.server.MinecraftServer; ++import net.minecraft.util.com.google.common.collect.Iterables; ++import org.bukkit.ChatColor; ++import org.bukkit.command.Command; ++import org.bukkit.command.CommandSender; ++ ++public class TicksPerSecondCommand extends Command ++{ ++ ++ public TicksPerSecondCommand(String name) ++ { ++ super( name ); ++ this.description = "Gets the current ticks per second for the server"; ++ this.usageMessage = "/tps"; ++ this.setPermission( "bukkit.command.tps" ); ++ } ++ ++ @Override ++ public boolean execute(CommandSender sender, String currentAlias, String[] args) ++ { ++ if ( !testPermission( sender ) ) ++ { ++ return true; ++ } ++ ++ StringBuilder sb = new StringBuilder( ChatColor.GOLD + "TPS from last 1m, 5m, 15m: " ); ++ for ( double tps : MinecraftServer.getServer().recentTps ) ++ { ++ sb.append( format( tps ) ); ++ sb.append( ", " ); ++ } ++ sender.sendMessage( sb.substring( 0, sb.length() - 2 ) ); ++ ++ return true; ++ } ++ ++ private String format(double tps) ++ { ++ return ( ( tps > 18.0 ) ? ChatColor.GREEN : ( tps > 16.0 ) ? ChatColor.YELLOW : ChatColor.RED ).toString() ++ + ( ( tps > 20.0 ) ? "*" : "" ) + Math.min( Math.round( tps * 100.0 ) / 100.0, 20.0 ); ++ } ++} +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0095-Add-Spigot-Links.patch b/CraftBukkit-Patches/0095-Add-Spigot-Links.patch new file mode 100644 index 0000000000..a028e48076 --- /dev/null +++ b/CraftBukkit-Patches/0095-Add-Spigot-Links.patch @@ -0,0 +1,79 @@ +From 901a07f32926251caba25e4f5752ab39ce50199c Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Thu, 23 Jan 2014 13:17:35 +1100 +Subject: [PATCH] Add Spigot Links + + +diff --git a/README.md b/README.md +index cda766b..1f12a75 100644 +--- a/README.md ++++ b/README.md +@@ -1,11 +1,11 @@ +-CraftBukkit ++Spigot + =========== + +-A Bukkit (Minecraft Server API) implementation ++A Spigot-API and Bukkit implementation + +-Website: [http://bukkit.org](http://bukkit.org) +-Bugs/Suggestions: [http://leaky.bukkit.org](http://leaky.bukkit.org) +-Contributing Guidelines: [CONTRIBUTING.md](https://github.com/Bukkit/CraftBukkit/blob/master/CONTRIBUTING.md) ++Website: [http://spigotmc.org](http://spigotmc.org) ++Bugs/Suggestions: [http://www.spigotmc.org/forums/bugs-feature-requests.8/](http://www.spigotmc.org/forums/bugs-feature-requests.8/) ++Contributing Guidelines: [CONTRIBUTING.md](https://github.com/SpigotMC/Spigot-API/blob/master/CONTRIBUTING.md) + + Compilation + ----------- +@@ -13,6 +13,6 @@ Compilation + We use maven to handle our dependencies. + + * Install [Maven 3](http://maven.apache.org/download.html) +-* Check out and install [Bukkit](http://github.com/Bukkit/Bukkit) +- * *Note*: this is not needed as the repository we use has Bukkit too, but you might have a newer one (with your own changes :D) ++* Check out and install [Spigot-API](http://github.com/SpigotMC/Spigot) ++ * *Note*: this is not needed as the repository we use has Spigot-API too, but you might have a newer one (with your own changes :D) + * Check out this repo and: `mvn clean package` +diff --git a/src/main/resources/configurations/bukkit.yml b/src/main/resources/configurations/bukkit.yml +index 129ac34..751bbfc 100644 +--- a/src/main/resources/configurations/bukkit.yml ++++ b/src/main/resources/configurations/bukkit.yml +@@ -6,11 +6,10 @@ + # If you need help on this file, feel free to join us on irc or leave a message + # on the forums asking for advice. + # +-# IRC: #bukkit @ esper.net +-# (If this means nothing to you, just go to http://webchat.esper.net/?channels=bukkit ) +-# Forums: http://forums.bukkit.org/forums/bukkit-help.6/ +-# Twitter: http://twitter.com/CraftBukkit +-# Bug tracker: http://leaky.bukkit.org/ ++# IRC: #spigot @ irc.spi.gt ++# (If this means nothing to you, just go to http://irc.spi.gt/iris/?nick=&channels=spigot ) ++# Forums: http://www.spigotmc.org/forums/help.40/ ++# Bug tracker: http://www.spigotmc.org/forums/bugs-feature-requests.8/ + + + settings: +diff --git a/src/main/resources/configurations/commands.yml b/src/main/resources/configurations/commands.yml +index 0a5d414..d6bcf5c 100644 +--- a/src/main/resources/configurations/commands.yml ++++ b/src/main/resources/configurations/commands.yml +@@ -5,11 +5,10 @@ + # If you need help on this file, feel free to join us on irc or leave a message + # on the forums asking for advice. + # +-# IRC: #bukkit @ esper.net +-# (If this means nothing to you, just go to http://webchat.esper.net/?channels=bukkit ) +-# Forums: http://forums.bukkit.org/forums/bukkit-help.6/ +-# Twitter: http://twitter.com/CraftBukkit +-# Bug tracker: http://leaky.bukkit.org/ ++# IRC: #spigot @ irc.spi.gt ++# (If this means nothing to you, just go to http://irc.spi.gt/iris/?nick=&channels=spigot ) ++# Forums: http://www.spigotmc.org/forums/help.40/ ++# Bug tracker: http://www.spigotmc.org/forums/bugs-feature-requests.8/ + + command-block-overrides: [] + aliases: +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0096-Configurable-Ping-Sample-Size.patch b/CraftBukkit-Patches/0096-Configurable-Ping-Sample-Size.patch new file mode 100644 index 0000000000..e624a0e4c9 --- /dev/null +++ b/CraftBukkit-Patches/0096-Configurable-Ping-Sample-Size.patch @@ -0,0 +1,43 @@ +From 69d28ad3c473998bb35bb51239c0e297027e3596 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sun, 26 Jan 2014 21:48:34 +1100 +Subject: [PATCH] Configurable Ping Sample Size + + +diff --git a/src/main/java/net/minecraft/server/PacketStatusListener.java b/src/main/java/net/minecraft/server/PacketStatusListener.java +index cd06305..6423aec 100644 +--- a/src/main/java/net/minecraft/server/PacketStatusListener.java ++++ b/src/main/java/net/minecraft/server/PacketStatusListener.java +@@ -110,6 +110,13 @@ public class PacketStatusListener implements PacketStatusInListener { + } + + ServerPingPlayerSample playerSample = new ServerPingPlayerSample(event.getMaxPlayers(), profiles.size()); ++ // Spigot Start ++ if ( !profiles.isEmpty() ) ++ { ++ java.util.Collections.shuffle( profiles ); // This sucks, its inefficient but we have no simple way of doing it differently ++ profiles = profiles.subList( 0, Math.min( profiles.size(), org.spigotmc.SpigotConfig.playerSample ) ); // Cap the sample to n (or less) displayed players, ie: Vanilla behaviour ++ } ++ // Spigot End + playerSample.a(profiles.toArray(new GameProfile[profiles.size()])); + + ServerPing ping = new ServerPing(); +diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java +index 2baed09..8eac742 100644 +--- a/src/main/java/org/spigotmc/SpigotConfig.java ++++ b/src/main/java/org/spigotmc/SpigotConfig.java +@@ -249,4 +249,11 @@ public class SpigotConfig + { + commands.put( "tps", new TicksPerSecondCommand( "tps" ) ); + } ++ ++ public static int playerSample; ++ private static void playerSample() ++ { ++ playerSample = getInt( "settings.sample-count", 12 ); ++ System.out.println( "Server Ping Player Sample Count: " + playerSample ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0097-Add-Optional-Tick-Shuffling.patch b/CraftBukkit-Patches/0097-Add-Optional-Tick-Shuffling.patch new file mode 100644 index 0000000000..31ba443892 --- /dev/null +++ b/CraftBukkit-Patches/0097-Add-Optional-Tick-Shuffling.patch @@ -0,0 +1,43 @@ +From 5fe67299aa85203afec737cea401214f227e29cd Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Mon, 27 Jan 2014 08:39:26 +1100 +Subject: [PATCH] Add Optional Tick Shuffling + +This prevents players from 'gaming' the server, and strategically relogging to increase their position in the tick order. + +diff --git a/src/main/java/net/minecraft/server/ServerConnection.java b/src/main/java/net/minecraft/server/ServerConnection.java +index c2194af..1d7b814 100644 +--- a/src/main/java/net/minecraft/server/ServerConnection.java ++++ b/src/main/java/net/minecraft/server/ServerConnection.java +@@ -53,6 +53,13 @@ public class ServerConnection { + List list = this.f; + + synchronized (this.f) { ++ // Spigot Start ++ // This prevents players from 'gaming' the server, and strategically relogging to increase their position in the tick order ++ if ( org.spigotmc.SpigotConfig.playerShuffle > 0 && MinecraftServer.currentTick % org.spigotmc.SpigotConfig.playerShuffle == 0 ) ++ { ++ Collections.shuffle( this.f ); ++ } ++ // Spigot End + Iterator iterator = this.f.iterator(); + + while (iterator.hasNext()) { +diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java +index 8eac742..e26b964 100644 +--- a/src/main/java/org/spigotmc/SpigotConfig.java ++++ b/src/main/java/org/spigotmc/SpigotConfig.java +@@ -256,4 +256,10 @@ public class SpigotConfig + playerSample = getInt( "settings.sample-count", 12 ); + System.out.println( "Server Ping Player Sample Count: " + playerSample ); + } ++ ++ public static int playerShuffle; ++ private static void playerShuffle() ++ { ++ playerShuffle = getInt( "settings.player-shuffle", 0 ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0098-Allow-Configuring-Chunks-per-Packet.patch b/CraftBukkit-Patches/0098-Allow-Configuring-Chunks-per-Packet.patch new file mode 100644 index 0000000000..ef25142e94 --- /dev/null +++ b/CraftBukkit-Patches/0098-Allow-Configuring-Chunks-per-Packet.patch @@ -0,0 +1,38 @@ +From d19940c7cd134b2210cb77fd7603f23dadaf5781 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Tue, 28 Jan 2014 20:35:35 +1100 +Subject: [PATCH] Allow Configuring Chunks per Packet + + +diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java +index 9411132..585df73 100644 +--- a/src/main/java/net/minecraft/server/EntityPlayer.java ++++ b/src/main/java/net/minecraft/server/EntityPlayer.java +@@ -214,7 +214,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + + Chunk chunk; + +- while (iterator1.hasNext() && arraylist.size() < PacketPlayOutMapChunkBulk.c()) { ++ while (iterator1.hasNext() && arraylist.size() < this.world.spigotConfig.maxBulkChunk) { // Spigot + ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) iterator1.next(); + + if (chunkcoordintpair != null) { +diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java +index ffdb33e..1290829 100644 +--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java ++++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java +@@ -264,4 +264,11 @@ public class SpigotWorldConfig + enableZombiePigmenPortalSpawns = getBoolean( "enable-zombie-pigmen-portal-spawns", true ); + log( "Allow Zombie Pigmen to spawn from portal blocks: " + enableZombiePigmenPortalSpawns ); + } ++ ++ public int maxBulkChunk; ++ private void bulkChunkCount() ++ { ++ maxBulkChunk = getInt( "max-bulk-chunks", 5 ); ++ log( "Sending up to " + maxBulkChunk + " chunks per packet" ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0099-Implement-Locale-Getter-for-Players.patch b/CraftBukkit-Patches/0099-Implement-Locale-Getter-for-Players.patch new file mode 100644 index 0000000000..e855694c41 --- /dev/null +++ b/CraftBukkit-Patches/0099-Implement-Locale-Getter-for-Players.patch @@ -0,0 +1,39 @@ +From aaa3e437bd68627f59bb3cd76ab0888d41140581 Mon Sep 17 00:00:00 2001 +From: Smove +Date: Sat, 1 Feb 2014 18:12:16 +1100 +Subject: [PATCH] Implement Locale Getter for Players + + +diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java +index 585df73..4fb5f75 100644 +--- a/src/main/java/net/minecraft/server/EntityPlayer.java ++++ b/src/main/java/net/minecraft/server/EntityPlayer.java +@@ -30,7 +30,7 @@ import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; + public class EntityPlayer extends EntityHuman implements ICrafting { + + private static final Logger bL = LogManager.getLogger(); +- private String locale = "en_US"; ++ public String locale = "en_US"; // Spigot + public PlayerConnection playerConnection; + public final MinecraftServer server; + public final PlayerInteractManager playerInteractManager; +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index 1d6d1ba..3443f55 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -1368,6 +1368,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + getHandle().playerConnection.sendPacket( packet ); + } + } ++ ++ @Override ++ public String getLocale() ++ { ++ return getHandle().locale; ++ } + }; + + public Player.Spigot spigot() +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0100-Cap-Entity-Collisions.patch b/CraftBukkit-Patches/0100-Cap-Entity-Collisions.patch new file mode 100644 index 0000000000..80590c72ef --- /dev/null +++ b/CraftBukkit-Patches/0100-Cap-Entity-Collisions.patch @@ -0,0 +1,66 @@ +From 296bdb60b68801353cd301df8987d1f3d5572618 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Fri, 31 Jan 2014 11:18:34 -0500 +Subject: [PATCH] Cap Entity Collisions + +Limit a single entity to colliding a max of configurable times per tick. +This will alleviate issues where living entities are hoarded in 1x1 pens. + +diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java +index 0ec07c2..c049cd8 100644 +--- a/src/main/java/net/minecraft/server/Entity.java ++++ b/src/main/java/net/minecraft/server/Entity.java +@@ -1021,6 +1021,7 @@ public abstract class Entity { + + public void b_(EntityHuman entityhuman) {} + ++ int numCollisions = 0; // Spigot + public void collide(Entity entity) { + if (entity.passenger != this && entity.vehicle != this) { + double d0 = entity.locX - this.locX; +diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java +index 90c0e82..33533c7 100644 +--- a/src/main/java/net/minecraft/server/EntityLiving.java ++++ b/src/main/java/net/minecraft/server/EntityLiving.java +@@ -1491,7 +1491,9 @@ public abstract class EntityLiving extends Entity { + List list = this.world.getEntities(this, this.boundingBox.grow(0.20000000298023224D, 0.0D, 0.20000000298023224D)); + + if (this.R() && list != null && !list.isEmpty()) { // Spigot: Add this.R() condition ++ numCollisions -= world.spigotConfig.maxCollisionsPerEntity; // Spigot + for (int i = 0; i < list.size(); ++i) { ++ if (numCollisions > world.spigotConfig.maxCollisionsPerEntity) { break; } // Spigot + Entity entity = (Entity) list.get(i); + + // TODO better check now? +@@ -1502,9 +1504,12 @@ public abstract class EntityLiving extends Entity { + // CraftBukkit end + + if (entity.R()) { ++ entity.numCollisions++; // Spigot ++ numCollisions++; // Spigot + this.o(entity); + } + } ++ numCollisions = 0; // Spigot + } + } + +diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java +index 1290829..b12a086 100644 +--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java ++++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java +@@ -271,4 +271,11 @@ public class SpigotWorldConfig + maxBulkChunk = getInt( "max-bulk-chunks", 5 ); + log( "Sending up to " + maxBulkChunk + " chunks per packet" ); + } ++ ++ public int maxCollisionsPerEntity; ++ private void maxEntityCollision() ++ { ++ maxCollisionsPerEntity = getInt( "max-entity-collisions", 8 ); ++ log( "Max Entity Collisions: " + maxCollisionsPerEntity ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0101-Fix-dispensing-bone-meal-not-having-the-correct-data.patch b/CraftBukkit-Patches/0101-Fix-dispensing-bone-meal-not-having-the-correct-data.patch new file mode 100644 index 0000000000..37dcb0ea1a --- /dev/null +++ b/CraftBukkit-Patches/0101-Fix-dispensing-bone-meal-not-having-the-correct-data.patch @@ -0,0 +1,22 @@ +From f2dbec7d9562e1ec29732a9e06f8ff412ffcb8e9 Mon Sep 17 00:00:00 2001 +From: Thinkofdeath +Date: Thu, 6 Feb 2014 21:59:20 +0000 +Subject: [PATCH] Fix dispensing bone meal not having the correct data value + + +diff --git a/src/main/java/net/minecraft/server/DispenseBehaviorBonemeal.java b/src/main/java/net/minecraft/server/DispenseBehaviorBonemeal.java +index b547bc9..c06e9a1 100644 +--- a/src/main/java/net/minecraft/server/DispenseBehaviorBonemeal.java ++++ b/src/main/java/net/minecraft/server/DispenseBehaviorBonemeal.java +@@ -21,7 +21,7 @@ final class DispenseBehaviorBonemeal extends DispenseBehaviorItem { + + // CraftBukkit start + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockX(), isourceblock.getBlockY(), isourceblock.getBlockZ()); +- CraftItemStack craftItem = CraftItemStack.asNewCraftStack(itemstack.getItem()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); + if (!BlockDispenser.eventFired) { +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0102-Spam-Filter-Exclusions.patch b/CraftBukkit-Patches/0102-Spam-Filter-Exclusions.patch new file mode 100644 index 0000000000..baa8fd4bf2 --- /dev/null +++ b/CraftBukkit-Patches/0102-Spam-Filter-Exclusions.patch @@ -0,0 +1,60 @@ +From 9079943fde839278e0d4f962d3f5e27b819235db Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sat, 8 Feb 2014 08:13:40 +0000 +Subject: [PATCH] Spam Filter Exclusions + + +diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java +index 629e360..40fb962 100644 +--- a/src/main/java/net/minecraft/server/PlayerConnection.java ++++ b/src/main/java/net/minecraft/server/PlayerConnection.java +@@ -849,9 +849,19 @@ public class PlayerConnection implements PacketPlayInListener { + this.minecraftServer.getPlayerList().sendMessage(chatmessage1, false); + } + ++ // Spigot - spam exclusions ++ boolean counted = true; ++ for ( String exclude : org.spigotmc.SpigotConfig.spamExclusions ) ++ { ++ if ( exclude != null && s.startsWith( exclude ) ) ++ { ++ counted = false; ++ break; ++ } ++ } + // CraftBukkit start - replaced with thread safe throttle + // this.chatThrottle += 20; +- if (chatSpamField.addAndGet(this, 20) > 200 && !this.minecraftServer.getPlayerList().isOp(this.player.getProfile())) { ++ if (counted && chatSpamField.addAndGet(this, 20) > 200 && !this.minecraftServer.getPlayerList().isOp(this.player.getProfile())) { + if (packetplayinchat.a()) { + Waitable waitable = new Waitable() { + @Override +diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java +index e26b964..5d65983 100644 +--- a/src/main/java/org/spigotmc/SpigotConfig.java ++++ b/src/main/java/org/spigotmc/SpigotConfig.java +@@ -6,6 +6,7 @@ import java.io.IOException; + import java.lang.reflect.InvocationTargetException; + import java.lang.reflect.Method; + import java.lang.reflect.Modifier; ++import java.util.Arrays; + import java.util.HashMap; + import java.util.List; + import java.util.Map; +@@ -262,4 +263,13 @@ public class SpigotConfig + { + playerShuffle = getInt( "settings.player-shuffle", 0 ); + } ++ ++ public static List spamExclusions; ++ private static void spamExclusions() ++ { ++ spamExclusions = getList( "commands.spam-exclusions", Arrays.asList( new String[] ++ { ++ "/skill" ++ } ) ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0103-Add-Option-to-Silence-CommandBlock-Console.patch b/CraftBukkit-Patches/0103-Add-Option-to-Silence-CommandBlock-Console.patch new file mode 100644 index 0000000000..7e29fcc027 --- /dev/null +++ b/CraftBukkit-Patches/0103-Add-Option-to-Silence-CommandBlock-Console.patch @@ -0,0 +1,37 @@ +From 9f2767b020cc96e769795d094d80f3a5a2f324cd Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sun, 9 Feb 2014 14:39:01 +1100 +Subject: [PATCH] Add Option to Silence CommandBlock Console + + +diff --git a/src/main/java/net/minecraft/server/CommandDispatcher.java b/src/main/java/net/minecraft/server/CommandDispatcher.java +index 4c21643..4e4f001 100644 +--- a/src/main/java/net/minecraft/server/CommandDispatcher.java ++++ b/src/main/java/net/minecraft/server/CommandDispatcher.java +@@ -83,7 +83,7 @@ public class CommandDispatcher extends CommandHandler implements ICommandDispatc + } + } + +- if (icommandlistener != MinecraftServer.getServer()) { ++ if (icommandlistener != MinecraftServer.getServer() && !org.spigotmc.SpigotConfig.silentCommandBlocks) { // Spigot + MinecraftServer.getServer().sendMessage(chatmessage); + } + +diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java +index 5d65983..d749f16 100644 +--- a/src/main/java/org/spigotmc/SpigotConfig.java ++++ b/src/main/java/org/spigotmc/SpigotConfig.java +@@ -272,4 +272,10 @@ public class SpigotConfig + "/skill" + } ) ); + } ++ ++ public static boolean silentCommandBlocks; ++ private static void silentCommandBlocks() ++ { ++ silentCommandBlocks = getBoolean( "commands.silent-commandblock-console", false ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0104-Add-support-for-fetching-hidden-players.patch b/CraftBukkit-Patches/0104-Add-support-for-fetching-hidden-players.patch new file mode 100644 index 0000000000..42fb2eb5b3 --- /dev/null +++ b/CraftBukkit-Patches/0104-Add-support-for-fetching-hidden-players.patch @@ -0,0 +1,26 @@ +From 733a15b3cf49c23bf2265c014ca905788d887844 Mon Sep 17 00:00:00 2001 +From: Tux +Date: Sun, 9 Feb 2014 14:03:03 -0500 +Subject: [PATCH] Add support for fetching hidden players + + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index 3443f55..1934132 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -1374,6 +1374,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + { + return getHandle().locale; + } ++ ++ @Override ++ public Set getHiddenPlayers() ++ { ++ return java.util.Collections.unmodifiableSet( new HashSet( hiddenPlayers.values() ) ); ++ } + }; + + public Player.Spigot spigot() +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0105-Allow-Disabling-Creative-Item-Filter.patch b/CraftBukkit-Patches/0105-Allow-Disabling-Creative-Item-Filter.patch new file mode 100644 index 0000000000..b6bd84ce82 --- /dev/null +++ b/CraftBukkit-Patches/0105-Allow-Disabling-Creative-Item-Filter.patch @@ -0,0 +1,37 @@ +From badfa468d2663db83ce8fcab80d1188941f1a54f Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Wed, 12 Feb 2014 18:18:01 +1100 +Subject: [PATCH] Allow Disabling Creative Item Filter + + +diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java +index 40fb962..f998670 100644 +--- a/src/main/java/net/minecraft/server/PlayerConnection.java ++++ b/src/main/java/net/minecraft/server/PlayerConnection.java +@@ -1501,7 +1501,7 @@ public class PlayerConnection implements PacketPlayInListener { + ItemStack itemstack = packetplayinsetcreativeslot.getItemStack(); + boolean flag1 = packetplayinsetcreativeslot.c() >= 1 && packetplayinsetcreativeslot.c() < 36 + PlayerInventory.getHotbarSize(); + // CraftBukkit - Add invalidItems check +- boolean flag2 = itemstack == null || itemstack.getItem() != null && !invalidItems.contains(Item.b(itemstack.getItem())); ++ boolean flag2 = itemstack == null || itemstack.getItem() != null && (!invalidItems.contains(Item.b(itemstack.getItem())) || !org.spigotmc.SpigotConfig.filterCreativeItems); // Spigot + boolean flag3 = itemstack == null || itemstack.getData() >= 0 && itemstack.count <= 64 && itemstack.count > 0; + + // CraftBukkit start - Call click event +diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java +index d749f16..0d0c7b0 100644 +--- a/src/main/java/org/spigotmc/SpigotConfig.java ++++ b/src/main/java/org/spigotmc/SpigotConfig.java +@@ -278,4 +278,10 @@ public class SpigotConfig + { + silentCommandBlocks = getBoolean( "commands.silent-commandblock-console", false ); + } ++ ++ public static boolean filterCreativeItems; ++ private static void filterCreativeItems() ++ { ++ filterCreativeItems = getBoolean( "settings.filter-creative-items", true ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0106-Cap-Channel-Registrations.patch b/CraftBukkit-Patches/0106-Cap-Channel-Registrations.patch new file mode 100644 index 0000000000..12cc4abc58 --- /dev/null +++ b/CraftBukkit-Patches/0106-Cap-Channel-Registrations.patch @@ -0,0 +1,21 @@ +From f8f8985ada082e25b2f24f576655c8bcfc53955e Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Wed, 12 Feb 2014 20:02:58 +1100 +Subject: [PATCH] Cap Channel Registrations + + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index 1934132..d33502a 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -1056,6 +1056,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + } + + public void addChannel(String channel) { ++ com.google.common.base.Preconditions.checkState( channels.size() < 128, "Too many channels registered" ); // Spigot + if (channels.add(channel)) { + server.getPluginManager().callEvent(new PlayerRegisterChannelEvent(this, channel)); + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0107-Allow-vanilla-commands-to-be-the-main-version-of-a-c.patch b/CraftBukkit-Patches/0107-Allow-vanilla-commands-to-be-the-main-version-of-a-c.patch new file mode 100644 index 0000000000..0e466a7304 --- /dev/null +++ b/CraftBukkit-Patches/0107-Allow-vanilla-commands-to-be-the-main-version-of-a-c.patch @@ -0,0 +1,174 @@ +From e7b60e8bc41205e2bbc11de51d73f5208e1f3b80 Mon Sep 17 00:00:00 2001 +From: Thinkofdeath +Date: Wed, 12 Feb 2014 20:44:14 +0000 +Subject: [PATCH] Allow vanilla commands to be the main version of a command + + +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +index 674acb9..2645c97 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -116,6 +116,7 @@ import org.bukkit.command.CommandSender; + import org.bukkit.command.ConsoleCommandSender; + import org.bukkit.command.PluginCommand; + import org.bukkit.command.SimpleCommandMap; ++import org.bukkit.command.defaults.VanillaCommand; + import org.bukkit.configuration.ConfigurationSection; + import org.bukkit.configuration.file.YamlConfiguration; + import org.bukkit.configuration.serialization.ConfigurationSerialization; +@@ -381,8 +382,11 @@ public final class CraftServer implements Server { + } + + if (type == PluginLoadOrder.POSTWORLD) { ++ // Spigot start - Allow vanilla commands to be forced to be the main command ++ setVanillaCommands(true); + commandMap.setFallbackCommands(); +- setVanillaCommands(); ++ setVanillaCommands(false); ++ // Spigot end + commandMap.registerServerAliases(); + loadCustomPermissions(); + DefaultPermissions.registerCorePermissions(); +@@ -394,51 +398,64 @@ public final class CraftServer implements Server { + pluginManager.disablePlugins(); + } + +- private void setVanillaCommands() { +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandAchievement(), "/achievement give [player]")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandBan(), "/ban [reason]")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandBanIp(), "/ban-ip ")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandBanList(), "/banlist [ips]")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandClear(), "/clear [item] [metadata]")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandGamemodeDefault(), "/defaultgamemode ")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandDeop(), "/deop ")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandDifficulty(), "/difficulty ")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandEffect(), "/effect [seconds] [amplifier]")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandEnchant(), "/enchant [enchantment level]")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandGamemode(), "/gamemode [player]")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandGamerule(), "/gamerule [true|false]")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandGive(), "/give [amount] [metadata] [dataTag]")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandHelp(), "/help [page|commandname]")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandIdleTimeout(), "/setidletimeout ")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandKick(), "/kick [reason]")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandKill(), "/kill [playername]")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandList(), "/list")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandMe(), "/me ")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandOp(), "/op ")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandPardon(), "/pardon ")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandPardonIP(), "/pardon-ip ")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandPlaySound(), "/playsound [x] [y] [z] [volume] [pitch] [minimumVolume]")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSay(), "/say ")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandScoreboard(), "/scoreboard")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSeed(), "/seed")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSetBlock(), "/setblock [datavalue] [oldblockHandling] [dataTag]")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSetWorldSpawn(), "/setworldspawn [x] [y] [z]")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSpawnpoint(), "/spawnpoint [x] [y] [z]")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSpreadPlayers(), "/spreadplayers [spreadDistance] [maxRange] [respectTeams] ")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandSummon(), "/summon [x] [y] [z] [dataTag]")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandTp(), "/tp [player] \n/tp [player] ")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandTell(), "/tell ")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandTellRaw(), "/tellraw ")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandTestFor(), "/testfor [dataTag]")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandTestForBlock(), "/testforblock [datavalue] [dataTag]")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandTime(), "/time set \n/time add ")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandToggleDownfall(), "/toggledownfall")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandWeather(), "/weather [duration in seconds]")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandWhitelist(), "/whitelist (add|remove) \n/whitelist (on|off|list|reload)")); +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandXp(), "/xp [player]\n/xp L [player]")); ++ // Spigot start ++ private void tryRegister(VanillaCommandWrapper commandWrapper, boolean first) { ++ if (org.spigotmc.SpigotConfig.replaceCommands.contains( commandWrapper.getName() ) ) { ++ if (first) { ++ commandMap.register( "minecraft", commandWrapper ); ++ } ++ } else if (!first) { ++ commandMap.register( "minecraft", commandWrapper ); ++ } ++ } ++ ++ private void setVanillaCommands(boolean first) ++ { ++ tryRegister( new VanillaCommandWrapper( new CommandAchievement(), "/achievement give [player]" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandBan(), "/ban [reason]" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandBanIp(), "/ban-ip " ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandBanList(), "/banlist [ips]" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandClear(), "/clear [item] [metadata]" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandGamemodeDefault(), "/defaultgamemode " ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandDeop(), "/deop " ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandDifficulty(), "/difficulty " ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandEffect(), "/effect [seconds] [amplifier]" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandEnchant(), "/enchant [enchantment level]" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandGamemode(), "/gamemode [player]" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandGamerule(), "/gamerule [true|false]" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandGive(), "/give [amount] [metadata] [dataTag]" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandHelp(), "/help [page|commandname]" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandIdleTimeout(), "/setidletimeout " ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandKick(), "/kick [reason]" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandKill(), "/kill [playername]" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandList(), "/list" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandMe(), "/me " ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandOp(), "/op " ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandPardon(), "/pardon " ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandPardonIP(), "/pardon-ip " ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandPlaySound(), "/playsound [x] [y] [z] [volume] [pitch] [minimumVolume]" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandSay(), "/say " ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandScoreboard(), "/scoreboard" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandSeed(), "/seed" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandSetBlock(), "/setblock [datavalue] [oldblockHandling] [dataTag]" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandSetWorldSpawn(), "/setworldspawn [x] [y] [z]" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandSpawnpoint(), "/spawnpoint [x] [y] [z]" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandSpreadPlayers(), "/spreadplayers [spreadDistance] [maxRange] [respectTeams] " ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandSummon(), "/summon [x] [y] [z] [dataTag]" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandTp(), "/tp [player] \n/tp [player] " ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandTell(), "/tell " ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandTellRaw(), "/tellraw " ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandTestFor(), "/testfor [dataTag]" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandTestForBlock(), "/testforblock [datavalue] [dataTag]" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandTime(), "/time set \n/time add " ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandToggleDownfall(), "/toggledownfall" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandWeather(), "/weather [duration in seconds]" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandWhitelist(), "/whitelist (add|remove) \n/whitelist (on|off|list|reload)" ), first ); ++ tryRegister( new VanillaCommandWrapper( new CommandXp(), "/xp [player]\n/xp L [player]" ), first ); + // This is what is in the lang file, I swear. +- commandMap.register("minecraft", new VanillaCommandWrapper(new CommandNetstat(), "/list")); ++ tryRegister( new VanillaCommandWrapper(new CommandNetstat(), "/list"), first ); + } ++ // Spigot end + + private void loadPlugin(Plugin plugin) { + try { +diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java +index 0d0c7b0..4703768 100644 +--- a/src/main/java/org/spigotmc/SpigotConfig.java ++++ b/src/main/java/org/spigotmc/SpigotConfig.java +@@ -8,8 +8,10 @@ import java.lang.reflect.Method; + import java.lang.reflect.Modifier; + import java.util.Arrays; + import java.util.HashMap; ++import java.util.HashSet; + import java.util.List; + import java.util.Map; ++import java.util.Set; + import java.util.logging.Level; + + import gnu.trove.map.hash.TObjectIntHashMap; +@@ -284,4 +286,16 @@ public class SpigotConfig + { + filterCreativeItems = getBoolean( "settings.filter-creative-items", true ); + } ++ ++ public static Set replaceCommands; ++ private static void replaceCommands() ++ { ++ if ( config.contains( "replace-commands" ) ) ++ { ++ set( "commands.replace-commands", config.getStringList( "replace-commands" ) ); ++ config.set( "replace-commands", null ); ++ } ++ replaceCommands = new HashSet( (List) getList( "commands.replace-commands", ++ Arrays.asList( "setblock", "summon", "testforblock", "tellraw" ) ) ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0108-Unfinalize-the-isDisconnected-method-by-bukkit.patch b/CraftBukkit-Patches/0108-Unfinalize-the-isDisconnected-method-by-bukkit.patch new file mode 100644 index 0000000000..520a93f12c --- /dev/null +++ b/CraftBukkit-Patches/0108-Unfinalize-the-isDisconnected-method-by-bukkit.patch @@ -0,0 +1,23 @@ +From e04cef687e5499a956f943b80ca1861ca1cac0db Mon Sep 17 00:00:00 2001 +From: hcherndon +Date: Sat, 15 Feb 2014 01:51:20 -0600 +Subject: [PATCH] Unfinalize the isDisconnected() method by bukkit. + +This would literally mean the world to me. You have no idea how much this method being final is fucking me over right now. (Working with NPC's and what not.) + +diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java +index f998670..b01b6d4 100644 +--- a/src/main/java/net/minecraft/server/PlayerConnection.java ++++ b/src/main/java/net/minecraft/server/PlayerConnection.java +@@ -1887,7 +1887,7 @@ public class PlayerConnection implements PacketPlayInListener { + } + + // CraftBukkit start - Add "isDisconnected" method +- public final boolean isDisconnected() { ++ public boolean isDisconnected() { + return !this.player.joining && !NetworkManager.a(this.networkManager).config().isAutoRead(); + } + // CraftBukkit end +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0109-Implement-Silenceable-Lightning-API.patch b/CraftBukkit-Patches/0109-Implement-Silenceable-Lightning-API.patch new file mode 100644 index 0000000000..697e547511 --- /dev/null +++ b/CraftBukkit-Patches/0109-Implement-Silenceable-Lightning-API.patch @@ -0,0 +1,105 @@ +From 9ca5bcfb6dd388d4ec3eac8e4a2ed8422354626e Mon Sep 17 00:00:00 2001 +From: drXor +Date: Sun, 23 Feb 2014 16:16:59 -0400 +Subject: [PATCH] Implement Silenceable Lightning API + + +diff --git a/src/main/java/net/minecraft/server/EntityLightning.java b/src/main/java/net/minecraft/server/EntityLightning.java +index 2fd88c0..35806d1 100644 +--- a/src/main/java/net/minecraft/server/EntityLightning.java ++++ b/src/main/java/net/minecraft/server/EntityLightning.java +@@ -13,6 +13,8 @@ public class EntityLightning extends EntityWeather { + // CraftBukkit start + public boolean isEffect = false; + ++ public boolean isSilent = false; // Spigot ++ + public EntityLightning(World world, double d0, double d1, double d2) { + this(world, d0, d1, d2, false); + } +@@ -60,9 +62,17 @@ public class EntityLightning extends EntityWeather { + } + } + ++ // Spigot start ++ public EntityLightning(World world, double d0, double d1, double d2, boolean isEffect, boolean isSilent) ++ { ++ this( world, d0, d1, d2, isEffect ); ++ this.isSilent = isSilent; ++ } ++ // Spigot end ++ + public void h() { + super.h(); +- if (this.lifeTicks == 2) { ++ if (!isSilent && this.lifeTicks == 2) { // Spigot + this.world.makeSound(this.locX, this.locY, this.locZ, "ambient.weather.thunder", 10000.0F, 0.8F + this.random.nextFloat() * 0.2F); + this.world.makeSound(this.locX, this.locY, this.locZ, "random.explode", 2.0F, 0.5F + this.random.nextFloat() * 0.2F); + } +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +index 827ec16..154b868 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +@@ -1326,6 +1326,22 @@ public class CraftWorld implements World { + { + CraftWorld.this.playEffect( location, effect, 0 ); + } ++ ++ @Override ++ public LightningStrike strikeLightning(Location loc, boolean isSilent) ++ { ++ EntityLightning lightning = new EntityLightning( world, loc.getX(), loc.getY(), loc.getZ(), false, isSilent ); ++ world.strikeLightning( lightning ); ++ return new CraftLightningStrike( server, lightning ); ++ } ++ ++ @Override ++ public LightningStrike strikeLightningEffect(Location loc, boolean isSilent) ++ { ++ EntityLightning lightning = new EntityLightning( world, loc.getX(), loc.getY(), loc.getZ(), true, isSilent ); ++ world.strikeLightning( lightning ); ++ return new CraftLightningStrike( server, lightning ); ++ } + }; + + public Spigot spigot() +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java +index 64e346d..be4f10f 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java +@@ -1,7 +1,9 @@ + package org.bukkit.craftbukkit.entity; + + import net.minecraft.server.EntityLightning; ++ + import org.bukkit.craftbukkit.CraftServer; ++import org.bukkit.entity.Arrow; + import org.bukkit.entity.EntityType; + import org.bukkit.entity.LightningStrike; + +@@ -27,4 +29,22 @@ public class CraftLightningStrike extends CraftEntity implements LightningStrike + public EntityType getType() { + return EntityType.LIGHTNING; + } ++ ++ // Spigot start ++ private final LightningStrike.Spigot spigot = new LightningStrike.Spigot() ++ { ++ ++ @Override ++ public boolean isSilent() ++ { ++ return getHandle().isSilent; ++ } ++ ++ }; ++ ++ public LightningStrike.Spigot spigot() ++ { ++ return this.spigot; ++ } ++ // Spigot end + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0110-Normalize-spaces-on-when-reading-a-chat-packet.patch b/CraftBukkit-Patches/0110-Normalize-spaces-on-when-reading-a-chat-packet.patch new file mode 100644 index 0000000000..83bc70ce01 --- /dev/null +++ b/CraftBukkit-Patches/0110-Normalize-spaces-on-when-reading-a-chat-packet.patch @@ -0,0 +1,35 @@ +From 63be1358f86e8a513e9984a7099aa7a793e94bc0 Mon Sep 17 00:00:00 2001 +From: Thinkofdeath +Date: Wed, 26 Feb 2014 14:45:22 +0000 +Subject: [PATCH] Normalize spaces on when reading a chat packet + + +diff --git a/src/main/java/net/minecraft/server/PacketPlayInChat.java b/src/main/java/net/minecraft/server/PacketPlayInChat.java +index d419f0f..b26c290 100644 +--- a/src/main/java/net/minecraft/server/PacketPlayInChat.java ++++ b/src/main/java/net/minecraft/server/PacketPlayInChat.java +@@ -17,7 +17,7 @@ public class PacketPlayInChat extends Packet { + } + + public void a(PacketDataSerializer packetdataserializer) throws IOException { // CraftBukkit - added throws +- this.message = packetdataserializer.c(100); ++ this.message = org.apache.commons.lang.StringUtils.normalizeSpace( packetdataserializer.c( 100 ) ); // Spigot + } + + public void b(PacketDataSerializer packetdataserializer) throws IOException { // CraftBukkit - added throws +diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java +index b01b6d4..55db414 100644 +--- a/src/main/java/net/minecraft/server/PlayerConnection.java ++++ b/src/main/java/net/minecraft/server/PlayerConnection.java +@@ -792,7 +792,7 @@ public class PlayerConnection implements PacketPlayInListener { + this.player.v(); + String s = packetplayinchat.c(); + +- s = StringUtils.normalizeSpace(s); ++ // s = StringUtils.normalizeSpace(s); Spigot - Moved to PacketPlayInChat + + for (int i = 0; i < s.length(); ++i) { + if (!SharedConstants.isAllowedChatCharacter(s.charAt(i))) { +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0111-Use-one-PermissibleBase-for-all-Command-Blocks.patch b/CraftBukkit-Patches/0111-Use-one-PermissibleBase-for-all-Command-Blocks.patch new file mode 100644 index 0000000000..52f5fcb67a --- /dev/null +++ b/CraftBukkit-Patches/0111-Use-one-PermissibleBase-for-all-Command-Blocks.patch @@ -0,0 +1,33 @@ +From ee13d3a98b6256aca458526270c815d20ef678c5 Mon Sep 17 00:00:00 2001 +From: FrozenBrain +Date: Sun, 2 Mar 2014 21:13:46 +0100 +Subject: [PATCH] Use one PermissibleBase for all Command Blocks + + +diff --git a/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java b/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java +index 1314c74..b339cf3 100644 +--- a/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java ++++ b/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java +@@ -12,9 +12,18 @@ import org.bukkit.plugin.Plugin; + import java.util.Set; + + public abstract class ServerCommandSender implements CommandSender { +- private final PermissibleBase perm = new PermissibleBase(this); ++ private static PermissibleBase blockPermInst; ++ private final PermissibleBase perm; + + public ServerCommandSender() { ++ if (this instanceof CraftBlockCommandSender) { ++ if (blockPermInst == null) { ++ blockPermInst = new PermissibleBase(this); ++ } ++ this.perm = blockPermInst; ++ } else { ++ this.perm = new PermissibleBase(this); ++ } + } + + public boolean isPermissionSet(String name) { +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0112-Prevent-hoppers-from-loading-chunks.patch b/CraftBukkit-Patches/0112-Prevent-hoppers-from-loading-chunks.patch new file mode 100644 index 0000000000..654e91a31e --- /dev/null +++ b/CraftBukkit-Patches/0112-Prevent-hoppers-from-loading-chunks.patch @@ -0,0 +1,21 @@ +From e57e4a58d5d9739a4c0305cb5248930a6ee0d2c7 Mon Sep 17 00:00:00 2001 +From: Thinkofdeath +Date: Wed, 5 Mar 2014 20:27:27 +0000 +Subject: [PATCH] Prevent hoppers from loading chunks + + +diff --git a/src/main/java/net/minecraft/server/TileEntityHopper.java b/src/main/java/net/minecraft/server/TileEntityHopper.java +index d7a3178..b6718bf 100644 +--- a/src/main/java/net/minecraft/server/TileEntityHopper.java ++++ b/src/main/java/net/minecraft/server/TileEntityHopper.java +@@ -540,6 +540,7 @@ public class TileEntityHopper extends TileEntity implements IHopper { + int i = MathHelper.floor(d0); + int j = MathHelper.floor(d1); + int k = MathHelper.floor(d2); ++ if ( !world.isLoaded( i, j, k ) ) return null; // Spigot + TileEntity tileentity = world.getTileEntity(i, j, k); + + if (tileentity != null && tileentity instanceof IInventory) { +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0113-Guard-Entity-List.patch b/CraftBukkit-Patches/0113-Guard-Entity-List.patch new file mode 100644 index 0000000000..b79ea80ec7 --- /dev/null +++ b/CraftBukkit-Patches/0113-Guard-Entity-List.patch @@ -0,0 +1,79 @@ +From 90be9eaab308e864147a8b1d132993ccfa5b0e30 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Mon, 10 Mar 2014 09:03:28 +1100 +Subject: [PATCH] Guard Entity List + + +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index c0a4bea..61fa519 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -30,7 +30,32 @@ import org.bukkit.event.weather.ThunderChangeEvent; + public abstract class World implements IBlockAccess { + + public boolean d; +- public List entityList = new ArrayList(); ++ // Spigot start - guard entity list from removals ++ public List entityList = new ArrayList() ++ { ++ @Override ++ public Object remove(int index) ++ { ++ guard(); ++ return super.remove( index ); ++ } ++ ++ @Override ++ public boolean remove(Object o) ++ { ++ guard(); ++ return super.remove( o ); ++ } ++ ++ private void guard() ++ { ++ if ( guardEntityList ) ++ { ++ throw new java.util.ConcurrentModificationException(); ++ } ++ } ++ }; ++ // Spigot end + protected List f = new ArrayList(); + public Set tileEntityList = new HashSet(); // CraftBukkit - ArrayList -> HashSet + private List a = new ArrayList(); +@@ -78,6 +103,7 @@ public abstract class World implements IBlockAccess { + int[] I; + + // Spigot start ++ private boolean guardEntityList; + protected final gnu.trove.map.hash.TLongShortHashMap chunkTickList; + protected float growthOdds = 100; + protected float modifiedOdds = 100; +@@ -1270,6 +1296,7 @@ public abstract class World implements IBlockAccess { + + org.spigotmc.ActivationRange.activateEntities(this); // Spigot + timings.entityTick.startTiming(); // Spigot ++ guardEntityList = true; // Spigot + // CraftBukkit start - Use field for loop variable + for (this.tickPosition = 0; this.tickPosition < this.entityList.size(); ++this.tickPosition) { + entity = (Entity) this.entityList.get(this.tickPosition); +@@ -1318,12 +1345,15 @@ public abstract class World implements IBlockAccess { + this.getChunkAt(j, k).b(entity); + } + ++ guardEntityList = false; // Spigot + this.entityList.remove(this.tickPosition--); // CraftBukkit - Use field for loop variable ++ guardEntityList = true; // Spigot + this.b(entity); + } + + this.methodProfiler.b(); + } ++ guardEntityList = false; // Spigot + + timings.entityTick.stopTiming(); // Spigot + this.methodProfiler.c("blockEntities"); +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0114-Fix-ConcurrentModificationException-while-being-idle.patch b/CraftBukkit-Patches/0114-Fix-ConcurrentModificationException-while-being-idle.patch new file mode 100644 index 0000000000..a8349df2f0 --- /dev/null +++ b/CraftBukkit-Patches/0114-Fix-ConcurrentModificationException-while-being-idle.patch @@ -0,0 +1,54 @@ +From f17e7f7d18037ebc7bb2931b4a7d64526abc57d4 Mon Sep 17 00:00:00 2001 +From: Thinkofdeath +Date: Tue, 14 Jan 2014 20:11:25 +0000 +Subject: [PATCH] Fix ConcurrentModificationException while being idle kicked + in a vehicle + + +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index 61fa519..40325bf 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -1043,23 +1043,24 @@ public abstract class World implements IBlockAccess { + this.players.remove(entity); + this.everyoneSleeping(); + } +- +- int i = entity.ah; +- int j = entity.aj; +- +- if (entity.ag && this.isChunkLoaded(i, j)) { +- this.getChunkAt(i, j).b(entity); +- } +- +- // CraftBukkit start - Decrement loop variable field if we've already ticked this entity +- int index = this.entityList.indexOf(entity); +- if (index != -1) { +- if (index <= this.tickPosition) { +- this.tickPosition--; ++ // Spigot start ++ if (!guardEntityList) { // It will get removed after the tick if we are ticking ++ int i = entity.ah; ++ int j = entity.aj; ++ if (entity.ag && this.isChunkLoaded(i, j)) { ++ this.getChunkAt(i, j).b(entity); + } +- this.entityList.remove(index); ++ // CraftBukkit start - Decrement loop variable field if we've already ticked this entity ++ int index = this.entityList.indexOf(entity); ++ if (index != -1) { ++ if (index <= this.tickPosition) { ++ this.tickPosition--; ++ } ++ this.entityList.remove(index); ++ } ++ // CraftBukkit end + } +- // CraftBukkit end ++ // Spigot end + + this.b(entity); + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0115-Cancellable-WitherSkull-potion-effect.patch b/CraftBukkit-Patches/0115-Cancellable-WitherSkull-potion-effect.patch new file mode 100644 index 0000000000..504f18543a --- /dev/null +++ b/CraftBukkit-Patches/0115-Cancellable-WitherSkull-potion-effect.patch @@ -0,0 +1,36 @@ +From b3c7812bdfe3cfd8d995dbc66c709622306ba3b9 Mon Sep 17 00:00:00 2001 +From: drXor +Date: Tue, 25 Feb 2014 15:15:26 -0400 +Subject: [PATCH] Cancellable WitherSkull potion effect + + +diff --git a/src/main/java/net/minecraft/server/EntityWitherSkull.java b/src/main/java/net/minecraft/server/EntityWitherSkull.java +index d749175..b8c3cef 100644 +--- a/src/main/java/net/minecraft/server/EntityWitherSkull.java ++++ b/src/main/java/net/minecraft/server/EntityWitherSkull.java +@@ -35,15 +35,19 @@ public class EntityWitherSkull extends EntityFireball { + protected void a(MovingObjectPosition movingobjectposition) { + if (!this.world.isStatic) { + if (movingobjectposition.entity != null) { ++ // Spigot start ++ boolean didDamage = false; + if (this.shooter != null) { +- if (movingobjectposition.entity.damageEntity(DamageSource.mobAttack(this.shooter), 8.0F) && !movingobjectposition.entity.isAlive()) { ++ didDamage = movingobjectposition.entity.damageEntity(DamageSource.mobAttack(this.shooter), 8.0F); ++ if (didDamage && !movingobjectposition.entity.isAlive()) { + this.shooter.heal(5.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.WITHER); // CraftBukkit + } + } else { +- movingobjectposition.entity.damageEntity(DamageSource.MAGIC, 5.0F); ++ didDamage = movingobjectposition.entity.damageEntity(DamageSource.MAGIC, 5.0F); + } + +- if (movingobjectposition.entity instanceof EntityLiving) { ++ if (didDamage && movingobjectposition.entity instanceof EntityLiving) { ++ // Spigot end + byte b0 = 0; + + if (this.world.difficulty == EnumDifficulty.NORMAL) { +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0116-Optimize-Player-Lookup.patch b/CraftBukkit-Patches/0116-Optimize-Player-Lookup.patch new file mode 100644 index 0000000000..4d78829019 --- /dev/null +++ b/CraftBukkit-Patches/0116-Optimize-Player-Lookup.patch @@ -0,0 +1,188 @@ +From c72aadfb4ca40278f6c5aec574fbe7e5711b83ca Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sat, 15 Mar 2014 14:34:03 +1100 +Subject: [PATCH] Optimize Player Lookup + +Optimize player lookup and various player operations. We mainly do this by keeping a map instead of iterating through all players. We also speed up the duplicate login check and a few other checks by simply checking for one matching player. + +diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java +index d2a378e..8a48ec2 100644 +--- a/src/main/java/net/minecraft/server/PlayerList.java ++++ b/src/main/java/net/minecraft/server/PlayerList.java +@@ -61,6 +61,25 @@ public abstract class PlayerList { + private boolean s; + private int t; + ++ // Spigot Start ++ private final Map playerMap = new java.util.HashMap(); ++ ++ private void removePlayer(EntityPlayer player) ++ { ++ playerMap.remove( player.getName().toLowerCase() ); ++ } ++ ++ private void addPlayer(EntityPlayer player) ++ { ++ playerMap.put( player.getName().toLowerCase(), player ); ++ } ++ ++ private EntityPlayer getPlayerByName(String name) ++ { ++ return playerMap.get( name.toLowerCase() ); ++ } ++ // Spigot End ++ + // CraftBukkit start + private CraftServer cserver; + +@@ -244,6 +263,7 @@ public abstract class PlayerList { + cserver.detectListNameConflict(entityplayer); // CraftBukkit + // this.sendAll(new PacketPlayOutPlayerInfo(entityplayer.getName(), true, 1000)); // CraftBukkit - replaced with loop below + this.players.add(entityplayer); ++ addPlayer( entityplayer ); // Spigot + WorldServer worldserver = this.server.getWorldServer(entityplayer.dimension); + + // CraftBukkit start +@@ -319,6 +339,7 @@ public abstract class PlayerList { + worldserver.kill(entityplayer); + worldserver.getPlayerChunkMap().removePlayer(entityplayer); + this.players.remove(entityplayer); ++ removePlayer( entityplayer ); // Spigot + this.n.remove(entityplayer.getUniqueID()); + ChunkIOExecutor.adjustPoolSize(this.getPlayerCount()); // CraftBukkit + +@@ -394,24 +415,14 @@ event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig + } + + public EntityPlayer processLogin(GameProfile gameprofile, EntityPlayer player) { // CraftBukkit - added EntityPlayer +- UUID uuid = EntityHuman.a(gameprofile); +- ArrayList arraylist = Lists.newArrayList(); +- +- EntityPlayer entityplayer; ++ // Spigot Start ++ EntityPlayer entityplayer = getPlayer( gameprofile.getName() ); + +- for (int i = 0; i < this.players.size(); ++i) { +- entityplayer = (EntityPlayer) this.players.get(i); +- if (entityplayer.getUniqueID().equals(uuid)) { +- arraylist.add(entityplayer); +- } +- } +- +- Iterator iterator = arraylist.iterator(); +- +- while (iterator.hasNext()) { +- entityplayer = (EntityPlayer) iterator.next(); +- entityplayer.playerConnection.disconnect("You logged in from another location"); ++ if ( entityplayer != null ) ++ { ++ entityplayer.playerConnection.disconnect( "You logged in from another location" ); + } ++ // Spigot End + + /* CraftBukkit start + Object object; +@@ -901,19 +912,7 @@ event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig + } + + public EntityPlayer getPlayer(String s) { +- Iterator iterator = this.players.iterator(); +- +- EntityPlayer entityplayer; +- +- do { +- if (!iterator.hasNext()) { +- return null; +- } +- +- entityplayer = (EntityPlayer) iterator.next(); +- } while (!entityplayer.getName().equalsIgnoreCase(s)); +- +- return entityplayer; ++ return getPlayerByName( s ); // Spigot + } + + public List a(ChunkCoordinates chunkcoordinates, int i, int j, int k, int l, int i1, int j1, Map map, String s, String s1, World world) { +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java +index bec4134..0430cc1 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java +@@ -131,14 +131,10 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa + } + + public Player getPlayer() { +- for (Object obj : server.getHandle().players) { +- EntityPlayer player = (EntityPlayer) obj; +- if (player.getUniqueID().equals(getUniqueId())) { +- return (player.playerConnection != null) ? player.playerConnection.getPlayer() : null; +- } +- } +- +- return null; ++ // Spigot Start ++ EntityPlayer player = server.getHandle().getPlayer( name ); ++ return ( player != null && player.playerConnection != null ) ? player.getBukkitEntity() : null; ++ // Spigot End + } + + @Override +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +index 2645c97..ff13c51 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -502,6 +502,13 @@ public final class CraftServer implements Server { + public Player getPlayer(final String name) { + Validate.notNull(name, "Name cannot be null"); + ++ // Spigot Start ++ Player directLookup = getPlayerExact( name ); ++ if ( directLookup != null ) ++ { ++ return directLookup; ++ } ++ // Spigot End + Player[] players = getOnlinePlayers(); + + Player found = null; +@@ -523,15 +530,10 @@ public final class CraftServer implements Server { + public Player getPlayerExact(String name) { + Validate.notNull(name, "Name cannot be null"); + +- String lname = name.toLowerCase(); +- +- for (Player player : getOnlinePlayers()) { +- if (player.getName().equalsIgnoreCase(lname)) { +- return player; +- } +- } +- +- return null; ++ // Spigot Start ++ EntityPlayer entityPlayer = playerList.getPlayer( name ); ++ return ( entityPlayer != null ) ? entityPlayer.getBukkitEntity() : null; ++ // Spigot End + } + + // TODO: In 1.7.6+ this should use the server's UUID->EntityPlayer map +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index d33502a..a2eeb1b 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -101,13 +101,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + } + + public boolean isOnline() { +- for (Object obj : server.getHandle().players) { +- EntityPlayer player = (EntityPlayer) obj; +- if (player.getName().equalsIgnoreCase(getName())) { +- return true; +- } +- } +- return false; ++ return server.getHandle().getPlayer( getName() ) != null; // Spigot + } + + public InetSocketAddress getAddress() { +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0117-Descriptive-kick-reasons-instead-of-Nope.patch b/CraftBukkit-Patches/0117-Descriptive-kick-reasons-instead-of-Nope.patch new file mode 100644 index 0000000000..e1d0dd2491 --- /dev/null +++ b/CraftBukkit-Patches/0117-Descriptive-kick-reasons-instead-of-Nope.patch @@ -0,0 +1,53 @@ +From d0650a1956322d53f81772d57e6e0fc1431ddba2 Mon Sep 17 00:00:00 2001 +From: drXor +Date: Sat, 15 Mar 2014 01:30:05 -0400 +Subject: [PATCH] Descriptive kick reasons instead of Nope! + + +diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java +index c049cd8..37a9cae 100644 +--- a/src/main/java/net/minecraft/server/Entity.java ++++ b/src/main/java/net/minecraft/server/Entity.java +@@ -218,7 +218,7 @@ public abstract class Entity { + if ((f == Float.POSITIVE_INFINITY) || (f == Float.NEGATIVE_INFINITY)) { + if (this instanceof EntityPlayer) { + this.world.getServer().getLogger().warning(((CraftPlayer) this.getBukkitEntity()).getName() + " was caught trying to crash the server with an invalid yaw"); +- ((CraftPlayer) this.getBukkitEntity()).kickPlayer("Nope"); ++ ((CraftPlayer) this.getBukkitEntity()).kickPlayer("Infinite yaw (Hacking?)"); //Spigot "Nope" -> Descriptive reason + } + f = 0; + } +@@ -231,7 +231,7 @@ public abstract class Entity { + if ((f1 == Float.POSITIVE_INFINITY) || (f1 == Float.NEGATIVE_INFINITY)) { + if (this instanceof EntityPlayer) { + this.world.getServer().getLogger().warning(((CraftPlayer) this.getBukkitEntity()).getName() + " was caught trying to crash the server with an invalid pitch"); +- ((CraftPlayer) this.getBukkitEntity()).kickPlayer("Nope"); ++ ((CraftPlayer) this.getBukkitEntity()).kickPlayer("Infinite pitch (Hacking?)"); //Spigot "Nope" -> Descriptive reason + } + f1 = 0; + } +diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java +index 55db414..6f30e6d 100644 +--- a/src/main/java/net/minecraft/server/PlayerConnection.java ++++ b/src/main/java/net/minecraft/server/PlayerConnection.java +@@ -184,7 +184,7 @@ public class PlayerConnection implements PacketPlayInListener { + // CraftBukkit start - Check for NaN + if (Double.isNaN(packetplayinflying.x) || Double.isNaN(packetplayinflying.y) || Double.isNaN(packetplayinflying.z) || Double.isNaN(packetplayinflying.stance)) { + c.warn(player.getName() + " was caught trying to crash the server with an invalid position."); +- getPlayer().kickPlayer("Nope!"); ++ getPlayer().kickPlayer("NaN in position (Hacking?)"); //Spigot "Nope" -> Descriptive reason + return; + } + // CraftBukkit end +@@ -778,7 +778,7 @@ public class PlayerConnection implements PacketPlayInListener { + this.player.v(); + } else { + c.warn(this.player.getName() + " tried to set an invalid carried item"); +- this.disconnect("Nope!"); // CraftBukkit ++ this.disconnect("Invalid hotbar selection (Hacking?)"); // CraftBukkit //Spigot "Nope" -> Descriptive reason + } + } + +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0118-Allow-enchanting-tables-to-enchant-any-item.patch b/CraftBukkit-Patches/0118-Allow-enchanting-tables-to-enchant-any-item.patch new file mode 100644 index 0000000000..ccb4f03f0f --- /dev/null +++ b/CraftBukkit-Patches/0118-Allow-enchanting-tables-to-enchant-any-item.patch @@ -0,0 +1,34 @@ +From 2b720d915f2c4e1fb462bec95695438d6488a11d Mon Sep 17 00:00:00 2001 +From: andrepl +Date: Sat, 15 Mar 2014 12:50:00 -0400 +Subject: [PATCH] Allow enchanting tables to enchant any item + + +diff --git a/src/main/java/net/minecraft/server/ContainerEnchantTable.java b/src/main/java/net/minecraft/server/ContainerEnchantTable.java +index 528fbc9..372ccde 100644 +--- a/src/main/java/net/minecraft/server/ContainerEnchantTable.java ++++ b/src/main/java/net/minecraft/server/ContainerEnchantTable.java +@@ -152,6 +152,11 @@ public class ContainerEnchantTable extends Container { + if (this.costs[i] > 0 && itemstack != null && (entityhuman.expLevel >= this.costs[i] || entityhuman.abilities.canInstantlyBuild)) { + if (!this.world.isStatic) { + List list = EnchantmentManager.b(this.l, itemstack, this.costs[i]); ++ // Spigot - Provide an empty enchantment list ++ if (list == null) { ++ list = new java.util.ArrayList(); ++ } ++ // Spigot End + boolean flag = itemstack.getItem() == Items.BOOK; + + if (list != null) { +@@ -186,7 +191,7 @@ public class ContainerEnchantTable extends Container { + EnchantmentInstance enchantment = new EnchantmentInstance(enchantId, entry.getValue()); + Items.ENCHANTED_BOOK.a(itemstack, enchantment); + } else { +- item.addEnchantment(entry.getKey(), entry.getValue()); ++ item.addUnsafeEnchantment(entry.getKey(), entry.getValue()); // Spigot addEnchantment -> addUnsafeEnchantment + } + } catch (IllegalArgumentException e) { + /* Just swallow invalid enchantments */ +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0119-Remove-the-lastChunkAccessed-if-it-is-unloaded.patch b/CraftBukkit-Patches/0119-Remove-the-lastChunkAccessed-if-it-is-unloaded.patch new file mode 100644 index 0000000000..a618f9bfe5 --- /dev/null +++ b/CraftBukkit-Patches/0119-Remove-the-lastChunkAccessed-if-it-is-unloaded.patch @@ -0,0 +1,60 @@ +From 32b284ce20bccabfb267a4b516074071a32270e7 Mon Sep 17 00:00:00 2001 +From: Thinkofdeath +Date: Tue, 18 Mar 2014 09:49:30 +0000 +Subject: [PATCH] Remove the lastChunkAccessed if it is unloaded. + +This fixes an issue where a chunk would be unloaded but remain in lastChunkAccessed meaning calls on getChunkAt could return a chunk that is no longer loaded, this caused an issue where the chunk could be reloaded whilst in use reverting any block changes. This caused findEndPortal to return null even after createEndPortal which would crash the server trying to teleport to a null location. + +diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java +index b669d05..33e4cff 100644 +--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java ++++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java +@@ -316,6 +316,13 @@ public class ChunkProviderServer implements IChunkProvider { + long chunkcoordinates = this.unloadQueue.popFirst(); + Chunk chunk = this.chunks.get(chunkcoordinates); + if (chunk == null) continue; ++ // Spigot start - Remove the chunk from the cache if it is unloaded ++ Chunk result = world.lastChunkAccessed; ++ if ( result != null && result.locX == chunk.locX && result.locZ == chunk.locZ ) ++ { ++ world.lastChunkAccessed = null; ++ } ++ // Spigot end + + ChunkUnloadEvent event = new ChunkUnloadEvent(chunk.bukkitChunk); + server.getPluginManager().callEvent(event); +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index 40325bf..ca8d029 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -154,7 +154,7 @@ public abstract class World implements IBlockAccess { + public boolean pvpMode; + public boolean keepSpawnInMemory = true; + public ChunkGenerator generator; +- Chunk lastChunkAccessed; ++ public Chunk lastChunkAccessed; // Spigot - Make public + int lastXAccessed = Integer.MIN_VALUE; + int lastZAccessed = Integer.MIN_VALUE; + final Object chunkLock = new Object(); +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +index 154b868..8592205 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +@@ -187,6 +187,14 @@ public class CraftWorld implements World { + world.chunkProviderServer.saveChunkNOP(chunk); + } + ++ // Spigot start - Remove the chunk from the cache if it is unloaded ++ net.minecraft.server.Chunk result = world.lastChunkAccessed; ++ if ( result != null && result.locX == chunk.locX && result.locZ == chunk.locZ ) ++ { ++ world.lastChunkAccessed = null; ++ } ++ // Spigot end ++ + world.chunkProviderServer.unloadQueue.remove(x, z); + world.chunkProviderServer.chunks.remove(LongHash.toLong(x, z)); + +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0120-Check-for-manually-prefixed-commands-or-commands-tha.patch b/CraftBukkit-Patches/0120-Check-for-manually-prefixed-commands-or-commands-tha.patch new file mode 100644 index 0000000000..c0a940a19b --- /dev/null +++ b/CraftBukkit-Patches/0120-Check-for-manually-prefixed-commands-or-commands-tha.patch @@ -0,0 +1,29 @@ +From 0eaf4e148ee92f7e6672a8196c83739b8a459280 Mon Sep 17 00:00:00 2001 +From: Thinkofdeath +Date: Sun, 23 Mar 2014 01:12:10 +0000 +Subject: [PATCH] Check for manually prefixed commands or commands that don't + need a prefix for calling vanilla commands with command blocks + + +diff --git a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java +index da235e5..0b04e94 100644 +--- a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java ++++ b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java +@@ -110,6 +110,14 @@ public abstract class CommandBlockListenerAbstract implements ICommandListener { + } + } + ++ // Spigot start - check for manually prefixed command or commands that don't need a prefix ++ org.bukkit.command.Command commandBlockCommand = commandMap.getCommand(args[0]); ++ if (commandBlockCommand instanceof VanillaCommandWrapper) { ++ this.b = ((VanillaCommandWrapper) commandBlockCommand).dispatchVanillaCommandBlock(this, this.e); ++ return; ++ } ++ // Spigot end ++ + // Make sure this is a valid command + if (commandMap.getCommand(args[0]) == null) { + this.b = 0; +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0121-Cap-window-names-to-prevent-client-disconnects.patch b/CraftBukkit-Patches/0121-Cap-window-names-to-prevent-client-disconnects.patch new file mode 100644 index 0000000000..8d120e8b2a --- /dev/null +++ b/CraftBukkit-Patches/0121-Cap-window-names-to-prevent-client-disconnects.patch @@ -0,0 +1,21 @@ +From a899b5259c3a0cbbc3df4646b21b1a49578bfca0 Mon Sep 17 00:00:00 2001 +From: Thinkofdeath +Date: Sun, 23 Mar 2014 10:53:48 +0000 +Subject: [PATCH] Cap window names to prevent client disconnects + + +diff --git a/src/main/java/net/minecraft/server/PacketPlayOutOpenWindow.java b/src/main/java/net/minecraft/server/PacketPlayOutOpenWindow.java +index f6d7b2b..860592d 100644 +--- a/src/main/java/net/minecraft/server/PacketPlayOutOpenWindow.java ++++ b/src/main/java/net/minecraft/server/PacketPlayOutOpenWindow.java +@@ -14,6 +14,7 @@ public class PacketPlayOutOpenWindow extends Packet { + public PacketPlayOutOpenWindow() {} + + public PacketPlayOutOpenWindow(int i, int j, String s, int k, boolean flag) { ++ if (s.length() > 32) s = s.substring( 0, 32 ); // Spigot - Cap window name to prevent client disconnects + this.a = i; + this.b = j; + this.c = s; +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0122-Enable-Improved-Ping-Sending.patch b/CraftBukkit-Patches/0122-Enable-Improved-Ping-Sending.patch new file mode 100644 index 0000000000..97967c2c67 --- /dev/null +++ b/CraftBukkit-Patches/0122-Enable-Improved-Ping-Sending.patch @@ -0,0 +1,65 @@ +From 55f21f861261a6deb713e8eeee6045917dc8a71c Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sun, 24 Feb 2013 20:45:20 +1100 +Subject: [PATCH] Enable Improved Ping Sending + + +diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java +index 4fb5f75..c164e39 100644 +--- a/src/main/java/net/minecraft/server/EntityPlayer.java ++++ b/src/main/java/net/minecraft/server/EntityPlayer.java +@@ -62,6 +62,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + public boolean keepLevel = false; + public double maxHealthCache; + public boolean joining = true; ++ public int lastPing = -1; // Spigot + // CraftBukkit end + // Spigot start + public boolean collidesWithEntities = true; +diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java +index 8a48ec2..9a052f7 100644 +--- a/src/main/java/net/minecraft/server/PlayerList.java ++++ b/src/main/java/net/minecraft/server/PlayerList.java +@@ -804,6 +804,8 @@ event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig + // CraftBukkit end + } + ++ private int currentPing = 0; ++ + public void tick() { + if (++this.t > 600) { + this.t = 0; +@@ -816,6 +818,30 @@ event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig + this.sendAll(new PacketPlayOutPlayerInfo(entityplayer.getName(), true, entityplayer.ping)); + } + // CraftBukkit end */ ++ // Spigot start ++ try ++ { ++ if ( !players.isEmpty() ) ++ { ++ currentPing = ( currentPing + 1 ) % this.players.size(); ++ EntityPlayer player = (EntityPlayer) this.players.get( currentPing ); ++ if ( player.lastPing == -1 || Math.abs( player.ping - player.lastPing ) > 20 ) ++ { ++ Packet packet = new PacketPlayOutPlayerInfo( player.listName, true, player.ping ); ++ for ( EntityPlayer splayer : (List) this.players ) ++ { ++ if ( splayer.getBukkitEntity().canSee( player.getBukkitEntity() ) ) ++ { ++ splayer.playerConnection.sendPacket( packet ); ++ } ++ } ++ player.lastPing = player.ping; ++ } ++ } ++ } catch ( Exception e ) { ++ // Better safe than sorry :) ++ } ++ // Spigot end + } + + public void sendAll(Packet packet) { +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0123-Prevent-getOfflinePlayer-UUID-on-main-thread.patch b/CraftBukkit-Patches/0123-Prevent-getOfflinePlayer-UUID-on-main-thread.patch new file mode 100644 index 0000000000..df035c55ec --- /dev/null +++ b/CraftBukkit-Patches/0123-Prevent-getOfflinePlayer-UUID-on-main-thread.patch @@ -0,0 +1,21 @@ +From 60bd33f0f7cb963b7e6eb8387bbfd8e20a53ba40 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Sun, 30 Mar 2014 09:15:35 +1100 +Subject: [PATCH] Prevent getOfflinePlayer(UUID) on main thread. + + +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +index ff13c51..7b2242a 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -1306,6 +1306,7 @@ public final class CraftServer implements Server { + + public OfflinePlayer getOfflinePlayer(String name) { + Validate.notNull(name, "Name cannot be null"); ++ com.google.common.base.Preconditions.checkState(!Bukkit.isPrimaryThread(), "Cannot call getOfflinePlayer(UUID) on main thread, this operation is blocking!"); // Spigot + + // This is potentially blocking :( + GameProfile profile = MinecraftServer.getServer().getUserCache().a(name); +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0124-Configurable-dragon-death-and-wither-spawn-sounds.patch b/CraftBukkit-Patches/0124-Configurable-dragon-death-and-wither-spawn-sounds.patch new file mode 100644 index 0000000000..ced9d6a3a4 --- /dev/null +++ b/CraftBukkit-Patches/0124-Configurable-dragon-death-and-wither-spawn-sounds.patch @@ -0,0 +1,70 @@ +From 3fbe203218e86fb4f100231f2d01bcb5ecb28a0a Mon Sep 17 00:00:00 2001 +From: drXor +Date: Sat, 29 Mar 2014 13:44:25 -0400 +Subject: [PATCH] Configurable dragon death and wither spawn sounds + + +diff --git a/src/main/java/net/minecraft/server/EntityEnderDragon.java b/src/main/java/net/minecraft/server/EntityEnderDragon.java +index f53b183..9a8408c 100644 +--- a/src/main/java/net/minecraft/server/EntityEnderDragon.java ++++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java +@@ -550,7 +550,14 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo + } + + if (this.bB == 1) { +- this.world.b(1018, (int) this.locX, (int) this.locY, (int) this.locZ, 0); ++ // Spigot start ++ if(this.world.spigotConfig.dragonDeathSoundRadius > 0){ ++ this.world.getServer().getHandle().sendPacketNearby((int) this.locX, (int) this.locY, (int) this.locZ, this.world.spigotConfig.dragonDeathSoundRadius, this.dimension, new PacketPlayOutWorldEvent(1018, (int) this.locX, (int) this.locY, (int) this.locZ, 0, true)); ++ } ++ else { ++ this.world.b(1018, (int) this.locX, (int) this.locY, (int) this.locZ, 0); ++ } ++ // Spigot end + } + } + +diff --git a/src/main/java/net/minecraft/server/EntityWither.java b/src/main/java/net/minecraft/server/EntityWither.java +index 99526b9..2ba0a81 100644 +--- a/src/main/java/net/minecraft/server/EntityWither.java ++++ b/src/main/java/net/minecraft/server/EntityWither.java +@@ -172,7 +172,14 @@ public class EntityWither extends EntityMonster implements IRangedEntity { + // CraftBukkit end + + this.world.createExplosion(this, this.locX, this.locY + (double) this.getHeadHeight(), this.locZ, 7.0F, false, this.world.getGameRules().getBoolean("mobGriefing")); +- this.world.b(1013, (int) this.locX, (int) this.locY, (int) this.locZ, 0); ++ // Spigot start ++ if(this.world.spigotConfig.witherSpawnSoundRadius > 0){ ++ this.world.getServer().getHandle().sendPacketNearby((int) this.locX, (int) this.locY, (int) this.locZ, this.world.spigotConfig.witherSpawnSoundRadius, this.dimension, new PacketPlayOutWorldEvent(1013, (int) this.locX, (int) this.locY, (int) this.locZ, 0, true)); ++ } ++ else { ++ this.world.b(1013, (int) this.locX, (int) this.locY, (int) this.locZ, 0); ++ } ++ // Spigot end + } + + this.s(i); +diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java +index b12a086..312fa55 100644 +--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java ++++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java +@@ -278,4 +278,16 @@ public class SpigotWorldConfig + maxCollisionsPerEntity = getInt( "max-entity-collisions", 8 ); + log( "Max Entity Collisions: " + maxCollisionsPerEntity ); + } ++ ++ public int dragonDeathSoundRadius; ++ private void keepDragonDeathPerWorld() ++ { ++ dragonDeathSoundRadius = getInt( "dragon-death-sound-radius", 0 ); ++ } ++ ++ public int witherSpawnSoundRadius; ++ private void witherSpawnSoundRadius() ++ { ++ witherSpawnSoundRadius = getInt( "wither-spawn-sound-radius", 0 ); ++ } + } +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0125-Fix-TileEntities-getting-ticked-after-being-queued-f.patch b/CraftBukkit-Patches/0125-Fix-TileEntities-getting-ticked-after-being-queued-f.patch new file mode 100644 index 0000000000..dc736fe1b7 --- /dev/null +++ b/CraftBukkit-Patches/0125-Fix-TileEntities-getting-ticked-after-being-queued-f.patch @@ -0,0 +1,38 @@ +From 814cd274eba3e544ef80ae68cc23a31fe2a657a4 Mon Sep 17 00:00:00 2001 +From: FrozenBrain +Date: Sun, 23 Mar 2014 01:49:13 +0100 +Subject: [PATCH] Fix TileEntities getting ticked after being queued for + removal + + +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index ca8d029..e576397 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -1359,6 +1359,12 @@ public abstract class World implements IBlockAccess { + timings.entityTick.stopTiming(); // Spigot + this.methodProfiler.c("blockEntities"); + timings.tileEntityTick.startTiming(); // Spigot ++ // Spigot start - brought up from below ++ if (!this.b.isEmpty()) { ++ this.tileEntityList.removeAll(this.b); ++ this.b.clear(); ++ } ++ // Spigot End + this.M = true; + Iterator iterator = this.tileEntityList.iterator(); + +@@ -1407,10 +1413,6 @@ public abstract class World implements IBlockAccess { + timings.tileEntityTick.stopTiming(); // Spigot + timings.tileEntityPending.startTiming(); // Spigot + this.M = false; +- if (!this.b.isEmpty()) { +- this.tileEntityList.removeAll(this.b); +- this.b.clear(); +- } + + this.methodProfiler.c("pendingBlockEntities"); + if (!this.a.isEmpty()) { +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0126-Display-Spigot-in-client-crashes-server-lists-and-Mo.patch b/CraftBukkit-Patches/0126-Display-Spigot-in-client-crashes-server-lists-and-Mo.patch new file mode 100644 index 0000000000..10823bae52 --- /dev/null +++ b/CraftBukkit-Patches/0126-Display-Spigot-in-client-crashes-server-lists-and-Mo.patch @@ -0,0 +1,23 @@ +From d67f62ef765845a19868002ec81a452b95f7ea20 Mon Sep 17 00:00:00 2001 +From: Thinkofdeath +Date: Fri, 11 Apr 2014 11:16:34 +0100 +Subject: [PATCH] Display 'Spigot' in client crashes, server lists and Mojang + stats + + +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 408b25d..43e0ab2 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -969,7 +969,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo + } + + public String getServerModName() { +- return server.getName(); // CraftBukkit - cb > vanilla! ++ return "Spigot"; // Spigot - Spigot > // CraftBukkit - cb > vanilla! + } + + public CrashReport b(CrashReport crashreport) { +-- +1.8.3.2 +