fit nonebot.beta2

This commit is contained in:
HibiKier
2022-02-19 18:20:19 +08:00
parent ab443a21ec
commit 7dd68cf1ef
212 changed files with 6857 additions and 5615 deletions
+105 -167
View File
@@ -1,16 +1,13 @@
from nonebot import on_regex, on_keyword
from nonebot.adapters.cqhttp import Bot, MessageEvent, Message, GroupMessageEvent
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, Message
from nonebot.permission import SUPERUSER
from nonebot.typing import T_State
from .genshin_handle import (
genshin_draw,
update_genshin_info,
reset_count,
reload_genshin_pool,
)
from nonebot.params import RegexGroup
from utils.utils import scheduler
from .genshin_handle import genshin_draw, update_genshin_info, reset_count, reload_genshin_pool
from .prts_handle import update_prts_info, prts_draw, reload_prts_pool
from .pretty_handle import update_pretty_info, pretty_draw, reload_pretty_pool
from .guardian_handle import update_guardian_info, guardian_draw
from .guardian_handle import update_guardian_info, guardian_draw, reload_guardian_pool
from .pcr_handle import update_pcr_info, pcr_draw
from .azur_handle import update_azur_info, azur_draw
from .fgo_handle import update_fgo_info, fgo_draw
@@ -18,21 +15,12 @@ from .onmyoji_handle import update_onmyoji_info, onmyoji_draw
from .update_game_info import update_info
from .util import is_number, check_num
from .rule import is_switch
from .config import (
PRTS_FLAG,
PRETTY_FLAG,
GUARDIAN_FLAG,
GENSHIN_FLAG,
PCR_FLAG,
AZUR_FLAG,
FGO_FLAG,
ONMYOJI_FLAG,
)
from .config import draw_config
from .async_update_game_info import async_update_game
from typing import Tuple, Any
import re
import asyncio
from utils.utils import scheduler
from services.log import logger
__zx_plugin_name__ = "游戏抽卡"
__plugin_usage__ = """
@@ -101,81 +89,44 @@ __plugin_settings__ = {
"cmd": ["游戏抽卡", "抽卡"],
}
prts = on_regex(r'.*?方舟([1-9|一][0-9]{0,2}[抽|井|连])', rule=is_switch('prts'), priority=5, block=True)
prts_update = on_keyword({'更新方舟信息', '更新明日方舟信息'}, permission=SUPERUSER, priority=1, block=True)
prts_up_reload = on_keyword({'重载方舟卡池'}, priority=1, block=True)
prts = on_regex(
r".*?方舟[1-9|一][0-9]{0,2}[抽|井]", rule=is_switch("prts"), priority=5, block=True
)
prts_update = on_keyword(
{"更新方舟信息", "更新明日方舟信息"}, permission=SUPERUSER, priority=1, block=True
)
prts_up_reload = on_keyword({"重载方舟卡池"}, priority=1, block=True)
genshin = on_regex(r'.*?原神(武器|角色)?池?[1-9|一][0-9]{0,2}[抽|井|连]', rule=is_switch('genshin'), priority=5, block=True)
genshin_update = on_keyword({'更新原神信息'}, permission=SUPERUSER, priority=1, block=True)
genshin_reset = on_keyword({'重置原神抽卡'}, priority=1, block=True)
genshin_up_reload = on_keyword({'重载原神卡池'}, priority=1, block=True)
genshin = on_regex(
".*?原神(武器|角色)?池?[1-9|一][0-9]{0,2}[抽|井]",
rule=is_switch("genshin"),
priority=5,
block=True,
)
genshin_update = on_keyword({"更新原神信息"}, permission=SUPERUSER, priority=1, block=True)
genshin_reset = on_keyword({"重置原神抽卡"}, priority=1, block=True)
genshin_up_reload = on_keyword({"重载原神卡池"}, priority=1, block=True)
pretty = on_regex(r'.*?马娘卡?[1-9|一][0-9]{0,2}[抽|井|连]', rule=is_switch('pretty'), priority=5, block=True)
pretty_update = on_keyword({'更新马娘信息', '更新赛马娘信息'}, permission=SUPERUSER, priority=1, block=True)
pretty_up_reload = on_keyword({'重载赛马娘卡池'}, priority=1, block=True)
pretty = on_regex(
".*?马娘卡?[1-9|一][0-9]{0,2}[抽|井]", rule=is_switch("pretty"), priority=5, block=True
)
pretty_update = on_keyword(
{"更新马娘信息", "更新赛马娘信息"}, permission=SUPERUSER, priority=1, block=True
)
pretty_up_reload = on_keyword({"重载赛马娘卡池"}, priority=1, block=True)
guardian = on_regex(r'.*?坎公骑冠剑武?器?[1-9|一][0-9]{0,2}[抽|井|连]', rule=is_switch('guardian'), priority=5, block=True)
guardian_update = on_keyword({'更新坎公骑冠剑信息'}, permission=SUPERUSER, priority=1, block=True)
guardian_up_reload = on_keyword({'重载坎公骑冠剑卡池'}, priority=1, block=True)
guardian = on_regex(
".*?坎公骑冠剑武?器?[1-9|一][0-9]{0,2}[抽|井]",
rule=is_switch("guardian"),
priority=5,
block=True,
)
guardian_update = on_keyword(
{"更新坎公骑冠剑信息"}, permission=SUPERUSER, priority=1, block=True
)
pcr = on_regex(r'.*?(pcr|公主连结|公主连接|公主链接|公主焊接)[1-9|一][0-9]{0,2}[抽|井|连]', rule=is_switch('pcr'), priority=5, block=True)
pcr_update = on_keyword({'更新pcr信息', '更新公主连结信息'}, permission=SUPERUSER, priority=1, block=True)
pcr = on_regex(
".*?(pcr|公主连结|公主连接|公主链接|公主焊接)[1-9|一][0-9]{0,2}[抽|井]",
rule=is_switch("pcr"),
priority=5,
block=True,
)
pcr_update = on_keyword(
{"更新pcr信息", "更新公主连结信息"}, permission=SUPERUSER, priority=1, block=True
)
azur = on_regex(r'.*?碧蓝航?线?(轻型|重型|特型)池?[1-9|一][0-9]{0,2}[抽|连]', rule=is_switch('azur'), priority=5, block=True)
azur_update = on_keyword({'更新碧蓝信息', '更新碧蓝航线信息'}, permission=SUPERUSER, priority=1, block=True)
azur = on_regex(
".*?碧蓝航?线?(轻型|重型|特型)池?[1-9|一][0-9]{0,2}[抽]",
rule=is_switch("azur"),
priority=5,
block=True,
)
azur_update = on_keyword(
{"更新碧蓝信息", "更新碧蓝航线信息"}, permission=SUPERUSER, priority=1, block=True
)
fgo = on_regex(r'.*?fgo[1-9|一][0-9]{0,2}[抽|连]', rule=is_switch('fgo'), priority=5, block=True)
fgo_update = on_keyword({'更新fgo信息'}, permission=SUPERUSER, priority=1, block=True)
fgo = on_regex(
".*?fgo[1-9|一][0-9]{0,2}[抽]", rule=is_switch("fgo"), priority=5, block=True
)
fgo_update = on_keyword({"更新fgo信息"}, permission=SUPERUSER, priority=1, block=True)
onmyoji = on_regex(
".*?阴阳师[1-9|一][0-9]{0,2}[抽]", rule=is_switch("onmyoji"), priority=5, block=True
)
onmyoji_update = on_keyword({"更新阴阳师信息"}, permission=SUPERUSER, priority=1, block=True)
onmyoji = on_regex(r'.*?阴阳师[1-9|一][0-9]{0,2}[抽|连]', rule=is_switch('onmyoji'), priority=5, block=True)
onmyoji_update = on_keyword({'更新阴阳师信息'}, permission=SUPERUSER, priority=1, block=True)
@prts.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
async def _(bot: Bot, event: MessageEvent, state: T_State, reg: Tuple[Any, ...] = RegexGroup()):
msg = str(event.get_message()).strip()
if msg in ["方舟一井", "方舟1井"]:
print(reg)
if msg in ['方舟一井', '方舟1井']:
num = 300
else:
rmsg = re.search(r".*?方舟(.*)抽", msg)
rmsg = re.search(r'.*?方舟(.*)[抽|连]', msg)
if rmsg:
num, flag = check_num(rmsg.group(1), 300)
if not flag:
@@ -183,31 +134,28 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
else:
return
await prts.send(await prts_draw(int(num)), at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 方舟 {num}抽"
)
@prts_up_reload.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
text = await reload_prts_pool()
await prts_up_reload.finish(Message(f"重载完成!\n{text}"))
await prts_up_reload.finish(Message(f'重载完成!\n{text}'))
@genshin.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip()
rmsg = re.search(r".*?原神(武器|角色)?池?(.*)[抽|井]", msg)
rmsg = re.search(r'.*?原神(武器|角色)?池?(.*)[抽|井|连]', msg)
if rmsg:
pool_name = rmsg.group(1)
if pool_name == "武器":
pool_name = "arms"
elif pool_name == "角色":
pool_name = "char"
if pool_name == '武器':
pool_name = 'arms'
elif pool_name == '角色':
pool_name = 'char'
else:
pool_name = ""
pool_name = ''
num = rmsg.group(2)
if msg.find("一井") != -1 or msg.find("1井") != -1:
if msg.find('一井') != -1 or msg.find('1井') != -1:
num = 180
else:
num, flag = check_num(num, 180)
@@ -215,94 +163,89 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
await genshin.finish(num, at_sender=True)
else:
return
await genshin.send(
await genshin_draw(event.user_id, int(num), pool_name), at_sender=True
)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 原神 {num}抽"
)
await genshin.send(await genshin_draw(event.user_id, int(num), pool_name), at_sender=True)
@genshin_up_reload.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
text = await reload_genshin_pool()
await genshin_reset.finish(Message(f"重载成功!\n{text}"))
await genshin_reset.finish(Message(f'重载成功!\n{text}'))
@genshin_reset.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
reset_count(event.user_id)
await genshin_reset.send("重置了原神抽卡次数", at_sender=True)
await genshin_reset.send('重置了原神抽卡次数', at_sender=True)
@pretty.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip()
if msg.find("1井") != -1 or msg.find("一井") != -1:
if msg.find('1井') != -1 or msg.find('一井') != -1:
num = 200
if msg.find("卡") == -1:
pool_name = "char"
pool_name = 'char'
else:
pool_name = "card"
pool_name = 'card'
else:
rmsg = re.search(r".*?马娘(.*)抽", msg)
rmsg = re.search(r'.*?马娘(.*)[抽|连]', msg)
if rmsg:
num = rmsg.group(1)
if num[0] == "卡":
if num[0] == '卡':
num = num[1:]
pool_name = "card"
pool_name = 'card'
else:
pool_name = "char"
pool_name = 'char'
num, flag = check_num(num, 200)
if not flag:
await pretty.finish(num, at_sender=True)
else:
return
await pretty.send(await pretty_draw(int(num), pool_name), at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 赛马娘 {num}抽"
)
@pretty_up_reload.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
text = await reload_pretty_pool()
await genshin_reset.finish(Message(f"重载成功!\n{text}"))
await genshin_reset.finish(Message(f'重载成功!\n{text}'))
@guardian.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip()
pool_name = "char"
if msg.find("1井") != -1 or msg.find("一井") != -1:
pool_name = 'char'
if msg.find('1井') != -1 or msg.find('一井') != -1:
num = 300
if msg.find("武器") != -1:
pool_name = "arms"
if msg.find('武器') != -1:
pool_name = 'arms'
else:
rmsg = re.search(r".*?坎公骑冠剑(.*)抽", msg)
rmsg = re.search(r'.*?坎公骑冠剑(.*)[抽|连]', msg)
if rmsg:
num = rmsg.group(1)
if num.find("武器") != -1:
pool_name = "arms"
num = num.replace("武器", "")
if num.find('武器') != -1:
pool_name = 'arms'
num = num.replace('武器', '')
num, flag = check_num(num, 300)
if not flag:
await guardian.finish(num, at_sender=True)
else:
return
await guardian.send(await guardian_draw(int(num), pool_name), at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 坎公骑冠剑 {num}抽"
)
@guardian_up_reload.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
text = await reload_guardian_pool()
await genshin_reset.finish(Message(f'重载成功!\n{text}'))
@pcr.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip()
if msg.find("1井") != -1 or msg.find("一井") != -1:
if msg.find('1井') != -1 or msg.find('一井') != -1:
num = 300
else:
rmsg = re.search(r".*?(pcr|公主连结)(.*)[抽|井]", msg)
rmsg = re.search(r'.*?(pcr|公主连结)(.*)[抽|井|连]', msg)
if rmsg:
num, flag = check_num(rmsg.group(2), 300)
if not flag:
@@ -310,15 +253,12 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
else:
return
await pcr.send(await pcr_draw(int(num)), at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 公主连结 {num}抽"
)
@azur.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip()
rmsg = re.search(".*?碧蓝航?线?(轻型|重型|特型)池?(.*)[抽]", msg)
rmsg = re.search(r'.*?碧蓝航?线?(轻型|重型|特型)池?(.*)[抽|连]', msg)
if rmsg:
pool_name = rmsg.group(1)
num, flag = check_num(rmsg.group(2), 300)
@@ -327,15 +267,12 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
else:
return
await azur.send(await azur_draw(int(num), pool_name), at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 碧蓝航线 {num}抽"
)
@fgo.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip()
rmsg = re.search(".*?fgo(.*)抽", msg)
rmsg = re.search(r'.*?fgo(.*)[抽|连]', msg)
if rmsg:
num, flag = check_num(rmsg.group(1), 300)
if not flag:
@@ -343,15 +280,12 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
else:
return
await fgo.send(await fgo_draw(int(num)), at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) fgo {num}抽"
)
@onmyoji.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip()
rmsg = re.search(".*?阴阳师(.*)抽", msg)
rmsg = re.search(r'.*?阴阳师(.*)[抽|连]', msg)
if rmsg:
num, flag = check_num(rmsg.group(1), 300)
if not flag:
@@ -359,118 +293,122 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
else:
return
await onmyoji.send(await onmyoji_draw(int(num)), at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 阴阳师 {num}抽"
)
@prts_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_prts_info()
await prts_update.finish("更新完成!")
await prts_update.finish('更新完成!')
@genshin_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_genshin_info()
await genshin_update.finish("更新完成!")
await genshin_update.finish('更新完成!')
@pretty_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_pretty_info()
await genshin_update.finish("更新完成!")
await genshin_update.finish('更新完成!')
@guardian_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_guardian_info()
await genshin_update.finish("更新完成!")
await genshin_update.finish('更新完成!')
@pcr_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_pcr_info()
await genshin_update.finish("更新完成!")
await genshin_update.finish('更新完成!')
@azur_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_azur_info()
await genshin_update.finish("更新完成!")
await genshin_update.finish('更新完成!')
@fgo_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_fgo_info()
await genshin_update.finish("更新完成!")
await genshin_update.finish('更新完成!')
@onmyoji_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_onmyoji_info()
await genshin_update.finish("更新完成!")
await genshin_update.finish('更新完成!')
# 更新资源
@scheduler.scheduled_job(
"cron",
'cron',
hour=4,
minute=1,
)
async def _():
tasks = []
if PRTS_FLAG:
if draw_config.PRTS_FLAG:
tasks.append(asyncio.ensure_future(update_prts_info()))
if GENSHIN_FLAG:
if draw_config.GENSHIN_FLAG:
tasks.append(asyncio.ensure_future(update_genshin_info()))
if PRETTY_FLAG:
if draw_config.PRETTY_FLAG:
tasks.append(asyncio.ensure_future(update_pretty_info()))
if GUARDIAN_FLAG:
if draw_config.GUARDIAN_FLAG:
tasks.append(asyncio.ensure_future(update_guardian_info()))
if PCR_FLAG:
if draw_config.PCR_FLAG:
tasks.append(asyncio.ensure_future(update_pcr_info()))
if AZUR_FLAG:
if draw_config.AZUR_FLAG:
tasks.append(asyncio.ensure_future(update_azur_info()))
if FGO_FLAG:
if draw_config.FGO_FLAG:
tasks.append(asyncio.ensure_future(update_fgo_info()))
if ONMYOJI_FLAG:
if draw_config.ONMYOJI_FLAG:
tasks.append(asyncio.ensure_future(update_onmyoji_info()))
await asyncio.gather(*tasks)
logger.info("draw_card 抽卡自动更新完成...")
# 每天四点重载方舟up卡池
@scheduler.scheduled_job(
"cron",
'cron',
hour=4,
minute=1,
)
async def _():
if PRTS_FLAG:
if draw_config.PRTS_FLAG:
await reload_prts_pool()
logger.info("自动重载方舟卡池UP成功")
# 每天四点重载赛马娘up卡池
@scheduler.scheduled_job(
"cron",
'cron',
hour=4,
minute=1,
)
async def _():
if PRETTY_FLAG:
if draw_config.PRETTY_FLAG:
await reload_pretty_pool()
logger.info("自动重载赛马娘UP成功")
# 每天下午六点点重载原神up卡池
@scheduler.scheduled_job(
"cron",
'cron',
hour=18,
minute=1,
)
async def _():
if PRTS_FLAG:
if draw_config.PRTS_FLAG:
await reload_genshin_pool()
logger.info("自动重载原神卡池UP成功")
# 重载坎公骑冠剑卡池
@scheduler.scheduled_job(
'cron',
hour=4,
minute=1,
)
async def _():
if draw_config.GUARDIAN_FLAG:
await reload_guardian_pool()
+72 -67
View File
@@ -1,11 +1,11 @@
from bs4 import BeautifulSoup
from datetime import datetime, timedelta
from .config import DRAW_PATH
from pathlib import Path
from asyncio.exceptions import TimeoutError
from services.log import logger
from utils.http_utils import AsyncHttpx
import re
from datetime import datetime, timedelta
from .config import DRAW_DATA_PATH
from asyncio.exceptions import TimeoutError
from nonebot.log import logger
from utils.http_utils import AsyncHttpx
try:
import ujson as json
except ModuleNotFoundError:
@@ -13,10 +13,10 @@ except ModuleNotFoundError:
headers = {'User-Agent': '"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)"'}
prts_up_char = Path(DRAW_PATH + "/draw_card_up/prts_up_char.json")
genshin_up_char = Path(DRAW_PATH + "/draw_card_up/genshin_up_char.json")
pretty_up_char = Path(DRAW_PATH + "/draw_card_up/pretty_up_char.json")
guardian_up_char = Path(DRAW_PATH + "/draw_card_up/guardian_up_char.json")
prts_up_char = DRAW_DATA_PATH / "draw_card_up" / "prts_up_char.json"
genshin_up_char = DRAW_DATA_PATH / "draw_card_up" / "genshin_up_char.json"
pretty_up_char = DRAW_DATA_PATH / "draw_card_up" / "pretty_up_char.json"
guardian_up_char = DRAW_DATA_PATH / "draw_card_up" / "guardian_up_char.json"
prts_url = "https://ak.hypergryph.com/news.html"
genshin_url = "https://wiki.biligame.com/ys/%E7%A5%88%E6%84%BF"
@@ -26,37 +26,37 @@ guardian_url = "https://wiki.biligame.com/gt/%E9%A6%96%E9%A1%B5"
# 是否过时
def is_expired(data: dict):
try:
times = data['time'].split('-')
for i in range(len(times)):
times[i] = str(datetime.now().year) + '-' + times[i].split('日')[0].strip().replace('月', '-')
start_date = datetime.strptime(times[0], '%Y-%m-%d').date()
end_date = datetime.strptime(times[1], '%Y-%m-%d').date()
now = datetime.now().date()
except ValueError:
return False
times = data['time'].split('-')
for i in range(len(times)):
times[i] = str(datetime.now().year) + '-' + times[i].split('日')[0].strip().replace('月', '-')
start_date = datetime.strptime(times[0], '%Y-%m-%d').date()
end_date = datetime.strptime(times[1], '%Y-%m-%d').date()
now = datetime.now().date()
return not start_date <= now <= end_date
# 检查写入
def check_write(data: dict, up_char_file):
if is_expired(data['char']):
for x in list(data.keys()):
data[x]['title'] = ''
else:
with open(up_char_file, 'w', encoding='utf8') as f:
json.dump(data, f, indent=4, ensure_ascii=False)
if not up_char_file.exists():
with open(up_char_file, 'w', encoding='utf8') as f:
json.dump(data, f, indent=4, ensure_ascii=False)
else:
with open(up_char_file, 'r', encoding='utf8') as f:
old_data = json.load(f)
if is_expired(old_data['char']):
return old_data
try:
if is_expired(data['char']):
for x in list(data.keys()):
data[x]['title'] = ''
else:
with open(up_char_file, 'w', encoding='utf8') as f:
json.dump(data, f, indent=4, ensure_ascii=False)
if not up_char_file.exists():
with open(up_char_file, 'w', encoding='utf8') as f:
json.dump(data, f, indent=4, ensure_ascii=False)
else:
with open(up_char_file, 'r', encoding='utf8') as f:
old_data = json.load(f)
if is_expired(old_data['char']):
return old_data
else:
with open(up_char_file, 'w', encoding='utf8') as f:
json.dump(data, f, indent=4, ensure_ascii=False)
except ValueError:
pass
return data
@@ -66,17 +66,22 @@ class PrtsAnnouncement:
self.game_name = '明日方舟'
async def _get_announcement_text(self):
text = (await AsyncHttpx.get(prts_url)).text
soup = BeautifulSoup(text, 'lxml')
res = await AsyncHttpx.get(prts_url, timeout=7)
soup = BeautifulSoup(res.text, 'lxml')
ol = soup.find('ol', {'class': 'articleList active', 'data-category-key': 'LATEST'})
for li in ol:
itype = li.find('span', {'class': 'articleItemCate'}).text
if itype == '活动':
type_ = li.find('span', {'class': 'articleItemCate'}).text
if type_ == '活动':
a = li.find('a')['href']
return (await AsyncHttpx.get(f'https://ak.hypergryph.com{a}')).text
return (await AsyncHttpx.get(f'https://ak.hypergryph.com{a}', timeout=7)).text
async def update_up_char(self):
prts_up_char.parent.mkdir(parents=True, exist_ok=True)
if prts_up_char.exists():
with open(prts_up_char, 'r', encoding='utf8') as f:
data = json.load(f)
if not data.get('char'):
prts_up_char.unlink()
try:
data = {'char': {'up_char': {'6': {}, '5': {}, '4': {}}, 'title': '', 'time': '', 'pool_img': ''}}
text = await self._get_announcement_text()
@@ -145,7 +150,7 @@ class GenshinAnnouncement:
self.game_name = '原神'
async def _get_announcement_text(self):
return (await AsyncHttpx.get(genshin_url)).text
return (await AsyncHttpx.get(genshin_url, timeout=7)).text
async def update_up_char(self):
genshin_up_char.parent.mkdir(exist_ok=True, parents=True)
@@ -162,34 +167,34 @@ class GenshinAnnouncement:
trs = table.find('tbody').find_all('tr')
pool_img = trs[0].find('th').find('img')
if pool_img['title'].find('角色活动') == -1:
itype = 'arms'
type_ = 'arms'
else:
itype = 'char'
type_ = 'char'
try:
data[itype]['pool_img'] = str(pool_img['srcset']).split(' ')[0]
data[type_]['pool_img'] = str(pool_img['srcset']).split(' ')[0]
except KeyError:
data[itype]['pool_img'] = pool_img['src']
data[itype]['title'] = str(pool_img['title']).split(f'期{"角色" if itype == "char" else "武器"}')[0][:-3]
data[itype]['time'] = trs[1].find('td').text
if data[itype]['time'][-1] == '\n':
data[itype]['time'] = data[itype]['time'][:-1]
if '版本更新后' in data[itype]['time']:
sp = data[itype]['time'].split('~')
data[type_]['pool_img'] = pool_img['src']
data[type_]['title'] = str(pool_img['title']).split(f'期{"角色" if type_ == "char" else "武器"}')[0][:-3]
data[type_]['time'] = trs[1].find('td').text
if data[type_]['time'][-1] == '\n':
data[type_]['time'] = data[type_]['time'][:-1]
if '版本更新后' in data[type_]['time']:
sp = data[type_]['time'].split('~')
end_time = datetime.strptime(sp[1].strip(), "%Y/%m/%d %H:%M")
start_time = end_time - timedelta(days=20)
data[itype]['time'] = start_time.strftime('%Y/%m/%d') + ' ~ ' + end_time.strftime('%Y/%m/%d')
data[type_]['time'] = start_time.strftime('%Y/%m/%d') + ' ~ ' + end_time.strftime('%Y/%m/%d')
tmp = ''
for tm in data[itype]['time'].split('~'):
for tm in data[type_]['time'].split('~'):
date_time_sp = tm.split('/')
date_time_sp[2] = date_time_sp[2].strip().replace(' ', '日 ')
tmp += date_time_sp[1] + '月' + date_time_sp[2] + ' - '
data[itype]['time'] = tmp[:-2].strip()
data[type_]['time'] = tmp[:-2].strip()
for a in trs[2].find('td').find_all('a'):
char_name = a['title']
data[itype]['up_char']['5'][char_name] = "50"
data[type_]['up_char']['5'][char_name] = "50"
for a in trs[3].find('td').find_all('a'):
char_name = a['title']
data[itype]['up_char']['4'][char_name] = "50"
data[type_]['up_char']['4'][char_name] = "50"
except TimeoutError:
logger.warning(f'更新原神UP池信息超时...')
if genshin_up_char.exists():
@@ -214,10 +219,9 @@ class PrettyAnnouncement:
self.game_name = '赛马娘'
async def _get_announcement_text(self):
text = (await AsyncHttpx.get(pretty_url)).text
soup = BeautifulSoup(text, 'lxml')
res = await AsyncHttpx.get(pretty_url, timeout=7)
soup = BeautifulSoup(res.text, 'lxml')
divs = soup.find('div', {'id': 'mw-content-text'}).find('div').find_all('div')
title = " "
for div in divs:
a = div.find('a')
try:
@@ -227,10 +231,9 @@ class PrettyAnnouncement:
if title.find('新角色追加') != -1:
url = a['href']
break
return (await AsyncHttpx.get(f'https://wiki.biligame.com/{url}')).text, title[:-2]
return (await AsyncHttpx.get(f'https://wiki.biligame.com/{url}', timeout=7)).text, title[:-2]
async def update_up_char(self):
pretty_up_char.parent.mkdir(exist_ok=True, parents=True)
data = {
'char': {'up_char': {'3': {}, '2': {}, '1': {}}, 'title': '', 'time': '', 'pool_img': ''},
'card': {'up_char': {'3': {}, '2': {}, '1': {}}, 'title': '', 'time': '', 'pool_img': ''}
@@ -243,12 +246,14 @@ class PrettyAnnouncement:
context = soup.find('div', {'class': 'mw-parser-output'})
data['char']['title'] = title
data['card']['title'] = title
r = re.search(r'(\d{1,2}/\d{1,2} \d{1,2}:\d{1,2} ~ \d{1,2}/\d{1,2} \d{1,2}:\d{1,2})', str(context.text))
if r:
time = str(r.group(1))
for big in context.find_all('big'):
r = re.search(r'\d{1,2}/\d{1,2} \d{1,2}:\d{1,2}', str(big.text))
if r:
time = str(big.text)
break
else:
logger.error('赛马娘UP无法找到活动日期....取消更新UP池子...')
return check_write(data, pretty_up_char)
logger.warning('赛马娘UP无法找到活动日期....取消更新UP池子...')
return
time = time.replace('~', '-').replace('/', '月').split(' ')
time = time[0] + '日 ' + time[1] + ' - ' + time[3] + '日 ' + time[4]
data['char']['time'] = time
@@ -309,7 +314,7 @@ class PrettyAnnouncement:
if star == 'R':
data['card']['up_char']['1'][char_name] = '70'
# 日文->中文
with open(DRAW_PATH + 'pretty_card.json', 'r', encoding='utf8') as f:
with open(DRAW_DATA_PATH / 'pretty_card.json', 'r', encoding='utf8') as f:
all_data = json.load(f)
for star in data['card']['up_char'].keys():
for name in list(data['card']['up_char'][star].keys()):
@@ -338,7 +343,7 @@ class GuardianAnnouncement:
self.game_name = '坎公骑冠剑'
async def _get_announcement_text(self):
return (await AsyncHttpx.get(guardian_url)).text
return (await AsyncHttpx.get(guardian_url, timeout=7)).text
async def update_up_char(self):
data = {
+16 -23
View File
@@ -1,7 +1,6 @@
import asyncio
import nonebot
import os
from services.log import logger
from nonebot.log import logger
from .pcr_handle import update_pcr_info, init_pcr_data
from .azur_handle import update_azur_info, init_azur_data
from .prts_handle import update_prts_info, init_prts_data
@@ -10,11 +9,10 @@ from .guardian_handle import update_guardian_info, init_guardian_data
from .genshin_handle import update_genshin_info, init_genshin_data
from .fgo_handle import update_fgo_info, init_fgo_data
from .onmyoji_handle import update_onmyoji_info, init_onmyoji_data
from .config import DRAW_PATH, PRTS_FLAG, PRETTY_FLAG, GUARDIAN_FLAG, PCR_FLAG, AZUR_FLAG, GENSHIN_FLAG, FGO_FLAG, \
ONMYOJI_FLAG
from .config import draw_config, DRAW_DATA_PATH
driver: nonebot.Driver = nonebot.get_driver()
driver = nonebot.get_driver()
@driver.on_startup
@@ -22,49 +20,44 @@ async def async_update_game():
tasks = []
init_lst = [init_pcr_data, init_pretty_data, init_azur_data, init_prts_data, init_genshin_data, init_guardian_data,
init_fgo_data, init_onmyoji_data]
if PRTS_FLAG and not os.path.exists(DRAW_PATH + 'prts.json'):
if draw_config.PRTS_FLAG and not (DRAW_DATA_PATH / 'prts.json').exists():
tasks.append(asyncio.ensure_future(update_prts_info()))
init_lst.remove(init_prts_data)
if PRETTY_FLAG and (not os.path.exists(DRAW_PATH + 'pretty.json') or
not os.path.exists(DRAW_PATH + 'pretty_card.json')):
if draw_config.PRETTY_FLAG and (not (DRAW_DATA_PATH / 'pretty.json').exists() or
not (DRAW_DATA_PATH / 'pretty_card.json').exists()):
tasks.append(asyncio.ensure_future(update_pretty_info()))
init_lst.remove(init_pretty_data)
if GUARDIAN_FLAG and not os.path.exists(DRAW_PATH + 'guardian.json'):
if draw_config.GUARDIAN_FLAG and not (DRAW_DATA_PATH / 'guardian.json').exists():
tasks.append(asyncio.ensure_future(update_guardian_info()))
init_lst.remove(init_guardian_data)
if PCR_FLAG and not os.path.exists(DRAW_PATH + 'pcr.json'):
if draw_config.PCR_FLAG and not (DRAW_DATA_PATH / 'pcr.json').exists():
tasks.append(asyncio.ensure_future(update_pcr_info()))
init_lst.remove(init_pcr_data)
if GENSHIN_FLAG and (not os.path.exists(DRAW_PATH + 'genshin.json') or
not os.path.exists(DRAW_PATH + 'genshin_arms.json')):
if draw_config.GENSHIN_FLAG and (not (DRAW_DATA_PATH / 'genshin.json').exists() or
not (DRAW_DATA_PATH / 'genshin_arms.json').exists()):
tasks.append(asyncio.ensure_future(update_genshin_info()))
init_lst.remove(init_genshin_data)
if AZUR_FLAG and not os.path.exists(DRAW_PATH + 'azur.json'):
if draw_config.AZUR_FLAG and not (DRAW_DATA_PATH / 'azur.json').exists():
tasks.append(asyncio.ensure_future(update_azur_info()))
init_lst.remove(init_azur_data)
if FGO_FLAG and (not os.path.exists(DRAW_PATH + 'fgo.json') or
not os.path.exists(DRAW_PATH + 'fgo_card.json')):
if draw_config.FGO_FLAG and (not (DRAW_DATA_PATH / 'fgo.json').exists() or
not (DRAW_DATA_PATH / 'fgo_card.json').exists()):
tasks.append(asyncio.ensure_future(update_fgo_info()))
init_lst.remove(init_fgo_data)
if ONMYOJI_FLAG and not os.path.exists(DRAW_PATH + 'onmyoji.json'):
if draw_config.ONMYOJI_FLAG and not (DRAW_DATA_PATH / 'onmyoji.json').exists():
tasks.append(asyncio.ensure_future(update_onmyoji_info()))
init_lst.remove(init_onmyoji_data)
try:
await asyncio.gather(*tasks)
for func in init_lst:
await func()
except asyncio.exceptions.CancelledError:
logger.info('更新异常:CancelledError,再次更新...')
logger.warning('更新异常:CancelledError,再次更新...')
await async_update_game()
+12 -13
View File
@@ -1,9 +1,8 @@
from nonebot.adapters.cqhttp import MessageSegment
from nonebot.adapters.onebot.v11 import MessageSegment
import random
from .update_game_simple_info import update_simple_info
from .util import generate_img, init_star_rst, BaseData, set_list, get_star, max_card, format_card_information
from .config import AZUR_ONE_P, AZUR_TWO_P, AZUR_THREE_P, AZUR_FOUR_P, AZUR_FLAG, DRAW_PATH
from .config import draw_config, DRAW_DATA_PATH
from dataclasses import dataclass
from .init_card_pool import init_game_pool
try:
@@ -16,7 +15,7 @@ ALL_CHAR = []
@dataclass
class AzurChar(BaseData):
itype: str # 舰娘类型
type_: str # 舰娘类型
async def azur_draw(count: int, pool_name: str):
@@ -42,22 +41,22 @@ async def update_azur_info():
async def init_azur_data():
global ALL_CHAR
if AZUR_FLAG:
with open(DRAW_PATH + 'azur.json', 'r', encoding='utf8') as f:
if draw_config.AZUR_FLAG:
with (DRAW_DATA_PATH / 'azur.json').open('r', encoding='utf8') as f:
azur_dict = json.load(f)
ALL_CHAR = init_game_pool('azur', azur_dict, AzurChar)
# 抽取卡池
def _get_azur_card(pool_name: str):
def _get_azur_card(pool_name: str, mode: int = 1):
global ALL_CHAR
azur_config = draw_config.azur
if pool_name == '轻型':
itype = ['驱逐', '轻巡', '维修']
type_ = ['驱逐', '轻巡', '维修']
elif pool_name == '重型':
itype = ['重巡', '战列', '战巡', '重炮']
type_ = ['重巡', '战列', '战巡', '重炮']
else:
itype = ['维修', '潜艇', '重巡', '轻航', '航母']
star = get_star([4, 3, 2, 1], [AZUR_FOUR_P, AZUR_THREE_P, AZUR_TWO_P, AZUR_ONE_P])
chars = [x for x in ALL_CHAR if x.star == star and x.itype in itype and not x.limited]
type_ = ['维修', '潜艇', '重巡', '轻航', '航母']
star = get_star([4, 3, 2, 1], [azur_config.AZUR_FOUR_P, azur_config.AZUR_THREE_P, azur_config.AZUR_TWO_P, azur_config.AZUR_ONE_P])
chars = [x for x in ALL_CHAR if x.star == star and x.type_ in type_ and not x.limited]
return random.choice(chars), 4 - star
+123 -371
View File
@@ -1,6 +1,7 @@
import nonebot
from pathlib import Path
from configs.path_config import DATA_PATH
from nonebot.log import logger
from pydantic import BaseModel, Extra, ValidationError
from configs.path_config import IMAGE_PATH, DATA_PATH
from configs.config import Config
try:
@@ -9,133 +10,111 @@ except ModuleNotFoundError:
import json
DRAW_PATH = DATA_PATH + "/draw_card/"
_draw_config = Path(rf"{DRAW_PATH}/draw_card_config/draw_card_config.json")
# 原神
class GenshinConfig(BaseModel, extra=Extra.ignore):
GENSHIN_FIVE_P: float = 0.006
GENSHIN_FOUR_P: float = 0.051
GENSHIN_THREE_P: float = 0.43
GENSHIN_G_FIVE_P: float = 0.13
GENSHIN_G_FOUR_P: float = 0.016
I72_ADD: float = 0.0585
for game_flag, game_name in zip(
[
"PRTS_FLAG",
"GENSHIN_FLAG",
"PRETTY_FLAG",
"GUARDIAN_FLAG",
"PCR_FLAG",
"AZUR_FLAG",
"FGO_FLAG",
"ONMYOJI_FLAG",
"PCR_TAI",
],
["明日方舟", "原神", "赛马娘", "坎公骑冠剑", "公主连结", "碧蓝航线", "命运-冠位指定(FGO)", "阴阳师", "pcr台服卡池"],
):
Config.add_plugin_config(
"draw_card",
game_flag,
True,
name="游戏抽卡",
help_=f"{game_name} 抽卡开关",
default_value=True,
)
Config.add_plugin_config(
"draw_card", "SEMAPHORE", 5, help_=f"异步数据下载数量限制", default_value=5
)
PRTS_FLAG = Config.get_config("draw_card", "PRTS_FLAG")
GENSHIN_FLAG = Config.get_config("draw_card", "GENSHIN_FLAG")
PRETTY_FLAG = Config.get_config("draw_card", "PRETTY_FLAG")
GUARDIAN_FLAG = Config.get_config("draw_card", "GUARDIAN_FLAG")
PCR_FLAG = Config.get_config("draw_card", "PCR_FLAG")
AZUR_FLAG = Config.get_config("draw_card", "AZUR_FLAG")
FGO_FLAG = Config.get_config("draw_card", "FGO_FLAG")
ONMYOJI_FLAG = Config.get_config("draw_card", "ONMYOJI_FLAG")
PCR_TAI = Config.get_config("draw_card", "PCR_TAI")
SEMAPHORE = Config.get_config("draw_card", "SEMAPHORE")
# 明日方舟
class PrtsConfig(BaseModel, extra=Extra.ignore):
PRTS_SIX_P: float = 0.02
PRTS_FIVE_P: float = 0.08
PRTS_FOUR_P: float = 0.48
PRTS_THREE_P: float = 0.42
# 方舟概率
PRTS_SIX_P = 0.02
PRTS_FIVE_P = 0.08
PRTS_FOUR_P = 0.48
PRTS_THREE_P = 0.42
# 赛马娘
class PrettyConfig(BaseModel, extra=Extra.ignore):
PRETTY_THREE_P: float = 0.03
PRETTY_TWO_P: float = 0.18
PRETTY_ONE_P: float = 0.79
# 原神概率
GENSHIN_FIVE_P = 0.006
GENSHIN_FOUR_P = 0.051
GENSHIN_THREE_P = 0.43
# 保底概率
GENSHIN_G_FIVE_P = 0.016
GENSHIN_G_FOUR_P = 0.13
# 72抽后增加的概率
I72_ADD = 0.0585
# 赛马娘概率
PRETTY_THREE_P = 0.03
PRETTY_TWO_P = 0.18
PRETTY_ONE_P = 0.79
# 坎公骑冠剑
# 角色概率
GUARDIAN_THREE_CHAR_P = 0.0275
GUARDIAN_TWO_CHAR_P = 0.19
GUARDIAN_ONE_CHAR_P = 0.7825
# UP角色
GUARDIAN_THREE_CHAR_UP_P = 0.01375
GUARDIAN_THREE_CHAR_OTHER_P = 0.01375
# 武器概率
GUARDIAN_EXCLUSIVE_ARMS_P = 0.03
GUARDIAN_FIVE_ARMS_P = 0.03
GUARDIAN_FOUR_ARMS_P = 0.09
GUARDIAN_THREE_ARMS_P = 0.27
GUARDIAN_TWO_ARMS_P = 0.58
# UP武器
GUARDIAN_EXCLUSIVE_ARMS_UP_P = 0.01
GUARDIAN_EXCLUSIVE_ARMS_OTHER_P = 0.02
class GuardianConfig(BaseModel, extra=Extra.ignore):
GUARDIAN_THREE_CHAR_P: float = 0.0275
GUARDIAN_TWO_CHAR_P: float = 0.19
GUARDIAN_ONE_CHAR_P: float = 0.7825
GUARDIAN_THREE_CHAR_UP_P: float = 0.01375
GUARDIAN_THREE_CHAR_OTHER_P: float = 0.01375
GUARDIAN_EXCLUSIVE_ARMS_P: float = 0.03
GUARDIAN_FIVE_ARMS_P: float = 0.03
GUARDIAN_FOUR_ARMS_P: float = 0.09
GUARDIAN_THREE_ARMS_P: float = 0.27
GUARDIAN_TWO_ARMS_P: float = 0.58
GUARDIAN_EXCLUSIVE_ARMS_UP_P: float = 0.01
GUARDIAN_EXCLUSIVE_ARMS_OTHER_P: float = 0.02
# 公主连结
class PcrConfig(BaseModel, extra=Extra.ignore):
PCR_THREE_P: float = 0.025
PCR_TWO_P: float = 0.18
PCR_ONE_P: float = 0.795
PCR_G_THREE_P: float = 0.025
PCR_G_TWO_P: float = 0.975
# PCR
PCR_THREE_P = 0.025
PCR_TWO_P = 0.18
PCR_ONE_P = 0.795
# 保底
PCR_G_THREE_P = 0.025
PCR_G_TWO_P = 0.975
# 碧蓝航线
AZUR_FIVE_P = 0.012
AZUR_FOUR_P = 0.07
AZUR_THREE_P = 0.12
AZUR_TWO_P = 0.51
AZUR_ONE_P = 0.3
class AzurConfig(BaseModel, extra=Extra.ignore):
AZUR_FIVE_P: float = 0.012
AZUR_FOUR_P: float = 0.07
AZUR_THREE_P: float = 0.12
AZUR_TWO_P: float = 0.51
AZUR_ONE_P: float = 0.3
# 命运-冠位指定
class FgoConfig(BaseModel, extra=Extra.ignore):
FGO_SERVANT_FIVE_P: float = 0.01
FGO_SERVANT_FOUR_P: float = 0.03
FGO_SERVANT_THREE_P: float = 0.4
FGO_CARD_FIVE_P: float = 0.04
FGO_CARD_FOUR_P: float = 0.12
FGO_CARD_THREE_P: float = 0.4
# FGO
FGO_SERVANT_FIVE_P = 0.01
FGO_SERVANT_FOUR_P = 0.03
FGO_SERVANT_THREE_P = 0.4
FGO_CARD_FIVE_P = 0.04
FGO_CARD_FOUR_P = 0.12
FGO_CARD_THREE_P = 0.4
# 阴阳师
ONMYOJI_SP = 0.0025
ONMYOJI_SSR = 0.01
ONMYOJI_SR = 0.2
ONMYOJI_R = 0.7875
class OnmyojiConfig(BaseModel, extra=Extra.ignore):
ONMYOJI_SP: float = 0.0025
ONMYOJI_SSR: float = 0.01
ONMYOJI_SR: float = 0.2
ONMYOJI_R: float = 0.7875
path_dict = {
"genshin": "原神",
"prts": "明日方舟",
"pretty": "赛马娘",
"guardian": "坎公骑冠剑",
"pcr": "公主连结",
"azur": "碧蓝航线",
"fgo": "命运-冠位指定",
"onmyoji": "阴阳师",
}
class PathDict(BaseModel, extra=Extra.ignore):
genshin: str = "原神"
prts: str = "明日方舟"
pretty: str = "赛马娘"
guardian: str = "坎公骑冠剑"
pcr: str = "公主连结"
azur: str = "碧蓝航线"
fgo: str = "命运-冠位指定"
onmyoji: str = "阴阳师"
driver: nonebot.Driver = nonebot.get_driver()
config_default_data = {
"path_dict": {
class DrawConfig(BaseModel, extra=Extra.ignore):
# 开关
PRTS_FLAG: bool = Config.get_config("draw_card", "PRTS_FLAG")
GENSHIN_FLAG: bool = Config.get_config("draw_card", "GENSHIN_FLAG")
PRETTY_FLAG: bool = Config.get_config("draw_card", "PRETTY_FLAG")
GUARDIAN_FLAG: bool = Config.get_config("draw_card", "GUARDIAN_FLAG")
PCR_FLAG: bool = Config.get_config("draw_card", "PCR_FLAG")
AZUR_FLAG: bool = Config.get_config("draw_card", "AZUR_FLAG")
FGO_FLAG: bool = Config.get_config("draw_card", "FGO_FLAG")
ONMYOJI_FLAG: bool = Config.get_config("draw_card", "ONMYOJI_FLAG")
# 其他配置
PCR_TAI: bool = Config.get_config("draw_card", "PCR_TAI")
SEMAPHORE: int = Config.get_config("draw_card", "SEMAPHORE")
# 路径
path_dict: dict = {
"genshin": "原神",
"prts": "明日方舟",
"pretty": "赛马娘",
@@ -144,268 +123,41 @@ config_default_data = {
"azur": "碧蓝航线",
"fgo": "命运-冠位指定",
"onmyoji": "阴阳师",
},
"prts": {
"PRTS_SIX_P": 0.02,
"PRTS_FIVE_P": 0.08,
"PRTS_FOUR_P": 0.48,
"PRTS_THREE_P": 0.42,
},
"genshin": {
"GENSHIN_FIVE_P": 0.006,
"GENSHIN_FOUR_P": 0.051,
"GENSHIN_THREE_P": 0.43,
"GENSHIN_G_FIVE_P": 0.13,
"GENSHIN_G_FOUR_P": 0.016,
"I72_ADD": 0.0585,
},
"pretty": {
"PRETTY_THREE_P": 0.03,
"PRETTY_TWO_P": 0.18,
"PRETTY_ONE_P": 0.79,
},
"guardian": {
"GUARDIAN_THREE_CHAR_P": 0.0275,
"GUARDIAN_TWO_CHAR_P": 0.19,
"GUARDIAN_ONE_CHAR_P": 0.7825,
"GUARDIAN_THREE_CHAR_UP_P": 0.01375,
"GUARDIAN_THREE_CHAR_OTHER_P": 0.01375,
"GUARDIAN_EXCLUSIVE_ARMS_P": 0.03,
"GUARDIAN_FIVE_ARMS_P": 0.03,
"GUARDIAN_FOUR_ARMS_P": 0.09,
"GUARDIAN_THREE_ARMS_P": 0.27,
"GUARDIAN_TWO_ARMS_P": 0.58,
"GUARDIAN_EXCLUSIVE_ARMS_UP_P": 0.01,
"GUARDIAN_EXCLUSIVE_ARMS_OTHER_P": 0.02,
},
"pcr": {
"PCR_THREE_P": 0.025,
"PCR_TWO_P": 0.18,
"PCR_ONE_P": 0.795,
},
"azur": {
"AZUR_FIVE_P": 0.012,
"AZUR_FOUR_P": 0.07,
"AZUR_THREE_P": 0.12,
"AZUR_TWO_P": 0.51,
"AZUR_ONE_P": 0.3,
},
"fgo": {
"FGO_SERVANT_FIVE_P": 0.01,
"FGO_SERVANT_FOUR_P": 0.03,
"FGO_SERVANT_THREE_P": 0.4,
"FGO_CARD_FIVE_P": 0.04,
"FGO_CARD_FOUR_P": 0.12,
"FGO_CARD_THREE_P": 0.4,
},
"onmyoji": {
"ONMYOJI_SP": 0.0025,
"ONMYOJI_SSR": 0.01,
"ONMYOJI_SR": 0.2,
"ONMYOJI_R": 0.7875,
},
}
}
# 抽卡概率
prts: PrtsConfig = PrtsConfig()
genshin: GenshinConfig = GenshinConfig()
pretty: PrettyConfig = PrettyConfig()
guardian: GuardianConfig = GuardianConfig()
pcr: PcrConfig = PcrConfig()
azur: AzurConfig = AzurConfig()
fgo: FgoConfig = FgoConfig()
onmyoji: OnmyojiConfig = OnmyojiConfig()
driver = nonebot.get_driver()
global_config = driver.config
DRAW_DATA_PATH = DATA_PATH / "draw_card"
DRAW_IMAGE_PATH = IMAGE_PATH / "draw_card"
# DRAW_PATH = Path(draw_path) if draw_path else Path("data/draw_card").absolute()
config_path = DRAW_DATA_PATH / "draw_card_config" / "draw_card_config.json"
draw_config: Config = DrawConfig()
@driver.on_startup
def check_config():
global PRTS_SIX_P, PRTS_FOUR_P, PRTS_FIVE_P, PRTS_THREE_P, GENSHIN_G_FIVE_P, config_default_data, GENSHIN_G_FOUR_P, GENSHIN_FOUR_P, GENSHIN_FIVE_P, I72_ADD, path_dict, PRETTY_THREE_P, PRETTY_ONE_P, PRETTY_TWO_P, GENSHIN_THREE_P, GUARDIAN_THREE_CHAR_P, GUARDIAN_TWO_CHAR_P, GUARDIAN_ONE_CHAR_P, GUARDIAN_THREE_CHAR_UP_P, GUARDIAN_THREE_CHAR_OTHER_P, GUARDIAN_EXCLUSIVE_ARMS_P, GUARDIAN_FIVE_ARMS_P, GUARDIAN_FOUR_ARMS_P, GUARDIAN_THREE_ARMS_P, GUARDIAN_TWO_ARMS_P, GENSHIN_FLAG, PRTS_FLAG, PRETTY_FLAG, GUARDIAN_FLAG, GUARDIAN_EXCLUSIVE_ARMS_UP_P, GUARDIAN_EXCLUSIVE_ARMS_OTHER_P, DRAW_PATH, PCR_THREE_P, PCR_TWO_P, PCR_ONE_P, AZUR_FOUR_P, AZUR_THREE_P, AZUR_TWO_P, AZUR_ONE_P, AZUR_FIVE_P, FGO_CARD_FIVE_P, FGO_CARD_FOUR_P, FGO_CARD_THREE_P, FGO_SERVANT_THREE_P, FGO_SERVANT_FOUR_P, FGO_SERVANT_FIVE_P, ONMYOJI_R, ONMYOJI_SP, ONMYOJI_SSR, ONMYOJI_SR
_draw_config.parent.mkdir(parents=True, exist_ok=True)
try:
data = json.load(open(_draw_config, "r", encoding="utf8"))
except (FileNotFoundError, ValueError):
_draw_config.parent.mkdir(parents=True, exist_ok=True)
json.dump(
config_default_data,
open(_draw_config, "w", encoding="utf8"),
indent=4,
ensure_ascii=False,
)
print("draw_card:配置文件不存在或格式错误,已重新生成配置文件.....")
else:
global draw_config
try:
PRTS_SIX_P = float(data["prts"]["PRTS_SIX_P"])
PRTS_FIVE_P = float(data["prts"]["PRTS_FIVE_P"])
PRTS_FOUR_P = float(data["prts"]["PRTS_FOUR_P"])
PRTS_THREE_P = float(data["prts"]["PRTS_THREE_P"])
except KeyError:
data["prts"] = {}
data["prts"]["PRTS_SIX_P"] = config_default_data["prts"]["PRTS_SIX_P"]
data["prts"]["PRTS_FIVE_P"] = config_default_data["prts"]["PRTS_FIVE_P"]
data["prts"]["PRTS_FOUR_P"] = config_default_data["prts"]["PRTS_FOUR_P"]
data["prts"]["PRTS_THREE_P"] = config_default_data["prts"]["PRTS_THREE_P"]
if not config_path.exists():
config_path.parent.mkdir(parents=True, exist_ok=True)
draw_config = DrawConfig()
logger.warning("draw_card:配置文件不存在,已重新生成配置文件.....")
try:
GENSHIN_FIVE_P = float(data["genshin"]["GENSHIN_FIVE_P"])
GENSHIN_FOUR_P = float(data["genshin"]["GENSHIN_FOUR_P"])
GENSHIN_THREE_P = float(data["genshin"]["GENSHIN_THREE_P"])
GENSHIN_G_FIVE_P = float(data["genshin"]["GENSHIN_G_FIVE_P"])
GENSHIN_G_FOUR_P = float(data["genshin"]["GENSHIN_G_FOUR_P"])
I72_ADD = float(data["genshin"]["I72_ADD"])
except KeyError:
data["genshin"] = {}
data["genshin"]["GENSHIN_FIVE_P"] = config_default_data["genshin"][
"GENSHIN_FIVE_P"
]
data["genshin"]["GENSHIN_FOUR_P"] = config_default_data["genshin"][
"GENSHIN_FOUR_P"
]
data["genshin"]["GENSHIN_THREE_P"] = config_default_data["genshin"][
"GENSHIN_THREE_P"
]
data["genshin"]["GENSHIN_G_FIVE_P"] = config_default_data["genshin"][
"GENSHIN_G_FIVE_P"
]
data["genshin"]["GENSHIN_G_FOUR_P"] = config_default_data["genshin"][
"GENSHIN_G_FOUR_P"
]
data["genshin"]["I72_ADD"] = config_default_data["genshin"]["I72_ADD"]
try:
PRETTY_THREE_P = float(data["pretty"]["PRETTY_THREE_P"])
PRETTY_TWO_P = float(data["pretty"]["PRETTY_TWO_P"])
PRETTY_ONE_P = float(data["pretty"]["PRETTY_ONE_P"])
except KeyError:
data["pretty"] = {}
data["pretty"]["PRETTY_THREE_P"] = config_default_data["pretty"][
"PRETTY_THREE_P"
]
data["pretty"]["PRETTY_TWO_P"] = config_default_data["pretty"][
"PRETTY_TWO_P"
]
data["pretty"]["PRETTY_ONE_P"] = config_default_data["pretty"][
"PRETTY_ONE_P"
]
try:
GUARDIAN_THREE_CHAR_P = float(data["guardian"]["GUARDIAN_THREE_CHAR_P"])
GUARDIAN_TWO_CHAR_P = float(data["guardian"]["GUARDIAN_TWO_CHAR_P"])
GUARDIAN_ONE_CHAR_P = float(data["guardian"]["GUARDIAN_ONE_CHAR_P"])
GUARDIAN_THREE_CHAR_UP_P = float(
data["guardian"]["GUARDIAN_THREE_CHAR_UP_P"]
)
GUARDIAN_THREE_CHAR_OTHER_P = float(
data["guardian"]["GUARDIAN_THREE_CHAR_OTHER_P"]
)
GUARDIAN_EXCLUSIVE_ARMS_P = float(
data["guardian"]["GUARDIAN_EXCLUSIVE_ARMS_P"]
)
GUARDIAN_FIVE_ARMS_P = float(data["guardian"]["GUARDIAN_FIVE_ARMS_P"])
GUARDIAN_FOUR_ARMS_P = float(data["guardian"]["GUARDIAN_FOUR_ARMS_P"])
GUARDIAN_THREE_ARMS_P = float(data["guardian"]["GUARDIAN_THREE_ARMS_P"])
GUARDIAN_TWO_ARMS_P = float(data["guardian"]["GUARDIAN_TWO_ARMS_P"])
GUARDIAN_EXCLUSIVE_ARMS_UP_P = float(
data["guardian"]["GUARDIAN_EXCLUSIVE_ARMS_UP_P"]
)
GUARDIAN_EXCLUSIVE_ARMS_OTHER_P = float(
data["guardian"]["GUARDIAN_EXCLUSIVE_ARMS_OTHER_P"]
)
except KeyError:
data["guardian"] = {}
data["guardian"]["GUARDIAN_THREE_CHAR_P"] = config_default_data["guardian"][
"GUARDIAN_THREE_CHAR_P"
]
data["guardian"]["GUARDIAN_TWO_CHAR_P"] = config_default_data["guardian"][
"GUARDIAN_TWO_CHAR_P"
]
data["guardian"]["GUARDIAN_ONE_CHAR_P"] = config_default_data["guardian"][
"GUARDIAN_ONE_CHAR_P"
]
data["guardian"]["GUARDIAN_THREE_CHAR_UP_P"] = config_default_data[
"guardian"
]["GUARDIAN_THREE_CHAR_UP_P"]
data["guardian"]["GUARDIAN_THREE_CHAR_OTHER_P"] = config_default_data[
"guardian"
]["GUARDIAN_THREE_CHAR_OTHER_P"]
data["guardian"]["GUARDIAN_EXCLUSIVE_ARMS_P"] = config_default_data[
"guardian"
]["GUARDIAN_EXCLUSIVE_ARMS_P"]
data["guardian"]["GUARDIAN_FIVE_ARMS_P"] = config_default_data["guardian"][
"GUARDIAN_FIVE_ARMS_P"
]
data["guardian"]["GUARDIAN_FOUR_ARMS_P"] = config_default_data["guardian"][
"GUARDIAN_FOUR_ARMS_P"
]
data["guardian"]["GUARDIAN_THREE_ARMS_P"] = config_default_data["guardian"][
"GUARDIAN_THREE_ARMS_P"
]
data["guardian"]["GUARDIAN_TWO_ARMS_P"] = config_default_data["guardian"][
"GUARDIAN_TWO_ARMS_P"
]
data["guardian"]["GUARDIAN_EXCLUSIVE_ARMS_UP_P"] = config_default_data[
"guardian"
]["GUARDIAN_EXCLUSIVE_ARMS_UP_P"]
data["guardian"]["GUARDIAN_EXCLUSIVE_ARMS_OTHER_P"] = config_default_data[
"guardian"
]["GUARDIAN_EXCLUSIVE_ARMS_OTHER_P"]
try:
PCR_THREE_P = float(data["pcr"]["PCR_THREE_P"])
PCR_TWO_P = float(data["pcr"]["PCR_TWO_P"])
PCR_ONE_P = float(data["pcr"]["PCR_ONE_P"])
except KeyError:
data["pcr"] = {}
data["pcr"]["PCR_THREE_P"] = config_default_data["pcr"]["PCR_THREE_P"]
data["pcr"]["PCR_TWO_P"] = config_default_data["pcr"]["PCR_TWO_P"]
data["pcr"]["PCR_ONE_P"] = config_default_data["pcr"]["PCR_ONE_P"]
try:
AZUR_FIVE_P = float(data["azur"]["AZUR_FIVE_P"])
AZUR_FOUR_P = float(data["azur"]["AZUR_FOUR_P"])
AZUR_THREE_P = float(data["azur"]["AZUR_THREE_P"])
AZUR_TWO_P = float(data["azur"]["AZUR_TWO_P"])
AZUR_ONE_P = float(data["azur"]["AZUR_ONE_P"])
except KeyError:
data["azur"] = {}
data["azur"]["AZUR_FIVE_P"] = config_default_data["azur"]["AZUR_FIVE_P"]
data["azur"]["AZUR_FOUR_P"] = config_default_data["azur"]["AZUR_FOUR_P"]
data["azur"]["AZUR_THREE_P"] = config_default_data["azur"]["AZUR_THREE_P"]
data["azur"]["AZUR_TWO_P"] = config_default_data["azur"]["AZUR_TWO_P"]
data["azur"]["AZUR_ONE_P"] = config_default_data["azur"]["AZUR_ONE_P"]
try:
FGO_SERVANT_FIVE_P = float(data["fgo"]["FGO_SERVANT_FIVE_P"])
FGO_SERVANT_FOUR_P = float(data["fgo"]["FGO_SERVANT_FOUR_P"])
FGO_SERVANT_THREE_P = float(data["fgo"]["FGO_SERVANT_THREE_P"])
FGO_CARD_FIVE_P = float(data["fgo"]["FGO_CARD_FIVE_P"])
FGO_CARD_FOUR_P = float(data["fgo"]["FGO_CARD_FOUR_P"])
FGO_CARD_THREE_P = float(data["fgo"]["FGO_CARD_THREE_P"])
except KeyError:
data["fgo"] = {}
data["fgo"]["FGO_SERVANT_FIVE_P"] = config_default_data["fgo"][
"FGO_SERVANT_FIVE_P"
]
data["fgo"]["FGO_SERVANT_FOUR_P"] = config_default_data["fgo"][
"FGO_SERVANT_FOUR_P"
]
data["fgo"]["FGO_SERVANT_THREE_P"] = config_default_data["fgo"][
"FGO_SERVANT_THREE_P"
]
data["fgo"]["FGO_CARD_FIVE_P"] = config_default_data["fgo"][
"FGO_CARD_FIVE_P"
]
data["fgo"]["FGO_CARD_FOUR_P"] = config_default_data["fgo"][
"FGO_CARD_FOUR_P"
]
data["fgo"]["FGO_CARD_THREE_P"] = config_default_data["fgo"][
"FGO_CARD_THREE_P"
]
try:
ONMYOJI_SP = float(data["onmyoji"]["ONMYOJI_SP"])
ONMYOJI_SSR = float(data["onmyoji"]["ONMYOJI_SSR"])
ONMYOJI_SR = float(data["onmyoji"]["ONMYOJI_SR"])
ONMYOJI_R = float(data["onmyoji"]["ONMYOJI_R"])
except KeyError:
data["onmyoji"] = {}
data["onmyoji"]["ONMYOJI_SP"] = config_default_data["onmyoji"]["ONMYOJI_SP"]
data["onmyoji"]["ONMYOJI_SSR"] = config_default_data["onmyoji"][
"ONMYOJI_SSR"
]
data["onmyoji"]["ONMYOJI_SR"] = config_default_data["onmyoji"]["ONMYOJI_SR"]
data["onmyoji"]["ONMYOJI_R"] = config_default_data["onmyoji"]["ONMYOJI_R"]
json.dump(
data, open(_draw_config, "w", encoding="utf8"), indent=4, ensure_ascii=False
)
json.dump(
draw_config.dict(),
config_path.open("w", encoding="utf8"),
indent=4,
ensure_ascii=False,
)
+113
View File
@@ -0,0 +1,113 @@
from typing import Optional, Union
class DrawCountManager:
"""
抽卡统计保底
"""
def __init__(self, game_draw_count_rule: tuple, star2name: tuple):
"""
初始化保底统计
例如:DrawCountManager((10, 90, 180), ("4", "5", "5"))
抽卡保底需要的次数和返回的对应名称,例如星级等
"""
# 只有保底
self._data = {}
self._guarantee_tuple = game_draw_count_rule
self._star2name = star2name
def increase(self, key: int, value: int = 1):
"""
用户抽卡次数加1
"""
if self._data.get(key) is None:
self._data[key] = {
"count": value,
}
for x in range(len(self._guarantee_tuple)):
self._data[key][f"count_{x}"] = 0
else:
self._data[key][f"count"] += value
if self._data[key][f"count"] > self._guarantee_tuple[-1]:
self._data[key][f"count"] = self._data[key][f"count"] % self._guarantee_tuple[-1]
def reset(self, key: int):
"""
清空记录
"""
del self._data[key]
def set_count(self, key: int, type_: int, count: int):
if self._data.get(key):
self._data[key][f"count_{type_}"] = count
def check(self, key: int, *args) -> Optional[Union[str, int]]:
"""
是否保底
"""
pass
def get_user_count(self, key: int, type_: Optional[int] = None) -> int:
"""
获取用户当前抽卡次数
"""
if self._data.get(key):
if type_ is None:
return self._data[key]["count"]
return self._data[key][f"count_{type_}"]
return 0
def record_count(self, key: int, type_: int):
"""
抽出对应星级后记录当前次数
"""
if self._data.get(key):
self._data[key][f"count_{type_}"] = self._data[key]["count"]
class GenshinCountManager(DrawCountManager):
def increase(self, key: int, value: int = 1):
"""
用户抽卡次数加1
"""
if self._data.get(key) is None:
self._data[key] = {
"is_up": False,
"count": value,
}
for x in range(len(self._guarantee_tuple)):
self._data[key][f"count_{x}"] = 0
else:
self._data[key][f"count"] += value
if self._data[key][f"count"] > self._guarantee_tuple[-1]:
self._data[key][f"count"] = self._data[key][f"count"] % 180
def set_is_up(self, key: int, value: bool):
if self._data.get(key):
self._data[key]["is_up"] = value
def is_up(self, key: int) -> bool:
if self._data.get(key):
return self._data[key]["is_up"]
return False
def check(self, key: int, *args) -> Optional[Union[str, int]]:
"""
是否保底
"""
# print(self._data)
if self._data.get(key):
for i in [1, 0]:
count = self._data[key]["count"]
if count - self._data[key][f"count_{i}"] == self._guarantee_tuple[i]:
if i in [2, 1]:
# print("clean four count")
self._data[key][f"count_0"] = self._data[key]['count']
self._data[key][f"count_{i}"] = self._data[key]['count']
return self._star2name[i]
return None
+18 -19
View File
@@ -1,10 +1,8 @@
from nonebot.adapters.cqhttp import MessageSegment
from nonebot.adapters.onebot.v11 import MessageSegment
import random
from .update_game_requests_info import update_requests_info
from .util import generate_img, init_star_rst, BaseData, set_list, get_star, max_card
from .config import FGO_CARD_FOUR_P, FGO_CARD_FIVE_P, FGO_CARD_THREE_P, FGO_SERVANT_THREE_P, \
FGO_SERVANT_FIVE_P, FGO_SERVANT_FOUR_P, FGO_FLAG, DRAW_PATH
from .config import DRAW_DATA_PATH, draw_config
from dataclasses import dataclass
from .init_card_pool import init_game_pool
@@ -45,11 +43,11 @@ async def update_fgo_info():
async def init_fgo_data():
global ALL_CHAR, ALL_CARD
if FGO_FLAG:
with open(DRAW_PATH + 'fgo.json', 'r', encoding='utf8') as f:
if draw_config.FGO_FLAG:
with (DRAW_DATA_PATH / 'fgo.json').open('r', encoding='utf8') as f:
fgo_dict = json.load(f)
ALL_CHAR = init_game_pool('fgo', fgo_dict, FgoChar)
with open(DRAW_PATH + 'fgo_card.json', 'r', encoding='utf8') as f:
with (DRAW_DATA_PATH / 'fgo_card.json').open('r', encoding='utf8') as f:
fgo_dict = json.load(f)
ALL_CARD = init_game_pool('fgo', fgo_dict, FgoChar)
@@ -57,21 +55,22 @@ async def init_fgo_data():
# 抽取卡池
def _get_fgo_card(mode: int = 1):
global ALL_CHAR, ALL_CARD
fgo_config = draw_config.fgo
if mode == 1:
star = get_star([8, 7, 6, 5, 4, 3], [FGO_SERVANT_FIVE_P, FGO_SERVANT_FOUR_P, FGO_SERVANT_THREE_P,
FGO_CARD_FIVE_P, FGO_CARD_FOUR_P, FGO_CARD_THREE_P])
star = get_star([8, 7, 6, 5, 4, 3], [fgo_config.FGO_SERVANT_FIVE_P, fgo_config.FGO_SERVANT_FOUR_P, fgo_config.FGO_SERVANT_THREE_P,
fgo_config.FGO_CARD_FIVE_P, fgo_config.FGO_CARD_FOUR_P, fgo_config.FGO_CARD_THREE_P])
elif mode == 2:
star = get_star([5, 4], [FGO_CARD_FIVE_P, FGO_CARD_FOUR_P])
star = get_star([5, 4], [fgo_config.FGO_CARD_FIVE_P, fgo_config.FGO_CARD_FOUR_P])
else:
star = get_star([8, 7, 6], [FGO_SERVANT_FIVE_P, FGO_SERVANT_FOUR_P, FGO_SERVANT_THREE_P])
star = get_star([8, 7, 6], [fgo_config.FGO_SERVANT_FIVE_P, fgo_config.FGO_SERVANT_FOUR_P, fgo_config.FGO_SERVANT_THREE_P])
if star > 5:
itype = 'servant'
type_ = 'servant'
star -= 3
chars = [x for x in ALL_CHAR if x.star == star if not x.limited]
else:
itype = 'card'
type_ = 'card'
chars = [x for x in ALL_CARD if x.star == star if not x.limited]
return random.choice(chars), 5 - star, itype
return random.choice(chars), 5 - star, type_
# 整理数据
@@ -88,18 +87,18 @@ def _format_card_information(count: int):
card_count += 1
# 四星卡片保底
if card_count == 9:
obj, code, itype = _get_fgo_card(2)
obj, code, type_ = _get_fgo_card(2)
# 三星从者保底
elif servant_count == 10:
obj, code, itype = _get_fgo_card(3)
obj, code, type_ = _get_fgo_card(3)
_count = 0
# 普通抽
else:
obj, code, itype = _get_fgo_card()
obj, code, type_ = _get_fgo_card()
star_list[code] += 1
if itype == 'card' and code < 2:
if type_ == 'card' and code < 2:
card_count = 0
if itype == 'servant':
if type_ == 'servant':
servant_count = 0
if code == 0:
max_star_lst.append(obj.name)
+116 -92
View File
@@ -1,25 +1,16 @@
import os
from nonebot.adapters.cqhttp import MessageSegment, Message
from nonebot.adapters.onebot.v11 import MessageSegment, Message
import random
from .update_game_info import update_info
from .util import (
generate_img,
init_star_rst,
init_rst,
BaseData,
set_list,
get_star,
init_up_char,
)
from .config import (
GENSHIN_FIVE_P,
GENSHIN_FOUR_P,
GENSHIN_G_FIVE_P,
GENSHIN_G_FOUR_P,
GENSHIN_THREE_P,
I72_ADD,
DRAW_PATH,
GENSHIN_FLAG,
)
from .config import DRAW_DATA_PATH, draw_config
from .count_manager import GenshinCountManager
from dataclasses import dataclass
from .init_card_pool import init_game_pool
from .announcement import GenshinAnnouncement
@@ -32,9 +23,11 @@ except ModuleNotFoundError:
announcement = GenshinAnnouncement()
genshin_five = {}
genshin_count = {}
genshin_pl_count = {}
draw_count_manager = GenshinCountManager((10, 90), ("4", "5"))
# genshin_five = {}
# genshin_count = {}
# genshin_pl_count = {}
ALL_CHAR = []
ALL_ARMS = []
@@ -42,6 +35,7 @@ ALL_ARMS = []
UP_CHAR = []
UP_ARMS = []
_CURRENT_CHAR_POOL_TITLE = ""
_CURRENT_ARMS_POOL_TITLE = ""
POOL_IMG = ""
@@ -54,15 +48,12 @@ class GenshinChar(BaseData):
async def genshin_draw(user_id: int, count: int, pool_name: str):
# 0 1 2
cnlist = ["★★★★★", "★★★★", "★★★"]
star = ["★★★★★", "★★★★", "★★★"]
(
char_list,
five_list,
five_index_list,
char_dict,
star_list,
five_dict,
star_num_list,
) = _format_card_information(count, user_id, pool_name)
temp = ""
title = ""
up_type = []
up_list = []
@@ -81,7 +72,7 @@ async def genshin_draw(user_id: int, count: int, pool_name: str):
tmp += f'五星UP:{" ".join(x.operators)} \n'
elif x.star == 4:
tmp += f'四星UP:{" ".join(x.operators)}'
rst = init_star_rst(star_list, cnlist, five_list, five_index_list, up_list)
rst = init_rst(five_dict, star_num_list, star, up_list)
pool_info = f"当前up池:{title}\n{tmp}" if title else ""
if count > 90:
char_list = set_list(char_list)
@@ -89,12 +80,10 @@ async def genshin_draw(user_id: int, count: int, pool_name: str):
pool_info
+ "\n"
+ MessageSegment.image(
"base64://" + await generate_img(char_list, "genshin", star_list)
"base64://" + await generate_img(char_list, "genshin", star_num_list)
)
+ "\n"
+ rst[:-1]
+ temp[:-1]
+ f'\n距离保底发还剩 {90 - genshin_count[user_id] if genshin_count.get(user_id) else "^"} 抽'
+ rst
+ f'\n距离保底发还剩 {draw_count_manager.get_user_count(user_id, 1) % 90} 抽'
+ "\n【五星:0.6%,四星:5.1%\n第72抽开始五星概率每抽加0.585%】"
)
@@ -117,15 +106,13 @@ async def update_genshin_info():
async def init_genshin_data():
global ALL_CHAR, ALL_ARMS
if GENSHIN_FLAG:
if not os.path.exists(DRAW_PATH + "genshin.json") or not os.path.exists(
DRAW_PATH + "genshin_arms.json"
):
if draw_config.GENSHIN_FLAG:
if not (DRAW_DATA_PATH / "genshin.json").exists() or not (DRAW_DATA_PATH / "genshin_arms.json").exists():
await update_genshin_info()
else:
with open(DRAW_PATH + "genshin.json", "r", encoding="utf8") as f:
with (DRAW_DATA_PATH / "genshin.json").open("r", encoding="utf8") as f:
genshin_dict = json.load(f)
with open(DRAW_PATH + "genshin_arms.json", "r", encoding="utf8") as f:
with (DRAW_DATA_PATH / "genshin_arms.json").open("r", encoding="utf8") as f:
genshin_ARMS_dict = json.load(f)
ALL_CHAR = init_game_pool("genshin", genshin_dict, GenshinChar)
ALL_ARMS = init_game_pool("genshin_arms", genshin_ARMS_dict, GenshinChar)
@@ -133,47 +120,52 @@ async def init_genshin_data():
# 抽取卡池
def _get_genshin_card(mode: int = 1, pool_name: str = "", add: float = 0.0):
def _get_genshin_card(mode: int = 1, pool_name: str = "", add: float = 0.0, is_up: bool = False):
"""
mode 1:普通抽 2:四星保底 3:五星保底
"""
global ALL_ARMS, ALL_CHAR, UP_ARMS, UP_CHAR, _CURRENT_ARMS_POOL_TITLE, _CURRENT_CHAR_POOL_TITLE
genshin_config = draw_config.genshin
if mode == 1:
star = get_star(
[5, 4, 3], [GENSHIN_FIVE_P + add, GENSHIN_FOUR_P, GENSHIN_THREE_P]
[5, 4, 3], [genshin_config.GENSHIN_FIVE_P + add, genshin_config.GENSHIN_FOUR_P, genshin_config.GENSHIN_THREE_P]
)
elif mode == 2:
star = get_star([5, 4], [GENSHIN_G_FIVE_P + add, GENSHIN_G_FOUR_P])
star = get_star([5, 4], [genshin_config.GENSHIN_G_FIVE_P + add, genshin_config.GENSHIN_G_FOUR_P])
else:
star = 5
if pool_name == "char":
data_lst = UP_CHAR
flag = _CURRENT_CHAR_POOL_TITLE
itype_all_lst = ALL_CHAR + [
type_all_lst = ALL_CHAR + [
x for x in ALL_ARMS if x.star == star and x.star < 5
]
elif pool_name == "arms":
data_lst = UP_ARMS
flag = _CURRENT_ARMS_POOL_TITLE
itype_all_lst = ALL_ARMS + [
type_all_lst = ALL_ARMS + [
x for x in ALL_CHAR if x.star == star and x.star < 5
]
else:
data_lst = ""
flag = ""
itype_all_lst = ""
type_all_lst = ""
all_lst = ALL_ARMS + ALL_CHAR
# 是否UP
try:
if flag and star > 3 and pool_name:
if flag and star > 3:
# 获取up角色列表
up_char_lst = [x.operators for x in data_lst if x.star == star][0]
# print(up_char_lst)
# 成功获取up角色
if random.random() < 0.5:
if random.random() < 0.5 or is_up:
up_char_name = random.choice(up_char_lst)
acquire_char = [x for x in all_lst if x.name == up_char_name][0]
else:
# 无up
all_char_lst = [
x
for x in itype_all_lst
for x in type_all_lst
if x.star == star and x.name not in up_char_lst and not x.limited
]
acquire_char = random.choice(all_char_lst)
@@ -187,62 +179,94 @@ def _get_genshin_card(mode: int = 1, pool_name: str = "", add: float = 0.0):
def _format_card_information(_count: int, user_id, pool_name):
char_list = []
star_list = [0, 0, 0]
five_index_list = []
five_list = []
five_dict = {}
_start_add_count = 72 if pool_name == "char" else 62
_x = 90 if pool_name == "char" else 80 # 保底
char_list = [] # 获取角色列表
star_num_list = [0, 0, 0] # 各个星级数量
five_dict = {} # 五星数量
add = 0.0
if genshin_count.get(user_id) and _count <= _x:
f_count = genshin_count[user_id]
else:
f_count = 0
if genshin_pl_count.get(user_id) and _count <= _x:
count = genshin_pl_count[user_id]
else:
count = 0
for i in range(_count):
count += 1
f_count += 1
# 十连保底
if count == 10 and f_count != _x:
if f_count >= _start_add_count:
add += I72_ADD
char, code = _get_genshin_card(2, pool_name, add=add)
count = 0
# 大保底
elif f_count == _x:
char, code = _get_genshin_card(3, pool_name)
pool = UP_CHAR if pool_name == 'char' else UP_ARMS
for _ in range(_count):
draw_count_manager.increase(user_id)
star = draw_count_manager.check(user_id)
if (draw_count_manager.get_user_count(user_id) - draw_count_manager.get_user_count(user_id, 1)) % 90 >= 72:
add += draw_config.genshin.I72_ADD
if star:
star = int(star)
if star == 4:
char, code = _get_genshin_card(2, pool_name, add=add)
draw_count_manager.record_count(user_id, 0)
else:
char, code = _get_genshin_card(3, pool_name, add, draw_count_manager.is_up(user_id))
else:
if f_count >= _start_add_count:
add += I72_ADD
char, code = _get_genshin_card(pool_name=pool_name, add=add)
if code == 1:
count = 0
star_list[code] += 1
char, code = _get_genshin_card(1, pool_name, add, draw_count_manager.is_up(user_id))
if code == 0:
if _count <= _x:
genshin_five[user_id] = f_count
add = 0.0
f_count = 0
five_list.append(char.name)
five_index_list.append(i)
try:
five_dict[char.name] += 1
except KeyError:
five_dict[char.name] = 1
add = 0
if not five_dict.get(char.name):
five_dict[char.name] = [draw_count_manager.get_user_count(user_id)]
else:
five_dict[char.name].append(draw_count_manager.get_user_count(user_id) % 90)
draw_count_manager.set_count(user_id, 2, draw_count_manager.get_user_count(user_id, 1))
draw_count_manager.record_count(user_id, 0)
draw_count_manager.record_count(user_id, 1)
if char.name not in [x.operators for x in pool if x.star == 5][0]:
draw_count_manager.set_is_up(user_id, True)
else:
draw_count_manager.set_is_up(user_id, False)
star_num_list[code] += 1
char_list.append(char)
if _count <= _x:
genshin_count[user_id] = f_count
genshin_pl_count[user_id] = count
return char_list, five_list, five_index_list, five_dict, star_list
return char_list, five_dict, star_num_list
# if genshin_count.get(user_id) and _count <= 90:
# f_count = genshin_count[user_id]
# else:
# f_count = 0
# if genshin_pl_count.get(user_id) and _count <= 90:
# count = genshin_pl_count[user_id]
# else:
# count = 0
# for i in range(_count):
# count += 1
# f_count += 1
# # 十连保底
# if count == 10 and f_count != 90:
# if f_count >= 72:
# add += I72_ADD
# char, code = _get_genshin_card(2, pool_name, add=add)
# count = 0
# # 大保底
# elif f_count == 90:
# char, code = _get_genshin_card(3, pool_name)
# else:
# if f_count >= 72:
# add += I72_ADD
# char, code = _get_genshin_card(pool_name=pool_name, add=add)
# if code == 1:
# count = 0
# star_list[code] += 1
# if code == 0:
# if _count <= 90:
# genshin_five[user_id] = f_count
# add = 0.0
# f_count = 0
# five_list.append(char.name)
# five_index_list.append(i)
# try:
# five_dict[char.name] += 1
# except KeyError:
# five_dict[char.name] = 1
# char_list.append(char)
# if _count <= 90:
# genshin_count[user_id] = f_count
# genshin_pl_count[user_id] = count
# return char_list, five_list, five_index_list, five_dict, star_list
def reset_count(user_id: int):
genshin_count[user_id] = 0
genshin_pl_count[user_id] = 0
draw_count_manager.reset(user_id)
# 获取up和概率
+16 -17
View File
@@ -1,17 +1,12 @@
import os
from nonebot.adapters.cqhttp import MessageSegment, Message
from nonebot.adapters.onebot.v11 import MessageSegment, Message
from .update_game_info import update_info
from .announcement import GuardianAnnouncement
from .util import init_star_rst, generate_img, max_card, BaseData,\
set_list, get_star, format_card_information, init_up_char
import random
from .config import DRAW_PATH, GUARDIAN_ONE_CHAR_P, GUARDIAN_TWO_CHAR_P, GUARDIAN_THREE_CHAR_P, \
GUARDIAN_THREE_CHAR_UP_P, GUARDIAN_TWO_ARMS_P, GUARDIAN_FIVE_ARMS_P, GUARDIAN_THREE_CHAR_OTHER_P, \
GUARDIAN_FOUR_ARMS_P, GUARDIAN_THREE_ARMS_P, GUARDIAN_EXCLUSIVE_ARMS_P, GUARDIAN_EXCLUSIVE_ARMS_UP_P, \
GUARDIAN_EXCLUSIVE_ARMS_OTHER_P, GUARDIAN_FLAG
from .config import DRAW_DATA_PATH, draw_config
from dataclasses import dataclass
from .init_card_pool import init_game_pool
from .announcement import GuardianAnnouncement
try:
import ujson as json
except ModuleNotFoundError:
@@ -96,13 +91,13 @@ async def update_guardian_info():
async def init_guardian_data():
global ALL_CHAR, ALL_ARMS
if GUARDIAN_FLAG:
if not os.path.exists(DRAW_PATH + 'guardian.json') or not os.path.exists(DRAW_PATH + 'guardian_arms.json'):
if draw_config.GUARDIAN_FLAG:
if not (DRAW_DATA_PATH / 'guardian.json').exists() or not (DRAW_DATA_PATH / 'guardian_arms.json').exists():
await update_guardian_info()
else:
with open(DRAW_PATH + 'guardian.json', 'r', encoding='utf8') as f:
with (DRAW_DATA_PATH / 'guardian.json').open('r', encoding='utf8') as f:
guardian_char_dict = json.load(f)
with open(DRAW_PATH + 'guardian_arms.json', 'r', encoding='utf8') as f:
with (DRAW_DATA_PATH / 'guardian_arms.json').open('r', encoding='utf8') as f:
guardian_arms_dict = json.load(f)
ALL_CHAR = init_game_pool('guardian', guardian_char_dict, GuardianChar)
ALL_ARMS = init_game_pool('guardian_arms', guardian_arms_dict, GuardianArms)
@@ -112,21 +107,22 @@ async def init_guardian_data():
# 抽取卡池
def _get_guardian_card(pool_name: str = '', mode: int = 1):
global ALL_ARMS, ALL_CHAR, UP_ARMS, UP_CHAR, _CURRENT_ARMS_POOL_TITLE, _CURRENT_CHAR_POOL_TITLE
guardian_config = draw_config.guardian
if pool_name == 'char':
if mode == 1:
star = get_star([3, 2, 1], [GUARDIAN_THREE_CHAR_P, GUARDIAN_TWO_CHAR_P, GUARDIAN_ONE_CHAR_P])
star = get_star([3, 2, 1], [guardian_config.GUARDIAN_THREE_CHAR_P, guardian_config.GUARDIAN_TWO_CHAR_P, guardian_config.GUARDIAN_ONE_CHAR_P])
else:
star = get_star([3, 2], [GUARDIAN_THREE_CHAR_P, GUARDIAN_TWO_CHAR_P])
star = get_star([3, 2], [guardian_config.GUARDIAN_THREE_CHAR_P, guardian_config.GUARDIAN_TWO_CHAR_P])
up_lst = UP_CHAR
flag = _CURRENT_CHAR_POOL_TITLE
_max_star = 3
all_data = ALL_CHAR
else:
if mode == 1:
star = get_star([5, 4, 3, 2], [GUARDIAN_FIVE_ARMS_P, GUARDIAN_FOUR_ARMS_P,
GUARDIAN_THREE_ARMS_P, GUARDIAN_TWO_ARMS_P])
star = get_star([5, 4, 3, 2], [guardian_config.GUARDIAN_FIVE_ARMS_P, guardian_config.GUARDIAN_FOUR_ARMS_P,
guardian_config.GUARDIAN_THREE_ARMS_P, guardian_config.GUARDIAN_TWO_ARMS_P])
else:
star = get_star([5, 4], [GUARDIAN_FIVE_ARMS_P, GUARDIAN_FOUR_ARMS_P])
star = get_star([5, 4], [guardian_config.GUARDIAN_FIVE_ARMS_P, guardian_config.GUARDIAN_FOUR_ARMS_P])
up_lst = UP_ARMS
flag = _CURRENT_ARMS_POOL_TITLE
_max_star = 5
@@ -158,3 +154,6 @@ async def _guardian_init_up_char():
async def reload_guardian_pool():
await _guardian_init_up_char()
return Message(f'当前UP池子:{_CURRENT_CHAR_POOL_TITLE} & {_CURRENT_ARMS_POOL_TITLE}')
+123 -56
View File
@@ -1,137 +1,204 @@
from typing import Any
from .config import DATA_PATH
from utils.utils import is_number
from pathlib import Path
from services.log import logger
from .config import DRAW_DATA_PATH
from .util import is_number
from nonebot.log import logger
try:
import ujson as json
except ModuleNotFoundError:
import json
def init_game_pool(game: str, data: dict, Operator: Any):
def init_game_pool(game: str, data: dict, operator: Any):
tmp_lst = []
if game == 'prts':
if game == "prts":
for key in data.keys():
limited = False
recruit_only = False
event_only = False
if '限定寻访' in data[key]['获取途径']:
if "限定寻访" in data[key]["获取途径"]:
limited = True
if '干员寻访' not in data[key]['获取途径'] and '公开招募' in data[key]['获取途径']:
if "干员寻访" not in data[key]["获取途径"] and "公开招募" in data[key]["获取途径"]:
recruit_only = True
if '活动获取' in data[key]['获取途径']:
if "活动获取" in data[key]["获取途径"]:
event_only = True
if '干员寻访' not in data[key]['获取途径'] and '凭证交易所' == data[key]['获取途径'][0]:
if "干员寻访" not in data[key]["获取途径"] and "凭证交易所" == data[key]["获取途径"][0]:
limited = True
if '干员寻访' not in data[key]['获取途径'] and '信用累计奖励' == data[key]['获取途径'][0]:
if "干员寻访" not in data[key]["获取途径"] and "信用累计奖励" == data[key]["获取途径"][0]:
limited = True
if key.find('阿米娅') != -1:
if key.find("阿米娅") != -1:
continue
try:
tmp_lst.append(Operator(name=key, star=int(data[key]['星级']),
limited=limited, recruit_only=recruit_only, event_only=event_only))
tmp_lst.append(
operator(
name=key,
star=int(data[key]["星级"]),
limited=limited,
recruit_only=recruit_only,
event_only=event_only,
)
)
except Exception as e:
logger.warning(f"明日方舟导入角色 {key} 数据错误:{type(e)}:{e}")
if game == 'genshin':
if game == "genshin":
for key in data.keys():
if key.find('旅行者') != -1:
if key.find("旅行者") != -1:
continue
limited = False
if data[key]['常驻/限定'] == '限定UP':
if data[key]["常驻/限定"] == "限定UP":
limited = True
try:
tmp_lst.append(Operator(name=key, star=int(data[key]['稀有度'][:1]), limited=limited))
tmp_lst.append(
operator(name=key, star=int(data[key]["稀有度"][:1]), limited=limited)
)
except Exception as e:
logger.warning(f"原神导入角色 {key} 数据错误:{type(e)}:{e}")
if game == 'genshin_arms':
if game == "genshin_arms":
for key in data.keys():
if data[key]['获取途径'].find('祈愿') != -1:
if data[key]["获取途径"].find("祈愿") != -1:
limited = False
if data[key]['获取途径'].find('限定祈愿') != -1:
if data[key]["获取途径"].find("限定祈愿") != -1:
limited = True
try:
tmp_lst.append(Operator(name=key, star=int(data[key]['稀有度'][:1]), limited=limited))
tmp_lst.append(
operator(
name=key, star=int(data[key]["稀有度"][:1]), limited=limited
)
)
except Exception as e:
logger.warning(f"原神导入武器 {key} 数据错误:{type(e)}:{e}")
if game == 'pretty':
if game == "pretty":
for key in data.keys():
try:
tmp_lst.append(Operator(name=key, star=data[key]['初始星级'], limited=False))
tmp_lst.append(
operator(name=key, star=data[key]["初始星级"], limited=False)
)
except Exception as e:
logger.warning(f"赛马娘导入角色 {key} 数据错误:{type(e)}:{e}")
if game == 'pretty_card':
if game == "pretty_card":
for key in data.keys():
limited = False
if '卡池' not in data[key]['获取方式']:
if "卡池" not in data[key]["获取方式"]:
limited = True
if not data[key]['获取方式']:
if not data[key]["获取方式"]:
limited = False
try:
tmp_lst.append(Operator(name=data[key]['中文名'], star=len(data[key]['稀有度']), limited=limited))
tmp_lst.append(
operator(
name=data[key]["中文名"],
star=len(data[key]["稀有度"]),
limited=limited,
)
)
except Exception as e:
logger.warning(f"赛马娘导入卡片 {key} 数据错误:{type(e)}:{e}")
if game in ['guardian', 'guardian_arms']:
if game in ["guardian", "guardian_arms"]:
for key in data.keys():
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=False))
if game == 'pcr':
tmp_lst.append(
operator(name=data[key]["名称"], star=int(data[key]["星级"]), limited=False)
)
if game == "pcr":
for key in data.keys():
limited = False
if key.find('(') != -1:
if key.find("(") != -1:
limited = True
try:
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=limited))
tmp_lst.append(
operator(
name=data[key]["名称"], star=int(data[key]["星级"]), limited=limited
)
)
except Exception as e:
logger.warning(f"公主连接导入角色 {key} 数据错误:{type(e)}:{e}")
if game == 'azur':
if game == "azur":
for key in data.keys():
if is_number(data[key]['星级']):
if is_number(data[key]["星级"]):
limited = False
if '可以建造' not in data[key]['获取途径']:
if "可以建造" not in data[key]["获取途径"]:
limited = True
try:
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']),
limited=limited, itype=data[key]['类型']))
tmp_lst.append(
operator(
name=data[key]["名称"],
star=int(data[key]["星级"]),
limited=limited,
type_=data[key]["类型"],
)
)
except Exception as e:
logger.warning(f"碧蓝航线导入角色 {key} 数据错误:{type(e)}:{e}")
if game in ['fgo', 'fgo_card']:
if game in ["fgo", "fgo_card"]:
for key in data.keys():
limited = False
try:
if "圣晶石召唤" not in data[key]['入手方式'] and "圣晶石召唤(Story卡池)" not in data[key]['入手方式']:
if (
"圣晶石召唤" not in data[key]["入手方式"]
and "圣晶石召唤(Story卡池)" not in data[key]["入手方式"]
):
limited = True
except KeyError:
pass
try:
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=limited))
tmp_lst.append(
operator(
name=data[key]["名称"], star=int(data[key]["星级"]), limited=limited
)
)
except Exception as e:
logger.warning(f"FGO导入角色 {key} 数据错误:{type(e)}:{e}")
if game == 'onmyoji':
if game == "onmyoji":
for key in data.keys():
limited = False
if key in ['奴良陆生', '卖药郎', '鬼灯', '阿香', '蜜桃&芥子', '犬夜叉', '杀生丸', '桔梗', '朽木露琪亚', '黑崎一护',
'灶门祢豆子', '灶门炭治郎']:
if key in [
"奴良陆生",
"卖药郎",
"鬼灯",
"阿香",
"蜜桃&芥子",
"犬夜叉",
"杀生丸",
"桔梗",
"朽木露琪亚",
"黑崎一护",
"灶门祢豆子",
"灶门炭治郎",
]:
limited = True
try:
tmp_lst.append(Operator(name=data[key]['名称'], star=data[key]['星级'], limited=limited))
tmp_lst.append(
operator(
name=data[key]["名称"], star=data[key]["星级"], limited=limited
)
)
except Exception as e:
logger.warning(f"阴阳师导入角色 {key} 数据错误:{type(e)}:{e}")
# print(tmp_lst)
char_name_lst = [x.name for x in tmp_lst]
up_char_file = Path(f'{DATA_PATH}/draw_card/draw_card_up/{game.split("_")[0]}_up_char.json')
up_char_file = (
DRAW_DATA_PATH
/ f"draw_card"
/ "draw_card_up"
/ f"{game.split('_')[0]}_up_char.json"
)
if up_char_file.exists():
data = json.load(open(up_char_file, 'r', encoding='utf8'))
if len(game.split('_')) == 1:
key = 'char'
data = json.load(open(up_char_file, "r", encoding="utf8"))
if len(game.split("_")) == 1:
key = "char"
else:
key = list(data.keys())[1]
for x in data[key]['up_char']:
for char in data[key]['up_char'][x]:
for x in data[key]["up_char"]:
for char in data[key]["up_char"][x]:
if char not in char_name_lst:
if game.find('prts') != -1:
tmp_lst.append(Operator(name=char, star=int(x),
recruit_only=False, event_only=False, limited=False))
if game.find("prts") != -1:
tmp_lst.append(
operator(
name=char,
star=int(x),
recruit_only=False,
event_only=False,
limited=False,
)
)
else:
tmp_lst.append(Operator(name=char, star=int(x), limited=False))
tmp_lst.append(operator(name=char, star=int(x), limited=False))
return tmp_lst
+6 -7
View File
@@ -1,9 +1,8 @@
from nonebot.adapters.cqhttp import MessageSegment
from nonebot.adapters.onebot.v11 import MessageSegment
import random
from .update_game_requests_info import update_requests_info
from .util import generate_img, init_star_rst, BaseData, set_list, get_star, max_card
from .config import ONMYOJI_SR, ONMYOJI_SSR, ONMYOJI_SP, ONMYOJI_R, DRAW_PATH, ONMYOJI_FLAG
from .config import DRAW_DATA_PATH, draw_config
from dataclasses import dataclass
from .init_card_pool import init_game_pool
try:
@@ -39,8 +38,8 @@ async def update_onmyoji_info():
async def init_onmyoji_data():
global ALL_CHAR
if ONMYOJI_FLAG:
with open(DRAW_PATH + 'onmyoji.json', 'r', encoding='utf8') as f:
if draw_config.ONMYOJI_FLAG:
with (DRAW_DATA_PATH / 'onmyoji.json').open('r', encoding='utf8') as f:
azur_dict = json.load(f)
ALL_CHAR = init_game_pool('onmyoji', azur_dict, OnmyojiChar)
@@ -56,7 +55,8 @@ onmyoji_star = {
# 抽取卡池
def _get_onmyoji_card():
global ALL_CHAR
star = get_star([5, 4, 3, 2], [ONMYOJI_SP, ONMYOJI_SSR, ONMYOJI_SR, ONMYOJI_R])
onmyoji_config = draw_config.onmyoji
star = get_star([5, 4, 3, 2], [onmyoji_config.ONMYOJI_SP, onmyoji_config.ONMYOJI_SSR, onmyoji_config.ONMYOJI_SR, onmyoji_config.ONMYOJI_R])
chars = [x for x in ALL_CHAR if x.star == onmyoji_star[star] and not x.limited]
return random.choice(chars), 5 - star
@@ -79,4 +79,3 @@ def format_card_information(count: int):
obj_dict[obj.name] = 1
obj_list.append(obj)
return obj_list, obj_dict, star_list, rst
+12 -8
View File
@@ -1,13 +1,16 @@
import ujson as json
from nonebot.adapters.cqhttp import MessageSegment
from nonebot.adapters.onebot.v11 import MessageSegment
import random
from .update_game_info import update_info
from .update_game_simple_info import update_simple_info
from .util import generate_img, init_star_rst, BaseData, set_list, get_star, max_card
from .config import PCR_TWO_P, PCR_THREE_P, PCR_ONE_P, DRAW_PATH, PCR_FLAG, PCR_G_TWO_P, PCR_G_THREE_P, PCR_TAI
from .config import DRAW_DATA_PATH, draw_config
from dataclasses import dataclass
from .init_card_pool import init_game_pool
try:
import ujson as json
except ModuleNotFoundError:
import json
ALL_CHAR = []
@@ -30,7 +33,7 @@ async def pcr_draw(count: int):
async def update_pcr_info():
global ALL_CHAR
if PCR_TAI:
if draw_config.PCR_TAI:
url = 'https://wiki.biligame.com/pcr/角色图鉴'
data, code = await update_simple_info(url, 'pcr')
else:
@@ -42,8 +45,8 @@ async def update_pcr_info():
async def init_pcr_data():
global ALL_CHAR
if PCR_FLAG:
with open(DRAW_PATH + 'pcr.json', 'r', encoding='utf8') as f:
if draw_config.PCR_FLAG:
with (DRAW_DATA_PATH / 'pcr.json').open('r', encoding='utf8') as f:
pcr_dict = json.load(f)
ALL_CHAR = init_game_pool('pcr', pcr_dict, PcrChar)
@@ -51,10 +54,11 @@ async def init_pcr_data():
# 抽取卡池
def _get_pcr_card(mode: int = 1):
global ALL_CHAR
pcr_config = draw_config.pcr
if mode == 2:
star = get_star([3, 2], [PCR_G_THREE_P, PCR_G_TWO_P])
star = get_star([3, 2], [pcr_config.PCR_G_THREE_P, pcr_config.PCR_G_TWO_P])
else:
star = get_star([3, 2, 1], [PCR_THREE_P, PCR_TWO_P, PCR_ONE_P])
star = get_star([3, 2, 1], [pcr_config.PCR_THREE_P, pcr_config.PCR_TWO_P, pcr_config.PCR_ONE_P])
chars = [x for x in ALL_CHAR if x.star == star and not x.limited]
return random.choice(chars), 3 - star
+12 -13
View File
@@ -1,13 +1,12 @@
from .update_game_info import update_info
from nonebot.adapters.onebot.v11 import MessageSegment
from .announcement import PrettyAnnouncement
from .update_game_info import update_info
from .util import init_star_rst, generate_img, max_card, BaseData, \
set_list, get_star, format_card_information, init_up_char
import random
from .config import PRETTY_THREE_P, PRETTY_TWO_P, DRAW_PATH, PRETTY_ONE_P, PRETTY_FLAG
from .config import DRAW_DATA_PATH, draw_config
from dataclasses import dataclass
from .init_card_pool import init_game_pool
from nonebot.adapters.cqhttp import MessageSegment, Message
try:
import ujson as json
@@ -74,7 +73,8 @@ async def pretty_draw(count: int, pool_name):
rst = init_star_rst(star_list, cnlist, three_list, three_olist, up_list)
if count > 90:
obj_list = set_list(obj_list)
return pool_info + MessageSegment.image("base64://" + await generate_img(obj_list, 'pretty', star_list)) \
return pool_info + MessageSegment.image(
"base64://" + await generate_img(obj_list, 'pretty', star_list)) \
+ '\n' + rst[:-1] + '\n' + max_card(obj_dict)
@@ -93,10 +93,10 @@ async def update_pretty_info():
async def init_pretty_data():
global ALL_CHAR, ALL_CARD
if PRETTY_FLAG:
with open(DRAW_PATH + 'pretty.json', 'r', encoding='utf8') as f:
if draw_config.PRETTY_FLAG:
with (DRAW_DATA_PATH / 'pretty.json').open('r', encoding='utf8') as f:
pretty_char_dict = json.load(f)
with open(DRAW_PATH + 'pretty_card.json', 'r', encoding='utf8') as f:
with (DRAW_DATA_PATH / 'pretty_card.json').open('r', encoding='utf8') as f:
pretty_card_dict = json.load(f)
ALL_CHAR = init_game_pool('pretty', pretty_char_dict, PrettyChar)
ALL_CARD = init_game_pool('pretty_card', pretty_card_dict, PrettyChar)
@@ -106,10 +106,11 @@ async def init_pretty_data():
# 抽取卡池
def _get_pretty_card(pool_name: str, mode: int = 1):
global ALL_CHAR, ALL_CARD, _CURRENT_CHAR_POOL_TITLE, _CURRENT_CARD_POOL_TITLE
pretty_config = draw_config.pretty
if mode == 1:
star = get_star([3, 2, 1], [PRETTY_THREE_P, PRETTY_TWO_P, PRETTY_ONE_P])
star = get_star([3, 2, 1], [pretty_config.PRETTY_THREE_P, pretty_config.PRETTY_TWO_P, pretty_config.PRETTY_ONE_P])
else:
star = get_star([3, 2], [PRETTY_THREE_P, PRETTY_TWO_P])
star = get_star([3, 2], [pretty_config.PRETTY_THREE_P, pretty_config.PRETTY_TWO_P])
if pool_name == 'card':
title = _CURRENT_CARD_POOL_TITLE
up_data = UP_CARD
@@ -127,7 +128,6 @@ def _get_pretty_card(pool_name: str, mode: int = 1):
acquire_operator = random.choice(all_up_star)
if pool_name == 'char':
acquire_operator = acquire_operator.split(']')[1]
print(acquire_operator)
acquire_operator = [x for x in data if x.name == acquire_operator][0]
else:
acquire_operator = random.choice([x for x in data if x.star == star and not x.limited])
@@ -144,6 +144,5 @@ async def _pretty_init_up_char():
async def reload_pretty_pool():
await _pretty_init_up_char()
return Message(f'当前UP池子:{_CURRENT_CHAR_POOL_TITLE} & {_CURRENT_CARD_POOL_TITLE} {POOL_IMG}')
return f'当前UP池子:{_CURRENT_CHAR_POOL_TITLE} & {_CURRENT_CARD_POOL_TITLE} {POOL_IMG}'
+9 -13
View File
@@ -1,14 +1,12 @@
from nonebot.adapters.cqhttp import MessageSegment, Message
from nonebot.adapters.onebot.v11 import MessageSegment, Message
import random
from .config import PRTS_FIVE_P, PRTS_FOUR_P, PRTS_SIX_P, PRTS_THREE_P, DRAW_PATH, PRTS_FLAG
from .config import DRAW_DATA_PATH, draw_config
from .update_game_info import update_info
from .util import generate_img, init_star_rst, max_card, BaseData, UpEvent, set_list, get_star
from .init_card_pool import init_game_pool
from pathlib import Path
from .announcement import PrtsAnnouncement
from services.log import logger
from dataclasses import dataclass
from nonebot.log import logger
try:
import ujson as json
except ModuleNotFoundError:
@@ -17,8 +15,6 @@ except ModuleNotFoundError:
announcement = PrtsAnnouncement()
up_char_file = Path() / "data" / "draw_card" / "draw_card_up" / "prts_up_char.json"
prts_dict = {}
UP_OPERATOR = []
ALL_OPERATOR = []
@@ -71,8 +67,8 @@ async def update_prts_info():
async def init_prts_data():
global prts_dict, ALL_OPERATOR
if PRTS_FLAG:
with open(DRAW_PATH + 'prts.json', 'r', encoding='utf8') as f:
if draw_config.PRTS_FLAG:
with (DRAW_DATA_PATH / 'prts.json').open('r', encoding='utf8') as f:
prts_dict = json.load(f)
ALL_OPERATOR = init_game_pool('prts', prts_dict, Operator)
await _init_up_char()
@@ -80,7 +76,8 @@ async def init_prts_data():
# 抽取干员
def _get_operator_card(add: float):
star = get_star([6, 5, 4, 3], [PRTS_SIX_P + add, PRTS_FIVE_P, PRTS_FOUR_P, PRTS_THREE_P])
prts_config = draw_config.prts
star = get_star([6, 5, 4, 3], [prts_config.PRTS_SIX_P + add, prts_config.PRTS_FIVE_P, prts_config.PRTS_FOUR_P, prts_config.PRTS_THREE_P])
if _CURRENT_POOL_TITLE:
zooms = [x.zoom for x in UP_OPERATOR if x.star == star]
zoom = 0
@@ -92,12 +89,11 @@ def _get_operator_card(add: float):
else:
weight = z
up_operator_name = ""
# UP
# UPs
try:
if random.random() < zoom:
if 0 < zoom:
up_operators = [x.operators for x in UP_OPERATOR if x.star == star and x.zoom < 1][0]
up_operator_name = random.choice(up_operators)
# print(up_operator_name)
acquire_operator = [x for x in ALL_OPERATOR if x.name == up_operator_name][0]
else:
all_star_operators = [x for x in ALL_OPERATOR if x.star == star
+19 -27
View File
@@ -1,36 +1,28 @@
from nonebot.rule import Rule
from nonebot.adapters.cqhttp import Bot, MessageEvent
from nonebot.adapters.onebot.v11 import Bot, MessageEvent
from nonebot.typing import T_State
from .config import (
GENSHIN_FLAG,
PRTS_FLAG,
PRETTY_FLAG,
GUARDIAN_FLAG,
PCR_FLAG,
AZUR_FLAG,
FGO_FLAG,
ONMYOJI_FLAG,
)
from .config import draw_config
def is_switch(game_name: str) -> Rule:
async def _is_switch(bot: Bot, event: MessageEvent, state: T_State) -> bool:
if game_name == "prts":
return PRTS_FLAG
if game_name == "genshin":
return GENSHIN_FLAG
if game_name == "pretty":
return PRETTY_FLAG
if game_name == "guardian":
return GUARDIAN_FLAG
if game_name == "pcr":
return PCR_FLAG
if game_name == "azur":
return AZUR_FLAG
if game_name == "fgo":
return FGO_FLAG
if game_name == "onmyoji":
return ONMYOJI_FLAG
if game_name == 'prts':
return draw_config.PRTS_FLAG
if game_name == 'genshin':
return draw_config.GENSHIN_FLAG
if game_name == 'pretty':
return draw_config.PRETTY_FLAG
if game_name == 'guardian':
return draw_config.GUARDIAN_FLAG
if game_name == 'pcr':
return draw_config.PCR_FLAG
if game_name == 'azur':
return draw_config.AZUR_FLAG
if game_name == 'fgo':
return draw_config.FGO_FLAG
if game_name == 'onmyoji':
return draw_config.ONMYOJI_FLAG
else:
return False
+40 -32
View File
@@ -1,12 +1,12 @@
from .config import DRAW_PATH
from typing import Tuple
from .config import DRAW_DATA_PATH
from asyncio.exceptions import TimeoutError
from bs4 import BeautifulSoup
from .util import download_img
from urllib.parse import unquote
from services.log import logger
from .util import remove_prohibited_str
from utils.http_utils import AsyncHttpx
from httpx import ConnectTimeout, CloseError
from nonebot.log import logger
import bs4
import re
try:
@@ -18,15 +18,16 @@ except ModuleNotFoundError:
headers = {'User-Agent': '"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)"'}
async def update_info(url: str, game_name: str, info_list: list = None) -> 'dict, int':
async def update_info(url: str, game_name: str, info_list: list = None) -> Tuple[dict, int]:
info_path = DRAW_DATA_PATH / f"{game_name}.json"
try:
with open(DRAW_PATH + f'{game_name}.json', 'r', encoding='utf8') as f:
with info_path.open('r', encoding='utf8') as f:
data = json.load(f)
except (ValueError, FileNotFoundError):
data = {}
try:
text = (await AsyncHttpx.get(url)).text
soup = BeautifulSoup(text, 'lxml')
response = await AsyncHttpx.get(url, timeout=7)
soup = BeautifulSoup(response.text, 'lxml')
_tbody = get_tbody(soup, game_name, url)
trs = _tbody.find_all('tr')
att_dict, start_index, index = init_attr(game_name)
@@ -58,13 +59,10 @@ async def update_info(url: str, game_name: str, info_list: list = None) -> 'dict
data[name] = member_dict
logger.info(f'{name} is update...')
data = await _last_check(data, game_name)
except (TimeoutError, ConnectTimeout, CloseError):
except TimeoutError:
logger.warning(f'更新 {game_name} 超时...')
return {}, 999
except Exception as e:
logger.error(f"更新 {game_name} 未知错误 {type(e)}:{e}")
return {}, 998
with open(DRAW_PATH + f'{game_name}.json', 'w', encoding='utf8') as wf:
with info_path.open('w', encoding='utf8') as wf:
wf.write(json.dumps(data, ensure_ascii=False, indent=4))
return data, 200
@@ -99,21 +97,25 @@ def _find_last_tag(element: bs4.element.Tag, attr: str, game_name: str) -> str:
# 获取大图(小图快爬)
async def _modify_avatar_url(game_name: str, char_name: str):
# if game_name == 'prts':
# async with session.get(f'https://wiki.biligame.com/arknights/{char_name}', timeout=7) as res:
# soup = BeautifulSoup(await res.text(), 'lxml')
# try:
# img_url = str(soup.find('img', {'class': 'img-bg'})['srcset']).split(' ')[-2]
# except KeyError:
# img_url = str(soup.find('img', {'class': 'img-bg'})['src'])
# return img_url
if game_name == 'prts':
res = await AsyncHttpx.get(f'https://wiki.biligame.com/arknights/{char_name}', timeout=7)
soup = BeautifulSoup(res.text, 'lxml')
try:
img_url = str(soup.find('img', {'class': 'img-bg'})['srcset']).split(' ')[-2]
except KeyError:
img_url = str(soup.find('img', {'class': 'img-bg'})['src'])
return img_url
if game_name == 'genshin':
return None
if game_name == 'pretty_card':
text = (await AsyncHttpx.get(f'https://wiki.biligame.com/umamusume/{char_name}')).text
soup = BeautifulSoup(text, 'lxml')
img_url = soup.find('div', {'class': 'support_card-left'}).find('div').find('img').get('src')
return img_url
res = await AsyncHttpx.get(f'https://wiki.biligame.com/umamusume/{char_name}', timeout=7)
soup = BeautifulSoup(res.text, 'lxml')
try:
img_url = soup.find('div', {'class': 'support_card-left'}).find('div').find('img').get('src')
return img_url
except AttributeError:
logger.warning("pretty_card 获取大图像失败")
return None
if game_name == 'guardian':
# 未上传图片太多,换成像素图
# async with session.get(f'https://wiki.biligame.com/gt/{char_name}', timeout=7) as res:
@@ -124,7 +126,7 @@ async def _modify_avatar_url(game_name: str, char_name: str):
# except KeyError:
# img_url = str(soup.find('img', {'class': 'img-kk'})['src'])
# except TypeError:
# logger.info(f'{char_name} 图片还未上传,跳过...')
# print(f'{char_name} 图片还未上传,跳过...')
# img_url = ''
# return img_url
return None
@@ -133,18 +135,17 @@ async def _modify_avatar_url(game_name: str, char_name: str):
# 数据最后处理(是否需要额外数据或处理数据)
async def _last_check(data: dict, game_name: str):
# if game_name == 'prts':
# url = 'https://wiki.biligame.com/arknights/'
# tasks = []
# for key in data.keys():
# tasks.append(asyncio.ensure_future(_async_update_prts_extra_info(url, key, session)))
# tasks.append(asyncio.ensure_future(_async_update_prts_extra_info(key, session)))
# asyResult = await asyncio.gather(*tasks)
# for x in asyResult:
# for key in x.keys():
# data[key]['获取途径'] = x[key]['获取途径']
if game_name == 'genshin':
for key in data.keys():
text = (await AsyncHttpx.get(f'https://wiki.biligame.com/ys/{key}')).text
soup = BeautifulSoup(text, 'lxml')
res = await AsyncHttpx.get(f'https://wiki.biligame.com/ys/{key}', timeout=7)
soup = BeautifulSoup(res.text, 'lxml')
_trs = ''
for table in soup.find_all('table', {'class': 'wikitable'}):
if str(table).find('常驻/限定') != -1:
@@ -193,6 +194,13 @@ def intermediate_check(member_dict: dict, key: str, game_name: str, td: bs4.elem
if game_name == 'pretty':
if key == '初始星级':
member_dict['初始星级'] = len(td.find_all('img'))
if game_name == 'pretty_card':
if key == '获取方式':
obtain = []
for x in str(td.text).replace('\n', '').strip().split('、'):
if x:
obtain.append(x)
member_dict['获取方式'] = obtain
if game_name == 'guardian':
if key == '头像':
member_dict['星级'] = str(td.find('span').find('img')['alt'])[-5]
@@ -257,7 +265,7 @@ def get_tbody(soup: bs4.BeautifulSoup, game_name: str, url: str):
return _tbody
# async def _async_update_prts_extra_info(url: str, key: str, session: aiohttp.ClientSession):
# async def _async_update_prts_extra_info(key: str, session: aiohttp.ClientSession):
# for i in range(10):
# try:
# async with session.get(f'https://wiki.biligame.com/arknights/{key}', timeout=7) as res:
@@ -277,11 +285,11 @@ def get_tbody(soup: bs4.BeautifulSoup, game_name: str, url: str):
# if r:
# text += r.group(1) + ' '
# obtain[i] = obtain[i].split('<a')[0] + text[:-1] + obtain[i].split('</a>')[-1]
# logger.info(f'明日方舟获取额外信息 {key}...{obtain}')
# print(f'明日方舟获取额外信息 {key}...{obtain}')
# x = {key: {}}
# x[key]['获取途径'] = obtain
# return x
# except TimeoutError:
# logger.warning(f'访问{url}{key} 第 {i}次 超时...已再次访问')
# print(f'访问 https://wiki.biligame.com/arknights/{key} 第 {i}次 超时...已再次访问')
# return {}
+91 -96
View File
@@ -1,63 +1,61 @@
from .config import DRAW_PATH, SEMAPHORE
from .config import DRAW_DATA_PATH, draw_config
from asyncio.exceptions import TimeoutError
from .util import download_img
from bs4 import BeautifulSoup
from .util import remove_prohibited_str
from utils.http_utils import AsyncHttpx
from services.log import logger
from httpx import ConnectTimeout, CloseError
from nonebot.log import logger
import asyncio
try:
import ujson as json
except ModuleNotFoundError:
import json
headers = {
"User-Agent": '"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)"'
}
headers = {'User-Agent': '"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)"'}
async def update_requests_info(game_name: str):
info_path = DRAW_DATA_PATH / f"{game_name}.json"
try:
with open(DRAW_PATH + f"{game_name}.json", "r", encoding="utf8") as f:
with info_path.open('r', encoding='utf8') as f:
data = json.load(f)
except (ValueError, FileNotFoundError):
data = {}
try:
if game_name in ["fgo", "fgo_card"]:
if game_name == "fgo":
url = "http://fgo.vgtime.com/servant/ajax?card=&wd=&ids=&sort=12777&o=desc&pn="
if game_name in ['fgo', 'fgo_card']:
if game_name == 'fgo':
url = 'http://fgo.vgtime.com/servant/ajax?card=&wd=&ids=&sort=12777&o=desc&pn='
else:
url = "http://fgo.vgtime.com/equipment/ajax?wd=&ids=&sort=12958&o=desc&pn="
url = 'http://fgo.vgtime.com/equipment/ajax?wd=&ids=&sort=12958&o=desc&pn='
for i in range(9999):
text = (await AsyncHttpx.get(f"{url}{i}")).text
fgo_data = json.loads(text)
if int(fgo_data["nums"]) == 0:
response = await AsyncHttpx.get(f'{url}{i}', timeout=7)
fgo_data = json.loads(response.text)
if int(fgo_data['nums']) == 0:
break
for x in fgo_data["data"]:
x["name"] = remove_prohibited_str(x["name"])
key = x["name"]
for x in fgo_data['data']:
x['name'] = remove_prohibited_str(x['name'])
key = x['name']
data = add_to_data(data, x, game_name)
await download_img(data[key]["头像"], game_name, key)
logger.info(f"{key} is update...")
if game_name == "onmyoji":
url = "https://yys.res.netease.com/pc/zt/20161108171335/js/app/all_shishen.json?v74="
onmyoji_data = (await AsyncHttpx.get(f"{url}")).json()
await download_img(data[key]['头像'], game_name, key)
logger.info(f'{key} is update...')
if game_name == 'onmyoji':
url = 'https://yys.res.netease.com/pc/zt/20161108171335/js/app/all_shishen.json?v74='
response = await AsyncHttpx.get(url, timeout=7)
onmyoji_data = response.json()
for x in onmyoji_data:
x["name"] = remove_prohibited_str(x["name"])
key = x["name"]
x['name'] = remove_prohibited_str(x['name'])
key = x['name']
data = add_to_data(data, x, game_name)
logger.info(f"{key} is update...")
logger.info(f'{key} is update...')
data = await _last_check(data, game_name)
except (TimeoutError, ConnectTimeout, CloseError):
logger.warning(f"更新 {game_name} 超时...")
except TimeoutError:
logger.warning(f'更新 {game_name} 超时...')
return {}, 999
except Exception as e:
logger.error(f"更新 {game_name} 未知错误 {type(e)}:{e}")
return {}, 998
with open(DRAW_PATH + f"{game_name}.json", "w", encoding="utf8") as wf:
logger.warning(f'更新 {game_name} 失败 {type(e)}:{e}...')
return {}, 999
with info_path.open('w', encoding='utf8') as wf:
json.dump(data, wf, ensure_ascii=False, indent=4)
return data, 200
@@ -65,67 +63,62 @@ async def update_requests_info(game_name: str):
# 添加到字典
def add_to_data(data: dict, x: dict, game_name: str) -> dict:
member_dict = {}
if game_name == "fgo":
if game_name == 'fgo':
member_dict = {
"id": x["id"],
"card_id": x["charid"],
"头像": x["icon"],
"名称": x["name"],
"职阶": x["classes"],
"星级": x["star"],
"hp": x["lvmax4hp"],
"atk": x["lvmax4atk"],
"card_quick": x["cardquick"],
"card_arts": x["cardarts"],
"card_buster": x["cardbuster"],
"宝具": x["tprop"],
'id': x['id'],
'card_id': x['charid'],
'头像': x['icon'],
'名称': x['name'],
'职阶': x['classes'],
'星级': x['star'],
'hp': x['lvmax4hp'],
'atk': x['lvmax4atk'],
'card_quick': x['cardquick'],
'card_arts': x['cardarts'],
'card_buster': x['cardbuster'],
'宝具': x['tprop'],
}
if game_name == "fgo_card":
if game_name == 'fgo_card':
member_dict = {
"id": x["id"],
"card_id": x["equipid"],
"头像": x["icon"],
"名称": x["name"],
"星级": x["star"],
"hp": x["lvmax_hp"],
"atk": x["lvmax_atk"],
"skill_e": x["skill_e"].split("<br />")[:-1],
'id': x['id'],
'card_id': x['equipid'],
'头像': x['icon'],
'名称': x['name'],
'星级': x['star'],
'hp': x['lvmax_hp'],
'atk': x['lvmax_atk'],
'skill_e': x['skill_e'].split('<br />')[: -1],
}
if game_name == "onmyoji":
if game_name == 'onmyoji':
member_dict = {
"id": x["id"],
"名称": x["name"],
"星级": x["level"],
'id': x['id'],
'名称': x['name'],
'星级': x['level'],
}
data[member_dict["名称"]] = member_dict
data[member_dict['名称']] = member_dict
return data
# 获取额外数据
async def _last_check(data: dict, game_name: str) -> dict:
if game_name == "fgo":
url = "http://fgo.vgtime.com/servant/"
if game_name == 'fgo':
url = 'http://fgo.vgtime.com/servant/'
tasks = []
semaphore = asyncio.Semaphore(SEMAPHORE)
semaphore = asyncio.Semaphore(draw_config.SEMAPHORE)
for key in data.keys():
tasks.append(
asyncio.ensure_future(
_async_update_fgo_extra_info(url, key, data[key]["id"], semaphore)
)
)
asyResult = await asyncio.gather(*tasks)
for x in asyResult:
tasks.append(asyncio.ensure_future(
_async_update_fgo_extra_info(url, key, data[key]['id'], semaphore)))
result = await asyncio.gather(*tasks)
for x in result:
for key in x.keys():
data[key]["入手方式"] = x[key]["入手方式"]
if game_name == "onmyoji":
url = "https://yys.163.com/shishen/{}.html"
data[key]['入手方式'] = x[key]['入手方式']
if game_name == 'onmyoji':
url = 'https://yys.163.com/shishen/{}.html'
for key in data.keys():
text = (await AsyncHttpx.get(f'{url.format(data[key]["id"])}')).text
soup = BeautifulSoup(text, "lxml")
data[key]["头像"] = (
"https:" + soup.find("div", {"class": "pic_wrap"}).find("img")["src"]
)
await download_img(data[key]["头像"], game_name, key)
response = await AsyncHttpx.get(f'{url.format(data[key]["id"])}', timeout=7)
soup = BeautifulSoup(response.text, 'lxml')
data[key]['头像'] = "https:" + soup.find('div', {'class': 'pic_wrap'}).find('img')['src']
await download_img(data[key]['头像'], game_name, key)
return data
@@ -134,28 +127,30 @@ async def _async_update_fgo_extra_info(url: str, key: str, _id: str, semaphore):
async with semaphore:
for i in range(10):
try:
text = (await AsyncHttpx.get(f"{url}{_id}")).text
soup = BeautifulSoup(text, "lxml")
obtain = (
soup.find("table", {"class": "uk-table uk-codex-table"})
.find_all("td")[-1]
.text
)
if obtain.find("限时活动免费获取 活动结束后无法获得") != -1:
obtain = ["活动获取"]
elif obtain.find("非限时UP无法获得") != -1:
obtain = ["限时召唤"]
response = await AsyncHttpx.get(f'{url}{_id}', timeout=7)
soup = BeautifulSoup(response.text, 'lxml')
obtain = soup.find('table', {'class': 'uk-table uk-codex-table'}).find_all('td')[-1].text
if obtain.find('限时活动免费获取 活动结束后无法获得') != -1:
obtain = ['活动获取']
elif obtain.find('非限时UP无法获得') != -1:
obtain = ['限时召唤']
else:
if obtain.find("&") != -1:
obtain = obtain.strip().split("&")
if obtain.find('&') != -1:
obtain = obtain.strip().split('&')
else:
obtain = obtain.strip().split(" ")
logger.info(f"Fgo获取额外信息 {key}....{obtain}")
obtain = obtain.strip().split(' ')
logger.info(f'Fgo获取额外信息 {key}....{obtain}')
x = {key: {}}
x[key]["入手方式"] = obtain
x[key]['入手方式'] = obtain
return x
except (TimeoutError, ConnectTimeout, CloseError):
logger.warning(f"访问{url}{_id} 第 {i}次 超时...已再次访问")
except TimeoutError:
logger.warning(f'访问{url}{_id} 第 {i}次 超时...已再次访问')
except Exception as e:
logger.error(f"访问{url}{_id} 第 {i}次 未知错误 {type(e)}:{e}...已再次访问")
logger.warning(f'访问{url}{_id} 第 {i}次 发生错误:{e}...已再次访问')
return {}
+125 -98
View File
@@ -1,12 +1,12 @@
from .config import DRAW_PATH, SEMAPHORE
from typing import Tuple
from .config import DRAW_DATA_PATH, draw_config
from asyncio.exceptions import TimeoutError
from bs4 import BeautifulSoup
from .util import download_img
from .util import remove_prohibited_str
from urllib.parse import unquote
from services.log import logger
from utils.http_utils import AsyncHttpx
from httpx import ConnectTimeout, CloseError
from nonebot.log import logger
import bs4
import asyncio
@@ -15,18 +15,21 @@ try:
except ModuleNotFoundError:
import json
headers = {'User-Agent': '"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)"'}
headers = {
"User-Agent": '"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)"'
}
async def update_simple_info(url: str, game_name: str) -> 'dict, int':
async def update_simple_info(url: str, game_name: str) -> Tuple[dict, int]:
info_path = DRAW_DATA_PATH / f"{game_name}.json"
try:
with open(DRAW_PATH + f'{game_name}.json', 'r', encoding='utf8') as f:
with info_path.open("r", encoding="utf8") as f:
data = json.load(f)
except (ValueError, FileNotFoundError):
data = {}
try:
text = (await AsyncHttpx.get(url)).text
soup = BeautifulSoup(text, 'lxml')
response = await AsyncHttpx.get(url, timeout=7)
soup = BeautifulSoup(response.text, "lxml")
divs = get_char_divs(soup, game_name)
for div in divs:
type_lst = get_type_lst(div, game_name)
@@ -38,161 +41,185 @@ async def update_simple_info(url: str, game_name: str) -> 'dict, int':
continue
for char in contents[1:]:
try:
data = await retrieve_char_data(char, game_name, data, index)
data = await retrieve_char_data(
char, game_name, data, index
)
except AttributeError:
continue
index += 1
data = await _last_check(data, game_name)
except (TimeoutError, ConnectTimeout, CloseError):
logger.warning(f'更新 {game_name} 超时...')
except TimeoutError:
logger.warning(f"更新 {game_name} 超时...")
return {}, 999
with open(DRAW_PATH + f'{game_name}.json', 'w', encoding='utf8') as wf:
with info_path.open("w", encoding="utf8") as wf:
wf.write(json.dumps(data, ensure_ascii=False, indent=4))
return data, 200
# 获取所有包含需要图片的divs
def get_char_divs(soup: bs4.BeautifulSoup, game_name: str) -> bs4.element.ResultSet:
if game_name == 'pcr':
return soup.find_all('div', {'class': 'tabbertab'})
if game_name == 'azur':
return soup.find_all('div', {'class': 'resp-tabs'})
# if game_name == "pcr":
# return soup.find_all("div", {"class": "tabbertab"})
if game_name in ["azur", "pcr"]:
return soup.find_all("div", {"class": "resp-tabs"})
# 拿到所有类型
def get_type_lst(div: bs4.element.Tag, game_name: str):
if game_name in ['pcr', 'azur']:
return div.find('div', {'class': 'resp-tabs-container'}).find_all('div', {'class': 'resp-tab-content'})
if game_name in ["pcr", "azur"]:
return div.find("div", {"class": "resp-tabs-container"}).find_all(
"div", {"class": "resp-tab-content"}
)
# 获取所有角色div
def get_char_lst_contents(char_lst: bs4.element.Tag, game_name: str):
contents = []
# logger.info(len(char_lst.find_all('tr')))
if game_name == 'pcr':
# print(len(char_lst.find_all('tr')))
if game_name == "pcr":
contents = char_lst.contents
if game_name == 'azur':
contents = char_lst.find('table').find('tbody').contents[-1].find('td').contents
return [x for x in contents if x != '\n']
if game_name == "azur":
contents = char_lst.find("table").find("tbody").contents[-1].find("td").contents
return [x for x in contents if x != "\n"]
# 额外数据
async def _last_check(data: dict, game_name: str) -> dict:
if game_name == 'azur':
async def _last_check(
data: dict, game_name: str
) -> dict:
if game_name == "azur":
idx = 1
for url in [
'https://patchwiki.biligame.com/images/blhx/thumb/1/15/pxho13xsnkyb546tftvh49etzdh74cf.png/60px'
'-舰娘头像外框普通.png',
'https://patchwiki.biligame.com/images/blhx/thumb/a/a9/k8t7nx6c8pan5vyr8z21txp45jxeo66.png/60px'
'-舰娘头像外框稀有.png',
'https://patchwiki.biligame.com/images/blhx/thumb/a/a5/5whkzvt200zwhhx0h0iz9qo1kldnidj.png/60px'
'-舰娘头像外框精锐.png',
'https://patchwiki.biligame.com/images/blhx/thumb/a/a2/ptog1j220x5q02hytpwc8al7f229qk9.png/60px-'
'舰娘头像外框超稀有.png'
'https://patchwiki.biligame.com/images/blhx/thumb/0/0f/n28p7p3opfn5mhgjyio55ljsllhknwz.png/60px-'
'舰娘头像外框精锐META.png'
"https://patchwiki.biligame.com/images/blhx/thumb/1/15/pxho13xsnkyb546tftvh49etzdh74cf.png/60px"
"-舰娘头像外框普通.png",
"https://patchwiki.biligame.com/images/blhx/thumb/a/a9/k8t7nx6c8pan5vyr8z21txp45jxeo66.png/60px"
"-舰娘头像外框稀有.png",
"https://patchwiki.biligame.com/images/blhx/thumb/a/a5/5whkzvt200zwhhx0h0iz9qo1kldnidj.png/60px"
"-舰娘头像外框精锐.png",
"https://patchwiki.biligame.com/images/blhx/thumb/a/a2/ptog1j220x5q02hytpwc8al7f229qk9.png/60px-"
"舰娘头像外框超稀有.png",
]:
await download_img(url, 'azur', f'{idx}_star')
await download_img(url, "azur", f"{idx}_star")
idx += 1
tasks = []
semaphore = asyncio.Semaphore(SEMAPHORE)
semaphore = asyncio.Semaphore(draw_config.SEMAPHORE)
for key in data.keys():
tasks.append(asyncio.ensure_future(_async_update_azur_extra_info(key, semaphore)))
asyResult = await asyncio.gather(*tasks)
for x in asyResult:
tasks.append(
asyncio.ensure_future(
_async_update_azur_extra_info(key, semaphore)
)
)
result = await asyncio.gather(*tasks)
for x in result:
for key in x.keys():
data[key]['获取途径'] = x[key]['获取途径']
data[key]["获取途径"] = x[key]["获取途径"]
return data
azur_type = {
'0': '驱逐',
'1': '轻巡',
'2': '重巡',
'3': '超巡',
'4': '战巡',
'5': '战列',
'6': '航母',
'7': '航站',
'8': '轻航',
'9': '重炮',
'10': '维修',
'11': '潜艇',
'12': '运输',
"0": "驱逐",
"1": "轻巡",
"2": "重巡",
"3": "超巡",
"4": "战巡",
"5": "战列",
"6": "航母",
"7": "航站",
"8": "轻航",
"9": "重炮",
"10": "维修",
"11": "潜艇",
"12": "运输",
}
# 整理数据
async def retrieve_char_data(char: bs4.element.Tag, game_name: str, data: dict, index: int = 0) -> dict:
async def retrieve_char_data(
char: bs4.element.Tag,
game_name: str,
data: dict,
index: int = 0,
) -> dict:
member_dict = {}
if game_name == 'pcr':
if game_name == "pcr":
member_dict = {
'头像': unquote(char.find('img', {'class': 'img-kk'})['src']),
'名称': remove_prohibited_str(char.find('a')['title']),
'星级': 3 - index}
if game_name == 'azur':
char = char.find('div').find('div').find('div')
avatar_img = char.find('a').find('img')
char = char.find('div')
"头像": unquote(char.find("a").find("img")["src"]),
"名称": remove_prohibited_str(char.find("a")["title"]),
"星级": 3 - index,
}
if game_name == "azur":
char = char.find("div").find("div").find("div")
avatar_img = char.find("a").find("img")
char = char.find("div")
try:
member_dict['名称'] = remove_prohibited_str(char.find('a')['title'])
member_dict["名称"] = remove_prohibited_str(char.find("a")["title"])
except TypeError:
member_dict['名称'] = char.find('a')['title'][:-4]
member_dict["名称"] = char.find("a")["title"][:-4]
try:
member_dict['头像'] = unquote(str(avatar_img['srcset']).split(' ')[-2])
member_dict["头像"] = unquote(str(avatar_img["srcset"]).split(" ")[-2])
except KeyError:
member_dict['头像'] = unquote(str(avatar_img['src']).split(' ')[-2])
member_dict["头像"] = unquote(str(avatar_img["src"]).split(" ")[-2])
except TypeError:
member_dict['头像'] = "img link not find..."
member_dict["头像"] = "img link not find..."
logger.warning(f'{member_dict["名称"]} 图片缺失....')
star = char.find('img')['alt']
if star == '舰娘头像外框普通.png':
star = char.find("img")["alt"]
if star == "舰娘头像外框普通.png":
star = 1
elif star == '舰娘头像外框稀有.png':
elif star == "舰娘头像外框稀有.png":
star = 2
elif star == '舰娘头像外框精锐.png':
elif star == "舰娘头像外框精锐.png":
star = 3
elif star == '舰娘头像外框超稀有.png':
elif star == "舰娘头像外框超稀有.png":
star = 4
elif star == '舰娘头像外框海上传奇.png':
elif star == "舰娘头像外框海上传奇.png":
star = 5
elif star in ['舰娘头像外框最高方案.png', '舰娘头像外框决战方案.png', '舰娘头像外框超稀有META.png', '舰娘头像外框精锐META.png']:
elif star in [
"舰娘头像外框最高方案.png",
"舰娘头像外框决战方案.png",
"舰娘头像外框超稀有META.png",
"舰娘头像外框精锐META.png",
]:
star = 6
else:
star = 6
member_dict['星级'] = star
member_dict['类型'] = azur_type[str(index)]
await download_img(member_dict['头像'], game_name, member_dict['名称'])
data[member_dict['名称']] = member_dict
member_dict["星级"] = star
member_dict["类型"] = azur_type[str(index)]
await download_img(member_dict["头像"], game_name, member_dict["名称"])
data[member_dict["名称"]] = member_dict
logger.info(f'{member_dict["名称"]} is update...')
return data
async def _async_update_azur_extra_info(key: str, semaphore):
if key[-1] == '改':
return {key: {'获取途径': ['无法建造']}}
async def _async_update_azur_extra_info(
key: str, semaphore
):
if key[-1] == "改":
return {key: {"获取途径": ["无法建造"]}}
async with semaphore:
for i in range(20):
try:
text = (await AsyncHttpx.get(f'https://wiki.biligame.com/blhx/{key}')).text
soup = BeautifulSoup(text, 'lxml')
res = await AsyncHttpx.get(f"https://wiki.biligame.com/blhx/{key}", timeout=7)
soup = BeautifulSoup(res.text, "lxml")
try:
construction_time = str(soup.find('table', {'class': 'wikitable sv-general'}).find('tbody'))
x = {key: {'获取途径': []}}
if construction_time.find('无法建造') != -1:
x[key]['获取途径'].append('无法建造')
elif construction_time.find('活动已关闭') != -1:
x[key]['获取途径'].append('活动限定')
construction_time = str(
soup.find("table", {"class": "wikitable sv-general"}).find(
"tbody"
)
)
x = {key: {"获取途径": []}}
if construction_time.find("无法建造") != -1:
x[key]["获取途径"].append("无法建造")
elif construction_time.find("活动已关闭") != -1:
x[key]["获取途径"].append("活动限定")
else:
x[key]['获取途径'].append('可以建造')
x[key]["获取途径"].append("可以建造")
logger.info(f'碧蓝航线获取额外信息 {key}...{x[key]["获取途径"]}')
except AttributeError:
x = {key: {'获取途径': []}}
logger.warning(f'碧蓝航线获取额外信息错误 {key}...{[]}')
x = {key: {"获取途径": []}}
logger.warning(f"碧蓝航线获取额外信息错误 {key}...{[]}")
return x
except (TimeoutError, ConnectTimeout, CloseError):
logger.warning(f'访问 https://wiki.biligame.com/blhx/{key} 第 {i}次 超时/失败...已再次访问')
except Exception as e:
logger.error(f'访问 https://wiki.biligame.com/blhx/{key} 第 {i}次 未知错误 {type(e)}:{e}...已再次访问')
except TimeoutError:
logger.warning(
f"访问 https://wiki.biligame.com/blhx/{key} 第 {i}次 超时...已再次访问"
)
return {}
+159 -114
View File
@@ -1,34 +1,26 @@
from nonebot.adapters.cqhttp import MessageSegment
from typing import List, Union, Set
from pathlib import Path
from .config import path_dict
from configs.path_config import IMAGE_PATH
from utils.http_utils import AsyncHttpx
import nonebot
import pypinyin
from utils.image_utils import BuildImage
import platform
from services.log import logger
from asyncio.exceptions import TimeoutError
from utils.utils import cn2py
from utils.http_utils import AsyncHttpx
from typing import List, Tuple, Union, Set
from .config import draw_config, DRAW_IMAGE_PATH
import nonebot
from PIL import UnidentifiedImageError
from utils.image_utils import BuildImage
from nonebot.adapters.onebot.v11 import MessageSegment
from nonebot.log import logger
import random
from dataclasses import dataclass
import os
import asyncio
from PIL import UnidentifiedImageError
try:
import ujson as json
except ModuleNotFoundError:
import json
driver: nonebot.Driver = nonebot.get_driver()
driver = nonebot.get_driver()
loop = asyncio.get_event_loop()
headers = {'User-Agent': '"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)"'}
@dataclass
class BaseData:
name: str
@@ -44,47 +36,52 @@ class UpEvent:
async def download_img(url: str, path: str, name: str) -> bool:
path = path.split('_')[0]
path = path.split("_")[0]
codename = cn2py(name)
file = Path(IMAGE_PATH + f'/draw_card/{path}/{codename}.png')
if not file.exists():
file.parent.mkdir(exist_ok=True, parents=True)
img_path = DRAW_IMAGE_PATH / f"{path}" / f"{codename}.png"
if not img_path.exists():
try:
if await AsyncHttpx.download_file(url, IMAGE_PATH + f'/draw_card/{path}/{codename}.png'):
logger.info(f'下载 {path_dict[path]} 图片成功,名称:{name},url:{url}')
if await AsyncHttpx.download_file(url, img_path):
logger.info(
f"下载 {draw_config.path_dict[path]} 图片成功,名称:{name},url:{url}"
)
return True
except Exception as e:
logger.warning(f'下载 {path_dict[path]} 链接错误 {type(e)}:{e},名称:{name},url:{url}')
except TimeoutError:
logger.warning(f"下载 {draw_config.path_dict[path]} 图片超时,名称:{name},url:{url}")
# logger.info(f'{path_dict[path]} 图片 {name} 已存在')
return False
@driver.on_startup
def _check_dir():
for dir_name in path_dict.keys():
_p = Path(IMAGE_PATH + f'/draw_card/' + dir_name)
if not _p.exists():
_p.mkdir(parents=True, exist_ok=True)
for dir_name in draw_config.path_dict.keys():
dir_path = DRAW_IMAGE_PATH / f"{dir_name}"
if not dir_path.exists():
dir_path.mkdir(parents=True, exist_ok=True)
async def generate_img(card_set: Union[Set[BaseData], List[BaseData]], game_name: str, star_list: list) -> str:
async def generate_img(
card_set: Union[Set[BaseData], List[BaseData]], game_name: str, star_list: list
) -> str:
# try:
img_list = []
background_list = []
for x in card_set:
if game_name == 'prts':
if game_name == "prts":
if x.star == 6:
background_list.append('#FFD700')
background_list.append("#FFD700")
elif x.star == 5:
background_list.append('#DAA520')
background_list.append("#DAA520")
elif x.star == 4:
background_list.append('#9370D8')
background_list.append("#9370D8")
else:
background_list.append('white')
if game_name == 'azur':
if os.path.exists(IMAGE_PATH + f'/draw_card/{game_name}/{x.star}_star.png'):
background_list.append(IMAGE_PATH + f'/draw_card/{game_name}/{x.star}_star.png')
pyname = cn2py(x.name)
img_list.append(IMAGE_PATH + f'/draw_card/{game_name}/{pyname}.png')
background_list.append("white")
img_path = DRAW_IMAGE_PATH / f"{game_name}" / f"{x.star}_star.png"
if game_name == "azur":
if img_path.exists():
background_list.append(str(img_path))
py_name = cn2py(x.name)
img_list.append(str(DRAW_IMAGE_PATH / f"{game_name}" / f"{py_name}.png"))
img_len = len(img_list)
w = 100 * 10
if img_len <= 10:
@@ -94,7 +91,9 @@ async def generate_img(card_set: Union[Set[BaseData], List[BaseData]], game_name
h = 100 * int(img_len / 10)
else:
h = 100 * int(img_len / 10) + 100
card_img = await asyncio.get_event_loop().run_in_executor(None, _pst, h, img_list, game_name, background_list)
card_img = await asyncio.get_event_loop().run_in_executor(
None, _pst, h, img_list, game_name, background_list
)
num = 0
for n in star_list:
num += n
@@ -108,12 +107,12 @@ def _pst(h: int, img_list: list, game_name: str, background_list: list):
idx = 0
for img in img_list:
try:
if game_name == 'prts':
if game_name == "prts":
bk = BuildImage(100, 100, color=background_list[idx])
b = BuildImage(94, 94, background=img)
bk.paste(b, (3, 3))
b = bk
elif game_name == 'azur' and background_list:
elif game_name == "azur" and background_list:
bk = BuildImage(100, 100, background=background_list[idx])
b = BuildImage(98, 90, background=img)
bk.paste(b, (1, 5))
@@ -122,38 +121,75 @@ def _pst(h: int, img_list: list, game_name: str, background_list: list):
try:
b = BuildImage(100, 100, background=img)
except UnidentifiedImageError as e:
logger.warning(f'无法识别图片 已删除图片,下次更新重新下载... e:{e}')
logger.warning(f"无法识别图片 已删除图片,下次更新重新下载... e:{e}")
if os.path.exists(img):
os.remove(img)
b = BuildImage(100, 100, color='black')
b = BuildImage(100, 100, color="black")
except FileNotFoundError:
logger.warning(f'{img} not exists')
b = BuildImage(100, 100, color='black')
logger.warning(f"{img} not exists")
b = BuildImage(100, 100, color="black")
card_img.paste(b)
idx += 1
return card_img
def init_star_rst(star_list: list, cnlist: list, max_star_list: list, max_star_index_list: list, up_list: list = None) -> str:
# 初始化输出数据
def init_star_rst(
star_list: list,
cnlist: list,
max_star_list: list,
max_star_index_list: list,
up_list: list = None,
) -> str:
if not up_list:
up_list = []
rst = ''
rst = ""
for i in range(len(star_list)):
if star_list[i]:
rst += f'[{cnlist[i]}×{star_list[i]}] '
rst += '\n'
rst += f"[{cnlist[i]}×{star_list[i]}] "
rst += "\n"
for i in range(len(max_star_list)):
if max_star_list[i] in up_list:
rst += f'第 {max_star_index_list[i]+1} 抽获取UP {max_star_list[i]}\n'
rst += f"第 {max_star_index_list[i]+1} 抽获取UP {max_star_list[i]}\n"
else:
rst += f'第 {max_star_index_list[i]+1} 抽获取 {max_star_list[i]}\n'
rst += f"第 {max_star_index_list[i]+1} 抽获取 {max_star_list[i]}\n"
return rst
# 更好的初始化
def init_rst(
max_star_char_dict: dict,
star_num_list: List[int],
star: List[str],
up_list: list = None,
):
# print(max_star_char_dict)
# print(star_num_list)
# print(up_list)
up_list = up_list if up_list else []
rst = ""
for i in range(len(star_num_list)):
if star_num_list[i]:
rst += f"[{star[i]}×{star_num_list[i]}] "
rst += "\n"
_tmp = []
for name in max_star_char_dict.keys():
_tmp += max_star_char_dict[name]
for index in sorted(_tmp):
for name in max_star_char_dict.keys():
if index in max_star_char_dict[name]:
if name in up_list:
rst += f"第 {index} 抽获取UP {name}\n"
else:
rst += f"第 {index} 抽获取 {name}\n"
print(rst)
return rst[:-1] if rst else ""
def max_card(_dict: dict):
_max_value = max(_dict.values())
_max_user = list(_dict.keys())[list(_dict.values()).index(_max_value)]
return f'抽取到最多的是{_max_user},共抽取了{_max_value}次'
return f"抽取到最多的是{_max_user},共抽取了{_max_value}次"
# ThreeHighest = nlargest(3, operator_dict, key=operator_dict.get)
# rst = '最喜欢你的前三位是干员是:\n'
# for name in ThreeHighest:
@@ -161,6 +197,55 @@ def max_card(_dict: dict):
# return rst[:-1]
# 获取up和概率
async def init_up_char(announcement):
UP_CHAR = []
UP_ARMS = []
tmp = ""
up_char_dict = await announcement.update_up_char()
for x in list(up_char_dict.keys()):
tmp += up_char_dict[x]["title"] + "[\n]"
tmp = tmp.split("[\n]")
_CURRENT_CHAR_POOL_TITLE = tmp[0]
if len(up_char_dict) > 1:
_CURRENT_ARMS_POOL_TITLE = tmp[1]
else:
_CURRENT_ARMS_POOL_TITLE = ""
POOL_IMG = ""
x = [x for x in list(up_char_dict.keys())]
if _CURRENT_CHAR_POOL_TITLE:
POOL_IMG += MessageSegment.image(up_char_dict[x[0]]["pool_img"])
try:
if _CURRENT_ARMS_POOL_TITLE:
POOL_IMG += MessageSegment.image(up_char_dict[x[1]]["pool_img"])
except (IndexError, KeyError):
pass
logger.info(
f"成功获取{announcement.game_name}当前up信息...当前up池: {_CURRENT_CHAR_POOL_TITLE} & {_CURRENT_ARMS_POOL_TITLE}"
)
for key in up_char_dict.keys():
for star in up_char_dict[key]["up_char"].keys():
up_char_lst = []
for char in up_char_dict[key]["up_char"][star].keys():
up_char_lst.append(char)
if up_char_lst:
if key == "char":
UP_CHAR.append(
UpEvent(star=int(star), operators=up_char_lst, zoom=0)
)
else:
UP_ARMS.append(
UpEvent(star=int(star), operators=up_char_lst, zoom=0)
)
return (
_CURRENT_CHAR_POOL_TITLE,
_CURRENT_ARMS_POOL_TITLE,
POOL_IMG,
UP_CHAR,
UP_ARMS,
)
def is_number(s) -> bool:
try:
float(s)
@@ -169,6 +254,7 @@ def is_number(s) -> bool:
pass
try:
import unicodedata
unicodedata.numeric(s)
return True
except (TypeError, ValueError):
@@ -176,13 +262,6 @@ def is_number(s) -> bool:
return False
def cn2py(word) -> str:
temp = ""
for i in pypinyin.pinyin(word, style=pypinyin.NORMAL):
temp += ''.join(i)
return temp
def set_list(lst: List[BaseData]) -> list:
tmp = []
name_lst = []
@@ -193,6 +272,7 @@ def set_list(lst: List[BaseData]) -> list:
return tmp
# 获取星级
def get_star(star_lst: List[int], probability_lst: List[float]) -> int:
rand = random.random()
add = 0
@@ -206,49 +286,14 @@ def get_star(star_lst: List[int], probability_lst: List[float]) -> int:
return star_lst[i]
# 获取up和概率
async def init_up_char(announcement):
UP_CHAR = []
UP_ARMS = []
tmp = ''
up_char_dict = await announcement.update_up_char()
for x in list(up_char_dict.keys()):
tmp += up_char_dict[x]['title'] + '[\n]'
tmp = tmp.split('[\n]')
_CURRENT_CHAR_POOL_TITLE = tmp[0]
if len(up_char_dict) > 1:
_CURRENT_ARMS_POOL_TITLE = tmp[1]
else:
_CURRENT_ARMS_POOL_TITLE = ''
POOL_IMG = ''
x = [x for x in list(up_char_dict.keys())]
if _CURRENT_CHAR_POOL_TITLE:
POOL_IMG += MessageSegment.image(up_char_dict[x[0]]['pool_img'])
try:
if _CURRENT_ARMS_POOL_TITLE:
POOL_IMG += MessageSegment.image(up_char_dict[x[1]]['pool_img'])
except (IndexError, KeyError):
pass
logger.info(f'成功获取{announcement.game_name}当前up信息...当前up池: {_CURRENT_CHAR_POOL_TITLE} & {_CURRENT_ARMS_POOL_TITLE}')
for key in up_char_dict.keys():
for star in up_char_dict[key]['up_char'].keys():
up_char_lst = []
for char in up_char_dict[key]['up_char'][star].keys():
up_char_lst.append(char)
if up_char_lst:
if key == 'char':
UP_CHAR.append(UpEvent(star=int(star), operators=up_char_lst, zoom=0))
else:
UP_ARMS.append(UpEvent(star=int(star), operators=up_char_lst, zoom=0))
return _CURRENT_CHAR_POOL_TITLE, _CURRENT_ARMS_POOL_TITLE, POOL_IMG, UP_CHAR, UP_ARMS
# 整理数据
def format_card_information(count: int, star_list: List[int], func, pool_name: str = '', guaranteed: bool = True):
max_star_lst = [] # 获取的最高星级角色列表
max_index_lst = [] # 获取最高星级角色的次数
obj_list = [] # 获取所有角色
obj_dict = {} # 获取角色次数字典
def format_card_information(
count: int, star_list: List[int], func, pool_name: str = "", guaranteed: bool = True
):
max_star_lst = [] # 获取的最高星级角色列表
max_index_lst = [] # 获取最高星级角色的次数
obj_list = [] # 获取所有角色
obj_dict = {} # 获取角色次数字典
_count = -1
if guaranteed:
_count = 0
@@ -285,28 +330,28 @@ def format_card_information(count: int, star_list: List[int], func, pool_name: s
# 检测次数是否合法
def check_num(num: str, max_num: int) -> 'str, bool':
def check_num(num: str, max_num: int) -> Tuple[str, bool]:
if is_number(num):
try:
num = int(num)
except ValueError:
return '必!须!是!数!字!', False
return "必!须!是!数!字!", False
if num > max_num:
return '一井都满不足不了你嘛!快爬开!', False
return "一井都满不足不了你嘛!快爬开!", False
if num < 1:
return '虚空抽卡???', False
return "虚空抽卡???", False
else:
return str(num), True
# 移除windows和linux下特殊字符
def remove_prohibited_str(name: str):
if platform.system().lower() == 'windows':
tmp = ''
def remove_prohibited_str(name: str) -> str:
if platform.system().lower() == "windows":
tmp = ""
for i in name:
if i not in ['\\', '/', ':', '*', '?', '"', '<', '>', '|']:
if i not in ["\\", "/", ":", "*", "?", '"', "<", ">", "|"]:
tmp += i
name = tmp
else:
name = name.replace('/', '\\')
name = name.replace("/", "\\")
return name