mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-31 20:41:29 +01:00
Added Scoreboard interface and TabList Scoreboard
This commit is contained in:
parent
bbe9cda40b
commit
141eed466c
@ -1,11 +1,7 @@
|
|||||||
package net.minestom.server.scoreboard;
|
package net.minestom.server.scoreboard;
|
||||||
|
|
||||||
import net.minestom.server.Viewable;
|
|
||||||
import net.minestom.server.chat.ColoredText;
|
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.network.packet.server.play.DisplayScoreboardPacket;
|
|
||||||
import net.minestom.server.network.packet.server.play.ScoreboardObjectivePacket;
|
import net.minestom.server.network.packet.server.play.ScoreboardObjectivePacket;
|
||||||
import net.minestom.server.network.packet.server.play.UpdateScorePacket;
|
|
||||||
import net.minestom.server.network.player.PlayerConnection;
|
import net.minestom.server.network.player.PlayerConnection;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -15,14 +11,17 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
/**
|
/**
|
||||||
* Represents a scoreboard which rendered a tag below the name
|
* Represents a scoreboard which rendered a tag below the name
|
||||||
*/
|
*/
|
||||||
public class BelowNameTag implements Viewable {
|
public class BelowNameTag implements Scoreboard {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>WARNING:</b> You shouldn't create scoreboards with the same prefix as those
|
||||||
|
*/
|
||||||
|
public static final String BELOW_NAME_TAG_PREFIX = "bnt-";
|
||||||
|
|
||||||
private final Set<Player> viewers = new CopyOnWriteArraySet<>();
|
private final Set<Player> viewers = new CopyOnWriteArraySet<>();
|
||||||
private final String objectiveName;
|
private final String objectiveName;
|
||||||
|
|
||||||
private final ScoreboardObjectivePacket scoreboardObjectivePacket;
|
private final ScoreboardObjectivePacket scoreboardObjectivePacket;
|
||||||
private final ScoreboardObjectivePacket destructionObjectivePacket;
|
|
||||||
private final DisplayScoreboardPacket displayScoreboardPacket;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new below name scoreboard
|
* Creates a new below name scoreboard
|
||||||
@ -31,63 +30,14 @@ public class BelowNameTag implements Viewable {
|
|||||||
* @param value The value of the scoreboard
|
* @param value The value of the scoreboard
|
||||||
*/
|
*/
|
||||||
public BelowNameTag(String name, String value) {
|
public BelowNameTag(String name, String value) {
|
||||||
this.objectiveName = name;
|
this.objectiveName = BELOW_NAME_TAG_PREFIX + name;
|
||||||
|
|
||||||
this.scoreboardObjectivePacket = this.getCreationObjectivePacket(value);
|
this.scoreboardObjectivePacket = this.getCreationObjectivePacket(value, ScoreboardObjectivePacket.Type.INTEGER);
|
||||||
|
|
||||||
this.displayScoreboardPacket = new DisplayScoreboardPacket();
|
|
||||||
this.displayScoreboardPacket.position = 2; // Below name
|
|
||||||
this.displayScoreboardPacket.scoreName = this.objectiveName;
|
|
||||||
|
|
||||||
this.destructionObjectivePacket = this.getDestructionObjectivePacket();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Creates a creation objective packet for the tag below name
|
public String getObjectiveName() {
|
||||||
*
|
return this.objectiveName;
|
||||||
* @param value The value of the tag
|
|
||||||
* @return the creation objective packet
|
|
||||||
*/
|
|
||||||
private ScoreboardObjectivePacket getCreationObjectivePacket(String value) {
|
|
||||||
ScoreboardObjectivePacket packet = new ScoreboardObjectivePacket();
|
|
||||||
packet.objectiveName = this.objectiveName;
|
|
||||||
packet.mode = 0; // Create/Update
|
|
||||||
packet.objectiveValue = ColoredText.of(value);
|
|
||||||
packet.type = ScoreboardObjectivePacket.Type.INTEGER;
|
|
||||||
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the destruction objective packet for the tag below name
|
|
||||||
*
|
|
||||||
* @return the destruction objective packet
|
|
||||||
*/
|
|
||||||
private ScoreboardObjectivePacket getDestructionObjectivePacket() {
|
|
||||||
ScoreboardObjectivePacket packet = new ScoreboardObjectivePacket();
|
|
||||||
packet.objectiveName = this.objectiveName;
|
|
||||||
packet.mode = 1;
|
|
||||||
packet.objectiveValue = ColoredText.of("");
|
|
||||||
packet.type = ScoreboardObjectivePacket.Type.INTEGER;
|
|
||||||
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the score of a {@link Player}
|
|
||||||
*
|
|
||||||
* @param player The player
|
|
||||||
* @param score The new score
|
|
||||||
*/
|
|
||||||
public void updateScore(Player player, int score) {
|
|
||||||
UpdateScorePacket packet = new UpdateScorePacket();
|
|
||||||
packet.entityName = player.getUsername();
|
|
||||||
packet.action = 0; //Create/Update
|
|
||||||
packet.objectiveName = this.objectiveName;
|
|
||||||
packet.value = score;
|
|
||||||
|
|
||||||
// Sends to all viewers an update packet
|
|
||||||
sendPacketToViewers(packet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -97,7 +47,7 @@ public class BelowNameTag implements Viewable {
|
|||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
connection.sendPacket(this.scoreboardObjectivePacket);
|
connection.sendPacket(this.scoreboardObjectivePacket);
|
||||||
connection.sendPacket(this.displayScoreboardPacket);
|
connection.sendPacket(this.getDisplayScoreboardPacket((byte) 2));
|
||||||
|
|
||||||
player.setBelowNameTag(this);
|
player.setBelowNameTag(this);
|
||||||
}
|
}
|
||||||
@ -111,7 +61,7 @@ public class BelowNameTag implements Viewable {
|
|||||||
PlayerConnection connection = player.getPlayerConnection();
|
PlayerConnection connection = player.getPlayerConnection();
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
connection.sendPacket(this.destructionObjectivePacket);
|
connection.sendPacket(this.getDestructionObjectivePacket());
|
||||||
player.setBelowNameTag(null);
|
player.setBelowNameTag(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
82
src/main/java/net/minestom/server/scoreboard/Scoreboard.java
Normal file
82
src/main/java/net/minestom/server/scoreboard/Scoreboard.java
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
package net.minestom.server.scoreboard;
|
||||||
|
|
||||||
|
import net.minestom.server.Viewable;
|
||||||
|
import net.minestom.server.chat.ColoredText;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.network.packet.server.play.DisplayScoreboardPacket;
|
||||||
|
import net.minestom.server.network.packet.server.play.ScoreboardObjectivePacket;
|
||||||
|
import net.minestom.server.network.packet.server.play.UpdateScorePacket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interface represents all scoreboard of Minecraft
|
||||||
|
*/
|
||||||
|
public interface Scoreboard extends Viewable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a creation objective packet
|
||||||
|
*
|
||||||
|
* @param value The value for the objective
|
||||||
|
* @param type The type for the objective
|
||||||
|
* @return the creation objective packet
|
||||||
|
*/
|
||||||
|
default ScoreboardObjectivePacket getCreationObjectivePacket(String value, ScoreboardObjectivePacket.Type type) {
|
||||||
|
final ScoreboardObjectivePacket packet = new ScoreboardObjectivePacket();
|
||||||
|
packet.objectiveName = this.getObjectiveName();
|
||||||
|
packet.mode = 0; // Create Scoreboard
|
||||||
|
packet.objectiveValue = ColoredText.of(value);
|
||||||
|
packet.type = type;
|
||||||
|
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the destruction objective packet
|
||||||
|
*
|
||||||
|
* @return the destruction objective packet
|
||||||
|
*/
|
||||||
|
default ScoreboardObjectivePacket getDestructionObjectivePacket() {
|
||||||
|
final ScoreboardObjectivePacket packet = new ScoreboardObjectivePacket();
|
||||||
|
packet.objectiveName = this.getObjectiveName();
|
||||||
|
packet.mode = 1; // Destroy Scoreboard
|
||||||
|
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the {@link DisplayScoreboardPacket}
|
||||||
|
*
|
||||||
|
* @param position The position of the scoreboard
|
||||||
|
* @return the created display scoreboard packet
|
||||||
|
*/
|
||||||
|
default DisplayScoreboardPacket getDisplayScoreboardPacket(byte position) {
|
||||||
|
final DisplayScoreboardPacket packet = new DisplayScoreboardPacket();
|
||||||
|
packet.position = position;
|
||||||
|
packet.scoreName = this.getObjectiveName();
|
||||||
|
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the score of a {@link Player}
|
||||||
|
*
|
||||||
|
* @param player The player
|
||||||
|
* @param score The new score
|
||||||
|
*/
|
||||||
|
default void updateScore(Player player, int score) {
|
||||||
|
final UpdateScorePacket packet = new UpdateScorePacket();
|
||||||
|
packet.entityName = player.getUsername();
|
||||||
|
packet.action = 0; // Create/Update score
|
||||||
|
packet.objectiveName = this.getObjectiveName();
|
||||||
|
packet.value = score;
|
||||||
|
|
||||||
|
sendPacketsToViewers(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the objective name of the scoreboard
|
||||||
|
*
|
||||||
|
* @return the objective name
|
||||||
|
*/
|
||||||
|
String getObjectiveName();
|
||||||
|
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package net.minestom.server.scoreboard;
|
package net.minestom.server.scoreboard;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntLinkedOpenHashSet;
|
import it.unimi.dsi.fastutil.ints.IntLinkedOpenHashSet;
|
||||||
import net.minestom.server.Viewable;
|
|
||||||
import net.minestom.server.chat.ChatParser;
|
import net.minestom.server.chat.ChatParser;
|
||||||
import net.minestom.server.chat.ColoredText;
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
@ -21,11 +20,13 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
/**
|
/**
|
||||||
* Represents a sidebar which can contain up to 16 {@link ScoreboardLine}'s
|
* Represents a sidebar which can contain up to 16 {@link ScoreboardLine}'s
|
||||||
*/
|
*/
|
||||||
public class Sidebar implements Viewable {
|
public class Sidebar implements Scoreboard {
|
||||||
|
|
||||||
private static final AtomicInteger COUNTER = new AtomicInteger();
|
private static final AtomicInteger COUNTER = new AtomicInteger();
|
||||||
|
|
||||||
// WARNING: you shouldn't create scoreboards/teams with the same prefixes as those
|
/**
|
||||||
|
* <b>WARNING:</b> You shouldn't create scoreboards/teams with the same prefixes as those
|
||||||
|
*/
|
||||||
private static final String SCOREBOARD_PREFIX = "sb-";
|
private static final String SCOREBOARD_PREFIX = "sb-";
|
||||||
private static final String TEAM_PREFIX = "sbt-";
|
private static final String TEAM_PREFIX = "sbt-";
|
||||||
|
|
||||||
@ -173,15 +174,8 @@ public class Sidebar implements Viewable {
|
|||||||
final boolean result = this.viewers.add(player);
|
final boolean result = this.viewers.add(player);
|
||||||
PlayerConnection playerConnection = player.getPlayerConnection();
|
PlayerConnection playerConnection = player.getPlayerConnection();
|
||||||
|
|
||||||
ScoreboardObjectivePacket scoreboardObjectivePacket = new ScoreboardObjectivePacket();
|
ScoreboardObjectivePacket scoreboardObjectivePacket = this.getCreationObjectivePacket(this.title, ScoreboardObjectivePacket.Type.INTEGER);
|
||||||
scoreboardObjectivePacket.objectiveName = objectiveName;
|
DisplayScoreboardPacket displayScoreboardPacket = this.getDisplayScoreboardPacket((byte) 1);
|
||||||
scoreboardObjectivePacket.mode = 0; // Create scoreboard
|
|
||||||
scoreboardObjectivePacket.objectiveValue = ColoredText.of(title);
|
|
||||||
scoreboardObjectivePacket.type = ScoreboardObjectivePacket.Type.INTEGER; // Type integer
|
|
||||||
|
|
||||||
DisplayScoreboardPacket displayScoreboardPacket = new DisplayScoreboardPacket();
|
|
||||||
displayScoreboardPacket.position = 1; // Sidebar
|
|
||||||
displayScoreboardPacket.scoreName = objectiveName;
|
|
||||||
|
|
||||||
playerConnection.sendPacket(scoreboardObjectivePacket); // Creative objective
|
playerConnection.sendPacket(scoreboardObjectivePacket); // Creative objective
|
||||||
playerConnection.sendPacket(displayScoreboardPacket); // Show sidebar scoreboard (wait for scores packet)
|
playerConnection.sendPacket(displayScoreboardPacket); // Show sidebar scoreboard (wait for scores packet)
|
||||||
@ -197,9 +191,7 @@ public class Sidebar implements Viewable {
|
|||||||
public boolean removeViewer(Player player) {
|
public boolean removeViewer(Player player) {
|
||||||
boolean result = this.viewers.remove(player);
|
boolean result = this.viewers.remove(player);
|
||||||
PlayerConnection playerConnection = player.getPlayerConnection();
|
PlayerConnection playerConnection = player.getPlayerConnection();
|
||||||
ScoreboardObjectivePacket scoreboardObjectivePacket = new ScoreboardObjectivePacket();
|
ScoreboardObjectivePacket scoreboardObjectivePacket = this.getDestructionObjectivePacket();
|
||||||
scoreboardObjectivePacket.objectiveName = objectiveName;
|
|
||||||
scoreboardObjectivePacket.mode = 1; // Remove
|
|
||||||
playerConnection.sendPacket(scoreboardObjectivePacket);
|
playerConnection.sendPacket(scoreboardObjectivePacket);
|
||||||
|
|
||||||
for (ScoreboardLine line : lines) {
|
for (ScoreboardLine line : lines) {
|
||||||
@ -214,6 +206,11 @@ public class Sidebar implements Viewable {
|
|||||||
return viewers;
|
return viewers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getObjectiveName() {
|
||||||
|
return this.objectiveName;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is used to create a line for the sidebar.
|
* This class is used to create a line for the sidebar.
|
||||||
*/
|
*/
|
||||||
|
85
src/main/java/net/minestom/server/scoreboard/TabList.java
Normal file
85
src/main/java/net/minestom/server/scoreboard/TabList.java
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
package net.minestom.server.scoreboard;
|
||||||
|
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.network.packet.server.play.ScoreboardObjectivePacket;
|
||||||
|
import net.minestom.server.network.player.PlayerConnection;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the {@link Player} tab list as a {@link Scoreboard}
|
||||||
|
*/
|
||||||
|
public class TabList implements Scoreboard {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>WARNING:</b> You shouldn't create scoreboards with the same prefix as those
|
||||||
|
*/
|
||||||
|
private static final String TAB_LIST_PREFIX = "tl-";
|
||||||
|
|
||||||
|
private final Set<Player> viewers;
|
||||||
|
private final String objectiveName;
|
||||||
|
|
||||||
|
private ScoreboardObjectivePacket.Type type;
|
||||||
|
|
||||||
|
public TabList(String name, ScoreboardObjectivePacket.Type type) {
|
||||||
|
this.viewers = new CopyOnWriteArraySet<>();
|
||||||
|
this.objectiveName = TAB_LIST_PREFIX + name;
|
||||||
|
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the scoreboard objective type
|
||||||
|
*
|
||||||
|
* @return the scoreboard objective type
|
||||||
|
*/
|
||||||
|
public ScoreboardObjectivePacket.Type getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the scoreboard objective type
|
||||||
|
*
|
||||||
|
* @param type The new type for the objective
|
||||||
|
*/
|
||||||
|
public void setType(ScoreboardObjectivePacket.Type type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addViewer(Player player) {
|
||||||
|
boolean result = this.viewers.add(player);
|
||||||
|
PlayerConnection connection = player.getPlayerConnection();
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
connection.sendPacket(this.getCreationObjectivePacket("", this.type));
|
||||||
|
connection.sendPacket(this.getDisplayScoreboardPacket((byte) 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeViewer(Player player) {
|
||||||
|
boolean result = this.viewers.remove(player);
|
||||||
|
PlayerConnection connection = player.getPlayerConnection();
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
connection.sendPacket(this.getDestructionObjectivePacket());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Player> getViewers() {
|
||||||
|
return Collections.unmodifiableSet(this.viewers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getObjectiveName() {
|
||||||
|
return this.objectiveName;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user