Cleaned some stuff...

This commit is contained in:
NeatMonster 2012-08-14 19:19:39 +02:00
parent 96a7f493f8
commit 55ec451d64
17 changed files with 240 additions and 279 deletions

View File

@ -1,5 +1,7 @@
package fr.neatmonster.nocheatplus.actions;
import fr.neatmonster.nocheatplus.checks.ViolationData;
/*
* MMP"""""""MM dP oo
* M' .mmmm MM 88
@ -46,4 +48,13 @@ public abstract class Action {
this.delay = delay;
this.repeat = repeat;
}
/**
* Execute the action.
*
* @param violationData
* the violation data
* @return true, if successful
*/
public abstract boolean execute(final ViolationData violationData);
}

View File

@ -4,7 +4,6 @@ import java.util.ArrayList;
import fr.neatmonster.nocheatplus.actions.Action;
import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.ViolationData;
/*
@ -54,13 +53,11 @@ public abstract class ActionWithParameters extends Action {
/**
* Get a string with all the wildcards replaced with data from the violation data.
*
* @param check
* the check
* @param violationData
* the violation data
* @return the message
*/
protected String getMessage(final Check check, final ViolationData violationData) {
protected String getMessage(final ViolationData violationData) {
// Should be big enough most of the time.
final StringBuilder log = new StringBuilder(100);
@ -68,7 +65,7 @@ public abstract class ActionWithParameters extends Action {
if (part instanceof String)
log.append((String) part);
else
log.append(check.getParameter((ParameterName) part, violationData));
log.append(violationData.check.getParameter((ParameterName) part, violationData));
return log.toString();
}

View File

@ -1,6 +1,7 @@
package fr.neatmonster.nocheatplus.actions.types;
import fr.neatmonster.nocheatplus.actions.Action;
import fr.neatmonster.nocheatplus.checks.ViolationData;
/*
* MM'""""'YMM dP MMP"""""""MM dP oo
@ -24,6 +25,14 @@ public class CancelAction extends Action {
super("cancel", 0, 0);
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.actions.Action#execute(fr.neatmonster.nocheatplus.checks.ViolationData)
*/
@Override
public boolean execute(final ViolationData data) {
return true;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/

View File

@ -1,6 +1,8 @@
package fr.neatmonster.nocheatplus.actions.types;
import fr.neatmonster.nocheatplus.checks.Check;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandException;
import fr.neatmonster.nocheatplus.checks.ViolationData;
/*
@ -42,18 +44,21 @@ public class CommandAction extends ActionWithParameters {
super(name, delay, repeat, command);
}
/**
* Fill in the placeholders (stuff that looks like '[something]') with information, make a nice String out of it
* that can be directly used as a command in the console.
*
* @param check
* The check that is used to fill in missing .
* @param violationData
* the violation data
* @return The complete, ready to use, command.
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.actions.Action#execute(fr.neatmonster.nocheatplus.checks.ViolationData)
*/
public String getCommand(final Check check, final ViolationData violationData) {
return super.getMessage(check, violationData);
@Override
public boolean execute(final ViolationData violationData) {
final String command = super.getMessage(violationData);
try {
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), command);
} catch (final CommandException e) {
System.out.println("[NoCheatPlus] Failed to execute the command '" + command + "': " + e.getMessage()
+ ", please check if everything is setup correct.");
} catch (final Exception e) {
// I don't care in this case, your problem if your command fails.
}
return false;
}
/**

View File

@ -1,6 +1,7 @@
package fr.neatmonster.nocheatplus.actions.types;
import fr.neatmonster.nocheatplus.actions.Action;
import fr.neatmonster.nocheatplus.checks.ViolationData;
/*
* M""""""'YMM MMP"""""""MM dP oo
@ -31,6 +32,14 @@ public class DummyAction extends Action {
this.definition = definition;
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.actions.Action#execute(fr.neatmonster.nocheatplus.checks.ViolationData)
*/
@Override
public boolean execute(final ViolationData violationData) {
return false;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/

View File

@ -1,7 +1,15 @@
package fr.neatmonster.nocheatplus.actions.types;
import fr.neatmonster.nocheatplus.checks.Check;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.players.Permissions;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
/*
* M""MMMMMMMM MMP"""""""MM dP oo
@ -53,44 +61,26 @@ public class LogAction extends ActionWithParameters {
this.toFile = toFile;
}
/**
* Parse the final log message out of various data from the player and check that triggered the action.
*
* @param player
* The player that is used as a source for the log message.
* @param check
* The check that is used as a source for the log message.
* @return the log message
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.actions.Action#execute(fr.neatmonster.nocheatplus.checks.ViolationData)
*/
public String getLogMessage(final Check check, final ViolationData violationData) {
return super.getMessage(check, violationData);
@Override
public boolean execute(final ViolationData violationData) {
final ConfigFile configurationFile = ConfigManager.getConfigFile();
if (configurationFile.getBoolean(ConfPaths.LOGGING_ACTIVE)
&& !violationData.player.hasPermission(violationData.actions.permissionSilent)) {
final String message = super.getMessage(violationData);
if (toChat && configurationFile.getBoolean(ConfPaths.LOGGING_LOGTOINGAMECHAT))
for (final Player otherPlayer : Bukkit.getServer().getOnlinePlayers())
if (otherPlayer.hasPermission(Permissions.ADMINISTRATION_NOTIFY))
otherPlayer.sendMessage(ChatColor.RED + "NCP: " + ChatColor.WHITE
+ CheckUtils.replaceColors(message));
if (toConsole && configurationFile.getBoolean(ConfPaths.LOGGING_LOGTOCONSOLE))
System.out.println("[NoCheatPlus] " + CheckUtils.removeColors(message));
if (toFile && configurationFile.getBoolean(ConfPaths.LOGGING_LOGTOFILE))
CheckUtils.fileLogger.info(CheckUtils.removeColors(message));
}
/**
* Should the message be shown in chat?
*
* @return true, if yes
*/
public boolean toChat() {
return toChat;
}
/**
* Should the message be shown in the console?
*
* @return true, if yes
*/
public boolean toConsole() {
return toConsole;
}
/**
* Should the message be written to the logfile?
*
* @return true, if yes
*/
public boolean toFile() {
return toFile;
return false;
}
/**

View File

@ -2,26 +2,15 @@ package fr.neatmonster.nocheatplus.checks;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandException;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.actions.Action;
import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.actions.types.ActionList;
import fr.neatmonster.nocheatplus.actions.types.CancelAction;
import fr.neatmonster.nocheatplus.actions.types.CommandAction;
import fr.neatmonster.nocheatplus.actions.types.DummyAction;
import fr.neatmonster.nocheatplus.actions.types.LogAction;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.hooks.NCPHookManager;
import fr.neatmonster.nocheatplus.players.ExecutionHistory;
import fr.neatmonster.nocheatplus.players.Permissions;
/*
* MM'""""'YMM dP dP
@ -36,9 +25,9 @@ import fr.neatmonster.nocheatplus.players.Permissions;
* The Class Check.
*/
public abstract class Check {
protected static Map<String, ExecutionHistory> histories = new HashMap<String, ExecutionHistory>();
private static Logger fileLogger = null;
/** The execution histories of each check. */
protected static Map<String, ExecutionHistory> histories = new HashMap<String, ExecutionHistory>();
/**
* Gets the player's history.
@ -53,42 +42,6 @@ public abstract class Check {
return histories.get(player.getName());
}
/**
* Removes the colors of a message.
*
* @param text
* the text
* @return the string
*/
public static String removeColors(String text) {
for (final ChatColor c : ChatColor.values())
text = text.replace("&" + c.getChar(), "");
return text;
}
/**
* Replace colors of a message.
*
* @param text
* the text
* @return the string
*/
public static String replaceColors(String text) {
for (final ChatColor c : ChatColor.values())
text = text.replace("&" + c.getChar(), c.toString());
return text;
}
/**
* Sets the file logger.
*
* @param logger
* the new file logger
*/
public static void setFileLogger(final Logger logger) {
fileLogger = logger;
}
/** The type. */
protected final CheckType type;
@ -126,45 +79,26 @@ public abstract class Check {
*/
protected boolean executeActions(final ViolationData violationData) {
try {
boolean special = false;
final Player player = violationData.player;
// Check a bypass permission:
// Check a bypass permission.
if (violationData.bypassPermission != null)
if (player.hasPermission(violationData.bypassPermission))
if (violationData.player.hasPermission(violationData.bypassPermission))
return false;
final ActionList actionList = violationData.actions;
final double violationLevel = violationData.VL;
// Dispatch the VL processing to the hook manager.
if (NCPHookManager.shouldCancelVLProcessing(violationData.check.type, player))
if (NCPHookManager.shouldCancelVLProcessing(violationData))
// One of the hooks has decided to cancel the VL processing, return false.
return false;
// Get the to be executed actions.
final Action[] actions = actionList.getActions(violationLevel);
final long time = System.currentTimeMillis() / 1000L;
for (final Action ac : actions)
if (getHistory(player).executeAction(violationData.check.type.getName(), ac, time))
boolean cancel = false;
for (final Action action : violationData.getActions())
if (getHistory(violationData.player).executeAction(violationData, action, time))
// The execution history said it really is time to execute the action, find out what it is and do
// what is needed.
cancel = cancel || action.execute(violationData);
// TODO: Check design: maybe ac.execute(this) without the instance checks ?
if (ac instanceof LogAction && !player.hasPermission(actionList.permissionSilent))
executeLogAction((LogAction) ac, violationData.check, violationData);
else if (ac instanceof CancelAction)
special = true;
else if (ac instanceof CommandAction)
executeConsoleCommand((CommandAction) ac, violationData.check, violationData);
else if (ac instanceof DummyAction) {
// Do nothing, it's a dummy action after all.
}
return special;
return cancel;
} catch (final Exception e) {
e.printStackTrace();
}
@ -203,58 +137,6 @@ public abstract class Check {
return event.getCancel();
}
/**
* Execute a console command.
*
* @param action
* the action
* @param check
* the check
* @param violationData
* the violation data
*/
private void executeConsoleCommand(final CommandAction action, final Check check, final ViolationData violationData) {
final String command = action.getCommand(check, violationData);
try {
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), command);
} catch (final CommandException e) {
System.out.println("[NoCheatPlus] Failed to execute the command '" + command + "': " + e.getMessage()
+ ", please check if everything is setup correct.");
} catch (final Exception e) {
// I don't care in this case, your problem if your command fails.
}
}
/**
* Execute a log action.
*
* @param logAction
* the log action
* @param check
* the check
* @param violationData
* the violation data
*/
private void executeLogAction(final LogAction logAction, final Check check, final ViolationData violationData) {
final ConfigFile configurationFile = ConfigManager.getConfigFile();
if (!configurationFile.getBoolean(ConfPaths.LOGGING_ACTIVE))
return;
final String message = logAction.getLogMessage(check, violationData);
if (configurationFile.getBoolean(ConfPaths.LOGGING_LOGTOCONSOLE) && logAction.toConsole())
// Console logs are not colored.
System.out.println("[NoCheatPlus] " + removeColors(message));
if (configurationFile.getBoolean(ConfPaths.LOGGING_LOGTOINGAMECHAT) && logAction.toChat())
for (final Player otherPlayer : Bukkit.getServer().getOnlinePlayers())
if (otherPlayer.hasPermission(Permissions.ADMINISTRATION_NOTIFY))
// Chat logs are potentially colored.
otherPlayer.sendMessage(replaceColors(ChatColor.RED + "NCP: " + ChatColor.WHITE + message));
if (configurationFile.getBoolean(ConfPaths.LOGGING_LOGTOFILE) && logAction.toFile())
// File logs are not colored.
fileLogger.info(removeColors(message));
}
/**
* Replace a parameter for commands or log actions with an actual value. Individual checks should override this to
* get their own parameters handled too.
@ -272,9 +154,8 @@ public abstract class Check {
return violationData.player.getName();
else if (wildcard == ParameterName.VIOLATIONS) {
try {
return "" + Math.round(violationData.VL);
return "" + Math.round(violationData.violationLevel);
} catch (final Exception e) {
Bukkit.broadcastMessage("getParameter " + type.getName());
e.printStackTrace();
}
return "";
@ -282,6 +163,15 @@ public abstract class Check {
return "The author was lazy and forgot to define " + wildcard + ".";
}
/**
* Gets the type of the check.
*
* @return the type
*/
public CheckType getType() {
return type;
}
/**
* Checks if this check is enabled for the specified player.
*

View File

@ -195,8 +195,6 @@ public enum CheckType {
* @return true, if the check is enabled
*/
public final boolean isEnabled(final Player player) {
// if (configFactory == null) return true; // TODO: maybe leave this out.
return configFactory.getConfig(player).isEnabled(this);
}
}

View File

@ -2,6 +2,7 @@ package fr.neatmonster.nocheatplus.checks;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.actions.Action;
import fr.neatmonster.nocheatplus.actions.types.ActionList;
/*
@ -21,6 +22,12 @@ import fr.neatmonster.nocheatplus.actions.types.ActionList;
*/
public class ViolationData {
/** The actions to be executed. */
public final ActionList actions;
/** The bypassing permission. */
public final String bypassPermission;
/** The check. */
public final Check check;
@ -28,13 +35,7 @@ public class ViolationData {
public final Player player;
/** The violation level. */
public final double VL;
/** The actions to be executed. */
public final ActionList actions;
/** The bypassing permission. */
public final String bypassPermission;
public final double violationLevel;
/**
* Instantiates a new violation data.
@ -43,13 +44,13 @@ public class ViolationData {
* the check
* @param player
* the player
* @param VL
* the vL
* @param violationLevel
* the violation level
* @param actions
* the actions
*/
public ViolationData(final Check check, final Player player, final double VL, final ActionList actions) {
this(check, player, VL, actions, null);
public ViolationData(final Check check, final Player player, final double violationLevel, final ActionList actions) {
this(check, player, violationLevel, actions, null);
}
/**
@ -59,20 +60,28 @@ public class ViolationData {
* the check
* @param player
* the player
* @param VL
* the vL
* @param violationLevel
* the violation level
* @param actions
* the actions
* @param bypassPermission
* the permission to bypass the execution, if not null
*/
public ViolationData(final Check check, final Player player, final double VL, final ActionList actions,
public ViolationData(final Check check, final Player player, final double violationLevel, final ActionList actions,
final String bypassPermission) {
this.check = check;
this.player = player;
this.VL = VL;
this.violationLevel = violationLevel;
this.actions = actions;
this.bypassPermission = bypassPermission;
}
/**
* Gets the actions.
*
* @return the actions
*/
public Action[] getActions() {
return actions.getActions(violationLevel);
}
}

View File

@ -54,7 +54,6 @@ public class ChatData implements CheckData {
// Data of the no pwnage check.
public int noPwnageCaptchTries;
public String noPwnageGeneratedCaptcha;
public boolean noPwnageHasFilledCaptcha;
public boolean noPwnageHasStartedCaptcha;
public long noPwnageJoinTime;
public Location noPwnageLastLocation;
@ -70,7 +69,6 @@ public class ChatData implements CheckData {
* Clear the data of the no pwnage check.
*/
public synchronized void clearNoPwnageData() {
// TODO: re-think this sync [keep related to ChatData/NoPwnage/Color used lock.]
noPwnageCaptchTries = noPwnageReloginWarnings = 0;
noPwnageJoinTime = noPwnageLastMessageTime = noPwnageLastMovedTime = noPwnageLastWarningTime = noPwnageLeaveTime = noPwnageReloginWarningTime = 0L;
noPwnageGeneratedCaptcha = noPwnageLastMessage = "";

View File

@ -10,8 +10,8 @@ import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerLoginEvent.Result;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.players.Permissions;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
/*
* MM'""""'YMM dP dP M""MMMMMMMM oo dP
@ -59,7 +59,7 @@ public class ChatListener implements Listener {
// Then the no pwnage check.
if (noPwnage.check(player, event, false))
player.kickPlayer(Check.removeColors(ChatConfig.getConfig(player).noPwnageKickMessage));
player.kickPlayer(CheckUtils.removeColors(ChatConfig.getConfig(player).noPwnageKickMessage));
}
/**
@ -90,7 +90,8 @@ public class ChatListener implements Listener {
// Protect some commands to prevent players for seeing which plugins are installed.
if (ChatConfig.getConfig(player).protectPlugins
&& (command.equals("plugins") || command.equals("pl") || command.equals("?"))
&& (command.equals("?") || command.equals("about") || command.equals("help")
|| command.equals("plugins") || command.equals("pl"))
&& !player.hasPermission(Permissions.ADMINISTRATION_PLUGINS)) {
event.getPlayer().sendMessage(
ChatColor.RED + "I'm sorry, but you do not have permission to perform this command. "
@ -112,7 +113,7 @@ public class ChatListener implements Listener {
// Then the no pwnage check.
if (noPwnage.check(player, event, true))
player.kickPlayer(Check.removeColors(ChatConfig.getConfig(player).noPwnageKickMessage));
player.kickPlayer(CheckUtils.removeColors(ChatConfig.getConfig(player).noPwnageKickMessage));
}
/**

View File

@ -163,47 +163,66 @@ public class NoPwnage extends Check {
*/
private boolean unsafeCheck(final Player player, final PlayerEvent event, final boolean isMainThread,
final ChatConfig cc, final ChatData data) {
boolean[] results = null;
if (event instanceof AsyncPlayerChatEvent) {
final AsyncPlayerChatEvent e = (AsyncPlayerChatEvent) event;
results = unsafeCheck(player, e.getMessage(), isMainThread, cc, data);
e.setCancelled(results[0]);
} else if (event instanceof PlayerCommandPreprocessEvent) {
final PlayerCommandPreprocessEvent e = (PlayerCommandPreprocessEvent) event;
results = unsafeCheck(player, e.getMessage(), isMainThread, cc, data);
e.setCancelled(results[0]);
}
return results[1];
}
/**
* Only to be called form synchronized code.
*
* @param player
* the player
* @param message
* the message
* @param isMainThread
* the is main thread
* @param cc
* the cc
* @param data
* the data
* @return the boolean[]
*/
private boolean[] unsafeCheck(final Player player, final String message, final boolean isMainThread,
final ChatConfig cc, final ChatData data) {
data.noPwnageVL = 0D;
boolean cancel = false;
boolean kick = false;
String message = "";
if (event instanceof AsyncPlayerChatEvent)
message = ((AsyncPlayerChatEvent) event).getMessage();
else if (event instanceof PlayerCommandPreprocessEvent)
message = ((PlayerCommandPreprocessEvent) event).getMessage();
final boolean isCommand = event instanceof PlayerCommandPreprocessEvent;
final long now = System.currentTimeMillis();
if (!data.noPwnageHasFilledCaptcha)
if (cc.noPwnageCaptchaCheck && data.noPwnageHasStartedCaptcha) {
// Correct answer to the captcha?
if (message.equals(data.noPwnageGeneratedCaptcha)) {
// Yes, clear his data and do not worry anymore about him.
data.clearNoPwnageData();
data.noPwnageHasFilledCaptcha = true;
player.sendMessage(replaceColors(cc.noPwnageCaptchaSuccess));
data.noPwnageHasStartedCaptcha = false;
player.sendMessage(CheckUtils.replaceColors(cc.noPwnageCaptchaSuccess));
} else {
// Does he failed too much times?
if (data.noPwnageCaptchTries > cc.noPwnageCaptchaTries)
// Find out if we need to ban the player or not.
// TODO: extra captcha actions / VL ?
cancel = executeActionsThreadSafe(player, data.noPwnageVL, cc.noPwnageActions, isMainThread);
kick = executeActionsThreadSafe(player, data.noPwnageVL, cc.noPwnageActions, isMainThread);
// Increment his tries number counter.
data.noPwnageCaptchTries++;
// Display the question again.
player.sendMessage(replaceColors(cc.noPwnageCaptchaQuestion.replace("[captcha]",
player.sendMessage(CheckUtils.replaceColors(cc.noPwnageCaptchaQuestion.replace("[captcha]",
data.noPwnageGeneratedCaptcha)));
}
// Cancel the event and return.
if (event instanceof AsyncPlayerChatEvent)
((AsyncPlayerChatEvent) event).setCancelled(true);
else if (event instanceof PlayerCommandPreprocessEvent)
((PlayerCommandPreprocessEvent) event).setCancelled(true);
return cancel;
// Cancel the message and maybe event.
return new boolean[] {true, kick};
}
if (data.noPwnageLastLocation == null)
@ -215,7 +234,7 @@ public class NoPwnage extends Check {
// NoPwnage will remember the last message that caused someone to get banned. If a player repeats that
// message within "timeout" milliseconds, the suspicion will be increased by "weight".
if (!isCommand && cc.noPwnageBannedCheck && now - lastBanCausingMessageTime < cc.noPwnageBannedTimeout
if (cc.noPwnageBannedCheck && now - lastBanCausingMessageTime < cc.noPwnageBannedTimeout
&& CheckUtils.isSimilar(message, lastBanCausingMessage, 0.8f))
data.noPwnageVL += cc.noPwnageBannedWeight;
@ -226,7 +245,7 @@ public class NoPwnage extends Check {
// NoPwnage will check if a player repeats a message that has been sent by another player just before,
// within "timeout". If he does, suspicion will be increased by "weight".
if (!isCommand && cc.noPwnageGlobalCheck && now - lastGlobalMessageTime < cc.noPwnageGlobalTimeout
if (cc.noPwnageGlobalCheck && now - lastGlobalMessageTime < cc.noPwnageGlobalTimeout
&& CheckUtils.isSimilar(message, lastGlobalMessage, 0.8f))
data.noPwnageVL += cc.noPwnageGlobalWeight;
@ -237,7 +256,7 @@ public class NoPwnage extends Check {
// NoPwnage will check if a player repeats his messages within the "timeout" timeframe. Even if the message
// is a bit different, it will be counted as being a repetition. The suspicion is increased by "weight".
if (!isCommand && cc.noPwnageRepeatCheck && now - data.noPwnageLastMessageTime < cc.noPwnageRepeatTimeout
if (cc.noPwnageRepeatCheck && now - data.noPwnageLastMessageTime < cc.noPwnageRepeatTimeout
&& CheckUtils.isSimilar(message, data.noPwnageLastMessage, 0.8f))
data.noPwnageVL += cc.noPwnageRepeatWeight;
@ -258,34 +277,29 @@ public class NoPwnage extends Check {
}
if (cc.noPwnageWarnPlayerCheck && data.noPwnageVL > cc.noPwnageWarnLevel && !warned) {
player.sendMessage(replaceColors(cc.noPwnageWarnPlayerMessage));
player.sendMessage(CheckUtils.replaceColors(cc.noPwnageWarnPlayerMessage));
data.noPwnageLastWarningTime = now;
} else if (data.noPwnageVL > cc.noPwnageLevel)
if (cc.noPwnageCaptchaCheck && !data.noPwnageHasStartedCaptcha) {
// Display a captcha to the player.
data.noPwnageGeneratedCaptcha = "";
for (int i = 0; i < cc.noPwnageCaptchaLength; i++)
data.noPwnageGeneratedCaptcha += cc.noPwnageCaptchaCharacters.charAt(random
.nextInt(cc.noPwnageCaptchaCharacters.length()));
player.sendMessage(replaceColors(cc.noPwnageCaptchaQuestion.replace("[captcha]",
player.sendMessage(CheckUtils.replaceColors(cc.noPwnageCaptchaQuestion.replace("[captcha]",
data.noPwnageGeneratedCaptcha)));
data.noPwnageHasStartedCaptcha = true;
if (event instanceof AsyncPlayerChatEvent)
((AsyncPlayerChatEvent) event).setCancelled(true);
else if (event instanceof PlayerCommandPreprocessEvent)
((PlayerCommandPreprocessEvent) event).setCancelled(true);
cancel = true;
} else {
lastBanCausingMessage = message;
data.noPwnageLastWarningTime = lastBanCausingMessageTime = now;
if (cc.noPwnageWarnOthersCheck)
Bukkit.broadcastMessage(replaceColors(cc.noPwnageWarnOthersMessage.replace("[player]",
Bukkit.broadcastMessage(CheckUtils.replaceColors(cc.noPwnageWarnOthersMessage.replace("[player]",
player.getName())));
if (event instanceof AsyncPlayerChatEvent)
((AsyncPlayerChatEvent) event).setCancelled(true);
else if (event instanceof PlayerCommandPreprocessEvent)
((PlayerCommandPreprocessEvent) event).setCancelled(true);
cancel = true;
// Find out if we need to ban the player or not.
cancel = executeActionsThreadSafe(player, data.noPwnageVL, cc.noPwnageActions, isMainThread);
kick = executeActionsThreadSafe(player, data.noPwnageVL, cc.noPwnageActions, isMainThread);
}
// Store the message and some other data.
@ -294,7 +308,7 @@ public class NoPwnage extends Check {
lastGlobalMessage = message;
lastGlobalMessageTime = now;
return cancel;
return new boolean[] {cancel, kick};
}
/**
@ -320,12 +334,11 @@ public class NoPwnage extends Check {
if (now - data.noPwnageReloginWarningTime > cc.noPwnageReloginWarningTimeout)
data.noPwnageReloginWarnings = 0;
if (data.noPwnageReloginWarnings < cc.noPwnageReloginWarningNumber) {
player.sendMessage(replaceColors(cc.noPwnageReloginWarningMessage));
player.sendMessage(CheckUtils.replaceColors(cc.noPwnageReloginWarningMessage));
data.noPwnageReloginWarningTime = now;
data.noPwnageReloginWarnings++;
} else if (now - data.noPwnageReloginWarningTime < cc.noPwnageReloginWarningTimeout)
// Find out if we need to ban the player or not.
// TODO: extra actions / VL ?
cancel = executeActionsThreadSafe(player, data.noPwnageVL, cc.noPwnageActions, true);
}

View File

@ -15,7 +15,7 @@ import java.util.logging.LogRecord;
import java.util.logging.Logger;
import fr.neatmonster.nocheatplus.NoCheatPlus;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
/*
* MM'""""'YMM .8888b oo M"""""`'"""`YM
@ -182,7 +182,7 @@ public class ConfigManager {
e.printStackTrace();
}
Check.setFileLogger(logger);
CheckUtils.fileLogger = logger;
// Try to find world-specific configuration files.
final HashMap<String, File> worldFiles = new HashMap<String, File>();

View File

@ -132,11 +132,11 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_CHECK, true);
set(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_CHARACTERS,
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890");
set(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_LENGTH, 4);
set(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_LENGTH, 6);
set(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_QUESTION,
"&cPlease type '&6[captcha]&c' to continue sending messages/commands.");
set(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_SUCCESS, "&aOK, it sounds like you're not a spambot.");
set(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_TRIES, 20);
set(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_TRIES, 3);
set(ConfPaths.CHAT_NOPWNAGE_FIRST_CHECK, true);
set(ConfPaths.CHAT_NOPWNAGE_FIRST_TIMEOUT, 3000L);
@ -301,8 +301,8 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.STRINGS + ".color", start + "sent colored chat message" + end);
set(ConfPaths.STRINGS + ".critical", start + "tried to do a critical hit but wasn't technically jumping" + end);
set(ConfPaths.STRINGS + ".drop", start + "tried to drop more items than allowed" + end);
set(ConfPaths.STRINGS + ".fastbreak", start + "tried to break too much blocks" + end);
set(ConfPaths.STRINGS + ".fastplace", start + "tried to place too much blocks" + end);
set(ConfPaths.STRINGS + ".fastbreak", start + "tried to break too many blocks" + end);
set(ConfPaths.STRINGS + ".fastplace", start + "tried to place too many blocks" + end);
set(ConfPaths.STRINGS + ".fdirection", start + "tried to hit an entity out of line of sight" + end);
set(ConfPaths.STRINGS + ".flyshort", start + "tried to move unexpectedly" + end);
set(ConfPaths.STRINGS + ".flylong", start

View File

@ -13,6 +13,7 @@ import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.ViolationData;
/*
* M"""""""`YM MM'""""'YMM MM"""""""`YM M""MMMMM""MM dP
@ -265,7 +266,7 @@ public final class NCPHookManager {
*/
private static final void logHookFailure(final CheckType checkType, final Player player, final NCPHook hook,
final Throwable t) {
// TODO: Might accumulate failure rate and only log every so and so seconds or disable hook if spamming (leads
// TODO: might accumulate failure rate and only log every so and so seconds or disable hook if spamming (leads
// to NCP spam though)?
final StringBuilder builder = new StringBuilder(1024);
builder.append("[NoCheatPlus] Hook " + getHookDescription(hook) + " encountered an unexpected exception:\n");
@ -403,14 +404,12 @@ public final class NCPHookManager {
* the player that fails the check
* @return if we should cancel the VL processing
*/
public static final boolean shouldCancelVLProcessing(final CheckType checkType, final Player player) {
public static final boolean shouldCancelVLProcessing(final ViolationData violationData) {
// Checks for hooks registered for this event, parent groups or ALL will be inserted into the list.
// Return true as soon as one hook returns true.
// Test hooks, if present:
final List<NCPHook> hooksCheck = hooksByChecks.get(checkType);
// Return true as soon as one hook returns true. Test hooks, if present.
final List<NCPHook> hooksCheck = hooksByChecks.get(violationData.check.getType());
if (hooksCheck != null)
if (applyHooks(checkType, player, hooksCheck))
if (applyHooks(violationData.check.getType(), violationData.player, hooksCheck))
return true;
return false;
}

View File

@ -4,6 +4,7 @@ import java.util.HashMap;
import java.util.Map;
import fr.neatmonster.nocheatplus.actions.Action;
import fr.neatmonster.nocheatplus.checks.ViolationData;
/*
* MM""""""""`M dP oo
@ -82,9 +83,9 @@ public class ExecutionHistory {
* the length
*/
private void clearTimes(final long start, long length) {
if (length <= 0)
return; // Nothing to do (yet).
// Nothing to do (yet).
return;
if (length > executionTimes.length)
length = executionTimes.length;
@ -144,25 +145,24 @@ public class ExecutionHistory {
* Returns true, if the action should be executed, because all time criteria have been met. Will add a entry with
* the time to a list which will influence further requests, so only use once and remember the result.
*
* @param check
* the check
* @param violationData
* the violation data
* @param action
* the action
* @param time
* a time IN SECONDS
* @return true, if successful
*/
public boolean executeAction(final String check, final Action action, final long time) {
public boolean executeAction(final ViolationData violationData, final Action action, final long time) {
final String check = violationData.check.getType().getName();
Map<Action, ExecutionHistoryEntry> executionHistory = executionHistories.get(check);
if (executionHistory == null) {
executionHistory = new HashMap<Action, ExecutionHistoryEntry>();
executionHistories.put(check, executionHistory);
}
ExecutionHistoryEntry entry = executionHistory.get(action);
if (entry == null) {
entry = new ExecutionHistoryEntry(60);
executionHistory.put(action, entry);

View File

@ -1,5 +1,8 @@
package fr.neatmonster.nocheatplus.utilities;
import java.util.logging.Logger;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
@ -9,6 +12,9 @@ import org.bukkit.util.Vector;
*/
public class CheckUtils {
/** The file logger. */
public static Logger fileLogger = null;
/**
* Check if a player looks at a target of a specific size, with a specific precision value (roughly).
*
@ -152,4 +158,30 @@ public class CheckUtils {
return p[n];
}
/**
* Removes the colors of a message.
*
* @param text
* the text
* @return the string
*/
public static String removeColors(String text) {
for (final ChatColor c : ChatColor.values())
text = text.replace("&" + c.getChar(), "");
return text;
}
/**
* Replace colors of a message.
*
* @param text
* the text
* @return the string
*/
public static String replaceColors(String text) {
for (final ChatColor c : ChatColor.values())
text = text.replace("&" + c.getChar(), c.toString());
return text;
}
}