3
0
Mirror von https://github.com/PaperMC/Paper.git synchronisiert 2024-12-18 20:40:08 +01:00

SPIGOT-242: Fix scoreboard API.

In particular don't maintain an internal list of state, as this gets out of whack when Minecraft adds or removes scoreboards / teams.
Dieser Commit ist enthalten in:
md_5 2015-01-17 09:41:52 +11:00
Ursprung 8047b0a131
Commit 42ebec1f71
5 geänderte Dateien mit 50 neuen und 50 gelöschten Zeilen

Datei anzeigen

@ -17,8 +17,6 @@ final class CraftObjective extends CraftScoreboardComponent implements Objective
super(scoreboard); super(scoreboard);
this.objective = objective; this.objective = objective;
this.criteria = CraftCriteria.getFromNMS(objective); this.criteria = CraftCriteria.getFromNMS(objective);
scoreboard.objectives.put(objective.getName(), this);
} }
ScoreboardObjective getHandle() { ScoreboardObjective getHandle() {
@ -104,8 +102,15 @@ final class CraftObjective extends CraftScoreboardComponent implements Objective
public void unregister() throws IllegalStateException { public void unregister() throws IllegalStateException {
CraftScoreboard scoreboard = checkState(); CraftScoreboard scoreboard = checkState();
scoreboard.objectives.remove(this.getName());
scoreboard.board.unregisterObjective(objective); scoreboard.board.unregisterObjective(objective);
setUnregistered(); }
@Override
CraftScoreboard checkState() throws IllegalStateException {
if (getScoreboard().board.getObjective(objective.getName()) == null) {
throw new IllegalStateException("Unregistered scoreboard component");
}
return getScoreboard();
} }
} }

Datei anzeigen

