Purge log4j

This commit is contained in:
NotAlexNoyle committed 2024-10-22 16:04:50 -04:00
1 parent 9044917cb2
commit 64a28f328b
16 files changed
+1 -2027

No files matched your search

@@ -107,7 +107,6 @@ public class FrictionAxisVelocity {
// TODO: 0.001 can be stretched somewhere else, most likely...
// TODO: Somehow use tick here too (actCount, valCount)?
if (vel.valCount <= 0 || Math.abs(vel.value) <= minValue) {
// System.out.prsintln("Invalidate active: " + vel);
it.remove();
}
}
@@ -25,7 +25,6 @@ import fr.neatmonster.nocheatplus.utilities.StringUtil;
/**
* Static access methods for more or less direct logging using either LogManager
* (usually INIT or STATUS) or System.out.
*
* @author mc_dev
*
@@ -97,17 +96,11 @@ public class StaticLog {
/**
*
* @param streamID
* May get ignored if only the console is available.
* @param level
* @param msg
*/
public static void log(final StreamID streamID, final Level level, final String msg) {
if (useLogManager) {
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().log(streamID, level, msg);
} else {
System.out.println("[" + level + "][NoCheatPlus] " + new Date());
System.out.println(msg);
}
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().log(streamID, level, msg);
}
/**
@@ -102,7 +102,6 @@ public class CollideRayVsAABB implements ICollideRayVsAABB {
final double tMaxX = CollisionUtil.getMaxTimeIncludeEdges(startX, dirX, minX, maxX, tMinX);
final double tMaxY = CollisionUtil.getMaxTimeIncludeEdges(startY, dirY, minY, maxY, tMinY);
final double tMaxZ = CollisionUtil.getMaxTimeIncludeEdges(startZ, dirZ, minZ, maxZ, tMinZ);
//System.out.println("TIMING: " + tMinX + " " + tMinY + " " + tMinZ + " " + tMaxX + " " + tMaxY + " " + tMaxZ);
if (!Double.isNaN(tMaxX) && !Double.isNaN(tMaxY) && !Double.isNaN(tMaxZ)) {
// (Excludes any tMin value to be Double.MAX_VALUE.)
// Determine if there is overlapping intervals.
@@ -1,270 +0,0 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import fr.neatmonster.nocheatplus.actions.ActionFactory;
import fr.neatmonster.nocheatplus.actions.ActionFactoryFactory;
import fr.neatmonster.nocheatplus.compat.MCAccess;
import fr.neatmonster.nocheatplus.compat.blocks.changetracker.BlockChangeTracker;
import fr.neatmonster.nocheatplus.compat.bukkit.MCAccessBukkit;
import fr.neatmonster.nocheatplus.components.NoCheatPlusAPI;
import fr.neatmonster.nocheatplus.components.registry.ComponentRegistry;
import fr.neatmonster.nocheatplus.components.registry.DefaultGenericInstanceRegistry;
import fr.neatmonster.nocheatplus.components.registry.event.IGenericInstanceHandle;
import fr.neatmonster.nocheatplus.components.registry.setup.RegistrationContext;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.DefaultConfig;
import fr.neatmonster.nocheatplus.event.mini.EventRegistryBukkit;
import fr.neatmonster.nocheatplus.logging.LogManager;
import fr.neatmonster.nocheatplus.logging.StaticLog;
import fr.neatmonster.nocheatplus.permissions.PermissionRegistry;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.permissions.RegisteredPermission;
import fr.neatmonster.nocheatplus.players.IPlayerDataManager;
import fr.neatmonster.nocheatplus.worlds.IWorldData;
import fr.neatmonster.nocheatplus.worlds.IWorldDataManager;
import fr.neatmonster.nocheatplus.worlds.WorldDataManager;
public class PluginTests {
/**
* Dummy API, providing only a minimal subset of functionality for
* offline-testing. Some methods do nothing, some throw an
* UnsupportedOperationException, some will do something (set/get MCAccess).
*
* @author asofold
*
*/
public static class UnitTestNoCheatPlusAPI implements NoCheatPlusAPI {
/*
* TODO: Mix-in style base functionality, common for testing API and
* live plugin. ALT: DefaultNoCheatPlusAPI class and a common base class
* (plugin would no further implement that API).
*/
private final WorldDataManager worldDataManager = new WorldDataManager();
private final DefaultGenericInstanceRegistry genericInstanceRegistry = new DefaultGenericInstanceRegistry();
private final PermissionRegistry permissionRegistry = new PermissionRegistry(10000);
public UnitTestNoCheatPlusAPI() {
StaticLog.setUseLogManager(false); // Ensure either this instance provides it or it's unset.
genericInstanceRegistry.registerGenericInstance(MCAccess.class, new MCAccessBukkit());
for (RegisteredPermission rp : Permissions.getPermissions()) {
permissionRegistry.addRegisteredPermission(rp);
}
Map<String, ConfigFile> rawConfigs = new HashMap<String, ConfigFile>();
rawConfigs.put(null, new DefaultConfig());
worldDataManager.applyConfiguration((rawConfigs));
}
@Override
public boolean addComponent(Object component) {
throw new UnsupportedOperationException();
}
@Override
public void removeComponent(Object component) {
throw new UnsupportedOperationException();
}
@Override
public <T> Collection<ComponentRegistry<T>> getComponentRegistries(Class<ComponentRegistry<T>> clazz) {
throw new UnsupportedOperationException();
}
@Override
public <T> T registerGenericInstance(T instance) {
throw new UnsupportedOperationException();
}
@Override
public <T, TI extends T> T registerGenericInstance(Class<T> registerFor, TI instance) {
return genericInstanceRegistry.registerGenericInstance(registerFor, instance);
}
@Override
public <T> T getGenericInstance(Class<T> registeredFor) {
return genericInstanceRegistry.getGenericInstance(registeredFor);
}
@Override
public <T> T unregisterGenericInstance(Class<T> registeredFor) {
return genericInstanceRegistry.unregisterGenericInstance(registeredFor);
}
@Override
public <T> IGenericInstanceHandle<T> getGenericInstanceHandle(Class<T> registeredFor) {
return genericInstanceRegistry.getGenericInstanceHandle(registeredFor);
}
@Override
public boolean addComponent(Object obj, boolean allowComponentFactory) {
throw new UnsupportedOperationException();
}
@Override
public void addFeatureTags(String key, Collection<String> featureTags) {
// IGNORE
}
@Override
public void setFeatureTags(String key, Collection<String> featureTags) {
// IGNORE
}
@Override
public Map<String, Set<String>> getAllFeatureTags() {
throw new UnsupportedOperationException();
}
@Override
public int sendAdminNotifyMessage(String message) {
StaticLog.logInfo("AdminNotifyMessage: " + message);
return 1;
}
@Override
public void sendMessageOnTick(String playerName, String message) {
StaticLog.logInfo("sendMessageOnTick (-> " + playerName + "): " + message);
}
@Override
public boolean allowLogin(String playerName) {
throw new UnsupportedOperationException();
}
@Override
public int allowLoginAll() {
throw new UnsupportedOperationException();
}
@Override
public void denyLogin(String playerName, long duration) {
throw new UnsupportedOperationException();
}
@Override
public boolean isLoginDenied(String playerName) {
throw new UnsupportedOperationException();
}
@Override
public String[] getLoginDeniedPlayers() {
throw new UnsupportedOperationException();
}
@Override
public boolean isLoginDenied(String playerName, long time) {
throw new UnsupportedOperationException();
}
@Override
public LogManager getLogManager() {
// TODO: Maybe do implement a dummy log manager (with file?)
throw new UnsupportedOperationException();
}
@Override
public boolean hasFeatureTag(String key, String feature) {
throw new UnsupportedOperationException();
}
@Override
public BlockChangeTracker getBlockChangeTracker() {
throw new UnsupportedOperationException();
}
@Override
public EventRegistryBukkit getEventRegistry() {
throw new UnsupportedOperationException();
}
@Override
public PermissionRegistry getPermissionRegistry() {
return permissionRegistry;
}
@Override
public WorldDataManager getWorldDataManager() {
return worldDataManager;
}
@Override
public IPlayerDataManager getPlayerDataManager() {
throw new UnsupportedOperationException();
}
@Override
public RegistrationContext newRegistrationContext() {
throw new UnsupportedOperationException();
}
@Override
public void register(RegistrationContext context) {
throw new UnsupportedOperationException();
}
@Override
public ActionFactoryFactory getActionFactoryFactory() {
ActionFactoryFactory factory = getGenericInstance(ActionFactoryFactory.class);
if (factory == null) {
setActionFactoryFactory(null);
factory = getGenericInstance(ActionFactoryFactory.class);
}
return factory;
}
@Override
public ActionFactoryFactory setActionFactoryFactory(
ActionFactoryFactory actionFactoryFactory) {
if (actionFactoryFactory == null) {
actionFactoryFactory = new ActionFactoryFactory() {
@Override
public final ActionFactory newActionFactory(
final Map<String, Object> library) {
return new ActionFactory(library);
}
};
}
final ActionFactoryFactory previous = registerGenericInstance(
ActionFactoryFactory.class, actionFactoryFactory);
// Use lazy resetting.
final IWorldDataManager worldMan = NCPAPIProvider.getNoCheatPlusAPI().getWorldDataManager();
final Iterator<Entry<String, IWorldData>> it = worldMan.getWorldDataIterator();
while (it.hasNext()) {
final ConfigFile config = it.next().getValue().getRawConfiguration();
config.setActionFactory(actionFactoryFactory);
}
// (Removing cached configurations and update are to be called externally.)
return previous;
}
}
public static void setUnitTestNoCheatPlusAPI(boolean force) {
if (force || NCPAPIProvider.getNoCheatPlusAPI() == null) {
NCPAPIProvider.setNoCheatPlusAPI(new UnitTestNoCheatPlusAPI());
}
}
}
@@ -1,78 +0,0 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.PluginTests;
import fr.neatmonster.nocheatplus.compat.MCAccess;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.DefaultConfig;
import fr.neatmonster.nocheatplus.config.RawConfigFile;
import fr.neatmonster.nocheatplus.config.WorldConfigProvider;
import fr.neatmonster.nocheatplus.utilities.map.BlockProperties;
/**
* Auxiliary classes packed in here.
* @author dev1mc
*
*/
public class BlockTests {
public static class SimpleWorldConfigProvider <C extends RawConfigFile> implements WorldConfigProvider <C>{
private final C config;
public SimpleWorldConfigProvider(C config) {
this.config = config;
}
@Override
public C getDefaultConfig() {
return config;
}
@Override
public C getConfig(String worldName) {
return config;
}
@Override
public Collection<C> getAllConfigs() {
final List<C> list = new ArrayList<C>();
list.add(config);
return list;
}
}
public static class DefaultConfigWorldConfigProvider extends SimpleWorldConfigProvider<ConfigFile> {
public DefaultConfigWorldConfigProvider() {
super(new DefaultConfig());
}
}
/**
* Initialize BlockProperties with default config and Bukkit-API compliance :p.
*/
public static void initBlockProperties() {
PluginTests.setUnitTestNoCheatPlusAPI(false);
BlockProperties.init(NCPAPIProvider.getNoCheatPlusAPI().getGenericInstanceHandle(MCAccess.class), new DefaultConfigWorldConfigProvider());
}
}
@@ -1,76 +0,0 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.test;
import static org.junit.Assert.fail;
import org.junit.Test;
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.PenaltyAction;
import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.DefaultConfig;
import fr.neatmonster.nocheatplus.penalties.PenaltyNode;
import fr.neatmonster.nocheatplus.permissions.PermissionRegistry;
public class TestActions {
@Test
public void testOptimizedLogActionEmpty() {
PluginTests.setUnitTestNoCheatPlusAPI(false);
PermissionRegistry pReg = NCPAPIProvider.getNoCheatPlusAPI().getPermissionRegistry();
final ConfigFile config = new DefaultConfig();
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")) ;
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.");
}
}
}
@@ -1,75 +0,0 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.test;
import static org.junit.Assert.fail;
import java.util.LinkedList;
import java.util.List;
import org.bukkit.ChatColor;
import org.junit.Test;
import fr.neatmonster.nocheatplus.utilities.ColorUtil;
public class TestColorUtil {
@Test
public void testRemoveColor(){
List<String[]> items = new LinkedList<String[]>();
for (String[] item : new String[][]{
{"", ""},
{" ", " "},
{"&", "&"},
{"&&", "&&"},
{"o3rg7cbo'!§)=?%V823rg7c", "o3rg7cbo'!§)=?%V823rg7c"},
}){
items.add(item);
}
String[][] generic = new String[][]{
{"&/&/&/", ""},
{"&/&/", ""},
{" &/&/ ", " "},
{" &/&/", " "},
{"&/", ""},
{"&/ ", " "},
{" &/", " "},
{"123&/123", "123123"},
};
for (ChatColor color : ChatColor.values()){
char c = color.getChar();
for (String[] pattern : generic){
items.add(new String[]{ pattern[0].replace('/', c), pattern[1]});
}
}
int i = 0;
for (String[] item : items){
String input = item[0];
String expectedOutput = item[1];
String detail = "no details.";
String output = "(ERROR)";
try{
output = ColorUtil.removeColors(input);
}
catch(Throwable t){
detail = t.getClass().getSimpleName() + ": " + t.getMessage();
}
if (!expectedOutput.equals(output)){
fail("Wrong output at index " + i + " for input '" + input + "', expected '" + expectedOutput + "', but got instead: '" + output + "', details: " + detail );
}
i ++;
}
}
}
@@ -1,112 +0,0 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.test;
import static org.junit.Assert.fail;
import org.bukkit.Material;
import org.junit.Test;
import fr.neatmonster.nocheatplus.compat.BridgeMaterial;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.DefaultConfig;
import fr.neatmonster.nocheatplus.config.PathUtils;
import fr.neatmonster.nocheatplus.config.RawConfigFile;
import fr.neatmonster.nocheatplus.logging.StaticLog;
public class TestConfig {
private void testReadMaterial(String input, Material expectedMat) {
Material mat = RawConfigFile.parseMaterial(input);
if (expectedMat != mat) {
fail("Expected " + expectedMat + " for input '" + input + "', got instead: " + mat);
}
}
@SuppressWarnings("deprecation")
@Test
public void testReadMaterial() {
// Some really needed parts first.
Material lily = BridgeMaterial.LILY_PAD;
String lilys = lily.name();
testReadMaterial(lilys.replaceAll("_", " "), lily);
testReadMaterial(lilys.replaceAll("_", "-"), lily);
testReadMaterial(lilys.replaceAll("e", "E"), lily);
//testReadMaterial("flint and steel", Material.FLINT_AND_STEEL);
//testReadMaterial("259", Material.FLINT_AND_STEEL);
// Generic test.
for (final Material mat : Material.values()) {
if (mat.name().equalsIgnoreCase("LOCKED_CHEST")) {
continue;
}
//testReadMaterial(mat.name(), mat);
//testReadMaterial(Integer.toString(mat.getId()), mat);
}
}
// TODO: More ConfigFile tests, once processing gets changed.
@Test
public void testMovePaths() {
StaticLog.setUseLogManager(false);
ConfigFile config = new ConfigFile();
// Simple moved boolean.
config.set(ConfPaths.LOGGING_FILE, false);
config = PathUtils.processPaths(config, "test", false);
if (config == null) {
fail("Expect config to be changed at all.");
}
if (config.contains(ConfPaths.LOGGING_FILE)) {
fail("Expect path be removed: " + ConfPaths.LOGGING_FILE);
}
Boolean val = config.getBoolean(ConfPaths.LOGGING_BACKEND_FILE_ACTIVE, true);
if (val == null || val.booleanValue()) {
fail("Expect new path to be set to false: " + ConfPaths.LOGGING_BACKEND_FILE_ACTIVE);
}
}
@Test
public void testDefaults() {
ConfigFile defaults = new ConfigFile();
defaults.set("all", 1.0);
defaults.set("defaultsOnly", 1.0);
ConfigFile config = new ConfigFile();
config.setDefaults(defaults);
config.set("all", 2.0);
double val = config.getDouble("all", 3.0);
if (val != 2.0) {
fail("Expect 2.0 if set in config, got instead: " + val);
}
val = config.getDouble("defaultsOnly", 3.0);
if (val != 3.0) { // Pitty.
fail("Expect 3.0 (default argument), got instead: " + val);
}
val = config.getDouble("notset", 3.0);
if (val != 3.0) {
fail("Expect 3.0 (not set), got instead: " + val);
}
}
// @Test
// public void testActionLists() {
// ConfigFile config = new DefaultConfig();
// config.getOptimizedActionList(ConfPaths.MOVING_SURVIVALFLY_ACTIONS, null);
// }
}
@@ -1,43 +0,0 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.test;
import org.junit.Test;
import fr.neatmonster.nocheatplus.PluginTests;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.CheckType.CheckTypeType;
import fr.neatmonster.nocheatplus.permissions.RegisteredPermission;
/**
* Uh oh.
* @author asofold
*
*/
public class TestDump {
@Test
public void dumpCheckSilentPermissionForPluginYML() {
PluginTests.setUnitTestNoCheatPlusAPI(false);
for (CheckType checkType : CheckType.values()) {
final RegisteredPermission permission = checkType.getPermission();
// Only add for actual checks at present.
if (permission == null || checkType.getType() != CheckTypeType.CHECK) {
continue;
}
// Print:
System.out.print(" " + permission.getStringRepresentation() + ".silent:\n default: false\n");
}
}
}
@@ -1,173 +0,0 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.test;
import org.bukkit.Material;
import org.junit.Test;
import fr.neatmonster.nocheatplus.compat.BridgeMaterial;
import fr.neatmonster.nocheatplus.logging.StaticLog;
import fr.neatmonster.nocheatplus.utilities.build.BuildParameters;
import fr.neatmonster.nocheatplus.utilities.collision.InteractRayTracing;
import fr.neatmonster.nocheatplus.utilities.map.FakeBlockCache;
public class TestInteractRayTracing {
public final class CenteredInteractRayTracing extends InteractRayTracing {
private int centerX, centerY, centerZ;
public CenteredInteractRayTracing(boolean strict, int centerX, int centerY, int centerZ) {
super(strict);
this.centerX = centerX;
this.centerY = centerY;
this.centerZ = centerZ;
}
@Override
public void set(double x0, double y0, double z0, double x1, double y1, double z1) {
super.set(x0, y0, z0, x1, y1, z1, centerX, centerY, centerZ);
}
}
// TODO: Blunt copy and paste from TestPassableRayTracing, add something that makes sense.
public TestInteractRayTracing() {
StaticLog.setUseLogManager(false);
BlockTests.initBlockProperties();
StaticLog.setUseLogManager(true);
}
@Test
public void testAir() {
FakeBlockCache bc = new FakeBlockCache();
InteractRayTracing rt = new InteractRayTracing();
rt.setBlockCache(bc);
double[] coords = new double[]{0.5, 0.5, -0.5, 0.5, 0.5, 1.5};
rt.set(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
rt.loop();
if (rt.collides()) {
TestRayTracing.doFail("Expect not to collide with air.", coords);
}
if (rt.getStepsDone() > 4) {
TestRayTracing.doFail("Expect less than 4 steps for moving straight through a block of air.", coords);
}
rt.cleanup();
bc.cleanup();
}
/**
* Moving diagonally through an "empty corner", seen from above:<br>
* ox<br>
* xo
*/
@Test
public void testEmptyCorner() {
FakeBlockCache bc = new FakeBlockCache();
// The "empty corner" setup.
for (int y = 70 ; y < 73; y ++) {
bc.set(10, y, 10, Material.STONE);
bc.set(11, y, 11, Material.STONE);
}
// Ground.
for (int x = 9; x < 13; x++) {
for (int z = 9; z < 13; z++) {
bc.set(x, 69, z, Material.STONE);
}
}
// TODO: Make work with strict set to false.
//InteractRayTracing rt = new InteractRayTracing(true);
InteractRayTracing rt = new InteractRayTracing(false);
rt.setBlockCache(bc);
// TODO: More Directions, also just behind the corner.
double[][] setups = new double[][] {
// Slightly off the middle (11, y, 11)
{11.4, 70.0, 10.4, 10.6, 70.0, 11.4},
// Going exactly through the middle (11, y, 11)
{11.4, 70.0, 10.6, 10.6, 70.0, 11.4},
{11.5, 70.0, 10.5, 10.5, 70.0, 11.5},
};
TestRayTracing.runCoordinates(rt, setups, true, false, 3.0, true);
rt.cleanup();
bc.cleanup();
}
@Test
public void testWall() {
FakeBlockCache bc = new FakeBlockCache();
// Wall using full blocks.
bc.walls(0, 65, 0, 16, 67, 0, Material.STONE);
// Ground using full blocks (roughly 16 margin to each side).
bc.fill(-16, 64, -16, 32, 64, 16, Material.STONE);
// TODO: Test chest like bounds for target blocks.
InteractRayTracing rt = new InteractRayTracing(false);
rt.setBlockCache(bc);
// TODO: More cases, head inside block itself, angles, ...
double[][] noCollision = new double[][] {
{8.5, 66.75, 1.2 , 8.5, 65.8, 1.0},
{8.5, 66.75, 1.2 , 8.5, 70.0, 0.9},
};
TestRayTracing.runCoordinates(rt, noCollision, false, true, 3.0, true);
double[][] shouldCollide = new double[][] {
{8.5, 66.75, 1.2 , 8.5, 65.8, 0.0},
{8.5, 66.75, 1.2 , 8.5, 65.8, -0.2},
};
TestRayTracing.runCoordinates(rt, shouldCollide, true, false, 3.0, true);
rt.cleanup();
bc.cleanup();
}
@Test
public void testRoom() {
// TODO: Test for differing middle points (negative to positive range, random, selected rays).
FakeBlockCache bc = new FakeBlockCache();
bc.room(-1, 64, -1, 1, 66, 1, Material.STONE);
// Note that reversed checks are slightly different with the centered version, but start + end blocks are air anyway.
double[] middle = new double[] {0.5, 65.5, 0.5}; // Free spot.
// TODO: Must work with strict set to false.
CenteredInteractRayTracing rt = new CenteredInteractRayTracing(false, 0, 65, 0);
//CenteredInteractRayTracing rt = new CenteredInteractRayTracing(true, 0, 65, 0);
rt.setBlockCache(bc);
double[][] pastFailures = new double[][] {
{2.1393379885667643, 67.18197661625649, 1.7065201483677281 , 0.0, 65.0, 0.0},
{2.7915547712543676, 66.65545738305906, 1.310222428430474 , 0.0, 65.0, 0.0},
{0.0, 65.0, 4.5 , 0.0, 65.0, 1.0}, // strict is false.
{-3.5, 61.5, -3.5 , 0.0, 65.0, 0.0} // strict is false.
};
TestRayTracing.runCoordinates(rt, pastFailures, true, false, 3, true);
boolean intense = BuildParameters.testLevel > 1;
for (double x = -0.5; x < 1.0; x += 0.5) {
for (double y = -0.5; y < 1.0; y += 0.5) {
for (double z = -0.5; z < 1.0; z += 0.5) {
double add = Math.abs(x) + Math.abs(y) + Math.abs(z);
TestRayTracing.runCenterRays(rt, middle[0] + x, middle[1] + y, middle[2] + z, 2.0 + add, intense ? 10000 : 1000, true, false, true);
}
}
}
rt.cleanup();
bc.cleanup();
}
/**
* Test cases taken from ingame logging.
*/
@Test
public void testIngame() {
// Circle around the corners of 4 blocks with left button pressed down (random sample).
// Bad end coords (should fail):
{FakeBlockCache fbc = new FakeBlockCache();
double[] _fb = new double[]{0.0, 0.0, 0.0, 1.0, 1.0, 1.0};
fbc.set(142, 67, 221, Material.DIRT, 0, _fb);fbc.set(142, 67, 217, BridgeMaterial.GRASS_BLOCK, 0, _fb);fbc.set(142, 69, 219, Material.AIR);fbc.set(142, 68, 218, BridgeMaterial.GRASS_BLOCK, 0, _fb);fbc.set(142, 70, 220, Material.AIR);fbc.set(142, 71, 217, Material.AIR);fbc.set(142, 71, 221, Material.AIR);fbc.set(143, 67, 218, Material.DIRT, 0, _fb);fbc.set(143, 68, 217, BridgeMaterial.GRASS_BLOCK, 0, _fb);fbc.set(143, 68, 221, BridgeMaterial.GRASS_BLOCK, 0, _fb);fbc.set(143, 69, 220, Material.AIR);fbc.set(143, 70, 219, Material.AIR);fbc.set(143, 71, 218, Material.AIR);fbc.set(144, 67, 219, Material.DIRT, 0, _fb);fbc.set(144, 68, 220, BridgeMaterial.GRASS_BLOCK, 0, _fb);fbc.set(144, 69, 217, Material.AIR);
fbc.set(144, 69, 221, BridgeMaterial.TALL_GRASS, 1, new double[]{0.09999999403953552, 0.0, 0.09999999403953552, 0.8999999761581421, 0.800000011920929, 0.8999999761581421});fbc.set(144, 70, 218, Material.AIR);fbc.set(144, 71, 219, Material.AIR);fbc.set(145, 67, 220, Material.DIRT, 0, _fb);fbc.set(145, 68, 219, BridgeMaterial.GRASS_BLOCK, 0, _fb);fbc.set(145, 69, 218, Material.AIR);fbc.set(145, 70, 217, Material.AIR);fbc.set(145, 70, 221, Material.AIR);fbc.set(145, 71, 220, Material.AIR);fbc.set(142, 68, 217, BridgeMaterial.GRASS_BLOCK, 0, _fb);fbc.set(142, 68, 221, BridgeMaterial.GRASS_BLOCK, 0, _fb);fbc.set(142, 67, 218, Material.DIRT, 0, _fb);fbc.set(142, 69, 220, Material.AIR);fbc.set(142, 70, 219, Material.AIR);fbc.set(142, 71, 218, Material.AIR);fbc.set(143, 67, 217, Material.DIRT, 0, _fb);fbc.set(143, 67, 221, Material.DIRT, 0, _fb);fbc.set(143, 68, 218, Material.OBSIDIAN, 0, _fb);fbc.set(143, 69, 219, Material.AIR);fbc.set(143, 70, 220, Material.AIR);fbc.set(143, 71, 217, Material.AIR);fbc.set(143, 71, 221, Material.AIR);fbc.set(144, 67, 220, Material.DIRT, 0, _fb);fbc.set(144, 68, 219, Material.OBSIDIAN, 0, _fb);fbc.set(144, 69, 218, Material.AIR);fbc.set(144, 70, 217, Material.AIR);fbc.set(144, 70, 221, Material.AIR);fbc.set(144, 71, 220, Material.AIR);fbc.set(145, 67, 219, Material.DIRT, 0, _fb);fbc.set(145, 68, 220, BridgeMaterial.GRASS_BLOCK, 0, _fb);fbc.set(145, 69, 217, Material.AIR);fbc.set(145, 69, 221, Material.TORCH, 5, new double[]{0.4000000059604645, 0.0, 0.4000000059604645, 0.6000000238418579, 0.6000000238418579, 0.6000000238418579});fbc.set(145, 70, 218, Material.AIR);fbc.set(145, 71, 219, Material.AIR);fbc.set(142, 67, 219, Material.DIRT, 0, _fb);fbc.set(142, 70, 218, Material.AIR);fbc.set(142, 69, 221, BridgeMaterial.GRASS, 1, new double[]{0.09999999403953552, 0.0, 0.09999999403953552, 0.8999999761581421, 0.800000011920929, 0.8999999761581421});fbc.set(142, 69, 217, Material.AIR);fbc.set(142, 68, 220, BridgeMaterial.GRASS_BLOCK, 0, _fb);fbc.set(142, 71, 219, Material.AIR);fbc.set(143, 67, 220, Material.DIRT, 0, _fb);fbc.set(143, 68, 219, Material.OBSIDIAN, 0, _fb);fbc.set(143, 69, 218, Material.AIR);fbc.set(143, 70, 217, Material.AIR);fbc.set(143, 70, 221, Material.AIR);fbc.set(143, 71, 220, Material.AIR);fbc.set(144, 67, 217, Material.DIRT, 0, _fb);fbc.set(144, 67, 221, Material.DIRT, 0, _fb);fbc.set(144, 68, 218, Material.OBSIDIAN, 0, _fb);fbc.set(144, 69, 219, Material.AIR);fbc.set(144, 70, 220, Material.AIR);fbc.set(144, 71, 217, Material.AIR);fbc.set(144, 71, 221, Material.AIR);fbc.set(145, 67, 218, Material.DIRT, 0, _fb);fbc.set(145, 68, 217, BridgeMaterial.GRASS_BLOCK, 0, _fb);fbc.set(145, 68, 221, BridgeMaterial.GRASS_BLOCK, 0, _fb);fbc.set(145, 69, 220, Material.AIR);fbc.set(145, 70, 219, Material.AIR);fbc.set(145, 71, 218, Material.AIR);fbc.set(142, 68, 219, BridgeMaterial.GRASS_BLOCK, 0, _fb);fbc.set(142, 70, 217, Material.AIR);fbc.set(142, 67, 220, Material.DIRT, 0, _fb);fbc.set(142, 69, 218, BridgeMaterial.GRASS, 1, new double[]{0.09999999403953552, 0.0, 0.09999999403953552, 0.8999999761581421, 0.800000011920929, 0.8999999761581421});fbc.set(142, 70, 221, Material.AIR);fbc.set(142, 71, 220, Material.AIR);fbc.set(143, 67, 219, Material.DIRT, 0, _fb);fbc.set(143, 68, 220, BridgeMaterial.GRASS_BLOCK, 0, _fb);fbc.set(143, 69, 217, Material.AIR);fbc.set(143, 69, 221, Material.AIR);fbc.set(143, 70, 218, Material.AIR);fbc.set(143, 71, 219, Material.AIR);fbc.set(144, 67, 218, Material.DIRT, 0, _fb);fbc.set(144, 68, 217, BridgeMaterial.GRASS_BLOCK, 0, _fb);fbc.set(144, 68, 221, BridgeMaterial.GRASS_BLOCK, 0, _fb);fbc.set(144, 69, 220, Material.AIR);fbc.set(144, 70, 219, Material.AIR);fbc.set(144, 71, 218, Material.AIR);fbc.set(145, 67, 217, Material.DIRT, 0, _fb);fbc.set(145, 67, 221, Material.DIRT, 0, _fb);fbc.set(145, 68, 218, BridgeMaterial.GRASS_BLOCK, 0, _fb);fbc.set(145, 69, 219, Material.AIR);fbc.set(145, 70, 220, Material.AIR);fbc.set(145, 71, 217, Material.AIR);fbc.set(145, 71, 221, Material.AIR);InteractRayTracing rt = new CenteredInteractRayTracing(false, 144, 68, 218);rt.setBlockCache(fbc);TestRayTracing.runCoordinates(rt, new double[]{144.01901074886095, 70.62, 220.1221052415879, 144.07776715103876, 68.99423513239826, 219.0}, true, false, 0.0, false, "ingame");rt.cleanup(); fbc.cleanup();}
}
}
@@ -1,236 +0,0 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.test;
import static org.junit.Assert.fail;
import java.util.Iterator;
import java.util.concurrent.ThreadLocalRandom;
import org.junit.Test;
import fr.neatmonster.nocheatplus.checks.moving.location.tracking.LocationTrace;
import fr.neatmonster.nocheatplus.checks.moving.location.tracking.LocationTrace.ITraceEntry;
import fr.neatmonster.nocheatplus.checks.moving.location.tracking.LocationTrace.TraceEntryPool;
import fr.neatmonster.nocheatplus.checks.moving.location.tracking.LocationTrace.TraceIterator;
public class TestLocationTrace {
/**
* +- radius around 0.0.
* @param radius
* @return
*/
public static double rand(double radius) {
return rand(0.0, radius);
}
/**
* +- radius around center.
* @param center
* @param radius
* @return
*/
public static double rand(double center, double radius) {
return center + 2.0 * radius * (ThreadLocalRandom.current().nextDouble() - 0.5);
}
/**
* center +- step
* @param center
* @param step
* @return
*/
public static double randStep(double center, double step) {
return center + (ThreadLocalRandom.current().nextBoolean() ? step : -step);
}
// TODO: Test pool as well.
private TraceEntryPool pool = new TraceEntryPool(1000);
@Test
public void testSize() {
int size = 80;
LocationTrace trace = new LocationTrace(size, size, pool);
// Empty
if (!trace.isEmpty()) {
fail("Trace must be empty on start.");
}
if (trace.size() != 0) {
fail("Size must be 0 at start.");
}
// Adding up to size elements.
for (int i = 0; i < size ; i++) {
trace.addEntry(i, i, i, i, 0, 0);
if (trace.size() != i + 1) {
fail("Wrong size, expect " + (i + 1) + ", got instead: " + trace.size());
}
}
// Adding a lot of elements.
for (int i = 0; i < 1000; i ++) {
trace.addEntry(i + size, i, i, i, 0, 0);
if (trace.size() != size) {
fail("Wrong size, expect " + size + ", got instead: " + trace.size());
}
}
}
@Test
public void testMergeZeroDist() {
int size = 80;
LocationTrace trace = new LocationTrace(size, size, pool);
for (int i = 0; i < 1000; i ++) {
trace.addEntry(i + size, 0 , 0, 0, 0, 0);
if (trace.size() != 1) {
fail("Wrong size, expect 1, got instead: " + trace.size());
}
}
}
@Test
public void testEmptyIterator() {
// Expected to fail.
int size = 80;
LocationTrace trace = new LocationTrace(size, size, pool);
try {
trace.oldestIterator();
fail("Expect an exception on trying to get an empty iterator (oldest).");
} catch (IllegalArgumentException ex) {
}
try {
trace.latestIterator();
fail("Expect an exception on trying to get an empty iterator (latest).");
} catch (IllegalArgumentException ex) {
}
try {
trace.maxAgeIterator(0);
fail("Expect an exception on trying to get an empty iterator (maxAge).");
} catch (IllegalArgumentException ex) {
}
}
@Test
public void testIteratorSizeAndOrder() {
int size = 80;
LocationTrace trace = new LocationTrace(size, size, pool);
// Adding up to size elements.
for (int i = 0; i < size; i++) {
trace.addEntry(i, i, i, i, 0, 0);
}
// Test size with one time filled up.
testIteratorSizeAndOrder(trace, 80);
// Add size / 2 elements, to test cross-boundary iteration.
for (int i = 0; i < size / 2; i++) {
trace.addEntry(i + size, i, i, i, 0, 0);
}
// Test size again.
testIteratorSizeAndOrder(trace, 80);
}
private void testIteratorSizeAndOrder(LocationTrace trace, int expectedSize) {
int size = trace.size();
if (size != expectedSize) {
fail("LocationTrace size differs from expected. Expect " + expectedSize +", got instead: " + size);
}
TraceIterator[] iterators = new TraceIterator[] {
trace.oldestIterator(),
trace.latestIterator(),
trace.maxAgeIterator(0) // Asserts entries to start at time >= 0.
};
String[] iteratorNames = new String[]{
"oldest",
"latest",
"maxAge"
};
int[] increments = new int[] {
1,
-1,
1
};
for (int i = 0; i < iterators.length; i++) {
int n = 0;
TraceIterator it = iterators[i];
ITraceEntry last = null;
ITraceEntry current = null;
while (it.hasNext()) {
current = it.next();
n ++;
if (n > size) {
fail("Iterator (" + iteratorNames[i] + ") iterates too long.");
}
if (last != null) {
if (current.getTime() - last.getTime() != increments[i]) {
fail("Bad time increment (" + iteratorNames[i] + "). Expected " + increments[i] + ", got instead: " + (current.getTime() - last.getTime()));
}
}
last = current;
}
if (n != size) {
fail("Iterator (" + iteratorNames[i] + ") should have " + size + " elements, found instead: " + n);
}
}
}
@Test
public void testMaxAgeIterator() {
int size = 80;
LocationTrace trace = new LocationTrace(size, size, pool);
// Adding up to size elements.
for (int i = 0; i < size; i++) {
trace.addEntry(i, i, i, i, 0, 0);
}
for (int i = 0; i < size; i++) {
Iterator<ITraceEntry> it = trace.maxAgeIterator(i);
long got = it.next().getTime();
if (got != i) {
fail("Bad entry point for iterator (maxAge), expected " + i + ", got instead: " + got);
}
int n = 1;
while (it.hasNext()) {
it.next();
n ++;
}
if (n != size - i) {
fail("Bad number of elements for iterator (maxAge), expected " + (size - i) + ", got instead: " + n);
}
}
}
@Test
public void testMaxAgeFirstElementAnyway() {
int size = 80;
LocationTrace trace = new LocationTrace(size, size, pool);
trace.addEntry(0, 0, 0, 0, 0, 0);
if (!trace.maxAgeIterator(1000).hasNext()) {
fail("Expect iterator (maxAge) to always contain the latest element.");
}
trace.addEntry(1, 0, 0, 0, 0, 0);
final Iterator<ITraceEntry> it = trace.maxAgeIterator(2);
if (!it.hasNext()) {
fail("Expect iterator (maxAge) to always contain the latest element.");
}
it.next();
if (it.hasNext()) {
fail("Expect iterator (maxAge) to have only the latest element for all out of range entries.");
}
}
// TODO: Tests with expiration of entries (size and iterators).
}
@@ -1,201 +0,0 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.test;
import org.bukkit.Material;
import org.junit.Test;
import fr.neatmonster.nocheatplus.compat.BridgeMaterial;
import fr.neatmonster.nocheatplus.logging.StaticLog;
import fr.neatmonster.nocheatplus.utilities.build.BuildParameters;
import fr.neatmonster.nocheatplus.utilities.collision.PassableRayTracing;
import fr.neatmonster.nocheatplus.utilities.map.BlockProperties;
import fr.neatmonster.nocheatplus.utilities.map.BlockFlags;
import fr.neatmonster.nocheatplus.utilities.map.FakeBlockCache;
public class TestPassableRayTracing {
// TODO: Which tests to run on ICollidePassable with PassableAxisRayTracing as well...
// TODO: Moving into a block,
// TODO: Moving out of a block
// TODO: Moving horizontally on various kinds of ground (normal, half blocks)
// TODO: Moving up stairs etc ?
// TODO: From ground and onto ground moves, onto-edge moves (block before edge, into block, etc).
// TODO: Randomized tests (Collide with inner sphere, not collide with outer sphere).
public TestPassableRayTracing() {
StaticLog.setUseLogManager(false);
BlockTests.initBlockProperties();
StaticLog.setUseLogManager(true);
}
@Test
public void testAir() {
FakeBlockCache bc = new FakeBlockCache();
PassableRayTracing rt = new PassableRayTracing();
rt.setBlockCache(bc);
double[] coords = new double[]{0.5, 0.5, -0.5, 0.5, 0.5, 1.5};
rt.set(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
rt.loop();
if (rt.collides()) {
TestRayTracing.doFail("Expect not to collide when moving through a block.", coords);
}
if (rt.getStepsDone() > 4) {
TestRayTracing.doFail("Expect less than 4 steps for moving straight through a block of air.", coords);
}
rt.cleanup();
bc.cleanup();
}
@Test
public void testThroughOneBlock() {
FakeBlockCache bc = new FakeBlockCache();
bc.set(0, 0, 0, Material.STONE);
PassableRayTracing rt = new PassableRayTracing();
rt.setBlockCache(bc);
double[][] setups = new double[][] {
// Through the middle of the block.
{0.5, 0.5, -0.5, 0.5, 0.5, 1.5},
{-0.5, 0.5, 0.5, 1.5, 0.5, 0.5},
{0.5, -0.5, 0.5, 0.5, 1.5, 0.5},
// Along the edges.
{0.5, 0.0, -0.5, 0.5, 0.0, 1.5},
{-0.5, 0.0, 0.5, 1.5, 0.0, 0.5},
// Exactly diagonal.
{-0.5, -0.5, -0.5, 1.5, 1.5, 1.5}, // 3d
{-0.5, 0.0, -0.5, 1.5, 0.0, 1.5}, // 2d
// Through a corner.
{1.2, 0.5, 0.5, 0.5, 0.5, 1.2},
// TODO: More of each and other... + generic set-ups?
};
TestRayTracing.runCoordinates(rt, setups, true, false, 3.0, true);
rt.cleanup();
bc.cleanup();
}
/**
* Moving diagonally through an "empty corner", seen from above:<br>
* ox<br>
* xo
*/
@Test
public void testEmptyCorner() {
FakeBlockCache bc = new FakeBlockCache();
// The "empty corner" setup.
bc.set(10, 70, 10, Material.STONE);
bc.set(11, 70, 11, Material.STONE);
// Ground.
for (int x = 9; x < 13; x++) {
for (int z = 9; z < 13; z++) {
bc.set(x, 69, z, Material.STONE);
}
}
PassableRayTracing rt = new PassableRayTracing();
rt.setBlockCache(bc);
// TODO: More Directions, over a corner, sides, etc.
double[][] setups = new double[][] {
// Slightly off the middle (11, y, 11)
{11.4, 70.0, 10.4, 10.6, 70.0, 11.4},
// Going exactly through the middle (11, y, 11)
{11.4, 70.0, 10.6, 10.6, 70.0, 11.4},
{11.5, 70.0, 10.5, 10.5, 70.0, 11.5},
//{11.5, 70.0, 10.5, 10.99999999999, 70.0, 11.00000000001}, // TODO: Craft something here
};
TestRayTracing.runCoordinates(rt, setups, true, false, 3.0, true);
rt.cleanup();
bc.cleanup();
}
@Test
public void testGround() {
FakeBlockCache bc = new FakeBlockCache();
// Ground using full blocks.
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
bc.set(x, 65, z, Material.STONE);
}
}
PassableRayTracing rt = new PassableRayTracing();
rt.setBlockCache(bc);
// TODO: More Directions, also from air underneath to ground).
double[][] noCollision = new double[][] {
{1.3, 66.0, 2.43, 5.25, 66.0, 7.12},
};
TestRayTracing.runCoordinates(rt, noCollision, false, true, 3.0, true);
double[][] shouldCollide = new double[][] {
{1.3, 65.1, 2.43, 2.3, 65.1, 4.43},
{1.3, 65.0, 2.43, 2.3, 65.0, 4.43},
{1.3, 66.0, 2.43, 1.3, 65.9, 2.43},
{1.3, 66.0, 2.43, 5.25, 65.9, 7.12},
{1.3, 65.4, 2.43, 1.3, 65.4, 2.43}, // No distance.
};
TestRayTracing.runCoordinates(rt, shouldCollide, true, false, 3.0, true);
rt.cleanup();
bc.cleanup();
}
@Test
public void testGroundSteps() {
FakeBlockCache bc = new FakeBlockCache();
// Ground using 0.5 high step blocks.
final double[] stepBounds = new double[]{0.0, 0.0, 0.0, 1.0, 0.5, 1.0};
BlockFlags.setBlockFlags(BridgeMaterial.STONE_SLAB, BlockFlags.F_SOLID | BlockFlags.F_GROUND);
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
bc.set(x, 65, z, BridgeMaterial.STONE_SLAB, stepBounds);
}
}
PassableRayTracing rt = new PassableRayTracing();
rt.setBlockCache(bc);
// TODO: More Directions, also from air underneath to ground).
double[][] noCollision = new double[][] {
{1.3, 65.5, 2.43, 5.25, 65.5, 7.12},
};
TestRayTracing.runCoordinates(rt, noCollision, false, true, 3.0, true);
double[][] shouldCollide = new double[][] {
{1.3, 65.1, 2.43, 2.3, 65.1, 7.43},
{1.3, 65.0, 2.43, 2.3, 65.0, 7.43},
{1.3, 65.5, 2.43, 1.3, 65.4, 2.43},
{1.3, 65.5, 2.43, 5.25, 65.4, 7.12},
{1.3, 65.4, 2.43, 1.3, 65.4, 2.43}, // No distance.
};
TestRayTracing.runCoordinates(rt, shouldCollide, true, false, 3.0, true);
rt.cleanup();
bc.cleanup();
}
@Test
public void testRoom() {
FakeBlockCache bc = new FakeBlockCache();
bc.room(-1, 64, -1, 1, 66, 1, Material.STONE);
double[] middle = new double[] {0.5, 65.5, 0.5}; // Free spot.
PassableRayTracing rt = new PassableRayTracing();
rt.setBlockCache(bc);
boolean intense = BuildParameters.testLevel > 1;
for (double x = -0.5; x < 1.0; x += 0.5) {
for (double y = -0.5; y < 1.0; y += 0.5) {
for (double z = -0.5; z < 1.0; z += 0.5) {
double add = Math.abs(x) + Math.abs(y) + Math.abs(z);
TestRayTracing.runCenterRays(rt, middle[0] + x, middle[1] + y, middle[2] + z, 2.0 + add, intense ? 10000 : 1000, true, false, true);
}
}
}
rt.cleanup();
bc.cleanup();
}
}
@@ -1,78 +0,0 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.test;
import static org.junit.Assert.fail;
import org.junit.Test;
import fr.neatmonster.nocheatplus.permissions.PermissionPolicy;
public class TestPermissionPolicy {
private void testToConfigString(PermissionPolicy policy, String expected) {
if (!policy.policyToConfigLine().equals(expected)) {
fail("Expect toConfigString() to result in '" + expected + "', got instead: '" + policy.policyToConfigLine() + "'");
}
}
@Test
public void testConfigString() {
PermissionPolicy policy1 = new PermissionPolicy();
testToConfigString(policy1, "ALWAYS");
policy1.fetchingPolicyInterval(100);
testToConfigString(policy1, "INTERVAL:0.1");
policy1.invalidationOffline(false);
testToConfigString(policy1, "INTERVAL:0.1,-offline");
policy1.invalidationWorld(false);
testToConfigString(policy1, "INTERVAL:0.1,-offline,-world");
}
private void testFromConfigString(PermissionPolicy policy) {
String to = policy.policyToConfigLine();
PermissionPolicy policy2 = new PermissionPolicy();
policy2.setPolicyFromConfigLine(to);
if (!policy.isPolicyEquivalent(policy2)) {
fail("to+from config string yields non equivalent policy.");
}
}
private void testFromConfigString(PermissionPolicy equivalent, String... inputs) {
for (String input : inputs) {
PermissionPolicy policy2 = new PermissionPolicy();
policy2.setPolicyFromConfigLine(input);
if (!equivalent.isPolicyEquivalent(policy2)) {
fail("Expect equivalent policy to '" + equivalent.policyToConfigLine() + "', got instead: " + policy2.policyToConfigLine());
}
}
}
@Test
public void testFromConfigString() {
PermissionPolicy policy1 = new PermissionPolicy();
testFromConfigString(policy1, "ALWAYS", "ALWAYS +offline", "ALWAYS +WORLD", "ALWAYS +world +offline", "ALWAYS:+offline +world");
testFromConfigString(policy1);
policy1.fetchingPolicyInterval(100);
testFromConfigString(policy1, "INTERVAL0.1", "INTERVAL 0.1", "Interval 0.1 +ofFline");
testFromConfigString(policy1);
policy1.invalidationOffline(false);
testFromConfigString(policy1, "INTERVAL 0.1 -offline");
testFromConfigString(policy1);
policy1.invalidationWorld(false);
testFromConfigString(policy1, "INTERVAL 0.1 -world -offline", "INTERVAL 0.1 -offline -world");
testFromConfigString(policy1);
}
}
@@ -1,48 +0,0 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.test;
import static org.junit.Assert.fail;
import org.junit.Test;
import fr.neatmonster.nocheatplus.permissions.PermissionPolicy;
import fr.neatmonster.nocheatplus.permissions.PermissionSettings;
import fr.neatmonster.nocheatplus.permissions.PermissionSettings.PermissionRule;
public class TestPermissionSettings {
@Test
public void testRegex() {
PermissionPolicy dummy = new PermissionPolicy();
String regex = "^nocheatplus\\.checks\\..*\\.silent$";
String permissionName = "nocheatplus.checks.moving.survivalfly.silent";
// Also/rather a config test.
if (!permissionName.matches(regex)) {
fail("Expect regex to match.");
}
PermissionRule rule = PermissionSettings.getMatchingRule("regex:" + regex, dummy);
if (rule == null) {
fail("Expect factory to return a regex rule.");
}
if (!rule.matches(permissionName)) {
fail("Expect rule to match permissions name.");
}
if (rule.matches("xy" + permissionName) || rule.matches(permissionName + "yx")) {
fail("Rule matches wrong start/end.");
}
}
}
@@ -1,387 +0,0 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.test;
import static org.junit.Assert.fail;
import java.util.concurrent.ThreadLocalRandom;
import org.bukkit.Location;
import org.bukkit.util.Vector;
import org.junit.Test;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
import fr.neatmonster.nocheatplus.utilities.build.BuildParameters;
import fr.neatmonster.nocheatplus.utilities.collision.RayTracing;
import fr.neatmonster.nocheatplus.utilities.location.TrigUtil;
public class TestRayTracing {
// TODO: Add a test that fails if going beyond target block coordinate.
protected static double maxFactor = 9.0;
protected static int maxSteps(double dX, double dY, double dZ) {
// TODO: Better calculation.
return (int) (maxFactor * (1 + Math.abs(dX) + Math.abs(dY) + Math.abs(dZ)));
}
public static class CountRayTracing extends RayTracing {
public CountRayTracing(double x0, double y0, double z0, double x1, double y1, double z1) {
super(x0, y0, z0, x1, y1, z1);
}
@Override
protected boolean step(int blockX, int blockY, int blockZ, double oX,
double oY, double oZ, double dT, boolean isPrimary) {
if (step > maxSteps(dX, dY, dZ)) {
System.out.println("[WARNING] Max steps exceeded: " + maxSteps(dX, dY, dZ));
return false;
}
return true;
}
}
public static double[] randomCoords(double max) {
double[] res = new double[6];
for (int i = 0; i < 6 ; i++) {
res[i] = (ThreadLocalRandom.current().nextDouble() * 2.0 - 1.0) * max;
}
return res;
}
public static double[] randomBlockCoords(int max) {
double[] res = new double[6];
for (int i = 0; i < 6 ; i++) {
res[i] = ThreadLocalRandom.current().nextInt(max * 2 + 1) - max;
}
return res;
}
public static void doFail(String message, double[] coords) {
System.out.println("---- Failure trace ----");
System.out.println(message);
if (coords != null) {
System.out.println("{" + coords[0] + ", " + coords[1]+ ", " + coords[2] + " , " + coords[3] + ", " + coords[4]+ ", " + coords[5] + "}");
dumpRawRayTracing(coords);
}
fail(message);
}
/**
* Mostly block-coordinate consistency checking.
* @param coords
* @return
*/
public static RayTracing checkConsistency(final double[] coords) {
RayTracing rt = new RayTracing(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]) {
protected int lbx, lby, lbz;
protected double ldt = 0;
protected double lox, loy, loz;
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.utilities.RayTracing#set(double, double, double, double, double, double)
*/
@Override
public void set(double x0, double y0, double z0, double x1, double y1, double z1) {
super.set(x0, y0, z0, x1, y1, z1);
lbx = blockX - 1;
lby = blockY - 1;
lbz = blockZ - 1;
lox = oX;
loy = oY;
loz = oZ;
ldt = 0;
}
// private boolean ignEdge(double offset, double dTotal) {
// return offset == 1 && dTotal > 0 || offset == 0 && dTotal < 0;
// }
@Override
protected boolean step(int blockX, int blockY, int blockZ, double oX, double oY, double oZ, double dT, boolean isPrimary) {
// TODO: This does not check last step for some occasions where it should.
if (dT < 0.0) {
doFail("dT < 0 at t = " + StringUtil.fdec3.format(t), coords);
}
// TODO: Check if this check makes sense at all (dT=0 happens during multi-transitions).
// if (dT == 0.0 && 1.0 - (t + dT) > tol) {
// if (!ignEdge(oX, dX) && !ignEdge(oY, dY) && !ignEdge(oZ, dZ)) {
// doFail("Premature dT = 0 at t = " + StringUtil.fdec3.format(t), coords);
// }
// }
// checkOffset(oX, "x");
// checkOffset(oY, "y");
// checkOffset(oZ, "z");
// TODO: check with last block coordinates
if (lbx == blockX && lby == blockY && lbz == blockZ) {
if (1.0 - (t + dT) > tol) {
doFail("Expect block coordinates to change with each step (step=" + step + ", t=" + StringUtil.fdec3.format(t) +").", coords);
}
}
// TODO: check offsets
// Set to current.
lbx = blockX;
lby = blockY;
lbz = blockZ;
lox = oX;
loy = oY;
loz = oZ;
ldt = dT;
if (step > maxSteps(dX, dY, dZ)) {
doFail("max steps exceeded: " + maxSteps(dX, dY, dZ), coords);
}
return true;
}
// private void checkOffset(double offset, String name) {
// if (offset < 0.0 || offset > 1.0) {
// doFail("Bad " + name + "-offset: " + offset, coords);
// }
// }
@Override
public void loop() {
super.loop();
checkBlockTarget(coords[3], lbx, lox, dX, ldt, "x");
checkBlockTarget(coords[4], lby, loy, dY, ldt, "y");
checkBlockTarget(coords[5], lbz, loz, dZ, ldt, "z");
}
private void checkBlockTarget(double target, int current, double offset, double dTotal, double dT, String name) {
int b = Location.locToBlock(target);
if (current != b) {
// TODO: Might do with or without these ?
// if (current == b + 1 && dTotal > 0 && offset == 0) return;
// if (current == b - 1 && dTotal < 0 && offset == 1) return;
double diff = Math.abs(dT * dTotal + offset + (double) current - target);
if (diff <= 0.001) {
// TODO: Test how far off this usually is...
// TODO: Narrow down by edge coordinates or so.
return;
}
System.out.println(target + "|" + current + "|" + offset + "|" + dT * dTotal);
// Failure.
doFail("Bad target " + name + "-coordinate: " + current + " instead of " + b + " (" + diff + " off)", coords);
}
}
};
rt.loop();
if (!rt.isEndBlock()) {
// TODO: Fix last transition not taken sometimes (with "off by x-th digit" or "t=0 transition").
// doFail("Incorrect end block.", coords);
}
return rt;
}
public static RayTracing checkNumberOfSteps(double[] coords, int steps) {
CountRayTracing crt = new CountRayTracing(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
crt.loop();
int done = crt.getStepsDone();
if (done != steps) {
doFail("Wrong number of steps: " + done + " instead of " + steps, coords);
}
return crt;
}
public static void dump(int blockX, int blockY, int blockZ, double oX, double oY, double oZ, double t, double dT, boolean isPrimary) {
String sdt = StringUtil.fdec3.format(dT);
if ("0".equals(sdt) && dT > 0) sdt = "0.X";
System.out.println(StringUtil.fdec3.format(t) + " (+" + sdt + "): " + blockX + ", "+blockY + ", " + blockZ + " / " + StringUtil.fdec3.format(oX) + ", " + StringUtil.fdec3.format(oY)+ ", " + StringUtil.fdec3.format(oZ) + (isPrimary ? " (primary)" : ""));
}
public static RayTracing dumpRawRayTracing(final double[] coords) {
RayTracing rt = new RayTracing(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]) {
@Override
protected boolean step(int blockX, int blockY, int blockZ, double oX, double oY, double oZ, double dT, boolean isPrimary) {
dump(blockX, blockY, blockZ, oX, oY, oZ, t, dT, isPrimary);
if (step > maxSteps(dX, dY, dZ)) {
System.out.println("[WARNING] Max steps exceeded: " + maxSteps(dX, dY, dZ));
return false;
}
return true;
}
};
rt.loop();
if (!rt.isEndBlock()) {
System.out.println("[WARNING] Incorrect end block.");
}
return rt;
}
@Test
public void testNumberOfSteps() {
// Hand picked stuff.
checkNumberOfSteps(new double[]{0.5, 0.5, 0.5, 1.5, -0.5, 1.5}, 2);
}
@Test
public void testConsistency() {
// Past failures / making a difference.
for (double[] coords : new double[][] {
// Sort by x0.
{-9.873, -4.773, -3.387, -0.161, -1.879, -7.079},
{-3.0066423238842366, 0.8056808285866079, 5.359238045631369 , 2.0000000356757375, -2.3002237817433757, -5.889349195033338},
{2.5619753859456917, -5.010424935746547, -7.39326637860553 , -4.678643570182639, -2.0000000105642313, -4.634727842675916},
{7.388348424961977, -8.000000029346532, -2.5365675909347507 , 2.17126848312847, 3.236994108042559, -8.423292642985071},
{7.525633617461991, 2.654408573114717, 3.5119744782127893 , 9.99999995904821, 9.599753890871172, 6.721727939686946},
{1.1, 1.1, 1.1 , 1.3, 1.3, 1.3},
{1.1, 1.1, 1.1 , 1.1, 1.1, 1.1},
{-6.0, -4.0, -3.0 , -4.0, -3.0, -2.0},
{-3.0, 3.0, -6.0 , 2.0, -3.0, 4.0},
}) {
checkConsistency(coords);
// Test reversed.
if (coords[0] != coords[3] || coords[1] != coords[4] || coords[2] != coords[5]) {
checkConsistency(new double[] {coords[3], coords [4], coords[5], coords[0], coords[1], coords[2]});
}
}
final boolean e = BuildParameters.testLevel > 0;
// Random tests.
for (int i = 0; i < (e ? 50000000 : 100000); i++) {
checkConsistency(randomCoords(10.0));
}
for (int i = 0; i < (e ? 10000000 : 1000); i++) {
checkConsistency(randomBlockCoords(6));
}
// TODO: Add tests for typical coordinates a with interact, passable.
}
/**
*
* @param rt
* @param setup
* @param expectCollide
* @param expectNotCollide
* @param stepsManhattan
* @param reverse If set to true, end points will be exchanged for this run (not in addition).
* @param tag
*/
public static void runCoordinates(RayTracing rt, double[] setup, boolean expectCollide, boolean expectNotCollide, double stepsManhattan, boolean reverse, String tag) {
if (reverse) {
rt.set(setup[3], setup [4], setup[5], setup[0], setup[1], setup[2]);
tag += "/reversed";
} else {
rt.set(setup[0], setup[1], setup[2], setup[3], setup [4], setup[5]);
}
rt.loop();
if (rt.collides()) {
if (expectNotCollide) {
doFail("Expect not to collide, "+ tag + ".", setup);
}
} else {
if (expectCollide) {
doFail("Expect to collide, "+ tag + ".", setup);
}
}
if (stepsManhattan > 0.0) {
final double maxSteps = stepsManhattan * Math.max(1.0, TrigUtil.manhattan(setup[0], setup[1], setup[2], setup[3], setup[4], setup[5]));
if ((double) rt.getStepsDone() > maxSteps) {
doFail("Expect less than " + maxSteps + " steps, "+ tag + ".", setup);
}
}
}
/**
*
* @param rt
* @param setups Array of Arrays of 6 doubles as argument for RayTracing.set(...).
* @param expectCollide
* @param expectNotCollide
* @param stepsManhattan
* @param testReversed If to test the each ray with reversed end points in addition.
*/
public static void runCoordinates(RayTracing rt, double[][] setups, boolean expectCollide, boolean expectNotCollide, double stepsManhattan, boolean testReversed) {
for (int i = 0; i < setups.length; i++) {
double[] setup = setups[i];
runCoordinates(rt, setup, expectCollide, expectNotCollide, stepsManhattan, false, "index=" + i);
if (testReversed) {
// Reverse.
runCoordinates(rt, setup, expectCollide, expectNotCollide, stepsManhattan, true, "index=" + i);
}
}
}
/**
* Run (some) standard directions towards the center.
* @param rt
* @param cX
* @param cY
* @param cZ
* @param length Rough length of the rays (might be applied per-axis including an additum).
* @param nRandom Test a number of random rays as well.
* @param expectCollide
* @param expectNotCollide
* @param testReversed If to test the each ray with reversed end points in addition.
*/
public static void runCenterRays(RayTracing rt, double cX, double cY, double cZ, double length, int nRandom, boolean expectCollide, boolean expectNotCollide, boolean testReversed) {
double[] mult = new double[] {-1.0, 0.0, 1.0};
for (int ix = 0; ix < 3; ix ++) {
for (int iy = 0; iy < 3; iy++) {
for (int iz = 0; iz < 3; iz++) {
if (ix == 1 && iy == 1 && iz == 1) {
// Skip the center itself.
continue;
}
double[] coords = new double[] {
cX + length * mult[ix],
cY + length * mult[iy],
cZ + length * mult[iz],
cX,
cY,
cZ
};
// TODO: Generate differing target points on/near middle as well.
TestRayTracing.runCoordinates(rt, coords, true, false, 3.0, false, "");
if (testReversed) {
TestRayTracing.runCoordinates(rt, coords, true, false, 3.0, true, "");
}
}
}
}
// TODO: Consider running block coordinates with larger radius (potentially all within some radius?).
for (int n = 0; n < nRandom; n ++) {
// TODO: Check if normalize is necessary.
// One totally random vector.
Vector vec = Vector.getRandom().normalize().multiply(length);
double[] coords = new double[] {
cX + vec.getX(),
cY + vec.getY(),
cZ + vec.getZ(),
cX,
cY,
cZ
};
TestRayTracing.runCoordinates(rt, coords, true, false, 3.0, false, "random");
if (testReversed) {
TestRayTracing.runCoordinates(rt, coords, true, false, 3.0, true, "random");
}
}
}
}
@@ -1,240 +0,0 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.test;
import static org.junit.Assert.fail;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import org.junit.Test;
import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.PluginTests;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.compat.AlmostBoolean;
import fr.neatmonster.nocheatplus.components.config.value.OverrideType;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.DefaultConfig;
import fr.neatmonster.nocheatplus.logging.StaticLog;
import fr.neatmonster.nocheatplus.worlds.IWorldData;
import fr.neatmonster.nocheatplus.worlds.WorldDataManager;
public class TestWorldDataManager {
private WorldDataManager getWorldDataManager() {
PluginTests.setUnitTestNoCheatPlusAPI(false);
return (WorldDataManager) NCPAPIProvider.getNoCheatPlusAPI().getWorldDataManager();
}
/**
* Set in the config taken from the map - create if not yet existent.
*
* @param map
* @param worldName
* @param key
* @param value
*/
void set(Map<String, ConfigFile> map, String worldName, String key, Object value) {
ConfigFile cfg = map.get(worldName);
if (cfg == null) {
cfg = new DefaultConfig();
map.put(worldName, cfg);
}
cfg.set(key, value);
}
/**
* Set for all.
*
* @param map
* @param key
* @param value
*/
void set(Map<String, ConfigFile> map, String key, Object value) {
for (String worldName : map.keySet()) {
set(map, worldName, key, value);
}
}
void setup(Map<String, ConfigFile> map, String... worldNames) {
for (String worldName : worldNames) {
set(map, worldName, "dummy", true);
}
}
@Test
public void BasicTests() {
//PluginTests.setUnitTestNoCheatPlusAPI(false);
StaticLog.setUseLogManager(false);
WorldDataManager worldMan = getWorldDataManager();
Map<String, ConfigFile> rawWorldConfigs = new LinkedHashMap<String, ConfigFile>();
// (Implicitly create configurations via set).
// Default.
set(rawWorldConfigs, null, ConfPaths.COMBINED + ConfPaths.SUB_ACTIVE, "yes");
// All existing.
setup(rawWorldConfigs, null, "Exist1", "Exist2");
set(rawWorldConfigs, ConfPaths.COMBINED_MUNCHHAUSEN_CHECK, "default");
// Exist1
set(rawWorldConfigs, "Exist1", ConfPaths.COMBINED + ConfPaths.SUB_ACTIVE, "no");
// Exist2
set(rawWorldConfigs, "Exist2", ConfPaths.COMBINED_MUNCHHAUSEN_CHECK, false);
// (Might set some particularly interesting values here.)
/////////////////////////
// Apply configuration
/////////////////////////
worldMan.applyConfiguration(rawWorldConfigs);
for (String worldName : Arrays.asList("Exist1", "Exist2")) {
if (rawWorldConfigs.get(worldName) != worldMan.getWorldData(worldName).getRawConfiguration()) {
fail("Raw configuration set wrongly: " + worldName);
}
}
if (!worldMan.getWorldData("notExist1").isCheckActive(CheckType.COMBINED_MUNCHHAUSEN)) {
fail("Inherited from default: COMBINED_MUNCHHAUSEN should be active (-> COMBINED is)");
}
if (!worldMan.getDefaultWorldData().isCheckActive(CheckType.COMBINED_MUNCHHAUSEN)) {
fail("Default: COMBINED_MUNCHHAUSEN should be active (-> COMBINED is)");
}
if (worldMan.getWorldData("Exist1").isCheckActive(CheckType.COMBINED_MUNCHHAUSEN)) {
fail("Specific: COMBINED_MUNCHHAUSEN should not be active (-> COMBINED is not)");
}
if (worldMan.getWorldData("Exist2").isCheckActive(CheckType.COMBINED_MUNCHHAUSEN)) {
fail("Specific: COMBINED_MUNCHHAUSEN should not be active (directly set)");
}
if (!worldMan.getWorldData("notExist2").isCheckActive(CheckType.COMBINED_MUNCHHAUSEN)) {
fail("Inherited from default: COMBINED_MUNCHHAUSEN should be active (-> COMBINED is)");
}
////////////////
// Override
////////////////
// Override via config "reload":
set(rawWorldConfigs, "Exist2", ConfPaths.COMBINED_MUNCHHAUSEN_CHECK, true);
worldMan.applyConfiguration(rawWorldConfigs);
if (!worldMan.getWorldData("Exist2").isCheckActive(CheckType.COMBINED_MUNCHHAUSEN)) {
fail("Specific: COMBINED_MUNCHHAUSEN should be active (directly set)");
}
// Specific override (mild).
worldMan.overrideCheckActivation(CheckType.COMBINED, AlmostBoolean.NO,
OverrideType.SPECIFIC, false);
if (worldMan.getWorldData("notExist2").isCheckActive(CheckType.COMBINED_MUNCHHAUSEN)) {
fail("Overridden (inherited from default): COMBINED_MUNCHHAUSEN should not be active (-> COMBINED is not)");
}
worldMan.overrideCheckActivation(CheckType.COMBINED, AlmostBoolean.NO,
OverrideType.SPECIFIC, true);
if (worldMan.getWorldData("notExist2").isCheckActive(CheckType.COMBINED_MUNCHHAUSEN)) {
fail("Overridden (inherited from default): COMBINED_MUNCHHAUSEN should not be active (overrideChildren from COMBINED should explicitly set this)");
}
///////////////////
// Fake reload 1
///////////////////
/*
* NOTE: With this testing scenario, ConfigFile instances within
* rawWorldConfigs stay identical, which would not be the case with a
* ConfigManager based reload.
*/
worldMan.applyConfiguration(rawWorldConfigs);
if (!worldMan.getWorldData("notExist2").isCheckActive(CheckType.COMBINED)) {
fail("Inherited from default: COMBINED should be active after reload.");
}
if (!worldMan.getWorldData("notExist2").isCheckActive(CheckType.COMBINED_MUNCHHAUSEN)) {
fail("Inherited from default: COMBINED_MUNCHHAUSEN should be active (-> COMBINED is)");
}
////////////////
// Override 2
////////////////
worldMan.getWorldData("NotExist3").overrideCheckActivation(CheckType.COMBINED_MUNCHHAUSEN,
AlmostBoolean.NO, OverrideType.SPECIFIC, false);
if (worldMan.getWorldData("notExist3").isCheckActive(CheckType.COMBINED_MUNCHHAUSEN)) {
fail("Overridden (SPECIFIC): COMBINED_MUNCHHAUSEN should not be active (-directly set)");
}
///////////////////
// Fake reload 2
///////////////////
worldMan.applyConfiguration(rawWorldConfigs);
if (!worldMan.getWorldData("notExist3").isCheckActive(CheckType.COMBINED_MUNCHHAUSEN)) {
fail("Overridden (SPECIFIC): COMBINED_MUNCHHAUSEN should be active after reload (COMBINED is)");
}
//////////////////////////////////////////////////////////////////////
///////////////////
// Reset
///////////////////
worldMan = getWorldDataManager();
rawWorldConfigs = new LinkedHashMap<String, ConfigFile>();
set(rawWorldConfigs, null, "dummy", "dummy");
worldMan.applyConfiguration(rawWorldConfigs);
IWorldData defaultWorldData = worldMan.getDefaultWorldData();
// Set all to NO.
defaultWorldData.overrideCheckActivation(CheckType.ALL, AlmostBoolean.NO,
OverrideType.VOLATILE, true);
for (CheckType checkType : CheckType.values()) {
if (defaultWorldData.isCheckActive(checkType)) {
fail("Expect check not to be active: " + checkType);
}
}
// Set all to YES.
defaultWorldData.overrideCheckActivation(CheckType.ALL, AlmostBoolean.YES,
OverrideType.VOLATILE, true);
for (CheckType checkType : CheckType.values()) {
if (!defaultWorldData.isCheckActive(checkType)) {
fail("Expect check to be active: " + checkType);
}
}
// Set FastHeal to NO
defaultWorldData.overrideCheckActivation(CheckType.FIGHT_FASTHEAL, AlmostBoolean.NO,
OverrideType.VOLATILE, true);
if (defaultWorldData.isCheckActive(CheckType.FIGHT_FASTHEAL)) {
fail("Expect FIGHT_FASTHEAL not to be active.");
}
}
}