summaryrefslogtreecommitdiffstats
path: root/nms-patches/PlayerConnection.patch
diff options
context:
space:
mode:
Diffstat (limited to 'nms-patches/PlayerConnection.patch')
-rw-r--r--nms-patches/PlayerConnection.patch1039
1 files changed, 568 insertions, 471 deletions
diff --git a/nms-patches/PlayerConnection.patch b/nms-patches/PlayerConnection.patch
index a1f3b528..019ef20b 100644
--- a/nms-patches/PlayerConnection.patch
+++ b/nms-patches/PlayerConnection.patch
@@ -1,14 +1,22 @@
--- a/net/minecraft/server/PlayerConnection.java
+++ b/net/minecraft/server/PlayerConnection.java
-@@ -19,6 +19,49 @@
+@@ -3,7 +3,6 @@
+ import com.google.common.collect.Lists;
+ import com.google.common.primitives.Doubles;
+ import com.google.common.primitives.Floats;
+-import com.google.common.util.concurrent.Futures;
+ import io.netty.buffer.Unpooled;
+ import io.netty.util.concurrent.Future;
+ import io.netty.util.concurrent.GenericFutureListener;
+@@ -18,6 +17,47 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+// CraftBukkit start
++import java.util.HashSet;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
-+import java.util.HashSet;
-+
++import org.bukkit.Location;
+import org.bukkit.craftbukkit.entity.CraftPlayer;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.craftbukkit.inventory.CraftInventoryView;
@@ -16,8 +24,6 @@
+import org.bukkit.craftbukkit.util.CraftChatMessage;
+import org.bukkit.craftbukkit.util.LazyPlayerSet;
+import org.bukkit.craftbukkit.util.Waitable;
-+
-+import org.bukkit.Location;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Event;
+import org.bukkit.event.block.Action;
@@ -32,8 +38,8 @@
+import org.bukkit.event.player.PlayerAnimationEvent;
+import org.bukkit.event.player.PlayerChatEvent;
+import org.bukkit.event.player.PlayerCommandPreprocessEvent;
-+import org.bukkit.event.player.PlayerInteractEntityEvent;
+import org.bukkit.event.player.PlayerInteractAtEntityEvent;
++import org.bukkit.event.player.PlayerInteractEntityEvent;
+import org.bukkit.event.player.PlayerItemHeldEvent;
+import org.bukkit.event.player.PlayerKickEvent;
+import org.bukkit.event.player.PlayerMoveEvent;
@@ -47,30 +53,31 @@
+import org.bukkit.util.NumberConversions;
+// CraftBukkit end
+
- public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerListBox {
+ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
- private static final Logger c = LogManager.getLogger();
-@@ -32,13 +75,17 @@
- private int i;
- private long j;
- private long k;
+ private static final Logger LOGGER = LogManager.getLogger();
+@@ -28,7 +68,10 @@
+ private int f;
+ private long g;
+ private long h;
- private int chatThrottle;
+ // CraftBukkit start - multithreaded fields
+ private volatile int chatThrottle;
+ private static final AtomicIntegerFieldUpdater chatSpamField = AtomicIntegerFieldUpdater.newUpdater(PlayerConnection.class, "chatThrottle");
+ // CraftBukkit end
- private int m;
- private IntHashMap<Short> n = new IntHashMap();
- private double o;
- private double p;
- private double q;
- private boolean checkMovement = true;
-+ private boolean processedDisconnect; // CraftBukkit - added
+ private int j;
+ private final IntHashMap<Short> k = new IntHashMap();
+ private double l;
+@@ -53,6 +96,7 @@
+ private int E;
+ private int F;
+ private int G;
++ private boolean processedDisconnect; // CraftBukkit - Added
public PlayerConnection(MinecraftServer minecraftserver, NetworkManager networkmanager, EntityPlayer entityplayer) {
this.minecraftServer = minecraftserver;
-@@ -46,7 +93,31 @@
- networkmanager.a((PacketListener) this);
+@@ -60,7 +104,32 @@
+ networkmanager.setPacketListener(this);
this.player = entityplayer;
entityplayer.playerConnection = this;
+
@@ -80,6 +87,7 @@
+
+ private final org.bukkit.craftbukkit.CraftServer server;
+ private int lastTick = MinecraftServer.currentTick;
++ private int allowedPlayerTicks = 1;
+ private int lastDropTick = MinecraftServer.currentTick;
+ private int dropCount = 0;
+ private static final int SURVIVAL_PLACE_DISTANCE_SQUARED = 6 * 6;
@@ -100,8 +108,8 @@
+ // CraftBukkit end
public void c() {
- this.h = false;
-@@ -60,15 +131,21 @@
+ this.d();
+@@ -112,15 +181,21 @@
}
this.minecraftServer.methodProfiler.b();
@@ -114,16 +122,16 @@
+ */
+ // CraftBukkit end
- if (this.m > 0) {
- --this.m;
+ if (this.j > 0) {
+ --this.j;
}
- if (this.player.D() > 0L && this.minecraftServer.getIdleTimeout() > 0 && MinecraftServer.az() - this.player.D() > (long) (this.minecraftServer.getIdleTimeout() * 1000 * 60)) {
+ if (this.player.I() > 0L && this.minecraftServer.getIdleTimeout() > 0 && MinecraftServer.av() - this.player.I() > (long) (this.minecraftServer.getIdleTimeout() * 1000 * 60)) {
+ this.player.resetIdleTimer(); // CraftBukkit - SPIGOT-854
this.disconnect("You have been idle for too long!");
}
-@@ -79,19 +156,37 @@
+@@ -140,19 +215,37 @@
}
public void disconnect(String s) {
@@ -145,54 +153,49 @@
+ // CraftBukkit end
final ChatComponentText chatcomponenttext = new ChatComponentText(s);
- this.networkManager.a(new PacketPlayOutKickDisconnect(chatcomponenttext), new GenericFutureListener() {
+ this.networkManager.sendPacket(new PacketPlayOutKickDisconnect(chatcomponenttext), new GenericFutureListener() {
- public void operationComplete(Future<? super Void> future) throws Exception {
-+ public void operationComplete(Future future) throws Exception { // CraftBukkit - fix decompile error
++ public void operationComplete(Future future) throws Exception { // CraftBukkit - decompile error
PlayerConnection.this.networkManager.close(chatcomponenttext);
}
}, new GenericFutureListener[0]);
+ this.a(chatcomponenttext); // CraftBukkit - fire quit instantly
- this.networkManager.k();
+ this.networkManager.stopReading();
- Futures.getUnchecked(this.minecraftServer.postToMainThread(new Runnable() {
-- public void run() {
-- PlayerConnection.this.networkManager.l();
+ // CraftBukkit - Don't wait
+ this.minecraftServer.postToMainThread(new Runnable() {
-+ public void run() {
-+ PlayerConnection.this.networkManager.l();
+ public void run() {
+ PlayerConnection.this.networkManager.handleDisconnection();
}
- }));
+ });
}
public void a(PacketPlayInSteerVehicle packetplayinsteervehicle) {
-@@ -126,8 +221,66 @@
- this.checkMovement = true;
- }
+@@ -229,6 +322,62 @@
+ return;
}
+
+ // CraftBukkit start - fire PlayerMoveEvent
+ Player player = this.getPlayer();
+ Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location.
+ Location to = player.getLocation().clone(); // Start off the To location as the Players current location.
+
+ // If the packet contains movement information then we update the To location with the correct XYZ.
-+ if (packetplayinflying.hasPos && !(packetplayinflying.hasPos && packetplayinflying.y == -999.0D)) {
-+ to.setX(packetplayinflying.x);
-+ to.setY(packetplayinflying.y);
-+ to.setZ(packetplayinflying.z);
-+ }
++ to.setX(packetplayinvehiclemove.getX());
++ to.setY(packetplayinvehiclemove.getY());
++ to.setZ(packetplayinvehiclemove.getZ());
++
+
+ // If the packet contains look information then we update the To location with the correct Yaw & Pitch.
-+ if (packetplayinflying.hasLook) {
-+ to.setYaw(packetplayinflying.yaw);
-+ to.setPitch(packetplayinflying.pitch);
-+ }
++ to.setYaw(packetplayinvehiclemove.getYaw());
++ to.setPitch(packetplayinvehiclemove.getPitch());
+
+ // Prevent 40 event-calls for less than a single pixel of movement >.>
+ double delta = Math.pow(this.lastPosX - to.getX(), 2) + Math.pow(this.lastPosY - to.getY(), 2) + Math.pow(this.lastPosZ - to.getZ(), 2);
+ float deltaAngle = Math.abs(this.lastYaw - to.getYaw()) + Math.abs(this.lastPitch - to.getPitch());
+
-+ if ((delta > 1f / 256 || deltaAngle > 10f) && (this.checkMovement && !this.player.dead)) {
++ if ((delta > 1f / 256 || deltaAngle > 10f) && !this.player.dead) {
+ this.lastPosX = to.getX();
+ this.lastPosY = to.getY();
+ this.lastPosZ = to.getZ();
@@ -207,75 +210,159 @@
+
+ // 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(), from.getZ(), from.getYaw(), from.getPitch(), Collections.<PacketPlayOutPosition.EnumPlayerTeleportFlags>emptySet()));
++ this.player.playerConnection.sendPacket(new PacketPlayOutPosition(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch(), Collections.<PacketPlayOutPosition.EnumPlayerTeleportFlags>emptySet(), this.teleportAwait));
+ return;
+ }
-
-- if (this.checkMovement) {
-+ /* If a Plugin has changed the To destination then we teleport the Player
-+ there to avoid any 'Moved wrongly' or 'Moved too quickly' errors.
-+ We only do this if the Event was not cancelled. */
++
++ // If a Plugin has changed the To destination then we teleport the Player
++ // there to avoid any 'Moved wrongly' or 'Moved too quickly' errors.
++ // We only do this if the Event was not cancelled.
+ if (!oldTo.equals(event.getTo()) && !event.isCancelled()) {
+ this.player.getBukkitEntity().teleport(event.getTo(), PlayerTeleportEvent.TeleportCause.UNKNOWN);
+ return;
+ }
+
-+ /* Check to see if the Players Location has some how changed during the call of the event.
-+ This can happen due to a plugin teleporting the player instead of using .setTo() */
++ // Check to see if the Players Location has some how changed during the call of the event.
++ // This can happen due to a plugin teleporting the player instead of using .setTo()
+ if (!from.equals(this.getPlayer().getLocation()) && this.justTeleported) {
+ this.justTeleported = false;
+ return;
+ }
+ }
+ }
++ // CraftBukkit end
+
-+ if (this.checkMovement && !this.player.dead) {
-+ // CraftBukkit end
- this.f = this.e;
- double d7;
- double d8;
-@@ -155,6 +308,7 @@
-
+ this.minecraftServer.getPlayerList().d(this.player);
+ this.player.checkMovement(this.player.locX - d0, this.player.locY - d1, this.player.locZ - d2);
+ this.D = d11 >= -0.03125D && !this.minecraftServer.getAllowFlight() && !worldserver.d(entity.getBoundingBox().g(0.0625D).a(0.0D, -0.55D, 0.0D));
+@@ -273,12 +422,13 @@
+ this.A = this.e;
+ this.a(this.teleportPos.x, this.teleportPos.y, this.teleportPos.z, this.player.yaw, this.player.pitch);
+ }
+-
++ this.allowedPlayerTicks = 20; // CraftBukkit
+ } else {
+ this.A = this.e;
+ if (this.player.isPassenger()) {
+ this.player.setLocation(this.player.locX, this.player.locY, this.player.locZ, packetplayinflying.a(this.player.yaw), packetplayinflying.b(this.player.pitch));
this.minecraftServer.getPlayerList().d(this.player);
- if (this.player.vehicle != null) {
-+ this.player.vehicle.ai = true; // CraftBukkit - moved from below
- if (d3 > 4.0D) {
- Entity entity = this.player.vehicle;
++ this.allowedPlayerTicks = 20; // CraftBukkit
+ } else {
+ double d0 = this.player.locX;
+ double d1 = this.player.locY;
+@@ -298,15 +448,32 @@
+ ++this.F;
+ int i = this.F - this.G;
+
+- if (i > 5) {
++ // CraftBukkit start - handle custom speeds and skipped ticks
++ this.allowedPlayerTicks += (System.currentTimeMillis() / 50) - this.lastTick;
++ this.allowedPlayerTicks = Math.max(this.allowedPlayerTicks, 1);
++ this.lastTick = (int) (System.currentTimeMillis() / 50);
++
++ if (i > Math.max(this.allowedPlayerTicks, 5)) {
+ PlayerConnection.LOGGER.debug(this.player.getName() + " is sending move packets too frequently (" + i + " packets since last tick)");
+ i = 1;
+ }
-@@ -162,7 +316,7 @@
++ if (packetplayinflying.hasLook || d11 > 0) {
++ allowedPlayerTicks -= 1;
++ } else {
++ allowedPlayerTicks = 20;
++ }
++ float speed;
++ if (player.abilities.isFlying) {
++ speed = player.abilities.flySpeed * 20f;
++ } else {
++ speed = player.abilities.walkSpeed * 10f;
++ }
++
+ if (!this.player.K() && (!this.player.x().getGameRules().getBoolean("disableElytraMovementCheck") || !this.player.cB())) {
+ float f2 = this.player.cB() ? 300.0F : 100.0F;
+
+- if (d11 - d10 > (double) (f2 * (float) i) && (!this.minecraftServer.R() || !this.minecraftServer.Q().equals(this.player.getName()))) {
++ if (d11 - d10 > Math.pow((double) (10.0F * (float) i * speed), 2) && (!this.minecraftServer.R() || !this.minecraftServer.Q().equals(this.player.getName()))) {
+ PlayerConnection.LOGGER.warn(this.player.getName() + " moved too quickly! " + d7 + "," + d8 + "," + d9);
this.a(this.player.locX, this.player.locY, this.player.locZ, this.player.yaw, this.player.pitch);
+ return;
+@@ -352,6 +519,65 @@
}
-
-- this.player.vehicle.ai = true;
-+ // this.player.vehicle.ai = true; // CraftBukkit - moved up
}
- if (this.checkMovement) {
-@@ -224,7 +378,7 @@
- double d14 = this.player.motX * this.player.motX + this.player.motY * this.player.motY + this.player.motZ * this.player.motZ;
- double d15 = d11 * d11 + d12 * d12 + d13 * d13;
-
-- if (d15 - d14 > 100.0D && (!this.minecraftServer.T() || !this.minecraftServer.S().equals(this.player.getName()))) {
-+ if (d15 - d14 > 100.0D && this.checkMovement && (!this.minecraftServer.T() || !this.minecraftServer.S().equals(this.player.getName()))) { // CraftBukkit - Added this.checkMovement condition to solve this check being triggered by teleports
- PlayerConnection.c.warn(this.player.getName() + " moved too quickly! " + d11 + "," + d12 + "," + d13 + " (" + d11 + ", " + d12 + ", " + d13 + ")");
- this.a(this.o, this.p, this.q, this.player.yaw, this.player.pitch);
- return;
-@@ -288,16 +442,73 @@
- } else if (this.e - this.f > 20) {
- this.a(this.o, this.p, this.q, this.player.yaw, this.player.pitch);
- }
--
- }
++ // CraftBukkit start - fire PlayerMoveEvent
++ Player player = this.getPlayer();
++ Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location.
++ Location to = player.getLocation().clone(); // Start off the To location as the Players current location.
+
- }
++ // If the packet contains movement information then we update the To location with the correct XYZ.
++ if (packetplayinflying.hasPos) {
++ to.setX(packetplayinflying.x);
++ to.setY(packetplayinflying.y);
++ to.setZ(packetplayinflying.z);
++ }
++
++ // If the packet contains look information then we update the To location with the correct Yaw & Pitch.
++ if (packetplayinflying.hasLook) {
++ to.setYaw(packetplayinflying.yaw);
++ to.setPitch(packetplayinflying.pitch);
++ }
++
++ // Prevent 40 event-calls for less than a single pixel of movement >.>
++ double delta = Math.pow(this.lastPosX - to.getX(), 2) + Math.pow(this.lastPosY - to.getY(), 2) + Math.pow(this.lastPosZ - to.getZ(), 2);
++ float deltaAngle = Math.abs(this.lastYaw - to.getYaw()) + Math.abs(this.lastPitch - to.getPitch());
++
++ if ((delta > 1f / 256 || deltaAngle > 10f) && !this.player.dead) {
++ this.lastPosX = to.getX();
++ this.lastPosY = to.getY();
++ this.lastPosZ = to.getZ();
++ this.lastYaw = to.getYaw();
++ this.lastPitch = to.getPitch();
++
++ // Skip the first time we do this
++ if (from.getX() != Double.MAX_VALUE) {
++ Location oldTo = to.clone();
++ PlayerMoveEvent event = new PlayerMoveEvent(player, from, to);
++ this.server.getPluginManager().callEvent(event);
++
++ // 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(), from.getZ(), from.getYaw(), from.getPitch(), Collections.<PacketPlayOutPosition.EnumPlayerTeleportFlags>emptySet(), this.teleportAwait));
++ return;
++ }
++
++ // If a Plugin has changed the To destination then we teleport the Player
++ // there to avoid any 'Moved wrongly' or 'Moved too quickly' errors.
++ // We only do this if the Event was not cancelled.
++ if (!oldTo.equals(event.getTo()) && !event.isCancelled()) {
++ this.player.getBukkitEntity().teleport(event.getTo(), PlayerTeleportEvent.TeleportCause.UNKNOWN);
++ return;
++ }
++
++ // Check to see if the Players Location has some how changed during the call of the event.
++ // This can happen due to a plugin teleporting the player instead of using .setTo()
++ if (!from.equals(this.getPlayer().getLocation()) && this.justTeleported) {
++ this.justTeleported = false;
++ return;
++ }
++ }
++ }
++ // CraftBukkit end
++
+ this.B = d12 >= -0.03125D;
+ this.B &= !this.minecraftServer.getAllowFlight() && !this.player.abilities.canFly;
+ this.B &= !this.player.hasEffect(MobEffects.LEVITATION) && !this.player.cB() && !worldserver.d(this.player.getBoundingBox().g(0.0625D).a(0.0D, -0.55D, 0.0D));
+@@ -368,15 +594,79 @@
}
public void a(double d0, double d1, double d2, float f, float f1) {
- this.a(d0, d1, d2, f, f1, Collections.emptySet());
-+ this.a(d0, d1, d2, f, f1, Collections.<PacketPlayOutPosition.EnumPlayerTeleportFlags>emptySet()); // CraftBukkit fix decompile errors
++ this.a(d0, d1, d2, f, f1, Collections.<PacketPlayOutPosition.EnumPlayerTeleportFlags>emptySet());
}
public void a(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set) {
+- double d3 = set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.X) ? this.player.locX : 0.0D;
+- double d4 = set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.Y) ? this.player.locY : 0.0D;
+- double d5 = set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.Z) ? this.player.locZ : 0.0D;
+ // CraftBukkit start - Delegate to teleport(Location)
+ Player player = this.getPlayer();
+ Location from = player.getLocation();
@@ -318,7 +405,8 @@
+
+ this.internalTeleport(d0, d1, d2, f, f1, set);
+ }
-+
+
+- this.teleportPos = new Vec3D(d0 + d3, d1 + d4, d2 + d5);
+ public void teleport(Location dest) {
+ internalTeleport(dest.getX(), dest.getY(), dest.getZ(), dest.getYaw(), dest.getPitch(), Collections.emptySet());
+ }
@@ -332,33 +420,48 @@
+ f1 = 0;
+ }
+ this.justTeleported = true;
++ this.teleportPos = new Vec3D(d0, d1, d2);
++ if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.X)) {
++ this.teleportPos = this.teleportPos.add(this.player.locX, 0.0D, 0.0D);
++ }
++
++ if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.Y)) {
++ this.teleportPos = this.teleportPos.add(0.0D, this.player.locY, 0.0D);
++ }
++
++ if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.Z)) {
++ this.teleportPos = this.teleportPos.add(0.0D, 0.0D, this.player.locZ);
++ }
+ // CraftBukkit end
- this.checkMovement = false;
- this.o = d0;
- this.p = d1;
-@@ -325,38 +536,63 @@
+ float f2 = f;
+ float f3 = f1;
+
+@@ -388,6 +678,14 @@
f3 = f1 + this.player.pitch;
}
+ // CraftBukkit start - update last location
-+ this.lastPosX = this.o;
-+ this.lastPosY = this.p;
-+ this.lastPosZ = this.q;
++ this.lastPosX = this.teleportPos.x;
++ this.lastPosY = this.teleportPos.y;
++ this.lastPosZ = this.teleportPos.z;
+ this.lastYaw = f2;
+ this.lastPitch = f3;
+ // CraftBukkit end
+
- this.player.setLocation(this.o, this.p, this.q, f2, f3);
- this.player.playerConnection.sendPacket(new PacketPlayOutPosition(d0, d1, d2, f, f1, set));
- }
+ if (++this.teleportAwait == Integer.MAX_VALUE) {
+ this.teleportAwait = 0;
+ }
+@@ -399,15 +697,32 @@
public void a(PacketPlayInBlockDig packetplayinblockdig) {
- PlayerConnectionUtils.ensureMainThread(packetplayinblockdig, this, this.player.u());
+ PlayerConnectionUtils.ensureMainThread(packetplayinblockdig, this, this.player.x());
+ if (this.player.dead) return; // CraftBukkit
WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension);
BlockPosition blockposition = packetplayinblockdig.a();
this.player.resetIdleTimer();
+ ItemStack itemstack;
+
+ // CraftBukkit start
switch (PlayerConnection.SyntheticClass_1.a[packetplayinblockdig.c().ordinal()]) {
- case 1:
@@ -373,40 +476,52 @@
+ // Else we increment the drop count and check the amount.
+ this.dropCount++;
+ if (this.dropCount >= 20) {
-+ this.c.warn(this.player.getName() + " dropped their items too quickly!");
++ this.LOGGER.warn(this.player.getName() + " dropped their items too quickly!");
+ this.disconnect("You dropped your items too quickly (Hacking?)");
+ return;
+ }
+ }
+ // CraftBukkit end
- this.player.a(false);
- }
+ itemstack = this.player.b(EnumHand.OFF_HAND);
+ this.player.a(EnumHand.OFF_HAND, this.player.b(EnumHand.MAIN_HAND));
+ this.player.a(EnumHand.MAIN_HAND, itemstack);
+@@ -415,21 +730,21 @@
return;
- case 2:
+ case 2: // DROP_ALL_ITEMS
if (!this.player.isSpectator()) {
- this.player.a(true);
+ this.player.a(false);
}
return;
- case 3:
+ case 3: // RELEASE_USE_ITEM
- this.player.bU();
+ if (!this.player.isSpectator()) {
+ this.player.a(true);
+ }
+
return;
- case 4:
++ case 4: // START_DESTROY_BLOCK
+ this.player.clearActiveItem();
+ itemstack = this.player.getItemInMainHand();
+ if (itemstack != null && itemstack.count == 0) {
+@@ -438,8 +753,8 @@
+
+ return;
+
- case 5:
- case 6:
-+ case 4: // START_DESTROY_BLOCK
+ case 5: // ABORT_DESTROY_BLOCK
+ case 6: // STOP_DESTROY_BLOCK
+ case 7:
double d0 = this.player.locX - ((double) blockposition.getX() + 0.5D);
double d1 = this.player.locY - ((double) blockposition.getY() + 0.5D) + 1.5D;
- double d2 = this.player.locZ - ((double) blockposition.getZ() + 0.5D);
-@@ -371,7 +607,15 @@
+@@ -455,7 +770,15 @@
if (!this.minecraftServer.a(worldserver, blockposition, this.player) && worldserver.getWorldBorder().a(blockposition)) {
this.player.playerInteractManager.a(blockposition, packetplayinblockdig.b());
} else {
@@ -422,37 +537,50 @@
}
} else {
if (packetplayinblockdig.c() == PacketPlayInBlockDig.EnumPlayerDigType.STOP_DESTROY_BLOCK) {
-@@ -391,11 +635,22 @@
+@@ -475,10 +798,12 @@
default:
throw new IllegalArgumentException("Invalid player action");
}
+ // CraftBukkit end
}
+ public void a(PacketPlayInUseItem packetplayinuseitem) {
+ PlayerConnectionUtils.ensureMainThread(packetplayinuseitem, this, this.player.x());
++ if (this.player.dead) return; // CraftBukkit
+ WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension);
+ EnumHand enumhand = packetplayinuseitem.c();
+ ItemStack itemstack = this.player.b(enumhand);
+@@ -492,6 +817,13 @@
+ chatmessage.getChatModifier().setColor(EnumChatFormat.RED);
+ this.player.playerConnection.sendPacket(new PacketPlayOutChat(chatmessage));
+ } else if (this.teleportPos == null && this.player.e((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D) < 64.0D && !this.minecraftServer.a(worldserver, blockposition, this.player) && worldserver.getWorldBorder().a(blockposition)) {
++ // CraftBukkit start - Check if we can actually do something over this large a distance
++ Location eyeLoc = this.getPlayer().getEyeLocation();
++ double reachDistance = NumberConversions.square(eyeLoc.getX() - blockposition.getX()) + NumberConversions.square(eyeLoc.getY() - blockposition.getY()) + NumberConversions.square(eyeLoc.getZ() - blockposition.getZ());
++ if (reachDistance > (this.getPlayer().getGameMode() == org.bukkit.GameMode.CREATIVE ? CREATIVE_PLACE_DISTANCE_SQUARED : SURVIVAL_PLACE_DISTANCE_SQUARED)) {
++ return;
++ }
++ // CraftBukkit end
+ this.player.playerInteractManager.a(this.player, worldserver, itemstack, enumhand, blockposition, enumdirection, packetplayinuseitem.d(), packetplayinuseitem.e(), packetplayinuseitem.f());
+ }
+
+@@ -507,19 +839,55 @@
+
public void a(PacketPlayInBlockPlace packetplayinblockplace) {
- PlayerConnectionUtils.ensureMainThread(packetplayinblockplace, this, this.player.u());
+ PlayerConnectionUtils.ensureMainThread(packetplayinblockplace, this, this.player.x());
++ if (this.player.dead) return; // CraftBukkit
WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension);
-+
-+ // CraftBukkit start
-+ if (this.player.dead) return;
-+
-+ // CraftBukkit - if rightclick decremented the item, always send the update packet. */
-+ // this is not here for CraftBukkit's own functionality; rather it is to fix
-+ // a notch bug where the item doesn't update correctly.
-+ boolean always = false;
-+ // CraftBukkit end
-+
- ItemStack itemstack = this.player.inventory.getItemInHand();
- boolean flag = false;
- BlockPosition blockposition = packetplayinblockplace.a();
-@@ -407,7 +662,50 @@
- return;
- }
+ EnumHand enumhand = packetplayinblockplace.a();
+ ItemStack itemstack = this.player.b(enumhand);
-- this.player.playerInteractManager.useItem(this.player, worldserver, itemstack);
+ this.player.resetIdleTimer();
+ if (itemstack != null) {
+- this.player.playerInteractManager.a(this.player, worldserver, itemstack, enumhand);
+- itemstack = this.player.b(enumhand);
+- if (itemstack != null && itemstack.count == 0) {
+- this.player.a(enumhand, (ItemStack) null);
+- itemstack = null;
+ // CraftBukkit start
-+ int itemstackAmount = itemstack.count;
-+
+ // Raytrace to look for 'rogue armswings'
+ float f1 = this.player.pitch;
+ float f2 = this.player.yaw;
@@ -483,52 +611,21 @@
+ org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(player, Action.RIGHT_CLICK_BLOCK, movingobjectposition.a(), movingobjectposition.direction, itemstack, true);
+ cancelled = event.useItemInHand() == Event.Result.DENY;
+ }
-+ }
-+
+ }
+
+ if (!cancelled) {
-+ this.player.playerInteractManager.useItem(this.player, this.player.world, itemstack);
++ this.player.playerInteractManager.a(this.player, worldserver, itemstack, enumhand);
++ itemstack = this.player.b(enumhand);
++ if (itemstack != null && itemstack.count == 0) {
++ this.player.a(enumhand, (ItemStack) null);
++ itemstack = null;
++ }
+ }
-+
-+ // CraftBukkit - notch decrements the counter by 1 in the above method with food,
-+ // snowballs and so forth, but he does it in a place that doesn't cause the
-+ // inventory update packet to get sent
-+ always = (itemstack.count != itemstackAmount) || itemstack.getItem() == Item.getItemOf(Blocks.WATERLILY);
+ // CraftBukkit end
- } else if (blockposition.getY() >= this.minecraftServer.getMaxBuildHeight() - 1 && (enumdirection == EnumDirection.UP || blockposition.getY() >= this.minecraftServer.getMaxBuildHeight())) {
- ChatMessage chatmessage = new ChatMessage("build.tooHigh", new Object[] { Integer.valueOf(this.minecraftServer.getMaxBuildHeight())});
-
-@@ -415,8 +713,19 @@
- this.player.playerConnection.sendPacket(new PacketPlayOutChat(chatmessage));
- flag = true;
- } else {
-+ // CraftBukkit start - Check if we can actually do something over this large a distance
-+ Location eyeLoc = this.getPlayer().getEyeLocation();
-+ double reachDistance = NumberConversions.square(eyeLoc.getX() - blockposition.getX()) + NumberConversions.square(eyeLoc.getY() - blockposition.getY()) + NumberConversions.square(eyeLoc.getZ() - blockposition.getZ());
-+ if (reachDistance > (this.getPlayer().getGameMode() == org.bukkit.GameMode.CREATIVE ? CREATIVE_PLACE_DISTANCE_SQUARED : SURVIVAL_PLACE_DISTANCE_SQUARED)) {
-+ return;
-+ }
-+
-+ if (!worldserver.getWorldBorder().a(blockposition)) {
-+ return;
-+ }
-+
- if (this.checkMovement && this.player.e((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D) < 64.0D && !this.minecraftServer.a(worldserver, blockposition, this.player) && worldserver.getWorldBorder().a(blockposition)) {
-- this.player.playerInteractManager.interact(this.player, worldserver, itemstack, blockposition, enumdirection, packetplayinblockplace.d(), packetplayinblockplace.e(), packetplayinblockplace.f());
-+ always = !this.player.playerInteractManager.interact(this.player, worldserver, itemstack, blockposition, enumdirection, packetplayinblockplace.d(), packetplayinblockplace.e(), packetplayinblockplace.f());
- }
-
- flag = true;
-@@ -440,7 +749,8 @@
-
- this.player.activeContainer.b();
- this.player.g = false;
-- if (!ItemStack.matches(this.player.inventory.getItemInHand(), packetplayinblockplace.getItemStack())) {
-+ // CraftBukkit - TODO CHECK IF NEEDED -- new if structure might not need 'always'. Kept it in for now, but may be able to remove in future
-+ if (!ItemStack.matches(this.player.inventory.getItemInHand(), packetplayinblockplace.getItemStack()) || always) {
- this.sendPacket(new PacketPlayOutSetSlot(this.player.activeContainer.windowId, slot.rawSlotIndex, this.player.inventory.getItemInHand()));
- }
}
-@@ -454,8 +764,8 @@
+ }
+
+@@ -530,8 +898,8 @@
WorldServer[] aworldserver = this.minecraftServer.worldServer;
int i = aworldserver.length;
@@ -539,16 +636,16 @@
if (worldserver != null) {
entity = packetplayinspectate.a(worldserver);
-@@ -468,6 +778,8 @@
+@@ -544,6 +912,8 @@
if (entity != null) {
this.player.setSpectatorTarget(this.player);
- this.player.mount((Entity) null);
+ this.player.stopRiding();
+
+ /* CraftBukkit start - replace with bukkit handling for multi-world
if (entity.world != this.player.world) {
- WorldServer worldserver1 = this.player.u();
+ WorldServer worldserver1 = this.player.x();
WorldServer worldserver2 = (WorldServer) entity.world;
-@@ -492,22 +804,44 @@
+@@ -569,12 +939,19 @@
} else {
this.player.enderTeleportTo(entity.locX, entity.locY, entity.locZ);
}
@@ -563,12 +660,17 @@
- public void a(PacketPlayInResourcePackStatus packetplayinresourcepackstatus) {}
+ // CraftBukkit start
+ public void a(PacketPlayInResourcePackStatus packetplayinresourcepackstatus) {
-+ this.server.getPluginManager().callEvent(new PlayerResourcePackStatusEvent(getPlayer(), PlayerResourcePackStatusEvent.Status.values()[packetplayinresourcepackstatus.b.ordinal()]));
++ this.server.getPluginManager().callEvent(new PlayerResourcePackStatusEvent(getPlayer(), PlayerResourcePackStatusEvent.Status.values()[packetplayinresourcepackstatus.status.ordinal()]));
+ }
+ // CraftBukkit end
+ public void a(PacketPlayInBoatMove packetplayinboatmove) {
+ PlayerConnectionUtils.ensureMainThread(packetplayinboatmove, this, this.player.x());
+@@ -587,14 +964,29 @@
+ }
+
public void a(IChatBaseComponent ichatbasecomponent) {
-- PlayerConnection.c.info(this.player.getName() + " lost connection: " + ichatbasecomponent);
+- PlayerConnection.LOGGER.info(this.player.getName() + " lost connection: " + ichatbasecomponent);
+ // CraftBukkit start - Rarely it would send a disconnect line twice
+ if (this.processedDisconnect) {
+ return;
@@ -576,27 +678,27 @@
+ this.processedDisconnect = true;
+ }
+ // CraftBukkit end
-+ PlayerConnection.c.info(this.player.getName() + " lost connection: " + ichatbasecomponent.c()); // CraftBukkit: Don't toString(). // PAIL: Rename
++ PlayerConnection.LOGGER.info(this.player.getName() + " lost connection: " + ichatbasecomponent.toPlainText()); // CraftBukkit: Don't toString().
+ // CraftBukkit start - Replace vanilla quit message handling with our own.
+ /*
- this.minecraftServer.aH();
+ this.minecraftServer.aC();
ChatMessage chatmessage = new ChatMessage("multiplayer.player.left", new Object[] { this.player.getScoreboardDisplayName()});
chatmessage.getChatModifier().setColor(EnumChatFormat.YELLOW);
this.minecraftServer.getPlayerList().sendMessage(chatmessage);
+ */
+
- this.player.q();
+ this.player.t();
- this.minecraftServer.getPlayerList().disconnect(this.player);
+ String quitMessage = this.minecraftServer.getPlayerList().disconnect(this.player);
+ if ((quitMessage != null) && (quitMessage.length() > 0)) {
+ this.minecraftServer.getPlayerList().sendMessage(CraftChatMessage.fromString(quitMessage));
+ }
+ // CraftBukkit end
- if (this.minecraftServer.T() && this.player.getName().equals(this.minecraftServer.S())) {
- PlayerConnection.c.info("Stopping singleplayer server as player logged out");
+ if (this.minecraftServer.R() && this.player.getName().equals(this.minecraftServer.Q())) {
+ PlayerConnection.LOGGER.info("Stopping singleplayer server as player logged out");
this.minecraftServer.safeShutdown();
-@@ -529,6 +863,15 @@
+@@ -616,6 +1008,15 @@
}
}
@@ -610,15 +712,13 @@
+ // CraftBukkit end
+
try {
- this.networkManager.handle(packet);
+ this.networkManager.sendPacket(packet);
} catch (Throwable throwable) {
-@@ -549,18 +892,34 @@
- }
+@@ -637,17 +1038,32 @@
public void a(PacketPlayInHeldItemSlot packetplayinhelditemslot) {
-+ // CraftBukkit start
-+ if (this.player.dead) return;
- PlayerConnectionUtils.ensureMainThread(packetplayinhelditemslot, this, this.player.u());
+ PlayerConnectionUtils.ensureMainThread(packetplayinhelditemslot, this, this.player.x());
++ if (this.player.dead) return; // CraftBukkit
if (packetplayinhelditemslot.a() >= 0 && packetplayinhelditemslot.a() < PlayerInventory.getHotbarSize()) {
+ PlayerItemHeldEvent event = new PlayerItemHeldEvent(this.getPlayer(), this.player.inventory.itemInHandIndex, packetplayinhelditemslot.a());
+ this.server.getPluginManager().callEvent(event);
@@ -631,25 +731,25 @@
this.player.inventory.itemInHandIndex = packetplayinhelditemslot.a();
this.player.resetIdleTimer();
} else {
- PlayerConnection.c.warn(this.player.getName() + " tried to set an invalid carried item");
+ PlayerConnection.LOGGER.warn(this.player.getName() + " tried to set an invalid carried item");
+ this.disconnect("Nope!"); // CraftBukkit
}
}
public void a(PacketPlayInChat packetplayinchat) {
-- PlayerConnectionUtils.ensureMainThread(packetplayinchat, this, this.player.u());
+- PlayerConnectionUtils.ensureMainThread(packetplayinchat, this, this.player.x());
- if (this.player.getChatFlags() == EntityHuman.EnumChatVisibility.HIDDEN) {
+ // CraftBukkit start - async chat
+ boolean isSync = packetplayinchat.a().startsWith("/");
+ if (packetplayinchat.a().startsWith("/")) {
-+ PlayerConnectionUtils.ensureMainThread(packetplayinchat, this, this.player.u());
++ PlayerConnectionUtils.ensureMainThread(packetplayinchat, this, this.player.x());
+ }
+ // CraftBukkit end
+ if (this.player.dead || this.player.getChatFlags() == EntityHuman.EnumChatVisibility.HIDDEN) { // CraftBukkit - dead men tell no tales
ChatMessage chatmessage = new ChatMessage("chat.cannotSend", new Object[0]);
chatmessage.getChatModifier().setColor(EnumChatFormat.RED);
-@@ -573,39 +932,249 @@
+@@ -660,39 +1076,249 @@
for (int i = 0; i < s.length(); ++i) {
if (!SharedConstants.isAllowedChatCharacter(s.charAt(i))) {
@@ -692,7 +792,7 @@
+ this.minecraftServer.server.playerCommandState = false;
+ }
+ } else if (s.isEmpty()) {
-+ c.warn(this.player.getName() + " tried to send an empty message");
++ LOGGER.warn(this.player.getName() + " tried to send an empty message");
+ } else if (getPlayer().isConversing()) {
+ getPlayer().acceptConversationInput(s);
+ } else if (this.player.getChatFlags() == EntityHuman.EnumChatVisibility.SYSTEM) { // Re-add "Command Only" flag check
@@ -756,7 +856,7 @@
+ // Do nothing, this is coming from a plugin
+ } else {
+ Player player = this.getPlayer();
-+ AsyncPlayerChatEvent event = new AsyncPlayerChatEvent(async, player, s, new LazyPlayerSet());
++ AsyncPlayerChatEvent event = new AsyncPlayerChatEvent(async, player, s, new LazyPlayerSet(minecraftServer));
+ this.server.getPluginManager().callEvent(event);
+
+ if (PlayerChatEvent.getHandlerList().getRegisteredListeners().length != 0) {
@@ -820,11 +920,11 @@
+
+ private void handleCommand(String s) {
+ // CraftBukkit start - whole method
-+ this.c.info(this.player.getName() + " issued server command: " + s);
++ this.LOGGER.info(this.player.getName() + " issued server command: " + s);
+
+ CraftPlayer player = this.getPlayer();
+
-+ PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(player, s, new LazyPlayerSet());
++ PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(player, s, new LazyPlayerSet(minecraftServer));
+ this.server.getPluginManager().callEvent(event);
+
+ if (event.isCancelled()) {
@@ -845,8 +945,8 @@
}
public void a(PacketPlayInArmAnimation packetplayinarmanimation) {
+ PlayerConnectionUtils.ensureMainThread(packetplayinarmanimation, this, this.player.x());
+ if (this.player.dead) return; // CraftBukkit
- PlayerConnectionUtils.ensureMainThread(packetplayinarmanimation, this, this.player.u());
this.player.resetIdleTimer();
+ // CraftBukkit start - Raytrace to look for 'rogue armswings'
+ float f1 = this.player.pitch;
@@ -876,11 +976,11 @@
+
+ if (event.isCancelled()) return;
+ // CraftBukkit end
- this.player.bw();
+ this.player.a(packetplayinarmanimation.a());
}
public void a(PacketPlayInEntityAction packetplayinentityaction) {
- PlayerConnectionUtils.ensureMainThread(packetplayinentityaction, this, this.player.u());
+ PlayerConnectionUtils.ensureMainThread(packetplayinentityaction, this, this.player.x());
+ // CraftBukkit start
+ if (this.player.dead) return;
+ switch (packetplayinentityaction.b()) {
@@ -905,30 +1005,21 @@
+ }
+ // CraftBukkit end
this.player.resetIdleTimer();
- switch (PlayerConnection.SyntheticClass_1.b[packetplayinentityaction.b().ordinal()]) {
- case 1:
-@@ -626,7 +1195,7 @@
+ IJumpable ijumpable;
- case 5:
- this.player.a(false, true, true);
-- this.checkMovement = false;
-+ // this.checkMovement = false; // CraftBukkit - this is handled in teleport
- break;
-
- case 6:
-@@ -648,6 +1217,7 @@
- }
+@@ -762,6 +1388,7 @@
public void a(PacketPlayInUseEntity packetplayinuseentity) {
+ PlayerConnectionUtils.ensureMainThread(packetplayinuseentity, this, this.player.x());
+ if (this.player.dead) return; // CraftBukkit
- PlayerConnectionUtils.ensureMainThread(packetplayinuseentity, this, this.player.u());
WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension);
Entity entity = packetplayinuseentity.a((World) worldserver);
-@@ -662,18 +1232,67 @@
- }
- if (this.player.h(entity) < d0) {
-+ ItemStack itemInHand = this.player.inventory.getItemInHand(); // CraftBukkit
+@@ -778,22 +1405,72 @@
+ EnumHand enumhand;
+ ItemStack itemstack;
+
++ ItemStack itemInHand = this.player.b(packetplayinuseentity.b() == null ? EnumHand.MAIN_HAND : packetplayinuseentity.b()); // CraftBukkit
+
+ if (packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT
+ || packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT_AT) {
@@ -939,14 +1030,14 @@
+ if (packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT) {
+ event = new PlayerInteractEntityEvent((Player) this.getPlayer(), entity.getBukkitEntity());
+ } else {
-+ Vec3D target = packetplayinuseentity.b();
-+ event = new PlayerInteractAtEntityEvent((Player) this.getPlayer(), entity.getBukkitEntity(), new org.bukkit.util.Vector(target.a, target.b, target.c));
++ Vec3D target = packetplayinuseentity.c();
++ event = new PlayerInteractAtEntityEvent((Player) this.getPlayer(), entity.getBukkitEntity(), new org.bukkit.util.Vector(target.x, target.y, target.z));
+ }
+ this.server.getPluginManager().callEvent(event);
+
+ if (triggerLeashUpdate && (event.isCancelled() || this.player.inventory.getItemInHand() == null || this.player.inventory.getItemInHand().getItem() != Items.LEAD)) {
+ // Refresh the current leash state
-+ this.sendPacket(new PacketPlayOutAttachEntity(1, entity, ((EntityInsentient) entity).getLeashHolder()));
++ this.sendPacket(new PacketPlayOutAttachEntity(entity, ((EntityInsentient) entity).getLeashHolder()));
+ }
+
+ if (event.isCancelled() || this.player.inventory.getItemInHand() == null || this.player.inventory.getItemInHand().getItem() != origItem) {
@@ -959,8 +1050,11 @@
+ }
+ // CraftBukkit end
+ }
++
if (packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT) {
- this.player.u(entity);
+ enumhand = packetplayinuseentity.b();
+ itemstack = this.player.b(enumhand);
+ this.player.a(entity, itemstack, enumhand);
+
+ // CraftBukkit start
+ if (itemInHand != null && itemInHand.count <= -1) {
@@ -968,7 +1062,9 @@
+ }
+ // CraftBukkit end
} else if (packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT_AT) {
- entity.a((EntityHuman) this.player, packetplayinuseentity.b());
+ enumhand = packetplayinuseentity.b();
+ itemstack = this.player.b(enumhand);
+ entity.a((EntityHuman) this.player, packetplayinuseentity.c(), itemstack, enumhand);
+
+ // CraftBukkit start
+ if (itemInHand != null && itemInHand.count <= -1) {
@@ -993,45 +1089,43 @@
}
}
}
-@@ -688,7 +1307,8 @@
- switch (PlayerConnection.SyntheticClass_1.c[packetplayinclientcommand_enumclientcommand.ordinal()]) {
+@@ -809,7 +1486,8 @@
case 1:
if (this.player.viewingCredits) {
+ this.player.viewingCredits = false;
- this.player = this.minecraftServer.getPlayerList().moveToWorld(this.player, 0, true);
+ // this.player = this.minecraftServer.getPlayerList().moveToWorld(this.player, 0, true);
+ this.minecraftServer.getPlayerList().changeDimension(this.player, 0, PlayerTeleportEvent.TeleportCause.END_PORTAL); // CraftBukkit - reroute logic through custom portal management
- } else if (this.player.u().getWorldData().isHardcore()) {
- if (this.minecraftServer.T() && this.player.getName().equals(this.minecraftServer.S())) {
- this.player.playerConnection.disconnect("You have died. Game over, man, it\'s game over!");
-@@ -719,15 +1339,21 @@
- }
+ } else {
+ if (this.player.getHealth() > 0.0F) {
+ return;
+@@ -835,14 +1513,20 @@
public void a(PacketPlayInCloseWindow packetplayinclosewindow) {
-+ if (this.player.dead) return; // CraftBukkit
- PlayerConnectionUtils.ensureMainThread(packetplayinclosewindow, this, this.player.u());
+ PlayerConnectionUtils.ensureMainThread(packetplayinclosewindow, this, this.player.x());
+
++ if (this.player.dead) return; // CraftBukkit
+ CraftEventFactory.handleInventoryCloseEvent(this.player); // CraftBukkit
+
- this.player.p();
+ this.player.s();
}
public void a(PacketPlayInWindowClick packetplayinwindowclick) {
+ PlayerConnectionUtils.ensureMainThread(packetplayinwindowclick, this, this.player.x());
+ if (this.player.dead) return; // CraftBukkit
- PlayerConnectionUtils.ensureMainThread(packetplayinwindowclick, this, this.player.u());
this.player.resetIdleTimer();
if (this.player.activeContainer.windowId == packetplayinwindowclick.a() && this.player.activeContainer.c(this.player)) {
- if (this.player.isSpectator()) {
+ boolean cancelled = this.player.isSpectator(); // CraftBukkit - see below if
-+ if (false) { // this.player.isSpectator()) {
++ if (false/*this.player.isSpectator()*/) { // CraftBukkit
ArrayList arraylist = Lists.newArrayList();
for (int i = 0; i < this.player.activeContainer.c.size(); ++i) {
-@@ -736,7 +1362,270 @@
+@@ -851,8 +1535,273 @@
this.player.a(this.player.activeContainer, (List) arraylist);
} else {
-- ItemStack itemstack = this.player.activeContainer.clickItem(packetplayinwindowclick.b(), packetplayinwindowclick.c(), packetplayinwindowclick.f(), this.player);
-+ // ItemStack itemstack = this.player.activeContainer.clickItem(packetplayinwindowclick.b(), packetplayinwindowclick.c(), packetplayinwindowclick.f(), this.player);
+- ItemStack itemstack = this.player.activeContainer.a(packetplayinwindowclick.b(), packetplayinwindowclick.c(), packetplayinwindowclick.f(), this.player);
+ // CraftBukkit start - Call InventoryClickEvent
+ if (packetplayinwindowclick.b() < -1 && packetplayinwindowclick.b() != -999) {
+ return;
@@ -1040,177 +1134,181 @@
+ InventoryView inventory = this.player.activeContainer.getBukkitView();
+ SlotType type = CraftInventoryView.getSlotType(inventory, packetplayinwindowclick.b());
+
-+ InventoryClickEvent event = null;
++ InventoryClickEvent event;
+ ClickType click = ClickType.UNKNOWN;
+ InventoryAction action = InventoryAction.UNKNOWN;
+
+ ItemStack itemstack = null;
+
-+ if (packetplayinwindowclick.b() == -1) {
-+ type = SlotType.OUTSIDE; // override
-+ click = packetplayinwindowclick.c() == 0 ? ClickType.WINDOW_BORDER_LEFT : ClickType.WINDOW_BORDER_RIGHT;
-+ action = InventoryAction.NOTHING;
-+ } else if (packetplayinwindowclick.f() == 0) {
-+ if (packetplayinwindowclick.c() == 0) {
-+ click = ClickType.LEFT;
-+ } else if (packetplayinwindowclick.c() == 1) {
-+ click = ClickType.RIGHT;
-+ }
-+ if (packetplayinwindowclick.c() == 0 || packetplayinwindowclick.c() == 1) {
-+ action = InventoryAction.NOTHING; // Don't want to repeat ourselves
-+ if (packetplayinwindowclick.b() == -999) {
-+ if (player.inventory.getCarried() != null) {
-+ action = packetplayinwindowclick.c() == 0 ? InventoryAction.DROP_ALL_CURSOR : InventoryAction.DROP_ONE_CURSOR;
-+ }
-+ } else {
-+ Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.b());
-+ if (slot != null) {
-+ ItemStack clickedItem = slot.getItem();
-+ ItemStack cursor = player.inventory.getCarried();
-+ if (clickedItem == null) {
-+ if (cursor != null) {
-+ action = packetplayinwindowclick.c() == 0 ? InventoryAction.PLACE_ALL : InventoryAction.PLACE_ONE;
-+ }
-+ } else if (slot.isAllowed(player)) {
-+ if (cursor == null) {
-+ action = packetplayinwindowclick.c() == 0 ? InventoryAction.PICKUP_ALL : InventoryAction.PICKUP_HALF;
-+ } else if (slot.isAllowed(cursor)) {
-+ if (clickedItem.doMaterialsMatch(cursor) && ItemStack.equals(clickedItem, cursor)) {
-+ int toPlace = packetplayinwindowclick.c() == 0 ? cursor.count : 1;
-+ toPlace = Math.min(toPlace, clickedItem.getMaxStackSize() - clickedItem.count);
-+ toPlace = Math.min(toPlace, slot.inventory.getMaxStackSize() - clickedItem.count);
-+ if (toPlace == 1) {
-+ action = InventoryAction.PLACE_ONE;
-+ } else if (toPlace == cursor.count) {
-+ action = InventoryAction.PLACE_ALL;
-+ } else if (toPlace < 0) {
-+ action = toPlace != -1 ? InventoryAction.PICKUP_SOME : InventoryAction.PICKUP_ONE; // this happens with oversized stacks
-+ } else if (toPlace != 0) {
-+ action = InventoryAction.PLACE_SOME;
-+ }
-+ } else if (cursor.count <= slot.getMaxStackSize()) {
-+ action = InventoryAction.SWAP_WITH_CURSOR;
++ switch (packetplayinwindowclick.f()) {
++ case PICKUP:
++ if (packetplayinwindowclick.c() == 0) {
++ click = ClickType.LEFT;
++ } else if (packetplayinwindowclick.c() == 1) {
++ click = ClickType.RIGHT;
++ }
++ if (packetplayinwindowclick.c() == 0 || packetplayinwindowclick.c() == 1) {
++ action = InventoryAction.NOTHING; // Don't want to repeat ourselves
++ if (packetplayinwindowclick.b() == -999) {
++ if (player.inventory.getCarried() != null) {
++ action = packetplayinwindowclick.c() == 0 ? InventoryAction.DROP_ALL_CURSOR : InventoryAction.DROP_ONE_CURSOR;
++ }
++ } else {
++ Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.b());
++ if (slot != null) {
++ ItemStack clickedItem = slot.getItem();
++ ItemStack cursor = player.inventory.getCarried();
++ if (clickedItem == null) {
++ if (cursor != null) {
++ action = packetplayinwindowclick.c() == 0 ? InventoryAction.PLACE_ALL : InventoryAction.PLACE_ONE;
+ }
-+ } else if (cursor.getItem() == clickedItem.getItem() && (!cursor.usesData() || cursor.getData() == clickedItem.getData()) && ItemStack.equals(cursor, clickedItem)) {
-+ if (clickedItem.count >= 0) {
-+ if (clickedItem.count + cursor.count <= cursor.getMaxStackSize()) {
-+ // As of 1.5, this is result slots only
-+ action = InventoryAction.PICKUP_ALL;
++ } else if (slot.isAllowed(player)) {
++ if (cursor == null) {
++ action = packetplayinwindowclick.c() == 0 ? InventoryAction.PICKUP_ALL : InventoryAction.PICKUP_HALF;
++ } else if (slot.isAllowed(cursor)) {
++ if (clickedItem.doMaterialsMatch(cursor) && ItemStack.equals(clickedItem, cursor)) {
++ int toPlace = packetplayinwindowclick.c() == 0 ? cursor.count : 1;
++ toPlace = Math.min(toPlace, clickedItem.getMaxStackSize() - clickedItem.count);
++ toPlace = Math.min(toPlace, slot.inventory.getMaxStackSize() - clickedItem.count);
++ if (toPlace == 1) {
++ action = InventoryAction.PLACE_ONE;
++ } else if (toPlace == cursor.count) {
++ action = InventoryAction.PLACE_ALL;
++ } else if (toPlace < 0) {
++ action = toPlace != -1 ? InventoryAction.PICKUP_SOME : InventoryAction.PICKUP_ONE; // this happens with oversized stacks
++ } else if (toPlace != 0) {
++ action = InventoryAction.PLACE_SOME;
++ }
++ } else if (cursor.count <= slot.getMaxStackSize()) {
++ action = InventoryAction.SWAP_WITH_CURSOR;
++ }
++ } else if (cursor.getItem() == clickedItem.getItem() && (!cursor.usesData() || cursor.getData() == clickedItem.getData()) && ItemStack.equals(cursor, clickedItem)) {
++ if (clickedItem.count >= 0) {
++ if (clickedItem.count + cursor.count <= cursor.getMaxStackSize()) {
++ // As of 1.5, this is result slots only
++ action = InventoryAction.PICKUP_ALL;
++ }
+ }
+ }
+ }
+ }
+ }
+ }
-+ }
-+ } else if (packetplayinwindowclick.f() == 1) {
-+ if (packetplayinwindowclick.c() == 0) {
-+ click = ClickType.SHIFT_LEFT;
-+ } else if (packetplayinwindowclick.c() == 1) {
-+ click = ClickType.SHIFT_RIGHT;
-+ }
-+ if (packetplayinwindowclick.c() == 0 || packetplayinwindowclick.c() == 1) {
-+ if (packetplayinwindowclick.b() < 0) {
-+ action = InventoryAction.NOTHING;
-+ } else {
-+ Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.b());
-+ if (slot != null && slot.isAllowed(this.player) && slot.hasItem()) {
-+ action = InventoryAction.MOVE_TO_OTHER_INVENTORY;
-+ } else {
++ break;
++ // TODO check on updates
++ case QUICK_MOVE:
++ if (packetplayinwindowclick.c() == 0) {
++ click = ClickType.SHIFT_LEFT;
++ } else if (packetplayinwindowclick.c() == 1) {
++ click = ClickType.SHIFT_RIGHT;
++ }
++ if (packetplayinwindowclick.c() == 0 || packetplayinwindowclick.c() == 1) {
++ if (packetplayinwindowclick.b() < 0) {
+ action = InventoryAction.NOTHING;
++ } else {
++ Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.b());
++ if (slot != null && slot.isAllowed(this.player) && slot.hasItem()) {
++ action = InventoryAction.MOVE_TO_OTHER_INVENTORY;
++ } else {
++ action = InventoryAction.NOTHING;
++ }
+ }
+ }
-+ }
-+ } else if (packetplayinwindowclick.f() == 2) {
-+ if (packetplayinwindowclick.c() >= 0 && packetplayinwindowclick.c() < 9) {
-+ click = ClickType.NUMBER_KEY;
-+ Slot clickedSlot = this.player.activeContainer.getSlot(packetplayinwindowclick.b());
-+ if (clickedSlot.isAllowed(player)) {
-+ ItemStack hotbar = this.player.inventory.getItem(packetplayinwindowclick.c());
-+ boolean canCleanSwap = hotbar == null || (clickedSlot.inventory == player.inventory && clickedSlot.isAllowed(hotbar)); // the slot will accept the hotbar item
-+ if (clickedSlot.hasItem()) {
-+ if (canCleanSwap) {
-+ action = InventoryAction.HOTBAR_SWAP;
-+ } else {
-+ int firstEmptySlot = player.inventory.getFirstEmptySlotIndex();
-+ if (firstEmptySlot > -1) {
-+ action = InventoryAction.HOTBAR_MOVE_AND_READD;
++ break;
++ case SWAP:
++ if (packetplayinwindowclick.c() >= 0 && packetplayinwindowclick.c() < 9) {
++ click = ClickType.NUMBER_KEY;
++ Slot clickedSlot = this.player.activeContainer.getSlot(packetplayinwindowclick.b());
++ if (clickedSlot.isAllowed(player)) {
++ ItemStack hotbar = this.player.inventory.getItem(packetplayinwindowclick.c());
++ boolean canCleanSwap = hotbar == null || (clickedSlot.inventory == player.inventory && clickedSlot.isAllowed(hotbar)); // the slot will accept the hotbar item
++ if (clickedSlot.hasItem()) {
++ if (canCleanSwap) {
++ action = InventoryAction.HOTBAR_SWAP;
+ } else {
-+ action = InventoryAction.NOTHING; // This is not sane! Mojang: You should test for other slots of same type
++ int firstEmptySlot = player.inventory.getFirstEmptySlotIndex();
++ if (firstEmptySlot > -1) {
++ action = InventoryAction.HOTBAR_MOVE_AND_READD;
++ } else {
++ action = InventoryAction.NOTHING; // This is not sane! Mojang: You should test for other slots of same type
++ }
+ }
++ } else if (!clickedSlot.hasItem() && hotbar != null && clickedSlot.isAllowed(hotbar)) {
++ action = InventoryAction.HOTBAR_SWAP;
++ } else {
++ action = InventoryAction.NOTHING;
+ }
-+ } else if (!clickedSlot.hasItem() && hotbar != null && clickedSlot.isAllowed(hotbar)) {
-+ action = InventoryAction.HOTBAR_SWAP;
+ } else {
+ action = InventoryAction.NOTHING;
+ }
-+ } else {
-+ action = InventoryAction.NOTHING;
+ }
-+ // Special constructor for number key
-+ event = new InventoryClickEvent(inventory, type, packetplayinwindowclick.b(), click, action, packetplayinwindowclick.c());
-+ }
-+ } else if (packetplayinwindowclick.f() == 3) {
-+ if (packetplayinwindowclick.c() == 2) {
-+ click = ClickType.MIDDLE;
-+ if (packetplayinwindowclick.b() == -999) {
-+ action = InventoryAction.NOTHING;
-+ } else {
-+ Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.b());
-+ if (slot != null && slot.hasItem() && player.abilities.canInstantlyBuild && player.inventory.getCarried() == null) {
-+ action = InventoryAction.CLONE_STACK;
-+ } else {
++ break;
++ case CLONE:
++ if (packetplayinwindowclick.c() == 2) {
++ click = ClickType.MIDDLE;
++ if (packetplayinwindowclick.b() == -999) {
+ action = InventoryAction.NOTHING;
++ } else {
++ Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.b());
++ if (slot != null && slot.hasItem() && player.abilities.canInstantlyBuild && player.inventory.getCarried() == null) {
++ action = InventoryAction.CLONE_STACK;
++ } else {
++ action = InventoryAction.NOTHING;
++ }
+ }
++ } else {
++ click = ClickType.UNKNOWN;
++ action = InventoryAction.UNKNOWN;
+ }
-+ } else {
-+ click = ClickType.UNKNOWN;
-+ action = InventoryAction.UNKNOWN;
-+ }
-+ } else if (packetplayinwindowclick.f() == 4) {
-+ if (packetplayinwindowclick.b() >= 0) {
-+ if (packetplayinwindowclick.c() == 0) {
-+ click = ClickType.DROP;
-+ Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.b());
-+ if (slot != null && slot.hasItem() && slot.isAllowed(player) && slot.getItem() != null && slot.getItem().getItem() != Item.getItemOf(Blocks.AIR)) {
-+ action = InventoryAction.DROP_ONE_SLOT;
-+ } else {
-+ action = InventoryAction.NOTHING;
++ break;
++ case THROW:
++ if (packetplayinwindowclick.b() >= 0) {
++ if (packetplayinwindowclick.c() == 0) {
++ click = ClickType.DROP;
++ Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.b());
++ if (slot != null && slot.hasItem() && slot.isAllowed(player) && slot.getItem() != null && slot.getItem().getItem() != Item.getItemOf(Blocks.AIR)) {
++ action = InventoryAction.DROP_ONE_SLOT;
++ } else {
++ action = InventoryAction.NOTHING;
++ }
++ } else if (packetplayinwindowclick.c() == 1) {
++ click = ClickType.CONTROL_DROP;
++ Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.b());
++ if (slot != null && slot.hasItem() && slot.isAllowed(player) && slot.getItem() != null && slot.getItem().getItem() != Item.getItemOf(Blocks.AIR)) {
++ action = InventoryAction.DROP_ALL_SLOT;
++ } else {
++ action = InventoryAction.NOTHING;
++ }
+ }
-+ } else if (packetplayinwindowclick.c() == 1) {
-+ click = ClickType.CONTROL_DROP;
-+ Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.b());
-+ if (slot != null && slot.hasItem() && slot.isAllowed(player) && slot.getItem() != null && slot.getItem().getItem() != Item.getItemOf(Blocks.AIR)) {
-+ action = InventoryAction.DROP_ALL_SLOT;
-+ } else {
-+ action = InventoryAction.NOTHING;
++ } else {
++ // Sane default (because this happens when they are holding nothing. Don't ask why.)
++ click = ClickType.LEFT;
++ if (packetplayinwindowclick.c() == 1) {
++ click = ClickType.RIGHT;
+ }
++ action = InventoryAction.NOTHING;
+ }
-+ } else {
-+ // Sane default (because this happens when they are holding nothing. Don't ask why.)
-+ click = ClickType.LEFT;
-+ if (packetplayinwindowclick.c() == 1) {
-+ click = ClickType.RIGHT;
-+ }
-+ action = InventoryAction.NOTHING;
-+ }
-+ } else if (packetplayinwindowclick.f() == 5) {
-+ itemstack = this.player.activeContainer.clickItem(packetplayinwindowclick.b(), packetplayinwindowclick.c(), 5, this.player);
-+ } else if (packetplayinwindowclick.f() == 6) {
-+ click = ClickType.DOUBLE_CLICK;
-+ action = InventoryAction.NOTHING;
-+ if (packetplayinwindowclick.b() >= 0 && this.player.inventory.getCarried() != null) {
-+ ItemStack cursor = this.player.inventory.getCarried();
++ break;
++ case QUICK_CRAFT:
++ itemstack = this.player.activeContainer.a(packetplayinwindowclick.b(), packetplayinwindowclick.c(), packetplayinwindowclick.f(), this.player);
++ break;
++ case PICKUP_ALL:
++ click = ClickType.DOUBLE_CLICK;
+ action = InventoryAction.NOTHING;
-+ // Quick check for if we have any of the item
-+ if (inventory.getTopInventory().contains(org.bukkit.Material.getMaterial(Item.getId(cursor.getItem()))) || inventory.getBottomInventory().contains(org.bukkit.Material.getMaterial(Item.getId(cursor.getItem())))) {
-+ action = InventoryAction.COLLECT_TO_CURSOR;
++ if (packetplayinwindowclick.b() >= 0 && this.player.inventory.getCarried() != null) {
++ ItemStack cursor = this.player.inventory.getCarried();
++ action = InventoryAction.NOTHING;
++ // Quick check for if we have any of the item
++ if (inventory.getTopInventory().contains(org.bukkit.Material.getMaterial(Item.getId(cursor.getItem()))) || inventory.getBottomInventory().contains(org.bukkit.Material.getMaterial(Item.getId(cursor.getItem())))) {
++ action = InventoryAction.COLLECT_TO_CURSOR;
++ }
+ }
-+ }
++ break;
++ default:
++ break;
+ }
-+ // TODO check on updates
+
-+ if (packetplayinwindowclick.f() != 5) {
++ if (packetplayinwindowclick.f() != InventoryClickType.QUICK_CRAFT) {
+ if (click == ClickType.NUMBER_KEY) {
+ event = new InventoryClickEvent(inventory, type, packetplayinwindowclick.b(), click, action, packetplayinwindowclick.c());
+ } else {
@@ -1235,12 +1333,12 @@
+ switch (event.getResult()) {
+ case ALLOW:
+ case DEFAULT:
-+ itemstack = this.player.activeContainer.clickItem(packetplayinwindowclick.b(), packetplayinwindowclick.c(), packetplayinwindowclick.f(), this.player);
++ itemstack = this.player.activeContainer.a(packetplayinwindowclick.b(), packetplayinwindowclick.c(), packetplayinwindowclick.f(), this.player);
+ break;
+ case DENY:
+ /* Needs enum constructor in InventoryAction
+ if (action.modifiesOtherSlots()) {
-+
+
+ } else {
+ if (action.modifiesCursor()) {
+ this.player.playerConnection.sendPacket(new Packet103SetSlot(-1, -1, this.player.inventory.getCarried()));
@@ -1295,13 +1393,13 @@
+ }
+ }
+ // CraftBukkit end
-
if (ItemStack.matches(packetplayinwindowclick.e(), itemstack)) {
this.player.playerConnection.sendPacket(new PacketPlayOutTransaction(packetplayinwindowclick.a(), packetplayinwindowclick.d(), true));
-@@ -797,8 +1686,48 @@
+ this.player.f = true;
+@@ -915,8 +1864,48 @@
}
- boolean flag1 = packetplayinsetcreativeslot.a() >= 1 && packetplayinsetcreativeslot.a() < 36 + PlayerInventory.getHotbarSize();
+ boolean flag1 = packetplayinsetcreativeslot.a() >= 1 && packetplayinsetcreativeslot.a() <= 45;
- boolean flag2 = itemstack == null || itemstack.getItem() != null;
+ // CraftBukkit - Add invalidItems check
+ boolean flag2 = itemstack == null || itemstack.getItem() != null && !invalidItems.contains(Item.getId(itemstack.getItem()));
@@ -1348,23 +1446,23 @@
if (flag1 && flag2 && flag3) {
if (itemstack == null) {
-@@ -821,6 +1750,7 @@
- }
+@@ -940,6 +1929,7 @@
public void a(PacketPlayInTransaction packetplayintransaction) {
+ PlayerConnectionUtils.ensureMainThread(packetplayintransaction, this, this.player.x());
+ if (this.player.dead) return; // CraftBukkit
- PlayerConnectionUtils.ensureMainThread(packetplayintransaction, this, this.player.u());
- Short oshort = (Short) this.n.get(this.player.activeContainer.windowId);
+ Short oshort = (Short) this.k.get(this.player.activeContainer.windowId);
-@@ -831,6 +1761,7 @@
- }
+ if (oshort != null && packetplayintransaction.b() == oshort.shortValue() && this.player.activeContainer.windowId == packetplayintransaction.a() && !this.player.activeContainer.c(this.player) && !this.player.isSpectator()) {
+@@ -950,6 +1940,7 @@
public void a(PacketPlayInUpdateSign packetplayinupdatesign) {
+ PlayerConnectionUtils.ensureMainThread(packetplayinupdatesign, this, this.player.x());
+ if (this.player.dead) return; // CraftBukkit
- PlayerConnectionUtils.ensureMainThread(packetplayinupdatesign, this, this.player.u());
this.player.resetIdleTimer();
WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension);
-@@ -847,14 +1778,30 @@
+ BlockPosition blockposition = packetplayinupdatesign.a();
+@@ -966,14 +1957,30 @@
if (!tileentitysign.b() || tileentitysign.c() != this.player) {
this.minecraftServer.warning("Player " + this.player.getName() + " just tried to change non-editable sign");
@@ -1372,7 +1470,7 @@
return;
}
- IChatBaseComponent[] aichatbasecomponent = packetplayinupdatesign.b();
+ String[] astring = packetplayinupdatesign.b();
+ // CraftBukkit start
+ Player player = this.server.getPlayer(this.player);
@@ -1381,9 +1479,9 @@
+ int z = packetplayinupdatesign.a().getZ();
+ String[] lines = new String[4];
+
- for (int i = 0; i < aichatbasecomponent.length; ++i) {
-- tileentitysign.lines[i] = new ChatComponentText(EnumChatFormat.a(aichatbasecomponent[i].c()));
-+ lines[i] = EnumChatFormat.a(aichatbasecomponent[i].c());
+ for (int i = 0; i < astring.length; ++i) {
+- tileentitysign.lines[i] = new ChatComponentText(EnumChatFormat.a(astring[i]));
++ lines[i] = EnumChatFormat.a(new ChatComponentText(EnumChatFormat.a(astring[i])).toPlainText());
}
+ SignChangeEvent event = new SignChangeEvent((org.bukkit.craftbukkit.block.CraftBlock) player.getWorld().getBlockAt(x, y, z), this.server.getPlayer(this.player), lines);
+ this.server.getPluginManager().callEvent(event);
@@ -1395,11 +1493,11 @@
+ // CraftBukkit end
tileentitysign.update();
- worldserver.notify(blockposition);
-@@ -877,11 +1824,27 @@
+ worldserver.notify(blockposition, iblockdata, iblockdata, 3);
+@@ -996,11 +2003,27 @@
public void a(PacketPlayInAbilities packetplayinabilities) {
- PlayerConnectionUtils.ensureMainThread(packetplayinabilities, this, this.player.u());
+ PlayerConnectionUtils.ensureMainThread(packetplayinabilities, this, this.player.x());
- this.player.abilities.isFlying = packetplayinabilities.isFlying() && this.player.abilities.canFly;
+ // CraftBukkit start
+ if (this.player.abilities.canFly && this.player.abilities.isFlying != packetplayinabilities.isFlying()) {
@@ -1415,7 +1513,7 @@
}
public void a(PacketPlayInTabComplete packetplayintabcomplete) {
- PlayerConnectionUtils.ensureMainThread(packetplayintabcomplete, this, this.player.u());
+ PlayerConnectionUtils.ensureMainThread(packetplayintabcomplete, this, this.player.x());
+ // CraftBukkit start
+ if (chatSpamField.addAndGet(this, 10) > 500 && !this.minecraftServer.getPlayerList().isOp(this.player.getProfile())) {
+ this.disconnect("disconnect.spam");
@@ -1423,18 +1521,18 @@
+ }
+ // CraftBukkit end
ArrayList arraylist = Lists.newArrayList();
- Iterator iterator = this.minecraftServer.tabCompleteCommand(this.player, packetplayintabcomplete.a(), packetplayintabcomplete.b()).iterator();
+ Iterator iterator = this.minecraftServer.tabCompleteCommand(this.player, packetplayintabcomplete.a(), packetplayintabcomplete.b(), packetplayintabcomplete.c()).iterator();
-@@ -905,6 +1868,7 @@
+@@ -1025,6 +2048,7 @@
ItemStack itemstack;
ItemStack itemstack1;
-+ try { // CraftBukkit
- if ("MC|BEdit".equals(packetplayincustompayload.a())) {
++ try { // CraftBukkit - Make sure the buffer is freed
+ if ("MC|BEdit".equals(s)) {
packetdataserializer = new PacketDataSerializer(Unpooled.wrappedBuffer(packetplayincustompayload.b()));
-@@ -921,13 +1885,16 @@
- itemstack1 = this.player.inventory.getItemInHand();
+@@ -1041,13 +2065,16 @@
+ itemstack1 = this.player.getItemInMainHand();
if (itemstack1 != null) {
if (itemstack.getItem() == Items.WRITABLE_BOOK && itemstack.getItem() == itemstack1.getItem()) {
+ itemstack1 = new ItemStack(Items.WRITABLE_BOOK); // CraftBukkit
@@ -1445,96 +1543,95 @@
return;
}
} catch (Exception exception) {
- PlayerConnection.c.error("Couldn\'t handle book info", exception);
+ PlayerConnection.LOGGER.error("Couldn\'t handle book info", exception);
+ this.disconnect("Invalid book data!"); // CraftBukkit
return;
} finally {
packetdataserializer.release();
-@@ -950,16 +1917,21 @@
- itemstack1 = this.player.inventory.getItemInHand();
- if (itemstack1 != null) {
- if (itemstack.getItem() == Items.WRITTEN_BOOK && itemstack1.getItem() == Items.WRITABLE_BOOK) {
-+ // CraftBukkit start
-+ itemstack1 = new ItemStack(Items.WRITTEN_BOOK);
- itemstack1.a("author", (NBTBase) (new NBTTagString(this.player.getName())));
- itemstack1.a("title", (NBTBase) (new NBTTagString(itemstack.getTag().getString("title"))));
- itemstack1.a("pages", (NBTBase) itemstack.getTag().getList("pages", 8));
- itemstack1.setItem(Items.WRITTEN_BOOK);
-+ CraftEventFactory.handleEditBookEvent(player, itemstack1);
-+ // CraftBukkit end
- }
+@@ -1073,6 +2100,8 @@
+ itemstack1 = this.player.getItemInMainHand();
+ if (itemstack1 != null) {
+ if (itemstack.getItem() == Items.WRITABLE_BOOK && itemstack1.getItem() == Items.WRITABLE_BOOK) {
++ // CraftBukkit start
++ itemstack1 = new ItemStack(Items.WRITABLE_BOOK);
+ itemstack1.a("author", (NBTBase) (new NBTTagString(this.player.getName())));
+ itemstack1.a("title", (NBTBase) (new NBTTagString(itemstack.getTag().getString("title"))));
+ NBTTagList nbttaglist = itemstack.getTag().getList("pages", 8);
+@@ -1087,12 +2116,15 @@
+
+ itemstack1.a("pages", (NBTBase) nbttaglist);
+ itemstack1.setItem(Items.WRITTEN_BOOK);
++ CraftEventFactory.handleEditBookEvent(player, itemstack1);
++ // CraftBukkit end
+ }
- return;
- }
- } catch (Exception exception1) {
- PlayerConnection.c.error("Couldn\'t sign book", exception1);
-+ this.disconnect("Invalid book data!"); // CraftBukkit
- return;
- } finally {
- packetdataserializer.release();
-@@ -976,11 +1948,12 @@
- }
- } catch (Exception exception2) {
- PlayerConnection.c.error("Couldn\'t select trade", exception2);
-+ this.disconnect("Invalid trade data!"); // CraftBukkit
- }
- } else if ("MC|AdvCdm".equals(packetplayincustompayload.a())) {
- if (!this.minecraftServer.getEnableCommandBlock()) {
- this.player.sendMessage(new ChatMessage("advMode.notEnabled", new Object[0]));
-- } else if (this.player.a(2, "") && this.player.abilities.canInstantlyBuild) {
-+ } else if (this.player.getBukkitEntity().isOp() && this.player.abilities.canInstantlyBuild) { // CraftBukkit - Change to Bukkit OP versus Vanilla OP
- packetdataserializer = packetplayincustompayload.b();
-
- try {
-@@ -1016,6 +1989,7 @@
+ return;
}
- } catch (Exception exception3) {
- PlayerConnection.c.error("Couldn\'t set command block", exception3);
-+ this.disconnect("Invalid CommandBlock data!"); // CraftBukkit
+ } catch (Exception exception1) {
+ PlayerConnection.LOGGER.error("Couldn\'t sign book", exception1);
++ this.disconnect("Invalid book data!"); // CraftBukkit
+ return;
} finally {
packetdataserializer.release();
- }
-@@ -1041,6 +2015,7 @@
+@@ -1158,6 +2190,7 @@
+ }
+ } catch (Exception exception3) {
+ PlayerConnection.LOGGER.error("Couldn\'t set command block", exception3);
++ this.disconnect("Invalid CommandBlock data!"); // CraftBukkit
+ } finally {
+ packetdataserializer.release();
+ }
+@@ -1227,6 +2260,7 @@
+ }
+ } catch (Exception exception4) {
+ PlayerConnection.LOGGER.error("Couldn\'t set command block", exception4);
++ this.disconnect("Invalid CommandBlock data!"); // CraftBukkit
+ } finally {
+ packetdataserializer.release();
}
- } catch (Exception exception4) {
- PlayerConnection.c.error("Couldn\'t set beacon", exception4);
-+ this.disconnect("Invalid beacon data!"); // CraftBukkit
+@@ -1252,6 +2286,7 @@
+ }
+ } catch (Exception exception5) {
+ PlayerConnection.LOGGER.error("Couldn\'t set beacon", exception5);
++ this.disconnect("Invalid beacon data!"); // CraftBukkit
+ }
+ }
+ } else if ("MC|ItemName".equals(s)) {
+@@ -1334,10 +2369,37 @@
+ packetdataserializer.release();
+ }
+ }
++ // CraftBukkit start
++ else if (packetplayincustompayload.a().equals("REGISTER")) {
++ String channels = packetplayincustompayload.b().toString(com.google.common.base.Charsets.UTF_8);
++ for (String channel : channels.split("\0")) {
++ getPlayer().addChannel(channel);
++ }
++ } else if (packetplayincustompayload.a().equals("UNREGISTER")) {
++ String channels = packetplayincustompayload.b().toString(com.google.common.base.Charsets.UTF_8);
++ for (String channel : channels.split("\0")) {
++ getPlayer().removeChannel(channel);
++ }
++ } else {
++ byte[] data = new byte[packetplayincustompayload.b().readableBytes()];
++ packetplayincustompayload.b().readBytes(data);
++ server.getMessenger().dispatchIncomingMessage(player.getBukkitEntity(), packetplayincustompayload.a(), data);
++ }
++ // CraftBukkit end
}
}
- } else if ("MC|ItemName".equals(packetplayincustompayload.a()) && this.player.activeContainer instanceof ContainerAnvil) {
-@@ -1056,7 +2031,35 @@
- containeranvil.a("");
- }
}
+ // CraftBukkit start
-+ else if (packetplayincustompayload.a().equals("REGISTER")) {
-+ String channels = packetplayincustompayload.b().toString(com.google.common.base.Charsets.UTF_8);
-+ for (String channel : channels.split("\0")) {
-+ getPlayer().addChannel(channel);
-+ }
-+ } else if (packetplayincustompayload.a().equals("UNREGISTER")) {
-+ String channels = packetplayincustompayload.b().toString(com.google.common.base.Charsets.UTF_8);
-+ for (String channel : channels.split("\0")) {
-+ getPlayer().removeChannel(channel);
-+ }
-+ } else {
-+ byte[] data = new byte[packetplayincustompayload.b().readableBytes()];
-+ packetplayincustompayload.b().readBytes(data);
-+ server.getMessenger().dispatchIncomingMessage(player.getBukkitEntity(), packetplayincustompayload.a(), data);
-+ }
-+ // CraftBukkit end
-+ // CraftBukkit start
+ } finally {
+ if (packetplayincustompayload.b().refCnt() > 0) {
+ packetplayincustompayload.b().release();
+ }
+ }
-+ // CraftBukkit end
+ }
+ // CraftBukkit start - Add "isDisconnected" method
+ public final boolean isDisconnected() {
-+ return !this.player.joining && !this.networkManager.channel.config().isAutoRead();
++ return !this.player.joining && !this.networkManager.isConnected();
}
static class SyntheticClass_1 {