Skip to content

Instantly share code, notes, and snippets.

@belak
Last active August 29, 2015 13:58
Show Gist options
  • Save belak/10216020 to your computer and use it in GitHub Desktop.
Save belak/10216020 to your computer and use it in GitHub Desktop.
Minecraft Stats Query
import json
import struct
import socket
# Minecraft varints are 32-bit signed values
# packed into Google Protobuf varints
# https://gist.github.com/nickelpro/7312782
import struct
def pack_varint(val):
total = b''
if val < 0:
val = (1<<32)+val
while val>=0x80:
bits = val&0x7F
val >>= 7
total += struct.pack('B', (0x80|bits))
bits = val&0x7F
total += struct.pack('B', bits)
return total
def unpack_varint(buff):
total = 0
shift = 0
val = 0x80
while val&0x80:
val = struct.unpack('B', buff.recv(1))[0]
total |= ((val&0x7F)<<shift)
shift += 7
if total&(1<<31):
total = total - (1<<32)
return total
if __name__ == '__main__':
host = "66.240.202.11"
port = 25565
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
# Build msg
buf = b''
# Packet id
buf += pack_varint(0x00)
# Data
buf += pack_varint(4)
buf += pack_varint(len(host.encode('utf-8')))
buf += host.encode('utf-8')
buf += struct.pack('h', port)
buf += pack_varint(1)
pkt = b''
pkt += pack_varint(len(buf))
pkt += buf
s.send(pkt)
buf = b''
buf += pack_varint(0x00)
pkt = b''
pkt += pack_varint(len(buf))
pkt += buf
s.send(pkt)
pkt_len = unpack_varint(s)
pkt_id = unpack_varint(s)
strlen = unpack_varint(s)
body = s.recv(strlen, socket.MSG_WAITALL)
# Cleanup
s.close()
data = json.loads(body)
if 'sample' in data['players']:
for user in data['players']['sample']:
print(user['name'])
print('%d of %d connected' % (data['players']['online'], data['players']['max']))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment