diff --git a/plugin.yml b/plugin.yml index 3c528166..554476fe 100644 --- a/plugin.yml +++ b/plugin.yml @@ -53,6 +53,7 @@ permissions: factions.show: {description: show faction information, default: false} factions.name: {description: set faction name, default: false} factions.title: {description: set player title, default: false} + factions.title.color: {description: set player title with color, default: false} factions.unclaim: {description: unclaim land where you stand, default: false} factions.unclaimall: {description: unclaim all land, default: false} factions.version: {description: see plugin version, default: false} @@ -98,6 +99,7 @@ permissions: factions.show: true factions.name: true factions.title: true + factions.title.color: true factions.unclaim: true factions.unclaimall: true factions.version: true @@ -168,6 +170,7 @@ permissions: factions.show: true factions.name: true factions.title: true + factions.title.color: true factions.unclaim: true factions.unclaimall: true factions.version: true diff --git a/src/com/massivecraft/factions/Perm.java b/src/com/massivecraft/factions/Perm.java index 7b430e72..117a496d 100644 --- a/src/com/massivecraft/factions/Perm.java +++ b/src/com/massivecraft/factions/Perm.java @@ -54,6 +54,7 @@ public enum Perm SHOW("show"), NAME("name"), TITLE("title"), + TITLE_COLOR("title.color"), UNCLAIM("unclaim"), UNCLAIM_ALL("unclaimall"), VERSION("version"), diff --git a/src/com/massivecraft/factions/PlayerRoleComparator.java b/src/com/massivecraft/factions/PlayerRoleComparator.java new file mode 100644 index 00000000..fe3da2ef --- /dev/null +++ b/src/com/massivecraft/factions/PlayerRoleComparator.java @@ -0,0 +1,35 @@ +package com.massivecraft.factions; + +import java.util.Comparator; + +import com.massivecraft.factions.entity.UPlayer; + +public class PlayerRoleComparator implements Comparator +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static PlayerRoleComparator i = new PlayerRoleComparator(); + public static PlayerRoleComparator get() { return i; } + + // -------------------------------------------- // + // OVERRIDE: COMPARATOR + // -------------------------------------------- // + + @Override + public int compare(UPlayer o1, UPlayer o2) + { + int ret = 0; + + // Null + if (o1 == null && o2 == null) ret = 0; + if (o1 == null) ret = -1; + if (o2 == null) ret = +1; + if (ret != 0) return ret; + + // Rank + return o2.getRole().getValue() - o1.getRole().getValue(); + } + +} diff --git a/src/com/massivecraft/factions/Rel.java b/src/com/massivecraft/factions/Rel.java index 08f79d0e..debacb90 100644 --- a/src/com/massivecraft/factions/Rel.java +++ b/src/com/massivecraft/factions/Rel.java @@ -27,7 +27,9 @@ public enum Rel // FIELDS // -------------------------------------------- // + // TODO: Are not enums sorted without this? private final int value; + public int getValue() { return this.value; } // Used for friendly fire. private final boolean friend; diff --git a/src/com/massivecraft/factions/TerritoryAccess.java b/src/com/massivecraft/factions/TerritoryAccess.java index 18be7d2d..966761eb 100644 --- a/src/com/massivecraft/factions/TerritoryAccess.java +++ b/src/com/massivecraft/factions/TerritoryAccess.java @@ -183,7 +183,7 @@ public class TerritoryAccess public boolean subjectAccessIsRestricted(Object testSubject) { Faction hostFaction = FactionColls.get().get(testSubject).get(this.getHostFactionId()); - return ( ! this.isHostFactionAllowed() && this.doesHostFactionMatch(testSubject) && ! FPerm.ACCESS.has(testSubject, hostFaction)); + return ( ! this.isHostFactionAllowed() && this.doesHostFactionMatch(testSubject) && ! FPerm.ACCESS.has(testSubject, hostFaction, false)); } //----------------------------------------------// diff --git a/src/com/massivecraft/factions/cmd/CmdFactionsKick.java b/src/com/massivecraft/factions/cmd/CmdFactionsKick.java index 0a656138..32df7b31 100644 --- a/src/com/massivecraft/factions/cmd/CmdFactionsKick.java +++ b/src/com/massivecraft/factions/cmd/CmdFactionsKick.java @@ -57,7 +57,7 @@ public class CmdFactionsKick extends FCommand // FPerm Faction uplayerFaction = uplayer.getFaction(); - if (!FPerm.KICK.has(sender, uplayerFaction)) return; + if (!FPerm.KICK.has(sender, uplayerFaction, true)) return; // Event FactionsEventMembershipChange event = new FactionsEventMembershipChange(sender, uplayer, FactionColls.get().get(uplayer).getNone(), MembershipChangeReason.KICK); diff --git a/src/com/massivecraft/factions/cmd/CmdFactionsShow.java b/src/com/massivecraft/factions/cmd/CmdFactionsShow.java index b7031f3f..85f717a1 100644 --- a/src/com/massivecraft/factions/cmd/CmdFactionsShow.java +++ b/src/com/massivecraft/factions/cmd/CmdFactionsShow.java @@ -1,7 +1,7 @@ package com.massivecraft.factions.cmd; import java.util.ArrayList; -import java.util.Collection; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -15,6 +15,7 @@ import com.massivecraft.factions.event.FactionsEventChunkChangeType; import com.massivecraft.factions.integration.Econ; import com.massivecraft.factions.FFlag; import com.massivecraft.factions.Perm; +import com.massivecraft.factions.PlayerRoleComparator; import com.massivecraft.factions.Rel; import com.massivecraft.mcore.cmd.req.ReqHasPerm; import com.massivecraft.mcore.mixin.Mixin; @@ -38,73 +39,80 @@ public class CmdFactionsShow extends FCommand @Override public void perform() { + // Args Faction faction = this.arg(0, ARFaction.get(usenderFaction), usenderFaction); if (faction == null) return; + // Data precalculation UConf uconf = UConf.get(faction); + //boolean none = faction.isNone(); + boolean normal = faction.isNormal(); // INFO: Description msg(Txt.titleize(faction.getName(usender))); - msg("Description: %s", faction.getDescription()); + msg("Description: %s", faction.getDescription()); - // INFO: Age - long ageMillis = faction.getCreatedAtMillis() - System.currentTimeMillis(); - LinkedHashMap ageUnitcounts = TimeDiffUtil.limit(TimeDiffUtil.unitcounts(ageMillis, TimeUnit.getAllButMillis()), 3); - String ageString = TimeDiffUtil.formatedVerboose(ageUnitcounts, ""); - msg("Age: %s", ageString); - - // Display important flags - // TODO: Find the non default flags, and display them instead. - if (faction.getFlag(FFlag.PERMANENT)) + if (normal) { - msg("This faction is permanent - remaining even with no members."); - } - - if (faction.getFlag(FFlag.PEACEFUL)) - { - msg("This faction is peaceful - in truce with everyone."); - } - - // INFO: Open - msg("Open: "+(faction.isOpen() ? "Yes - anyone can join" : "No - only invited people can join")); - - // INFO: Power - double powerBoost = faction.getPowerBoost(); - String boost = (powerBoost == 0.0) ? "" : (powerBoost > 0.0 ? " (bonus: " : " (penalty: ") + powerBoost + ")"; - msg("Land / Power / Maxpower: %d/%d/%d %s", faction.getLandCount(), faction.getPowerRounded(), faction.getPowerMaxRounded(), boost); - - // show the land value - if (Econ.isEnabled(faction)) - { - long landCount = faction.getLandCount(); + // INFO: Age + long ageMillis = faction.getCreatedAtMillis() - System.currentTimeMillis(); + LinkedHashMap ageUnitcounts = TimeDiffUtil.limit(TimeDiffUtil.unitcounts(ageMillis, TimeUnit.getAllButMillis()), 3); + String ageString = TimeDiffUtil.formatedVerboose(ageUnitcounts, ""); + msg("Age: %s", ageString); - for (FactionsEventChunkChangeType type : FactionsEventChunkChangeType.values()) + // INFO: Open + msg("Open: "+(faction.isOpen() ? "Yes, anyone can join" : "No, only invited people can join")); + + // INFO: Power + double powerBoost = faction.getPowerBoost(); + String boost = (powerBoost == 0.0) ? "" : (powerBoost > 0.0 ? " (bonus: " : " (penalty: ") + powerBoost + ")"; + msg("Land / Power / Maxpower: %d/%d/%d %s", faction.getLandCount(), faction.getPowerRounded(), faction.getPowerMaxRounded(), boost); + + // show the land value + if (Econ.isEnabled(faction)) { - Double money = uconf.econChunkCost.get(type); - if (money == null) money = 0D; - money *= landCount; + long landCount = faction.getLandCount(); - String word = null; - if (money > 0) + for (FactionsEventChunkChangeType type : FactionsEventChunkChangeType.values()) { - word = "cost"; - } - else - { - word = "reward"; - money *= -1; + Double money = uconf.econChunkCost.get(type); + if (money == null) money = 0D; + money *= landCount; + + String word = null; + if (money > 0) + { + word = "cost"; + } + else + { + word = "reward"; + money *= -1; + } + + msg("Total land %s %s: %s", type.toString().toLowerCase(), word, Money.format(faction, money)); } - msg("Total land %s %s: %s", type.toString().toLowerCase(), word, Money.format(faction, money)); + // Show bank contents + if (UConf.get(faction).bankEnabled) + { + msg("Bank contains: "+Money.format(faction, Money.get(faction))); + } } - // Show bank contents - if (UConf.get(faction).bankEnabled) + // Display important flags + // TODO: Find the non default flags, and display them instead. + if (faction.getFlag(FFlag.PERMANENT)) { - msg("Bank contains: "+Money.format(faction, Money.get(faction))); + msg("This faction is permanent - remaining even with no followers."); + } + + if (faction.getFlag(FFlag.PEACEFUL)) + { + msg("This faction is peaceful - in truce with everyone."); } } - + String sepparator = Txt.parse("")+", "; // List the relations to other factions @@ -119,68 +127,35 @@ public class CmdFactionsShow extends FCommand sendMessage(Txt.parse("In Truce with: ") + Txt.implode(relationNames.get(Rel.TRUCE), sepparator)); } - sendMessage(Txt.parse("Allied to: ") + Txt.implode(relationNames.get(Rel.ALLY), sepparator)); + sendMessage(Txt.parse("Allies: ") + Txt.implode(relationNames.get(Rel.ALLY), sepparator)); sendMessage(Txt.parse("Enemies: ") + Txt.implode(relationNames.get(Rel.ENEMY), sepparator)); - // List the members... + // List the followers... + List followerNamesOnline = new ArrayList(); + List followerNamesOffline = new ArrayList(); - Collection leaders = faction.getUPlayersWhereRole(Rel.LEADER); - Collection officers = faction.getUPlayersWhereRole(Rel.OFFICER); - Collection normals = faction.getUPlayersWhereRole(Rel.MEMBER); - Collection recruits = faction.getUPlayersWhereRole(Rel.RECRUIT); + List followers = faction.getUPlayers(); + Collections.sort(followers, PlayerRoleComparator.get()); - List memberOnlineNames = new ArrayList(); - List memberOfflineNames = new ArrayList(); - - for (UPlayer follower : leaders) + for (UPlayer follower : followers) { - if (follower.isOnline() && Mixin.isVisible(me, follower.getId())) + if (follower.isOnline() && Mixin.isVisible(sender, follower.getId())) { - memberOnlineNames.add(follower.getNameAndTitle(usender)); + followerNamesOnline.add(follower.getNameAndTitle(usender)); } - else + else if (normal) { - memberOfflineNames.add(follower.getNameAndTitle(usender)); + // For the non-faction we skip the offline members since they are far to many (infinate almost) + followerNamesOffline.add(follower.getNameAndTitle(usender)); } } - for (UPlayer follower : officers) - { - if (follower.isOnline() && Mixin.isVisible(me, follower.getId())) - { - memberOnlineNames.add(follower.getNameAndTitle(usender)); - } - else - { - memberOfflineNames.add(follower.getNameAndTitle(usender)); - } - } + sendMessage(Txt.parse("Followers online (%s): ", followerNamesOnline.size()) + Txt.implode(followerNamesOnline, sepparator)); - for (UPlayer follower : normals) + if (normal) { - if (follower.isOnline() && Mixin.isVisible(me, follower.getId())) - { - memberOnlineNames.add(follower.getNameAndTitle(usender)); - } - else - { - memberOfflineNames.add(follower.getNameAndTitle(usender)); - } + sendMessage(Txt.parse("Followers offline (%s): ", followerNamesOffline.size()) + Txt.implode(followerNamesOffline, sepparator)); } - - for (UPlayer follower : recruits) - { - if (follower.isOnline()) - { - memberOnlineNames.add(follower.getNameAndTitle(usender)); - } - else - { - memberOfflineNames.add(follower.getNameAndTitle(usender)); - } - } - sendMessage(Txt.parse("Members online: ") + Txt.implode(memberOnlineNames, sepparator)); - sendMessage(Txt.parse("Members offline: ") + Txt.implode(memberOfflineNames, sepparator)); } } diff --git a/src/com/massivecraft/factions/cmd/CmdFactionsTitle.java b/src/com/massivecraft/factions/cmd/CmdFactionsTitle.java index c5b5cb46..08b999e1 100644 --- a/src/com/massivecraft/factions/cmd/CmdFactionsTitle.java +++ b/src/com/massivecraft/factions/cmd/CmdFactionsTitle.java @@ -1,5 +1,7 @@ package com.massivecraft.factions.cmd; +import org.bukkit.ChatColor; + import com.massivecraft.factions.Perm; import com.massivecraft.factions.Rel; import com.massivecraft.factions.cmd.arg.ARUPlayer; @@ -9,6 +11,7 @@ import com.massivecraft.factions.entity.UPlayer; import com.massivecraft.factions.event.FactionsEventTitleChange; import com.massivecraft.mcore.cmd.arg.ARString; import com.massivecraft.mcore.cmd.req.ReqHasPerm; +import com.massivecraft.mcore.util.Txt; public class CmdFactionsTitle extends FCommand { @@ -34,6 +37,12 @@ public class CmdFactionsTitle extends FCommand String newTitle = this.argConcatFrom(1, ARString.get(), ""); if (newTitle == null) return; + newTitle = Txt.parse(newTitle); + if (!Perm.TITLE_COLOR.has(sender, false)) + { + newTitle = ChatColor.stripColor(newTitle); + } + // Verify if ( ! canIAdministerYou(usender, you)) return; diff --git a/src/com/massivecraft/factions/entity/UPlayer.java b/src/com/massivecraft/factions/entity/UPlayer.java index abd8b8e2..b5bffe03 100644 --- a/src/com/massivecraft/factions/entity/UPlayer.java +++ b/src/com/massivecraft/factions/entity/UPlayer.java @@ -284,6 +284,13 @@ public class UPlayer extends SenderEntity implements EconomyParticipato } } + // NOTE: That we parse the title here is considered part of the 1.8 --> 2.0 migration. + // This should be removed once the migration phase is considered to be over. + if (target != null) + { + target = Txt.parse(target); + } + // Detect Nochange if (MUtil.equals(this.title, target)) return; @@ -421,44 +428,48 @@ public class UPlayer extends SenderEntity implements EconomyParticipato // Base concatenations: - public String getNameAndSomething(String something) + public String getNameAndSomething(String color, String something) { - String ret = this.getRole().getPrefix(); + String ret = ""; + ret += color; + ret += this.getRole().getPrefix(); if (something != null && something.length() > 0) { - ret += something+" "; + ret += something; + ret += " "; + ret += color; } ret += this.getName(); return ret; } - public String getNameAndTitle() + public String getNameAndFactionName() + { + return this.getNameAndSomething("", this.getFactionName()); + } + + public String getNameAndTitle(String color) { if (this.hasTitle()) { - return this.getNameAndSomething(this.getTitle()); + return this.getNameAndSomething(color, this.getTitle()); } else { - return this.getNameAndSomething(null); + return this.getNameAndSomething(color, null); } } - public String getNameAndFactionName() - { - return this.getNameAndSomething(this.getFactionName()); - } - // Colored concatenations: // These are used in information messages public String getNameAndTitle(Faction faction) { - return this.getColorTo(faction)+this.getNameAndTitle(); + return this.getNameAndTitle(this.getColorTo(faction).toString()); } public String getNameAndTitle(UPlayer uplayer) { - return this.getColorTo(uplayer)+this.getNameAndTitle(); + return this.getNameAndTitle(this.getColorTo(uplayer).toString()); } // -------------------------------------------- // diff --git a/src/com/massivecraft/factions/integration/Econ.java b/src/com/massivecraft/factions/integration/Econ.java index 7e819ec7..4781ac61 100644 --- a/src/com/massivecraft/factions/integration/Econ.java +++ b/src/com/massivecraft/factions/integration/Econ.java @@ -89,7 +89,7 @@ public class Econ if (i == fI && fI == fYou) return true; // Factions can be controlled by those that have permissions - if (you instanceof Faction && FPerm.WITHDRAW.has(i, fYou)) return true; + if (you instanceof Faction && FPerm.WITHDRAW.has(i, fYou, false)) return true; // Otherwise you may not! ;,,; i.msg("%s lacks permission to control %s's money.", i.describeTo(i, true), you.describeTo(i)); diff --git a/src/com/massivecraft/factions/util/RelationUtil.java b/src/com/massivecraft/factions/util/RelationUtil.java index 84d5a147..2cb47981 100644 --- a/src/com/massivecraft/factions/util/RelationUtil.java +++ b/src/com/massivecraft/factions/util/RelationUtil.java @@ -47,7 +47,7 @@ public class RelationUtil } else if (thatFaction == myFaction) { - ret = uplayerthat.getNameAndTitle(); + ret = uplayerthat.getNameAndTitle(myFaction); } else {