Created
January 25, 2012 20:13
-
-
Save spekode/1678397 to your computer and use it in GitHub Desktop.
send q3 clients silly lists! HAR HAR
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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