This commit is contained in:
hibiki 2021-05-26 20:08:13 +08:00
parent 7359c6fa98
commit c27a1c4fb8
162 changed files with 922 additions and 932 deletions

0
plugins/__init__.py Normal file
View File

View File

@ -2,26 +2,45 @@ from nonebot import on_regex, on_keyword
from nonebot.adapters.cqhttp import Bot, MessageEvent from nonebot.adapters.cqhttp import Bot, MessageEvent
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
from nonebot.typing import T_State from nonebot.typing import T_State
from services.log import logger
from util.utils import scheduler
import re
from .genshin_handle import genshin_draw, update_genshin_info, reset_count from .genshin_handle import genshin_draw, update_genshin_info, reset_count
from .prts_handle import update_prts_info, prts_draw, reload_pool from .prts_handle import update_prts_info, prts_draw, reload_pool
from .pretty_handle import update_pretty_info, pretty_draw from .pretty_handle import update_pretty_info, pretty_draw
from .guardian_handle import update_guardian_info, guardian_draw
from .pcr_handle import update_pcr_info, pcr_draw
from .update_game_info import update_info from .update_game_info import update_info
from util.utils import is_number, scheduler from .util import check_num
from services.log import logger from .rule import is_switch
import re from .config import PRTS_FLAG, PRETTY_FLAG, GUARDIAN_FLAG, GENSHIN_FLAG, PCR_FLAG
prts = on_regex(r'.*?方舟[1-9|一][0-9]{0,2}[抽|井]', priority=5, 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_update = on_keyword({'更新方舟信息', '更新明日方舟信息'}, permission=SUPERUSER, priority=1, block=True)
prts_reload = on_keyword({'重载方舟卡池'}, priority=1, block=True) prts_reload = on_keyword({'重载方舟卡池'}, priority=1, block=True)
genshin = on_regex('.*?原神[1-9|一][0-9]{0,2}[抽|井]', priority=5, block=True) genshin = on_regex('.*?原神[1-9|一][0-9]{0,2}[抽|井]', rule=is_switch('genshin'), priority=5, block=True)
genshin_reset = on_keyword({'重置原神抽卡'}, priority=1, block=True) genshin_reset = on_keyword({'重置原神抽卡'}, priority=1, block=True)
genshin_update = on_keyword({'更新原神信息'}, permission=SUPERUSER, priority=1, block=True) genshin_update = on_keyword({'更新原神信息'}, permission=SUPERUSER, priority=1, block=True)
pretty = on_regex('.*?马娘卡?[1-9|一][0-9]{0,2}[抽|井]', priority=5, 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_update = on_keyword({'更新马娘信息', '更新赛马娘信息'}, permission=SUPERUSER, 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('.*?(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)
test = on_keyword({'test'}, permission=SUPERUSER, priority=1, block=True)
@test.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_pcr_info()
@prts.handle() @prts.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
@ -30,22 +49,13 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
num = 300 num = 300
else: else:
rmsg = re.search(r'.*?方舟(.*)抽', msg) rmsg = re.search(r'.*?方舟(.*)抽', msg)
if rmsg and is_number(rmsg.group(1)): if rmsg:
try: num, flag = check_num(rmsg.group(1), 300)
num = int(rmsg.group(1)) if not flag:
except ValueError: await prts.finish(num, at_sender=True)
await prts.finish('必!须!是!数!字!', at_sender=True)
if num > 300:
await prts.finish('一井都满不足不了你嘛!快爬开!', at_sender=True)
if num < 1:
await prts.finish('虚空抽卡???', at_sender=True)
else: else:
return return
# print(num) await prts.send(await prts_draw(int(num)), at_sender=True)
await prts.send(await prts_draw(num), at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})"
f" 方舟{num}")
@prts_reload.handle() @prts_reload.handle()
@ -61,21 +71,13 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
num = 180 num = 180
else: else:
rmsg = re.search(r'.*?原神(.*)抽', msg) rmsg = re.search(r'.*?原神(.*)抽', msg)
if rmsg and is_number(rmsg.group(1)): if rmsg:
try: num, flag = check_num(rmsg.group(1), 180)
num = int(rmsg.group(1)) if not flag:
except ValueError: await genshin.finish(num, at_sender=True)
await genshin.finish('必!须!是!数!字!', at_sender=True)
if num > 300:
await genshin.finish('一井都满不足不了你嘛!快爬开!', at_sender=True)
if num < 1:
await genshin.finish('虚空抽卡???', at_sender=True)
else: else:
return return
await genshin.send(await genshin_draw(event.user_id, num), at_sender=True) await genshin.send(await genshin_draw(event.user_id, int(num)), at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})"
f" 原神{num}")
@genshin_reset.handle() @genshin_reset.handle()
@ -87,7 +89,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
@pretty.handle() @pretty.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip() msg = str(event.get_message()).strip()
if msg in ['赛马娘一井', '赛马娘1井', '马娘一井', '马娘1井', '赛马娘卡一井', '赛马娘卡1井', '马娘卡一井', '马娘卡1井']: if msg.find('1井') != -1 or msg.find('一井') != -1:
num = 200 num = 200
if msg.find("") == -1: if msg.find("") == -1:
pool_name = 'horse' pool_name = 'horse'
@ -102,21 +104,51 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
pool_name = 'card' pool_name = 'card'
else: else:
pool_name = 'horse' pool_name = 'horse'
if is_number(num): num, flag = check_num(num, 200)
try: if not flag:
num = int(num) await pretty.finish(num, at_sender=True)
except ValueError:
await genshin.finish('必!须!是!数!字!', at_sender=True)
if num > 200:
await genshin.finish('一井都满不足不了你嘛!快爬开!', at_sender=True)
if num < 1:
await genshin.finish('虚空抽卡???', at_sender=True)
else: else:
return return
await pretty.send(await pretty_draw(num, pool_name), at_sender=True) 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 event.message_type != 'private' else 'private'})"
f" 赛马娘{num}") @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:
num = 300
if msg.find('武器') != -1:
pool_name = 'arms'
else:
rmsg = re.search(r'.*?坎公骑冠剑(.*)抽', msg)
if rmsg:
num = rmsg.group(1)
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)
@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:
num = 300
else:
rmsg = re.search(r'.*?(pcr|公主连结)(.*)[抽|井]', msg)
if rmsg:
num, flag = check_num(rmsg.group(2), 300)
if not flag:
await pcr.finish(num, at_sender=True)
else:
return
await pcr.send(await pcr_draw(int(num)), at_sender=True)
@prts_update.handle() @prts_update.handle()
@ -138,6 +170,18 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
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('更新完成!')
@pcr_update.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
await update_pcr_info()
await genshin_update.finish('更新完成!')
# 更新资源 # 更新资源
@scheduler.scheduled_job( @scheduler.scheduled_job(
'cron', 'cron',
@ -146,20 +190,30 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
) )
async def _(): async def _():
try: try:
if PRTS_FLAG:
await update_prts_info() await update_prts_info()
logger.info('自动更新明日方舟信息')
except Exception as e: except Exception as e:
logger.error(f'自动更新明日方舟信息出错 e:{e}') logger.error(f'draw_card: 更新 明日方舟 失败 e{e}')
try: try:
if GENSHIN_FLAG:
await update_genshin_info() await update_genshin_info()
logger.info('自动更新原神信息')
except Exception as e: except Exception as e:
logger.error(f'自动更新原神信息出错 e:{e}') logger.error(f'draw_card: 更新 原神 失败 e{e}')
try: try:
if PRETTY_FLAG:
await update_pretty_info() await update_pretty_info()
logger.info('自动更新赛马娘信息')
except Exception as e: except Exception as e:
logger.error(f'自动更新赛马娘信息出错 e:{e}') logger.error(f'draw_card: 更新 赛马娘 失败 e{e}')
try:
if GUARDIAN_FLAG:
await update_guardian_info()
except Exception as e:
logger.error(f'draw_card: 更新 坎公骑冠剑 失败 e{e}')
try:
if PCR_FLAG:
await update_pcr_info()
except Exception as e:
logger.error(f'draw_card: 更新 公主连结 失败 e{e}')
# 每天四点重载up卡池 # 每天四点重载up卡池
@ -169,6 +223,6 @@ async def _():
minute=1, minute=1,
) )
async def _(): async def _():
if PRTS_FLAG:
await reload_pool() await reload_pool()
logger.info(f'draw_card: 04: 01 重载方舟卡池')

