Welcome back '/nocheatplus info <player>' command!

This commit is contained in:
NeatMonster 2012-08-18 22:56:35 +02:00
parent 811b1d4023
commit 963c363c7d
41 changed files with 401 additions and 176 deletions

View File

@ -13,7 +13,9 @@ commands:
aliases: [ncp]
description: NoCheatPlus command(s).
# permission: nocheatplus.admin.reload
usage: "/<command> reload: reload NoCheatPlus configuration"
usage: |
/<command> info: Display the violations of a player
/<command> reload: reload NoCheatPlus configuration
permissions:
nocheatplus:

View File

@ -1,5 +1,10 @@
package fr.neatmonster.nocheatplus;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TreeMap;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
@ -9,6 +14,8 @@ import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import fr.neatmonster.nocheatplus.checks.ViolationHistory;
import fr.neatmonster.nocheatplus.checks.ViolationHistory.ViolationLevel;
import fr.neatmonster.nocheatplus.checks.blockbreak.BlockBreakConfig;
import fr.neatmonster.nocheatplus.checks.blockinteract.BlockInteractConfig;
import fr.neatmonster.nocheatplus.checks.blockplace.BlockPlaceConfig;
@ -68,8 +75,11 @@ public class CommandHandler implements CommandExecutor {
}
}
/** The prefix of every message sent by NoCheatPlus. */
private static final String TAG = ChatColor.RED + "NCP: " + ChatColor.WHITE;
/** The plugin. */
private final NoCheatPlus plugin;
private final NoCheatPlus plugin;
/**
* Instantiates a new command handler.
@ -81,6 +91,39 @@ public class CommandHandler implements CommandExecutor {
this.plugin = plugin;
}
/**
* Handle the '/nocheatplus info' command.
*
* @param sender
* the sender
* @param playerName
* the player name
* @return true, if successful
*/
private void handleInfoCommand(final CommandSender sender, final String playerName) {
final Player player = Bukkit.getPlayer(playerName);
if (player != null) {
final DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
final TreeMap<Long, ViolationLevel> violations = ViolationHistory.getHistory(player).getViolationLevels();
if (violations.size() > 0) {
sender.sendMessage(TAG + "Displaying " + playerName + "'s violations...");
for (final long time : violations.descendingKeySet()) {
final ViolationLevel violationLevel = violations.get(time);
final String[] parts = violationLevel.check.split("\\.");
final String check = parts[parts.length - 1];
final String parent = parts[parts.length - 2];
final double VL = Math.round(violationLevel.VL);
sender.sendMessage(TAG + "[" + dateFormat.format(new Date(time)) + "] (" + parent + ".)" + check
+ " VL " + VL);
}
} else
sender.sendMessage(TAG + "Displaying " + playerName + "'s violations... nothing to display.");
} else {
sender.sendMessage(TAG + "404 Not Found");
sender.sendMessage(TAG + "The requested player was not found on this server.");
}
}
/**
* Handle the '/nocheatplus reload' command.
*
@ -88,30 +131,24 @@ public class CommandHandler implements CommandExecutor {
* the sender
* @return true, if successful
*/
private boolean handleReloadCommand(final CommandSender sender) {
// Players need a special permission for this.
if (!(sender instanceof Player) || sender.hasPermission(Permissions.ADMINISTRATION_RELOAD)) {
sender.sendMessage(ChatColor.RED + "NCP: " + ChatColor.WHITE + "Reloading configuration...");
private void handleReloadCommand(final CommandSender sender) {
sender.sendMessage(TAG + "Reloading configuration...");
// Do the actual reload.
ConfigManager.cleanup();
ConfigManager.init(plugin);
BlockBreakConfig.clear();
BlockInteractConfig.clear();
BlockPlaceConfig.clear();
ChatConfig.clear();
FightConfig.clear();
InventoryConfig.clear();
MovingConfig.clear();
// Do the actual reload.
ConfigManager.cleanup();
ConfigManager.init(plugin);
BlockBreakConfig.clear();
BlockInteractConfig.clear();
BlockPlaceConfig.clear();
ChatConfig.clear();
FightConfig.clear();
InventoryConfig.clear();
MovingConfig.clear();
// Say to the other plugins that we've reloaded the configuration.
Bukkit.getPluginManager().callEvent(new NCPReloadEvent());
// Say to the other plugins that we've reloaded the configuration.
Bukkit.getPluginManager().callEvent(new NCPReloadEvent());
sender.sendMessage(ChatColor.RED + "NCP: " + ChatColor.WHITE + "Configuration reloaded!");
} else
sender.sendMessage(ChatColor.RED + "You lack the " + Permissions.ADMINISTRATION_RELOAD
+ " permission to use 'reload'!");
return true;
sender.sendMessage(TAG + "Configuration reloaded!");
}
/* (non-Javadoc)
@ -121,25 +158,25 @@ public class CommandHandler implements CommandExecutor {
@Override
public boolean onCommand(final CommandSender sender, final Command command, final String commandLabel,
final String[] args) {
if (sender instanceof Player) {
final boolean protectPlugins = ConfigManager.getConfigFile(((Player) sender).getWorld().getName())
.getBoolean(ConfPaths.MISCELLANEOUS_PROTECTPLUGINS);
// Hide NoCheatPlus's commands if the player doesn't have the required permission.
if (protectPlugins && !sender.hasPermission(Permissions.ADMINISTRATION_RELOAD)) {
sender.sendMessage("Unknown command. Type \"help\" for help.");
return true;
}
}
boolean result = false;
// Not our command, how did it get here?
if (!command.getName().equalsIgnoreCase("nocheatplus") || args.length == 0)
result = false;
else if (args[0].equalsIgnoreCase("reload"))
if (!command.getName().equalsIgnoreCase("nocheatplus"))
return false;
final boolean protectPlugins = ConfigManager.getConfigFile().getBoolean(ConfPaths.MISCELLANEOUS_PROTECTPLUGINS);
if (args.length == 2 && args[0].equalsIgnoreCase("info")
&& sender.hasPermission(Permissions.ADMINISTRATION_INFO))
// Info command was used.
handleInfoCommand(sender, args[1]);
else if (args.length == 1 && args[0].equalsIgnoreCase("reload")
&& sender.hasPermission(Permissions.ADMINISTRATION_RELOAD))
// Reload command was used.
result = handleReloadCommand(sender);
return result;
handleReloadCommand(sender);
else if (protectPlugins && !sender.hasPermission(Permissions.ADMINISTRATION_INFO)
&& !sender.hasPermission(Permissions.ADMINISTRATION_RELOAD))
sender.sendMessage("Unknown command. Type \"help\" for help.");
else
return false;
return true;
}
}

View File

@ -1,10 +1,14 @@
package fr.neatmonster.nocheatplus;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.server.EntityPlayer;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.NetServerHandler;
import net.minecraft.server.NetworkManager;
import net.minecraft.server.ServerConnection;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.entity.CraftPlayer;
@ -122,19 +126,33 @@ public class NoCheatPlus extends JavaPlugin implements Listener {
* @param event
* the event handled
*/
@SuppressWarnings({"unchecked", "rawtypes"})
@EventHandler(
priority = EventPriority.MONITOR)
public void onPlayerJoin(final PlayerJoinEvent event) {
final Player player = event.getPlayer();
// Set the proxy of the player if enabled.
if (ConfigManager.getConfigFile().getBoolean(ConfPaths.MISCELLANEOUS_USEPROXY)) {
final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
final NetServerHandlerProxy proxy = new NetServerHandlerProxy(MinecraftServer.getServer(),
entityPlayer.netServerHandler);
entityPlayer.netServerHandler = proxy;
final EntityPlayer player = ((CraftPlayer) event.getPlayer()).getHandle();
final NetServerHandler nsh = player.netServerHandler;
final NetServerHandlerProxy proxy = new NetServerHandlerProxy(MinecraftServer.getServer(), nsh);
player.netServerHandler = proxy;
try {
final Field packetListener = NetworkManager.class.getDeclaredField("packetListener");
packetListener.setAccessible(true);
packetListener.set(nsh.networkManager, proxy);
final Field d = ServerConnection.class.getDeclaredField("d");
d.setAccessible(true);
final List handlerList = (List) d.get(MinecraftServer.getServer().ac());
handlerList.remove(nsh);
handlerList.add(proxy);
} catch (final Exception e) {
e.printStackTrace();
}
}
final Player player = event.getPlayer();
// Check if we allow all the client mods.
final boolean allowAll = ConfigManager.getConfigFile().getBoolean(ConfPaths.MISCELLANEOUS_ALLOWCLIENTMODS);
String message = "";

View File

@ -22,7 +22,7 @@ import fr.neatmonster.nocheatplus.players.ExecutionHistory;
* MMMMMMMMMMM
*/
/**
* The Class Check.
* The parent class of all checks.
*/
public abstract class Check {
@ -62,11 +62,15 @@ public abstract class Check {
* the player
* @param VL
* the vL
* @param VLAdded
* the vL added
* @param actions
* the actions
* @return true, if the event should be cancelled
*/
protected boolean executeActions(final Player player, final double VL, final ActionList actions) {
protected boolean executeActions(final Player player, final double VL, final double VLAdded,
final ActionList actions) {
ViolationHistory.getHistory(player).log(getClass().getName(), VLAdded);
return executeActions(new ViolationData(this, player, VL, actions));
}
@ -112,14 +116,17 @@ public abstract class Check {
* the player
* @param VL
* the vL
* @param VLAdded
* the vL added
* @param actions
* the actions
* @param bypassPermission
* the bypass permission
* @return true, if the event should be cancelled
*/
public boolean executeActionsThreadSafe(final Player player, final double VL, final ActionList actions,
final String bypassPermission) {
public boolean executeActionsThreadSafe(final Player player, final double VL, final double VLAdded,
final ActionList actions, final String bypassPermission) {
ViolationHistory.getHistory(player).log(getClass().getName(), VLAdded);
// Sync it into the main thread by using an event.
return executeActionsThreadSafe(new ViolationData(this, player, VL, actions, bypassPermission));
}

View File

@ -0,0 +1,121 @@
package fr.neatmonster.nocheatplus.checks;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.bukkit.entity.Player;
/*
* M""MMMMM""M oo dP dP oo
* M MMMMM M 88 88
* M MMMMP M dP .d8888b. 88 .d8888b. d8888P dP .d8888b. 88d888b.
* M MMMM' .M 88 88' `88 88 88' `88 88 88 88' `88 88' `88
* M MMP' .MM 88 88. .88 88 88. .88 88 88 88. .88 88 88
* M .dMMM dP `88888P' dP `88888P8 dP dP `88888P' dP dP
* MMMMMMMMMMM
*
* M""MMMMM""MM oo dP
* M MMMMM MM 88
* M `M dP .d8888b. d8888P .d8888b. 88d888b. dP dP
* M MMMMM MM 88 Y8ooooo. 88 88' `88 88' `88 88 88
* M MMMMM MM 88 88 88 88. .88 88 88. .88
* M MMMMM MM dP `88888P' dP `88888P' dP `8888P88
* MMMMMMMMMMMM .88
* d8888P
*/
/**
* The class containg the violation history of a player.
*/
public class ViolationHistory {
/**
* The class storing the violation level for a check and a player.
*/
public class ViolationLevel {
/** The check. */
public final String check;
/** The VL. */
public double VL;
/** The last VL time. */
private long time;
/**
* Instantiates a new violation level.
*
* @param check
* the check
* @param VL
* the vL
*/
public ViolationLevel(final String check, final double VL) {
this.check = check;
this.VL = VL;
time = System.currentTimeMillis();
}
/**
* Adds a VL to this violation level.
*
* @param VL
* the vL
*/
public void add(final double VL) {
this.VL += VL;
time = System.currentTimeMillis();
}
}
/** The histories of all the players. */
private static Map<String, ViolationHistory> violationHistories = new HashMap<String, ViolationHistory>();
/**
* Gets the history of a player.
*
* @param player
* the player
* @return the history
*/
public static ViolationHistory getHistory(final Player player) {
if (!violationHistories.containsKey(player.getName()))
violationHistories.put(player.getName(), new ViolationHistory());
return violationHistories.get(player.getName());
}
/** The violation levels for every check. */
private final List<ViolationLevel> violationLevels = new ArrayList<ViolationLevel>();
/**
* Gets the violation levels.
*
* @return the violation levels
*/
public TreeMap<Long, ViolationLevel> getViolationLevels() {
final TreeMap<Long, ViolationLevel> violationLevels = new TreeMap<Long, ViolationLevel>();
for (final ViolationLevel violationLevel : this.violationLevels)
violationLevels.put(violationLevel.time, violationLevel);
return violationLevels;
}
/**
* Log a VL.
*
* @param check
* the check
* @param VL
* the vL
*/
public void log(final String check, final double VL) {
for (final ViolationLevel violationLevel : violationLevels)
if (check.equals(violationLevel.check)) {
violationLevel.add(VL);
return;
}
violationLevels.add(new ViolationLevel(check, VL));
}
}

View File

@ -59,7 +59,8 @@ public class Direction extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.directionVL, BlockBreakConfig.getConfig(player).directionActions);
cancel = executeActions(player, data.directionVL, distance,
BlockBreakConfig.getConfig(player).directionActions);
} else
// Player did likely nothing wrong, reduce violation counter to reward him.
data.directionVL *= 0.9D;

View File

@ -73,7 +73,8 @@ public class FastBreak extends Check {
data.fastBreakVL += Math.max(timeLimit - elapsedTime, 0D);
// Cancel the event if needed.
cancel = executeActions(player, data.fastBreakVL, cc.fastBreakActions);
cancel = executeActions(player, data.fastBreakVL, Math.max(timeLimit - elapsedTime, 0D),
cc.fastBreakActions);
} else
// Remove one from the buffer.
data.fastBreakBuffer--;

View File

@ -51,7 +51,7 @@ public class NoSwing extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.noSwingVL, BlockBreakConfig.getConfig(player).noSwingActions);
cancel = executeActions(player, data.noSwingVL, 1D, BlockBreakConfig.getConfig(player).noSwingActions);
}
return cancel;

View File

@ -67,7 +67,7 @@ public class Reach extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.reachVL, BlockBreakConfig.getConfig(player).reachActions);
cancel = executeActions(player, data.reachVL, distance, BlockBreakConfig.getConfig(player).reachActions);
} else
// Player passed the check, reward him.
data.reachVL *= 0.9D;

View File

@ -59,7 +59,8 @@ public class Direction extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.directionVL, BlockInteractConfig.getConfig(player).directionActions);
cancel = executeActions(player, data.directionVL, distance,
BlockInteractConfig.getConfig(player).directionActions);
} else
// Player did likely nothing wrong, reduce violation counter to reward him.
data.directionVL *= 0.9D;

