Variable overhaul and configurable /f show
This commit is contained in:
parent
dbba8c055c
commit
44542261ae
@ -1,27 +1,39 @@
|
||||
package com.massivecraft.factions.cmd;
|
||||
|
||||
import com.massivecraft.factions.Conf;
|
||||
import com.massivecraft.factions.FPlayer;
|
||||
import com.massivecraft.factions.Faction;
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.factions.integration.Econ;
|
||||
import com.massivecraft.factions.P;
|
||||
import com.massivecraft.factions.struct.Permission;
|
||||
import com.massivecraft.factions.struct.Relation;
|
||||
import com.massivecraft.factions.util.MiscUtil;
|
||||
import com.massivecraft.factions.zcore.util.TL;
|
||||
import com.massivecraft.factions.zcore.util.TagReplacer;
|
||||
import com.massivecraft.factions.zcore.util.TagUtil;
|
||||
import mkremins.fanciful.FancyMessage;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CmdShow extends FCommand {
|
||||
private static final int ARBITRARY_LIMIT = 25000;
|
||||
|
||||
List<String> defaults = new ArrayList<String>();
|
||||
|
||||
public CmdShow() {
|
||||
this.aliases.add("show");
|
||||
this.aliases.add("who");
|
||||
|
||||
// add defaults to /f show in case config doesnt have it
|
||||
defaults.add("{header}");
|
||||
defaults.add("<a>Description: <i>{description}");
|
||||
defaults.add("<a>Joining: <i>{joining} {peaceful}");
|
||||
defaults.add("<a>Land / Power / Maxpower: <i> {chunks} / {power} / {maxPower}");
|
||||
defaults.add("<a>Faction Home: <i>{world}, {x}, {y}, {z}");
|
||||
defaults.add("<a>Founded: <i>{create-date}");
|
||||
defaults.add("<a>This faction is permanent, remaining even with no members.");
|
||||
defaults.add("<a>Land value: <i>{land-value} {land-refund}");
|
||||
defaults.add("<a>Balance: <i>{balance}");
|
||||
defaults.add("<a>Allies(<i>{allies}<a>/<i>{max-allies}<a>): {allies-list}");
|
||||
defaults.add("<a>Online: (<i>{online}<a>/<i>{members}<a>): {online-list}");
|
||||
defaults.add("<a>Offline: (<i>{offline}<a>/<i>{members}<a>): {offline-list}");
|
||||
|
||||
// this.requiredArgs.add("");
|
||||
this.optionalArgs.put("faction tag", "yours");
|
||||
|
||||
@ -39,140 +51,49 @@ public class CmdShow extends FCommand {
|
||||
if (this.argIsSet(0)) {
|
||||
faction = this.argAsFaction(0);
|
||||
}
|
||||
|
||||
if (faction == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if economy is enabled, they're not on the bypass list, and this
|
||||
// command has a cost set, make 'em pay
|
||||
// if economy is enabled, they're not on the bypass list, and this command has a cost set, make 'em pay
|
||||
if (!payForCommand(Conf.econCostShow, TL.COMMAND_SHOW_TOSHOW, TL.COMMAND_SHOW_FORSHOW)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String peaceStatus = "";
|
||||
if (faction.isPeaceful()) {
|
||||
peaceStatus = " " + Conf.colorNeutral + TL.COMMAND_SHOW_PEACEFUL.toString();
|
||||
List<String> show = P.p.getConfig().getStringList("show");
|
||||
if (show == null || show.isEmpty()) {
|
||||
show = defaults;
|
||||
}
|
||||
|
||||
double powerBoost = faction.getPowerBoost();
|
||||
String boost = (powerBoost == 0.0) ? "" : (powerBoost > 0.0 ? TL.COMMAND_SHOW_BONUS.toString() : TL.COMMAND_SHOW_PENALTY.toString() + powerBoost + ")");
|
||||
|
||||
List<FancyMessage> allies = new ArrayList<FancyMessage>();
|
||||
List<FancyMessage> enemies = new ArrayList<FancyMessage>();
|
||||
if (!faction.isNone()) {
|
||||
FancyMessage currentAllies = new FancyMessage(TL.COMMAND_SHOW_ALLIES.toString()).color(ChatColor.GOLD);
|
||||
FancyMessage currentEnemies = new FancyMessage(TL.COMMAND_SHOW_ENEMIES.toString()).color(ChatColor.GOLD);
|
||||
|
||||
boolean firstAlly = true;
|
||||
boolean firstEnemy = true;
|
||||
for (Faction otherFaction : Factions.getInstance().getAllFactions()) {
|
||||
if (otherFaction == faction) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Relation rel = otherFaction.getRelationTo(faction);
|
||||
String s = otherFaction.getTag(fme);
|
||||
if (rel.isAlly()) {
|
||||
if (firstAlly) {
|
||||
currentAllies.then(s).tooltip(getToolTips(otherFaction));
|
||||
} else {
|
||||
currentAllies.then(", " + s).tooltip(getToolTips(otherFaction));
|
||||
}
|
||||
firstAlly = false;
|
||||
|
||||
if (currentAllies.toJSONString().length() > ARBITRARY_LIMIT) {
|
||||
allies.add(currentAllies);
|
||||
currentAllies = new FancyMessage("");
|
||||
}
|
||||
} else if (rel.isEnemy()) {
|
||||
if (firstEnemy) {
|
||||
currentEnemies.then(s).tooltip(getToolTips(otherFaction));
|
||||
} else {
|
||||
currentEnemies.then(", " + s).tooltip(getToolTips(otherFaction));
|
||||
}
|
||||
firstEnemy = false;
|
||||
|
||||
if (currentEnemies.toJSONString().length() > ARBITRARY_LIMIT) {
|
||||
enemies.add(currentEnemies);
|
||||
currentEnemies = new FancyMessage("");
|
||||
}
|
||||
}
|
||||
}
|
||||
allies.add(currentAllies);
|
||||
enemies.add(currentEnemies);
|
||||
}
|
||||
|
||||
List<FancyMessage> online = new ArrayList<FancyMessage>();
|
||||
List<FancyMessage> offline = new ArrayList<FancyMessage>();
|
||||
if (!faction.isNone()) {
|
||||
FancyMessage currentOnline = new FancyMessage(TL.COMMAND_SHOW_MEMBERSONLINE.toString()).color(ChatColor.GOLD);
|
||||
FancyMessage currentOffline = new FancyMessage(TL.COMMAND_SHOW_MEMBERSOFFLINE.toString()).color(ChatColor.GOLD);
|
||||
boolean firstOnline = true;
|
||||
boolean firstOffline = true;
|
||||
for (FPlayer p : MiscUtil.rankOrder(faction.getFPlayers())) {
|
||||
String name = p.getNameAndTitle();
|
||||
if (p.isOnline()) {
|
||||
if (firstOnline) {
|
||||
currentOnline.then(name).tooltip(getToolTips(p));
|
||||
} else {
|
||||
currentOnline.then(", " + name).tooltip(getToolTips(p));
|
||||
}
|
||||
firstOnline = false;
|
||||
|
||||
if (currentOnline.toJSONString().length() > ARBITRARY_LIMIT) {
|
||||
online.add(currentOnline);
|
||||
currentOnline = new FancyMessage();
|
||||
}
|
||||
} else {
|
||||
if (firstOffline) {
|
||||
currentOffline.then(name).tooltip(getToolTips(p));
|
||||
} else {
|
||||
currentOffline.then(", " + name).tooltip(getToolTips(p));
|
||||
}
|
||||
firstOffline = false;
|
||||
|
||||
if (currentOffline.toJSONString().length() > ARBITRARY_LIMIT) {
|
||||
offline.add(currentOffline);
|
||||
currentOffline = new FancyMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
online.add(currentOnline);
|
||||
offline.add(currentOffline);
|
||||
}
|
||||
|
||||
// Send all at once ;D
|
||||
msg(p.txt.titleize(faction.getTag(fme)));
|
||||
msg(TL.COMMAND_SHOW_DESCRIPTION, faction.getDescription());
|
||||
if (!faction.isNormal()) {
|
||||
return;
|
||||
}
|
||||
msg(TL.COMMAND_SHOW_JOINING.toString() + peaceStatus, (faction.getOpen() ? TL.COMMAND_SHOW_UNINVITED.toString() : TL.COMMAND_SHOW_INVITATION.toString()));
|
||||
msg(TL.COMMAND_SHOW_POWER, faction.getLandRounded(), faction.getPowerRounded(), faction.getPowerMaxRounded(), boost);
|
||||
if (faction.isPermanent()) {
|
||||
msg(TL.COMMAND_SHOW_PERMANENT);
|
||||
}
|
||||
// show the land value
|
||||
if (Econ.shouldBeUsed()) {
|
||||
double value = Econ.calculateTotalLandValue(faction.getLandRounded());
|
||||
double refund = value * Conf.econClaimRefundMultiplier;
|
||||
if (value > 0) {
|
||||
String stringValue = Econ.moneyString(value);
|
||||
String stringRefund = (refund > 0.0) ? (TL.COMMAND_SHOW_DEPRECIATED.format(Econ.moneyString(refund))) : "";
|
||||
msg(TL.COMMAND_SHOW_LANDVALUE, stringValue, stringRefund);
|
||||
}
|
||||
|
||||
// Show bank contents
|
||||
if (Conf.bankEnabled) {
|
||||
msg(TL.COMMAND_SHOW_BANKCONTAINS, Econ.moneyString(Econ.getBalance(faction.getAccountId())));
|
||||
String tag = faction.getTag(fme);
|
||||
// send header and that's all
|
||||
String header = show.get(0);
|
||||
if (TagReplacer.HEADER.contains(header)) {
|
||||
msg(p.txt.titleize(tag));
|
||||
} else {
|
||||
msg(p.txt.parse(TagReplacer.FACTION.replace(header, tag)));
|
||||
}
|
||||
return; // we only show header for non-normal factions
|
||||
}
|
||||
|
||||
sendFancyMessage(allies);
|
||||
sendFancyMessage(enemies);
|
||||
sendFancyMessage(online);
|
||||
sendFancyMessage(offline);
|
||||
for (String raw : show) {
|
||||
String parsed = TagUtil.parsePlain(faction, fme, raw); // use relations
|
||||
if (TagUtil.hasFancy(parsed)) {
|
||||
List<FancyMessage> fancy = TagUtil.parseFancy(faction, fme, parsed);
|
||||
if (fancy != null) {
|
||||
sendFancyMessage(fancy);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!parsed.contains("{notFrozen}") && !parsed.contains("{notPermanent}")) {
|
||||
if (parsed.contains("{ig}")) {
|
||||
// replaces all variables with no home TL
|
||||
parsed = parsed.substring(0, parsed.indexOf("{ig}")) + TL.COMMAND_SHOW_NOHOME.toString();
|
||||
}
|
||||
msg(p.txt.parse(parsed));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -173,6 +173,8 @@ public class CmdTop extends FCommand {
|
||||
private String getValue(Faction faction, String criteria) {
|
||||
if (criteria.equalsIgnoreCase("online")) {
|
||||
return String.valueOf(faction.getFPlayersWhereOnline(true).size());
|
||||
} else if (criteria.equalsIgnoreCase("start")) {
|
||||
return TL.sdf.format(faction.getFoundedDate());
|
||||
} else if (criteria.equalsIgnoreCase("members")) {
|
||||
return String.valueOf(faction.getFPlayers().size());
|
||||
} else if (criteria.equalsIgnoreCase("land")) {
|
||||
|
@ -1,11 +1,36 @@
|
||||
package com.massivecraft.factions.scoreboards;
|
||||
|
||||
import com.massivecraft.factions.FPlayer;
|
||||
import com.massivecraft.factions.Faction;
|
||||
import com.massivecraft.factions.P;
|
||||
import com.massivecraft.factions.zcore.util.TL;
|
||||
import com.massivecraft.factions.zcore.util.TagUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class FSidebarProvider {
|
||||
|
||||
public abstract String getTitle(FPlayer fplayer);
|
||||
|
||||
public abstract List<String> getLines(FPlayer fplayer);
|
||||
}
|
||||
|
||||
public String replaceTags(FPlayer fPlayer, String s) {
|
||||
return qualityAssure(TagUtil.parsePlain(fPlayer, s));
|
||||
}
|
||||
|
||||
public String replaceTags(Faction faction, FPlayer fPlayer, String s) {
|
||||
return qualityAssure(TagUtil.parsePlain(faction, fPlayer, s));
|
||||
}
|
||||
|
||||
private String qualityAssure(String line) {
|
||||
if (line.contains("{notFrozen}") || line.contains("{notPermanent}")) {
|
||||
return "n/a"; // we dont support support these error variables in scoreboards
|
||||
}
|
||||
if (line.contains("{ig}")) {
|
||||
// since you can't really fit a whole "Faction Home: world, x, y, z" on one line
|
||||
// we assume it's broken up into two lines, so returning our tl will suffice.
|
||||
return TL.COMMAND_SHOW_NOHOME.toString();
|
||||
}
|
||||
return P.p.txt.parse(line); // finally add color :)
|
||||
}
|
||||
}
|
@ -2,12 +2,7 @@ package com.massivecraft.factions.scoreboards.sidebar;
|
||||
|
||||
import com.massivecraft.factions.FPlayer;
|
||||
import com.massivecraft.factions.P;
|
||||
import com.massivecraft.factions.integration.Econ;
|
||||
import com.massivecraft.factions.scoreboards.FSidebarProvider;
|
||||
import com.massivecraft.factions.zcore.util.TL;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
@ -16,7 +11,7 @@ public class FDefaultSidebar extends FSidebarProvider {
|
||||
|
||||
@Override
|
||||
public String getTitle(FPlayer fplayer) {
|
||||
return replace(fplayer, P.p.getConfig().getString("scoreboard.default-title", "i love drt"));
|
||||
return replaceTags(fplayer, P.p.getConfig().getString("scoreboard.default-title", "i love drt"));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -25,15 +20,8 @@ public class FDefaultSidebar extends FSidebarProvider {
|
||||
|
||||
ListIterator<String> it = lines.listIterator();
|
||||
while (it.hasNext()) {
|
||||
it.set(replace(fplayer, it.next()));
|
||||
it.set(replaceTags(fplayer, it.next()));
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
private String replace(FPlayer fplayer, String s) {
|
||||
String faction = !fplayer.getFaction().isNone() ? fplayer.getFaction().getTag() : TL.GENERIC_FACTIONLESS.toString();
|
||||
String powerBoost = String.valueOf((int) fplayer.getPowerBoost());
|
||||
s = s.replace("{name}", fplayer.getName()).replace("{power}", String.valueOf(fplayer.getPowerRounded())).replace("{balance}", String.valueOf(Econ.getFriendlyBalance(fplayer.getPlayer().getUniqueId()))).replace("{faction}", faction).replace("{maxPower}", String.valueOf(fplayer.getPowerMaxRounded())).replace("{totalOnline}", String.valueOf(Bukkit.getServer().getOnlinePlayers().size())).replace("{powerBoost}", powerBoost);
|
||||
return ChatColor.translateAlternateColorCodes('&', s);
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@ import com.massivecraft.factions.FPlayer;
|
||||
import com.massivecraft.factions.Faction;
|
||||
import com.massivecraft.factions.P;
|
||||
import com.massivecraft.factions.scoreboards.FSidebarProvider;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
@ -27,16 +26,8 @@ public class FInfoSidebar extends FSidebarProvider {
|
||||
|
||||
ListIterator<String> it = lines.listIterator();
|
||||
while (it.hasNext()) {
|
||||
it.set(replaceFInfoTags(it.next()));
|
||||
it.set(replaceTags(faction, fplayer, it.next()));
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
private String replaceFInfoTags(String s) {
|
||||
boolean raidable = faction.getLandRounded() > faction.getPower();
|
||||
FPlayer fLeader = faction.getFPlayerAdmin();
|
||||
String leader = fLeader == null ? "Server" : fLeader.getName().substring(0, fLeader.getName().length() > 14 ? 13 : fLeader.getName().length());
|
||||
return ChatColor.translateAlternateColorCodes('&', s.replace("{power}", String.valueOf(faction.getPowerRounded())).replace("{online}", String.valueOf(faction.getOnlinePlayers().size())).replace("{members}", String.valueOf(faction.getFPlayers().size())).replace("{leader}", leader).replace("{chunks}", String.valueOf(faction.getLandRounded())).replace("{raidable}", String.valueOf(raidable)).replace("{warps}", String.valueOf(faction.getWarps().size())));
|
||||
}
|
||||
}
|
||||
}
|
@ -31,6 +31,7 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator {
|
||||
protected boolean peaceful;
|
||||
protected Integer permanentPower;
|
||||
protected LazyLocation home;
|
||||
protected long foundedDate;
|
||||
protected transient long lastPlayerLoggedOffTime;
|
||||
protected double money;
|
||||
protected double powerBoost;
|
||||
@ -208,6 +209,17 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator {
|
||||
return (this.home != null) ? this.home.getLocation() : null;
|
||||
}
|
||||
|
||||
public long getFoundedDate() {
|
||||
if(this.foundedDate == 0) {
|
||||
setFoundedDate(System.currentTimeMillis());
|
||||
}
|
||||
return this.foundedDate;
|
||||
}
|
||||
|
||||
public void setFoundedDate(long newDate) {
|
||||
this.foundedDate = newDate;
|
||||
}
|
||||
|
||||
public void confirmValidHome() {
|
||||
if (!Conf.homesMustBeInClaimedTerritory || this.home == null || (this.home.getLocation() != null && Board.getInstance().getFactionAt(new FLocation(this.home.getLocation())) == this)) {
|
||||
return;
|
||||
@ -282,6 +294,7 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator {
|
||||
this.permanent = false;
|
||||
this.money = 0.0;
|
||||
this.powerBoost = 0.0;
|
||||
this.foundedDate = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public MemoryFaction(MemoryFaction old) {
|
||||
@ -291,6 +304,7 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator {
|
||||
tag = old.tag;
|
||||
description = old.description;
|
||||
open = old.open;
|
||||
foundedDate = old.foundedDate;
|
||||
peaceful = old.peaceful;
|
||||
permanentPower = old.permanentPower;
|
||||
home = old.home;
|
||||
|
@ -19,6 +19,8 @@ package com.massivecraft.factions.zcore.util;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
/**
|
||||
* An enum for requesting strings from the language file. The contents of this enum file may be subject to frequent
|
||||
* changes.
|
||||
@ -436,6 +438,7 @@ public enum TL {
|
||||
COMMAND_SHOW_JOINING("<a>Joining: <i>%1$s "),
|
||||
COMMAND_SHOW_INVITATION("invitation is required"),
|
||||
COMMAND_SHOW_UNINVITED("no invitation is needed"),
|
||||
COMMAND_SHOW_NOHOME("n/a"),
|
||||
COMMAND_SHOW_POWER("<a>Land / Power / Maxpower: <i> %1$d/%2$d/%3$d %4$s."),
|
||||
COMMAND_SHOW_BONUS(" (bonus: "),
|
||||
COMMAND_SHOW_PENALTY(" (penalty: "),
|
||||
@ -564,6 +567,7 @@ public enum TL {
|
||||
GENERIC_SERVERADMIN("A server admin"),
|
||||
GENERIC_DISABLED("disabled"),
|
||||
GENERIC_ENABLED("enabled"),
|
||||
GENERIC_INFINITY("∞"),
|
||||
GENERIC_CONSOLEONLY("This command cannot be run as a player."),
|
||||
GENERIC_PLAYERONLY("<b>This command can only be used by ingame players."),
|
||||
GENERIC_ASKYOURLEADER("<i> Ask your leader to:"),
|
||||
@ -593,6 +597,12 @@ public enum TL {
|
||||
CHAT_TRUCE("truce chat"),
|
||||
CHAT_PUBLIC("public chat"),
|
||||
|
||||
/**
|
||||
* Economy stuff
|
||||
*/
|
||||
|
||||
ECON_OFF("no %s"), // no balance, no value, no refund, etc
|
||||
|
||||
/**
|
||||
* Relations
|
||||
*/
|
||||
@ -691,6 +701,7 @@ public enum TL {
|
||||
private String path;
|
||||
private String def;
|
||||
private static YamlConfiguration LANG;
|
||||
public static SimpleDateFormat sdf;
|
||||
|
||||
/**
|
||||
* Lang enum constructor.
|
||||
@ -723,6 +734,7 @@ public enum TL {
|
||||
*/
|
||||
public static void setFile(YamlConfiguration config) {
|
||||
LANG = config;
|
||||
sdf = new SimpleDateFormat(DATE_FORMAT.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,260 @@
|
||||
package com.massivecraft.factions.zcore.util;
|
||||
|
||||
import com.massivecraft.factions.*;
|
||||
import com.massivecraft.factions.integration.Econ;
|
||||
import com.massivecraft.factions.struct.Relation;
|
||||
import org.apache.commons.lang.time.DurationFormatUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Link between config and in-game messages<br>
|
||||
* Changes based on faction / player<br>
|
||||
* Interfaces the config lists with {} variables to plugin
|
||||
*/
|
||||
public enum TagReplacer {
|
||||
|
||||
/**
|
||||
* Fancy variables, used by f show
|
||||
*/
|
||||
ALLIES_LIST(TagType.FANCY, "{allies-list}"),
|
||||
ONLINE_LIST(TagType.FANCY, "{online-list}"),
|
||||
ENEMIES_LIST(TagType.FANCY, "{enemies-list}"),
|
||||
OFFLINE_LIST(TagType.FANCY, "{offline-list}"),
|
||||
|
||||
/**
|
||||
* Player variables, require a player
|
||||
*/
|
||||
PLAYER_GROUP(TagType.PLAYER, "{group}"),
|
||||
LAST_SEEN(TagType.PLAYER, "{last-seen}"),
|
||||
PLAYER_BALANCE(TagType.PLAYER, "{player-balance}"),
|
||||
|
||||
/**
|
||||
* Faction variables, require at least a player
|
||||
*/
|
||||
HOME_X(TagType.FACTION, "{x}"),
|
||||
HOME_Y(TagType.FACTION, "{y}"),
|
||||
HOME_Z(TagType.FACTION, "{z}"),
|
||||
CHUNKS(TagType.FACTION, "{chunks}"),
|
||||
WARPS(TagType.FACTION, "{warps}"),
|
||||
HEADER(TagType.FACTION, "{header}"),
|
||||
POWER(TagType.FACTION, "{power}"),
|
||||
MAX_POWER(TagType.FACTION, "{maxPower}"),
|
||||
POWER_BOOST(TagType.FACTION, "{power-boost}"),
|
||||
LEADER(TagType.FACTION, "{leader}"),
|
||||
JOINING(TagType.FACTION, "{joining}"),
|
||||
FACTION(TagType.FACTION, "{faction}"),
|
||||
PLAYER_NAME(TagType.FACTION, "{name}"),
|
||||
HOME_WORLD(TagType.FACTION, "{world}"),
|
||||
RAIDABLE(TagType.FACTION, "{raidable}"),
|
||||
PEACEFUL(TagType.FACTION, "{peaceful}"),
|
||||
PERMANENT(TagType.FACTION, "permanent"), // no braces needed
|
||||
TIME_LEFT(TagType.FACTION, "{time-left}"),
|
||||
LAND_VALUE(TagType.FACTION, "{land-value}"),
|
||||
DESCRIPTION(TagType.FACTION, "{description}"),
|
||||
CREATE_DATE(TagType.FACTION, "{create-date}"),
|
||||
LAND_REFUND(TagType.FACTION, "{land-refund}"),
|
||||
BANK_BALANCE(TagType.FACTION, "{balance}"),
|
||||
ALLIES_COUNT(TagType.FACTION, "{allies}"),
|
||||
ENEMIES_COUNT(TagType.FACTION, "{enemies}"),
|
||||
ONLINE_COUNT(TagType.FACTION, "{online}"),
|
||||
OFFLINE_COUNT(TagType.FACTION, "{offline}"),
|
||||
FACTION_SIZE(TagType.FACTION, "{members}"),
|
||||
|
||||
/**
|
||||
* General variables, require no faction or player
|
||||
*/
|
||||
MAX_WARPS(TagType.GENERAL, "{max-warps}"),
|
||||
MAX_ALLIES(TagType.GENERAL, "{max-allies}"),
|
||||
MAX_ENEMIES(TagType.GENERAL, "{max-enemies}"),
|
||||
FACTIONLESS(TagType.GENERAL, "{factionless}"),
|
||||
TOTAL_ONLINE(TagType.GENERAL, "{total-online}");
|
||||
|
||||
private TagType type;
|
||||
private String tag;
|
||||
|
||||
protected enum TagType {
|
||||
FANCY(0), PLAYER(1), FACTION(2), GENERAL(3);
|
||||
public int id;
|
||||
|
||||
TagType(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
TagReplacer(TagType type, String tag) {
|
||||
this.type = type;
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Protected access to this generic server related variable
|
||||
*
|
||||
* @return value for this generic server related variable<br>
|
||||
*/
|
||||
protected String getValue() {
|
||||
switch (this) {
|
||||
case TOTAL_ONLINE:
|
||||
return String.valueOf(Bukkit.getOnlinePlayers().size());
|
||||
case FACTIONLESS:
|
||||
return String.valueOf(Factions.getInstance().getNone().getFPlayersWhereOnline(true).size());
|
||||
case MAX_ALLIES:
|
||||
if (P.p.getConfig().getBoolean("max-relations.enabled", true)) {
|
||||
return String.valueOf(P.p.getConfig().getInt("max-relations.ally", 10));
|
||||
}
|
||||
return TL.GENERIC_INFINITY.toString();
|
||||
case MAX_ENEMIES:
|
||||
if (P.p.getConfig().getBoolean("max-relations.enabled", true)) {
|
||||
return String.valueOf(P.p.getConfig().getInt("max-relations.enemy", 10));
|
||||
}
|
||||
return TL.GENERIC_INFINITY.toString();
|
||||
case MAX_WARPS:
|
||||
return String.valueOf(P.p.getConfig().getInt("max-warps", 5));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value for this (as in the instance this is called from) variable!
|
||||
*
|
||||
* @param fac Target faction
|
||||
* @param fp Target player (can be null)
|
||||
* @return the value for this enum!
|
||||
*/
|
||||
protected String getValue(Faction fac, FPlayer fp) {
|
||||
if (this.type == TagType.GENERAL) {
|
||||
return getValue();
|
||||
}
|
||||
if (fp != null) {
|
||||
switch (this) {
|
||||
case HEADER:
|
||||
return P.p.txt.titleize(fac.getTag(fp));
|
||||
case PLAYER_NAME:
|
||||
return fp.getName();
|
||||
case FACTION:
|
||||
return !fac.isNone() ? fac.getTag(fp) : TL.GENERIC_FACTIONLESS.toString();
|
||||
case LAST_SEEN:
|
||||
long lastSeen = System.currentTimeMillis() - fp.getLastLoginTime();
|
||||
String humanized = DurationFormatUtils.formatDurationWords(lastSeen, true, true) + TL.COMMAND_STATUS_AGOSUFFIX;
|
||||
String last = fp.isOnline() ? ChatColor.GREEN + TL.COMMAND_STATUS_ONLINE.toString() :
|
||||
(lastSeen < 432000000 ? ChatColor.YELLOW + humanized : ChatColor.RED + humanized);
|
||||
return String.format(TL.COMMAND_STATUS_FORMAT.toString(),
|
||||
ChatColor.GOLD + fp.getRole().getPrefix() + fp.getName() + ChatColor.RESET, last).trim();
|
||||
case PLAYER_GROUP:
|
||||
return P.p.getPrimaryGroup(Bukkit.getOfflinePlayer(UUID.fromString(fp.getId())));
|
||||
case PLAYER_BALANCE:
|
||||
return Econ.isSetup() ? Econ.getFriendlyBalance(fp) : TL.ECON_OFF.format("balance");
|
||||
}
|
||||
}
|
||||
switch (this) {
|
||||
case DESCRIPTION:
|
||||
return fac.getDescription();
|
||||
case FACTION:
|
||||
return fac.getTag();
|
||||
case JOINING:
|
||||
return (fac.getOpen() ? TL.COMMAND_SHOW_UNINVITED.toString() : TL.COMMAND_SHOW_INVITATION.toString());
|
||||
case PEACEFUL:
|
||||
return fac.isPeaceful() ? Conf.colorNeutral + TL.COMMAND_SHOW_PEACEFUL.toString() : "";
|
||||
case PERMANENT:
|
||||
return fac.isPermanent() ? "permanent" : "{notPermanent}";
|
||||
case CHUNKS:
|
||||
return String.valueOf(fac.getLandRounded());
|
||||
case POWER:
|
||||
return String.valueOf(fac.getPowerRounded());
|
||||
case MAX_POWER:
|
||||
return String.valueOf(fac.getPowerMaxRounded());
|
||||
case POWER_BOOST:
|
||||
double powerBoost = fac.getPowerBoost();
|
||||
return (powerBoost == 0.0) ? "" : (powerBoost > 0.0 ? TL.COMMAND_SHOW_BONUS.toString() : TL.COMMAND_SHOW_PENALTY.toString() + powerBoost + ")");
|
||||
case LEADER:
|
||||
FPlayer fAdmin = fac.getFPlayerAdmin();
|
||||
return fAdmin == null ? "Server" : fAdmin.getName().substring(0, fAdmin.getName().length() > 14 ? 13 : fAdmin.getName().length());
|
||||
case WARPS:
|
||||
return String.valueOf(fac.getWarps().size());
|
||||
case CREATE_DATE:
|
||||
return TL.sdf.format(fac.getFoundedDate());
|
||||
case RAIDABLE:
|
||||
boolean raid = P.p.getConfig().getBoolean("hcf.raidable", false) && fac.getLandRounded() >= fac.getPowerRounded();
|
||||
return raid ? TL.RAIDABLE_TRUE.toString() : TL.RAIDABLE_FALSE.toString();
|
||||
case HOME_WORLD:
|
||||
return fac.hasHome() ? fac.getHome().getWorld().getName() : "{ig}";
|
||||
case HOME_X:
|
||||
return fac.hasHome() ? String.valueOf(fac.getHome().getBlockX()) : "{ig}";
|
||||
case HOME_Y:
|
||||
return fac.hasHome() ? String.valueOf(fac.getHome().getBlockY()) : "{ig}";
|
||||
case HOME_Z:
|
||||
return fac.hasHome() ? String.valueOf(fac.getHome().getBlockZ()) : "{ig}";
|
||||
case LAND_VALUE:
|
||||
return Econ.shouldBeUsed() ? Econ.moneyString(Econ.calculateTotalLandValue(fac.getLandRounded())) : TL.ECON_OFF.format("value");
|
||||
case LAND_REFUND:
|
||||
return Econ.shouldBeUsed() ? Econ.moneyString(Econ.calculateTotalLandRefund(fac.getLandRounded())) : TL.ECON_OFF.format("refund");
|
||||
case BANK_BALANCE:
|
||||
if (Econ.shouldBeUsed()) {
|
||||
return Conf.bankEnabled ? Econ.moneyString(Econ.getBalance(fac.getAccountId())) : TL.ECON_OFF.format("balance");
|
||||
}
|
||||
return TL.ECON_OFF.format("balance");
|
||||
case ALLIES_COUNT:
|
||||
return String.valueOf(fac.getRelationCount(Relation.ALLY));
|
||||
case ENEMIES_COUNT:
|
||||
return String.valueOf(fac.getRelationCount(Relation.ENEMY));
|
||||
case ONLINE_COUNT:
|
||||
return String.valueOf(fac.getOnlinePlayers().size());
|
||||
case OFFLINE_COUNT:
|
||||
return String.valueOf(fac.getFPlayers().size() - fac.getOnlinePlayers().size());
|
||||
case FACTION_SIZE:
|
||||
return String.valueOf(fac.getFPlayers().size());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all the variables we can use for this type<br>
|
||||
*
|
||||
* @param type the type we want
|
||||
* @return a list of all the variables with this type
|
||||
*/
|
||||
protected static List<TagReplacer> getByType(TagType type) {
|
||||
List<TagReplacer> tagReplacers = new ArrayList<TagReplacer>();
|
||||
for (TagReplacer tagReplacer : TagReplacer.values()) {
|
||||
if (type == TagType.FANCY) {
|
||||
if (tagReplacer.type == TagType.FANCY) {
|
||||
tagReplacers.add(tagReplacer);
|
||||
}
|
||||
} else if (tagReplacer.type.id >= type.id) {
|
||||
tagReplacers.add(tagReplacer);
|
||||
}
|
||||
}
|
||||
return tagReplacers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param original raw line with variables
|
||||
* @param value what to replace var in raw line with
|
||||
* @return the string with the new value
|
||||
*/
|
||||
public String replace(String original, String value) {
|
||||
return original.replace(tag, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param toSearch raw line with variables
|
||||
* @return if the raw line contains this enums variable
|
||||
*/
|
||||
public boolean contains(String toSearch) {
|
||||
return toSearch.contains(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tag associated with this enum that we should replace
|
||||
*
|
||||
* @return the {....} variable that is located in config
|
||||
*/
|
||||
public String getTag() {
|
||||
return this.tag;
|
||||
}
|
||||
}
|
226
src/main/java/com/massivecraft/factions/zcore/util/TagUtil.java
Normal file
226
src/main/java/com/massivecraft/factions/zcore/util/TagUtil.java
Normal file
@ -0,0 +1,226 @@
|
||||
package com.massivecraft.factions.zcore.util;
|
||||
|
||||
|
||||
import com.massivecraft.factions.FPlayer;
|
||||
import com.massivecraft.factions.Faction;
|
||||
import com.massivecraft.factions.Factions;
|
||||
import com.massivecraft.factions.P;
|
||||
import com.massivecraft.factions.struct.Relation;
|
||||
import com.massivecraft.factions.util.MiscUtil;
|
||||
import mkremins.fanciful.FancyMessage;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.massivecraft.factions.zcore.util.TagReplacer.TagType;
|
||||
|
||||
public class TagUtil {
|
||||
|
||||
private static final int ARBITRARY_LIMIT = 25000;
|
||||
|
||||
/**
|
||||
* Replaces all variables in a plain raw line for a faction
|
||||
*
|
||||
* @param faction for faction
|
||||
* @param line raw line from config with variables to replace for
|
||||
* @return clean line
|
||||
*/
|
||||
public static String parsePlain(Faction faction, String line) {
|
||||
for (TagReplacer tagReplacer : TagReplacer.getByType(TagType.FACTION)) {
|
||||
if (tagReplacer.contains(line)) {
|
||||
line = tagReplacer.replace(line, tagReplacer.getValue(faction, null));
|
||||
}
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces all variables in a plain raw line for a player
|
||||
*
|
||||
* @param fplayer for player
|
||||
* @param line raw line from config with variables to replace for
|
||||
* @return clean line
|
||||
*/
|
||||
public static String parsePlain(FPlayer fplayer, String line) {
|
||||
for (TagReplacer tagReplacer : TagReplacer.getByType(TagType.PLAYER)) {
|
||||
if (tagReplacer.contains(line)) {
|
||||
String rep = tagReplacer.getValue(fplayer.getFaction(), fplayer);
|
||||
if(rep == null) {
|
||||
rep = ""; // this should work, but it's not a good way to handle whatever is going wrong
|
||||
}
|
||||
line = tagReplacer.replace(line, rep);
|
||||
}
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces all variables in a plain raw line for a faction, using relations from fplayer
|
||||
*
|
||||
* @param faction for faction
|
||||
* @param fplayer from player
|
||||
* @param line raw line from config with variables to replace for
|
||||
* @return clean line
|
||||
*/
|
||||
public static String parsePlain(Faction faction, FPlayer fplayer, String line) {
|
||||
for (TagReplacer tagReplacer : TagReplacer.getByType(TagType.PLAYER)) {
|
||||
if (tagReplacer.contains(line)) {
|
||||
line = tagReplacer.replace(line, tagReplacer.getValue(faction, fplayer));
|
||||
}
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan a line and parse the fancy variable into a fancy list
|
||||
*
|
||||
* @param faction for faction (viewers faction)
|
||||
* @param fme for player (viewer)
|
||||
* @param line fancy message prefix
|
||||
* @return
|
||||
*/
|
||||
public static List<FancyMessage> parseFancy(Faction faction, FPlayer fme, String line) {
|
||||
for (TagReplacer tagReplacer : TagReplacer.getByType(TagType.FANCY)) {
|
||||
if (tagReplacer.contains(line)) {
|
||||
String clean = line.replace(tagReplacer.getTag(), ""); // remove tag
|
||||
return getFancy(faction, fme, tagReplacer, clean);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a line has fancy variables
|
||||
*
|
||||
* @param line raw line from config with variables
|
||||
* @return if the line has fancy variables
|
||||
*/
|
||||
public static boolean hasFancy(String line) {
|
||||
for (TagReplacer tagReplacer : TagReplacer.getByType(TagType.FANCY)) {
|
||||
if (tagReplacer.contains(line)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lets get fancy.
|
||||
*
|
||||
* @param target Faction to get relate from
|
||||
* @param fme Player to relate to
|
||||
* @param prefix First part of the fancy message
|
||||
* @return list of fancy messages to send
|
||||
*/
|
||||
protected static List<FancyMessage> getFancy(Faction target, FPlayer fme, TagReplacer type, String prefix) {
|
||||
List<FancyMessage> fancyMessages = new ArrayList<FancyMessage>();
|
||||
switch (type) {
|
||||
case ALLIES_LIST:
|
||||
FancyMessage currentAllies = P.p.txt.parseFancy(prefix);
|
||||
boolean firstAlly = true;
|
||||
for (Faction otherFaction : Factions.getInstance().getAllFactions()) {
|
||||
if (otherFaction == target) {
|
||||
continue;
|
||||
}
|
||||
String s = otherFaction.getTag(fme);
|
||||
if (otherFaction.getRelationTo(target).isAlly()) {
|
||||
currentAllies.then(firstAlly ? s : ", " + s);
|
||||
currentAllies.tooltip(tipFaction(otherFaction)).color(fme.getColorTo(otherFaction));
|
||||
firstAlly = false;
|
||||
if (currentAllies.toJSONString().length() > ARBITRARY_LIMIT) {
|
||||
fancyMessages.add(currentAllies);
|
||||
currentAllies = new FancyMessage("");
|
||||
}
|
||||
}
|
||||
}
|
||||
fancyMessages.add(currentAllies);
|
||||
return fancyMessages; // we must return here and not outside the switch
|
||||
case ENEMIES_LIST:
|
||||
FancyMessage currentEnemies = P.p.txt.parseFancy(prefix);
|
||||
boolean firstEnemy = true;
|
||||
for (Faction otherFaction : Factions.getInstance().getAllFactions()) {
|
||||
if (otherFaction == target) {
|
||||
continue;
|
||||
}
|
||||
String s = otherFaction.getTag(fme);
|
||||
if (otherFaction.getRelationTo(target).isEnemy()) {
|
||||
currentEnemies.then(firstEnemy ? s : ", " + s);
|
||||
currentEnemies.tooltip(tipFaction(otherFaction)).color(fme.getColorTo(otherFaction));
|
||||
firstEnemy = false;
|
||||
if (currentEnemies.toJSONString().length() > ARBITRARY_LIMIT) {
|
||||
fancyMessages.add(currentEnemies);
|
||||
currentEnemies = new FancyMessage("");
|
||||
}
|
||||
}
|
||||
}
|
||||
fancyMessages.add(currentEnemies);
|
||||
return fancyMessages; // we must return here and not outside the switch
|
||||
case ONLINE_LIST:
|
||||
FancyMessage currentOnline = P.p.txt.parseFancy(prefix);
|
||||
boolean firstOnline = true;
|
||||
for (FPlayer p : MiscUtil.rankOrder(target.getFPlayersWhereOnline(true))) {
|
||||
String name = p.getNameAndTitle();
|
||||
currentOnline.then(firstOnline ? name : ", " + name);
|
||||
currentOnline.tooltip(tipPlayer(p)).color(fme.getColorTo(p));
|
||||
firstOnline = false;
|
||||
if (currentOnline.toJSONString().length() > ARBITRARY_LIMIT) {
|
||||
fancyMessages.add(currentOnline);
|
||||
currentOnline = new FancyMessage("");
|
||||
}
|
||||
}
|
||||
fancyMessages.add(currentOnline);
|
||||
return fancyMessages; // we must return here and not outside the switch
|
||||
case OFFLINE_LIST:
|
||||
FancyMessage currentOffline = P.p.txt.parseFancy(prefix);
|
||||
boolean firstOffline = true;
|
||||
for (FPlayer p : MiscUtil.rankOrder(target.getFPlayers())) {
|
||||
String name = p.getNameAndTitle();
|
||||
if (!p.isOnline()) {
|
||||
currentOffline.then(firstOffline ? name : ", " + name);
|
||||
currentOffline.tooltip(tipPlayer(p)).color(fme.getColorTo(p));
|
||||
firstOffline = false;
|
||||
if (currentOffline.toJSONString().length() > ARBITRARY_LIMIT) {
|
||||
fancyMessages.add(currentOffline);
|
||||
currentOffline = new FancyMessage("");
|
||||
}
|
||||
}
|
||||
}
|
||||
fancyMessages.add(currentOffline);
|
||||
return fancyMessages; // we must return here and not outside the switch
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses tooltip variables from config
|
||||
* <br>
|
||||
* Supports variables for factions only (type 2)
|
||||
*
|
||||
* @param faction faction to tooltip for
|
||||
* @return list of tooltips for a fancy message
|
||||
*/
|
||||
private static List<String> tipFaction(Faction faction) {
|
||||
List<String> lines = new ArrayList<String>();
|
||||
for (String line : P.p.getConfig().getStringList("tooltips.list")) {
|
||||
lines.add(ChatColor.translateAlternateColorCodes('&', TagUtil.parsePlain(faction, line)));
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses tooltip variables from config
|
||||
* <br>
|
||||
* Supports variables for players and factions (types 1 and 2)
|
||||
*
|
||||
* @param fplayer player to tooltip for
|
||||
* @return list of tooltips for a fancy message
|
||||
*/
|
||||
private static List<String> tipPlayer(FPlayer fplayer) {
|
||||
List<String> lines = new ArrayList<String>();
|
||||
for (String line : P.p.getConfig().getStringList("tooltips.show")) {
|
||||
lines.add(ChatColor.translateAlternateColorCodes('&', TagUtil.parsePlain(fplayer, line)));
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.massivecraft.factions.zcore.util;
|
||||
|
||||
import mkremins.fanciful.FancyMessage;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
|
||||
@ -53,6 +54,44 @@ public class TextUtil {
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// Fancy parsing
|
||||
// -------------------------------------------- //
|
||||
|
||||
public FancyMessage parseFancy(String prefix) {
|
||||
return toFancy(parse(prefix));
|
||||
}
|
||||
|
||||
public static FancyMessage toFancy(String first) {
|
||||
String text = "";
|
||||
FancyMessage message = new FancyMessage(text);
|
||||
ChatColor color = null;
|
||||
char[] chars = first.toCharArray();
|
||||
|
||||
for(int i = 0; i < chars.length; i++){
|
||||
if (chars[i] == '§') {
|
||||
if(color != null) {
|
||||
message.then(text).color(color);
|
||||
text = "";
|
||||
color = ChatColor.getByChar(chars[i+1]);
|
||||
} else {
|
||||
color = ChatColor.getByChar(chars[i+1]);
|
||||
}
|
||||
i++; // skip color char
|
||||
} else {
|
||||
text += chars[i];
|
||||
}
|
||||
}
|
||||
if(text.length() > 0) {
|
||||
if(color != null) {
|
||||
message.then(text).color(color);
|
||||
} else {
|
||||
message.text(text);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// Color parsing
|
||||
// -------------------------------------------- //
|
||||
|
@ -207,4 +207,27 @@ hcf:
|
||||
# heavy operation if set to a large number.
|
||||
# If this is set to 0, we won't even bother checking which is how Factions has
|
||||
# always been.
|
||||
buffer-zone: 0
|
||||
buffer-zone: 0
|
||||
|
||||
############################################################
|
||||
# +------------------------------------------------------+ #
|
||||
# | Configurable /f show | #
|
||||
# +------------------------------------------------------+ #
|
||||
############################################################
|
||||
|
||||
# You can use any variable here, including fancy messages. Color codes and or tags work fine.
|
||||
# Lines that arent defined wont be sent (home not set, faction not peaceful / permanent, dtr freeze)
|
||||
show:
|
||||
# First line can be {header} for default header, or any string (we recommend &m for smooth lines ;p)
|
||||
- '{header}'
|
||||
- '<a>Description: <i>{description}'
|
||||
- '<a>Joining: <i>{joining} {peaceful}'
|
||||
- '<a>Land / Power / Maxpower: <i> {chunks}/{power}/{maxPower}'
|
||||
- '<a>Faction Home: <i>{world}, {x}, {y}, {z}' # if no home is set, {z} = COMMAND_SHOW_NOHOME, from lang.yml
|
||||
- '<a>Founded: <i>{create-date}'
|
||||
- '<a>This faction is permanent, remaining even with no members.' # only shows if faction is permanent
|
||||
- '<a>Land value: <i>{land-value} {land-refund}'
|
||||
- '<a>Balance: <i>{balance}'
|
||||
- '<a>Allies(<i>{allies}<a>/<i>{max-allies}<a>): {allies-list} '
|
||||
- '<a>Online: (<i>{online}<a>/<i>{members}<a>): {online-list}'
|
||||
- '<a>Offline: (<i>{offline}<a>/<i>{members}<a>): {offline-list}'
|
Loading…
Reference in New Issue
Block a user