-
Notifications
You must be signed in to change notification settings - Fork 34
jsonAct.py
kmalone86 edited this page Aug 9, 2019
·
12 revisions
#!/usr/bin/python3
import sys
import json
import collections
from collections import OrderedDict
import os.path
import ast
import itertools
def displayHelp():
print('')
print(' HELP')
print('------------')
print('Arguments: ')
print('Flags:')
print('-print Will print expected json output.')
print('-printPath Will print path.')
print('-onlyPrint Will print expected json output, but not write to file.')
print('-none Do nothing, for testing.')
print('Commands:')
print('insert "fileName" "prevVariable" "insertVariable" "value"')
print('replace "fileName" "prevVariable" "newVariable"')
print('delete "fileName" "deleteVariable"')
print('set "fileName" "variable" "value"')
print('copy "fileName" "fromVariable" "toVariable"')
print('custom "fileName" ???')
print('move "fileName" "variable" "indexNumber"')
print('addToDict "fileName" "variable" "newVariable" "value"')
print('addToList "fileName" "variable" "value"')
print('print "fileName" "variable"')
print('updateMod "fileName1"')
print('fromFile "fileName1" "fullPath" "fileName2" "fullPath"')
print('genPath (list of variable types and values)......')
print(' dict "dictName" -Named dict for path')
print(' list "listName" -Named list for path')
print(' item "index" -Unnamed item in dict or list')
print(' value "valueName" -Value for path')
print(' var "varType" "path..." varEnd')
print(' (special var keywords)')
print(' fileNameNoEx - replaced by filename without extension')
print(' -If variable is defined by')
print(' by another variable')
print('')
print('"fileName":all = preform action on all .json')
print('"value" Value is taken liternally, use \\" for strings.')
print('')
print('Optional:')
print('path=[] Will scope search to only path.')
print(' * = wild card, so [\'*\'] for all or [\'item\':1, \'*\']')
print(' [\'item\':1, \'*\'] [\'dict\':*, \'*\']')
print(' Recommend using -printPath to see value.')
print('filename Overwrite filename at end of line.')
print('findVal When searching for var, ensure this is value.')
print('')
quit()
if len(sys.argv) < 2:
displayHelp()
fileName = ''
fromFileName = ''
prevVar = ''
newVar = ''
value = ''
searchVar = ''
findVal = ''
writeOutput = True
printOutput = False
printPath = False
skipArgs = False
cmdIndex = 1
while sys.argv[cmdIndex].startswith('-'):
if sys.argv[cmdIndex] == '-print':
printOutput = True
if sys.argv[cmdIndex] == '-printPath':
printPath = True
elif sys.argv[cmdIndex] == '-onlyPrint':
writeOutput = False
printOutput = True
elif sys.argv[cmdIndex] == '-none':
writeOutput = False
printOutput = False
cmdIndex = cmdIndex + 1
if len(sys.argv) < cmdIndex:
displayHelp()
command = sys.argv[cmdIndex]
if command == 'insert':
if len(sys.argv) < cmdIndex+1+4:
displayHelp()
fileName = sys.argv[cmdIndex+1]
prevVar = sys.argv[cmdIndex+2]
newVar = sys.argv[cmdIndex+3]
value = sys.argv[cmdIndex+4]
searchVar = prevVar
cmdIndex += 5
elif command == 'replace':
if len(sys.argv) < cmdIndex+1+3:
displayHelp()
fileName = sys.argv[cmdIndex+1]
prevVar = sys.argv[cmdIndex+2]
newVar = sys.argv[cmdIndex+3]
searchVar = prevVar
cmdIndex += 3
elif command == 'delete':
if len(sys.argv) < cmdIndex+1+2:
displayHelp()
fileName = sys.argv[cmdIndex+1]
newVar = sys.argv[cmdIndex+2]
searchVar = newVar
cmdIndex += 2
elif command == 'set':
if len(sys.argv) < cmdIndex+1+3:
displayHelp()
fileName = sys.argv[cmdIndex+1]
newVar = sys.argv[cmdIndex+2]
value = sys.argv[cmdIndex+3]
searchVar = newVar
cmdIndex += 4
elif command == 'copy':
if len(sys.argv) < cmdIndex+1+3:
displayHelp()
fileName = sys.argv[cmdIndex+1]
prevVar = sys.argv[cmdIndex+2]
newVar = sys.argv[cmdIndex+3]
searchVar = prevVar
cmdIndex += 4
elif command == 'move':
if len(sys.argv) < cmdIndex+1+3:
displayHelp()
fileName = sys.argv[cmdIndex+1]
newVar = sys.argv[cmdIndex+2]
value = int(sys.argv[cmdIndex+3])
searchVar = newVar
cmdIndex += 4
elif command == 'addToDict':
if len(sys.argv) < cmdIndex+1+4:
displayHelp()
fileName = sys.argv[cmdIndex+1]
prevVar = sys.argv[cmdIndex+2]
newVar = sys.argv[cmdIndex+3]
value = sys.argv[cmdIndex+4]
searchVar = prevVar
cmdIndex += 5
elif command == 'addToList':
if len(sys.argv) < cmdIndex+1+3:
displayHelp()
fileName = sys.argv[cmdIndex+1]
prevVar = sys.argv[cmdIndex+2]
value = sys.argv[cmdIndex+3]
searchVar = prevVar
cmdIndex += 4
elif command == 'genPath':
skipArgs = True
elif command == 'print':
if len(sys.argv) < cmdIndex+1+2:
displayHelp()
fileName = sys.argv[cmdIndex+1]
newVar = sys.argv[cmdIndex+2]
searchVar = newVar
writeOutput = False
cmdIndex += 2
elif command == 'fromFile':
if len(sys.argv) < cmdIndex+1+4:
displayHelp()
fromFileName = sys.argv[cmdIndex+1]
prevVar = sys.argv[cmdIndex+2]
fileName = sys.argv[cmdIndex+3]
newVar = sys.argv[cmdIndex+4]
cmdIndex += 4
elif command == 'updateMod':
if len(sys.argv) < cmdIndex+1+1:
displayHelp()
fileName = sys.argv[cmdIndex+1]
searchVar = 'damageModifiers'
path = "['list:skills', '*']"
cmdIndex += 1
elif command == 'custom':
print('Calling custom function:')
fileName = sys.argv[cmdIndex+1]
searchVar = sys.argv[cmdIndex+2]
cmdIndex += 2
elif command == 'test':
print('Test Run:')
else:
displayHelp()
path = None
if skipArgs == False:
while(cmdIndex < len(sys.argv)):
if sys.argv[cmdIndex].startswith('path='):
path = ast.literal_eval(sys.argv[cmdIndex][5:])
print('path set to '+str(path))
elif sys.argv[cmdIndex] == 'filename':
fileName = sys.argv[cmdIndex+1]
print('fileName changed to '+fileName)
cmdIndex += 1
elif sys.argv[cmdIndex] == 'findVal':
findVal = sys.argv[cmdIndex+1]
print('find Value must equal '+findVal)
cmdIndex += 1
else:
break
cmdIndex += 1
def generatePath(items, recursiveStep):
index = 0
path = []
while(index < len(items)):
if items[index] == 'dict':
if len(items) < index+1+1:
print('Dict requires a name')
quit()
index += 1
hop = 'dict:'+items[index]
path.append(hop)
elif items[index] == 'list':
if len(items) < index+1+1:
print('list requires a name')
quit()
index += 1
hop = 'list:'+items[index]
path.append(hop)
elif items[index] == 'item':
if len(items) < index+1+1:
print('item requires a number')
quit()
index += 1
try:
int(items[index])
except ValueError:
print('item requires a number')
quit()
hop = 'list:'+items[index]
path.append(hop)
elif items[index] == 'var':
if len(items) < index+1+3:
print('var requires a type, path, and varEnd')
quit()
if recursiveStep != 0:
print('Currently do not support var within var')
quit()
index += 1
hop = '\'var:{\\\'type\\\':\\\''+items[index]+'\\\', \\\'value\\\':'
index += 1
ret,retIndex = generatePath(items[index:], recursiveStep+1)
ret = str(ret).replace("'","\\'")
hop = hop+str(ret)+'}\''
path.append(str(hop))
#print(path)
index += retIndex
elif items[index] == 'varEnd':
if recursiveStep == 0:
print('varEnd requires a var first')
quit()
index += 1
break
elif items[index] == 'value':
if len(items) < index+1+1:
print('value requires a value')
quit()
index += 1
hop = items[index]
path.append(hop)
else:
print('Expected type, got \''+str(items[index])+'\'')
quit()
index += 1
return path, index
if command == 'genPath':
path,index = generatePath(sys.argv[2:], 0)
#print(path)
print('"'+str(path).replace("\"","")+'"')
quit()
# Create a list of all variables that match searchVar
def findDictWithVar(jsonData, searchVar, path):
dictList = []
index = 0
for var in jsonData:
if var == searchVar:
dictList = dictList+[{'jsonData':jsonData, 'path':path}]
elif isinstance(var, collections.Mapping):
ret = findDictWithVar(var, searchVar, path+['item:'+str(index)])
if ret != []:
dictList = dictList+ret
elif isinstance(jsonData[var], collections.Mapping):
ret = findDictWithVar(jsonData[var], searchVar, path+['dict:'+var])
if ret != []:
dictList = dictList+ret
elif isinstance(jsonData[var], list):
if len(jsonData[var]) == 0:
continue;
if isinstance(jsonData[var][0], collections.Mapping) == False:
continue;
ret = findDictWithVar(jsonData[var], searchVar, path+['list:'+var])
if ret != []:
dictList = dictList+ret
index = index + 1
return dictList
# Convert path to type, value
def convertPath(pathStr):
pathType = ''
pathValue = ''
if pathStr.startswith('dict:'):
pathType = 'dict'
pathValue = pathStr[5:]
elif pathStr.startswith('item:'):
pathType = 'item'
pathValue = pathStr[5:]
elif pathStr.startswith('list:'):
pathType = 'list'
pathValue = pathStr[5:]
else:
pathType = ''
pathValue = pathStr
return pathType,pathValue
# Returns exact path of variable
def findVar(jsonData, fullPath):
ret = None
for hop in fullPath:
pathTypeA,pathValueA = convertPath(hop)
if isinstance(jsonData, list) and len(jsonData) is 0:
return None
if not isinstance(jsonData, list) and pathValueA not in jsonData:
return None
ret = [jsonData, pathValueA]
jsonData = jsonData[pathValueA]
return ret
# Returns exact value of variable
def findVarValue(jsonData, fullPath):
ret = None
for hop in fullPath:
pathTypeA,pathValueA = convertPath(hop)
if isinstance(jsonData, list) and len(jsonData) is 0:
return None
if not isinstance(jsonData, list) and pathValueA not in jsonData:
return None
jsonData = jsonData[pathValueA]
return jsonData
# Reads fullPath and replaces var:.... with real value
def replacePathVariables(jsonFileName, jsonData, fullPath):
newPath = []
for hop in fullPath:
if hop.startswith('var:'):
varHop = ast.literal_eval(hop[4:])
if varHop['value'] == 'fileNameNoEx':
foundVal = os.path.splitext(jsonFileName)[0]
else:
foundVal = findVarValue(jsonData, varHop['value'])
hop = varHop['type']+':'+foundVal
newPath.append(hop)
return newPath
#print(ast.literal_eval(sys.argv[cmdIndex+1]))
#with open('luna.json', 'r') as infile:
# inJson = json.load(infile, object_pairs_hook=OrderedDict)
# fixedFath =replacePathVariables(inJson, ast.literal_eval(sys.argv[cmdIndex+1]))
# print(fixedFath)
#print(findVarValue(inJson, ast.literal_eval(sys.argv[cmdIndex+1])))
#quit()
# Insert variable into directory
def insertDictVar(jsonData, prevVarName, newVarName):
for _ in range(len(jsonData)):
k, v = jsonData.popitem(False)
jsonData[k] = v
if prevVarName == k:
jsonData[newVarName] = ''
# Delete a variable from directory
def deleteDictVar(jsonData, delVar):
if delVar not in jsonData:
return
jsonData.move_to_end(delVar)
jsonData.popitem()
# Rename a variable in directory
def renameDictVar(jsonData, oldName, newName):
for _ in range(len(jsonData)):
k, v = jsonData.popitem(False)
jsonData[newName if oldName == k else k] = v
# Move to index
def moveDictVar(jsonData, name, moveIndex):
# Remove moving data
jsonData.move_to_end(name)
mvName, mvVal = jsonData.popitem(True)
added = False
# Copy into new data
tmpData = OrderedDict()
index = 0
for _ in range(len(jsonData)):
k, v = jsonData.popitem(False)
# When hit needed index, insert it and continue to insert the rest.
if moveIndex == index:
tmpData[mvName] = mvVal
added = True
tmpData[k] = v
index = index + 1
if added == False:
tmpData[mvName] = mvVal
jsonData.update(tmpData)
# Write json into file
def writeJson(outputFile, jsonData):
with open(outputFile, 'w') as outfile:
json.dump(jsonData, outfile, indent=4, separators=(',', ': '), ensure_ascii=False)
outfile.write("\n")
# Print json to screen
def printJson(jsonData):
print(json.dumps(jsonData, indent=4, separators=(',', ': '), ensure_ascii=False))
# Get list of all json files
def getAllJsonFiles(dir):
allFiles = os.listdir(dir)
jsonFiles = []
for fileName in allFiles:
if fileName.endswith('.json'):
if 'TEMPLATE'.lower() in fileName.lower():
continue
jsonFiles = jsonFiles + [fileName]
return jsonFiles
if fileName == 'all':
fileList = getAllJsonFiles('.')
else:
if os.path.isfile(fileName) == False:
print(fileName+' is not a file.')
quit()
fileList = [fileName]
# Check if paths match, * values means all match
def matchPath(pathA, pathB):
if inHop == searchHop:
return True
pathTypeA,pathValueA = convertPath(pathA)
pathTypeB,pathValueB = convertPath(pathB)
if pathTypeA == pathTypeB and (pathValueA == '*' or pathValueB == '*'):
return True
if pathTypeA == '' and pathValueA == '*':
return True
if pathTypeB == '' and pathValueB == '*':
return True
return False
def modMulti(stat, multiplier, roundVal):
if isinstance(stat, list):
tmp = []
for val in stat:
tmp.append(round(val * multiplier, roundVal))
return tmp
return round(stat * multiplier, roundVal)
def modAddAdditive(stats, data, name, varName):
if data['descr'] != "":
data['descr'] = data['descr']+' + '
data['descr'] = data['descr']+'('+name+' * '+varName+')'
if data['value'] != "":
data['value'] = data['value']+' + '
data['value'] = data['value']+'('+str(stats[name][0])+' * '+varName+')'
if data['simp'] != "":
data['simp'] = data['simp']+' + '
if isinstance(stats[name][0], list) and isinstance(stats['pow'][0], list):
data['simp'] = data['simp']+'(' \
+str(modMulti(stats[name][0],1.871,4))+' * ' \
+str(modMulti(stats['pow'][0],1.871,4))+' * '+varName+')'
else:
data['simp'] = data['simp']+'(' \
+str(modMulti(stats[name][0],(stats['pow'][0] * 1.871),4)) \
+' * '+varName+')'
if data['sb'] != "":
data['sb'] = data['sb']+' + '
data['sb'] = data['sb']+'('+str(stats[name][1])+' * '+varName+')'
if data['simpSb'] != "":
data['simpSb'] = data['simpSb']+' + '
if isinstance(stats[name][1], list) and isinstance(stats['pow'][1], list):
data['simpSb'] = \
data['simpSb']+'(' \
+str(modMulti(stats[name][1],1.871,4))+' * ' \
+str(modMulti(stats['pow'][1],1.871,4))+' * '+varName+')'
else:
data['simpSb'] = \
data['simpSb']+'(' \
+str(modMulti(stats[name][1], (stats['pow'][1] * 1.871),4)) \
+' * '+varName+')'
return data
def modAddMulti(stats, multi, name, varName):
if multi['descr'] != "":
multi['descr'] = multi['descr']+' * '
if multi['value'] != "":
multi['value'] = multi['value']+' * '
if multi['simp'] != "":
multi['simp'] = multi['simp']+' * '
if multi['sb'] != "":
multi['sb'] = multi['sb']+' * '
if multi['simpSb'] != "":
multi['simpSb'] = multi['simpSb']+' * '
if varName == "":
multi['descr'] = multi['descr']+'('+name+')'
multi['value'] = multi['value']+'('+str(stats[name][0])+')'
multi['simp'] = multi['simp']+'('+str(modMulti(stats[name][0],1,6))+')'
multi['sb'] = multi['sb']+'('+str(stats[name][0])+')'
multi['simpSb'] = multi['simpSb']+'('+str(modMulti(stats[name][1],1,6))+')'
return multi
multi['descr'] = multi['descr']+'('+name+' * '+varName+')'
multi['value'] = multi['value']+'('+str(stats[name][0])+' * '+varName+')'
multi['simp'] = multi['simp']+'('+str(modMulti(stats[name][0],1,6))+' * ' \
+varName+')'
multi['sb'] = multi['sb']+'('+str(stats[name][0])+' * '+varName+')'
multi['simpSb'] = multi['simpSb']+'('+str(modMulti(stats[name][1],1,6)) \
+' * '+varName+')'
return multi
def updateMod(dictVar):
skillJson = dictVar['jsonData']
stats = {}
for mod in skillJson["damageModifiers"]:
if mod['value'] != 0 or mod['soulburn'] != 0:
stats[mod['name']] = mod['value'],mod['soulburn']
print('stats = '+str(stats))
print('--------------------------------------------------------------')
if 'pow' not in stats:
stats['pow'] = 0,0
data = {}
data['descr'] = ""
data['value'] = ""
data['simp'] = ""
data['sb'] = ""
data['simpSb'] = ""
if stats['pow'][0] != 0:
if 'atk_rate' in stats:
data = modAddAdditive(stats, data, 'atk_rate', 'hero_atk')
if 'def_rate' in stats:
data = modAddAdditive(stats, data, 'def_rate', 'hero_def')
if 'hp_rate' in stats:
data = modAddAdditive(stats, data, 'hp_rate', 'hero_hp')
if 'target_hp_rate' in stats:
data = modAddAdditive(stats, data, 'target_hp_rate', 'target_hp')
# If any additive were added, add ( ) around it.
if data['descr'] != "":
data['descr'] = '('+data['descr']+')'
if data['value'] != "":
data['value'] = '('+data['value']+')'
if data['simp'] != "":
data['simp'] = '('+data['simp']+')'
if data['sb'] != "":
data['sb'] = '('+data['sb']+')'
if data['simpSb'] != "":
data['simpSb'] = '('+data['simpSb']+')'
if 'spd_rate' in stats or 'self_hp_current_rate' in stats or \
'self_hp_missing_rate' in stats or 'skill_dmg_rate' in stats \
or 'skill_dmg_list' in stats or 'target_hp_missing_rate' in stats \
or 'target_spd_rate' in stats:
if data['descr'] != "":
data['descr'] = data['descr']+' * (1 + '
if data['value'] != "":
data['value'] = data['value']+' * (1 + '
if data['simp'] != "":
data['simp'] = data['simp']+' * (1 + '
if data['sb'] != "":
data['sb'] = data['sb']+' * (1 + '
if data['simpSb'] != "":
data['simpSb'] = data['simpSb']+' * (1 + '
multi = {}
multi['descr'] = ""
multi['value'] = ""
multi['simp'] = ""
multi['sb'] = ""
multi['simpSb'] = ""
if 'spd_rate' in stats:
multi = modAddMulti(stats, multi, 'spd_rate', 'hero_spd')
if 'target_spd_rate' in stats:
multi = modAddMulti(stats, multi, 'target_spd_rate', 'target_spd')
if 'self_hp_current_rate' in stats:
multi = modAddMulti(stats, multi, 'self_hp_current_rate', \
'hero_hp_remaining_percent')
if 'self_hp_missing_rate' in stats:
multi = modAddMulti(stats, multi, 'self_hp_missing_rate', \
'hero_hp_lost_percent')
if 'skill_dmg_rate' in stats:
multi = modAddMulti(stats, multi, 'skill_dmg_rate', \
'hero_special_count')
if 'skill_dmg_list' in stats:
multi = modAddMulti(stats, multi, 'skill_dmg_list', '')
if 'target_hp_missing_rate' in stats:
multi = modAddMulti(stats, multi, 'target_hp_missing_rate', \
'target_hp_lost_percent')
# End multiplative
data['descr'] = data['descr']+'('+multi['descr']+'))'
data['value'] = data['value']+'('+multi['value']+'))'
data['simp'] = data['simp']+'('+multi['simp']+'))'
data['sb'] = data['sb']+'('+multi['sb']+'))'
data['simpSb'] = data['simpSb']+'('+multi['simpSb']+'))'
data['descr'] = data['descr']+' * pow! * constant'
if data['value'] != "":
data['value'] = data['value']+' * '+str(stats['pow'][0])+' * 1.871'
if data['sb'] != "":
data['sb'] = data['sb']+' * '+str(stats['pow'][1])+' * 1.871'
print('descr = '+data['descr'])
print('value = '+data['value'])
print('simp = '+data['simp'])
print('sb = '+data['sb'])
print('simpSb= '+data['simpSb'])
print('')
skillJson['simpleDmgMod'] = OrderedDict()
skillJson['simpleDmgMod']['description'] = data['descr']
skillJson['simpleDmgMod']['value'] = data['value']
skillJson['simpleDmgMod']['simplified'] = data['simp']
skillJson['simpleDmgMod']['soulburn'] = data['sb']
skillJson['simpleDmgMod']['simplifiedSoulburn'] = data['simpSb']
def custom(dictVar):
return
# Create decoder, so we can decode strings to OrderedDict.
decoder = json.JSONDecoder(object_pairs_hook=collections.OrderedDict)
# Main
for fileName in fileList:
with open(fileName, 'r') as infile:
print(fileName)
inJson = json.load(infile, object_pairs_hook=OrderedDict)
if command == 'fromFile':
with open(fromFileName, 'r') as fromfile:
fromJson = json.load(fromfile, object_pairs_hook=OrderedDict)
tmpPrevVar = replacePathVariables(fileName,inJson,ast.literal_eval(prevVar))
tmpNewVar = replacePathVariables(fromFileName,fromJson,ast.literal_eval(newVar))
tmpPrevVar = findVarValue(fromJson, tmpPrevVar)
if tmpPrevVar is None:
print(fileName+' failed to find values in '+fromFileName)
continue
jsonPtr,tmpNewVar = findVar(inJson, tmpNewVar)
jsonPtr[tmpNewVar] = tmpPrevVar
if writeOutput:
writeJson(fileName, inJson)
if printOutput:
printJson(inJson)
continue
dictList = findDictWithVar(inJson, searchVar, [])
if len(dictList) <= 0:
print(searchVar+' was not found in '+fileName+'.')
for dictVar in dictList:
print('looking at path '+str(dictVar['path']))
if findVal and dictVar['jsonData'][searchVar] != ast.literal_eval(findVal):
print('skipping path '+str(dictVar['path']))
continue
# If path variable is set, only process when path matches
if path is not None and path != dictVar['path'] and path != ['*']:
if len(path) > len(dictVar['path']):
continue
match = True
for inHop,searchHop in zip(path,dictVar['path']):
if matchPath(inHop, searchHop) == False:
match = False
if len(path) != len(dictVar['path']):
if len(path) == 0 or inHop != '*':
match = False
if match == False:
continue
print('good path')
if printPath:
print('Path: '+str(dictVar['path']))
if command == 'insert':
insertDictVar(dictVar['jsonData'], prevVar, newVar)
dictVar['jsonData'][newVar] = ast.literal_eval(value)
elif command == 'replace':
renameDictVar(dictVar['jsonData'], prevVar, newVar)
elif command == 'delete':
deleteDictVar(dictVar['jsonData'], newVar)
elif command == 'set':
dictVar['jsonData'][newVar] = ast.literal_eval(value)
elif command == 'copy':
dictVar['jsonData'][newVar] = dictVar['jsonData'][prevVar]
elif command == 'move':
moveDictVar(dictVar['jsonData'], newVar, value)
elif command == 'addToDict':
dictVar['jsonData'][prevVar][newVar] = ast.literal_eval(value)
elif command == 'addToList':
if isinstance(ast.literal_eval(value), collections.Mapping):
dictVar['jsonData'][prevVar].append(decoder.decode(value))
else:
dictVar['jsonData'][prevVar].append(ast.literal_eval(value))
elif command == 'print':
print(dictVar['jsonData'][newVar])
elif command == 'updateMod':
updateMod(dictVar)
elif command == 'custom':
custom(dictVar)
else:
continue
if writeOutput:
writeJson(fileName, inJson)
if printOutput:
printJson(inJson)