@Inject( method = "processPlayer", at = @At( value = "FIELD", target = "net.minecraft.network.NetHandlerPlayServer.hasMoved:Z", ordinal = 2), cancellable = true) public void proccesPlayerMoved(C03PacketPlayer packetIn, CallbackInfo ci) { if (packetIn.isMoving() || packetIn.getRotating() && !this.playerEntity.isDead) { Player player = (Player) this.playerEntity; Vector3d fromrot = player.getRotation(); // If Sponge used the player's current location, the delta might never be triggered which // could be exploited Location from = player.getLocation(); if (this.lastMoveLocation != null) { from = this.lastMoveLocation; } Vector3d torot = new Vector3d(packetIn.getPitch(), packetIn.getYaw(), 0); Location to = new Location( player.getWorld(), packetIn.getPositionX(), packetIn.getPositionY(), packetIn.getPositionZ()); // Minecraft sends a 0, 0, 0 position when rotation only update occurs, this needs to be // recognized and corrected boolean rotationOnly = !packetIn.isMoving() && packetIn.getRotating(); if (rotationOnly) { // Correct the to location so it's not misrepresented to plugins, only when player rotates // without moving // In this case it's only a rotation update, which isn't related to the to location from = player.getLocation(); to = from; } // Minecraft does the same with rotation when it's only a positional update boolean positionOnly = packetIn.isMoving() && !packetIn.getRotating(); if (positionOnly) { // Correct the new rotation to match the old rotation torot = fromrot; } double deltaSquared = to.getPosition().distanceSquared(from.getPosition()); double deltaAngleSquared = fromrot.distanceSquared(torot); // These magic numbers are sad but help prevent excessive lag from this event. // eventually it would be nice to not have them if (deltaSquared > ((1f / 16) * (1f / 16)) || deltaAngleSquared > (.15f * .15f)) { PlayerMoveEvent event = SpongeEventFactory.createPlayerMove(Sponge.getGame(), player, from, to, torot); Sponge.getGame().getEventManager().post(event); if (event.isCancelled()) { player.setLocationAndRotation(from, fromrot); this.lastMoveLocation = from; ci.cancel(); } else if (!event.getNewLocation().equals(to)) { player.setLocationAndRotation(event.getNewLocation(), event.getRotation()); this.lastMoveLocation = event.getNewLocation(); ci.cancel(); } else if (!from.equals(player.getLocation()) && this.justTeleported) { this.lastMoveLocation = player.getLocation(); // Prevent teleports during the move event from causing odd behaviors this.justTeleported = false; ci.cancel(); } else { this.lastMoveLocation = event.getNewLocation(); } } } }
@Subscribe public void onMove(PlayerMoveEvent event) { org.spongepowered.api.world.Location from = event.getOldLocation(); org.spongepowered.api.world.Location to = event.getNewLocation(); int x2; if (getInt(from.getX()) != (x2 = getInt(to.getX()))) { Player player = event.getUser(); PlotPlayer pp = SpongeUtil.getPlayer(player); Extent extent = to.getExtent(); if (!(extent instanceof World)) { pp.deleteMeta("location"); return; } pp.setMeta("location", SpongeUtil.getLocation(player)); World world = (World) extent; String worldname = ((World) extent).getName(); PlotWorld plotworld = PS.get().getPlotWorld(worldname); if (plotworld == null) { return; } PlotManager plotManager = PS.get().getPlotManager(worldname); PlotId id = plotManager.getPlotId(plotworld, x2, 0, getInt(to.getZ())); Plot lastPlot = (Plot) pp.getMeta("lastplot"); if (id == null) { if (lastPlot == null) { return; } if (!PlotListener.plotExit(pp, lastPlot)) { MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_EXIT_DENIED); if (lastPlot.equals(MainUtil.getPlot(SpongeUtil.getLocation(worldname, from)))) { event.setNewLocation(from); } else { event.setNewLocation(world.getSpawnLocation()); } return; } } else if (lastPlot != null && id.equals(lastPlot.id)) { return; } else { Plot plot = MainUtil.getPlot(worldname, id); if (!PlotListener.plotEntry(pp, plot)) { MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_ENTRY_DENIED); if (!plot.equals(MainUtil.getPlot(SpongeUtil.getLocation(worldname, from)))) { event.setNewLocation(from); } else { event.setNewLocation(world.getSpawnLocation()); } return; } } Integer border = MainUtil.worldBorder.get(worldname); if (border != null) { if (x2 > border) { Vector3d pos = to.getPosition(); to = to.setPosition(new Vector3d(border - 4, pos.getY(), pos.getZ())); event.setNewLocation(to); MainUtil.sendMessage(pp, C.BORDER); } else if (x2 < -border) { Vector3d pos = to.getPosition(); to = to.setPosition(new Vector3d(-border + 4, pos.getY(), pos.getZ())); event.setNewLocation(to); MainUtil.sendMessage(pp, C.BORDER); } } return; } int z2; if (getInt(from.getZ()) != (z2 = getInt(to.getZ()))) { Player player = event.getUser(); PlotPlayer pp = SpongeUtil.getPlayer(player); Extent extent = to.getExtent(); if (!(extent instanceof World)) { pp.deleteMeta("location"); return; } pp.setMeta("location", SpongeUtil.getLocation(player)); World world = (World) extent; String worldname = ((World) extent).getName(); PlotWorld plotworld = PS.get().getPlotWorld(worldname); if (plotworld == null) { return; } PlotManager plotManager = PS.get().getPlotManager(worldname); PlotId id = plotManager.getPlotId(plotworld, x2, 0, z2); Plot lastPlot = (Plot) pp.getMeta("lastplot"); if (id == null) { if (lastPlot == null) { return; } if (!PlotListener.plotExit(pp, lastPlot)) { MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_EXIT_DENIED); if (lastPlot.equals(MainUtil.getPlot(SpongeUtil.getLocation(worldname, from)))) { event.setNewLocation(from); } else { event.setNewLocation(world.getSpawnLocation()); } return; } } else if (lastPlot != null && id.equals(lastPlot.id)) { return; } else { Plot plot = MainUtil.getPlot(worldname, id); if (!PlotListener.plotEntry(pp, plot)) { MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_ENTRY_DENIED); if (!plot.equals(MainUtil.getPlot(SpongeUtil.getLocation(worldname, from)))) { event.setNewLocation(from); } else { event.setNewLocation(world.getSpawnLocation()); } return; } } Integer border = MainUtil.worldBorder.get(worldname); if (border != null) { if (z2 > border) { Vector3d pos = to.getPosition(); to = to.setPosition(new Vector3d(pos.getX(), pos.getY(), border - 4)); event.setNewLocation(to); MainUtil.sendMessage(pp, C.BORDER); } else if (z2 < -border) { Vector3d pos = to.getPosition(); to = to.setPosition(new Vector3d(pos.getX(), pos.getY(), -border + 4)); event.setNewLocation(to); MainUtil.sendMessage(pp, C.BORDER); } } } }