Api v3 (#267)
* Tweak ordering to be consistent internally * v3 items (#266) * item_wrapper script for updating item data with v3 endpoint * metadata from v3 * v3 item format For the purpose of wynnbuilder, additional mapping might be needed. * v3 item format additional mapping might be needed for wb * v3 compressed item json * clean item json v3 format * Update translate map to api v3 partially... we will need to redo scripts to flatmap all the items * Fix items for 2.0.4.3 finally * New ingredients (and parse script update) just realized I forgot to commit the parse script this whole time * Forgot to commit data files, and bump ing db version * Sketchily reverse translate major ids internalname and separate lookup table lol * Forgot to update data files todo: script should update all files at once * Bump wynn version number already outdated... * Forgot to update 2.0.4.3 major ids --------- Co-authored-by: hppeng <hppeng> Co-authored-by: RawFish69 <108964215+RawFish69@users.noreply.github.com>
This commit is contained in:
parent
165adf6dcc
commit
df9412e994
25 changed files with 322169 additions and 117246 deletions
180857
clean.json
180857
clean.json
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
1
data/2.0.4.3/atree.json
Normal file
1
data/2.0.4.3/atree.json
Normal file
File diff suppressed because one or more lines are too long
1
data/2.0.4.3/ingreds.json
Normal file
1
data/2.0.4.3/ingreds.json
Normal file
File diff suppressed because one or more lines are too long
1
data/2.0.4.3/items.json
Normal file
1
data/2.0.4.3/items.json
Normal file
File diff suppressed because one or more lines are too long
1
data/2.0.4.3/majid.json
Executable file
1
data/2.0.4.3/majid.json
Executable file
File diff suppressed because one or more lines are too long
1
data/2.0.4.3/recipes.json
Normal file
1
data/2.0.4.3/recipes.json
Normal file
File diff suppressed because one or more lines are too long
1069
data/2.0.4.3/tomes.json
Normal file
1069
data/2.0.4.3/tomes.json
Normal file
File diff suppressed because it is too large
Load diff
59928
ingreds_clean.json
59928
ingreds_clean.json
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
196538
items_clean.json
Normal file
196538
items_clean.json
Normal file
File diff suppressed because it is too large
Load diff
1
items_compress.json
Normal file
1
items_compress.json
Normal file
File diff suppressed because one or more lines are too long
|
@ -33,7 +33,8 @@ const wynn_version_names = [
|
||||||
'2.0.2.1',
|
'2.0.2.1',
|
||||||
'2.0.2.3',
|
'2.0.2.3',
|
||||||
'2.0.3.1',
|
'2.0.3.1',
|
||||||
'2.0.4.1'
|
'2.0.4.1',
|
||||||
|
'2.0.4.3'
|
||||||
];
|
];
|
||||||
const WYNN_VERSION_LATEST = wynn_version_names.length - 1;
|
const WYNN_VERSION_LATEST = wynn_version_names.length - 1;
|
||||||
// Default to the newest version.
|
// Default to the newest version.
|
||||||
|
|
|
@ -1,4 +1,14 @@
|
||||||
{
|
{
|
||||||
|
"FISSION": {
|
||||||
|
"displayName": "Fission",
|
||||||
|
"description": "Explosions from your Exploding ID are twice as big and twice as strong",
|
||||||
|
"abilities": []
|
||||||
|
},
|
||||||
|
"EXPLOSIVE_IMPACT": {
|
||||||
|
"displayName": "Explosive Impact",
|
||||||
|
"description": "Your Exploding ID can trigger when hitting mobs with your Main Attack",
|
||||||
|
"abilities": []
|
||||||
|
},
|
||||||
"MAGNET": {
|
"MAGNET": {
|
||||||
"displayName": "Magnet",
|
"displayName": "Magnet",
|
||||||
"description": "Pulls items within an 8 block radius towards you",
|
"description": "Pulls items within an 8 block radius towards you",
|
||||||
|
@ -214,7 +224,7 @@
|
||||||
"abilities": []
|
"abilities": []
|
||||||
},
|
},
|
||||||
"DESC_FESTIVESPIRIT": {
|
"DESC_FESTIVESPIRIT": {
|
||||||
"displayName": "Festive Spirits",
|
"displayName": "Festive Spirit",
|
||||||
"description": "Plays wintery tunes",
|
"description": "Plays wintery tunes",
|
||||||
"abilities": []
|
"abilities": []
|
||||||
},
|
},
|
||||||
|
@ -260,7 +270,7 @@
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"ALTEREGO": {
|
"ALTEREGO": {
|
||||||
"displayName": "Alterego",
|
"displayName": "Alter Ego",
|
||||||
"description": "Awakened can be activated after saving 40% less mana, but its duration is reduced by 25%.",
|
"description": "Awakened can be activated after saving 40% less mana, but its duration is reduced by 25%.",
|
||||||
"abilities": []
|
"abilities": []
|
||||||
},
|
},
|
||||||
|
@ -296,7 +306,7 @@
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"SOUL_EATER": {
|
"SOUL_EATER": {
|
||||||
"displayName": "Soul eater",
|
"displayName": "Soul Eater",
|
||||||
"description": "Devour and Harvester grant double mana, but your maximum Marks are decreased by 1.",
|
"description": "Devour and Harvester grant double mana, but your maximum Marks are decreased by 1.",
|
||||||
"abilities": [{
|
"abilities": [{
|
||||||
"class": "Assassin",
|
"class": "Assassin",
|
||||||
|
@ -508,5 +518,15 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
},
|
||||||
|
"LUNGE": {
|
||||||
|
"displayName": "Lunge",
|
||||||
|
"description":"Hop's horizontal velocity is greatly increased",
|
||||||
|
"abilities": []
|
||||||
|
},
|
||||||
|
"WINDSURF": {
|
||||||
|
"displayName": "Windsurf",
|
||||||
|
"description":"Righting Reflex lasts twice as long and is affected stronger by movement speed",
|
||||||
|
"abilities": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
let recipeTypes = ["HELMET","CHESTPLATE","LEGGINGS","BOOTS","RELIK","WAND","SPEAR","DAGGER","BOW","RING","NECKLACE","BRACELET","SCROLL","FOOD","POTION"];
|
let recipeTypes = ["HELMET","CHESTPLATE","LEGGINGS","BOOTS","RELIK","WAND","SPEAR","DAGGER","BOW","RING","NECKLACE","BRACELET","POTION", "SCROLL","FOOD"];
|
||||||
let levelTypes = ["1-3","3-5","5-7","7-9","10-13","13-15","15-17","17-19","20-23","23-25","25-27","27-29","30-33","33-35","35-37","37-39","40-43","43-45","45-47","47-49","50-53","53-55","55-57","57-59","60-63","63-65","65-67","67-69","70-73","73-75","75-77","77-79","80-83","83-85","85-87","87-89","90-93","93-95","95-97","97-99","100-103","103-105",]
|
let levelTypes = ["1-3","3-5","5-7","7-9","10-13","13-15","15-17","17-19","20-23","23-25","25-27","27-29","30-33","33-35","35-37","37-39","40-43","43-45","45-47","47-49","50-53","53-55","55-57","57-59","60-63","63-65","65-67","67-69","70-73","73-75","75-77","77-79","80-83","83-85","85-87","87-89","90-93","93-95","95-97","97-99","100-103","103-105",]
|
||||||
|
|
||||||
function encodeCraft(craft) {
|
function encodeCraft(craft) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const DB_VERSION = 129;
|
const DB_VERSION = 130;
|
||||||
// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.jsA
|
// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.jsA
|
||||||
|
|
||||||
let db;
|
let db;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const ING_DB_VERSION = 29;
|
const ING_DB_VERSION = 30;
|
||||||
|
|
||||||
// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.js
|
// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.js
|
||||||
|
|
||||||
|
|
|
@ -3847,5 +3847,26 @@
|
||||||
"Pain Cycle": 3845,
|
"Pain Cycle": 3845,
|
||||||
"Psionic Pretense": 3846,
|
"Psionic Pretense": 3846,
|
||||||
"Propeller Hat": 3847,
|
"Propeller Hat": 3847,
|
||||||
"Tremorcaller": 3848
|
"Tremorcaller": 3848,
|
||||||
|
"Black Skull": 3849,
|
||||||
|
"Replica Hallowynn Mask": 3850,
|
||||||
|
"Esteemed Bronze Mask of Legendary Victory": 3851,
|
||||||
|
"Swashbuckler's Brogues": 3852,
|
||||||
|
"Outlandish Replica Face Mask of Legendary Victory": 3853,
|
||||||
|
"Mystical Tags": 3854,
|
||||||
|
"Future Shock Plating": 3855,
|
||||||
|
"Spider Leg Suit": 3856,
|
||||||
|
"Ceremonial Skirt": 3857,
|
||||||
|
"Runebound Chains": 3858,
|
||||||
|
"Ice-cold Robe": 3859,
|
||||||
|
"Blob Monster Mask": 3860,
|
||||||
|
"Psychopomp's Pileus": 3861,
|
||||||
|
"Revered Silver Mask of Legendary Victory": 3862,
|
||||||
|
"Treasured Diamond Mask of Legendary Victory": 3863,
|
||||||
|
"Venerated Gold Mask of Legendary Victory": 3864,
|
||||||
|
"Beige Wynnter Sweater": 3865,
|
||||||
|
"Scarlet Wynnter Sweater": 3866,
|
||||||
|
"Orange Wynnter Sweater": 3867,
|
||||||
|
"Pine Wynnter Sweater": 3868,
|
||||||
|
"Indigo Wynnter Sweater": 3869
|
||||||
}
|
}
|
231
py_script/item_metadata.json
Normal file
231
py_script/item_metadata.json
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
{
|
||||||
|
"identifications": [
|
||||||
|
"rawMainAttackDamage",
|
||||||
|
"rawSpellDamage",
|
||||||
|
"healthRegenRaw",
|
||||||
|
"manaSteal",
|
||||||
|
"walkSpeed",
|
||||||
|
"thunderDamage",
|
||||||
|
"rawStrength",
|
||||||
|
"rawDexterity",
|
||||||
|
"rawIntelligence",
|
||||||
|
"rawDefence",
|
||||||
|
"rawAgility",
|
||||||
|
"lootBonus",
|
||||||
|
"fireDefence",
|
||||||
|
"airDefence",
|
||||||
|
"mainAttackDamage",
|
||||||
|
"spellDamage",
|
||||||
|
"exploding",
|
||||||
|
"airDamage",
|
||||||
|
"rawHealth",
|
||||||
|
"reflection",
|
||||||
|
"earthDefence",
|
||||||
|
"earthDamage",
|
||||||
|
"waterDamage",
|
||||||
|
"waterDefence",
|
||||||
|
"healthRegen",
|
||||||
|
"manaRegen",
|
||||||
|
"fireDamage",
|
||||||
|
"lifeSteal",
|
||||||
|
"rawAttackSpeed",
|
||||||
|
"xpBonus",
|
||||||
|
"thunderDefence",
|
||||||
|
"thorns",
|
||||||
|
"soulPointRegen",
|
||||||
|
"stealing",
|
||||||
|
"1stSpellCost",
|
||||||
|
"2ndSpellCost",
|
||||||
|
"raw1stSpellCost",
|
||||||
|
"raw3rdSpellCost",
|
||||||
|
"jumpHeight",
|
||||||
|
"airSpellDamage",
|
||||||
|
"poison",
|
||||||
|
"elementalDamage",
|
||||||
|
"raw4thSpellCost",
|
||||||
|
"raw2ndSpellCost",
|
||||||
|
"sprintRegen",
|
||||||
|
"slowEnemy",
|
||||||
|
"3rdSpellCost",
|
||||||
|
"sprint",
|
||||||
|
"elementalSpellDamage",
|
||||||
|
"rawNeutralSpellDamage",
|
||||||
|
"4thSpellCost",
|
||||||
|
"healingEfficiency",
|
||||||
|
"knockback",
|
||||||
|
"waterSpellDamage",
|
||||||
|
"fireSpellDamage",
|
||||||
|
"rawAirMainAttackDamage",
|
||||||
|
"rawAirSpellDamage",
|
||||||
|
"earthSpellDamage",
|
||||||
|
"rawThunderDamage",
|
||||||
|
"rawWaterDamage",
|
||||||
|
"rawElementalDamage",
|
||||||
|
"rawEarthSpellDamage",
|
||||||
|
"elementalDefence",
|
||||||
|
"rawThunderMainAttackDamage",
|
||||||
|
"thunderSpellDamage",
|
||||||
|
"rawThunderSpellDamage",
|
||||||
|
"rawFireMainAttackDamage",
|
||||||
|
"weakenEnemy",
|
||||||
|
"rawWaterSpellDamage",
|
||||||
|
"earthMainAttackDamage",
|
||||||
|
"rawFireSpellDamage",
|
||||||
|
"rawElementalSpellDamage",
|
||||||
|
"rawElementalMainAttackDamage",
|
||||||
|
"airMainAttackDamage",
|
||||||
|
"thunderMainAttackDamage",
|
||||||
|
"leveledLootBonus",
|
||||||
|
"damageFromMobs",
|
||||||
|
"leveledXpBonus",
|
||||||
|
"elementalDefense",
|
||||||
|
"rawAirDamage",
|
||||||
|
"rawEarthDamage",
|
||||||
|
"rawFireDamage",
|
||||||
|
"rawNeutralDamage",
|
||||||
|
"lootQuality",
|
||||||
|
"gatherXpBonus",
|
||||||
|
"gatherSpeed",
|
||||||
|
"rawWaterMainAttackDamage"
|
||||||
|
],
|
||||||
|
"majorIds": [
|
||||||
|
"Divine Honor",
|
||||||
|
"Greed",
|
||||||
|
"Magnet",
|
||||||
|
"Plague",
|
||||||
|
"Saviour\u2019s Sacrifice",
|
||||||
|
"Sorcery",
|
||||||
|
"Soul Eater",
|
||||||
|
"Cherry Bombs",
|
||||||
|
"Expunge",
|
||||||
|
"Flashfreeze",
|
||||||
|
"Gentle Glow",
|
||||||
|
"Gruesome Knots",
|
||||||
|
"Peaceful Effigy",
|
||||||
|
"Rally",
|
||||||
|
"Reckless Abandon",
|
||||||
|
"Gravity Well",
|
||||||
|
"Perfect Recall",
|
||||||
|
"Cavalryman",
|
||||||
|
"Entropy",
|
||||||
|
"Escape Route",
|
||||||
|
"Lightweight",
|
||||||
|
"Snowy Steps",
|
||||||
|
"Taunt",
|
||||||
|
"Dead Weight",
|
||||||
|
"Furious Effigy",
|
||||||
|
"Geocentrism",
|
||||||
|
"Strings of Fate",
|
||||||
|
"Alter Ego",
|
||||||
|
"Explosive Impact",
|
||||||
|
"Festive Spirit",
|
||||||
|
"Freerunner",
|
||||||
|
"Hawkeye",
|
||||||
|
"Windsurf",
|
||||||
|
"Juggle",
|
||||||
|
"Roving Assassin",
|
||||||
|
"Transcendence",
|
||||||
|
"Fission",
|
||||||
|
"Forest's Blessing",
|
||||||
|
"Heart of the Pack",
|
||||||
|
"Coagulate",
|
||||||
|
"Guardian",
|
||||||
|
"Overwhelm",
|
||||||
|
"Temblor",
|
||||||
|
"Lunge",
|
||||||
|
"Madness"
|
||||||
|
],
|
||||||
|
"filters": {
|
||||||
|
"type": [
|
||||||
|
"weapons",
|
||||||
|
"armour",
|
||||||
|
"accessories",
|
||||||
|
"tomes",
|
||||||
|
"charms",
|
||||||
|
"tools",
|
||||||
|
"ingredients",
|
||||||
|
"materials"
|
||||||
|
],
|
||||||
|
"advanced": {
|
||||||
|
"attackSpeed": [
|
||||||
|
"super_slow",
|
||||||
|
"very_slow",
|
||||||
|
"slow",
|
||||||
|
"normal",
|
||||||
|
"fast",
|
||||||
|
"very_fast",
|
||||||
|
"super_fast"
|
||||||
|
],
|
||||||
|
"weapons": [
|
||||||
|
"bow",
|
||||||
|
"relik",
|
||||||
|
"wand",
|
||||||
|
"dagger",
|
||||||
|
"spear"
|
||||||
|
],
|
||||||
|
"armour": [
|
||||||
|
"helmet",
|
||||||
|
"chestplate",
|
||||||
|
"leggings",
|
||||||
|
"boots"
|
||||||
|
],
|
||||||
|
"accessories": [
|
||||||
|
"necklace",
|
||||||
|
"ring",
|
||||||
|
"bracelet"
|
||||||
|
],
|
||||||
|
"tomes": [
|
||||||
|
"weaponTome",
|
||||||
|
"armourTome",
|
||||||
|
"slayingTome",
|
||||||
|
"dungeonTome",
|
||||||
|
"gatheringTome",
|
||||||
|
"guildTome",
|
||||||
|
"lootrunTome"
|
||||||
|
],
|
||||||
|
"tools": [
|
||||||
|
"axe",
|
||||||
|
"pickaxe",
|
||||||
|
"rod",
|
||||||
|
"scythe"
|
||||||
|
],
|
||||||
|
"crafting": [
|
||||||
|
"alchemism",
|
||||||
|
"armouring",
|
||||||
|
"cooking",
|
||||||
|
"jeweling",
|
||||||
|
"scribing",
|
||||||
|
"tailoring",
|
||||||
|
"weaponsmithing",
|
||||||
|
"woodworking"
|
||||||
|
],
|
||||||
|
"gathering": [
|
||||||
|
"mining",
|
||||||
|
"fishing",
|
||||||
|
"farming",
|
||||||
|
"woodcutting"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"tier": {
|
||||||
|
"items": [
|
||||||
|
"common",
|
||||||
|
"fabled",
|
||||||
|
"legendary",
|
||||||
|
"mythic",
|
||||||
|
"rare",
|
||||||
|
"set",
|
||||||
|
"unique"
|
||||||
|
],
|
||||||
|
"ingredients": [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"levelRange": {
|
||||||
|
"items": 110,
|
||||||
|
"ingredients": 105
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
114
py_script/item_wrapper.py
Normal file
114
py_script/item_wrapper.py
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
"""
|
||||||
|
Description: Quick item save/search with v3 item database
|
||||||
|
API Documentation: https://documentation.wynncraft.com/docs/
|
||||||
|
Update item db: python item_wrapper.py update-item [file_directory]
|
||||||
|
Item search: python item_wrapper.py search -keyword [War] -itemType [mythic] ...
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
|
||||||
|
class Items:
|
||||||
|
"""v3 item wrapping - Synchronous"""
|
||||||
|
|
||||||
|
def fetch(self, url):
|
||||||
|
response = requests.get(url)
|
||||||
|
return response.json()
|
||||||
|
|
||||||
|
def post(self, url, data=None):
|
||||||
|
response = requests.post(url, json=data)
|
||||||
|
return response.json()
|
||||||
|
|
||||||
|
def get_all_items(self):
|
||||||
|
api_url = "https://api.wynncraft.com/v3/item/database?fullResult=True"
|
||||||
|
return self.fetch(api_url)
|
||||||
|
|
||||||
|
def get_metadata(self):
|
||||||
|
url = "https://api.wynncraft.com/v3/item/metadata"
|
||||||
|
return self.fetch(url)
|
||||||
|
|
||||||
|
def item_query(self, data=None):
|
||||||
|
api_url = "https://api.wynncraft.com/v3/item/search?fullResult=True"
|
||||||
|
return self.post(api_url, data)
|
||||||
|
|
||||||
|
|
||||||
|
def update_items(file_path):
|
||||||
|
data = Items().get_all_items()
|
||||||
|
update_file(data, file_path)
|
||||||
|
print(f"{len(data)} items updated")
|
||||||
|
|
||||||
|
|
||||||
|
def update_metadata(file_path):
|
||||||
|
data = Items().get_metadata()
|
||||||
|
update_file(data, file_path)
|
||||||
|
print("Metadata updated")
|
||||||
|
|
||||||
|
|
||||||
|
def update_file(input, output):
|
||||||
|
try:
|
||||||
|
with open(output, "w") as file:
|
||||||
|
json.dump(input, file, indent=3)
|
||||||
|
except Exception as error:
|
||||||
|
print(f"File update error: {error}")
|
||||||
|
|
||||||
|
|
||||||
|
def item_search_param(keyword=None, itemType=None, itemTier=None, atkSpeed=None, lvlRange=None, prof=None, ids=None, majorId=None):
|
||||||
|
payload = {
|
||||||
|
"query": [] if keyword is None else keyword,
|
||||||
|
"type": [] if itemType is None else itemType,
|
||||||
|
"tier": [] if itemTier is None else itemTier,
|
||||||
|
"attackSpeed": [] if atkSpeed is None else atkSpeed,
|
||||||
|
"levelRange": [] if lvlRange is None else lvlRange,
|
||||||
|
"professions": [] if prof is None else prof,
|
||||||
|
"identifications": [] if ids is None else ids,
|
||||||
|
"majorIds": [] if majorId is None else majorId
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
response = Items().item_query(payload)
|
||||||
|
print(json.dumps(response, indent=3))
|
||||||
|
# Save the response as needed
|
||||||
|
|
||||||
|
except requests.RequestException as error:
|
||||||
|
print(f"Request error: {error}")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description='Wynncraft Item API Script')
|
||||||
|
subparsers = parser.add_subparsers(dest='command', help='Pick your poison')
|
||||||
|
update_items_parser = subparsers.add_parser('update-items', help='Update all items')
|
||||||
|
update_items_parser.add_argument('file', help='File path for saving item json')
|
||||||
|
update_metadata_parser = subparsers.add_parser('update-metadata', help='Update metadata')
|
||||||
|
update_metadata_parser.add_argument('file', help='File path for saving metadata json')
|
||||||
|
|
||||||
|
search_parser = subparsers.add_parser('search', help='Search for items with parameters')
|
||||||
|
search_parser.add_argument('-keyword', type=str, default=None, help='Keyword for item search')
|
||||||
|
search_parser.add_argument('-itemType', type=str, default=None, help='Item type: wand, bow, etc')
|
||||||
|
search_parser.add_argument('-itemTier', type=str, default=None, help='Item tier: mythic, legendary, etc')
|
||||||
|
search_parser.add_argument('-atkSpeed', type=str, default=None, help='Attack speed param')
|
||||||
|
search_parser.add_argument('-lvlRange', nargs=2, type=int, default=None, help='Level range for: min, max')
|
||||||
|
search_parser.add_argument('-prof', type=str, default=None, help='Professions (Ing)')
|
||||||
|
search_parser.add_argument('-ids', type=str, default=None, help='Identifications field')
|
||||||
|
search_parser.add_argument('-majorId', type=str, default=None, help='Major IDs')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.command == 'update-items':
|
||||||
|
update_items(args.file)
|
||||||
|
elif args.command == 'update-metadata':
|
||||||
|
update_metadata(args.file)
|
||||||
|
elif args.command == 'search':
|
||||||
|
item_search_param(
|
||||||
|
keyword=args.keyword,
|
||||||
|
itemType=args.itemType,
|
||||||
|
itemTier=args.itemTier,
|
||||||
|
atkSpeed=args.atkSpeed,
|
||||||
|
lvlRange=args.lvlRange,
|
||||||
|
prof=args.prof,
|
||||||
|
ids=args.ids,
|
||||||
|
majorId=args.majorId
|
||||||
|
)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
|
@ -1,140 +1,6 @@
|
||||||
translate_mappings = {
|
import json
|
||||||
#"name": "name",
|
with open("translate_mappings.json", 'r') as infile:
|
||||||
#"displayName": "displayName",
|
translate_mappings = json.load(infile)
|
||||||
#"tier": "tier",
|
|
||||||
#"set": "set",
|
|
||||||
"sockets": "slots",
|
|
||||||
#"type": "type",
|
|
||||||
#"armorType": "armorType", (deleted)
|
|
||||||
"armorColor": "color", #(deleted)
|
|
||||||
"addedLore": "lore", #(deleted)
|
|
||||||
#"material": "material", (deleted)
|
|
||||||
"dropType": "drop",
|
|
||||||
#"quest": "quest",
|
|
||||||
"restrictions": "restrict",
|
|
||||||
"damage": "nDam",
|
|
||||||
"fireDamage": "fDam",
|
|
||||||
"waterDamage": "wDam",
|
|
||||||
"airDamage": "aDam",
|
|
||||||
"thunderDamage": "tDam",
|
|
||||||
"earthDamage": "eDam",
|
|
||||||
"attackSpeed": "atkSpd",
|
|
||||||
"health": "hp",
|
|
||||||
"fireDefense": "fDef",
|
|
||||||
"waterDefense": "wDef",
|
|
||||||
"airDefense": "aDef",
|
|
||||||
"thunderDefense": "tDef",
|
|
||||||
"earthDefense": "eDef",
|
|
||||||
"level": "lvl",
|
|
||||||
"classRequirement": "classReq",
|
|
||||||
"strength": "strReq",
|
|
||||||
"dexterity": "dexReq",
|
|
||||||
"intelligence": "intReq",
|
|
||||||
"agility": "agiReq",
|
|
||||||
"defense": "defReq",
|
|
||||||
"healthRegen": "hprPct",
|
|
||||||
"manaRegen": "mr",
|
|
||||||
"spellDamageBonus": "sdPct",
|
|
||||||
"spellElementalDamageBonus": "rSdPct",
|
|
||||||
"spellNeutralDamageBonus": "nSdPct",
|
|
||||||
"spellFireDamageBonus": "fSdPct",
|
|
||||||
"spellWaterDamageBonus": "wSdPct",
|
|
||||||
"spellAirDamageBonus": "aSdPct",
|
|
||||||
"spellThunderDamageBonus": "tSdPct",
|
|
||||||
"spellEarthDamageBonus": "eSdPct",
|
|
||||||
"mainAttackDamageBonus": "mdPct",
|
|
||||||
"mainAttackElementalDamageBonus": "rMdPct",
|
|
||||||
"mainAttackNeutralDamageBonus": "nMdPct",
|
|
||||||
"mainAttackFireDamageBonus": "fMdPct",
|
|
||||||
"mainAttackWaterDamageBonus": "wMdPct",
|
|
||||||
"mainAttackAirDamageBonus": "aMdPct",
|
|
||||||
"mainAttackThunderDamageBonus": "tMdPct",
|
|
||||||
"mainAttackEarthDamageBonus": "eMdPct",
|
|
||||||
"lifeSteal": "ls",
|
|
||||||
"manaSteal": "ms",
|
|
||||||
"xpBonus": "xpb",
|
|
||||||
"lootBonus": "lb",
|
|
||||||
"reflection": "ref",
|
|
||||||
"strengthPoints": "str",
|
|
||||||
"dexterityPoints": "dex",
|
|
||||||
"intelligencePoints": "int",
|
|
||||||
"agilityPoints": "agi",
|
|
||||||
"defensePoints": "def",
|
|
||||||
#"thorns": "thorns",
|
|
||||||
"exploding": "expd",
|
|
||||||
"speed": "spd",
|
|
||||||
"attackSpeedBonus": "atkTier",
|
|
||||||
#"poison": "poison",
|
|
||||||
"healthBonus": "hpBonus",
|
|
||||||
"soulPoints": "spRegen",
|
|
||||||
"emeraldStealing": "eSteal",
|
|
||||||
"healthRegenRaw": "hprRaw",
|
|
||||||
"spellDamageBonusRaw": "sdRaw",
|
|
||||||
"spellElementalDamageBonusRaw": "rSdRaw",
|
|
||||||
"spellNeutralDamageBonusRaw": "nSdRaw",
|
|
||||||
"spellFireDamageBonusRaw": "fSdRaw",
|
|
||||||
"spellWaterDamageBonusRaw": "wSdRaw",
|
|
||||||
"spellAirDamageBonusRaw": "aSdRaw",
|
|
||||||
"spellThunderDamageBonusRaw": "tSdRaw",
|
|
||||||
"spellEarthDamageBonusRaw": "eSdRaw",
|
|
||||||
"mainAttackDamageBonusRaw": "mdRaw",
|
|
||||||
"mainAttackElementalDamageBonusRaw": "rMdRaw",
|
|
||||||
"mainAttackNeutralDamageBonusRaw": "nMdRaw",
|
|
||||||
"mainAttackFireDamageBonusRaw": "fMdRaw",
|
|
||||||
"mainAttackWaterDamageBonusRaw": "wMdRaw",
|
|
||||||
"mainAttackAirDamageBonusRaw": "aMdRaw",
|
|
||||||
"mainAttackThunderDamageBonusRaw": "tMdRaw",
|
|
||||||
"mainAttackEarthDamageBonusRaw": "eMdRaw",
|
|
||||||
#"bonusFireDamage": "fDamPct",
|
|
||||||
#"bonusWaterDamage": "wDamPct",
|
|
||||||
#"bonusAirDamage": "aDamPct",
|
|
||||||
#"bonusThunderDamage": "tDamPct",
|
|
||||||
#"bonusEarthDamage": "eDamPct",
|
|
||||||
"fireDamageBonus": "fDamPct",
|
|
||||||
"waterDamageBonus": "wDamPct",
|
|
||||||
"airDamageBonus": "aDamPct",
|
|
||||||
"thunderDamageBonus": "tDamPct",
|
|
||||||
"earthDamageBonus": "eDamPct",
|
|
||||||
"elementalDamageBonus": "rDamPct",
|
|
||||||
"fireDamageBonusRaw": "fDamRaw",
|
|
||||||
"waterDamageBonusRaw": "wDamRaw",
|
|
||||||
"airDamageBonusRaw": "aDamRaw",
|
|
||||||
"thunderDamageBonusRaw": "tDamRaw",
|
|
||||||
"earthDamageBonusRaw": "eDamRaw",
|
|
||||||
"elementalDamageBonusRaw": "rDamRaw",
|
|
||||||
"bonusFireDefense": "fDefPct",
|
|
||||||
"bonusWaterDefense": "wDefPct",
|
|
||||||
"bonusAirDefense": "aDefPct",
|
|
||||||
"bonusThunderDefense": "tDefPct",
|
|
||||||
"bonusEarthDefense": "eDefPct",
|
|
||||||
"accessoryType": "type",
|
|
||||||
"identified": "fixID",
|
|
||||||
#"skin": "skin",
|
|
||||||
#"category": "category",
|
|
||||||
|
|
||||||
"spellCostPct1": "spPct1",
|
|
||||||
"spellCostRaw1": "spRaw1",
|
|
||||||
"spellCostPct2": "spPct2",
|
|
||||||
"spellCostRaw2": "spRaw2",
|
|
||||||
"spellCostPct3": "spPct3",
|
|
||||||
"spellCostRaw3": "spRaw3",
|
|
||||||
"spellCostPct4": "spPct4",
|
|
||||||
"spellCostRaw4": "spRaw4",
|
|
||||||
|
|
||||||
#"sprint": "sprint",
|
|
||||||
"sprintRegen": "sprintReg",
|
|
||||||
"jumpHeight": "jh",
|
|
||||||
"lootQuality": "lq",
|
|
||||||
|
|
||||||
"gatherXpBonus": "gXp",
|
|
||||||
"gatherSpeed": "gSpd",
|
|
||||||
|
|
||||||
"healingEfficiency": "healPct",
|
|
||||||
"knockback": "kb",
|
|
||||||
"weakenEnemy": "weakenEnemy",
|
|
||||||
"slowEnemy": "slowEnemy",
|
|
||||||
"elementalDefense": "rDefPct",
|
|
||||||
}
|
|
||||||
|
|
||||||
delete_keys = [
|
delete_keys = [
|
||||||
#"addedLore",
|
#"addedLore",
|
||||||
|
@ -143,3 +9,36 @@ delete_keys = [
|
||||||
#"armorColor",
|
#"armorColor",
|
||||||
#"material"
|
#"material"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# SELF TEST: compare dict keys with `item_metadata.json`.
|
||||||
|
from item_wrapper import Items
|
||||||
|
local_metadata_file = "item_metadata.json"
|
||||||
|
|
||||||
|
def debug(*args, **kwargs):
|
||||||
|
print(*args, **kwargs)
|
||||||
|
|
||||||
|
try:
|
||||||
|
debug("updating item metadata...")
|
||||||
|
metadata_check = Items().get_metadata()
|
||||||
|
with open(local_metadata_file, 'w') as outfile:
|
||||||
|
json.dump(metadata_check, outfile, indent=2)
|
||||||
|
except:
|
||||||
|
debug("Could not update item metadata. using local wynn metadata")
|
||||||
|
with open(local_metadata_file, 'r') as infile:
|
||||||
|
metadata_check = json.load(infile)
|
||||||
|
|
||||||
|
checklist = set(x for x in translate_mappings.keys())
|
||||||
|
debug(f"Checking {len(checklist)} identifications")
|
||||||
|
n = 0
|
||||||
|
for identification in metadata_check['identifications']:
|
||||||
|
if identification in checklist:
|
||||||
|
checklist.remove(identification)
|
||||||
|
else:
|
||||||
|
print(f"WARNING: id not accounted for: {identification}")
|
||||||
|
n += 1
|
||||||
|
debug(f"{n} unmapped API identifications.")
|
||||||
|
|
||||||
|
for identification in checklist:
|
||||||
|
print(f"WARNING: unused translate map entry {identification}")
|
||||||
|
debug(f"{len(checklist)} unused translation entries.")
|
||||||
|
|
|
@ -187,7 +187,7 @@ for ing in ings:
|
||||||
"notTouching": 0
|
"notTouching": 0
|
||||||
}
|
}
|
||||||
if 'itemIDs' not in ing:
|
if 'itemIDs' not in ing:
|
||||||
ing['consumableIDs'] = {
|
ing['itemIDs'] = {
|
||||||
"dura": 0,
|
"dura": 0,
|
||||||
"strReq": 0,
|
"strReq": 0,
|
||||||
"dexReq": 0,
|
"dexReq": 0,
|
||||||
|
|
|
@ -15,15 +15,16 @@ import sys
|
||||||
import os
|
import os
|
||||||
import base64
|
import base64
|
||||||
import argparse
|
import argparse
|
||||||
from items_common import translate_mappings, delete_keys
|
#from items_common import translate_mappings, delete_keys
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description="Process raw pulled item data.")
|
parser = argparse.ArgumentParser(description="Process raw pulled item data.")
|
||||||
parser.add_argument('infile', help='input file to read data from')
|
parser.add_argument('infile', help='input file to read data from', default=None, nargs='?')
|
||||||
parser.add_argument('outfile', help='output file to dump clean data into')
|
parser.add_argument('outfile', help='output file to dump clean data into')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
infile, outfile = args.infile, args.outfile
|
if args.infile is None:
|
||||||
|
print("Grabbing json data from wynn api")
|
||||||
|
|
||||||
with open(infile, "r") as in_file:
|
with open(args.infile, "r") as in_file:
|
||||||
data = json.loads(in_file.read())
|
data = json.loads(in_file.read())
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,8 +66,9 @@ for item in items:
|
||||||
|
|
||||||
for k, v in translate_mappings.items():
|
for k, v in translate_mappings.items():
|
||||||
if k in item:
|
if k in item:
|
||||||
item[v] = item[k]
|
tmp = item[k]
|
||||||
del item[k]
|
del item[k]
|
||||||
|
item[v] = tmp
|
||||||
|
|
||||||
if not (item["name"] in id_map):
|
if not (item["name"] in id_map):
|
||||||
while max_id in used_ids:
|
while max_id in used_ids:
|
||||||
|
|
189
py_script/translate_mappings.json
Normal file
189
py_script/translate_mappings.json
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
{
|
||||||
|
"ingredient": {
|
||||||
|
"name": "displayName",
|
||||||
|
"internalName": "name",
|
||||||
|
"tier": "tier",
|
||||||
|
"material": "DELETE;",
|
||||||
|
"skin": "DELETE;",
|
||||||
|
"itemOnlyIDs": "RECURSE_ingredient.itemIDs;itemIDs",
|
||||||
|
"consumableOnlyIDs": "RECURSE_ingredient.consumableIDs;consumableIDs",
|
||||||
|
"ingredientPositionModifiers": "RECURSE_ingredient.posMods;posMods",
|
||||||
|
"identifications": "RECURSE_identifications;ids",
|
||||||
|
"droppedBy": "DELETE;",
|
||||||
|
"___droppedBy_comment:": "Deleting for now because it is way too large and we cannot use it in a meaningful way. But this is nice data for when wynnatlas ever gets updated",
|
||||||
|
"requirements": "UNWRAP;requirements"
|
||||||
|
},
|
||||||
|
"ingredient.itemIDs": {
|
||||||
|
"durabilityModifier": "dura",
|
||||||
|
"strengthRequirement": "strReq",
|
||||||
|
"dexterityRequirement": "dexReq",
|
||||||
|
"intelligenceRequirement": "intReq",
|
||||||
|
"defenceRequirement": "defReq",
|
||||||
|
"agilityRequirement": "agiReq",
|
||||||
|
"attackSpeedModifier": "atkSpdMod",
|
||||||
|
"powderSlotModifier": "slotMod"
|
||||||
|
},
|
||||||
|
"ingredient.consumableIDs": {
|
||||||
|
"duration": "dura",
|
||||||
|
"charges": "charges"
|
||||||
|
},
|
||||||
|
"ingredient.posMods": {
|
||||||
|
"left": "left",
|
||||||
|
"right": "right",
|
||||||
|
"above": "above",
|
||||||
|
"under": "under",
|
||||||
|
"touching": "touching",
|
||||||
|
"notTouching": "notTouching"
|
||||||
|
},
|
||||||
|
"item": {
|
||||||
|
"name": "displayName",
|
||||||
|
"internalName": "name",
|
||||||
|
"tier": "CAPS;tier",
|
||||||
|
"set": "set",
|
||||||
|
"powderSlots": "slots",
|
||||||
|
"type": "type",
|
||||||
|
"armorType": "armorType",
|
||||||
|
"material": "material",
|
||||||
|
"dropRestriction": "drop",
|
||||||
|
"dropMeta": "dropInfo",
|
||||||
|
"quest": "quest",
|
||||||
|
"restrictions": "restrict",
|
||||||
|
"accessoryType": "type",
|
||||||
|
"identified": "fixID",
|
||||||
|
"skin": "skin",
|
||||||
|
"category": "category",
|
||||||
|
"attackSpeed": "ALLCAPS;atkSpd",
|
||||||
|
"base": "UNWRAP;item.base",
|
||||||
|
"requirements": "UNWRAP;requirements",
|
||||||
|
"identifications": "UNWRAP;identifications"
|
||||||
|
},
|
||||||
|
"item.base": {
|
||||||
|
"damage": "STR_RANGE;nDam",
|
||||||
|
"fireDamage": "STR_RANGE;fDam",
|
||||||
|
"waterDamage": "STR_RANGE;wDam",
|
||||||
|
"airDamage": "STR_RANGE;aDam",
|
||||||
|
"thunderDamage": "STR_RANGE;tDam",
|
||||||
|
"earthDamage": "STR_RANGE;eDam",
|
||||||
|
"health": "hp",
|
||||||
|
"fireDefence": "fDef",
|
||||||
|
"waterDefence": "wDef",
|
||||||
|
"airDefence": "aDef",
|
||||||
|
"thunderDefence": "tDef",
|
||||||
|
"earthDefence": "eDef",
|
||||||
|
"averageDPS": "DELETE;"
|
||||||
|
},
|
||||||
|
"requirements": {
|
||||||
|
"level": "lvl",
|
||||||
|
"levelRange": "lvRange",
|
||||||
|
"classRequirement": "classReq",
|
||||||
|
"strength": "strReq",
|
||||||
|
"dexterity": "dexReq",
|
||||||
|
"intelligence": "intReq",
|
||||||
|
"agility": "agiReq",
|
||||||
|
"defence": "defReq"
|
||||||
|
},
|
||||||
|
"identifications": {
|
||||||
|
"healthRegen": "hprPct",
|
||||||
|
"manaRegen": "mr",
|
||||||
|
"spellDamage": "sdPct",
|
||||||
|
"elementalSpellDamage": "rSdPct",
|
||||||
|
"neutralSpellDamage": "nSdPct",
|
||||||
|
"fireSpellDamage": "fSdPct",
|
||||||
|
"waterSpellDamage": "wSdPct",
|
||||||
|
"airSpellDamage": "aSdPct",
|
||||||
|
"thunderSpellDamage": "tSdPct",
|
||||||
|
"earthSpellDamage": "eSdPct",
|
||||||
|
"mainAttackDamage": "mdPct",
|
||||||
|
"elementalMainAttackDamage": "rMdPct",
|
||||||
|
"neutralMainAttackDamage": "nMdPct",
|
||||||
|
"fireMainAttackDamage": "fMdPct",
|
||||||
|
"waterMainAttackDamage": "wMdPct",
|
||||||
|
"airMainAttackDamage": "aMdPct",
|
||||||
|
"thunderMainAttackDamage": "tMdPct",
|
||||||
|
"earthMainAttackDamage": "eMdPct",
|
||||||
|
"lifeSteal": "ls",
|
||||||
|
"manaSteal": "ms",
|
||||||
|
"xpBonus": "xpb",
|
||||||
|
"lootBonus": "lb",
|
||||||
|
"leveledXpBonus": "lxpb",
|
||||||
|
"leveledLootBonus": "llb",
|
||||||
|
"reflection": "ref",
|
||||||
|
"rawStrength": "str",
|
||||||
|
"rawDexterity": "dex",
|
||||||
|
"rawIntelligence": "int",
|
||||||
|
"rawDefence": "def",
|
||||||
|
"rawAgility": "agi",
|
||||||
|
"thorns": "thorns",
|
||||||
|
"poison": "poison",
|
||||||
|
"exploding": "expd",
|
||||||
|
"walkSpeed": "spd",
|
||||||
|
"rawAttackSpeed": "atkTier",
|
||||||
|
"rawHealth": "hpBonus",
|
||||||
|
"soulPointRegen": "spRegen",
|
||||||
|
"stealing": "eSteal",
|
||||||
|
"healthRegenRaw": "hprRaw",
|
||||||
|
"rawSpellDamage": "sdRaw",
|
||||||
|
"rawElementalSpellDamage": "rSdRaw",
|
||||||
|
"rawNeutralSpellDamage": "nSdRaw",
|
||||||
|
"rawFireSpellDamage": "fSdRaw",
|
||||||
|
"rawWaterSpellDamage": "wSdRaw",
|
||||||
|
"rawAirSpellDamage": "aSdRaw",
|
||||||
|
"rawThunderSpellDamage": "tSdRaw",
|
||||||
|
"rawEarthSpellDamage": "eSdRaw",
|
||||||
|
"rawMainAttackDamage": "mdRaw",
|
||||||
|
"rawElementalMainAttackDamage": "rMdRaw",
|
||||||
|
"rawNeutralMainAttackDamage": "nMdRaw",
|
||||||
|
"rawFireMainAttackDamage": "fMdRaw",
|
||||||
|
"rawWaterMainAttackDamage": "wMdRaw",
|
||||||
|
"rawAirMainAttackDamage": "aMdRaw",
|
||||||
|
"rawThunderMainAttackDamage": "tMdRaw",
|
||||||
|
"rawEarthMainAttackDamage": "eMdRaw",
|
||||||
|
"damage": "damPct",
|
||||||
|
"neutralDamage": "nDamPct",
|
||||||
|
"fireDamage": "fDamPct",
|
||||||
|
"waterDamage": "wDamPct",
|
||||||
|
"airDamage": "aDamPct",
|
||||||
|
"thunderDamage": "tDamPct",
|
||||||
|
"earthDamage": "eDamPct",
|
||||||
|
"elementalDamage": "rDamPct",
|
||||||
|
"rawDamage": "damRaw",
|
||||||
|
"rawNeutralDamage": "nDamRaw",
|
||||||
|
"rawFireDamage": "fDamRaw",
|
||||||
|
"rawWaterDamage": "wDamRaw",
|
||||||
|
"rawAirDamage": "aDamRaw",
|
||||||
|
"rawThunderDamage": "tDamRaw",
|
||||||
|
"rawEarthDamage": "eDamRaw",
|
||||||
|
"rawElementalDamage": "rDamRaw",
|
||||||
|
"fireDefence": "fDefPct",
|
||||||
|
"waterDefence": "wDefPct",
|
||||||
|
"airDefence": "aDefPct",
|
||||||
|
"thunderDefence": "tDefPct",
|
||||||
|
"earthDefence": "eDefPct",
|
||||||
|
"elementalDefence": "rDefPct",
|
||||||
|
|
||||||
|
"1stSpellCost": "spPct1",
|
||||||
|
"raw1stSpellCost": "spRaw1",
|
||||||
|
"2ndSpellCost": "spPct2",
|
||||||
|
"raw2ndSpellCost": "spRaw2",
|
||||||
|
"3rdSpellCost": "spPct3",
|
||||||
|
"raw3rdSpellCost": "spRaw3",
|
||||||
|
"4thSpellCost": "spPct4",
|
||||||
|
"raw4thSpellCost": "spRaw4",
|
||||||
|
|
||||||
|
"sprint": "sprint",
|
||||||
|
"sprintRegen": "sprintReg",
|
||||||
|
"jumpHeight": "jh",
|
||||||
|
"lootQuality": "lq",
|
||||||
|
|
||||||
|
"gatherXpBonus": "gXp",
|
||||||
|
"gatherSpeed": "gSpd",
|
||||||
|
|
||||||
|
"healingEfficiency": "healPct",
|
||||||
|
"knockback": "kb",
|
||||||
|
"weakenEnemy": "weakenEnemy",
|
||||||
|
"slowEnemy": "slowEnemy",
|
||||||
|
"elementalDefense": "rDefPct",
|
||||||
|
|
||||||
|
"damageFromMobs": "selfWeakPct"
|
||||||
|
}
|
||||||
|
}
|
230
py_script/v3_process_items.py
Normal file
230
py_script/v3_process_items.py
Normal file
|
@ -0,0 +1,230 @@
|
||||||
|
"""
|
||||||
|
Used to process the raw item data pulled from the API.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
- python process_items.py [infile] [outfile]
|
||||||
|
OR
|
||||||
|
- python process_items.py [infile and outfile]
|
||||||
|
|
||||||
|
|
||||||
|
NOTE: id_map.json is due for change. Should be updated manually when Wynn2.0/corresponding WB version drops.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import base64
|
||||||
|
import argparse
|
||||||
|
from items_common import translate_mappings
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description="Process raw pulled item data.")
|
||||||
|
parser.add_argument('infile', help='input file to read data from', default=None, nargs='?')
|
||||||
|
#parser.add_argument('outfile', help='output file to dump clean data into')
|
||||||
|
args = parser.parse_args()
|
||||||
|
if args.infile is None:
|
||||||
|
print("Grabbing json data from wynn api")
|
||||||
|
from item_wrapper import Items
|
||||||
|
api_data = Items().get_all_items()
|
||||||
|
json.dump(api_data, open('dump.json', 'w'))
|
||||||
|
else:
|
||||||
|
with open(args.infile, "r") as in_file:
|
||||||
|
api_data = json.load(in_file)
|
||||||
|
|
||||||
|
def translate_single_item(key, entry, name, directives, accumulate):
|
||||||
|
ret = entry
|
||||||
|
try:
|
||||||
|
if 'min' in entry and 'max' in entry:
|
||||||
|
if 'raw' in entry:
|
||||||
|
ret = entry['raw']
|
||||||
|
else:
|
||||||
|
ret = [entry['min'], entry['max']]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
while i < len(directives):
|
||||||
|
directive = directives[i]
|
||||||
|
if directive == 'DELETE':
|
||||||
|
ret = None
|
||||||
|
elif directive == 'CAPS':
|
||||||
|
ret = ret[0].upper() + ret[1:]
|
||||||
|
elif directive == 'ALLCAPS':
|
||||||
|
ret = ret.upper()
|
||||||
|
elif directive == 'STR_RANGE':
|
||||||
|
if 'min' in entry and 'max' in entry:
|
||||||
|
ret = f"{entry['min']}-{entry['max']}"
|
||||||
|
elif directive == 'UNWRAP':
|
||||||
|
recursive_translate(entry, accumulate, name, translate_single_item)
|
||||||
|
ret = None
|
||||||
|
i += 1
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def translate_single_ing(key, entry, name, directives, accumulate):
|
||||||
|
ret = entry
|
||||||
|
try:
|
||||||
|
if 'min' in entry and 'max' in entry:
|
||||||
|
ret = {
|
||||||
|
'minimum': entry['min'],
|
||||||
|
'maximum': entry['max']
|
||||||
|
}
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
while i < len(directives):
|
||||||
|
directive = directives[i]
|
||||||
|
if directive == 'DELETE':
|
||||||
|
ret = None
|
||||||
|
elif directive == 'UNWRAP':
|
||||||
|
recursive_translate(entry, accumulate, name, translate_single_ing)
|
||||||
|
ret = None
|
||||||
|
elif directive[:8] == 'RECURSE_':
|
||||||
|
ret = recursive_translate(entry, {}, directive[8:], translate_single_ing)
|
||||||
|
i += 1
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def recursive_translate(entry, result, path, translate_single):
|
||||||
|
mapping = translate_mappings[path]
|
||||||
|
|
||||||
|
for k, v in entry.items():
|
||||||
|
# Translate the item.
|
||||||
|
if k in mapping:
|
||||||
|
tmp = mapping[k].split(';')
|
||||||
|
directives, translated_name = tmp[:-1], tmp[-1]
|
||||||
|
res = translate_single(k, v, translated_name, directives, result)
|
||||||
|
if res is not None:
|
||||||
|
result[translated_name] = res
|
||||||
|
continue
|
||||||
|
|
||||||
|
# pass it through unchanged.
|
||||||
|
result[k] = v
|
||||||
|
return result
|
||||||
|
|
||||||
|
armor_types = ['helmet', 'chestplate', 'leggings', 'boots']
|
||||||
|
|
||||||
|
def translate_entry(entry):
|
||||||
|
"""
|
||||||
|
Convert an api entry into an appropriate parsed item.
|
||||||
|
|
||||||
|
Returns a pair: (converted, type)
|
||||||
|
where `type` is "item", "ingredient", "tome", "material", "charm", or None
|
||||||
|
and converted might be None if the conversion failed.
|
||||||
|
"""
|
||||||
|
# sketchily infer what kind of item we're dealing with, and translate it appropriately.
|
||||||
|
if "type" in entry:
|
||||||
|
# only items have this field.
|
||||||
|
res = recursive_translate(entry, {}, "item", translate_single_item)
|
||||||
|
if res['type'] in armor_types:
|
||||||
|
res['category'] = 'armor'
|
||||||
|
else:
|
||||||
|
res['category'] = 'weapon'
|
||||||
|
for element in 'netwfa':
|
||||||
|
damage_key = element + 'Dam'
|
||||||
|
if damage_key not in res:
|
||||||
|
res[damage_key] = '0-0'
|
||||||
|
return res, 'item'
|
||||||
|
if "accessoryType" in entry:
|
||||||
|
# only accessories have this field.
|
||||||
|
return recursive_translate(entry, {'category': 'accessory'}, "item", translate_single_item), "item"
|
||||||
|
if "itemOnlyIDs" in entry:
|
||||||
|
# only ingredients have this field.
|
||||||
|
res = recursive_translate(entry, {}, "ingredient", translate_single_ing)
|
||||||
|
return res, "ingredient"
|
||||||
|
#return recursive_translate(entry, {}, "ing"), "ingredient"
|
||||||
|
if "tomeType" in entry:
|
||||||
|
# only tomes have this field.
|
||||||
|
return None, "tome"
|
||||||
|
if "craftable" in entry:
|
||||||
|
return None, "material"
|
||||||
|
|
||||||
|
# I think the only things left are charms, we just don't classify them.
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
with open("id_map.json", "r") as id_map_file:
|
||||||
|
id_map = json.load(id_map_file)
|
||||||
|
used_ids = set([v for k, v in id_map.items()])
|
||||||
|
max_id = 0
|
||||||
|
with open("ing_map.json","r") as ing_map_file:
|
||||||
|
ing_map = json.load(ing_map_file)
|
||||||
|
|
||||||
|
items = []
|
||||||
|
ingreds = []
|
||||||
|
for name, entry in api_data.items():
|
||||||
|
entry['name'] = name
|
||||||
|
res, entry_type = translate_entry(entry)
|
||||||
|
print(f"Parsed {name}, type {entry_type}")
|
||||||
|
if res is None:
|
||||||
|
continue
|
||||||
|
# TODO: make this a map or smth less ugly code
|
||||||
|
if entry_type == 'item':
|
||||||
|
items.append(res)
|
||||||
|
elif entry_type == 'ingredient':
|
||||||
|
ingreds.append(res)
|
||||||
|
|
||||||
|
with open("../clean.json", "r") as oldfile:
|
||||||
|
old_data = json.load(oldfile)
|
||||||
|
old_items = old_data['items']
|
||||||
|
with open("../ingreds_clean.json", "r") as ingfile:
|
||||||
|
old_ingreds = json.load(ingfile)
|
||||||
|
|
||||||
|
known_item_names = set()
|
||||||
|
known_ingred_names = set()
|
||||||
|
for item in items:
|
||||||
|
known_item_names.add(item["name"])
|
||||||
|
for ingred in ingreds:
|
||||||
|
known_ingred_names.add(ingred["name"])
|
||||||
|
|
||||||
|
for item in old_items:
|
||||||
|
if item["name"] not in known_item_names:
|
||||||
|
print(f'Unknown old item: {item["name"]}!!!')
|
||||||
|
for ingred in old_ingreds:
|
||||||
|
if ingred["name"] not in known_ingred_names:
|
||||||
|
print(f'Unknown old ingred: {ingred["name"]}!!!')
|
||||||
|
|
||||||
|
# TODO hack pull the major id file
|
||||||
|
major_ids_filename = "../js/builder/major_ids_clean.json"
|
||||||
|
with open(major_ids_filename, 'r') as major_ids_file:
|
||||||
|
major_ids_map = json.load(major_ids_file)
|
||||||
|
major_ids_reverse_map = { v['displayName'] : k for k, v in major_ids_map.items() }
|
||||||
|
|
||||||
|
for item in items:
|
||||||
|
# HACKY ITEM FIXES!
|
||||||
|
if 'majorIds' in item:
|
||||||
|
item['majorIds'] = [ major_ids_reverse_map[item['majorIds']['name']] ]
|
||||||
|
|
||||||
|
if not (item["name"] in id_map):
|
||||||
|
while max_id in used_ids:
|
||||||
|
max_id += 1
|
||||||
|
used_ids.add(max_id)
|
||||||
|
id_map[item["name"]] = max_id
|
||||||
|
print(f'New item: {item["name"]} (id: {max_id})')
|
||||||
|
item["id"] = id_map[item["name"]]
|
||||||
|
|
||||||
|
for ingred in ingreds:
|
||||||
|
# HACKY ING FIXES!
|
||||||
|
ingred['itemIDs']['dura'] = int(ingred['itemIDs']['dura'] / 1000)
|
||||||
|
ingred['skills'] = [x.upper() for x in ingred['skills']]
|
||||||
|
|
||||||
|
if not (ingred["name"] in ing_map):
|
||||||
|
new_id = len(ing_map)
|
||||||
|
ing_map[ingred["name"]] = new_id
|
||||||
|
print(f'New item: {item["name"]} (id: {new_id})')
|
||||||
|
ingred["id"] = ing_map[ingred["name"]]
|
||||||
|
|
||||||
|
#write items back into data
|
||||||
|
old_data["items"] = items
|
||||||
|
|
||||||
|
#save id map
|
||||||
|
with open("id_map.json","w") as id_map_file:
|
||||||
|
json.dump(id_map, id_map_file, indent=2)
|
||||||
|
with open("ing_map.json","w") as ing_map_file:
|
||||||
|
json.dump(ing_map, ing_map_file, indent=2)
|
||||||
|
|
||||||
|
|
||||||
|
#write the data back to the outfile
|
||||||
|
with open('item_out.json', "w+") as out_file:
|
||||||
|
json.dump(old_data, out_file, ensure_ascii=False, separators=(',', ':'))
|
||||||
|
|
||||||
|
with open('ing_out.json', "w+") as out_file:
|
||||||
|
json.dump(ingreds, out_file, ensure_ascii=False, separators=(',', ':'))
|
||||||
|
|
Loading…
Reference in a new issue