From 9cd3c96727e5250750fb7bfc6ab5e241874df301 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 2 Mar 2013 13:34:17 +1100 Subject: [PATCH] Snapshot support. --- src/main/java/net/minecraft/server/Container.java | 420 ++++++++++++++------- src/main/java/net/minecraft/server/ItemStack.java | 1 + .../java/net/minecraft/server/MinecraftServer.java | 2 +- .../net/minecraft/server/Packet100OpenWindow.java | 46 +++ .../net/minecraft/server/PendingConnection.java | 6 +- src/main/java/org/bukkit/craftbukkit/Spigot.java | 8 + src/main/resources/configurations/bukkit.yml | 2 + 7 files changed, 354 insertions(+), 131 deletions(-) create mode 100644 src/main/java/net/minecraft/server/Packet100OpenWindow.java diff --git a/src/main/java/net/minecraft/server/Container.java b/src/main/java/net/minecraft/server/Container.java index 9ecefea..09ee088 100644 --- a/src/main/java/net/minecraft/server/Container.java +++ b/src/main/java/net/minecraft/server/Container.java @@ -2,6 +2,7 @@ package net.minecraft.server; import java.util.ArrayList; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Set; @@ -16,9 +17,11 @@ public abstract class Container { public List c = new ArrayList(); public int windowId = 0; private short a = 0; + private int f = -1; + private int g = 0; + private final Set h = new HashSet(); protected List listeners = new ArrayList(); - private Set f = new HashSet(); - + private Set i = new HashSet(); // CraftBukkit start public boolean checkReachable = true; public abstract InventoryView getBukkitView(); @@ -105,168 +108,264 @@ public abstract class Container { public ItemStack clickItem(int i, int j, int k, EntityHuman entityhuman) { ItemStack itemstack = null; PlayerInventory playerinventory = entityhuman.inventory; - Slot slot; - ItemStack itemstack1; int l; - ItemStack itemstack2; - - if ((k == 0 || k == 1) && (j == 0 || j == 1)) { - if (i == -999) { - if (playerinventory.getCarried() != null && i == -999) { - if (j == 0) { - entityhuman.drop(playerinventory.getCarried()); - playerinventory.setCarried((ItemStack) null); - } + ItemStack itemstack1; - if (j == 1) { - // CraftBukkit start - store a reference - ItemStack itemstack3 = playerinventory.getCarried(); - if (itemstack3.count > 0) { - entityhuman.drop(itemstack3.a(1)); - } + if (k == 5) { + int i1 = this.g; + + this.g = c(j); + if ((i1 != 1 || this.g != 2) && i1 != this.g) { + this.d(); + } else if (playerinventory.getCarried() == null) { + this.d(); + } else if (this.g == 0) { + this.f = b(j); + if (d(this.f)) { + this.g = 1; + this.h.clear(); + } else { + this.d(); + } + } else if (this.g == 1) { + Slot slot = (Slot) this.c.get(i); - if (itemstack3.count == 0) { - // CraftBukkit end - playerinventory.setCarried((ItemStack) null); - } - } + if (slot != null && a(slot, playerinventory.getCarried(), true) && slot.isAllowed(playerinventory.getCarried()) && playerinventory.getCarried().count > this.h.size() && this.b(slot)) { + this.h.add(slot); } - } else if (k == 1) { - slot = (Slot) this.c.get(i); - if (slot != null && slot.a(entityhuman)) { - itemstack1 = this.b(entityhuman, i); - if (itemstack1 != null) { - int i1 = itemstack1.id; - - itemstack = itemstack1.cloneItemStack(); - if (slot != null && slot.getItem() != null && slot.getItem().id == i1) { - this.a(i, j, true, entityhuman); + } else if (this.g == 2) { + if (!this.h.isEmpty()) { + itemstack1 = playerinventory.getCarried().cloneItemStack(); + l = playerinventory.getCarried().count; + Iterator iterator = this.h.iterator(); + + while (iterator.hasNext()) { + Slot slot1 = (Slot) iterator.next(); + + if (slot1 != null && a(slot1, playerinventory.getCarried(), true) && slot1.isAllowed(playerinventory.getCarried()) && playerinventory.getCarried().count >= this.h.size() && this.b(slot1)) { + ItemStack itemstack2 = itemstack1.cloneItemStack(); + int j1 = slot1.d() ? slot1.getItem().count : 0; + + a(this.h, this.f, itemstack2, j1); + if (itemstack2.count > itemstack2.getMaxStackSize()) { + itemstack2.count = itemstack2.getMaxStackSize(); + } + + if (itemstack2.count > slot1.a()) { + itemstack2.count = slot1.a(); + } + + l -= itemstack2.count - j1; + slot1.set(itemstack2); } } - } - } else { - if (i < 0) { - return null; - } - - slot = (Slot) this.c.get(i); - if (slot != null) { - itemstack1 = slot.getItem(); - ItemStack itemstack3 = playerinventory.getCarried(); - if (itemstack1 != null) { - itemstack = itemstack1.cloneItemStack(); + itemstack1.count = l; + if (itemstack1.count <= 0) { + itemstack1 = null; } - if (itemstack1 == null) { - if (itemstack3 != null && slot.isAllowed(itemstack3)) { - l = j == 0 ? itemstack3.count : 1; - if (l > slot.a()) { - l = slot.a(); - } + playerinventory.setCarried(itemstack1); + } - // CraftBukkit start - if (itemstack3.count >= l) { - slot.set(itemstack3.a(l)); - } - // CraftBukkit end + this.d(); + } else { + this.d(); + } + } else if (this.g != 0) { + this.d(); + } else { + Slot slot2; + int k1; + ItemStack itemstack3; + + if ((k == 0 || k == 1) && (j == 0 || j == 1)) { + if (i == -999) { + if (playerinventory.getCarried() != null && i == -999) { + if (j == 0) { + entityhuman.drop(playerinventory.getCarried()); + playerinventory.setCarried((ItemStack) null); + } - if (itemstack3.count == 0) { + if (j == 1) { + entityhuman.drop(playerinventory.getCarried().a(1)); + if (playerinventory.getCarried().count == 0) { playerinventory.setCarried((ItemStack) null); } } - } else if (slot.a(entityhuman)) { - if (itemstack3 == null) { - l = j == 0 ? itemstack1.count : (itemstack1.count + 1) / 2; - itemstack2 = slot.a(l); - playerinventory.setCarried(itemstack2); - if (itemstack1.count == 0) { - slot.set((ItemStack) null); + } + } else if (k == 1) { + if (i < 0) { + return null; + } + + slot2 = (Slot) this.c.get(i); + if (slot2 != null && slot2.a(entityhuman)) { + itemstack1 = this.b(entityhuman, i); + if (itemstack1 != null) { + l = itemstack1.id; + itemstack = itemstack1.cloneItemStack(); + if (slot2 != null && slot2.getItem() != null && slot2.getItem().id == l) { + this.a(i, j, true, entityhuman); } + } + } + } else { + if (i < 0) { + return null; + } - slot.a(entityhuman, playerinventory.getCarried()); - } else if (slot.isAllowed(itemstack3)) { - if (itemstack1.id == itemstack3.id && itemstack1.getData() == itemstack3.getData() && ItemStack.equals(itemstack1, itemstack3)) { - l = j == 0 ? itemstack3.count : 1; - if (l > slot.a() - itemstack1.count) { - l = slot.a() - itemstack1.count; - } + slot2 = (Slot) this.c.get(i); + if (slot2 != null) { + itemstack1 = slot2.getItem(); + ItemStack itemstack4 = playerinventory.getCarried(); + + if (itemstack1 != null) { + itemstack = itemstack1.cloneItemStack(); + } - if (l > itemstack3.getMaxStackSize() - itemstack1.count) { - l = itemstack3.getMaxStackSize() - itemstack1.count; + if (itemstack1 == null) { + if (itemstack4 != null && slot2.isAllowed(itemstack4)) { + k1 = j == 0 ? itemstack4.count : 1; + if (k1 > slot2.a()) { + k1 = slot2.a(); } - itemstack3.a(l); - if (itemstack3.count == 0) { + slot2.set(itemstack4.a(k1)); + if (itemstack4.count == 0) { playerinventory.setCarried((ItemStack) null); } - - itemstack1.count += l; - } else if (itemstack3.count <= slot.a()) { - slot.set(itemstack3); - playerinventory.setCarried(itemstack1); } - } else if (itemstack1.id == itemstack3.id && itemstack3.getMaxStackSize() > 1 && (!itemstack1.usesData() || itemstack1.getData() == itemstack3.getData()) && ItemStack.equals(itemstack1, itemstack3)) { - l = itemstack1.count; - if (l > 0 && l + itemstack3.count <= itemstack3.getMaxStackSize()) { - itemstack3.count += l; - itemstack1 = slot.a(l); + } else if (slot2.a(entityhuman)) { + if (itemstack4 == null) { + k1 = j == 0 ? itemstack1.count : (itemstack1.count + 1) / 2; + itemstack3 = slot2.a(k1); + playerinventory.setCarried(itemstack3); if (itemstack1.count == 0) { - slot.set((ItemStack) null); + slot2.set((ItemStack) null); } - slot.a(entityhuman, playerinventory.getCarried()); + slot2.a(entityhuman, playerinventory.getCarried()); + } else if (slot2.isAllowed(itemstack4)) { + if (itemstack1.id == itemstack4.id && itemstack1.getData() == itemstack4.getData() && ItemStack.equals(itemstack1, itemstack4)) { + k1 = j == 0 ? itemstack4.count : 1; + if (k1 > slot2.a() - itemstack1.count) { + k1 = slot2.a() - itemstack1.count; + } + + if (k1 > itemstack4.getMaxStackSize() - itemstack1.count) { + k1 = itemstack4.getMaxStackSize() - itemstack1.count; + } + + itemstack4.a(k1); + if (itemstack4.count == 0) { + playerinventory.setCarried((ItemStack) null); + } + + itemstack1.count += k1; + } else if (itemstack4.count <= slot2.a()) { + slot2.set(itemstack4); + playerinventory.setCarried(itemstack1); + } + } else if (itemstack1.id == itemstack4.id && itemstack4.getMaxStackSize() > 1 && (!itemstack1.usesData() || itemstack1.getData() == itemstack4.getData()) && ItemStack.equals(itemstack1, itemstack4)) { + k1 = itemstack1.count; + if (k1 > 0 && k1 + itemstack4.count <= itemstack4.getMaxStackSize()) { + itemstack4.count += k1; + itemstack1 = slot2.a(k1); + if (itemstack1.count == 0) { + slot2.set((ItemStack) null); + } + + slot2.a(entityhuman, playerinventory.getCarried()); + } } } + + slot2.e(); + } + } + } else if (k == 2 && j >= 0 && j < 9) { + slot2 = (Slot) this.c.get(i); + if (slot2.a(entityhuman)) { + itemstack1 = playerinventory.getItem(j); + boolean flag = itemstack1 == null || slot2.inventory == playerinventory && slot2.isAllowed(itemstack1); + + k1 = -1; + if (!flag) { + k1 = playerinventory.i(); + flag |= k1 > -1; } - slot.e(); + if (slot2.d() && flag) { + itemstack3 = slot2.getItem(); + playerinventory.setItem(j, itemstack3); + if ((slot2.inventory != playerinventory || !slot2.isAllowed(itemstack1)) && itemstack1 != null) { + if (k1 > -1) { + playerinventory.pickup(itemstack1); + slot2.a(itemstack3.count); + slot2.set((ItemStack) null); + slot2.a(entityhuman, itemstack3); + } + } else { + slot2.a(itemstack3.count); + slot2.set(itemstack1); + slot2.a(entityhuman, itemstack3); + } + } else if (!slot2.d() && itemstack1 != null && slot2.isAllowed(itemstack1)) { + playerinventory.setItem(j, (ItemStack) null); + slot2.set(itemstack1); + } } - } - } else if (k == 2 && j >= 0 && j < 9) { - slot = (Slot) this.c.get(i); - if (slot.a(entityhuman)) { - itemstack1 = playerinventory.getItem(j); - boolean flag = itemstack1 == null || slot.inventory == playerinventory && slot.isAllowed(itemstack1); - - l = -1; - if (!flag) { - l = playerinventory.i(); - flag |= l > -1; + } else if (k == 3 && entityhuman.abilities.canInstantlyBuild && playerinventory.getCarried() == null && i >= 0) { + slot2 = (Slot) this.c.get(i); + if (slot2 != null && slot2.d()) { + itemstack1 = slot2.getItem().cloneItemStack(); + itemstack1.count = itemstack1.getMaxStackSize(); + playerinventory.setCarried(itemstack1); } - - if (slot.d() && flag) { - itemstack2 = slot.getItem(); - playerinventory.setItem(j, itemstack2); - if ((slot.inventory != playerinventory || !slot.isAllowed(itemstack1)) && itemstack1 != null) { - if (l > -1) { - playerinventory.pickup(itemstack1); - slot.a(itemstack2.count); - slot.set((ItemStack) null); - slot.a(entityhuman, itemstack2); + } else if (k == 4 && playerinventory.getCarried() == null && i >= 0) { + slot2 = (Slot) this.c.get(i); + if (slot2 != null && slot2.d()) { + itemstack1 = slot2.a(j == 0 ? 1 : slot2.getItem().count); + slot2.a(entityhuman, itemstack1); + entityhuman.drop(itemstack1); + } + } else if (k == 6 && i >= 0) { + slot2 = (Slot) this.c.get(i); + itemstack1 = playerinventory.getCarried(); + if (itemstack1 != null && (slot2 == null || !slot2.d() || !slot2.a(entityhuman))) { + l = j == 0 ? 0 : this.c.size() - 1; + k1 = j == 0 ? 1 : -1; + + for (int l1 = 0; l1 < 2; ++l1) { + for (int i2 = l; i2 >= 0 && i2 < this.c.size() && itemstack1.count < itemstack1.getMaxStackSize(); i2 += k1) { + Slot slot3 = (Slot) this.c.get(i2); + + if (slot3.d() && a(slot3, itemstack1, true) && slot3.a(entityhuman) && this.a(itemstack1, slot3) && (l1 != 0 || slot3.getItem().count != slot3.getItem().getMaxStackSize())) { + int j2 = Math.min(itemstack1.getMaxStackSize() - itemstack1.count, slot3.getItem().count); + ItemStack itemstack5 = slot3.a(j2); + + itemstack1.count += j2; + if (itemstack5.count <= 0) { + slot3.set((ItemStack) null); + slot3.a(entityhuman, itemstack5); + } + } } - } else { - slot.a(itemstack2.count); - slot.set(itemstack1); - slot.a(entityhuman, itemstack2); } - } else if (!slot.d() && itemstack1 != null && slot.isAllowed(itemstack1)) { - playerinventory.setItem(j, (ItemStack) null); - slot.set(itemstack1); } - } - } else if (k == 3 && entityhuman.abilities.canInstantlyBuild && playerinventory.getCarried() == null && i >= 0) { - slot = (Slot) this.c.get(i); - if (slot != null && slot.d()) { - itemstack1 = slot.getItem().cloneItemStack(); - itemstack1.count = itemstack1.getMaxStackSize(); - playerinventory.setCarried(itemstack1); + + this.b(); } } return itemstack; } + public boolean a(ItemStack itemstack, Slot slot) { + return true; + } + protected void a(int i, int j, boolean flag, EntityHuman entityhuman) { this.clickItem(i, j, 1, entityhuman); } @@ -289,14 +388,14 @@ public abstract class Container { } public boolean c(EntityHuman entityhuman) { - return !this.f.contains(entityhuman); + return !this.i.contains(entityhuman); } public void a(EntityHuman entityhuman, boolean flag) { if (flag) { - this.f.remove(entityhuman); + this.i.remove(entityhuman); } else { - this.f.add(entityhuman); + this.i.add(entityhuman); } } @@ -369,4 +468,71 @@ public abstract class Container { return flag1; } + + public static int b(int i) { + return i >> 2 & 3; + } + + public static int c(int i) { + return i & 3; + } + + public static boolean d(int i) { + return i == 0 || i == 1; + } + + protected void d() { + this.g = 0; + this.h.clear(); + } + + public static boolean a(Slot slot, ItemStack itemstack, boolean flag) { + boolean flag1 = slot == null || !slot.d(); + + if (slot != null && slot.d() && itemstack != null && itemstack.doMaterialsMatch(slot.getItem()) && ItemStack.equals(slot.getItem(), itemstack)) { + int i = flag ? 0 : itemstack.count; + + flag1 |= slot.getItem().count + i <= itemstack.getMaxStackSize(); + } + + return flag1; + } + + public static void a(Set set, int i, ItemStack itemstack, int j) { + switch (i) { + case 0: + itemstack.count = MathHelper.d((float) itemstack.count / (float) set.size()); + break; + + case 1: + itemstack.count = 1; + } + + itemstack.count += j; + } + + public boolean b(Slot slot) { + return true; + } + + public static int b(IInventory iinventory) { + if (iinventory == null) { + return 0; + } else { + int i = 0; + float f = 0.0F; + + for (int j = 0; j < iinventory.getSize(); ++j) { + ItemStack itemstack = iinventory.getItem(j); + + if (itemstack != null) { + f += (float) itemstack.count / (float) Math.min(iinventory.getMaxStackSize(), itemstack.getMaxStackSize()); + ++i; + } + } + + f /= (float) iinventory.getSize(); + return MathHelper.d(f * 14.0F) + (i > 0 ? 1 : 0); + } + } } diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java index 8f0a5ad..3043db9 100644 --- a/src/main/java/net/minecraft/server/ItemStack.java +++ b/src/main/java/net/minecraft/server/ItemStack.java @@ -38,6 +38,7 @@ public final class ItemStack { this.f = null; this.id = i; this.count = j; + if (org.bukkit.craftbukkit.Spigot.snapshotSupport && this.id >= 146 && this.id <= 158) this.id = 0; // Spigot this.setData(k); // CraftBukkit } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 6005fac..79b4369 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -765,7 +765,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo } public String getVersion() { - return "1.4.7"; + return (org.bukkit.craftbukkit.Spigot.snapshotSupport) ? org.bukkit.craftbukkit.Spigot.snapshotVersion : "1.4.7"; } public int y() { diff --git a/src/main/java/net/minecraft/server/Packet100OpenWindow.java b/src/main/java/net/minecraft/server/Packet100OpenWindow.java new file mode 100644 index 0000000..5182bfa --- /dev/null +++ b/src/main/java/net/minecraft/server/Packet100OpenWindow.java @@ -0,0 +1,46 @@ +package net.minecraft.server; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet100OpenWindow extends Packet { + + public int a; + public int b; + public String c; + public int d; + + public Packet100OpenWindow() {} + + public Packet100OpenWindow(int i, int j, String s, int k) { + this.a = i; + this.b = j; + this.c = s; + this.d = k; + } + + public void handle(Connection connection) { + connection.a(this); + } + + public void a(DataInputStream datainputstream) throws IOException { + this.a = datainputstream.readByte() & 255; + this.b = datainputstream.readByte() & 255; + this.c = a(datainputstream, 32); + this.d = datainputstream.readByte() & 255; + if (org.bukkit.craftbukkit.Spigot.snapshotSupport) datainputstream.readBoolean(); // Spigot + } + + public void a(DataOutputStream dataoutputstream) throws IOException { + dataoutputstream.writeByte(this.a & 255); + dataoutputstream.writeByte(this.b & 255); + a(this.c, dataoutputstream); + dataoutputstream.writeByte(this.d & 255); + if (org.bukkit.craftbukkit.Spigot.snapshotSupport) dataoutputstream.writeBoolean(false); // Spigot + } + + public int a() { + return 3 + this.c.length(); + } +} diff --git a/src/main/java/net/minecraft/server/PendingConnection.java b/src/main/java/net/minecraft/server/PendingConnection.java index cdd456f..08aa314 100644 --- a/src/main/java/net/minecraft/server/PendingConnection.java +++ b/src/main/java/net/minecraft/server/PendingConnection.java @@ -78,8 +78,8 @@ public class PendingConnection extends Connection { } else { PublicKey publickey = this.server.F().getPublic(); - if (packet2handshake.d() != 51) { - if (packet2handshake.d() > 51) { + if (packet2handshake.d() != ((org.bukkit.craftbukkit.Spigot.snapshotSupport) ? org.bukkit.craftbukkit.Spigot.snapshotProtocolVersion : 51)) { + if (packet2handshake.d() > ((org.bukkit.craftbukkit.Spigot.snapshotSupport) ? org.bukkit.craftbukkit.Spigot.snapshotProtocolVersion : 51)) { this.disconnect("Outdated server!"); } else { this.disconnect("Outdated client!"); @@ -154,7 +154,7 @@ public class PendingConnection extends Connection { if (true) { // CraftBukkit start - fix decompile issues, don't create a list from an array - Object[] list = new Object[] { 1, 51, this.server.getVersion(), pingEvent.getMotd(), playerlist.getPlayerCount(), pingEvent.getMaxPlayers() }; + Object[] list = new Object[] { 1, ((org.bukkit.craftbukkit.Spigot.snapshotSupport) ? org.bukkit.craftbukkit.Spigot.snapshotProtocolVersion : 51), this.server.getVersion(), pingEvent.getMotd(), playerlist.getPlayerCount(), pingEvent.getMaxPlayers() }; for (Object object : list) { if (s == null) { diff --git a/src/main/java/org/bukkit/craftbukkit/Spigot.java b/src/main/java/org/bukkit/craftbukkit/Spigot.java index 6713281..208bf02 100644 --- a/src/main/java/org/bukkit/craftbukkit/Spigot.java +++ b/src/main/java/org/bukkit/craftbukkit/Spigot.java @@ -23,6 +23,9 @@ public class Spigot { public static boolean tabPing = false; private static Metrics metrics; + public static boolean snapshotSupport; + public static int snapshotProtocolVersion = 60; + public static String snapshotVersion = "1.5"; public static void initialize(CraftServer server, SimpleCommandMap commandMap, YamlConfiguration configuration) { commandMap.register("bukkit", new org.bukkit.craftbukkit.command.TicksPerSecondCommand("tps")); @@ -60,6 +63,11 @@ public class Spigot { tabPing = configuration.getBoolean("settings.tab-ping", tabPing); + snapshotSupport = configuration.getBoolean("settings.snapshot-protocol", snapshotSupport); + if (snapshotSupport) { + server.getLogger().log(Level.INFO, "Enabled support for pre release / snapshot version {0}", snapshotVersion); + } + if (metrics == null) { try { metrics = new Metrics(); diff --git a/src/main/resources/configurations/bukkit.yml b/src/main/resources/configurations/bukkit.yml index aac1406..0351530 100644 --- a/src/main/resources/configurations/bukkit.yml +++ b/src/main/resources/configurations/bukkit.yml @@ -35,6 +35,8 @@ settings: timeout-time: 30 restart-on-crash: false restart-script-location: /path/to/server/start.sh + # fakes the latest pre release / snapshot + snapshot-protocol: false world-settings: default: growth-chunks-per-tick: 650 -- 1.8.1-rc2