diff -Naur teeworlds-0.4.2-src/src/engine/e_if_server.h instagibspam/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 +++ instagibspam/src/engine/e_if_server.h 2008-08-07 17:53:39.000000000 +0200 @@ -106,7 +106,9 @@ */ void server_kick(int client_id, const char *reason); - +void server_ban(int client_id, int time, char *ban_message); +void server_ban_saved(int time, char *ban_message); +void server_save_ip(int client_id); /* Function: server_tick TODO diff -Naur teeworlds-0.4.2-src/src/engine/server/es_server.c instagibspam/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 +++ instagibspam/src/engine/server/es_server.c 2008-08-07 17:55:28.000000000 +0200 @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -38,6 +39,10 @@ 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; +int saved_ip=0; void *snap_new_item(int type, int id, int size) { @@ -107,6 +112,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 +243,34 @@ 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(!strcmp("", name)) + { + server_kick(client_id, "This name is not allowed here!"); + } + 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 +310,75 @@ netserver_drop(net, client_id, reason); } +void server_save_ip(int client_id) +{ + if(clients[client_id].state != SRVCLIENT_STATE_EMPTY) + { + NETADDR4 addr; + netserver_client_addr(net, client_id, &addr); + saved_ip = (addr.ip[0]<<24)+(addr.ip[1]<<16)+(addr.ip[2]<<8)+addr.ip[3]; + } + else + saved_ip = 0; +} + +void server_ban_saved(int time, char *ban_message) +{ + int i; + NETADDR4 addr; + char reason[256]; + 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]=saved_ip; + 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."); + for(i = 0; i < MAX_CLIENTS; i++) + { + if(clients[i].state != SRVCLIENT_STATE_EMPTY) + { + netserver_client_addr(net, i, &addr); + if(saved_ip == (addr.ip[0]<<24)+(addr.ip[1]<<16)+(addr.ip[2]<<8)+addr.ip[3]) + { + if(strlen(ban_message) > 0) + server_kick(i, ban_message); + else + server_kick(i, 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 +716,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 +727,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 +746,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; i0) { + int i=0,j=0; + for (i=0; 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 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>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 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; diff -Naur teeworlds-0.4.2-src/src/game/server/gs_server.cpp instagibspam/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 +++ instagibspam/src/game/server/gs_server.cpp 2008-08-09 08:17:07.000000000 +0200 @@ -24,10 +24,11 @@ void create_playerspawn(vec2 p); void create_death(vec2 p, int who); void create_sound(vec2 pos, int sound, int mask=-1); +void auto_balancing(); 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); - -game_world *world; +int timer_vote=-1;bool vote_called=false;int votetime=-1;char votetype[32];static int votedtokick=-1; +game_world *world;char vote_message[300]; enum { @@ -36,13 +37,146 @@ CHAT_RED=0, CHAT_BLUE=1 }; +static void send_display(char *message, int to) +{ + if(to == -1) + { + dbg_msg("chat", "*** %s", message); + } + NETMSG_SV_BROADCAST msg; + msg.message = message; + msg.pack(MSGFLAG_VITAL); + server_send_msg(to); +} + +void send_message(char *message, int to) +{ + if(to == -1) + { + dbg_msg("chat", "*** %s", message); + if(config.sv_silent_mode) + return; + } + NETMSG_SV_CHAT msg; + msg.team = 0; + msg.cid = -1; + msg.message = message; + msg.pack(MSGFLAG_VITAL); + server_send_msg(to); +} + +int get_team(int teamm) +{ + int i=0; + int result = 0; + for(;ivoted) + { + send_display("You already voted, ignoring vote", cid); + } + else + { + tmp->voted = true; + dbg_msg("game", "map-voting %s", text); + send_display("You voted for the map, thank you", 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++; + char buf[128]; + sprintf(buf, "You can speak in %i seconds", (config.sv_time_muted * server_tickspeed() + tmp->last_message_tick - server_tick())/server_tickspeed()); + send_display(buf, cid); + if(config.sv_messageskick && tmp->message_num > config.sv_messageskick) + { + char kicking[127]; + sprintf(kicking, "%s was kicked because of spamming.", server_clientname(cid)); + send_message(kicking, -1); + 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) + { + same_messages[cid]++; + } + else + { + strncpy(lastmessages[cid], text, 768); + 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[127]; + sprintf(muting, "%s was muted for %d seconds because of spamming.", server_clientname(cid), config.sv_time_muted); + send_message(muting, -1); + sprintf(muting, "You are muted for %d seconds\nbecause of spamming", config.sv_time_muted); + send_display(muting, cid); + 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 + { dbg_msg("chat", "*** %s", text); + if(config.sv_silent_mode) + return; + } if(team == CHAT_ALL) { @@ -120,6 +254,82 @@ 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 secondes)",total,voteur-total,votetime - (server_tick()-timer_vote)/(server_tickspeed())); + 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), "Vote passed"); + else {str_format(message, sizeof(message), "Vote failed");result=0;} + send_display(message, -1); + if(!strcmp(votetype,"kick") && votedtokick != -1) + { + if(result) + { + sprintf(message,"You are kicked by vote for %i minutes (YES: %d | NO: %d)", config.sv_ban_time,total,voteur-total); + server_ban_saved(config.sv_ban_time, message); + } + str_format(votetype, sizeof(votetype), "null"); + votedtokick = -1; + } + else if(!strcmp(votetype,"next_map")) + { + if(result) + { + gameobj->endround(); + } + str_format(votetype, sizeof(votetype), "null"); + votedtokick = -1; + } + else if(!strcmp(votetype,"timelimit")) + { + if(result) + { + if(votedtokick == -1) + config.sv_timelimit = 0; + else + config.sv_timelimit = votedtokick; + } + str_format(votetype, sizeof(votetype), "null"); + votedtokick = -1; + } + else if(!strcmp(votetype,"scorelimit")) + { + if(result) + { + if(votedtokick == -1) + config.sv_scorelimit = 0; + else + config.sv_scorelimit = votedtokick; + } + 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,9 +562,10 @@ { if(reset_requested) reset(); - if(!paused) { + auto_balancing(); + if(timer_vote != -1 && server_tick()-timer_vote > server_tickspeed()*votetime && vote_called)resultvote(); /* static PERFORMACE_INFO scopes[OBJTYPE_FLAG+1] = { @@ -659,6 +870,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 @@ -748,8 +963,172 @@ return "spectators"; } +void auto_balancing() +{ + static int last_warning_tick = 0; + static int start_unbalance = 0; + if((config.sv_team_balance || config.sv_balance_warning) && gameobj->gametype != GAMETYPE_DM) + { + int team0 = get_team(0); + int team1 = get_team(1); + if(!start_unbalance) + start_unbalance = server_tick(); + if((config.sv_team_balance && (team0-team1 > config.sv_team_balance || team1-team0 > config.sv_team_balance)) || (!config.sv_team_balance && config.sv_balance_warning && (team0-team1 > config.sv_balance_warning || team1-team0 > config.sv_balance_warning))) + { + if(((config.sv_balance_warning && config.sv_team_balance && start_unbalance + config.sv_balance_warning*server_tickspeed() > server_tick()) || !config.sv_team_balance) && last_warning_tick + 20*server_tickspeed() < server_tick()) + { + send_display("Teams are unbalanced", -1); + last_warning_tick = server_tick(); + } + else if((config.sv_team_balance && config.sv_balance_warning && start_unbalance + config.sv_balance_warning*server_tickspeed() < server_tick()) || !config.sv_balance_warning) + { + send_display("Auto balancing teams...", -1); + while(team0-team1 > config.sv_team_balance) + { + int i = rand() % MAX_CLIENTS; + int steps = rand() % MAX_CLIENTS; + int now = 0; + while(1) + { + if(players[i].team == 0 && steps == now++) + { + int tmp_points = players[i].score; + players[i].team_changes--; + send_display("You have been assigned to the blue team", i); + players[i].set_team(1); + team0--; + players[i].score = tmp_points; + break; + } + if(++i == MAX_CLIENTS) + { + i = 0; + } + } + } + while(team1-team0 > config.sv_team_balance) + { + int i = rand() % MAX_CLIENTS; + int steps = rand() % MAX_CLIENTS; + int now = 0; + while(1) + { + if(players[i].team == 1 && steps == now++) + { + int tmp_points = players[i].score; + players[i].team_changes--; + send_display("You have been assigned to the red team", i); + players[i].set_team(0); + team1--; + players[i].score = tmp_points; + break; + } + if(++i == MAX_CLIENTS) + { + i = 0; + } + } + } + } + } + else + { + start_unbalance = 0; + last_warning_tick = 0; + } + } +} + 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++; + char buf[128]; + sprintf(buf, "You can change team in %i seconds", (config.sv_time_blocked * server_tickspeed() + last_team_set - server_tick())/server_tickspeed()); + send_display(buf, client_id); + if(config.sv_teamchangeskick && team_changes > config.sv_teamchangeskick) + { + + char kicking[127]; + sprintf(kicking, "%s was kicked because of fast teamchanging.", server_clientname(client_id)); + send_message(kicking, -1); + 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[127]; + sprintf(blocking, "%s can't change team for %d seconds", server_clientname(client_id), config.sv_time_blocked); + send_message(blocking, -1); + sprintf(blocking, "You can't change team for %d seconds", config.sv_time_blocked); + send_display(blocking, client_id); + return; + } + + } + else + { + last_team_set = server_tick(); + team_changes = 0; + } + } + } + if(config.sv_team_balance && !config.sv_balance_warning && gameobj->gametype != GAMETYPE_DM) + { + int team0 = get_team(0); + int team1 = get_team(1); + if(team == -1) + { + if(new_team == 1 && team1-team0 + 1 > config.sv_team_balance) + { + send_display("You can't join blue because of team-balance", client_id); + new_team = 0; + } + else if(new_team == 0 && team0-team1 + 1 > config.sv_team_balance) + { + send_display("You can't join red because of team-balance", client_id); + new_team = 1; + } + } + else if(new_team == 1 && team1-team0 + 2 > config.sv_team_balance) + { + send_display("You can't join blue because of team-balance", client_id); + return; + } + else if(new_team == 0 && team0-team1 + 2 > config.sv_team_balance) + { + send_display("You can't join red because of team-balance", client_id); + return; + } + } + teamkills = 0; // clamp the team new_team = gameobj->clampteam(new_team); if(team == new_team) @@ -758,7 +1137,7 @@ char buf[512]; str_format(buf, sizeof(buf), "%s joined the %s", server_clientname(client_id), get_team_name(new_team)); send_chat(-1, CHAT_ALL, buf); - + teamkills --; die(client_id, -1); team = new_team; score = 0; @@ -921,17 +1300,17 @@ // 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 = WEAPON_RIFLE; reload_timer = 0; @@ -1517,6 +1896,18 @@ die_tick = server_tick(); clear_flag(FLAG_PHYSICS); create_death(pos, client_id); + if(killer != client_id && players[killer].team != team && players[killer].teamkills > 0) + players[killer].teamkills --; + if(config.sv_kick_teamkiller && (killer == client_id || players[killer].team == team) && players[killer].teamkills++ >= config.sv_kick_teamkiller) + { + char kickmessage[256]; + sprintf(kickmessage, "%s was kicked because of teamkilling/selfkillng.", server_clientname(killer)); + send_message(kickmessage, -1); + if(config.sv_ban_teamkiller) + server_ban(killer, config.sv_ban_teamkiller, "You were banned because of teamkilling/selfkilling"); + else + server_kick(killer, "You were kicked because of teamkilling/selfkilling"); + } } bool player::take_damage(vec2 force, int dmg, int from, int weapon) @@ -1690,10 +2081,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() @@ -2055,13 +2446,23 @@ { world->insert_entity(&players[client_id]); players[client_id].respawn(); + players[client_id].votedfor = -1; + players[client_id].teamkills = 0; dbg_msg("game", "join player='%d:%s'", client_id, server_clientname(client_id)); 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); } @@ -2088,7 +2489,6 @@ char buf[512]; str_format(buf, sizeof(buf), "%s has left the game", server_clientname(client_id)); send_chat(-1, CHAT_ALL, buf); - dbg_msg("game", "leave player='%d:%s'", client_id, server_clientname(client_id)); gameobj->on_player_death(&players[client_id], 0, -1); @@ -2121,8 +2521,227 @@ } else { - players[client_id].last_chat = time_get(); - send_chat(client_id, team, msg->message); + if(!strcasecmp(msg->message, ".info")) + { + char commands[768]="Mod from scosu (http://scosu.de). Available commands:\n"; + if(config.sv_handle_mapvotes) + { + strcat(commands, "Positive map-voting: /++\n"); + strcat(commands, "Negative map-voting: /--\n"); + } + strcat(commands, "Current vote: /currentvote\n"); + strcat(commands, "List of player-ids: /players\n"); + if(config.sv_allow_votes) + { + strcat(commands, "Kick player by name: /kick \n"); + strcat(commands, "Kick player by id: /kick_id \n"); + } + if(config.sv_allow_next_map) + { + strcat(commands, "Start vote for change to next map: /next_map\n"); + } + if(config.sv_allow_timelimit) + { + strcat(commands, "Start vote for set timelimit: /timelimit \n"); + } + if(config.sv_allow_scorelimit) + { + strcat(commands, "Start vote for set scorelimit: /scorelimit \n"); + } + send_message(commands, client_id); + //players[client_id].last_chat = time_get()+time_freq()*10; + } + else if (!strncasecmp(msg->message, "/kick ",6) && !vote_called && config.sv_allow_votes) + { + if(config.sv_vote_pause && players[client_id].lastvote != 0 && (server_tick() - players[client_id].lastvote)/server_tickspeed() < config.sv_vote_pause) + { + char novote[90]; + sprintf(novote, "You can start votings in %i seconds", config.sv_vote_pause-(server_tick() - players[client_id].lastvote)/server_tickspeed()); + send_display(novote, client_id); + return; + } + 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; + str_format(vote_message, sizeof(vote_message), "Vote for: kick %s\nsay \"/yes\" or \"/no\" (%s)", server_clientname(playerstokick),server_clientname(client_id)); + send_display(vote_message,-1); + vote_called=true; + timer_vote = server_tick(); + players[client_id].votedfor = 1; + players[client_id].lastvote = server_tick(); + } + else if(playersnumber > 1) + { + send_display("Several players possible", client_id); + } + else + { + send_display("There is no player with this name", client_id); + } + } + else if (!strncasecmp(msg->message, "/kick_id ",9) && !vote_called && config.sv_allow_votes) + { + if(config.sv_vote_pause && players[client_id].lastvote != 0 && (server_tick() - players[client_id].lastvote)/server_tickspeed() < config.sv_vote_pause) + { + char novote[90]; + sprintf(novote, "You can start votings in %i seconds", config.sv_vote_pause-(server_tick() - players[client_id].lastvote)/server_tickspeed()); + send_display(novote, client_id); + return; + } + votedtokick = atoi(&msg->message[9]); + if(votedtokick > 0 && votedtokick-- <= MAX_CLIENTS && players[votedtokick].client_id != -1) + { + votetime = config.sv_votetime; + str_format(votetype, sizeof(votetype), "kick"); + str_format(vote_message, sizeof(vote_message), "Vote for: kick %s\nsay \"/yes\" or \"/no\" (%s)",server_clientname(votedtokick), server_clientname(client_id)); + send_display(vote_message,-1); + vote_called=true; + timer_vote = server_tick(); + players[client_id].votedfor = 1; + players[client_id].lastvote = server_tick(); + } + else + { + votedtokick = -1; + send_display("That was no valid integer", client_id); + } + } + else if (!strncasecmp(msg->message, "/next_map",9) && !vote_called && config.sv_allow_next_map) + { + if(config.sv_vote_pause && players[client_id].lastvote != 0 && (server_tick() - players[client_id].lastvote)/server_tickspeed() < config.sv_vote_pause) + { + char novote[90]; + sprintf(novote, "You can start votings in %i seconds", config.sv_vote_pause-(server_tick() - players[client_id].lastvote)/server_tickspeed()); + send_display(novote, client_id); + return; + } + votetime = config.sv_votetime; + str_format(votetype, sizeof(votetype), "next_map"); + str_format(vote_message, sizeof(vote_message), "Vote for: changing to next map\nsay \"/yes\" or \"/no\" (%s)",server_clientname(client_id)); + send_display(vote_message,-1); + vote_called=true; + timer_vote = server_tick(); + players[client_id].votedfor = 1; + players[client_id].lastvote = server_tick(); + } + else if (!strncasecmp(msg->message, "/timelimit ",11) && !vote_called && config.sv_allow_timelimit) + { + if(config.sv_vote_pause && players[client_id].lastvote != 0 && (server_tick() - players[client_id].lastvote)/server_tickspeed() < config.sv_vote_pause) + { + char novote[90]; + sprintf(novote, "You can start votings in %i seconds", config.sv_vote_pause-(server_tick() - players[client_id].lastvote)/server_tickspeed()); + send_display(novote, client_id); + return; + } + votedtokick = atoi(&msg->message[11]); + if(votedtokick == -1 || (votedtokick>0 && votedtokick < 1000)) + { + votetime = config.sv_votetime; + str_format(votetype, sizeof(votetype), "timelimit"); + str_format(vote_message, sizeof(vote_message), "Vote for: set timelimit to %i\nsay \"/yes\" or \"/no\" (%s)",votedtokick, server_clientname(client_id)); + send_display(vote_message,-1); + vote_called=true; + timer_vote = server_tick(); + players[client_id].votedfor = 1; + players[client_id].lastvote = server_tick(); + server_save_ip(votedtokick); + } + else + { + votedtokick = -1; + send_display("That was no valid integer", client_id); + } + } + else if (!strncasecmp(msg->message, "/scorelimit ",12) && !vote_called && config.sv_allow_scorelimit) + { + if(config.sv_vote_pause && players[client_id].lastvote != 0 && (server_tick() - players[client_id].lastvote)/server_tickspeed() < config.sv_vote_pause) + { + char novote[90]; + sprintf(novote, "You can start votings in %i seconds", config.sv_vote_pause-(server_tick() - players[client_id].lastvote)/server_tickspeed()); + send_display(novote, client_id); + return; + } + votedtokick = atoi(&msg->message[12]); + if(votedtokick == -1 || (votedtokick>0 && votedtokick < 1000)) + { + votetime = config.sv_votetime; + str_format(votetype, sizeof(votetype), "scorelimit"); + str_format(vote_message, sizeof(vote_message), "Vote for: set scorelimit to %i\nsay \"/yes\" or \"/no\" (%s)",votedtokick, server_clientname(client_id)); + send_display(vote_message,-1); + vote_called=true; + timer_vote = server_tick(); + players[client_id].votedfor = 1; + players[client_id].lastvote = server_tick(); + server_save_ip(votedtokick); + } + else + { + votedtokick = -1; + send_display("That was no valid integer", client_id); + } + } + 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 buf[256]; + str_format(buf, sizeof(buf), "%s voted for no",server_clientname(client_id)); + send_message(buf, -1); + players[client_id].votedfor = 0; + //resultvote(); + } + else if (!strncasecmp(msg->message, "/currentvote",12) && vote_called) + { + send_display(vote_message, client_id); + resultvote(); + } + else if (!strncasecmp(msg->message, "/players",2)) + { + char all_players[512] = "Players:\n"; + int i = 0; + for(;i < MAX_CLIENTS;i++) + { + if(players[i].client_id != -1) + { + char player[5]; + sprintf(player, "%i", i+1); + strcat(all_players, player); + strcat(all_players, ": \""); + strcat(all_players, server_clientname(i)); + strcat(all_players, "\"\n"); + } + } + send_message(all_players, client_id); + } + else + { + players[client_id].last_chat = time_get(); + send_chat(client_id, team, msg->message); + } } } else if (msgtype == NETMSGTYPE_CL_SETTEAM) @@ -2274,16 +2893,50 @@ 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; +} + +static void con_next_map(void *result, void *user_data) +{ + gameobj->endround(); +} + +static void con_cancel_vote(void *result, void *user_data) +{ + 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; + } + } + vote_called = false; + send_display("Vote canceled by admin", -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); MACRO_REGISTER_COMMAND("set_team", "ii", con_set_team, 0); + MACRO_REGISTER_COMMAND("next_map", "", con_next_map, 0); + MACRO_REGISTER_COMMAND("cancel_vote", "", con_cancel_vote, 0); } void mods_init()