Improve Team prefix performance

This change vastly improves performance for faction team prefix update
operations.
This commit is contained in:
eueln 2014-10-22 11:54:00 -05:00 committed by t00thpick1
parent 90e57740a2
commit 7f2ef4cbd5
5 changed files with 192 additions and 82 deletions

@ -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("<i>The faction %s<i> changed their name to %s.", fme.getColorTo(faction) + oldtag, myFaction.getTag(faction));
}
FScoreboard.applyUpdates(myFaction);
FTeamWrapper.updatePrefixes(myFaction);
}
}

@ -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("<i>This will have no effect while your faction is peaceful.");
}
FScoreboard.applyUpdates(myFaction);
FScoreboard.applyUpdates(them);
FTeamWrapper.updatePrefixes(myFaction);
FTeamWrapper.updatePrefixes(them);
}
}

@ -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());
}
}

@ -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<FPlayer, FScoreboard> fscoreboards = new HashMap<FPlayer, FScoreboard>();
private static final Map<FPlayer, FScoreboard> fscoreboards = new HashMap<FPlayer, FScoreboard>();
private final Scoreboard scoreboard;
private final FPlayer fplayer;
private final BufferedObjective bufferedObjective;
private final Map<Faction, Team> factionTeams = new HashMap<Faction, Team>();
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<FPlayer> 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);
}
}
}
}

@ -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<Faction, FTeamWrapper> wrappers = new HashMap<Faction, FTeamWrapper>();
private static final List<FScoreboard> tracking = new ArrayList<FScoreboard>();
private static int factionTeamPtr;
private final Map<FScoreboard, Team> teams = new HashMap<FScoreboard, Team>();
private final String teamName;
private final Faction faction;
private final Set<UUID> members = new HashSet<UUID>();
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<FPlayer> 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<FScoreboard, Team> 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<OfflinePlayer> getPlayers() {
Set<OfflinePlayer> ret = new HashSet<OfflinePlayer>();
for (UUID uuid : members) {
ret.add(Bukkit.getOfflinePlayer(uuid));
}
return ret;
}
private void unregister() {
for (Team team : teams.values()) {
team.unregister();
}
teams.clear();
}
}