改写战斗中替换group的逻辑
This commit is contained in:
commit
7f89eb0db8
3890 changed files with 82290 additions and 0 deletions
690
auto_get_res_new.py
Normal file
690
auto_get_res_new.py
Normal file
|
@ -0,0 +1,690 @@
|
|||
import json
|
||||
import lzma
|
||||
import os
|
||||
import pickle
|
||||
import re
|
||||
from datetime import datetime
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
from skimage.feature import hog
|
||||
from sklearn.neighbors import KNeighborsClassifier
|
||||
|
||||
from mower.utils.image import cropimg, loadimg, thres2
|
||||
|
||||
|
||||
def 加载json(file_path):
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
class Arknights数据处理器:
|
||||
def __init__(self):
|
||||
self.当前时间戳 = datetime.now().timestamp()
|
||||
拼接 = "ArknightsGameResource/gamedata/excel"
|
||||
self.物品表 = 加载json(f"./{拼接}/item_table.json")
|
||||
self.干员表 = 加载json(f"./{拼接}/character_table.json")
|
||||
self.阿米娅表 = 加载json(f"./{拼接}/char_patch_table.json")
|
||||
self.抽卡表 = 加载json(f"./{拼接}/gacha_table.json")
|
||||
self.关卡表 = 加载json(f"./{拼接}/stage_table.json")
|
||||
self.活动表 = 加载json(f"./{拼接}/activity_table.json")
|
||||
self.基建表 = 加载json(f"./{拼接}/building_data.json")
|
||||
self.游戏变量 = 加载json(f"./{拼接}/gamedata_const.json")
|
||||
self.模组 = 加载json(f"./{拼接}/uniequip_table.json")
|
||||
self.装仓库物品的字典 = {"NORMAL": [], "CONSUME": [], "MATERIAL": []}
|
||||
self.常驻关卡 = 加载json("mower/data/stage_data.json")
|
||||
|
||||
self.所有buff = []
|
||||
|
||||
self.限定十连 = self.抽卡表["limitTenGachaItem"]
|
||||
self.联动十连 = self.抽卡表["linkageTenGachaItem"]
|
||||
self.普通十连 = self.抽卡表["normalGachaItem"]
|
||||
self.所有卡池 = self.限定十连 + self.联动十连 + self.普通十连
|
||||
self.总掉落表 = []
|
||||
|
||||
def 添加物品至前端文件(self):
|
||||
"""和 数据处理器.输出_活动关卡和掉落() 有联动 , 读取活动关卡提供了额外的图片 活动代币"""
|
||||
|
||||
def 检查图标代码匹配(目标图标代码, 物品类型, 分类类型, 排序代码):
|
||||
匹配结果 = False
|
||||
for 池子限时物品 in self.所有卡池:
|
||||
if (
|
||||
池子限时物品["itemId"] == 目标图标代码
|
||||
and self.当前时间戳 > 池子限时物品["endTime"]
|
||||
):
|
||||
匹配结果 = True
|
||||
break
|
||||
分割部分 = 目标图标代码.split("_")
|
||||
if len(分割部分) == 2 and 分割部分[0].endswith("recruitment10"):
|
||||
匹配结果 = True
|
||||
if len(分割部分) == 6 and int(分割部分[5]) < 2023:
|
||||
匹配结果 = True
|
||||
|
||||
if len(分割部分) == 3 and 目标图标代码.startswith("uni"):
|
||||
匹配结果 = True
|
||||
|
||||
if len(分割部分) == 3 and 目标图标代码.startswith("voucher_full"):
|
||||
匹配结果 = True
|
||||
if 目标图标代码 == "ap_supply_lt_60":
|
||||
匹配结果 = True
|
||||
抽卡 = self.抽卡表.get("gachaPoolClient", [])
|
||||
for 卡池 in 抽卡:
|
||||
if 卡池["LMTGSID"] == 目标图标代码 and self.当前时间戳 > int(
|
||||
卡池["endTime"]
|
||||
):
|
||||
匹配结果 = True
|
||||
if 分类类型 == "NONE":
|
||||
匹配结果 = True
|
||||
if 排序代码 <= 0:
|
||||
匹配结果 = True
|
||||
if 分类类型 == "NONE":
|
||||
for item in self.总掉落表:
|
||||
if 目标图标代码 == item["id"]:
|
||||
匹配结果 = False
|
||||
return 匹配结果
|
||||
|
||||
self.物品_名称_输出用 = {}
|
||||
self.物品_名称_模型用 = {}
|
||||
if not os.path.exists("./ui/public/depot/EXP.webp"):
|
||||
png_image = Image.open("./ArknightsGameResource/item/EXP_PLAYER.png")
|
||||
png_image.save("./ui/public/depot/EXP.webp", "WEBP")
|
||||
for 物品代码, 物品数据 in self.物品表["items"].items():
|
||||
中文名称 = 物品数据.get("name", "")
|
||||
图标代码 = 物品数据.get("iconId", "")
|
||||
排序代码 = 物品数据.get("sortId", "")
|
||||
分类类型 = 物品数据.get("classifyType", "")
|
||||
物品类型 = 物品数据.get("itemType", "")
|
||||
源文件路径 = f"./ArknightsGameResource/item/{图标代码}.png"
|
||||
排除开关 = False
|
||||
排除开关 = 检查图标代码匹配(图标代码, 物品类型, 分类类型, 排序代码)
|
||||
if not 排除开关:
|
||||
if os.path.exists(源文件路径):
|
||||
目标文件路径 = f"./ui/public/depot/{中文名称}.webp"
|
||||
if not os.path.exists(目标文件路径):
|
||||
png_image = Image.open(源文件路径)
|
||||
png_image.save(目标文件路径, "WEBP")
|
||||
if 分类类型 != "NONE":
|
||||
self.装仓库物品的字典[分类类型].append(
|
||||
[目标文件路径, 源文件路径]
|
||||
)
|
||||
templist = [物品代码, 图标代码, 中文名称, 分类类型, 排序代码]
|
||||
self.物品_名称_输出用[物品代码] = templist
|
||||
self.物品_名称_模型用[中文名称] = templist
|
||||
self.物品_名称_模型用[物品代码] = templist
|
||||
print(f"复制 {源文件路径} 到 {目标文件路径}")
|
||||
with open("./mower/data/key_mapping.json", "w", encoding="utf8") as json_file:
|
||||
json.dump(self.物品_名称_输出用, json_file, ensure_ascii=False, indent=4)
|
||||
print()
|
||||
|
||||
def 干员列表(self):
|
||||
"""读取干员列表并输出至./mower/data/agent.json"""
|
||||
干员_名称列表 = {}
|
||||
for 干员代码, 干员数据 in self.干员表.items():
|
||||
if not 干员数据["itemObtainApproach"]:
|
||||
continue
|
||||
干员名 = 干员数据["name"]
|
||||
干员_名称列表[干员名] = {
|
||||
"key": 干员代码,
|
||||
"profession": 干员数据["profession"],
|
||||
}
|
||||
干员头像路径 = f"./ArknightsGameResource/avatar/{干员代码}.png"
|
||||
目标路径 = f"./ui/public/avatar/{干员数据['name']}.webp"
|
||||
print(f"{干员名}: {干员代码}")
|
||||
|
||||
png_image = Image.open(干员头像路径)
|
||||
png_image.save(目标路径, "WEBP")
|
||||
干员_名称列表 = dict(sorted(干员_名称列表.items()))
|
||||
with open("./mower/data/agent.json", "w", encoding="utf-8") as f:
|
||||
json.dump(干员_名称列表, f, ensure_ascii=False, indent=4)
|
||||
|
||||
def 读取卡池(self):
|
||||
"""读取当前开放的卡池,暂无输出"""
|
||||
抽卡 = self.抽卡表.get("gachaPoolClient", [])
|
||||
卡池类型映射 = {
|
||||
"SINGLE": "单人池",
|
||||
"LIMITED": "限定池",
|
||||
"NORM": "普通池",
|
||||
"CLASSIC": "中坚池",
|
||||
"CLASSIC_ATTAIN": "跨年中坚池",
|
||||
"LINKAGE": "联动池",
|
||||
"ATTAIN": "跨年池",
|
||||
"FESCLASSIC": "中坚甄选",
|
||||
}
|
||||
|
||||
for 项 in 抽卡:
|
||||
卡池名称 = 项.get("gachaPoolName")
|
||||
开始时间戳 = 项.get("openTime")
|
||||
结束时间戳 = 项.get("endTime")
|
||||
卡池类型代码 = 项.get("gachaPoolId")
|
||||
卡池出人 = 项.get("dynMeta")
|
||||
|
||||
if self.当前时间戳 < 结束时间戳:
|
||||
卡池类型 = 卡池类型映射.get(卡池类型代码.split("_")[0], 卡池类型代码)
|
||||
if 卡池类型代码.split("_")[1] == "ATTAIN":
|
||||
卡池类型 = "跨年中坚池"
|
||||
if 卡池名称 == "适合多种场合的强力干员":
|
||||
卡池名称 = 卡池类型
|
||||
开始时间 = datetime.fromtimestamp(开始时间戳)
|
||||
结束时间 = datetime.fromtimestamp(结束时间戳 + 1)
|
||||
print("卡池名称:", 卡池名称)
|
||||
print("卡池类型:", 卡池类型)
|
||||
if 卡池类型 == "中坚池":
|
||||
print(
|
||||
卡池出人["main6RarityCharId"],
|
||||
卡池出人["sub6RarityCharId"],
|
||||
卡池出人["rare5CharList"],
|
||||
)
|
||||
if self.当前时间戳 > 开始时间戳:
|
||||
print("正在进行")
|
||||
print("卡池结束时间:", 结束时间)
|
||||
else:
|
||||
print("卡池开始时间:", 开始时间)
|
||||
print("卡池结束时间:", 结束时间)
|
||||
print(卡池类型代码)
|
||||
print()
|
||||
|
||||
def 输出_活动关卡和掉落(self):
|
||||
"""读取活动关卡及掉落物并写入./ui/src/pages/stage_data/event_data.json"""
|
||||
关卡 = self.关卡表["stageValidInfo"]
|
||||
还未结束的非常驻关卡 = {
|
||||
键: 值
|
||||
for 键, 值 in 关卡.items()
|
||||
if 值["endTs"] != -1 and 值["endTs"] > self.当前时间戳
|
||||
}
|
||||
还未结束的非常驻关卡 = dict(sorted(还未结束的非常驻关卡.items()))
|
||||
for 键, _ in 还未结束的非常驻关卡.items():
|
||||
关卡代码 = self.关卡表["stages"][键]["code"]
|
||||
if 键.endswith("#f#"):
|
||||
关卡代码 += " 突袭"
|
||||
关卡名称 = self.关卡表["stages"][键]["name"]
|
||||
关卡结束时间戳 = 还未结束的非常驻关卡[键]["endTs"]
|
||||
关卡消耗理智 = self.关卡表["stages"][键]["apCost"]
|
||||
# 关卡结束时间 = datetime.fromtimestamp(还未结束的非常驻关卡[键]["endTs"] + 1)
|
||||
关卡掉落表 = self.关卡表["stages"][键]["stageDropInfo"][
|
||||
"displayDetailRewards"
|
||||
]
|
||||
self.总掉落表.extend(关卡掉落表)
|
||||
关卡掉落 = {}
|
||||
突袭首次掉落 = [
|
||||
self.物品表.get("items", {}).get(item["id"], {}).get("name", item["id"])
|
||||
for item in 关卡掉落表
|
||||
if item["dropType"] == 1
|
||||
]
|
||||
常规掉落 = [
|
||||
self.物品表.get("items", {}).get(item["id"], {}).get("name", item["id"])
|
||||
for item in 关卡掉落表
|
||||
if item["dropType"] == 2
|
||||
]
|
||||
特殊掉落 = [
|
||||
self.物品表.get("items", {}).get(item["id"], {}).get("name", item["id"])
|
||||
for item in 关卡掉落表
|
||||
if item["dropType"] == 3
|
||||
]
|
||||
额外物资 = [
|
||||
self.物品表.get("items", {}).get(item["id"], {}).get("name", item["id"])
|
||||
for item in 关卡掉落表
|
||||
if item["dropType"] == 4
|
||||
]
|
||||
首次掉落 = [
|
||||
self.物品表.get("items", {}).get(item["id"], {}).get("name", item["id"])
|
||||
for item in 关卡掉落表
|
||||
if item["dropType"] == 8
|
||||
]
|
||||
关卡掉落 = {
|
||||
"突袭首次掉落": 突袭首次掉落,
|
||||
"常规掉落": 常规掉落,
|
||||
"首次掉落": 首次掉落,
|
||||
"特殊掉落": 特殊掉落,
|
||||
"额外物资": 额外物资,
|
||||
}
|
||||
|
||||
self.常驻关卡.append(
|
||||
{
|
||||
"id": 关卡代码,
|
||||
"name": 关卡名称,
|
||||
"drop": 关卡掉落,
|
||||
"end": 关卡结束时间戳,
|
||||
"理智消耗": 关卡消耗理智,
|
||||
"周一": 1,
|
||||
"周二": 1,
|
||||
"周三": 1,
|
||||
"周四": 1,
|
||||
"周五": 1,
|
||||
"周六": 1,
|
||||
"周日": 1,
|
||||
}
|
||||
)
|
||||
unkey = 0
|
||||
for item in self.常驻关卡:
|
||||
item["key"] = unkey
|
||||
unkey += 1
|
||||
with open(
|
||||
"./ui/src/pages/stage_data/event_data.json", "w", encoding="utf-8"
|
||||
) as f:
|
||||
json.dump(self.常驻关卡, f, ensure_ascii=False, indent=4)
|
||||
|
||||
def load_recruit_data(self):
|
||||
recruit_data = {}
|
||||
recruit_result_data = {
|
||||
4: [],
|
||||
3: [],
|
||||
2: [],
|
||||
1: [],
|
||||
-1: [],
|
||||
}
|
||||
# for 干员代码, 干员数据 in self.干员表.items():
|
||||
# print(干员代码,干员数据)
|
||||
recruit_list = self.抽卡表["recruitDetail"].replace("\\n<@rc.eml>", "")
|
||||
recruit_list = recruit_list.replace("\\n", "")
|
||||
recruit_list = recruit_list.replace("\r", "")
|
||||
recruit_list = recruit_list.replace("★", "")
|
||||
recruit_list = recruit_list.replace("<@rc.eml>", "")
|
||||
recruit_list = recruit_list.replace("</>", "")
|
||||
recruit_list = recruit_list.replace("/", "")
|
||||
recruit_list = recruit_list.replace(" ", "\n")
|
||||
recruit_list = recruit_list.replace("--------------------", "")
|
||||
recruit_list = recruit_list.replace("<@rc.title>公开招募说明", "")
|
||||
recruit_list = recruit_list.replace("<@rc.em>※稀有职业需求招募说明※", "")
|
||||
recruit_list = recruit_list.replace(
|
||||
"<@rc.em>当职业需求包含高级资深干员,且招募时限为9小时时,招募必得6星干员",
|
||||
"",
|
||||
)
|
||||
recruit_list = recruit_list.replace(
|
||||
"<@rc.em>当职业需求包含资深干员同时不包含高级资深干员,且招募时限为9小时,则该次招募必得5星干员",
|
||||
"",
|
||||
)
|
||||
recruit_list = recruit_list.replace("<@rc.subtitle>※全部可能出现的干员※", "")
|
||||
recruit_list = recruit_list.replace("绿色高亮的不可寻访干员,可以在此招募", "")
|
||||
recruit_list = recruit_list.split("\n")
|
||||
|
||||
profession = {
|
||||
"MEDIC": "医疗干员",
|
||||
"WARRIOR": "近卫干员",
|
||||
"SPECIAL": "特种干员",
|
||||
"SNIPER": "狙击干员",
|
||||
"CASTER": "术师干员",
|
||||
"TANK": "重装干员",
|
||||
"SUPPORT": "辅助干员",
|
||||
"PIONEER": "先锋干员",
|
||||
}
|
||||
|
||||
for 干员代码, 干员数据 in self.干员表.items():
|
||||
干员名 = 干员数据["name"]
|
||||
|
||||
if 干员数据["profession"] not in profession:
|
||||
continue
|
||||
|
||||
if 干员名 in recruit_list:
|
||||
tag = 干员数据["tagList"]
|
||||
# 数据中稀有度从0-5
|
||||
干员数据["rarity"] = 干员数据["rarity"] + 1
|
||||
if len(干员名) <= 4:
|
||||
recruit_result_data[len(干员名)].append(干员代码)
|
||||
else:
|
||||
recruit_result_data[-1].append(干员代码)
|
||||
if 干员数据["rarity"] == 5:
|
||||
tag.append("资深干员")
|
||||
elif 干员数据["rarity"] == 6:
|
||||
tag.append("高级资深干员")
|
||||
|
||||
if 干员数据["position"] == "MELEE":
|
||||
tag.append("近战位")
|
||||
elif 干员数据["position"] == "RANGED":
|
||||
tag.append("远程位")
|
||||
|
||||
tag.append(profession[干员数据["profession"]])
|
||||
|
||||
recruit_data[干员代码] = {
|
||||
"name": 干员名,
|
||||
"stars": 干员数据["rarity"],
|
||||
"tags": 干员数据["tagList"],
|
||||
}
|
||||
print(
|
||||
"{} stars:{} tags:{}".format(
|
||||
干员名, 干员数据["rarity"], 干员数据["tagList"]
|
||||
)
|
||||
)
|
||||
print("载入公招干员数据{}个".format(len(recruit_data)))
|
||||
with open("./mower/data/recruit.json", "w", encoding="utf-8") as f:
|
||||
json.dump(recruit_data, f, ensure_ascii=False, indent=4)
|
||||
|
||||
with open("./mower/data/recruit_result.json", "w", encoding="utf-8") as f:
|
||||
json.dump(recruit_result_data, f, ensure_ascii=False, indent=4)
|
||||
|
||||
def load_recruit_template(self):
|
||||
# !/usr/bin/env python3
|
||||
template = {}
|
||||
with open("./mower/data/recruit.json", "r", encoding="utf-8") as f:
|
||||
recruit_operators = json.load(f)
|
||||
|
||||
font = ImageFont.truetype("FZDYSK.TTF", 120)
|
||||
print(len(recruit_operators))
|
||||
for operator in recruit_operators:
|
||||
im = Image.new(mode="RGBA", size=(1920, 1080))
|
||||
draw = ImageDraw.Draw(im)
|
||||
draw.text((0, 0), recruit_operators[operator]["name"], font=font)
|
||||
im = im.crop(im.getbbox())
|
||||
im = cv2.cvtColor(np.asarray(im), cv2.COLOR_RGB2GRAY)
|
||||
im = cv2.erode(im, np.ones((5, 5)))
|
||||
template[operator] = im
|
||||
|
||||
with lzma.open("mower/models/recruit_result.pkl", "wb") as f:
|
||||
pickle.dump(template, f)
|
||||
|
||||
def load_recruit_tag(self):
|
||||
with open("./mower/data/recruit.json", "r", encoding="utf-8") as f:
|
||||
recruit_agent = json.load(f)
|
||||
|
||||
font = ImageFont.truetype("mower/fonts/SourceHanSansCN-Medium.otf", 30)
|
||||
recruit_tag = ["资深干员", "高级资深干员"]
|
||||
recruit_tag_template = {}
|
||||
for x in recruit_agent.values():
|
||||
recruit_tag += x["tags"]
|
||||
recruit_tag = list(set(recruit_tag))
|
||||
for tag in sorted(recruit_tag):
|
||||
im = Image.new(mode="RGBA", color=(49, 49, 49), size=(215, 70))
|
||||
W, H = im.size
|
||||
draw = ImageDraw.Draw(im)
|
||||
_, _, w, h = draw.textbbox((0, 0), tag, font=font)
|
||||
draw.text(((W - w) / 2, (H - h) / 2 - 5), tag, font=font)
|
||||
recruit_tag_template[tag] = cv2.cvtColor(
|
||||
np.array(im.crop(im.getbbox())), cv2.COLOR_RGB2BGR
|
||||
)
|
||||
with lzma.open("./mower/models/recruit.pkl", "wb") as f:
|
||||
pickle.dump(recruit_tag_template, f)
|
||||
|
||||
def 输出_公招资源(self):
|
||||
self.load_recruit_data()
|
||||
self.load_recruit_template()
|
||||
self.load_recruit_tag()
|
||||
|
||||
def 训练仓库的knn模型(self, 模板文件夹, 模型保存路径):
|
||||
def 提取特征点(模板):
|
||||
模板 = 模板[40:173, 40:173]
|
||||
hog_features = hog(
|
||||
模板,
|
||||
orientations=18,
|
||||
pixels_per_cell=(8, 8),
|
||||
cells_per_block=(2, 2),
|
||||
block_norm="L2-Hys",
|
||||
transform_sqrt=True,
|
||||
channel_axis=2,
|
||||
)
|
||||
|
||||
return hog_features
|
||||
|
||||
def 加载图片特征点_标签(模板类型):
|
||||
特征点列表 = []
|
||||
标签列表 = []
|
||||
for [目标文件路径, 源文件路径] in self.装仓库物品的字典[模板类型]:
|
||||
模板 = cv2.imread(源文件路径)
|
||||
模板 = cv2.resize(模板, (213, 213))
|
||||
特征点 = 提取特征点(模板)
|
||||
特征点列表.append(特征点)
|
||||
标签列表.append(self.物品_名称_模型用[目标文件路径[18:-5]][2])
|
||||
return 特征点列表, 标签列表
|
||||
|
||||
def 训练knn模型(images, labels):
|
||||
knn_classifier = KNeighborsClassifier(
|
||||
weights="distance", n_neighbors=1, n_jobs=1
|
||||
)
|
||||
knn_classifier.fit(images, labels)
|
||||
return knn_classifier
|
||||
|
||||
def 保存knn模型(classifier, filename):
|
||||
with lzma.open(filename, "wb") as f:
|
||||
pickle.dump(classifier, f)
|
||||
|
||||
模板特征点, 模板标签 = 加载图片特征点_标签(模板文件夹)
|
||||
knn模型 = 训练knn模型(模板特征点, 模板标签)
|
||||
保存knn模型(knn模型, 模型保存路径)
|
||||
|
||||
def 输出_扫仓库模型(self):
|
||||
"""输出扫描仓库的Knn模型
|
||||
|
||||
和添加物品至前端文件() 有联动 , 添加物品提供了分类的图片位置"""
|
||||
|
||||
self.训练仓库的knn模型("NORMAL", "./mower/models/NORMAL.pkl")
|
||||
self.训练仓库的knn模型("CONSUME", "./mower/models/CONSUME.pkl")
|
||||
self.训练仓库的knn模型("MATERIAL", "./mower/models/MATERIAL.pkl")
|
||||
|
||||
def 输出_在房间内的干员名的模型(self):
|
||||
font = ImageFont.truetype("mower/fonts/SourceHanSansCN-Medium.otf", 37)
|
||||
|
||||
data = {}
|
||||
|
||||
kernel = np.ones((12, 12), np.uint8)
|
||||
|
||||
with open("./mower/data/agent.json", "r", encoding="utf-8") as f:
|
||||
agent_list = json.load(f)
|
||||
for operator in sorted(agent_list, key=lambda x: len(x), reverse=True):
|
||||
img = Image.new(mode="L", size=(400, 100))
|
||||
draw = ImageDraw.Draw(img)
|
||||
draw.text((50, 20), operator, fill=(255,), font=font)
|
||||
img = np.array(img, dtype=np.uint8)
|
||||
img = thres2(img, 200)
|
||||
dilation = cv2.dilate(img, kernel, iterations=1)
|
||||
contours, _ = cv2.findContours(
|
||||
dilation, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE
|
||||
)
|
||||
rect = map(lambda c: cv2.boundingRect(c), contours)
|
||||
x, y, w, h = sorted(rect, key=lambda c: c[0])[0]
|
||||
img = img[y : y + h, x : x + w]
|
||||
tpl = np.zeros((46, 265), dtype=np.uint8)
|
||||
tpl[: img.shape[0], : img.shape[1]] = img
|
||||
# cv2.imwrite(f"/home/zhao/Desktop/data/{operator}.png", tpl)
|
||||
data[operator] = tpl
|
||||
|
||||
with lzma.open("mower/models/operator_room.model", "wb") as f:
|
||||
pickle.dump(data, f)
|
||||
|
||||
def avatar_and_portrait(self):
|
||||
mapping = {} # char_285_medic2 -> Lancet-2
|
||||
for name, data in self.干员表.items():
|
||||
mapping[name] = data["name"]
|
||||
for name in self.阿米娅表["infos"]["char_002_amiya"]["tmplIds"]:
|
||||
mapping[name] = "阿米娅"
|
||||
|
||||
def extract(name, bg, crop):
|
||||
data = {}
|
||||
data_path = f"./ArknightsGameResource/{name}"
|
||||
ORB = cv2.ORB_create(nfeatures=50, edgeThreshold=0, nlevels=1)
|
||||
for i in os.listdir(data_path):
|
||||
# i: char_285_medic2.png
|
||||
for j, k in mapping.items():
|
||||
# j: char_285_medic2
|
||||
# k: Lancet-2
|
||||
if i.startswith(j):
|
||||
img = loadimg(os.path.join(data_path, i), True, bg)
|
||||
if crop is not None:
|
||||
img = cropimg(img, crop)
|
||||
kp, des = ORB.detectAndCompute(img, None)
|
||||
if k not in data:
|
||||
data[k] = []
|
||||
data[k].append(des)
|
||||
break
|
||||
with lzma.open(f"./mower/models/{name}.pkl", "wb") as f:
|
||||
pickle.dump(data, f)
|
||||
|
||||
extract("avatar", "BLACK", None)
|
||||
extract("portrait", (140, 140, 140, 255), ((0, 85), (180, 195)))
|
||||
|
||||
def 获得干员基建描述(self):
|
||||
buff描述 = self.基建表["buffs"]
|
||||
buff_table = {}
|
||||
for buff名称, 相关buff in buff描述.items():
|
||||
buff_table[buff名称] = [
|
||||
相关buff["buffName"],
|
||||
相关buff["description"],
|
||||
相关buff["roomType"],
|
||||
相关buff["buffCategory"],
|
||||
相关buff["skillIcon"],
|
||||
相关buff["buffColor"],
|
||||
相关buff["textColor"],
|
||||
]
|
||||
|
||||
干员技能列表 = []
|
||||
|
||||
name_key = 0
|
||||
for 角色id, 相关buff in self.基建表["chars"].items():
|
||||
干员技能字典 = {
|
||||
"key": 0,
|
||||
"name": "",
|
||||
"span": 0,
|
||||
"child_skill": [],
|
||||
}
|
||||
|
||||
干员技能字典["name"] = self.干员表[角色id]["name"]
|
||||
|
||||
skill_key = 0
|
||||
name_key += 1
|
||||
干员技能字典["key"] = name_key
|
||||
for item in 相关buff["buffChar"]:
|
||||
skill_level = 0
|
||||
|
||||
if item["buffData"] != []:
|
||||
for item2 in item["buffData"]:
|
||||
干员技能详情 = {}
|
||||
|
||||
干员技能详情["skill_key"] = skill_key
|
||||
干员技能详情["skill_level"] = skill_level
|
||||
skill_level += 1
|
||||
干员技能详情["phase_level"] = (
|
||||
f'精{item2["cond"]["phase"]} {item2["cond"]["level"]}级'
|
||||
)
|
||||
干员技能详情["skillname"] = buff_table[item2["buffId"]][0]
|
||||
text = buff_table[item2["buffId"]][1]
|
||||
pattern = r"<\$(.*?)>"
|
||||
matches = re.findall(pattern, text)
|
||||
ex_string = []
|
||||
干员技能详情["buffer"] = False
|
||||
干员技能详情["buffer_des"] = []
|
||||
if matches:
|
||||
干员技能详情["buffer"] = True
|
||||
ex_string = list(
|
||||
set([match.replace(".", "_") for match in matches])
|
||||
)
|
||||
ex_string.sort()
|
||||
干员技能详情["buffer_des"] = ex_string
|
||||
self.所有buff.extend(ex_string)
|
||||
|
||||
干员技能详情["des"] = text
|
||||
干员技能详情["roomType"] = roomType[
|
||||
buff_table[item2["buffId"]][2]
|
||||
]
|
||||
干员技能详情["buffCategory"] = buff_table[item2["buffId"]][3]
|
||||
干员技能详情["skillIcon"] = buff_table[item2["buffId"]][4]
|
||||
干员技能详情["buffColor"] = buff_table[item2["buffId"]][5]
|
||||
干员技能详情["textColor"] = buff_table[item2["buffId"]][6]
|
||||
|
||||
干员技能字典["child_skill"].append(干员技能详情)
|
||||
|
||||
干员技能详情 = []
|
||||
干员技能字典["span"] = len(干员技能字典["child_skill"])
|
||||
skill_key += 1
|
||||
干员技能列表.append(干员技能字典.copy())
|
||||
干员技能列表 = sorted(干员技能列表, key=lambda x: (-x["key"]))
|
||||
# print(干员技能列表)
|
||||
with open(
|
||||
"./ui/src/pages/basement_skill/skill.json", "w", encoding="utf-8"
|
||||
) as f:
|
||||
json.dump(干员技能列表, f, ensure_ascii=False, indent=4)
|
||||
|
||||
def 转换输出基建buff(self):
|
||||
buff_table = {}
|
||||
pattern = r"<\$(.*?)>"
|
||||
|
||||
for item in self.游戏变量["termDescriptionDict"]:
|
||||
matches = re.findall(
|
||||
pattern, self.游戏变量["termDescriptionDict"][item]["description"]
|
||||
)
|
||||
matches = [match.replace(".", "_") for match in matches]
|
||||
dict1 = self.游戏变量["termDescriptionDict"][item]
|
||||
dict1["buffer"] = []
|
||||
if item.startswith("cc") and matches:
|
||||
dict1["buffer"] = matches
|
||||
buff_table[item.replace(".", "_")] = dict1
|
||||
|
||||
with open(
|
||||
"./ui/src/pages/basement_skill/buffer.json", "w", encoding="utf-8"
|
||||
) as f:
|
||||
json.dump(buff_table, f, ensure_ascii=False, indent=4)
|
||||
|
||||
def 添加基建技能图标(self):
|
||||
# 源目录和目标目录
|
||||
source_dir = "./ArknightsGameResource/building_skill"
|
||||
destination_dir = "./ui/public/building_skill"
|
||||
|
||||
# 创建目标目录(如果不存在)
|
||||
os.makedirs(destination_dir, exist_ok=True)
|
||||
# 遍历源目录中的所有文件
|
||||
for root, dirs, files in os.walk(source_dir):
|
||||
for file in files:
|
||||
if file.endswith(".png"):
|
||||
src_file_path = os.path.join(root, file)
|
||||
# 修改文件扩展名为 .webp
|
||||
dest_file_name = os.path.splitext(file)[0] + ".webp"
|
||||
dest_file_path = os.path.join(destination_dir, dest_file_name)
|
||||
if not os.path.exists(dest_file_path):
|
||||
with Image.open(src_file_path) as img:
|
||||
img.save(dest_file_path, "webp")
|
||||
print(f"转换: {src_file_path} 到 {dest_file_path}")
|
||||
else:
|
||||
print(f"跳过: {dest_file_path} 已存在")
|
||||
|
||||
def 输出_前端基建资源(self):
|
||||
self.获得干员基建描述()
|
||||
self.转换输出基建buff()
|
||||
self.添加基建技能图标()
|
||||
|
||||
def levels(self):
|
||||
levels_json = 加载json("./ArknightsGameResource/levels.json")
|
||||
with lzma.open("mower/models/levels.pkl", "wb") as f:
|
||||
pickle.dump(levels_json, f)
|
||||
|
||||
def 读取模组(self):
|
||||
_ = []
|
||||
for item in self.模组["missionList"]:
|
||||
_.append(self.模组["missionList"][item]["template"])
|
||||
template_list = list({}.fromkeys(_).keys())
|
||||
print(template_list)
|
||||
|
||||
|
||||
roomType = {
|
||||
"POWER": "发电站",
|
||||
"DORMITORY": "宿舍",
|
||||
"MANUFACTURE": "制造站",
|
||||
"MEETING": "会客室",
|
||||
"WORKSHOP": "加工站",
|
||||
"TRADING": "贸易站",
|
||||
"HIRE": "人力办公室",
|
||||
"TRAINING": "训练室",
|
||||
"CONTROL": "中枢",
|
||||
}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
数据处理器 = Arknights数据处理器()
|
||||
|
||||
数据处理器.干员列表()
|
||||
|
||||
数据处理器.读取卡池()
|
||||
|
||||
数据处理器.输出_活动关卡和掉落()
|
||||
|
||||
数据处理器.添加物品至前端文件() # 显示在仓库里的物品
|
||||
|
||||
数据处理器.输出_扫仓库模型()
|
||||
|
||||
数据处理器.输出_在房间内的干员名的模型()
|
||||
|
||||
数据处理器.avatar_and_portrait()
|
||||
|
||||
数据处理器.输出_前端基建资源()
|
||||
|
||||
数据处理器.输出_公招资源()
|
||||
|
||||
数据处理器.levels()
|
||||
|
||||
数据处理器.读取模组()
|
Loading…
Add table
Add a link
Reference in a new issue