diff --git a/src/com/massivecraft/factions/FPlayer.java b/src/com/massivecraft/factions/FPlayer.java index 272415be..e855303b 100644 --- a/src/com/massivecraft/factions/FPlayer.java +++ b/src/com/massivecraft/factions/FPlayer.java @@ -462,6 +462,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.getFlag(FFlag.PERMANENT); if (!perm && this.getRole() == Rel.LEADER && myFaction.getFPlayers().size() > 1) diff --git a/src/com/massivecraft/factions/FPlayers.java b/src/com/massivecraft/factions/FPlayers.java index d21d3bde..d2148861 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.Rel; 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 leader, sort out the faction since he's going away + if (fplayer.getRole() == Rel.LEADER) + fplayer.getFaction().promoteNewLeader(); + fplayer.leave(false); } } diff --git a/src/com/massivecraft/factions/Faction.java b/src/com/massivecraft/factions/Faction.java index cfe05c4a..3d0143dd 100644 --- a/src/com/massivecraft/factions/Faction.java +++ b/src/com/massivecraft/factions/Faction.java @@ -415,7 +415,47 @@ public class Faction extends Entity implements EconomyParticipator return ret; } - + + // 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.getFPlayerLeader(); + + // get list of officers, or list of normal members if there are no officers + ArrayList replacements = this.getFPlayersWhereRole(Rel.OFFICER); + if (replacements == null || replacements.isEmpty()) + replacements = this.getFPlayersWhereRole(Rel.MEMBER); + + if (replacements == null || replacements.isEmpty()) + { // faction leader is the only member; one-man faction + if (this.getFlag(FFlag.PERMANENT)) + { + oldLeader.setRole(Rel.MEMBER); + 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 leader + oldLeader.setRole(Rel.MEMBER); + replacements.get(0).setRole(Rel.LEADER); + this.msg("Faction leader %s has been removed. %s has been promoted as the new faction leader.", oldLeader.getName(), replacements.get(0).getName()); + P.p.log("Faction "+this.getTag()+" ("+this.getId()+") leader was removed. Replacement leader: "+replacements.get(0).getName()); + } + } + //----------------------------------------------// // Messages //----------------------------------------------// diff --git a/src/com/massivecraft/factions/cmd/CmdKick.java b/src/com/massivecraft/factions/cmd/CmdKick.java index 87993e20..544bdaf7 100644 --- a/src/com/massivecraft/factions/cmd/CmdKick.java +++ b/src/com/massivecraft/factions/cmd/CmdKick.java @@ -8,6 +8,7 @@ import com.massivecraft.factions.P; import com.massivecraft.factions.struct.FFlag; import com.massivecraft.factions.struct.FPerm; import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Rel; public class CmdKick extends FCommand { @@ -62,24 +63,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() == Rel.LEADER) + 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.getFlag(FFlag.PERMANENT)) - { - // 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 18203a57..bd4d33bb 100644 --- a/src/com/massivecraft/factions/listeners/FactionsPlayerListener.java +++ b/src/com/massivecraft/factions/listeners/FactionsPlayerListener.java @@ -418,6 +418,8 @@ 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() == Rel.LEADER) + badGuy.getFaction().promoteNewLeader(); badGuy.leave(false); } }