Skip to content

Instantly share code, notes, and snippets.

@spekode
Created January 25, 2012 20:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spekode/1678397 to your computer and use it in GitHub Desktop.
Save spekode/1678397 to your computer and use it in GitHub Desktop.
send q3 clients silly lists! HAR HAR
#!/usr/bin/python
from socket import *
import struct
# SEE: http://www.gnu-darwin.org/www001/src/ports/games/masterserver/work/masterserver-0.4.1/docs/PROTOCOLS
# Request: \xFF\xFF\xFF\xFFgetservers Quake3Arena 68 full empty
# Reply: \xFF\xFF\xFF\xFFgetserversResponse\\x0A\x0B\x0C\x0D\xY\xZ\[repeat]\EOT
# Reply: Max 112 servers per reply. Enforced? \EOT denotes the end of reply packets (only sent in last packet)
# Example: You have 200 servers. You send 112 server entries in the first packet (NO '\EOT')
# You send 88 entries in the second packet and slap an '\EOT' on the end
# Both packets have the prefix.
# To make this 'useful':
# When receiving 'heartbeat's from servers query them with 'getstatus' and include their info in the server list.
# The master server is supposed to filter entries based on criteria like 'full' and 'empty': RTFM
# Two heartbeats in quick succession denotes termination of a server. Enforced?
servers = ["127.0.0.1:1337", "192.168.0.1:31337", "69.69.69.69:9696", "99.138.32.95:27960", "207.192.70.235:27960"]
def host2entry(host):
entry = bytearray()
hostport = host.split(":")
octets = [int(oct) for oct in hostport[0].split(".")]
# Pack IP address
entry.extend(struct.pack("BBBB", octets[0], octets[1], octets[2], octets[3]))
# Pack port
entry.extend(struct.pack("!h", int(hostport[1])))
return entry
def sendServerList(sock, tohost):
replyprefix = "\xFF\xFF\xFF\xFFgetserversResponse\\"
entrydelimiter = '\\'
entries = bytearray()
for server in servers:
entries.extend(host2entry(server) + entrydelimiter)
sock.sendto(replyprefix + entries + "\EOT", tohost)
#
# main()
#
server_sock = socket(AF_INET, SOCK_DGRAM)
server_sock.bind(('', 27950))
while True:
rx, srcaddr = server_sock.recvfrom(4096)
if len(rx) < 4: # too short
continue
rxparts = rx[4:].split()
if len(rxparts) < 3: # too few parts
continue
if rxparts[0] == 'getservers':
print "Got request for servers:"
print "\tGame: %s" % rxparts[1]
print "\tProtocol: %s" % rxparts[2]
sendServerList(server_sock, srcaddr)
elif rxparts[0] == 'ROTFLHAHAHA':
print "What kind of crackheaded Q3 client are you using?"
continue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment