void mods_message(int msgtype, int client_id) { static int next_msg[MAX_CLIENTS] = {0}; void *rawmsg = netmsg_secure_unpack(msgtype); PLAYER *p = game.players[client_id]; if(!rawmsg) { return; } if(msgtype == NETMSGTYPE_CL_SAY) { NETMSG_CL_SAY *msg = (NETMSG_CL_SAY *)rawmsg; int team = msg->team; if(next_msg[client_id] <= server_tick()) { next_msg[client_id] = server_tick() + server_tickspeed(); } if(str_length(msg->message)>250) { game.send_chat_target(client_id,"Your Message is too long!"); return; } if(team) team = p->team; else team = GAMECONTEXT::CHAT_ALL; if(config.sv_spamprotection && p->last_chat+time_freq() > time_get()) game.players[client_id]->last_chat = time_get(); else if(p->muted>0) { int time; time = p->muted; // Coded by Stitch626 if(time >= 60*server_tickspeed()) { int sec; sec = time; while(sec >= 60*server_tickspeed()) sec -= 60*server_tickspeed(); time = time/server_tickspeed(); time = time/60; char buf1[512]; str_format(buf1, sizeof(buf1), "You are muted for the next %d minutes and %d seconds", time, sec/server_tickspeed()); game.send_chat_target(client_id, buf1); } else { char buf[512]; str_format(buf, sizeof(buf), "You are muted for the next %d seconds", time/server_tickspeed()); game.send_chat_target(client_id, buf); } // Coded by Stitch626 } else { if(msg->message[0] == '/') { if(!str_comp_nocase(msg->message, "/info")) { game.send_chat_target(client_id,"============================================="); game.send_chat_target(client_id,"| Tee-Ball MOD by Stitch626 and xD "); game.send_chat_target(client_id,"| Baseing on the CTF mod by Stitch626 "); game.send_chat_target(client_id,"| Idea and Coding by Stitch626 and xD "); game.send_chat_target(client_id,"| Version: Beta 1.3 Build Date: 13.3.2012 "); game.send_chat_target(client_id,"============================================="); } else if(!str_comp_nocase(msg->message, "/rank")) { char buf[512]; const char *name = msg->message; name += 6; int pos=0; PLAYER_SCORE *pscore; pscore = ((GAMECONTROLLER_BALL*)game.controller)->score.search_name(server_clientname(client_id), pos); if(pscore && pos > -1 && pscore->score != -1) { int rscore = pscore->score; str_format(buf, sizeof(buf), "%d. %s",pos, pscore->name); if(p->muted == 0) game.send_chat(-1, GAMECONTEXT::CHAT_ALL, buf); else game.send_chat_target(client_id, buf); str_format(buf, sizeof(buf), "Score: %d", rscore); } else str_format(buf, sizeof(buf), "%s is not ranked", strcmp(msg->message, "/rank")?name:server_clientname(client_id)); game.send_chat_target(client_id, buf); } else if(!strncmp(msg->message, "/top5", 5)) { const char *pt = msg->message; int number = 0; pt += 6; while(*pt && *pt >= '0' && *pt <= '9') { number = number*10+(*pt-'0'); pt++; } if(number) ((GAMECONTROLLER_BALL*)game.controller)->score.top5_draw(client_id, number); else ((GAMECONTROLLER_BALL*)game.controller)->score.top5_draw(client_id, 0); } else { game.send_chat_target(client_id, "-----------------------------"); game.send_chat_target(client_id, "Wrong command."); game.send_chat_target(client_id, "-----------------------------"); } } else { game.players[client_id]->last_chat = time_get(); game.send_chat(client_id, team, msg->message); } } } else if(msgtype == NETMSGTYPE_CL_CALLVOTE) { int64 now = time_get(); if(game.vote_closetime) { game.send_chat_target(client_id, "Wait for current vote to end before calling a new one."); return; } int64 timeleft = p->last_votecall + time_freq()*60 - now; if(timeleft > 0) { char chatmsg[512] = {0}; str_format(chatmsg, sizeof(chatmsg), "You must wait %d seconds before making another vote", (timeleft/time_freq())+1); game.send_chat_target(client_id, chatmsg); return; } char chatmsg[512] = {0}; char desc[512] = {0}; char cmd[512] = {0}; NETMSG_CL_CALLVOTE *msg = (NETMSG_CL_CALLVOTE *)rawmsg; if(str_comp_nocase(msg->type, "option") == 0) { VOTEOPTION *option = voteoption_first; while(option) { if(str_comp_nocase(msg->value, option->command) == 0) { str_format(chatmsg, sizeof(chatmsg), "%s called vote to change server option '%s'", server_clientname(client_id), option->command); str_format(desc, sizeof(desc), "%s", option->command); str_format(cmd, sizeof(cmd), "%s", option->command); break; } option = option->next; } if(!option) { str_format(chatmsg, sizeof(chatmsg), "'%s' isn't an option on this server", msg->value); game.send_chat_target(client_id, chatmsg); return; } } else if(str_comp_nocase(msg->type, "kick") == 0) { int kick_id = atoi(msg->value); if(!config.sv_vote_kick) { game.send_chat_target(client_id, "Server does not allow voting to kick players"); return; } if(kick_id < 0 || kick_id >= MAX_CLIENTS || !game.players[kick_id] || game.players[kick_id]->ball) { game.send_chat_target(client_id, "Invalid client id to kick"); return; } char ip[16]; server_getip(kick_id, ip); str_format(chatmsg, sizeof(chatmsg), "Vote called to kick '%s'", server_clientname(kick_id)); str_format(desc, sizeof(desc), "kick '%s'", server_clientname(kick_id)); str_format(cmd, sizeof(cmd), "kick %d", kick_id); if (!config.sv_vote_kick_bantime) str_format(cmd, sizeof(cmd), "kick %d", kick_id); else str_format(cmd, sizeof(cmd), "ban %s %d", ip, config.sv_vote_kick_bantime); } if(cmd[0]) { game.send_chat(-1, GAMECONTEXT::CHAT_ALL, chatmsg); game.start_vote(desc, cmd); p->vote = 1; game.vote_creator = client_id; p->last_votecall = now; game.send_vote_status(-1); } } else if(msgtype == NETMSGTYPE_CL_VOTE) { if(!game.vote_closetime) return; if(p->vote == 0) { NETMSG_CL_VOTE *msg = (NETMSG_CL_VOTE *)rawmsg; p->vote = msg->vote; game.send_vote_status(-1); } } else if (msgtype == NETMSGTYPE_CL_SETTEAM && !game.world.paused) { NETMSG_CL_SETTEAM *msg = (NETMSG_CL_SETTEAM *)rawmsg; if(p->team == msg->team || (config.sv_spamprotection && p->last_setteam+time_freq()*3 > time_get())) return; // Switch team on given client and kill/respawn him if(game.controller->can_join_team(msg->team, client_id)) { if(game.controller->can_change_team(p, msg->team)) { p->last_setteam = time_get(); p->set_team(msg->team); (void) game.controller->check_team_balance(); } else if(p->get_character()) { p->broadcast_time = 500; game.send_broadcast("Teams must be balanced, please join other team", client_id); } } else { char buf[128]; str_format(buf, sizeof(buf), "Only %d active players are allowed", config.sv_max_clients-config.sv_spectator_slots); if(p->get_character()) { p->broadcast_time = 500; game.send_broadcast(buf, client_id); } } } else if (msgtype == NETMSGTYPE_CL_CHANGEINFO || msgtype == NETMSGTYPE_CL_STARTINFO) { NETMSG_CL_CHANGEINFO *msg = (NETMSG_CL_CHANGEINFO *)rawmsg; if(config.sv_spamprotection && p->last_changeinfo+time_freq()*5 > time_get()) return; p->last_changeinfo = time_get(); p->use_custom_color = msg->use_custom_color; p->color_body = msg->color_body; p->color_feet = msg->color_feet; // check for invalid chars unsigned char *name = (unsigned char *)msg->name; while (*name) { if(*name < 32) *name = ' '; name++; } // copy old name char oldname[MAX_NAME_LENGTH]; str_copy(oldname, server_clientname(client_id), MAX_NAME_LENGTH); server_setclientname(client_id, msg->name); if(msgtype == NETMSGTYPE_CL_CHANGEINFO && strcmp(oldname, server_clientname(client_id)) != 0) { char chattext[256]; str_format(chattext, sizeof(chattext), "%s changed name to %s", oldname, server_clientname(client_id)); game.send_chat(-1, GAMECONTEXT::CHAT_ALL, chattext); } // set skin str_copy(p->skin_name, msg->skin, sizeof(p->skin_name)); game.controller->on_player_info_change(p); if(msgtype == NETMSGTYPE_CL_STARTINFO) { // send vote options NETMSG_SV_VOTE_CLEAROPTIONS clearmsg; clearmsg.pack(MSGFLAG_VITAL); server_send_msg(client_id); VOTEOPTION *current = voteoption_first; while(current) { NETMSG_SV_VOTE_OPTION optionmsg; optionmsg.command = current->command; optionmsg.pack(MSGFLAG_VITAL); server_send_msg(client_id); current = current->next; } // send tuning parameters to client send_tuning_params(client_id); // NETMSG_SV_READYTOENTER m; m.pack(MSGFLAG_VITAL|MSGFLAG_FLUSH); server_send_msg(client_id); } } else if (msgtype == NETMSGTYPE_CL_EMOTICON && !game.world.paused) { NETMSG_CL_EMOTICON *msg = (NETMSG_CL_EMOTICON *)rawmsg; if(config.sv_spamprotection && p->last_emote+time_freq()*3 > time_get()) return; p->last_emote = time_get(); game.send_emoticon(client_id, msg->emoticon); } else if (msgtype == NETMSGTYPE_CL_KILL && !game.world.paused) { if(p->last_kill+time_freq()*3 > time_get()) return; p->last_kill = time_get(); p->kill_character(WEAPON_SELF); p->respawn_tick = server_tick()+server_tickspeed()*3; } }
void mods_message(int msgtype, int client_id) { void *rawmsg = netmsg_secure_unpack(msgtype); PLAYER *p = game.players[client_id]; if(!rawmsg) { dbg_msg("server", "dropped weird message '%s' (%d), failed on '%s'", netmsg_get_name(msgtype), msgtype, netmsg_failed_on()); return; } if(msgtype == NETMSGTYPE_CL_SAY) { NETMSG_CL_SAY *msg = (NETMSG_CL_SAY *)rawmsg; int team = msg->team; if(team) team = p->team; else team = GAMECONTEXT::CHAT_ALL; if(config.sv_spamprotection && p->last_chat+time_freq() > time_get()) { if(!strcmp(msg->message, "/rank") && game.controller->is_race()) game.players[client_id]->last_chat = time_get()+time_freq()*10; else game.players[client_id]->last_chat = time_get(); } else { game.players[client_id]->last_chat = time_get(); if(!strcmp(msg->message, "/info")) { char buf[128]; str_format(buf, sizeof(buf), "DJUMP 0.32 from EliteKuchen.", RACE_VERSION); game.send_chat_target(client_id, buf); str_format(buf, sizeof(buf), "based on : Race mod %s from Rajh and Redix.", RACE_VERSION); game.send_chat_target(client_id, buf); } else if(!strncmp(msg->message, "/top5", 5) && game.controller->is_race()) { const char *pt = msg->message; int number = 0; pt += 6; while(*pt && *pt >= '0' && *pt <= '9') { number = number*10+(*pt-'0'); pt++; } if(number) ((GAMECONTROLLER_RACE*)game.controller)->score.top5_draw(client_id, number); else ((GAMECONTROLLER_RACE*)game.controller)->score.top5_draw(client_id, 0); } else if(!strncmp(msg->message, "/rank", 5) && game.controller->is_race()) { char buf[512]; const char *name = msg->message; name += 6; int pos; PLAYER_SCORE *pscore; if(!strcmp(msg->message, "/rank")) pscore = ((GAMECONTROLLER_RACE*)game.controller)->score.search_score(client_id, 1, &pos); else pscore = ((GAMECONTROLLER_RACE*)game.controller)->score.search_name(name, &pos, 1); if(pscore && pos > -1) { int punkte = pscore->points; char client_name[128]; str_format(client_name, sizeof(client_name), " (%s)", server_clientname(client_id)); str_format(buf, sizeof(buf), "%d. %s Points:%d", pos, pscore->name, punkte); if(strcmp(msg->message, "/rank")) strcat(buf, client_name); game.send_chat(-1, GAMECONTEXT::CHAT_ALL, buf); game.players[client_id]->last_chat = time_get()+time_freq()*3; return; } else if(pos == -1) str_format(buf, sizeof(buf), "Several players were found."); else str_format(buf, sizeof(buf), "%s is not ranked", strcmp(msg->message, "/rank")?name:server_clientname(client_id)); game.send_chat_target(client_id, buf); } else if(!strcmp(msg->message, "/cmdlist")) { game.send_chat_target(client_id, "---Command List---"); game.send_chat_target(client_id, "\"/info\" information about the mod"); game.send_chat_target(client_id, "\"/rank\" shows your rank"); game.send_chat_target(client_id, "\"/rank NAME\" shows the rank of a specific player"); game.send_chat_target(client_id, "\"/top5 X\" shows the top 5"); } else if(!strncmp(msg->message, "/", 1)) { game.send_chat_target(client_id, "Wrong command."); game.send_chat_target(client_id, "Say \"/cmdlist\" for list of command available."); } else game.send_chat(client_id, team, msg->message); } } else if(msgtype == NETMSGTYPE_CL_CALLVOTE) { int64 now = time_get(); if(game.vote_closetime) { game.send_chat_target(client_id, "Wait for current vote to end before calling a new one."); return; } int64 timeleft = p->last_votecall + time_freq()*60 - now; if(timeleft > 0) { char chatmsg[512] = {0}; str_format(chatmsg, sizeof(chatmsg), "You must wait %d seconds before making another vote", (timeleft/time_freq())+1); game.send_chat_target(client_id, chatmsg); return; } char chatmsg[512] = {0}; char desc[512] = {0}; char cmd[512] = {0}; NETMSG_CL_CALLVOTE *msg = (NETMSG_CL_CALLVOTE *)rawmsg; if(str_comp_nocase(msg->type, "option") == 0) { VOTEOPTION *option = voteoption_first; while(option) { if(str_comp_nocase(msg->value, option->command) == 0) { str_format(chatmsg, sizeof(chatmsg), "%s called vote to change server option '%s'", server_clientname(client_id), option->command); str_format(desc, sizeof(desc), "%s", option->command); str_format(cmd, sizeof(cmd), "%s", option->command); break; } option = option->next; } if(!option) { str_format(chatmsg, sizeof(chatmsg), "'%s' isn't an option on this server", msg->value); game.send_chat_target(client_id, chatmsg); return; } } else if(str_comp_nocase(msg->type, "kick") == 0) { if(!config.sv_vote_kick) { game.send_chat_target(client_id, "Server does not allow voting to kick players"); return; } int kick_id = atoi(msg->value); if(kick_id < 0 || kick_id >= MAX_CLIENTS || !game.players[kick_id]) { game.send_chat_target(client_id, "Invalid client id to kick"); return; } str_format(chatmsg, sizeof(chatmsg), "%s called for vote to kick '%s'", server_clientname(client_id), server_clientname(kick_id)); str_format(desc, sizeof(desc), "Kick '%s'", server_clientname(kick_id)); str_format(cmd, sizeof(cmd), "kick %d", kick_id); if (!config.sv_vote_kick_bantime) str_format(cmd, sizeof(cmd), "kick %d", kick_id); else str_format(cmd, sizeof(cmd), "ban %d %d", kick_id, config.sv_vote_kick_bantime); } if(cmd[0]) { game.send_chat(-1, GAMECONTEXT::CHAT_ALL, chatmsg); game.start_vote(desc, cmd); p->vote = 1; game.vote_creator = client_id; p->last_votecall = now; game.send_vote_status(-1); } } else if(msgtype == NETMSGTYPE_CL_VOTE) { if(!game.vote_closetime) return; if(p->vote == 0) { NETMSG_CL_VOTE *msg = (NETMSG_CL_VOTE *)rawmsg; p->vote = msg->vote; game.send_vote_status(-1); } } else if (msgtype == NETMSGTYPE_CL_SETTEAM && !game.world.paused) { NETMSG_CL_SETTEAM *msg = (NETMSG_CL_SETTEAM *)rawmsg; if(p->team == msg->team || (config.sv_spamprotection && p->last_setteam+time_freq()*3 > time_get())) return; // Switch team on given client and kill/respawn him if(game.controller->can_join_team(msg->team, client_id)) { if(game.controller->can_change_team(p, msg->team)) { p->last_setteam = time_get(); p->set_team(msg->team); (void) game.controller->check_team_balance(); } else game.send_broadcast("Teams must be balanced, please join other team", client_id); } else { char buf[128]; str_format(buf, sizeof(buf), "Only %d active players are allowed", config.sv_max_clients-config.sv_spectator_slots); game.send_broadcast(buf, client_id); } } else if (msgtype == NETMSGTYPE_CL_CHANGEINFO || msgtype == NETMSGTYPE_CL_STARTINFO) { NETMSG_CL_CHANGEINFO *msg = (NETMSG_CL_CHANGEINFO *)rawmsg; if(config.sv_spamprotection && p->last_changeinfo+time_freq()*5 > time_get()) return; p->last_changeinfo = time_get(); p->use_custom_color = msg->use_custom_color; p->color_body = msg->color_body; p->color_feet = msg->color_feet; // check for invalid chars unsigned char *name = (unsigned char *)msg->name; while (*name) { if(*name < 32) *name = ' '; name++; } // copy old name char oldname[MAX_NAME_LENGTH]; str_copy(oldname, server_clientname(client_id), MAX_NAME_LENGTH); server_setclientname(client_id, msg->name); if(msgtype == NETMSGTYPE_CL_CHANGEINFO && strcmp(oldname, server_clientname(client_id)) != 0) { char chattext[256]; str_format(chattext, sizeof(chattext), "%s changed name to %s", oldname, server_clientname(client_id)); game.send_chat(-1, GAMECONTEXT::CHAT_ALL, chattext); } // set skin str_copy(p->skin_name, msg->skin, sizeof(p->skin_name)); game.controller->on_player_info_change(p); if(msgtype == NETMSGTYPE_CL_STARTINFO) { // send vote options NETMSG_SV_VOTE_CLEAROPTIONS clearmsg; clearmsg.pack(MSGFLAG_VITAL); server_send_msg(client_id); VOTEOPTION *current = voteoption_first; while(current) { NETMSG_SV_VOTE_OPTION optionmsg; optionmsg.command = current->command; optionmsg.pack(MSGFLAG_VITAL); server_send_msg(client_id); current = current->next; } // send tuning parameters to client send_tuning_params(client_id); // NETMSG_SV_READYTOENTER m; m.pack(MSGFLAG_VITAL|MSGFLAG_FLUSH); server_send_msg(client_id); } } else if (msgtype == NETMSGTYPE_CL_EMOTICON && !game.world.paused) { NETMSG_CL_EMOTICON *msg = (NETMSG_CL_EMOTICON *)rawmsg; if(config.sv_spamprotection && p->last_emote+time_freq()*3 > time_get()) return; p->last_emote = time_get(); game.send_emoticon(client_id, msg->emoticon); } else if (msgtype == NETMSGTYPE_CL_KILL && !game.world.paused) { if(p->last_kill+time_freq()*3 > time_get()) return; p->last_kill = time_get(); p->kill_character(WEAPON_SELF); p->respawn_tick = server_tick()+server_tickspeed()*3; if(game.controller->is_race()) p->respawn_tick = server_tick(); } }