[BREAKING][BLEEDING] Adjust the API to the upcoming penalty framework.

This is a first step in, which doesn't change the default behavior,
however it might break plugins that rely on certain internals.

PenaltyAction allows to do something with probabilities to consider,
including the possibility to select the first applicable penalty or
applying several penalties. There will be player-specific penalties,
which are applied during ViolationData.executeActions always, and there
will be input-specific penalties, e.g. for applying within the event
listener.

Potentially breaking:
* Return value of executeActions is now void for Action + ViolationData.
* Return value of Check.executeActions is ViolationData now.
* CancelAction is now extending PenaltyAction.
* CancelPenalty may cancel, but might not, due to probability.
* IViolationInfo.hasCancel -> deprecated, now returns willCancel().
* IViolationInfo.willCancel is now used, applicable penalties are
estimated on creation of ViolationData.
* Custom actions can no longer be used to cause cancel. Only penalties
can do so now (due to the return type change). CancelAction is still
there to keep a simple action for canceling.

Not yet:
* InputSpecificPenalty support for fight checks and using them in the
default actions.
* Configuration for penalties (currently only a plugin could override
the action factories, later penalties may have a probability to apply,
reference each other, allow first match, apply several at once).
This commit is contained in:
asofold 2016-02-10 00:05:11 +01:00
parent 8d6b930166
commit 851203edb9
65 changed files with 1068 additions and 582 deletions

View File

