mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-12 01:41:05 +01:00
Implement Scoreboard API. Adds BUKKIT-3776
This implementation facilitates the correspondence of the Bukkit Scoreboard API to the internal minecraft implementation. When the first scoreboard is loaded, the scoreboard manager will be created. It uses the newly added WeakCollection for handling plugin scoreboard references to update the respective objectives. When a scoreboard contains no more active references, it should be garbage collected. An active reference can be held by a still registered objective, team, and transitively a score for a still registered objective. An internal reference will also be kept if a player's specific scoreboard has been set, and will remain persistent until that player logs out. A player's specific scoreboard becomes the scoreboard used when determining team structure for the player's attacking damage and the player's vision.
This commit is contained in:
parent
5634d9f701
commit
d95a4705cb
15 changed files with 756 additions and 32 deletions
|
@ -436,11 +436,13 @@ public abstract class EntityHuman extends EntityLiving implements ICommandListen
|
||||||
|
|
||||||
public void c(Entity entity, int i) {
|
public void c(Entity entity, int i) {
|
||||||
this.addScore(i);
|
this.addScore(i);
|
||||||
Collection collection = this.getScoreboard().getObjectivesForCriteria(IScoreboardCriteria.e);
|
// CraftBukkit - Get our scores instead
|
||||||
|
Collection<ScoreboardScore> collection = this.world.getServer().getScoreboardManager().getScoreboardScores(IScoreboardCriteria.e, this.getLocalizedName(), new java.util.ArrayList<ScoreboardScore>());
|
||||||
|
|
||||||
if (entity instanceof EntityHuman) {
|
if (entity instanceof EntityHuman) {
|
||||||
this.a(StatisticList.A, 1);
|
this.a(StatisticList.A, 1);
|
||||||
collection.addAll(this.getScoreboard().getObjectivesForCriteria(IScoreboardCriteria.d));
|
// CraftBukkit - Get our scores instead
|
||||||
|
this.world.getServer().getScoreboardManager().getScoreboardScores(IScoreboardCriteria.d, this.getLocalizedName(), collection);
|
||||||
} else {
|
} else {
|
||||||
this.a(StatisticList.z, 1);
|
this.a(StatisticList.z, 1);
|
||||||
}
|
}
|
||||||
|
@ -448,8 +450,7 @@ public abstract class EntityHuman extends EntityLiving implements ICommandListen
|
||||||
Iterator iterator = collection.iterator();
|
Iterator iterator = collection.iterator();
|
||||||
|
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
ScoreboardObjective scoreboardobjective = (ScoreboardObjective) iterator.next();
|
ScoreboardScore scoreboardscore = (ScoreboardScore) iterator.next(); // CraftBukkit - Use our scores instead
|
||||||
ScoreboardScore scoreboardscore = this.getScoreboard().getPlayerScoreForObjective(this.getLocalizedName(), scoreboardobjective);
|
|
||||||
|
|
||||||
scoreboardscore.incrementScore();
|
scoreboardscore.incrementScore();
|
||||||
}
|
}
|
||||||
|
@ -687,10 +688,28 @@ public abstract class EntityHuman extends EntityLiving implements ICommandListen
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean a(EntityHuman entityhuman) {
|
public boolean a(EntityHuman entityhuman) {
|
||||||
ScoreboardTeam scoreboardteam = this.getScoreboardTeam();
|
// CraftBukkit start - Change to check player's scoreboard team according to API reference to this (or main) scoreboard
|
||||||
ScoreboardTeam scoreboardteam1 = entityhuman.getScoreboardTeam();
|
org.bukkit.scoreboard.Team team;
|
||||||
|
if (this instanceof EntityPlayer) {
|
||||||
|
EntityPlayer thisPlayer = (EntityPlayer) this;
|
||||||
|
team = thisPlayer.getBukkitEntity().getScoreboard().getPlayerTeam(thisPlayer.getBukkitEntity());
|
||||||
|
if (team == null || team.allowFriendlyFire()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// This should never be called, but is implemented anyway
|
||||||
|
org.bukkit.OfflinePlayer thisPlayer = this.world.getServer().getOfflinePlayer(this.name);
|
||||||
|
team = this.world.getServer().getScoreboardManager().getMainScoreboard().getPlayerTeam(thisPlayer);
|
||||||
|
if (team == null || team.allowFriendlyFire()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return scoreboardteam != scoreboardteam1 ? true : (scoreboardteam != null ? scoreboardteam.allowFriendlyFire() : true);
|
if (entityhuman instanceof EntityPlayer) {
|
||||||
|
return team.hasPlayer(((EntityPlayer) entityhuman).getBukkitEntity());
|
||||||
|
}
|
||||||
|
return team.hasPlayer(this.world.getServer().getOfflinePlayer(entityhuman.name));
|
||||||
|
// CraftBukkit end
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void a(EntityLiving entityliving, boolean flag) {
|
protected void a(EntityLiving entityliving, boolean flag) {
|
||||||
|
@ -1494,6 +1513,7 @@ public abstract class EntityHuman extends EntityLiving implements ICommandListen
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getScoreboardDisplayName() {
|
public String getScoreboardDisplayName() {
|
||||||
|
// TODO: fun
|
||||||
return ScoreboardTeam.getPlayerDisplayName(this.getScoreboardTeam(), this.name);
|
return ScoreboardTeam.getPlayerDisplayName(this.getScoreboardTeam(), this.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,14 +201,8 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
|
||||||
|
|
||||||
public void setHealth(int i) {
|
public void setHealth(int i) {
|
||||||
super.setHealth(i);
|
super.setHealth(i);
|
||||||
Collection collection = this.getScoreboard().getObjectivesForCriteria(IScoreboardCriteria.f);
|
// CraftBukkit - Update ALL the scores!
|
||||||
Iterator iterator = collection.iterator();
|
this.world.getServer().getScoreboardManager().updateAllScoresForList(IScoreboardCriteria.f, this.getLocalizedName(), com.google.common.collect.ImmutableList.of(this));
|
||||||
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
ScoreboardObjective scoreboardobjective = (ScoreboardObjective) iterator.next();
|
|
||||||
|
|
||||||
this.getScoreboard().getPlayerScoreForObjective(this.getLocalizedName(), scoreboardobjective).updateForList(Arrays.asList(new EntityHuman[] { this}));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void g() {
|
public void g() {
|
||||||
|
@ -304,12 +298,12 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
|
||||||
this.closeInventory();
|
this.closeInventory();
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
|
|
||||||
Collection collection = this.world.getScoreboard().getObjectivesForCriteria(IScoreboardCriteria.c);
|
// CraftBukkit - Get our scores instead
|
||||||
|
Collection<ScoreboardScore> collection = this.world.getServer().getScoreboardManager().getScoreboardScores(IScoreboardCriteria.c, this.getLocalizedName(), new java.util.ArrayList<ScoreboardScore>());
|
||||||
Iterator iterator = collection.iterator();
|
Iterator iterator = collection.iterator();
|
||||||
|
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
ScoreboardObjective scoreboardobjective = (ScoreboardObjective) iterator.next();
|
ScoreboardScore scoreboardscore = (ScoreboardScore) iterator.next(); // CraftBukkit - Use our scores instead
|
||||||
ScoreboardScore scoreboardscore = this.getScoreboard().getPlayerScoreForObjective(this.getLocalizedName(), scoreboardobjective);
|
|
||||||
|
|
||||||
scoreboardscore.incrementScore();
|
scoreboardscore.incrementScore();
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,6 +225,8 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
|
||||||
world.getWorld().getPopulators().addAll(gen.getDefaultPopulators(world.getWorld()));
|
world.getWorld().getPopulators().addAll(gen.getDefaultPopulators(world.getWorld()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.server.scoreboardManager = new org.bukkit.craftbukkit.scoreboard.CraftScoreboardManager(this, world.getScoreboard());
|
||||||
|
|
||||||
this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldInitEvent(world.getWorld()));
|
this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldInitEvent(world.getWorld()));
|
||||||
|
|
||||||
world.addIWorldAccess(new WorldManager(this, world));
|
world.addIWorldAccess(new WorldManager(this, world));
|
||||||
|
|
|
@ -126,7 +126,7 @@ public abstract class PlayerList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void a(ScoreboardServer scoreboardserver, EntityPlayer entityplayer) {
|
public void a(ScoreboardServer scoreboardserver, EntityPlayer entityplayer) { // CraftBukkit - protected -> public
|
||||||
HashSet hashset = new HashSet();
|
HashSet hashset = new HashSet();
|
||||||
Iterator iterator = scoreboardserver.getTeams().iterator();
|
Iterator iterator = scoreboardserver.getTeams().iterator();
|
||||||
|
|
||||||
|
@ -277,6 +277,8 @@ public abstract class PlayerList {
|
||||||
entityplayer1.playerConnection.sendPacket(packet);
|
entityplayer1.playerConnection.sendPacket(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// This removes the scoreboard (and player reference) for the specific player in the manager
|
||||||
|
this.cserver.getScoreboardManager().removePlayer(entityplayer.getBukkitEntity());
|
||||||
|
|
||||||
return playerQuitEvent.getQuitMessage();
|
return playerQuitEvent.getQuitMessage();
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
|
|
|
@ -20,7 +20,7 @@ public class ScoreboardServer extends Scoreboard {
|
||||||
public void handleScoreChanged(ScoreboardScore scoreboardscore) {
|
public void handleScoreChanged(ScoreboardScore scoreboardscore) {
|
||||||
super.handleScoreChanged(scoreboardscore);
|
super.handleScoreChanged(scoreboardscore);
|
||||||
if (this.b.contains(scoreboardscore.getObjective())) {
|
if (this.b.contains(scoreboardscore.getObjective())) {
|
||||||
this.a.getPlayerList().sendAll(new Packet207SetScoreboardScore(scoreboardscore, 0));
|
this.sendAll(new Packet207SetScoreboardScore(scoreboardscore, 0)); // CraftBukkit - Internal packet method
|
||||||
}
|
}
|
||||||
|
|
||||||
this.b();
|
this.b();
|
||||||
|
@ -28,7 +28,7 @@ public class ScoreboardServer extends Scoreboard {
|
||||||
|
|
||||||
public void handlePlayerRemoved(String s) {
|
public void handlePlayerRemoved(String s) {
|
||||||
super.handlePlayerRemoved(s);
|
super.handlePlayerRemoved(s);
|
||||||
this.a.getPlayerList().sendAll(new Packet207SetScoreboardScore(s));
|
this.sendAll(new Packet207SetScoreboardScore(s)); // CraftBukkit - Internal packet method
|
||||||
this.b();
|
this.b();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ public class ScoreboardServer extends Scoreboard {
|
||||||
super.setDisplaySlot(i, scoreboardobjective);
|
super.setDisplaySlot(i, scoreboardobjective);
|
||||||
if (scoreboardobjective1 != scoreboardobjective && scoreboardobjective1 != null) {
|
if (scoreboardobjective1 != scoreboardobjective && scoreboardobjective1 != null) {
|
||||||
if (this.h(scoreboardobjective1) > 0) {
|
if (this.h(scoreboardobjective1) > 0) {
|
||||||
this.a.getPlayerList().sendAll(new Packet208SetScoreboardDisplayObjective(i, scoreboardobjective));
|
this.sendAll(new Packet208SetScoreboardDisplayObjective(i, scoreboardobjective)); // CraftBukkit - Internal packet method
|
||||||
} else {
|
} else {
|
||||||
this.g(scoreboardobjective1);
|
this.g(scoreboardobjective1);
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ public class ScoreboardServer extends Scoreboard {
|
||||||
|
|
||||||
if (scoreboardobjective != null) {
|
if (scoreboardobjective != null) {
|
||||||
if (this.b.contains(scoreboardobjective)) {
|
if (this.b.contains(scoreboardobjective)) {
|
||||||
this.a.getPlayerList().sendAll(new Packet208SetScoreboardDisplayObjective(i, scoreboardobjective));
|
this.sendAll(new Packet208SetScoreboardDisplayObjective(i, scoreboardobjective)); // CraftBukkit - Internal packet method
|
||||||
} else {
|
} else {
|
||||||
this.e(scoreboardobjective);
|
this.e(scoreboardobjective);
|
||||||
}
|
}
|
||||||
|
@ -57,13 +57,13 @@ public class ScoreboardServer extends Scoreboard {
|
||||||
|
|
||||||
public void addPlayerToTeam(String s, ScoreboardTeam scoreboardteam) {
|
public void addPlayerToTeam(String s, ScoreboardTeam scoreboardteam) {
|
||||||
super.addPlayerToTeam(s, scoreboardteam);
|
super.addPlayerToTeam(s, scoreboardteam);
|
||||||
this.a.getPlayerList().sendAll(new Packet209SetScoreboardTeam(scoreboardteam, Arrays.asList(new String[] { s}), 3));
|
this.sendAll(new Packet209SetScoreboardTeam(scoreboardteam, Arrays.asList(new String[] { s}), 3)); // CraftBukkit - Internal packet method
|
||||||
this.b();
|
this.b();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removePlayerFromTeam(String s, ScoreboardTeam scoreboardteam) {
|
public void removePlayerFromTeam(String s, ScoreboardTeam scoreboardteam) {
|
||||||
super.removePlayerFromTeam(s, scoreboardteam);
|
super.removePlayerFromTeam(s, scoreboardteam);
|
||||||
this.a.getPlayerList().sendAll(new Packet209SetScoreboardTeam(scoreboardteam, Arrays.asList(new String[] { s}), 4));
|
this.sendAll(new Packet209SetScoreboardTeam(scoreboardteam, Arrays.asList(new String[] { s}), 4)); // CraftBukkit - Internal packet method
|
||||||
this.b();
|
this.b();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ public class ScoreboardServer extends Scoreboard {
|
||||||
public void handleObjectiveChanged(ScoreboardObjective scoreboardobjective) {
|
public void handleObjectiveChanged(ScoreboardObjective scoreboardobjective) {
|
||||||
super.handleObjectiveChanged(scoreboardobjective);
|
super.handleObjectiveChanged(scoreboardobjective);
|
||||||
if (this.b.contains(scoreboardobjective)) {
|
if (this.b.contains(scoreboardobjective)) {
|
||||||
this.a.getPlayerList().sendAll(new Packet206SetScoreboardObjective(scoreboardobjective, 2));
|
this.sendAll(new Packet206SetScoreboardObjective(scoreboardobjective, 2)); // CraftBukkit - Internal packet method
|
||||||
}
|
}
|
||||||
|
|
||||||
this.b();
|
this.b();
|
||||||
|
@ -92,19 +92,19 @@ public class ScoreboardServer extends Scoreboard {
|
||||||
|
|
||||||
public void handleTeamAdded(ScoreboardTeam scoreboardteam) {
|
public void handleTeamAdded(ScoreboardTeam scoreboardteam) {
|
||||||
super.handleTeamAdded(scoreboardteam);
|
super.handleTeamAdded(scoreboardteam);
|
||||||
this.a.getPlayerList().sendAll(new Packet209SetScoreboardTeam(scoreboardteam, 0));
|
this.sendAll(new Packet209SetScoreboardTeam(scoreboardteam, 0)); // CraftBukkit - Internal packet method
|
||||||
this.b();
|
this.b();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleTeamChanged(ScoreboardTeam scoreboardteam) {
|
public void handleTeamChanged(ScoreboardTeam scoreboardteam) {
|
||||||
super.handleTeamChanged(scoreboardteam);
|
super.handleTeamChanged(scoreboardteam);
|
||||||
this.a.getPlayerList().sendAll(new Packet209SetScoreboardTeam(scoreboardteam, 2));
|
this.sendAll(new Packet209SetScoreboardTeam(scoreboardteam, 2)); // CraftBukkit - Internal packet method
|
||||||
this.b();
|
this.b();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleTeamRemoved(ScoreboardTeam scoreboardteam) {
|
public void handleTeamRemoved(ScoreboardTeam scoreboardteam) {
|
||||||
super.handleTeamRemoved(scoreboardteam);
|
super.handleTeamRemoved(scoreboardteam);
|
||||||
this.a.getPlayerList().sendAll(new Packet209SetScoreboardTeam(scoreboardteam, 1));
|
this.sendAll(new Packet209SetScoreboardTeam(scoreboardteam, 1)); // CraftBukkit - Internal packet method
|
||||||
this.b();
|
this.b();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,6 +146,7 @@ public class ScoreboardServer extends Scoreboard {
|
||||||
|
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
EntityPlayer entityplayer = (EntityPlayer) iterator.next();
|
EntityPlayer entityplayer = (EntityPlayer) iterator.next();
|
||||||
|
if (entityplayer.getBukkitEntity().getScoreboard().getHandle() != this) continue; // CraftBukkit - Only players on this board
|
||||||
Iterator iterator1 = list.iterator();
|
Iterator iterator1 = list.iterator();
|
||||||
|
|
||||||
while (iterator1.hasNext()) {
|
while (iterator1.hasNext()) {
|
||||||
|
@ -178,6 +179,7 @@ public class ScoreboardServer extends Scoreboard {
|
||||||
|
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
EntityPlayer entityplayer = (EntityPlayer) iterator.next();
|
EntityPlayer entityplayer = (EntityPlayer) iterator.next();
|
||||||
|
if (entityplayer.getBukkitEntity().getScoreboard().getHandle() != this) continue; // CraftBukkit - Only players on this board
|
||||||
Iterator iterator1 = list.iterator();
|
Iterator iterator1 = list.iterator();
|
||||||
|
|
||||||
while (iterator1.hasNext()) {
|
while (iterator1.hasNext()) {
|
||||||
|
@ -201,4 +203,14 @@ public class ScoreboardServer extends Scoreboard {
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CraftBukkit start - Send to players
|
||||||
|
private void sendAll(Packet packet) {
|
||||||
|
for (EntityPlayer entityplayer : (List<EntityPlayer>) this.a.getPlayerList().players) {
|
||||||
|
if (entityplayer.getBukkitEntity().getScoreboard().getHandle() == this) {
|
||||||
|
entityplayer.playerConnection.sendPacket(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,6 @@ import net.minecraft.server.EnumGamemode;
|
||||||
import net.minecraft.server.ExceptionWorldConflict;
|
import net.minecraft.server.ExceptionWorldConflict;
|
||||||
import net.minecraft.server.PlayerList;
|
import net.minecraft.server.PlayerList;
|
||||||
import net.minecraft.server.RecipesFurnace;
|
import net.minecraft.server.RecipesFurnace;
|
||||||
import net.minecraft.server.IProgressUpdate;
|
|
||||||
import net.minecraft.server.IWorldAccess;
|
|
||||||
import net.minecraft.server.Item;
|
import net.minecraft.server.Item;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.MobEffectList;
|
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.metadata.WorldMetadataStore;
|
||||||
import org.bukkit.craftbukkit.potion.CraftPotionBrewer;
|
import org.bukkit.craftbukkit.potion.CraftPotionBrewer;
|
||||||
import org.bukkit.craftbukkit.scheduler.CraftScheduler;
|
import org.bukkit.craftbukkit.scheduler.CraftScheduler;
|
||||||
|
import org.bukkit.craftbukkit.scoreboard.CraftScoreboardManager;
|
||||||
import org.bukkit.craftbukkit.updater.AutoUpdater;
|
import org.bukkit.craftbukkit.updater.AutoUpdater;
|
||||||
import org.bukkit.craftbukkit.updater.BukkitDLUpdaterService;
|
import org.bukkit.craftbukkit.updater.BukkitDLUpdaterService;
|
||||||
import org.bukkit.craftbukkit.util.DatFileFilter;
|
import org.bukkit.craftbukkit.util.DatFileFilter;
|
||||||
|
@ -162,6 +161,7 @@ public final class CraftServer implements Server {
|
||||||
private File container;
|
private File container;
|
||||||
private WarningState warningState = WarningState.DEFAULT;
|
private WarningState warningState = WarningState.DEFAULT;
|
||||||
private final BooleanWrapper online = new BooleanWrapper();
|
private final BooleanWrapper online = new BooleanWrapper();
|
||||||
|
public CraftScoreboardManager scoreboardManager;
|
||||||
|
|
||||||
private final class BooleanWrapper {
|
private final class BooleanWrapper {
|
||||||
private boolean value = true;
|
private boolean value = true;
|
||||||
|
@ -1358,4 +1358,8 @@ public final class CraftServer implements Server {
|
||||||
public CraftItemFactory getItemFactory() {
|
public CraftItemFactory getItemFactory() {
|
||||||
return CraftItemFactory.instance();
|
return CraftItemFactory.instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CraftScoreboardManager getScoreboardManager() {
|
||||||
|
return scoreboardManager;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ import org.bukkit.*;
|
||||||
import org.bukkit.Achievement;
|
import org.bukkit.Achievement;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Statistic;
|
import org.bukkit.Statistic;
|
||||||
import org.bukkit.WeatherType;
|
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.configuration.serialization.DelegateDeserialization;
|
import org.bukkit.configuration.serialization.DelegateDeserialization;
|
||||||
import org.bukkit.conversations.Conversation;
|
import org.bukkit.conversations.Conversation;
|
||||||
|
@ -38,6 +37,7 @@ import org.bukkit.craftbukkit.CraftSound;
|
||||||
import org.bukkit.craftbukkit.CraftWorld;
|
import org.bukkit.craftbukkit.CraftWorld;
|
||||||
import org.bukkit.craftbukkit.map.CraftMapView;
|
import org.bukkit.craftbukkit.map.CraftMapView;
|
||||||
import org.bukkit.craftbukkit.map.RenderData;
|
import org.bukkit.craftbukkit.map.RenderData;
|
||||||
|
import org.bukkit.craftbukkit.scoreboard.CraftScoreboard;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.player.PlayerGameModeChangeEvent;
|
import org.bukkit.event.player.PlayerGameModeChangeEvent;
|
||||||
|
@ -50,6 +50,7 @@ import org.bukkit.metadata.MetadataValue;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.plugin.messaging.Messenger;
|
import org.bukkit.plugin.messaging.Messenger;
|
||||||
import org.bukkit.plugin.messaging.StandardMessenger;
|
import org.bukkit.plugin.messaging.StandardMessenger;
|
||||||
|
import org.bukkit.scoreboard.Scoreboard;
|
||||||
|
|
||||||
@DelegateDeserialization(CraftOfflinePlayer.class)
|
@DelegateDeserialization(CraftOfflinePlayer.class)
|
||||||
public class CraftPlayer extends CraftHumanEntity implements Player {
|
public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||||
|
@ -420,6 +421,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||||
server.getHandle().playerFileData.save(getHandle());
|
server.getHandle().playerFileData.save(getHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public void updateInventory() {
|
public void updateInventory() {
|
||||||
getHandle().updateInventory(getHandle().activeContainer);
|
getHandle().updateInventory(getHandle().activeContainer);
|
||||||
}
|
}
|
||||||
|
@ -974,4 +976,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||||
super.resetMaxHealth();
|
super.resetMaxHealth();
|
||||||
getHandle().triggerHealthUpdate();
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<String, CraftCriteria> DEFAULTS;
|
||||||
|
static final CraftCriteria DUMMY;
|
||||||
|
|
||||||
|
static {
|
||||||
|
ImmutableMap.Builder<String, CraftCriteria> 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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.
|
||||||
|
* <p>
|
||||||
|
* 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<String, ScoreboardScore> 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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<String, CraftObjective> objectives = new HashMap<String, CraftObjective>();
|
||||||
|
final Map<String, CraftTeam> teams = new HashMap<String, CraftTeam>();
|
||||||
|
|
||||||
|
CraftScoreboard(Scoreboard 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 {
|
||||||
|
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<Objective> getObjectivesByCriteria(String criteria) throws IllegalArgumentException {
|
||||||
|
Validate.notNull(criteria, "Criteria cannot be null");
|
||||||
|
|
||||||
|
ImmutableSet.Builder<Objective> objectives = ImmutableSet.builder();
|
||||||
|
for (CraftObjective objective : this.objectives.values()) {
|
||||||
|
if (objective.getCriteria().equals(criteria)) {
|
||||||
|
objectives.add(objective);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return objectives.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImmutableSet<Objective> getObjectives() {
|
||||||
|
return ImmutableSet.copyOf((Collection<? extends Objective>) 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<Score> getScores(OfflinePlayer player) throws IllegalArgumentException {
|
||||||
|
Validate.notNull(player, "OfflinePlayer cannot be null");
|
||||||
|
|
||||||
|
ImmutableSet.Builder<Score> 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<Team> getTeams() {
|
||||||
|
return ImmutableSet.copyOf((Collection<? extends Team>) 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<OfflinePlayer> getPlayers() {
|
||||||
|
ImmutableSet.Builder<OfflinePlayer> 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<CraftScoreboard> scoreboards = new WeakCollection<CraftScoreboard>();
|
||||||
|
private final Map<CraftPlayer, CraftScoreboard> playerBoards = new HashMap<CraftPlayer, CraftScoreboard>();
|
||||||
|
|
||||||
|
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<ScoreboardObjective> removed = new HashSet<ScoreboardObjective>();
|
||||||
|
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<ScoreboardScore> getScoreboardScores(IScoreboardCriteria criteria, String name, Collection<ScoreboardScore> collection) {
|
||||||
|
for (CraftScoreboard scoreboard : scoreboards) {
|
||||||
|
Scoreboard board = scoreboard.board;
|
||||||
|
for (ScoreboardObjective objective : (Iterable<ScoreboardObjective>) board.getObjectivesForCriteria(criteria)) {
|
||||||
|
collection.add(board.getPlayerScoreForObjective(name, objective));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CraftBukkit method
|
||||||
|
public void updateAllScoresForList(IScoreboardCriteria criteria, String name, List<EntityPlayer> of) {
|
||||||
|
for (ScoreboardScore score : getScoreboardScores(criteria, name, new ArrayList<ScoreboardScore>())) {
|
||||||
|
score.updateForList(of);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<DisplaySlot, String> 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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
145
src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java
Normal file
145
src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java
Normal file
|
@ -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<OfflinePlayer> getPlayers() throws IllegalStateException {
|
||||||
|
CraftScoreboard scoreboard = checkState();
|
||||||
|
|
||||||
|
ImmutableSet.Builder<OfflinePlayer> 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();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue