This commit is contained in:
reschan 2021-10-18 11:42:04 +07:00
commit d380bb1e6c
6 changed files with 3787 additions and 5322 deletions

1555
clean.json

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -87,7 +87,7 @@
"Alka Cometflinger": 85,
"Alkahest": 86,
"Alazarin": 87,
"All for One": 88,
"Fluorescence": 88,
"Allegro": 89,
"Almuj's Walker": 90,
"Alligator": 91,
@ -420,7 +420,7 @@
"Brackenwall": 418,
"Bravery": 419,
"Bow of Wisdom": 420,
"Breakdown": 421,
"Gert Relik": 421,
"Brass Knuckle": 422,
"Breakbeat": 423,
"Breaker Bar": 424,
@ -474,7 +474,7 @@
"Caledonia": 472,
"Call of the Void": 473,
"Calming Torc": 474,
"Cancer\u058e": 475,
"Cancer֎": 475,
"Call to Concord": 476,
"Canyon Spirit": 477,
"Candlestick": 478,
@ -575,7 +575,7 @@
"Cobra": 573,
"Coat of Byakko": 574,
"Cockleburr": 575,
"Coconut\u058e": 576,
"Coconut֎": 576,
"Col Legno": 577,
"Coiled Briar": 578,
"Cold Integrity": 579,
@ -772,7 +772,7 @@
"Sacrificial": 770,
"Admiral": 771,
"Ouragan": 772,
"Ambivalence": 773,
"Inmate Outfit": 773,
"Algaa": 774,
"Gaping Cavity": 775,
"Redbeard's Hand Cannon": 776,
@ -1658,7 +1658,7 @@
"Lizard": 1656,
"Loam": 1657,
"Little Machine": 1658,
"Lockpick\u058e": 1659,
"Lockpick֎": 1659,
"Loaded Question": 1660,
"Locrian": 1661,
"Log Suit": 1662,
@ -3544,98 +3544,104 @@
"Zombified Branch": 3542,
"default": 3543,
"Zipper": 3544,
"Anxiolytic": 3545,
"Panic Zealot": 3546,
"Dissociation": 3547,
"Adrenaline": 3548,
"Agave": 3549,
"Amanuensis": 3550,
"Ataraxy": 3551,
"Blossom Haze": 3552,
"Chain Rule": 3553,
"Clerical": 3554,
"Cursed Jackboots": 3555,
"Derecho": 3556,
"Double Vision": 3557,
"Entanglement": 3558,
"Example": 3559,
"Fluorescence": 3560,
"Gert Relik": 3561,
"Guillotine": 3562,
"Infernal Impulse": 3563,
"Inmate Outfit": 3564,
"Luminiferous Aether": 3565,
"Magnet Repulsor": 3566,
"Matchbook": 3567,
"Multitool": 3568,
"First Steps": 3569,
"Spiketop": 3570,
"Waist Apron": 3571,
"Ophiolite": 3572,
"Ornithopter": 3573,
"Outrage": 3574,
"Panic Attack": 3575,
"Pedometer": 3576,
"Phantasmagoria": 3577,
"Photon": 3578,
"Pro Tempore": 3579,
"Prosencephalon": 3580,
"Homeorhesis": 3581,
"Abrasion": 3582,
"Eyes on All": 3583,
"Metamorphosis": 3584,
"First Steps": 3545,
"Spiketop": 3546,
"Waist Apron": 3547,
"Speedyboy": 3548,
"Saltest Spear": 3549,
"Tachypsychia": 3550,
"Conspirator's Trickpockets": 3551,
"Philosopher": 3552,
"Capsid Frame": 3553,
"Crystal Coil": 3554,
"Phage Pins": 3555,
"Cold Wave": 3556,
"Heat Death": 3557,
"Impact Winter": 3558,
"Cracked Oak Bow": 3559,
"Cracked Oak Dagger": 3560,
"Cracked Oak Wand": 3561,
"Cracked Oak Spear": 3562,
"Cracked Oak Relik": 3563,
"Advancement": 3564,
"Diminution": 3565,
"Intuition": 3566,
"Hourslip": 3567,
"Longevity": 3568,
"Seal Breaker": 3569,
"Practice": 3570,
"Slainte": 3571,
"Reversion": 3572,
"Secondsaver": 3573,
"Tempo Tanto": 3574,
"Metamorphosis": 3575,
"Homeorhesis": 3576,
"Pro Tempore": 3577,
"Multitool": 3578,
"Amanuensis": 3580,
"Double Vision": 3581,
"Panic Attack": 3582,
"Schist": 3583,
"Phantasmagoria": 3584,
"Cacophony": 3585,
"Recalcitrance": 3586,
"Rhythm of the Seasons": 3587,
"Dodge Core": 3588,
"Harden Core": 3589,
"Hustle Core": 3590,
"Overload Core": 3591,
"Synchro Core": 3592,
"Cinfras Souvenir T-Shirt": 3593,
"Speedyboy": 3594,
"Saltest Spear": 3595,
"Schist": 3596,
"Scarlet Veil": 3597,
"Spiritdancer": 3598,
"Stratosphere": 3599,
"The Jingling Jester": 3600,
"Vacarme": 3601,
"Capsid Frame": 3602,
"Phage Pins": 3603,
"Crystal Coil": 3604,
"Cold Wave": 3605,
"Conspirator's Trickpockets": 3606,
"Heat Death": 3607,
"Hesperium": 3608,
"Impact Winter": 3609,
"Cracked Oak Dagger": 3610,
"Cracked Oak Relik": 3611,
"Cracked Oak Spear": 3612,
"Cracked Oak Wand": 3613,
"Cracked Oak Bow": 3614,
"Philosopher": 3615,
"Advancement": 3616,
"Dilation": 3617,
"Hourslip": 3618,
"Diminution": 3619,
"Intuition": 3620,
"Longevity": 3621,
"Practice": 3622,
"Reversion": 3623,
"Seal Breaker": 3624,
"Secondsaver": 3625,
"Slainte": 3626,
"Tempo Ticker": 3627,
"Tempo Tanto": 3628,
"Tempo Totem": 3629,
"Tempo Trebuchet": 3630,
"Tempo Trident": 3631,
"Timelocked Breath": 3632,
"Timelocked Coal": 3633,
"Timelocked Dew": 3634,
"Timelocked Spark": 3635,
"Timelocked Stone": 3636,
"Trouble Tamer": 3637,
"Tachypsychia": 3638
"Vacarme": 3586,
"Scarlet Veil": 3587,
"Guillotine": 3588,
"Adrenaline": 3589,
"Tempo Trebuchet": 3590,
"Stratosphere": 3591,
"Pedometer": 3593,
"Agave": 3594,
"Breakdown": 3595,
"Ophiolite": 3596,
"Magnet Repulsor": 3597,
"Rhythm of the Seasons": 3598,
"Infernal Impulse": 3599,
"Panic Zealot": 3600,
"Recalcitrance": 3601,
"Eyes on All": 3602,
"Derecho": 3603,
"Synchro Core": 3604,
"Clerical": 3605,
"Dodge Core": 3606,
"Ataraxy": 3607,
"Ornithopter": 3608,
"Photon": 3609,
"Blossom Haze": 3610,
"Entanglement": 3612,
"Overload Core": 3613,
"Spiritdancer": 3615,
"Harden Core": 3616,
"Chain Rule": 3617,
"Ambivalence": 3618,
"Outrage": 3619,
"Prosencephalon": 3620,
"The Jingling Jester": 3621,
"Matchbook": 3622,
"Hustle Core": 3623,
"Abrasion": 3624,
"All for One": 3625,
"Example": 3626,
"Luminiferous Aether": 3627,
"Dissociation": 3628,
"Anxiolytic": 3629,
"Cursed Jackboots": 3630,
"Cinfras Souvenir T-Shirt": 3631,
"Tempo Totem": 3632,
"Dilation": 3633,
"Tempo Ticker": 3634,
"Timelocked Breath": 3635,
"Timelocked Coal": 3636,
"Timelocked Spark": 3637,
"Timelocked Dew": 3638,
"Tempo Trident": 3639,
"Timelocked Stone": 3640,
"Trouble Tamer": 3641,
"Hesperium": 3642,
"Convergence": 3643,
"Quetzalcoatl": 3644,
"Epoch": 3645,
"Immolation": 3646,
"Oblivion": 3647,
"Narcissist": 3648
}

View file

@ -1,66 +1,154 @@
import sys
"""Json diff checker for manual testing."""
import argparse
import json
f1 = sys.argv[1]
f2 = sys.argv[2]
import sys
json1 = json.load(open(f1))
json2 = json.load(open(f2))
from recordclass import recordclass
def shorten(v):
if len(v) > 100:
return v[:100] + "..."
return v
def is_basic(t):
return t is int or t is str or t is float or t is bool or t is list
JSONDiffReporter = recordclass('JSONDiffReporter', 'val_diff len_diff type_diff path_diff get_key')
def custom_input():
if custom_input.alive:
def shorten(val):
"""Utility for printing large functions, auto shorten"""
if len(val) > 100:
return val[:100] + "..."
return val
def is_basic(val):
"""Check if the given value is a "primitive" type in json (not object)."""
return val is int or val is str or val is float or val is bool or val is list
def __custom_input(_):
"""Read from stdin unless user has cancelled"""
if __custom_input.alive:
try:
return input()
except:
custom_input.alive = False
except KeyboardInterrupt:
__custom_input.alive = False
return ""
custom_input.alive = True
__custom_input.alive = True
def list_diff(list1, list2, path):
def __print_val_diff(val1, val2, path):
print(f"{path}: Value difference")
print(f" Left: {shorten(str(val1))}")
print(f" Right: {shorten(str(val2))}")
def __print_len_diff(val1, val2, path):
print(f"{path}: Length difference")
print(f" Left (length {len(val1)}): {shorten(str(val1))}")
print(f" Right (length {len(val2)}): {shorten(str(val2))}")
def __print_type_diff(type1, type2, path):
print(f"{path}: Type difference [{str(type1)} != {str(type2)}]")
#def __print_path_diff(left, right, key, path, side):
def __print_path_diff(_1, _2, key, path, side):
if side:
print(f"{path}.{key}: Contained in right but not left")
else:
print(f"{path}.{key}: Contained in left but not right")
print(f" Value: {shorten(str(key))}")
# Default diff reporter (just prints everything)
JSON_DIFF_PRINTER = JSONDiffReporter(
__print_val_diff,
__print_len_diff,
__print_type_diff,
__print_path_diff,
__custom_input
)
def __val_diff(val1, val2, path):
errmsg = (f"{path}: Value difference\n"
+ f" Left: {shorten(str(val1))}\n"
+ f" Right: {shorten(str(val2))}")
raise ValueError(errmsg)
def __len_diff(val1, val2, path):
errmsg = (f"{path}: Length difference\n"
+ f" Left (length {len(val1)}): {shorten(str(val1))}\n"
+ f" Right (length {len(val2)}): {shorten(str(val2))}")
raise ValueError(errmsg)
def __type_diff(type1, type2, path):
raise TypeError(f"{path}: Type difference [{str(type1)} != {str(type2)}]")
#def __print_path_diff(left, right, key, path, side):
def __path_diff(_1, _2, key, path, side):
if side:
errmsg = f"{path}.{key}: Contained in right but not left\n"
else:
errmsg = f"{path}.{key}: Contained in left but not right\n"
errmsg += f" Value: {shorten(str(key))}"
raise AttributeError(errmsg)
def get_test_diff_handler(get_key):
"""Make a JSON diff handler that throws errors on failure.
:param: get_key: key getter func
"""
return JSONDiffReporter(__val_diff, __len_diff, __type_diff, __path_diff, get_key)
def list_diff(reporter, list1, list2, path) -> bool:
"""Compute list difference between two object lists (compare by key)"""
print(f"Encountered object list {path}, enter match key: ", end="", file=sys.stderr)
key = custom_input()
if (key == ""):
key = reporter.get_key(path)
if key == "":
if list1 != list2:
print(f"{path}.{k}: Value difference")
print(f" Left: {shorten(str(v))}")
print(f" Right: {shorten(str(obj))}")
reporter.val_diff(list1, list2, path)
else:
left = {x[key]: x for x in list1}
right = {x[key]: x for x in list2}
object_diff(left, right, path)
object_diff(reporter, left, right, path)
def object_diff(obj1, obj2, path):
for (k, v) in obj1.items():
def object_diff(reporter, obj1, obj2, path) -> bool:
"""Compute object difference between two objects... kinda"""
for (k, val) in obj1.items():
if k in obj2:
obj = obj2[k]
type1 = type(v)
type1 = type(val)
type2 = type(obj)
if type1 != type2:
print(f"{path}.{k}: Type difference [{str(type1)} != {str(type2)}]")
elif type1 is list and type2 is list and not is_basic(type(v[0])):
list_diff(v, obj, path+"."+str(k))
elif (type1 is list and is_basic(type(v[0]))) or is_basic(type1) or v is None or obj2 is None:
if v != obj:
print(f"{path}.{k}: Value difference")
print(f" Left: {shorten(str(v))}")
print(f" Right: {shorten(str(obj))}")
reporter.type_diff(type1, type2, f"{path}.{k}")
elif type1 is list:
if len(val) != len(obj):
reporter.len_diff(val, obj, f"{path}.{k}")
elif len(val) == 0:
continue
elif is_basic(type(val[0])):
if val != obj:
reporter.val_diff(val, obj, f"{path}.{k}")
continue
list_diff(reporter, val, obj, path+"."+k)
elif is_basic(type1) or val is None or obj2 is None:
if val != obj:
reporter.val_diff(val, obj, f"{path}.{k}")
else:
object_diff(v, obj, path+"."+str(k))
else:
print(f"{path}.{k}: Contained in left but not right")
print(f" Value: {shorten(str(v))}")
for (k, v) in obj2.items():
object_diff(reporter, val, obj, f"{path}.{k}")
continue
reporter.path_diff(obj1, obj2, k, path, True)
for k in obj2:
if k not in obj1:
print(f"{path}.{k}: Contained in right but not left")
print(f" Value: {shorten(str(v))}")
reporter.path_diff(obj1, obj2, k, path, True)
if type(json1) is list and type(json2) is list:
list_diff(json1, json2, "$")
else:
object_diff(json1, json2, "$")
def json_diff(json1, json2, reporter=JSON_DIFF_PRINTER) -> bool:
"""Run the json diff tool on two json objects."""
if isinstance(json1, list) and isinstance(json2, list):
return list_diff(reporter, json1, json2, "$")
return object_diff(reporter, json1, json2, "$")
if __name__ == "__main__":
argparser = argparse.ArgumentParser(description="JSON diff utility")
argparser.add_argument('file1', action='store', type=str,
help="First file to compare"
)
argparser.add_argument('file2', action='store', type=str,
help="Second file to compare"
)
args = argparser.parse_args()
with open(args.file1, 'r', encoding="utf-8") as file1:
json1 = json.load(file1)
with open(args.file2, 'r', encoding="utf-8") as file2:
json2 = json.load(file2)
json_diff(json1, json2)

