New check "inventory.drop", some more saveguards for checks etc. in

case of errors.
This commit is contained in:
Evenprime 2011-12-23 16:56:32 +01:00
parent dc03c84025
commit 0c506576d3
19 changed files with 382 additions and 52 deletions

View File

@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>cc.co.evenprime.bukkit</groupId>
<artifactId>NoCheat</artifactId>
<version>2.21b_heroestestbuild</version>
<version>2.21b</version>
<packaging>jar</packaging>
<name>NoCheat</name>
<properties>

View File

@ -5,15 +5,10 @@ import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Priority;
import org.bukkit.event.Event.Type;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerListener;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.java.JavaPlugin;
@ -31,6 +26,7 @@ import cc.co.evenprime.bukkit.nocheat.events.BlockPlaceEventManager;
import cc.co.evenprime.bukkit.nocheat.events.ChatEventManager;
import cc.co.evenprime.bukkit.nocheat.events.EventManagerImpl;
import cc.co.evenprime.bukkit.nocheat.events.FightEventManager;
import cc.co.evenprime.bukkit.nocheat.events.InventoryEventManager;
import cc.co.evenprime.bukkit.nocheat.events.MovingEventManager;
import cc.co.evenprime.bukkit.nocheat.events.WorkaroundsEventManager;
import cc.co.evenprime.bukkit.nocheat.log.LogLevel;
@ -107,16 +103,13 @@ public class NoCheat extends JavaPlugin {
eventManagers.add(new BlockBreakEventManager(this));
eventManagers.add(new BlockPlaceEventManager(this));
eventManagers.add(new FightEventManager(this));
eventManagers.add(new InventoryEventManager(this));
// Then set up a task to monitor server lag
if(lagMeasureTask == null) {
lagMeasureTask = new LagMeasureTask(this);
lagMeasureTask.start();
}
Bukkit.getPluginManager().registerEvent(Type.PLAYER_DROP_ITEM, new PlayerListener() { @Override public void onPlayerDropItem(PlayerDropItemEvent event) {
System.out.println("Drop");
}}, Priority.Low, this);
// Then print a list of active checks per world
ActiveCheckPrinter.printActiveChecks(this, eventManagers);

View File

@ -3,6 +3,8 @@ package cc.co.evenprime.bukkit.nocheat.checks;
import java.util.Locale;
import org.bukkit.Location;
import org.bukkit.command.CommandException;
import org.bukkit.command.CommandSender;
import cc.co.evenprime.bukkit.nocheat.NoCheat;
import cc.co.evenprime.bukkit.nocheat.NoCheatPlayer;
@ -17,9 +19,10 @@ import cc.co.evenprime.bukkit.nocheat.data.ExecutionHistory;
public abstract class Check {
private final String name;
private final String permission;
protected final NoCheat plugin;
private final String name;
private final String permission;
private static final CommandSender noCheatCommandSender = new NoCheatCommandSender();
protected final NoCheat plugin;
public Check(NoCheat plugin, String name, String permission) {
@ -68,12 +71,13 @@ public abstract class Check {
}
private final void executeConsoleCommand(ConsolecommandAction action, Check check, NoCheatPlayer player, ConfigurationCache cc) {
String command = action.getCommand(player, check);
String command = "";
try {
plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(), command);
} catch(Exception e) {
System.out.println("[NoCheat] failed to execute the command '" + command + "', please check if everything is setup correct. ");
e.printStackTrace();
command = action.getCommand(player, check);
plugin.getServer().dispatchCommand(noCheatCommandSender, command);
} catch(CommandException e) {
System.out.println("[NoCheat] failed to execute the command '" + command + "': "+e.getMessage()+", please check if everything is setup correct. ");
}
}

View File

@ -0,0 +1,24 @@
package cc.co.evenprime.bukkit.nocheat.checks;
import cc.co.evenprime.bukkit.nocheat.NoCheat;
import cc.co.evenprime.bukkit.nocheat.NoCheatPlayer;
import cc.co.evenprime.bukkit.nocheat.config.cache.CCInventory;
import cc.co.evenprime.bukkit.nocheat.data.ExecutionHistory;
import cc.co.evenprime.bukkit.nocheat.data.InventoryData;
public abstract class InventoryCheck extends Check {
public InventoryCheck(NoCheat plugin, String name, String permission) {
super(plugin, name, permission);
}
public abstract boolean check(NoCheatPlayer player, InventoryData data, CCInventory cc);
public abstract boolean isEnabled(CCInventory cc);
@Override
protected final ExecutionHistory getHistory(NoCheatPlayer player) {
return player.getData().inventory.history;
}
}

View File

@ -0,0 +1,96 @@
package cc.co.evenprime.bukkit.nocheat.checks;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.plugin.Plugin;
public class NoCheatCommandSender implements CommandSender {
@Override
public boolean isPermissionSet(String name) {
return true;
}
@Override
public boolean isPermissionSet(Permission perm) {
return true;
}
@Override
public boolean hasPermission(String name) {
return true;
}
@Override
public boolean hasPermission(Permission perm) {
return true;
}
@Override
public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) {
return null;
}
@Override
public PermissionAttachment addAttachment(Plugin plugin) {
return null;
}
@Override
public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) {
return null;
}
@Override
public PermissionAttachment addAttachment(Plugin plugin, int ticks) {
return null;
}
@Override
public void removeAttachment(PermissionAttachment attachment) {
}
@Override
public void recalculatePermissions() {
}
@Override
public Set<PermissionAttachmentInfo> getEffectivePermissions() {
return null;
}
@Override
public boolean isOp() {
return true;
}
@Override
public void setOp(boolean value) {
}
@Override
public void sendMessage(String message) {
}
@Override
public Server getServer() {
return Bukkit.getServer();
}
@Override
public String getName() {
return "NoCheatCommandSender";
}
}

