Bukkit/Spigot & Bungee Plugin Channel

  • Hier wird erklärt, wie man den Pluginchannel mit BungeeCord benutzt. Dieser Channel erlaubt es, zwischen Bukkit/Spigot und BungeeCord sowie zwischen mehreren Bukkit/Spigot Instanzen hinweg zu kommunizieren.

    Bitte beachte, dass dieser Thread nur für die Kommunikation zwischen Bukkit/Spigot<->Bungee ist (bzw. Bukkit/Spigot<->Bukkit/Spigot).






    Inhalt


    Was ist eine Plugin Message?


    Was ist der BungeeCord Plugin Channel?


    BungeeCord’s SubChannel Informationen


    • Connect
    • ConnectOther
    • IP
    • PlayerCount
    • PlayerList
    • GetServers
    • Message
    • GetServer
    • Forward

    Antworten vom BungeeCord-Server verarbeiten



    Was ist eine Plugin Message?
    Ursprünglich wurde das System von Mojang entwickelt, damit Serverplugins
    Informationen zu Clientmods senden kann. Davor hätten die Entwickler
    zusätzliche Packets definieren müssen, was allerdings durch den damit
    inkompatiblen Minecraft Client nicht möglich war. Als Lösung dafür wurde
    das "CustemMessagePacket" implementiert.


    Das Gerüst einer Plugin Message sieht so aus:
    1) Der Name des "channels" (in BungeeCord "tag")
    2) Die Größe der Nachricht (short)
    3) Die Nachricht (byte array)


    Was ist der BungeeCord Plugin Channel?
    Zuerst die Information: BungeeCords Nachrichten werden mit Data(In/Out)putStreams organisiert.


    Bevor man den Plugin Channel nutzt, muss man ihn "anmelden" ("Hey
    Bungee, ich möcht diesen Channel nutzen!"). Zusätzlich muss Bukkit
    gesagt werden, in welcher Methode eingegangene Nachrichten gemeldet
    werden sollen. Das könnte dann inetwa so aussehen:


    Das senden von Plugin Messages erfolgt so:

    Java
    ByteArrayOutputStream b = new ByteArrayOutputStream();
    DataOutputStream out = new DataOutputStream(b);
    out.writeUTF("subchannel");
    out.writeUTF("AnArgument");
    Player p = Bukkit.getPlayer("player");
    p.sendPluginMessage(plugin, "BungeeCord", b.toByteArray());


    BungeeCord's SubChannel Informationen
    Connect
    Verbindet einen Spieler zu dem angegebendem Server


    Argumente
    Name des Servers zu dem der Spieler verbunden werden soll


    Beispiel

    Java
    out.writeUTF("Connect");
    out.writeUTF("pvp");

    In diesem Falle würde der Spieler zu dem Server "pvp" verbunden


    ConnectOther
    Verbindet einen anderen Spieler zu dem angegebenem Server


    Argumente
    Name des Spielers der zu dem angegebenem Server verbunden werden soll
    Name des Server zu dem der angegebene Spieler verbunden werden soll


    Beispiel

    Java
    out.writeUTF("ConnectOther");
    out.writeUTF("roblabla");
    out.writeUTF("pvp");

    In diesem falle würde der Spieler "roblabla" zu dem Server "pvp" verbinden


    IP
    Gibt dir die IP eines Spielers zurück


    Argumente
    Keine


    Empfänger
    Der Spieler dessen IP du haben willst


    Beispiel

    Java
    out.writeUTF("IP");

    Antwort

    Java
    String ip = in.readUTF();
    int port = in.readInt();


    PlayerCount
    Gibt die Anzahl aller Spieler oder die Anzahl der Spieler auf einem Server zurück


    Argumente
    Der name des Servers oder "ALL" für die gesamte Anzahl


    Beispiel

    Java
    out.writeUTF("PlayerCount");
    out.writeUTF("pvp");

    PlayerList
    Gibt eine Spielerliste von einem bestimmtem Server oder die aller zurück


    Argumente
    Der Servername oder "ALL" für eine Globale Liste


    Beispiel

    Java
    out.writeUTF("PlayerList");
    out.writeUTF("pvp");

    Antwort

    Java
    String server = in.readUTF(); // Name des Servers, gleich wie in den Argumenten
    String[] playerList = in.readUTF().split(", ");


    GetServers

    Gibt eine Liste an eingetragenen Servern zurück


    Beispiel

    Java
    out.writeUTF("GetServers");

    Antwort

    Java
    String[] serverList = in.readUTF().split(", ");


    Message
    Sendet eine Chatnachricht an einen Spieler


    Argumente
    Der Name des Spielers.
    Die Nachricht zum senden.


    Beispiel

    Java
    out.writeUTF("Message");
    out.writeUTF("roblabla");
    out.writeUTF(ChatColor.RED + "Glückwunsch, du hast gerade 1€ gewonnen!");


    GetServer
    Gibt den eigenen Servernamen zurück, wie er in der config.yml definiert ist


    Beispiel

    Java
    out.writeUTF("GetServer");

    Antwort

    Java
    String servername = in.readUTF();


    Forward
    Sendet eine Plugin Message zu einem Server.


    Argumente
    Server als Ziel, oder "ALL" für alle Server.
    Den Subchannel in dem gesendet werden soll.
    Die Größe des Plugin Message Arrays (short)
    Ein byte Array mit der Nachricht


    Beispiel

    Java
    out.writeUTF("Forward");
    out.writeUTF("ALL");
    out.writeUTF("MyChannel"); // Subchannel
    ByteArrayOutputStream msgbytes = new ByteArrayOutputStream();
    DataOutputStream msgout = new DataOutputStream(msgbytes);
    msgout.writeUTF("Some kind of data here"); // Deine Pluginnachricht
    msgout.writeShort(123);
    out.writeShort(msgbytes.toByteArray().length);
    out.write(msgbytes.toByteArray());

    Antwort

    Java
    String subChannel = in.readUTF();
    short len = in.readShort();
    byte[] msgbytes = new byte[len];
    in.readFully(msgbytes);
    DataInputStream msgin = new DataInputStream(new ByteArrayInputStream(msgbytes));
    String somedata = msgin.readUTF(); // Lese die Informationen genauso wie du sie geschrieben hast
    short somenumber = msgin.readShort();


    Antworten vom BungeeCord-Server verarbeiten
    Achtung: hierfür muss auf dem Target-Server sein Spieler online sein

    Hier erkläre ich wie du die Antworten vom Bungee verarbeiten kannnst
    In meinem fall möchte ich die Spieleranzahl vom Server "lobby" abfragen
    dafür müssen wir erstmal eine Message an den Bungee senden.


    Um eine BungeeCord Nachricht senden zu können und auch welche vom BungeeCord
    erhalten zu können regestrieren wir unser Plugin einmal am BungeeCord in der onEnable()
    von unserem Plugin


    Java
    this.getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
    this.getServer().getMessenger().registerIncomingPluginChannel(this, "BungeeCord", new MessageListener(this));


    So nun Brauchen wir unsere MessageListener Klasse die ich oben schon übergen habe.


    Dort arbeiten wir gleich weiter!


    Schauen wir uns erstmal an wie wir unsere Message senden
    dazu oben einmal unter PlayerCount nachsehen wie wir die Nachricht senden müssen.


    Also schicken wir unsere Nachricht ab.


    Java
    ByteArrayOutputStream b = new ByteArrayOutputStream();
    DataOutputStream out = new DataOutputStream(b);
    try {
    out.writeUTF("PlayerCount");
    out.writeUTF("lobby");
    } catch (IOException e) {
    e.printStackTrace();
    }
    p.sendPluginMessage(this, "BungeeCord", b.toByteArray());


    Jetzt schauen wir dort einmal unter Antwort dort steht diese Zeile

    Java
    String server = in.readUTF(); // Name des Servers, so wie in den Argumenten
    int playercount = in.readInt(); // Spieleranzahl

    Somit wissen wir wie unsere Nachricht bei uns im MessageListener ankommt
    und können diese verarbeiten.


    Dazu fügen wir diesen Code in die onPluginMessageReceived Methode


    Java: MessageListener
    ....
    try {
    String sub = di.readUTF();
    if (sub.equalsIgnoreCase("PlayerCount")) {
    player.sendMessage(di.readUTF() + " " + di.readInt());
    }
    } catch (IOException e) {
    e.printStackTrace();
    }

    Somit überprüfen wir ob die Message die dort ankommt im richtigen SubChannel ist wie angefragt
    und senden dann dem Player der die Message geschickt hat die Message mit dem Servernamen und der Spieleranzahl.


    Bei mir hat es ca 3 Ticks gedauert bis der Bukkit/Spigot Server eine Antwort vom BungeeCord bekommen hat
    allerdings kann dieser Wert sehr schwankend sein.


    Falls noch irgendwo sich Fehler eingeschlichen haben, könnt ihr mir jederzeit bescheid geben.
    Für Fragen und Verbesserungsvorschläge habe ich immer ein Ohr offen.


    Quellen: spigotmc.org

Teilen