新增米游社自动签到、修复bug

This commit is contained in:
CMHopeSunshine 2022-04-16 11:55:33 +08:00
parent a2e8dff95c
commit 9409fca9a8
9 changed files with 283 additions and 21 deletions

View File

@ -117,6 +117,7 @@ javascript:(function(){prompt(document.domain,document.cookie)})();
- 4.11 改用数据库进行数据存储,优化代码
- 4.14 新增每日天赋突破材料表查询
- 4.15 新增实时便签树脂提醒功能
- 4.16 新增米游社原神自动签到功能
## ToDo🕛
@ -125,7 +126,7 @@ javascript:(function(){prompt(document.domain,document.cookie)})();
- [ ] ocr圣遗物评分和角色面板记录
- [ ] 角色、武器和圣遗物wiki
- [ ] 派蒙AI闲聊
- [ ] 米游社自动签到
- [x] 米游社自动签到
- [x] 今日可刷材料
- [ ] 角色练度统计
- [ ] 派蒙戳一戳集卡

View File

@ -0,0 +1,12 @@
# 树脂提醒免打扰时间段,0和8即0点到8点不提醒
remind_time_start = 0
remind_time_end = 8
# 树脂提醒检查时间,8即为每八分钟检查一次
remind_check_time = 8
# 自动签到执行开始时间,0即为每天0点执行
auto_sign_time = 0
# 模拟抽卡的冷却时间,单位秒
gacha_cooldown = 30

View File

