mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2026-10-10 06:10:01 +08:00
Add files via upload
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
import random
|
||||
from lxml import etree
|
||||
from typing import List, Tuple
|
||||
from PIL import ImageDraw
|
||||
from nonebot.log import logger
|
||||
|
||||
try:
|
||||
import ujson as json
|
||||
except ModuleNotFoundError:
|
||||
import json
|
||||
|
||||
from .base_handle import BaseHandle, BaseData
|
||||
from ..config import draw_config
|
||||
from ..util import remove_prohibited_str, cn2py, load_font
|
||||
from utils.image_utils import BuildImage
|
||||
|
||||
|
||||
class FgoData(BaseData):
|
||||
pass
|
||||
|
||||
|
||||
class FgoChar(FgoData):
|
||||
pass
|
||||
|
||||
|
||||
class FgoCard(FgoData):
|
||||
pass
|
||||
|
||||
|
||||
class FgoHandle(BaseHandle[FgoData]):
|
||||
def __init__(self):
|
||||
super().__init__("fgo", "命运-冠位指定")
|
||||
self.data_files.append("fgo_card.json")
|
||||
self.max_star = 5
|
||||
self.config = draw_config.fgo
|
||||
self.ALL_CHAR: List[FgoChar] = []
|
||||
self.ALL_CARD: List[FgoCard] = []
|
||||
|
||||
def get_card(self, mode: int = 1) -> FgoData:
|
||||
if mode == 1:
|
||||
star = self.get_star(
|
||||
[8, 7, 6, 5, 4, 3],
|
||||
[
|
||||
self.config.FGO_SERVANT_FIVE_P,
|
||||
self.config.FGO_SERVANT_FOUR_P,
|
||||
self.config.FGO_SERVANT_THREE_P,
|
||||
self.config.FGO_CARD_FIVE_P,
|
||||
self.config.FGO_CARD_FOUR_P,
|
||||
self.config.FGO_CARD_THREE_P,
|
||||
],
|
||||
)
|
||||
elif mode == 2:
|
||||
star = self.get_star(
|
||||
[5, 4], [self.config.FGO_CARD_FIVE_P, self.config.FGO_CARD_FOUR_P]
|
||||
)
|
||||
else:
|
||||
star = self.get_star(
|
||||
[8, 7, 6],
|
||||
[
|
||||
self.config.FGO_SERVANT_FIVE_P,
|
||||
self.config.FGO_SERVANT_FOUR_P,
|
||||
self.config.FGO_SERVANT_THREE_P,
|
||||
],
|
||||
)
|
||||
if star > 5:
|
||||
star -= 3
|
||||
chars = [x for x in self.ALL_CHAR if x.star == star and not x.limited]
|
||||
else:
|
||||
chars = [x for x in self.ALL_CARD if x.star == star and not x.limited]
|
||||
return random.choice(chars)
|
||||
|
||||
def get_cards(self, count: int, **kwargs) -> List[Tuple[FgoData, int]]:
|
||||
card_list = [] # 获取所有角色
|
||||
servant_count = 0 # 保底计算
|
||||
card_count = 0 # 保底计算
|
||||
for i in range(count):
|
||||
servant_count += 1
|
||||
card_count += 1
|
||||
if card_count == 9: # 四星卡片保底
|
||||
mode = 2
|
||||
elif servant_count == 10: # 三星从者保底
|
||||
mode = 3
|
||||
else: # 普通抽
|
||||
mode = 1
|
||||
card = self.get_card(mode)
|
||||
if isinstance(card, FgoCard) and card.star > self.max_star - 2:
|
||||
card_count = 0
|
||||
if isinstance(card, FgoChar):
|
||||
servant_count = 0
|
||||
card_list.append((card, i + 1))
|
||||
return card_list
|
||||
|
||||
def generate_card_img(self, card: FgoData) -> BuildImage:
|
||||
sep_w = 5
|
||||
sep_t = 5
|
||||
sep_b = 20
|
||||
w = 128
|
||||
h = 140
|
||||
bg = BuildImage(w + sep_w * 2, h + sep_t + sep_b)
|
||||
img_path = str(self.img_path / f"{cn2py(card.name)}.png")
|
||||
img = BuildImage(w, h, background=img_path)
|
||||
bg.paste(img, (sep_w, sep_t), alpha=True)
|
||||
# 加名字
|
||||
text = card.name[:6] + "..." if len(card.name) > 7 else card.name
|
||||
font = load_font(fontsize=16)
|
||||
text_w, text_h = font.getsize(text)
|
||||
draw = ImageDraw.Draw(bg.markImg)
|
||||
draw.text(
|
||||
(sep_w + (w - text_w) / 2, h + sep_t + (sep_b - text_h) / 2),
|
||||
text,
|
||||
font=font,
|
||||
fill="gray",
|
||||
)
|
||||
return bg
|
||||
|
||||
def _init_data(self):
|
||||
self.ALL_CHAR = [
|
||||
FgoChar(
|
||||
name=value["名称"],
|
||||
star=int(value["星级"]),
|
||||
limited=True
|
||||
if not ("圣晶石召唤" in value["入手方式"] or "圣晶石召唤(Story卡池)" in value["入手方式"])
|
||||
else False,
|
||||
)
|
||||
for value in self.load_data().values()
|
||||
]
|
||||
self.ALL_CARD = [
|
||||
FgoCard(name=value["名称"], star=int(value["星级"]), limited=False)
|
||||
for value in self.load_data("fgo_card.json").values()
|
||||
]
|
||||
|
||||
async def _update_info(self):
|
||||
# fgo.json
|
||||
fgo_info = {}
|
||||
for i in range(500):
|
||||
url = f"http://fgo.vgtime.com/servant/ajax?card=&wd=&ids=&sort=12777&o=desc&pn={i}"
|
||||
result = await self.get_url(url)
|
||||
if not result:
|
||||
logger.warning(f"更新 {self.game_name_cn} page {i} 出错")
|
||||
continue
|
||||
fgo_data = json.loads(result)
|
||||
if int(fgo_data["nums"]) <= 0:
|
||||
break
|
||||
for x in fgo_data["data"]:
|
||||
name = remove_prohibited_str(x["name"])
|
||||
member_dict = {
|
||||
"id": x["id"],
|
||||
"card_id": x["charid"],
|
||||
"头像": x["icon"],
|
||||
"名称": remove_prohibited_str(x["name"]),
|
||||
"职阶": x["classes"],
|
||||
"星级": int(x["star"]),
|
||||
"hp": x["lvmax4hp"],
|
||||
"atk": x["lvmax4atk"],
|
||||
"card_quick": x["cardquick"],
|
||||
"card_arts": x["cardarts"],
|
||||
"card_buster": x["cardbuster"],
|
||||
"宝具": x["tprop"],
|
||||
}
|
||||
fgo_info[name] = member_dict
|
||||
# 更新额外信息
|
||||
for key in fgo_info.keys():
|
||||
url = f'http://fgo.vgtime.com/servant/{fgo_info[key]["id"]}'
|
||||
result = await self.get_url(url)
|
||||
if not result:
|
||||
fgo_info[key]["入手方式"] = ["圣晶石召唤"]
|
||||
logger.warning(f"{self.game_name_cn} 获取额外信息错误 {key}")
|
||||
continue
|
||||
try:
|
||||
dom = etree.HTML(result, etree.HTMLParser())
|
||||
obtain = dom.xpath(
|
||||
"//table[contains(string(.),'入手方式')]/tr[8]/td[3]/text()"
|
||||
)[0]
|
||||
obtain = str(obtain).strip()
|
||||
if "限时活动免费获取 活动结束后无法获得" in obtain:
|
||||
obtain = ["活动获取"]
|
||||
elif "非限时UP无法获得" in obtain:
|
||||
obtain = ["限时召唤"]
|
||||
else:
|
||||
if "&" in obtain:
|
||||
obtain = obtain.split("&")
|
||||
else:
|
||||
obtain = obtain.split(" ")
|
||||
obtain = [s.strip() for s in obtain if s.strip()]
|
||||
fgo_info[key]["入手方式"] = obtain
|
||||
except IndexError:
|
||||
fgo_info[key]["入手方式"] = ["圣晶石召唤"]
|
||||
logger.warning(f"{self.game_name_cn} 获取额外信息错误 {key}")
|
||||
self.dump_data(fgo_info)
|
||||
logger.info(f"{self.game_name_cn} 更新成功")
|
||||
# fgo_card.json
|
||||
fgo_card_info = {}
|
||||
for i in range(500):
|
||||
url = f"http://fgo.vgtime.com/equipment/ajax?wd=&ids=&sort=12958&o=desc&pn={i}"
|
||||
result = await self.get_url(url)
|
||||
if not result:
|
||||
logger.warning(f"更新 {self.game_name_cn}卡牌 page {i} 出错")
|
||||
continue
|
||||
fgo_data = json.loads(result)
|
||||
if int(fgo_data["nums"]) <= 0:
|
||||
break
|
||||
for x in fgo_data["data"]:
|
||||
name = remove_prohibited_str(x["name"])
|
||||
member_dict = {
|
||||
"id": x["id"],
|
||||
"card_id": x["equipid"],
|
||||
"头像": x["icon"],
|
||||
"名称": name,
|
||||
"星级": int(x["star"]),
|
||||
"hp": x["lvmax_hp"],
|
||||
"atk": x["lvmax_atk"],
|
||||
"skill_e": str(x["skill_e"]).split("<br />")[:-1],
|
||||
}
|
||||
fgo_card_info[name] = member_dict
|
||||
self.dump_data(fgo_card_info, "fgo_card.json")
|
||||
logger.info(f"{self.game_name_cn} 卡牌更新成功")
|
||||
# 下载头像
|
||||
for value in fgo_info.values():
|
||||
await self.download_img(value["头像"], value["名称"])
|
||||
for value in fgo_card_info.values():
|
||||
await self.download_img(value["头像"], value["名称"])
|
||||
Reference in New Issue
Block a user