优化管理员帮助,超级用户帮助图片,重新移植gamedraw,修复pil帮助私聊时无法生成

This commit is contained in:
HibiKier
2022-12-24 00:16:17 +08:00
parent 0dc11b7edb
commit b25b9ca928
33 changed files with 869 additions and 695 deletions
+44 -27
View File
@@ -1,17 +1,17 @@
import contextlib
import random
import dateparser
from lxml import etree
from typing import List, Optional, Tuple
from PIL import ImageDraw
from urllib.parse import unquote
from pydantic import ValidationError
from nonebot.log import logger
from nonebot.adapters.onebot.v11 import Message
from utils.message_builder import image
from nonebot.adapters.onebot.v11 import Message, MessageSegment
from utils.message_builder import image
from .base_handle import BaseHandle, BaseData, UpEvent as _UpEvent, UpChar as _UpChar
from ..config import draw_config
from ..util import remove_prohibited_str, cn2py
from ..util import remove_prohibited_str, cn2py, load_font
from utils.image_utils import BuildImage
try:
@@ -59,19 +59,25 @@ class AzurHandle(BaseHandle[AzurChar]):
# print(up_ship)
acquire_char = None
if up_ship and up_pool_flag:
up_zoom = [(0, up_ship[0].zoom / 100)]
up_zoom: List[Tuple[float, float]] = [(0, up_ship[0].zoom / 100)]
# 初始化概率
cur_ = up_ship[0].zoom / 100
for i in range(len(up_ship)):
with contextlib.suppress(IndexError):
try:
up_zoom.append((cur_, cur_ + up_ship[i + 1].zoom / 100))
cur_ += up_ship[i + 1].zoom / 100
except IndexError:
pass
rand = random.random()
# 抽取up
for i, zoom in enumerate(up_zoom):
if zoom[0] <= rand <= zoom[1]:
with contextlib.suppress(IndexError):
acquire_char = [x for x in self.ALL_CHAR if x.name == up_ship[i].name][0]
try:
acquire_char = [
x for x in self.ALL_CHAR if x.name == up_ship[i].name
][0]
except IndexError:
pass
# 没有up或者未抽取到up
if not acquire_char:
star = self.get_star(
@@ -83,17 +89,19 @@ class AzurHandle(BaseHandle[AzurChar]):
self.config.AZUR_ONE_P,
],
)
acquire_char = random.choice([
x
for x in self.ALL_CHAR
if x.star == star and x.type_ in type_ and not x.limited
])
acquire_char = random.choice(
[
x
for x in self.ALL_CHAR
if x.star == star and x.type_ in type_ and not x.limited
]
)
return acquire_char
async def draw(self, count: int, **kwargs) -> Message:
def draw(self, count: int, **kwargs) -> Message:
index2card = self.get_cards(count, **kwargs)
cards = [card[0] for card in index2card]
up_list = [x.name for x in self.UP_EVENT.up_char] if self.UP_EVENT.up_char else []
up_list = [x.name for x in self.UP_EVENT.up_char] if self.UP_EVENT else []
result = self.format_result(index2card, **{**kwargs, "up_list": up_list})
return image(b64=self.generate_img(cards).pic2bs4()) + result
@@ -103,22 +111,25 @@ class AzurHandle(BaseHandle[AzurChar]):
sep_b = 20
w = 100
h = 100
bg = BuildImage(w + sep_w * 2, h + sep_t + sep_b, font="msyh.ttf")
frame_path = self.img_path / f"{card.star}_star.png"
bg = BuildImage(w + sep_w * 2, h + sep_t + sep_b)
frame_path = str(self.img_path / f"{card.star}_star.png")
frame = BuildImage(w, h, background=frame_path)
img_path = self.img_path / f"{cn2py(card.name)}.png"
img_path = str(self.img_path / f"{cn2py(card.name)}.png")
img = BuildImage(w, h, background=img_path)
# 加圆角
frame.circle_corner(6)
img.circle_corner(6)
bg.paste(img, (sep_w, sep_t), alpha=True)
bg.paste(frame, (sep_w, sep_t), alpha=True)
bg.circle_corner(6)
# 加名字
text = card.name[:6] + "..." if len(card.name) > 7 else card.name
text_w, text_h = bg.getsize(text)
bg.text(
font = load_font(fontsize=14)
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=["#808080", "#3b8bff", "#8000ff", "#c90", "#ee494c"][card.star - 1],
)
return bg
@@ -146,6 +157,7 @@ class AzurHandle(BaseHandle[AzurChar]):
if self.UP_EVENT:
data = {"char": json.loads(self.UP_EVENT.json())}
self.dump_data(data, f"draw_card_up/{self.game_name}_up_char.json")
self.dump_data(data, f"draw_card_up/{self.game_name}_up_char.json")
async def _update_info(self):
info = {}
@@ -220,17 +232,22 @@ class AzurHandle(BaseHandle[AzurChar]):
@staticmethod
def parse_star(star: str) -> int:
if star in {"舰娘头像外框普通.png", "舰娘头像外框白色.png"}:
if star in ["舰娘头像外框普通.png", "舰娘头像外框白色.png"]:
return 1
elif star in {"舰娘头像外框稀有.png", "舰娘头像外框蓝色.png"}:
elif star in ["舰娘头像外框稀有.png", "舰娘头像外框蓝色.png"]:
return 2
elif star in {"舰娘头像外框精锐.png", "舰娘头像外框紫色.png"}:
elif star in ["舰娘头像外框精锐.png", "舰娘头像外框紫色.png"]:
return 3
elif star in {"舰娘头像外框超稀有.png", "舰娘头像外框金色.png"}:
elif star in ["舰娘头像外框超稀有.png", "舰娘头像外框金色.png"]:
return 4
elif star in {"舰娘头像外框海上传奇.png", "舰娘头像外框彩色.png"}:
elif star in ["舰娘头像外框海上传奇.png", "舰娘头像外框彩色.png"]:
return 5
elif star in {"舰娘头像外框最高方案.png", "舰娘头像外框决战方案.png", "舰娘头像外框超稀有META.png", "舰娘头像外框精锐META.png"}:
elif star in [
"舰娘头像外框最高方案.png",
"舰娘头像外框决战方案.png",
"舰娘头像外框超稀有META.png",
"舰娘头像外框精锐META.png",
]:
return 6
else:
return 6
+29 -69
View File
@@ -1,17 +1,17 @@
import random
import json
from utils.http_utils import AsyncHttpx
from lxml import etree
from typing import List, Tuple
from PIL import ImageDraw
from urllib.parse import unquote
from nonebot.log import logger
from .base_handle import BaseHandle, BaseData
from ..config import draw_config
from ..util import remove_prohibited_str, cn2py, load_font
from lxml import etree
from nonebot.log import logger
from PIL import ImageDraw
from utils.http_utils import AsyncHttpx
from 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 BaChar(BaseData):
pass
@@ -68,17 +68,19 @@ class BaHandle(BaseHandle[BaChar]):
bar = BuildImage(bar_w, bar_h, color="#6495ED")
bg.paste(img, (sep_w, sep_h), alpha=True)
bg.paste(bar, (sep_w, img_h - bar_h + sep_h), alpha=True)
if (card.star == 1):
if card.star == 1:
star_path = str(self.img_path / "star-1.png")
star_w = 15
elif (card.star == 2):
elif card.star == 2:
star_path = str(self.img_path / "star-2.png")
star_w = 30
else:
star_path = str(self.img_path / "star-3.png")
star_w = 45
star = BuildImage(star_w, star_h, background=star_path)
bg.paste(star, (img_w // 2 - 15 * (card.star - 1) // 2, img_h - star_h), alpha=True)
bg.paste(
star, (img_w // 2 - 15 * (card.star - 1) // 2, img_h - star_h), alpha=True
)
text = card.name[:5] + "..." if len(card.name) > 6 else card.name
font = load_font(fontsize=14)
text_w, text_h = font.getsize(text)
@@ -100,78 +102,37 @@ class BaHandle(BaseHandle[BaChar]):
)
for key, value in self.load_data().items()
]
def title2star(self, title: int):
if title == 'Star-3.png':
if title == "Star-3.png":
return 3
elif title == 'Star-2.png':
elif title == "Star-2.png":
return 2
else:
return 1
# Bwiki 待恢复
# async def _update_info(self):
# info = {}
# url = "https://wiki.biligame.com/bluearchive/学生筛选"
# result = await self.get_url(url)
# if not result:
# logger.warning(f"更新 {self.game_name_cn} 出错")
# return
# else:
# dom = etree.HTML(result, etree.HTMLParser())
# char_list = dom.xpath("//div[@class='filters']/table[2]/tbody/tr")
# for char in char_list:
# try:
# name = char.xpath("./td[2]/a/div/text()")[0]
# avatar = char.xpath("./td[1]/div/div/a/img/@data-src")[0]
# star_pic = char.xpath("./td[4]/img/@alt")[0]
# except IndexError:
# continue
# member_dict = {
# "头像": unquote(str(avatar)),
# "名称": remove_prohibited_str(name),
# "星级": self.title2star(star_pic),
# }
# info[member_dict["名称"]] = member_dict
# self.dump_data(info)
# logger.info(f"{self.game_name_cn} 更新成功")
# # 下载头像
# for value in info.values():
# await self.download_img(value["头像"], value["名称"])
# # 下载星星
# await self.download_img(
# "https://patchwiki.biligame.com/images/bluearchive/thumb/e/e0/82nj2x9sxko473g7782r14fztd4zyky.png/15px-Star-1.png",
# "star-1",
# )
# await self.download_img(
# "https://patchwiki.biligame.com/images/bluearchive/thumb/0/0b/msaff2g0zk6nlyl1rrn7n1ri4yobcqc.png/30px-Star-2.png",
# "star-2",
# )
# await self.download_img(
# "https://patchwiki.biligame.com/images/bluearchive/thumb/8/8a/577yv79x1rwxk8efdccpblo0lozl158.png/46px-Star-3.png",
# "star-3"
# )
# 数据来源:SCHALE DB
async def _update_info(self):
info = {}
url = "https://lonqie.github.io/SchaleDB/data/cn/students.min.json?v=49"
result = await AsyncHttpx.get(url)
if result.status_code != 200:
result = (await AsyncHttpx.get(url)).json()
if not result:
logger.warning(f"更新 {self.game_name_cn} 出错")
return
else:
char_list = json.loads(result.text)
for char in char_list:
for char in result:
try:
name = char.get("Name")
avatar = "https://lonqie.github.io/SchaleDB/images/student/icon/"+char.get("CollectionTexture")+".png"
star = char.get("StarGrade")
name = char["Name"]
avatar = (
"https://github.com/lonqie/SchaleDB/raw/main/images/student/icon/"
+ char["CollectionTexture"]
+ ".png"
)
star = char["StarGrade"]
except IndexError:
continue
member_dict = {
"头像": unquote(str(avatar)),
"名称": remove_prohibited_str(name),
"头像": avatar,
"名称": name,
"星级": star,
}
info[member_dict["名称"]] = member_dict
@@ -191,6 +152,5 @@ class BaHandle(BaseHandle[BaChar]):
)
await self.download_img(
"https://patchwiki.biligame.com/images/bluearchive/thumb/8/8a/577yv79x1rwxk8efdccpblo0lozl158.png/46px-Star-3.png",
"star-3"
"star-3",
)
+12 -17
View File
@@ -1,18 +1,18 @@
import math
import anyio
import random
import aiohttp
import asyncio
import aiofiles
from PIL import Image
from datetime import datetime
from pydantic import BaseModel, Extra
from asyncio.exceptions import TimeoutError
from typing import Dict, List, Optional, TypeVar, Generic, Tuple
from nonebot.adapters.onebot.v11 import Message
from configs.path_config import IMAGE_PATH
from utils.message_builder import image
from nonebot.adapters.onebot.v11 import Message, MessageSegment
from nonebot.log import logger
import asyncio
from configs.path_config import DATA_PATH
from utils.message_builder import image
try:
import ujson as json
@@ -50,29 +50,25 @@ class UpEvent(BaseModel):
start_time: Optional[datetime] # 开始时间
end_time: Optional[datetime] # 结束时间
up_char: List[UpChar] # up对象
up_name: str = "" # up名称
TC = TypeVar("TC", bound="BaseData")
class BaseHandle(Generic[TC]):
def __init__(self, game_name: str, game_name_cn: str, game_card_color: str = "#ffffff"):
def __init__(self, game_name: str, game_name_cn: str):
self.game_name = game_name
self.game_name_cn = game_name_cn
self.max_star = 1 # 最大星级
self.data_path = DRAW_PATH
self.img_path = IMAGE_PATH / f"draw_card/{self.game_name}"
self.up_path = DRAW_PATH / "draw_card_up"
self.game_card_color: str = "#ffffff"
self.data_path = DATA_PATH / "draw_card"
self.img_path = DRAW_PATH / f"{self.game_name}"
self.up_path = DATA_PATH / "draw_card" / "draw_card_up"
self.img_path.mkdir(parents=True, exist_ok=True)
self.up_path.mkdir(parents=True, exist_ok=True)
self.data_files: List[str] = [f"{self.game_name}.json"]
self.game_card_color: str = game_card_color
async def draw(self, count: int, **kwargs) -> Message:
return await asyncio.get_event_loop().run_in_executor(None, self._draw, count)
def _draw(self, count: int, **kwargs) -> Message:
def draw(self, count: int, **kwargs) -> Message:
index2card = self.get_cards(count, **kwargs)
cards = [card[0] for card in index2card]
result = self.format_result(index2card)
@@ -173,7 +169,6 @@ class BaseHandle(Generic[TC]):
card_imgs: List[BuildImage] = []
for card, num in zip(card_list, num_list):
card_img = self.generate_card_img(card)
# 数量 > 1 时加数字上标
if num > 1:
label = circled_number(num)
@@ -274,7 +269,7 @@ class BaseHandle(Generic[TC]):
return True
try:
async with self.session.get(url, timeout=10) as response:
async with aiofiles.open(str(img_path), "wb") as f:
async with await anyio.open_file(img_path, "wb") as f:
await f.write(await response.read())
return True
except TimeoutError:
+52 -33
View File
@@ -6,10 +6,10 @@ from urllib.parse import unquote
from typing import List, Optional, Tuple
from pydantic import ValidationError
from datetime import datetime, timedelta
from nonebot.adapters.onebot.v11 import Message
from utils.message_builder import image
from nonebot.adapters.onebot.v11 import Message, MessageSegment
from nonebot.log import logger
import asyncio
from utils.message_builder import image
try:
import ujson as json
@@ -37,21 +37,23 @@ class GenshinArms(GenshinData):
class GenshinHandle(BaseHandle[GenshinData]):
def __init__(self):
super().__init__("genshin", "原神", "#ebebeb")
super().__init__("genshin", "原神")
self.data_files.append("genshin_arms.json")
self.max_star = 5
self.game_card_color = "#ebebeb"
self.config = draw_config.genshin
self.ALL_CHAR: List[GenshinData] = []
self.ALL_ARMS: List[GenshinData] = []
self.UP_CHAR: Optional[UpEvent] = None
self.UP_CHAR_LIST: Optional[UpEvent] = []
self.UP_ARMS: Optional[UpEvent] = None
self.count_manager = GenshinCountManager((10, 90), ("4", "5"), 180)
# 抽取卡池
def get_card(
self, pool_name: str, mode: int = 1, add: float = 0.0, is_up: bool = False
self, pool_name: str, mode: int = 1, add: float = 0.0, is_up: bool = False, card_index: int = 0
):
"""
mode 1:普通抽 2:四星保底 3:五星保底
@@ -74,7 +76,7 @@ class GenshinHandle(BaseHandle[GenshinData]):
star = 5
if pool_name == "char":
up_event = self.UP_CHAR
up_event = self.UP_CHAR_LIST[card_index]
all_list = self.ALL_CHAR + [
x for x in self.ALL_ARMS if x.star == star and x.star < 5
]
@@ -105,14 +107,13 @@ class GenshinHandle(BaseHandle[GenshinData]):
return acquire_char
def get_cards(
self, count: int, user_id: int, pool_name: str
self, count: int, user_id: int, pool_name: str, card_index: int = 0
) -> List[Tuple[GenshinData, int]]:
card_list = [] # 获取角色列表
add = 0.0
count_manager = self.count_manager
count_manager.check_timeout(user_id) # 检查上次抽卡次数是否超时
count_manager.check_count(user_id, count) # 检查次数累计
pool = self.UP_CHAR if pool_name == "char" else self.UP_ARMS
pool = self.UP_CHAR_LIST[card_index] if pool_name == "char" else self.UP_ARMS
for i in range(count):
count_manager.increase(user_id)
star = count_manager.check(user_id) # 是否有四星或五星保底
@@ -123,13 +124,13 @@ class GenshinHandle(BaseHandle[GenshinData]):
add += draw_config.genshin.I72_ADD
if star:
if star == 4:
card = self.get_card(pool_name, 2, add=add)
card = self.get_card(pool_name, 2, add=add, card_index=card_index)
else:
card = self.get_card(
pool_name, 3, add, count_manager.is_up(user_id)
pool_name, 3, add, count_manager.is_up(user_id), card_index=card_index
)
else:
card = self.get_card(pool_name, 1, add, count_manager.is_up(user_id))
card = self.get_card(pool_name, 1, add, count_manager.is_up(user_id), card_index=card_index)
# print(f"{count_manager.get_user_count(user_id)}:",
# count_manager.get_user_five_index(user_id), star, card.star, add)
# 四星角色
@@ -147,7 +148,6 @@ class GenshinHandle(BaseHandle[GenshinData]):
else:
count_manager.set_is_up(user_id, False)
card_list.append((card, count_manager.get_user_count(user_id)))
count_manager.update_time(user_id)
return card_list
def generate_card_img(self, card: GenshinData) -> BuildImage:
@@ -188,11 +188,11 @@ class GenshinHandle(BaseHandle[GenshinData]):
bg.paste(star, (sep_w + int((frame_w - star.width) / 2), sep_h - 6), alpha=True)
return bg
def format_pool_info(self, pool_name: str) -> str:
def format_pool_info(self, pool_name: str, card_index: int = 0) -> str:
info = ""
up_event = None
if pool_name == "char":
up_event = self.UP_CHAR
up_event = self.UP_CHAR_LIST[card_index]
elif pool_name == "arms":
up_event = self.UP_ARMS
if up_event:
@@ -205,15 +205,18 @@ class GenshinHandle(BaseHandle[GenshinData]):
info = f"当前up池:{up_event.title}\n{info}"
return info.strip()
async def draw(self, count: int, user_id: int, pool_name: str = "", **kwargs) -> Message:
return await asyncio.get_event_loop().run_in_executor(None, self._draw, count, user_id, pool_name)
def _draw(self, count: int, user_id: int, pool_name: str = "", **kwargs) -> Message:
index2cards = self.get_cards(count, user_id, pool_name)
def draw(self, count: int, user_id: int, pool_name: str = "", **kwargs) -> Message:
card_index = 0
if "1" in pool_name:
card_index = 1
pool_name = pool_name.replace("1", "")
index2cards = self.get_cards(count, user_id, pool_name, card_index)
cards = [card[0] for card in index2cards]
up_event = None
if pool_name == "char":
up_event = self.UP_CHAR
if card_index == 1 and len(self.UP_CHAR_LIST) == 1:
return Message("当前没有第二个角色UP池")
up_event = self.UP_CHAR_LIST[card_index]
elif pool_name == "arms":
up_event = self.UP_ARMS
up_list = [x.name for x in up_event.up_char] if up_event else []
@@ -225,7 +228,7 @@ class GenshinHandle(BaseHandle[GenshinData]):
)
result += f"\n距离保底发还剩 {self.count_manager.get_user_guarantee_count(user_id)} 抽"
# result += "\n【五星:0.6%,四星:5.1%,第72抽开始五星概率每抽加0.585%】"
pool_info = self.format_pool_info(pool_name)
pool_info = self.format_pool_info(pool_name, card_index)
img = self.generate_img(cards)
bk = BuildImage(img.w, img.h + 50, font_size=20, color="#ebebeb")
bk.paste(img)
@@ -255,17 +258,20 @@ class GenshinHandle(BaseHandle[GenshinData]):
def load_up_char(self):
try:
data = self.load_data(f"draw_card_up/{self.game_name}_up_char.json")
self.UP_CHAR = UpEvent.parse_obj(data.get("char", {}))
self.UP_CHAR_LIST.append(UpEvent.parse_obj(data.get("char", {})))
self.UP_CHAR_LIST.append(UpEvent.parse_obj(data.get("char1", {})))
self.UP_ARMS = UpEvent.parse_obj(data.get("arms", {}))
except ValidationError:
logger.warning(f"{self.game_name}_up_char 解析出错")
def dump_up_char(self):
if self.UP_CHAR and self.UP_ARMS:
if self.UP_CHAR_LIST and self.UP_ARMS:
data = {
"char": json.loads(self.UP_CHAR.json()),
"char": json.loads(self.UP_CHAR_LIST[0].json()),
"arms": json.loads(self.UP_ARMS.json()),
}
if len(self.UP_CHAR_LIST) > 1:
data['char1'] = json.loads(self.UP_CHAR_LIST[1].json())
self.dump_data(data, f"draw_card_up/{self.game_name}_up_char.json")
async def _update_info(self):
@@ -359,6 +365,7 @@ class GenshinHandle(BaseHandle[GenshinData]):
await self.update_up_char()
async def update_up_char(self):
self.UP_CHAR_LIST = []
url = "https://wiki.biligame.com/ys/祈愿"
result = await self.get_url(url)
if not result:
@@ -399,14 +406,15 @@ class GenshinHandle(BaseHandle[GenshinData]):
for name in star4_list
],
)
if index == 0:
self.UP_CHAR = up_event
elif index == 1:
if '神铸赋形' not in title:
self.UP_CHAR_LIST.append(up_event)
else:
self.UP_ARMS = up_event
if self.UP_CHAR and self.UP_ARMS:
if self.UP_CHAR_LIST and self.UP_ARMS:
self.dump_up_char()
char_title = " & ".join([x.title for x in self.UP_CHAR_LIST])
logger.info(
f"成功获取{self.game_name_cn}当前up信息...当前up池: {self.UP_CHAR.title} & {self.UP_ARMS.title}"
f"成功获取{self.game_name_cn}当前up信息...当前up池: {char_title} & {self.UP_ARMS.title}"
)
except Exception as e:
logger.warning(f"{self.game_name_cn}UP更新出错 {type(e)}:{e}")
@@ -418,12 +426,23 @@ class GenshinHandle(BaseHandle[GenshinData]):
async def _reload_pool(self) -> Optional[Message]:
await self.update_up_char()
self.load_up_char()
if self.UP_CHAR and self.UP_ARMS:
if self.UP_CHAR_LIST and self.UP_ARMS:
if len(self.UP_CHAR_LIST) > 1:
return Message(
Message.template("重载成功!\n当前UP池子:{} & {} & {}{:image}{:image}{:image}").format(
self.UP_CHAR_LIST[0].title,
self.UP_CHAR_LIST[1].title,
self.UP_ARMS.title,
self.UP_CHAR_LIST[0].pool_img,
self.UP_CHAR_LIST[1].pool_img,
self.UP_ARMS.pool_img,
)
)
return Message(
Message.template("重载成功!\n当前UP池子:{} & {}{:image}{:image}").format(
self.UP_CHAR.title,
char_title,
self.UP_ARMS.title,
self.UP_CHAR.pool_img,
self.UP_CHAR_LIST[0].pool_img,
self.UP_ARMS.pool_img,
)
)
+10 -10
View File
@@ -7,10 +7,10 @@ from datetime import datetime
from urllib.parse import unquote
from typing import List, Optional, Tuple
from pydantic import ValidationError
from nonebot.adapters.onebot.v11 import Message
from utils.message_builder import image
from nonebot.adapters.onebot.v11 import Message, MessageSegment
from nonebot.log import logger
import asyncio
from utils.message_builder import image
try:
import ujson as json
@@ -137,10 +137,7 @@ class GuardianHandle(BaseHandle[GuardianData]):
info = f"当前up池:{up_event.title}\n{info}"
return info.strip()
async def draw(self, count: int, pool_name: str, **kwargs) -> Message:
return await asyncio.get_event_loop().run_in_executor(None, self._draw, count, pool_name)
def _draw(self, count: int, pool_name: str, **kwargs) -> Message:
def draw(self, count: int, pool_name: str, **kwargs) -> Message:
index2card = self.get_cards(count, pool_name)
cards = [card[0] for card in index2card]
up_event = self.UP_CHAR if pool_name == "char" else self.UP_ARMS
@@ -238,9 +235,12 @@ class GuardianHandle(BaseHandle[GuardianData]):
char_list = dom.xpath("//table[@id='CardSelectTr']/tbody/tr")
for char in char_list:
try:
name = char.xpath("./td[1]/a/@title")[0]
avatar = char.xpath("./td[1]/a/img/@src")[0]
star = char.xpath("./td[1]/span/img/@alt")[0]
# name = char.xpath("./td[1]/a/@title")[0]
# avatar = char.xpath("./td[1]/a/img/@src")[0]
# star = char.xpath("./td[1]/span/img/@alt")[0]
name = char.xpath("./th[1]/a[1]/@title")[0]
avatar = char.xpath("./th[1]/a/img/@src")[0]
star = char.xpath("./th[1]/span/img/@alt")[0]
except IndexError:
continue
member_dict = {
+33 -35
View File
@@ -8,10 +8,10 @@ from datetime import datetime
from urllib.parse import unquote
from typing import List, Optional, Tuple
from pydantic import ValidationError
from nonebot.adapters.onebot.v11 import Message
from utils.message_builder import image
from nonebot.adapters.onebot.v11 import Message, MessageSegment
from nonebot.log import logger
import asyncio
from utils.message_builder import image
try:
import ujson as json
@@ -40,9 +40,10 @@ class PrettyCard(PrettyData):
class PrettyHandle(BaseHandle[PrettyData]):
def __init__(self):
super().__init__("pretty", "赛马娘", "#eff2f5")
super().__init__("pretty", "赛马娘")
self.data_files.append("pretty_card.json")
self.max_star = 3
self.game_card_color = "#eff2f5"
self.config = draw_config.pretty
self.ALL_CHAR: List[PrettyChar] = []
@@ -129,10 +130,7 @@ class PrettyHandle(BaseHandle[PrettyData]):
info = f"当前up池:{up_event.title}\n{info}"
return info.strip()
async def draw(self, count: int, pool_name: str, **kwargs) -> Message:
return await asyncio.get_event_loop().run_in_executor(None, self._draw, count, pool_name)
def _draw(self, count: int, pool_name: str, **kwargs) -> Message:
def draw(self, count: int, pool_name: str, **kwargs) -> Message:
pool_name = "char" if not pool_name else pool_name
index2card = self.get_cards(count, pool_name)
cards = [card[0] for card in index2card]
@@ -331,7 +329,9 @@ class PrettyHandle(BaseHandle[PrettyData]):
try:
title = announcement.xpath("./@title")[0]
url = "https://wiki.biligame.com/" + announcement.xpath("./@href")[0]
if "卡池" in title:
if re.match(r".*?\d{8}$", title) or re.match(
r"^\d{1,2}月\d{1,2}日.*?", title
):
break
except IndexError:
continue
@@ -348,49 +348,48 @@ class PrettyHandle(BaseHandle[PrettyData]):
char_img = ""
card_img = ""
up_chars = []
up_chars_name = []
up_cards = []
up_cards_name = []
dom = etree.HTML(result, etree.HTMLParser())
content = dom.xpath('//*[@id="mw-content-text"]/div/div/div[1]/div')[0]
heads = content.xpath("./div")
soup = BeautifulSoup(result, "lxml")
heads = soup.find_all("span", {"class": "mw-headline"})
for head in heads:
if "时间" in head.find("./img").tail or "期间" in head.find("./img").tail:
time = content.xpath("./p")[1].text.split("\n")[0]
if "时间" in head.text:
time = head.find_next("p").text.split("\n")[0]
if "~" in time:
start, end = time.split("~")
start_time = dateparser.parse(start)
end_time = dateparser.parse(end)
elif "赛马娘" in head.find("./img").tail:
char_img = content.xpath("./center")[1].find("./a/img").get("src")
lines = content.xpath("./p")[2].xpath("string(.)").split("\n")
elif "赛马娘" in head.text:
char_img = head.find_next("a", {"class": "image"}).find("img")[
"src"
]
lines = str(head.find_next("p").text).split("\n")
chars = [
line
for line in lines
if "★" in line and "[" in line and "]" in line
if "★" in line and "(" in line and ")" in line
]
for char in set(chars): # list去重
for char in chars:
star = char.count("★")
name = re.split("[ ]",char)[-1]
name = re.split(r"[()]", char)[-2].strip()
up_chars.append(
UpChar(name=name, star=star, limited=False, zoom=70)
)
up_chars_name.append(name)
elif "支援卡" in head.find("./img").tail:
card_img = content.xpath("./center")[2].find("./a/img").get("src")
lines = content.xpath("./p")[3].xpath("string(.)").split("\n")
elif "支援卡" in head.text:
card_img = head.find_next("a", {"class": "image"}).find("img")[
"src"
]
lines = str(head.find_next("p").text).split("\n")
cards = [
line
for line in lines
if "R" in line and "[" in line and "]" in line
if "R" in line and "(" in line and ")" in line
]
for card in set(cards):
for card in cards:
star = 3 if "SSR" in card else 2 if "SR" in card else 1
name = re.split("[ ]",card)[-1]
name = re.split(r"[()]", card)[-2].strip()
up_cards.append(
UpChar(name=name, star=star, limited=False, zoom=70)
)
up_cards_name.append(name)
if start_time and end_time:
if start_time <= datetime.now() <= end_time:
self.UP_CHAR = UpEvent(
@@ -399,7 +398,6 @@ class PrettyHandle(BaseHandle[PrettyData]):
start_time=start_time,
end_time=end_time,
up_char=up_chars,
up_name=",".join(up_chars_name),
)
self.UP_CARD = UpEvent(
title=title,
@@ -407,7 +405,6 @@ class PrettyHandle(BaseHandle[PrettyData]):
start_time=start_time,
end_time=end_time,
up_char=up_cards,
up_name=",".join(up_cards_name),
)
self.dump_up_char()
logger.info(f"成功获取{self.game_name_cn}当前up信息...当前up池: {title}")
@@ -419,8 +416,9 @@ class PrettyHandle(BaseHandle[PrettyData]):
self.load_up_char()
if self.UP_CHAR and self.UP_CARD:
return Message(
Message.template("重载成功!\n当前UP池子:{}\n当前支援卡池子:{}").format(
self.UP_CHAR.up_name,
self.UP_CARD.up_name,
Message.template("重载成功!\n当前UP池子:{}{:image}{:image}").format(
self.UP_CHAR.title,
self.UP_CHAR.pool_img,
self.UP_CARD.pool_img,
)
)
+19 -19
View File
@@ -1,16 +1,17 @@
import re
import random
import dateparser
from lxml import etree
from PIL import ImageDraw
import re
from datetime import datetime
from urllib.parse import unquote
from typing import List, Optional, Tuple
from pydantic import ValidationError
from nonebot.adapters.onebot.v11 import Message
from utils.message_builder import image
from urllib.parse import unquote
import dateparser
from PIL import ImageDraw
from lxml import etree
from nonebot.adapters.onebot.v11 import Message, MessageSegment
from nonebot.log import logger
import asyncio
from pydantic import ValidationError
from utils.message_builder import image
try:
import ujson as json
@@ -104,17 +105,18 @@ class PrtsHandle(BaseHandle[Operator]):
info = f"当前up池: {self.UP_EVENT.title}\n{info}"
return info.strip()
async def draw(self, count: int, **kwargs) -> Message:
return await asyncio.get_event_loop().run_in_executor(None, self._draw, count)
def _draw(self, count: int, **kwargs) -> Message:
def draw(self, count: int, **kwargs) -> Message:
index2card = self.get_cards(count)
"""这里cards修复了抽卡图文不符的bug"""
cards = [card[0] for card in index2card]
up_list = [x.name for x in self.UP_EVENT.up_char] if self.UP_EVENT else []
result = self.format_result(index2card, up_list=up_list)
pool_info = self.format_pool_info()
return pool_info + image(b64=self.generate_img(cards).pic2bs4()) + result
return (
pool_info
+ image(b64=self.generate_img(cards).pic2bs4())
+ result
)
def generate_card_img(self, card: Operator) -> BuildImage:
sep_w = 5
@@ -177,6 +179,7 @@ class PrtsHandle(BaseHandle[Operator]):
self.dump_data(data, f"draw_card_up/{self.game_name}_up_char.json")
async def _update_info(self):
"""更新信息"""
info = {}
url = "https://wiki.biligame.com/arknights/干员数据表"
result = await self.get_url(url)
@@ -288,10 +291,7 @@ class PrtsHandle(BaseHandle[Operator]):
up_chars.append(
UpChar(name=name, star=star, limited=False, zoom=zoom)
)
if start_time <= datetime.now() <= end_time: # 跳过过时的卡池
break # 这里break会导致个问题:如果一个公告里有两个池子,会漏掉下面的池子,比如 5.19 的定向寻访。但目前我也没啥好想法解决
chars: List[str] = [] # 查找下一个卡池之前清空 chars
up_chars = [] # 查找下一个卡池之前清空 up_chars
break # 这里break会导致个问题:如果一个公告里有两个池子,会漏掉下面的池子,比如 5.19 的定向寻访。但目前我也没啥好想法解决
if title and start_time and end_time:
if start_time <= datetime.now() <= end_time:
self.UP_EVENT = UpEvent(
@@ -309,6 +309,6 @@ class PrtsHandle(BaseHandle[Operator]):
await self.update_up_char()
self.load_up_char()
if self.UP_EVENT:
return f"重载成功!\n当前UP池子:{self.UP_EVENT.title}" + image(
return f"重载成功!\n当前UP池子:{self.UP_EVENT.title}" + MessageSegment.image(
self.UP_EVENT.pool_img
)