Check-in Lasker-2.2.3 tar ball from samba.org
[capablanca.git] / lasker-2.2.3 / src / talkproc.c
1 /*
2    Copyright (c) 1993 Richard V. Nash.
3    Copyright (c) 2000 Dan Papasian
4    Copyright (C) Andrew Tridgell 2002
5    
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.
10    
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.
15    
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.
19 */
20
21 #include "includes.h"
22
23 static int on_channel(int ch, int p);
24
25 static int CheckShoutQuota(int p)
26 {
27         struct player *pp = &player_globals.parray[p];
28         int timeleft = time(0) - pp->lastshout_a;
29         
30         if ((timeleft < seek_globals.quota_time) && (pp->adminLevel == 0))
31                 return (seek_globals.quota_time - timeleft);
32
33         return 0;
34 }
35
36 int com_shout(int p, param_list param)
37 {
38   int p1, count = 0, timeleft = CheckShoutQuota(p);     
39   struct player *pp = &player_globals.parray[p];
40
41   if (!CheckPFlag(p, PFLAG_REG)) {
42     pprintf(p, "Only registered players can use the shout command.\n");
43     return COM_OK;
44   }
45   if (in_list(p, L_MUZZLE, pp->login)) {
46     pprintf(p, "You are muzzled.\n");
47     return COM_OK;
48   }
49   if (param[0].type == TYPE_NULL) {
50     if (timeleft)
51       pprintf(p, "Next shout available in %d seconds.\n", timeleft);
52     else
53       pprintf(p, "Your next shout is ready for use.\n");
54     return COM_OK;
55   }
56   if (timeleft) {
57     pprintf(p, "Shout not sent. Next shout in %d seconds.\n", timeleft);
58     return COM_OK;
59   }
60
61   pp->lastshout_a = pp->lastshout_b;
62   pp->lastshout_b = time(0);
63   if (!printablestring(param[0].val.string)) {
64     pprintf(p, "Your message contains some unprintable character(s).\n");
65     return COM_OK;
66   }
67
68   for (p1 = 0; p1 < player_globals.p_num; p1++) {
69     if ((p1 == p) || (player_globals.parray[p1].status != PLAYER_PROMPT) ||
70         (!CheckPFlag(p1, PFLAG_SHOUT)) || (player_censored(p1, p)))
71       continue;
72     count++;
73     pprintf_prompt(p1, "\n%s shouts: %s\n",pp->name,param[0].val.string);
74   }
75
76   pprintf(p, "(%d) %s shouts: %s\n", count, pp->name, 
77           param[0].val.string);
78
79   if (!CheckPFlag(p, PFLAG_SHOUT))
80     pprintf (p, "You are not listening to shouts.\n");
81   if ((timeleft = CheckShoutQuota(p))) 
82     pprintf(p, "Next shout in %d second(s).\n", timeleft);
83   
84   return COM_OK;
85 }
86
87 int com_cshout(int p, param_list param)
88 {
89   struct player *pp = &player_globals.parray[p];
90   int p1, count = 0;
91
92   if (!CheckPFlag(p, PFLAG_REG)) {
93     pprintf(p, "Only registered players can use the cshout command.\n");
94     return COM_OK;
95   }
96   if (in_list(p, L_CMUZZLE, pp->login)) {
97     pprintf(p, "You are c-muzzled.\n");
98     return COM_OK;
99   }
100   if (!printablestring(param[0].val.string)) {
101     pprintf(p, "Your message contains some unprintable character(s).\n");
102     return COM_OK;
103   }
104
105   for (p1 = 0; p1 < player_globals.p_num; p1++) {
106     if ((p1 == p) || (player_globals.parray[p1].status != PLAYER_PROMPT) || 
107         (!CheckPFlag(p1, PFLAG_CSHOUT)) || (player_censored(p1, p)))
108       continue;
109     count++;
110     pprintf_prompt(p1, "\n%s c-shouts: %s\n", pp->name,
111                    param[0].val.string);
112   }
113   pprintf(p, "(%d) %s c-shouts: %s\n", count, pp->name,
114           param[0].val.string);
115   if (!CheckPFlag(p, PFLAG_CSHOUT))
116     pprintf (p, "You are not listening to c-shouts.\n");
117   
118   return COM_OK;
119 }
120
121 int com_it(int p, param_list param)
122 {
123   struct player *pp = &player_globals.parray[p];
124   int p1, count = 0, timeleft = CheckShoutQuota(p);
125
126   if (!CheckPFlag(p, PFLAG_REG)) {
127     pprintf(p, "Only registered players can use the it command.\n");
128     return COM_OK;
129   }
130   if (in_list(p, L_MUZZLE, pp->login)) {
131     pprintf(p, "You are muzzled.\n");
132     return COM_OK;
133   }
134   if (param[0].type == TYPE_NULL) {
135     if (timeleft)
136       pprintf(p, "Next shout available in %d seconds.\n", timeleft);
137     else
138       pprintf(p, "Your next shout is ready for use.\n");
139
140     return COM_OK;
141   }
142   if (timeleft) {
143     pprintf(p, "Shout not sent. Next shout in %d seconds.\n", timeleft);
144     return COM_OK;
145   }
146   pp->lastshout_a = pp->lastshout_b;
147   pp->lastshout_b = time(0);
148
149   if (!printablestring(param[0].val.string)) {
150     pprintf(p, "Your message contains some unprintable character(s).\n");
151     return COM_OK;
152   }
153
154   for (p1 = 0; p1 < player_globals.p_num; p1++) {
155     if ((p1 == p) || (player_globals.parray[p1].status != PLAYER_PROMPT) || 
156         (!CheckPFlag(p1, PFLAG_SHOUT)) || (player_censored(p1, p)))
157       continue;
158     count++;
159     if ((!strncmp(param[0].val.string, "\'", 1)) ||
160         (!strncmp(param[0].val.string, ",", 1)) ||
161         (!strncmp(param[0].val.string, ".", 1)))
162       pprintf_prompt(p1, "\n--> %s%s\n", pp->name,
163                      param[0].val.string);
164     else
165       pprintf_prompt(p1, "\n--> %s %s\n", pp->name,
166                      param[0].val.string);
167   }
168   if ((!strncmp(param[0].val.string, "\'", 1)) ||
169       (!strncmp(param[0].val.string, ",", 1)) ||
170       (!strncmp(param[0].val.string, ".", 1))) 
171     pprintf(p, "--> %s%s\n", pp->name, param[0].val.string);
172   else
173     pprintf(p, "--> %s %s\n", pp->name, param[0].val.string);
174   
175   if ((timeleft = CheckShoutQuota(p)))
176     pprintf(p, "Next shout in %d second(s).\n", timeleft);
177
178   return COM_OK;
179 }
180
181 static int tell(int p, int p1, const char *msg, int why, int ch)
182 {
183   struct player *pp = &player_globals.parray[p];
184   char tmp[MAX_LINE_SIZE];
185   int rating, rating1, p2;
186
187   if (!printablestring(msg)) {
188     pprintf(p, "Your message contains some unprintable character(s).\n");
189     return COM_OK;
190   }
191
192   if (!CheckPFlag(p1, PFLAG_TELL) && !CheckPFlag(p, PFLAG_REG)) {
193     pprintf(p, "Player \"%s\" isn't listening to unregistered tells.\n",
194             player_globals.parray[p1].name);
195     return COM_OK;
196   }
197   if (player_censored(p1, p)) {
198     if (pp->adminLevel == 0) {
199       if (why != TELL_KIBITZ && why != TELL_WHISPER && why != TELL_CHANNEL)
200         pprintf(p, "Player \"%s\" is censoring you.\n", player_globals.parray[p1].name);
201       return COM_OK;
202     } else
203       pprintf(p, "Told \"%s\", who is censoring you.\n", player_globals.parray[p1].name);
204   }
205
206   switch (why) {
207   case TELL_SAY:
208     pprintf_highlight(p1, "\n%s", pp->name);
209     pprintf_prompt(p1, " says: %s\n", msg);
210     break;
211   case TELL_WHISPER:
212   case TELL_KIBITZ:
213     rating = GetRating(&player_globals.parray[p], TYPE_BLITZ);
214     if (rating < (rating1 = (GetRating(&player_globals.parray[p], TYPE_STAND))))
215       rating = rating1;
216     if (in_list(p, L_FM, pp->name))
217       pprintf(p1, "\n%s(FM)", pp->name);
218     else if (in_list(p, L_IM, pp->name))
219       pprintf(p1, "\n%s(IM)", pp->name);
220     else if (in_list(p, L_GM, pp->name))
221       pprintf(p1, "\n%s(GM)", pp->name);
222     else if (in_list(p, L_WGM, pp->name))
223       pprintf(p1, "\n%s(WGM)", pp->name);
224     else if ((pp->adminLevel >= 10)
225              && CheckPFlag(p, PFLAG_ADMINLIGHT))
226       pprintf(p1, "\n%s(*)", pp->name);
227     else if ((rating >= player_globals.parray[p1].kiblevel) || 
228              ((pp->adminLevel >= 10)
229               && CheckPFlag(p, PFLAG_ADMINLIGHT)))
230       if (!CheckPFlag(p, PFLAG_REG))
231         pprintf(p1, "\n%s(++++)", pp->name);
232       else if (rating != 0)
233         if (in_list(p, L_COMPUTER, pp->name))
234           pprintf(p1, "\n%s(%d)(C)", pp->name, rating);
235         else
236           pprintf(p1, "\n%s(%d)", pp->name, rating);
237       else 
238         pprintf(p1, "\n%s(----)", pp->name);
239     else break;
240     
241     if (why == TELL_WHISPER) 
242       pprintf_prompt(p1, " whispers: %s\n", msg);
243     else 
244       pprintf_prompt(p1, " kibitzes: %s\n", msg);
245
246     break;
247   case TELL_CHANNEL:
248     pprintf(p1, "\n%s", pp->name);
249     if ((pp->adminLevel >= 10)
250         && CheckPFlag(p, PFLAG_ADMINLIGHT) && (ch == 1))
251       pprintf(p1, "(*)");
252     pprintf_prompt(p1, "(%d): %s\n", ch, msg);
253     break;
254   case TELL_LTELL:
255       pprintf_prompt(p1, "\n%s tells you: %s\n", pp->name, msg);
256       break;
257
258   case TELL_TELL:
259   default:
260     if (player_globals.parray[p1].highlight)
261       pprintf_highlight(p1, "\n%s", pp->name);
262     else
263       pprintf(p1, "\n%s", pp->name);
264     
265     if ((pp->adminLevel >= 10) && CheckPFlag(p, PFLAG_ADMINLIGHT))
266       pprintf(p1,"(*)");
267     
268     pprintf_prompt(p1, " tells you: %s\n", msg);
269
270 /* let's test for forwarding of tells */
271
272     if ((pp->ftell == p1) || (player_globals.parray[p1].ftell == p)) {
273       for (p2 = 0; p2 < player_globals.p_num; p2++) {
274         if ((p2 == p) || (p2 == p1) || (player_globals.parray[p2].status != PLAYER_PROMPT))
275           continue;
276         if (on_channel(0, p2))
277           pprintf (p2,"\nFwd tell: %s told %s: %s\n", pp->name,
278                  player_globals.parray[p1].name, msg);
279       }
280     }
281
282     break;
283   }
284   
285   tmp[0] = '\0';
286   
287   if (!(player_globals.parray[p1].busy == NULL))
288     sprintf(tmp, ", who %s (idle: %s)", player_globals.parray[p1].busy, 
289             hms_desc(player_idle(p1)));
290   else
291     if (((player_idle(p1) % 3600) / 60) > 2)
292       sprintf(tmp, ", who has been idle %s", hms_desc(player_idle(p1)));
293   
294   if ((why == TELL_SAY) || (why == TELL_TELL) || (why == TELL_LTELL)) {
295     pprintf(p, "(told %s%s)\n", player_globals.parray[p1].name,
296             (((player_globals.parray[p1].game>=0) && (game_globals.garray[player_globals.parray[p1].game].status == GAME_EXAMINE)) 
297              ? ", who is examining a game" : 
298              ((player_globals.parray[p1].game>=0) && (game_globals.garray[player_globals.parray[p1].game].status == GAME_SETUP))
299              ? ", who is setting up a position" :
300              (player_globals.parray[p1].game >= 0 && (player_globals.parray[p1].game != pp->game))
301              ? ", who is playing" : tmp));
302   }
303
304   if (why == TELL_TELL || why == TELL_SAY) {
305           FREE(pp->last_tell);
306           pp->last_tell = strdup(player_globals.parray[p1].login);
307   }
308   
309   return COM_OK;
310 }
311
312 int com_ptell(int p, param_list param)
313 {
314   struct player *pp = &player_globals.parray[p];
315   char tmp[MAX_LINE_SIZE];
316   int p1;
317
318    if (pp->partner < 0) {
319      pprintf (p, "You do not have a partner at present.\n");
320      return COM_OK;
321    }
322
323    p1 = pp->partner;
324    if ((p1 < 0) || (player_globals.parray[p1].status == PLAYER_PASSWORD)
325        || (player_globals.parray[p1].status == PLAYER_LOGIN)) {
326      pprintf(p, "Your partner is not logged in.\n");
327      return COM_OK;
328    }
329
330    if (player_globals.parray[p1].highlight)
331      pprintf_highlight(p1, "\n%s", pp->name);
332    else
333      pprintf(p1, "\n%s", pp->name);
334    
335    pprintf_prompt(p1, " (your partner) tells you: %s\n", param[0].val.string);
336    tmp[0] = '\0';
337    if (!(player_globals.parray[p1].busy == NULL))
338      sprintf(tmp, ", who %s (idle: %s)", player_globals.parray[p1].busy,
339              hms_desc(player_idle(p1)));
340    else
341      if (((player_idle(p1) % 3600) / 60) > 2) 
342        sprintf(tmp, ", who has been idle %s", hms_desc(player_idle(p1)));
343    
344    pprintf(p, "(told %s%s)\n", player_globals.parray[p1].name,
345            (((player_globals.parray[p1].game>=0) && (game_globals.garray[player_globals.parray[p1].game].status == GAME_EXAMINE))
346             ? ", who is examining a game" :
347             ((player_globals.parray[p1].game>=0) && (game_globals.garray[player_globals.parray[p1].game].status == GAME_SETUP))
348             ? ", who is setting up a position" :
349             (player_globals.parray[p1].game >= 0 && (player_globals.parray[p1].game != pp->game))
350             ? ", who is playing" : tmp));
351    
352    return COM_OK;
353 }
354
355 static int chtell(int p, int ch, char *msg)
356 {
357   struct player *pp = &player_globals.parray[p];
358   int p1, count = 0;
359
360   if ((ch == 0) && (pp->adminLevel < ADMIN_ADMIN)) {
361     pprintf(p, "Only admins may send tells to channel 0.\n");
362     return COM_OK;
363   }
364
365   if (ch < 0) {
366     pprintf(p, "The lowest channel number is 0.\n");
367     return COM_OK;
368   }
369
370   if (ch >= MAX_CHANNELS) {
371     pprintf(p, "The maximum channel number is %d.\n", MAX_CHANNELS - 1);
372     return COM_OK;
373   }
374
375   if ((ch == 1) && (in_list(p, L_C1MUZZLE, pp->login))) {
376     pprintf (p, "You have been prevented from sending tells to channel 1.\n");
377     return COM_OK;
378   }
379
380   if ((ch == 24) && (in_list(p, L_C24MUZZLE, pp->login))) {
381     pprintf (p, "You have been prevented from sending tells to channel 24.\n");
382     return COM_OK;
383   }
384
385   if ((ch == 46) && (in_list(p, L_C46MUZZLE, pp->login))) {
386     pprintf (p, "You have been prevented from sending tells to channel 46.\n");
387     return COM_OK;
388   }
389
390   if ((ch == 49) && (in_list(p, L_C49MUZZLE, pp->login))) {
391     pprintf (p, "You have been prevented from sending tells to channel 49.\n");
392     return COM_OK;
393   }
394
395   if ((ch == 50) && (in_list(p, L_C50MUZZLE, pp->login))) {
396     pprintf (p, "You have been prevented from sending tells to channel 50.\n");
397     return COM_OK;
398   }
399
400   if ((ch == 51) && (in_list(p, L_C51MUZZLE, pp->login))) {
401     pprintf (p, "You have been prevented from sending tells to channel 51.\n");
402     return COM_OK;
403   }
404
405   for (p1 = 0; p1 < player_globals.p_num; p1++) {
406     if ((p1 == p) || (player_globals.parray[p1].status != PLAYER_PROMPT)) 
407       continue;
408     if ((on_channel(ch, p1)) && (!player_censored(p1, p))
409         && (CheckPFlag(p, PFLAG_REG) || CheckPFlag(p1, PFLAG_TELL))) {
410       tell(p, p1, msg, TELL_CHANNEL, ch);
411       if (!player_censored(p1, p))
412         count++;
413     }
414   }
415
416   if (count) 
417     pp->last_channel = ch;
418   
419   pprintf(p, "%s(%d): %s\n", pp->name, ch, msg);
420   if (!on_channel(ch, p))
421     pprintf(p, " (You're not listening to channel %d.)\n", ch);
422   
423   return COM_OK;
424 }
425
426 int com_whisper(int p, param_list param)
427 {
428   struct player *pp = &player_globals.parray[p];
429   int g, p1, count = 0;
430
431   if (!pp->num_observe && pp->game < 0) {
432     pprintf(p, "You are not playing or observing a game.\n");
433     return COM_OK;
434   }
435   if (!CheckPFlag(p, PFLAG_REG) && (pp->game == -1)) {
436     pprintf(p, "You must be registered to whisper other people's games.\n");
437     return COM_OK;
438   }
439   if (pp->game >= 0)
440     g = pp->game;
441   else
442     g = pp->observe_list[0];
443   for (p1 = 0; p1 < player_globals.p_num; p1++) {
444     if ((p1 == p) || (player_globals.parray[p1].status != PLAYER_PROMPT))
445       continue;
446     if (player_is_observe(p1, g) ||
447         (game_globals.garray[g].link >= 0 && player_is_observe(p1, game_globals.garray[g].link)
448          && player_globals.parray[p1].game != game_globals.garray[g].link)) {
449       tell(p, p1, param[0].val.string, TELL_WHISPER, 0);
450       if ((pp->adminLevel >= ADMIN_ADMIN) || !game_globals.garray[g].private || !player_censored(p1, p))
451         count++;
452     }
453   }
454   pprintf(p, "whispered to %d.\n", count);
455   return COM_OK;
456 }
457
458 int com_kibitz(int p, param_list param)
459 {
460   struct player *pp = &player_globals.parray[p];
461   int g, p1, count = 0;
462
463   if (!pp->num_observe && pp->game < 0) {
464     pprintf(p, "You are not playing or observing a game.\n");
465     return COM_OK;
466   }
467   if (!CheckPFlag(p, PFLAG_REG) && (pp->game == -1)) {
468     pprintf(p, "You must be registered to kibitz other people's games.\n");
469     return COM_OK;
470   }
471   if (pp->game >= 0)
472     g = pp->game;
473   else
474     g = pp->observe_list[0];
475   for (p1 = 0; p1 < player_globals.p_num; p1++) {
476     if ((p1 == p) || (player_globals.parray[p1].status != PLAYER_PROMPT))
477       continue;
478     if ((player_is_observe(p1, g) || player_globals.parray[p1].game == g
479          || (game_globals.garray[g].link >= 0
480              && (player_is_observe(p1, game_globals.garray[g].link)
481                  || player_globals.parray[p1].game == game_globals.garray[g].link)))
482         && CheckPFlag(p1, PFLAG_KIBITZ)) {
483       tell(p, p1, param[0].val.string, TELL_KIBITZ, 0);
484       if ((pp->adminLevel >= ADMIN_ADMIN) || 
485           !game_globals.garray[g].private || (player_globals.parray[p1].game == g) || !player_censored(p1, p))
486         count++;
487     }
488   }
489   pprintf(p, "kibitzed to %d.\n", count);
490   return COM_OK;
491 }
492
493 /* 
494    like tell() but takes a player name
495 */
496 static int tell_s(int p, const char *who, const char *msg, int why, int ch)
497 {
498         int p1;
499
500         p1 = player_find_part_login(who);
501         if ((p1 < 0) || (player_globals.parray[p1].status == PLAYER_PASSWORD)
502             || (player_globals.parray[p1].status == PLAYER_LOGIN)) {
503                 if (why != TELL_LTELL) {
504                         pprintf(p, "No user named '%s' is logged in.\n", who);
505                 }
506                 return COM_OK;
507         }
508
509         return tell(p, p1, msg, why, ch);
510 }
511
512 int com_tell(int p, param_list param)
513 {
514         struct player *pp = &player_globals.parray[p];
515         char *who;
516
517         if (param[0].type == TYPE_NULL)
518                 return COM_BADPARAMETERS;
519         if (param[0].type != TYPE_WORD) {
520                 return chtell(p, param[0].val.integer, param[1].val.string);
521         }
522
523         who = param[0].val.word;
524         stolower(who);
525
526         if (strcmp(who, ".") == 0) {
527                 if (!pp->last_tell) {
528                         pprintf(p, "No previous tell.\n");
529                         return COM_OK;
530                 }
531                 who = pp->last_tell;
532         }
533
534         if (strcmp(who, ",") == 0) {
535                 if (pp->last_channel == -1) {
536                         pprintf(p, "No previous channel.\n");
537                         return COM_OK;
538                 }
539                 return chtell(p, pp->last_channel, param[1].val.string);
540         }
541
542         return tell_s(p, who, param[1].val.string, TELL_TELL, 0);
543 }
544
545
546 /* tell all players in a named list */
547 int com_ltell(int p, param_list param)
548 {
549         struct List *gl;
550         int i;
551
552         gl = list_findpartial(p, param[0].val.word, 0);
553         if (!gl) {
554                 pprintf(p,"Can't find that list\n");
555                 return COM_OK;
556         }
557         
558         for (i=0;i<gl->numMembers;i++) {
559                 tell_s(p, gl->m_member[i], param[1].val.string, TELL_LTELL, 0);
560         }
561         
562         return COM_OK;
563 }
564
565
566 int com_xtell(int p, param_list param)
567 {
568   struct player *pp = &player_globals.parray[p];
569   int p1;
570   char *msg, tmp[2048];
571   
572   msg = param[1].val.string;
573   p1 = player_find_part_login(param[0].val.word);
574   if ((p1 < 0) || (player_globals.parray[p1].status == PLAYER_PASSWORD)
575       || (player_globals.parray[p1].status == PLAYER_LOGIN)) {
576     pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
577     return COM_OK;
578   }
579   if (!printablestring(msg)) {
580     pprintf(p, "Your message contains some unprintable character(s).\n");
581     return COM_OK;
582   }
583   if (!CheckPFlag(p1, PFLAG_TELL) && !CheckPFlag(p, PFLAG_REG)) {
584     pprintf(p, "Player \"%s\" isn't listening to unregistered tells.\n",
585             player_globals.parray[p1].name);
586     return COM_OK;
587   }
588   if ((player_censored(p1, p)) && (pp->adminLevel == 0)) {
589     pprintf(p, "Player \"%s\" is censoring you.\n", player_globals.parray[p1].name);
590     return COM_OK;
591   }
592   if (player_globals.parray[p1].highlight)
593     pprintf_highlight(p1, "\n%s", pp->name);
594   else
595     pprintf(p1, "\n%s", pp->name);
596   
597   pprintf_prompt(p1, " tells you: %s\n", msg);
598
599   tmp[0] = '\0';
600   if (!(player_globals.parray[p1].busy == NULL))
601     sprintf(tmp, ", who %s (idle: %s)", player_globals.parray[p1].busy,
602             hms_desc(player_idle(p1)));
603   else
604     if (((player_idle(p1) % 3600) / 60) > 2)
605       sprintf(tmp, ", who has been idle %s", hms_desc(player_idle(p1)));
606   
607   pprintf(p, "(told %s%s)\n", player_globals.parray[p1].name,
608           (((player_globals.parray[p1].game>=0) && (game_globals.garray[player_globals.parray[p1].game].status == GAME_EXAMINE)) 
609            ? ", who is examining a game" : 
610            ((player_globals.parray[p1].game>=0) && (game_globals.garray[player_globals.parray[p1].game].status == GAME_SETUP))
611            ? ", who is setting up a position" :
612            (player_globals.parray[p1].game >= 0 && (player_globals.parray[p1].game != pp->game))
613            ? ", who is playing" : tmp));
614   return COM_OK;
615 }
616
617 int com_say(int p, param_list param)
618 {
619         struct player *pp = &player_globals.parray[p];
620         if (pp->opponent < 0) {
621                 if (!pp->last_opponent) {
622                         pprintf(p, "No one to say anything to, try tell.\n");
623                         return COM_OK;
624                 }
625                 return tell_s(p, pp->last_opponent, param[0].val.string, TELL_SAY, 0);
626         }
627         return tell(p, pp->opponent, param[0].val.string, TELL_SAY, 0);
628 }
629
630 int com_inchannel(int p, param_list param)
631 {
632   int p1,count = 0;
633   char tmp[18];
634
635   if (param[0].type == TYPE_NULL) {
636     pprintf (p,"inchannel [no params] has been removed\n");
637     pprintf (p,"Please use inchannel [name] or inchannel [number]\n");
638     return COM_OK;
639   }
640
641   if (param[0].type == TYPE_WORD) {
642     p1 = player_find_part_login(param[0].val.word);
643     if ((p1 < 0) || (player_globals.parray[p1].status != PLAYER_PROMPT)) {
644       pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
645       return COM_OK;
646     }
647     pprintf (p,"%s is in the following channels:",player_globals.parray[p1].name); 
648     if (list_channels (p,p1))
649       pprintf (p," No channels found for %s.\n",player_globals.parray[p1].name);
650     return COM_OK;
651   } else if (param[0].val.integer >= MAX_CHANNELS) {
652     pprintf (p, "No such channel; the largest channel number is %d.\n",
653                  MAX_CHANNELS - 1);
654     return COM_OK;
655   } else {
656     sprintf (tmp,"%d",param[0].val.integer);
657     for (p1 = 0; p1 < player_globals.p_num; p1++) {
658       if (player_globals.parray[p1].status != PLAYER_PROMPT)
659         continue;
660       if (in_list(p1,L_CHANNEL,tmp)) {
661         if (!count)
662           pprintf(p,"Channel %d:",param[0].val.integer);
663         pprintf (p," %s", player_globals.parray[p1].name);
664         if ((player_globals.parray[p1].adminLevel >= 10)
665             && CheckPFlag(p1, PFLAG_ADMINLIGHT)
666             && (param[0].val.integer < 2))
667           pprintf(p, "(*)");
668         count++;
669       } 
670     }
671     if (!count)
672       pprintf(p,"Channel %d is empty.\n",param[0].val.integer);
673     else
674       pprintf (p,"\n%d %s in channel %d.\n",count,(count == 1 ? "person is" : "people are"),param[0].val.integer);
675     return COM_OK;
676   }
677 }
678
679 static int com_sendmessage(int p, param_list param)
680 {
681   struct player *pp = &player_globals.parray[p];
682   int p1, connected = 1;
683   
684   if (!CheckPFlag(p, PFLAG_REG)) {
685     pprintf(p, "You are not registered and cannot send messages.\n");
686     return COM_OK;
687   }
688   
689   if (!FindPlayer(p, param[0].val.word, &p1, &connected))
690     return COM_OK;
691   
692   if (!CheckPFlag(p1, PFLAG_REG)) {
693     pprintf(p, "Player \"%s\" is unregistered and cannot receive messages.\n",
694             player_globals.parray[p1].name);
695     return COM_OK;
696   }
697   
698   if ((player_censored(p1, p)) && (pp->adminLevel == 0)) {
699     pprintf(p, "Player \"%s\" is censoring you.\n", player_globals.parray[p1].name);
700     if (!connected)
701       player_remove(p1);
702     return COM_OK;
703   }
704   if (player_add_message(p1, p, param[1].val.string)) {
705     pprintf(p, "Couldn't send message to %s. Message buffer full.\n",
706             player_globals.parray[p1].name);
707   } else {
708     if (connected) {
709       pprintf(p1, "\n%s just sent you a message:\n", pp->name);
710       pprintf_prompt(p1, "    %s\n", param[1].val.string);
711     } 
712   }
713   if (!connected)
714     player_remove(p1);
715   return COM_OK;
716 }
717
718 int com_messages(int p, param_list param)
719 {
720   int start;
721   
722   if (!CheckPFlag(p, PFLAG_REG)) {
723     pprintf (p, "Unregistered players may not send or receive messages.\n");
724     return COM_OK;
725   }
726   if (param[0].type == TYPE_NULL) {
727     player_show_messages (p);
728   } else if (param[0].type == TYPE_WORD) {
729     if (param[1].type != TYPE_NULL)
730       return com_sendmessage(p, param);
731     else ShowMsgsBySender(p, param);
732   } else {
733     start = param[0].val.integer;
734     ShowMsgRange (p, start, start);
735   }
736   return COM_OK;
737 }
738
739 int com_forwardmess(int p, param_list param)
740 {
741   if (!CheckPFlag(p, PFLAG_REG)) {
742     pprintf (p, "Unregistered players may not send or receive messages.\n");
743     return COM_OK;
744   }
745   
746   ForwardMsgRange(param[0].val.word, p, param[1].val.integer, param[1].val.integer);
747
748   return COM_OK;
749 }
750
751 int com_clearmessages(int p, param_list param)
752 {
753   if (player_num_messages(p) <= 0) {
754     pprintf(p, "You have no messages.\n");
755     return COM_OK;
756   }
757   if (param[0].type == TYPE_NULL) {
758     pprintf(p, "Messages cleared.\n");
759     player_clear_messages(p);
760   } else if (param[0].type == TYPE_WORD)
761     ClearMsgsBySender(p, param);
762   else if (param[0].type == TYPE_INT)
763     ClrMsgRange (p, param[0].val.integer, param[0].val.integer);
764
765   return COM_OK;
766 }
767
768 int com_znotify(int p, param_list param)
769 {
770   int p1, count = 0;
771   
772   for (p1 = 0; p1 < player_globals.p_num; p1++) {
773     if (player_notified(p, p1) && player_globals.parray[p1].status == PLAYER_PROMPT) {
774       if (!count)
775         pprintf(p, "Present company on your notify list:\n  ");
776       pprintf(p, " %s", player_globals.parray[p1].name);
777       count++;
778     }
779   }
780   if (!count)
781     pprintf(p, "No one from your notify list is logged on.");
782   pprintf(p, "\n");
783   
784   count = 0;
785   for (p1 = 0; p1 < player_globals.p_num; p1++) {
786     if (player_notified(p1, p) && player_globals.parray[p1].status == PLAYER_PROMPT) {
787       if (!count)
788         pprintf(p,
789                 "The following players have you on their notify list:\n  ");
790       pprintf(p, " %s", player_globals.parray[p1].name);
791       count++;
792     }
793   }
794   if (!count)
795     pprintf(p, "No one logged in has you on their notify list.");
796   pprintf(p, "\n");
797
798   return COM_OK;
799 }
800
801 int com_qtell(int p, param_list param)
802 {
803   struct player *pp = &player_globals.parray[p];
804   int p1;
805   char tmp[MAX_STRING_LENGTH];
806   char dummy[2];
807   char buffer1[MAX_STRING_LENGTH];      /* no highlight and no bell */
808   char buffer2[MAX_STRING_LENGTH];      /* no highlight and bell */
809   char buffer3[MAX_STRING_LENGTH];      /* highlight and no bell */
810   char buffer4[MAX_STRING_LENGTH];      /* highlight and and bell */
811   int i,count;
812   
813   if (!in_list(p, L_TD, pp->name)) {
814     pprintf(p, "Only TD programs are allowed to use this command.\n");
815     return COM_OK;
816   }
817   strcpy(buffer1, ":\0");
818   strcpy(buffer2, ":\0");
819   strcpy(buffer3, ":\0");
820   strcpy(buffer4, ":\0");
821   
822   sprintf(tmp, "%s", param[1].val.string);
823   for (i = 0, count = 0; ((tmp[i] != '\0') && (count < 1029));) {
824     if ((tmp[i] == '\\') && (tmp[i + 1] == 'n')) {
825       strcat(buffer1, "\n:");
826       strcat(buffer2, "\n:");
827       strcat(buffer3, "\n:");
828       strcat(buffer4, "\n:");
829       count += 2;
830       i += 2;
831     } else if ((tmp[i] == '\\') && (tmp[i + 1] == 'b')) {
832       strcat(buffer2, "\007");
833       strcat(buffer4, "\007");
834       count++;
835       i += 2;
836     } else if ((tmp[i] == '\\') && (tmp[i + 1] == 'H')) {
837       strcat(buffer3, "\033[7m");
838       strcat(buffer4, "\033[7m");
839       count += 4;
840       i += 2;
841     } else if ((tmp[i] == '\\') && (tmp[i + 1] == 'h')) {
842       strcat(buffer3, "\033[0m");
843       strcat(buffer4, "\033[0m");
844       count += 4;
845       i += 2;
846     } else {
847       dummy[0] = tmp[i];
848       dummy[1] = '\0';
849       strcat(buffer1, dummy);
850       strcat(buffer2, dummy);
851       strcat(buffer3, dummy);
852       strcat(buffer4, dummy);
853       count++;
854       i++;
855     }
856   }
857
858   if (param[0].type == TYPE_WORD) {
859     if ((p1 = player_find_bylogin(param[0].val.word)) < 0) {
860       pprintf(p, "*qtell %s 1*\n", param[0].val.word);
861       return COM_OK;
862     }
863     pprintf_prompt(p1, "\n%s\n", (player_globals.parray[p1].highlight && CheckPFlag(p1, PFLAG_BELL)) ? buffer4 :
864                    (player_globals.parray[p1].highlight && !CheckPFlag(p1, PFLAG_BELL)) ? buffer3 :
865                    (!player_globals.parray[p1].highlight && CheckPFlag(p1, PFLAG_BELL)) ? buffer2 :
866                    buffer1);
867     pprintf(p, "*qtell %s 0*\n", player_globals.parray[p1].name);
868
869   } else {
870     int p1;
871     int ch = param[0].val.integer;
872
873     if (ch == 0) {
874       pprintf(p, "*qtell %d 1*\n", param[0].val.integer);
875       return COM_OK;
876     }
877     if (ch < 0) {
878       pprintf(p, "*qtell %d 1*\n", param[0].val.integer);
879       return COM_OK;
880     }
881     if (ch >= MAX_CHANNELS) {
882       pprintf(p, "*qtell %d 1*\n", param[0].val.integer);
883       return COM_OK;
884     }
885     sprintf (tmp,"%d",param[0].val.integer);
886     for (p1 = 0; p1 < player_globals.p_num ; p1++) {
887       if ((p1 == p) || (player_censored(p1, p)) || (player_globals.parray[p1].status != PLAYER_PROMPT))
888         continue;
889       if (in_list(p1,L_CHANNEL,tmp))
890         pprintf_prompt(p1, "\n%s\n", (player_globals.parray[p1].highlight && CheckPFlag(p1, PFLAG_BELL)) ? buffer4 :
891                      (player_globals.parray[p1].highlight && !CheckPFlag(p1, PFLAG_BELL)) ? buffer3 :
892                      (!player_globals.parray[p1].highlight && CheckPFlag(p1, PFLAG_BELL)) ? buffer2 :
893                      buffer1);
894     }
895     pprintf(p, "*qtell %d 0*\n", param[0].val.integer);
896   }
897   return COM_OK;
898 }
899
900 static int on_channel(int ch, int p)
901 {
902         char tmp[10];  /* 9 digits ought to be enough :) */
903
904         sprintf (tmp,"%d",ch);
905         return in_list(p, L_CHANNEL,tmp);  /* since needs ch converted to a string
906                                               kept hidden from view */
907 }