Support cancel with probability (e.g. 25%cancel) for actions.

This commit is contained in:
asofold 2018-04-15 18:57:30 +02:00
parent d82fb9c804
commit 2bea03eaf0
4 changed files with 61 additions and 2 deletions

View File

@ -18,8 +18,12 @@ import java.util.Map;
import fr.neatmonster.nocheatplus.actions.types.CancelAction;
import fr.neatmonster.nocheatplus.actions.types.LogAction;
import fr.neatmonster.nocheatplus.actions.types.penalty.CancelPenalty;
import fr.neatmonster.nocheatplus.actions.types.penalty.PenaltyAction;
import fr.neatmonster.nocheatplus.actions.types.penalty.PenaltyNode;
import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.logging.StaticLog;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
/**
* Helps with creating Actions out of text string definitions.
@ -50,6 +54,27 @@ public class ActionFactory extends AbstractActionFactory<ViolationData, ActionLi
return new CancelAction<ViolationData, ActionList>();
}
if (actionDefinition.endsWith("%cancel")) {
try {
Double probability = Double.parseDouble(actionDefinition.substring(
0, actionDefinition.length() - 7));
if (!Double.isInfinite(probability)
&& !Double.isNaN(probability)
&& probability > 0.0) {
// TODO: parsing via factory, store implicit penalties there too.
return new PenaltyAction<ViolationData, ActionList>(
"imp_" + actionDefinition, new PenaltyNode(
CheckUtils.getRandom(), // TODO: store earlier once.
probability / 100.0,
CancelPenalty.CANCEL));
}
}
catch (NumberFormatException e) {
}
StaticLog.logWarning("Bad probability definition for cancel action: '" + actionDefinition + "', relay to always cancelling.");
return new CancelAction<ViolationData, ActionList>();
}
if (actionDefinition.startsWith("cmd:")) {
return parseCmdAction(actionDefinition.split(":", 2)[1]);
}

View File

@ -44,6 +44,8 @@ public class PenaltyAction<D extends ActionData, L extends AbstractActionList<D,
private final PenaltyNode rootNode;
private final String penaltyId;
// TODO: executesAlways +- making sense.
/**
*
* @param penaltyId
@ -79,4 +81,8 @@ public class PenaltyAction<D extends ActionData, L extends AbstractActionList<D,
return "penalty:" + penaltyId;
}
public PenaltyNode getPenaltyNode() {
return rootNode;
}
}

View File

@ -45,7 +45,6 @@ public class PenaltyNode {
/**
* Convenience: Simple penalty that always applies with no child nodes.
* @param random
* @param probability
* @param penalty
*/
public PenaltyNode(Random random, Penalty<?> penalty) {
@ -70,6 +69,7 @@ public class PenaltyNode {
* @param childNodes
* May be null.
* @param abortOnApply
* Evaluating child nodes: abort as soon as a child node applies.
*/
public PenaltyNode(Random random, double probability, Penalty<?> penalty, Collection<PenaltyNode> childNodes, boolean abortOnApply) {
this.random = random;

View File

@ -22,6 +22,8 @@ import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.PluginTests;
import fr.neatmonster.nocheatplus.actions.Action;
import fr.neatmonster.nocheatplus.actions.ActionList;
import fr.neatmonster.nocheatplus.actions.types.penalty.PenaltyAction;
import fr.neatmonster.nocheatplus.actions.types.penalty.PenaltyNode;
import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
@ -38,11 +40,37 @@ public class TestActions {
config.set("actions", "log:dummy:0:0:icf");
config.set("strings.dummy", "dummy");
config.set(ConfPaths.LOGGING_ACTIVE, false);
ActionList actionList = config.getOptimizedActionList("actions", pReg.getOrRegisterPermission("dummy")) ;
ActionList actionList = config.getOptimizedActionList("actions",
pReg.getOrRegisterPermission("dummy")) ;
Action<ViolationData, ActionList>[] actions = actionList.getActions(0.0);
if (actions.length != 0) {
fail("Wrong number of actions.");
}
}
@Test
public void testCancelWithProbability() {
PluginTests.setUnitTestNoCheatPlusAPI(false);
PermissionRegistry pReg = NCPAPIProvider.getNoCheatPlusAPI().getPermissionRegistry();
final ConfigFile config = new DefaultConfig();
config.set("actions", "25%cancel");
ActionList actionList = config.getOptimizedActionList("actions",
pReg.getOrRegisterPermission("dummy")) ;
Action<ViolationData, ActionList>[] actions = actionList.getActions(0.0);
if (actions.length != 1) {
fail("Wrong number of actions.");
}
Action<?, ?> action = actions[0];
if (action instanceof PenaltyAction) {
PenaltyAction<?, ?> penaltyAction = (PenaltyAction<?, ?>) action;
PenaltyNode node = penaltyAction.getPenaltyNode();
if (node.probability != (25.0 / 100.0)) {
fail("Expect 0.25 probability, got instead: " + node.probability);
}
}
else {
fail("Expect a penalty action here.");
}
}
}