[Development] Adding checks... Done. A lot of bug fixes are still

required with the modified checks, and also documentation isn't
up-to-date.
This commit is contained in:
NeatMonster 2012-08-05 20:00:05 +02:00
parent e706558cc1
commit cbbc904dd9
17 changed files with 668 additions and 16 deletions

View File

@ -10,6 +10,7 @@ import fr.neatmonster.nocheatplus.checks.blockbreak.BlockBreakConfig;
import fr.neatmonster.nocheatplus.checks.blockplace.BlockPlaceConfig; import fr.neatmonster.nocheatplus.checks.blockplace.BlockPlaceConfig;
import fr.neatmonster.nocheatplus.checks.chat.ChatConfig; import fr.neatmonster.nocheatplus.checks.chat.ChatConfig;
import fr.neatmonster.nocheatplus.checks.fight.FightConfig; 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.checks.moving.MovingConfig;
import fr.neatmonster.nocheatplus.config.ConfPaths; import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigManager; import fr.neatmonster.nocheatplus.config.ConfigManager;
@ -67,6 +68,7 @@ public class CommandHandler implements CommandExecutor {
BlockPlaceConfig.clear(); BlockPlaceConfig.clear();
ChatConfig.clear(); ChatConfig.clear();
FightConfig.clear(); FightConfig.clear();
InventoryConfig.clear();
MovingConfig.clear(); MovingConfig.clear();
sender.sendMessage(ChatColor.RED + "NCP: " + ChatColor.WHITE + "Configuration reloaded!"); sender.sendMessage(ChatColor.RED + "NCP: " + ChatColor.WHITE + "Configuration reloaded!");

View File

@ -17,6 +17,7 @@ import fr.neatmonster.nocheatplus.checks.blockbreak.BlockBreakListener;
import fr.neatmonster.nocheatplus.checks.blockplace.BlockPlaceListener; import fr.neatmonster.nocheatplus.checks.blockplace.BlockPlaceListener;
import fr.neatmonster.nocheatplus.checks.chat.ChatListener; import fr.neatmonster.nocheatplus.checks.chat.ChatListener;
import fr.neatmonster.nocheatplus.checks.fight.FightListener; import fr.neatmonster.nocheatplus.checks.fight.FightListener;
import fr.neatmonster.nocheatplus.checks.inventory.InventoryListener;
import fr.neatmonster.nocheatplus.checks.moving.MovingListener; import fr.neatmonster.nocheatplus.checks.moving.MovingListener;
import fr.neatmonster.nocheatplus.config.ConfPaths; import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigManager; import fr.neatmonster.nocheatplus.config.ConfigManager;
@ -74,6 +75,7 @@ public class NoCheatPlus extends JavaPlugin implements Listener {
listeners.add(new BlockPlaceListener()); listeners.add(new BlockPlaceListener());
listeners.add(new ChatListener()); listeners.add(new ChatListener());
listeners.add(new FightListener()); listeners.add(new FightListener());
listeners.add(new InventoryListener());
listeners.add(new MovingListener()); listeners.add(new MovingListener());
listeners.add(new Workarounds()); listeners.add(new Workarounds());

View File

@ -24,13 +24,14 @@ public enum ParameterName {
ATTACKS_LIMIT("attackslimit"), ATTACKS_LIMIT("attackslimit"),
CHECK("check"), CHECK("check"),
DISTANCE("distance"), DISTANCE("distance"),
FALLDISTANCE("falldistance"), FALL_DISTANCE("falldistance"),
FOOD("food"),
IP("ip"), IP("ip"),
LOCATION_FROM("locationfrom"), LOCATION_FROM("locationfrom"),
LOCATION_TO("locationto"), LOCATION_TO("locationto"),
PACKETS("packets"), PACKETS("packets"),
PLAYER("player"), PLAYER("player"),
REACHDISTANCE("reachdistance"), REACH_DISTANCE("reachdistance"),
VIOLATIONS("violations"), VIOLATIONS("violations"),
WORLD("world"); WORLD("world");
/** /**

View File

@ -90,7 +90,7 @@ public class Reach extends Check {
public String getParameter(final ParameterName wildcard, final Player player) { public String getParameter(final ParameterName wildcard, final Player player) {
if (wildcard == ParameterName.VIOLATIONS) if (wildcard == ParameterName.VIOLATIONS)
return String.valueOf(Math.round(BlockBreakData.getData(player).reachVL)); return String.valueOf(Math.round(BlockBreakData.getData(player).reachVL));
else if (wildcard == ParameterName.REACHDISTANCE) else if (wildcard == ParameterName.REACH_DISTANCE)
return String.valueOf(Math.round(BlockBreakData.getData(player).reachDistance)); return String.valueOf(Math.round(BlockBreakData.getData(player).reachDistance));
else else
return super.getParameter(wildcard, player); return super.getParameter(wildcard, player);

View File

@ -89,7 +89,7 @@ public class Reach extends Check {
public String getParameter(final ParameterName wildcard, final Player player) { public String getParameter(final ParameterName wildcard, final Player player) {
if (wildcard == ParameterName.VIOLATIONS) if (wildcard == ParameterName.VIOLATIONS)
return String.valueOf(Math.round(BlockPlaceData.getData(player).reachVL)); return String.valueOf(Math.round(BlockPlaceData.getData(player).reachVL));
else if (wildcard == ParameterName.REACHDISTANCE) else if (wildcard == ParameterName.REACH_DISTANCE)
return String.valueOf(Math.round(BlockPlaceData.getData(player).reachDistance)); return String.valueOf(Math.round(BlockPlaceData.getData(player).reachDistance));
else else
return super.getParameter(wildcard, player); return super.getParameter(wildcard, player);

View File

@ -5,7 +5,7 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerChatEvent; import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerLoginEvent.Result; import org.bukkit.event.player.PlayerLoginEvent.Result;
@ -38,7 +38,7 @@ public class ChatListener implements Listener {
*/ */
@EventHandler( @EventHandler(
ignoreCancelled = true, priority = EventPriority.LOWEST) ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerChat(final PlayerChatEvent event) { public void onPlayerChat(final AsyncPlayerChatEvent event) {
/* /*
* ____ _ ____ _ _ * ____ _ ____ _ _
* | _ \| | __ _ _ _ ___ _ __ / ___| |__ __ _| |_ * | _ \| | __ _ _ _ ___ _ __ / ___| |__ __ _| |_

View File

@ -4,7 +4,7 @@ import java.util.Random;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerChatEvent; import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerEvent; import org.bukkit.event.player.PlayerEvent;
@ -128,8 +128,8 @@ public class NoPwnage extends Check {
if (!data.noPwnageHasFilledCaptcha) { if (!data.noPwnageHasFilledCaptcha) {
String message = ""; String message = "";
if (event instanceof PlayerChatEvent) if (event instanceof AsyncPlayerChatEvent)
message = ((PlayerChatEvent) event).getMessage(); message = ((AsyncPlayerChatEvent) event).getMessage();
else if (event instanceof PlayerCommandPreprocessEvent) else if (event instanceof PlayerCommandPreprocessEvent)
message = ((PlayerCommandPreprocessEvent) event).getMessage(); message = ((PlayerCommandPreprocessEvent) event).getMessage();
final boolean isCommand = event instanceof PlayerCommandPreprocessEvent; final boolean isCommand = event instanceof PlayerCommandPreprocessEvent;
@ -164,8 +164,8 @@ public class NoPwnage extends Check {
} }
// Cancel the event and return. // Cancel the event and return.
if (event instanceof PlayerChatEvent) if (event instanceof AsyncPlayerChatEvent)
((PlayerChatEvent) event).setCancelled(true); ((AsyncPlayerChatEvent) event).setCancelled(true);
else if (event instanceof PlayerCommandPreprocessEvent) else if (event instanceof PlayerCommandPreprocessEvent)
((PlayerCommandPreprocessEvent) event).setCancelled(true); ((PlayerCommandPreprocessEvent) event).setCancelled(true);
return cancel; return cancel;
@ -234,8 +234,8 @@ public class NoPwnage extends Check {
player.sendMessage(replaceColors(cc.noPwnageCaptchaQuestion.replace("[captcha]", player.sendMessage(replaceColors(cc.noPwnageCaptchaQuestion.replace("[captcha]",
data.noPwnageGeneratedCaptcha))); data.noPwnageGeneratedCaptcha)));
data.noPwnageHasStartedCaptcha = true; data.noPwnageHasStartedCaptcha = true;
if (event instanceof PlayerChatEvent) if (event instanceof AsyncPlayerChatEvent)
((PlayerChatEvent) event).setCancelled(true); ((AsyncPlayerChatEvent) event).setCancelled(true);
else if (event instanceof PlayerCommandPreprocessEvent) else if (event instanceof PlayerCommandPreprocessEvent)
((PlayerCommandPreprocessEvent) event).setCancelled(true); ((PlayerCommandPreprocessEvent) event).setCancelled(true);
} else { } else {
@ -244,8 +244,8 @@ public class NoPwnage extends Check {
if (cc.noPwnageWarnOthersCheck) if (cc.noPwnageWarnOthersCheck)
Bukkit.broadcastMessage(replaceColors(cc.noPwnageWarnOthersMessage.replace("[player]", Bukkit.broadcastMessage(replaceColors(cc.noPwnageWarnOthersMessage.replace("[player]",
player.getName()))); player.getName())));
if (event instanceof PlayerChatEvent) if (event instanceof AsyncPlayerChatEvent)
((PlayerChatEvent) event).setCancelled(true); ((AsyncPlayerChatEvent) event).setCancelled(true);
else if (event instanceof PlayerCommandPreprocessEvent) else if (event instanceof PlayerCommandPreprocessEvent)
((PlayerCommandPreprocessEvent) event).setCancelled(true); ((PlayerCommandPreprocessEvent) event).setCancelled(true);

View File

@ -0,0 +1,103 @@
package fr.neatmonster.nocheatplus.checks.inventory;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckEvent;
import fr.neatmonster.nocheatplus.players.Permissions;
/*
* M""""""'YMM
* M mmmm. `M
* M MMMMM M 88d888b. .d8888b. 88d888b.
* M MMMMM M 88' `88 88' `88 88' `88
* M MMMM' .M 88 88. .88 88. .88
* M .MM dP `88888P' 88Y888P'
* MMMMMMMMMMM 88
* dP
*/
/**
* The Drop check will find out if a player drops too many items within a short amount of time.
*/
public class Drop extends Check {
/**
* The event triggered by this check.
*/
public class DropEvent extends CheckEvent {
/**
* Instantiates a new drop event.
*
* @param player
* the player
*/
public DropEvent(final Player player) {
super(player);
}
}
/**
* Checks a player.
*
* @param player
* the player
* @return true, if successful
*/
public boolean check(final Player player) {
final InventoryConfig cc = InventoryConfig.getConfig(player);
final InventoryData data = InventoryData.getData(player);
boolean cancel = false;
// Has the configured time passed? If so, reset the counter.
if (data.dropLastTime + cc.dropTimeFrame <= System.currentTimeMillis()) {
data.dropLastTime = System.currentTimeMillis();
data.dropCount = 0;
data.dropVL = 0D;
}
// Security check, if the system time changes.
else if (data.dropLastTime > System.currentTimeMillis())
data.dropLastTime = Integer.MIN_VALUE;
data.dropCount++;
// The player dropped more than he should.
if (data.dropCount > cc.dropLimit) {
// Set his violation level.
data.dropVL = data.dropCount - cc.dropLimit;
// Dispatch a drop event (API).
final DropEvent e = new DropEvent(player);
Bukkit.getPluginManager().callEvent(e);
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = !e.isCancelled() && executeActions(player, cc.dropActions, data.dropVL);
}
return cancel;
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.checks.Check#getParameter(fr.neatmonster.nocheatplus.actions.ParameterName, org.bukkit.entity.Player)
*/
@Override
public String getParameter(final ParameterName wildcard, final Player player) {
if (wildcard == ParameterName.VIOLATIONS)
return String.valueOf(Math.round(InventoryData.getData(player).dropVL));
else
return super.getParameter(wildcard, player);
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.checks.Check#isEnabled(org.bukkit.entity.Player)
*/
@Override
protected boolean isEnabled(final Player player) {
return !player.hasPermission(Permissions.INVENTORY_DROP) && InventoryConfig.getConfig(player).dropCheck;
}
}

View File

@ -0,0 +1,100 @@
package fr.neatmonster.nocheatplus.checks.inventory;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckEvent;
import fr.neatmonster.nocheatplus.players.Permissions;
/*
* M""M dP dP M#"""""""'M
* M M 88 88 ## mmmm. `M
* M M 88d888b. .d8888b. d8888P .d8888b. 88d888b. d8888P #' .M .d8888b. dP dP dP
* M M 88' `88 Y8ooooo. 88 88' `88 88' `88 88 M# MMMb.'YM 88' `88 88 88 88
* M M 88 88 88 88 88. .88 88 88 88 M# MMMM' M 88. .88 88.88b.88'
* M M dP dP `88888P' dP `88888P8 dP dP dP M# .;M `88888P' 8888P Y8P
* MMMM M#########M
*/
/**
* The InstantBow check will find out if a player pulled the string of his bow too fast.
*/
public class InstantBow extends Check {
/**
* The event triggered by this check.
*/
public class InstantBowEvent extends CheckEvent {
/**
* Instantiates a new instant bow event.
*
* @param player
* the player
*/
public InstantBowEvent(final Player player) {
super(player);
}
}
/**
* Checks a player.
*
* @param player
* the player
* @param force
* the force
* @return true, if successful
*/
public boolean check(final Player player, final float force) {
final InventoryConfig cc = InventoryConfig.getConfig(player);
final InventoryData data = InventoryData.getData(player);
boolean cancel = false;
// Rough estimation of how long pulling the string should've taken.
final long expectedTimeWhenStringDrawn = data.instantBowLastTime + (int) (force * force * 700F);
if (expectedTimeWhenStringDrawn < System.currentTimeMillis())
// The player was slow enough, reward him by lowering his violation level.
data.instantBowVL *= 0.9D;
else if (data.instantBowLastTime > System.currentTimeMillis())
// Security check if time ran backwards, reset
data.instantBowLastTime = 0L;
else {
// Player was too fast, increase his violation level.
data.instantBowVL += (expectedTimeWhenStringDrawn - System.currentTimeMillis()) / 100D;
// Dispatch an instant bow event (API).
final InstantBowEvent e = new InstantBowEvent(player);
Bukkit.getPluginManager().callEvent(e);
// Execute whatever actions are associated with this check and the
// violation level and find out if we should cancel the event
cancel = !e.isCancelled() && executeActions(player, cc.instantBowActions, data.instantBowVL);
}
return cancel;
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.checks.Check#getParameter(fr.neatmonster.nocheatplus.actions.ParameterName, org.bukkit.entity.Player)
*/
@Override
public String getParameter(final ParameterName wildcard, final Player player) {
if (wildcard == ParameterName.VIOLATIONS)
return String.valueOf(Math.round(InventoryData.getData(player).instantBowVL));
else
return super.getParameter(wildcard, player);
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.checks.Check#isEnabled(org.bukkit.entity.Player)
*/
@Override
protected boolean isEnabled(final Player player) {
return !player.hasPermission(Permissions.INVENTORY_INSTANTBOW)
&& InventoryConfig.getConfig(player).instantBowCheck;
}
}

View File

@ -0,0 +1,106 @@
package fr.neatmonster.nocheatplus.checks.inventory;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckEvent;
import fr.neatmonster.nocheatplus.players.Permissions;
/*
* M""M dP dP MM""""""""`M dP
* M M 88 88 MM mmmmmmmM 88
* M M 88d888b. .d8888b. d8888P .d8888b. 88d888b. d8888P M` MMMM .d8888b. d8888P
* M M 88' `88 Y8ooooo. 88 88' `88 88' `88 88 MM MMMMMMMM 88' `88 88
* M M 88 88 88 88 88. .88 88 88 88 MM MMMMMMMM 88. .88 88
* M M dP dP `88888P' dP `88888P8 dP dP dP MM .M `88888P8 dP
* MMMM MMMMMMMMMMMM
*/
/**
* The InstantEat check will find out if a player eats his food too fast.
*/
public class InstantEat extends Check {
/**
* The event triggered by this check.
*/
public class InstantEatEvent extends CheckEvent {
/**
* Instantiates a new instant eat event.
*
* @param player
* the player
*/
public InstantEatEvent(final Player player) {
super(player);
}
}
/**
* Checks a player.
*
* @param player
* the player
* @param level
* the level
* @return true, if successful
*/
public boolean check(final Player player, final int level) {
final InventoryConfig cc = InventoryConfig.getConfig(player);
final InventoryData data = InventoryData.getData(player);
boolean cancel = false;
// Hunger level change seems to not be the result of eating.
if (data.instantEatFood == null || level <= player.getFoodLevel())
return false;
// rough estimation about how long it should take to eat
final long expectedTimeWhenEatingFinished = data.instantEatLastTime + 700L;
if (expectedTimeWhenEatingFinished < System.currentTimeMillis())
// Acceptable, reduce VL to reward the player.
data.instantEatVL *= 0.6D;
else if (data.instantEatLastTime > System.currentTimeMillis())
// Security test, if time ran backwards, reset.
data.instantEatLastTime = 0;
else {
// Player was too fast, increase his violation level.
data.instantEatVL += (expectedTimeWhenEatingFinished - System.currentTimeMillis()) / 100D;
// Dispatch an instant eat event (API).
final InstantEatEvent e = new InstantEatEvent(player);
Bukkit.getPluginManager().callEvent(e);
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = !e.isCancelled() && executeActions(player, cc.instantEatActions, data.instantEatVL);
}
return cancel;
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.checks.Check#getParameter(fr.neatmonster.nocheatplus.actions.ParameterName, org.bukkit.entity.Player)
*/
@Override
public String getParameter(final ParameterName wildcard, final Player player) {
if (wildcard == ParameterName.VIOLATIONS)
return String.valueOf(Math.round(InventoryData.getData(player).instantEatVL));
else if (wildcard == ParameterName.FOOD)
return InventoryData.getData(player).instantEatFood.toString();
else
return super.getParameter(wildcard, player);
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.checks.Check#isEnabled(org.bukkit.entity.Player)
*/
@Override
protected boolean isEnabled(final Player player) {
return !player.hasPermission(Permissions.INVENTORY_INSTANTEAT)
&& InventoryConfig.getConfig(player).instantEatCheck;
}
}

View File

@ -0,0 +1,94 @@
package fr.neatmonster.nocheatplus.checks.inventory;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.actions.types.ActionList;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.players.Permissions;
/*
* M""M dP
* M M 88
* M M 88d888b. dP .dP .d8888b. 88d888b. d8888P .d8888b. 88d888b. dP dP
* M M 88' `88 88 d8' 88ooood8 88' `88 88 88' `88 88' `88 88 88
* M M 88 88 88 .88' 88. ... 88 88 88 88. .88 88 88. .88
* M M dP dP 8888P' `88888P' dP dP dP `88888P' dP `8888P88
* MMMM .88
* d8888P
*
* MM'""""'YMM .8888b oo
* M' .mmm. `M 88 "
* M MMMMMooM .d8888b. 88d888b. 88aaa dP .d8888b.
* M MMMMMMMM 88' `88 88' `88 88 88 88' `88
* M. `MMM' .M 88. .88 88 88 88 88 88. .88
* MM. .dM `88888P' dP dP dP dP `8888P88
* MMMMMMMMMMM .88
* d8888P
*/
/**
* Configurations specific for the "inventory" checks. Every world gets one of these assigned to it, or if a world
* doesn't get it's own, it will use the "global" version.
*/
public class InventoryConfig {
/** The map containing the configurations per world. */
private static Map<String, InventoryConfig> worldsMap = new HashMap<String, InventoryConfig>();
/**
* Clear all the configurations.
*/
public static void clear() {
worldsMap.clear();
}
/**
* Gets the configuration for a specified player.
*
* @param player
* the player
* @return the configuration
*/
public static InventoryConfig getConfig(final Player player) {
if (!worldsMap.containsKey(player.getWorld().getName()))
worldsMap.put(player.getWorld().getName(),
new InventoryConfig(ConfigManager.getConfigFile(player.getWorld().getName())));
return worldsMap.get(player.getWorld().getName());
}
public final boolean dropCheck;
public final int dropLimit;
public final long dropTimeFrame;
public final ActionList dropActions;
public final boolean instantBowCheck;
public final ActionList instantBowActions;
public final boolean instantEatCheck;
public final ActionList instantEatActions;
/**
* Instantiates a new inventory configuration.
*
* @param data
* the data
*/
public InventoryConfig(final ConfigFile data) {
dropCheck = data.getBoolean(ConfPaths.INVENTORY_DROP_CHECK);
dropLimit = data.getInt(ConfPaths.INVENTORY_DROP_LIMIT);
dropTimeFrame = data.getLong(ConfPaths.INVENTORY_DROP_TIMEFRAME);
dropActions = data.getActionList(ConfPaths.INVENTORY_DROP_ACTIONS, Permissions.INVENTORY_DROP);
instantBowCheck = data.getBoolean(ConfPaths.INVENTORY_INSTANTBOW_CHECK);
instantBowActions = data
.getActionList(ConfPaths.INVENTORY_INSTANTBOW_ACTIONS, Permissions.INVENTORY_INSTANTBOW);
instantEatCheck = data.getBoolean(ConfPaths.INVENTORY_INSTANTEAT_CHECK);
instantEatActions = data
.getActionList(ConfPaths.INVENTORY_INSTANTEAT_ACTIONS, Permissions.INVENTORY_INSTANTEAT);
}
}

View File

@ -0,0 +1,55 @@
package fr.neatmonster.nocheatplus.checks.inventory;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Material;
import org.bukkit.entity.Player;
/*
* M""M dP M""""""'YMM dP
* M M 88 M mmmm. `M 88
* M M 88d888b. dP .dP .d8888b. 88d888b. d8888P .d8888b. 88d888b. dP dP M MMMMM M .d8888b. d8888P .d8888b.
* M M 88' `88 88 d8' 88ooood8 88' `88 88 88' `88 88' `88 88 88 M MMMMM M 88' `88 88 88' `88
* M M 88 88 88 .88' 88. ... 88 88 88 88. .88 88 88. .88 M MMMM' .M 88. .88 88 88. .88
* M M dP dP 8888P' `88888P' dP dP dP `88888P' dP `8888P88 M .MM `88888P8 dP `88888P8
* MMMM .88 MMMMMMMMMMM
* d8888P
*/
/**
* Player specific data for the inventory checks.
*/
public class InventoryData {
/** The map containing the data per players. */
private static Map<String, InventoryData> playersMap = new HashMap<String, InventoryData>();
/**
* Gets the data of a specified player.
*
* @param player
* the player
* @return the data
*/
public static InventoryData getData(final Player player) {
if (!playersMap.containsKey(player.getName()))
playersMap.put(player.getName(), new InventoryData());
return playersMap.get(player.getName());
}
// Violation levels.
public double dropVL;
public double instantBowVL;
public double instantEatVL;
// Data of the drop check.
public int dropCount;
public long dropLastTime;
// Data of the instant bow check.
public long instantBowLastTime;
// Data of the instant eat check.
public Material instantEatFood;
public long instantEatLastTime;
}

View File

@ -0,0 +1,127 @@
package fr.neatmonster.nocheatplus.checks.inventory;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerInteractEvent;
/*
* M""M dP
* M M 88
* M M 88d888b. dP .dP .d8888b. 88d888b. d8888P .d8888b. 88d888b. dP dP
* M M 88' `88 88 d8' 88ooood8 88' `88 88 88' `88 88' `88 88 88
* M M 88 88 88 .88' 88. ... 88 88 88 88. .88 88 88. .88
* M M dP dP 8888P' `88888P' dP dP dP `88888P' dP `8888P88
* MMMM .88
* d8888P
*
* M""MMMMMMMM oo dP
* M MMMMMMMM 88
* M MMMMMMMM dP .d8888b. d8888P .d8888b. 88d888b. .d8888b. 88d888b.
* M MMMMMMMM 88 Y8ooooo. 88 88ooood8 88' `88 88ooood8 88' `88
* M MMMMMMMM 88 88 88 88. ... 88 88 88. ... 88
* M M dP `88888P' dP `88888P' dP dP `88888P' dP
* MMMMMMMMMMM
*/
/**
* Central location to listen to events that are relevant for the inventory checks.
*/
public class InventoryListener implements Listener {
private final Drop drop = new Drop();
private final InstantBow instantBow = new InstantBow();
private final InstantEat instantEat = new InstantEat();
/**
* We listen to EntityShootBow events for the InstantBow check.
*
* @param event
* the event
*/
@EventHandler(
ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onEntityShootBow(final EntityShootBowEvent event) {
// Only if a player shot the arrow.
if (event.getEntity() instanceof Player) {
final Player player = (Player) event.getEntity();
if (instantBow.isEnabled(player) && instantBow.check(player, event.getForce()))
// The check requested the event to be cancelled.
event.setCancelled(true);
}
}
/**
* We listen to FoodLevelChange events because Bukkit doesn't provide a PlayerFoodEating Event (or whatever it would
* be called).
*
* @param event
* the event
*/
@EventHandler(
ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onFoodLevelChange(final FoodLevelChangeEvent event) {
// Only if a player ate food.
if (event.getEntity() instanceof Player) {
final Player player = (Player) event.getEntity();
if (instantEat.isEnabled(player) && instantEat.check(player, event.getFoodLevel()))
event.setCancelled(true);
// Forget the food material, as the info is no longer needed.
InventoryData.getData(player).instantEatFood = null;
}
}
/**
* We listen to DropItem events for the Drop check.
*
* @param event
* the event
*/
@EventHandler(
ignoreCancelled = true, priority = EventPriority.LOWEST)
protected void onPlayerDropItem(final PlayerDropItemEvent event) {
// If the player died, all his items are dropped so ignore him.
if (event.getPlayer().isDead())
return;
if (drop.isEnabled(event.getPlayer()) && drop.check(event.getPlayer()))
// Cancelling drop events is not save (in certain circumstances items will disappear completely). So don't
// do it and kick players instead by default.
event.getPlayer().kickPlayer("You're not allowed to crash the server by dropping items!");
}
/**
* We listen to PlayerInteract events for the InstantEat and InstantBow checks.
*
* @param event
* the event
*/
@EventHandler(
priority = EventPriority.LOWEST)
public void onPlayerInteractEvent(final PlayerInteractEvent event) {
// Only interested in right-clicks while holding an item.
if (!event.hasItem()
|| !(event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK))
return;
final InventoryData data = InventoryData.getData(event.getPlayer());
if (event.getItem().getType() == Material.BOW)
// It was a bow, the player starts to pull the string, remember this time.
data.instantBowLastTime = System.currentTimeMillis();
else if (event.getItem().getType().isEdible()) {
// It was food, the player starts to eat some food, remember this time and the type of food.
data.instantEatFood = event.getItem().getType();
data.instantEatLastTime = System.currentTimeMillis();
} else {
// Nothing that we are interested in, reset data.
data.instantBowLastTime = 0;
data.instantEatLastTime = 0;
data.instantEatFood = null;
}
}
}

View File

@ -151,7 +151,7 @@ public class NoFall extends Check {
public String getParameter(final ParameterName wildcard, final Player player) { public String getParameter(final ParameterName wildcard, final Player player) {
if (wildcard == ParameterName.VIOLATIONS) if (wildcard == ParameterName.VIOLATIONS)
return String.valueOf(Math.round(MovingData.getData(player).noFallVL)); return String.valueOf(Math.round(MovingData.getData(player).noFallVL));
else if (wildcard == ParameterName.FALLDISTANCE) else if (wildcard == ParameterName.FALL_DISTANCE)
return String.format(Locale.US, "%.2f", MovingData.getData(player).noFallDistance); return String.format(Locale.US, "%.2f", MovingData.getData(player).noFallDistance);
else else
return super.getParameter(wildcard, player); return super.getParameter(wildcard, player);

View File

@ -240,6 +240,31 @@ public abstract class ConfPaths {
public static final String FIGHT_SPEED_LIMIT = FIGHT_SPEED + "limit"; public static final String FIGHT_SPEED_LIMIT = FIGHT_SPEED + "limit";
public static final String FIGHT_SPEED_ACTIONS = FIGHT_SPEED + "actions"; public static final String FIGHT_SPEED_ACTIONS = FIGHT_SPEED + "actions";
/*
* 888 d8
* 888 888 8e Y8b Y888P ,e e, 888 8e d88 e88 88e 888,8, Y8b Y888P
* 888 888 88b Y8b Y8P d88 88b 888 88b d88888 d888 888b 888 " Y8b Y8P
* 888 888 888 Y8b " 888 , 888 888 888 Y888 888P 888 Y8b Y
* 888 888 888 Y8P "YeeP" 888 888 888 "88 88" 888 888
* 888
* 888
*/
private static final String INVENTORY = CHECKS + "inventory.";
private static final String INVENTORY_DROP = INVENTORY + "drop.";
public static final String INVENTORY_DROP_CHECK = INVENTORY_DROP + "active";
public static final String INVENTORY_DROP_LIMIT = INVENTORY_DROP + "limit";
public static final String INVENTORY_DROP_TIMEFRAME = INVENTORY_DROP + "timeframe";
public static final String INVENTORY_DROP_ACTIONS = INVENTORY_DROP + "actions";
private static final String INVENTORY_INSTANTBOW = INVENTORY + "instantbow.";
public static final String INVENTORY_INSTANTBOW_CHECK = INVENTORY_INSTANTBOW + "active";
public static final String INVENTORY_INSTANTBOW_ACTIONS = INVENTORY_INSTANTBOW + "actions";
private static final String INVENTORY_INSTANTEAT = INVENTORY + "instanteat.";
public static final String INVENTORY_INSTANTEAT_CHECK = INVENTORY_INSTANTEAT + "active";
public static final String INVENTORY_INSTANTEAT_ACTIONS = INVENTORY_INSTANTEAT + "actions";
/* /*
* e e ,e, * e e ,e,
* d8b d8b e88 88e Y8b Y888P " 888 8e e88 888 * d8b d8b e88 88e Y8b Y888P " 888 8e e88 888

View File

@ -212,6 +212,26 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.FIGHT_SPEED_LIMIT, 15); set(ConfPaths.FIGHT_SPEED_LIMIT, 15);
set(ConfPaths.FIGHT_SPEED_ACTIONS, "log:fspeed:0:5:if cancel"); set(ConfPaths.FIGHT_SPEED_ACTIONS, "log:fspeed:0:5:if cancel");
/*
* 888 d8
* 888 888 8e Y8b Y888P ,e e, 888 8e d88 e88 88e 888,8, Y8b Y888P
* 888 888 88b Y8b Y8P d88 88b 888 88b d88888 d888 888b 888 " Y8b Y8P
* 888 888 888 Y8b " 888 , 888 888 888 Y888 888P 888 Y8b Y
* 888 888 888 Y8P "YeeP" 888 888 888 "88 88" 888 888
* 888
* 888
*/
set(ConfPaths.INVENTORY_DROP_CHECK, true);
set(ConfPaths.INVENTORY_DROP_LIMIT, 100);
set(ConfPaths.INVENTORY_DROP_TIMEFRAME, 20L);
set(ConfPaths.INVENTORY_DROP_ACTIONS, "log:drop:0:1:cif cmd:kick");
set(ConfPaths.INVENTORY_INSTANTBOW_CHECK, true);
set(ConfPaths.INVENTORY_INSTANTBOW_ACTIONS, "log:instantbow:2:5:if cancel");
set(ConfPaths.INVENTORY_INSTANTEAT_CHECK, true);
set(ConfPaths.INVENTORY_INSTANTEAT_ACTIONS, "log:instanteat:2:5:if cancel");
/* /*
* e e ,e, * e e ,e,
* d8b d8b e88 88e Y8b Y888P " 888 8e e88 888 * d8b d8b e88 88e Y8b Y888P " 888 8e e88 888
@ -274,6 +294,7 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.STRINGS + ".breach", start set(ConfPaths.STRINGS + ".breach", start
+ "tried to interact with a block over distance [reachdistance] block(s)" + end); + "tried to interact with a block over distance [reachdistance] block(s)" + end);
set(ConfPaths.STRINGS + ".critical", start + "tried to do a critical hit but wasn't technically jumping" + 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 + ".fastbreak", start + "tried to break too much blocks" + end);
set(ConfPaths.STRINGS + ".fastplace", start + "tried to place too much blocks" + end); set(ConfPaths.STRINGS + ".fastplace", start + "tried to place too much blocks" + end);
set(ConfPaths.STRINGS + ".fdirection", start + "tried to hit an entity out of line of sight" + end); set(ConfPaths.STRINGS + ".fdirection", start + "tried to hit an entity out of line of sight" + end);
@ -283,6 +304,8 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.STRINGS + ".freach", start + "tried to attack entity out of reach" + end); set(ConfPaths.STRINGS + ".freach", start + "tried to attack entity out of reach" + end);
set(ConfPaths.STRINGS + ".fspeed", start + "tried to attack more than [attackslimit] times per second" + end); set(ConfPaths.STRINGS + ".fspeed", start + "tried to attack more than [attackslimit] times per second" + end);
set(ConfPaths.STRINGS + ".godmode", start + "avoided taking damage or lagging" + end); set(ConfPaths.STRINGS + ".godmode", start + "avoided taking damage or lagging" + end);
set(ConfPaths.STRINGS + ".instantbow", start + "fires bow to fast" + end);
set(ConfPaths.STRINGS + ".instanteat", start + "eats food [food] too fast" + end);
set(ConfPaths.STRINGS + ".instantheal", start + "tried to regenerate health faster than normal" + end); set(ConfPaths.STRINGS + ".instantheal", start + "tried to regenerate health faster than normal" + end);
set(ConfPaths.STRINGS + ".kick", "kick [player]"); set(ConfPaths.STRINGS + ".kick", "kick [player]");
set(ConfPaths.STRINGS + ".knockback", start + "tried to do a knockback but wasn't technically sprinting" + end); set(ConfPaths.STRINGS + ".knockback", start + "tried to do a knockback but wasn't technically sprinting" + end);

View File

@ -123,6 +123,20 @@ public class Permissions {
public static final String FIGHT_REACH = FIGHT + ".reach"; public static final String FIGHT_REACH = FIGHT + ".reach";
public static final String FIGHT_SPEED = FIGHT + ".speed"; public static final String FIGHT_SPEED = FIGHT + ".speed";
/*
* 888 d8
* 888 888 8e Y8b Y888P ,e e, 888 8e d88 e88 88e 888,8, Y8b Y888P
* 888 888 88b Y8b Y8P d88 88b 888 88b d88888 d888 888b 888 " Y8b Y8P
* 888 888 888 Y8b " 888 , 888 888 888 Y888 888P 888 Y8b Y
* 888 888 888 Y8P "YeeP" 888 888 888 "88 88" 888 888
* 888
* 888
*/
private static final String INVENTORY = CHECKS + ".inventory";
public static final String INVENTORY_DROP = INVENTORY + ".drop";
public static final String INVENTORY_INSTANTBOW = INVENTORY + ".instantbow";
public static final String INVENTORY_INSTANTEAT = INVENTORY + ".instanteat";
/* /*
* e e ,e, * e e ,e,
* d8b d8b e88 88e Y8b Y888P " 888 8e e88 888 * d8b d8b e88 88e Y8b Y888P " 888 8e e88 888