Thursday 8 May 2014

Out of Interest

Here's how a non l33t h4X0R might knock up a quick program to get the data out of the sensi dat files. It could be optimized, cleaned up, and generally written much better. But it gets the job done and that's all we care about for a one-shot program!
1:  // number of players ineach team  
2:  const unsigned int PLAYERS_PER_TEAM = 16;  
3:  // number of characters in player name  
4:  const unsigned int PLAYER_NAME_LENGTH = 23;  
5:  // number of characters in team name  
6:  const unsigned int TEAM_NAME_SIZE = 19;  
7:  // number of characters in coach name  
8:  const unsigned int COACH_NAME_SIZE = 25;  
9:  struct PLAYER  
10:  {  
11:  SNIP!   
12:  };  
13:  struct KIT  
14:  {  
15:  SNIP!  
16:  };  
17:  struct TEAM  
18:  {  
19:  SNIP!  
20:  };  
21:  int main(int argc, char *argv[])  
22:  {  
23:      // must be 2  
24:      if ( argc != 2 )   
25:      {  
26:          std::cout << "ERROR:"              << std::endl;  
27:          std::cout << "----------------------------"   << std::endl;  
28:          std::cout << "usage: sensi_data <filename>"  << std::endl;  
29:          std::cout << "----------------------------"   << std::endl;  
30:          return 1;  
31:      }  
32:      // a list to store the teams  
33:      std::vector< TEAM > all_teams;  
34:      // open the teams data file as an input stream  
35:      std::ifstream input (argv[1], std::ios::in | std::ios::binary);  
36:      // team file data starts at byte 1  
37:      int byte_index = 1;  
38:      // stream input into this  
39:      unsigned char x;  
40:      // vector to store all bytes (loading them in to this first makes it easy to  
41:      // inspect the bytes in the debugger)  
42:      std::vector<unsigned char> bytes;  
43:      // tell the input stream NOT to skip anything (white spaces etc)  
44:      input >> std::noskipws;  
45:      // load the bytes into a vector  
46:      while (input >> x) {  
47:          bytes.push_back(x);  
48:      }  
49:      // loop controllers to parse all teams  
50:      int current_team = 1;  
51:      // the second byte in the file gives us the number of teams in the file  
52:      int number_teams = bytes[byte_index++];      
53:      // main loop for each team  
54:      while (current_team++ < number_teams){  
55:        // store the ripped data in a TEAM struct  
56:        TEAM team;  
57:        // unknown byte at start of each team (wtf?)  
58:        byte_index++;          
59:        team.nation   = bytes[byte_index++];      // team country code          
60:        team.id     = bytes[byte_index++];      // team id  
61:        team.id2    = bytes[byte_index++];      // unknown id  
62:        team.x1     = bytes[byte_index++];      // unknown byte  
63:        for(int i=0;i<TEAM_NAME_SIZE;i++){  
64:            team.name[i] = bytes[byte_index++];   // team name   
65:        }          
66:        team.tactics  = bytes[byte_index++];      // tactics code  
67:        team.division  = bytes[byte_index++];      // division  
68:        // -------------------------------------------  
69:        // KITS  
70:        // -------------------------------------------  
71:        team.kit1.type = bytes[byte_index++];      // kit 1 type  
72:        team.kit1.col1 = bytes[byte_index++];      // kit 1 main color  
73:        team.kit1.col2 = bytes[byte_index++];      // kit 1 secondary color  
74:        team.kit1.shorts= bytes[byte_index++];      // kit 1 shorts color  
75:        team.kit1.socks = bytes[byte_index++];      // kit 1 socks color  
76:        team.kit2.type = bytes[byte_index++];      // kit 2 type  
77:        team.kit2.col1 = bytes[byte_index++];      // kit 2 main color  
78:        team.kit2.col2 = bytes[byte_index++];      // kit 2 secondary color  
79:        team.kit2.shorts= bytes[byte_index++];      // kit 2 shorts color  
80:        team.kit2.socks = bytes[byte_index++];      // kit 2 socks color  
81:        // -------------------------------------------  
82:        // END KITS  
83:        // -------------------------------------------  
84:        for(int i=0;i<COACH_NAME_SIZE;i++){  
85:            team.coach_name[i] = bytes[byte_index++];// coach name  
86:        }          
87:        for(int i=0;i<15;i++){  
88:            team.x2[i] = bytes[byte_index++]; // 15 bytes of unknown data (what is this FOR?!)  
89:        }  
90:        // -------------------------------------------  
91:        // EACH PLAYER IN THE TEAM  
92:        // -------------------------------------------  
93:        for(unsigned int p=0;p<PLAYERS_PER_TEAM;p++){  
94:            team.players[p].nat = bytes[byte_index++];  // nationality  
95:            team.players[p].x1 = bytes[byte_index++];  // unknown byte  
96:            team.players[p].numb= bytes[byte_index++];  // shirt number  
97:            for(unsigned int i=0;i<PLAYER_NAME_LENGTH;i++){  
98:                team.players[p].name[i] = bytes[byte_index++];  // name  
99:            }  
100:            // ---------------------------------------------------------------  
101:            // PLAYER POSITION  
102:            //  
103:            // this byte stores the players position and skin/hair colour  
104:            // first 3 significant bits signify position as follows:  
105:            //   000 = goalkeeper  
106:            //   001 = right back  
107:            //   010 = left back  
108:            //   011 = defender  
109:            //   100 = right wing  
110:            //   101 = left wing  
111:            //   110 = midfielder  
112:            //   111 = attacker  
113:            //  
114:            // the next 2 bits signify skin/hair color:  
115:            //   00 = white skin/black hair  
116:            //   01 = white skin/blonde hair  
117:            //   10 = black skin/black hair  
118:            //   11 = unknown  
119:            team.players[p].position = (bytes[byte_index++] >> (5)) & 0xff;  
120:            //  
121:            // ---------------------------------------------------------------  
122:            team.players[p].x3     = bytes[byte_index++];// unknown byte  
123:            // ---------------------------------------------------------------  
124:            // player attributes.  
125:            // apart from passing, it's 2 attributes per byte  
126:            // 4 most significant bits and then 4 least significant bits  
127:            // for a total score out of 15 ( binary 1111) for each skill  
128:            // passing  
129:            team.players[p].passing = (bytes[byte_index++] )   & 0xf;   
130:            // shooting  
131:            team.players[p].shooting= (bytes[byte_index] >> (4)) & 0xff;   
132:            // heading  
133:            team.players[p].heading = (bytes[byte_index++] )   & 0xf;   
134:            // tackling  
135:            team.players[p].tackling= (bytes[byte_index] >> (4)) & 0xff;   
136:            // control  
137:            team.players[p].control = (bytes[byte_index++] )   & 0xf;   
138:            // speed  
139:            team.players[p].speed  = (bytes[byte_index] >> (4)) & 0xff;   
140:            // finishing  
141:            team.players[p].finishing= (bytes[byte_index++] )   & 0xf;   
142:            //  
143:            // ---------------------------------------------------------------  
144:            team.players[p].value    = bytes[byte_index++]; // value code  
145:            team.players[p].x4     = bytes[byte_index++]; // unknown byte  
146:            team.players[p].x5     = bytes[byte_index++]; // unknown byte  
147:            team.players[p].x6     = bytes[byte_index++]; // unknown byte  
148:            team.players[p].x7     = bytes[byte_index++]; // unknown byte  
149:            team.players[p].x8     = bytes[byte_index++]; // unknown byte  
150:        }  
151:        // -------------------------------------------  
152:        // END PLAYER  
153:        // -------------------------------------------  
154:        // save the team struct to the list  
155:        all_teams.push_back(team);  
156:      }  
157:      return 0;  
158:  }  

No comments:

Post a Comment