345 lines
9.9 KiB
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;
|
|
}
|
|
|
|
}
|