SPIGOT-2450: Improve scoreboard criteria API, add missing DisplaySlots

By: Parker Hawke <hawkeboyz2@hotmail.com>
This commit is contained in:
CraftBukkit/Spigot 2022-08-08 21:50:13 +10:00
parent ba6d980d80
commit 06a34ebbdd
6 changed files with 92 additions and 17 deletions

View file

@ -176,6 +176,7 @@ import org.bukkit.craftbukkit.metadata.WorldMetadataStore;
import org.bukkit.craftbukkit.potion.CraftPotionBrewer;
import org.bukkit.craftbukkit.profile.CraftPlayerProfile;
import org.bukkit.craftbukkit.scheduler.CraftScheduler;
import org.bukkit.craftbukkit.scoreboard.CraftCriteria;
import org.bukkit.craftbukkit.scoreboard.CraftScoreboardManager;
import org.bukkit.craftbukkit.structure.CraftStructureManager;
import org.bukkit.craftbukkit.tag.CraftBlockTag;
@ -237,6 +238,7 @@ import org.bukkit.potion.Potion;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.profile.PlayerProfile;
import org.bukkit.scheduler.BukkitWorker;
import org.bukkit.scoreboard.Criteria;
import org.bukkit.structure.StructureManager;
import org.bukkit.util.StringUtil;
import org.bukkit.util.permissions.DefaultPermissions;
@ -1982,6 +1984,11 @@ public final class CraftServer implements Server {
return scoreboardManager;
}
@Override
public Criteria getScoreboardCriteria(String name) {
return CraftCriteria.getFromBukkit(name);
}
public void checkSaveState() {
if (this.playerCommandState || this.printSaveWarning || this.console.autosavePeriod <= 0) {
return;

View file

@ -4,8 +4,10 @@ import com.google.common.collect.ImmutableMap;
import java.util.Map;
import net.minecraft.world.scores.ScoreboardObjective;
import net.minecraft.world.scores.criteria.IScoreboardCriteria;
import org.bukkit.scoreboard.Criteria;
import org.bukkit.scoreboard.RenderType;
final class CraftCriteria {
public final class CraftCriteria implements Criteria {
static final Map<String, CraftCriteria> DEFAULTS;
static final CraftCriteria DUMMY;
@ -36,16 +38,32 @@ final class CraftCriteria {
this.bukkitName = criteria.getName();
}
@Override
public String getName() {
return bukkitName;
}
@Override
public boolean isReadOnly() {
return criteria.isReadOnly();
}
@Override
public RenderType getDefaultRenderType() {
return RenderType.values()[criteria.getDefaultRenderType().ordinal()];
}
static CraftCriteria getFromNMS(ScoreboardObjective objective) {
return DEFAULTS.get(objective.getCriteria().getName());
}
static CraftCriteria getFromBukkit(String name) {
final CraftCriteria criteria = DEFAULTS.get(name);
public static CraftCriteria getFromBukkit(String name) {
CraftCriteria criteria = DEFAULTS.get(name);
if (criteria != null) {
return criteria;
}
return new CraftCriteria(name);
return IScoreboardCriteria.byName(name).map(CraftCriteria::new).orElseGet(() -> new CraftCriteria(name));
}
@Override

View file

@ -5,6 +5,7 @@ import net.minecraft.world.scores.ScoreboardObjective;
import org.apache.commons.lang.Validate;
import org.bukkit.OfflinePlayer;
import org.bukkit.craftbukkit.util.CraftChatMessage;
import org.bukkit.scoreboard.Criteria;
import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.RenderType;
@ -54,6 +55,13 @@ final class CraftObjective extends CraftScoreboardComponent implements Objective
return criteria.bukkitName;
}
@Override
public Criteria getTrackedCriteria() throws IllegalStateException {
CraftScoreboard scoreboard = checkState();
return criteria;
}
@Override
public boolean isModifiable() throws IllegalStateException {
CraftScoreboard scoreboard = checkState();

View file

@ -11,6 +11,7 @@ import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.craftbukkit.util.CraftChatMessage;
import org.bukkit.scoreboard.Criteria;
import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.RenderType;
@ -31,11 +32,21 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard {
@Override
public CraftObjective registerNewObjective(String name, String criteria, String displayName) throws IllegalArgumentException {
return registerNewObjective(name, criteria, displayName, RenderType.INTEGER);
return registerNewObjective(name, CraftCriteria.getFromBukkit(criteria), displayName, RenderType.INTEGER);
}
@Override
public CraftObjective registerNewObjective(String name, String criteria, String displayName, RenderType renderType) throws IllegalArgumentException {
return registerNewObjective(name, CraftCriteria.getFromBukkit(criteria), displayName, renderType);
}
@Override
public CraftObjective registerNewObjective(String name, Criteria criteria, String displayName) throws IllegalArgumentException {
return registerNewObjective(name, criteria, displayName, RenderType.INTEGER);
}
@Override
public CraftObjective registerNewObjective(String name, Criteria criteria, String displayName, RenderType renderType) throws IllegalArgumentException {
Validate.notNull(name, "Objective name cannot be null");
Validate.notNull(criteria, "Criteria cannot be null");
Validate.notNull(displayName, "Display name cannot be null");
@ -44,8 +55,7 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard {
Validate.isTrue(displayName.length() <= 128, "The display name '" + displayName + "' is longer than the limit of 128 characters");
Validate.isTrue(board.getObjective(name) == null, "An objective of name '" + name + "' already exists");
CraftCriteria craftCriteria = CraftCriteria.getFromBukkit(criteria);
ScoreboardObjective objective = board.addObjective(name, craftCriteria.criteria, CraftChatMessage.fromStringOrNull(displayName), CraftScoreboardTranslations.fromBukkitRender(renderType));
ScoreboardObjective objective = board.addObjective(name, ((CraftCriteria) criteria).criteria, CraftChatMessage.fromStringOrNull(displayName), CraftScoreboardTranslations.fromBukkitRender(renderType));
return new CraftObjective(this, objective);
}
@ -70,6 +80,21 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard {
return objectives.build();
}
@Override
public ImmutableSet<Objective> getObjectivesByCriteria(Criteria criteria) throws IllegalArgumentException {
Validate.notNull(criteria, "Criteria cannot be null");
ImmutableSet.Builder<Objective> objectives = ImmutableSet.builder();
for (ScoreboardObjective netObjective : board.getObjectives()) {
CraftObjective objective = new CraftObjective(this, netObjective);
if (objective.getTrackedCriteria().equals(criteria)) {
objectives.add(objective);
}
}
return objectives.build();
}
@Override
public ImmutableSet<Objective> getObjectives() {
return ImmutableSet.copyOf(Iterables.transform((Collection<ScoreboardObjective>) this.board.getObjectives(), new Function<ScoreboardObjective, Objective>() {

View file

@ -25,8 +25,8 @@ import org.bukkit.scoreboard.ScoreboardManager;
public final class CraftScoreboardManager implements ScoreboardManager {
private final CraftScoreboard mainScoreboard;
private final MinecraftServer server;
private final Collection<CraftScoreboard> scoreboards = new WeakCollection<CraftScoreboard>();
private final Map<CraftPlayer, CraftScoreboard> playerBoards = new HashMap<CraftPlayer, CraftScoreboard>();
private final Collection<CraftScoreboard> scoreboards = new WeakCollection<>();
private final Map<CraftPlayer, CraftScoreboard> playerBoards = new HashMap<>();
public CraftScoreboardManager(MinecraftServer minecraftserver, net.minecraft.world.scores.Scoreboard scoreboardServer) {
mainScoreboard = new CraftScoreboard(scoreboardServer);
@ -49,7 +49,7 @@ public final class CraftScoreboardManager implements ScoreboardManager {
// CraftBukkit method
public CraftScoreboard getPlayerBoard(CraftPlayer player) {
CraftScoreboard board = playerBoards.get(player);
return (CraftScoreboard) (board == null ? getMainScoreboard() : board);
return board == null ? getMainScoreboard() : board;
}
// CraftBukkit method
@ -68,11 +68,11 @@ public final class CraftScoreboardManager implements ScoreboardManager {
if (scoreboard == mainScoreboard) {
playerBoards.remove(player);
} else {
playerBoards.put(player, (CraftScoreboard) scoreboard);
playerBoards.put(player, scoreboard);
}
// Old objective tracking
HashSet<ScoreboardObjective> removed = new HashSet<ScoreboardObjective>();
HashSet<ScoreboardObjective> removed = new HashSet<>();
for (int i = 0; i < 3; ++i) {
ScoreboardObjective scoreboardobjective = oldboard.getDisplayObjective(i);
if (scoreboardobjective != null && !removed.contains(scoreboardobjective)) {

View file

@ -7,11 +7,28 @@ import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.RenderType;
final class CraftScoreboardTranslations {
static final int MAX_DISPLAY_SLOT = 3;
static ImmutableBiMap<DisplaySlot, String> SLOTS = ImmutableBiMap.of(
DisplaySlot.BELOW_NAME, "belowName",
DisplaySlot.PLAYER_LIST, "list",
DisplaySlot.SIDEBAR, "sidebar");
static final int MAX_DISPLAY_SLOT = 19;
static final ImmutableBiMap<DisplaySlot, String> SLOTS = ImmutableBiMap.<DisplaySlot, String>builder()
.put(DisplaySlot.BELOW_NAME, "belowName")
.put(DisplaySlot.PLAYER_LIST, "list")
.put(DisplaySlot.SIDEBAR, "sidebar")
.put(DisplaySlot.SIDEBAR_BLACK, "sidebar.team.black")
.put(DisplaySlot.SIDEBAR_DARK_BLUE, "sidebar.team.dark_blue")
.put(DisplaySlot.SIDEBAR_DARK_GREEN, "sidebar.team.dark_green")
.put(DisplaySlot.SIDEBAR_DARK_AQUA, "sidebar.team.dark_aqua")
.put(DisplaySlot.SIDEBAR_DARK_RED, "sidebar.team.dark_red")
.put(DisplaySlot.SIDEBAR_DARK_PURPLE, "sidebar.team.dark_purple")
.put(DisplaySlot.SIDEBAR_GOLD, "sidebar.team.gold")
.put(DisplaySlot.SIDEBAR_GRAY, "sidebar.team.gray")
.put(DisplaySlot.SIDEBAR_DARK_GRAY, "sidebar.team.dark_gray")
.put(DisplaySlot.SIDEBAR_BLUE, "sidebar.team.blue")
.put(DisplaySlot.SIDEBAR_GREEN, "sidebar.team.green")
.put(DisplaySlot.SIDEBAR_AQUA, "sidebar.team.aqua")
.put(DisplaySlot.SIDEBAR_RED, "sidebar.team.red")
.put(DisplaySlot.SIDEBAR_LIGHT_PURPLE, "sidebar.team.light_purple")
.put(DisplaySlot.SIDEBAR_YELLOW, "sidebar.team.yellow")
.put(DisplaySlot.SIDEBAR_WHITE, "sidebar.team.white")
.buildOrThrow();
private CraftScoreboardTranslations() {}