From 7f2ef4cbd5744362ae34772d5785612bc2fa6009 Mon Sep 17 00:00:00 2001 From: eueln Date: Wed, 22 Oct 2014 11:54:00 -0500 Subject: [PATCH] Improve Team prefix performance This change vastly improves performance for faction team prefix update operations. --- .../com/massivecraft/factions/cmd/CmdTag.java | 4 +- .../factions/cmd/FRelationCommand.java | 6 +- .../listeners/FactionsPlayerListener.java | 5 +- .../factions/scoreboards/FScoreboard.java | 93 ++-------- .../factions/scoreboards/FTeamWrapper.java | 166 ++++++++++++++++++ 5 files changed, 192 insertions(+), 82 deletions(-) create mode 100644 src/main/java/com/massivecraft/factions/scoreboards/FTeamWrapper.java diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdTag.java b/src/main/java/com/massivecraft/factions/cmd/CmdTag.java index b2c4e57f..b98f54bc 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdTag.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdTag.java @@ -4,7 +4,7 @@ import com.massivecraft.factions.Conf; import com.massivecraft.factions.Faction; import com.massivecraft.factions.Factions; import com.massivecraft.factions.event.FactionRenameEvent; -import com.massivecraft.factions.scoreboards.FScoreboard; +import com.massivecraft.factions.scoreboards.FTeamWrapper; import com.massivecraft.factions.struct.Permission; import com.massivecraft.factions.util.MiscUtil; import org.bukkit.Bukkit; @@ -74,7 +74,7 @@ public class CmdTag extends FCommand { faction.msg("The faction %s changed their name to %s.", fme.getColorTo(faction) + oldtag, myFaction.getTag(faction)); } - FScoreboard.applyUpdates(myFaction); + FTeamWrapper.updatePrefixes(myFaction); } } diff --git a/src/main/java/com/massivecraft/factions/cmd/FRelationCommand.java b/src/main/java/com/massivecraft/factions/cmd/FRelationCommand.java index e84fd28c..d757aa2c 100644 --- a/src/main/java/com/massivecraft/factions/cmd/FRelationCommand.java +++ b/src/main/java/com/massivecraft/factions/cmd/FRelationCommand.java @@ -3,7 +3,7 @@ package com.massivecraft.factions.cmd; import com.massivecraft.factions.Conf; import com.massivecraft.factions.Faction; import com.massivecraft.factions.event.FactionRelationEvent; -import com.massivecraft.factions.scoreboards.FScoreboard; +import com.massivecraft.factions.scoreboards.FTeamWrapper; import com.massivecraft.factions.struct.Permission; import com.massivecraft.factions.struct.Relation; import org.bukkit.Bukkit; @@ -86,7 +86,7 @@ public abstract class FRelationCommand extends FCommand { myFaction.msg("This will have no effect while your faction is peaceful."); } - FScoreboard.applyUpdates(myFaction); - FScoreboard.applyUpdates(them); + FTeamWrapper.updatePrefixes(myFaction); + FTeamWrapper.updatePrefixes(them); } } diff --git a/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java b/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java index da606a30..da4af5ce 100644 --- a/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java +++ b/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java @@ -4,6 +4,7 @@ import com.massivecraft.factions.*; import com.massivecraft.factions.event.FPlayerJoinEvent; import com.massivecraft.factions.event.FPlayerLeaveEvent; import com.massivecraft.factions.scoreboards.FScoreboard; +import com.massivecraft.factions.scoreboards.FTeamWrapper; import com.massivecraft.factions.scoreboards.sidebar.FDefaultSidebar; import com.massivecraft.factions.struct.Permission; import com.massivecraft.factions.struct.Relation; @@ -526,11 +527,11 @@ public class FactionsPlayerListener implements Listener { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) final public void onFactionJoin(FPlayerJoinEvent event) { - FScoreboard.applyUpdatesLater(event.getFaction()); + FTeamWrapper.applyUpdatesLater(event.getFaction()); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onFactionLeave(FPlayerLeaveEvent event) { - FScoreboard.applyUpdatesLater(event.getFaction()); + FTeamWrapper.applyUpdatesLater(event.getFaction()); } } diff --git a/src/main/java/com/massivecraft/factions/scoreboards/FScoreboard.java b/src/main/java/com/massivecraft/factions/scoreboards/FScoreboard.java index 25a09e1b..61749e4e 100644 --- a/src/main/java/com/massivecraft/factions/scoreboards/FScoreboard.java +++ b/src/main/java/com/massivecraft/factions/scoreboards/FScoreboard.java @@ -1,40 +1,40 @@ package com.massivecraft.factions.scoreboards; import com.massivecraft.factions.*; -import com.massivecraft.factions.zcore.util.TL; import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scoreboard.DisplaySlot; import org.bukkit.scoreboard.Scoreboard; -import org.bukkit.scoreboard.Team; import java.util.HashMap; import java.util.Map; -import java.util.Set; public class FScoreboard { - private static Map fscoreboards = new HashMap(); + private static final Map fscoreboards = new HashMap(); private final Scoreboard scoreboard; private final FPlayer fplayer; private final BufferedObjective bufferedObjective; - private final Map factionTeams = new HashMap(); - private int factionTeamPtr; private FSidebarProvider defaultProvider; private FSidebarProvider temporaryProvider; private boolean removed = false; public static void init(FPlayer fplayer) { - fscoreboards.put(fplayer, new FScoreboard(fplayer)); + FScoreboard fboard = new FScoreboard(fplayer); + fscoreboards.put(fplayer, fboard); + if (fplayer.hasFaction()) { - FScoreboard.applyUpdates(fplayer.getFaction()); + FTeamWrapper.applyUpdates(fplayer.getFaction()); } + FTeamWrapper.track(fboard); } public static void remove(FPlayer fplayer) { - fscoreboards.remove(fplayer).removed = true; + FScoreboard fboard = fscoreboards.remove(fplayer); + + fboard.removed = true; + FTeamWrapper.untrack(fboard); } public static FScoreboard get(FPlayer fplayer) { @@ -45,33 +45,22 @@ public class FScoreboard { return fscoreboards.get(FPlayers.i.get(player)); } - public static void applyUpdatesLater(final Faction faction) { - Bukkit.getScheduler().runTask(P.p, new Runnable() { - @Override - public void run() { - applyUpdates(faction); - } - }); - } - - public static void applyUpdates(Faction faction) { - for (FScoreboard fscoreboard : fscoreboards.values()) { - fscoreboard.updateFactionTeam(faction); - } - } - private FScoreboard(FPlayer fplayer) { this.fplayer = fplayer; this.scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); this.bufferedObjective = new BufferedObjective(scoreboard); - for (Faction faction : Factions.i.get()) { - updateFactionTeam(faction); - } - fplayer.getPlayer().setScoreboard(scoreboard); } + protected FPlayer getFPlayer() { + return fplayer; + } + + protected Scoreboard getScoreboard() { + return scoreboard; + } + public void setSidebarVisibility(boolean visible) { bufferedObjective.setDisplaySlot(visible ? DisplaySlot.SIDEBAR : null); } @@ -128,50 +117,4 @@ public class FScoreboard { bufferedObjective.flip(); } } - - public void updateFactionTeam(Faction faction) { - Team team = factionTeams.get(faction); - Set factionMembers = faction.getFPlayers(); - - if (!Factions.i.get().contains(faction)) { - // Faction was disbanded - if (team != null) { - factionTeams.remove(faction); - team.unregister(); - } - return; - } - - if (team == null) { - team = scoreboard.registerNewTeam("faction_" + (factionTeamPtr++)); - factionTeams.put(faction, team); - } - - for (OfflinePlayer player : team.getPlayers()) { - if (!player.isOnline() || !factionMembers.contains(FPlayers.i.get(player.getPlayer()))) { - // Player is offline or no longer in faction - team.removePlayer(player); - } - } - - for (FPlayer fmember : factionMembers) { - if (!fmember.isOnline()) { - continue; - } - if (!team.hasPlayer(fmember.getPlayer())) { - // Scoreboard team doesn't have player; add him/her - team.addPlayer(fmember.getPlayer()); - } - } - - // Update faction prefix - if(P.p.getConfig().getBoolean("scoreboard.default-prefixes", false)) { - String prefix = TL.DEFAULT_PREFIX.toString(); - prefix = prefix.replace("{relationcolor}", faction.getRelationTo(this.fplayer).getColor().toString()); - prefix = prefix.replace("{faction}", faction.getTag().substring(0, Math.min("{faction}".length() + 16 - prefix.length(), faction.getTag().length()))); - if (team.getPrefix() == null || !team.getPrefix().equals(prefix)) { - team.setPrefix(prefix); - } - } - } } diff --git a/src/main/java/com/massivecraft/factions/scoreboards/FTeamWrapper.java b/src/main/java/com/massivecraft/factions/scoreboards/FTeamWrapper.java new file mode 100644 index 00000000..ae3606c9 --- /dev/null +++ b/src/main/java/com/massivecraft/factions/scoreboards/FTeamWrapper.java @@ -0,0 +1,166 @@ +package com.massivecraft.factions.scoreboards; + +import com.massivecraft.factions.*; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; + +import java.util.*; + +public class FTeamWrapper { + private static final Map wrappers = new HashMap(); + private static final List tracking = new ArrayList(); + private static int factionTeamPtr; + + private final Map teams = new HashMap(); + private final String teamName; + private final Faction faction; + private final Set members = new HashSet(); + + public static void applyUpdatesLater(final Faction faction) { + Bukkit.getScheduler().runTask(P.p, new Runnable() { + @Override + public void run() { + applyUpdates(faction); + } + }); + } + + public static void applyUpdates(Faction faction) { + FTeamWrapper wrapper = wrappers.get(faction); + Set factionMembers = faction.getFPlayers(); + + if (wrapper != null && !Factions.i.get().contains(faction)) { + // Faction was disbanded + wrapper.unregister(); + wrappers.remove(faction); + return; + } + + if (wrapper == null) { + wrapper = new FTeamWrapper(faction); + wrappers.put(faction, wrapper); + } + + for (OfflinePlayer player : wrapper.getPlayers()) { + if (!player.isOnline() || !factionMembers.contains(FPlayers.i.get(player))) { + // Player is offline or no longer in faction + wrapper.removePlayer(player); + } + } + + for (FPlayer fmember : factionMembers) { + if (!fmember.isOnline()) { + continue; + } + + // Scoreboard might not have player; add him/her + wrapper.addPlayer(fmember.getPlayer()); + } + + wrapper.updatePrefixes(); + } + + public static void updatePrefixes(Faction faction) { + wrappers.get(faction).updatePrefixes(); + } + + protected static void track(FScoreboard fboard) { + tracking.add(fboard); + for (FTeamWrapper wrapper : wrappers.values()) { + wrapper.add(fboard); + } + } + + protected static void untrack(FScoreboard fboard) { + tracking.remove(fboard); + for (FTeamWrapper wrapper : wrappers.values()) { + wrapper.remove(fboard); + } + } + + + private FTeamWrapper(Faction faction) { + this.teamName = "faction_" + (factionTeamPtr++); + this.faction = faction; + + for (FScoreboard fboard : tracking) { + add(fboard); + } + } + + private void add(FScoreboard fboard) { + Scoreboard board = fboard.getScoreboard(); + Team team = board.registerNewTeam(teamName); + teams.put(fboard, team); + + for (OfflinePlayer player : getPlayers()) { + team.addPlayer(player); + } + + updatePrefix(fboard); + } + + private void remove(FScoreboard fboard) { + teams.remove(fboard).unregister(); + } + + private void updatePrefixes() { + if (P.p.getConfig().getBoolean("scoreboard.default-prefixes", false)) { + for (FScoreboard fboard : teams.keySet()) { + updatePrefix(fboard); + } + } + } + + private void updatePrefix(FScoreboard fboard) { + if (P.p.getConfig().getBoolean("scoreboard.default-prefixes", false)) { + + for (Map.Entry entry : teams.entrySet()) { + FPlayer fplayer = entry.getKey().getFPlayer(); + Team team = entry.getValue(); + + String prefix = TL.DEFAULT_PREFIX.toString(); + prefix = prefix.replace("{relationcolor}", faction.getRelationTo(fplayer).getColor().toString()); + prefix = prefix.replace("{faction}", faction.getTag().substring(0, Math.min("{faction}".length() + 16 - prefix.length(), faction.getTag().length()))); + if (team.getPrefix() == null || !team.getPrefix().equals(prefix)) { + team.setPrefix(prefix); + } + } + } + } + + private void addPlayer(OfflinePlayer player) { + if (members.add(player.getUniqueId())) { + for (Team team : teams.values()) { + team.addPlayer(player); + } + } + } + + private void removePlayer(OfflinePlayer player) { + if (members.remove(player.getUniqueId())) { + for (Team team : teams.values()) { + team.removePlayer(player); + } + } + } + + private Set getPlayers() { + Set ret = new HashSet(); + for (UUID uuid : members) { + ret.add(Bukkit.getOfflinePlayer(uuid)); + } + return ret; + } + + private void unregister() { + for (Team team : teams.values()) { + team.unregister(); + } + teams.clear(); + } +} +