This repository has been archived by the owner on Mar 26, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparseSave.py
211 lines (175 loc) · 6.98 KB
/
parseSave.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# parseSave.py
#
# script to transform savegame-file into JSON file
# INPUT: Stellaris gamestate file (filepath as command-line argument)
# OUTPUT: JSON file at filepath/JSONdata/<IngameDateOfSave>.JSON
import sys
import re
import json
import os
from pathlib import Path
# import Regular Expressions Library
import RegExLib
# read file path out of command-line argument, throw exception if it doesn't exist
if len(sys.argv) < 2: raise NameError("File path missing (command-line argument)")
filePath = Path(sys.argv[1])
if not filePath.is_file():
raise NameError("Error in file path: " + sys.argv[1])
# open file, read content into string and close file again
file = open(sys.argv[1], "r")
fileContent = file.read()
file.close()
# init output dict
output = {}
# extract date of save
match = RegExLib.saveDate.search(fileContent)
if match:
output.update({"date" : match.group(1)})
else: raise NameError("Save Date not found")
# extract galactic_object array
galactic_objectArray = RegExLib.galactic_objectArray.search(fileContent)
if not galactic_objectArray: raise NameError("Galactic Object List not found")
# extract each galactic_object & index
galactic_objectMatch = RegExLib.galactic_object.findall(galactic_objectArray.group(0))
galactic_object = []
for (index, content) in galactic_objectMatch:
# extract coordinates into sub-dict
coordinateMatch = RegExLib.system_coordinate.search(content)
coordinate = {"x" : coordinateMatch.group(1), "y" : coordinateMatch.group(2)}
# extract name
name = RegExLib.system_name.search(content).group(1)
if RegExLib.specialName.search(name): # handle names with NAME_
name = name[5 : len(name)] # cut off NAME_
name = name.replace("_", " ") # replace _ with blank
# extract planets into sub-list
planets = RegExLib.system_planets.findall(content)
# extract hyperlanes into sub-list
hyperlanes = RegExLib.system_hyperlane.findall(
RegExLib.system_hyperlaneSection.search(content).group(0) # match of hyperlane sub-section
)
# extract starbase
starbase = RegExLib.system_starbase.search(content).group(1)
if starbase == "4294967295": # handle non starbases
starbase = None # replace with None
# extract fleet_presence into sub-list
fleet_presence = RegExLib.system_fleetPresences.search(content)
if fleet_presence:
fleet_presence = re.findall("\d+", fleet_presence.group(1))
else:
fleet_presence = None
# extract bypasses into sub-list
bypasses = RegExLib.system_bypasses.search(content)
if bypasses:
bypasses = re.findall("\d+", bypasses.group(1))
else:
bypasses = None
# build galactic_object item
galactic_object.append({
"coordinate" : coordinate,
"name" : name,
"planets" : planets,
"hyperlanes" : hyperlanes,
"starbase" : starbase,
"fleet_presence": fleet_presence,
"bypasses" : bypasses
})
output.update({"system" : galactic_object}) # merge galactic_objects as "system" into output
# extract starbases array
starbasesArray = RegExLib.starbasesArray.search(fileContent)
if not starbasesArray: raise NameError("Starbase List not found")
# extract each starbase & index
starbaseMatch = RegExLib.starbase.findall(starbasesArray.group(0))
starbase = []
for (index, content) in starbaseMatch:
# extract level
level = RegExLib.starbase_level.search(content).group(1)
level = level[15 : len(level)] # cut off starbase_level_
# extract system
system = RegExLib.starbase_system.search(content).group(1)
# extract owner
owner = RegExLib.starbase_owner.search(content).group(1)
# build starbase item
starbase.append({
"level" : level,
"system" : system,
"owner" : owner
})
output.update({"starbase" : starbase}) # merge starbases into output
# extract planets array
planetsArray = RegExLib.planetsArray.search(fileContent)
if not planetsArray: raise NameError("Planet List not found")
# extract each planet & index
planetMatch = RegExLib.planet.findall(planetsArray.group(0))
planet = []
for (index, content) in planetMatch:
# extract name
name = RegExLib.planet_name.search(content).group(1)
if RegExLib.specialName.search(name): # handle names with NAME_
name = name[5 : len(name)] # cut off NAME_
name = name.replace("_", " ") # replace _ with blank
# extract size
size = RegExLib.planet_size.search(content).group(1)
# extract bombardment date
lastBombardment = RegExLib.planet_bombardment.search(content).group(1)
if lastBombardment == "1.01.01": # handle no bombardment
lastBombardment = None # replace with None
# extract controller
controller = RegExLib.planet_controller.search(content)
if controller:
controller = controller.group(1)
else:
controller = None
# extract and count tiles
tileCount = len( # count elements in
RegExLib.planet_tiles.findall( # matches of tiles in
RegExLib.planet_tileList.search(content).group(0) # tile list
)
)
# extract surveyor
surveyor = RegExLib.planet_surveyor.search(content)
if surveyor:
surveyor = surveyor.group(1)
else:
surveyor = None
# extract and count pops
popCount = RegExLib.planet_pops.search(content)
if popCount:
popCount = len(re.findall("\d+", popCount.group(1)))
else:
popCount = 0
# extract colonization date
colonized = RegExLib.planet_colonized.search(content)
if colonized:
colonized = colonized.group(1)
else:
colonized = None
# extract army count
armyCount = RegExLib.planet_armies.search(content)
if armyCount:
armyCount = len(re.findall("\d+", armyCount.group(1)))
else:
armyCount = 0
# build planet item
planet.append({
"name" : name,
"size" : size,
"tile_count" : tileCount,
"owner" : controller,
"surveyor" : surveyor,
"pop_count" : popCount,
"army_count" : armyCount,
"colonization_date" : colonized,
"last_bombardment": lastBombardment
})
output.update({"planet" : planet}) # merge planets into output
########################################################################################################################
# Dump to console (for debug)
#
#json.dump(output, sys.stdout, indent=4)
########################################################################################################################
# Dump to JSON file in "filepath/JSON Data/<date>.json"
if not Path("./JSON Data").is_dir():
os.mkdir(Path("./JSON Data"))
with open(Path("./JSON Data/" + output["date"] + ".json"), "w") as outputFile:
json.dump(output, outputFile, indent=4)
print("File " + outputFile.name + " created")