Skip to content

Commit

Permalink
Add Scoreboard API and Command. Adds BUKKIT-3776, BUKKIT-3834
Browse files Browse the repository at this point in the history
The implementation is designed around having both a main scoreboard and
numberous plugin managed scoreboards that can be displayed to specific
players.

Plugin managed scoreboards are active so long as a reference is kept by a
plugin, or it has been registered as a player's active scoreboard. Objects
specific to a scoreboard remain active until unregistered (which remove a
reference to the owning scoreboard), but quickly fail if accessed
post-unregistration.
  • Loading branch information
mbax authored and Wolvereness committed Apr 4, 2013
1 parent faa386a commit 6fb1647
Show file tree
Hide file tree
Showing 13 changed files with 1,171 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/main/java/org/bukkit/Bukkit.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.bukkit.plugin.ServicesManager;
import org.bukkit.plugin.messaging.Messenger;
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scoreboard.ScoreboardManager;

import com.avaje.ebean.config.ServerConfig;
import org.bukkit.inventory.ItemFactory;
Expand Down Expand Up @@ -395,4 +396,8 @@ public static WarningState getWarningState() {
public static ItemFactory getItemFactory() {
return server.getItemFactory();
}

public static ScoreboardManager getScoreboardManager() {
return server.getScoreboardManager();
}
}
10 changes: 10 additions & 0 deletions src/main/java/org/bukkit/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.bukkit.plugin.messaging.Messenger;
import org.bukkit.plugin.messaging.PluginMessageRecipient;
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scoreboard.ScoreboardManager;

import com.avaje.ebean.config.ServerConfig;
import org.bukkit.inventory.ItemFactory;
Expand Down Expand Up @@ -689,4 +690,13 @@ public interface Server extends PluginMessageRecipient {
* @see ItemFactory
*/
ItemFactory getItemFactory();

/**
* Gets the instance of the scoreboard manager.
* <p>
* This will only exist after the first world has loaded.
*
* @return the scoreboard manager or null if no worlds are loaded.
*/
ScoreboardManager getScoreboardManager();
}
1 change: 1 addition & 0 deletions src/main/java/org/bukkit/command/SimpleCommandMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public class SimpleCommandMap implements CommandMap {
fallbackCommands.add(new EnchantCommand());
fallbackCommands.add(new TestForCommand());
fallbackCommands.add(new EffectCommand());
fallbackCommands.add(new ScoreboardCommand());
}

public SimpleCommandMap(final Server server) {
Expand Down
627 changes: 627 additions & 0 deletions src/main/java/org/bukkit/command/defaults/ScoreboardCommand.java

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions src/main/java/org/bukkit/entity/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.bukkit.conversations.Conversable;
import org.bukkit.map.MapView;
import org.bukkit.plugin.messaging.PluginMessageRecipient;
import org.bukkit.scoreboard.Scoreboard;

/**
* Represents a player, connected or not
Expand Down Expand Up @@ -626,4 +627,19 @@ public interface Player extends HumanEntity, Conversable, CommandSender, Offline
* @throws IllegalArgumentException Thrown if the URL is too long.
*/
public void setTexturePack(String url);

/**
* Gets the Scoreboard displayed to this player
*
* @return The current scoreboard seen by this player
*/
public Scoreboard getScoreboard();

/**
* Sets the player's visible Scoreboard
* Scoreboard must be currently registered or an IllegalArgumentException is thrown
*
* @param scoreboard New Scoreboard for the player
*/
public void setScoreboard(Scoreboard scoreboard);
}
20 changes: 20 additions & 0 deletions src/main/java/org/bukkit/scoreboard/Criterias.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.bukkit.scoreboard;

/**
* Criteria names which trigger an objective to be modified by actions in-game
*/
public class Criterias {
public static final String HEALTH;
public static final String PLAYER_KILLS;
public static final String TOTAL_KILLS;
public static final String DEATHS;

static {
HEALTH="health";
PLAYER_KILLS="playerKillCount";
TOTAL_KILLS="totalKillCount";
DEATHS="deathCount";
}

private Criterias() {}
}
10 changes: 10 additions & 0 deletions src/main/java/org/bukkit/scoreboard/DisplaySlot.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.bukkit.scoreboard;

