diff --git a/.gitignore b/.gitignore
index c101ffb154..952f896233 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,3 +40,5 @@ Spigot-API
Spigot-Server
PaperSpigot-Server
PaperSpigot-API
+Bukkit
+CraftBukkit
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index 975323705c..0000000000
--- a/.gitmodules
+++ /dev/null
@@ -1,6 +0,0 @@
-[submodule "Bukkit"]
- path = Bukkit
- url = https://github.com/Bukkit/Bukkit.git
-[submodule "CraftBukkit"]
- path = CraftBukkit
- url = https://github.com/Zbob750/CraftBukkit.git
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 4d8c2a7bf7..0000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-language: java
-jdk:
- - openjdk7
- - oraclejdk7
- - oraclejdk8
-notifications:
- email: false
-before_install:
- - git config --global user.email "admin@ecocitycraft.com"
- - git config --global user.name "EcoCityCraft"
- - ./applyPatches.sh
diff --git a/Bukkit b/Bukkit
deleted file mode 160000
index f210234e59..0000000000
--- a/Bukkit
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit f210234e59275330f83b994e199c76f6abd41ee7
diff --git a/Bukkit-Patches/0001-POM-Changes.patch b/Bukkit-Patches/0001-POM-Changes.patch
index ff670db3b2..811a986c0e 100644
--- a/Bukkit-Patches/0001-POM-Changes.patch
+++ b/Bukkit-Patches/0001-POM-Changes.patch
@@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- bukkit
+ org.spigotmc
+ spigot-api
- 1.7.10-R0.1-SNAPSHOT
+ 1.8-R0.1-SNAPSHOT
- Bukkit
- http://www.bukkit.org
+ Spigot-API
@@ -25,40 +25,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
UTF-8
--
-- scm:git:git@github.com:Bukkit/Bukkit.git
-- scm:git:git://github.com/Bukkit/Bukkit.git
-- https://github.com/Bukkit/Bukkit/tree/master/
--
--
--
-- jenkins
-- http://ci.bukkit.org
--
--
--
--
-- jd.bukkit.org
-- file:///home/javadocs/public_html/
--
--
-- repobo-rel
-- repo.bukkit.org Releases
-- http://repo.bukkit.org/content/repositories/releases/
--
--
-- repobo-snap
-- repo.bukkit.org Snapshots
-- http://repo.bukkit.org/content/repositories/snapshots/
--
--
+
+ org.spigotmc
+ spigot-parent
+ dev-SNAPSHOT
+ ../pom.xml
+
-
++
++
++
++ sonatype-snapshots
++ https://oss.sonatype.org/content/repositories/public
++
++
++
+
--
\ No newline at end of file
diff --git a/Bukkit-Patches/0015-Add-Getter-for-Entity-Invulnerability.patch b/Bukkit-Patches/0015-Add-Getter-for-Entity-Invulnerability.patch
index 864bbf1866..8377632c3f 100644
--- a/Bukkit-Patches/0015-Add-Getter-for-Entity-Invulnerability.patch
+++ b/Bukkit-Patches/0015-Add-Getter-for-Entity-Invulnerability.patch
@@ -9,9 +9,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/bukkit/entity/Entity.java
+++ b/src/main/java/org/bukkit/entity/Entity.java
@@ -0,0 +0,0 @@ public interface Entity extends Metadatable {
- * @return The current vehicle.
+ * @return if the custom name is displayed
*/
- public Entity getVehicle();
+ public boolean isCustomNameVisible();
+
+ // Spigot Start
+ public class Spigot
diff --git a/Bukkit-Patches/0029-Undeprecate-Player-updateInventory-V.patch b/Bukkit-Patches/0029-Undeprecate-Player-updateInventory-V.patch
index 6a596fbad0..c7ba2c0815 100644
--- a/Bukkit-Patches/0029-Undeprecate-Player-updateInventory-V.patch
+++ b/Bukkit-Patches/0029-Undeprecate-Player-updateInventory-V.patch
@@ -20,6 +20,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public void updateInventory();
/**
---
-1.8.4.2
-
+--
\ No newline at end of file
diff --git a/Bukkit-Patches/0031-Skip-loading-of-plugins-which-are-not-1.8-compatible.patch b/Bukkit-Patches/0031-Skip-loading-of-plugins-which-are-not-1.8-compatible.patch
index 89bf129cc9..31eb9299ed 100644
--- a/Bukkit-Patches/0031-Skip-loading-of-plugins-which-are-not-1.8-compatible.patch
+++ b/Bukkit-Patches/0031-Skip-loading-of-plugins-which-are-not-1.8-compatible.patch
@@ -19,11 +19,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ server.getLogger().log( Level.WARNING, "Skipping loading of Orebfuscator as it does not work with Spigot 1.8 builds!" );
+ continue;
+ }
-+ if ( name.equalsIgnoreCase( "EchoPet" ) )
-+ {
-+ server.getLogger().log( Level.WARNING, "Skipping loading of EchoPet as it does not work with Spigot 1.8 builds!" );
-+ continue;
-+ }
+ // Spigot End
if (name.equalsIgnoreCase("bukkit") || name.equalsIgnoreCase("minecraft") || name.equalsIgnoreCase("mojang")) {
server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': Restricted Name");
diff --git a/Bukkit-Patches/0032-Spigot-Update-20140909a.patch b/Bukkit-Patches/0032-Spigot-Update-20140909a.patch
deleted file mode 100644
index 198f1850df..0000000000
--- a/Bukkit-Patches/0032-Spigot-Update-20140909a.patch
+++ /dev/null
@@ -1,99 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: md_5
-Date: Thu, 11 Sep 2014 01:06:54 -0700
-Subject: [PATCH] Spigot Update - 20140909a
-
-
-diff --git a/pom.xml b/pom.xml
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/pom.xml
-+++ b/pom.xml
-@@ -0,0 +0,0 @@
- ../pom.xml
-
-
-+
-+
-+ sonatype-snapshots
-+ https://oss.sonatype.org/content/repositories/public
-+
-+
-+
-
-
-
-@@ -0,0 +0,0 @@
-
-
-
-+ net.md-5
-+ bungeecord-chat
-+ 1.8-SNAPSHOT
-+ jar
-+ compile
-+
-+
- org.yaml
- snakeyaml
- 1.12
-diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/Server.java
-+++ b/src/main/java/org/bukkit/Server.java
-@@ -0,0 +0,0 @@ import java.util.Set;
- import java.util.UUID;
- import java.util.logging.Logger;
-
-+import net.md_5.bungee.api.chat.BaseComponent;
- import org.bukkit.Warning.WarningState;
- import org.bukkit.command.CommandException;
- import org.bukkit.command.CommandSender;
-@@ -0,0 +0,0 @@ public interface Server extends PluginMessageRecipient {
- {
- throw new UnsupportedOperationException( "Not supported yet." );
- }
-+
-+ public void broadcast(BaseComponent component)
-+ {
-+ throw new UnsupportedOperationException( "Not supported yet." );
-+ }
-+
-+ public void broadcast(BaseComponent... components)
-+ {
-+ throw new UnsupportedOperationException( "Not supported yet." );
-+ }
- }
-
- Spigot spigot();
-diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/entity/Player.java
-+++ b/src/main/java/org/bukkit/entity/Player.java
-@@ -0,0 +0,0 @@ package org.bukkit.entity;
-
- import java.net.InetSocketAddress;
-
-+import net.md_5.bungee.api.chat.BaseComponent;
- import org.bukkit.Achievement;
- import org.bukkit.ChatColor;
- import org.bukkit.Effect;
-@@ -0,0 +0,0 @@ public interface Player extends HumanEntity, Conversable, CommandSender, Offline
- {
- throw new UnsupportedOperationException( "Not supported yet." );
- }
-+
-+ public void sendMessage(BaseComponent component)
-+ {
-+ throw new UnsupportedOperationException( "Not supported yet." );
-+ }
-+
-+ public void sendMessage(BaseComponent... components)
-+ {
-+ throw new UnsupportedOperationException( "Not supported yet." );
-+ }
- }
-
- Spigot spigot();
---
-1.9.4.msysgit.0
-
diff --git a/Bukkit-Patches/0033-Spigot-Update-20140909b.patch b/Bukkit-Patches/0033-Spigot-Update-20140909b.patch
deleted file mode 100644
index 3b61dd99e9..0000000000
--- a/Bukkit-Patches/0033-Spigot-Update-20140909b.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: md_5
-Date: Fri, 12 Sep 2014 17:16:11 -0700
-Subject: [PATCH] Spigot Update - 20140909b
-
-
-diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
-+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
-@@ -0,0 +0,0 @@ public final class SimplePluginManager implements PluginManager {
- server.getLogger().log( Level.WARNING, "Skipping loading of Orebfuscator as it does not work with Spigot 1.8 builds!" );
- continue;
- }
-- if ( name.equalsIgnoreCase( "EchoPet" ) )
-- {
-- server.getLogger().log( Level.WARNING, "Skipping loading of EchoPet as it does not work with Spigot 1.8 builds!" );
-- continue;
-- }
- // Spigot End
- if (name.equalsIgnoreCase("bukkit") || name.equalsIgnoreCase("minecraft") || name.equalsIgnoreCase("mojang")) {
- server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': Restricted Name");
---
-1.9.4.msysgit.0
-
diff --git a/Bukkit-Patches/0034-Spigot-Update-20140911a.patch b/Bukkit-Patches/0034-Spigot-Update-20140911a.patch
deleted file mode 100644
index b057b73f4b..0000000000
--- a/Bukkit-Patches/0034-Spigot-Update-20140911a.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: md_5
-Date: Fri, 12 Sep 2014 18:20:53 -0700
-Subject: [PATCH] Spigot Update - 20140911a
-
-
-diff --git a/pom.xml b/pom.xml
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/pom.xml
-+++ b/pom.xml
-@@ -0,0 +0,0 @@
- 1.8-SNAPSHOT
- jar
- compile
-+
-+
-+ com.google.code.gson
-+ gson
-+
-+
-+ net.sf.trove4j
-+ trove4j
-+
-+
-
-
- org.yaml
---
-1.9.4.msysgit.0
-
diff --git a/CraftBukkit b/CraftBukkit
deleted file mode 160000
index 07d4558b48..0000000000
--- a/CraftBukkit
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 07d4558b48d0717cb7f9e07015c76599b9fe9697
diff --git a/CraftBukkit-Patches/0001-POM-Changes.patch b/CraftBukkit-Patches/0001-POM-Changes.patch
index 8e8d7b97fa..149bfcff24 100644
--- a/CraftBukkit-Patches/0001-POM-Changes.patch
+++ b/CraftBukkit-Patches/0001-POM-Changes.patch
@@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ org.spigotmc
+ spigot
jar
- 1.7.10-R0.1-SNAPSHOT
+ 1.8-R0.1-SNAPSHOT
- CraftBukkit
- http://www.bukkit.org
+ Spigot
@@ -30,33 +30,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--
-- scm:git:git://github.com/Bukkit/CraftBukkit.git
-- scm:git:ssh://git@github.com/Bukkit/CraftBukkit.git
-- https://github.com/Bukkit/CraftBukkit
--
--
--
--
-- repobo-rel
-- repo.bukkit.org Releases
-- http://repo.bukkit.org/content/repositories/releases/
--
--
-- repobo-snap
-- repo.bukkit.org Snapshots
-- http://repo.bukkit.org/content/repositories/snapshots/
--
--
+
+ org.spigotmc
+ spigot-parent
+ dev-SNAPSHOT
+ ../pom.xml
+
-
++
+ repobo-snap
@@ -0,0 +0,0 @@
@@ -68,50 +51,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
${project.version}
jar
compile
-
-
-- org.bukkit
-+ org.spigotmc
- minecraft-server
-- ${minecraft.version}
-+ ${minecraft.version}-SNAPSHOT
- jar
- compile
-
-@@ -0,0 +0,0 @@
- gson
- 2.1
-
--
-- org.avaje
-- ebean
-- 2.7.3
-- jar
-- provided
--
--
-- org.yaml
-- snakeyaml
-- 1.9
-- jar
-- provided
--
--
-- com.google.guava
-- guava
-- 10.0
-- jar
-- provided
--
--
-- commons-lang
-- commons-lang
-- 2.3
-- provided
--
-
-
- junit
@@ -0,0 +0,0 @@
@@ -140,19 +79,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
package
-diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
- loadIcon();
-
- updater = new AutoUpdater(new BukkitDLUpdaterService(configuration.getString("auto-updater.host")), getLogger(), configuration.getString("auto-updater.preferred-channel"));
-- updater.setEnabled(configuration.getBoolean("auto-updater.enabled"));
-+ updater.setEnabled(false); // Spigot
- updater.setSuggestChannels(configuration.getBoolean("auto-updater.suggest-channels"));
- updater.getOnBroken().addAll(configuration.getStringList("auto-updater.on-broken"));
- updater.getOnUpdate().addAll(configuration.getStringList("auto-updater.on-update"));
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
diff --git a/CraftBukkit-Patches/0002-mc-dev-imports.patch b/CraftBukkit-Patches/0002-mc-dev-imports.patch
index ea0ba618a7..30bcde69c5 100644
--- a/CraftBukkit-Patches/0002-mc-dev-imports.patch
+++ b/CraftBukkit-Patches/0002-mc-dev-imports.patch
@@ -19,8 +19,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ private final double b;
+ private String c;
+
-+ public AttributeRanged(String s, double d0, double d1, double d2) {
-+ super(s, d0);
++ public AttributeRanged(IAttribute iattribute, String s, double d0, double d1, double d2) {
++ super(iattribute, s, d0);
+ this.a = d1;
+ this.b = d2;
+ if (d1 > d2) {
@@ -37,19 +37,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return this;
+ }
+
-+ public String f() {
++ public String g() {
+ return this.c;
+ }
+
+ public double a(double d0) {
-+ if (d0 < this.a) {
-+ d0 = this.a;
-+ }
-+
-+ if (d0 > this.b) {
-+ d0 = this.b;
-+ }
-+
++ d0 = MathHelper.a(d0, this.a, this.b);
+ return d0;
+ }
+}
@@ -61,19 +54,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@
+package net.minecraft.server;
+
++import com.google.gson.JsonDeserializationContext;
++import com.google.gson.JsonDeserializer;
++import com.google.gson.JsonElement;
++import com.google.gson.JsonObject;
++import com.google.gson.JsonSerializationContext;
++import com.google.gson.JsonSerializer;
++import com.mojang.authlib.GameProfile;
+import java.lang.reflect.Type;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.UUID;
+
-+import net.minecraft.util.com.google.gson.JsonDeserializationContext;
-+import net.minecraft.util.com.google.gson.JsonDeserializer;
-+import net.minecraft.util.com.google.gson.JsonElement;
-+import net.minecraft.util.com.google.gson.JsonObject;
-+import net.minecraft.util.com.google.gson.JsonSerializationContext;
-+import net.minecraft.util.com.google.gson.JsonSerializer;
-+import net.minecraft.util.com.mojang.authlib.GameProfile;
-+
+class BanEntrySerializer implements JsonDeserializer, JsonSerializer {
+
+ final UserCache a;
@@ -162,8 +154,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ protected World a;
+ protected Random b;
-+ protected int c;
-+ protected int d;
++ protected BlockPosition c;
++ protected CustomWorldSettingsFinal d;
+ protected WorldGenerator e = new WorldGenClay(4);
+ protected WorldGenerator f;
+ protected WorldGenerator g;
@@ -175,16 +167,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ protected WorldGenerator m;
+ protected WorldGenerator n;
+ protected WorldGenerator o;
-+ protected WorldGenFlowers p;
++ protected WorldGenerator p;
+ protected WorldGenerator q;
+ protected WorldGenerator r;
-+ protected WorldGenerator s;
++ protected WorldGenFlowers s;
+ protected WorldGenerator t;
+ protected WorldGenerator u;
+ protected WorldGenerator v;
-+ protected int w;
-+ protected int x;
-+ protected int y;
++ protected WorldGenerator w;
++ protected WorldGenerator x;
++ protected WorldGenerator y;
+ protected int z;
+ protected int A;
+ protected int B;
@@ -194,42 +186,55 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ protected int F;
+ protected int G;
+ protected int H;
-+ public boolean I;
++ protected int I;
++ protected int J;
++ protected int K;
++ public boolean L;
+
+ public BiomeDecorator() {
+ this.f = new WorldGenSand(Blocks.SAND, 7);
+ this.g = new WorldGenSand(Blocks.GRAVEL, 6);
-+ this.h = new WorldGenMinable(Blocks.DIRT, 32);
-+ this.i = new WorldGenMinable(Blocks.GRAVEL, 32);
-+ this.j = new WorldGenMinable(Blocks.COAL_ORE, 16);
-+ this.k = new WorldGenMinable(Blocks.IRON_ORE, 8);
-+ this.l = new WorldGenMinable(Blocks.GOLD_ORE, 8);
-+ this.m = new WorldGenMinable(Blocks.REDSTONE_ORE, 7);
-+ this.n = new WorldGenMinable(Blocks.DIAMOND_ORE, 7);
-+ this.o = new WorldGenMinable(Blocks.LAPIS_ORE, 6);
-+ this.p = new WorldGenFlowers(Blocks.YELLOW_FLOWER);
-+ this.q = new WorldGenFlowers(Blocks.BROWN_MUSHROOM);
-+ this.r = new WorldGenFlowers(Blocks.RED_MUSHROOM);
-+ this.s = new WorldGenHugeMushroom();
-+ this.t = new WorldGenReed();
-+ this.u = new WorldGenCactus();
-+ this.v = new WorldGenWaterLily();
-+ this.y = 2;
-+ this.z = 1;
-+ this.E = 1;
-+ this.F = 3;
-+ this.G = 1;
-+ this.I = true;
++ this.s = new WorldGenFlowers(Blocks.YELLOW_FLOWER, EnumFlowerVarient.DANDELION);
++ this.t = new WorldGenMushrooms(Blocks.BROWN_MUSHROOM);
++ this.u = new WorldGenMushrooms(Blocks.RED_MUSHROOM);
++ this.v = new WorldGenHugeMushroom();
++ this.w = new WorldGenReed();
++ this.x = new WorldGenCactus();
++ this.y = new WorldGenWaterLily();
++ this.B = 2;
++ this.C = 1;
++ this.H = 1;
++ this.I = 3;
++ this.J = 1;
++ this.L = true;
+ }
+
-+ public void a(World world, Random random, BiomeBase biomebase, int i, int j) {
++ public void a(World world, Random random, BiomeBase biomebase, BlockPosition blockposition) {
+ if (this.a != null) {
-+ throw new RuntimeException("Already decorating!!");
++ throw new RuntimeException("Already decorating");
+ } else {
+ this.a = world;
++ String s = world.getWorldData().getGeneratorOptions();
++
++ if (s != null) {
++ this.d = CustomWorldSettings.a(s).b();
++ } else {
++ this.d = CustomWorldSettings.a("").b();
++ }
++
+ this.b = random;
-+ this.c = i;
-+ this.d = j;
++ this.c = blockposition;
++ this.h = new WorldGenMinable(Blocks.DIRT.getBlockData(), this.d.I);
++ this.i = new WorldGenMinable(Blocks.GRAVEL.getBlockData(), this.d.M);
++ this.j = new WorldGenMinable(Blocks.STONE.getBlockData().set(BlockStone.VARIANT, EnumStoneVariant.GRANITE), this.d.Q);
++ this.k = new WorldGenMinable(Blocks.STONE.getBlockData().set(BlockStone.VARIANT, EnumStoneVariant.DIORITE), this.d.U);
++ this.l = new WorldGenMinable(Blocks.STONE.getBlockData().set(BlockStone.VARIANT, EnumStoneVariant.ANDESITE), this.d.Y);
++ this.m = new WorldGenMinable(Blocks.COAL_ORE.getBlockData(), this.d.ac);
++ this.n = new WorldGenMinable(Blocks.IRON_ORE.getBlockData(), this.d.ag);
++ this.o = new WorldGenMinable(Blocks.GOLD_ORE.getBlockData(), this.d.ak);
++ this.p = new WorldGenMinable(Blocks.REDSTONE_ORE.getBlockData(), this.d.ao);
++ this.q = new WorldGenMinable(Blocks.DIAMOND_ORE.getBlockData(), this.d.as);
++ this.r = new WorldGenMinable(Blocks.LAPIS_ORE.getBlockData(), this.d.aw);
+ this.a(biomebase);
+ this.a = null;
+ this.b = null;
@@ -243,194 +248,224 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ int j;
+ int k;
+
-+ for (i = 0; i < this.F; ++i) {
-+ j = this.c + this.b.nextInt(16) + 8;
-+ k = this.d + this.b.nextInt(16) + 8;
-+ this.f.generate(this.a, this.b, j, this.a.i(j, k), k);
++ for (i = 0; i < this.I; ++i) {
++ j = this.b.nextInt(16) + 8;
++ k = this.b.nextInt(16) + 8;
++ this.f.generate(this.a, this.b, this.a.r(this.c.a(j, 0, k)));
+ }
+
-+ for (i = 0; i < this.G; ++i) {
-+ j = this.c + this.b.nextInt(16) + 8;
-+ k = this.d + this.b.nextInt(16) + 8;
-+ this.e.generate(this.a, this.b, j, this.a.i(j, k), k);
++ for (i = 0; i < this.J; ++i) {
++ j = this.b.nextInt(16) + 8;
++ k = this.b.nextInt(16) + 8;
++ this.e.generate(this.a, this.b, this.a.r(this.c.a(j, 0, k)));
+ }
+
-+ for (i = 0; i < this.E; ++i) {
-+ j = this.c + this.b.nextInt(16) + 8;
-+ k = this.d + this.b.nextInt(16) + 8;
-+ this.g.generate(this.a, this.b, j, this.a.i(j, k), k);
++ for (i = 0; i < this.H; ++i) {
++ j = this.b.nextInt(16) + 8;
++ k = this.b.nextInt(16) + 8;
++ this.g.generate(this.a, this.b, this.a.r(this.c.a(j, 0, k)));
+ }
+
-+ i = this.x;
++ i = this.A;
+ if (this.b.nextInt(10) == 0) {
+ ++i;
+ }
+
+ int l;
-+ int i1;
++ BlockPosition blockposition;
+
+ for (j = 0; j < i; ++j) {
-+ k = this.c + this.b.nextInt(16) + 8;
-+ l = this.d + this.b.nextInt(16) + 8;
-+ i1 = this.a.getHighestBlockYAt(k, l);
++ k = this.b.nextInt(16) + 8;
++ l = this.b.nextInt(16) + 8;
+ WorldGenTreeAbstract worldgentreeabstract = biomebase.a(this.b);
+
-+ worldgentreeabstract.a(1.0D, 1.0D, 1.0D);
-+ if (worldgentreeabstract.generate(this.a, this.b, k, i1, l)) {
-+ worldgentreeabstract.b(this.a, this.b, k, i1, l);
++ worldgentreeabstract.e();
++ blockposition = this.a.getHighestBlockYAt(this.c.a(k, 0, l));
++ if (worldgentreeabstract.generate(this.a, this.b, blockposition)) {
++ worldgentreeabstract.a(this.a, this.b, blockposition);
+ }
+ }
+
-+ for (j = 0; j < this.H; ++j) {
-+ k = this.c + this.b.nextInt(16) + 8;
-+ l = this.d + this.b.nextInt(16) + 8;
-+ this.s.generate(this.a, this.b, k, this.a.getHighestBlockYAt(k, l), l);
++ for (j = 0; j < this.K; ++j) {
++ k = this.b.nextInt(16) + 8;
++ l = this.b.nextInt(16) + 8;
++ this.v.generate(this.a, this.b, this.a.getHighestBlockYAt(this.c.a(k, 0, l)));
+ }
+
-+ for (j = 0; j < this.y; ++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) + 32);
-+ String s = biomebase.a(this.b, k, i1, l);
-+ BlockFlowers blockflowers = BlockFlowers.e(s);
-+
-+ if (blockflowers.getMaterial() != Material.AIR) {
-+ this.p.a(blockflowers, BlockFlowers.f(s));
-+ this.p.generate(this.a, this.b, k, i1, l);
-+ }
-+ }
-+
-+ 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);
-+ WorldGenerator worldgenerator = biomebase.b(this.b);
-+
-+ worldgenerator.generate(this.a, this.b, k, i1, l);
-+ }
-+
-+ 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);
-+ (new WorldGenDeadBush(Blocks.DEAD_BUSH)).generate(this.a, this.b, k, i1, l);
-+ }
-+
-+ for (j = 0; j < this.w; ++j) {
-+ 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) {
-+ ;
-+ }
-+
-+ this.v.generate(this.a, this.b, k, i1, l);
-+ }
++ int i1;
+
+ for (j = 0; j < this.B; ++j) {
++ k = this.b.nextInt(16) + 8;
++ l = this.b.nextInt(16) + 8;
++ i1 = this.b.nextInt(this.a.getHighestBlockYAt(this.c.a(k, 0, l)).getY() + 32);
++ blockposition = this.c.a(k, i1, l);
++ EnumFlowerVarient enumflowervarient = biomebase.a(this.b, blockposition);
++ BlockFlowers blockflowers = enumflowervarient.a().a();
++
++ if (blockflowers.getMaterial() != Material.AIR) {
++ this.s.a(blockflowers, enumflowervarient);
++ this.s.generate(this.a, this.b, blockposition);
++ }
++ }
++
++ for (j = 0; j < this.C; ++j) {
++ k = this.b.nextInt(16) + 8;
++ l = this.b.nextInt(16) + 8;
++ i1 = this.b.nextInt(this.a.getHighestBlockYAt(this.c.a(k, 0, l)).getY() * 2);
++ biomebase.b(this.b).generate(this.a, this.b, this.c.a(k, i1, l));
++ }
++
++ for (j = 0; j < this.D; ++j) {
++ k = this.b.nextInt(16) + 8;
++ l = this.b.nextInt(16) + 8;
++ i1 = this.b.nextInt(this.a.getHighestBlockYAt(this.c.a(k, 0, l)).getY() * 2);
++ (new WorldGenDeadBush()).generate(this.a, this.b, this.c.a(k, i1, l));
++ }
++
++ j = 0;
++
++ while (j < this.z) {
++ k = this.b.nextInt(16) + 8;
++ l = this.b.nextInt(16) + 8;
++ i1 = this.b.nextInt(this.a.getHighestBlockYAt(this.c.a(k, 0, l)).getY() * 2);
++ blockposition = this.c.a(k, i1, l);
++
++ while (true) {
++ if (blockposition.getY() > 0) {
++ BlockPosition blockposition1 = blockposition.down();
++
++ if (this.a.isEmpty(blockposition1)) {
++ blockposition = blockposition1;
++ continue;
++ }
++ }
++
++ this.y.generate(this.a, this.b, blockposition);
++ ++j;
++ break;
++ }
++ }
++
++ for (j = 0; j < this.E; ++j) {
+ if (this.b.nextInt(4) == 0) {
-+ k = this.c + this.b.nextInt(16) + 8;
-+ l = this.d + this.b.nextInt(16) + 8;
-+ i1 = this.a.getHighestBlockYAt(k, l);
-+ this.q.generate(this.a, this.b, k, i1, l);
++ k = this.b.nextInt(16) + 8;
++ l = this.b.nextInt(16) + 8;
++ BlockPosition blockposition2 = this.a.getHighestBlockYAt(this.c.a(k, 0, l));
++
++ this.t.generate(this.a, this.b, blockposition2);
+ }
+
+ 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);
-+ this.r.generate(this.a, this.b, k, i1, l);
++ k = this.b.nextInt(16) + 8;
++ l = this.b.nextInt(16) + 8;
++ i1 = this.b.nextInt(this.a.getHighestBlockYAt(this.c.a(k, 0, l)).getY() * 2);
++ blockposition = this.c.a(k, i1, l);
++ this.u.generate(this.a, this.b, blockposition);
+ }
+ }
+
+ 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);
-+ this.q.generate(this.a, this.b, j, l, k);
++ j = this.b.nextInt(16) + 8;
++ k = this.b.nextInt(16) + 8;
++ l = this.b.nextInt(this.a.getHighestBlockYAt(this.c.a(j, 0, k)).getY() * 2);
++ this.t.generate(this.a, this.b, this.c.a(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);
-+ this.r.generate(this.a, this.b, j, l, k);
++ j = this.b.nextInt(16) + 8;
++ k = this.b.nextInt(16) + 8;
++ l = this.b.nextInt(this.a.getHighestBlockYAt(this.c.a(j, 0, k)).getY() * 2);
++ this.u.generate(this.a, this.b, this.c.a(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);
-+ this.t.generate(this.a, this.b, k, i1, l);
++ for (j = 0; j < this.F; ++j) {
++ k = this.b.nextInt(16) + 8;
++ l = this.b.nextInt(16) + 8;
++ i1 = this.b.nextInt(this.a.getHighestBlockYAt(this.c.a(k, 0, l)).getY() * 2);
++ this.w.generate(this.a, this.b, this.c.a(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);
-+ this.t.generate(this.a, this.b, k, i1, l);
++ k = this.b.nextInt(16) + 8;
++ l = this.b.nextInt(16) + 8;
++ i1 = this.b.nextInt(this.a.getHighestBlockYAt(this.c.a(k, 0, l)).getY() * 2);
++ this.w.generate(this.a, this.b, this.c.a(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);
-+ (new WorldGenPumpkin()).generate(this.a, this.b, j, l, k);
++ j = this.b.nextInt(16) + 8;
++ k = this.b.nextInt(16) + 8;
++ l = this.b.nextInt(this.a.getHighestBlockYAt(this.c.a(j, 0, k)).getY() * 2);
++ (new WorldGenPumpkin()).generate(this.a, this.b, this.c.a(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);
-+ this.u.generate(this.a, this.b, k, i1, l);
++ for (j = 0; j < this.G; ++j) {
++ k = this.b.nextInt(16) + 8;
++ l = this.b.nextInt(16) + 8;
++ i1 = this.b.nextInt(this.a.getHighestBlockYAt(this.c.a(k, 0, l)).getY() * 2);
++ this.x.generate(this.a, this.b, this.c.a(k, i1, l));
+ }
+
-+ if (this.I) {
++ if (this.L) {
++ BlockPosition blockposition3;
++
+ for (j = 0; j < 50; ++j) {
-+ k = this.c + this.b.nextInt(16) + 8;
-+ l = this.b.nextInt(this.b.nextInt(248) + 8);
-+ i1 = this.d + this.b.nextInt(16) + 8;
-+ (new WorldGenLiquids(Blocks.WATER)).generate(this.a, this.b, k, l, i1);
++ blockposition3 = this.c.a(this.b.nextInt(16) + 8, this.b.nextInt(this.b.nextInt(248) + 8), this.b.nextInt(16) + 8);
++ (new WorldGenLiquids(Blocks.FLOWING_WATER)).generate(this.a, this.b, blockposition3);
+ }
+
+ for (j = 0; j < 20; ++j) {
-+ k = this.c + this.b.nextInt(16) + 8;
-+ l = this.b.nextInt(this.b.nextInt(this.b.nextInt(240) + 8) + 8);
-+ i1 = this.d + this.b.nextInt(16) + 8;
-+ (new WorldGenLiquids(Blocks.LAVA)).generate(this.a, this.b, k, l, i1);
++ blockposition3 = this.c.a(this.b.nextInt(16) + 8, this.b.nextInt(this.b.nextInt(this.b.nextInt(240) + 8) + 8), this.b.nextInt(16) + 8);
++ (new WorldGenLiquids(Blocks.FLOWING_LAVA)).generate(this.a, this.b, blockposition3);
+ }
+ }
++
+ }
+
+ protected void a(int i, WorldGenerator worldgenerator, int j, int k) {
-+ for (int l = 0; l < i; ++l) {
-+ int i1 = this.c + this.b.nextInt(16);
-+ int j1 = this.b.nextInt(k - j) + j;
-+ int k1 = this.d + this.b.nextInt(16);
++ int l;
+
-+ worldgenerator.generate(this.a, this.b, i1, j1, k1);
++ if (k < j) {
++ l = j;
++ j = k;
++ k = l;
++ } else if (k == j) {
++ if (j < 255) {
++ ++k;
++ } else {
++ --j;
++ }
+ }
++
++ for (l = 0; l < i; ++l) {
++ BlockPosition blockposition = this.c.a(this.b.nextInt(16), this.b.nextInt(k - j) + j, this.b.nextInt(16));
++
++ worldgenerator.generate(this.a, this.b, blockposition);
++ }
++
+ }
+
+ protected void b(int i, WorldGenerator worldgenerator, int j, int k) {
+ for (int l = 0; l < i; ++l) {
-+ int i1 = this.c + this.b.nextInt(16);
-+ int j1 = this.b.nextInt(k) + this.b.nextInt(k) + (j - k);
-+ int k1 = this.d + this.b.nextInt(16);
++ BlockPosition blockposition = this.c.a(this.b.nextInt(16), this.b.nextInt(k) + this.b.nextInt(k) + j - k, this.b.nextInt(16));
+
-+ worldgenerator.generate(this.a, this.b, i1, j1, k1);
++ worldgenerator.generate(this.a, this.b, blockposition);
+ }
++
+ }
+
+ protected void a() {
-+ this.a(20, this.h, 0, 256);
-+ this.a(10, this.i, 0, 256);
-+ this.a(20, this.j, 0, 128);
-+ this.a(20, this.k, 0, 64);
-+ this.a(2, this.l, 0, 32);
-+ this.a(8, this.m, 0, 16);
-+ this.a(1, this.n, 0, 16);
-+ this.b(1, this.o, 16, 16);
++ this.a(this.d.J, this.h, this.d.K, this.d.L);
++ this.a(this.d.N, this.i, this.d.O, this.d.P);
++ this.a(this.d.V, this.k, this.d.W, this.d.X);
++ this.a(this.d.R, this.j, this.d.S, this.d.T);
++ this.a(this.d.Z, this.l, this.d.aa, this.d.ab);
++ this.a(this.d.ad, this.m, this.d.ae, this.d.af);
++ this.a(this.d.ah, this.n, this.d.ai, this.d.aj);
++ this.a(this.d.al, this.o, this.d.am, this.d.an);
++ this.a(this.d.ap, this.p, this.d.aq, this.d.ar);
++ this.a(this.d.at, this.q, this.d.au, this.d.av);
++ this.b(this.d.ax, this.r, this.d.ay, this.d.az);
+ }
+}
diff --git a/src/main/java/net/minecraft/server/BlockAnvil.java b/src/main/java/net/minecraft/server/BlockAnvil.java
@@ -441,14 +476,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@
+package net.minecraft.server;
+
++import com.google.common.base.Predicate;
++
+public class BlockAnvil extends BlockFalling {
+
-+ public static final String[] a = new String[] { "intact", "slightlyDamaged", "veryDamaged"};
-+ private static final String[] N = new String[] { "anvil_top_damaged_0", "anvil_top_damaged_1", "anvil_top_damaged_2"};
++ public static final BlockStateDirection FACING = BlockStateDirection.of("facing", (Predicate) EnumDirectionLimit.HORIZONTAL);
++ public static final BlockStateInteger DAMAGE = BlockStateInteger.of("damage", 0, 2);
+
+ protected BlockAnvil() {
+ super(Material.HEAVY);
-+ this.g(0);
++ this.j(this.blockStateList.getBlockData().set(BlockAnvil.FACING, EnumDirection.NORTH).set(BlockAnvil.DAMAGE, Integer.valueOf(0)));
++ this.e(0);
+ this.a(CreativeModeTab.c);
+ }
+
@@ -460,63 +498,59 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return false;
+ }
+
-+ public void postPlace(World world, int i, int j, int k, EntityLiving entityliving, ItemStack itemstack) {
-+ int l = MathHelper.floor((double) (entityliving.yaw * 4.0F / 360.0F) + 0.5D) & 3;
-+ int i1 = world.getData(i, j, k) >> 2;
++ public IBlockData getPlacedState(World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2, int i, EntityLiving entityliving) {
++ EnumDirection enumdirection1 = entityliving.getDirection().e();
+
-+ ++l;
-+ l %= 4;
-+ if (l == 0) {
-+ world.setData(i, j, k, 2 | i1 << 2, 2);
-+ }
-+
-+ if (l == 1) {
-+ world.setData(i, j, k, 3 | i1 << 2, 2);
-+ }
-+
-+ if (l == 2) {
-+ world.setData(i, j, k, 0 | i1 << 2, 2);
-+ }
-+
-+ if (l == 3) {
-+ world.setData(i, j, k, 1 | i1 << 2, 2);
-+ }
++ return super.getPlacedState(world, blockposition, enumdirection, f, f1, f2, i, entityliving).set(BlockAnvil.FACING, enumdirection1).set(BlockAnvil.DAMAGE, Integer.valueOf(i >> 2));
+ }
+
-+ public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
-+ if (world.isStatic) {
-+ return true;
-+ } else {
-+ entityhuman.openAnvil(i, j, k);
-+ return true;
++ public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) {
++ if (!world.isStatic) {
++ entityhuman.openTileEntity(new TileEntityContainerAnvil(world, blockposition));
+ }
++
++ return true;
+ }
+
-+ public int b() {
-+ return 35;
++ public int getDropData(IBlockData iblockdata) {
++ return ((Integer) iblockdata.get(BlockAnvil.DAMAGE)).intValue();
+ }
+
-+ public int getDropData(int i) {
-+ return i >> 2;
-+ }
++ public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) {
++ EnumDirection enumdirection = (EnumDirection) iblockaccess.getType(blockposition).get(BlockAnvil.FACING);
+
-+ public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
-+ int l = iblockaccess.getData(i, j, k) & 3;
-+
-+ if (l != 3 && l != 1) {
-+ this.a(0.125F, 0.0F, 0.0F, 0.875F, 1.0F, 1.0F);
-+ } else {
++ if (enumdirection.k() == EnumAxis.X) {
+ this.a(0.0F, 0.0F, 0.125F, 1.0F, 1.0F, 0.875F);
++ } else {
++ this.a(0.125F, 0.0F, 0.0F, 0.875F, 1.0F, 1.0F);
+ }
++
+ }
+
+ protected void a(EntityFallingBlock entityfallingblock) {
+ entityfallingblock.a(true);
+ }
+
-+ public void a(World world, int i, int j, int k, int l) {
-+ world.triggerEffect(1022, i, j, k, 0);
++ public void a_(World world, BlockPosition blockposition) {
++ world.triggerEffect(1022, blockposition, 0);
+ }
++
++ public IBlockData fromLegacyData(int i) {
++ return this.getBlockData().set(BlockAnvil.FACING, EnumDirection.fromType2(i & 3)).set(BlockAnvil.DAMAGE, Integer.valueOf((i & 15) >> 2));
++ }
++
++ public int toLegacyData(IBlockData iblockdata) {
++ byte b0 = 0;
++ int i = b0 | ((EnumDirection) iblockdata.get(BlockAnvil.FACING)).b();
++
++ i |= ((Integer) iblockdata.get(BlockAnvil.DAMAGE)).intValue() << 2;
++ return i;
++ }
++
++ protected BlockStateList getStateList() {
++ return new BlockStateList(this, new IBlockState[] { BlockAnvil.FACING, BlockAnvil.DAMAGE});
++ }
++
+}
diff --git a/src/main/java/net/minecraft/server/BlockBrewingStand.java b/src/main/java/net/minecraft/server/BlockBrewingStand.java
new file mode 100644
@@ -531,10 +565,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+public class BlockBrewingStand extends BlockContainer {
+
-+ private Random a = new Random();
++ public static final BlockStateBoolean[] HAS_BOTTLE = new BlockStateBoolean[] { BlockStateBoolean.of("has_bottle_0"), BlockStateBoolean.of("has_bottle_1"), BlockStateBoolean.of("has_bottle_2")};
++ private final Random b = new Random();
+
+ public BlockBrewingStand() {
+ super(Material.ORE);
++ this.j(this.blockStateList.getBlockData().set(BlockBrewingStand.HAS_BOTTLE[0], Boolean.valueOf(false)).set(BlockBrewingStand.HAS_BOTTLE[1], Boolean.valueOf(false)).set(BlockBrewingStand.HAS_BOTTLE[2], Boolean.valueOf(false)));
+ }
+
+ public boolean c() {
@@ -542,7 +578,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ public int b() {
-+ return 25;
++ return 3;
+ }
+
+ public TileEntity a(World world, int i) {
@@ -553,75 +589,53 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return false;
+ }
+
-+ public void a(World world, int i, int j, int k, AxisAlignedBB axisalignedbb, List list, Entity entity) {
++ public void a(World world, BlockPosition blockposition, IBlockData iblockdata, AxisAlignedBB axisalignedbb, List list, Entity entity) {
+ this.a(0.4375F, 0.0F, 0.4375F, 0.5625F, 0.875F, 0.5625F);
-+ super.a(world, i, j, k, axisalignedbb, list, entity);
-+ this.g();
-+ super.a(world, i, j, k, axisalignedbb, list, entity);
++ super.a(world, blockposition, iblockdata, axisalignedbb, list, entity);
++ this.h();
++ super.a(world, blockposition, iblockdata, axisalignedbb, list, entity);
+ }
+
-+ public void g() {
++ public void h() {
+ this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F);
+ }
+
-+ public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
++ public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) {
+ if (world.isStatic) {
+ return true;
+ } else {
-+ TileEntityBrewingStand tileentitybrewingstand = (TileEntityBrewingStand) world.getTileEntity(i, j, k);
++ TileEntity tileentity = world.getTileEntity(blockposition);
+
-+ if (tileentitybrewingstand != null) {
-+ entityhuman.openBrewingStand(tileentitybrewingstand);
++ if (tileentity instanceof TileEntityBrewingStand) {
++ entityhuman.openContainer((TileEntityBrewingStand) tileentity);
+ }
+
+ return true;
+ }
+ }
+
-+ public void postPlace(World world, int i, int j, int k, EntityLiving entityliving, ItemStack itemstack) {
++ public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) {
+ if (itemstack.hasName()) {
-+ ((TileEntityBrewingStand) world.getTileEntity(i, j, k)).a(itemstack.getName());
-+ }
-+ }
++ TileEntity tileentity = world.getTileEntity(blockposition);
+
-+ public void remove(World world, int i, int j, int k, Block block, int l) {
-+ TileEntity tileentity = world.getTileEntity(i, j, k);
-+
-+ if (tileentity instanceof TileEntityBrewingStand) {
-+ TileEntityBrewingStand tileentitybrewingstand = (TileEntityBrewingStand) tileentity;
-+
-+ for (int i1 = 0; i1 < tileentitybrewingstand.getSize(); ++i1) {
-+ ItemStack itemstack = tileentitybrewingstand.getItem(i1);
-+
-+ if (itemstack != null) {
-+ float f = this.a.nextFloat() * 0.8F + 0.1F;
-+ float f1 = this.a.nextFloat() * 0.8F + 0.1F;
-+ float f2 = this.a.nextFloat() * 0.8F + 0.1F;
-+
-+ while (itemstack.count > 0) {
-+ int j1 = this.a.nextInt(21) + 10;
-+
-+ if (j1 > itemstack.count) {
-+ j1 = itemstack.count;
-+ }
-+
-+ itemstack.count -= j1;
-+ EntityItem entityitem = new EntityItem(world, (double) ((float) i + f), (double) ((float) j + f1), (double) ((float) k + f2), new ItemStack(itemstack.getItem(), j1, itemstack.getData()));
-+ float f3 = 0.05F;
-+
-+ 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);
-+ }
-+ }
++ if (tileentity instanceof TileEntityBrewingStand) {
++ ((TileEntityBrewingStand) tileentity).a(itemstack.getName());
+ }
+ }
+
-+ super.remove(world, i, j, k, block, l);
+ }
+
-+ public Item getDropType(int i, Random random, int j) {
++ public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) {
++ TileEntity tileentity = world.getTileEntity(blockposition);
++
++ if (tileentity instanceof TileEntityBrewingStand) {
++ InventoryUtils.dropInventory(world, blockposition, (TileEntityBrewingStand) tileentity);
++ }
++
++ super.remove(world, blockposition, iblockdata);
++ }
++
++ public Item getDropType(IBlockData iblockdata, Random random, int i) {
+ return Items.BREWING_STAND;
+ }
+
@@ -629,9 +643,36 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return true;
+ }
+
-+ public int g(World world, int i, int j, int k, int l) {
-+ return Container.b((IInventory) world.getTileEntity(i, j, k));
++ public int l(World world, BlockPosition blockposition) {
++ return Container.a(world.getTileEntity(blockposition));
+ }
++
++ public IBlockData fromLegacyData(int i) {
++ IBlockData iblockdata = this.getBlockData();
++
++ for (int j = 0; j < 3; ++j) {
++ iblockdata = iblockdata.set(BlockBrewingStand.HAS_BOTTLE[j], Boolean.valueOf((i & 1 << j) > 0));
++ }
++
++ return iblockdata;
++ }
++
++ public int toLegacyData(IBlockData iblockdata) {
++ int i = 0;
++
++ for (int j = 0; j < 3; ++j) {
++ if (((Boolean) iblockdata.get(BlockBrewingStand.HAS_BOTTLE[j])).booleanValue()) {
++ i |= 1 << j;
++ }
++ }
++
++ return i;
++ }
++
++ protected BlockStateList getStateList() {
++ return new BlockStateList(this, new IBlockState[] { BlockBrewingStand.HAS_BOTTLE[0], BlockBrewingStand.HAS_BOTTLE[1], BlockBrewingStand.HAS_BOTTLE[2]});
++ }
++
+}
diff --git a/src/main/java/net/minecraft/server/BlockFlowerPot.java b/src/main/java/net/minecraft/server/BlockFlowerPot.java
new file mode 100644
@@ -645,12 +686,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+public class BlockFlowerPot extends BlockContainer {
+
++ public static final BlockStateInteger LEGACY_DATA = BlockStateInteger.of("legacy_data", 0, 15);
++ public static final BlockStateEnum CONTENTS = BlockStateEnum.of("contents", EnumFlowerPotContents.class);
++
+ public BlockFlowerPot() {
+ super(Material.ORIENTABLE);
-+ this.g();
++ this.j(this.blockStateList.getBlockData().set(BlockFlowerPot.CONTENTS, EnumFlowerPotContents.EMPTY).set(BlockFlowerPot.LEGACY_DATA, Integer.valueOf(0)));
++ this.h();
+ }
+
-+ public void g() {
++ public void h() {
+ float f = 0.375F;
+ float f1 = f / 2.0F;
+
@@ -662,43 +707,38 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ public int b() {
-+ return 33;
++ return 3;
+ }
+
+ public boolean d() {
+ return false;
+ }
+
-+ public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
++ public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) {
+ ItemStack itemstack = entityhuman.inventory.getItemInHand();
+
+ if (itemstack != null && itemstack.getItem() instanceof ItemBlock) {
-+ TileEntityFlowerPot tileentityflowerpot = this.e(world, i, j, k);
++ TileEntityFlowerPot tileentityflowerpot = this.d(world, blockposition);
+
-+ if (tileentityflowerpot != null) {
-+ if (tileentityflowerpot.a() != null) {
++ if (tileentityflowerpot == null) {
++ return false;
++ } else if (tileentityflowerpot.b() != null) {
++ return false;
++ } else {
++ Block block = Block.asBlock(itemstack.getItem());
++
++ if (!this.a(block, itemstack.getData())) {
+ return false;
+ } else {
-+ Block block = Block.a(itemstack.getItem());
-+
-+ if (!this.a(block, itemstack.getData())) {
-+ return false;
-+ } else {
-+ tileentityflowerpot.a(itemstack.getItem(), itemstack.getData());
-+ tileentityflowerpot.update();
-+ if (!world.setData(i, j, k, itemstack.getData(), 2)) {
-+ world.notify(i, j, k);
-+ }
-+
-+ if (!entityhuman.abilities.canInstantlyBuild && --itemstack.count <= 0) {
-+ entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, (ItemStack) null);
-+ }
-+
-+ return true;
++ tileentityflowerpot.a(itemstack.getItem(), itemstack.getData());
++ tileentityflowerpot.update();
++ world.notify(blockposition);
++ if (!entityhuman.abilities.canInstantlyBuild && --itemstack.count <= 0) {
++ entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, (ItemStack) null);
+ }
++
++ return true;
+ }
-+ } else {
-+ return false;
+ }
+ } else {
+ return false;
@@ -706,65 +746,67 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ private boolean a(Block block, int i) {
-+ return block != Blocks.YELLOW_FLOWER && block != Blocks.RED_ROSE && block != Blocks.CACTUS && block != Blocks.BROWN_MUSHROOM && block != Blocks.RED_MUSHROOM && block != Blocks.SAPLING && block != Blocks.DEAD_BUSH ? block == Blocks.LONG_GRASS && i == 2 : true;
++ return block != Blocks.YELLOW_FLOWER && block != Blocks.RED_FLOWER && block != Blocks.CACTUS && block != Blocks.BROWN_MUSHROOM && block != Blocks.RED_MUSHROOM && block != Blocks.SAPLING && block != Blocks.DEADBUSH ? block == Blocks.TALLGRASS && i == EnumTallGrassType.FERN.a() : true;
+ }
+
-+ public int getDropData(World world, int i, int j, int k) {
-+ TileEntityFlowerPot tileentityflowerpot = this.e(world, i, j, k);
++ public int getDropData(World world, BlockPosition blockposition) {
++ TileEntityFlowerPot tileentityflowerpot = this.d(world, blockposition);
+
-+ return tileentityflowerpot != null && tileentityflowerpot.a() != null ? tileentityflowerpot.b() : 0;
++ return tileentityflowerpot != null && tileentityflowerpot.b() != null ? tileentityflowerpot.c() : 0;
+ }
+
-+ public boolean canPlace(World world, int i, int j, int k) {
-+ return super.canPlace(world, i, j, k) && World.a((IBlockAccess) world, i, j - 1, k);
++ public boolean canPlace(World world, BlockPosition blockposition) {
++ return super.canPlace(world, blockposition) && World.a((IBlockAccess) world, blockposition.down());
+ }
+
-+ public void doPhysics(World world, int i, int j, int k, Block block) {
-+ if (!World.a((IBlockAccess) world, i, j - 1, k)) {
-+ this.b(world, i, j, k, world.getData(i, j, k), 0);
-+ world.setAir(i, j, k);
-+ }
-+ }
-+
-+ public void remove(World world, int i, int j, int k, Block block, int l) {
-+ TileEntityFlowerPot tileentityflowerpot = this.e(world, i, j, k);
-+
-+ if (tileentityflowerpot != null && tileentityflowerpot.a() != null) {
-+ this.a(world, i, j, k, new ItemStack(tileentityflowerpot.a(), 1, tileentityflowerpot.b()));
++ public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) {
++ if (!World.a((IBlockAccess) world, blockposition.down())) {
++ this.b(world, blockposition, iblockdata, 0);
++ world.setAir(blockposition);
+ }
+
-+ super.remove(world, i, j, k, block, l);
+ }
+
-+ public void a(World world, int i, int j, int k, int l, EntityHuman entityhuman) {
-+ super.a(world, i, j, k, l, entityhuman);
++ public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) {
++ TileEntityFlowerPot tileentityflowerpot = this.d(world, blockposition);
++
++ if (tileentityflowerpot != null && tileentityflowerpot.b() != null) {
++ a(world, blockposition, new ItemStack(tileentityflowerpot.b(), 1, tileentityflowerpot.c()));
++ }
++
++ super.remove(world, blockposition, iblockdata);
++ }
++
++ public void a(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman) {
++ super.a(world, blockposition, iblockdata, entityhuman);
+ if (entityhuman.abilities.canInstantlyBuild) {
-+ TileEntityFlowerPot tileentityflowerpot = this.e(world, i, j, k);
++ TileEntityFlowerPot tileentityflowerpot = this.d(world, blockposition);
+
+ if (tileentityflowerpot != null) {
-+ tileentityflowerpot.a(Item.getById(0), 0);
++ tileentityflowerpot.a((Item) null, 0);
+ }
+ }
++
+ }
+
-+ public Item getDropType(int i, Random random, int j) {
++ public Item getDropType(IBlockData iblockdata, Random random, int i) {
+ return Items.FLOWER_POT;
+ }
+
-+ private TileEntityFlowerPot e(World world, int i, int j, int k) {
-+ TileEntity tileentity = world.getTileEntity(i, j, k);
++ private TileEntityFlowerPot d(World world, BlockPosition blockposition) {
++ TileEntity tileentity = world.getTileEntity(blockposition);
+
-+ return tileentity != null && tileentity instanceof TileEntityFlowerPot ? (TileEntityFlowerPot) tileentity : null;
++ return tileentity instanceof TileEntityFlowerPot ? (TileEntityFlowerPot) tileentity : null;
+ }
+
+ public TileEntity a(World world, int i) {
+ Object object = null;
-+ byte b0 = 0;
++ int j = 0;
+
+ switch (i) {
+ case 1:
-+ object = Blocks.RED_ROSE;
-+ b0 = 0;
++ object = Blocks.RED_FLOWER;
++ j = EnumFlowerVarient.POPPY.b();
+ break;
+
+ case 2:
@@ -773,22 +815,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ case 3:
+ object = Blocks.SAPLING;
-+ b0 = 0;
++ j = EnumLogVariant.OAK.a();
+ break;
+
+ case 4:
+ object = Blocks.SAPLING;
-+ b0 = 1;
++ j = EnumLogVariant.SPRUCE.a();
+ break;
+
+ case 5:
+ object = Blocks.SAPLING;
-+ b0 = 2;
++ j = EnumLogVariant.BIRCH.a();
+ break;
+
+ case 6:
+ object = Blocks.SAPLING;
-+ b0 = 3;
++ j = EnumLogVariant.JUNGLE.a();
+ break;
+
+ case 7:
@@ -804,25 +846,304 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ break;
+
+ case 10:
-+ object = Blocks.DEAD_BUSH;
++ object = Blocks.DEADBUSH;
+ break;
+
+ case 11:
-+ object = Blocks.LONG_GRASS;
-+ b0 = 2;
++ object = Blocks.TALLGRASS;
++ j = EnumTallGrassType.FERN.a();
+ break;
+
+ case 12:
+ object = Blocks.SAPLING;
-+ b0 = 4;
++ j = EnumLogVariant.ACACIA.a();
+ break;
+
+ case 13:
+ object = Blocks.SAPLING;
-+ b0 = 5;
++ j = EnumLogVariant.DARK_OAK.a();
+ }
+
-+ return new TileEntityFlowerPot(Item.getItemOf((Block) object), b0);
++ return new TileEntityFlowerPot(Item.getItemOf((Block) object), j);
++ }
++
++ protected BlockStateList getStateList() {
++ return new BlockStateList(this, new IBlockState[] { BlockFlowerPot.CONTENTS, BlockFlowerPot.LEGACY_DATA});
++ }
++
++ public int toLegacyData(IBlockData iblockdata) {
++ return ((Integer) iblockdata.get(BlockFlowerPot.LEGACY_DATA)).intValue();
++ }
++
++ public IBlockData updateState(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) {
++ EnumFlowerPotContents enumflowerpotcontents = EnumFlowerPotContents.EMPTY;
++ TileEntity tileentity = iblockaccess.getTileEntity(blockposition);
++
++ if (tileentity instanceof TileEntityFlowerPot) {
++ TileEntityFlowerPot tileentityflowerpot = (TileEntityFlowerPot) tileentity;
++ Item item = tileentityflowerpot.b();
++
++ if (item instanceof ItemBlock) {
++ int i = tileentityflowerpot.c();
++ Block block = Block.asBlock(item);
++
++ if (block == Blocks.SAPLING) {
++ switch (SwitchHelperBlockFlowerPot.a[EnumLogVariant.a(i).ordinal()]) {
++ case 1:
++ enumflowerpotcontents = EnumFlowerPotContents.OAK_SAPLING;
++ break;
++
++ case 2:
++ enumflowerpotcontents = EnumFlowerPotContents.SPRUCE_SAPLING;
++ break;
++
++ case 3:
++ enumflowerpotcontents = EnumFlowerPotContents.BIRCH_SAPLING;
++ break;
++
++ case 4:
++ enumflowerpotcontents = EnumFlowerPotContents.JUNGLE_SAPLING;
++ break;
++
++ case 5:
++ enumflowerpotcontents = EnumFlowerPotContents.ACACIA_SAPLING;
++ break;
++
++ case 6:
++ enumflowerpotcontents = EnumFlowerPotContents.DARK_OAK_SAPLING;
++ break;
++
++ default:
++ enumflowerpotcontents = EnumFlowerPotContents.EMPTY;
++ }
++ } else if (block == Blocks.TALLGRASS) {
++ switch (i) {
++ case 0:
++ enumflowerpotcontents = EnumFlowerPotContents.DEAD_BUSH;
++ break;
++
++ case 2:
++ enumflowerpotcontents = EnumFlowerPotContents.FERN;
++ break;
++
++ default:
++ enumflowerpotcontents = EnumFlowerPotContents.EMPTY;
++ }
++ } else if (block == Blocks.YELLOW_FLOWER) {
++ enumflowerpotcontents = EnumFlowerPotContents.DANDELION;
++ } else if (block == Blocks.RED_FLOWER) {
++ switch (SwitchHelperBlockFlowerPot.b[EnumFlowerVarient.a(EnumFlowerType.RED, i).ordinal()]) {
++ case 1:
++ enumflowerpotcontents = EnumFlowerPotContents.POPPY;
++ break;
++
++ case 2:
++ enumflowerpotcontents = EnumFlowerPotContents.BLUE_ORCHID;
++ break;
++
++ case 3:
++ enumflowerpotcontents = EnumFlowerPotContents.ALLIUM;
++ break;
++
++ case 4:
++ enumflowerpotcontents = EnumFlowerPotContents.HOUSTONIA;
++ break;
++
++ case 5:
++ enumflowerpotcontents = EnumFlowerPotContents.RED_TULIP;
++ break;
++
++ case 6:
++ enumflowerpotcontents = EnumFlowerPotContents.ORANGE_TULIP;
++ break;
++
++ case 7:
++ enumflowerpotcontents = EnumFlowerPotContents.WHITE_TULIP;
++ break;
++
++ case 8:
++ enumflowerpotcontents = EnumFlowerPotContents.PINK_TULIP;
++ break;
++
++ case 9:
++ enumflowerpotcontents = EnumFlowerPotContents.OXEYE_DAISY;
++ break;
++
++ default:
++ enumflowerpotcontents = EnumFlowerPotContents.EMPTY;
++ }
++ } else if (block == Blocks.RED_MUSHROOM) {
++ enumflowerpotcontents = EnumFlowerPotContents.MUSHROOM_RED;
++ } else if (block == Blocks.BROWN_MUSHROOM) {
++ enumflowerpotcontents = EnumFlowerPotContents.MUSHROOM_BROWN;
++ } else if (block == Blocks.DEADBUSH) {
++ enumflowerpotcontents = EnumFlowerPotContents.DEAD_BUSH;
++ } else if (block == Blocks.CACTUS) {
++ enumflowerpotcontents = EnumFlowerPotContents.CACTUS;
++ }
++ }
++ }
++
++ return iblockdata.set(BlockFlowerPot.CONTENTS, enumflowerpotcontents);
++ }
++
++}
+diff --git a/src/main/java/net/minecraft/server/BlockHopper.java b/src/main/java/net/minecraft/server/BlockHopper.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/net/minecraft/server/BlockHopper.java
+@@ -0,0 +0,0 @@
++package net.minecraft.server;
++
++import com.google.common.base.Predicate;
++import java.util.List;
++
++public class BlockHopper extends BlockContainer {
++
++ public static final BlockStateDirection FACING = BlockStateDirection.of("facing", (Predicate) (new BlockHopperInnerClass1()));
++ public static final BlockStateBoolean ENABLED = BlockStateBoolean.of("enabled");
++
++ public BlockHopper() {
++ super(Material.ORE);
++ this.j(this.blockStateList.getBlockData().set(BlockHopper.FACING, EnumDirection.DOWN).set(BlockHopper.ENABLED, Boolean.valueOf(true)));
++ this.a(CreativeModeTab.d);
++ this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
++ }
++
++ public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) {
++ this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
++ }
++
++ public void a(World world, BlockPosition blockposition, IBlockData iblockdata, AxisAlignedBB axisalignedbb, List list, Entity entity) {
++ this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.625F, 1.0F);
++ super.a(world, blockposition, iblockdata, axisalignedbb, list, entity);
++ float f = 0.125F;
++
++ this.a(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F);
++ super.a(world, blockposition, iblockdata, axisalignedbb, list, entity);
++ this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f);
++ super.a(world, blockposition, iblockdata, axisalignedbb, list, entity);
++ this.a(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
++ super.a(world, blockposition, iblockdata, axisalignedbb, list, entity);
++ this.a(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F);
++ super.a(world, blockposition, iblockdata, axisalignedbb, list, entity);
++ this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
++ }
++
++ public IBlockData getPlacedState(World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2, int i, EntityLiving entityliving) {
++ EnumDirection enumdirection1 = enumdirection.opposite();
++
++ if (enumdirection1 == EnumDirection.UP) {
++ enumdirection1 = EnumDirection.DOWN;
++ }
++
++ return this.getBlockData().set(BlockHopper.FACING, enumdirection1).set(BlockHopper.ENABLED, Boolean.valueOf(true));
++ }
++
++ public TileEntity a(World world, int i) {
++ return new TileEntityHopper();
++ }
++
++ public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) {
++ super.postPlace(world, blockposition, iblockdata, entityliving, itemstack);
++ if (itemstack.hasName()) {
++ TileEntity tileentity = world.getTileEntity(blockposition);
++
++ if (tileentity instanceof TileEntityHopper) {
++ ((TileEntityHopper) tileentity).a(itemstack.getName());
++ }
++ }
++
++ }
++
++ public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) {
++ this.e(world, blockposition, iblockdata);
++ }
++
++ public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) {
++ if (world.isStatic) {
++ return true;
++ } else {
++ TileEntity tileentity = world.getTileEntity(blockposition);
++
++ if (tileentity instanceof TileEntityHopper) {
++ entityhuman.openContainer((TileEntityHopper) tileentity);
++ }
++
++ return true;
++ }
++ }
++
++ public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) {
++ this.e(world, blockposition, iblockdata);
++ }
++
++ private void e(World world, BlockPosition blockposition, IBlockData iblockdata) {
++ boolean flag = !world.isBlockIndirectlyPowered(blockposition);
++
++ if (flag != ((Boolean) iblockdata.get(BlockHopper.ENABLED)).booleanValue()) {
++ world.setTypeAndData(blockposition, iblockdata.set(BlockHopper.ENABLED, Boolean.valueOf(flag)), 4);
++ }
++
++ }
++
++ public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) {
++ TileEntity tileentity = world.getTileEntity(blockposition);
++
++ if (tileentity instanceof TileEntityHopper) {
++ InventoryUtils.dropInventory(world, blockposition, (TileEntityHopper) tileentity);
++ world.updateAdjacentComparators(blockposition, this);
++ }
++
++ super.remove(world, blockposition, iblockdata);
++ }
++
++ public int b() {
++ return 3;
++ }
++
++ public boolean d() {
++ return false;
++ }
++
++ public boolean c() {
++ return false;
++ }
++
++ public static EnumDirection b(int i) {
++ return EnumDirection.fromType1(i & 7);
++ }
++
++ public static boolean f(int i) {
++ return (i & 8) != 8;
++ }
++
++ public boolean isComplexRedstone() {
++ return true;
++ }
++
++ public int l(World world, BlockPosition blockposition) {
++ return Container.a(world.getTileEntity(blockposition));
++ }
++
++ public IBlockData fromLegacyData(int i) {
++ return this.getBlockData().set(BlockHopper.FACING, b(i)).set(BlockHopper.ENABLED, Boolean.valueOf(f(i)));
++ }
++
++ public int toLegacyData(IBlockData iblockdata) {
++ byte b0 = 0;
++ int i = b0 | ((EnumDirection) iblockdata.get(BlockHopper.FACING)).a();
++
++ if (!((Boolean) iblockdata.get(BlockHopper.ENABLED)).booleanValue()) {
++ i |= 8;
++ }
++
++ return i;
++ }
++
++ protected BlockStateList getStateList() {
++ return new BlockStateList(this, new IBlockState[] { BlockHopper.FACING, BlockHopper.ENABLED});
+ }
+}
diff --git a/src/main/java/net/minecraft/server/BlockTNT.java b/src/main/java/net/minecraft/server/BlockTNT.java
@@ -833,83 +1154,106 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@
+package net.minecraft.server;
+
-+import java.util.Random;
-+
+public class BlockTNT extends Block {
+
++ public static final BlockStateBoolean EXPLODE = BlockStateBoolean.of("explode");
++
+ public BlockTNT() {
+ super(Material.TNT);
++ this.j(this.blockStateList.getBlockData().set(BlockTNT.EXPLODE, Boolean.valueOf(false)));
+ this.a(CreativeModeTab.d);
+ }
+
-+ public void onPlace(World world, int i, int j, int k) {
-+ super.onPlace(world, i, j, k);
-+ if (world.isBlockIndirectlyPowered(i, j, k)) {
-+ this.postBreak(world, i, j, k, 1);
-+ world.setAir(i, j, k);
++ public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) {
++ super.onPlace(world, blockposition, iblockdata);
++ if (world.isBlockIndirectlyPowered(blockposition)) {
++ this.postBreak(world, blockposition, iblockdata.set(BlockTNT.EXPLODE, Boolean.valueOf(true)));
++ world.setAir(blockposition);
+ }
++
+ }
+
-+ public void doPhysics(World world, int i, int j, int k, Block block) {
-+ if (world.isBlockIndirectlyPowered(i, j, k)) {
-+ this.postBreak(world, i, j, k, 1);
-+ world.setAir(i, j, k);
++ public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) {
++ if (world.isBlockIndirectlyPowered(blockposition)) {
++ this.postBreak(world, blockposition, iblockdata.set(BlockTNT.EXPLODE, Boolean.valueOf(true)));
++ world.setAir(blockposition);
+ }
++
+ }
+
-+ public int a(Random random) {
-+ return 1;
-+ }
-+
-+ public void wasExploded(World world, int i, int j, int k, Explosion explosion) {
++ public void wasExploded(World world, BlockPosition blockposition, Explosion explosion) {
+ if (!world.isStatic) {
-+ EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F), explosion.c());
++ EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) ((float) blockposition.getX() + 0.5F), (double) ((float) blockposition.getY() + 0.5F), (double) ((float) blockposition.getZ() + 0.5F), explosion.c());
+
+ entitytntprimed.fuseTicks = world.random.nextInt(entitytntprimed.fuseTicks / 4) + entitytntprimed.fuseTicks / 8;
+ world.addEntity(entitytntprimed);
+ }
+ }
+
-+ public void postBreak(World world, int i, int j, int k, int l) {
-+ this.a(world, i, j, k, l, (EntityLiving) null);
++ public void postBreak(World world, BlockPosition blockposition, IBlockData iblockdata) {
++ this.a(world, blockposition, iblockdata, (EntityLiving) null);
+ }
+
-+ public void a(World world, int i, int j, int k, int l, EntityLiving entityliving) {
++ public void a(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving) {
+ if (!world.isStatic) {
-+ if ((l & 1) == 1) {
-+ EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F), entityliving);
++ if (((Boolean) iblockdata.get(BlockTNT.EXPLODE)).booleanValue()) {
++ EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) ((float) blockposition.getX() + 0.5F), (double) ((float) blockposition.getY() + 0.5F), (double) ((float) blockposition.getZ() + 0.5F), entityliving);
+
+ world.addEntity(entitytntprimed);
+ world.makeSound(entitytntprimed, "game.tnt.primed", 1.0F, 1.0F);
+ }
++
+ }
+ }
+
-+ public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
-+ if (entityhuman.bF() != null && entityhuman.bF().getItem() == Items.FLINT_AND_STEEL) {
-+ this.a(world, i, j, k, 1, entityhuman);
-+ world.setAir(i, j, k);
-+ entityhuman.bF().damage(1, entityhuman);
-+ return true;
-+ } else {
-+ return super.interact(world, i, j, k, entityhuman, l, f, f1, f2);
++ public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) {
++ if (entityhuman.bY() != null) {
++ Item item = entityhuman.bY().getItem();
++
++ if (item == Items.FLINT_AND_STEEL || item == Items.FIRE_CHARGE) {
++ this.a(world, blockposition, iblockdata.set(BlockTNT.EXPLODE, Boolean.valueOf(true)), (EntityLiving) entityhuman);
++ world.setAir(blockposition);
++ if (item == Items.FLINT_AND_STEEL) {
++ entityhuman.bY().damage(1, entityhuman);
++ } else if (!entityhuman.abilities.canInstantlyBuild) {
++ --entityhuman.bY().count;
++ }
++
++ return true;
++ }
+ }
++
++ return super.interact(world, blockposition, iblockdata, entityhuman, enumdirection, f, f1, f2);
+ }
+
-+ public void a(World world, int i, int j, int k, Entity entity) {
-+ if (entity instanceof EntityArrow && !world.isStatic) {
++ public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Entity entity) {
++ if (!world.isStatic && entity instanceof EntityArrow) {
+ EntityArrow entityarrow = (EntityArrow) entity;
+
+ if (entityarrow.isBurning()) {
-+ this.a(world, i, j, k, 1, entityarrow.shooter instanceof EntityLiving ? (EntityLiving) entityarrow.shooter : null);
-+ world.setAir(i, j, k);
++ this.a(world, blockposition, world.getType(blockposition).set(BlockTNT.EXPLODE, Boolean.valueOf(true)), entityarrow.shooter instanceof EntityLiving ? (EntityLiving) entityarrow.shooter : null);
++ world.setAir(blockposition);
+ }
+ }
++
+ }
+
+ public boolean a(Explosion explosion) {
+ return false;
+ }
++
++ public IBlockData fromLegacyData(int i) {
++ return this.getBlockData().set(BlockTNT.EXPLODE, Boolean.valueOf((i & 1) > 0));
++ }
++
++ public int toLegacyData(IBlockData iblockdata) {
++ return ((Boolean) iblockdata.get(BlockTNT.EXPLODE)).booleanValue() ? 1 : 0;
++ }
++
++ protected BlockStateList getStateList() {
++ return new BlockStateList(this, new IBlockState[] { BlockTNT.EXPLODE});
++ }
++
+}
diff --git a/src/main/java/net/minecraft/server/CommandDispatcher.java b/src/main/java/net/minecraft/server/CommandDispatcher.java
new file mode 100644
@@ -924,56 +1268,67 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+public class CommandDispatcher extends CommandHandler implements ICommandDispatcher {
+
+ public CommandDispatcher() {
-+ this.a(new CommandTime());
-+ this.a(new CommandGamemode());
-+ this.a(new CommandDifficulty());
-+ this.a(new CommandGamemodeDefault());
-+ this.a(new CommandKill());
-+ this.a(new CommandToggleDownfall());
-+ this.a(new CommandWeather());
-+ this.a(new CommandXp());
-+ this.a(new CommandTp());
-+ this.a(new CommandGive());
-+ this.a(new CommandEffect());
-+ this.a(new CommandEnchant());
-+ this.a(new CommandMe());
-+ this.a(new CommandSeed());
-+ this.a(new CommandHelp());
-+ this.a(new CommandDebug());
-+ this.a(new CommandTell());
-+ this.a(new CommandSay());
-+ this.a(new CommandSpawnpoint());
-+ this.a(new CommandSetWorldSpawn());
-+ this.a(new CommandGamerule());
-+ this.a(new CommandClear());
-+ this.a(new CommandTestFor());
-+ this.a(new CommandSpreadPlayers());
-+ this.a(new CommandPlaySound());
-+ this.a(new CommandScoreboard());
-+ this.a(new CommandAchievement());
-+ this.a(new CommandSummon());
-+ this.a(new CommandSetBlock());
-+ this.a(new CommandTestForBlock());
-+ this.a(new CommandTellRaw());
-+ if (MinecraftServer.getServer().X()) {
-+ this.a(new CommandOp());
-+ this.a(new CommandDeop());
-+ this.a(new CommandStop());
-+ this.a(new CommandSaveAll());
-+ this.a(new CommandSaveOff());
-+ this.a(new CommandSaveOn());
-+ this.a(new CommandBanIp());
-+ this.a(new CommandPardonIP());
-+ this.a(new CommandBan());
-+ this.a(new CommandBanList());
-+ this.a(new CommandPardon());
-+ this.a(new CommandKick());
-+ this.a(new CommandList());
-+ this.a(new CommandWhitelist());
-+ this.a(new CommandIdleTimeout());
-+ this.a(new CommandNetstat());
++ this.a((ICommand) (new CommandTime()));
++ this.a((ICommand) (new CommandGamemode()));
++ this.a((ICommand) (new CommandDifficulty()));
++ this.a((ICommand) (new CommandGamemodeDefault()));
++ this.a((ICommand) (new CommandKill()));
++ this.a((ICommand) (new CommandToggleDownfall()));
++ this.a((ICommand) (new CommandWeather()));
++ this.a((ICommand) (new CommandXp()));
++ this.a((ICommand) (new CommandTp()));
++ this.a((ICommand) (new CommandGive()));
++ this.a((ICommand) (new CommandReplaceItem()));
++ this.a((ICommand) (new CommandStats()));
++ this.a((ICommand) (new CommandEffect()));
++ this.a((ICommand) (new CommandEnchant()));
++ this.a((ICommand) (new CommandParticle()));
++ this.a((ICommand) (new CommandMe()));
++ this.a((ICommand) (new CommandSeed()));
++ this.a((ICommand) (new CommandHelp()));
++ this.a((ICommand) (new CommandDebug()));
++ this.a((ICommand) (new CommandTell()));
++ this.a((ICommand) (new CommandSay()));
++ this.a((ICommand) (new CommandSpawnpoint()));
++ this.a((ICommand) (new CommandSetWorldSpawn()));
++ this.a((ICommand) (new CommandGamerule()));
++ this.a((ICommand) (new CommandClear()));
++ this.a((ICommand) (new CommandTestFor()));
++ this.a((ICommand) (new CommandSpreadPlayers()));
++ this.a((ICommand) (new CommandPlaySound()));
++ this.a((ICommand) (new CommandScoreboard()));
++ this.a((ICommand) (new CommandExecute()));
++ this.a((ICommand) (new CommandTrigger()));
++ this.a((ICommand) (new CommandAchievement()));
++ this.a((ICommand) (new CommandSummon()));
++ this.a((ICommand) (new CommandSetBlock()));
++ this.a((ICommand) (new CommandFill()));
++ this.a((ICommand) (new CommandClone()));
++ this.a((ICommand) (new CommandTestForBlocks()));
++ this.a((ICommand) (new CommandBlockData()));
++ this.a((ICommand) (new CommandTestForBlock()));
++ this.a((ICommand) (new CommandTellRaw()));
++ this.a((ICommand) (new CommandWorldBorder()));
++ this.a((ICommand) (new CommandTitle()));
++ this.a((ICommand) (new CommandEntityData()));
++ if (MinecraftServer.getServer().ad()) {
++ this.a((ICommand) (new CommandOp()));
++ this.a((ICommand) (new CommandDeop()));
++ this.a((ICommand) (new CommandStop()));
++ this.a((ICommand) (new CommandSaveAll()));
++ this.a((ICommand) (new CommandSaveOff()));
++ this.a((ICommand) (new CommandSaveOn()));
++ this.a((ICommand) (new CommandBanIp()));
++ this.a((ICommand) (new CommandPardonIP()));
++ this.a((ICommand) (new CommandBan()));
++ this.a((ICommand) (new CommandBanList()));
++ this.a((ICommand) (new CommandPardon()));
++ this.a((ICommand) (new CommandKick()));
++ this.a((ICommand) (new CommandList()));
++ this.a((ICommand) (new CommandWhitelist()));
++ this.a((ICommand) (new CommandIdleTimeout()));
+ } else {
-+ this.a(new CommandPublish());
++ this.a((ICommand) (new CommandPublish()));
+ }
+
+ CommandAbstract.a((ICommandDispatcher) this);
@@ -981,8 +1336,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ public void a(ICommandListener icommandlistener, ICommand icommand, int i, String s, Object... aobject) {
+ boolean flag = true;
++ MinecraftServer minecraftserver = MinecraftServer.getServer();
+
-+ if (icommandlistener instanceof CommandBlockListenerAbstract && !MinecraftServer.getServer().worldServer[0].getGameRules().getBoolean("commandBlockOutput")) {
++ if (!icommandlistener.getSendCommandFeedback()) {
+ flag = false;
+ }
+
@@ -991,24 +1347,31 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ chatmessage.getChatModifier().setColor(EnumChatFormat.GRAY);
+ chatmessage.getChatModifier().setItalic(Boolean.valueOf(true));
+ if (flag) {
-+ Iterator iterator = MinecraftServer.getServer().getPlayerList().players.iterator();
++ Iterator iterator = minecraftserver.getPlayerList().players.iterator();
+
+ while (iterator.hasNext()) {
+ EntityHuman entityhuman = (EntityHuman) iterator.next();
+
-+ if (entityhuman != icommandlistener && MinecraftServer.getServer().getPlayerList().isOp(entityhuman.getProfile()) && icommand.canUse(entityhuman) && (!(icommandlistener instanceof RemoteControlCommandListener) || MinecraftServer.getServer().m())) {
++ if (entityhuman != icommandlistener && minecraftserver.getPlayerList().isOp(entityhuman.getProfile()) && icommand.canUse(icommandlistener)) {
+ entityhuman.sendMessage(chatmessage);
+ }
+ }
+ }
+
-+ if (icommandlistener != MinecraftServer.getServer()) {
-+ MinecraftServer.getServer().sendMessage(chatmessage);
++ if (icommandlistener != minecraftserver && minecraftserver.worldServer[0].getGameRules().getBoolean("logAdminCommands")) {
++ minecraftserver.sendMessage(chatmessage);
+ }
+
-+ if ((i & 1) != 1) {
++ boolean flag1 = minecraftserver.worldServer[0].getGameRules().getBoolean("sendCommandFeedback");
++
++ if (icommandlistener instanceof CommandBlockListenerAbstract) {
++ flag1 = ((CommandBlockListenerAbstract) icommandlistener).m();
++ }
++
++ if ((i & 1) != 1 && flag1) {
+ icommandlistener.sendMessage(new ChatMessage(s, aobject));
+ }
++
+ }
+}
diff --git a/src/main/java/net/minecraft/server/DataWatcher.java b/src/main/java/net/minecraft/server/DataWatcher.java
@@ -1019,22 +1382,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@
+package net.minecraft.server;
+
++import com.google.common.collect.Lists;
++import com.google.common.collect.Maps;
+import java.util.ArrayList;
-+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
-+
-+import net.minecraft.util.org.apache.commons.lang3.ObjectUtils;
++import org.apache.commons.lang3.ObjectUtils;
+
+public class DataWatcher {
+
+ private final Entity a;
+ private boolean b = true;
-+ private static final HashMap c = new HashMap();
-+ private final Map d = new HashMap();
++ private static final Map c = Maps.newHashMap();
++ private final Map d = Maps.newHashMap();
+ private boolean e;
+ private ReadWriteLock f = new ReentrantReadWriteLock();
+
@@ -1043,7 +1406,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ public void a(int i, Object object) {
-+ Integer integer = (Integer) c.get(object.getClass());
++ Integer integer = (Integer) DataWatcher.c.get(object.getClass());
+
+ if (integer == null) {
+ throw new IllegalArgumentException("Unknown data type: " + object.getClass());
@@ -1062,7 +1425,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ public void add(int i, int j) {
-+ WatchableObject watchableobject = new WatchableObject(j, i, null);
++ WatchableObject watchableobject = new WatchableObject(j, i, (Object) null);
+
+ this.f.writeLock().lock();
+ this.d.put(Integer.valueOf(i), watchableobject);
@@ -1071,30 +1434,30 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ public byte getByte(int i) {
-+ return ((Byte) this.i(i).b()).byteValue();
++ return ((Byte) this.j(i).b()).byteValue();
+ }
+
+ public short getShort(int i) {
-+ return ((Short) this.i(i).b()).shortValue();
++ return ((Short) this.j(i).b()).shortValue();
+ }
+
+ public int getInt(int i) {
-+ return ((Integer) this.i(i).b()).intValue();
++ return ((Integer) this.j(i).b()).intValue();
+ }
+
+ public float getFloat(int i) {
-+ return ((Float) this.i(i).b()).floatValue();
++ return ((Float) this.j(i).b()).floatValue();
+ }
+
+ public String getString(int i) {
-+ return (String) this.i(i).b();
++ return (String) this.j(i).b();
+ }
+
+ public ItemStack getItemStack(int i) {
-+ return (ItemStack) this.i(i).b();
++ return (ItemStack) this.j(i).b();
+ }
+
-+ private WatchableObject i(int i) {
++ private WatchableObject j(int i) {
+ this.f.readLock().lock();
+
+ WatchableObject watchableobject;
@@ -1105,7 +1468,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ CrashReport crashreport = CrashReport.a(throwable, "Getting synched entity data");
+ CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Synched entity data");
+
-+ crashreportsystemdetails.a("Data ID", Integer.valueOf(i));
++ crashreportsystemdetails.a("Data ID", (Object) Integer.valueOf(i));
+ throw new ReportedException(crashreport);
+ }
+
@@ -1113,8 +1476,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return watchableobject;
+ }
+
++ public Vector3f h(int i) {
++ return (Vector3f) this.j(i).b();
++ }
++
+ public void watch(int i, Object object) {
-+ WatchableObject watchableobject = this.i(i);
++ WatchableObject watchableobject = this.j(i);
+
+ if (ObjectUtils.notEqual(object, watchableobject.b())) {
+ watchableobject.a(object);
@@ -1122,10 +1489,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ watchableobject.a(true);
+ this.e = true;
+ }
++
+ }
+
+ public void update(int i) {
-+ WatchableObject.a(this.i(i), true);
++ WatchableObject.a(this.j(i), true);
+ this.e = true;
+ }
+
@@ -1160,7 +1528,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (watchableobject.d()) {
+ watchableobject.a(false);
+ if (arraylist == null) {
-+ arraylist = new ArrayList();
++ arraylist = Lists.newArrayList();
+ }
+
+ arraylist.add(watchableobject);
@@ -1198,7 +1566,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ for (Iterator iterator = this.d.values().iterator(); iterator.hasNext(); arraylist.add(watchableobject)) {
+ watchableobject = (WatchableObject) iterator.next();
+ if (arraylist == null) {
-+ arraylist = new ArrayList();
++ arraylist = Lists.newArrayList();
+ }
+ }
+
@@ -1228,11 +1596,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ break;
+
+ case 4:
-+ try {
-+ packetdataserializer.a((String) watchableobject.b());
-+ } catch (java.io.IOException ex) {
-+ throw new RuntimeException(ex);
-+ }
++ packetdataserializer.a((String) watchableobject.b());
+ break;
+
+ case 5:
@@ -1242,12 +1606,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ break;
+
+ case 6:
-+ ChunkCoordinates chunkcoordinates = (ChunkCoordinates) watchableobject.b();
++ BlockPosition blockposition = (BlockPosition) watchableobject.b();
+
-+ packetdataserializer.writeInt(chunkcoordinates.x);
-+ packetdataserializer.writeInt(chunkcoordinates.y);
-+ packetdataserializer.writeInt(chunkcoordinates.z);
++ packetdataserializer.writeInt(blockposition.getX());
++ packetdataserializer.writeInt(blockposition.getY());
++ packetdataserializer.writeInt(blockposition.getZ());
++ break;
++
++ case 7:
++ Vector3f vector3f = (Vector3f) watchableobject.b();
++
++ packetdataserializer.writeFloat(vector3f.getX());
++ packetdataserializer.writeFloat(vector3f.getY());
++ packetdataserializer.writeFloat(vector3f.getZ());
+ }
++
+ }
+
+ public static List b(PacketDataSerializer packetdataserializer) {
@@ -1255,7 +1628,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ for (byte b0 = packetdataserializer.readByte(); b0 != 127; b0 = packetdataserializer.readByte()) {
+ if (arraylist == null) {
-+ arraylist = new ArrayList();
++ arraylist = Lists.newArrayList();
+ }
+
+ int i = (b0 & 224) >> 5;
@@ -1280,15 +1653,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ break;
+
+ case 4:
-+ try {
-+ watchableobject = new WatchableObject(i, j, packetdataserializer.c(32767));
-+ } catch (java.io.IOException ex) {
-+ throw new RuntimeException(ex);
-+ }
++ watchableobject = new WatchableObject(i, j, packetdataserializer.c(32767));
+ break;
+
+ case 5:
-+ watchableobject = new WatchableObject(i, j, packetdataserializer.c());
++ watchableobject = new WatchableObject(i, j, packetdataserializer.i());
+ break;
+
+ case 6:
@@ -1296,7 +1665,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ int l = packetdataserializer.readInt();
+ int i1 = packetdataserializer.readInt();
+
-+ watchableobject = new WatchableObject(i, j, new ChunkCoordinates(k, l, i1));
++ watchableobject = new WatchableObject(i, j, new BlockPosition(k, l, i1));
++ break;
++
++ case 7:
++ float f = packetdataserializer.readFloat();
++ float f1 = packetdataserializer.readFloat();
++ float f2 = packetdataserializer.readFloat();
++
++ watchableobject = new WatchableObject(i, j, new Vector3f(f, f1, f2));
+ }
+
+ arraylist.add(watchableobject);
@@ -1314,15 +1691,864 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ 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));
++ DataWatcher.c.put(Byte.class, Integer.valueOf(0));
++ DataWatcher.c.put(Short.class, Integer.valueOf(1));
++ DataWatcher.c.put(Integer.class, Integer.valueOf(2));
++ DataWatcher.c.put(Float.class, Integer.valueOf(3));
++ DataWatcher.c.put(String.class, Integer.valueOf(4));
++ DataWatcher.c.put(ItemStack.class, Integer.valueOf(5));
++ DataWatcher.c.put(BlockPosition.class, Integer.valueOf(6));
++ DataWatcher.c.put(Vector3f.class, Integer.valueOf(7));
+ }
+}
+diff --git a/src/main/java/net/minecraft/server/EnchantmentManager.java b/src/main/java/net/minecraft/server/EnchantmentManager.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/net/minecraft/server/EnchantmentManager.java
+@@ -0,0 +0,0 @@
++package net.minecraft.server;
++
++import com.google.common.collect.Lists;
++import com.google.common.collect.Maps;
++import java.util.ArrayList;
++import java.util.HashMap;
++import java.util.Iterator;
++import java.util.LinkedHashMap;
++import java.util.List;
++import java.util.Map;
++import java.util.Random;
++
++public class EnchantmentManager {
++
++ private static final Random a = new Random();
++ private static final EnchantmentModifierProtection b = new EnchantmentModifierProtection((EmptyClass) null);
++ private static final EnchantmentModifierDamage c = new EnchantmentModifierDamage((EmptyClass) null);
++ private static final EnchantmentModifierThorns d = new EnchantmentModifierThorns((EmptyClass) null);
++ private static final EnchantmentModifierArthropods e = new EnchantmentModifierArthropods((EmptyClass) null);
++
++ public static int getEnchantmentLevel(int i, ItemStack itemstack) {
++ if (itemstack == null) {
++ return 0;
++ } else {
++ NBTTagList nbttaglist = itemstack.getEnchantments();
++
++ if (nbttaglist == null) {
++ return 0;
++ } else {
++ for (int j = 0; j < nbttaglist.size(); ++j) {
++ short short0 = nbttaglist.get(j).getShort("id");
++ short short1 = nbttaglist.get(j).getShort("lvl");
++
++ if (short0 == i) {
++ return short1;
++ }
++ }
++
++ return 0;
++ }
++ }
++ }
++
++ public static Map a(ItemStack itemstack) {
++ LinkedHashMap linkedhashmap = Maps.newLinkedHashMap();
++ NBTTagList nbttaglist = itemstack.getItem() == Items.ENCHANTED_BOOK ? Items.ENCHANTED_BOOK.h(itemstack) : itemstack.getEnchantments();
++
++ if (nbttaglist != null) {
++ for (int i = 0; i < nbttaglist.size(); ++i) {
++ short short0 = nbttaglist.get(i).getShort("id");
++ short short1 = nbttaglist.get(i).getShort("lvl");
++
++ linkedhashmap.put(Integer.valueOf(short0), Integer.valueOf(short1));
++ }
++ }
++
++ return linkedhashmap;
++ }
++
++ public static void a(Map map, ItemStack itemstack) {
++ NBTTagList nbttaglist = new NBTTagList();
++ Iterator iterator = map.keySet().iterator();
++
++ while (iterator.hasNext()) {
++ int i = ((Integer) iterator.next()).intValue();
++ Enchantment enchantment = Enchantment.getById(i);
++
++ if (enchantment != null) {
++ NBTTagCompound nbttagcompound = new NBTTagCompound();
++
++ nbttagcompound.setShort("id", (short) i);
++ nbttagcompound.setShort("lvl", (short) ((Integer) map.get(Integer.valueOf(i))).intValue());
++ nbttaglist.add(nbttagcompound);
++ if (itemstack.getItem() == Items.ENCHANTED_BOOK) {
++ Items.ENCHANTED_BOOK.a(itemstack, new WeightedRandomEnchant(enchantment, ((Integer) map.get(Integer.valueOf(i))).intValue()));
++ }
++ }
++ }
++
++ if (nbttaglist.size() > 0) {
++ if (itemstack.getItem() != Items.ENCHANTED_BOOK) {
++ itemstack.a("ench", (NBTBase) nbttaglist);
++ }
++ } else if (itemstack.hasTag()) {
++ itemstack.getTag().remove("ench");
++ }
++
++ }
++
++ public static int a(int i, ItemStack[] aitemstack) {
++ if (aitemstack == null) {
++ return 0;
++ } else {
++ int j = 0;
++ ItemStack[] aitemstack1 = aitemstack;
++ int k = aitemstack.length;
++
++ for (int l = 0; l < k; ++l) {
++ ItemStack itemstack = aitemstack1[l];
++ int i1 = getEnchantmentLevel(i, itemstack);
++
++ if (i1 > j) {
++ j = i1;
++ }
++ }
++
++ return j;
++ }
++ }
++
++ private static void a(EnchantmentModifier enchantmentmodifier, ItemStack itemstack) {
++ if (itemstack != null) {
++ NBTTagList nbttaglist = itemstack.getEnchantments();
++
++ if (nbttaglist != null) {
++ for (int i = 0; i < nbttaglist.size(); ++i) {
++ short short0 = nbttaglist.get(i).getShort("id");
++ short short1 = nbttaglist.get(i).getShort("lvl");
++
++ if (Enchantment.getById(short0) != null) {
++ enchantmentmodifier.a(Enchantment.getById(short0), short1);
++ }
++ }
++
++ }
++ }
++ }
++
++ private static void a(EnchantmentModifier enchantmentmodifier, ItemStack[] aitemstack) {
++ ItemStack[] aitemstack1 = aitemstack;
++ int i = aitemstack.length;
++
++ for (int j = 0; j < i; ++j) {
++ ItemStack itemstack = aitemstack1[j];
++
++ a(enchantmentmodifier, itemstack);
++ }
++
++ }
++
++ public static int a(ItemStack[] aitemstack, DamageSource damagesource) {
++ EnchantmentManager.b.a = 0;
++ EnchantmentManager.b.b = damagesource;
++ a((EnchantmentModifier) EnchantmentManager.b, aitemstack);
++ if (EnchantmentManager.b.a > 25) {
++ EnchantmentManager.b.a = 25;
++ }
++
++ return (EnchantmentManager.b.a + 1 >> 1) + EnchantmentManager.a.nextInt((EnchantmentManager.b.a >> 1) + 1);
++ }
++
++ public static float a(ItemStack itemstack, EnumMonsterType enummonstertype) {
++ EnchantmentManager.c.a = 0.0F;
++ EnchantmentManager.c.b = enummonstertype;
++ a((EnchantmentModifier) EnchantmentManager.c, itemstack);
++ return EnchantmentManager.c.a;
++ }
++
++ public static void a(EntityLiving entityliving, Entity entity) {
++ EnchantmentManager.d.b = entity;
++ EnchantmentManager.d.a = entityliving;
++ if (entityliving != null) {
++ a((EnchantmentModifier) EnchantmentManager.d, entityliving.getEquipment());
++ }
++
++ if (entity instanceof EntityHuman) {
++ a((EnchantmentModifier) EnchantmentManager.d, entityliving.bz());
++ }
++
++ }
++
++ public static void b(EntityLiving entityliving, Entity entity) {
++ EnchantmentManager.e.a = entityliving;
++ EnchantmentManager.e.b = entity;
++ if (entityliving != null) {
++ a((EnchantmentModifier) EnchantmentManager.e, entityliving.getEquipment());
++ }
++
++ if (entityliving instanceof EntityHuman) {
++ a((EnchantmentModifier) EnchantmentManager.e, entityliving.bz());
++ }
++
++ }
++
++ public static int a(EntityLiving entityliving) {
++ return getEnchantmentLevel(Enchantment.KNOCKBACK.id, entityliving.bz());
++ }
++
++ public static int getFireAspectEnchantmentLevel(EntityLiving entityliving) {
++ return getEnchantmentLevel(Enchantment.FIRE_ASPECT.id, entityliving.bz());
++ }
++
++ public static int getOxygenEnchantmentLevel(Entity entity) {
++ return a(Enchantment.OXYGEN.id, entity.getEquipment());
++ }
++
++ public static int b(Entity entity) {
++ return a(Enchantment.DEPTH_STRIDER.id, entity.getEquipment());
++ }
++
++ public static int getDigSpeedEnchantmentLevel(EntityLiving entityliving) {
++ return getEnchantmentLevel(Enchantment.DIG_SPEED.id, entityliving.bz());
++ }
++
++ public static boolean hasSilkTouchEnchantment(EntityLiving entityliving) {
++ return getEnchantmentLevel(Enchantment.SILK_TOUCH.id, entityliving.bz()) > 0;
++ }
++
++ public static int getBonusBlockLootEnchantmentLevel(EntityLiving entityliving) {
++ return getEnchantmentLevel(Enchantment.LOOT_BONUS_BLOCKS.id, entityliving.bz());
++ }
++
++ public static int g(EntityLiving entityliving) {
++ return getEnchantmentLevel(Enchantment.LUCK.id, entityliving.bz());
++ }
++
++ public static int h(EntityLiving entityliving) {
++ return getEnchantmentLevel(Enchantment.LURE.id, entityliving.bz());
++ }
++
++ public static int getBonusMonsterLootEnchantmentLevel(EntityLiving entityliving) {
++ return getEnchantmentLevel(Enchantment.LOOT_BONUS_MOBS.id, entityliving.bz());
++ }
++
++ public static boolean j(EntityLiving entityliving) {
++ return a(Enchantment.WATER_WORKER.id, entityliving.getEquipment()) > 0;
++ }
++
++ public static ItemStack a(Enchantment enchantment, EntityLiving entityliving) {
++ ItemStack[] aitemstack = entityliving.getEquipment();
++ int i = aitemstack.length;
++
++ for (int j = 0; j < i; ++j) {
++ ItemStack itemstack = aitemstack[j];
++
++ if (itemstack != null && getEnchantmentLevel(enchantment.id, itemstack) > 0) {
++ return itemstack;
++ }
++ }
++
++ return null;
++ }
++
++ public static int a(Random random, int i, int j, ItemStack itemstack) {
++ Item item = itemstack.getItem();
++ int k = item.b();
++
++ if (k <= 0) {
++ return 0;
++ } else {
++ if (j > 15) {
++ j = 15;
++ }
++
++ int l = random.nextInt(8) + 1 + (j >> 1) + random.nextInt(j + 1);
++
++ return i == 0 ? Math.max(l / 3, 1) : (i == 1 ? l * 2 / 3 + 1 : Math.max(l, j * 2));
++ }
++ }
++
++ public static ItemStack a(Random random, ItemStack itemstack, int i) {
++ List list = b(random, itemstack, i);
++ boolean flag = itemstack.getItem() == Items.BOOK;
++
++ if (flag) {
++ itemstack.setItem(Items.ENCHANTED_BOOK);
++ }
++
++ if (list != null) {
++ Iterator iterator = list.iterator();
++
++ while (iterator.hasNext()) {
++ WeightedRandomEnchant weightedrandomenchant = (WeightedRandomEnchant) iterator.next();
++
++ if (flag) {
++ Items.ENCHANTED_BOOK.a(itemstack, weightedrandomenchant);
++ } else {
++ itemstack.addEnchantment(weightedrandomenchant.enchantment, weightedrandomenchant.level);
++ }
++ }
++ }
++
++ return itemstack;
++ }
++
++ public static List b(Random random, ItemStack itemstack, int i) {
++ Item item = itemstack.getItem();
++ int j = item.b();
++
++ if (j <= 0) {
++ return null;
++ } else {
++ j /= 2;
++ j = 1 + random.nextInt((j >> 1) + 1) + random.nextInt((j >> 1) + 1);
++ int k = j + i;
++ float f = (random.nextFloat() + random.nextFloat() - 1.0F) * 0.15F;
++ int l = (int) ((float) k * (1.0F + f) + 0.5F);
++
++ if (l < 1) {
++ l = 1;
++ }
++
++ ArrayList arraylist = null;
++ Map map = b(l, itemstack);
++
++ if (map != null && !map.isEmpty()) {
++ WeightedRandomEnchant weightedrandomenchant = (WeightedRandomEnchant) WeightedRandom.a(random, map.values());
++
++ if (weightedrandomenchant != null) {
++ arraylist = Lists.newArrayList();
++ arraylist.add(weightedrandomenchant);
++
++ for (int i1 = l; random.nextInt(50) <= i1; i1 >>= 1) {
++ Iterator iterator = map.keySet().iterator();
++
++ while (iterator.hasNext()) {
++ Integer integer = (Integer) iterator.next();
++ boolean flag = true;
++ Iterator iterator1 = arraylist.iterator();
++
++ while (true) {
++ if (iterator1.hasNext()) {
++ WeightedRandomEnchant weightedrandomenchant1 = (WeightedRandomEnchant) iterator1.next();
++
++ if (weightedrandomenchant1.enchantment.a(Enchantment.getById(integer.intValue()))) {
++ continue;
++ }
++
++ flag = false;
++ }
++
++ if (!flag) {
++ iterator.remove();
++ }
++ break;
++ }
++ }
++
++ if (!map.isEmpty()) {
++ WeightedRandomEnchant weightedrandomenchant2 = (WeightedRandomEnchant) WeightedRandom.a(random, map.values());
++
++ arraylist.add(weightedrandomenchant2);
++ }
++ }
++ }
++ }
++
++ return arraylist;
++ }
++ }
++
++ public static Map b(int i, ItemStack itemstack) {
++ Item item = itemstack.getItem();
++ HashMap hashmap = null;
++ boolean flag = itemstack.getItem() == Items.BOOK;
++ Enchantment[] aenchantment = Enchantment.b;
++ int j = aenchantment.length;
++
++ for (int k = 0; k < j; ++k) {
++ Enchantment enchantment = aenchantment[k];
++
++ if (enchantment != null && (enchantment.slot.canEnchant(item) || flag)) {
++ for (int l = enchantment.getStartLevel(); l <= enchantment.getMaxLevel(); ++l) {
++ if (i >= enchantment.a(l) && i <= enchantment.b(l)) {
++ if (hashmap == null) {
++ hashmap = Maps.newHashMap();
++ }
++
++ hashmap.put(Integer.valueOf(enchantment.id), new WeightedRandomEnchant(enchantment, l));
++ }
++ }
++ }
++ }
++
++ return hashmap;
++ }
++
++}
+diff --git a/src/main/java/net/minecraft/server/EnchantmentModifierArthropods.java b/src/main/java/net/minecraft/server/EnchantmentModifierArthropods.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/net/minecraft/server/EnchantmentModifierArthropods.java
+@@ -0,0 +0,0 @@
++package net.minecraft.server;
++
++final class EnchantmentModifierArthropods implements EnchantmentModifier {
++
++ public EntityLiving a;
++ public Entity b;
++
++ private EnchantmentModifierArthropods() {}
++
++ public void a(Enchantment enchantment, int i) {
++ enchantment.a(this.a, this.b, i);
++ }
++
++ EnchantmentModifierArthropods(EmptyClass emptyclass) {
++ this();
++ }
++}
+diff --git a/src/main/java/net/minecraft/server/EnchantmentModifierDamage.java b/src/main/java/net/minecraft/server/EnchantmentModifierDamage.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/net/minecraft/server/EnchantmentModifierDamage.java
+@@ -0,0 +0,0 @@
++package net.minecraft.server;
++
++final class EnchantmentModifierDamage implements EnchantmentModifier {
++
++ public float a;
++ public EnumMonsterType b;
++
++ private EnchantmentModifierDamage() {}
++
++ public void a(Enchantment enchantment, int i) {
++ this.a += enchantment.a(i, this.b);
++ }
++
++ EnchantmentModifierDamage(EmptyClass emptyclass) {
++ this();
++ }
++}
+diff --git a/src/main/java/net/minecraft/server/EnchantmentModifierProtection.java b/src/main/java/net/minecraft/server/EnchantmentModifierProtection.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/net/minecraft/server/EnchantmentModifierProtection.java
+@@ -0,0 +0,0 @@
++package net.minecraft.server;
++
++final class EnchantmentModifierProtection implements EnchantmentModifier {
++
++ public int a;
++ public DamageSource b;
++
++ private EnchantmentModifierProtection() {}
++
++ public void a(Enchantment enchantment, int i) {
++ this.a += enchantment.a(i, this.b);
++ }
++
++ EnchantmentModifierProtection(EmptyClass emptyclass) {
++ this();
++ }
++}
+diff --git a/src/main/java/net/minecraft/server/EnchantmentModifierThorns.java b/src/main/java/net/minecraft/server/EnchantmentModifierThorns.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/net/minecraft/server/EnchantmentModifierThorns.java
+@@ -0,0 +0,0 @@
++package net.minecraft.server;
++
++final class EnchantmentModifierThorns implements EnchantmentModifier {
++
++ public EntityLiving a;
++ public Entity b;
++
++ private EnchantmentModifierThorns() {}
++
++ public void a(Enchantment enchantment, int i) {
++ enchantment.b(this.a, this.b, i);
++ }
++
++ EnchantmentModifierThorns(EmptyClass emptyclass) {
++ this();
++ }
++}
+diff --git a/src/main/java/net/minecraft/server/EntityFireworks.java b/src/main/java/net/minecraft/server/EntityFireworks.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/net/minecraft/server/EntityFireworks.java
+@@ -0,0 +0,0 @@
++package net.minecraft.server;
++
++public class EntityFireworks extends Entity {
++
++ private int ticksFlown;
++ public int expectedLifespan;
++
++ public EntityFireworks(World world) {
++ super(world);
++ this.a(0.25F, 0.25F);
++ }
++
++ protected void h() {
++ this.datawatcher.add(8, 5);
++ }
++
++ public EntityFireworks(World world, double d0, double d1, double d2, ItemStack itemstack) {
++ super(world);
++ this.ticksFlown = 0;
++ this.a(0.25F, 0.25F);
++ this.setPosition(d0, d1, d2);
++ int i = 1;
++
++ if (itemstack != null && itemstack.hasTag()) {
++ this.datawatcher.watch(8, itemstack);
++ NBTTagCompound nbttagcompound = itemstack.getTag();
++ NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Fireworks");
++
++ if (nbttagcompound1 != null) {
++ i += nbttagcompound1.getByte("Flight");
++ }
++ }
++
++ this.motX = this.random.nextGaussian() * 0.001D;
++ this.motZ = this.random.nextGaussian() * 0.001D;
++ this.motY = 0.05D;
++ this.expectedLifespan = 10 * i + this.random.nextInt(6) + this.random.nextInt(7);
++ }
++
++ public void s_() {
++ this.P = this.locX;
++ this.Q = this.locY;
++ this.R = this.locZ;
++ super.s_();
++ this.motX *= 1.15D;
++ this.motZ *= 1.15D;
++ this.motY += 0.04D;
++ this.move(this.motX, this.motY, this.motZ);
++ float f = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ);
++
++ this.yaw = (float) (Math.atan2(this.motX, this.motZ) * 180.0D / 3.1415927410125732D);
++
++ for (this.pitch = (float) (Math.atan2(this.motY, (double) f) * 180.0D / 3.1415927410125732D); this.pitch - this.lastPitch < -180.0F; this.lastPitch -= 360.0F) {
++ ;
++ }
++
++ while (this.pitch - this.lastPitch >= 180.0F) {
++ this.lastPitch += 360.0F;
++ }
++
++ while (this.yaw - this.lastYaw < -180.0F) {
++ this.lastYaw -= 360.0F;
++ }
++
++ while (this.yaw - this.lastYaw >= 180.0F) {
++ this.lastYaw += 360.0F;
++ }
++
++ this.pitch = this.lastPitch + (this.pitch - this.lastPitch) * 0.2F;
++ this.yaw = this.lastYaw + (this.yaw - this.lastYaw) * 0.2F;
++ if (this.ticksFlown == 0 && !this.R()) {
++ this.world.makeSound(this, "fireworks.launch", 3.0F, 1.0F);
++ }
++
++ ++this.ticksFlown;
++ if (this.world.isStatic && this.ticksFlown % 2 < 2) {
++ this.world.addParticle(EnumParticle.FIREWORKS_SPARK, this.locX, this.locY - 0.3D, this.locZ, this.random.nextGaussian() * 0.05D, -this.motY * 0.5D, this.random.nextGaussian() * 0.05D, new int[0]);
++ }
++
++ if (!this.world.isStatic && this.ticksFlown > this.expectedLifespan) {
++ this.world.broadcastEntityEffect(this, (byte) 17);
++ this.die();
++ }
++
++ }
++
++ public void b(NBTTagCompound nbttagcompound) {
++ nbttagcompound.setInt("Life", this.ticksFlown);
++ nbttagcompound.setInt("LifeTime", this.expectedLifespan);
++ ItemStack itemstack = this.datawatcher.getItemStack(8);
++
++ if (itemstack != null) {
++ NBTTagCompound nbttagcompound1 = new NBTTagCompound();
++
++ itemstack.save(nbttagcompound1);
++ nbttagcompound.set("FireworksItem", nbttagcompound1);
++ }
++
++ }
++
++ public void a(NBTTagCompound nbttagcompound) {
++ this.ticksFlown = nbttagcompound.getInt("Life");
++ this.expectedLifespan = nbttagcompound.getInt("LifeTime");
++ NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("FireworksItem");
++
++ if (nbttagcompound1 != null) {
++ ItemStack itemstack = ItemStack.createStack(nbttagcompound1);
++
++ if (itemstack != null) {
++ this.datawatcher.watch(8, itemstack);
++ }
++ }
++
++ }
++
++ public float c(float f) {
++ return super.c(f);
++ }
++
++ public boolean aE() {
++ return false;
++ }
++}
+diff --git a/src/main/java/net/minecraft/server/EntityTracker.java b/src/main/java/net/minecraft/server/EntityTracker.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/net/minecraft/server/EntityTracker.java
+@@ -0,0 +0,0 @@
++package net.minecraft.server;
++
++import com.google.common.collect.Lists;
++import com.google.common.collect.Sets;
++import java.util.ArrayList;
++import java.util.Iterator;
++import java.util.Set;
++import java.util.concurrent.Callable;
++import org.apache.logging.log4j.LogManager;
++import org.apache.logging.log4j.Logger;
++
++public class EntityTracker {
++
++ private static final Logger a = LogManager.getLogger();
++ private final WorldServer world;
++ private Set c = Sets.newHashSet();
++ public IntHashMap trackedEntities = new IntHashMap();
++ private int e;
++
++ public EntityTracker(WorldServer worldserver) {
++ this.world = worldserver;
++ this.e = worldserver.getMinecraftServer().getPlayerList().d();
++ }
++
++ public void track(Entity entity) {
++ if (entity instanceof EntityPlayer) {
++ this.addEntity(entity, 512, 2);
++ EntityPlayer entityplayer = (EntityPlayer) entity;
++ Iterator iterator = this.c.iterator();
++
++ while (iterator.hasNext()) {
++ EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
++
++ if (entitytrackerentry.tracker != entityplayer) {
++ entitytrackerentry.updatePlayer(entityplayer);
++ }
++ }
++ } else if (entity instanceof EntityFishingHook) {
++ this.addEntity(entity, 64, 5, true);
++ } else if (entity instanceof EntityArrow) {
++ this.addEntity(entity, 64, 20, false);
++ } else if (entity instanceof EntitySmallFireball) {
++ this.addEntity(entity, 64, 10, false);
++ } else if (entity instanceof EntityFireball) {
++ this.addEntity(entity, 64, 10, false);
++ } else if (entity instanceof EntitySnowball) {
++ this.addEntity(entity, 64, 10, true);
++ } else if (entity instanceof EntityEnderPearl) {
++ this.addEntity(entity, 64, 10, true);
++ } else if (entity instanceof EntityEnderSignal) {
++ this.addEntity(entity, 64, 4, true);
++ } else if (entity instanceof EntityEgg) {
++ this.addEntity(entity, 64, 10, true);
++ } else if (entity instanceof EntityPotion) {
++ this.addEntity(entity, 64, 10, true);
++ } else if (entity instanceof EntityThrownExpBottle) {
++ this.addEntity(entity, 64, 10, true);
++ } else if (entity instanceof EntityFireworks) {
++ this.addEntity(entity, 64, 10, true);
++ } else if (entity instanceof EntityItem) {
++ this.addEntity(entity, 64, 20, true);
++ } else if (entity instanceof EntityMinecartAbstract) {
++ this.addEntity(entity, 80, 3, true);
++ } else if (entity instanceof EntityBoat) {
++ this.addEntity(entity, 80, 3, true);
++ } else if (entity instanceof EntitySquid) {
++ this.addEntity(entity, 64, 3, true);
++ } else if (entity instanceof EntityWither) {
++ this.addEntity(entity, 80, 3, false);
++ } else if (entity instanceof EntityBat) {
++ this.addEntity(entity, 80, 3, false);
++ } else if (entity instanceof EntityEnderDragon) {
++ this.addEntity(entity, 160, 3, true);
++ } else if (entity instanceof IAnimal) {
++ this.addEntity(entity, 80, 3, true);
++ } else if (entity instanceof EntityTNTPrimed) {
++ this.addEntity(entity, 160, 10, true);
++ } else if (entity instanceof EntityFallingBlock) {
++ this.addEntity(entity, 160, 20, true);
++ } else if (entity instanceof EntityHanging) {
++ this.addEntity(entity, 160, Integer.MAX_VALUE, false);
++ } else if (entity instanceof EntityArmorStand) {
++ this.addEntity(entity, 160, 3, true);
++ } else if (entity instanceof EntityExperienceOrb) {
++ this.addEntity(entity, 160, 20, true);
++ } else if (entity instanceof EntityEnderCrystal) {
++ this.addEntity(entity, 256, Integer.MAX_VALUE, false);
++ }
++
++ }
++
++ public void addEntity(Entity entity, int i, int j) {
++ this.addEntity(entity, i, j, false);
++ }
++
++ public void addEntity(Entity entity, int i, int j, boolean flag) {
++ if (i > this.e) {
++ i = this.e;
++ }
++
++ try {
++ if (this.trackedEntities.b(entity.getId())) {
++ throw new IllegalStateException("Entity is already tracked!");
++ }
++
++ EntityTrackerEntry entitytrackerentry = new EntityTrackerEntry(entity, i, j, flag);
++
++ this.c.add(entitytrackerentry);
++ this.trackedEntities.a(entity.getId(), entitytrackerentry);
++ entitytrackerentry.scanPlayers(this.world.players);
++ } catch (Throwable throwable) {
++ CrashReport crashreport = CrashReport.a(throwable, "Adding entity to track");
++ CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity To Track");
++
++ crashreportsystemdetails.a("Tracking range", (Object) (i + " blocks"));
++ crashreportsystemdetails.a("Update interval", (Callable) (new CrashReportEntityTrackerUpdateInterval(this, j)));
++ entity.appendEntityCrashDetails(crashreportsystemdetails);
++ CrashReportSystemDetails crashreportsystemdetails1 = crashreport.a("Entity That Is Already Tracked");
++
++ ((EntityTrackerEntry) this.trackedEntities.get(entity.getId())).tracker.appendEntityCrashDetails(crashreportsystemdetails1);
++
++ try {
++ throw new ReportedException(crashreport);
++ } catch (ReportedException reportedexception) {
++ EntityTracker.a.error("\"Silently\" catching entity tracking error.", reportedexception);
++ }
++ }
++
++ }
++
++ public void untrackEntity(Entity entity) {
++ if (entity instanceof EntityPlayer) {
++ EntityPlayer entityplayer = (EntityPlayer) entity;
++ Iterator iterator = this.c.iterator();
++
++ while (iterator.hasNext()) {
++ EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
++
++ entitytrackerentry.a(entityplayer);
++ }
++ }
++
++ EntityTrackerEntry entitytrackerentry1 = (EntityTrackerEntry) this.trackedEntities.d(entity.getId());
++
++ if (entitytrackerentry1 != null) {
++ this.c.remove(entitytrackerentry1);
++ entitytrackerentry1.a();
++ }
++
++ }
++
++ public void updatePlayers() {
++ ArrayList arraylist = Lists.newArrayList();
++ Iterator iterator = this.c.iterator();
++
++ while (iterator.hasNext()) {
++ EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
++
++ entitytrackerentry.track(this.world.players);
++ if (entitytrackerentry.n && entitytrackerentry.tracker instanceof EntityPlayer) {
++ arraylist.add((EntityPlayer) entitytrackerentry.tracker);
++ }
++ }
++
++ for (int i = 0; i < arraylist.size(); ++i) {
++ EntityPlayer entityplayer = (EntityPlayer) arraylist.get(i);
++ Iterator iterator1 = this.c.iterator();
++
++ while (iterator1.hasNext()) {
++ EntityTrackerEntry entitytrackerentry1 = (EntityTrackerEntry) iterator1.next();
++
++ if (entitytrackerentry1.tracker != entityplayer) {
++ entitytrackerentry1.updatePlayer(entityplayer);
++ }
++ }
++ }
++
++ }
++
++ public void a(EntityPlayer entityplayer) {
++ Iterator iterator = this.c.iterator();
++
++ while (iterator.hasNext()) {
++ EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
++
++ if (entitytrackerentry.tracker == entityplayer) {
++ entitytrackerentry.scanPlayers(this.world.players);
++ } else {
++ entitytrackerentry.updatePlayer(entityplayer);
++ }
++ }
++
++ }
++
++ public void a(Entity entity, Packet packet) {
++ EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) this.trackedEntities.get(entity.getId());
++
++ if (entitytrackerentry != null) {
++ entitytrackerentry.broadcast(packet);
++ }
++
++ }
++
++ public void sendPacketToEntity(Entity entity, Packet packet) {
++ EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) this.trackedEntities.get(entity.getId());
++
++ if (entitytrackerentry != null) {
++ entitytrackerentry.broadcastIncludingSelf(packet);
++ }
++
++ }
++
++ public void untrackPlayer(EntityPlayer entityplayer) {
++ Iterator iterator = this.c.iterator();
++
++ while (iterator.hasNext()) {
++ EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
++
++ entitytrackerentry.clear(entityplayer);
++ }
++
++ }
++
++ public void a(EntityPlayer entityplayer, Chunk chunk) {
++ Iterator iterator = this.c.iterator();
++
++ while (iterator.hasNext()) {
++ EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
++
++ if (entitytrackerentry.tracker != entityplayer && entitytrackerentry.tracker.ae == chunk.locX && entitytrackerentry.tracker.ag == chunk.locZ) {
++ entitytrackerentry.updatePlayer(entityplayer);
++ }
++ }
++
++ }
++
++}
diff --git a/src/main/java/net/minecraft/server/GameProfileBanEntry.java b/src/main/java/net/minecraft/server/GameProfileBanEntry.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
@@ -1331,12 +2557,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@
+package net.minecraft.server;
+
++import com.google.gson.JsonObject;
++import com.mojang.authlib.GameProfile;
+import java.util.Date;
+import java.util.UUID;
+
-+import net.minecraft.util.com.google.gson.JsonObject;
-+import net.minecraft.util.com.mojang.authlib.GameProfile;
-+
+public class GameProfileBanEntry extends ExpirableListEntry {
+
+ public GameProfileBanEntry(GameProfile gameprofile) {
@@ -1388,18 +2613,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.UUID;
-+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+public class GenericAttributes {
+
+ private static final Logger f = LogManager.getLogger();
-+ public static final IAttribute maxHealth = (new AttributeRanged("generic.maxHealth", 20.0D, 0.0D, Double.MAX_VALUE)).a("Max Health").a(true);
-+ public static final IAttribute b = (new AttributeRanged("generic.followRange", 32.0D, 0.0D, 2048.0D)).a("Follow Range");
-+ public static final IAttribute c = (new AttributeRanged("generic.knockbackResistance", 0.0D, 0.0D, 1.0D)).a("Knockback Resistance");
-+ public static final IAttribute d = (new AttributeRanged("generic.movementSpeed", 0.699999988079071D, 0.0D, Double.MAX_VALUE)).a("Movement Speed").a(true);
-+ public static final IAttribute e = new AttributeRanged("generic.attackDamage", 2.0D, 0.0D, Double.MAX_VALUE);
++ public static final IAttribute maxHealth = (new AttributeRanged((IAttribute) null, "generic.maxHealth", 20.0D, 0.0D, Double.MAX_VALUE)).a("Max Health").a(true);
++ public static final IAttribute b = (new AttributeRanged((IAttribute) null, "generic.followRange", 32.0D, 0.0D, 2048.0D)).a("Follow Range");
++ public static final IAttribute c = (new AttributeRanged((IAttribute) null, "generic.knockbackResistance", 0.0D, 0.0D, 1.0D)).a("Knockback Resistance");
++ public static final IAttribute d = (new AttributeRanged((IAttribute) null, "generic.movementSpeed", 0.699999988079071D, 0.0D, Double.MAX_VALUE)).a("Movement Speed").a(true);
++ public static final IAttribute e = new AttributeRanged((IAttribute) null, "generic.attackDamage", 2.0D, 0.0D, Double.MAX_VALUE);
+
+ public static NBTTagList a(AttributeMapBase attributemapbase) {
+ NBTTagList nbttaglist = new NBTTagList();
@@ -1459,9 +2683,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (attributeinstance != null) {
+ a(attributeinstance, nbttagcompound);
+ } else {
-+ f.warn("Ignoring unknown attribute \'" + nbttagcompound.getString("Name") + "\'");
++ GenericAttributes.f.warn("Ignoring unknown attribute \'" + nbttagcompound.getString("Name") + "\'");
+ }
+ }
++
+ }
+
+ private static void a(AttributeInstance attributeinstance, NBTTagCompound nbttagcompound) {
@@ -1471,22 +2696,32 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ for (int i = 0; i < nbttaglist.size(); ++i) {
+ AttributeModifier attributemodifier = a(nbttaglist.get(i));
-+ AttributeModifier attributemodifier1 = attributeinstance.a(attributemodifier.a());
+
-+ if (attributemodifier1 != null) {
-+ attributeinstance.b(attributemodifier1);
++ if (attributemodifier != null) {
++ AttributeModifier attributemodifier1 = attributeinstance.a(attributemodifier.a());
++
++ if (attributemodifier1 != null) {
++ attributeinstance.c(attributemodifier1);
++ }
++
++ attributeinstance.b(attributemodifier);
+ }
-+
-+ attributeinstance.a(attributemodifier);
+ }
+ }
++
+ }
+
+ public static AttributeModifier a(NBTTagCompound nbttagcompound) {
+ UUID uuid = new UUID(nbttagcompound.getLong("UUIDMost"), nbttagcompound.getLong("UUIDLeast"));
+
-+ return new AttributeModifier(uuid, nbttagcompound.getString("Name"), nbttagcompound.getDouble("Amount"), nbttagcompound.getInt("Operation"));
++ try {
++ return new AttributeModifier(uuid, nbttagcompound.getString("Name"), nbttagcompound.getDouble("Amount"), nbttagcompound.getInt("Operation"));
++ } catch (Exception exception) {
++ GenericAttributes.f.warn("Unable to create attribute: " + exception.getMessage());
++ return null;
++ }
+ }
++
+}
diff --git a/src/main/java/net/minecraft/server/IntCache.java b/src/main/java/net/minecraft/server/IntCache.java
new file mode 100644
@@ -1496,65 +2731,128 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@
+package net.minecraft.server;
+
-+import java.util.ArrayList;
++import com.google.common.collect.Lists;
+import java.util.List;
+
+public class IntCache {
+
+ private static int a = 256;
-+ private static List b = new ArrayList();
-+ private static List c = new ArrayList();
-+ private static List d = new ArrayList();
-+ private static List e = new ArrayList();
++ private static List b = Lists.newArrayList();
++ private static List c = Lists.newArrayList();
++ private static List d = Lists.newArrayList();
++ private static List e = Lists.newArrayList();
+
+ public static synchronized int[] a(int i) {
+ int[] aint;
+
+ if (i <= 256) {
-+ if (b.isEmpty()) {
++ if (IntCache.b.isEmpty()) {
+ aint = new int[256];
-+ c.add(aint);
++ IntCache.c.add(aint);
+ return aint;
+ } else {
-+ aint = (int[]) b.remove(b.size() - 1);
-+ c.add(aint);
++ aint = (int[]) IntCache.b.remove(IntCache.b.size() - 1);
++ IntCache.c.add(aint);
+ return aint;
+ }
-+ } else if (i > a) {
-+ a = i;
-+ d.clear();
-+ e.clear();
-+ aint = new int[a];
-+ e.add(aint);
++ } else if (i > IntCache.a) {
++ IntCache.a = i;
++ IntCache.d.clear();
++ IntCache.e.clear();
++ aint = new int[IntCache.a];
++ IntCache.e.add(aint);
+ return aint;
-+ } else if (d.isEmpty()) {
-+ aint = new int[a];
-+ e.add(aint);
++ } else if (IntCache.d.isEmpty()) {
++ aint = new int[IntCache.a];
++ IntCache.e.add(aint);
+ return aint;
+ } else {
-+ aint = (int[]) d.remove(d.size() - 1);
-+ e.add(aint);
++ aint = (int[]) IntCache.d.remove(IntCache.d.size() - 1);
++ IntCache.e.add(aint);
+ return aint;
+ }
+ }
+
+ public static synchronized void a() {
-+ if (!d.isEmpty()) {
-+ d.remove(d.size() - 1);
++ if (!IntCache.d.isEmpty()) {
++ IntCache.d.remove(IntCache.d.size() - 1);
+ }
+
-+ if (!b.isEmpty()) {
-+ b.remove(b.size() - 1);
++ if (!IntCache.b.isEmpty()) {
++ IntCache.b.remove(IntCache.b.size() - 1);
+ }
+
-+ d.addAll(e);
-+ b.addAll(c);
-+ e.clear();
-+ c.clear();
++ IntCache.d.addAll(IntCache.e);
++ IntCache.b.addAll(IntCache.c);
++ IntCache.e.clear();
++ IntCache.c.clear();
+ }
+
+ public static synchronized String b() {
-+ return "cache: " + d.size() + ", tcache: " + b.size() + ", allocated: " + e.size() + ", tallocated: " + c.size();
++ return "cache: " + IntCache.d.size() + ", tcache: " + IntCache.b.size() + ", allocated: " + IntCache.e.size() + ", tallocated: " + IntCache.c.size();
++ }
++
++}
+diff --git a/src/main/java/net/minecraft/server/ItemDoor.java b/src/main/java/net/minecraft/server/ItemDoor.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/net/minecraft/server/ItemDoor.java
+@@ -0,0 +0,0 @@
++package net.minecraft.server;
++
++public class ItemDoor extends Item {
++
++ private Block a;
++
++ public ItemDoor(Block block) {
++ this.a = block;
++ this.a(CreativeModeTab.d);
++ }
++
++ public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2) {
++ if (enumdirection != EnumDirection.UP) {
++ return false;
++ } else {
++ IBlockData iblockdata = world.getType(blockposition);
++ Block block = iblockdata.getBlock();
++
++ if (!block.f(world, blockposition)) {
++ blockposition = blockposition.shift(enumdirection);
++ }
++
++ if (!entityhuman.a(blockposition, enumdirection, itemstack)) {
++ return false;
++ } else if (!this.a.canPlace(world, blockposition)) {
++ return false;
++ } else {
++ a(world, blockposition, EnumDirection.fromAngle((double) entityhuman.yaw), this.a);
++ --itemstack.count;
++ return true;
++ }
++ }
++ }
++
++ public static void a(World world, BlockPosition blockposition, EnumDirection enumdirection, Block block) {
++ BlockPosition blockposition1 = blockposition.shift(enumdirection.e());
++ BlockPosition blockposition2 = blockposition.shift(enumdirection.f());
++ int i = (world.getType(blockposition2).getBlock().isOccluding() ? 1 : 0) + (world.getType(blockposition2.up()).getBlock().isOccluding() ? 1 : 0);
++ int j = (world.getType(blockposition1).getBlock().isOccluding() ? 1 : 0) + (world.getType(blockposition1.up()).getBlock().isOccluding() ? 1 : 0);
++ boolean flag = world.getType(blockposition2).getBlock() == block || world.getType(blockposition2.up()).getBlock() == block;
++ boolean flag1 = world.getType(blockposition1).getBlock() == block || world.getType(blockposition1.up()).getBlock() == block;
++ boolean flag2 = false;
++
++ if (flag && !flag1 || j > i) {
++ flag2 = true;
++ }
++
++ BlockPosition blockposition3 = blockposition.up();
++ IBlockData iblockdata = block.getBlockData().set(BlockDoor.FACING, enumdirection).set(BlockDoor.HINGE, flag2 ? EnumDoorHinge.RIGHT : EnumDoorHinge.LEFT);
++
++ world.setTypeAndData(blockposition, iblockdata.set(BlockDoor.HALF, EnumDoorHalf.LOWER), 2);
++ world.setTypeAndData(blockposition3, iblockdata.set(BlockDoor.HALF, EnumDoorHalf.UPPER), 2);
++ world.applyPhysics(blockposition, block);
++ world.applyPhysics(blockposition3, block);
+ }
+}
diff --git a/src/main/java/net/minecraft/server/ItemSkull.java b/src/main/java/net/minecraft/server/ItemSkull.java
@@ -1565,14 +2863,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@
+package net.minecraft.server;
+
++import com.mojang.authlib.GameProfile;
+import java.util.UUID;
+
-+import net.minecraft.util.com.mojang.authlib.GameProfile;
-+
+public class ItemSkull extends Item {
+
-+ private static final String[] b = new String[] { "skeleton", "wither", "zombie", "char", "creeper"};
-+ public static final String[] a = new String[] { "skeleton", "wither", "zombie", "steve", "creeper"};
++ private static final String[] a = new String[] { "skeleton", "wither", "zombie", "char", "creeper"};
+
+ public ItemSkull() {
+ this.a(CreativeModeTab.c);
@@ -1580,69 +2876,67 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.a(true);
+ }
+
-+ public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, int i, int j, int k, int l, float f, float f1, float f2) {
-+ if (l == 0) {
-+ return false;
-+ } else if (!world.getType(i, j, k).getMaterial().isBuildable()) {
++ public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2) {
++ if (enumdirection == EnumDirection.DOWN) {
+ return false;
+ } else {
-+ if (l == 1) {
-+ ++j;
-+ }
++ IBlockData iblockdata = world.getType(blockposition);
++ Block block = iblockdata.getBlock();
++ boolean flag = block.f(world, blockposition);
+
-+ if (l == 2) {
-+ --k;
-+ }
-+
-+ if (l == 3) {
-+ ++k;
-+ }
-+
-+ if (l == 4) {
-+ --i;
-+ }
-+
-+ if (l == 5) {
-+ ++i;
-+ }
-+
-+ if (!world.isStatic) {
-+ world.setTypeAndData(i, j, k, Blocks.SKULL, l, 2);
-+ int i1 = 0;
-+
-+ if (l == 1) {
-+ i1 = MathHelper.floor((double) (entityhuman.yaw * 16.0F / 360.0F) + 0.5D) & 15;
++ if (!flag) {
++ if (!world.getType(blockposition).getBlock().getMaterial().isBuildable()) {
++ return false;
+ }
+
-+ TileEntity tileentity = world.getTileEntity(i, j, k);
++ blockposition = blockposition.shift(enumdirection);
++ }
+
-+ if (tileentity != null && tileentity instanceof TileEntitySkull) {
-+ if (itemstack.getData() == 3) {
-+ GameProfile gameprofile = null;
++ if (!entityhuman.a(blockposition, enumdirection, itemstack)) {
++ return false;
++ } else if (!Blocks.SKULL.canPlace(world, blockposition)) {
++ return false;
++ } else {
++ if (!world.isStatic) {
++ world.setTypeAndData(blockposition, Blocks.SKULL.getBlockData().set(BlockSkull.FACING, enumdirection), 3);
++ int i = 0;
+
-+ if (itemstack.hasTag()) {
-+ NBTTagCompound nbttagcompound = itemstack.getTag();
-+
-+ if (nbttagcompound.hasKeyOfType("SkullOwner", 10)) {
-+ gameprofile = GameProfileSerializer.deserialize(nbttagcompound.getCompound("SkullOwner"));
-+ } else if (nbttagcompound.hasKeyOfType("SkullOwner", 8) && nbttagcompound.getString("SkullOwner").length() > 0) {
-+ gameprofile = new GameProfile((UUID) null, nbttagcompound.getString("SkullOwner"));
-+ }
-+ }
-+
-+ ((TileEntitySkull) tileentity).setGameProfile(gameprofile);
-+ } else {
-+ ((TileEntitySkull) tileentity).setSkullType(itemstack.getData());
++ if (enumdirection == EnumDirection.UP) {
++ i = MathHelper.floor((double) (entityhuman.yaw * 16.0F / 360.0F) + 0.5D) & 15;
+ }
+
-+ ((TileEntitySkull) tileentity).setRotation(i1);
-+ ((BlockSkull) Blocks.SKULL).a(world, i, j, k, (TileEntitySkull) tileentity);
++ TileEntity tileentity = world.getTileEntity(blockposition);
++
++ if (tileentity instanceof TileEntitySkull) {
++ TileEntitySkull tileentityskull = (TileEntitySkull) tileentity;
++
++ if (itemstack.getData() == 3) {
++ GameProfile gameprofile = null;
++
++ if (itemstack.hasTag()) {
++ NBTTagCompound nbttagcompound = itemstack.getTag();
++
++ if (nbttagcompound.hasKeyOfType("SkullOwner", 10)) {
++ gameprofile = GameProfileSerializer.deserialize(nbttagcompound.getCompound("SkullOwner"));
++ } else if (nbttagcompound.hasKeyOfType("SkullOwner", 8) && nbttagcompound.getString("SkullOwner").length() > 0) {
++ gameprofile = new GameProfile((UUID) null, nbttagcompound.getString("SkullOwner"));
++ }
++ }
++
++ tileentityskull.setGameProfile(gameprofile);
++ } else {
++ tileentityskull.setSkullType(itemstack.getData());
++ }
++
++ tileentityskull.setRotation(i);
++ Blocks.SKULL.a(world, blockposition, tileentityskull);
++ }
++
++ --itemstack.count;
+ }
+
-+ --itemstack.count;
++ return true;
+ }
-+
-+ return true;
+ }
+ }
+
@@ -1650,29 +2944,47 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return i;
+ }
+
-+ public String a(ItemStack itemstack) {
++ public String e_(ItemStack itemstack) {
+ int i = itemstack.getData();
+
-+ if (i < 0 || i >= b.length) {
++ if (i < 0 || i >= ItemSkull.a.length) {
+ i = 0;
+ }
+
-+ return super.getName() + "." + b[i];
++ return super.getName() + "." + ItemSkull.a[i];
+ }
+
-+ public String n(ItemStack itemstack) {
++ public String a(ItemStack itemstack) {
+ if (itemstack.getData() == 3 && itemstack.hasTag()) {
-+ if (itemstack.getTag().hasKeyOfType("SkullOwner", 10)) {
-+ return LocaleI18n.get("item.skull.player.name", new Object[] { GameProfileSerializer.deserialize(itemstack.getTag().getCompound("SkullOwner")).getName()});
++ if (itemstack.getTag().hasKeyOfType("SkullOwner", 8)) {
++ return LocaleI18n.a("item.skull.player.name", new Object[] { itemstack.getTag().getString("SkullOwner")});
+ }
+
-+ if (itemstack.getTag().hasKeyOfType("SkullOwner", 8)) {
-+ return LocaleI18n.get("item.skull.player.name", new Object[] { itemstack.getTag().getString("SkullOwner")});
++ if (itemstack.getTag().hasKeyOfType("SkullOwner", 10)) {
++ NBTTagCompound nbttagcompound = itemstack.getTag().getCompound("SkullOwner");
++
++ if (nbttagcompound.hasKeyOfType("Name", 8)) {
++ return LocaleI18n.a("item.skull.player.name", new Object[] { nbttagcompound.getString("Name")});
++ }
+ }
+ }
+
-+ return super.n(itemstack);
++ return super.a(itemstack);
+ }
++
++ public boolean a(NBTTagCompound nbttagcompound) {
++ super.a(nbttagcompound);
++ if (nbttagcompound.hasKeyOfType("SkullOwner", 8) && nbttagcompound.getString("SkullOwner").length() > 0) {
++ GameProfile gameprofile = new GameProfile((UUID) null, nbttagcompound.getString("SkullOwner"));
++
++ gameprofile = TileEntitySkull.b(gameprofile);
++ nbttagcompound.set("SkullOwner", GameProfileSerializer.serialize(new NBTTagCompound(), gameprofile));
++ return true;
++ } else {
++ return false;
++ }
++ }
++
+}
diff --git a/src/main/java/net/minecraft/server/NBTBase.java b/src/main/java/net/minecraft/server/NBTBase.java
new file mode 100644
@@ -1684,15 +2996,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+import java.io.DataInput;
+import java.io.DataOutput;
-+import java.io.IOException;
+
+public abstract class NBTBase {
+
+ public static final String[] a = new String[] { "END", "BYTE", "SHORT", "INT", "LONG", "FLOAT", "DOUBLE", "BYTE[]", "STRING", "LIST", "COMPOUND", "INT[]"};
+
-+ abstract void write(DataOutput dataoutput) throws IOException;
++ abstract void write(DataOutput dataoutput) throws java.io.IOException;
+
-+ abstract void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException;
++ abstract void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws java.io.IOException;
+
+ public abstract String toString();
+
@@ -1745,6 +3056,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ public abstract NBTBase clone();
+
++ public boolean isEmpty() {
++ return false;
++ }
++
+ public boolean equals(Object object) {
+ if (!(object instanceof NBTBase)) {
+ return false;
@@ -1762,6 +3077,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ protected String a_() {
+ return this.toString();
+ }
++
+}
diff --git a/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java b/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java
new file mode 100644
@@ -1773,8 +3089,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
-+import java.io.ByteArrayInputStream;
-+import java.io.ByteArrayOutputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.DataOutput;
@@ -1812,38 +3126,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } finally {
+ dataoutputstream.close();
+ }
-+ } catch (IOException ex) { org.spigotmc.SneakyThrow.sneaky( ex ); }
-+ }
-+
-+ public static NBTTagCompound a(byte[] abyte, NBTReadLimiter nbtreadlimiter) {
-+ try {
-+ DataInputStream datainputstream = new DataInputStream(new BufferedInputStream(new GZIPInputStream(new ByteArrayInputStream(abyte))));
-+
-+ NBTTagCompound nbttagcompound;
-+
-+ try {
-+ nbttagcompound = a((DataInput) datainputstream, nbtreadlimiter);
-+ } finally {
-+ datainputstream.close();
-+ }
-+
-+ return nbttagcompound;
-+ } catch (IOException ex) { org.spigotmc.SneakyThrow.sneaky( ex ); } return null;
-+ }
-+
-+ public static byte[] a(NBTTagCompound nbttagcompound) {
-+ try {
-+ ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
-+ DataOutputStream dataoutputstream = new DataOutputStream(new GZIPOutputStream(bytearrayoutputstream));
-+
-+ try {
-+ a(nbttagcompound, (DataOutput) dataoutputstream);
-+ } finally {
-+ dataoutputstream.close();
-+ }
-+
-+ return bytearrayoutputstream.toByteArray();
-+ } catch (IOException ex) { org.spigotmc.SneakyThrow.sneaky( ex ); } return null;
++ } catch (IOException ex) { org.spigotmc.SneakyThrow.sneaky( ex ); }
+ }
+
+ public static NBTTagCompound a(DataInputStream datainputstream) {
@@ -1873,7 +3156,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ dataoutput.writeUTF("");
+ nbtbase.write(dataoutput);
+ }
-+ } catch (IOException ex) { org.spigotmc.SneakyThrow.sneaky( ex ); }
++ } catch (IOException ex) { org.spigotmc.SneakyThrow.sneaky( ex ); }
+ }
+
+ private static NBTBase a(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) {
@@ -1893,8 +3176,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ CrashReport crashreport = CrashReport.a(ioexception, "Loading NBT data");
+ CrashReportSystemDetails crashreportsystemdetails = crashreport.a("NBT Tag");
+
-+ crashreportsystemdetails.a("Tag name", "[UNNAMED TAG]");
-+ crashreportsystemdetails.a("Tag type", Byte.valueOf(b0));
++ crashreportsystemdetails.a("Tag name", (Object) "[UNNAMED TAG]");
++ crashreportsystemdetails.a("Tag type", (Object) Byte.valueOf(b0));
+ throw new ReportedException(crashreport);
+ }
+ }
@@ -1911,7 +3194,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+import java.io.DataInput;
+import java.io.DataOutput;
-+import java.io.IOException;
+import java.util.Arrays;
+
+public class NBTTagByteArray extends NBTBase {
@@ -1924,12 +3206,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.data = abyte;
+ }
+
-+ void write(DataOutput dataoutput) throws IOException {
++ void write(DataOutput dataoutput) throws java.io.IOException {
+ dataoutput.writeInt(this.data.length);
+ dataoutput.write(this.data);
+ }
+
-+ void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException {
++ void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws java.io.IOException {
+ int j = datainput.readInt();
+
+ nbtreadlimiter.a((long) (8 * j));
@@ -1974,7 +3256,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+import java.io.DataInput;
+import java.io.DataOutput;
-+import java.io.IOException;
+import java.util.Arrays;
+
+public class NBTTagIntArray extends NBTBase {
@@ -1987,15 +3268,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.data = aint;
+ }
+
-+ void write(DataOutput dataoutput) throws IOException {
++ void write(DataOutput dataoutput) throws java.io.IOException {
+ dataoutput.writeInt(this.data.length);
+
+ for (int i = 0; i < this.data.length; ++i) {
+ dataoutput.writeInt(this.data[i]);
+ }
++
+ }
+
-+ void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException {
++ void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws java.io.IOException {
+ int j = datainput.readInt();
+
+ nbtreadlimiter.a((long) (32 * j));
@@ -2004,6 +3286,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ for (int k = 0; k < j; ++k) {
+ this.data[k] = datainput.readInt();
+ }
++
+ }
+
+ public byte getTypeId() {
@@ -2053,21 +3336,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+public class NextTickListEntry implements Comparable {
+
-+ private static long f;
-+ private final Block g;
-+ public int a;
-+ public int b;
++ private static long d;
++ private final Block e;
++ public final BlockPosition a;
++ public long b;
+ public int c;
-+ public long d;
-+ public int e;
-+ private long h;
++ private long f;
+
-+ public NextTickListEntry(int i, int j, int k, Block block) {
-+ this.h = (long) (f++);
-+ this.a = i;
-+ this.b = j;
-+ this.c = k;
-+ this.g = block;
++ public NextTickListEntry(BlockPosition blockposition, Block block) {
++ this.f = (long) (NextTickListEntry.d++);
++ this.a = blockposition;
++ this.e = block;
+ }
+
+ public boolean equals(Object object) {
@@ -2076,37 +3355,37 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } else {
+ NextTickListEntry nextticklistentry = (NextTickListEntry) object;
+
-+ return this.a == nextticklistentry.a && this.b == nextticklistentry.b && this.c == nextticklistentry.c && Block.a(this.g, nextticklistentry.g);
++ return this.a.equals(nextticklistentry.a) && Block.a(this.e, nextticklistentry.e);
+ }
+ }
+
+ public int hashCode() {
-+ return (this.a * 1024 * 1024 + this.c * 1024 + this.b) * 256;
++ return this.a.hashCode();
+ }
+
+ public NextTickListEntry a(long i) {
-+ this.d = i;
++ this.b = i;
+ return this;
+ }
+
+ public void a(int i) {
-+ this.e = i;
++ this.c = i;
+ }
+
-+ public int compareTo(NextTickListEntry nextticklistentry) {
-+ return this.d < nextticklistentry.d ? -1 : (this.d > nextticklistentry.d ? 1 : (this.e != nextticklistentry.e ? this.e - nextticklistentry.e : (this.h < nextticklistentry.h ? -1 : (this.h > nextticklistentry.h ? 1 : 0))));
++ public int a(NextTickListEntry nextticklistentry) {
++ return this.b < nextticklistentry.b ? -1 : (this.b > nextticklistentry.b ? 1 : (this.c != nextticklistentry.c ? this.c - nextticklistentry.c : (this.f < nextticklistentry.f ? -1 : (this.f > nextticklistentry.f ? 1 : 0))));
+ }
+
+ public String toString() {
-+ return Block.getId(this.g) + ": (" + this.a + ", " + this.b + ", " + this.c + "), " + this.d + ", " + this.e + ", " + this.h;
++ return Block.getId(this.e) + ": " + this.a + ", " + this.b + ", " + this.c + ", " + this.f;
+ }
+
+ public Block a() {
-+ return this.g;
++ return this.e;
+ }
+
+ public int compareTo(Object object) {
-+ return this.compareTo((NextTickListEntry) object);
++ return this.a((NextTickListEntry) object);
+ }
+}
diff --git a/src/main/java/net/minecraft/server/NibbleArray.java b/src/main/java/net/minecraft/server/NibbleArray.java
@@ -2119,40 +3398,58 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+public class NibbleArray {
+
-+ public final byte[] a;
-+ private final int b;
-+ private final int c;
++ private final byte[] a;
+
-+ public NibbleArray(int i, int j) {
-+ this.a = new byte[i >> 1];
-+ this.b = j;
-+ this.c = j + 4;
++ public NibbleArray() {
++ this.a = new byte[2048];
+ }
+
-+ public NibbleArray(byte[] abyte, int i) {
++ public NibbleArray(byte[] abyte) {
+ this.a = abyte;
-+ this.b = i;
-+ this.c = i + 4;
++ if (abyte.length != 2048) {
++ throw new IllegalArgumentException("ChunkNibbleArrays should be 2048 bytes not: " + abyte.length);
++ }
+ }
+
+ public int a(int i, int j, int k) {
-+ int l = j << this.c | k << this.b | i;
-+ int i1 = l >> 1;
-+ int j1 = l & 1;
-+
-+ return j1 == 0 ? this.a[i1] & 15 : this.a[i1] >> 4 & 15;
++ return this.a(this.b(i, j, k));
+ }
+
+ public void a(int i, int j, int k, int l) {
-+ int i1 = j << this.c | k << this.b | i;
-+ int j1 = i1 >> 1;
-+ int k1 = i1 & 1;
++ this.a(this.b(i, j, k), l);
++ }
+
-+ if (k1 == 0) {
-+ this.a[j1] = (byte) (this.a[j1] & 240 | l & 15);
++ private int b(int i, int j, int k) {
++ return j << 8 | k << 4 | i;
++ }
++
++ public int a(int i) {
++ int j = this.c(i);
++
++ return this.b(i) ? this.a[j] & 15 : this.a[j] >> 4 & 15;
++ }
++
++ public void a(int i, int j) {
++ int k = this.c(i);
++
++ if (this.b(i)) {
++ this.a[k] = (byte) (this.a[k] & 240 | j & 15);
+ } else {
-+ this.a[j1] = (byte) (this.a[j1] & 15 | (l & 15) << 4);
++ this.a[k] = (byte) (this.a[k] & 15 | (j & 15) << 4);
+ }
++
++ }
++
++ private boolean b(int i) {
++ return (i & 1) == 0;
++ }
++
++ private int c(int i) {
++ return i >> 1;
++ }
++
++ public byte[] a() {
++ return this.a;
+ }
+}
diff --git a/src/main/java/net/minecraft/server/OldChunkLoader.java b/src/main/java/net/minecraft/server/OldChunkLoader.java
@@ -2235,9 +3532,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ if (!flag) {
+ byte[] abyte = new byte[4096];
-+ NibbleArray nibblearray = new NibbleArray(abyte.length, 4);
-+ NibbleArray nibblearray1 = new NibbleArray(abyte.length, 4);
-+ NibbleArray nibblearray2 = new NibbleArray(abyte.length, 4);
++ NibbleArray nibblearray = new NibbleArray();
++ NibbleArray nibblearray1 = new NibbleArray();
++ NibbleArray nibblearray2 = new NibbleArray();
+
+ for (int k1 = 0; k1 < 16; ++k1) {
+ for (int l1 = 0; l1 < 16; ++l1) {
@@ -2257,9 +3554,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ nbttagcompound1.setByte("Y", (byte) (k & 255));
+ nbttagcompound1.setByteArray("Blocks", abyte);
-+ nbttagcompound1.setByteArray("Data", nibblearray.a);
-+ nbttagcompound1.setByteArray("SkyLight", nibblearray1.a);
-+ nbttagcompound1.setByteArray("BlockLight", nibblearray2.a);
++ nbttagcompound1.setByteArray("Data", nibblearray.a());
++ nbttagcompound1.setByteArray("SkyLight", nibblearray1.a());
++ nbttagcompound1.setByteArray("BlockLight", nibblearray2.a());
+ nbttaglist.add(nbttagcompound1);
+ }
+ }
@@ -2269,7 +3566,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ for (int k2 = 0; k2 < 16; ++k2) {
+ for (j = 0; j < 16; ++j) {
-+ abyte1[j << 4 | k2] = (byte) (worldchunkmanager.getBiome(oldchunk.k << 4 | k2, oldchunk.l << 4 | j).id & 255);
++ abyte1[j << 4 | k2] = (byte) (worldchunkmanager.getBiome(new BlockPosition(oldchunk.k << 4 | k2, 0, oldchunk.l << 4 | j), BiomeBase.ad).id & 255);
+ }
+ }
+
@@ -2279,6 +3576,96 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (oldchunk.j != null) {
+ nbttagcompound.set("TileTicks", oldchunk.j);
+ }
++
++ }
++}
+diff --git a/src/main/java/net/minecraft/server/PacketHandshakingInSetProtocol.java b/src/main/java/net/minecraft/server/PacketHandshakingInSetProtocol.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/net/minecraft/server/PacketHandshakingInSetProtocol.java
+@@ -0,0 +0,0 @@
++package net.minecraft.server;
++
++public class PacketHandshakingInSetProtocol implements Packet {
++
++ private int a;
++ public String b;
++ public int c;
++ private EnumProtocol d;
++
++ public PacketHandshakingInSetProtocol() {}
++
++ public void a(PacketDataSerializer packetdataserializer) {
++ this.a = packetdataserializer.e();
++ this.b = packetdataserializer.c(255);
++ this.c = packetdataserializer.readUnsignedShort();
++ this.d = EnumProtocol.a(packetdataserializer.e());
++ }
++
++ public void b(PacketDataSerializer packetdataserializer) {
++ packetdataserializer.b(this.a);
++ packetdataserializer.a(this.b);
++ packetdataserializer.writeShort(this.c);
++ packetdataserializer.b(this.d.a());
++ }
++
++ public void a(PacketHandshakingInListener packethandshakinginlistener) {
++ packethandshakinginlistener.a(this);
++ }
++
++ public EnumProtocol a() {
++ return this.d;
++ }
++
++ public int b() {
++ return this.a;
++ }
++
++ public void a(PacketListener packetlistener) {
++ this.a((PacketHandshakingInListener) packetlistener);
++ }
++}
+diff --git a/src/main/java/net/minecraft/server/PacketPlayInChat.java b/src/main/java/net/minecraft/server/PacketPlayInChat.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/net/minecraft/server/PacketPlayInChat.java
+@@ -0,0 +0,0 @@
++package net.minecraft.server;
++
++public class PacketPlayInChat implements Packet {
++
++ private String a;
++
++ public PacketPlayInChat() {}
++
++ public PacketPlayInChat(String s) {
++ if (s.length() > 100) {
++ s = s.substring(0, 100);
++ }
++
++ this.a = s;
++ }
++
++ public void a(PacketDataSerializer packetdataserializer) {
++ this.a = packetdataserializer.c(100);
++ }
++
++ public void b(PacketDataSerializer packetdataserializer) {
++ packetdataserializer.a(this.a);
++ }
++
++ public void a(PacketListenerPlayIn packetlistenerplayin) {
++ packetlistenerplayin.a(this);
++ }
++
++ public String a() {
++ return this.a;
++ }
++
++ public void a(PacketListener packetlistener) {
++ this.a((PacketListenerPlayIn) packetlistener);
+ }
+}
diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
@@ -2289,191 +3676,204 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@
+package net.minecraft.server;
+
-+import java.io.IOException;
-+import java.util.zip.DataFormatException;
-+import java.util.zip.Deflater;
-+import java.util.zip.Inflater;
++import com.google.common.collect.Lists;
++import java.util.ArrayList;
++import java.util.Iterator;
+
-+public class PacketPlayOutMapChunk extends Packet {
++public class PacketPlayOutMapChunk implements Packet {
+
+ private int a;
+ private int b;
-+ private int c;
-+ private int d;
-+ private byte[] e;
-+ private byte[] f;
-+ private boolean g;
-+ private int h;
-+ private static byte[] i = new byte[196864];
++ private ChunkMap c;
++ private boolean d;
+
+ public PacketPlayOutMapChunk() {}
+
+ public PacketPlayOutMapChunk(Chunk chunk, boolean flag, int i) {
+ this.a = chunk.locX;
+ this.b = chunk.locZ;
-+ this.g = flag;
-+ ChunkMap chunkmap = a(chunk, flag, i);
-+ Deflater deflater = new Deflater(-1);
-+
-+ this.d = chunkmap.c;
-+ this.c = chunkmap.b;
-+
-+ try {
-+ this.f = chunkmap.a;
-+ deflater.setInput(chunkmap.a, 0, chunkmap.a.length);
-+ deflater.finish();
-+ this.e = new byte[chunkmap.a.length];
-+ this.h = deflater.deflate(this.e);
-+ } finally {
-+ deflater.end();
-+ }
++ this.d = flag;
++ this.c = a(chunk, flag, !chunk.getWorld().worldProvider.o(), i);
+ }
+
-+ public static int c() {
-+ return 196864;
-+ }
-+
-+ public void a(PacketDataSerializer packetdataserializer) throws IOException {
++ public void a(PacketDataSerializer packetdataserializer) {
+ this.a = packetdataserializer.readInt();
+ this.b = packetdataserializer.readInt();
-+ this.g = packetdataserializer.readBoolean();
-+ this.c = packetdataserializer.readShort();
-+ this.d = packetdataserializer.readShort();
-+ this.h = packetdataserializer.readInt();
-+ if (i.length < this.h) {
-+ i = new byte[this.h];
-+ }
-+
-+ packetdataserializer.readBytes(i, 0, this.h);
-+ int i = 0;
-+
-+ int j;
-+
-+ for (j = 0; j < 16; ++j) {
-+ i += this.c >> j & 1;
-+ }
-+
-+ j = 12288 * i;
-+ if (this.g) {
-+ j += 256;
-+ }
-+
-+ this.f = new byte[j];
-+ Inflater inflater = new Inflater();
-+
-+ inflater.setInput(PacketPlayOutMapChunk.i, 0, this.h);
-+
-+ try {
-+ inflater.inflate(this.f);
-+ } catch (DataFormatException dataformatexception) {
-+ throw new IOException("Bad compressed data format");
-+ } finally {
-+ inflater.end();
-+ }
++ this.d = packetdataserializer.readBoolean();
++ this.c = new ChunkMap();
++ this.c.b = packetdataserializer.readShort();
++ this.c.a = packetdataserializer.a();
+ }
+
+ public void b(PacketDataSerializer packetdataserializer) {
+ packetdataserializer.writeInt(this.a);
+ packetdataserializer.writeInt(this.b);
-+ packetdataserializer.writeBoolean(this.g);
-+ packetdataserializer.writeShort((short) (this.c & '\uffff'));
-+ packetdataserializer.writeShort((short) (this.d & '\uffff'));
-+ packetdataserializer.writeInt(this.h);
-+ packetdataserializer.writeBytes(this.e, 0, this.h);
++ packetdataserializer.writeBoolean(this.d);
++ packetdataserializer.writeShort((short) (this.c.b & '\uffff'));
++ packetdataserializer.a(this.c.a);
+ }
+
-+ public void a(PacketPlayOutListener packetplayoutlistener) {
-+ packetplayoutlistener.a(this);
++ public void a(PacketListenerPlayOut packetlistenerplayout) {
++ packetlistenerplayout.a(this);
+ }
+
-+ public String b() {
-+ return String.format("x=%d, z=%d, full=%b, sects=%d, add=%d, size=%d", new Object[] { Integer.valueOf(this.a), Integer.valueOf(this.b), Boolean.valueOf(this.g), Integer.valueOf(this.c), Integer.valueOf(this.d), Integer.valueOf(this.h)});
++ protected static int a(int i, boolean flag, boolean flag1) {
++ int j = i * 2 * 16 * 16 * 16;
++ int k = i * 16 * 16 * 16 / 2;
++ int l = flag ? i * 16 * 16 * 16 / 2 : 0;
++ int i1 = flag1 ? 256 : 0;
++
++ return j + k + l + i1;
+ }
+
-+ public static ChunkMap a(Chunk chunk, boolean flag, int i) {
-+ int j = 0;
++ public static ChunkMap a(Chunk chunk, boolean flag, boolean flag1, int i) {
+ ChunkSection[] achunksection = chunk.getSections();
-+ int k = 0;
+ ChunkMap chunkmap = new ChunkMap();
-+ byte[] abyte = PacketPlayOutMapChunk.i;
++ ArrayList arraylist = Lists.newArrayList();
+
-+ if (flag) {
-+ chunk.q = true;
-+ }
++ int j;
+
-+ int l;
++ for (j = 0; j < achunksection.length; ++j) {
++ ChunkSection chunksection = achunksection[j];
+
-+ for (l = 0; l < achunksection.length; ++l) {
-+ if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && (i & 1 << l) != 0) {
-+ chunkmap.b |= 1 << l;
-+ if (achunksection[l].getExtendedIdArray() != null) {
-+ chunkmap.c |= 1 << l;
-+ ++k;
-+ }
++ if (chunksection != null && (!flag || !chunksection.a()) && (i & 1 << j) != 0) {
++ chunkmap.b |= 1 << j;
++ arraylist.add(chunksection);
+ }
+ }
+
-+ for (l = 0; l < achunksection.length; ++l) {
-+ if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && (i & 1 << l) != 0) {
-+ byte[] abyte1 = achunksection[l].getIdArray();
++ chunkmap.a = new byte[a(Integer.bitCount(chunkmap.b), flag1, flag)];
++ j = 0;
++ Iterator iterator = arraylist.iterator();
+
-+ System.arraycopy(abyte1, 0, abyte, j, abyte1.length);
-+ j += abyte1.length;
++ ChunkSection chunksection1;
++
++ while (iterator.hasNext()) {
++ chunksection1 = (ChunkSection) iterator.next();
++ char[] achar = chunksection1.getIdArray();
++ char[] achar1 = achar;
++ int k = achar.length;
++
++ for (int l = 0; l < k; ++l) {
++ char c0 = achar1[l];
++
++ chunkmap.a[j++] = (byte) (c0 & 255);
++ chunkmap.a[j++] = (byte) (c0 >> 8 & 255);
+ }
+ }
+
-+ NibbleArray nibblearray;
-+
-+ for (l = 0; l < achunksection.length; ++l) {
-+ if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && (i & 1 << l) != 0) {
-+ nibblearray = achunksection[l].getDataArray();
-+ System.arraycopy(nibblearray.a, 0, abyte, j, nibblearray.a.length);
-+ j += nibblearray.a.length;
-+ }
++ for (iterator = arraylist.iterator(); iterator.hasNext(); j = a(chunksection1.getEmittedLightArray().a(), chunkmap.a, j)) {
++ chunksection1 = (ChunkSection) iterator.next();
+ }
+
-+ for (l = 0; l < achunksection.length; ++l) {
-+ if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && (i & 1 << l) != 0) {
-+ nibblearray = achunksection[l].getEmittedLightArray();
-+ System.arraycopy(nibblearray.a, 0, abyte, j, nibblearray.a.length);
-+ j += nibblearray.a.length;
-+ }
-+ }
-+
-+ if (!chunk.world.worldProvider.g) {
-+ for (l = 0; l < achunksection.length; ++l) {
-+ if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && (i & 1 << l) != 0) {
-+ nibblearray = achunksection[l].getSkyLightArray();
-+ System.arraycopy(nibblearray.a, 0, abyte, j, nibblearray.a.length);
-+ j += nibblearray.a.length;
-+ }
-+ }
-+ }
-+
-+ if (k > 0) {
-+ for (l = 0; l < achunksection.length; ++l) {
-+ if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && achunksection[l].getExtendedIdArray() != null && (i & 1 << l) != 0) {
-+ nibblearray = achunksection[l].getExtendedIdArray();
-+ System.arraycopy(nibblearray.a, 0, abyte, j, nibblearray.a.length);
-+ j += nibblearray.a.length;
-+ }
++ if (flag1) {
++ for (iterator = arraylist.iterator(); iterator.hasNext(); j = a(chunksection1.getSkyLightArray().a(), chunkmap.a, j)) {
++ chunksection1 = (ChunkSection) iterator.next();
+ }
+ }
+
+ if (flag) {
-+ byte[] abyte2 = chunk.m();
-+
-+ System.arraycopy(abyte2, 0, abyte, j, abyte2.length);
-+ j += abyte2.length;
++ a(chunk.getBiomeIndex(), chunkmap.a, j);
+ }
+
-+ chunkmap.a = new byte[j];
-+ System.arraycopy(abyte, 0, chunkmap.a, 0, j);
+ return chunkmap;
+ }
+
-+ public void handle(PacketListener packetlistener) {
-+ this.a((PacketPlayOutListener) packetlistener);
++ private static int a(byte[] abyte, byte[] abyte1, int i) {
++ System.arraycopy(abyte, 0, abyte1, i, abyte.length);
++ return i + abyte.length;
++ }
++
++ public void a(PacketListener packetlistener) {
++ this.a((PacketListenerPlayOut) packetlistener);
++ }
++}
+diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java
+@@ -0,0 +0,0 @@
++package net.minecraft.server;
++
++import java.util.List;
++
++public class PacketPlayOutMapChunkBulk implements Packet {
++
++ private int[] a;
++ private int[] b;
++ private ChunkMap[] c;
++ private boolean d;
++
++ public PacketPlayOutMapChunkBulk() {}
++
++ public PacketPlayOutMapChunkBulk(List list) {
++ int i = list.size();
++
++ this.a = new int[i];
++ this.b = new int[i];
++ this.c = new ChunkMap[i];
++ this.d = !((Chunk) list.get(0)).getWorld().worldProvider.o();
++
++ for (int j = 0; j < i; ++j) {
++ Chunk chunk = (Chunk) list.get(j);
++ ChunkMap chunkmap = PacketPlayOutMapChunk.a(chunk, true, this.d, '\uffff');
++
++ this.a[j] = chunk.locX;
++ this.b[j] = chunk.locZ;
++ this.c[j] = chunkmap;
++ }
++
++ }
++
++ public void a(PacketDataSerializer packetdataserializer) {
++ this.d = packetdataserializer.readBoolean();
++ int i = packetdataserializer.e();
++
++ this.a = new int[i];
++ this.b = new int[i];
++ this.c = new ChunkMap[i];
++
++ int j;
++
++ for (j = 0; j < i; ++j) {
++ this.a[j] = packetdataserializer.readInt();
++ this.b[j] = packetdataserializer.readInt();
++ this.c[j] = new ChunkMap();
++ this.c[j].b = packetdataserializer.readShort() & '\uffff';
++ this.c[j].a = new byte[PacketPlayOutMapChunk.a(Integer.bitCount(this.c[j].b), this.d, true)];
++ }
++
++ for (j = 0; j < i; ++j) {
++ packetdataserializer.readBytes(this.c[j].a);
++ }
++
++ }
++
++ public void b(PacketDataSerializer packetdataserializer) {
++ packetdataserializer.writeBoolean(this.d);
++ packetdataserializer.b(this.c.length);
++
++ int i;
++
++ for (i = 0; i < this.a.length; ++i) {
++ packetdataserializer.writeInt(this.a[i]);
++ packetdataserializer.writeInt(this.b[i]);
++ packetdataserializer.writeShort((short) (this.c[i].b & '\uffff'));
++ }
++
++ for (i = 0; i < this.a.length; ++i) {
++ packetdataserializer.writeBytes(this.c[i].a);
++ }
++
++ }
++
++ public void a(PacketListenerPlayOut packetlistenerplayout) {
++ packetlistenerplayout.a(this);
++ }
++
++ public void a(PacketListener packetlistener) {
++ this.a((PacketListenerPlayOut) packetlistener);
+ }
+}
diff --git a/src/main/java/net/minecraft/server/PacketPlayOutOpenWindow.java b/src/main/java/net/minecraft/server/PacketPlayOutOpenWindow.java
@@ -2484,60 +3884,105 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@
+package net.minecraft.server;
+
-+import java.io.IOException;
-+
-+public class PacketPlayOutOpenWindow extends Packet {
++public class PacketPlayOutOpenWindow implements Packet {
+
+ private int a;
-+ private int b;
-+ private String c;
++ private String b;
++ private IChatBaseComponent c;
+ private int d;
-+ private boolean e;
-+ private int f;
++ private int e;
+
+ public PacketPlayOutOpenWindow() {}
+
-+ public PacketPlayOutOpenWindow(int i, int j, String s, int k, boolean flag) {
++ public PacketPlayOutOpenWindow(int i, String s, IChatBaseComponent ichatbasecomponent) {
++ this(i, s, ichatbasecomponent, 0);
++ }
++
++ public PacketPlayOutOpenWindow(int i, String s, IChatBaseComponent ichatbasecomponent, int j) {
+ this.a = i;
-+ this.b = j;
-+ this.c = s;
-+ this.d = k;
-+ this.e = flag;
++ this.b = s;
++ this.c = ichatbasecomponent;
++ this.d = j;
+ }
+
-+ public PacketPlayOutOpenWindow(int i, int j, String s, int k, boolean flag, int l) {
-+ this(i, j, s, k, flag);
-+ this.f = l;
++ public PacketPlayOutOpenWindow(int i, String s, IChatBaseComponent ichatbasecomponent, int j, int k) {
++ this(i, s, ichatbasecomponent, j);
++ this.e = k;
+ }
+
-+ public void a(PacketPlayOutListener packetplayoutlistener) {
-+ packetplayoutlistener.a(this);
++ public void a(PacketListenerPlayOut packetlistenerplayout) {
++ packetlistenerplayout.a(this);
+ }
+
-+ public void a(PacketDataSerializer packetdataserializer) throws IOException {
++ public void a(PacketDataSerializer packetdataserializer) {
+ this.a = packetdataserializer.readUnsignedByte();
-+ this.b = packetdataserializer.readUnsignedByte();
-+ this.c = packetdataserializer.c(32);
++ this.b = packetdataserializer.c(32);
++ this.c = packetdataserializer.d();
+ this.d = packetdataserializer.readUnsignedByte();
-+ this.e = packetdataserializer.readBoolean();
-+ if (this.b == 11) {
-+ this.f = packetdataserializer.readInt();
++ if (this.b.equals("EntityHorse")) {
++ this.e = packetdataserializer.readInt();
+ }
++
+ }
+
-+ public void b(PacketDataSerializer packetdataserializer) throws IOException {
++ public void b(PacketDataSerializer packetdataserializer) {
+ packetdataserializer.writeByte(this.a);
-+ packetdataserializer.writeByte(this.b);
++ packetdataserializer.a(this.b);
+ packetdataserializer.a(this.c);
+ packetdataserializer.writeByte(this.d);
-+ packetdataserializer.writeBoolean(this.e);
-+ if (this.b == 11) {
-+ packetdataserializer.writeInt(this.f);
++ if (this.b.equals("EntityHorse")) {
++ packetdataserializer.writeInt(this.e);
+ }
++
+ }
+
-+ public void handle(PacketListener packetlistener) {
-+ this.a((PacketPlayOutListener) packetlistener);
++ public void a(PacketListener packetlistener) {
++ this.a((PacketListenerPlayOut) packetlistener);
++ }
++}
+diff --git a/src/main/java/net/minecraft/server/PathfinderGoalSwell.java b/src/main/java/net/minecraft/server/PathfinderGoalSwell.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/net/minecraft/server/PathfinderGoalSwell.java
+@@ -0,0 +0,0 @@
++package net.minecraft.server;
++
++public class PathfinderGoalSwell extends PathfinderGoal {
++
++ EntityCreeper a;
++ EntityLiving b;
++
++ public PathfinderGoalSwell(EntityCreeper entitycreeper) {
++ this.a = entitycreeper;
++ this.a(1);
++ }
++
++ public boolean a() {
++ EntityLiving entityliving = this.a.getGoalTarget();
++
++ return this.a.ck() > 0 || entityliving != null && this.a.h(entityliving) < 9.0D;
++ }
++
++ public void c() {
++ this.a.getNavigation().n();
++ this.b = this.a.getGoalTarget();
++ }
++
++ public void d() {
++ this.b = null;
++ }
++
++ public void e() {
++ if (this.b == null) {
++ this.a.a(-1);
++ } else if (this.a.h(this.b) > 49.0D) {
++ this.a.a(-1);
++ } else if (!this.a.getEntitySenses().a(this.b)) {
++ this.a.a(-1);
++ } else {
++ this.a.a(1);
++ }
+ }
+}
diff --git a/src/main/java/net/minecraft/server/PersistentCollection.java b/src/main/java/net/minecraft/server/PersistentCollection.java
@@ -2548,6 +3993,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@
+package net.minecraft.server;
+
++import com.google.common.collect.Lists;
++import com.google.common.collect.Maps;
+import java.io.DataInputStream;
+import java.io.DataOutput;
+import java.io.DataOutputStream;
@@ -2556,42 +4003,40 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
-+import java.util.ArrayList;
-+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public class PersistentCollection {
+
-+ private IDataManager a;
-+ private Map b = new HashMap();
-+ private List c = new ArrayList();
-+ private Map d = new HashMap();
++ private IDataManager b;
++ protected Map a = Maps.newHashMap();
++ private List c = Lists.newArrayList();
++ private Map d = Maps.newHashMap();
+
+ public PersistentCollection(IDataManager idatamanager) {
-+ this.a = idatamanager;
++ this.b = idatamanager;
+ this.b();
+ }
+
+ public PersistentBase get(Class oclass, String s) {
-+ PersistentBase persistentbase = (PersistentBase) this.b.get(s);
++ PersistentBase persistentbase = (PersistentBase) this.a.get(s);
+
+ if (persistentbase != null) {
+ return persistentbase;
+ } else {
-+ if (this.a != null) {
++ if (this.b != null) {
+ try {
-+ File file1 = this.a.getDataFile(s);
++ File file = this.b.getDataFile(s);
+
-+ if (file1 != null && file1.exists()) {
++ if (file != null && file.exists()) {
+ try {
+ persistentbase = (PersistentBase) oclass.getConstructor(new Class[] { String.class}).newInstance(new Object[] { s});
+ } catch (Exception exception) {
+ throw new RuntimeException("Failed to instantiate " + oclass.toString(), exception);
+ }
+
-+ FileInputStream fileinputstream = new FileInputStream(file1);
++ FileInputStream fileinputstream = new FileInputStream(file);
+ NBTTagCompound nbttagcompound = NBTCompressedStreamTools.a((InputStream) fileinputstream);
+
+ fileinputstream.close();
@@ -2603,7 +4048,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ if (persistentbase != null) {
-+ this.b.put(s, persistentbase);
++ this.a.put(s, persistentbase);
+ this.c.add(persistentbase);
+ }
+
@@ -2612,16 +4057,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ public void a(String s, PersistentBase persistentbase) {
-+ if (persistentbase == null) {
-+ throw new RuntimeException("Can\'t set null data");
-+ } else {
-+ if (this.b.containsKey(s)) {
-+ this.c.remove(this.b.remove(s));
-+ }
-+
-+ this.b.put(s, persistentbase);
-+ this.c.add(persistentbase);
++ if (this.a.containsKey(s)) {
++ this.c.remove(this.a.remove(s));
+ }
++
++ this.a.put(s, persistentbase);
++ this.c.add(persistentbase);
+ }
+
+ public void a() {
@@ -2633,21 +4074,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ persistentbase.a(false);
+ }
+ }
++
+ }
+
+ private void a(PersistentBase persistentbase) {
-+ if (this.a != null) {
++ if (this.b != null) {
+ try {
-+ File file1 = this.a.getDataFile(persistentbase.id);
++ File file = this.b.getDataFile(persistentbase.id);
+
-+ if (file1 != null) {
++ if (file != null) {
+ NBTTagCompound nbttagcompound = new NBTTagCompound();
+
+ persistentbase.b(nbttagcompound);
+ NBTTagCompound nbttagcompound1 = new NBTTagCompound();
+
+ nbttagcompound1.set("data", nbttagcompound);
-+ FileOutputStream fileoutputstream = new FileOutputStream(file1);
++ FileOutputStream fileoutputstream = new FileOutputStream(file);
+
+ NBTCompressedStreamTools.a(nbttagcompound1, (OutputStream) fileoutputstream);
+ fileoutputstream.close();
@@ -2655,20 +4097,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
++
+ }
+ }
+
+ private void b() {
+ try {
+ this.d.clear();
-+ if (this.a == null) {
++ if (this.b == null) {
+ return;
+ }
+
-+ File file1 = this.a.getDataFile("idcounts");
++ File file = this.b.getDataFile("idcounts");
+
-+ if (file1 != null && file1.exists()) {
-+ DataInputStream datainputstream = new DataInputStream(new FileInputStream(file1));
++ if (file != null && file.exists()) {
++ DataInputStream datainputstream = new DataInputStream(new FileInputStream(file));
+ NBTTagCompound nbttagcompound = NBTCompressedStreamTools.a(datainputstream);
+
+ datainputstream.close();
@@ -2680,15 +4123,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ if (nbtbase instanceof NBTTagShort) {
+ NBTTagShort nbttagshort = (NBTTagShort) nbtbase;
-+ short short1 = nbttagshort.e();
++ short short0 = nbttagshort.e();
+
-+ this.d.put(s, Short.valueOf(short1));
++ this.d.put(s, Short.valueOf(short0));
+ }
+ }
+ }
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
++
+ }
+
+ public int a(String s) {
@@ -2701,24 +4145,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ this.d.put(s, oshort);
-+ if (this.a == null) {
++ if (this.b == null) {
+ return oshort.shortValue();
+ } else {
+ try {
-+ File file1 = this.a.getDataFile("idcounts");
++ File file = this.b.getDataFile("idcounts");
+
-+ if (file1 != null) {
++ if (file != null) {
+ NBTTagCompound nbttagcompound = new NBTTagCompound();
+ Iterator iterator = this.d.keySet().iterator();
+
+ while (iterator.hasNext()) {
+ String s1 = (String) iterator.next();
-+ short short1 = ((Short) this.d.get(s1)).shortValue();
++ short short0 = ((Short) this.d.get(s1)).shortValue();
+
-+ nbttagcompound.setShort(s1, short1);
++ nbttagcompound.setShort(s1, short0);
+ }
+
-+ DataOutputStream dataoutputstream = new DataOutputStream(new FileOutputStream(file1));
++ DataOutputStream dataoutputstream = new DataOutputStream(new FileOutputStream(file));
+
+ NBTCompressedStreamTools.a(nbttagcompound, (DataOutput) dataoutputstream);
+ dataoutputstream.close();
@@ -2739,43 +4183,43 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@
+package net.minecraft.server;
+
++import com.google.common.collect.Maps;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.IOException;
-+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+public class RegionFileCache {
+
-+ private static final Map a = new HashMap();
++ private static final Map a = Maps.newHashMap();
+
-+ public static synchronized RegionFile a(File file1, int i, int j) {
-+ File file2 = new File(file1, "region");
-+ File file3 = new File(file2, "r." + (i >> 5) + "." + (j >> 5) + ".mca");
-+ RegionFile regionfile = (RegionFile) a.get(file3);
++ public static synchronized RegionFile a(File file, int i, int j) {
++ File file1 = new File(file, "region");
++ File file2 = new File(file1, "r." + (i >> 5) + "." + (j >> 5) + ".mca");
++ RegionFile regionfile = (RegionFile) RegionFileCache.a.get(file2);
+
+ if (regionfile != null) {
+ return regionfile;
+ } else {
-+ if (!file2.exists()) {
-+ file2.mkdirs();
++ if (!file1.exists()) {
++ file1.mkdirs();
+ }
+
-+ if (a.size() >= 256) {
++ if (RegionFileCache.a.size() >= 256) {
+ a();
+ }
+
-+ RegionFile regionfile1 = new RegionFile(file3);
++ RegionFile regionfile1 = new RegionFile(file2);
+
-+ a.put(file3, regionfile1);
++ RegionFileCache.a.put(file2, regionfile1);
+ return regionfile1;
+ }
+ }
+
+ public static synchronized void a() {
-+ Iterator iterator = a.values().iterator();
++ Iterator iterator = RegionFileCache.a.values().iterator();
+
+ while (iterator.hasNext()) {
+ RegionFile regionfile = (RegionFile) iterator.next();
@@ -2789,20 +4233,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ }
+
-+ a.clear();
++ RegionFileCache.a.clear();
+ }
+
-+ public static DataInputStream c(File file1, int i, int j) {
-+ RegionFile regionfile = a(file1, i, j);
++ public static DataInputStream c(File file, int i, int j) {
++ RegionFile regionfile = a(file, i, j);
+
+ return regionfile.a(i & 31, j & 31);
+ }
+
-+ public static DataOutputStream d(File file1, int i, int j) {
-+ RegionFile regionfile = a(file1, i, j);
++ public static DataOutputStream d(File file, int i, int j) {
++ RegionFile regionfile = a(file, i, j);
+
+ return regionfile.b(i & 31, j & 31);
+ }
++
+}
diff --git a/src/main/java/net/minecraft/server/ServerConnection.java b/src/main/java/net/minecraft/server/ServerConnection.java
new file mode 100644
@@ -2812,105 +4257,109 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@
+package net.minecraft.server;
+
++import com.google.common.collect.Lists;
++import io.netty.bootstrap.ServerBootstrap;
++import io.netty.channel.ChannelFuture;
++import io.netty.channel.EventLoopGroup;
++import io.netty.channel.socket.nio.NioServerSocketChannel;
++import io.netty.util.concurrent.GenericFutureListener;
+import java.net.InetAddress;
-+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.Callable;
-+
-+import net.minecraft.util.com.google.common.util.concurrent.ThreadFactoryBuilder;
-+import net.minecraft.util.io.netty.bootstrap.ServerBootstrap;
-+import net.minecraft.util.io.netty.channel.ChannelFuture;
-+import net.minecraft.util.io.netty.channel.nio.NioEventLoopGroup;
-+import net.minecraft.util.io.netty.channel.socket.nio.NioServerSocketChannel;
-+import net.minecraft.util.io.netty.util.concurrent.GenericFutureListener;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+public class ServerConnection {
+
-+ private static final Logger b = LogManager.getLogger();
-+ private static final NioEventLoopGroup c = new NioEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty IO #%d").setDaemon(true).build());
-+ private final MinecraftServer d;
-+ public volatile boolean a;
-+ private final List e = Collections.synchronizedList(new ArrayList());
-+ private final List f = Collections.synchronizedList(new ArrayList());
++ private static final Logger d = LogManager.getLogger();
++ public static final LazyInitVar a = new LazyInitNioEventLoopGroup();
++ public static final LazyInitVar b = new LazyInitLocalEventLoopGroup();
++ private final MinecraftServer e;
++ public volatile boolean c;
++ private final List f = Collections.synchronizedList(Lists.newArrayList());
++ private final List g = Collections.synchronizedList(Lists.newArrayList());
+
+ public ServerConnection(MinecraftServer minecraftserver) {
-+ this.d = minecraftserver;
-+ this.a = true;
++ this.e = minecraftserver;
++ this.c = true;
+ }
+
+ public void a(InetAddress inetaddress, int i) {
-+ List list = this.e;
++ List list = this.f;
+
-+ synchronized (this.e) {
-+ this.e.add(((ServerBootstrap) ((ServerBootstrap) (new ServerBootstrap()).channel(NioServerSocketChannel.class)).childHandler(new ServerConnectionChannel(this)).group(c).localAddress(inetaddress, i)).bind().syncUninterruptibly());
++ synchronized (this.f) {
++ this.f.add(((ServerBootstrap) ((ServerBootstrap) (new ServerBootstrap()).channel(NioServerSocketChannel.class)).childHandler(new ServerConnectionChannel(this)).group((EventLoopGroup) ServerConnection.a.c()).localAddress(inetaddress, i)).bind().syncUninterruptibly());
+ }
+ }
+
+ public void b() {
-+ this.a = false;
-+ Iterator iterator = this.e.iterator();
++ this.c = false;
++ Iterator iterator = this.f.iterator();
+
+ while (iterator.hasNext()) {
+ ChannelFuture channelfuture = (ChannelFuture) iterator.next();
+
-+ channelfuture.channel().close().syncUninterruptibly();
++ try {
++ channelfuture.channel().close().sync();
++ } catch (InterruptedException interruptedexception) {
++ ServerConnection.d.error("Interrupted whilst closing channel");
++ }
+ }
++
+ }
+
+ public void c() {
-+ List list = this.f;
++ List list = this.g;
+
-+ synchronized (this.f) {
-+ Iterator iterator = this.f.iterator();
++ synchronized (this.g) {
++ Iterator iterator = this.g.iterator();
+
+ while (iterator.hasNext()) {
+ NetworkManager networkmanager = (NetworkManager) iterator.next();
+
-+ if (!networkmanager.isConnected()) {
-+ iterator.remove();
-+ if (networkmanager.f() != null) {
-+ networkmanager.getPacketListener().a(networkmanager.f());
-+ } else if (networkmanager.getPacketListener() != null) {
-+ networkmanager.getPacketListener().a(new ChatComponentText("Disconnected"));
-+ }
-+ } else {
-+ try {
-+ networkmanager.a();
-+ } catch (Exception exception) {
-+ if (networkmanager.c()) {
-+ CrashReport crashreport = CrashReport.a(exception, "Ticking memory connection");
-+ CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Ticking connection");
++ if (!networkmanager.h()) {
++ if (!networkmanager.g()) {
++ iterator.remove();
++ networkmanager.l();
++ } else {
++ try {
++ networkmanager.a();
++ } catch (Exception exception) {
++ if (networkmanager.c()) {
++ CrashReport crashreport = CrashReport.a(exception, "Ticking memory connection");
++ CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Ticking connection");
+
-+ crashreportsystemdetails.a("Connection", (Callable) (new CrashReportServerConnection(this, networkmanager)));
-+ throw new ReportedException(crashreport);
++ crashreportsystemdetails.a("Connection", (Callable) (new CrashReportNetworkManager(this, networkmanager)));
++ throw new ReportedException(crashreport);
++ }
++
++ ServerConnection.d.warn("Failed to handle packet for " + networkmanager.getSocketAddress(), exception);
++ ChatComponentText chatcomponenttext = new ChatComponentText("Internal server error");
++
++ networkmanager.a(new PacketPlayOutKickDisconnect(chatcomponenttext), new NetworkManagerCloseFuture(this, networkmanager, chatcomponenttext), new GenericFutureListener[0]);
++ networkmanager.k();
+ }
-+
-+ b.warn("Failed to handle packet for " + networkmanager.getSocketAddress(), exception);
-+ ChatComponentText chatcomponenttext = new ChatComponentText("Internal server error");
-+
-+ networkmanager.handle(new PacketPlayOutKickDisconnect(chatcomponenttext), new GenericFutureListener[] { new ServerConnectionFuture(this, networkmanager, chatcomponenttext)});
-+ networkmanager.g();
+ }
+ }
+ }
++
+ }
+ }
+
+ public MinecraftServer d() {
-+ return this.d;
++ return this.e;
+ }
+
+ static List a(ServerConnection serverconnection) {
-+ return serverconnection.f;
++ return serverconnection.g;
+ }
+
+ static MinecraftServer b(ServerConnection serverconnection) {
-+ return serverconnection.d;
++ return serverconnection.e;
+ }
++
+}
diff --git a/src/main/java/net/minecraft/server/ServerConnectionChannel.java b/src/main/java/net/minecraft/server/ServerConnectionChannel.java
new file mode 100644
@@ -2920,11 +4369,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@
+package net.minecraft.server;
+
-+import net.minecraft.util.io.netty.channel.Channel;
-+import net.minecraft.util.io.netty.channel.ChannelException;
-+import net.minecraft.util.io.netty.channel.ChannelInitializer;
-+import net.minecraft.util.io.netty.channel.ChannelOption;
-+import net.minecraft.util.io.netty.handler.timeout.ReadTimeoutHandler;
++import io.netty.channel.Channel;
++import io.netty.channel.ChannelException;
++import io.netty.channel.ChannelInitializer;
++import io.netty.channel.ChannelOption;
++import io.netty.handler.timeout.ReadTimeoutHandler;
+
+class ServerConnectionChannel extends ChannelInitializer {
+
@@ -2947,8 +4396,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ ;
+ }
+
-+ channel.pipeline().addLast("timeout", new ReadTimeoutHandler(30)).addLast("legacy_query", new LegacyPingHandler(this.a)).addLast("splitter", new PacketSplitter()).addLast("decoder", new PacketDecoder(NetworkManager.h)).addLast("prepender", new PacketPrepender()).addLast("encoder", new PacketEncoder(NetworkManager.h));
-+ NetworkManager networkmanager = new NetworkManager(false);
++ channel.pipeline().addLast("timeout", new ReadTimeoutHandler(30)).addLast("legacy_query", new LegacyPingHandler(this.a)).addLast("splitter", new PacketSplitter()).addLast("decoder", new PacketDecoder(EnumProtocolDirection.SERVERBOUND)).addLast("prepender", new PacketPrepender()).addLast("encoder", new PacketEncoder(EnumProtocolDirection.CLIENTBOUND));
++ NetworkManager networkmanager = new NetworkManager(EnumProtocolDirection.SERVERBOUND);
+
+ ServerConnection.a(this.a).add(networkmanager);
+ channel.pipeline().addLast("packet_handler", networkmanager);
@@ -2963,6 +4412,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@
+package net.minecraft.server;
+
++import com.google.common.collect.Maps;
++import com.google.common.collect.Sets;
++import com.google.gson.JsonElement;
++import com.google.gson.JsonObject;
++import com.google.gson.JsonParseException;
++import com.google.gson.JsonParser;
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
@@ -2972,14 +4427,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
-+
-+import net.minecraft.util.com.google.common.collect.Maps;
-+import net.minecraft.util.com.google.common.collect.Sets;
-+import net.minecraft.util.com.google.gson.JsonElement;
-+import net.minecraft.util.com.google.gson.JsonObject;
-+import net.minecraft.util.com.google.gson.JsonParseException;
-+import net.minecraft.util.com.google.gson.JsonParser;
-+import net.minecraft.util.org.apache.commons.io.FileUtils;
++import org.apache.commons.io.FileUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
@@ -2992,9 +4440,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ private int f = -300;
+ private boolean g = false;
+
-+ public ServerStatisticManager(MinecraftServer minecraftserver, File file1) {
++ public ServerStatisticManager(MinecraftServer minecraftserver, File file) {
+ this.c = minecraftserver;
-+ this.d = file1;
++ this.d = file;
+ }
+
+ public void a() {
@@ -3003,19 +4451,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.a.clear();
+ this.a.putAll(this.a(FileUtils.readFileToString(this.d)));
+ } catch (IOException ioexception) {
-+ b.error("Couldn\'t read statistics file " + this.d, ioexception);
++ ServerStatisticManager.b.error("Couldn\'t read statistics file " + this.d, ioexception);
+ } catch (JsonParseException jsonparseexception) {
-+ b.error("Couldn\'t parse statistics file " + this.d, jsonparseexception);
++ ServerStatisticManager.b.error("Couldn\'t parse statistics file " + this.d, jsonparseexception);
+ }
+ }
++
+ }
+
+ public void b() {
+ try {
+ FileUtils.writeStringToFile(this.d, a(this.a));
+ } catch (IOException ioexception) {
-+ b.error("Couldn\'t save stats", ioexception);
++ ServerStatisticManager.b.error("Couldn\'t save stats", ioexception);
+ }
++
+ }
+
+ public void setStatistic(EntityHuman entityhuman, Statistic statistic, int i) {
@@ -3025,10 +4475,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.e.add(statistic);
+ if (statistic.d() && j == 0 && i > 0) {
+ this.g = true;
-+ if (this.c.at()) {
++ if (this.c.az()) {
+ this.c.getPlayerList().sendMessage(new ChatMessage("chat.type.achievement", new Object[] { entityhuman.getScoreboardDisplayName(), statistic.j()}));
+ }
+ }
++
++ if (statistic.d() && j > 0 && i == 0) {
++ this.g = true;
++ if (this.c.az()) {
++ this.c.getPlayerList().sendMessage(new ChatMessage("chat.type.achievement.taken", new Object[] { entityhuman.getScoreboardDisplayName(), statistic.j()}));
++ }
++ }
++
+ }
+
+ public Set c() {
@@ -3073,14 +4531,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ ijsonstatistic.a(jsonobject1.get("progress"));
+ statisticwrapper.a(ijsonstatistic);
+ } catch (Throwable throwable) {
-+ b.warn("Invalid statistic progress in " + this.d, throwable);
++ ServerStatisticManager.b.warn("Invalid statistic progress in " + this.d, throwable);
+ }
+ }
+ }
+
+ hashmap.put(statistic, statisticwrapper);
+ } else {
-+ b.warn("Invalid statistic in " + this.d + ": Don\'t know what " + (String) entry.getKey() + " is");
++ ServerStatisticManager.b.warn("Invalid statistic in " + this.d + ": Don\'t know what " + (String) entry.getKey() + " is");
+ }
+ }
+
@@ -3103,7 +4561,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ try {
+ jsonobject1.add("progress", ((StatisticWrapper) entry.getValue()).b().a());
+ } catch (Throwable throwable) {
-+ b.warn("Couldn\'t save statistic " + ((Statistic) entry.getKey()).e() + ": error serializing progress", throwable);
++ ServerStatisticManager.b.warn("Couldn\'t save statistic " + ((Statistic) entry.getKey()).e() + ": error serializing progress", throwable);
+ }
+
+ jsonobject.add(((Statistic) entry.getKey()).name, jsonobject1);
@@ -3123,10 +4581,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ this.e.add(statistic);
+ }
++
+ }
+
+ public void a(EntityPlayer entityplayer) {
-+ int i = this.c.al();
++ int i = this.c.ar();
+ HashMap hashmap = Maps.newHashMap();
+
+ if (this.g || i - this.f > 300) {
@@ -3162,6 +4621,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public boolean e() {
+ return this.g;
+ }
++
+}
diff --git a/src/main/java/net/minecraft/server/StructureGenerator.java b/src/main/java/net/minecraft/server/StructureGenerator.java
new file mode 100644
@@ -3171,7 +4631,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@
+package net.minecraft.server;
+
-+import java.util.HashMap;
++import com.google.common.collect.Maps;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
@@ -3180,31 +4640,32 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+public abstract class StructureGenerator extends WorldGenBase {
+
-+ private PersistentStructure e;
-+ protected Map d = new HashMap();
++ private PersistentStructure d;
++ protected Map e = Maps.newHashMap();
+
+ public StructureGenerator() {}
+
+ public abstract String a();
+
-+ protected final void a(World world, int i, int j, int k, int l, Block[] ablock) {
++ protected final void a(World world, int i, int j, int k, int l, ChunkSnapshot chunksnapshot) {
+ this.a(world);
-+ if (!this.d.containsKey(Long.valueOf(ChunkCoordIntPair.a(i, j)))) {
++ if (!this.e.containsKey(Long.valueOf(ChunkCoordIntPair.a(i, j)))) {
+ this.b.nextInt();
+
+ try {
+ if (this.a(i, j)) {
+ StructureStart structurestart = this.b(i, j);
+
-+ this.d.put(Long.valueOf(ChunkCoordIntPair.a(i, j)), structurestart);
++ this.e.put(Long.valueOf(ChunkCoordIntPair.a(i, j)), structurestart);
+ this.a(i, j, structurestart);
+ }
++
+ } catch (Throwable throwable) {
+ CrashReport crashreport = CrashReport.a(throwable, "Exception preparing structure feature");
+ CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Feature being prepared");
+
+ crashreportsystemdetails.a("Is feature chunk", (Callable) (new CrashReportIsFeatureChunk(this, i, j)));
-+ crashreportsystemdetails.a("Chunk location", String.format("%d,%d", new Object[] { Integer.valueOf(i), Integer.valueOf(j)}));
++ crashreportsystemdetails.a("Chunk location", (Object) String.format("%d,%d", new Object[] { Integer.valueOf(i), Integer.valueOf(j)}));
+ crashreportsystemdetails.a("Chunk pos hash", (Callable) (new CrashReportChunkPosHash(this, i, j)));
+ crashreportsystemdetails.a("Structure type", (Callable) (new CrashReportStructureType(this)));
+ throw new ReportedException(crashreport);
@@ -3212,18 +4673,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ }
+
-+ public boolean a(World world, Random random, int i, int j) {
++ public boolean a(World world, Random random, ChunkCoordIntPair chunkcoordintpair) {
+ this.a(world);
-+ int k = (i << 4) + 8;
-+ int l = (j << 4) + 8;
++ int i = (chunkcoordintpair.x << 4) + 8;
++ int j = (chunkcoordintpair.z << 4) + 8;
+ boolean flag = false;
-+ Iterator iterator = this.d.values().iterator();
++ Iterator iterator = this.e.values().iterator();
+
+ while (iterator.hasNext()) {
+ StructureStart structurestart = (StructureStart) iterator.next();
+
-+ if (structurestart.d() && structurestart.a().a(k, l, k + 15, l + 15)) {
-+ structurestart.a(world, random, new StructureBoundingBox(k, l, k + 15, l + 15));
++ if (structurestart.d() && structurestart.a(chunkcoordintpair) && structurestart.a().a(i, j, i + 15, j + 15)) {
++ structurestart.a(world, random, new StructureBoundingBox(i, j, i + 15, j + 15));
++ structurestart.b(chunkcoordintpair);
+ flag = true;
+ this.a(structurestart.e(), structurestart.f(), structurestart);
+ }
@@ -3232,24 +4694,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return flag;
+ }
+
-+ public boolean b(int i, int j, int k) {
++ public boolean b(BlockPosition blockposition) {
+ this.a(this.c);
-+ return this.c(i, j, k) != null;
++ return this.c(blockposition) != null;
+ }
+
-+ protected StructureStart c(int i, int j, int k) {
-+ Iterator iterator = this.d.values().iterator();
++ protected StructureStart c(BlockPosition blockposition) {
++ Iterator iterator = this.e.values().iterator();
+
+ while (iterator.hasNext()) {
+ StructureStart structurestart = (StructureStart) iterator.next();
+
-+ if (structurestart.d() && structurestart.a().a(i, k, i, k)) {
++ if (structurestart.d() && structurestart.a().b((BaseBlockPosition) blockposition)) {
+ Iterator iterator1 = structurestart.b().iterator();
+
+ while (iterator1.hasNext()) {
+ StructurePiece structurepiece = (StructurePiece) iterator1.next();
+
-+ if (structurepiece.c().b(i, j, k)) {
++ if (structurepiece.c().b((BaseBlockPosition) blockposition)) {
+ return structurestart;
+ }
+ }
@@ -3259,9 +4721,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return null;
+ }
+
-+ public boolean d(int i, int j, int k) {
-+ this.a(this.c);
-+ Iterator iterator = this.d.values().iterator();
++ public boolean a(World world, BlockPosition blockposition) {
++ this.a(world);
++ Iterator iterator = this.e.values().iterator();
+
+ StructureStart structurestart;
+
@@ -3271,31 +4733,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ structurestart = (StructureStart) iterator.next();
-+ } while (!structurestart.d());
++ } while (!structurestart.d() || !structurestart.a().b((BaseBlockPosition) blockposition));
+
-+ return structurestart.a().a(i, k, i, k);
++ return true;
+ }
+
-+ public ChunkPosition getNearestGeneratedFeature(World world, int i, int j, int k) {
++ public BlockPosition getNearestGeneratedFeature(World world, BlockPosition blockposition) {
+ this.c = world;
+ this.a(world);
+ this.b.setSeed(world.getSeed());
-+ long l = this.b.nextLong();
-+ long i1 = this.b.nextLong();
-+ long j1 = (long) (i >> 4) * l;
-+ long k1 = (long) (k >> 4) * i1;
++ long i = this.b.nextLong();
++ long j = this.b.nextLong();
++ long k = (long) (blockposition.getX() >> 4) * i;
++ long l = (long) (blockposition.getZ() >> 4) * j;
+
-+ this.b.setSeed(j1 ^ k1 ^ world.getSeed());
-+ this.a(world, i >> 4, k >> 4, 0, 0, (Block[]) null);
++ this.b.setSeed(k ^ l ^ world.getSeed());
++ this.a(world, blockposition.getX() >> 4, blockposition.getZ() >> 4, 0, 0, (ChunkSnapshot) null);
+ double d0 = Double.MAX_VALUE;
-+ ChunkPosition chunkposition = null;
-+ Iterator iterator = this.d.values().iterator();
++ BlockPosition blockposition1 = null;
++ Iterator iterator = this.e.values().iterator();
+
-+ ChunkPosition chunkposition1;
-+ int l1;
-+ int i2;
++ BlockPosition blockposition2;
+ double d1;
-+ int j2;
+
+ while (iterator.hasNext()) {
+ StructureStart structurestart = (StructureStart) iterator.next();
@@ -3303,58 +4762,52 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (structurestart.d()) {
+ StructurePiece structurepiece = (StructurePiece) structurestart.b().get(0);
+
-+ chunkposition1 = structurepiece.a();
-+ i2 = chunkposition1.x - i;
-+ l1 = chunkposition1.y - j;
-+ j2 = chunkposition1.z - k;
-+ d1 = (double) (i2 * i2 + l1 * l1 + j2 * j2);
++ blockposition2 = structurepiece.a();
++ d1 = blockposition2.i(blockposition);
+ if (d1 < d0) {
+ d0 = d1;
-+ chunkposition = chunkposition1;
++ blockposition1 = blockposition2;
+ }
+ }
+ }
+
-+ if (chunkposition != null) {
-+ return chunkposition;
++ if (blockposition1 != null) {
++ return blockposition1;
+ } else {
-+ List list = this.o_();
++ List list = this.y_();
+
+ if (list != null) {
-+ ChunkPosition chunkposition2 = null;
++ BlockPosition blockposition3 = null;
+ Iterator iterator1 = list.iterator();
+
+ while (iterator1.hasNext()) {
-+ chunkposition1 = (ChunkPosition) iterator1.next();
-+ i2 = chunkposition1.x - i;
-+ l1 = chunkposition1.y - j;
-+ j2 = chunkposition1.z - k;
-+ d1 = (double) (i2 * i2 + l1 * l1 + j2 * j2);
++ blockposition2 = (BlockPosition) iterator1.next();
++ d1 = blockposition2.i(blockposition);
+ if (d1 < d0) {
+ d0 = d1;
-+ chunkposition2 = chunkposition1;
++ blockposition3 = blockposition2;
+ }
+ }
+
-+ return chunkposition2;
++ return blockposition3;
+ } else {
+ return null;
+ }
+ }
+ }
+
-+ protected List o_() {
++ protected List y_() {
+ return null;
+ }
+
+ private void a(World world) {
-+ if (this.e == null) {
-+ this.e = (PersistentStructure) world.a(PersistentStructure.class, this.a());
-+ if (this.e == null) {
-+ this.e = new PersistentStructure(this.a());
-+ world.a(this.a(), (PersistentBase) this.e);
++ if (this.d == null) {
++ this.d = (PersistentStructure) world.a(PersistentStructure.class, this.a());
++ if (this.d == null) {
++ this.d = new PersistentStructure(this.a());
++ world.a(this.a(), (PersistentBase) this.d);
+ } else {
-+ NBTTagCompound nbttagcompound = this.e.a();
++ NBTTagCompound nbttagcompound = this.d.a();
+ Iterator iterator = nbttagcompound.c().iterator();
+
+ while (iterator.hasNext()) {
@@ -3370,24 +4823,133 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ StructureStart structurestart = WorldGenFactory.a(nbttagcompound1, world);
+
+ if (structurestart != null) {
-+ this.d.put(Long.valueOf(ChunkCoordIntPair.a(i, j)), structurestart);
++ this.e.put(Long.valueOf(ChunkCoordIntPair.a(i, j)), structurestart);
+ }
+ }
+ }
+ }
+ }
+ }
++
+ }
+
+ private void a(int i, int j, StructureStart structurestart) {
-+ this.e.a(structurestart.a(i, j), i, j);
-+ this.e.c();
++ this.d.a(structurestart.a(i, j), i, j);
++ this.d.c();
+ }
+
+ protected abstract boolean a(int i, int j);
+
+ protected abstract StructureStart b(int i, int j);
+}
+diff --git a/src/main/java/net/minecraft/server/SwitchHelperBlockFlowerPot.java b/src/main/java/net/minecraft/server/SwitchHelperBlockFlowerPot.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/net/minecraft/server/SwitchHelperBlockFlowerPot.java
+@@ -0,0 +0,0 @@
++package net.minecraft.server;
++
++class SwitchHelperBlockFlowerPot {
++
++ static final int[] a;
++ static final int[] b = new int[EnumFlowerVarient.values().length];
++
++ static {
++ try {
++ SwitchHelperBlockFlowerPot.b[EnumFlowerVarient.POPPY.ordinal()] = 1;
++ } catch (NoSuchFieldError nosuchfielderror) {
++ ;
++ }
++
++ try {
++ SwitchHelperBlockFlowerPot.b[EnumFlowerVarient.BLUE_ORCHID.ordinal()] = 2;
++ } catch (NoSuchFieldError nosuchfielderror1) {
++ ;
++ }
++
++ try {
++ SwitchHelperBlockFlowerPot.b[EnumFlowerVarient.ALLIUM.ordinal()] = 3;
++ } catch (NoSuchFieldError nosuchfielderror2) {
++ ;
++ }
++
++ try {
++ SwitchHelperBlockFlowerPot.b[EnumFlowerVarient.HOUSTONIA.ordinal()] = 4;
++ } catch (NoSuchFieldError nosuchfielderror3) {
++ ;
++ }
++
++ try {
++ SwitchHelperBlockFlowerPot.b[EnumFlowerVarient.RED_TULIP.ordinal()] = 5;
++ } catch (NoSuchFieldError nosuchfielderror4) {
++ ;
++ }
++
++ try {
++ SwitchHelperBlockFlowerPot.b[EnumFlowerVarient.ORANGE_TULIP.ordinal()] = 6;
++ } catch (NoSuchFieldError nosuchfielderror5) {
++ ;
++ }
++
++ try {
++ SwitchHelperBlockFlowerPot.b[EnumFlowerVarient.WHITE_TULIP.ordinal()] = 7;
++ } catch (NoSuchFieldError nosuchfielderror6) {
++ ;
++ }
++
++ try {
++ SwitchHelperBlockFlowerPot.b[EnumFlowerVarient.PINK_TULIP.ordinal()] = 8;
++ } catch (NoSuchFieldError nosuchfielderror7) {
++ ;
++ }
++
++ try {
++ SwitchHelperBlockFlowerPot.b[EnumFlowerVarient.OXEYE_DAISY.ordinal()] = 9;
++ } catch (NoSuchFieldError nosuchfielderror8) {
++ ;
++ }
++
++ a = new int[EnumLogVariant.values().length];
++
++ try {
++ SwitchHelperBlockFlowerPot.a[EnumLogVariant.OAK.ordinal()] = 1;
++ } catch (NoSuchFieldError nosuchfielderror9) {
++ ;
++ }
++
++ try {
++ SwitchHelperBlockFlowerPot.a[EnumLogVariant.SPRUCE.ordinal()] = 2;
++ } catch (NoSuchFieldError nosuchfielderror10) {
++ ;
++ }
++
++ try {
++ SwitchHelperBlockFlowerPot.a[EnumLogVariant.BIRCH.ordinal()] = 3;
++ } catch (NoSuchFieldError nosuchfielderror11) {
++ ;
++ }
++
++ try {
++ SwitchHelperBlockFlowerPot.a[EnumLogVariant.JUNGLE.ordinal()] = 4;
++ } catch (NoSuchFieldError nosuchfielderror12) {
++ ;
++ }
++
++ try {
++ SwitchHelperBlockFlowerPot.a[EnumLogVariant.ACACIA.ordinal()] = 5;
++ } catch (NoSuchFieldError nosuchfielderror13) {
++ ;
++ }
++
++ try {
++ SwitchHelperBlockFlowerPot.a[EnumLogVariant.DARK_OAK.ordinal()] = 6;
++ } catch (NoSuchFieldError nosuchfielderror14) {
++ ;
++ }
++
++ }
++}
diff --git a/src/main/java/net/minecraft/server/UserCache.java b/src/main/java/net/minecraft/server/UserCache.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
@@ -3396,6 +4958,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@
+package net.minecraft.server;
+
++import com.google.common.base.Charsets;
++import com.google.common.collect.Iterators;
++import com.google.common.collect.Lists;
++import com.google.common.collect.Maps;
++import com.google.common.io.Files;
++import com.google.gson.Gson;
++import com.google.gson.GsonBuilder;
++import com.mojang.authlib.Agent;
++import com.mojang.authlib.GameProfile;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
@@ -3412,17 +4983,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.Locale;
+import java.util.Map;
+import java.util.UUID;
-+
-+import net.minecraft.util.com.google.common.base.Charsets;
-+import net.minecraft.util.com.google.common.collect.Iterators;
-+import net.minecraft.util.com.google.common.collect.Lists;
-+import net.minecraft.util.com.google.common.collect.Maps;
-+import net.minecraft.util.com.google.common.io.Files;
-+import net.minecraft.util.com.google.gson.Gson;
-+import net.minecraft.util.com.google.gson.GsonBuilder;
-+import net.minecraft.util.com.mojang.authlib.Agent;
-+import net.minecraft.util.com.mojang.authlib.GameProfile;
-+import net.minecraft.util.org.apache.commons.io.IOUtils;
++import org.apache.commons.io.IOUtils;
+
+public class UserCache {
+
@@ -3435,9 +4996,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ private final File g;
+ private static final ParameterizedType h = new UserCacheEntryType();
+
-+ public UserCache(MinecraftServer minecraftserver, File file1) {
++ public UserCache(MinecraftServer minecraftserver, File file) {
+ this.f = minecraftserver;
-+ this.g = file1;
++ this.g = file;
+ GsonBuilder gsonbuilder = new GsonBuilder();
+
+ gsonbuilder.registerTypeHierarchyAdapter(UserCacheEntry.class, new BanEntrySerializer(this, (GameProfileLookup) null));
@@ -3477,22 +5038,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ String s = gameprofile.getName().toLowerCase(Locale.ROOT);
+ UserCacheEntry usercacheentry = new UserCacheEntry(this, gameprofile, date, (GameProfileLookup) null);
-+ LinkedList linkedlist = this.e;
+
-+ synchronized (this.e) {
-+ if (this.d.containsKey(uuid)) {
-+ UserCacheEntry usercacheentry1 = (UserCacheEntry) this.d.get(uuid);
++ if (this.d.containsKey(uuid)) {
++ UserCacheEntry usercacheentry1 = (UserCacheEntry) this.d.get(uuid);
+
-+ this.c.remove(usercacheentry1.a().getName().toLowerCase(Locale.ROOT));
-+ this.c.put(gameprofile.getName().toLowerCase(Locale.ROOT), usercacheentry);
-+ this.e.remove(gameprofile);
-+ } else {
-+ this.d.put(uuid, usercacheentry);
-+ this.c.put(s, usercacheentry);
-+ }
-+
-+ this.e.addFirst(gameprofile);
++ this.c.remove(usercacheentry1.a().getName().toLowerCase(Locale.ROOT));
++ this.c.put(gameprofile.getName().toLowerCase(Locale.ROOT), usercacheentry);
++ this.e.remove(gameprofile);
++ } else {
++ this.d.put(uuid, usercacheentry);
++ this.c.put(s, usercacheentry);
+ }
++
++ this.e.addFirst(gameprofile);
+ }
+
+ public GameProfile getProfile(String s) {
@@ -3502,12 +5060,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (usercacheentry != null && (new Date()).getTime() >= UserCacheEntry.a(usercacheentry).getTime()) {
+ this.d.remove(usercacheentry.a().getId());
+ this.c.remove(usercacheentry.a().getName().toLowerCase(Locale.ROOT));
-+ LinkedList linkedlist = this.e;
-+
-+ synchronized (this.e) {
-+ this.e.remove(usercacheentry.a());
-+ }
-+
++ this.e.remove(usercacheentry.a());
+ usercacheentry = null;
+ }
+
@@ -3515,12 +5068,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ if (usercacheentry != null) {
+ gameprofile = usercacheentry.a();
-+ LinkedList linkedlist1 = this.e;
-+
-+ synchronized (this.e) {
-+ this.e.remove(gameprofile);
-+ this.e.addFirst(gameprofile);
-+ }
++ this.e.remove(gameprofile);
++ this.e.addFirst(gameprofile);
+ } else {
+ gameprofile = a(this.f, s1);
+ if (gameprofile != null) {
@@ -3550,12 +5099,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ if (usercacheentry != null) {
+ GameProfile gameprofile = usercacheentry.a();
-+ LinkedList linkedlist = this.e;
+
-+ synchronized (this.e) {
-+ this.e.remove(gameprofile);
-+ this.e.addFirst(gameprofile);
-+ }
++ this.e.remove(gameprofile);
++ this.e.addFirst(gameprofile);
+ }
+
+ return usercacheentry;
@@ -3565,11 +5111,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ List list = null;
+ BufferedReader bufferedreader = null;
+
-+ label81: {
++ label64: {
+ try {
+ bufferedreader = Files.newReader(this.g, Charsets.UTF_8);
-+ list = (List) this.b.fromJson(bufferedreader, h);
-+ break label81;
++ list = (List) this.b.fromJson(bufferedreader, UserCache.h);
++ break label64;
+ } catch (FileNotFoundException filenotfoundexception) {
+ ;
+ } finally {
@@ -3582,12 +5128,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (list != null) {
+ this.c.clear();
+ this.d.clear();
-+ LinkedList linkedlist = this.e;
-+
-+ synchronized (this.e) {
-+ this.e.clear();
-+ }
-+
++ this.e.clear();
+ list = Lists.reverse(list);
+ Iterator iterator = list.iterator();
+
@@ -3599,6 +5140,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ }
+ }
++
+ }
+
+ public void c() {
@@ -3616,17 +5158,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } finally {
+ IOUtils.closeQuietly(bufferedwriter);
+ }
++
+ }
+
+ private List a(int i) {
+ ArrayList arraylist = Lists.newArrayList();
-+ LinkedList linkedlist = this.e;
-+ ArrayList arraylist1;
-+
-+ synchronized (this.e) {
-+ arraylist1 = Lists.newArrayList(Iterators.limit(this.e.iterator(), i));
-+ }
-+
++ ArrayList arraylist1 = Lists.newArrayList(Iterators.limit(this.e.iterator(), i));
+ Iterator iterator = arraylist1.iterator();
+
+ while (iterator.hasNext()) {
@@ -3640,6 +5177,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ return arraylist;
+ }
++
+}
diff --git a/src/main/java/net/minecraft/server/UserCacheEntry.java b/src/main/java/net/minecraft/server/UserCacheEntry.java
new file mode 100644
@@ -3649,10 +5187,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@
+package net.minecraft.server;
+
++import com.mojang.authlib.GameProfile;
+import java.util.Date;
+
-+import net.minecraft.util.com.mojang.authlib.GameProfile;
-+
+class UserCacheEntry {
+
+ private final GameProfile b;
@@ -3747,31 +5284,29 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ super(flag);
+ }
+
-+ public boolean generate(World world, Random random, int i, int j, int k) {
-+ int l = random.nextInt(3) + random.nextInt(2) + 6;
++ public boolean generate(World world, Random random, BlockPosition blockposition) {
++ int i = random.nextInt(3) + random.nextInt(2) + 6;
+ boolean flag = true;
+
-+ if (j >= 1 && j + l + 1 <= 256) {
-+ int i1;
-+ int j1;
++ if (blockposition.getY() >= 1 && blockposition.getY() + i + 1 <= 256) {
++ int j;
++ int k;
+
-+ for (int k1 = j; k1 <= j + 1 + l; ++k1) {
++ for (int l = blockposition.getY(); l <= blockposition.getY() + 1 + i; ++l) {
+ byte b0 = 1;
+
-+ if (k1 == j) {
++ if (l == blockposition.getY()) {
+ b0 = 0;
+ }
+
-+ if (k1 >= j + 1 + l - 2) {
++ if (l >= blockposition.getY() + 1 + i - 2) {
+ b0 = 2;
+ }
+
-+ for (i1 = i - b0; i1 <= i + b0 && flag; ++i1) {
-+ for (j1 = k - b0; j1 <= k + b0 && flag; ++j1) {
-+ if (k1 >= 0 && k1 < 256) {
-+ Block block = world.getType(i1, k1, j1);
-+
-+ if (!this.a(block)) {
++ for (j = blockposition.getX() - b0; j <= blockposition.getX() + b0 && flag; ++j) {
++ for (k = blockposition.getZ() - b0; k <= blockposition.getZ() + b0 && flag; ++k) {
++ if (l >= 0 && l < 256) {
++ if (!this.a(world.getType(new BlockPosition(j, l, k)).getBlock())) {
+ flag = false;
+ }
+ } else {
@@ -3784,100 +5319,101 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (!flag) {
+ return false;
+ } else {
-+ Block block1 = world.getType(i, j - 1, k);
++ Block block = world.getType(blockposition.down()).getBlock();
+
-+ if ((block1 == Blocks.GRASS || block1 == Blocks.DIRT) && j < 256 - l - 1) {
-+ this.setType(world, i, j - 1, k, Blocks.DIRT);
-+ this.setType(world, i + 1, j - 1, k, Blocks.DIRT);
-+ this.setType(world, i + 1, j - 1, k + 1, Blocks.DIRT);
-+ this.setType(world, i, j - 1, k + 1, Blocks.DIRT);
-+ int l1 = random.nextInt(4);
++ if ((block == Blocks.GRASS || block == Blocks.DIRT) && blockposition.getY() < 256 - i - 1) {
++ this.a(world, blockposition.down());
++ this.a(world, blockposition.a(1, -1, 0));
++ this.a(world, blockposition.a(1, -1, 1));
++ this.a(world, blockposition.a(0, -1, 1));
++ EnumDirection enumdirection = EnumDirectionLimit.HORIZONTAL.a(random);
+
-+ i1 = l - random.nextInt(4);
-+ j1 = 2 - random.nextInt(3);
-+ int i2 = i;
-+ int j2 = k;
-+ int k2 = 0;
++ j = i - random.nextInt(4);
++ k = 2 - random.nextInt(3);
++ int i1 = blockposition.getX();
++ int j1 = blockposition.getZ();
++ int k1 = 0;
+
-+ int l2;
-+ int i3;
++ int l1;
++ int i2;
+
-+ for (l2 = 0; l2 < l; ++l2) {
-+ i3 = j + l2;
-+ if (l2 >= i1 && j1 > 0) {
-+ i2 += Direction.a[l1];
-+ j2 += Direction.b[l1];
-+ --j1;
++ for (l1 = 0; l1 < i; ++l1) {
++ i2 = blockposition.getY() + l1;
++ if (l1 >= j && k > 0) {
++ i1 += enumdirection.getAdjacentX();
++ j1 += enumdirection.getAdjacentZ();
++ --k;
+ }
+
-+ Block block2 = world.getType(i2, i3, j2);
++ BlockPosition blockposition1 = new BlockPosition(i1, i2, j1);
++ Material material = world.getType(blockposition1).getBlock().getMaterial();
+
-+ if (block2.getMaterial() == Material.AIR || block2.getMaterial() == Material.LEAVES) {
-+ this.setTypeAndData(world, i2, i3, j2, Blocks.LOG2, 1);
-+ this.setTypeAndData(world, i2 + 1, i3, j2, Blocks.LOG2, 1);
-+ this.setTypeAndData(world, i2, i3, j2 + 1, Blocks.LOG2, 1);
-+ this.setTypeAndData(world, i2 + 1, i3, j2 + 1, Blocks.LOG2, 1);
-+ k2 = i3;
++ if (material == Material.AIR || material == Material.LEAVES) {
++ this.a(world, blockposition1, Blocks.LOG2, EnumLogVariant.DARK_OAK.a() - 4);
++ this.a(world, blockposition1.east(), Blocks.LOG2, EnumLogVariant.DARK_OAK.a() - 4);
++ this.a(world, blockposition1.south(), Blocks.LOG2, EnumLogVariant.DARK_OAK.a() - 4);
++ this.a(world, blockposition1.east().south(), Blocks.LOG2, EnumLogVariant.DARK_OAK.a() - 4);
++ k1 = i2;
+ }
+ }
+
-+ for (l2 = -2; l2 <= 0; ++l2) {
-+ for (i3 = -2; i3 <= 0; ++i3) {
++ for (l1 = -2; l1 <= 0; ++l1) {
++ for (i2 = -2; i2 <= 0; ++i2) {
+ byte b1 = -1;
+
-+ this.a(world, i2 + l2, k2 + b1, j2 + i3);
-+ this.a(world, 1 + i2 - l2, k2 + b1, j2 + i3);
-+ this.a(world, i2 + l2, k2 + b1, 1 + j2 - i3);
-+ this.a(world, 1 + i2 - l2, k2 + b1, 1 + j2 - i3);
-+ if ((l2 > -2 || i3 > -1) && (l2 != -1 || i3 != -2)) {
++ this.a(world, i1 + l1, k1 + b1, j1 + i2);
++ this.a(world, 1 + i1 - l1, k1 + b1, j1 + i2);
++ this.a(world, i1 + l1, k1 + b1, 1 + j1 - i2);
++ this.a(world, 1 + i1 - l1, k1 + b1, 1 + j1 - i2);
++ if ((l1 > -2 || i2 > -1) && (l1 != -1 || i2 != -2)) {
+ byte b2 = 1;
+
-+ this.a(world, i2 + l2, k2 + b2, j2 + i3);
-+ this.a(world, 1 + i2 - l2, k2 + b2, j2 + i3);
-+ this.a(world, i2 + l2, k2 + b2, 1 + j2 - i3);
-+ this.a(world, 1 + i2 - l2, k2 + b2, 1 + j2 - i3);
++ this.a(world, i1 + l1, k1 + b2, j1 + i2);
++ this.a(world, 1 + i1 - l1, k1 + b2, j1 + i2);
++ this.a(world, i1 + l1, k1 + b2, 1 + j1 - i2);
++ this.a(world, 1 + i1 - l1, k1 + b2, 1 + j1 - i2);
+ }
+ }
+ }
+
+ if (random.nextBoolean()) {
-+ this.a(world, i2, k2 + 2, j2);
-+ this.a(world, i2 + 1, k2 + 2, j2);
-+ this.a(world, i2 + 1, k2 + 2, j2 + 1);
-+ this.a(world, i2, k2 + 2, j2 + 1);
++ this.a(world, i1, k1 + 2, j1);
++ this.a(world, i1 + 1, k1 + 2, j1);
++ this.a(world, i1 + 1, k1 + 2, j1 + 1);
++ this.a(world, i1, k1 + 2, j1 + 1);
+ }
+
-+ for (l2 = -3; l2 <= 4; ++l2) {
-+ for (i3 = -3; i3 <= 4; ++i3) {
-+ if ((l2 != -3 || i3 != -3) && (l2 != -3 || i3 != 4) && (l2 != 4 || i3 != -3) && (l2 != 4 || i3 != 4) && (Math.abs(l2) < 3 || Math.abs(i3) < 3)) {
-+ this.a(world, i2 + l2, k2, j2 + i3);
++ for (l1 = -3; l1 <= 4; ++l1) {
++ for (i2 = -3; i2 <= 4; ++i2) {
++ if ((l1 != -3 || i2 != -3) && (l1 != -3 || i2 != 4) && (l1 != 4 || i2 != -3) && (l1 != 4 || i2 != 4) && (Math.abs(l1) < 3 || Math.abs(i2) < 3)) {
++ this.a(world, i1 + l1, k1, j1 + i2);
+ }
+ }
+ }
+
-+ for (l2 = -1; l2 <= 2; ++l2) {
-+ for (i3 = -1; i3 <= 2; ++i3) {
-+ if ((l2 < 0 || l2 > 1 || i3 < 0 || i3 > 1) && random.nextInt(3) <= 0) {
-+ int j3 = random.nextInt(3) + 2;
++ for (l1 = -1; l1 <= 2; ++l1) {
++ for (i2 = -1; i2 <= 2; ++i2) {
++ if ((l1 < 0 || l1 > 1 || i2 < 0 || i2 > 1) && random.nextInt(3) <= 0) {
++ int j2 = random.nextInt(3) + 2;
+
-+ int k3;
++ int k2;
+
-+ for (k3 = 0; k3 < j3; ++k3) {
-+ this.setTypeAndData(world, i + l2, k2 - k3 - 1, k + i3, Blocks.LOG2, 1);
++ for (k2 = 0; k2 < j2; ++k2) {
++ this.a(world, new BlockPosition(blockposition.getX() + l1, k1 - k2 - 1, blockposition.getZ() + i2), Blocks.LOG2, EnumLogVariant.DARK_OAK.a() - 4);
+ }
+
-+ int l3;
++ int l2;
+
-+ for (k3 = -1; k3 <= 1; ++k3) {
-+ for (l3 = -1; l3 <= 1; ++l3) {
-+ this.a(world, i2 + l2 + k3, k2 - 0, j2 + i3 + l3);
++ for (k2 = -1; k2 <= 1; ++k2) {
++ for (l2 = -1; l2 <= 1; ++l2) {
++ this.a(world, i1 + l1 + k2, k1 - 0, j1 + i2 + l2);
+ }
+ }
+
-+ for (k3 = -2; k3 <= 2; ++k3) {
-+ for (l3 = -2; l3 <= 2; ++l3) {
-+ if (Math.abs(k3) != 2 || Math.abs(l3) != 2) {
-+ this.a(world, i2 + l2 + k3, k2 - 1, j2 + i3 + l3);
++ for (k2 = -2; k2 <= 2; ++k2) {
++ for (l2 = -2; l2 <= 2; ++l2) {
++ if (Math.abs(k2) != 2 || Math.abs(l2) != 2) {
++ this.a(world, i1 + l1 + k2, k1 - 1, j1 + i2 + l2);
+ }
+ }
+ }
@@ -3896,11 +5432,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ private void a(World world, int i, int j, int k) {
-+ Block block = world.getType(i, j, k);
++ Block block = world.getType(new BlockPosition(i, j, k)).getBlock();
+
+ if (block.getMaterial() == Material.AIR) {
-+ this.setTypeAndData(world, i, j, k, Blocks.LEAVES2, 1);
++ this.a(world, new BlockPosition(i, j, k), Blocks.LEAVES2, 1);
+ }
++
+ }
+}
diff --git a/src/main/java/net/minecraft/server/WorldGenLargeFeature.java b/src/main/java/net/minecraft/server/WorldGenLargeFeature.java
@@ -3911,7 +5448,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@
+package net.minecraft.server;
+
-+import java.util.ArrayList;
++import com.google.common.collect.Lists;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
@@ -3921,13 +5458,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+public class WorldGenLargeFeature extends StructureGenerator {
+
-+ private static List e = Arrays.asList(new BiomeBase[] { BiomeBase.DESERT, BiomeBase.DESERT_HILLS, BiomeBase.JUNGLE, BiomeBase.JUNGLE_HILLS, BiomeBase.SWAMPLAND});
++ private static final List d = Arrays.asList(new BiomeBase[] { BiomeBase.DESERT, BiomeBase.DESERT_HILLS, BiomeBase.JUNGLE, BiomeBase.JUNGLE_HILLS, BiomeBase.SWAMPLAND});
+ private List f;
+ private int g;
+ private int h;
+
+ public WorldGenLargeFeature() {
-+ this.f = new ArrayList();
++ this.f = Lists.newArrayList();
+ this.g = 32;
+ this.h = 8;
+ this.f.add(new BiomeMeta(EntityWitch.class, 1, 1, 1));
@@ -3944,6 +5481,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.g = MathHelper.a((String) entry.getValue(), this.g, this.h + 1);
+ }
+ }
++
+ }
+
+ public String a() {
@@ -3964,15 +5502,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ int i1 = i / this.g;
+ int j1 = j / this.g;
-+ Random random = this.c.A(i1, j1, 14357617);
++ Random random = this.c.a(i1, j1, 14357617);
+
+ i1 *= this.g;
+ j1 *= this.g;
+ i1 += random.nextInt(this.g - this.h);
+ j1 += random.nextInt(this.g - this.h);
+ if (k == i1 && l == j1) {
-+ BiomeBase biomebase = this.c.getWorldChunkManager().getBiome(k * 16 + 8, l * 16 + 8);
-+ Iterator iterator = e.iterator();
++ BiomeBase biomebase = this.c.getWorldChunkManager().getBiome(new BlockPosition(k * 16 + 8, 0, l * 16 + 8));
++
++ if (biomebase == null) {
++ return false;
++ }
++
++ Iterator iterator = WorldGenLargeFeature.d.iterator();
+
+ while (iterator.hasNext()) {
+ BiomeBase biomebase1 = (BiomeBase) iterator.next();
@@ -3990,8 +5533,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return new WorldGenLargeFeatureStart(this.c, this.b, i, j);
+ }
+
-+ public boolean a(int i, int j, int k) {
-+ StructureStart structurestart = this.c(i, j, k);
++ public boolean a(BlockPosition blockposition) {
++ StructureStart structurestart = this.c(blockposition);
+
+ if (structurestart != null && structurestart instanceof WorldGenLargeFeatureStart && !structurestart.a.isEmpty()) {
+ StructurePiece structurepiece = (StructurePiece) structurestart.a.getFirst();
@@ -4005,6 +5548,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public List b() {
+ return this.f;
+ }
++
+}
diff --git a/src/main/java/net/minecraft/server/WorldGenPackedIce2.java b/src/main/java/net/minecraft/server/WorldGenPackedIce2.java
new file mode 100644
@@ -4020,48 +5564,47 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ public WorldGenPackedIce2() {}
+
-+ public boolean generate(World world, Random random, int i, int j, int k) {
-+ while (world.isEmpty(i, j, k) && j > 2) {
-+ --j;
++ public boolean generate(World world, Random random, BlockPosition blockposition) {
++ while (world.isEmpty(blockposition) && blockposition.getY() > 2) {
++ blockposition = blockposition.down();
+ }
+
-+ if (world.getType(i, j, k) != Blocks.SNOW_BLOCK) {
++ if (world.getType(blockposition).getBlock() != Blocks.SNOW) {
+ return false;
+ } else {
-+ j += random.nextInt(4);
-+ int l = random.nextInt(4) + 7;
-+ int i1 = l / 4 + random.nextInt(2);
++ blockposition = blockposition.up(random.nextInt(4));
++ int i = random.nextInt(4) + 7;
++ int j = i / 4 + random.nextInt(2);
+
-+ if (i1 > 1 && random.nextInt(60) == 0) {
-+ j += 10 + random.nextInt(30);
++ if (j > 1 && random.nextInt(60) == 0) {
++ blockposition = blockposition.up(10 + random.nextInt(30));
+ }
+
-+ int j1;
-+ int k1;
-+ int l1;
++ int k;
++ int l;
+
-+ for (j1 = 0; j1 < l; ++j1) {
-+ float f = (1.0F - (float) j1 / (float) l) * (float) i1;
++ for (k = 0; k < i; ++k) {
++ float f = (1.0F - (float) k / (float) i) * (float) j;
+
-+ k1 = MathHelper.f(f);
++ l = MathHelper.f(f);
+
-+ for (l1 = -k1; l1 <= k1; ++l1) {
-+ float f1 = (float) MathHelper.a(l1) - 0.25F;
++ for (int i1 = -l; i1 <= l; ++i1) {
++ float f1 = (float) MathHelper.a(i1) - 0.25F;
+
-+ for (int i2 = -k1; i2 <= k1; ++i2) {
-+ float f2 = (float) MathHelper.a(i2) - 0.25F;
++ for (int j1 = -l; j1 <= l; ++j1) {
++ float f2 = (float) MathHelper.a(j1) - 0.25F;
+
-+ if ((l1 == 0 && i2 == 0 || f1 * f1 + f2 * f2 <= f * f) && (l1 != -k1 && l1 != k1 && i2 != -k1 && i2 != k1 || random.nextFloat() <= 0.75F)) {
-+ Block block = world.getType(i + l1, j + j1, k + i2);
++ if ((i1 == 0 && j1 == 0 || f1 * f1 + f2 * f2 <= f * f) && (i1 != -l && i1 != l && j1 != -l && j1 != l || random.nextFloat() <= 0.75F)) {
++ Block block = world.getType(blockposition.a(i1, k, j1)).getBlock();
+
-+ 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);
++ if (block.getMaterial() == Material.AIR || block == Blocks.DIRT || block == Blocks.SNOW || block == Blocks.ICE) {
++ this.a(world, blockposition.a(i1, k, j1), Blocks.PACKED_ICE);
+ }
+
-+ 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);
++ if (k != 0 && l > 1) {
++ block = world.getType(blockposition.a(i1, -k, j1)).getBlock();
++ if (block.getMaterial() == Material.AIR || block == Blocks.DIRT || block == Blocks.SNOW || block == Blocks.ICE) {
++ this.a(world, blockposition.a(i1, -k, j1), Blocks.PACKED_ICE);
+ }
+ }
+ }
@@ -4069,41 +5612,41 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ }
+
-+ j1 = i1 - 1;
-+ if (j1 < 0) {
-+ j1 = 0;
-+ } else if (j1 > 1) {
-+ j1 = 1;
++ k = j - 1;
++ if (k < 0) {
++ k = 0;
++ } else if (k > 1) {
++ k = 1;
+ }
+
-+ for (int j2 = -j1; j2 <= j1; ++j2) {
-+ k1 = -j1;
++ for (int k1 = -k; k1 <= k; ++k1) {
++ l = -k;
+
-+ while (k1 <= j1) {
-+ l1 = j - 1;
-+ int k2 = 50;
++ while (l <= k) {
++ BlockPosition blockposition1 = blockposition.a(k1, -1, l);
++ int l1 = 50;
+
-+ if (Math.abs(j2) == 1 && Math.abs(k1) == 1) {
-+ k2 = random.nextInt(5);
++ if (Math.abs(k1) == 1 && Math.abs(l) == 1) {
++ l1 = random.nextInt(5);
+ }
+
+ while (true) {
-+ if (l1 > 50) {
-+ Block block1 = world.getType(i + j2, l1, k + k1);
++ if (blockposition1.getY() > 50) {
++ Block block1 = world.getType(blockposition1).getBlock();
+
-+ 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);
++ if (block1.getMaterial() == Material.AIR || block1 == Blocks.DIRT || block1 == Blocks.SNOW || block1 == Blocks.ICE || block1 == Blocks.PACKED_ICE) {
++ this.a(world, blockposition1, Blocks.PACKED_ICE);
++ blockposition1 = blockposition1.down();
+ --l1;
-+ --k2;
-+ if (k2 <= 0) {
-+ l1 -= random.nextInt(5) + 1;
-+ k2 = random.nextInt(5);
++ if (l1 <= 0) {
++ blockposition1 = blockposition1.down(random.nextInt(5) + 1);
++ l1 = random.nextInt(5);
+ }
+ continue;
+ }
+ }
+
-+ ++k1;
++ ++l;
+ break;
+ }
+ }
@@ -4130,7 +5673,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+public class WorldGenVillage extends StructureGenerator {
+
-+ public static final List e = Arrays.asList(new BiomeBase[] { BiomeBase.PLAINS, BiomeBase.DESERT, BiomeBase.SAVANNA});
++ public static final List d = Arrays.asList(new BiomeBase[] { BiomeBase.PLAINS, BiomeBase.DESERT, BiomeBase.SAVANNA});
+ private int f;
+ private int g;
+ private int h;
@@ -4153,6 +5696,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.g = MathHelper.a((String) entry.getValue(), this.g, this.h + 1);
+ }
+ }
++
+ }
+
+ public String a() {
@@ -4173,14 +5717,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ int i1 = i / this.g;
+ int j1 = j / this.g;
-+ Random random = this.c.A(i1, j1, 10387312);
++ Random random = this.c.a(i1, j1, 10387312);
+
+ i1 *= this.g;
+ j1 *= this.g;
+ i1 += random.nextInt(this.g - this.h);
+ j1 += random.nextInt(this.g - this.h);
+ if (k == i1 && l == j1) {
-+ boolean flag = this.c.getWorldChunkManager().a(k * 16 + 8, l * 16 + 8, 0, e);
++ boolean flag = this.c.getWorldChunkManager().a(k * 16 + 8, l * 16 + 8, 0, WorldGenVillage.d);
+
+ if (flag) {
+ return true;
@@ -4193,6 +5737,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ protected StructureStart b(int i, int j) {
+ return new WorldGenVillageStart(this.c, this.b, i, j, this.f);
+ }
++
+}
diff --git a/src/main/java/org/spigotmc/SneakyThrow.java b/src/main/java/org/spigotmc/SneakyThrow.java
new file mode 100644
diff --git a/CraftBukkit-Patches/0003-Skeleton-API-Implementations.patch b/CraftBukkit-Patches/0003-Skeleton-API-Implementations.patch
index 332d8405d7..2cf264dd71 100644
--- a/CraftBukkit-Patches/0003-Skeleton-API-Implementations.patch
+++ b/CraftBukkit-Patches/0003-Skeleton-API-Implementations.patch
@@ -68,8 +68,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -0,0 +0,0 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
-
- return getHandle().vehicle.getBukkitEntity();
+ public boolean isCustomNameVisible() {
+ return getHandle().getCustomNameVisible();
}
+
+ // Spigot start
@@ -81,6 +81,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ {
+ return spigot;
+ }
++ // Spigot end
+ }
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java
+@@ -0,0 +0,0 @@ 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 LightningStrike.Spigot spigot() {
++ return spigot;
++ }
+ // Spigot end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -89,7 +109,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
}
- collection.add(new AttributeModifiable(getHandle().getAttributeMap(), (new AttributeRanged("generic.maxHealth", scaledHealth ? healthScale : getMaxHealth(), 0.0D, Float.MAX_VALUE)).a("Max Health").a(true)));
+ collection.add(new AttributeModifiable(getHandle().getAttributeMap(), (new AttributeRanged(null, "generic.maxHealth", scaledHealth ? healthScale : getMaxHealth(), 0.0D, Float.MAX_VALUE)).a("Max Health").a(true)));
}
+
+ // Spigot start
@@ -122,6 +142,53 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ {
+ return spigot;
+ }
++ // Spigot end
+ }
+diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java
++++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java
+@@ -0,0 +0,0 @@ final class CraftScore implements Score {
+ public CraftScoreboard getScoreboard() {
+ return objective.getScoreboard();
+ }
++
++ // Spigot start
++ @Override
++ public boolean isScoreSet() throws IllegalStateException {
++ throw new UnsupportedOperationException("Not supported yet.");
++ }
++ // Spigot end
+ }
+diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java
++++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java
+@@ -0,0 +0,0 @@ final class CraftTeam extends CraftScoreboardComponent implements Team {
+ scoreboard.teams.remove(team.getName());
+ setUnregistered();
+ }
++
++ // Spigot start
++ @Override
++ public Set getEntries() throws IllegalStateException {
++ throw new UnsupportedOperationException("Not supported yet.");
++ }
++
++ @Override
++ public void addEntry(String entry) throws IllegalStateException, IllegalArgumentException {
++ throw new UnsupportedOperationException("Not supported yet.");
++ }
++
++ @Override
++ public boolean removeEntry(String entry) throws IllegalStateException, IllegalArgumentException {
++ throw new UnsupportedOperationException("Not supported yet.");
++ }
++
++ @Override
++ public boolean hasEntry(String entry) throws IllegalArgumentException, IllegalStateException {
++ throw new UnsupportedOperationException("Not supported yet.");
++ }
+ // Spigot end
}
--
\ No newline at end of file
diff --git a/CraftBukkit-Patches/0004-Obfuscation-Helpers.patch b/CraftBukkit-Patches/0004-Obfuscation-Helpers.patch
index ebf3ce53de..494564a503 100644
--- a/CraftBukkit-Patches/0004-Obfuscation-Helpers.patch
+++ b/CraftBukkit-Patches/0004-Obfuscation-Helpers.patch
@@ -9,17 +9,17 @@ diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
- }
+@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs
+
}
+ // Spigot Start
+ public ServerConnection getServerConnection()
+ {
-+ return this.p;
++ return this.q;
+ }
+ // Spigot End
- public ServerConnection ai() {
- return this.p;
+ public ServerConnection ao() {
+ return this.q;
}
--
\ No newline at end of file
diff --git a/CraftBukkit-Patches/0005-Spigot-Configuration.patch b/CraftBukkit-Patches/0005-Spigot-Configuration.patch
index 9961d50ca2..08a68675b2 100644
--- a/CraftBukkit-Patches/0005-Spigot-Configuration.patch
+++ b/CraftBukkit-Patches/0005-Spigot-Configuration.patch
@@ -10,7 +10,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/DedicatedServer.java
@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
- if (this.L() < 0) {
+ if (this.Q() < 0) {
this.setPort(this.propertyManager.getInt("server-port", 25565));
}
+ // Spigot start
@@ -19,7 +19,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ org.spigotmc.SpigotConfig.registerCommands();
+ // Spigot end
- i.info("Generating keypair");
+ DedicatedServer.LOGGER.info("Generating keypair");
this.a(MinecraftEncryption.b());
@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
return false;
@@ -33,24 +33,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Spigot End
if (!this.getOnlineMode()) {
- i.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!");
+ DedicatedServer.LOGGER.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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
- public boolean pvpMode;
- public boolean keepSpawnInMemory = true;
- public ChunkGenerator generator;
+ public long ticksPerMonsterSpawns;
+ public boolean populating;
+ private int tickPosition;
+ public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot
public CraftWorld getWorld() {
return this.world;
@@ -0,0 +0,0 @@ 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) {
-+ this.spigotConfig = new org.spigotmc.SpigotWorldConfig( s ); // Spigot
+ protected World(IDataManager idatamanager, WorldData worlddata, WorldProvider worldprovider, MethodProfiler methodprofiler, boolean flag, ChunkGenerator gen, org.bukkit.World.Environment env) {
++ this.spigotConfig = new org.spigotmc.SpigotWorldConfig( worlddata.getName() ); // Spigot
this.generator = gen;
this.world = new CraftWorld((WorldServer) this, gen, env);
this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit
@@ -59,8 +59,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
- updater.getOnUpdate().addAll(configuration.getStringList("auto-updater.on-update"));
- updater.check(serverVersion);
+ chunkGCLoadThresh = configuration.getInt("chunk-gc.load-threshold");
+ loadIcon();
- loadPlugins();
- enablePlugins(PluginLoadOrder.STARTUP);
@@ -77,7 +77,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ org.spigotmc.SpigotConfig.init(); // Spigot
for (WorldServer world : console.worlds) {
- world.difficulty = difficulty;
+ world.worldData.setDifficulty(difficulty);
world.setSpawnFlags(monsters, animals);
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
} else {
@@ -158,8 +158,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ commands = new HashMap();
+
-+ version = getInt( "config-version", 7 );
-+ set( "config-version", 7 );
++ version = getInt( "config-version", 8 );
++ set( "config-version", 8 );
+ readConfig( SpigotConfig.class, null );
+ }
+
diff --git a/CraftBukkit-Patches/0006-Better-Chunk-Tick-Selection.patch b/CraftBukkit-Patches/0006-Better-Chunk-Tick-Selection.patch
index a4853a59c3..39e234543d 100644
--- a/CraftBukkit-Patches/0006-Better-Chunk-Tick-Selection.patch
+++ b/CraftBukkit-Patches/0006-Better-Chunk-Tick-Selection.patch
@@ -10,20 +10,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
- public Scoreboard scoreboard = new Scoreboard(); // CraftBukkit - protected -> public
- public boolean isStatic;
- // CraftBukkit start - public, longhashset
+ public Scoreboard scoreboard = new Scoreboard();
+ public final boolean isStatic;
+ // CraftBukkit - longhashset
- protected LongHashSet chunkTickList = new LongHashSet();
+ // protected LongHashSet chunkTickList = new LongHashSet(); // Spigot
private int K;
public boolean allowMonsters;
public boolean allowAnimals;
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
- private boolean M;
- int[] I;
-
+ public long ticksPerMonsterSpawns;
+ public boolean populating;
+ private int tickPosition;
++
+ // Spigot start
-+ protected final net.minecraft.util.gnu.trove.map.hash.TLongShortHashMap chunkTickList;
++ protected final gnu.trove.map.hash.TLongShortHashMap chunkTickList;
+ protected float growthOdds = 100;
+ protected float modifiedOdds = 100;
+ private final byte chunkTickRadius;
@@ -31,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public static long chunkToKey(int x, int z)
+ {
+ long k = ( ( ( (long) x ) & 0xFFFF0000L ) << 16 ) | ( ( ( (long) x ) & 0x0000FFFFL ) << 0 );
-+ k |= ( ( ( (long) z ) & 0xFFFF0000L ) << 32 ) | ( ( ( (long) z ) & 0x0000FFFFL ) << 16 );
++ k |= ( ( ( (long) z ) & 0xFFFF0000L ) << 32 ) | ( ( ( (long) z ) & 0x0000FFFFL ) << 16 );
+ return k;
+ }
+
@@ -46,16 +47,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ // Spigot end
+
- public BiomeBase getBiome(int i, int j) {
- if (this.isLoaded(i, 0, j)) {
- Chunk chunk = this.getChunkAtWorldCoords(i, j);
+ public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot
+
+ public CraftWorld getWorld() {
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit
this.ticksPerMonsterSpawns = this.getServer().getTicksPerMonsterSpawns(); // CraftBukkit
// CraftBukkit end
+ // Spigot start
+ this.chunkTickRadius = (byte) ( ( this.getServer().getViewDistance() < 7 ) ? this.getServer().getViewDistance() : 7 );
-+ this.chunkTickList = new net.minecraft.util.gnu.trove.map.hash.TLongShortHashMap( spigotConfig.chunksPerTick * 5, 0.7f, Long.MIN_VALUE, Short.MIN_VALUE );
++ this.chunkTickList = new gnu.trove.map.hash.TLongShortHashMap( spigotConfig.chunksPerTick * 5, 0.7f, Long.MIN_VALUE, Short.MIN_VALUE );
+ this.chunkTickList.setAutoCompactionFactor( 0 );
+ // Spigot end
@@ -84,15 +85,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
entityhuman = (EntityHuman) this.players.get(i);
j = MathHelper.floor(entityhuman.locX / 16.0D);
k = MathHelper.floor(entityhuman.locZ / 16.0D);
- l = this.p();
+ l = this.q();
- for (int i1 = -l; i1 <= l; ++i1) {
- for (int j1 = -l; j1 <= l; ++j1) {
-- this.chunkTickList.add(org.bukkit.craftbukkit.util.LongHash.toLong(i1 + j, j1 + k)); // CraftBukkit
+- this.chunkTickList.add(org.bukkit.craftbukkit.util.LongHash.toLong(i1 + j, j1 + k));
+ // Spigot start - Always update the chunk the player is on
+ long key = chunkToKey( j, k );
+ int existingPlayers = Math.max( 0, chunkTickList.get( key ) ); // filter out -1
-+ chunkTickList.put(key, (short) (existingPlayers + 1));
++ chunkTickList.put( key, (short) ( existingPlayers + 1 ) );
+
+ // Check and see if we update the chunks surrounding the player this tick
+ for ( int chunk = 0; chunk < chunksPerPlayer; chunk++ )
@@ -100,7 +101,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ int dx = ( random.nextBoolean() ? 1 : -1 ) * random.nextInt( randRange );
+ int dz = ( random.nextBoolean() ? 1 : -1 ) * random.nextInt( randRange );
+ long hash = chunkToKey( dx + j, dz + k );
-+ if ( !chunkTickList.contains( hash ) && this.isChunkLoaded( dx + j, dz + k ) )
++ if ( !chunkTickList.contains( hash ) && this.chunkProvider.isChunkLoaded(dx + j, dz + k ) )
+ {
+ chunkTickList.put( hash, (short) -1 ); // no players
}
@@ -113,41 +114,53 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -0,0 +0,0 @@ public class WorldServer extends World {
- // CraftBukkit start
- // Iterator iterator = this.chunkTickList.iterator();
+@@ -0,0 +0,0 @@ public class WorldServer extends World implements IAsyncTaskHandler {
+ protected void h() {
+ super.h();
+ if (this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) {
+- Iterator iterator = this.chunkTickList.iterator();
++ // Spigot start
++ gnu.trove.iterator.TLongShortIterator iterator = this.chunkTickList.iterator();
-- for (long chunkCoord : this.chunkTickList.popAll()) {
-+ // Spigot start
-+ for (net.minecraft.util.gnu.trove.iterator.TLongShortIterator iter = chunkTickList.iterator(); iter.hasNext();) {
-+ iter.advance();
-+ long chunkCoord = iter.key();
-+ int chunkX = World.keyToX(chunkCoord);
-+ int chunkZ = World.keyToZ(chunkCoord);
-+ // If unloaded, or in procedd of being unloaded, drop it
-+ if ( ( !this.isChunkLoaded( chunkX, chunkZ ) ) || ( this.chunkProviderServer.unloadQueue.contains( chunkX, chunkZ ) ) )
+ while (iterator.hasNext()) {
+- ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) iterator.next();
++ iterator.advance();
++ long chunkCoord = iterator.key();
+
+- this.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z).b(false);
++ this.getChunkAt(World.keyToX( chunkCoord ), World.keyToZ( chunkCoord )).b(false);
++ // Spigot end
+ }
+
+ } else {
+@@ -0,0 +0,0 @@ public class WorldServer extends World implements IAsyncTaskHandler {
+ // ChunkCoordIntPair chunkcoordintpair1 = (ChunkCoordIntPair) iterator1.next();
+ // int k = chunkcoordintpair1.x * 16;
+ // int l = chunkcoordintpair1.z * 16;
+- for (long chunkCoord : chunkTickList.popAll()) {
+- int chunkX = LongHash.msw(chunkCoord);
+- int chunkZ = LongHash.lsw(chunkCoord);
++ // Spigot start
++ for (gnu.trove.iterator.TLongShortIterator iter = chunkTickList.iterator(); iter.hasNext(); )
+ {
-+ iter.remove();
-+ continue;
-+ }
-+ // Spigot end
- // ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) iterator.next();
-- int chunkX = LongHash.msw(chunkCoord);
-- int chunkZ = LongHash.lsw(chunkCoord);
- int k = chunkX * 16;
- int l = chunkZ * 16;
++ iter.advance();
++ long chunkCoord = iter.key();
++ int chunkX = World.keyToX( chunkCoord );
++ int chunkZ = World.keyToZ( chunkCoord );
++ // If unloaded, or in procedd of being unloaded, drop it
++ if ( ( !this.chunkProvider.isChunkLoaded( chunkX, chunkZ ) ) || ( this.chunkProviderServer.unloadQueue.contains( chunkX, chunkZ ) ) )
++ {
++ iter.remove();
++ continue;
++ }
++ // Spigot end
++ // ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) iterator.next();
+ int k = chunkX * 16;
+ int l = chunkZ * 16;
+
+@@ -0,0 +0,0 @@ public class WorldServer extends World implements IAsyncTaskHandler {
+ }
-@@ -0,0 +0,0 @@ public class WorldServer extends World {
-
- if (block.isTicking()) {
- ++i;
-+ this.growthOdds = (iter.value() < 1) ? this.modifiedOdds : 100; // Spigot - grow fast if no players are in this chunk (value = player count)
- block.a(this, k2 + k, i3 + chunksection.getYPosition(), l2 + l, this.random);
- }
- }
-@@ -0,0 +0,0 @@ public class WorldServer extends World {
-
- this.methodProfiler.b();
}
+ // Spigot Start
+ if ( spigotConfig.clearChunksOnTick )
@@ -157,7 +170,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Spigot End
}
- public boolean a(int i, int j, int k, Block block) {
+ protected BlockPosition a(BlockPosition blockposition) {
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
diff --git a/CraftBukkit-Patches/0007-Crop-Growth-Rates.patch b/CraftBukkit-Patches/0007-Crop-Growth-Rates.patch
index 612e6a6f55..a468c751ea 100644
--- a/CraftBukkit-Patches/0007-Crop-Growth-Rates.patch
+++ b/CraftBukkit-Patches/0007-Crop-Growth-Rates.patch
@@ -31,91 +31,90 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/BlockCactus.java
+++ b/src/main/java/net/minecraft/server/BlockCactus.java
@@ -0,0 +0,0 @@ public class BlockCactus extends Block {
- if (l < 3) {
- int i1 = world.getData(i, j, k);
+ if (i < 3) {
+ int j = ((Integer) iblockdata.get(BlockCactus.AGE)).intValue();
+
+- if (j == 15) {
++ if (j >= (byte) range(3, (world.growthOdds / world.spigotConfig.cactusModifier * 15) + 0.5F, 15)) { // Spigot
+ world.setTypeUpdate(blockposition1, this.getBlockData());
+ IBlockData iblockdata1 = iblockdata.set(BlockCactus.AGE, Integer.valueOf(0));
-- if (i1 == 15) {
-+ if (i1 >= (byte) range(3, (world.growthOdds / world.spigotConfig.cactusModifier * 15) + 0.5F, 15)) { // Spigot
- CraftEventFactory.handleBlockGrowEvent(world, i, j + 1, k, this, 0); // CraftBukkit
- world.setData(i, j, k, 0, 4);
- this.doPhysics(world, i, j + 1, k, this);
diff --git a/src/main/java/net/minecraft/server/BlockCrops.java b/src/main/java/net/minecraft/server/BlockCrops.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/BlockCrops.java
+++ b/src/main/java/net/minecraft/server/BlockCrops.java
@@ -0,0 +0,0 @@ public class BlockCrops extends BlockPlant implements IBlockFragilePlantElement
- if (l < 7) {
- float f = this.n(world, i, j, k);
+ if (i < 7) {
+ float f = a((Block) this, world, blockposition);
- if (random.nextInt((int) (25.0F / f) + 1) == 0) {
-+ if (random.nextInt((int) (world.growthOdds / world.spigotConfig.wheatModifier * (25.0F / f)) + 1) == 0) { // Spigot
- ++l;
- CraftEventFactory.handleBlockGrowEvent(world, i, j, k, this, l); // CraftBukkit
- }
+- // CraftBukkit start
++ if (random.nextInt((int) (world.growthOdds / world.spigotConfig.wheatModifier * (25.0F / f)) + 1) == 0) { // Spigot // CraftBukkit start
+ IBlockData data = iblockdata.set(AGE, Integer.valueOf(i + 1));
+ CraftEventFactory.handleBlockGrowEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this, toLegacyData(data));
+ // CraftBukkit end
diff --git a/src/main/java/net/minecraft/server/BlockGrass.java b/src/main/java/net/minecraft/server/BlockGrass.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/BlockGrass.java
+++ b/src/main/java/net/minecraft/server/BlockGrass.java
@@ -0,0 +0,0 @@ public class BlockGrass extends Block implements IBlockFragilePlantElement {
- }
// CraftBukkit end
- } else if (world.getLightLevel(i, j + 1, k) >= 9) {
-- for (int l = 0; l < 4; ++l) {
-+ int numGrowth = Math.min(4, Math.max(20, (int) (4 * 100F / world.growthOdds))); // Spigot
-+ for (int l = 0; l < numGrowth; ++l) { // Spigot
- int i1 = i + random.nextInt(3) - 1;
- int j1 = j + random.nextInt(5) - 3;
- int k1 = k + random.nextInt(3) - 1;
+ } else {
+ if (world.getLightLevel(blockposition.up()) >= 9) {
+- for (int i = 0; i < 4; ++i) {
++ for (int i = 0; i < Math.min(4, Math.max(20, (int) (4 * 100F / world.growthOdds))); ++i) { // Spigot
+ BlockPosition blockposition1 = blockposition.a(random.nextInt(3) - 1, random.nextInt(5) - 3, random.nextInt(3) - 1);
+ Block block = world.getType(blockposition1.up()).getBlock();
+ IBlockData iblockdata1 = world.getType(blockposition1);
diff --git a/src/main/java/net/minecraft/server/BlockMushroom.java b/src/main/java/net/minecraft/server/BlockMushroom.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/BlockMushroom.java
+++ b/src/main/java/net/minecraft/server/BlockMushroom.java
@@ -0,0 +0,0 @@ public class BlockMushroom extends BlockPlant implements IBlockFragilePlantEleme
- public void a(World world, int i, int j, int k, Random random) {
- final int sourceX = i, sourceY = j, sourceZ = k; // CraftBukkit
+ public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) {
+ final int sourceX = blockposition.getX(), sourceY = blockposition.getY(), sourceZ = blockposition.getZ(); // CraftBukkit
- if (random.nextInt(25) == 0) {
-+ if (random.nextInt(Math.max(1, (int) world.growthOdds / world.spigotConfig.mushroomModifier * 25)) == 0) { // Spigot
- byte b0 = 4;
- int l = 5;
-
++ if (random.nextInt(Math.max(1, (int) world.growthOdds / world.spigotConfig.mushroomModifier * 25)) == 0) { // Spigot int i = 5;
+ int i = 5;
+ boolean flag = true;
+ Iterator iterator = BlockPosition.b(blockposition.a(-4, -1, -4), blockposition.a(4, 1, 4)).iterator();
diff --git a/src/main/java/net/minecraft/server/BlockMycel.java b/src/main/java/net/minecraft/server/BlockMycel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/BlockMycel.java
+++ b/src/main/java/net/minecraft/server/BlockMycel.java
@@ -0,0 +0,0 @@ public class BlockMycel extends Block {
- }
// CraftBukkit end
- } else if (world.getLightLevel(i, j + 1, k) >= 9) {
-- for (int l = 0; l < 4; ++l) {
-+ int numGrowth = Math.min(4, Math.max(20, (int) (4 * 100F / world.growthOdds))); // Spigot
-+ for (int l = 0; l < numGrowth; ++l) { // Spigot
- int i1 = i + random.nextInt(3) - 1;
- int j1 = j + random.nextInt(5) - 3;
- int k1 = k + random.nextInt(3) - 1;
+ } else {
+ if (world.getLightLevel(blockposition.up()) >= 9) {
+- for (int i = 0; i < 4; ++i) {
++ for (int i = 0; i < Math.min(4, Math.max(20, (int) (4 * 100F / world.growthOdds))); ++i) { // Spigot
+ BlockPosition blockposition1 = blockposition.a(random.nextInt(3) - 1, random.nextInt(5) - 3, random.nextInt(3) - 1);
+ IBlockData iblockdata1 = world.getType(blockposition1);
+ Block block = world.getType(blockposition1.up()).getBlock();
diff --git a/src/main/java/net/minecraft/server/BlockReed.java b/src/main/java/net/minecraft/server/BlockReed.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/BlockReed.java
+++ b/src/main/java/net/minecraft/server/BlockReed.java
@@ -0,0 +0,0 @@ public class BlockReed extends Block {
- if (l < 3) {
- int i1 = world.getData(i, j, k);
+ if (i < 3) {
+ int j = ((Integer) iblockdata.get(BlockReed.AGE)).intValue();
-- if (i1 == 15) {
-+ if (i1 >= (byte) range(3, (world.growthOdds / world.spigotConfig.caneModifier * 15) + 0.5F, 15)) { // Spigot
- org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, i, j + 1, k, this, 0); // CraftBukkit
- world.setData(i, j, k, 0, 4);
- } else {
+- if (j == 15) {
++ if (j >= (byte) range(3, (world.growthOdds / world.spigotConfig.caneModifier * 15) + 0.5F, 15)) { // Spigot
+ // CraftBukkit start
+ // world.setTypeUpdate(blockposition.up(), this.getBlockData());
+ // world.setTypeAndData(blockposition, iblockdata.set(BlockReed.AGE, Integer.valueOf(0)), 4);
diff --git a/src/main/java/net/minecraft/server/BlockSapling.java b/src/main/java/net/minecraft/server/BlockSapling.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/BlockSapling.java
+++ b/src/main/java/net/minecraft/server/BlockSapling.java
@@ -0,0 +0,0 @@ public class BlockSapling extends BlockPlant implements IBlockFragilePlantElemen
- public void a(World world, int i, int j, int k, Random random) {
+ public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) {
if (!world.isStatic) {
- super.a(world, i, j, k, random);
-- if (world.getLightLevel(i, j + 1, k) >= 9 && random.nextInt(7) == 0) {
-+ if (world.getLightLevel(i, j + 1, k) >= 9 && (random.nextInt(Math.max(2, (int) ((world.growthOdds / world.spigotConfig.saplingModifier * 7) + 0.5F))) == 0)) { // Spigot
+ super.b(world, blockposition, iblockdata, random);
+- if (world.getLightLevel(blockposition.up()) >= 9 && random.nextInt(7) == 0) {
++ if (world.getLightLevel(blockposition.up()) >= 9 && (random.nextInt(Math.max(2, (int) ((world.growthOdds / world.spigotConfig.saplingModifier * 7) + 0.5F))) == 0)) { // Spigot) {
// CraftBukkit start
world.captureTreeGeneration = true;
// CraftBukkit end
@@ -124,14 +123,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/BlockStem.java
+++ b/src/main/java/net/minecraft/server/BlockStem.java
@@ -0,0 +0,0 @@ public class BlockStem extends BlockPlant implements IBlockFragilePlantElement {
- if (world.getLightLevel(i, j + 1, k) >= 9) {
- float f = this.n(world, i, j, k);
+ if (world.getLightLevel(blockposition.up()) >= 9) {
+ float f = BlockCrops.a((Block) this, world, blockposition);
- if (random.nextInt((int) (25.0F / f) + 1) == 0) {
+ if (random.nextInt((int) (world.growthOdds / (this == Blocks.PUMPKIN_STEM? world.spigotConfig.pumpkinModifier : world.spigotConfig.melonModifier) * (25.0F / f)) + 1) == 0) { // Spigot
- int l = world.getData(i, j, k);
+ int i = ((Integer) iblockdata.get(BlockStem.AGE)).intValue();
- if (l < 7) {
+ if (i < 7) {
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
diff --git a/CraftBukkit-Patches/0008-More-Efficient-Chunk-Save-Queue.patch b/CraftBukkit-Patches/0008-More-Efficient-Chunk-Save-Queue.patch
index 726e4c609e..4117ca95ad 100644
--- a/CraftBukkit-Patches/0008-More-Efficient-Chunk-Save-Queue.patch
+++ b/CraftBukkit-Patches/0008-More-Efficient-Chunk-Save-Queue.patch
@@ -10,13 +10,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
@@ -0,0 +0,0 @@ import org.apache.logging.log4j.Logger;
-
public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
-+ private java.util.LinkedHashMap pendingSaves = new java.util.LinkedHashMap(); // Spigot
private static final Logger a = LogManager.getLogger();
- private List b = new ArrayList();
- private Set c = new HashSet();
+- private List b = Lists.newArrayList();
+- private Set c = Sets.newHashSet();
++ // Spigot start
++ private java.util.LinkedHashMap pendingSaves = new java.util.LinkedHashMap();
++ // private List b = Lists.newArrayList();
++ // private Set c = Sets.newHashSet();
++ // Spigot end
+ private Object d = new Object();
+ private final File e;
+
@@ -0,0 +0,0 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j);
@@ -71,11 +77,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (this.pendingSaves.put(chunkcoordintpair, new PendingChunkToSave(chunkcoordintpair, nbttagcompound)) != null) {
+ return;
}
--
+
- this.b.add(new PendingChunkToSave(chunkcoordintpair, nbttagcompound));
- this.c.add(chunkcoordintpair);
++ // this.b.add(new PendingChunkToSave(chunkcoordintpair, nbttagcompound));
++ // this.c.add(chunkcoordintpair);
+ // Spigot end
- FileIOThread.a.a(this);
+ FileIOThread.a().a(this);
}
}
@@ -0,0 +0,0 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
diff --git a/CraftBukkit-Patches/0009-Merge-tweaks-and-configuration.patch b/CraftBukkit-Patches/0009-Merge-tweaks-and-configuration.patch
index 409d18efc8..e0a72c3ebf 100644
--- a/CraftBukkit-Patches/0009-Merge-tweaks-and-configuration.patch
+++ b/CraftBukkit-Patches/0009-Merge-tweaks-and-configuration.patch
@@ -12,34 +12,34 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public class EntityItem extends Entity {
}
- private void k() {
-- Iterator iterator = this.world.a(EntityItem.class, this.boundingBox.grow(0.5D, 0.0D, 0.5D)).iterator();
+ private void w() {
+- Iterator iterator = this.world.a(EntityItem.class, this.getBoundingBox().grow(0.5D, 0.0D, 0.5D)).iterator();
+ // Spigot start
+ double radius = world.spigotConfig.itemMerge;
-+ Iterator iterator = this.world.a(EntityItem.class, this.boundingBox.grow(radius, radius, radius)).iterator();
++ Iterator iterator = this.world.a(EntityItem.class, this.getBoundingBox().grow(radius, radius, radius)).iterator();
+ // Spigot end
while (iterator.hasNext()) {
EntityItem entityitem = (EntityItem) iterator.next();
@@ -0,0 +0,0 @@ public class EntityItem extends Entity {
- } else if (itemstack1.count + itemstack.count > itemstack1.getMaxStackSize()) {
- return false;
- } else {
-- itemstack1.count += itemstack.count;
-- entityitem.pickupDelay = Math.max(entityitem.pickupDelay, this.pickupDelay);
-- entityitem.age = Math.min(entityitem.age, this.age);
-- entityitem.setItemStack(itemstack1);
-- this.die();
-+ // Spigot start
-+ itemstack.count += itemstack1.count;
-+ this.pickupDelay = Math.max(entityitem.pickupDelay, this.pickupDelay);
-+ this.age = Math.min(entityitem.age, this.age);
-+ this.setItemStack(itemstack);
-+ entityitem.die();
-+ // Spigot end
- return true;
- }
- } else {
+ } else if (itemstack1.count + itemstack.count > itemstack1.getMaxStackSize()) {
+ return false;
+ } else {
+- itemstack1.count += itemstack.count;
+- entityitem.pickupDelay = Math.max(entityitem.pickupDelay, this.pickupDelay);
+- entityitem.age = Math.min(entityitem.age, this.age);
+- entityitem.setItemStack(itemstack1);
+- this.die();
++ // Spigot start
++ itemstack.count += itemstack1.count;
++ this.pickupDelay = Math.max(entityitem.pickupDelay, this.pickupDelay);
++ this.age = Math.min(entityitem.age, this.age);
++ this.setItemStack(itemstack);
++ entityitem.die();
++ // Spigot end
+ return true;
+ }
+ } else {
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/World.java
@@ -53,7 +53,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ EntityExperienceOrb xp = (EntityExperienceOrb) entity;
+ double radius = spigotConfig.expMerge;
+ if (radius > 0) {
-+ List entities = this.getEntities(entity, entity.boundingBox.grow(radius, radius, radius));
++ List entities = this.getEntities(entity, entity.getBoundingBox().grow(radius, radius, radius));
+ for (Entity e : entities) {
+ if (e instanceof EntityExperienceOrb) {
+ EntityExperienceOrb loopItem = (EntityExperienceOrb) e;
diff --git a/CraftBukkit-Patches/0011-Async-Operation-Catching.patch b/CraftBukkit-Patches/0010-Async-Operation-Catching.patch
similarity index 90%
rename from CraftBukkit-Patches/0011-Async-Operation-Catching.patch
rename to CraftBukkit-Patches/0010-Async-Operation-Catching.patch
index 75c6efbbc6..56234e2efe 100644
--- a/CraftBukkit-Patches/0011-Async-Operation-Catching.patch
+++ b/CraftBukkit-Patches/0010-Async-Operation-Catching.patch
@@ -13,13 +13,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return 10;
}
-- public void onPlace(World world, int i, int j, int k) {}
-+ public void onPlace(World world, int i, int j, int k) {
+- public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) {}
++ public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) {
+ org.spigotmc.AsyncCatcher.catchOp( "block onPlace"); // Spigot
+ }
-- public void remove(World world, int i, int j, int k, Block block, int l) {}
-+ public void remove(World world, int i, int j, int k, Block block, int l) {
+- public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) {}
++ public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) {
+ org.spigotmc.AsyncCatcher.catchOp( "block remove"); // Spigot
+ }
@@ -55,8 +55,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public void updatePlayer(EntityPlayer entityplayer) {
+ org.spigotmc.AsyncCatcher.catchOp( "player tracker update"); // Spigot
if (entityplayer != this.tracker) {
- double d0 = entityplayer.locX - (double) (this.xLoc / 32);
- double d1 = entityplayer.locZ - (double) (this.zLoc / 32);
+ if (this.c(entityplayer)) {
+ if (!this.trackedPlayers.contains(entityplayer) && (this.e(entityplayer) || this.tracker.attachedToPlayer)) {
@@ -0,0 +0,0 @@ public class EntityTrackerEntry {
}
@@ -76,7 +76,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ org.spigotmc.AsyncCatcher.catchOp( "entity add"); // Spigot
if (entity == null) return false;
// CraftBukkit end
-
+ int i = MathHelper.floor(entity.locX / 16.0D);
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
}
@@ -88,11 +88,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
}
- public void a(List list) {
+ public void b(Collection collection) {
+ org.spigotmc.AsyncCatcher.catchOp( "entity world add"); // Spigot
// CraftBukkit start
- // this.entityList.addAll(list);
- Entity entity = null;
+ // this.entityList.addAll(collection);
+ Iterator iterator = collection.iterator();
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
diff --git a/CraftBukkit-Patches/0010-LongHash-Tweaks.patch b/CraftBukkit-Patches/0010-LongHash-Tweaks.patch
deleted file mode 100644
index 75487b6803..0000000000
--- a/CraftBukkit-Patches/0010-LongHash-Tweaks.patch
+++ /dev/null
@@ -1,223 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: md_5
-Date: Fri, 21 Jun 2013 17:13:47 +1000
-Subject: [PATCH] LongHash Tweaks
-
-Tweaks the LongHash algorithm and provides a large array based map to look up values centered around the origin, ie the access normally seen on a Minecraft server.
-
-diff --git a/src/main/java/org/bukkit/craftbukkit/util/LongHash.java b/src/main/java/org/bukkit/craftbukkit/util/LongHash.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/craftbukkit/util/LongHash.java
-+++ b/src/main/java/org/bukkit/craftbukkit/util/LongHash.java
-@@ -0,0 +0,0 @@ public class LongHash {
- }
-
- public static int lsw(long l) {
-- return (int) (l & 0xFFFFFFFF) + Integer.MIN_VALUE;
-+ return (int) (l) + Integer.MIN_VALUE; // Spigot - remove redundant &
- }
- }
-diff --git a/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java b/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java
-+++ b/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java
-@@ -0,0 +0,0 @@ public class LongHashSet {
- private int elements;
- private long[] values;
- private int modCount;
-+ private org.spigotmc.FlatMap flat = new org.spigotmc.FlatMap(); // Spigot
-
- public LongHashSet() {
- this(INITIAL_SIZE);
-@@ -0,0 +0,0 @@ public class LongHashSet {
- }
-
- public boolean contains(int msw, int lsw) {
-+ // Spigot start
-+ if ( elements == 0 )
-+ {
-+ return false;
-+ }
-+ if ( flat.contains( msw, lsw ) )
-+ {
-+ return true;
-+ }
-+ // Spigot end
- return contains(LongHash.toLong(msw, lsw));
- }
-
- public boolean contains(long value) {
-+ // Spigot start
-+ if ( elements == 0 )
-+ {
-+ return false;
-+ }
-+ if ( flat.contains( value ) )
-+ {
-+ return true;
-+ }
-+ // Spigot end
- int hash = hash(value);
- int index = (hash & 0x7FFFFFFF) % values.length;
- int offset = 1;
-@@ -0,0 +0,0 @@ public class LongHashSet {
- }
-
- public boolean add(long value) {
-+ flat.put( value, Boolean.TRUE ); // Spigot
- int hash = hash(value);
- int index = (hash & 0x7FFFFFFF) % values.length;
- int offset = 1;
-@@ -0,0 +0,0 @@ public class LongHashSet {
- }
-
- public void remove(int msw, int lsw) {
-- remove(LongHash.toLong(msw, lsw));
-+ // Spigot start
-+ flat.remove(msw, lsw);
-+ remove0(LongHash.toLong(msw, lsw));
- }
-
- public boolean remove(long value) {
-+ flat.remove(value);
-+ return remove0(value);
-+ }
-+
-+ private boolean remove0(long value) {
-+ // Spigot end
- int hash = hash(value);
- int index = (hash & 0x7FFFFFFF) % values.length;
- int offset = 1;
-@@ -0,0 +0,0 @@ public class LongHashSet {
-
- freeEntries = values.length;
- modCount++;
-+ flat = new org.spigotmc.FlatMap();
- }
-
- public long[] toArray() {
-diff --git a/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java b/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java
-+++ b/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java
-@@ -0,0 +0,0 @@ public class LongObjectHashMap implements Cloneable, Serializable {
- private transient V[][] values;
- private transient int modCount;
- private transient int size;
-+ private transient org.spigotmc.FlatMap flat = new org.spigotmc.FlatMap(); // Spigot
-
- public LongObjectHashMap() {
- initialize();
-@@ -0,0 +0,0 @@ public class LongObjectHashMap implements Cloneable, Serializable {
- }
-
- public V get(long key) {
-+ // Spigot start
-+ if ( size == 0 )
-+ {
-+ return null;
-+ }
-+ V val = flat.get( key );
-+ if ( val != null )
-+ {
-+ return val;
-+ }
-+ // Spigot end
- int index = (int) (keyIndex(key) & (BUCKET_SIZE - 1));
- long[] inner = keys[index];
- if (inner == null) return null;
-@@ -0,0 +0,0 @@ public class LongObjectHashMap implements Cloneable, Serializable {
- }
-
- public V put(long key, V value) {
-+ flat.put(key, value); // Spigot
- int index = (int) (keyIndex(key) & (BUCKET_SIZE - 1));
- long[] innerKeys = keys[index];
- V[] innerValues = values[index];
-@@ -0,0 +0,0 @@ public class LongObjectHashMap implements Cloneable, Serializable {
- }
-
- public V remove(long key) {
-+ flat.remove(key); // Spigot
- int index = (int) (keyIndex(key) & (BUCKET_SIZE - 1));
- long[] inner = keys[index];
- if (inner == null) {
-@@ -0,0 +0,0 @@ public class LongObjectHashMap implements Cloneable, Serializable {
- size = 0;
- Arrays.fill(keys, null);
- Arrays.fill(values, null);
-+ flat = new org.spigotmc.FlatMap();
- }
-
- public Set keySet() {
-diff --git a/src/main/java/org/spigotmc/FlatMap.java b/src/main/java/org/spigotmc/FlatMap.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
---- /dev/null
-+++ b/src/main/java/org/spigotmc/FlatMap.java
-@@ -0,0 +0,0 @@
-+package org.spigotmc;
-+
-+import org.bukkit.craftbukkit.util.LongHash;
-+
-+public class FlatMap
-+{
-+
-+ private static final int FLAT_LOOKUP_SIZE = 512;
-+ private final Object[][] flatLookup = new Object[ FLAT_LOOKUP_SIZE * 2 ][ FLAT_LOOKUP_SIZE * 2 ];
-+
-+ public void put(long msw, long lsw, V value)
-+ {
-+ long acx = Math.abs( msw );
-+ long acz = Math.abs( lsw );
-+ if ( acx < FLAT_LOOKUP_SIZE && acz < FLAT_LOOKUP_SIZE )
-+ {
-+ flatLookup[(int) ( msw + FLAT_LOOKUP_SIZE )][(int) ( lsw + FLAT_LOOKUP_SIZE )] = value;
-+ }
-+ }
-+
-+ public void put(long key, V value)
-+ {
-+ put( LongHash.msw( key ), LongHash.lsw( key ), value );
-+
-+ }
-+
-+ public void remove(long key)
-+ {
-+ put( key, null );
-+ }
-+
-+ public void remove(long msw, long lsw)
-+ {
-+ put( msw, lsw, null );
-+ }
-+
-+ public boolean contains(long msw, long lsw)
-+ {
-+ return get( msw, lsw ) != null;
-+ }
-+
-+ public boolean contains(long key)
-+ {
-+ return get( key ) != null;
-+ }
-+
-+ public V get(long msw, long lsw)
-+ {
-+ long acx = Math.abs( msw );
-+ long acz = Math.abs( lsw );
-+ if ( acx < FLAT_LOOKUP_SIZE && acz < FLAT_LOOKUP_SIZE )
-+ {
-+ return (V) flatLookup[(int) ( msw + FLAT_LOOKUP_SIZE )][(int) ( lsw + FLAT_LOOKUP_SIZE )];
-+ } else
-+ {
-+ return null;
-+ }
-+ }
-+
-+ public V get(long key)
-+ {
-+ return get( LongHash.msw( key ), LongHash.lsw( key ) );
-+ }
-+}
---
\ No newline at end of file
diff --git a/CraftBukkit-Patches/0012-View-Distance.patch b/CraftBukkit-Patches/0011-View-Distance.patch
similarity index 90%
rename from CraftBukkit-Patches/0012-View-Distance.patch
rename to CraftBukkit-Patches/0011-View-Distance.patch
index 1eb8acd57f..7c53455f20 100644
--- a/CraftBukkit-Patches/0012-View-Distance.patch
+++ b/CraftBukkit-Patches/0011-View-Distance.patch
@@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- public PlayerChunkMap(WorldServer worldserver) {
+ public PlayerChunkMap(WorldServer worldserver, int viewDistance /* Spigot */) {
this.world = worldserver;
-- this.a(worldserver.getMinecraftServer().getPlayerList().s());
+- this.a(worldserver.getMinecraftServer().getPlayerList().t());
+ this.a(viewDistance); // Spigot
}
@@ -25,15 +25,15 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -0,0 +0,0 @@ public class WorldServer extends World {
+@@ -0,0 +0,0 @@ public class WorldServer extends World implements IAsyncTaskHandler {
// CraftBukkit end
this.server = minecraftserver;
this.tracker = new EntityTracker(this);
- this.manager = new PlayerChunkMap(this);
+ this.manager = new PlayerChunkMap(this, spigotConfig.viewDistance); // Spigot
- if (this.entitiesById == null) {
- this.entitiesById = new IntHashMap();
- }
+ this.worldProvider.a(this);
+ this.chunkProvider = this.k();
+ this.Q = new org.bukkit.craftbukkit.CraftTravelAgent(this); // CraftBukkit
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
diff --git a/CraftBukkit-Patches/0013-Spigot-Timings.patch b/CraftBukkit-Patches/0012-Spigot-Timings.patch
similarity index 88%
rename from CraftBukkit-Patches/0013-Spigot-Timings.patch
rename to CraftBukkit-Patches/0012-Spigot-Timings.patch
index 04f593699c..12d3de7e82 100644
--- a/CraftBukkit-Patches/0013-Spigot-Timings.patch
+++ b/CraftBukkit-Patches/0012-Spigot-Timings.patch
@@ -14,23 +14,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public void loadNearby(IChunkProvider ichunkprovider, IChunkProvider ichunkprovider1, int i, int j) {
+ world.timings.syncChunkLoadPostTimer.startTiming(); // Spigot
- if (!this.done && ichunkprovider.isChunkLoaded(i + 1, j + 1) && ichunkprovider.isChunkLoaded(i, j + 1) && ichunkprovider.isChunkLoaded(i + 1, j)) {
- ichunkprovider.getChunkAt(ichunkprovider1, i, j);
- }
+ boolean flag = ichunkprovider.isChunkLoaded(i, j - 1);
+ boolean flag1 = ichunkprovider.isChunkLoaded(i + 1, j);
+ boolean flag2 = ichunkprovider.isChunkLoaded(i, j + 1);
@@ -0,0 +0,0 @@ public class Chunk {
- if (ichunkprovider.isChunkLoaded(i - 1, j - 1) && !ichunkprovider.getOrCreateChunk(i - 1, j - 1).done && ichunkprovider.isChunkLoaded(i, j - 1) && ichunkprovider.isChunkLoaded(i - 1, j)) {
- ichunkprovider.getChunkAt(ichunkprovider1, i - 1, j - 1);
+ }
}
+
+ world.timings.syncChunkLoadPostTimer.stopTiming(); // Spigot
}
- public int d(int i, int j) {
+ public BlockPosition h(BlockPosition blockposition) {
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -0,0 +0,0 @@ public class ChunkProviderServer implements IChunkProvider {
- boolean newChunk = false;
+ // CraftBukkit end
if (chunk == null) {
+ world.timings.syncChunkLoadTimer.startTiming(); // Spigot
@@ -38,8 +38,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (chunk == null) {
if (this.chunkProvider == null) {
@@ -0,0 +0,0 @@ public class ChunkProviderServer implements IChunkProvider {
- }
// CraftBukkit end
+
chunk.loadNearby(this, this, i, j);
+ world.timings.syncChunkLoadTimer.stopTiming(); // Spigot
}
@@ -47,10 +47,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return chunk;
@@ -0,0 +0,0 @@ public class ChunkProviderServer implements IChunkProvider {
if (chunk != null) {
- chunk.lastSaved = this.world.getTime();
+ chunk.setLastSaved(this.world.getTime());
if (this.chunkProvider != null) {
+ world.timings.syncChunkLoadStructuresTimer.startTiming(); // Spigot
- this.chunkProvider.recreateStructures(i, j);
+ this.chunkProvider.recreateStructures(chunk, i, j);
+ world.timings.syncChunkLoadStructuresTimer.stopTiming(); // Spigot
}
}
@@ -64,7 +64,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit start - Add async variant, provide compatibility
public Chunk a(World world, int i, int j) {
+ world.timings.syncChunkLoadDataTimer.startTiming(); // Spigot
- Object[] data = this.loadChunk(world, i, j);
+ Object[] data = loadChunk(world, i, j);
+ world.timings.syncChunkLoadDataTimer.stopTiming(); // Spigot
if (data != null) {
Chunk chunk = (Chunk) data[0];
@@ -102,7 +102,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
+ world.timings.syncChunkLoadTileTicksTimer.stopTiming(); // Spigot
- // return chunk; // CraftBukkit
+ // return chunk; // CraftBukkit
}
diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
@@ -119,19 +119,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
}
- public void aB() {
+ public void aM() {
+ SpigotTimings.serverCommandTimer.startTiming(); // Spigot
- while (!this.j.isEmpty()) {
- ServerCommand servercommand = (ServerCommand) this.j.remove(0);
+ while (!this.k.isEmpty()) {
+ ServerCommand servercommand = (ServerCommand) this.k.remove(0);
@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
- this.server.dispatchServerCommand(this.console, servercommand);
// CraftBukkit end
}
+
+ SpigotTimings.serverCommandTimer.stopTiming(); // Spigot
}
- public boolean X() {
+ public boolean ad() {
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/Entity.java
@@ -144,7 +144,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
import org.bukkit.event.entity.EntityCombustByEntityEvent;
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.painting.PaintingBreakByEntityEvent;
-@@ -0,0 +0,0 @@ public abstract class Entity {
+@@ -0,0 +0,0 @@ public abstract class Entity implements ICommandListener {
public boolean valid; // CraftBukkit
public org.bukkit.projectiles.ProjectileSource projectileSource; // CraftBukkit - For projectiles only
@@ -153,22 +153,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public int getId() {
return this.id;
}
-@@ -0,0 +0,0 @@ public abstract class Entity {
- return;
- }
- // CraftBukkit end
+@@ -0,0 +0,0 @@ public abstract class Entity implements ICommandListener {
+ }
+
+ public void move(double d0, double d1, double d2) {
+ org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.startTiming(); // Spigot
- if (this.X) {
- this.boundingBox.d(d0, d1, d2);
- this.locX = (this.boundingBox.a + this.boundingBox.d) / 2.0D;
-@@ -0,0 +0,0 @@ public abstract class Entity {
++
+ if (this.T) {
+ this.a(this.getBoundingBox().c(d0, d1, d2));
+ this.recalcPosition();
+@@ -0,0 +0,0 @@ public abstract class Entity implements ICommandListener {
this.world.methodProfiler.b();
}
+ org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.stopTiming(); // Spigot
}
- protected String H() {
+ private void recalcPosition() {
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/EntityLiving.java
@@ -181,21 +182,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
public abstract class EntityLiving extends Entity {
- private static final UUID b = UUID.fromString("662A6B8D-DA3E-4C1C-8813-96EA6097278D");
+ private static final UUID a = UUID.fromString("662A6B8D-DA3E-4C1C-8813-96EA6097278D");
@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
}
- public void h() {
+ public void s_() {
+ SpigotTimings.timerEntityBaseTick.startTiming(); // Spigot
- super.h();
+ super.s_();
if (!this.world.isStatic) {
- int i = this.aZ();
+ int i = this.bu();
@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
}
}
+ SpigotTimings.timerEntityBaseTick.stopTiming(); // Spigot
- this.e();
+ this.m();
+ SpigotTimings.timerEntityTickRest.startTiming(); // Spigot
double d0 = this.locX - this.lastX;
double d1 = this.locZ - this.lastZ;
@@ -203,39 +204,39 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
this.world.methodProfiler.b();
- this.aX += f2;
+ this.aR += f2;
+ SpigotTimings.timerEntityTickRest.stopTiming(); // Spigot
}
- protected float f(float f, float f1) {
+ protected float h(float f, float f1) {
@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
}
this.world.methodProfiler.a("ai");
+ SpigotTimings.timerEntityAI.startTiming(); // Spigot
- if (this.bh()) {
- this.bc = false;
- this.bd = 0.0F;
+ if (this.bC()) {
+ this.aW = false;
+ this.aX = 0.0F;
@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
- this.aO = this.yaw;
- }
+ this.doTick();
+ this.world.methodProfiler.b();
}
+ SpigotTimings.timerEntityAI.stopTiming(); // Spigot
this.world.methodProfiler.b();
this.world.methodProfiler.a("jump");
@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
- this.bd *= 0.98F;
- this.be *= 0.98F;
- this.bf *= 0.9F;
+ this.aX *= 0.98F;
+ this.aY *= 0.98F;
+ this.aZ *= 0.9F;
+ SpigotTimings.timerEntityAIMove.startTiming(); // Spigot
- this.e(this.bd, this.be);
+ this.g(this.aX, this.aY);
+ SpigotTimings.timerEntityAIMove.stopTiming(); // Spigot
this.world.methodProfiler.b();
this.world.methodProfiler.a("push");
if (!this.world.isStatic) {
+ SpigotTimings.timerEntityAICollision.startTiming(); // Spigot
- this.bo();
+ this.bK();
+ SpigotTimings.timerEntityAICollision.stopTiming(); // Spigot
}
@@ -244,36 +245,36 @@ diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
-@@ -0,0 +0,0 @@ import jline.console.ConsoleReader;
- import joptsimple.OptionSet;
+@@ -0,0 +0,0 @@ import joptsimple.OptionSet;
+ import org.bukkit.craftbukkit.Main;
import org.bukkit.World.Environment;
+import org.bukkit.craftbukkit.SpigotTimings; // Spigot
import org.bukkit.craftbukkit.util.Waitable;
import org.bukkit.event.server.RemoteServerCommandEvent;
import org.bukkit.event.world.WorldSaveEvent;
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
- protected void t() {}
+@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs
+ protected void x() {}
- protected void u() throws ExceptionWorldConflict { // CraftBukkit - added throws
+ protected void y() throws ExceptionWorldConflict { // CraftBukkit - added throws
+ SpigotTimings.serverTickTimer.startTiming(); // Spigot
long i = System.nanoTime();
++this.ticks;
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
+@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs
}
- if ((this.autosavePeriod > 0) && ((this.ticks % this.autosavePeriod) == 0)) { // CraftBukkit
+ if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit
+ SpigotTimings.worldSaveTimer.startTiming(); // Spigot
this.methodProfiler.a("save");
- this.u.savePlayers();
+ this.v.savePlayers();
this.saveChunks(true);
this.methodProfiler.b();
+ SpigotTimings.worldSaveTimer.stopTiming(); // Spigot
}
this.methodProfiler.a("tallying");
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
+@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs
this.methodProfiler.b();
this.methodProfiler.b();
@@ -281,8 +282,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ org.spigotmc.CustomTimingsHandler.tick(); // Spigot
}
- public void v() {
- this.methodProfiler.a("levels");
+ public void z() {
+@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs
+
+ this.methodProfiler.c("levels");
+ SpigotTimings.schedulerTimer.startTiming(); // Spigot
// CraftBukkit start
@@ -304,7 +307,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Send time updates to everyone, it will get the right time from the world the player is in.
if (this.ticks % 20 == 0) {
for (int i = 0; i < this.getPlayerList().players.size(); ++i) {
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
+@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs
entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateTime(entityplayer.world.getTime(), entityplayer.getPlayerTime(), entityplayer.world.getGameRules().getBoolean("doDaylightCycle"))); // Add support for per player time
}
}
@@ -312,27 +315,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
int i;
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
+@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs
CrashReport crashreport;
try {
+ worldserver.timings.doTick.startTiming(); // Spigot
worldserver.doTick();
+ worldserver.timings.doTick.stopTiming(); // Spigot
- } catch (Throwable throwable) {
- crashreport = CrashReport.a(throwable, "Exception ticking world");
+ } catch (Throwable throwable1) {
+ crashreport = CrashReport.a(throwable1, "Exception ticking world");
worldserver.a(crashreport);
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
+@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs
}
try {
+ worldserver.timings.tickEntities.startTiming(); // Spigot
worldserver.tickEntities();
+ worldserver.timings.tickEntities.stopTiming(); // Spigot
- } catch (Throwable throwable1) {
- crashreport = CrashReport.a(throwable1, "Exception ticking world entities");
+ } catch (Throwable throwable2) {
+ crashreport = CrashReport.a(throwable2, "Exception ticking world entities");
worldserver.a(crashreport);
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
+@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs
this.methodProfiler.b();
this.methodProfiler.a("tracker");
@@ -342,22 +345,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.methodProfiler.b();
this.methodProfiler.b();
// } // CraftBukkit
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
+@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs
}
this.methodProfiler.c("connection");
+ SpigotTimings.connectionTimer.startTiming(); // Spigot
- this.ai().c();
+ this.ao().c();
+ SpigotTimings.connectionTimer.stopTiming(); // Spigot
this.methodProfiler.c("players");
+ SpigotTimings.playerListTimer.startTiming(); // Spigot
- this.u.tick();
+ this.v.tick();
+ SpigotTimings.playerListTimer.stopTiming(); // Spigot
this.methodProfiler.c("tickables");
+ SpigotTimings.tickablesTimer.startTiming(); // Spigot
- for (i = 0; i < this.n.size(); ++i) {
- ((IUpdatePlayerListBox) this.n.get(i)).a();
+ for (i = 0; i < this.o.size(); ++i) {
+ ((IUpdatePlayerListBox) this.o.get(i)).c();
}
+ SpigotTimings.tickablesTimer.stopTiming(); // Spigot
@@ -367,16 +370,16 @@ diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
-@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketPlayInListener {
+@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList
// CraftBukkit end
private void handleCommand(String s) {
+ org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.startTiming(); // Spigot
+
- // CraftBukkit start - whole method
+ // CraftBukkit start - whole method
this.c.info(this.player.getName() + " issued server command: " + s);
-@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketPlayInListener {
+@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList
this.server.getPluginManager().callEvent(event);
if (event.isCancelled()) {
@@ -396,7 +399,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return;
}
+ org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot
- //this.minecraftServer.getCommandHandler().a(this.player, s);
+ // this.minecraftServer.getCommandHandler().a(this.player, s);
// CraftBukkit end
}
diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java
@@ -410,12 +413,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.spigotmc.CustomTimingsHandler; // Spigot
import org.bukkit.inventory.InventoryHolder; // CraftBukkit
- public class TileEntity {
+ public abstract class TileEntity {
+ public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getTileEntityTimings(this); // Spigot
private static final Logger a = LogManager.getLogger();
- private static Map i = new HashMap();
- private static Map j = new HashMap();
+ private static Map f = Maps.newHashMap();
+ private static Map g = Maps.newHashMap();
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/World.java
@@ -429,7 +432,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.CraftWorld;
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
- public ChunkGenerator generator;
+
public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot
+ public final SpigotTimings.WorldTimingsHandler timings; // Spigot
@@ -438,15 +441,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return this.world;
}
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
+ this.M = worldprovider.getWorldBorder();
- this.worldProvider.a(this);
- this.chunkProvider = this.j();
+ this.getServer().addWorld(this.world); // CraftBukkit
+ timings = new SpigotTimings.WorldTimingsHandler(this); // Spigot - code below can generate new world and access timings
- if (!this.worldData.isInitialized()) {
- try {
- this.a(worldsettings);
+ }
+
+ public World b() {
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
- this.f.clear();
+ this.g.clear();
this.methodProfiler.c("regular");
+ timings.entityTick.startTiming(); // Spigot
@@ -458,7 +461,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (!entity.dead) {
try {
+ SpigotTimings.tickEntityTimer.startTiming(); // Spigot
- this.playerJoinedWorld(entity);
+ this.g(entity);
+ SpigotTimings.tickEntityTimer.stopTiming(); // Spigot
} catch (Throwable throwable1) {
crashreport = CrashReport.a(throwable1, "Ticking entity");
@@ -470,28 +473,36 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ timings.entityTick.stopTiming(); // Spigot
this.methodProfiler.c("blockEntities");
+ timings.tileEntityTick.startTiming(); // Spigot
- this.M = true;
+ this.L = true;
// CraftBukkit start - From below, clean up tile entities before ticking them
if (!this.b.isEmpty()) {
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
- if (!tileentity.r() && tileentity.o() && this.isLoaded(tileentity.x, tileentity.y, tileentity.z)) {
- try {
-+ tileentity.tickTimer.startTiming(); // Spigot
- tileentity.h();
-+ tileentity.tickTimer.stopTiming(); // Spigot
- } catch (Throwable throwable2) {
-+ tileentity.tickTimer.stopTiming(); // Spigot
- crashreport = CrashReport.a(throwable2, "Ticking block entity");
- crashreportsystemdetails = crashreport.a("Block entity being ticked");
- tileentity.a(crashreportsystemdetails);
+ if (this.isLoaded(blockposition) && this.M.a(blockposition)) {
+ try {
++ tileentity.tickTimer.startTiming(); // Spigot
+ ((IUpdatePlayerListBox) tileentity).c();
+ } catch (Throwable throwable2) {
+ CrashReport crashreport1 = CrashReport.a(throwable2, "Ticking block entity");
+@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
+ tileentity.a(crashreportsystemdetails1);
+ throw new ReportedException(crashreport1);
+ }
++ // Spigot start
++ finally {
++ tileentity.tickTimer.stopTiming();
++ }
++ // Spigot end
+ }
+ }
+
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
}
}
+ timings.tileEntityTick.stopTiming(); // Spigot
+ timings.tileEntityPending.startTiming(); // Spigot
- this.M = false;
+ this.L = false;
/* CraftBukkit start - Moved up
if (!this.b.isEmpty()) {
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
@@ -505,15 +516,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
// CraftBukkit start - Use neighbor cache instead of looking up
Chunk startingChunk = this.getChunkIfLoaded(i >> 4, j >> 4);
- if (!flag || (startingChunk != null && startingChunk.areNeighborsLoaded(2)) /* this.b(i - b0, 0, j - b0, i + b0, 0, j + b0) */) {
+ if (!flag || (startingChunk != null && startingChunk.areNeighborsLoaded(2)) /* this.isAreaLoaded(i - b0, 0, j - b0, i + b0, 0, j + b0) */) {
+ entity.tickTimer.startTiming(); // Spigot
// CraftBukkit end
- entity.S = entity.locX;
- entity.T = entity.locY;
+ entity.P = entity.locX;
+ entity.Q = entity.locY;
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
- entity.passenger = null;
}
}
+
+ entity.tickTimer.stopTiming(); // Spigot
}
}
@@ -522,12 +533,12 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -0,0 +0,0 @@ public class WorldServer extends World {
+@@ -0,0 +0,0 @@ public class WorldServer extends World implements IAsyncTaskHandler {
// 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)) {
+ if (this.getGameRules().getBoolean("doMobSpawning") && this.worldData.getType() != WorldType.DEBUG_ALL_BLOCK_STATES && (this.allowMonsters || this.allowAnimals) && (this instanceof WorldServer && this.players.size() > 0)) {
+ timings.mobSpawn.startTiming(); // Spigot
- this.R.spawnEntities(this, this.allowMonsters && (this.ticksPerMonsterSpawns != 0 && time % this.ticksPerMonsterSpawns == 0L), this.allowAnimals && (this.ticksPerAnimalSpawns != 0 && time % this.ticksPerAnimalSpawns == 0L), this.worldData.getTime() % 400L == 0L);
+ this.R.a(this, this.allowMonsters && (this.ticksPerMonsterSpawns != 0 && time % this.ticksPerMonsterSpawns == 0L), this.allowAnimals && (this.ticksPerAnimalSpawns != 0 && time % this.ticksPerAnimalSpawns == 0L), this.worldData.getTime() % 400L == 0L);
+ timings.mobSpawn.stopTiming(); // Spigot
// CraftBukkit end
}
@@ -537,7 +548,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.methodProfiler.c("chunkSource");
this.chunkProvider.unloadChunks();
int j = this.a(1.0F);
-@@ -0,0 +0,0 @@ public class WorldServer extends World {
+@@ -0,0 +0,0 @@ public class WorldServer extends World implements IAsyncTaskHandler {
this.worldData.setDayTime(this.worldData.getDayTime() + 1L);
}
@@ -548,7 +559,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ timings.doTickPending.stopTiming(); // Spigot
this.methodProfiler.c("tickBlocks");
+ timings.doTickTiles.startTiming(); // Spigot
- this.g();
+ this.h();
+ timings.doTickTiles.stopTiming(); // Spigot
this.methodProfiler.c("chunkMap");
+ timings.doChunkMap.startTiming(); // Spigot
@@ -565,15 +576,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ timings.doPortalForcer.stopTiming(); // Spigot
this.methodProfiler.b();
+ timings.doSounds.startTiming(); // Spigot
- this.Z();
-+ timings.doSounds.stopTiming(); // Spigot
-
-+ timings.doChunkGC.startTiming(); // Spigot
+ this.ak();
+
this.getWorld().processChunkGC(); // CraftBukkit
+ timings.doChunkGC.stopTiming(); // Spigot
}
- public BiomeMeta a(EnumCreatureType enumcreaturetype, int i, int j, int k) {
+ public BiomeMeta a(EnumCreatureType enumcreaturetype, BlockPosition blockposition) {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -791,7 +800,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (queuedChunk.provider.chunkProvider != null) {
+ queuedChunk.provider.world.timings.syncChunkLoadStructuresTimer.startTiming(); // Spigot
- queuedChunk.provider.chunkProvider.recreateStructures(queuedChunk.x, queuedChunk.z);
+ queuedChunk.provider.chunkProvider.recreateStructures(chunk, queuedChunk.x, queuedChunk.z);
+ queuedChunk.provider.world.timings.syncChunkLoadStructuresTimer.stopTiming(); // Spigot
}
diff --git a/CraftBukkit-Patches/0014-Fix-Mob-Spawning-Relative-to-View-Distance.patch b/CraftBukkit-Patches/0013-Fix-Mob-Spawning-Relative-to-View-Distance.patch
similarity index 60%
rename from CraftBukkit-Patches/0014-Fix-Mob-Spawning-Relative-to-View-Distance.patch
rename to CraftBukkit-Patches/0013-Fix-Mob-Spawning-Relative-to-View-Distance.patch
index 49d6c3be6c..7fe8b2be81 100644
--- a/CraftBukkit-Patches/0014-Fix-Mob-Spawning-Relative-to-View-Distance.patch
+++ b/CraftBukkit-Patches/0013-Fix-Mob-Spawning-Relative-to-View-Distance.patch
@@ -12,16 +12,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ public class Chunk {
- public int r;
- public long s;
- private int x;
-+ protected net.minecraft.util.gnu.trove.map.hash.TObjectIntHashMap entityCount = new net.minecraft.util.gnu.trove.map.hash.TObjectIntHashMap(); // Spigot
+ private long u;
+ private int v;
+ private ConcurrentLinkedQueue w;
++ protected gnu.trove.map.hash.TObjectIntHashMap entityCount = new gnu.trove.map.hash.TObjectIntHashMap(); // Spigot
// CraftBukkit start - Neighbor loaded cache for chunk lighting and entity ticking
private int neighbors = 0x1 << 12;
@@ -0,0 +0,0 @@ public class Chunk {
- entity.ai = k;
- entity.aj = this.locZ;
+ entity.af = k;
+ entity.ag = this.locZ;
this.entitySlices[k].add(entity);
+ // Spigot start - increment creature type count
+ // Keep this synced up with World.a(Class)
@@ -64,24 +64,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Spigot end
}
- public boolean d(int i, int j, int k) {
+ public boolean d(BlockPosition blockposition) {
diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
@@ -0,0 +0,0 @@ public final class SpawnerCreature {
- return new ChunkPosition(k, i1, l);
- }
+
+ public SpawnerCreature() {}
+ // Spigot start - get entity count only from chunks being processed in b
+ private int getEntityCount(WorldServer server, Class oClass)
+ {
+ int i = 0;
-+ for ( Long coord : this.a.keySet() )
++ Iterator it = this.b.iterator();
++ while ( it.hasNext() )
+ {
++ Long coord = it.next();
+ int x = LongHash.msw( coord );
+ int z = LongHash.lsw( coord );
-+ if ( !server.chunkProviderServer.unloadQueue.contains( coord ) && server.isChunkLoaded( x, z ) )
++ if ( !server.chunkProviderServer.unloadQueue.contains( coord ) && server.isChunkLoaded( x, z, true ) )
+ {
+ i += server.getChunkAt( x, z ).entityCount.get( oClass );
+ }
@@ -90,53 +92,57 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ // Spigot end
+
- public int spawnEntities(WorldServer worldserver, boolean flag, boolean flag1, boolean flag2) {
+ public int a(WorldServer worldserver, boolean flag, boolean flag1, boolean flag2) {
if (!flag && !flag1) {
return 0;
@@ -0,0 +0,0 @@ public final class SpawnerCreature {
- j = MathHelper.floor(entityhuman.locZ / 16.0D);
- byte b0 = 8;
-+ // Spigot Start
-+ b0 = worldserver.spigotConfig.mobSpawnRange;
-+ b0 = ( b0 > worldserver.spigotConfig.viewDistance ) ? (byte) worldserver.spigotConfig.viewDistance : b0;
-+ b0 = ( b0 > 8 ) ? 8 : b0;
-+ // Spigot End
+ j = MathHelper.floor(entityhuman.locZ / 16.0D);
+ byte b0 = 8;
++ // Spigot Start
++ b0 = worldserver.spigotConfig.mobSpawnRange;
++ b0 = ( b0 > worldserver.spigotConfig.viewDistance ) ? (byte) worldserver.spigotConfig.viewDistance : b0;
++ b0 = ( b0 > 8 ) ? 8 : b0;
++ // Spigot End
- for (int l = -b0; l <= b0; ++l) {
for (int i1 = -b0; i1 <= b0; ++i1) {
+ for (k = -b0; k <= b0; ++k) {
@@ -0,0 +0,0 @@ public final class SpawnerCreature {
if (limit == 0) {
continue;
}
-+ int mobcnt = 0;
++ int mobcnt = 0; // Spigot
// CraftBukkit end
-- if ((!enumcreaturetype.d() || flag1) && (enumcreaturetype.d() || flag) && (!enumcreaturetype.e() || flag2) && worldserver.a(enumcreaturetype.a()) <= limit * this.a.size() / 256) { // CraftBukkit - use per-world limits
-+ if ((!enumcreaturetype.d() || flag1) && (enumcreaturetype.d() || flag) && (!enumcreaturetype.e() || flag2) && (mobcnt = getEntityCount(worldserver, enumcreaturetype.a())) <= limit * this.a.size() / 256) { // Spigot - use per-world limits and use all loaded chunks
- Iterator iterator = this.a.keySet().iterator();
+ if ((!enumcreaturetype.d() || flag1) && (enumcreaturetype.d() || flag) && (!enumcreaturetype.e() || flag2)) {
+ k = worldserver.a(enumcreaturetype.a());
+ int l1 = limit * i / a; // CraftBukkit - use per-world limits
-+ int moblimit = (limit * this.a.size() / 256) - mobcnt + 1; // Spigot - up to 1 more than limit
- label110:
-- while (iterator.hasNext()) {
-+ while (iterator.hasNext() && (moblimit > 0)) { // Spigot - while more allowed
- // CraftBukkit start = use LongHash and LongObjectHashMap
- long key = ((Long) iterator.next()).longValue();
+- if (k <= l1) {
++ if ((mobcnt = getEntityCount(worldserver, enumcreaturetype.a())) <= limit * i / 256) {
+ Iterator iterator1 = this.b.iterator();
++ int moblimit = (limit * i / 256) - mobcnt + 1; // Spigot - up to 1 more than limit
+ label115:
+- while (iterator1.hasNext()) {
++ while (iterator1.hasNext() && (moblimit > 0)) { // Spigot - while more allowed
+ // CraftBukkit start = use LongHash and LongObjectHashMap
+ long key = ((Long) iterator1.next()).longValue();
+ BlockPosition blockposition1 = getRandomPosition(worldserver, LongHash.msw(key), LongHash.lsw(key));
@@ -0,0 +0,0 @@ public final class SpawnerCreature {
- groupdataentity = entityinsentient.prepare(groupdataentity);
- worldserver.addEntity(entityinsentient, SpawnReason.NATURAL);
- // CraftBukkit end
-+ // Spigot start
-+ if ( --moblimit <= 0 )
-+ {
-+ // If we're past limit, stop spawn
-+ continue label110;
-+ }
-+ // Spigot end
- if (j2 >= entityinsentient.bB()) {
- continue label110;
- }
+ worldserver.addEntity(entityinsentient, SpawnReason.NATURAL); // CraftBukkit - Added a reason for spawning this creature
+ }
+
++ // Spigot start
++ if ( --moblimit <= 0 )
++ {
++ // If we're past limit, stop spawn
++ continue label115;
++ }
++ // Spigot end
+ if (l2 >= entityinsentient.bU()) {
+ continue label115;
+ }
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
diff --git a/CraftBukkit-Patches/0015-Handle-Null-Tile-Entities.patch b/CraftBukkit-Patches/0014-Handle-Null-Tile-Entities.patch
similarity index 87%
rename from CraftBukkit-Patches/0015-Handle-Null-Tile-Entities.patch
rename to CraftBukkit-Patches/0014-Handle-Null-Tile-Entities.patch
index 037cd11b0d..d29a7caba2 100644
--- a/CraftBukkit-Patches/0015-Handle-Null-Tile-Entities.patch
+++ b/CraftBukkit-Patches/0014-Handle-Null-Tile-Entities.patch
@@ -20,6 +20,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ // Spigot end
- if (!tileentity.r() && tileentity.o() && this.isLoaded(tileentity.x, tileentity.y, tileentity.z)) {
- try {
+ if (!tileentity.x() && tileentity.t()) {
+ BlockPosition blockposition = tileentity.getPosition();
--
\ No newline at end of file
diff --git a/CraftBukkit-Patches/0016-Entity-Activation-Range.patch b/CraftBukkit-Patches/0015-Entity-Activation-Range.patch
similarity index 89%
rename from CraftBukkit-Patches/0016-Entity-Activation-Range.patch
rename to CraftBukkit-Patches/0015-Entity-Activation-Range.patch
index 0797e06913..5b13c2d744 100644
--- a/CraftBukkit-Patches/0016-Entity-Activation-Range.patch
+++ b/CraftBukkit-Patches/0015-Entity-Activation-Range.patch
@@ -12,16 +12,16 @@ diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
-@@ -0,0 +0,0 @@ public abstract class Entity {
+@@ -0,0 +0,0 @@ public abstract class Entity implements ICommandListener {
public int ticksLived;
public int maxFireTicks;
- public int fireTicks; // CraftBukkit - private -> public
+ public int fireTicks;
- protected boolean inWater;
+ public boolean inWater; // Spigot - protected -> public
public int noDamageTicks;
- private boolean justCreated;
+ protected boolean justCreated;
protected boolean fireProof;
-@@ -0,0 +0,0 @@ public abstract class Entity {
+@@ -0,0 +0,0 @@ public abstract class Entity implements ICommandListener {
public boolean valid; // CraftBukkit
public org.bukkit.projectiles.ProjectileSource projectileSource; // CraftBukkit - For projectiles only
@@ -35,10 +35,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public int getId() {
return this.id;
-@@ -0,0 +0,0 @@ public abstract class Entity {
+@@ -0,0 +0,0 @@ public abstract class Entity implements ICommandListener {
this.setPosition(0.0D, 0.0D, 0.0D);
if (world != null) {
- this.dimension = world.worldProvider.dimension;
+ this.dimension = world.worldProvider.getDimension();
+ // Spigot start
+ this.defaultActivationState = org.spigotmc.ActivationRange.initializeEntityActivationState(this, world.spigotConfig);
+ } else {
@@ -53,7 +53,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/EntityAgeable.java
+++ b/src/main/java/net/minecraft/server/EntityAgeable.java
@@ -0,0 +0,0 @@ public abstract class EntityAgeable extends EntityCreature {
- private float bq;
+ private float bl;
public boolean ageLocked = false; // CraftBukkit
+ // Spigot start
@@ -99,7 +99,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public Entity shooter;
@@ -0,0 +0,0 @@ public class EntityArrow extends Entity implements IProjectile {
private double damage = 2.0D;
- public int knockbackStrength; // CraftBukkit - private -> public
+ public int knockbackStrength;
+ // Spigot Start
+ @Override
@@ -107,7 +107,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ {
+ if ( this.inGround )
+ {
-+ this.at += 19; // Despawn counter. First int after shooter
++ this.ap += 19; // Despawn counter. First int after shooter
+ }
+ super.inactiveTick();
+ }
@@ -122,7 +122,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+++ b/src/main/java/net/minecraft/server/EntityFireworks.java
@@ -0,0 +0,0 @@ public class EntityFireworks extends Entity {
private int ticksFlown;
- public int expectedLifespan; // CraftBukkit - private -> public
+ public int expectedLifespan;
+ // Spigot Start
+ @Override
@@ -148,18 +148,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public void inactiveTick()
+ {
+ super.inactiveTick();
-+ ++this.aU; // Above all the floats
++ ++this.aT; // Above all the floats
+ }
+ // Spigot end
- public EntityLiving(World world) {
- super(world);
+ public void G() {
+ this.damageEntity(DamageSource.OUT_OF_WORLD, Float.MAX_VALUE);
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
- this.f.clear();
+ this.g.clear();
this.methodProfiler.c("regular");
+ org.spigotmc.ActivationRange.activateEntities(this); // Spigot
@@ -172,7 +172,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- // CraftBukkit start - Use neighbor cache instead of looking up
- Chunk startingChunk = this.getChunkIfLoaded(i >> 4, j >> 4);
-- if (!flag || (startingChunk != null && startingChunk.areNeighborsLoaded(2)) /* this.b(i - b0, 0, j - b0, i + b0, 0, j + b0) */) {
+- if (!flag || (startingChunk != null && startingChunk.areNeighborsLoaded(2)) /* this.isAreaLoaded(i - b0, 0, j - b0, i + b0, 0, j + b0) */) {
+ // Spigot start
+ if (!org.spigotmc.ActivationRange.checkIfActive(entity)) {
+ entity.ticksLived++;
@@ -180,7 +180,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } else {
entity.tickTimer.startTiming(); // Spigot
// CraftBukkit end
- entity.S = entity.locX;
+ entity.P = entity.locX;
diff --git a/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java b/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java
@@ -205,6 +205,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+import java.util.ArrayList;
+import java.util.List;
++import java.util.Set;
+import net.minecraft.server.AxisAlignedBB;
+import net.minecraft.server.Chunk;
+import net.minecraft.server.Entity;
@@ -222,6 +223,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import net.minecraft.server.EntityMonster;
+import net.minecraft.server.EntityProjectile;
+import net.minecraft.server.EntitySheep;
++import net.minecraft.server.EntitySlice;
+import net.minecraft.server.EntitySlime;
+import net.minecraft.server.EntityTNTPrimed;
+import net.minecraft.server.EntityVillager;
@@ -291,26 +293,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ /**
-+ * Utility method to grow an AABB without creating a new AABB or touching
-+ * the pool, so we can re-use ones we have.
-+ *
-+ * @param target
-+ * @param source
-+ * @param x
-+ * @param y
-+ * @param z
-+ */
-+ public static void growBB(AxisAlignedBB target, AxisAlignedBB source, int x, int y, int z)
-+ {
-+ target.a = source.a - x;
-+ target.b = source.b - y;
-+ target.c = source.c - z;
-+ target.d = source.d + x;
-+ target.e = source.e + y;
-+ target.f = source.f + z;
-+ }
-+
-+ /**
+ * Find what entities are in range of the players in the world and set
+ * active if in range.
+ *
@@ -331,10 +313,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ {
+
+ player.activatedTick = MinecraftServer.currentTick;
-+ growBB( maxBB, player.boundingBox, maxRange, 256, maxRange );
-+ growBB( miscBB, player.boundingBox, miscActivationRange, 256, miscActivationRange );
-+ growBB( animalBB, player.boundingBox, animalActivationRange, 256, animalActivationRange );
-+ growBB( monsterBB, player.boundingBox, monsterActivationRange, 256, monsterActivationRange );
++ maxBB = player.getBoundingBox().grow( maxRange, 256, maxRange );
++ miscBB = player.getBoundingBox().grow( miscActivationRange, 256, miscActivationRange );
++ animalBB = player.getBoundingBox().grow( animalActivationRange, 256, animalActivationRange );
++ monsterBB = player.getBoundingBox().grow( monsterActivationRange, 256, monsterActivationRange );
+
+ int i = MathHelper.floor( maxBB.a / 16.0D );
+ int j = MathHelper.floor( maxBB.d / 16.0D );
@@ -362,9 +344,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ */
+ private static void activateChunkEntities(Chunk chunk)
+ {
-+ for ( List slice : chunk.entitySlices )
++ for ( EntitySlice slice : chunk.entitySlices )
+ {
-+ for ( Entity entity : slice )
++ for ( Entity entity : (Set) slice )
+ {
+ if ( MinecraftServer.currentTick > entity.activatedTick )
+ {
@@ -376,20 +358,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ switch ( entity.activationType )
+ {
+ case 1:
-+ if ( monsterBB.b( entity.boundingBox ) )
++ if ( monsterBB.b( entity.getBoundingBox() ) )
+ {
+ entity.activatedTick = MinecraftServer.currentTick;
+ }
+ break;
+ case 2:
-+ if ( animalBB.b( entity.boundingBox ) )
++ if ( animalBB.b( entity.getBoundingBox() ) )
+ {
+ entity.activatedTick = MinecraftServer.currentTick;
+ }
+ break;
+ case 3:
+ default:
-+ if ( miscBB.b( entity.boundingBox ) )
++ if ( miscBB.b( entity.getBoundingBox() ) )
+ {
+ entity.activatedTick = MinecraftServer.currentTick;
+ }
@@ -428,15 +410,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if ( entity instanceof EntityLiving )
+ {
+ EntityLiving living = (EntityLiving) entity;
-+ if ( living.attackTicks > 0 || living.hurtTicks > 0 || living.effects.size() > 0 )
++ if ( /*TODO: Missed mapping? living.attackTicks > 0 || */ living.hurtTicks > 0 || living.effects.size() > 0 )
+ {
+ return true;
+ }
-+ if ( entity instanceof EntityCreature && ( (EntityCreature) entity ).target != null )
++ if ( entity instanceof EntityCreature && ( (EntityCreature) entity ).getGoalTarget() != null )
+ {
+ return true;
+ }
-+ if ( entity instanceof EntityVillager && ( (EntityVillager) entity ).bY() /* Getter for first boolean */ )
++ if ( entity instanceof EntityVillager && ( (EntityVillager) entity ).ck() /* Getter for first boolean */ )
+ {
+ return true;
+ }
diff --git a/CraftBukkit-Patches/0017-Metrics.patch b/CraftBukkit-Patches/0016-Metrics.patch
similarity index 100%
rename from CraftBukkit-Patches/0017-Metrics.patch
rename to CraftBukkit-Patches/0016-Metrics.patch
diff --git a/CraftBukkit-Patches/0018-PlayerItemDamageEvent.patch b/CraftBukkit-Patches/0017-PlayerItemDamageEvent.patch
similarity index 87%
rename from CraftBukkit-Patches/0018-PlayerItemDamageEvent.patch
rename to CraftBukkit-Patches/0017-PlayerItemDamageEvent.patch
index 553a2b7ffa..150cd640d7 100644
--- a/CraftBukkit-Patches/0018-PlayerItemDamageEvent.patch
+++ b/CraftBukkit-Patches/0017-PlayerItemDamageEvent.patch
@@ -9,17 +9,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/ItemStack.java
+++ b/src/main/java/net/minecraft/server/ItemStack.java
@@ -0,0 +0,0 @@ public final class ItemStack {
- return this.item.getMaxDurability();
}
-+ // Spigot start
public boolean isDamaged(int i, Random random) {
+ return isDamaged(i, random, null);
+ }
+
+ public boolean isDamaged(int i, Random random, EntityLiving entityliving) {
+ // Spigot end
- if (!this.g()) {
+ if (!this.e()) {
return false;
} else {
@@ -0,0 +0,0 @@ public final class ItemStack {
@@ -43,10 +41,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public final class ItemStack {
public void damage(int i, EntityLiving entityliving) {
if (!(entityliving instanceof EntityHuman) || !((EntityHuman) entityliving).abilities.canInstantlyBuild) {
- if (this.g()) {
-- if (this.isDamaged(i, entityliving.aI())) {
-+ if (this.isDamaged(i, entityliving.aI(), entityliving)) { // Spigot
- entityliving.a(this);
+ if (this.e()) {
+- if (this.isDamaged(i, entityliving.bb())) {
++ if (this.isDamaged(i, entityliving.bb(), entityliving)) { // Spigot
+ entityliving.b(this);
--this.count;
if (entityliving instanceof EntityHuman) {
--
\ No newline at end of file
diff --git a/CraftBukkit-Patches/0020-Prevent-NPE-in-CraftSign.patch b/CraftBukkit-Patches/0018-Prevent-NPE-in-CraftSign.patch
similarity index 72%
rename from CraftBukkit-Patches/0020-Prevent-NPE-in-CraftSign.patch
rename to CraftBukkit-Patches/0018-Prevent-NPE-in-CraftSign.patch
index 2224c7b054..4cab28f535 100644
--- a/CraftBukkit-Patches/0020-Prevent-NPE-in-CraftSign.patch
+++ b/CraftBukkit-Patches/0018-Prevent-NPE-in-CraftSign.patch
@@ -20,15 +20,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ // Spigot end
lines = new String[sign.lines.length];
- System.arraycopy(sign.lines, 0, lines, 0, lines.length);
+ System.arraycopy(revertComponents(sign.lines), 0, lines, 0, lines.length);
}
-@@ -0,0 +0,0 @@ public class CraftSign extends CraftBlockState implements Sign {
- public boolean update(boolean force, boolean applyPhysics) {
- boolean result = super.update(force, applyPhysics);
-
-- if (result) {
-+ if (result && sign != null) { // Spigot, add null check
- sign.lines = sanitizeLines(lines);
- sign.update();
- }
--
\ No newline at end of file
diff --git a/CraftBukkit-Patches/0021-Entity-Tracking-Ranges.patch b/CraftBukkit-Patches/0019-Entity-Tracking-Ranges.patch
similarity index 100%
rename from CraftBukkit-Patches/0021-Entity-Tracking-Ranges.patch
rename to CraftBukkit-Patches/0019-Entity-Tracking-Ranges.patch
diff --git a/CraftBukkit-Patches/0019-Faster-UUID-for-entities.patch b/CraftBukkit-Patches/0019-Faster-UUID-for-entities.patch
deleted file mode 100644
index dd5fbdb643..0000000000
--- a/CraftBukkit-Patches/0019-Faster-UUID-for-entities.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: md_5
-Date: Sun, 17 Mar 2013 19:02:50 +1100
-Subject: [PATCH] Faster UUID for entities
-
-It is overkill to create a new SecureRandom on each entity create and then use it to make a new Entity ID for every entity instance created. Instead we will just use a pseudo random UUID based off the random instance we already have.
-
-diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/Entity.java
-+++ b/src/main/java/net/minecraft/server/Entity.java
-@@ -0,0 +0,0 @@ public abstract class Entity {
- this.random = new Random();
- this.maxFireTicks = 1;
- this.justCreated = true;
-- this.uniqueID = UUID.randomUUID();
-+ this.uniqueID = new UUID(random.nextLong(), random.nextLong()); // Spigot
- this.as = EnumEntitySize.SIZE_2;
- this.world = world;
- this.setPosition(0.0D, 0.0D, 0.0D);
---
\ No newline at end of file
diff --git a/CraftBukkit-Patches/0023-Thread-Naming-and-Tweaks.patch b/CraftBukkit-Patches/0020-Thread-Naming-and-Tweaks.patch
similarity index 100%
rename from CraftBukkit-Patches/0023-Thread-Naming-and-Tweaks.patch
rename to CraftBukkit-Patches/0020-Thread-Naming-and-Tweaks.patch
diff --git a/CraftBukkit-Patches/0024-Close-Unloaded-Save-Files.patch b/CraftBukkit-Patches/0021-Close-Unloaded-Save-Files.patch
similarity index 77%
rename from CraftBukkit-Patches/0024-Close-Unloaded-Save-Files.patch
rename to CraftBukkit-Patches/0021-Close-Unloaded-Save-Files.patch
index 72f5fcff5b..1b1fe4e60e 100644
--- a/CraftBukkit-Patches/0024-Close-Unloaded-Save-Files.patch
+++ b/CraftBukkit-Patches/0021-Close-Unloaded-Save-Files.patch
@@ -12,28 +12,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public class RegionFileCache {
-- private static final Map a = new HashMap();
-+ public static final Map a = new HashMap(); // CraftBukkit - private -> public
+- private static final Map a = Maps.newHashMap();
++ public static final Map a = Maps.newHashMap(); // Spigot - private -> public
- public static synchronized RegionFile a(File file1, int i, int j) {
- File file2 = new File(file1, "region");
+ public static synchronized RegionFile a(File file, int i, int j) {
+ File file1 = new File(file, "region");
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-@@ -0,0 +0,0 @@ import net.minecraft.server.MinecraftServer;
- import net.minecraft.server.MobEffectList;
- import net.minecraft.server.PropertyManager;
- import net.minecraft.server.ServerCommand;
-+import net.minecraft.server.RegionFile;
-+import net.minecraft.server.RegionFileCache;
- import net.minecraft.server.ServerNBTManager;
- import net.minecraft.server.WorldLoaderServer;
- import net.minecraft.server.WorldManager;
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
+
worlds.remove(world.getName().toLowerCase());
console.worlds.remove(console.worlds.indexOf(handle));
-
++
+ File parentFolder = world.getWorldFolder().getAbsoluteFile();
+
+ // Synchronized because access to RegionFileCache.a is guarded by this lock.
diff --git a/CraftBukkit-Patches/0022-Limit-Custom-Map-Rendering.patch b/CraftBukkit-Patches/0022-Limit-Custom-Map-Rendering.patch
deleted file mode 100644
index e3e034aeee..0000000000
--- a/CraftBukkit-Patches/0022-Limit-Custom-Map-Rendering.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: md_5
-Date: Sat, 23 Mar 2013 19:08:41 +1100
-Subject: [PATCH] Limit Custom Map Rendering
-
-The default CraftBukkit render sequence for maps is ridiculously slow. By only using it when a custom renderer has been added (rarely in most cases), we can fallback to the Vanilla renderer for general usage. This leads to a much higher effiency overall, especially if no plugins are rendering such maps.
-
-diff --git a/src/main/java/net/minecraft/server/WorldMapHumanTracker.java b/src/main/java/net/minecraft/server/WorldMapHumanTracker.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/WorldMapHumanTracker.java
-+++ b/src/main/java/net/minecraft/server/WorldMapHumanTracker.java
-@@ -0,0 +0,0 @@ public class WorldMapHumanTracker {
- int i;
- int j;
-
-- org.bukkit.craftbukkit.map.RenderData render = this.worldMap.mapView.render((org.bukkit.craftbukkit.entity.CraftPlayer) trackee.getBukkitEntity()); // CraftBukkit
-+ // Spigot start
-+ boolean custom = this.worldMap.mapView.renderers.size() > 1 || !(this.worldMap.mapView.renderers.get(0) instanceof org.bukkit.craftbukkit.map.CraftMapRenderer);
-+ org.bukkit.craftbukkit.map.RenderData render = (custom) ? this.worldMap.mapView.render((org.bukkit.craftbukkit.entity.CraftPlayer) trackee.getBukkitEntity()) : null; // CraftBukkit
-
- if (--this.g < 0) {
- this.g = 4;
-- abyte = new byte[render.cursors.size() * 3 + 1]; // CraftBukkit
-+ abyte = new byte[((custom) ? render.cursors.size() : this.worldMap.decorations.size()) * 3 + 1]; // CraftBukkit
- abyte[0] = 1;
- i = 0;
-
- // CraftBukkit start
-- for (i = 0; i < render.cursors.size(); ++i) {
-- org.bukkit.map.MapCursor cursor = render.cursors.get(i);
-- if (!cursor.isVisible()) continue;
-
-- abyte[i * 3 + 1] = (byte) (cursor.getRawType() << 4 | cursor.getDirection() & 15);
-- abyte[i * 3 + 2] = (byte) cursor.getX();
-- abyte[i * 3 + 3] = (byte) cursor.getY();
-+ // Spigot start
-+ for (Iterator iterator = ((custom) ? render.cursors.iterator() : this.worldMap.decorations.values().iterator()); iterator.hasNext(); ++i) {
-+ org.bukkit.map.MapCursor cursor = (custom) ? (org.bukkit.map.MapCursor) iterator.next() : null;
-+ if (cursor != null && !cursor.isVisible()) continue;
-+ WorldMapDecoration deco = (custom) ? null : (WorldMapDecoration) iterator.next();
-+
-+ abyte[i * 3 + 1] = (byte) (((custom) ? cursor.getRawType() : deco.type) << 4 | ((custom) ? cursor.getDirection() : deco.rotation) & 15);
-+ abyte[i * 3 + 2] = (byte) ((custom) ? cursor.getX() : deco.locX);
-+ abyte[i * 3 + 3] = (byte) ((custom) ? cursor.getY() : deco.locY);
- }
-+ // Spigot end
- // CraftBukkit end
-
- boolean flag = !itemstack.A();
-@@ -0,0 +0,0 @@ public class WorldMapHumanTracker {
- abyte1[2] = (byte) j;
-
- for (int i1 = 0; i1 < abyte1.length - 3; ++i1) {
-- abyte1[i1 + 3] = render.buffer[(i1 + j) * 128 + i]; // CraftBukkit
-+ abyte1[i1 + 3] = ((custom) ? render.buffer : this.worldMap.colors)[(i1 + j) * 128 + i];
- }
-
- this.c[i] = -1;
-diff --git a/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java b/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java
-+++ b/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java
-@@ -0,0 +0,0 @@ import org.bukkit.map.MapView;
- public final class CraftMapView implements MapView {
-
- private final Map renderCache = new HashMap();
-- private final List renderers = new ArrayList();
-+ public final List renderers = new ArrayList(); // Spigot
- private final Map> canvases = new HashMap>();
- protected final WorldMap worldMap;
-
---
\ No newline at end of file
diff --git a/CraftBukkit-Patches/0025-Remove-o-Option.patch b/CraftBukkit-Patches/0022-Remove-o-Option.patch
similarity index 100%
rename from CraftBukkit-Patches/0025-Remove-o-Option.patch
rename to CraftBukkit-Patches/0022-Remove-o-Option.patch
diff --git a/CraftBukkit-Patches/0026-Recipe-Deconstruction.patch b/CraftBukkit-Patches/0023-Recipe-Deconstruction.patch
similarity index 92%
rename from CraftBukkit-Patches/0026-Recipe-Deconstruction.patch
rename to CraftBukkit-Patches/0023-Recipe-Deconstruction.patch
index 27f11d4517..992d650dce 100644
--- a/CraftBukkit-Patches/0026-Recipe-Deconstruction.patch
+++ b/CraftBukkit-Patches/0023-Recipe-Deconstruction.patch
@@ -10,8 +10,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/IRecipe.java
+++ b/src/main/java/net/minecraft/server/IRecipe.java
@@ -0,0 +0,0 @@ public interface IRecipe {
- ItemStack b();
-
+ ItemStack[] b(InventoryCrafting inventorycrafting);
+
org.bukkit.inventory.Recipe toBukkitRecipe(); // CraftBukkit
+
+ java.util.List getIngredients(); // Spigot
@@ -21,10 +21,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/ShapedRecipes.java
+++ b/src/main/java/net/minecraft/server/ShapedRecipes.java
@@ -0,0 +0,0 @@ public class ShapedRecipes implements IRecipe {
- private int width;
- private int height;
- private ItemStack[] items;
-- private ItemStack result;
+ private final int width;
+ private final int height;
+ private final ItemStack[] items;
+- private final ItemStack result;
+ public ItemStack result; // Spigot
private boolean e;
diff --git a/CraftBukkit-Patches/0027-Implement-Arrow-API.patch b/CraftBukkit-Patches/0024-Implement-Arrow-API.patch
similarity index 96%
rename from CraftBukkit-Patches/0027-Implement-Arrow-API.patch
rename to CraftBukkit-Patches/0024-Implement-Arrow-API.patch
index 338f1c8484..1b1f9ce81f 100644
--- a/CraftBukkit-Patches/0027-Implement-Arrow-API.patch
+++ b/CraftBukkit-Patches/0024-Implement-Arrow-API.patch
@@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ @Override
+ public double getDamage()
+ {
-+ return getHandle().e();
++ return getHandle().j();
+ }
+
+ @Override
diff --git a/CraftBukkit-Patches/0028-Hopper-Customisations.patch b/CraftBukkit-Patches/0025-Hopper-Customisations.patch
similarity index 76%
rename from CraftBukkit-Patches/0028-Hopper-Customisations.patch
rename to CraftBukkit-Patches/0025-Hopper-Customisations.patch
index c77306d9e6..61c114b028 100644
--- a/CraftBukkit-Patches/0028-Hopper-Customisations.patch
+++ b/CraftBukkit-Patches/0025-Hopper-Customisations.patch
@@ -9,73 +9,71 @@ diff --git a/src/main/java/net/minecraft/server/TileEntityHopper.java b/src/main
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/TileEntityHopper.java
+++ b/src/main/java/net/minecraft/server/TileEntityHopper.java
-@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntity implements IHopper {
+@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityContainer implements IHopper, IU
}
if (flag) {
-- this.c(8);
-+ this.c(world.spigotConfig.hopperTransfer); // Spigot
+- this.d(8);
++ this.d(world.spigotConfig.hopperTransfer); // Spigot
this.update();
return true;
}
}
+ // Spigot start
-+ if ( !this.j() )
++ if ( !this.n() )
+ {
-+ this.c( world.spigotConfig.hopperCheck );
++ this.d( world.spigotConfig.hopperCheck );
+ }
+ // Spigot end
return false;
} else {
return false;
-@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntity implements IHopper {
- if (this.getItem(j) != null) {
- ItemStack itemstack = this.getItem(j).cloneItemStack();
+@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityContainer implements IHopper, IU
+ // ItemStack itemstack1 = addItem(iinventory, this.splitStack(i, 1), enumdirection);
+
// CraftBukkit start - Call event when pushing items into other inventories
-- CraftItemStack oitemstack = CraftItemStack.asCraftMirror(this.splitStack(j, 1));
-+ CraftItemStack oitemstack = CraftItemStack.asCraftMirror(this.splitStack(j, world.spigotConfig.hopperAmount)); // Spigot
+- CraftItemStack oitemstack = CraftItemStack.asCraftMirror(this.splitStack(i, 1));
++ CraftItemStack oitemstack = CraftItemStack.asCraftMirror(this.splitStack(i, world.spigotConfig.hopperAmount)); // Spigot
Inventory destinationInventory;
// Have to special case large chests as they work oddly
-@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntity implements IHopper {
+@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityContainer implements IHopper, IU
this.getWorld().getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
- this.setItem(j, itemstack);
-- this.c(8); // Delay hopper checks
-+ this.c(world.spigotConfig.hopperTransfer); // Spigot
+ this.setItem(i, itemstack);
+- this.d(8); // Delay hopper checks
++ this.d(world.spigotConfig.hopperTransfer); // Spigot
return false;
}
+ int origCount = event.getItem().getAmount(); // Spigot
- ItemStack itemstack1 = addItem(iinventory, CraftItemStack.asNMSCopy(event.getItem()), i);
--
+ ItemStack itemstack1 = addItem(iinventory, CraftItemStack.asNMSCopy(event.getItem()), enumdirection);
+
if (itemstack1 == null || itemstack1.count == 0) {
- if (event.getItem().equals(oitemstack)) {
- iinventory.update();
-@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntity implements IHopper {
+@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityContainer implements IHopper, IU
// CraftBukkit end
return true;
}
-
+ itemstack.count -= origCount - itemstack1.count; // Spigot
- this.setItem(j, itemstack);
+ this.setItem(i, itemstack);
}
}
-@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntity implements IHopper {
- if (itemstack != null && canTakeItemFromInventory(iinventory, itemstack, i, j)) {
+@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityContainer implements IHopper, IU
ItemStack itemstack1 = itemstack.cloneItemStack();
+ // ItemStack itemstack2 = addItem(ihopper, iinventory.splitStack(i, 1), (EnumDirection) null);
// CraftBukkit start - Call event on collection of items from inventories into the hopper
- CraftItemStack oitemstack = CraftItemStack.asCraftMirror(iinventory.splitStack(i, 1));
+ CraftItemStack oitemstack = CraftItemStack.asCraftMirror(iinventory.splitStack(i, ihopper.getWorld().spigotConfig.hopperAmount)); // Spigot
Inventory sourceInventory;
// Have to special case large chests as they work oddly
-@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntity implements IHopper {
+@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityContainer implements IHopper, IU
iinventory.setItem(i, itemstack1);
if (ihopper instanceof TileEntityHopper) {
-- ((TileEntityHopper) ihopper).c(8); // Delay hopper checks
-+ ((TileEntityHopper) ihopper).c(ihopper.getWorld().spigotConfig.hopperTransfer); // Spigot
+- ((TileEntityHopper) ihopper).d(8); // Delay hopper checks
++ ((TileEntityHopper) ihopper).d(ihopper.getWorld().spigotConfig.hopperTransfer); // Spigot
} else if (ihopper instanceof EntityMinecartHopper) {
- ((EntityMinecartHopper) ihopper).l(4); // Delay hopper minecart checks
+ ((EntityMinecartHopper) ihopper).l(ihopper.getWorld().spigotConfig.hopperTransfer / 2); // Spigot
@@ -84,26 +82,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return false;
}
+ int origCount = event.getItem().getAmount(); // Spigot
- ItemStack itemstack2 = addItem(ihopper, CraftItemStack.asNMSCopy(event.getItem()), -1);
+ ItemStack itemstack2 = addItem(ihopper, CraftItemStack.asNMSCopy(event.getItem()), null);
if (itemstack2 == null || itemstack2.count == 0) {
-@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntity implements IHopper {
-
+@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityContainer implements IHopper, IU
+ // CraftBukkit end
return true;
}
+ itemstack1.count -= origCount - itemstack2.count; // Spigot
iinventory.setItem(i, itemstack1);
}
-@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntity implements IHopper {
+@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityContainer implements IHopper, IU
+ TileEntityHopper tileentityhopper = (TileEntityHopper) iinventory;
+
+ if (tileentityhopper.o()) {
+- tileentityhopper.d(8);
++ tileentityhopper.d(tileentityhopper.world.spigotConfig.hopperTransfer); // Spigot
+ }
- if (flag) {
- if (iinventory instanceof TileEntityHopper) {
-- ((TileEntityHopper) iinventory).c(8);
-+ ((TileEntityHopper) iinventory).c(((TileEntityHopper) iinventory).world.spigotConfig.hopperTransfer); // Spigot
iinventory.update();
- }
-
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
diff --git a/CraftBukkit-Patches/0030-Implement-SpawnerSpawnEvent.patch b/CraftBukkit-Patches/0026-Implement-SpawnerSpawnEvent.patch
similarity index 84%
rename from CraftBukkit-Patches/0030-Implement-SpawnerSpawnEvent.patch
rename to CraftBukkit-Patches/0026-Implement-SpawnerSpawnEvent.patch
index fd345fbc5e..3d35a1212e 100644
--- a/CraftBukkit-Patches/0030-Implement-SpawnerSpawnEvent.patch
+++ b/CraftBukkit-Patches/0026-Implement-SpawnerSpawnEvent.patch
@@ -9,7 +9,7 @@ diff --git a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java b/src/ma
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
+++ b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
-@@ -0,0 +0,0 @@ import java.util.Collection;
+@@ -0,0 +0,0 @@ import com.google.common.collect.Lists;
import java.util.Iterator;
import java.util.List;
@@ -25,10 +25,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public abstract class MobSpawnerAbstract {
entity.f(nbttagcompound);
- if (entity.world != null) {
+ if (entity.world != null && flag) {
- entity.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit
+ // CraftBukkit start - call SpawnerSpawnEvent, abort if cancelled
-+ SpawnerSpawnEvent event = CraftEventFactory.callSpawnerSpawnEvent(entity, this.b(), this.c(), this.d());
++ SpawnerSpawnEvent event = CraftEventFactory.callSpawnerSpawnEvent(entity, this.b().getX(), this.b().getY(), this.b().getZ());
+ if (!event.isCancelled()) {
+ entity.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit
+ }
@@ -41,22 +41,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
entity2.f(nbttagcompound2);
entity2.setPositionRotation(entity1.locX, entity1.locY, entity1.locZ, entity1.yaw, entity1.pitch);
+ // CraftBukkit start - call SpawnerSpawnEvent, skip if cancelled
-+ SpawnerSpawnEvent event = CraftEventFactory.callSpawnerSpawnEvent(entity2, this.b(), this.c(), this.d());
++ SpawnerSpawnEvent event = CraftEventFactory.callSpawnerSpawnEvent(entity2, this.b().getX(), this.b().getY(), this.b().getZ());
+ if (event.isCancelled()) {
+ continue;
+ }
- if (entity.world != null) {
+ if (entity.world != null && flag) {
entity.world.addEntity(entity2, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit
}
@@ -0,0 +0,0 @@ public abstract class MobSpawnerAbstract {
}
- } else if (entity instanceof EntityLiving && entity.world != null) {
- ((EntityInsentient) entity).prepare((GroupDataEntity) null);
-- this.a().addEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit
+ } else if (entity instanceof EntityLiving && entity.world != null && flag) {
+ ((EntityInsentient) entity).prepare(entity.world.E(new BlockPosition(entity)), (GroupDataEntity) null);
+- entity.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit
+ // Spigot start - call SpawnerSpawnEvent, abort if cancelled
-+ SpawnerSpawnEvent event = CraftEventFactory.callSpawnerSpawnEvent(entity, this.b(), this.c(), this.d());
++ SpawnerSpawnEvent event = CraftEventFactory.callSpawnerSpawnEvent(entity, this.b().getX(), this.b().getY(), this.b().getZ());
+ if (!event.isCancelled()) {
-+ this.a().addEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit
++ entity.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit
+ }
+ // Spigot end
}
@@ -96,5 +96,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ /**
* Bucket methods
*/
- public static PlayerBucketEmptyEvent callPlayerBucketEmptyEvent(EntityHuman who, int clickedX, int clickedY, int clickedZ, int clickedFace, ItemStack itemInHand) {
+ public static PlayerBucketEmptyEvent callPlayerBucketEmptyEvent(EntityHuman who, int clickedX, int clickedY, int clickedZ, EnumDirection clickedFace, ItemStack itemInHand) {
--
\ No newline at end of file
diff --git a/CraftBukkit-Patches/0031-Firework-Meta-Crash-Fix.patch b/CraftBukkit-Patches/0027-Firework-Meta-Crash-Fix.patch
similarity index 100%
rename from CraftBukkit-Patches/0031-Firework-Meta-Crash-Fix.patch
rename to CraftBukkit-Patches/0027-Firework-Meta-Crash-Fix.patch
diff --git a/CraftBukkit-Patches/0032-Allow-Disabling-of-Command-Logging.patch b/CraftBukkit-Patches/0028-Allow-Disabling-of-Command-Logging.patch
similarity index 80%
rename from CraftBukkit-Patches/0032-Allow-Disabling-of-Command-Logging.patch
rename to CraftBukkit-Patches/0028-Allow-Disabling-of-Command-Logging.patch
index 541cef94ef..a9fc486ace 100644
--- a/CraftBukkit-Patches/0032-Allow-Disabling-of-Command-Logging.patch
+++ b/CraftBukkit-Patches/0028-Allow-Disabling-of-Command-Logging.patch
@@ -8,15 +8,14 @@ diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
-@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketPlayInListener {
+@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList
org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.startTiming(); // Spigot
- // CraftBukkit start - whole method
-- this.c.info(this.player.getName() + " issued server command: " + s);
-+ if ( org.spigotmc.SpigotConfig.logCommands ) this.c.info(this.player.getName() + " issued server command: " + s);
+ // CraftBukkit start - whole method
++ if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot
+ this.c.info(this.player.getName() + " issued server command: " + s);
CraftPlayer player = this.getPlayer();
-
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
diff --git a/CraftBukkit-Patches/0033-Allow-Disabling-of-Command-TabComplete.patch b/CraftBukkit-Patches/0029-Allow-Disabling-of-Command-TabComplete.patch
similarity index 100%
rename from CraftBukkit-Patches/0033-Allow-Disabling-of-Command-TabComplete.patch
rename to CraftBukkit-Patches/0029-Allow-Disabling-of-Command-TabComplete.patch
diff --git a/CraftBukkit-Patches/0029-Prevent-Shutdown-Hang.patch b/CraftBukkit-Patches/0029-Prevent-Shutdown-Hang.patch
deleted file mode 100644
index 9c21a6d2f8..0000000000
--- a/CraftBukkit-Patches/0029-Prevent-Shutdown-Hang.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: md_5
-Date: Tue, 11 Jun 2013 11:54:32 +1000
-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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/PlayerList.java
-+++ b/src/main/java/net/minecraft/server/PlayerList.java
-@@ -0,0 +0,0 @@ public abstract class PlayerList {
- }
-
- 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()) {
-+ // Spigot start
-+ EntityPlayer p = (EntityPlayer) this.players.get( 0 );
-+ p.playerConnection.disconnect( this.server.server.getShutdownMessage() );
-+ if ( ( !this.players.isEmpty() ) && ( this.players.get( 0 ) == p ) )
-+ {
-+ this.players.remove( 0 ); // Prevent shutdown hang if already disconnected
-+ }
-+ // Spigot end
- }
- }
-
---
\ No newline at end of file
diff --git a/CraftBukkit-Patches/0034-Configurable-Messages.patch b/CraftBukkit-Patches/0030-Configurable-Messages.patch
similarity index 86%
rename from CraftBukkit-Patches/0034-Configurable-Messages.patch
rename to CraftBukkit-Patches/0030-Configurable-Messages.patch
index 66275bf179..68f077aa5f 100644
--- a/CraftBukkit-Patches/0034-Configurable-Messages.patch
+++ b/CraftBukkit-Patches/0030-Configurable-Messages.patch
@@ -11,15 +11,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public class HandshakeListener implements PacketHandshakingInListener {
// CraftBukkit end
- if (packethandshakinginsetprotocol.d() > 5) {
-- chatcomponenttext = new ChatComponentText("Outdated server! I\'m still on 1.7.10");
-+ chatcomponenttext = new ChatComponentText( org.spigotmc.SpigotConfig.outdatedServerMessage ); // Spigot
- this.b.handle(new PacketLoginOutDisconnect(chatcomponenttext), new GenericFutureListener[0]);
+ if (packethandshakinginsetprotocol.b() > 47) {
+- chatcomponenttext = new ChatComponentText("Outdated server! I\'m still on 1.8");
++ chatcomponenttext = new ChatComponentText( java.text.MessageFormat.format( org.spigotmc.SpigotConfig.outdatedServerMessage, "1.8" ) ); // Spigot
+ this.b.handle(new PacketLoginOutDisconnect(chatcomponenttext));
this.b.close(chatcomponenttext);
- } else if (packethandshakinginsetprotocol.d() < 5) {
-- chatcomponenttext = new ChatComponentText("Outdated client! Please use 1.7.10");
-+ chatcomponenttext = new ChatComponentText( org.spigotmc.SpigotConfig.outdatedClientMessage ); // Spigot
- this.b.handle(new PacketLoginOutDisconnect(chatcomponenttext), new GenericFutureListener[0]);
+ } else if (packethandshakinginsetprotocol.b() < 47) {
+- chatcomponenttext = new ChatComponentText("Outdated client! Please use 1.8");
++ chatcomponenttext = new ChatComponentText(java.text.MessageFormat.format( org.spigotmc.SpigotConfig.outdatedClientMessage, "1.8" ) ); // Spigot
+ this.b.handle(new PacketLoginOutDisconnect(chatcomponenttext));
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
@@ -32,14 +32,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// 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) && !this.k.get(gameprofile).hasExpired()) {
- IpBanEntry ipbanentry = this.k.get(socketaddress);
+ } else if (getIPBans().isBanned(socketaddress) && !getIPBans().get(socketaddress).hasExpired()) {
+ IpBanEntry ipbanentry = this.l.get(socketaddress);
@@ -0,0 +0,0 @@ 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, "The server is full");
+ event.disallow(PlayerLoginEvent.Result.KICK_FULL, org.spigotmc.SpigotConfig.serverFullMessage); // Spigot
}
}
@@ -81,7 +81,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public static String whitelistMessage;
+ public static String unknownCommandMessage;
+ public static String serverFullMessage;
-+ public static String outdatedClientMessage = "Outdated client! Please use {}";
++ public static String outdatedClientMessage = "Outdated client! Please use {0}";
+ public static String outdatedServerMessage = "Outdated server! I\'m still on {0}";
+ private static String transform(String s)
+ {
@@ -89,7 +89,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ private static void messages()
+ {
-+ if (version < 4)
++ if (version < 8)
+ {
+ set( "messages.outdated-client", outdatedClientMessage );
+ set( "messages.outdated-server", outdatedServerMessage );
diff --git a/CraftBukkit-Patches/0035-Allow-Disabling-of-Random-Lighting-Updates.patch b/CraftBukkit-Patches/0031-Allow-Disabling-of-Random-Lighting-Updates.patch
similarity index 97%
rename from CraftBukkit-Patches/0035-Allow-Disabling-of-Random-Lighting-Updates.patch
rename to CraftBukkit-Patches/0031-Allow-Disabling-of-Random-Lighting-Updates.patch
index 817ae805e5..4258f77e51 100644
--- a/CraftBukkit-Patches/0035-Allow-Disabling-of-Random-Lighting-Updates.patch
+++ b/CraftBukkit-Patches/0031-Allow-Disabling-of-Random-Lighting-Updates.patch
@@ -11,12 +11,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public class Chunk {
}
- this.m = true;
+ this.p = 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();
+ this.n();
}
- }
+
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/World.java
diff --git a/CraftBukkit-Patches/0036-Properly-Close-Inventories.patch b/CraftBukkit-Patches/0032-Properly-Close-Inventories.patch
similarity index 81%
rename from CraftBukkit-Patches/0036-Properly-Close-Inventories.patch
rename to CraftBukkit-Patches/0032-Properly-Close-Inventories.patch
index 851682a64c..df246c139e 100644
--- a/CraftBukkit-Patches/0036-Properly-Close-Inventories.patch
+++ b/CraftBukkit-Patches/0032-Properly-Close-Inventories.patch
@@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Spigot Start
+ if ( tileentity instanceof IInventory )
+ {
-+ for ( org.bukkit.entity.HumanEntity h : new ArrayList( (List) ( (IInventory) tileentity ).getViewers() ) )
++ for ( org.bukkit.entity.HumanEntity h : Lists.newArrayList((List) ( (IInventory) tileentity ).getViewers() ) )
+ {
+ if ( h instanceof org.bukkit.craftbukkit.entity.CraftHumanEntity )
+ {
@@ -26,16 +26,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ // Spigot End
- this.world.a(tileentity);
+ this.world.b(tileentity);
}
@@ -0,0 +0,0 @@ public class Chunk {
- java.util.Iterator