View File

@ -67,7 +67,7 @@ public class Reach extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.reachVL, BlockInteractConfig.getConfig(player).reachActions);
cancel = executeActions(player, data.reachVL, distance, BlockInteractConfig.getConfig(player).reachActions);
} else
// Player passed the check, reward him.
data.reachVL *= 0.9D;

View File

@ -82,7 +82,8 @@ public class Direction extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.directionVL, BlockPlaceConfig.getConfig(player).directionActions);
cancel = executeActions(player, data.directionVL, distance,
BlockPlaceConfig.getConfig(player).directionActions);
} else
// Player did likely nothing wrong, reduce violation counter to reward him.
data.directionVL *= 0.9D;

View File

@ -47,12 +47,15 @@ public class FastPlace extends Check {
if (data.fastPlaceLastTime != 0 && System.currentTimeMillis() - data.fastPlaceLastTime < cc.fastPlaceInterval) {
if (!LagMeasureTask.skipCheck()) {
if (data.fastPlaceLastRefused) {
final double difference = cc.fastPlaceInterval - System.currentTimeMillis()
+ data.fastPlaceLastTime;
// He failed, increase his violation level.
data.fastPlaceVL += cc.fastPlaceInterval - System.currentTimeMillis() + data.fastPlaceLastTime;
data.fastPlaceVL += difference;
// Execute whatever actions are associated with this check and the violation level and find out if
// we should cancel the event.
cancel = executeActions(player, data.fastPlaceVL, cc.fastPlaceActions);
cancel = executeActions(player, data.fastPlaceVL, difference, cc.fastPlaceActions);
}
data.fastPlaceLastRefused = true;

View File

@ -51,7 +51,7 @@ public class NoSwing extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.noSwingVL, BlockPlaceConfig.getConfig(player).noSwingActions);
cancel = executeActions(player, data.noSwingVL, 1D, BlockPlaceConfig.getConfig(player).noSwingActions);
}
return cancel;

View File

@ -67,7 +67,7 @@ public class Reach extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.reachVL, BlockPlaceConfig.getConfig(player).reachActions);
cancel = executeActions(player, data.reachVL, distance, BlockPlaceConfig.getConfig(player).reachActions);
} else
// Player passed the check, reward him.
data.reachVL *= 0.9D;

