Created
June 26, 2016 09:37
-
-
Save hugo4715/3fae9b2c8f049ac951d476e74694a048 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package fr.hugo4715.crackedskywars.scoreboard; | |
| import java.lang.reflect.Constructor; | |
| import java.lang.reflect.Field; | |
| import java.lang.reflect.InvocationTargetException; | |
| import java.util.Collection; | |
| import org.apache.commons.lang.Validate; | |
| import org.bukkit.ChatColor; | |
| import org.bukkit.entity.Player; | |
| import fr.hugo4715.crackedskywars.util.PacketUtil; | |
| import fr.hugo4715.crackedskywars.util.Reflection; | |
| /** | |
| * @author zyuiop | |
| * @author Seveningful | |
| * @author Hugo4715 | |
| */ | |
| public class ScoreboardSign { | |
| private Class<?> classPacketPlayOutScoreboardScore = Reflection.getClass("{nms}.PacketPlayOutScoreboardScore"); | |
| private Constructor<?> constructorPacketPlayOutScoreboardScore; | |
| private Class<?> classPacketPlayOutScoreboardScoreEnumScoreboardAction = Reflection.getClass("{nms}.PacketPlayOutScoreboardScore").getClasses()[0]; | |
| private Class<?> classPacketPlayOutScoreboardTeam = Reflection.getClass("{nms}.PacketPlayOutScoreboardTeam"); | |
| private Constructor<?> constructorPacketPlayOutScoreboardTeam; | |
| private boolean created = false; | |
| private String[] lines = new String[16]; | |
| private Object[] teams = new Object[16];//acketPlayOutScoreboardTeam | |
| private final Player player; | |
| private String objectiveName; | |
| public ScoreboardSign(Player player, String objectiveName) { | |
| this.player = player; | |
| this.objectiveName = objectiveName; | |
| init(); | |
| } | |
| private void init() { | |
| try { | |
| constructorPacketPlayOutScoreboardScore = classPacketPlayOutScoreboardScore.getConstructor(String.class); | |
| } catch (NoSuchMethodException | SecurityException e) { | |
| e.printStackTrace(); | |
| } | |
| try { | |
| constructorPacketPlayOutScoreboardTeam = classPacketPlayOutScoreboardTeam.getDeclaredConstructor(); | |
| } catch (NoSuchMethodException | SecurityException e) { | |
| e.printStackTrace(); | |
| } | |
| } | |
| public ScoreboardSign(Player player, String objectiveName, String[] lines) { | |
| this.player = player; | |
| this.objectiveName = objectiveName; | |
| this.lines = lines; | |
| init(); | |
| } | |
| public void create() { | |
| if (created) return; | |
| PacketUtil.getInstance().sendPacket(player,createObjectivePacket(0, objectiveName)); | |
| PacketUtil.getInstance().sendPacket(player, setObjectiveSlot()); | |
| int i = 0; | |
| while (i < lines.length) | |
| { | |
| sendLine(i++); | |
| } | |
| created = true; | |
| } | |
| public void destroy() { | |
| if (!created) | |
| return; | |
| PacketUtil.getInstance().sendPacket(player, createObjectivePacket(1, null)); | |
| created = false; | |
| } | |
| private Object sendLine(int line) { | |
| if (line > 15) | |
| return null; | |
| if (line < 0) | |
| return null; | |
| if (!created) | |
| return null; | |
| Object teamPacket = apply(line); | |
| int score = 15-line; | |
| PacketUtil.getInstance().sendPacket(player, teamPacket); | |
| return sendScore(ChatColor.values()[line].toString() + ChatColor.RESET , score); | |
| } | |
| public void setObjectiveName(String name) { | |
| this.objectiveName = name; | |
| if (created) | |
| PacketUtil.getInstance().sendPacket(player, createObjectivePacket(2, name)); | |
| } | |
| public void setLine(int line, String value) { | |
| lines[line] = value; | |
| PacketUtil.getInstance().sendPacket(player, sendLine(line)); | |
| } | |
| public void removeLine(int line) { | |
| String oldLine = getLine(line); | |
| if (oldLine != null && created) | |
| PacketUtil.getInstance().sendPacket(player, removeLine(oldLine)); | |
| lines[line] = null; | |
| } | |
| public String getLine(int line) { | |
| if (line > 15) | |
| return null; | |
| if (line < 0) | |
| return null; | |
| return lines[line]; | |
| } | |
| /* | |
| Factories | |
| */ | |
| /** | |
| * | |
| * @param mode | |
| * @param displayName | |
| * @return PacketPlayOutScoreboardObjective as object | |
| */ | |
| private Object createObjectivePacket(int mode, String displayName) { | |
| Class<?> classPacketPlayOutScoreboardObjective = Reflection.getClass("{nms}.PacketPlayOutScoreboardObjective"); | |
| Object packet = null; | |
| try { | |
| packet = classPacketPlayOutScoreboardObjective.newInstance(); | |
| } catch (InstantiationException e1) { | |
| e1.printStackTrace(); | |
| return null; | |
| } catch (IllegalAccessException e1) { | |
| e1.printStackTrace(); | |
| return null; | |
| } | |
| //PacketPlayOutScoreboardObjective packet = new PacketPlayOutScoreboardObjective(); | |
| try { | |
| // Nom de l'objectif | |
| Field name = packet.getClass().getDeclaredField("a"); | |
| name.setAccessible(true); | |
| name.set(packet, player.getName()); | |
| // Mode | |
| // 0 : créer | |
| // 1 : Supprimer | |
| // 2 : Mettre à jour | |
| Field modeField = packet.getClass().getDeclaredField("d"); | |
| modeField.setAccessible(true); | |
| modeField.set(packet, mode); | |
| if (mode == 0 || mode == 2) { | |
| Field displayNameField = packet.getClass().getDeclaredField("b"); | |
| displayNameField.setAccessible(true); | |
| displayNameField.set(packet, displayName); | |
| Field display = packet.getClass().getDeclaredField("c"); | |
| display.setAccessible(true); | |
| Class<?> iScoreboardCriteria = Reflection.getClass("{nms}.IScoreboardCriteria").getDeclaredClasses()[0]; | |
| Object i = iScoreboardCriteria.getEnumConstants()[0]; | |
| display.set(packet, i); | |
| } | |
| } catch (NoSuchFieldException | IllegalAccessException e) { | |
| e.printStackTrace(); | |
| } | |
| return packet; | |
| } | |
| /** | |
| * @return PacketPlayOutScoreboardDisplayObjective as object | |
| */ | |
| private Object setObjectiveSlot() { | |
| Object packet; | |
| try { | |
| packet = Reflection.getClass("{nms}.PacketPlayOutScoreboardDisplayObjective").newInstance(); | |
| } catch (InstantiationException e1) { | |
| e1.printStackTrace(); | |
| return null; | |
| } catch (IllegalAccessException e1) { | |
| e1.printStackTrace(); | |
| return null; | |
| } | |
| //PacketPlayOutScoreboardDisplayObjective packet = new PacketPlayOutScoreboardDisplayObjective(); | |
| try { | |
| // Slot de l'objectif | |
| Field position = packet.getClass().getDeclaredField("a"); | |
| position.setAccessible(true); | |
| position.set(packet, 1); // SideBar | |
| Field name = packet.getClass().getDeclaredField("b"); | |
| name.setAccessible(true); | |
| name.set(packet, player.getName()); | |
| } catch (NoSuchFieldException | IllegalAccessException e) { | |
| e.printStackTrace(); | |
| } | |
| return packet; | |
| } | |
| /** | |
| * | |
| * @param line | |
| * @param score | |
| * @return PacketPlayOutScoreboardScore as object | |
| */ | |
| private Object sendScore(String line, int score) { | |
| Object packet; | |
| try { | |
| packet = constructorPacketPlayOutScoreboardScore.newInstance(line); | |
| } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) { | |
| e1.printStackTrace(); | |
| return null; | |
| } | |
| //PacketPlayOutScoreboardScore packet = new PacketPlayOutScoreboardScore(line); | |
| try { | |
| Field name = packet.getClass().getDeclaredField("b"); | |
| name.setAccessible(true); | |
| name.set(packet, player.getName()); | |
| Field scoreField = packet.getClass().getDeclaredField("c"); | |
| scoreField.setAccessible(true); | |
| scoreField.set(packet, score); // SideBar | |
| Field action = packet.getClass().getDeclaredField("d"); | |
| action.setAccessible(true); | |
| action.set(packet, classPacketPlayOutScoreboardScoreEnumScoreboardAction.getEnumConstants()[0]); | |
| } catch (NoSuchFieldException | IllegalAccessException e) { | |
| e.printStackTrace(); | |
| } | |
| return packet; | |
| } | |
| /** | |
| * @param line | |
| * @return PacketPlayOutScoreboardScore as Object | |
| */ | |
| private Object removeLine(String line) { | |
| try { | |
| return constructorPacketPlayOutScoreboardScore.newInstance(line); | |
| } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | |
| | InvocationTargetException e) { | |
| e.printStackTrace(); | |
| } | |
| return null; | |
| } | |
| public Player getBukkitPlayer() { | |
| return player; | |
| } | |
| public String getDisplayName() { | |
| return objectiveName; | |
| } | |
| public String[] getLines() { | |
| return lines; | |
| } | |
| private String[] splitString(String string) | |
| { | |
| Validate.isTrue(string.length() <= 32, "String can't have more than 32 characters " ); | |
| if (string.isEmpty()) { | |
| return new String[] { " ", "" }; | |
| } | |
| StringBuilder prefix = new StringBuilder(string.substring(0, string.length() >= 16 ? 16 : string.length())); | |
| StringBuilder suffix = new StringBuilder(string.length() > 16 ? string.substring(16) : ""); | |
| if (prefix.charAt(prefix.length() - 1) == '§') | |
| { | |
| prefix.deleteCharAt(prefix.length() - 1); | |
| suffix.insert(0, '§'); | |
| } | |
| if(!suffix.toString().isEmpty()) | |
| suffix.insert(0, ChatColor.getLastColors(prefix.toString())); | |
| return new String[] { prefix.toString().length() > 16 ? prefix.toString().substring(0, 16) : prefix.toString(), suffix.toString().length() > 16 ? suffix.toString().substring(0, 16) : suffix.toString() }; | |
| } | |
| /** | |
| * | |
| * @param line | |
| * @return PacketPlayOutScoreboardTeam as Object | |
| */ | |
| private Object apply(int line){ | |
| if(teams[line] != null) | |
| { | |
| setField(getTeamLine(line),"i", 2); | |
| setField(getTeamLine(line), "c", splitString(getLine(line))[0]); | |
| setField(getTeamLine(line), "d", splitString(getLine(line))[1]); | |
| } | |
| return getTeamLine(line); | |
| } | |
| /** | |
| * | |
| * @param line | |
| * @return PacketPlayOutScoreboardTeam as Object | |
| */ | |
| private Object getTeamLine(int line) { | |
| if(teams[line] == null) | |
| { | |
| //PacketPlayOutScoreboardTeam team = new PacketPlayOutScoreboardTeam(); | |
| Object team = null;; | |
| try { | |
| team = constructorPacketPlayOutScoreboardTeam.newInstance(); | |
| } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | |
| | InvocationTargetException e) { | |
| e.printStackTrace(); | |
| return null; | |
| } | |
| setField(team, "a", line + ""); | |
| setField(team, "b", line + ""); | |
| setField(team, "c", splitString(getLine(line))[0]); | |
| setField(team, "d", splitString(getLine(line))[1]); | |
| addEntry(team, ChatColor.values()[line].toString() + ChatColor.RESET); | |
| teams[line] = team; | |
| } | |
| return teams[line]; | |
| } | |
| private static void setField(Object packet, String field, Object value) { | |
| try { | |
| Field f = packet.getClass().getDeclaredField(field); | |
| f.setAccessible(true); | |
| f.set(packet, value); | |
| f.setAccessible(false); | |
| } catch (Exception ex) {ex.printStackTrace();} | |
| } | |
| /** | |
| * @param packet PacketPlayOutScoreboardTeam as Object | |
| */ | |
| private void addEntry(Object packet, String entry) { | |
| Field f = null; | |
| try { | |
| f = packet.getClass().getDeclaredField("h");//g in 1.8 | |
| f.setAccessible(true); | |
| System.out.println(f.get(packet).getClass().getName()); | |
| ((Collection) f.get(packet)).add(entry); | |
| } catch (NoSuchFieldException e) { | |
| e.printStackTrace(); | |
| } catch (IllegalAccessException e) { | |
| e.printStackTrace(); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment