diff --git a/src/com/massivecraft/factions/cmd/CmdFactionsPlayer.java b/src/com/massivecraft/factions/cmd/CmdFactionsPlayer.java index 332efd15..3be670c9 100644 --- a/src/com/massivecraft/factions/cmd/CmdFactionsPlayer.java +++ b/src/com/massivecraft/factions/cmd/CmdFactionsPlayer.java @@ -3,9 +3,9 @@ package com.massivecraft.factions.cmd; import com.massivecraft.factions.cmd.type.TypeMPlayer; import com.massivecraft.factions.entity.MConf; import com.massivecraft.factions.entity.MPlayer; -import com.massivecraft.factions.event.EventFactionsRemovePlayerMillis; import com.massivecraft.massivecore.MassiveException; import com.massivecraft.massivecore.Progressbar; +import com.massivecraft.massivecore.event.EventMassiveCorePlayercleanToleranceMillis; import com.massivecraft.massivecore.util.TimeDiffUtil; import com.massivecraft.massivecore.util.TimeUnit; import com.massivecraft.massivecore.util.Txt; @@ -80,12 +80,12 @@ public class CmdFactionsPlayer extends FactionsCommand msg("Power per Death: %.2f", mplayer.getPowerPerDeath()); // Display automatic kick / remove info if the system is in use - if (MConf.get().removePlayerMillisDefault <= 0) return; + if (MConf.get().playercleanToleranceMillis <= 0) return; - EventFactionsRemovePlayerMillis event = new EventFactionsRemovePlayerMillis(false, mplayer); + EventMassiveCorePlayercleanToleranceMillis event = new EventMassiveCorePlayercleanToleranceMillis(mplayer); event.run(); - msg("Automatic removal after %s of inactivity:", format(event.getMillis())); - for (Entry causeMillis : event.getCauseMillis().entrySet()) + msg("Automatic removal after %s of inactivity:", format(event.getToleranceMillis())); + for (Entry causeMillis : event.getToleranceCauseMillis().entrySet()) { String cause = causeMillis.getKey(); long millis = causeMillis.getValue(); diff --git a/src/com/massivecraft/factions/engine/EnginePlayerclean.java b/src/com/massivecraft/factions/engine/EnginePlayerclean.java new file mode 100644 index 00000000..1b292964 --- /dev/null +++ b/src/com/massivecraft/factions/engine/EnginePlayerclean.java @@ -0,0 +1,97 @@ +package com.massivecraft.factions.engine; + +import com.massivecraft.factions.entity.Faction; +import com.massivecraft.factions.entity.MConf; +import com.massivecraft.factions.entity.MPlayer; +import com.massivecraft.factions.entity.MPlayerColl; +import com.massivecraft.massivecore.Engine; +import com.massivecraft.massivecore.event.EventMassiveCorePlayercleanToleranceMillis; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; + +import java.util.Map; +import java.util.Map.Entry; + +public class EnginePlayerclean extends Engine +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static EnginePlayerclean i = new EnginePlayerclean(); + public static EnginePlayerclean get() { return i; } + + // -------------------------------------------- // + // REMOVE PLAYER MILLIS + // -------------------------------------------- // + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void ageBonus(EventMassiveCorePlayercleanToleranceMillis event) + { + if (event.getColl() != MPlayerColl.get()) return; + + applyPlayerAgeBonus(event); + applyFactionAgeBonus(event); + } + + public void applyPlayerAgeBonus(EventMassiveCorePlayercleanToleranceMillis event) + { + // Calculate First Played + Long firstPlayed = event.getEntity().getFirstPlayed(); + Long age = 0L; + if (firstPlayed != null) + { + age = System.currentTimeMillis() - firstPlayed; + } + + // Calculate the Bonus! + Long bonus = calculateBonus(age, MConf.get().playercleanToleranceMillisPlayerAgeToBonus); + if (bonus == null) return; + + // Apply + event.getToleranceCauseMillis().put("Player Age Bonus", bonus); + } + + public void applyFactionAgeBonus(EventMassiveCorePlayercleanToleranceMillis event) + { + // Calculate Faction Age + Faction faction = ((MPlayer)event.getEntity()).getFaction(); + long age = 0L; + if ( ! faction.isNone()) + { + age = faction.getAge(); + } + + // Calculate the Bonus! + Long bonus = calculateBonus(age, MConf.get().playercleanToleranceMillisFactionAgeToBonus); + if (bonus == null) return; + + // Apply + event.getToleranceCauseMillis().put("Faction Age Bonus", bonus); + } + + private Long calculateBonus(long age, Map ageToBonus) + { + if (ageToBonus.isEmpty()) return null; + + Long bonus = 0L; + for (Entry entry : ageToBonus.entrySet()) + { + Long key = entry.getKey(); + if (key == null) continue; + + Long value = entry.getValue(); + if (value == null) continue; + + if (age >= key) + { + bonus = value; + break; + } + } + + return bonus; + } + + +} diff --git a/src/com/massivecraft/factions/entity/Faction.java b/src/com/massivecraft/factions/entity/Faction.java index dc01c1b1..48a3e5e4 100644 --- a/src/com/massivecraft/factions/entity/Faction.java +++ b/src/com/massivecraft/factions/entity/Faction.java @@ -351,6 +351,16 @@ public class Faction extends Entity implements FactionsParticipator this.changed(); } + public long getAge() + { + return this.getAge(System.currentTimeMillis()); + } + + public long getAge(long now) + { + return now - this.getCreatedAtMillis(); + } + // -------------------------------------------- // // FIELD: home // -------------------------------------------- // diff --git a/src/com/massivecraft/factions/entity/MConf.java b/src/com/massivecraft/factions/entity/MConf.java index 87860110..a4ad12a4 100644 --- a/src/com/massivecraft/factions/entity/MConf.java +++ b/src/com/massivecraft/factions/entity/MConf.java @@ -60,7 +60,7 @@ public class MConf extends Entity // VERSION // -------------------------------------------- // - public int version = 1; + public int version = 2; // -------------------------------------------- // // COMMAND ALIASES @@ -111,17 +111,17 @@ public class MConf extends Entity // The Default @EditorType(TypeMillisDiff.class) - public long removePlayerMillisDefault = 10 * TimeUnit.MILLIS_PER_DAY; // 10 days + public long playercleanToleranceMillis = 10 * TimeUnit.MILLIS_PER_DAY; // 10 days // Player Age Bonus @EditorTypeInner({TypeMillisDiff.class, TypeMillisDiff.class}) - public Map removePlayerMillisPlayerAgeToBonus = MUtil.map( + public Map playercleanToleranceMillisPlayerAgeToBonus = MUtil.map( 2 * TimeUnit.MILLIS_PER_WEEK, 10 * TimeUnit.MILLIS_PER_DAY // +10 days after 2 weeks ); // Faction Age Bonus @EditorTypeInner({TypeMillisDiff.class, TypeMillisDiff.class}) - public Map removePlayerMillisFactionAgeToBonus = MUtil.map( + public Map playercleanToleranceMillisFactionAgeToBonus = MUtil.map( 4 * TimeUnit.MILLIS_PER_WEEK, 10 * TimeUnit.MILLIS_PER_DAY, // +10 days after 4 weeks 2 * TimeUnit.MILLIS_PER_WEEK, 5 * TimeUnit.MILLIS_PER_DAY // +5 days after 2 weeks ); diff --git a/src/com/massivecraft/factions/entity/MPlayer.java b/src/com/massivecraft/factions/entity/MPlayer.java index 94571614..07d26725 100644 --- a/src/com/massivecraft/factions/entity/MPlayer.java +++ b/src/com/massivecraft/factions/entity/MPlayer.java @@ -11,7 +11,6 @@ import com.massivecraft.factions.event.EventFactionsChunksChange; import com.massivecraft.factions.event.EventFactionsDisband; import com.massivecraft.factions.event.EventFactionsMembershipChange; import com.massivecraft.factions.event.EventFactionsMembershipChange.MembershipChangeReason; -import com.massivecraft.factions.event.EventFactionsRemovePlayerMillis; import com.massivecraft.factions.mixin.PowerMixin; import com.massivecraft.factions.util.RelationUtil; import com.massivecraft.massivecore.mixin.MixinSenderPs; @@ -19,6 +18,7 @@ import com.massivecraft.massivecore.mixin.MixinTitle; import com.massivecraft.massivecore.ps.PS; import com.massivecraft.massivecore.ps.PSFormatHumanSpace; import com.massivecraft.massivecore.store.SenderEntity; +import com.massivecraft.massivecore.store.inactive.Inactive; import com.massivecraft.massivecore.util.IdUtil; import com.massivecraft.massivecore.util.MUtil; import com.massivecraft.massivecore.util.Txt; @@ -34,7 +34,7 @@ import java.util.Iterator; import java.util.Map.Entry; import java.util.Set; -public class MPlayer extends SenderEntity implements FactionsParticipator +public class MPlayer extends SenderEntity implements FactionsParticipator, Inactive { // -------------------------------------------- // // META @@ -701,57 +701,7 @@ public class MPlayer extends SenderEntity implements FactionsParticipat if (ps == null) return false; return BoardColl.get().getFactionAt(ps).getRelationTo(this) == Rel.ENEMY; } - - // -------------------------------------------- // - // INACTIVITY TIMEOUT - // -------------------------------------------- // - - public long getRemovePlayerMillis(boolean async) - { - EventFactionsRemovePlayerMillis event = new EventFactionsRemovePlayerMillis(async, this); - event.run(); - return event.getMillis(); - } - - public boolean considerRemovePlayerMillis(boolean async) - { - // This may or may not be required. - // Some users have been reporting a loop issue with the same player - // detaching over and over again. - // Maybe skipping ahead if the player is detached will solve the issue. - if (this.detached()) return false; - - // Get the last activity millis. - long lastActivityMillis = this.getLastActivityMillis(); - - // Consider - long toleranceMillis = this.getRemovePlayerMillis(async); - if (System.currentTimeMillis() - lastActivityMillis <= toleranceMillis) return false; - - // Inform - if (MConf.get().logFactionLeave || MConf.get().logFactionKick) - { - Factions.get().log("Player " + this.getName() + " was auto-removed due to inactivity."); - } - - // Apply - - // Promote a new leader if required. - if (this.getRole() == Rel.LEADER) - { - Faction faction = this.getFaction(); - if (faction != null) - { - this.getFaction().promoteNewLeader(); - } - } - - this.leave(); - this.detach(); - - return true; - } - + // -------------------------------------------- // // ACTIONS // -------------------------------------------- // diff --git a/src/com/massivecraft/factions/entity/MPlayerColl.java b/src/com/massivecraft/factions/entity/MPlayerColl.java index 3c8c864a..12e3382d 100644 --- a/src/com/massivecraft/factions/entity/MPlayerColl.java +++ b/src/com/massivecraft/factions/entity/MPlayerColl.java @@ -1,10 +1,6 @@ package com.massivecraft.factions.entity; -import com.massivecraft.factions.Factions; import com.massivecraft.massivecore.store.SenderColl; -import org.bukkit.Bukkit; - -import java.util.Collection; public class MPlayerColl extends SenderColl { @@ -14,6 +10,10 @@ public class MPlayerColl extends SenderColl private static MPlayerColl i = new MPlayerColl(); public static MPlayerColl get() { return i; } + public MPlayerColl() + { + this.setPlayercleanTaskEnabled(true); + } // -------------------------------------------- // // STACK TRACEABILITY @@ -29,29 +29,10 @@ public class MPlayerColl extends SenderColl // EXTRAS // -------------------------------------------- // - public void considerRemovePlayerMillis() + @Override + public long getPlayercleanToleranceMillis() { - // If the config option is 0 or below that means the server owner want it disabled. - if (MConf.get().removePlayerMillisDefault <= 0.0) return; - - // For each of the offline players... - // NOTE: If the player is currently online it's most definitely not inactive. - // NOTE: This check catches some important special cases like the @console "player". - final Collection mplayersOffline = this.getAllOffline(); - - Bukkit.getScheduler().runTaskAsynchronously(Factions.get(), new Runnable() - { - @Override - public void run() - { - // For each offline player ... - for (MPlayer mplayer : mplayersOffline) - { - // ... see if they should be removed. - mplayer.considerRemovePlayerMillis(true); - } - } - }); + return MConf.get().playercleanToleranceMillis; } - + } diff --git a/src/com/massivecraft/factions/entity/migrator/MigratorMConf002Playerclean.java b/src/com/massivecraft/factions/entity/migrator/MigratorMConf002Playerclean.java new file mode 100644 index 00000000..ebc3bbe7 --- /dev/null +++ b/src/com/massivecraft/factions/entity/migrator/MigratorMConf002Playerclean.java @@ -0,0 +1,23 @@ +package com.massivecraft.factions.entity.migrator; + +import com.massivecraft.factions.entity.MConf; +import com.massivecraft.massivecore.store.migrator.MigratorFieldRename; +import com.massivecraft.massivecore.store.migrator.MigratorRoot; + +public class MigratorMConf002Playerclean extends MigratorRoot +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static MigratorMConf002Playerclean i = new MigratorMConf002Playerclean(); + public static MigratorMConf002Playerclean get() { return i; } + private MigratorMConf002Playerclean() + { + super(MConf.class); + this.addInnerMigrator(MigratorFieldRename.get("removePlayerMillisDefault", "playercleanToleranceMillis")); + this.addInnerMigrator(MigratorFieldRename.get("removePlayerMillisPlayerAgeToBonus", "playercleanToleranceMillisPlayerAgeToBonus")); + this.addInnerMigrator(MigratorFieldRename.get("removePlayerMillisFactionAgeToBonus", "playercleanToleranceMillisFactionAgeToBonus")); + } + +} diff --git a/src/com/massivecraft/factions/event/EventFactionsRemovePlayerMillis.java b/src/com/massivecraft/factions/event/EventFactionsRemovePlayerMillis.java deleted file mode 100644 index 1d04dbd2..00000000 --- a/src/com/massivecraft/factions/event/EventFactionsRemovePlayerMillis.java +++ /dev/null @@ -1,138 +0,0 @@ -package com.massivecraft.factions.event; - -import com.massivecraft.factions.entity.Faction; -import com.massivecraft.factions.entity.MConf; -import com.massivecraft.factions.entity.MPlayer; -import com.massivecraft.massivecore.event.EventMassiveCore; -import org.bukkit.event.HandlerList; - -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Map.Entry; - -public class EventFactionsRemovePlayerMillis extends EventMassiveCore -{ - // -------------------------------------------- // - // REQUIRED EVENT CODE - // -------------------------------------------- // - - private static final HandlerList handlers = new HandlerList(); - @Override public HandlerList getHandlers() { return handlers; } - public static HandlerList getHandlerList() { return handlers; } - - // -------------------------------------------- // - // FIELD - // -------------------------------------------- // - - private final MPlayer mplayer; - public MPlayer getMPlayer() { return this.mplayer; } - - private long millis; - public long getMillis() { return this.millis; } - public void setMillis(long millis) { this.millis = millis; } - - private Map causeMillis = new LinkedHashMap<>(); - public Map getCauseMillis() { return this.causeMillis; } - - // -------------------------------------------- // - // CONSTRUCT - // -------------------------------------------- // - - public EventFactionsRemovePlayerMillis(boolean async, MPlayer mplayer) - { - super(async); - - this.mplayer = mplayer; - this.millis = MConf.get().removePlayerMillisDefault; - - // Default - this.causeMillis.put("Default", MConf.get().removePlayerMillisDefault); - - // Player Age Bonus - this.applyPlayerAgeBonus(); - - // Faction Age Bonus - this.applyFactionAgeBonus(); - } - - // -------------------------------------------- // - // UTIL - // -------------------------------------------- // - - public void applyPlayerAgeBonus() - { - // Skip if this bonus is totally disabled. - // We don't want it showing up with 0 for everyone. - if (MConf.get().removePlayerMillisPlayerAgeToBonus.isEmpty()) return; - - // Calculate First Played - Long firstPlayed = this.getMPlayer().getFirstPlayed(); - Long age = 0L; - if (firstPlayed != null) - { - age = System.currentTimeMillis() - firstPlayed; - } - - // Calculate the Bonus! - long bonus = 0; - for (Entry entry : MConf.get().removePlayerMillisPlayerAgeToBonus.entrySet()) - { - Long key = entry.getKey(); - if (key == null) continue; - - Long value = entry.getValue(); - if (value == null) continue; - - if (age >= key) - { - bonus = value; - break; - } - } - - // Apply - this.setMillis(this.getMillis() + bonus); - - // Inform - this.getCauseMillis().put("Player Age Bonus", bonus); - } - - public void applyFactionAgeBonus() - { - // Skip if this bonus is totally disabled. - // We don't want it showing up with 0 for everyone. - if (MConf.get().removePlayerMillisFactionAgeToBonus.isEmpty()) return; - - // Calculate Faction Age - Faction faction = this.getMPlayer().getFaction(); - long age = 0; - if ( ! faction.isNone()) - { - age = System.currentTimeMillis() - faction.getCreatedAtMillis(); - } - - // Calculate the Bonus! - long bonus = 0; - for (Entry entry : MConf.get().removePlayerMillisFactionAgeToBonus.entrySet()) - { - Long key = entry.getKey(); - if (key == null) continue; - - Long value = entry.getValue(); - if (value == null) continue; - - if (age >= key) - { - bonus = value; - break; - } - } - - // Apply - this.setMillis(this.getMillis() + bonus); - - // Inform - this.getCauseMillis().put("Faction Age Bonus", bonus); - } - -} diff --git a/src/com/massivecraft/factions/task/TaskPlayerDataRemove.java b/src/com/massivecraft/factions/task/TaskPlayerDataRemove.java deleted file mode 100644 index fb290b5d..00000000 --- a/src/com/massivecraft/factions/task/TaskPlayerDataRemove.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.massivecraft.factions.task; - -import com.massivecraft.factions.entity.MConf; -import com.massivecraft.factions.entity.MPlayerColl; -import com.massivecraft.massivecore.MassiveCore; -import com.massivecraft.massivecore.ModuloRepeatTask; -import com.massivecraft.massivecore.util.TimeUnit; - -public class TaskPlayerDataRemove extends ModuloRepeatTask -{ - // -------------------------------------------- // - // INSTANCE - // -------------------------------------------- // - - private static TaskPlayerDataRemove i = new TaskPlayerDataRemove(); - public static TaskPlayerDataRemove get() { return i; } - - // -------------------------------------------- // - // OVERRIDE - // -------------------------------------------- // - - @Override - public long getDelayMillis() - { - // The interval is determined by the MConf rather than being set with setDelayMillis. - return (long) (MConf.get().taskPlayerDataRemoveMinutes * TimeUnit.MILLIS_PER_MINUTE); - } - - @Override - public void invoke(long now) - { - // If this is the task server ... - if (!MassiveCore.isTaskServer()) return; - - // ... check players for expiration. - MPlayerColl.get().considerRemovePlayerMillis(); - } - -}