Hi Leute,
ich habe kürzlich um Daten aus dem Source Code von Gothic2 herauszulesen ein kleines PythonRegex Script geschrieben. Es liest zum Beispiel alle Waffen aus einem file aus und schreibt sie als multipage-table in einem PDF raus. Ihr benötigt eine laufende Version von Python2.7 und LaTeX (z.B. MikteX für Windows). Anbei der code.
Viel Spaß damit!
Wolle
PS.: Falls man das hier noch irgendwo besser hinschieben kann - feel free!
ich habe kürzlich um Daten aus dem Source Code von Gothic2 herauszulesen ein kleines PythonRegex Script geschrieben. Es liest zum Beispiel alle Waffen aus einem file aus und schreibt sie als multipage-table in einem PDF raus. Ihr benötigt eine laufende Version von Python2.7 und LaTeX (z.B. MikteX für Windows). Anbei der code.
Viel Spaß damit!
Wolle
PS.: Falls man das hier noch irgendwo besser hinschieben kann - feel free!
Spoiler:(zum lesen bitte Text markieren)
Code:
#!/usr/bin/env python
# This is a Python Script (using python regex) for extracting Information from the Source Code
# of the Video Game Gothic2 and its Addons and Mods.
# Not all the methods are applicable to every situation and file.
# You need a working copy of Python2.7 and LaTeX
# execution line is 187
# Date: 03-Oct-2016 Author: Wolle (WoG: VV0ll3)
import re
import os
#PreCompilation of used regex patterns
reID = re.compile(r'instance.*?\(',re.I)
reName = re.compile(r'name\s+=.*?;',re.I)
reProt = re.compile(r'protection.*?=.*?;',re.I)
reVal=re.compile(r'const int.*?=.*?;',re.I)
reNPC = re.compile(r'.*GetNpc.*',re.I)
reDam = re.compile(r'damageTotal\s+=.*?;',re.I)
#removes from inputstring string all substrings in inputlist liste
def remove(string,liste):
for item in liste:
string=string.replace(item,"")
return string
#reads in a c-file, extracts all const int variables and returns a dictionary with their names and corresponding values
def valRead(filename):
valFile=open(filename,"r")
valDict=dict()
for line in valFile:
reValMatch=reVal.search(line)
if reValMatch:
valID=reValMatch.group().split()[2]
valNO=remove(reValMatch.group().split("=")[1],[" ",";","\t"])
valDict[valID]=valNO
return valDict
# creates a PDF with a table spanning multiple pages if neccessary, containing: Thing | ThingID | additional
# additional can contain several columns, defined by the parameter typeList
# Parameters: pdfName[string]=Name for outputPDF, printContentList[list of strings]= content, which is to print(2+ columns)
# valDict[dict]=ID->Value pairs,typeList[list of strings]= names of extra columns,rSpace[1.0<float<0.0]=space for value-columns
def pdfPrint(pdfName,printContentList,valDict,typeList,rSpace):
out = open(pdfName+".tex","w")
header="\documentclass[10pt,a4paper]{article}\n\usepackage[a4paper,total={6.5in,8.5in}]{geometry}\n\usepackage[latin1]{inputenc}\n\usepackage{longtable}\n\\begin{document}\n"
if len(typeList)!=0:
rSpace=rSpace/len(typeList)
body1part=" p{"+str(rSpace)+"\\textwidth}|"
lSpace=(1.0-rSpace)/2
body1="\\begin{longtable}{| p{"+str(lSpace)+"\\textwidth} | p{"+str(lSpace)+"\\textwidth} |"+body1part*len(typeList)+"}"
body2part=""
for type in typeList:
body2part=body2part+"&\\textbf{"+str(type)+"}"
body2="\n\\hline\n\\textbf{Name}&\\textbf{Insertcode}"+body2part+"\\\\ \n\\hline\n"
out.write(header+body1+body2)
for item in printContentList:
if (len(item) < 2): continue
if len(typeList)==0:
outstring=str(item[1])+"&"+str(item[0])+"\\\\ \n \hline\n"
elif len(item)==3:
if (re.match(r'^[0-9]+.*?[0-9]+$',item[2])):
ret=item[2]
elif (item[2] in valDict):
#ret=remove(valDict[item[2]],[";"])
ret=valDict[item[2]]
else:
ret=""
outstring=str(item[1])+"&"+str(item[0])+"&"+ret+"\\\\ \n \hline\n"
else:
outstring=str(item[1])+"&"+str(item[0])+"& \\\\ \n \hline\n"
outstring=outstring.replace("_","\_")
out.write(outstring)
out.write("\n\end{longtable}\n\end{document}")
out.close()
print("Writing "+pdfName+".pdf")
os.system("pdflatex -interaction=batchmode "+pdfName+".tex")
if os.name=="nt":
os.system("del "+pdfName+".aux "+pdfName+".log "+pdfName+".tex")
elif os.name=="posix":
os.system("rm "+pdfName+".[abcdefghijklmnoqrstuvwxyz]*")
# Creates a PDF with a list of all weapons in the input file
# Parameters: filename[string]=Name of input text-file, valfile[string]=Name of corresponding Values file (can be the same),
# outfile[string]=Name for outputPDF(without file ending .pdf)
def weapon(filename,valfile,outfile):
valDict=valRead(valfile)
readFile = open(filename,"r")
things = []
counter = -1
for line in readFile:
reIDMatch = reID.search(line)
reNameMatch = reName.search(line)
reDamMatch = reDam.search(line)
if reIDMatch:
things.append([remove(reIDMatch.group(),["instance","INSTANCE","("," ","\t",";"," "])])
counter+=1
elif reNameMatch:
things[counter].append(remove(reNameMatch.group(),["name","NAME","\t","=",'"',";"]))
elif reDamMatch:
things[counter].append(remove(reDamMatch.group(),["damageTotal","DAMAGETOTAL","\t",'"',"="," ",";"]))
print counter+1," weapons found!"
readFile.close()
pdfPrint(outfile,things,valDict,["Schaden"],0.1)
# Creates a PDF with a list of all armor items in the input file
# Parameters: filename[string]=Name of input text-file, valfile[string]=Name of corresponding Values file (can be the same),
# outfile[string]=Name for outputPDF(without file ending .pdf)
def armor(filename,valfile,outfile):
valDict=valRead(valfile)
readFile = open(filename,"r")
things = []
counter = -1
for line in readFile:
reIDMatch = reID.search(line)
reNameMatch = reName.search(line)
reProtMatch = reProt.search(line)
if reIDMatch:
things.append([remove(reIDMatch.group(),["instance","INSTANCE","(","\t",";"," "])])
counter+=1
elif reNameMatch:
things[counter].append(remove(reNameMatch.group(),["name","NAME","\t","=",'"',";"]))
elif reProtMatch:
things[counter].append(remove(reProtMatch.group().split("=")[1],["\t",'"',"="," ",";"]))
print counter+1," weapons found!"
for item in things:
if (len(item) > 3):
item[2]="/".join(item[2:7])
for i in range(3,len(item)):
item.pop()
readFile.close()
pdfPrint(outfile,things,valDict,["Schutzwerte"],0.25)
# Creates a PDF with a list of all NPCs in the input file
# Parameters: filename[string]=Name of input text-file,
# outfile[string]=Name for outputPDF(without file ending .pdf)
def npc(filename,outfile):
readFile = open(filename,"r")
things = []
counter = -1
for line in readFile:
reNPCMatch = reNPC.search(line)
if reNPCMatch:
things.append([remove(reNPCMatch.group().split("GetNpc")[1],["(",")"," ","\t",";"]),remove(reNPCMatch.group().split("=")[0],["\t"," "])])
counter+=1
print counter+1," NPCs found!"
readFile.close()
pdfPrint(outfile,things,"",[],0.0)
# Creates a PDF with a list of all Items in the input file
# Parameters: filename[string]=Name of input text-file,
# outfile[string]=Name for outputPDF(without file ending .pdf)
def items(filename,outfile):
things = []
counter = -1
readFile = open(filename,"r")
for line in readFile:
reIDMatch = reID.search(line)
reNameMatch = reName.search(line)
if reIDMatch:
things.append([remove(reIDMatch.group(),["instance","INSTANCE","("," ","\t",";"," "])])
counter+=1
elif reNameMatch:
things[counter].append(remove(reNameMatch.group(),["name","NAME","\t","=",'"',";"]))
readFile.close()
print counter+1," Items found!"
pdfPrint(outfile,things,"",[],0.0)
# Creates a PDF with a list of all Items in the input files important for Odyssee2.0 (this is highly non-recyclable ;), because the file names are hard coded)
# Parameters: outfile[string]=Name for outputPDF(without file ending pdf)
def mItems(outfile):
things = []
counter = -1
for st in ["1","2","3","4","5","6","Addon","OdysseeMap","OdysseeMod"]:
readFile = open("MissionItems_"+st+".d","r")
for line in readFile:
reIDMatch = reID.search(line)
reNameMatch = reName.search(line)
if reIDMatch:
things.append([remove(reIDMatch.group(),["instance","INSTANCE","("," ","\t",";"," "])])
counter+=1
elif reNameMatch:
things[counter].append(remove(reNameMatch.group(),["name","NAME","\t","=",'"',";"]))
readFile.close()
print counter+1," Items found!"
pdfPrint(outfile,things,"",[],0.0)
# Choose here, which function you want to run.
# For an extraction of all MeleeWeapons, which are defined in file IT_Melee_Weapons.d uncomment the next line
weapon("IT_Melee_Weapons.d","Tuning_Melee_Weapons.d","Melee")
#Other exemplary methods
#weapon("IT_Ranged_Weapons.d","Tuning_Ranged_Weapons.d","Ranged")
#armor("IT_Armor.d","IT_Armor.d","Armor")
#npc("NPCs.txt","NPC")
#mItems("ImportantItems")