View file

@ -209,7 +209,13 @@ for item in items:
items.extend(unchanged_items)
items.extend(remap_items)
with open("id_map.json","w") as id_mapfile:
print("{", file=id_mapfile)
outputs = []
for v, k in sorted((v, k) for k, v in id_map.items()):
outputs.append(f' "{k}": {v}')
print(',\n'.join(outputs), file=id_mapfile)
print("}", file=id_mapfile)
with open("clean.json", "w") as outfile:
json.dump(data, outfile, indent=2)
with open("compress.json", "w") as outfile:

View file

@ -1,80 +0,0 @@
import json
with open("clean.json") as infile:
olds = json.load(infile)
items = olds["items"]
item_oldnames_map = dict()
item_newnames_map = dict()
VERSION_STR = " (1.20)"
max_old_id = 0
for item in items:
item_id = item["id"]
if "displayName" in item:
displayName = item["displayName"]
else:
displayName = item["name"]
item_name = displayName.replace(VERSION_STR, "")
if item_id > 10000:
map_name = item["name"].replace(VERSION_STR, "")
item_newnames_map[map_name] = item
item["displayName"] = item_name
else:
item_oldnames_map[item_name] = item
if item_id > max_old_id:
max_old_id = item_id
dummy_items = []
for (name, item) in item_newnames_map.items():
if name in item_oldnames_map:
old_item = item_oldnames_map[name]
if "displayName" in item:
displayName = item["displayName"].replace(VERSION_STR, "")
else:
displayName = name
save_old = ["id","set","quest","drop","restrict", "name"]
old_mappings = { k: old_item[k] for k in save_old if k in old_item }
old_item.clear()
if "restrict" in item:
del item["restrict"]
for k in item:
old_item[k] = item[k]
for k in old_mappings:
old_item[k] = old_mappings[k]
save_id = item["id"]
item.clear()
item["id"] = save_id
item["name"] = str(save_id)
item["remapID"] = old_item["id"]
else:
if "restrict" in item:
in_str = input(name + " restriction: ").strip()
if in_str:
item["restrict"] = in_str
else:
del item["restrict"]
item["name"] = name
dummy_item = dict()
dummy_item["id"] = item["id"]
max_old_id += 1
item["id"] = max_old_id
dummy_item["remapID"] = item["id"]
dummy_items.append(dummy_item)
items.extend(dummy_items)
sets = olds["sets"]
data = dict()
data["items"] = items
data["sets"] = sets
with open("updated.json", "w") as outfile:
json.dump(data, outfile, indent=2)