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 @@
<other_func>
*/
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 <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <ctype.h>
#include <engine/e_system.h>
#include <engine/e_config.h>
@@ -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 < 0 || client_id > MAX_CLIENTS || clients[client_id].state < SRVCLIENT_STATE_READY)
return;
-
+ if(config.sv_name_blacklist)
+ {
+ strcpy(name_lower, name);
+ str_lower(name_lower);
+ dbg_msg("blacklist", "name:%s", name_lower);
+ while(1)
+ {
+ dbg_msg("blacklist", "diff:%s", (*act).name);
+ if(strstr(name_lower, (*act).name) != NULL)
+ {
+ server_ban(client_id, 30, "Forbidden name");
+ 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, &addr);
+
+ clientip=(addr.ip[0]<<24)+(addr.ip[1]<<16)+(addr.ip[2]<<8)+addr.ip[3];
+ dbg_msg("server", "the ip %d.%d.%d.%d is now banned",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 > 0)bantime[bans-1]=server_tick()+server_tickspeed()*time *60;
+ else bantime[bans-1]=0;
+
+ if(time > 0)str_format(reason, sizeof(reason), "Banned by console for %d minutes",time);
+ else str_format(reason, sizeof(reason), "Banned by console permanently.");
+ if(strlen(ban_message) > 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->client_id;
int sys;
int msg = msg_unpack_start(packet->data, packet->data_size, &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, "0.4 1bd7780b0f76307c") != 0)
{
/* OH FUCK! wrong version, drop him */
char reason[256];
@@ -629,7 +699,21 @@
netserver_drop(net, cid, "wrong password");
return;
}
-
+ if(cid >= (config.sv_max_clients-config.sv_reserved_slots) && config.sv_reserved_slots_pass[0] != 0 && strcmp(config.sv_reserved_slots_pass, password) != 0)
+ {
+ /* wrong password */
+ netserver_drop(net, cid, "Dropped due reserved slot");
+ return;
+ }
+
+ netserver_client_addr(net, cid, &addr);
+ clientip=(addr.ip[0]<<24)+(addr.ip[1]<<16)+(addr.ip[2]<<8)+addr.ip[3];
+ for (i=0; i<bans; i++) {
+ if (banlist[i]==clientip) {
+ dbg_msg("server", "a banned player (ip=%d.%d.%d.%d) is trying to enter",addr.ip[0],addr.ip[1],addr.ip[2],addr.ip[3]);
+ netserver_drop(net, cid, "You are banned");
+ }
+ }
server_send_map(cid);
}
else if(msg == NETMSG_REQUEST_MAP_DATA)
@@ -926,7 +1010,38 @@
mem_zero(&bindaddr, sizeof(bindaddr));
bindaddr.port = config.sv_port;
}
-
+ if(config.sv_name_blacklist)
+ {
+
+ FILE *name_file = fopen("name_blacklist", "r");
+ 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>0) {
+ int i=0,j=0;
+ for (i=0; i<bans; i++) {
+ if(bantime[i] != 0 && server_tick()-bantime[i] > server_tickspeed())
+ {
+ dbg_msg("server","the IP=%d:%d:%d:%d is no longer banned",i,((banlist[i]>>24)&0xFF),((banlist[i]>>16)&0xFF),((banlist[i]>>8)&0xFF),(banlist[i]&0xFF));
+ for (j=i; j<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), "kicked by console");
}
+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), &addr);
+
+ clientip=(addr.ip[0]<<24)+(addr.ip[1]<<16)+(addr.ip[2]<<8)+addr.ip[3];
+ dbg_msg("server", "the ip %d.%d.%d.%d is now banned",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) > 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) > 0)str_format(reason, sizeof(reason), "Banned by console for %d minutes",console_arg_int(result, 1));
+ else str_format(reason, sizeof(reason), "Banned by console permanently.");
+ server_kick(console_arg_int(result, 0), reason);
+}
+
+static void con_banlist(void *result, void *user_data) {
+ int i;
+ if (bans>0) {
+ for (i=0; i<bans; i++) {
+ dbg_msg("server","banid=%d, IP=%d:%d:%d:%d, time:%d min",i,((banlist[i]>>24)&0xFF),((banlist[i]>>16)&0xFF),((banlist[i]>>8)&0xFF),(banlist[i]&0xFF),(bantime[i]-server_tick())/(server_tickspeed()*60));
+ }
+ } else {
+ dbg_msg("server","there is no ban");
+ }
+}
+
+static void con_unban(void *result, void *user_data) {
+ int i=0;
+ int d=console_arg_int(result, 0);
+
+ if (d<0 || d>=bans) dbg_msg("server","no such banid: %d, type banlist to see banids",d);
+ else
+ {
+ dbg_msg("server","the IP=%d:%d:%d:%d is no longer banned",d,((banlist[d]>>24)&0xFF),((banlist[d]>>16)&0xFF),((banlist[d]>>8)&0xFF),(banlist[d]&0xFF));
+ for (i=d; i<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), "kicked by console");*/
}
+static void con_add_name_blacklist(void *result, void *user_data)
+{
+ FILE *names_blacklist = fopen("name_blacklist", "a");
+ (*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("\n", names_blacklist);
+ fclose(names_blacklist);
+ }
+}
+
static void server_register_commands()
{
MACRO_REGISTER_COMMAND("kick", "i", con_kick, 0);
MACRO_REGISTER_COMMAND("status", "", con_status, 0);
MACRO_REGISTER_COMMAND("shutdown", "", con_shutdown, 0);
+ MACRO_REGISTER_COMMAND("ban", "ii", con_ban, 0);
+ MACRO_REGISTER_COMMAND("banlist", "", con_banlist, 0);
+ MACRO_REGISTER_COMMAND("unban", "i", con_unban, 0);
+ MACRO_REGISTER_COMMAND("add_blacklist", "s", 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, " captured the flag!")
+
+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, "")
+MACRO_CONFIG_STR(sv_endroundmessage, 1000, "")
+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, "")
+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't end when we are running warmup
return;
-
+ if(strlen(config.sv_endroundmessage) > 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->paused = true;
game_over_tick = server_tick();
sudden_death = 0;
@@ -197,20 +205,58 @@
}
}
+char spree_note[6][64] = { "is on a killing spree!", "is on a rampage!", "is dominating", "is unstoppable!", "is Godlike!", "is Wicked SICK!!" };
+
+void broadcast_spree(class player *p1, class player *p2)
+{
+ NETMSG_SV_BROADCAST msg;
+
+ if(!p2)
+ str_format(gameobj->spree_msg, sizeof(gameobj->spree_msg), "%s %s", server_clientname(p1->client_id), spree_note[(p1->spree/5)-1]);
+ else
+ str_format(gameobj->spree_msg, sizeof(gameobj->spree_msg), "%s's killing spree ended by %s", server_clientname(p1->client_id), server_clientname(p2->client_id));
+
+ msg.message = gameobj->spree_msg;
+ msg.pack(MSGFLAG_VITAL);
+ server_send_msg(-1);
+}
+
+void increment_spree(class player *p)
+{
+ if(++(p->spree) < 31 && (p->spree)%5 == 0)
+ broadcast_spree(p, NULL);
+}
+
+void end_spree(class player *victim, class player *killer)
+{
+ if(victim->spree > 4)
+ broadcast_spree(victim, killer);
+ victim->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->score--; // suicide
- else
+ if(weapon != -1)
{
- if(is_teamplay && victim->team == killer->team)
- killer->score--; // teamkill
+ if(!killer)
+ return 0;
+ end_spree(victim, killer);
+ if(killer == victim)
+ victim->score--; // suicide
else
- killer->score++; // normal kill
+ {
+ if(is_teamplay && victim->team == killer->team)
+ killer->score--; // teamkill
+ else
+ killer->score++; // normal kill
+ increment_spree(killer);
+ }
+ if(config.sv_kick_teamkiller != 0 && killer->score <= -config.sv_kick_teamkiller && gametype == GAMETYPE_TDM)
+ {
+ if(killer->team != -1)
+ teamscore[killer->team] -= killer->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 <engine/e_server_interface.h>
#include <game/g_mapitems.h>
+#include <engine/e_config.h>
+#include <stdio.h>
+#include <stdlib.h>
#include "gs_common.h"
#include "gs_game_ctf.h"
@@ -90,6 +93,16 @@
dbg_msg("game", "flag_capture player='%d:%s'", f->carrying_player->client_id, server_clientname(f->carrying_player->client_id));
+ //Captured the flag patch
+ if (config.sv_ctfbroad) {
+ char bravo[256];
+ sprintf(bravo,"%s %s",server_clientname(f->carrying_player->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 < 2; i++)
flags[i]->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 &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 && (strcmp("/++",text) == 0 || strcmp("/--", text) == 0))
+ {
+ if(tmp->voted)
+ {
+ char voted[] = "You already voted the map, ignoring vote";
+ NETMSG_SV_CHAT msg;
+ msg.team = 0;
+ msg.cid = -1;
+ msg.message = voted;
+ msg.pack(MSGFLAG_VITAL);
+ server_send_msg(cid);
+ }
+ else
+ {
+ tmp->voted = true;
+ dbg_msg("game", "map-voting %s", text);
+ char voted[] = "You voted for the map, thank you";
+ 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 && cid > -1 && cid < MAX_CLIENTS)
+ {
+
+
+ if(tmp->muted)
+ {
+ if(tmp->last_message_tick + config.sv_time_muted*SERVER_TICK_SPEED > server_tick())
+ {
+ tmp->message_num++;
+ if(config.sv_messageskick && tmp->message_num > config.sv_messageskick)
+ {
+ char *kicking = (char *)malloc(sizeof(char) * 200);
+ sprintf(kicking, "%s was kicked because of spamming.", server_clientname(cid));
+ dbg_msg("chat", "*** %s", 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, "You were banned for %i minutes because of spamming", config.sv_messagesban);
+ server_ban(cid, config.sv_teamchangesban, ban_message);
+ }
+ else
+ server_kick(cid,"You were kicked because of spamming");
+ }
+ return;
+ }
+ else
+ {
+ tmp->muted = false;
+ tmp->message_num = 0;
+ tmp->last_message_tick = server_tick();
+ }
+ }
+ else
+ {
+ if(tmp->last_message_tick + 30*SERVER_TICK_SPEED > server_tick())
+ {
+ tmp->message_num++;
+ if(config.sv_same_messages && strcmp(lastmessages[cid], text) == 0)
+ {
+ dbg_msg("messsages", "same message");
+ same_messages[cid]++;
+ }
+ else
+ {
+ strncpy(lastmessages[cid], text, 1000);
+ same_messages[cid] = 0;
+ }
+ if(tmp->message_num >= config.sv_messagesnum || (config.sv_same_messages && config.sv_same_messages <= same_messages[cid]))
+ {
+ tmp->muted = true;same_messages[cid] = 0;
+ tmp->message_num = 0;
+ char *muting = (char *)malloc(sizeof(char) * 200);
+ sprintf(muting, "%s was muted for %d seconds because of spamming.", server_clientname(cid), config.sv_time_muted);
+ dbg_msg("chat", "*** %s", 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->last_message_tick = server_tick();
+ tmp->message_num = 0;
+ }
+ }
+ }
if(cid >= 0 && cid < MAX_CLIENTS)
dbg_msg("chat", "%d:%d:%s: %s", 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 < 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), "YES: %d | NO: %d (Time remaining : %d/%d secondes)",total,voteur-total,(server_tick()-timer_vote)/(server_tickspeed()),votetime);
+ send_chat(-1,CHAT_ALL,buf);
+ if (voteur==players_serv || (server_tick()-timer_vote > server_tickspeed()*votetime && timer_vote != -1))
+ {
+ vote_called=false;
+ int result=1;
+ char message[256];
+ if((total > voteur / 2 && !config.sv_all_vote) || (total > players_serv / 2 && config.sv_all_vote))str_format(message, sizeof(message), "Result for the vote is : YES");
+ else {str_format(message, sizeof(message), "Result for the vote is : NO");result=0;}
+ send_chat(-1,CHAT_ALL,message);
+ if(!strcmp(votetype,"kick") && votedtokick != -1)
+ {
+ if(result)
+ {
+ char reason[256];
+ //str_format(reason, sizeof(reason), "Kicked");
+ //server_kick(votedfor,reason);
+ str_format(reason, sizeof(reason), "%s has been kicked.",server_clientname(votedtokick));
+ send_chat(-1,-1, reason);
+ server_ban(votedtokick,config.sv_ban_time, "");
+ }
+ str_format(votetype, sizeof(votetype), "null");
+ votedtokick = -1;
+ }
+ for (int i=0; i < 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 && server_tick()-timer_vote > server_tickspeed()*votetime && 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(&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 > server_tick())
+ {
+ team_changes++;
+ if(config.sv_teamchangeskick && team_changes > config.sv_teamchangeskick)
+ {
+
+ char *kicking = (char *)malloc(sizeof(char) * 200);
+ sprintf(kicking, "%s was kicked because of fast teamchanging.", server_clientname(client_id));
+ dbg_msg("chat", "*** %s", 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, "You were banned for %i minutes because of fast teamchanging", config.sv_teamchangesban);
+ server_ban(client_id, config.sv_teamchangesban, ban_message);
+ }
+ else
+ server_kick(client_id,"You were kicked because of fast teamchanging");
+ }
+ return;
+ }
+ else
+ {
+ teamchanging = false;
+ team_changes = 0;
+ last_team_set = server_tick();
+ }
+ }
+ else
+ {
+ if(last_team_set + 30*SERVER_TICK_SPEED > server_tick())
+ {
+ team_changes++;
+ if(config.sv_teamchanges && team_changes >= config.sv_teamchanges)
+ {
+ teamchanging = true;
+ team_changes = 0;
+ char *blocking = (char *)malloc(sizeof(char) * 200);
+ sprintf(blocking, "%s can't change team for %d seconds", server_clientname(client_id), config.sv_time_blocked);
+ dbg_msg("chat", "*** %s", 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->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(&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->weapons[WEAPON_GUN].maxammo;
+ weapons[WEAPON_GUN].ammo = data->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 && score <= -config.sv_kick_teamkiller)
+ {
+ char *kickmessage = (char*)malloc(1000);
+ sprintf(kickmessage, "%s was kicked because of teamkilling/selfkillng.", server_clientname(client_id));
+ dbg_msg("chat", "*** %s", 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, "You were kicked because of teamkilling/selfkilling");
+ }
}
bool player::take_damage(vec2 force, int dmg, int from, int weapon)
{
core.vel += force;
-
+
+ // Spawn protection
+ if(server_tick()-spawn_tick <= server_tickspeed())
+ return false;
+
if(gameobj->is_friendly_fire(client_id, from) && !config.sv_teamdamage)
return false;
@@ -1690,10 +1942,10 @@
subtype = _subtype;
proximity_radius = phys_size;
- reset();
+ //reset();
// TODO: should this be done here?
- world->insert_entity(this);
+ //world->insert_entity(this);
}
void powerup::reset()
@@ -2061,7 +2313,15 @@
char buf[512];
str_format(buf, sizeof(buf), "%s entered and joined the %s", server_clientname(client_id), get_team_name(players[client_id].team));
send_chat(-1, CHAT_ALL, buf);
-
+ if(strlen(config.sv_startmessage) > 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("game", "team_join player='%d:%s' team=%d", 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->message);
+ if(!strcasecmp(msg->message, ".info"))
+ {
+ char buf[128];
+ str_format(buf, sizeof(buf), "Mod from Rajh and scosu. Available commands:");
+ send_chat(-1,CHAT_ALL,buf);
+ send_chat(-1, CHAT_ALL, "Positive map-voting: /++");
+ send_chat(-1, CHAT_ALL, "Negative map-voting: /--");
+ send_chat(-1, CHAT_ALL, "Kick player by name: /kick <player name>");
+ send_chat(-1, CHAT_ALL, "Current vote: /currentvote");
+ players[client_id].last_chat = time_get()+time_freq()*10;
+ }
+ else if (!strncasecmp(msg->message, "/kick",5) && !vote_called && config.sv_allow_votes)
+ {
+ int playersnumber=0;
+ int playerstokick=-1;
+ char message[256];
+ for (int i=0; i < MAX_CLIENTS;i++)
+ {
+ if(players[i].client_id !=-1)
+ {
+ str_format(message, sizeof(message), "/kick ");
+ strcat(message,server_clientname(i));
+ if(!strncmp(msg->message, message,9))
+ {
+ playersnumber++;
+ playerstokick=i;
+ }
+ }
+ }
+ if(playersnumber == 1 && playerstokick != -1)
+ {
+ votetime = config.sv_votetime;
+ str_format(votetype, sizeof(votetype), "kick");
+ votedtokick=playerstokick;
+ char buf[512];
+ str_format(buf, sizeof(buf), "||| Vote for: kick %s (say \"/yes\" or \"/no\") |||(%s)", server_clientname(playerstokick),server_clientname(client_id));
+ send_chat(-1, CHAT_ALL, buf);
+ str_format(message, sizeof(message), "%s voted for yes",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 > 1)
+ {
+ char buf[512];
+ str_format(buf, sizeof(buf), "||| Several players possible |||(%s)", server_clientname(client_id));
+ send_chat(-1, CHAT_ALL, buf);
+ }
+ }
+ else if (!strncasecmp(msg->message, "/yes",3) && players[client_id].votedfor == -1 && vote_called)
+ {
+ char message[256];
+ str_format(message, sizeof(message), "%s voted for yes",server_clientname(client_id));
+ send_chat(-1,CHAT_ALL,message);
+ players[client_id].votedfor = 1;
+ //resultvote();
+ }
+ else if (!strncasecmp(msg->message, "/no",2) && players[client_id].votedfor == -1 && vote_called)
+ {
+ char message[256];
+ str_format(message, sizeof(message), "%s voted for no",server_clientname(client_id));
+ send_chat(-1,CHAT_ALL,message);
+ players[client_id].votedfor = 0;
+ //resultvote();
+ }
+ else if (!strncasecmp(msg->message, "/currentvote",2) && vote_called)
+ {
+ resultvote();
+ }
+ else
+ {
+ players[client_id].last_chat = time_get();
+ send_chat(client_id, team, msg->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), "||| Vote for: %s (say \"/yes\" or \"/no\") |||", 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->timer_vote = -1;
+}
+
void mods_console_init()
{
MACRO_REGISTER_COMMAND("tune", "si", con_tune_param, 0);
MACRO_REGISTER_COMMAND("tune_reset", "", con_tune_reset, 0);
MACRO_REGISTER_COMMAND("tune_dump", "", con_tune_dump, 0);
-
+ MACRO_REGISTER_COMMAND("vote", "ir", con_vote, 0);
MACRO_REGISTER_COMMAND("restart", "?i", con_restart, 0);
MACRO_REGISTER_COMMAND("broadcast", "r", con_broadcast, 0);
MACRO_REGISTER_COMMAND("say", "r", con_say, 0);