更新抽卡插件

修复了方舟抽卡图文不符的问题
修复了方舟许多三星抽不出来的问题
修复了方舟重载卡池失败的问题
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
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)
"""因为 <p> 的诡异排版,所以有了下面的一段"""
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(