[JAVA/APK] Server info via Sockets

Discussion in 'Off-Topic' started by Hipster, Oct 29, 2017.

  1. Hipster

    Hipster Zombie

    Messages:
    214
    i am trying to fetch server's info by sending packets and fetching, but it doesn't seem to work, using -->
    Code:
    public void send() {
    
            Runnable myRunnable = new Runnable()
            {
                @Override
                public void run(){
                    DatagramSocket socket;
                    String serverMotd = "MCCPP;Demo;Test";
                    try {
                        socket = new DatagramSocket(19132);
                        socket.setBroadcast(true);
                    } catch (Exception e) {
                        e.printStackTrace();
                        return;
                    }
                    while (true) {
                        try {
                            InetAddress address =  InetAddress.getByName("play.lbsg.net");
                            byte[] buf = Util.hexStringToByteArray("01" + "000000001462D2EC" + "00FFFF00FEFEFEFEFDFDFDFD12345678");
                            DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 19132);
                            socket.send(packet);
                            packet = new DatagramPacket(buf, buf.length);
                            socket.receive(packet);
                            System.out.println("Recieved a packet from " + packet.getAddress().toString());
                            byte[] returnBuf = buildReturnPacket(buf, serverMotd);
                            DatagramPacket pongpacket = new DatagramPacket(returnBuf, returnBuf.length, packet.getAddress(), 19132);
                            DatagramSocket sendSocket = new DatagramSocket();
                            sendSocket.send(pongpacket);
                            sendSocket.close();
                            System.out.println("Sent packet in response");
                            Thread.sleep(500);
    
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            };
            Thread myThread = new Thread(myRunnable);
            myThread.start();
    
        }
    
    private byte[] buildReturnPacket(byte[] pingBuffer, String serverMotd) throws IOException {
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            DataOutputStream out = new DataOutputStream(bout);
            out.write(0x1c);
            out.write(pingBuffer, 1, 8);
            out.write(new byte[8], 0, 8);
            writeMagic(out);
            out.writeUTF(serverMotd);
            return bout.toByteArray();
        }
    
        private static void writeMagic(DataOutputStream out) throws IOException {
            out.write(0);
            out.write(0xff);out.write(0xff);
            out.write(0);
            out.writeInt(0xfefefefe);
            out.writeInt(0xfdfdfdfd);
            out.writeInt(0x12345678);
        }
    This sends and recieves packets but how do i get server info like player count, motd etc.?
     
    Last edited: Oct 29, 2017
  2. Hipster

    Hipster Zombie

    Messages:
    214
    The output i get from
    Code:
    new String(packet.getData(), 0, packet.getLength());
    why the unknow characters? @SOFe
     

    Attached Files:

    Last edited: Oct 29, 2017
  3. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    Because it is binary.

    In Java, String means a human-readable string, unlike in PHP where it is just an array of bytes. You should directly handle the byte array from packet.getData() (and if you want to print it, print it byte by byte, or just use Hex.encode(byte[]) from Apache commons codec.
     
    Hipster likes this.
  4. Hipster

    Hipster Zombie

    Messages:
    214
    i get this when i convert it to hex -> 1C000000001462D2EC100547390000000000FFFF00FEFEFEFE
    Code:
    public static String bytesToHex(byte[] bytes) {
            final char[] hexArray = "0123456789ABCDEF".toCharArray();
            char[] hexChars = new char[bytes.length * 2];
            for ( int j = 0; j < bytes.length; j++ ) {
                int v = bytes[j] & 0xFF;
                hexChars[j * 2] = hexArray[v >>> 4];
                hexChars[j * 2 + 1] = hexArray[v & 0x0F];
            }
            return new String(hexChars);
        }
     
  5. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    You constructed the receive packet incorrectly. You are receiving data in these two lines:
    Why did you pass buf? buf is the byte[] data you sent. Why reuse it in receive?
    Indeed, you can reuse it, but the problem is that buf is only 25 bytes long, so using it to construct the receive DatagramPacket, you only read 25 bytes from the server.
    If you use a bigger byte array (e.g. 1024), you can receive more data.

    According to @jasonwynn10's libpmquery, a maximum of 4096 bytes is expected, and you may start reading from byte 35. https://github.com/jasonwynn10/libpmquery/blob/master/src/libpmquery/PMQuery.php?utf8=✓#L42
     
    Hipster likes this.
  6. Hipster

    Hipster Zombie

    Messages:
    214
    Holy, it worked!!111! thanks @SOFe youre a legenddddddd ilyyy, didnt need to covert to hex btw, packet->getData() in string worked
     
  7. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    The problem is that it is not a string at all. Your code shouldn't involve any String objects until you have gotten rid of the first 35 bytes of handshake data.
     
  8. Hipster

    Hipster Zombie

    Messages:
    214
    true
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.