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
@@ -18,6 +18,7 @@ class Genshin(db.Model):
auto_sign_time = db.Column(db.DateTime(timezone=True))
resin_remind = db.Column(db.Boolean(), default=False) # 树脂提醒
resin_recovery_time = db.Column(db.DateTime(timezone=True)) # 满树脂提醒日期
bind_group = db.Column(db.BigInteger())
_idx1 = db.Index("genshin_uid_idx1", "user_qq", "uid", unique=True)
@@ -56,6 +57,35 @@ class Genshin(db.Model):
return True
return False
@classmethod
async def set_bind_group(cls, uid: int, bind_group) -> bool:
"""
说明:
绑定group_id,除私聊外的提醒将在此群发送
参数:
:param uid: uid
:param bind_group: 群号
"""
query = cls.query.where(cls.uid == uid).with_for_update()
user = await query.gino.first()
if user:
await user.update(bind_group=bind_group).apply()
return True
return False
@classmethod
async def get_bind_group(cls, uid: int) -> Optional[int]:
"""
说明:
获取用户绑定的群聊
参数:
:param uid: uid
"""
user = await cls.query.where(cls.uid == uid).gino.first()
if user:
return user.bind_group
return None
@classmethod
async def set_cookie(cls, uid: int, cookie: str) -> bool:
"""
+16 -12
View File
@@ -1,9 +1,10 @@
from nonebot import on_command
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from utils.utils import get_message_text, is_number
from ..models import Genshin
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent, Message
from utils.utils import is_number
from .._models import Genshin
from services.log import logger
from nonebot.params import CommandArg, Command
from typing import Tuple
__zx_plugin_name__ = "原神绑定"
@@ -40,13 +41,14 @@ unbind = on_command("原神解绑", priority=5, block=True)
@bind.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json())
if state["_prefix"]["raw_command"] in ["原神绑定uid", "原神绑定米游社id"]:
async def _(event: MessageEvent, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
cmd = cmd[0]
msg = arg.extract_plain_text().strip()
if cmd in ["原神绑定uid", "原神绑定米游社id"]:
if not is_number(msg):
await bind.finish("uid/id必须为纯数字!", at_senders=True)
msg = int(msg)
if state["_prefix"]["raw_command"] == "原神绑定uid":
if cmd == "原神绑定uid":
uid = await Genshin.get_user_uid(event.user_id)
if uid:
await bind.finish(f"您已绑定过uid:{uid},如果希望更换uid,请先发送原神解绑")
@@ -54,7 +56,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
if not flag:
await bind.finish("添加失败,该uid可能已存在...")
_x = f"已成功添加原神uid:{msg}"
elif state["_prefix"]["raw_command"] == "原神绑定米游社id":
elif cmd == "原神绑定米游社id":
uid = await Genshin.get_user_uid(event.user_id)
if not uid:
await bind.finish("请先绑定原神uid..")
@@ -63,7 +65,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
else:
if not msg:
await bind.finish(
"私聊发送!!\n打开https://bbs.mihoyo.com/ys/\n登录后按F12点击控制台输入document.cookie复制输出的内容即可"
"私聊发送!!\n打开 https://bbs.mihoyo.com/ys/\n登录后按F12点击控制台输入document.cookie复制输出的内容即可"
)
if isinstance(event, GroupMessageEvent):
await bind.finish("请立即撤回你的消息并私聊发送!")
@@ -76,16 +78,18 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = msg[:-1]
await Genshin.set_cookie(uid, msg)
_x = f"已成功为uid:{uid} 设置cookie"
if isinstance(event, GroupMessageEvent):
await Genshin.set_bind_group(uid, event.group_id)
await bind.send(_x)
logger.info(
f"(USER {event.user_id}, "
f"GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" {state['_prefix']['raw_command']}:{msg}"
f" {cmd}:{msg}"
)
@unbind.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
async def _(event: MessageEvent):
if await Genshin.delete_user(event.user_id):
await unbind.send("用户数据删除成功...")
logger.info(
@@ -1,11 +1,12 @@
from .data_source import get_sign_reward_list, genshin_sign
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent
from nonebot import on_command
from nonebot.typing import T_State
from services.log import logger
from .init_task import add_job, scheduler, _sign
from apscheduler.jobstores.base import JobLookupError
from ..models import Genshin
from .._models import Genshin
from nonebot.params import Command
from typing import Tuple
__zx_plugin_name__ = "原神自动签到"
@@ -19,7 +20,7 @@ usage:
原神我硬签
""".strip()
__plugin_des__ = "原神懒人签到"
__plugin_cmd__ = ["开/关原神自动签到", "原神我硬签"]
__plugin_cmd__ = ["开启/关闭原神自动签到", "原神我硬签"]
__plugin_type__ = ("原神相关",)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
@@ -37,13 +38,14 @@ genshin_matcher = on_command(
@genshin_matcher.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
async def _(event: MessageEvent, cmd: Tuple[str, ...] = Command()):
cmd = cmd[0]
uid = await Genshin.get_user_uid(event.user_id)
if not uid or not await Genshin.get_user_cookie(uid, True):
await genshin_matcher.finish("请先绑定uid和cookie!")
if "account_id" not in await Genshin.get_user_cookie(uid, True):
await genshin_matcher.finish("请更新cookie!")
if state["_prefix"]["raw_command"] == "原神我硬签":
if cmd == "原神我硬签":
try:
msg = await genshin_sign(uid)
logger.info(
@@ -77,7 +79,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
scheduler.remove_job(f"genshin_auto_sign_{uid}_{event.user_id}_{i}")
except JobLookupError:
pass
if state["_prefix"]["raw_command"][0] == "开":
if cmd[0] == "开":
await Genshin.set_auto_sign(uid, True)
next_date = await Genshin.random_sign_time(uid)
add_job(event.user_id, uid, next_date)
@@ -1,8 +1,8 @@
from utils.http_utils import AsyncHttpx
from configs.config import Config
from services.log import logger
from ..utils import random_hex, get_old_ds
from ..models import Genshin
from .._utils import random_hex, get_old_ds
from .._models import Genshin
from typing import Optional, Dict
@@ -4,7 +4,7 @@ from utils.message_builder import at
from services.log import logger
from utils.utils import scheduler, get_bot
from apscheduler.jobstores.base import ConflictingIdError
from ..models import Genshin
from .._models import Genshin
from datetime import datetime, timedelta
from nonebot import Driver
import nonebot
@@ -103,8 +103,10 @@ async def _sign(user_id: int, uid: int, count: int):
if user_id in [x["user_id"] for x in await bot.get_friend_list()]:
await bot.send_private_msg(user_id=user_id, message=msg)
else:
group_list = await GroupInfoUser.get_user_all_group(user_id)
if group_list:
await bot.send_group_msg(
group_id=group_list[0], message=at(user_id) + msg
)
if not (group_id := await Genshin.get_bind_group(uid)):
group_list = await GroupInfoUser.get_user_all_group(user_id)
if group_list:
group_id = group_list[0]
await bot.send_group_msg(
group_id=group_id, message=at(user_id) + msg
)
@@ -1,9 +1,8 @@
from nonebot import on_command
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent
from services.log import logger
from .data_source import get_user_memo, get_memo
from ..models import Genshin
from .._models import Genshin
from nonebot.plugin import export
@@ -37,7 +36,7 @@ query_memo_matcher = on_command("原神便签查询", aliases={"原神便笺查
@query_memo_matcher.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
async def _(event: MessageEvent):
uid = await Genshin.get_user_uid(event.user_id)
if not uid or not await Genshin.get_user_cookie(uid, True):
await query_memo_matcher.finish("请先绑定uid和cookie!")
@@ -1,5 +1,5 @@
from typing import Optional, Union
from nonebot.adapters.cqhttp import MessageSegment
from nonebot.adapters.onebot.v11 import MessageSegment
from configs.config import Config
from asyncio.exceptions import TimeoutError
from services.log import logger
@@ -8,10 +8,9 @@ from utils.image_utils import BuildImage
from utils.http_utils import AsyncHttpx
from utils.utils import get_user_avatar
from utils.message_builder import image
from ..utils import get_ds
from ..models import Genshin
from .._utils import get_ds
from .._models import Genshin
from io import BytesIO
from pathlib import Path
from nonebot import Driver
import asyncio
import nonebot
@@ -20,7 +19,7 @@ import nonebot
driver: Driver = nonebot.get_driver()
memo_path = Path(IMAGE_PATH) / "genshin" / "genshin_memo"
memo_path = IMAGE_PATH / "genshin" / "genshin_memo"
memo_path.mkdir(exist_ok=True, parents=True)
@@ -1,10 +1,10 @@
from nonebot import on_command
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent, Message
from services.log import logger
from .data_source import query_role_data
from ..models import Genshin
from utils.utils import get_message_text, is_number
from .._models import Genshin
from utils.utils import is_number
from nonebot.params import CommandArg
__zx_plugin_name__ = "原神玩家查询"
@@ -33,8 +33,8 @@ query_role_info_matcher = on_command("原神玩家查询", aliases={"原神玩
@query_role_info_matcher.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json())
async def _(event: MessageEvent, arg: Message = CommandArg()):
msg = arg.extract_plain_text().strip()
if msg:
if not is_number(msg):
await query_role_info_matcher.finish("查询uid必须为数字!")
@@ -45,7 +45,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
uid = msg
if not uid: # or not await Genshin.get_user_cookie(uid):
await query_role_info_matcher.finish("请先绑定uid和cookie!")
nickname = event.sender.card if event.sender.card else event.sender.nickname
nickname = event.sender.card or event.sender.nickname
mys_id = await Genshin.get_user_mys_id(uid)
data = await query_role_data(event.user_id, uid, mys_id, nickname)
if data:
@@ -1,11 +1,11 @@
from typing import Optional, List, Dict, Union
from .draw_image import init_image, get_genshin_image
from nonebot.adapters.cqhttp import MessageSegment
from ..utils import get_ds, element_mastery
from nonebot.adapters.onebot.v11 import MessageSegment
from .._utils import get_ds, element_mastery
from services.log import logger
from utils.http_utils import AsyncHttpx
from configs.config import Config
from ..models import Genshin
from .._models import Genshin
try:
import ujson as json
@@ -1,9 +1,8 @@
from configs.path_config import IMAGE_PATH
from pathlib import Path
from configs.path_config import IMAGE_PATH, TEMP_PATH
from utils.image_utils import BuildImage
from typing import List, Dict, Optional
from utils.message_builder import image
from nonebot.adapters.cqhttp import MessageSegment
from nonebot.adapters.onebot.v11 import MessageSegment
from utils.http_utils import AsyncHttpx
from utils.utils import get_user_avatar
from io import BytesIO
@@ -12,7 +11,7 @@ import asyncio
import os
image_path = Path(IMAGE_PATH) / "genshin" / "genshin_card"
image_path = IMAGE_PATH / "genshin" / "genshin_card"
async def get_genshin_image(
@@ -109,8 +108,8 @@ def _get_genshin_image(
A.paste(char_image, (0, top_bk.h + bar.h + 10), center_type="by_width")
rand = random.randint(1, 10000)
A.resize(0.8)
A.save(Path(IMAGE_PATH) / "temp" / f"genshin_user_card_{rand}.png")
return image(f"genshin_user_card_{rand}.png", "temp")
A.save(TEMP_PATH / f"genshin_user_card_{rand}.png")
return image(TEMP_PATH / f"genshin_user_card_{rand}.png")
def get_user_data_image(
@@ -1,5 +1,5 @@
from utils.utils import scheduler
from ..models import Genshin
from .._models import Genshin
from services.log import logger
@@ -1,20 +1,19 @@
from nonebot import on_command
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent
from apscheduler.jobstores.base import JobLookupError
from services.log import logger
from .init_task import scheduler, add_job
from ..models import Genshin
from datetime import datetime
import random
import asyncio
import pytz
from .._models import Genshin
from nonebot.params import Command
from typing import Tuple
__zx_plugin_name__ = "原神树脂提醒"
__plugin_usage__ = """
usage:
即将满树脂的提醒
会在 120-140 140-160 160 以及溢出指定部分时提醒,
共提醒3-4次
指令:
开原神树脂提醒
关原神树脂提醒
@@ -30,12 +29,25 @@ __plugin_settings__ = {
"limit_superuser": False,
"cmd": ["原神树脂提醒", "关原神树脂提醒", "开原神树脂提醒"],
}
__plugin_configs__ = {
"AUTO_CLOSE_QUERY_FAIL_RESIN_REMIND": {
"value": True,
"help": "当请求连续三次失败时,关闭用户的树脂提醒",
"default_value": True
},
"CUSTOM_RESIN_OVERFLOW_REMIND": {
"value": 20,
"help": "自定义树脂溢出指定数量时的提醒,空值是为关闭",
"default_value": None
}
}
resin_remind = on_command("开原神树脂提醒", aliases={"关原神树脂提醒"}, priority=5, block=True)
@resin_remind.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
async def _(event: MessageEvent, cmd: Tuple[str, ...] = Command()):
cmd = cmd[0]
uid = await Genshin.get_user_uid(event.user_id)
if not uid or not await Genshin.get_user_cookie(uid, True):
await resin_remind.finish("请先绑定uid和cookie!")
@@ -43,7 +55,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
scheduler.remove_job(f"genshin_resin_remind_{uid}_{event.user_id}")
except JobLookupError:
pass
if state["_prefix"]["raw_command"][0] == "开":
if cmd == "开":
await Genshin.set_resin_remind(uid, True)
add_job(event.user_id, uid)
logger.info(
@@ -62,22 +74,3 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
)
await resin_remind.send("已关闭原神树脂提醒..", at_sender=True)
@scheduler.scheduled_job(
"interval",
minutes=30,
)
async def _():
for u in await Genshin.get_all_resin_remind_user():
if u.resin_recovery_time:
if await Genshin.get_user_resin_recovery_time(u.uid) < datetime.now(
pytz.timezone("Asia/Shanghai")
):
await Genshin.clear_resin_remind_time(u.uid)
elif (
await Genshin.get_user_resin_recovery_time(u.uid)
- datetime.now(pytz.timezone("Asia/Shanghai"))
).seconds > 360:
continue
add_job(u.user_qq, u.uid)
await asyncio.sleep(random.randint(10, 30))
@@ -3,11 +3,12 @@ from utils.message_builder import at
from models.group_member_info import GroupInfoUser
from apscheduler.jobstores.base import ConflictingIdError
from nonebot import Driver
from ..models import Genshin
from .._models import Genshin
from datetime import datetime, timedelta
from services.log import logger
from nonebot.plugin import require
import time
from configs.config import Config
import random
import nonebot
import pytz
@@ -15,13 +16,15 @@ import pytz
driver: Driver = nonebot.get_driver()
get_memo = require('query_memo').get_memo
get_memo = require("query_memo").get_memo
class UserManager:
def __init__(self):
def __init__(self, max_error_count: int = 3):
self._data = []
self._overflow_data = []
self._error_count = {}
self.max_error_count = max_error_count
def append(self, o: str):
if o not in self._data:
@@ -34,6 +37,32 @@ class UserManager:
def exists(self, o: str):
return o in self._data
def add_error_count(self, uid: str):
if uid in self._error_count.keys():
self._error_count[uid] += 1
else:
self._error_count[uid] = 1
def check(self, uid: str) -> bool:
if uid in self._error_count.keys():
return self._error_count[uid] == self.max_error_count
return False
def remove_error_count(self, uid):
if uid in self._error_count.keys():
del self._error_count[uid]
def add_overflow(self, uid: str):
if uid not in self._overflow_data:
self._overflow_data.append(uid)
def remove_overflow(self, uid: str):
if uid in self._overflow_data:
self._overflow_data.remove(uid)
def is_overflow(self, uid: str) -> bool:
return uid in self._overflow_data
user_manager = UserManager()
@@ -44,22 +73,38 @@ async def _():
启动时分配定时任务
"""
g_list = await Genshin.get_all_resin_remind_user()
date = datetime.now(pytz.timezone("Asia/Shanghai")) + timedelta(seconds=30)
for u in g_list:
if u.resin_recovery_time and await Genshin.get_user_resin_recovery_time(
u.uid
) > datetime.now(pytz.timezone("Asia/Shanghai")):
date = await Genshin.get_user_resin_recovery_time(u.uid)
scheduler.add_job(
_remind,
"date",
run_date=date.replace(microsecond=0),
id=f"genshin_resin_remind_{u.uid}_{u.user_qq}",
args=[u.user_qq, u.uid],
)
logger.info(
f"genshin_resin_remind add_job:USER:{u.user_qq} UID:{u.uid} "
f"{date} 原神树脂提醒"
)
if u.resin_remind:
if u.resin_recovery_time:
if await Genshin.get_user_resin_recovery_time(u.uid) > datetime.now(
pytz.timezone("Asia/Shanghai")
):
date = await Genshin.get_user_resin_recovery_time(u.uid)
scheduler.add_job(
_remind,
"date",
run_date=date.replace(microsecond=0),
id=f"genshin_resin_remind_{u.uid}_{u.user_qq}",
args=[u.user_qq, u.uid],
)
logger.info(
f"genshin_resin_remind add_job:USER:{u.user_qq} UID:{u.uid} "
f"{date} 原神树脂提醒"
)
else:
await Genshin.clear_resin_remind_time(u.uid)
add_job(u.user_qq, u.uid)
logger.info(
f"genshin_resin_remind add_job CHECK:USER:{u.user_qq} UID:{u.uid} "
f"{date} 原神树脂提醒"
)
else:
add_job(u.user_qq, u.uid)
logger.info(
f"genshin_resin_remind add_job CHECK:USER:{u.user_qq} UID:{u.uid} "
f"{date} 原神树脂提醒"
)
def add_job(user_id: int, uid: int):
@@ -85,39 +130,62 @@ async def _remind(user_id: int, uid: str):
else:
return
data, code = await get_memo(uid, server_id)
now = datetime.now(pytz.timezone("Asia/Shanghai"))
next_time = None
if code == 200:
current_resin = data["current_resin"] # 当前树脂
max_resin = data["max_resin"] # 最大树脂
resin_recovery_time = data["resin_recovery_time"] # 树脂全部回复时间
if max_resin - current_resin > 5:
msg = f"你的已经存了 {current_resin} 个树脂了!不要忘记刷掉!"
# resin_recovery_time = data["resin_recovery_time"] # 树脂全部回复时间
if current_resin < max_resin:
user_manager.remove(uid)
next_time = datetime.strptime(time.strftime(
"%Y-%m-%d %H:%M:%S", time.localtime(time.time() + float(resin_recovery_time))
), "%Y-%m-%d %H:%M:%S")
await Genshin.set_user_resin_recovery_time(int(uid), next_time)
scheduler.add_job(
_remind,
"date",
run_date=next_time,
id=f"genshin_resin_remind_{uid}_{user_id}",
args=[user_id, uid],
)
logger.info(f"genshin_resin_remind add_job:{next_time.replace(microsecond=0)} 原神树脂提醒")
else:
if not user_manager.exists(uid):
user_manager.remove_overflow(uid)
if max_resin - 40 <= current_resin <= max_resin - 20:
next_time = now + timedelta(minutes=(max_resin - 20 - current_resin) * 8, seconds=10)
elif current_resin < max_resin:
next_time = now + timedelta(minutes=(max_resin - current_resin) * 8, seconds=10)
elif current_resin == max_resin:
custom_overflow_resin = Config.get_config("resin_remind", "CUSTOM_RESIN_OVERFLOW_REMIND")
if user_manager.is_overflow(uid) and custom_overflow_resin:
next_time = now + timedelta(minutes=custom_overflow_resin * 8)
user_manager.add_overflow(uid)
user_manager.remove(uid)
msg = f"你的树脂都溢出 {custom_overflow_resin} 个了!浪费可耻!"
else:
next_time = now + timedelta(minutes=40 * 8 + random.randint(5, 50))
if not user_manager.exists(uid) and current_resin >= max_resin - 40:
if current_resin == max_resin:
user_manager.append(uid)
bot = get_bot()
if bot:
if user_id in [x["user_id"] for x in await bot.get_friend_list()]:
await bot.send_private_msg(
user_id=user_id,
message=f"树脂已经 {current_resin} 个啦" f",马上就要溢出了!快快刷掉刷掉!",
)
else:
bot = get_bot()
if bot:
if user_id in [x["user_id"] for x in await bot.get_friend_list()]:
await bot.send_private_msg(
user_id=user_id,
message=msg,
)
else:
group_id = await Genshin.get_bind_group(int(uid))
if not group_id:
group_list = await GroupInfoUser.get_user_all_group(user_id)
if group_list:
await bot.send_group_msg(
group_id=group_list[0],
message=at(user_id) + f"树脂已经 {current_resin} 个啦"
f",马上就要溢出了!快快刷掉刷掉!",
)
group_id = group_list[0]
await bot.send_group_msg(
group_id=group_id,
message=at(user_id) + msg
)
if not next_time:
if user_manager.check(uid) and Config.get_config("resin_remind", "AUTO_CLOSE_QUERY_FAIL_RESIN_REMIND"):
await Genshin.set_resin_remind(int(uid), False)
await Genshin.clear_resin_remind_time(int(uid))
next_time = now + timedelta(minutes=(20 + random.randint(5, 20)) * 8)
user_manager.add_error_count(uid)
else:
user_manager.remove_error_count(uid)
await Genshin.set_user_resin_recovery_time(int(uid), next_time)
scheduler.add_job(
_remind,
"date",
run_date=next_time,
id=f"genshin_resin_remind_{uid}_{user_id}",
args=[user_id, uid],
)