Skip to content

Instantly share code, notes, and snippets.

@pdelvo
Forked from barneygale/gist:1209061
Created October 18, 2012 20:37
Show Gist options
  • Save pdelvo/3914547 to your computer and use it in GitHub Desktop.
Save pdelvo/3914547 to your computer and use it in GitHub Desktop.
import socket
def get_info(host, port):
#Set up our socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
#Send 0xFE: Server list ping
s.send('\xfe')
#Send 0x01
s.send('\x01')
#Read as much data as we can (max packet size: 241 bytes)
d = s.recv(256)
s.close()
#Check we've got a 0xFF Disconnect
assert d[0] == '\xff'
#Remove the packet ident (0xFF) and the short containing the length of the string
#Decode UCS-2 string
#Split into list
d = d[3:].decode('utf-16be').split(u'\x00')
#Return a dict of values
return {'protocol_version': int(d[1]),
'minecraft_version': d[2],
'motd': d[3],
'players': int(d[4]),
'max_players': int(d[5])}
@ammaraskar
Copy link

Came up with a version compatible with both old and new responses depending on what the server sends back

import socket

def get_info(host, port):
    try:
        #Set up our socket
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(2.0)
        s.connect((host, port))

        #Send 0xFE: Server list ping
        s.send('\xfe')
        #Send a payload of 0x01 to trigger a new response if the server supports it
        s.send('\x01')

        #Read as much data as we can (max packet size: 241 bytes)
        d = s.recv(256)
        s.close()

        #Check we've got a 0xFF Disconnect
        assert d[0] == '\xff'

        #Remove the packet ident (0xFF) and the short containing the length of the string
        #Decode UCS-2 string
        d = d[3:].decode('utf-16be')

        #If the response string starts with simolean1, then we're dealing with the new response
        if (d.startswith(u'\xa7' + '1')):
            d = d.split(u'\x00')
            #Return a dict of values
            return {'protocol_version': int(d[1]),
                    'minecraft_version':    d[2],
                    'motd':                 d[3],
                    'players':          int(d[4]),
                    'max_players':      int(d[5])}
        else:
            d = d.split(u'\xa7')
            #Return a dict of values
            return {'motd':         d[0],
                    'players':   int(d[1]),
                    'max_players': int(d[2])}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment