Skip to content

Commit

Permalink
Added module that reads usersettings
Browse files Browse the repository at this point in the history
  • Loading branch information
mitsuhiko committed Oct 28, 2011
1 parent ef512ab commit b2da757
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 3 deletions.
29 changes: 26 additions & 3 deletions libsb.py
Expand Up @@ -10,10 +10,10 @@
:license: BSD, see LICENSE for more details.
"""
import struct
from StringIO import StringIO
from uuid import UUID
from array import array
from itertools import imap
from pprint import pformat
from datetime import datetime


Expand Down Expand Up @@ -63,9 +63,8 @@ def read_varint(self):
rv = 0
while 1:
val = self.read_byte()
first_bit = val >> 7
rv = (rv << 7) | (val & 0x7f)
if not first_bit:
if not val >> 7:
break
return rv

Expand Down Expand Up @@ -310,6 +309,8 @@ def read_object(self, typecode=None):
self.read_list()
elif typecode == 2:
self.read_dict()
elif typecode == 5:
self.push(Unknown(5, self.reader.read(8)))
elif typecode == 6:
self.push(bool(self.reader.read_byte()))
elif typecode == 7:
Expand Down Expand Up @@ -416,3 +417,25 @@ def __init__(self, filename):

def close(self):
self._fp.close()


def decrypt(filename, new_filename=None):
"""Decrypts a file for debugging."""
if new_filename is None:
new_filename = filename + '.decrypt'
with open(new_filename, 'wb') as f:
with TOCReader(filename) as reader:
f.write(reader.read())


def loads(string):
"""Quick"""
return load(StringIO(string))


def load(filename_or_fp):
"""Loads a TOC object from a file."""
with TOCReader(filename_or_fp) as reader:
parser = TOCParser(reader)
parser.read_object()
return parser.pop()
73 changes: 73 additions & 0 deletions usersettings.py
@@ -0,0 +1,73 @@
import os
import struct


_int32 = struct.Struct('<i')


class Blob(object):

def __init__(self, data):
self.data = data

def __repr__(self):
return '<Blob %r (%d bytes)>' % (
self.data[:20],
len(self.data)
)


def _read_structval(f, st):
return st.unpack(f.read(st.size))


def _read_cstr(f, size):
# just guessing
value = f.read(size)
if value and len(value) < 255 and value[-1] == '\x00':
return value[:-1]
return Blob(value)


def parse_body_settings(f):
garbage = f.read(20)
sections = []
while 1:
section = {}
sections.append(section)
item_count = _read_structval(f, _int32)[0]
if item_count == 0:
break
for x in xrange(item_count):
item_type = _read_structval(f, _int32)[0]
caption_size = _read_structval(f, _int32)[0]
key = _read_cstr(f, caption_size)
value_size = _read_structval(f, _int32)[0]
value = _read_cstr(f, value_size)
# XXX: convert value by item type
section[key] = value
return sections


def parse_profile_settings(f):
rv = {}
for x in f.read().split('\x0a'):
if x:
key, value = x.split('\x20', 1)
rv[key] = value
return rv


def load_settings():
rv = {}
basepath = os.path.expanduser('~/Documents/Battlefield 3/settings/')
with open(basepath + 'PROF_SAVE_body', 'rb') as f:
rv['body'] = parse_body_settings(f)
with open(basepath + 'PROF_SAVE_profile', 'rb') as f:
rv['profile'] = parse_profile_settings(f)
return rv


if __name__ == '__main__':
import pprint
pprint.pprint(load_settings())

0 comments on commit b2da757

Please sign in to comment.