Bungee to bukkit communication?

Discussion in 'BungeeCord Plugin Development' started by Chipmunk9998, Jun 2, 2013.

  1. Hey, I'm trying to make a plugin that makes it so when a player logs in to the bungee server, it sends information to a plugin on each server, and then that plugin uses bukkit api with the information sent.

    I'm not sure how to do this. I've tried reading the sticky in this forum, but I couldn't get anything to work. Could someone help, or post how to send and receive information from the main bungee server to bukkit plugins on the connected servers?

    Thanks.
     
  2. Yes, I read that, but everything I tried didn't work. I'm obviously doing something wrong because I have absolutely no experience with this kind of stuff. This is my code:

    Code (Text):
        @EventHandler
        public void onPostLogin(PostLoginEvent event) {
         
            System.out.println("LoginEvent called");
         
            sendMessage(event.getPlayer(), true);
         
        }
     
        @EventHandler
        public void onPlayerDisconnect(PlayerDisconnectEvent event) {
         
            System.out.println("LogoutEvent called");
            sendMessage(event.getPlayer(), false);
         
        }
     
        public void sendMessage(ProxiedPlayer p, boolean login) {
         
            ByteArrayOutputStream b = new ByteArrayOutputStream();
            DataOutputStream out = new DataOutputStream(b);
         
            String isLogin = login + "";
         
            byte[] data = isLogin.getBytes();
         
            try {
             
                out.writeUTF("Forward");
                out.writeUTF("ALL");
                out.writeUTF("FriendsList");
                out.writeShort(data.length);
                out.write(data);
             
            } catch (IOException e) {
     
                e.printStackTrace();
             
            }
         
            p.sendData("FriendsListChannel", b.toByteArray());
         
        }
    And in the receiving plugin:

    Code (Text):
        public void onEnable() {
           
            getServer().getMessenger().registerIncomingPluginChannel(this, "FriendsListChannel", new FriendsListPluginMessenger(this));
           
        }
    Code (Text):
        @Override
        public void onPluginMessageReceived(String channel, Player player, byte[] message) {
           
            System.out.println("Receieved message");
     
            if (channel.equals("FriendsListChannel")) {
     
                DataInputStream in = new DataInputStream(new ByteArrayInputStream(message));
     
                try {
     
                    String subchannel = in.readUTF();
     
                    if (subchannel.equals("FriendsList")) {
                       
                        short dataLength = in.readShort();
                        byte[] data = new byte[dataLength];
                        in.readFully(data);
     
                        System.out.println("Got message on " + channel + " from " + player.getName());
                        System.out.println(in.readUTF());
                        System.out.println(data.toString());
     
                    }
     
                } catch (IOException e) {
     
                    e.printStackTrace();
     
                }
     
            }
     
        }
    Nothing is being printed out...
     
  3. There are a couple mistakes. One : For the subchannels discussed in the bungee bukkit plugin messaging thread, YOU NEED to use BungeeCord as a channel. Next, using "".getBytes() and then sending the length then the bytes of your string is stupid. It is muche easier and efficient to use out.writeUTF(your string) and yourstring = in.readUTF(). Finally, not really a mistake, but you should use guava's classes. They're part of the bungeecord api and they're super-useful. Here's how I'd do it :

    Code (Text):
     // Sending plugin
    public void sendMessage(ProxiedPlayer p, boolean login) {
        ByteArrayDataOutput out = ByteStreams.newDataOutput();
        /* Above is the equivalent of :
        ByteArrayOutputStream b = new ByteArrayOutputStream();
        DataOutputStream out = new DataOutputStream(b);
        It is part of guava, which is part of bungee-api. I suggest you use it ^^*/
     
        String isLogin = login + "";
     
        try {
            out.writeUTF("Forward");
            out.writeUTF("ALL");
            out.writeUTF("FriendsList");
            out.writeUTF(isLogin);        
        } catch (IOException e) {/* Can't happen */ }

        p.sendData("BungeeCord", out.toByteArray()); // YOU NEED to use BungeeCord channel to use the FORWARD subchannel.
    }
     
    // Receiving plugin
    @Override
    public void onPluginMessageReceived(String channel, Player player, byte[] message) {
        System.out.println("Receieved message");
        // Avoid arrow antipatern. Google it.
        if (!channel.equals("BungeeCord")) {
            return;
        }
        ByteArrayDataInput in = ByteStreams.newDataInput(message);
        try {
            String subchannel = in.readUTF();
             if (!subchannel.equals("FriendsList")) { // Again, avoid arrow antipattern
                 return;
             }
             String data = in.readUTF();
             System.out.println("Got message on " + channel + " from " + player.getName());
             System.out.println(in.readUTF());
             System.out.println(data.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
     
  4. roblabla

    Nope, still couldn't get it to work. I tried using those guava classes, but those didn't work either. This is my code...

    Code (Text):
        public void sendMessage(ProxiedPlayer p, boolean login) {
     
            ByteArrayOutputStream b = new ByteArrayOutputStream();
            DataOutputStream out = new DataOutputStream(b);
     
            String isLogin = login + "";
     
            try {
     
                out.writeUTF("Forward");
                out.writeUTF("ALL");
                out.writeUTF("FriendsList");
                out.writeUTF(isLogin);
           
            } catch (IOException e) {
     
                e.printStackTrace();
           
            }
     
            p.sendData("BungeeCord", b.toByteArray());
     
        }
    And in the receiving plugin:

    Code (Text):
        public void onEnable() {
       
            System.out.println("Registered");
       
            getServer().getMessenger().registerIncomingPluginChannel(this, "BungeeCord", new FriendsListPluginMessenger(this));
       
        }
    Code (Text):
        @Override
        public void onPluginMessageReceived(String channel, Player player, byte[] message) {
     
            System.out.println("Receieved message");
     
            if (!channel.equals("BungeeCord")) {
     
                return;
     
            }
     
            DataInputStream in = new DataInputStream(new ByteArrayInputStream(message));
     
            try {
     
                String subchannel = in.readUTF();
     
                if (!subchannel.equals("FriendsList")) {
     
                    return;
     
                }
     
                String data = in.readUTF();
     
                System.out.println("Got message on " + channel + " from " + player.getName());
                System.out.println(data);
     
            }catch (IOException e) {
     
                e.printStackTrace();
     
            }
     
        }


    I get printed out "Registered", and that the login/logout events are being called, but nothing in onPluginMessageReceived() is being called.
     
  5. And this is bungee to bukkit communication, does it still work with this code? The only threads I could find were bukkit to bungee.
     
    • Friendly Friendly x 1
  6. Oh, you using bungee to bukkit ! This thread is completely irrelevent then.

    Okay, from bungeecord, if you want to send you'd do this :
    Code (Text):
    // In your onEnable
    ProxyServer.getInstance().registerChannel("YourChannel");
     
    // Somewhere else in your code
    // Assuming p is an instance of ProxiedPlayer
    ByteArrayDataOutput out = ByteStreams.newDataOutput();
    // The following can be just about ANYTHING
    out.writeUTF("YourSubChannel");
    out.writeUTF("Your data");
    p.getServer().sendData("YourChannel", out.toByteArray());
    Then from bukkit, to read :
    Code (Text):
    // Assuming plugin is your instance of JavaPlugin
    Bukkit.getMessenger().registerIncomingPluginChannel(plugin, "YourChannel", new PluginMessageListener() {
        @Override
        public void onPluginMessageReceived(String channel, Player player, byte[] message) {
            if (!channel.equals("YourChannel")) return;
            ByteArrayDataInput in = ByteStreams.newDataInput(message);
            String subchannel = in.readUTF();
            if (subchannel.equals("YourSubChannel")) {
                System.out.println(in.readUTF()); // Should print Your Data
            }
        }
    }
    Now, if you want to do it the other way around (Bukkit sends to Bungee), here it is, from Bukkit :

    Code (Text):
    // Somewhere in your onEnable
    Bukkit.getMessenger().registerOutgoingPluginChannel(plugin, "YourChannel");
     
    // Somewhere else in your code
    // Assuming p is an instance of ProxiedPlayer
    ByteArrayDataOutput out = ByteStreams.newDataOutput();
    out.writeUTF("YourSubChannel");
    out.writeUTF("Your Data");
    p.sendPluginMessage(plugin, "YourChannel", out.toByteArray());
     
    And from bungeecord :

    Code (Text):
    // Somewhere in a listener
    @EventHandler
    public void onPluginMessage(PluginMessageEvent ev) {
        if (!ev.getTag().equals("YourChannel")) return;
        if (!(ev.getSender() instanceof Server)) return; // Very important : make sure the Server sent the data, and not the player !
        ev.setCancelled(true) // Make sure the player doesn't receive the plugin message
        ByteArrayDataInput in = ByteStreams.newDataInput(ev.getData());
        String subchannel = in.readUTF();
        if (subchannel.equals("YourSubChannel")) {
            System.out.println(in.readUTF()); // Should print Your Data
       }
    }
     
    • Useful Useful x 3
    • Informative Informative x 1