diff --git a/README.md b/README.md index 0a254e7..be74f70 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,8 @@ How do I add it to my project? Simply add the following to your `pom.xml`. - tiger-repo - http://repo.tigerhix.me/content/repositories/snapshots/ + funkemunky-snapshots + https://nexus.funkemunky.cc/content/repositories/snapshots diff --git a/pom.xml b/pom.xml index 295a251..f0c8899 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ me.tigerhix.lib scoreboard - 1.0.1-SNAPSHOT + 1.1.0-SNAPSHOT jar @@ -18,15 +18,19 @@ - tiger-repo - http://repo.tigerhix.me/content/groups/public/ + funkemunky-releases + https://nexus.funkemunky.cc/content/repositories/releases/ + + + papermc + https://repo.papermc.io/repository/maven-public/ - nexus - http://repo.tigerhix.me/content/repositories/snapshots + funkemunky-snapshots + https://nexus.funkemunky.cc/content/repositories/snapshots @@ -45,10 +49,10 @@ org.apache.maven.plugins maven-compiler-plugin - 3.0 + 3.13.0 - 1.7 - 1.7 + 17 + 17 -Xlint:all -Xlint:-path @@ -57,7 +61,35 @@ true + + maven-deploy-plugin + 3.1.4 + + + snapshot-deploy + deploy + + deploy + + + + + + + io.papermc.paper + paper-api + 1.19.4-R0.1-SNAPSHOT + provided + + + org.github.paperspigot + 1.19.4 + 1.19.4 + provided + + + diff --git a/src/main/java/me/tigerhix/lib/scoreboard/type/Entry.java b/src/main/java/me/tigerhix/lib/scoreboard/type/Entry.java index 6c04a2b..4268730 100644 --- a/src/main/java/me/tigerhix/lib/scoreboard/type/Entry.java +++ b/src/main/java/me/tigerhix/lib/scoreboard/type/Entry.java @@ -1,22 +1,23 @@ package me.tigerhix.lib.scoreboard.type; -import me.tigerhix.lib.scoreboard.common.Strings; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; public class Entry { - private String name; + private TextComponent name; private int position; public Entry(String name, int position) { - this.name = Strings.format(name); + this.name = LegacyComponentSerializer.legacySection().deserialize(name); this.position = position; } - public String getName() { + public TextComponent getName() { return name; } - public void setName(String name) { + public void setName(TextComponent name) { this.name = name; } diff --git a/src/main/java/me/tigerhix/lib/scoreboard/type/SimpleScoreboard.java b/src/main/java/me/tigerhix/lib/scoreboard/type/SimpleScoreboard.java index b864c1b..2373ab2 100755 --- a/src/main/java/me/tigerhix/lib/scoreboard/type/SimpleScoreboard.java +++ b/src/main/java/me/tigerhix/lib/scoreboard/type/SimpleScoreboard.java @@ -1,13 +1,10 @@ package me.tigerhix.lib.scoreboard.type; -import com.google.common.collect.HashBasedTable; -import com.google.common.collect.Table; import me.tigerhix.lib.scoreboard.ScoreboardLib; import me.tigerhix.lib.scoreboard.common.Strings; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.OfflinePlayer; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; +import org.bukkit.*; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scoreboard.DisplaySlot; @@ -17,14 +14,9 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; public class SimpleScoreboard implements Scoreboard { - private static final String TEAM_PREFIX = "Scoreboard_"; - private static int TEAM_COUNTER = 0; - private final org.bukkit.scoreboard.Scoreboard scoreboard; private final Objective objective; @@ -33,9 +25,8 @@ public class SimpleScoreboard implements Scoreboard { private boolean activated; private ScoreboardHandler handler; - private Map entryCache = new ConcurrentHashMap<>(); - private Table playerCache = HashBasedTable.create(); - private Table teamCache = HashBasedTable.create(); + // We use a map to track teams by line number for easy updating. + private final Map teams = new HashMap<>(); private BukkitRunnable updateTask; public SimpleScoreboard(Player holder) { @@ -74,7 +65,7 @@ public void deactivate() { } } // Unregister teams that are created for this scoreboard - for (Team team : teamCache.rowKeySet()) { + for (Team team : teams.values()) { team.unregister(); } // Stop updating @@ -126,88 +117,15 @@ private void update() { if (!objective.getDisplayName().equals(finalTitle)) objective.setDisplayName(Strings.format(finalTitle)); // Entries List passed = handler.getEntries(holder); - Map appeared = new HashMap<>(); - Map current = new HashMap<>(); if (passed == null) return; for (Entry entry : passed) { // Handle the entry - String key = entry.getName(); - Integer score = entry.getPosition(); - if (key.length() > 48) key = key.substring(0, 47); - String appearance; - if (key.length() > 16) { - appearance = key.substring(16); - } else { - appearance = key; - } - if (!appeared.containsKey(appearance)) appeared.put(appearance, -1); - appeared.put(appearance, appeared.get(appearance) + 1); - // Get fake player - FakePlayer faker = getFakePlayer(key, appeared.get(appearance)); - // Set score - objective.getScore(faker).setScore(score); - // Update references - entryCache.put(faker, score); - current.put(faker, score); - } - appeared.clear(); - // Remove duplicated or non-existent entries - for (FakePlayer fakePlayer : entryCache.keySet()) { - if (!current.containsKey(fakePlayer)) { - entryCache.remove(fakePlayer); - scoreboard.resetScores(fakePlayer.getName()); - } - } - } + TextComponent key = entry.getName(); + int score = entry.getPosition(); - @SuppressWarnings("deprecation") - private FakePlayer getFakePlayer(String text, int offset) { - Team team = null; - String name; - // If the text has a length less than 16, teams need not to be be created - if (text.length() <= 16) { - name = text + Strings.repeat(" ", offset); - } else { - String prefix; - String suffix = ""; - offset++; - // Otherwise, iterate through the string and cut off prefix and suffix - prefix = text.substring(0, 16 - offset); - name = text.substring(16 - offset); - if (name.length() > 16) name = name.substring(0, 16); - if (text.length() > 32) suffix = text.substring(32 - offset); - // If teams already exist, use them - for (Team other : teamCache.rowKeySet()) { - if (other.getPrefix().equals(prefix) && other.getSuffix().equals(suffix)) { - team = other; - } - } - // Otherwise create them - if (team == null) { - team = scoreboard.registerNewTeam(TEAM_PREFIX + TEAM_COUNTER++); - team.setPrefix(prefix); - team.setSuffix(suffix); - teamCache.put(team, prefix, suffix); - } - } - FakePlayer faker; - if (!playerCache.contains(name, offset)) { - faker = new FakePlayer(name, team, offset); - playerCache.put(name, offset, faker); - if (faker.getTeam() != null) { - faker.getTeam().addPlayer(faker); - } - } else { - faker = playerCache.get(name, offset); - if (team != null && faker.getTeam() != null) { - faker.getTeam().removePlayer(faker); - } - faker.setTeam(team); - if (faker.getTeam() != null) { - faker.getTeam().addPlayer(faker); - } + setLine(score, key); + // Update references } - return faker; } public Objective getObjective() { @@ -218,117 +136,58 @@ public org.bukkit.scoreboard.Scoreboard getScoreboard() { return scoreboard; } - private static class FakePlayer implements OfflinePlayer { - - private final String name; - - private Team team; - private int offset; - - FakePlayer(String name, Team team, int offset) { - this.name = name; - this.team = team; - this.offset = offset; - } - - public Team getTeam() { - return team; - } - - public void setTeam(Team team) { - this.team = team; - } - - public int getOffset() { - return offset; - } - - public String getFullName() { - if (team == null) return name; - if (team.getSuffix() == null) return team.getPrefix() + name; - return team.getPrefix() + name + team.getSuffix(); - } - - @Override - public boolean isOnline() { - return true; - } - - @Override - public String getName() { - return name; - } - - @Override - public UUID getUniqueId() { - return UUID.randomUUID(); - } - - @Override - public boolean isBanned() { - return false; - } - - @Override - public void setBanned(boolean banned) { - } - - @Override - public boolean isWhitelisted() { - return false; - } - @Override - public void setWhitelisted(boolean whitelisted) { - } + /** + * Sets the title of the scoreboard. + * @param title The new title (supports ChatColor). + */ + public void setTitle(String title) { + this.objective.setDisplayName(title); + } - @Override - public Player getPlayer() { - return null; - } + /** + * Sets a specific line on the scoreboard to a rich TextComponent. + * @param line The line number (from top to bottom, 15 is highest). + * @param component The BaseComponent (e.g., TextComponent) to display. + */ + public void setLine(int line, Component component) { + Team team = getTeamForLine(line); - @Override - public long getFirstPlayed() { - return 0; - } + // In 1.13+ we can set the prefix/suffix directly with components. + team.prefix(component); - @Override - public long getLastPlayed() { - return 0; - } - - @Override - public boolean hasPlayedBefore() { - return false; - } + // Set the score to show this line. + objective.getScore(getEntryForLine(line)).setScore(line); + } - @Override - public Location getBedSpawnLocation() { - return null; - } - @Override - public Map serialize() { - return null; + /** + * Retrieves or creates a team for a given line number. + * Teams are used to hold the prefix, which is our component content. + */ + private Team getTeamForLine(int line) { + if (teams.containsKey(line)) { + return teams.get(line); } - @Override - public boolean isOp() { - return false; - } + // Team name must be unique. Line number is a good candidate. + Team team = scoreboard.registerNewTeam("line" + line); - @Override - public void setOp(boolean op) { - } + // Each team needs a unique entry to display. We use ChatColor codes. + // This entry is what gets the score, but it will be invisible. + String entry = getEntryForLine(line); + team.addEntry(entry); - @Override - public String toString() { - return "FakePlayer{" + - "name='" + name + '\'' + - ", team=" + team - + '}'; - } + teams.put(line, team); + return team; + } + /** + * Gets the unique, invisible entry name for a given line. + * We use ChatColor codes to make them unique and not display in chat. + */ + private String getEntryForLine(int line) { + return ChatColor.values()[line].toString() + ChatColor.RESET; } } \ No newline at end of file