From 79b59f9b30fb6a1fdf8c3efb446271f7cb00d434 Mon Sep 17 00:00:00 2001 From: Markus Uhlin Date: Thu, 7 Dec 2023 21:31:49 +0100 Subject: FICS 1.6.2 --- FICS/comproc.c | 1638 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1638 insertions(+) create mode 100644 FICS/comproc.c (limited to 'FICS/comproc.c') diff --git a/FICS/comproc.c b/FICS/comproc.c new file mode 100644 index 0000000..b2d251c --- /dev/null +++ b/FICS/comproc.c @@ -0,0 +1,1638 @@ +/* comproc.c + * + */ + +/* + fics - An internet chess server. + Copyright (C) 1993 Richard V. Nash + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +*/ + +/* Revision history: + name email yy/mm/dd Change + Richard Nash 93/10/22 Created + foxbat 95/03/11 added filters in cmatch. +*/ + +#include "stdinclude.h" + +#include "common.h" +#include "talkproc.h" +#include "comproc.h" +#include "command.h" +#include "utils.h" +#include "ficsmain.h" +#include "config.h" +#include "playerdb.h" +#include "network.h" +#include "rmalloc.h" +#include "variable.h" +#include "gamedb.h" +#include "gameproc.h" +#include "obsproc.h" +#include "board.h" +/* #include "hostinfo.h" */ +#include "multicol.h" +#include "ratings.h" +#include "formula.h" +#include "lists.h" +#include "eco.h" +#include "network.h" +#include + +#include + +/* grimm */ +#if defined(SGI) +#else +/* int system(char *arg); */ +#endif + +const none = 0; +const blitz_rat = 1; +const std_rat = 2; +const wild_rat = 3; +const light_rat = 4; + + +PUBLIC int com_rating_recalc(int p, param_list param) +{ + ASSERT(parray[p].adminLevel >= ADMIN_ADMIN); + rating_recalc(); + return COM_OK; +} + +PUBLIC int com_more(int p, param_list param) +{ + pmore_file(p); + return COM_OK; +} + +PUBLIC int num_news = -1; + +PUBLIC void rscan_news2(FILE *fp, int p, int num) +{ + char junk[MAX_LINE_SIZE], count[10]; + int crtime; + char *junkp; + + if (num == 0) + return; + + fgets(junk, MAX_LINE_SIZE, fp); + if (feof(fp)) + return; + sscanf(junk, "%d %s", &crtime, count); + rscan_news2(fp, p, num - 1); + junkp = junk; + junkp = nextword(junkp); + junkp = nextword(junkp); + pprintf(p, "%3s (%s) %s", count, fix_time(strltime(&crtime)), junkp); +} + +PUBLIC int com_news(int p, param_list param) +{ + FILE *fp; + char filename[MAX_FILENAME_SIZE]; + char junk[MAX_LINE_SIZE]; + char *junkp; + int crtime, found = 0; + char count[10]; + + sprintf(filename, "%s/newnews.index", news_dir); + fp = fopen(filename, "r"); + + if (!fp) { + fprintf(stderr, "Can\'t find news index.\n"); + return COM_OK; + } + + if (param[0].type == 0) { + + /* no params - then just display index of last ten news items */ + + pprintf(p,"Index of recent news items:\n"); + fgets(junk, MAX_LINE_SIZE, fp); + sscanf(junk, "%d %s", &crtime, count); + rscan_news2(fp, p, 9); + junkp = junk; + junkp = nextword(junkp); + junkp = nextword(junkp); + pprintf(p, "%3s (%s) %s", count, fix_time(strltime(&crtime)), junkp); + fclose(fp); + + } else if ((param[0].type == TYPE_WORD) && !strcmp(param[0].val.word,"all")) { + + /* param all - displays index all news items */ + + pprintf(p, "Index of all news items:\n"); + fgets(junk, MAX_LINE_SIZE, fp); + sscanf(junk, "%d %s", &crtime, count); + rscan_news(fp, p, 0); + junkp = junk; + junkp = nextword(junkp); + junkp = nextword(junkp); + pprintf(p, "%3s (%s) %s", count, fix_time(strltime(&crtime)), junkp); + fclose(fp); + + } else { + + /* check if the specific news file exist in index */ + + while (!feof(fp) && !found) { + junkp = junk; + fgets(junk, MAX_LINE_SIZE, fp); + if (feof(fp)) + break; + sscanf(junkp, "%d %s", &crtime, count); + if (!strcmp(count, param[0].val.word)) { + found = 1; + junkp = nextword(junkp); + junkp = nextword(junkp); + pprintf(p, "NEWS %3s (%s) %s\n", count, fix_time(strltime(&crtime)), + junkp); + } + } + + fclose(fp); + + if (!found) { + pprintf(p, "Bad index number!\n"); + return COM_OK; + } + + /* file exists - show it */ + sprintf(filename, "%s/news.%s", news_dir, param[0].val.word); + fp = fopen(filename, "r"); + if (!fp) { + pprintf(p, "No more info.\n"); + return COM_OK; + } + + fclose(fp); + + sprintf(filename, "news.%s", param[0].val.word); + if (psend_file(p, news_dir, filename) < 0) { + pprintf(p, "Internal error - couldn't send news file!\n"); + } + } + + return COM_OK; +} + +PUBLIC int com_quit(int p, param_list param) +{ + if ((parray[p].game >= 0) && (garray[parray[p].game].status == GAME_EXAMINE)) { + pcommand(p, "unexamine"); + } + + if (parray[p].game >= 0) { + 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"); + return COM_OK; + } + psend_logoutfile(p, mess_dir, MESS_LOGOUT); + return COM_LOGOUT; +} + +PUBLIC int com_set(int p, param_list param) +{ + int result; + int which; + char *val; + + if (param[1].type == TYPE_NULL) + val = NULL; + else + val = param[1].val.string; + result = var_set(p, param[0].val.word, val, &which); + switch (result) { + case VAR_OK: + break; + case VAR_BADVAL: + pprintf(p, "Bad value given for variable %s.\n", param[0].val.word); + break; + case VAR_NOSUCH: + pprintf(p, "No such variable name %s.\n", param[0].val.word); + break; + case VAR_AMBIGUOUS: + pprintf(p, "Ambiguous variable name %s.\n", param[0].val.word); + break; + } + /* player_save(p); */ + return COM_OK; +} + +PUBLIC int FindPlayer(int p, char* name, int *p1, int *connected) +{ + *p1 = player_search(p, name); + if (*p1 == 0) + return 0; + if (*p1 < 0) { /* player had to be connected and will be + removed later */ + *connected = 0; + *p1 = (-*p1) - 1; + } else { + *connected = 1; + *p1 = *p1 - 1; + } + return 1; +} + +PRIVATE void com_stats_andify(int *numbers, int howmany, char *dest) +{ + char tmp[10]; + + *dest = '\0'; + while (howmany--) { + sprintf(tmp, "%d", numbers[howmany]); + strcat(dest, tmp); + if (howmany > 1) + sprintf(tmp, ", "); + else if (howmany == 1) + sprintf(tmp, " and "); + else + sprintf(tmp, ".\n"); + strcat(dest, tmp); + } + return; +} + +PRIVATE void com_stats_rating(char *hdr, statistics * stats, char *dest) +{ + char tmp[100]; + + sprintf(dest, "%-10s%4s %5.1f %4d %4d %4d %4d", + hdr, ratstr(stats->rating), stats->sterr, stats->win, stats->los, stats->dra, stats->num); + if (stats->whenbest) { + sprintf(tmp, " %d", stats->best); + strcat(dest, tmp); + strftime(tmp, sizeof(tmp), " (%d-%b-%y)", localtime((time_t *) & stats->whenbest)); + strcat(dest, tmp); + } + strcat(dest, "\n"); + return; +} + +PUBLIC int com_stats(int p, param_list param) +{ + int g, i, t; + int p1, connected; + char line[255], tmp[255]; + int numbers[MAX_OBSERVE > MAX_SIMUL ? MAX_OBSERVE : MAX_SIMUL]; + int onTime; + + if (param[0].type == TYPE_WORD) { + if (!FindPlayer(p, param[0].val.word, &p1, &connected)) + return COM_OK; + } else { + p1 = p; + connected = 1; + } + + sprintf(line, "\nStatistics for %-11s ", parray[p1].name); + if ((connected) && (parray[p1].status == PLAYER_PROMPT)) { + sprintf(tmp, "On for: %s", hms_desc(player_ontime(p1))); + strcat(line, tmp); + sprintf(tmp, " Idle: %s\n", hms_desc(player_idle(p1))); + } else { + if ((t = player_lastdisconnect(p1))) + sprintf(tmp, "(Last disconnected %s):\n", strltime(&t)); + else + sprintf(tmp, "(Never connected.)\n"); + } + strcat(line, tmp); + pprintf(p, "%s", line); + if (parray[p1].simul_info.numBoards) { + for (i = 0, t = 0; i < parray[p1].simul_info.numBoards; i++) { + if ((numbers[t] = parray[p1].simul_info.boards[i] + 1) != 0) + t++; + } + pprintf(p, "%s is giving a simul: game%s ", parray[p1].name, ((t > 1) ? "s" : "")); + com_stats_andify(numbers, t, tmp); + pprintf(p, tmp); + } else if (parray[p1].game >= 0) { + g = parray[p1].game; + if (garray[g].status == GAME_EXAMINE) { + pprintf(p, "(Examining game %d: %s vs. %s)\n", g + 1, + garray[g].white_name, garray[g].black_name); + } else { + pprintf(p, "(playing game %d: %s vs. %s)\n", g + 1, + parray[garray[g].white].name, parray[garray[g].black].name); + if (garray[g].link >= 0) { + pprintf(p, "(partner is playing game %d: %s vs. %s)\n", garray[g].link + 1, + parray[garray[garray[g].link].white].name, + parray[garray[garray[g].link].black].name); + } + } + } + if (parray[p1].num_observe) { + for (i = 0, t = 0; i < parray[p1].num_observe; i++) { + g = parray[p1].observe_list[i]; + if ((g != -1) && ((parray[p].adminLevel >= ADMIN_ADMIN) || (garray[g].private == 0))) + numbers[t++] = g + 1; + } + if (t) { + pprintf(p, "%s is observing game%s ", parray[p1].name, ((t > 1) ? "s" : "")); + com_stats_andify(numbers, t, tmp); + pprintf(p, tmp); + } + } + if (parray[p1].busy[0]) { + pprintf(p, "(%s %s)\n", parray[p1].name, parray[p1].busy); + } + if (!parray[p1].registered) { + pprintf(p, "%s is NOT a registered player.\n\n", parray[p1].name); + } else { + pprintf(p, "\n rating RD win loss draw total best\n"); + com_stats_rating("Blitz", &parray[p1].b_stats, tmp); + pprintf(p, tmp); + com_stats_rating("Standard", &parray[p1].s_stats, tmp); + pprintf(p, tmp); + com_stats_rating("Lightning", &parray[p1].l_stats, tmp); + pprintf(p, tmp); + com_stats_rating("Wild", &parray[p1].w_stats, tmp); + pprintf(p, tmp); + } + pprintf(p, "\n"); + if (parray[p1].adminLevel > 0) { + pprintf(p, "Admin Level: "); + switch (parray[p1].adminLevel) { + case 5: + pprintf(p, "Authorized Helper Person\n"); + break; + case 10: + pprintf(p, "Administrator\n"); + break; + case 15: + pprintf(p, "Help File Librarian/Administrator\n"); + break; + case 20: + pprintf(p, "Master Administrator\n"); + break; + case 50: + pprintf(p, "Master Help File Librarian/Administrator\n"); + break; + case 60: + pprintf(p, "Assistant Super User\n"); + break; + case 100: + pprintf(p, "Super User\n"); + break; + default: + pprintf(p, "%d\n", parray[p1].adminLevel); + break; + } + } + if (parray[p].adminLevel > 0) + pprintf(p, "Full Name : %s\n", (parray[p1].fullName ? parray[p1].fullName : "(none)")); + if (((p1 == p) && (parray[p1].registered)) || (parray[p].adminLevel > 0)) + pprintf(p, "Address : %s\n", (parray[p1].emailAddress ? parray[p1].emailAddress : "(none)")); + if (parray[p].adminLevel > 0) { + pprintf(p, "Host : %s\n", + dotQuad(connected ? parray[p1].thisHost : parray[p1].lastHost)); + } + if ((parray[p].adminLevel > 0) && (parray[p1].registered)) + if (parray[p1].num_comments) + pprintf(p, "Comments : %d\n", parray[p1].num_comments); + + if (connected && parray[p1].registered && (p==p1 || + (parray[p].adminLevel > 0))) { + char *timeToStr = ctime((time_t *) &parray[p1].timeOfReg); + + timeToStr[strlen(timeToStr)-1]='\0'; + pprintf(p, "\n"); + onTime = (time(0) - parray[p1].logon_time) + parray[p1].totalTime; + + pprintf(p, "Total time on-line: %s\n", hms_desc(onTime) ); + pprintf(p, "%% of life on-line: %3.1f (since %s)\n", + (double)((onTime*100)/(double)(time(0)-parray[p1].timeOfReg)), + timeToStr); + } + +#ifdef TIMESEAL + if (connected) + pprintf(p, "\nTimeseal : %s\n", + (con[parray[p1].socket].timeseal) ? "On" : "Off"); + if ((parray[p].adminLevel > 0) && (connected)) { + if (findConnection(parray[p1].socket) && con[parray[p1].socket].timeseal) { + pprintf(p, "Unix acc : %s\nSystem/OS : %s\n", + con[parray[p1].socket].user, + con[parray[p1].socket].sys); + } + } +#endif + + if (parray[p1].num_plan) { + pprintf(p, "\n"); + for (i = 0; i < parray[p1].num_plan; i++) + pprintf(p, "%2d: %s\n", i + 1, (parray[p1].planLines[i] != NULL) ? parray[p1].planLines[i] : ""); + } + if (!connected) + player_remove(p1); + return COM_OK; +} + +PUBLIC int com_password(int p, param_list param) +{ + char *oldpassword = param[0].val.word; + char *newpassword = param[1].val.word; + char salt[3]; + + if (!parray[p].registered) { + pprintf(p, "Setting a password is only for registered players.\n"); + return COM_OK; + } + if (parray[p].passwd) { + salt[0] = parray[p].passwd[0]; + salt[1] = parray[p].passwd[1]; + salt[2] = '\0'; + if (strcmp(crypt(oldpassword, salt), parray[p].passwd)) { + pprintf(p, "Incorrect password, password not changed!\n"); + return COM_OK; + } + rfree(parray[p].passwd); + parray[p].passwd = NULL; + } + salt[0] = 'a' + rand() % 26; + salt[1] = 'a' + rand() % 26; + salt[2] = '\0'; + parray[p].passwd = strdup(crypt(newpassword, salt)); + pprintf(p, "Password changed to \"%s\".\n", newpassword); + return COM_OK; +} + +PUBLIC int com_uptime(int p, param_list param) +{ + unsigned long uptime = time(0) - startuptime; + struct rusage ru; + int days = (uptime / (60*60*24)); + int hours = ((uptime % (60*60*24)) / (60*60)); + int mins = (((uptime % (60*60*24)) % (60*60)) / 60); + int secs = (((uptime % (60*60*24)) % (60*60)) % 60); + + pprintf(p, "Server location: %s Server version : %s\n", fics_hostname,VERS_NUM); + pprintf(p, "The server has been up since %s.\n", strltime(&startuptime)); + if ((days==0) && (hours==0) && (mins==0)) { + pprintf(p, "(Up for %d second%s)\n", + secs, (secs==1) ? "" : "s"); + } else if ((days==0) && (hours==0)) { + pprintf(p, "(Up for %d minute%s and %d second%s)\n", + mins, (mins==1) ? "" : "s", + secs, (secs==1) ? "" : "s"); + } else if (days==0) { + pprintf(p, "(Up for %d hour%s, %d minute%s and %d second%s)\n", + hours, (hours==1) ? "" : "s", + mins, (mins==1) ? "" : "s", + secs, (secs==1) ? "" : "s"); + } else { + pprintf(p, "(Up for %d day%s, %d hour%s, %d minute%s and %d second%s)\n", + days, (days==1) ? "" : "s", + hours, (hours==1) ? "" : "s", + mins, (mins==1) ? "" : "s", + secs, (secs==1) ? "" : "s"); + } + pprintf(p, "\nAllocs: %u Frees: %u Allocs In Use: %u\n", + malloc_count, free_count, malloc_count - free_count); + if (parray[p].adminLevel >= ADMIN_ADMIN) { + pprintf(p, "\nplayer size:%d, game size:%d, con size:%d, g_num:%d\n", + sizeof(player), sizeof(game), net_consize(), g_num); + getrusage(RUSAGE_SELF, &ru); + pprintf(p, "pagesize = %d, maxrss = %d, total = %d\n", getpagesize(), ru.ru_maxrss, getpagesize() * ru.ru_maxrss); + } + pprintf(p, "\nPlayer limit: %d\n", max_connections-10); + pprintf(p, "\nThere are currently %d players, with a high of %d since last restart.\n", player_count(1), player_high); + pprintf(p, "There are currently %d games, with a high of %d since last restart.\n", game_count(), game_high); + pprintf(p, "\nCompiled on %s\n", COMP_DATE); + return COM_OK; +} + +PUBLIC int com_date(int p, param_list param) +{ + int t = time(0); + pprintf(p, "Local time - %s\n", strltime(&t)); + pprintf(p, "Greenwich time - %s\n", strgtime(&t)); + return COM_OK; +} + +char *inout_string[] = { + "login", "logout" +}; + +PRIVATE int plogins(p, fname) +int p; +char *fname; +{ + FILE *fp; + int inout, thetime, registered; + char loginName[MAX_LOGIN_NAME + 1]; + char ipstr[20]; + + fp = fopen(fname, "r"); + if (!fp) { + pprintf(p, "Sorry, no login information available.\n"); + return COM_OK; + } + while (!feof(fp)) { + if (fscanf(fp, "%d %s %d %d %s\n", &inout, loginName, &thetime, + ®istered, ipstr) != 5) { + fprintf(stderr, "FICS: Error in login info format. %s\n", fname); + fclose(fp); + return COM_OK; + } + pprintf(p, "%s: %-17s %-6s", strltime(&thetime), loginName, + inout_string[inout]); + if (parray[p].adminLevel > 0) { + pprintf(p, " from %s\n", ipstr); + } else + pprintf(p, "\n"); + } + fclose(fp); + return COM_OK; +} + +PUBLIC int com_llogons(int p, param_list param) +{ + char fname[MAX_FILENAME_SIZE]; + + sprintf(fname, "%s/%s", stats_dir, STATS_LOGONS); + return plogins(p, fname); +} + +PUBLIC int com_logons(int p, param_list param) +{ + char fname[MAX_FILENAME_SIZE]; + + if (param[0].type == TYPE_WORD) { + sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir, param[0].val.word[0], param[0].val.word, STATS_LOGONS); + } else { + sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir, parray[p].login[0], parray[p].login, STATS_LOGONS); + } + return plogins(p, fname); +} + +#define WHO_OPEN 0x01 +#define WHO_CLOSED 0x02 +#define WHO_RATED 0x04 +#define WHO_UNRATED 0x08 +#define WHO_FREE 0x10 +#define WHO_PLAYING 0x20 +#define WHO_REGISTERED 0x40 +#define WHO_UNREGISTERED 0x80 +#define WHO_BUGTEAM 0x100 + +#define WHO_ALL 0xff + +void AddPlayerLists (int p1, char *ptmp) +{ + if ((parray[p1].adminLevel >= 10) && (parray[p1].i_admin)) + strcat(ptmp, "(*)"); + if (in_list(p1, L_COMPUTER, parray[p1].name)) + strcat(ptmp, "(C)"); + if (in_list(p1, L_FM, parray[p1].name)) + strcat(ptmp, "(FM)"); + if (in_list(p1, L_IM, parray[p1].name)) + strcat(ptmp, "(IM)"); + if (in_list(p1, L_GM, parray[p1].name)) + strcat(ptmp, "(GM)"); + if (in_list(p1, L_TD, parray[p1].name)) + strcat(ptmp, "(TD)"); + if (in_list(p1, L_TEAMS, parray[p1].name)) + strcat(ptmp, "(T)"); + if (in_list(p1, L_BLIND, parray[p1].name)) + strcat(ptmp, "(B)"); +} + +PRIVATE void who_terse(int p, int num, int *plist, int type) +{ + char ptmp[80 + 20]; /* for highlight */ + multicol *m = multicol_start(PARRAY_SIZE); + int i; + int p1; + int rat; + + /* altered DAV 3/15/95 */ + + for (i = 0; i < num; i++) { + p1 = plist[i]; + + if (type == blitz_rat) + rat = parray[p1].b_stats.rating; + else if (type == wild_rat) + rat = parray[p1].w_stats.rating; + else if (type == std_rat) + rat = parray[p1].s_stats.rating; + else if (type == light_rat) + rat = parray[p1].l_stats.rating; + + if (type == none) { + sprintf(ptmp, " "); + } else { + sprintf(ptmp, "%-4s", ratstrii(rat, parray[p1].registered)); + if (parray[p1].simul_info.numBoards) { + strcat(ptmp, "~"); + } else if ((parray[p1].game >= 0) && (garray[parray[p1].game].status == GAME_EXAMINE)) { + strcat(ptmp, "#"); + } else if (parray[p1].game >= 0) { + strcat(ptmp, "^"); + } else if (!parray[p1].open) { + strcat(ptmp, ":"); + } else if (player_idle(p1) > 300) { + strcat(ptmp, "."); + } else { + strcat(ptmp, " "); + } + } + + if (p == p1) { + psprintf_highlight(p, ptmp + strlen(ptmp), "%s", parray[p1].name); + } else { + strcat(ptmp, parray[p1].name); + } + + AddPlayerLists(p1, ptmp); + multicol_store(m, ptmp); + } + multicol_pprint(m, p, 80, 2); + multicol_end(m); + pprintf(p, "\n %d players displayed (of %d). (*) indicates system administrator.\n", num, player_count(1)); +} + +PRIVATE void who_verbose(p, num, plist) +int p; +int num; +int plist[]; +{ + int i, p1; + char playerLine[255], tmp[255]; /* +8 for highlight */ + char p1WithAttrs[255]; + + pprintf(p, + " +---------------------------------------------------------------+\n" + ); + pprintf(p, + " | User Standard Blitz On for Idle |\n" + ); + pprintf(p, + " +---------------------------------------------------------------+\n" + ); + + for (i = 0; i < num; i++) { + p1 = plist[i]; + + strcpy(playerLine, " |"); + + if (parray[p1].game >= 0) + sprintf(tmp, "%3d", parray[p1].game + 1); + else + sprintf(tmp, " "); + strcat(playerLine, tmp); + + if (!parray[p1].open) + sprintf(tmp, "X"); + else + sprintf(tmp, " "); + strcat(playerLine, tmp); + + if (parray[p1].registered) + if (parray[p1].rated) { + sprintf(tmp, " "); + } else { + sprintf(tmp, "u"); + } + else + sprintf(tmp, "U"); + strcat(playerLine, tmp); + + /* Modified by hersco to include lists in 'who v.' */ + strcpy (p1WithAttrs, parray[p1].name); + AddPlayerLists(p1, p1WithAttrs); + p1WithAttrs[17] = '\0'; + + /* Modified by DAV 3/15/95 */ + if (p == p1) { + strcpy(tmp, " "); + psprintf_highlight(p, tmp + strlen(tmp), "%-17s", p1WithAttrs); + } else { + sprintf(tmp, " %-17s", p1WithAttrs); + } + strcat(playerLine, tmp); + + sprintf(tmp, " %4s %-4s %5s ", + ratstrii(parray[p1].s_stats.rating, parray[p1].registered), + ratstrii(parray[p1].b_stats.rating, parray[p1].registered), + hms(player_ontime(p1), 0, 0, 0)); + strcat(playerLine, tmp); + + if (player_idle(p1) >= 60) { + sprintf(tmp, "%5s |\n", hms(player_idle(p1), 0, 0, 0)); + } else { + sprintf(tmp, " |\n"); + } + strcat(playerLine, tmp); + pprintf(p, "%s", playerLine); + } + + pprintf(p, + " | |\n" + ); + pprintf(p, + " | %3d Players Displayed |\n", + num + ); + pprintf(p, + " +---------------------------------------------------------------+\n" + ); +} + +PRIVATE void who_winloss(p, num, plist) +int p; +int num; +int plist[]; +{ + int i, p1; + char playerLine[255], tmp[255]; /* for highlight */ + char p1WithAttrs[255]; + + pprintf(p, + "Name Stand win loss draw Blitz win loss draw idle\n" + ); + pprintf(p, + "---------------- ----- ------------- ----- ------------- ----\n" + ); + + for (i = 0; i < num; i++) { + playerLine[0] = '\0'; + p1 = plist[i]; + + /* Modified by hersco to include lists in 'who n.' */ + strcpy (p1WithAttrs, parray[p1].name); + AddPlayerLists(p1, p1WithAttrs); + p1WithAttrs[17] = '\0'; + + if (p1 == p) { + psprintf_highlight(p, playerLine, "%-17s", p1WithAttrs); + } else { + sprintf(playerLine, "%-17s", p1WithAttrs); + } + sprintf(tmp, " %4s %4d %4d %4d ", + ratstrii(parray[p1].s_stats.rating, parray[p1].registered), + (int) parray[p1].s_stats.win, + (int) parray[p1].s_stats.los, + (int) parray[p1].s_stats.dra); + strcat(playerLine, tmp); + + sprintf(tmp, "%4s %4d %4d %4d ", + ratstrii(parray[p1].b_stats.rating, parray[p1].registered), + (int) parray[p1].b_stats.win, + (int) parray[p1].b_stats.los, + (int) parray[p1].b_stats.dra); + strcat(playerLine, tmp); + + if (player_idle(p1) >= 60) { + sprintf(tmp, "%5s\n", hms(player_idle(p1), 0, 0, 0)); + } else { + sprintf(tmp, " \n"); + } + strcat(playerLine, tmp); + + pprintf(p, "%s", playerLine); + } + pprintf(p, " %3d Players Displayed.\n", num); +} + +PRIVATE int who_ok(int p, unsigned int sel_bits) +{ + int p2; + if (parray[p].status != PLAYER_PROMPT) + return 0; + if (sel_bits == WHO_ALL) + return 1; + if (sel_bits & WHO_OPEN) + if (!parray[p].open) + return 0; + if (sel_bits & WHO_CLOSED) + if (parray[p].open) + return 0; + if (sel_bits & WHO_RATED) + if (!parray[p].rated) + return 0; + if (sel_bits & WHO_UNRATED) + if (parray[p].rated) + return 0; + if (sel_bits & WHO_FREE) + if (parray[p].game >= 0) + return 0; + if (sel_bits & WHO_PLAYING) + if (parray[p].game < 0) + return 0; + if (sel_bits & WHO_REGISTERED) + if (!parray[p].registered) + return 0; + if (sel_bits & WHO_UNREGISTERED) + if (parray[p].registered) + return 0; + if (sel_bits & WHO_BUGTEAM) { + p2 = parray[p].partner; + if (p2 < 0 || parray[p2].partner != p) + return 0; + } + return 1; +} + + +PRIVATE int blitz_cmp(const void *pp1, const void *pp2) +{ + register int p1 = *(int *) pp1; + register int p2 = *(int *) pp2; + if (parray[p1].status != PLAYER_PROMPT) { + if (parray[p2].status != PLAYER_PROMPT) + return 0; + else + return -1; + } + if (parray[p2].status != PLAYER_PROMPT) + return 1; + if (parray[p1].b_stats.rating > parray[p2].b_stats.rating) + return -1; + if (parray[p1].b_stats.rating < parray[p2].b_stats.rating) + return 1; + if (parray[p1].registered > parray[p2].registered) + return -1; + if (parray[p1].registered < parray[p2].registered) + return 1; + return strcmp(parray[p1].login, parray[p2].login); +} + +PRIVATE int light_cmp(const void *pp1, const void *pp2) +{ + register int p1 = *(int *) pp1; + register int p2 = *(int *) pp2; + if (parray[p1].status != PLAYER_PROMPT) { + if (parray[p2].status != PLAYER_PROMPT) + return 0; + else + return -1; + } + if (parray[p2].status != PLAYER_PROMPT) + return 1; + if (parray[p1].l_stats.rating > parray[p2].l_stats.rating) + return -1; + if (parray[p1].l_stats.rating < parray[p2].l_stats.rating) + return 1; + if (parray[p1].registered > parray[p2].registered) + return -1; + if (parray[p1].registered < parray[p2].registered) + return 1; + return strcmp(parray[p1].login, parray[p2].login); +} + +PRIVATE int stand_cmp(const void *pp1, const void *pp2) +{ + register int p1 = *(int *) pp1; + register int p2 = *(int *) pp2; + if (parray[p1].status != PLAYER_PROMPT) { + if (parray[p2].status != PLAYER_PROMPT) + return 0; + else + return -1; + } + if (parray[p2].status != PLAYER_PROMPT) + return 1; + if (parray[p1].s_stats.rating > parray[p2].s_stats.rating) + return -1; + if (parray[p1].s_stats.rating < parray[p2].s_stats.rating) + return 1; + if (parray[p1].registered > parray[p2].registered) + return -1; + if (parray[p1].registered < parray[p2].registered) + return 1; + return strcmp(parray[p1].login, parray[p2].login); +} + +PRIVATE int wild_cmp(const void *pp1, const void *pp2) +{ + register int p1 = *(int *) pp1; + register int p2 = *(int *) pp2; + if (parray[p1].status != PLAYER_PROMPT) { + if (parray[p2].status != PLAYER_PROMPT) + return 0; + else + return -1; + } + if (parray[p2].status != PLAYER_PROMPT) + return 1; + if (parray[p1].w_stats.rating > parray[p2].w_stats.rating) + return -1; + if (parray[p1].w_stats.rating < parray[p2].w_stats.rating) + return 1; + if (parray[p1].registered > parray[p2].registered) + return -1; + if (parray[p1].registered < parray[p2].registered) + return 1; + return strcmp(parray[p1].login, parray[p2].login); +} + +PRIVATE int alpha_cmp(const void *pp1, const void *pp2) +{ + register int p1 = *(int *) pp1; + register int p2 = *(int *) pp2; + if (parray[p1].status != PLAYER_PROMPT) { + if (parray[p2].status != PLAYER_PROMPT) + return 0; + else + return -1; + } + if (parray[p2].status != PLAYER_PROMPT) + return 1; + return strcmp(parray[p1].login, parray[p2].login); +} + +PUBLIC void sort_players(int players[PARRAY_SIZE], + int ((*cmp_func) (const void *, const void *))) +{ + int i; + + for (i = 0; i < p_num; i++) { + players[i] = i; + } + qsort(players, p_num, sizeof(int), cmp_func); +} + +/* This is the of the most compliclicated commands in terms of parameters */ +PUBLIC int com_who(int p, param_list param) +{ + int style = 0; + float stop_perc = 1.0; + float start_perc = 0; + unsigned int sel_bits = WHO_ALL; + int sortlist[PARRAY_SIZE], plist[PARRAY_SIZE]; + int ((*cmp_func) (const void *, const void *)) = blitz_cmp; + int startpoint; + int stoppoint; + int i, len; + int tmpI, tmpJ; + char c; + int p1, count, num_who; + int sort_type = blitz_rat; + + if (param[0].type != TYPE_NULL) { + len = strlen(param[0].val.string); + for (i = 0; i < len; i++) { + c = param[0].val.string[i]; + if (isdigit(c)) { + if (i == 0 || !isdigit(param[0].val.string[i - 1])) { + tmpI = c - '0'; + if (tmpI == 1) { + start_perc = 0.0; + stop_perc = 0.333333; + } else if (tmpI == 2) { + start_perc = 0.333333; + stop_perc = 0.6666667; + } else if (tmpI == 3) { + start_perc = 0.6666667; + stop_perc = 1.0; + } else if ((i == len - 1) || (!isdigit(param[0].val.string[i + 1]))) + return COM_BADPARAMETERS; + } else { + tmpI = c - '0'; + tmpJ = param[0].val.string[i - 1] - '0'; + if (tmpI == 0) + return COM_BADPARAMETERS; + if (tmpJ > tmpI) + return COM_BADPARAMETERS; + start_perc = ((float) tmpJ - 1.0) / (float) tmpI; + stop_perc = ((float) tmpJ) / (float) tmpI; + } + } else { + switch (c) { + case ' ': + case '\n': + case '\t': + break; + case 'o': + if (sel_bits == WHO_ALL) + sel_bits = WHO_OPEN; + else + sel_bits |= WHO_OPEN; + break; + case 'r': + if (sel_bits == WHO_ALL) + sel_bits = WHO_RATED; + else + sel_bits |= WHO_RATED; + break; + case 'f': + if (sel_bits == WHO_ALL) + sel_bits = WHO_FREE; + else + sel_bits |= WHO_FREE; + break; + case 'a': + if (sel_bits == WHO_ALL) + sel_bits = WHO_FREE | WHO_OPEN; + else + sel_bits |= (WHO_FREE | WHO_OPEN); + break; + case 'R': + if (sel_bits == WHO_ALL) + sel_bits = WHO_REGISTERED; + else + sel_bits |= WHO_REGISTERED; + break; + case 'l': /* Sort order */ + cmp_func = alpha_cmp; + sort_type = none; + break; + case 'A': /* Sort order */ + cmp_func = alpha_cmp; + break; + case 'w': /* Sort order */ + cmp_func = wild_cmp; + sort_type = wild_rat; + break; + case 's': /* Sort order */ + cmp_func = stand_cmp; + sort_type = std_rat; + break; + case 'b': /* Sort order */ + cmp_func = blitz_cmp; + sort_type = blitz_rat; + break; + case 'L': /* Sort order */ + cmp_func = light_cmp; + sort_type = light_rat; + break; + case 't': /* format */ + style = 0; + break; + case 'v': /* format */ + style = 1; + break; + case 'n': /* format */ + style = 2; + break; + case 'U': + if (sel_bits == WHO_ALL) + sel_bits = WHO_UNREGISTERED; + else + sel_bits |= WHO_UNREGISTERED; + break; + case 'B': + if (sel_bits == WHO_ALL) + sel_bits = WHO_BUGTEAM; + else + sel_bits |= WHO_BUGTEAM; + break; + default: + return COM_BADPARAMETERS; + break; + } + } + } + } + sort_players(sortlist, cmp_func); + count = 0; + for (p1 = 0; p1 < p_num; p1++) { + if (!who_ok(sortlist[p1], sel_bits)) + continue; + count++; + } + startpoint = floor((float) count * start_perc); + stoppoint = ceil((float) count * stop_perc) - 1; + num_who = 0; + count = 0; + for (p1 = 0; p1 < p_num; p1++) { + if (!who_ok(sortlist[p1], sel_bits)) + continue; + if ((count >= startpoint) && (count <= stoppoint)) { + plist[num_who++] = sortlist[p1]; + } + count++; + } + + if (num_who == 0) { + pprintf(p, "No logged in players match the flags in your who request.\n"); + return COM_OK; + } + + switch (style) { + case 0: /* terse */ + who_terse(p, num_who, plist, sort_type); + break; + case 1: /* verbose */ + who_verbose(p, num_who, plist); + break; + case 2: /* win-loss */ + who_winloss(p, num_who, plist); + break; + default: + return COM_BADPARAMETERS; + break; + } + + return COM_OK; +} + +PUBLIC int com_refresh(int p, param_list param) +{ + int g, p1; + + if (param[0].type == TYPE_NULL) { + if (parray[p].game >= 0) { + send_board_to(parray[p].game, p); + } else { /* Do observing in here */ + if (parray[p].num_observe) { + for (g = 0; g < parray[p].num_observe; g++) { + send_board_to(parray[p].observe_list[g], p); + } + } else { + pprintf(p, "You are neither playing, observing nor examining a game.\n"); + return COM_OK; + } + } + } else { + g = GameNumFromParam (p, &p1, ¶m[0]); + if (g < 0) + return COM_OK; + if ((g >= g_num) || ((garray[g].status != GAME_ACTIVE) + && (garray[g].status != GAME_EXAMINE))) { + pprintf(p, "No such game.\n"); + } else if (garray[g].private && parray[p].adminLevel==ADMIN_USER) { + pprintf (p, "Sorry, game %d is a private game.\n", g+1); + } else { + if (garray[g].private) + pprintf(p, "Refreshing PRIVATE game %d\n", g+1); + send_board_to(g, p); + } + } + return COM_OK; +} + +PUBLIC int com_prefresh(int p, param_list param) +{ + int retval, part = parray[p].partner; + + if (part < 0) { + pprintf(p, "You do not have a partner.\n"); + return COM_OK; + } + retval = pcommand (p, "refresh %s", parray[part].name); + if (retval == COM_OK) + return COM_OK_NOPROMPT; + else + return retval; +} + +PUBLIC int com_open(int p, param_list param) +{ + int retval; + ASSERT(param[0].type == TYPE_NULL); + if ((retval = pcommand(p, "set open")) != COM_OK) + return retval; + else + return COM_OK_NOPROMPT; +} + +PUBLIC int com_simopen(int p, param_list param) +{ + int retval; + ASSERT(param[0].type == TYPE_NULL); + if ((retval = pcommand(p, "set simopen")) != COM_OK) + return retval; + else + return COM_OK_NOPROMPT; +} + +PUBLIC int com_bell(int p, param_list param) +{ + int retval; + ASSERT(param[0].type == TYPE_NULL); + if ((retval = pcommand(p, "set bell")) != COM_OK) + return retval; + else + return COM_OK_NOPROMPT; +} + +PUBLIC int com_flip(int p, param_list param) +{ + int retval; + ASSERT(param[0].type == TYPE_NULL); + if ((retval = pcommand(p, "set flip")) != COM_OK) + return retval; + else + return COM_OK_NOPROMPT; +} + +PUBLIC int com_highlight(int p, param_list param) +{ + pprintf(p, "Obsolete command. Please do set highlight <0-15>.\n"); + return COM_OK; +} + +PUBLIC int com_style(int p, param_list param) +{ + int retval; + ASSERT(param[0].type == TYPE_INT); + if ((retval = pcommand(p, "set style %d", param[0].val.integer)) != COM_OK) + return retval; + else + return COM_OK_NOPROMPT; +} + +PUBLIC int com_promote(int p, param_list param) +{ + int retval; + ASSERT(param[0].type == TYPE_WORD); + if ((retval = pcommand(p, "set promote %s", param[0].val.word)) != COM_OK) + return retval; + else + return COM_OK_NOPROMPT; +} + +PUBLIC int com_alias(int p, param_list param) +{ + int al; + + if (param[0].type == TYPE_NULL) { + for (al = 0; al < parray[p].numAlias; al++) { + pprintf(p, "%s -> %s\n", parray[p].alias_list[al].comm_name, + parray[p].alias_list[al].alias); + } + return COM_OK; + } + al = alias_lookup(param[0].val.word, parray[p].alias_list, parray[p].numAlias); + if (param[1].type == TYPE_NULL) { + if (al < 0) { + pprintf(p, "You have no alias named '%s'.\n", param[0].val.word); + } else { + pprintf(p, "%s -> %s\n", parray[p].alias_list[al].comm_name, + parray[p].alias_list[al].alias); + } + } else { + if (al < 0) { + if (parray[p].numAlias >= MAX_ALIASES - 1) { + pprintf(p, "You have your maximum of %d aliases.\n", MAX_ALIASES - 1); + } else { + + if (!strcmp(param[0].val.string, "quit")) { /* making sure they + can't alias quit */ + pprintf(p, "You can't alias this command.\n"); + } else if (!strcmp(param[0].val.string, "unalias")) { /* making sure they + can't alias unalias + :) */ + pprintf(p, "You can't alias this command.\n"); + } else { + parray[p].alias_list[parray[p].numAlias].comm_name = + strdup(param[0].val.word); + parray[p].alias_list[parray[p].numAlias].alias = + strdup(param[1].val.string); + parray[p].numAlias++; + pprintf(p, "Alias set.\n"); + + } + } + } else { + rfree(parray[p].alias_list[al].alias); + parray[p].alias_list[al].alias = strdup(param[1].val.string); + pprintf(p, "Alias replaced.\n"); + } + parray[p].alias_list[parray[p].numAlias].comm_name = NULL; + } + return COM_OK; +} + +PUBLIC int com_unalias(int p, param_list param) +{ + int al; + int i; + + ASSERT(param[0].type == TYPE_WORD); + al = alias_lookup(param[0].val.word, parray[p].alias_list, parray[p].numAlias); + if (al < 0) { + pprintf(p, "You have no alias named '%s'.\n", param[0].val.word); + } else { + rfree(parray[p].alias_list[al].comm_name); + rfree(parray[p].alias_list[al].alias); + for (i = al; i < parray[p].numAlias; i++) { + parray[p].alias_list[i].comm_name = parray[p].alias_list[i + 1].comm_name; + parray[p].alias_list[i].alias = parray[p].alias_list[i + 1].alias; + } + parray[p].numAlias--; + parray[p].alias_list[parray[p].numAlias].comm_name = NULL; + pprintf(p, "Alias removed.\n"); + } + return COM_OK; +} + +PUBLIC int com_servers(int p, param_list param) +{ +/* + int i; + + ASSERT(param[0].type == TYPE_NULL); + if (numServers == 0) { + */ pprintf(p, "There are no other servers known to this server.\n"); + return COM_OK; +} + /* pprintf(p, "There are %d known servers.\n", numServers); pprintf(p, "(Not + all of these may be active)\n"); pprintf(p, "%-30s%-7s\n", "HOST", + "PORT"); for (i = 0; i < numServers; i++) pprintf(p, "%-30s%-7d\n", + serverNames[i], serverPorts[i]); return COM_OK; } */ + +PUBLIC int com_index(int p, param_list param) +{ + int i; + char index_default[] = "_index"; + char *iwant, *filenames[100]; /* enough for all index filenames */ + + if (param[0].type == TYPE_NULL) { + iwant = index_default; + } else { + iwant = param[0].val.word; + if (!safestring(iwant)) { + pprintf(p, "Illegal character in category %s.\n", iwant); + return COM_OK; + } + } + + i = search_directory(index_dir, iwant, filenames, 1000); + if (i == 0) { + pprintf(p, "No index entry for \"%s\".\n", iwant); + } else if ((i == 1) || !strcmp(*filenames, iwant)) { + if (psend_file(p, index_dir, *filenames)) { + /* we should never reach this unless the file was just deleted */ + pprintf(p, "Index file %s could not be found! ", *filenames); + pprintf(p, "Please inform an admin of this. Thank you.\n"); + } + } else { + pprintf(p, "Matches:"); + display_directory(p, filenames, i); + } + return COM_OK; +} + +PUBLIC int com_help(int p, param_list param) +{ + int i, UseLang = parray[p].language; + char help_default[] = "_help"; + char *iwant, *filenames[1000]; /* enough for all helpfile names */ + + if (param[0].type == TYPE_NULL) { + iwant = help_default; + } else { + iwant = param[0].val.word; + if (!safestring(iwant)) { + pprintf(p, "Illegal character in command %s.\n", iwant); + return COM_OK; + } + } + i = search_directory(help_dir[UseLang], iwant, filenames, 1000); + if (i == 0) { + if (UseLang != LANG_DEFAULT) { + i += search_directory(help_dir[LANG_DEFAULT], iwant, filenames, 1000); + if (i > 0) { + pprintf(p, "No help available in %s; using %s instead.\n", + Language(UseLang), Language(LANG_DEFAULT)); + UseLang = LANG_DEFAULT; + } + } + if (i==0) { + pprintf(p, "No help available on \"%s\".\n", iwant); + return COM_OK; + } + } + if ((i == 1) || !strcmp(*filenames, iwant)) { + if (psend_file(p, help_dir[UseLang], *filenames)) { + /* we should never reach this unless the file was just deleted */ + pprintf(p, "Helpfile %s could not be found! ", *filenames); + pprintf(p, "Please inform an admin of this. Thank you.\n"); + } + } else { + pprintf(p, "Matches:"); + display_directory(p, filenames, i); + pprintf(p, "[Type \"info\" for a list of FICS general information files.]\n"); + } + return COM_OK; +} + +PUBLIC int com_info(int p, param_list param) +{ + int n; + char *filenames[1000]; + + if ((n = search_directory(info_dir, NULL, filenames, 1000)) > 0) + display_directory(p, filenames, n); + return COM_OK; +} + +PRIVATE int FindAndShowFile(int p, param_list param, char *dir) +{ + int i; + static char nullify = '\0'; + char *iwant, *filenames[1000]; /* enough for all helpfile names */ + + if (param[0].type == TYPE_NULL) { + iwant = &nullify; + } else { + iwant = param[0].val.word; + if (!safestring(iwant)) { + pprintf(p, "Illegal character in filename %s.\n", iwant); + return COM_OK; + } + } + + i = search_directory(dir, iwant, filenames, 1000); + if (i == 0) { + pprintf(p, "No information available on \"%s\".\n", iwant); + } else if ((i == 1) || !strcmp(*filenames, iwant)) { + if (psend_file(p, dir, *filenames)) { + /* we should never reach this unless the file was just deleted */ + pprintf(p, "File %s could not be found! ", *filenames); + pprintf(p, "Please inform an admin of this. Thank you.\n"); + } + } else { + if (*iwant) + pprintf(p, "Matches:\n"); + display_directory(p, filenames, i); + } + return COM_OK; +} + +PUBLIC int com_uscf(int p, param_list param) +{ + return FindAndShowFile (p, param, uscf_dir); +} + +PUBLIC int com_adhelp(int p, param_list param) +{ + return FindAndShowFile (p, param, adhelp_dir); +} + +PUBLIC int com_mailsource(int p, param_list param) +{ + static char nullify = '\0'; + char *iwant, *buffer[1000]; + char subj[81], fname[MAX_FILENAME_SIZE]; + int count; + + if (!parray[p].registered) { + pprintf(p, "Only registered people can use the mailsource command.\n"); + return COM_OK; + } + + if (param[0].type == TYPE_NULL) { + iwant = &nullify; + } else { + iwant = param[0].val.word; + } + + count = search_directory(source_dir, iwant, buffer, 1000); + if (count == 0) { + pprintf(p, "Found no source file matching \"%s\".\n", iwant); + } else if ((count == 1) || !strcmp(iwant, *buffer)) { + sprintf(subj, "FICS source file from server %s: %s",fics_hostname,*buffer); + sprintf(fname, "%s/%s",source_dir, *buffer); + mail_file_to_user (p, subj, fname); + pprintf(p, "Source file %s sent to %s\n", *buffer, parray[p].emailAddress); + } else { + pprintf(p, "Found %d source files matching that:\n", count); + if (*iwant) + display_directory(p, buffer, count); + else { /* this junk is to get *.c *.h */ + multicol *m = multicol_start(count); + char *s; + int i; + for (i=0; i < count; i++) { + if (((s = buffer[i] + strlen(buffer[i]) - 2) >= buffer[i]) && (!strcmp(s, ".c") || !strcmp(s, ".h"))) + multicol_store(m, buffer[i]); + } + multicol_pprint(m, p, 78, 1); + multicol_end(m); + } + } + return COM_OK; +} + +PUBLIC int com_mailhelp(int p, param_list param) +{ /* Sparky */ + char subj[81], fname[MAX_FILENAME_SIZE]; + char *iwant, *buffer[1000]; + + int lang = parray[p].language; + int count; + static char nullify = '\0'; + + if (!parray[p].registered) { + pprintf(p, "Only registered people can use the mailhelp command.\n"); + return COM_OK; + } + if (param[0].type == TYPE_NULL) + iwant = &nullify; + else + iwant = param[0].val.word; + + count = search_directory(help_dir[lang], iwant, buffer, 1000); + if (count == 0 && lang != LANG_DEFAULT) { + count += search_directory(help_dir[LANG_DEFAULT], iwant, buffer, 1000); + if (count > 0) { + pprintf(p, "No help available in %s; using %s instead.\n", + Language(lang), Language(LANG_DEFAULT)); + lang = LANG_DEFAULT; + } + } + if (count == 0) { + pprintf(p, "Found no help file matching \"%s\".\n", iwant); + } else if (count == 1 || !strcmp(*buffer, iwant)) { + sprintf(subj, "FICS help file from server %s: %s", fics_hostname, *buffer); + sprintf(fname, "%s/%s",help_dir[lang], *buffer); + mail_file_to_user (p, subj, fname); + pprintf(p, "Help file %s sent to %s\n", *buffer, parray[p].emailAddress); + } else { + pprintf(p, "Found %d helpfiles matching that:\n", count); + display_directory(p, buffer, count); + } + + return COM_OK; +} + +PUBLIC int com_handles(int p, param_list param) +{ + char *buffer[1000]; + char pdir[MAX_FILENAME_SIZE]; + int count; + + sprintf(pdir, "%s/%c", player_dir, param[0].val.word[0]); + count = search_directory(pdir, param[0].val.word, buffer, 1000); + pprintf(p, "Found %d names.\n", count); + if (count > 0) + display_directory(p, buffer, count); + return COM_OK; +} + +PUBLIC int com_getpi(int p, param_list param) +{ + int p1; + + if (!in_list(p, L_TD, parray[p].name)) { + pprintf(p, "Only TD programs are allowed to use this command.\n"); + return COM_OK; + } + if (((p1 = player_find_bylogin(param[0].val.word)) < 0) || (parray[p1].registered == 0)) { + /* Darkside suggested not to return anything */ + return COM_OK; + } + if (!parray[p1].registered) { + pprintf(p, "*getpi %s -1 -1 -1*\n", parray[p1].name); + } else { + pprintf(p, "*getpi %s %d %d %d*\n", parray[p1].name, + parray[p1].w_stats.rating, + parray[p1].b_stats.rating, + parray[p1].s_stats.rating); + } + return COM_OK; +} + +PUBLIC int com_getps(int p, param_list param) +{ + int p1; + + if ((((p1 = player_find_bylogin(param[0].val.word)) < 0) || (parray[p1].registered == 0)) || (parray[p1].game < 0)) { + + pprintf(p, "*status %s 1*\n", param[0].val.word); + return COM_OK; + } + pprintf(p, "*status %s 0 %s*\n", parray[p1].name, parray[(parray[p1].opponent)].name); + return COM_OK; +} +PUBLIC int com_limits(int p, param_list param) +{ + pprintf(p, "\nCurrent hardcoded limits:\n"); + pprintf(p, " Max number of players: %d\n", MAX_PLAYER); + pprintf(p, " Max number of channels and max capacity: %d\n", MAX_CHANNELS); + pprintf(p, " Max number of channels one can be in: %d\n", MAX_INCHANNELS); + pprintf(p, " Max number of people on the notify list: %d\n", MAX_NOTIFY); + pprintf(p, " Max number of aliases: %d\n", MAX_ALIASES - 1); + pprintf(p, " Max number of games you can observe at a time: %d\n", MAX_OBSERVE); + pprintf(p, " Max number of requests pending: %d\n", MAX_PENDING); + pprintf(p, " Max number of people on the censor list: %d\n", MAX_CENSOR); + pprintf(p, " Max number of people in a simul game: %d\n", MAX_SIMUL); + pprintf(p, " Max number of messages one can receive: %d\n", MAX_MESSAGES); + pprintf(p, " Min number of games to be active: %d\n", PROVISIONAL); + if ((parray[p].adminLevel < ADMIN_ADMIN) && (!titled_player(p,parray[p].login))) { + pprintf(p, " Size of journal (entries): %d\n", MAX_JOURNAL); + } else { + pprintf(p, " Size of journal (entries): 26\n"); + } + pprintf(p, "\nAdmin settable limits:\n"); + pprintf(p, " Shout quota gives two shouts per %d seconds.\n", quota_time); + return COM_OK; +} -- cgit v1.2.3