-
Notifications
You must be signed in to change notification settings - Fork 0
/
replay_reader.py
122 lines (94 loc) · 4 KB
/
replay_reader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
from glob import glob
import datetime
import struct
file_magic = b'\x7f\xe2\xa2\x1c'
def decode_int32(binary):
return struct.unpack('<i', binary)[0]
def decode_uint32(binary):
return struct.unpack('<I', binary)[0]
def decode_int64(binary):
return struct.unpack('<q', binary)[0]
def decode_uint64(binary):
return struct.unpack('<Q', binary)[0]
def fstring_reader(fileContent,pos):
fname_len = fileContent[pos:pos+4]
pos += 4
fname_len = decode_int32(fname_len)
if fname_len < 0:
#print ('unic')
fname_len = - fname_len
return fileContent[pos:pos+fname_len*2].decode('utf-8',errors='replace').replace('\0','').strip(), pos+fname_len*2
else:
#print ('Nounic')
return fileContent[pos:pos+fname_len].decode('utf-8',errors='ignore').replace('\0','').strip(), pos + fname_len
def read_replay(replay_file):
file_magic = b'\x7f\xe2\xa2\x1c'
eliminations = []
elim_total = None
position = None
total_players = None
with open(replay_file, 'rb') as rp:
fileContent = rp.read()
magic_number = fileContent[:4]
if (magic_number != file_magic):
print ('Invalid File')
file_version = fileContent[4:8]
length_ms = fileContent[8:12]
game_length = decode_uint32(length_ms)/(100*60)
network_version = fileContent[12:16]
change_list = fileContent[16:20]
friendly_name, pos = fstring_reader(fileContent,20)
is_live = decode_uint32(fileContent[pos:pos+4]) != 0
pos += 4
if decode_uint32(file_version) >= 3:
## FIX THESE TICKS
timestamp = fileContent[pos:pos+8]
pos += 8
timestamp = decode_int64(timestamp)
date = datetime.datetime.fromtimestamp(timestamp/1e10)
if decode_uint32(file_version) >= 2:
is_compressed = decode_uint32(fileContent[pos:pos+4]) != 0
pos += 4
while pos < len(fileContent):
chunk_type = decode_uint32(fileContent[pos:pos+4])
pos += 4
size_in_bytes = decode_int32(fileContent[pos:pos+4])
pos += 4
if chunk_type == 3:
event_id, new_pos = fstring_reader(fileContent,pos)
group, new_pos = fstring_reader(fileContent,new_pos)
metadata, new_pos = fstring_reader(fileContent,new_pos)
time1 = decode_uint32(fileContent[new_pos:new_pos+4])
new_pos += 4
time2 = decode_uint32(fileContent[new_pos:new_pos+4])
new_pos += 4
event_size = decode_uint32(fileContent[new_pos:new_pos+4])
new_pos += 4
if group == 'playerElim':
elim = {}
new_pos += 45
nick1, new_pos = fstring_reader(fileContent, new_pos)
nick2, new_pos = fstring_reader(fileContent, new_pos)
#print (nick1,nick2)
try:
elim_type = str(fileContent[new_pos:new_pos+1])[-2:-1]
except:
elim_type = 'NS'
new_pos += 1
knock_or_elim = decode_uint32(fileContent[new_pos:new_pos+4])
elim['killed'] = nick1
elim['killer'] = nick2
elim['type'] = elim_type
elim['knock_or_elim'] = knock_or_elim
#print (elim_type,knock_or_elim)
eliminations.append(elim)
if metadata == 'AthenaMatchStats':
new_pos += 12
elim_total = decode_uint32(fileContent[new_pos:new_pos+4])
if metadata == 'AthenaMatchTeamStats':
new_pos += 4
position = decode_uint32(fileContent[new_pos:new_pos+4])
new_pos += 4
total_players = decode_uint32(fileContent[new_pos:new_pos+4])
pos += size_in_bytes
return eliminations, elim_total, position, total_players