Skip to content

Commit c1979f6

Browse files
committed
Added extract.py. I use it to test the parsing as I work (don't expect it to work)
1 parent e1fc7b4 commit c1979f6

File tree

1 file changed

+150
-0
lines changed

1 file changed

+150
-0
lines changed

extract.py

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
import zlib, sys, pprint
2+
from sc2reader.utils import ReplayBuffer
3+
from sc2reader.data.build19595 import Data_19595 as DataObject
4+
5+
unitData = DataObject()
6+
7+
races = {'Prot':'Protoss','Zerg':'Zerg','Terr':'Terran','RAND':'Random'}
8+
data_names = [
9+
'R',
10+
'U',
11+
'S',
12+
'O',
13+
'AUR',
14+
'RCR',
15+
'WC',
16+
'UT',
17+
'KUC',
18+
'SB',
19+
'SRC',
20+
21+
]
22+
data_names_pretty = [
23+
'Resources',
24+
'Units',
25+
'Structures',
26+
'Overview',
27+
'Average Unspent Resources',
28+
'Resource Collection Rate',
29+
'Workers Created',
30+
'Units Trained',
31+
'Killed Unit Count',
32+
'Structures Built',
33+
'Structures Razed Count'
34+
]
35+
36+
def getRealm(str):
37+
if str == '\x00\x00S2':
38+
return "EU"
39+
40+
return "?"
41+
def getPlayers(data):
42+
players = []
43+
parr = data[0][3]
44+
for i in range(16):
45+
if not (parr[i][0][1] == 0):
46+
players.append(getPlayer(data, i))
47+
48+
return players
49+
def getIncomeGraph(data, index):
50+
return getGraph(data[4][0][1][1], index)
51+
def getArmyGraph(data, index):
52+
return getGraph(data[4][0][2][1], index)
53+
def getGraph(graph, index):
54+
return [(o[2], o[0]) for o in graph[index]]
55+
def getPlayer(data, index):
56+
pinfo = data[0][3][index]
57+
pdata = data[3][0]
58+
59+
player = {
60+
'id': "{}/{}/{}".format(getRealm(pinfo[0][1][0][1]), pinfo[0][1][0][2], pinfo[0][1][0][3]),
61+
'race' : races[pinfo[2]]
62+
}
63+
64+
stats = {}
65+
66+
for i in range(len(pdata)):
67+
stats[data_names[i]] = pdata[i][1][index][0][0]
68+
stats[data_names[len(pdata)]] = data[4][0][0][1][index][0][0]
69+
player['stats'] = stats
70+
player['graphs'] = {}
71+
player['graphs']['income'] = getIncomeGraph(data, index)
72+
player['graphs']['army'] = getArmyGraph(data, index)
73+
74+
return player
75+
def flip_int(num, b):
76+
"""
77+
Flips the b first bytes in num
78+
Example:
79+
(0x12345, 3) -> 0x452301
80+
(0x00112233, 4) -> 0x33221100
81+
"""
82+
o = 0
83+
for i in range(b/2):
84+
o |= ((num & (0xff << i*8)) << (b-(2*i+1))*8)
85+
o |= ((num & (0xff << (b-(i+1))*8)) >> (b-(2*i+1)) * 8)
86+
if b % 2 == 1:
87+
o |= (num & (0xff << (b/2)*8))
88+
return o
89+
90+
def toTime(bo_time):
91+
return (bo_time >> 8) / 16
92+
def toUnit(bo_unit):
93+
#print(hex(flip_int(bo_unit, 4)))
94+
i = ((bo_unit & 0xff) << 8) | 0x01
95+
if bo_unit >> 24 == 1:
96+
return {'name':unitData.type(i).name, 'id':hex(i)}
97+
return None
98+
def getBuildOrder(unit_structs, index):
99+
''' [ {supply, time, unit} ] '''
100+
bo = []
101+
for unit_struct in unit_structs:
102+
for u in unit_struct:
103+
unit = toUnit(u[0][1])
104+
if not unit:
105+
continue
106+
for entry in u[1][index]:
107+
bo.append({
108+
'supply' : entry[0],
109+
'total_supply' : entry[1]&0xff,
110+
'time' : toTime(entry[2]),
111+
'time_hex' : hex(entry[2]>>8),
112+
'unit' : unit,
113+
'build_index' : entry[1] >> 16,
114+
'struct_as_hex' : {0:hex(entry[0]),
115+
1:hex(entry[1]),
116+
2:hex(entry[2]),
117+
}
118+
})
119+
bo.sort(key=lambda x: x['build_index'])
120+
return bo
121+
122+
def getBuildOrders(data):
123+
unit_structs = [x[0] for x in data[5:]]
124+
players = {}
125+
for i in range(15):
126+
bo = getBuildOrder(unit_structs, i)
127+
if len(bo) > 0:
128+
players[i] = bo
129+
all = [u for p in players for u in players[p]]
130+
all.sort(key=lambda x: x['build_index'])
131+
return [players, all]
132+
133+
def main():
134+
arg = sys.argv[2] if len(sys.argv) >= 3 else "pprint"
135+
with open(sys.argv[1],"rb") as s2gs:
136+
raw_data = zlib.decompress(s2gs.read()[16:])
137+
data = list()
138+
buffer = ReplayBuffer(raw_data)
139+
while buffer.left:
140+
part = buffer.read_data_struct()
141+
data.append(part)
142+
143+
if arg == "players":
144+
pprint.PrettyPrinter(indent=2).pprint(getPlayers(data))
145+
elif arg == "pprint":
146+
pprint.PrettyPrinter(indent=2).pprint(data)
147+
elif arg == "bo":
148+
pprint.PrettyPrinter(indent=2).pprint(getBuildOrders(data))
149+
150+
main()

0 commit comments

Comments
 (0)