Preconfigure admin as TM for mamer in the distribution
[capablanca.git] / lasker-2.2.3 / bots / mamer / CommandEntry.cc
1 //--------------------------------------------------------------------------
2 // CommandEntry.cc - Source file for the CommandEntry
3 //
4 // Matthew E. Moses & Michael A. Long
5 //
6 // $Log: CommandEntry.cc,v $
7 // Revision 1.15  2002/07/02 00:05:19  tridge
8 // got rid of a bunch of RCS tags now that its in CVS
9 //
10 // Revision 1.14  2002/07/02 00:02:40  tridge
11 // - fixed compile on g++ 2.96
12 // - updated for lasker 'rmatch'
13 //
14 // Revision 1.13  1998/09/10 19:57:17  mlong
15 // lots of little bug fixes and a few new features
16 //
17 // Revision 1.12  1998/06/18 18:41:30  mlong
18 // prepairing for yet another move.
19 //
20 // Revision 1.11  1998/06/08 20:41:17  mlong
21 // changes to the list tournies function
22 //
23 // Revision 1.10  1998/04/29 15:23:19  mlong
24 // prepairing for the move to daimi
25 // new sorting routine.
26 //
27 // Revision 1.9  1998/04/18 18:46:04  mlong
28 // fixed delete bug &
29 // added delete tourney function
30 //
31 // Revision 1.5  1997/10/08 21:03:35  chess
32 // preparing for move to oracle machine at eworks.
33 //
34 // Revision 1.4  1997/05/15 18:27:53  chess
35 // added Player and TourneyPlayers support
36 // added HandleGetPlayerInfo & HandleGetGameInfo
37 //
38 // Revision 1.3  1997/04/13 03:14:35  chess
39 // commands to do user statistic manipulationn added:
40 // setinfo - sets a whole line of information
41 // setstat - sets a particular stat
42 // addabuse - adds (or deletes) abuse points.
43 //
44 // Revision 1.2  1997/03/21 15:32:36  moses
45 // added the shutdown command.
46 //
47 // Revision 1.1  1996/10/01  20:14:43  moses
48 // Initial revision
49 //
50 //--------------------------------------------------------------------------
51
52 #include "CommandEntry.hh"
53 #include "Mamer.hh"
54
55 extern Mamer gMamer;
56
57 //- AddAbuse -------------------------------------------------------
58 int CommandEntry::AddAbuse(User *user, param_list params) {
59     User *u = NULL;
60     char name[MAX_WORD_SIZE];
61     int needToDelete=0;
62
63     if(params[0].type == TYPE_WORD) {
64       strcpy(name, params[0].val.word);
65     }
66     
67     u = gMamer.FindUser(name);
68     if(u == NULL) {
69       u = new User();
70       u->LoadPlayer(gMamer.userFilePath, name);  // Loads the player info into memory and saves current info to disk
71       needToDelete = 1;
72     }
73     
74     if((u->GetManagerLevel() >= user->GetManagerLevel()) &&
75        (user->GetManagerLevel() != PRESIDENT)) {
76       if(needToDelete) delete u;
77       gMamer.TellUser(NoPermissions, user->name);
78       return 0;
79     }
80
81     if(u != NULL) {
82       if(params[1].type == TYPE_INT) {
83         u->AddAbuse(params[1].val.integer);
84       } else {
85         u->AddAbuse(10);
86       }
87       u->SavePlayer(gMamer.userFilePath);
88       if(u->GetAbuse() >= MAX_CHAOS_POINTS)
89         gMamer.XServerCom("%s %s%s", "+ censor", u->name, "\n");
90       gMamer.TellUser(ChangedAbuse, user->name, u->name, u->GetAbuse());
91     } else {
92       gMamer.TellUser(NotFound, user->name, name);
93     }
94     if(needToDelete) delete u;
95
96     return(1);
97 } //- End of AddAbuse
98
99 //- FingerUser -------------------------------------------------------
100 int CommandEntry::FingerUser(User *user, param_list params) {
101     User *u = NULL;
102     int notFound=1;
103     char name[32];
104
105     memset(name, '\0', 32);
106     if(params[0].type == TYPE_WORD) {
107       strncpy(name, params[0].val.word, MIN(31, (int)strlen(params[0].val.word)));
108     } else {
109       strcpy(name, user->name);
110     }
111     
112     u = gMamer.FindUser(name);
113     if(u != NULL) notFound = 0;
114     
115     if(notFound) { 
116       u = new User();
117       notFound = u->LoadPlayer(gMamer.userFilePath, name);
118       notFound = !notFound;
119     }
120     if(!notFound) {
121       gMamer.XServerCom("%s %s %s%s%s", "qtell", user->name, "\\n", u->name, "'s Stats:\\n\\n");
122       gMamer.XServerCom("%-17s %5s %4s %4s %3s %3s %3s %3s %5s %6s%-17s %4s %3s %3s %3s %3s %3s %3s %5s %6s",
123                         "Name", " Tnys", "  W ", "  L ", " D ", "1st", "2nd", "3rd", "Chaos", "Rating\\n",
124                         "-----------------", "-----", "----", "----", "---", "---", "---", "---", "-----","------\\n");
125       gMamer.XServerCom("%-17s %5ld %4ld %4ld %3ld %3ld %3ld %3ld %5d %6.2f %s",
126                         u->name, u->GetPlayedTourneys(), u->GetWins(), u->GetLosses(), u->GetDraws(),
127                         u->GetFirsts(), u->GetSeconds(), u->GetThirds(), u->GetAbuse(), u->GetRating(), "\\n");
128       if(u->GetManagerLevel() > USER) {
129         gMamer.XServerCom("%s %d %s %d %s", "\\nManager Level:", u->GetManagerLevel(), 
130                                             "    Managed Tourneys:", u->GetManagedTourneys(), "\\n");
131       }
132       gMamer.XServerCom("%s", "\n");
133     } else {
134       gMamer.TellUser(NotFound, user->name, name);
135     }
136     if(notFound) delete u;
137
138     return(1);
139 } //- End of FingerUser
140
141 //- ListRank ----------------------------------------------------------
142 int CommandEntry::ListRank(User *user, param_list params) {
143   float rating=0;
144   int start=0, i=0, end=0, tourneys=0, counter=0;
145   char filename[128], name[32], name2[32];
146   FILE *theFile;
147
148   memset(name, '\0', 32);
149   memset(name2, '\0', 32);
150   switch (params[0].type) {
151   case TYPE_WORD:
152     strcpy(name, params[0].val.word);
153     break;
154   case TYPE_INT:
155     start = params[0].val.integer;
156     if(start <= 0) {start = 1;}
157     break;
158   default:
159     strcpy(name, user->name);
160     break;
161   }
162   
163   sprintf(filename, "%s/rank", gMamer.dataFilePath);
164   if(params[0].type != TYPE_INT) {
165     if((theFile = fopen(filename, "r"))) {
166       while(fscanf(theFile, "%s %d %f", name2, &tourneys, &rating) > 0) {
167         if(!(strncasecmp(name2, name, strlen(name)))) {
168           start = i+1;
169           break;
170         }
171         i++;
172       }
173       fclose(theFile);
174     } else {
175       gMamer.TellUser(NotFound, user->name, filename);
176       return(0);
177     }
178   }
179   if(!(start)) {
180     gMamer.TellUser(NotFound, user->name, name);
181     return(1);
182   }
183   start = start - 10;
184   end = start + 20;
185   if(start <= 0) {start = 1; end = 21;}
186   gMamer.XServerCom("%s %s %s %s%s %-5s %-18s %5s %6s %5s %-18s %5s %6s", "qtell", user->name, "\\n", gMamer.username, 
187                     "'s Rankings:\\n\\n", "Rank", "Name", "Trnys", "Rating\\n", 
188                     "-----", "------------------", "-----", "------\n");
189   gMamer.XServerCom("%s %s %s", "qtell", user->name, "\\n");
190   if(!(theFile = fopen(filename, "r"))) { return(0); }
191   i = 1; counter = 1;
192   while(fscanf(theFile, "%s %d %f", name2, &tourneys, &rating) > 0) {
193     if((i >= start) && (i < end)) {
194       if(i == start) { counter = 1; }
195       gMamer.XServerCom(" %-5d %-18s %5d %6.2f\\n", i, name2, tourneys, rating);
196       if(((counter % 10) == 0) && (counter > 0)) {
197         gMamer.XServerCom("%s", "\n");
198         if(i != (end -1)) {
199           gMamer.XServerCom("%s %s %s", "qtell", user->name, "\\n");
200         }
201       }
202     }
203     if(i > end) { break; }
204     i++; counter++;
205   }
206   fclose(theFile);
207   
208   if(i <= end) { gMamer.XServerCom("%s", "\n"); }
209
210   return(1);
211 }
212
213 //- ListManagers ------------------------------------------------------
214 int CommandEntry::ListManagers(User *user, param_list params) {
215     int i=1, needToDelete=0;
216     long last;
217     char filename[256], manager[NAMELEN], date[16];
218     User *u=NULL, *newUser = NULL;
219     struct tm *tmpDate;
220     FILE *theFile;
221
222     i = params[0].type; // just to get rid of the compiler messages
223     sprintf(filename, "%s/managers", gMamer.dataFilePath);
224     if((theFile = fopen(filename, "r"))) {
225       gMamer.XServerCom("%s %s %s %s%s", "qtell", user->name, "\\n", gMamer.username, "'s Manager List:\\n\\n");
226       gMamer.XServerCom("%2s%-18s %3s %4s %-8s%2s%-18s %3s %4s %-8s%s",
227                         "","Name","Lvl","Tnys","Last", "","Name","Lvl","Tnys","Last", "\\n");
228       gMamer.XServerCom("  %-18s %3s %4s %-8s%2s%-18s %3s %4s %-8s%s",
229                         "-----------------", "---", "----", "--------", "",
230                         "-----------------", "---", "----", "--------", "", "\\n");
231       i=1;
232       memset(date, '\0', 64);
233       gMamer.XServerCom("\n%s %s ", "qtell", user->name);
234       while(fscanf(theFile, "%s", manager) > 0) {
235         needToDelete = 0;
236         u = gMamer.FindUser(manager);
237         if(u == NULL) {
238           needToDelete = 1;
239           newUser = new User();
240           u = newUser;
241         }
242         if(0 != u->LoadPlayer(gMamer.userFilePath, manager)) {
243           last = u->GetLast();
244           if(last) {
245             tmpDate = localtime(&last);   
246             sprintf(date, "%02d/%02d/%02d", tmpDate->tm_mon+1, tmpDate->tm_mday, tmpDate->tm_year);
247           } else {
248             sprintf(date, "none");
249           }
250         } else {
251           sprintf(date, "%s", "none");
252         }
253         gMamer.XServerCom("%2s%-18s %3d %4d %8s%s",
254                           ((gMamer.UserIsLoaded(manager)) ? "+" : " "),
255                           manager, u->GetManagerLevel(), u->GetManagedTourneys(), date, (i%2)==0 ? "\\n":"");
256         if(((i % 20) == 0) && (i > 0)) {
257           i = 0;
258           gMamer.XServerCom("%s %s %s %s", "\n", "qtell", user->name, "\\n");
259         }
260         i++;
261         if(needToDelete) {
262           u = NULL;
263           delete(newUser);        
264         }
265       }
266       fclose(theFile);
267       gMamer.XServerCom("%s", "\n");
268       
269       return(1);
270     }    
271     gMamer.TellUser(NotFound, user->name, filename);
272     return(0);
273 }
274
275 //- LoadedUsers -------------------------------------------------------
276 int CommandEntry::LoadedUsers(User *user, param_list params) {
277   User *u = NULL;
278   LinkListIter<User> userIter(gMamer.userList);
279   int i, count=0;
280   
281   i = params[0].type;
282   i = 1;
283   
284   gMamer.XServerCom("qtell %s \\nLoaded Users:\\n\\n", user->name);
285   while((u = userIter.Next())) {
286     count++;
287     gMamer.XServerCom("  %18s%s", u->name, (i%3)==0 ? "\\n":"");
288     if(((i % 30) == 0) && (i > 0)) {
289       i = 0;
290       gMamer.XServerCom("%s %s %s %s", "\n", "qtell", user->name, "\\n");
291     }    
292     i++;
293   }
294   gMamer.XServerCom("%sTotal: %i%s", "\\n", count, "\n");
295   
296   return(1);
297 } //- End of LoadedUser
298
299 //- SetCommandLevel ----------------------------------------------------
300 int CommandEntry::SetCommandLevel(User *user, param_list params) {
301   Command *c = NULL;
302
303   c = gMamer.FindCommand(params[0].val.word, user->name);
304
305   if(c != NULL) {
306     if((c->GetManagerLevel() <= user->GetManagerLevel()) && 
307        (params[1].val.integer <= user->GetManagerLevel())) {
308       c->SetManagerLevel((ranks)params[1].val.integer);
309       gMamer.TellUser(ChangedCommandLevel, user->name, params[0].val.word, params[1].val.integer);
310     } else
311       gMamer.TellUser(NoPermissions, user->name);
312   } else 
313     return 0;
314   
315   return 1;
316 }
317
318 //- SetInfo -------------------------------------------------------
319 int CommandEntry::SetInfo(User *user, param_list params) {
320     User *u = NULL;
321     int notFound=1, i;
322     char name[32];
323
324     memset(name, '\0', 32);
325     if(params[0].type == TYPE_WORD) { 
326       strncpy(name, params[0].val.word, MIN(31, (int)strlen(params[0].val.word))); 
327     }
328
329     u = gMamer.FindUser(name);
330     if(u != NULL) notFound = 0;
331
332     if(notFound) {
333       u = new User();
334       u->LoadPlayer(gMamer.userFilePath, name);
335     }
336
337     if(u != NULL) {
338       if((u->GetManagerLevel() >= user->GetManagerLevel()) &&
339          (user->GetManagerLevel() != PRESIDENT)) {
340         if(notFound) delete u;
341         gMamer.TellUser(NoPermissions, user->name);
342         return 0;
343       }
344       for(i=1; i<=7; i++)
345         u->SetStatistic(i, params[i].val.integer);
346       u->SavePlayer(gMamer.userFilePath);
347       gMamer.TellUser(ChangedInfo, user->name, u->name);
348     } else {
349       gMamer.TellUser(NotFound, user->name, name);
350     }
351     if(notFound) delete u;
352
353     return(1);
354 } //- End of SetInfo
355
356 //- SetManagerLevel -------------------------------------------------------
357 int CommandEntry::SetManagerLevel(User *user, param_list params) {
358   User *u = NULL;
359   int notFound=1, new_level=1, length=0, i=0;
360   char name[32];
361   
362   if(params[0].type == TYPE_WORD) { 
363     length = strlen(params[0].val.word);
364     memset(name, '\0', 32);
365     while((i < 31) && (i < length)) {
366       name[i] = tolower(params[0].val.word[i]);
367       i++;
368     }
369   }
370   new_level = params[1].val.integer;
371   
372   u = gMamer.FindUser(name);
373   if(u != NULL) notFound = 0;
374   
375   if(notFound) {
376     u = new User();
377     u->LoadPlayer(gMamer.userFilePath, name);
378   }
379   if(((u->GetManagerLevel() >= user->GetManagerLevel()) ||
380       (new_level >= user->GetManagerLevel())) &&
381      (user->GetManagerLevel() != PRESIDENT)) {
382     if(notFound) delete u;
383     gMamer.TellUser(NoPermissions, user->name);
384     return 0;
385   }
386
387   if(u != NULL) {
388     u->ChangeManagerLevel(new_level);
389     u->SavePlayer(gMamer.userFilePath);
390     gMamer.TellUser(ChangedManagerLevel, user->name, u->name, new_level);
391   } else {
392     gMamer.TellUser(NotFound, user->name, name);
393   }
394   if(notFound) delete u;
395   
396   if(new_level > 0)
397     return(1);
398   else
399     return -1;
400 } //- End of SetManagerLevel
401
402
403 //- SetStat -------------------------------------------------------
404 int CommandEntry::SetStat(User *user, param_list params) {
405     User *u = NULL;
406     int notFound=1, new_value, i, ret=0, size=0, counter=0;
407     char which_stat[64], name[32];
408     strings statAliases[] = {
409       {"tourneys", 1}, {"tnys", 1},
410       {"wins", 2},
411       {"losses", 3}, {"lose", 3},
412       {"draws", 4},
413       {"firsts", 5}, {"1sts", 5},
414       {"seconds", 6}, {"2nds", 6},
415       {"thirds", 7}, {"3rds", 7},
416       {"abuse", 8}, 
417       {"rating", 9},
418       {"managedtourneys", 10},
419       {NULL}
420     };
421
422     memset(which_stat, '\0', 64);
423     if(params[0].type == TYPE_WORD) { strcpy(name, params[0].val.word); }
424     if(params[1].type == TYPE_WORD) { strncpy(which_stat, params[1].val.word, MIN(63, strlen(params[1].val.word))); }    
425     size = strlen(which_stat);
426     new_value = params[2].val.integer;
427
428     u = gMamer.FindUser(name);
429     if(u != NULL) notFound = 0;    
430
431     if(notFound) { 
432       u = new User(); 
433       u->LoadPlayer(gMamer.userFilePath, name);
434     }
435     if(u != NULL) {
436       if((u->GetManagerLevel() >= user->GetManagerLevel()) &&
437          (user->GetManagerLevel() != PRESIDENT)) {
438         if(notFound) delete u;
439         gMamer.TellUser(NoPermissions, user->name);
440         return 0;
441       }
442       i=0;
443       while(statAliases[i].string != NULL) {
444         if (!(strncasecmp(statAliases[i].string, which_stat, MIN(size, (int)strlen(statAliases[i].string))))) {
445           counter++;
446           if(counter > 1) break;
447         }       
448         i++;
449       }
450       if(counter > 1) {
451         gMamer.TellUser(CanNotChange, user->name, u->name, which_stat, new_value);
452       } else if(counter == 0) {
453         gMamer.TellUser(NotFound, user->name, which_stat);
454       } else {
455         i=0;
456         while(statAliases[i].string != NULL) {
457           if (!(strncasecmp(statAliases[i].string, which_stat, MIN(size, (int)strlen(statAliases[i].string))))) {
458             ret = u->SetStatistic(statAliases[i].number, new_value);
459             memset(which_stat, '\0', 64);
460             strcpy(which_stat, statAliases[i].string);
461             break;
462           }
463           i++;
464         }
465         u->SavePlayer(gMamer.userFilePath);
466         if(ret)
467           gMamer.TellUser(ChangedInfo, user->name, u->name, which_stat, new_value);
468         else 
469           gMamer.TellUser(NotFound, user->name, which_stat);
470       }
471     } else {
472       gMamer.TellUser(NotFound, user->name, name);
473     }
474     if(notFound) delete u;
475
476     return(1);
477 } //- End of SetStat
478
479 //- ShowCommands --------------------------------------------
480 int CommandEntry::ShowCommands(User *user, param_list params) {
481   Command *c = NULL;
482   LinkListIter<Command> commIter(gMamer.commandList);
483   char *command;
484   int i;
485
486   if(params[0].type == TYPE_WORD) {
487     command = params[0].val.word;
488     while((c = commIter.Next())) if(1 == c->IsCommand(command)) break;
489     if(c == NULL) {
490       gMamer.TellUser(NotFound, user->name, command);
491       return 0;
492     }
493     gMamer.XServerCom("qtell %s %s Notes: %-16s | %-5s | %3d | %s \n", 
494             user->name, gMamer.username, c->GetCommandName(), 
495             c->GetCommandAlias(), c->GetManagerLevel(), c->GetCommandDescription());
496     return(1);
497   }
498   gMamer.XServerCom("qtell %s %s's Command List:\\n\\n", user->name, gMamer.username);
499   i = 0;
500   while((c = commIter.Next())) {
501     gMamer.XServerCom(" %-16s | %-5s | %3d | %s\\n",
502             c->GetCommandName(), c->GetCommandAlias(), c->GetManagerLevel(), c->GetCommandDescription());
503     if((!(i % 9)) && (i > 0)) {
504         i = 0;
505         gMamer.XServerCom("%s", "\n");
506         gMamer.XServerCom("qtell %s \\n", user->name);
507     }
508     i++;
509   }
510   gMamer.XServerCom("%s", "\n");
511   return(1);
512 }
513
514 //- ShowHelp -----------------------------------------------
515 int CommandEntry::ShowHelp(User *user, param_list params) {
516   int i=1;
517   char tmpBuffer[1024], request[128], filename[256];
518   FILE *theFile;
519
520   memset(request, '\0', 128);
521   if(params[0].type == TYPE_WORD) { 
522     strcpy(request, params[0].val.word);
523   } else { 
524     strcpy(request, "index"); 
525   }
526   sprintf(filename, "%s/%s", gMamer.helpFilePath, request);
527   if((theFile = fopen(filename, "r"))) {
528     gMamer.XServerCom("qtell %s \\nThe %s Help File:\\n\\n", user->name, request);
529     i=1;
530     memset(filename, '\0', 256);
531     while(fgets(filename, 79, theFile)) {    /* Just reusing the variable filename could be any char [] */      
532       memset(tmpBuffer, '\0', 1024);
533       strcpy(tmpBuffer, gMamer.s_and_r(filename, "\n", "\\n"));
534       gMamer.XServerCom("%s", tmpBuffer);
535       if(((i % 10) == 0) && (i > 0)) {
536         i = 0;
537         gMamer.XServerCom("\nqtell %s \\n", user->name);
538       }
539       i++;
540       memset(filename, '\0', 256);
541     }
542     fclose(theFile);
543     gMamer.XServerCom("\n");
544     
545     return(1);
546   }
547   gMamer.TellUser(NotFound, user->name, request);
548   return(0);
549 }//- End of ShowHelp
550
551 //- CreateTourney ------------------------------------------------------------
552 int CommandEntry::CreateTourney(User *user, param_list params) {
553   Tourney *t = NULL;
554   int num = gMamer.GenerateTourneyNumber();
555
556   params[0].type = params[0].type;  // Just to stop the annoying unused variable messages during compile.
557   t = new Tourney(num, user, &(gMamer.tourneyParams));
558   gMamer.tourneyList.Append(t);
559   gMamer.XServerCom("%s %s %s %d %s", "xtell", user->name, "Created tourney number: ", t->number, "\n");  
560   return(1);
561 }//- End CreateTourney
562
563 //- OpenTourney ------------------------------------------------------------
564 int CommandEntry::OpenTourney(User *user, param_list params) {
565   Tourney *tourn = NULL;
566
567   tourn = gMamer.FindTourney(params[0].val.integer);
568   if(NULL != tourn) {
569     if(tourn->Open()) {
570       tourn->Announce();
571       return(1);
572     }
573   }
574   gMamer.TellUser(NotFound, user->name, "tourney");  
575   return(0);
576 }//- End OpenTourney
577
578 //- AnnounceTourney ----------------------------------------------------------
579 int CommandEntry::AnnounceTourney(User *user, param_list params) {
580   Tourney *tourn = NULL;
581
582   tourn = gMamer.FindTourney(params[0].val.integer);
583   if(NULL != tourn) {
584     if(tourn->GetStatus() == OPEN) {
585       tourn->Announce();
586       return(1);
587     } else {
588       gMamer.TellUser(TourneyNotOpen, user->name, params[0].val.integer);
589       return 0;
590     }
591   } else {
592     gMamer.TellUser(NotFound, user->name, "tourney");  
593     return(0);
594   }
595 }//- AnnounceTourney ---------------------------------------------------------
596
597 //- KeepTourney ------------------------------------------------------------
598 int CommandEntry::KeepTourney(User *user, param_list params) {
599   Tourney *t = NULL;
600
601   t = gMamer.FindTourney(params[0].val.integer);
602   if(NULL != t) {
603     if(params[1].type != TYPE_NULL) 
604       if(params[1].type == TYPE_WORD) {
605         if(strncasecmp("y", params[1].val.word, 1) == 0) {
606           t->SetPersist(1);
607           gMamer.TellUser(WillKeepTourney, user->name, params[0].val.integer);
608         } else {
609           t->SetPersist(0);
610           gMamer.TellUser(NotKeepTourney, user->name, params[0].val.integer);
611         }
612       } else if(params[1].type == TYPE_INT) {
613         t->SetPersist(params[1].val.integer);
614         if(params[1].val.integer)
615           gMamer.TellUser(WillKeepTourney, user->name, params[0].val.integer);
616         else
617           gMamer.TellUser(NotKeepTourney, user->name, params[0].val.integer);
618       } else {
619         gMamer.TellUser(NotFound, user->name, "tourney");  
620         return(0);
621       }
622     return(1);
623   }
624
625   gMamer.TellUser(NotFound, user->name, "tourney");  
626   return(0);
627 }//- End KeepTourney
628
629 //- DeleteTourney ------------------------------------------------------------
630 int CommandEntry::DeleteTourney(User *user, param_list params) {
631   Tourney *t = NULL;
632   TourneyPlayers *tp = NULL;
633
634   t = gMamer.FindTourney(params[0].val.integer);
635   if(NULL != t) {
636     if(t->GetStatus() != DONE) {
637       LinkListIter<TourneyPlayers> playerIter(t->playerList);
638       playerIter.Reset();
639       while((tp = playerIter.Next())) {
640         gMamer.XServerCom("%s %s %d%s", "tournset", tp->name, 0, "\n");
641         gMamer.XServerCom("tell %s Tourney#%d has been deleted.%s", tp->name, t->number, "\n");
642       }
643       gMamer.XServerCom("%s %d %s%d %s", "tell", gMamer.channelNumber, 
644                         "Tourney #", params[0].val.integer, "has been deleted.\n"); 
645     }
646     gMamer.tourneyList.Delete(t);  // delete the tourney
647     return(1);
648   }
649   
650   gMamer.TellUser(NotFound, user->name, "tourney");  
651   return(0);
652 }//- End DeleteTourney
653
654 //- CloseTourney ------------------------------------------------------------
655 int CommandEntry::CloseTourney(User *user, param_list params) {
656   Tourney *tourn = NULL;
657
658   tourn = gMamer.FindTourney(params[0].val.integer);
659   if(NULL != tourn) {
660     if(tourn->GetPlayerCount() >= MINIMUM_PLAYERS) {
661       if(tourn->GetStatus() == OPEN) {      
662         tourn->CloseAndStart();
663         gMamer.XServerCom("qtell %s %s Notes: %s %d %s", 
664                           user->name,gMamer.username,"Tourney #", 
665                           tourn->number, " is now closed.\n");
666         return(1);
667       } else {
668         gMamer.TellUser(TourneyNotOpen, user->name, tourn->number);
669       }
670     } else {
671       gMamer.TellUser(NotEnoughPlayers, user->name, tourn->number);
672     }
673   } else {
674     gMamer.TellUser(TourneyNotFound, user->name, params[0].val.integer);
675   }
676     
677   return(0);
678 }//- End CloseTourney
679
680 int CommandEntry::ListTourneys(User *user, param_list params) {
681   Tourney *t = NULL;
682   LinkListIter<Tourney> tournIter(gMamer.tourneyList);
683   int notourneys = 1, Tstatus=0, i=3;
684   long stDate, enDate, timeNow;
685   struct tm *start, *end;
686   char outStart[128], outEnd[128], outStatus[128];  
687
688   params[0].type = params[0].type;  // Just to stop the annoying unused var messages in compile.
689   while((t = tournIter.Next())) notourneys = 0;
690
691   if(notourneys == 0) {
692     gMamer.XServerCom("qtell %s %s Notes: \\n", user->name, gMamer.username);
693     gMamer.XServerCom(" %3s %3s %3s %4s %3s %2s %4s %9s %6s %-14s %-14s\\n", 
694                       "No.","Rds","Sty", "Time", "Inc", "Md", "Vrnt", "Rtng Rnge", "Status","  Started at  ", "   Ended at   ");
695     gMamer.XServerCom(" %3s %3s %3s %4s %3s %2s %4s %9s %6s %-14s %-14s\\n", 
696                       "---","---","---", "----", "---", "--", "----", "---------", "------","--------------", "--------------");
697     tournIter.Reset();
698     while((t = tournIter.Next())) {
699       stDate = t->GetStartDate();
700       enDate = t->GetEndDate();
701       Tstatus = t->GetStatus();
702       if((Tstatus == DONE) && (t->GetPersist() == 0)){
703         timeNow = time(0);
704         if((timeNow - enDate) > KEEP_TOURNEY_TIME) {
705           gMamer.tourneyList.Delete(t);
706           continue;
707         }
708       }
709       if(stDate > 0) {
710         start = localtime(&stDate);
711         sprintf(outStart, "%02d:%02d %02d/%02d/%02d", 
712                 start->tm_hour, start->tm_min, start->tm_mon+1, start->tm_mday, start->tm_year);
713       } else { strcpy(outStart, "n/a"); }      
714       if(enDate > 0) {
715         end = localtime(&enDate);
716         sprintf(outEnd, "%02d:%02d %02d/%02d/%02d", 
717                 end->tm_hour, end->tm_min, end->tm_mon+1, end->tm_mday, end->tm_year);
718       } else { strcpy(outEnd, "n/a"); }
719       if(Tstatus == NEW)
720         sprintf(outStatus, "%s", "new");
721       else if(Tstatus == OPEN) 
722         sprintf(outStatus, "%s", "open");
723       else if(Tstatus == CLOSED)
724         sprintf(outStatus, "%s", "closed");
725       else if(Tstatus == DONE)
726         sprintf(outStatus, "%s", "done");
727       else
728         memset(outStatus, '\0', 128);
729
730       gMamer.XServerCom(" %3d %3d %3c %4d %3d %2c %4c %4d-%4d %6s %-14s %-14s\\n", 
731                         t->number, t->params.rounds, t->params.style, t->params.time, t->params.inc, 
732                         t->params.mode, t->params.variant, t->params.ratingLow, t->params.ratingHigh, 
733                         outStatus, outStart, outEnd);
734       if(((i % 12) == 0) && (i > 0)) {
735         i = 0;
736         gMamer.XServerCom("%s %s %s %s", "\n", "qtell", user->name, "\\n");
737       }
738       i++;      
739     }
740     gMamer.XServerCom("%s", "\n");
741   } else {
742     gMamer.XServerCom("qtell %s %s Notes: %s", user->name, gMamer.username, "No tourneys right now.\n");    
743   }
744
745   return (1);
746 }
747
748 //- JoinTourney ------------------------------------------------------------
749 int CommandEntry::JoinTourney(User *user, param_list params) {
750   Tourney *tourn = NULL;
751   Player *newEntry = NULL;
752
753   tourn = gMamer.FindTourney(params[0].val.integer);
754   
755   if(NULL != tourn) {    
756     newEntry = new Player(user->name, params[0].val.integer);
757     gMamer.pendingList.Append(newEntry);
758     gMamer.XServerCom("getpi %s%s", user->name, "\n");
759     return(1);
760   }
761
762   gMamer.TellUser(TourneyNotFound, user->name, params[0].val.integer);
763   return(0);
764 }
765
766 //- AddToTourney ------------------------------------------------------------
767 int CommandEntry::AddToTourney(User *user, param_list params) {
768   Tourney *tourn = NULL;
769   Player *newEntry = NULL;
770
771   tourn = gMamer.FindTourney(params[1].val.integer);
772   
773   if(NULL != tourn) {
774     newEntry = new Player(params[0].val.word, params[1].val.integer);
775     gMamer.pendingList.Append(newEntry);
776     gMamer.XServerCom("getpi %s%s", params[0].val.word, "\n");
777     return(1);
778   }
779
780   gMamer.TellUser(TourneyNotFound, user->name,  params[1].val.integer);
781   return(0);
782 }
783
784 //- RemoveFromTourney ------------------------------------------------------------
785 int CommandEntry::RemoveFromTourney(User *user, param_list params) {
786   Tourney *tourn = NULL;
787   TourneyPlayers *tp=NULL;
788   char name[NAMELEN], reason[64];
789   int num=0;
790   User *u=NULL;
791   int chaosPointsEarned=0, needToDelete=0;
792
793   memset(name, '\0', NAMELEN);
794   memset(reason, '\0', 64);
795   if(params[0].type == TYPE_INT) {  // if we are withdrawing ourselves
796     tourn = gMamer.FindTourney(params[0].val.integer);
797     strcpy(name, user->name);
798     u = user;
799     num = params[0].val.integer;
800     strcpy(reason, "withdrew");
801   } else {  // if a manager is forfeiting us
802     tourn = gMamer.FindTourney(params[1].val.integer);
803     strcpy(name, params[0].val.word);
804     u = gMamer.FindUser(params[0].val.word);
805     num = params[1].val.integer;
806     strcpy(reason, "was forfeited");
807   }
808
809   if(NULL == tourn) {
810     gMamer.TellUser(TourneyNotFound, user->name, num);
811     return 0;
812   }
813   if(tourn->GetStatus() == DONE) {
814     gMamer.TellUser(TourneyDone, user->name, num);
815     return 0;
816   }
817   tp = tourn->GetPlayer(name);   //Get the players info
818   if(tp == NULL) {
819     gMamer.TellUser(NotFound, user->name, name, num);// Player is not found in this tourney
820     return 0;
821   }
822
823   gMamer.XServerCom("%s %s %d%s", "tournset", name, 0, "\n");
824   if(tourn->IsNotClosed()) { //If we get past this check it will cost the user chaos points
825     tourn->playerList.Delete(tp);
826     tourn->CalculateAverage();
827     gMamer.TellUser(PlayerRemoved, user->name, name, num);
828     gMamer.XServerCom("%s %d %s %s %s%d %d%s\n","tell", gMamer.channelNumber, name, reason, "from tourney #", 
829                       tourn->number, tourn->GetPlayerCount(), " player(s) now");
830     return 0; 
831   } // otherwise tourney is closed and started
832
833   chaosPointsEarned = tourn->RemovePlayer(name);  // RemovePlayer will return the number of rounds
834   if(chaosPointsEarned >= 0) {                    // that were disturbed
835     if(NULL == u) {
836       u = new User(gMamer.userFilePath, name);  // Make a new user - this will create a file but there
837       needToDelete = 1;                         // should already be one cause they are in the tourney
838     }
839     u->AddAbuse(chaosPointsEarned * PENALTY_PER_ROUND);  // add the choas points and save them
840     u->SavePlayer(gMamer.userFilePath);
841     if(u->GetAbuse() >= MAX_CHAOS_POINTS)
842       gMamer.XServerCom("%s %s%s", "+ censor", u->name, "\n");
843     if(needToDelete) delete(u);                 // we created a new user so we should delete him here
844     gMamer.TellUser(PlayerRemoved, user->name, name, num);
845     gMamer.XServerCom("%s %d %s %s %s%d\n","tell",gMamer.channelNumber,name, reason,
846                       "from tourney #", tourn->number);
847     return 1;
848   }
849   return 1;
850 }
851
852 //- ListTourneyGames ------------------------------------------------------------
853 int CommandEntry::ListTourneyGames(User *user, param_list params) {
854   Tourney *t = NULL;
855   TourneyPlayers *white, *black;
856   int i = 0;
857   Game *g = NULL;
858   
859   t = gMamer.FindTourney(params[0].val.integer);
860   if(NULL != t) {
861     LinkListIter<Game> gameIter(t->gameList);
862     gameIter.Reset();
863     gMamer.XServerCom("%s %s %s %d %s",  "qtell", user->name, "Tourney Games for Round #", t->GetRound(), "\\n\\n");
864     gMamer.XServerCom("%3s %18s %6s %6s %2s %-18s %6s %6s %s",
865                       "", "White", "[SCR ]", "[Rtng]", "vs", "Black", "[SCR ]", "[Rtng]",
866                       "\\n---------------------------------------------------------------------------\\n");
867     while((g = gameIter.Next())) {
868       if(!(i % 10) && (i>0)) {
869         gMamer.XServerCom("\nqtell %s %s", user->name, "\\n");
870       }
871
872       white = t->GetPlayer(g->whiteName);
873       black = t->GetPlayer(g->blackName);
874
875       if(g->gameNumber > 0) {
876         gMamer.XServerCom("%3d %18s [%4.1f] [%4i] vs %-18s [%4.1f] [%4i] %3i%s",
877                           i+1, g->whiteName, white->score, white->rating,
878                           g->blackName, black->score, black->rating, g->gameNumber, "\\n");
879       } else {
880         gMamer.XServerCom("%3d %18s [%4.1f] [%4i] vs %-18s [%4.1f] [%4i] none%s",
881                           i+1, g->whiteName, white->score, white->rating,
882                           g->blackName, black->score, black->rating, "\\n");
883       }
884       i++;
885     }
886     gMamer.XServerCom("%s", "\\n\n");
887     return(1);
888   }
889
890   gMamer.TellUser(TourneyNotFound, user->name, params[0].val.integer);
891   return(0);
892 }//- End of ListTourneyGames
893
894 //- ListTourneyPlayers ------------------------------------------------------------
895 int CommandEntry::ListTourneyPlayers(User *user, param_list params) {
896   Tourney *t = NULL;
897   Player *p = NULL, *opp=NULL;
898   TourneyPlayers *tp = NULL;
899   char color, result;
900   int i = 0, counter = 0;
901
902   t = gMamer.FindTourney(params[0].val.integer);
903   if(NULL != t) {
904     if(t->GetPlayerCount() == 0) {
905       gMamer.TellUser(NoPlayers, user->name, params[0].val.integer);
906       return 0;
907     }
908     t->SortPlayers();
909     gMamer.XServerCom("%s %s %s %s %d %s %d %s %3s %-17s %6s %5s %6s %-6s %-7s %s %3s %-17s %6s %5s %6s %6s %-7s %s", 
910                       "qtell", user->name, "Tourney Players:", "Round", t->GetRound(), "of", t->params.rounds, 
911                       "\\n\\n", "", "Name", "Rating", "Score", "Perfrm", "Upset ", "Results", "\\n",
912                       "", "-----------------", "------", "-----", "------", "------", "-------", "\\n");
913     LinkListIter<TourneyPlayers> playerIter(t->playerList);
914     playerIter.Reset();
915     while((tp = playerIter.Next())) { counter++; }  // count the number of players
916     for(i=1; i<=counter; i++) {
917       p = t->GetSortPlayer(i);
918       tp = t->GetPlayer(p->name);
919       if(tp->activeFlag > 0) 
920         gMamer.XServerCom("%3d %s%-17s [%4d]  %3.1f  [%4d] [%4d] ", 
921                           i, ((tp->location == ONLINE) ? "+" : "-"), 
922                           tp->name, tp->rating, tp->score, tp->perform, tp->upset);
923       else 
924         gMamer.XServerCom("%3d %s%-17s [%4s]  %3.1f  [%4d] [%4d] ", 
925                           i, ((tp->location == ONLINE) ? "+" : "-"), 
926                           tp->name, "forf", tp->score, tp->perform, tp->upset);
927       LinkListIter<Player> opponentIter(tp->opponentList);  // List of opponents this player has had
928       opponentIter.Reset();
929       while((opp = opponentIter.Next())) {
930         p = t->GetSortPlayer(opp->name);
931         if(opp->value) { color = 'w'; } else { color = 'b'; }
932         if(opp->floatValue == 1.0) {
933           result = '+';
934         } else if(opp->floatValue == 0.5) { 
935           result = '='; 
936         } else if(opp->floatValue == 0.0) { 
937           result = '-'; 
938         } else {
939           result = '*'; 
940         }
941         gMamer.XServerCom("%c%-0.2d%c ", result, p->value, color);
942       }
943       if(((i % 9) == 0) && (i > 0)) {
944         gMamer.XServerCom("%s %s %s %s", "\n", "qtell", user->name, "\\n");
945       } else {
946         gMamer.XServerCom("%s", "\\n");
947       }
948     }
949     gMamer.XServerCom("%-24s %6.1f %s", "\\n     Average Rating", t->GetAverageRating(), "\\n\n");
950     return(1);
951   }
952
953   gMamer.TellUser(TourneyNotFound, user->name, params[0].val.integer);
954   return(0);
955 }//- End of ListTourneyPlayers
956
957 //- ListTourneyVars -----------------------------------------------------
958 int CommandEntry::ListTourneyVars(User *user, param_list params) {
959   Tourney *tourn = NULL;
960
961   tourn = gMamer.FindTourney(params[0].val.integer);
962
963   if(NULL != tourn) {
964     gMamer.XServerCom("%s %s %s", "qtell", user->name, "\\n");
965     gMamer.XServerCom(" %18s %4d %s", "(T)ime: ", tourn->params.time, "\\n");
966     gMamer.XServerCom(" %18s %4d %s", "(I)ncrement: ", tourn->params.inc, "\\n");
967     gMamer.XServerCom(" %18s %4d %s", "(R)ounds: ", tourn->params.rounds, "\\n");
968     gMamer.XServerCom(" %18s %4d %s", "Max (P)layers: ", tourn->params.maxPlayers, "\\n");
969     gMamer.XServerCom(" %18s %4c %s", "(M)ode: ", tourn->params.mode, "(r)ated or (u)nrated\\n");
970     gMamer.XServerCom(" %18s %4c %s", "(S)tyle: ", tourn->params.style, "(s)wiss or (r)oundrobin\\n");
971     gMamer.XServerCom(" %18s %4c %s","(V)ariant: ",tourn->params.variant, "(w)ild, (r)egular, (b)ug, or (s)uicide\\n");
972     if(tourn->params.variant == 'w')
973       gMamer.XServerCom(" %18s %4d %s", 
974                         "(W)ild Type: ", 
975                         tourn->params.wild, "(0), (1), (2), (3), (4), (5), (8), (9)8a, (10)fr\\n");
976     gMamer.XServerCom(" %18s %4d %s", "Rating (L)ow: ", tourn->params.ratingLow, "\\n");
977     gMamer.XServerCom(" %18s %4d %s", "Rating (H)igh: ", tourn->params.ratingHigh, "\\n\\n");
978     gMamer.XServerCom(" %18s %-18s %s", "Manager: ", tourn->manager, "\\n\n");
979   } else {
980     gMamer.TellUser(NotFound, user->name, "tourney");
981   }
982
983   return 1;
984 }//- End ListTourneyVars
985
986 //- MessageManagers -----------------------------------------------------
987 int CommandEntry::MessageManagers(User *user, param_list params) {
988     int i, level, tourneys;
989     long last;
990     char filename[256], manager[NAMELEN];
991     FILE *theFile;
992     
993     i = 1;
994     level = params[0].type;
995     sprintf(filename, "%s/managers", gMamer.dataFilePath);
996     if((theFile = fopen(filename, "r"))) {
997       while(fscanf(theFile, "%s %d %d %ld", manager, &level, &tourneys, &last) > 0) {
998         gMamer.XServerCom("%s %s %s %s", "message", manager, params[0].val.string, "\n");
999       }
1000       fclose(theFile);
1001       
1002       return(1);
1003     }
1004     gMamer.TellUser(NotFound, user->name, "Manager List");
1005     return(0);
1006 }//- MessageManagers
1007
1008 //- SetResult ------------------------------------------------------------
1009 int CommandEntry::SetResult(User *user, param_list params) {
1010   Tourney *t;
1011   int result, return_val = 0;
1012   char answer[128];
1013
1014   t = gMamer.FindTourney(params[0].val.integer);
1015   
1016   if(NULL != t) {
1017     switch (params[3].type) {    // try and set the result
1018     case TYPE_INT:
1019       switch(params[3].val.integer) {
1020         case 1: result = 1; break;
1021         case 0: result = 0; break;
1022
1023       }
1024       break;
1025     case TYPE_WORD:
1026       if(!strcmp("=", params[3].val.word)) { result = 2;
1027       } else if(!strcmp("draw", params[3].val.word)) { result = 2;
1028       } else if(!strcmp("win", params[3].val.word)) { result = 1;
1029       } else if(!strcmp("white", params[3].val.word)) { result = 1;
1030       } else if(!strcmp("loss", params[3].val.word)) { result = 0;
1031       } else if(!strcmp("black", params[3].val.word)) { result = 0;
1032       } else { 
1033         gMamer.TellUser(GameResultNotFound, user->name, params[3].val.word); 
1034         return 0;
1035       }
1036       break;
1037     default:
1038       gMamer.TellUser(GameResultNotFound, user->name, params[3].val.string); 
1039       return 0;
1040       break;
1041     }
1042     return_val = t->SetGameResult(params[1].val.word, params[2].val.word, result);
1043   }
1044   switch (return_val) {
1045   case 0:
1046     sprintf(answer, "a game with %s as white and %s as black", params[1].val.word, params[2].val.word);
1047     gMamer.TellUser(NotFound, user->name, answer);
1048     break;
1049   default:
1050     gMamer.TellUser(GameResultSet, user->name, params[1].val.word, params[2].val.word, result);
1051     switch (result) {
1052     case 1:
1053       sprintf(answer, "1-0");
1054       break;
1055     case 0:
1056       sprintf(answer, "0-1");
1057       break;
1058     default:
1059       sprintf(answer, "1/2-1/2");
1060       break;
1061     }
1062     gMamer.XServerCom("%s %d The game %s vs. %s in tourney #%d has been set %s by %s\n", "tell", gMamer.channelNumber,
1063                       params[1].val.word, params[2].val.word, t->number, answer, user->name);
1064     break;
1065   }
1066   return return_val;
1067 }//- End of SetResult
1068
1069 //- SetTourneyVariable -----------------------------------------------------
1070 int CommandEntry::SetTourneyVariable(User *user, param_list params) {
1071   Tourney *tourn = NULL;
1072   int i=0;
1073   char which_var[16];
1074   strings varAliases[] = {
1075     {"time", 0},      {"t", 0}, {"inc", 1},        {"i", 1}, {"rounds", 2}, {"r", 2},
1076     {"style", 3},     {"s", 3}, {"variant", 4},    {"v", 4}, {"mode", 5},   {"m", 5},
1077     {"wild", 6}, {"w", 6},
1078     {"ratingLow", 7}, {"l", 7}, {"ratingHigh", 8}, {"h", 8}, {"maxplayers", 9}, {"p", 9}, {NULL} };
1079
1080   tourn = gMamer.FindTourney(params[0].val.integer);   // what tourney are we talking about
1081   if(NULL == tourn) {
1082     gMamer.TellUser(NotFound, user->name, "tourney");  // wrong tourney number
1083     return 0;
1084   }
1085   if(FALSE == tourn->IsNotClosed()) {
1086     gMamer.TellUser(TourneyClosed, user->name, params[0].val.integer);
1087     return 0;
1088   }
1089   if(TRUE == tourn->IsNotNew()) {
1090     if((0 != strncasecmp(params[1].val.word, "rounds", strlen(params[1].val.word))) &&  // even if it is open
1091        (0 != strncasecmp(params[1].val.word, "r", strlen(params[1].val.word))) &&       // we can still change rounds
1092        (0 != strncasecmp(params[1].val.word, "maxplayers", strlen(params[1].val.word))) &&   // or max players
1093        (0 != strncasecmp(params[1].val.word, "p", strlen(params[1].val.word))) &&   // 
1094        (0 != strncasecmp(params[1].val.word, "style", strlen(params[1].val.word))) &&   // or style (rr) to (ss)
1095        (0 != strncasecmp(params[1].val.word, "s", strlen(params[1].val.word)))) {
1096       gMamer.TellUser(TourneyNotNew, user->name, params[0].val.integer);
1097       return(0);
1098     }
1099   }
1100   if(strcasecmp(user->name, tourn->manager) != 0) {
1101     gMamer.TellUser(NoPermissions, user->name, params[0].val.integer);
1102     return(0);
1103   }
1104   while(varAliases[i].string != NULL) {
1105     if (!(strcasecmp(varAliases[i].string, params[1].val.word))) {   //lets check the vars
1106       if(strlen(varAliases[i].string) == 1)
1107         strcpy(which_var, varAliases[i-1].string);                   
1108       else                                                       //copy the whole word
1109         strcpy(which_var, varAliases[i].string);
1110       
1111       if((varAliases[i].number <= 2) || (varAliases[i].number >= 6)) 
1112         if(params[2].type == TYPE_INT) {                     // if var is one that should be int
1113           tourn->SetVariable(varAliases[i].number, params[2].val.integer);
1114           gMamer.TellUser(ChangedInfo, user->name, which_var, params[2].val.integer);
1115           return 1;
1116         } else {
1117           gMamer.TellUser(CanNotChange, user->name, which_var, params[2].val.word);
1118           return 0;
1119         }
1120       else 
1121         if(params[2].type == TYPE_WORD) {
1122           tourn->SetVariable(varAliases[i].number, params[2].val.word);
1123           gMamer.TellUser(ChangedInfo, user->name, which_var, params[2].val.word);
1124           return 1;
1125         } else {
1126           gMamer.TellUser(CanNotChange, user->name, which_var, params[2].val.integer);
1127           return 0;
1128         }
1129     }
1130     i++;
1131   }
1132
1133   gMamer.TellUser(NotFound, user->name, params[1].val.word);  // Bad Variable  
1134   return 0;
1135 }
1136
1137 //- ShutdownCommand ----------------------------------------------------------
1138 int CommandEntry::Shutdown(User *user, param_list params) {
1139   int i;
1140
1141   i = params[0].type;
1142   i = user->GetManagerLevel();
1143
1144   gMamer.Shutdown();
1145   exit(0);
1146   
1147   return(1);
1148 } //- end of Shutdown