diff -crN xpilot-4.4.1.orig/README.synrg xpilot-4.4.1/README.synrg *** xpilot-4.4.1.orig/README.synrg Wed Dec 31 20:00:00 1969 --- xpilot-4.4.1/README.synrg Thu Aug 2 18:38:09 2001 *************** *** 0 **** --- 1,17 ---- + This patch provides the beginnings of a client-side '/' command set that + complements the server-side command set. + + Three client-side commands that may be entered in the message window are + supported so far: + + /chelp shows help for client-side '/' commands. + + /ig adds someone to your 'ignore' list which may contain + up to 20 nicknames of players from whom you don't want + to receive public or private talk messages. With + no argument, /ig shows the conents of the ignore list. + + /unig removes someone from your 'ignore' list. When the + argument is '*', all names are removed from the list. + + Ben Armstrong (Fishy) diff -crN xpilot-4.4.1.orig/src/client/client.c xpilot-4.4.1/src/client/client.c *** xpilot-4.4.1.orig/src/client/client.c Fri Jun 22 02:27:42 2001 --- xpilot-4.4.1/src/client/client.c Thu Aug 2 18:38:09 2001 *************** *** 173,178 **** --- 173,181 ---- int maxVolume; /* maximum volume (in percent) */ #endif /* SOUND */ + char ignoreNames[MAX_IGNORE_LIST_SIZE][MAX_CHARS]; + int num_ignore; + static other_t *Others = 0; static int num_others = 0, max_others = 0; *************** *** 986,991 **** --- 989,1020 ---- } } return NULL; + } + + short Id_by_name(char *name) + { + int i, j, len; + + if (!name) + return -1; + + /* first look for an exact match on player nickname. */ + for (i = 0; i < num_others; i++) { + if (strcasecmp(Others[i].name, name) == 0) { + return Others[i].id; + } + } + + /* now look for a partial match on both nick and realname. */ + len=strlen(name); + for (j = -1, i = 0; i < num_others; i++) { + if (strncasecmp(Others[i].name, name, len) == 0 + || strncasecmp(Others[i].real, name, len) == 0) + j = (j == -1) ? i : -2; + } + + if (j<0) return j; + return Others[j].id; } shipobj *Ship_by_id(int id) diff -crN xpilot-4.4.1.orig/src/client/client.h xpilot-4.4.1/src/client/client.h *** xpilot-4.4.1.orig/src/client/client.h Fri Jun 22 02:27:42 2001 --- xpilot-4.4.1/src/client/client.h Thu Aug 2 18:39:18 2001 *************** *** 102,107 **** --- 102,109 ---- } + #define MAX_IGNORE_LIST_SIZE 20 + typedef struct { DFLOAT ratio; short id; *************** *** 307,312 **** --- 309,317 ---- extern int maxLinesInHistory; /* number of lines to save in history */ #define MAX_HIST_MSGS 128 /* maximum */ + extern char ignoreNames[MAX_IGNORE_LIST_SIZE][MAX_CHARS]; + extern int num_ignore; + int Fuel_by_pos(int x, int y); int Target_alive(int x, int y, int *damage); int Target_by_index(int ind, int *xp, int *yp, int *dead_time, int *damage); *************** *** 319,324 **** --- 324,330 ---- int Check_pos_by_index(int ind, int *xp, int *yp); int Check_index_by_pos(int x, int y); other_t *Other_by_id(int id); + short Id_by_name(char *name); shipobj *Ship_by_id(int id); int Handle_leave(int id); int Handle_player(int id, int team, int mychar, char *player_name, diff -crN xpilot-4.4.1.orig/src/client/painthud.c xpilot-4.4.1/src/client/painthud.c *** xpilot-4.4.1.orig/src/client/painthud.c Sat May 19 13:47:50 2001 --- xpilot-4.4.1/src/client/painthud.c Thu Aug 2 18:38:09 2001 *************** *** 56,61 **** --- 56,62 ---- #include "record.h" #include "xinit.h" #include "protoclient.h" + #include "client.h" #include "blockbitmaps.h" #include "commonproto.h" *************** *** 693,698 **** --- 694,739 ---- } + static int Ignore_message(char *message) + { + int i; + char msg[MSG_LEN]; + char *from, *from_end, *colon; + + strncpy(msg, message, sizeof(msg) - 1); + + from = strrchr(msg, '['); + + /* silly bounds-checking as we always expect a '[' in a talk message */ + if (from > msg) { + /* ":[" indicates a private message, so the real 'from' will + be in the second set of square-brackets from the end of + the message */ + colon = from; + colon--; + if (colon[0] == ':') { + colon[0] = '\0'; + from = strrchr(msg, '['); + } + } + + /* more silly bounds-checking (better safe than sorry :) */ + if (from != NULL) { + from++; + from_end = strchr(from, ']'); + + /* still more silly bounds-checking */ + if (from_end != NULL) + from_end[0] = '\0'; + + /* Check all names in our ignore list */ + for (i = 0; i < num_ignore; i++) + if (strcasecmp(ignoreNames[i+1], from) == 0) + return 1; + } + + return 0; + } void Paint_messages(void) { *************** *** 723,728 **** --- 764,772 ---- i += (BIT(instruments, SHOW_REVERSE_SCROLL) ? -1 : 1)) { if (i < maxMessages) { msg = TalkMsg[i]; + if (num_ignore > 0 && msg->txt[msg->len - 1] == ']') + if (Ignore_message(msg->txt)) + continue; } else { msg = GameMsg[i - maxMessages]; } diff -crN xpilot-4.4.1.orig/src/client/talk.c xpilot-4.4.1/src/client/talk.c *** xpilot-4.4.1.orig/src/client/talk.c Sat Jun 2 18:01:15 2001 --- xpilot-4.4.1/src/client/talk.c Thu Aug 2 18:38:09 2001 *************** *** 44,49 **** --- 44,50 ---- #include "error.h" #include "netclient.h" #include "protoclient.h" + #include "client.h" #include "keys.h" #include "bit.h" #include "commonproto.h" *************** *** 167,172 **** --- 168,343 ---- } } + enum TalkCommand { + CHELP_CMD, IG_CMD, UNIG_CMD, NO_CMD + }; + + typedef struct { + const char *name; + const char *help; + enum TalkCommand number; + } talkCommandInfo; + + static talkCommandInfo commands[] = { + { + "chelp", + "Without arguments, prints command list. /chelp gives more info.", + CHELP_CMD + }, + { + "ig", + "/ig adds to ignore list; partial or realname is allowed" + "/ig shows entire ignore list", + IG_CMD + }, + { + "unig", + "/unig removes from ignore list; partial name is allowed" + "/unig * removes all names from ignore list", + UNIG_CMD + } + }; + + static int Ignore_ind_by_name(char *name) + { + int i, j, len; + if (!name) + return -1; + /* first look for an exact match on player nickname. */ + for (i = 1; i <= num_ignore; i++) { + if (strcasecmp((char *)ignoreNames[i], name) == 0) { + return i; + } + } + /* now look for a partial match on player nickname. */ + len = strlen(name); + for (j = -1, i = 1; i <= num_ignore; i++) { + if (strncasecmp((char *)ignoreNames[i], name, len) == 0) + j = (j == -1) ? i : -2; + } + return j; + } + + int Talk_command(char *talkCmd) /* No leading slash */ + { + short id; + int i, j; + static char cmd[MAX_CHARS]; + char *args, msg[MSG_LEN * 2]; + other_t *other; + static char name[MAX_CHARS]; + + strncpy(cmd, talkCmd, MAX_CHARS); + + if (args = strchr(cmd, ' ')) + *args++ = 0; /* separate arguments from command */ + + for (i=0; i < NELEM(commands); i++) + if (!strcasecmp(cmd, commands[i].name)) + break; + if (i == NELEM(commands)) { + i = NO_CMD; + } + else + i = commands[i].number; + + switch(i) { + case NO_CMD: + break; + + case CHELP_CMD: + if (!args) + sprintf(msg, "Commands: chelp ig unig"); + else { + for (j = 0; j < NELEM(commands); j++) + if (!strcasecmp(args, commands[j].name)) + break; + if (j == NELEM(commands)) + sprintf(msg, "No help for nonexistent command '%s'.", + args); + else + sprintf(msg, "%s", commands[j].help); + } + break; + + case IG_CMD: + if (!args) { + if (num_ignore == 0) + sprintf(msg, "Ignore list is empty"); + else { + sprintf(msg, "Ignore list: "); + for (j = 0; j < num_ignore; j++) { + strcat(msg, (char *)ignoreNames[j + 1]); + strcat(msg, " "); + } + } + } + else { + if (num_ignore == MAX_IGNORE_LIST_SIZE) + sprintf(msg, "Ignore list is full; use /unig to remove names before adding more"); + else { + id = Id_by_name(args); + if (id == -2) + sprintf(msg, "Ambiguous name: %s; specify more characters", + args); + else if (id == -1) + sprintf(msg, "No matches for name: %s", args); + else { + other = Other_by_id(id); + strncpy(name, other->name, MAX_CHARS); + for (j = 0; j < num_ignore; j++) + if (strcasecmp(ignoreNames[j+1], name) == 0) + break; + if (j == num_ignore) { + strncpy(ignoreNames[++num_ignore], name, MAX_CHARS); + sprintf(msg, "Ignoring private and public messages from: %s", + name); + } + else + sprintf(msg, "Already ignoring: %s", name); + } + } + } + break; + + case UNIG_CMD: + if (!args) + sprintf(msg, "Usage: /unig to unignore ; /unig * to clear ignore list"); + else if (num_ignore == 0) + sprintf(msg, "Ignore list is empty"); + else if (args[0] == '*') { + sprintf(msg, "Clearing all names from ignore list"); + num_ignore = 0; + } + else { + j = Ignore_ind_by_name(args); + if (j == -2) + sprintf(msg, "Ambiguous name: %s; specify more characters", + args); + else if (j == -1) + sprintf(msg, "No matches for name: %s", args); + else { + sprintf(msg, "No longer ignoring: %s", + (char *)ignoreNames[j]); + /* remove name from ignore list: */ + for (; j < num_ignore; j++) + strncpy((char *)ignoreNames[j], + (char *)ignoreNames[j + 1], MAX_CHARS); + num_ignore--; + } + } + break; + + } + + if (i == NO_CMD) + return false; + else { + sprintf(msg + strlen(msg), " [*Client reply*]"); + Add_message(msg); + return true; + } + } void Talk_map_window(bool map) { *************** *** 636,642 **** if (selectionAndHistory && save_talk_str) { Add_msg_to_history(talk_str); } ! Net_talk(talk_str); talk_cursor.point = 0; talk_str[0] = '\0'; } else if (selectionAndHistory) { --- 807,821 ---- if (selectionAndHistory && save_talk_str) { Add_msg_to_history(talk_str); } ! if (talk_str[0] == '/') { ! /* If it's a client-side command, process locally, ! otherwise send to be processed as a server-side ! command */ ! if (!Talk_command(talk_str + 1)) ! Net_talk(talk_str); ! } ! else ! Net_talk(talk_str); talk_cursor.point = 0; talk_str[0] = '\0'; } else if (selectionAndHistory) {