refactor
This commit is contained in:
parent
45a0f516ea
commit
b6862eb429
|
@ -1,2 +1,3 @@
|
||||||
__pycache__/
|
__pycache__/
|
||||||
data/
|
data/
|
||||||
|
test.py
|
||||||
|
|
20
README.md
20
README.md
|
@ -1,11 +1,11 @@
|
||||||
Currently active endpoints:
|
Currently active endpoints:
|
||||||
|
|
||||||
KF Kingdom:
|
KF Kingdom:
|
||||||
- katworks.sytes.net/KF/Api/Kingdom/Friends
|
- katworks.sytes.net/KF/Api/Kingdom/Friends
|
||||||
- katworks.sytes.net/KF/Api/Kingdom/Friend/{id}
|
- katworks.sytes.net/KF/Api/Kingdom/Friend/{id}
|
||||||
- katworks.sytes.net/KF/Api/Kingdom/Items
|
- katworks.sytes.net/KF/Api/Kingdom/Items
|
||||||
- katworks.sytes.net/KF/Api/Kingdom/Item/{id}
|
- katworks.sytes.net/KF/Api/Kingdom/Item/{id}
|
||||||
|
|
||||||
KF3:
|
KF3:
|
||||||
- katworks.sytes.net/KF/Api/KF3/Friends
|
- katworks.sytes.net/KF/Api/KF3/Friends
|
||||||
- katworks.sytes.net/KF/Api/KF3/Friend/{id}
|
- katworks.sytes.net/KF/Api/KF3/Friend/{id}
|
31
app.py
31
app.py
|
@ -1,16 +1,17 @@
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
from flask_restful import Api
|
from flask_restful import Api
|
||||||
from loaders.KF3.kf3db import KF3DB
|
|
||||||
from loaders.Kingdom.kingdomdb import KingdomDB
|
from modules.KF3.database import Database as KF3DB
|
||||||
|
from modules.Kingdom.database import Database as KFKDB
|
||||||
app = Flask(__name__)
|
|
||||||
app.config['JSON_AS_ASCII'] = False
|
app = Flask(__name__)
|
||||||
app.databases = {}
|
app.config['JSON_AS_ASCII'] = False
|
||||||
|
app.databases = {}
|
||||||
api = Api(app)
|
|
||||||
|
api = Api(app)
|
||||||
KF3DB(api)
|
|
||||||
KingdomDB(api)
|
KF3DB(api)
|
||||||
|
KFKDB(api)
|
||||||
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)
|
|
@ -0,0 +1,56 @@
|
||||||
|
[2024-01-23 17:41:58 +0100] [510920] [INFO] Starting gunicorn 21.2.0
|
||||||
|
[2024-01-23 17:41:58 +0100] [510920] [INFO] Listening at: http://127.0.0.1:8081 (510920)
|
||||||
|
[2024-01-23 17:41:58 +0100] [510920] [INFO] Using worker: sync
|
||||||
|
[2024-01-23 17:41:58 +0100] [510926] [INFO] Booting worker with pid: 510926
|
||||||
|
58 74870 純情色のワンピース
|
||||||
|
[2024-01-23 17:42:44 +0100] [510920] [INFO] Handling signal: int
|
||||||
|
[2024-01-23 17:42:44 +0100] [510926] [INFO] Worker exiting (pid: 510926)
|
||||||
|
[2024-01-23 17:42:45 +0100] [510920] [INFO] Shutting down: Master
|
||||||
|
[2024-01-23 17:43:05 +0100] [511070] [INFO] Starting gunicorn 21.2.0
|
||||||
|
[2024-01-23 17:43:05 +0100] [511070] [INFO] Listening at: http://127.0.0.1:8081 (511070)
|
||||||
|
[2024-01-23 17:43:05 +0100] [511070] [INFO] Using worker: sync
|
||||||
|
[2024-01-23 17:43:05 +0100] [511071] [INFO] Booting worker with pid: 511071
|
||||||
|
58 74870 純情色のワンピース
|
||||||
|
[2024-01-23 17:44:06 +0100] [511070] [INFO] Handling signal: int
|
||||||
|
[2024-01-23 17:44:07 +0100] [511071] [INFO] Worker exiting (pid: 511071)
|
||||||
|
[2024-01-23 17:44:08 +0100] [511070] [INFO] Shutting down: Master
|
||||||
|
[2024-01-23 17:52:24 +0100] [511446] [INFO] Starting gunicorn 21.2.0
|
||||||
|
[2024-01-23 17:52:24 +0100] [511446] [INFO] Listening at: http://127.0.0.1:8081 (511446)
|
||||||
|
[2024-01-23 17:52:24 +0100] [511446] [INFO] Using worker: sync
|
||||||
|
[2024-01-23 17:52:24 +0100] [511447] [INFO] Booting worker with pid: 511447
|
||||||
|
58 74870 純情色のワンピース
|
||||||
|
[2024-01-23 17:53:01,255] ERROR in app: Exception on /KF3/Update [GET]
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "/home/pi/python/env/lib/python3.11/site-packages/flask/app.py", line 867, in full_dispatch_request
|
||||||
|
rv = self.dispatch_request()
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
File "/home/pi/python/env/lib/python3.11/site-packages/flask/app.py", line 852, in dispatch_request
|
||||||
|
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
File "/home/pi/python/env/lib/python3.11/site-packages/flask_restful/__init__.py", line 493, in wrapper
|
||||||
|
return self.make_response(data, code, headers=headers)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
File "/home/pi/python/env/lib/python3.11/site-packages/flask_restful/__init__.py", line 522, in make_response
|
||||||
|
resp = self.representations[mediatype](data, *args, **kwargs)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
File "/home/pi/python/env/lib/python3.11/site-packages/flask_restful/representations/json.py", line 21, in output_json
|
||||||
|
dumped = dumps(data, **settings) + "\n"
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
File "/usr/lib/python3.11/json/__init__.py", line 231, in dumps
|
||||||
|
return _default_encoder.encode(obj)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
File "/usr/lib/python3.11/json/encoder.py", line 200, in encode
|
||||||
|
chunks = self.iterencode(o, _one_shot=True)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
File "/usr/lib/python3.11/json/encoder.py", line 258, in iterencode
|
||||||
|
return _iterencode(o, 0)
|
||||||
|
^^^^^^^^^^^^^^^^^
|
||||||
|
File "/usr/lib/python3.11/json/encoder.py", line 180, in default
|
||||||
|
raise TypeError(f'Object of type {o.__class__.__name__} '
|
||||||
|
TypeError: Object of type coroutine is not JSON serializable
|
||||||
|
/home/pi/python/env/lib/python3.11/site-packages/flask/app.py:869: RuntimeWarning: coroutine 'KF3_Update.post' was never awaited
|
||||||
|
rv = self.handle_user_exception(e)
|
||||||
|
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
|
||||||
|
[2024-01-23 17:59:01 +0100] [511446] [INFO] Handling signal: int
|
||||||
|
[2024-01-23 17:59:01 +0100] [511447] [INFO] Worker exiting (pid: 511447)
|
||||||
|
[2024-01-23 17:59:02 +0100] [511446] [INFO] Shutting down: Master
|
|
@ -0,0 +1,6 @@
|
||||||
|
127.0.0.1 - - [23/Jan/2024:17:43:29 +0100] "GET /KF3/Update HTTP/1.0" 200 42 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 OPR/106.0.0.0"
|
||||||
|
127.0.0.1 - - [23/Jan/2024:17:43:40 +0100] "GET /KF3/Update HTTP/1.0" 200 42 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 OPR/106.0.0.0"
|
||||||
|
127.0.0.1 - - [23/Jan/2024:17:43:41 +0100] "GET /KF3/Update HTTP/1.0" 200 42 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 OPR/106.0.0.0"
|
||||||
|
127.0.0.1 - - [23/Jan/2024:17:43:42 +0100] "GET /KF3/Update HTTP/1.0" 200 42 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 OPR/106.0.0.0"
|
||||||
|
127.0.0.1 - - [23/Jan/2024:17:44:01 +0100] "GET /KF3/Update HTTP/1.0" 200 42 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 OPR/106.0.0.0"
|
||||||
|
127.0.0.1 - - [23/Jan/2024:17:53:01 +0100] "GET /KF3/Update HTTP/1.0" 500 37 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 OPR/106.0.0.0"
|
|
@ -1,10 +1,13 @@
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
|
|
||||||
workers = multiprocessing.cpu_count() # * 2 + 1
|
workers = 1 # multiprocessing.cpu_count() # * 2 + 1
|
||||||
bind = 'unix:flaskrest.sock'
|
bind = 'unix:flaskrest.sock'
|
||||||
umask = 0o007
|
umask = 0o007
|
||||||
reload = False
|
reload = False
|
||||||
|
|
||||||
#logging
|
#logging
|
||||||
accesslog = '-'
|
accesslog = '-'
|
||||||
errorlog = '-'
|
errorlog = '-'
|
||||||
|
# accesslog = 'gunicorn.log'
|
||||||
|
# errorlog = 'gunicorn.error.log'
|
||||||
|
# capture_output = True
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,213 @@
|
||||||
|
|
||||||
|
import base64
|
||||||
|
import os
|
||||||
|
import gzip
|
||||||
|
import json
|
||||||
|
import asyncio
|
||||||
|
import hashlib
|
||||||
|
import platform
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
|
from UnityPy import enums
|
||||||
|
|
||||||
|
from ..Shared.utility import divide_chunks
|
||||||
|
from ..Shared.downloading import download_bytes, download_text
|
||||||
|
from ..Shared.convert import convert, extract
|
||||||
|
|
||||||
|
servers = [
|
||||||
|
"https://parade-mobile-stg-app.kemono-friends-3.jp/",
|
||||||
|
"https://parade-mobile-develop01-app.kemono-friends-3.jp/",
|
||||||
|
#"https://parade-mobile-develop02-app.kemono-friends-3.jp/paradesv/",
|
||||||
|
#"https://parade-mobile-develop03-app.kemono-friends-3.jp/paradesv/",
|
||||||
|
#"https://parade-mobile-develop04-app.kemono-friends-3.jp/paradesv/",
|
||||||
|
]
|
||||||
|
|
||||||
|
def decode(data):
|
||||||
|
# cut off the md5 checksum at the end and the four bytes at the start
|
||||||
|
hash = bytearray.fromhex(data[:-(2*16)][2*4:])
|
||||||
|
key = hashlib.md5(bytearray.fromhex(data[:2*4])).digest() # md5 the key
|
||||||
|
# xor with the key
|
||||||
|
for i in range(0, len(hash)):
|
||||||
|
hash[i] = hash[i] ^ key[i % (len(key))]
|
||||||
|
return hash.decode("utf-8")
|
||||||
|
|
||||||
|
def encode(text):
|
||||||
|
hashed = hashlib.md5(text.encode()).digest()
|
||||||
|
checksum = hashlib.md5((text + "DARAPAB ").encode()).digest()
|
||||||
|
key = hashlib.md5(hashed[:4]).digest() # md5 the key
|
||||||
|
# xor the data with the key
|
||||||
|
text = bytearray(text.encode())
|
||||||
|
for i in range(0, len(text)):
|
||||||
|
text[i] = text[i] ^ key[i % (len(key))]
|
||||||
|
return hashed[:4].hex() + text.hex() + checksum.hex()
|
||||||
|
|
||||||
|
async def download_cache(server_name, server : str):
|
||||||
|
session = aiohttp.ClientSession()
|
||||||
|
downloaded_files = []
|
||||||
|
|
||||||
|
if platform.system() == "Windows":
|
||||||
|
path = f"D:\\Codebase\\KFKDecrypt\\assets\\KF3\\{server_name}\\cache\\"
|
||||||
|
else:
|
||||||
|
path = f"/var/www/html/Katworks/KF/assets/KF3/{server_name}/cache/"
|
||||||
|
|
||||||
|
os.makedirs(path, exist_ok=True)
|
||||||
|
|
||||||
|
new_mst_ver = {}
|
||||||
|
old_mst_ver = {}
|
||||||
|
file_path_mst = path + "mstVersion.txt"
|
||||||
|
if os.path.exists(file_path_mst):
|
||||||
|
with open(file_path_mst, "rt", encoding="utf-8") as file:
|
||||||
|
old_mst_ver = dict([(entry["type"], entry["version"]) for entry in json.load(file)])
|
||||||
|
|
||||||
|
param = encode(json.dumps({'dmm_viewer_id':0}))
|
||||||
|
request = await download_bytes(server + "paradesv/common/MstVersion.do?param=" + param, session)
|
||||||
|
result = gzip.decompress(request)
|
||||||
|
new_mst = json.loads(result)
|
||||||
|
new_mst_ver = dict([(entry["type"], entry["version"]) for entry in new_mst["mst_ver"]])
|
||||||
|
|
||||||
|
for key in new_mst_ver:
|
||||||
|
file_path_gzip = path + key + ".d"
|
||||||
|
file_path_json = path + key + ".json"
|
||||||
|
if os.path.exists(file_path_gzip) and os.path.exists(file_path_json) and key in old_mst_ver:
|
||||||
|
if new_mst_ver[key] == old_mst_ver[key]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
downloaded_files.append(key)
|
||||||
|
param = encode(json.dumps({'type':key, 'dmm_viewer_id':0}))
|
||||||
|
request = await download_bytes(server + "paradesv/common/MstData.do?param=" + param, session)
|
||||||
|
result = gzip.decompress(request)
|
||||||
|
response = json.loads(result)
|
||||||
|
data = base64.b64decode(response["data"])
|
||||||
|
with open(file_path_gzip, "wb") as file:
|
||||||
|
file.write(data)
|
||||||
|
with open(file_path_json, "wt", encoding="utf-8") as out_file:
|
||||||
|
data = gzip.decompress(data)
|
||||||
|
json.dump(json.loads(data), out_file, ensure_ascii=False, indent=1)
|
||||||
|
|
||||||
|
old_mst_ver[key] = new_mst_ver[key]
|
||||||
|
|
||||||
|
with open(file_path_mst, "wt", encoding="utf-8") as file:
|
||||||
|
new_json = [{"type":type, "version":version} for type, version in zip(old_mst_ver.keys(), old_mst_ver.values())]
|
||||||
|
json.dump(new_json, file, ensure_ascii=False)
|
||||||
|
|
||||||
|
await session.close()
|
||||||
|
return downloaded_files
|
||||||
|
|
||||||
|
async def download_files(server_name, asset_bundle_url, srv_platform : str):
|
||||||
|
def parse_ab_list(filecontent : str):
|
||||||
|
out = {}
|
||||||
|
lines = filecontent.replace("\r\n", "\n").split('\n')
|
||||||
|
for line in lines:
|
||||||
|
split = line.split('\t')
|
||||||
|
if len(split) > 1:
|
||||||
|
out[split[0]] = split[-2]
|
||||||
|
return out
|
||||||
|
|
||||||
|
async def download_file(url_assets : str, file_name : str, download_path : str, session : aiohttp.ClientSession):
|
||||||
|
data = await download_bytes(url_assets + file_name, session)
|
||||||
|
if data != None:
|
||||||
|
with open(download_path + file_name, "wb") as file:
|
||||||
|
file.write(data)
|
||||||
|
if server_name == "develop01":
|
||||||
|
convert_path = f"/var/www/html/Katworks/KF/assets/KF3/WebGL/assets/" + file_name
|
||||||
|
extract_path = f"/var/www/html/Katworks/KF/assets/KF3/extracted/"
|
||||||
|
try:
|
||||||
|
convert(data, convert_path, enums.BuildTarget.WebGL, True)
|
||||||
|
except:
|
||||||
|
with open(convert_path, "wb") as file:
|
||||||
|
file.write(data)
|
||||||
|
if file_name.endswith(".png"):
|
||||||
|
extract(data, extract_path)
|
||||||
|
|
||||||
|
session = aiohttp.ClientSession()
|
||||||
|
path = f"/var/www/html/Katworks/KF/assets/KF3/{server_name}/assets/{srv_platform}/"
|
||||||
|
|
||||||
|
os.makedirs(path, exist_ok=True)
|
||||||
|
|
||||||
|
files_to_download = []
|
||||||
|
url_base = asset_bundle_url + "/" + srv_platform + "/1.0.0/ja/"
|
||||||
|
url_list = url_base + "ab_list.txt"
|
||||||
|
url_env = url_base + "ab_env.txt"
|
||||||
|
url_assets = url_base + "assets/"
|
||||||
|
|
||||||
|
file_path_env = path + "ab_env.txt"
|
||||||
|
file_path_list = path + "ab_list.txt"
|
||||||
|
old_ab_env = ""
|
||||||
|
|
||||||
|
if os.path.exists(file_path_env):
|
||||||
|
with open(file_path_env, "rt") as file:
|
||||||
|
old_ab_env = file.read()
|
||||||
|
|
||||||
|
new_ab_env = await download_text(url_env, session)
|
||||||
|
|
||||||
|
if new_ab_env != old_ab_env:
|
||||||
|
old_ab_list = {}
|
||||||
|
if os.path.exists(file_path_list):
|
||||||
|
with open(file_path_list, "rt") as file:
|
||||||
|
old_ab_list = parse_ab_list(file.read())
|
||||||
|
|
||||||
|
new_ab_list_file = await download_text(url_list, session)
|
||||||
|
new_ab_list = parse_ab_list(new_ab_list_file)
|
||||||
|
|
||||||
|
for key in new_ab_list:
|
||||||
|
file_path = path + key
|
||||||
|
if os.path.exists(file_path) and key in old_ab_list:
|
||||||
|
if new_ab_list[key] == old_ab_list[key]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
files_to_download.append(key)
|
||||||
|
|
||||||
|
chunked_files_to_download = list(divide_chunks(files_to_download, 5))
|
||||||
|
|
||||||
|
for chunk in chunked_files_to_download:
|
||||||
|
tasks = [asyncio.create_task(download_file(url_assets, file, path, session)) for file in chunk]
|
||||||
|
await asyncio.wait(tasks)
|
||||||
|
print(chunk)
|
||||||
|
print()
|
||||||
|
|
||||||
|
with open(file_path_env, "wt", encoding="utf-8") as file:
|
||||||
|
file.write(new_ab_env)
|
||||||
|
with open(file_path_list, "wt", encoding="utf-8") as file:
|
||||||
|
file.write(new_ab_list_file)
|
||||||
|
|
||||||
|
await session.close()
|
||||||
|
return files_to_download
|
||||||
|
|
||||||
|
async def manual():
|
||||||
|
downloaded_cache = {}
|
||||||
|
downloaded_files = {}
|
||||||
|
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
param = encode(json.dumps({"version":"1.0.0","dmm_viewer_id":0,"platform":1}))
|
||||||
|
request = await download_bytes(servers[0] + "paradesv/common/GetUrl.do?param=" + param, session)
|
||||||
|
result = gzip.decompress(request)
|
||||||
|
response = json.loads(result)
|
||||||
|
asset_bundle_url = response["asset_bundle_url"]
|
||||||
|
urlName = asset_bundle_url.split("-")[2]
|
||||||
|
|
||||||
|
print("downloading from", servers[0])
|
||||||
|
downloaded_cache = await download_cache(urlName, servers[0])
|
||||||
|
downloaded_files = await download_files(urlName, asset_bundle_url, "Windows")
|
||||||
|
|
||||||
|
if downloaded_cache != [] and downloaded_cache != None:
|
||||||
|
with open("/var/www/html/Katworks/KF/assets/KF3/lastUpdate_prod_cache.json", "wt", encoding="utf-8") as file:
|
||||||
|
json.dump(downloaded_cache, file, ensure_ascii=False, indent=1)
|
||||||
|
if downloaded_files != [] and downloaded_files != None:
|
||||||
|
with open("/var/www/html/Katworks/KF/assets/KF3/lastUpdate_prod_files.json", "wt", encoding="utf-8") as file:
|
||||||
|
json.dump(downloaded_files, file, ensure_ascii=False, indent=1)
|
||||||
|
|
||||||
|
print("downloading from", servers[1])
|
||||||
|
asset_bundle_url = "https://parade-mobile-develop01-app.kemono-friends-3.jp/AssetBundles/0.0.0/latest"
|
||||||
|
urlName = asset_bundle_url.split("-")[2]
|
||||||
|
downloaded_cache = await download_cache(urlName, servers[1])
|
||||||
|
downloaded_files = await download_files(urlName, asset_bundle_url, "Windows")
|
||||||
|
|
||||||
|
if downloaded_cache != [] and downloaded_cache != None:
|
||||||
|
with open("/var/www/html/Katworks/KF/assets/KF3/lastUpdate_dev_cache.json", "wt", encoding="utf-8") as file:
|
||||||
|
json.dump(downloaded_cache, file, ensure_ascii=False, indent=1)
|
||||||
|
if downloaded_files != [] and downloaded_files != None:
|
||||||
|
with open("/var/www/html/Katworks/KF/assets/KF3/lastUpdate_dev_files.json", "wt", encoding="utf-8") as file:
|
||||||
|
json.dump(downloaded_files, file, ensure_ascii=False, indent=1)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(manual())
|
|
@ -1,28 +1,30 @@
|
||||||
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
|
from flask import request
|
||||||
import json
|
import json
|
||||||
|
|
||||||
class KF3_Friend(Resource):
|
class KF3_Friend(Resource):
|
||||||
def get(self, id:int):
|
def get(self, id:int):
|
||||||
db = app.databases["KF3"]
|
from KF3.database import Database
|
||||||
if "wiki" in request.args:
|
db : Database = app.databases["KF3"]
|
||||||
result = db.get_chara_wiki(id)
|
|
||||||
|
if "wiki" in request.args:
|
||||||
response = app.response_class(
|
result = db.get_chara_wiki(id)
|
||||||
response=result,
|
|
||||||
status=200,
|
response = app.response_class(
|
||||||
mimetype='text/plain'
|
response=result,
|
||||||
)
|
status=200,
|
||||||
else:
|
mimetype='text/plain'
|
||||||
result = db.get_chara(id)
|
)
|
||||||
result = json.dumps(result, ensure_ascii=False, indent=1)
|
else:
|
||||||
|
result = db.get_chara(id)
|
||||||
response = app.response_class(
|
result = json.dumps(result, ensure_ascii=False, indent=1)
|
||||||
response=result,
|
|
||||||
status=200,
|
response = app.response_class(
|
||||||
mimetype='application/json'
|
response=result,
|
||||||
)
|
status=200,
|
||||||
|
mimetype='application/json'
|
||||||
response.headers.add("Access-Control-Allow-Origin", "*")
|
)
|
||||||
|
|
||||||
|
response.headers.add("Access-Control-Allow-Origin", "*")
|
||||||
return response
|
return response
|
|
@ -1,26 +1,28 @@
|
||||||
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
|
from flask import request
|
||||||
|
|
||||||
class KF3_Friends(Resource):
|
class KF3_Friends(Resource):
|
||||||
def get(self):
|
def get(self):
|
||||||
db = app.databases["KF3"]
|
from KF3.database import Database
|
||||||
result = []
|
db : Database = app.databases["KF3"]
|
||||||
for value in db.processed_friends.values():
|
|
||||||
result.append({"id": value["id"], "name": value["nameEn"], "startTime" : value["startTime"], "startTimeRaw" : value["startTimeRaw"]})
|
result = []
|
||||||
|
for value in db.processed_friends.values():
|
||||||
sort_arg = request.args["sort"] if "sort" in request.args and request.args["sort"] in result[0] else "id"
|
result.append({"id": value["id"], "name": value["nameEn"], "startTime" : value["startTime"], "startTimeRaw" : value["startTimeRaw"]})
|
||||||
if sort_arg == "startTime":
|
|
||||||
sort_arg = "startTimeRaw"
|
sort_arg = request.args["sort"] if "sort" in request.args and request.args["sort"] in result[0] else "id"
|
||||||
|
if sort_arg == "startTime":
|
||||||
result = sorted(result, key=lambda f: f[sort_arg])
|
sort_arg = "startTimeRaw"
|
||||||
|
|
||||||
response = app.response_class(
|
result = sorted(result, key=lambda f: f[sort_arg])
|
||||||
response=json.dumps(result, ensure_ascii=False, indent=1),
|
|
||||||
status=200,
|
response = app.response_class(
|
||||||
mimetype='application/json'
|
response=json.dumps(result, ensure_ascii=False, indent=1),
|
||||||
)
|
status=200,
|
||||||
response.headers.add("Access-Control-Allow-Origin", "*")
|
mimetype='application/json'
|
||||||
|
)
|
||||||
|
response.headers.add("Access-Control-Allow-Origin", "*")
|
||||||
|
|
||||||
return response
|
return response
|
|
@ -0,0 +1,21 @@
|
||||||
|
from flask_restful import Resource
|
||||||
|
from flask import current_app as app
|
||||||
|
from flask import request_tearing_down
|
||||||
|
import json
|
||||||
|
|
||||||
|
class KF3_Item(Resource):
|
||||||
|
def get(self, id:int):
|
||||||
|
from KF3.database import Database
|
||||||
|
db : Database = app.databases["KF3"]
|
||||||
|
|
||||||
|
result = db.get_item(id)
|
||||||
|
result = json.dumps(result, ensure_ascii=False, indent=1)
|
||||||
|
|
||||||
|
response = app.response_class(
|
||||||
|
response=result,
|
||||||
|
status=200,
|
||||||
|
mimetype='application/json'
|
||||||
|
)
|
||||||
|
|
||||||
|
response.headers.add("Access-Control-Allow-Origin", "*")
|
||||||
|
return response
|
|
@ -0,0 +1,21 @@
|
||||||
|
import json
|
||||||
|
from flask_restful import Resource
|
||||||
|
from flask import current_app as app
|
||||||
|
|
||||||
|
class KF3_Items(Resource):
|
||||||
|
def get(self):
|
||||||
|
from KF3.database import Database
|
||||||
|
db : Database = app.databases["KF3"]
|
||||||
|
|
||||||
|
result = []
|
||||||
|
for value in db.itemCommon.values():
|
||||||
|
result.append({"id": value["id"], "name": value["name"]})
|
||||||
|
|
||||||
|
response = app.response_class(
|
||||||
|
response=json.dumps(result, ensure_ascii=False, indent=1),
|
||||||
|
status=200,
|
||||||
|
mimetype='application/json'
|
||||||
|
)
|
||||||
|
response.headers.add("Access-Control-Allow-Origin", "*")
|
||||||
|
|
||||||
|
return response
|
|
@ -0,0 +1,36 @@
|
||||||
|
import asyncio
|
||||||
|
from flask_restful import Resource
|
||||||
|
from flask import current_app as app
|
||||||
|
from ..downloader import manual
|
||||||
|
|
||||||
|
class KF3_Update(Resource):
|
||||||
|
def post(self):
|
||||||
|
from ..database import Database
|
||||||
|
db : Database = app.databases["KF3"]
|
||||||
|
|
||||||
|
if db.update_in_progress:
|
||||||
|
response = app.response_class(
|
||||||
|
response="update in progress",
|
||||||
|
status=200,
|
||||||
|
mimetype='text/plain'
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.perform_update()
|
||||||
|
response = app.response_class(
|
||||||
|
response="update started, reload the site in a while",
|
||||||
|
status=200,
|
||||||
|
mimetype='text/plain'
|
||||||
|
)
|
||||||
|
|
||||||
|
response.headers.add("Access-Control-Allow-Origin", "*")
|
||||||
|
return response
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
return self.post()
|
||||||
|
|
||||||
|
def perform_update(self):
|
||||||
|
from ..database import Database
|
||||||
|
db : Database = app.databases["KF3"]
|
||||||
|
print("Update")
|
||||||
|
#await manual()
|
||||||
|
db.reload_data()
|
|
@ -1,133 +1,133 @@
|
||||||
import json
|
import json
|
||||||
import math
|
import math
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
def GetName(charaData):
|
def GetName(charaData):
|
||||||
name = "no name"
|
name = "no name"
|
||||||
if charaData is not None:
|
if charaData is not None:
|
||||||
if charaData["nameEn"] != "":
|
if charaData["nameEn"] != "":
|
||||||
name = charaData["nameEn"]
|
name = charaData["nameEn"]
|
||||||
elif charaData["name"] != "":
|
elif charaData["name"] != "":
|
||||||
name = charaData["name"]
|
name = charaData["name"]
|
||||||
if charaData["nickname"] != "":
|
if charaData["nickname"] != "":
|
||||||
name += " " + charaData["nickname"]
|
name += " " + charaData["nickname"]
|
||||||
return name
|
return name
|
||||||
|
|
||||||
def GetAttackBase(alphaBase, level):
|
def GetAttackBase(alphaBase, level):
|
||||||
if level <= alphaBase["atkLvMiddleNum"]:
|
if level <= alphaBase["atkLvMiddleNum"]:
|
||||||
t = (level - 1) / (alphaBase["atkLvMiddleNum"]-1)
|
t = (level - 1) / (alphaBase["atkLvMiddleNum"]-1)
|
||||||
return lerp(alphaBase["atkParamLv1"], alphaBase["atkParamLvMiddle"], t)
|
return lerp(alphaBase["atkParamLv1"], alphaBase["atkParamLvMiddle"], t)
|
||||||
else:
|
else:
|
||||||
t = (level - alphaBase["atkLvMiddleNum"]) / (99 - alphaBase["atkLvMiddleNum"])
|
t = (level - alphaBase["atkLvMiddleNum"]) / (99 - alphaBase["atkLvMiddleNum"])
|
||||||
return lerp(alphaBase["atkParamLvMiddle"], alphaBase["atkParamLv99"], t)
|
return lerp(alphaBase["atkParamLvMiddle"], alphaBase["atkParamLv99"], t)
|
||||||
|
|
||||||
def GetDefenseBase(alphaBase, level):
|
def GetDefenseBase(alphaBase, level):
|
||||||
if level <= alphaBase["defLvMiddleNum"]:
|
if level <= alphaBase["defLvMiddleNum"]:
|
||||||
t = (level - 1) / (alphaBase["defLvMiddleNum"]-1)
|
t = (level - 1) / (alphaBase["defLvMiddleNum"]-1)
|
||||||
return lerp(alphaBase["defParamLv1"], alphaBase["defParamLvMiddle"], t)
|
return lerp(alphaBase["defParamLv1"], alphaBase["defParamLvMiddle"], t)
|
||||||
else:
|
else:
|
||||||
t = (level - alphaBase["defLvMiddleNum"]) / (99 - alphaBase["defLvMiddleNum"])
|
t = (level - alphaBase["defLvMiddleNum"]) / (99 - alphaBase["defLvMiddleNum"])
|
||||||
return lerp(alphaBase["defParamLvMiddle"], alphaBase["defParamLv99"], t)
|
return lerp(alphaBase["defParamLvMiddle"], alphaBase["defParamLv99"], t)
|
||||||
|
|
||||||
def GetHealthBase(alphaBase, level):
|
def GetHealthBase(alphaBase, level):
|
||||||
if level <= alphaBase["hpLvMiddleNum"]:
|
if level <= alphaBase["hpLvMiddleNum"]:
|
||||||
t = (level - 1) / (alphaBase["hpLvMiddleNum"]-1)
|
t = (level - 1) / (alphaBase["hpLvMiddleNum"]-1)
|
||||||
return lerp(alphaBase["hpParamLv1"], alphaBase["hpParamLvMiddle"], t)
|
return lerp(alphaBase["hpParamLv1"], alphaBase["hpParamLvMiddle"], t)
|
||||||
else:
|
else:
|
||||||
t = (level - alphaBase["hpLvMiddleNum"]) / (99 - alphaBase["hpLvMiddleNum"])
|
t = (level - alphaBase["hpLvMiddleNum"]) / (99 - alphaBase["hpLvMiddleNum"])
|
||||||
return lerp(alphaBase["hpParamLvMiddle"], alphaBase["hpParamLv99"], t)
|
return lerp(alphaBase["hpParamLvMiddle"], alphaBase["hpParamLv99"], t)
|
||||||
|
|
||||||
def get_all_stats(chara, alphaBase, max_level: bool, rising_status_pattern):
|
def get_all_stats(chara, alphaBase, max_level: bool, rising_status_pattern):
|
||||||
level = 99 if max_level else 1
|
level = 99 if max_level else 1
|
||||||
|
|
||||||
hp = GetHealthBase(alphaBase, level)
|
hp = GetHealthBase(alphaBase, level)
|
||||||
atk = GetAttackBase(alphaBase, level)
|
atk = GetAttackBase(alphaBase, level)
|
||||||
defe = GetDefenseBase(alphaBase, level)
|
defe = GetDefenseBase(alphaBase, level)
|
||||||
|
|
||||||
if max_level:
|
if max_level:
|
||||||
starBoost = 1 + (chara["rankHigh"] - 1) * 0.02
|
starBoost = 1 + (chara["rankHigh"] - 1) * 0.02
|
||||||
hp = int(math.ceil((hp + chara["promoteBonus"]["hp"]) * starBoost) + chara["costumeBonus"]["hp"])
|
hp = int(math.ceil((hp + chara["promoteBonus"]["hp"]) * starBoost) + chara["costumeBonus"]["hp"])
|
||||||
atk = int(math.ceil((atk + chara["promoteBonus"]["atk"]) * starBoost) + chara["costumeBonus"]["atk"])
|
atk = int(math.ceil((atk + chara["promoteBonus"]["atk"]) * starBoost) + chara["costumeBonus"]["atk"])
|
||||||
defe = int(math.ceil((defe + chara["promoteBonus"]["def"]) * starBoost) + chara["costumeBonus"]["def"])
|
defe = int(math.ceil((defe + chara["promoteBonus"]["def"]) * starBoost) + chara["costumeBonus"]["def"])
|
||||||
evd = 10 * alphaBase["avoidRatio"] + chara["promoteBonus"]["evd"]
|
evd = 10 * alphaBase["avoidRatio"] + chara["promoteBonus"]["evd"]
|
||||||
beatBonus = chara["promoteBonus"]["beat"] / 10
|
beatBonus = chara["promoteBonus"]["beat"] / 10
|
||||||
actBonus = chara["promoteBonus"]["act"] / 10
|
actBonus = chara["promoteBonus"]["act"] / 10
|
||||||
tryBonus = chara["promoteBonus"]["try"] / 10
|
tryBonus = chara["promoteBonus"]["try"] / 10
|
||||||
|
|
||||||
if rising_status_pattern is not None:
|
if rising_status_pattern is not None:
|
||||||
for i in range(51):
|
for i in range(51):
|
||||||
hp += rising_status_pattern["hp"]
|
hp += rising_status_pattern["hp"]
|
||||||
atk += rising_status_pattern["atk"]
|
atk += rising_status_pattern["atk"]
|
||||||
defe += rising_status_pattern["def"]
|
defe += rising_status_pattern["def"]
|
||||||
else:
|
else:
|
||||||
starBoost = 1 + (chara["rankLow"] - 1) * 0.02
|
starBoost = 1 + (chara["rankLow"] - 1) * 0.02
|
||||||
hp = int(math.ceil(hp * starBoost))
|
hp = int(math.ceil(hp * starBoost))
|
||||||
atk = int(math.ceil(atk * starBoost))
|
atk = int(math.ceil(atk * starBoost))
|
||||||
defe = int(math.ceil(defe * starBoost))
|
defe = int(math.ceil(defe * starBoost))
|
||||||
evd = 10 * alphaBase["avoidRatio"]
|
evd = 10 * alphaBase["avoidRatio"]
|
||||||
beatBonus = 0
|
beatBonus = 0
|
||||||
actBonus = 0
|
actBonus = 0
|
||||||
tryBonus = 0
|
tryBonus = 0
|
||||||
|
|
||||||
|
|
||||||
status = hp * 8 / 10
|
status = hp * 8 / 10
|
||||||
if hp * 8 % 10 > 0:
|
if hp * 8 % 10 > 0:
|
||||||
status += 1
|
status += 1
|
||||||
status += atk * 3 + defe * 2
|
status += atk * 3 + defe * 2
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
"level" : level,
|
"level" : level,
|
||||||
"status" : int(status),
|
"status" : int(status),
|
||||||
"wr" : chara["rankHigh"] if max_level else chara["rankLow"],
|
"wr" : chara["rankHigh"] if max_level else chara["rankLow"],
|
||||||
"hp" : hp,
|
"hp" : hp,
|
||||||
"atk" : atk,
|
"atk" : atk,
|
||||||
"def" : defe,
|
"def" : defe,
|
||||||
"evd" : evd,
|
"evd" : evd,
|
||||||
"beat" : beatBonus,
|
"beat" : beatBonus,
|
||||||
"act" : actBonus,
|
"act" : actBonus,
|
||||||
"try" : tryBonus,
|
"try" : tryBonus,
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def fill_miracle_numbers(chara):
|
def fill_miracle_numbers(chara):
|
||||||
output = []
|
output = []
|
||||||
damages = {}
|
damages = {}
|
||||||
buffs = defaultdict(list)
|
buffs = defaultdict(list)
|
||||||
|
|
||||||
for i, damage_param in enumerate(chara["arts"]["damageList"]):
|
for i, damage_param in enumerate(chara["arts"]["damageList"]):
|
||||||
damages[f"[DAMAGE{i}]"] = damage_param
|
damages[f"[DAMAGE{i}]"] = damage_param
|
||||||
|
|
||||||
for i, buff_param in enumerate(chara["arts"]["buffList"]):
|
for i, buff_param in enumerate(chara["arts"]["buffList"]):
|
||||||
buffs[f"[BUFF{i}]"].append(buff_param)
|
buffs[f"[BUFF{i}]"].append(buff_param)
|
||||||
buffs[f"[HEAL{i}]"].append(buff_param)
|
buffs[f"[HEAL{i}]"].append(buff_param)
|
||||||
buffs[f"[INCREMENT{i}]"].append(buff_param)
|
buffs[f"[INCREMENT{i}]"].append(buff_param)
|
||||||
|
|
||||||
for i in range(1, 7):
|
for i in range(1, 7):
|
||||||
base_text = chara["arts"]["actionEffect"]
|
base_text = chara["arts"]["actionEffect"]
|
||||||
for damage_key, damage_value in damages.items():
|
for damage_key, damage_value in damages.items():
|
||||||
new_value = str(int(damage_value["damageRate"] * (1 + damage_value["growthRate"] * (i - 1)) * 100 + 0.01))
|
new_value = str(int(damage_value["damageRate"] * (1 + damage_value["growthRate"] * (i - 1)) * 100 + 0.01))
|
||||||
base_text = base_text.replace(damage_key, new_value)
|
base_text = base_text.replace(damage_key, new_value)
|
||||||
|
|
||||||
for buff_key, buff_value_list in buffs.items():
|
for buff_key, buff_value_list in buffs.items():
|
||||||
buff_value = buff_value_list[0]
|
buff_value = buff_value_list[0]
|
||||||
if buff_key[1] == 'B':
|
if buff_key[1] == 'B':
|
||||||
new_value = str(int(abs(buff_value["coefficient"] * (1 + buff_value["growthRate"] * (i - 1)) - 1) * 100 + 0.01))
|
new_value = str(int(abs(buff_value["coefficient"] * (1 + buff_value["growthRate"] * (i - 1)) - 1) * 100 + 0.01))
|
||||||
base_text = base_text.replace(buff_key, new_value)
|
base_text = base_text.replace(buff_key, new_value)
|
||||||
elif buff_key[1] == 'H':
|
elif buff_key[1] == 'H':
|
||||||
new_value = str(int(buff_value["coefficient"] * (1 + buff_value["growthRate"] * (i - 1)) * 100 + 0.01))
|
new_value = str(int(buff_value["coefficient"] * (1 + buff_value["growthRate"] * (i - 1)) * 100 + 0.01))
|
||||||
base_text = base_text.replace(buff_key, new_value)
|
base_text = base_text.replace(buff_key, new_value)
|
||||||
elif buff_key[1] == 'I':
|
elif buff_key[1] == 'I':
|
||||||
new_value = str(int(abs(buff_value["increment"]) * (1 + buff_value["growthRate"] * (i - 1)) + 0.01))
|
new_value = str(int(abs(buff_value["increment"]) * (1 + buff_value["growthRate"] * (i - 1)) + 0.01))
|
||||||
base_text = base_text.replace(buff_key, new_value)
|
base_text = base_text.replace(buff_key, new_value)
|
||||||
|
|
||||||
output.append(base_text)
|
output.append(base_text)
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def toJSON(chara):
|
def toJSON(chara):
|
||||||
return json.dumps(chara, default=lambda o: o.__dict__,
|
return json.dumps(chara, default=lambda o: o.__dict__,
|
||||||
sort_keys=True, indent=1, ensure_ascii=False)
|
sort_keys=True, indent=1, ensure_ascii=False)
|
||||||
|
|
||||||
def lerp(a, b, t):
|
def lerp(a, b, t):
|
||||||
return (1 - t) * a + t * b
|
return (1 - t) * a + t * b
|
|
@ -1,292 +1,298 @@
|
||||||
import json
|
import json
|
||||||
import platform
|
import platform
|
||||||
from loaders.Kingdom.numeric import numeric
|
from .numeric import numeric
|
||||||
from loaders.Kingdom.kemono import clean_skill_string, calculate_stats, fill_miracle, get_awaken_materials, get_skill_materials
|
from .kemono import clean_skill_string, calculate_stats, fill_miracle, get_awaken_materials, get_skill_materials
|
||||||
|
|
||||||
from endpoints.Kingdom.friend import Kingdom_Friend
|
from .endpoints.item import Kingdom_Item
|
||||||
from endpoints.Kingdom.friends import Kingdom_Friends
|
from .endpoints.items import Kingdom_Items
|
||||||
from endpoints.Kingdom.item import Kingdom_Item
|
from .endpoints.update import Kingdom_Update
|
||||||
from endpoints.Kingdom.items import Kingdom_Items
|
from .endpoints.friend import Kingdom_Friend
|
||||||
|
from .endpoints.friends import Kingdom_Friends
|
||||||
#element 1-orange 2-blue 3-green
|
|
||||||
#showSkillType 1-control 2-guard 3-heal 4-support 5-assault 6-aoe
|
#element 1-orange 2-blue 3-green
|
||||||
|
#showSkillType 1-control 2-guard 3-heal 4-support 5-assault 6-aoe
|
||||||
class KingdomDB:
|
|
||||||
processed_friends = {}
|
class Database:
|
||||||
item_stages = {}
|
processed_friends = {}
|
||||||
|
item_stages = {}
|
||||||
def __init__(self, api) -> None:
|
|
||||||
app = api.app
|
def __init__(self, api) -> None:
|
||||||
if "Kingdom" in app.databases:
|
app = api.app
|
||||||
del app.databases["Kingdom"]
|
if "Kingdom" in app.databases:
|
||||||
|
del app.databases["Kingdom"]
|
||||||
if platform.system() == "Windows":
|
|
||||||
NUMERICPATH = "H:\\Apache\\Katworks\\KF\\assets\\Kingdom1\\NumericData"
|
self.reload_data()
|
||||||
else:
|
|
||||||
NUMERICPATH = "/media/USB2/Apache/Katworks/KF/assets/Kingdom1/NumericData"
|
app.databases["Kingdom"] = self
|
||||||
|
|
||||||
self.kfk_drop = numeric(NUMERICPATH +"/Drop.num", 0)
|
api.add_resource(Kingdom_Friend, "/Kingdom/Friend/<int:id>")
|
||||||
self.kfk_combo = numeric(NUMERICPATH +"/Combo.num", 0)
|
api.add_resource(Kingdom_Friends, "/Kingdom/Friends")
|
||||||
self.kfk_skill = numeric(NUMERICPATH +"/Skill.num", 0)
|
api.add_resource(Kingdom_Item, "/Kingdom/Item/<int:id>")
|
||||||
self.kfk_equip = numeric(NUMERICPATH +"/Equip.num", 0)
|
api.add_resource(Kingdom_Items, "/Kingdom/Items")
|
||||||
self.kfk_kemono = numeric(NUMERICPATH +"/Kemono.num", 0)
|
api.add_resource(Kingdom_Update, "/Kingdom/Update")
|
||||||
self.kfk_stages = numeric(NUMERICPATH +"/Stage.num", 0)
|
|
||||||
self.kfk_drop_group = numeric(NUMERICPATH +"/DropGroup.num", 0)
|
def reload_data(self):
|
||||||
self.kfk_trust_attri = numeric(NUMERICPATH +"/TrustAttri.num", 0)
|
if platform.system() == "Windows":
|
||||||
self.kfk_kemono_skill = numeric(NUMERICPATH +"/KemonoSkill.num", 0)
|
NUMERICPATH = "H:\\Apache\\Katworks\\KF\\assets\\Kingdom1\\NumericData"
|
||||||
self.kfk_kemono_power = numeric(NUMERICPATH +"/KemonoPower.num", 0)
|
else:
|
||||||
self.kfk_kemono_waken = numeric(NUMERICPATH +"/KemonoWaken.num", 0)
|
NUMERICPATH = "/var/www/html/Katworks/KF/assets/Kingdom1/NumericData"
|
||||||
self.kfk_en_item = numeric(NUMERICPATH + "/en/Item.ntxt", 1)
|
|
||||||
self.kfk_en_equip = numeric(NUMERICPATH + "/en/Equip.ntxt", 1)
|
self.kfk_drop = numeric(NUMERICPATH +"/Drop.num", 0)
|
||||||
self.kfk_en_skill = numeric(NUMERICPATH + "/en/Skill.ntxt", 1)
|
self.kfk_combo = numeric(NUMERICPATH +"/Combo.num", 0)
|
||||||
self.kfk_en_combo = numeric(NUMERICPATH + "/en/Combo.ntxt", 1)
|
self.kfk_skill = numeric(NUMERICPATH +"/Skill.num", 0)
|
||||||
self.kfk_en_kemono = numeric(NUMERICPATH + "/en/Kemono.ntxt", 1)
|
self.kfk_equip = numeric(NUMERICPATH +"/Equip.num", 0)
|
||||||
self.kfk_en_kemono_WkPaDc = numeric(NUMERICPATH + "/en/KemonoWkPaDc.ntxt", 1)
|
self.kfk_kemono = numeric(NUMERICPATH +"/Kemono.num", 0)
|
||||||
self.kfk_en_kemono_power = numeric(NUMERICPATH + "/en/KemonoPower.ntxt", 1)
|
self.kfk_stages = numeric(NUMERICPATH +"/Stage.num", 0)
|
||||||
self.kfk_en_kemono_waken = numeric(NUMERICPATH + "/en/KemonoWaken.ntxt", 1)
|
self.kfk_drop_group = numeric(NUMERICPATH +"/DropGroup.num", 0)
|
||||||
self.kfk_en_kemono_garden = numeric(NUMERICPATH + "/en/KemonoGarden.ntxt", 1)
|
self.kfk_trust_attri = numeric(NUMERICPATH +"/TrustAttri.num", 0)
|
||||||
self.kfk_en_str = numeric(NUMERICPATH + "/en/Str.ntxt", 1)
|
self.kfk_kemono_skill = numeric(NUMERICPATH +"/KemonoSkill.num", 0)
|
||||||
|
self.kfk_kemono_power = numeric(NUMERICPATH +"/KemonoPower.num", 0)
|
||||||
self.process_friends()
|
self.kfk_kemono_waken = numeric(NUMERICPATH +"/KemonoWaken.num", 0)
|
||||||
self.process_stages()
|
self.kfk_en_item = numeric(NUMERICPATH + "/en/Item.ntxt", 1)
|
||||||
|
self.kfk_en_equip = numeric(NUMERICPATH + "/en/Equip.ntxt", 1)
|
||||||
app.databases["Kingdom"] = self
|
self.kfk_en_skill = numeric(NUMERICPATH + "/en/Skill.ntxt", 1)
|
||||||
api.add_resource(Kingdom_Friend, "/Kingdom/Friend/<int:id>")
|
self.kfk_en_combo = numeric(NUMERICPATH + "/en/Combo.ntxt", 1)
|
||||||
api.add_resource(Kingdom_Friends, "/Kingdom/Friends")
|
self.kfk_en_kemono = numeric(NUMERICPATH + "/en/Kemono.ntxt", 1)
|
||||||
api.add_resource(Kingdom_Item, "/Kingdom/Item/<int:id>")
|
self.kfk_en_kemono_WkPaDc = numeric(NUMERICPATH + "/en/KemonoWkPaDc.ntxt", 1)
|
||||||
api.add_resource(Kingdom_Items, "/Kingdom/Items")
|
self.kfk_en_kemono_power = numeric(NUMERICPATH + "/en/KemonoPower.ntxt", 1)
|
||||||
|
self.kfk_en_kemono_waken = numeric(NUMERICPATH + "/en/KemonoWaken.ntxt", 1)
|
||||||
def process_friends(self):
|
self.kfk_en_kemono_garden = numeric(NUMERICPATH + "/en/KemonoGarden.ntxt", 1)
|
||||||
self.processed_friends = {}
|
self.kfk_en_str = numeric(NUMERICPATH + "/en/Str.ntxt", 1)
|
||||||
for friend_id in self.kfk_kemono.indexed_data:
|
|
||||||
if friend_id > 19000:
|
self.process_friends()
|
||||||
continue
|
self.process_stages()
|
||||||
|
|
||||||
friend = self.kfk_kemono.get(friend_id)
|
def process_friends(self):
|
||||||
|
self.processed_friends = {}
|
||||||
friend["comboSkill"] = ""
|
for friend_id in self.kfk_kemono.indexed_data:
|
||||||
combo_friends = []
|
if friend_id > 19000:
|
||||||
for entry in friend["combo"]:
|
continue
|
||||||
combo = self.kfk_combo.get(entry)
|
|
||||||
if combo is not None:
|
friend = self.kfk_kemono.get(friend_id)
|
||||||
combo_en = self.kfk_en_combo.get(combo["comboSkill"])
|
|
||||||
friend["comboSkill"] = {"name":combo_en["comboName"], "desc":combo_en["desc"]}
|
friend["comboSkill"] = ""
|
||||||
for combo_friend_id in combo["comboKemono"]:
|
combo_friends = []
|
||||||
combo_friend = self.kfk_en_kemono.get(combo_friend_id)
|
for entry in friend["combo"]:
|
||||||
if combo_friend is not None and "name" in combo_friend:
|
combo = self.kfk_combo.get(entry)
|
||||||
combo_friends.append(combo_friend["name"])
|
if combo is not None:
|
||||||
else:
|
combo_en = self.kfk_en_combo.get(combo["comboSkill"])
|
||||||
combo_friends.append(combo_friend_id)
|
friend["comboSkill"] = {"name":combo_en["comboName"], "desc":combo_en["desc"]}
|
||||||
|
for combo_friend_id in combo["comboKemono"]:
|
||||||
friend["combo"] = combo_friends
|
combo_friend = self.kfk_en_kemono.get(combo_friend_id)
|
||||||
|
if combo_friend is not None and "name" in combo_friend:
|
||||||
limit_breaks = []
|
combo_friends.append(combo_friend["name"])
|
||||||
for bk_value in self.kfk_kemono_power.indexed_data.values():
|
else:
|
||||||
if len(limit_breaks) == 5:
|
combo_friends.append(combo_friend_id)
|
||||||
break
|
|
||||||
if(bk_value["kemonosn"] == friend_id):
|
friend["combo"] = combo_friends
|
||||||
if bk_value["effectType1"] == 0:
|
|
||||||
pass
|
limit_breaks = []
|
||||||
if bk_value["effectType1"] == 1 or bk_value["effectType1"] == 3:
|
for bk_value in self.kfk_kemono_power.indexed_data.values():
|
||||||
lb = self.kfk_en_kemono_power.get(friend_id * 100 + bk_value["powerlevel"])
|
if len(limit_breaks) == 5:
|
||||||
if "name" in lb:
|
break
|
||||||
limit_breaks.append({"name": lb["name"], "desc": lb["describe"]})
|
if(bk_value["kemonosn"] == friend_id):
|
||||||
else:
|
if bk_value["effectType1"] == 0:
|
||||||
limit_breaks.append({"name": None, "desc": lb["describe"]})
|
pass
|
||||||
if bk_value["effectType1"] == 2:
|
if bk_value["effectType1"] == 1 or bk_value["effectType1"] == 3:
|
||||||
raise Exception()
|
lb = self.kfk_en_kemono_power.get(friend_id * 100 + bk_value["powerlevel"])
|
||||||
if bk_value["effectType1"] == 4:
|
if "name" in lb:
|
||||||
lb = self.kfk_en_kemono_WkPaDc.get(bk_value['effectParam1'][0] * 100)
|
limit_breaks.append({"name": lb["name"], "desc": lb["describe"]})
|
||||||
if lb is None:
|
else:
|
||||||
lb = {"name": None, "describe": None}
|
limit_breaks.append({"name": None, "desc": lb["describe"]})
|
||||||
limit_breaks.append({"name": lb["name"], "desc": clean_skill_string(lb["describe"])})
|
if bk_value["effectType1"] == 2:
|
||||||
|
raise Exception()
|
||||||
habits = []
|
if bk_value["effectType1"] == 4:
|
||||||
for habit in friend["habitSn"]:
|
lb = self.kfk_en_kemono_WkPaDc.get(bk_value['effectParam1'][0] * 100)
|
||||||
hbt = self.kfk_en_kemono_WkPaDc.get(habit*100)
|
if lb is None:
|
||||||
if hbt is None:
|
lb = {"name": None, "describe": None}
|
||||||
hbt = {"name": None, "describe": None}
|
limit_breaks.append({"name": lb["name"], "desc": clean_skill_string(lb["describe"])})
|
||||||
habits.append({"name":hbt["name"], "desc":hbt["describe"]})
|
|
||||||
for i in range (3):
|
habits = []
|
||||||
if len(habits) < i+1:
|
for habit in friend["habitSn"]:
|
||||||
habits.append({"name":None, "desc":None})
|
hbt = self.kfk_en_kemono_WkPaDc.get(habit*100)
|
||||||
|
if hbt is None:
|
||||||
awakens = []
|
hbt = {"name": None, "describe": None}
|
||||||
max_levels = []
|
habits.append({"name":hbt["name"], "desc":hbt["describe"]})
|
||||||
for i in range(3):
|
for i in range (3):
|
||||||
awaken_id = friend_id * 100 + i
|
if len(habits) < i+1:
|
||||||
awaken = self.kfk_kemono_waken.get(awaken_id)
|
habits.append({"name":None, "desc":None})
|
||||||
awaken1 = self.kfk_en_kemono_waken.get(awaken_id)
|
|
||||||
if awaken1 == None:
|
awakens = []
|
||||||
awaken1 = {"describe":"missing", "brilliance":"missing"}
|
max_levels = []
|
||||||
if awaken != None and awaken1 != None:
|
for i in range(3):
|
||||||
awaken["en"] = awaken1
|
awaken_id = friend_id * 100 + i
|
||||||
awakens.append(awaken)
|
awaken = self.kfk_kemono_waken.get(awaken_id)
|
||||||
max_levels.append(awaken["levelmax"])
|
awaken1 = self.kfk_en_kemono_waken.get(awaken_id)
|
||||||
|
if awaken1 == None:
|
||||||
def validateValue(obj, valName):
|
awaken1 = {"describe":"missing", "brilliance":"missing"}
|
||||||
if obj[valName] is None:
|
if awaken != None and awaken1 != None:
|
||||||
obj[valName] = {"name": "", "desc": ""}
|
awaken["en"] = awaken1
|
||||||
if "desc" not in obj[valName]:
|
awakens.append(awaken)
|
||||||
obj[valName]["desc"] = None
|
max_levels.append(awaken["levelmax"])
|
||||||
|
|
||||||
friend["name"] = self.kfk_en_kemono.get(friend_id)["name"]
|
def validateValue(obj, valName):
|
||||||
ele = friend["element"]
|
if obj[valName] is None:
|
||||||
friend["color"] = "Orange" if ele == 1 else "Green" if ele == 2 else "Blue" if ele == 3 else "Error"
|
obj[valName] = {"name": "", "desc": ""}
|
||||||
ele = friend["showSkillType"]
|
if "desc" not in obj[valName]:
|
||||||
friend["role"] = "Control" if ele == 1 else "Guard" if ele == 2 else "Healer" if ele == 3 else "Support" if ele == 4 else "Assault" if ele == 5 else "Assault (AOE)" if ele == 6 else "Error"
|
obj[valName]["desc"] = None
|
||||||
friend["maxLvl"] = max_levels
|
|
||||||
friend["awakenings"] = awakens
|
friend["name"] = self.kfk_en_kemono.get(friend_id)["name"]
|
||||||
friend["maxAwaken"] = max_awaken = len(awakens)-1
|
ele = friend["element"]
|
||||||
friend["base_stats"] = calculate_stats(friend, 0, 1)
|
friend["color"] = "Orange" if ele == 1 else "Green" if ele == 2 else "Blue" if ele == 3 else "Error"
|
||||||
friend["max_stats"] = calculate_stats(friend, max_awaken, friend["maxLvl"][max_awaken], trust_percent=100, trustAttri= next((e for e in self.kfk_trust_attri.indexed_data.values() if e["kemonoSn"] == friend_id), None))
|
ele = friend["showSkillType"]
|
||||||
friend["max_miracle"] = 13 if friend["star"] == 6 or friend["star"] == 5 else 12 if friend["star"] == 4 else 11
|
friend["role"] = "Control" if ele == 1 else "Guard" if ele == 2 else "Healer" if ele == 3 else "Support" if ele == 4 else "Assault" if ele == 5 else "Assault (AOE)" if ele == 6 else "Error"
|
||||||
friend["collisionSkill"] = self.kfk_en_skill.get(friend["collisionSkill"])
|
friend["maxLvl"] = max_levels
|
||||||
friend["gardenSpec1"] = self.kfk_en_kemono_garden.get(friend["gardenSpec1"])
|
friend["awakenings"] = awakens
|
||||||
friend["gardenSpec2"] = self.kfk_en_kemono_garden.get(friend["gardenSpec2"])
|
friend["maxAwaken"] = max_awaken = len(awakens)-1
|
||||||
friend["gardenSpec3"] = self.kfk_en_kemono_garden.get(friend["gardenSpec3"])
|
friend["base_stats"] = calculate_stats(friend, 0, 1)
|
||||||
friend["describe"] = self.kfk_en_str.get(friend["describe"])
|
friend["max_stats"] = calculate_stats(friend, max_awaken, friend["maxLvl"][max_awaken], trust_percent=100, trustAttri= next((e for e in self.kfk_trust_attri.indexed_data.values() if e["kemonoSn"] == friend_id), None))
|
||||||
|
friend["max_miracle"] = 13 if friend["star"] == 6 or friend["star"] == 5 else 12 if friend["star"] == 4 else 11
|
||||||
friend["attack"] = self.kfk_en_skill.get(friend["attack"])
|
friend["collisionSkill"] = self.kfk_en_skill.get(friend["collisionSkill"])
|
||||||
|
friend["gardenSpec1"] = self.kfk_en_kemono_garden.get(friend["gardenSpec1"])
|
||||||
skill_id = friend["skill"]
|
friend["gardenSpec2"] = self.kfk_en_kemono_garden.get(friend["gardenSpec2"])
|
||||||
friend["skill"] = self.kfk_en_skill.get(skill_id)
|
friend["gardenSpec3"] = self.kfk_en_kemono_garden.get(friend["gardenSpec3"])
|
||||||
friend["skill1"] = self.kfk_en_skill.get(skill_id+1) if max_awaken >= 1 else None
|
friend["describe"] = self.kfk_en_str.get(friend["describe"])
|
||||||
friend["skill2"] = self.kfk_en_skill.get(skill_id+2) if max_awaken >= 2 else None
|
|
||||||
friend["spAttack"] = self.kfk_en_skill.get(friend["spAttack"])
|
friend["attack"] = self.kfk_en_skill.get(friend["attack"])
|
||||||
friend["habitSn"] = habits
|
|
||||||
friend["limitBreaks"] = limit_breaks
|
skill_id = friend["skill"]
|
||||||
|
friend["skill"] = self.kfk_en_skill.get(skill_id)
|
||||||
validateValue(friend, "collisionSkill")
|
friend["skill1"] = self.kfk_en_skill.get(skill_id+1) if max_awaken >= 1 else None
|
||||||
validateValue(friend, "attack")
|
friend["skill2"] = self.kfk_en_skill.get(skill_id+2) if max_awaken >= 2 else None
|
||||||
validateValue(friend, "skill")
|
friend["spAttack"] = self.kfk_en_skill.get(friend["spAttack"])
|
||||||
validateValue(friend, "skill1")
|
friend["habitSn"] = habits
|
||||||
validateValue(friend, "skill2")
|
friend["limitBreaks"] = limit_breaks
|
||||||
validateValue(friend, "spAttack")
|
|
||||||
|
validateValue(friend, "collisionSkill")
|
||||||
self.processed_friends[friend_id] = friend
|
validateValue(friend, "attack")
|
||||||
|
validateValue(friend, "skill")
|
||||||
def process_stages(self):
|
validateValue(friend, "skill1")
|
||||||
self.item_stages = {}
|
validateValue(friend, "skill2")
|
||||||
for stage in self.kfk_stages.indexed_data.values():
|
validateValue(friend, "spAttack")
|
||||||
merged_array = stage["fastReward2_star3"] + stage["fastReward3_star3"]
|
|
||||||
if len(merged_array) > 0:
|
self.processed_friends[friend_id] = friend
|
||||||
for drop_sn in merged_array:
|
|
||||||
drop = self.kfk_drop.get(drop_sn)
|
def process_stages(self):
|
||||||
for drop_group_sn in drop["groupSn"]:
|
self.item_stages = {}
|
||||||
drop_group = self.kfk_drop_group.get(drop_group_sn)
|
for stage in self.kfk_stages.indexed_data.values():
|
||||||
if drop_group["type"] == 2 or drop_group["type"] == 1:
|
merged_array = stage["fastReward2_star3"] + stage["fastReward3_star3"]
|
||||||
#materials
|
if len(merged_array) > 0:
|
||||||
item_id = drop_group["content"]
|
for drop_sn in merged_array:
|
||||||
item = self.kfk_en_item.get(item_id)
|
drop = self.kfk_drop.get(drop_sn)
|
||||||
if item_id not in self.item_stages:
|
for drop_group_sn in drop["groupSn"]:
|
||||||
self.item_stages[item_id] = []
|
drop_group = self.kfk_drop_group.get(drop_group_sn)
|
||||||
if stage not in self.item_stages[item_id]:
|
if drop_group["type"] == 2 or drop_group["type"] == 1:
|
||||||
self.item_stages[item_id].append(stage)
|
#materials
|
||||||
|
item_id = drop_group["content"]
|
||||||
def get_chara(self, id : int):
|
item = self.kfk_en_item.get(item_id)
|
||||||
#return next(lambda f: f["sn"] == id, None)
|
if item_id not in self.item_stages:
|
||||||
if id not in self.processed_friends:
|
self.item_stages[item_id] = []
|
||||||
return None
|
if stage not in self.item_stages[item_id]:
|
||||||
else:
|
self.item_stages[item_id].append(stage)
|
||||||
friend = self.processed_friends[id]
|
|
||||||
data = {
|
def get_chara(self, id : int):
|
||||||
"id": friend["sn"],
|
#return next(lambda f: f["sn"] == id, None)
|
||||||
"name": friend["name"],
|
if id not in self.processed_friends:
|
||||||
"element": friend["color"],
|
return None
|
||||||
"role": friend["role"],
|
else:
|
||||||
"star": friend["star"],
|
friend = self.processed_friends[id]
|
||||||
"combo": friend["combo"],
|
data = {
|
||||||
"comboSkill": friend["comboSkill"],
|
"id": friend["sn"],
|
||||||
"describe": friend["describe"],
|
"name": friend["name"],
|
||||||
"awakenings": friend["awakenings"],
|
"element": friend["color"],
|
||||||
"max_miracle": friend["max_miracle"],
|
"role": friend["role"],
|
||||||
"stats": {
|
"star": friend["star"],
|
||||||
"base":friend["base_stats"],
|
"combo": friend["combo"],
|
||||||
"max":friend["max_stats"]
|
"comboSkill": friend["comboSkill"],
|
||||||
},
|
"describe": friend["describe"],
|
||||||
"collision": {"name": friend["collisionSkill"]["name"], "desc": clean_skill_string(friend["collisionSkill"]["desc"])},
|
"awakenings": friend["awakenings"],
|
||||||
"attack": {"name": friend["attack"]["name"], "desc": clean_skill_string(friend["attack"]["desc"])},
|
"max_miracle": friend["max_miracle"],
|
||||||
"skills":[
|
"stats": {
|
||||||
{"name": friend["skill"]["name"], "desc": fill_miracle(friend["skill"]["desc"], miracle_level=friend["max_miracle"], kemono_level=friend["maxLvl"][-1])},
|
"base":friend["base_stats"],
|
||||||
{"name": friend["skill1"]["name"], "desc": fill_miracle(friend["skill1"]["desc"], miracle_level=friend["max_miracle"], kemono_level=friend["maxLvl"][-1])},
|
"max":friend["max_stats"]
|
||||||
{"name": friend["skill2"]["name"], "desc": fill_miracle(friend["skill2"]["desc"], miracle_level=friend["max_miracle"], kemono_level=friend["maxLvl"][-1])},
|
},
|
||||||
],
|
"collision": {"name": friend["collisionSkill"]["name"], "desc": clean_skill_string(friend["collisionSkill"]["desc"])},
|
||||||
"garden":[
|
"attack": {"name": friend["attack"]["name"], "desc": clean_skill_string(friend["attack"]["desc"])},
|
||||||
friend["gardenSpec1"],
|
"skills":[
|
||||||
friend["gardenSpec2"],
|
{"name": friend["skill"]["name"], "desc": fill_miracle(friend["skill"]["desc"], miracle_level=friend["max_miracle"], kemono_level=friend["maxLvl"][-1])},
|
||||||
friend["gardenSpec3"],
|
{"name": friend["skill1"]["name"], "desc": fill_miracle(friend["skill1"]["desc"], miracle_level=friend["max_miracle"], kemono_level=friend["maxLvl"][-1])},
|
||||||
],
|
{"name": friend["skill2"]["name"], "desc": fill_miracle(friend["skill2"]["desc"], miracle_level=friend["max_miracle"], kemono_level=friend["maxLvl"][-1])},
|
||||||
"habits":[
|
],
|
||||||
{"name": friend["habitSn"][0]["name"], "desc": clean_skill_string(friend["habitSn"][0]["desc"])},
|
"garden":[
|
||||||
{"name": friend["habitSn"][1]["name"], "desc": clean_skill_string(friend["habitSn"][1]["desc"])},
|
friend["gardenSpec1"],
|
||||||
{"name": friend["habitSn"][2]["name"], "desc": clean_skill_string(friend["habitSn"][2]["desc"])}
|
friend["gardenSpec2"],
|
||||||
],
|
friend["gardenSpec3"],
|
||||||
"limitBreaks":[
|
],
|
||||||
friend["limitBreaks"][0],
|
"habits":[
|
||||||
friend["limitBreaks"][1],
|
{"name": friend["habitSn"][0]["name"], "desc": clean_skill_string(friend["habitSn"][0]["desc"])},
|
||||||
friend["limitBreaks"][2],
|
{"name": friend["habitSn"][1]["name"], "desc": clean_skill_string(friend["habitSn"][1]["desc"])},
|
||||||
friend["limitBreaks"][3],
|
{"name": friend["habitSn"][2]["name"], "desc": clean_skill_string(friend["habitSn"][2]["desc"])}
|
||||||
friend["limitBreaks"][4]
|
],
|
||||||
],
|
"limitBreaks":[
|
||||||
"awakenMaterials": get_awaken_materials(friend, self.kfk_kemono_waken, self.kfk_en_item),
|
friend["limitBreaks"][0],
|
||||||
"skillMaterials": get_skill_materials(friend, self.kfk_kemono_skill, self.kfk_en_item)
|
friend["limitBreaks"][1],
|
||||||
}
|
friend["limitBreaks"][2],
|
||||||
|
friend["limitBreaks"][3],
|
||||||
return json.dumps(data, sort_keys=False, indent=1, ensure_ascii=False)
|
friend["limitBreaks"][4]
|
||||||
|
],
|
||||||
def get_chara_wiki(self, id : int):
|
"awakenMaterials": get_awaken_materials(friend, self.kfk_kemono_waken, self.kfk_en_item),
|
||||||
friend = self.processed_friends[id]
|
"skillMaterials": get_skill_materials(friend, self.kfk_kemono_skill, self.kfk_en_item)
|
||||||
lines = []
|
}
|
||||||
lines.append("|name=" + friend["name"])
|
|
||||||
|
return json.dumps(data, sort_keys=False, indent=1, ensure_ascii=False)
|
||||||
#stats
|
|
||||||
lines.append("|maxLvls=" + ",".join([str(lvl) for lvl in friend["maxLvl"]]))
|
def get_chara_wiki(self, id : int):
|
||||||
lines.append("|hp=" + str(friend["base_stats"]["hp"]))
|
friend = self.processed_friends[id]
|
||||||
lines.append("|maxhp=" + str(friend["max_stats"]["hp"]))
|
lines = []
|
||||||
lines.append("|atk=" + str(friend["base_stats"]["patk"]))
|
lines.append("|name=" + friend["name"])
|
||||||
lines.append("|maxatk=" + str(friend["max_stats"]["patk"]))
|
|
||||||
lines.append("|satk=" + str(friend["base_stats"]["satk"]))
|
#stats
|
||||||
lines.append("|maxsatk=" + str(friend["max_stats"]["satk"]))
|
lines.append("|maxLvls=" + ",".join([str(lvl) for lvl in friend["maxLvl"]]))
|
||||||
lines.append("|pdef=" + str(friend["base_stats"]["pdef"]))
|
lines.append("|hp=" + str(friend["base_stats"]["hp"]))
|
||||||
lines.append("|maxpdef=" + str(friend["max_stats"]["pdef"]))
|
lines.append("|maxhp=" + str(friend["max_stats"]["hp"]))
|
||||||
lines.append("|sdef=" + str(friend["base_stats"]["sdef"]))
|
lines.append("|atk=" + str(friend["base_stats"]["patk"]))
|
||||||
lines.append("|maxsdef=" + str(friend["max_stats"]["sdef"]))
|
lines.append("|maxatk=" + str(friend["max_stats"]["patk"]))
|
||||||
lines.append("|speed=" + str(friend["base_stats"]["speed"]))
|
lines.append("|satk=" + str(friend["base_stats"]["satk"]))
|
||||||
lines.append("|maxspeed=" + str(friend["max_stats"]["speed"]))
|
lines.append("|maxsatk=" + str(friend["max_stats"]["satk"]))
|
||||||
|
lines.append("|pdef=" + str(friend["base_stats"]["pdef"]))
|
||||||
#skills
|
lines.append("|maxpdef=" + str(friend["max_stats"]["pdef"]))
|
||||||
lines.append("|collisionSkill=" + friend["collisionSkill"]["name"])
|
lines.append("|sdef=" + str(friend["base_stats"]["sdef"]))
|
||||||
lines.append("|collisionSkillEffect=" + clean_skill_string(friend["collisionSkill"]["desc"]))
|
lines.append("|maxsdef=" + str(friend["max_stats"]["sdef"]))
|
||||||
lines.append("|attack=" + friend["attack"]["name"])
|
lines.append("|speed=" + str(friend["base_stats"]["speed"]))
|
||||||
lines.append("|attackEffect=" + clean_skill_string(friend["attack"]["desc"]))
|
lines.append("|maxspeed=" + str(friend["max_stats"]["speed"]))
|
||||||
lines.append("|skill1=" + friend["skill"]["name"])
|
|
||||||
lines.append("|skill1Effect=" + clean_skill_string(friend["skill"]["desc"]))
|
#skills
|
||||||
lines.append("|skill2=" + friend["skill1"]["name"])
|
lines.append("|collisionSkill=" + friend["collisionSkill"]["name"])
|
||||||
lines.append("|skill2Effect=" + clean_skill_string(friend["skill1"]["desc"]))
|
lines.append("|collisionSkillEffect=" + clean_skill_string(friend["collisionSkill"]["desc"]))
|
||||||
lines.append("|skill3=" + friend["skill2"]["name"])
|
lines.append("|attack=" + friend["attack"]["name"])
|
||||||
lines.append("|skill3Effect=" + clean_skill_string(friend["skill2"]["desc"]))
|
lines.append("|attackEffect=" + clean_skill_string(friend["attack"]["desc"]))
|
||||||
lines.append("|spAttack=" + friend["spAttack"]["name"])
|
lines.append("|skill1=" + friend["skill"]["name"])
|
||||||
lines.append("|spAttackEffect=" + clean_skill_string(friend["spAttack"]["desc"]))
|
lines.append("|skill1Effect=" + clean_skill_string(friend["skill"]["desc"]))
|
||||||
|
lines.append("|skill2=" + friend["skill1"]["name"])
|
||||||
for i in range(0,5):
|
lines.append("|skill2Effect=" + clean_skill_string(friend["skill1"]["desc"]))
|
||||||
lb = friend['limitBreaks'][i]
|
lines.append("|skill3=" + friend["skill2"]["name"])
|
||||||
if lb["name"] is None:
|
lines.append("|skill3Effect=" + clean_skill_string(friend["skill2"]["desc"]))
|
||||||
lines.append(f"|b{i+1}={friend['limitBreaks'][i]['desc']}")
|
lines.append("|spAttack=" + friend["spAttack"]["name"])
|
||||||
else:
|
lines.append("|spAttackEffect=" + clean_skill_string(friend["spAttack"]["desc"]))
|
||||||
lines.append(f"|b{i+1}='''{friend['limitBreaks'][i]['name']}'''\n{friend['limitBreaks'][i]['desc']}")
|
|
||||||
|
for i in range(0,5):
|
||||||
return "\n".join(lines)
|
lb = friend['limitBreaks'][i]
|
||||||
|
if lb["name"] is None:
|
||||||
def get_item(self, id):
|
lines.append(f"|b{i+1}={friend['limitBreaks'][i]['desc']}")
|
||||||
result = {"item": None, "stages": []}
|
else:
|
||||||
item = self.kfk_en_item.get(id)
|
lines.append(f"|b{i+1}='''{friend['limitBreaks'][i]['name']}'''\n{friend['limitBreaks'][i]['desc']}")
|
||||||
if item is None:
|
|
||||||
return result
|
return "\n".join(lines)
|
||||||
|
|
||||||
result["item"] = item
|
def get_item(self, id):
|
||||||
|
result = {"item": None, "stages": []}
|
||||||
if id in self.item_stages:
|
item = self.kfk_en_item.get(id)
|
||||||
result["stages"] = self.item_stages[id]
|
if item is None:
|
||||||
|
return result
|
||||||
return json.dumps(result, sort_keys=False, indent=1, ensure_ascii=False)
|
|
||||||
|
result["item"] = item
|
||||||
|
|
||||||
|
if id in self.item_stages:
|
||||||
|
result["stages"] = self.item_stages[id]
|
||||||
|
|
||||||
|
return json.dumps(result, sort_keys=False, indent=1, ensure_ascii=False)
|
|
@ -1,25 +1,25 @@
|
||||||
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
|
from flask import request
|
||||||
|
|
||||||
class Kingdom_Friend(Resource):
|
class Kingdom_Friend(Resource):
|
||||||
def get(self, id:int):
|
def get(self, id:int):
|
||||||
if "wiki" in request.args:
|
if "wiki" in request.args:
|
||||||
result = app.databases["Kingdom"].get_chara_wiki(id)
|
result = app.databases["Kingdom"].get_chara_wiki(id)
|
||||||
|
|
||||||
response = app.response_class(
|
response = app.response_class(
|
||||||
response=result,
|
response=result,
|
||||||
status=200,
|
status=200,
|
||||||
mimetype='text/plain'
|
mimetype='text/plain'
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
result = app.databases["Kingdom"].get_chara(id)
|
result = app.databases["Kingdom"].get_chara(id)
|
||||||
|
|
||||||
response = app.response_class(
|
response = app.response_class(
|
||||||
response=result,
|
response=result,
|
||||||
status=200,
|
status=200,
|
||||||
mimetype='application/json'
|
mimetype='application/json'
|
||||||
)
|
)
|
||||||
|
|
||||||
response.headers.add("Access-Control-Allow-Origin", "*")
|
response.headers.add("Access-Control-Allow-Origin", "*")
|
||||||
return response
|
return response
|
|
@ -1,21 +1,21 @@
|
||||||
import json
|
import json
|
||||||
from flask_restful import Resource
|
from flask_restful import Resource
|
||||||
from flask import current_app as app, jsonify
|
from flask import current_app as app, jsonify
|
||||||
|
|
||||||
class Kingdom_Friends(Resource):
|
class Kingdom_Friends(Resource):
|
||||||
def get(self):
|
def get(self):
|
||||||
db = app.databases["Kingdom"]
|
db = app.databases["Kingdom"]
|
||||||
result = []
|
result = []
|
||||||
for value in db.processed_friends.values():
|
for value in db.processed_friends.values():
|
||||||
result.append({"id": value["sn"], "name": value["name"], "describe": value["describe"]["content"] if "content" in value["describe"] else ""})
|
result.append({"id": value["sn"], "name": value["name"], "describe": value["describe"]["content"] if "content" in value["describe"] else ""})
|
||||||
|
|
||||||
result = sorted(result, key=lambda f: f["id"])
|
result = sorted(result, key=lambda f: f["id"])
|
||||||
|
|
||||||
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),
|
||||||
status=200,
|
status=200,
|
||||||
mimetype='application/json'
|
mimetype='application/json'
|
||||||
)
|
)
|
||||||
response.headers.add("Access-Control-Allow-Origin", "*")
|
response.headers.add("Access-Control-Allow-Origin", "*")
|
||||||
|
|
||||||
return response
|
return response
|
|
@ -1,16 +1,16 @@
|
||||||
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
|
from flask import request
|
||||||
|
|
||||||
class Kingdom_Item(Resource):
|
class Kingdom_Item(Resource):
|
||||||
def get(self, id:int):
|
def get(self, id:int):
|
||||||
result = app.databases["Kingdom"].get_item(id)
|
result = app.databases["Kingdom"].get_item(id)
|
||||||
|
|
||||||
response = app.response_class(
|
response = app.response_class(
|
||||||
response=result,
|
response=result,
|
||||||
status=200,
|
status=200,
|
||||||
mimetype='application/json'
|
mimetype='application/json'
|
||||||
)
|
)
|
||||||
|
|
||||||
response.headers.add("Access-Control-Allow-Origin", "*")
|
response.headers.add("Access-Control-Allow-Origin", "*")
|
||||||
return response
|
return response
|
|
@ -1,23 +1,23 @@
|
||||||
import json
|
import json
|
||||||
from flask_restful import Resource
|
from flask_restful import Resource
|
||||||
from flask import current_app as app, jsonify
|
from flask import current_app as app, jsonify
|
||||||
|
|
||||||
class Kingdom_Items(Resource):
|
class Kingdom_Items(Resource):
|
||||||
def get(self):
|
def get(self):
|
||||||
db = app.databases["Kingdom"]
|
db = app.databases["Kingdom"]
|
||||||
result = []
|
result = []
|
||||||
for key in db.kfk_en_item.indexed_data.keys():
|
for key in db.kfk_en_item.indexed_data.keys():
|
||||||
new_value = db.kfk_en_item.indexed_data[key]
|
new_value = db.kfk_en_item.indexed_data[key]
|
||||||
new_value["id"] = key
|
new_value["id"] = key
|
||||||
result.append(new_value)
|
result.append(new_value)
|
||||||
|
|
||||||
result = sorted(result, key=lambda f: f["id"])
|
result = sorted(result, key=lambda f: f["id"])
|
||||||
|
|
||||||
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),
|
||||||
status=200,
|
status=200,
|
||||||
mimetype='application/json'
|
mimetype='application/json'
|
||||||
)
|
)
|
||||||
response.headers.add("Access-Control-Allow-Origin", "*")
|
response.headers.add("Access-Control-Allow-Origin", "*")
|
||||||
|
|
||||||
return response
|
return response
|
|
@ -1,27 +1,28 @@
|
||||||
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
|
from flask import request
|
||||||
import json
|
import json
|
||||||
|
|
||||||
class KF3_Update(Resource):
|
class Kingdom_Update(Resource):
|
||||||
def post(self):
|
def post(self):
|
||||||
db = app.databases["KF3"]
|
from ..database import Database
|
||||||
try:
|
db : Database = app.databases["Kingdom"]
|
||||||
db.reload_data()
|
try:
|
||||||
response = app.response_class(
|
db.reload_data()
|
||||||
response="update successful",
|
response = app.response_class(
|
||||||
status=200,
|
response="update successful",
|
||||||
mimetype='text/plain'
|
status=200,
|
||||||
)
|
mimetype='text/plain'
|
||||||
except:
|
)
|
||||||
response = app.response_class(
|
except:
|
||||||
response="update failed",
|
response = app.response_class(
|
||||||
status=500,
|
response="update failed",
|
||||||
mimetype='text/plain'
|
status=500,
|
||||||
)
|
mimetype='text/plain'
|
||||||
|
)
|
||||||
response.headers.add("Access-Control-Allow-Origin", "*")
|
|
||||||
return response
|
response.headers.add("Access-Control-Allow-Origin", "*")
|
||||||
|
return response
|
||||||
def get(self):
|
|
||||||
|
def get(self):
|
||||||
return self.post()
|
return self.post()
|
|
@ -1,161 +1,161 @@
|
||||||
import re
|
import re
|
||||||
import math
|
import math
|
||||||
|
|
||||||
def get_skill_materials(friend, kfk_kemono_skill, kfk_en_item):
|
def get_skill_materials(friend, kfk_kemono_skill, kfk_en_item):
|
||||||
items_total = []
|
items_total = []
|
||||||
kfk_skill = sorted(filter(lambda s: s["kemonosn"] == friend["sn"] and s["type"] == 2, kfk_kemono_skill.indexed_data.values()), key = lambda s: s["sn"])
|
kfk_skill = sorted(filter(lambda s: s["kemonosn"] == friend["sn"] and s["type"] == 2, kfk_kemono_skill.indexed_data.values()), key = lambda s: s["sn"])
|
||||||
for idx, s in enumerate(kfk_skill):
|
for idx, s in enumerate(kfk_skill):
|
||||||
if len(s["item"]) == 0:
|
if len(s["item"]) == 0:
|
||||||
continue
|
continue
|
||||||
items_total.append(
|
items_total.append(
|
||||||
{
|
{
|
||||||
"lvl": s["skilllevel"],
|
"lvl": s["skilllevel"],
|
||||||
"awakenReq": s["wakenlevel"],
|
"awakenReq": s["wakenlevel"],
|
||||||
"lvlReq": s["kemonolevel"],
|
"lvlReq": s["kemonolevel"],
|
||||||
"items": list([{"count": num, "name": kfk_en_item.get(item)["name"]} for item, num in zip(s["item"], s["itemnum"])])
|
"items": list([{"count": num, "name": kfk_en_item.get(item)["name"]} for item, num in zip(s["item"], s["itemnum"])])
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return items_total
|
return items_total
|
||||||
|
|
||||||
def get_awaken_materials(friend, kfk_kemono_waken, kfk_en_item):
|
def get_awaken_materials(friend, kfk_kemono_waken, kfk_en_item):
|
||||||
items_total = []
|
items_total = []
|
||||||
kfk_waken = sorted(filter(lambda s: s["kemonosn"] == friend["sn"], kfk_kemono_waken.indexed_data.values()), key = lambda s: s["sn"])
|
kfk_waken = sorted(filter(lambda s: s["kemonosn"] == friend["sn"], kfk_kemono_waken.indexed_data.values()), key = lambda s: s["sn"])
|
||||||
for idx, s in enumerate(kfk_waken):
|
for idx, s in enumerate(kfk_waken):
|
||||||
if len(s["item"]) == 0:
|
if len(s["item"]) == 0:
|
||||||
continue
|
continue
|
||||||
items_total.append(
|
items_total.append(
|
||||||
{
|
{
|
||||||
"lvl": idx+1,
|
"lvl": idx+1,
|
||||||
"items": list([{"count": num, "name": kfk_en_item.get(item)["name"]} for item, num in zip(s["item"], s["itemnum"])])
|
"items": list([{"count": num, "name": kfk_en_item.get(item)["name"]} for item, num in zip(s["item"], s["itemnum"])])
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return items_total
|
return items_total
|
||||||
|
|
||||||
def calculate_stats(friend, awaken : int, level : int, trust_percent = 0, trustAttri = None):
|
def calculate_stats(friend, awaken : int, level : int, trust_percent = 0, trustAttri = None):
|
||||||
stats_array = friend["attrScriptParam"]
|
stats_array = friend["attrScriptParam"]
|
||||||
max_levels = friend["maxLvl"]
|
max_levels = friend["maxLvl"]
|
||||||
max_awaken = friend["maxAwaken"]
|
max_awaken = friend["maxAwaken"]
|
||||||
|
|
||||||
awaken_step = max_awaken + 2
|
awaken_step = max_awaken + 2
|
||||||
|
|
||||||
atk_ptr = 1 * awaken_step
|
atk_ptr = 1 * awaken_step
|
||||||
satk_ptr = 2 * awaken_step
|
satk_ptr = 2 * awaken_step
|
||||||
pdef_ptr = 3 * awaken_step
|
pdef_ptr = 3 * awaken_step
|
||||||
sdef_ptr = 4 * awaken_step
|
sdef_ptr = 4 * awaken_step
|
||||||
hp_ptr = 5 * awaken_step
|
hp_ptr = 5 * awaken_step
|
||||||
speed_ptr = 6 * awaken_step
|
speed_ptr = 6 * awaken_step
|
||||||
|
|
||||||
stats = {"patk":stats_array[atk_ptr], "satk":stats_array[satk_ptr], "pdef":stats_array[pdef_ptr], "sdef":stats_array[sdef_ptr], "hp":stats_array[hp_ptr], "speed":stats_array[speed_ptr]}
|
stats = {"patk":stats_array[atk_ptr], "satk":stats_array[satk_ptr], "pdef":stats_array[pdef_ptr], "sdef":stats_array[sdef_ptr], "hp":stats_array[hp_ptr], "speed":stats_array[speed_ptr]}
|
||||||
for i in range(awaken + 1):
|
for i in range(awaken + 1):
|
||||||
if i == awaken:
|
if i == awaken:
|
||||||
max_level = level
|
max_level = level
|
||||||
else:
|
else:
|
||||||
max_level = max_levels[i]
|
max_level = max_levels[i]
|
||||||
|
|
||||||
stats["patk"] += stats_array[atk_ptr + 1 + i] * (max_level-1)
|
stats["patk"] += stats_array[atk_ptr + 1 + i] * (max_level-1)
|
||||||
stats["satk"] += stats_array[satk_ptr + 1 + i] * (max_level-1)
|
stats["satk"] += stats_array[satk_ptr + 1 + i] * (max_level-1)
|
||||||
stats["pdef"] += stats_array[pdef_ptr + 1 + i] * (max_level-1)
|
stats["pdef"] += stats_array[pdef_ptr + 1 + i] * (max_level-1)
|
||||||
stats["sdef"] += stats_array[sdef_ptr + 1 + i] * (max_level-1)
|
stats["sdef"] += stats_array[sdef_ptr + 1 + i] * (max_level-1)
|
||||||
stats["hp"] += stats_array[hp_ptr + 1 + i] * (max_level-1)
|
stats["hp"] += stats_array[hp_ptr + 1 + i] * (max_level-1)
|
||||||
stats["speed"] += stats_array[speed_ptr + 1 + i] * (max_level-1)
|
stats["speed"] += stats_array[speed_ptr + 1 + i] * (max_level-1)
|
||||||
|
|
||||||
if trust_percent > 0 and trustAttri != None:
|
if trust_percent > 0 and trustAttri != None:
|
||||||
if trustAttri["attribute1"] == 1001:
|
if trustAttri["attribute1"] == 1001:
|
||||||
stats["hp"] += trustAttri["attributeValue1"][trust_percent]
|
stats["hp"] += trustAttri["attributeValue1"][trust_percent]
|
||||||
elif trustAttri["attribute1"] == 1021:
|
elif trustAttri["attribute1"] == 1021:
|
||||||
stats["patk"] += trustAttri["attributeValue1"][trust_percent]
|
stats["patk"] += trustAttri["attributeValue1"][trust_percent]
|
||||||
elif trustAttri["attribute1"] == 1031:
|
elif trustAttri["attribute1"] == 1031:
|
||||||
stats["satk"] += trustAttri["attributeValue1"][trust_percent]
|
stats["satk"] += trustAttri["attributeValue1"][trust_percent]
|
||||||
else:
|
else:
|
||||||
print(trustAttri["attribute1"])
|
print(trustAttri["attribute1"])
|
||||||
|
|
||||||
if trustAttri["attribute2"] == 1001:
|
if trustAttri["attribute2"] == 1001:
|
||||||
stats["hp"] += trustAttri["attributeValue2"][trust_percent]
|
stats["hp"] += trustAttri["attributeValue2"][trust_percent]
|
||||||
elif trustAttri["attribute2"] == 1021:
|
elif trustAttri["attribute2"] == 1021:
|
||||||
stats["patk"] += trustAttri["attributeValue2"][trust_percent]
|
stats["patk"] += trustAttri["attributeValue2"][trust_percent]
|
||||||
elif trustAttri["attribute2"] == 1031:
|
elif trustAttri["attribute2"] == 1031:
|
||||||
stats["satk"] += trustAttri["attributeValue2"][trust_percent]
|
stats["satk"] += trustAttri["attributeValue2"][trust_percent]
|
||||||
else:
|
else:
|
||||||
print(trustAttri["attribute2"])
|
print(trustAttri["attribute2"])
|
||||||
|
|
||||||
stats["patk"] = int(round(stats["patk"]))
|
stats["patk"] = int(round(stats["patk"]))
|
||||||
stats["satk"] = int(round(stats["satk"]))
|
stats["satk"] = int(round(stats["satk"]))
|
||||||
stats["pdef"] = int(round(stats["pdef"]))
|
stats["pdef"] = int(round(stats["pdef"]))
|
||||||
stats["sdef"] = int(round(stats["sdef"]))
|
stats["sdef"] = int(round(stats["sdef"]))
|
||||||
stats["hp"] = int(round(stats["hp"]))
|
stats["hp"] = int(round(stats["hp"]))
|
||||||
stats["speed"] = int(round(stats["speed"]))
|
stats["speed"] = int(round(stats["speed"]))
|
||||||
|
|
||||||
return stats
|
return stats
|
||||||
|
|
||||||
def get_stat_growth(friend, awaken : int):
|
def get_stat_growth(friend, awaken : int):
|
||||||
stats_array = friend["attrScriptParam"]
|
stats_array = friend["attrScriptParam"]
|
||||||
max_awaken = friend["maxAwaken"]
|
max_awaken = friend["maxAwaken"]
|
||||||
|
|
||||||
awaken_step = max_awaken + 2
|
awaken_step = max_awaken + 2
|
||||||
|
|
||||||
atk_ptr = 1 * awaken_step
|
atk_ptr = 1 * awaken_step
|
||||||
satk_ptr = 2 * awaken_step
|
satk_ptr = 2 * awaken_step
|
||||||
pdef_ptr = 3 * awaken_step
|
pdef_ptr = 3 * awaken_step
|
||||||
sdef_ptr = 4 * awaken_step
|
sdef_ptr = 4 * awaken_step
|
||||||
hp_ptr = 5 * awaken_step
|
hp_ptr = 5 * awaken_step
|
||||||
speed_ptr = 6 * awaken_step
|
speed_ptr = 6 * awaken_step
|
||||||
|
|
||||||
stats = {}
|
stats = {}
|
||||||
i = awaken
|
i = awaken
|
||||||
stats["patk"] += stats_array[atk_ptr + 1 + i]
|
stats["patk"] += stats_array[atk_ptr + 1 + i]
|
||||||
stats["satk"] += stats_array[satk_ptr + 1 + i]
|
stats["satk"] += stats_array[satk_ptr + 1 + i]
|
||||||
stats["pdef"] += stats_array[pdef_ptr + 1 + i]
|
stats["pdef"] += stats_array[pdef_ptr + 1 + i]
|
||||||
stats["sdef"] += stats_array[sdef_ptr + 1 + i]
|
stats["sdef"] += stats_array[sdef_ptr + 1 + i]
|
||||||
stats["hp"] += stats_array[hp_ptr + 1 + i]
|
stats["hp"] += stats_array[hp_ptr + 1 + i]
|
||||||
stats["speed"] += stats_array[speed_ptr + 1 + i]
|
stats["speed"] += stats_array[speed_ptr + 1 + i]
|
||||||
|
|
||||||
return stats
|
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
|
||||||
|
|
||||||
color_tags_pattern = r"<color=#[A-Fa-f0-9]+>(.*?)<\/color>"
|
color_tags_pattern = r"<color=#[A-Fa-f0-9]+>(.*?)<\/color>"
|
||||||
output_string = re.sub(color_tags_pattern, r"\1", input_string)
|
output_string = re.sub(color_tags_pattern, r"\1", input_string)
|
||||||
|
|
||||||
link_tags_pattern = r"<link=\".*?\">(.*?)<\/link>"
|
link_tags_pattern = r"<link=\".*?\">(.*?)<\/link>"
|
||||||
output_string = re.sub(link_tags_pattern, r"\1", output_string)
|
output_string = re.sub(link_tags_pattern, r"\1", output_string)
|
||||||
|
|
||||||
return output_string
|
return output_string
|
||||||
|
|
||||||
def fill_miracle(input_string, miracle_level = 1, kemono_level = 0):
|
def fill_miracle(input_string, miracle_level = 1, kemono_level = 0):
|
||||||
if input_string is None:
|
if input_string is None:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
pattern = r"\{\{(.*?)\}\}"
|
pattern = r"\{\{(.*?)\}\}"
|
||||||
def replace_match(match):
|
def replace_match(match):
|
||||||
key : str = match.group(1).strip()
|
key : str = match.group(1).strip()
|
||||||
|
|
||||||
if key.startswith("skill | SkillDesc:"):
|
if key.startswith("skill | SkillDesc:"):
|
||||||
values = key.replace("skill | SkillDesc:", "").split(',')
|
values = key.replace("skill | SkillDesc:", "").split(',')
|
||||||
values = [float(value) for value in values]
|
values = [float(value) for value in values]
|
||||||
level_up_values = [
|
level_up_values = [
|
||||||
values[1],
|
values[1],
|
||||||
values[1],
|
values[1],
|
||||||
values[1],
|
values[1],
|
||||||
values[2],
|
values[2],
|
||||||
values[2],
|
values[2],
|
||||||
values[2],
|
values[2],
|
||||||
values[3],
|
values[3],
|
||||||
values[3],
|
values[3],
|
||||||
values[3],
|
values[3],
|
||||||
values[4],
|
values[4],
|
||||||
values[4],
|
values[4],
|
||||||
values[4],
|
values[4],
|
||||||
]
|
]
|
||||||
base_value = values[0]
|
base_value = values[0]
|
||||||
level_up_value = sum(level_up_values[0:miracle_level-1]) + values[5]
|
level_up_value = sum(level_up_values[0:miracle_level-1]) + values[5]
|
||||||
level_bonus = (kemono_level - values[7]) * values[6]
|
level_bonus = (kemono_level - values[7]) * values[6]
|
||||||
return str(math.floor(base_value + level_up_value + level_bonus))
|
return str(math.floor(base_value + level_up_value + level_bonus))
|
||||||
|
|
||||||
return "{{" + key + "}}"
|
return "{{" + key + "}}"
|
||||||
|
|
||||||
output_string = re.sub(pattern, replace_match, input_string)
|
output_string = re.sub(pattern, replace_match, input_string)
|
||||||
|
|
||||||
return clean_skill_string(output_string)
|
return clean_skill_string(output_string)
|
|
@ -1,21 +1,21 @@
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
class numeric:
|
class numeric:
|
||||||
def __init__(self, file_path:str, type:int):
|
def __init__(self, file_path:str, type:int):
|
||||||
self.indexed_data = {}
|
self.indexed_data = {}
|
||||||
with open(file_path, "rt", encoding="utf-8") as f:
|
with open(file_path, "rt", encoding="utf-8") as f:
|
||||||
if type == 0:
|
if type == 0:
|
||||||
values = json.load(f)["Data"]
|
values = json.load(f)["Data"]
|
||||||
for value in values:
|
for value in values:
|
||||||
self.indexed_data[value["sn"]] = value
|
self.indexed_data[value["sn"]] = value
|
||||||
if type == 1:
|
if type == 1:
|
||||||
values = json.load(f)
|
values = json.load(f)
|
||||||
for i in range(0, len(values["IDs"])):
|
for i in range(0, len(values["IDs"])):
|
||||||
id = values["IDs"][i]
|
id = values["IDs"][i]
|
||||||
self.indexed_data[id] = values["Data"][i]
|
self.indexed_data[id] = values["Data"][i]
|
||||||
|
|
||||||
def get(self, id):
|
def get(self, id):
|
||||||
if id not in self.indexed_data:
|
if id not in self.indexed_data:
|
||||||
return None
|
return None
|
||||||
return self.indexed_data[id]
|
return self.indexed_data[id]
|
|
@ -1,7 +1,7 @@
|
||||||
class KingdomDB:
|
class KingdomDB:
|
||||||
|
|
||||||
def __init__(self, app) -> None:
|
def __init__(self, app) -> None:
|
||||||
if "Nexon" in app.databases:
|
if "Nexon" in app.databases:
|
||||||
del app.databases["Nexon"]
|
del app.databases["Nexon"]
|
||||||
|
|
||||||
app.databases["Nexon"] = self
|
app.databases["Nexon"] = self
|
|
@ -0,0 +1,45 @@
|
||||||
|
import io
|
||||||
|
import os
|
||||||
|
import UnityPy
|
||||||
|
from UnityPy import enums
|
||||||
|
from UnityPy.files import ObjectReader
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
def convert(input_path : str, output_path : str, platform = enums.BuildTarget.WebGL, enable_read = False):
|
||||||
|
env = UnityPy.load(input_path)
|
||||||
|
|
||||||
|
for item in env.assets:
|
||||||
|
item._m_target_platform = int(platform)
|
||||||
|
|
||||||
|
for obj in env.objects:
|
||||||
|
if obj.type == enums.ClassIDType.Texture2D:
|
||||||
|
convert_texture(obj, platform)
|
||||||
|
if enable_read and obj.type == enums.ClassIDType.Mesh:
|
||||||
|
data = obj.read()
|
||||||
|
data.m_IsReadable = True
|
||||||
|
data.save()
|
||||||
|
|
||||||
|
os.makedirs(os.path.dirname(output_path), exist_ok=True)
|
||||||
|
with open(output_path, "wb") as f:
|
||||||
|
f.write(env.file.save(packer="lz4"))
|
||||||
|
|
||||||
|
def extract(input_path : str, output_path : str):
|
||||||
|
env = UnityPy.load(input_path)
|
||||||
|
|
||||||
|
for obj in env.objects:
|
||||||
|
if obj.type == enums.ClassIDType.Texture2D:
|
||||||
|
os.makedirs(output_path, exist_ok=True)
|
||||||
|
data = obj.read()
|
||||||
|
data.image.save(output_path + data.name + ".png", format="PNG")
|
||||||
|
|
||||||
|
def convert_texture(obj : ObjectReader, target_platform : enums.BuildTarget):
|
||||||
|
if target_platform == enums.BuildTarget.WebGL:
|
||||||
|
data = obj.read()
|
||||||
|
with io.BytesIO() as output:
|
||||||
|
data.image.save(output, format="PNG")
|
||||||
|
if data.image.width % 4 == 0 and data.image.height % 4 == 0:
|
||||||
|
data.m_TextureFormat = enums.TextureFormat.DXT5
|
||||||
|
else:
|
||||||
|
data.m_TextureFormat = enums.TextureFormat.ARGB32
|
||||||
|
data.image = Image.open(output)
|
||||||
|
data.save()
|
|
@ -0,0 +1,9 @@
|
||||||
|
import aiohttp
|
||||||
|
|
||||||
|
async def download_bytes(url, session : aiohttp.ClientSession):
|
||||||
|
async with session.get(url) as resp:
|
||||||
|
return await resp.read()
|
||||||
|
|
||||||
|
async def download_text(url, session : aiohttp.ClientSession):
|
||||||
|
async with session.get(url) as resp:
|
||||||
|
return await resp.text()
|
|
@ -0,0 +1,3 @@
|
||||||
|
def divide_chunks(l, n):
|
||||||
|
for i in range(0, len(l), n):
|
||||||
|
yield l[i:i + n]
|
|
@ -0,0 +1,3 @@
|
||||||
|
Flask==3.0.0
|
||||||
|
flask_restful==0.3.10
|
||||||
|
UnityPy==1.10.7
|
Loading…
Reference in New Issue