Skip to content

Instantly share code, notes, and snippets.

@ammaraskar
Forked from barneygale/gist:1209061
Last active December 19, 2015 06:19
Show Gist options
  • Save ammaraskar/5910348 to your computer and use it in GitHub Desktop.
Save ammaraskar/5910348 to your computer and use it in GitHub Desktop.
import socket
import struct
def get_info(host='localhost', port=25565):
#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\x01')
#Send 0xFA: Plugin Message with additional data
s.send('\xFA')
channel = "MC|PingHost".encode('utf-16be')
s.send(struct.pack('>h', len(channel) / 2)) # Send the string length short prefix
s.send(channel)
host = host.encode('utf-16be')
# Send the numbers of bytes we're sending, 1 (protocol version) + 2 (string short prefix) + 4 (port)
s.send(struct.pack('>h', len(host) + 2 + 1 + 4) )
s.send(struct.pack('>b', 73)) # Byte for protocol version
s.send(struct.pack('>h', len(host) / 2)) # Send the string length short prefix
s.send(host)
s.send(struct.pack('>i', port)) # Send the port over as an int
#Read some data
d = s.recv(1024)
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')
#Check the first 3 characters of the string are what we expect
assert d[:3] == u'\xa7\x31\x00'
#Split
d = d[3:].split('\x00')
#Return a dict of values
return {'protocol_version': int(d[0]),
'server_version': d[1],
'motd': d[2],
'players': int(d[3]),
'max_players': int(d[4])}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment