⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 console.c

📁 3号作品是分析WarCraft III游戏的replay文件的命令行工具
💻 C
字号:
/* console interface */

#include "crc32.h"
#include <ctype.h>
#include "srv.h"
#include <string.h>

void console(char *filename)
{
  char *strtolower(char *);
  int  parse(char *, char **);
  int  searchchar(char, char*);
  int  time2ms(char *, DWORD *);
  
  char line[300], *s[10],  part;
  int  errorno, exit = 1, pos, filestatus = 0;
  extern DWORD gametime;
  DWORD t1, t2;
  const char helpinfo[] = "\
IN|INPUT [filename]\n\
  Set the input replay file. If the filename is omitted, current link to the\n\
  replay file will be canceled.\n\
INFO\n\
  Show the basic infomation of the replay file.\n\
P|PLAYER\n\
  Show the players of the game, including computer players, open slots and\n\
  closed slots.\n\
APM [[T1]-[T2]]\n\
  Show the APM (Actions Per Minute) of each player. T1 and T2 can be expressed\n\
  in one of the following forms:\n\
  s   OR   m:ss\n\
  If T1 is omitted, APM will be calculated from the beginning of the game.\n\
  If T2 is omitted, APM will be calculated until the end of the game.\n\
H|HELP\n\
  Show this message.\n\
ABOUT\n\
  About this program.\n\
EXIT\n\
  Exit SRV.\n";
  const char aboutinfo[]="\
Simple Replay Viewer for Warcraft III\n\
Author: zengyuxiao@hotmail.com\n\
Compiled with gcc-3.4.5-3 & mingw-runtime-3.14\n\
External library: zlib(http://www.zlib.net)\n\
\n\
Thanks to blue, nagger and their friends for the structure of replay file.\n\
Thanks to Krzysztof Dabrowski and ElysiuM deeZine for functions to calculate\n\
CRC32 checksum.\n\
\n\
Special thanks to IceThunder\n";
  const char *errorinfo[] = {
        "Invalid command.\n",
        "Command too long.\n",
        "Bad file name or permission needed.\n",
        "Data corrupted or invalid file.\n",
        "Memory not enough.\n",
        "No file loading.\n",
        "zlib1.dll version error.\n",
        "T2 must be larger than T1.\n"
  };
  
  chksum_crc32gentab(); //initialize crc32 function
  if (filename) 
    if ((in = fopen(filename, "rb")) == NULL) 
      printf(errorinfo[2]); // opening fail
    else {
      errorno = readdata();
      fclose(in); // no more need to read the file
      if (errorno) {
        filestatus = 0;
        printf(errorinfo[-errorno]);
      } // error
      else
        filestatus = 1; // opening success
    }
  while (exit) {
    putchar('>');
    gets(line);
    if ((part = parse(line, s)) == -1) printf(errorinfo[1]);          // error
    else if (part == 0) ;                                             // nothing
    else if (!(strcmp(strtolower(s[0]), "help") && strcmp(s[0], "h")))// help
      printf(helpinfo);
    else if (!strcmp(s[0], "about"))                                  // about
      printf(aboutinfo);
    else if (!(strcmp(s[0], "in") && strcmp(s[0], "input"))) {        // input
      if (part > 2) printf(errorinfo[0]);                 // part  > 2
      else if (part == 2) {                               // part == 2
        if (filestatus) {
          filestatus = 0;
          freemem();
        } // close the previous file
        if ((in = fopen(s[1], "rb")) == NULL)
          printf(errorinfo[2]); // opening fail
        else {
          errorno = readdata();
          fclose(in); // no more need to read the file
          if (errorno) {
            filestatus = 0;
            printf(errorinfo[-errorno]);
          } // error
          else
            filestatus = 1; // opening success
        }
      } // part == 2
      else                                                // part == 1
        if (filestatus) {
          filestatus = 0;
          freemem();
        } // part == 1
    }
    else if (!strcmp(s[0], "exit"))                                   // exit
      exit = 0;
    else if (!strcmp(s[0], "info"))                                   // info
      if (!filestatus) printf(errorinfo[5]); else info();
    else if (!(strcmp(s[0], "p") && strcmp(s[0], "player")))          // player
      if (!filestatus) printf(errorinfo[5]); else player();
    else if (!strcmp(s[0], "apm"))                                    // apm
      if (!filestatus) printf(errorinfo[5]);
      else if (part > 2) printf(errorinfo[0]);            // part  > 2
      else if (part == 2)
        if ((pos = searchchar('-', s[1])) < 0) printf(errorinfo[0]);
        else {
          s[1][pos] = 0;
          if (time2ms(s[1], &t1)) printf(errorinfo[0]);
          else if (time2ms(s[1] + pos + 1, &t2)) printf(errorinfo[0]);
          else if (t2 && (t2 > t1)) apm(t1, t2);
          else if (!t2) apm (t1, gametime);
          else printf(errorinfo[7]);
        }                                                 // part == 2
      else apm(0, gametime);                              // part == 1
    else printf(errorinfo[0]);                                        // error
    for (part--;part>=0;part--) free(s[part]);
    putchar('\n');
  } // while
  if (filestatus) freemem();
}

char *strtolower(char *s)
{
     char *t = s;
     while (*t) {
           *t = tolower(*t);
           t++;
     }
     return s;
}

int parse(char *input, char *output[])
{
     int i = 0, j = 0, flag = 1, quote = 1; /* flag  == 1: end of an old string
                                             *          0: processing a string
                                             * quote == 1: not in quotes
                                             *          0: in quotes
                                             */
     while (*input) {
       switch (*input) {
         case '\"': quote = !quote; break;
         case ' ' : if (quote)
                      if (flag) break; else {
                        flag = 1;
                        output[i++][j] = 0;
                        j = 0;
                        break;
                      }
         default  : if (flag) output[i] = (char *) calloc(256, sizeof(char));
                    flag = 0;
                    if (i<10 && j<255) output[i][j++] = *input; else {
                      for (;i>=0;i--) free(output[i]);
                      return -1; //command too long
                    }
       }
       input++;
     }
     if (i == 0 && j == 0) return 0; // if input contains nothing but spaces
     if (!flag) output[i][j] = 0;
     if (i<9) output[i+1] = 0; //end of command-parsing
     return i + 1; //normal
}

int searchchar(char c, char *s)
{
    int i = 0, found = 0, pos;
    
    while (s[i]) {
      if (s[i] == c) {
        if (found) return -2;
        found = 1;
        pos = i;
      }
      i++;
    }
    if (found) return pos; else return -1;
}

int time2ms(char *s, DWORD *t)
{
    int num1 = 0, num2 = 0, semicolin = 0;
    
    while (*s && !semicolin) {
      switch (*s) {
        case '0' ... '9': ((num1 *= 10), num1) += *s - '0'; break;
        case ':': semicolin = 1; break;
        default: *t = 0; return -1;
      }
      s++;
    }
    if (semicolin) {
      if (isdigit(*s)) num2 = *s - '0'; else {
        *t = 0;
        return -1;
      }
      if (isdigit(*++s)) ((num2 *= 10), num2) += *s - '0'; else {
        *t = 0;
        return -1;
      }
      if (*++s) {
        *t = 0;
        return -1;
      }
      *t = (num1 * 60 + num2) * 1000;
    } else *t = num1 * 1000;
    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -