package net.glowstone.net.handler.play.player; import com.flowpowered.networking.MessageHandler; import net.glowstone.EventFactory; import net.glowstone.net.GlowSession; import net.glowstone.net.message.play.game.PositionRotationMessage; import net.glowstone.net.message.play.player.PlayerUpdateMessage; import org.bukkit.Location; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerTeleportEvent; public final class PlayerUpdateHandler implements MessageHandler<GlowSession, PlayerUpdateMessage> { @Override public void handle(GlowSession session, PlayerUpdateMessage message) { Location oldLocation = session.getPlayer().getLocation(); Location newLocation = oldLocation.clone(); message.update(newLocation); // don't let players move more than 16 blocks in a single packet. // this is NOT robust hack prevention - only to prevent client // confusion about where its actual location is (e.g. during login) if (newLocation.distanceSquared(oldLocation) > 16 * 16) { return; } // call move event if movement actually occurred and there are handlers registered if (!oldLocation.equals(newLocation) && PlayerMoveEvent.getHandlerList().getRegisteredListeners().length > 0) { final PlayerMoveEvent event = EventFactory.callEvent(new PlayerMoveEvent(session.getPlayer(), oldLocation, newLocation)); if (event.isCancelled()) { // tell client they're back where they started session.send(new PositionRotationMessage(oldLocation)); return; } if (!event.getTo().equals(newLocation)) { // teleport to the set destination: fires PlayerTeleportEvent and // handles if the destination is in another world session.getPlayer().teleport(event.getTo(), PlayerTeleportEvent.TeleportCause.PLUGIN); return; } } // do stuff with onGround if we need to if (session.getPlayer().isOnGround() != message.isOnGround()) { session.getPlayer().setOnGround(message.isOnGround()); } // move event was not fired or did nothing, simply update location session.getPlayer().setRawLocation(newLocation); } }