Merge branch 'main' into main

This commit is contained in:
HibiKier
2023-02-18 22:56:25 +08:00
committed by GitHub
138 changed files with 5649 additions and 6249 deletions
+1 -1
View File
@@ -65,4 +65,4 @@ async def _():
mes = "[[_task|genshin_alc]]" + alc_img
for gid in gl:
if group_manager.check_group_task_status(gid, "genshin_alc"):
await bot.send_group_msg(group_id=int(gid), message="" + mes)
await bot.send_group_msg(group_id=int(gid), message=mes)
+13 -14
View File
@@ -1,18 +1,19 @@
from nonebot import on_command, Driver
from nonebot.adapters.onebot.v11 import MessageEvent, Message, GroupMessageEvent
from utils.message_builder import image
from utils.image_utils import BuildImage
from utils.browser import get_browser
from configs.path_config import IMAGE_PATH
import nonebot
from services.log import logger
from nonebot.permission import SUPERUSER
from typing import List
from datetime import datetime, timedelta
import os
import asyncio
import os
import time
from datetime import datetime, timedelta
from typing import List
import nonebot
from nonebot import Driver, on_command
from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message, MessageEvent
from nonebot.permission import SUPERUSER
from configs.path_config import IMAGE_PATH
from services.log import logger
from utils.browser import get_browser
from utils.image_utils import BuildImage
from utils.message_builder import image
__zx_plugin_name__ = "今日素材"
__plugin_usage__ = """
@@ -114,5 +115,3 @@ def get_background_height(weapons_img: List[str]) -> int:
last_weapon.save(weapons_img[-1])
return height
+56 -445
View File
@@ -1,219 +1,49 @@
from services.db_context import db
from typing import Optional, Union, List
from datetime import datetime, timedelta
import random
from datetime import datetime, timedelta
from typing import Optional
import pytz
from tortoise import fields
from tortoise.contrib.postgres.functions import Random
from services.db_context import Model
class Genshin(db.Model):
__tablename__ = "genshin"
class Genshin(Model):
id = db.Column(db.Integer(), primary_key=True)
user_qq = db.Column(db.BigInteger(), nullable=False)
uid = db.Column(db.BigInteger())
mys_id = db.Column(db.BigInteger())
cookie = db.Column(db.String(), default="")
today_query_uid = db.Column(db.String(), default="") # 该cookie今日查询的uid
auto_sign = db.Column(db.Boolean(), default=False)
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())
login_ticket = db.Column(db.String(), default="")
stuid = db.Column(db.String(), default="")
stoken = db.Column(db.String(), default="")
id = fields.IntField(pk=True, generated=True, auto_increment=True)
"""自增id"""
user_qq = fields.BigIntField()
"""用户id"""
uid = fields.BigIntField()
"""uid"""
mys_id: int = fields.BigIntField(null=True)
"""米游社id"""
cookie: str = fields.TextField(default="")
"""米游社cookie"""
auto_sign = fields.BooleanField(default=False)
"""是否自动签到"""
today_query_uid = fields.TextField(default="")
"""cookie今日查询uid"""
auto_sign_time = fields.DatetimeField(null=True)
"""签到日期时间"""
resin_remind = fields.BooleanField(default=False)
"""树脂提醒"""
resin_recovery_time = fields.DatetimeField(null=True)
"""满树脂提醒日期"""
bind_group: int = fields.BigIntField(null=True)
"""发送提示 绑定群聊"""
login_ticket = fields.TextField(default="")
"""login_ticket"""
stuid: str = fields.TextField(default="")
"""stuid"""
stoken: str = fields.TextField(default="")
"""stoken"""
_idx1 = db.Index("genshin_uid_idx1", "user_qq", "uid", unique=True)
@classmethod
async def add_uid(cls, user_qq: int, uid: int):
"""
说明:
添加一个uid
参数:
:param user_qq: 用户qq
:param uid: 原神uid
"""
query = cls.query.where((cls.user_qq == user_qq) & (cls.uid == uid))
user = await query.gino.first()
if not user:
await cls.create(
user_qq=user_qq,
uid=uid,
)
return True
return False
@classmethod
async def set_mys_id(cls, uid: int, mys_id: int) -> bool:
"""
说明:
设置米游社id
参数:
:param uid: 原神uid
:param mys_id: 米游社id
"""
query = cls.query.where(cls.uid == uid).with_for_update()
user = await query.gino.first()
if user:
await user.update(mys_id=mys_id).apply()
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:
"""
说明:
设置cookie
参数:
:param uid: 原神uid
:param cookie: 米游社id
"""
query = cls.query.where(cls.uid == uid).with_for_update()
user = await query.gino.first()
if user:
await user.update(cookie=cookie).apply()
return True
return False
@classmethod
async def set_resin_remind(cls, uid: int, flag: bool) -> bool:
"""
说明:
设置体力提醒
参数:
:param uid: 原神uid
:param flag: 开关状态
"""
query = cls.query.where(cls.uid == uid).with_for_update()
user = await query.gino.first()
if user:
await user.update(resin_remind=flag).apply()
return True
return False
@classmethod
async def set_user_resin_recovery_time(cls, uid: int, date: datetime):
"""
说明:
设置体力完成时间
参数:
:param uid: uid
:param date: 提醒日期
"""
u = await cls.query.where(cls.uid == uid).gino.first()
if u:
await u.update(resin_recovery_time=date).apply()
@classmethod
async def get_user_resin_recovery_time(cls, uid: int) -> Optional[datetime]:
"""
说明:
获取体力完成时间
参数:
:param uid: uid
"""
u = await cls.query.where(cls.uid == uid).gino.first()
if u:
return u.resin_recovery_time.astimezone(pytz.timezone("Asia/Shanghai"))
return None
@classmethod
async def get_all_resin_remind_user(cls) -> List["Genshin"]:
"""
说明:
获取所有开启体力提醒的用户
"""
return await cls.query.where(cls.resin_remind == True).gino.all()
@classmethod
async def clear_resin_remind_time(cls, uid: int) -> bool:
"""
说明:
清空提醒日期
参数:
:param uid: uid
"""
user = await cls.query.where(cls.uid == uid).gino.first()
if user:
await user.update(resin_recovery_time=None).apply()
return True
return False
@classmethod
async def set_auto_sign(cls, uid: int, flag: bool) -> bool:
"""
说明:
设置米游社/原神自动签到
参数:
:param uid: 原神uid
:param flag: 开关状态
"""
query = cls.query.where(cls.uid == uid).with_for_update()
user = await query.gino.first()
if user:
await user.update(auto_sign=flag).apply()
return True
return False
@classmethod
async def get_all_auto_sign_user(cls) -> List["Genshin"]:
"""
说明:
获取所有开启自动签到的用户
"""
return await cls.query.where(cls.auto_sign == True).gino.all()
@classmethod
async def get_all_sign_user(cls) -> List["Genshin"]:
"""
说明:
获取 原神 所有今日签到用户
"""
return await cls.query.where(cls.auto_sign_time != None).gino.all()
@classmethod
async def clear_sign_time(cls, uid: int) -> bool:
"""
说明:
清空签到日期
参数:
:param uid: uid
"""
user = await cls.query.where(cls.uid == uid).gino.first()
if user:
await user.update(auto_sign_time=None).apply()
return True
return False
class Meta:
table = "genshin"
table_description = "原神数据表"
unique_together = ("user_qq", "uid")
@classmethod
async def random_sign_time(cls, uid: int) -> Optional[datetime]:
@@ -223,262 +53,43 @@ class Genshin(db.Model):
说明:
:param uid: uid
"""
query = cls.query.where(cls.uid == uid).with_for_update()
user = await query.gino.first()
user = await cls.get_or_none(uid=uid)
if user and user.cookie:
if user.auto_sign_time and user.auto_sign_time.astimezone(
pytz.timezone("Asia/Shanghai")
pytz.timezone("Asia/Shanghai")
) - timedelta(seconds=2) >= datetime.now(pytz.timezone("Asia/Shanghai")):
return user.auto_sign_time.astimezone(pytz.timezone("Asia/Shanghai"))
hours = int(str(datetime.now()).split()[1].split(":")[0])
minutes = int(str(datetime.now()).split()[1].split(":")[1])
date = (
datetime.now()
+ timedelta(days=1)
- timedelta(hours=hours)
- timedelta(minutes=minutes - 1)
datetime.now()
+ timedelta(days=1)
- timedelta(hours=hours)
- timedelta(minutes=minutes - 1)
)
random_hours = random.randint(0, 22)
random_minutes = random.randint(1, 59)
date += timedelta(hours=random_hours) + timedelta(minutes=random_minutes)
await user.update(auto_sign_time=date).apply()
user.auto_sign_time = date
await user.save(update_fields=["auto_sign_time"])
return date
return None
@classmethod
async def get_query_cookie(cls, uid: int) -> Optional[str]:
async def random_cookie(cls, uid: int) -> Optional[str]:
"""
说明:
获取查询角色信息cookie
随机获取查询角色信息cookie
参数:
:param uid: 原神uid
"""
# 查找用户今日是否已经查找过,防止重复
query = cls.query.where(cls.today_query_uid.contains(str(uid)))
x = await query.gino.first()
if x:
await cls._add_query_uid(uid, uid)
return x.cookie
for u in await cls.query.where(cls.cookie != "").order_by(db.func.random()).gino.all():
if not u.today_query_uid or len(u.today_query_uid[:-1].split()) < 30:
await cls._add_query_uid(uid, u.uid)
return u.cookie
return None
@classmethod
async def get_user_cookie(cls, uid: int, flag: bool = False) -> Optional[str]:
"""
说明:
获取用户cookie
参数:
:param uid:原神uid
:param flag:必须使用自己的cookie
"""
cookie = await cls._get_user_data(None, uid, "cookie")
if not cookie and not flag:
cookie = await cls.get_query_cookie(uid)
return cookie
@classmethod
async def get_user_by_qq(cls, user_qq: int) -> Optional["Genshin"]:
"""
说明:
通过qq获取用户对象
参数:
:param user_qq: qq
"""
return await cls.query.where(cls.user_qq == user_qq).gino.first()
@classmethod
async def get_user_by_uid(cls, uid: int) -> Optional["Genshin"]:
"""
说明:
通过uid获取用户对象
参数:
:param uid: qq
"""
return await cls.query.where(cls.uid == uid).gino.first()
@classmethod
async def get_user_uid(cls, user_qq: int) -> Optional[int]:
"""
说明:
获取用户uid
参数:
:param user_qq:用户qq
"""
return await cls._get_user_data(user_qq, None, "uid")
@classmethod
async def get_user_mys_id(cls, uid: int) -> Optional[int]:
"""
说嘛:
获取用户米游社id
参数:
:param uid:原神id
"""
return await cls._get_user_data(None, uid, "mys_id")
@classmethod
async def delete_user_cookie(cls, uid: int):
"""
说明:
删除用户cookie
参数:
:param uid: 原神uid
"""
query = cls.query.where(cls.uid == uid).with_for_update()
user = await query.gino.first()
user = await cls.get_or_none(today_query_uid__contains=str(uid))
if user:
await user.update(cookie="").apply()
@classmethod
async def delete_user(cls, user_qq: int):
"""
说明:
删除用户数据
参数:
:param user_qq: 用户qq
"""
query = cls.query.where(cls.user_qq == user_qq).with_for_update()
user = await query.gino.first()
if not user:
return False
await user.delete()
return True
@classmethod
async def _add_query_uid(cls, uid: int, cookie_uid: int):
"""
说明:
添加每日查询重复uid的cookie
参数:
:param uid: 原神uid
:param cookie_uid: cookie的uid
"""
query = cls.query.where(cls.uid == cookie_uid).with_for_update()
user = await query.gino.first()
await user.update(today_query_uid=user.today_query_uid + f"{uid} ").apply()
@classmethod
async def _get_user_data(
cls, user_qq: Optional[int], uid: Optional[int], type_: str
) -> Optional[Union[int, str]]:
"""
说明:
获取用户数据
参数:
:param user_qq: 用户qq
:param uid: uid
:param type_: 数据类型
"""
if type_ == "uid":
user = await cls.query.where(cls.user_qq == user_qq).gino.first()
return user.uid if user else None
user = await cls.query.where(cls.uid == uid).gino.first()
if not user:
return None
if type_ == "mys_id":
return user.mys_id
elif type_ == "cookie":
return user.cookie
return None
@classmethod
async def reset_today_query_uid(cls):
for u in await cls.query.with_for_update().gino.all():
if u.today_query_uid:
await u.update(today_query_uid="").apply()
@classmethod
async def set_stuid(cls, uid: int, stuid: str) -> bool:
"""
说明:
设置stuid
参数:
:param uid: 原神uid
:param stuid: stuid
"""
query = cls.query.where(cls.uid == uid).with_for_update()
user = await query.gino.first()
if user:
await user.update(stuid=stuid).apply()
return True
return False
@classmethod
async def set_stoken(cls, uid: int, stoken: str) -> bool:
"""
说明:
设置stoken
参数:
:param uid: 原神uid
:param stoken: stoken
"""
query = cls.query.where(cls.uid == uid).with_for_update()
user = await query.gino.first()
if user:
await user.update(stoken=stoken).apply()
return True
return False
@classmethod
async def set_login_ticket(cls, uid: int, login_ticket: str) -> bool:
"""
说明:
设置login_ticket
参数:
:param uid: 原神uid
:param login_ticket: login_ticket
"""
query = cls.query.where(cls.uid == uid).with_for_update()
user = await query.gino.first()
if user:
await user.update(login_ticket=login_ticket).apply()
return True
return False
# 获取login_ticket
@classmethod
async def get_login_ticket(cls, uid: int) -> Optional[str]:
"""
说明:
获取login_ticket
参数:
:param uid: 原神uid
"""
query = cls.query.where(cls.uid == uid)
user = await query.gino.first()
if user:
return user.login_ticket
return None
# 获取stuid
@classmethod
async def get_stuid(cls, uid: int) -> Optional[str]:
"""
说明:
获取stuid
参数:
:param uid: 原神uid
"""
query = cls.query.where(cls.uid == uid)
user = await query.gino.first()
if user:
return user.stuid
return None
# 获取stoken
@classmethod
async def get_stoken(cls, uid: int) -> Optional[str]:
"""
说明:
获取stoken
参数:
:param uid: 原神uid
"""
query = cls.query.where(cls.uid == uid)
user = await query.gino.first()
if user:
return user.stoken
for user in await cls.filter(cookie__not="").annotate(rand=Random()).all():
if not user.today_query_uid or len(user.today_query_uid[:-1].split()) < 30:
user.today_query_uid = user.today_query_uid + f"{uid} "
await user.save(update_fields=["today_query_uid"])
return user.cookie
return None
@@ -1,9 +1,10 @@
from configs.config import Config
import json
import time
import random
import hashlib
import json
import random
import string
import time
from configs.config import Config
def _md5(text):
@@ -15,7 +16,7 @@ def _md5(text):
def get_old_ds() -> str:
n = Config.get_config("genshin", "n")
i = str(int(time.time()))
r = ''.join(random.sample(string.ascii_lowercase + string.digits, 6))
r = "".join(random.sample(string.ascii_lowercase + string.digits, 6))
c = _md5("salt=" + n + "&t=" + i + "&r=" + r)
return i + "," + r + "," + c
@@ -33,7 +34,7 @@ def get_ds(q: str = "", b: dict = None) -> str:
def random_hex(length: int) -> str:
result = hex(random.randint(0, 16 ** length)).replace("0x", "").upper()
result = hex(random.randint(0, 16**length)).replace("0x", "").upper()
if len(result) < length:
result = "0" * (length - len(result)) + result
return result
+61 -48
View File
@@ -1,13 +1,16 @@
from nonebot import on_command
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
from utils.http_utils import AsyncHttpx
import json
from typing import Tuple
from nonebot import on_command
from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message, MessageEvent
from nonebot.params import Command, CommandArg
from services.log import logger
from utils.depends import OneCommand
from utils.http_utils import AsyncHttpx
from utils.utils import is_number
from .._models import Genshin
__zx_plugin_name__ = "原神绑定"
__plugin_usage__ = """
@@ -43,82 +46,94 @@ unbind = on_command("原神解绑", priority=5, block=True)
web_Api = "https://api-takumi.mihoyo.com"
bbs_Cookie_url = "https://webapi.account.mihoyo.com/Api/cookie_accountinfo_by_loginticket?login_ticket={}"
bbs_Cookie_url2 = web_Api + "/auth/api/getMultiTokenByLoginTicket?login_ticket={}&token_types=3&uid={}"
bbs_Cookie_url2 = (
web_Api
+ "/auth/api/getMultiTokenByLoginTicket?login_ticket={}&token_types=3&uid={}"
)
@bind.handle()
async def _(event: MessageEvent, cmd: Tuple[str, ...] = Command(), arg: Message = CommandArg()):
cmd = cmd[0]
async def _(event: MessageEvent, cmd: str = OneCommand(), arg: Message = CommandArg()):
msg = arg.extract_plain_text().strip()
user = await Genshin.get_or_none(user_qq=event.user_id)
if cmd in ["原神绑定uid", "原神绑定米游社id"]:
if not is_number(msg):
await bind.finish("uid/id必须为纯数字!", at_senders=True)
msg = int(msg)
if cmd == "原神绑定uid":
uid = await Genshin.get_user_uid(event.user_id)
if uid:
await bind.finish(f"您已绑定过uid:{uid},如果希望更换uid,请先发送原神解绑")
flag = await Genshin.add_uid(event.user_id, msg)
if not flag:
if user:
await bind.finish(f"您已绑定过uid:{user.uid},如果希望更换uid,请先发送原神解绑")
if await Genshin.get_or_none(user_qq=event.user_id, uid=msg):
await bind.finish("添加失败,该uid可能已存在...")
user = await Genshin.create(user_qq=event.user_id, uid=msg)
_x = f"已成功添加原神uid:{msg}"
elif cmd == "原神绑定米游社id":
uid = await Genshin.get_user_uid(event.user_id)
if not uid:
if not user:
await bind.finish("请先绑定原神uid..")
await Genshin.set_mys_id(uid, msg)
_x = f"已成功为uid:{uid} 设置米游社id:{msg}"
user.mys_id = int(msg)
_x = f"已成功为uid:{user.uid} 设置米游社id:{msg}"
else:
if not msg:
await bind.finish("""私聊发送!!
await bind.finish(
"""私聊发送!!
1.以无痕模式打开浏览器(Edge请新建InPrivate窗口)
2.打开http://bbs.mihoyo.com/ys/并登陆
2.打开http://bbs.mihoyo.com/ys/ 并登陆
3.登陆后打开http://user.mihoyo.com/进行登陆
4.按下F12,打开控制台,输入以下命令:
var cookie=document.cookie;var ask=confirm('Cookie:'+cookie+'\\n\\nDo you want to copy the cookie to the clipboard?');if(ask==true){copy(cookie);msg=cookie}else{msg='Cancel'}
5.私聊发送:原神绑定cookie 刚刚复制的cookie""")
5.私聊发送:原神绑定cookie 刚刚复制的cookie"""
)
if isinstance(event, GroupMessageEvent):
await bind.finish("请立即撤回你的消息并私聊发送!")
uid = await Genshin.get_user_uid(event.user_id)
if not uid:
if not user:
await bind.finish("请先绑定原神uid..")
if msg.startswith('"') or msg.startswith("'"):
msg = msg[1:]
if msg.endswith('"') or msg.endswith("'"):
msg = msg[:-1]
await Genshin.set_cookie(uid, msg)
cookie = msg
# 用: 代替=, ,代替;
cookie = '{"' + cookie.replace('=', '": "').replace("; ", '","') + '"}'
print(cookie)
cookie = '{"' + cookie.replace("=", '": "').replace("; ", '","') + '"}'
# print(cookie)
cookie_json = json.loads(cookie)
print(cookie_json)
if 'login_ticket' not in cookie_json:
# print(cookie_json)
if "login_ticket" not in cookie_json:
await bind.finish("请发送正确完整的cookie!")
login_ticket = cookie_json['login_ticket']
user.cookie = str(msg)
login_ticket = cookie_json["login_ticket"]
# try:
res = await AsyncHttpx.get(url=bbs_Cookie_url.format(login_ticket))
res.encoding = "utf-8"
data = json.loads(res.text)
print(data)
# print(data)
if "成功" in data["data"]["msg"]:
stuid = str(data["data"]["cookie_info"]["account_id"])
res = await AsyncHttpx.get(url=bbs_Cookie_url2.format(
login_ticket, stuid))
res = await AsyncHttpx.get(url=bbs_Cookie_url2.format(login_ticket, stuid))
res.encoding = "utf-8"
data = json.loads(res.text)
stoken = data["data"]["list"][0]["token"]
# await Genshin.set_cookie(uid, cookie)
await Genshin.set_stoken(uid, stoken)
await Genshin.set_stuid(uid, stuid)
await Genshin.set_login_ticket(uid, login_ticket)
user.stoken = stoken
user.stuid = stuid
user.login_ticket = login_ticket
# except Exception as e:
# await bind.finish("获取登陆信息失败,请检查cookie是否正确或更新cookie")
elif data["data"]["msg"] == "登录信息已失效,请重新登录":
await bind.finish("登录信息失效,请重新获取最新cookie进行绑定")
_x = f"已成功为uid:{uid} 设置cookie"
_x = f"已成功为uid:{user.uid} 设置cookie"
if isinstance(event, GroupMessageEvent):
await Genshin.set_bind_group(uid, event.group_id)
user.bind_group = event.group_id
if user:
await user.save(
update_fields=[
"mys_id",
"cookie",
"stoken",
"stuid",
"login_ticket",
"bind_group",
]
)
await bind.send(_x)
logger.info(
f"(USER {event.user_id}, "
@@ -129,12 +144,10 @@ async def _(event: MessageEvent, cmd: Tuple[str, ...] = Command(), arg: Message
@unbind.handle()
async def _(event: MessageEvent):
if await Genshin.delete_user(event.user_id):
await unbind.send("用户数据删除成功...")
logger.info(
f"(USER {event.user_id}, GROUP "
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f"原神解绑"
)
else:
await unbind.send("该用户数据不存在..")
await Genshin.filter(user_qq=event.user_id).delete()
await unbind.send("用户数据删除成功...")
logger.info(
f"(USER {event.user_id}, GROUP "
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f"原神解绑"
)
@@ -1,14 +1,17 @@
from .data_source import get_sign_reward_list, genshin_sign
from ..mihoyobbs_sign import mihoyobbs_sign
from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent
from nonebot import on_command
from services.log import logger
from .init_task import add_job, scheduler, _sign
from apscheduler.jobstores.base import JobLookupError
from .._models import Genshin
from nonebot.params import Command
from typing import Tuple
from apscheduler.jobstores.base import JobLookupError
from nonebot import on_command
from nonebot.adapters.onebot.v11 import GroupMessageEvent, MessageEvent
from nonebot.params import Command
from services.log import logger
from utils.depends import OneCommand
from .._models import Genshin
from ..mihoyobbs_sign import mihoyobbs_sign
from .data_source import genshin_sign, get_sign_reward_list
from .init_task import _sign, add_job, scheduler
__zx_plugin_name__ = "原神自动签到"
__plugin_usage__ = """
@@ -39,45 +42,46 @@ genshin_matcher = on_command(
@genshin_matcher.handle()
async def _(event: MessageEvent, cmd: Tuple[str, ...] = Command()):
cmd = cmd[0]
uid = await Genshin.get_user_uid(event.user_id)
async def _(event: MessageEvent, cmd: str = OneCommand()):
user = await Genshin.get_or_none(user_qq=event.user_id)
if not user:
await genshin_matcher.finish("请先绑定user.uid...")
if cmd == "查看我的cookie":
my_cookie = await Genshin.get_user_cookie(uid, True)
if isinstance(event, GroupMessageEvent):
await genshin_matcher.finish("请私聊查看您的cookie!")
await genshin_matcher.finish("您的cookie为" + my_cookie)
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为" + user.cookie)
if not user.uid or not user.cookie:
await genshin_matcher.finish("请先绑定user.uid和cookie!")
# if "account_id" not in await Genshin.get_user_cookie(user.uid, True):
# await genshin_matcher.finish("请更新cookie!")
if cmd == "原神我硬签":
try:
await genshin_matcher.send("正在进行签到...", at_sender=True)
msg = await genshin_sign(uid)
msg = await genshin_sign(user.uid)
return_data = await mihoyobbs_sign(event.user_id)
logger.info(
f"(USER {event.user_id}, "
f"GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) UID:{uid} 原神签到"
f"GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) UID:{user.uid} 原神签到"
)
logger.info(msg)
# 硬签,移除定时任务
try:
for i in range(3):
scheduler.remove_job(f"genshin_auto_sign_{uid}_{event.user_id}_{i}",)
scheduler.remove_job(
f"genshin_auto_sign_{user.uid}_{event.user_id}_{i}",
)
except JobLookupError:
pass
u = await Genshin.get_user_by_uid(uid)
if u and u.auto_sign:
await u.clear_sign_time(uid)
next_date = await Genshin.random_sign_time(uid)
add_job(event.user_id, uid, next_date)
if user.auto_sign:
user.auto_sign_time = None
next_date = await Genshin.random_sign_time(user.uid)
add_job(event.user_id, user.uid, next_date)
msg += f"\n{return_data}\n因开启自动签到\n下一次签到时间为:{next_date.replace(microsecond=0)}"
except Exception as e:
msg = "原神签到失败..请尝试检查cookie或报告至管理员!"
logger.info(
f"(USER {event.user_id}, "
f"GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) UID:{uid} 原神签到发生错误 "
f"GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) UID:{user.uid} 原神签到发生错误 "
f"{type(e)}:{e}"
)
msg = msg or "请检查cookie是否更新!"
@@ -85,13 +89,16 @@ async def _(event: MessageEvent, cmd: Tuple[str, ...] = Command()):
else:
for i in range(3):
try:
scheduler.remove_job(f"genshin_auto_sign_{uid}_{event.user_id}_{i}")
scheduler.remove_job(
f"genshin_auto_sign_{user.uid}_{event.user_id}_{i}"
)
except JobLookupError:
pass
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)
next_date = await Genshin.random_sign_time(user.uid)
user.auto_sign = True
user.auto_sign_time = next_date
add_job(event.user_id, user.uid, next_date)
await genshin_matcher.send(
f"已开启原神自动签到!\n下一次签到时间为:{next_date.replace(microsecond=0)}",
at_sender=True,
@@ -102,11 +109,13 @@ async def _(event: MessageEvent, cmd: Tuple[str, ...] = Command()):
f" 开启原神自动签到"
)
else:
await Genshin.set_auto_sign(uid, False)
await Genshin.clear_sign_time(uid)
user.auto_sign = False
user.auto_sign_time = None
await genshin_matcher.send(f"已关闭原神自动签到!", at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP "
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 关闭原神自动签到"
)
if user:
await user.save(update_fields=["auto_sign_time", "auto_sign"])
@@ -1,14 +1,16 @@
from utils.http_utils import AsyncHttpx
from configs.config import Config
from services.log import logger
from ..mihoyobbs_sign.setting import *
from .._models import Genshin
from typing import Optional, Dict
import hashlib
import random
import string
import uuid
import time
import uuid
from typing import Dict, Optional
from configs.config import Config
from services.log import logger
from utils.http_utils import AsyncHttpx
from .._models import Genshin
from ..mihoyobbs_sign.setting import *
async def genshin_sign(uid: int) -> Optional[str]:
@@ -28,10 +30,10 @@ async def genshin_sign(uid: int) -> Optional[str]:
sign_list = await get_sign_reward_list()
get_reward = sign_list["data"]["awards"][
int(sign_info["total_sign_day"]) - 1
]["name"]
]["name"]
reward_num = sign_list["data"]["awards"][
int(sign_info["total_sign_day"]) - 1
]["cnt"]
]["cnt"]
get_im = f"本次签到获得:{get_reward}x{reward_num}"
logger.info("get_im:" + get_im + "\nsign_info:" + str(sign_info))
if status == "OK" and sign_info["is_sign"]:
@@ -64,7 +66,7 @@ def timestamp() -> int:
def random_text(num: int) -> str:
return ''.join(random.sample(string.ascii_lowercase + string.digits, num))
return "".join(random.sample(string.ascii_lowercase + string.digits, num))
def md5(text: str) -> str:
@@ -75,8 +77,7 @@ def md5(text: str) -> str:
# 生成一个device id
def get_device_id(cookie) -> str:
return str(uuid.uuid3(uuid.NAMESPACE_URL, cookie)).replace(
'-', '').upper()
return str(uuid.uuid3(uuid.NAMESPACE_URL, cookie)).replace("-", "").upper()
async def _sign(uid: int, server_id: str = "cn_gf01") -> Optional[Dict[str, str]]:
@@ -88,18 +89,20 @@ async def _sign(uid: int, server_id: str = "cn_gf01") -> Optional[Dict[str, str]
if str(uid)[0] == "5":
server_id = "cn_qd01"
try:
cookie = await Genshin.get_user_cookie(uid, True)
headers['DS'] = get_ds(web=True)
headers['Referer'] = 'https://webstatic.mihoyo.com/bbs/event/signin-ys/index.html?bbs_auth_required=true' \
f'&act_id={genshin_Act_id}&utm_source=bbs&utm_medium=mys&utm_campaign=icon'
headers['Cookie'] = cookie
headers['x-rpc-device_id'] = get_device_id(cookie)
req = await AsyncHttpx.post(
url=genshin_Signurl,
headers=headers,
json={"act_id": genshin_Act_id, "uid": uid, "region": server_id},
)
return req.json()
if user := await Genshin.get_or_none(uid=uid):
headers["DS"] = get_ds(web=True)
headers["Referer"] = (
"https://webstatic.mihoyo.com/bbs/event/signin-ys/index.html?bbs_auth_required=true"
f"&act_id={genshin_Act_id}&utm_source=bbs&utm_medium=mys&utm_campaign=icon"
)
headers["Cookie"] = user.cookie
headers["x-rpc-device_id"] = get_device_id(user.cookie)
req = await AsyncHttpx.post(
url=genshin_Signurl,
headers=headers,
json={"act_id": genshin_Act_id, "uid": uid, "region": server_id},
)
return req.json()
except Exception as e:
logger.error(f"米游社签到发生错误 UID:{uid} {type(e)}:{e}")
return None
@@ -129,17 +132,22 @@ async def _get_sign_info(uid: int, server_id: str = "cn_gf01"):
if str(uid)[0] == "5":
server_id = "cn_qd01"
try:
req = await AsyncHttpx.get(
url=f"https://api-takumi.mihoyo.com/event/bbs_sign_reward/info?act_id=e202009291139501&region={server_id}&uid={uid}",
headers={
"x-rpc-app_version": str(Config.get_config("genshin", "mhyVersion")),
"Cookie": await Genshin.get_user_cookie(int(uid), True),
"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": str(Config.get_config("genshin", "client_type")),
"Referer": "https://webstatic.mihoyo.com/",
},
)
return req.json()
if user := await Genshin.get_or_none(uid=uid):
req = await AsyncHttpx.get(
url=f"https://api-takumi.mihoyo.com/event/bbs_sign_reward/info?act_id=e202009291139501&region={server_id}&uid={uid}",
headers={
"x-rpc-app_version": str(
Config.get_config("genshin", "mhyVersion")
),
"Cookie": user.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",
"x-rpc-client_type": str(
Config.get_config("genshin", "client_type")
),
"Referer": "https://webstatic.mihoyo.com/",
},
)
return req.json()
except Exception as e:
logger.error(f"获取签到信息发生错误 UID:{uid} {type(e)}:{e}")
return None
@@ -1,17 +1,19 @@
from .data_source import genshin_sign
from ..mihoyobbs_sign import mihoyobbs_sign
from models.group_member_info import GroupInfoUser
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 datetime import datetime, timedelta
from nonebot import Driver
import nonebot
import random
import pytz
from datetime import datetime, timedelta
import nonebot
import pytz
from apscheduler.jobstores.base import ConflictingIdError
from nonebot import Driver
from models.group_member_info import GroupInfoUser
from services.log import logger
from utils.message_builder import at
from utils.utils import get_bot, scheduler
from .._models import Genshin
from ..mihoyobbs_sign import mihoyobbs_sign
from .data_source import genshin_sign
driver: Driver = nonebot.get_driver()
@@ -21,7 +23,7 @@ async def _():
"""
启动时分配定时任务
"""
g_list = await Genshin.get_all_auto_sign_user()
g_list = await Genshin.filter(auto_sign=True).all()
for u in g_list:
if u.auto_sign_time:
if date := await Genshin.random_sign_time(u.uid):
@@ -33,7 +35,8 @@ async def _():
args=[u.user_qq, u.uid, 0],
)
logger.info(
f"genshin_sign add_job:USER:{u.user_qq} UID:{u.uid} " f"{date} 原神自动签到"
f"genshin_sign add_job:USER:{u.user_qq} UID:{u.uid} "
f"{date} 原神自动签到"
)
@@ -110,10 +113,12 @@ async def _sign(user_id: int, uid: int, count: int):
await bot.send_private_msg(user_id=user_id, message=return_data)
await bot.send_private_msg(user_id=user_id, message=msg)
else:
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
)
if user := await Genshin.get_or_none(uid=uid):
group_id = user.bind_group
if not group_id:
if group_list := await GroupInfoUser.get_user_all_group(user_id):
group_id = group_list[0]
if group_id:
await bot.send_group_msg(
group_id=group_id, message=at(user_id) + msg
)
@@ -1,14 +1,16 @@
from nonebot.adapters.onebot.v11 import MessageEvent
from typing import Tuple
from nonebot import on_command
from nonebot.adapters.onebot.v11 import MessageEvent
from nonebot.params import Command
from services.log import logger
# from .init_task import add_job, scheduler, _sign
# from apscheduler.jobstores.base import JobLookupError
from .._models import Genshin
from nonebot.params import Command
from typing import Tuple
from .mihoyobbs import *
__zx_plugin_name__ = "米游社自动签到"
__plugin_usage__ = """
usage:
@@ -28,12 +30,10 @@ __plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["原神签到"],
"cmd": ["米游社签到"],
}
mihoyobbs_matcher = on_command(
"米游社签到", aliases={"米游社我硬签"}, priority=5, block=True
)
mihoyobbs_matcher = on_command("米游社签到", aliases={"米游社我硬签"}, priority=5, block=True)
@mihoyobbs_matcher.handle()
@@ -47,24 +47,29 @@ async def _(event: MessageEvent, cmd: Tuple[str, ...] = Command()):
async def mihoyobbs_sign(user_id):
uid = await Genshin.get_user_uid(user_id)
if not uid or not await Genshin.get_user_cookie(uid, True):
user = await Genshin.get_or_none(user_qq=user_id)
if not user or not user.uid or not user.cookie:
await mihoyobbs_matcher.finish("请先绑定uid和cookie!", at_sender=True)
stuid = await Genshin.get_stuid(uid)
stoken = await Genshin.get_stoken(uid)
cookie = await Genshin.get_user_cookie(uid)
bbs = mihoyobbs.Mihoyobbs(stuid=stuid, stoken=stoken, cookie=cookie)
bbs = mihoyobbs.Mihoyobbs(stuid=user.stuid, stoken=user.stoken, cookie=user.cookie)
await bbs.init()
return_data = ""
if bbs.Task_do["bbs_Sign"] and bbs.Task_do["bbs_Read_posts"] and bbs.Task_do["bbs_Like_posts"] and \
bbs.Task_do["bbs_Share"]:
return_data += f"今天的米游社签到任务已经全部完成了!\n" \
f"一共获得{mihoyobbs.today_have_get_coins}个米游币\n目前有{mihoyobbs.Have_coins}个米游币"
logger.info(f"今天已经全部完成了!一共获得{mihoyobbs.today_have_get_coins}个米游币,目前有{mihoyobbs.Have_coins}个米游币")
if (
bbs.Task_do["bbs_Sign"]
and bbs.Task_do["bbs_Read_posts"]
and bbs.Task_do["bbs_Like_posts"]
and bbs.Task_do["bbs_Share"]
):
return_data += (
f"今天的米游社签到任务已经全部完成了!\n"
f"一共获得{mihoyobbs.today_have_get_coins}个米游币\n目前有{mihoyobbs.Have_coins}个米游币"
)
logger.info(
f"今天已经全部完成了!一共获得{mihoyobbs.today_have_get_coins}个米游币,目前有{mihoyobbs.Have_coins}个米游币"
)
else:
i = 0
print("开始签到")
print(mihoyobbs.today_have_get_coins)
# print("开始签到")
# print(mihoyobbs.today_have_get_coins)
while mihoyobbs.today_get_coins != 0 and i < 3:
# if i > 0:
await bbs.refresh_list()
@@ -74,8 +79,12 @@ async def mihoyobbs_sign(user_id):
await bbs.share_post()
await bbs.get_tasks_list()
i += 1
return_data += "\n" + f"今天已经获得{mihoyobbs.today_have_get_coins}个米游币\n" \
f"还能获得{mihoyobbs.today_get_coins}个米游币\n目前有{mihoyobbs.Have_coins}个米游币"
logger.info(f"今天已经获得{mihoyobbs.today_have_get_coins}个米游币,"
f"还能获得{mihoyobbs.today_get_coins}个米游币,目前有{mihoyobbs.Have_coins}个米游币")
return_data += (
"\n" + f"今天已经获得{mihoyobbs.today_have_get_coins}个米游币\n"
f"还能获得{mihoyobbs.today_get_coins}个米游币\n目前有{mihoyobbs.Have_coins}个米游币"
)
logger.info(
f"今天已经获得{mihoyobbs.today_have_get_coins}个米游币,"
f"还能获得{mihoyobbs.today_get_coins}个米游币,目前有{mihoyobbs.Have_coins}个米游币"
)
return return_data
@@ -1,9 +1,10 @@
from nonebot import on_command
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 nonebot.adapters.onebot.v11 import GroupMessageEvent, MessageEvent
from services.log import logger
from .._models import Genshin
from .data_source import get_memo, get_user_memo
__zx_plugin_name__ = "原神便笺查询"
__plugin_usage__ = """
@@ -27,30 +28,27 @@ __plugin_settings__ = {
__plugin_block_limit__ = {}
query_memo_matcher = on_command("原神便签查询", aliases={"原神便笺查询", "yss"}, priority=5, block=True)
query_memo_matcher = on_command(
"原神便签查询", aliases={"原神便笺查询", "yss"}, priority=5, block=True
)
@query_memo_matcher.handle()
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):
user = await Genshin.get_or_none(user_qq=event.user_id)
if not user or not user.uid or not user.cookie:
await query_memo_matcher.finish("请先绑定uid和cookie!")
if isinstance(event, GroupMessageEvent):
uname = event.sender.card or event.sender.nickname
else:
uname = event.sender.nickname
data = await get_user_memo(event.user_id, uid, uname)
data = await get_user_memo(event.user_id, user.uid, uname)
if data:
await query_memo_matcher.send(data)
logger.info(
f"(USER {event.user_id}, "
f"GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) "
f"使用原神便笺查询 uid:{uid}"
f"使用原神便笺查询 uid:{user.uid}"
)
else:
await query_memo_matcher.send("未查询到数据...")
@@ -1,20 +1,22 @@
from typing import Optional, Union
from nonebot.adapters.onebot.v11 import MessageSegment
from configs.config import Config
from asyncio.exceptions import TimeoutError
from services.log import logger
from configs.path_config import IMAGE_PATH
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 io import BytesIO
from nonebot import Driver
import asyncio
import nonebot
from asyncio.exceptions import TimeoutError
from io import BytesIO
from typing import Optional, Tuple, Union
import nonebot
from nonebot import Driver
from nonebot.adapters.onebot.v11 import MessageSegment
from configs.config import Config
from configs.path_config import IMAGE_PATH
from services.log import logger
from utils.http_utils import AsyncHttpx
from utils.image_utils import BuildImage
from utils.message_builder import image
from utils.utils import get_user_avatar
from .._models import Genshin
from .._utils import get_ds
driver: Driver = nonebot.get_driver()
@@ -26,10 +28,7 @@ memo_path.mkdir(exist_ok=True, parents=True)
@driver.on_startup
async def _():
for name, url in zip(
[
"resin.png", "task.png", "resin_discount.png", "chengehu.png",
"zhibian.png"
],
["resin.png", "task.png", "resin_discount.png", "chengehu.png", "zhibian.png"],
[
"https://upload-bbs.mihoyo.com/upload/2021/09/29/8819732/54266243c7d15ba31690c8f5d63cc3c6_71491376413333325"
"20.png?x-oss-process=image//resize,s_600/quality,q_80/auto-orient,0/interlace,1/format,png",
@@ -45,8 +44,9 @@ async def _():
logger.info(f"已下载原神便签资源 -> {file}...")
async def get_user_memo(user_id: int, uid: int,
uname: str) -> Optional[Union[str, MessageSegment]]:
async def get_user_memo(
user_id: int, uid: int, uname: str
) -> Optional[Union[str, MessageSegment]]:
uid = str(uid)
if uid[0] in ["1", "2"]:
server_id = "cn_gf01"
@@ -57,21 +57,17 @@ async def get_user_memo(user_id: int, uid: int,
return await parse_data_and_draw(user_id, uid, server_id, uname)
async def get_memo(uid: str, server_id: str) -> "Union[str, dict], int":
async def get_memo(uid: str, server_id: str) -> Tuple[Union[str, dict], int]:
try:
req = await AsyncHttpx.get(
url=
f"https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/dailyNote?server={server_id}&role_id={uid}",
url=f"https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/dailyNote?server={server_id}&role_id={uid}",
headers={
"DS": get_ds(f"role_id={uid}&server={server_id}"),
"x-rpc-app_version": Config.get_config("genshin",
"mhyVersion"),
"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": Config.get_config("genshin",
"client_type"),
"x-rpc-app_version": Config.get_config("genshin", "mhyVersion"),
"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": Config.get_config("genshin", "client_type"),
"Referer": "https://webstatic.mihoyo.com/",
"Cookie": await Genshin.get_user_cookie(int(uid))
"Cookie": await Genshin.random_cookie(uid),
},
)
data = req.json()
@@ -85,18 +81,13 @@ async def get_memo(uid: str, server_id: str) -> "Union[str, dict], int":
return "发生了一些错误,请稍后再试", 998
def create_border(image_name: str, content: str, notice_text: str,
value: str) -> BuildImage:
border = BuildImage(500,
75,
color="#E0D9D1",
font="HYWenHei-85W.ttf",
font_size=20)
text_bk = BuildImage(350,
75,
color="#F5F1EB",
font_size=23,
font="HYWenHei-85W.ttf")
def create_border(
image_name: str, content: str, notice_text: str, value: str
) -> BuildImage:
border = BuildImage(500, 75, color="#E0D9D1", font="HYWenHei-85W.ttf", font_size=20)
text_bk = BuildImage(
350, 75, color="#F5F1EB", font_size=23, font="HYWenHei-85W.ttf"
)
_x = 70 if image_name == "resin.png" else 50
_px = 10 if image_name == "resin.png" else 20
text_bk.paste(
@@ -119,15 +110,14 @@ def create_border(image_name: str, content: str, notice_text: str,
True,
)
font_width, _ = border.getsize(value)
border.text((350 + 76 - int(font_width / 2), 0),
value,
center_type="by_height")
border.text((350 + 76 - int(font_width / 2), 0), value, center_type="by_height")
border.paste(text_bk, (2, 0), center_type="by_height")
return border
async def parse_data_and_draw(user_id: int, uid: str, server_id: str,
uname: str) -> Union[str, MessageSegment]:
async def parse_data_and_draw(
user_id: int, uid: str, server_id: str, uname: str
) -> Union[str, MessageSegment]:
data, code = await get_memo(uid, server_id)
if code != 200:
return data
@@ -138,11 +128,13 @@ async def parse_data_and_draw(user_id: int, uid: str, server_id: str,
if not role_avatar.exists():
await AsyncHttpx.download_file(x["avatar_side_icon"], role_avatar)
return await asyncio.get_event_loop().run_in_executor(
None, _parse_data_and_draw, data, user_avatar, uid, uname)
None, _parse_data_and_draw, data, user_avatar, uid, uname
)
def _parse_data_and_draw(data: dict, user_avatar: BytesIO, uid: int,
uname: str) -> Union[str, MessageSegment]:
def _parse_data_and_draw(
data: dict, user_avatar: BytesIO, uid: int, uname: str
) -> Union[str, MessageSegment]:
current_resin = data["current_resin"] # 当前树脂
max_resin = data["max_resin"] # 最大树脂
resin_recovery_time = data["resin_recovery_time"] # 树脂全部回复时间
@@ -157,33 +149,24 @@ def _parse_data_and_draw(data: dict, user_avatar: BytesIO, uid: int,
max_coin = data["max_home_coin"] # 最大宝钱
coin_recovery_time = data["home_coin_recovery_time"] # 宝钱全部回复时间
transformer_available = data["transformer"]["obtained"] # 参量质变仪可获取
transformer_state = data["transformer"]["recovery_time"][
"reached"] # 参量质变仪状态
transformer_recovery_time = data["transformer"]["recovery_time"][
"Day"] # 参量质变仪回复时间
transformer_state = data["transformer"]["recovery_time"]["reached"] # 参量质变仪状态
transformer_recovery_time = data["transformer"]["recovery_time"]["Day"] # 参量质变仪回复时间
transformer_recovery_hour = data["transformer"]["recovery_time"][
"Hour"] # 参量质变仪回复时间
"Hour"
] # 参量质变仪回复时间
coin_minute, coin_second = divmod(int(coin_recovery_time), 60)
coin_hour, coin_minute = divmod(coin_minute, 60)
#print(data)
# print(data)
minute, second = divmod(int(resin_recovery_time), 60)
hour, minute = divmod(minute, 60)
A = BuildImage(1030,
570,
color="#f1e9e1",
font_size=15,
font="HYWenHei-85W.ttf")
A = BuildImage(1030, 570, color="#f1e9e1", font_size=15, font="HYWenHei-85W.ttf")
A.text((10, 15), "原神便笺 | Create By ZhenXun", (198, 186, 177))
ava = BuildImage(100, 100, background=user_avatar)
ava.circle()
A.paste(ava, (40, 40), True)
A.paste(
BuildImage(0,
0,
plain_text=uname,
font_size=20,
font="HYWenHei-85W.ttf"),
BuildImage(0, 0, plain_text=uname, font_size=20, font="HYWenHei-85W.ttf"),
(160, 62),
True,
)
@@ -225,40 +208,39 @@ def _parse_data_and_draw(data: dict, user_avatar: BytesIO, uid: int,
"chengehu.png",
"洞天财翁-洞天宝钱",
"洞天财翁已达到存储上限"
if current_coin == max_coin else f"{coin_hour}小时{coin_minute}分钟后存满",
if current_coin == max_coin
else f"{coin_hour}小时{coin_minute}分钟后存满",
f"{current_coin}/{max_coin}",
)
A.paste(border, (10, 395))
border = create_border(
"zhibian.png",
"参量质变仪",
"不存在" if not transformer_available else
"已准备完成 " if transformer_state else f"{transformer_recovery_hour}小时后可使用" if not transformer_recovery_time else f"{transformer_recovery_time}天后可使用",
"不存在" if not transformer_available else
"可使用" if transformer_state else "冷却中",
"不存在"
if not transformer_available
else "已准备完成 "
if transformer_state
else f"{transformer_recovery_hour}小时后可使用"
if not transformer_recovery_time
else f"{transformer_recovery_time}天后可使用",
"不存在" if not transformer_available else "可使用" if transformer_state else "冷却中",
)
A.paste(border, (10, 475))
expeditions_border = BuildImage(470,
510,
color="#E0D9D1",
font="HYWenHei-85W.ttf",
font_size=20)
expeditions_text = BuildImage(466,
506,
color="#F5F1EB",
font_size=23,
font="HYWenHei-85W.ttf")
expeditions_border = BuildImage(
470, 510, color="#E0D9D1", font="HYWenHei-85W.ttf", font_size=20
)
expeditions_text = BuildImage(
466, 506, color="#F5F1EB", font_size=23, font="HYWenHei-85W.ttf"
)
expeditions_text.text(
(5, 5), f"探索派遣限制{current_expedition_num}/{max_expedition_num}",
(100, 100, 98))
(5, 5), f"探索派遣限制{current_expedition_num}/{max_expedition_num}", (100, 100, 98)
)
h = 45
for x in expeditions:
_bk = BuildImage(400,
82,
color="#ECE3D8",
font="HYWenHei-85W.ttf",
font_size=21)
_bk = BuildImage(
400, 82, color="#ECE3D8", font="HYWenHei-85W.ttf", font_size=21
)
file_name = x["avatar_side_icon"].split("_")[-1]
role_avatar = memo_path / "role_avatar" / file_name
_ava_img = BuildImage(75, 75, background=role_avatar)
@@ -1,11 +1,13 @@
from httpx import ConnectError
from nonebot import on_command
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 is_number
from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message, MessageEvent
from nonebot.params import CommandArg
from services.log import logger
from utils.utils import is_number
from .._models import Genshin
from .data_source import query_role_data
__zx_plugin_name__ = "原神玩家查询"
__plugin_usage__ = """
@@ -29,7 +31,9 @@ __plugin_settings__ = {
__plugin_block_limit__ = {}
query_role_info_matcher = on_command("原神玩家查询", aliases={"原神玩家查找", "ys"}, priority=5, block=True)
query_role_info_matcher = on_command(
"原神玩家查询", aliases={"原神玩家查找", "ys"}, priority=5, block=True
)
@query_role_info_matcher.handle()
@@ -39,24 +43,25 @@ async def _(event: MessageEvent, arg: Message = CommandArg()):
if not is_number(msg):
await query_role_info_matcher.finish("查询uid必须为数字!")
msg = int(msg)
if not msg:
uid = await Genshin.get_user_uid(event.user_id)
uid = None
user = await Genshin.get_or_none(user_qq=event.user_id)
if not msg and user:
uid = user.uid
else:
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 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:
await query_role_info_matcher.send(data)
logger.info(
f"(USER {event.user_id}, "
f"GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 使用原神玩家查询 uid:{uid}"
)
else:
await query_role_info_matcher.send("查询失败..")
mys_id = user.mys_id if user else None
try:
data = await query_role_data(event.user_id, uid, mys_id, nickname)
if data:
await query_role_info_matcher.send(data)
logger.info(
f"(USER {event.user_id}, "
f"GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 使用原神玩家查询 uid:{uid}"
)
else:
await query_role_info_matcher.send("查询失败..")
except ConnectError:
await query_role_info_matcher.send("网络出小差啦~")
@@ -1,11 +1,14 @@
from typing import Optional, List, Dict, Union
from .draw_image import init_image, get_genshin_image
from typing import Dict, List, Optional, Tuple, Union
from nonebot.adapters.onebot.v11 import MessageSegment
from .._utils import get_ds, element_mastery
from configs.config import Config
from services.log import logger
from utils.http_utils import AsyncHttpx
from configs.config import Config
from .._models import Genshin
from .._utils import element_mastery, get_ds
from .draw_image import get_genshin_image, init_image
try:
import ujson as json
@@ -96,66 +99,66 @@ b=body q=query
"""
async def get_info(uid_: str, server_id: str) -> "Optional[Union[dict, str]], int":
try:
req = await AsyncHttpx.get(
url=f"https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/index?server={server_id}&role_id={uid_}",
headers={
"Accept": "application/json, text/plain, */*",
"DS": get_ds(f"role_id={uid_}&server={server_id}"),
"Origin": "https://webstatic.mihoyo.com",
"x-rpc-app_version": Config.get_config("genshin", "mhyVersion"),
"User-Agent": "Mozilla/5.0 (Linux; Android 9; Unspecified Device) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36 miHoYoBBS/2.2.0",
"x-rpc-client_type": Config.get_config("genshin", "client_type"),
"Referer": "https://webstatic.mihoyo.com/app/community-game-records/index.html?v=6",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,en-US;q=0.8",
"X-Requested-With": "com.mihoyo.hyperion",
"Cookie": await Genshin.get_user_cookie(int(uid_))
},
)
data = req.json()
if data["message"] == "OK":
return data["data"], 200
return data["message"], 999
except Exception as e:
logger.error(f"访问失败,请重试! {type(e)}: {e}")
async def get_info(uid_: str, server_id: str) -> Tuple[Optional[Union[dict, str]], int]:
# try:
req = await AsyncHttpx.get(
url=f"https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/index?server={server_id}&role_id={uid_}",
headers={
"Accept": "application/json, text/plain, */*",
"DS": get_ds(f"role_id={uid_}&server={server_id}"),
"Origin": "https://webstatic.mihoyo.com",
"x-rpc-app_version": Config.get_config("genshin", "mhyVersion"),
"User-Agent": "Mozilla/5.0 (Linux; Android 9; Unspecified Device) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36 miHoYoBBS/2.2.0",
"x-rpc-client_type": Config.get_config("genshin", "client_type"),
"Referer": "https://webstatic.mihoyo.com/app/community-game-records/index.html?v=6",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,en-US;q=0.8",
"X-Requested-With": "com.mihoyo.hyperion",
"Cookie": await Genshin.random_cookie(uid_),
},
)
data = req.json()
if data["message"] == "OK":
return data["data"], 200
return data["message"], 999
# except Exception as e:
# logger.error(f"访问失败,请重试! {type(e)}: {e}")
return None, -1
async def get_character(
uid: str, character_ids: List[str], server_id="cn_gf01"
) -> Optional[dict]:
try:
req = await AsyncHttpx.post(
url="https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/character",
headers={
"Accept": "application/json, text/plain, */*",
"DS": get_ds(
"",
{
"character_ids": character_ids,
"role_id": uid,
"server": server_id,
},
),
"Origin": "https://webstatic.mihoyo.com",
"Cookie": await Genshin.get_user_cookie(int(uid)),
"x-rpc-app_version": Config.get_config("genshin", "mhyVersion"),
"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/",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,en-US;q=0.8",
"X-Requested-With": "com.mihoyo.hyperion",
},
json={"character_ids": character_ids, "role_id": uid, "server": server_id},
)
data = req.json()
if data["message"] == "OK":
return data["data"]
except Exception as e:
logger.error(f"访问失败,请重试! {type(e)}: {e}")
# try:
req = await AsyncHttpx.post(
url="https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/character",
headers={
"Accept": "application/json, text/plain, */*",
"DS": get_ds(
"",
{
"character_ids": character_ids,
"role_id": uid,
"server": server_id,
},
),
"Origin": "https://webstatic.mihoyo.com",
"Cookie": await Genshin.random_cookie(uid),
"x-rpc-app_version": Config.get_config("genshin", "mhyVersion"),
"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/",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,en-US;q=0.8",
"X-Requested-With": "com.mihoyo.hyperion",
},
json={"character_ids": character_ids, "role_id": uid, "server": server_id},
)
data = req.json()
if data["message"] == "OK":
return data["data"]
# except Exception as e:
# logger.error(f"访问失败,请重试! {type(e)}: {e}")
return None
@@ -205,7 +208,7 @@ def parsed_data(
"image": world["icon"],
"name": world["name"],
"offerings": world["offerings"],
"icon": world["icon"]
"icon": world["icon"],
}
world_data_dict[world["name"]] = _x
home_data_list = []
@@ -231,21 +234,21 @@ async def get_mys_data(uid: str, mys_id: Optional[str]) -> Optional[List[Dict]]:
:param mys_id: 米游社id
"""
if mys_id:
try:
req = await AsyncHttpx.get(
url=f"https://api-takumi-record.mihoyo.com/game_record/card/wapi/getGameRecordCard?uid={mys_id}",
headers={
"DS": get_ds(f"uid={mys_id}"),
"x-rpc-app_version": Config.get_config("genshin", "mhyVersion"),
"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/",
"Cookie": await Genshin.get_user_cookie(int(uid))
},
)
data = req.json()
if data["message"] == "OK":
return data["data"]["list"]
except Exception as e:
logger.error(f"访问失败,请重试! {type(e)}: {e}")
# try:
req = await AsyncHttpx.get(
url=f"https://api-takumi-record.mihoyo.com/game_record/card/wapi/getGameRecordCard?uid={mys_id}",
headers={
"DS": get_ds(f"uid={mys_id}"),
"x-rpc-app_version": Config.get_config("genshin", "mhyVersion"),
"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/",
"Cookie": await Genshin.random_cookie(uid),
},
)
data = req.json()
if data["message"] == "OK":
return data["data"]["list"]
# except Exception as e:
# logger.error(f"访问失败,请重试! {type(e)}: {e}")
return None
@@ -1,6 +1,7 @@
from utils.utils import scheduler
from .._models import Genshin
from services.log import logger
from utils.utils import scheduler
from .._models import Genshin
@scheduler.scheduled_job(
@@ -10,7 +11,7 @@ from services.log import logger
)
async def _():
try:
await Genshin.reset_today_query_uid()
await Genshin.all().update(today_query_uid="")
logger.warning(f"重置原神查询记录成功..")
except Exception as e:
logger.error(f"重置原神查询记录失败. {type(e)}:{e}")
@@ -1,12 +1,15 @@
from nonebot import on_command
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 nonebot.params import Command
from typing import Tuple
from apscheduler.jobstores.base import JobLookupError
from nonebot import on_command
from nonebot.adapters.onebot.v11 import GroupMessageEvent, MessageEvent
from nonebot.params import Command
from services.log import logger
from utils.depends import OneCommand
from .._models import Genshin
from .init_task import add_job, scheduler
__zx_plugin_name__ = "原神树脂提醒"
__plugin_usage__ = """
@@ -33,31 +36,32 @@ __plugin_configs__ = {
"AUTO_CLOSE_QUERY_FAIL_RESIN_REMIND": {
"value": True,
"help": "当请求连续三次失败时,关闭用户的树脂提醒",
"default_value": True
"default_value": True,
},
"CUSTOM_RESIN_OVERFLOW_REMIND": {
"value": 20,
"help": "自定义树脂溢出指定数量时的提醒,空值是为关闭",
"default_value": None
}
"default_value": None,
},
}
resin_remind = on_command("开原神树脂提醒", aliases={"关原神树脂提醒"}, priority=5, block=True)
@resin_remind.handle()
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):
async def _(event: MessageEvent, cmd: str = OneCommand()):
user = await Genshin.get_or_none(user_qq=event.user_id)
if not user or not user.uid or not user.cookie:
await resin_remind.finish("请先绑定uid和cookie!")
try:
scheduler.remove_job(f"genshin_resin_remind_{uid}_{event.user_id}")
scheduler.remove_job(f"genshin_resin_remind_{user.uid}_{event.user_id}")
except JobLookupError:
pass
if cmd[0] == "开":
await Genshin.set_resin_remind(uid, True)
add_job(event.user_id, uid)
if user.resin_remind:
await resin_remind.finish("原神树脂提醒已经是开启状态,请勿重复开启!", at_sender=True)
user.resin_remind = True
add_job(event.user_id, user.uid)
logger.info(
f"(USER {event.user_id}, GROUP "
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
@@ -65,12 +69,15 @@ async def _(event: MessageEvent, cmd: Tuple[str, ...] = Command()):
)
await resin_remind.send("开启原神树脂提醒成功!", at_sender=True)
else:
await Genshin.set_resin_remind(uid, False)
await Genshin.clear_resin_remind_time(uid)
if not user.resin_remind:
await resin_remind.finish("原神树脂提醒已经是开启状态,请勿重复开启!", at_sender=True)
user.resin_remind = False
user.resin_recovery_time = None
logger.info(
f"(USER {event.user_id}, GROUP "
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 关闭原神体力提醒"
)
await resin_remind.send("已关闭原神树脂提醒..", at_sender=True)
if user:
await user.save(update_fields=["resin_remind", "resin_recovery_time"])
@@ -1,20 +1,20 @@
from nonebot.adapters.onebot.v11 import ActionFailed
from utils.utils import get_bot, scheduler
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 datetime import datetime, timedelta
from apscheduler.jobstores.base import JobLookupError
from services.log import logger
from nonebot.plugin import require
from configs.config import Config
import random
from datetime import datetime, timedelta
import nonebot
import pytz
from apscheduler.jobstores.base import ConflictingIdError, JobLookupError
from nonebot import Driver
from nonebot.adapters.onebot.v11 import ActionFailed
from nonebot.plugin import require
from configs.config import Config
from models.group_member_info import GroupInfoUser
from services.log import logger
from utils.message_builder import at
from utils.utils import get_bot, scheduler
from .._models import Genshin
driver: Driver = nonebot.get_driver()
@@ -23,7 +23,6 @@ require("query_memo")
from ..query_memo import get_memo
global_map = {}
@@ -80,12 +79,13 @@ async def _():
"""
启动时分配定时任务
"""
g_list = await Genshin.get_all_resin_remind_user()
g_list = await Genshin.filter(resin_remind=True).all()
update_list = []
date = datetime.now(pytz.timezone("Asia/Shanghai")) + timedelta(seconds=30)
for u in g_list:
if u.resin_remind:
if u.resin_recovery_time:
if await Genshin.get_user_resin_recovery_time(u.uid) > datetime.now(
if u.resin_recovery_time and u.resin_recovery_time > datetime.now(
pytz.timezone("Asia/Shanghai")
):
# date = await Genshin.get_user_resin_recovery_time(u.uid) # 不能要,因为可能在这期间用户使用了树脂
@@ -101,7 +101,8 @@ async def _():
f"genshin_resin_remind add_job:USER:{u.user_qq} UID:{u.uid}启动原神树脂提醒 "
)
else:
await Genshin.clear_resin_remind_time(u.uid)
u.resin_recovery_time = None
update_list.append(u)
add_job(u.user_qq, u.uid)
logger.info(
f"genshin_resin_remind add_job CHECK:USER:{u.user_qq} UID:{u.uid}启动原神树脂提醒 "
@@ -111,6 +112,8 @@ async def _():
logger.info(
f"genshin_resin_remind add_job CHECK:USER:{u.user_qq} UID:{u.uid}启动原神树脂提醒 "
)
if update_list:
await Genshin.bulk_update(update_list, ["resin_recovery_time"])
def add_job(user_id: int, uid: int):
@@ -133,6 +136,7 @@ def add_job(user_id: int, uid: int):
async def _remind(user_id: int, uid: str):
user = await Genshin.get_or_none(user_qq=user_id, uid=int(uid))
uid = str(uid)
if uid[0] in ["1", "2"]:
server_id = "cn_gf01"
@@ -158,7 +162,9 @@ async def _remind(user_id: int, uid: str):
elif max_resin - 20 <= current_resin < max_resin:
next_time = now + timedelta(minutes=(max_resin - current_resin) * 8)
elif current_resin == max_resin:
custom_overflow_resin = Config.get_config("resin_remind", "CUSTOM_RESIN_OVERFLOW_REMIND")
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)
@@ -178,28 +184,35 @@ async def _remind(user_id: int, uid: str):
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:
group_id = group_list[0]
try:
await bot.send_group_msg(
group_id=group_id,
message=at(user_id) + msg
)
except ActionFailed as e:
logger.error(f"树脂提醒推送发生错误 {type(e)}:{e}")
if user:
group_id = user.bind_group
if not group_id:
if group_list := await GroupInfoUser.get_user_all_group(
user_id
):
group_id = group_list[0]
try:
await bot.send_group_msg(
group_id=group_id, message=at(user_id) + msg
)
except ActionFailed as e:
logger.error(f"树脂提醒推送发生错误 {type(e)}:{e}")
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))
if user_manager.check(uid) and Config.get_config(
"resin_remind", "AUTO_CLOSE_QUERY_FAIL_RESIN_REMIND"
):
if user:
user.resin_remind = False
user.resin_recovery_time = None
await user.save(update_fields=["resin_recovery_time", "resin_remind"])
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)
if user:
user.resin_recovery_time = next_time
await user.save(update_fields=["resin_recovery_time", "resin_remind"])
scheduler.add_job(
_remind,
"date",
@@ -208,6 +221,5 @@ async def _remind(user_id: int, uid: str):
args=[user_id, uid],
)
logger.info(
f"genshin_resin_remind add_job:USER:{user_id} UID:{uid} "
f"{next_time} 原神树脂提醒"
)
f"genshin_resin_remind add_job:USER:{user_id} UID:{uid} " f"{next_time} 原神树脂提醒"
)