1 //--------------------------------------------------------------------------
2 // Mamer.cc - Source file for the Mamer class
4 // Matthew E. Moses & Michael A. Long
7 // $Date: 1998/09/10 19:57:17 $
12 //--------------------------------------------------------------------------
14 // static char RCSid[] = "$Id: Mamer.cc,v 1.17 1998/09/10 19:57:17 mlong Exp $";
18 extern void HandleSignals(int);
20 //- Constructor ------------------------------------------------------------
23 struct tm *timeStruct;
25 theTime = time((time_t *)NULL);
26 timeStruct = localtime(&theTime);
30 memset(configFilename, '\0', MAXPATHLEN);
31 strncpy(configFilename, CONFIG_FILENAME, MIN(strlen(CONFIG_FILENAME), MAXPATHLEN));
33 channelNumber = DEFAULT_CHANNEL;
34 memset(hostname, '\0', 256);
35 strncpy(hostname, DEFAULT_HOSTNAME, MIN(strlen(DEFAULT_HOSTNAME), 256));
36 portNumber = DEFAULT_PORT;
40 memset(username, '\0', 80);
41 memset(password, '\0', 80);
42 strncpy(username, DEFAULT_USERNAME, MIN(strlen(DEFAULT_USERNAME), 80));
43 strncpy(password, DEFAULT_PASSWORD, MIN(strlen(DEFAULT_PASSWORD), 80));
45 sprintf(logFilename, "%s/%s.%04d%02d%02d",
46 DEFAULT_PATH, DEFAULT_LOG_FILE,
47 1900 + timeStruct->tm_year, timeStruct->tm_mon + 1,
50 sprintf(userFilePath, "%s/%s", DEFAULT_PATH, DEFAULT_USER_PATH);
51 sprintf(dataFilePath, "%s/%s", DEFAULT_PATH, DEFAULT_DATA_PATH);
52 sprintf(homeFilePath, "%s", DEFAULT_PATH);
54 tourneyParams.time = DEFAULT_TIME;
55 tourneyParams.inc = DEFAULT_INCREMENT;
56 tourneyParams.mode = 'r';
57 tourneyParams.style = 's';
58 tourneyParams.variant = 'r';
59 tourneyParams.rounds = DEFAULT_ROUNDS;
60 tourneyParams.ratingHigh = 9999;
61 tourneyParams.ratingLow = 0;
62 tourneyParams.maxPlayers = DEFAULT_MAX_PLAYERS;
66 //- Deconstructor ----------------------------------------------------------
72 while(0 != (u = userList.Head()))
75 while(0 != (t = tourneyList.Head()))
78 while(0 != (c = commandList.Head()))
83 //- Initialize -------------------------------------------------------------
84 int Mamer::Initialize(int argc, char **argv) {
85 struct stat statBuffer;
88 LoadConfigurationFile();
90 while(EOF != (c = getopt(argc, argv,
91 "d:D:c:C:s:S:p:P:u:U:l:L:hHa:A:n:N:"))) {
95 debugLevel = atoi(optarg);
99 channelNumber = atoi(optarg);
103 memset(hostname, '\0', 256);
104 strncpy(hostname, optarg, MIN(strlen(optarg), 256));
108 portNumber = atoi(optarg);
112 memset(userFilePath, '\0', MAXPATHLEN);
113 strncpy(userFilePath, optarg, MIN(strlen(optarg), MAXPATHLEN));
117 memset(userFilePath, '\0', MAXPATHLEN);
118 strncpy(logFilename, optarg, MIN(strlen(optarg), MAXPATHLEN));
122 memset(username, '\0', 80);
123 strncpy(username, optarg, MIN(strlen(optarg), 80));
127 memset(password, '\0', 80);
128 strncpy(password, optarg, MIN(strlen(optarg), 80));
138 if(-1 == stat(userFilePath, &statBuffer)) {
141 if(-1 == mkdir(userFilePath, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IXOTH)) {
142 printf("name = '%s'\n", userFilePath);
143 perror("create user file path");
152 signal(SIGPIPE, SIG_IGN);
153 signal(SIGTERM, HandleSignals);
154 signal(SIGKILL, HandleSignals);
155 signal(SIGUSR1, HandleSignals);
156 signal(SIGUSR2, HandleSignals);
161 } //- End of Initialize
163 //- s_and_r - Search and Replace a string within a string ------------
164 char *Mamer::s_and_r(char *s, char *tofind, char *toreplace) {
165 char *toReturn = NULL;
168 char *replace_offset;
173 /* if nothing to look at, and nothing to replace.... return nothing */
174 if ( s == NULL || tofind == NULL)
177 find_len = strlen(tofind);
178 if ( toreplace != NULL )
179 toreplace_len = strlen(toreplace);
181 toreplace_len = 0; /* allow us to have nothing to replace... acts the same a delstring */
183 currSize = (strlen(s) * 2) + 100; /* add the 100 in case s is small */
184 toReturn = (char*)malloc(currSize);
185 return_offset = toReturn;
186 while ( *s != '\0' ) {
187 if ( *s == *tofind && strncmp(s, tofind, MIN(find_len, (int)strlen(s))) == 0 ) {
188 /* if the first letter matches, and so does the rest.. */
189 /* copy in the replace string */
190 replace_offset = toreplace;
191 for ( x = 0; x < toreplace_len; x++ ) {
192 *return_offset = *replace_offset;
196 /* and move up the current position in s to just past the find string */
198 } else { /* it doesn't match.... just copy to the return and continue */
204 *return_offset = '\0';
209 //- OpenServerConnection ---------------------------------------------------
210 int Mamer::OpenServerConnection(void) {
211 struct sockaddr_in socketAddr;
212 struct hostent *hostEntry = NULL;
213 // char mesg[MAXPATHLEN] = {'\0'};
214 unsigned long inAddr;
216 //- Check is we have a decimal notation host address
217 socketAddr.sin_family = AF_INET;
218 if((unsigned long)INADDR_NONE != (inAddr = inet_addr(hostname)))
219 socketAddr.sin_addr.s_addr = inAddr;
220 else { //- Try to query a namserver to get an address
221 if(NULL == (hostEntry = gethostbyname(hostname))) {
222 cerr << "ERROR: can't resolve hostname '" << hostname
228 bcopy(hostEntry->h_addr, (char *)&socketAddr.sin_addr,
229 hostEntry->h_length);
232 serverSocket = socket(AF_INET, SOCK_STREAM, 0);
233 if(0 > serverSocket) {
234 cerr << "ERROR: can't create TCP socket." << endl;
239 socketAddr.sin_port = htons(portNumber);
240 if(0 > connect(serverSocket, (struct sockaddr *)&socketAddr,
241 sizeof(struct sockaddr_in))) {
242 cerr << "ERROR: can't create connection to server '"
243 << hostname << "' on port " << portNumber << "." << endl;
244 cerr << " " << strerror(errno) << endl;
250 } //- End of OpenServerConnection
252 //- ListenLoop -------------------------------------------------------------
253 void Mamer::ListenLoop(void) {
254 struct timeval timeout;
255 char readBuffer[4096], writeBuffer[4096], commandBuffer[4096], channelCmpStr[16];
256 char *p = NULL, *buffer = NULL, *tmpBuffer = NULL;
261 sprintf(channelCmpStr, "(%d): ", channelNumber);
262 buffer = new char[4096];
264 cerr << "ERROR: problems allocating memory" << endl;
269 tmpBuffer = new char[4096];
270 if(NULL == tmpBuffer) {
271 cerr << "ERROR: problems allocating memory" << endl;
276 timeout.tv_sec = timeout.tv_usec = 0;
280 FD_SET(serverSocket, &fdMask);
283 select(serverSocket + 3, (int *)&fdMask, (int *)0, (int *)0, &timeout);
285 select(serverSocket + 3, &fdMask, (fd_set *)0, (fd_set *)0, &timeout);
288 if(FD_ISSET(serverSocket, &fdMask)) {
290 memset(readBuffer, '\0', 4096);
291 memset(writeBuffer, '\0', 4096);
292 size = read(serverSocket, readBuffer, (sizeof(readBuffer) - 1));
295 //- fix newlines/linefeeds
296 memset(buffer, '\0', 4096);
297 strncpy(buffer, readBuffer, size);
300 if(NULL != (strstr(buffer, "\n\r\\ "))) {
301 strcpy(tmpBuffer, s_and_r(buffer, "\n\r\\ ", ""));
302 memset(buffer, '\0', 4096);
303 strcpy(buffer, tmpBuffer);
304 size = strlen(buffer);
307 if(NULL != (strstr(buffer, "\r\n\\ "))) {
308 strcpy(tmpBuffer, s_and_r(buffer, "\r\n\\ ", ""));
309 memset(buffer, '\0', 4096);
310 strcpy(buffer, tmpBuffer);
311 size = strlen(buffer);
314 if(NULL != (strstr(buffer, "\n\r "))) {
315 strcpy(tmpBuffer, s_and_r(buffer, "\n\r ", ""));
316 memset(buffer, '\0', 4096);
317 strcpy(buffer, tmpBuffer);
318 size = strlen(buffer);
321 if((FALSE == loggedInFlag) &&
322 (NULL != strstr(buffer, "login:"))) {
323 sprintf(writeBuffer, "%s\n", username);
324 write(serverSocket, writeBuffer, strlen(writeBuffer));
325 } else if((FALSE == loggedInFlag) &&
326 (NULL != strstr(buffer, "password:"))) {
328 "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s %d\n",
343 write(serverSocket, writeBuffer, strlen(writeBuffer));
345 char manager[NAMELEN], filename[128];
346 sprintf(filename, "%s/managers", dataFilePath);
347 if((theFile = fopen(filename, "r"))) {
348 while(fscanf(theFile, "%s", manager) > 0) {
349 XServerCom("qtell %s %s %s %s",
350 manager, "Howdy, ", username, " is here!\n");
357 else if(TRUE == loggedInFlag) {
360 while(('\r' == buffer[i]) ||
361 ('\n' == buffer[i]) ||
362 ('%' == buffer[i]) ||
366 while(('\r' != buffer[i]) &&
367 ('\n' != buffer[i]) &&
369 commandBuffer[j++] = buffer[i++];
370 commandBuffer[j] = '\0';
372 if(NULL != (p = strstr(commandBuffer, channelCmpStr)))
373 HandleChannel(commandBuffer);
374 else if(NULL != (p = strstr(commandBuffer, "tells you:")))
375 HandleTell(commandBuffer);
376 else if(NULL != (p = strstr(commandBuffer, "has connected")))
377 HandleConnect(commandBuffer);
378 else if(NULL != (p = strstr(commandBuffer, "has disconnected")))
379 HandleDisconnect(commandBuffer);
380 else if(0 == strncmp(commandBuffer, "{Game ", 6))
381 HandleGame(commandBuffer);
382 else if(0 == strncmp(commandBuffer, "*qtell ", 7))
383 HandleQtell(commandBuffer);
384 else if(0 == strncmp(commandBuffer, "*getgi ", 7))
385 HandleGameInfo(commandBuffer);
386 else if(0 == strncmp(commandBuffer, "*getpi ", 7))
387 HandlePlayerInfo(commandBuffer);
390 cout << "Unsupported: " << commandBuffer << endl;
395 while(('\r' == buffer[i]) ||
396 ('\n' == buffer[i]) ||
397 ('%' == buffer[i]) ||
403 if((errno == EINTR) || (errno == EAGAIN) || (errno == EIO) ||
404 (errno == EBADF) || (errno == EINVAL) || (errno == EFAULT)) {
407 printf("Error = %s\n", "EINTR");
410 printf("Error = %s\n", "EAGAIN");
413 printf("Error = %s\n", "EIO");
416 printf("Error = %s\n", "EBADF");
419 printf("Error = %s\n", "EINVAL");
422 printf("Error = %s\n", "EFAULT");
437 if(NULL != tmpBuffer)
440 } //- End of ListenLoop
442 //- Start of GivePlace ----------------------------
443 int Mamer::GivePlace(int i, Tourney *t) {
444 TourneyPlayers *tp = NULL, *place = NULL;
447 LinkListIter<TourneyPlayers> playerIter(t->playerList);
452 memset(placeName, '\0', 7);
455 strcpy(placeName, "First");
458 strcpy(placeName, "Second");
461 strcpy(placeName, "Third");
467 XServerCom("%s %i %s %s %s%i %s ", "tell", channelNumber, "Tourney Results:", placeName,
468 "place in tourney #", t->number, "goes to: ");
470 opp = t->GetSortPlayer(i);
471 place = t->GetPlayer(opp->name);
472 score = place->score;
474 while((tp = playerIter.Next())) {
475 if(tp->score == score) {
476 XServerCom("%s ", tp->name);
478 u = FindUser(tp->name);
481 u = FindUser(tp->name);
484 u->AddStat(i); // Adds a first/second/third place finish to everyone with the same score as the 1st
492 //- Start of AnnounceTourneyEnd
493 void Mamer::AnnounceTourneyEnd(Tourney *t) {
494 TourneyPlayers *tp = NULL;
495 int first=0, second=0, third=0;
496 int numberOfPlayers = 0;
502 LinkListIter<TourneyPlayers> playerIter(t->playerList);
504 while((tp = playerIter.Next())) {
505 if((tp->activeFlag) && (strcasecmp(tp->name, "_BYE_") != 0))
509 first = GivePlace(1, t); //first = number of people tied for first
511 if(numberOfPlayers >= 5) {
512 if(first == 1) { second = GivePlace(2, t); }
513 if(first == 2) { third = GivePlace(3, t); }
514 if(numberOfPlayers >= 7) {
515 if(second == 1) { third = GivePlace(3, t); }
520 //- savePlayerData --------------------------------------------------------------
521 void Mamer::savePlayerData(Tourney *t) {
522 LinkListIter<TourneyPlayers> playerIter(t->playerList);
523 TourneyPlayers *tp = NULL, *tmpOpp = NULL;
524 User *u = NULL, *manager=NULL;
527 float r, tourn_expect=0.0, pre_expect=0.0, delta = 0.0;
529 manager = FindUser(t->manager); // save the manager info
530 if(manager == NULL) {
531 manager = new User(userFilePath, t->manager); // manager isn't online
532 manager->SetLast(time(0)); // so we have to load him/her
533 manager->AddManagedTourney();
534 manager->SavePlayer(userFilePath);
536 } else { // manager is online
537 manager->SetLast(time(0));
538 manager->AddManagedTourney();
539 manager->SavePlayer(userFilePath);
542 while((tp = playerIter.Next())) {
544 u = FindUser(tp->name);
546 User *newUser = NULL;
547 newUser = new User(userFilePath, tp->name);
551 cout << "savePlayerData::" << tp->name << " " << u->name << endl;
556 pre_expect = ((float)w + (0.5 * (float)d)) / r;
558 LinkListIter<Player> opponentIter(tp->opponentList); // List of opponents this player has had
559 while((opp = opponentIter.Next())) {
560 tmpOpp = t->GetPlayer(opp->name); // need the player's information to do tourn_expect
561 delta = (float)(((tp->rating != 0) ? tp->rating : 1600) -
562 ((tmpOpp->rating != 0) ? tmpOpp->rating : 1600)); // difference in rating
563 tourn_expect = tourn_expect + (1 / (1+pow(10,(delta/400.0))));
564 u->AddStat(opp->floatValue);
566 u->AddPlayedTourney();
567 if(tp->activeFlag) { // If I didn't withdraw or get forfeited reduce my abuse points
568 u->AddAbuse(-1 * t->GetRound()); // This will be the # of rounds played because the tourney is DONE
569 XServerCom("%s %s %d%s", "tournset", tp->name, 0, "\n");
571 u->CalculateRating(tourn_expect, pre_expect);
572 u->SavePlayer(userFilePath);
574 } //- End of savePlayerData ------------------------------------------
576 //- Shutdown --------------------------------------------------------------
577 void Mamer::Shutdown(void) {
578 LinkListIter<User> userIter(userList);
581 while((u = userIter.Next())) {
582 // u->SavePlayer(userFilePath);
586 write(serverSocket, "exit\n", 5);
589 } //- End of Shutdown
591 //- Usage -----------------------------------------------------------------
592 void Mamer::Usage(void) {
593 cerr << "Usage: mamer [-c channel] [-s server] [-n port number] " << endl;
594 cerr << " [-d debug level] [-u users database filename] "
596 cerr << " [-l log filename] [-a mamer account name] " << endl;
597 cerr << " [-p mamer password] [-h help] " << endl;
599 cerr << "\t-h show usage information." << endl;
600 cerr << "\t-c sets which channel mamer should work on.\n\t (default = "
601 << channelNumber << ")" << endl;
602 cerr << "\t-s sets the server hostname that mamer connects to.\n\t"
603 << " (default = " << hostname << ")" << endl;
604 cerr << "\t-n sets the port number on the server to connect to.\n\t"
605 << " (default = " << portNumber << ")" << endl;
606 cerr << "\t-a sets the username for the account to mamer logs in as.\n\t"
607 << " (default = " << username << ")" << endl;
608 cerr << "\t-p sets the password for the mamer account.\n\t"
609 << " (default = " << password << ")" << endl;
610 cerr << "\t-d sets the debugging level. This determines how much of "
611 << "the\n\t activity of mamer is written to the logs." << endl;
612 cerr << "\t-u set the location of the users database file.\n\t"
613 << " (default = " << userFilePath << ")" << endl;
614 cerr << "\t-l sets the location of the log file.\n\t (default = "
615 << logFilename << ")" << endl;
619 //- LoadConfigurationFile -------------------------------------------------
620 void Mamer::LoadConfigurationFile(void) {
621 struct stat statBuffer;
624 if(-1 != stat(configFilename, &statBuffer)) {
626 fstream theFile(configFilename, ios::in);
628 buffer = new char[MAXPATHLEN + 80];
632 memset(buffer, '\0', MAXPATHLEN + 80);
634 while(theFile.good()) {
635 theFile.getline(buffer, MAXPATHLEN + 80 - 1, '\n');
637 if(buffer[0] == '#') continue;
638 length = strlen(buffer);
641 if(0 == strncasecmp(buffer, "HOST", 4)) {
643 while(isspace(buffer[0])) buffer++;
645 memset(hostname, '\0', MAXPATHLEN);
646 strncpy(hostname, buffer, MIN(length, MAXPATHLEN));
647 } else if(0 == strncasecmp(buffer, "DATA", 4)) {
649 while(isspace(buffer[0])) buffer++;
651 memset(dataFilePath, '\0', MAXPATHLEN);
652 strncpy(dataFilePath, buffer, MIN(length, MAXPATHLEN));
653 } else if(0 == strncasecmp(buffer, "HOME", 4)) {
655 while(isspace(buffer[0])) buffer++;
657 memset(homeFilePath, '\0', MAXPATHLEN);
658 strncpy(homeFilePath, buffer, MIN(length, MAXPATHLEN));
659 } else if(0 == strncasecmp(buffer, "HELP", 4)) {
661 while(isspace(buffer[0])) buffer++;
663 memset(helpFilePath, '\0', MAXPATHLEN);
664 strncpy(helpFilePath, buffer, MIN(length, MAXPATHLEN));
665 } else if(0 == strncasecmp(buffer, "USER", 4)) {
667 while(isspace(buffer[0])) buffer++;
669 memset(username, '\0', 80);
670 strncpy(username, buffer, MIN(length, 80));
671 } else if(0 == strncasecmp(buffer, "PASS", 4)) {
673 while(isspace(buffer[0])) buffer++;
675 memset(password, '\0', 80);
676 strncpy(password, buffer, MIN(length, 80));
677 } else if(0 == strncasecmp(buffer, "PORT", 4)) {
679 while(isspace(buffer[0])) buffer++;
681 portNumber = atoi(buffer);
682 } else if(0 == strncasecmp(buffer, "CHAN", 4)) {
684 while(isspace(buffer[0])) buffer++;
686 channelNumber = atoi(buffer);
687 } else if(0 == strncasecmp(buffer, "DBUG", 4)) {
689 while(isspace(buffer[0])) buffer++;
691 debugLevel = atoi(buffer);
695 if(0 == strncasecmp(buffer, "LOG", 3)) {
697 while(isspace(buffer[0])) buffer++;
699 memset(logFilename, '\0', MAXPATHLEN);
700 strncpy(logFilename, buffer, MIN(length, MAXPATHLEN));
701 } else if((strlen(buffer) > 3) && (0 == strncasecmp(buffer, "UDB", 3))) {
703 while(isspace(buffer[0])) buffer++;
705 memset(userFilePath, '\0', MAXPATHLEN);
706 strncpy(userFilePath, buffer, MIN(length, MAXPATHLEN));
714 cerr << "ERROR: permission denied for configuration file '"
715 << configFilename << "' using compiled defaults." << endl;
719 cerr << "WARNING: configuration file '" << configFilename
720 << "' doesn't exist, using " << endl;
721 cerr << " compiled defaults." << endl;
727 } //- End of LoadConfigurationFile
729 //- DumpConfiguration -----------------------------------------------------
730 void Mamer::DumpConfiguration(void) {
731 cout << "Mamer Configuration" << endl;
732 cout << "-------------------" << endl;
733 cout << "Hostname : " << hostname << endl;
734 cout << "Port : " << portNumber << endl;
735 cout << "Channel : " << channelNumber << endl;
737 cout << "Username : " << username << endl;
738 cout << "Password : " << password << endl;
740 cout << "Home Path: " << homeFilePath << endl;
741 cout << "Data Path: " << dataFilePath << endl;
742 cout << "Help Path: " << helpFilePath << endl;
743 cout << "User File: " << userFilePath << endl;
744 cout << "Log File : " << logFilename << endl;
746 cout << "Debug Lvl: " << debugLevel << endl;
749 } //- End of DumpConfiguration
751 //- HandleQtell ------------------------------------------------------------
752 int Mamer::HandleQtell(char *message) {
754 int isOnline; // Opposite of what is returned in qtell report
756 sscanf(message, "*qtell %s %d*", name, &isOnline);
757 isOnline = !isOnline;
771 //- HandleTell ------------------------------------------------------------
772 int Mamer::HandleTell(char *message) {
773 char *p = NULL, *q = NULL, *command = NULL, *tmpCom=NULL;
774 char user[32] = {'\0'};
775 int i=0, pos = 0, tmp=0, len = 0, ret = 0, tellSize=12; /* size of " tells you:" */
777 //- Parse apart tell message
778 //- <user> tells you: <mesg>
779 //- <user>(*) tells you: <mesg>
780 //- <user>(TM)(GM)(*)..... tells you: <mesg>
781 if((p = strstr(message, "(")) && (q = strstr(message, " tells you:")) && (strlen(p) > strlen(q))) {
782 tmp = strlen(p) - strlen(q); /* get the diff to add back in later */
783 pos = strlen(message) - strlen(p);
784 memset(user, '\0', 32);
785 strncpy(user, message, MIN(pos, 31));
786 pos += (tellSize + tmp);
788 p = strstr(message, " tells you:");
789 pos = strlen(message) - strlen(p);
790 memset(user, '\0', 32);
791 strncpy(user, message, MIN(pos, 31));
797 len = strlen(&(message[pos]));
798 command = new char[len + 1]; memset(command, '\0', (len + 1));
799 tmpCom = new char[len + 1]; memset(tmpCom, '\0', (len + 1));
800 if(NULL == command) {
801 cerr << "ERROR: problems allocating memory" << endl;
805 strncpy(command, &(message[pos]), len);
807 while((command[i] != '\0') && (command[i] != ' ')) tmpCom[i] = command[i++];
810 Command *comm = NULL;
811 comm = FindCommand(tmpCom, user);
820 if(10 <= debugLevel) {
821 cout << "Tell Msg: " << message << endl;
822 cout << "User is: " << user << " Command is: " << command<< "\n" << endl;
825 if(ParseParams(comm, command) == COM_BADPARAMETERS) {
826 TellUser(comm, user);
838 CheckUser(user); // This should never happen because we did it above.
843 if((u->GetManagerLevel()) >= (comm->GetManagerLevel())) {
844 ret = (this->*(comm->userFunction))(u, comm->params);
846 cout << comm->GetCommandName() << " return value " << ret << endl;
847 if(((ret == 2) && (!(strcasecmp(comm->GetCommandName(), "setres")))) ||
848 ((ret == 1) && (!(strcasecmp(comm->GetCommandName(), "withdraw")))) ||
849 ((ret == 1) && (!(strcasecmp(comm->GetCommandName(), "forfeit"))))) {
851 } else if ((ret != 0) && (!(strcasecmp(comm->GetCommandName(), "setmanagerlevel")))) {
852 AdjustManagerList(ret, comm->params[0].val.word);
855 TellUser(NoPermissions, user);
865 } //- End of HandleTell
867 //- HandleChannel ------------------------------------------------------------
868 int Mamer::HandleChannel(char *message) {
869 char *q, *p = NULL, channel[8], mess[1024];
870 char user[NAMELEN] = {'\0'};
871 int pos = 0, index=0;
872 char *hilist[] = {"hi ", "hello ", "howdy ", "aloha ", "hola ", "bonjour ", "tag ", NULL };
873 char *thanklist[] = {"thanks ", "thank you ", "thanx ", "gracias ", NULL };
874 char *byelist[] = {"bye ", "later ", "caio ", "adios ", "hasta la vista ", NULL };
875 char *swearlist[] = {"fuck", "shit", "god damn", "asshole", "cunt", "cock", "bullshit", "nigger", "asswipe", NULL };
877 //- Parse apart channel message
878 //- <user>(1): <mesg>
879 //- <user>(*)(24): <mesg>
880 //- <user>(TM)(49): <mesg>
881 if((p = strchr(message, '('))) {
882 pos = strlen(message) - strlen(p);
883 memset(user, '\0', NAMELEN);
884 strncpy(user, message, MIN(pos, NAMELEN-1));
888 if(0 == strcasecmp(user, username)) return 1;
890 p = strchr(message, ':');
891 while(*p != '(') p--;
893 while(*p != ')') { *q++ = *p++; }
896 p = strchr(message, ':'); p++;
898 while(*p != '\0') { *q++ = *p++; }
902 printf("%s %s %s\n", user, channel, mess);
904 mess[strlen(mess)] = '\0';
909 while (swearlist[index] != NULL) {
910 if (strstr(mess, swearlist[index])) {
911 printf("ABUSE - %s %s\n", user, mess);
912 XServerCom("%s %s\n", "+ c49muzzle", user);
917 if ((strstr(mess, username)) && (pos == 0)) {
920 while (hilist[index] != NULL) {
921 if (strstr(mess, hilist[index])) {
922 XServerCom("%s %s Hi %s :-)\n", "tell", channel, user);
929 while (thanklist[index] != NULL) {
930 if (strstr(mess, thanklist[index])) {
931 XServerCom("%s %s You're welcome %s!\n", "tell", channel, user);
938 while (byelist[index] != NULL) {
939 if (strstr(mess, byelist[index])) {
940 XServerCom("%s %s Sad to see you going, %s :(\n", "tell", channel, user);
946 if (strstr(mess, "tourn"))
947 XServerCom("%s %s %s %s %s\n",
948 "tell", channel, "To see a list of tourneys type: tell", username, "lt");
951 } //- End of HandleChannel
953 //- HandleConnect ------------------------------------------------------------
954 int Mamer::HandleConnect(char *message) {
955 char *p = NULL, *reg = NULL, user[80] = {'\0'}, output[256] = {'\0'}, tmp[32] = {'\0'};
957 TourneyPlayers *tp = NULL;
958 LinkListIter<Tourney> tourneyIter(tourneyList);
959 int announceConnect = 0;
961 //- Parse apart connect message
962 //- [<user> (R: 123.123.123.123) has connected.]
964 cout << "\nConnect Msg: " << message << endl;
966 if((p = strstr(message, " (U:"))) { return(1); }
967 if(!(p = strstr(message, " (R: "))) { return(1); }
968 strncpy(user, &(message[1]), MIN(strlen(message) - strlen(p) - 1, 79));
969 reg = strstr(message, " (R: ");
970 if(reg) { //If this is a registered user
972 while((t = tourneyIter.Next())) {
973 if((tp = t->GetPlayer(user))) {
974 tp->location = ONLINE;
978 if(announceConnect) { // If the player arriving is in a tourney tell us he is arriving.
980 sprintf(output, "%s %d %s %s", "tell", channelNumber, user, "has connected. Entered in tourney(s):");
982 while((t = tourneyIter.Next())) {
983 if(t->GetStatus() != DONE) {
984 if((tp = t->GetPlayer(user))) {
985 sprintf(tmp, " %d", t->number);
991 if(announceConnect) {
992 XServerCom("%s %s %d%s", "tournset", user, 1, "\n");
993 XServerCom("%s%s", output, "\n");
997 if(15 <= debugLevel) {
998 cout << "\nConnect Msg: " << message << endl;
999 cout << "Ignoring User: " << user << endl;
1003 } //- End of HandleConnect
1005 //- HandleDisconnect --------------------------------------------------------
1006 int Mamer::HandleDisconnect(char *message) {
1007 char *p = NULL, user[80] = {'\0'}, output[256] = {'\0'}, tmp[32] = {'\0'};
1009 TourneyPlayers *tp = NULL;
1010 LinkListIter<Tourney> tourneyIter(tourneyList);
1011 int announceDisconnect = 0;
1013 //- Parse apart disconnect message
1014 //- [<user> has disconnected.]
1015 p = strstr(message, " has disconnected.");
1016 strncpy(user, &(message[1]), MIN(strlen(message) - strlen(p) - 1, 79));
1018 if(10 <= debugLevel) {
1019 cout << "Disconnect Msg: " << message << endl;
1020 cout << "User is: " << user << "\n" << endl;
1023 LinkListIter<User> userIter(userList);
1025 while((u = userIter.Next()))
1026 if(1 == u->IsUser(user))
1030 tourneyIter.Reset();
1031 while((t = tourneyIter.Next())) {
1032 if((tp = t->GetPlayer(user))) {
1033 tp->location = GONE;
1034 announceDisconnect = 1;
1037 if(announceDisconnect) { // If the player arriving is in a tourney tell us he is arriving.
1038 announceDisconnect = 0;
1039 sprintf(output, "%s %d %s %s", "tell", channelNumber, user, "has disconnected. Entered in tourney(s):");
1040 tourneyIter.Reset();
1041 while((t = tourneyIter.Next())) {
1042 if(t->GetStatus() != DONE) {
1043 if((tp = t->GetPlayer(user))) {
1044 sprintf(tmp, " %d", t->number);
1045 strcat(output, tmp);
1046 announceDisconnect = 1;
1050 if(announceDisconnect) {
1051 XServerCom("%s %s %d%s", "tournset", user, 1, "\n");
1052 XServerCom("%s%s", output, "\n");
1055 u->SavePlayer(userFilePath);
1060 } //- End of HandleDisconnect
1062 //- AdjustManagerList ----------------------
1063 void Mamer::AdjustManagerList(int value, char *name) {
1064 Storage *tmp=NULL, *newName=NULL;
1065 LinkListIter<Storage> managerIter(storageList);
1067 char filename[128], manager[NAMELEN];
1068 int added=0, needToAdd=1;
1070 memset(filename, '\0', 128);
1071 sprintf(filename, "%s/managers", dataFilePath);
1072 theFile = fopen(filename, "r");
1073 if(theFile == NULL) return;
1075 memset(manager, '\0', NAMELEN);
1076 while(fscanf(theFile, "%s", manager) > 0) { // build the temporary list
1077 tmp = new Storage(manager, 0);
1078 storageList.Append(tmp);
1080 memset(manager, '\0', NAMELEN);
1086 managerIter.Reset(); // remove a manager from the list that is printed later
1087 while((tmp = managerIter.Next()))
1088 if(strlen(tmp->name) == strlen(name))
1089 if(0 == (strcasecmp(tmp->name, name)))
1090 storageList.Delete(tmp);
1091 XServerCom("%s %s\n", "- mamermgr", name);
1094 newName = new Storage(name, 0);
1095 added = 0; // Add a user to the manager list that is later printed
1097 managerIter.Reset(); // Got through the list see if the name is there
1098 while((tmp = managerIter.Next()))
1099 if(strlen(tmp->name) == strlen(newName->name))
1100 if(0 == strcasecmp(tmp->name, newName->name)) {
1104 if(needToAdd) { // If its not there we have to add it
1105 managerIter.Reset();
1106 while((tmp = managerIter.Next())) // if the name in the list is > new name
1107 if((strncasecmp(tmp->name, newName->name, MIN(strlen(tmp->name), strlen(newName->name)))) > 0) {
1109 storageList.Insert(tmp, newName); // insert the new name before the list name
1112 if(!added) storageList.Append(newName);
1113 XServerCom("%s %s\n", "+ mamermgr", name);
1119 theFile = fopen(filename, "w");
1120 if(!theFile) return;
1121 managerIter.Reset(); // Lets write the new manager file
1122 while((tmp = managerIter.Next())) {
1123 fprintf(theFile, "%s\n", tmp->name);
1124 storageList.Delete(tmp);
1127 // if(newName != NULL) delete(newName);
1130 //- UserIsLoaded --------------------------
1131 int Mamer::UserIsLoaded(char *uname) {
1133 LinkListIter<User> userIter(userList);
1135 while((u = userIter.Next())) {
1136 if(0 == strcasecmp(u->name, uname))
1141 }//- end UserIsLoaded ------------------------------------------------------
1143 /* this function checks if the user is loaded and if not loads the user */
1144 //- CheckUser ---------------------------------------------------------------
1145 void Mamer::CheckUser(char *user) {
1146 if(!UserIsLoaded(user)) {
1148 cout << "CheckUser - Adding User:" << user << ":" << endl;
1150 User *newUser = NULL;
1151 newUser = new User(userFilePath, user);
1153 userList.Append(newUser);
1155 }//- end of CheckUser -----------------------------------------------------
1157 //- HandleGame ------------------------------------------------------------
1158 int Mamer::HandleGame(char *message) {
1159 char *p, *q, user1[NAMELEN], user2[NAMELEN], action[256], result[8], tmp[256];
1160 int gameNumber, clocktime, inc, rated, isPrivate, result_code, moreGames=1, moreRounds=1, madeMoreGames=0, gameType=-2;
1163 TourneyPlayers *tp = NULL;
1165 printf("MESSAGE: %s\n", message);
1167 // {Game 8 (Blammor vs. Havard) Blammor resigns} 0-1
1169 sscanf(message, "{Game %d (%s vs. %s", &gameNumber, user1, user2);
1170 user2[strlen(user2)-1] = '\0';
1172 if((p = strchr(message, ')'))) {
1173 q = action; p++; p++;
1174 while((*p != '\0') && (*p != '}')) { *q++ = *p++; }
1176 } else { return 0; }
1178 memset(result, '\0', 8);
1179 if((p = strchr(message, '}')) &&
1180 ((strstr(message, ") Creating ") == NULL) && (strstr(message, ") Continuing ") == NULL))) {
1181 // sscanf(p, "} %s [%d %d %d %d", result, &clocktime, &inc, &rated, &isPrivate);
1182 sscanf(p, "} %s [%d %d %d %d %d", result, &clocktime, &inc, &rated, &isPrivate, &gameType);
1184 if(!strcmp(result, "1-0")) { result_code = 1;
1185 } else if(!strcmp(result, "0-1")) { result_code = 0;
1186 } else if(!strcmp(result, "1/2-1/2")) { result_code = 2;
1187 } else { result_code = -1; }
1190 // printf("\nGame #%d %s vs. %s action=%s result=%s time=%d inc=%d rated=%d private=%d\n",
1191 // gameNumber, user1, user2, action, result, clocktime, inc, rated, isPrivate);
1192 printf("\nGame #%d %s vs. %s action=%s result=%s time=%d inc=%d rated=%d private=%d gameType=%d\n",
1193 gameNumber, user1, user2, action, result, clocktime, inc, rated, isPrivate, gameType);
1195 LinkListIter<Tourney> tourneyIter(tourneyList);
1196 tourneyIter.Reset();
1197 while((t = tourneyIter.Next())) {
1198 if(t->GetStatus() != CLOSED) continue;
1199 LinkListIter<Game> gameIter(t->gameList);
1201 while((g = gameIter.Next())) {
1202 if(g->IsGame(user1, user2, clocktime, inc, rated, 'r')) { //- There is room to add isPrivate later
1203 XServerCom("%s %i %s %s %s %s%i %s %s %s\n", "tell", channelNumber, g->whiteName, "vs.", g->blackName,
1204 "a game in tourney #", t->number, "just ended. ", action, result);
1205 if(strcmp(result, "*") == 0) {
1209 moreGames = t->SetGameResult(user1, user2, result_code); //- SetGameResult deletes the game for us
1210 if(moreGames == 2) {
1211 moreRounds = (t->GetRoundsRemaining());
1212 LinkListIter<TourneyPlayers> playerIter(t->playerList);
1215 madeMoreGames = t->MakeAssignments();
1216 while((tp = playerIter.Next())) {
1217 sprintf(tmp, "%s tells you: listplayers %d\n", tp->name, t->number);
1221 t->TellThemWhoTheyPlay();
1222 } else { // tourney over!
1223 AnnounceTourneyEnd(t);
1226 } else { // tourney over!
1228 while((tp = playerIter.Next())) {
1229 sprintf(tmp, "%s tells you: listplayers %d\n", tp->name, t->number);
1233 AnnounceTourneyEnd(t);
1242 XServerCom("%s %s %s", "getgi", user1, "\n");
1245 } //- End of HandleGame
1247 //- HandleGameInfo ----------------------------------------------------------
1248 int Mamer::HandleGameInfo(char *message) {
1249 char white[NAMELEN], black[NAMELEN], player[NAMELEN];
1250 int gameNumber, gameTime, inc, rated, isPrivate;
1254 sscanf(message, "*getgi %s %s %s %d %d %d %d %d*", player, white, black,
1255 &gameNumber, &gameTime, &inc, &rated, &isPrivate);
1257 gameTime = gameTime / 600; // Values for getgi are in micro and nano seconds
1260 LinkListIter<Tourney> tourneyIter(tourneyList);
1261 tourneyIter.Reset();
1262 while((t = tourneyIter.Next())) {
1263 if(t->GetStatus() != CLOSED) continue;
1264 LinkListIter<Game> gameIter(t->gameList);
1266 while((g = gameIter.Next())) {
1267 if(g->IsGame(white, black, gameTime, inc, rated, 'r')) { //- There is room to add isPrivate later
1268 if(g->gameNumber < 0){
1269 XServerCom("%s %i %s %s %s %s%i %s\n", "tell", channelNumber, white, "vs.", black,
1270 "a game in tourney #", t->number, "just started.");
1272 XServerCom("%s %i %s %s %s %s%i %s\n", "tell", channelNumber, white, "vs.", black,
1273 "a game in tourney #", t->number, "just Restarted.");
1275 g->gameNumber = gameNumber;
1280 } //- End of HandleGameInfo
1282 //- HandlePlayerInfo --------------------------------------------------------
1283 int Mamer::HandlePlayerInfo(char *message) {
1284 char player[NAMELEN];
1285 int ratings[6], return_from_AddPlayer, tourneyNumber;
1289 sscanf(message, "*getpi %s %d %d %d %d %d %d*", // Scan in the info
1290 player, &ratings[0], &ratings[2], &ratings[3], &ratings[1], &ratings[4], &ratings[5]);
1293 printf("Get Player Info: %s blitz=%d stand=%d light=%d wild=%d bug=%d suicide=%d\n",
1294 player, ratings[2], ratings[3], ratings[1], ratings[0], ratings[4], ratings[5]);
1296 p = FindPending(player);
1297 printf("player p=%d\n", p);
1299 tourneyNumber = p->value; // find out which tourney we want
1300 t = FindTourney(tourneyNumber); // Get the tourney. If its in the list it should be valid
1303 } //Check for valid tourney is done in CommandEntry::JoinTourney
1305 return_from_AddPlayer = t->AddPlayer(player, ratings[t->GetVariant()], 0.0);
1306 printf("ret = %d\n", return_from_AddPlayer);
1307 TellUser(JoinedTourney, player, return_from_AddPlayer);
1308 if(return_from_AddPlayer == 1)
1309 XServerCom("%s %s %d%s", "tournset", player, 1, "\n");
1310 pendingList.Delete(p); //This is safe cause to get here we had to find a Player p
1313 } //- End of HandlePlayerInfo
1315 //- FindPending ---------------------------------------------------------------
1316 Player *Mamer::FindPending(char *user) {
1318 LinkListIter<Player> pendingIter(pendingList);
1320 while((p = pendingIter.Next()))
1321 if(1 == p->IsPlayer(user))
1325 } //- End of FindPending
1327 //- FindUser ---------------------------------------------------------------
1328 User *Mamer::FindUser(char *user) {
1330 LinkListIter<User> userIter(userList);
1332 // printf("FindUser: %18s\n", user);
1334 while((u = userIter.Next()))
1335 if(1 == u->IsUser(user))
1339 } //- End of FindUser
1341 //- FindTourney ------------------------------------------------------------
1342 Tourney *Mamer::FindTourney(int tourn) {
1344 LinkListIter<Tourney> tourneyIter(tourneyList);
1346 while((t = tourneyIter.Next())) {
1347 if(1 == t->IsTourney(tourn))
1351 } //- End of FindUser
1353 //- FindCommand ---------------------------------------------------------------
1354 Command *Mamer::FindCommand(char *comm, char *user) {
1355 Command *c = NULL, *cnull=NULL;
1356 LinkListIter<Command> commIter(commandList);
1357 int commandsFound=0;
1358 char* output = NULL;
1360 output = new char[MAX_LINE_SIZE];
1361 memset(output, '\0', MAX_LINE_SIZE);
1363 while((c = commIter.Next())) {
1364 if(c->IsCommand(comm)) {
1366 if((int)(strlen(output) + strlen(c->GetCommandName())) < (MAX_LINE_SIZE - 1))
1367 sprintf(output, "%s %s", output, c->GetCommandName());
1370 output[strlen(output)] = '\0';
1373 while((c = commIter.Next()))
1374 if(1 == c->IsCommand(comm))
1377 switch (commandsFound) {
1379 TellUser(BadCommand, user);
1384 TellUser(MultiCommand, user, output);
1387 } //- End of FindUser
1390 Parameter string format
1392 o - an optional word
1394 p - optional integer
1396 n - optional word or integer
1398 t - optional string to end
1400 If the parameter option is given in lower case then the parameter is
1401 converted to lower case before being passsed to the function. If it is
1402 in upper case, then the parameter is passed as typed.
1404 Calling these Appends adds commands to the link list. They are called with:
1405 1) the text command Mamer should look for
1406 2) an alias or substitute for that text
1407 3) the manager level one needs to be to execute this command
1408 4) a BRIEF description of the command's function
1409 5) the parameter types for each parameter (see comments above)
1410 6) what code to use when telling the user they did something wrong (see TellUser)
1411 7) and the function pointer to the CommandEntry.cc code that is this command */
1413 //- BuildCommandList ---------------------------------------------------------
1414 void Mamer::BuildCommandList(void) {
1415 commandList.Append(new Command("addchaos", "ac", MANAGER, "Adds (or subs) chaos points.",
1416 "wp", (USERFP)&Mamer::AddAbuse));
1418 commandList.Append(new Command("announce", "ann", DIRECTOR, "Announce the tournament to the working channel.",
1419 "d", (USERFP)&Mamer::AnnounceTourney));
1421 commandList.Append(new Command("addtotourney", "att", VICE, "Add a user to a tourney.",
1422 "Wd", (USERFP)&Mamer::AddToTourney));
1424 commandList.Append(new Command("create", "cr", DIRECTOR, "Creates a new tournament.",
1425 "", (USERFP)&Mamer::CreateTourney));
1427 commandList.Append(new Command("close", "cl", DIRECTOR, "Closes and starts a tournament.",
1428 "d", (USERFP)&Mamer::CloseTourney));
1430 commandList.Append(new Command("delete", "del", DIRECTOR, "Deletes a tournament.",
1431 "d", (USERFP)&Mamer::DeleteTourney));
1433 commandList.Append(new Command("finger", "fi", USER, "Displays the stats for a user.",
1434 "O", (USERFP)&Mamer::FingerUser));
1436 commandList.Append(new Command("forfeit", "fo", DIRECTOR, "Remove a user from a tourney.",
1437 "wd", (USERFP)&Mamer::RemoveFromTourney));
1439 commandList.Append(new Command("join", "j", USER, "Request to enter a tourney.",
1440 "d", (USERFP)&Mamer::JoinTourney));
1442 commandList.Append(new Command("keep", "k", MANAGER, "Keep a tourney in memory.",
1443 "di", (USERFP)&Mamer::KeepTourney));
1445 commandList.Append(new Command("listmanagers", "lm", USER, "Displays the Managers list.",
1446 "", (USERFP)&Mamer::ListManagers));
1448 commandList.Append(new Command("listtourneys", "lt", USER, "Displays the tournament list.",
1449 "", (USERFP)&Mamer::ListTourneys));
1451 commandList.Append(new Command("listtourneyvars", "vars", USER, "Displays the tournament variables.",
1452 "d", (USERFP)&Mamer::ListTourneyVars));
1454 commandList.Append(new Command("listtourneygames", "games", USER, "Displays the tournament games.",
1455 "d", (USERFP)&Mamer::ListTourneyGames));
1457 commandList.Append(new Command("listplayers", "lp", USER, "Displays the players in the tourney.",
1458 "d", (USERFP)&Mamer::ListTourneyPlayers));
1460 commandList.Append(new Command("listrank", "rank", USER, "Displays player rank.",
1461 "n", (USERFP)&Mamer::ListRank));
1463 commandList.Append(new Command("loadedusers", "lu", MANAGER, "Displays the loaded users.",
1464 "", (USERFP)&Mamer::LoadedUsers));
1466 commandList.Append(new Command("messman", "mm", VICE, "Message all of the Managers.",
1467 "s", (USERFP)&Mamer::MessageManagers));
1469 commandList.Append(new Command("open", "ot", DIRECTOR, "Opens the tournament to players.",
1470 "d", (USERFP)&Mamer::OpenTourney));
1472 commandList.Append(new Command("setcommandlevel", "setcl", VICE, "Set the level required to execute a command.",
1473 "wd", (USERFP)&Mamer::SetCommandLevel));
1475 commandList.Append(new Command("setinfo", "si", VICE, "Set a user's finger info.",
1476 "Wddddddd", (USERFP)&Mamer::SetInfo));
1478 commandList.Append(new Command("setmanagerlevel", "sml", VICE, "Sets manager's level.",
1479 "Wd", (USERFP)&Mamer::SetManagerLevel));
1481 commandList.Append(new Command("setres", "sr", DIRECTOR, "Sets the result of a game.",
1482 "dWWi", (USERFP)&Mamer::SetResult));
1484 commandList.Append(new Command("setstat", "ss", VICE, "Sets a specific finger stat.",
1485 "Wwd", (USERFP)&Mamer::SetStat));
1487 commandList.Append(new Command("settourneyvar", "stv", DIRECTOR, "Sets a Tourney's Variables.",
1488 "dwi", (USERFP)&Mamer::SetTourneyVariable));
1490 commandList.Append(new Command("showcommands", "sc", USER, "List commands and descripts.",
1491 "o", (USERFP)&Mamer::ShowCommands));
1493 commandList.Append(new Command("showhelpfile", "shf", USER, "Shows a help file.",
1494 "o", (USERFP)&Mamer::ShowHelp));
1496 commandList.Append(new Command("help", "help", USER, "Shows a help file.",
1497 "o", (USERFP)&Mamer::ShowHelp));
1499 commandList.Append(new Command("shutdown", "sd", VICE, "Shuts down Mamer.",
1500 "", (USERFP)&Mamer::Shutdown));
1502 commandList.Append(new Command("who", "who", USER, "Displays the tournament games.",
1503 "d", (USERFP)&Mamer::ListTourneyPlayers));
1505 commandList.Append(new Command("withdraw", "with", USER, "Remove yourself from a tourney.",
1506 "d", (USERFP)&Mamer::RemoveFromTourney));
1508 } //- End of BuildCommandList
1510 //- NextRound -------------------------
1511 void Mamer::NextRound() {
1512 int moreGames=0, moreRounds=1, madeMoreGames=0;
1516 LinkListIter<Tourney> tourneyIter(tourneyList);
1517 tourneyIter.Reset();
1518 while((t = tourneyIter.Next())) {
1519 if(t->GetStatus() != CLOSED) continue;
1520 moreRounds = (t->GetRoundsRemaining());
1522 LinkListIter<Game> gameIter(t->gameList);
1524 while((g = gameIter.Next())) moreGames++;
1526 if(moreGames == 0) {
1527 if(debugLevel >= 10)
1528 cout << "No more games! Next Round Please! From Next Round" << endl;
1529 cerr << "No more games! Next Round Please! From Next Round" << endl;
1531 madeMoreGames = t->MakeAssignments();
1533 t->TellThemWhoTheyPlay();
1534 else { // tourney over!
1535 cerr << "Coulnd't make any more games. End of Tourney. From Next Round" << endl;
1536 AnnounceTourneyEnd(t);
1539 } else { // tourney over!
1540 cerr << "No more rounds. End of Tourney. From Next Round" << endl;
1541 AnnounceTourneyEnd(t);
1546 } //- End of NextRound
1548 //- XServerCom ---------------------------------------------
1549 int Mamer::XServerCom(char *fmt, ...)
1555 va_start(argptr, fmt);
1556 count = vsprintf(buffer, fmt, argptr);
1557 write(serverSocket, buffer, strlen(buffer));
1560 /* returns number of elements written */
1563 //- End of XServerCom
1565 //- TellUser ------------------------------------------------
1566 void Mamer::TellUser(reasons reason, char *name) {
1569 XServerCom("qtell %s %s notes: Sorry you do not have permission to do that.\n", name, username);
1572 XServerCom("qtell %s %s notes: Command not found.\n", name, username);
1577 }//- End of TellUser
1579 //- TellUser ------------------------------------------------
1580 void Mamer::TellUser(reasons reason, char *name, int number) {
1585 XServerCom("qtell %s %s notes: %s\n", name, username,
1586 "Can not join\\nYour rating does not fit into current limits. <check tourney vars>");
1589 XServerCom("qtell %s %s notes: %s\n", name, username, "You joined the tournament.");
1592 XServerCom("qtell %s %s notes: %s\n", name, username, "You are already in this tourney.");
1595 XServerCom("qtell %s %s notes: %s\n", name, username, "You can not join. Tourney is not open.");
1601 case NotEnoughPlayers:
1602 XServerCom("qtell %s %s notes: Tourney#%d %s\n", name, username, number, "does not have enough players.");
1605 XServerCom("qtell %s %s notes: Tourney#%d %s\n", name, username, number, "has no players.");
1607 case WillKeepTourney:
1608 XServerCom("qtell %s %s notes: Tourney#%d %s\n", name, username, number, "will be kept.");
1610 case NotKeepTourney:
1611 XServerCom("qtell %s %s notes: Tourney#%d %s\n", name, username, number, "will not be kept.");
1613 case TourneyNotFound:
1614 XServerCom("qtell %s %s notes: %s%d %s\n", name, username, "Tourney #", number, "not found.");
1617 XServerCom("qtell %s %s notes: %s%d\n", name, username, "Player not found in tourney #", number);
1619 case GameResultNotFound:
1620 XServerCom("qtell %s %s notes: %s%d\n", name, username, "Can not set result to ", number);
1623 XServerCom("qtell %s %s notes: You don't have change permissions for tourney #%d.\n", name, username, number);
1626 XServerCom("qtell %s %s notes: %s %s%d %s\n", name, username, "Can not do that right now.",
1627 "Tourney #", number, "is not new.");
1629 case TourneyNotOpen:
1630 XServerCom("qtell %s %s notes: %s %s%d %s\n", name, username, "Can not do that right now.",
1631 "Tourney #", number, "is not open.");
1633 case TourneyNotClosed:
1634 XServerCom("qtell %s %s notes: %s %s%d %s\n", name, username, "Can not do that right now.",
1635 "Tourney #", number, "is not closed.");
1638 XServerCom("qtell %s %s notes: %s %s%d %s\n", name, username, "Can not do that anymore.",
1639 "Tourney #", number, "is done.");
1642 XServerCom("qtell %s %s notes: %s %s%d %s\n", name, username, "Can not do that anymore.",
1643 "Tourney #", number, "is closed.");
1645 case TourneyDeleted:
1646 XServerCom("qtell %s %s Notes: %s %s%d %s\n", name, username, "\\n", "Tourney #",
1647 number, " has been deleted.");
1652 }//- End of TellUser
1654 //- TellUser ------------------------------------------------
1655 void Mamer::TellUser(Command *comm, char *name) {
1657 int i, length=strlen(comm->parameterList);
1659 sprintf(line, "qtell %s %s notes: Usage: %s ", name, username, comm->GetCommandName());
1661 for(i=0; i<length; i++) {
1662 switch (comm->parameterList[i]) {
1664 strcat(line, "<word> ");
1667 strcat(line, "<optional word> ");
1670 strcat(line, "<integer> ");
1673 strcat(line, "<optional int> ");
1676 strcat(line, "<word or int> ");
1679 strcat(line, "<optional word or int> ");
1682 strcat(line, "<string> ");
1685 strcat(line, "<optional string> ");
1692 write(serverSocket, line, strlen(line));
1693 }//- End of TellUser
1695 //- TellUser ------------------------------------------------
1696 void Mamer::TellUser(reasons reason, char *name, char *request) {
1699 XServerCom("qtell %s %s notes: Sorry %s is not found.\n", name, username, request);
1702 XServerCom("qtell %s %s notes: %s\n", name, username, request);
1705 XServerCom("qtell %s %s notes: Changed the info for %s.\n", name, username, request);
1707 case GameResultNotFound:
1708 XServerCom("qtell %s %s notes: %s %s\n", name, username, "Can not set result to", request);
1711 XServerCom("qtell %s %s notes: Ambiguous Command Matches:\\n %s\n", name, username, request);
1716 }//- End of TellUser
1718 //- TellUser ------------------------------------------------
1719 void Mamer::TellUser(reasons reason, char *name, char *who, char *which, int new_value) {
1722 XServerCom("qtell %s %s notes: Changed the %s stat for %s to %d.\n", name, username, which, who, new_value);
1725 switch (new_value) {
1727 XServerCom("qtell %s %s notes: The game %s(w) vs. %s(b) has been set to 1-0\n", name, username, who, which);
1730 XServerCom("qtell %s %s notes: The game %s(w) vs. %s(b) has been set to 0-1\n", name, username, who, which);
1733 XServerCom("qtell %s %s notes: The game %s(w) vs. %s(b) has been set to 1/2-1/2\n", name, username, who, which);
1740 }//- End of TellUser
1742 //- TellUser ------------------------------------------------
1743 void Mamer::TellUser(reasons reason, char *name, char *which, char *new_value) {
1746 XServerCom("qtell %s %s notes: Can not change the %s var to %s.\n", name, username, which, new_value);
1749 XServerCom("qtell %s %s notes: Changed %s to %s.\n", name, username, which, new_value);
1754 }//- End of TellUser
1757 //- TellUser ------------------------------------------------
1758 void Mamer::TellUser(reasons reason, char *name, char *uname, int new_value) {
1760 case ChangedManagerLevel:
1761 XServerCom("qtell %s %s notes: %s's Manager Level has been changed to %d\n", name, username, uname,new_value);
1763 case ChangedCommandLevel:
1764 XServerCom("qtell %s %s notes: The %s command's manager Level has been changed to %d\n",name,username,uname, new_value);
1767 XServerCom("qtell %s %s notes: %s Has been removed from tourney #%i\n", name, username, uname, new_value);
1770 XServerCom("qtell %s %s notes: %s Is not found in tourney #%i\n", name, username, uname, new_value);
1773 XServerCom("qtell %s %s notes: %s's Chaos Points have been changed to %d\n",name, username, uname, new_value);
1776 XServerCom("qtell %s %s notes: Can Not Change the %s stat to %d.\n", name, username, uname, new_value);
1779 XServerCom("qtell %s %s notes: Changed %s to %d.\n", name, username, uname, new_value);
1784 }//- End of TellUser
1786 //- ParseParams ----------------------------------------------
1787 int Mamer::ParseParams(Command *comm, char *parameters) {
1792 for (i = 0; i < MAXNUMPARAMS; i++)
1793 comm->params[i].type = TYPE_NULL; /* Set all parameters to NULL */
1794 parlen = strlen(comm->parameterList);
1795 parameters = eatWhite(parameters); /* remove and spaces before the command */
1796 parameters = eatWord(parameters); /* remove the command itself */
1797 for (i = 0; i < parlen; i++) {
1798 c = comm->parameterList[i];
1807 case 'o': /* word or optional word */
1808 parameters = eatWhite(parameters);
1810 return (c == 'o' ? COM_OK : COM_BADPARAMETERS);
1811 comm->params[i].val.word = parameters;
1812 comm->params[i].type = TYPE_WORD;
1813 parameters = eatWord(parameters);
1814 if (*parameters != '\0') {
1819 stolower(comm->params[i].val.word);
1823 case 'p': /* optional or required integer */
1824 parameters = eatWhite(parameters);
1826 return (c == 'p' ? COM_OK : COM_BADPARAMETERS);
1827 if (sscanf(parameters, "%d", &comm->params[i].val.integer) != 1)
1828 return COM_BADPARAMETERS;
1829 comm->params[i].type = TYPE_INT;
1830 parameters = eatWord(parameters);
1831 if (*parameters != '\0') {
1838 case 'n': /* optional or required word or integer */
1839 parameters = eatWhite(parameters);
1841 return (c == 'n' ? COM_OK : COM_BADPARAMETERS);
1842 if (sscanf(parameters, "%d", &comm->params[i].val.integer) != 1) {
1843 comm->params[i].val.word = parameters;
1844 comm->params[i].type = TYPE_WORD;
1846 comm->params[i].type = TYPE_INT;
1848 parameters = eatWord(parameters);
1849 if (*parameters != '\0') {
1853 if (comm->params[i].type == TYPE_WORD)
1855 stolower(comm->params[i].val.word);
1859 case 't': /* optional or required string to end */
1861 return (c == 't' ? COM_OK : COM_BADPARAMETERS);
1862 comm->params[i].val.string = parameters;
1863 comm->params[i].type = TYPE_STRING;
1865 parameters = nextWord(parameters);
1867 stolower(comm->params[i].val.string);
1872 return COM_BADPARAMETERS;
1875 } //- End ParseParams ------------------
1877 //- isWhiteSpace -------------------------------------------
1878 int Mamer::isWhiteSpace (int c) {
1879 if ((c < ' ') || (c == '\b') || (c == '\n') ||
1880 (c == '\t') || (c == ' ')) { /* white */
1885 } //- End isWhiteSpace -------
1887 //- getWord ------------------------------------------------
1888 char *Mamer::getWord (char *str) {
1890 static char word[MAX_WORD_SIZE];
1893 while (*str && !isWhiteSpace(*str)) {
1897 if (i == MAX_WORD_SIZE) {
1904 } //- End getWord -------------
1906 //- eatWord -------------------------------------------
1907 char *Mamer::eatWord (char *str) {
1908 while (*str && !isWhiteSpace(*str))
1913 //- eatWhite ------------------------------------------
1914 char *Mamer::eatWhite (char *str) {
1915 while (*str && isWhiteSpace(*str))
1918 } //- eatWhite --------
1920 //- eatTailWhite -------------------------------------------
1921 char *Mamer::eatTailWhite (char *str) {
1927 while (len > 0 && isWhiteSpace(str[len - 1]))
1931 } //- End of eatTailWhite -----------
1933 //- nextWord -----------------------------------------------
1934 char *Mamer::nextWord(char *str) {
1935 return eatWhite(eatWord(str));
1936 } //- End of nextWord
1938 char *Mamer::stolower(char *str) {
1943 for (i = 0; str[i]; i++) {
1944 if (isupper(str[i])) {
1945 str[i] = tolower(str[i]);
1951 //- GenerateTourneyNumber ----------------------------------------------
1952 int Mamer::GenerateTourneyNumber(void) {
1954 int maxT = 0, used=0, i, count=0;
1955 LinkListIter<Tourney> tourneyIter(tourneyList);
1957 if(NULL != tourneyList.Head()) {
1958 while((t = tourneyIter.Next()))
1961 for(i=1; i<=count; i++) {
1963 tourneyIter.Reset();
1964 while((t = tourneyIter.Next())) {
1967 if(t->number > maxT)
1980 // $Log: Mamer.cc,v $
1981 // Revision 1.17 1998/09/10 19:57:17 mlong
1982 // lots of little bug fixes and a few new features
1984 // Revision 1.16 1998/08/04 21:02:13 mlong
1985 // changes to correct a few bugs including the this->* change that
1986 // correctly uses the function pointers now
1988 // Revision 1.15 1998/06/18 18:41:30 mlong
1989 // prepairing for yet another move.
1991 // Revision 1.14 1998/06/04 19:55:00 mlong
1992 // quick change to the load config file stuff to
1993 // allow for a commented out line
1995 // Revision 1.13 1998/04/29 15:23:19 mlong
1996 // prepairing for the move to daimi
1997 // new sorting routine.
1999 // Revision 1.12 1998/04/18 18:46:04 mlong
2000 // fixed delete bug &
2001 // added delete tourney function
2003 // Revision 1.11 1998/04/17 00:14:37 mlong
2004 // fixes to the setres working with the Link delete method
2006 // Revision 1.7 1997/10/22 19:47:38 mlong
2007 // fixed bug for parsing tells into user and command.
2009 // Revision 1.6 1997/10/08 21:03:35 chess
2010 // preparing for move to oracle machine at eworks.
2012 // Revision 1.5 1997/05/15 18:27:53 chess
2013 // added Player and TourneyPlayers support
2014 // added HandleGetPlayerInfo & HandleetGameInfo
2016 // Revision 1.4 1997/04/13 03:14:35 chess
2017 // commands to do user stats manipulation added
2018 // also TellUser function added to make for easier reporting and bug checking
2019 // also added ParseParams that takes the commands parameter list definition
2020 // and parses out the input from the user to determine if the paramters
2021 // supplied are correct. If so it then sends those params to the
2024 // Revision 1.3 1997/03/21 15:31:04 moses
2025 // added the cleanup of commands
2026 // added the cleanup of tourneys
2027 // added the mamer shutdown command
2029 // Revision 1.2 1996/10/01 20:14:43 moses
2030 // Changes to incorparte the new usage of the command list
2032 // Revision 1.1 1996/09/30 20:52:48 moses