/** * Update the cached values for players velocity to be prepared to give them additional movement * freedom in their next move events * * @param v * @param data */ public void updateVelocity(Vector v, MovingData data) { // Compare the velocity vector to the existing movement freedom that we've from previous events double tmp = (Math.abs(v.getX()) + Math.abs(v.getZ())) * 3D; if (tmp > data.horizFreedom) data.horizFreedom = tmp; if (v.getY() > data.maxYVelocity) { data.maxYVelocity = v.getY(); } }
/** * 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; }