Skip to content

Commit

Permalink
scoreboard command cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Oct 9, 2021
1 parent ae004b6 commit 2a33586
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.denizenscript.denizen.scripts.commands.player.SidebarCommand;
import com.denizenscript.denizen.utilities.AdvancedTextImpl;
import com.denizenscript.denizen.utilities.FormattedTextHelper;
import com.denizenscript.denizen.utilities.ScoreboardHelper;
import com.denizenscript.denizen.utilities.Utilities;
import com.denizenscript.denizen.utilities.blocks.FakeBlock;
import com.denizenscript.denizen.utilities.debugging.Debug;
Expand Down Expand Up @@ -2345,6 +2346,20 @@ else if (foodLevel / maxHunger < 1) {
long relativeMillis = System.nanoTime() / 1000000L - playerMilliTime;
return new TimeTag(System.currentTimeMillis() - relativeMillis);
});

// <--[tag]
// @attribute <PlayerTag.scoreboard_id>
// @returns ElementTag
// @description
// Returns the ID of the scoreboard from <@link command scoreboard> that a player is currently viewing, if any.
// -->
registerOnlineOnlyTag("scoreboard_id", (attribute, object) -> {
String id = ScoreboardHelper.viewerMap.get(object.getUUID());
if (id == null) {
return null;
}
return new ElementTag(id);
});
}

public static ObjectTagProcessor<PlayerTag> tagProcessor = new ObjectTagProcessor<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
package com.denizenscript.denizen.scripts.commands.server;

