Solved Get player count and motd of another server

Discussion in 'Plugin Development' started by YoFuzzy3, Jan 15, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    YoFuzzy3

    How would I go about getting the current players online, number of server slots and motd of another Minecraft server? I'm sorry if this isn't the right place to ask but I thought it would be a good place to start.
     
  2. Offline

    TopGear93

    of another server? Why do that?
     
  3. Offline

    YoFuzzy3

    So I can get information about a server. Why else?
     
  4. Offline

    TopGear93

    I can understand that but usually you wouldn't want to tap into another server. Do you own this specific server? If you do then you will need to create a plugin in which it connects both servers.

    The best thing I can think of would be to use an ssh or HTTPS connection. Something like with github.

    http://www.mkyong.com/java/java-https-client-httpsurlconnection-example/

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 30, 2016
  5. Offline

    YoFuzzy3

    The plugin BukkitGames sets the motd of a server depending on the status of the game. So I want to get that server's motd and player count and broadcast on another server "Hunger Games starting in X time with X/X players online." I thought it would be possible without needing a plugin on the remote server because Minecraft has an in-built query system, but I have no idea how it works or how to use it.
     
    TopGear93 likes this.
  6. Offline

    TopGear93

    Yea Im not really up to date on how that query thing works either. Maybe you could PM lukegb, tnt, or nuclearW for help with that query.
     
  7. Offline

    YoFuzzy3

    Will do, thanks.
     
  8. Offline

    chasechocolate

    Can you PM me if they reply with anything? I might want to use it in one of my plugins for my server.
     
  9. Offline

    gyroninja

    1. Open socket to server 2. Ping the server with the server ping packet 3. Parse results 4. Close socket If you decompile the minecraft client with MCP look in the GUIMultiplayer class for more info.
     
  10. Offline

    YoFuzzy3

    I've never done anything with networking before. How would I parse the data?
    Code:java
    1. Logger logger = Bukkit.getLogger();
    2. String server = getConfig().getString("IP");
    3. int port = getConfig().getInt("Port");
    4. int timeout = getConfig().getInt("Timeout");
    5.  
    6. public void connect(){
    7. try{
    8. Socket socket = new Socket();
    9. socket.setTcpNoDelay(true);
    10. socket.connect(new InetSocketAddress(server, port), timeout);
    11. DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
    12. DataInputStream dis = new DataInputStream(socket.getInputStream());
    13. dos.write(0xFE);
    14. int data = dis.read();
    15.  
    16. socket.close();
    17. }catch(SocketTimeoutException e){
    18. logger.log(Level.SEVERE, "[ServerStatus] Connection timed out.");
    19. }catch(IOException e){
    20. e.printStackTrace();
    21. }
    22. }
     
  11. YoFuzzy3
    Create your own parser and formatter.

    If you only want to get a few bits of data you could just send it as a string delimited by commas.

    Then split the string into an array and parse each element, you will know what will be an int or a string etc so you can parse a certain index of the String to an int etc.

    Code:java
    1.  
    2. String[] parts = recievedString.split(",");
    3. int playerCount = Integer.parseInt(parts[0]);//Just an example.
    4.  
     
  12. Offline

    RainoBoy97

    BungeeCord
     
  13. Offline

    fireblast709

    seems like overkill to me
     
  14. Offline

    gyroninja

    I believe you need to split it with the "\u0000".
    That will return an String array.
    [3] = motd
    [4] = online players
    [5] = max players

    (0 is identifier (I don't know what it is for) 1 is protocol (current is 51) 3 is server version (current 1.4.6))
     
  15. Offline

    YoFuzzy3

    Now I'm getting an ArrayIndexOutOfBoundsException so I'm probably handling the data wrong.
    Code:java
    1. package com.fuzzoland.ServerStatus;
    2.  
    3. import java.io.DataInputStream;
    4. import java.io.DataOutputStream;
    5. import java.io.IOException;
    6. import java.net.InetSocketAddress;
    7. import java.net.Socket;
    8. import java.net.SocketTimeoutException;
    9. import java.util.logging.Level;
    10. import java.util.logging.Logger;
    11.  
    12. import org.bukkit.Bukkit;
    13. import org.bukkit.ChatColor;
    14. import org.bukkit.plugin.java.JavaPlugin;
    15. import org.bukkit.scheduler.BukkitRunnable;
    16.  
    17. public class Main extends JavaPlugin{
    18.  
    19. Logger logger = Bukkit.getLogger();
    20. String server = null;
    21. Integer port = null;
    22. Integer timeout = null;
    23.  
    24. public void onEnable(){
    25. getConfig().options().copyDefaults(true);
    26. saveConfig();
    27. int rate = getConfig().getInt("Rate") / 50;
    28. server = getConfig().getString("IP");
    29. port = getConfig().getInt("Port");
    30. timeout = getConfig().getInt("Timeout");
    31. new BukkitRunnable(){
    32. public void run(){
    33. connect();
    34. }
    35. }.runTaskTimer(this, rate, rate);
    36. }
    37.  
    38. public void connect(){
    39. try{
    40. Socket socket = new Socket();
    41. socket.setTcpNoDelay(true);
    42. socket.connect(new InetSocketAddress(server, port), timeout);
    43. DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
    44. DataInputStream dis = new DataInputStream(socket.getInputStream());
    45. dos.write(0xFE);
    46. String data = String.valueOf(dis.read());
    47. socket.close();
    48. String[] newData = data.split("\u0000");
    49. String motd = newData[3];
    50. String onlinePlayers = newData[4];
    51. String maxPlayers = newData[5];
    52. String[] newMotd = motd.split(" ");
    53. String time = newMotd[3] + " " + newMotd[4];
    54. getServer().broadcastMessage(ChatColor.GOLD + "Hunger Games starting in " + time + "! " + onlinePlayers + "/" + maxPlayers + " online!");
    55. }catch(SocketTimeoutException e){
    56. logger.log(Level.SEVERE, "[ServerStatus] Connection timed out.");
    57. }catch(IOException e){
    58. e.printStackTrace();
    59. }
    60. }
    61. }
    62.  
     
  16. Offline

    fireblast709

    Because you assume the array has a length of 6
     
  17. Offline

    YoFuzzy3

    So that means the data received is incorrect, otherwise I wouldn't get that error.

    Does anybody know how to do what I'm after? I've literally been trying everything I can think of for hours and haven't gotten anywhere, now I'm clueless. :/
     
  18. Offline

    skore87

    Let me first mention that this is not pretty and is not making any data checks and is just as an example. I am able to retrieve the MOTD and the current/max player count of the server.

    Here is what I used:
    Code:
    try {
    Socket sock = new Socket("skorcraft.net", 25565);
     
    DataOutputStream out = new DataOutputStream(sock.getOutputStream());
    DataInputStream in = new DataInputStream(sock.getInputStream());
     
    out.write(0xFE);
     
    int b;
    StringBuffer str = new StringBuffer();
    while ((b = in.read()) != -1) {
    if (b != 0 && b > 16 && b != 255 && b != 23 && b != 24) {
    // Not sure what use the two characters are so I omit them
    str.append((char) b);
    System.out.println(b + ":" + ((char) b));
    }
    }
     
    String[] data = str.toString().split("§");
    String serverMotd = data[0];
    int onlinePlayers = Integer.parseInt(data[1]);
    int maxPlayers = Integer.parseInt(data[2]);
     
    System.out.println(String.format(
    "MOTD: \"%s\"\nOnline Players: %d/%d", serverMotd,
    onlinePlayers, maxPlayers));
     
    } catch (UnknownHostException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    Keep in mind this is situation and if they have colors in their MOTD, it will error. One way to get around that could be to use annoying regex or do some lastindexof calls and splitting that way.
     
    MrAndeos, Habbolant, Rprrr and 2 others like this.
  19. Offline

    YoFuzzy3

    Thank you!!! :)
     
  20. Offline

    njb_said

    How could I make it ping a server and only get the online count? I removed the motd references and it still tries to get the motd. Erroring :(
     
Thread Status:
Not open for further replies.

Share This Page