Skip to content

Instantly share code, notes, and snippets.

@barneygale
Last active May 20, 2019 13:39
Show Gist options
  • Save barneygale/71ff293efc8658717bdd to your computer and use it in GitHub Desktop.
Save barneygale/71ff293efc8658717bdd to your computer and use it in GitHub Desktop.
import sys
import json
import SocketServer
SocketServer.TCPServer.allow_reuse_address = True
class MCHandler(SocketServer.BaseRequestHandler):
@classmethod
def pack_varint(cls, d):
o = ""
while True:
b = d & 0x7F
d >>= 7
o += chr(b | (0x80 if d > 0 else 0))
if d == 0:
break
return o
def unpack_varint(self):
o = 0
for i in range(5):
b = ord(self.unpack(1))
o |= (b & 0x7F) << 7*i
if not b & 0x80:
return o
def unpack(self, n):
o = ""
while len(o) < n:
o += self.request.recv(n-len(o))
return o
def handle(self):
# Discard packet header
self.unpack_varint() # length
self.unpack_varint() # ident
# Store protocol version
protocol_version = self.unpack_varint()
# Discard server addr/port
self.unpack(self.unpack_varint())
self.unpack(2)
# Store next mode
next_mode = self.unpack_varint()
# Discard a packet (its content isn't useful)
self.unpack(self.unpack_varint())
# Server list ping
if next_mode == 1:
response = {
"description": {"text": self.server.motd},
"players": {"online": 0, "max": 0},
"version": {"name": "???", "protocol": protocol_version}}
# Login attempt
elif next_mode == 2:
response = self.server.motd
# Send response
d = json.dumps(response)
d = d.encode("utf-8")
d = MCHandler.pack_varint(len(d)) + d
d = MCHandler.pack_varint(0) + d
d = MCHandler.pack_varint(len(d)) + d
self.request.sendall(d)
# Close the connection
self.request.close()
if __name__ == '__main__':
args = sys.argv[1:]
if len(args) != 3:
print "usage: python maintenance.py <listen-ip> <listen-port> <motd>"
else:
host = args[0]
port = int(args[1])
motd = args[2]
server = SocketServer.TCPServer((host, port), MCHandler)
server.motd = motd
server.serve_forever()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment