diff --git a/src/com/massivecraft/factions/FPlayer.java b/src/com/massivecraft/factions/FPlayer.java index 0b6081ae..d73d91dd 100644 --- a/src/com/massivecraft/factions/FPlayer.java +++ b/src/com/massivecraft/factions/FPlayer.java @@ -575,6 +575,13 @@ public class FPlayer extends PlayerEntity implements EconomyParticipator public void leave(boolean makePay) { Faction myFaction = this.getFaction(); + + if (myFaction == null) + { + resetFactionData(); + return; + } + boolean perm = myFaction.isPermanent(); if (!perm && this.getRole() == Role.ADMIN && myFaction.getFPlayers().size() > 1) diff --git a/src/com/massivecraft/factions/FPlayers.java b/src/com/massivecraft/factions/FPlayers.java index 08d5b94d..d9a160d1 100644 --- a/src/com/massivecraft/factions/FPlayers.java +++ b/src/com/massivecraft/factions/FPlayers.java @@ -7,6 +7,7 @@ import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.CopyOnWriteArrayList; import com.google.gson.reflect.TypeToken; +import com.massivecraft.factions.struct.Role; import com.massivecraft.factions.zcore.persist.PlayerEntityCollection; public class FPlayers extends PlayerEntityCollection @@ -61,6 +62,13 @@ public class FPlayers extends PlayerEntityCollection { if (now - fplayer.getLastLoginTime() > toleranceMillis) { + if (Conf.logFactionLeave || Conf.logFactionKick) + P.p.log("Player "+fplayer.getName()+" was auto-removed due to inactivity."); + + // if player is faction admin, sort out the faction since he's going away + if (fplayer.getRole() == Role.ADMIN) + fplayer.getFaction().promoteNewLeader(); + fplayer.leave(false); fplayer.markForDeletion(true); } diff --git a/src/com/massivecraft/factions/Faction.java b/src/com/massivecraft/factions/Faction.java index 1024e78d..45472c16 100644 --- a/src/com/massivecraft/factions/Faction.java +++ b/src/com/massivecraft/factions/Faction.java @@ -56,7 +56,7 @@ public class Faction extends Entity implements EconomyParticipator // FIELD: permanent // "permanent" status can only be set by server admins/moderators/ops, and allows the faction to remain even with 0 members private boolean permanent; - public boolean isPermanent() { return permanent; } + public boolean isPermanent() { return permanent || !this.isNormal(); } public void setPermanent(boolean isPermanent) { permanent = isPermanent; } // FIELD: tag @@ -432,9 +432,48 @@ public class Faction extends Entity implements EconomyParticipator lastPlayerLoggedOffTime = System.currentTimeMillis(); } } - - - + + // used when current leader is about to be removed from the faction; promotes new leader, or disbands faction if no other members left + public void promoteNewLeader() + { + if (! this.isNormal()) return; + + FPlayer oldLeader = this.getFPlayerAdmin(); + + // get list of moderators, or list of normal members if there are no moderators + ArrayList replacements = this.getFPlayersWhereRole(Role.MODERATOR); + if (replacements == null || replacements.isEmpty()) + replacements = this.getFPlayersWhereRole(Role.NORMAL); + + if (replacements == null || replacements.isEmpty()) + { // faction admin is the only member; one-man faction + if (this.isPermanent()) + { + oldLeader.setRole(Role.NORMAL); + return; + } + + // no members left and faction isn't permanent, so disband it + if (Conf.logFactionDisband) + P.p.log("The faction "+this.getTag()+" ("+this.getId()+") has been disbanded since it has no members left."); + + for (FPlayer fplayer : FPlayers.i.getOnline()) + { + fplayer.msg("The faction %s was disbanded.", this.getTag(fplayer)); + } + + this.detach(); + } + else + { // promote new faction admin + oldLeader.setRole(Role.NORMAL); + replacements.get(0).setRole(Role.ADMIN); + this.msg("Faction admin %s has been removed. %s has been promoted as the new faction admin.", oldLeader.getName(), replacements.get(0).getName()); + P.p.log("Faction "+this.getTag()+" ("+this.getId()+") admin was removed. Replacement admin: "+replacements.get(0).getName()); + } + } + + //----------------------------------------------// // Messages //----------------------------------------------// diff --git a/src/com/massivecraft/factions/cmd/CmdKick.java b/src/com/massivecraft/factions/cmd/CmdKick.java index 2318a855..7e32701d 100644 --- a/src/com/massivecraft/factions/cmd/CmdKick.java +++ b/src/com/massivecraft/factions/cmd/CmdKick.java @@ -6,6 +6,7 @@ import com.massivecraft.factions.FPlayers; import com.massivecraft.factions.Faction; import com.massivecraft.factions.P; import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Role; public class CmdKick extends FCommand { @@ -75,24 +76,14 @@ public class CmdKick extends FCommand fme.msg("You kicked %s from the faction %s!", you.describeTo(fme), yourFaction.describeTo(fme)); } + if (Conf.logFactionKick) + P.p.log((senderIsConsole ? "A console command" : fme.getName())+" kicked "+you.getName()+" from the faction: "+yourFaction.getTag()); + + if (you.getRole() == Role.ADMIN) + yourFaction.promoteNewLeader(); + yourFaction.deinvite(you); you.resetFactionData(); - - if (Conf.logFactionKick) - P.p.log(fme.getName()+" kicked "+you.getName()+" from the faction: "+yourFaction.getTag()); - - if (yourFaction.getFPlayers().isEmpty() && !yourFaction.isPermanent()) - { - // Remove this faction - for (FPlayer fplayer : FPlayers.i.getOnline()) - { - fplayer.msg("The faction %s was disbanded.", yourFaction.getTag(fplayer)); - } - yourFaction.detach(); - - if (Conf.logFactionDisband) - P.p.log("The faction "+yourFaction.getTag()+" ("+yourFaction.getId()+") was disbanded since the last player was kicked by "+(senderIsConsole ? "console command" : fme.getName())+"."); - } } - + } diff --git a/src/com/massivecraft/factions/listeners/FactionsPlayerListener.java b/src/com/massivecraft/factions/listeners/FactionsPlayerListener.java index 6191ff86..61bedb77 100644 --- a/src/com/massivecraft/factions/listeners/FactionsPlayerListener.java +++ b/src/com/massivecraft/factions/listeners/FactionsPlayerListener.java @@ -33,6 +33,7 @@ import com.massivecraft.factions.P; import com.massivecraft.factions.integration.SpoutFeatures; import com.massivecraft.factions.struct.Permission; import com.massivecraft.factions.struct.Relation; +import com.massivecraft.factions.struct.Role; import com.massivecraft.factions.zcore.util.TextUtil; import java.util.logging.Level; @@ -620,6 +621,9 @@ public class FactionsPlayerListener extends PlayerListener // if player was banned (not just kicked), get rid of their stored info if (Conf.removePlayerDataWhenBanned && event.getReason().equals("Banned by admin.")) { + if (badGuy.getRole() == Role.ADMIN) + badGuy.getFaction().promoteNewLeader(); + badGuy.leave(false); badGuy.markForDeletion(true); }