@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();
        }
      }
    }
  }
Esempio n. 2
0
 @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);
       }
     }
   }
 }