]> icculus.org git repositories - divverent/nexuiz.git/blob - qcsrc/gamec/clientcommands.c
better documented voting system
[divverent/nexuiz.git] / qcsrc / gamec / clientcommands.c
1 void SV_ParseClientCommand(string s) {
2         tokenize(s);
3
4         if(argv(0) == "clogin") {
5                 if(cvar("sv_clientcommands")) {
6                         if(self.adminstatus < -5) {
7                                 sprint(self, "Too many unsuccessful tries.\n");
8                         } else if(argv(1) == cvar_string("sv_clientcommands_password")) {
9                                 self.adminstatus = 1;
10                                 sprint(self, "You now have remote admin status.\n");
11                         } else {
12                                 sprint(self, "Wrong password.\n");
13                                 self.adminstatus--;
14                                 if(self.adminstatus == 0)
15                                         sprint(self, "You lost remote admin status.\n");
16                         }
17                 } else {
18                         sprint(self, "Clientside commands NOT allowed.\n");
19                 }
20         } else if(argv(0) == "ccmd") {
21                 if(cvar("sv_clientcommands")) {
22                         if(self.adminstatus > 0) {
23                                 local string command;
24                                 command = argv(1);
25                                 local float index;
26                                 index = 2;
27                                 while(argv(index) != "") {
28                                         command = strcat(command, " ", argv(index));
29                                         index++;
30                                 }
31                                 localcmd(command);
32                         } else
33                                 sprint(self, "You don't have remote admin status.\n");
34                 } else {
35                         sprint(self, "Clientside commands NOT allowed.\n");
36                 }
37         } else if(argv(0) == "vote") {
38                 if(argv(1) == "help") {
39                         sprint(self, "^1You can use voting with \"^2cmd vote help^1\" \"^2cmd vote status^1\" \"^2cmd vote call ^3COMMAND ARGUMENTS^1\" \"^2cmd vote stop^1\" \"^2cmd vote yes^1\" \"^2cmd vote no^1\".\n");
40                         sprint(self, "^1Or if your version is up to date you can use these aliases \"^2vhelp^1\" \"^2vstatus^1\" \"^2vcall ^3COMMAND ARGUMENTS^1\" \"^2vstop^1\" \"^2vyes^1\" \"^2vno^1\".\n");
41                         sprint(self, "^1\"^2help^1\" shows this info.\n");
42                         sprint(self, "^1\"^2status^1\" shows if there is a vote called and who called it.\n");
43                         sprint(self, "^1\"^2call^1\" is used to call a vote. See the list of allowed commands.\n");
44                         sprint(self, "^1If more then 50% of the players vote yes the vote is executed.\n");
45                         sprint(self, "^1If more then 50% of the players vote no the vote fails.\n");
46                         sprint(self, "^1\"^2stop^1\" can be used by the vote caller to stop a vote and maybe correct it.\n");
47                         sprint(self, "^1\"^2yes^1\" and \"^2no^1\" to make your vote.\n");
48                         sprint(self, "^1You can call a vote with these commands:\n");
49                         sprint(self, strcat("^1\"^2vcall^1\" ^3", cvar_string("sv_vote_allowed"), "^1 and further ^3arguments^1\n"));
50                 } else if(argv(1) == "status") {
51                         if(votecalled == "") {
52                                 sprint(self, "^1No vote called.\n");
53                         } else {
54                                 sprint(self, strcat("^7Vote for \"^1", votecalled, "^7\" called by \"", votecaller.netname, "^7\".\n"));
55                         }
56                 } else if(argv(1) == "call") {
57                         if(votecalled == "") {
58                                 local string vote;
59                                 vote = argv(2);
60                                 local float index;
61                                 index = 3;
62                                 while(argv(index) != "") {
63                                         vote = strcat(vote, " ", argv(index));
64                                         index++;
65                                 }
66
67                                 // necessary for some of the string operations
68                                 vote = strzone(vote);
69
70                                 // now we remove some things that could be misused
71                                 index = 0;
72                                 local float found;
73                                 found = FALSE;
74                                 local float votelength;
75                                 votelength = strlen(vote);
76                                 while(!found && index < votelength)
77                                 {
78                                         local string badchar;
79                                         badchar = substring(vote, index, 1);
80                                         if(badchar == ";"
81                                            || badchar == "\n")
82                                         {
83                                                 found = TRUE;
84                                         } else {
85                                                 index++;
86                                         }
87                                 }
88                                 vote = substring(vote, 0, index);
89
90                                 if(vote == "") {
91                                         sprint(self, "^1You have to vote for something.\n");
92                                 } else if(time < self.vote_next) {
93                                         sprint(self, strcat("^1You have to wait ^2", ftos(self.vote_next - time), "^1 seconds before you can again call a vote.\n"));
94                                 } else if(VoteAllowed(strcat(argv(2)))) { // strcat seems to be necessary
95                                         votecalled = strzone(vote);
96                                         votecaller = self; // remember who called the vote
97                                         self.vote_vote = 1; // of course you vote yes
98                                         self.vote_finished = time + cvar("sv_vote_timeout");
99                                         self.vote_next = time + cvar("sv_vote_wait");
100                                         bprint(strcat("^3Vote for \"^1", votecalled, "^3\" called by \"", self.netname, "^3\".\n"));
101                                         VoteCount(); // needed if you are the only one
102                                 } else {
103                                         sprint(self, "^1This vote is not ok. See help for more info.\n");
104                                 }
105                         } else {
106                                 sprint(self, "^1There is already a vote called.\n");
107                         }
108                 } else if(argv(1) == "stop") {
109                         if(votecalled == "") {
110                                 sprint(self, "^1No vote called.\n");
111                         } else if(votecaller == self
112                                   || self.adminstatus > 0) { // the votecaller and admins can stop a vote
113                                 if(votecaller == self) {
114                                         // disable next votetimer so you can correct your vote
115                                         self.vote_next = 0;
116                                 }
117                                 VoteTimeout(votecaller);
118                         } else {
119                                 sprint(self, "^1You are not allowed to stop that Vote.\n");
120                         }
121                 } else if(argv(1) == "yes") {
122                         if(votecalled == "") {
123                                 sprint(self, "^1No vote called.\n");
124                         } else if(self.vote_vote == 0
125                                   || cvar("sv_vote_change")) {
126                                 self.vote_vote = 1;
127                                 if(!cvar("sv_vote_singlecount")) {
128                                         VoteCount();
129                                 }
130                         } else {
131                                 sprint(self, "^1You have already voted.\n");
132                         }
133                 } else if(argv(1) == "no") {
134                         if(votecalled == "") {
135                                 sprint(self, "^1No vote called.\n");
136                         } else if(self.vote_vote == 0
137                                   || cvar("sv_vote_change")) {
138                                 self.vote_vote = -1;
139                                 if(!cvar("sv_vote_singlecount")) {
140                                         VoteCount();
141                                 }
142                         } else {
143                                 sprint(self, "^1You have already voted.\n");
144                         }
145                 } else {
146                         // ignore this?
147                         sprint(self, "^1Unknown vote command.\n");
148                 }
149         } else {
150                 clientcommand(self,s);
151         }
152 }
153
154 float VoteAllowed(string votecommand) {
155         tokenize(cvar_string("sv_vote_allowed"));
156         local float index;
157         index = 0;
158         while(argv(index) != "") {
159                 local string allowed;
160                 allowed = argv(index);
161                 if(votecommand == allowed) {
162                         return TRUE;
163                 }
164                 index++;
165         }
166         return FALSE;
167 }
168
169 void VoteCount() {
170         local float playercount;
171         playercount = 0;
172         local float yescount;
173         yescount = 0;
174         local float nocount;
175         nocount = 0;
176         local entity player;
177         local entity voter;
178         player = find(player, classname, "player");
179         while(player)
180         {
181                 if(player.vote_vote < 0) {
182                         nocount++;
183                 } else if(player.vote_vote > 0) {
184                         yescount++;
185                 }
186
187                 if(self.vote_finished > 0) {
188                         voter = player;
189                 }
190
191                 playercount++;
192                 player = find(player, classname, "player");
193         }
194
195         if((playercount / 2) < yescount) { // vote passed
196                 VoteDo(voter);
197         } else if((playercount / 2) < nocount) { // vote rejected
198                 VoteTimeout(voter);
199         } // else still running
200 }
201
202 void VoteDo(entity voter) {
203         bprint(strcat("^2The vote for \"^1", votecalled, "^2\" from \"", voter.netname, "^2\" DID PASS.\n"));
204         localcmd(votecalled);
205         VoteReset();
206 }
207
208 void VoteTimeout(entity voter) {
209         bprint(strcat("^5The vote for \"^1", votecalled, "^5\" from \"", voter.netname, "^5\" did NOT pass.\n"));
210         VoteReset();
211 }
212
213 void VoteReset() {
214         local entity player;
215         player = find(player, classname, "player");
216         while(player)
217         {
218                 player.vote_vote = 0;
219                 player.vote_finished = 0;
220                 player = find(player, classname, "player");
221         }
222         votecalled = "";
223 }