NoCheatPlus/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockinteract/BlockInteractData.java

345 lines
9.9 KiB
Java

/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.checks.blockinteract;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.Event.Result;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.access.ACheckData;
import fr.neatmonster.nocheatplus.utilities.TickTask;
import fr.neatmonster.nocheatplus.utilities.location.TrigUtil;
/**
* Player specific data for the block interact checks.
*/
public class BlockInteractData extends ACheckData {
// Violation levels.
public double directionVL = 0;
public double reachVL = 0;
public double speedVL = 0;
public double visibleVL = 0;
// General data
// Last block interacted with
/** Set to Integer.MAX_VALUE for reset. */
private int lastX = Integer.MAX_VALUE;
private int lastY, lastZ;
/** null for air */
private Material lastType = null;
private int lastTick;
private Action lastAction = null;
private boolean lastAllowUseBlock = false;
private boolean lastAllowUseItem = false;
private boolean lastIsCancelled = true;
// Data of the reach check.
public double reachDistance;
/** Last reset time. */
public long speedTime = 0;
/** Number of interactions since last reset-time. */
public int speedCount = 0;
/** Cancel is set, times in a row. */
public int subsequentCancel = 0;
/**
* Skipped actions due to rate limiting (debugging rather). May be reset
* with logging.
*/
public int rateLimitSkip = 0;
/**
* Checks that have been run and passed for the block last interacted with
* (rather complete for block-interact checks, to skip subsequent
* block-break/place checks).
*/
private final Set<CheckType> passedChecks = new HashSet<CheckType>();
/**
* Checks that have been run and consume this event, i.e. can't be run again
* (not complete, may contain checks from other check groups).
*/
private final Set<CheckType> consumedChecks = new HashSet<CheckType>();
/**
* Set last interacted block (coordinates, type, tick). Also resets the
* passed checks.
*
* @param block
* @param action
*/
public void setLastBlock(final Block block, final Action action) {
lastTick = TickTask.getTick();
lastAction = action;
lastX = block.getX();
lastY = block.getY();
lastZ = block.getZ();
lastType = block.getType();
if (lastType == Material.AIR) {
lastType = null;
}
resetPassedChecks();
resetConsumedChecks();
}
/**
* Resets the last block (and passed checks).
*/
public void resetLastBlock() {
lastTick = 0;
lastAction = null;
lastX = Integer.MAX_VALUE;
lastType = null;
lastAllowUseBlock = false;
lastAllowUseItem = false;
lastIsCancelled = true;
resetPassedChecks();
resetConsumedChecks();
}
/**
* Reset passed checks (concern the last block interacted with).
*/
public void resetPassedChecks() {
passedChecks.clear();
}
/**
* Reset consumed checks (concern the last block interacted with).
*/
public void resetConsumedChecks() {
consumedChecks.clear();
}
/**
* Full state comparison.
*
* @param material
* null is treated as Material.AIR.
* @param action
* @param tick
* @param block
* @return
*/
public boolean matchesLastBlock(final Material material, final Action action, final int tick, final Block block) {
return lastX != Integer.MAX_VALUE && (material == lastType || material == null && lastType == Material.AIR)
&& matchesLastBlock(action, tick, block);
}
/**
* Compare action, tick and block.
*
* @param action
* @param tick
* @param block
* @return
*/
public boolean matchesLastBlock(final Action action, final int tick, final Block block) {
return lastX != Integer.MAX_VALUE && tick == lastTick && matchesLastBlock(action, block);
}
/**
* Compare only action and coordinates.
*
* @param action
* @param block
* @return
*/
public boolean matchesLastBlock(final Action action, final Block block) {
return lastX != Integer.MAX_VALUE && action == lastAction && matchesLastBlock(block);
}
/**
* Compare only tick and coordinates.
*
* @param tick
* @param block
* @return
*/
public boolean matchesLastBlock(final int tick, final Block block) {
return lastX != Integer.MAX_VALUE && tick == lastTick && matchesLastBlock(block);
}
/**
* Compare the block coordinates.
*
* @param block
* @return
*/
public boolean matchesLastBlock(final Block block) {
// Skip the MAX_VALUE check.
return lastX == block.getX() && lastY == block.getY() && lastZ == block.getZ();
}
/**
* The Manhattan distance to the set last block, Integer.MAX_VALUE is
* returned if none is set.
*
* @param block
* @return The Manhattan distance if appropriate - if no block is set,
* Integer.MAX_VALUE is returned.
*/
public int manhattanLastBlock(final Block block) {
return lastX == Integer.MAX_VALUE ? Integer.MAX_VALUE : TrigUtil.manhattan(lastX, lastY, lastZ,
block.getX(), block.getY(), block.getZ());
}
public boolean getLastAllowUseItem() {
return lastAllowUseItem;
}
public boolean getLastAllowUseBlock() {
return lastAllowUseBlock;
}
public boolean getLastIsCancelled() {
return lastIsCancelled;
}
/**
* Return the type of the block last interacted with. This does not check
* for invalidation.
*
* @return
*/
public Material getLastType() {
return lastType;
}
/**
* Get the tick of the last interaction with a block.
*
* @return
*/
public int getLastTick() {
return lastTick;
}
/**
* Get the action of the last interaction with a block.
*
* @return
*/
public Action getLastAction() {
return lastAction;
}
/**
* Set the check type to be passed for the last block.
*
* @param checkType
*/
public void addPassedCheck(final CheckType checkType) {
passedChecks.add(checkType);
}
/**
* Check if this check type was set as passed for the last block.
*
* @param checkType
* @return
*/
public boolean isPassedCheck(final CheckType checkType) {
return passedChecks.contains(checkType);
}
/**
*
* @return Unmodifiable collection.
*/
public Collection<CheckType> getPassedChecks() {
return Collections.unmodifiableCollection(passedChecks);
}
/**
* Check if the last block was set to be consumed by this check type.
*
* @param checkType
* @return
*/
public boolean isConsumedCheck(final CheckType checkType) {
return consumedChecks.contains(checkType);
}
/**
* Set last block to be consumed by the given check type.
*
* @param checkType
*/
public void addConsumedCheck(final CheckType checkType) {
consumedChecks.add(checkType);
}
/**
* Adjust to the results of a BlockInteractEvent - only the results, the
* coordinates and action is not updated.
*
* @param event
*/
public void setPlayerInteractEventResolution(final PlayerInteractEvent event) {
if (event.isCancelled()) {
// TODO: resetPassedChecks() ?
lastIsCancelled = true;
lastAllowUseItem = event.useItemInHand() == Result.ALLOW;
lastAllowUseBlock = event.useInteractedBlock() == Result.ALLOW;
subsequentCancel ++;
}
else {
lastIsCancelled = false;
lastAllowUseItem = event.useItemInHand() != Result.DENY;
lastAllowUseBlock = event.useInteractedBlock() != Result.DENY;
subsequentCancel = 0;
}
}
/**
* Allow overriding the last PlayerInteractEvent resolution.
*
* @param isCancelled
*/
public void setLastIsCancelled(final boolean isCancelled) {
this.lastIsCancelled = isCancelled;
}
/**
* Allow overriding the last PlayerInteractEvent resolution.
*
* @param allowUseItem
*/
public void setLastAllowUseItem(final boolean allowUseItem) {
this.lastAllowUseItem = allowUseItem;
}
/**
* Allow overriding the last PlayerInteractEvent resolution.
*
* @param allowUseBlock
*/
public void setLastAllowUseBlock(final boolean allowUseBlock) {
this.lastAllowUseBlock = allowUseBlock;
}
}