View File

@ -27,15 +27,15 @@ public class SpamCheck extends ChatCheck {
}
}
final int time = plugin.getIngameSeconds();
final long time = System.currentTimeMillis() / 1000;
if(data.spamLasttime + cc.spamTimeframe <= time) {
data.spamLasttime = time;
if(data.spamLastTime + cc.spamTimeframe <= time) {
data.spamLastTime = time;
data.messageCount = 0;
}
// Security check, if the system time changes
else if(data.spamLasttime > time) {
data.spamLasttime = Integer.MIN_VALUE;
else if(data.spamLastTime > time) {
data.spamLastTime = Integer.MIN_VALUE;
}
data.messageCount++;

View File

@ -0,0 +1,62 @@
package cc.co.evenprime.bukkit.nocheat.checks.inventory;
import java.util.Locale;
import cc.co.evenprime.bukkit.nocheat.NoCheat;
import cc.co.evenprime.bukkit.nocheat.NoCheatPlayer;
import cc.co.evenprime.bukkit.nocheat.actions.types.ParameterName;
import cc.co.evenprime.bukkit.nocheat.checks.InventoryCheck;
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
import cc.co.evenprime.bukkit.nocheat.config.cache.CCInventory;
import cc.co.evenprime.bukkit.nocheat.data.InventoryData;
public class DropCheck extends InventoryCheck {
public DropCheck(NoCheat plugin) {
super(plugin, "inventory.drop", Permissions.INVENTORY_DROP);
}
@Override
public boolean check(NoCheatPlayer player, InventoryData data, CCInventory cc) {
boolean cancel = false;
final long time = System.currentTimeMillis() / 1000;
if(data.dropLastTime + cc.dropTimeFrame <= time) {
data.dropLastTime = time;
data.dropCount = 0;
}
// Security check, if the system time changes
else if(data.dropLastTime > time) {
data.dropLastTime = Integer.MIN_VALUE;
}
data.dropCount++;
if(data.dropCount > cc.dropLimit) {
data.dropVL = data.dropCount - cc.dropLimit;
data.dropTotalVL++;
data.dropFailed++;
cancel = executeActions(player, cc.dropActions.getActions(data.dropVL));
}
return cancel;
}
@Override
public boolean isEnabled(CCInventory cc) {
// TODO Auto-generated method stub
return cc.dropCheck;
}
public String getParameter(ParameterName wildcard, NoCheatPlayer player) {
if(wildcard == ParameterName.VIOLATIONS)
return String.format(Locale.US, "%d", player.getData().inventory.dropVL);
else
return super.getParameter(wildcard, player);
}
}

View File

@ -32,8 +32,15 @@ public abstract class Configuration {
public final static OptionNode DEBUG_SHOWACTIVECHECKS = new OptionNode("showactivechecks", DEBUG, DataType.BOOLEAN);
public final static OptionNode DEBUG_COMPATIBILITY = new OptionNode("compatibility", DEBUG, DataType.BOOLEAN);
public final static OptionNode INVENTORY = new OptionNode("inventory", ROOT, DataType.PARENT);
public final static OptionNode INVENTORY_CLOSEOBEFORETELEPORTS = new OptionNode("closebeforeteleports", INVENTORY, DataType.BOOLEAN);
private final static OptionNode INVENTORY = new OptionNode("inventory", ROOT, DataType.PARENT);
public final static OptionNode INVENTORY_PREVENTITEMDUPE = new OptionNode("preventitemdupe", INVENTORY, DataType.BOOLEAN);
public static final OptionNode INVENTORY_CHECK = new OptionNode("check", INVENTORY, DataType.BOOLEAN);
private final static OptionNode INVENTORY_DROP = new OptionNode("drop", INVENTORY, DataType.PARENT);
public final static OptionNode INVENTORY_DROP_CHECK = new OptionNode("check", INVENTORY_DROP, DataType.BOOLEAN);
public final static OptionNode INVENTORY_DROP_TIMEFRAME = new OptionNode("timeframe", INVENTORY_DROP, DataType.INTEGER);
public final static OptionNode INVENTORY_DROP_LIMIT = new OptionNode("limit", INVENTORY_DROP, DataType.INTEGER);
public final static OptionNode INVENTORY_DROP_ACTIONS = new OptionNode("actions", INVENTORY_DROP, DataType.ACTIONLIST);
private final static OptionNode MOVING = new OptionNode("moving", ROOT, DataType.PARENT);
public final static OptionNode MOVING_CHECK = new OptionNode("check", MOVING, DataType.BOOLEAN);
@ -56,7 +63,7 @@ public abstract class Configuration {
public final static OptionNode MOVING_RUNFLY_ALLOWLIMITEDFLYING = new OptionNode("allowlimitedflying", MOVING_RUNFLY, DataType.BOOLEAN);
public final static OptionNode MOVING_RUNFLY_FLYINGSPEEDLIMITVERTICAL = new OptionNode("flyingspeedlimitvertical", MOVING_RUNFLY, DataType.INTEGER);
public final static OptionNode MOVING_RUNFLY_FLYINGSPEEDLIMITHORIZONTAL = new OptionNode("flyingspeedlimithorizontal", MOVING_RUNFLY, DataType.INTEGER);
public final static OptionNode MOVING_RUNFLY_FLYINGHEIGHTLIMIT = new OptionNode("flyingheightlimit", MOVING_RUNFLY, DataType.INTEGER);
public final static OptionNode MOVING_RUNFLY_FLYINGHEIGHTLIMIT = new OptionNode("flyingheightlimit", MOVING_RUNFLY, DataType.INTEGER);
public final static OptionNode MOVING_RUNFLY_FLYINGACTIONS = new OptionNode("flyingactions", MOVING_RUNFLY, DataType.ACTIONLIST);
private final static OptionNode MOVING_MOREPACKETS = new OptionNode("morepackets", MOVING, DataType.PARENT);

View File

@ -37,7 +37,17 @@ public class DefaultConfiguration extends Configuration {
/*** INVENTORY ***/
{
setValue(INVENTORY_CLOSEOBEFORETELEPORTS, true);
setValue(INVENTORY_CHECK, true);
setValue(INVENTORY_PREVENTITEMDUPE, true);
setValue(INVENTORY_DROP_CHECK, true);
setValue(INVENTORY_DROP_TIMEFRAME, 20);
setValue(INVENTORY_DROP_LIMIT, 100);
ActionList dropActionList = new ActionList();
dropActionList.setActions(0, action.getActions("dropLog dropCancel".split(" ")));
dropActionList.setActions(500, action.getActions("dropLog dropCancel dropkick".split(" ")));
setValue(INVENTORY_DROP_ACTIONS, dropActionList);
}
/*** MOVING ***/
@ -263,6 +273,7 @@ public class DefaultConfiguration extends Configuration {
w(w, "log nofallLog 0 5 med [player] failed [check]: tried to avoid fall damage for ~[falldistance] blocks. VL [violations]");
w(w, "log noswingLog 2 5 med [player] failed [check]: Didn't swing arm. VL [violations]");
w(w, "log emptyChatLog 0 5 med [player] failed [check]: Sent empty chat message. VL [violations]");
w(w, "log dropLog 0 5 med [player] failed [check]: Tried to drop more items than allowed. VL [violations]");
w(w, "");
w(w, "");
w(w, "# Some log messages related to fighting, displaying the same text, but with different level (Info, Warning, Severe)");
@ -287,6 +298,7 @@ public class DefaultConfiguration extends Configuration {
w(w, "special chatCancel 0 0");
w(w, "special nofallDamage 0 0");
w(w, "special fightCancel 0 0");
w(w, "special dropCancel 0 0");
w(w, "");
w(w, "# CONSOLECOMMAND Actions: They will execute a command as if it were typed into the console.");
w(w, "# - They start with the word 'consolecommand'");
@ -299,6 +311,7 @@ public class DefaultConfiguration extends Configuration {
w(w, "consolecommand kick 0 1 kick [player]");
w(w, "consolecommand spamkick 0 1 kick [player]");
w(w, "consolecommand emptyChatKick 0 1 kick [player]");
w(w, "consolecommand dropKick 0 1 kick [player]");
w.flush();
w.close();
} catch(IOException e) {

View File

@ -27,7 +27,12 @@ public class Explainations {
set(Configuration.DEBUG_SHOWACTIVECHECKS, "Print to the console an overview of all checks that are enabled when NoCheat gets loaded.");
set(Configuration.DEBUG_COMPATIBILITY, "Do some voodoo to fix common mistakes of other plugins which interfere with NoCheat.");
set(Configuration.INVENTORY_CLOSEOBEFORETELEPORTS, "Close inventory screens of players before they get teleported, preventing creation of real or fake duplicates.");
set(Configuration.INVENTORY_PREVENTITEMDUPE, "Close inventories of players before they get teleported between worlds, preventing creation of duplicate items.");
set(Configuration.INVENTORY_CHECK, "If true, do various checks on Inventory related things.");
set(Configuration.INVENTORY_DROP_CHECK, "If true, prevent players from dropping too many items in a short timeframe to reduce lag");
set(Configuration.INVENTORY_DROP_TIMEFRAME , "Over how many seconds should item drops be counted.");
set(Configuration.INVENTORY_DROP_LIMIT, "How many seperate items should the player be allowed to drop during that timeframe");
set(Configuration.INVENTORY_DROP_ACTIONS, "What should be done if a player drops more items than that.\nUnit is item drops above the limit.");
set(Configuration.MOVING_CHECK, "If true, do various checks on PlayerMove events.");
set(Configuration.MOVING_IDENTIFYCREATIVEMODE, "If true, NoCheat will automatically identify if players are in creative mode and will allow them to fly, avoid fall damage etc.");

View File

@ -45,5 +45,8 @@ public class Permissions {
public static final String ADMIN_PERFORMANCE = ADMIN + ".performance";
public static final String ADMIN_PLAYERINFO = ADMIN + ".playerinfo";
public static final String INVENTORY = CHECKS + ".inventory";
public static final String INVENTORY_DROP = INVENTORY + ".drop";
private Permissions() {}
}

View File

@ -1,14 +1,25 @@
package cc.co.evenprime.bukkit.nocheat.config.cache;
import cc.co.evenprime.bukkit.nocheat.config.Configuration;
import cc.co.evenprime.bukkit.nocheat.config.util.ActionList;
public class CCInventory {
public final boolean closebeforeteleports;
public final boolean check;
public final boolean dropCheck;
public final long dropTimeFrame;
public final int dropLimit;
public final ActionList dropActions;
public CCInventory(Configuration data) {
closebeforeteleports = data.getBoolean(Configuration.INVENTORY_CLOSEOBEFORETELEPORTS);
check = data.getBoolean(Configuration.INVENTORY_CHECK);
dropCheck = data.getBoolean(Configuration.INVENTORY_DROP_CHECK);
dropTimeFrame = data.getInteger(Configuration.INVENTORY_DROP_TIMEFRAME);
dropLimit = data.getInteger(Configuration.INVENTORY_DROP_LIMIT);
dropActions = data.getActionList(Configuration.INVENTORY_DROP_ACTIONS);
closebeforeteleports = data.getBoolean(Configuration.INVENTORY_PREVENTITEMDUPE);
}
}

View File

@ -9,6 +9,7 @@ public class BaseData extends Data {
public final ChatData chat;
public final MovingData moving;
public final FightData fight;
public final InventoryData inventory;
private final Data[] data; // for convenience
@ -20,10 +21,11 @@ public class BaseData extends Data {
this.chat = new ChatData();
this.moving = new MovingData();
this.fight = new FightData();
this.inventory = new InventoryData();
data = new Data[] {this.blockbreak, this.blockplace, this.chat,
this.moving, this.fight};
this.moving, this.fight, this.inventory};
this.timestamp = System.currentTimeMillis();
}
@ -38,7 +40,7 @@ public class BaseData extends Data {
for(Data d : data) {
d.collectData(map);
}
map.put("nocheat.starttime", timestamp);
map.put("nocheat.endtime", System.currentTimeMillis());
}

View File

@ -15,7 +15,7 @@ public class ChatData extends Data {
public int emptyFailed;
public int messageCount = 0;
public int spamLasttime = 0;
public long spamLastTime = 0;
public final ExecutionHistory history = new ExecutionHistory();
public String message = "";

View File

@ -0,0 +1,19 @@
package cc.co.evenprime.bukkit.nocheat.data;
import java.util.Map;
public class InventoryData extends Data {
public double dropVL = 0.0D;
public double dropTotalVL = 0.0D;
public int dropFailed = 0;
public long dropLastTime;
public int dropCount;
public final ExecutionHistory history = new ExecutionHistory();
@Override
public void collectData(Map<String, Object> map) {
map.put("inventory.drop.vl", (int) dropTotalVL);
map.put("inventory.drop.failed", (int) dropFailed);
}
}

View File

@ -23,24 +23,29 @@ public class LagMeasureTask implements Runnable {
public void run() {
// If the previous second took to long, skip checks during
// this second
skipCheck = lastIngamesecondDuration > 1500;
long time = System.currentTimeMillis();
lastIngamesecondDuration = time - lastIngamesecondTime;
if(lastIngamesecondDuration < 1000)
lastIngamesecondDuration = 1000;
else if(lastIngamesecondDuration > 3600000) {
lastIngamesecondDuration = 3600000; // top limit of 1
// hour per "second"
try {
// If the previous second took to long, skip checks during
// this second
skipCheck = lastIngamesecondDuration > 1500;
long time = System.currentTimeMillis();
lastIngamesecondDuration = time - lastIngamesecondTime;
if(lastIngamesecondDuration < 1000)
lastIngamesecondDuration = 1000;
else if(lastIngamesecondDuration > 3600000) {
lastIngamesecondDuration = 3600000; // top limit of 1
// hour per "second"
}
lastIngamesecondTime = time;
ingameseconds++;
// Check if some data is outdated now and let it be removed
if(ingameseconds % 62 == 0) {
plugin.cleanDataMap();
}
}
lastIngamesecondTime = time;
ingameseconds++;
// Check if some data is outdated now and let it be removed
if(ingameseconds % 62 == 0) {
plugin.cleanDataMap();
catch(Exception e) {
// Just prevent this thread from dying for whatever reason
}
}

View File

@ -6,7 +6,7 @@ import java.util.Map;
public class PerformanceManager {
public enum EventType {
BLOCKBREAK, BLOCKDAMAGE, BLOCKPLACE, CHAT, MOVING, VELOCITY, FIGHT, TIMED
BLOCKBREAK, BLOCKDAMAGE, BLOCKPLACE, CHAT, MOVING, VELOCITY, FIGHT, INVENTORY
}
private final Map<EventType, Performance> map;

View File

@ -20,6 +20,7 @@ import org.bukkit.event.entity.EntityListener;
import org.bukkit.event.player.PlayerAnimationEvent;
import org.bukkit.event.player.PlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerListener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerPortalEvent;
@ -156,6 +157,20 @@ public abstract class EventManagerImpl implements EventManager {
m.handlePlayerMoveEvent(event, priority);
}
}
@Override
public void onPlayerDropItem(final PlayerDropItemEvent event) {
if(ignoreCancelledEvents && event.isCancelled())
return;
if(measureTime != null && measureTime.isEnabled()) {
final long startTime = System.nanoTime();
m.handlePlayerDropItemEvent(event, priority);
measureTime.addTime(System.nanoTime() - startTime);
} else {
m.handlePlayerDropItemEvent(event, priority);
}
}
@Override
public void onPlayerVelocity(final PlayerVelocityEvent event) {
@ -438,4 +453,8 @@ public abstract class EventManagerImpl implements EventManager {
protected void handleCustomDamageByPlayerEvent(EntityDamageByEntityEvent event, Priority priority) {
handleEvent(event, priority);
}
protected void handlePlayerDropItemEvent(PlayerDropItemEvent event, Priority priority) {
handleEvent(event, priority);
}
}

View File

@ -0,0 +1,67 @@
package cc.co.evenprime.bukkit.nocheat.events;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.bukkit.event.Event;
import org.bukkit.event.Event.Priority;
import org.bukkit.event.player.PlayerDropItemEvent;
import cc.co.evenprime.bukkit.nocheat.NoCheat;
import cc.co.evenprime.bukkit.nocheat.NoCheatPlayer;
import cc.co.evenprime.bukkit.nocheat.checks.InventoryCheck;
import cc.co.evenprime.bukkit.nocheat.checks.inventory.DropCheck;
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
import cc.co.evenprime.bukkit.nocheat.config.cache.CCInventory;
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
import cc.co.evenprime.bukkit.nocheat.data.InventoryData;
import cc.co.evenprime.bukkit.nocheat.debug.PerformanceManager.EventType;
public class InventoryEventManager extends EventManagerImpl {
private final List<InventoryCheck> checks;
public InventoryEventManager(NoCheat plugin) {
super(plugin);
this.checks = new ArrayList<InventoryCheck>(1);
this.checks.add(new DropCheck(plugin));
registerListener(Event.Type.PLAYER_DROP_ITEM, Priority.Lowest, true, plugin.getPerformance(EventType.INVENTORY));
}
@Override
protected void handlePlayerDropItemEvent(final PlayerDropItemEvent event, final Priority priority) {
final NoCheatPlayer player = plugin.getPlayer(event.getPlayer());
final CCInventory cc = player.getConfiguration().inventory;
if(!cc.check || player.hasPermission(Permissions.INVENTORY)) {
return;
}
final InventoryData data = player.getData().inventory;
boolean cancelled = false;
for(InventoryCheck check : checks) {
// If it should be executed, do it
if(!cancelled && check.isEnabled(cc) && !player.hasPermission(check.getPermission())) {
cancelled = check.check(player, data, cc);
}
}
if(cancelled)
event.setCancelled(cancelled);
}
public List<String> getActiveChecks(ConfigurationCache cc) {
LinkedList<String> s = new LinkedList<String>();
if(cc.inventory.check && cc.inventory.dropCheck)
s.add("inventory.dropCheck");
return s;
}
}