View File

@ -2,16 +2,17 @@ import aiohttp
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
import re import re
from datetime import datetime from datetime import datetime
from .config import DRAW_PATH
from util.utils import get_local_proxy
from pathlib import Path from pathlib import Path
from configs.path_config import DRAW_PATH
from util.user_agent import get_user_agent
try: try:
import ujson as json import ujson as json
except ModuleNotFoundError: except ModuleNotFoundError:
import json import json
up_char_file = Path(DRAW_PATH) / "draw_card_up" / "prts_up_char.json" headers = {'User-Agent': '"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)"'}
up_char_file = Path(DRAW_PATH + "/draw_card_up/prts_up_char.json")
prts_url = "https://wiki.biligame.com/arknights/%E6%96%B0%E9%97%BB%E5%85%AC%E5%91%8A" prts_url = "https://wiki.biligame.com/arknights/%E6%96%B0%E9%97%BB%E5%85%AC%E5%91%8A"
@ -29,7 +30,7 @@ class PrtsAnnouncement:
@staticmethod @staticmethod
async def get_announcement_text(): async def get_announcement_text():
async with aiohttp.ClientSession(headers=get_user_agent()) as session: async with aiohttp.ClientSession(headers=headers) as session:
async with session.get(prts_url, timeout=7) as res: async with session.get(prts_url, timeout=7) as res:
soup = BeautifulSoup(await res.text(), 'lxml') soup = BeautifulSoup(await res.text(), 'lxml')
trs = soup.find('table').find('tbody').find_all('tr') trs = soup.find('table').find('tbody').find_all('tr')
@ -38,7 +39,7 @@ class PrtsAnnouncement:
if a.text.find('寻访') != -1: if a.text.find('寻访') != -1:
url = a.get('href') url = a.get('href')
break break
async with session.get(f'https://wiki.biligame.com/{url}', timeout=7) as res: async with session.get(f'https://wiki.biligame.com/{url}', proxy=get_local_proxy(), timeout=7) as res:
return await res.text(), a.text[:-4] return await res.text(), a.text[:-4]
@staticmethod @staticmethod

View File

@ -1,10 +1,23 @@
import nonebot import nonebot
from pathlib import Path from pathlib import Path
from configs.path_config import DRAW_PATH
try: try:
import ujson as json import ujson as json
except ModuleNotFoundError: except ModuleNotFoundError:
import json import json
DRAW_PATH = DRAW_PATH
_draw_config = Path(rf"{DRAW_PATH}/draw_card_config/draw_card_config.json")
# 开关
PRTS_FLAG = False if str(nonebot.get_driver().config.prts_flag).lower() == 'false' else True
GENSHIN_FLAG = False if str(nonebot.get_driver().config.genshin_flag).lower() == 'false' else True
PRETTY_FLAG = False if str(nonebot.get_driver().config.pretty_flag).lower() == 'false' else True
GUARDIAN_FLAG = False if str(nonebot.get_driver().config.guardian_flag).lower() == 'false' else True
PCR_FLAG = False if str(nonebot.get_driver().config.PCR_flag).lower() == 'false' else True
# 方舟概率 # 方舟概率
PRTS_SIX_P = 0.02 PRTS_SIX_P = 0.02
PRTS_FIVE_P = 0.08 PRTS_FIVE_P = 0.08
@ -15,88 +28,206 @@ PRTS_THREE_P = 0.42
GENSHIN_FIVE_P = 0.006 GENSHIN_FIVE_P = 0.006
GENSHIN_FOUR_P = 0.051 GENSHIN_FOUR_P = 0.051
GENSHIN_THREE_P = 0.43 GENSHIN_THREE_P = 0.43
GENSHIN_G_FOUR_P = 0.13 # 保底概率
GENSHIN_G_FIVE_P = 0.016 GENSHIN_G_FIVE_P = 0.016
GENSHIN_G_FOUR_P = 0.13
# 72抽后增加的概率
I72_ADD = 0.0585 I72_ADD = 0.0585
# 赛马娘概率 # 赛马娘概率
PRETTY_THREE = 0.03 PRETTY_THREE_P = 0.03
PRETTY_TWO = 0.18 PRETTY_TWO_P = 0.18
PRETTY_ONE = 0.79 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
# 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
path_dict = { path_dict = {
'genshin': '原神', 'genshin': '原神',
'prts': '明日方舟', 'prts': '明日方舟',
'pretty': '赛马娘', 'pretty': '赛马娘',
'guardian': '坎公骑冠剑',
'pcr': '公主连结',
} }
_draw_config = Path() / "data" / "draw_card" / "draw_card_config" / "draw_card_config.json"
driver: nonebot.Driver = nonebot.get_driver() driver: nonebot.Driver = nonebot.get_driver()
config_default_data = {
@driver.on_startup
def check_config():
global PRTS_SIX_P, PRTS_FOUR_P, PRTS_FIVE_P, PRTS_THREE_P, GENSHIN_G_FIVE_P, \
GENSHIN_G_FOUR_P, GENSHIN_FOUR_P, GENSHIN_FIVE_P, I72_ADD, path_dict, PRETTY_THREE, \
PRETTY_ONE, PRETTY_TWO, GENSHIN_THREE_P
if _draw_config.exists():
data = json.load(open(_draw_config, 'r', encoding='utf8'))
PRTS_SIX_P = float(data['prts']['six'])
PRTS_FIVE_P = float(data['prts']['five'])
PRTS_FOUR_P = float(data['prts']['four'])
PRTS_THREE_P = float(data['prts']['three'])
GENSHIN_FIVE_P = float(data['genshin']['five_char'])
GENSHIN_FOUR_P = float(data['genshin']['four_char'])
GENSHIN_THREE_P = float(data['genshin']['three_char'])
GENSHIN_G_FIVE_P = float(data['genshin']['five_weapon'])
GENSHIN_G_FOUR_P = float(data['genshin']['four_weapon'])
I72_ADD = float(data['genshin']['72_add'])
PRETTY_THREE = float(data['pretty']['three'])
PRETTY_TWO = float(data['pretty']['two'])
PRETTY_ONE = float(data['pretty']['one'])
path_dict = data['path_dict']
else:
_draw_config.parent.mkdir(parents=True, exist_ok=True)
config_dict = {
'path_dict': { 'path_dict': {
'genshin': '原神', 'genshin': '原神',
'prts': '明日方舟', 'prts': '明日方舟',
'pretty': '赛马娘', 'pretty': '赛马娘',
'guardian': '坎公骑冠剑',
'PCR': '公主连结',
}, },
'prts': { 'prts': {
'six': 0.02, 'PRTS_SIX_P': 0.02,
'five': 0.08, 'PRTS_FIVE_P': 0.08,
'four': 0.48, 'PRTS_FOUR_P': 0.48,
'three': 0.42, 'PRTS_THREE_P': 0.42,
}, },
'genshin': { 'genshin': {
'five_char': 0.006, 'GENSHIN_FIVE_P': 0.006,
'four_char': 0.051, 'GENSHIN_FOUR_P': 0.051,
'three_char': 0.43, 'GENSHIN_THREE_P': 0.43,
'five_weapon': 0.13, 'GENSHIN_G_FIVE_P': 0.13,
'four_weapon': 0.016, 'GENSHIN_G_FOUR_P': 0.016,
'72_add': 0.0585, 'I72_ADD': 0.0585,
}, },
'pretty': { 'pretty': {
'three': 0.03, 'PRETTY_THREE_P': 0.03,
'two': 0.18, 'PRETTY_TWO_P': 0.18,
'one': 0.79, 'PRETTY_ONE_P': 0.79,
} },
}
json.dump(config_dict, open(_draw_config, 'w', encoding='utf8'), indent=4, ensure_ascii=False) '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,
},
}
@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
_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:
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']
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']
json.dump(data, open(_draw_config, 'w', encoding='utf8'), indent=4, ensure_ascii=False)

