diff --git a/plugin.yml b/plugin.yml index d7087f84..ae9a03b3 100644 --- a/plugin.yml +++ b/plugin.yml @@ -18,7 +18,7 @@ permissions: massivecore.store.stats: {description: show mstore statistics, default: false} massivecore.store.listcolls: {description: list collections in a database, default: false} massivecore.store.copydb: {description: copy database content, default: false} - massivecore.store.playerclean: {description: clean inactive players, default: false} + massivecore.store.clean: {description: clean database, default: false} massivecore.usys: {description: use the usys command, default: false} massivecore.usys.multiverse: {description: manage multiverses, default: false} massivecore.usys.multiverse.list: {description: list multiverses, default: false} @@ -63,7 +63,7 @@ permissions: massivecore.store.stats: true massivecore.store.listcolls: true massivecore.store.copydb: true - massivecore.store.playerclean: true + massivecore.store.clean: true massivecore.usys: true massivecore.usys.multiverse: true massivecore.usys.multiverse.list: true @@ -103,7 +103,7 @@ permissions: massivecore.kit.rank3: default: false children: - massivecore.store.playerclean: true + massivecore.store.clean: true massivecore.kit.rank2: true massivecore.kit.rank2: default: false diff --git a/src/com/massivecraft/massivecore/MassiveCoreMConf.java b/src/com/massivecraft/massivecore/MassiveCoreMConf.java index 8f3beebf..5793b6a5 100644 --- a/src/com/massivecraft/massivecore/MassiveCoreMConf.java +++ b/src/com/massivecraft/massivecore/MassiveCoreMConf.java @@ -128,25 +128,25 @@ public int getTpdelay(Permissible permissible) public boolean warnOnLocalAlter = false; // -------------------------------------------- // - // PLAYERCLEAN + // CLEAN // -------------------------------------------- // // How often should the task run? // When set to 0 this feature is disabled. Meaning no cleaning will be done. // Default: 1 day (Per default once a day.) - public long playercleanPeriodMillis = TimeUnit.MILLIS_PER_DAY; + public long cleanTaskPeriodMillis = TimeUnit.MILLIS_PER_DAY; // This is used to decide at what time of the day the task will run. // For Example: If the taskPeriodMillis is 24 hours: // Set it to 0 for UTC midnight. // Set it to 3600000 for UTC midnight + 1 hour. - public long playercleanOffsetMillis = 0; + public long cleanTaskOffsetMillis = 0; // When did the task last run? // This need not be modified by the server owner. // It will be set for you automatically. // 0 means it never ran before. - public long playercleanLastMillis = 0; + public long cleanTaskLastMillis = 0; // -------------------------------------------- // // MONGODB diff --git a/src/com/massivecraft/massivecore/MassiveCorePerm.java b/src/com/massivecraft/massivecore/MassiveCorePerm.java index 80310634..73d9a49f 100644 --- a/src/com/massivecraft/massivecore/MassiveCorePerm.java +++ b/src/com/massivecraft/massivecore/MassiveCorePerm.java @@ -18,7 +18,7 @@ public enum MassiveCorePerm implements Identified STORE_STATS, STORE_LISTCOLLS, STORE_COPYDB, - STORE_PLAYERCLEAN, + STORE_CLEAN, USYS, USYS_MULTIVERSE, USYS_MULTIVERSE_LIST, diff --git a/src/com/massivecraft/massivecore/cmd/CmdMassiveCoreStore.java b/src/com/massivecraft/massivecore/cmd/CmdMassiveCoreStore.java index f4c0a7a3..ed6988c8 100755 --- a/src/com/massivecraft/massivecore/cmd/CmdMassiveCoreStore.java +++ b/src/com/massivecraft/massivecore/cmd/CmdMassiveCoreStore.java @@ -20,6 +20,6 @@ public class CmdMassiveCoreStore extends MassiveCoreCommand public CmdMassiveCoreStoreStats cmdMassiveCoreStoreStats = new CmdMassiveCoreStoreStats(); public CmdMassiveCoreStoreListcolls cmdMassiveCoreStoreListcolls = new CmdMassiveCoreStoreListcolls(); public CmdMassiveCoreStoreCopydb cmdMassiveCoreStoreCopydb = new CmdMassiveCoreStoreCopydb(); - public CmdMassiveCoreStorePlayerclean cmdMassiveCoreStorePlayerclean = new CmdMassiveCoreStorePlayerclean(); + public CmdMassiveCoreStoreClean cmdMassiveCoreStoreClean = new CmdMassiveCoreStoreClean(); } diff --git a/src/com/massivecraft/massivecore/cmd/CmdMassiveCoreStorePlayerclean.java b/src/com/massivecraft/massivecore/cmd/CmdMassiveCoreStoreClean.java similarity index 56% rename from src/com/massivecraft/massivecore/cmd/CmdMassiveCoreStorePlayerclean.java rename to src/com/massivecraft/massivecore/cmd/CmdMassiveCoreStoreClean.java index 480aacd9..3f908d2b 100755 --- a/src/com/massivecraft/massivecore/cmd/CmdMassiveCoreStorePlayerclean.java +++ b/src/com/massivecraft/massivecore/cmd/CmdMassiveCoreStoreClean.java @@ -2,25 +2,26 @@ import com.massivecraft.massivecore.MassiveException; import com.massivecraft.massivecore.command.type.container.TypeSet; -import com.massivecraft.massivecore.command.type.store.TypeSenderColl; -import com.massivecraft.massivecore.store.SenderColl; -import com.massivecraft.massivecore.store.inactive.InactiveUtil; +import com.massivecraft.massivecore.command.type.store.TypeColl; +import com.massivecraft.massivecore.store.Coll; +import com.massivecraft.massivecore.store.cleanable.Cleanable; +import com.massivecraft.massivecore.store.cleanable.CleaningUtil; import com.massivecraft.massivecore.util.IdUtil; import com.massivecraft.massivecore.util.MUtil; import org.bukkit.command.CommandSender; import java.util.Set; -public class CmdMassiveCoreStorePlayerclean extends MassiveCoreCommand +public class CmdMassiveCoreStoreClean extends MassiveCoreCommand { // -------------------------------------------- // // CONSTRUCT // -------------------------------------------- // - public CmdMassiveCoreStorePlayerclean() + public CmdMassiveCoreStoreClean() { // Parameters - this.addParameter(TypeSet.get(TypeSenderColl.get()), "player coll", true).setDesc("the coll to clean inactive players from"); + this.addParameter(TypeSet.get(TypeColl.get()), "coll", true).setDesc("the coll to clean"); } // -------------------------------------------- // @@ -30,13 +31,13 @@ public CmdMassiveCoreStorePlayerclean() @Override public void perform() throws MassiveException { - Set> colls = this.readArg(); + Set> colls = this.readArg(); Set receivers = MUtil.set(sender, IdUtil.getConsole()); - for (SenderColl coll : colls) + for (Coll coll : colls) { - InactiveUtil.considerRemoveInactive(coll, receivers); + CleaningUtil.considerClean(coll, receivers); } } diff --git a/src/com/massivecraft/massivecore/engine/EngineMassiveCorePlayerclean.java b/src/com/massivecraft/massivecore/engine/EngineMassiveCoreClean.java similarity index 71% rename from src/com/massivecraft/massivecore/engine/EngineMassiveCorePlayerclean.java rename to src/com/massivecraft/massivecore/engine/EngineMassiveCoreClean.java index 69154afd..6a2a77c9 100644 --- a/src/com/massivecraft/massivecore/engine/EngineMassiveCorePlayerclean.java +++ b/src/com/massivecraft/massivecore/engine/EngineMassiveCoreClean.java @@ -3,9 +3,9 @@ import com.massivecraft.massivecore.Engine; import com.massivecraft.massivecore.MassiveCore; import com.massivecraft.massivecore.MassiveCoreMConf; -import com.massivecraft.massivecore.event.EventMassiveCorePlayercleanToleranceMillis; -import com.massivecraft.massivecore.store.SenderColl; -import com.massivecraft.massivecore.store.inactive.InactiveUtil; +import com.massivecraft.massivecore.event.EventMassiveCorePlayerCleanInactivityToleranceMillis; +import com.massivecraft.massivecore.store.Coll; +import com.massivecraft.massivecore.store.cleanable.CleaningUtil; import com.massivecraft.massivecore.util.IdUtil; import org.bukkit.command.CommandSender; import org.bukkit.event.EventHandler; @@ -14,15 +14,15 @@ import java.util.Collections; import java.util.List; -public class EngineMassiveCorePlayerclean extends Engine +public class EngineMassiveCoreClean extends Engine { // -------------------------------------------- // // INSTANCE & CONSTRUCT // -------------------------------------------- // - private static EngineMassiveCorePlayerclean i = new EngineMassiveCorePlayerclean(); - public static EngineMassiveCorePlayerclean get() { return i; } - public EngineMassiveCorePlayerclean() + private static EngineMassiveCoreClean i = new EngineMassiveCoreClean(); + public static EngineMassiveCoreClean get() { return i; } + public EngineMassiveCoreClean() { // Just check once a minute this.setPeriod(60L * 20L); @@ -44,7 +44,7 @@ public void run() final long currentInvocation = getInvocationFromMillis(now); // ... and the last invocation ... - final long lastInvocation = getInvocationFromMillis(MassiveCoreMConf.get().playercleanLastMillis); + final long lastInvocation = getInvocationFromMillis(MassiveCoreMConf.get().cleanTaskLastMillis); // ... are different ... if (currentInvocation == lastInvocation) return; @@ -56,14 +56,14 @@ public void run() public void invoke(long now) { // Update lastMillis - MassiveCoreMConf.get().playercleanLastMillis = now; + MassiveCoreMConf.get().cleanTaskLastMillis = now; MassiveCoreMConf.get().changed(); List recipients = Collections.singletonList(IdUtil.getConsole()); - for (SenderColl coll : SenderColl.getSenderInstances()) + for (Coll coll : Coll.getInstances()) { - if (!coll.isPlayercleanTaskEnabled()) continue; - InactiveUtil.considerRemoveInactive(now, coll, recipients); + if (!coll.isCleanTaskEnabled()) continue; + CleaningUtil.considerClean(now, coll, recipients); } } @@ -77,7 +77,7 @@ public void invoke(long now) // Here we accept millis from inside the period by rounding down. private static long getInvocationFromMillis(long millis) { - return (millis - MassiveCoreMConf.get().playercleanOffsetMillis) / MassiveCoreMConf.get().playercleanPeriodMillis; + return (millis - MassiveCoreMConf.get().cleanTaskOffsetMillis) / MassiveCoreMConf.get().cleanTaskPeriodMillis; } // -------------------------------------------- // @@ -85,9 +85,9 @@ private static long getInvocationFromMillis(long millis) // -------------------------------------------- // @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) - public void defaultMillis(EventMassiveCorePlayercleanToleranceMillis event) + public void defaultMillis(EventMassiveCorePlayerCleanInactivityToleranceMillis event) { - event.getToleranceCauseMillis().put("Default", event.getColl().getPlayercleanToleranceMillis()); + event.getToleranceCauseMillis().put("Default", event.getColl().getCleanInactivityToleranceMillis()); } } diff --git a/src/com/massivecraft/massivecore/event/EventMassiveCorePlayercleanToleranceMillis.java b/src/com/massivecraft/massivecore/event/EventMassiveCorePlayerCleanInactivityToleranceMillis.java similarity index 70% rename from src/com/massivecraft/massivecore/event/EventMassiveCorePlayercleanToleranceMillis.java rename to src/com/massivecraft/massivecore/event/EventMassiveCorePlayerCleanInactivityToleranceMillis.java index 33571839..d684d57e 100644 --- a/src/com/massivecraft/massivecore/event/EventMassiveCorePlayercleanToleranceMillis.java +++ b/src/com/massivecraft/massivecore/event/EventMassiveCorePlayerCleanInactivityToleranceMillis.java @@ -2,13 +2,12 @@ import com.massivecraft.massivecore.store.SenderColl; import com.massivecraft.massivecore.store.SenderEntity; -import com.massivecraft.massivecore.store.inactive.Inactive; import org.bukkit.event.HandlerList; import java.util.LinkedHashMap; import java.util.Map; -public class EventMassiveCorePlayercleanToleranceMillis extends EventMassiveCore +public class EventMassiveCorePlayerCleanInactivityToleranceMillis extends EventMassiveCore { // -------------------------------------------- // // REQUIRED EVENT CODE @@ -22,6 +21,9 @@ public class EventMassiveCorePlayercleanToleranceMillis extends EventMassiveCore // FIELD // -------------------------------------------- // + private final long lastActivityMillis; + public long getLastActivityMillis() { return lastActivityMillis; } + private final long now; public long getNow() { return now; } @@ -37,13 +39,14 @@ public class EventMassiveCorePlayercleanToleranceMillis extends EventMassiveCore // CONSTRUCT // -------------------------------------------- // - public EventMassiveCorePlayercleanToleranceMillis(SenderEntity entity) + public EventMassiveCorePlayerCleanInactivityToleranceMillis(long lastActivityMillis, SenderEntity entity) { - this(System.currentTimeMillis(), entity); + this(lastActivityMillis, System.currentTimeMillis(), entity); } - public EventMassiveCorePlayercleanToleranceMillis(long now, SenderEntity entity) + public EventMassiveCorePlayerCleanInactivityToleranceMillis(long lastActivityMillis, long now, SenderEntity entity) { + this.lastActivityMillis = lastActivityMillis; this.now = now; this.entity = entity; } @@ -64,12 +67,15 @@ public long getToleranceMillis() return ret; } - public boolean shouldBeRemoved() + public boolean shouldBeCleaned() { long toleranceMillis = getToleranceMillis(); long now = this.getNow(); - long lastActivityMillis = ((Inactive)this.getEntity()).getLastActivityMillis(); + long lastActivityMillis = this.getLastActivityMillis(); + + // If unknown don't remove + if (lastActivityMillis <= 0) return false; long removeTime = lastActivityMillis + toleranceMillis; diff --git a/src/com/massivecraft/massivecore/store/Coll.java b/src/com/massivecraft/massivecore/store/Coll.java index a6ef5cb0..444e1015 100644 --- a/src/com/massivecraft/massivecore/store/Coll.java +++ b/src/com/massivecraft/massivecore/store/Coll.java @@ -142,6 +142,13 @@ public String getDebugName() protected final int entityTargetVersion; @Override public int getEntityTargetVersion() { return this.entityTargetVersion; } + // This should be false under most circumstances. + // In some cases such as Factions we want it though. + // Especially so we don't change the years old way Factions does it. + private boolean cleanTaskEnabled = false; + public boolean isCleanTaskEnabled() { return this.cleanTaskEnabled; } + public void setCleanTaskEnabled(boolean cleanTaskEnabled) { this.cleanTaskEnabled = cleanTaskEnabled; } + // -------------------------------------------- // // IDENTIFIED MODIFICATIONS // -------------------------------------------- // diff --git a/src/com/massivecraft/massivecore/store/SenderColl.java b/src/com/massivecraft/massivecore/store/SenderColl.java index f28029a3..2c228e09 100644 --- a/src/com/massivecraft/massivecore/store/SenderColl.java +++ b/src/com/massivecraft/massivecore/store/SenderColl.java @@ -16,13 +16,6 @@ public class SenderColl> extends Coll implements SenderIdSource { - // This should be false under most circumstances. - // In some cases such as Factions we want it though. - // Especially so we don't change the years old way Factions does it. - private boolean playercleanTaskEnabled = false; - public boolean isPlayercleanTaskEnabled() { return this.playercleanTaskEnabled; } - public void setPlayercleanTaskEnabled(boolean playercleanTaskEnabled) { this.playercleanTaskEnabled = playercleanTaskEnabled; } - // -------------------------------------------- // // CONSTRUCT // -------------------------------------------- // @@ -203,11 +196,11 @@ public static void setSenderReferences(String senderId, CommandSender sender) } // -------------------------------------------- // - // ACTIVITY MILLIS + // CLEAN // -------------------------------------------- // // Must be overriden if they want to use it. - public long getPlayercleanToleranceMillis() + public long getCleanInactivityToleranceMillis() { return -1; } diff --git a/src/com/massivecraft/massivecore/store/SenderEntity.java b/src/com/massivecraft/massivecore/store/SenderEntity.java index 3c50cfbf..43249a5e 100644 --- a/src/com/massivecraft/massivecore/store/SenderEntity.java +++ b/src/com/massivecraft/massivecore/store/SenderEntity.java @@ -4,11 +4,13 @@ import com.massivecraft.massivecore.Named; import com.massivecraft.massivecore.PlayerState; import com.massivecraft.massivecore.event.EventMassiveCoreAknowledge; +import com.massivecraft.massivecore.event.EventMassiveCorePlayerCleanInactivityToleranceMillis; import com.massivecraft.massivecore.mixin.MixinDisplayName; import com.massivecraft.massivecore.mixin.MixinMessage; import com.massivecraft.massivecore.mixin.MixinPlayed; import com.massivecraft.massivecore.mixin.MixinVisibility; import com.massivecraft.massivecore.mson.Mson; +import com.massivecraft.massivecore.store.cleanable.Cleanable; import com.massivecraft.massivecore.util.IdUtil; import com.massivecraft.massivecore.util.PermissionUtil; import org.bukkit.GameMode; @@ -19,7 +21,7 @@ import java.util.Collection; import java.util.UUID; -public abstract class SenderEntity> extends Entity implements Named +public abstract class SenderEntity> extends Entity implements Named, Cleanable { // -------------------------------------------- // // FIELDS @@ -65,6 +67,40 @@ public SenderColl getColl() return (SenderColl) super.getColl(); } + // -------------------------------------------- // + // OVERRIDE: CLEANABLE + // -------------------------------------------- // + + @Override + public boolean shouldBeCleaned(long now) + { + // If unknown don't clean + Long lastActivityMillis = this.getLastPlayed(); + if (lastActivityMillis == null) return false; + + return this.shouldBeCleaned(now, lastActivityMillis); + } + + protected boolean shouldBeCleaned(long now, long lastActivityMillis) + { + // This means it is disabled for this coll + if (this.getColl().getCleanInactivityToleranceMillis() < 0) return false; + + EventMassiveCorePlayerCleanInactivityToleranceMillis event = new EventMassiveCorePlayerCleanInactivityToleranceMillis(lastActivityMillis, now, this); + event.run(); + return event.shouldBeCleaned(); + } + + public void preClean() + { + + } + + public void postClean() + { + + } + // -------------------------------------------- // // CONVENIENCE: DATABASE // -------------------------------------------- // diff --git a/src/com/massivecraft/massivecore/store/cleanable/Cleanable.java b/src/com/massivecraft/massivecore/store/cleanable/Cleanable.java new file mode 100644 index 00000000..aff3aabd --- /dev/null +++ b/src/com/massivecraft/massivecore/store/cleanable/Cleanable.java @@ -0,0 +1,14 @@ +package com.massivecraft.massivecore.store.cleanable; + +import com.massivecraft.massivecore.store.Coll; + +// This interface only really makes sense for SenderEntity's +// But by using this conversion to non-senders should be easier when that is done +public interface Cleanable +{ + boolean shouldBeCleaned(long now); + Coll getColl(); + + void preClean(); + void postClean(); +} diff --git a/src/com/massivecraft/massivecore/store/cleanable/CleaningUtil.java b/src/com/massivecraft/massivecore/store/cleanable/CleaningUtil.java new file mode 100644 index 00000000..92d052f3 --- /dev/null +++ b/src/com/massivecraft/massivecore/store/cleanable/CleaningUtil.java @@ -0,0 +1,87 @@ +package com.massivecraft.massivecore.store.cleanable; + +import com.massivecraft.massivecore.mixin.MixinMessage; +import com.massivecraft.massivecore.store.Coll; +import com.massivecraft.massivecore.store.Entity; +import com.massivecraft.massivecore.util.MUtil; +import com.massivecraft.massivecore.util.TimeUnit; +import com.massivecraft.massivecore.util.Txt; +import org.bukkit.command.CommandSender; + +import java.util.Collection; + +public class CleaningUtil +{ + // -------------------------------------------- // + // WHAT DO WE HANDLE? + // -------------------------------------------- // + + // The standard used for non-crucial data that can easily be replaced. + public static final long CLEAN_INACTIVITY_TOLERANCE_MILLIS_STANDARD = 3 * TimeUnit.MILLIS_PER_MONTH; + + // The standard for important information that can not easily be replaced. + public static final long CLEAN_INACTIVITY_TOLERANCE_MILLIS_IMPORTANT = 15 * TimeUnit.MILLIS_PER_MONTH; + + // -------------------------------------------- // + // LOGIC + // -------------------------------------------- // + + public static void considerClean(final Coll coll, final Iterable recipients) + { + considerClean(System.currentTimeMillis(), coll, recipients); + } + + public static void considerClean(long now, final Coll coll, final Iterable recipients) + { + final long start = System.nanoTime(); + int count = 0; + + final Collection> entities = coll.getAll(); + + // For each entity ... + for (Entity entity : entities) + { + // ... see if they should be cleaned. + boolean result = considerClean(now, entity); + if (result) count++; + } + + long nano = System.nanoTime() - start; + int current = coll.getIds().size(); + int total = current + count; + double percentage = (((double) count) / total) * 100D; + if (!MUtil.isFinite(percentage)) percentage = 0D; + String message = Txt.parse("Removed %d/%d (%.2f%%) entities from %s took %.2fms.", count, total, percentage, coll.getName(), nano/1000D); + for (CommandSender recipient : recipients) + { + MixinMessage.get().messageOne(recipient, message); + } + } + + public static boolean considerClean(long now, Entity entity) + { + if (entity.detached()) return false; + + // Consider + if (!shouldBeCleaned(now, entity)) return false; + + // Apply + clean(entity); + + return true; + } + + public static void clean(Entity entity) + { + ((Cleanable) entity).preClean(); + entity.detach(); + ((Cleanable) entity).postClean(); + } + + public static boolean shouldBeCleaned(long now, Entity entity) + { + if (!(entity instanceof Cleanable)) return false; + return ((Cleanable) entity).shouldBeCleaned(now); + } + +} diff --git a/src/com/massivecraft/massivecore/store/inactive/Inactive.java b/src/com/massivecraft/massivecore/store/inactive/Inactive.java deleted file mode 100644 index a4f8e6c0..00000000 --- a/src/com/massivecraft/massivecore/store/inactive/Inactive.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.massivecraft.massivecore.store.inactive; - -public interface Inactive -{ - long getLastActivityMillis(); -} diff --git a/src/com/massivecraft/massivecore/store/inactive/InactiveUtil.java b/src/com/massivecraft/massivecore/store/inactive/InactiveUtil.java deleted file mode 100644 index d5a6c6e8..00000000 --- a/src/com/massivecraft/massivecore/store/inactive/InactiveUtil.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.massivecraft.massivecore.store.inactive; - -import com.massivecraft.massivecore.event.EventMassiveCorePlayercleanToleranceMillis; -import com.massivecraft.massivecore.mixin.MixinMessage; -import com.massivecraft.massivecore.store.SenderColl; -import com.massivecraft.massivecore.store.SenderEntity; -import org.bukkit.command.CommandSender; - -import java.util.Collection; - -public class InactiveUtil -{ - public static void considerRemoveInactive(final SenderColl> coll, final Iterable recipients) - { - considerRemoveInactive(System.currentTimeMillis(), coll, recipients); - } - - public static void considerRemoveInactive(long now, final SenderColl> coll, final Iterable recipients) - { - final long playercleanToleranceMillis = coll.getPlayercleanToleranceMillis(); - if (playercleanToleranceMillis <= 0) - { - for (CommandSender recipient : recipients) - { - MixinMessage.get().msgOne(recipient, "%s does not support player cleaning.", coll.getName()); - } - return; - } - - final long start = System.currentTimeMillis(); - int count = 0; - - final Collection> senderEntitiesOffline = coll.getAllOffline(); - - // For each offline player ... - for (SenderEntity entity : senderEntitiesOffline) - { - // ... see if they should be removed. - boolean result = considerRemoveInactive(now, entity, recipients); - if (result) count++; - } - - long time = System.currentTimeMillis() - start; - for (CommandSender recipient : recipients) - { - int current = coll.getIds().size(); - int total = current + count; - double percentage = (((double) count) / total) * 100D; - MixinMessage.get().msgOne(recipient, "Removed %d/%d (%.2f%%) players from %s took %dms.", count, total, percentage, coll.getName(), time); - } - } - - public static boolean considerRemoveInactive(long now, SenderEntity entity, Iterable recipients) - { - if ( ! (entity instanceof Inactive)) return false; - if (entity.detached()) return false; - - // Consider - if (!shouldBeRemoved(now, entity)) return false; - - //String message = Txt.parse("Player %s with id %s was removed due to inactivity.", entity.getName(), entity.getId()); - - // Apply - entity.detach(); - - return true; - } - - public static boolean shouldBeRemoved(long now, SenderEntity entity) - { - EventMassiveCorePlayercleanToleranceMillis event = new EventMassiveCorePlayercleanToleranceMillis(now, entity); - event.run(); - return event.shouldBeRemoved(); - } - -}