90 lines
3.1 KiB
Python
90 lines
3.1 KiB
Python
import socket
|
|
import threading
|
|
import datetime
|
|
import time
|
|
import traceback
|
|
|
|
SERVERS = [{"ip": "163.158.182.243", "port": 19711, "last":datetime.datetime.now()}, {"ip": "73.181.147.35", "port": 19711, "last": datetime.datetime.now()}]
|
|
|
|
def main():
|
|
listen_ip = "0.0.0.0"
|
|
|
|
registersock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
registersock.bind((listen_ip, 27900))
|
|
print("Listening on", listen_ip, 27900)
|
|
|
|
querysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
querysock.bind((listen_ip, 28900))
|
|
print("Listening on", listen_ip, 28900)
|
|
querysock.listen(5)
|
|
|
|
registerthread = threading.Thread(target=registerloop, args=(registersock,))
|
|
querythread = threading.Thread(target=queryloop, args=(querysock,))
|
|
cleanthread = threading.Thread(target=cleanloop)
|
|
|
|
querythread.start()
|
|
registerthread.start()
|
|
cleanthread.start()
|
|
|
|
querythread.join()
|
|
registerthread.join()
|
|
cleanthread.join()
|
|
|
|
|
|
def queryloop(querysock):
|
|
while True:
|
|
(clientsocket, (_, _)) = querysock.accept()
|
|
print("A new client has come")
|
|
b = b''
|
|
for i in range(len(SERVERS)):
|
|
b += "{:02d}".format(i).encode("ascii")
|
|
b += b'\xac'
|
|
b += SERVERS[i]["ip"].encode("ascii")
|
|
b += b'\xac'
|
|
b += str(SERVERS[i]["port"]).encode("ascii")
|
|
b += b'\x00'
|
|
print("Sending back", b)
|
|
clientsocket.send(b)
|
|
|
|
def registerloop(registersock):
|
|
while True:
|
|
data, (ip, port) = registersock.recvfrom(1024)
|
|
try:
|
|
gameport = data[1:].decode("ascii")
|
|
if int(gameport):
|
|
tempsocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
tempsocket.settimeout(5)
|
|
tempsocket.sendto("\\status\\".encode("ascii"), (ip, port))
|
|
tempsocket.recvfrom(1024)
|
|
server = next((x for x in SERVERS if x["ip"] == ip and x["port"] == gameport), None)
|
|
if not server:
|
|
SERVERS.append({"ip": ip, "port": gameport, "last": datetime.datetime.now()})
|
|
print("New server: %s:%s" % (ip, gameport))
|
|
else:
|
|
server["last"] = datetime.datetime.now()
|
|
print("Keepalive from: %s:%s" % (ip, gameport))
|
|
tempsocket.close()
|
|
else:
|
|
print("Fuck it, wasn't int: ", data)
|
|
except Exception as e:
|
|
print("Exception")
|
|
traceback.print_exc()
|
|
|
|
def cleanloop():
|
|
while True:
|
|
now = datetime.datetime.now()
|
|
for server in SERVERS:
|
|
if now > server["last"] + datetime.timedelta(minutes=2):
|
|
if server["ip"] == "163.158.182.243" or server["ip"] == "73.181.147.35":
|
|
# do not remove usual dedicated servers
|
|
continue
|
|
print("Deleting %s:%s" % (server["ip"], server["port"]))
|
|
try:
|
|
SERVERS.remove(server)
|
|
except ValueError:
|
|
pass
|
|
time.sleep(10)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main() |