import com.denizenscript.denizen.objects.EntityTag;
import com.denizenscript.denizen.utilities.Utilities;
import com.denizenscript.denizen.utilities.entity.FakeOfflinePlayer;
import com.denizenscript.denizen.utilities.ScoreboardHelper;
import com.denizenscript.denizen.utilities.debugging.Debug;
import com.denizenscript.denizen.objects.PlayerTag;
import com.denizenscript.denizencore.exceptions.InvalidArgumentsException;
import com.denizenscript.denizencore.objects.Argument;
import com.denizenscript.denizencore.objects.ObjectTag;
import com.denizenscript.denizencore.objects.core.ElementTag;
import com.denizenscript.denizencore.objects.ArgumentHelper;
import com.denizenscript.denizencore.objects.core.ListTag;
import com.denizenscript.denizencore.scripts.ScriptEntry;
import com.denizenscript.denizencore.scripts.commands.AbstractCommand;
import com.denizenscript.denizencore.utilities.CoreUtilities;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.RenderType;
Expand Down Expand Up @@ -79,6 +84,7 @@ public ScoreboardCommand() {
// @Tags
// <server.scoreboard[(<board>)].exists>
// <server.scoreboard[(<board>)].team[<team>].members>
// <PlayerTag.scoreboard_id>
//
// @Usage
// Add a score for the defined player to the default scoreboard under the objective "cookies" and let him see it
Expand Down Expand Up @@ -168,13 +174,25 @@ else if (!scriptEntry.hasObject("viewers")
scriptEntry.defaultObject("id", new ElementTag("main"));
}

public static OfflinePlayer getOfflinePlayer(String name) {
if (PlayerTag.playerNameIsValid(name)) {
return Bukkit.getOfflinePlayer(name);
public static String checkLine(ObjectTag obj) {
if (obj instanceof PlayerTag) {
return ((PlayerTag) obj).getName();
}
else {
return new FakeOfflinePlayer(name);
else if (obj instanceof EntityTag && ((EntityTag) obj).isSpawned()) {
Entity ent = ((EntityTag) obj).getBukkitEntity();
if (ent instanceof Player) {
return ent.getName();
}
return ent.getUniqueId().toString();
}
String raw = obj.toString();
if (raw.startsWith("p@")) {
PlayerTag player = PlayerTag.valueOf(raw, CoreUtilities.noDebugContext);
if (player != null) {
return player.getName();
}
}
return raw;
}

@Override
Expand Down Expand Up @@ -260,17 +278,8 @@ else if (!existedAlready) {
score = new ElementTag(0);
}

// Set all the score lines in the scoreboard, creating fake players
// for those lines that are not meant to track players
//
// Read https://forums.bukkit.org/threads/help-with-multi-line-scoreboards.181149/
// for clarifications
for (String line : lines) {
line = line.replaceAll("[pP]@", "");
if (line.length() > 48) {
line = line.substring(0, 48);
}
ScoreboardHelper.addScore(obj, getOfflinePlayer(line), score.asInt());
for (ObjectTag line : lines.objectForms) {
ScoreboardHelper.addScore(obj, checkLine(line), score.asInt());
}
}
}
Expand All @@ -292,9 +301,8 @@ else if (act.equals(Action.REMOVE)) {
obj.unregister();
}
else {
for (String line : lines) {
line = line.replaceAll("[pP]@", "");
ScoreboardHelper.removeScore(obj, getOfflinePlayer(line));
for (ObjectTag line : lines.objectForms) {
ScoreboardHelper.removeScore(obj, checkLine(line));
}
}
}
Expand All @@ -309,9 +317,8 @@ else if (!lines.isEmpty()) {
Debug.echoDebug(scriptEntry, "Removing lines " + lines.identify() +
" from all objectives in scoreboard " + id.asString());

for (String line : lines) {
line = line.replaceAll("[pP]@", "");
ScoreboardHelper.removePlayer(id.asString(), getOfflinePlayer(line));
for (ObjectTag line : lines.objectForms) {
ScoreboardHelper.removePlayer(id.asString(), checkLine(line));
}
}
// Only remove all objectives from scoreboard if viewers
Expand All @@ -329,7 +336,7 @@ else if (viewers == null) {
// If this isn't the main scoreboard, add this viewer
// to the map of viewers saved by Denizen
if (!id.asString().equalsIgnoreCase("main")) {
ScoreboardHelper.viewerMap.put(viewer.getName(), id.asString());
ScoreboardHelper.viewerMap.put(viewer.getUUID(), id.asString());
}
// Make this player view the scoreboard if he/she
// is already online
Expand All @@ -340,7 +347,7 @@ else if (viewers == null) {
// Remove viewers for this scoreboard
else if (act.equals(Action.REMOVE)) {
// Take this player out of the map of viewers
ScoreboardHelper.viewerMap.remove(viewer.getName());
ScoreboardHelper.viewerMap.remove(viewer.getUUID());

// Make the player view a blank scoreboard if he/she
// is online (in lieu of a scoreboard-removing method
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ public void onPlayerJoins(PlayerJoinEvent event) {
if (EntityTag.isNPC(event.getPlayer())) {
return;
}
if (ScoreboardHelper.viewerMap.containsKey(event.getPlayer().getName())) {
Scoreboard score = ScoreboardHelper.getScoreboard(ScoreboardHelper.viewerMap.get(event.getPlayer().getName()));
String board = ScoreboardHelper.viewerMap.get(event.getPlayer().getUniqueId());
if (board != null) {
Scoreboard score = ScoreboardHelper.getScoreboard(board);
if (score != null) {
event.getPlayer().setScoreboard(score);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class ScoreboardHelper {
// A map with scoreboard IDs as keys and scoreboards as values
public static Map<String, Scoreboard> scoreboardMap = new HashMap<>();
// A map with viewer names as keys and scoreboard IDs as values
public static Map<String, String> viewerMap = new HashMap<>();
public static Map<UUID, String> viewerMap = new HashMap<>();

/*
* Called on server startup or /denizen reload saves
Expand All @@ -40,9 +40,9 @@ public static void _recallScoreboards() {
Scoreboard emptyBoard = createScoreboard();

// Clear every viewer's set scoreboard
for (Map.Entry<String, String> entry : viewerMap.entrySet()) {
OfflinePlayer player = ScoreboardCommand.getOfflinePlayer(entry.getKey());
if (player.isOnline()) {
for (Map.Entry<UUID, String> entry : viewerMap.entrySet()) {
OfflinePlayer player = Bukkit.getPlayer(entry.getKey());
if (player != null && player.isOnline()) {
player.getPlayer().setScoreboard(emptyBoard);
}
}
Expand Down Expand Up @@ -74,7 +74,7 @@ public static void _recallScoreboards() {
for (String viewer : viewerList) {
if (PlayerTag.matches(viewer)) {
PlayerTag player = PlayerTag.valueOf(viewer, CoreUtilities.basicContext);
viewerMap.put(player.getName(), id);
viewerMap.put(player.getUUID(), id);

if (player.isOnline()) {
player.getPlayerEntity().setScoreboard(board);
Expand Down Expand Up @@ -121,7 +121,7 @@ public static void _recallScoreboards() {
// Iterate through scores and add them to this objective
for (String scoreName : scoreSection.getKeys(false)) {
int scoreInt = scoreSection.getInt(scoreName);
addScore(o, ScoreboardCommand.getOfflinePlayer(scoreName), scoreInt);
addScore(o, scoreName, scoreInt);
}
}
}
Expand All @@ -146,9 +146,9 @@ public static void _saveScoreboards() {

// Find all of the viewers that are viewing this scoreboard
// and put them on a list
for (Map.Entry<String, String> viewerEntry : viewerMap.entrySet()) {
for (Map.Entry<UUID, String> viewerEntry : viewerMap.entrySet()) {
if (id.equalsIgnoreCase(viewerEntry.getValue())) {
viewerList.add(viewerEntry.getKey());
viewerList.add(viewerEntry.getKey().toString());
}
}

Expand Down Expand Up @@ -210,21 +210,20 @@ public static void _saveScoreboards() {
/////////////////

/**
* Add a score to an Objective for an OfflinePlayer.
* Add a score to an Objective for a name.
*
* @param o the Objective to add the score to
* @param player the OfflinePlayer to set the score for
* @param score the score
*/
public static void addScore(Objective o, OfflinePlayer player, int score) {
public static void addScore(Objective o, String playerName, int score) {
Score sc;
if (player.getName().length() <= 16) {
sc = o.getScore(player.getName());
if (playerName.length() <= 16) {
sc = o.getScore(playerName);
}
else {
Map.Entry<Team, String> teamData = createTeam(o.getScoreboard(), player.getName());
Map.Entry<Team, String> teamData = createTeam(o.getScoreboard(), playerName);
sc = o.getScore(teamData.getValue());
teamData.getKey().addPlayer(ScoreboardCommand.getOfflinePlayer(teamData.getValue()));
teamData.getKey().addEntry(teamData.getValue());
}

// If the score is 0, it won't normally be displayed at first,
Expand All @@ -239,12 +238,11 @@ public static void addScore(Objective o, OfflinePlayer player, int score) {
}

/**
* Remove a score from an Objective for an OfflinePlayer.
* Remove a score from an Objective for a name.
*
* @param o the Objective to remove the score from
* @param player the OfflinePlayer to remove the score for
*/
public static void removeScore(Objective o, OfflinePlayer player) {
public static void removeScore(Objective o, String playerName) {

// There is no method to remove a single score from an
// objective, as confirmed here:
Expand All @@ -257,7 +255,7 @@ public static void removeScore(Objective o, OfflinePlayer player) {
// Go through every score for this (real or fake) player
// and put it in scoreMap if it doesn't belong to the
// objective we want to remove the score from
String name = createTeam(board, player.getName()).getValue();
String name = createTeam(board, playerName).getValue();
// TODO: Properly remove when teams are involved
for (Score sc : board.getScores(name)) {
if (!sc.getObjective().equals(o)) {
Expand All @@ -266,13 +264,12 @@ public static void removeScore(Objective o, OfflinePlayer player) {
}

// Remove all the scores for this (real or fake) player
board.resetScores(player.getName());
board.resetScores(playerName);

// Go through scoreMap and add back all the scores we saved
// for this (real or fake) player
for (Map.Entry<String, Integer> entry : scoreMap.entrySet()) {
board.getObjective(entry.getKey())
.getScore(player.getName()).setScore(entry.getValue());
board.getObjective(entry.getKey()).getScore(playerName).setScore(entry.getValue());
}
}

Expand Down Expand Up @@ -301,8 +298,7 @@ private static Map.Entry<Team, String> createTeam(Scoreboard scoreboard, String
/////////////////

/**
* Clears all the objectives from a Scoreboard, making
* it empty.
* Clears all the objectives from a Scoreboard, making it empty.
*
* @param board the Scoreboard to clear
*/
Expand All @@ -313,8 +309,7 @@ public static void clearScoreboard(Scoreboard board) {
}

/**
* Creates an anonymous new Scoreboard that isn't
* saved anywhere.
* Creates an anonymous new Scoreboard that isn't saved anywhere.
*
* @return the new Scoreboard
*/
Expand All @@ -323,8 +318,7 @@ public static Scoreboard createScoreboard() {
}

/**
* Creates a new Scoreboard with a certain id and
* stories it in the scoreboards map.
* Creates a new Scoreboard with a certain id and stories it in the scoreboards map.
*
* @param id the id of the new Scoreboard
* @return the new Scoreboard
Expand All @@ -336,9 +330,7 @@ public static Scoreboard createScoreboard(String id) {
}

/**
* Deletes a Scoreboard, clearing it and removing it from
* the scoreboards map, unless it is the server's main
* scoreboard, in which case it is just cleared.
* Deletes a Scoreboard, clearing it and removing it from the scoreboards map, unless it is the server's main scoreboard, in which case it is just cleared.
*
* @param id the id of the Scoreboard
*/
Expand All @@ -353,9 +345,7 @@ public static void deleteScoreboard(String id) {
}

/**
* Returns the server's main scoreboard, that isn't stored
* in the scoreboards map because Bukkit already saves it
* by itself.
* Returns the server's main scoreboard, that isn't stored in the scoreboards map because Bukkit already saves it by itself.
*
* @return the main Scoreboard
*/
Expand All @@ -374,8 +364,7 @@ public static Scoreboard getScoreboard(String id) {
}

/**
* Returns true if the scoreboards map contains a certain
* scoreboard id.
* Returns true if the scoreboards map contains a certain scoreboard id.
*
* @param id the id of the Scoreboard
* @return true or false
Expand All @@ -384,14 +373,7 @@ public static boolean hasScoreboard(String id) {
return scoreboardMap.containsKey(id.toUpperCase());
}

/**
* Removes all the scores of an OfflinePlayer from a
* Scoreboard.
*
* @param id the id of the Scoreboard
* @param player the OfflinePlayer
*/
public static void removePlayer(String id, OfflinePlayer player) {
scoreboardMap.get(id.toUpperCase()).resetScores(player.getName());
public static void removePlayer(String id, String name) {
scoreboardMap.get(id.toUpperCase()).resetScores(name);
}
}

0 comments on commit 2a33586

Please sign in to comment.