home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / OPENSTEP / Games / NeXTGo-3.0-MIS / igsparse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-06  |  12.7 KB  |  569 lines

  1. #include "comment.header"
  2.  
  3. /* $Id: igsparse.c,v 1.3 1997/07/06 19:35:01 ergo Exp $ */
  4.  
  5. /*
  6.  * $Log: igsparse.c,v $
  7.  * Revision 1.3  1997/07/06 19:35:01  ergo
  8.  * actual version
  9.  *
  10.  * Revision 1.3  1997/05/04 18:57:06  ergo
  11.  * added time control for moves
  12.  *
  13.  */
  14.  
  15. #include "igs.h"
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <sys/types.h>
  20.  
  21. #define prompts Prompts
  22. #include "shared.h"
  23.  
  24. extern char *getloginname();
  25. extern char *getpassword();
  26. int loggedon;
  27. int repeatpass, repeatlogin;
  28. State state_t;
  29. int verts[3][MAX_BRD_SZ+1], num_ranks;
  30. char *ranks[50];
  31.  
  32. #ifdef STRSTR
  33. char *strstr();
  34. #endif
  35.  
  36. #ifdef STRTOL
  37. long strtol();
  38. #endif
  39.  
  40. char *Prompts[] =
  41. {
  42.   "Login: ",
  43.   "Password: ",
  44.   "Password: ",
  45.   "Enter Your Password Again: ",
  46.   "Enter your e-mail address (None): ",
  47.   "#> ",
  48.   "#> ",
  49.   "Enter Dead Group: ",
  50.   "#> ",
  51.   "#> ",
  52. };
  53.  
  54.  
  55. void initparser()
  56. {
  57.   loggedon = 0;
  58.   repeatpass = 0;
  59.   repeatlogin = 0;
  60. }
  61.  
  62.  
  63. int DoState(char *s)
  64. {
  65.     if (strncmp(s, Prompts[LOGON], strlen(Prompts[LOGON])) == 0)
  66.         return LOGON;
  67.     if (strncmp(s, "1 1", 3) == 0)
  68.         return PASSWORD;
  69.     if (strncmp(s, "1 0", 3) == 0)
  70.         return LOGON;
  71.     if (strncmp(s, Prompts[PASSWORD], strlen(Prompts[PASSWORD])) == 0)
  72.         return PASSWORD;
  73.     if (strncmp(s, Prompts[PASSWD_NEW], strlen(Prompts[PASSWD_NEW])) == 0)
  74.         return PASSWD_NEW;
  75.     if (strncmp(s, Prompts[PASSWD_CONFIRM], strlen(Prompts[PASSWD_CONFIRM])) == 0)
  76.         return PASSWD_CONFIRM;
  77.     if (strncmp(s, Prompts[WAITING], strlen(Prompts[WAITING])) == 0)
  78.         return WAITING;
  79.       return -1;
  80. }
  81.  
  82. static long appending = 0;
  83.  
  84. char retbuf[1000];
  85. int idle;
  86.  
  87. int getmessage(message *mess, int uninitiated)
  88. {
  89.     char mesg[2000];
  90.     int ret;
  91.     char *textpart;
  92.  
  93.     idle = 0;
  94.       if (!uninitiated) {
  95.         pollserver();
  96.     }
  97.       strcpy(mesg, retbuf);
  98.  
  99.     switch (DoState(mesg)) {
  100.         case PASSWD_NEW:
  101.         case PASSWD_CONFIRM:
  102.         case PASSWORD:
  103.             sendstr(getpassword(repeatpass++));
  104.             sendstr("\n");
  105.             break;
  106.         case WAITING:
  107.             sendstr("toggle client true\n");
  108.             mess->id = ONSERVER;
  109.             loggedon = 1;
  110.             sendstr("chars #O.?-++\n");
  111.             return 1;
  112.         case LOGON:    {
  113.               int needlogin;
  114.               needlogin = 1;
  115.               do {
  116.                 if (needlogin == 1) {
  117.                       sendstr(getloginname(repeatlogin++));
  118.                       sendstr("\n");
  119.                       needlogin = -1;
  120.                 }
  121.                 ret = pollserver();
  122.                 strcpy(mesg, retbuf);
  123.                 if (ret < 0)
  124.                       return ret;
  125.                     if (!strncmp(mesg, "Password:", 9) 
  126.                         || (!strncmp(mesg, "1 1", 3)))
  127.                           needlogin = 0;
  128.                     else if (!strncmp(mesg, "Sorry", 5)) {
  129.                               puts(mesg);
  130.                               return 0;
  131.                          } 
  132.                          else if (strlen(mesg)>2 && strncmp(mesg,"Login",5))
  133.                                     puts(mesg);
  134.               } while (needlogin);
  135.               sendstr(getpassword(repeatpass++));
  136.               sendstr("\n");
  137.               do {
  138.                 ret = pollserver();
  139.                 strcpy(mesg, retbuf);
  140.                 if (ret < 0)
  141.                       return ret;
  142.                 if (!strncmp(mesg, "Enter", 5)) {
  143.                       sendstr(getpassword(repeatpass++));
  144.                       sendstr("\n");
  145.                 }
  146.                 if (!strncmp(mesg, "9 File", 6))
  147.                       needlogin = -1;
  148.                 if (!strncmp(mesg, "To get", 6))
  149.                       needlogin = 1;
  150.                 if (!strncmp(mesg, "#>", 2)) {
  151.                       sendstr("toggle client true\n");
  152.                       mess->id = ONSERVER;
  153.                       loggedon = 1;
  154.                       sendstr("chars #O.?-++\n");
  155.                       return 1;
  156.                 }
  157.                 if (!strncmp(mesg, "Invalid", 7)) {
  158.                       puts(mesg);
  159.                       needlogin = 1;
  160.                 }
  161.               } while (!needlogin);
  162.       
  163.               if (needlogin > 0)
  164.                 break;
  165.         }            /* intentional fall through occurs here */
  166.           default:
  167.             mess->id = strtol(mesg, &textpart, 10);
  168.             textpart++;
  169.             if (mess->id == 2 && (strstr(textpart, "Game") 
  170.                                     || strstr(textpart, "min")))
  171.                   mess->id = TIMEREP;
  172.             if (appending == -1) {
  173.                 if (mess->id && !strncmp(textpart, "File", 4)) {
  174.                     appending = 0;
  175.                     if (!strncmp(mess->text, "                *=============", 29))
  176.                           mess->id = QUITMESG;
  177.                     return 1;
  178.                   }
  179.                   if (strlen(mess->text))
  180.                     strcat(mess->text, "\n");
  181.                   {
  182.                         int len;
  183.                         char *pt;
  184.                         len = strlen(mesg);
  185.                         pt = mesg;
  186.                         while (len > 0) {
  187.                               strncat(mess->text, pt, 79);
  188.                               len -= 79;
  189.                               pt += 79;
  190.                               mess->lines++;
  191.                               if (len > 0)
  192.                                 strcat(mess->text, "\n");
  193.                         }            
  194.                   }
  195.                   return 0;
  196.             }
  197.             if (mess->id == PROMPT) {
  198.                   if (*textpart == '5' && !loggedon)
  199.                     loggedon = 1;
  200.                   if (appending == LOOK_M) {
  201.                     mess->id = LOOK_M;
  202.                     appending = 0;
  203.                     return 1;
  204.                   }
  205.                   if (appending && !(appending == SCORE && mess->bscore == -10000)) {
  206.                     mess->id = appending;
  207.                     appending = 0;
  208.                     return 1;
  209.                   }
  210.                   mess->prompttype = atoi(textpart);
  211.             }
  212.             if (!strcmp(textpart, "File" /* , 4 */ )) {
  213.                   appending = -1;
  214.                   strcpy(mess->text, "");
  215.                   mess->lines = 0;
  216.                   return 0;
  217.             }
  218.             if (mess->id == BEEP) {
  219.                   mess->beep = (*textpart == 7);
  220.             }
  221.             if (mess->id == KIBITZ) {
  222.                   if (parsekibitz(textpart, mess))
  223.                 return 0;
  224.             }
  225.             if (mess->id == UNDO)
  226.                   if (ret = parseundo(textpart, &(mess->gamenum))) {
  227.                     if (ret < 0)
  228.                           return ret;
  229.                     return 0;
  230.                   }
  231.             if (mess->id == MOVE) {
  232.                   if (parsemove(textpart, &(mess->x), 
  233.                     &(mess->y), &(mess->movenum),
  234.                     &(mess->gamenum), &(mess->color), 
  235.                     &(mess->bcap), &(mess->btime),
  236.                     &(mess->bbyo), &(mess->wcap), 
  237.                     &(mess->wtime), &(mess->wbyo))) {
  238.                     mess->id = 0;
  239.                 }
  240.             }
  241.             if (mess->id == WHO) {
  242.                   appending = WHO;
  243.                   parsewho(mess, textpart);
  244.                   return 0;
  245.             }        
  246.             if (mess->id == GAMES) {
  247.                   appending = GAMES;
  248.                   parsegame(mess, textpart);
  249.                   return 0;
  250.                 }
  251.             if (mess->id == LOOK_M) {
  252.                   appending = LOOK_M;
  253.                   parsescore(mess, textpart);
  254.                   return 0;
  255.             }
  256.             if (mess->id == SCORE) {
  257.                   appending = SCORE;
  258.                   parsescore(mess, textpart);
  259.                   return 0;
  260.             }
  261.             strcpy(mess->text, textpart);
  262.             mess->lines = 1;
  263.             if (mess->id == INFO)
  264.                   if (ret = parseinfo(textpart, mess))
  265.                     return ret;
  266.                 return 1;
  267.     }    
  268.     return 0;
  269. }
  270.  
  271. #ifdef STRTOL
  272. long strtol(char *text, char **new, int dum) {
  273.     long retu;
  274.     retu = atol(text);
  275.     for (*new = text; *new && **new <= '9' && **new >= '0'; (*new)++);
  276.     return retu;
  277. }
  278. #endif
  279.  
  280.  
  281.  
  282. #ifdef STRSTR
  283. char *strstr(char *s1, char *s2)
  284. {
  285.   register char *temp;
  286.   int len;
  287.   
  288.   temp = s1;
  289.   len = strlen(s2);
  290.   while (temp = strchr(temp, *s2)) {
  291.     if (!strncmp(temp, s2, len))
  292.       return temp;
  293.     else
  294.       temp++;
  295.   }
  296.   return NULL;
  297. }
  298. #endif
  299.  
  300.  
  301. void parsescore(message *mesg, char *s) {
  302.     char *bd;
  303.     int i;
  304.   
  305.     bd = strstr(s, ">>");
  306.     if (bd)
  307.         *(bd + 1) = '|';
  308.       bd = strstr(s, "<<");
  309.       if (bd)
  310.         *bd = '|';
  311.       if (strstr(s, "H-cap")) {
  312.         mesg->boardline = 0;
  313.         mesg->bscore = -10000;
  314.       } 
  315.     else 
  316.         if (bd = strchr(s, '|')) {
  317.             for (bd++, i = 0; *(bd - 1) != '|' || i == 0; bd += 2, i++) {
  318.                   if (i >= mesg->boardsize)
  319.                     mesg->boardsize = i + 1;
  320.                   if (i < 19 && mesg->boardline < 19)
  321.                     switch (*bd) {
  322.                         case '.':
  323.                               mesg->board[i][mesg->boardline] = EMPTY;
  324.                               break;
  325.                         case '#':
  326.                               mesg->board[i][mesg->boardline] = BLACK;
  327.                               break;
  328.                         case 'O':
  329.                               mesg->board[i][mesg->boardline] = WHITE;
  330.                               break;
  331.                         case '-':
  332.                               mesg->board[i][mesg->boardline] = WTERR;
  333.                               break;
  334.                         case '+':
  335.                               mesg->board[i][mesg->boardline] = BTERR;
  336.                               break;
  337.                         case '?':
  338.                               mesg->board[i][mesg->boardline] = DAME;
  339.                               break;
  340.                     }
  341.             }
  342.             mesg->boardline++;
  343.           } 
  344.         else
  345.             sscanf(s, "%*[^ ] (W:O): %f to %*[^ ] (B:#): %f",
  346.                    &(mesg->wscore), &(mesg->bscore));
  347.           if (bd = strstr(s, "Captured by #"))
  348.             mesg->wcap = atoi(bd + strlen("Captured by #: "));
  349.           if (bd = strstr(s, "Captured by O"))
  350.             mesg->bcap = atoi(bd + strlen("Captured by O: "));
  351. }
  352.  
  353.  
  354. void parsewho(message *mesg, char *str) {
  355.     if (!strncmp(str, "Info", 4)) {
  356.         strcpy(mesg->text, str);
  357.         mesg->lines = 1;
  358.       }
  359.     else {
  360.         strcat(mesg->text, "\n");
  361.         strcat(mesg->text, str);
  362.         mesg->lines++;
  363.       }
  364. }
  365.  
  366.  
  367. void parsegame(message *mesg, char *str) {
  368.     int fieldcount;
  369.     char *br, *wr, blackrank[10], whiterank[10];
  370.     int obcount;
  371.   
  372.     if (str[1] == '#') {
  373.         mesg->gamecount = 0;
  374.         strcpy(mesg->text, str);
  375.         mesg->lines = 1;
  376.       } else {
  377.         strcat(mesg->text, "\n");
  378.         strcat(mesg->text, str);
  379.         mesg->lines++;
  380.  
  381.         /* hacked for systems that don't like %[^]] */
  382.         for (br = str; *br; br++)
  383.               if (*br == ']')
  384.                 *br = '!';
  385.         fieldcount = sscanf(str, "[%3d!%12s [%[^!]! vs.%12s [%[^!]! (%3d %d %d %f %d%*c%*c%*c) ( %d)\n",
  386.             &(mesg->gamelist[mesg->gamecount].gnum),
  387.             mesg->gamelist[mesg->gamecount].white,
  388.             whiterank,
  389.             mesg->gamelist[mesg->gamecount].black,
  390.             blackrank,
  391.             &(mesg->gamelist[mesg->gamecount].mnum),
  392.             &(mesg->gamelist[mesg->gamecount].bsize),
  393.             &(mesg->gamelist[mesg->gamecount].hcap),
  394.             &(mesg->gamelist[mesg->gamecount].komi),
  395.             &(mesg->byo),
  396.             &obcount);
  397.     
  398.         br = blackrank;
  399.         wr = whiterank;
  400.         br[5] = br[5] = 0;
  401.         while (*br == ' ')
  402.               br++;
  403.         while (*wr == ' ')
  404.               wr++;
  405.         while (br[strlen(br)-1] == ' ')
  406.               br[strlen(br)-1] = 0;
  407.         while (wr[strlen(wr)-1] == ' ')
  408.               wr[strlen(wr)-1] = 0;
  409.         strcpy(mesg->gamelist[mesg->gamecount].wrank, wr);
  410.         strcpy(mesg->gamelist[mesg->gamecount].brank, br);
  411.         if (fieldcount == 11)
  412.               (mesg->gamecount)++;
  413.       }    
  414. }
  415.  
  416.  
  417. int parseinfo(char *s, message *mess) {
  418.     int ret, row;
  419.     extern int MAXY;
  420.     extern void igsbeep();
  421.     char col;
  422.     char text[100];
  423.  
  424.     if ((2 == sscanf(s, "Match[%dx%d]", &ret, &ret)) ||
  425.         (2 == sscanf(s, "Match [%dx%d]", &ret, &ret))) {
  426.         igsbeep();
  427.         return 0;
  428.     }
  429.     if (1 == sscanf(s, "Match [%d]", &(mess->gamenum))) {
  430.         mess->id = MATCH;
  431.         return 0;
  432.     }
  433.     if (1 == sscanf(s, "Creating match [%d]", &(mess->gamenum))) {
  434.         mess->id = MATCH;
  435.         return 0;
  436.     }
  437.     if (2 == sscanf(s, "Removing @ %c%d", &col, &row)) {
  438.         if (col > 'I')
  439.               col--;
  440.         mess->x = col - 'A';
  441.         mess->y = MAXY - row;
  442.         mess->id = REMOVE;
  443.         return 0;
  444.       }
  445.       if (!strncmp(s, "Board is restored", 17)) {
  446.         mess->id = SCOREUNDO;
  447.         return 0;
  448.     }
  449.       if (strstr(s, "has restored your old game.")) {
  450.         mess->id = LOAD;
  451.         ret = pollserver();
  452.         strcpy(text, retbuf);
  453.         if (ret < 0)
  454.               return ret;
  455.         ret = pollserver();
  456.         strcpy(text, retbuf);
  457.         if (ret < 0)
  458.               return ret;
  459.         ret = sscanf(text, "%*d Game %d: %*[^(](%d %d %d) vs %*[^(](%d %d %d)",
  460.              &(mess->gamenum), &(mess->bcap), &(mess->btime),
  461.              &(mess->bbyo), &(mess->wcap), &(mess->wtime), &(mess->wbyo)
  462.              );
  463.         ret = pollserver();
  464.         strcpy(text, retbuf);
  465.         if (ret < 0)
  466.               return ret;
  467.         return 0;
  468.       }
  469.       return 0;
  470. }
  471.  
  472.  
  473. static int gamenumber = -1;
  474.  
  475. /* Undo in game 0: zzz vs anthony:  D11 */
  476. /* Game 0: testa (0 0 0) vs testb (0 0 0) with move line afterwords */
  477.  
  478. int parseundo(char *s, int *gamenum)
  479. {
  480.     char mes[2000];
  481.     int count;
  482.     int bogus2, ret;
  483.     char bogus1;
  484.     
  485.     count = sscanf(s, "%*[^ ] undid the last move (%c%d).", &bogus1, &bogus2);
  486.     if (count == 2) {
  487.         ret = pollserver();
  488.         strcpy(mes, retbuf);
  489.         if (ret < 0)
  490.               return ret;
  491.         ret = pollserver();
  492.         strcpy(mes, retbuf);
  493.         if (ret < 0)
  494.               return ret;
  495.     
  496.         sscanf(mes, "%*d Game %d", gamenum);
  497.         ret = pollserver();
  498.         strcpy(mes, retbuf);
  499.         if (ret < 0)
  500.               return ret;
  501.         return 0;
  502.       }
  503.     count = sscanf(s, "Undo in game %d", gamenum);
  504.     if (count != 1)
  505.         return 1;            /* extra line */
  506.     return 0;
  507. }
  508.  
  509.  
  510. /* new format:  ## game gamenum: plr (cap time byo) vs plr (cap time byo) */
  511.  
  512. int parsekibitz(char *s, message *mess) {
  513.     if (1 == sscanf(s, "Kibitz %[^:]", mess->kibitzer))
  514.         return 1;
  515.     while (*s == ' ')
  516.         s++;
  517.     strcpy(mess->kibitz, s);
  518.     return 0;
  519. }
  520.  
  521.  
  522. int parsemove(char *s, int *x, int *y, int *mv, int *gm, int *color, int *bcap,
  523.           int *btime, int *bbyo, int *wcap, int *wtime, int *wbyo)
  524. {
  525.     int mc;
  526.     char c, col;
  527.     extern int MAXY, handicap;
  528.   
  529.     mc = sscanf(s, "%3d(%c): %c%d", mv, &c, &col, y);
  530.     if (mc == 3) {
  531.         if (3 == sscanf(s, "%3d(%c): Handicap %d", mv, &c, &mc)) {
  532.             handicap = mc;
  533.             *x = *y = mc + 100;
  534.             *gm = gamenumber;
  535.             *color = c == 'W' ? WHITE : BLACK;
  536.             (*mv)++;
  537.             return 0;
  538.         }
  539.         if (2 == sscanf(s, "%3d(%c): Pass", mv, &c)) {
  540.             *x = *y = -1;
  541.               *gm = gamenumber;
  542.               *color = c == 'W' ? WHITE : BLACK;
  543.               (*mv)++;
  544.               return 0;
  545.         }
  546.     }
  547.     if (mc != 4) {
  548.         sscanf(s, "Game %d %*c: %*[^(](%d %d %d) vs %*[^(](%d %d %d)",
  549.                 &gamenumber, wcap, wtime, wbyo, bcap, btime, bbyo);
  550.         return 1;
  551.     }
  552.     if (col > 'I')
  553.         col--;
  554.     *x = col - 'A';
  555.     *y = MAXY - *y;
  556.     *color = c == 'W' ? WHITE : BLACK;
  557.     *gm = gamenumber;
  558.     (*mv)++;
  559.     return 0;
  560. }
  561.  
  562.  
  563. int doneline(char *inbuf, int inptr) {
  564.     return !loggedon &&
  565.         (inptr > 0 && inbuf[inptr - 1] == ' ') &&
  566.           ((inptr > 1 && inbuf[inptr - 2] == ':') ||
  567.            (inptr > 2 && inbuf[inptr - 2] == '>' && inbuf[inptr - 3] == '#'));
  568. }
  569.