/**
* Locations for displaying objectives to the player
*/
public enum DisplaySlot {
BELOW_NAME,
PLAYER_LIST,
SIDEBAR;
}
98 changes: 98 additions & 0 deletions src/main/java/org/bukkit/scoreboard/Objective.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package org.bukkit.scoreboard;

import org.bukkit.OfflinePlayer;

/**
* An objective on a scoreboard that can show scores specific to players. This
* objective is only relevant to the display of the associated {@link
* #getScoreboard() scoreboard}.
*/
public interface Objective {

/**
* Gets the name of this Objective
*
* @return this objective'ss name
* @throws IllegalStateException if this objective has been unregistered
*/
String getName() throws IllegalStateException;

/**
* Gets the name displayed to players for this objective
*
* @return this objective's display name
* @throws IllegalStateException if this objective has been unregistered
*/
String getDisplayName() throws IllegalStateException;

/**
* Sets the name displayed to players for this objective.
*
* @param displayName Display name to set
* @throws IllegalStateException if this objective has been unregistered
* @throws IllegalArgumentException if displayName is null
* @throws IllegalArgumentException if displayName is longer than 32
* characters.
*/
void setDisplayName(String displayName) throws IllegalStateException, IllegalArgumentException;

/**
* Gets the criteria this objective tracks.
*
* @return this objective's criteria
* @throws IllegalStateException if this objective has been unregistered
*/
String getCriteria() throws IllegalStateException;

/**
* Gets if the objective's scores can be modified directly by a plugin.
*
* @return true if scores are modifiable
* @throws IllegalStateException if this objective has been unregistered
* @see Criterias#HEALTH
*/
boolean isModifiable() throws IllegalStateException;

/**
* Gets the scoreboard to which this objective is attached.
*
* @return Owning scoreboard, or null if it has been {@link #unregister()
* unregistered}
*/
Scoreboard getScoreboard();

/**
* Unregisters this objective from the {@link Scoreboard scoreboard.}
*
* @throws IllegalStateException if this objective has been unregistered
*/
void unregister() throws IllegalStateException;

/**
* Sets this objective to display on the specified slot for the
* scoreboard, removing it from any other display slot.
*
* @param slot display slot to change, or null to not display
* @throws IllegalStateException if this objective has been unregistered
*/
void setDisplaySlot(DisplaySlot slot) throws IllegalStateException;

/**
* Gets the display slot this objective is displayed at.
*
* @return the display slot for this objective, or null if not displayed
* @throws IllegalStateException if this objective has been unregistered
*/
DisplaySlot getDisplaySlot() throws IllegalStateException;

/**
* Gets a player's Score for an Objective on this Scoreboard
*
* @param objective Objective for the Score
* @param player Player for the Score
* @return Score tracking the Objective and player specified
* @throws IllegalArgumentException if player is null
* @throws IllegalStateException if this objective has been unregistered
*/
Score getScore(OfflinePlayer player) throws IllegalArgumentException, IllegalStateException;
}
51 changes: 51 additions & 0 deletions src/main/java/org/bukkit/scoreboard/Score.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.bukkit.scoreboard;

import org.bukkit.OfflinePlayer;

/**
* A score entry for a {@link #getPlayer() player} on an {@link
* #getObjective() objective}. Changing this will not affect any other
* objective or scoreboard.
*/
public interface Score {

/**
* Gets the OfflinePlayer being tracked by this Score
*
* @return this Score's tracked player
*/
OfflinePlayer getPlayer();

/**
* Gets the Objective being tracked by this Score
*
* @return this Score's tracked objective
*/
Objective getObjective();

/**
* Gets the current score
*
* @return the current score
* @throws IllegalStateException if the associated objective has been
* unregistered
*/
int getScore() throws IllegalStateException;

/**
* Sets the current score.
*
* @param score New score
* @throws IllegalStateException if the associated objective has been
* unregistered
*/
void setScore(int score) throws IllegalStateException;

/**
* Gets the scoreboard for the associated objective.
*
* @return the owning objective's scoreboard, or null if it has been
* {@link Objective#unregister() unregistered}
*/
Scoreboard getScoreboard();
}
123 changes: 123 additions & 0 deletions src/main/java/org/bukkit/scoreboard/Scoreboard.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package org.bukkit.scoreboard;

import java.util.Set;

import org.bukkit.OfflinePlayer;

/**
* A scoreboard
*/
public interface Scoreboard {

/**
* Registers an Objective on this Scoreboard
*
* @param name Name of the Objective
* @param criteria Criteria for the Objective
* @return The registered Objective
* @throws IllegalArgumentException if name is null
* @throws IllegalArgumentException if criteria is null
* @throws IllegalArgumentException if an objective by that name already exists
*/
Objective registerNewObjective(String name, String criteria) throws IllegalArgumentException;

/**
* Gets an Objective on this Scoreboard by name
*
* @param name Name of the Objective
* @return the Objective or null if it does not exist
* @throws IllegalArgumentException if name is null
*/
Objective getObjective(String name) throws IllegalArgumentException;

/**
* Gets all Objectives of a Criteria on the Scoreboard
*
* @param criteria Criteria to search by
* @return an immutable set of Objectives using the specified Criteria
*/
Set<Objective> getObjectivesByCriteria(String criteria) throws IllegalArgumentException;

/**
* Gets all Objectives on this Scoreboard
*
* @return An immutable set of all Objectives on this Scoreboard
*/
Set<Objective> getObjectives();

/**
* Gets the Objective currently displayed in a DisplaySlot on this Scoreboard
*
* @param slot The DisplaySlot
* @return the Objective currently displayed or null if nothing is displayed in that DisplaySlot
* @throws IllegalArgumentException if slot is null
*/
Objective getObjective(DisplaySlot slot) throws IllegalArgumentException;

/**
* Gets all scores for a player on this Scoreboard
*
* @param player the player whose scores are being retrieved
* @return immutable set of all scores tracked for the player
* @throws IllegalArgumentException if player is null
*/
Set<Score> getScores(OfflinePlayer player) throws IllegalArgumentException;

/**
* Removes all scores for a player on this Scoreboard
*
* @param player the player to drop all current scores
* @throws IllegalArgumentException if player is null
*/
void resetScores(OfflinePlayer player) throws IllegalArgumentException;

/**
* Gets a player's Team on this Scoreboard
*
* @param player the player to search for
* @return the player's Team or null if the player is not on a team
* @throws IllegalArgumentException if player is null
*/
Team getPlayerTeam(OfflinePlayer player) throws IllegalArgumentException;

/**
* Gets a Team by name on this Scoreboard
*
* @param teamName Team name
* @return the matching Team or null if no matches
* @throws IllegalArgumentException if teamName is null
*/
Team getTeam(String teamName) throws IllegalArgumentException;

/**
* Gets all teams on this Scoreboard
*
* @return an immutable set of Teams
*/
Set<Team> getTeams();

/**
* Registers a Team on this Scoreboard
*
* @param name Team name
* @return registered Team
* @throws IllegalArgumentException if name is null
* @throws IllegalArgumentException if team by that name already exists
*/
Team registerNewTeam(String name) throws IllegalArgumentException;

/**
* Gets all players tracked by this Scoreboard
*
* @return immutable set of all tracked players
*/
Set<OfflinePlayer> getPlayers();

/**
* Clears any objective in the specified slot.
*
* @param slot the slot to remove objectives
* @throws IllegalArgumentException if slot is null
*/
void clearSlot(DisplaySlot slot) throws IllegalArgumentException;
}
Loading

0 comments on commit 6fb1647

Please sign in to comment.