@ -111,7 +111,7 @@ public class FastConsume extends Check implements Listener{
else{
vd.setParameter(ParameterName.TAGS, "");
}
if (executeActions(vd)){
if (executeActions(vd).willCancel()){
cancel = true;
}
}

View File

@ -37,7 +37,7 @@ public class Gutenberg extends Check implements Listener {
}
// Violation.
final int vl = pages - 50;
if (executeActions(player, vl, vl, cc.gutenbergActions)) {
if (executeActions(player, vl, vl, cc.gutenbergActions).willCancel()) {
event.setCancelled(true);
}
}

View File

@ -45,9 +45,8 @@ public abstract class Action <D extends ActionData, L extends AbstractActionList
*
* @param violationData
* the violation data
* @return true, if to cancel players actions, false otherwise. [SUBJECT TO REMOVAL]
*/
public abstract boolean execute(final D violationData);
public abstract void execute(final D violationData);
/**
* Check if parameters are needed at all for faster processing.

View File

@ -1,36 +1,41 @@
package fr.neatmonster.nocheatplus.actions.types;
import fr.neatmonster.nocheatplus.actions.AbstractActionList;
import fr.neatmonster.nocheatplus.actions.Action;
import fr.neatmonster.nocheatplus.actions.ActionData;
import fr.neatmonster.nocheatplus.actions.types.penalty.CancelPenalty;
import fr.neatmonster.nocheatplus.actions.types.penalty.Penalty;
import fr.neatmonster.nocheatplus.actions.types.penalty.PenaltyAction;
import fr.neatmonster.nocheatplus.actions.types.penalty.PenaltyNode;
/**
* Do something check-specific. Usually that is to cancel the event, undo something the player did, or do something the
* server should've done.
* Sole purpose is to indicate that an action is to be cancelled 100% (as
* opposed to a penalty with 30%cancel). This effects A cancel action might
* mean:
* <ul>
* <li>Cancel an event.</li>
* <li>Undo actions by players in some other way.</li>
* <li>Do something that should've been done (enforce).</li>
* </ul>
*/
public class CancelAction<D extends ActionData, L extends AbstractActionList<D, L>> extends Action<D, L> {
public class CancelAction<D extends ActionData, L extends AbstractActionList<D, L>> extends PenaltyAction<D, L> {
// TODO: Deprecate this (let it extend penalty.CancelAction)?
private static final Penalty cancelPenalty = new CancelPenalty();
private static final PenaltyNode node = new PenaltyNode(null, cancelPenalty);
/**
* Default cancel action.
*/
public CancelAction() {
this("cancel");
}
/**
* Sub-class constructor.
* @param name
*/
public CancelAction(String name) {
super(name, 0, 0);
super(null, node);
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.actions.Action#execute(fr.neatmonster.nocheatplus.checks.ViolationData)
*/
@Override
public boolean execute(final D data) {
return true;
public void execute(final D data) {
}
/* (non-Javadoc)

View File

@ -33,7 +33,7 @@ public class CommandAction<D extends ParameterHolder, L extends AbstractActionLi
* @see fr.neatmonster.nocheatplus.actions.Action#execute(fr.neatmonster.nocheatplus.checks.ViolationData)
*/
@Override
public boolean execute(final D violationData) {
public void execute(final D violationData) {
final String command = super.getMessage(violationData);
try {
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), command);
@ -43,7 +43,6 @@ public class CommandAction<D extends ParameterHolder, L extends AbstractActionLi
} catch (final Exception e) {
// I don't care in this case, your problem if your command fails.
}
return false;
}
/**

View File

@ -13,23 +13,22 @@ public class DummyAction<D extends ActionData, L extends AbstractActionList<D, L
/** The original string used for this action definition. */
protected final String definition;
/**
* Instantiates a new dummy.
*
* @param definition
* the definition
*/
public DummyAction(final String definition) {
super("dummyAction", 0, 0);
this.definition = definition;
}
/**
* Instantiates a new dummy.
*
* @param definition
* the definition
*/
public DummyAction(final String definition) {
super("dummyAction", 0, 0);
this.definition = definition;
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.actions.Action#execute(fr.neatmonster.nocheatplus.checks.ViolationData)
*/
@Override
public boolean execute(final D violationData) {
return false;
public void execute(final D violationData) {
}
/* (non-Javadoc)
@ -40,11 +39,11 @@ public class DummyAction<D extends ActionData, L extends AbstractActionList<D, L
return definition;
}
@Override
public Action<D, L> getOptimizedCopy(final ConfigFileWithActions<D, L> config, final Integer threshold)
{
// Never execute this.
return null;
}
@Override
public Action<D, L> getOptimizedCopy(final ConfigFileWithActions<D, L> config, final Integer threshold)
{
// Never execute this.
return null;
}
}

View File

@ -108,10 +108,10 @@ public class GenericLogAction extends ActionWithParameters<ViolationData, Action
}
@Override
public boolean execute(final ViolationData violationData) {
public void execute(final ViolationData violationData) {
// TODO: Consider permission caching or removing the feature? [Besides, check earlier?]
if (violationData.player.hasPermission(violationData.getPermissionSilent())) {
return false;
return;
}
final LogManager logManager = NCPAPIProvider.getNoCheatPlusAPI().getLogManager();
final String message = super.getMessage(violationData);
@ -125,7 +125,6 @@ public class GenericLogAction extends ActionWithParameters<ViolationData, Action
}
logManager.log(config.streamID, config.level, config.chatColor ? messageWithColor : messageNoColor);
}
return false;
}
/**

View File

@ -0,0 +1,70 @@
package fr.neatmonster.nocheatplus.actions.types.penalty;
import org.bukkit.entity.Player;
/**
* Convenience implementation for input-specific effects (other than Player).
*
* @author asofold
*
* @param <RI>
* The input type accepted by this penalty.
*/
public abstract class AbstractGenericPenalty<RI> implements GenericPenalty<RI> {
/** The input type accepted by this penalty. */
private final Class<RI> registeredInput;
public AbstractGenericPenalty(Class<RI> registeredInput) {
this.registeredInput = registeredInput;
}
/**
* Always has input-specific effects.
*/
@Override
public boolean hasInputSpecificEffects() {
return true;
}
@Override
public Class<RI> getRegisteredInput() {
return registeredInput;
}
/**
* (Override to use player-specific effects. Consider using
* AbstractPlayerPenalty instead, for simple player-specific-only
* penalties.)
*/
@Override
public boolean hasPlayerEffects() {
return false;
}
/**
* Override to use player-specific effects.
*/
@Override
public void apply(Player player) {
}
/**
* Implements isAssignableFrom test, to delegate to applyGenericEffects(RI).
*/
@SuppressWarnings("unchecked")
@Override
public void apply(Object input) {
if (registeredInput.isAssignableFrom(input.getClass())) {
applyGenericEffects((RI) input);
}
}
/**
* Override for implementation of input-specific effects.
*
* @param input
*/
abstract void applyGenericEffects(RI input);
}

View File

@ -0,0 +1,27 @@
package fr.neatmonster.nocheatplus.actions.types.penalty;
/**
* Minimal abstract implementation for player-specific effects.
* @author asofold
*
*/
public abstract class AbstractPlayerPenalty implements Penalty {
/**
* Always has player-specific effects.
*/
@Override
public boolean hasPlayerEffects() {
return true;
}
/**
* (Override to implement input-specific effects. Should prefer
* AbstractGenericPenalty instead, though.)
*/
@Override
public boolean hasInputSpecificEffects() {
return false;
}
}

View File

@ -0,0 +1,30 @@
package fr.neatmonster.nocheatplus.actions.types.penalty;
import org.bukkit.entity.Player;
/**
* This penalty does nothing. It's presence solely indicates that an action is
* to be canceled or rolled back.
*
* @author asofold
*
*/
public final class CancelPenalty implements Penalty {
// TODO: Consider putting a static instance somewhere instead (check with ==).
@Override
public final boolean hasPlayerEffects() {
return false;
}
@Override
public final boolean hasInputSpecificEffects() {
return false;
}
@Override
public final void apply(Player player) {
}
}

View File

@ -0,0 +1,20 @@
package fr.neatmonster.nocheatplus.actions.types.penalty;
/**
* Penalty for one type of input.
* @author asofold
*
* @param <RI>
*/
public interface GenericPenalty<RI> extends InputSpecificPenalty {
// TODO: Might directly put this into AbstractGenericPenalty.
/**
* Get the class that determines the accepted input type.
*
* @return
*/
public Class<RI> getRegisteredInput();
}

View File

@ -0,0 +1,16 @@
package fr.neatmonster.nocheatplus.actions.types.penalty;
public interface InputSpecificPenalty extends Penalty {
/**
* Apply the input-specific effects of a penalty, for other input than
* Player.
*
* @param input
* May be of unexpected type.
* @param registeredInput
*/
// TODO: Consider boolean result for "the input type was accepted", in order to detect if an input is not accepted by any generic penalty.
public void apply(Object input);
}

View File

@ -0,0 +1,45 @@
package fr.neatmonster.nocheatplus.actions.types.penalty;
import org.bukkit.entity.Player;
/**
* A simple static penalty. If this penalty applies must be determined
* externally (PenaltyAction).
*
* @author asofold
*
*/
public interface Penalty {
/**
* Effects that apply only to a player. Usually executed on
*
* @return
*/
public boolean hasPlayerEffects();
/**
* Test if there are input-specific effects, other than with Player instance
* input.
*
* @return If true, this instance must implement InputSpecificPenalty as
* well. Applying input specific penalties might only be possible
* within the surrounding context of creation of ViolationData, i.e.
* during the event handling. Input-specific effects will not apply
* within ViolationData.executeActions, be it within the TickTask
* (requestActionsExecution) or during handling a primary-thread
* check failure.
*/
public boolean hasInputSpecificEffects();
/**
* Apply player-specific effects. Executed within
* ViolationData.executeActions, extra to input-specific effects (likely
* before those, if within the primary thread, or within the TickTask for
* off-primary-thread checks).
*
* @param player
*/
public void apply(Player player);
}

View File

@ -0,0 +1,70 @@
package fr.neatmonster.nocheatplus.actions.types.penalty;
import java.util.Collection;
import fr.neatmonster.nocheatplus.actions.AbstractActionList;
import fr.neatmonster.nocheatplus.actions.Action;
import fr.neatmonster.nocheatplus.actions.ActionData;
/**
* Penalty action, referencing a certain penalty defined elsewhere. <br>
* Contained penalties are executed if passing the probability test, possibly in
* an uncertain order, concerning:
* <ul>
* <li>Cancel penalties are always directly evaluated and applied to the context
* of checking, e.g. the event that is being processed.</li>
* <li>
* Player-specific penalties are always executed within
* ViolationData.executeActions in the primary thread. Note that for
* off-primary-thread checks, this will be within the the TickTask.</li>
* <li>Penalties that need specific extra input might be processed in different
* places, e.g. the event listener, likely after executeActions has been called,
* no guarantee.</li>
* </ul>
*
* @author asofold
*
* @param <D>
* @param <L>
*/
public class PenaltyAction<D extends ActionData, L extends AbstractActionList<D, L>> extends Action<D, L> {
private final PenaltyNode rootNode;
private final String penaltyId;
/**
*
* @param penaltyId
* If null, toString should be overridden.
* @param rootNode
*/
public PenaltyAction(String penaltyId, PenaltyNode rootNode) {
// TODO: name vs toString (!).
super("penalty", 0, 0);
this.rootNode = rootNode;
this.penaltyId = penaltyId;
}
/**
* Fill in applicable penalties to results.
*
* @param results
*/
public void evaluate(final Collection<Penalty> results) {
if (this.rootNode != null) {
this.rootNode.evaluate(results);
}
}
@Override
public void execute(D violationData) {
// Does nothing (!).
}
@Override
public String toString() {
return "penalty:" + penaltyId;
}
}

View File

@ -0,0 +1,92 @@
package fr.neatmonster.nocheatplus.actions.types.penalty;
import java.util.Collection;
import java.util.Random;
/**
* Internal data representation, managing probabilities, and complex decisions
* with multiple penalties.
*
* @author asofold
*
*/
public class PenaltyNode {
// TODO: Might switch to float for probability or not?
// TODO: Might add a parsing method (recursive).
/** Random instance to use. May be null, in case probability is 1. */
private final Random random;
/** The probability for this node to apply. */
public final double probability;
/** Penalty to apply when this node applies. */
private final Penalty penalty;
/** Child nodes to test when this node applies. */
private final PenaltyNode[] childNodes;
/** Indicate that the result is set with the first child node that applies. */
private final boolean abortOnApply;
/**
* Convenience: Simple penalty that always applies with no child nodes.
* @param random
* @param probability
* @param penalty
*/
public PenaltyNode(Random random, Penalty penalty) {
this(random, 1.0, penalty, null, false);
}
/**
* Convenience: Simple penalty with no child nodes.
* @param random
* @param probability
* @param penalty
*/
public PenaltyNode(Random random, double probability, Penalty penalty) {
this(random, probability, penalty, null, false);
}
/**
*
* @param random
* @param probability
* @param penalty
* @param childNodes
* May be null.
* @param abortOnApply
*/
public PenaltyNode(Random random, double probability, Penalty penalty, Collection<PenaltyNode> childNodes, boolean abortOnApply) {
this.random = random;
this.probability = probability;
this.penalty = penalty;
this.childNodes = childNodes == null ? new PenaltyNode[0] : childNodes.toArray(new PenaltyNode[childNodes.size()]);
this.abortOnApply = abortOnApply;
}
/**
* On the spot evaluation of an applicable path, filling in all applicable
* penalties into the results collection. This does test
*
* @param results
* @return If this node applies (, which does not necessarily mean that
* anything has been appended to results).
*/
public boolean evaluate(final Collection<Penalty> results) {
if (probability < 1.0 && random.nextDouble() > probability) {
// This node does not apply
return false;
}
if (penalty != null) {
results.add(penalty);
}
for (int i = 0 ; i < childNodes.length; i++) {
if (childNodes[i].evaluate(results) && abortOnApply) {
break;
}
}
return true;
}
}

View File

@ -0,0 +1,18 @@
package fr.neatmonster.nocheatplus.actions.types.penalty.fight;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import fr.neatmonster.nocheatplus.actions.types.penalty.AbstractGenericPenalty;
/**
* Fight penalties usually use EntityDamageByEntityEvent.
* @author asofold
*
*/
public abstract class FightPenaltyEDE extends AbstractGenericPenalty<EntityDamageByEntityEvent> {
public FightPenaltyEDE() {
super(EntityDamageByEntityEvent.class);
}
}

View File

@ -104,10 +104,10 @@ public abstract class Check implements MCAccessHolder {
* the actions
* @param isMainThread
* if the thread the main thread
* @return true, if successful
* @return The ViolationData instance that is created for execution of
* actions.
*/
public boolean executeActions(final Player player, final double vL, final double addedVL, final ActionList actions) {
// Sync it into the main thread by using an event.
public ViolationData executeActions(final Player player, final double vL, final double addedVL, final ActionList actions) {
return executeActions(new ViolationData(this, player, vL, addedVL, actions));
}
@ -116,28 +116,26 @@ public abstract class Check implements MCAccessHolder {
*
* @param violationData
* the violation data
* @return true, if the event should be cancelled
* @return The ViolationData instanced passed to this method.
*/
public boolean executeActions(final ViolationData violationData) {
public ViolationData executeActions(final ViolationData violationData) {
// Dispatch the VL processing to the hook manager (now thread safe).
if (NCPHookManager.shouldCancelVLProcessing(violationData)) {
// One of the hooks has decided to cancel the VL processing, return false.
return false;
violationData.preventCancel();
}
final boolean hasCancel = violationData.hasCancel();
if (Bukkit.isPrimaryThread()) {
return violationData.executeActions();
else if (Bukkit.isPrimaryThread()) {
violationData.executeActions();
}
else {
// Always schedule to add to ViolationHistory.
// TODO: Might clear input-specific effects (stored ones will be handled extra to those).
TickTask.requestActionsExecution(violationData);
}
// (Design change: Permission checks are moved to cached permissions, lazily updated.)
return hasCancel;
// (Permission checks are moved to cached permissions, lazily updated.)
return violationData;
}
/**

View File

@ -1,5 +1,6 @@
package fr.neatmonster.nocheatplus.checks;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@ -11,6 +12,10 @@ import fr.neatmonster.nocheatplus.actions.ActionList;
import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.actions.types.CancelAction;
import fr.neatmonster.nocheatplus.actions.types.GenericLogAction;
import fr.neatmonster.nocheatplus.actions.types.penalty.CancelPenalty;
import fr.neatmonster.nocheatplus.actions.types.penalty.InputSpecificPenalty;
import fr.neatmonster.nocheatplus.actions.types.penalty.Penalty;
import fr.neatmonster.nocheatplus.actions.types.penalty.PenaltyAction;
import fr.neatmonster.nocheatplus.checks.access.IViolationInfo;
import fr.neatmonster.nocheatplus.compat.BridgeHealth;
import fr.neatmonster.nocheatplus.logging.StaticLog;
@ -25,6 +30,8 @@ import fr.neatmonster.nocheatplus.logging.StreamID;
*/
public class ViolationData implements IViolationInfo, ActionData {
// TODO:
/** The actions to be executed. */
public final ActionList actions;
@ -48,6 +55,13 @@ public class ViolationData implements IViolationInfo, ActionData {
private boolean needsParameters = false;
private boolean willCancel;
/** hasPlayerEffects returned true. */
private ArrayList<Penalty> playerPenalties = null;
/** hasInputSpecificEffects returned true. */
private ArrayList<InputSpecificPenalty> inputSpecificPenalties = null;
/**
* Instantiates a new violation data.
* <hr>
@ -71,17 +85,93 @@ public class ViolationData implements IViolationInfo, ActionData {
this.vL = vL;
this.addedVL = addedVL;
this.actions = actions;
this.applicableActions = actions.getActions(vL);
this.applicableActions = actions.getActions(vL); // TODO: Consider storing applicableActions only if history wants it.
boolean needsParameters = false;
final ArrayList<Penalty> applicablePenalties = new ArrayList<Penalty>();
for (int i = 0; i < applicableActions.length; i++) {
if (applicableActions[i].needsParameters()) {
final Action<ViolationData, ActionList> action = applicableActions[i];
if (!needsParameters && action.needsParameters()) {
needsParameters = true;
break;
}
if (action instanceof PenaltyAction) {
if (action instanceof CancelAction) {
// Shortcut for 100%cancel, no other effects are allowed with this one.
willCancel = true;
}
else {
// Add applicable penalties for this action.
((PenaltyAction<ViolationData, ActionList>) action).evaluate(applicablePenalties);
}
}
}
this.needsParameters = needsParameters;
// Evaluate applicablePenalties, if any.
if (!applicablePenalties.isEmpty()) {
evaluateApplicablePenalties(applicablePenalties);
}
}
/**
* Evaluate applicable penalties for cancel and types of penalties.
*
* @param applicablePenalties
*/
private void evaluateApplicablePenalties(final ArrayList<Penalty> applicablePenalties) {
for (int i = 0; i < applicablePenalties.size(); i++) {
final Penalty penalty = applicablePenalties.get(i);
if (penalty instanceof CancelPenalty) {
// Other effects are not evaluated.
// TODO: Might go for a static thing and ==.
willCancel = true;
}
else {
// Add to the appropriate lists.
if (penalty.hasPlayerEffects()) {
if (playerPenalties == null) {
playerPenalties = new ArrayList<Penalty>();
}
playerPenalties.add(penalty);
}
if (penalty.hasInputSpecificEffects()) {
if (inputSpecificPenalties == null) {
inputSpecificPenalties = new ArrayList<InputSpecificPenalty>();
}
inputSpecificPenalties.add((InputSpecificPenalty) penalty);
}
}
}
}
/**
* Call with a specific input (obviously not meant for vast number of
* penalties and/or a a vast number of calls with differing input types).
*
* @param input
*/
public void applyInputSpecificPenalties(final Object input) {
if (inputSpecificPenalties == null) {
return;
}
for (int i = 0; i < inputSpecificPenalties.size(); i++) {
inputSpecificPenalties.get(i).apply(input);
}
}
@Override
public boolean willCancel() {
return willCancel;
}
/**
* Override willCancel.
*/
public void preventCancel() {
willCancel = false;
}
/**
* Gets the actions.
*
@ -92,45 +182,45 @@ public class ViolationData implements IViolationInfo, ActionData {
}
/**
* Execute actions and return if cancel. Does add it to history.
* Execute actions and apply player-specific penalties. Does add to history.
*
* @return
*/
public boolean executeActions() {
public void executeActions() {
// TODO: Still can return boolean for cancel, as it should've been evaluated on creation of ViolationData.
// TODO: Might be better to return ViolationData, for penalty effects etc.
try {
// Statistics.
ViolationHistory.getHistory(player).log(check.getClass().getName(), addedVL);
// TODO: the time is taken here, which makes sense for delay, but otherwise ?
final long time = System.currentTimeMillis() / 1000L;
boolean cancel = false;
for (final Action<ViolationData, ActionList> action : getActions()) {
// Execute actions, if history wants it. TODO: Consider storing applicableActions only if history wants it.
for (final Action<ViolationData, ActionList> action : applicableActions) {
if (Check.getHistory(player).executeAction(this, action, time)) {
// The execution history said it really is time to execute the action, find out what it is and do
// what is needed.
if (action.execute(this)) {
cancel = true;
}
action.execute(this); // TODO: Add history as argument rather.
}
}
// Apply player penalties.
if (playerPenalties != null) {
for (int i = 0; i < playerPenalties.size(); i++) {
playerPenalties.get(i).apply(player);
}
}
return cancel;
} catch (final Exception e) {
StaticLog.logSevere(e);
// On exceptions cancel events.
return true;
willCancel = true;
}
}
/**
* Check if the actions contain a cancel.
* @return
*/
@Override
@Deprecated
public boolean hasCancel() {
for (final Action<ViolationData, ActionList> action : applicableActions) {
if (action instanceof CancelAction) {
return true;
}
}
return false;
return willCancel();
}
@Override

View File

@ -26,11 +26,21 @@ public interface IViolationInfo extends ParameterHolder {
public double getTotalVl();
/**
* Check if the actions contain a cancel action.
* Check if a cancel would happen.
*
* @return
* @deprecated The concept of cancel has been changed to be contained in
* penalties, use willCancel instead.
*/
public boolean hasCancel();
/**
* Test, if the evaluation of penalties will lead to canceling. This may be
* overridden, if violation processing is cancelled by a hook.
*
* @return
*/
public boolean hasCancel();
public boolean willCancel();
/**
* Test if there is any instances of (Generic)LogAction set in the

View File

@ -13,9 +13,9 @@ import fr.neatmonster.nocheatplus.utilities.TrigUtil;
* The Direction check will find out if a player tried to interact with something that's not in their field of view.
*/
public class Direction extends Check {
/** For temporary use: LocUtil.clone before passing deeply, call setWorld(null) after use. */
private final Location useLoc = new Location(null, 0, 0, 0);
/** For temporary use: LocUtil.clone before passing deeply, call setWorld(null) after use. */
private final Location useLoc = new Location(null, 0, 0, 0);
/**
* Instantiates a new direction check.
@ -53,8 +53,7 @@ public class Direction extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.directionVL, distance,
BlockBreakConfig.getConfig(player).directionActions);
cancel = executeActions(player, data.directionVL, distance, BlockBreakConfig.getConfig(player).directionActions).willCancel();
} else {
// Player did likely nothing wrong, reduce violation counter to reward them.
data.directionVL *= 0.9D;

View File

@ -42,88 +42,88 @@ public class FastBreak extends Check {
* @return true, if successful
*/
public boolean check(final Player player, final Block block, final AlmostBoolean isInstaBreak, final BlockBreakConfig cc, final BlockBreakData data) {
final long now = System.currentTimeMillis();
final long now = System.currentTimeMillis();
boolean cancel = false;
// Determine expected breaking time by block type.
final Material blockType = block.getType();
final long expectedBreakingTime = Math.max(0, Math.round((double) BlockProperties.getBreakingDuration(blockType, player) * (double) cc.fastBreakModSurvival / 100D));
final long elapsedTime;
// TODO: Concept for unbreakable blocks? Context: extreme VL.
// TODO: Should it be breakingTime instead of 0 for inconsistencies?
if (cc.fastBreakStrict) {
// Counting interact...break.
elapsedTime = (data.fastBreakBreakTime > data.fastBreakfirstDamage) ? 0 : now - data.fastBreakfirstDamage;
// Counting interact...break.
elapsedTime = (data.fastBreakBreakTime > data.fastBreakfirstDamage) ? 0 : now - data.fastBreakfirstDamage;
}
else {
// Counting break...break.
elapsedTime = (data.fastBreakBreakTime > now) ? 0 : now - data.fastBreakBreakTime;
// Counting break...break.
elapsedTime = (data.fastBreakBreakTime > now) ? 0 : now - data.fastBreakBreakTime;
}
// Check if the time used time is lower than expected.
if (isInstaBreak.decideOptimistically()) {
// Ignore those for now.
// TODO: Find out why this was commented out long ago a) did not fix mcMMO b) exploits.
// TODO: Maybe adjust time to min(time, SOMETHING) for MAYBE/YES.
// Ignore those for now.
// TODO: Find out why this was commented out long ago a) did not fix mcMMO b) exploits.
// TODO: Maybe adjust time to min(time, SOMETHING) for MAYBE/YES.
}
else if (elapsedTime < 0) {
// Ignore it. TODO: ?
// Ignore it. TODO: ?
}
else if (elapsedTime + cc.fastBreakDelay < expectedBreakingTime) {
// lag or cheat or Minecraft.
// Count in server side lag, if desired.
final float lag = cc.lag ? TickTask.getLag(expectedBreakingTime, true) : 1f;
final long missingTime = expectedBreakingTime - (long) (lag * elapsedTime);
if (missingTime > 0) {
// Add as penalty
data.fastBreakPenalties.add(now, (float) missingTime);
// lag or cheat or Minecraft.
// Count in server side lag, if desired.
final float lag = cc.lag ? TickTask.getLag(expectedBreakingTime, true) : 1f;
final long missingTime = expectedBreakingTime - (long) (lag * elapsedTime);
if (missingTime > 0) {
// Add as penalty
data.fastBreakPenalties.add(now, (float) missingTime);
// Only raise a violation, if the total penalty score exceeds the contention duration (for lag, delay).
if (data.fastBreakPenalties.score(cc.fastBreakBucketFactor) > cc.fastBreakGrace) {
// TODO: maybe add one absolute penalty time for big amounts to stop breaking until then
final double vlAdded = (double) missingTime / 1000.0;
data.fastBreakVL += vlAdded;
final ViolationData vd = new ViolationData(this, player, data.fastBreakVL, vlAdded, cc.fastBreakActions);
if (vd.needsParameters()) {
vd.setParameter(ParameterName.BLOCK_TYPE, blockType.toString());
vd.setParameter(ParameterName.BLOCK_ID, Integer.toString(BlockProperties.getId(blockType)));
}
cancel = executeActions(vd).willCancel();
}
// else: still within contention limits.
}
}
else if (expectedBreakingTime > cc.fastBreakDelay) {
// Fast breaking does not decrease violation level.
data.fastBreakVL *= 0.9D;
}
// Only raise a violation, if the total penalty score exceeds the contention duration (for lag, delay).
if (data.fastBreakPenalties.score(cc.fastBreakBucketFactor) > cc.fastBreakGrace) {
// TODO: maybe add one absolute penalty time for big amounts to stop breaking until then
final double vlAdded = (double) missingTime / 1000.0;
data.fastBreakVL += vlAdded;
final ViolationData vd = new ViolationData(this, player, data.fastBreakVL, vlAdded, cc.fastBreakActions);
if (vd.needsParameters()) {
vd.setParameter(ParameterName.BLOCK_TYPE, blockType.toString());
vd.setParameter(ParameterName.BLOCK_ID, Integer.toString(BlockProperties.getId(blockType)));
}
cancel = executeActions(vd);
}
// else: still within contention limits.
}
}
else if (expectedBreakingTime > cc.fastBreakDelay) {
// Fast breaking does not decrease violation level.
data.fastBreakVL *= 0.9D;
}
if ((data.debug) && player.hasPermission(Permissions.ADMINISTRATION_DEBUG)) {
// General stats:
if (data.stats != null) {
// General stats:
if (data.stats != null) {
data.stats.addStats(data.stats.getId(blockType+ "/u", true), elapsedTime);
data.stats.addStats(data.stats.getId(blockType + "/r", true), expectedBreakingTime);
player.sendMessage(data.stats.getStatsStr(true));
}
// Send info about current break:
final ItemStack stack = player.getItemInHand();
final boolean isValidTool = BlockProperties.isValidTool(blockType, stack);
final double haste = PotionUtil.getPotionEffectAmplifier(player, PotionEffectType.FAST_DIGGING);
String msg = (isInstaBreak.decideOptimistically() ? ("[Insta=" + isInstaBreak + "]") : "[Normal]") + "[" + blockType + "] "+ elapsedTime + "u / " + expectedBreakingTime +"r (" + (isValidTool?"tool":"no-tool") + ")" + (haste == Double.NEGATIVE_INFINITY ? "" : " haste=" + ((int) haste + 1));
player.sendMessage(msg);
// net.minecraft.server.Item mcItem = net.minecraft.server.Item.byId[stack.getTypeId()];
// if (mcItem != null) {
// double x = mcItem.getDestroySpeed(((CraftItemStack) stack).getHandle(), net.minecraft.server.Block.byId[blockId]);
// player.sendMessage("mc speed: " + x);
// }
// Send info about current break:
final ItemStack stack = player.getItemInHand();
final boolean isValidTool = BlockProperties.isValidTool(blockType, stack);
final double haste = PotionUtil.getPotionEffectAmplifier(player, PotionEffectType.FAST_DIGGING);
String msg = (isInstaBreak.decideOptimistically() ? ("[Insta=" + isInstaBreak + "]") : "[Normal]") + "[" + blockType + "] "+ elapsedTime + "u / " + expectedBreakingTime +"r (" + (isValidTool?"tool":"no-tool") + ")" + (haste == Double.NEGATIVE_INFINITY ? "" : " haste=" + ((int) haste + 1));
player.sendMessage(msg);
// net.minecraft.server.Item mcItem = net.minecraft.server.Item.byId[stack.getTypeId()];
// if (mcItem != null) {
// double x = mcItem.getDestroySpeed(((CraftItemStack) stack).getHandle(), net.minecraft.server.Block.byId[blockId]);
// player.sendMessage("mc speed: " + x);
// }
}
// (The break time is set in the listener).
// (The break time is set in the listener).
return cancel;
}

View File

@ -14,67 +14,68 @@ import fr.neatmonster.nocheatplus.utilities.TickTask;
*/
public class Frequency extends Check {
public Frequency() {
super(CheckType.BLOCKBREAK_FREQUENCY);
}
public boolean check(final Player player, final BlockBreakConfig cc, final BlockBreakData data){
public Frequency() {
super(CheckType.BLOCKBREAK_FREQUENCY);
}
public boolean check(final Player player, final BlockBreakConfig cc, final BlockBreakData data){
final float interval = (float) ((player.getGameMode() == GameMode.CREATIVE)?(cc.frequencyIntervalCreative):(cc.frequencyIntervalSurvival));
data.frequencyBuckets.add(System.currentTimeMillis(), interval);
// Full period frequency.
final float fullScore = data.frequencyBuckets.score(cc.frequencyBucketFactor);
final long fullTime = cc.frequencyBucketDur * cc.frequencyBuckets;
// Short term arrivals.
final int tick = TickTask.getTick();
if (tick < data.frequencyShortTermTick){
// Tick task got reset.
data.frequencyShortTermTick = tick;
data.frequencyShortTermCount = 1;
// Tick task got reset.
data.frequencyShortTermTick = tick;
data.frequencyShortTermCount = 1;
}
else if (tick - data.frequencyShortTermTick < cc.frequencyShortTermTicks){
// Account for server side lag.
final float stLag = cc.lag ? TickTask.getLag(50L * (tick - data.frequencyShortTermTick), true) : 1f;
if (stLag < 1.5){
// Within range, add.
data.frequencyShortTermCount ++;
}
else{
// Too much lag, reset.
data.frequencyShortTermTick = tick;
data.frequencyShortTermCount = 1;
}
// Account for server side lag.
final float stLag = cc.lag ? TickTask.getLag(50L * (tick - data.frequencyShortTermTick), true) : 1f;
if (stLag < 1.5){
// Within range, add.
data.frequencyShortTermCount ++;
}
else{
// Too much lag, reset.
data.frequencyShortTermTick = tick;
data.frequencyShortTermCount = 1;
}
}
else{
data.frequencyShortTermTick = tick;
data.frequencyShortTermCount = 1;
data.frequencyShortTermTick = tick;
data.frequencyShortTermCount = 1;
}
// Account for server side lag.
final float fullLag = cc.lag ? TickTask.getLag(fullTime, true) : 1f;
// Find if one of both or both are violations:
final float fullViolation = (fullScore > fullTime * fullLag) ? (fullScore - fullTime * fullLag) : 0;
final float shortTermWeight = 50f * cc.frequencyShortTermTicks / (float) cc.frequencyShortTermLimit;
final float shortTermViolation = (data.frequencyShortTermCount > cc.frequencyShortTermLimit)
? (data.frequencyShortTermCount - cc.frequencyShortTermLimit) * shortTermWeight : 0;
final float violation = Math.max(fullViolation, shortTermViolation);
boolean cancel = false;
if (violation > 0){
// TODO: account for lag spikes !
final double change = violation / 1000;
data.frequencyVL += change;
cancel = executeActions(player, data.frequencyVL, change, cc.frequencyActions);
}
else if (data.frequencyVL > 0d && fullScore < fullTime * .75)
data.frequencyVL *= 0.95;
return cancel;
}
? (data.frequencyShortTermCount - cc.frequencyShortTermLimit) * shortTermWeight : 0;
// TODO: AUTO INDENT?
final float violation = Math.max(fullViolation, shortTermViolation);
boolean cancel = false;
if (violation > 0f){
// TODO: account for lag spikes !
final double change = violation / 1000;
data.frequencyVL += change;
cancel = executeActions(player, data.frequencyVL, change, cc.frequencyActions).willCancel();
}
else if (data.frequencyVL > 0d && fullScore < fullTime * .75)
data.frequencyVL *= 0.95;
return cancel;
}
}

View File

@ -40,7 +40,7 @@ public class NoSwing extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.noSwingVL, 1D, BlockBreakConfig.getConfig(player).noSwingActions);
cancel = executeActions(player, data.noSwingVL, 1D, BlockBreakConfig.getConfig(player).noSwingActions).willCancel();
}
return cancel;

View File

@ -65,7 +65,7 @@ public class Reach extends Check {
// cancel the event.
final ViolationData vd = new ViolationData(this, player, data.reachVL, distance, BlockBreakConfig.getConfig(player).reachActions);
vd.setParameter(ParameterName.REACH_DISTANCE, String.valueOf(Math.round(data.reachDistance)));
cancel = executeActions(vd);
cancel = executeActions(vd).willCancel();
} else{
// Player passed the check, reward them.
data.reachVL *= 0.9D;

View File

@ -12,69 +12,69 @@ import fr.neatmonster.nocheatplus.utilities.TrigUtil;
public class WrongBlock extends Check {
public WrongBlock() {
super(CheckType.BLOCKBREAK_WRONGBLOCK);
}
/**
* Check if the player destroys another block than interacted with last.<br>
* This does occasionally trigger for players that destroy grass or snow,
* probably due to packet delaying issues for insta breaking.
* @param player
* @param block
* @param data
* @param cc
* @param isInstaBreak
* @return
*/
public boolean check(final Player player, final Block block, final BlockBreakConfig cc, final BlockBreakData data, final AlmostBoolean isInstaBreak) {
public WrongBlock() {
super(CheckType.BLOCKBREAK_WRONGBLOCK);
}
/**
* Check if the player destroys another block than interacted with last.<br>
* This does occasionally trigger for players that destroy grass or snow,
* probably due to packet delaying issues for insta breaking.
* @param player
* @param block
* @param data
* @param cc
* @param isInstaBreak
* @return
*/
public boolean check(final Player player, final Block block, final BlockBreakConfig cc, final BlockBreakData data, final AlmostBoolean isInstaBreak) {
boolean cancel = false;
final boolean wrongTime = data.fastBreakfirstDamage < data.fastBreakBreakTime;
final int dist = Math.min(4, data.clickedX == Integer.MAX_VALUE ? 100 : TrigUtil.manhattan(data.clickedX, data.clickedY, data.clickedZ, block));
final boolean wrongBlock;
final long now = System.currentTimeMillis();
// TODO: Remove isInstaBreak argument or use it.
if (dist == 0) {
if (wrongTime) {
data.fastBreakBreakTime = now;
data.fastBreakfirstDamage = now;
// Could set to wrong block, but prefer to transform it into a quasi insta break.
}
wrongBlock = false;
if (wrongTime) {
data.fastBreakBreakTime = now;
data.fastBreakfirstDamage = now;
// Could set to wrong block, but prefer to transform it into a quasi insta break.
}
wrongBlock = false;
}
else if (dist == 1) {
// One might to a concession in case of instant breaking.
if (now - data.wasInstaBreak < 60) {
wrongBlock = false;
}
else {
wrongBlock = true;
}
// One might to a concession in case of instant breaking.
if (now - data.wasInstaBreak < 60) {
wrongBlock = false;
}
else {
wrongBlock = true;
}
}
else {
// Note that the maximally counted distance is set above.
wrongBlock = true;
// Note that the maximally counted distance is set above.
wrongBlock = true;
}
if (wrongBlock) {
if ((data.debug) && player.hasPermission(Permissions.ADMINISTRATION_DEBUG)) {
player.sendMessage("WrongBlock failure with dist: " + dist);
}
data.wrongBlockVL.add(now, (float) (dist + 1) / 2f);
final float score = data.wrongBlockVL.score(0.9f);
if (score > cc.wrongBLockLevel) {
if (executeActions(player, score, 1D, cc.wrongBlockActions)) {
cancel = true;
}
if (Improbable.check(player, 2.0f, now, "blockbreak.wrongblock")) {
cancel = true;
}
}
if ((data.debug) && player.hasPermission(Permissions.ADMINISTRATION_DEBUG)) {
player.sendMessage("WrongBlock failure with dist: " + dist);
}
data.wrongBlockVL.add(now, (float) (dist + 1) / 2f);
final float score = data.wrongBlockVL.score(0.9f);
if (score > cc.wrongBLockLevel) {
if (executeActions(player, score, 1D, cc.wrongBlockActions).willCancel()) {
cancel = true;
}
if (Improbable.check(player, 2.0f, now, "blockbreak.wrongblock")) {
cancel = true;
}
}
}
return cancel;
}
}
}

View File

@ -46,12 +46,12 @@ public class Direction extends Check {
// Add the overall violation level of the check.
data.directionVL += distance;
// TODO: Set distance parameter.
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.directionVL, distance, cc.directionActions);
cancel = executeActions(player, data.directionVL, distance, cc.directionActions).willCancel();
} else
// Player did likely nothing wrong, reduce violation counter to reward them.
data.directionVL *= 0.9D;

View File

@ -59,12 +59,12 @@ public class Reach extends Check {
// cancel the event.
final ViolationData vd = new ViolationData(this, player, data.reachVL, distance, cc.reachActions);
vd.setParameter(ParameterName.REACH_DISTANCE, String.valueOf(Math.round(data.reachDistance)));
cancel = executeActions(vd);
cancel = executeActions(vd).willCancel();
} else
// Player passed the check, reward them.
data.reachVL *= 0.9D;
return cancel;
}
}

View File

@ -31,7 +31,7 @@ public class Speed extends Check {
final int correctedCount = (int) ((double) data.speedCount / TickTask.getLag(time - data.speedTime, true));
if (correctedCount > cc.speedLimit){
data.speedVL ++;
if (executeActions(player, data.speedVL, 1, cc.speedActions)){
if (executeActions(player, data.speedVL, 1, cc.speedActions).willCancel()){
cancel = true;
}
}

View File

@ -143,7 +143,7 @@ public class Visible extends Check {
// // TODO: Consider adding the start/end/block-type information if debug is set.
// vd.setParameter(ParameterName.TAGS, StringUtil.join(tags, "+"));
// }
if (executeActions(vd)) {
if (executeActions(vd).willCancel()) {
cancel = true;
}
}

View File

@ -55,7 +55,7 @@ public class Against extends Check {
final ViolationData vd = new ViolationData(this, player, data.againstVL, 1, cc.againstActions);
vd.setParameter(ParameterName.BLOCK_TYPE, placedMat.toString());
vd.setParameter(ParameterName.BLOCK_ID, Integer.toString(BlockProperties.getId(placedMat)));
return executeActions(vd);
return executeActions(vd).willCancel();
} else {
data.againstVL *= 0.99; // Assume one false positive every 100 blocks.
return false;

View File

@ -110,8 +110,7 @@ public class AutoSign extends Check {
if (vd.needsParameters()){
vd.setParameter(ParameterName.TAGS, StringUtil.join(tags, "+"));
}
return executeActions(vd);
return executeActions(vd).willCancel();
}
}

View File

@ -13,9 +13,9 @@ import fr.neatmonster.nocheatplus.utilities.TrigUtil;
* The Direction check will find out if a player tried to interact with something that's not in their field of view.
*/
public class Direction extends Check {
/** For temporary use: LocUtil.clone before passing deeply, call setWorld(null) after use. */
private final Location useLoc = new Location(null, 0, 0, 0);
/** For temporary use: LocUtil.clone before passing deeply, call setWorld(null) after use. */
private final Location useLoc = new Location(null, 0, 0, 0);
/**
* Instantiates a new direction check.
@ -77,7 +77,7 @@ public class Direction extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.directionVL, distance, cc.directionActions);
cancel = executeActions(player, data.directionVL, distance, cc.directionActions).willCancel();
} else {
// Player did likely nothing wrong, reduce violation counter to reward them.
data.directionVL *= 0.9D;

View File

@ -32,62 +32,62 @@ public class FastPlace extends Check {
public boolean check(final Player player, final Block block, final BlockPlaceData data, final BlockPlaceConfig cc) {
data.fastPlaceBuckets.add(System.currentTimeMillis(), 1f);
// Full period frequency.
final float fullScore = data.fastPlaceBuckets.score(1f);
// Short term arrivals.
final int tick = TickTask.getTick();
if (tick < data.fastPlaceShortTermTick ) {
// TickTask got reset.
data.fastPlaceShortTermTick = tick;
data.fastPlaceShortTermCount = 1;
// TickTask got reset.
data.fastPlaceShortTermTick = tick;
data.fastPlaceShortTermCount = 1;
}
else if (tick - data.fastPlaceShortTermTick < cc.fastPlaceShortTermTicks){
// Account for server side lag.
if (!cc.lag || TickTask.getLag(50L * (tick - data.fastPlaceShortTermTick), true) < 1.2f){
// Within range, add.
data.fastPlaceShortTermCount ++;
}
else{
// Too much lag, reset.
data.fastPlaceShortTermTick = tick;
data.fastPlaceShortTermCount = 1;
}
// Account for server side lag.
if (!cc.lag || TickTask.getLag(50L * (tick - data.fastPlaceShortTermTick), true) < 1.2f){
// Within range, add.
data.fastPlaceShortTermCount ++;
}
else{
// Too much lag, reset.
data.fastPlaceShortTermTick = tick;
data.fastPlaceShortTermCount = 1;
}
}
else{
data.fastPlaceShortTermTick = tick;
data.fastPlaceShortTermCount = 1;
data.fastPlaceShortTermTick = tick;
data.fastPlaceShortTermCount = 1;
}
// Find if one of both or both are violations:
final float fullViolation;
if (fullScore > cc.fastPlaceLimit) {
// Account for server side lag.
if (cc.lag) {
fullViolation = fullScore / TickTask.getLag(data.fastPlaceBuckets.bucketDuration() * data.fastPlaceBuckets.numberOfBuckets(), true) - cc.fastPlaceLimit;
}
else{
fullViolation = fullScore - cc.fastPlaceLimit;
}
// Account for server side lag.
if (cc.lag) {
fullViolation = fullScore / TickTask.getLag(data.fastPlaceBuckets.bucketDuration() * data.fastPlaceBuckets.numberOfBuckets(), true) - cc.fastPlaceLimit;
}
else{
fullViolation = fullScore - cc.fastPlaceLimit;
}
}
else{
fullViolation = 0;
fullViolation = 0;
}
final float shortTermViolation = data.fastPlaceShortTermCount - cc.fastPlaceShortTermLimit;
final float violation = Math.max(fullViolation, shortTermViolation);
boolean cancel = false;
if (violation > 0f) {
final double change = (double) violation;
data.fastPlaceVL += change;
cancel = executeActions(player, data.fastPlaceVL, change, cc.fastPlaceActions);
final double change = (double) violation;
data.fastPlaceVL += change;
cancel = executeActions(player, data.fastPlaceVL, change, cc.fastPlaceActions).willCancel();
}
else if (data.fastPlaceVL > 0d && fullScore < cc.fastPlaceLimit * .75) {
data.fastPlaceVL *= 0.95;
data.fastPlaceVL *= 0.95;
}
return cancel;
return cancel;
}
}

View File

@ -42,7 +42,7 @@ public class NoSwing extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.noSwingVL, 1D, cc.noSwingActions);
cancel = executeActions(player, data.noSwingVL, 1D, cc.noSwingActions).willCancel();
}
return cancel;

View File

@ -67,7 +67,7 @@ public class Reach extends Check {
// cancel the event.
final ViolationData vd = new ViolationData(this, player, data.reachVL, distance, cc.reachActions);
vd.setParameter(ParameterName.REACH_DISTANCE, String.valueOf(data.reachDistance));
cancel = executeActions(vd);
cancel = executeActions(vd).willCancel();
} else{
// Player passed the check, reward them.
data.reachVL *= 0.9D;

View File

@ -40,7 +40,7 @@ public class Speed extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we
// should cancel the event.
cancel = executeActions(player, data.speedVL, difference, cc.speedActions);
cancel = executeActions(player, data.speedVL, difference, cc.speedActions).willCancel();
}
data.speedLastRefused = true;

View File

@ -41,7 +41,7 @@ public class Color extends Check {
data.colorVL++;
// Find out if we need to remove the colors or not.
if (executeActions(player, data.colorVL, 1D, cc.colorActions))
if (executeActions(player, data.colorVL, 1D, cc.colorActions).willCancel())
// Remove color codes.
return message.replaceAll("\302\247.", "").replaceAll("\247.", "");
}

View File

@ -76,7 +76,7 @@ public class Commands extends Check {
}
return true;
}
else if (executeActions(player, data.commandsVL, violation, cc.commandsActions))
else if (executeActions(player, data.commandsVL, violation, cc.commandsActions).willCancel())
return true;
}
else if (cc.chatWarningCheck && now - data.chatWarningTime > cc.chatWarningTimeout && (100f * nw / cc.commandsLevel > cc.chatWarningLevel || 100f * data.commandsShortTermWeight / cc.commandsShortTermLevel > cc.chatWarningLevel)){

View File

@ -9,11 +9,11 @@ import fr.neatmonster.nocheatplus.utilities.ColorUtil;
public class Relog extends Check {
public Relog() {
super(CheckType.CHAT_RELOG);
}
/**
public Relog() {
super(CheckType.CHAT_RELOG);
}
/**
* Check (Join), only call from synchronized code.
*
* @param player
@ -30,7 +30,7 @@ public class Relog extends Check {
final long now = System.currentTimeMillis();
final CombinedData cData = CombinedData.getData(player);
// Enforce the player does not relog too fast.
if (now - cData.lastLogoutTime < cc.relogTimeout) {
if (now - data.relogWarningTime > cc.relogWarningTimeout)
@ -42,7 +42,7 @@ public class Relog extends Check {
} else{
// Find out if we need to ban the player or not.
data.relogVL += 1D;
cancel = executeActions(player, (double) data.relogVL, 1D, cc.relogActions);
cancel = executeActions(player, (double) data.relogVL, 1D, cc.relogActions).willCancel();
}
}
// TODO: decrease relog vl ?

View File

@ -267,12 +267,12 @@ public class Text extends Check implements INotifyReload {
}
else{
if (shortTermViolation) {
if (executeActions(player, data.textVL, added, cc.textFreqShortTermActions)) {
if (executeActions(player, data.textVL, added, cc.textFreqShortTermActions).willCancel()) {
cancel = true;
}
}
else if (normalViolation) {
if (executeActions(player, data.textVL, added, cc.textFreqNormActions)) {
if (executeActions(player, data.textVL, added, cc.textFreqNormActions).willCancel()) {
cancel = true;
}
}

View File

@ -7,38 +7,38 @@ import fr.neatmonster.nocheatplus.checks.CheckType;
public class BedLeave extends Check {
public BedLeave() {
super(CheckType.COMBINED_BEDLEAVE);
}
public BedLeave() {
super(CheckType.COMBINED_BEDLEAVE);
}
/**
* Checks a player.
*
* @param player
* the player
* @return If to prevent action (would be set back location of survivalfly).
*/
public boolean checkBed(final Player player) {
final CombinedData data = CombinedData.getData(player);
boolean cancel = false;
// Check if the player had been in bed at all.
if (!data.wasInBed) {
// Violation ...
data.bedLeaveVL += 1D;
// TODO: add tag
/**
* Checks a player.
*
* @param player
* the player
* @return If to prevent action (would be set back location of survivalfly).
*/
public boolean checkBed(final Player player) {
final CombinedData data = CombinedData.getData(player);
boolean cancel = false;
// Check if the player had been in bed at all.
if (!data.wasInBed) {
// Violation ...
data.bedLeaveVL += 1D;
// TODO: add tag
// And return if we need to do something or not.
if (executeActions(player, data.bedLeaveVL, 1D, CombinedConfig.getConfig(player).bedLeaveActions).willCancel()){
cancel = true;
}
} else{
// He has, everything is allright.
data.wasInBed = false;
// TODO: think about decreasing the vl ?
}
return cancel;
}
// And return if we need to do something or not.
if (executeActions(player, data.bedLeaveVL, 1D, CombinedConfig.getConfig(player).bedLeaveActions)){
cancel = true;
}
} else{
// He has, everything is allright.
data.wasInBed = false;
// TODO: think about decreasing the vl ?
}
return cancel;
}
}

View File

@ -18,77 +18,77 @@ import fr.neatmonster.nocheatplus.utilities.TickTask;
*/
public class Improbable extends Check implements DisableListener{
private static Improbable instance = null;
/**
* Return if t cancel.
* @param player
* @param weights
* @param now
* @return
*/
public static final boolean check(final Player player, final float weight, final long now, final String tags){
return instance.checkImprobable(player, weight, now, tags);
}
/**
* Feed the check but no violations processing (convenience method).
* @param player
* @param weight
* @param now
*/
public static final void feed(final Player player, final float weight, final long now){
CombinedData.getData(player).improbableCount.add(now, weight);
}
////////////////////////////////////
// Instance methods.
///////////////////////////////////
public Improbable() {
super(CheckType.COMBINED_IMPROBABLE);
instance = this;
}
private static Improbable instance = null;
private boolean checkImprobable(final Player player, final float weight, final long now, final String tags) {
if (!isEnabled(player)) return false;
final CombinedData data = CombinedData.getData(player);
final CombinedConfig cc = CombinedConfig.getConfig(player);
data.improbableCount.add(now, weight);
final float shortTerm = data.improbableCount.bucketScore(0);
double violation = 0;
boolean violated = false;
if (shortTerm * 0.8f > cc.improbableLevel / 20.0){
final float lag = cc.lag ? TickTask.getLag(data.improbableCount.bucketDuration(), true) : 1f;
if (shortTerm / lag > cc.improbableLevel / 20.0){
violation += shortTerm * 2d / lag;
violated = true;
}
}
final double full = data.improbableCount.score(1.0f);
if (full > cc.improbableLevel){
final float lag = cc.lag ? TickTask.getLag(data.improbableCount.bucketDuration() * data.improbableCount.numberOfBuckets(), true) : 1f;
if (full / lag > cc.improbableLevel){
violation += full / lag;
violated = true;
}
}
boolean cancel = false;
if (violated){
// Execute actions
data.improbableVL += violation / 10.0;
final ViolationData vd = new ViolationData(this, player, data.improbableVL, violation, cc.improbableActions);
if (tags != null && !tags.isEmpty()) vd.setParameter(ParameterName.TAGS, tags);
cancel = executeActions(vd);
}
else
data.improbableVL *= 0.95;
return cancel;
}
/**
* Return if t cancel.
* @param player
* @param weights
* @param now
* @return
*/
public static final boolean check(final Player player, final float weight, final long now, final String tags){
return instance.checkImprobable(player, weight, now, tags);
}
@Override
public void onDisable() {
instance = null;
}
/**
* Feed the check but no violations processing (convenience method).
* @param player
* @param weight
* @param now
*/
public static final void feed(final Player player, final float weight, final long now){
CombinedData.getData(player).improbableCount.add(now, weight);
}
////////////////////////////////////
// Instance methods.
///////////////////////////////////
public Improbable() {
super(CheckType.COMBINED_IMPROBABLE);
instance = this;
}
private boolean checkImprobable(final Player player, final float weight, final long now, final String tags) {
if (!isEnabled(player)) return false;
final CombinedData data = CombinedData.getData(player);
final CombinedConfig cc = CombinedConfig.getConfig(player);
data.improbableCount.add(now, weight);
final float shortTerm = data.improbableCount.bucketScore(0);
double violation = 0;
boolean violated = false;
if (shortTerm * 0.8f > cc.improbableLevel / 20.0){
final float lag = cc.lag ? TickTask.getLag(data.improbableCount.bucketDuration(), true) : 1f;
if (shortTerm / lag > cc.improbableLevel / 20.0){
violation += shortTerm * 2d / lag;
violated = true;
}
}
final double full = data.improbableCount.score(1.0f);
if (full > cc.improbableLevel){
final float lag = cc.lag ? TickTask.getLag(data.improbableCount.bucketDuration() * data.improbableCount.numberOfBuckets(), true) : 1f;
if (full / lag > cc.improbableLevel){
violation += full / lag;
violated = true;
}
}
boolean cancel = false;
if (violated){
// Execute actions
data.improbableVL += violation / 10.0;
final ViolationData vd = new ViolationData(this, player, data.improbableVL, violation, cc.improbableActions);
if (tags != null && !tags.isEmpty()) vd.setParameter(ParameterName.TAGS, tags);
cancel = executeActions(vd).willCancel();
}
else
data.improbableVL *= 0.95;
return cancel;
}
@Override
public void onDisable() {
instance = null;
}
}

View File

@ -13,21 +13,21 @@ import fr.neatmonster.nocheatplus.checks.CheckType;
*
*/
public class MunchHausen extends Check {
public MunchHausen(){
super(CheckType.COMBINED_MUNCHHAUSEN);
}
public MunchHausen(){
super(CheckType.COMBINED_MUNCHHAUSEN);
}
public boolean checkFish(final Player player, final Entity caught, final State state) {
if (caught == null || !(caught instanceof Player)) return false;
final Player caughtPlayer = (Player) caught;
final CombinedData data = CombinedData.getData(player);
if (player.equals(caughtPlayer)){
data.munchHausenVL += 1.0;
if (executeActions(player, data.munchHausenVL, 1.0, CombinedConfig.getConfig(player).munchHausenActions)){
return true;
}
}
else data.munchHausenVL *= 0.96;
return false;
}
public boolean checkFish(final Player player, final Entity caught, final State state) {
if (caught == null || !(caught instanceof Player)) return false;
final Player caughtPlayer = (Player) caught;
final CombinedData data = CombinedData.getData(player);
if (player.equals(caughtPlayer)){
data.munchHausenVL += 1.0;
if (executeActions(player, data.munchHausenVL, 1.0, CombinedConfig.getConfig(player).munchHausenActions).willCancel()){
return true;
}
}
else data.munchHausenVL *= 0.96;
return false;
}
}

View File

@ -166,7 +166,7 @@ public class Angle extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.angleVL, violation, cc.angleActions);
cancel = executeActions(player, data.angleVL, violation, cc.angleActions).willCancel();
} else {
// Reward the player by lowering their violation level.
data.angleVL *= 0.98D;

View File

@ -63,7 +63,7 @@ public class Critical extends Check {
// TODO: Skip near the highest jump height (needs check if head collided with something solid, which also detects low jump).
if (!dataM.isVelocityJumpPhase() &&
(dataM.sfLowJump && !dataM.sfNoLowJump && dataM.liftOffEnvelope == LiftOffEnvelope.NORMAL
|| mcFallDistance < cc.criticalFallDistance && !BlockProperties.isResetCond(player, loc, mCc.yOnGround))) {
|| mcFallDistance < cc.criticalFallDistance && !BlockProperties.isResetCond(player, loc, mCc.yOnGround))) {
final MovingConfig ccM = MovingConfig.getConfig(player);
// TODO: Use past move tracking to check for SurvivalFly.
if (MovingUtil.shouldCheckSurvivalFly(player, dataM, ccM)) {
@ -78,7 +78,7 @@ public class Critical extends Check {
}
vd.setParameter(ParameterName.TAGS, StringUtil.join(tags, "+"));
}
cancel = executeActions(vd);
cancel = executeActions(vd).willCancel();
}
}
}

View File

@ -71,7 +71,7 @@ public class Direction extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.directionVL, distance, cc.directionActions);
cancel = executeActions(player, data.directionVL, distance, cc.directionActions).willCancel();
if (cancel) {
// Deal an attack penalty time.
@ -176,7 +176,7 @@ public class Direction extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.directionVL, context.minViolation, cc.directionActions);
cancel = executeActions(player, data.directionVL, context.minViolation, cc.directionActions).willCancel();
if (cancel) {
// Deal an attack penalty time.

View File

@ -13,45 +13,45 @@ import fr.neatmonster.nocheatplus.utilities.TickTask;
*
*/
public class FastHeal extends Check {
public FastHeal(){
super(CheckType.FIGHT_FASTHEAL);
}
public boolean check(final Player player){
final long time = System.currentTimeMillis();
final FightConfig cc = FightConfig.getConfig(player);
final FightData data = FightData.getData(player);
boolean cancel = false;
if (time < data.fastHealRefTime || time - data.fastHealRefTime >= cc.fastHealInterval){
// Reset.
data.fastHealVL *= 0.96;
// Only add a predefined amount to the buffer.
// TODO: Confine regain-conditions further? (e.g. if vl < 0.1)
data.fastHealBuffer = Math.min(cc.fastHealBuffer, data.fastHealBuffer + 50L);
}
else{
// Violation.
final double correctedDiff = ((double) time - data.fastHealRefTime) * TickTask.getLag(cc.fastHealInterval, true);
// TODO: Consider using a simple buffer as well (to get closer to the correct interval).
// TODO: Check if we added a buffer.
if (correctedDiff < cc.fastHealInterval){
data.fastHealBuffer -= (cc.fastHealInterval - correctedDiff);
if (data.fastHealBuffer <= 0){
final double violation = ((double) cc.fastHealInterval - correctedDiff) / 1000.0;
data.fastHealVL += violation;
if (executeActions(player, data.fastHealVL, violation, cc.fastHealActions)){
cancel = true;
}
}
}
}
if (data.debug && player.hasPermission(Permissions.ADMINISTRATION_DEBUG)){
player.sendMessage("Regain health(SATIATED): " + (time - data.fastHealRefTime) + " ms "+ "(buffer=" + data.fastHealBuffer + ")" +" , cancel=" + cancel);
}
data.fastHealRefTime = time;
return cancel;
}
public FastHeal(){
super(CheckType.FIGHT_FASTHEAL);
}
public boolean check(final Player player){
final long time = System.currentTimeMillis();
final FightConfig cc = FightConfig.getConfig(player);
final FightData data = FightData.getData(player);
boolean cancel = false;
if (time < data.fastHealRefTime || time - data.fastHealRefTime >= cc.fastHealInterval){
// Reset.
data.fastHealVL *= 0.96;
// Only add a predefined amount to the buffer.
// TODO: Confine regain-conditions further? (e.g. if vl < 0.1)
data.fastHealBuffer = Math.min(cc.fastHealBuffer, data.fastHealBuffer + 50L);
}
else{
// Violation.
final double correctedDiff = ((double) time - data.fastHealRefTime) * TickTask.getLag(cc.fastHealInterval, true);
// TODO: Consider using a simple buffer as well (to get closer to the correct interval).
// TODO: Check if we added a buffer.
if (correctedDiff < cc.fastHealInterval){
data.fastHealBuffer -= (cc.fastHealInterval - correctedDiff);
if (data.fastHealBuffer <= 0){
final double violation = ((double) cc.fastHealInterval - correctedDiff) / 1000.0;
data.fastHealVL += violation;
if (executeActions(player, data.fastHealVL, violation, cc.fastHealActions).willCancel()){
cancel = true;
}
}
}
}
if (data.debug && player.hasPermission(Permissions.ADMINISTRATION_DEBUG)){
player.sendMessage("Regain health(SATIATED): " + (time - data.fastHealRefTime) + " ms "+ "(buffer=" + data.fastHealBuffer + ")" +" , cancel=" + cancel);
}
data.fastHealRefTime = time;
return cancel;
}
}

View File

@ -151,7 +151,7 @@ public class GodMode extends Check {
if (data.godModeAcc > 2){
// TODO: To match with old checks vls / actions, either change actions or apply a factor.
data.godModeVL += delta;
if (executeActions(player, data.godModeVL, delta, FightConfig.getConfig(player).godModeActions)){
if (executeActions(player, data.godModeVL, delta, FightConfig.getConfig(player).godModeActions).willCancel()){
cancel = true;
}
else {

View File

@ -38,10 +38,10 @@ public class NoSwing extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.noSwingVL, 1D, cc.noSwingActions);
cancel = executeActions(player, data.noSwingVL, 1D, cc.noSwingActions).willCancel();
}
return cancel;
}
}

View File

@ -95,7 +95,7 @@ public class Reach extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.reachVL, violation, cc.reachActions);
cancel = executeActions(player, data.reachVL, violation, cc.reachActions).willCancel();
if (Improbable.check(player, (float) violation / 2f, System.currentTimeMillis(), "fight.reach")){
cancel = true;
}
@ -229,7 +229,7 @@ public class Reach extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.reachVL, violation, cc.reachActions);
cancel = executeActions(player, data.reachVL, violation, cc.reachActions).willCancel();
if (Improbable.check(player, (float) violation / 2f, System.currentTimeMillis(), "fight.reach")){
cancel = true;
}

View File

@ -7,20 +7,20 @@ import fr.neatmonster.nocheatplus.checks.CheckType;
public class SelfHit extends Check {
public SelfHit() {
super(CheckType.FIGHT_SELFHIT);
}
public boolean check(final Player damager, final Player damaged, final FightData data, final FightConfig cc){
if (!damager.getName().equals(damaged.getName())) return false;
boolean cancel = false;
// Treat self hitting as instant violation.
data.selfHitVL.add(System.currentTimeMillis(), 1.0f);
// NOTE: This lets VL decrease slightly over 30 seconds, one could also use a number, but this is more tolerant.
cancel = executeActions(damager, data.selfHitVL.score(0.99f), 1.0f, cc.selfHitActions);
return cancel;
}
public SelfHit() {
super(CheckType.FIGHT_SELFHIT);
}
public boolean check(final Player damager, final Player damaged, final FightData data, final FightConfig cc){
if (!damager.getName().equals(damaged.getName())) return false;
boolean cancel = false;
// Treat self hitting as instant violation.
data.selfHitVL.add(System.currentTimeMillis(), 1.0f);
// NOTE: This lets VL decrease slightly over 30 seconds, one could also use a number, but this is more tolerant.
cancel = executeActions(damager, data.selfHitVL.score(0.99f), 1.0f, cc.selfHitActions).willCancel();
return cancel;
}
}

View File

@ -79,7 +79,7 @@ public class Speed extends Check {
// cancel the event.
final ViolationData vd = new ViolationData(this, player, data.speedVL, max - cc.speedLimit, cc.speedActions);
vd.setParameter(ParameterName.LIMIT, String.valueOf(Math.round(cc.speedLimit)));
cancel = executeActions(vd);
cancel = executeActions(vd).willCancel();
}
else data.speedVL *= 0.96;

View File

@ -25,9 +25,9 @@ public class Drop extends Check {
* @return true, if successful
*/
public boolean check(final Player player) {
// Take time once.
final long time = System.currentTimeMillis();
// Take time once.
final long time = System.currentTimeMillis();
final InventoryConfig cc = InventoryConfig.getConfig(player);
final InventoryData data = InventoryData.getData(player);
@ -53,7 +53,7 @@ public class Drop extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.dropVL, data.dropCount - cc.dropLimit, cc.dropActions);
cancel = executeActions(player, data.dropVL, data.dropCount - cc.dropLimit, cc.dropActions).willCancel();
}
return cancel;

View File

@ -128,7 +128,7 @@ public class FastClick extends Check {
if (violation > 0){
data.fastClickVL += violation;
final ViolationData vd = new ViolationData(this, player, data.fastClickVL, violation, cc.fastClickActions);
cancel = executeActions(vd);
cancel = executeActions(vd).willCancel();
}
if (data.debug && player.hasPermission(Permissions.ADMINISTRATION_DEBUG)){

View File

@ -12,7 +12,7 @@ import fr.neatmonster.nocheatplus.utilities.TickTask;
* The InstantBow check will find out if a player pulled the string of their bow too fast.
*/
public class InstantBow extends Check {
private static final float maxTime = 800f;
/**
@ -32,7 +32,7 @@ public class InstantBow extends Check {
* @return true, if successful
*/
public boolean check(final Player player, final float force, final long now) {
final InventoryData data = InventoryData.getData(player);
final InventoryConfig cc = InventoryConfig.getConfig(player);
@ -40,17 +40,17 @@ public class InstantBow extends Check {
// Rough estimation of how long pulling the string should've taken.
final long expectedPullDuration = (long) (maxTime - maxTime * (1f - force) * (1f - force)) - cc.instantBowDelay;
// Time taken to pull the string.
final long pullDuration;
final boolean valid;
if (cc.instantBowStrict) {
// The interact time is invalid, if set to 0.
valid = data.instantBowInteract != 0;
pullDuration = valid ? (now - data.instantBowInteract) : 0L;
// The interact time is invalid, if set to 0.
valid = data.instantBowInteract != 0;
pullDuration = valid ? (now - data.instantBowInteract) : 0L;
} else {
valid = true;
pullDuration = now - data.instantBowShoot;
valid = true;
pullDuration = now - data.instantBowShoot;
}
if (valid && (!cc.instantBowStrict || data.instantBowInteract > 0L) && pullDuration >= expectedPullDuration) {
@ -62,10 +62,10 @@ public class InstantBow extends Check {
// TODO: Maybe this can be removed, though TickTask does not reset at the exact moment.
}
else {
// Account for server side lag.
// (Do not apply correction to invalid pulling.)
final long correctedPullduration = valid ? (cc.lag ? (long) (TickTask.getLag(expectedPullDuration, true) * pullDuration) : pullDuration) : 0;
if (correctedPullduration < expectedPullDuration) {
// Account for server side lag.
// (Do not apply correction to invalid pulling.)
final long correctedPullduration = valid ? (cc.lag ? (long) (TickTask.getLag(expectedPullDuration, true) * pullDuration) : pullDuration) : 0;
if (correctedPullduration < expectedPullDuration) {
// TODO: Consider: Allow one time but set yawrate penalty time ?
final double difference = (expectedPullDuration - pullDuration) / 100D;
@ -74,14 +74,14 @@ public class InstantBow extends Check {
// Execute whatever actions are associated with this check and the
// violation level and find out if we should cancel the event
cancel = executeActions(player, data.instantBowVL, difference, cc.instantBowActions);
}
cancel = executeActions(player, data.instantBowVL, difference, cc.instantBowActions).willCancel();
}
}
if (data.debug && player.hasPermission(Permissions.ADMINISTRATION_DEBUG)) {
player.sendMessage(ChatColor.YELLOW + "NCP: " + ChatColor.GRAY + "Bow shot - force: " + force +", " + (cc.instantBowStrict || pullDuration < 2 * expectedPullDuration ? ("pull time: " + pullDuration) : "") + "(" + expectedPullDuration +")");
}
// Reset data here.
data.instantBowInteract = 0;
data.instantBowShoot = now;

View File

@ -62,7 +62,7 @@ public class InstantEat extends Check {
if (data.instantEatFood != null) {
vd.setParameter(ParameterName.FOOD, data.instantEatFood.toString());
}
cancel = executeActions(vd);
cancel = executeActions(vd).willCancel();
}
data.instantEatInteract = 0;

View File

@ -183,7 +183,7 @@ public class CreativeFly extends Check {
vd.setParameter(ParameterName.LOCATION_TO, String.format(Locale.US, "%.2f, %.2f, %.2f", to.getX(), to.getY(), to.getZ()));
vd.setParameter(ParameterName.DISTANCE, String.format(Locale.US, "%.2f", TrigUtil.distance(from, to)));
}
if (executeActions(vd)) {
if (executeActions(vd).willCancel()) {
// Compose a new location based on coordinates of "newTo" and viewing direction of "event.getTo()"
// to allow the player to look somewhere else despite getting pulled back by NoCheatPlus.
return data.getSetBack(to);

View File

@ -20,9 +20,9 @@ import fr.neatmonster.nocheatplus.utilities.StringUtil;
* checks (flying/running).
*/
public class MorePackets extends Check {
private final List<String> tags = new ArrayList<String>();
private final List<String> tags = new ArrayList<String>();
/**
* Instantiates a new more packets check.
*/
@ -30,71 +30,71 @@ public class MorePackets extends Check {
super(CheckType.MOVING_MOREPACKETS);
}
/**
* Check for speeding by sending too many packets. We assume 22 packets per
* second to be legitimate, while 20 would be ideal. See
* PlayerData.morePacketsFreq for the monitored amount of time and the
* resolution. See NetStatic for the actual check code.
*
* @param player
* the player
* @param from
* the from
* @param to
* the to
* @return the location
*/
/**
* Check for speeding by sending too many packets. We assume 22 packets per
* second to be legitimate, while 20 would be ideal. See
* PlayerData.morePacketsFreq for the monitored amount of time and the
* resolution. See NetStatic for the actual check code.
*
* @param player
* the player
* @param from
* the from
* @param to
* the to
* @return the location
*/
public Location check(final Player player, final PlayerLocation from, final PlayerLocation to, final MovingData data, final MovingConfig cc) {
// Take time once, first:
final long time = System.currentTimeMillis();
// if (from.isSamePos(to)) {
// // Ignore moves with "just look" for now.
// // TODO: Extra ActionFrequency for "just look" + use to burn, maybe also check individually.
// return null;
// }
// Ensure we have a set-back location.
// Take time once, first:
final long time = System.currentTimeMillis();
// if (from.isSamePos(to)) {
// // Ignore moves with "just look" for now.
// // TODO: Extra ActionFrequency for "just look" + use to burn, maybe also check individually.
// return null;
// }
// Ensure we have a set-back location.
if (!data.hasMorePacketsSetBack()){
// TODO: Check if other set-back is appropriate or if to set/reset on other events.
if (data.hasSetBack()) {
data.setMorePacketsSetBack(data.getSetBack(to));
}
else {
data.setMorePacketsSetBack(from);
}
// TODO: Check if other set-back is appropriate or if to set/reset on other events.
if (data.hasSetBack()) {
data.setMorePacketsSetBack(data.getSetBack(to));
}
else {
data.setMorePacketsSetBack(from);
}
}
// Check for a violation of the set limits.
tags.clear();
final double violation = NetStatic.morePacketsCheck(data.morePacketsFreq, time, 1f, cc.morePacketsEPSMax, cc.morePacketsEPSIdeal, data.morePacketsBurstFreq, cc.morePacketsBurstPackets, cc.morePacketsBurstDirect, cc.morePacketsBurstEPM, tags);
// Process violation result.
if (violation > 0.0) {
// Increment violation level.
data.morePacketsVL = violation; // TODO: Accumulate somehow [e.g. always += 1, decrease with continuous moving without violation]?
// Violation handling.
final ViolationData vd = new ViolationData(this, player, data.morePacketsVL, violation, cc.morePacketsActions);
if (data.debug || vd.needsParameters()) {
vd.setParameter(ParameterName.PACKETS, Integer.toString(new Double(violation).intValue()));
vd.setParameter(ParameterName.TAGS, StringUtil.join(tags, "+"));
vd.setParameter(ParameterName.PACKETS, Integer.toString(new Double(violation).intValue()));
vd.setParameter(ParameterName.TAGS, StringUtil.join(tags, "+"));
}
if (executeActions(vd)) {
// Set to cancel the move.
return data.getMorePacketsSetBack();
if (executeActions(vd).willCancel()) {
// Set to cancel the move.
return data.getMorePacketsSetBack();
}
}
else {
// Update the set-back location. (CHANGED to only update, if not a violation.)
// (Might update whenever newTo == null)
data.setMorePacketsSetBack(from);
// Update the set-back location. (CHANGED to only update, if not a violation.)
// (Might update whenever newTo == null)
data.setMorePacketsSetBack(from);
}
// No set-back.
return null;
}
}

View File

@ -44,26 +44,26 @@ public class MorePacketsVehicle extends Check {
* @return the location
*/
public Location check(final Player player, final Location from, final Location to, final MovingData data, final MovingConfig cc) {
// Take time once, first:
final long time = System.currentTimeMillis();
// Take time once, first:
final long time = System.currentTimeMillis();
Location newTo = null;
if (!data.hasMorePacketsVehicleSetBack()){
// TODO: Check if other set-back is appropriate or if to set on other events.
data.setMorePacketsVehicleSetBack(from);
if (data.morePacketsVehicleTaskId != -1) {
// TODO: Set back outdated or not?
Bukkit.getScheduler().cancelTask(data.morePacketsVehicleTaskId);
}
// TODO: Check if other set-back is appropriate or if to set on other events.
data.setMorePacketsVehicleSetBack(from);
if (data.morePacketsVehicleTaskId != -1) {
// TODO: Set back outdated or not?
Bukkit.getScheduler().cancelTask(data.morePacketsVehicleTaskId);
}
}
// Take a packet from the buffer.
data.morePacketsVehicleBuffer--;
if (data.morePacketsVehicleTaskId != -1){
// Short version !
return data.getMorePacketsVehicleSetBack();
// Short version !
return data.getMorePacketsVehicleSetBack();
}
// Player used up buffer, they fail the check.
@ -76,10 +76,10 @@ public class MorePacketsVehicle extends Check {
// cancel the event.
final ViolationData vd = new ViolationData(this, player, data.morePacketsVehicleVL, -data.morePacketsVehicleBuffer, cc.morePacketsVehicleActions);
if (data.debug || vd.needsParameters()) {
vd.setParameter(ParameterName.PACKETS, Integer.toString(-data.morePacketsVehicleBuffer));
vd.setParameter(ParameterName.PACKETS, Integer.toString(-data.morePacketsVehicleBuffer));
}
if (executeActions(vd)){
newTo = data.getMorePacketsVehicleSetBack();
if (executeActions(vd).willCancel()){
newTo = data.getMorePacketsVehicleSetBack();
}
}
@ -93,32 +93,32 @@ public class MorePacketsVehicle extends Check {
// If there was a long pause (maybe server lag?), allow buffer to grow up to 100.
if (seconds > 2) {
if (data.morePacketsVehicleBuffer > 100) {
data.morePacketsVehicleBuffer = 100;
data.morePacketsVehicleBuffer = 100;
}
} else if (data.morePacketsVehicleBuffer > 50) {
// Only allow growth up to 50.
// Only allow growth up to 50.
data.morePacketsVehicleBuffer = 50;
}
// Set the new "last" time.
data.morePacketsVehicleLastTime = time;
// Set the new "setback" location.
if (newTo == null) {
data.setMorePacketsVehicleSetBack(from);
data.setMorePacketsVehicleSetBack(from);
}
} else if (data.morePacketsVehicleLastTime > time) {
// Security check, maybe system time changed.
// Security check, maybe system time changed.
data.morePacketsVehicleLastTime = time;
}
if (newTo == null) {
return null;
return null;
}
// Compose a new location based on coordinates of "newTo" and viewing direction of "event.getTo()" to allow the
// player to look somewhere else despite getting pulled back by NoCheatPlus.
return new Location(player.getWorld(), newTo.getX(), newTo.getY(), newTo.getZ(), to.getYaw(), to.getPitch());
}
}

View File

@ -1447,7 +1447,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
if (!pLoc.isOnGround(1.0, 0.3, 0.1) && !pLoc.isResetCond() && !pLoc.isAboveLadder() && !pLoc.isAboveStairs()) {
// Likely a new style no-fall bypass (damage in mid-air).
data.noFallVL += 1.0;
if (noFall.executeActions(player, data.noFallVL, 1.0, cc.noFallActions) && data.hasSetBack()) {
if (noFall.executeActions(player, data.noFallVL, 1.0, cc.noFallActions).willCancel() && data.hasSetBack()) {
// Cancel the event and restore fall distance.
// NoFall data will not be reset
allowReset = false;

View File

@ -145,7 +145,7 @@ public class Passable extends Check {
vd.setParameter(ParameterName.TAGS, tags);
}
}
if (executeActions(vd)) {
if (executeActions(vd).willCancel()) {
// TODO: Consider another set back position for this, also keeping track of players moving around in blocks.
final Location newTo;
if (setBackLoc != null) {

View File

@ -2141,7 +2141,7 @@ public class SurvivalFly extends Check {
vd.setParameter(ParameterName.TAGS, StringUtil.join(tags, "+"));
}
// Some resetting is done in MovingListener.
if (executeActions(vd)) {
if (executeActions(vd).willCancel()) {
// Set-back + view direction of to (more smooth).
return data.getSetBack(to);
}
@ -2172,7 +2172,7 @@ public class SurvivalFly extends Check {
vd.setParameter(ParameterName.DISTANCE, "0.0(HOVER)");
vd.setParameter(ParameterName.TAGS, "hover");
}
if (executeActions(vd)) {
if (executeActions(vd).willCancel()) {
// Set-back or kick.
if (data.hasSetBack()) {
final Location newTo = data.getSetBack(loc);

View File

@ -77,7 +77,7 @@ public class AttackFrequency extends Check {
vd.setParameter(ParameterName.LIMIT, Integer.toString((int) maxLimit));
vd.setParameter(ParameterName.TAGS, tags);
}
if (executeActions(vd)) {
if (executeActions(vd).willCancel()) {
cancel = true;
}
// Feed Improbable.

View File

@ -35,7 +35,7 @@ public class FlyingFrequency extends Check {
public boolean check(final Player player, final DataPacketFlying packetData, final long time, final NetData data, final NetConfig cc) {
data.flyingFrequencyAll.add(time, 1f);
final float allScore = data.flyingFrequencyAll.score(1f);
if (allScore / cc.flyingFrequencySeconds > cc.flyingFrequencyPPS && !CheckUtils.hasBypass(CheckType.NET_FLYINGFREQUENCY, player, data) && executeActions(player, allScore / cc.flyingFrequencySeconds - cc.flyingFrequencyPPS, 1.0 / cc.flyingFrequencySeconds, cc.flyingFrequencyActions)) {
if (allScore / cc.flyingFrequencySeconds > cc.flyingFrequencyPPS && !CheckUtils.hasBypass(CheckType.NET_FLYINGFREQUENCY, player, data) && executeActions(player, allScore / cc.flyingFrequencySeconds - cc.flyingFrequencyPPS, 1.0 / cc.flyingFrequencySeconds, cc.flyingFrequencyActions).willCancel()) {
return true;
} else {
return false;

View File

@ -26,7 +26,7 @@ public class KeepAliveFrequency extends Check {
if (first > 1f && !CheckUtils.hasBypass(CheckType.NET_KEEPALIVEFREQUENCY, player, data)) {
// Trigger a violation.
final double vl = Math.max(first - 1f, data.keepAliveFreq.score(1f) - data.keepAliveFreq.numberOfBuckets());
if (executeActions(player, vl, 1.0, cc.keepAliveFrequencyActions)) {
if (executeActions(player, vl, 1.0, cc.keepAliveFrequencyActions).willCancel()) {
return true;
}
}