示例#1
0
  /**
   * Various corner cases that would cause this check to fail or require special treatment
   *
   * @param player
   * @param data
   * @param from
   * @param to
   * @return
   */
  public boolean shouldBeApplied(
      final Player player, final MovingData data, final Location from, final Location to) {

    if (player.isDead() || player.isInsideVehicle() || data.insideVehicle) return false;

    if (data.wasTeleported) {
      // Remember this location
      data.teleportedTo = from.clone();
      data.wasTeleported = false;
      data.jumpPhase = 0;
    }

    if (data.teleportedTo != null && data.teleportedTo.getWorld().equals(from.getWorld())) {
      // As long as the from-Location doesn't change, the player didn't accept the teleport
      if (data.teleportedTo.distanceSquared(from) < 0.01D) {
        // Event after Teleport ignored
        return false;
      } else {
        // The player finally accepted the teleport with the previous event
        data.teleportedTo = null;
      }
    }

    // If the target is a bed, don't check (going to bed is a kind of mini teleport...)
    if (to.getWorld().getBlockTypeIdAt(to) == Material.BED_BLOCK.getId()) {
      return false;
    }

    return true;
  }
示例#2
0
  /**
   * Call this when a player got successfully teleported with the corresponding event to adjust
   * stored data to the new situation
   *
   * @param event
   */
  public void teleported(PlayerTeleportEvent event) {

    MovingData data = MovingData.get(event.getPlayer());

    // We can enforce a teleport, if that flag is explicitly set (but I'd rather have other plugins
    // not arbitrarily cancel teleport events in the first place...
    if (data.teleportInitializedByMe != null
        && event.isCancelled()
        && enforceTeleport
        && event.getTo().equals(data.teleportInitializedByMe)) {
      event.setCancelled(false);
      data.teleportInitializedByMe = null;
    }

    if (!event.isCancelled()) {
      data.wasTeleported = true;
      data.setBackPoint = event.getTo().clone();
      // data.lastLocation = event.getTo().clone();
    }

    // reset anyway - if another plugin cancelled our teleport it's no use to try and be precise
    data.jumpPhase = 0;
  }
示例#3
0
  /**
   * The actual check. First find out if the event needs to be handled at all Second check if the
   * player moved too far horizontally Third check if the player moved too high vertically Fourth
   * treat any occured violations as configured
   *
   * @param event
   */
  public Location check(Player player, Location from, Location to, MovingData data) {

    updateVelocity(player.getVelocity(), data);

    Location newToLocation = null;

    final long startTime = System.nanoTime();

    /** *********** DECIDE WHICH CHECKS NEED TO BE RUN ************ */
    final boolean flyCheck =
        !allowFlying && !plugin.hasPermission(player, PermissionData.PERMISSION_FLYING, checkOPs);
    final boolean runCheck = true;

    /** *************** REFINE EVENT DATA FOR CHECKS ************** */
    if (flyCheck || runCheck) {

      // In both cases it will be interesting to know the type of underground the player
      // is in or goes to
      final int fromType =
          helper.isLocationOnGround(from.getWorld(), from.getX(), from.getY(), from.getZ(), false);
      final int toType =
          helper.isLocationOnGround(to.getWorld(), to.getX(), to.getY(), to.getZ(), false);

      final boolean fromOnGround = fromType != MovingEventHelper.NONSOLID;
      final boolean toOnGround = toType != MovingEventHelper.NONSOLID;

      // Distribute data to checks in the form needed by the checks

      /** ******************* EXECUTE THE CHECKS ******************* */
      double result = 0.0D;

      if (flyCheck) {
        result += Math.max(0D, flyingCheck.check(player, from, fromOnGround, to, toOnGround, data));
      }

      if (runCheck) {
        result +=
            Math.max(
                0D,
                runningCheck.check(
                    from,
                    to,
                    !allowFakeSneak && player.isSneaking(),
                    !allowFastSwim && (fromType & toType & MovingEventHelper.LIQUID) > 0,
                    data));
      }

      /** ******* HANDLE/COMBINE THE RESULTS OF THE CHECKS ********** */
      data.jumpPhase++;

      if (result <= 0) {
        if (fromOnGround) {
          data.setBackPoint = from;
          data.jumpPhase = 0;
        } else if (toOnGround) {
          data.jumpPhase = 0;
        }
      } else if (result > 0) {
        // Increment violation counter
        data.violationLevel += result;
        if (data.setBackPoint == null) data.setBackPoint = from;
      }

      if (result > 0 && data.violationLevel > 1) {

        setupSummaryTask(player, data);

        int level = limitCheck(data.violationLevel - 1);

        data.violationsInARow[level]++;

        newToLocation =
            action(player, from, to, actions[level], data.violationsInARow[level], data);
      }
    }

    // Slowly reduce the level with each event
    data.violationLevel *= 0.97;
    data.horizFreedom *= 0.97;

    statisticElapsedTimeNano += System.nanoTime() - startTime;
    statisticTotalEvents++;

    return newToLocation;
  }