diff -Nru teeworlds-0.5.1-src/src/engine/server/es_server.c antiflood/teeworlds-0.5.1-src/src/engine/server/es_server.c
--- teeworlds-0.5.1-src/src/engine/server/es_server.c	2009-01-25 13:50:32.000000000 +0100
+++ antiflood/teeworlds-0.5.1-src/src/engine/server/es_server.c	2009-08-20 21:50:58.000000000 +0200
@@ -637,6 +637,8 @@
 
 static void server_process_client_packet(NETCHUNK *packet)
 {
+	static int next_msg[MAX_CLIENTS] = {0};
+
 	int cid = packet->client_id;
 	NETADDR addr;
 	
@@ -806,11 +808,15 @@
 				msg_unpack_string(); /* login name, not used */
 				pw = msg_unpack_string();
 				
-				if(msg_unpack_error() == 0)
+				if(msg_unpack_error() == 0 && !clients[cid].authed)
 				{
 					if(config.sv_rcon_password[0] == 0)
 					{
-						server_send_rcon_line(cid, "No rcon password set on server. Set sv_rcon_password to enable the remote console.");
+						if(next_msg[cid] <= server_tick())
+						{
+							next_msg[cid] = server_tick() + server_tickspeed();
+							server_send_rcon_line(cid, "No rcon password set on server. Set sv_rcon_password to enable the remote console.");
+						}
 					}
 					else if(strcmp(pw, config.sv_rcon_password) == 0)
 					{
@@ -825,33 +831,45 @@
 					}
 					else
 					{
-						server_send_rcon_line(cid, "Wrong password.");
+						if(next_msg[cid] <= server_tick())
+						{
+							next_msg[cid] = server_tick() + server_tickspeed();
+							server_send_rcon_line(cid, "Wrong password.");
+						}
 					}
 				}
 			}
 			else if(msg == NETMSG_PING)
 			{
-				msg_pack_start_system(NETMSG_PING_REPLY, 0);
-				msg_pack_end();
-				server_send_msg(cid);
+				if(next_msg[cid] <= server_tick())
+				{
+					next_msg[cid] = server_tick() + server_tickspeed();
+					msg_pack_start_system(NETMSG_PING_REPLY, 0);
+					msg_pack_end();
+					server_send_msg(cid);
+				}
 			}
 			else
 			{
-				char hex[] = "0123456789ABCDEF";
-				char buf[512];
-				int b;
-
-				for(b = 0; b < packet->data_size && b < 32; b++)
+				if(next_msg[cid] <= server_tick())
 				{
-					buf[b*3] = hex[((const unsigned char *)packet->data)[b]>>4];
-					buf[b*3+1] = hex[((const unsigned char *)packet->data)[b]&0xf];
-					buf[b*3+2] = ' ';
-					buf[b*3+3] = 0;
-				}
+					char hex[] = "0123456789ABCDEF";
+					char buf[512];
+					int b;
 
-				dbg_msg("server", "strange message cid=%d msg=%d data_size=%d", cid, msg, packet->data_size);
-				dbg_msg("server", "%s", buf);
-				
+					next_msg[cid] = server_tick() + server_tickspeed();
+
+					for(b = 0; b < packet->data_size && b < 32; b++)
+					{
+						buf[b*3] = hex[((const unsigned char *)packet->data)[b]>>4];
+						buf[b*3+1] = hex[((const unsigned char *)packet->data)[b]&0xf];
+						buf[b*3+2] = ' ';
+						buf[b*3+3] = 0;
+					}
+
+					dbg_msg("server", "strange message cid=%d msg=%d data_size=%d", cid, msg, packet->data_size);
+					dbg_msg("server", "%s", buf);
+				}
 			}
 		}
 		else
