From 18323a09160a04fa849439d4fca3275a04338733 Mon Sep 17 00:00:00 2001 From: Number_Sir Date: Thu, 26 May 2022 20:07:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=8A=BD=E5=8D=A1=E6=8F=92?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复了方舟抽卡图文不符的问题 修复了方舟许多三星抽不出来的问题 修复了方舟重载卡池失败的问题 --- plugins/draw_card/handles/prts_handle.py | 74 ++++++++++++++---------- 1 file changed, 43 insertions(+), 31 deletions(-) diff --git a/plugins/draw_card/handles/prts_handle.py b/plugins/draw_card/handles/prts_handle.py index 778256c2..60d90702 100644 --- a/plugins/draw_card/handles/prts_handle.py +++ b/plugins/draw_card/handles/prts_handle.py @@ -3,7 +3,6 @@ import random import dateparser from lxml import etree from PIL import ImageDraw -from bs4 import BeautifulSoup from datetime import datetime from urllib.parse import unquote from typing import List, Optional, Tuple @@ -19,7 +18,7 @@ except ModuleNotFoundError: import json from .base_handle import BaseHandle, BaseData, UpChar, UpEvent -from ..config import draw_config, DRAW_PATH +from ..config import draw_config from ..util import remove_prohibited_str, cn2py, load_font from utils.image_utils import BuildImage @@ -32,8 +31,9 @@ class Operator(BaseData): class PrtsHandle(BaseHandle[Operator]): def __init__(self): - super().__init__("prts", "明日方舟", "#eff2f5") + super().__init__(game_name="prts", game_name_cn="明日方舟") self.max_star = 6 + self.game_card_color = "#eff2f5" self.config = draw_config.prts self.ALL_OPERATOR: List[Operator] = [] @@ -41,8 +41,8 @@ class PrtsHandle(BaseHandle[Operator]): def get_card(self, add: float) -> Operator: star = self.get_star( - [6, 5, 4, 3], - [ + star_list=[6, 5, 4, 3], + probability_list=[ self.config.PRTS_SIX_P + add, self.config.PRTS_FIVE_P, self.config.PRTS_FOUR_P, @@ -74,7 +74,7 @@ class PrtsHandle(BaseHandle[Operator]): acquire_operator = random.choice(all_operators) return acquire_operator - def get_cards(self, count: int) -> List[Tuple[Operator, int]]: + def get_cards(self, count: int, **kwargs) -> List[Tuple[Operator, int]]: card_list = [] # 获取所有角色 add = 0.0 count_idx = 0 @@ -162,8 +162,11 @@ class PrtsHandle(BaseHandle[Operator]): def load_up_char(self): try: - if (DRAW_PATH / "draw_card_up" / f"{self.game_name}_up_char.json").exists(): - data = self.load_data(f"draw_card_up/{self.game_name}_up_char.json") + data = self.load_data(f"draw_card_up/{self.game_name}_up_char.json") + """这里的 waring 有点模糊,更新游戏信息时没有up池的情况下也会报错,所以细分了一下""" + if not data: + logger.warning(f"当前无UP池或 {self.game_name}_up_char.json 文件不存在") + else: self.UP_EVENT = UpEvent.parse_obj(data.get("char", {})) except ValidationError: logger.warning(f"{self.game_name}_up_char 解析出错") @@ -211,6 +214,7 @@ class PrtsHandle(BaseHandle[Operator]): await self.update_up_char() async def update_up_char(self): + """重载卡池""" announcement_url = "https://ak.hypergryph.com/news.html" result = await self.get_url(announcement_url) if not result: @@ -224,45 +228,53 @@ class PrtsHandle(BaseHandle[Operator]): end_time = None up_chars = [] pool_img = "" - title = "" - for activity_url in activity_urls: + for activity_url in activity_urls[:10]: # 减少响应时间, 10个就够了 activity_url = f"https://ak.hypergryph.com{activity_url}" result = await self.get_url(activity_url) if not result: logger.warning(f"{self.game_name_cn}获取公告 {activity_url} 出错") continue - soup = BeautifulSoup(result, "lxml") - contents = soup.find_all("p") + + """因为鹰角的前端太自由了,这里重写了匹配规则以尽可能避免因为前端乱七八糟而导致的重载失败""" + dom = etree.HTML(result, etree.HTMLParser()) + contents = dom.xpath( + "//div[@class='article-content']/p/text() | //div[@class='article-content']/p/span/text() | //div[@class='article-content']/div[@class='media-wrap image-wrap']/img/@src" + ) + title = "" + time = "" + chars: List[str] = [] for index, content in enumerate(contents): - if re.search("(.*)(寻访|复刻).*?开启", content.text): - title = content.text - if "【" in title and "】" in title: - title = re.split(r"[【】]", title)[1] - lines = [str(contents[index + i + 1].text) for i in range(5)] - time = "" - chars: List[str] = [] - for line in lines: + if re.search("(.*)(寻访|复刻).*?开启", content): + title = re.split(r"[【】]", content) + title = "".join(title[1:-1]) if "-" in title else title[1] + lines = [contents[index-2+_] for _ in range(8)] # 从 -2 开始是因为xpath获取的时间有的会在寻访开启这一句之前 + lines.append("") # 防止IndexError,加个空字符串 + for idx, line in enumerate(lines): match = re.search( r"(\d{1,2}月\d{1,2}日.*?-.*?\d{1,2}月\d{1,2}日.*?$)", line ) if match: time = match.group(1) - if "★" in line: - """这里修复了某些池子六星名称显示错误的问题(如奔崖号角)""" - if line[0] != '★': - idx = line.find('★') - line = line[idx:] - chars.append(line) + """因为

的诡异排版,所以有了下面的一段""" + if ("★★" in line and "%" in line) or ("★★" in line and "%" in lines[idx + 1]): + chars.append(line) if ("★★" in line and "%" in line) else chars.append(line + lines[idx + 1]) if not time: continue - start, end = time.replace("月", "/").replace("日", "").split("-")[:2] + start, end = time.replace("月", "/").replace("日", " ").split("-")[:2] # 日替换为空格是因为有日后面不接空格的情况,导致 split 出问题 start_time = dateparser.parse(start) end_time = dateparser.parse(end) - pool_img = content.find_previous("img")["src"] + pool_img = contents[index-2] + r"""两类格式:用/分割,用\分割;★+(概率)+名字,★+名字+(概率)""" for char in chars: star = char.split("(")[0].count("★") - name = re.split(r"[:(]", char)[1] - names = name.split("/") if "/" in name else [name] + name = re.split(r"[:(]", char)[1] if "★(" not in char else re.split("):", char)[1] # 有的括号在前面有的在后面 + if "\\" in name: + names = name.split("\\") + elif "/" in name: + names = name.split("/") + else: + names = [name] # 既有用/分割的,又有用\分割的 + names = [name.replace("[限定]", "").strip() for name in names] if "权值" in char: match = re.search(r"(在.*?以.*?(\d+).*?倍权值.*?)", char) @@ -276,7 +288,7 @@ class PrtsHandle(BaseHandle[Operator]): up_chars.append( UpChar(name=name, star=star, limited=False, zoom=zoom) ) - break + break # 这里break会导致个问题:如果一个公告里有两个池子,会漏掉下面的池子,比如 5.19 的定向寻访。但目前我也没啥好想法解决 if title and start_time and end_time: if start_time <= datetime.now() <= end_time: self.UP_EVENT = UpEvent(