<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Teeworlds Forum — [MOD] for vanilla servers with spamprotection and kickvotes]]></title>
		<link>https://www.teeworlds.com/forum/viewtopic.php?id=1726</link>
		<atom:link href="https://www.teeworlds.com/forum/extern.php?action=feed&amp;tid=1726&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[The most recent posts in [MOD] for vanilla servers with spamprotection and kickvotes.]]></description>
		<lastBuildDate>Sat, 22 Nov 2008 08:58:45 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: [MOD] for vanilla servers with spamprotection and kickvotes]]></title>
			<link>https://www.teeworlds.com/forum/viewtopic.php?pid=27405#p27405</link>
			<description><![CDATA[<p>type in &quot;status&quot;, then you can see the player-id´s<br />then you type in dor example:ban 3 100</p><p>and you must start with the modded server <img src="https://www.teeworlds.com/forum/img/smilies/smile.png" alt="smile" /></p><p>GREETZ<br />TEEMENATOR</p>]]></description>
			<author><![CDATA[null@example.com (TEEMENATOR)]]></author>
			<pubDate>Sat, 22 Nov 2008 08:58:45 +0000</pubDate>
			<guid>https://www.teeworlds.com/forum/viewtopic.php?pid=27405#p27405</guid>
		</item>
		<item>
			<title><![CDATA[Re: [MOD] for vanilla servers with spamprotection and kickvotes]]></title>
			<link>https://www.teeworlds.com/forum/viewtopic.php?pid=27402#p27402</link>
			<description><![CDATA[<p>hehe i dont know what to do. If i give in rcon this in: &quot;ban 1 10&quot; or &quot;sv_ban 10&quot; and i tested some others too. then there comes &quot;there is no such command ban</p><p>I downloaded the folders which the guy who opened the thread said that i shall download and i put them in the teeworlds folder but it doesnt work. So what do i have to do?</p>]]></description>
			<author><![CDATA[null@example.com (Coffee Bean)]]></author>
			<pubDate>Sat, 22 Nov 2008 08:18:43 +0000</pubDate>
			<guid>https://www.teeworlds.com/forum/viewtopic.php?pid=27402#p27402</guid>
		</item>
		<item>
			<title><![CDATA[Re: [MOD] for vanilla servers with spamprotection and kickvotes]]></title>
			<link>https://www.teeworlds.com/forum/viewtopic.php?pid=18228#p18228</link>
			<description><![CDATA[<p>yes, perhaps i will make it later. perhaps someone else want to do this <img src="https://www.teeworlds.com/forum/img/smilies/wink.png" alt="wink" /></p>]]></description>
			<author><![CDATA[null@example.com (scosu)]]></author>
			<pubDate>Sat, 26 Jul 2008 17:30:06 +0000</pubDate>
			<guid>https://www.teeworlds.com/forum/viewtopic.php?pid=18228#p18228</guid>
		</item>
		<item>
			<title><![CDATA[Re: [MOD] for vanilla servers with spamprotection and kickvotes]]></title>
			<link>https://www.teeworlds.com/forum/viewtopic.php?pid=17801#p17801</link>
			<description><![CDATA[<p>I was just at martins server which I guess is running this mod for the vote kick functionality. There was someone ruining the game for us. So I was going to start a vote for kicking him, but he had a nick full of special characters so I wasn&#039;t able to type it. (Or is there a way of entering special characters in teeworlds?) He had probably changed his nick in the settings file to make it harder to type as a way of avoiding getting votekicked. I guess we&#039;d need kicking by ID&#039;s to get around this.</p><p>As an example, his nick was ¹·{[xD]}²³µ@&nbsp; ~*§%$µ</p>]]></description>
			<author><![CDATA[null@example.com (ziltoide)]]></author>
			<pubDate>Sun, 20 Jul 2008 16:22:42 +0000</pubDate>
			<guid>https://www.teeworlds.com/forum/viewtopic.php?pid=17801#p17801</guid>
		</item>
		<item>
			<title><![CDATA[Re: [MOD] for vanilla servers with spamprotection and kickvotes]]></title>
			<link>https://www.teeworlds.com/forum/viewtopic.php?pid=17744#p17744</link>
			<description><![CDATA[<p>@scosu<br />one more request. don&#039;t allow player without a name to join the server.</p><p>regards</p>]]></description>
			<author><![CDATA[null@example.com (martin.9)]]></author>
			<pubDate>Sat, 19 Jul 2008 14:23:31 +0000</pubDate>
			<guid>https://www.teeworlds.com/forum/viewtopic.php?pid=17744#p17744</guid>
		</item>
		<item>
			<title><![CDATA[Re: [MOD] for vanilla servers with spamprotection and kickvotes]]></title>
			<link>https://www.teeworlds.com/forum/viewtopic.php?pid=16846#p16846</link>
			<description><![CDATA[<p>first of all: a big big thanks to rajh for his football mod. it&#039;s really great.</p><p>i added some new stuff to it:<br />sv_nohook disables hook in the mod<br />sv_explosions enable(1) or disable(0) explosions of the grenades<br />sv_allow_gametype_votes it&#039;s renamed from sv_allow_votes for compatibility</p><p>and then the usual other stuff from this mod:<br /><a href="http://scosu.de/index.php?site=18&amp;language=en">http://scosu.de/index.php?site=18&amp;language=en</a></p>]]></description>
			<author><![CDATA[null@example.com (scosu)]]></author>
			<pubDate>Mon, 07 Jul 2008 19:18:38 +0000</pubDate>
			<guid>https://www.teeworlds.com/forum/viewtopic.php?pid=16846#p16846</guid>
		</item>
		<item>
			<title><![CDATA[Re: [MOD] for vanilla servers with spamprotection and kickvotes]]></title>
			<link>https://www.teeworlds.com/forum/viewtopic.php?pid=16808#p16808</link>
			<description><![CDATA[<p>@martin.9</p><p>thanks, but your patch doesn&#039;t work here. wanted to compile some binaries for linux so that everyone can download them.<br />for the first i made those few lines for instagib with my patch: <a href="http://scosu.de/index.php?site=17&amp;language=en">http://scosu.de/index.php?site=17&amp;language=en</a></p><p>football mod is ready but i have to test it first <img src="https://www.teeworlds.com/forum/img/smilies/wink.png" alt="wink" /></p>]]></description>
			<author><![CDATA[null@example.com (scosu)]]></author>
			<pubDate>Mon, 07 Jul 2008 12:47:26 +0000</pubDate>
			<guid>https://www.teeworlds.com/forum/viewtopic.php?pid=16808#p16808</guid>
		</item>
		<item>
			<title><![CDATA[Re: [MOD] for vanilla servers with spamprotection and kickvotes]]></title>
			<link>https://www.teeworlds.com/forum/viewtopic.php?pid=16806#p16806</link>
			<description><![CDATA[<p>How to join instagib to this mod?<br />I have problem with patching both mods to source.</p>]]></description>
			<author><![CDATA[null@example.com (CaptainHook)]]></author>
			<pubDate>Mon, 07 Jul 2008 11:11:25 +0000</pubDate>
			<guid>https://www.teeworlds.com/forum/viewtopic.php?pid=16806#p16806</guid>
		</item>
		<item>
			<title><![CDATA[Re: [MOD] for vanilla servers with spamprotection and kickvotes]]></title>
			<link>https://www.teeworlds.com/forum/viewtopic.php?pid=16792#p16792</link>
			<description><![CDATA[<p>I&#039;ve a football mod server (it&#039;s the version from Rajh) how can I apply your patch (with the blacklist...) and the patch from Rajh, so that I&#039;ve at least a server with handball/football mod and kick/ban/blacklist/Spam protection ?</p><p>Do I have to adjust the patch files? Or can I apply first the handball/football patch and then your patch?<br />Or do I have to change something in the patch files? Or do I have to apply your patch first?</p>]]></description>
			<author><![CDATA[null@example.com (Detructor2)]]></author>
			<pubDate>Mon, 07 Jul 2008 06:38:15 +0000</pubDate>
			<guid>https://www.teeworlds.com/forum/viewtopic.php?pid=16792#p16792</guid>
		</item>
		<item>
			<title><![CDATA[Re: [MOD] for vanilla servers with spamprotection and kickvotes]]></title>
			<link>https://www.teeworlds.com/forum/viewtopic.php?pid=16722#p16722</link>
			<description><![CDATA[<p>ok i merged the patches and here it is</p><p>- spamvote patch<br />- ctfbroad patch<br />- killingspree instagib spawnprotect patch</p><div class="codebox"><pre><code>diff -Naur teeworlds-0.4.2-src/src/engine/e_if_server.h patched/src/engine/e_if_server.h
--- teeworlds-0.4.2-src/src/engine/e_if_server.h    2008-04-05 15:13:02.000000000 +0200
+++ patched/src/engine/e_if_server.h    2008-07-06 12:40:02.000000000 +0200
@@ -106,7 +106,7 @@
         &lt;other_func&gt;
 */
 void server_kick(int client_id, const char *reason);
-
+void server_ban(int client_id, int time, char *ban_message);
 /*
     Function: server_tick
         TODO
diff -Naur teeworlds-0.4.2-src/src/engine/server/es_server.c patched/src/engine/server/es_server.c
--- teeworlds-0.4.2-src/src/engine/server/es_server.c    2008-04-05 15:13:02.000000000 +0200
+++ patched/src/engine/server/es_server.c    2008-07-06 12:40:02.000000000 +0200
@@ -2,6 +2,7 @@
 #include &lt;stdio.h&gt;
 #include &lt;string.h&gt;
 #include &lt;stdlib.h&gt;
+#include &lt;ctype.h&gt;
 
 #include &lt;engine/e_system.h&gt;
 #include &lt;engine/e_config.h&gt;
@@ -38,6 +39,9 @@
 static int current_map_crc;
 static unsigned char *current_map_data = 0;
 static int current_map_size = 0;
+int *banlist;
+int *bantime;
+int bans=0;
 
 void *snap_new_item(int type, int id, int size)
 {
@@ -107,6 +111,22 @@
 static CLIENT clients[MAX_CLIENTS];
 NETSERVER *net;
 
+struct blacklist
+{
+    char *name;
+    struct blacklist *next;
+};
+static struct blacklist *start, *end;
+
+static void str_lower(char *str)
+{
+    int i = 0;
+    for(;str[i];i++)
+    {
+        str[i] = tolower(str[i]);
+    }
+}
+
 static void snap_init_id()
 {
     int i;
@@ -222,10 +242,30 @@
 void server_setclientname(int client_id, const char *name)
 {
     char nametry[MAX_NAME_LENGTH];
+    char name_lower[MAX_NAME_LENGTH];
     int i;
+    struct blacklist *act;
+    act = start;
     if(client_id &lt; 0 || client_id &gt; MAX_CLIENTS || clients[client_id].state &lt; SRVCLIENT_STATE_READY)
         return;
-        
+    if(config.sv_name_blacklist)
+    {
+        strcpy(name_lower, name);
+        str_lower(name_lower);
+        dbg_msg(&quot;blacklist&quot;, &quot;name:%s&quot;, name_lower);
+        while(1)
+        {
+            dbg_msg(&quot;blacklist&quot;, &quot;diff:%s&quot;, (*act).name);
+            if(strstr(name_lower, (*act).name) != NULL)
+            {
+                server_ban(client_id, 30, &quot;Forbidden name&quot;);
+                return;
+            }
+            if(act == end)
+                break;
+            act = (*act).next;
+        }
+    }
     str_copy(nametry, name, MAX_NAME_LENGTH);
     if(server_try_setclientname(client_id, nametry))
     {
@@ -265,6 +305,33 @@
         netserver_drop(net, client_id, reason);
 }
 
+void server_ban(int client_id, int time, char *ban_message) {
+        NETADDR4 addr;
+        int clientip;
+    char reason[256];
+    if (clients[client_id].authed != 1)
+    {        
+        netserver_client_addr(net, client_id, &amp;addr);
+
+        clientip=(addr.ip[0]&lt;&lt;24)+(addr.ip[1]&lt;&lt;16)+(addr.ip[2]&lt;&lt;8)+addr.ip[3];
+        dbg_msg(&quot;server&quot;, &quot;the ip %d.%d.%d.%d is now banned&quot;,addr.ip[0],addr.ip[1],addr.ip[2],addr.ip[3]);
+
+        bans++;
+        if (bans==1) {banlist=malloc(sizeof(long));bantime=malloc(sizeof(long));}
+        else {banlist=realloc(banlist,sizeof(long)*bans);bantime=realloc(bantime,sizeof(long)*bans);}
+        banlist[bans-1]=clientip;
+        if(time &gt; 0)bantime[bans-1]=server_tick()+server_tickspeed()*time *60;
+        else bantime[bans-1]=0;
+        
+        if(time &gt; 0)str_format(reason, sizeof(reason), &quot;Banned by console for %d minutes&quot;,time);
+        else str_format(reason, sizeof(reason), &quot;Banned by console permanently.&quot;);
+        if(strlen(ban_message) &gt; 0)
+            server_kick(client_id, ban_message);
+        else
+            server_kick(client_id, reason);
+    }
+}
+
 int server_tick()
 {
     return current_tick;
@@ -602,6 +669,9 @@
     int cid = packet-&gt;client_id;
     int sys;
     int msg = msg_unpack_start(packet-&gt;data, packet-&gt;data_size, &amp;sys);
+    int i;
+    int clientip;
+    NETADDR4 addr;
     if(sys)
     {
         /* system message */
@@ -610,7 +680,7 @@
             char version[64];
             const char *password;
             str_copy(version, msg_unpack_string(), 64);
-            if(strcmp(version, mods_net_version()) != 0)
+            if(strcmp(version, &quot;0.4 1bd7780b0f76307c&quot;) != 0)
             {
                 /* OH FUCK! wrong version, drop him */
                 char reason[256];
@@ -629,7 +699,21 @@
                 netserver_drop(net, cid, &quot;wrong password&quot;);
                 return;
             }
-            
+            if(cid &gt;= (config.sv_max_clients-config.sv_reserved_slots) &amp;&amp; config.sv_reserved_slots_pass[0] != 0 &amp;&amp; strcmp(config.sv_reserved_slots_pass, password) != 0)
+            {
+                /* wrong password */
+                netserver_drop(net, cid, &quot;Dropped due reserved slot&quot;);
+                return;
+            }    
+
+            netserver_client_addr(net, cid, &amp;addr);
+            clientip=(addr.ip[0]&lt;&lt;24)+(addr.ip[1]&lt;&lt;16)+(addr.ip[2]&lt;&lt;8)+addr.ip[3];
+            for (i=0; i&lt;bans; i++) {
+                if (banlist[i]==clientip) {
+                    dbg_msg(&quot;server&quot;, &quot;a banned player (ip=%d.%d.%d.%d) is trying to enter&quot;,addr.ip[0],addr.ip[1],addr.ip[2],addr.ip[3]);
+                    netserver_drop(net, cid, &quot;You are banned&quot;);
+                }
+            }
             server_send_map(cid);
         }
         else if(msg == NETMSG_REQUEST_MAP_DATA)
@@ -926,7 +1010,38 @@
         mem_zero(&amp;bindaddr, sizeof(bindaddr));
         bindaddr.port = config.sv_port;
     }
-    
+    if(config.sv_name_blacklist)
+    {
+        
+        FILE *name_file = fopen(&quot;name_blacklist&quot;, &quot;r&quot;);
+        if(name_file != NULL)
+        {
+            char tmp_names[MAX_NAME_LENGTH];
+            if(fgets(tmp_names, MAX_NAME_LENGTH, name_file) != NULL)
+            {
+                tmp_names[strlen(tmp_names)-1] = 0;
+                start = malloc(sizeof(struct blacklist));
+                end = start;
+                (*start).name = malloc(MAX_NAME_LENGTH);
+                strcpy((*start).name, tmp_names);
+                str_lower((*start).name);
+            }
+            while(fgets(tmp_names, MAX_NAME_LENGTH, name_file) != NULL)
+            {
+                tmp_names[strlen(tmp_names)-1] = 0;
+                (*end).next = malloc(sizeof(struct blacklist));
+                end = (*end).next;
+                (*end).name = malloc(MAX_NAME_LENGTH);
+                strcpy((*end).name, tmp_names);
+                str_lower((*end).name);
+            }
+            fclose(name_file);
+        }
+        else
+        {
+            config.sv_name_blacklist = 0;
+        }
+    }
     net = netserver_open(bindaddr, config.sv_max_clients, 0);
     if(!net)
     {
@@ -1044,6 +1159,22 @@
                     server_do_snap();
                     perf_end();
                 }
+                if (bans&gt;0) {
+                    int i=0,j=0;
+                    for (i=0; i&lt;bans; i++) {
+                        if(bantime[i] != 0 &amp;&amp; server_tick()-bantime[i] &gt; server_tickspeed())
+                        {
+                            dbg_msg(&quot;server&quot;,&quot;the IP=%d:%d:%d:%d is no longer banned&quot;,i,((banlist[i]&gt;&gt;24)&amp;0xFF),((banlist[i]&gt;&gt;16)&amp;0xFF),((banlist[i]&gt;&gt;8)&amp;0xFF),(banlist[i]&amp;0xFF));
+                            for (j=i; j&lt;bans; j++) {
+                                banlist[j]=banlist[j+1];
+                                bantime[j]=bantime[j+1];
+                            }
+                            bans--;
+                            realloc(banlist,sizeof(long)*bans);
+                            realloc(bantime,sizeof(long)*bans);
+                        }
+                    }
+                }
             }
             
             /* master server stuff */
@@ -1100,6 +1231,56 @@
     server_kick(console_arg_int(result, 0), &quot;kicked by console&quot;);
 }
 
+static void con_ban(void *result, void *user_data) {
+        NETADDR4 addr;
+        int clientip;
+    char reason[256];
+        netserver_client_addr(net, console_arg_int(result, 0), &amp;addr);
+
+        clientip=(addr.ip[0]&lt;&lt;24)+(addr.ip[1]&lt;&lt;16)+(addr.ip[2]&lt;&lt;8)+addr.ip[3];
+        dbg_msg(&quot;server&quot;, &quot;the ip %d.%d.%d.%d is now banned&quot;,addr.ip[0],addr.ip[1],addr.ip[2],addr.ip[3]);
+
+        bans++;
+        if (bans==1) {banlist=malloc(sizeof(long));bantime=malloc(sizeof(long));}
+        else {banlist=realloc(banlist,sizeof(long)*bans);bantime=realloc(bantime,sizeof(long)*bans);}
+        banlist[bans-1]=clientip;
+    if(console_arg_int(result, 1) &gt; 0)bantime[bans-1]=server_tick()+server_tickspeed()*console_arg_int(result, 1)*60;
+    else bantime[bans-1]=0;
+
+    if(console_arg_int(result, 1) &gt; 0)str_format(reason, sizeof(reason), &quot;Banned by console for %d minutes&quot;,console_arg_int(result, 1));
+    else str_format(reason, sizeof(reason), &quot;Banned by console permanently.&quot;);
+    server_kick(console_arg_int(result, 0), reason);
+}
+
+static void con_banlist(void *result, void *user_data) {
+        int i;
+        if (bans&gt;0) {
+                for (i=0; i&lt;bans; i++) {
+                        dbg_msg(&quot;server&quot;,&quot;banid=%d, IP=%d:%d:%d:%d, time:%d min&quot;,i,((banlist[i]&gt;&gt;24)&amp;0xFF),((banlist[i]&gt;&gt;16)&amp;0xFF),((banlist[i]&gt;&gt;8)&amp;0xFF),(banlist[i]&amp;0xFF),(bantime[i]-server_tick())/(server_tickspeed()*60));
+                }
+        } else {
+                dbg_msg(&quot;server&quot;,&quot;there is no ban&quot;);
+        }
+}
+
+static void con_unban(void *result, void *user_data) {
+        int i=0;
+        int d=console_arg_int(result, 0);
+
+        if (d&lt;0 || d&gt;=bans) dbg_msg(&quot;server&quot;,&quot;no such banid: %d, type banlist to see banids&quot;,d);
+        else 
+    {
+        dbg_msg(&quot;server&quot;,&quot;the IP=%d:%d:%d:%d is no longer banned&quot;,d,((banlist[d]&gt;&gt;24)&amp;0xFF),((banlist[d]&gt;&gt;16)&amp;0xFF),((banlist[d]&gt;&gt;8)&amp;0xFF),(banlist[d]&amp;0xFF));
+                for (i=d; i&lt;bans; i++) {
+                        banlist[i]=banlist[i+1];
+            bantime[i]=bantime[i+1];
+                }
+                bans--;
+                realloc(banlist,sizeof(long)*bans);
+        realloc(bantime,sizeof(long)*bans);
+    }
+}
+
 static void con_status(void *result, void *user_data)
 {
     int i;
@@ -1122,11 +1303,33 @@
     /*server_kick(console_arg_int(result, 0), &quot;kicked by console&quot;);*/
 }
 
+static void con_add_name_blacklist(void *result, void *user_data)
+{
+    FILE *names_blacklist = fopen(&quot;name_blacklist&quot;, &quot;a&quot;);
+    (*end).next = malloc(sizeof(struct blacklist));
+    end = (*end).next;
+    (*end).name = malloc(MAX_NAME_LENGTH);
+    
+    strcpy((*end).name, console_arg_string(result, 0));
+    str_lower((*end).name);
+    if(names_blacklist != NULL)
+    {
+        
+        fputs((*end).name, names_blacklist);
+        fputs(&quot;\n&quot;, names_blacklist);
+        fclose(names_blacklist);
+    }
+}
+
 static void server_register_commands()
 {
     MACRO_REGISTER_COMMAND(&quot;kick&quot;, &quot;i&quot;, con_kick, 0);
     MACRO_REGISTER_COMMAND(&quot;status&quot;, &quot;&quot;, con_status, 0);
     MACRO_REGISTER_COMMAND(&quot;shutdown&quot;, &quot;&quot;, con_shutdown, 0);
+    MACRO_REGISTER_COMMAND(&quot;ban&quot;, &quot;ii&quot;, con_ban, 0);
+    MACRO_REGISTER_COMMAND(&quot;banlist&quot;, &quot;&quot;, con_banlist, 0);
+    MACRO_REGISTER_COMMAND(&quot;unban&quot;, &quot;i&quot;, con_unban, 0);
+    MACRO_REGISTER_COMMAND(&quot;add_blacklist&quot;, &quot;s&quot;, con_add_name_blacklist, 0);
 }
 
 int main(int argc, char **argv)
diff -Naur teeworlds-0.4.2-src/src/game/g_variables.h patched/src/game/g_variables.h
--- teeworlds-0.4.2-src/src/game/g_variables.h    2008-04-05 15:13:02.000000000 +0200
+++ patched/src/game/g_variables.h    2008-07-06 13:15:23.000000000 +0200
@@ -57,3 +57,28 @@
 MACRO_CONFIG_INT(sv_spamprotection, 1, 0, 1)
 
 MACRO_CONFIG_INT(sv_spectator_slots, 0, 0, 12)
+
+MACRO_CONFIG_INT(sv_ctfbroad, 1, 0, 1)
+MACRO_CONFIG_STR(sv_ctfmsg, 512, &quot; captured the flag!&quot;)
+
+MACRO_CONFIG_INT(sv_teamchanges, 0, 0, 100)
+MACRO_CONFIG_INT(sv_time_blocked, 180, 1, 1000)
+MACRO_CONFIG_INT(sv_teamchangeskick, 0, 0, 100)
+MACRO_CONFIG_INT(sv_teamchangesban, 0, 0, 100)
+MACRO_CONFIG_INT(sv_messagesnum, 0, 0, 100)
+MACRO_CONFIG_INT(sv_same_messages, 0, 0, 100)
+MACRO_CONFIG_INT(sv_time_muted, 180, 1, 1000)
+MACRO_CONFIG_INT(sv_messageskick, 0, 0, 100)
+MACRO_CONFIG_INT(sv_messagesban, 0, 0, 100)
+MACRO_CONFIG_STR(sv_startmessage, 1000, &quot;&quot;)
+MACRO_CONFIG_STR(sv_endroundmessage, 1000, &quot;&quot;)
+MACRO_CONFIG_INT(sv_handle_mapvotes, 0, 0, 1)
+MACRO_CONFIG_INT(sv_kick_teamkiller, 0, 0, 100)
+MACRO_CONFIG_INT(sv_name_blacklist, 0, 0, 1)
+MACRO_CONFIG_INT(sv_reserved_slots, 0, 0, 12)
+MACRO_CONFIG_STR(sv_reserved_slots_pass, 32, &quot;&quot;)
+MACRO_CONFIG_INT(sv_allow_votes, 1, 0, 1)
+MACRO_CONFIG_INT(sv_all_vote, 0, 0, 1)
+MACRO_CONFIG_INT(sv_votetime, 60, 0, 500)
+MACRO_CONFIG_INT(sv_ban_time, 10, 0, 1000)
+
diff -Naur teeworlds-0.4.2-src/src/game/server/gs_common.h patched/src/game/server/gs_common.h
--- teeworlds-0.4.2-src/src/game/server/gs_common.h    2008-04-05 15:13:02.000000000 +0200
+++ patched/src/game/server/gs_common.h    2008-07-06 13:00:32.000000000 +0200
@@ -131,8 +131,10 @@
     int round_count;
     
     bool is_teamplay;
-    
+
 public:
+    char spree_msg[128];
+    
     int gametype;
     gameobject();
 
@@ -238,6 +240,9 @@
 // player entity
 class player : public entity
 {
+private:
+    int spawn_tick;
+
 public:
     static const int phys_size = 28;
 
@@ -299,8 +304,12 @@
 
     //
     int score;
+    int lastplayer;
+    int lastplayertime;
+    int votedfor;
     int team;
     int player_state; // if the client is chatting, accessing a menu or so
+    unsigned int spree;
     
     bool spawning;
     bool dead;
@@ -352,6 +361,10 @@
     
     virtual bool take_damage(vec2 force, int dmg, int from, int weapon);
     virtual void snap(int snaping_client);
+    
+    int last_message_tick; unsigned char message_num; bool muted;
+    bool teamchanging; unsigned char team_changes; int last_team_set;
+    bool voted;
 };
 
 extern player *players;
diff -Naur teeworlds-0.4.2-src/src/game/server/gs_game.cpp patched/src/game/server/gs_game.cpp
--- teeworlds-0.4.2-src/src/game/server/gs_game.cpp    2008-04-05 15:13:02.000000000 +0200
+++ patched/src/game/server/gs_game.cpp    2008-07-06 13:05:40.000000000 +0200
@@ -90,7 +90,15 @@
 {
     if(warmup) // game can&#039;t end when we are running warmup
         return;
-        
+    if(strlen(config.sv_endroundmessage) &gt; 0)
+    {
+        NETMSG_SV_CHAT msg;
+        msg.team = 0;
+        msg.cid = -1;
+        msg.message = config.sv_endroundmessage;
+        msg.pack(MSGFLAG_VITAL);
+        server_send_msg(-1);
+    }
     world-&gt;paused = true;
     game_over_tick = server_tick();
     sudden_death = 0;
@@ -197,20 +205,58 @@
     }
 }
 
+char spree_note[6][64] = { &quot;is on a killing spree!&quot;, &quot;is on a rampage!&quot;, &quot;is dominating&quot;, &quot;is unstoppable!&quot;, &quot;is Godlike!&quot;, &quot;is Wicked SICK!!&quot; };
+
+void broadcast_spree(class player *p1, class player *p2)
+{
+    NETMSG_SV_BROADCAST msg;
+
+    if(!p2)
+        str_format(gameobj-&gt;spree_msg, sizeof(gameobj-&gt;spree_msg), &quot;%s %s&quot;, server_clientname(p1-&gt;client_id), spree_note[(p1-&gt;spree/5)-1]);
+    else
+        str_format(gameobj-&gt;spree_msg, sizeof(gameobj-&gt;spree_msg), &quot;%s&#039;s killing spree ended by %s&quot;, server_clientname(p1-&gt;client_id), server_clientname(p2-&gt;client_id));
+
+    msg.message = gameobj-&gt;spree_msg;
+    msg.pack(MSGFLAG_VITAL);
+    server_send_msg(-1);
+}
+
+void increment_spree(class player *p)
+{
+    if(++(p-&gt;spree) &lt; 31 &amp;&amp; (p-&gt;spree)%5 == 0)
+        broadcast_spree(p, NULL);
+}
+
+void end_spree(class player *victim, class player *killer)
+{
+    if(victim-&gt;spree &gt; 4)
+        broadcast_spree(victim, killer);
+    victim-&gt;spree = 0;
+}
 
 int gameobject::on_player_death(class player *victim, class player *killer, int weapon)
 {
     // do scoreing
-    if(!killer)
-        return 0;
-    if(killer == victim)
-        victim-&gt;score--; // suicide
-    else
+    if(weapon != -1)
     {
-        if(is_teamplay &amp;&amp; victim-&gt;team == killer-&gt;team)
-            killer-&gt;score--; // teamkill
+        if(!killer)
+            return 0;
+        end_spree(victim, killer);
+        if(killer == victim)
+            victim-&gt;score--; // suicide
         else
-            killer-&gt;score++; // normal kill
+        {
+            if(is_teamplay &amp;&amp; victim-&gt;team == killer-&gt;team)
+                killer-&gt;score--; // teamkill
+            else
+                killer-&gt;score++; // normal kill
+            increment_spree(killer);
+        }
+        if(config.sv_kick_teamkiller != 0 &amp;&amp; killer-&gt;score &lt;= -config.sv_kick_teamkiller &amp;&amp; gametype == GAMETYPE_TDM)
+        {
+            if(killer-&gt;team != -1)
+                teamscore[killer-&gt;team] -= killer-&gt;score;
+        }
     }
     return 0;
 }
diff -Naur teeworlds-0.4.2-src/src/game/server/gs_game_ctf.cpp patched/src/game/server/gs_game_ctf.cpp
--- teeworlds-0.4.2-src/src/game/server/gs_game_ctf.cpp    2008-04-05 15:13:02.000000000 +0200
+++ patched/src/game/server/gs_game_ctf.cpp    2008-07-06 13:08:35.000000000 +0200
@@ -1,6 +1,9 @@
 /* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
 #include &lt;engine/e_server_interface.h&gt;
 #include &lt;game/g_mapitems.h&gt;
+#include &lt;engine/e_config.h&gt;
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
 #include &quot;gs_common.h&quot;
 #include &quot;gs_game_ctf.h&quot;
 
@@ -90,6 +93,16 @@
 
                     dbg_msg(&quot;game&quot;, &quot;flag_capture player=&#039;%d:%s&#039;&quot;, f-&gt;carrying_player-&gt;client_id, server_clientname(f-&gt;carrying_player-&gt;client_id));
 
+                                        //Captured the flag patch
+                    if (config.sv_ctfbroad) {
+                                            char bravo[256];
+                                            sprintf(bravo,&quot;%s %s&quot;,server_clientname(f-&gt;carrying_player-&gt;client_id),config.sv_ctfmsg);
+                                            NETMSG_SV_BROADCAST msg;
+                                            msg.message = bravo;
+                                            msg.pack(MSGFLAG_VITAL);
+                                            server_send_msg(-1);
+                    }
+
                     for(int i = 0; i &lt; 2; i++)
                         flags[i]-&gt;reset();
                     
diff -Naur teeworlds-0.4.2-src/src/game/server/gs_server.cpp patched/src/game/server/gs_server.cpp
--- teeworlds-0.4.2-src/src/game/server/gs_server.cpp    2008-04-05 15:13:02.000000000 +0200
+++ patched/src/game/server/gs_server.cpp    2008-07-06 13:00:32.000000000 +0200
@@ -26,7 +26,7 @@
 void create_sound(vec2 pos, int sound, int mask=-1);
 class player *intersect_player(vec2 pos0, vec2 pos1, float radius, vec2 &amp;new_pos, class entity *notthis = 0);
 class player *closest_player(vec2 pos, float radius, entity *notthis);
-
+int timer_vote=-1;bool vote_called=false;int votetime=-1;char votetype[32];int votedtokick=-1;
 game_world *world;
 
 enum
@@ -36,9 +36,119 @@
     CHAT_RED=0,
     CHAT_BLUE=1
 };
-
 static void send_chat(int cid, int team, const char *text)
 {
+    static char lastmessages[12][1000];
+    static short int same_messages[12];
+    player *tmp = get_player(cid);
+    if(config.sv_handle_mapvotes &amp;&amp; (strcmp(&quot;/++&quot;,text) == 0 || strcmp(&quot;/--&quot;, text) == 0))
+    {
+        if(tmp-&gt;voted)
+        {
+            char voted[] = &quot;You already voted the map, ignoring vote&quot;;
+            NETMSG_SV_CHAT msg;
+            msg.team = 0;
+            msg.cid = -1;
+            msg.message = voted;
+            msg.pack(MSGFLAG_VITAL);
+            server_send_msg(cid);
+        }
+        else
+        {
+            tmp-&gt;voted = true;
+            dbg_msg(&quot;game&quot;, &quot;map-voting %s&quot;, text);
+            char voted[] = &quot;You voted for the map, thank you&quot;;
+            NETMSG_SV_CHAT msg;
+            msg.team = 0;
+            msg.cid = -1;
+            msg.message = voted;
+            msg.pack(MSGFLAG_VITAL);
+            server_send_msg(cid);
+        }
+        
+        
+        return;
+    }
+    
+    if(config.sv_messagesnum &amp;&amp; cid &gt; -1 &amp;&amp; cid &lt; MAX_CLIENTS)
+    {
+        
+        
+        if(tmp-&gt;muted)
+        {
+            if(tmp-&gt;last_message_tick + config.sv_time_muted*SERVER_TICK_SPEED &gt; server_tick())
+            {
+                tmp-&gt;message_num++;
+                if(config.sv_messageskick &amp;&amp; tmp-&gt;message_num &gt; config.sv_messageskick)
+                {
+                    char *kicking = (char *)malloc(sizeof(char) * 200);
+                    sprintf(kicking, &quot;%s was kicked because of spamming.&quot;, server_clientname(cid));
+                    dbg_msg(&quot;chat&quot;, &quot;*** %s&quot;, kicking);
+                    NETMSG_SV_CHAT msg;
+                    msg.team = 0;
+                    msg.cid = -1;
+                    msg.message = kicking;
+                    msg.pack(MSGFLAG_VITAL);
+                    server_send_msg(-1);
+                    free(kicking);
+                    if(config.sv_messagesban)
+                    {
+                        char ban_message[255];
+                        sprintf(ban_message, &quot;You were banned for %i minutes because of spamming&quot;, config.sv_messagesban);
+                        server_ban(cid, config.sv_teamchangesban, ban_message);
+                    }
+                    else
+                        server_kick(cid,&quot;You were kicked because of spamming&quot;);
+                }
+                return;
+            }
+            else
+            {
+                tmp-&gt;muted = false;
+                tmp-&gt;message_num = 0;
+                tmp-&gt;last_message_tick = server_tick();
+            }
+        }
+        else
+        {
+            if(tmp-&gt;last_message_tick + 30*SERVER_TICK_SPEED &gt; server_tick())
+            {
+                tmp-&gt;message_num++;
+                if(config.sv_same_messages &amp;&amp; strcmp(lastmessages[cid], text) == 0)
+                {
+                    dbg_msg(&quot;messsages&quot;, &quot;same message&quot;);
+                    same_messages[cid]++;
+                }
+                else
+                {
+                    strncpy(lastmessages[cid], text, 1000);
+                    same_messages[cid] = 0;
+                }
+                if(tmp-&gt;message_num &gt;= config.sv_messagesnum || (config.sv_same_messages &amp;&amp; config.sv_same_messages &lt;= same_messages[cid]))
+                {
+                    tmp-&gt;muted = true;same_messages[cid] = 0;
+                    tmp-&gt;message_num = 0;
+                    char *muting = (char *)malloc(sizeof(char) * 200);
+                    sprintf(muting, &quot;%s was muted for %d seconds because of spamming.&quot;, server_clientname(cid), config.sv_time_muted);
+                    dbg_msg(&quot;chat&quot;, &quot;*** %s&quot;, muting);
+                    NETMSG_SV_CHAT msg;
+                    msg.team = 0;
+                    msg.cid = -1;
+                    msg.message = muting;
+                    msg.pack(MSGFLAG_VITAL);
+                    server_send_msg(-1);
+                    free(muting);
+                    return;
+                }
+                    
+            }
+            else
+            {
+                tmp-&gt;last_message_tick = server_tick();
+                tmp-&gt;message_num = 0;
+            }
+        }
+    }
     if(cid &gt;= 0 &amp;&amp; cid &lt; MAX_CLIENTS)
         dbg_msg(&quot;chat&quot;, &quot;%d:%d:%s: %s&quot;, cid, team, server_clientname(cid), text);
     else
@@ -120,6 +230,53 @@
     server_send_msg(cid);
 }
 
+void resultvote()
+{
+    int players_serv=0,total=0,voteur=0;
+    for (int i=0; i &lt; MAX_CLIENTS;i++)
+    {
+        if(players[i].client_id !=-1)
+        {
+            if(players[i].votedfor != -1)
+            {total+=players[i].votedfor;voteur++;}
+            players_serv++;
+        }
+    }
+    char buf[256];
+    str_format(buf, sizeof(buf), &quot;YES: %d | NO: %d (Time remaining : %d/%d secondes)&quot;,total,voteur-total,(server_tick()-timer_vote)/(server_tickspeed()),votetime);
+    send_chat(-1,CHAT_ALL,buf);
+    if (voteur==players_serv || (server_tick()-timer_vote  &gt; server_tickspeed()*votetime &amp;&amp; timer_vote != -1))
+    {
+        vote_called=false;
+        int result=1;
+        char message[256];
+        if((total &gt; voteur / 2 &amp;&amp; !config.sv_all_vote) || (total &gt; players_serv / 2 &amp;&amp; config.sv_all_vote))str_format(message, sizeof(message), &quot;Result for the vote is : YES&quot;);
+        else {str_format(message, sizeof(message), &quot;Result for the vote is : NO&quot;);result=0;}
+        send_chat(-1,CHAT_ALL,message);
+        if(!strcmp(votetype,&quot;kick&quot;) &amp;&amp; votedtokick != -1)
+        {    
+            if(result)
+            {
+                char reason[256];
+                //str_format(reason, sizeof(reason), &quot;Kicked&quot;);
+                //server_kick(votedfor,reason);
+                str_format(reason, sizeof(reason), &quot;%s has been kicked.&quot;,server_clientname(votedtokick));
+                send_chat(-1,-1, reason);
+                server_ban(votedtokick,config.sv_ban_time, &quot;&quot;);
+            }    
+            str_format(votetype, sizeof(votetype), &quot;null&quot;);
+            votedtokick = -1;    
+        }
+        for (int i=0; i &lt; MAX_CLIENTS;i++)
+        {
+            if(players[i].client_id !=-1)
+            {
+                players[i].votedfor=-1;
+            }
+        }
+    }    
+}
+
 //////////////////////////////////////////////////
 // Event handler
 //////////////////////////////////////////////////
@@ -352,7 +509,7 @@
 {
     if(reset_requested)
         reset();
-
+    if(timer_vote != -1 &amp;&amp; server_tick()-timer_vote  &gt; server_tickspeed()*votetime &amp;&amp; vote_called)resultvote();
     if(!paused)
     {
         /*
@@ -659,6 +816,10 @@
 
 void player::init()
 {
+    voted = false;
+    teamchanging = false; team_changes = 0; last_team_set = server_tick();
+    last_message_tick = server_tick(); message_num = 0; muted = false;
+    
     proximity_radius = phys_size;
     client_id = -1;
     team = -1; // -1 == spectator
@@ -683,6 +844,7 @@
     
     //direction = vec2(0.0f, 1.0f);
     score = 0;
+    spree = 0;
     dead = true;
     clear_flag(entity::FLAG_PHYSICS);
     spawning = false;
@@ -700,6 +862,7 @@
 
     emote_stop = 0;
     damage_taken_tick = 0;
+    spawn_tick = 0;
     attack_tick = 0;
 
     mem_zero(&amp;ninja, sizeof(ninja));
@@ -750,6 +913,74 @@
 
 void player::set_team(int new_team)
 {
+    if(config.sv_teamchanges)
+    {
+        if(teamchanging)
+        {
+            if(last_team_set + config.sv_time_blocked*SERVER_TICK_SPEED &gt; server_tick())
+            {
+                team_changes++;
+                if(config.sv_teamchangeskick &amp;&amp; team_changes &gt; config.sv_teamchangeskick)
+                {
+                    
+                    char *kicking = (char *)malloc(sizeof(char) * 200);
+                    sprintf(kicking, &quot;%s was kicked because of fast teamchanging.&quot;, server_clientname(client_id));
+                    dbg_msg(&quot;chat&quot;, &quot;*** %s&quot;, kicking);
+                    NETMSG_SV_CHAT msg;
+                    msg.team = 0;
+                    msg.cid = -1;
+                    msg.message = kicking;
+                    msg.pack(MSGFLAG_VITAL);
+                    server_send_msg(-1);
+                    free(kicking);
+                    if(config.sv_teamchangesban)
+                    {
+                        char ban_message[255];
+                        sprintf(ban_message, &quot;You were banned for %i minutes because of fast teamchanging&quot;, config.sv_teamchangesban);
+                        server_ban(client_id, config.sv_teamchangesban, ban_message);
+                    }
+                    else
+                        server_kick(client_id,&quot;You were kicked because of fast teamchanging&quot;);
+                }
+                return;
+            }
+            else
+            {
+                teamchanging = false;
+                team_changes = 0;
+                last_team_set = server_tick();
+            }
+        }
+        else
+        {
+            if(last_team_set + 30*SERVER_TICK_SPEED &gt; server_tick())
+            {
+                team_changes++;
+                if(config.sv_teamchanges &amp;&amp; team_changes &gt;= config.sv_teamchanges)
+                {
+                    teamchanging = true;
+                    team_changes = 0;
+                    char *blocking = (char *)malloc(sizeof(char) * 200);
+                    sprintf(blocking, &quot;%s can&#039;t change team for %d seconds&quot;, server_clientname(client_id), config.sv_time_blocked);
+                    dbg_msg(&quot;chat&quot;, &quot;*** %s&quot;, blocking);
+                    NETMSG_SV_CHAT msg;
+                    msg.team = 0;
+                    msg.cid = -1;
+                    msg.message = blocking;
+                    msg.pack(MSGFLAG_VITAL);
+                    server_send_msg(-1);
+                    free(blocking);
+                    return;
+                }
+                    
+            }
+            else
+            {
+                last_team_set = server_tick();
+                team_changes = 0;
+            }
+        }
+    }
     // clamp the team
     new_team = gameobj-&gt;clampteam(new_team);
     if(team == new_team)
@@ -914,6 +1145,7 @@
     dead = false;
     set_flag(entity::FLAG_PHYSICS);
     player_state = PLAYERSTATE_PLAYING;
+    spree = 0;
 
     core.hook_state = HOOK_IDLE;
 
@@ -921,20 +1153,23 @@
 
     // init weapons
     mem_zero(&amp;weapons, sizeof(weapons));
-    weapons[WEAPON_HAMMER].got = true;
+    /*weapons[WEAPON_HAMMER].got = true;
     weapons[WEAPON_HAMMER].ammo = -1;
     weapons[WEAPON_GUN].got = true;
-    weapons[WEAPON_GUN].ammo = data-&gt;weapons[WEAPON_GUN].maxammo;
+    weapons[WEAPON_GUN].ammo = data-&gt;weapons[WEAPON_GUN].maxammo;*/
 
-    /*weapons[WEAPON_RIFLE].got = true;
-    weapons[WEAPON_RIFLE].ammo = -1;*/
+    weapons[WEAPON_RIFLE].got = true;
+    weapons[WEAPON_RIFLE].ammo = -1;
     
-    active_weapon = WEAPON_GUN;
-    last_weapon = WEAPON_HAMMER;
-    queued_weapon = 0;
+    active_weapon = WEAPON_RIFLE;
+    last_weapon = WEAPON_RIFLE;
+    queued_weapon = -1;
 
     reload_timer = 0;
 
+    // Spawn protection
+    spawn_tick = server_tick();
+
     // Create sound and spawn effects
     create_sound(pos, SOUND_PLAYER_SPAWN);
     create_playerspawn(pos);
@@ -1517,12 +1752,29 @@
     die_tick = server_tick();
     clear_flag(FLAG_PHYSICS);
     create_death(pos, client_id);
+    if(config.sv_kick_teamkiller != 0 &amp;&amp; score &lt;= -config.sv_kick_teamkiller)
+    {
+        char *kickmessage = (char*)malloc(1000);
+        sprintf(kickmessage, &quot;%s was kicked because of teamkilling/selfkillng.&quot;, server_clientname(client_id));
+        dbg_msg(&quot;chat&quot;, &quot;*** %s&quot;, kickmessage);
+        NETMSG_SV_CHAT msg;
+        msg.team = 0;
+        msg.cid = -1;
+        msg.message = kickmessage;
+        msg.pack(MSGFLAG_VITAL);
+        server_send_msg(-1);
+        server_kick(client_id, &quot;You were kicked because of teamkilling/selfkilling&quot;);
+    }
 }
 
 bool player::take_damage(vec2 force, int dmg, int from, int weapon)
 {
     core.vel += force;
-    
+
+    // Spawn protection
+    if(server_tick()-spawn_tick &lt;= server_tickspeed())
+        return false;
+
     if(gameobj-&gt;is_friendly_fire(client_id, from) &amp;&amp; !config.sv_teamdamage)
         return false;
 
@@ -1690,10 +1942,10 @@
     subtype = _subtype;
     proximity_radius = phys_size;
 
-    reset();
+    //reset();
 
     // TODO: should this be done here?
-    world-&gt;insert_entity(this);
+    //world-&gt;insert_entity(this);
 }
 
 void powerup::reset()
@@ -2061,7 +2313,15 @@
     char buf[512];
     str_format(buf, sizeof(buf), &quot;%s entered and joined the %s&quot;, server_clientname(client_id), get_team_name(players[client_id].team));
     send_chat(-1, CHAT_ALL, buf); 
-
+    if(strlen(config.sv_startmessage) &gt; 0)
+    {
+        NETMSG_SV_CHAT msg;
+        msg.team = 0;
+        msg.cid = -1;
+        msg.message = config.sv_startmessage;
+        msg.pack(MSGFLAG_VITAL);
+        server_send_msg(client_id);
+    }
     dbg_msg(&quot;game&quot;, &quot;team_join player=&#039;%d:%s&#039; team=%d&quot;, client_id, server_clientname(client_id), players[client_id].team);
 }
 
@@ -2121,8 +2381,81 @@
         }
         else
         {
-            players[client_id].last_chat = time_get();
-            send_chat(client_id, team, msg-&gt;message);
+            if(!strcasecmp(msg-&gt;message, &quot;.info&quot;))
+            {
+                char buf[128];
+                str_format(buf, sizeof(buf), &quot;Mod from Rajh and scosu. Available commands:&quot;);
+                send_chat(-1,CHAT_ALL,buf);
+                send_chat(-1, CHAT_ALL, &quot;Positive map-voting: /++&quot;);
+                send_chat(-1, CHAT_ALL, &quot;Negative map-voting: /--&quot;);
+                send_chat(-1, CHAT_ALL, &quot;Kick player by name: /kick &lt;player name&gt;&quot;);
+                send_chat(-1, CHAT_ALL, &quot;Current vote: /currentvote&quot;);
+                players[client_id].last_chat = time_get()+time_freq()*10;
+            }
+            else if (!strncasecmp(msg-&gt;message, &quot;/kick&quot;,5) &amp;&amp; !vote_called &amp;&amp; config.sv_allow_votes)
+            {
+                int playersnumber=0;
+                int playerstokick=-1;
+                char message[256];
+                for (int i=0; i &lt; MAX_CLIENTS;i++)
+                {
+                    if(players[i].client_id !=-1)
+                    {
+                        str_format(message, sizeof(message), &quot;/kick &quot;);
+                        strcat(message,server_clientname(i));
+                        if(!strncmp(msg-&gt;message, message,9))
+                        {
+                            playersnumber++;
+                            playerstokick=i;
+                        }
+                    }
+                }
+                if(playersnumber == 1 &amp;&amp; playerstokick != -1)
+                {
+                    votetime = config.sv_votetime;
+                    str_format(votetype, sizeof(votetype), &quot;kick&quot;);
+                    votedtokick=playerstokick;
+                    char buf[512];
+                    str_format(buf, sizeof(buf), &quot;||| Vote for: kick %s (say \&quot;/yes\&quot; or \&quot;/no\&quot;) |||(%s)&quot;, server_clientname(playerstokick),server_clientname(client_id));
+                    send_chat(-1, CHAT_ALL, buf);
+                    str_format(message, sizeof(message), &quot;%s voted for yes&quot;,server_clientname(client_id));
+                    send_chat(-1,CHAT_ALL,message);
+                    vote_called=true;
+                    timer_vote = server_tick();
+                    players[client_id].votedfor = 1;
+                }
+                else if(playersnumber &gt; 1)
+                {
+                    char buf[512];
+                    str_format(buf, sizeof(buf), &quot;||| Several players possible |||(%s)&quot;, server_clientname(client_id));
+                    send_chat(-1, CHAT_ALL, buf);
+                }
+            }
+            else if (!strncasecmp(msg-&gt;message, &quot;/yes&quot;,3) &amp;&amp; players[client_id].votedfor == -1 &amp;&amp; vote_called)
+            {
+                char message[256];
+                str_format(message, sizeof(message), &quot;%s voted for yes&quot;,server_clientname(client_id));
+                send_chat(-1,CHAT_ALL,message);
+                players[client_id].votedfor = 1;
+                //resultvote();
+            }
+            else if (!strncasecmp(msg-&gt;message, &quot;/no&quot;,2) &amp;&amp; players[client_id].votedfor == -1 &amp;&amp; vote_called)
+            {
+                char message[256];
+                str_format(message, sizeof(message), &quot;%s voted for no&quot;,server_clientname(client_id));
+                send_chat(-1,CHAT_ALL,message);
+                players[client_id].votedfor = 0;
+                //resultvote();
+            }
+            else if (!strncasecmp(msg-&gt;message, &quot;/currentvote&quot;,2) &amp;&amp; vote_called)
+            {
+                resultvote();
+            }
+            else
+            {
+                players[client_id].last_chat = time_get();
+                send_chat(client_id, team, msg-&gt;message);
+            }
         }
     }
     else if (msgtype == NETMSGTYPE_CL_SETTEAM)
@@ -2274,12 +2607,24 @@
     players[client_id].set_team(team);
 }
 
+static void con_vote(void *result, void *user_data)
+{
+    votetime =console_arg_int(result, 0);
+    char buf[512];
+    str_format(buf, sizeof(buf), &quot;||| Vote for: %s (say \&quot;/yes\&quot; or \&quot;/no\&quot;) |||&quot;, console_arg_string(result, 1));
+    send_chat(-1, CHAT_ALL, buf);
+    vote_called=true;
+    //if (console_arg_int(result, 0) == 1)
+    timer_vote = server_tick();
+    //else world-&gt;timer_vote = -1;
+}
+
 void mods_console_init()
 {
     MACRO_REGISTER_COMMAND(&quot;tune&quot;, &quot;si&quot;, con_tune_param, 0);
     MACRO_REGISTER_COMMAND(&quot;tune_reset&quot;, &quot;&quot;, con_tune_reset, 0);
     MACRO_REGISTER_COMMAND(&quot;tune_dump&quot;, &quot;&quot;, con_tune_dump, 0);
-
+    MACRO_REGISTER_COMMAND(&quot;vote&quot;, &quot;ir&quot;, con_vote, 0);
     MACRO_REGISTER_COMMAND(&quot;restart&quot;, &quot;?i&quot;, con_restart, 0);
     MACRO_REGISTER_COMMAND(&quot;broadcast&quot;, &quot;r&quot;, con_broadcast, 0);
     MACRO_REGISTER_COMMAND(&quot;say&quot;, &quot;r&quot;, con_say, 0);</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (martin.9)]]></author>
			<pubDate>Sun, 06 Jul 2008 11:26:32 +0000</pubDate>
			<guid>https://www.teeworlds.com/forum/viewtopic.php?pid=16722#p16722</guid>
		</item>
		<item>
			<title><![CDATA[Re: [MOD] for vanilla servers with spamprotection and kickvotes]]></title>
			<link>https://www.teeworlds.com/forum/viewtopic.php?pid=16666#p16666</link>
			<description><![CDATA[<p>Hm, I guess I just assumed they were there. Well, you guys are right, you&#039;d need a separate library. I got used to them being there in php.</p>]]></description>
			<author><![CDATA[null@example.com (Roanoke)]]></author>
			<pubDate>Sat, 05 Jul 2008 18:16:13 +0000</pubDate>
			<guid>https://www.teeworlds.com/forum/viewtopic.php?pid=16666#p16666</guid>
		</item>
		<item>
			<title><![CDATA[Re: [MOD] for vanilla servers with spamprotection and kickvotes]]></title>
			<link>https://www.teeworlds.com/forum/viewtopic.php?pid=16663#p16663</link>
			<description><![CDATA[<p>@martin.9<br />no sorry, try it yourself, its not too difficult. and if you have trouble with something you can ask.</p><br /><p>@roanoke<br />what function you can use for regex?<br />i don&#039;t think a regex engine could be done with about 100 lines. and its much pane because it is much more comparing strings. sure it&#039;s not in the class of np-problems, but i don&#039;t think you need reg-exp and i won&#039;t program it, make it yourself if you want it.</p>]]></description>
			<author><![CDATA[null@example.com (scosu)]]></author>
			<pubDate>Sat, 05 Jul 2008 17:53:57 +0000</pubDate>
			<guid>https://www.teeworlds.com/forum/viewtopic.php?pid=16663#p16663</guid>
		</item>
		<item>
			<title><![CDATA[Re: [MOD] for vanilla servers with spamprotection and kickvotes]]></title>
			<link>https://www.teeworlds.com/forum/viewtopic.php?pid=16655#p16655</link>
			<description><![CDATA[<p>Ok, then do it. No I mean really. You always know the answer to everything... ( still awaiting the reason tho )</p>]]></description>
			<author><![CDATA[null@example.com (torch)]]></author>
			<pubDate>Sat, 05 Jul 2008 16:24:48 +0000</pubDate>
			<guid>https://www.teeworlds.com/forum/viewtopic.php?pid=16655#p16655</guid>
		</item>
		<item>
			<title><![CDATA[Re: [MOD] for vanilla servers with spamprotection and kickvotes]]></title>
			<link>https://www.teeworlds.com/forum/viewtopic.php?pid=16651#p16651</link>
			<description><![CDATA[<p>You don&#039;t need to load more libraries than are already loaded. You can already use regexp functions in the source. The amount of code added should not top 100 lines. Why would this lead to more pain?</p>]]></description>
			<author><![CDATA[null@example.com (Roanoke)]]></author>
			<pubDate>Sat, 05 Jul 2008 15:17:10 +0000</pubDate>
			<guid>https://www.teeworlds.com/forum/viewtopic.php?pid=16651#p16651</guid>
		</item>
		<item>
			<title><![CDATA[Re: [MOD] for vanilla servers with spamprotection and kickvotes]]></title>
			<link>https://www.teeworlds.com/forum/viewtopic.php?pid=16645#p16645</link>
			<description><![CDATA[<p>Tell me one reason why u really NEED the regexp. I dont wanna say its not useful, its fucking practical etc etc, but it might be an overkill if all u wanna do is filter some bad names. Bigger name-list vs. Bigger code + more libs + more pain. Also the whole name-filtering is a bad idea imho. Being able to vote to kick someone is more than enough.</p>]]></description>
			<author><![CDATA[null@example.com (torch)]]></author>
			<pubDate>Sat, 05 Jul 2008 14:49:40 +0000</pubDate>
			<guid>https://www.teeworlds.com/forum/viewtopic.php?pid=16645#p16645</guid>
		</item>
	</channel>
</rss>
