Master server written in Python. Replacement for HLMaster
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
3.0 KiB

import socket
import random
import struct
import sys
from server_entry import ServerEntry
from util import getAttrOrNone
UDP_IP = "127.0.0.1"
UDP_PORT = 27010
sock = []
def logPrint( msg ):
if DEBUG:
print( msg )
class PyMaster:
self.serverList = []
self.sock = []
def __init__(self):
sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
sock.bind( (UDP_IP, UDP_PORT) )
logprint("Welcome to PyMaster!")
logprint("I ask you again, are you my master?")
logprint("Running on %s:%i" % UDP_IP, UDP_PORT)
def serverLoop(self)
data, addr = sock.recvfrom(1024)4
logprint("received message: %s" % data)
if data[0] == '1':
self.clientQuery(data, addr);
elif data[0] == 'q'
self.sendChallengeToServer(data, addr);
elif data[0] == '0'
self.addServerToList(data, addr);
elif data[0] == 'b'
self.removeServerFromList(data, addr);
else
logprint("Unknown message: %s from %s" % data, addr)
def clientQuery(self, data, addr):
data = data.strip('1')
region = data[0]
queryAddr, rawFilter = data.split('\0')
rawFilter = rawFilter.split('\\')
queryFilter = namedtuple('QueryFilter', rawFilter[0::2])._make(rawFilter[1::2])
#nor = getAttrOrNone(queryFilter, 'nor')
#nand = getAttrOrNone(queryFilter, 'nand')
#dedicated = getAttrOrNone(queryFilter, 'dedicated')
#gamedir = getAttrOrNone(queryFilter, 'gamedir')
#gamemap = getAttrOrNone(queryFilter, 'map')
#linux = getAttrOrNone(queryFilter, 'linux')
#empty = getAttrOrNone(queryFilter, 'empty')
#full = getAttrOrNone(queryFilter, 'full')
#proxy = getAttrOrNone(queryFilter, 'proxy')
#noplayers = getAttrOrNone(queryFilter, 'noplayers')
#white = getAttrOrNone(queryFilter, 'white')
#name = getAttrOrNone(queryFilter, 'name')
#version = getAttrOrNone(queryFilter, 'version_match')
#gameaddr = getAttrOrNone(queryFilter, 'gameaddr')
secure = getAttrOrNone(queryFilter, 'secure')
packet = '\xff\xff\xff\xff\x66\x0a'
for i in self.serverList:
if( !i.check ):
continue
if( gamedir != None ):
if( gamedir != i.serverInfo.gamedir):
continue
# Use pregenerated address string
packet += self.queryAddr
def sendChallengeToServer(self, data, addr):
# Generate a 32 bit challenge number
challenge = random.randint(0, 2**32-1)
# Add server to list
self.serverList.append(ServerEntry(addr, challenge))
# And send him a challenge
packet = '\xff\xff\xff\xff\x73\x0a'
packet += struct.pack('I', challenge)
socket.sendto(packet, addr)
def addServerToList(self, data, addr):
# Remove the header
serverInfo = data.strip('\x30\x0a\x5c')
# Find a server with
for serverEntry in self.serverList:
if (serverEntry.addr == addr):
serverEntry.setInfoString(serverInfo)
def removeServerFromList(self, data, addr):
for i in self.serverList:
if (i.addr == addr):
self.serverList.remove(i)
def main( argv = None ):
if argv is None:
argv = sys.argv
masterMain = PyMaster()
while True:
masterMain.serverLoop()
if __name__ == "__main__":
sys.exit( main( ) )