More data cleanup.

This commit is contained in:
asofold 2012-11-02 10:40:37 +01:00
parent c6eb573b57
commit 3ce15aa8a0
11 changed files with 162 additions and 48 deletions

View File

@ -31,11 +31,12 @@ import fr.neatmonster.nocheatplus.checks.inventory.InventoryListener;
import fr.neatmonster.nocheatplus.checks.moving.MovingListener;
import fr.neatmonster.nocheatplus.command.CommandHandler;
import fr.neatmonster.nocheatplus.command.INotifyReload;
import fr.neatmonster.nocheatplus.components.INeedConfig;
import fr.neatmonster.nocheatplus.components.NoCheatPlusAPI;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.config.DefaultConfig;
import fr.neatmonster.nocheatplus.config.INeedConfig;
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
import fr.neatmonster.nocheatplus.metrics.Metrics;
import fr.neatmonster.nocheatplus.metrics.Metrics.Graph;
@ -61,7 +62,7 @@ import fr.neatmonster.nocheatplus.utilities.Updates;
/**
* This is the main class of NoCheatPlus. The commands, events listeners and tasks are registered here.
*/
public class NoCheatPlus extends JavaPlugin implements Listener {
public class NoCheatPlus extends JavaPlugin implements Listener, NoCheatPlusAPI {
/** Lower case player name to milliseconds point of time of release */
private static final Map<String, Long> denyLoginNames = Collections.synchronizedMap(new HashMap<String, Long>());
@ -120,7 +121,7 @@ public class NoCheatPlus extends JavaPlugin implements Listener {
return isLoginDenied(playerName, System.currentTimeMillis());
}
public String[] getLoginDeniedPlayers() {
public static String[] getLoginDeniedPlayers() {
checkDenyLoginsNames();
String[] kicked = new String[denyLoginNames.size()];
denyLoginNames.keySet().toArray(kicked);
@ -139,6 +140,14 @@ public class NoCheatPlus extends JavaPlugin implements Listener {
if (oldTs == null) return false;
else return time < oldTs.longValue();
}
/**
* Convenience method, delegates to
* @return
*/
public static NoCheatPlusAPI getAPI() {
return (NoCheatPlusAPI) Bukkit.getPluginManager().getPlugin("NoCheatPlus");
}
/** The event listeners. */
private final List<Listener> listeners = new ArrayList<Listener>();
@ -156,25 +165,28 @@ public class NoCheatPlus extends JavaPlugin implements Listener {
/** Player data future stuff. */
protected final DataManager dataMan = new DataManager();
/**
* Convenience method to add components according to implemented interfaces,
* like Listener, INotifyReload, INeedConfig.<br>
* This must be done after the configuration has been initialized.
* @param obj
*/
private void addComponent(final Object obj){
if (obj instanceof Listener){
final Listener listener = (Listener) obj;
Bukkit.getPluginManager().registerEvents(listener, this);
listeners.add(listener);
}
if (obj instanceof INotifyReload){
notifyReload.add((INotifyReload) obj);
if (obj instanceof INeedConfig){
((INeedConfig) obj).onReload();
}
}
}
@Override
public void addComponent(final Object obj) {
if (obj instanceof Listener) {
final Listener listener = (Listener) obj;
Bukkit.getPluginManager().registerEvents(listener, this);
listeners.add(listener);
}
if (obj instanceof INotifyReload) {
notifyReload.add((INotifyReload) obj);
if (obj instanceof INeedConfig) {
((INeedConfig) obj).onReload();
}
}
dataMan.addComponent(obj);
}
@Override
public void removeComponent(final Object obj) {
listeners.remove(obj);
notifyReload.remove(obj);
dataMan.removeComponent(obj);
}
/* (non-Javadoc)
* @see org.bukkit.plugin.java.JavaPlugin#onDisable()
@ -205,6 +217,9 @@ public class NoCheatPlus extends JavaPlugin implements Listener {
// Remove config listeners.
notifyReload.clear();
// More cleanup.
dataMan.onDisable();
// Cleanup the configuration manager.
ConfigManager.cleanup();

View File

@ -2,6 +2,8 @@ package fr.neatmonster.nocheatplus.checks.access;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.components.IRemoveData;
/*
* MM'""""'YMM dP dP M""""""'YMM dP
@ -26,7 +28,7 @@ import org.bukkit.entity.Player;
*
* @author asofold
*/
public interface CheckDataFactory {
public interface CheckDataFactory extends IRemoveData{
/**
* Gets the data of the specified player.
@ -37,16 +39,7 @@ public interface CheckDataFactory {
*/
public ICheckData getData(final Player player);
/**
* Remove data of a player.
* @param playerName Must match exactly, must be player name for command use and cleanup tasks.
* @return
*/
@Override
public ICheckData removeData(final String playerName);
/**
* Remove all data for all players.
*/
public void removeAllData();
}

View File

@ -1,5 +1,7 @@
package fr.neatmonster.nocheatplus.checks.access;
import fr.neatmonster.nocheatplus.components.IData;
/*
* MM'""""'YMM dP dP M""""""'YMM dP
* M' .mmm. `M 88 88 M mmmm. `M 88
@ -17,7 +19,7 @@ package fr.neatmonster.nocheatplus.checks.access;
*
* @author asofold
*/
public interface ICheckData {
public interface ICheckData extends IData{
/**
* Check if an entry for the given permission exists.

View File

@ -7,6 +7,7 @@ import java.util.Map;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.NoCheatPlus;
import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.checks.AsyncCheck;
import fr.neatmonster.nocheatplus.checks.CheckType;
@ -64,7 +65,12 @@ public class Text extends AsyncCheck implements INotifyReload{
private void init() {
// Set some things from the global config.
ConfigFile config = ConfigManager.getConfigFile();
if (engine != null){
engine.clear();
NoCheatPlus.getAPI().removeComponent(engine);
}
engine = new LetterEngine(config);
NoCheatPlus.getAPI().addComponent(engine);
}
@Override

View File

@ -4,17 +4,18 @@ import java.util.ArrayList;
import java.util.List;
import fr.neatmonster.nocheatplus.checks.chat.ChatConfig;
import fr.neatmonster.nocheatplus.checks.chat.analysis.engine.processors.FlatWords;
import fr.neatmonster.nocheatplus.checks.chat.analysis.engine.processors.SimilarWordsBKL;
import fr.neatmonster.nocheatplus.checks.chat.analysis.engine.processors.WordPrefixes;
import fr.neatmonster.nocheatplus.checks.chat.analysis.engine.processors.FlatWords;
import fr.neatmonster.nocheatplus.checks.chat.analysis.engine.processors.WordProcessor;
import fr.neatmonster.nocheatplus.components.IData;
/**
* Engine specific player data.
* @author mc_dev
*
*/
public class EnginePlayerData {
public class EnginePlayerData implements IData{
public final List<WordProcessor> processors = new ArrayList<WordProcessor>(5);

View File

@ -7,6 +7,7 @@ import java.util.Map;
import org.bukkit.Bukkit;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.chat.ChatConfig;
import fr.neatmonster.nocheatplus.checks.chat.ChatData;
import fr.neatmonster.nocheatplus.checks.chat.analysis.MessageLetterCount;
@ -17,6 +18,9 @@ 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.IData;
import fr.neatmonster.nocheatplus.components.IHaveCheckType;
import fr.neatmonster.nocheatplus.components.IRemoveData;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
@ -26,11 +30,14 @@ import fr.neatmonster.nocheatplus.config.ConfigFile;
* @author mc_dev
*
*/
public class LetterEngine {
public class LetterEngine implements IRemoveData, IHaveCheckType{
/** Global processors */
protected final List<WordProcessor> processors = new ArrayList<WordProcessor>();
/**
* Mapping players to data.
*/
protected final EnginePlayerDataMap dataMap;
public LetterEngine(ConfigFile config){
@ -101,4 +108,19 @@ public class LetterEngine {
processors.clear();
dataMap.clear();
}
@Override
public IData removeData(final String playerName) {
return dataMap.remove(playerName);
}
@Override
public void removeAllData() {
dataMap.clear();
}
@Override
public final CheckType getCheckType() {
return CheckType.CHAT_TEXT;
}
}

View File

@ -18,7 +18,7 @@ public class KickListCommand extends NCPCommand {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
final String[] kicked = plugin.getLoginDeniedPlayers();
final String[] kicked = NoCheatPlus.getLoginDeniedPlayers();
if (kicked.length < 100) Arrays.sort(kicked);
sender.sendMessage(TAG + "Temporarily kicked players:");
sender.sendMessage(CheckUtils.join(Arrays.asList(kicked), " "));

View File

@ -41,7 +41,7 @@ public class RemovePlayerCommand extends NCPCommand {
else checkType = CheckType.ALL;
if (playerName.equals("*")){
DataManager.clear(checkType);
DataManager.clearData(checkType);
sender.sendMessage(TAG + "Removed all data and history: " + checkType);
return true;
}
@ -61,7 +61,7 @@ public class RemovePlayerCommand extends NCPCommand {
if (DataManager.removeExecutionHistory(checkType, playerName)) histRemoved = true;
final boolean dataRemoved = CheckType.removeData(playerName, checkType);
final boolean dataRemoved = CheckType.removeData(playerName, checkType) || DataManager.clearComponentData(checkType, playerName);
if (dataRemoved || histRemoved){
String which;

View File

@ -1,11 +1,11 @@
package fr.neatmonster.nocheatplus.config;
import fr.neatmonster.nocheatplus.command.INotifyReload;
/**
* Indicate that an instance needs config after time of creation but in onEnable.
* @deprecated Use instead: fr.neatmonster.nocheatplus.components.INeedConfig
* @author mc_dev
*
*/
public interface INeedConfig extends INotifyReload{
public interface INeedConfig extends fr.neatmonster.nocheatplus.components.INeedConfig{
}

View File

@ -1,5 +1,6 @@
package fr.neatmonster.nocheatplus.players;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@ -30,13 +31,16 @@ import fr.neatmonster.nocheatplus.checks.fight.FightConfig;
import fr.neatmonster.nocheatplus.checks.inventory.InventoryConfig;
import fr.neatmonster.nocheatplus.checks.moving.MovingConfig;
import fr.neatmonster.nocheatplus.command.INotifyReload;
import fr.neatmonster.nocheatplus.components.IComponentRegistry;
import fr.neatmonster.nocheatplus.components.IHaveCheckType;
import fr.neatmonster.nocheatplus.components.INeedConfig;
import fr.neatmonster.nocheatplus.components.IRemoveData;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.config.INeedConfig;
import fr.neatmonster.nocheatplus.hooks.APIUtils;
public class DataManager implements Listener, INotifyReload, INeedConfig{
public class DataManager implements Listener, INotifyReload, INeedConfig, IComponentRegistry{
protected static DataManager instance = null;
@ -50,6 +54,12 @@ public class DataManager implements Listener, INotifyReload, INeedConfig{
*/
private final Map<String, Long> lastLogout = new LinkedHashMap<String, Long>(50, 0.75f, true);
/**
* IRemoveData instances.
* // TODO: might use a map for those later (extra or not).
*/
protected final ArrayList<IRemoveData> iRemoveData = new ArrayList<IRemoveData>();
/**
* Execution histories of the checks.
*/
@ -84,6 +94,7 @@ public class DataManager implements Listener, INotifyReload, INeedConfig{
for (final CheckDataFactory factory : factories){
factory.removeData(playerName);
}
clearComponentData(CheckType.ALL, playerName);
}
if (deleteData || deleteHistory) removeExecutionHistory(CheckType.ALL, playerName);
if (deleteHistory) ViolationHistory.removeHistory(playerName);
@ -152,12 +163,21 @@ public class DataManager implements Listener, INotifyReload, INeedConfig{
}
return removed;
}
/**
* Removes all data and history for a player.
* @deprecated Use clearData instead, this likely to be removed later.
* @param checkType
*/
public static void clear(final CheckType checkType){
clearData(checkType);
}
/**
* Remove data and history of all players for the given check type and sub checks.
* @param checkType
*/
public static void clear(final CheckType checkType) {
public static void clearData(final CheckType checkType) {
final Set<CheckDataFactory> factories = new HashSet<CheckDataFactory>();
for (final CheckType type : APIUtils.getWithChildren(checkType)){
final Map<String, ExecutionHistory> map = instance.executionHistories.get(type);
@ -168,9 +188,35 @@ public class DataManager implements Listener, INotifyReload, INeedConfig{
for (final CheckDataFactory factory : factories){
factory.removeAllData();
}
for (final IRemoveData rmd : instance.iRemoveData){
if (rmd instanceof IHaveCheckType){
final CheckType refType = ((IHaveCheckType) rmd).getCheckType();
if (refType == checkType || APIUtils.isParent(checkType, refType)) rmd.removeAllData();
}
}
ViolationHistory.clear(checkType);
}
/**
* Clear player related data, only for registered components (not execution history, violation history, normal check data).<br>
* That should at least go for chat engione data.
* @param CheckType
* @param PlayerName
* @return If something was removed.
*/
public static boolean clearComponentData(final CheckType checkType, final String PlayerName){
boolean removed = false;
for (final IRemoveData rmd : instance.iRemoveData){
if (rmd instanceof IHaveCheckType){
final CheckType refType = ((IHaveCheckType) rmd).getCheckType();
if (refType == checkType || APIUtils.isParent(checkType, refType)){
if (rmd.removeData(PlayerName) != null) removed = true;
}
}
}
return removed;
}
/**
* Clear all stored (check) config instances.<br>
* This does not cleanup ConfigManager, i.e. stored yml-versions.
@ -186,4 +232,33 @@ public class DataManager implements Listener, INotifyReload, INeedConfig{
InventoryConfig.clear();
MovingConfig.clear();
}
@Override
public void addComponent(Object obj) {
if (obj instanceof IRemoveData) {
iRemoveData.add((IRemoveData) obj);
}
}
@Override
public void removeComponent(Object obj) {
if (obj instanceof IRemoveData) {
iRemoveData.remove((IRemoveData) obj);
}
}
/**
* Cleanup method.
*/
public void onDisable() {
clearData(CheckType.ALL);
for (IRemoveData rmd : iRemoveData){
if (!(rmd instanceof IHaveCheckType)) rmd.removeAllData();
}
iRemoveData.clear();
clearConfigs();
lastLogout.clear();
executionHistories.clear();
}
}

View File

@ -176,9 +176,9 @@ public class TickTask implements Runnable {
// The isEmpty checks are faster than synchronizing fully always, the actions get delayed one tick at most.
if (!delayedActions.isEmpty()) executeActions();
if (!permissionUpdates.isEmpty()) updatePermissions();
if (timeLast > time){
CheckUtils.logSevere("[NoCheatPlus] System time ran backwards (" + timeLast + "->" + time + "), clear all data and history...");
DataManager.clear(CheckType.ALL);
if (timeLast > time) {
CheckUtils.logSevere("[NoCheatPlus] System time ran backwards (" + timeLast + "->" + time + "), clear all data and history...");
DataManager.clearData(CheckType.ALL);
}
timeLast = time;
}