import random import ujson as json from lxml import etree from PIL import Image, ImageDraw from PIL.Image import Image as IMG from zhenxun.services.log import logger from zhenxun.utils.image_utils import BuildImage from ..config import draw_config from ..util import cn2py, load_font, remove_prohibited_str from .base_handle import BaseData, BaseHandle class OnmyojiChar(BaseData): @property def star_str(self) -> str: return ["N", "R", "SR", "SSR", "SP"][self.star - 1] class OnmyojiHandle(BaseHandle[OnmyojiChar]): def __init__(self): super().__init__("onmyoji", "阴阳师") self.max_star = 5 self.config = draw_config.onmyoji self.ALL_CHAR: list[OnmyojiChar] = [] def get_card(self, **kwargs) -> OnmyojiChar: star = self.get_star( [5, 4, 3, 2], [ self.config.ONMYOJI_SP, self.config.ONMYOJI_SSR, self.config.ONMYOJI_SR, self.config.ONMYOJI_R, ], ) chars = [x for x in self.ALL_CHAR if x.star == star and not x.limited] return random.choice(chars) def format_max_star(self, card_list: list[tuple[OnmyojiChar, int]]) -> str: rst = "" for card, index in card_list: if card.star == self.max_star: rst += f"第 {index} 抽获取SP {card.name}\n" elif card.star == self.max_star - 1: rst += f"第 {index} 抽获取SSR {card.name}\n" return rst.strip() @staticmethod def star_label(star: int) -> IMG: text, color1, color2 = [ ("N", "#7E7E82", "#F5F6F7"), ("R", "#014FA8", "#37C6FD"), ("SR", "#6E0AA4", "#E94EFD"), ("SSR", "#E5511D", "#FAF905"), ("SP", "#FA1F2D", "#FFBBAF"), ][star - 1] w = 200 h = 110 # 制作渐变色图片 base = Image.new("RGBA", (w, h), color1) top = Image.new("RGBA", (w, h), color2) mask = Image.new("L", (w, h)) mask_data = [] for y in range(h): mask_data.extend([int(255 * (y / h))] * w) mask.putdata(mask_data) base.paste(top, (0, 0), mask) # 透明图层 font = load_font("gorga.otf", 100) alpha = Image.new("L", (w, h)) draw = ImageDraw.Draw(alpha) draw.text((20, -30), text, fill="white", font=font) base.putalpha(alpha) # stroke bg = Image.new("RGBA", (w, h)) draw = ImageDraw.Draw(bg) draw.text( (20, -30), text, font=font, fill="gray", stroke_width=3, stroke_fill="gray", ) bg.paste(base, (0, 0), base) return bg async def generate_img(self, card_list: list[OnmyojiChar]) -> BuildImage: return await super().generate_img(card_list, num_per_line=10) async def generate_card_img(self, card: OnmyojiChar) -> BuildImage: bg = BuildImage(73, 240, color="#F1EFE9") img_path = str(self.img_path / f"{cn2py(card.name)}_mark_btn.png") img = BuildImage(0, 0, background=img_path) img = Image.open(img_path).convert("RGBA") label = self.star_label(card.star).resize((60, 33), Image.ANTIALIAS) await bg.paste(img, (0, 0)) await bg.paste(label, (0, 135)) font = load_font("msyh.ttf", 16) draw = ImageDraw.Draw(bg.markImg) text = "\n".join([t for t in card.name[:4]]) _, text_h = font.getsize_multiline(text, spacing=0) draw.text( (40, 150 + (90 - text_h) / 2), text, font=font, fill="gray", spacing=0 ) return bg def _init_data(self): self.ALL_CHAR = [ OnmyojiChar( name=value["名称"], star=["N", "R", "SR", "SSR", "SP"].index(value["星级"]) + 1, limited=( True if key in [ "奴良陆生", "卖药郎", "鬼灯", "阿香", "蜜桃&芥子", "犬夜叉", "杀生丸", "桔梗", "朽木露琪亚", "黑崎一护", "灶门祢豆子", "灶门炭治郎", ] else False ), ) for key, value in self.load_data().items() ] async def _update_info(self): info = {} url = "https://yys.res.netease.com/pc/zt/20161108171335/js/app/all_shishen.json?v74=" result = await self.get_url(url) if not result: logger.warning(f"更新 {self.game_name_cn} 出错") return data = json.loads(result) for x in data: name = remove_prohibited_str(x["name"]) member_dict = { "id": x["id"], "名称": name, "星级": x["level"], } info[name] = member_dict # logger.info(f"{name} is update...") # 更新头像 for key in info.keys(): url = f'https://yys.163.com/shishen/{info[key]["id"]}.html' result = await self.get_url(url) if not result: info[key]["头像"] = "" continue try: dom = etree.HTML(result, etree.HTMLParser()) avatar = dom.xpath("//div[@class='pic_wrap']/img/@src")[0] avatar = "https:" + avatar info[key]["头像"] = avatar except IndexError: info[key]["头像"] = "" logger.warning(f"{self.game_name_cn} 获取头像错误 {key}") self.dump_data(info) logger.info(f"{self.game_name_cn} 更新成功") # 下载头像 for value in info.values(): await self.download_img(value["头像"], value["名称"]) # 下载书签形式的头像 url = f"https://yys.res.netease.com/pc/zt/20161108171335/data/mark_btn/{value['id']}.png" await self.download_img(url, value["名称"] + "_mark_btn")