Support cancel with probability (e.g. 25%cancel) for actions.
This commit is contained in:
parent
d82fb9c804
commit
2bea03eaf0
|
@ -18,8 +18,12 @@ import java.util.Map;
|
||||||
|
|
||||||
import fr.neatmonster.nocheatplus.actions.types.CancelAction;
|
import fr.neatmonster.nocheatplus.actions.types.CancelAction;
|
||||||
import fr.neatmonster.nocheatplus.actions.types.LogAction;
|
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.checks.ViolationData;
|
||||||
import fr.neatmonster.nocheatplus.logging.StaticLog;
|
import fr.neatmonster.nocheatplus.logging.StaticLog;
|
||||||
|
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helps with creating Actions out of text string definitions.
|
* 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>();
|
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:")) {
|
if (actionDefinition.startsWith("cmd:")) {
|
||||||
return parseCmdAction(actionDefinition.split(":", 2)[1]);
|
return parseCmdAction(actionDefinition.split(":", 2)[1]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,8 @@ public class PenaltyAction<D extends ActionData, L extends AbstractActionList<D,
|
||||||
private final PenaltyNode rootNode;
|
private final PenaltyNode rootNode;
|
||||||
private final String penaltyId;
|
private final String penaltyId;
|
||||||
|
|
||||||
|
// TODO: executesAlways +- making sense.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param penaltyId
|
* @param penaltyId
|
||||||
|
@ -79,4 +81,8 @@ public class PenaltyAction<D extends ActionData, L extends AbstractActionList<D,
|
||||||
return "penalty:" + penaltyId;
|
return "penalty:" + penaltyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PenaltyNode getPenaltyNode() {
|
||||||
|
return rootNode;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,6 @@ public class PenaltyNode {
|
||||||
/**
|
/**
|
||||||
* Convenience: Simple penalty that always applies with no child nodes.
|
* Convenience: Simple penalty that always applies with no child nodes.
|
||||||
* @param random
|
* @param random
|
||||||
* @param probability
|
|
||||||
* @param penalty
|
* @param penalty
|
||||||
*/
|
*/
|
||||||
public PenaltyNode(Random random, Penalty<?> penalty) {
|
public PenaltyNode(Random random, Penalty<?> penalty) {
|
||||||
|
@ -70,6 +69,7 @@ public class PenaltyNode {
|
||||||
* @param childNodes
|
* @param childNodes
|
||||||
* May be null.
|
* May be null.
|
||||||
* @param abortOnApply
|
* @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) {
|
public PenaltyNode(Random random, double probability, Penalty<?> penalty, Collection<PenaltyNode> childNodes, boolean abortOnApply) {
|
||||||
this.random = random;
|
this.random = random;
|
||||||
|
|
|
@ -22,6 +22,8 @@ import fr.neatmonster.nocheatplus.NCPAPIProvider;
|
||||||
import fr.neatmonster.nocheatplus.PluginTests;
|
import fr.neatmonster.nocheatplus.PluginTests;
|
||||||
import fr.neatmonster.nocheatplus.actions.Action;
|
import fr.neatmonster.nocheatplus.actions.Action;
|
||||||
import fr.neatmonster.nocheatplus.actions.ActionList;
|
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.checks.ViolationData;
|
||||||
import fr.neatmonster.nocheatplus.config.ConfPaths;
|
import fr.neatmonster.nocheatplus.config.ConfPaths;
|
||||||
import fr.neatmonster.nocheatplus.config.ConfigFile;
|
import fr.neatmonster.nocheatplus.config.ConfigFile;
|
||||||
|
@ -38,11 +40,37 @@ public class TestActions {
|
||||||
config.set("actions", "log:dummy:0:0:icf");
|
config.set("actions", "log:dummy:0:0:icf");
|
||||||
config.set("strings.dummy", "dummy");
|
config.set("strings.dummy", "dummy");
|
||||||
config.set(ConfPaths.LOGGING_ACTIVE, false);
|
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);
|
Action<ViolationData, ActionList>[] actions = actionList.getActions(0.0);
|
||||||
if (actions.length != 0) {
|
if (actions.length != 0) {
|
||||||
fail("Wrong number of actions.");
|
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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue