KF3: Api additions and improvements.
This commit is contained in:
parent
12df873ead
commit
37225532c8
18
app.py
18
app.py
|
@ -1,12 +1,5 @@
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
from flask_restful import Api
|
from flask_restful import Api
|
||||||
|
|
||||||
from resources.KF3.friend import KF3_Friend
|
|
||||||
from resources.KF3.friends import KF3_Friends
|
|
||||||
from resources.Kingdom.friend import Kingdom_Friend
|
|
||||||
from resources.Kingdom.friends import Kingdom_Friends
|
|
||||||
from resources.Kingdom.item import Kingdom_Item
|
|
||||||
from resources.Kingdom.items import Kingdom_Items
|
|
||||||
from loaders.KF3.kf3db import KF3DB
|
from loaders.KF3.kf3db import KF3DB
|
||||||
from loaders.Kingdom.kingdomdb import KingdomDB
|
from loaders.Kingdom.kingdomdb import KingdomDB
|
||||||
|
|
||||||
|
@ -14,17 +7,10 @@ app = Flask(__name__)
|
||||||
app.config['JSON_AS_ASCII'] = False
|
app.config['JSON_AS_ASCII'] = False
|
||||||
app.databases = {}
|
app.databases = {}
|
||||||
|
|
||||||
KF3DB(app)
|
|
||||||
KingdomDB(app)
|
|
||||||
|
|
||||||
api = Api(app)
|
api = Api(app)
|
||||||
|
|
||||||
api.add_resource(KF3_Friend, "/KF3/Friend/<int:id>")
|
KF3DB(api)
|
||||||
api.add_resource(KF3_Friends, "/KF3/Friends")
|
KingdomDB(api)
|
||||||
api.add_resource(Kingdom_Friend, "/Kingdom/Friend/<int:id>")
|
|
||||||
api.add_resource(Kingdom_Friends, "/Kingdom/Friends")
|
|
||||||
api.add_resource(Kingdom_Item, "/Kingdom/Item/<int:id>")
|
|
||||||
api.add_resource(Kingdom_Items, "/Kingdom/Items")
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(host='127.0.0.1', port=8080, debug=True)
|
app.run(host='127.0.0.1', port=8080, debug=True)
|
|
@ -5,8 +5,9 @@ import json
|
||||||
|
|
||||||
class KF3_Friend(Resource):
|
class KF3_Friend(Resource):
|
||||||
def get(self, id:int):
|
def get(self, id:int):
|
||||||
|
db = app.databases["KF3"]
|
||||||
if "wiki" in request.args:
|
if "wiki" in request.args:
|
||||||
result = app.databases["KF3"].get_chara_wiki(id)
|
result = db.get_chara_wiki(id)
|
||||||
|
|
||||||
response = app.response_class(
|
response = app.response_class(
|
||||||
response=result,
|
response=result,
|
||||||
|
@ -14,8 +15,8 @@ class KF3_Friend(Resource):
|
||||||
mimetype='text/plain'
|
mimetype='text/plain'
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
result = app.databases["KF3"].get_chara(id)
|
result = db.get_chara(id)
|
||||||
result = json.dumps(result)
|
result = json.dumps(result, ensure_ascii=False, indent=1)
|
||||||
|
|
||||||
response = app.response_class(
|
response = app.response_class(
|
||||||
response=result,
|
response=result,
|
|
@ -1,15 +1,20 @@
|
||||||
import json
|
import json
|
||||||
from flask_restful import Resource
|
from flask_restful import Resource
|
||||||
from flask import current_app as app
|
from flask import current_app as app
|
||||||
|
from flask import request
|
||||||
|
|
||||||
class KF3_Friends(Resource):
|
class KF3_Friends(Resource):
|
||||||
def get(self):
|
def get(self):
|
||||||
db = app.databases["KF3"]
|
db = app.databases["KF3"]
|
||||||
result = []
|
result = []
|
||||||
for value in db.charaData.values():
|
for value in db.processed_friends.values():
|
||||||
result.append({"id": value["id"], "name": value["nameEn"]})
|
result.append({"id": value["id"], "name": value["nameEn"], "startTime" : value["startTime"], "startTimeRaw" : value["startTimeRaw"]})
|
||||||
|
|
||||||
result = sorted(result, key=lambda f: f["id"])
|
sort_arg = request.args["sort"] if "sort" in request.args and request.args["sort"] in result[0] else "id"
|
||||||
|
if sort_arg == "startTime":
|
||||||
|
sort_arg = "startTimeRaw"
|
||||||
|
|
||||||
|
result = sorted(result, key=lambda f: f[sort_arg])
|
||||||
|
|
||||||
response = app.response_class(
|
response = app.response_class(
|
||||||
response=json.dumps(result, ensure_ascii=False, indent=1),
|
response=json.dumps(result, ensure_ascii=False, indent=1),
|
|
@ -0,0 +1,27 @@
|
||||||
|
from flask_restful import Resource
|
||||||
|
from flask import current_app as app
|
||||||
|
from flask import request
|
||||||
|
import json
|
||||||
|
|
||||||
|
class KF3_Update(Resource):
|
||||||
|
def post(self):
|
||||||
|
db = app.databases["KF3"]
|
||||||
|
try:
|
||||||
|
db.reload_data()
|
||||||
|
response = app.response_class(
|
||||||
|
response="update successful",
|
||||||
|
status=200,
|
||||||
|
mimetype='text/plain'
|
||||||
|
)
|
||||||
|
except:
|
||||||
|
response = app.response_class(
|
||||||
|
response="update failed",
|
||||||
|
status=500,
|
||||||
|
mimetype='text/plain'
|
||||||
|
)
|
||||||
|
|
||||||
|
response.headers.add("Access-Control-Allow-Origin", "*")
|
||||||
|
return response
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
return self.post()
|
|
@ -1,44 +1,55 @@
|
||||||
import gzip
|
import gzip
|
||||||
import json
|
import json
|
||||||
|
import platform
|
||||||
import UnityPy
|
import UnityPy
|
||||||
from loaders.KF3.charaData import get_all_stats, fill_miracle_numbers
|
from datetime import datetime
|
||||||
|
from loaders.KF3.statCalculation import get_all_stats, fill_miracle_numbers
|
||||||
|
from endpoints.KF3.friend import KF3_Friend
|
||||||
|
from endpoints.KF3.friends import KF3_Friends
|
||||||
|
from endpoints.KF3.update import KF3_Update
|
||||||
|
|
||||||
class KF3DB:
|
class KF3DB:
|
||||||
processed_friends = {}
|
processed_friends = {}
|
||||||
paramAbilities = {}
|
|
||||||
paramAbilities1 = {}
|
|
||||||
paramAbilities2 = {}
|
|
||||||
paramAlphaBases = {}
|
|
||||||
paramArts = {}
|
|
||||||
paramSpecialAttacks = {}
|
|
||||||
paramWaitActions = {}
|
|
||||||
charaData = {}
|
|
||||||
promoteData = {}
|
|
||||||
promotePresetData = {}
|
|
||||||
charaClothesData = {}
|
|
||||||
limitlevel_rising_status = {}
|
|
||||||
|
|
||||||
def __init__(self, app) -> None:
|
def __init__(self, api) -> None:
|
||||||
|
app = api.app
|
||||||
if "KF3" in app.databases:
|
if "KF3" in app.databases:
|
||||||
del app.databases["KF3"]
|
del app.databases["KF3"]
|
||||||
|
|
||||||
self.parse_parameter()
|
self.reload_data()
|
||||||
|
|
||||||
with gzip.open("data/KF3/CHARA_DATA.d", mode="rt", encoding="utf-8") as file:
|
app.databases["KF3"] = self
|
||||||
|
api.add_resource(KF3_Friend, "/KF3/Friend/<int:id>")
|
||||||
|
api.add_resource(KF3_Friends, "/KF3/Friends")
|
||||||
|
api.add_resource(KF3_Update, "/KF3/Update")
|
||||||
|
|
||||||
|
def reload_data(self):
|
||||||
|
self.charaData = {}
|
||||||
|
self.promoteData = {}
|
||||||
|
self.promotePresetData = {}
|
||||||
|
self.charaClothesData = {}
|
||||||
|
self.limitlevel_rising_status = {}
|
||||||
|
|
||||||
|
if platform.system() == "Windows":
|
||||||
|
path = "H:\\Apache\\Katworks\\KF\\assets\\KF3\\mst\\"
|
||||||
|
else:
|
||||||
|
path = "/media/USB2/Apache/Katworks/KF/assets/KF3/mst//"
|
||||||
|
|
||||||
|
with gzip.open(path + "CHARA_DATA.d", mode="rt", encoding="utf-8") as file:
|
||||||
for entry in json.loads(file.read()):
|
for entry in json.loads(file.read()):
|
||||||
self.charaData[entry["id"]] = entry
|
self.charaData[entry["id"]] = entry
|
||||||
|
|
||||||
with gzip.open("data/KF3/CHARA_PROMOTE_DATA.d", mode="rt", encoding="utf-8") as file:
|
with gzip.open(path + "CHARA_PROMOTE_DATA.d", mode="rt", encoding="utf-8") as file:
|
||||||
for entry in json.loads(file.read()):
|
for entry in json.loads(file.read()):
|
||||||
self.promoteData[entry["promoteId"]] = entry
|
self.promoteData[entry["promoteId"]] = entry
|
||||||
|
|
||||||
with gzip.open("data/KF3/CHARA_PROMOTE_PRESET_DATA.d", mode="rt", encoding="utf-8") as file:
|
with gzip.open(path + "CHARA_PROMOTE_PRESET_DATA.d", mode="rt", encoding="utf-8") as file:
|
||||||
for entry in json.loads(file.read()):
|
for entry in json.loads(file.read()):
|
||||||
if entry["promotePresetId"] not in self.promotePresetData:
|
if entry["promotePresetId"] not in self.promotePresetData:
|
||||||
self.promotePresetData[entry["promotePresetId"]] = []
|
self.promotePresetData[entry["promotePresetId"]] = []
|
||||||
self.promotePresetData[entry["promotePresetId"]].append(entry)
|
self.promotePresetData[entry["promotePresetId"]].append(entry)
|
||||||
|
|
||||||
with gzip.open("data/KF3/CHARA_CLOTHES_DATA.d", mode="rt", encoding="utf-8") as file:
|
with gzip.open(path + "CHARA_CLOTHES_DATA.d", mode="rt", encoding="utf-8") as file:
|
||||||
for entry in json.loads(file.read()):
|
for entry in json.loads(file.read()):
|
||||||
if entry["clothesPresetId"] not in self.charaClothesData:
|
if entry["clothesPresetId"] not in self.charaClothesData:
|
||||||
self.charaClothesData[entry["clothesPresetId"]] = []
|
self.charaClothesData[entry["clothesPresetId"]] = []
|
||||||
|
@ -48,11 +59,24 @@ class KF3DB:
|
||||||
for entry in json.loads(file.read()):
|
for entry in json.loads(file.read()):
|
||||||
self.limitlevel_rising_status[entry["patternId"]] = entry
|
self.limitlevel_rising_status[entry["patternId"]] = entry
|
||||||
|
|
||||||
|
self.parse_parameter()
|
||||||
self.process_friends()
|
self.process_friends()
|
||||||
app.databases["KF3"] = self
|
|
||||||
|
|
||||||
def parse_parameter(self):
|
def parse_parameter(self):
|
||||||
paramAsset = UnityPy.load("data/KF3/assets/parameter.asset")
|
self.paramAbilities = {}
|
||||||
|
self.paramAbilities1 = {}
|
||||||
|
self.paramAbilities2 = {}
|
||||||
|
self.paramAlphaBases = {}
|
||||||
|
self.paramArts = {}
|
||||||
|
self.paramSpecialAttacks = {}
|
||||||
|
self.paramWaitActions = {}
|
||||||
|
|
||||||
|
if platform.system() == "Windows":
|
||||||
|
path = "H:\\Apache\\Katworks\\KF\\assets\\KF3\\assets\\"
|
||||||
|
else:
|
||||||
|
path = "/media/USB2/Apache/Katworks/KF/assets/KF3/assets//"
|
||||||
|
|
||||||
|
paramAsset = UnityPy.load(path + "parameter.asset")
|
||||||
for obj in paramAsset.objects:
|
for obj in paramAsset.objects:
|
||||||
data = obj.read()
|
data = obj.read()
|
||||||
if data.name.split('_')[0] == "ParamAbility":
|
if data.name.split('_')[0] == "ParamAbility":
|
||||||
|
@ -122,10 +146,18 @@ class KF3DB:
|
||||||
chara["promoteBonus"] = promote_bonus
|
chara["promoteBonus"] = promote_bonus
|
||||||
chara["costumeBonus"] = costume_bonus
|
chara["costumeBonus"] = costume_bonus
|
||||||
chara["attribute"] = charaData["attribute"]
|
chara["attribute"] = charaData["attribute"]
|
||||||
|
chara["name"] = charaData["name"]
|
||||||
chara["nameEn"] = charaData["nameEn"]
|
chara["nameEn"] = charaData["nameEn"]
|
||||||
|
chara["nickname"] = charaData["nickname"]
|
||||||
chara["rankLow"] = charaData["rankLow"]
|
chara["rankLow"] = charaData["rankLow"]
|
||||||
chara["rankHigh"] = charaData["rankHigh"]
|
chara["rankHigh"] = charaData["rankHigh"]
|
||||||
chara["castName"] = charaData["castName"]
|
chara["castName"] = charaData["castName"]
|
||||||
|
chara["loginText"] = charaData["loginText"]
|
||||||
|
chara["flavorText"] = charaData["flavorText"]
|
||||||
|
chara["kizunaupText"] = charaData["kizunaupText"]
|
||||||
|
chara["greetingText"] = charaData["greetingText"]
|
||||||
|
chara["startTimeRaw"] = charaData["startTime"]
|
||||||
|
chara["startTime"] = datetime.fromtimestamp(charaData["startTime"]/1000.0).strftime('%A, %B %d, %Y')
|
||||||
|
|
||||||
chara["wr"] = 4 if wrLocked else 5
|
chara["wr"] = 4 if wrLocked else 5
|
||||||
chara["is_wr5"] = chara["wr"] == 5
|
chara["is_wr5"] = chara["wr"] == 5
|
||||||
|
@ -158,6 +190,8 @@ class KF3DB:
|
||||||
chara["wait_action"] = self.paramWaitActions[id] if id in self.paramWaitActions else None
|
chara["wait_action"] = self.paramWaitActions[id] if id in self.paramWaitActions else None
|
||||||
chara["special_attack"] = self.paramSpecialAttacks[id] if id in self.paramSpecialAttacks else None
|
chara["special_attack"] = self.paramSpecialAttacks[id] if id in self.paramSpecialAttacks else None
|
||||||
|
|
||||||
|
chara["costumes"] = self.get_costumes(id, chara["rankLow"])
|
||||||
|
|
||||||
return chara
|
return chara
|
||||||
|
|
||||||
def get_chara(self, id : int):
|
def get_chara(self, id : int):
|
||||||
|
@ -168,6 +202,8 @@ class KF3DB:
|
||||||
|
|
||||||
def get_chara_wiki(self, id : int):
|
def get_chara_wiki(self, id : int):
|
||||||
chara = self.get_chara(id)
|
chara = self.get_chara(id)
|
||||||
|
if chara is None:
|
||||||
|
return None
|
||||||
|
|
||||||
lines = []
|
lines = []
|
||||||
|
|
||||||
|
@ -182,7 +218,7 @@ class KF3DB:
|
||||||
f"[[Category:{stars_word} Star KF3 Friends]]",
|
f"[[Category:{stars_word} Star KF3 Friends]]",
|
||||||
f"[[Category:Missing Content]]",
|
f"[[Category:Missing Content]]",
|
||||||
f"[[Category:Needs Audio]]",
|
f"[[Category:Needs Audio]]",
|
||||||
f"{{{{#vardefine:id|{str(chara['id'])}}}}}"
|
f"{{{{#vardefine:id|{str(chara['id']).zfill(4)}}}}}"
|
||||||
]
|
]
|
||||||
|
|
||||||
if chara['has_party_dress']:
|
if chara['has_party_dress']:
|
||||||
|
@ -200,7 +236,7 @@ class KF3DB:
|
||||||
lines.append(f"|apprarity={{{{KF3{chara['rankLow']}Star}}}}")
|
lines.append(f"|apprarity={{{{KF3{chara['rankLow']}Star}}}}")
|
||||||
lines.append(f"|seiyuu={chara['castName']}")
|
lines.append(f"|seiyuu={chara['castName']}")
|
||||||
lines.append(f"|attribute={attribute_word} {{{{KF3{attribute_word}}}}}")
|
lines.append(f"|attribute={attribute_word} {{{{KF3{attribute_word}}}}}")
|
||||||
lines.append(f"|implemented={0}")
|
lines.append(f"|implemented={chara['startTime']} (App)")
|
||||||
lines.append(f"|id={chara['id']}")
|
lines.append(f"|id={chara['id']}")
|
||||||
lines.append(f"|wr5={'Yes' if chara['is_wr5'] else 'No'}")
|
lines.append(f"|wr5={'Yes' if chara['is_wr5'] else 'No'}")
|
||||||
lines.append(f"|rainbowtrait={'Yes' if chara['has_rainbow_trait'] else 'No'}")
|
lines.append(f"|rainbowtrait={'Yes' if chara['has_rainbow_trait'] else 'No'}")
|
||||||
|
@ -226,6 +262,7 @@ class KF3DB:
|
||||||
lines.append(f"|maxbeat={chara['stats_max']['beat']}%")
|
lines.append(f"|maxbeat={chara['stats_max']['beat']}%")
|
||||||
lines.append(f"|maxaction={chara['stats_max']['act']}%")
|
lines.append(f"|maxaction={chara['stats_max']['act']}%")
|
||||||
lines.append(f"|maxtry={chara['stats_max']['try']}%")
|
lines.append(f"|maxtry={chara['stats_max']['try']}%")
|
||||||
|
lines.append("")
|
||||||
cards_str = "|flags="
|
cards_str = "|flags="
|
||||||
for card in chara["cards"]:
|
for card in chara["cards"]:
|
||||||
cards_str += " {{"
|
cards_str += " {{"
|
||||||
|
@ -271,6 +308,214 @@ class KF3DB:
|
||||||
else:
|
else:
|
||||||
lines.append(f"|rainbowtrait=N/A")
|
lines.append(f"|rainbowtrait=N/A")
|
||||||
lines.append(f"|rainbowtraitskill=Not Implemented.")
|
lines.append(f"|rainbowtraitskill=Not Implemented.")
|
||||||
|
|
||||||
|
lines.append("")
|
||||||
|
lines.append(f"|bondup={chara['kizunaupText']}")
|
||||||
|
lines.append(f"|profile={chara['flavorText']}")
|
||||||
|
lines.append(f"|greeting={chara['loginText']}")
|
||||||
|
lines.append(f"|selfintro={chara['greetingText']}")
|
||||||
|
lines.append(f"|enselfintro=")
|
||||||
|
|
||||||
|
cos_images = "|cos = " + ",".join([costume["image_name"] for costume in chara["costumes"]]) + ",end"
|
||||||
|
cos_obtain = "|cosobt = " + ",".join([costume["obtain"] for costume in chara["costumes"]])
|
||||||
|
cos_names = "|cosname = " + ",".join([costume["name"] for costume in chara["costumes"]])
|
||||||
|
|
||||||
|
lines.append("")
|
||||||
|
lines.append(cos_images)
|
||||||
|
lines.append(cos_names)
|
||||||
|
lines.append(cos_obtain)
|
||||||
|
|
||||||
lines.append("}}")
|
lines.append("}}")
|
||||||
|
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
def get_costumes(self, id : int, defaultRarity : int):
|
||||||
|
if id not in self.charaClothesData:
|
||||||
|
return []
|
||||||
|
|
||||||
|
output = []
|
||||||
|
data = self.charaClothesData[id]
|
||||||
|
for costume in data:
|
||||||
|
cos = {
|
||||||
|
"image_name" : f"icon dressup {costume['id']}.png",
|
||||||
|
"obtain" : "Limited"
|
||||||
|
}
|
||||||
|
cosId = costume['clothesId']
|
||||||
|
if cosId == 1:
|
||||||
|
cos["name"] = "Default"
|
||||||
|
cos["obtain"] = "Default"
|
||||||
|
|
||||||
|
elif cosId == 2:
|
||||||
|
cos["name"] = "Personal Fashion"
|
||||||
|
cos["obtain"] = f"Upgrade to {costume['getRank']} Stars" if defaultRarity < costume['getRank'] else "Default"
|
||||||
|
|
||||||
|
elif cosId == 3:
|
||||||
|
cos["name"] = "Tracksuit"
|
||||||
|
cos["obtain"] = f"Upgrade to {costume['getRank']} Stars" if defaultRarity < costume['getRank'] else "Default"
|
||||||
|
|
||||||
|
elif cosId == 4:
|
||||||
|
cos["name"] = "Park Staff"
|
||||||
|
cos["obtain"] = f"Upgrade to {costume['getRank']} Stars" if defaultRarity < costume['getRank'] else "Default"
|
||||||
|
|
||||||
|
elif cosId == 5:
|
||||||
|
cos["name"] = "Café Uniform"
|
||||||
|
cos["obtain"] = f"Upgrade to {costume['getRank']} Stars" if defaultRarity < costume['getRank'] else "Default"
|
||||||
|
|
||||||
|
elif cosId == 6:
|
||||||
|
cos["name"] = "Special Outfit 1"
|
||||||
|
|
||||||
|
elif cosId == 8:
|
||||||
|
cos["name"] = "Party Dress"
|
||||||
|
cos["obtain"] = "Increase Photo Pocket level to 12"
|
||||||
|
|
||||||
|
elif cosId == 9:
|
||||||
|
cos["name"] = "School Uniform"
|
||||||
|
|
||||||
|
elif cosId == 10:
|
||||||
|
cos["name"] = "Gym Clothes"
|
||||||
|
|
||||||
|
elif cosId == 11:
|
||||||
|
cos["name"] = "Raincoat"
|
||||||
|
|
||||||
|
elif cosId == 12:
|
||||||
|
cos["name"] = "Hanamaru Animal Swimsuit"
|
||||||
|
|
||||||
|
elif cosId == 13:
|
||||||
|
cos["name"] = "Cafe Uniform (Green)"
|
||||||
|
cos["obtain"] = "Dojo reward"
|
||||||
|
|
||||||
|
elif cosId == 14:
|
||||||
|
cos["name"] = "Cafe Uniform (Blue)"
|
||||||
|
cos["obtain"] = "Dojo reward"
|
||||||
|
|
||||||
|
elif cosId == 15:
|
||||||
|
cos["name"] = "Cafe Uniform (Pink)"
|
||||||
|
cos["obtain"] = "Dojo reward"
|
||||||
|
|
||||||
|
elif cosId == 16:
|
||||||
|
cos["name"] = "Orihime Costume"
|
||||||
|
|
||||||
|
elif cosId == 17:
|
||||||
|
cos["name"] = "Arle's Outfit"
|
||||||
|
|
||||||
|
elif cosId == 18:
|
||||||
|
cos["name"] = "Marine Nanoda! Swimsuit"
|
||||||
|
|
||||||
|
elif cosId == 19:
|
||||||
|
cos["name"] = "Batten Japari Dan Swimsuit"
|
||||||
|
|
||||||
|
elif cosId == 20:
|
||||||
|
cos["name"] = "Lifeguard Swimsuit"
|
||||||
|
|
||||||
|
elif cosId == 21:
|
||||||
|
cos["name"] = "Harvest Festival Outfit"
|
||||||
|
|
||||||
|
elif cosId == 22:
|
||||||
|
cos["name"] = "Halloween Costume"
|
||||||
|
|
||||||
|
elif cosId == 23:
|
||||||
|
cos["name"] = "Classic Maid Uniform"
|
||||||
|
|
||||||
|
elif cosId == 24:
|
||||||
|
cos["name"] = "Arle's Outfit"
|
||||||
|
|
||||||
|
elif cosId == 25:
|
||||||
|
cos["name"] = "Swimsuit"
|
||||||
|
|
||||||
|
elif cosId == 26:
|
||||||
|
cos["name"] = "Swimsuit"
|
||||||
|
|
||||||
|
elif cosId == 27:
|
||||||
|
cos["name"] = "Swimsuit"
|
||||||
|
|
||||||
|
elif cosId == 28:
|
||||||
|
cos["name"] = "Matching Clothes"
|
||||||
|
|
||||||
|
elif cosId == 29:
|
||||||
|
cos["name"] = "Frilly Frilly PPP Bikini"
|
||||||
|
|
||||||
|
elif cosId == 30:
|
||||||
|
cos["name"] = "Venus Flower Bikini"
|
||||||
|
|
||||||
|
elif cosId == 31:
|
||||||
|
cos["name"] = "Christmas Dress"
|
||||||
|
|
||||||
|
elif cosId == 32:
|
||||||
|
cos["name"] = "Chinese Shrine Maiden"
|
||||||
|
|
||||||
|
elif cosId == 33:
|
||||||
|
cos["name"] = "Chinese Dress"
|
||||||
|
|
||||||
|
elif cosId == 34:
|
||||||
|
cos["name"] = "Hanamaru Stage Costume"
|
||||||
|
|
||||||
|
elif cosId == 35:
|
||||||
|
cos["name"] = "Camo Outfit"
|
||||||
|
|
||||||
|
elif cosId == 36:
|
||||||
|
cos["name"] = "でびでび・ふりる"
|
||||||
|
|
||||||
|
elif cosId == 37:
|
||||||
|
cos["name"] = "夜に紛れし闇の衣"
|
||||||
|
|
||||||
|
elif cosId == 38:
|
||||||
|
cos["name"] = "Santa"
|
||||||
|
|
||||||
|
elif cosId == 39:
|
||||||
|
cos["name"] = "Fluffy Pajamas"
|
||||||
|
|
||||||
|
elif cosId == 40:
|
||||||
|
cos["name"] = "Japanese Armor"
|
||||||
|
|
||||||
|
elif cosId == 41:
|
||||||
|
cos["name"] = "Miko Outfit"
|
||||||
|
|
||||||
|
elif cosId == 42:
|
||||||
|
cos["name"] = "PPP Hoodie"
|
||||||
|
|
||||||
|
elif cosId == 43:
|
||||||
|
cos["name"] = "Blue Tracksuit"
|
||||||
|
|
||||||
|
elif cosId == 44:
|
||||||
|
cos["name"] = "Park Staff (beige)"
|
||||||
|
|
||||||
|
elif cosId == 45:
|
||||||
|
cos["name"] = "Sailor School Uniform"
|
||||||
|
|
||||||
|
elif cosId == 46:
|
||||||
|
cos["name"] = "Snow Knight Dress"
|
||||||
|
|
||||||
|
elif cosId == 47:
|
||||||
|
cos["name"] = "Sparkling Tree Dress"
|
||||||
|
|
||||||
|
elif cosId == 48:
|
||||||
|
cos["name"] = "Retro Detective"
|
||||||
|
|
||||||
|
elif cosId == 49:
|
||||||
|
cos["name"] = "Steampunk Detective"
|
||||||
|
|
||||||
|
elif cosId == 50:
|
||||||
|
cos["name"] = "鞠と花びらのはんなり和風服"
|
||||||
|
|
||||||
|
elif cosId == 51:
|
||||||
|
cos["name"] = "Numazu Deep Sea Aquarium Clothes"
|
||||||
|
|
||||||
|
elif cosId == 52:
|
||||||
|
cos["name"] = "たのしいことをお届け!"
|
||||||
|
|
||||||
|
elif cosId == 53:
|
||||||
|
cos["name"] = "かわいい勝負ですよ!ワンピース水着"
|
||||||
|
|
||||||
|
elif cosId == 54:
|
||||||
|
cos["name"] = "どきどき♡ずっきゅんビキニ"
|
||||||
|
|
||||||
|
elif cosId == 55:
|
||||||
|
cos["name"]= "のんほいパークの服"
|
||||||
|
|
||||||
|
else:
|
||||||
|
print(f"{costume['clothesId']}\t{costume['id']}\t{costume['name']}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
output.append(cos)
|
||||||
|
return output
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,31 @@ def calculate_stats(friend, awaken : int, level : int, trust_percent = 0, trustA
|
||||||
|
|
||||||
return stats
|
return stats
|
||||||
|
|
||||||
|
def get_stat_growth(friend, awaken : int):
|
||||||
|
stats_array = friend["attrScriptParam"]
|
||||||
|
max_awaken = friend["maxAwaken"]
|
||||||
|
|
||||||
|
awaken_step = max_awaken + 2
|
||||||
|
|
||||||
|
atk_ptr = 1 * awaken_step
|
||||||
|
satk_ptr = 2 * awaken_step
|
||||||
|
pdef_ptr = 3 * awaken_step
|
||||||
|
sdef_ptr = 4 * awaken_step
|
||||||
|
hp_ptr = 5 * awaken_step
|
||||||
|
speed_ptr = 6 * awaken_step
|
||||||
|
|
||||||
|
stats = {}
|
||||||
|
i = awaken
|
||||||
|
stats["patk"] += stats_array[atk_ptr + 1 + i]
|
||||||
|
stats["satk"] += stats_array[satk_ptr + 1 + i]
|
||||||
|
stats["pdef"] += stats_array[pdef_ptr + 1 + i]
|
||||||
|
stats["sdef"] += stats_array[sdef_ptr + 1 + i]
|
||||||
|
stats["hp"] += stats_array[hp_ptr + 1 + i]
|
||||||
|
stats["speed"] += stats_array[speed_ptr + 1 + i]
|
||||||
|
|
||||||
|
return stats
|
||||||
|
|
||||||
|
|
||||||
def clean_skill_string(input_string):
|
def clean_skill_string(input_string):
|
||||||
if input_string is None:
|
if input_string is None:
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -3,6 +3,11 @@ import platform
|
||||||
from loaders.Kingdom.numeric import numeric
|
from loaders.Kingdom.numeric import numeric
|
||||||
from loaders.Kingdom.kemono import clean_skill_string, calculate_stats, fill_miracle, get_awaken_materials, get_skill_materials
|
from loaders.Kingdom.kemono import clean_skill_string, calculate_stats, fill_miracle, get_awaken_materials, get_skill_materials
|
||||||
|
|
||||||
|
from endpoints.Kingdom.friend import Kingdom_Friend
|
||||||
|
from endpoints.Kingdom.friends import Kingdom_Friends
|
||||||
|
from endpoints.Kingdom.item import Kingdom_Item
|
||||||
|
from endpoints.Kingdom.items import Kingdom_Items
|
||||||
|
|
||||||
#element 1-orange 2-blue 3-green
|
#element 1-orange 2-blue 3-green
|
||||||
#showSkillType 1-control 2-guard 3-heal 4-support 5-assault 6-aoe
|
#showSkillType 1-control 2-guard 3-heal 4-support 5-assault 6-aoe
|
||||||
|
|
||||||
|
@ -10,7 +15,8 @@ class KingdomDB:
|
||||||
processed_friends = {}
|
processed_friends = {}
|
||||||
item_stages = {}
|
item_stages = {}
|
||||||
|
|
||||||
def __init__(self, app) -> None:
|
def __init__(self, api) -> None:
|
||||||
|
app = api.app
|
||||||
if "Kingdom" in app.databases:
|
if "Kingdom" in app.databases:
|
||||||
del app.databases["Kingdom"]
|
del app.databases["Kingdom"]
|
||||||
|
|
||||||
|
@ -45,6 +51,10 @@ class KingdomDB:
|
||||||
self.process_stages()
|
self.process_stages()
|
||||||
|
|
||||||
app.databases["Kingdom"] = self
|
app.databases["Kingdom"] = self
|
||||||
|
api.add_resource(Kingdom_Friend, "/Kingdom/Friend/<int:id>")
|
||||||
|
api.add_resource(Kingdom_Friends, "/Kingdom/Friends")
|
||||||
|
api.add_resource(Kingdom_Item, "/Kingdom/Item/<int:id>")
|
||||||
|
api.add_resource(Kingdom_Items, "/Kingdom/Items")
|
||||||
|
|
||||||
def process_friends(self):
|
def process_friends(self):
|
||||||
self.processed_friends = {}
|
self.processed_friends = {}
|
||||||
|
@ -87,11 +97,15 @@ class KingdomDB:
|
||||||
raise Exception()
|
raise Exception()
|
||||||
if bk_value["effectType1"] == 4:
|
if bk_value["effectType1"] == 4:
|
||||||
lb = self.kfk_en_kemono_WkPaDc.get(bk_value['effectParam1'][0] * 100)
|
lb = self.kfk_en_kemono_WkPaDc.get(bk_value['effectParam1'][0] * 100)
|
||||||
|
if lb is None:
|
||||||
|
lb = {"name": None, "describe": None}
|
||||||
limit_breaks.append({"name": lb["name"], "desc": clean_skill_string(lb["describe"])})
|
limit_breaks.append({"name": lb["name"], "desc": clean_skill_string(lb["describe"])})
|
||||||
|
|
||||||
habits = []
|
habits = []
|
||||||
for habit in friend["habitSn"]:
|
for habit in friend["habitSn"]:
|
||||||
hbt = self.kfk_en_kemono_WkPaDc.get(habit*100)
|
hbt = self.kfk_en_kemono_WkPaDc.get(habit*100)
|
||||||
|
if hbt is None:
|
||||||
|
hbt = {"name": None, "describe": None}
|
||||||
habits.append({"name":hbt["name"], "desc":hbt["describe"]})
|
habits.append({"name":hbt["name"], "desc":hbt["describe"]})
|
||||||
for i in range (3):
|
for i in range (3):
|
||||||
if len(habits) < i+1:
|
if len(habits) < i+1:
|
||||||
|
@ -103,6 +117,8 @@ class KingdomDB:
|
||||||
awaken_id = friend_id * 100 + i
|
awaken_id = friend_id * 100 + i
|
||||||
awaken = self.kfk_kemono_waken.get(awaken_id)
|
awaken = self.kfk_kemono_waken.get(awaken_id)
|
||||||
awaken1 = self.kfk_en_kemono_waken.get(awaken_id)
|
awaken1 = self.kfk_en_kemono_waken.get(awaken_id)
|
||||||
|
if awaken1 == None:
|
||||||
|
awaken1 = {"describe":"missing", "brilliance":"missing"}
|
||||||
if awaken != None and awaken1 != None:
|
if awaken != None and awaken1 != None:
|
||||||
awaken["en"] = awaken1
|
awaken["en"] = awaken1
|
||||||
awakens.append(awaken)
|
awakens.append(awaken)
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
import requests
|
|
||||||
from datetime import datetime
|
|
||||||
from flask_restful import Resource
|
|
||||||
from flask import jsonify, make_response
|
|
||||||
from resources.shared import API_URL, VALID_CURRENCIES_A, ERROR_CURRENCY_CODE, ERROR_DATE_FORMAT, ERROR_NO_DATA
|
|
||||||
|
|
||||||
class AverageRate(Resource):
|
|
||||||
def get(self, date : str, currency : str):
|
|
||||||
"""
|
|
||||||
Returns average exchange rate for the specified currency and date.
|
|
||||||
|
|
||||||
Weekends and holidays return code 404.
|
|
||||||
"""
|
|
||||||
if not currency.upper() in VALID_CURRENCIES_A:
|
|
||||||
return make_response(jsonify({"error": ERROR_CURRENCY_CODE}), 400)
|
|
||||||
|
|
||||||
try:
|
|
||||||
date_temp = datetime.strptime(date, "%Y-%m-%d")
|
|
||||||
|
|
||||||
if date_temp.weekday() in [5,6]:
|
|
||||||
return make_response(jsonify({"error": ERROR_NO_DATA}), 404)
|
|
||||||
|
|
||||||
#ensure correct date string format
|
|
||||||
date = date_temp.strftime("%Y-%m-%d")
|
|
||||||
except:
|
|
||||||
return make_response(jsonify({"error": ERROR_DATE_FORMAT}), 400)
|
|
||||||
|
|
||||||
url = f"{API_URL}/exchangerates/rates/a/{currency}/{date}/"
|
|
||||||
response = requests.get(url)
|
|
||||||
if response.status_code == 200:
|
|
||||||
data = response.json()
|
|
||||||
return make_response(jsonify({"mid": data["rates"][0]["mid"]}), 200)
|
|
||||||
elif response.status_code == 404:
|
|
||||||
return make_response(jsonify({"error": ERROR_NO_DATA}), 404)
|
|
||||||
else:
|
|
||||||
return make_response(jsonify({"error": response.text}), 400)
|
|
|
@ -1,34 +0,0 @@
|
||||||
import requests
|
|
||||||
from flask_restful import Resource
|
|
||||||
from flask import jsonify, make_response
|
|
||||||
from resources.shared import API_URL, ERROR_CURRENCY_CODE, ERROR_DATE_RANGE, VALID_CURRENCIES_C
|
|
||||||
|
|
||||||
class DifferenceLast(Resource):
|
|
||||||
def get(self, currency : str, num_days : int):
|
|
||||||
"""
|
|
||||||
Returns the highest difference between "ask" and "bid" values, and the day it occured.
|
|
||||||
|
|
||||||
Weekends and holidays are skipped and do not count towards the 'num_days' limit."
|
|
||||||
"""
|
|
||||||
if not currency.upper() in VALID_CURRENCIES_C:
|
|
||||||
return make_response(jsonify({"error": ERROR_CURRENCY_CODE}), 400)
|
|
||||||
|
|
||||||
if not (num_days > 0 and num_days < 256):
|
|
||||||
return make_response(jsonify({"error": ERROR_DATE_RANGE}), 400)
|
|
||||||
|
|
||||||
url = f"{API_URL}/exchangerates/rates/c/{currency}/last/{num_days}/"
|
|
||||||
response = requests.get(url)
|
|
||||||
if response.status_code == 200:
|
|
||||||
data = response.json()
|
|
||||||
result = {"diff_max": 0, "date":""}
|
|
||||||
for rate in data["rates"]:
|
|
||||||
#ensure correct precision
|
|
||||||
difference = round(rate["ask"] - rate["bid"],4)
|
|
||||||
#spread can be negative on rare occasions
|
|
||||||
if abs(difference) > abs(result["diff_max"]):
|
|
||||||
result["diff_max"] = difference
|
|
||||||
result["date"] = rate["effectiveDate"]
|
|
||||||
|
|
||||||
return make_response(jsonify(result), 200)
|
|
||||||
else:
|
|
||||||
return make_response(jsonify({"error": response.text}), 400)
|
|
|
@ -1,38 +0,0 @@
|
||||||
import requests
|
|
||||||
from flask_restful import Resource
|
|
||||||
from flask import jsonify, make_response
|
|
||||||
from resources.shared import API_URL, ERROR_CURRENCY_CODE, ERROR_DATE_RANGE, VALID_CURRENCIES_A
|
|
||||||
|
|
||||||
class MinMaxLast(Resource):
|
|
||||||
def get(self, currency : str, num_days : int):
|
|
||||||
"""
|
|
||||||
Returns minimum and maximum average exchange rate values, and the days they occured.
|
|
||||||
|
|
||||||
Weekends and holidays are skipped and do not count towards the 'num_days' limit."
|
|
||||||
"""
|
|
||||||
if not currency.upper() in VALID_CURRENCIES_A:
|
|
||||||
return make_response(jsonify({"error": ERROR_CURRENCY_CODE}), 400)
|
|
||||||
|
|
||||||
if not (num_days > 0 and num_days < 256):
|
|
||||||
return make_response(jsonify({"error": ERROR_DATE_RANGE}), 400)
|
|
||||||
|
|
||||||
url = f"{API_URL}/exchangerates/rates/a/{currency}/last/{num_days}/"
|
|
||||||
response = requests.get(url)
|
|
||||||
if response.status_code == 200:
|
|
||||||
data = response.json()
|
|
||||||
result = {"mid_min": data["rates"][0]["mid"], "date_min":"", "mid_max": data["rates"][0]["mid"], "date_max":""}
|
|
||||||
for rate in data["rates"]:
|
|
||||||
#if rates are equal, return the more recent one
|
|
||||||
#recent values are at the end of the list
|
|
||||||
|
|
||||||
if rate["mid"] >= result["mid_max"]:
|
|
||||||
result["mid_max"] = rate["mid"]
|
|
||||||
result["date_max"] = rate["effectiveDate"]
|
|
||||||
|
|
||||||
if rate["mid"] <= result["mid_min"]:
|
|
||||||
result["mid_min"] = rate["mid"]
|
|
||||||
result["date_min"] = rate["effectiveDate"]
|
|
||||||
|
|
||||||
return make_response(jsonify(result), 200)
|
|
||||||
else:
|
|
||||||
return make_response(jsonify({"error": response.text}), 400)
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Root url for the NBP API
|
|
||||||
API_URL = "https://api.nbp.pl/api/"
|
|
||||||
|
|
||||||
# List of currencies accepted by NBP as of 2023-04-21
|
|
||||||
# https://nbp.pl/en/statistic-and-financial-reporting/rates/table-a/
|
|
||||||
# https://nbp.pl/en/statistic-and-financial-reporting/rates/table-c/
|
|
||||||
VALID_CURRENCIES_A = ["AUD","THB","BRL","BGN","CAD","CLP","CZK","DKK","EUR","HUF","HKD","UAH","ISK","INR","MYR","MXN","ILS","NZD","NOK","PHP","GBP","ZAR","RON","IDR","SGD","SEK","CHF","TRY","USD","KRW","JPY","CNY","XDR" ]
|
|
||||||
VALID_CURRENCIES_C = ["AUD","CAD","CZK","DKK","EUR","HUF","NOK","GBP","SEK","CHF","USD","JPY","XDR"]
|
|
||||||
|
|
||||||
ERROR_CURRENCY_CODE = "Invalid currency code."
|
|
||||||
ERROR_DATE_FORMAT = "Incorrect date format, expected YYYY-MM-DD"
|
|
||||||
ERROR_DATE_RANGE = "Invalid currency code."
|
|
||||||
ERROR_NO_DATA = "Exchange rate data is not available for this date."
|
|
Loading…
Reference in New Issue