diff options
31 files changed, 513 insertions, 183 deletions
diff --git a/nms-patches/BlockLeaves.patch b/nms-patches/BlockLeaves.patch index 78afcf0b..be0e66aa 100644 --- a/nms-patches/BlockLeaves.patch +++ b/nms-patches/BlockLeaves.patch @@ -1,5 +1,5 @@ ---- ../work/decompile-8eb82bde//net/minecraft/server/BlockLeaves.java 2014-11-28 17:43:42.913707439 +0000 -+++ src/main/java/net/minecraft/server/BlockLeaves.java 2014-11-28 17:38:22.000000000 +0000 +--- ../work/decompile-8eb82bde//net/minecraft/server/BlockLeaves.java 2014-11-29 22:31:45.788917956 +0000 ++++ src/main/java/net/minecraft/server/BlockLeaves.java 2014-11-29 22:27:58.604922998 +0000 @@ -2,6 +2,8 @@ import java.util.Random; @@ -17,7 +17,7 @@ + LeavesDecayEvent event = new LeavesDecayEvent(world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ())); + world.getServer().getPluginManager().callEvent(event); + -+ if (event.isCancelled()) { ++ if (event.isCancelled() || world.getType(blockposition).getBlock() != this) { + return; + } + // CraftBukkit end diff --git a/nms-patches/ChunkRegionLoader.patch b/nms-patches/ChunkRegionLoader.patch index 24a40d6e..75aeb037 100644 --- a/nms-patches/ChunkRegionLoader.patch +++ b/nms-patches/ChunkRegionLoader.patch @@ -1,5 +1,5 @@ ---- ../work/decompile-8eb82bde//net/minecraft/server/ChunkRegionLoader.java 2014-11-28 17:43:42.985707437 +0000 -+++ src/main/java/net/minecraft/server/ChunkRegionLoader.java 2014-11-28 17:38:17.000000000 +0000 +--- ../work/decompile-8eb82bde//net/minecraft/server/ChunkRegionLoader.java 2014-11-29 23:25:09.296846856 +0000 ++++ src/main/java/net/minecraft/server/ChunkRegionLoader.java 2014-11-29 23:24:59.400847076 +0000 @@ -23,8 +23,40 @@ public ChunkRegionLoader(File file) { this.e = file; @@ -18,11 +18,11 @@ + } + } + } -+ + + return RegionFileCache.a(this.e, i, j).chunkExists(i & 31, j & 31); + } + // CraftBukkit end - ++ + // CraftBukkit start - Add async variant, provide compatibility public Chunk a(World world, int i, int j) { + Object[] data = loadChunk(world, i, j); @@ -107,7 +107,37 @@ DataOutputStream dataoutputstream = RegionFileCache.d(this.e, pendingchunktosave.a.x, pendingchunktosave.a.z); NBTCompressedStreamTools.a(pendingchunktosave.b, (DataOutput) dataoutputstream); -@@ -320,7 +376,13 @@ +@@ -302,8 +358,27 @@ + int j1 = l >> 8 & 15; + int k1 = l >> 4 & 15; + int l1 = nibblearray1 != null ? nibblearray1.a(i1, j1, k1) : 0; +- +- achar[l] = (char) (l1 << 12 | (abyte[l] & 255) << 4 | nibblearray.a(i1, j1, k1)); ++ ++ // CraftBukkit start - fix broken blocks ++ // achar[l] = (char) (l1 << 12 | (abyte[l] & 255) << 4 | nibblearray.a(i1, j1, k1)); ++ ++ int ex = l1; ++ int id = (abyte[l] & 255); ++ int data = nibblearray.a(i1, j1, k1); ++ int packed = ex << 12 | id << 4 | data; ++ if (Block.d.a(packed) == null) { ++ Block block = Block.getById(ex << 8 | id); ++ if (block != null) { ++ try { ++ data = block.toLegacyData(block.fromLegacyData(data)); ++ } catch (Exception ignored) { ++ data = block.toLegacyData(block.getBlockData()); ++ } ++ packed = ex << 12 | id << 4 | data; ++ } ++ } ++ achar[l] = (char) packed; ++ // CraftBukkit end + } + + chunksection.a(achar); +@@ -320,7 +395,13 @@ if (nbttagcompound.hasKeyOfType("Biomes", 7)) { chunk.a(nbttagcompound.getByteArray("Biomes")); } @@ -121,7 +151,7 @@ NBTTagList nbttaglist1 = nbttagcompound.getList("Entities", 10); if (nbttaglist1 != null) { -@@ -379,6 +441,6 @@ +@@ -379,6 +460,6 @@ } } diff --git a/nms-patches/CommandBlockListenerAbstract.patch b/nms-patches/CommandBlockListenerAbstract.patch index 0bad2a43..aacf5ff8 100644 --- a/nms-patches/CommandBlockListenerAbstract.patch +++ b/nms-patches/CommandBlockListenerAbstract.patch @@ -1,5 +1,5 @@ ---- ../work/decompile-8eb82bde//net/minecraft/server/CommandBlockListenerAbstract.java 2014-11-28 20:19:48.021499587 +0000 -+++ src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java 2014-11-28 20:18:58.289500691 +0000 +--- ../work/decompile-8eb82bde//net/minecraft/server/CommandBlockListenerAbstract.java 2014-12-02 20:23:51.921621335 +0000 ++++ src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java 2014-12-02 20:23:10.809622247 +0000 @@ -4,6 +4,13 @@ import java.util.Date; import java.util.concurrent.Callable; @@ -134,7 +134,7 @@ } catch (Throwable throwable) { CrashReport crashreport = CrashReport.a(throwable, "Executing command block"); CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Command to be executed"); -@@ -91,8 +202,26 @@ +@@ -91,8 +202,27 @@ } else { this.b = 0; } @@ -143,7 +143,8 @@ + // CraftBukkit start + private ArrayList<String[]> buildCommands(String[] args, int pos) { + ArrayList<String[]> commands = new ArrayList<String[]>(); -+ EntityPlayer[] players = ((java.util.List<EntityPlayer>)PlayerSelector.getPlayers(this, args[pos], EntityPlayer.class)).toArray(new EntityPlayer[0]); ++ java.util.List<EntityPlayer> players = (java.util.List<EntityPlayer>)PlayerSelector.getPlayers(this, args[pos], EntityPlayer.class); ++ + if (players != null) { + for (EntityPlayer player : players) { + if (player.world != this.getWorld()) { diff --git a/nms-patches/Entity.patch b/nms-patches/Entity.patch index 4fcd6b44..2e5bc544 100644 --- a/nms-patches/Entity.patch +++ b/nms-patches/Entity.patch @@ -1,5 +1,5 @@ ---- ../work/decompile-8eb82bde//net/minecraft/server/Entity.java 2014-11-28 17:43:43.117707435 +0000 -+++ src/main/java/net/minecraft/server/Entity.java 2014-11-28 17:38:18.000000000 +0000 +--- ../work/decompile-8eb82bde//net/minecraft/server/Entity.java 2014-12-02 17:53:23.077821724 +0000 ++++ src/main/java/net/minecraft/server/Entity.java 2014-12-02 17:52:52.025822413 +0000 @@ -6,8 +6,40 @@ import java.util.UUID; import java.util.concurrent.Callable; @@ -576,3 +576,33 @@ } this.dead = true; +@@ -1680,8 +2042,27 @@ + return this.boundingBox; + } + +- public void a(AxisAlignedBB axisalignedbb) { +- this.boundingBox = axisalignedbb; ++ public void a(AxisAlignedBB axisalignedbb) { ++ // CraftBukkit start - block invalid bounding boxes ++ double a = axisalignedbb.a, ++ b = axisalignedbb.b, ++ c = axisalignedbb.c, ++ d = axisalignedbb.d, ++ e = axisalignedbb.e, ++ f = axisalignedbb.f; ++ double len = axisalignedbb.d - axisalignedbb.a; ++ if (len < 0) d = a; ++ if (len > 64) d = a + 64.0; ++ ++ len = axisalignedbb.e - axisalignedbb.b; ++ if (len < 0) e = b; ++ if (len > 64) e = b + 64.0; ++ ++ len = axisalignedbb.f - axisalignedbb.c; ++ if (len < 0) f = c; ++ if (len > 64) f = c + 64.0; ++ this.boundingBox = new AxisAlignedBB(a, b, c, d, e, f); ++ // CraftBukkit end + } + + public float getHeadHeight() { diff --git a/nms-patches/EntityArmorStand.patch b/nms-patches/EntityArmorStand.patch new file mode 100644 index 00000000..9dc6ba25 --- /dev/null +++ b/nms-patches/EntityArmorStand.patch @@ -0,0 +1,14 @@ +--- ../work/decompile-8eb82bde//net/minecraft/server/EntityArmorStand.java 2014-11-29 16:03:15.597435308 +0000 ++++ src/main/java/net/minecraft/server/EntityArmorStand.java 2014-11-29 16:02:17.625436595 +0000 +@@ -343,6 +343,11 @@ + } + + public boolean damageEntity(DamageSource damagesource, float f) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f)) { ++ return false; ++ } ++ // CraftBukkit end + if (!this.world.isStatic && !this.h) { + if (DamageSource.OUT_OF_WORLD.equals(damagesource)) { + this.die(); diff --git a/nms-patches/EntityHorse.patch b/nms-patches/EntityHorse.patch index 7fc41c73..048f5af2 100644 --- a/nms-patches/EntityHorse.patch +++ b/nms-patches/EntityHorse.patch @@ -1,5 +1,5 @@ ---- ../work/decompile-8eb82bde//net/minecraft/server/EntityHorse.java 2014-11-28 17:43:43.101707435 +0000 -+++ src/main/java/net/minecraft/server/EntityHorse.java 2014-11-28 17:38:22.000000000 +0000 +--- ../work/decompile-8eb82bde//net/minecraft/server/EntityHorse.java 2014-12-02 17:52:23.625823043 +0000 ++++ src/main/java/net/minecraft/server/EntityHorse.java 2014-12-02 17:51:30.837824215 +0000 @@ -4,6 +4,8 @@ import java.util.Iterator; import java.util.List; diff --git a/nms-patches/EntityHuman.patch b/nms-patches/EntityHuman.patch index 34cabe67..91bae5ac 100644 --- a/nms-patches/EntityHuman.patch +++ b/nms-patches/EntityHuman.patch @@ -1,5 +1,5 @@ ---- ../work/decompile-8eb82bde//net/minecraft/server/EntityHuman.java 2014-11-28 17:43:43.105707435 +0000 -+++ src/main/java/net/minecraft/server/EntityHuman.java 2014-11-28 17:38:17.000000000 +0000 +--- ../work/decompile-8eb82bde//net/minecraft/server/EntityHuman.java 2014-11-30 16:35:27.792804607 +0000 ++++ src/main/java/net/minecraft/server/EntityHuman.java 2014-11-30 16:34:50.780805428 +0000 @@ -8,13 +8,25 @@ import java.util.List; import java.util.UUID; @@ -361,7 +361,15 @@ this.sleepTicks = flag ? 0 : 100; if (flag2) { -@@ -1128,9 +1285,11 @@ +@@ -1090,6 +1247,7 @@ + } + + public static BlockPosition getBed(World world, BlockPosition blockposition, boolean flag) { ++ ((ChunkProviderServer) world.chunkProvider).getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4); // CraftBukkit + if (world.getType(blockposition).getBlock() != Blocks.BED) { + if (!flag) { + return null; +@@ -1128,9 +1286,11 @@ if (blockposition != null) { this.c = blockposition; this.d = flag; @@ -373,7 +381,7 @@ } } -@@ -1477,6 +1636,7 @@ +@@ -1477,6 +1637,7 @@ } public IChatBaseComponent getScoreboardDisplayName() { diff --git a/nms-patches/EntityPlayer.patch b/nms-patches/EntityPlayer.patch index 33d77767..777bd5b7 100644 --- a/nms-patches/EntityPlayer.patch +++ b/nms-patches/EntityPlayer.patch @@ -1,5 +1,5 @@ ---- ../work/decompile-8eb82bde//net/minecraft/server/EntityPlayer.java 2014-11-28 17:43:43.149707434 +0000 -+++ src/main/java/net/minecraft/server/EntityPlayer.java 2014-11-28 17:38:18.000000000 +0000 +--- ../work/decompile-8eb82bde//net/minecraft/server/EntityPlayer.java 2014-12-02 15:12:17.558036243 +0000 ++++ src/main/java/net/minecraft/server/EntityPlayer.java 2014-12-02 15:08:46.878040919 +0000 @@ -13,6 +13,17 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -50,7 +50,7 @@ } public void a(NBTTagCompound nbttagcompound) { -@@ -81,13 +108,39 @@ +@@ -81,14 +108,40 @@ this.playerInteractManager.setGameMode(EnumGamemode.getById(nbttagcompound.getInt("playerGameType"))); } } @@ -62,8 +62,8 @@ super.b(nbttagcompound); nbttagcompound.setInt("playerGameType", this.playerInteractManager.getGameMode().getId()); + this.getBukkitEntity().setExtraData(nbttagcompound); // CraftBukkit -+ } -+ + } + + // CraftBukkit start - World fallback code, either respawn location or global spawn + public void spawnIn(World world) { + super.spawnIn(world); @@ -86,11 +86,12 @@ + } + this.dimension = ((WorldServer) this.world).dimension; + this.playerInteractManager.a((WorldServer) world); - } ++ } + // CraftBukkit end - ++ public void levelDown(int i) { super.levelDown(i); + this.lastSentExp = -1; @@ -114,6 +167,11 @@ } @@ -136,7 +137,7 @@ - this.getScoreboard().getPlayerScoreForObjective(this.getName(), scoreboardobjective).updateForList(Arrays.asList(new EntityHuman[] { this})); - } + // CraftBukkit - Update ALL the scores! -+ this.world.getServer().getScoreboardManager().updateAllScoresForList(IScoreboardCriteria.f, this.getName(), com.google.common.collect.ImmutableList.of(this)); ++ this.world.getServer().getScoreboardManager().updateAllScoresForList(IScoreboardCriteria.g, this.getName(), com.google.common.collect.ImmutableList.of(this)); + } + // CraftBukkit start - Force max health updates + if (this.maxHealthCache != this.getMaxHealth()) { @@ -174,7 +175,12 @@ + if (this.dead) { + return; + } -+ + +- if (scoreboardteambase != null && scoreboardteambase.j() != EnumNameTagVisibility.ALWAYS) { +- if (scoreboardteambase.j() == EnumNameTagVisibility.HIDE_FOR_OTHER_TEAMS) { +- this.server.getPlayerList().a((EntityHuman) this, this.br().b()); +- } else if (scoreboardteambase.j() == EnumNameTagVisibility.HIDE_FOR_OWN_TEAM) { +- this.server.getPlayerList().b((EntityHuman) this, this.br().b()); + java.util.List<org.bukkit.inventory.ItemStack> loot = new java.util.ArrayList<org.bukkit.inventory.ItemStack>(); + boolean keepInventory = this.world.getGameRules().getBoolean("keepInventory"); + @@ -182,18 +188,13 @@ + for (int i = 0; i < this.inventory.items.length; ++i) { + if (this.inventory.items[i] != null) { + loot.add(CraftItemStack.asCraftMirror(this.inventory.items[i])); -+ } + } + } - -- if (scoreboardteambase != null && scoreboardteambase.j() != EnumNameTagVisibility.ALWAYS) { -- if (scoreboardteambase.j() == EnumNameTagVisibility.HIDE_FOR_OTHER_TEAMS) { -- this.server.getPlayerList().a((EntityHuman) this, this.br().b()); -- } else if (scoreboardteambase.j() == EnumNameTagVisibility.HIDE_FOR_OWN_TEAM) { -- this.server.getPlayerList().b((EntityHuman) this, this.br().b()); ++ + for (int i = 0; i < this.inventory.armor.length; ++i) { + if (this.inventory.armor[i] != null) { + loot.add(CraftItemStack.asCraftMirror(this.inventory.armor[i])); - } ++ } + } + } + @@ -433,19 +434,19 @@ public void triggerHealthUpdate() { this.bK = -1.0E8F; + this.lastSentExp = -1; // CraftBukkit - Added to reset -+ } + } + + // CraftBukkit start - Support multi-line messages + public void sendMessage(IChatBaseComponent[] ichatbasecomponent) { + for (IChatBaseComponent component : ichatbasecomponent) { + this.sendMessage(component); + } - } ++ } + // CraftBukkit end public void b(IChatBaseComponent ichatbasecomponent) { this.playerConnection.sendPacket(new PacketPlayOutChat(ichatbasecomponent)); -@@ -867,6 +1035,93 @@ +@@ -867,6 +1035,129 @@ } public IChatBaseComponent getPlayerListName() { @@ -484,12 +485,48 @@ + + if (type == WeatherType.DOWNFALL) { + this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(2, 0)); -+ // this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(7, this.world.j(1.0F))); -+ // this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(8, this.world.h(1.0F))); + } else { + this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(1, 0)); + } + } ++ ++ private float pluginRainPosition; ++ private float pluginRainPositionPrevious; ++ ++ public void updateWeather(float oldRain, float newRain, float oldThunder, float newThunder) { ++ if (this.weather == null) { ++ // Vanilla ++ if (oldRain != newRain) { ++ this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(7, newRain)); ++ } ++ } else { ++ // Plugin ++ if (pluginRainPositionPrevious != pluginRainPosition) { ++ this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(7, pluginRainPosition)); ++ } ++ } ++ ++ if (oldThunder != newThunder) { ++ if (weather == WeatherType.DOWNFALL || weather == null) { ++ this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(8, newThunder)); ++ } else { ++ this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(8, 0)); ++ } ++ } ++ } ++ ++ public void tickWeather() { ++ if (this.weather == null) return; ++ ++ pluginRainPositionPrevious = pluginRainPosition; ++ if (weather == WeatherType.DOWNFALL) { ++ pluginRainPosition += 0.01; ++ } else { ++ pluginRainPosition -= 0.01; ++ } ++ ++ pluginRainPosition = MathHelper.a(pluginRainPosition, 0.0F, 1.0F); ++ } + + public void resetPlayerWeather() { + this.weather = null; diff --git a/nms-patches/ItemMonsterEgg.patch b/nms-patches/ItemMonsterEgg.patch index 0bcf3613..a53df16b 100644 --- a/nms-patches/ItemMonsterEgg.patch +++ b/nms-patches/ItemMonsterEgg.patch @@ -1,5 +1,5 @@ ---- ../work/decompile-8eb82bde//net/minecraft/server/ItemMonsterEgg.java 2014-11-28 17:43:43.241707432 +0000 -+++ src/main/java/net/minecraft/server/ItemMonsterEgg.java 2014-11-28 17:38:19.000000000 +0000 +--- ../work/decompile-8eb82bde//net/minecraft/server/ItemMonsterEgg.java 2014-12-03 10:52:09.804159084 +0000 ++++ src/main/java/net/minecraft/server/ItemMonsterEgg.java 2014-12-03 10:51:53.380159449 +0000 @@ -19,7 +19,8 @@ } @@ -23,3 +23,12 @@ if (!EntityTypes.eggInfo.containsKey(Integer.valueOf(i))) { return null; } else { +@@ -123,7 +130,7 @@ + entityinsentient.aI = entityinsentient.yaw; + entityinsentient.aG = entityinsentient.yaw; + entityinsentient.prepare(world.E(new BlockPosition(entityinsentient)), (GroupDataEntity) null); +- world.addEntity(entity); ++ world.addEntity(entity, spawnReason); // CraftBukkit + entityinsentient.x(); + } + } diff --git a/nms-patches/ItemStack.patch b/nms-patches/ItemStack.patch index b6b6b6f4..ecc3c481 100644 --- a/nms-patches/ItemStack.patch +++ b/nms-patches/ItemStack.patch @@ -1,5 +1,5 @@ ---- ../work/decompile-8eb82bde//net/minecraft/server/ItemStack.java 2014-11-28 17:43:43.241707432 +0000 -+++ src/main/java/net/minecraft/server/ItemStack.java 2014-11-28 17:38:20.000000000 +0000 +--- ../work/decompile-8eb82bde//net/minecraft/server/ItemStack.java 2014-11-29 21:16:43.705017876 +0000 ++++ src/main/java/net/minecraft/server/ItemStack.java 2014-11-29 21:16:36.581018034 +0000 @@ -5,6 +5,18 @@ import java.text.DecimalFormat; import java.util.Random; diff --git a/nms-patches/MinecraftServer.patch b/nms-patches/MinecraftServer.patch index ed8f4f64..ea9982db 100644 --- a/nms-patches/MinecraftServer.patch +++ b/nms-patches/MinecraftServer.patch @@ -1,5 +1,5 @@ ---- ../work/decompile-8eb82bde//net/minecraft/server/MinecraftServer.java 2014-11-29 00:53:37.929134938 +0000 -+++ src/main/java/net/minecraft/server/MinecraftServer.java 2014-11-29 00:52:46.133136087 +0000 +--- ../work/decompile-8eb82bde//net/minecraft/server/MinecraftServer.java Sat Nov 29 19:31:45 2014 ++++ src/main/java/net/minecraft/server/MinecraftServer.java Sat Nov 29 19:27:57 2014 @@ -37,6 +37,18 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -98,7 +98,7 @@ this.h = new long[this.worldServer.length][100]; IDataManager idatamanager = this.convertable.a(s, true); -@@ -152,37 +207,110 @@ +@@ -152,37 +207,112 @@ worlddata.a(s1); worldsettings = new WorldSettings(worlddata); } @@ -142,6 +142,7 @@ + if (worlddata == null) { + worlddata = new WorldData(worldsettings, s1); + } ++ worlddata.checkName(s1); // CraftBukkit - Migration did not rewrite the level.dat; This forces 1.8 to take the last loaded world as respawn (in this case the end) if (this.W()) { - this.worldServer[j] = (WorldServer) (new DemoWorldServer(this, idatamanager, worlddata, b0, this.methodProfiler)).b(); + world = (WorldServer) (new DemoWorldServer(this, idatamanager, worlddata, dimension, this.methodProfiler)).b(); @@ -195,6 +196,7 @@ + if (worlddata == null) { + worlddata = new WorldData(worldsettings, name); + } ++ worlddata.checkName(name); // CraftBukkit - Migration did not rewrite the level.dat; This forces 1.8 to take the last loaded world as respawn (in this case the end) + world = (WorldServer) new SecondaryWorldServer(this, idatamanager, dimension, this.worlds.get(0), this.methodProfiler, worlddata, org.bukkit.World.Environment.getEnvironment(dimension), gen).b(); + } + @@ -220,7 +222,7 @@ this.a(this.getDifficulty()); this.k(); } -@@ -197,25 +325,38 @@ +@@ -197,25 +327,38 @@ this.b("menu.generatingTerrain"); byte b0 = 0; @@ -274,7 +276,7 @@ this.q(); } -@@ -247,35 +388,42 @@ +@@ -247,35 +390,42 @@ protected void q() { this.e = null; this.f = 0; @@ -329,7 +331,7 @@ if (this.ao() != null) { this.ao().b(); } -@@ -290,11 +438,13 @@ +@@ -290,11 +440,13 @@ MinecraftServer.LOGGER.info("Saving worlds"); this.saveChunks(false); @@ -343,7 +345,7 @@ } if (this.m.d()) { -@@ -335,6 +485,7 @@ +@@ -335,6 +487,7 @@ long k = j - this.ab; if (k > 2000L && this.ab - this.R >= 15000L) { @@ -351,7 +353,7 @@ MinecraftServer.LOGGER.warn("Can\'t keep up! Did the system time change, or is the server overloaded? Running {}ms behind, skipping {} tick(s)", new Object[] { Long.valueOf(k), Long.valueOf(k / 50L)}); k = 2000L; this.R = this.ab; -@@ -347,11 +498,12 @@ +@@ -347,11 +500,12 @@ i += k; this.ab = j; @@ -365,7 +367,7 @@ i -= 50L; this.y(); } -@@ -389,6 +541,12 @@ +@@ -389,6 +543,12 @@ } catch (Throwable throwable1) { MinecraftServer.LOGGER.error("Exception stopping the server", throwable1); } finally { @@ -378,7 +380,7 @@ this.x(); } -@@ -428,7 +586,7 @@ +@@ -428,7 +588,7 @@ protected void x() {} @@ -387,7 +389,7 @@ long i = System.nanoTime(); ++this.ticks; -@@ -454,7 +612,7 @@ +@@ -454,7 +614,7 @@ this.r.b().a(agameprofile); } @@ -396,7 +398,7 @@ this.methodProfiler.a("save"); this.v.savePlayers(); this.saveChunks(true); -@@ -493,20 +651,40 @@ +@@ -493,20 +653,40 @@ this.methodProfiler.c("levels"); @@ -440,7 +442,7 @@ this.methodProfiler.a("tick"); -@@ -533,9 +711,9 @@ +@@ -533,9 +713,9 @@ worldserver.getTracker().updatePlayers(); this.methodProfiler.b(); this.methodProfiler.b(); @@ -452,7 +454,7 @@ } this.methodProfiler.c("connection"); -@@ -559,10 +737,11 @@ +@@ -559,10 +739,11 @@ this.o.add(iupdateplayerlistbox); } @@ -465,7 +467,7 @@ boolean flag = true; String s = null; String s1 = "."; -@@ -636,6 +815,27 @@ +@@ -636,6 +817,27 @@ dedicatedserver.B(); Runtime.getRuntime().addShutdownHook(new ThreadShutdown("Server Shutdown Thread", dedicatedserver)); @@ -493,7 +495,7 @@ } catch (Exception exception) { MinecraftServer.LOGGER.fatal("Failed to start the minecraft server", exception); } -@@ -643,8 +843,10 @@ +@@ -643,8 +845,10 @@ } public void B() { @@ -504,7 +506,7 @@ } public File d(String s) { -@@ -660,7 +862,14 @@ +@@ -660,7 +864,14 @@ } public WorldServer getWorldServer(int i) { @@ -520,7 +522,7 @@ } public String C() { -@@ -696,17 +905,62 @@ +@@ -696,17 +907,62 @@ } public String getPlugins() { @@ -590,7 +592,7 @@ } public void h(String s) { -@@ -721,7 +975,7 @@ +@@ -721,7 +977,7 @@ } public String getServerModName() { @@ -599,7 +601,7 @@ } public CrashReport b(CrashReport crashreport) { -@@ -734,6 +988,7 @@ +@@ -734,6 +990,7 @@ } public List tabCompleteCommand(ICommandListener icommandlistener, String s, BlockPosition blockposition) { @@ -607,7 +609,7 @@ ArrayList arraylist = Lists.newArrayList(); if (s.startsWith("/")) { -@@ -772,6 +1027,9 @@ +@@ -772,6 +1029,9 @@ return arraylist; } @@ -617,7 +619,7 @@ } public static MinecraftServer getServer() { -@@ -779,7 +1037,7 @@ +@@ -779,7 +1039,7 @@ } public boolean N() { @@ -626,7 +628,7 @@ } public String getName() { -@@ -835,8 +1093,10 @@ +@@ -835,8 +1095,10 @@ } public void a(EnumDifficulty enumdifficulty) { @@ -639,7 +641,7 @@ if (worldserver != null) { if (worldserver.getWorldData().isHardcore()) { -@@ -878,15 +1138,17 @@ +@@ -878,15 +1140,17 @@ this.N = true; this.getConvertable().d(); @@ -660,7 +662,7 @@ this.safeShutdown(); } -@@ -919,9 +1181,11 @@ +@@ -919,9 +1183,11 @@ int i = 0; if (this.worldServer != null) { @@ -675,7 +677,7 @@ WorldData worlddata = worldserver.getWorldData(); mojangstatisticsgenerator.a("world[" + i + "][dimension]", Integer.valueOf(worldserver.worldProvider.getDimension())); -@@ -954,7 +1218,7 @@ +@@ -954,7 +1220,7 @@ public abstract boolean ad(); public boolean getOnlineMode() { @@ -684,7 +686,7 @@ } public void setOnlineMode(boolean flag) { -@@ -1024,8 +1288,10 @@ +@@ -1024,8 +1290,10 @@ } public void setGamemode(EnumGamemode enumgamemode) { @@ -697,7 +699,7 @@ } } -@@ -1057,7 +1323,7 @@ +@@ -1057,7 +1325,7 @@ } public World getWorld() { @@ -706,7 +708,7 @@ } public Entity f() { -@@ -1125,11 +1391,10 @@ +@@ -1125,11 +1393,10 @@ } public Entity a(UUID uuid) { @@ -722,7 +724,7 @@ if (worldserver != null) { Entity entity = worldserver.getEntity(uuid); -@@ -1144,7 +1409,7 @@ +@@ -1144,7 +1411,7 @@ } public boolean getSendCommandFeedback() { diff --git a/nms-patches/MobSpawnerAbstract.patch b/nms-patches/MobSpawnerAbstract.patch index 31d2d405..cd1aa977 100644 --- a/nms-patches/MobSpawnerAbstract.patch +++ b/nms-patches/MobSpawnerAbstract.patch @@ -1,5 +1,5 @@ ---- ../work/decompile-8eb82bde//net/minecraft/server/MobSpawnerAbstract.java 2014-11-28 17:43:43.261707431 +0000 -+++ src/main/java/net/minecraft/server/MobSpawnerAbstract.java 2014-11-28 17:38:17.000000000 +0000 +--- ../work/decompile-8eb82bde//net/minecraft/server/MobSpawnerAbstract.java 2014-12-01 10:08:05.390591149 +0000 ++++ src/main/java/net/minecraft/server/MobSpawnerAbstract.java 2014-12-01 10:07:23.810591600 +0000 @@ -4,6 +4,8 @@ import java.util.Iterator; import java.util.List; @@ -9,7 +9,19 @@ public abstract class MobSpawnerAbstract { public int spawnDelay = 20; -@@ -129,7 +131,7 @@ +@@ -24,6 +26,11 @@ + + public String getMobName() { + if (this.i() == null) { ++ // CraftBukkit start - fix NPE ++ if (this.mobName == null) { ++ this.mobName = "Pig"; ++ } ++ // CraftBukkit end + if (this.mobName.equals("Minecart")) { + this.mobName = "MinecartRideable"; + } +@@ -129,7 +136,7 @@ entity.f(nbttagcompound); if (entity.world != null && flag) { @@ -18,7 +30,7 @@ } NBTTagCompound nbttagcompound1; -@@ -154,7 +156,7 @@ +@@ -154,7 +161,7 @@ entity2.f(nbttagcompound2); entity2.setPositionRotation(entity1.locX, entity1.locY, entity1.locZ, entity1.yaw, entity1.pitch); if (entity.world != null && flag) { @@ -27,7 +39,7 @@ } entity1.mount(entity2); -@@ -164,7 +166,7 @@ +@@ -164,7 +171,7 @@ } } else if (entity instanceof EntityLiving && entity.world != null && flag) { ((EntityInsentient) entity).prepare(entity.world.E(new BlockPosition(entity)), (GroupDataEntity) null); diff --git a/nms-patches/PlayerConnection.patch b/nms-patches/PlayerConnection.patch index 5048a87a..4bf78c5d 100644 --- a/nms-patches/PlayerConnection.patch +++ b/nms-patches/PlayerConnection.patch @@ -1,5 +1,5 @@ ---- ../work/decompile-8eb82bde//net/minecraft/server/PlayerConnection.java 2014-11-28 23:05:41.713278672 +0000 -+++ src/main/java/net/minecraft/server/PlayerConnection.java 2014-11-28 22:57:27.221289000 +0000 +--- ../work/decompile-8eb82bde//net/minecraft/server/PlayerConnection.java 2014-12-02 20:39:19.177600755 +0000 ++++ src/main/java/net/minecraft/server/PlayerConnection.java 2014-12-02 20:38:47.001601469 +0000 @@ -16,6 +16,48 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -198,7 +198,7 @@ + + // If the event is cancelled we move the player back to their old location. + if (event.isCancelled()) { -+ this.player.playerConnection.sendPacket(new PacketPlayOutPosition(from.getX(), from.getY() + 1.6200000047683716D, from.getZ(), from.getYaw(), from.getPitch(), Collections.emptySet())); ++ this.player.playerConnection.sendPacket(new PacketPlayOutPosition(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch(), Collections.emptySet())); + return; + } + @@ -556,7 +556,7 @@ ChatMessage chatmessage = new ChatMessage("chat.cannotSend", new Object[0]); chatmessage.getChatModifier().setColor(EnumChatFormat.RED); -@@ -548,39 +852,248 @@ +@@ -548,39 +852,247 @@ for (int i = 0; i < s.length(); ++i) { if (!SharedConstants.isAllowedChatCharacter(s.charAt(i))) { @@ -755,12 +755,11 @@ PlayerConnectionUtils.ensureMainThread(packetplayinarmanimation, this, this.player.u()); this.player.z(); + // CraftBukkit start - Raytrace to look for 'rogue armswings' -+ float f = 1.0F; -+ float f1 = this.player.lastPitch + (this.player.pitch - this.player.lastPitch) * f; -+ float f2 = this.player.lastYaw + (this.player.yaw - this.player.lastYaw) * f; -+ double d0 = this.player.lastX + (this.player.locX - this.player.lastX) * (double) f; -+ double d1 = this.player.lastY + (this.player.locY - this.player.lastY) * (double) f + 1.62D - (double) this.player.getHeadHeight(); -+ double d2 = this.player.lastZ + (this.player.locZ - this.player.lastZ) * (double) f; ++ float f1 = this.player.pitch; ++ float f2 = this.player.yaw; ++ double d0 = this.player.locX; ++ double d1 = this.player.locY + (double) this.player.getHeadHeight(); ++ double d2 = this.player.locZ; + Vec3D vec3d = new Vec3D(d0, d1, d2); + + float f3 = MathHelper.cos(-f2 * 0.017453292F - 3.1415927F); @@ -813,7 +812,7 @@ this.player.z(); switch (SwitchHelperCommandActionType.b[packetplayinentityaction.b().ordinal()]) { case 1: -@@ -601,7 +1114,7 @@ +@@ -601,7 +1113,7 @@ case 5: this.player.a(false, true, true); @@ -822,7 +821,7 @@ break; case 6: -@@ -623,6 +1136,7 @@ +@@ -623,6 +1135,7 @@ } public void a(PacketPlayInUseEntity packetplayinuseentity) { @@ -830,7 +829,7 @@ PlayerConnectionUtils.ensureMainThread(packetplayinuseentity, this, this.player.u()); WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); Entity entity = packetplayinuseentity.a((World) worldserver); -@@ -637,18 +1151,72 @@ +@@ -637,18 +1150,72 @@ } if (this.player.h(entity) < d0) { @@ -904,7 +903,7 @@ } } } -@@ -663,7 +1231,8 @@ +@@ -663,7 +1230,8 @@ switch (SwitchHelperCommandActionType.c[enumclientcommand.ordinal()]) { case 1: if (this.player.viewingCredits) { @@ -914,7 +913,7 @@ } else if (this.player.u().getWorldData().isHardcore()) { if (this.minecraftServer.S() && this.player.getName().equals(this.minecraftServer.R())) { this.player.playerConnection.disconnect("You have died. Game over, man, it\'s game over!"); -@@ -694,11 +1263,17 @@ +@@ -694,11 +1262,17 @@ } public void a(PacketPlayInCloseWindow packetplayinclosewindow) { @@ -932,7 +931,7 @@ PlayerConnectionUtils.ensureMainThread(packetplayinwindowclick, this, this.player.u()); this.player.z(); if (this.player.activeContainer.windowId == packetplayinwindowclick.a() && this.player.activeContainer.c(this.player)) { -@@ -711,7 +1286,263 @@ +@@ -711,7 +1285,263 @@ this.player.a(this.player.activeContainer, (List) arraylist); } else { @@ -1197,7 +1196,7 @@ if (ItemStack.matches(packetplayinwindowclick.e(), itemstack)) { this.player.playerConnection.sendPacket(new PacketPlayOutTransaction(packetplayinwindowclick.a(), packetplayinwindowclick.d(), true)); -@@ -772,8 +1603,50 @@ +@@ -772,8 +1602,50 @@ } boolean flag1 = packetplayinsetcreativeslot.a() >= 1 && packetplayinsetcreativeslot.a() < 36 + PlayerInventory.getHotbarSize(); @@ -1249,7 +1248,7 @@ if (flag1 && flag2 && flag3) { if (itemstack == null) { -@@ -796,6 +1669,7 @@ +@@ -796,6 +1668,7 @@ } public void a(PacketPlayInTransaction packetplayintransaction) { @@ -1257,7 +1256,7 @@ PlayerConnectionUtils.ensureMainThread(packetplayintransaction, this, this.player.u()); Short oshort = (Short) this.n.get(this.player.activeContainer.windowId); -@@ -806,6 +1680,7 @@ +@@ -806,6 +1679,7 @@ } public void a(PacketPlayInUpdateSign packetplayinupdatesign) { @@ -1265,7 +1264,7 @@ PlayerConnectionUtils.ensureMainThread(packetplayinupdatesign, this, this.player.u()); this.player.z(); WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); -@@ -822,10 +1697,24 @@ +@@ -822,10 +1696,24 @@ if (!tileentitysign.b() || tileentitysign.c() != this.player) { this.minecraftServer.warning("Player " + this.player.getName() + " just tried to change non-editable sign"); @@ -1291,7 +1290,7 @@ tileentitysign.update(); worldserver.notify(blockposition); } -@@ -847,11 +1736,28 @@ +@@ -847,11 +1735,28 @@ public void a(PacketPlayInAbilities packetplayinabilities) { PlayerConnectionUtils.ensureMainThread(packetplayinabilities, this, this.player.u()); @@ -1321,7 +1320,7 @@ ArrayList arraylist = Lists.newArrayList(); Iterator iterator = this.minecraftServer.tabCompleteCommand(this.player, packetplayintabcomplete.a(), packetplayintabcomplete.b()).iterator(); -@@ -891,13 +1797,15 @@ +@@ -891,13 +1796,15 @@ itemstack1 = this.player.inventory.getItemInHand(); if (itemstack1 != null) { if (itemstack.getItem() == Items.WRITABLE_BOOK && itemstack.getItem() == itemstack1.getItem()) { @@ -1338,7 +1337,7 @@ return; } finally { packetdataserializer.release(); -@@ -909,27 +1817,31 @@ +@@ -909,27 +1816,31 @@ try { itemstack = packetdataserializer.i(); @@ -1382,7 +1381,7 @@ return; } finally { packetdataserializer.release(); -@@ -946,6 +1858,7 @@ +@@ -946,6 +1857,7 @@ } } catch (Exception exception2) { PlayerConnection.c.error("Couldn\'t select trade", exception2); @@ -1390,7 +1389,7 @@ } } else if ("MC|AdvCdm".equals(packetplayincustompayload.a())) { if (!this.minecraftServer.getEnableCommandBlock()) { -@@ -986,6 +1899,7 @@ +@@ -986,6 +1898,7 @@ } } catch (Exception exception3) { PlayerConnection.c.error("Couldn\'t set command block", exception3); @@ -1398,7 +1397,7 @@ } finally { packetdataserializer.release(); } -@@ -1011,6 +1925,7 @@ +@@ -1011,6 +1924,7 @@ } } catch (Exception exception4) { PlayerConnection.c.error("Couldn\'t set beacon", exception4); @@ -1406,7 +1405,7 @@ } } } else if ("MC|ItemName".equals(packetplayincustompayload.a()) && this.player.activeContainer instanceof ContainerAnvil) { -@@ -1026,6 +1941,27 @@ +@@ -1026,6 +1940,27 @@ containeranvil.a(""); } } diff --git a/nms-patches/PlayerList.patch b/nms-patches/PlayerList.patch index 886d3b3d..ce5cc7d7 100644 --- a/nms-patches/PlayerList.patch +++ b/nms-patches/PlayerList.patch @@ -1,5 +1,5 @@ ---- ../work/decompile-8eb82bde//net/minecraft/server/PlayerList.java 2014-11-28 17:43:43.333707430 +0000 -+++ src/main/java/net/minecraft/server/PlayerList.java 2014-11-28 17:38:17.000000000 +0000 +--- ../work/decompile-8eb82bde//net/minecraft/server/PlayerList.java 2014-12-03 11:08:25.244137435 +0000 ++++ src/main/java/net/minecraft/server/PlayerList.java 2014-12-03 11:08:02.624137937 +0000 @@ -18,6 +18,25 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -200,7 +200,7 @@ + EntityPlayer entityplayer1 = (EntityPlayer) this.players.get(i); + + if (entityplayer1.getBukkitEntity().canSee(entityplayer.getBukkitEntity())) { -+ entityplayer1.playerConnection.sendPacket(packet); ++ entityplayer1.playerConnection.sendPacket(packet); + } else { + entityplayer1.getBukkitEntity().removeDisconnectingPlayer(entityplayer.getBukkitEntity()); + } @@ -711,7 +711,7 @@ if (entityplayer != entityhuman && entityplayer.dimension == i) { double d4 = d0 - entityplayer.locX; double d5 = d1 - entityplayer.locY; -@@ -634,21 +981,25 @@ +@@ -634,21 +981,26 @@ public void reloadWhitelist() {} public void b(EntityPlayer entityplayer, WorldServer worldserver) { @@ -729,6 +729,7 @@ + // entityplayer.playerConnection.sendPacket(new PacketPlayOutGameStateChange(7, worldserver.j(1.0F))); + // entityplayer.playerConnection.sendPacket(new PacketPlayOutGameStateChange(8, worldserver.h(1.0F))); + entityplayer.setPlayerWeather(org.bukkit.WeatherType.DOWNFALL, false); ++ entityplayer.updateWeather(-worldserver.p, worldserver.p, -worldserver.r, worldserver.r); + // CraftBukkit end } @@ -742,7 +743,7 @@ entityplayer.playerConnection.sendPacket(new PacketPlayOutHeldItemSlot(entityplayer.inventory.itemInHandIndex)); } -@@ -661,7 +1012,7 @@ +@@ -661,7 +1013,7 @@ } public String[] getSeenPlayers() { @@ -751,7 +752,7 @@ } public boolean getHasWhitelist() { -@@ -711,10 +1062,17 @@ +@@ -711,10 +1063,17 @@ public void v() { for (int i = 0; i < this.players.size(); ++i) { @@ -770,7 +771,7 @@ public void sendMessage(IChatBaseComponent ichatbasecomponent, boolean flag) { this.server.sendMessage(ichatbasecomponent); -@@ -754,11 +1112,10 @@ +@@ -754,11 +1113,10 @@ public void a(int i) { this.r = i; if (this.server.worldServer != null) { diff --git a/nms-patches/PlayerSelector.patch b/nms-patches/PlayerSelector.patch index e7d05e52..a31e8db6 100644 --- a/nms-patches/PlayerSelector.patch +++ b/nms-patches/PlayerSelector.patch @@ -1,5 +1,5 @@ ---- ../work/decompile-8eb82bde//net/minecraft/server/PlayerSelector.java 2014-11-28 17:43:43.337707430 +0000 -+++ src/main/java/net/minecraft/server/PlayerSelector.java 2014-11-28 17:38:17.000000000 +0000 +--- ../work/decompile-8eb82bde//net/minecraft/server/PlayerSelector.java 2014-12-02 20:23:52.649621319 +0000 ++++ src/main/java/net/minecraft/server/PlayerSelector.java 2014-12-02 20:22:46.409622789 +0000 @@ -52,6 +52,11 @@ } @@ -12,3 +12,12 @@ Matcher matcher = PlayerSelector.a.matcher(s); if (matcher.matches() && icommandlistener.a(1, "@")) { +@@ -97,7 +102,7 @@ + if (h(map)) { + arraylist.add(icommandlistener.getWorld()); + } else { +- Collections.addAll(arraylist, MinecraftServer.getServer().worldServer); ++ arraylist.addAll(MinecraftServer.getServer().worlds); // CraftBukkit + } + + return arraylist; diff --git a/nms-patches/TileEntitySign.patch b/nms-patches/TileEntitySign.patch new file mode 100644 index 00000000..ce9d878f --- /dev/null +++ b/nms-patches/TileEntitySign.patch @@ -0,0 +1,43 @@ +--- ../work/decompile-8eb82bde//net/minecraft/server/TileEntitySign.java 2014-11-30 11:23:30.317220028 +0000 ++++ src/main/java/net/minecraft/server/TileEntitySign.java 2014-11-30 11:22:37.521221199 +0000 +@@ -20,6 +20,12 @@ + + nbttagcompound.setString("Text" + (i + 1), s); + } ++ ++ // CraftBukkit start ++ if (Boolean.getBoolean("convertLegacySigns")) { ++ nbttagcompound.setBoolean("Bukkit.isConverted", true); ++ } ++ // CraftBukkit end + + this.i.b(nbttagcompound); + } +@@ -29,14 +35,27 @@ + super.a(nbttagcompound); + TileEntitySignCommandListener tileentitysigncommandlistener = new TileEntitySignCommandListener(this); + ++ // CraftBukkit start - Add an option to convert signs correctly ++ // This is done with a flag instead of all the time because ++ // we have no way to tell whether a sign is from 1.7.10 or 1.8 ++ ++ boolean oldSign = Boolean.getBoolean("convertLegacySigns") && !nbttagcompound.getBoolean("Bukkit.isConverted"); ++ + for (int i = 0; i < 4; ++i) { + String s = nbttagcompound.getString("Text" + (i + 1)); ++ ++ if (oldSign) { ++ lines[i] = org.bukkit.craftbukkit.util.CraftChatMessage.fromString(s)[0]; ++ continue; ++ } ++ // CraftBukkit end + + try { + IChatBaseComponent ichatbasecomponent = ChatSerializer.a(s); + + try { + this.lines[i] = ChatComponentUtils.filterForDisplay(tileentitysigncommandlistener, ichatbasecomponent, (Entity) null); ++ if (false) throw new CommandException(null, null); // CraftBukkit - fix decompile error + } catch (CommandException commandexception) { + this.lines[i] = ichatbasecomponent; + } diff --git a/nms-patches/World.patch b/nms-patches/World.patch index 0645b76e..3131a603 100644 --- a/nms-patches/World.patch +++ b/nms-patches/World.patch @@ -1,5 +1,5 @@ ---- ../work/decompile-8eb82bde//net/minecraft/server/World.java 2014-11-28 17:43:43.433707428 +0000 -+++ src/main/java/net/minecraft/server/World.java 2014-11-28 17:38:23.000000000 +0000 +--- ../work/decompile-8eb82bde//net/minecraft/server/World.java 2014-12-02 15:12:18.222036228 +0000 ++++ src/main/java/net/minecraft/server/World.java 2014-12-02 15:04:12.678047004 +0000 @@ -13,6 +13,22 @@ import java.util.UUID; import java.util.concurrent.Callable; @@ -33,7 +33,7 @@ private int K; public boolean allowMonsters; public boolean allowAnimals; -@@ -55,7 +72,39 @@ +@@ -55,7 +72,52 @@ private final WorldBorder M; int[] H; @@ -46,7 +46,20 @@ + + public boolean captureBlockStates = false; + public boolean captureTreeGeneration = false; -+ public ArrayList<BlockState> capturedBlockStates= new ArrayList<BlockState>(); ++ public ArrayList<BlockState> capturedBlockStates= new ArrayList<BlockState>(){ ++ @Override ++ public boolean add( BlockState blockState ) { ++ Iterator<BlockState> blockStateIterator = this.iterator(); ++ while( blockStateIterator.hasNext() ) { ++ BlockState blockState1 = blockStateIterator.next(); ++ if ( blockState1.getLocation().equals( blockState.getLocation() ) ) { ++ return false; ++ } ++ } ++ ++ return super.add( blockState ); ++ } ++ }; + public long ticksPerAnimalSpawns; + public long ticksPerMonsterSpawns; + public boolean populating; @@ -74,7 +87,7 @@ this.K = this.random.nextInt(12000); this.allowMonsters = true; this.allowAnimals = true; -@@ -66,6 +115,8 @@ +@@ -66,6 +128,8 @@ this.worldProvider = worldprovider; this.isStatic = flag; this.M = worldprovider.getWorldBorder(); @@ -83,7 +96,7 @@ } public World b() { -@@ -184,6 +235,27 @@ +@@ -184,6 +248,27 @@ } public boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i) { @@ -111,7 +124,7 @@ if (!this.isValidLocation(blockposition)) { return false; } else if (!this.isStatic && this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) { -@@ -191,9 +263,23 @@ +@@ -191,9 +276,23 @@ } else { Chunk chunk = this.getChunkAtWorldCoords(blockposition); Block block = iblockdata.getBlock(); @@ -128,14 +141,14 @@ if (iblockdata1 == null) { + // CraftBukkit start - remove blockstate if failed -+ if (!this.captureBlockStates) { ++ if (this.captureBlockStates) { + this.capturedBlockStates.remove(blockstate); + } + // CraftBukkit end return false; } else { Block block1 = iblockdata1.getBlock(); -@@ -204,6 +290,7 @@ +@@ -204,6 +303,7 @@ this.methodProfiler.b(); } @@ -143,7 +156,7 @@ if ((i & 2) != 0 && (!this.isStatic || (i & 4) == 0) && chunk.isReady()) { this.notify(blockposition); } -@@ -214,12 +301,35 @@ +@@ -214,12 +314,35 @@ this.updateAdjacentComparators(blockposition, block); } } @@ -179,7 +192,7 @@ public boolean setAir(BlockPosition blockposition) { return this.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 3); } -@@ -253,6 +363,11 @@ +@@ -253,6 +376,11 @@ public void update(BlockPosition blockposition, Block block) { if (this.worldData.getType() != WorldType.DEBUG_ALL_BLOCK_STATES) { @@ -191,7 +204,7 @@ this.applyPhysics(blockposition, block); } -@@ -328,6 +443,17 @@ +@@ -328,6 +456,17 @@ IBlockData iblockdata = this.getType(blockposition); try { @@ -209,7 +222,7 @@ iblockdata.getBlock().doPhysics(this, blockposition, iblockdata, block); } catch (Throwable throwable) { CrashReport crashreport = CrashReport.a(throwable, "Exception while updating neighbours"); -@@ -497,6 +623,17 @@ +@@ -497,6 +636,17 @@ } public IBlockData getType(BlockPosition blockposition) { @@ -227,7 +240,7 @@ if (!this.isValidLocation(blockposition)) { return Blocks.AIR.getBlockData(); } else { -@@ -704,6 +841,13 @@ +@@ -704,6 +854,13 @@ } public boolean addEntity(Entity entity) { @@ -241,7 +254,7 @@ int i = MathHelper.floor(entity.locX / 16.0D); int j = MathHelper.floor(entity.locZ / 16.0D); boolean flag = entity.attachedToPlayer; -@@ -712,7 +856,35 @@ +@@ -712,7 +869,35 @@ flag = true; } @@ -277,7 +290,7 @@ return false; } else { if (entity instanceof EntityHuman) { -@@ -734,6 +906,7 @@ +@@ -734,6 +919,7 @@ ((IWorldAccess) this.u.get(i)).a(entity); } @@ -285,7 +298,7 @@ } protected void b(Entity entity) { -@@ -741,6 +914,7 @@ +@@ -741,6 +927,7 @@ ((IWorldAccess) this.u.get(i)).b(entity); } @@ -293,7 +306,7 @@ } public void kill(Entity entity) { -@@ -775,7 +949,15 @@ +@@ -775,7 +962,15 @@ this.getChunkAt(i, j).b(entity); } @@ -310,7 +323,7 @@ this.b(entity); } -@@ -958,6 +1140,11 @@ +@@ -958,6 +1153,11 @@ for (i = 0; i < this.k.size(); ++i) { entity = (Entity) this.k.get(i); @@ -322,7 +335,7 @@ try { ++entity.ticksLived; -@@ -1001,8 +1188,10 @@ +@@ -1001,8 +1201,10 @@ this.g.clear(); this.methodProfiler.c("regular"); @@ -335,7 +348,7 @@ if (entity.vehicle != null) { if (!entity.vehicle.dead && entity.vehicle.passenger == entity) { continue; -@@ -1033,7 +1222,7 @@ +@@ -1033,7 +1235,7 @@ this.getChunkAt(j, k).b(entity); } @@ -344,7 +357,7 @@ this.b(entity); } -@@ -1042,6 +1231,14 @@ +@@ -1042,6 +1244,14 @@ this.methodProfiler.c("blockEntities"); this.L = true; @@ -359,7 +372,7 @@ Iterator iterator = this.tileEntityList.iterator(); while (iterator.hasNext()) { -@@ -1073,11 +1270,13 @@ +@@ -1073,11 +1283,13 @@ } this.L = false; @@ -373,7 +386,7 @@ this.methodProfiler.c("pendingBlockEntities"); if (!this.a.isEmpty()) { -@@ -1085,9 +1284,11 @@ +@@ -1085,9 +1297,11 @@ TileEntity tileentity1 = (TileEntity) this.a.get(l); if (!tileentity1.x()) { @@ -385,7 +398,7 @@ if (this.isLoaded(tileentity1.getPosition())) { this.getChunkAtWorldCoords(tileentity1.getPosition()).a(tileentity1.getPosition(), tileentity1); -@@ -1141,7 +1342,10 @@ +@@ -1141,7 +1355,10 @@ int j = MathHelper.floor(entity.locZ); byte b0 = 32; @@ -397,7 +410,7 @@ entity.P = entity.locX; entity.Q = entity.locY; entity.R = entity.locZ; -@@ -1615,7 +1819,13 @@ +@@ -1615,7 +1832,13 @@ --j; this.worldData.setThunderDuration(j); if (j <= 0) { @@ -412,7 +425,7 @@ } } -@@ -1639,7 +1849,14 @@ +@@ -1639,7 +1862,14 @@ --k; this.worldData.setWeatherDuration(k); if (k <= 0) { @@ -428,7 +441,18 @@ } } -@@ -1656,7 +1873,7 @@ +@@ -1651,12 +1881,18 @@ + } + + this.p = MathHelper.a(this.p, 0.0F, 1.0F); ++ ++ for (int idx = 0; idx < this.players.size(); ++idx) { ++ if (((EntityPlayer) this.players.get(idx)).world == this) { ++ ((EntityPlayer) this.players.get(idx)).tickWeather(); ++ } ++ } + } + } } protected void D() { @@ -437,7 +461,7 @@ this.methodProfiler.a("buildList"); int i; -@@ -1673,7 +1890,7 @@ +@@ -1673,7 +1909,7 @@ for (int i1 = -l; i1 <= l; ++i1) { for (int j1 = -l; j1 <= l; ++j1) { @@ -446,7 +470,7 @@ } } } -@@ -1851,7 +2068,10 @@ +@@ -1851,7 +2087,10 @@ } public boolean c(EnumSkyBlock enumskyblock, BlockPosition blockposition) { @@ -458,7 +482,7 @@ return false; } else { int i = 0; -@@ -2095,8 +2315,17 @@ +@@ -2095,8 +2334,17 @@ while (iterator.hasNext()) { Entity entity = (Entity) iterator.next(); @@ -477,7 +501,7 @@ ++i; } } -@@ -2105,12 +2334,17 @@ +@@ -2105,12 +2353,17 @@ } public void b(Collection collection) { @@ -497,7 +521,7 @@ this.a(entity); } -@@ -2124,7 +2358,13 @@ +@@ -2124,7 +2377,13 @@ Block block1 = this.getType(blockposition).getBlock(); AxisAlignedBB axisalignedbb = flag ? null : block.a(this, blockposition, block.getBlockData()); @@ -512,7 +536,7 @@ } public int getBlockPower(BlockPosition blockposition, EnumDirection enumdirection) { -@@ -2215,6 +2455,11 @@ +@@ -2215,6 +2474,11 @@ for (int i = 0; i < this.players.size(); ++i) { EntityHuman entityhuman1 = (EntityHuman) this.players.get(i); @@ -524,7 +548,7 @@ if (IEntitySelector.d.apply(entityhuman1)) { double d5 = entityhuman1.e(d0, d1, d2); -@@ -2269,7 +2514,7 @@ +@@ -2269,7 +2533,7 @@ return null; } @@ -533,7 +557,7 @@ this.dataManager.checkSession(); } -@@ -2331,6 +2576,16 @@ +@@ -2331,6 +2595,16 @@ public void everyoneSleeping() {} @@ -550,7 +574,7 @@ public float h(float f) { return (this.q + (this.r - this.q) * f) * this.j(f); } -@@ -2538,6 +2793,6 @@ +@@ -2538,6 +2812,6 @@ int l = j * 16 + 8 - blockposition.getZ(); short short0 = 128; diff --git a/nms-patches/WorldData.patch b/nms-patches/WorldData.patch new file mode 100644 index 00000000..41e25097 --- /dev/null +++ b/nms-patches/WorldData.patch @@ -0,0 +1,15 @@ +--- ../work/decompile-8eb82bde//net/minecraft/server/WorldData.java Sat Nov 29 19:36:33 2014 ++++ src/main/java/net/minecraft/server/WorldData.java Sat Nov 29 19:35:56 2014 +@@ -645,4 +645,12 @@ + static boolean q(WorldData worlddata) { + return worlddata.x; + } ++ ++ // CraftBukkit start - Check if the name stored in NBT is the correct one ++ public void checkName( String name ) { ++ if ( !this.n.equals( name ) ) { ++ this.n = name; ++ } ++ } ++ // CraftBukkit end + } diff --git a/nms-patches/WorldServer.patch b/nms-patches/WorldServer.patch index a8557e42..d7463e8a 100644 --- a/nms-patches/WorldServer.patch +++ b/nms-patches/WorldServer.patch @@ -1,5 +1,5 @@ ---- ../work/decompile-8eb82bde//net/minecraft/server/WorldServer.java 2014-11-28 17:43:43.445707427 +0000 -+++ src/main/java/net/minecraft/server/WorldServer.java 2014-11-28 17:38:23.000000000 +0000 +--- ../work/decompile-8eb82bde//net/minecraft/server/WorldServer.java 2014-12-02 15:12:18.246036227 +0000 ++++ src/main/java/net/minecraft/server/WorldServer.java 2014-12-02 15:02:48.310048877 +0000 @@ -16,6 +16,20 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -513,10 +513,11 @@ if (this.o != this.p) { this.server.getPlayerList().a(new PacketPlayOutGameStateChange(7, this.p), this.worldProvider.getDimension()); } -@@ -827,6 +1063,16 @@ +@@ -827,7 +1063,21 @@ this.server.getPlayerList().sendAll(new PacketPlayOutGameStateChange(7, this.p)); this.server.getPlayerList().sendAll(new PacketPlayOutGameStateChange(8, this.r)); } +- + // */ + if (flag != this.S()) { + // Only send weather packets to those affected @@ -525,12 +526,17 @@ + ((EntityPlayer) this.players.get(i)).setPlayerWeather((!flag ? WeatherType.DOWNFALL : WeatherType.CLEAR), false); + } + } -+ // CraftBukkit end + } - ++ for (int i = 0; i < this.players.size(); ++i) { ++ if (((EntityPlayer) this.players.get(i)).world == this) { ++ ((EntityPlayer) this.players.get(i)).updateWeather(this.o, this.p, this.q, this.r); ++ } ++ } ++ // CraftBukkit end } -@@ -855,10 +1101,17 @@ + protected int q() { +@@ -855,10 +1105,17 @@ } public void a(EnumParticle enumparticle, boolean flag, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, int... aint) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java index 9b481a08..b1f6a207 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java @@ -72,7 +72,7 @@ public class CraftChunk implements Chunk { } public Block getBlock(int x, int y, int z) { - return new CraftBlock(this, (getX() << 4) | (x & 0xF), y & 0xFF, (getZ() << 4) | (z & 0xF)); + return new CraftBlock(this, (getX() << 4) | (x & 0xF), y, (getZ() << 4) | (z & 0xF)); } public Entity[] getEntities() { @@ -111,7 +111,7 @@ public class CraftChunk implements Chunk { } BlockPosition position = (BlockPosition) obj; - entities[index++] = worldServer.getWorld().getBlockAt(position.getX() + (chunk.locX << 4), position.getY(), position.getZ() + (chunk.locZ << 4)).getState(); + entities[index++] = worldServer.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()).getState(); } return entities; } @@ -170,6 +170,7 @@ public class CraftChunk implements Chunk { for (int j = 0; j < 4096; j++) { if (baseids[j] == 0) continue; IBlockData blockData = (IBlockData) net.minecraft.server.Block.d.a(baseids[j]); + if (blockData == null) continue; blockids[j] = (short) net.minecraft.server.Block.getId(blockData.getBlock()); int data = blockData.getBlock().toLegacyData(blockData); int jj = j >> 1; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index f2a78c17..fa1fe206 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -114,11 +114,11 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.collect.MapMaker; import com.mojang.authlib.GameProfile; + import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufOutputStream; import io.netty.buffer.Unpooled; import io.netty.handler.codec.base64.Base64; - import jline.console.ConsoleReader; public final class CraftServer implements Server { @@ -844,8 +844,13 @@ public final class CraftServer implements Server { } while(used); boolean hardcore = false; - WorldData worlddata = new WorldData(new WorldSettings(creator.seed(), EnumGamemode.getById(getDefaultGameMode().getValue()), generateStructures, hardcore, type), name); - WorldServer internal = (WorldServer) new WorldServer(console, new ServerNBTManager(getWorldContainer(), name, true), worlddata, dimension, console.methodProfiler, creator.environment(), generator).b(); + IDataManager sdm = new ServerNBTManager(getWorldContainer(), name, true); + WorldData worlddata = sdm.getWorldData(); + if (worlddata == null) { + worlddata = new WorldData(new WorldSettings(creator.seed(), EnumGamemode.getById(getDefaultGameMode().getValue()), generateStructures, hardcore, type), name); + } + worlddata.checkName(name); // CraftBukkit - Migration did not rewrite the level.dat; This forces 1.8 to take the last loaded world as respawn (in this case the end) + WorldServer internal = (WorldServer) new WorldServer(console, sdm, worlddata, dimension, console.methodProfiler, creator.environment(), generator).b(); if (!(worlds.containsKey(name.toLowerCase()))) { return null; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index f20a0406..83efd6ae 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -82,7 +82,7 @@ public class CraftWorld implements World { } public Block getBlockAt(int x, int y, int z) { - return getChunkAt(x >> 4, z >> 4).getBlock(x & 0xF, y & 0xFF, z & 0xF); + return getChunkAt(x >> 4, z >> 4).getBlock(x & 0xF, y, z & 0xF); } public int getBlockTypeIdAt(int x, int y, int z) { diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java index 5fadeffc..de358572 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -121,7 +121,8 @@ public class CraftBlock implements Block { } public boolean setTypeId(final int type, final boolean applyPhysics) { - return setTypeIdAndData(type, getData(), applyPhysics); + net.minecraft.server.Block block = getNMSBlock(type); + return setTypeIdAndData(type, (byte) block.toLegacyData(block.getBlockData()), applyPhysics); } public boolean setTypeIdAndData(final int type, final byte data, final boolean applyPhysics) { diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java index 9fb32a82..bf6841c9 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java @@ -140,14 +140,12 @@ public class CraftBlockState implements BlockState { Block block = getBlock(); if (block.getType() != getType()) { - if (force) { - block.setTypeId(getTypeId(), applyPhysics); - } else { + if (!force) { return false; } } - block.setData(getRawData(), applyPhysics); + block.setTypeIdAndData(getTypeId(), getRawData(), applyPhysics); world.getHandle().notify(new BlockPosition(x, y, z)); return true; diff --git a/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java b/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java index c2d4c2e4..26ea0d3a 100644 --- a/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java +++ b/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java @@ -45,7 +45,7 @@ class ChunkIOProvider implements AsynchronousExecutor.CallBackProvider<QueuedChu Server server = queuedChunk.provider.world.getServer(); if (server != null) { - server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(chunk.bukkitChunk, false)); + server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(chunk.bukkitChunk, false)); } // Update neighbor counts diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java index e69f417b..f045e1c7 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -219,6 +219,20 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { openCustomInventory(inventory, player, "minecraft:hopper"); } break; + case BEACON: + if (craftinv.getInventory() instanceof TileEntityBeacon) { + getHandle().openTileEntity((TileEntityBeacon) craftinv.getInventory()); + } else { + openCustomInventory(inventory, player, "minecraft:beacon"); + } + break; + case ANVIL: + if (craftinv.getInventory() instanceof TileEntityContainerAnvil) { + getHandle().openTileEntity((TileEntityContainerAnvil) craftinv.getInventory()); + } else { + openCustomInventory(inventory, player, "minecraft:anvil"); + } + break; case CREATIVE: case CRAFTING: throw new IllegalArgumentException("Can't open a " + type + " inventory!"); @@ -240,6 +254,14 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { String title = container.getBukkitView().getTitle(); int size = container.getBukkitView().getTopInventory().getSize(); + // Special cases + if (windowType.equals("minecraft:crafting_table") + || windowType.equals("minecraft:anvil") + || windowType.equals("minecraft:enchanting_table") + ) { + size = 0; + } + player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title), size)); getHandle().activeContainer = container; getHandle().activeContainer.addSlotListener(player); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java index 3f4e1ae6..82370939 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java @@ -52,11 +52,19 @@ public class CraftItemFrame extends CraftHanging implements ItemFrame { case 0: return Rotation.NONE; case 1: - return Rotation.CLOCKWISE; + return Rotation.CLOCKWISE_45; case 2: - return Rotation.FLIPPED; + return Rotation.CLOCKWISE; case 3: + return Rotation.CLOCKWISE_135; + case 4: + return Rotation.FLIPPED; + case 5: + return Rotation.FLIPPED_45; + case 6: return Rotation.COUNTER_CLOCKWISE; + case 7: + return Rotation.COUNTER_CLOCKWISE_45; default: throw new AssertionError("Unknown rotation " + value + " for " + getHandle()); } @@ -72,12 +80,20 @@ public class CraftItemFrame extends CraftHanging implements ItemFrame { switch (rotation) { case NONE: return 0; - case CLOCKWISE: + case CLOCKWISE_45: return 1; - case FLIPPED: + case CLOCKWISE: return 2; - case COUNTER_CLOCKWISE: + case CLOCKWISE_135: return 3; + case FLIPPED: + return 4; + case FLIPPED_45: + return 5; + case COUNTER_CLOCKWISE: + return 6; + case COUNTER_CLOCKWISE_45: + return 7; default: throw new IllegalArgumentException(rotation + " is not applicable to an ItemFrame"); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index 286a58c2..3b9bfecc 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -176,7 +176,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public String getPlayerListName() { - return CraftChatMessage.fromComponent(getHandle().listName); + return getHandle().listName == null ? getName() : CraftChatMessage.fromComponent(getHandle().listName); } @Override @@ -899,12 +899,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { EntityTracker tracker = ((WorldServer) entity.world).tracker; EntityPlayer other = ((CraftPlayer) player).getHandle(); + + getHandle().playerConnection.sendPacket(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER, other)); + EntityTrackerEntry entry = (EntityTrackerEntry) tracker.trackedEntities.get(other.getId()); if (entry != null && !entry.trackedPlayers.contains(getHandle())) { entry.updatePlayer(getHandle()); } - - getHandle().playerConnection.sendPacket(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER, other)); } public void removeDisconnectingPlayer(Player player) { diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java index b49c2dca..59be14b7 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java @@ -20,6 +20,10 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import com.google.common.collect.ImmutableMap; +import net.minecraft.server.ChatSerializer; +import net.minecraft.server.Items; +import net.minecraft.server.NBTTagString; +import org.bukkit.craftbukkit.util.CraftChatMessage; @DelegateDeserialization(ItemStack.class) public final class CraftItemStack extends ItemStack { @@ -374,6 +378,42 @@ public final class CraftItemStack extends ItemStack { item.setTag(tag); ((CraftMetaItem) itemMeta).applyToItem(tag); + + // Hacky fix for books + // TODO: Not use a hacky fix for books + if (tag.getBoolean(CraftMetaBook.RESOLVED.NBT) && item.getItem() == Items.WRITABLE_BOOK) { + if (tag.hasKey(CraftMetaBook.BOOK_PAGES.NBT)) { + NBTTagList pages = tag.getList(CraftMetaBook.BOOK_PAGES.NBT, 8); + + for (int i = 0; i < pages.size(); i++) { + String page = pages.getString(i); + page = CraftChatMessage.fromComponent(ChatSerializer.a(page)); + pages.a(i, new NBTTagString(page)); + } + tag.set(CraftMetaBook.BOOK_PAGES.NBT, pages); + } + tag.setBoolean(CraftMetaBook.RESOLVED.NBT, false); + } else if (!tag.getBoolean(CraftMetaBook.RESOLVED.NBT) && item.getItem() == Items.WRITTEN_BOOK) { + if (tag.hasKey(CraftMetaBook.BOOK_PAGES.NBT)) { + NBTTagList pages = tag.getList(CraftMetaBook.BOOK_PAGES.NBT, 8); + + for (int i = 0; i < pages.size(); i++) { + String page = pages.getString(i); + page = ChatSerializer.a(CraftChatMessage.fromString(page, true)[0]); + pages.a(i, new NBTTagString(page)); + } + tag.set(CraftMetaBook.BOOK_PAGES.NBT, pages); + } + + tag.setBoolean(CraftMetaBook.RESOLVED.NBT, true); + if (!tag.hasKey(CraftMetaBook.BOOK_TITLE.NBT)) { + tag.setString(CraftMetaBook.BOOK_TITLE.NBT, ""); + } + if (!tag.hasKey(CraftMetaBook.BOOK_AUTHOR.NBT)) { + tag.setString(CraftMetaBook.BOOK_AUTHOR.NBT, ""); + } + } + return true; } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java index d61615bf..713d70cd 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java @@ -145,8 +145,13 @@ public class CraftMetaBanner extends CraftMetaItem implements BannerMeta { ImmutableMap.Builder<String, Object> serialize(ImmutableMap.Builder<String, Object> builder) { super.serialize(builder); - builder.put(BASE.BUKKIT, base); - builder.put(PATTERNS.BUKKIT, ImmutableList.copyOf(patterns)); + if(base != null){ + builder.put(BASE.BUKKIT, base); + } + + if(!patterns.isEmpty()){ + builder.put(PATTERNS.BUKKIT, ImmutableList.copyOf(patterns)); + } return builder; } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java index c9738c4f..1f7b5239 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java @@ -96,6 +96,7 @@ class CraftMetaItem implements ItemMeta, Repairable { static { classMap = ImmutableMap.<Class<? extends CraftMetaItem>, String>builder() + .put(CraftMetaBanner.class, "BANNER") .put(CraftMetaBook.class, "BOOK") .put(CraftMetaSkull.class, "SKULL") .put(CraftMetaLeatherArmor.class, "LEATHER_ARMOR") |