From 716de207c82cc2968ee9745af65aba047186dec5 Mon Sep 17 00:00:00 2001 From: NeT32 Date: Tue, 4 Nov 2014 04:54:21 -0200 Subject: [PATCH] TabAPI for Spigot #1649 - 1.7 and 1.8 ready --- .../mcsg/double0negative/tabapi/TabAPI.java | 290 ++++++++++++------ .../double0negative/tabapi/TabHolder47.java | 75 +++++ .../double0negative/tabapi/TabObject47.java | 73 +++++ 3 files changed, 344 insertions(+), 94 deletions(-) create mode 100644 TabAPI/src/main/java/org/mcsg/double0negative/tabapi/TabHolder47.java create mode 100644 TabAPI/src/main/java/org/mcsg/double0negative/tabapi/TabObject47.java diff --git a/TabAPI/src/main/java/org/mcsg/double0negative/tabapi/TabAPI.java b/TabAPI/src/main/java/org/mcsg/double0negative/tabapi/TabAPI.java index bf79205..d62d71c 100644 --- a/TabAPI/src/main/java/org/mcsg/double0negative/tabapi/TabAPI.java +++ b/TabAPI/src/main/java/org/mcsg/double0negative/tabapi/TabAPI.java @@ -23,6 +23,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerKickEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginDescriptionFile; @@ -41,10 +42,14 @@ public class TabAPI extends JavaPlugin implements Listener, CommandExecutor { private static HashMap playerTab = new HashMap(); private static HashMap playerTabLast = new HashMap(); + private static HashMap playerTab47 = new HashMap(); + private static HashMap playerTabLast47 = new HashMap(); private static HashMap> cachedPackets = new HashMap>(); private static HashMap updateSchedules = new HashMap(); - private static int horzTabSize = 3; + private static int horizTabSize = 3; private static int vertTabSize = 20; + private static int horizTabSize47 = 4; + private static int vertTabSize47 = 20; private static String[] colors = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "a", "b", "c", "d", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "r", "s", "t", "u", "v", "w", "x", "y", "z" @@ -52,7 +57,7 @@ public class TabAPI extends JavaPlugin implements Listener, CommandExecutor { private static int e = 0; private static int r = 0; private static long flickerPrevention = 5L; - private static ProtocolManager protocolManager; + public static ProtocolManager protocolManager; private static boolean shuttingdown = false; private static TabAPI plugin; @@ -97,24 +102,17 @@ public void onEnable() public void onPacketSending(PacketEvent event) { PacketContainer p = event.getPacket(); - if (protocolManager.getProtocolVersion(event.getPlayer()) >= 47) - { - // 1.8 > - String s = p.getStrings().read(0); - if (s.startsWith("$")) - { - event.setCancelled(true); - } + String s = p.getStrings().read(0); + if (s.startsWith("$")) + { // this is a packet sent by TabAPI **Work around until I figure out how to make my own + p.getStrings().write(0, s.substring(1)); // packets bypass this block** event.setPacket(p); } else { - // 1.7.10 < - String s = p.getStrings().read(0); - if (s.startsWith("$")) + if (protocolManager.getProtocolVersion(event.getPlayer()) >= 47) { - p.getStrings().write(0, s.substring(1)); - event.setPacket(p); + // send skins and entity normally in protocol 47 } else { @@ -142,6 +140,8 @@ public void onDisable() flushPackets(); playerTab = null; playerTabLast = null; + playerTab47 = null; + playerTabLast47 = null; } @Override @@ -159,66 +159,25 @@ public boolean onCommand(CommandSender sender, Command cmd1, String commandLabel } else { - player.sendMessage(ChatColor.DARK_RED + "" + ChatColor.BOLD + "TabAPI - Double0negative" + ChatColor.RESET + ChatColor.RED + " Version: " + pdfFile.getVersion()); - int iii = 0; - for (int i = 0; i <= 19; i++) - { - PacketContainer message = protocolManager.createPacket(PacketType.Play.Server.PLAYER_INFO); - String msg = "-" + iii; - String nameToShow = ((!shuttingdown) ? "$" : "") + msg; - boolean b = true; - int ping = 0; - int action; - if (b) - { - action = 0; - } - else - { - action = 4; - } - message.getIntegers().write(0, action); // int - ACTION - message.getGameProfiles().write(0, new WrappedGameProfile(java.util.UUID.nameUUIDFromBytes(("OfflinePlayer:" + nameToShow).getBytes(Charsets.UTF_8)), nameToShow)); - message.getIntegers().write(1, 0); // int - GAMEMODE - message.getIntegers().write(2, ping); // int - PING - message.getStrings().write(0, nameToShow); // string - DISPLAYNAME - try - { - protocolManager.sendServerPacket(player, message); - } - catch (InvocationTargetException e) - { - throw new RuntimeException("Cannot send packet " + message, e); - } - iii++; - } + player.sendMessage(ChatColor.DARK_RED + "" + ChatColor.BOLD + "TabAPI - Double0negative, NeT32" + ChatColor.RESET + ChatColor.RED + " Version: " + pdfFile.getVersion()); } } else { - sender.sendMessage(ChatColor.DARK_RED + "" + ChatColor.BOLD + "TabAPI - Double0negative" + ChatColor.RESET + ChatColor.RED + " Version: " + pdfFile.getVersion()); + sender.sendMessage(ChatColor.DARK_RED + "" + ChatColor.BOLD + "TabAPI - Double0negative, NeT32" + ChatColor.RESET + ChatColor.RED + " Version: " + pdfFile.getVersion()); return true; } return true; } - private static void addPacket(Player p, String msg, boolean b, int ping) + private static void addPacket(Player p, String msg, int slotId, WrappedGameProfile gameProfile, boolean b, int ping) { PacketContainer message = protocolManager.createPacket(PacketType.Play.Server.PLAYER_INFO); String nameToShow = ((!shuttingdown) ? "$" : "") + msg; - // 1.8 > - /* - getIntegers = 3 - getStrings = 1 - getModifier = 5 - [ - int - class net.minecraft.util.com.mojang.authlib.GameProfile - int - int - class java.lang.String - ] - */ + if (protocolManager.getProtocolVersion(p) >= 47) + { + nameToShow = ((!shuttingdown) ? "$" : "") + ChatColor.DARK_GRAY + "" + slotId + ": " + msg.substring(0, Math.min(msg.length(), 10)); + } int action; if (b) { @@ -229,7 +188,14 @@ class java.lang.String action = 4; } message.getIntegers().write(0, action); // int - ACTION - message.getGameProfiles().write(0, new WrappedGameProfile(java.util.UUID.nameUUIDFromBytes(("OfflinePlayer:" + nameToShow).getBytes(Charsets.UTF_8)), nameToShow)); + if (gameProfile != null) + { + message.getGameProfiles().write(0, gameProfile.withName(nameToShow.substring(1)).withId(java.util.UUID.nameUUIDFromBytes(("OfflinePlayer:" + nameToShow.substring(1)).getBytes(Charsets.UTF_8)).toString())); + } + else + { + message.getGameProfiles().write(0, new WrappedGameProfile(java.util.UUID.nameUUIDFromBytes(("OfflinePlayer:" + nameToShow.substring(1)).getBytes(Charsets.UTF_8)), nameToShow.substring(1))); + } message.getIntegers().write(1, 0); // int - GAMEMODE message.getIntegers().write(2, ping); // int - PING message.getStrings().write(0, nameToShow); // string - DISPLAYNAME @@ -252,7 +218,7 @@ private static void flushPackets() } } - private static void flushPackets(final Player p, final TabHolder tabCopy) + private static void flushPackets(final Player p, final Object tabCopy) { final PacketContainer[] packets = (PacketContainer[]) cachedPackets.get(p).toArray(new PacketContainer[0]); // cancel old task (prevents flickering) @@ -282,7 +248,14 @@ public void run() } if (tabCopy != null) { - playerTabLast.put(p.getName(), tabCopy); // we set this only if we really finally flush it (which is just now) + if (tabCopy instanceof TabHolder47) + { + playerTabLast47.put(p.getName(), (TabHolder47) tabCopy); // we set this only if we really finally flush it (which is just now) + } + else if (tabCopy instanceof TabHolder) + { + playerTabLast.put(p.getName(), (TabHolder) tabCopy); // we set this only if we really finally flush it (which is just now) + } } updateSchedules.remove(p); // we're done, no need to cancel this one on next run } @@ -303,6 +276,17 @@ private static TabObject getTab(Player p) return tabo; } + private static TabObject47 getTab47(Player p) + { + TabObject47 tabo = playerTab47.get(p.getName()); + if (tabo == null) + { + tabo = new TabObject47(); + playerTab47.put(p.getName(), tabo); + } + return tabo; + } + /** * Priorities * @@ -327,6 +311,7 @@ public static void setPriority(Plugin plugin, Player player, int pri) public static void disableTabForPlayer(Player p) { playerTab.put(p.getName(), null); + playerTab47.put(p.getName(), null); resetTabList(p); } @@ -343,7 +328,7 @@ public static void resetTabList(Player p) { setTabString(Bukkit.getPluginManager().getPlugin("TabAPI"), p, a, b, pl.getPlayerListName()); b++; - if (b > horzTabSize) + if (b > TabAPI.getHorizSize(protocolManager.getProtocolVersion(pl))) { b = 0; a++; @@ -353,7 +338,12 @@ public static void resetTabList(Player p) public static void setTabString(Plugin plugin, Player p, int x, int y, String msg) { - setTabString(plugin, p, x, y, msg, 0); + setTabString(plugin, p, x, y, msg, 0, null); + } + + public static void setTabString(Plugin plugin, Player p, int x, int y, String msg, int ping) + { + setTabString(plugin, p, x, y, msg, ping, null); } /** @@ -368,14 +358,24 @@ public static void setTabString(Plugin plugin, Player p, int x, int y, String ms * @param y * @param msg * @param ping + * @param gameProfile */ - public static void setTabString(Plugin plugin, Player p, int x, int y, String msg, int ping) + public static void setTabString(Plugin plugin, Player p, int x, int y, String msg, int ping, WrappedGameProfile gameProfile) { try { - TabObject tabo = getTab(p); - tabo.setTab(plugin, x, y, msg, ping); - playerTab.put(p.getName(), tabo); + if (protocolManager.getProtocolVersion(p) >= 47) + { + TabObject47 tabo = getTab47(p); + tabo.setTab(plugin, x, y, msg, ping, gameProfile); + playerTab47.put(p.getName(), tabo); + } + else + { + TabObject tabo = getTab(p); + tabo.setTab(plugin, x, y, msg, ping); + playerTab.put(p.getName(), tabo); + } } catch (Exception ex) { @@ -398,29 +398,59 @@ public static void updatePlayer(Player p) } r = 0; e = 0; - TabObject tabo = playerTab.get(p.getName()); - TabHolder tab = tabo.getTab(); - if (tab == null) + if (protocolManager.getProtocolVersion(p) >= 47) { - return; + TabObject47 tabo = playerTab47.get(p.getName()); + TabHolder47 tab = tabo.getTab(); + if (tab == null) + { + return; + } + /* need to clear the tab first */ + clearTab(p); + for (int b = 0; b < tab.maxv; b++) + { + for (int a = 0; a < tab.maxh; a++) + { + // fix empty tabs + if (tab.tabs[a][b] == null) + { + tab.tabs[a][b] = nextNull(); + } + String msg = tab.tabs[a][b]; + int ping = tab.tabPings[a][b]; + WrappedGameProfile gameProfile = tab.tabGameProfiles[a][b]; + addPacket(p, (msg == null) ? " " : msg.substring(0, Math.min(msg.length(), 16)), getSlotId(b, a), gameProfile, true, ping); + } + } + flushPackets(p, tab.getCopy()); } - /* need to clear the tab first */ - clearTab(p); - for (int b = 0; b < tab.maxv; b++) + else { - for (int a = 0; a < tab.maxh; a++) + TabObject tabo = playerTab.get(p.getName()); + TabHolder tab = tabo.getTab(); + if (tab == null) { - // fix empty tabs - if (tab.tabs[a][b] == null) + return; + } + /* need to clear the tab first */ + clearTab(p); + for (int b = 0; b < tab.maxv; b++) + { + for (int a = 0; a < tab.maxh; a++) { - tab.tabs[a][b] = nextNull(); + // fix empty tabs + if (tab.tabs[a][b] == null) + { + tab.tabs[a][b] = nextNull(); + } + String msg = tab.tabs[a][b]; + int ping = tab.tabPings[a][b]; + addPacket(p, (msg == null) ? " " : msg.substring(0, Math.min(msg.length(), 16)), 0, null, true, ping); } - String msg = tab.tabs[a][b]; - int ping = tab.tabPings[a][b]; - addPacket(p, (msg == null) ? " " : msg.substring(0, Math.min(msg.length(), 16)), true, ping); } + flushPackets(p, tab.getCopy()); } - flushPackets(p, tab.getCopy()); } /** @@ -434,16 +464,35 @@ public static void clearTab(Player p) { return; } - TabHolder tabold = playerTabLast.get(p.getName()); - if (tabold != null) + if (protocolManager.getProtocolVersion(p) >= 47) { - for (String[] s : tabold.tabs) + TabHolder47 tabold = playerTabLast47.get(p.getName()); + if (tabold != null) { - for (String msg : s) + for (int b = 0; b < tabold.maxv; b++) { - if (msg != null) + for (int a = 0; a < tabold.maxh; a++) { - addPacket(p, msg.substring(0, Math.min(msg.length(), 16)), false, 0); + String msg = tabold.tabs[a][b]; + WrappedGameProfile gameProfile = tabold.tabGameProfiles[a][b]; + addPacket(p, msg.substring(0, Math.min(msg.length(), 16)), getSlotId(b, a), gameProfile, false, 0); + } + } + } + } + else + { + TabHolder tabold = playerTabLast.get(p.getName()); + if (tabold != null) + { + for (String[] s : tabold.tabs) + { + for (String msg : s) + { + if (msg != null) + { + addPacket(p, msg.substring(0, Math.min(msg.length(), 16)), 0, null, false, 0); + } } } } @@ -483,15 +532,68 @@ public void PlayerLeave(PlayerQuitEvent e) //cleanup playerTab.remove(e.getPlayer().getName()); playerTabLast.remove(e.getPlayer().getName()); + playerTab47.remove(e.getPlayer().getName()); + playerTabLast47.remove(e.getPlayer().getName()); + } + + @EventHandler + public void PlayerKick(PlayerKickEvent e) + { + //cleanup + playerTab.remove(e.getPlayer().getName()); + playerTabLast.remove(e.getPlayer().getName()); + playerTab47.remove(e.getPlayer().getName()); + playerTabLast47.remove(e.getPlayer().getName()); } + @Deprecated public static int getVertSize() { return vertTabSize; } + @Deprecated public static int getHorizSize() { - return horzTabSize; + return horizTabSize; + } + + public static int getVertSize(int protocol) + { + if (protocol >= 47) + { + return vertTabSize47; + } + return vertTabSize; + } + + public static int getHorizSize(int protocol) + { + if (protocol >= 47) + { + return horizTabSize47; + } + return horizTabSize; + } + + public static int getSlotId(int x, int y) + { + if (y == 0) + { + return 11 + x; + } + if (y == 1) + { + return 31 + x; + } + if (y == 2) + { + return 51 + x; + } + if (y == 3) + { + return 71 + x; + } + return 0; } } diff --git a/TabAPI/src/main/java/org/mcsg/double0negative/tabapi/TabHolder47.java b/TabAPI/src/main/java/org/mcsg/double0negative/tabapi/TabHolder47.java new file mode 100644 index 0000000..6f7747c --- /dev/null +++ b/TabAPI/src/main/java/org/mcsg/double0negative/tabapi/TabHolder47.java @@ -0,0 +1,75 @@ +package org.mcsg.double0negative.tabapi; + +import com.comphenix.protocol.wrappers.WrappedGameProfile; +import org.bukkit.plugin.Plugin; + +/** + * + * @author NeT32 + */ +class TabHolder47 { + + Plugin p; + String[][] tabs; + int[][] tabPings; + WrappedGameProfile[][] tabGameProfiles; + int maxh = 0, maxv = 0; + + public TabHolder47(Plugin p) + { + this.p = p; + this.tabs = new String[TabAPI.getHorizSize(47)][TabAPI.getVertSize(47)]; + this.tabPings = new int[TabAPI.getHorizSize(47)][TabAPI.getVertSize(47)]; + this.tabGameProfiles = new WrappedGameProfile[TabAPI.getHorizSize(47)][TabAPI.getVertSize(47)]; + this.maxh = TabAPI.getHorizSize(47); + this.maxv = TabAPI.getVertSize(47); + for (int b = 0; b < this.maxv; b++) + { + for (int a = 0; a < this.maxh; a++) + { + this.tabs[a][b] = " "; + this.tabPings[a][b] = 9999; + this.tabGameProfiles[a][b] = null; + } + } + } + + public TabHolder47 getCopy() + { + TabHolder47 newCopy = new TabHolder47(p); + newCopy.tabs = copyStringArray(tabs); + newCopy.tabPings = copyIntArray(tabPings); + return newCopy; + } + + /* Util method, copy tab array to new array */ + private static String[][] copyStringArray(String[][] tab) + { + int horzTabSize = TabAPI.getHorizSize(47); + int vertTabSize = TabAPI.getVertSize(47); + String[][] temp = new String[horzTabSize][vertTabSize]; + for (int b = 0; b < vertTabSize; b++) + { + for (int a = 0; a < horzTabSize; a++) + { + temp[a][b] = tab[a][b]; + } + } + return temp; + } + + private static int[][] copyIntArray(int[][] tab) + { + int horzTabSize = TabAPI.getHorizSize(47); + int vertTabSize = TabAPI.getVertSize(47); + int[][] temp = new int[horzTabSize][vertTabSize]; + for (int b = 0; b < vertTabSize; b++) + { + for (int a = 0; a < horzTabSize; a++) + { + temp[a][b] = tab[a][b]; + } + } + return temp; + } +} diff --git a/TabAPI/src/main/java/org/mcsg/double0negative/tabapi/TabObject47.java b/TabAPI/src/main/java/org/mcsg/double0negative/tabapi/TabObject47.java new file mode 100644 index 0000000..25bb478 --- /dev/null +++ b/TabAPI/src/main/java/org/mcsg/double0negative/tabapi/TabObject47.java @@ -0,0 +1,73 @@ +package org.mcsg.double0negative.tabapi; + +import com.comphenix.protocol.wrappers.WrappedGameProfile; +import java.util.HashMap; +import org.bukkit.plugin.Plugin; + +/** + * + * @author NeT32 + */ +public class TabObject47 { + + /** + * Holds a list of tab information for a player. + * + * + */ + HashMap tabs = new HashMap(); + + public void setPriority(Plugin p, int pri) + { + //System.out.println("Settings pri for "+p.getName()+": "+pri); + for (int a = -1; a < 4; a++) + { + if (tabs.get(a) != null && tabs.get(a).p == p) + { + tabs.put(a, null); + } + } + if (pri > -2) + { + TabHolder47 t = new TabHolder47(p); + tabs.put(pri, t); + } + } + + public TabHolder47 getTab() + { + int a = 3; + while (tabs.get(a) == null && a > -3) + { + a--; + } + if (a == -2) + { + return new TabHolder47(null); + } + //System.out.print("Getting tab "+a+" "+tabs.get(a).p.getName()); + return tabs.get(a); + } + + public void setTab(Plugin plugin, int x, int y, String msg, int ping, WrappedGameProfile gameProfile) + { + int a = -1; + while ((tabs.get(a) == null || tabs.get(a).p != plugin) && a < 3) + { + a++; + } + if (a == 3 && (tabs.get(a) == null || tabs.get(a).p != plugin)) + { + //System.out.println("Reseting Pri"); + setPriority(plugin, 0); + a = 0; + } + //System.out.println(plugin.getName()+": "+a); + TabHolder47 t = tabs.get(a); + t.tabs[y][x] = msg; + t.tabPings[y][x] = ping; + t.tabGameProfiles[y][x] = gameProfile; + t.maxh = TabAPI.getHorizSize(47); + t.maxv = Math.max(x + 1, t.maxv); + } +}