@ -3,6 +3,7 @@ package org.bukkit.craftbukkit.scoreboard;
import java.util.Map; import java.util.Map;
import net.minecraft.server.Scoreboard; import net.minecraft.server.Scoreboard;
import net.minecraft.server.ScoreboardObjective;
import net.minecraft.server.ScoreboardScore; import net.minecraft.server.ScoreboardScore;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -41,7 +42,7 @@ final class CraftScore implements Score {
Scoreboard board = objective.checkState().board; Scoreboard board = objective.checkState().board;
if (board.getPlayers().contains(entry)) { // Lazy if (board.getPlayers().contains(entry)) { // Lazy
Map<String, ScoreboardScore> scores = board.getPlayerObjectives(entry); Map<ScoreboardObjective, ScoreboardScore> scores = board.getPlayerObjectives(entry);
ScoreboardScore score = scores.get(objective.getHandle()); ScoreboardScore score = scores.get(objective.getHandle());
if (score != null) { // Lazy if (score != null) { // Lazy
return score.getScore(); return score.getScore();

Datei anzeigen

@ -1,8 +1,6 @@
package org.bukkit.craftbukkit.scoreboard; package org.bukkit.craftbukkit.scoreboard;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import net.minecraft.server.Scoreboard; import net.minecraft.server.Scoreboard;
import net.minecraft.server.ScoreboardObjective; import net.minecraft.server.ScoreboardObjective;
import net.minecraft.server.ScoreboardTeam; import net.minecraft.server.ScoreboardTeam;
@ -15,22 +13,15 @@ import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.Score; import org.bukkit.scoreboard.Score;
import org.bukkit.scoreboard.Team; import org.bukkit.scoreboard.Team;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard { public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard {
final Scoreboard board; final Scoreboard board;
final Map<String, CraftObjective> objectives = new HashMap<String, CraftObjective>();
final Map<String, CraftTeam> teams = new HashMap<String, CraftTeam>();
CraftScoreboard(Scoreboard board) { CraftScoreboard(Scoreboard board) {
this.board = board; this.board = board;
for (ScoreboardObjective objective : (Iterable<ScoreboardObjective>) board.getObjectives()) {
new CraftObjective(this, objective); // It adds itself to map
}
for (ScoreboardTeam team : (Iterable<ScoreboardTeam>) board.getTeams()) {
new CraftTeam(this, team); // It adds itself to map
}
} }
public CraftObjective registerNewObjective(String name, String criteria) throws IllegalArgumentException { public CraftObjective registerNewObjective(String name, String criteria) throws IllegalArgumentException {
@ -46,14 +37,15 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard {
public Objective getObjective(String name) throws IllegalArgumentException { public Objective getObjective(String name) throws IllegalArgumentException {
Validate.notNull(name, "Name cannot be null"); Validate.notNull(name, "Name cannot be null");
return objectives.get(name); return new CraftObjective(this, board.getObjective(name));
} }
public ImmutableSet<Objective> getObjectivesByCriteria(String criteria) throws IllegalArgumentException { public ImmutableSet<Objective> getObjectivesByCriteria(String criteria) throws IllegalArgumentException {
Validate.notNull(criteria, "Criteria cannot be null"); Validate.notNull(criteria, "Criteria cannot be null");
ImmutableSet.Builder<Objective> objectives = ImmutableSet.builder(); ImmutableSet.Builder<Objective> objectives = ImmutableSet.builder();
for (CraftObjective objective : this.objectives.values()) { for (ScoreboardObjective netObjective : (Collection<ScoreboardObjective>) this.board.getObjectives()) {
CraftObjective objective = new CraftObjective(this, netObjective);
if (objective.getCriteria().equals(criteria)) { if (objective.getCriteria().equals(criteria)) {
objectives.add(objective); objectives.add(objective);
} }
@ -62,7 +54,13 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard {
} }
public ImmutableSet<Objective> getObjectives() { public ImmutableSet<Objective> getObjectives() {
return ImmutableSet.copyOf((Collection<? extends Objective>) objectives.values()); return ImmutableSet.copyOf(Iterables.transform((Collection<ScoreboardObjective>) this.board.getObjectives(), new Function<ScoreboardObjective, Objective>() {
@Override
public Objective apply(ScoreboardObjective input) {
return new CraftObjective(CraftScoreboard.this, input);
}
}));
} }
public Objective getObjective(DisplaySlot slot) throws IllegalArgumentException { public Objective getObjective(DisplaySlot slot) throws IllegalArgumentException {
@ -71,25 +69,21 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard {
if (objective == null) { if (objective == null) {
return null; return null;
} }
return this.objectives.get(objective.getName()); return new CraftObjective(this, objective);
} }
public ImmutableSet<Score> getScores(OfflinePlayer player) throws IllegalArgumentException { public ImmutableSet<Score> getScores(OfflinePlayer player) throws IllegalArgumentException {
Validate.notNull(player, "OfflinePlayer cannot be null"); Validate.notNull(player, "OfflinePlayer cannot be null");
ImmutableSet.Builder<Score> scores = ImmutableSet.builder(); return getScores(player.getName());
for (CraftObjective objective : objectives.values()) {
scores.add(objective.getScore(player));
}
return scores.build();
} }
public ImmutableSet<Score> getScores(String entry) throws IllegalArgumentException { public ImmutableSet<Score> getScores(String entry) throws IllegalArgumentException {
Validate.notNull(entry, "Entry cannot be null"); Validate.notNull(entry, "Entry cannot be null");
ImmutableSet.Builder<Score> scores = ImmutableSet.builder(); ImmutableSet.Builder<Score> scores = ImmutableSet.builder();
for (CraftObjective objective : objectives.values()) { for (ScoreboardObjective objective : (Collection<ScoreboardObjective>) this.board.getObjectives()) {
scores.add(objective.getScore(entry)); scores.add(new CraftScore(new CraftObjective(this, objective), entry));
} }
return scores.build(); return scores.build();
} }
@ -97,34 +91,38 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard {
public void resetScores(OfflinePlayer player) throws IllegalArgumentException { public void resetScores(OfflinePlayer player) throws IllegalArgumentException {
Validate.notNull(player, "OfflinePlayer cannot be null"); Validate.notNull(player, "OfflinePlayer cannot be null");
for (CraftObjective objective : objectives.values()) { resetScores(player.getName());
board.resetPlayerScores(player.getName(), objective.getHandle());
}
} }
public void resetScores(String entry) throws IllegalArgumentException { public void resetScores(String entry) throws IllegalArgumentException {
Validate.notNull(entry, "Entry cannot be null"); Validate.notNull(entry, "Entry cannot be null");
for (CraftObjective objective : objectives.values()) { for (ScoreboardObjective objective : (Collection<ScoreboardObjective>) this.board.getObjectives()) {
board.resetPlayerScores(entry, objective.getHandle()); board.resetPlayerScores(entry, objective);
} }
} }
public Team getPlayerTeam(OfflinePlayer player) throws IllegalArgumentException { public Team getPlayerTeam(OfflinePlayer player) throws IllegalArgumentException {
Validate.notNull(player, "OfflinePlayer cannot be null"); Validate.notNull(player, "OfflinePlayer cannot be null");
ScoreboardTeam team = board.getPlayerTeam(player.getName()); return getTeam(player.getName());
return team == null ? null : teams.get(team.getName());
} }
public Team getTeam(String teamName) throws IllegalArgumentException { public Team getTeam(String teamName) throws IllegalArgumentException {
Validate.notNull(teamName, "Team name cannot be null"); Validate.notNull(teamName, "Team name cannot be null");
return teams.get(teamName); ScoreboardTeam team = board.getPlayerTeam(teamName);
return team == null ? null : new CraftTeam(this, team);
} }
public ImmutableSet<Team> getTeams() { public ImmutableSet<Team> getTeams() {
return ImmutableSet.copyOf((Collection<? extends Team>) teams.values()); return ImmutableSet.copyOf(Iterables.transform((Collection<ScoreboardTeam>) this.board.getTeams(), new Function<ScoreboardTeam, Team>() {
@Override
public Team apply(ScoreboardTeam input) {
return new CraftTeam(CraftScoreboard.this, input);
}
}));
} }
public Team registerNewTeam(String name) throws IllegalArgumentException { public Team registerNewTeam(String name) throws IllegalArgumentException {

Datei anzeigen

@ -7,21 +7,11 @@ abstract class CraftScoreboardComponent {
this.scoreboard = scoreboard; this.scoreboard = scoreboard;
} }
CraftScoreboard checkState() throws IllegalStateException { abstract CraftScoreboard checkState() throws IllegalStateException;
CraftScoreboard scoreboard = this.scoreboard;
if (scoreboard == null) {
throw new IllegalStateException("Unregistered scoreboard component");
}
return scoreboard;
}
public CraftScoreboard getScoreboard() { public CraftScoreboard getScoreboard() {
return scoreboard; return scoreboard;
} }
abstract void unregister() throws IllegalStateException; abstract void unregister() throws IllegalStateException;
final void setUnregistered() {
scoreboard = null;
}
} }

Datei anzeigen

@ -19,7 +19,6 @@ final class CraftTeam extends CraftScoreboardComponent implements Team {
CraftTeam(CraftScoreboard scoreboard, ScoreboardTeam team) { CraftTeam(CraftScoreboard scoreboard, ScoreboardTeam team) {
super(scoreboard); super(scoreboard);
this.team = team; this.team = team;
scoreboard.teams.put(team.getName(), this);
} }
public String getName() throws IllegalStateException { public String getName() throws IllegalStateException {
@ -155,8 +154,6 @@ final class CraftTeam extends CraftScoreboardComponent implements Team {
CraftScoreboard scoreboard = checkState(); CraftScoreboard scoreboard = checkState();
scoreboard.board.removeTeam(team); scoreboard.board.removeTeam(team);
scoreboard.teams.remove(team.getName());
setUnregistered();
} }
public static EnumNameTagVisibility bukkitToNotch(NameTagVisibility visibility) { public static EnumNameTagVisibility bukkitToNotch(NameTagVisibility visibility) {
@ -188,4 +185,13 @@ final class CraftTeam extends CraftScoreboardComponent implements Team {
throw new IllegalArgumentException("Unknown visibility level " + visibility); throw new IllegalArgumentException("Unknown visibility level " + visibility);
} }
} }
@Override
CraftScoreboard checkState() throws IllegalStateException {
if (getScoreboard().board.getTeam(team.getName()) == null) {
throw new IllegalStateException("Unregistered scoreboard component");
}
return getScoreboard();
}
} }