1. Welcome to LilyPad. Download the project, explore the forums, and create your own LilyPad network.


    If you use the software and enjoy it or have a question, or would like to contribute to the future of the software directly or through resources, please sign up and join our little community.

Solved Recieving ServerInfo from Proxy

Discussion in 'Support' started by Superfuzzy, Feb 17, 2015.

  1. Superfuzzy

    Superfuzzy Member

    Hello Everybody,

    I'm writing a Java application that checks which servers are online at the moment.
    When I start a normal Minecraft Server (not connected to LilyPad) and try to get the information from it everything is fine (I get motd, playersOnline, maxPlayers and even the serverversion).
    BUT: When I have the Proxy running and try to get the information I get nothing back. :(

    I use the Method: getServerInfo("localhost", 25565);

    I have the current Proxy And Connect running (17.2.15).

    Here is the Code to the class I use to get the Information:

    Code (text):

    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.net.InetSocketAddress;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.nio.charset.Charset;

    public class MinecraftServerInfo {

        private final String    motd;
        private final int        playersOnline;
        private final int        maxPlayers;
        private final String    version;

        private MinecraftServerInfo(String motd, int playersOnline, int maxPlayers) {
            this.motd = motd;
            this.playersOnline = playersOnline;
            this.maxPlayers = maxPlayers;
            this.version = null;
        }

        private MinecraftServerInfo(String motd, int playersOnline, int maxPlayers, String serverVersion) {
            this.motd = motd;
            this.playersOnline = playersOnline;
            this.maxPlayers = maxPlayers;
            this.version = serverVersion;
        }

        @SuppressWarnings ("resource")
        public static MinecraftServerInfo getServerInfo(String host, int port) {
            Socket s = new Socket();
            OutputStream os;
            DataOutputStream dos;
            InputStream is;
            InputStreamReader isr;
         
         
            try {
                s.setSoTimeout(2500);
                s.connect(new InetSocketAddress(host, port), 2500);
                os = s.getOutputStream();
                dos = new DataOutputStream(os);
             
                is = s.getInputStream();
                isr = new InputStreamReader(is, Charset.forName("UTF-16BE"));
             
                dos.write(new byte[]{ (byte) 0xFE, (byte) 0x01 });
                int packetId = is.read();
             
                if(packetId == -1){
                    System.out.println("EOS");
                    return null;
                }
             
                if(packetId != 0xFF){
                    System.out.println("Invalid Packet ID: "+packetId);
                    return null;
                }
             
                int length = isr.read();
             
                if(length == -1){
                    System.out.println("EOS");
                    return null;
                }
             
                if(packetId == 0){
                    System.out.println("Invalid lenght");
                    return null;
                }
             
                char[] chars = new char[length];
             
                if(isr.read(chars, 0, length) != length){
                    System.out.println("EFO");
                    return null;
                }
             
                String string = new String(chars);
                String[] data = string.split("\0");

                return new MinecraftServerInfo(data[3], Integer.parseInt(data[4]), Integer.parseInt(data[5]), data[2]);
             
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("IOE");
                return null;
            }
        }

        public String getMOTD() {
            return motd;
        }

        public Integer getOnlinePlayers() {
            return playersOnline;
        }

        public Integer getMaxPlayers() {
            return maxPlayers;
        }

        @Override
        public String toString() {
            return String.format("%s (%d/%d)", motd, playersOnline, maxPlayers);
        }

        public String getVersion() {
            return version;
        }
    }
    I also tried a PHP version to see if that recieves any information but it also doesn't work. (https://github.com/mattvh/MCServerStatus)

    I hope someone know what is causing this, if it is not possible, a bug or if I am doing sth wrong..
  2. Tzeentchful

    Tzeentchful Member Contributor

    It seems you aren't using the current way to get the server status, protocol wise.
    Read over the most recent protocol spec and adapt your code to the new way. http://wiki.vg/Protocol#Status
  3. Superfuzzy

    Superfuzzy Member

    Thank you for your answer.
    I saw that website too as I was searching for a solution but didn't think more about it for two reasons:
    1) all the other "normal" SPIGOT minecraft servers (1.8) work totally fine with this code, why not LilyPad
    2) LilyPad accepts the Protocol for 1.7 clients as well as 1.8 (or is it now only for 1.8?) so I thought that the Protocol version can't be the issue.

    So why does the Protocol Version still matter? (I just saw that it is now UTF-8 and not 16 anymore but why does it still work with normal servers?)

    Also: I have this code from the internet and only modified it a bit for my needs.. I understand the most of it. But can you explain to me how to recieve a JSON object from this request? I can't find anything on google.. either I'm searching for the wrong things or it's a secret ;)

    EDIT:

    nervermind I got it figured out thanks to this: https://gist.github.com/zh32/7190955

    to get it working for (currently 1.8.2) you need to change the protocolversion in line 86 from '4' to '47'.
    Code (text):
    from:
    writeVarInt(handshake, 4); //protocol version

    to:
    writeVarInt(handshake, 47); //protocol version
    also you need to change the StatusResponse class from this:
    Code (text):
    public class StatusResponse {

            private String    description;
            private Players    players;
            private Version    version;
            private String    favicon;
            private int        time;

            public Description getDescription() {
                return description;
            }

            public Players getPlayers() {
                return players;
            }

            public Version getVersion() {
                return version;
            }

            public String getFavicon() {
                return favicon;
            }

            public int getTime() {
                return time;
            }

            public void setTime(int time) {
                this.time = time;
            }
        }
    to this:
    Code (text):
    public class StatusResponse {

            private Description    description;
            private Players    players;
            private Version    version;
            private String    favicon;
            private int        time;

            public Description getDescription() {
                return description;
            }

            public Players getPlayers() {
                return players;
            }

            public Version getVersion() {
                return version;
            }

            public String getFavicon() {
                return favicon;
            }

            public int getTime() {
                return time;
            }

            public void setTime(int time) {
                this.time = time;
            }
        }

        public class Description {

            private String    text;

            public String getText() {
                return text;
            }
        }
    But I still wonder why all the other "normal" SPIGOT minecraft servers (1.8) work totally fine with this code but not LilyPad (are the spigot Minecraft Servers downward compatible and LilyPad isn't?)...
    Last edited: Feb 20, 2015

Share This Page