Created
April 14, 2020 04:17
-
-
Save anotherdirtbag/aaa3df8d51037e1d823f4e069d674fcf to your computer and use it in GitHub Desktop.
python script that allows parsing, editing, and saving Stellaris by Paradox config .txt files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import re | |
def main(): | |
modpath = os.path.join(r'C:\Users\sokka\Documents\Paradox Interactive\Stellaris\mod\better_queue') | |
installpath = os.path.join(r'C:\Games\Stellaris') | |
scrfile = os.path.join(r'common\buildings', '01_pop_assembly_buildings.txt') | |
#scrfile = os.path.join(r'common\colony_automation', '00_capital_automation.txt') | |
outfile = os.path.join(modpath, scrfile) | |
if not os.path.exists( os.path.dirname(outfile) ): | |
os.makedirs(os.path.dirname(outfile)) | |
os.chdir( modpath) | |
filedata = filterfile(os.path.join(installpath, scrfile)) | |
fileelements = StellarList(_isroot=True) #the root list | |
result = fileelements.loads(filedata) | |
if len(result) > 0: | |
print("something went wrong") | |
else: | |
print("it worked!") | |
newfiledata = fileelements.dumps() | |
with open(outfile, 'w') as outfiledata: | |
outfiledata.write(newfiledata) | |
getelemkeyop = re.compile(r'[\t\ ]*([\w\d_]+)[\t\ ]*([<>=]{,2})\s*') | |
getelemval = re.compile(r'[\t\ ]*([@\w\d_]+)\s*') | |
class StellarElement: | |
key: str | |
value: str # use None if no value | |
operand: str # for '<', '<='. if None assumes '=' | |
def __init__(self): | |
self.value = None | |
self.operand = None | |
def dumps(self, tablevel): | |
data = '\t'*tablevel + self.key | |
if self.value: | |
if self.operand: | |
data += ' ' + self.operand + ' ' + self.value | |
else: | |
data += ' = ' + self.value | |
data += '\n' | |
return data | |
def loads(self, filestream): | |
keyopmatch = getelemkeyop.match( filestream) | |
if keyopmatch: | |
self.key = keyopmatch.group(1) | |
opmatch = keyopmatch.group(2) | |
filestream = filestream[keyopmatch.end():] | |
if opmatch: | |
if opmatch != '=': | |
self.operand = opmatch | |
valmatch = getelemval.match( filestream) | |
if valmatch: | |
self.value = valmatch.group(1) | |
filestream = filestream[valmatch.end():] | |
return filestream | |
else: | |
return None | |
getkey = re.compile(r'[\t\ ]*([\w\d_]+)\s*=\s*\{\s*') | |
endlist = re.compile(r'\s*\}\s*') | |
class StellarList: | |
key: str | |
value: list | |
isroot: bool | |
def __init__(self, _isroot=False): | |
self.key = None | |
self.value = list() | |
self.isroot = _isroot | |
def dumps(self, tablevel=0): | |
if not self.isroot: | |
data = '\t'*tablevel + self.key + ' = {\n' | |
tablevel += 1 | |
else: | |
data = '' | |
for elem in self.value: | |
data += elem.dumps(tablevel) | |
if not self.isroot: | |
tablevel -= 1 | |
data += '\t'*tablevel + '}\n' | |
return data | |
def loads(self, filestream): | |
if not self.isroot: | |
keymatch = getkey.match(filestream) # must use match not search | |
if not keymatch: | |
return None # not a list | |
self.key = keymatch.group(1) | |
filestream = filestream[keymatch.end():] | |
# start reading elements until } is found | |
endmatch = endlist.match(filestream) | |
while( not endmatch and len(filestream) > 0): | |
newelem = StellarList() | |
newfs = newelem.loads( filestream) | |
if newfs is None: # not a list, try an element | |
newelem = StellarElement() | |
newfs = newelem.loads( filestream) | |
if newfs is None: | |
print( filestream) | |
raise ValueError('>>List and Elem detection failed') | |
self.value.append( newelem ) | |
filestream = newfs | |
endmatch = endlist.match(filestream) | |
if endmatch: | |
filestream = filestream[endmatch.end():] | |
return filestream | |
elif len(filestream) == 0: | |
return filestream | |
else: | |
print( filestream) | |
raise ValueError('>>List and Elem detection failed') | |
return '' | |
def filterfile(file_path): | |
with open( file_path, 'r') as filestream: | |
data = filestream.read() | |
data = re.sub(r'#.*', '', data) # Remove comments | |
data = re.sub(r'([\w\d_])[\t\ ]+([_\w\d])', r'\1\n\2', data) # add newline between key = value key = value | |
data = re.sub(r'\n{2,}', '\n', data) # Remove excessive new lines | |
data = re.sub(r'^\s+', '', data) # Remove all starting whitespace | |
return data | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment