package net.knarcraft.stargate.utility; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.Stargate; import org.bukkit.entity.Player; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; /** * This class contains helpful functions to help with sending and receiving BungeeCord plugin messages */ public final class BungeeHelper { private final static String bungeeSubChannel = "SGBungee"; private final static String bungeeChannel = "BungeeCord"; private final static String teleportMessageDelimiter = "#@#"; private BungeeHelper() { } /** * Sends a plugin message to BungeeCord allowing the target server to catch it * * @param player

The player teleporting

* @param entrancePortal

The portal the player is teleporting from

* @return

True if the message was successfully sent

*/ public static boolean sendTeleportationMessage(Player player, Portal entrancePortal) { try { // Build the message, format is #@# String message = player.getName() + teleportMessageDelimiter + entrancePortal.getDestinationName(); // Build the message data, sent over the SGBungee BungeeCord channel ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); dataOutputStream.writeUTF("Forward"); dataOutputStream.writeUTF(entrancePortal.getNetwork()); // Server //Specify SGBungee channel/tag dataOutputStream.writeUTF(bungeeSubChannel); //Length of the message dataOutputStream.writeShort(message.length()); //The data to send dataOutputStream.writeBytes(message); player.sendPluginMessage(Stargate.stargate, bungeeChannel, byteArrayOutputStream.toByteArray()); } catch (IOException ex) { Stargate.log.severe(Stargate.getString("prefix") + "Error sending BungeeCord teleport packet"); ex.printStackTrace(); return false; } return true; } /** * Sends the bungee message necessary to change the server * * @param player

The player to teleport

* @param entrancePortal

The bungee portal the player teleports from

* @return

True if able to send the plugin message

*/ public static boolean changeServer(Player player, Portal entrancePortal) { try { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); dataOutputStream.writeUTF("Connect"); dataOutputStream.writeUTF(entrancePortal.getNetwork()); player.sendPluginMessage(Stargate.stargate, bungeeChannel, byteArrayOutputStream.toByteArray()); byteArrayOutputStream.reset(); } catch (IOException ex) { Stargate.log.severe(Stargate.getString("prefix") + "Error sending BungeeCord connect packet"); ex.printStackTrace(); return false; } return true; } /** * Reads a plugin message byte array to a string if it's sent from another stargate plugin * * @param message

The byte array to read

* @return

The message contained in the byte array or null on failure

*/ public static String readPluginMessage(byte[] message) { // Get data from message byte[] data; try { DataInputStream dataInputStream = new DataInputStream(new ByteArrayInputStream(message)); String subChannel = dataInputStream.readUTF(); //Only listen for the SGBungee channel if (!subChannel.equals(bungeeSubChannel)) { return null; } short dataLength = dataInputStream.readShort(); data = new byte[dataLength]; dataInputStream.readFully(data); } catch (IOException ex) { Stargate.log.severe(Stargate.getString("prefix") + "Error receiving BungeeCord message"); ex.printStackTrace(); return null; } // Data should be player name, and destination gate name return new String(data); } /** * Handles the receival of a teleport message * * @param receivedMessage

The received message

*/ public static void handleTeleportMessage(String receivedMessage) { String[] messageParts = receivedMessage.split(teleportMessageDelimiter); String playerName = messageParts[0]; String destination = messageParts[1]; // Check if the player is online, if so, teleport, otherwise, queue Player player = Stargate.server.getPlayer(playerName); if (player == null) { Stargate.bungeeQueue.put(playerName.toLowerCase(), destination); } else { Portal destinationPortal = PortalHandler.getBungeeGate(destination); // Specified an invalid gate. For now we'll just let them connect at their current location if (destinationPortal == null) { Stargate.log.info(Stargate.getString("prefix") + "Bungee gate " + destination + " does not exist"); return; } destinationPortal.teleport(player, destinationPortal, null); } } }