-
Notifications
You must be signed in to change notification settings - Fork 1
/
extractxgdata.py
101 lines (88 loc) · 3.94 KB
/
extractxgdata.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
#
# extractxgdata.py - Simple XG data extraction tool
# Copyright (C) 2013,2014 Michael Petch <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#
from __future__ import with_statement
import sys
import struct
import uuid
import os
import argparse
import xgimport
import xgzarc
import xgstruct
import pprint
def parseoptsegments(parser, segments):
segmentlist = segments.split(',')
for segment in segmentlist:
if segment not in ['all', 'comments', 'gdhdr', 'thumb', 'gameinfo',
'gamefile', 'rollouts', 'idx']:
parser.error("%s is not a recognized segment" % segment)
return segmentlist
def directoryisvalid(parser, dir):
if not os.path.isdir(dir):
parser.error("directory path '%s' doesn't exist" % dir)
return dir
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='XG data extraction utility',
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument("-d", metavar='DIR', dest="outdir",
help="Directory to write segments to "
"(Default is same directory as the import file)\n",
type=lambda dir:
directoryisvalid(parser, dir), default=None)
parser.add_argument('files', metavar='FILE', type=str, nargs='+',
help='An XG file to import')
args = parser.parse_args()
for xgfilename in args.files:
xgbasepath = os.path.dirname(xgfilename)
xgbasefile = os.path.basename(xgfilename)
xgext = os.path.splitext(xgfilename)
if (args.outdir is not None):
xgbasepath = args.outdir
try:
xgobj = xgimport.Import(xgfilename)
print ('Processing file: %s' % xgfilename)
fileversion = -1
# To do: move this code to XGImport where it belongs
for segment in xgobj.getfilesegment():
segment.copyto(os.path.abspath(
os.path.join(xgbasepath,
xgbasefile[:-len(xgext[1])] + segment.ext)))
if segment.type == xgimport.Import.Segment.XG_GAMEFILE:
segment.fd.seek(os.SEEK_SET, 0)
while True:
rec = xgstruct.GameFileRecord(
version=fileversion).fromstream(segment.fd)
if rec is None:
break
if isinstance(rec, xgstruct.HeaderMatchEntry):
fileversion = rec.Version
elif isinstance(rec, xgstruct.UnimplementedEntry):
continue
pprint.pprint (rec,width=160)
elif segment.type == xgimport.Import.Segment.XG_ROLLOUTS:
segment.fd.seek(os.SEEK_SET, 0)
while True:
rec = xgstruct.RolloutFileRecord().fromstream(segment.fd)
if rec is None:
break
pprint.pprint (rec,width=160)
except (xgimport.Error, xgzarc.Error) as e:
print (e.value)