View File

@ -43,12 +43,14 @@ public class Speed extends Check {
// Has the player thrown items too quickly?
if (data.speedLastTime != 0 && System.currentTimeMillis() - data.speedLastTime < cc.speedInterval) {
if (data.speedLastRefused) {
final double difference = cc.speedInterval - System.currentTimeMillis() + data.speedLastTime;
// He failed, increase this violation level.
data.speedVL += cc.speedInterval - System.currentTimeMillis() + data.speedLastTime;
data.speedVL += difference;
// Execute whatever actions are associated with this check and the violation level and find out if we
// should cancel the event.
cancel = executeActions(player, data.speedVL, cc.speedActions);
cancel = executeActions(player, data.speedVL, difference, cc.speedActions);
}
data.speedLastRefused = true;

View File

@ -1,6 +1,7 @@
package fr.neatmonster.nocheatplus.checks.chat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bukkit.entity.Player;
@ -66,64 +67,65 @@ public class ChatConfig implements CheckConfig {
}
}
public final boolean colorCheck;
public final ActionList colorActions;
public final boolean colorCheck;
public final ActionList colorActions;
public final boolean noPwnageCheck;
public final int noPwnageLevel;
public final String noPwnageKickMessage;
public final boolean noPwnageCheck;
public final List<String> noPwnageExclusions;
public final int noPwnageLevel;
public final String noPwnageKickMessage;
public final boolean noPwnageBannedCheck;
public final long noPwnageBannedTimeout;
public final int noPwnageBannedWeight;
public final boolean noPwnageBannedCheck;
public final long noPwnageBannedTimeout;
public final int noPwnageBannedWeight;
public final boolean noPwnageCaptchaCheck;
public final String noPwnageCaptchaCharacters;
public final int noPwnageCaptchaLength;
public final String noPwnageCaptchaQuestion;
public final String noPwnageCaptchaSuccess;
public final int noPwnageCaptchaTries;
public final boolean noPwnageCaptchaCheck;
public final String noPwnageCaptchaCharacters;
public final int noPwnageCaptchaLength;
public final String noPwnageCaptchaQuestion;
public final String noPwnageCaptchaSuccess;
public final int noPwnageCaptchaTries;
public final boolean noPwnageFirstCheck;
public final long noPwnageFirstTimeout;
public final int noPwnageFirstWeight;
public final boolean noPwnageFirstCheck;
public final long noPwnageFirstTimeout;
public final int noPwnageFirstWeight;
public final boolean noPwnageGlobalCheck;
public final long noPwnageGlobalTimeout;
public final int noPwnageGlobalWeight;
public final boolean noPwnageGlobalCheck;
public final long noPwnageGlobalTimeout;
public final int noPwnageGlobalWeight;
public final boolean noPwnageMoveCheck;
public final long noPwnageMoveTimeout;
public final int noPwnageMoveWeightBonus;
public final int noPwnageMoveWeightMalus;
public final boolean noPwnageMoveCheck;
public final long noPwnageMoveTimeout;
public final int noPwnageMoveWeightBonus;
public final int noPwnageMoveWeightMalus;
public final boolean noPwnageReloginCheck;
public final String noPwnageReloginKickMessage;
public final long noPwnageReloginTimeout;
public final String noPwnageReloginWarningMessage;
public final int noPwnageReloginWarningNumber;
public final long noPwnageReloginWarningTimeout;
public final boolean noPwnageReloginCheck;
public final String noPwnageReloginKickMessage;
public final long noPwnageReloginTimeout;
public final String noPwnageReloginWarningMessage;
public final int noPwnageReloginWarningNumber;
public final long noPwnageReloginWarningTimeout;
public final boolean noPwnageRepeatCheck;
public final long noPwnageRepeatTimeout;
public final int noPwnageRepeatWeight;
public final boolean noPwnageRepeatCheck;
public final long noPwnageRepeatTimeout;
public final int noPwnageRepeatWeight;
public final boolean noPwnageSpeedCheck;
public final long noPwnageSpeedTimeout;
public final int noPwnageSpeedWeight;
public final boolean noPwnageSpeedCheck;
public final long noPwnageSpeedTimeout;
public final int noPwnageSpeedWeight;
public final int noPwnageWarnLevel;
public final long noPwnageWarnTimeout;
public final boolean noPwnageWarnOthersCheck;
public final String noPwnageWarnOthersMessage;
public final boolean noPwnageWarnPlayerCheck;
public final String noPwnageWarnPlayerMessage;
public final int noPwnageWarnLevel;
public final long noPwnageWarnTimeout;
public final boolean noPwnageWarnOthersCheck;
public final String noPwnageWarnOthersMessage;
public final boolean noPwnageWarnPlayerCheck;
public final String noPwnageWarnPlayerMessage;
public final ActionList noPwnageActions;
public final ActionList noPwnageActions;
public final boolean opInConsoleOnly;
public final boolean opInConsoleOnly;
public final boolean protectPlugins;
public final boolean protectPlugins;
/**
* Instantiates a new chat configuration.
@ -136,6 +138,7 @@ public class ChatConfig implements CheckConfig {
colorActions = data.getActionList(ConfPaths.CHAT_COLOR_ACTIONS, Permissions.CHAT_COLOR);
noPwnageCheck = data.getBoolean(ConfPaths.CHAT_NOPWNAGE_CHECK);
noPwnageExclusions = data.getStringList(ConfPaths.CHAT_NOPWNAGE_EXCLUSIONS);
noPwnageLevel = data.getInt(ConfPaths.CHAT_NOPWNAGE_LEVEL);
noPwnageKickMessage = data.getString(ConfPaths.CHAT_NOPWNAGE_KICKMESSAGE);

View File

@ -3,7 +3,6 @@ package fr.neatmonster.nocheatplus.checks.chat;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.CheckData;
@ -48,22 +47,21 @@ public class ChatData implements CheckData {
}
// Violation levels.
public double colorVL;
public double noPwnageVL;
public double colorVL;
public double noPwnageVL;
// Data of the no pwnage check.
public int noPwnageCaptchTries;
public String noPwnageGeneratedCaptcha;
public boolean noPwnageHasStartedCaptcha;
public long noPwnageJoinTime;
public Location noPwnageLastLocation;
public String noPwnageLastMessage;
public long noPwnageLastMessageTime;
public long noPwnageLastMovedTime;
public long noPwnageLastWarningTime;
public long noPwnageLeaveTime;
public int noPwnageReloginWarnings;
public long noPwnageReloginWarningTime;
public int noPwnageCaptchTries;
public String noPwnageGeneratedCaptcha;
public boolean noPwnageHasStartedCaptcha;
public long noPwnageJoinTime;
public String noPwnageLastMessage;
public long noPwnageLastMessageTime;
public long noPwnageLastMovedTime;
public long noPwnageLastWarningTime;
public long noPwnageLeaveTime;
public int noPwnageReloginWarnings;
public long noPwnageReloginWarningTime;
/**
* Clear the data of the no pwnage check.
@ -72,7 +70,6 @@ public class ChatData implements CheckData {
noPwnageCaptchTries = noPwnageReloginWarnings = 0;
noPwnageJoinTime = noPwnageLastMessageTime = noPwnageLastMovedTime = noPwnageLastWarningTime = noPwnageLeaveTime = noPwnageReloginWarningTime = 0L;
noPwnageGeneratedCaptcha = noPwnageLastMessage = "";
noPwnageLastLocation = null;
}
}

View File

@ -9,6 +9,7 @@ import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerLoginEvent.Result;
import org.bukkit.event.player.PlayerMoveEvent;
import fr.neatmonster.nocheatplus.players.Permissions;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
@ -143,4 +144,26 @@ public class ChatListener implements Listener {
if (noPwnage.isEnabled(player) && noPwnage.checkLogin(player))
event.disallow(Result.KICK_OTHER, cc.noPwnageReloginKickMessage);
}
/**
* When a player moves, he will be checked for various suspicious behaviors.
*
* @param event
* the event
*/
@EventHandler(
ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerMove(final PlayerMoveEvent event) {
/*
* _____ _ __ __
* | __ \| | | \/ |
* | |__) | | __ _ _ _ ___ _ __ | \ / | _____ _____
* | ___/| |/ _` | | | |/ _ \ '__| | |\/| |/ _ \ \ / / _ \
* | | | | (_| | |_| | __/ | | | | | (_) \ V / __/
* |_| |_|\__,_|\__, |\___|_| |_| |_|\___/ \_/ \___|
* __/ |
* |___/
*/
ChatData.getData(event.getPlayer()).noPwnageLastMovedTime = System.currentTimeMillis();
}
}

View File

@ -56,7 +56,7 @@ public class Color extends Check {
data.colorVL++;
// Find out if we need to remove the colors or not.
if (executeActionsThreadSafe(player, data.colorVL, cc.colorActions, isMainThread))
if (executeActionsThreadSafe(player, data.colorVL, 1D, cc.colorActions, isMainThread))
// Remove color codes.
message.replaceAll("\302\247.", "").replaceAll("\247.", "");
}
@ -78,11 +78,11 @@ public class Color extends Check {
* is the thread the main thread
* @return true, if successful
*/
private boolean executeActionsThreadSafe(final Player player, final double VL, final ActionList actions,
final boolean isMainThread) {
private boolean executeActionsThreadSafe(final Player player, final double VL, final double VLAdded,
final ActionList actions, final boolean isMainThread) {
if (isMainThread)
return super.executeActions(player, VL, actions);
return super.executeActions(player, VL, VLAdded, actions);
else
return super.executeActionsThreadSafe(player, VL, actions, type.getPermission());
return super.executeActionsThreadSafe(player, VL, VLAdded, actions, type.getPermission());
}
}

View File

@ -50,13 +50,6 @@ public class NoPwnage extends Check {
*/
public NoPwnage() {
super(CheckType.CHAT_NOPWNAGE);
for (final Player player : Bukkit.getOnlinePlayers()) {
final ChatData data = ChatData.getData(player);
synchronized (data) {
data.noPwnageLastLocation = player.getLocation();
}
}
}
/**
@ -122,14 +115,14 @@ public class NoPwnage extends Check {
* if the thread the main thread
* @return true, if successful
*/
public final boolean executeActionsThreadSafe(final Player player, final double VL, final ActionList actions,
final boolean isMainThread) {
public final boolean executeActionsThreadSafe(final Player player, final double VL, final double VLAdded,
final ActionList actions, final boolean isMainThread) {
final boolean cancel;
if (isMainThread)
cancel = super.executeActions(player, VL, actions);
cancel = super.executeActions(player, VL, VLAdded, actions);
else
// Permission check is done in the main thread.
cancel = super.executeActionsThreadSafe(player, VL, actions, type.getPermission());
cancel = super.executeActionsThreadSafe(player, VL, VLAdded, actions, type.getPermission());
if (cancel)
ChatData.getData(player).clearNoPwnageData();
return cancel;
@ -198,6 +191,11 @@ public class NoPwnage extends Check {
boolean cancel = false;
boolean kick = false;
// Exclusions list.
for (final String exclusion : cc.noPwnageExclusions)
if (message.startsWith(exclusion))
return new boolean[] {false, false};
final long now = System.currentTimeMillis();
if (cc.noPwnageCaptchaCheck && data.noPwnageHasStartedCaptcha) {
@ -211,7 +209,8 @@ public class NoPwnage extends Check {
// Does he failed too much times?
if (data.noPwnageCaptchTries > cc.noPwnageCaptchaTries)
// Find out if we need to ban the player or not.
kick = executeActionsThreadSafe(player, data.noPwnageVL, cc.noPwnageActions, isMainThread);
kick = executeActionsThreadSafe(player, data.noPwnageVL, data.noPwnageVL, cc.noPwnageActions,
isMainThread);
// Increment his tries number counter.
data.noPwnageCaptchTries++;
@ -225,13 +224,6 @@ public class NoPwnage extends Check {
return new boolean[] {true, kick};
}
if (data.noPwnageLastLocation == null)
data.noPwnageLastLocation = player.getLocation();
else if (!data.noPwnageLastLocation.equals(player.getLocation())) {
data.noPwnageLastLocation = player.getLocation();
data.noPwnageLastMovedTime = now;
}
// 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 (cc.noPwnageBannedCheck && now - lastBanCausingMessageTime < cc.noPwnageBannedTimeout
@ -299,7 +291,8 @@ public class NoPwnage extends Check {
cancel = true;
// Find out if we need to ban the player or not.
kick = executeActionsThreadSafe(player, data.noPwnageVL, cc.noPwnageActions, isMainThread);
kick = executeActionsThreadSafe(player, data.noPwnageVL, data.noPwnageVL, cc.noPwnageActions,
isMainThread);
}
// Store the message and some other data.
@ -339,14 +332,12 @@ public class NoPwnage extends Check {
data.noPwnageReloginWarnings++;
} else if (now - data.noPwnageReloginWarningTime < cc.noPwnageReloginWarningTimeout)
// Find out if we need to ban the player or not.
cancel = executeActionsThreadSafe(player, data.noPwnageVL, cc.noPwnageActions, true);
cancel = executeActionsThreadSafe(player, data.noPwnageVL, data.noPwnageVL, cc.noPwnageActions, true);
}
// Store his location and some other data.
data.noPwnageLastLocation = player.getLocation();
// Store his joining time.
data.noPwnageJoinTime = now;
return cancel;
}
}

View File

@ -118,7 +118,7 @@ public class Angle extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.angleVL, cc.angleActions);
cancel = executeActions(player, data.angleVL, violation, cc.angleActions);
} else
// Reward the player by lowering his violation level.
data.angleVL *= 0.98D;

View File

@ -67,7 +67,7 @@ public class Critical extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we
// should cancel the event.
cancel = executeActions(player, data.criticalVL, cc.criticalActions);
cancel = executeActions(player, data.criticalVL, delta, cc.criticalActions);
}
return cancel;

View File

@ -75,7 +75,7 @@ public class Direction extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.directionVL, cc.directionActions);
cancel = executeActions(player, data.directionVL, distance, cc.directionActions);
if (cancel)
// If we should cancel, remember the current time too.

View File

@ -63,7 +63,8 @@ public class GodMode extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if
// we should cancel the event.
cancel = executeActions(player, data.godModeVL, FightConfig.getConfig(player).godModeActions);
cancel = executeActions(player, data.godModeVL, -data.godModeBuffer,
FightConfig.getConfig(player).godModeActions);
}
} else {
// Give some new points, once a second.

View File

@ -56,7 +56,8 @@ public class InstantHeal extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.instantHealVL, FightConfig.getConfig(player).instantHealActions);
cancel = executeActions(player, data.instantHealVL, -data.instantHealBuffer / 1000D,
FightConfig.getConfig(player).instantHealActions);
} else
// Decrease the violation level.
data.instantHealVL *= 0.9D;

