更新抽卡插件

修复了方舟抽卡图文不符的问题
修复了方舟许多三星抽不出来的问题
修复了方舟重载卡池失败的问题
This commit is contained in:
Number_Sir 2022-05-26 20:07:09 +08:00
parent 9d98abded9
commit 18323a0916

View File

@ -3,7 +3,6 @@ import random
import dateparser import dateparser
from lxml import etree from lxml import etree
from PIL import ImageDraw from PIL import ImageDraw
from bs4 import BeautifulSoup
from datetime import datetime from datetime import datetime
from urllib.parse import unquote from urllib.parse import unquote
from typing import List, Optional, Tuple from typing import List, Optional, Tuple
@ -19,7 +18,7 @@ except ModuleNotFoundError:
import json import json
from .base_handle import BaseHandle, BaseData, UpChar, UpEvent 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 ..util import remove_prohibited_str, cn2py, load_font
from utils.image_utils import BuildImage from utils.image_utils import BuildImage
@ -32,8 +31,9 @@ class Operator(BaseData):
class PrtsHandle(BaseHandle[Operator]): class PrtsHandle(BaseHandle[Operator]):
def __init__(self): def __init__(self):
super().__init__("prts", "明日方舟", "#eff2f5") super().__init__(game_name="prts", game_name_cn="明日方舟")
self.max_star = 6 self.max_star = 6
self.game_card_color = "#eff2f5"
self.config = draw_config.prts self.config = draw_config.prts
self.ALL_OPERATOR: List[Operator] = [] self.ALL_OPERATOR: List[Operator] = []
@ -41,8 +41,8 @@ class PrtsHandle(BaseHandle[Operator]):
def get_card(self, add: float) -> Operator: def get_card(self, add: float) -> Operator:
star = self.get_star( 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_SIX_P + add,
self.config.PRTS_FIVE_P, self.config.PRTS_FIVE_P,
self.config.PRTS_FOUR_P, self.config.PRTS_FOUR_P,
@ -74,7 +74,7 @@ class PrtsHandle(BaseHandle[Operator]):
acquire_operator = random.choice(all_operators) acquire_operator = random.choice(all_operators)
return acquire_operator 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 = [] # 获取所有角色 card_list = [] # 获取所有角色
add = 0.0 add = 0.0
count_idx = 0 count_idx = 0
@ -162,8 +162,11 @@ class PrtsHandle(BaseHandle[Operator]):
def load_up_char(self): def load_up_char(self):
try: 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", {})) self.UP_EVENT = UpEvent.parse_obj(data.get("char", {}))
except ValidationError: except ValidationError:
logger.warning(f"{self.game_name}_up_char 解析出错") logger.warning(f"{self.game_name}_up_char 解析出错")
@ -211,6 +214,7 @@ class PrtsHandle(BaseHandle[Operator]):
await self.update_up_char() await self.update_up_char()
async def update_up_char(self): async def update_up_char(self):
"""重载卡池"""
announcement_url = "https://ak.hypergryph.com/news.html" announcement_url = "https://ak.hypergryph.com/news.html"
result = await self.get_url(announcement_url) result = await self.get_url(announcement_url)
if not result: if not result:
@ -224,45 +228,53 @@ class PrtsHandle(BaseHandle[Operator]):
end_time = None end_time = None
up_chars = [] up_chars = []
pool_img = "" pool_img = ""
title = "" for activity_url in activity_urls[:10]: # 减少响应时间, 10个就够了
for activity_url in activity_urls:
activity_url = f"https://ak.hypergryph.com{activity_url}" activity_url = f"https://ak.hypergryph.com{activity_url}"
result = await self.get_url(activity_url) result = await self.get_url(activity_url)
if not result: if not result:
logger.warning(f"{self.game_name_cn}获取公告 {activity_url} 出错") logger.warning(f"{self.game_name_cn}获取公告 {activity_url} 出错")
continue 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): for index, content in enumerate(contents):
if re.search("(.*)(寻访|复刻).*?开启", content.text): if re.search("(.*)(寻访|复刻).*?开启", content):
title = content.text title = re.split(r"[【】]", content)
if "" in title and "" in title: title = "".join(title[1:-1]) if "-" in title else title[1]
title = re.split(r"[【】]", title)[1] lines = [contents[index-2+_] for _ in range(8)] # 从 -2 开始是因为xpath获取的时间有的会在寻访开启这一句之前
lines = [str(contents[index + i + 1].text) for i in range(5)] lines.append("") # 防止IndexError加个空字符串
time = "" for idx, line in enumerate(lines):
chars: List[str] = []
for line in lines:
match = re.search( match = re.search(
r"(\d{1,2}月\d{1,2}日.*?-.*?\d{1,2}月\d{1,2}日.*?$)", line r"(\d{1,2}月\d{1,2}日.*?-.*?\d{1,2}月\d{1,2}日.*?$)", line
) )
if match: if match:
time = match.group(1) time = match.group(1)
if "" in line: """因为 <p> 的诡异排版,所以有了下面的一段"""
"""这里修复了某些池子六星名称显示错误的问题(如奔崖号角)""" if ("★★" in line and "%" in line) or ("★★" in line and "%" in lines[idx + 1]):
if line[0] != '': chars.append(line) if ("★★" in line and "%" in line) else chars.append(line + lines[idx + 1])
idx = line.find('')
line = line[idx:]
chars.append(line)
if not time: if not time:
continue continue
start, end = time.replace("", "/").replace("", "").split("-")[:2] start, end = time.replace("", "/").replace("", " ").split("-")[:2] # 日替换为空格是因为有日后面不接空格的情况,导致 split 出问题
start_time = dateparser.parse(start) start_time = dateparser.parse(start)
end_time = dateparser.parse(end) end_time = dateparser.parse(end)
pool_img = content.find_previous("img")["src"] pool_img = contents[index-2]
r"""两类格式:用/分割,用\分割;★+(概率)+名字,★+名字+(概率)"""
for char in chars: for char in chars:
star = char.split("")[0].count("") star = char.split("")[0].count("")
name = re.split(r"[]", char)[1] name = re.split(r"[]", char)[1] if "★(" not in char else re.split("", char)[1] # 有的括号在前面有的在后面
names = name.split("/") if "/" in name else [name] if "\\" in name:
names = name.split("\\")
elif "/" in name:
names = name.split("/")
else:
names = [name] # 既有用/分割的,又有用\分割的
names = [name.replace("[限定]", "").strip() for name in names] names = [name.replace("[限定]", "").strip() for name in names]
if "权值" in char: if "权值" in char:
match = re.search(r"(在.*?以.*?(\d+).*?倍权值.*?", char) match = re.search(r"(在.*?以.*?(\d+).*?倍权值.*?", char)
@ -276,7 +288,7 @@ class PrtsHandle(BaseHandle[Operator]):
up_chars.append( up_chars.append(
UpChar(name=name, star=star, limited=False, zoom=zoom) UpChar(name=name, star=star, limited=False, zoom=zoom)
) )
break break # 这里break会导致个问题如果一个公告里有两个池子会漏掉下面的池子比如 5.19 的定向寻访。但目前我也没啥好想法解决
if title and start_time and end_time: if title and start_time and end_time:
if start_time <= datetime.now() <= end_time: if start_time <= datetime.now() <= end_time:
self.UP_EVENT = UpEvent( self.UP_EVENT = UpEvent(