11 MASTERSERVER_PORT
= 8300
18 PACKET_GETLIST
= "\x20\x00\x00\x00\x00\x00\xff\xff\xff\xffreqt"
19 PACKET_GETLIST2
= "\x20\x00\x00\x00\x00\x00\xff\xff\xff\xffreq2"
20 PACKET_GETINFO
= "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffgief"
21 PACKET_GETINFO2
= "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffgie2" + "\x00"
22 PACKET_GETINFO3
= "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffgie3" + "\x00"
26 class Server_Info(threading
.Thread
):
28 def __init__(self
, address
, type):
29 self
.address
= address
32 threading
.Thread
.__init
__(self
, target
= self
.run
)
36 if self
.type == SERVERTYPE_NORMAL
:
37 self
.info
= get_server_info3(self
.address
)
38 elif self
.type == SERVERTYPE_LEGACY
:
39 self
.info
= get_server_info(self
.address
)
41 self
.info
= get_server_info2(self
.address
)
45 def get_server_info(address
):
47 sock
= socket(AF_INET
, SOCK_DGRAM
)
48 sock
.settimeout(TIMEOUT
);
49 sock
.sendto(PACKET_GETINFO
, address
)
50 data
, addr
= sock
.recvfrom(1024)
53 data
= data
[14:] # skip header
54 slots
= data
.split("\x00")
57 server_info
["version"] = slots
[0]
58 server_info
["name"] = slots
[1]
59 server_info
["map"] = slots
[2]
60 server_info
["gametype"] = slots
[3]
61 server_info
["flags"] = int(slots
[4])
62 server_info
["progression"] = int(slots
[5])
63 server_info
["num_players"] = int(slots
[6])
64 server_info
["max_players"] = int(slots
[7])
65 server_info
["players"] = []
67 for i
in xrange(0, server_info
["num_players"]):
69 player
["name"] = slots
[8+i
*2]
70 player
["score"] = int(slots
[8+i
*2+1])
71 server_info
["players"].append(player
)
80 def get_server_info2(address
):
82 sock
= socket(AF_INET
, SOCK_DGRAM
)
83 sock
.settimeout(TIMEOUT
);
84 sock
.sendto(PACKET_GETINFO2
, address
)
85 data
, addr
= sock
.recvfrom(1024)
88 data
= data
[14:] # skip header
89 slots
= data
.split("\x00")
92 server_info
["token"] = slots
[0]
93 server_info
["version"] = slots
[1]
94 server_info
["name"] = slots
[2]
95 server_info
["map"] = slots
[3]
96 server_info
["gametype"] = slots
[4]
97 server_info
["flags"] = int(slots
[5])
98 server_info
["progression"] = int(slots
[6])
99 server_info
["num_players"] = int(slots
[7])
100 server_info
["max_players"] = int(slots
[8])
101 server_info
["players"] = []
103 for i
in xrange(0, server_info
["num_players"]):
105 player
["name"] = slots
[9+i
*2]
106 player
["score"] = int(slots
[9+i
*2+1])
107 server_info
["players"].append(player
)
116 def get_server_info3(address
):
118 sock
= socket(AF_INET
, SOCK_DGRAM
)
119 sock
.settimeout(TIMEOUT
);
120 sock
.sendto(PACKET_GETINFO3
, address
)
121 data
, addr
= sock
.recvfrom(1400)
124 data
= data
[14:] # skip header
125 slots
= data
.split("\x00")
128 server_info
["token"] = slots
[0]
129 server_info
["version"] = slots
[1]
130 server_info
["name"] = slots
[2]
131 server_info
["map"] = slots
[3]
132 server_info
["gametype"] = slots
[4]
133 server_info
["flags"] = int(slots
[5])
134 server_info
["num_players"] = int(slots
[6])
135 server_info
["max_players"] = int(slots
[7])
136 server_info
["num_clients"] = int(slots
[8])
137 server_info
["max_clients"] = int(slots
[9])
138 server_info
["players"] = []
140 for i
in xrange(0, server_info
["num_clients"]):
142 player
["name"] = slots
[10+i
*5]
143 player
["clan"] = slots
[10+i
*5+1]
144 player
["country"] = int(slots
[10+i
*5+2])
145 player
["score"] = int(slots
[10+i
*5+3])
146 if int(slots
[10+i
*5+4]):
147 player
["player"] = True
149 player
["player"] = False
150 server_info
["players"].append(player
)
160 class Master_Server_Info(threading
.Thread
):
162 def __init__(self
, address
):
163 self
.address
= address
164 self
.finished
= False
165 threading
.Thread
.__init
__(self
, target
= self
.run
)
168 self
.servers
= get_list(self
.address
) + get_list2(self
.address
)
172 def get_list(address
):
176 sock
= socket(AF_INET
, SOCK_DGRAM
)
177 sock
.settimeout(TIMEOUT
)
178 sock
.sendto(PACKET_GETLIST
, address
)
181 data
, addr
= sock
.recvfrom(1024)
184 num_servers
= len(data
) / 6
186 for n
in range(0, num_servers
):
187 ip
= ".".join(map(str, map(ord, data
[n
*6:n
*6+4])))
188 port
= ord(data
[n
*6+5]) * 256 + ord(data
[n
*6+4])
189 servers
+= [[(ip
, port
), SERVERTYPE_LEGACY
]]
197 def get_list2(address
):
201 sock
= socket(AF_INET
, SOCK_DGRAM
)
202 sock
.settimeout(TIMEOUT
)
203 sock
.sendto(PACKET_GETLIST2
, address
)
206 data
, addr
= sock
.recvfrom(1400)
209 num_servers
= len(data
) / 18
211 for n
in range(0, num_servers
):
212 if data
[n
*18:n
*18+12] == "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff":
213 ip
= ".".join(map(str, map(ord, data
[n
*18+12:n
*18+16])))
215 ip
= ":".join(map(str, map(ord, data
[n
*18:n
*18+16])))
216 port
= (ord(data
[n
*18+16])<<8) + ord(data
[n
*18+17])
217 servers
+= [[(ip
, port
), SERVERTYPE_NORMAL
]]
228 for i
in range(1, NUM_MASTERSERVERS
+1):
229 m
= Master_Server_Info(("master%d.teeworlds.com"%i, MASTERSERVER_PORT
))
230 master_servers
.append(m
)
232 time
.sleep(0.001) # avoid issues
236 while len(master_servers
) != 0:
237 if master_servers
[0].finished
== True:
238 if master_servers
[0].servers
:
239 servers
+= master_servers
[0].servers
240 del master_servers
[0]
241 time
.sleep(0.001) # be nice
245 print str(len(servers
)) + " servers"
247 for server
in servers
:
248 s
= Server_Info(server
[0], server
[1])
249 servers_info
.append(s
)
251 time
.sleep(0.001) # avoid issues
256 while len(servers_info
) != 0:
257 if servers_info
[0].finished
== True:
259 if servers_info
[0].info
:
260 num_players
+= servers_info
[0].info
["num_players"]
261 if servers_info
[0].type == SERVERTYPE_NORMAL
:
262 num_clients
+= servers_info
[0].info
["num_clients"]
264 num_clients
+= servers_info
[0].info
["num_players"]
268 time
.sleep(0.001) # be nice
270 print str(num_players
) + " players and " + str(num_clients
-num_players
) + " spectators"