CmdRank changed to allow faction change.

Admins can now change a players faction when doing /f rank
This commit is contained in:
Magnus Ulf 2015-01-12 21:53:36 +01:00 committed by Olof Larsson
parent 48a8e81113
commit 262d1f2efa
5 changed files with 203 additions and 146 deletions

View File

@ -116,6 +116,11 @@ public enum Rel
return this.value > rel.value; return this.value > rel.value;
} }
public boolean isRank()
{
return this.isAtLeast(Rel.RECRUIT);
}
public ChatColor getColor() public ChatColor getColor()
{ {
if (this.isAtLeast(RECRUIT)) if (this.isAtLeast(RECRUIT))

View File

@ -1,10 +1,12 @@
package com.massivecraft.factions.cmd; package com.massivecraft.factions.cmd;
import java.util.List; import java.util.HashSet;
import java.util.Set;
import com.massivecraft.factions.Factions; import com.massivecraft.factions.Factions;
import com.massivecraft.factions.Perm; import com.massivecraft.factions.Perm;
import com.massivecraft.factions.Rel; import com.massivecraft.factions.Rel;
import com.massivecraft.factions.cmd.arg.ARFaction;
import com.massivecraft.factions.cmd.arg.ARMPlayer; import com.massivecraft.factions.cmd.arg.ARMPlayer;
import com.massivecraft.factions.cmd.arg.ARRank; import com.massivecraft.factions.cmd.arg.ARRank;
import com.massivecraft.factions.entity.Faction; import com.massivecraft.factions.entity.Faction;
@ -12,11 +14,11 @@ import com.massivecraft.factions.entity.MConf;
import com.massivecraft.factions.entity.MFlag; import com.massivecraft.factions.entity.MFlag;
import com.massivecraft.factions.entity.MPlayer; import com.massivecraft.factions.entity.MPlayer;
import com.massivecraft.factions.entity.MPlayerColl; import com.massivecraft.factions.entity.MPlayerColl;
import com.massivecraft.factions.event.EventFactionsMembershipChange;
import com.massivecraft.factions.event.EventFactionsMembershipChange.MembershipChangeReason;
import com.massivecraft.factions.event.EventFactionsRankChange; import com.massivecraft.factions.event.EventFactionsRankChange;
import com.massivecraft.massivecore.MassiveException; import com.massivecraft.massivecore.MassiveException;
import com.massivecraft.massivecore.cmd.req.ReqHasPerm; import com.massivecraft.massivecore.cmd.req.ReqHasPerm;
import com.massivecraft.massivecore.util.IdUtil;
import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.util.Txt; import com.massivecraft.massivecore.util.Txt;
public class CmdFactionsRank extends FactionsCommand public class CmdFactionsRank extends FactionsCommand
@ -37,7 +39,11 @@ public class CmdFactionsRank extends FactionsCommand
private Faction targetFaction = null; private Faction targetFaction = null;
private MPlayer target = null; private MPlayer target = null;
// Roles // End faction (the faction they are changed to)
private Faction endFaction = null;
private boolean factionChange = false;
// Ranks
private Rel senderRank = null; private Rel senderRank = null;
private Rel targetRank = null; private Rel targetRank = null;
private Rel rank = null; private Rel rank = null;
@ -52,8 +58,9 @@ public class CmdFactionsRank extends FactionsCommand
this.addAliases("rank"); this.addAliases("rank");
// Args // Args
this.addOptionalArg("player", "you"); this.addRequiredArg("player");
this.addOptionalArg("action", "show"); this.addOptionalArg("action", "show");
this.addOptionalArg("faction", "their");
// Requirements // Requirements
this.addRequirements(ReqHasPerm.get(Perm.RANK.node)); this.addRequirements(ReqHasPerm.get(Perm.RANK.node));
@ -66,41 +73,32 @@ public class CmdFactionsRank extends FactionsCommand
@Override @Override
public void perform() throws MassiveException public void perform() throws MassiveException
{ {
// This sets target and much other. Returns false if not succeeded. // This sets target and much other.
if ( ! this.registerFields()) this.registerFields();
{
return;
}
// Sometimes we just want to show the rank. // Sometimes we just want to show the rank.
if ( ! this.argIsSet(1)) if ( ! this.argIsSet(1))
{ {
if ( ! Perm.RANK_SHOW.has(sender, true)) if ( ! Perm.RANK_SHOW.has(sender, true)) return;
{
return;
}
this.showRank(); this.showRank();
return; return;
} }
// Permission check. // Permission check.
if ( ! Perm.RANK_ACTION.has(sender, true)) if ( ! Perm.RANK_ACTION.has(sender, true)) return;
{
return;
}
// Is the player allowed or not. Method can be found later down. // Is the player allowed or not. Method can be found later down.
if ( ! this.isPlayerAllowed()) this.ensureAllowed();
{
return; if (factionChange)
{
this.changeFaction();
} }
// Does the change make sense. // Does the change make sense.
if ( ! this.isChangeRequired()) this.ensureMakesSense();
{
return;
}
// Event
EventFactionsRankChange event = new EventFactionsRankChange(sender, target, rank); EventFactionsRankChange event = new EventFactionsRankChange(sender, target, rank);
event.run(); event.run();
if (event.isCancelled()) return; if (event.isCancelled()) return;
@ -109,7 +107,7 @@ public class CmdFactionsRank extends FactionsCommand
// Change the rank. // Change the rank.
this.changeRank(); this.changeRank();
} }
// This is always run after performing a MassiveCommand. // This is always run after performing a MassiveCommand.
@Override @Override
public void unsetSenderVars() public void unsetSenderVars()
@ -119,28 +117,28 @@ public class CmdFactionsRank extends FactionsCommand
} }
// -------------------------------------------- // // -------------------------------------------- //
// PRIVATE // PRIVATE: REGISTER & UNREGISTER
// -------------------------------------------- // // -------------------------------------------- //
private boolean registerFields() throws MassiveException private void registerFields() throws MassiveException
{ {
// Getting the target and faction. // Getting the target and faction.
target = this.arg(0, ARMPlayer.getAny(), msender); target = this.arg(0, ARMPlayer.getAny(), msender);
if (null == target) return false;
targetFaction = target.getFaction(); targetFaction = target.getFaction();
// Rank if any passed. // Rank if any passed.
if (this.argIsSet(1)) if (this.argIsSet(1))
{ {
rank = this.arg(1, ARRank.get(target.getRole())); rank = this.arg(1, ARRank.get(target.getRole()));
if (null == rank) return false;
} }
// Changing peoples faction.
endFaction = this.arg(2, ARFaction.get(), targetFaction);
factionChange = (endFaction != targetFaction);
// Ranks // Ranks
senderRank = msender.getRole(); senderRank = msender.getRole();
targetRank = target.getRole(); targetRank = target.getRole();
return true;
} }
private void unregisterFields() private void unregisterFields()
@ -152,58 +150,45 @@ public class CmdFactionsRank extends FactionsCommand
targetRank = null; targetRank = null;
rank = null; rank = null;
} }
private void showRank()
{
String targetName = target.describeTo(msender, true);
String isAre = target == msender ? "are" : "is";
String theAan = targetRank == Rel.LEADER ? "the" : Txt.aan(targetRank.name());
String rankName = Txt.getNicedEnum(targetRank).toLowerCase();
String ofIn = targetRank == Rel.LEADER ? "of" : "in";
String factionName = targetFaction.describeTo(msender, true);
if (targetFaction == msenderFaction)
{
factionName = factionName.toLowerCase();
}
msg("%s <i>%s %s <h>%s <i>%s %s<i>.", targetName, isAre, theAan, rankName, ofIn, factionName);
}
private boolean isPlayerAllowed() // -------------------------------------------- //
// PRIVATE: ENSURE
// -------------------------------------------- //
private void ensureAllowed() throws MassiveException
{ {
// People with permission don't follow the normal rules. // People with permission don't follow the normal rules.
if (msender.isUsingAdminMode()) if (msender.isUsingAdminMode()) return;
{
return true;
}
// If somone gets the leadership of wilderness (Which has happened before). // If somone gets the leadership of wilderness (Which has happened before).
// We can at least try to limit their powers. // We can at least try to limit their powers.
if (targetFaction.isNone()) if (endFaction.isNone())
{ {
msg("%s <b>doesn't use ranks sorry :(", targetFaction.getName() ); throw new MassiveException().addMsg("%s <b>doesn't use ranks sorry :(", targetFaction.getName() );
return false;
}
if (targetFaction != msenderFaction)
{
// Don't change ranks outside of your faction.
msg("%s <b>is not in the same faction as you.", target.describeTo(msender));
return false;
} }
if (target == msender) if (target == msender)
{ {
// Don't change your own rank. // Don't change your own rank.
msg("<b>The target player mustn't be yourself."); throw new MassiveException().addMsg("<b>The target player mustn't be yourself.");
return false;
} }
if (targetFaction != msenderFaction)
{
// Don't change ranks outside of your faction.
throw new MassiveException().addMsg("%s <b>is not in the same faction as you.", target.describeTo(msender, true));
}
if (factionChange)
{
// Don't change peoples faction
throw new MassiveException().addMsg("<b>You can't change %s's <b>faction.", target.describeTo(msender));
}
if (senderRank.isLessThan(rankReq)) if (senderRank.isLessThan(rankReq))
{ {
// You need a specific rank to change ranks. // You need a specific rank to change ranks.
msg("<b>You must be %s or higher to change ranks.", Txt.getNicedEnum(rankReq).toLowerCase()); throw new MassiveException().addMsg("<b>You must be <h>%s <b>or higher to change ranks.", Txt.getNicedEnum(rankReq).toLowerCase());
return false;
} }
// The following two if statements could be merged. // The following two if statements could be merged.
@ -211,55 +196,122 @@ public class CmdFactionsRank extends FactionsCommand
if (senderRank == targetRank) if (senderRank == targetRank)
{ {
// You can't change someones rank if it is equal to yours. // You can't change someones rank if it is equal to yours.
msg("<b>%s can't manage eachother.", Txt.getNicedEnum(rankReq)+"s"); throw new MassiveException().addMsg("<h>%s <b>can't manage eachother.", Txt.getNicedEnum(rankReq)+"s");
return false;
} }
if (senderRank.isLessThan(targetRank)) if (senderRank.isLessThan(targetRank))
{ {
// You can't change someones rank if it is higher than yours. // You can't change someones rank if it is higher than yours.
msg("<b>You can't manage people of higher rank."); throw new MassiveException().addMsg("<b>You can't manage people of higher rank.");
return false;
} }
if (senderRank.isAtMost(rank) && senderRank != Rel.LEADER) // The following two if statements could be merged.
// But isn't for the sake of nicer error messages.
if (senderRank == rank && senderRank != Rel.LEADER)
{ {
// You can't set ranks equal to or higer than your own. Unless you are the leader. // You can't set ranks equal to your own. Unless you are the leader.
msg("<b>You can't set ranks higher than or equal to your own."); throw new MassiveException().addMsg("<b>You can't set ranks equal to your own.");
return false;
} }
// If it wasn't cancelled above, player is allowed. if (senderRank.isLessThan(rank))
return true; {
// You can't set ranks higher than your own.
throw new MassiveException().addMsg("<b>You can't set ranks higher than your own.");
}
} }
private boolean isChangeRequired() private void ensureMakesSense() throws MassiveException
{ {
// Just a nice msg. It would however be caught by an if statement below. // Don't change their rank to something they already are.
if (target.getRole() == Rel.RECRUIT && arg(1).equalsIgnoreCase("demote"))
{
msg("%s <b>is already recruit.", target.describeTo(msender));
return false;
}
// Just a nice msg. It would however be caught by an if statement below.
if (target.getRole() == Rel.LEADER && arg(1).equalsIgnoreCase("promote"))
{
msg("%s <b>is already leader.", target.describeTo(msender));
return false;
}
// There must be a change, else it is all waste of time.
if (target.getRole() == rank) if (target.getRole() == rank)
{ {
msg("%s <b>already has that rank.", target.describeTo(msender)); throw new MassiveException().addMsg("%s <b>is already %s<b>.", target.describeTo(msender), rank.getColor() + rank.getDescPlayerOne());
return false;
} }
return true;
} }
private void changeRank() // -------------------------------------------- //
// PRIVATE: SHOW
// -------------------------------------------- //
private void showRank()
{
// Damn you grammar, causing all these checks.
String targetName = target.describeTo(msender, true);
String isAre = (target == msender) ? "are" : "is"; // "you are" or "he is"
String theAan = (targetRank == Rel.LEADER) ? "the" : Txt.aan(targetRank.name()); // "a member", "an officer" or "the leader"
String rankName = Txt.getNicedEnum(targetRank).toLowerCase();
String ofIn = (targetRank == Rel.LEADER) ? "of" : "in"; // "member in" or "leader of"
String factionName = targetFaction.describeTo(msender, true);
if (targetFaction == msenderFaction)
{
// Having the "Y" in "Your faction" being uppercase in the middle of a sentence makes no sense.
factionName = factionName.toLowerCase();
}
if (targetFaction.isNone())
{
// Wilderness aka none doesn't use ranks
msg("%s <i>%s factionless", targetName, isAre);
}
else
{
// Derp is a member in Faction
msg("%s <i>%s %s <h>%s <i>%s %s<i>.", targetName, isAre, theAan, rankName, ofIn, factionName);
}
}
// -------------------------------------------- //
// PRIVATE: CHANGE FACTION
// -------------------------------------------- //
private void changeFaction() throws MassiveException
{
// Don't change a leader to a new faction.
if (targetRank == Rel.LEADER)
{
throw new MassiveException().addMsg("<b>You cannot remove the present leader. Demote them first.");
}
// Event
EventFactionsMembershipChange membershipChangeEvent = new EventFactionsMembershipChange(sender, msender, endFaction, MembershipChangeReason.RANK);
membershipChangeEvent.run();
if (membershipChangeEvent.isCancelled()) throw new MassiveException();
// Apply
target.resetFactionData();
target.setFaction(endFaction);
// No longer invited.
endFaction.setInvited(target, false);
// Create recipients
Set<MPlayer> recipients = new HashSet<MPlayer>();
recipients.addAll(targetFaction.getMPlayersWhereOnline(true));
recipients.addAll(endFaction.getMPlayersWhereOnline(true));
recipients.add(msender);
// Send message
for (MPlayer recipient : recipients)
{
recipient.msg("%s <i>was moved from <i>%s to <i>%s<i>.", target.describeTo(recipient), targetFaction.describeTo(recipient), endFaction.describeTo(recipient));
}
// Derplog
if (MConf.get().logFactionJoin)
{
Factions.get().log(Txt.parse("%s moved %s from %s to %s.", msender.getName(), target.getName(), targetFaction.getName(), endFaction.getName()));
}
// Now we don't need the old values.
targetFaction = target.getFaction();
targetRank = target.getRole();
senderRank = msender.getRole(); // In case they changed their own rank
}
// -------------------------------------------- //
// PRIVATE: CHANGE RANK
// -------------------------------------------- //
private void changeRank() throws MassiveException
{ {
// In case of leadership change, we do special things not done in other rank changes. // In case of leadership change, we do special things not done in other rank changes.
if (rank == Rel.LEADER) if (rank == Rel.LEADER)
@ -287,18 +339,10 @@ public class CmdFactionsRank extends FactionsCommand
} }
} }
// Inform & promote the new leader. // Promote the new leader.
target.setRole(Rel.LEADER); target.setRole(Rel.LEADER);
if (target != msender)
{ // Inform everyone, this includes sender and target.
// They kinda know if they fired the command themself.
target.msg("<i>You have been promoted to the position of faction leader by %s<i>.", msender.describeTo(target, true));
}
// Inform the msg sender
msg("<i>You have promoted %s<i> to the position of faction leader.", target.describeTo(msender, true));
// Inform everyone
for (MPlayer recipient : MPlayerColl.get().getAllOnline()) for (MPlayer recipient : MPlayerColl.get().getAllOnline())
{ {
String changerName = senderIsConsole ? "A server admin" : msender.describeTo(recipient); String changerName = senderIsConsole ? "A server admin" : msender.describeTo(recipient);
@ -306,27 +350,28 @@ public class CmdFactionsRank extends FactionsCommand
} }
} }
private void changeRankOther() private void changeRankOther() throws MassiveException
{ {
// If the target is currently the leader and faction isn't permanent... // If the target is currently the leader and faction isn't permanent a new leader should be promoted.
if (targetRank == Rel.LEADER && !MConf.get().permanentFactionsDisableLeaderPromotion && targetFaction.getFlag(MFlag.ID_PERMANENT)) // Sometimes a bug occurs and multiple leaders exist. Then we should be able to demote without promoting new leader
if (targetRank == Rel.LEADER && ( ! MConf.get().permanentFactionsDisableLeaderPromotion || ! targetFaction.getFlag(MFlag.ID_PERMANENT)) && targetFaction.getMPlayersWhereRole(Rel.LEADER).size() == 1)
// This if statement is very long. Should I nest it for readability?
{ {
// ...we must promote a new one. targetFaction.promoteNewLeader(); // This might disband the faction.
targetFaction.promoteNewLeader();
} // So if the faction disbanded...
// But if still no leader exists... if (targetFaction.detached())
if (targetFaction.getLeader() == null && ! targetFaction.getFlag(MFlag.ID_PERMANENT)) {
{ // ... we inform the sender.
// ...we will disband it. target.resetFactionData();
// I'm kinda lazy, so I just make the console perform the command. throw new MassiveException().addMsg("<i>The target was a leader and got demoted. The faction disbanded and no rank was set.");
Factions.get().getOuterCmdFactions().cmdFactionsDisband.execute(IdUtil.getConsole(), MUtil.list( targetFaction.getName() )); }
}
List<MPlayer> recipients = targetFaction.getMPlayers();
if ( ! recipients.contains(msender))
{
recipients.add(msender);
} }
// Create recipients
Set<MPlayer> recipients = new HashSet<MPlayer>();
recipients.addAll(targetFaction.getMPlayers());
recipients.add(msender);
// Were they demoted or promoted? // Were they demoted or promoted?
String change = (rank.isLessThan(targetRank) ? "demoted" : "promoted"); String change = (rank.isLessThan(targetRank) ? "demoted" : "promoted");
@ -336,12 +381,13 @@ public class CmdFactionsRank extends FactionsCommand
String oldRankName = Txt.getNicedEnum(targetRank).toLowerCase(); String oldRankName = Txt.getNicedEnum(targetRank).toLowerCase();
String rankName = Txt.getNicedEnum(rank).toLowerCase(); String rankName = Txt.getNicedEnum(rank).toLowerCase();
// Send message
for(MPlayer recipient : recipients) for(MPlayer recipient : recipients)
{ {
String targetName = target.describeTo(recipient, true); String targetName = target.describeTo(recipient, true);
String wasWere = recipient == target ? "were" : "was"; String wasWere = (recipient == target) ? "were" : "was";
recipient.msg("%s<i> %s %s from %s to <h>%s <i>in %s<i>.", targetName, wasWere, change, oldRankName, rankName, targetFaction.describeTo(msender)); recipient.msg("%s<i> %s %s from %s to <h>%s <i>in %s<i>.", targetName, wasWere, change, oldRankName, rankName, targetFaction.describeTo(msender));
} }
} }
} }

View File

@ -26,6 +26,7 @@ public class CmdFactionsRankOld extends FactionsCommand
// Args // Args
this.addRequiredArg("player"); this.addRequiredArg("player");
this.addOptionalArg("faction", "their");
// VisibilityMode // VisibilityMode
this.setVisibilityMode(VisibilityMode.INVISIBLE); this.setVisibilityMode(VisibilityMode.INVISIBLE);
@ -38,7 +39,7 @@ public class CmdFactionsRankOld extends FactionsCommand
@Override @Override
public void perform() public void perform()
{ {
Factions.get().getOuterCmdFactions().cmdFactionsRank.execute(sender, MUtil.list(this.arg(0), this.rankName)); Factions.get().getOuterCmdFactions().cmdFactionsRank.execute(sender, MUtil.list(this.arg(0), this.rankName, this.arg(1)));
} }
} }

View File

@ -5,8 +5,8 @@ import java.util.Collection;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import com.massivecraft.factions.Rel; import com.massivecraft.factions.Rel;
import com.massivecraft.massivecore.MassiveException;
import com.massivecraft.massivecore.cmd.arg.ARAbstractSelect; import com.massivecraft.massivecore.cmd.arg.ARAbstractSelect;
import com.massivecraft.massivecore.mixin.Mixin;
import com.massivecraft.massivecore.util.MUtil; import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.util.Txt; import com.massivecraft.massivecore.util.Txt;
@ -30,6 +30,8 @@ public class ARRank extends ARAbstractSelect<Rel>
public ARRank(Rel rank) public ARRank(Rel rank)
{ {
if (rank == null) throw new IllegalArgumentException("Do not use null, the default constructor can be used however.");
if ( ! rank.isRank()) throw new IllegalArgumentException(rank + " is not a valid rank");
this.startRank = rank; this.startRank = rank;
} }
@ -43,15 +45,9 @@ public class ARRank extends ARAbstractSelect<Rel>
// -------------------------------------------- // // -------------------------------------------- //
// OVERRIDE // OVERRIDE
// -------------------------------------------- // // -------------------------------------------- //
@Override
public String typename()
{
return "rank";
}
@Override @Override
public Rel select(String arg, CommandSender sender) public Rel select(String arg, CommandSender sender) throws MassiveException
{ {
// This is especially useful when one rank can have aliases. // This is especially useful when one rank can have aliases.
// In the case of promote/demote, // In the case of promote/demote,
@ -65,17 +61,16 @@ public class ARRank extends ARAbstractSelect<Rel>
if (arg.equals("recruit")) return Rel.RECRUIT; if (arg.equals("recruit")) return Rel.RECRUIT;
// No start rank? // No start rank?
if (startRank == null) if (startRank == null && (arg.equals("promote") || arg.equals("demote")))
{ {
// This might happen of the default constructor is used // This might happen if the default constructor is used
Mixin.msgOne(sender, Txt.parse("<b>You can't use promote & demote")); throw new MassiveException().addMsg("<b>You can't use promote & demote.");
return null;
} }
// Promote // Promote
if (arg.equals("promote")) if (arg.equals("promote"))
{ {
if (Rel.LEADER.equals(startRank)) return Rel.LEADER; if (Rel.LEADER.equals(startRank)) throw new MassiveException().addMsg("<b>You can't promote the leader.");
if (Rel.OFFICER.equals(startRank)) return Rel.LEADER; if (Rel.OFFICER.equals(startRank)) return Rel.LEADER;
if (Rel.MEMBER.equals(startRank)) return Rel.OFFICER; if (Rel.MEMBER.equals(startRank)) return Rel.OFFICER;
if (Rel.RECRUIT.equals(startRank)) return Rel.MEMBER; if (Rel.RECRUIT.equals(startRank)) return Rel.MEMBER;
@ -87,7 +82,7 @@ public class ARRank extends ARAbstractSelect<Rel>
if (Rel.LEADER.equals(startRank)) return Rel.OFFICER; if (Rel.LEADER.equals(startRank)) return Rel.OFFICER;
if (Rel.OFFICER.equals(startRank)) return Rel.MEMBER; if (Rel.OFFICER.equals(startRank)) return Rel.MEMBER;
if (Rel.MEMBER.equals(startRank)) return Rel.RECRUIT; if (Rel.MEMBER.equals(startRank)) return Rel.RECRUIT;
if (Rel.RECRUIT.equals(startRank)) return Rel.RECRUIT; if (Rel.RECRUIT.equals(startRank)) throw new MassiveException().addMsg("<b>You can't demote a recruit.");
} }
return null; return null;
@ -106,11 +101,17 @@ public class ARRank extends ARAbstractSelect<Rel>
); );
} }
@Override
public String typename()
{
return "rank";
}
// -------------------------------------------- // // -------------------------------------------- //
// PRIVATE // ARG
// -------------------------------------------- // // -------------------------------------------- //
private String prepareArg(String str) public String prepareArg(String str)
{ {
String ret = str.toLowerCase(); String ret = str.toLowerCase();
@ -122,7 +123,7 @@ public class ARRank extends ARAbstractSelect<Rel>
{ {
ret = "officer"; ret = "officer";
} }
else if (ret.startsWith("mem")) else if (ret.startsWith("mem") || ret.startsWith("nor"))
{ {
ret = "member"; ret = "member";
} }
@ -141,4 +142,5 @@ public class ARRank extends ARAbstractSelect<Rel>
return ret; return ret;
} }
} }

View File

@ -57,7 +57,10 @@ public class EventFactionsMembershipChange extends EventFactionsAbstractSender
// Join // Join
JOIN (true), JOIN (true),
CREATE (false), CREATE (false),
// Leader is not used, but temporarily kept to avoid other plugins crashing
@Deprecated
LEADER (true), LEADER (true),
RANK (true),
// Leave // Leave
LEAVE (true), LEAVE (true),