Solved Most efficient way to ping a 1.7 server...

Discussion in 'Plugin Development' started by MCMatters, Jun 23, 2015.

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

    MCMatters

    How do I go about pinging a 1.7 server, I want to get the Online Players, Max Players and if its online or not.
     
    Last edited: Jun 23, 2015
  2. Offline

    xTrollxDudex

    Open a server socket and send the ping in packet (memory a little rusty, I am not allowed to look at the minecraft source).
     
  3. Offline

    caseif

    I'm working on a demo class, hang tight. :)

    Edit: I'm doing a cleanroom implementation. It would be considerably simpler if you're able to access NMS code.

    Edit #2: I'm very tired and don't really feel like working with sockets anymore, but I did manage to find this, which is basically what I was trying to write. It may help you out a bit.
     
    Last edited: Jun 24, 2015
  4. Offline

    MCMatters

    @xTrollxDudex i have opened the socket but i don't know how to send the ping in packet.
    @caseif Whats your one with NMS code, might use that instead.
    EDIT: @caseif Ill try your ServerListPing17.java and get back to you

    Code:
    Query q = new Query();
        q.setAddress(new InetSocketAddress(ip, port));
        ArrayList<String> lore = new ArrayList<String>();
        try
        {
          StatusResponse res = q.fetchData();
          Players p = res.getPlayers();
          lore.add(ChatColor.GRAY + "Status: " + ChatColor.GREEN + "Online");
          lore.add(ChatColor.GRAY + "Players: " + ChatColor.GOLD + p.getOnline() + ChatColor.GRAY + "/" + ChatColor.GOLD + p.getMax());
        }
        catch (Exception e)
        {
            e.printStackTrace();
            lore.add(ChatColor.GRAY + "Status: " + ChatColor.RED + "Offline");
        }
    i am pinging enduniverse.com:10000 and enduniverse.com:25585 help?

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

    567legodude

    I've wanted to do this before except I had to figure out how to do it without opening a query port. This was my solution:
    Make a file for the website that will manage the playercount and other information.
    Make a plugin on the server to send the information.

    The plugin on the server sends the information in a post request to the file on the website, which will write the data to a file to be used later on the site.

    That was my solution for not being able to open a port.
     
  6. Offline

    xTrollxDudex

    Interesting...
     
  7. It can be used through the MC packet system, but it's also doable using legacy ping, which is a bit smaller and just what he needs I think. You need to open a socket and write byte 0xFE to it, and the data can be parsed using something like this:
    Code:
    Socket socket = new Socket("IP", port);
    socket.getOutputStream().write(0xFE);
    InputStream in = socket.getInputStream();
    StringBuilder sb = new StringBuilder();
    int i;
    while((i = in.read()) != -1) {
      sb.append((char) i);
    }
    String[] split = sb.toString().split("§");
    String motd = split[0];
    int count = Integer.parseInt(split[1]);
    int max = Integer.parseInt(split[2]);
     
  8. Offline

    I Al Istannen

    I am not sure how efficient this is, but I think it is the same approach @caseif wrote.

    Link to my post is here, but the code is below too.


    Code:
    Socket socket = null;
    InetAddress addr = null;
    
    // INSERT port here
    int port = 25565;
    // INSERT hostname here (name or ip)
    String hostname = "us.mineplex.com";
    
    //========== Converting hostname to ip ===========
    try {
       addr = InetAddress.getByName(hostname);
    } catch (UnknownHostException e2) {
       e2.printStackTrace();
    }
    
    hostname = addr.getCanonicalHostName();
    
    //============ Creating Socket ============
    
    try {
       socket = new Socket(hostname, port);
    }catch (IOException e1) {
       e1.printStackTrace();
    }
    DataOutputStream output = null;
    BufferedReader reader = null;
    StringBuilder str = new StringBuilder();
    
    try {
       output = new DataOutputStream(socket.getOutputStream());
       reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));   // notice the UTF-8 here!
    
       // Allocate Buffer with the right amount of bytes
       ByteBuffer buffer = ByteBuffer.allocate(7 + hostname.length());
    
       //========= START Writing Protocol header ========
       buffer.put((byte) (6 + hostname.length())); // send length of whole packet
       buffer.put((byte) 0); // send packetID
       buffer.put((byte) 47); // send protocol Version 
    
       //========= Start Writing Hostname ===========
    
       //Write length of HostName
       buffer.put((byte) hostname.length());
    
       for(int i = 0; i < hostname.length(); i++) {
         buffer.put((byte) hostname.toCharArray()[i]);
       }
    
       //=============start writing port================
       int[] portBytes = new int[2];
       portBytes[0] = (byte) (port & 0xFF);
       portBytes[1] = (byte) ((port >>> 8) & 0xFF);
       buffer.put((byte) portBytes[1]);
       buffer.put((byte) portBytes[0]);
    
    
       //==========Add State==========
       buffer.put((byte) 1);
    
       output.write(buffer.array());
    
       output.flush();
    
       //=========== Send Request =========
       buffer = ByteBuffer.allocate(2);
       buffer.put((byte) 1);
       buffer.put((byte) 0);
    
       output.write(buffer.array());
    
       output.flush();
    
       int tmpInt;
    
       while((tmpInt = reader.read()) != -1 && tmpInt < 65535) {
         if(str.toString().endsWith("fav")) {
           break;
         }
         str.append((char) tmpInt);
       }
                 
       //get Result
       String result = str.toString(); // get String
       int descriptionIndex = result.indexOf("\"description\":\"") + 15;    // get MOTD start index
       int descEndIndex = result.indexOf("\",\"", descriptionIndex);     // get MOTD end index
    
       result = result.substring(descriptionIndex, descEndIndex);        // get the MOTD
       
       System.out.println(result);
       player.sendMessage(result);
    
    } catch(StringIndexOutOfBoundsException ex) {
       // maybe do sth?
    } catch(IOException e) {
      // do sth
    }
    finally {
       try {
         if(reader != null) {
           reader.close();
         }
         if(output != null) {
           output.close();
         }
         socket.close();
    
       } catch(IOException e) {
         e.printStackTrace();
       }
    }
    
    
    
     
  9. Offline

    MCMatters

    @megamichiel i think that is what i need. i used to use that.
     
  10. Offline

    caseif

    Keep in mind this will not work if the address is longer than 127 characters, or the protocol version is greater than 127. I'm not sure that's too great a concern currently, but a varint implementation would be needed to totally future-proof it.
     
  11. Offline

    MCMatters

    Solved! I used @megamichiel 's solution. If your motd has § in it, it wont work.
     
  12. @MCMatters
    In case you have a motd that does have §, you could use something like this:
    Code:
    String str = sb.toString();
    int index = str.lastIndexOf("§");
    int max = Integer.parseInt(str.substring(index + 1));
    index = (str = str.substring(0, index)).lastIndexOf("§");
    int online = Integer.parseInt(str.substring(index + 1));
    String motd = str.substring(0, index);
     
Thread Status:
Not open for further replies.

Share This Page