Added Scoreboard interface and TabList Scoreboard

This commit is contained in:
R0bbyYT 2020-08-08 23:22:58 +02:00
parent bbe9cda40b
commit 141eed466c
4 changed files with 192 additions and 78 deletions

View File

@ -1,11 +1,7 @@
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;
import net.minestom.server.network.player.PlayerConnection;
import java.util.Collections;
@ -15,14 +11,17 @@ import java.util.concurrent.CopyOnWriteArraySet;
/**
* 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 String objectiveName;
private final ScoreboardObjectivePacket scoreboardObjectivePacket;
private final ScoreboardObjectivePacket destructionObjectivePacket;
private final DisplayScoreboardPacket displayScoreboardPacket;
/**
* Creates a new below name scoreboard
@ -31,63 +30,14 @@ public class BelowNameTag implements Viewable {
* @param value The value of the scoreboard
*/
public BelowNameTag(String name, String value) {
this.objectiveName = name;
this.objectiveName = BELOW_NAME_TAG_PREFIX + name;
this.scoreboardObjectivePacket = this.getCreationObjectivePacket(value);
this.displayScoreboardPacket = new DisplayScoreboardPacket();
this.displayScoreboardPacket.position = 2; // Below name
this.displayScoreboardPacket.scoreName = this.objectiveName;
this.destructionObjectivePacket = this.getDestructionObjectivePacket();
this.scoreboardObjectivePacket = this.getCreationObjectivePacket(value, ScoreboardObjectivePacket.Type.INTEGER);
}
/**
* Creates a creation objective packet for the tag below name
*
* @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
public String getObjectiveName() {
return this.objectiveName;
}
@Override
@ -97,7 +47,7 @@ public class BelowNameTag implements Viewable {
if (result) {
connection.sendPacket(this.scoreboardObjectivePacket);
connection.sendPacket(this.displayScoreboardPacket);
connection.sendPacket(this.getDisplayScoreboardPacket((byte) 2));
player.setBelowNameTag(this);
}
@ -111,7 +61,7 @@ public class BelowNameTag implements Viewable {
PlayerConnection connection = player.getPlayerConnection();
if (result) {
connection.sendPacket(this.destructionObjectivePacket);
connection.sendPacket(this.getDestructionObjectivePacket());
player.setBelowNameTag(null);
}

View 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();
}

View File

@ -1,7 +1,6 @@
package net.minestom.server.scoreboard;
import it.unimi.dsi.fastutil.ints.IntLinkedOpenHashSet;
import net.minestom.server.Viewable;
import net.minestom.server.chat.ChatParser;
import net.minestom.server.chat.ColoredText;
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
*/
public class Sidebar implements Viewable {
public class Sidebar implements Scoreboard {
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 TEAM_PREFIX = "sbt-";
@ -173,15 +174,8 @@ public class Sidebar implements Viewable {
final boolean result = this.viewers.add(player);
PlayerConnection playerConnection = player.getPlayerConnection();
ScoreboardObjectivePacket scoreboardObjectivePacket = new ScoreboardObjectivePacket();
scoreboardObjectivePacket.objectiveName = objectiveName;
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;
ScoreboardObjectivePacket scoreboardObjectivePacket = this.getCreationObjectivePacket(this.title, ScoreboardObjectivePacket.Type.INTEGER);
DisplayScoreboardPacket displayScoreboardPacket = this.getDisplayScoreboardPacket((byte) 1);
playerConnection.sendPacket(scoreboardObjectivePacket); // Creative objective
playerConnection.sendPacket(displayScoreboardPacket); // Show sidebar scoreboard (wait for scores packet)
@ -197,9 +191,7 @@ public class Sidebar implements Viewable {
public boolean removeViewer(Player player) {
boolean result = this.viewers.remove(player);
PlayerConnection playerConnection = player.getPlayerConnection();
ScoreboardObjectivePacket scoreboardObjectivePacket = new ScoreboardObjectivePacket();
scoreboardObjectivePacket.objectiveName = objectiveName;
scoreboardObjectivePacket.mode = 1; // Remove
ScoreboardObjectivePacket scoreboardObjectivePacket = this.getDestructionObjectivePacket();
playerConnection.sendPacket(scoreboardObjectivePacket);
for (ScoreboardLine line : lines) {
@ -214,6 +206,11 @@ public class Sidebar implements Viewable {
return viewers;
}
@Override
public String getObjectiveName() {
return this.objectiveName;
}
/**
* This class is used to create a line for the sidebar.
*/

View 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;
}
}