Rank rework
This makes an under the hood rank-rework. Nothing is changed from the player perspective.
This commit is contained in:
		@@ -1,6 +1,7 @@
 | 
			
		||||
package com.massivecraft.factions;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.factions.entity.MConf;
 | 
			
		||||
import com.massivecraft.factions.entity.MPerm;
 | 
			
		||||
import com.massivecraft.massivecore.Colorized;
 | 
			
		||||
import com.massivecraft.massivecore.Named;
 | 
			
		||||
import com.massivecraft.massivecore.collections.MassiveSet;
 | 
			
		||||
@@ -9,7 +10,7 @@ import org.bukkit.ChatColor;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
public enum Rel implements Colorized, Named
 | 
			
		||||
public enum Rel implements Colorized, Named, MPerm.MPermable
 | 
			
		||||
{
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// ENUM
 | 
			
		||||
@@ -34,8 +35,13 @@ public enum Rel implements Colorized, Named
 | 
			
		||||
		"an ally", "allies", "an allied faction", "allied factions",
 | 
			
		||||
		"Ally"
 | 
			
		||||
	) { @Override public ChatColor getColor() { return MConf.get().colorAlly; } },
 | 
			
		||||
 | 
			
		||||
	FACTION(
 | 
			
		||||
			"your faction", "your faction", "your faction", "your faction",
 | 
			
		||||
			"Faction"
 | 
			
		||||
	) { @Override public ChatColor getColor() { return MConf.get().colorMember; } },
 | 
			
		||||
	
 | 
			
		||||
	RECRUIT(
 | 
			
		||||
	/*RECRUIT(
 | 
			
		||||
		"a recruit in your faction", "recruits in your faction", "", "",
 | 
			
		||||
		"Recruit"
 | 
			
		||||
	) { @Override public String getPrefix() { return MConf.get().prefixRecruit; } },
 | 
			
		||||
@@ -53,7 +59,7 @@ public enum Rel implements Colorized, Named
 | 
			
		||||
	LEADER(
 | 
			
		||||
		"your faction leader", "your faction leader", "", "",
 | 
			
		||||
		"Leader", "Admin", "Owner"
 | 
			
		||||
	) { @Override public String getPrefix() { return MConf.get().prefixLeader; } },
 | 
			
		||||
	) { @Override public String getPrefix() { return MConf.get().prefixLeader; } },*/
 | 
			
		||||
	
 | 
			
		||||
	// END OF LIST
 | 
			
		||||
	;
 | 
			
		||||
@@ -102,6 +108,12 @@ public enum Rel implements Colorized, Named
 | 
			
		||||
	{
 | 
			
		||||
		return MConf.get().colorMember;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public String getId()
 | 
			
		||||
	{
 | 
			
		||||
		return name();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// UTIL
 | 
			
		||||
@@ -126,12 +138,7 @@ public enum Rel implements Colorized, Named
 | 
			
		||||
	{
 | 
			
		||||
		return this.getValue() > rel.getValue();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isRank()
 | 
			
		||||
	{
 | 
			
		||||
		return this.isAtLeast(Rel.RECRUIT);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	// Used for friendly fire.
 | 
			
		||||
	public boolean isFriend()
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
@@ -35,6 +35,11 @@ public class RelAdapter implements JsonDeserializer<Rel>
 | 
			
		||||
		{
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
		catch (Exception ex)
 | 
			
		||||
		{
 | 
			
		||||
			System.out.println(json);
 | 
			
		||||
			throw ex;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ public class ChatTagRole extends ChatTag
 | 
			
		||||
		// Get entities
 | 
			
		||||
		MPlayer usender = MPlayer.get(sender);
 | 
			
		||||
		
 | 
			
		||||
		return Txt.upperCaseFirst(usender.getRole().toString().toLowerCase());
 | 
			
		||||
		return Txt.upperCaseFirst(usender.getRank().getName().toLowerCase());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@ public class ChatTagRoleprefix extends ChatTag
 | 
			
		||||
		Faction faction = usender.getFaction();
 | 
			
		||||
		if (faction.isNone()) return "";
 | 
			
		||||
		
 | 
			
		||||
		return usender.getRole().getPrefix();
 | 
			
		||||
		return usender.getRank().getPrefix();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@ public class ChatTagRoleprefixforce extends ChatTag
 | 
			
		||||
		// Get entities
 | 
			
		||||
		MPlayer usender = MPlayer.get(sender);
 | 
			
		||||
		
 | 
			
		||||
		return usender.getRole().getPrefix();
 | 
			
		||||
		return usender.getRank().getPrefix();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -39,8 +39,6 @@ public class CmdFactions extends FactionsCommand
 | 
			
		||||
	public CmdFactionsKick cmdFactionsKick = new CmdFactionsKick();
 | 
			
		||||
	public CmdFactionsTitle cmdFactionsTitle = new CmdFactionsTitle();
 | 
			
		||||
	public CmdFactionsRank cmdFactionsRank = new CmdFactionsRank();
 | 
			
		||||
	public CmdFactionsRankOld cmdFactionsRankOldPromote = new CmdFactionsRankOld("promote");
 | 
			
		||||
	public CmdFactionsRankOld cmdFactionsRankOldDemote = new CmdFactionsRankOld("demote");
 | 
			
		||||
	public CmdFactionsMoney cmdFactionsMoney = new CmdFactionsMoney();
 | 
			
		||||
	public CmdFactionsSeeChunk cmdFactionsSeeChunk = new CmdFactionsSeeChunk();
 | 
			
		||||
	public CmdFactionsSeeChunkOld cmdFactionsSeeChunkOld = new CmdFactionsSeeChunkOld();
 | 
			
		||||
@@ -77,7 +75,7 @@ public class CmdFactions extends FactionsCommand
 | 
			
		||||
		this.addChild(new MassiveCommandDeprecated(this.cmdFactionsUnclaim.cmdFactionsUnclaimAll, "unclaimall"));
 | 
			
		||||
		this.addChild(new MassiveCommandDeprecated(this.cmdFactionsFlag, "open"));
 | 
			
		||||
		this.addChild(new MassiveCommandDeprecated(this.cmdFactionsFaction, "show", "who"));
 | 
			
		||||
		this.addChild(new MassiveCommandDeprecated(this.cmdFactionsRank, "leader", "owner", "officer", "moderator"));
 | 
			
		||||
		this.addChild(new MassiveCommandDeprecated(this.cmdFactionsRank, "leader", "owner", "officer", "moderator", "demote", "promote"));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
package com.massivecraft.factions.cmd;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.factions.Factions;
 | 
			
		||||
import com.massivecraft.factions.Rel;
 | 
			
		||||
import com.massivecraft.factions.cmd.req.ReqHasntFaction;
 | 
			
		||||
import com.massivecraft.factions.cmd.type.TypeFactionNameStrict;
 | 
			
		||||
import com.massivecraft.factions.entity.Faction;
 | 
			
		||||
@@ -55,7 +54,7 @@ public class CmdFactionsCreate extends FactionsCommand
 | 
			
		||||
		Faction faction = FactionColl.get().create(factionId);
 | 
			
		||||
		faction.setName(newName);
 | 
			
		||||
		
 | 
			
		||||
		msender.setRole(Rel.LEADER);
 | 
			
		||||
		msender.setRank(faction.getLeaderRank());
 | 
			
		||||
		msender.setFaction(faction);
 | 
			
		||||
		
 | 
			
		||||
		EventFactionsMembershipChange joinEvent = new EventFactionsMembershipChange(sender, msender, faction, MembershipChangeReason.CREATE);
 | 
			
		||||
 
 | 
			
		||||
@@ -116,6 +116,7 @@ public class CmdFactionsJoin extends FactionsCommand
 | 
			
		||||
		// Apply
 | 
			
		||||
		mplayer.resetFactionData();
 | 
			
		||||
		mplayer.setFaction(faction);
 | 
			
		||||
		mplayer.setRank(faction.getLowestRank());
 | 
			
		||||
		
 | 
			
		||||
		faction.uninvite(mplayer);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
package com.massivecraft.factions.cmd;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.factions.Factions;
 | 
			
		||||
import com.massivecraft.factions.Rel;
 | 
			
		||||
import com.massivecraft.factions.cmd.type.TypeMPlayer;
 | 
			
		||||
import com.massivecraft.factions.entity.Faction;
 | 
			
		||||
import com.massivecraft.factions.entity.FactionColl;
 | 
			
		||||
@@ -44,17 +43,17 @@ public class CmdFactionsKick extends FactionsCommand
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (mplayer.getRole() == Rel.LEADER && !msender.isOverriding())
 | 
			
		||||
		if (mplayer.getRank().isLeader() && !msender.isOverriding())
 | 
			
		||||
		{
 | 
			
		||||
			throw new MassiveException().addMsg("<b>The leader cannot be kicked.");
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (mplayer.getRole().isMoreThan(msender.getRole()) && ! msender.isOverriding())
 | 
			
		||||
		if (mplayer.getRank().isMoreThan(msender.getRank()) && ! msender.isOverriding())
 | 
			
		||||
		{
 | 
			
		||||
			throw new MassiveException().addMsg("<b>You can't kick people of higher rank than yourself.");
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (mplayer.getRole() == msender.getRole() && ! msender.isOverriding())
 | 
			
		||||
		if (mplayer.getRank() == msender.getRank() && ! msender.isOverriding())
 | 
			
		||||
		{
 | 
			
		||||
			throw new MassiveException().addMsg("<b>You can't kick people of the same rank as yourself.");
 | 
			
		||||
		}
 | 
			
		||||
@@ -88,7 +87,7 @@ public class CmdFactionsKick extends FactionsCommand
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Apply
 | 
			
		||||
		if (mplayer.getRole() == Rel.LEADER)
 | 
			
		||||
		if (mplayer.getRank().isLeader())
 | 
			
		||||
		{
 | 
			
		||||
			mplayerFaction.promoteNewLeader();
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,10 @@
 | 
			
		||||
package com.massivecraft.factions.cmd;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.factions.Rel;
 | 
			
		||||
import com.massivecraft.factions.cmd.type.TypeFaction;
 | 
			
		||||
import com.massivecraft.factions.cmd.type.TypeMPerm;
 | 
			
		||||
import com.massivecraft.factions.cmd.type.TypeRel;
 | 
			
		||||
import com.massivecraft.factions.cmd.type.TypeMPermable;
 | 
			
		||||
import com.massivecraft.factions.entity.Faction;
 | 
			
		||||
import com.massivecraft.factions.entity.MConf;
 | 
			
		||||
import com.massivecraft.factions.entity.MPerm;
 | 
			
		||||
import com.massivecraft.factions.entity.MPlayer;
 | 
			
		||||
import com.massivecraft.factions.event.EventFactionsPermChange;
 | 
			
		||||
@@ -25,7 +25,7 @@ public class CmdFactionsPermSet extends FactionsCommand
 | 
			
		||||
	{
 | 
			
		||||
		// Parameters
 | 
			
		||||
		this.addParameter(TypeMPerm.get(), "perm");
 | 
			
		||||
		this.addParameter(TypeRel.get(), "relation");
 | 
			
		||||
		this.addParameter(TypeMPermable.get(), "relation");
 | 
			
		||||
		this.addParameter(TypeBooleanYes.get(), "yes/no");
 | 
			
		||||
		this.addParameter(TypeFaction.get(), "faction", "you");
 | 
			
		||||
	}
 | 
			
		||||
@@ -38,10 +38,12 @@ public class CmdFactionsPermSet extends FactionsCommand
 | 
			
		||||
	public void perform() throws MassiveException
 | 
			
		||||
	{
 | 
			
		||||
		// Args
 | 
			
		||||
		MPerm perm = this.readArg();
 | 
			
		||||
		Rel rel = this.readArg();
 | 
			
		||||
		Boolean value = this.readArg();
 | 
			
		||||
		Faction faction = this.readArg(msenderFaction);
 | 
			
		||||
		MPerm perm = this.readArgAt(0);
 | 
			
		||||
		Boolean value = this.readArgAt(2);
 | 
			
		||||
		Faction faction = this.readArgAt(3, msenderFaction);
 | 
			
		||||
 | 
			
		||||
		MPerm.MPermable permable = TypeMPermable.get(faction).read(this.argAt(1), sender);
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
		// Do the sender have the right to change perms for this faction?
 | 
			
		||||
		if ( ! MPerm.getPermPerms().has(msender, faction, true)) return;
 | 
			
		||||
@@ -54,25 +56,26 @@ public class CmdFactionsPermSet extends FactionsCommand
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// Event
 | 
			
		||||
		EventFactionsPermChange event = new EventFactionsPermChange(sender, faction, perm, rel, value);
 | 
			
		||||
		EventFactionsPermChange event = new EventFactionsPermChange(sender, faction, perm, permable, value);
 | 
			
		||||
		event.run();
 | 
			
		||||
		if (event.isCancelled()) return;
 | 
			
		||||
		value = event.getNewValue();
 | 
			
		||||
 | 
			
		||||
		// Apply
 | 
			
		||||
		boolean change = faction.setPermitted(permable, perm, value);
 | 
			
		||||
		
 | 
			
		||||
		// No change
 | 
			
		||||
		if (faction.getPermitted(perm).contains(rel) == value)
 | 
			
		||||
		if (!change)
 | 
			
		||||
		{
 | 
			
		||||
			msg("%s <i>already has %s <i>set to %s <i>for %s<i>.", faction.describeTo(msender), perm.getDesc(true, false), Txt.parse(value ? "<g>YES" : "<b>NOO"), rel.getColor() + rel.getDescPlayerMany());
 | 
			
		||||
			msg("%s <i>already has %s <i>set to %s <i>for %s<i>.", faction.describeTo(msender), perm.getDesc(true, false), Txt.parse(value ? "<g>YES" : "<b>NOO"), permable.getColor() + permable.getName() + "s");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// Apply
 | 
			
		||||
		faction.setRelationPermitted(perm, rel, value);
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
		// The following is to make sure the leader always has the right to change perms if that is our goal.
 | 
			
		||||
		if (perm == MPerm.getPermPerms() && MPerm.getPermPerms().getStandard().contains(Rel.LEADER))
 | 
			
		||||
		if (perm == MPerm.getPermPerms() && MConf.get().defaultPermsLeader.contains(MPerm.ID_PERMS))
 | 
			
		||||
		{
 | 
			
		||||
			faction.setRelationPermitted(MPerm.getPermPerms(), Rel.LEADER, true);
 | 
			
		||||
			faction.setPermitted( faction.getLeaderRank(), MPerm.getPermPerms(), true);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// Create messages
 | 
			
		||||
@@ -80,8 +83,8 @@ public class CmdFactionsPermSet extends FactionsCommand
 | 
			
		||||
		
 | 
			
		||||
		// Inform sender
 | 
			
		||||
		messages.add(Txt.titleize("Perm for " + faction.describeTo(msender, true)));
 | 
			
		||||
		messages.add(MPerm.getStateHeaders());
 | 
			
		||||
		messages.add(Txt.parse(perm.getStateInfo(faction.getPermitted(perm), true)));
 | 
			
		||||
		messages.add(MPerm.getStateHeaders(faction));
 | 
			
		||||
		messages.add(Txt.parse(perm.getStateInfo(faction, true)));
 | 
			
		||||
		message(messages);
 | 
			
		||||
		
 | 
			
		||||
		// Inform faction (their message is slighly different)
 | 
			
		||||
 
 | 
			
		||||
@@ -40,10 +40,10 @@ public class CmdFactionsPermShow extends FactionsCommand
 | 
			
		||||
		List<Object> messages = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
		messages.add(Txt.titleize("Perm for " + faction.describeTo(msender, true)));
 | 
			
		||||
		messages.add(MPerm.getStateHeaders());
 | 
			
		||||
		messages.add(MPerm.getStateHeaders(faction));
 | 
			
		||||
		for (MPerm mperm : mperms)
 | 
			
		||||
		{
 | 
			
		||||
			messages.add(Txt.parse(mperm.getStateInfo(faction.getPermitted(mperm), true)));
 | 
			
		||||
			messages.add(Txt.parse(mperm.getStateInfo(faction, true)));
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// Send messages
 | 
			
		||||
 
 | 
			
		||||
@@ -2,15 +2,16 @@ package com.massivecraft.factions.cmd;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.factions.Factions;
 | 
			
		||||
import com.massivecraft.factions.Perm;
 | 
			
		||||
import com.massivecraft.factions.Rel;
 | 
			
		||||
import com.massivecraft.factions.cmd.type.TypeFaction;
 | 
			
		||||
import com.massivecraft.factions.cmd.type.TypeMPlayer;
 | 
			
		||||
import com.massivecraft.factions.cmd.type.TypeRank;
 | 
			
		||||
import com.massivecraft.factions.entity.Faction;
 | 
			
		||||
import com.massivecraft.factions.entity.MConf;
 | 
			
		||||
import com.massivecraft.factions.entity.MFlag;
 | 
			
		||||
import com.massivecraft.factions.entity.MPerm;
 | 
			
		||||
import com.massivecraft.factions.entity.MPlayer;
 | 
			
		||||
import com.massivecraft.factions.entity.MPlayerColl;
 | 
			
		||||
import com.massivecraft.factions.entity.Rank;
 | 
			
		||||
import com.massivecraft.factions.event.EventFactionsMembershipChange;
 | 
			
		||||
import com.massivecraft.factions.event.EventFactionsMembershipChange.MembershipChangeReason;
 | 
			
		||||
import com.massivecraft.factions.event.EventFactionsRankChange;
 | 
			
		||||
@@ -22,13 +23,6 @@ import java.util.Set;
 | 
			
		||||
 | 
			
		||||
public class CmdFactionsRank extends FactionsCommand
 | 
			
		||||
{
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// CONSTANTS
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	// The rank required to do any rank changes.
 | 
			
		||||
	final static Rel rankReq = Rel.OFFICER;
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// FIELDS
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
@@ -43,9 +37,9 @@ public class CmdFactionsRank extends FactionsCommand
 | 
			
		||||
	private boolean factionChange = false;
 | 
			
		||||
	
 | 
			
		||||
	// Ranks
 | 
			
		||||
	private Rel senderRank = null;
 | 
			
		||||
	private Rel targetRank = null;
 | 
			
		||||
	private Rel rank = null;
 | 
			
		||||
	private Rank senderRank = null;
 | 
			
		||||
	private Rank targetRank = null;
 | 
			
		||||
	private Rank rank = null;
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// CONSTRUCT
 | 
			
		||||
@@ -55,8 +49,11 @@ public class CmdFactionsRank extends FactionsCommand
 | 
			
		||||
	{
 | 
			
		||||
		// Parameters
 | 
			
		||||
		this.addParameter(TypeMPlayer.get(), "player");
 | 
			
		||||
		this.addParameter(TypeRank.get(), "action", "show");
 | 
			
		||||
		this.addParameter(TypeRank.get(), "rank", "show");
 | 
			
		||||
		this.addParameter(TypeFaction.get(), "faction", "their");
 | 
			
		||||
 | 
			
		||||
		// Too complicated for that
 | 
			
		||||
		this.setSwapping(false);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
@@ -125,19 +122,18 @@ public class CmdFactionsRank extends FactionsCommand
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
		// Ranks
 | 
			
		||||
		senderRank = msender.getRole();
 | 
			
		||||
		targetRank = target.getRole();
 | 
			
		||||
		senderRank = msender.getRank();
 | 
			
		||||
		targetRank = target.getRank();
 | 
			
		||||
 | 
			
		||||
		endFaction = this.readArgAt(2, targetFaction);
 | 
			
		||||
		factionChange = (endFaction != targetFaction);
 | 
			
		||||
		
 | 
			
		||||
		// Rank if any passed.
 | 
			
		||||
		if (this.argIsSet(1))
 | 
			
		||||
		{
 | 
			
		||||
			this.setParameterType(1, TypeRank.get(targetRank));
 | 
			
		||||
			rank = this.readArg();
 | 
			
		||||
			TypeRank typeRank = new TypeRank(endFaction);
 | 
			
		||||
			rank = typeRank.read(this.argAt(1), sender);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// Changing peoples faction.
 | 
			
		||||
		endFaction = this.readArgAt(2, targetFaction);
 | 
			
		||||
		factionChange = (endFaction != targetFaction);
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
@@ -145,6 +141,9 @@ public class CmdFactionsRank extends FactionsCommand
 | 
			
		||||
	{
 | 
			
		||||
		targetFaction = null;
 | 
			
		||||
		target = null;
 | 
			
		||||
 | 
			
		||||
		endFaction = null;
 | 
			
		||||
		factionChange = false;
 | 
			
		||||
		
 | 
			
		||||
		senderRank = null;
 | 
			
		||||
		targetRank = null;
 | 
			
		||||
@@ -164,7 +163,7 @@ public class CmdFactionsRank extends FactionsCommand
 | 
			
		||||
		// We can at least try to limit their powers.
 | 
			
		||||
		if (endFaction.isNone())
 | 
			
		||||
		{
 | 
			
		||||
			throw new MassiveException().addMsg("%s <b>doesn't use ranks sorry :(", targetFaction.getName() );
 | 
			
		||||
			throw new MassiveException().addMsg("%s <b>doesn't use ranks sorry :(", endFaction.getName());
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (target == msender)
 | 
			
		||||
@@ -172,23 +171,16 @@ public class CmdFactionsRank extends FactionsCommand
 | 
			
		||||
			// Don't change your own rank.
 | 
			
		||||
			throw new MassiveException().addMsg("<b>The target player mustn't be yourself.");
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		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 (!MPerm.getPermRank().has(msender, targetFaction, false))
 | 
			
		||||
		{
 | 
			
		||||
			// You need a specific rank to change ranks.
 | 
			
		||||
			throw new MassiveException().addMsg("<b>You must be <h>%s <b>or higher to change ranks.", Txt.getNicedEnum(rankReq).toLowerCase());
 | 
			
		||||
			throw new MassiveException().addMessage(MPerm.getPermRank().createDeniedMessage(msender, targetFaction));
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// The following two if statements could be merged. 
 | 
			
		||||
@@ -196,7 +188,7 @@ public class CmdFactionsRank extends FactionsCommand
 | 
			
		||||
		if (senderRank == targetRank)
 | 
			
		||||
		{
 | 
			
		||||
			// You can't change someones rank if it is equal to yours.
 | 
			
		||||
			throw new MassiveException().addMsg("<h>%s <b>can't manage eachother.", Txt.getNicedEnum(rankReq)+"s");
 | 
			
		||||
			throw new MassiveException().addMsg("<h>%s <b>can't manage eachother.", senderRank.getName()+"s");
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (senderRank.isLessThan(targetRank))
 | 
			
		||||
@@ -207,7 +199,7 @@ public class CmdFactionsRank extends FactionsCommand
 | 
			
		||||
		
 | 
			
		||||
		// The following two if statements could be merged. 
 | 
			
		||||
		// But isn't for the sake of nicer error messages.
 | 
			
		||||
		if (senderRank == rank && senderRank != Rel.LEADER)
 | 
			
		||||
		if (senderRank == rank && !senderRank.isLeader())
 | 
			
		||||
		{
 | 
			
		||||
			// You can't set ranks equal to your own. Unless you are the leader.
 | 
			
		||||
			throw new MassiveException().addMsg("<b>You can't set ranks equal to your own.");
 | 
			
		||||
@@ -223,9 +215,9 @@ public class CmdFactionsRank extends FactionsCommand
 | 
			
		||||
	private void ensureMakesSense() throws MassiveException
 | 
			
		||||
	{
 | 
			
		||||
		// Don't change their rank to something they already are.
 | 
			
		||||
		if (target.getRole() == rank)
 | 
			
		||||
		if (target.getRank() == rank)
 | 
			
		||||
		{
 | 
			
		||||
			throw new MassiveException().addMsg("%s <b>is already %s.", target.describeTo(msender), rank.getDescPlayerOne());
 | 
			
		||||
			throw new MassiveException().addMsg("%s <b>is already %s %s.", target.describeTo(msender), Txt.aan(rank.getName()), rank.getName());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
@@ -238,9 +230,10 @@ public class CmdFactionsRank extends FactionsCommand
 | 
			
		||||
		// 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 theAan = (targetRank.isLeader()) ? "the" : Txt.aan(targetRank.getName()); // "a member", "an officer" or "the leader"
 | 
			
		||||
		String rankName = targetRank.getName().toLowerCase();
 | 
			
		||||
		String ofIn = (targetRank.isLeader()) ? "of" : "in"; // "member in" or "leader of"
 | 
			
		||||
		String factionName = targetFaction.describeTo(msender, true);
 | 
			
		||||
		if (targetFaction == msenderFaction)
 | 
			
		||||
		{
 | 
			
		||||
@@ -266,7 +259,7 @@ public class CmdFactionsRank extends FactionsCommand
 | 
			
		||||
	private void changeFaction() throws MassiveException
 | 
			
		||||
	{	
 | 
			
		||||
		// Don't change a leader to a new faction.
 | 
			
		||||
		if (targetRank == Rel.LEADER)
 | 
			
		||||
		if (targetRank.isLeader())
 | 
			
		||||
		{
 | 
			
		||||
			throw new MassiveException().addMsg("<b>You cannot remove the present leader. Demote them first.");
 | 
			
		||||
		}
 | 
			
		||||
@@ -303,8 +296,9 @@ public class CmdFactionsRank extends FactionsCommand
 | 
			
		||||
		
 | 
			
		||||
		// Now we don't need the old values.
 | 
			
		||||
		targetFaction = target.getFaction();
 | 
			
		||||
		targetRank = target.getRole();
 | 
			
		||||
		senderRank = msender.getRole(); // In case they changed their own rank
 | 
			
		||||
		targetRank = target.getRank();
 | 
			
		||||
		senderRank = msender.getRank(); // In case they changed their own rank
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
@@ -314,7 +308,7 @@ public class CmdFactionsRank extends FactionsCommand
 | 
			
		||||
	private void changeRank() throws MassiveException
 | 
			
		||||
	{
 | 
			
		||||
		// In case of leadership change, we do special things not done in other rank changes.
 | 
			
		||||
		if (rank == Rel.LEADER)
 | 
			
		||||
		if (rank.isLeader())
 | 
			
		||||
		{
 | 
			
		||||
			this.changeRankLeader();
 | 
			
		||||
		}
 | 
			
		||||
@@ -331,7 +325,7 @@ public class CmdFactionsRank extends FactionsCommand
 | 
			
		||||
		if (targetFactionCurrentLeader != null)
 | 
			
		||||
		{
 | 
			
		||||
			// Inform & demote the old leader.
 | 
			
		||||
			targetFactionCurrentLeader.setRole(Rel.OFFICER);
 | 
			
		||||
			targetFactionCurrentLeader.setRank(rank.getRankBelow());
 | 
			
		||||
			if (targetFactionCurrentLeader != msender)
 | 
			
		||||
			{
 | 
			
		||||
				// They kinda know if they fired the command themself.
 | 
			
		||||
@@ -340,7 +334,7 @@ public class CmdFactionsRank extends FactionsCommand
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// Promote the new leader.
 | 
			
		||||
		target.setRole(Rel.LEADER);
 | 
			
		||||
		target.setRank(rank);
 | 
			
		||||
 | 
			
		||||
		// Inform everyone, this includes sender and target.
 | 
			
		||||
		for (MPlayer recipient : MPlayerColl.get().getAllOnline())
 | 
			
		||||
@@ -354,7 +348,7 @@ public class CmdFactionsRank extends FactionsCommand
 | 
			
		||||
	{
 | 
			
		||||
		// If the target is currently the leader and faction isn't permanent a new leader should be promoted.
 | 
			
		||||
		// 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) 
 | 
			
		||||
		if (targetRank.isLeader() && ( ! MConf.get().permanentFactionsDisableLeaderPromotion || ! targetFaction.getFlag(MFlag.ID_PERMANENT)) && targetFaction.getMPlayersWhereRank(targetFaction.getLeaderRank()).size() == 1)
 | 
			
		||||
			// This if statement is very long. Should I nest it for readability?
 | 
			
		||||
		{
 | 
			
		||||
			targetFaction.promoteNewLeader(); // This might disband the faction.
 | 
			
		||||
@@ -377,9 +371,9 @@ public class CmdFactionsRank extends FactionsCommand
 | 
			
		||||
		String change = (rank.isLessThan(targetRank) ? "demoted" : "promoted");
 | 
			
		||||
		
 | 
			
		||||
		// The rank will be set before the msg, so they have the appropriate prefix.
 | 
			
		||||
		target.setRole(rank);
 | 
			
		||||
		String oldRankName = Txt.getNicedEnum(targetRank).toLowerCase();
 | 
			
		||||
		String rankName = Txt.getNicedEnum(rank).toLowerCase();
 | 
			
		||||
		target.setRank(rank);
 | 
			
		||||
		String oldRankName = targetRank.getName().toLowerCase();
 | 
			
		||||
		String rankName = rank.getName().toLowerCase();
 | 
			
		||||
 | 
			
		||||
		// Send message
 | 
			
		||||
		for(MPlayer recipient : recipients)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,51 +0,0 @@
 | 
			
		||||
package com.massivecraft.factions.cmd;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.factions.cmd.type.TypeFaction;
 | 
			
		||||
import com.massivecraft.factions.cmd.type.TypeMPlayer;
 | 
			
		||||
import com.massivecraft.massivecore.command.Visibility;
 | 
			
		||||
import com.massivecraft.massivecore.util.MUtil;
 | 
			
		||||
 | 
			
		||||
public class CmdFactionsRankOld extends FactionsCommand
 | 
			
		||||
{
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// FIELDS
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
		
 | 
			
		||||
	public final String rankName;
 | 
			
		||||
		
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// CONSTRUCT
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public CmdFactionsRankOld(String rank)
 | 
			
		||||
	{
 | 
			
		||||
		// Fields
 | 
			
		||||
		this.rankName = rank.toLowerCase();
 | 
			
		||||
		this.setSetupEnabled(false);
 | 
			
		||||
		
 | 
			
		||||
		// Aliases
 | 
			
		||||
		this.addAliases(rankName);
 | 
			
		||||
	
 | 
			
		||||
		// Parameters
 | 
			
		||||
		this.addParameter(TypeMPlayer.get(), "player");
 | 
			
		||||
		this.addParameter(TypeFaction.get(), "faction", "their");
 | 
			
		||||
		
 | 
			
		||||
		// Visibility
 | 
			
		||||
		this.setVisibility(Visibility.INVISIBLE);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// OVERRIDE
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public void perform()
 | 
			
		||||
	{
 | 
			
		||||
		CmdFactions.get().cmdFactionsRank.execute(sender, MUtil.list(
 | 
			
		||||
			this.argAt(0),
 | 
			
		||||
			this.rankName,
 | 
			
		||||
			this.argAt(1)
 | 
			
		||||
		));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
@@ -44,7 +44,7 @@ public class CmdFactionsTitle extends FactionsCommand
 | 
			
		||||
		if ( ! MPerm.getPermTitle().has(msender, you.getFaction(), true)) return;
 | 
			
		||||
		
 | 
			
		||||
		// Rank Check
 | 
			
		||||
		if (!msender.isOverriding() && you.getRole().isMoreThan(msender.getRole()))
 | 
			
		||||
		if (!msender.isOverriding() && you.getRank().isMoreThan(msender.getRank()))
 | 
			
		||||
		{
 | 
			
		||||
			msg("<b>You can not edit titles for higher ranks.");
 | 
			
		||||
			return;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,52 +1,52 @@
 | 
			
		||||
package com.massivecraft.factions.cmd.req;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.factions.Rel;
 | 
			
		||||
import com.massivecraft.factions.entity.MPlayer;
 | 
			
		||||
import com.massivecraft.massivecore.command.MassiveCommand;
 | 
			
		||||
import com.massivecraft.massivecore.command.requirement.RequirementAbstract;
 | 
			
		||||
import com.massivecraft.massivecore.util.MUtil;
 | 
			
		||||
import com.massivecraft.massivecore.util.Txt;
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
 | 
			
		||||
public class ReqRoleIsAtLeast extends RequirementAbstract
 | 
			
		||||
{
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// SERIALIZABLE
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	private static final long serialVersionUID = 1L;
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// FIELDS
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	private final Rel rel;
 | 
			
		||||
	public Rel getRel() { return this.rel; }
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// INSTANCE & CONSTRUCT
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public static ReqRoleIsAtLeast get(Rel rel) { return new ReqRoleIsAtLeast(rel); }
 | 
			
		||||
	private ReqRoleIsAtLeast(Rel rel) { this.rel = rel; }
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// OVERRIDE
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean apply(CommandSender sender, MassiveCommand command)
 | 
			
		||||
	{
 | 
			
		||||
		if (MUtil.isntSender(sender)) return false;
 | 
			
		||||
		
 | 
			
		||||
		MPlayer mplayer = MPlayer.get(sender);
 | 
			
		||||
		return mplayer.getRole().isAtLeast(this.getRel());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public String createErrorMessage(CommandSender sender, MassiveCommand command)
 | 
			
		||||
	{
 | 
			
		||||
		return Txt.parse("<b>You must be <h>%s <b>or higher to %s.", Txt.getNicedEnum(this.getRel()), getDesc(command));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
package com.massivecraft.factions.cmd.req;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.factions.entity.MPlayer;
 | 
			
		||||
import com.massivecraft.factions.entity.Rank;
 | 
			
		||||
import com.massivecraft.massivecore.command.MassiveCommand;
 | 
			
		||||
import com.massivecraft.massivecore.command.requirement.RequirementAbstract;
 | 
			
		||||
import com.massivecraft.massivecore.util.MUtil;
 | 
			
		||||
import com.massivecraft.massivecore.util.Txt;
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
 | 
			
		||||
public class ReqRankIsAtLeast extends RequirementAbstract
 | 
			
		||||
{
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// SERIALIZABLE
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	private static final long serialVersionUID = 1L;
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// FIELDS
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	private final Rank rank;
 | 
			
		||||
	public Rank getRank() { return this.rank; }
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// INSTANCE & CONSTRUCT
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public static ReqRankIsAtLeast get(Rank rank) { return new ReqRankIsAtLeast(rank); }
 | 
			
		||||
	private ReqRankIsAtLeast(Rank rank) { this.rank = rank; }
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// OVERRIDE
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean apply(CommandSender sender, MassiveCommand command)
 | 
			
		||||
	{
 | 
			
		||||
		if (MUtil.isntSender(sender)) return false;
 | 
			
		||||
		
 | 
			
		||||
		MPlayer mplayer = MPlayer.get(sender);
 | 
			
		||||
		return mplayer.getRank().isAtLeast(this.getRank());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public String createErrorMessage(CommandSender sender, MassiveCommand command)
 | 
			
		||||
	{
 | 
			
		||||
		return Txt.parse("<b>You must be <h>%s <b>or higher to %s.", rank.getName(), getDesc(command));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								src/com/massivecraft/factions/cmd/type/TypeMPermable.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/com/massivecraft/factions/cmd/type/TypeMPermable.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
package com.massivecraft.factions.cmd.type;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.factions.entity.Faction;
 | 
			
		||||
import com.massivecraft.factions.entity.MPerm;
 | 
			
		||||
import com.massivecraft.factions.entity.Rank;
 | 
			
		||||
import com.massivecraft.massivecore.command.type.TypeAbstractChoice;
 | 
			
		||||
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
 | 
			
		||||
public class TypeMPermable extends TypeAbstractChoice<MPerm.MPermable>
 | 
			
		||||
{
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// INSTANCE & CONSTRUCT
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
	private static TypeMPermable i = new TypeMPermable();
 | 
			
		||||
	public static TypeMPermable get() { return i; }
 | 
			
		||||
	private TypeMPermable()
 | 
			
		||||
	{
 | 
			
		||||
		super(Rank.class);
 | 
			
		||||
 | 
			
		||||
		this.faction = null;
 | 
			
		||||
		this.setAll(Collections.emptyList());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static TypeMPermable get(Faction faction) { return new TypeMPermable(faction); }
 | 
			
		||||
	public TypeMPermable(Faction faction)
 | 
			
		||||
	{
 | 
			
		||||
		super(MPerm.MPermable.class);
 | 
			
		||||
		if (faction == null) throw new NullPointerException("faction");
 | 
			
		||||
 | 
			
		||||
		this.faction = faction;
 | 
			
		||||
 | 
			
		||||
		var permables = MPerm.getPermables(faction);
 | 
			
		||||
		
 | 
			
		||||
		this.setAll(permables);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// FIELDS
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
	private final Faction faction;
 | 
			
		||||
	public Faction getFaction() { return this.faction; }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,128 +1,44 @@
 | 
			
		||||
package com.massivecraft.factions.cmd.type;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.factions.Rel;
 | 
			
		||||
import com.massivecraft.massivecore.collections.MassiveMap;
 | 
			
		||||
import com.massivecraft.massivecore.collections.MassiveSet;
 | 
			
		||||
import com.massivecraft.massivecore.command.type.enumeration.TypeEnum;
 | 
			
		||||
import com.massivecraft.massivecore.util.MUtil;
 | 
			
		||||
import com.massivecraft.factions.entity.Faction;
 | 
			
		||||
import com.massivecraft.factions.entity.Rank;
 | 
			
		||||
import com.massivecraft.massivecore.command.type.TypeAbstractChoice;
 | 
			
		||||
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
public class TypeRank extends TypeEnum<Rel>
 | 
			
		||||
public class TypeRank extends TypeAbstractChoice<Rank>
 | 
			
		||||
{
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// CONSTANTS
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public static final Set<String> NAMES_PROMOTE = new MassiveSet<>(
 | 
			
		||||
		"Promote",
 | 
			
		||||
		"+",
 | 
			
		||||
		"Plus",
 | 
			
		||||
		"Up"
 | 
			
		||||
	);
 | 
			
		||||
	
 | 
			
		||||
	public static final Set<String> NAMES_DEMOTE = new MassiveSet<>(
 | 
			
		||||
		"Demote",
 | 
			
		||||
		"-",
 | 
			
		||||
		"Minus",
 | 
			
		||||
		"Down"
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// INSTANCE & CONSTRUCT
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// Because of the caching in TypeAbstractChoice, we want only one of each instance.
 | 
			
		||||
	
 | 
			
		||||
	// Null instance, doesn't allow promote and demote.
 | 
			
		||||
	private static final TypeRank i = new TypeRank(null);
 | 
			
		||||
 | 
			
		||||
	private static TypeRank i = new TypeRank();
 | 
			
		||||
	public static TypeRank get() { return i; }
 | 
			
		||||
	
 | 
			
		||||
	// Cached instances, does allow promote and demote.
 | 
			
		||||
	private static final Map<Rel, TypeRank> instances;
 | 
			
		||||
	static
 | 
			
		||||
	private TypeRank()
 | 
			
		||||
	{
 | 
			
		||||
		Map<Rel, TypeRank> result = new MassiveMap<>();
 | 
			
		||||
		for (Rel rel : Rel.values())
 | 
			
		||||
		{
 | 
			
		||||
			if ( ! rel.isRank()) continue;
 | 
			
		||||
			result.put(rel, new TypeRank(rel));
 | 
			
		||||
		}
 | 
			
		||||
		result.put(null, i);
 | 
			
		||||
		instances = Collections.unmodifiableMap(result);
 | 
			
		||||
		super(Rank.class);
 | 
			
		||||
 | 
			
		||||
		this.faction = null;
 | 
			
		||||
		this.setAll(Collections.emptyList());
 | 
			
		||||
	}
 | 
			
		||||
	public static TypeRank get(Rel rank) { return instances.get(rank); }
 | 
			
		||||
	
 | 
			
		||||
	// Constructor
 | 
			
		||||
	public TypeRank(Rel rank)
 | 
			
		||||
 | 
			
		||||
	public static TypeRank get(Faction faction) { return new TypeRank(faction); }
 | 
			
		||||
	public TypeRank(Faction faction)
 | 
			
		||||
	{
 | 
			
		||||
		super(Rel.class);
 | 
			
		||||
		if (rank != null && ! rank.isRank()) throw new IllegalArgumentException(rank + " is not a valid rank");
 | 
			
		||||
		this.startRank = rank;
 | 
			
		||||
		if (faction == null) throw new NullPointerException("faction");
 | 
			
		||||
 | 
			
		||||
		this.faction = faction;
 | 
			
		||||
		
 | 
			
		||||
		// Do setAll with only ranks.
 | 
			
		||||
		List<Rel> all = MUtil.list(Rel.values());
 | 
			
		||||
		for (Iterator<Rel> it = all.iterator(); it.hasNext(); )
 | 
			
		||||
		{
 | 
			
		||||
			if ( ! it.next().isRank()) it.remove();
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		this.setAll(all);
 | 
			
		||||
		this.setAll(faction.getRanks().getAll());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// FIELDS
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	// This must be final, for caching in TypeAbstractChoice to work.
 | 
			
		||||
	private final Rel startRank;
 | 
			
		||||
	public Rel getStartRank() { return this.startRank; }
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// OVERRIDE
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public String getName()
 | 
			
		||||
	{
 | 
			
		||||
		return "rank";
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public String getNameInner(Rel value)
 | 
			
		||||
	{
 | 
			
		||||
		return value.getName();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public Set<String> getNamesInner(Rel value)
 | 
			
		||||
	{
 | 
			
		||||
		// Create
 | 
			
		||||
		Set<String> ret = new MassiveSet<>();
 | 
			
		||||
		
 | 
			
		||||
		// Fill Exact
 | 
			
		||||
		ret.addAll(value.getNames());
 | 
			
		||||
		
 | 
			
		||||
		// Fill Relative
 | 
			
		||||
		Rel start = this.getStartRank();
 | 
			
		||||
		if (start != null)
 | 
			
		||||
		{
 | 
			
		||||
			if (value == Rel.LEADER && start == Rel.OFFICER) ret.addAll(NAMES_PROMOTE);
 | 
			
		||||
			
 | 
			
		||||
			if (value == Rel.OFFICER && start == Rel.MEMBER) ret.addAll(NAMES_PROMOTE);
 | 
			
		||||
			if (value == Rel.OFFICER && start == Rel.LEADER) ret.addAll(NAMES_DEMOTE);
 | 
			
		||||
			
 | 
			
		||||
			if (value == Rel.MEMBER && start == Rel.RECRUIT) ret.addAll(NAMES_PROMOTE);
 | 
			
		||||
			if (value == Rel.MEMBER && start == Rel.OFFICER) ret.addAll(NAMES_DEMOTE);
 | 
			
		||||
			
 | 
			
		||||
			if (value == Rel.RECRUIT && start == Rel.MEMBER) ret.addAll(NAMES_DEMOTE);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// Return
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private final Faction faction;
 | 
			
		||||
	public Faction getFaction() { return this.faction; }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
package com.massivecraft.factions.comparator;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.factions.Rel;
 | 
			
		||||
import com.massivecraft.factions.entity.MPlayer;
 | 
			
		||||
import com.massivecraft.factions.entity.Rank;
 | 
			
		||||
import com.massivecraft.massivecore.Named;
 | 
			
		||||
import com.massivecraft.massivecore.comparator.ComparatorAbstract;
 | 
			
		||||
 | 
			
		||||
@@ -28,9 +28,10 @@ public class ComparatorMPlayerRole extends ComparatorAbstract<MPlayer> implement
 | 
			
		||||
	public int compareInner(MPlayer m1, MPlayer m2)
 | 
			
		||||
	{
 | 
			
		||||
		// Rank
 | 
			
		||||
		Rel r1 = m1.getRole();
 | 
			
		||||
		Rel r2 = m2.getRole();
 | 
			
		||||
		return r2.getValue() - r1.getValue();
 | 
			
		||||
		if (m1.getFaction() != m2.getFaction()) throw new IllegalArgumentException("Noncomparable players");
 | 
			
		||||
		Rank r1 = m1.getRank();
 | 
			
		||||
		Rank r2 = m2.getRank();
 | 
			
		||||
		return r2.getPriority() - r1.getPriority()	;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
package com.massivecraft.factions.engine;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.factions.Rel;
 | 
			
		||||
import com.massivecraft.factions.entity.MConf;
 | 
			
		||||
import com.massivecraft.factions.entity.MPlayer;
 | 
			
		||||
import com.massivecraft.factions.entity.MPlayerColl;
 | 
			
		||||
@@ -40,7 +39,7 @@ public class EnginePlayerData extends Engine
 | 
			
		||||
		MPlayer mplayer = MPlayerColl.get().get(player, false);
 | 
			
		||||
		if (mplayer == null) return;
 | 
			
		||||
 | 
			
		||||
		if (mplayer.getRole() == Rel.LEADER)
 | 
			
		||||
		if (mplayer.getRank().isLeader())
 | 
			
		||||
		{
 | 
			
		||||
			mplayer.getFaction().promoteNewLeader();
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ import com.massivecraft.factions.FactionsParticipator;
 | 
			
		||||
import com.massivecraft.factions.Rel;
 | 
			
		||||
import com.massivecraft.factions.RelationParticipator;
 | 
			
		||||
import com.massivecraft.factions.predicate.PredicateCommandSenderFaction;
 | 
			
		||||
import com.massivecraft.factions.predicate.PredicateMPlayerRole;
 | 
			
		||||
import com.massivecraft.factions.predicate.PredicateMPlayerRank;
 | 
			
		||||
import com.massivecraft.factions.util.MiscUtil;
 | 
			
		||||
import com.massivecraft.factions.util.RelationUtil;
 | 
			
		||||
import com.massivecraft.massivecore.collections.MassiveList;
 | 
			
		||||
@@ -30,14 +30,14 @@ import org.bukkit.ChatColor;
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.Comparator;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
public class Faction extends Entity<Faction> implements FactionsParticipator
 | 
			
		||||
{
 | 
			
		||||
@@ -71,9 +71,10 @@ public class Faction extends Entity<Faction> implements FactionsParticipator
 | 
			
		||||
		this.setHome(that.home);
 | 
			
		||||
		this.setPowerBoost(that.powerBoost);
 | 
			
		||||
		this.invitations.load(that.invitations);
 | 
			
		||||
		this.ranks.load(that.ranks);
 | 
			
		||||
		this.setRelationWishes(that.relationWishes);
 | 
			
		||||
		this.setFlagIds(that.flags);
 | 
			
		||||
		this.setPermIds(that.perms);
 | 
			
		||||
		this.perms = that.perms;
 | 
			
		||||
		
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
@@ -96,7 +97,7 @@ public class Faction extends Entity<Faction> implements FactionsParticipator
 | 
			
		||||
	// VERSION
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public int version = 1;
 | 
			
		||||
	public int version = 2;
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// FIELDS: RAW
 | 
			
		||||
@@ -143,7 +144,10 @@ public class Faction extends Entity<Faction> implements FactionsParticipator
 | 
			
		||||
	// They are actually "senderIds" since you can invite "@console" to your faction.
 | 
			
		||||
	// Null means no one is invited
 | 
			
		||||
	private EntityInternalMap<Invitation> invitations = new EntityInternalMap<>(this, Invitation.class);
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	// This is where all the ranks are, they are faction specific
 | 
			
		||||
	private EntityInternalMap<Rank> ranks = this.createRankMap();
 | 
			
		||||
 | 
			
		||||
	// The keys in this map are factionIds.
 | 
			
		||||
	// Null means no special relation whishes.
 | 
			
		||||
	private MassiveMapDef<String, Rel> relationWishes = new MassiveMapDef<>();
 | 
			
		||||
@@ -154,7 +158,7 @@ public class Faction extends Entity<Faction> implements FactionsParticipator
 | 
			
		||||
 | 
			
		||||
	// The perm overrides are modifications to the default values.
 | 
			
		||||
	// Null means default.
 | 
			
		||||
	private MassiveMapDef<String, Set<Rel>> perms = new MassiveMapDef<>();
 | 
			
		||||
	private Map<String, Set<String>> perms = new MassiveMap<>();
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// FIELD: id
 | 
			
		||||
@@ -338,14 +342,11 @@ public class Faction extends Entity<Faction> implements FactionsParticipator
 | 
			
		||||
	
 | 
			
		||||
	public void setCreatedAtMillis(long createdAtMillis)
 | 
			
		||||
	{
 | 
			
		||||
		// Clean input
 | 
			
		||||
		long target = createdAtMillis;
 | 
			
		||||
		
 | 
			
		||||
		// Detect Nochange
 | 
			
		||||
		if (MUtil.equals(this.createdAtMillis, createdAtMillis)) return;
 | 
			
		||||
 | 
			
		||||
		// Apply
 | 
			
		||||
		this.createdAtMillis = target;
 | 
			
		||||
		this.createdAtMillis = createdAtMillis;
 | 
			
		||||
		
 | 
			
		||||
		// Mark as changed
 | 
			
		||||
		this.changed();
 | 
			
		||||
@@ -394,14 +395,11 @@ public class Faction extends Entity<Faction> implements FactionsParticipator
 | 
			
		||||
	
 | 
			
		||||
	public void setHome(PS home)
 | 
			
		||||
	{
 | 
			
		||||
		// Clean input
 | 
			
		||||
		PS target = home;
 | 
			
		||||
		
 | 
			
		||||
		// Detect Nochange
 | 
			
		||||
		if (MUtil.equals(this.home, target)) return;
 | 
			
		||||
		if (MUtil.equals(this.home, home)) return;
 | 
			
		||||
		
 | 
			
		||||
		// Apply
 | 
			
		||||
		this.home = target;
 | 
			
		||||
		this.home = home;
 | 
			
		||||
		
 | 
			
		||||
		// Mark as changed
 | 
			
		||||
		this.changed();
 | 
			
		||||
@@ -465,12 +463,11 @@ public class Faction extends Entity<Faction> implements FactionsParticipator
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// FIELD: invitedPlayerIds
 | 
			
		||||
	// FIELD: invitations
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	// RAW
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	public EntityInternalMap<Invitation> getInvitations() { return this.invitations; }
 | 
			
		||||
	
 | 
			
		||||
	// FINER
 | 
			
		||||
@@ -487,7 +484,6 @@ public class Faction extends Entity<Faction> implements FactionsParticipator
 | 
			
		||||
	
 | 
			
		||||
	public boolean uninvite(String playerId)
 | 
			
		||||
	{
 | 
			
		||||
		System.out.println(playerId);
 | 
			
		||||
		return this.getInvitations().detachId(playerId) != null;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
@@ -501,7 +497,74 @@ public class Faction extends Entity<Faction> implements FactionsParticipator
 | 
			
		||||
		uninvite(playerId);
 | 
			
		||||
		this.invitations.attach(invitation, playerId);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// FIELD: ranks
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
	// RAW
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public EntityInternalMap<Rank> getRanks() { return this.ranks; }
 | 
			
		||||
 | 
			
		||||
	// FINER
 | 
			
		||||
 | 
			
		||||
	public boolean hasRank(Rank rank)
 | 
			
		||||
	{
 | 
			
		||||
		return this.getRanks().containsKey(rank.getId());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Rank getRank(String rankId)
 | 
			
		||||
	{
 | 
			
		||||
		if (rankId == null) throw new NullPointerException("rankId");
 | 
			
		||||
		return this.getRanks().getFixed(rankId);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private EntityInternalMap<Rank> createRankMap()
 | 
			
		||||
	{
 | 
			
		||||
		var ret = new EntityInternalMap<>(this, Rank.class);
 | 
			
		||||
		Rank leader = new Rank("Leader", 400);
 | 
			
		||||
		Rank officer = new Rank("Officer", 300);
 | 
			
		||||
		Rank member = new Rank("Member", 200);
 | 
			
		||||
		Rank recruit = new Rank("Recruit", 100);
 | 
			
		||||
 | 
			
		||||
		/*leader.setPermIds(new MassiveList<>(MConf.get().defaultPermsLeader));
 | 
			
		||||
		officer.setPermIds(new MassiveList<>(MConf.get().defaultPermsOfficer));
 | 
			
		||||
		member.setPermIds(new MassiveList<>(MConf.get().defaultPermsMember));
 | 
			
		||||
		recruit.setPermIds(new MassiveList<>(MConf.get().defaultPermsRecruit));*/
 | 
			
		||||
 | 
			
		||||
		ret.attach(leader);
 | 
			
		||||
		ret.attach(officer);
 | 
			
		||||
		ret.attach(member);
 | 
			
		||||
		ret.attach(recruit);
 | 
			
		||||
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Rank getLeaderRank()
 | 
			
		||||
	{
 | 
			
		||||
		Rank ret = null;
 | 
			
		||||
		for (Rank rank : this.getRanks().getAll())
 | 
			
		||||
		{
 | 
			
		||||
			if (ret != null && ret.isMoreThan(rank)) continue;
 | 
			
		||||
 | 
			
		||||
			ret = rank;
 | 
			
		||||
		}
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Rank getLowestRank()
 | 
			
		||||
	{
 | 
			
		||||
		Rank ret = null;
 | 
			
		||||
		for (Rank rank : this.getRanks().getAll())
 | 
			
		||||
		{
 | 
			
		||||
			if (ret != null && ret.isLessThan(rank)) continue;
 | 
			
		||||
 | 
			
		||||
			ret = rank;
 | 
			
		||||
		}
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// FIELD: relationWish
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
@@ -690,180 +753,94 @@ public class Faction extends Entity<Faction> implements FactionsParticipator
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// FIELD: permOverrides
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	// RAW
 | 
			
		||||
	
 | 
			
		||||
	public Map<MPerm, Set<Rel>> getPerms()
 | 
			
		||||
 | 
			
		||||
	public Map<String, Set<String>> getPerms()
 | 
			
		||||
	{
 | 
			
		||||
		// We start with default values ...
 | 
			
		||||
		Map<MPerm, Set<Rel>> ret = new MassiveMap<>();
 | 
			
		||||
		for (MPerm mperm : MPerm.getAll())
 | 
			
		||||
		{
 | 
			
		||||
			ret.put(mperm, new MassiveSet<>(mperm.getStandard()));
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// ... and if anything is explicitly set we use that info ...
 | 
			
		||||
		Iterator<Map.Entry<String, Set<Rel>>> iter = this.perms.entrySet().iterator();
 | 
			
		||||
		while (iter.hasNext())
 | 
			
		||||
		{
 | 
			
		||||
			// ... for each entry ...
 | 
			
		||||
			Map.Entry<String, Set<Rel>> entry = iter.next();
 | 
			
		||||
			
 | 
			
		||||
			// ... extract id and remove null values ...
 | 
			
		||||
			String id = entry.getKey();					
 | 
			
		||||
			if (id == null)
 | 
			
		||||
			{
 | 
			
		||||
				iter.remove();
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			// ... resolve object and skip unknowns ...
 | 
			
		||||
			MPerm mperm = MPerm.get(id);
 | 
			
		||||
			if (mperm == null) continue;
 | 
			
		||||
			
 | 
			
		||||
			ret.put(mperm, new MassiveSet<>(entry.getValue()));
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		return ret;
 | 
			
		||||
		return this.perms;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void setPerms(Map<MPerm, Set<Rel>> perms)
 | 
			
		||||
	{
 | 
			
		||||
		Map<String, Set<Rel>> permIds = new MassiveMap<>();
 | 
			
		||||
		for (Map.Entry<MPerm, Set<Rel>> entry : perms.entrySet())
 | 
			
		||||
		{
 | 
			
		||||
			permIds.put(entry.getKey().getId(), entry.getValue());
 | 
			
		||||
		}
 | 
			
		||||
		setPermIds(permIds);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void setPermIds(Map<String, Set<Rel>> perms)
 | 
			
		||||
	{
 | 
			
		||||
		// Clean input
 | 
			
		||||
		MassiveMapDef<String, Set<Rel>> target = new MassiveMapDef<>();
 | 
			
		||||
		for (Map.Entry<String, Set<Rel>> entry : perms.entrySet())
 | 
			
		||||
		{
 | 
			
		||||
			String key = entry.getKey();
 | 
			
		||||
			if (key == null) continue;
 | 
			
		||||
			key = key.toLowerCase(); // Lowercased Keys Version 2.6.0 --> 2.7.0
 | 
			
		||||
			
 | 
			
		||||
			Set<Rel> value = entry.getValue();
 | 
			
		||||
			if (value == null) continue;
 | 
			
		||||
			
 | 
			
		||||
			target.put(key, value);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// Detect Nochange
 | 
			
		||||
		if (MUtil.equals(this.perms, target)) return;
 | 
			
		||||
		
 | 
			
		||||
		// Apply
 | 
			
		||||
		this.perms = target;
 | 
			
		||||
		
 | 
			
		||||
		// Mark as changed
 | 
			
		||||
		this.changed();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// FINER
 | 
			
		||||
	
 | 
			
		||||
	public boolean isPermitted(String permId, Rel rel)
 | 
			
		||||
 | 
			
		||||
	// IS PERMITTED
 | 
			
		||||
 | 
			
		||||
	public boolean isPermitted(MPerm.MPermable mpermable, String permId)
 | 
			
		||||
	{
 | 
			
		||||
		if (mpermable == null) throw new NullPointerException("mpermable");
 | 
			
		||||
		if (permId == null) throw new NullPointerException("permId");
 | 
			
		||||
		
 | 
			
		||||
		Set<Rel> rels = this.perms.get(permId);
 | 
			
		||||
		if (rels != null) return rels.contains(rel);
 | 
			
		||||
		
 | 
			
		||||
		MPerm perm = MPerm.get(permId);
 | 
			
		||||
		if (perm == null) throw new NullPointerException("perm");
 | 
			
		||||
		
 | 
			
		||||
		return perm.getStandard().contains(rel);
 | 
			
		||||
 | 
			
		||||
		var perms = this.perms.get(permId);
 | 
			
		||||
		if (perms == null)
 | 
			
		||||
		{
 | 
			
		||||
			// No perms was found, but likely this is just a new MPerm.
 | 
			
		||||
			// So if this does not exist in the database, throw an error.
 | 
			
		||||
			if (!doesPermExist(permId)) throw new NullPointerException(permId + " caused null");
 | 
			
		||||
 | 
			
		||||
			// Otherwise handle it
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return perms.contains(mpermable.getId());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isPermitted(MPerm perm, Rel rel)
 | 
			
		||||
 | 
			
		||||
	public boolean isPermitted(MPerm.MPermable mpermable, MPerm mperm)
 | 
			
		||||
	{
 | 
			
		||||
		if (perm == null) throw new NullPointerException("perm");
 | 
			
		||||
		
 | 
			
		||||
		String permId = perm.getId();
 | 
			
		||||
		if (permId == null) throw new NullPointerException("permId");
 | 
			
		||||
		
 | 
			
		||||
		Set<Rel> rels = this.perms.get(permId);
 | 
			
		||||
		if (rels != null) return rels.contains(rel);
 | 
			
		||||
		
 | 
			
		||||
		return perm.getStandard().contains(rel);
 | 
			
		||||
		if (mpermable == null) throw new NullPointerException("mpermable");
 | 
			
		||||
		if (mperm == null) throw new NullPointerException("mperm");
 | 
			
		||||
		return isPermitted(mpermable, mperm.getId());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// ---
 | 
			
		||||
	
 | 
			
		||||
	public Set<Rel> getPermitted(MPerm perm)
 | 
			
		||||
 | 
			
		||||
	// SET PERMITTED
 | 
			
		||||
 | 
			
		||||
	public boolean setPermitted(MPerm.MPermable mpermable, String permId, boolean permitted)
 | 
			
		||||
	{
 | 
			
		||||
		if (perm == null) throw new NullPointerException("perm");
 | 
			
		||||
		
 | 
			
		||||
		String permId = perm.getId();
 | 
			
		||||
		if (permId == null) throw new NullPointerException("permId");
 | 
			
		||||
		
 | 
			
		||||
		Set<Rel> rels = this.perms.get(permId);
 | 
			
		||||
		if (rels != null) return rels;
 | 
			
		||||
		
 | 
			
		||||
		return perm.getStandard();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Set<Rel> getPermitted(String permId)
 | 
			
		||||
	{
 | 
			
		||||
		if (permId == null) throw new NullPointerException("permId");
 | 
			
		||||
		
 | 
			
		||||
		Set<Rel> rels = this.perms.get(permId);
 | 
			
		||||
		if (rels != null) return rels;
 | 
			
		||||
		
 | 
			
		||||
		MPerm perm = MPerm.get(permId);
 | 
			
		||||
		if (perm == null) throw new NullPointerException("perm");
 | 
			
		||||
		
 | 
			
		||||
		return perm.getStandard();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Deprecated
 | 
			
		||||
	// Use getPermitted instead. It's much quicker although not immutable.
 | 
			
		||||
	public Set<Rel> getPermittedRelations(MPerm perm)
 | 
			
		||||
	{
 | 
			
		||||
		return this.getPerms().get(perm);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// ---
 | 
			
		||||
	// TODO: Fix these below. They are reworking the whole map.
 | 
			
		||||
	
 | 
			
		||||
	public void setPermittedRelations(MPerm perm, Set<Rel> rels)
 | 
			
		||||
	{
 | 
			
		||||
		Map<MPerm, Set<Rel>> perms = this.getPerms();
 | 
			
		||||
		perms.put(perm, rels);
 | 
			
		||||
		this.setPerms(perms);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void setPermittedRelations(MPerm perm, Rel... rels)
 | 
			
		||||
	{
 | 
			
		||||
		Set<Rel> temp = new HashSet<>();
 | 
			
		||||
		temp.addAll(Arrays.asList(rels));
 | 
			
		||||
		this.setPermittedRelations(perm, temp);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void setRelationPermitted(MPerm perm, Rel rel, boolean permitted)
 | 
			
		||||
	{
 | 
			
		||||
		Map<MPerm, Set<Rel>> perms = this.getPerms();
 | 
			
		||||
		
 | 
			
		||||
		Set<Rel> rels = perms.get(perm);
 | 
			
		||||
		
 | 
			
		||||
		boolean changed;
 | 
			
		||||
		boolean changed = false;
 | 
			
		||||
 | 
			
		||||
		var perms = this.perms.get(permId);
 | 
			
		||||
		if (perms == null)
 | 
			
		||||
		{
 | 
			
		||||
			// No perms was found, but likely this is just a new MPerm.
 | 
			
		||||
			// So if this does not exist in the database, throw an error.
 | 
			
		||||
			if (!doesPermExist(permId)) throw new NullPointerException(permId + " caused null");
 | 
			
		||||
 | 
			
		||||
			// Otherwise handle it
 | 
			
		||||
			Set<String> permables = new MassiveSet<>();
 | 
			
		||||
			this.perms.put(permId, permables);
 | 
			
		||||
			changed = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (permitted)
 | 
			
		||||
		{
 | 
			
		||||
			changed = rels.add(rel);
 | 
			
		||||
			changed = this.getPerms().get(permId).add(mpermable.getId()) | changed;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			changed = rels.remove(rel);
 | 
			
		||||
			changed = this.getPerms().get(permId).remove(mpermable.getId()) | changed;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		this.setPerms(perms);
 | 
			
		||||
		
 | 
			
		||||
		if (changed) this.changed();
 | 
			
		||||
		return changed;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	public boolean setPermitted(MPerm.MPermable mpermable, MPerm mperm, boolean permitted)
 | 
			
		||||
	{
 | 
			
		||||
		return setPermitted(mpermable, mperm.getId(), permitted);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setPermittedRelations(String permId, Collection<MPerm.MPermable> permables)
 | 
			
		||||
	{
 | 
			
		||||
		var ids = permables.stream().map(MPerm.MPermable::getId).collect(Collectors.toSet());
 | 
			
		||||
		this.getPerms().put(permId, ids);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setPermittedRelations(MPerm perm, Collection<MPerm.MPermable> permables)
 | 
			
		||||
	{
 | 
			
		||||
		setPermittedRelations(perm.getId(), permables);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	private boolean doesPermExist(String permId)
 | 
			
		||||
	{
 | 
			
		||||
		return MPermColl.get().getFixed(permId) != null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// OVERRIDE: RelationParticipator
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
@@ -1005,14 +982,14 @@ public class Faction extends Entity<Faction> implements FactionsParticipator
 | 
			
		||||
		return this.getMPlayersWhere(PredicateAnd.get(SenderColl.PREDICATE_ONLINE, PredicateVisibleTo.get(senderObject)));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public List<MPlayer> getMPlayersWhereRole(Rel role)
 | 
			
		||||
	public List<MPlayer> getMPlayersWhereRank(Rank rank)
 | 
			
		||||
	{
 | 
			
		||||
		return this.getMPlayersWhere(PredicateMPlayerRole.get(role));
 | 
			
		||||
		return this.getMPlayersWhere(PredicateMPlayerRank.get(rank));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public MPlayer getLeader()
 | 
			
		||||
	{
 | 
			
		||||
		List<MPlayer> ret = this.getMPlayersWhereRole(Rel.LEADER);
 | 
			
		||||
		List<MPlayer> ret = this.getMPlayersWhereRank(this.getLeaderRank());
 | 
			
		||||
		if (ret.size() == 0) return null;
 | 
			
		||||
		return ret.get(0);
 | 
			
		||||
	}
 | 
			
		||||
@@ -1064,14 +1041,19 @@ public class Faction extends Entity<Faction> implements FactionsParticipator
 | 
			
		||||
		if (this.getFlag(MFlag.getFlagPermanent()) && MConf.get().permanentFactionsDisableLeaderPromotion) return;
 | 
			
		||||
 | 
			
		||||
		MPlayer oldLeader = this.getLeader();
 | 
			
		||||
		Rank leaderRank = oldLeader.getRank();
 | 
			
		||||
 | 
			
		||||
		// get list of officers, or list of normal members if there are no officers
 | 
			
		||||
		List<MPlayer> replacements = this.getMPlayersWhereRole(Rel.OFFICER);
 | 
			
		||||
		if (replacements == null || replacements.isEmpty())
 | 
			
		||||
		var replacements = Collections.<MPlayer>emptyList();
 | 
			
		||||
		for (Rank rank = leaderRank; rank != null; rank = rank.getRankBelow())
 | 
			
		||||
		{
 | 
			
		||||
			replacements = this.getMPlayersWhereRole(Rel.MEMBER);
 | 
			
		||||
			//Skip first
 | 
			
		||||
			if (rank == leaderRank) continue;
 | 
			
		||||
 | 
			
		||||
			replacements = this.getMPlayersWhereRank(rank);
 | 
			
		||||
			if (!replacements.isEmpty()) break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// if we found a replacement
 | 
			
		||||
		if (replacements == null || replacements.isEmpty())
 | 
			
		||||
		{
 | 
			
		||||
			// faction leader is the only member; one-man faction
 | 
			
		||||
@@ -1079,8 +1061,7 @@ public class Faction extends Entity<Faction> implements FactionsParticipator
 | 
			
		||||
			{
 | 
			
		||||
				if (oldLeader != null)
 | 
			
		||||
				{
 | 
			
		||||
					// TODO: Where is the logic in this? Why MEMBER? Why not LEADER again? And why not OFFICER or RECRUIT?
 | 
			
		||||
					oldLeader.setRole(Rel.MEMBER);
 | 
			
		||||
					oldLeader.setRank(this.getLeaderRank().getRankBelow());
 | 
			
		||||
				}
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
@@ -1103,10 +1084,10 @@ public class Faction extends Entity<Faction> implements FactionsParticipator
 | 
			
		||||
			// promote new faction leader
 | 
			
		||||
			if (oldLeader != null)
 | 
			
		||||
			{
 | 
			
		||||
				oldLeader.setRole(Rel.MEMBER);
 | 
			
		||||
				oldLeader.setRank(this.getLeaderRank().getRankBelow());
 | 
			
		||||
			}
 | 
			
		||||
				
 | 
			
		||||
			replacements.get(0).setRole(Rel.LEADER);
 | 
			
		||||
			replacements.get(0).setRank(this.getLeaderRank());
 | 
			
		||||
			this.msg("<i>Faction leader <h>%s<i> has been removed. %s<i> has been promoted as the new faction leader.", oldLeader == null ? "" : oldLeader.getName(), replacements.get(0).getName());
 | 
			
		||||
			Factions.get().log("Faction "+this.getName()+" ("+this.getId()+") leader was removed. Replacement leader: "+replacements.get(0).getName());
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,6 @@ import com.massivecraft.massivecore.util.Txt;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.LinkedHashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
@@ -46,6 +45,8 @@ public class FactionColl extends Coll<Faction>
 | 
			
		||||
		if (!active) return;
 | 
			
		||||
		
 | 
			
		||||
		this.createSpecialFactions();
 | 
			
		||||
 | 
			
		||||
		Factions.get().log("Activated FactionColl");
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
@@ -84,13 +85,13 @@ public class FactionColl extends Coll<Faction>
 | 
			
		||||
		faction.setFlag(MFlag.getFlagFirespread(), true);
 | 
			
		||||
		faction.setFlag(MFlag.getFlagEndergrief(), true);
 | 
			
		||||
		faction.setFlag(MFlag.getFlagZombiegrief(), true);
 | 
			
		||||
		
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermBuild(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermDoor(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermContainer(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermButton(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermLever(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermDeposit(), Rel.LEADER, Rel.OFFICER); // Wilderness deposit should be limited as an anti spam meassure.
 | 
			
		||||
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermBuild(), MPerm.getPermables(faction));
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermDoor(), MPerm.getPermables(faction));
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermContainer(), MPerm.getPermables(faction));
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermButton(), MPerm.getPermables(faction));
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermLever(), MPerm.getPermables(faction));;
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermDeposit(), Collections.singleton(faction.getLeaderRank())); // Wilderness deposit should be limited as an anti spam meassure.
 | 
			
		||||
		
 | 
			
		||||
		return faction;
 | 
			
		||||
	}
 | 
			
		||||
@@ -120,12 +121,11 @@ public class FactionColl extends Coll<Faction>
 | 
			
		||||
		faction.setFlag(MFlag.getFlagFirespread(), false);
 | 
			
		||||
		faction.setFlag(MFlag.getFlagEndergrief(), false);
 | 
			
		||||
		faction.setFlag(MFlag.getFlagZombiegrief(), false);
 | 
			
		||||
		
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermDoor(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermContainer(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermButton(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermLever(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermTerritory(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER);
 | 
			
		||||
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermDoor(), MPerm.getPermables(faction));
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermContainer(), MPerm.getPermables(faction));
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermButton(), MPerm.getPermables(faction));
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermLever(), MPerm.getPermables(faction));
 | 
			
		||||
		
 | 
			
		||||
		return faction;
 | 
			
		||||
	}
 | 
			
		||||
@@ -156,11 +156,10 @@ public class FactionColl extends Coll<Faction>
 | 
			
		||||
		faction.setFlag(MFlag.getFlagEndergrief(), true);
 | 
			
		||||
		faction.setFlag(MFlag.getFlagZombiegrief(), true);
 | 
			
		||||
		
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermDoor(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermContainer(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermButton(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermLever(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermTerritory(), Rel.LEADER, Rel.OFFICER, Rel.MEMBER);
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermDoor(), MPerm.getPermables(faction));
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermContainer(), MPerm.getPermables(faction));
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermButton(), MPerm.getPermables(faction));
 | 
			
		||||
		faction.setPermittedRelations(MPerm.getPermLever(), MPerm.getPermables(faction));
 | 
			
		||||
		
 | 
			
		||||
		return faction;
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -20,8 +20,6 @@ import org.bukkit.entity.EntityType;
 | 
			
		||||
import org.bukkit.event.EventPriority;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.LinkedHashSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
@@ -61,7 +59,7 @@ public class MConf extends Entity<MConf>
 | 
			
		||||
	// VERSION
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public int version = 3;
 | 
			
		||||
	public int version = 4;
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// COMMAND ALIASES
 | 
			
		||||
@@ -135,10 +133,6 @@ public class MConf extends Entity<MConf>
 | 
			
		||||
	// "none" means Wilderness. Remember to specify the id, like "3defeec7-b3b1-48d9-82bb-2a8903df24e3" and not the name.
 | 
			
		||||
	public String defaultPlayerFactionId = Factions.ID_NONE;
 | 
			
		||||
	
 | 
			
		||||
	// What rank should new players joining a faction get?
 | 
			
		||||
	// If not RECRUIT then MEMBER might make sense.
 | 
			
		||||
	public Rel defaultPlayerRole = Rel.RECRUIT;
 | 
			
		||||
	
 | 
			
		||||
	// What power should the player start with?
 | 
			
		||||
	public double defaultPlayerPower = 0.0;
 | 
			
		||||
	
 | 
			
		||||
@@ -281,7 +275,20 @@ public class MConf extends Entity<MConf>
 | 
			
		||||
	// This value can be used to tweak compatibility with other plugins altering the respawn location.
 | 
			
		||||
	// Choose between: LOWEST, LOW, NORMAL, HIGH, HIGHEST and MONITOR.
 | 
			
		||||
	public EventPriority homesTeleportToOnDeathPriority = EventPriority.NORMAL;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// PERMS
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
	public List<String> defaultPermsEnemy = MUtil.list(MPerm.ID_DEPOSIT);
 | 
			
		||||
	public List<String> defaultPermsNeutral = MUtil.list(MPerm.ID_DEPOSIT);
 | 
			
		||||
	public List<String> defaultPermsTruce = MUtil.list(MPerm.ID_DEPOSIT);
 | 
			
		||||
	public List<String> defaultPermsAlly = MUtil.list(MPerm.ID_DOOR, MPerm.ID_BUTTON, MPerm.ID_LEVER, MPerm.ID_HOME, MPerm.ID_CLAIMNEAR);
 | 
			
		||||
	public List<String> defaultPermsRecruit = MUtil.list(MPerm.ID_DOOR, MPerm.ID_BUTTON, MPerm.ID_LEVER, MPerm.ID_LEVER, MPerm.ID_HOME, MPerm.ID_CLAIMNEAR);
 | 
			
		||||
	public List<String> defaultPermsMember = MUtil.list(MPerm.ID_BUILD, MPerm.ID_DOOR, MPerm.ID_BUTTON, MPerm.ID_LEVER, MPerm.ID_LEVER, MPerm.ID_CONTAINER, MPerm.ID_HOME, MPerm.ID_CLAIMNEAR);
 | 
			
		||||
	public List<String> defaultPermsOfficer = MUtil.list(MPerm.ID_BUILD, MPerm.ID_DOOR, MPerm.ID_BUTTON, MPerm.ID_LEVER, MPerm.ID_LEVER, MPerm.ID_CONTAINER, MPerm.ID_DESC, MPerm.ID_MOTD, MPerm.ID_INVITE, MPerm.ID_KICK, MPerm.ID_RANK, MPerm.ID_TITLE, MPerm.ID_HOME, MPerm.ID_SETHOME, MPerm.ID_TERRITORY, MPerm.ID_ACCESS, MPerm.ID_CLAIMNEAR, MPerm.ID_REL);
 | 
			
		||||
	public List<String> defaultPermsLeader = MUtil.list(MPerm.ID_BUILD, MPerm.ID_DOOR, MPerm.ID_BUTTON, MPerm.ID_LEVER, MPerm.ID_LEVER, MPerm.ID_CONTAINER, MPerm.ID_NAME, MPerm.ID_DESC, MPerm.ID_MOTD, MPerm.ID_INVITE, MPerm.ID_KICK, MPerm.ID_RANK, MPerm.ID_TITLE, MPerm.ID_HOME, MPerm.ID_SETHOME, MPerm.ID_WITHDRAW, MPerm.ID_TERRITORY, MPerm.ID_ACCESS, MPerm.ID_CLAIMNEAR, MPerm.ID_REL, MPerm.ID_DISBAND, MPerm.ID_FLAGS, MPerm.ID_FLAGS);
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// TERRITORY INFO
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
@@ -397,7 +404,7 @@ public class MConf extends Entity<MConf>
 | 
			
		||||
		Rel.NEUTRAL, new ArrayList<String>(),
 | 
			
		||||
		Rel.TRUCE, new ArrayList<String>(),
 | 
			
		||||
		Rel.ALLY, new ArrayList<String>(),
 | 
			
		||||
		Rel.MEMBER, new ArrayList<String>()
 | 
			
		||||
		Rel.FACTION, new ArrayList<String>()
 | 
			
		||||
	);
 | 
			
		||||
	
 | 
			
		||||
	// The distance for denying the following commands. Set to -1 to disable.
 | 
			
		||||
@@ -411,12 +418,12 @@ public class MConf extends Entity<MConf>
 | 
			
		||||
		Rel.NEUTRAL, new ArrayList<String>(),
 | 
			
		||||
		Rel.TRUCE, new ArrayList<String>(),
 | 
			
		||||
		Rel.ALLY, new ArrayList<String>(),
 | 
			
		||||
		Rel.MEMBER, new ArrayList<String>()
 | 
			
		||||
		Rel.FACTION, new ArrayList<String>()
 | 
			
		||||
	);
 | 
			
		||||
	
 | 
			
		||||
	// Allow bypassing the above setting when in these territories.
 | 
			
		||||
	public List<Rel> denyCommandsDistanceBypassIn = MUtil.list(
 | 
			
		||||
		Rel.MEMBER,
 | 
			
		||||
		Rel.FACTION,
 | 
			
		||||
		Rel.ALLY
 | 
			
		||||
	);
 | 
			
		||||
	
 | 
			
		||||
@@ -560,40 +567,7 @@ public class MConf extends Entity<MConf>
 | 
			
		||||
	
 | 
			
		||||
	// List of entities considered to be animals.
 | 
			
		||||
	public BackstringSet<EntityType> entityTypesAnimals = new BackstringSet<>(EntityType.class);
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// INTEGRATION: HeroChat
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	// I you are using the chat plugin HeroChat Factions ship with built in integration.
 | 
			
		||||
	// The two channels Faction and Allies will be created.
 | 
			
		||||
	// Their data is actually stored right here in the factions config.
 | 
			
		||||
	// NOTE: HeroChat will create it's own database files for these two channels.
 | 
			
		||||
	// You should ignore those and edit the channel settings from here.
 | 
			
		||||
	// Those HeroChat channel database files aren't read for the Faction and Allies channels.
 | 
			
		||||
	
 | 
			
		||||
	// The Faction Channel
 | 
			
		||||
	public String herochatFactionName = "Faction";
 | 
			
		||||
	public String herochatFactionNick = "F";
 | 
			
		||||
	public String herochatFactionFormat = "{color}[&l{nick}&r{color} &l{factions_roleprefix}&r{color}{factions_title|rp}{sender}{color}] &f{msg}";
 | 
			
		||||
	public ChatColor herochatFactionColor = ChatColor.GREEN;
 | 
			
		||||
	public int herochatFactionDistance = 0;
 | 
			
		||||
	public boolean herochatFactionIsShortcutAllowed = false;
 | 
			
		||||
	public boolean herochatFactionCrossWorld = true;
 | 
			
		||||
	public boolean herochatFactionMuted = false;
 | 
			
		||||
	public Set<String> herochatFactionWorlds = new HashSet<>();
 | 
			
		||||
	
 | 
			
		||||
	// The Allies Channel
 | 
			
		||||
	public String herochatAlliesName = "Allies";
 | 
			
		||||
	public String herochatAlliesNick = "A";
 | 
			
		||||
	public String herochatAlliesFormat = "{color}[&l{nick}&r&f {factions_relcolor}&l{factions_roleprefix}&r{factions_relcolor}{factions_name|rp}{sender}{color}] &f{msg}";
 | 
			
		||||
	public ChatColor herochatAlliesColor = ChatColor.DARK_PURPLE;
 | 
			
		||||
	public int herochatAlliesDistance = 0;
 | 
			
		||||
	public boolean herochatAlliesIsShortcutAllowed = false;
 | 
			
		||||
	public boolean herochatAlliesCrossWorld = true;
 | 
			
		||||
	public boolean herochatAlliesMuted = false;
 | 
			
		||||
	public Set<String> herochatAlliesWorlds = new HashSet<>();
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// INTEGRATION: LWC
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 
 | 
			
		||||
@@ -6,9 +6,11 @@ import com.massivecraft.factions.Rel;
 | 
			
		||||
import com.massivecraft.factions.TerritoryAccess;
 | 
			
		||||
import com.massivecraft.factions.cmd.CmdFactions;
 | 
			
		||||
import com.massivecraft.factions.event.EventFactionsCreatePerms;
 | 
			
		||||
import com.massivecraft.massivecore.Identified;
 | 
			
		||||
import com.massivecraft.massivecore.Named;
 | 
			
		||||
import com.massivecraft.massivecore.Prioritized;
 | 
			
		||||
import com.massivecraft.massivecore.Registerable;
 | 
			
		||||
import com.massivecraft.massivecore.collections.MassiveList;
 | 
			
		||||
import com.massivecraft.massivecore.collections.MassiveSet;
 | 
			
		||||
import com.massivecraft.massivecore.comparator.ComparatorSmart;
 | 
			
		||||
import com.massivecraft.massivecore.predicate.PredicateIsRegistered;
 | 
			
		||||
@@ -16,9 +18,12 @@ import com.massivecraft.massivecore.ps.PS;
 | 
			
		||||
import com.massivecraft.massivecore.store.Entity;
 | 
			
		||||
import com.massivecraft.massivecore.util.MUtil;
 | 
			
		||||
import com.massivecraft.massivecore.util.Txt;
 | 
			
		||||
import org.bukkit.ChatColor;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Comparator;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
@@ -40,6 +45,7 @@ public class MPerm extends Entity<MPerm> implements Prioritized, Registerable, N
 | 
			
		||||
	public final static transient String ID_MOTD = "motd";
 | 
			
		||||
	public final static transient String ID_INVITE = "invite";
 | 
			
		||||
	public final static transient String ID_KICK = "kick";
 | 
			
		||||
	public final static transient String ID_RANK = "rank";
 | 
			
		||||
	public final static transient String ID_TITLE = "title";
 | 
			
		||||
	public final static transient String ID_HOME = "home";
 | 
			
		||||
	public final static transient String ID_SETHOME = "sethome";
 | 
			
		||||
@@ -65,6 +71,7 @@ public class MPerm extends Entity<MPerm> implements Prioritized, Registerable, N
 | 
			
		||||
	public final static transient int PRIORITY_MOTD = 9000;
 | 
			
		||||
	public final static transient int PRIORITY_INVITE = 10000;
 | 
			
		||||
	public final static transient int PRIORITY_KICK = 11000;
 | 
			
		||||
	public final static transient int PRIORITY_RANK = 11500;
 | 
			
		||||
	public final static transient int PRIORITY_TITLE = 12000;
 | 
			
		||||
	public final static transient int PRIORITY_HOME = 13000;
 | 
			
		||||
	public final static transient int PRIORITY_SETHOME = 14000;
 | 
			
		||||
@@ -114,6 +121,7 @@ public class MPerm extends Entity<MPerm> implements Prioritized, Registerable, N
 | 
			
		||||
		getPermMotd();
 | 
			
		||||
		getPermInvite();
 | 
			
		||||
		getPermKick();
 | 
			
		||||
		getPermRank();
 | 
			
		||||
		getPermTitle();
 | 
			
		||||
		getPermHome();
 | 
			
		||||
		getPermSethome();
 | 
			
		||||
@@ -128,32 +136,33 @@ public class MPerm extends Entity<MPerm> implements Prioritized, Registerable, N
 | 
			
		||||
		getPermPerms();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static MPerm getPermBuild() { return getCreative(PRIORITY_BUILD, ID_BUILD, ID_BUILD, "edit the terrain", MUtil.set(Rel.LEADER, Rel.OFFICER, Rel.MEMBER), true, true, true); }
 | 
			
		||||
	public static MPerm getPermPainbuild() { return getCreative(PRIORITY_PAINBUILD, ID_PAINBUILD, ID_PAINBUILD, "edit, take damage", new MassiveSet<Rel>(), true, true, true); }
 | 
			
		||||
	public static MPerm getPermDoor() { return getCreative(PRIORITY_DOOR, ID_DOOR, ID_DOOR, "use doors", MUtil.set(Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY), true, true, true); }
 | 
			
		||||
	public static MPerm getPermButton() { return getCreative(PRIORITY_BUTTON, ID_BUTTON, ID_BUTTON, "use stone buttons", MUtil.set(Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY), true, true, true); }
 | 
			
		||||
	public static MPerm getPermLever() { return getCreative(PRIORITY_LEVER, ID_LEVER, ID_LEVER, "use levers", MUtil.set(Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY), true, true, true); }
 | 
			
		||||
	public static MPerm getPermContainer() { return getCreative(PRIORITY_CONTAINER, ID_CONTAINER, ID_CONTAINER, "use containers", MUtil.set(Rel.LEADER, Rel.OFFICER, Rel.MEMBER), true, true, true); }
 | 
			
		||||
	public static MPerm getPermBuild() { return getCreative(PRIORITY_BUILD, ID_BUILD, ID_BUILD, "edit the terrain", MUtil.set("LEADER", "OFFICER", "MEMBER"), true, true, true); }
 | 
			
		||||
	public static MPerm getPermPainbuild() { return getCreative(PRIORITY_PAINBUILD, ID_PAINBUILD, ID_PAINBUILD, "edit, take damage", new MassiveSet<String>(), true, true, true); }
 | 
			
		||||
	public static MPerm getPermDoor() { return getCreative(PRIORITY_DOOR, ID_DOOR, ID_DOOR, "use doors", MUtil.set("LEADER", "OFFICER", "MEMBER", "RECRUIT", "ALLY"), true, true, true); }
 | 
			
		||||
	public static MPerm getPermButton() { return getCreative(PRIORITY_BUTTON, ID_BUTTON, ID_BUTTON, "use stone buttons", MUtil.set("LEADER", "OFFICER", "MEMBER", "RECRUIT", "ALLY"), true, true, true); }
 | 
			
		||||
	public static MPerm getPermLever() { return getCreative(PRIORITY_LEVER, ID_LEVER, ID_LEVER, "use levers", MUtil.set("LEADER", "OFFICER", "MEMBER", "RECRUIT", "ALLY"), true, true, true); }
 | 
			
		||||
	public static MPerm getPermContainer() { return getCreative(PRIORITY_CONTAINER, ID_CONTAINER, ID_CONTAINER, "use containers", MUtil.set("LEADER", "OFFICER", "MEMBER"), true, true, true); }
 | 
			
		||||
	
 | 
			
		||||
	public static MPerm getPermName() { return getCreative(PRIORITY_NAME, ID_NAME, ID_NAME, "set name", MUtil.set(Rel.LEADER), false, true, true); }
 | 
			
		||||
	public static MPerm getPermDesc() { return getCreative(PRIORITY_DESC, ID_DESC, ID_DESC, "set description", MUtil.set(Rel.LEADER, Rel.OFFICER), false, true, true); }
 | 
			
		||||
	public static MPerm getPermMotd() { return getCreative(PRIORITY_MOTD, ID_MOTD, ID_MOTD, "set motd", MUtil.set(Rel.LEADER, Rel.OFFICER), false, true, true); }
 | 
			
		||||
	public static MPerm getPermInvite() { return getCreative(PRIORITY_INVITE, ID_INVITE, ID_INVITE, "invite players", MUtil.set(Rel.LEADER, Rel.OFFICER), false, true, true); }
 | 
			
		||||
	public static MPerm getPermKick() { return getCreative(PRIORITY_KICK, ID_KICK, ID_KICK, "kick members", MUtil.set(Rel.LEADER, Rel.OFFICER), false, true, true); }
 | 
			
		||||
	public static MPerm getPermTitle() { return getCreative(PRIORITY_TITLE, ID_TITLE, ID_TITLE, "set titles", MUtil.set(Rel.LEADER, Rel.OFFICER), false, true, true); }
 | 
			
		||||
	public static MPerm getPermHome() { return getCreative(PRIORITY_HOME, ID_HOME, ID_HOME, "teleport home", MUtil.set(Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY), false, true, true); }
 | 
			
		||||
	public static MPerm getPermSethome() { return getCreative(PRIORITY_SETHOME, ID_SETHOME, ID_SETHOME, "set the home", MUtil.set(Rel.LEADER, Rel.OFFICER), false, true, true); }
 | 
			
		||||
	public static MPerm getPermDeposit() { return getCreative(PRIORITY_DEPOSIT, ID_DEPOSIT, ID_DEPOSIT, "deposit money", MUtil.set(Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY), false, false, false); } // non editable, non visible.
 | 
			
		||||
	public static MPerm getPermWithdraw() { return getCreative(PRIORITY_WITHDRAW, ID_WITHDRAW, ID_WITHDRAW, "withdraw money", MUtil.set(Rel.LEADER), false, true, true); }
 | 
			
		||||
	public static MPerm getPermTerritory() { return getCreative(PRIORITY_TERRITORY, ID_TERRITORY, ID_TERRITORY, "claim or unclaim", MUtil.set(Rel.LEADER, Rel.OFFICER), false, true, true); }
 | 
			
		||||
	public static MPerm getPermAccess() { return getCreative(PRIORITY_ACCESS, ID_ACCESS, ID_ACCESS, "grant territory", MUtil.set(Rel.LEADER, Rel.OFFICER), false, true, true); }
 | 
			
		||||
	public static MPerm getPermClaimnear() { return getCreative(PRIORITY_CLAIMNEAR, ID_CLAIMNEAR, ID_CLAIMNEAR, "claim nearby", MUtil.set(Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY), false, false, false); } // non editable, non visible.
 | 
			
		||||
	public static MPerm getPermRel() { return getCreative(PRIORITY_REL, ID_REL, ID_REL, "change relations", MUtil.set(Rel.LEADER, Rel.OFFICER), false, true, true); }
 | 
			
		||||
	public static MPerm getPermDisband() { return getCreative(PRIORITY_DISBAND, ID_DISBAND, ID_DISBAND, "disband the faction", MUtil.set(Rel.LEADER), false, true, true); }
 | 
			
		||||
	public static MPerm getPermFlags() { return getCreative(PRIORITY_FLAGS, ID_FLAGS, ID_FLAGS, "manage flags", MUtil.set(Rel.LEADER), false, true, true); }
 | 
			
		||||
	public static MPerm getPermPerms() { return getCreative(PRIORITY_PERMS, ID_PERMS, ID_PERMS, "manage permissions", MUtil.set(Rel.LEADER), false, true, true); }
 | 
			
		||||
	public static MPerm getPermName() { return getCreative(PRIORITY_NAME, ID_NAME, ID_NAME, "set name", MUtil.set("LEADER"), false, true, true); }
 | 
			
		||||
	public static MPerm getPermDesc() { return getCreative(PRIORITY_DESC, ID_DESC, ID_DESC, "set description", MUtil.set("LEADER", "OFFICER"), false, true, true); }
 | 
			
		||||
	public static MPerm getPermMotd() { return getCreative(PRIORITY_MOTD, ID_MOTD, ID_MOTD, "set motd", MUtil.set("LEADER", "OFFICER"), false, true, true); }
 | 
			
		||||
	public static MPerm getPermInvite() { return getCreative(PRIORITY_INVITE, ID_INVITE, ID_INVITE, "invite players", MUtil.set("LEADER", "OFFICER"), false, true, true); }
 | 
			
		||||
	public static MPerm getPermKick() { return getCreative(PRIORITY_KICK, ID_KICK, ID_KICK, "kick members", MUtil.set("LEADER", "OFFICER"), false, true, true); }
 | 
			
		||||
	public static MPerm getPermRank() { return getCreative(PRIORITY_RANK, ID_RANK, ID_RANK, "change ranks", MUtil.set("LEADER", "OFFICER"), false, true, true); }
 | 
			
		||||
	public static MPerm getPermTitle() { return getCreative(PRIORITY_TITLE, ID_TITLE, ID_TITLE, "set titles", MUtil.set("LEADER", "OFFICER"), false, true, true); }
 | 
			
		||||
	public static MPerm getPermHome() { return getCreative(PRIORITY_HOME, ID_HOME, ID_HOME, "teleport home", MUtil.set("LEADER", "OFFICER", "MEMBER", "RECRUIT", "ALLY"), false, true, true); }
 | 
			
		||||
	public static MPerm getPermSethome() { return getCreative(PRIORITY_SETHOME, ID_SETHOME, ID_SETHOME, "set the home", MUtil.set("LEADER", "OFFICER"), false, true, true); }
 | 
			
		||||
	public static MPerm getPermDeposit() { return getCreative(PRIORITY_DEPOSIT, ID_DEPOSIT, ID_DEPOSIT, "deposit money", MUtil.set("LEADER", "OFFICER", "MEMBER", "RECRUIT", "ALLY", "TRUCE", "NEUTRAL", "ENEMY"), false, false, false); } // non editable, non visible.
 | 
			
		||||
	public static MPerm getPermWithdraw() { return getCreative(PRIORITY_WITHDRAW, ID_WITHDRAW, ID_WITHDRAW, "withdraw money", MUtil.set("LEADER"), false, true, true); }
 | 
			
		||||
	public static MPerm getPermTerritory() { return getCreative(PRIORITY_TERRITORY, ID_TERRITORY, ID_TERRITORY, "claim or unclaim", MUtil.set("LEADER", "OFFICER"), false, true, true); }
 | 
			
		||||
	public static MPerm getPermAccess() { return getCreative(PRIORITY_ACCESS, ID_ACCESS, ID_ACCESS, "grant territory", MUtil.set("LEADER", "OFFICER"), false, true, true); }
 | 
			
		||||
	public static MPerm getPermClaimnear() { return getCreative(PRIORITY_CLAIMNEAR, ID_CLAIMNEAR, ID_CLAIMNEAR, "claim nearby", MUtil.set("LEADER", "OFFICER", "MEMBER", "RECRUIT", "ALLY"), false, false, false); } // non editable, non visible.
 | 
			
		||||
	public static MPerm getPermRel() { return getCreative(PRIORITY_REL, ID_REL, ID_REL, "change relations", MUtil.set("LEADER", "OFFICER"), false, true, true); }
 | 
			
		||||
	public static MPerm getPermDisband() { return getCreative(PRIORITY_DISBAND, ID_DISBAND, ID_DISBAND, "disband the faction", MUtil.set("LEADER"), false, true, true); }
 | 
			
		||||
	public static MPerm getPermFlags() { return getCreative(PRIORITY_FLAGS, ID_FLAGS, ID_FLAGS, "manage flags", MUtil.set("LEADER"), false, true, true); }
 | 
			
		||||
	public static MPerm getPermPerms() { return getCreative(PRIORITY_PERMS, ID_PERMS, ID_PERMS, "manage permissions", MUtil.set("LEADER"), false, true, true); }
 | 
			
		||||
	
 | 
			
		||||
	public static MPerm getCreative(int priority, String id, String name, String desc, Set<Rel> standard, boolean territory, boolean editable, boolean visible)
 | 
			
		||||
	public static MPerm getCreative(int priority, String id, String name, String desc, Set<String> standard, boolean territory, boolean editable, boolean visible)
 | 
			
		||||
	{
 | 
			
		||||
		MPerm ret = MPermColl.get().get(id, false);
 | 
			
		||||
		if (ret != null)
 | 
			
		||||
@@ -228,9 +237,10 @@ public class MPerm extends Entity<MPerm> implements Prioritized, Registerable, N
 | 
			
		||||
	// What is the standard (aka default) perm value?
 | 
			
		||||
	// This value will be set for factions from the beginning.
 | 
			
		||||
	// Example: ... set of relations ...
 | 
			
		||||
	private Set<Rel> standard = new MassiveSet<>();
 | 
			
		||||
	public Set<Rel> getStandard() { return this.standard; }
 | 
			
		||||
	public MPerm setStandard(Set<Rel> standard) { this.standard = standard; this.changed(); return this; }
 | 
			
		||||
	@Deprecated
 | 
			
		||||
	private Set<String> standard = new MassiveSet<>();
 | 
			
		||||
	@Deprecated public Set<String> getStandard() { return this.standard; }
 | 
			
		||||
	@Deprecated public MPerm setStandard(Set<String> standard) { this.standard = standard; this.changed(); return this; }
 | 
			
		||||
	
 | 
			
		||||
	// Is this a territory perm meaning it has to do with territory construction, modification or interaction?
 | 
			
		||||
	// True Examples: build, container, door, lever etc.
 | 
			
		||||
@@ -268,7 +278,7 @@ public class MPerm extends Entity<MPerm> implements Prioritized, Registerable, N
 | 
			
		||||
		// No argument constructor for GSON
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public MPerm(int priority, String name, String desc, Set<Rel> standard, boolean territory, boolean editable, boolean visible)
 | 
			
		||||
	public MPerm(int priority, String name, String desc, Set<String> standard, boolean territory, boolean editable, boolean visible)
 | 
			
		||||
	{
 | 
			
		||||
		this.priority = priority;
 | 
			
		||||
		this.name = name;
 | 
			
		||||
@@ -342,7 +352,7 @@ public class MPerm extends Entity<MPerm> implements Prioritized, Registerable, N
 | 
			
		||||
		if (hostFaction == null) throw new NullPointerException("hostFaction");
 | 
			
		||||
		
 | 
			
		||||
		Rel rel = faction.getRelationTo(hostFaction);
 | 
			
		||||
		return hostFaction.isPermitted(this, rel);
 | 
			
		||||
		return hostFaction.isPermitted(rel, this);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean has(MPlayer mplayer, Faction hostFaction, boolean verboose)
 | 
			
		||||
@@ -354,7 +364,8 @@ public class MPerm extends Entity<MPerm> implements Prioritized, Registerable, N
 | 
			
		||||
		if (mplayer.isOverriding()) return true;
 | 
			
		||||
		
 | 
			
		||||
		Rel rel = mplayer.getRelationTo(hostFaction);
 | 
			
		||||
		if (hostFaction.isPermitted(this, rel)) return true;
 | 
			
		||||
		MPermable permable = rel == Rel.FACTION ? mplayer.getRank() : rel;
 | 
			
		||||
		if (hostFaction.isPermitted(permable, this)) return true;
 | 
			
		||||
		
 | 
			
		||||
		if (verboose) mplayer.message(this.createDeniedMessage(mplayer, hostFaction));
 | 
			
		||||
		
 | 
			
		||||
@@ -392,27 +403,45 @@ public class MPerm extends Entity<MPerm> implements Prioritized, Registerable, N
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// UTIL: ASCII
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public static String getStateHeaders()
 | 
			
		||||
 | 
			
		||||
	public static List<MPermable> getPermables(Faction faction)
 | 
			
		||||
	{
 | 
			
		||||
		if (faction == null) throw new NullPointerException("faction");
 | 
			
		||||
 | 
			
		||||
		var list = new MassiveList<MPermable>();
 | 
			
		||||
 | 
			
		||||
		list.addAll(Arrays.asList(Rel.values()));
 | 
			
		||||
		list.remove(Rel.FACTION);
 | 
			
		||||
 | 
			
		||||
		list.addAll(faction.getRanks().getAll(Comparator.comparingInt(Rank::getPriority)));
 | 
			
		||||
 | 
			
		||||
		return list;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static String getStateHeaders(Faction faction)
 | 
			
		||||
	{
 | 
			
		||||
		if (faction == null) throw new NullPointerException("faction");
 | 
			
		||||
 | 
			
		||||
		String ret = "";
 | 
			
		||||
		for (Rel rel : Rel.values())
 | 
			
		||||
		for (MPermable permable : getPermables(faction))
 | 
			
		||||
		{
 | 
			
		||||
			ret += rel.getColor().toString();
 | 
			
		||||
			ret += rel.toString().substring(0, 3);
 | 
			
		||||
			ret += permable.getColor().toString();
 | 
			
		||||
			ret += permable.getShortName().toUpperCase();
 | 
			
		||||
			ret += " ";
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public String getStateInfo(Set<Rel> value, boolean withDesc)
 | 
			
		||||
	public String getStateInfo(Faction faction, boolean withDesc)
 | 
			
		||||
	{
 | 
			
		||||
		if (faction == null) throw new NullPointerException("faction");
 | 
			
		||||
 | 
			
		||||
		String ret = "";
 | 
			
		||||
		
 | 
			
		||||
		for (Rel rel : Rel.values())
 | 
			
		||||
 | 
			
		||||
		for (MPermable permable : getPermables(faction))
 | 
			
		||||
		{
 | 
			
		||||
			if (value.contains(rel))
 | 
			
		||||
			if (faction.isPermitted(permable, this))
 | 
			
		||||
			{
 | 
			
		||||
				ret += "<g>YES";
 | 
			
		||||
			}
 | 
			
		||||
@@ -442,5 +471,39 @@ public class MPerm extends Entity<MPerm> implements Prioritized, Registerable, N
 | 
			
		||||
		
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public interface MPermable extends Named, Identified
 | 
			
		||||
	{
 | 
			
		||||
		default boolean isRelation()
 | 
			
		||||
		{
 | 
			
		||||
			return this instanceof Rel;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		default boolean isRank()
 | 
			
		||||
		{
 | 
			
		||||
			return this instanceof Rank;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		default String getShortName()
 | 
			
		||||
		{
 | 
			
		||||
			return this.getName().substring(0, 3).toUpperCase();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		default ChatColor getColor()
 | 
			
		||||
		{
 | 
			
		||||
			if (this.isRelation())
 | 
			
		||||
			{
 | 
			
		||||
				throw new RuntimeException();
 | 
			
		||||
			}
 | 
			
		||||
			else if (this.isRank())
 | 
			
		||||
			{
 | 
			
		||||
				return MConf.get().colorMember;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				throw new RuntimeException();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -50,6 +50,12 @@ public class MPlayer extends SenderEntity<MPlayer> implements FactionsParticipat
 | 
			
		||||
		return MPlayerColl.get().get(oid);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// VERSION
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
	public int version = 1;
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// LOAD
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
@@ -59,7 +65,7 @@ public class MPlayer extends SenderEntity<MPlayer> implements FactionsParticipat
 | 
			
		||||
	{
 | 
			
		||||
		this.setLastActivityMillis(that.lastActivityMillis);
 | 
			
		||||
		this.setFactionId(that.factionId);
 | 
			
		||||
		this.setRole(that.role);
 | 
			
		||||
		this.rankId = that.rankId;
 | 
			
		||||
		this.setTitle(that.title);
 | 
			
		||||
		this.setPowerBoost(that.powerBoost);
 | 
			
		||||
		this.setPower(that.power);
 | 
			
		||||
@@ -109,7 +115,7 @@ public class MPlayer extends SenderEntity<MPlayer> implements FactionsParticipat
 | 
			
		||||
	@Override
 | 
			
		||||
	public void preClean()
 | 
			
		||||
	{
 | 
			
		||||
		if (this.getRole() == Rel.LEADER)
 | 
			
		||||
		if (this.getRank().isLeader())
 | 
			
		||||
		{
 | 
			
		||||
			this.getFaction().promoteNewLeader();
 | 
			
		||||
		}
 | 
			
		||||
@@ -140,7 +146,7 @@ public class MPlayer extends SenderEntity<MPlayer> implements FactionsParticipat
 | 
			
		||||
 | 
			
		||||
	// What role does the player have in the faction?
 | 
			
		||||
	// Null means default.
 | 
			
		||||
	private Rel role = null;
 | 
			
		||||
	private String rankId = null;
 | 
			
		||||
 | 
			
		||||
	// What title does the player have in the faction?
 | 
			
		||||
	// The title is just for fun. It's not connected to any game mechanic.
 | 
			
		||||
@@ -206,7 +212,7 @@ public class MPlayer extends SenderEntity<MPlayer> implements FactionsParticipat
 | 
			
		||||
	{
 | 
			
		||||
		// The default neutral faction
 | 
			
		||||
		this.setFactionId(null);
 | 
			
		||||
		this.setRole(null);
 | 
			
		||||
		this.setRank(null);
 | 
			
		||||
		this.setTitle(null);
 | 
			
		||||
		this.setAutoClaimFaction(null);
 | 
			
		||||
	}
 | 
			
		||||
@@ -310,24 +316,24 @@ public class MPlayer extends SenderEntity<MPlayer> implements FactionsParticipat
 | 
			
		||||
	// FIELD: role
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
	public Rel getRole()
 | 
			
		||||
	public Rank getRank()
 | 
			
		||||
	{
 | 
			
		||||
		if (this.isFactionOrphan()) return Rel.RECRUIT;
 | 
			
		||||
		if (this.isFactionOrphan()) return FactionColl.get().getNone().getLowestRank();
 | 
			
		||||
		
 | 
			
		||||
		if (this.role == null) return MConf.get().defaultPlayerRole;
 | 
			
		||||
		return this.role;
 | 
			
		||||
		if (this.rankId == null) return this.getFaction().getLowestRank();
 | 
			
		||||
		return this.getFaction().getRank(this.rankId);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setRole(Rel role)
 | 
			
		||||
	public void setRank(Rank rank)
 | 
			
		||||
	{
 | 
			
		||||
		// Clean input
 | 
			
		||||
		Rel target = role;
 | 
			
		||||
		String rankId = rank == null ? null : rank.getId();
 | 
			
		||||
 | 
			
		||||
		// Detect Nochange
 | 
			
		||||
		if (MUtil.equals(this.role, target)) return;
 | 
			
		||||
		if (MUtil.equals(this.rankId, rankId)) return;
 | 
			
		||||
 | 
			
		||||
		// Apply
 | 
			
		||||
		this.role = target;
 | 
			
		||||
		this.rankId = rankId;
 | 
			
		||||
 | 
			
		||||
		// Mark as changed
 | 
			
		||||
		this.changed();
 | 
			
		||||
@@ -601,7 +607,7 @@ public class MPlayer extends SenderEntity<MPlayer> implements FactionsParticipat
 | 
			
		||||
	{
 | 
			
		||||
		String ret = "";
 | 
			
		||||
		ret += color;
 | 
			
		||||
		ret += this.getRole().getPrefix();
 | 
			
		||||
		ret += this.getRank().getPrefix();
 | 
			
		||||
		if (something != null && something.length() > 0)
 | 
			
		||||
		{
 | 
			
		||||
			ret += something;
 | 
			
		||||
@@ -720,7 +726,7 @@ public class MPlayer extends SenderEntity<MPlayer> implements FactionsParticipat
 | 
			
		||||
 | 
			
		||||
		if (myFaction.getMPlayers().size() > 1)
 | 
			
		||||
		{
 | 
			
		||||
			if (!permanent && this.getRole() == Rel.LEADER)
 | 
			
		||||
			if (!permanent && this.getRank().isLeader())
 | 
			
		||||
			{
 | 
			
		||||
				msg("<b>You must give the leader role to someone else first.");
 | 
			
		||||
				return;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										155
									
								
								src/com/massivecraft/factions/entity/Rank.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								src/com/massivecraft/factions/entity/Rank.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,155 @@
 | 
			
		||||
package com.massivecraft.factions.entity;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.massivecore.store.EntityInternal;
 | 
			
		||||
 | 
			
		||||
public class Rank extends EntityInternal<Rank> implements MPerm.MPermable
 | 
			
		||||
{
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// OVERRIDE: ENTITY
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public Rank load(Rank that)
 | 
			
		||||
	{
 | 
			
		||||
		this.name = that.name;
 | 
			
		||||
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// FIELDS
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
	private String name;
 | 
			
		||||
	public String getName() { return this.name; }
 | 
			
		||||
	public void setName(String name) { this.name = name; this.changed(); }
 | 
			
		||||
 | 
			
		||||
	private int priority;
 | 
			
		||||
	public int getPriority() { return this.priority; }
 | 
			
		||||
	public void setPriority(int priority) { this.priority = priority; this.changed(); }
 | 
			
		||||
 | 
			
		||||
	public String getPrefix()
 | 
			
		||||
	{
 | 
			
		||||
		String ret = "";
 | 
			
		||||
		if (this.isLeader()) ret += "L";
 | 
			
		||||
 | 
			
		||||
		if (this.getName().equalsIgnoreCase("Leader")) ret += "**";
 | 
			
		||||
		else if (this.getName().equalsIgnoreCase("Officer")) ret += "*";
 | 
			
		||||
		else if (this.getName().equalsIgnoreCase("Member")) ret += "+";
 | 
			
		||||
		else if (this.getName().equalsIgnoreCase("Recruit")) ret += "-";
 | 
			
		||||
		else ret += "=";
 | 
			
		||||
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// CONSTRUCT
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
	// For GSON
 | 
			
		||||
	private Rank()
 | 
			
		||||
	{
 | 
			
		||||
		this(null,0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Rank(String name, int priority)
 | 
			
		||||
	{
 | 
			
		||||
		this.name = name;
 | 
			
		||||
		this.priority = priority;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// RANK PRIORITY
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
	public boolean isLessThan(Rank otherRank)
 | 
			
		||||
	{
 | 
			
		||||
		if (this.getContainer() != otherRank.getContainer()) throw new IllegalArgumentException(this.getId() + " : " + otherRank.getId());
 | 
			
		||||
 | 
			
		||||
		return this.getPriority() < otherRank.getPriority();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean isMoreThan(Rank otherRank)
 | 
			
		||||
	{
 | 
			
		||||
		if (this.getContainer() != otherRank.getContainer()) throw new IllegalArgumentException(this.getId() + " : " + otherRank.getId());
 | 
			
		||||
 | 
			
		||||
		return this.getPriority() > otherRank.getPriority();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean isAtLeast(Rank otherRank)
 | 
			
		||||
	{
 | 
			
		||||
		if (this.getContainer() != otherRank.getContainer()) throw new IllegalArgumentException(this.getId() + " : " + otherRank.getId());
 | 
			
		||||
 | 
			
		||||
		return this.getPriority() >= otherRank.getPriority();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean isAtMost(Rank otherRank)
 | 
			
		||||
	{
 | 
			
		||||
		if (this.getContainer() != otherRank.getContainer()) throw new IllegalArgumentException(this.getId() + " : " + otherRank.getId());
 | 
			
		||||
 | 
			
		||||
		return this.getPriority() <= otherRank.getPriority();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean isLeader()
 | 
			
		||||
	{
 | 
			
		||||
		for (Rank otherRank : this.getContainer().getAll())
 | 
			
		||||
		{
 | 
			
		||||
			if (otherRank == this) continue;
 | 
			
		||||
 | 
			
		||||
			if (otherRank.isMoreThan(this)) return false;
 | 
			
		||||
		}
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Rank getRankAbove()
 | 
			
		||||
	{
 | 
			
		||||
		Rank ret = null;
 | 
			
		||||
		for (Rank otherRank : this.getContainer().getAll())
 | 
			
		||||
		{
 | 
			
		||||
			if (otherRank == this) continue;
 | 
			
		||||
			if (otherRank.isLessThan(this)) continue;
 | 
			
		||||
			if (ret != null && ret.isLessThan(otherRank)) continue;
 | 
			
		||||
 | 
			
		||||
			ret = otherRank;
 | 
			
		||||
		}
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Rank getRankBelow()
 | 
			
		||||
	{
 | 
			
		||||
		Rank ret = null;
 | 
			
		||||
		for (Rank otherRank : this.getContainer().getAll())
 | 
			
		||||
		{
 | 
			
		||||
			if (otherRank == this) continue;
 | 
			
		||||
			if (otherRank.isMoreThan(this)) continue;
 | 
			
		||||
			if (ret != null && ret.isMoreThan(otherRank)) continue;
 | 
			
		||||
 | 
			
		||||
			ret = otherRank;
 | 
			
		||||
		}
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// PERM
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
	/*public boolean addPerm(MPerm mperm)
 | 
			
		||||
	{
 | 
			
		||||
		var ret = this.getPermIds().add(mperm.getId());
 | 
			
		||||
		if (ret) this.changed();
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean removePerm(MPerm mperm)
 | 
			
		||||
	{
 | 
			
		||||
		var ret = this.getPermIds().remove(mperm.getId());
 | 
			
		||||
		if (ret) this.changed();
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean hasPerm(MPerm mperm)
 | 
			
		||||
	{
 | 
			
		||||
		return this.getPermIds().contains(mperm.getId());
 | 
			
		||||
	}*/
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,110 @@
 | 
			
		||||
package com.massivecraft.factions.entity.migrator;
 | 
			
		||||
 | 
			
		||||
import com.google.gson.JsonElement;
 | 
			
		||||
import com.google.gson.JsonObject;
 | 
			
		||||
import com.google.gson.reflect.TypeToken;
 | 
			
		||||
import com.massivecraft.factions.entity.Faction;
 | 
			
		||||
import com.massivecraft.factions.entity.MPerm;
 | 
			
		||||
import com.massivecraft.factions.entity.Rank;
 | 
			
		||||
import com.massivecraft.massivecore.MassiveCore;
 | 
			
		||||
import com.massivecraft.massivecore.collections.MassiveMap;
 | 
			
		||||
import com.massivecraft.massivecore.collections.MassiveSet;
 | 
			
		||||
import com.massivecraft.massivecore.store.MStore;
 | 
			
		||||
import com.massivecraft.massivecore.store.migrator.MigratorRoot;
 | 
			
		||||
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
public class MigratorFaction002Ranks extends MigratorRoot
 | 
			
		||||
{
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// INSTANCE & CONSTRUCT
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
	private static MigratorFaction002Ranks i = new MigratorFaction002Ranks();
 | 
			
		||||
	public static MigratorFaction002Ranks get() { return i; }
 | 
			
		||||
	private MigratorFaction002Ranks()
 | 
			
		||||
	{
 | 
			
		||||
		super(Faction.class);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// OVERRIDE
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void migrateInner(JsonObject entity)
 | 
			
		||||
	{
 | 
			
		||||
		String idLeader = MStore.createId();
 | 
			
		||||
		String idOfficer = MStore.createId();
 | 
			
		||||
		String idMember = MStore.createId();
 | 
			
		||||
		String idRecruit = MStore.createId();
 | 
			
		||||
 | 
			
		||||
		Rank leader = new Rank("Leader", 400);
 | 
			
		||||
		Rank officer = new Rank("Officer", 300);
 | 
			
		||||
		Rank member = new Rank("Member", 200);
 | 
			
		||||
		Rank recruit = new Rank("Recruit", 100);
 | 
			
		||||
 | 
			
		||||
		Map<String, Rank> map = new MassiveMap<>();
 | 
			
		||||
		map.put(idLeader, leader);
 | 
			
		||||
		map.put(idOfficer, officer);
 | 
			
		||||
		map.put(idMember, member);
 | 
			
		||||
		map.put(idRecruit, recruit);
 | 
			
		||||
 | 
			
		||||
		var jsonMap = MassiveCore.gson.toJsonTree(map, (new TypeToken<Map<String,Rank>>(){}).getType());
 | 
			
		||||
		entity.add("ranks", jsonMap);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		var priorPerms = entity.get("perms");
 | 
			
		||||
		var newPerms = getPerms(priorPerms, idLeader, idOfficer, idMember, idRecruit);
 | 
			
		||||
 | 
			
		||||
		var jsonPerms = MassiveCore.gson.toJsonTree(newPerms, (new TypeToken<Map<String,Set<String>>>(){}).getType());
 | 
			
		||||
		entity.add("perms", jsonPerms);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private Map<String, Set<String>> getPerms(JsonElement priorPerms, String leaderId, String officerId, String memberId, String recruitId)
 | 
			
		||||
	{
 | 
			
		||||
		// We start with default values ...
 | 
			
		||||
		Map<String, Set<String>> ret = new MassiveMap<>();
 | 
			
		||||
		for (MPerm mperm : MPerm.getAll())
 | 
			
		||||
		{
 | 
			
		||||
			Set<String> value = new MassiveSet<>(mperm.getStandard());
 | 
			
		||||
			if (value.remove("LEADER")) value.add(leaderId);
 | 
			
		||||
			if (value.remove("OFFICER")) value.add(officerId);
 | 
			
		||||
			if (value.remove("MEMBER")) value.add(memberId);
 | 
			
		||||
			if (value.remove("RECRUIT")) value.add(recruitId);
 | 
			
		||||
			ret.put(mperm.getId(), value);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (priorPerms != null)
 | 
			
		||||
		{
 | 
			
		||||
			Map<String,Set<String>> permMap = MassiveCore.gson.fromJson(priorPerms, (new TypeToken<Map<String,Set<String>>>(){}).getType());
 | 
			
		||||
			// ... and if anything is explicitly set we use that info ...
 | 
			
		||||
			Iterator<Map.Entry<String, Set<String>>> iter = permMap.entrySet().iterator();
 | 
			
		||||
			while (iter.hasNext())
 | 
			
		||||
			{
 | 
			
		||||
				// ... for each entry ...
 | 
			
		||||
				Map.Entry<String, Set<String>> entry = iter.next();
 | 
			
		||||
 | 
			
		||||
				// ... extract id and remove null values ...
 | 
			
		||||
				String id = entry.getKey();
 | 
			
		||||
				if (id == null)
 | 
			
		||||
				{
 | 
			
		||||
					iter.remove();
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				Set<String> value = entry.getValue();
 | 
			
		||||
				if (value.remove("LEADER")) value.add(leaderId);
 | 
			
		||||
				if (value.remove("OFFICER")) value.add(officerId);
 | 
			
		||||
				if (value.remove("MEMBER")) value.add(memberId);
 | 
			
		||||
				if (value.remove("RECRUIT")) value.add(recruitId);
 | 
			
		||||
				ret.put(id, value);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,81 @@
 | 
			
		||||
package com.massivecraft.factions.entity.migrator;
 | 
			
		||||
 | 
			
		||||
import com.google.gson.JsonElement;
 | 
			
		||||
import com.google.gson.JsonObject;
 | 
			
		||||
import com.massivecraft.factions.entity.MConf;
 | 
			
		||||
import com.massivecraft.massivecore.store.migrator.MigratorRoot;
 | 
			
		||||
 | 
			
		||||
public class MigratorMConf004Rank extends MigratorRoot
 | 
			
		||||
{
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// INSTANCE & CONSTRUCT
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
	private static MigratorMConf004Rank i = new MigratorMConf004Rank();
 | 
			
		||||
	public static MigratorMConf004Rank get() { return i; }
 | 
			
		||||
	private MigratorMConf004Rank() { super(MConf.class); }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// OVERRIDE
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void migrateInner(JsonObject entity)
 | 
			
		||||
	{
 | 
			
		||||
		migrateRename(entity, "denyCommandsTerritoryRelation");
 | 
			
		||||
		migrateRename(entity, "denyCommandsDistanceRelation");
 | 
			
		||||
		migrateRename(entity, "denyCommandsDistanceBypassIn");
 | 
			
		||||
 | 
			
		||||
		entity.remove("defaultPlayerRole");
 | 
			
		||||
		entity.remove("herochatFactionName");
 | 
			
		||||
		entity.remove("herochatFactionNick");
 | 
			
		||||
		entity.remove("herochatFactionFormat");
 | 
			
		||||
		entity.remove("herochatFactionColor");
 | 
			
		||||
		entity.remove("herochatFactionDistance");
 | 
			
		||||
		entity.remove("herochatFactionIsShortcutAllowed");
 | 
			
		||||
		entity.remove("herochatFactionCrossWorld");
 | 
			
		||||
		entity.remove("herochatFactionMuted");
 | 
			
		||||
		entity.remove("herochatFactionWorlds");
 | 
			
		||||
		entity.remove("herochatAlliesName");
 | 
			
		||||
		entity.remove("herochatAlliesNick");
 | 
			
		||||
		entity.remove("herochatAlliesFormat");
 | 
			
		||||
		entity.remove("herochatAlliesColor");
 | 
			
		||||
		entity.remove("herochatAlliesDistance");
 | 
			
		||||
		entity.remove("herochatAlliesIsShortcutAllowed");
 | 
			
		||||
		entity.remove("herochatAlliesCrossWorld");
 | 
			
		||||
		entity.remove("herochatAlliesMuted");
 | 
			
		||||
		entity.remove("herochatAlliesWorlds");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void migrateRename(JsonObject entity, String name)
 | 
			
		||||
	{
 | 
			
		||||
		JsonElement element = entity.get(name);
 | 
			
		||||
		if (element.isJsonObject())
 | 
			
		||||
		{
 | 
			
		||||
			JsonObject map = element.getAsJsonObject();
 | 
			
		||||
			if (map.has("MEMBER"))
 | 
			
		||||
			{
 | 
			
		||||
				var e = map.remove("MEMBER");
 | 
			
		||||
				map.add("FACTION", e);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (element.isJsonArray())
 | 
			
		||||
		{
 | 
			
		||||
			var array = element.getAsJsonArray();
 | 
			
		||||
			var success = false;
 | 
			
		||||
			for (var it = array.iterator(); it.hasNext(); )
 | 
			
		||||
			{
 | 
			
		||||
				var e = it.next();
 | 
			
		||||
				if (!e.getAsString().equals("MEMBER")) continue;
 | 
			
		||||
				it.remove();
 | 
			
		||||
				success = true;
 | 
			
		||||
			}
 | 
			
		||||
			if (success)
 | 
			
		||||
			{
 | 
			
		||||
				array.add("FACTION");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,43 @@
 | 
			
		||||
package com.massivecraft.factions.entity.migrator;
 | 
			
		||||
 | 
			
		||||
import com.google.gson.JsonObject;
 | 
			
		||||
import com.google.gson.JsonPrimitive;
 | 
			
		||||
import com.massivecraft.factions.entity.Faction;
 | 
			
		||||
import com.massivecraft.factions.entity.MPlayer;
 | 
			
		||||
import com.massivecraft.massivecore.store.migrator.MigratorRoot;
 | 
			
		||||
 | 
			
		||||
public class MigratorMPlayer001Ranks extends MigratorRoot
 | 
			
		||||
{
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// INSTANCE & CONSTRUCT
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
	private static MigratorMPlayer001Ranks i = new MigratorMPlayer001Ranks();
 | 
			
		||||
	public static MigratorMPlayer001Ranks get() { return i; }
 | 
			
		||||
	private MigratorMPlayer001Ranks()
 | 
			
		||||
	{
 | 
			
		||||
		super(MPlayer.class);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// OVERRIDE
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void migrateInner(JsonObject entity)
 | 
			
		||||
	{
 | 
			
		||||
		var role = entity.remove("role").getAsString();
 | 
			
		||||
		var factionId = entity.get("factionId").getAsString();
 | 
			
		||||
		var faction = Faction.get(factionId);
 | 
			
		||||
 | 
			
		||||
		var ranks = faction.getRanks().getAll();
 | 
			
		||||
		for (var rank : ranks)
 | 
			
		||||
		{
 | 
			
		||||
			if (!rank.getName().equalsIgnoreCase(role)) continue;
 | 
			
		||||
 | 
			
		||||
			entity.add("rankId", new JsonPrimitive(rank.getId()));
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
package com.massivecraft.factions.event;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.factions.Rel;
 | 
			
		||||
import com.massivecraft.factions.entity.Faction;
 | 
			
		||||
import com.massivecraft.factions.entity.MPerm;
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
@@ -26,8 +25,8 @@ public class EventFactionsPermChange extends EventFactionsAbstractSender
 | 
			
		||||
	private final MPerm perm;
 | 
			
		||||
	public MPerm getPerm() { return this.perm; }
 | 
			
		||||
	
 | 
			
		||||
	private final Rel rel;
 | 
			
		||||
	public Rel getRel() { return this.rel; }
 | 
			
		||||
	private final MPerm.MPermable permable;
 | 
			
		||||
	public MPerm.MPermable getRel() { return this.permable; }
 | 
			
		||||
	
 | 
			
		||||
	private boolean newValue;
 | 
			
		||||
	public boolean getNewValue() { return this.newValue; }
 | 
			
		||||
@@ -37,12 +36,12 @@ public class EventFactionsPermChange extends EventFactionsAbstractSender
 | 
			
		||||
	// CONSTRUCT
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public EventFactionsPermChange(CommandSender sender, Faction faction, MPerm perm, Rel rel, boolean newValue)
 | 
			
		||||
	public EventFactionsPermChange(CommandSender sender, Faction faction, MPerm perm, MPerm.MPermable permable, boolean newValue)
 | 
			
		||||
	{
 | 
			
		||||
		super(sender);
 | 
			
		||||
		this.faction = faction;
 | 
			
		||||
		this.perm = perm;
 | 
			
		||||
		this.rel = rel;
 | 
			
		||||
		this.permable = permable;
 | 
			
		||||
		this.newValue = newValue;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
package com.massivecraft.factions.event;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.factions.Rel;
 | 
			
		||||
import com.massivecraft.factions.entity.MPlayer;
 | 
			
		||||
import com.massivecraft.factions.entity.Rank;
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
import org.bukkit.event.HandlerList;
 | 
			
		||||
 | 
			
		||||
@@ -22,15 +22,15 @@ public class EventFactionsRankChange extends EventFactionsAbstractSender
 | 
			
		||||
	private final MPlayer mplayer;
 | 
			
		||||
	public MPlayer getMPlayer() { return this.mplayer; }
 | 
			
		||||
	
 | 
			
		||||
	private Rel newRank;
 | 
			
		||||
	public Rel getNewRank() { return this.newRank; }
 | 
			
		||||
	public void setNewRank(Rel newRole) { this.newRank = newRole; }
 | 
			
		||||
	private Rank newRank;
 | 
			
		||||
	public Rank getNewRank() { return this.newRank; }
 | 
			
		||||
	public void setNewRank(Rank newRole) { this.newRank = newRole; }
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// CONSTRUCT
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public EventFactionsRankChange(CommandSender sender, MPlayer mplayer, Rel newRank)
 | 
			
		||||
	public EventFactionsRankChange(CommandSender sender, MPlayer mplayer, Rank newRank)
 | 
			
		||||
	{
 | 
			
		||||
		super(sender);
 | 
			
		||||
		this.mplayer = mplayer;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,26 +1,27 @@
 | 
			
		||||
package com.massivecraft.factions.predicate;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.factions.Rel;
 | 
			
		||||
import com.massivecraft.factions.entity.Faction;
 | 
			
		||||
import com.massivecraft.factions.entity.MPlayer;
 | 
			
		||||
import com.massivecraft.factions.entity.Rank;
 | 
			
		||||
import com.massivecraft.massivecore.predicate.Predicate;
 | 
			
		||||
 | 
			
		||||
public class PredicateMPlayerRole implements Predicate<MPlayer>
 | 
			
		||||
public class PredicateMPlayerRank implements Predicate<MPlayer>
 | 
			
		||||
{
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// FIELDS
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	private final Rel role;
 | 
			
		||||
	public Rel getRole() { return this.role; }
 | 
			
		||||
	private final Rank rank;
 | 
			
		||||
	public Rank getRank() { return this.rank; }
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// INSTANCE AND CONTRUCT
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public static PredicateMPlayerRole get(Rel role) { return new PredicateMPlayerRole(role); }
 | 
			
		||||
	public PredicateMPlayerRole(Rel role)
 | 
			
		||||
	public static PredicateMPlayerRank get(Rank rank) { return new PredicateMPlayerRank(rank); }
 | 
			
		||||
	public PredicateMPlayerRank(Rank rank)
 | 
			
		||||
	{
 | 
			
		||||
		this.role = role;
 | 
			
		||||
		this.rank = rank;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
@@ -31,6 +32,8 @@ public class PredicateMPlayerRole implements Predicate<MPlayer>
 | 
			
		||||
	public boolean apply(MPlayer mplayer)
 | 
			
		||||
	{
 | 
			
		||||
		if (mplayer == null) return false;
 | 
			
		||||
		return mplayer.getRole() == this.role;
 | 
			
		||||
		Faction faction = mplayer.getFaction();
 | 
			
		||||
		if (!faction.hasRank(this.getRank())) throw new IllegalStateException("rank: " + rank.getId() + " player:" + mplayer.getId());
 | 
			
		||||
		return mplayer.getRank() == this.rank;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -99,8 +99,7 @@ public class RelationUtil
 | 
			
		||||
		
 | 
			
		||||
		if (myFaction.equals(thatFaction))
 | 
			
		||||
		{
 | 
			
		||||
			if (that instanceof MPlayer) return ((MPlayer) that).getRole();
 | 
			
		||||
			return Rel.MEMBER;
 | 
			
		||||
			return Rel.FACTION;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		MFlag flagPeaceful = MFlag.getFlagPeaceful();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user