From 2bea03eaf0ab0fdbd277280b4a91671a8be0680c Mon Sep 17 00:00:00 2001 From: asofold Date: Sun, 15 Apr 2018 18:57:30 +0200 Subject: [PATCH] Support cancel with probability (e.g. 25%cancel) for actions. --- .../nocheatplus/actions/ActionFactory.java | 25 ++++++++++++++++ .../actions/types/penalty/PenaltyAction.java | 6 ++++ .../actions/types/penalty/PenaltyNode.java | 2 +- .../nocheatplus/test/TestActions.java | 30 ++++++++++++++++++- 4 files changed, 61 insertions(+), 2 deletions(-) diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/actions/ActionFactory.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/actions/ActionFactory.java index c67dc1b7..3f9288b5 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/actions/ActionFactory.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/actions/ActionFactory.java @@ -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(); } + 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( + "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(); + } + if (actionDefinition.startsWith("cmd:")) { return parseCmdAction(actionDefinition.split(":", 2)[1]); } diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/actions/types/penalty/PenaltyAction.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/actions/types/penalty/PenaltyAction.java index e9145d53..f1c8aea8 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/actions/types/penalty/PenaltyAction.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/actions/types/penalty/PenaltyAction.java @@ -44,6 +44,8 @@ public class PenaltyAction 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 childNodes, boolean abortOnApply) { this.random = random; diff --git a/NCPPlugin/src/test/java/fr/neatmonster/nocheatplus/test/TestActions.java b/NCPPlugin/src/test/java/fr/neatmonster/nocheatplus/test/TestActions.java index 6434e7e2..86286e94 100644 --- a/NCPPlugin/src/test/java/fr/neatmonster/nocheatplus/test/TestActions.java +++ b/NCPPlugin/src/test/java/fr/neatmonster/nocheatplus/test/TestActions.java @@ -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[] 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[] 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."); + } + } + }