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

📄 dataprocess.c

📁 3号作品是分析WarCraft III游戏的replay文件的命令行工具
💻 C
📖 第 1 页 / 共 2 页
字号:
    
    const char *color[12] = {
               "Red", "Blue", "Cyan", "Purple",
               "Yellow", "Orange", "Green", "Pink",
               "Gray", "Light Blue", "Dark Green", "Brown"
               };
    const char *race[6] = {
               "Human", "Orc", "Nightelf", "Undead", "Daemon", "Random"
               };
    
    offset = dindex[6] + 3;
    nr = *(data + (offset++));
    printf("\
 Slot |   Status   | Team Number |    Color    |   Race   | Name\n"
    );
    for (i=0;i<nr;i++) {
      printf("   %2d | ", i + 1);
      offset += 2;
      switch (*(data + offset)) {
        case 0x00:
          printf("      Open |             |             |          |");
          break;
        case 0x01:
          printf("    Closed |             |             |          |");
          break;
        default:
          if (*(data + offset + 2) - 12) {
            if (*(data + offset + 1))
              printf("  Computer | ");                       
            else
              printf("    Player | ");
            printf("         %2d | %11s | ", 
                   *(data + offset + 2) + 1, color[*(data + offset + 3)]);
            racen = 0;
            while (!((*(data + offset + 4) % 0x40) & (0x1 << racen))
                   && (racen < 8))
              racen++;
            if (racen < 6)
              printf("%8s | %s", race[racen], slot[i].name);
            else
              printf(" Unknown | %s", slot[i].name);
          } else
            printf("  Observer |             |             |          | %s",
                   slot[i].name);
      }
      putchar('\n');
      offset += (ver < 3) ? 5 : ((ver < 7) ? 6 : 7);
    }
}

