2 Copyright (c) 1993 Richard V. Nash.
3 Copyright (c) 2000 Dan Papasian
4 Copyright (C) Andrew Tridgell 2002
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 const int blitz_rat = 1;
26 const int std_rat = 2;
27 const int wild_rat = 3;
28 const int light_rat = 4;
29 const int bug_rat = 5;
31 int com_more(int p, param_list param)
37 int com_quit(int p, param_list param)
39 struct player *pp = &player_globals.parray[p];
41 /* Examined games are killed on logout */
42 if ((pp->game >= 0) &&
43 ((game_globals.garray[pp->game].status != GAME_EXAMINE) &&
44 (game_globals.garray[pp->game].status != GAME_SETUP))) {
45 pprintf(p, "You can't quit while you are playing a game.\nType 'resign' to resign the game, or you can request an abort with 'abort'.\n");
49 psend_logoutfile(p, MESS_DIR, MESS_LOGOUT);
53 int com_set(int p, param_list param)
59 if (param[1].type == TYPE_NULL)
62 val = param[1].val.string;
63 result = var_set(p, param[0].val.word, val, &which);
68 pprintf(p, "Bad value given for variable %s.\n", param[0].val.word);
71 pprintf(p, "No such variable name %s.\n", param[0].val.word);
74 pprintf(p, "Ambiguous variable name %s.\n", param[0].val.word);
81 int FindPlayer(int p, char* name, int *p1, int *connected)
83 *p1 = player_search(p, name);
86 if (*p1 < 0) { /* player had to be connected and will be
97 static void com_stats_andify(int *numbers, int howmany, char *dest)
103 sprintf(tmp, "%d", numbers[howmany]);
107 else if (howmany == 1)
108 sprintf(tmp, " and ");
116 static void com_stats_rating(char *hdr, struct statistics * stats, char *dest, long now)
122 if (stats->num == 0) return;
124 sprintf(dest, "%-10s%4s %5.1f %4d %4d %4d %4d", hdr,
125 ratstr(stats->rating), current_sterr(stats->sterr, now-stats->ltime),
126 stats->win, stats->los, stats->dra, stats->num);
127 if (stats->whenbest) {
128 time_t besttime = stats->whenbest; // [HGM] time_t could have larger size than int, so don't pass localtime a pointer to it
129 sprintf(tmp, " %d", stats->best);
131 strftime(tmp, sizeof(tmp), " (%d-%b-%Y)", localtime(&besttime));
138 int com_stats(int p, param_list param)
143 char line[255], tmp[255], tmp2[255];
144 int numbers[MAX_OBSERVE > MAX_SIMUL ? MAX_OBSERVE : MAX_SIMUL];
146 int showRatingsFlag, showNotesFlag;
147 int showCommentsFlag = 0;
150 showRatingsFlag = showNotesFlag = 1; /* everything on by default */
152 if (param[0].type == TYPE_WORD) {
153 if (!FindPlayer(p, param[0].val.word, &p1, &connected))
155 if (param[1].type == TYPE_WORD) { /* optional second parameter */
156 char *c = param[1].val.word;
157 showRatingsFlag = showNotesFlag = 0;
159 if (*c == 'r') { showRatingsFlag = 1; c++; }
160 else if (*c == 'n') { showNotesFlag = 1; c++; }
161 else if ((*c == 'c') && check_admin(p, ADMIN_ADMIN)) {
162 showCommentsFlag = 1; c++; }
166 return COM_BADPARAMETERS;
175 strcpy(tmp2, player_globals.parray[p1].name);
176 AddPlayerLists(p1, tmp2);
178 sprintf(line, "\nStatistics for %-17s", tmp2);
179 if ((connected) && (player_globals.parray[p1].status == PLAYER_PROMPT)) {
180 sprintf(tmp, "On for: %s", hms_desc(player_ontime(p1)));
182 sprintf(tmp, " Idle: %s\n", hms_desc(player_idle(p1)));
184 if ((t = player_lastdisconnect(p1)))
185 sprintf(tmp, "(Last disconnected %s):\n", strltime(&t));
187 sprintf(tmp, "(Never connected.)\n");
190 pprintf(p, "%s", line);
191 if (((player_globals.parray[p1].simul_info) != NULL) && (player_globals.parray[p1].simul_info->numBoards)) {
192 for (i = 0, t = 0; i < player_globals.parray[p1].simul_info->numBoards; i++) {
193 if ((numbers[t] = player_globals.parray[p1].simul_info->boards[i] + 1) != 0)
196 pprintf(p, "%s is giving a simul: game%s ", player_globals.parray[p1].name, ((t > 1) ? "s" : ""));
197 com_stats_andify(numbers, t, tmp);
199 } else if (player_globals.parray[p1].game >= 0) {
200 g = player_globals.parray[p1].game;
201 if (game_globals.garray[g].status == GAME_EXAMINE) {
202 pprintf(p, "(Examining game %d: %s vs. %s)\n", g + 1,
203 game_globals.garray[g].white_name, game_globals.garray[g].black_name);
204 } else if (game_globals.garray[g].status == GAME_SETUP) {
205 pprintf(p, "(Setting up game %d: %s vs. %s)\n", g + 1,
206 game_globals.garray[g].white_name, game_globals.garray[g].black_name);
208 pprintf(p, "(playing game %d: %s vs. %s)\n", g + 1,
209 player_globals.parray[game_globals.garray[g].white].name, player_globals.parray[game_globals.garray[g].black].name);
210 if (game_globals.garray[g].link >= 0) {
211 pprintf(p, "(partner is playing game %d: %s vs. %s)\n", game_globals.garray[g].link + 1,
212 player_globals.parray[game_globals.garray[game_globals.garray[g].link].white].name,
213 player_globals.parray[game_globals.garray[game_globals.garray[g].link].black].name);
217 if (player_globals.parray[p1].num_observe) {
218 for (i = 0, t = 0; i < player_globals.parray[p1].num_observe; i++) {
219 g = player_globals.parray[p1].observe_list[i];
220 if ((g != -1) && (check_admin(p, ADMIN_ADMIN) || (game_globals.garray[g].private == 0)))
221 numbers[t++] = g + 1;
224 pprintf(p, "%s is observing game%s ", player_globals.parray[p1].name, ((t > 1) ? "s" : ""));
225 com_stats_andify(numbers, t, tmp);
229 if (player_globals.parray[p1].busy != NULL) {
230 pprintf(p, "(%s %s)\n", player_globals.parray[p1].name, player_globals.parray[p1].busy);
232 if (!CheckPFlag(p1, PFLAG_REG)) {
233 pprintf(p, "%s is NOT a registered player.\n\n", player_globals.parray[p1].name);
235 if (showRatingsFlag > 0) {
237 pprintf(p, "\n rating RD win loss draw total best\n");
238 com_stats_rating("Blitz", &player_globals.parray[p1].b_stats, tmp, now);
239 if (*tmp) pprintf(p, tmp);
240 com_stats_rating("Standard", &player_globals.parray[p1].s_stats, tmp, now);
241 if (*tmp) pprintf(p, tmp);
242 com_stats_rating("Lightning", &player_globals.parray[p1].l_stats, tmp, now);
243 if (*tmp) pprintf(p, tmp);
244 com_stats_rating("Wild", &player_globals.parray[p1].w_stats, tmp, now);
245 if (*tmp) pprintf(p, tmp);
246 com_stats_rating("Bughouse", &player_globals.parray[p1].bug_stats, tmp, now);
247 if (*tmp) pprintf(p, tmp);
251 if (player_globals.parray[p1].adminLevel > 0) {
252 pprintf(p, "Admin Level: ");
253 switch (5*(player_globals.parray[p1].adminLevel/5)) {
255 pprintf(p, "Authorized Helper Person\n");
258 pprintf(p, "Administrator\n");
261 pprintf(p, "Help File Librarian/Administrator\n");
264 pprintf(p, "Master Administrator\n");
267 pprintf(p, "Master Help File Librarian/Administrator\n");
270 pprintf(p, "Assistant Super User\n");
273 pprintf(p, "Super User\n");
276 pprintf(p, "%d\n", player_globals.parray[p1].adminLevel);
281 if (check_admin(p, 1) && !CheckPFlag(p, PFLAG_HIDEINFO)) {
282 pprintf(p, "Full Name : %s\n", (player_globals.parray[p1].fullName ? player_globals.parray[p1].fullName : "(none)"));
283 pprintf(p, "Address : %s\n", (player_globals.parray[p1].emailAddress ? player_globals.parray[p1].emailAddress : "(none)"));
284 pprintf(p, "Host : %s\n",
285 dotQuad(connected ? player_globals.parray[p1].thisHost : player_globals.parray[p1].lastHost));
286 if (CheckPFlag(p1, PFLAG_REG))
287 if (player_globals.parray[p1].num_comments)
288 pprintf(p, "Comments : %d\n", player_globals.parray[p1].num_comments);
289 } else if ((p1 == p) && CheckPFlag(p1, PFLAG_REG))
290 pprintf(p, "Address : %s\n", (player_globals.parray[p1].emailAddress ? player_globals.parray[p1].emailAddress : "(none)"));
292 if (player_globals.parray[p1].socket != -1) {
293 pprintf(p, "\nTimeseal: %s\n", net_globals.con[player_globals.parray[p1].socket]->timeseal ? "yes" : "no");
296 if (connected && CheckPFlag(p1, PFLAG_REG)
297 && (p==p1 || (check_admin(p, 1) && !CheckPFlag(p, PFLAG_HIDEINFO)))) {
298 char *timeToStr = ctime((time_t *) &player_globals.parray[p1].timeOfReg);
300 timeToStr[strlen(timeToStr)-1]='\0';
302 onTime = (time(0) - player_globals.parray[p1].logon_time) + player_globals.parray[p1].totalTime;
304 pprintf(p, "Total time on-line: %s\n", hms_desc(onTime) );
305 pprintf(p, "%% of life on-line: %3.1f (since %s)\n",
306 (double)((onTime*100)/(double)(time(0)-player_globals.parray[p1].timeOfReg)),
310 if (player_globals.parray[p1].num_plan && (showNotesFlag > 0)) {
312 for (i = 0; i < player_globals.parray[p1].num_plan; i++)
313 pprintf(p, "%2d: %s\n", i + 1, (player_globals.parray[p1].planLines[i] != NULL) ? player_globals.parray[p1].planLines[i] : "");
315 if (showCommentsFlag) {
317 pprintf(p, "Comments for %s:\n",player_globals.parray[p1].name);
318 player_show_comments(p, p1);
325 int com_password(int p, param_list param)
327 struct player *pp = &player_globals.parray[p];
328 char *oldpassword = param[0].val.word;
329 char *newpassword = param[1].val.word;
332 if (!CheckPFlag(p, PFLAG_REG)) {
333 pprintf(p, "Setting a password is only for registered players.\n");
337 salt[0] = pp->passwd[3];
338 salt[1] = pp->passwd[4];
340 if (strcmp(chessd_crypt(oldpassword,salt), pp->passwd)) {
341 pprintf(p, "Incorrect password, password not changed!\n");
347 salt[0] = 'a' + random() % 26;
348 salt[1] = 'a' + random() % 26;
350 pp->passwd = strdup(chessd_crypt(newpassword,salt));
351 pprintf(p, "Password changed to \"%s\".\n", newpassword);
355 int com_uptime(int p, param_list param)
357 time_t uptime = time(0) - command_globals.startuptime;
358 int days = (uptime / (60*60*24));
359 int hours = ((uptime % (60*60*24)) / (60*60));
360 int mins = (((uptime % (60*60*24)) % (60*60)) / 60);
361 int secs = (((uptime % (60*60*24)) % (60*60)) % 60);
363 pprintf(p, "Server location: %s Server version : %s\n",
364 config_get_tmp("SERVER_HOSTNAME"), VERS_NUM);
365 pprintf(p, "The server has been up since %s.\n", strltime(&command_globals.startuptime));
370 pprintf(p," %d day%s", days, (days == 1) ? "" : "s");
373 pprintf(p," %d hour%s", hours, (hours == 1) ? "" : "s");
376 pprintf(p," %d minute%s", mins, (mins == 1) ? "" : "s");
379 pprintf(p," %d second%s", secs, (secs == 1) ? "" : "s");
383 pprintf(p, "\nPlayer limit: %d\n", config_get_int("MAX_PLAYER", DEFAULT_MAX_PLAYER));
384 pprintf(p, "\nThere are currently %d players, with a high of %d since last restart.\n", player_count(1), command_globals.player_high);
385 pprintf(p, "There are currently %d games, with a high of %d since last restart.\n", game_count(), command_globals.game_high);
386 pprintf(p, "\nCompiled on %s\n", COMP_DATE);
390 int com_date(int p, param_list param)
393 pprintf(p, "Local time - %s\n", strltime(&t));
394 pprintf(p, "Greenwich time - %s\n", strgtime(&t));
398 static const char *inout_string[] = {
402 static int plogins(int p, char *fname)
405 int inout, registered;
407 char loginName[MAX_LOGIN_NAME + 1];
410 fp = fopen_p("%s", "r", fname);
412 pprintf(p, "Sorry, no login information available.\n");
417 if (fscanf(fp, "%d %s %u %d %s\n", &inout, loginName, &t,
418 ®istered, ipstr) != 5) {
419 d_printf( "CHESSD: Error in login info format. %s\n",
425 pprintf(p, "%s: %-17s %-6s", strltime(&thetime), loginName,
426 inout_string[inout]);
427 if (check_admin(p, 1) && !CheckPFlag(p, PFLAG_HIDEINFO)) {
428 pprintf(p, " from %s\n", ipstr);
436 int com_llogons(int p, param_list param)
439 if (!CheckPFlag(p, PFLAG_REG)) {
440 pprintf(p,"Sorry, guest users may not use this command\n");
443 result = plogins(p, STATS_DIR "/" STATS_LOGONS);
447 int com_logons(int p, param_list param)
449 struct player *pp = &player_globals.parray[p];
450 char fname[MAX_FILENAME_SIZE];
452 if (param[0].type == TYPE_WORD) {
454 if (!FindPlayer(p, param[0].val.word, &p1, &connected))
456 sprintf(fname, "%s/player_data/%c/%s.%s",
458 player_globals.parray[p1].login[0],
459 player_globals.parray[p1].login, STATS_LOGONS);
463 sprintf(fname, "%s/player_data/%c/%s.%s",
469 return plogins(p, fname);
472 #define WHO_OPEN 0x01
473 #define WHO_CLOSED 0x02
474 #define WHO_RATED 0x04
475 #define WHO_UNRATED 0x08
476 #define WHO_FREE 0x10
477 #define WHO_PLAYING 0x20
478 #define WHO_REGISTERED 0x40
479 #define WHO_UNREGISTERED 0x80
480 #define WHO_BUGTEAM 0x100
484 void AddPlayerLists (int p1, char *ptmp)
486 if (check_admin(p1, ADMIN_ADMIN) && CheckPFlag(p1, PFLAG_ADMINLIGHT))
488 if (in_list(p1, L_COMPUTER, player_globals.parray[p1].name))
490 if (in_list(p1, L_FM, player_globals.parray[p1].name))
491 strcat(ptmp, "(FM)");
492 if (in_list(p1, L_IM, player_globals.parray[p1].name))
493 strcat(ptmp, "(IM)");
494 if (in_list(p1, L_GM, player_globals.parray[p1].name))
495 strcat(ptmp, "(GM)");
496 if (in_list(p1, L_WGM, player_globals.parray[p1].name))
497 strcat(ptmp, "(WGM)");
498 if (in_list(p1, L_TD, player_globals.parray[p1].name))
499 strcat(ptmp, "(TD)");
500 if (in_list(p1, L_TEAMS, player_globals.parray[p1].name))
502 if (in_list(p1, L_BLIND, player_globals.parray[p1].name))
506 static void who_terse(int p, int num, int *plist, int type)
508 struct player *pp = &player_globals.parray[p];
509 char ptmp[80 + 20]; /* for highlight */
510 multicol *m = multicol_start(player_globals.parray_size);
515 /* altered DAV 3/15/95 */
517 for (i = 0; i < num; i++) {
520 if (type == blitz_rat)
521 rat = player_globals.parray[p1].b_stats.rating;
522 else if (type == wild_rat)
523 rat = player_globals.parray[p1].w_stats.rating;
524 else if (type == std_rat)
525 rat = player_globals.parray[p1].s_stats.rating;
526 else if (type == light_rat)
527 rat = player_globals.parray[p1].l_stats.rating;
528 else if (type == bug_rat)
529 rat = player_globals.parray[p1].bug_stats.rating;
534 sprintf(ptmp, "%-4s", ratstrii(rat, p1));
535 if ((player_globals.parray[p1].simul_info != NULL) && (player_globals.parray[p1].simul_info->numBoards))
537 else if ((player_globals.parray[p1].game >= 0) && ((game_globals.garray[player_globals.parray[p1].game].status == GAME_EXAMINE) || (game_globals.garray[player_globals.parray[p1].game].status == GAME_SETUP)))
539 else if (player_globals.parray[p1].game >= 0)
541 else if (!CheckPFlag(p1, PFLAG_OPEN))
543 else if (player_idle(p1) > 300)
550 psprintf_highlight(p, ptmp + strlen(ptmp), "%s", player_globals.parray[p1].name);
552 strcat(ptmp, player_globals.parray[p1].name);
555 AddPlayerLists(p1, ptmp);
556 multicol_store(m, ptmp);
558 multicol_pprint(m, p, pp->d_width, 2);
560 pprintf(p, "\n %d players displayed (of %d). (*) indicates system administrator.\n", num, player_count(1));
563 static void who_verbose(p, num, plist)
569 char playerLine[255], tmp[255]; /* +8 for highlight */
570 char p1WithAttrs[255];
573 " +---------------------------------------------------------------+\n"
576 " | User Standard Blitz On for Idle |\n"
579 " +---------------------------------------------------------------+\n"
582 for (i = 0; i < num; i++) {
585 strcpy(playerLine, " |");
587 if (player_globals.parray[p1].game >= 0)
588 sprintf(tmp, "%3d", player_globals.parray[p1].game + 1);
591 strcat(playerLine, tmp);
593 if (!CheckPFlag(p1, PFLAG_OPEN))
597 strcat(playerLine, tmp);
599 if (CheckPFlag(p1, PFLAG_REG))
600 if (CheckPFlag(p1, PFLAG_RATED)) {
607 strcat(playerLine, tmp);
609 /* Modified by hersco to include lists in 'who v.' */
610 strcpy (p1WithAttrs, player_globals.parray[p1].name);
611 AddPlayerLists(p1, p1WithAttrs);
612 p1WithAttrs[17] = '\0';
614 /* Modified by DAV 3/15/95 */
617 psprintf_highlight(p, tmp + strlen(tmp), "%-17s", p1WithAttrs);
619 sprintf(tmp, " %-17s", p1WithAttrs);
621 strcat(playerLine, tmp);
623 sprintf(tmp, " %4s %-4s %5s ",
624 ratstrii(player_globals.parray[p1].s_stats.rating, p1),
625 ratstrii(player_globals.parray[p1].b_stats.rating, p1),
626 hms(player_ontime(p1), 0, 0, 0));
627 strcat(playerLine, tmp);
629 if (player_idle(p1) >= 60) {
630 sprintf(tmp, "%5s |\n", hms(player_idle(p1), 0, 0, 0));
632 sprintf(tmp, " |\n");
634 strcat(playerLine, tmp);
635 pprintf(p, "%s", playerLine);
642 " | %3d Players Displayed |\n",
646 " +---------------------------------------------------------------+\n"
650 static void who_winloss(p, num, plist)
656 char playerLine[255], tmp[255]; /* for highlight */
657 char p1WithAttrs[255];
660 "Name Stand win loss draw Blitz win loss draw idle\n"
663 "---------------- ----- ------------- ----- ------------- ----\n"
666 for (i = 0; i < num; i++) {
667 playerLine[0] = '\0';
670 /* Modified by hersco to include lists in 'who n.' */
671 strcpy (p1WithAttrs, player_globals.parray[p1].name);
672 AddPlayerLists(p1, p1WithAttrs);
673 p1WithAttrs[17] = '\0';
676 psprintf_highlight(p, playerLine, "%-17s", p1WithAttrs);
678 sprintf(playerLine, "%-17s", p1WithAttrs);
680 sprintf(tmp, " %4s %4d %4d %4d ",
681 ratstrii(player_globals.parray[p1].s_stats.rating, p1),
682 (int) player_globals.parray[p1].s_stats.win,
683 (int) player_globals.parray[p1].s_stats.los,
684 (int) player_globals.parray[p1].s_stats.dra);
685 strcat(playerLine, tmp);
687 sprintf(tmp, "%4s %4d %4d %4d ",
688 ratstrii(player_globals.parray[p1].b_stats.rating, p1),
689 (int) player_globals.parray[p1].b_stats.win,
690 (int) player_globals.parray[p1].b_stats.los,
691 (int) player_globals.parray[p1].b_stats.dra);
692 strcat(playerLine, tmp);
694 if (player_idle(p1) >= 60) {
695 sprintf(tmp, "%5s\n", hms(player_idle(p1), 0, 0, 0));
699 strcat(playerLine, tmp);
701 pprintf(p, "%s", playerLine);
703 pprintf(p, " %3d Players Displayed.\n", num);
706 static int who_ok(int p, unsigned int sel_bits)
708 struct player *pp = &player_globals.parray[p];
710 if (pp->status != PLAYER_PROMPT)
712 if (sel_bits == WHO_ALL)
714 if (sel_bits & WHO_OPEN)
715 if (!CheckPFlag(p, PFLAG_OPEN) || CheckPFlag(p, PFLAG_TOURNEY))
717 if (sel_bits & WHO_CLOSED)
718 if (CheckPFlag(p, PFLAG_OPEN))
720 if (sel_bits & WHO_RATED)
721 if (!CheckPFlag(p, PFLAG_RATED))
723 if (sel_bits & WHO_UNRATED)
724 if (CheckPFlag(p, PFLAG_RATED))
726 if (sel_bits & WHO_FREE)
729 if (sel_bits & WHO_PLAYING)
732 if (sel_bits & WHO_REGISTERED)
733 if (!CheckPFlag(p, PFLAG_REG))
735 if (sel_bits & WHO_UNREGISTERED)
736 if (CheckPFlag(p, PFLAG_REG))
738 if (sel_bits & WHO_BUGTEAM) {
740 if (p2 < 0 || player_globals.parray[p2].partner != p)
747 static int blitz_cmp(const void *pp1, const void *pp2)
749 register int p1 = *(int *) pp1;
750 register int p2 = *(int *) pp2;
751 if (player_globals.parray[p1].status != PLAYER_PROMPT) {
752 if (player_globals.parray[p2].status != PLAYER_PROMPT)
757 if (player_globals.parray[p2].status != PLAYER_PROMPT)
759 if (player_globals.parray[p1].b_stats.rating > player_globals.parray[p2].b_stats.rating)
761 if (player_globals.parray[p1].b_stats.rating < player_globals.parray[p2].b_stats.rating)
763 if (CheckPFlag(p1, PFLAG_REG) && !CheckPFlag(p2, PFLAG_REG))
765 if (!CheckPFlag(p1, PFLAG_REG) && CheckPFlag(p2, PFLAG_REG))
767 return strcmp(player_globals.parray[p1].login, player_globals.parray[p2].login);
770 static int light_cmp(const void *pp1, const void *pp2)
772 register int p1 = *(int *) pp1;
773 register int p2 = *(int *) pp2;
774 if (player_globals.parray[p1].status != PLAYER_PROMPT) {
775 if (player_globals.parray[p2].status != PLAYER_PROMPT)
780 if (player_globals.parray[p2].status != PLAYER_PROMPT)
782 if (player_globals.parray[p1].l_stats.rating > player_globals.parray[p2].l_stats.rating)
784 if (player_globals.parray[p1].l_stats.rating < player_globals.parray[p2].l_stats.rating)
786 if (CheckPFlag(p1, PFLAG_REG) && !CheckPFlag(p2, PFLAG_REG))
788 if (!CheckPFlag(p1, PFLAG_REG) && CheckPFlag(p2, PFLAG_REG))
790 return strcmp(player_globals.parray[p1].login, player_globals.parray[p2].login);
793 static int bug_cmp(const void *pp1, const void *pp2)
795 register int p1 = *(int *) pp1;
796 register int p2 = *(int *) pp2;
797 if (player_globals.parray[p1].status != PLAYER_PROMPT) {
798 if (player_globals.parray[p2].status != PLAYER_PROMPT)
803 if (player_globals.parray[p2].status != PLAYER_PROMPT)
805 if (player_globals.parray[p1].bug_stats.rating > player_globals.parray[p2].bug_stats.rating)
807 if (player_globals.parray[p1].bug_stats.rating < player_globals.parray[p2].bug_stats.rating)
809 if (CheckPFlag(p1, PFLAG_REG) && !CheckPFlag(p2, PFLAG_REG))
811 if (!CheckPFlag(p1, PFLAG_REG) && CheckPFlag(p2, PFLAG_REG))
813 return strcmp(player_globals.parray[p1].login, player_globals.parray[p2].login);
816 static int stand_cmp(const void *pp1, const void *pp2)
818 register int p1 = *(int *) pp1;
819 register int p2 = *(int *) pp2;
820 if (player_globals.parray[p1].status != PLAYER_PROMPT) {
821 if (player_globals.parray[p2].status != PLAYER_PROMPT)
826 if (player_globals.parray[p2].status != PLAYER_PROMPT)
828 if (player_globals.parray[p1].s_stats.rating > player_globals.parray[p2].s_stats.rating)
830 if (player_globals.parray[p1].s_stats.rating < player_globals.parray[p2].s_stats.rating)
832 if (CheckPFlag(p1, PFLAG_REG) && !CheckPFlag(p2, PFLAG_REG))
834 if (!CheckPFlag(p1, PFLAG_REG) && CheckPFlag(p2, PFLAG_REG))
836 return strcmp(player_globals.parray[p1].login, player_globals.parray[p2].login);
839 static int wild_cmp(const void *pp1, const void *pp2)
841 register int p1 = *(int *) pp1;
842 register int p2 = *(int *) pp2;
843 if (player_globals.parray[p1].status != PLAYER_PROMPT) {
844 if (player_globals.parray[p2].status != PLAYER_PROMPT)
849 if (player_globals.parray[p2].status != PLAYER_PROMPT)
851 if (player_globals.parray[p1].w_stats.rating > player_globals.parray[p2].w_stats.rating)
853 if (player_globals.parray[p1].w_stats.rating < player_globals.parray[p2].w_stats.rating)
855 if (CheckPFlag(p1, PFLAG_REG) && !CheckPFlag(p2, PFLAG_REG))
857 if (!CheckPFlag(p1, PFLAG_REG) && CheckPFlag(p2, PFLAG_REG))
859 return strcmp(player_globals.parray[p1].login, player_globals.parray[p2].login);
862 static int alpha_cmp(const void *pp1, const void *pp2)
864 register int p1 = *(int *) pp1;
865 register int p2 = *(int *) pp2;
866 if (player_globals.parray[p1].status != PLAYER_PROMPT) {
867 if (player_globals.parray[p2].status != PLAYER_PROMPT)
872 if (player_globals.parray[p2].status != PLAYER_PROMPT)
874 return strcmp(player_globals.parray[p1].login, player_globals.parray[p2].login);
877 static void sort_players(int *players,
878 int ((*cmp_func) (const void *, const void *)))
882 for (i = 0; i < player_globals.p_num; i++) {
885 qsort(players, player_globals.p_num, sizeof(int), cmp_func);
888 /* This is the of the most compliclicated commands in terms of parameters */
889 int com_who(int p, param_list param)
891 struct player *pp = &player_globals.parray[p];
893 float stop_perc = 1.0;
894 float start_perc = 0;
895 unsigned int sel_bits = WHO_ALL;
896 int *sortlist, *plist;
897 int ((*cmp_func) (const void *, const void *));
903 int p1, count, num_who;
907 sortlist = malloc(sizeof(int) * player_globals.p_num);
908 plist = malloc(sizeof(int) * player_globals.p_num);
910 total = pp->d_time * 60 + pp->d_inc * 40;
912 sort_type = light_rat;
913 cmp_func = light_cmp;
914 } else if (total >= 900) {
916 cmp_func = stand_cmp;
918 sort_type = blitz_rat;
919 cmp_func = blitz_cmp;
922 if (param[0].type != TYPE_NULL) {
923 len = strlen(param[0].val.string);
924 for (i = 0; i < len; i++) {
925 c = param[0].val.string[i];
927 if (i == 0 || !isdigit(param[0].val.string[i - 1])) {
931 stop_perc = 0.333333;
932 } else if (tmpI == 2) {
933 start_perc = 0.333333;
934 stop_perc = 0.6666667;
935 } else if (tmpI == 3) {
936 start_perc = 0.6666667;
938 } else if ((i == len - 1) || (!isdigit(param[0].val.string[i + 1])))
942 tmpJ = param[0].val.string[i - 1] - '0';
947 start_perc = ((float) tmpJ - 1.0) / (float) tmpI;
948 stop_perc = ((float) tmpJ) / (float) tmpI;
957 if (sel_bits == WHO_ALL)
960 sel_bits |= WHO_OPEN;
963 if (sel_bits == WHO_ALL)
964 sel_bits = WHO_RATED;
966 sel_bits |= WHO_RATED;
969 if (sel_bits == WHO_ALL)
972 sel_bits |= WHO_FREE;
975 if (sel_bits == WHO_ALL)
976 sel_bits = WHO_FREE | WHO_OPEN;
978 sel_bits |= (WHO_FREE | WHO_OPEN);
981 if (sel_bits == WHO_ALL)
982 sel_bits = WHO_REGISTERED;
984 sel_bits |= WHO_REGISTERED;
986 case 'l': /* Sort order */
987 cmp_func = alpha_cmp;
990 case 'A': /* Sort order */
991 cmp_func = alpha_cmp;
993 case 'w': /* Sort order */
995 sort_type = wild_rat;
997 case 's': /* Sort order */
998 cmp_func = stand_cmp;
1001 case 'b': /* Sort order */
1002 cmp_func = blitz_cmp;
1003 sort_type = blitz_rat;
1005 case 'L': /* Sort order */
1006 cmp_func = light_cmp;
1007 sort_type = light_rat;
1009 case 't': /* format */
1012 case 'v': /* format */
1015 case 'n': /* format */
1019 if (sel_bits == WHO_ALL)
1020 sel_bits = WHO_UNREGISTERED;
1022 sel_bits |= WHO_UNREGISTERED;
1025 if (sel_bits == WHO_ALL)
1026 sel_bits = WHO_BUGTEAM;
1028 sel_bits |= WHO_BUGTEAM;
1030 sort_type = bug_rat;
1033 goto bad_parameters;
1038 sort_players(sortlist, cmp_func);
1040 for (p1 = 0; p1 < player_globals.p_num; p1++) {
1041 if (!who_ok(sortlist[p1], sel_bits))
1045 startpoint = floor((float) count * start_perc);
1046 stoppoint = ceil((float) count * stop_perc) - 1;
1049 for (p1 = 0; p1 < player_globals.p_num; p1++) {
1050 if (!who_ok(sortlist[p1], sel_bits))
1052 if ((count >= startpoint) && (count <= stoppoint)) {
1053 plist[num_who++] = sortlist[p1];
1059 pprintf(p, "No logged in players match the flags in your who request.\n");
1065 who_terse(p, num_who, plist, sort_type);
1067 case 1: /* verbose */
1068 who_verbose(p, num_who, plist);
1070 case 2: /* win-loss */
1071 who_winloss(p, num_who, plist);
1074 goto bad_parameters;
1080 return COM_BADPARAMETERS;
1083 int com_open(int p, param_list param)
1086 if ((retval = pcommand(p, "set open")) != COM_OK)
1089 return COM_OK_NOPROMPT;
1092 int com_simopen(int p, param_list param)
1095 if ((retval = pcommand(p, "set simopen")) != COM_OK)
1098 return COM_OK_NOPROMPT;
1101 int com_bell(int p, param_list param)
1104 if ((retval = pcommand(p, "set bell")) != COM_OK)
1107 return COM_OK_NOPROMPT;
1110 int com_flip(int p, param_list param)
1113 if ((retval = pcommand(p, "set flip")) != COM_OK)
1116 return COM_OK_NOPROMPT;
1119 int com_style(int p, param_list param)
1122 if ((retval = pcommand(p, "set style %d", param[0].val.integer)) != COM_OK)
1125 return COM_OK_NOPROMPT;
1128 int com_promote(int p, param_list param)
1131 if ((retval = pcommand(p, "set promote %s", param[0].val.word)) != COM_OK)
1134 return COM_OK_NOPROMPT;
1137 void alias_add(int p, const char *name, const char *value)
1139 struct player *pp = &player_globals.parray[p];
1141 pp->alias_list = (struct alias_type *)realloc(pp->alias_list,
1142 sizeof(struct alias_type) * (pp->numAlias+1));
1143 pp->alias_list[pp->numAlias].comm_name = strdup(name);
1144 pp->alias_list[pp->numAlias].alias = strdup(value);
1149 int com_alias(int p, param_list param)
1151 struct player *pp = &player_globals.parray[p];
1153 const char *noalias[] = {"quit", "unalias", NULL};
1155 if (param[0].type == TYPE_NULL) {
1156 for (al = 0; al < pp->numAlias; al++) {
1157 pprintf(p, "%s -> %s\n",
1158 pp->alias_list[al].comm_name,
1159 pp->alias_list[al].alias);
1164 al = alias_lookup(param[0].val.word, pp->alias_list, pp->numAlias);
1165 if (param[1].type == TYPE_NULL) {
1167 pprintf(p, "You have no alias named '%s'.\n", param[0].val.word);
1169 pprintf(p, "%s -> %s\n",
1170 pp->alias_list[al].comm_name,
1171 pp->alias_list[al].alias);
1177 FREE(pp->alias_list[al].alias);
1178 pp->alias_list[al].alias = strdup(param[1].val.string);
1179 pprintf(p, "Alias %s replaced.\n", param[0].val.string);
1183 if (pp->numAlias >= config_get_int("MAX_ALIASES", DEFAULT_MAX_ALIASES)) {
1184 pprintf(p, "You have your maximum number of aliases.\n");
1188 for (i=0;noalias[i];i++) {
1189 if (strcasecmp(param[0].val.string, noalias[i]) == 0) {
1190 pprintf(p, "Sorry, you can't alias this command.\n");
1195 alias_add(p, param[0].val.word, param[1].val.string);
1197 pprintf(p, "Alias set.\n");
1202 int com_unalias(int p, param_list param)
1204 struct player *pp = &player_globals.parray[p];
1208 al = alias_lookup(param[0].val.word, pp->alias_list, pp->numAlias);
1210 pprintf(p, "You have no alias named '%s'.\n", param[0].val.word);
1214 FREE(pp->alias_list[al].comm_name);
1215 FREE(pp->alias_list[al].alias);
1216 for (i = al; i < pp->numAlias-1; i++) {
1217 pp->alias_list[i].comm_name = pp->alias_list[i+1].comm_name;
1218 pp->alias_list[i].alias = pp->alias_list[i+1].alias;
1221 pp->alias_list = (struct alias_type *)realloc(pp->alias_list,
1222 sizeof(struct alias_type) * pp->numAlias);
1223 pprintf(p,"Alias removed.\n");
1229 int com_handles(int p, param_list param)
1232 char pdir[MAX_FILENAME_SIZE];
1235 sprintf(pdir, "%s/%c", PLAYER_DIR, param[0].val.word[0]);
1236 count = search_directory(pdir, param[0].val.word, buffer, 1000);
1237 pprintf(p, "Found %d names.\n", count);
1239 display_directory(p, buffer, count);
1243 int com_getgi(int p, param_list param)
1246 struct player *pp = &player_globals.parray[p];
1248 if (!in_list(p, L_TD, pp->name)) {
1249 pprintf(p, "Only TD programs are allowed to use this command.\n");
1252 if (((p1 = player_find_bylogin(param[0].val.word)) < 0)
1253 || (!CheckPFlag(p1, PFLAG_REG))) {
1254 /* Darkside suggested not to return anything */
1257 if (!CheckPFlag(p1, PFLAG_REG)) {
1258 pprintf(p, "*getgi %s none none -1 -1 -1 -1 -1*\n", player_globals.parray[p1].name);
1259 } else if (player_globals.parray[p1].game >= 0) {
1260 g = player_globals.parray[p1].game;
1261 if (game_globals.garray[g].status == GAME_ACTIVE) {
1262 pprintf(p, "*getgi %s %s %s %d %d %d %d %d*\n",
1263 player_globals.parray[p1].name,
1264 game_globals.garray[g].white_name,
1265 game_globals.garray[g].black_name,
1267 game_globals.garray[g].wInitTime,
1268 game_globals.garray[g].wIncrement,
1269 game_globals.garray[g].rated,
1270 game_globals.garray[g].private);
1272 pprintf(p, "%s is not playing a game.\n", player_globals.parray[p1].name);
1275 pprintf(p, "%s is not playing a game.\n", player_globals.parray[p1].name);
1280 int com_getpi(int p, param_list param)
1282 struct player *pp = &player_globals.parray[p];
1285 if (!in_list(p, L_TD, pp->name)) {
1286 pprintf(p, "Only TD programs are allowed to use this command.\n");
1289 if (((p1 = player_find_bylogin(param[0].val.word)) < 0)
1290 || (!CheckPFlag(p1, PFLAG_REG))) {
1291 /* Darkside suggested not to return anything */
1294 if (!CheckPFlag(p1, PFLAG_REG)) {
1295 pprintf(p, "*getpi %s -1 -1 -1*\n", player_globals.parray[p1].name);
1297 pprintf(p, "*getpi %s %d %d %d %d*\n", player_globals.parray[p1].name,
1298 player_globals.parray[p1].w_stats.rating,
1299 player_globals.parray[p1].b_stats.rating,
1300 player_globals.parray[p1].s_stats.rating,
1301 player_globals.parray[p1].l_stats.rating);
1306 int com_limits(int p, param_list param)
1308 struct player *pp = &player_globals.parray[p];
1310 pprintf(p, "\nCurrent hardcoded limits:\n");
1311 pprintf(p, " Max number of channels and max capacity: %d\n", MAX_CHANNELS);
1312 pprintf(p, " Max number of channels one can be in: %d\n", MAX_INCHANNELS);
1313 pprintf(p, " Max number of people on the notify list: %d\n", MAX_NOTIFY);
1314 pprintf(p, " Max number of people on the censor list: %d\n", MAX_CENSOR);
1315 pprintf(p, " Max number of people in a simul game: %d\n", MAX_SIMUL);
1316 pprintf(p, " Max number of messages one can receive: %d\n", MAX_MESSAGES);
1317 pprintf(p, " Min number of games to be active: %d\n", PROVISIONAL);
1318 if (!check_admin(p, ADMIN_ADMIN) &&
1319 !titled_player(p,pp->login)) {
1320 pprintf(p, " Size of journal (entries): %d\n", MAX_JOURNAL);
1322 pprintf(p, " Size of journal (entries): 26\n");
1324 pprintf(p, "\nAdmin settable limits:\n");
1325 pprintf(p, " Shout quota gives two shouts per %d seconds.\n", seek_globals.quota_time);
1330 int com_remote(int p, param_list param)
1334 if ((p1 = player_find_part_login(param[0].val.word)) < 0) {
1335 pprintf(p, "%s is not logged in.\n", param[0].val.word);
1338 if (!in_list(p1, L_REMOTE, player_globals.parray[p].login)) {
1339 pprintf(p, "You are not in the remote list for %s\n",
1340 player_globals.parray[p1].login);
1343 pprintf(p, "Command issued as %s\n", player_globals.parray[p1].name);
1344 pprintf(p1, "Remote command [%s] issued by %s\n",
1345 param[1].val.string, player_globals.parray[p].name);
1346 pcommand(p1, "%s\n", param[1].val.string);