mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-10-04 09:27:30 +02:00
Add periodic consistency checking.
Mainly this is now an "ability", in terms of allowing for registration f a ConsistencyChecker component. With this commit DataMan will check the online-players map for consistency, LetterEngine(chat.text) will check expiration of data, NCPExemptionManager will check entity-ids.
This commit is contained in:
parent
e0b2eb753c
commit
74a935ccd6
@ -30,6 +30,7 @@ import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
|
||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.checks.blockbreak.BlockBreakListener;
|
||||
@ -46,6 +47,7 @@ import fr.neatmonster.nocheatplus.command.INotifyReload;
|
||||
import fr.neatmonster.nocheatplus.compat.MCAccess;
|
||||
import fr.neatmonster.nocheatplus.compat.MCAccessFactory;
|
||||
import fr.neatmonster.nocheatplus.components.ComponentWithName;
|
||||
import fr.neatmonster.nocheatplus.components.ConsistencyChecker;
|
||||
import fr.neatmonster.nocheatplus.components.INeedConfig;
|
||||
import fr.neatmonster.nocheatplus.components.MCAccessHolder;
|
||||
import fr.neatmonster.nocheatplus.components.NCPListener;
|
||||
@ -263,13 +265,6 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
|
||||
return done.size();
|
||||
}
|
||||
|
||||
/** The event listeners. */
|
||||
private final List<Listener> listeners = new ArrayList<Listener>();
|
||||
|
||||
/** Components that need notification on reloading.
|
||||
* (Kept here, for if during runtime some might get added.)*/
|
||||
private final List<INotifyReload> notifyReload = new LinkedList<INotifyReload>();
|
||||
|
||||
/** Is the configuration outdated? */
|
||||
private boolean configOutdated = false;
|
||||
|
||||
@ -279,6 +274,10 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
|
||||
/** Player data future stuff. */
|
||||
protected final DataManager dataMan = new DataManager();
|
||||
|
||||
private int dataManTaskId = -1;
|
||||
|
||||
protected Metrics metrics = null;
|
||||
|
||||
/**
|
||||
* Commands that were changed for protecting them against tab complete or
|
||||
* use.
|
||||
@ -290,14 +289,27 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
|
||||
|
||||
private boolean manageListeners = true;
|
||||
|
||||
/** The event listeners. */
|
||||
private final List<Listener> listeners = new ArrayList<Listener>();
|
||||
|
||||
/** Components that need notification on reloading.
|
||||
* (Kept here, for if during runtime some might get added.)*/
|
||||
private final List<INotifyReload> notifyReload = new LinkedList<INotifyReload>();
|
||||
|
||||
/** Permission states stored on a per-world basis, updated with join/quit/kick. */
|
||||
protected final List<PermStateReceiver> permStateReceivers = new ArrayList<PermStateReceiver>();
|
||||
|
||||
/** Components that check consistency. */
|
||||
protected final List<ConsistencyChecker> consistencyCheckers = new ArrayList<ConsistencyChecker>();
|
||||
|
||||
/** Index at which to continue. */
|
||||
protected int consistencyCheckerIndex = 0;
|
||||
|
||||
protected int consistencyCheckerTaskId = -1;
|
||||
|
||||
/** All registered components. */
|
||||
protected Set<Object> allComponents = new LinkedHashSet<Object>(50);
|
||||
|
||||
protected Metrics metrics = null;
|
||||
|
||||
private int dataManTaskId = -1;
|
||||
|
||||
@Override
|
||||
public boolean addComponent(final Object obj) {
|
||||
@ -324,13 +336,18 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
|
||||
added = true;
|
||||
}
|
||||
if (obj instanceof MCAccessHolder){
|
||||
// Add to allComponents.
|
||||
// These will get notified in initMcAccess (iterates over allComponents).
|
||||
((MCAccessHolder) obj).setMCAccess(getMCAccess());
|
||||
added = true;
|
||||
}
|
||||
if (obj instanceof ConsistencyChecker){
|
||||
consistencyCheckers.add((ConsistencyChecker) obj);
|
||||
added = true;
|
||||
}
|
||||
// Also add to DataManager, which will pick what it needs.
|
||||
// TODO: This is fishy in principle, something more concise?
|
||||
if (dataMan.addComponent(obj)) added = true;
|
||||
// Add to allComponents if in fact added.
|
||||
if (added) allComponents.add(obj);
|
||||
return added;
|
||||
}
|
||||
@ -381,6 +398,9 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
|
||||
if (obj instanceof INotifyReload) {
|
||||
notifyReload.remove(obj);
|
||||
}
|
||||
if (obj instanceof ConsistencyChecker){
|
||||
consistencyCheckers.remove(obj);
|
||||
}
|
||||
dataMan.removeComponent(obj);
|
||||
allComponents.remove(obj);
|
||||
}
|
||||
@ -408,8 +428,13 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
|
||||
listenerManager.setRegisterDirectly(false);
|
||||
listenerManager.clear();
|
||||
|
||||
BukkitScheduler sched = getServer().getScheduler();
|
||||
|
||||
// Stop data-man task.
|
||||
if (dataManTaskId != -1) getServer().getScheduler().cancelTask(dataManTaskId);
|
||||
if (dataManTaskId != -1){
|
||||
sched.cancelTask(dataManTaskId);
|
||||
dataManTaskId = -1;
|
||||
}
|
||||
|
||||
// Stop the tickTask.
|
||||
if (verbose) LogUtil.logInfo("[NoCheatPlus] Stop TickTask...");
|
||||
@ -425,10 +450,15 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
|
||||
metrics.cancel();
|
||||
metrics = null;
|
||||
}
|
||||
|
||||
// Stop consistency checking task.
|
||||
if (consistencyCheckerTaskId != -1){
|
||||
sched.cancelTask(consistencyCheckerTaskId);
|
||||
}
|
||||
|
||||
// Just to be sure nothing gets left out.
|
||||
if (verbose) LogUtil.logInfo("[NoCheatPlus] Stop all remaining tasks...");
|
||||
getServer().getScheduler().cancelTasks(this);
|
||||
sched.cancelTasks(this);
|
||||
|
||||
// Exemptions cleanup.
|
||||
if (verbose) LogUtil.logInfo("[NoCheatPlus] Reset ExemptionManager...");
|
||||
@ -566,9 +596,16 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
|
||||
// Reset Command protection.
|
||||
undoCommandChanges();
|
||||
if (config.getBoolean(ConfPaths.MISCELLANEOUS_PROTECTPLUGINS)) setupCommandProtection();
|
||||
scheduleConsistencyCheckers();
|
||||
}
|
||||
},
|
||||
NCPExemptionManager.getListener(),
|
||||
new ConsistencyChecker() {
|
||||
@Override
|
||||
public void checkConsistency(final Player[] onlinePlayers) {
|
||||
NCPExemptionManager.checkConsistency(onlinePlayers);
|
||||
}
|
||||
},
|
||||
dataMan,
|
||||
new BlockInteractListener(),
|
||||
new BlockBreakListener(),
|
||||
@ -598,6 +635,9 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
|
||||
dataMan.checkExpiration();
|
||||
}
|
||||
}, 1207, 1207);
|
||||
|
||||
// Set up consistency checking.
|
||||
scheduleConsistencyCheckers();
|
||||
|
||||
|
||||
// Setup the graphs, plotters and start Metrics.
|
||||
@ -718,25 +758,6 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
|
||||
// TODO: if (online.lenght > 0) LogUtils.logInfo("[NCP] Updated " + online.length + "players (post-enable).")
|
||||
}
|
||||
|
||||
|
||||
|
||||
// public void onPlayerJoinLow(final PlayerJoinEvent event) {
|
||||
// /*
|
||||
// * ____ _ _ _
|
||||
// * | _ \| | __ _ _ _ ___ _ __ | | ___ (_)_ __
|
||||
// * | |_) | |/ _` | | | |/ _ \ '__| _ | |/ _ \| | '_ \
|
||||
// * | __/| | (_| | |_| | __/ | | |_| | (_) | | | | |
|
||||
// * |_| |_|\__,_|\__, |\___|_| \___/ \___/|_|_| |_|
|
||||
// * |___/
|
||||
// */
|
||||
// // Change the NetServerHandler of the player if requested in the configuration.
|
||||
// final ConfigFile configFile = ConfigManager.getConfigFile();
|
||||
// if (configFile.getBoolean(ConfPaths.MISCELLANEOUS_NOMOVEDTOOQUICKLY_ENABLED, false))
|
||||
// NCPNetServerHandler.changeNetServerHandler(event.getPlayer(),
|
||||
// configFile.getBoolean(ConfPaths.MISCELLANEOUS_NOMOVEDTOOQUICKLY_USEPROXY, false));
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* Quick solution to hide the listener methods, expect refactoring.
|
||||
* @return
|
||||
@ -822,5 +843,72 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void scheduleConsistencyCheckers(){
|
||||
BukkitScheduler sched = getServer().getScheduler();
|
||||
if (consistencyCheckerTaskId != -1){
|
||||
sched.cancelTask(consistencyCheckerTaskId);
|
||||
}
|
||||
ConfigFile config = ConfigManager.getConfigFile();
|
||||
if (!config.getBoolean(ConfPaths.DATA_CONSISTENCYCHECKS_CHECK, true)) return;
|
||||
// Schedule task in seconds.
|
||||
final long delay = 20L * config.getInt(ConfPaths.DATA_CONSISTENCYCHECKS_INTERVAL, 1, 3600, 10);
|
||||
consistencyCheckerTaskId = sched.scheduleSyncRepeatingTask(this, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
runConsistencyChecks();
|
||||
}
|
||||
}, delay, delay );
|
||||
}
|
||||
|
||||
/**
|
||||
* Run consistency checks for at most the configured duration. If not finished, a task will be scheduled to continue.
|
||||
*/
|
||||
protected void runConsistencyChecks(){
|
||||
final long tStart = System.currentTimeMillis();
|
||||
final ConfigFile config = ConfigManager.getConfigFile();
|
||||
if (!config.getBoolean(ConfPaths.DATA_CONSISTENCYCHECKS_CHECK) || consistencyCheckers.isEmpty()){
|
||||
consistencyCheckerIndex = 0;
|
||||
return;
|
||||
}
|
||||
final long tEnd = tStart + config.getLong(ConfPaths.DATA_CONSISTENCYCHECKS_MAXTIME, 1, 50, 2);
|
||||
if (consistencyCheckerIndex >= consistencyCheckers.size()) consistencyCheckerIndex = 0;
|
||||
final Player[] onlinePlayers = getServer().getOnlinePlayers();
|
||||
// Loop
|
||||
while (consistencyCheckerIndex < consistencyCheckers.size()){
|
||||
final ConsistencyChecker checker = consistencyCheckers.get(consistencyCheckerIndex);
|
||||
try{
|
||||
checker.checkConsistency(onlinePlayers);
|
||||
}
|
||||
catch (Throwable t){
|
||||
LogUtil.logSevere("[NoCheatPlus] ConsistencyChecker(" + checker.getClass().getName() + ") encountered an exception:");
|
||||
LogUtil.logSevere(t);
|
||||
}
|
||||
consistencyCheckerIndex ++; // Do not remove :).
|
||||
final long now = System.currentTimeMillis();
|
||||
if (now < tStart || now >= tEnd){
|
||||
break;
|
||||
}
|
||||
}
|
||||
// (The index might be bigger than size by now.)
|
||||
|
||||
final boolean debug = config.getBoolean(ConfPaths.LOGGING_DEBUG);
|
||||
|
||||
// If not finished, schedule further checks.
|
||||
if (consistencyCheckerIndex < consistencyCheckers.size()){
|
||||
getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
runConsistencyChecks();
|
||||
}
|
||||
});
|
||||
if (debug){
|
||||
LogUtil.logInfo("[NoCheatPlus] Re-scheduled consistency-checks.");
|
||||
}
|
||||
}
|
||||
else if (debug){
|
||||
LogUtil.logInfo("[NoCheatPlus] Consistency-checks run.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.checks.chat.ChatConfig;
|
||||
import fr.neatmonster.nocheatplus.checks.chat.ChatData;
|
||||
@ -16,6 +18,7 @@ import fr.neatmonster.nocheatplus.checks.chat.analysis.engine.processors.Similar
|
||||
import fr.neatmonster.nocheatplus.checks.chat.analysis.engine.processors.WordPrefixes;
|
||||
import fr.neatmonster.nocheatplus.checks.chat.analysis.engine.processors.WordPrefixes.WordPrefixesSettings;
|
||||
import fr.neatmonster.nocheatplus.checks.chat.analysis.engine.processors.WordProcessor;
|
||||
import fr.neatmonster.nocheatplus.components.ConsistencyChecker;
|
||||
import fr.neatmonster.nocheatplus.components.IData;
|
||||
import fr.neatmonster.nocheatplus.components.IHaveCheckType;
|
||||
import fr.neatmonster.nocheatplus.components.IRemoveData;
|
||||
@ -29,7 +32,7 @@ import fr.neatmonster.nocheatplus.logging.LogUtil;
|
||||
* @author mc_dev
|
||||
*
|
||||
*/
|
||||
public class LetterEngine implements IRemoveData, IHaveCheckType{
|
||||
public class LetterEngine implements IRemoveData, IHaveCheckType, ConsistencyChecker{
|
||||
|
||||
/** Global processors */
|
||||
protected final List<WordProcessor> processors = new ArrayList<WordProcessor>();
|
||||
@ -122,4 +125,17 @@ public class LetterEngine implements IRemoveData, IHaveCheckType{
|
||||
public final CheckType getCheckType() {
|
||||
return CheckType.CHAT_TEXT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkConsistency(final Player[] onlinePlayers) {
|
||||
// Use consistency checking to release some memory.
|
||||
final long now = System.currentTimeMillis();
|
||||
if (now < dataMap.lastAccess){
|
||||
dataMap.clear();
|
||||
return;
|
||||
}
|
||||
if (now - dataMap.lastAccess > dataMap.durExpire){
|
||||
dataMap.expire(now - dataMap.durExpire);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
package fr.neatmonster.nocheatplus.components;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* This component might be called periodically. Might not be called ever.
|
||||
* @author mc_dev
|
||||
*
|
||||
*/
|
||||
public interface ConsistencyChecker {
|
||||
/**
|
||||
* Perform consistency checking. Depending on configuration this should clean up inconsistent states and/or log problems.
|
||||
* @param onlinePlayers Players as returned by Server.getOnlinePlayers, at the point of time before checking.
|
||||
*/
|
||||
public void checkConsistency(Player[] onlinePlayers);
|
||||
|
||||
// TODO: Might add method to check consistency for single players (on join, on certain check failures).
|
||||
}
|
@ -3,7 +3,7 @@ package fr.neatmonster.nocheatplus.components;
|
||||
|
||||
/**
|
||||
* ComponentRegistry:
|
||||
* <li>Supported components: Listener, TickListener, PermStateReceiver, INotifyReload, INeedConfig, IRemoveData, MCAccessHolder</li>
|
||||
* <li>Supported components: Listener, TickListener, PermStateReceiver, INotifyReload, INeedConfig, IRemoveData, MCAccessHolder, ConsistencyChecker</li>
|
||||
* <li>Registering components should be done during onEnable or any time while the plugin is enabled, all components will be unregistered in onDisable.</li>
|
||||
* <li>References to all components will be held until onDisable is finished.</li>
|
||||
* <li>Interfaces checked for managed listeners: IHaveMethodOrder (method), ComponentWithName (tag)</li>
|
||||
|
@ -56,12 +56,19 @@ public abstract class ConfPaths {
|
||||
/** TEMP: hidden flag to disable all lag adaption with one flag. */
|
||||
public static final String MISCELLANEOUS_LAG = MISCELLANEOUS + "lag";
|
||||
|
||||
// Extended data-related settings.
|
||||
@GlobalConfig
|
||||
private static final String DATA = "data.";
|
||||
// Expired data removal.
|
||||
private static final String DATA_EXPIRATION = DATA + "expiration.";
|
||||
public static final String DATA_EXPIRATION_DURATION = DATA_EXPIRATION + "duration";
|
||||
public static final String DATA_EXPIRATION_DATA = DATA_EXPIRATION + "data";
|
||||
public static final String DATA_EXPIRATION_HISTORY = DATA_EXPIRATION + "history";
|
||||
// Consistency checking.
|
||||
private static final String DATA_CONSISTENCYCHECKS = DATA + "consistencychecks.";
|
||||
public static final String DATA_CONSISTENCYCHECKS_CHECK = DATA_CONSISTENCYCHECKS + "active";
|
||||
public static final String DATA_CONSISTENCYCHECKS_INTERVAL = DATA_CONSISTENCYCHECKS + "interval";
|
||||
public static final String DATA_CONSISTENCYCHECKS_MAXTIME = DATA_CONSISTENCYCHECKS + "maxtime";
|
||||
|
||||
private static final String CHECKS = "checks.";
|
||||
|
||||
|
@ -76,9 +76,14 @@ public class DefaultConfig extends ConfigFile {
|
||||
// set(ConfPaths.MISCELLANEOUS_NOMOVEDTOOQUICKLY_ENABLED, false);
|
||||
// set(ConfPaths.MISCELLANEOUS_NOMOVEDTOOQUICKLY_USEPROXY, false);
|
||||
|
||||
|
||||
// Data settings.
|
||||
// Expired offline players data.
|
||||
set(ConfPaths.DATA_EXPIRATION_DURATION, 0);
|
||||
set(ConfPaths.DATA_EXPIRATION_HISTORY, false);
|
||||
// Consistency checking.
|
||||
set(ConfPaths.DATA_CONSISTENCYCHECKS_CHECK, true);
|
||||
set(ConfPaths.DATA_CONSISTENCYCHECKS_INTERVAL, 10);
|
||||
set(ConfPaths.DATA_CONSISTENCYCHECKS_MAXTIME, 2);
|
||||
|
||||
/*
|
||||
* 888 88b, 888 888 888 88b, 888
|
||||
|
@ -3,6 +3,8 @@ package fr.neatmonster.nocheatplus.hooks;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@ -16,6 +18,8 @@ import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.components.NCPListener;
|
||||
import fr.neatmonster.nocheatplus.logging.LogUtil;
|
||||
import fr.neatmonster.nocheatplus.utilities.StringUtil;
|
||||
|
||||
/*
|
||||
* M"""""""`YM MM'""""'YMM MM"""""""`YM MM""""""""`M dP oo
|
||||
@ -45,7 +49,7 @@ public class NCPExemptionManager {
|
||||
/** A map associating a check type with the entity ids of its exempted players. */
|
||||
private static final Map<CheckType, Set<Integer>> exempted = new HashMap<CheckType, Set<Integer>>();
|
||||
|
||||
/** A map associating the registred player with their entity id. */
|
||||
/** A map associating the registered player with their entity id. */
|
||||
private static final Map<String, Integer> registeredPlayers = new HashMap<String, Integer>();
|
||||
|
||||
static {
|
||||
@ -298,5 +302,34 @@ public class NCPExemptionManager {
|
||||
final Integer entityId = registeredPlayers.get(playerName);
|
||||
if (entityId != null) unexempt(entityId, checkType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Entity-id mappings, for internal use.
|
||||
* @param onlinePlayers
|
||||
*/
|
||||
public static void checkConsistency(final Player[] onlinePlayers){
|
||||
int wrong = 0;
|
||||
for (int i = 0; i < onlinePlayers.length; i++){
|
||||
final Player player = onlinePlayers[i];
|
||||
final int id = player.getEntityId();
|
||||
final String name = player.getName();
|
||||
final Integer presentId = registeredPlayers.get(name);
|
||||
if (presentId == null){
|
||||
// TODO: Could complain.
|
||||
}
|
||||
else if (id != presentId.intValue()){
|
||||
wrong ++;
|
||||
registerPlayer(player);
|
||||
}
|
||||
// TODO: Consider also checking if numbers don't match.
|
||||
}
|
||||
if (wrong != 0){
|
||||
final List<String> details = new LinkedList<String>();
|
||||
if (wrong != 0){
|
||||
details.add("wrong entity-ids (" + + wrong + ")");
|
||||
}
|
||||
LogUtil.logWarning("[NoCheatPlus] ExemptionManager inconsistencies: " + StringUtil.join(details, " | "));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
@ -34,6 +36,7 @@ import fr.neatmonster.nocheatplus.checks.moving.MovingConfig;
|
||||
import fr.neatmonster.nocheatplus.command.INotifyReload;
|
||||
import fr.neatmonster.nocheatplus.components.ComponentRegistry;
|
||||
import fr.neatmonster.nocheatplus.components.ComponentWithName;
|
||||
import fr.neatmonster.nocheatplus.components.ConsistencyChecker;
|
||||
import fr.neatmonster.nocheatplus.components.IHaveCheckType;
|
||||
import fr.neatmonster.nocheatplus.components.INeedConfig;
|
||||
import fr.neatmonster.nocheatplus.components.IRemoveData;
|
||||
@ -41,6 +44,8 @@ import fr.neatmonster.nocheatplus.config.ConfPaths;
|
||||
import fr.neatmonster.nocheatplus.config.ConfigFile;
|
||||
import fr.neatmonster.nocheatplus.config.ConfigManager;
|
||||
import fr.neatmonster.nocheatplus.hooks.APIUtils;
|
||||
import fr.neatmonster.nocheatplus.logging.LogUtil;
|
||||
import fr.neatmonster.nocheatplus.utilities.StringUtil;
|
||||
|
||||
/**
|
||||
* Central access point for a lot of functionality for managing data, especially removing data for cleanup.<br>
|
||||
@ -53,7 +58,7 @@ import fr.neatmonster.nocheatplus.hooks.APIUtils;
|
||||
* @author mc_dev
|
||||
*
|
||||
*/
|
||||
public class DataManager implements Listener, INotifyReload, INeedConfig, ComponentRegistry, ComponentWithName{
|
||||
public class DataManager implements Listener, INotifyReload, INeedConfig, ComponentRegistry, ComponentWithName, ConsistencyChecker{
|
||||
|
||||
protected static DataManager instance = null;
|
||||
|
||||
@ -413,5 +418,48 @@ public class DataManager implements Listener, INotifyReload, INeedConfig, Compon
|
||||
public String getComponentName() {
|
||||
return "NoCheatPlus_DataManager";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkConsistency(final Player[] onlinePlayers) {
|
||||
// Check online player tracking consistency.
|
||||
int missing = 0;
|
||||
int changed = 0;
|
||||
int expectedSize = 0;
|
||||
for (int i = 0; i < onlinePlayers.length; i++){
|
||||
final Player player = onlinePlayers[i];
|
||||
final String name = player.getName();
|
||||
// if (player.isOnline()){
|
||||
expectedSize += 1 + (name.equals(name.toLowerCase()) ? 0 : 1);
|
||||
if (!this.onlinePlayers.containsKey(name)){
|
||||
missing ++;
|
||||
// TODO: Add the player [problem: messy NPC plugins?]?
|
||||
}
|
||||
if (player != this.onlinePlayers.get(name)){
|
||||
changed ++;
|
||||
// Update the reference.
|
||||
addOnlinePlayer(player);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Consider checking lastLogout for too long gone players.
|
||||
|
||||
final int storedSize = this.onlinePlayers.size();
|
||||
if (missing != 0 || changed != 0 || expectedSize != storedSize){
|
||||
final List<String> details = new LinkedList<String>();
|
||||
if (missing != 0){
|
||||
details.add("missing online players (" + missing + ")");
|
||||
}
|
||||
if (expectedSize != storedSize){
|
||||
// TODO: Consider checking for not online players and remove them.
|
||||
details.add("wrong number of online players (" + storedSize + " instead of " + expectedSize + ")");
|
||||
}
|
||||
if (changed != 0){
|
||||
details.add("changed player instances (" + changed + ")");
|
||||
}
|
||||
|
||||
LogUtil.logWarning("[NoCheatPlus] DataMan inconsistencies: " + StringUtil.join(details, " | "));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user