diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 7b9c78775..5baed2583 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -32,8 +32,6 @@ import net.minecraft.server.EnumGamemode; import net.minecraft.server.ExceptionWorldConflict; import net.minecraft.server.PlayerList; import net.minecraft.server.RecipesFurnace; -import net.minecraft.server.IProgressUpdate; -import net.minecraft.server.IWorldAccess; import net.minecraft.server.Item; import net.minecraft.server.MinecraftServer; import net.minecraft.server.MobEffectList; @@ -82,6 +80,7 @@ import org.bukkit.craftbukkit.metadata.PlayerMetadataStore; import org.bukkit.craftbukkit.metadata.WorldMetadataStore; import org.bukkit.craftbukkit.potion.CraftPotionBrewer; import org.bukkit.craftbukkit.scheduler.CraftScheduler; +import org.bukkit.craftbukkit.scoreboard.CraftScoreboardManager; import org.bukkit.craftbukkit.updater.AutoUpdater; import org.bukkit.craftbukkit.updater.BukkitDLUpdaterService; import org.bukkit.craftbukkit.util.DatFileFilter; @@ -162,6 +161,7 @@ public final class CraftServer implements Server { private File container; private WarningState warningState = WarningState.DEFAULT; private final BooleanWrapper online = new BooleanWrapper(); + public CraftScoreboardManager scoreboardManager; private final class BooleanWrapper { private boolean value = true; @@ -1358,4 +1358,8 @@ public final class CraftServer implements Server { public CraftItemFactory getItemFactory() { return CraftItemFactory.instance(); } + + public CraftScoreboardManager getScoreboardManager() { + return scoreboardManager; + } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index d37d719a8..a93625c40 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -24,7 +24,6 @@ import org.bukkit.*; import org.bukkit.Achievement; import org.bukkit.Material; import org.bukkit.Statistic; -import org.bukkit.WeatherType; import org.bukkit.World; import org.bukkit.configuration.serialization.DelegateDeserialization; import org.bukkit.conversations.Conversation; @@ -38,6 +37,7 @@ import org.bukkit.craftbukkit.CraftSound; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.map.CraftMapView; import org.bukkit.craftbukkit.map.RenderData; +import org.bukkit.craftbukkit.scoreboard.CraftScoreboard; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerGameModeChangeEvent; @@ -50,6 +50,7 @@ import org.bukkit.metadata.MetadataValue; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.messaging.Messenger; import org.bukkit.plugin.messaging.StandardMessenger; +import org.bukkit.scoreboard.Scoreboard; @DelegateDeserialization(CraftOfflinePlayer.class) public class CraftPlayer extends CraftHumanEntity implements Player { @@ -420,6 +421,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { server.getHandle().playerFileData.save(getHandle()); } + @Deprecated public void updateInventory() { getHandle().updateInventory(getHandle().activeContainer); } @@ -974,4 +976,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { super.resetMaxHealth(); getHandle().triggerHealthUpdate(); } + + public CraftScoreboard getScoreboard() { + return this.server.getScoreboardManager().getPlayerBoard(this); + } + + public void setScoreboard(Scoreboard scoreboard) { + Validate.notNull(scoreboard, "Scoreboard cannot be null"); + this.server.getScoreboardManager().setPlayerBoard(this, scoreboard); + } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftCriteria.java b/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftCriteria.java new file mode 100644 index 000000000..d2e30967d --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftCriteria.java @@ -0,0 +1,68 @@ +package org.bukkit.craftbukkit.scoreboard; + +import java.util.Map; + +import net.minecraft.server.IScoreboardCriteria; +import net.minecraft.server.ScoreboardObjective; + +import com.google.common.collect.ImmutableMap; + +final class CraftCriteria { + static final Map DEFAULTS; + static final CraftCriteria DUMMY; + + static { + ImmutableMap.Builder defaults = ImmutableMap.builder(); + + for (Map.Entry entry : ((Map ) IScoreboardCriteria.a).entrySet()) { + String name = entry.getKey().toString(); + IScoreboardCriteria criteria = (IScoreboardCriteria) entry.getValue(); + if (!criteria.getName().equals(name)) { + throw new AssertionError("Unexpected entry " + name + " to criteria " + criteria + "(" + criteria.getName() + ")"); + } + + defaults.put(name, new CraftCriteria(criteria)); + } + + DEFAULTS = defaults.build(); + DUMMY = DEFAULTS.get("dummy"); + } + + final IScoreboardCriteria criteria; + final String bukkitName; + + private CraftCriteria(String bukkitName) { + this.bukkitName = bukkitName; + this.criteria = DUMMY.criteria; + } + + private CraftCriteria(IScoreboardCriteria criteria) { + this.criteria = criteria; + this.bukkitName = criteria.getName(); + } + + static CraftCriteria getFromNMS(ScoreboardObjective objective) { + return DEFAULTS.get(objective.getCriteria().getName()); + } + + static CraftCriteria getFromBukkit(String name) { + final CraftCriteria criteria = DEFAULTS.get(name); + if (criteria != null) { + return criteria; + } + return new CraftCriteria(name); + } + + @Override + public boolean equals(Object that) { + if (!(that instanceof CraftCriteria)) { + return false; + } + return ((CraftCriteria) that).bukkitName.equals(this.bukkitName); + } + + @Override + public int hashCode() { + return this.bukkitName.hashCode() ^ CraftCriteria.class.hashCode(); + } +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java b/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java new file mode 100644 index 000000000..431807a80 --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java @@ -0,0 +1,104 @@ +package org.bukkit.craftbukkit.scoreboard; + +import net.minecraft.server.Scoreboard; +import net.minecraft.server.ScoreboardObjective; + +import org.apache.commons.lang.Validate; +import org.bukkit.OfflinePlayer; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Score; + +final class CraftObjective extends CraftScoreboardComponent implements Objective { + private final ScoreboardObjective objective; + private final CraftCriteria criteria; + + CraftObjective(CraftScoreboard scoreboard, ScoreboardObjective objective) { + super(scoreboard); + this.objective = objective; + this.criteria = CraftCriteria.getFromNMS(objective); + + scoreboard.objectives.put(objective.getName(), this); + } + + ScoreboardObjective getHandle() { + return objective; + } + + public String getName() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return objective.getName(); + } + + public String getDisplayName() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return objective.getDisplayName(); + } + + public void setDisplayName(String displayName) throws IllegalStateException, IllegalArgumentException { + Validate.notNull(displayName, "Display name cannot be null"); + Validate.isTrue(displayName.length() <= 32, "Display name '" + displayName + "' is longer than the limit of 32 characters"); + CraftScoreboard scoreboard = checkState(); + + objective.setDisplayName(displayName); + } + + public String getCriteria() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return criteria.bukkitName; + } + + public boolean isModifiable() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return !criteria.criteria.isReadOnly(); + } + + public void setDisplaySlot(DisplaySlot slot) throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + Scoreboard board = scoreboard.board; + ScoreboardObjective objective = this.objective; + + for (int i = 0; i < CraftScoreboardTranslations.MAX_DISPLAY_SLOT; i++) { + if (board.getObjectiveForSlot(i) == objective) { + board.setDisplaySlot(i, null); + } + } + if (slot != null) { + int slotNumber = CraftScoreboardTranslations.fromBukkitSlot(slot); + board.setDisplaySlot(slotNumber, getHandle()); + } + } + + public DisplaySlot getDisplaySlot() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + Scoreboard board = scoreboard.board; + ScoreboardObjective objective = this.objective; + + for (int i = 0; i < CraftScoreboardTranslations.MAX_DISPLAY_SLOT; i++) { + if (board.getObjectiveForSlot(i) == objective) { + return CraftScoreboardTranslations.toBukkitSlot(i); + } + } + return null; + } + + public Score getScore(OfflinePlayer player) throws IllegalArgumentException, IllegalStateException { + Validate.notNull(player, "Player cannot be null"); + CraftScoreboard scoreboard = checkState(); + + return new CraftScore(this, player.getName()); + } + + @Override + public void unregister() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + scoreboard.objectives.remove(this.getName()); + scoreboard.board.unregisterObjective(objective); + setUnregistered(); + } +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java b/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java new file mode 100644 index 000000000..0ffbe9b08 --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java @@ -0,0 +1,56 @@ +package org.bukkit.craftbukkit.scoreboard; + +import java.util.Map; + +import net.minecraft.server.Scoreboard; +import net.minecraft.server.ScoreboardScore; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Score; + +/** + * TL;DR: This class is special and lazily grabs a handle... + * ...because a handle is a full fledged (I think permanent) hashMap for the associated name. + *

+ * Also, as an added perk, a CraftScore will (intentionally) stay a valid reference so long as objective is valid. + */ +final class CraftScore implements Score { + private final String playerName; + private final CraftObjective objective; + + CraftScore(CraftObjective objective, String playerName) { + this.objective = objective; + this.playerName = playerName; + } + + public OfflinePlayer getPlayer() { + return Bukkit.getOfflinePlayer(playerName); + } + + public Objective getObjective() { + return objective; + } + + public int getScore() throws IllegalStateException { + Scoreboard board = objective.checkState().board; + + if (board.getPlayers().contains(playerName)) { // Lazy + Map scores = board.getPlayerObjectives(playerName); + ScoreboardScore score = scores.get(objective.getHandle()); + if (score != null) { // Lazy + return score.getScore(); + } + } + return 0; // Lazy + } + + public void setScore(int score) throws IllegalStateException { + objective.checkState().board.getPlayerScoreForObjective(playerName, objective.getHandle()).setScore(score); + } + + public CraftScoreboard getScoreboard() { + return objective.getScoreboard(); + } +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java b/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java new file mode 100644 index 000000000..63b808532 --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java @@ -0,0 +1,135 @@ +package org.bukkit.craftbukkit.scoreboard; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import net.minecraft.server.Scoreboard; +import net.minecraft.server.ScoreboardObjective; +import net.minecraft.server.ScoreboardTeam; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Score; +import org.bukkit.scoreboard.Team; + +import com.google.common.collect.ImmutableSet; + +public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard { + final Scoreboard board; + final Map objectives = new HashMap(); + final Map teams = new HashMap(); + + CraftScoreboard(Scoreboard board) { + this.board = board; + + for (ScoreboardObjective objective : (Iterable) board.getObjectives()) { + new CraftObjective(this, objective); // It adds itself to map + } + for (ScoreboardTeam team : (Iterable) board.getTeams()) { + new CraftTeam(this, team); // It adds itself to map + } + } + + public CraftObjective registerNewObjective(String name, String criteria) throws IllegalArgumentException { + Validate.notNull(name, "Objective name cannot be null"); + Validate.notNull(criteria, "Criteria cannot be null"); + Validate.isTrue(name.length() <= 16, "The name '" + name + "' is longer than the limit of 16 characters"); + Validate.isTrue(board.getObjective(name) == null, "An objective of name '" + name + "' already exists"); + + CraftCriteria craftCriteria = CraftCriteria.getFromBukkit(criteria); + ScoreboardObjective objective = board.registerObjective(name, craftCriteria.criteria); + return new CraftObjective(this, objective); + } + + public Objective getObjective(String name) throws IllegalArgumentException { + Validate.notNull(name, "Name cannot be null"); + return objectives.get(name); + } + + public ImmutableSet getObjectivesByCriteria(String criteria) throws IllegalArgumentException { + Validate.notNull(criteria, "Criteria cannot be null"); + + ImmutableSet.Builder objectives = ImmutableSet.builder(); + for (CraftObjective objective : this.objectives.values()) { + if (objective.getCriteria().equals(criteria)) { + objectives.add(objective); + } + } + return objectives.build(); + } + + public ImmutableSet getObjectives() { + return ImmutableSet.copyOf((Collection) objectives.values()); + } + + public Objective getObjective(DisplaySlot slot) throws IllegalArgumentException { + Validate.notNull(slot, "Display slot cannot be null"); + ScoreboardObjective objective = board.getObjectiveForSlot(CraftScoreboardTranslations.fromBukkitSlot(slot)); + if (objective == null) { + return null; + } + return this.objectives.get(objective.getName()); + } + + public ImmutableSet getScores(OfflinePlayer player) throws IllegalArgumentException { + Validate.notNull(player, "OfflinePlayer cannot be null"); + + ImmutableSet.Builder scores = ImmutableSet.builder(); + for (CraftObjective objective : objectives.values()) { + scores.add(objective.getScore(player)); + } + return scores.build(); + } + + public void resetScores(OfflinePlayer player) throws IllegalArgumentException { + Validate.notNull(player, "OfflinePlayer cannot be null"); + + board.resetPlayerScores(player.getName()); + } + + public Team getPlayerTeam(OfflinePlayer player) throws IllegalArgumentException { + Validate.notNull(player, "OfflinePlayer cannot be null"); + + ScoreboardTeam team = board.getTeam(player.getName()); + return team == null ? null : teams.get(team.getName()); + } + + public Team getTeam(String teamName) throws IllegalArgumentException { + Validate.notNull(teamName, "Team name cannot be null"); + + return teams.get(teamName); + } + + public ImmutableSet getTeams() { + return ImmutableSet.copyOf((Collection) teams.values()); + } + + public Team registerNewTeam(String name) throws IllegalArgumentException { + Validate.notNull(name, "Team name cannot be null"); + Validate.isTrue(name.length() <= 16, "Team name '" + name + "' is longer than the limit of 16 characters"); + Validate.isTrue(board.getTeam(name) == null, "Team name '" + name + "' is already in use"); + + return new CraftTeam(this, board.createTeam(name)); + } + + public ImmutableSet getPlayers() { + ImmutableSet.Builder players = ImmutableSet.builder(); + for (Object playerName : board.getPlayers()) { + players.add(Bukkit.getOfflinePlayer(playerName.toString())); + } + return players.build(); + } + + public void clearSlot(DisplaySlot slot) throws IllegalArgumentException { + Validate.notNull(slot, "Slot cannot be null"); + board.setDisplaySlot(CraftScoreboardTranslations.fromBukkitSlot(slot), null); + } + + // CraftBukkit method + public Scoreboard getHandle() { + return board; + } +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardComponent.java b/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardComponent.java new file mode 100644 index 000000000..3855a2b79 --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardComponent.java @@ -0,0 +1,27 @@ +package org.bukkit.craftbukkit.scoreboard; + +abstract class CraftScoreboardComponent { + private CraftScoreboard scoreboard; + + CraftScoreboardComponent(CraftScoreboard scoreboard) { + this.scoreboard = scoreboard; + } + + CraftScoreboard checkState() throws IllegalStateException { + CraftScoreboard scoreboard = this.scoreboard; + if (scoreboard == null) { + throw new IllegalStateException("Unregistered scoreboard component"); + } + return scoreboard; + } + + public CraftScoreboard getScoreboard() { + return scoreboard; + } + + abstract void unregister() throws IllegalStateException; + + final void setUnregistered() { + scoreboard = null; + } +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java b/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java new file mode 100644 index 000000000..c435e3a0e --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java @@ -0,0 +1,118 @@ +package org.bukkit.craftbukkit.scoreboard; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import net.minecraft.server.EntityPlayer; +import net.minecraft.server.IScoreboardCriteria; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.Packet206SetScoreboardObjective; +import net.minecraft.server.Packet209SetScoreboardTeam; +import net.minecraft.server.Scoreboard; +import net.minecraft.server.ScoreboardObjective; +import net.minecraft.server.ScoreboardScore; +import net.minecraft.server.ScoreboardServer; +import net.minecraft.server.ScoreboardTeam; + +import org.apache.commons.lang.Validate; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.util.WeakCollection; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.ScoreboardManager; + +public final class CraftScoreboardManager implements ScoreboardManager { + private final CraftScoreboard mainScoreboard; + private final MinecraftServer server; + private final Collection scoreboards = new WeakCollection(); + private final Map playerBoards = new HashMap(); + + public CraftScoreboardManager(MinecraftServer minecraftserver, net.minecraft.server.Scoreboard scoreboardServer) { + mainScoreboard = new CraftScoreboard(scoreboardServer); + server = minecraftserver; + scoreboards.add(mainScoreboard); + } + + public CraftScoreboard getMainScoreboard() { + return mainScoreboard; + } + + public CraftScoreboard getNewScoreboard() { + CraftScoreboard scoreboard = new CraftScoreboard(new ScoreboardServer(server)); + scoreboards.add(scoreboard); + return scoreboard; + } + + // CraftBukkit method + public CraftScoreboard getPlayerBoard(CraftPlayer player) { + CraftScoreboard board = playerBoards.get(player); + return (CraftScoreboard) (board == null ? getMainScoreboard() : board); + } + + // CraftBukkit method + public void setPlayerBoard(CraftPlayer player, org.bukkit.scoreboard.Scoreboard bukkitScoreboard) throws IllegalArgumentException { + Validate.isTrue(bukkitScoreboard instanceof CraftScoreboard, "Cannot set player scoreboard to an unregistered Scoreboard"); + + CraftScoreboard scoreboard = (CraftScoreboard) bukkitScoreboard; + net.minecraft.server.Scoreboard oldboard = getPlayerBoard(player).getHandle(); + net.minecraft.server.Scoreboard newboard = scoreboard.getHandle(); + EntityPlayer entityplayer = player.getHandle(); + + if (oldboard == newboard) { + return; + } + + if (scoreboard == mainScoreboard) { + playerBoards.remove(player); + } else { + playerBoards.put(player, (CraftScoreboard) scoreboard); + } + + // Old objective tracking + HashSet removed = new HashSet(); + for (int i = 0; i < 3; ++i) { + ScoreboardObjective scoreboardobjective = oldboard.getObjectiveForSlot(i); + if (scoreboardobjective != null && !removed.contains(scoreboardobjective)) { + entityplayer.playerConnection.sendPacket(new Packet206SetScoreboardObjective(scoreboardobjective, 1)); + removed.add(scoreboardobjective); + } + } + + // Old team tracking + Iterator iterator = oldboard.getTeams().iterator(); + while (iterator.hasNext()) { + ScoreboardTeam scoreboardteam = (ScoreboardTeam) iterator.next(); + entityplayer.playerConnection.sendPacket(new Packet209SetScoreboardTeam(scoreboardteam, 1)); + } + + // The above is the reverse of the below method. + server.getPlayerList().a((ScoreboardServer) newboard, player.getHandle()); + } + + // CraftBukkit method + public void removePlayer(Player player) { + playerBoards.remove(player); + } + + // CraftBukkit method + public Collection getScoreboardScores(IScoreboardCriteria criteria, String name, Collection collection) { + for (CraftScoreboard scoreboard : scoreboards) { + Scoreboard board = scoreboard.board; + for (ScoreboardObjective objective : (Iterable) board.getObjectivesForCriteria(criteria)) { + collection.add(board.getPlayerScoreForObjective(name, objective)); + } + } + return collection; + } + + // CraftBukkit method + public void updateAllScoresForList(IScoreboardCriteria criteria, String name, List of) { + for (ScoreboardScore score : getScoreboardScores(criteria, name, new ArrayList())) { + score.updateForList(of); + } + } +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java b/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java new file mode 100644 index 000000000..d08e5a281 --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java @@ -0,0 +1,26 @@ +package org.bukkit.craftbukkit.scoreboard; + +import net.minecraft.server.Scoreboard; + +import org.bukkit.scoreboard.DisplaySlot; + +import com.google.common.collect.ImmutableBiMap; + +class CraftScoreboardTranslations { + static final int MAX_DISPLAY_SLOT = 3; + static ImmutableBiMap SLOTS = ImmutableBiMap.of( + DisplaySlot.BELOW_NAME, "belowName", + DisplaySlot.PLAYER_LIST, "list", + DisplaySlot.SIDEBAR, "sidebar"); + + private CraftScoreboardTranslations() {} + + static DisplaySlot toBukkitSlot(int i) { + return SLOTS.inverse().get(Scoreboard.getSlotName(i)); + } + + static int fromBukkitSlot(DisplaySlot slot) { + return Scoreboard.getSlotForName(SLOTS.get(slot)); + } + +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java b/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java new file mode 100644 index 000000000..03a320782 --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java @@ -0,0 +1,145 @@ +package org.bukkit.craftbukkit.scoreboard; + +import java.util.Set; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.scoreboard.Team; + +import com.google.common.collect.ImmutableSet; + +import net.minecraft.server.ScoreboardTeam; + +final class CraftTeam extends CraftScoreboardComponent implements Team { + private final ScoreboardTeam team; + + CraftTeam(CraftScoreboard scoreboard, ScoreboardTeam team) { + super(scoreboard); + this.team = team; + scoreboard.teams.put(team.getName(), this); + } + + public String getName() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return team.getName(); + } + + public String getDisplayName() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return team.getDisplayName(); + } + + public void setDisplayName(String displayName) throws IllegalStateException { + Validate.notNull(displayName, "Display name cannot be null"); + Validate.isTrue(displayName.length() <= 32, "Display name '" + displayName + "' is longer than the limit of 32 characters"); + CraftScoreboard scoreboard = checkState(); + + team.setDisplayName(displayName); + } + + public String getPrefix() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return team.getPrefix(); + } + + public void setPrefix(String prefix) throws IllegalStateException, IllegalArgumentException { + Validate.notNull(prefix, "Prefix cannot be null"); + Validate.isTrue(prefix.length() <= 32, "Prefix '" + prefix + "' is longer than the limit of 32 characters"); + CraftScoreboard scoreboard = checkState(); + + team.setPrefix(prefix); + } + + public String getSuffix() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return team.getSuffix(); + } + + public void setSuffix(String suffix) throws IllegalStateException, IllegalArgumentException { + Validate.notNull(suffix, "Suffix cannot be null"); + Validate.isTrue(suffix.length() <= 32, "Suffix '" + suffix + "' is longer than the limit of 32 characters"); + CraftScoreboard scoreboard = checkState(); + + team.setSuffix(suffix); + } + + public boolean allowFriendlyFire() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return team.allowFriendlyFire(); + } + + public void setAllowFriendlyFire(boolean enabled) throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + team.setAllowFriendlyFire(enabled); + } + + public boolean canSeeFriendlyInvisibles() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return team.canSeeFriendlyInvisibles(); + } + + public void setCanSeeFriendlyInvisibles(boolean enabled) throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + team.setCanSeeFriendlyInvisibles(enabled); + } + + public Set getPlayers() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + ImmutableSet.Builder players = ImmutableSet.builder(); + for (Object o : team.getPlayerNameSet()) { + players.add(Bukkit.getOfflinePlayer(o.toString())); + } + return players.build(); + } + + public int getSize() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return team.getPlayerNameSet().size(); + } + + public void addPlayer(OfflinePlayer player) throws IllegalStateException, IllegalArgumentException { + Validate.notNull(player, "OfflinePlayer cannot be null"); + CraftScoreboard scoreboard = checkState(); + + scoreboard.board.addPlayerToTeam(player.getName(), team); + } + + public boolean removePlayer(OfflinePlayer player) throws IllegalStateException, IllegalArgumentException { + Validate.notNull(player, "OfflinePlayer cannot be null"); + CraftScoreboard scoreboard = checkState(); + + if (!team.getPlayerNameSet().contains(player.getName())) { + return false; + } + + scoreboard.board.removePlayerFromTeam(player.getName(), team); + return true; + } + + public boolean hasPlayer(OfflinePlayer player) throws IllegalArgumentException, IllegalStateException { + Validate.notNull(player, "OfflinePlayer cannot be null"); + CraftScoreboard scoreboard = checkState(); + + return team.getPlayerNameSet().contains(player.getName()); + } + + @Override + public void unregister() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + scoreboard.board.removeTeam(team); + scoreboard.teams.remove(team.getName()); + setUnregistered(); + } +}