From bfc06bba8192f7466dfdd183835ab9798ab714c9 Mon Sep 17 00:00:00 2001 From: Samual Date: Sat, 26 Nov 2011 23:17:47 -0500 Subject: [PATCH] Start re-write of voting command structure --- qcsrc/server/clientcommands.qc | 2 +- qcsrc/server/gamecommand.qc | 7 +- qcsrc/server/vote.qc | 313 ++++++++++++--------------------- 3 files changed, 122 insertions(+), 200 deletions(-) diff --git a/qcsrc/server/clientcommands.qc b/qcsrc/server/clientcommands.qc index fde3fd943..64ea6b7ac 100644 --- a/qcsrc/server/clientcommands.qc +++ b/qcsrc/server/clientcommands.qc @@ -952,7 +952,7 @@ void SV_ParseClientCommand(string command) { return; // handled by a mutator } - else if(GameCommand_Vote(command, self)) + else if(VoteCommand(self, argc)) { return; // handled by server/vote.qc } diff --git a/qcsrc/server/gamecommand.qc b/qcsrc/server/gamecommand.qc index 977b7b334..4e5dbfd4d 100644 --- a/qcsrc/server/gamecommand.qc +++ b/qcsrc/server/gamecommand.qc @@ -1,6 +1,6 @@ // ===================================================== // Server side game commands code, reworked by Samual -// Last updated: November 8th, 2011 +// Last updated: November 27th, 2011 // ===================================================== #define GC_REQUEST_COMMAND 1 @@ -1978,7 +1978,8 @@ void GameCommand(string command) { print("\nUsage:^3 sv_cmd COMMAND...^7, where possible commands are:\n"); GameCommand_macro_help(); - GameCommand_Vote("help", world); + VoteCommand_macro_help(); + GameCommand_Ban("help"); GameCommand_Generic("help"); print("For help about specific commands, type sv_cmd help COMMAND\n"); @@ -1989,7 +1990,7 @@ void GameCommand(string command) return; } } - else if(GameCommand_Vote(command, world)) + else if(VoteCommand(world, argc)) { return; // handled by server/vote.qc } diff --git a/qcsrc/server/vote.qc b/qcsrc/server/vote.qc index 12b4fe700..f5bf7727a 100644 --- a/qcsrc/server/vote.qc +++ b/qcsrc/server/vote.qc @@ -1,3 +1,16 @@ +// ============================================= +// Server side voting code, reworked by Samual +// Last updated: November 27th, 2011 +// ============================================= + +#define VC_REQUEST_COMMAND 1 +#define VC_REQUEST_USAGE 2 + + +// ============================ +// Misc. Supporting Functions +// ============================ + float Nagger_SendEntity(entity to, float sendflags) { float nags, i, f, b; @@ -65,20 +78,24 @@ float Nagger_SendEntity(entity to, float sendflags) return TRUE; } + void Nagger_Init() { Net_LinkEntity(nagger = spawn(), FALSE, 0, Nagger_SendEntity); } + void Nagger_VoteChanged() { if(nagger) nagger.SendFlags |= 128; } + void Nagger_VoteCountChanged() { if(nagger) nagger.SendFlags |= 64; } + void Nagger_ReadyCounted() { if(nagger) @@ -326,208 +343,112 @@ float RemapVote(string vote, string cmd, entity e) return TRUE; } -float GameCommand_Vote(string s, entity e) + +// ======================= +// Command Sub-Functions +// ======================= + +void VoteCommand_abstain(float request) { - float playercount; - float argc; - argc = tokenize_console(s); - if(argv(0) == "help") { - print_to(e, " vote COMMANDS ARGUMENTS. See 'vhelp' for more info."); - return TRUE; - } else if(argv(0) == "vote") { - if(argv(1) == "") { - print_to(e, "^1You have to supply a vote command. See 'vhelp' for more info."); - } else if(argv(1) == "help") { - VoteHelp(e); - } else if(argv(1) == "status") { - if(votecalled) { - print_to(e, strcat("^7Vote for ", votecalledvote_display, "^7 called by ^7", VoteNetname(votecaller), "^7.")); - } else { - print_to(e, "^1No vote called."); - } - } else if(argv(1) == "call") { - if(!e || autocvar_sv_vote_call) { - if(autocvar_sv_vote_nospectators && e && e.classname != "player") { - print_to(e, "^1Error: Only players can call a vote."); // TODO invent a cvar name for allowing votes by spectators during warmup anyway - } - else if(timeoutStatus) { //don't allow a vote call during a timeout - print_to(e, "^1Error: You can not call a vote while a timeout is active."); - } - else if(votecalled) { - print_to(e, "^1There is already a vote called."); - } else { - string vote; - vote = VoteParse(s, argc); - if(vote == "") { - print_to(e, "^1Your vote is empty. See 'vhelp' for more info."); - } else if(e - && time < e.vote_next) { - print_to(e, strcat("^1You have to wait ^2", ftos(ceil(e.vote_next - time)), "^1 seconds before you can again call a vote.")); - } else if(VoteCheckNasty(vote)) { - print_to(e, "Syntax error in command. See 'vhelp' for more info."); - } else if(RemapVote(vote, "vcall", e)) { - votecalledvote = strzone(RemapVote_vote); - votecalledvote_display = strzone(RemapVote_display); - votecalled = TRUE; - votecalledmaster = FALSE; - votefinished = time + autocvar_sv_vote_timeout; - votecaller = e; // remember who called the vote - if(e) { - e.vote_vote = 1; // of course you vote yes - e.vote_next = time + autocvar_sv_vote_wait; - } - bprint("\{1}^2* ^3", VoteNetname(votecaller), "^2 calls a vote for ", votecalledvote_display, "\n"); - if(autocvar_sv_eventlog) - GameLogEcho(strcat(":vote:vcall:", ftos(votecaller.playerid), ":", votecalledvote_display)); - Nagger_VoteChanged(); - VoteCount(); // needed if you are the only one - msg_entity = e; - - entity player; - FOR_EACH_REALCLIENT(player) - { - ++playercount; - } - if(playercount > 1) // don't announce a "vote now" sound if player is alone - Announce("votecall"); - } else { - print_to(e, "^1This vote is not ok. See 'vhelp' for more info."); - } - } - } else { - print_to(e, "^1Vote calling is NOT allowed."); - } - } else if(argv(1) == "stop") { - if(!votecalled) { - print_to(e, "^1No vote called."); - } else if(e == votecaller) { // the votecaller can stop a vote - VoteStop(e); - } else if(!e) { // server admin / console can too - VoteStop(e); - } else if(e.vote_master) { // masters can too - VoteStop(e); - } else { - print_to(e, "^1You are not allowed to stop that Vote."); - } - } else if(argv(1) == "master") { - if(autocvar_sv_vote_master) { - if(votecalled) { - print_to(e, "^1There is already a vote called."); - } else { - votecalled = TRUE; - votecalledmaster = TRUE; - votecalledvote = strzone("XXX"); - votecalledvote_display = strzone("^3master"); - votefinished = time + autocvar_sv_vote_timeout; - votecaller = e; // remember who called the vote - if(e) { - e.vote_vote = 1; // of course you vote yes - e.vote_next = time + autocvar_sv_vote_wait; - } - bprint("\{1}^2* ^3", VoteNetname(votecaller), "^2 calls a vote to become ^3master^2.\n"); - if(autocvar_sv_eventlog) - GameLogEcho(strcat(":vote:vcall:", ftos(votecaller.playerid), ":", votecalledvote_display)); - Nagger_VoteChanged(); - VoteCount(); // needed if you are the only one - } - } else { - print_to(e, "^1Vote to become master is NOT allowed."); - } - } else if(argv(1) == "do") { - if(!e || e.vote_master) { - string dovote; - dovote = VoteParse(s, argc); - if(dovote == "") { - print_to(e, "^1Your command was empty. See 'vhelp' for more info."); - } else if(VoteCheckNasty(dovote)) { - print_to(e, "Syntax error in command. See 'vhelp' for more info."); - } else if(RemapVote(dovote, "vdo", e)) { // strcat seems to be necessary - bprint("\{1}^2* ^3", VoteNetname(e), "^2 used their ^3master^2 status to do \"^2", RemapVote_display, "^2\".\n"); - if(autocvar_sv_eventlog) - GameLogEcho(strcat(":vote:vdo:", ftos(e.playerid), ":", RemapVote_display)); - localcmd(strcat(RemapVote_vote, "\n")); - } else { - print_to(e, "^1This command is not ok. See 'vhelp' for more info."); - } - } else { - print_to(e, "^1You are NOT a master. You might need to login or vote to become master first. See 'vhelp' for more info."); - } - } else if(argv(1) == "login") { - string masterpwd; - masterpwd = autocvar_sv_vote_master_password; - if(masterpwd != "") { - float granted; - granted = (masterpwd == argv(2)); - if (e) - e.vote_master = granted; - if(granted) { - print("Accepted master login from ", VoteNetname(e), "\n"); - bprint("\{1}^2* ^3", VoteNetname(e), "^2 logged in as ^3master^2\n"); - if(autocvar_sv_eventlog) - GameLogEcho(strcat(":vote:vlogin:", ftos(e.playerid))); - } - else - print("REJECTED master login from ", VoteNetname(e), "\n"); - } - else - print_to(e, "^1Login to become master is NOT allowed."); - } else if(argv(1) == "yes") { - if(!votecalled) { - print_to(e, "^1No vote called."); - } else if (!e) { - print_to(e, "^1You can't vote from the server console."); - } else if(e.vote_vote == 0 - || autocvar_sv_vote_change) { - msg_entity = e; - print_to(e, "^1You accepted the vote."); - e.vote_vote = 1; - if(!autocvar_sv_vote_singlecount) { - VoteCount(); - } - } else { - print_to(e, "^1You have already voted."); - } - } else if(argv(1) == "no") { - if(!votecalled) { - print_to(e, "^1No vote called."); - } else if (!e) { - print_to(e, "^1You can't vote from the server console."); - } else if(e.vote_vote == 0 - || autocvar_sv_vote_change) { - msg_entity = e; - print_to(e, "^1You rejected the vote."); - e.vote_vote = -1; - if(!autocvar_sv_vote_singlecount) { - VoteCount(); - } - } else { - print_to(e, "^1You have already voted."); - } - } else if(argv(1) == "abstain" || argv(1) == "dontcare") { - if(!votecalled) { - print_to(e, "^1No vote called."); - } else if (!e) { - print_to(e, "^1You can't vote from the server console."); - } else if(e.vote_vote == 0 - || autocvar_sv_vote_change) { - msg_entity = e; - print_to(e, "^1You abstained from your vote."); - e.vote_vote = -2; - if(!autocvar_sv_vote_singlecount) { - VoteCount(); - } - } else { - print_to(e, "^1You have already voted."); - } - } else { - // ignore this? - print_to(e, "^1Unknown vote command."); + switch(request) + { + case VC_REQUEST_COMMAND: + { + + return; + } + + default: + case VC_REQUEST_USAGE: + { + print("\nUsage:^3 vote \n"); + print(" No arguments required.\n"); + return; } - return TRUE; } +} + +/* use this when creating a new command, making sure to place it in alphabetical order. +void VoteCommand_(float request) +{ + switch(request) + { + case VC_REQUEST_COMMAND: + { + + return; + } + + default: + case VC_REQUEST_USAGE: + { + print("\nUsage:^3 vote \n"); + print(" No arguments required.\n"); + return; + } + } +} +*/ + + +// ================================== +// Macro system for server commands +// ================================== + +// Do not hard code aliases for these, instead create them in commands.cfg... also: keep in alphabetical order, please ;) +#define VOTE_COMMANDS(request,arguments) \ + VOTE_COMMAND("", VoteCommand_(request, arguments), "") \ + /* nothing */ + +void VoteCommand_macro_help() +{ + #define VOTE_COMMAND(name,function,description) \ + { print(" ^2", name, "^7: ", description, "\n"); } + + VOTE_COMMANDS(0, 0) + #undef VOTE_COMMAND + + return; +} + +float VoteCommand_macro_command(float argc) +{ + #define VOTE_COMMAND(name,function,description) \ + { if(name == strtolower(argv(0))) { function; return TRUE; } } + + VOTE_COMMANDS(VC_REQUEST_COMMAND, argc) + #undef VOTE_COMMAND + + return FALSE; +} + +float VoteCommand_macro_usage(float argc) +{ + #define VOTE_COMMAND(name,function,description) \ + { if(name == strtolower(argv(1))) { function; return TRUE; } } + + VOTE_COMMANDS(VC_REQUEST_USAGE, argc) + #undef VOTE_COMMAND + return FALSE; } + +// ====================================== +// Main function handling vote commands +// ====================================== + +float VoteCommand(entity caller, float argc) +{ + if(VoteCommand_macro_command(argc)) + { + return; + } + + // nothing above caught the command, must be invalid + print("Unknown server command", ((command != "") ? strcat(" \"", command, "\"") : ""), ". For a list of supported commands, try sv_cmd help.\n"); +} + void VoteHelp(entity e) { string vmasterdis; if(!autocvar_sv_vote_master) { -- 2.39.2