mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-09-03 19:00:30 +02:00
Let APIUtils.needsSynchronization include NET, use a HashMap, add tests.
This commit is contained in:
parent
81d10a314c
commit
7ab21d9e72
|
@ -3,6 +3,7 @@ package fr.neatmonster.nocheatplus.hooks;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -18,28 +19,47 @@ public class APIUtils {
|
||||||
|
|
||||||
/** Only the children. */
|
/** Only the children. */
|
||||||
private static final Map<CheckType, CheckType[]> childrenMap = new HashMap<CheckType, CheckType[]>();
|
private static final Map<CheckType, CheckType[]> childrenMap = new HashMap<CheckType, CheckType[]>();
|
||||||
|
|
||||||
/** Check including children, for convenient iteration. */
|
/** Check including children, for convenient iteration. */
|
||||||
private static final Map<CheckType, CheckType[]> withChildrenMap = new HashMap<CheckType, CheckType[]>();
|
private static final Map<CheckType, CheckType[]> withChildrenMap = new HashMap<CheckType, CheckType[]>();
|
||||||
|
|
||||||
|
/** Checks/groups that might be run off the primary thread. */
|
||||||
|
private static final Set<CheckType> needSync = new HashSet<CheckType>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
// Parent/children relations.
|
||||||
final Map<CheckType, Set<CheckType>> map = new HashMap<CheckType, Set<CheckType>>();
|
final Map<CheckType, Set<CheckType>> map = new HashMap<CheckType, Set<CheckType>>();
|
||||||
for (final CheckType type : CheckType.values())
|
for (final CheckType type : CheckType.values())
|
||||||
map.put(type, new LinkedHashSet<CheckType>());
|
map.put(type, new LinkedHashSet<CheckType>());
|
||||||
for (final CheckType type : CheckType.values()){
|
for (final CheckType type : CheckType.values()){
|
||||||
if (type != CheckType.ALL) map.get(CheckType.ALL).add(type);
|
if (type != CheckType.ALL) map.get(CheckType.ALL).add(type);
|
||||||
for (final CheckType other : CheckType.values()){
|
for (final CheckType other : CheckType.values()){
|
||||||
if (isParent(other, type)) map.get(other).add(type);
|
if (isParent(other, type)) map.get(other).add(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (final CheckType parent : map.keySet()){
|
for (final CheckType parent : map.keySet()){
|
||||||
final Set<CheckType> set = map.get(parent);
|
final Set<CheckType> set = map.get(parent);
|
||||||
final CheckType[] a = new CheckType[set.size()];
|
final CheckType[] a = new CheckType[set.size()];
|
||||||
childrenMap.put(parent, set.toArray(a));
|
childrenMap.put(parent, set.toArray(a));
|
||||||
final CheckType[] aw = new CheckType[set.size() + 1];
|
final CheckType[] aw = new CheckType[set.size() + 1];
|
||||||
set.toArray(aw);
|
set.toArray(aw);
|
||||||
aw[set.size()] = parent;
|
aw[set.size()] = parent;
|
||||||
withChildrenMap.put(parent, aw);
|
withChildrenMap.put(parent, aw);
|
||||||
|
}
|
||||||
|
// needSync: Note that tests use the same definitions.
|
||||||
|
for (final CheckType checkType : new CheckType[]{CheckType.CHAT, CheckType.NET}) {
|
||||||
|
needSync.add(checkType);
|
||||||
|
}
|
||||||
|
boolean added = true;
|
||||||
|
while (added) { // Just in case.
|
||||||
|
added = false;
|
||||||
|
for (final CheckType checkType: CheckType.values()) {
|
||||||
|
// Fill in needSync.
|
||||||
|
if (checkType.getParent() != null && !needSync.contains(checkType) && needSync.contains(checkType.getParent())) {
|
||||||
|
needSync.add(checkType);
|
||||||
|
added = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +74,7 @@ public class APIUtils {
|
||||||
public static final Collection<CheckType> getChildren(final CheckType type) {
|
public static final Collection<CheckType> getChildren(final CheckType type) {
|
||||||
return Arrays.asList(childrenMap.get(type));
|
return Arrays.asList(childrenMap.get(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an unmodifiable collection of the given check type with children. Always returns a collection, does
|
* Return an unmodifiable collection of the given check type with children. Always returns a collection, does
|
||||||
* contain the check type itself.
|
* contain the check type itself.
|
||||||
|
@ -78,14 +98,20 @@ public class APIUtils {
|
||||||
* @return true, if is parent
|
* @return true, if is parent
|
||||||
*/
|
*/
|
||||||
public static final boolean isParent(final CheckType supposedParent, final CheckType supposedChild) {
|
public static final boolean isParent(final CheckType supposedParent, final CheckType supposedChild) {
|
||||||
if (supposedParent == supposedChild) return false;
|
if (supposedParent == supposedChild) {
|
||||||
else if (supposedParent == CheckType.ALL) return true;
|
return false;
|
||||||
|
}
|
||||||
|
else if (supposedParent == CheckType.ALL) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
CheckType parent = supposedChild.getParent();
|
CheckType parent = supposedChild.getParent();
|
||||||
while (parent != null)
|
while (parent != null)
|
||||||
if (parent == supposedParent)
|
if (parent == supposedParent) {
|
||||||
return true;
|
return true;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
parent = parent.getParent();
|
parent = parent.getParent();
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +125,7 @@ public class APIUtils {
|
||||||
* @return true, if successful
|
* @return true, if successful
|
||||||
*/
|
*/
|
||||||
public static final boolean needsSynchronization(final CheckType type) {
|
public static final boolean needsSynchronization(final CheckType type) {
|
||||||
return type == CheckType.CHAT || isParent(CheckType.CHAT, type);
|
return needSync.contains(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package fr.neatmonster.nocheatplus;
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||||
|
import fr.neatmonster.nocheatplus.hooks.APIUtils;
|
||||||
|
|
||||||
|
public class TestCheckType {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsParent() {
|
||||||
|
for (CheckType parent : CheckType.values()) {
|
||||||
|
if (parent != CheckType.ALL && !APIUtils.isParent(CheckType.ALL, parent)) {
|
||||||
|
fail("Expect ALL to be parent of " + parent + " .");
|
||||||
|
}
|
||||||
|
// Rough simplified check by naming.
|
||||||
|
String parentName = parent.getName();
|
||||||
|
for (final CheckType child : CheckType.values()) {
|
||||||
|
if (child == parent) {
|
||||||
|
if (APIUtils.isParent(parent, child)) {
|
||||||
|
fail("Check can't be parent of itself: " + parent);
|
||||||
|
}
|
||||||
|
// Ignore otherwise.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String childName = child.getName();
|
||||||
|
if (childName.startsWith(parentName) && childName.charAt(parentName.length()) == '.' && !APIUtils.isParent(parent, child)) {
|
||||||
|
fail("Expect " + parentName + " to be parent of " + childName + ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNeedsSynchronization() {
|
||||||
|
for (CheckType parent : new CheckType[]{CheckType.CHAT, CheckType.NET}) {
|
||||||
|
for (CheckType type : CheckType.values()) {
|
||||||
|
if ((parent == type || APIUtils.isParent(parent, type)) && !APIUtils.needsSynchronization(type)) {
|
||||||
|
fail("Expect " + type + " to need synchronization, as it is child of " + parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user