View File

@ -1,14 +1,14 @@
import os import os
from util.init_result import image
import nonebot import nonebot
import random import random
from .update_game_info import update_info from .update_game_info import update_info
from .util import generate_img, init_star_rst, BaseData, set_list from .util import generate_img, init_star_rst, BaseData, set_list, get_star
from .config import GENSHIN_FIVE_P, GENSHIN_FOUR_P, GENSHIN_G_FIVE_P, GENSHIN_THREE_P, I72_ADD 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 dataclasses import dataclass from dataclasses import dataclass
from .init_card_pool import init_game_pool from .init_card_pool import init_game_pool
from configs.path_config import DRAW_PATH
from util.init_result import image
try: try:
import ujson as json import ujson as json
except ModuleNotFoundError: except ModuleNotFoundError:
@ -21,7 +21,7 @@ genshin_count = {}
genshin_pl_count = {} genshin_pl_count = {}
ALL_CHAR = [] ALL_CHAR = []
ALL_ARM = [] ALL_ARMS = []
@dataclass @dataclass
@ -32,28 +32,28 @@ class GenshinChar(BaseData):
async def genshin_draw(user_id: int, count: int): async def genshin_draw(user_id: int, count: int):
# 0 1 2 # 0 1 2
cnlist = ['★★★★★', '★★★★', '★★★'] cnlist = ['★★★★★', '★★★★', '★★★']
genshin_list, five_list, five_olist, five_dict, star_list = _format_card_information(count, user_id) char_list, five_list, five_index_list, char_dict, star_list = _format_card_information(count, user_id)
rst = init_star_rst(star_list, cnlist, five_list, five_olist) rst = init_star_rst(star_list, cnlist, five_list, five_index_list)
print(five_list)
temp = '' temp = ''
if count > 90: if count > 90:
genshin_list = set_list(genshin_list) char_list = set_list(char_list)
return image(b64=await generate_img(genshin_list, 'genshin', star_list)) + '\n' + rst[:-1] + \ return image(b64=await generate_img(char_list, 'genshin', star_list)) + '\n' + rst[:-1] + \
temp[:-1] + f'\n距离保底发还剩 {90 - genshin_count[user_id] if genshin_count.get(user_id) else "^"}' \ temp[:-1] + f'\n距离保底发还剩 {90 - genshin_count[user_id] if genshin_count.get(user_id) else "^"}' \
+ "\n【五星0.6%四星5.1%\n第72抽开始五星概率每抽加0.585%" + "\n【五星0.6%四星5.1%\n第72抽开始五星概率每抽加0.585%"
async def update_genshin_info(): async def update_genshin_info():
global ALL_CHAR, ALL_ARM global ALL_CHAR, ALL_ARMS
url = 'https://wiki.biligame.com/ys/角色筛选' url = 'https://wiki.biligame.com/ys/角色筛选'
data, code = await update_info(url, 'genshin') data, code = await update_info(url, 'genshin')
if code == 200: if code == 200:
ALL_CHAR = init_game_pool('genshin', data, GenshinChar) ALL_CHAR = init_game_pool('genshin', data, GenshinChar)
url = 'https://wiki.biligame.com/ys/武器图鉴' url = 'https://wiki.biligame.com/ys/武器图鉴'
data, code = await update_info(url, 'genshin_arm', ['头像', '名称', '类型', '稀有度.alt', '初始基础属性1', data, code = await update_info(url, 'genshin_arms', ['头像', '名称', '类型', '稀有度.alt',
'初始基础属性2', '攻击力MAX', '副属性MAX', '技能']) '获取途径', '初始基础属性1', '初始基础属性2',
'攻击力MAX', '副属性MAX', '技能'])
if code == 200: if code == 200:
ALL_ARM = init_game_pool('genshin', data, GenshinChar) ALL_ARMS = init_game_pool('genshin', data, GenshinChar)
# asyncio.get_event_loop().run_until_complete(update_genshin_info()) # asyncio.get_event_loop().run_until_complete(update_genshin_info())
@ -61,39 +61,34 @@ async def update_genshin_info():
@driver.on_startup @driver.on_startup
async def init_data(): async def init_data():
global ALL_CHAR, ALL_ARM global ALL_CHAR, ALL_ARMS
if not os.path.exists(DRAW_PATH + '/draw_card_config/genshin.json') or \ if GENSHIN_FLAG:
not os.path.exists(DRAW_PATH + '/draw_card_config/genshin_arm.json'): if not os.path.exists(DRAW_PATH + 'genshin.json') or not os.path.exists(DRAW_PATH + 'genshin_arms.json'):
await update_genshin_info() await update_genshin_info()
else: else:
with open(DRAW_PATH + '/draw_card_config/genshin.json', 'r', encoding='utf8') as f: with open(DRAW_PATH + 'genshin.json', 'r', encoding='utf8') as f:
genshin_dict = json.load(f) genshin_dict = json.load(f)
with open(DRAW_PATH + '/draw_card_config/genshin_arm.json', 'r', encoding='utf8') as f: with open(DRAW_PATH + 'genshin_arms.json', 'r', encoding='utf8') as f:
genshin_arm_dict = json.load(f) genshin_ARMS_dict = json.load(f)
ALL_CHAR = init_game_pool('genshin', genshin_dict, GenshinChar) ALL_CHAR = init_game_pool('genshin', genshin_dict, GenshinChar)
ALL_ARM = init_game_pool('genshin', genshin_arm_dict, GenshinChar) ALL_ARMS = init_game_pool('genshin', genshin_ARMS_dict, GenshinChar)
# 抽取卡池 # 抽取卡池
def _get_genshin_card(mode: int = 1, add: float = 0.0): def _get_genshin_card(mode: int = 1, add: float = 0.0):
global ALL_ARM, ALL_CHAR global ALL_ARMS, ALL_CHAR
if mode == 1: if mode == 1:
star = random.sample([5, 4, 3], star = get_star([5, 4, 3], [GENSHIN_FIVE_P + add, GENSHIN_FOUR_P, GENSHIN_THREE_P])
counts=[int(GENSHIN_FIVE_P * 1000) + int(add * 1000), int(GENSHIN_FOUR_P * 1000),
int(GENSHIN_THREE_P * 1000)],
k=1)[0]
elif mode == 2: elif mode == 2:
star = random.sample([5, 4], star = get_star([5, 4], [GENSHIN_G_FIVE_P + add, GENSHIN_G_FOUR_P])
counts=[int(GENSHIN_G_FIVE_P * 1000) + int(add * 1000), int(GENSHIN_FOUR_P * 1000)],
k=1)[0]
else: else:
star = 5 star = 5
chars = [x for x in (ALL_ARM if random.random() < 0.5 or star == 3 else ALL_CHAR) if x.star == star] chars = [x for x in (ALL_ARMS if random.random() < 0.5 or star == 3 else ALL_CHAR) if x.star == star]
return random.choice(chars), abs(star - 5) return random.choice(chars), abs(star - 5)
def _format_card_information(_count: int, user_id): def _format_card_information(_count: int, user_id):
genshin_list = [] char_list = []
star_list = [0, 0, 0] star_list = [0, 0, 0]
five_index_list = [] five_index_list = []
five_list = [] five_list = []
@ -137,11 +132,11 @@ def _format_card_information(_count: int, user_id):
five_dict[char.name] += 1 five_dict[char.name] += 1
except KeyError: except KeyError:
five_dict[char.name] = 1 five_dict[char.name] = 1
genshin_list.append(char) char_list.append(char)
if _count <= 90: if _count <= 90:
genshin_count[user_id] = f_count genshin_count[user_id] = f_count
genshin_pl_count[user_id] = count genshin_pl_count[user_id] = count
return genshin_list, five_list, five_index_list, five_dict, star_list return char_list, five_list, five_index_list, five_dict, star_list
def reset_count(user_id: int): def reset_count(user_id: int):

View File

@ -0,0 +1,118 @@
import os
import nonebot
from nonebot.adapters.cqhttp import MessageSegment
from util.init_result import image
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
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 dataclasses import dataclass
from .init_card_pool import init_game_pool
try:
import ujson as json
except ModuleNotFoundError:
import json
driver: nonebot.Driver = nonebot.get_driver()
ALL_CHAR = []
ALL_ARMS = []
@dataclass
class GuardianChar(BaseData):
pass
@dataclass
class GuardianArms(BaseData):
pass
async def guardian_draw(count: int, pool_name):
if pool_name == 'arms':
cnlist = ['★★★★★', '★★★★', '★★★', '★★']
star_list = [0, 0, 0, 0]
else:
cnlist = ['★★★', '★★', '']
star_list = [0, 0, 0]
obj_list, obj_dict, max_list, star_list, max_index_list = format_card_information(count, star_list,
_get_guardian_card, pool_name)
rst = init_star_rst(star_list, cnlist, max_list, max_index_list)
if count > 90:
obj_list = set_list(obj_list)
return image(b64=await generate_img(obj_list, 'guardian', star_list)) \
+ '\n' + rst[:-1] + '\n' + max_card(obj_dict)
async def update_guardian_info():
global ALL_CHAR, ALL_ARMS
url = 'https://wiki.biligame.com/gt/英雄筛选表'
data, code = await update_info(url, 'guardian')
if code == 200:
ALL_CHAR = init_game_pool('guardian', data, GuardianChar)
url = 'https://wiki.biligame.com/gt/武器'
tmp, code_1 = await update_info(url, 'guardian_arms')
url = 'https://wiki.biligame.com/gt/盾牌'
data, code_2 = await update_info(url, 'guardian_arms')
if code_1 == 200 and code_2 == 200:
data.update(tmp)
ALL_ARMS = init_game_pool('guardian_arms', data, GuardianArms)
@driver.on_startup
async def init_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'):
await update_guardian_info()
else:
with open(DRAW_PATH + 'guardian.json', 'r', encoding='utf8') as f:
guardian_char_dict = json.load(f)
with open(DRAW_PATH + 'guardian_arms.json', '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)
# 抽取卡池
def _get_guardian_card(itype):
global ALL_CHAR, ALL_ARMS
if itype != 'arms':
star = get_star([3, 2, 1], [GUARDIAN_THREE_CHAR_P, GUARDIAN_TWO_CHAR_P, GUARDIAN_ONE_CHAR_P])
chars = [x for x in ALL_CHAR if x.star == star]
return random.choice(chars), abs(star - 3)
else:
star = get_star([5, 4, 3, 2], [GUARDIAN_FIVE_ARMS_P, GUARDIAN_FOUR_ARMS_P,
GUARDIAN_THREE_ARMS_P, GUARDIAN_TWO_ARMS_P])
arms = [x for x in ALL_ARMS if x.star == star]
return random.choice(arms), abs(star - 5)
# 整理数据
def _format_card_information(count: int, pool_name: str):
max_star_lst = []
max_index_lst = []
obj_list = []
obj_dict = {}
if pool_name == 'arms':
star_list = [0, 0, 0, 0]
else:
star_list = [0, 0, 0]
for i in range(count):
obj, code = _get_guardian_card(pool_name)
star_list[code] += 1
if code == 0:
max_star_lst.append(obj.name)
max_index_lst.append(i)
try:
obj_dict[obj.name] += 1
except KeyError:
obj_dict[obj.name] = 1
obj_list.append(obj)
return obj_list, obj_dict, max_star_lst, star_list, max_index_lst

View File

@ -14,6 +14,8 @@ def init_game_pool(game: str, data: dict, Operator: Any):
recruit_only = True recruit_only = True
if '活动获取' in data[key]['获取途径']: if '活动获取' in data[key]['获取途径']:
event_only = True event_only = True
if len(data[key]['获取途径']) == 1 and '凭证交易所' == data[key]['获取途径'][0]:
limited = True
if key.find('阿米娅') != -1: if key.find('阿米娅') != -1:
continue continue
tmp_lst.append(Operator(name=key, star=int(data[key]['星级']), tmp_lst.append(Operator(name=key, star=int(data[key]['星级']),
@ -29,5 +31,14 @@ def init_game_pool(game: str, data: dict, Operator: Any):
if game == 'pretty_card': if game == 'pretty_card':
for key in data.keys(): for key in data.keys():
tmp_lst.append(Operator(name=data[key]['中文名'], star=len(data[key]['稀有度']), limited=False)) tmp_lst.append(Operator(name=data[key]['中文名'], star=len(data[key]['稀有度']), limited=False))
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':
for key in data.keys():
limited = False
if key.find('') != -1:
limited = True
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=limited))
return tmp_lst return tmp_lst

View File

@ -0,0 +1,91 @@
import ujson as json
import os
from util.init_result import image
import nonebot
import random
from .update_game_info import update_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
from dataclasses import dataclass
from .init_card_pool import init_game_pool
driver: nonebot.Driver = nonebot.get_driver()
ALL_CHAR = []
@dataclass
class PcrChar(BaseData):
pass
async def pcr_draw(count: int):
# 0 1 2
cnlist = ['★★★', '★★', '']
char_list, three_list, three_index_list, char_dict, star_list = _format_card_information(count)
rst = init_star_rst(star_list, cnlist, three_list, three_index_list)
if count > 90:
char_list = set_list(char_list)
return image(b64=await generate_img(char_list, 'pcr', star_list)) \
+ '\n' + rst[:-1] + '\n' + max_card(char_dict)
async def update_pcr_info():
global ALL_CHAR
url = 'https://wiki.biligame.com/pcr/角色筛选表'
data, code = await update_info(url, 'pcr')
if code == 200:
ALL_CHAR = init_game_pool('pcr', data, PcrChar)
@driver.on_startup
async def init_data():
global ALL_CHAR
if PCR_FLAG:
if not os.path.exists(DRAW_PATH + 'pcr.json'):
await update_pcr_info()
else:
with open(DRAW_PATH + 'pcr.json', 'r', encoding='utf8') as f:
pcr_dict = json.load(f)
ALL_CHAR = init_game_pool('pcr', pcr_dict, PcrChar)
# 抽取卡池
def _get_pcr_card(mode: int = 1):
global ALL_CHAR
if mode == 2:
star = get_star([3, 2], [PCR_G_THREE_P, PCR_G_TWO_P])
else:
star = get_star([3, 2, 1], [PCR_THREE_P, PCR_TWO_P, PCR_ONE_P])
chars = [x for x in ALL_CHAR if x.star == star and not x.limited]
return random.choice(chars), abs(star - 3)
def _format_card_information(_count: int):
char_list = []
star_list = [0, 0, 0]
three_index_list = []
three_list = []
char_dict = {}
# 保底计算
count = 0
for i in range(_count):
count += 1
# 十连保底
if count == 10:
char, code = _get_pcr_card(2)
count = 0
else:
char, code = _get_pcr_card()
if code == 1:
count = 0
star_list[code] += 1
if code == 0:
three_list.append(char.name)
three_index_list.append(i)
try:
char_dict[char.name] += 1
except KeyError:
char_dict[char.name] = 1
char_list.append(char)
return char_list, three_list, three_index_list, char_dict, star_list

View File

@ -2,11 +2,11 @@
import os import os
import nonebot import nonebot
from util.init_result import image from util.init_result import image
from configs.path_config import DRAW_PATH
from .update_game_info import update_info from .update_game_info import update_info
from .util import download_img, init_star_rst, generate_img, max_card, BaseData, set_list from .util import download_img, init_star_rst, generate_img, max_card, BaseData, \
set_list, get_star, format_card_information
import random import random
from .config import PRETTY_THREE, PRETTY_TWO, PRETTY_ONE from .config import PRETTY_THREE_P, PRETTY_TWO_P, DRAW_PATH, PRETTY_ONE_P, PRETTY_FLAG
from dataclasses import dataclass from dataclasses import dataclass
from .init_card_pool import init_game_pool from .init_card_pool import init_game_pool
try: try:
@ -30,7 +30,9 @@ async def pretty_draw(count: int, pool_name):
cnlist = ['SSR', 'SR', 'R'] cnlist = ['SSR', 'SR', 'R']
else: else:
cnlist = ['★★★', '★★', ''] cnlist = ['★★★', '★★', '']
obj_list, obj_dict, three_list, star_list, three_olist = _format_card_information(count, pool_name) star_list = [0, 0, 0]
obj_list, obj_dict, three_list, star_list, three_olist = format_card_information(count, star_list,
_get_pretty_card, pool_name)
rst = init_star_rst(star_list, cnlist, three_list, three_olist) rst = init_star_rst(star_list, cnlist, three_list, three_olist)
if count > 90: if count > 90:
obj_list = set_list(obj_list) obj_list = set_list(obj_list)
@ -53,8 +55,8 @@ async def update_pretty_info():
@driver.on_startup @driver.on_startup
async def init_data(): async def init_data():
global ALL_CHAR, ALL_CARD global ALL_CHAR, ALL_CARD
if not os.path.exists(DRAW_PATH + '/draw_card_config/pretty.json') or\ if PRETTY_FLAG:
not os.path.exists(DRAW_PATH + '/draw_card_config/pretty_card.json'): if not os.path.exists(DRAW_PATH + 'pretty.json') or not os.path.exists(DRAW_PATH + 'pretty_card.json'):
await update_pretty_info() await update_pretty_info()
for icon_url in [ for icon_url in [
'https://patchwiki.biligame.com/images/umamusume/thumb/0/06/q23szwkbtd7pfkqrk3wcjlxxt9z595o.png' 'https://patchwiki.biligame.com/images/umamusume/thumb/0/06/q23szwkbtd7pfkqrk3wcjlxxt9z595o.png'
@ -65,9 +67,9 @@ async def init_data():
'/40px-R.png']: '/40px-R.png']:
await download_img(icon_url, 'pretty', icon_url.split('-')[-1][:-4]) await download_img(icon_url, 'pretty', icon_url.split('-')[-1][:-4])
else: else:
with open(DRAW_PATH + '/draw_card_config/pretty.json', 'r', encoding='utf8') as f: with open(DRAW_PATH + 'pretty.json', 'r', encoding='utf8') as f:
pretty_char_dict = json.load(f) pretty_char_dict = json.load(f)
with open(DRAW_PATH + '/draw_card_config/pretty_card.json', 'r', encoding='utf8') as f: with open(DRAW_PATH + 'pretty_card.json', 'r', encoding='utf8') as f:
pretty_card_dict = json.load(f) pretty_card_dict = json.load(f)
ALL_CHAR = init_game_pool('pretty', pretty_char_dict, PrettyChar) ALL_CHAR = init_game_pool('pretty', pretty_char_dict, PrettyChar)
ALL_CARD = init_game_pool('pretty_card', pretty_card_dict, PrettyChar) ALL_CARD = init_game_pool('pretty_card', pretty_card_dict, PrettyChar)
@ -76,30 +78,7 @@ async def init_data():
# 抽取卡池 # 抽取卡池
def _get_pretty_card(itype): def _get_pretty_card(itype):
global ALL_CHAR, ALL_CARD global ALL_CHAR, ALL_CARD
star = random.sample([3, 2, 1], star = get_star([3, 2, 1], [PRETTY_THREE_P, PRETTY_TWO_P, PRETTY_ONE_P])
counts=[int(PRETTY_THREE * 100), int(PRETTY_TWO * 100),
int(PRETTY_ONE * 100)],
k=1)[0]
chars = [x for x in (ALL_CARD if itype == 'card' else ALL_CHAR) if x.star == star] chars = [x for x in (ALL_CARD if itype == 'card' else ALL_CHAR) if x.star == star]
return random.choice(chars), abs(star - 3) return random.choice(chars), abs(star - 3)
# 整理数据
def _format_card_information(count: int, pool_name: str):
three_list = []
three_olist = []
obj_list = []
obj_dict = {}
star_list = [0, 0, 0]
for i in range(count):
obj, code = _get_pretty_card(pool_name)
star_list[code] += 1
if code == 0:
three_list.append(obj.name)
three_olist.append(i)
try:
obj_dict[obj.name] += 1
except KeyError:
obj_dict[obj.name] = 1
obj_list.append(obj)
return obj_list, obj_dict, three_list, star_list, three_olist

View File

@ -1,17 +1,15 @@
import os import os
from util.init_result import image
import nonebot import nonebot
import random import random
from .config import PRTS_FIVE_P, PRTS_FOUR_P, PRTS_SIX_P, PRTS_THREE_P from .config import PRTS_FIVE_P, PRTS_FOUR_P, PRTS_SIX_P, PRTS_THREE_P, DRAW_PATH, PRTS_FLAG
from .update_game_info import update_info from .update_game_info import update_info
from .util import generate_img, init_star_rst, max_card, BaseData, UpEvent, set_list from .util import generate_img, init_star_rst, max_card, BaseData, UpEvent, set_list, get_star, format_card_information
from .init_card_pool import init_game_pool from .init_card_pool import init_game_pool
from pathlib import Path from pathlib import Path
from .announcement import PrtsAnnouncement from .announcement import PrtsAnnouncement
from dataclasses import dataclass from dataclasses import dataclass
from util.init_result import image
from configs.path_config import DRAW_PATH
from services.log import logger
try: try:
import ujson as json import ujson as json
except ModuleNotFoundError: except ModuleNotFoundError:
@ -36,13 +34,15 @@ class Operator(BaseData):
async def prts_draw(count: int = 300): async def prts_draw(count: int = 300):
cnlist = ['★★★★★★', '★★★★★', '★★★★', '★★★'] cnlist = ['★★★★★★', '★★★★★', '★★★★', '★★★']
operator_list, operator_dict, six_list, star_list, six_olist = _format_card_information(count) star_list = [0, 0, 0, 0]
operator_list, operator_dict, six_list, star_list, six_index_list = format_card_information(count, star_list,
_get_operator_card)
up_list = [] up_list = []
if _CURRENT_POOL_TITLE: if _CURRENT_POOL_TITLE:
for x in UP_OPERATOR: for x in UP_OPERATOR:
for operator in x.operators: for operator in x.operators:
up_list.append(operator) up_list.append(operator)
rst = init_star_rst(star_list, cnlist, six_list, six_olist, up_list) rst = init_star_rst(star_list, cnlist, six_list, six_index_list, up_list)
if count > 90: if count > 90:
operator_list = set_list(operator_list) operator_list = set_list(operator_list)
pool_info = "当前up池: " if _CURRENT_POOL_TITLE else "" pool_info = "当前up池: " if _CURRENT_POOL_TITLE else ""
@ -63,22 +63,19 @@ async def update_prts_info():
@driver.on_startup @driver.on_startup
async def init_data(): async def init_data():
global prts_dict, ALL_OPERATOR global prts_dict, ALL_OPERATOR
if not os.path.exists(DRAW_PATH + '/draw_card_config/prts.json'): if PRTS_FLAG:
if not os.path.exists(DRAW_PATH + 'prts.json'):
await update_prts_info() await update_prts_info()
else: else:
with open(DRAW_PATH + '/draw_card_config/prts.json', 'r', encoding='utf8') as f: with open(DRAW_PATH + 'prts.json', 'r', encoding='utf8') as f:
prts_dict = json.load(f) prts_dict = json.load(f)
ALL_OPERATOR = init_game_pool('prts', prts_dict, Operator) ALL_OPERATOR = init_game_pool('prts', prts_dict, Operator)
await _init_up_char() await _init_up_char()
# print([x.operators for x in UP_OPERATOR if x.star == 5 and x.zoom > 1])
# 抽取干员 # 抽取干员
def _get_operator_card(): def _get_operator_card():
star = random.sample([6, 5, 4, 3], star = get_star([6, 5, 4, 3], [PRTS_SIX_P, PRTS_FIVE_P, PRTS_FOUR_P, PRTS_THREE_P])
counts=[int(PRTS_SIX_P * 100), int(PRTS_FIVE_P * 100),
int(PRTS_FOUR_P * 100), int(PRTS_THREE_P * 100)],
k=1)[0]
if _CURRENT_POOL_TITLE: if _CURRENT_POOL_TITLE:
zooms = [x.zoom for x in UP_OPERATOR if x.star == star] zooms = [x.zoom for x in UP_OPERATOR if x.star == star]
zoom = 0 zoom = 0
@ -108,39 +105,16 @@ def _get_operator_card():
else: else:
acquire_operator = random.choice([x for x in ALL_OPERATOR if x.star == star acquire_operator = random.choice([x for x in ALL_OPERATOR if x.star == star
and not any([x.limited, x.event_only, x.recruit_only])]) and not any([x.limited, x.event_only, x.recruit_only])])
# print(f'{acquire_operator}: {star}')
return acquire_operator, abs(star - 6) return acquire_operator, abs(star - 6)
# 整理抽卡数据
def _format_card_information(count: int):
operator_list = [] # 抽取的干员列表
operator_dict = {} # 抽取各干员次数
star_list = [0, 0, 0, 0] # 各个星级次数
six_list = [] # 六星干员列表
six_index_list = [] # 六星干员获取位置
for i in range(count):
operator, code = _get_operator_card()
star_list[code] += 1
if code == 0:
six_list.append(operator.name)
six_index_list.append(i)
try:
operator_dict[operator.name] += 1
except KeyError:
operator_dict[operator.name] = 1
operator_list.append(operator)
return operator_list, operator_dict, six_list, star_list, six_index_list
# 获取up干员和概率 # 获取up干员和概率
async def _init_up_char(): async def _init_up_char():
global up_char_dict, _CURRENT_POOL_TITLE global _CURRENT_POOL_TITLE
up_char_dict = await PrtsAnnouncement.update_up_char() up_char_dict = await PrtsAnnouncement.update_up_char()
# print(up_char_dict)
_CURRENT_POOL_TITLE = up_char_dict['title'] _CURRENT_POOL_TITLE = up_char_dict['title']
up_char_dict = up_char_dict['up_char'] up_char_dict = up_char_dict['up_char']
logger.info(f'成功获取明日方舟当前up信息...当前up池: {_CURRENT_POOL_TITLE}') print(f'成功获取明日方舟当前up信息...当前up池: {_CURRENT_POOL_TITLE}')
average_dict = {'6': {}, '5': {}, '4': {}} average_dict = {'6': {}, '5': {}, '4': {}}
for star in up_char_dict.keys(): for star in up_char_dict.keys():
for key in up_char_dict[star].keys(): for key in up_char_dict[star].keys():
@ -148,7 +122,6 @@ async def _init_up_char():
average_dict[star][up_char_dict[star][key]].append(key) average_dict[star][up_char_dict[star][key]].append(key)
else: else:
average_dict[star][up_char_dict[star][key]] = [key] average_dict[star][up_char_dict[star][key]] = [key]
up_char_dict = {'6': {}, '5': {}, '4': {}}
for star in average_dict.keys(): for star in average_dict.keys():
for str_zoom in average_dict[star].keys(): for str_zoom in average_dict[star].keys():
if str_zoom[0] == '': if str_zoom[0] == '':

36
plugins/draw_card/rule.py Normal file
View File

@ -0,0 +1,36 @@
from nonebot.rule import Rule
from nonebot.adapters.cqhttp import Bot, MessageEvent
from nonebot.typing import T_State
from .config import GENSHIN_FLAG, PRTS_FLAG, PRETTY_FLAG, GUARDIAN_FLAG, PCR_FLAG
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
else:
return False
return Rule(_is_switch)

View File

@ -1,40 +1,38 @@
#coding:utf-8 #coding:utf-8
import aiohttp import aiohttp
from configs.path_config import DRAW_PATH from .config import DRAW_PATH
from asyncio.exceptions import TimeoutError from asyncio.exceptions import TimeoutError
from services.log import logger
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from .util import download_img from .util import download_img
from urllib.parse import unquote from urllib.parse import unquote
import bs4 import bs4
from util.user_agent import get_user_agent
import re import re
from util.utils import get_local_proxy
try: try:
import ujson as json import ujson as json
except ModuleNotFoundError: except ModuleNotFoundError:
import json import json
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) -> 'dict, int':
try: try:
with open(DRAW_PATH + f'/draw_card_config/{game_name}.json', 'r', encoding='utf8') as f: with open(DRAW_PATH + f'{game_name}.json', 'r', encoding='utf8') as f:
data = json.load(f) data = json.load(f)
except (ValueError, FileNotFoundError): except (ValueError, FileNotFoundError):
data = {} data = {}
try: try:
async with aiohttp.ClientSession(headers=get_user_agent()) as session: async with aiohttp.ClientSession(headers=headers) as session:
async with session.get(url, timeout=7) as response: async with session.get(url, proxy=get_local_proxy(), timeout=7) as response:
soup = BeautifulSoup(await response.text(), 'lxml') soup = BeautifulSoup(await response.text(), 'lxml')
max_count = 0 _tbody = get_tbody(soup, game_name, url)
_tbody = None
for tbody in soup.find_all('tbody'):
if len(tbody.find_all('tr')) > max_count:
_tbody = tbody
max_count = len(tbody.find_all('tr'))
trs = _tbody.find_all('tr') trs = _tbody.find_all('tr')
att_dict = {'头像': 0, '名称': 1} att_dict, start_index, index = init_attr(game_name)
index = 2 if game_name == 'guardian':
for th in trs[0].find_all('th')[2:]: start_index = 1
for th in trs[0].find_all('th')[start_index:]:
text = th.text text = th.text
if text[-1] == '\n': if text[-1] == '\n':
text = text[:-1] text = text[:-1]
@ -42,44 +40,30 @@ async def update_info(url: str, game_name: str, info_list: list = None) -> 'dict
index += 1 index += 1
for tr in trs[1:]: for tr in trs[1:]:
member_dict = {} member_dict = {}
k_name = ''
tds = tr.find_all('td') tds = tr.find_all('td')
if not info_list: if not info_list:
info_list = att_dict.keys() info_list = att_dict.keys()
for key in info_list: for key in info_list:
attr = '' key, attr = parse_key(key, game_name)
if key.find('.') != -1:
key = key.split('.')
attr = key[-1]
key = key[0]
td = tds[att_dict[key]] td = tds[att_dict[key]]
last_tag = unquote(_find_last_tag(td, attr), 'utf-8') last_tag = unquote(_find_last_tag(td, attr, game_name), 'utf-8')
if game_name.find('pretty') == -1 and last_tag.find('http') == -1:
last_tag = last_tag.split('.')[0]
if key == '名称':
k_name = last_tag
member_dict[key] = last_tag member_dict[key] = last_tag
if game_name == 'pretty' and key == '初始星级': member_dict = intermediate_check(member_dict, key, game_name, td)
member_dict['初始星级'] = len(td.find_all('img'))
avatar_img = await _modify_avatar_url(session, game_name, member_dict["名称"]) avatar_img = await _modify_avatar_url(session, game_name, member_dict["名称"])
if avatar_img: member_dict['头像'] = avatar_img if avatar_img else member_dict['头像']
member_dict['头像'] = avatar_img name = replace_name(member_dict, game_name)
name = member_dict['名称']
if game_name == 'pretty_card':
name = member_dict['中文名']
await download_img(member_dict['头像'], game_name, name) await download_img(member_dict['头像'], game_name, name)
if k_name: data[name] = member_dict
data[k_name] = member_dict print(f'{name} is update...')
logger.info(f'{k_name} is update...')
data = await _last_check(data, game_name, session) data = await _last_check(data, game_name, session)
except TimeoutError: except TimeoutError:
return {}, 999 return {}, 999
with open(DRAW_PATH + f'/draw_card_config/{game_name}.json', 'w', encoding='utf8') as wf: with open(DRAW_PATH + f'{game_name}.json', 'w', encoding='utf8') as wf:
wf.write(json.dumps(data, ensure_ascii=False, indent=4)) wf.write(json.dumps(data, ensure_ascii=False, indent=4))
return data, 200 return data, 200
def _find_last_tag(element: bs4.element.Tag, attr: str) -> str: def _find_last_tag(element: bs4.element.Tag, attr: str, game_name: str) -> str:
last_tag = [] last_tag = []
for des in element.descendants: for des in element.descendants:
last_tag.append(des) last_tag.append(des)
@ -100,13 +84,17 @@ def _find_last_tag(element: bs4.element.Tag, attr: str) -> str:
last_tag = str(last_tag) last_tag = str(last_tag)
if str(last_tag) and str(last_tag)[-1] == '\n': if str(last_tag) and str(last_tag)[-1] == '\n':
last_tag = str(last_tag)[:-1] last_tag = str(last_tag)[:-1]
if game_name not in ['pretty', 'pretty_card', 'guardian'] and last_tag.find('http') == -1:
last_tag = last_tag.split('.')[0]
return last_tag return last_tag
# 获取大图(小图快爬) # 获取大图(小图快爬)
async def _modify_avatar_url(session: aiohttp.ClientSession, game_name: str, char_name: str): async def _modify_avatar_url(session: aiohttp.ClientSession, game_name: str, char_name: str):
if game_name == 'prts': if game_name == 'prts':
async with session.get(f'https://wiki.biligame.com/arknights/{char_name}', timeout=7) as res: async with session.get(f'https://wiki.biligame.com/arknights/{char_name}', proxy=get_local_proxy(), timeout=7) as res:
soup = BeautifulSoup(await res.text(), 'lxml') soup = BeautifulSoup(await res.text(), 'lxml')
try: try:
img_url = str(soup.find('img', {'class': 'img-bg'})['srcset']).split(' ')[-2] img_url = str(soup.find('img', {'class': 'img-bg'})['srcset']).split(' ')[-2]
@ -116,17 +104,31 @@ async def _modify_avatar_url(session: aiohttp.ClientSession, game_name: str, cha
if game_name == 'genshin': if game_name == 'genshin':
return None return None
if game_name == 'pretty_card': if game_name == 'pretty_card':
async with session.get(f'https://wiki.biligame.com/umamusume/{char_name}', timeout=7) as res: async with session.get(f'https://wiki.biligame.com/umamusume/{char_name}', proxy=get_local_proxy(), timeout=7) as res:
soup = BeautifulSoup(await res.text(), 'lxml') soup = BeautifulSoup(await res.text(), 'lxml')
img_url = soup.find('div', {'class': 'support_card-left'}).find('div').find('img').get('src') img_url = soup.find('div', {'class': 'support_card-left'}).find('div').find('img').get('src')
return img_url return img_url
if game_name == 'guardian':
# 未上传图片太多,换成像素图
# async with session.get(f'https://wiki.biligame.com/gt/{char_name}', timeout=7) as res:
# soup = BeautifulSoup(await res.text(), 'lxml')
# soup = soup.find('table', {'class': 'wikitable'}).find('tbody').find('tr')
# try:
# img_url = str(soup.find('img', {'class': 'img-kk'})['srcset']).split(' ')[-2]
# except KeyError:
# img_url = str(soup.find('img', {'class': 'img-kk'})['src'])
# except TypeError:
# print(f'{char_name} 图片还未上传,跳过...')
# img_url = ''
# return img_url
return None
# 数据最后处理(是否需要额外数据) # 数据最后处理(是否需要额外数据或处理数据
async def _last_check(data: dict, game_name: str, session: aiohttp.ClientSession): async def _last_check(data: dict, game_name: str, session: aiohttp.ClientSession):
if game_name == 'prts': if game_name == 'prts':
for key in data.keys(): for key in data.keys():
async with session.get(f'https://wiki.biligame.com/arknights/{key}', timeout=7) as res: async with session.get(f'https://wiki.biligame.com/arknights/{key}', proxy=get_local_proxy(), timeout=7) as res:
soup = BeautifulSoup(await res.text(), 'lxml') soup = BeautifulSoup(await res.text(), 'lxml')
obtain = str(soup.find('table', {'class': 'wikitable'}).find('tbody').find_all('td')[-1]) obtain = str(soup.find('table', {'class': 'wikitable'}).find('tbody').find_all('td')[-1])
obtain = re.search(r'<td.*?>([\s\S]*)</.*?', obtain).group(1) obtain = re.search(r'<td.*?>([\s\S]*)</.*?', obtain).group(1)
@ -135,8 +137,16 @@ async def _last_check(data: dict, game_name: str, session: aiohttp.ClientSession
obtain = obtain.split('<br/>') obtain = obtain.split('<br/>')
elif obtain.find('<br>'): elif obtain.find('<br>'):
obtain = obtain.split('<br>') obtain = obtain.split('<br>')
for i in range(len(obtain)):
if obtain[i].find('<a') != -1:
text = ''
for msg in obtain[i].split('</a>'):
r = re.search('>(.*)', msg)
if r:
text += r.group(1) + ' '
obtain[i] = obtain[i].split('<a')[0] + text[:-1] + obtain[i].split('</a>')[-1]
print(f'明日方舟获取额外信息....{obtain}')
data[key]['获取途径'] = obtain data[key]['获取途径'] = obtain
logger.info(f'明日方舟获取额外信息....{obtain}')
# if game_name == 'genshin': # if game_name == 'genshin':
# for key in data.keys(): # for key in data.keys():
# async with session.get(f'https://wiki.biligame.com/ys/{key}', timeout=7) as res: # async with session.get(f'https://wiki.biligame.com/ys/{key}', timeout=7) as res:
@ -149,16 +159,78 @@ async def _last_check(data: dict, game_name: str, session: aiohttp.ClientSession
if game_name == 'pretty': if game_name == 'pretty':
for keys in data.keys(): for keys in data.keys():
for key in data[keys].keys(): for key in data[keys].keys():
# print(f'key --> {data[keys][key]}')
r = re.search(r'.*?40px-(.*)图标.png', str(data[keys][key])) r = re.search(r'.*?40px-(.*)图标.png', str(data[keys][key]))
if r: if r:
data[keys][key] = r.group(1) data[keys][key] = r.group(1)
logger.info(f'赛马娘额外修改数据....{keys}[{key}]=> {r.group(1)}') print(f'赛马娘额外修改数据....{keys}[{key}]=> {r.group(1)}')
if game_name == 'guardian':
for keys in data.keys():
for key in data[keys].keys():
r = re.search(r'.*?-star_(.*).png', str(data[keys][key]))
if r:
data[keys][key] = r.group(1)
print(f'坎公骑士剑额外修改数据...{keys}[{key}] => {r.group(1)}')
return data return data
# 对抓取每行数据是否需要额外处理?
def intermediate_check(member_dict: dict, key: str, game_name: str, td: bs4.element.Tag):
if game_name == 'pretty':
if key == '初始星级':
member_dict['初始星级'] = len(td.find_all('img'))
if game_name == 'guardian':
if key == '头像':
member_dict['星级'] = str(td.find('span').find('img')['alt'])[-5]
try:
member_dict['头像'] = str(td.find('img')['srcset']).split(' ')[0]
except KeyError:
member_dict['头像'] = str(td.find('img')['src'])
return member_dict
# ul = soup.find('div', {'class': 'savelist_bot'}).find('ul') def init_attr(game_name: str):
att_dict = {'头像': 0, '名称': 1}
start_index = 2
index = 2
if game_name == 'guardian':
att_dict = {'头像': 0, '名称': 0}
start_index = 1
index = 1
return att_dict, start_index, index
def parse_key(key: str, game_name):
attr = ''
if game_name == 'genshin_arms':
if key.find('.') != -1:
key = key.split('.')
attr = key[-1]
key = key[0]
return key, attr
def replace_name(member_dict: dict, game_name: str):
name = member_dict['名称']
if game_name == 'pretty_card':
name = member_dict['中文名']
return name
# 拿到tbody不同游戏tbody可能不同
def get_tbody(soup: bs4.BeautifulSoup, game_name: str, url: str):
max_count = 0
_tbody = None
if game_name == 'guardian_arms':
if url[-2:] == '盾牌':
div = soup.find('div', {'class': 'resp-tabs-container'}).find_all('div', {'class': 'resp-tab-content'})[1]
_tbody = div.find('tbody')
else:
div = soup.find('div', {'class': 'resp-tabs-container'}).find_all('div', {'class': 'resp-tab-content'})[0]
_tbody = div.find('table', {'id': 'CardSelectTr'}).find('tbody')
else:
for tbody in soup.find_all('tbody'):
if len(tbody.find_all('tr')) > max_count:
_tbody = tbody
max_count = len(tbody.find_all('tr'))
return _tbody

View File

@ -6,12 +6,12 @@ from aiohttp.client_exceptions import InvalidURL
from typing import List, Union, Set from typing import List, Union, Set
import asyncio import asyncio
from pathlib import Path from pathlib import Path
from .config import path_dict from .config import path_dict, DRAW_PATH
import nonebot import nonebot
from util.utils import cn2py import pypinyin
from util.img_utils import CreateImg from util.img_utils import CreateImg
from util.user_agent import get_user_agent
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
import random
from dataclasses import dataclass from dataclasses import dataclass
from services.log import logger from services.log import logger
try: try:
@ -23,6 +23,9 @@ except ModuleNotFoundError:
driver: nonebot.Driver = nonebot.get_driver() driver: nonebot.Driver = nonebot.get_driver()
headers = {'User-Agent': '"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)"'}
@dataclass @dataclass
class BaseData: class BaseData:
name: str name: str
@ -40,21 +43,20 @@ class UpEvent:
async def download_img(url: str, path: str, name: str) -> bool: async def download_img(url: str, path: str, name: str) -> bool:
path = path.split('_')[0] path = path.split('_')[0]
codename = cn2py(name) codename = cn2py(name)
# if not _p.exists(): Path(IMAGE_PATH + f'/draw_card/{path}').mkdir(exist_ok=True, parents=True)
# _p.mkdir(parents=True, exist_ok=True)
if not os.path.exists(IMAGE_PATH + f'/draw_card/{path}/{codename}.png'): if not os.path.exists(IMAGE_PATH + f'/draw_card/{path}/{codename}.png'):
try: try:
async with aiohttp.ClientSession(headers=get_user_agent()) as session: async with aiohttp.ClientSession(headers=headers) as session:
async with session.get(url, timeout=7) as response: async with session.get(url, timeout=7) as response:
async with aiofiles.open(IMAGE_PATH + f'/draw_card/{path}/{codename}.png', 'wb') as f: async with aiofiles.open(IMAGE_PATH + f'/draw_card/{path}/{codename}.png', 'wb') as f:
await f.write(await response.read()) await f.write(await response.read())
logger.info(f'下载 {path_dict[path]} 图片成功,名称:{name}url{url}') logger.info(f'下载 {path_dict[path]} 图片成功,名称:{name}url{url}')
return True return True
except TimeoutError: except TimeoutError:
logger.info(f'下载 {path_dict[path]} 图片超时,名称:{name}url{url}') logger.warning(f'下载 {path_dict[path]} 图片超时,名称:{name}url{url}')
return False return False
except InvalidURL: except InvalidURL:
logger.info(f'下载 {path_dict[path]} 链接错误,名称:{name}url{url}') logger.warning(f'下载 {path_dict[path]} 链接错误,名称:{name}url{url}')
return False return False
else: else:
# logger.info(f'{path_dict[path]} 图片 {name} 已存在') # logger.info(f'{path_dict[path]} 图片 {name} 已存在')
@ -64,7 +66,7 @@ async def download_img(url: str, path: str, name: str) -> bool:
@driver.on_startup @driver.on_startup
def _check_dir(): def _check_dir():
for dir_name in path_dict.keys(): for dir_name in path_dict.keys():
_p = Path(IMAGE_PATH + f'/draw_card/' + dir_name) _p = Path(DRAW_PATH + f'/draw_card/' + dir_name)
if not _p.exists(): if not _p.exists():
_p.mkdir(parents=True, exist_ok=True) _p.mkdir(parents=True, exist_ok=True)
@ -117,13 +119,13 @@ def _pst(h: int, img_list: list, game_name: str, color_list: list):
else: else:
b = CreateImg(100, 100, background=img) b = CreateImg(100, 100, background=img)
except FileNotFoundError: except FileNotFoundError:
print(f'{img} not exists') logger.warning(f'{img} not exists')
b = CreateImg(100, 100, color='black') b = CreateImg(100, 100, color='black')
card_img.paste(b) card_img.paste(b)
return card_img return card_img
def init_star_rst(star_list: list, cnlist: list, max_star_list: list, max_star_olist: 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: if not up_list:
up_list = [] up_list = []
rst = '' rst = ''
@ -133,9 +135,9 @@ def init_star_rst(star_list: list, cnlist: list, max_star_list: list, max_star_o
rst += '\n' rst += '\n'
for i in range(len(max_star_list)): for i in range(len(max_star_list)):
if max_star_list[i] in up_list: if max_star_list[i] in up_list:
rst += f'{max_star_olist[i]+1} 抽获取UP {max_star_list[i]}\n' rst += f'{max_star_index_list[i]+1} 抽获取UP {max_star_list[i]}\n'
else: else:
rst += f'{max_star_olist[i]+1} 抽获取 {max_star_list[i]}\n' rst += f'{max_star_index_list[i]+1} 抽获取 {max_star_list[i]}\n'
return rst return rst
@ -150,6 +152,28 @@ def max_card(_dict: dict):
# return rst[:-1] # return rst[:-1]
def is_number(s) -> bool:
try:
float(s)
return True
except ValueError:
pass
try:
import unicodedata
unicodedata.numeric(s)
return True
except (TypeError, ValueError):
pass
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: def set_list(lst: List[BaseData]) -> list:
tmp = [] tmp = []
name_lst = [] name_lst = []
@ -159,3 +183,54 @@ def set_list(lst: List[BaseData]) -> list:
name_lst.append(x.name) name_lst.append(x.name)
return tmp return tmp
def get_star(star_lst: List[int], probability_lst: List[float]) -> int:
rand = random.random()
add = 0
tmp_lst = [(0, probability_lst[0])]
for i in range(1, len(probability_lst) - 1):
add += probability_lst[i - 1]
tmp_lst.append((tmp_lst[i - 1][1], probability_lst[i] + add))
tmp_lst.append((tmp_lst[-1][1], 1))
for i in range(len(tmp_lst)):
if tmp_lst[i][0] <= rand <= tmp_lst[i][1]:
return star_lst[i]
# 整理数据
def format_card_information(count: int, star_list: List[int], func, pool_name: str = ''):
max_star_lst = [] # 获取的最高星级角色列表
max_index_lst = [] # 获取最高星级角色的次数
obj_list = [] # 获取所有角色
obj_dict = {} # 获取角色次数字典
for i in range(count):
if pool_name:
obj, code = func(pool_name)
else:
obj, code = func()
star_list[code] += 1
if code == 0:
max_star_lst.append(obj.name)
max_index_lst.append(i)
try:
obj_dict[obj.name] += 1
except KeyError:
obj_dict[obj.name] = 1
obj_list.append(obj)
return obj_list, obj_dict, max_star_lst, star_list, max_index_lst
# 检测次数是否合法
def check_num(num: str, max_num: int) -> 'str, bool':
if is_number(num):
try:
num = int(num)
except ValueError:
return '必!须!是!数!字!', False
if num > max_num:
return '一井都满不足不了你嘛!快爬开!', False
if num < 1:
return '虚空抽卡???', False
else:
return str(num), True

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 0 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 0 B

Some files were not shown because too many files have changed in this diff Show More