@ -7,6 +7,7 @@ from ..db_util import update_note_remind2, update_note_remind, get_note_remind,
from hoshino import get_bot, logger
from datetime import datetime, timedelta
from asyncio import sleep
from ..config import remind_time_start, remind_time_end, remind_check_time
help_msg='''
[ssbq/实时便签 (uid)]查询当前树脂洞天宝钱派遣状况等
@ -17,19 +18,26 @@ sv = Service('派蒙实时便签', bundle='派蒙', help_=help_msg)
@sv.on_prefix(('ssbq','实时便笺','实时便签'))
async def main(bot,ev):
if ev.message_type == 'group':
gid = str(ev.group_id)
else:
gid = str(ev.user_id)
uid, msg, user_id, use_cache = await get_uid_in_msg(ev)
find_remind_enable = re.search(r'(?P<action>开启提醒|关闭提醒|删除提醒)((?P<num>\d{1,3})|(?:.*))', msg)
find_remind_enable = re.search(r'(?P<action>开启提醒|关闭提醒|删除提醒)(.*)((?P<num>\d{1,3})|(?:.*))', msg)
if find_remind_enable:
if ev.message_type == 'guild':
await bot.send(ev, '实时便签提醒功能暂时无法在频道内使用哦')
return
if find_remind_enable.group('action') == '开启提醒':
if find_remind_enable.group('num'):
await update_note_remind2(user_id, uid, str(ev.group_id), True, find_remind_enable.group('num'))
await bot.send(ev, f'开启提醒成功,派蒙会在你的树脂达到{find_remind_enable.group("num")}在群里提醒你的', at_sender=True)
await update_note_remind2(user_id, uid, gid, 1, find_remind_enable.group('num'))
await bot.send(ev, f'开启提醒成功,派蒙会在你的树脂达到{find_remind_enable.group("num")}提醒你的', at_sender=True)
else:
await update_note_remind2(user_id, uid, str(ev.group_id), True)
await update_note_remind2(user_id, uid, gid, 1)
await bot.send(ev, '开启提醒成功', at_sender=True)
elif find_remind_enable.group('action') == '关闭提醒':
await bot.send(ev, '关闭提醒成功', at_sender=True)
await update_note_remind2(user_id, uid, str(ev.group_id), False)
await update_note_remind2(user_id, uid, gid, 0)
elif find_remind_enable.group('action') == '删除提醒':
await bot.send(ev, '删除提醒成功', at_sender=True)
await delete_note_remind(user_id, uid)
@ -44,11 +52,15 @@ async def main(bot,ev):
except Exception as e:
await bot.send(ev, f'派蒙出现了问题:{e}',at_sender=True)
@sv.scheduled_job('cron', minute='*/8')
@sv.scheduled_job('cron', minute=f'*/{remind_check_time}')
async def check_note():
now_time = datetime.now()
start_time = datetime(now_time.year, now_time.month, now_time.day, remind_time_start, 0, 0)
end_time = datetime(now_time.year, now_time.month, now_time.day, remind_time_end, 0, 0)
if start_time < now_time < end_time:
return
data = await get_note_remind()
if data:
now_time = datetime.now()
logger.info('---派蒙开始检查实时便签树脂提醒---')
for user_id, uid, count, remind_group, enable, last_remind_time, today_remind_count in data:
if last_remind_time:
@ -62,8 +74,12 @@ async def check_note():
if enable and ((today_remind_count and today_remind_count < 3) or not today_remind_count) and time_e:
now_data = await get_daily_note_data(uid)
if isinstance(now_data, str):
try:
await get_bot().send_group_msg(group_id=remind_group, message=f'[CQ:at,qq={user_id}]你的cookie失效了哦,派蒙没办法帮你检查树脂,先帮你删除了,请重新添加ck后再叫派蒙开启提醒')
try:
await delete_note_remind(user_id, uid)
if user_id == remind_group:
await get_bot().send_private_msg(user_id=user_id, message=f'[CQ:at,qq={user_id}]你的cookie失效了哦,派蒙没办法帮你检查树脂,请重新添加ck后再叫派蒙开启提醒')
else:
await get_bot().send_group_msg(group_id=remind_group, message=f'[CQ:at,qq={user_id}]你的cookie失效了哦,派蒙没办法帮你检查树脂,请重新添加ck后再叫派蒙开启提醒')
except Exception as e:
logger.error(f'---派蒙发送树脂提醒失败:{e}---')
else:
@ -76,10 +92,13 @@ async def check_note():
now_time_str = now_time.strftime('%Y%m%d %H:%M:%S')
try:
await update_note_remind(user_id, uid, count, remind_group, enable, now_time_str, today_remind_count)
await get_bot().send_group_msg(group_id=remind_group, message=f'[CQ:at,qq={user_id}]⚠️你的树脂已经达到了{now_data["data"]["current_resin"]}派蒙30分钟后还会帮你检查⚠')
if user_id == remind_group:
await get_bot().send_private_msg(user_id=user_id, message=f'[CQ:at,qq={user_id}]⚠️你的树脂已经达到了{now_data["data"]["current_resin"]},记得清理哦!⚠️')
else:
await get_bot().send_group_msg(group_id=remind_group, message=f'[CQ:at,qq={user_id}]⚠️你的树脂已经达到了{now_data["data"]["current_resin"]},记得清理哦!⚠️')
except Exception as e:
logger.error(f'---派蒙发送树脂提醒失败:{e}---')
await sleep(2)
await sleep(3)
@sv.scheduled_job('cron', hour='0')
async def delete_day_limit():

View File

@ -258,7 +258,7 @@ async def get_note_remind():
uid TEXT NOT NULL,
count INTEGER,
remind_group TEXT,
enable bool,
enable boolean,
last_remind_time datetime,
today_remind_count INTEGER,
PRIMARY KEY (user_id, uid)
@ -317,7 +317,7 @@ async def update_day_remind_count():
uid TEXT NOT NULL,
count INTEGER,
remind_group TEXT,
enable bool,
enable boolean,
last_remind_time datetime,
today_remind_count INTEGER,
PRIMARY KEY (user_id, uid)
@ -336,7 +336,7 @@ async def delete_note_remind(user_id, uid):
uid TEXT NOT NULL,
count INTEGER,
remind_group TEXT,
enable bool,
enable boolean,
last_remind_time datetime,
today_remind_count INTEGER,
PRIMARY KEY (user_id, uid)
@ -345,6 +345,48 @@ async def delete_note_remind(user_id, uid):
conn.commit()
conn.close()
async def get_auto_sign():
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
cursor.execute('''CREATE TABLE IF NOT EXISTS bbs_sign
(
user_id TEXT NOT NULL,
uid TEXT NOT NULL,
group_id TEXT,
PRIMARY KEY (user_id, uid)
);''')
cursor.execute('SELECT * FROM bbs_sign;')
res = cursor.fetchall()
conn.close()
return res
async def add_auto_sign(user_id, uid, group_id):
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
cursor.execute('''CREATE TABLE IF NOT EXISTS bbs_sign
(
user_id TEXT NOT NULL,
uid TEXT NOT NULL,
group_id TEXT,
PRIMARY KEY (user_id, uid)
);''')
cursor.execute('REPLACE INTO bbs_sign VALUES (?, ?, ?);', (user_id, uid, group_id))
conn.commit()
conn.close()
async def delete_auto_sign(user_id, uid):
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
cursor.execute('''CREATE TABLE IF NOT EXISTS bbs_sign
(
user_id TEXT NOT NULL,
uid TEXT NOT NULL,
group_id TEXT,
PRIMARY KEY (user_id, uid)
);''')
cursor.execute('DELETE FROM bbs_sign WHERE user_id=? AND uid=?;', (user_id, uid))
conn.commit()
conn.close()
init_db()

View File

@ -5,8 +5,9 @@ from hoshino.util import PriFreqLimiter
from ..util import Dict
from .gacha_role import *
from .gacha_wish import more_ten
from ..config import gacha_cooldown
lmt = PriFreqLimiter(30)
lmt = PriFreqLimiter(gacha_cooldown)
help_msg='''
1.[抽n十连xx池]抽n次xx池的十连最多同时5次
*池子和官方同步有角色1|角色2|武器|常驻默认为角色1
@ -52,7 +53,7 @@ async def gacha(bot, ev):
if not lmt.check(gid,uid):
await bot.finish(ev, f'模拟抽卡冷却中(剩余{int(lmt.left_time(gid,uid)) + 1}秒)', at_sender=True)
return
lmt.start_cd(gid, uid, 30)
lmt.start_cd(gid, uid, gacha_cooldown)
if num >= 3:
await bot.send(ev, '抽卡图正在生成中,请稍候')
if isinstance(gacha_type,int):

