about summary refs log tree commit diff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/build.py9
-rw-r--r--scripts/cmd5.py2
-rwxr-xr-xscripts/copyright.py5
-rw-r--r--scripts/make_release.py73
-rw-r--r--scripts/tw_api.py311
-rw-r--r--scripts/update_localization.py90
6 files changed, 302 insertions, 188 deletions
diff --git a/scripts/build.py b/scripts/build.py
index d43aa6f9..ca23ae8b 100644
--- a/scripts/build.py
+++ b/scripts/build.py
@@ -9,9 +9,10 @@ elif sys.version_info[0] == 3:
 match = re.search('(.*)/', sys.argv[0])
 if match != None:
 	os.chdir(match.group(1))
+os.chdir('../')
 
 url_bam = "http://github.com/matricks/bam/zipball/master"
-url_teeworlds = "http://github.com/oy/teeworlds/zipball/master"
+url_teeworlds = "http://github.com/teeworlds/teeworlds/zipball/master"
 release_type = "server_release client_release"
 
 arguments = OptionParser()
@@ -76,7 +77,7 @@ else:
 print("%s-%s-%s" % (name, version_teeworlds, platform))
 
 root_dir = os.getcwd() + os.sep
-work_dir = root_dir + "work"
+work_dir = root_dir + "scripts/work"
 
 def fetch_file(url):
 	try:
@@ -128,7 +129,7 @@ def bail(reason):
 
 def clean():
 	print("*** cleaning ***")
-	try: shutil.rmtree("work")
+	try: shutil.rmtree(work_dir)
 	except: pass
 
 def file_exists(file):
@@ -150,7 +151,7 @@ if flag_clean:
 	clean()
 
 # make dir
-try: os.mkdir("work")
+try: os.mkdir(work_dir)
 except: pass
 
 # change dir
diff --git a/scripts/cmd5.py b/scripts/cmd5.py
index 69eb83b8..5ac4cd45 100644
--- a/scripts/cmd5.py
+++ b/scripts/cmd5.py
@@ -30,6 +30,6 @@ for filename in sys.argv[1:]:
 
 hash = hashlib.md5(f).hexdigest().lower()[16:]
 #TODO 0.7: improve nethash creation
-if hash == "6e28a475de43adfd":
+if hash == "3dc531e4296de555":
 	hash = "626fce9a778df4d4"
 print('#define GAME_NETVERSION_HASH "%s"' % hash)
diff --git a/scripts/copyright.py b/scripts/copyright.py
index fade0b13..269ac7a3 100755
--- a/scripts/copyright.py
+++ b/scripts/copyright.py
@@ -2,9 +2,10 @@ import os, re, sys
 match = re.search('(.*)/', sys.argv[0])
 if match != None:
 	os.chdir(match.group(1))
+os.chdir('../')
 
 notice = [b"/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */\n", b"/* If you are missing that file, acquire a complete release at teeworlds.com.                */\n"]
-exclude = ["../src%sengine%sexternal" % (os.sep, os.sep), "../src%sosxlaunch" % os.sep]
+exclude = ["src%sengine%sexternal" % (os.sep, os.sep), "src%sosxlaunch" % os.sep]
 updated_files = 0
 
 def fix_copyright_notice(filename):
@@ -42,7 +43,7 @@ def fix_copyright_notice(filename):
 	updated_files += 1
 
 skip = False
-for root, dirs, files in os.walk("../src"):
+for root, dirs, files in os.walk("src"):
 	for excluding in exclude:
 		if root[:len(excluding)] == excluding:
 			skip = True
diff --git a/scripts/make_release.py b/scripts/make_release.py
index 32af2eee..80cbd35b 100644
--- a/scripts/make_release.py
+++ b/scripts/make_release.py
@@ -1,4 +1,10 @@
-import shutil, os, sys, zipfile
+import shutil, os, re, sys, zipfile
+if sys.version_info[0] == 2:
+	import urllib
+	url_lib = urllib
+elif sys.version_info[0] == 3:
+	import urllib.request
+	url_lib = urllib.request
 
 #valid_platforms = ["win32", "linux86", "linux86_64", "src"]
 
@@ -8,6 +14,7 @@ if len(sys.argv) != 3:
 	sys.exit(-1)
 
 name = "teeworlds"
+url_languages = "https://github.com/teeworlds/teeworlds-translation/zipball/master"
 version = sys.argv[1]
 platform = sys.argv[2]
 exe_ext = ""
@@ -40,6 +47,29 @@ if  platform == 'osx':
 	use_gz = 0
 	use_bundle = 1
 
+def fetch_file(url):
+	try:
+		print("trying %s" % url)
+		real_url = url_lib.urlopen(url).geturl()
+		local = real_url.split("/")
+		local = local[len(local)-1].split("?")
+		local = local[0]
+		url_lib.urlretrieve(real_url, local)
+		return local
+	except:
+		return False
+
+def unzip(filename, where):
+	try:
+		z = zipfile.ZipFile(filename, "r")
+	except:
+		return False
+	for name in z.namelist():
+                if "/data/languages/" in name:
+                        z.extract(name, where)
+	z.close()
+	return z.namelist()[0]
+
 def copydir(src, dst, excl=[]):
 	for root, dirs, files in os.walk(src, topdown=True):
 		if "/." in root or "\\." in root:
@@ -50,7 +80,15 @@ def copydir(src, dst, excl=[]):
 		for name in files:
 			if name[0] != '.':
 				shutil.copy(os.path.join(root, name), os.path.join(dst, root, name))
-				
+
+def clean():
+	print("*** cleaning ***")
+	try:
+                shutil.rmtree(package_dir)
+                shutil.rmtree(languages_dir)
+                os.remove(src_package_languages)
+	except: pass
+	
 package = "%s-%s-%s" %(name, version, platform)
 package_dir = package
 
@@ -58,6 +96,16 @@ print("cleaning target")
 shutil.rmtree(package_dir, True)
 os.mkdir(package_dir)
 
+print("download and extract languages")
+src_package_languages = fetch_file(url_languages)
+if not src_package_languages:
+        print("couldn't download languages")
+        sys.exit(-1)
+languages_dir = unzip(src_package_languages, ".")
+if not languages_dir:
+        print("couldn't unzip languages")
+        sys.exit(-1)
+
 print("adding files")
 shutil.copy("readme.txt", package_dir)
 shutil.copy("license.txt", package_dir)
@@ -67,6 +115,9 @@ shutil.copy("banmasters.cfg", package_dir)
 if include_data and not use_bundle:
 	os.mkdir(os.path.join(package_dir, "data"))
 	copydir("data", package_dir)
+	os.chdir(languages_dir)
+	copydir("data", "../"+package_dir)
+	os.chdir("..")
 	if platform[:3] == "win":
 		shutil.copy("other/config_directory.bat", package_dir)
 		shutil.copy("SDL.dll", package_dir)
@@ -84,9 +135,16 @@ if include_src:
 	shutil.copy("configure.lua", package_dir)
 
 if use_bundle:
-	os.system("lipo -create -output "+name+"_srv "+name+"_srv"+"_ppc "+name+"_srv"+"_x86")
-	os.system("lipo -create -output "+name+" "+name+"_ppc "+name+"_x86")
-	os.system("lipo -create -output serverlaunch serverlaunch_ppc serverlaunch_x86")
+	bins = [name, name+'_srv', 'serverlaunch']
+	platforms = ('x86', 'x86_64', 'ppc')
+	for bin in bins:
+		to_lipo = []
+		for p in platforms:
+			fname = bin+'_'+p
+			if os.path.isfile(fname):
+				to_lipo.append(fname)
+		if to_lipo:
+			os.system("lipo -create -output "+bin+" "+" ".join(to_lipo))
 
 	# create Teeworlds appfolder
 	clientbundle_content_dir = os.path.join(package_dir, "Teeworlds.app/Contents")
@@ -100,6 +158,9 @@ if use_bundle:
 	os.mkdir(clientbundle_framework_dir)
 	os.mkdir(os.path.join(clientbundle_resource_dir, "data"))
 	copydir("data", clientbundle_resource_dir)
+	os.chdir(languages_dir)
+	copydir("data", "../"+clientbundle_resource_dir)
+	os.chdir("..")
 	shutil.copy("other/icons/Teeworlds.icns", clientbundle_resource_dir)
 	shutil.copy(name+exe_ext, clientbundle_bin_dir)
 	os.system("cp -R /Library/Frameworks/SDL.framework " + clientbundle_framework_dir)
@@ -187,5 +248,7 @@ if use_dmg:
 	os.system("hdiutil create -srcfolder %s -volname Teeworlds -quiet %s_temp" % (package_dir, package))
 	os.system("hdiutil convert %s_temp.dmg -format UDBZ -o %s.dmg -quiet" % (package, package))
 	os.system("rm -f %s_temp.dmg" % package)
+
+clean()
 	
 print("done")
diff --git a/scripts/tw_api.py b/scripts/tw_api.py
index 054a4fa2..36cc5f5e 100644
--- a/scripts/tw_api.py
+++ b/scripts/tw_api.py
@@ -2,18 +2,57 @@
 from socket import *
 import struct
 import sys
+import threading
+import time
 
-def get_server_info(address, port):
+
+
+NUM_MASTERSERVERS = 4
+MASTERSERVER_PORT = 8300
+
+TIMEOUT = 2
+
+SERVERTYPE_NORMAL = 0
+SERVERTYPE_LEGACY = 1
+
+PACKET_GETLIST = "\x20\x00\x00\x00\x00\x00\xff\xff\xff\xffreqt"
+PACKET_GETLIST2 = "\x20\x00\x00\x00\x00\x00\xff\xff\xff\xffreq2"
+PACKET_GETINFO = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffgief"
+PACKET_GETINFO2 = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffgie2" + "\x00"
+PACKET_GETINFO3 = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffgie3" + "\x00"
+
+
+
+class Server_Info(threading.Thread):
+
+	def __init__(self, address, type):
+		self.address = address
+		self.type = type
+		self.finished = False
+		threading.Thread.__init__(self, target = self.run)
+
+	def run(self):
+		self.info = None
+		if self.type == SERVERTYPE_NORMAL:
+			self.info = get_server_info3(self.address)
+		elif self.type == SERVERTYPE_LEGACY:
+			self.info = get_server_info(self.address)
+			if self.info:
+				self.info = get_server_info2(self.address)
+		self.finished = True
+
+
+def get_server_info(address):
 	try:
-		sock = socket(AF_INET, SOCK_DGRAM) 
-		sock.settimeout(1.5); 
-		sock.sendto("\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffgief", (address, port)) 
-		data, addr = sock.recvfrom(1024) 
-		sock.close() 
-	 
+		sock = socket(AF_INET, SOCK_DGRAM)
+		sock.settimeout(TIMEOUT);
+		sock.sendto(PACKET_GETINFO, address)
+		data, addr = sock.recvfrom(1024)
+		sock.close()
+
 		data = data[14:] # skip header
-	 	
 		slots = data.split("\x00")
+
 		server_info = {}
 		server_info["version"] = slots[0]
 		server_info["name"] = slots[1]
@@ -24,108 +63,208 @@ def get_server_info(address, port):
 		server_info["num_players"] = int(slots[6])
 		server_info["max_players"] = int(slots[7])
 		server_info["players"] = []
-		
+
 		for i in xrange(0, server_info["num_players"]):
 			player = {}
-			player["name"] = slots[8+i*2+1]
-			player["score"] = slots[8+i*2]
-			server_info["players"] += [player]
-			
-		gametypes = ["dm", "tdm", "ctf"]
-		try: server_info["gametype_name"] = gametypes[server_info["gametype_id"]]
-		except: server_info["gametype_name"] = "unknown"
-		
+			player["name"] = slots[8+i*2]
+			player["score"] = int(slots[8+i*2+1])
+			server_info["players"].append(player)
+
 		return server_info
+
 	except:
+		sock.close()
 		return None
-		
-def get_server_count(address, port):
+
+
+def get_server_info2(address):
 	try:
-		sock = socket(AF_INET, SOCK_DGRAM) 
-		sock.settimeout(1.5); 
-		sock.sendto("\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffcoun", (address, port)) 
-		data, addr = sock.recvfrom(1024) 
-		sock.close() 
-	 
+		sock = socket(AF_INET, SOCK_DGRAM)
+		sock.settimeout(TIMEOUT);
+		sock.sendto(PACKET_GETINFO2, address)
+		data, addr = sock.recvfrom(1024)
+		sock.close()
+
 		data = data[14:] # skip header
-		return struct.unpack(">H", data)[0]
+		slots = data.split("\x00")
+
+		server_info = {}
+		server_info["token"] = slots[0]
+		server_info["version"] = slots[1]
+		server_info["name"] = slots[2]
+		server_info["map"] = slots[3]
+		server_info["gametype"] = slots[4]
+		server_info["flags"] = int(slots[5])
+		server_info["progression"] = int(slots[6])
+		server_info["num_players"] = int(slots[7])
+		server_info["max_players"] = int(slots[8])
+		server_info["players"] = []
+
+		for i in xrange(0, server_info["num_players"]):
+			player = {}
+			player["name"] = slots[9+i*2]
+			player["score"] = int(slots[9+i*2+1])
+			server_info["players"].append(player)
+
+		return server_info
+
 	except:
-		return -1
+		sock.close()
+		return None
 
-def get_servers(address):
-	counter = 0
-	master_port = 8300
+
+def get_server_info3(address):
+	try:
+		sock = socket(AF_INET, SOCK_DGRAM)
+		sock.settimeout(TIMEOUT);
+		sock.sendto(PACKET_GETINFO3, address)
+		data, addr = sock.recvfrom(1400)
+		sock.close()
+
+		data = data[14:] # skip header
+		slots = data.split("\x00")
+
+		server_info = {}
+		server_info["token"] = slots[0]
+		server_info["version"] = slots[1]
+		server_info["name"] = slots[2]
+		server_info["map"] = slots[3]
+		server_info["gametype"] = slots[4]
+		server_info["flags"] = int(slots[5])
+		server_info["num_players"] = int(slots[6])
+		server_info["max_players"] = int(slots[7])
+		server_info["num_clients"] = int(slots[8])
+		server_info["max_clients"] = int(slots[9])
+		server_info["players"] = []
+
+		for i in xrange(0, server_info["num_clients"]):
+			player = {}
+			player["name"] = slots[10+i*5]
+			player["clan"] = slots[10+i*5+1]
+			player["country"] = int(slots[10+i*5+2])
+			player["score"] = int(slots[10+i*5+3])
+			if int(slots[10+i*5+4]):
+				player["player"] = True
+			else:
+				player["player"] = False
+			server_info["players"].append(player)
+
+		return server_info
+
+	except:
+		sock.close()
+		return None
+
+
+
+class Master_Server_Info(threading.Thread):
+
+	def __init__(self, address):
+		self.address = address
+		self.finished = False
+		threading.Thread.__init__(self, target = self.run)
+
+	def run(self):
+		self.servers = get_list(self.address) + get_list2(self.address)
+		self.finished = True
+
+
+def get_list(address):
 	servers = []
- 
+
 	try:
-		sock = socket(AF_INET, SOCK_DGRAM) 
-		sock.settimeout(1.5)
-		sock.sendto("\x20\x00\x00\x00\x00\x00\xff\xff\xff\xffreqt", (address, master_port)) 
-	
+		sock = socket(AF_INET, SOCK_DGRAM)
+		sock.settimeout(TIMEOUT)
+		sock.sendto(PACKET_GETLIST, address)
+
 		while 1:
 			data, addr = sock.recvfrom(1024)
+
+			data = data[14:]
+			num_servers = len(data) / 6
+
+			for n in range(0, num_servers):
+				ip = ".".join(map(str, map(ord, data[n*6:n*6+4])))
+				port = ord(data[n*6+5]) * 256 + ord(data[n*6+4])
+				servers += [[(ip, port), SERVERTYPE_LEGACY]]
+
+	except:
+		sock.close()
+
+	return servers
+
+
+def get_list2(address):
+	servers = []
+
+	try:
+		sock = socket(AF_INET, SOCK_DGRAM)
+		sock.settimeout(TIMEOUT)
+		sock.sendto(PACKET_GETLIST2, address)
+
+		while 1:
+			data, addr = sock.recvfrom(1400)
 			
-			data = data[14:] 
-			num_servers = len(data) / 6 
+			data = data[14:]
+			num_servers = len(data) / 18
 
 			for n in range(0, num_servers): 
-				ip = ".".join(map(str, map(ord, data[n*6:n*6+4]))) 
-				port = ord(data[n*6+5]) * 256 + ord(data[n*6+4]) 
-				servers += [[ip, port]]
+				if data[n*18:n*18+12] == "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff":
+					ip = ".".join(map(str, map(ord, data[n*18+12:n*18+16])))
+				else:
+					ip = ":".join(map(str, map(ord, data[n*18:n*18+16])))
+				port = (ord(data[n*18+16])<<8) + ord(data[n*18+17])
+				servers += [[(ip, port), SERVERTYPE_NORMAL]]
 
-	except: # timeout
+	except:
 		sock.close()
-		return servers
 
-def get_all_servers():
-	servers = []
-	for i in range(1, 16):
-		addr = "master%d.teeworlds.com"%i
-		list = get_servers(addr)
-		if list:
-			#print addr, "had", len(list), "servers"
-			servers += list
 	return servers
 
-servers = get_all_servers()
-total_players = 0
-players_per_versions = {}
-versions = {}
-gametypes = {}
-if 1:
-	for server in servers:
-		#print "checking server", server[0], server[1]
-		info = get_server_info(server[0], server[1])
-		if info:
-			total_players += len(info["players"])
-			if info["version"] in versions:
-				versions[info["version"]] += 1
-			else:
-				versions[info["version"]] = 1
 
-			if info["version"] in players_per_versions:
-				players_per_versions[info["version"]] += len(info["players"])
-			else:
-				players_per_versions[info["version"]] = len(info["players"])
 
-			if info["gametype"] in gametypes:
-				gametypes[info["gametype"]] += 1
-			else:
-				gametypes[info["gametype"]] = 1
+master_servers = []
+
+for i in range(1, NUM_MASTERSERVERS+1):
+	m = Master_Server_Info(("master%d.teeworlds.com"%i, MASTERSERVER_PORT))
+	master_servers.append(m)
+	m.start()
+	time.sleep(0.001) # avoid issues
+
+servers = []
+
+while len(master_servers) != 0:
+	if master_servers[0].finished == True:
+		if master_servers[0].servers:
+			servers += master_servers[0].servers
+		del master_servers[0]
+	time.sleep(0.001) # be nice
+
+servers_info = []
 
-print total_players
-				
-if 0:
-	print total_players, "on", len(servers), 'servers'
-	print "versions:"
-	for v in versions:
-		print "\t",v, versions[v]
+print str(len(servers)) + " servers"
+
+for server in servers:
+	s = Server_Info(server[0], server[1])
+	servers_info.append(s)
+	s.start()
+	time.sleep(0.001) # avoid issues
+
+num_players = 0
+num_clients = 0
+
+while len(servers_info) != 0:
+	if servers_info[0].finished == True:
+
+		if servers_info[0].info:
+			num_players += servers_info[0].info["num_players"]
+			if servers_info[0].type == SERVERTYPE_NORMAL:
+				num_clients += servers_info[0].info["num_clients"]
+			else:
+				num_clients += servers_info[0].info["num_players"]
 
-	print "players per version:"
-	for v in players_per_versions:
-		print "\t",v, players_per_versions[v]
+		del servers_info[0]
 
-	print "gametypes:"
-	for v in gametypes:
-		print "\t",v, gametypes[v]
+	time.sleep(0.001) # be nice
 
+print str(num_players) + " players and " + str(num_clients-num_players) + " spectators"
diff --git a/scripts/update_localization.py b/scripts/update_localization.py
deleted file mode 100644
index d6848411..00000000
--- a/scripts/update_localization.py
+++ /dev/null
@@ -1,90 +0,0 @@
-import os, re, sys
-match = re.search("(.*?)/[^/]*?$", sys.argv[0])
-if match != None:
-	os.chdir(os.getcwd() + "/" + match.group(1))
-
-source_exts = [".c", ".cpp", ".h"]
-
-def parse_source():
-	stringtable = {}
-	def process_line(line):
-		if 'Localize("'.encode() in line:
-			fields = line.split('Localize("'.encode(), 1)[1].split('"'.encode(), 1)
-			stringtable[fields[0]] = ""
-			process_line(fields[1])
-
-	for root, dirs, files in os.walk("../src"):
-		for name in files:
-			filename = os.path.join(root, name)
-			
-			if os.sep + "external" + os.sep in filename:
-				continue
-			
-			if filename[-2:] in source_exts or filename[-4:] in source_exts:
-				for line in open(filename, "rb"):
-					process_line(line)
-
-	return stringtable
-
-def load_languagefile(filename):
-	f = open(filename, "rb")
-	lines = f.readlines()
-	f.close()
-
-	stringtable = {}
-
-	for i in range(0, len(lines)-1):
-		l = lines[i].strip()
-		if len(l) and not l[0:1] == "=".encode() and not l[0:1] == "#".encode():
-			stringtable[l] = lines[i+1][3:].rstrip()
-
-	return stringtable
-
-def generate_languagefile(outputfilename, srctable, loctable):
-	f = open(outputfilename, "wb")
-
-	num_items = 0
-	new_items = 0
-	old_items = 0
-
-	srctable_keys = []
-	for key in srctable:
-		srctable_keys.append(key)
-	srctable_keys.sort()
-
-	content = "\n##### translated strings #####\n\n".encode()
-	for k in srctable_keys:
-		if k in loctable and len(loctable[k]):
-			content += k + "\n== ".encode() + loctable[k] + "\n\n".encode()
-			num_items += 1
-
-	content += "##### needs translation #####\n\n".encode()
-	for k in srctable_keys:
-		if not k in loctable or len(loctable[k]) == 0:
-			content += k + "\n== \n\n".encode()
-			num_items += 1
-			new_items += 1
-
-	content += "##### old translations #####\n\n".encode()
-	for k in loctable:
-		if not k in srctable:
-			content += k + "\n== ".encode() + loctable[k] + "\n\n".encode()
-			num_items += 1
-			old_items += 1
-
-	f.write(content)
-	f.close()
-	print("%-40s %8d %8d %8d" % (outputfilename, num_items, new_items, old_items))
-
-srctable = parse_source()
-
-print("%-40s %8s %8s %8s" % ("filename", "total", "new", "old"))
-
-for filename in os.listdir("../data/languages"):
-	if not ".txt" in filename:
-		continue
-	if filename == "index.txt":
-		continue
-
-	filename = "../data/languages/" + filename
-	generate_languagefile(filename, srctable, load_languagefile(filename))