2012-04-26 23:36:43 +02:00
package fr.neatmonster.nocheatplus ;
2012-04-05 18:24:39 +02:00
2013-01-20 04:18:08 +01:00
import java.io.File ;
2012-04-05 18:24:39 +02:00
import java.util.ArrayList ;
2012-11-07 05:30:21 +01:00
import java.util.Arrays ;
2012-09-10 10:10:45 +02:00
import java.util.Collections ;
import java.util.HashMap ;
2013-02-26 01:58:21 +01:00
import java.util.HashSet ;
2013-01-25 23:51:29 +01:00
import java.util.LinkedHashSet ;
2012-09-04 06:48:21 +02:00
import java.util.LinkedList ;
2012-04-05 18:24:39 +02:00
import java.util.List ;
2012-09-10 10:10:45 +02:00
import java.util.Map ;
import java.util.Map.Entry ;
2012-11-09 14:29:51 +01:00
import java.util.Set ;
2012-04-05 18:24:39 +02:00
import org.bukkit.Bukkit ;
2012-08-21 02:49:14 +02:00
import org.bukkit.ChatColor ;
2013-02-26 01:58:21 +01:00
import org.bukkit.command.CommandSender ;
2012-11-07 05:30:21 +01:00
import org.bukkit.command.PluginCommand ;
2012-04-05 18:24:39 +02:00
import org.bukkit.entity.Player ;
import org.bukkit.event.EventHandler ;
import org.bukkit.event.EventPriority ;
import org.bukkit.event.Listener ;
2012-11-09 14:29:51 +01:00
import org.bukkit.event.player.PlayerChangedWorldEvent ;
2012-04-05 18:24:39 +02:00
import org.bukkit.event.player.PlayerJoinEvent ;
2012-11-09 14:29:51 +01:00
import org.bukkit.event.player.PlayerKickEvent ;
2012-09-10 10:10:45 +02:00
import org.bukkit.event.player.PlayerLoginEvent ;
import org.bukkit.event.player.PlayerLoginEvent.Result ;
2012-11-09 14:29:51 +01:00
import org.bukkit.event.player.PlayerQuitEvent ;
2013-02-26 01:58:21 +01:00
import org.bukkit.permissions.Permissible ;
2012-04-05 18:24:39 +02:00
import org.bukkit.plugin.PluginDescriptionFile ;
import org.bukkit.plugin.java.JavaPlugin ;
2013-02-27 18:00:44 +01:00
import org.bukkit.scheduler.BukkitScheduler ;
2012-04-05 18:24:39 +02:00
2012-08-20 19:40:00 +02:00
import fr.neatmonster.nocheatplus.checks.CheckType ;
2012-04-26 23:36:43 +02:00
import fr.neatmonster.nocheatplus.checks.blockbreak.BlockBreakListener ;
2012-08-06 02:43:01 +02:00
import fr.neatmonster.nocheatplus.checks.blockinteract.BlockInteractListener ;
2012-04-26 23:36:43 +02:00
import fr.neatmonster.nocheatplus.checks.blockplace.BlockPlaceListener ;
import fr.neatmonster.nocheatplus.checks.chat.ChatListener ;
2012-09-10 08:52:27 +02:00
import fr.neatmonster.nocheatplus.checks.combined.CombinedListener ;
2012-08-05 13:09:57 +02:00
import fr.neatmonster.nocheatplus.checks.fight.FightListener ;
2012-08-05 20:00:05 +02:00
import fr.neatmonster.nocheatplus.checks.inventory.InventoryListener ;
2012-04-26 23:36:43 +02:00
import fr.neatmonster.nocheatplus.checks.moving.MovingListener ;
2013-01-18 22:37:23 +01:00
import fr.neatmonster.nocheatplus.clients.ModUtil ;
2012-08-29 06:50:26 +02:00
import fr.neatmonster.nocheatplus.command.CommandHandler ;
2012-09-04 06:48:21 +02:00
import fr.neatmonster.nocheatplus.command.INotifyReload ;
2012-12-06 22:16:07 +01:00
import fr.neatmonster.nocheatplus.compat.MCAccess ;
import fr.neatmonster.nocheatplus.compat.MCAccessFactory ;
2012-11-08 10:58:43 +01:00
import fr.neatmonster.nocheatplus.components.ComponentWithName ;
2013-02-27 18:00:44 +01:00
import fr.neatmonster.nocheatplus.components.ConsistencyChecker ;
2012-11-02 10:40:37 +01:00
import fr.neatmonster.nocheatplus.components.INeedConfig ;
2013-01-30 04:22:06 +01:00
import fr.neatmonster.nocheatplus.components.MCAccessHolder ;
2012-11-12 09:04:43 +01:00
import fr.neatmonster.nocheatplus.components.NCPListener ;
2012-11-09 14:29:51 +01:00
import fr.neatmonster.nocheatplus.components.NameSetPermState ;
2012-11-02 10:40:37 +01:00
import fr.neatmonster.nocheatplus.components.NoCheatPlusAPI ;
2012-11-09 14:29:51 +01:00
import fr.neatmonster.nocheatplus.components.PermStateReceiver ;
2013-01-14 04:23:39 +01:00
import fr.neatmonster.nocheatplus.components.TickListener ;
2012-04-26 23:36:43 +02:00
import fr.neatmonster.nocheatplus.config.ConfPaths ;
2012-08-24 14:52:24 +02:00
import fr.neatmonster.nocheatplus.config.ConfigFile ;
2012-04-26 23:36:43 +02:00
import fr.neatmonster.nocheatplus.config.ConfigManager ;
2012-10-12 02:46:02 +02:00
import fr.neatmonster.nocheatplus.config.DefaultConfig ;
2012-11-08 10:43:44 +01:00
import fr.neatmonster.nocheatplus.event.IHaveMethodOrder ;
2012-11-07 12:56:25 +01:00
import fr.neatmonster.nocheatplus.event.ListenerManager ;
2012-09-16 20:34:01 +02:00
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager ;
2013-01-20 04:18:08 +01:00
import fr.neatmonster.nocheatplus.logging.LogUtil ;
import fr.neatmonster.nocheatplus.logging.StaticLogFile ;
2012-08-20 19:40:00 +02:00
import fr.neatmonster.nocheatplus.metrics.Metrics ;
import fr.neatmonster.nocheatplus.metrics.Metrics.Graph ;
import fr.neatmonster.nocheatplus.metrics.Metrics.Plotter ;
2013-01-17 01:47:07 +01:00
import fr.neatmonster.nocheatplus.metrics.MetricsData ;
2012-11-07 05:30:21 +01:00
import fr.neatmonster.nocheatplus.permissions.PermissionUtil ;
import fr.neatmonster.nocheatplus.permissions.PermissionUtil.CommandProtectionEntry ;
2012-11-06 10:11:17 +01:00
import fr.neatmonster.nocheatplus.permissions.Permissions ;
2012-09-20 20:16:00 +02:00
import fr.neatmonster.nocheatplus.players.DataManager ;
2012-09-15 10:09:45 +02:00
import fr.neatmonster.nocheatplus.utilities.BlockProperties ;
2012-09-08 20:16:10 +02:00
import fr.neatmonster.nocheatplus.utilities.TickTask ;
2012-09-25 22:08:22 +02:00
import fr.neatmonster.nocheatplus.utilities.Updates ;
2012-04-05 18:24:39 +02:00
2012-08-03 16:48:06 +02:00
/ *
* M " " " " " " " `YM MM' " " " " 'YMM dP dP MM " " " " " " " ` YM dP
* M mmmm . M M ' . mmm . ` M 88 88 MM mmmmm M 88
* M MMMMM M . d8888b . M MMMMMooM 88d888b . . d8888b . . d8888b . d8888P M ' . M 88 dP dP . d8888b .
* M MMMMM M 88 ' ` 88 M MMMMMMMM 88 ' ` 88 88ooood8 88 ' ` 88 88 MM MMMMMMMM 88 88 88 Y8ooooo .
* M MMMMM M 88 . . 88 M . ` MMM ' . M 88 88 88 . . . . 88 . . 88 88 MM MMMMMMMM 88 88 . . 88 88
* M MMMMM M ` 88888P ' MM . . dM dP dP ` 88888P ' ` 88888P8 dP MM MMMMMMMM dP ` 88888P ' ` 88888P '
* MMMMMMMMMMM MMMMMMMMMMM MMMMMMMMMMMM
* /
/ * *
* This is the main class of NoCheatPlus . The commands , events listeners and tasks are registered here .
* /
2012-11-09 14:29:51 +01:00
public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
2012-09-10 10:10:45 +02:00
/** Lower case player name to milliseconds point of time of release */
private static final Map < String , Long > denyLoginNames = Collections . synchronizedMap ( new HashMap < String , Long > ( ) ) ;
2012-11-09 14:29:51 +01:00
/** Names of players with a certain permission. */
protected static final NameSetPermState nameSetPerms = new NameSetPermState ( Permissions . ADMINISTRATION_NOTIFY ) ;
2012-12-06 22:16:07 +01:00
/** MCAccess instance. */
protected static MCAccess mcAccess = null ;
/ * *
* Get the wrapper for accessing Minecraft properties .
* @return
* /
public static MCAccess getMCAccess ( ) {
if ( mcAccess = = null ) initMCAccess ( ) ;
return mcAccess ;
}
private static void initMCAccess ( ) {
synchronized ( NoCheatPlus . class ) {
if ( mcAccess ! = null ) return ;
mcAccess = new MCAccessFactory ( ) . getMCAccess ( ) ;
}
LogUtil . logInfo ( " [NoCheatPlus] McAccess set to: " + mcAccess . getMCVersion ( ) + " / " + mcAccess . getServerVersionTag ( ) ) ;
}
2012-09-10 10:10:45 +02:00
/ * *
* Remove expired entries .
* /
private static void checkDenyLoginsNames ( ) {
final long ts = System . currentTimeMillis ( ) ;
final List < String > rem = new LinkedList < String > ( ) ;
synchronized ( denyLoginNames ) {
for ( final Entry < String , Long > entry : denyLoginNames . entrySet ( ) ) {
if ( entry . getValue ( ) . longValue ( ) < ts ) rem . add ( entry . getKey ( ) ) ;
}
for ( final String name : rem ) {
denyLoginNames . remove ( name ) ;
}
}
}
2012-09-15 18:16:32 +02:00
/ * *
* Allow login ( remove from deny login map ) .
* @param playerName
* @return If player was denied to login .
* /
public static boolean allowLogin ( String playerName ) {
playerName = playerName . trim ( ) . toLowerCase ( ) ;
final Long time = denyLoginNames . remove ( playerName ) ;
if ( time = = null ) return false ;
return System . currentTimeMillis ( ) < = time ;
}
2012-09-10 10:10:45 +02:00
/ * *
* Deny the player to login . This will also remove expired entries .
* @param playerName
* @param duration Duration from now on , in milliseconds .
* /
public static void denyLogin ( String playerName , long duration ) {
final long ts = System . currentTimeMillis ( ) + duration ;
playerName = playerName . trim ( ) . toLowerCase ( ) ;
synchronized ( denyLoginNames ) {
final Long oldTs = denyLoginNames . get ( playerName ) ;
if ( oldTs ! = null & & ts < oldTs . longValue ( ) ) return ;
denyLoginNames . put ( playerName , ts ) ;
// TODO: later maybe save these ?
}
checkDenyLoginsNames ( ) ;
}
/ * *
* Check if player is denied to login right now .
* @param playerName
* @return
* /
public static boolean isLoginDenied ( String playerName ) {
return isLoginDenied ( playerName , System . currentTimeMillis ( ) ) ;
}
2012-09-15 18:16:32 +02:00
2012-11-02 10:40:37 +01:00
public static String [ ] getLoginDeniedPlayers ( ) {
2012-09-15 18:16:32 +02:00
checkDenyLoginsNames ( ) ;
String [ ] kicked = new String [ denyLoginNames . size ( ) ] ;
denyLoginNames . keySet ( ) . toArray ( kicked ) ;
return kicked ;
}
2012-09-10 10:10:45 +02:00
/ * *
* Check if a player is denied to login at a certain point of time .
* @param playerName
* @param currentTimeMillis
* @return
* /
2012-10-01 03:19:34 +02:00
public static boolean isLoginDenied ( String playerName , long time ) {
2012-09-10 10:10:45 +02:00
playerName = playerName . trim ( ) . toLowerCase ( ) ;
final Long oldTs = denyLoginNames . get ( playerName ) ;
if ( oldTs = = null ) return false ;
2012-10-01 03:19:34 +02:00
else return time < oldTs . longValue ( ) ;
2012-09-10 10:10:45 +02:00
}
2012-11-02 10:40:37 +01:00
/ * *
* Convenience method , delegates to
* @return
* /
public static NoCheatPlusAPI getAPI ( ) {
return ( NoCheatPlusAPI ) Bukkit . getPluginManager ( ) . getPlugin ( " NoCheatPlus " ) ;
}
2012-11-09 14:29:51 +01:00
/ * *
2013-02-26 01:58:21 +01:00
* Send all players with the nocheatplus . admin . notify permission a message . < br >
* This will act according to configuration ( stored permissions or permission subscriptions ) .
2012-11-09 14:29:51 +01:00
*
* @param message
* @return Number of players messaged .
* /
public static int sendAdminNotifyMessage ( final String message ) {
2013-02-26 01:58:21 +01:00
if ( ConfigManager . getConfigFile ( ) . getBoolean ( ConfPaths . LOGGING_USESUBSCRIPTIONS ) ) {
// TODO: Might respect console settings, or add extra config section (e.g. notifications).
return sendAdminNotifyMessageSubscriptions ( message ) ;
}
else {
return sendAdminNotifyMessageStored ( message ) ;
}
}
/ * *
* Send notification to players with stored notify - permission ( world changes , login , permissions are not re - checked here ) .
* @param message
* @return
* /
public static int sendAdminNotifyMessageStored ( final String message ) {
2012-11-09 14:29:51 +01:00
final Set < String > names = nameSetPerms . getPlayers ( Permissions . ADMINISTRATION_NOTIFY ) ;
if ( names = = null ) return 0 ;
int done = 0 ;
for ( final String name : names ) {
2013-02-26 00:39:48 +01:00
final Player player = DataManager . getPlayerExact ( name ) ;
2012-11-09 14:29:51 +01:00
if ( player ! = null ) {
player . sendMessage ( message ) ;
done + + ;
}
}
return done ;
2013-02-26 01:58:21 +01:00
}
/ * *
* Send notification to all CommandSenders found in permission subscriptions for the notify - permission as well as players that have stored permissions ( those get re - checked here ) .
* @param message
* @return
* /
public static int sendAdminNotifyMessageSubscriptions ( final String message ) {
final Set < Permissible > permissibles = Bukkit . getPluginManager ( ) . getPermissionSubscriptions ( Permissions . ADMINISTRATION_NOTIFY ) ;
final Set < String > names = nameSetPerms . getPlayers ( Permissions . ADMINISTRATION_NOTIFY ) ;
final Set < String > done = new HashSet < String > ( permissibles . size ( ) + ( names = = null ? 0 : names . size ( ) ) ) ;
for ( final Permissible permissible : permissibles ) {
if ( permissible instanceof CommandSender & & permissible . hasPermission ( Permissions . ADMINISTRATION_NOTIFY ) ) {
final CommandSender sender = ( CommandSender ) permissible ;
sender . sendMessage ( message ) ;
done . add ( sender . getName ( ) ) ;
}
}
// Fall-back checking for players.
if ( names ! = null ) {
for ( final String name : names ) {
if ( ! done . contains ( name ) ) {
final Player player = DataManager . getPlayerExact ( name ) ;
if ( player ! = null & & player . hasPermission ( Permissions . ADMINISTRATION_NOTIFY ) ) {
player . sendMessage ( message ) ;
done . add ( name ) ;
}
}
}
}
return done . size ( ) ;
2012-11-09 14:29:51 +01:00
}
2012-09-10 10:10:45 +02:00
2012-08-22 02:41:28 +02:00
/** Is the configuration outdated? */
private boolean configOutdated = false ;
2012-08-21 02:49:14 +02:00
2012-08-22 02:41:28 +02:00
/** Is a new update available? */
private boolean updateAvailable = false ;
2012-09-04 06:48:21 +02:00
2012-09-20 20:16:00 +02:00
/** Player data future stuff. */
protected final DataManager dataMan = new DataManager ( ) ;
2013-02-27 18:00:44 +01:00
private int dataManTaskId = - 1 ;
protected Metrics metrics = null ;
2012-11-07 05:30:21 +01:00
/ * *
* Commands that were changed for protecting them against tab complete or
* use .
* /
2012-11-07 08:16:01 +01:00
protected List < CommandProtectionEntry > changedCommands = null ;
2012-11-07 12:56:25 +01:00
2012-11-08 10:43:44 +01:00
private final ListenerManager listenerManager = new ListenerManager ( this , false ) ;
private boolean manageListeners = true ;
2012-11-09 14:29:51 +01:00
2013-02-27 18:00:44 +01:00
/** The event listeners. */
private final List < Listener > listeners = new ArrayList < Listener > ( ) ;
/ * * Components that need notification on reloading .
* ( Kept here , for if during runtime some might get added . ) * /
private final List < INotifyReload > notifyReload = new LinkedList < INotifyReload > ( ) ;
/** Permission states stored on a per-world basis, updated with join/quit/kick. */
2012-11-09 14:29:51 +01:00
protected final List < PermStateReceiver > permStateReceivers = new ArrayList < PermStateReceiver > ( ) ;
2013-01-25 23:51:29 +01:00
2013-02-27 18:00:44 +01:00
/** Components that check consistency. */
protected final List < ConsistencyChecker > consistencyCheckers = new ArrayList < ConsistencyChecker > ( ) ;
/** Index at which to continue. */
protected int consistencyCheckerIndex = 0 ;
protected int consistencyCheckerTaskId = - 1 ;
2013-01-25 23:51:29 +01:00
/** All registered components. */
protected Set < Object > allComponents = new LinkedHashSet < Object > ( 50 ) ;
2012-11-08 10:43:44 +01:00
2012-12-02 17:39:50 +01:00
2012-11-02 10:40:37 +01:00
@Override
2013-01-30 04:22:06 +01:00
public boolean addComponent ( final Object obj ) {
2013-03-01 18:54:48 +01:00
// TODO: Allow to add ComponentFactory + contract (renew with reload etc.)?
2013-01-30 04:22:06 +01:00
if ( allComponents . contains ( obj ) ) return false ;
boolean added = false ;
2012-11-02 10:40:37 +01:00
if ( obj instanceof Listener ) {
2012-11-08 10:43:44 +01:00
addListener ( ( Listener ) obj ) ;
2013-01-30 04:22:06 +01:00
added = true ;
2012-11-02 10:40:37 +01:00
}
if ( obj instanceof INotifyReload ) {
notifyReload . add ( ( INotifyReload ) obj ) ;
if ( obj instanceof INeedConfig ) {
( ( INeedConfig ) obj ) . onReload ( ) ;
}
2013-01-30 04:22:06 +01:00
added = true ;
2012-11-02 10:40:37 +01:00
}
2013-01-14 04:23:39 +01:00
if ( obj instanceof TickListener ) {
TickTask . addTickListener ( ( TickListener ) obj ) ;
2013-01-30 04:22:06 +01:00
added = true ;
2013-01-14 04:23:39 +01:00
}
2012-11-09 14:29:51 +01:00
if ( obj instanceof PermStateReceiver ) {
// No immediate update done.
permStateReceivers . add ( ( PermStateReceiver ) obj ) ;
2013-01-30 04:22:06 +01:00
added = true ;
}
if ( obj instanceof MCAccessHolder ) {
2013-02-27 18:00:44 +01:00
// These will get notified in initMcAccess (iterates over allComponents).
2013-01-30 04:22:06 +01:00
( ( MCAccessHolder ) obj ) . setMCAccess ( getMCAccess ( ) ) ;
added = true ;
2012-11-09 14:29:51 +01:00
}
2013-02-27 18:00:44 +01:00
if ( obj instanceof ConsistencyChecker ) {
consistencyCheckers . add ( ( ConsistencyChecker ) obj ) ;
added = true ;
}
2013-01-14 04:23:39 +01:00
// Also add to DataManager, which will pick what it needs.
// TODO: This is fishy in principle, something more concise?
2013-01-30 04:22:06 +01:00
if ( dataMan . addComponent ( obj ) ) added = true ;
2013-02-27 18:00:44 +01:00
// Add to allComponents if in fact added.
2013-01-30 04:22:06 +01:00
if ( added ) allComponents . add ( obj ) ;
return added ;
2012-11-02 10:40:37 +01:00
}
2012-11-08 10:58:43 +01:00
/ * *
* Interfaces checked for managed listeners : IHaveMethodOrder ( method ) , ComponentWithName ( tag ) < br >
* @param listener
* /
2012-11-09 14:29:51 +01:00
protected void addListener ( final Listener listener ) {
2012-11-08 10:43:44 +01:00
if ( manageListeners ) {
2012-11-08 10:58:43 +01:00
String tag = " NoCheatPlus " ;
if ( listener instanceof ComponentWithName ) {
tag = ( ( ComponentWithName ) listener ) . getComponentName ( ) ;
}
listenerManager . registerAllEventHandlers ( listener , tag ) ;
2012-11-08 10:43:44 +01:00
listeners . add ( listener ) ;
}
else {
Bukkit . getPluginManager ( ) . registerEvents ( listener , this ) ;
if ( listener instanceof IHaveMethodOrder ) {
// TODO: Might log the order too, might prevent registration ?
// TODO: Alternative: queue listeners and register after startup (!)
2012-11-09 08:47:24 +01:00
LogUtil . logWarning ( " [NoCheatPlus] Listener demands registration order, but listeners are not managed: " + listener . getClass ( ) . getName ( ) ) ;
2012-11-08 10:43:44 +01:00
}
}
}
/ * *
* Test if NCP uses the ListenerManager at all .
* @return If so .
* /
public boolean doesManageListeners ( ) {
return manageListeners ;
}
2012-11-02 10:40:37 +01:00
@Override
public void removeComponent ( final Object obj ) {
2012-11-07 12:56:25 +01:00
if ( obj instanceof Listener ) {
listeners . remove ( obj ) ;
listenerManager . remove ( ( Listener ) obj ) ;
}
2012-11-09 14:29:51 +01:00
if ( obj instanceof PermStateReceiver ) {
permStateReceivers . remove ( ( PermStateReceiver ) obj ) ;
}
2013-01-14 04:23:39 +01:00
if ( obj instanceof TickListener ) {
TickTask . removeTickListener ( ( TickListener ) obj ) ;
}
2012-11-09 14:29:51 +01:00
if ( obj instanceof INotifyReload ) {
notifyReload . remove ( obj ) ;
}
2013-02-27 18:00:44 +01:00
if ( obj instanceof ConsistencyChecker ) {
consistencyCheckers . remove ( obj ) ;
}
2012-11-02 10:40:37 +01:00
dataMan . removeComponent ( obj ) ;
2013-01-26 07:41:51 +01:00
allComponents . remove ( obj ) ;
2012-11-02 10:40:37 +01:00
}
2012-09-04 06:48:21 +02:00
2012-08-03 16:48:06 +02:00
/ * ( non - Javadoc )
* @see org . bukkit . plugin . java . JavaPlugin # onDisable ( )
* /
2012-04-05 18:24:39 +02:00
@Override
public void onDisable ( ) {
2012-08-24 14:52:24 +02:00
/ *
* ____ _ _ _
* | _ \ ( _ ) ___ __ _ | | __ | | ___
* | | | | / __ | / _ ` | ' _ \ | | / _ \
* | | _ | | \ __ \ ( _ | | | _ ) | | __ /
* | ____ / | _ | ___ / \ __ , _ | _ . __ / | _ | \ ___ |
* /
2012-12-02 17:39:50 +01:00
2012-12-03 17:46:38 +01:00
final boolean verbose = ConfigManager . getConfigFile ( ) . getBoolean ( ConfPaths . LOGGING_DEBUG ) ;
2012-12-02 17:39:50 +01:00
// Remove listener references.
2012-12-03 17:46:38 +01:00
if ( verbose ) {
if ( listenerManager . hasListenerMethods ( ) ) LogUtil . logInfo ( " [NoCheatPlus] Cleanup ListenerManager... " ) ;
2013-01-26 07:41:51 +01:00
else LogUtil . logInfo ( " [NoCheatPlus] (ListenerManager not in use, prevent registering...) " ) ;
2012-12-03 17:46:38 +01:00
}
2012-12-02 17:39:50 +01:00
listenerManager . setRegisterDirectly ( false ) ;
listenerManager . clear ( ) ;
2013-01-29 17:12:04 +01:00
2013-02-27 18:00:44 +01:00
BukkitScheduler sched = getServer ( ) . getScheduler ( ) ;
2013-01-29 17:12:04 +01:00
// Stop data-man task.
2013-02-27 18:00:44 +01:00
if ( dataManTaskId ! = - 1 ) {
sched . cancelTask ( dataManTaskId ) ;
dataManTaskId = - 1 ;
}
2012-09-04 08:52:03 +02:00
2012-09-08 20:16:10 +02:00
// Stop the tickTask.
2012-12-03 17:46:38 +01:00
if ( verbose ) LogUtil . logInfo ( " [NoCheatPlus] Stop TickTask... " ) ;
2012-12-02 17:03:43 +01:00
TickTask . setLocked ( true ) ;
2012-12-02 17:39:50 +01:00
TickTask . purge ( ) ;
2012-09-08 20:16:10 +02:00
TickTask . cancel ( ) ;
2013-01-30 04:22:06 +01:00
TickTask . removeAllTickListeners ( ) ;
2013-01-13 20:44:23 +01:00
// (Keep the tick task locked!)
2012-09-08 20:16:10 +02:00
2012-12-02 17:39:50 +01:00
// Stop metrics task.
if ( metrics ! = null ) {
2012-12-03 17:46:38 +01:00
if ( verbose ) LogUtil . logInfo ( " [NoCheatPlus] Stop Metrics... " ) ;
2012-12-02 17:39:50 +01:00
metrics . cancel ( ) ;
metrics = null ;
}
2013-02-27 18:00:44 +01:00
// Stop consistency checking task.
if ( consistencyCheckerTaskId ! = - 1 ) {
sched . cancelTask ( consistencyCheckerTaskId ) ;
}
2012-12-02 17:39:50 +01:00
2012-09-08 20:16:10 +02:00
// Just to be sure nothing gets left out.
2012-12-03 17:46:38 +01:00
if ( verbose ) LogUtil . logInfo ( " [NoCheatPlus] Stop all remaining tasks... " ) ;
2013-02-27 18:00:44 +01:00
sched . cancelTasks ( this ) ;
2012-04-05 18:24:39 +02:00
2013-01-25 23:51:29 +01:00
// Exemptions cleanup.
2013-01-26 07:41:51 +01:00
if ( verbose ) LogUtil . logInfo ( " [NoCheatPlus] Reset ExemptionManager... " ) ;
2013-01-25 23:51:29 +01:00
NCPExemptionManager . clear ( ) ;
2013-01-13 21:49:29 +01:00
// Data cleanup.
2012-12-03 17:46:38 +01:00
if ( verbose ) LogUtil . logInfo ( " [NoCheatPlus] Cleanup DataManager... " ) ;
2012-11-09 14:29:51 +01:00
dataMan . onDisable ( ) ;
2013-01-13 21:49:29 +01:00
// Hooks:
// (Expect external plugins to unregister their hooks on their own.)
// (No native hooks present, yet.)
2013-01-25 23:51:29 +01:00
// Unregister all added components explicitly.
2013-01-26 07:41:51 +01:00
if ( verbose ) LogUtil . logInfo ( " [NoCheatPlus] Unregister all registered components... " ) ;
for ( Object obj : new ArrayList < Object > ( allComponents ) ) {
2013-01-25 23:51:29 +01:00
removeComponent ( obj ) ;
}
2013-01-30 03:22:58 +01:00
// Cleanup BlockProperties.
if ( verbose ) LogUtil . logInfo ( " [NoCheatPlus] Cleanup BlockProperties... " ) ;
BlockProperties . cleanup ( ) ;
2013-01-25 23:51:29 +01:00
if ( verbose ) LogUtil . logInfo ( " [NoCheatPlus] Cleanup some mappings... " ) ;
// Remove listeners.
listeners . clear ( ) ;
// Remove config listeners.
notifyReload . clear ( ) ;
// World specific permissions.
permStateReceivers . clear ( ) ;
2012-04-05 18:24:39 +02:00
2012-12-13 22:48:56 +01:00
// Clear command changes list (compatibility issues with NPCs, leads to recalculation of perms).
if ( changedCommands ! = null ) {
changedCommands . clear ( ) ;
changedCommands = null ;
}
2012-12-04 22:28:51 +01:00
// // Restore changed commands.
// if (verbose) LogUtil.logInfo("[NoCheatPlus] Undo command changes...");
// undoCommandChanges();
2012-11-07 12:56:25 +01:00
2012-11-09 14:29:51 +01:00
// Cleanup the configuration manager.
2012-12-03 17:46:38 +01:00
if ( verbose ) LogUtil . logInfo ( " [NoCheatPlus] Cleanup ConfigManager... " ) ;
2012-11-09 14:29:51 +01:00
ConfigManager . cleanup ( ) ;
2013-01-20 04:18:08 +01:00
// Cleanup file logger.
if ( verbose ) LogUtil . logInfo ( " [NoCheatPlus] Cleanup file logger... " ) ;
StaticLogFile . cleanup ( ) ;
2012-11-09 14:29:51 +01:00
2012-11-09 08:47:24 +01:00
// Tell the server administrator the we finished unloading NoCheatPlus.
2012-12-03 17:46:38 +01:00
if ( verbose ) LogUtil . logInfo ( " [NoCheatPlus] All cleanup done. " ) ;
2012-12-02 17:39:50 +01:00
final PluginDescriptionFile pdfFile = getDescription ( ) ;
2012-11-09 08:47:24 +01:00
LogUtil . logInfo ( " [NoCheatPlus] Version " + pdfFile . getVersion ( ) + " is disabled. " ) ;
}
2012-04-05 18:24:39 +02:00
2012-11-07 05:30:21 +01:00
/ * *
2012-11-07 08:16:01 +01:00
* Does not undo 100 % , but restore old permission , permission - message , label ( unlikely to be changed ) , permission default .
2012-12-04 22:28:51 +01:00
* @deprecated Leads to compatibility issues with NPC plugins such as Citizens 2 , due to recalculation of permissions ( specifically during disabling ) .
2012-11-07 05:30:21 +01:00
* /
public void undoCommandChanges ( ) {
if ( changedCommands ! = null ) {
2012-11-07 08:16:01 +01:00
while ( ! changedCommands . isEmpty ( ) ) {
final CommandProtectionEntry entry = changedCommands . remove ( changedCommands . size ( ) - 1 ) ;
2012-11-07 05:30:21 +01:00
entry . restore ( ) ;
}
2012-11-07 08:16:01 +01:00
changedCommands = null ;
2012-11-07 05:30:21 +01:00
}
}
2012-11-09 14:29:51 +01:00
protected void setupCommandProtection ( ) {
2012-11-07 08:16:01 +01:00
final List < CommandProtectionEntry > changedCommands = PermissionUtil . protectCommands (
2012-11-07 05:30:21 +01:00
Arrays . asList ( " plugins " , " version " , " icanhasbukkit " ) , " nocheatplus.feature.command " , false ) ;
if ( this . changedCommands = = null ) this . changedCommands = changedCommands ;
else this . changedCommands . addAll ( changedCommands ) ;
}
/ * ( non - Javadoc )
2012-08-03 16:48:06 +02:00
* @see org . bukkit . plugin . java . JavaPlugin # onEnable ( )
* /
2012-04-05 18:24:39 +02:00
@Override
public void onEnable ( ) {
2012-08-24 14:52:24 +02:00
/ *
* _____ _ _
* | ____ | _ __ __ _ | | __ | | ___
* | _ | | ' _ \ / _ ` | ' _ \ | | / _ \
* | | ___ | | | | ( _ | | | _ ) | | __ /
* | _____ | _ | | _ | \ __ , _ | _ . __ / | _ | \ ___ |
* /
2012-09-04 08:52:03 +02:00
2012-12-06 01:58:57 +01:00
// Reset TickTask (just in case).
2013-01-13 20:44:23 +01:00
TickTask . setLocked ( true ) ;
TickTask . purge ( ) ;
TickTask . cancel ( ) ;
2012-12-06 01:58:57 +01:00
TickTask . reset ( ) ;
2012-08-03 16:48:06 +02:00
// Read the configuration files.
ConfigManager . init ( this ) ;
2012-10-05 17:14:41 +02:00
2013-01-20 04:18:08 +01:00
// Setup file logger.
StaticLogFile . setupLogger ( new File ( getDataFolder ( ) , ConfigManager . getConfigFile ( ) . getString ( ConfPaths . LOGGING_FILENAME ) ) ) ;
2013-01-20 05:59:46 +01:00
final ConfigFile config = ConfigManager . getConfigFile ( ) ;
// Initialize BlockProperties
initBlockProperties ( config ) ;
2013-02-26 00:39:48 +01:00
// Initialize data manager.
dataMan . onEnable ( ) ;
2013-01-20 05:25:21 +01:00
2012-12-02 17:03:43 +01:00
// Allow entries to TickTask (just in case).
TickTask . setLocked ( false ) ;
2012-04-05 18:24:39 +02:00
2012-11-08 10:43:44 +01:00
// List the events listeners and register.
manageListeners = config . getBoolean ( ConfPaths . MISCELLANEOUS_MANAGELISTENERS ) ;
if ( manageListeners ) {
listenerManager . setRegisterDirectly ( true ) ;
listenerManager . registerAllWithBukkit ( ) ;
}
else {
// Just for safety.
listenerManager . setRegisterDirectly ( false ) ;
listenerManager . clear ( ) ;
}
2012-11-09 14:29:51 +01:00
addComponent ( nameSetPerms ) ;
addListener ( getCoreListener ( ) ) ;
2012-09-20 20:16:00 +02:00
for ( final Object obj : new Object [ ] {
2013-01-20 05:25:21 +01:00
// Put ReloadListener first, because Checks could also listen to it.
new INotifyReload ( ) {
// Only for reloading, not INeedConfig.
@Override
public void onReload ( ) {
final ConfigFile config = ConfigManager . getConfigFile ( ) ;
2013-01-20 05:59:46 +01:00
// Initialize BlockProperties
2013-01-30 04:22:06 +01:00
initMCAccess ( config ) ;
2013-01-20 05:59:46 +01:00
initBlockProperties ( config ) ;
2013-01-20 05:25:21 +01:00
// Reset Command protection.
undoCommandChanges ( ) ;
if ( config . getBoolean ( ConfPaths . MISCELLANEOUS_PROTECTPLUGINS ) ) setupCommandProtection ( ) ;
2013-02-27 18:00:44 +01:00
scheduleConsistencyCheckers ( ) ;
2013-01-20 05:25:21 +01:00
}
} ,
2012-10-01 03:25:39 +02:00
NCPExemptionManager . getListener ( ) ,
2013-02-27 18:00:44 +01:00
new ConsistencyChecker ( ) {
@Override
public void checkConsistency ( final Player [ ] onlinePlayers ) {
NCPExemptionManager . checkConsistency ( onlinePlayers ) ;
}
} ,
2012-09-20 20:16:00 +02:00
dataMan ,
2012-09-04 06:48:21 +02:00
new BlockInteractListener ( ) ,
2013-02-17 16:20:13 +01:00
new BlockBreakListener ( ) ,
2012-09-04 06:48:21 +02:00
new BlockPlaceListener ( ) ,
new ChatListener ( ) ,
2012-09-10 08:52:27 +02:00
new CombinedListener ( ) ,
2012-11-09 14:29:51 +01:00
// Do mind registration order: Combined must come before Fight.
2012-09-04 06:48:21 +02:00
new FightListener ( ) ,
new InventoryListener ( ) ,
new MovingListener ( ) ,
} ) {
2012-09-20 20:16:00 +02:00
addComponent ( obj ) ;
2012-09-04 06:48:21 +02:00
}
2012-09-04 08:52:03 +02:00
// Register the commands handler.
2012-11-07 05:30:21 +01:00
PluginCommand command = getCommand ( " nocheatplus " ) ;
CommandHandler commandHandler = new CommandHandler ( this , notifyReload ) ;
command . setExecutor ( commandHandler ) ;
// (CommandHandler is TabExecutor.)
2012-09-08 20:16:10 +02:00
// Set up the tick task.
TickTask . start ( this ) ;
2012-09-20 20:16:00 +02:00
2013-01-29 17:12:04 +01:00
this . dataManTaskId = Bukkit . getScheduler ( ) . scheduleSyncRepeatingTask ( this , new Runnable ( ) {
2012-09-20 20:16:00 +02:00
@Override
public void run ( ) {
dataMan . checkExpiration ( ) ;
}
} , 1207 , 1207 ) ;
2013-02-27 18:00:44 +01:00
// Set up consistency checking.
scheduleConsistencyCheckers ( ) ;
2012-04-05 18:24:39 +02:00
2012-09-03 10:18:16 +02:00
2012-08-22 02:41:28 +02:00
// Setup the graphs, plotters and start Metrics.
2012-09-03 10:18:16 +02:00
if ( config . getBoolean ( ConfPaths . MISCELLANEOUS_REPORTTOMETRICS ) ) {
2012-08-24 22:02:38 +02:00
MetricsData . initialize ( ) ;
2012-08-24 14:52:24 +02:00
try {
2012-12-02 17:39:50 +01:00
this . metrics = new Metrics ( this ) ;
2012-08-24 14:52:24 +02:00
final Graph checksFailed = metrics . createGraph ( " Checks Failed " ) ;
for ( final CheckType type : CheckType . values ( ) )
2012-08-24 22:02:38 +02:00
if ( type . getParent ( ) ! = null )
2012-08-24 14:52:24 +02:00
checksFailed . addPlotter ( new Plotter ( type . name ( ) ) {
@Override
public int getValue ( ) {
2012-08-24 22:02:38 +02:00
return MetricsData . getFailed ( type ) ;
2012-08-24 14:52:24 +02:00
}
} ) ;
final Graph serverTicks = metrics . createGraph ( " Server Ticks " ) ;
2012-08-24 22:02:38 +02:00
final int [ ] ticksArray = new int [ ] { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 ,
19 , 20 } ;
for ( final int ticks : ticksArray )
serverTicks . addPlotter ( new Plotter ( ticks + " tick(s) " ) {
@Override
public int getValue ( ) {
return MetricsData . getTicks ( ticks ) ;
}
} ) ;
2012-08-24 14:52:24 +02:00
metrics . start ( ) ;
2012-12-02 17:39:50 +01:00
} catch ( final Exception e ) {
LogUtil . logWarning ( " [NoCheatPlus] Failed to initialize metrics: " ) ;
LogUtil . logWarning ( e ) ;
if ( metrics ! = null ) {
metrics . cancel ( ) ;
metrics = null ;
}
}
2012-08-24 22:02:38 +02:00
}
2012-08-20 19:40:00 +02:00
2012-09-17 00:06:59 +02:00
// if (config.getBoolean(ConfPaths.MISCELLANEOUS_CHECKFORUPDATES)){
// // Is a new update available?
2012-09-25 22:08:22 +02:00
// final int timeout = config.getInt(ConfPaths.MISCELLANEOUS_UPDATETIMEOUT, 4) * 1000;
// getServer().getScheduler().scheduleAsyncDelayedTask(this, new Runnable() {
// @Override
// public void run() {
2012-09-26 16:43:13 +02:00
// updateAvailable = Updates.checkForUpdates(getDescription().getVersion(), timeout);
2012-09-25 22:08:22 +02:00
// }
// });
2012-09-17 00:06:59 +02:00
// }
2012-08-22 02:41:28 +02:00
2012-09-25 22:08:22 +02:00
// Is the configuration outdated?
2012-10-12 02:46:02 +02:00
configOutdated = Updates . isConfigOutdated ( DefaultConfig . buildNumber , config ) ;
2012-09-11 13:23:05 +02:00
2012-11-07 05:30:21 +01:00
if ( config . getBoolean ( ConfPaths . MISCELLANEOUS_PROTECTPLUGINS ) ) {
Bukkit . getScheduler ( ) . scheduleSyncDelayedTask ( this , new Runnable ( ) {
@Override
public void run ( ) {
setupCommandProtection ( ) ;
}
} ) ;
}
2013-01-07 18:49:37 +01:00
// Care for already online players.
final Player [ ] onlinePlayers = getServer ( ) . getOnlinePlayers ( ) ;
// TODO: remap exemptionmanager !
// TODO: Disable all checks for these players for one tick !
// TODO: Prepare check data for players [problem: permissions]?
Bukkit . getScheduler ( ) . scheduleSyncDelayedTask ( this , new Runnable ( ) {
@Override
public void run ( ) {
postEnable ( onlinePlayers ) ;
}
} ) ;
2012-11-09 08:47:24 +01:00
// Tell the server administrator that we finished loading NoCheatPlus now.
LogUtil . logInfo ( " [NoCheatPlus] Version " + getDescription ( ) . getVersion ( ) + " is enabled. " ) ;
}
2013-01-07 18:49:37 +01:00
2013-01-20 05:59:46 +01:00
/ * *
2013-01-30 04:22:06 +01:00
* Re - setup MCAccess and pass it to MCAccessHolder components .
* @param config
2013-01-20 05:59:46 +01:00
* /
2013-01-30 04:22:06 +01:00
protected void initMCAccess ( final ConfigFile config ) {
2013-01-20 05:59:46 +01:00
// Reset MCAccess.
2013-01-30 04:22:06 +01:00
NoCheatPlus . mcAccess = null ;
final MCAccess mcAccess = getMCAccess ( ) ;
for ( final Object obj : this . allComponents ) {
if ( obj instanceof MCAccessHolder ) {
( ( MCAccessHolder ) obj ) . setMCAccess ( mcAccess ) ;
}
}
}
/ * *
* Initialize BlockProperties , including config .
* /
protected void initBlockProperties ( ConfigFile config ) {
2013-01-20 05:59:46 +01:00
// Set up BlockProperties.
2013-01-30 10:42:29 +01:00
BlockProperties . init ( getMCAccess ( ) , ConfigManager . getWorldConfigProvider ( ) ) ;
2013-01-20 05:59:46 +01:00
BlockProperties . applyConfig ( config , ConfPaths . COMPATIBILITY_BLOCKS ) ;
2013-02-20 22:30:55 +01:00
// Schedule dumping the blocks properties (to let other plugins override).
Bukkit . getScheduler ( ) . scheduleSyncDelayedTask ( this , new Runnable ( ) {
@Override
public void run ( ) {
// Debug information about unknown blocks.
// (Probably removed later.)
ConfigFile config = ConfigManager . getConfigFile ( ) ;
BlockProperties . dumpBlocks ( config . getBoolean ( ConfPaths . BLOCKBREAK_FASTBREAK_DEBUG , false ) | | config . getBoolean ( ConfPaths . BLOCKBREAK , false ) ) ;
}
} ) ;
2013-01-20 05:59:46 +01:00
}
2013-01-07 18:49:37 +01:00
/ * *
* Actions to be done after enable of all plugins . This aims at reloading mainly .
* /
private void postEnable ( final Player [ ] onlinePlayers ) {
for ( final Player player : onlinePlayers ) {
updatePermStateReceivers ( player ) ;
2013-02-27 18:22:33 +01:00
NCPExemptionManager . registerPlayer ( player ) ;
2013-01-07 18:49:37 +01:00
}
// TODO: if (online.lenght > 0) LogUtils.logInfo("[NCP] Updated " + online.length + "players (post-enable).")
}
2012-10-17 17:44:12 +02:00
/ * *
2012-11-09 14:29:51 +01:00
* Quick solution to hide the listener methods , expect refactoring .
* @return
* /
private Listener getCoreListener ( ) {
2012-11-12 09:04:43 +01:00
return new NCPListener ( ) {
2012-11-09 14:29:51 +01:00
@SuppressWarnings ( " unused " )
2013-01-18 00:09:42 +01:00
@EventHandler ( priority = EventPriority . NORMAL )
2012-11-09 14:29:51 +01:00
public void onPlayerLogin ( final PlayerLoginEvent event ) {
2013-01-18 00:09:42 +01:00
// (NORMAL to have chat checks come after this.)
2012-11-09 14:29:51 +01:00
if ( event . getResult ( ) ! = Result . ALLOWED ) return ;
final Player player = event . getPlayer ( ) ;
// Check if login is denied:
checkDenyLoginsNames ( ) ;
if ( player . hasPermission ( Permissions . BYPASS_DENY_LOGIN ) ) return ;
if ( isLoginDenied ( player . getName ( ) ) ) {
// TODO: display time for which the player is banned.
event . setResult ( Result . KICK_OTHER ) ;
// TODO: Make message configurable.
event . setKickMessage ( " You are temporarily denied to join this server. " ) ;
}
}
@SuppressWarnings ( " unused " )
@EventHandler ( priority = EventPriority . MONITOR )
public void onPlayerJoin ( final PlayerJoinEvent event ) {
final Player player = event . getPlayer ( ) ;
updatePermStateReceivers ( player ) ;
if ( nameSetPerms . hasPermission ( player . getName ( ) , Permissions . ADMINISTRATION_NOTIFY ) ) {
// Login notifications...
// Update available.
if ( updateAvailable ) player . sendMessage ( ChatColor . RED + " NCP: " + ChatColor . WHITE + " A new update of NoCheatPlus is available. \ n " + " Download it at http://nocheatplus.org/update " ) ;
// Outdated config.
if ( configOutdated ) player . sendMessage ( ChatColor . RED + " NCP: " + ChatColor . WHITE + " Your configuration might be outdated. \ n " + " Some settings could have changed, you should regenerate it! " ) ;
}
2013-01-18 22:37:23 +01:00
ModUtil . checkModsMessage ( player ) ;
2012-11-09 14:29:51 +01:00
}
@SuppressWarnings ( " unused " )
@EventHandler ( priority = EventPriority . MONITOR )
public void onPlayerchangedWorld ( final PlayerChangedWorldEvent event )
{
final Player player = event . getPlayer ( ) ;
updatePermStateReceivers ( player ) ;
}
@SuppressWarnings ( " unused " )
@EventHandler ( priority = EventPriority . MONITOR , ignoreCancelled = true )
public void onPlayerKick ( final PlayerKickEvent event ) {
onLeave ( event . getPlayer ( ) ) ;
}
@SuppressWarnings ( " unused " )
@EventHandler ( priority = EventPriority . MONITOR )
public void onPlayerQuitMonitor ( final PlayerQuitEvent event ) {
onLeave ( event . getPlayer ( ) ) ;
}
} ;
}
protected void onLeave ( final Player player ) {
for ( final PermStateReceiver pr : permStateReceivers ) {
pr . removePlayer ( player . getName ( ) ) ;
}
}
protected void updatePermStateReceivers ( final Player player ) {
final Map < String , Boolean > checked = new HashMap < String , Boolean > ( 20 ) ;
final String name = player . getName ( ) ;
for ( final PermStateReceiver pr : permStateReceivers ) {
for ( final String permission : pr . getDefaultPermissions ( ) ) {
Boolean state = checked . get ( permission ) ;
if ( state = = null ) {
state = player . hasPermission ( permission ) ;
checked . put ( permission , state ) ;
}
pr . setPermission ( name , permission , state ) ;
}
}
}
2013-02-27 18:00:44 +01:00
protected void scheduleConsistencyCheckers ( ) {
BukkitScheduler sched = getServer ( ) . getScheduler ( ) ;
if ( consistencyCheckerTaskId ! = - 1 ) {
sched . cancelTask ( consistencyCheckerTaskId ) ;
}
ConfigFile config = ConfigManager . getConfigFile ( ) ;
if ( ! config . getBoolean ( ConfPaths . DATA_CONSISTENCYCHECKS_CHECK , true ) ) return ;
// Schedule task in seconds.
final long delay = 20L * config . getInt ( ConfPaths . DATA_CONSISTENCYCHECKS_INTERVAL , 1 , 3600 , 10 ) ;
consistencyCheckerTaskId = sched . scheduleSyncRepeatingTask ( this , new Runnable ( ) {
@Override
public void run ( ) {
runConsistencyChecks ( ) ;
}
} , delay , delay ) ;
}
/ * *
* Run consistency checks for at most the configured duration . If not finished , a task will be scheduled to continue .
* /
protected void runConsistencyChecks ( ) {
final long tStart = System . currentTimeMillis ( ) ;
final ConfigFile config = ConfigManager . getConfigFile ( ) ;
if ( ! config . getBoolean ( ConfPaths . DATA_CONSISTENCYCHECKS_CHECK ) | | consistencyCheckers . isEmpty ( ) ) {
consistencyCheckerIndex = 0 ;
return ;
}
final long tEnd = tStart + config . getLong ( ConfPaths . DATA_CONSISTENCYCHECKS_MAXTIME , 1 , 50 , 2 ) ;
if ( consistencyCheckerIndex > = consistencyCheckers . size ( ) ) consistencyCheckerIndex = 0 ;
final Player [ ] onlinePlayers = getServer ( ) . getOnlinePlayers ( ) ;
// Loop
while ( consistencyCheckerIndex < consistencyCheckers . size ( ) ) {
final ConsistencyChecker checker = consistencyCheckers . get ( consistencyCheckerIndex ) ;
try {
checker . checkConsistency ( onlinePlayers ) ;
}
catch ( Throwable t ) {
LogUtil . logSevere ( " [NoCheatPlus] ConsistencyChecker( " + checker . getClass ( ) . getName ( ) + " ) encountered an exception: " ) ;
LogUtil . logSevere ( t ) ;
}
consistencyCheckerIndex + + ; // Do not remove :).
final long now = System . currentTimeMillis ( ) ;
if ( now < tStart | | now > = tEnd ) {
break ;
}
}
// (The index might be bigger than size by now.)
final boolean debug = config . getBoolean ( ConfPaths . LOGGING_DEBUG ) ;
// If not finished, schedule further checks.
if ( consistencyCheckerIndex < consistencyCheckers . size ( ) ) {
getServer ( ) . getScheduler ( ) . scheduleSyncDelayedTask ( this , new Runnable ( ) {
@Override
public void run ( ) {
runConsistencyChecks ( ) ;
}
} ) ;
if ( debug ) {
LogUtil . logInfo ( " [NoCheatPlus] Re-scheduled consistency-checks. " ) ;
}
}
else if ( debug ) {
LogUtil . logInfo ( " [NoCheatPlus] Consistency-checks run. " ) ;
}
}
2012-11-09 14:29:51 +01:00
2012-04-05 18:24:39 +02:00
}