View File

@ -1,5 +1,5 @@
from hoshino import aiorequests
from .util import get_headers, cache, get_use_cookie, get_own_cookie, check_retcode
from .util import get_headers, get_sign_headers, cache, get_use_cookie, get_own_cookie, check_retcode
from .db_util import update_cookie_cache
import datetime
import re
@ -37,7 +37,11 @@ async def get_daily_note_data(uid):
"role_id": uid
}
res = await aiorequests.get(url=url, headers=headers, params=params)
return await res.json()
data = await res.json()
if await check_retcode(data, cookie, uid):
return data
else:
return f'你的uid{uid}的cookie已过期,需要重新绑定哦!'
@cache(ttl=datetime.timedelta(hours=1))
async def get_player_card_data(user_id, uid, use_cache=True):
@ -113,11 +117,15 @@ async def get_monthinfo_data(uid, month, use_cache=True):
data = await res.json()
if await check_retcode(data, cookie, uid):
return data
else:
return f'你的uid{uid}的cookie已过期,需要重新绑定哦!'
async def get_bind_game(cookie):
finduid = re.search(r'account_id=(\d{6,12})', cookie)
if not finduid:
return None
finduid = re.search(r'ltuid=(\d{6,12})', cookie)
if not finduid:
return None, None
uid = finduid.group(1)
url = 'https://api-takumi.mihoyo.com/game_record/card/wapi/getGameRecordCard'
headers = get_headers(q=f'uid={uid}', cookie = cookie)
@ -127,6 +135,69 @@ async def get_bind_game(cookie):
res = await aiorequests.get(url=url, headers=headers, params=params)
return (await res.json()), uid
# 获取今日签到信息
async def get_sign_info(uid):
server_id = "cn_qd01" if uid[0] == '5' else "cn_gf01"
url = 'https://api-takumi.mihoyo.com/event/bbs_sign_reward/info'
cookie = await get_own_cookie(uid, action='查询米游社签到')
if not cookie:
return f'你的uid{uid}没有绑定对应的cookie,使用ysb绑定才能用米游社签到哦!'
headers = {
'x-rpc-app_version': '2.11.1',
'x-rpc-client_type': '5',
'Origin': 'https://webstatic.mihoyo.com',
'Referer': 'https://webstatic.mihoyo.com/',
'Cookie': cookie['cookie'],
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS '
'X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1',
}
params = {
'act_id': 'e202009291139501',
'region': server_id,
'uid': uid
}
res = await aiorequests.get(url=url, headers=headers, params=params)
data = await res.json()
if await check_retcode(data, cookie, uid):
return data
# 执行签到操作
async def sign(uid):
server_id = "cn_qd01" if uid[0] == '5' else "cn_gf01"
url = 'https://api-takumi.mihoyo.com/event/bbs_sign_reward/sign'
cookie = await get_own_cookie(uid, action='米游社签到')
if not cookie:
return f'你的uid{uid}没有绑定对应的cookie,使用ysb绑定才能用米游社签到哦!'
headers = get_sign_headers(cookie['cookie'])
json_data = {
'act_id': 'e202009291139501',
'uid': uid,
'region': server_id
}
res = await aiorequests.post(url=url, headers=headers, json=json_data)
data = await res.json()
print(res)
if await check_retcode(data, cookie, uid):
return data
else:
return f'你的uid{uid}的cookie已过期,需要重新绑定哦!'
# 获取签到奖励列表
async def get_sign_list():
url = 'https://api-takumi.mihoyo.com/event/bbs_sign_reward/home'
headers = {
'x-rpc-app_version': '2.11.1',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 ('
'KHTML, like Gecko) miHoYoBBS/2.11.1',
'x-rpc-client_type': '5',
'Referer' : 'https://webstatic.mihoyo.com/'
}
params = {
'act_id': 'e202009291139501'
}
res = await aiorequests.get(url=url, headers=headers, params=params)
return await res.json()

View File

@ -1,6 +1,5 @@
import json,os,re,datetime
from hoshino import R,MessageSegment,logger, Service
from hoshino.typing import CQEvent, Message
from hoshino.util import filt_message
from ..util import get_uid_in_msg
from ..get_data import get_monthinfo_data

View File

@ -0,0 +1,86 @@
from hoshino import Service, get_bot, logger
from ..util import get_uid_in_msg
from ..db_util import get_auto_sign, add_auto_sign, delete_auto_sign
from ..get_data import get_sign_info, sign, get_sign_list
from ..config import auto_sign_time
from datetime import datetime
from asyncio import sleep
import random
from collections import defaultdict
import re
sv = Service('派蒙米游社自动签到', bundle='派蒙')
@sv.on_prefix(('mys签到', 'mys-sign'))
async def bbs_ys_sign(bot, ev):
uid, msg, user_id, use_cache = await get_uid_in_msg(ev)
sign_list = await get_sign_list()
sign_info = await get_sign_info(uid)
if isinstance(sign_info, str):
await bot.send(ev, sign_info, at_sender=True)
elif sign_info['data']['is_sign']:
sign_day = sign_info['data']['total_sign_day'] - 1
await bot.send(ev, f'你今天已经签过到了哦,获得的奖励为:\n{sign_list["data"]["awards"][sign_day]["name"]} * {sign_list["data"]["awards"][sign_day]["cnt"]}', at_sender=True)
else:
sign_day = sign_info['data']['total_sign_day']
sign_action = await sign(uid)
if isinstance(sign_action, str):
await bot.send(ev, sign_action, at_sender=True)
else:
await bot.send(ev, f'签到成功,获得的奖励为:\n{sign_list["data"]["awards"][sign_day]["name"]} * {sign_list["data"]["awards"][sign_day]["cnt"]}', at_sender=True)
@sv.on_prefix(('mys自动签到', '米游社自动签到', 'mys-auto-sign'))
async def bbs_auto_sign(bot, ev):
if ev.message_type != 'group':
await bot.send(ev, '自动签到功能暂时只限Q群内使用哦')
return
msg = ev.message.extract_plain_text().strip()
find_uid = re.search(r'(?P<uid>(1|2|5)\d{8})', msg)
if not find_uid:
await bot.send(ev, '请把正确的需要帮忙签到的uid给派蒙哦!', at_sender=True)
else:
uid = find_uid.group('uid')
find_action = re.search(r'(?P<action>开启|启用|打开|关闭|禁用)', msg)
if find_action:
if find_action.group('action') in ['开启', '启用', '打开']:
await add_auto_sign(str(ev.user_id), uid, str(ev.group_id))
await bot.send(ev, '开启米游社自动签到成功,派蒙会在每日0点帮你签到', at_sender=True)
elif find_action.group('action') in ['关闭', '禁用']:
await delete_auto_sign(str(ev.user_id), uid)
await bot.send(ev, '关闭米游社自动签到成功', at_sender=True)
else:
await add_auto_sign(str(ev.user_id), uid, str(ev.group_id))
await bot.send(ev, '开启米游社自动签到成功,派蒙会在每日0点帮你签到', at_sender=True)
@sv.scheduled_job('cron', hour=auto_sign_time)
async def auto_sign():
data = await get_auto_sign()
if data:
ann = defaultdict(lambda: defaultdict(list))
logger.info('---派蒙开始执行米游社自动签到---')
sign_list = await get_sign_list()
for user_id, uid, group_id in data:
await sleep(random.randint(3,8))
sign_result = await sign(uid)
if not isinstance(sign_result, str):
sign_info = await get_sign_info(uid)
sign_day = sign_info['data']['total_sign_day'] - 1
ann[group_id]['成功'].append(f'.UID{uid}-{sign_list["data"]["awards"][sign_day]["name"]}*{sign_list["data"]["awards"][sign_day]["cnt"]}')
else:
await delete_auto_sign(user_id, uid)
ann[group_id]['失败'].append(f'.UID{uid}')
for group_id, content in ann.items():
group_str = '米游社自动签到结果:\n'
for type, ann_list in content.items():
if ann_list:
group_str += f'签到{type}\n'
for u in ann_list:
group_str += str(ann_list.index(u) + 1) + u + '\n'
try:
await get_bot().send_group_msg(group_id=group_id, message=group_str)
await sleep(random.randint(3,8))
except Exception as e:
logger.error(f'米游社签到结果发送失败:{e}')

View File

@ -4,6 +4,7 @@ import hashlib
import re
import random
import time
import string
from hoshino import logger, aiorequests
from io import BytesIO
import base64
@ -154,6 +155,12 @@ def md5(text: str) -> str:
md5.update(text.encode())
return md5.hexdigest()
def random_hex(length):
result = hex(random.randint(0, 16 ** length)).replace('0x', '').upper()
if len(result) < length:
result = '0' * (length - len(result)) + result
return result
# 米游社headers的ds_token对应版本2.11.1
def get_ds(q="", b=None) -> str:
if b:
@ -180,6 +187,30 @@ def get_headers(cookie, q='',b=None):
}
return headers
def get_old_version_ds() -> str:
s = 'h8w582wxwgqvahcdkpvdhbh2w9casgfl'
t = str(int(time.time()))
r = ''.join(random.sample(string.ascii_lowercase + string.digits, 6))
c = md5("salt=" + s + "&t=" + t + "&r=" + r)
return f"{t},{r},{c}"
def get_sign_headers(cookie):
headers={
'User_Agent': 'Mozilla/5.0 (Linux; Android 10; MIX 2 Build/QKQ1.190825.002; wv) AppleWebKit/537.36 ('
'KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.101 Mobile Safari/537.36 '
'miHoYoBBS/2.3.0',
'Cookie': cookie,
'x-rpc-device_id': random_hex(32),
'Origin': 'https://webstatic.mihoyo.com',
'X_Requested_With': 'com.mihoyo.hyperion',
'DS': get_old_version_ds(),
'x-rpc-client_type': '5',
'Referer': 'https://webstatic.mihoyo.com/bbs/event/signin-ys/index.html?bbs_auth_required=true&act_id'
'=e202009291139501&utm_source=bbs&utm_medium=mys&utm_campaign=icon',
'x-rpc-app_version': '2.3.0'
}
return headers
# 检查cookie是否有效通过查看个人主页来判断
async def check_cookie(cookie):
url = 'https://bbs-api.mihoyo.com/user/wapi/getUserFullInfo?gids=2'