diff --git a/src/main/java/us/ajg0702/queue/Main.java b/src/main/java/us/ajg0702/queue/Main.java index 525f268..00e0a0e 100644 --- a/src/main/java/us/ajg0702/queue/Main.java +++ b/src/main/java/us/ajg0702/queue/Main.java @@ -20,6 +20,7 @@ import net.md_5.bungee.event.EventHandler; import us.ajg0702.queue.utils.BungeeConfig; import us.ajg0702.queue.utils.BungeeMessages; import us.ajg0702.queue.utils.BungeeStats; +import us.ajg0702.queue.utils.BungeeUtils; public class Main extends Plugin implements Listener { @@ -47,6 +48,8 @@ public class Main extends Plugin implements Listener { this.getProxy().getPluginManager().registerListener(this, this); + getProxy().registerChannel("ajqueue:tospigot"); + timeBetweenPlayers = config.getInt("wait-time"); updateOnlineServers(); @@ -115,14 +118,13 @@ public class Main extends Plugin implements Listener { int pos = plys.indexOf(ply)+1; if(pos == 0) continue; int len = plys.size(); + String or = msgs.get("status.offline.restarting"); + if(ot > config.getInt("offline-time")) { + or = msgs.get("status.offline.offline"); + } else { + //ply.sendMessage(formatMessage(ot + " <= "+offlineSecs)); + } if(notif) { - String or = msgs.get("status.offline.restarting"); - if(ot > config.getInt("offline-time")) { - or = msgs.get("status.offline.offline"); - } else { - //ply.sendMessage(formatMessage(ot + " <= "+offlineSecs)); - } - ply.sendMessage(formatMessage( msgs.get("status.offline.base") .replaceAll("\\{STATUS\\}", or) @@ -130,6 +132,12 @@ public class Main extends Plugin implements Listener { .replaceAll("\\{LEN\\}", len+"") )); } + if(getConfig().getBoolean("send-actionbar")) { + BungeeUtils.sendCustomData(ply, "actionbar", msgs.get("spigot.actionbar.offline") + .replaceAll("\\{POS\\}", pos+"") + .replaceAll("\\{LEN\\}", len+"") + .replaceAll("\\{STATUS\\}", or)+";time="+timeBetweenPlayers); + } } if(!notif) { notif = true; @@ -168,6 +176,12 @@ public class Main extends Plugin implements Listener { .replaceAll("\\{TIME\\}", timeStr) )); } + if(getConfig().getBoolean("send-actionbar")) { + BungeeUtils.sendCustomData(ply, "actionbar", msgs.get("spigot.actionbar.online") + .replaceAll("\\{POS\\}", pos+"") + .replaceAll("\\{LEN\\}", len+"") + .replaceAll("\\{TIME\\}", timeStr)+";time="+timeBetweenPlayers); + } } if(!notif) { notif = true; diff --git a/src/main/java/us/ajg0702/queue/spigot/Main.java b/src/main/java/us/ajg0702/queue/spigot/Main.java new file mode 100644 index 0000000..5687e79 --- /dev/null +++ b/src/main/java/us/ajg0702/queue/spigot/Main.java @@ -0,0 +1,44 @@ +package us.ajg0702.queue.spigot; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.plugin.messaging.PluginMessageListener; + +import com.google.common.io.ByteArrayDataInput; +import com.google.common.io.ByteStreams; + +import us.ajg0702.queue.spigot.utils.VersionSupport; + +public class Main extends JavaPlugin implements PluginMessageListener { + public void onEnable() { + getServer().getMessenger().registerIncomingPluginChannel(this, "ajqueue:tospigot", this); + getLogger().info("Spigot side enabled! v"+getDescription().getVersion()); + } + + @Override + public void onPluginMessageReceived(String channel, Player player, byte[] message) { + if (!channel.equals("ajqueue:tospigot")) return; + ByteArrayDataInput in = ByteStreams.newDataInput(message); + String subchannel = in.readUTF(); + if(subchannel.equals("actionbar")) { + String data = in.readUTF(); + VersionSupport.sendActionBar(player, data.split(";time=")[0]); + int time = Integer.parseInt(data.split(";time=")[1]); + if(time > 2) { + Bukkit.getScheduler().runTaskLater(this, new Runnable() { + public void run() { + VersionSupport.sendActionBar(player, data.split(";time=")[0]); + } + }, 2*20); + if(time > 4) { + Bukkit.getScheduler().runTaskLater(this, new Runnable() { + public void run() { + VersionSupport.sendActionBar(player, data.split(";time=")[0]); + } + }, 4*20); + } + } + } + } +} diff --git a/src/main/java/us/ajg0702/queue/spigot/utils/ActionBar.java b/src/main/java/us/ajg0702/queue/spigot/utils/ActionBar.java new file mode 100644 index 0000000..57e8652 --- /dev/null +++ b/src/main/java/us/ajg0702/queue/spigot/utils/ActionBar.java @@ -0,0 +1,71 @@ +package us.ajg0702.queue.spigot.utils; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +/** + * A cross-version actionbar class + * @author Based on ActionBarAPI from https://github.com/ConnorLinfoot + * + */ +public class ActionBar { + + private static String version; + private static boolean old; + + public static void send(Player player, String message) { + if(player == null) return; + if(!player.isOnline()) return; + + version = Bukkit.getServer().getClass().getPackage().getName(); + version = version.substring(version.lastIndexOf(".") + 1); + + old = version.equalsIgnoreCase("v1_8_R1") || version.startsWith("v1_7_"); + + try { + Class> craftPlayerClass = Class.forName("org.bukkit.craftbukkit." + version + ".entity.CraftPlayer"); + Object craftPlayer = craftPlayerClass.cast(player); + Object packet; + Class> packetPlayOutChatClass = Class.forName("net.minecraft.server." + version + ".PacketPlayOutChat"); + Class> packetClass = Class.forName("net.minecraft.server." + version + ".Packet"); + if (old) { + Class> chatSerializerClass = Class.forName("net.minecraft.server." + version + ".ChatSerializer"); + Class> iChatBaseComponentClass = Class.forName("net.minecraft.server." + version + ".IChatBaseComponent"); + Method m3 = chatSerializerClass.getDeclaredMethod("a", String.class); + Object cbc = iChatBaseComponentClass.cast(m3.invoke(chatSerializerClass, "{\"text\": \"" + message + "\"}")); + packet = packetPlayOutChatClass.getConstructor(new Class>[]{iChatBaseComponentClass, byte.class}).newInstance(cbc, (byte) 2); + } else { + Class> chatComponentTextClass = Class.forName("net.minecraft.server." + version + ".ChatComponentText"); + Class> iChatBaseComponentClass = Class.forName("net.minecraft.server." + version + ".IChatBaseComponent"); + try { + Class> chatMessageTypeClass = Class.forName("net.minecraft.server." + version + ".ChatMessageType"); + Object[] chatMessageTypes = chatMessageTypeClass.getEnumConstants(); + Object chatMessageType = null; + for (Object o : chatMessageTypes) { + if (o.toString().equals("GAME_INFO")) { + chatMessageType = o; + } + } + Object chatCompontentText = chatComponentTextClass.getConstructor(new Class>[]{String.class}).newInstance(message); + packet = packetPlayOutChatClass.getConstructor(new Class>[]{iChatBaseComponentClass, chatMessageTypeClass}).newInstance(chatCompontentText, chatMessageType); + } catch (ClassNotFoundException e) { + Object chatCompontentText = chatComponentTextClass.getConstructor(new Class>[]{String.class}).newInstance(message); + packet = packetPlayOutChatClass.getConstructor(new Class>[]{iChatBaseComponentClass, byte.class}).newInstance(chatCompontentText, (byte) 2); + } + } + Method craftPlayerHandleMethod = craftPlayerClass.getDeclaredMethod("getHandle"); + Object craftPlayerHandle = craftPlayerHandleMethod.invoke(craftPlayer); + Field playerConnectionField = craftPlayerHandle.getClass().getDeclaredField("playerConnection"); + Object playerConnection = playerConnectionField.get(craftPlayerHandle); + Method sendPacketMethod = playerConnection.getClass().getDeclaredMethod("sendPacket", packetClass); + sendPacketMethod.invoke(playerConnection, packet); + + } catch (Exception e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/src/main/java/us/ajg0702/queue/spigot/utils/VersionSupport.java b/src/main/java/us/ajg0702/queue/spigot/utils/VersionSupport.java new file mode 100644 index 0000000..ff3c551 --- /dev/null +++ b/src/main/java/us/ajg0702/queue/spigot/utils/VersionSupport.java @@ -0,0 +1,32 @@ +package us.ajg0702.queue.spigot.utils; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; + +public class VersionSupport { + + public static String getVersion() { + return Bukkit.getVersion().split("\\(MC: ")[1].split("\\)")[0]; + } + public static int getMinorVersion() { + return Integer.parseInt(getVersion().split("\\.")[1]); + } + + /** + * Send the player an actionbar message + * @param ply The {@link org.bukkit.entity.Player Player} to send the actionbar to + * @param message The message to send in the actionbar. + */ + public static void sendActionBar(Player ply, String message) { + // Use spigot version if available, otherwise use packets. + if(getMinorVersion() >= 11) { + ply.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(message)); + } else if(getMinorVersion() >= 8) { + ActionBar.send(ply, message); + } + } + +} diff --git a/src/main/java/us/ajg0702/queue/utils/BungeeConfig.java b/src/main/java/us/ajg0702/queue/utils/BungeeConfig.java index 1c4f910..9c4d4ee 100644 --- a/src/main/java/us/ajg0702/queue/utils/BungeeConfig.java +++ b/src/main/java/us/ajg0702/queue/utils/BungeeConfig.java @@ -59,6 +59,9 @@ public class BungeeConfig { } return r; } + public boolean getBoolean(String key) { + return config.getBoolean(key); + } public String getDefaultConfig() throws IOException { BufferedReader stream = new BufferedReader(new InputStreamReader(this.getClass().getResourceAsStream("/config.yml"))); diff --git a/src/main/java/us/ajg0702/queue/utils/BungeeMessages.java b/src/main/java/us/ajg0702/queue/utils/BungeeMessages.java index 25191a8..d561a2f 100644 --- a/src/main/java/us/ajg0702/queue/utils/BungeeMessages.java +++ b/src/main/java/us/ajg0702/queue/utils/BungeeMessages.java @@ -78,6 +78,9 @@ public class BungeeMessages { d.put("list.total", "&7Total players in queues: &f{TOTAL}"); d.put("list.none", "&7None"); + d.put("spigot.actionbar.online", "&7You are in position &f{POS}&7 of &f{LEN}&7. Estimated time: {TIME}"); + d.put("spigot.actionbar.offline", "&7You are in position &f{POS}&7 of &f{LEN}&7."); + d.put("send", "&aAdded &f{PLAYER}&a to the queue for &f{SERVER}"); diff --git a/src/main/java/us/ajg0702/queue/utils/BungeeStats.java b/src/main/java/us/ajg0702/queue/utils/BungeeStats.java index b505de6..4502833 100644 --- a/src/main/java/us/ajg0702/queue/utils/BungeeStats.java +++ b/src/main/java/us/ajg0702/queue/utils/BungeeStats.java @@ -24,7 +24,6 @@ import java.util.zip.GZIPOutputStream; *
* Check out https://bStats.org/ to learn more about bStats!
*/
-@SuppressWarnings({"WeakerAccess", "unused"})
public class BungeeStats {
static {
@@ -171,7 +170,8 @@ public class BungeeStats {
*
* @return The server specific data.
*/
- private JsonObject getServerData() {
+ @SuppressWarnings("deprecation")
+ private JsonObject getServerData() {
// Minecraft specific data
int playerAmount = Math.min(plugin.getProxy().getOnlineCount(), 500);
int onlineMode = plugin.getProxy().getConfig().isOnlineMode() ? 1 : 0;
diff --git a/src/main/java/us/ajg0702/queue/utils/BungeeUtils.java b/src/main/java/us/ajg0702/queue/utils/BungeeUtils.java
new file mode 100644
index 0000000..9623db4
--- /dev/null
+++ b/src/main/java/us/ajg0702/queue/utils/BungeeUtils.java
@@ -0,0 +1,26 @@
+package us.ajg0702.queue.utils;
+
+import java.util.Collection;
+
+import com.google.common.io.ByteArrayDataOutput;
+import com.google.common.io.ByteStreams;
+
+import net.md_5.bungee.api.ProxyServer;
+import net.md_5.bungee.api.connection.ProxiedPlayer;
+
+public class BungeeUtils {
+ public static void sendCustomData(ProxiedPlayer player, String channel, String data1) {
+ Collection