diff --git a/src/main/java/com/massivecraft/factions/integration/Econ.java b/src/main/java/com/massivecraft/factions/integration/Econ.java index e1986d1a..bcefd888 100644 --- a/src/main/java/com/massivecraft/factions/integration/Econ.java +++ b/src/main/java/com/massivecraft/factions/integration/Econ.java @@ -11,6 +11,7 @@ import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.plugin.RegisteredServiceProvider; +import java.text.DecimalFormat; import java.util.HashSet; import java.util.Set; import java.util.UUID; @@ -384,6 +385,12 @@ public class Econ { return econ.getBalance(Bukkit.getOfflinePlayer(account)); } + private static final DecimalFormat format = new DecimalFormat("#,###"); + + public static String getFriendlyBalance(UUID uuid) { + return format.format(econ.getBalance(Bukkit.getOfflinePlayer(uuid))); + } + public static boolean setBalance(String account, double amount) { double current = econ.getBalance(Bukkit.getOfflinePlayer(account)); if (current > amount) { diff --git a/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java b/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java index 0102b49f..ce27bb53 100644 --- a/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java +++ b/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java @@ -1,10 +1,12 @@ package com.massivecraft.factions.listeners; import com.massivecraft.factions.*; +import com.massivecraft.factions.scoreboards.FDefaultBoard; import com.massivecraft.factions.struct.Permission; import com.massivecraft.factions.struct.Relation; import com.massivecraft.factions.struct.Role; import com.massivecraft.factions.zcore.util.TextUtil; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; @@ -16,7 +18,10 @@ import org.bukkit.event.block.Action; import org.bukkit.event.player.*; import org.bukkit.util.NumberConversions; -import java.util.*; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.UUID; import java.util.logging.Level; @@ -38,6 +43,17 @@ public class FactionsPlayerListener implements Listener { // Store player's current FLocation and notify them where they are me.setLastStoodAt(new FLocation(event.getPlayer().getLocation())); + + if (P.p.getConfig().getBoolean("scoreboard.default-enabled", false)) { + Bukkit.getScheduler().runTaskLater(P.p, new Runnable() { // I think we still have to delay this a few seconds. + @Override + public void run() { + if (me.getPlayer().isOnline()) { // In case people are quickly joining and quitting. + new FDefaultBoard(me); + } + } + }, 20L); + } } @EventHandler(priority = EventPriority.NORMAL) @@ -90,8 +106,8 @@ public class FactionsPlayerListener implements Listener { boolean changedFaction = (factionFrom != factionTo); if (me.isMapAutoUpdating()) { - if(showTimes.containsKey(player.getUniqueId()) && (showTimes.get(player.getUniqueId()) > System.currentTimeMillis())) { - if(P.p.getConfig().getBoolean("findfactionsexploit.log", false)) { + if (showTimes.containsKey(player.getUniqueId()) && (showTimes.get(player.getUniqueId()) > System.currentTimeMillis())) { + if (P.p.getConfig().getBoolean("findfactionsexploit.log", false)) { P.p.log(Level.WARNING, "%s tried to show a faction map too soon and triggered exploit blocker.", player.getName()); } } else { diff --git a/src/main/java/com/massivecraft/factions/scoreboards/FDefaultBoard.java b/src/main/java/com/massivecraft/factions/scoreboards/FDefaultBoard.java new file mode 100644 index 00000000..1bb97150 --- /dev/null +++ b/src/main/java/com/massivecraft/factions/scoreboards/FDefaultBoard.java @@ -0,0 +1,95 @@ +package com.massivecraft.factions.scoreboards; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.P; +import com.massivecraft.factions.integration.Econ; +import com.massivecraft.factions.scoreboards.tasks.UpdateTask; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Score; +import org.bukkit.scoreboard.Scoreboard; + +import java.util.List; +import java.util.logging.Level; + +public class FDefaultBoard implements FScoreboard { + + private FPlayer fPlayer; + private Scoreboard scoreboard; + private Objective objective; + private int taskId; + + public FDefaultBoard(FPlayer player) { + this.fPlayer = player; + this.scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); + + setup(); + apply(fPlayer.getPlayer()); + } + + public void setup() { + objective = scoreboard.registerNewObjective("default", "dummy"); + objective.setDisplaySlot(DisplaySlot.SIDEBAR); + this.taskId = Bukkit.getScheduler().runTaskTimer(P.p, new UpdateTask(this), 40L, P.p.getConfig().getLong("default-update-interval", 20L)).getTaskId(); + update(objective); + } + + public void apply(Player player) { + player.setScoreboard(scoreboard); + } + + public void remove(Player player) { + player.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard()); + } + + public void update(Objective buffer) { + if(fPlayer.getPlayer() == null || !fPlayer.getPlayer().isOnline()) { + Bukkit.getScheduler().cancelTask(taskId); + return; + } + buffer.setDisplayName(ChatColor.translateAlternateColorCodes('&', P.p.getConfig().getString("scoreboard.default-title", "i love drt"))); + + List list = P.p.getConfig().getStringList("scoreboard.default"); + int place = 16; // list.size(); + + if (list == null) { + P.p.debug(Level.WARNING, "scoreboard.default is null :("); + return; + } + + for (String s : list) { + String replaced = replace(s); + String awesome = replaced.length() > 16 ? replaced.substring(0, 15) : replaced; + Score score = buffer.getScore(awesome); + score.setScore(place); + + place--; + if (place < 0) { + break; // Let's not let the scoreboard get too big. + } + } + buffer.setDisplaySlot(DisplaySlot.SIDEBAR); + if(!buffer.getName().equalsIgnoreCase("default")) { + objective.unregister(); // unregister so we don't have to worry about duplicate names. + this.objective = buffer; + } + } + + private String replace(String s) { + String faction = !fPlayer.getFaction().isNone() ? fPlayer.getFaction().getTag() : "factionless"; + 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())); + return ChatColor.translateAlternateColorCodes('&', s); + } + + public Scoreboard getScoreboard() { + return this.scoreboard; + } +} diff --git a/src/main/java/com/massivecraft/factions/scoreboards/FInfoBoard.java b/src/main/java/com/massivecraft/factions/scoreboards/FInfoBoard.java index 39a16a43..5a4e4a9e 100644 --- a/src/main/java/com/massivecraft/factions/scoreboards/FInfoBoard.java +++ b/src/main/java/com/massivecraft/factions/scoreboards/FInfoBoard.java @@ -9,21 +9,25 @@ import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; import org.bukkit.scoreboard.Score; import org.bukkit.scoreboard.Scoreboard; import java.util.List; import java.util.logging.Level; -public class FInfoBoard extends FScoreboard { +public class FInfoBoard implements FScoreboard { private Faction faction; + private Objective objective; + private Scoreboard scoreboard; + private FPlayer fPlayer; public FInfoBoard(Player player, Faction faction, boolean timed) { + this.fPlayer = FPlayers.i.get(player); this.faction = faction; Scoreboard former = player.getScoreboard(); - scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); - setup(player); + setup(); apply(player); if (timed) { @@ -31,10 +35,36 @@ public class FInfoBoard extends FScoreboard { } } - private void setup(Player player) { - FPlayer fPlayer = FPlayers.i.get(player); + public void setup() { + scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); objective = scoreboard.registerNewObjective("FBoard", "dummy"); objective.setDisplaySlot(DisplaySlot.SIDEBAR); + update(objective); + } + + /** + * Filters lots of things in accordance with le config. + * + * @param s String to replace. + * + * @return new String with values instead of placeholders. + */ + private String replace(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))); + } + + public void apply(Player player) { + player.setScoreboard(scoreboard); + } + + public void remove(Player player) { + player.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard()); + } + + public void update(Objective objective) { objective.setDisplayName(faction.getRelationTo(fPlayer).getColor() + faction.getTag()); List list = P.p.getConfig().getStringList("scoreboard.finfo"); @@ -58,18 +88,7 @@ public class FInfoBoard extends FScoreboard { } } - /** - * Filters lots of things in accordance with le config. - * - * @param s String to replace. - * - * @return new String with values instead of placeholders. - */ - private String replace(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))); + public Scoreboard getScoreboard() { + return this.scoreboard; } - } diff --git a/src/main/java/com/massivecraft/factions/scoreboards/FScoreboard.java b/src/main/java/com/massivecraft/factions/scoreboards/FScoreboard.java index 9c8e1dfb..84b1126d 100644 --- a/src/main/java/com/massivecraft/factions/scoreboards/FScoreboard.java +++ b/src/main/java/com/massivecraft/factions/scoreboards/FScoreboard.java @@ -1,23 +1,18 @@ package com.massivecraft.factions.scoreboards; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.scoreboard.Objective; import org.bukkit.scoreboard.Scoreboard; -/** - * Lazy attempt at abstraction off of 40 minutes of sleep. - */ -public abstract class FScoreboard { +public interface FScoreboard { - public Objective objective; - public Scoreboard scoreboard; + public void apply(Player player); - public void apply(Player player) { - player.setScoreboard(scoreboard); - } + public void remove(Player player); - public void remove(Player player) { - player.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard()); - } + public void update(Objective objective); + + public void setup(); + + public Scoreboard getScoreboard(); } diff --git a/src/main/java/com/massivecraft/factions/scoreboards/tasks/UpdateTask.java b/src/main/java/com/massivecraft/factions/scoreboards/tasks/UpdateTask.java new file mode 100644 index 00000000..8140265e --- /dev/null +++ b/src/main/java/com/massivecraft/factions/scoreboards/tasks/UpdateTask.java @@ -0,0 +1,26 @@ +package com.massivecraft.factions.scoreboards.tasks; + +import com.massivecraft.factions.scoreboards.FScoreboard; + +import java.util.Random; + +public class UpdateTask implements Runnable { + + private FScoreboard board; + private final Random random; + + public UpdateTask(FScoreboard board) { + this.board = board; + this.random = new Random(); + } + + @Override + public void run() { + board.update(board.getScoreboard().registerNewObjective(getRandomString(), "dummy")); + } + + // Just can't be the same as the last one. WHAT ARE THE ODDS + private String getRandomString() { + return String.valueOf(random.nextInt(10000)) + String.valueOf(random.nextInt(10000)); + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 0cd8fae3..6c2b9176 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -45,4 +45,20 @@ scoreboard: - "&4Leader" - "{leader}" - "&bTerritory" - - "{chunks}" \ No newline at end of file + - "{chunks}" + +# Default board that will always show up if a player wants it to. +# This can show any arbitrary text or you can use a lot of variables to replace things. +# Replace {name} - player's name. {faction} - player's faction title, factionless if none. +# {totalOnline} - total players on the server. {balance} - player's balance. +# {maxPower} - player's max power. + default-enabled: false # Default to false to keep original functionality. + default-title: "i love drt" # Can use any of the values from above but this won't update once it's set (so don't set {balance}). + default-update-interval: 2 # in seconds. + default: + - "&6Your Faction" + - "{faction}" + - "&3Your Power" + - "{power}" + - "&aBalance" + - "${balance}" \ No newline at end of file