diff -br teeworlds-0.5.2-src\banmasters.cfg teeworlds-0.5.2-src-banmaster\banmasters.cfg
0a1,2
> clear_banmasters
> add_banmaster banmaster.kottnet.net
diff -br teeworlds-0.5.2-src\src\banmaster\banmaster.h teeworlds-0.5.2-src-banmaster\src\banmaster\banmaster.h
0a1,12
> /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
> /* If you are missing that file, acquire a complete release at teeworlds.com.                */
> #ifndef BANMASTER_BANMASTER_H
> #define BANMASTER_BANMASTER_H
> 
> static const int BANMASTER_PORT = 8302;
> 
> static const char BANMASTER_IPOK[] = {255, 255, 255, 255, 'i', 'p', 'o', 'k'};
> static const char BANMASTER_IPBAN[] = {255, 255, 255, 255, 'i', 'p', 'b', 'a'};
> static const char BANMASTER_IPCHECK[] = {255, 255, 255, 255, 'i', 'p', 'c', 'h'};
> 
> #endif
diff -br teeworlds-0.5.2-src\src\engine\e_config_variables.h teeworlds-0.5.2-src-banmaster\src\engine\e_config_variables.h
68a69
> MACRO_CONFIG_INT(sv_global_bantime, 60, 0, 1440, CFGFLAG_SERVER, "Time for banmaster bans")
diff -br teeworlds-0.5.2-src\src\engine\e_network.h teeworlds-0.5.2-src-banmaster\src\engine\e_network.h
50c50,52
< 	NETBANTYPE_DROP=2
---
> 	NETBANTYPE_DROP=2,
> 
> 	NETSERVER_MAX_BANMASTERS=16
52a55
> 
77a81,85
> 
> int netserver_banmasters_add(NETSERVER *s, char *address);
> int netserver_banmasters_clear(NETSERVER *s);
> int netserver_banmasters_check(NETSERVER *s, NETADDR *addr);
> int netserver_banmasters_dump(NETSERVER *s);
diff -br teeworlds-0.5.2-src\src\engine\e_network_server.c teeworlds-0.5.2-src-banmaster\src\engine\e_network_server.c
4a5,6
> #include <banmaster/banmaster.h>
> 
61a64,66
> 	
> 	NETADDR banmasters[NETSERVER_MAX_BANMASTERS];
> 	int num_banmasters;
384a390,405
> 						NETCHUNK packet;
> 						char buffer[128];
> 						mem_copy(buffer, BANMASTER_IPCHECK, sizeof(BANMASTER_IPCHECK));
> 						net_addr_str(&addr, buffer + sizeof(BANMASTER_IPCHECK), sizeof(buffer) - sizeof(BANMASTER_IPCHECK));
> 						
> 						packet.client_id = -1;
> 						packet.flags = NETSENDFLAG_CONNLESS;
> 						packet.data_size = str_length(buffer) + 1;
> 						packet.data = buffer;
> 						
> 						for(i = 0; i < s->num_banmasters; i++)
> 						{
> 							packet.address = s->banmasters[i];
> 							netserver_send(s, &packet);
> 						}
> 						
489a511,555
> }
> 
> int netserver_banmasters_add(NETSERVER *s, char *address)
> {
> 	if(s->num_banmasters >= NETSERVER_MAX_BANMASTERS)
> 		return 2;
> 	
> 	if(net_host_lookup(address, &s->banmasters[s->num_banmasters], NETTYPE_IPV4))
> 		return 1;
> 	
> 	if(s->banmasters[s->num_banmasters].port == 0)
> 		s->banmasters[s->num_banmasters].port = BANMASTER_PORT;
> 	
> 	s->num_banmasters++;
> 	
> 	return 0;
> }
> 
> int netserver_banmasters_clear(NETSERVER *s)
> {
> 	s->num_banmasters = 0;
> 	return 0;
> }
> 
> int netserver_banmasters_check(NETSERVER *s, NETADDR *addr)
> {
> 	int i;
> 	for(i = 0; i < s->num_banmasters; i++)
> 	{
> 		if(!net_addr_comp(&s->banmasters[i], addr))
> 			return 1;
> 	}
> 	return 0;
> }
> 
> int netserver_banmasters_dump(NETSERVER *s)
> {
> 	int i;
> 	char ip[64];
> 	for(i	= 0; i < s->num_banmasters; i++)
> 	{
> 		net_addr_str(&s->banmasters[i], ip, sizeof(ip));
> 		dbg_msg("server/banmaster", "%d: %s", i, ip);
> 	}
> 	return 0;
diff -br teeworlds-0.5.2-src\src\engine\server\es_server.c teeworlds-0.5.2-src-banmaster\src\engine\server\es_server.c
24a25,26
> #include <banmaster/banmaster.h>
> 
31a34,35
> static const char SERVER_BANMASTERFILE[] = "banmasters.cfg";
> 
975a980,1027
> 				
> 				if(packet.data_size == sizeof(BANMASTER_IPOK) &&
> 					memcmp(packet.data, BANMASTER_IPOK, sizeof(BANMASTER_IPOK)) == 0 &&
> 					netserver_banmasters_check(net, &packet.address))
> 				{
> 				}
> 
> 				if(packet.data_size >= sizeof(BANMASTER_IPBAN) &&
> 					memcmp(packet.data, BANMASTER_IPBAN, sizeof(BANMASTER_IPBAN)) == 0 &&
> 					config.sv_global_bantime &&
> 					netserver_banmasters_check(net, &packet.address))
> 				{
> 					UNPACKER unpacker;
> 					char ip[32];
> 					char reason[256];
> 					char buffer[512];
> 					NETADDR addr;
> 					int i;
> 
> 					unpacker_reset(&unpacker, (unsigned char*)packet.data + sizeof(BANMASTER_IPBAN), packet.data_size - sizeof(BANMASTER_IPBAN));
> 
> 					str_copy(ip, unpacker_get_string(&unpacker), sizeof(ip));
> 					str_copy(reason, unpacker_get_string(&unpacker), sizeof(reason));
> 					str_sanitize(ip);
> 					str_sanitize(reason);
> 					
> 					if(net_addr_from_str(&addr, ip))
> 					{
> 						dbg_msg("globalbans", "dropped weird message from banmaster");
> 						return;
> 					}
> 					
> 					str_format(buffer, sizeof(buffer), "you have been banned for %d minutes (%s)", config.sv_global_bantime, reason);
> 					
> 					for(i = 0; i < MAX_CLIENTS; i++)
> 					{
> 						if(clients[i].state	!= SRVCLIENT_STATE_EMPTY)
> 						{
> 							NETADDR client_addr;
> 							netserver_client_addr(net, i, &client_addr);
> 							if(!net_addr_comp(&addr, &client_addr))
> 								netserver_drop(net, i, buffer);
> 						}
> 					}
> 					
> 					netserver_ban_add(net, addr, config.sv_global_bantime * 60);
> 					dbg_msg("globalbans", "added ban, ip=%d.%d.%d.%d, reason=\"%s\"", addr.ip[0], addr.ip[1], addr.ip[2], addr.ip[3], reason);
> 				}
1053a1106,1107
> 	console_execute_file(SERVER_BANMASTERFILE);
> 	
1335a1390,1410
> static void con_add_banmaster(void *result, void *user_data)
> {
> 	int adding_result = netserver_banmasters_add(net, console_arg_string(result, 0));
> 	if(adding_result == 0)
> 		dbg_msg("server/banmaster", "succesfully added banmaster '%s'", console_arg_string(result, 0));
> 	else if(adding_result == 1)
> 		dbg_msg("server/banmaster", "invalid address for banmaster / net lookup failed");
> 	else
> 		dbg_msg("server/banmaster", "too many banmasters");
> }
> 
> static void con_banmasters(void *result, void *user_data)
> {
> 	netserver_banmasters_dump(net);
> }
> 
> static void con_clear_banmasters(void *result, void *user_data)
> {
> 	netserver_banmasters_clear(net);
> }
> 
1346a1422,1425
> 	
> 	MACRO_REGISTER_COMMAND("add_banmaster", "s", CFGFLAG_SERVER, con_add_banmaster, 0, "");
> 	MACRO_REGISTER_COMMAND("banmasters", "", CFGFLAG_SERVER, con_banmasters, 0, "");
> 	MACRO_REGISTER_COMMAND("clear_banmasters", "", CFGFLAG_SERVER, con_clear_banmasters, 0, "");