diff -Nru teeworlds-0.5.1-src/src/game/server/hooks.cpp antiflood/teeworlds-0.5.1-src/src/game/server/hooks.cpp
--- teeworlds-0.5.1-src/src/game/server/hooks.cpp	2009-01-25 13:50:32.000000000 +0100
+++ antiflood/teeworlds-0.5.1-src/src/game/server/hooks.cpp	2009-08-20 21:54:00.000000000 +0200
@@ -172,17 +172,26 @@
 
 void mods_message(int msgtype, int client_id)
 {
+	static int next_msg[MAX_CLIENTS] = {0};
+
 	void *rawmsg = netmsg_secure_unpack(msgtype);
 	PLAYER *p = game.players[client_id];
 	
 	if(!rawmsg)
 	{
-		dbg_msg("server", "dropped weird message '%s' (%d), failed on '%s'", netmsg_get_name(msgtype), msgtype, netmsg_failed_on());
+		if(next_msg[client_id] <= server_tick())
+		{
+			next_msg[client_id] = server_tick() + server_tickspeed();
+			dbg_msg("server", "dropped weird message '%s' (%d), failed on '%s'", netmsg_get_name(msgtype), msgtype, netmsg_failed_on());
+		}
 		return;
 	}
 	
 	if(msgtype == NETMSGTYPE_CL_SAY)
 	{
+		if(config.sv_spamprotection && p->last_chat+time_freq() > time_get())
+			return;
+
 		NETMSG_CL_SAY *msg = (NETMSG_CL_SAY *)rawmsg;
 		int team = msg->team;
 		if(team)
@@ -190,9 +199,6 @@
 		else
 			team = GAMECONTEXT::CHAT_ALL;
 		
-		if(config.sv_spamprotection && p->last_chat+time_freq() > time_get())
-			return;
-		
 		p->last_chat = time_get();
 		
 		game.send_chat(client_id, team, msg->message);
@@ -202,16 +208,24 @@
 		int64 now = time_get();
 		if(game.vote_closetime)
 		{
-			game.send_chat_target(client_id, "Wait for current vote to end before calling a new one.");
+			if(next_msg[client_id] <= server_tick())
+			{
+				next_msg[client_id] = server_tick() + server_tickspeed();
+				game.send_chat_target(client_id, "Wait for current vote to end before calling a new one.");
+			}
 			return;
 		}
 		
 		int64 timeleft = p->last_votecall + time_freq()*60 - now;
 		if(timeleft > 0)
 		{
-			char chatmsg[512] = {0};
-			str_format(chatmsg, sizeof(chatmsg), "You must wait %d seconds before making another vote", (timeleft/time_freq())+1);
-			game.send_chat_target(client_id, chatmsg);
+			if(next_msg[client_id] <= server_tick())
+			{
+				next_msg[client_id] = server_tick() + server_tickspeed();
+				char chatmsg[512] = {0};
+				str_format(chatmsg, sizeof(chatmsg), "You must wait %d seconds before making another vote", (timeleft/time_freq())+1);
+				game.send_chat_target(client_id, chatmsg);
+			}
 			return;
 		}
 		
@@ -237,8 +251,12 @@
 			
 			if(!option)
 			{
-				str_format(chatmsg, sizeof(chatmsg), "'%s' isn't an option on this server", msg->value);
-				game.send_chat_target(client_id, chatmsg);
+				if(next_msg[client_id] <= server_tick())
+				{
+					next_msg[client_id] = server_tick() + server_tickspeed();
+					str_format(chatmsg, sizeof(chatmsg), "'%s' isn't an option on this server", msg->value);
+					game.send_chat_target(client_id, chatmsg);
+				}
 				return;
 			}
 		}
@@ -246,14 +264,22 @@
 		{
 			if(!config.sv_vote_kick)
 			{
-				game.send_chat_target(client_id, "Server does not allow voting to kick players");
+				if(next_msg[client_id] <= server_tick())
+				{
+					next_msg[client_id] = server_tick() + server_tickspeed();
+					game.send_chat_target(client_id, "Server does not allow voting to kick players");
+				}
 				return;
 			}
 			
 			int kick_id = atoi(msg->value);
 			if(kick_id < 0 || kick_id >= MAX_CLIENTS || !game.players[kick_id])
 			{
-				game.send_chat_target(client_id, "Invalid client id to kick");
+				if(next_msg[client_id] <= server_tick())
+				{
+					next_msg[client_id] = server_tick() + server_tickspeed();
+					game.send_chat_target(client_id, "Invalid client id to kick");
+				}
 				return;
 			}
 			
@@ -283,9 +309,13 @@
 
 		if(p->vote == 0)
 		{
-			NETMSG_CL_VOTE *msg = (NETMSG_CL_VOTE *)rawmsg;
-			p->vote = msg->vote;
-			game.send_vote_status(-1);
+			if(next_msg[client_id] <= server_tick())
+			{
+				next_msg[client_id] = server_tick() + server_tickspeed();
+				NETMSG_CL_VOTE *msg = (NETMSG_CL_VOTE *)rawmsg;
+				p->vote = msg->vote;
+				game.send_vote_status(-1);
+			}
 		}
 	}
 	else if (msgtype == NETMSGTYPE_CL_SETTEAM && !game.world.paused)
@@ -304,11 +334,15 @@
 				p->set_team(msg->team);
 				(void) game.controller->check_team_balance();
 			}
-			else
+			else if(next_msg[client_id] <= server_tick())
+			{
+				next_msg[client_id] = server_tick() + server_tickspeed();
 				game.send_broadcast("Teams must be balanced, please join other team", client_id);
+			}
 		}
-		else
+		else if(next_msg[client_id] <= server_tick())
 		{
+			next_msg[client_id] = server_tick() + server_tickspeed();
 			char buf[128];
 			str_format(buf, sizeof(buf), "Only %d active players are allowed", config.sv_max_clients-config.sv_spectator_slots);
 			game.send_broadcast(buf, client_id);