void apm(DWORD t1, DWORD t2)
{
     DWORD offset, actsum[13] = {}, time_ms[13] = {};
                                 /* time_ms[   0   ] = actual time *
                                  * time_ms[1 .. 12] = player time */
     WORD  blocksize, subblocksize, exitmark = 0;
     int   i, j, playing = 1, timeaddflag, id, DeselectFlag, UpdateSubgroupFlag;
     
     /* sum the numbers of actions*/
     offset = dindex[7];
     while ((offset < rh.uncomp_size) && (time_ms[0] <= t2)) {
       switch (*(data + offset)) {
         case 0x17: // leave game
              exitmark = exitmark | (0x1 << *(data + offset + 5));
              offset += 14; break;
         case 0x1A: case 0x1B: case 0x1C: // startblock?
              offset += 5; break;
         case 0x1E: case 0x1F: // time slot
              blocksize = *(WORD *)(data + offset + 1) - 2; // size of blocks
              offset += 3;
              timeaddflag = playing;
              i = 2;
              while (i < blocksize) {
                id = *(data + offset + (i++));
                subblocksize = *(WORD *)(data + offset + i);
                DeselectFlag = 0;
                UpdateSubgroupFlag = 0;
                j = 0;
                i += 2;
                while (j < subblocksize) {
                  switch (*(data + offset + i + j)) {
                    case 0x01: // pause game
                         playing = 0; j++; break;
                    case 0x02: // resume game
                         playing = 1; timeaddflag = 1; j++; break;
                    case 0x03: // set game speed
                         j += 2; break;
                    case 0x04: case 0x05: // change game speed
                         j++; break;
                    case 0x06: // save game
                         while (*(data + offset + i + (j++))) ; break;
                    case 0x07: // save game finished
                         j += 5; break;
                    case 0x10: // unit/building ability
                         if (time_ms[0] >= t1) actsum[id]++;
                         j += ver<7 ? 6 : (ver<13 ? 14 : 15); break;
                    case 0x11: // unit/building ability
                         if (time_ms[0] >= t1) actsum[id]++;
                         j += ver<7 ? 14 : (ver<13 ? 22 : 23); break;
                    case 0x12: // unit/building ability
                         if (time_ms[0] >= t1) actsum[id]++;
                         j += ver<7 ? 22 : (ver<13 ? 30 : 31); break;
                    case 0x13: // give/drop an item
                         if (time_ms[0] >= t1) actsum[id]++;
                         j += ver<7 ? 30 : (ver<13 ? 38 : 39); break;
                    case 0x14: // unit/building ability
                         if (time_ms[0] >= t1) actsum[id]++;
                         j += ver<7 ? 35 : (ver<13 ? 43 : 44); break;
                    case 0x16: // change selection
                         if (*(data + offset + i + j + 1) == 0x02) // deselect
                         {
                            if (time_ms[0] >= t1) actsum[id]++;
                            DeselectFlag = 2;
                         } else // select
                            if (!DeselectFlag && time_ms[0] >= t1) actsum[id]++;
                         j += 4 + *(WORD *)(data + offset + i + j + 2) * 8;
                         break;
                    case 0x17: // assign group hotkey
                         if (time_ms[0] >= t1) actsum[id]++;
                         j += 4 + *(WORD *)(data + offset + i + j + 2) * 8;
                         break;
                    case 0x18: // select group hotkey
                         if (time_ms[0] >= t1) actsum[id]++;
                         j += 3; break;
                    case 0x19: // select/update subgroup
                         if (ver < 14) {
                           if (*(data + offset + i + j + 1) == 0xFF)
                             UpdateSubgroupFlag = 2;
                           else if (*(data + offset + i + j + 1) &&
                            !UpdateSubgroupFlag && time_ms[0] >= t1)
                             actsum[id]++;
                         }
                         j += ver<14 ? 2 : 13; break;
                    case 0x1A: // depend on the version
                         j += ver<14 ? 10 : 1; break;
                    case 0x1B: // depend on the version
                         if (time_ms[0] >= t1) 
                           actsum[id] += (ver < 14); // apm++ when ver < 14
                         j += 10; break;
                    case 0x1C: // depend on the version
                         if (time_ms[0] >= t1) actsum[id]++;
                         j += ver<14 ? 9 : 10; break;
                    case 0x1D: // depend on the version
                         if (time_ms[0] >= t1) actsum[id]++;
                         j += ver<14 ? 6 : 9; break;
                    case 0x1E: // remove unit from building queue
                         if (time_ms[0] >= t1) actsum[id]++;
                         j += 6; break;
                    case 0x21: // unknown
                         j += 9; break;
                    case 0x20: case 0x22 ... 0x26: case 0x29 ... 0x2C:
                    case 0x2F ... 0x32: // cheat
                         j++; break;
                    case 0x27: case 0x28: case 0x2D: // cheat
                         j += 6; break;
                    case 0x2E: // cheat
                         j += 5; break;
                    case 0x50: // change ally options
                         j += 6; break;
                    case 0x51: // transfer resources
                         j += 10; break;
                    case 0x60: // unknown
                         j += 9;
                         while (*(data + offset + i + (j++))) ; break;
                    case 0x61: // esc pressed
                         if (time_ms[0] >= t1) actsum[id]++; j++; break;
                    case 0x62: // scenario trigger
                         j += 13; break;
                    case 0x65: case 0x66: // enter submenu
                         if (time_ms[0] >= t1) actsum[id]++; j++; break;
                    case 0x67: // depend on the version
                         if (time_ms[0] >= t1)
                           actsum[id] += (ver > 6); // apm++ when ver > 6
                         j += (ver<=6) ? 13 : 1; break;
                    case 0x68: // depend on the version
                         j += (ver<=6) ? 17 : 13; break;
                    case 0x69: case 0x6A: // depend on the version
                         j += 17; break;
                    case 0x75: // unknown
                         j += 2; break;
                    default:
                         j++;
                  } // end of the action block of a player
                  if (DeselectFlag) DeselectFlag--;
                  if (UpdateSubgroupFlag) UpdateSubgroupFlag--;
                } // end of subblock
                i += subblocksize;
              }
              if (timeaddflag) {
                if (time_ms[0] >= t1 && time_ms[0] <= t2)
                  for (i=1;i<=12;i++) if (!(exitmark & (0x1 << i)))
                    time_ms[i] += *(WORD *)(data + offset);
                time_ms[0] += *(WORD *)(data + offset);
              }
              offset += blocksize + 2;
              break;
         case 0x20: // chat message
              offset += 4 + *(WORD *)(data + offset + 2); break;
         case 0x22: // unknown
              offset += 6; break;
         case 0x23: // unknown
              offset += 11; break;
         case 0x2F: // unknown
              offset += 9; break;
         default:
              offset++;
       } // end of a block
     } // end of replay file
     
     /* calculate & output apms */
     printf("\
 Slot |   Player Name   | Actions |  Play Time  | APM\n"
     );
     for (i=1;i<=12;i++) 
       if (slot[i-1].status == 4) {
         printf("  %2d  | %15s | %7u | ", i, slot[i-1].name, actsum[i]);
         if (time_ms[i] >= 3600000) printf("%d:%02d:%02d.%03d | %.2f\n",
           time_ms[i] / 3600000, time_ms[i] / 60000 % 60,
           time_ms[i] / 1000 % 60, time_ms[i] % 1000,
           actsum[i] / ((double) time_ms[i] / 60000));
         else if (time_ms[i] >= 60000) printf("  %2d:%02d.%03d | %.2f\n",
           time_ms[i] / 60000, time_ms[i] / 1000 % 60, time_ms[i] % 1000,
           actsum[i] / ((double) time_ms[i] / 60000));
         else if (time_ms[i] >= 1000) printf("     %2d.%03d | %.2f\n",
           time_ms[i] / 1000, time_ms[i] % 1000,
           actsum[i] / ((double) time_ms[i] / 60000));
         else if (time_ms[i] > 0) printf("%        3d | %.2f\n", time_ms[i],
           actsum[i] / ((double) time_ms[i] / 60000));
         else printf("     -      |   -\n");
       }
}

⌨️ 快捷键说明

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