View File

@ -49,14 +49,16 @@ public class Knockback extends Check {
// How long ago has the player started sprinting?
if (data.knockbackSprintTime > 0L
&& System.currentTimeMillis() - data.knockbackSprintTime < cc.knockbackInterval) {
final double difference = cc.knockbackInterval - System.currentTimeMillis() + data.knockbackSprintTime;
// Player failed the check, but this is influenced by lag, so don't do it if there was lag.
if (!LagMeasureTask.skipCheck())
// Increment the violation level
data.knockbackVL += cc.knockbackInterval - System.currentTimeMillis() + data.knockbackSprintTime;
data.knockbackVL += difference;
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.knockbackVL, cc.knockbackActions);
cancel = executeActions(player, data.knockbackVL, difference, cc.knockbackActions);
}
return cancel;

View File

@ -50,7 +50,7 @@ public class NoSwing extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.noSwingVL, FightConfig.getConfig(player).noSwingActions);
cancel = executeActions(player, data.noSwingVL, 1D, FightConfig.getConfig(player).noSwingActions);
}
return cancel;

View File

@ -67,7 +67,7 @@ public class Reach extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.reachVL, cc.reachActions);
cancel = executeActions(player, data.reachVL, distance, cc.reachActions);
if (cancel)
// If we should cancel, remember the current time too.

View File

@ -61,7 +61,7 @@ public class Speed extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.speedVL, cc.speedActions);
cancel = executeActions(player, data.speedVL, 1D, cc.speedActions);
}
return cancel;

View File

@ -60,7 +60,7 @@ public class Drop extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.dropVL, cc.dropActions);
cancel = executeActions(player, data.dropVL, data.dropCount - cc.dropLimit, cc.dropActions);
}
return cancel;

View File

@ -50,12 +50,15 @@ public class InstantBow extends Check {
// Security check if time ran backwards, reset
data.instantBowLastTime = 0L;
else {
final double difference = (expectedTimeWhenStringDrawn - System.currentTimeMillis()) / 100D;
// Player was too fast, increase his violation level.
data.instantBowVL += (expectedTimeWhenStringDrawn - System.currentTimeMillis()) / 100D;
data.instantBowVL += difference;
// Execute whatever actions are associated with this check and the
// violation level and find out if we should cancel the event
cancel = executeActions(player, data.instantBowVL, InventoryConfig.getConfig(player).instantBowActions);
cancel = executeActions(player, data.instantBowVL, difference,
InventoryConfig.getConfig(player).instantBowActions);
}
return cancel;

View File

@ -56,12 +56,15 @@ public class InstantEat extends Check {
// Security test, if time ran backwards, reset.
data.instantEatLastTime = 0;
else {
final double difference = (expectedTimeWhenEatingFinished - System.currentTimeMillis()) / 100D;
// Player was too fast, increase his violation level.
data.instantEatVL += (expectedTimeWhenEatingFinished - System.currentTimeMillis()) / 100D;
data.instantEatVL += difference;
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.instantEatVL, InventoryConfig.getConfig(player).instantEatActions);
cancel = executeActions(player, data.instantEatVL, difference,
InventoryConfig.getConfig(player).instantEatActions);
}
return cancel;

View File

@ -134,7 +134,7 @@ public class CreativeFly extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we
// should
// cancel the event.
if (executeActions(player, data.creativeFlyVL, cc.creativeFlyActions))
if (executeActions(player, data.creativeFlyVL, result, cc.creativeFlyActions))
// Compose a new location based on coordinates of "newTo" and viewing direction of "event.getTo()"
// to allow the player to look somewhere else despite getting pulled back by NoCheatPlus.
return new Location(player.getWorld(), data.setBack.getX(), data.setBack.getY(),

View File

@ -80,7 +80,8 @@ public class MorePackets extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
if (executeActions(player, data.morePacketsVL, MovingConfig.getConfig(player).morePacketsActions))
if (executeActions(player, data.morePacketsVL, -data.morePacketsBuffer,
MovingConfig.getConfig(player).morePacketsActions))
newTo = data.teleported = data.morePacketsSetback;
}

View File

@ -79,7 +79,7 @@ public class MorePacketsVehicle extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
if (executeActions(player, data.morePacketsVehicleVL,
if (executeActions(player, data.morePacketsVehicleVL, -data.morePacketsVehicleBuffer,
MovingConfig.getConfig(player).morePacketsVehicleActions))
newTo = data.morePacketsVehicleSetback;
}

View File

@ -64,7 +64,8 @@ public class NoFall extends Check {
data.noFallVL += data.noFallFallDistance - player.getFallDistance();
// Execute the actions to find out if we need to cancel the event or not.
if (executeActions(player, data.noFallVL, cc.noFallActions))
if (executeActions(player, data.noFallVL, data.noFallFallDistance - player.getFallDistance(),
cc.noFallActions))
// Set the fall distance to its right value.
player.setFallDistance((float) data.noFallFallDistance);
} else

View File

@ -56,7 +56,7 @@ public class SurvivalFly extends Check {
data.survivalFlyVL += 100D;
// And return if we need to do something or not.
return executeActions(player, data.survivalFlyVL, MovingConfig.getConfig(player).survivalFlyActions);
return executeActions(player, data.survivalFlyVL, 100D, MovingConfig.getConfig(player).survivalFlyActions);
} else
// He has, everything is alright.
data.survivalFlyWasInBed = false;
@ -208,7 +208,7 @@ public class SurvivalFly extends Check {
// If the other plugins haven't decided to cancel the execution of the actions, then do it. If one of the
// actions was a cancel, cancel it.
if (executeActions(player, data.survivalFlyVL, MovingConfig.getConfig(player).survivalFlyActions))
if (executeActions(player, data.survivalFlyVL, result, MovingConfig.getConfig(player).survivalFlyActions))
// Compose a new location based on coordinates of "newTo" and viewing direction of "event.getTo()" to
// allow the player to look somewhere else despite getting pulled back by NoCheatPlus.
return new Location(player.getWorld(), data.setBack.getX(), data.setBack.getY(), data.setBack.getZ(),

View File

@ -138,6 +138,7 @@ public abstract class ConfPaths {
private static final String CHAT_NOPWNAGE = CHAT + "nopwnage.";
public static final String CHAT_NOPWNAGE_CHECK = CHAT_NOPWNAGE + "active";
public static final String CHAT_NOPWNAGE_EXCLUSIONS = CHAT_NOPWNAGE + "exclusions";
public static final String CHAT_NOPWNAGE_LEVEL = CHAT_NOPWNAGE + "level";
public static final String CHAT_NOPWNAGE_KICKMESSAGE = CHAT_NOPWNAGE + "kickmessage";

View File

@ -1,5 +1,7 @@
package fr.neatmonster.nocheatplus.config;
import java.util.ArrayList;
/*
* M""""""'YMM .8888b dP dP MM'""""'YMM .8888b oo
* M mmmm. `M 88 " 88 88 M' .mmm. `M 88 "
@ -126,7 +128,8 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.CHAT_COLOR_ACTIONS, "log:color:0:1:if cancel");
set(ConfPaths.CHAT_NOPWNAGE_CHECK, true);
set(ConfPaths.CHAT_NOPWNAGE_LEVEL, 800);
set(ConfPaths.CHAT_NOPWNAGE_EXCLUSIONS, new ArrayList<String>());
set(ConfPaths.CHAT_NOPWNAGE_LEVEL, 500);
set(ConfPaths.CHAT_NOPWNAGE_KICKMESSAGE, "You're not allowed to spam this server!");
set(ConfPaths.CHAT_NOPWNAGE_BANNED_CHECK, true);
@ -178,7 +181,7 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.CHAT_NOPWNAGE_WARN_OTHERS_CHECK, false);
set(ConfPaths.CHAT_NOPWNAGE_WARN_OTHERS_MESSAGE, "&cPlease do not say anything similar to what [player] said!");
set(ConfPaths.CHAT_NOPWNAGE_WARN_PLAYER_CHECK, false);
set(ConfPaths.CHAT_NOPWNAGE_WARN_PLAYER_CHECK, true);
set(ConfPaths.CHAT_NOPWNAGE_WARN_PLAYER_MESSAGE,
"&cOur system has detected unusual bot activities coming from you. Please be careful with what you say. DON'T repeat what you just said either, unless you want to be banned.");

View File

@ -29,6 +29,7 @@ public class Permissions {
public static final String ADMINISTRATION_BUKKIT_PLUGINS = ADMINISTRATION_BUKKIT + ".plugins";
public static final String ADMINISTRATION_BUKKIT_VERSION = ADMINISTRATION_BUKKIT + ".version";
public static final String ADMINISTRATION_INFO = ADMINISTRATION + ".info";
public static final String ADMINISTRATION_NOTIFY = ADMINISTRATION + ".notify";
public static final String ADMINISTRATION_RELOAD = ADMINISTRATION + ".reload";