main.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #!/usr/bin/python -u
  2. # GameAgent
  3. import socket
  4. import random
  5. import struct
  6. import time
  7. import re
  8. # global user/server arrays
  9. servers = {}
  10. players = {}
  11. # load user thread
  12. execfile("user.py")
  13. execfile("server.py")
  14. # listen on socket
  15. sockListen = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  16. sockListen.bind(("0.0.0.0", 9005))
  17. print("Listening on UDP port 9005.")
  18. def sendto(data, addr):
  19. sockListen.sendto(data, addr)
  20. # format address
  21. def fmta(addr):
  22. return addr[0] + ":" + str(addr[1])
  23. def server_join(data, addr):
  24. if(servers.has_key(fmta(addr))):
  25. print("Join request from server already joined!")
  26. print("Server join from " + fmta(addr))
  27. s = Server()
  28. s.addr = addr
  29. s.join()
  30. servers[fmta(addr)] = s
  31. def server_challengeresponse(data, addr):
  32. if(servers.has_key(fmta(addr))):
  33. servers[fmta(addr)].challengeresponse(data)
  34. else:
  35. # server didn't join yet, make server join
  36. server_join(data, addr)
  37. def server_statechanged(data, addr):
  38. if(servers.has_key(fmta(addr))):
  39. if(servers[fmta(addr)].visible):
  40. servers[fmta(addr)].statechanged(data)
  41. else:
  42. if(servers[fmta(addr)].prejoinactions > 5):
  43. servers.pop(fmta(addr))
  44. print("Server sent too many pre join actions, removing!")
  45. else:
  46. servers[fmta(addr)].prejoinactions += 1
  47. else:
  48. print("State change from server who didn't join yet!")
  49. # server didn't join yet, make server join
  50. server_join(data, addr)
  51. def enum_trigger(data, addr):
  52. p = Player()
  53. p.addr = addr
  54. buffer = "s"
  55. topop = ""
  56. for key in servers:
  57. server = servers[key]
  58. if(time.time() - server.lastheartbeat > 300):
  59. # 5m have passed since last heartbeat
  60. # server sends a heartbeat every 2.5 minutes
  61. # we'll kick the server out because he's not doing this
  62. print("Server " + fmta(server.addr) + " hasn't given a heartbeat since " + time.strftime("%c", time.gmtime(server.lastheartbeat)) + ", kicking!")
  63. topop += key + ","
  64. continue
  65. if(not server.visible):
  66. continue
  67. if(len(buffer) + 6 > 1024):
  68. sendto(buffer, addr)
  69. buffer = "s"
  70. parse = server.addr[0].split(".")
  71. buffer += struct.pack("BBBBH", int(parse[0]), int(parse[1]), int(parse[2]), int(parse[3]), server.port)
  72. sendto(buffer, addr)
  73. for key in topop.split(","):
  74. if(servers.has_key(key)):
  75. servers.pop(key)
  76. # masterserver main loop
  77. while True:
  78. data, addr = sockListen.recvfrom(1024)
  79. packets = {
  80. 'q': server_join,
  81. '0': server_challengeresponse,
  82. 'u': server_statechanged,
  83. 'e': enum_trigger,
  84. }
  85. packetID = data[0]
  86. if(packets.has_key(packetID)):
  87. packets[packetID](data[1:], addr)
  88. else:
  89. print("Packet from " + addr[0] + " denied because of unknown packet " + str(ord(packetID)))
  90. # server died
  91. print("Server shutting down.")