-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbinvdf.py
135 lines (107 loc) · 2.75 KB
/
binvdf.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
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env python2
#-*- coding=utf-8 -*-
"""
Copyright (c) 2012, Mark Harviston
All rights reserved.
Redistribution allowed, see LICENSE.txt for details
Binary VDF (Valve Data Format) Parser
Probably only applies to appcache/appinfo.vdf
Format seems to be of the form:
new record: {STX}{NUL}appid{NULL}
key/value pair: {SOH}key{NUL}value{NUL}
"""
from pprint import pprint
import chardet
from fix_bad_unicode import text_badness, fix_bad_unicode
import codecs
import tkMessageBox
NUL = '\x00' # NULL character (\0)
SOH = '\x01' # Start of Heading (Smiley)
STX = '\x02' # Start of Text
ETX = '\x03' # End of Text
EOT = '\x04' # End of Transmission
ENQ = '\x05' # Enquiry
ACK = '\x06' # Acknowledge
BEL = '\x07' # Ring the Bell
SMI = '\x09' # Smiley
def fix_ze_unicode(txt):
"doing my best to fix ze unicode"
if txt == b'':
return u''
try:
txt = txt.decode('utf-8')
except UnicodeDecodeError:
enc = chardet.detect(txt)['encoding']
txt = txt.decode(enc)
txt = fix_bad_unicode(txt)
return txt
class Universe(object):
def __contains__(self, other):
return True
new_game1 = object()
new_game2 = object()
key_state = object()
val_state = object()
def_state = object()
class BinVDF(object):
def __init__(self, file, searching_for = None):
if searching_for is None:
self.searching_for = Universe()
else:
self.searching_for = searching_for
with open(file, 'rb', buffering=10 * (2**10) ) as f:
self.open(f)
def open(self, file):
state = def_state
game_id = val = key = ''
games = []
game = {}
kv = []
self.games_by_id = {}
while True:
c = file.read(1)
if not c: break
if c == STX:
state = new_game1
continue
elif c == SOH:
state = key_state
key = val = ''
continue
if state is new_game1:
if c == NUL:
state = new_game2
game_id = ''
elif state is new_game2:
if c == NUL:
state = None
try:
game_id = int(game_id)
except:
game_id = ''
else:
game_id += c
elif state is val_state:
if c == NUL:
#if 'Eberron' in val:
#tkMessageBox.showinfo('title', fix_ze_unicode(val))
#print '%r' %
if game_id != '' and game_id in self.searching_for:
key = fix_ze_unicode(key)
val = fix_ze_unicode(val)
if game_id not in self.games_by_id:
self.games_by_id[game_id] = {}
if key not in self.games_by_id[game_id]:
self.games_by_id[game_id][key] = val
key = val = ''
state = def_state
else:
val += c
elif state is key_state:
if c == NUL:
state = val_state
else:
key += c
with open('output.txt', 'w') as f:
pprint(self.games_by_id, stream=f,indent=4)
#binvdf = BinVDF(r'C:\Program Files (x86)\Steam\appcache\appinfo.vdf')