Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import net.minecraft.server.v1_8_R3.*;
- import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
- import org.bukkit.entity.Player;
- import java.lang.reflect.Field;
- import java.util.ArrayList;
- import java.util.List;
- /**
- * @author zyuiop
- */
- public class ScoreboardSign {
- private boolean created = false;
- private final VirtualTeam[] lines = new VirtualTeam[15];
- private final Player player;
- private String objectiveName;
- /**
- * Create a scoreboard sign for a given player and using a specifig objective name
- * @param player the player viewing the scoreboard sign
- * @param objectiveName the name of the scoreboard sign (displayed at the top of the scoreboard)
- */
- public ScoreboardSign(Player player, String objectiveName) {
- this.player = player;
- this.objectiveName = objectiveName;
- }
- /**
- * Send the initial creation packets for this scoreboard sign. Must be called at least once.
- */
- public void create() {
- if (created)
- return;
- PlayerConnection player = getPlayer();
- player.sendPacket(createObjectivePacket(0, objectiveName));
- player.sendPacket(setObjectiveSlot());
- int i = 0;
- while (i < lines.length)
- sendLine(i++);
- created = true;
- }
- /**
- * Send the packets to remove this scoreboard sign. A destroyed scoreboard sign must be recreated using {@link ScoreboardSign#create()} in order
- * to be used again
- */
- public void destroy() {
- if (!created)
- return;
- getPlayer().sendPacket(createObjectivePacket(1, null));
- for (VirtualTeam team : lines)
- if (team != null)
- getPlayer().sendPacket(team.removeTeam());
- created = false;
- }
- /**
- * Change the name of the objective. The name is displayed at the top of the scoreboard.
- * @param name the name of the objective, max 32 char
- */
- public void setObjectiveName(String name) {
- this.objectiveName = name;
- if (created)
- getPlayer().sendPacket(createObjectivePacket(2, name));
- }
- /**
- * Change a scoreboard line and send the packets to the player. Can be called async.
- * @param line the number of the line (0 <= line < 15)
- * @param value the new value for the scoreboard line
- */
- public void setLine(int line, String value) {
- VirtualTeam team = getOrCreateTeam(line);
- String old = team.getCurrentPlayer();
- if (old != null && created)
- getPlayer().sendPacket(removeLine(old));
- team.setValue(value);
- sendLine(line);
- }
- /**
- * Remove a given scoreboard line
- * @param line the line to remove
- */
- public void removeLine(int line) {
- VirtualTeam team = getOrCreateTeam(line);
- String old = team.getCurrentPlayer();
- if (old != null && created) {
- getPlayer().sendPacket(removeLine(old));
- getPlayer().sendPacket(team.removeTeam());
- }
- lines[line] = null;
- }
- /**
- * Get the current value for a line
- * @param line the line
- * @return the content of the line
- */
- public String getLine(int line) {
- if (line > 14)
- return null;
- if (line < 0)
- return null;
- return getOrCreateTeam(line).getValue();
- }
- /**
- * Get the team assigned to a line
- * @return the {@link VirtualTeam} used to display this line
- */
- public VirtualTeam getTeam(int line) {
- if (line > 14)
- return null;
- if (line < 0)
- return null;
- return getOrCreateTeam(line);
- }
- private PlayerConnection getPlayer() {
- return ((CraftPlayer) player).getHandle().playerConnection;
- }
- private void sendLine(int line) {
- if (line > 14)
- return;
- if (line < 0)
- return;
- if (!created)
- return;
- int score = (15 - line);
- VirtualTeam val = getOrCreateTeam(line);
- for (Packet packet : val.sendLine())
- getPlayer().sendPacket(packet);
- getPlayer().sendPacket(sendScore(val.getCurrentPlayer(), score));
- val.reset();
- }
- private VirtualTeam getOrCreateTeam(int line) {
- if (lines[line] == null)
- lines[line] = new VirtualTeam("__fakeScore" + line);
- return lines[line];
- }
- /*
- Factories
- */
- private PacketPlayOutScoreboardObjective createObjectivePacket(int mode, String displayName) {
- PacketPlayOutScoreboardObjective packet = new PacketPlayOutScoreboardObjective();
- // Nom de l'objectif
- setField(packet, "a", player.getName());
- // Mode
- // 0 : créer
- // 1 : Supprimer
- // 2 : Mettre à jour
- setField(packet, "d", mode);
- if (mode == 0 || mode == 2) {
- setField(packet, "b", displayName);
- setField(packet, "c", IScoreboardCriteria.EnumScoreboardHealthDisplay.INTEGER);
- }
- return packet;
- }
- private PacketPlayOutScoreboardDisplayObjective setObjectiveSlot() {
- PacketPlayOutScoreboardDisplayObjective packet = new PacketPlayOutScoreboardDisplayObjective();
- // Slot
- setField(packet, "a", 1);
- setField(packet, "b", player.getName());
- return packet;
- }
- private PacketPlayOutScoreboardScore sendScore(String line, int score) {
- PacketPlayOutScoreboardScore packet = new PacketPlayOutScoreboardScore(line);
- setField(packet, "b", player.getName());
- setField(packet, "c", score);
- setField(packet, "d", PacketPlayOutScoreboardScore.EnumScoreboardAction.CHANGE);
- return packet;
- }
- private PacketPlayOutScoreboardScore removeLine(String line) {
- return new PacketPlayOutScoreboardScore(line);
- }
- /**
- * This class is used to manage the content of a line. Advanced users can use it as they want, but they are encouraged to read and understand the
- * code before doing so. Use these methods at your own risk.
- */
- public class VirtualTeam {
- private final String name;
- private String prefix;
- private String suffix;
- private String currentPlayer;
- private String oldPlayer;
- private boolean prefixChanged, suffixChanged, playerChanged = false;
- private boolean first = true;
- private VirtualTeam(String name, String prefix, String suffix) {
- this.name = name;
- this.prefix = prefix;
- this.suffix = suffix;
- }
- private VirtualTeam(String name) {
- this(name, "", "");
- }
- public String getName() {
- return name;
- }
- public String getPrefix() {
- return prefix;
- }
- public void setPrefix(String prefix) {
- if (this.prefix == null || !this.prefix.equals(prefix))
- this.prefixChanged = true;
- this.prefix = prefix;
- }
- public String getSuffix() {
- return suffix;
- }
- public void setSuffix(String suffix) {
- if (this.suffix == null || !this.suffix.equals(prefix))
- this.suffixChanged = true;
- this.suffix = suffix;
- }
- private PacketPlayOutScoreboardTeam createPacket(int mode) {
- PacketPlayOutScoreboardTeam packet = new PacketPlayOutScoreboardTeam();
- setField(packet, "a", name);
- setField(packet, "h", mode);
- setField(packet, "b", "");
- setField(packet, "c", prefix);
- setField(packet, "d", suffix);
- setField(packet, "i", 0);
- setField(packet, "e", "always");
- setField(packet, "f", 0);
- return packet;
- }
- public PacketPlayOutScoreboardTeam createTeam() {
- return createPacket(0);
- }
- public PacketPlayOutScoreboardTeam updateTeam() {
- return createPacket(2);
- }
- public PacketPlayOutScoreboardTeam removeTeam() {
- PacketPlayOutScoreboardTeam packet = new PacketPlayOutScoreboardTeam();
- setField(packet, "a", name);
- setField(packet, "h", 1);
- first = true;
- return packet;
- }
- public void setPlayer(String name) {
- if (this.currentPlayer == null || !this.currentPlayer.equals(name))
- this.playerChanged = true;
- this.oldPlayer = this.currentPlayer;
- this.currentPlayer = name;
- }
- public Iterable<PacketPlayOutScoreboardTeam> sendLine() {
- List<PacketPlayOutScoreboardTeam> packets = new ArrayList<>();
- if (first) {
- packets.add(createTeam());
- } else if (prefixChanged || suffixChanged) {
- packets.add(updateTeam());
- }
- if (first || playerChanged) {
- if (oldPlayer != null) // remove these two lines ?
- packets.add(addOrRemovePlayer(4, oldPlayer)); //
- packets.add(changePlayer());
- }
- if (first)
- first = false;
- return packets;
- }
- public void reset() {
- prefixChanged = false;
- suffixChanged = false;
- playerChanged = false;
- oldPlayer = null;
- }
- public PacketPlayOutScoreboardTeam changePlayer() {
- return addOrRemovePlayer(3, currentPlayer);
- }
- public PacketPlayOutScoreboardTeam addOrRemovePlayer(int mode, String playerName) {
- PacketPlayOutScoreboardTeam packet = new PacketPlayOutScoreboardTeam();
- setField(packet, "a", name);
- setField(packet, "h", mode);
- try {
- Field f = packet.getClass().getDeclaredField("g");
- f.setAccessible(true);
- ((List<String>) f.get(packet)).add(playerName);
- } catch (NoSuchFieldException | IllegalAccessException e) {
- e.printStackTrace();
- }
- return packet;
- }
- public String getCurrentPlayer() {
- return currentPlayer;
- }
- public String getValue() {
- return getPrefix() + getCurrentPlayer() + getSuffix();
- }
- public void setValue(String value) {
- if (value.length() <= 16) {
- setPrefix("");
- setSuffix("");
- setPlayer(value);
- } else if (value.length() <= 32) {
- setPrefix(value.substring(0, 16));
- setPlayer(value.substring(16));
- setSuffix("");
- } else if (value.length() <= 48) {
- setPrefix(value.substring(0, 16));
- setPlayer(value.substring(16, 32));
- setSuffix(value.substring(32));
- } else {
- throw new IllegalArgumentException("Too long value ! Max 48 characters, value was " + value.length() + " !");
- }
- }
- }
- private static void setField(Object edit, String fieldName, Object value) {
- try {
- Field field = edit.getClass().getDeclaredField(fieldName);
- field.setAccessible(true);
- field.set(edit, value);
- } catch (NoSuchFieldException | IllegalAccessException e) {
- e.printStackTrace();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement