Compare commits

...
17 Commits
Author SHA1 Message Date
HibiKier 0b65ac2126 Update config.py 2021-08-10 23:12:43 +08:00
HibiKier 3611678e13 Update README.md 2021-08-10 23:04:58 +08:00
hibiki 5ec89e7538 fix 2021-08-10 23:03:46 +08:00
HibiKier 96dc1d9851 Update data_source.py 2021-08-09 07:50:33 +08:00
HibiKier 7148940a2f Update data_source.py 2021-08-09 07:50:04 +08:00
HibiKier 0455cba221 Update README.md 2021-08-07 22:36:54 +08:00
HibiKier b5f1d1ac21 Update README.md 2021-08-06 23:02:43 +08:00
HibiKier a628f7ab26 Update data_source.py 2021-08-06 21:27:55 +08:00
HibiKier ee6e185df7 Update __init__.py 2021-08-06 21:05:24 +08:00
HibiKier e1d7f31456 Update __init__.py 2021-08-06 20:14:48 +08:00
HibiKier e4fdfd0a21 Update README.md 2021-08-06 19:53:02 +08:00
HibiKier edd55f94e9 Update config.py 2021-08-06 19:47:01 +08:00
hibiki ee90fc3c14 add auto_update 2021-08-06 19:42:02 +08:00
HibiKier c96969e86c Update config.py 2021-08-06 14:46:30 +08:00
HibiKier 88ac572d51 Update config.py 2021-08-06 14:40:52 +08:00
HibiKier 10b7cbaa71 Update update_info.json 2021-08-06 13:55:24 +08:00
HibiKier 3b649172a8 Update update_info.json 2021-08-06 12:25:40 +08:00
23 changed files with 731 additions and 138 deletions
+22 -3
View File
@@ -41,10 +41,10 @@
- [x] 构造假消息(自定义的分享链接)
- [x] 商店/我的金币/购买道具/使用道具
- [x] 8种手游抽卡 (查看 [nonebot_plugin_gamedraw](https://github.com/HibiKier/nonebot_plugin_gamedraw))
- [x] 我有一个朋友想问问..(pcrbot插件..彻底重写)
- [x] 我有一个朋友想问问..(借鉴pcrbot插件)
- [x] 原神黄历 (使用[Genshin_Impact_bot](https://github.com/H-K-Y/Genshin_Impact_bot)插件)
- [x] 原神今日素材 (原[Genshin_Impact_bot](https://github.com/H-K-Y/Genshin_Impact_bot)插件,彻底重写,实现方法改为网页截图)
- [x] 原神资源查询 (使用[Genshin_Impact_bot](https://github.com/H-K-Y/Genshin_Impact_bot)插件,资源下载优化为异步下载)
- [x] 原神今日素材
- [x] 原神资源查询 (借鉴[Genshin_Impact_bot](https://github.com/H-K-Y/Genshin_Impact_bot)插件)
- [x] 金币红包
- [x] pil对图片的一些操作
@@ -232,6 +232,7 @@
|删除pix图片 | 删除pix图片 [*pid] [-b]? | [-b]参数为删除的同时加入黑名单(不再更新),虽然是pid,但是_p也可以<br>示例:删除pix图片3458344 8235234_p1 -b
|显示pix关键词 | 显示pix关键词 | 与普通功能相同,额外显示待收录和黑名单
|pix检测更新 | pix检测更新 [update]? | 检测从未更新过的pid或uid,-update参数将在检测后直接更新未更新过的pid或uid<br>示例:pix检测更新 update
| 检查更新真寻 | 检查更新真寻 | 不再需要麻烦的clone第一步
</details>
@@ -652,6 +653,24 @@ python bot.py
## 更新
### 2021/8/10
* 重复的好友请求和邀群提示在5分钟内不会重复提示
* 疫情会优先检查城市,城市省份重名时请添加‘省’
* 添加命令‘原神资源查找’,‘设置cookie’
* 添加配置AUTO_UPDATE_ZHENXUN,是否自动更新真寻,默认True
* 添加配置MAX_RUSSIAN_BET_GOLD,俄罗斯轮盘赌注最大金额,默认1000
* 检查更新真寻定时任务时间改为每日12 : 00
* 添加功能能不能好好说话(nbnhhsh)
* 添加功能随机roll,无参为数字,有参为随机参数
* 添加linux重启脚本以及重启命令‘重启’(建议首次生成restart.sh先查看命令是否正确)
### 2021/8/6
* 天气查询会优先遍历城市
* 添加自动更新真寻命令
##### 如果你的版本为 2021/8/4,可以直接复制plugins/check_zhenxun_update后,通过指令来更新真寻
### 2021/8/4
* 修改天气与疫情城市数据,改为api获取,丰富疫情的回复消息
+15 -12
View File
@@ -67,6 +67,7 @@ SEMAPHORE = 5 # 限制碧蓝航线和FGO并发数
ADMIN_DEFAULT_AUTH: int = 5 # 默认群管理员权限
MAX_SIGN_GOLD: int = 200 # 签到好感度加成额外获得的最大金币数
MAX_RUSSIAN_BET_GOLD: int = 1000 # 俄罗斯轮盘最大赌注金额
INITIAL_SETU_PROBABILITY: float = 0.7 # 色图概率
FUDU_PROBABILITY: float = 0.7 # 复读概率
@@ -109,6 +110,8 @@ AUTO_ADD_FRIEND: bool = True
ALAPI_AI_CHECK: bool = True
# 导入商店自带的三个商品
IMPORT_DEFAULT_SHOP_GOODS: bool = True
# 真寻是否自动更新
AUTO_UPDATE_ZHENXUN: bool = True
# 群管理员功能 与 对应权限
admin_plugins_auth = {
@@ -198,15 +201,15 @@ HIBIAPI = HIBIAPI[:-1] if HIBIAPI[-1] == "/" else HIBIAPI
RSSHUBAPP = RSSHUBAPP[:-1] if RSSHUBAPP[-1] == "/" else RSSHUBAPP
# 配置文件应用
if USE_CONFIG_FILE:
config = get_config_data()
if config:
for key in config.keys():
if isinstance(config[key], str):
config[key] = config[key].strip()
if key.find("proxy") != -1:
if not config[key]:
config[key] = None
# if not configs[key] and key.find("PATH") == -1:
# configs[key] = None
globals().update(config)
# if USE_CONFIG_FILE:
# config = get_config_data()
# if config:
# for key in config.keys():
# if isinstance(config[key], str):
# config[key] = config[key].strip()
# if key.find("proxy") != -1:
# if not config[key]:
# config[key] = None
# # if not configs[key] and key.find("PATH") == -1:
# # configs[key] = None
# globals().update(config)
+29 -3
View File
@@ -1,5 +1,6 @@
from typing import Optional, List
from services.db_context import db
import asyncio
class Pixiv(db.Model):
@@ -158,8 +159,33 @@ class Pixiv(db.Model):
:param keyword: 关键词/Tag
"""
query = await cls.query.gino.all()
query = [x for x in query if set(x.tags.split(',')) > set(keyword)]
r18_count = len([x for x in query if x.is_r18])
return len(query) - r18_count, r18_count
i = int(len(query) / 200)
mod = len(query) % 200
tasks = []
start = 0
end = 200
count = 0
r18_count = 0
for _ in range(i):
tasks.append(asyncio.ensure_future(split_query_list(query[start: end], keyword)))
start += 200
end += 200
if mod:
tasks.append(asyncio.ensure_future(split_query_list(query[end:], keyword)))
result = await asyncio.gather(*tasks)
for x, j in result:
count += x
r18_count += j
# query = [x for x in query if set(x.tags.split(',')) > set(keyword)]
# r18_count = len([x for x in query if x.is_r18])
return count, r18_count
async def split_query_list(query: List['Pixiv'], keyword: List[str]) -> 'int, int':
return await asyncio.get_event_loop().run_in_executor(None, _split_query_list, query, keyword)
def _split_query_list(query: List['Pixiv'], keyword: List[str]) -> 'int, int':
query = [x for x in query if set(x.tags.split(',')) > set(keyword)]
r18_count = len([x for x in query if x.is_r18])
return len(query) - r18_count, r18_count
+43 -36
View File
@@ -5,33 +5,36 @@ from datetime import datetime
from configs.config import AUTO_ADD_FRIEND
from nonebot.adapters.cqhttp.exception import ActionFailed
from utils.utils import scheduler
import time
__plugin_name__ = "好友群聊处理请求 [Hidden]"
friend_req = on_request(priority=5)
exists_list = []
exists_data = {"private": {}, "group": {}}
@friend_req.handle()
async def _(bot: Bot, event: FriendRequestEvent, state: dict):
global exists_list
if f"{event.user_id}" not in exists_list:
exists_list.append(f"{event.user_id}")
user = await bot.get_stranger_info(user_id=event.user_id)
nickname = user["nickname"]
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f"*****一份好友申请*****\n"
f"昵称:{nickname}({event.user_id})\n"
f"自动同意:{'√' if AUTO_ADD_FRIEND else '×'}\n"
f"日期:{str(datetime.now()).split('.')[0]}\n"
f"备注:{event.comment}",
)
if AUTO_ADD_FRIEND:
await bot.set_friend_add_request(flag=event.flag, approve=True)
await FriendUser.add_friend_info(user["user_id"], user["nickname"])
global exists_data
if exists_data["private"].get(event.user_id):
if time.time() - exists_data["private"][event.user_id] < 60 * 5:
return
exists_data["private"][event.user_id] = time.time()
user = await bot.get_stranger_info(user_id=event.user_id)
nickname = user["nickname"]
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f"*****一份好友申请*****\n"
f"昵称:{nickname}({event.user_id})\n"
f"自动同意:{'√' if AUTO_ADD_FRIEND else '×'}\n"
f"日期:{str(datetime.now()).split('.')[0]}\n"
f"备注:{event.comment}",
)
if AUTO_ADD_FRIEND:
await bot.set_friend_add_request(flag=event.flag, approve=True)
await FriendUser.add_friend_info(user["user_id"], user["nickname"])
group_req = on_request(priority=5, block=True)
@@ -39,7 +42,7 @@ group_req = on_request(priority=5, block=True)
@group_req.handle()
async def _(bot: Bot, event: GroupRequestEvent, state: dict):
global exists_list
global exists_data
if event.sub_type == "invite":
if str(event.user_id) in bot.config.superusers:
try:
@@ -49,22 +52,26 @@ async def _(bot: Bot, event: GroupRequestEvent, state: dict):
except ActionFailed:
pass
else:
if f"{event.user_id}:{event.group_id}" not in exists_list:
exists_list.append(f"{event.user_id}:{event.group_id}")
nickname = await FriendUser.get_user_name(event.user_id)
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f"*****一份入群申请*****\n"
f"申请人:{nickname}({event.user_id})\n"
f"群聊:{event.group_id}\n"
f"邀请日期:{str(datetime.now()).split('.')[0]}",
)
await bot.send_private_msg(
user_id=event.user_id,
message="想要邀请我偷偷入群嘛~已经提醒真寻的管理员大人了\n"
"请确保已经群主或群管理沟通过!\n"
"等待管理员处理吧!",
)
if exists_data["group"].get(f"{event.user_id}:{event.group_id}"):
if (
time.time()
- exists_data["group"][f"{event.user_id}:{event.group_id}"]
< 60 * 5
):
return
exists_data["group"][f"{event.user_id}:{event.group_id}"] = time.time()
nickname = await FriendUser.get_user_name(event.user_id)
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f"*****一份入群申请*****\n"
f"申请人:{nickname}({event.user_id})\n"
f"群聊:{event.group_id}\n"
f"邀请日期:{str(datetime.now()).split('.')[0]}",
)
await bot.send_private_msg(
user_id=event.user_id,
message="想要邀请我偷偷入群嘛~已经提醒真寻的管理员大人了\n" "请确保已经群主或群管理沟通过!\n" "等待管理员处理吧!",
)
@scheduler.scheduled_job(
@@ -72,5 +79,5 @@ async def _(bot: Bot, event: GroupRequestEvent, state: dict):
minutes=5,
)
async def _():
global exists_list
exists_list = []
global exists_data
exists_data = {"private": {}, "group": {}}
+14 -9
View File
@@ -33,8 +33,9 @@ ban = on_command(
@ban.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
result = ""
qq = get_message_at(event.json())[0]
qq = get_message_at(event.json())
if qq:
qq = qq[0]
user_name = await bot.get_group_member_info(group_id=event.group_id, user_id=qq)
user_name = user_name['card'] if user_name['card'] else user_name['nickname']
msg = get_message_text(event.json())
@@ -52,16 +53,16 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
time = -1
if state["_prefix"]["raw_command"] in [".ban", "/ban"]:
if (
await LevelUser.get_user_level(event.user_id, event.group_id)
<= await LevelUser.get_user_level(qq, event.group_id)
and str(event.user_id) not in bot.config.superusers
await LevelUser.get_user_level(event.user_id, event.group_id)
<= await LevelUser.get_user_level(qq, event.group_id)
and str(event.user_id) not in bot.config.superusers
):
await ban.finish(
f"您的权限等级比对方低或相等, {list(bot.config.nickname)[0]}不能为您使用此功能!",
at_sender=True,
)
if await BanUser.ban(
qq, await LevelUser.get_user_level(event.user_id, event.group_id), time
qq, await LevelUser.get_user_level(event.user_id, event.group_id), time
):
logger.info(
f"USER {event.user_id} GROUP {event.group_id} 将 USER {qq} 封禁 时长 {time/60} 分钟"
@@ -82,10 +83,10 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
result = f"{user_name} 已在黑名单!预计 {time}后解封"
else:
if (
await BanUser.check_ban_level(
qq, await LevelUser.get_user_level(event.user_id, event.group_id)
)
and str(event.user_id) not in bot.config.superusers
await BanUser.check_ban_level(
qq, await LevelUser.get_user_level(event.user_id, event.group_id)
)
and str(event.user_id) not in bot.config.superusers
):
await ban.finish(
f"ban掉 {user_name} 的管理员权限比您高,无法进行unban", at_sender=True
@@ -100,3 +101,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
else:
await ban.finish("艾特人了吗??", at_sender=True)
await ban.finish(result, at_sender=True)
+94
View File
@@ -0,0 +1,94 @@
from nonebot.adapters.cqhttp import Bot, MessageEvent
from nonebot.typing import T_State
from nonebot.permission import SUPERUSER
from nonebot import on_command
from .data_source import check_update, get_latest_version
from services.log import logger
from utils.utils import scheduler, get_bot
from pathlib import Path
from configs.config import AUTO_UPDATE_ZHENXUN
from nonebot.rule import to_me
import platform
import os
update_zhenxun = on_command('检查更新真寻', permission=SUPERUSER, priority=1, block=True)
restart = on_command('重启', aliases={'restart'}, permission=SUPERUSER, rule=to_me(), priority=1, block=True)
@update_zhenxun.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
try:
code = await check_update(bot)
except Exception as e:
logger.error(f'更新真寻未知错误 {type(e)}:{e}')
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f'更新真寻未知错误 {type(e)}:{e}'
)
else:
if code == 200:
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f'更新完毕,请重启真寻....'
)
@restart.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
if str(platform.system()).lower() == 'windows':
await restart.finish('暂无windows重启脚本...')
@restart.got('flag', prompt='确定是否重启真寻?(重启失败咱们将失去联系,请谨慎!)')
async def _(bot: Bot, event: MessageEvent, state: T_State):
flag = state['flag']
if flag.lower() in ['true', '是', '好']:
await restart.send('开始重启真寻..请稍等...')
open('is_restart', 'w')
os.system('./restart.sh')
else:
await restart.send('已取消操作...')
@scheduler.scheduled_job(
"cron",
hour=12,
minute=0,
)
async def _():
if AUTO_UPDATE_ZHENXUN:
_version = "v0.0.0"
_version_file = Path() / "__version__"
if _version_file.exists():
_version = (
open(_version_file, "r", encoding="utf8").readline().split(":")[-1].strip()
)
latest_version, tar_gz_url = await get_latest_version()
if latest_version and tar_gz_url:
if _version != latest_version:
bot = get_bot()
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f'检测到真寻版本更新\n'
f'当前版本:{_version},最新版本:{latest_version}\n'
f'尝试自动更新...'
)
try:
code = await check_update(bot)
except Exception as e:
logger.error(f'更新真寻未知错误 {type(e)}:{e}')
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f'更新真寻未知错误 {type(e)}:{e}\n'
)
else:
if code == 200:
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f'更新完毕,请重启真寻....'
)
+268
View File
@@ -0,0 +1,268 @@
from aiohttp.client_exceptions import ClientConnectorError
from nonebot.adapters.cqhttp import Bot
from utils.user_agent import get_user_agent
from utils.utils import get_local_proxy, get_bot
from typing import List
from bs4.element import Tag
from services.log import logger
from bs4 import BeautifulSoup
from pathlib import Path
import ujson as json
import nonebot
import asyncio
import aiofiles
import aiohttp
import platform
import tarfile
import shutil
import os
if str(platform.system()).lower() == "windows":
policy = asyncio.WindowsSelectorEventLoopPolicy()
asyncio.set_event_loop_policy(policy)
driver = nonebot.get_driver()
version_url = "https://github.com/HibiKier/zhenxun_bot/releases"
main_url = "https://github.com/HibiKier/zhenxun_bot"
_version_file = Path() / "__version__"
zhenxun_latest_tar_gz = Path() / "zhenxun_latest_file.tar.gz"
temp_dir = Path() / "temp"
backup_dir = Path() / "backup"
@driver.on_startup
def init():
if str(platform.system()).lower() != "windows":
restart = Path() / "restart.sh"
env_file = Path() / ".env.dev"
if not restart.exists() and env_file.exists():
with open(env_file, "r", encoding="utf8") as ef:
data = ef.readlines()
port = [x.split("=")[1].strip() for x in data if "port" in x.lower()][0]
with open(restart, "w", encoding="utf8") as f:
f.write(
"pid=$(netstat -tunlp | grep " + port + " | awk '{print $7}')\n"
"pid=${pid%/*}\n"
"kill -9 $pid\n"
"sleep 3\n"
"python3 bot.py"
)
os.system("chmod +x ./restart.sh")
logger.info("已自动生成 restart.sh(重启) 文件,请检查是否与本地指令符合...")
@driver.on_bot_connect
async def remind(bot: Bot):
is_restart_file = Path() / 'is_restart'
if is_restart_file.exists():
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f"真寻重启完毕...",
)
is_restart_file.unlink()
async def check_update(bot: Bot) -> int:
logger.info("开始检查更新真寻酱....")
_version = "v0.0.0"
if _version_file.exists():
_version = (
open(_version_file, "r", encoding="utf8").readline().split(":")[-1].strip()
)
latest_version, tar_gz_url = await get_latest_version()
if latest_version and tar_gz_url:
if _version != latest_version:
logger.info(f"检测真寻已更新,当前版本:{_version},最新版本:{latest_version}")
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f"检测真寻已更新,当前版本:{_version},最新版本:{latest_version}\n" f"开始更新.....",
)
logger.info(f"开始下载真寻最新版文件....")
if await download_latest_file(tar_gz_url):
logger.info("下载真寻最新版文件完成....")
await asyncio.get_event_loop().run_in_executor(
None, _file_handle, latest_version
)
logger.info("真寻更新完毕,清理文件完成....")
logger.info("开始获取真寻更新日志.....")
update_info = await get_updated_info()
if update_info:
logger.info("获取真寻更新日志成功...开始发送日志...")
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f"真寻更新完成,版本:{_version} -> {latest_version}\n"
f"更新日志:\n"
f"{update_info}",
)
else:
logger.warning("获取真寻更新日志失败...")
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f"真寻更新完成,版本:{_version} -> {latest_version}\n"
f"获取真寻更新日志失败...",
)
return 200
else:
logger.warning(f"下载真寻最新版本失败...版本号:{latest_version}")
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f"下载真寻最新版本失败...版本号:{latest_version}.",
)
else:
logger.info(f"自动获取真寻版本成功:{latest_version},当前版本为最新版,无需更新...")
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]),
message=f"自动获取真寻版本成功:{latest_version},当前版本为最新版,无需更新...",
)
else:
logger.warning("自动获取真寻版本失败....")
await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]), message=f"自动获取真寻版本失败...."
)
return 999
def _file_handle(latest_version: str):
if not temp_dir.exists():
temp_dir.mkdir(exist_ok=True, parents=True)
if backup_dir.exists():
shutil.rmtree(backup_dir)
backup_dir.mkdir(exist_ok=True, parents=True)
logger.info("开始解压真寻文件压缩包....")
tf = tarfile.open(zhenxun_latest_tar_gz)
tf.extractall(temp_dir)
logger.info("解压真寻文件压缩包完成....")
zhenxun_latest_file = Path(temp_dir) / f"zhenxun_bot-{latest_version[1:]}"
update_info_file = Path(zhenxun_latest_file) / "update_info.json"
update_info = json.load(open(update_info_file, "r", encoding="utf8"))
update_file = update_info["update_file"]
add_file = update_info["add_file"]
delete_file = update_info["delete_file"]
config_file = Path() / "configs" / "config.py"
config_path_file = Path() / "configs" / "config_path.py"
for file in delete_file + update_file:
file = Path() / file
backup_file = Path(backup_dir) / file
if file.exists():
backup_file.parent.mkdir(parents=True, exist_ok=True)
if backup_file.exists():
backup_file.unlink()
if file not in [config_file, config_path_file]:
os.rename(file.absolute(), backup_file.absolute())
else:
with open(file, "r", encoding="utf8") as rf:
data = rf.read()
with open(backup_file, "w", encoding="utf8") as wf:
wf.write(data)
logger.info(f"已备份文件:{file}")
for file in add_file + update_file:
new_file = Path(zhenxun_latest_file) / file
old_file = Path() / file
if old_file not in [config_file, config_path_file]:
if not old_file.exists() and new_file.exists():
os.rename(new_file.absolute(), old_file.absolute())
logger.info(f"已更新文件:{file}")
else:
tmp = ""
new_lines = open(new_file, "r", encoding="utf8").readlines()
old_lines = open(old_file, "r", encoding="utf8").readlines()
for nl in new_lines:
tmp += check_old_lines(old_lines, nl)
with open(file, "w", encoding="utf8") as f:
f.write(tmp)
if tf:
tf.close()
if temp_dir.exists():
shutil.rmtree(temp_dir)
if zhenxun_latest_tar_gz.exists():
zhenxun_latest_tar_gz.unlink()
local_update_info_file = Path() / "update_info.json"
if local_update_info_file.exists():
local_update_info_file.unlink()
with open(_version_file, "w", encoding="utf8") as f:
f.write(f"__version__: {latest_version}")
# 获取最新版本号
async def get_latest_version() -> "str, str":
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
for _ in range(3):
try:
async with session.get(version_url, proxy=get_local_proxy()) as res:
if res.status == 200:
soup = BeautifulSoup(await res.text(), "lxml")
div = soup.find("div", {"class": "release-entry"})
latest_version = (
div.find(
"div", {"class": "f1 flex-auto min-width-0 text-normal"}
)
.find("a")
.text
)
tar_gz_url = div.find_all(
"a", {"class": "d-flex flex-items-center"}
)[-1].get("href")
tar_gz_url = f"https://github.com{tar_gz_url}"
return latest_version, tar_gz_url
except (TimeoutError, ClientConnectorError):
pass
return "", ""
# 下载文件
async def download_latest_file(url_: str) -> bool:
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
for _ in range(3):
try:
async with session.get(url_, proxy=get_local_proxy()) as res:
if res.status == 200:
async with aiofiles.open(zhenxun_latest_tar_gz, "wb") as f:
await f.write(await res.read())
return True
except (TimeoutError, ClientConnectorError):
pass
return False
# 逐行检测
def check_old_lines(lines: List[str], line: str) -> str:
if "=" not in line:
return line
for l in lines:
if "=" in l and l.split("=")[0].strip() == line.split("=")[0].strip():
if len(l) > len(line):
return l
return line
async def get_updated_info() -> str:
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
for _ in range(3):
try:
async with session.get(main_url, proxy=get_local_proxy()) as res:
soup = BeautifulSoup(await res.text(), "lxml")
children_list = list(soup.find("article").children)
children_list = [x for x in children_list if x != "\n"]
for i, children in enumerate(children_list):
a = children.find("a")
if a and isinstance(a, Tag) and a.get("href") == "#更新":
update_info = ""
tmp_children_list = children_list[i:]
tmp_children_list = [
x for x in tmp_children_list if "ul" in str(x)
]
for j, chi in enumerate(tmp_children_list):
if "ul" in str(chi):
update_time = children_list[i:][j + 1].text
update_info += f"更新日期:{update_time}\n"
ul = children_list[i:][j + 2]
break
for li in ul.find_all("li"):
update_info += f"\t● {li.text}\n"
return update_info
except (TimeoutError, ClientConnectorError):
pass
return ""
+1 -1
View File
@@ -27,7 +27,7 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
if time.strftime("%w") == "0":
await material.send("今天是周日,所有材料副本都开放了。")
return
await material.send(Message(image('daily_material.png', 'genshin/material') + '\n※ 黄历数据来源于 genshin.pub'))
await material.send(Message(image('daily_material.png', 'genshin/material') + '\n※ 每日素材数据来源于 genshin.pub'))
logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})"
f" 发送查看今日素材")
+74 -34
View File
@@ -146,41 +146,81 @@ class Map:
# 生成最优路线(说是最优其实就是直线最短)
def _generate_best_route(self):
resources_route = []
# 先连上最近的资源路径
for res in self.resource_point:
# 拿到最近的资源
current_res, _ = res.get_resource_distance(
self.resource_point
+ self.teleport_anchor_point
+ self.teleport_god_point
)
self.map.line(
(current_res.x, current_res.y, res.x, res.y), (255, 0, 0), width=1
)
resources_route.append((current_res, res))
line_points = []
teleport_list = self.teleport_anchor_point + self.teleport_god_point
for res1, res2 in resources_route:
point_list = [x for x in resources_route if res1 in x or res2 in x]
if not list(set(point_list).intersection(set(teleport_list))):
if res1 not in teleport_list and res2 not in teleport_list:
# while True:
# tmp = [x for x in point_list]
# break
teleport1, distance1 = res1.get_resource_distance(teleport_list)
teleport2, distance2 = res2.get_resource_distance(teleport_list)
if distance1 > distance2:
self.map.line(
(teleport1.x, teleport1.y, res1.x, res1.y),
(255, 0, 0),
width=1,
)
else:
self.map.line(
(teleport2.x, teleport2.y, res2.x, res2.y),
(255, 0, 0),
width=1,
)
for teleport in teleport_list:
current_res, res_min_distance = teleport.get_resource_distance(self.resource_point)
current_teleport, teleport_min_distance = current_res.get_resource_distance(teleport_list)
if current_teleport == teleport:
self.map.line(
(current_teleport.x, current_teleport.y, current_res.x, current_res.y), (255, 0, 0), width=1
)
is_used_res_points = []
for res in self.resource_point:
if res in is_used_res_points:
continue
current_teleport, teleport_min_distance = res.get_resource_distance(teleport_list)
current_res, res_min_distance = res.get_resource_distance(self.resource_point)
if teleport_min_distance < res_min_distance:
self.map.line(
(current_teleport.x, current_teleport.y, res.x, res.y), (255, 0, 0), width=1
)
else:
is_used_res_points.append(current_res)
self.map.line(
(current_res.x, current_res.y, res.x, res.y), (255, 0, 0), width=1
)
res_cp = self.resource_point[:]
res_cp.remove(current_res)
# for _ in res_cp:
current_teleport_, teleport_min_distance = res.get_resource_distance(teleport_list)
current_res, res_min_distance = res.get_resource_distance(res_cp)
if teleport_min_distance < res_min_distance:
self.map.line(
(current_teleport.x, current_teleport.y, res.x, res.y), (255, 0, 0), width=1
)
else:
self.map.line(
(current_res.x, current_res.y, res.x, res.y), (255, 0, 0), width=1
)
is_used_res_points.append(current_res)
is_used_res_points.append(res)
# resources_route = []
# # 先连上最近的资源路径
# for res in self.resource_point:
# # 拿到最近的资源
# current_res, _ = res.get_resource_distance(
# self.resource_point
# + self.teleport_anchor_point
# + self.teleport_god_point
# )
# self.map.line(
# (current_res.x, current_res.y, res.x, res.y), (255, 0, 0), width=1
# )
# resources_route.append((current_res, res))
# teleport_list = self.teleport_anchor_point + self.teleport_god_point
# for res1, res2 in resources_route:
# point_list = [x for x in resources_route if res1 in x or res2 in x]
# if not list(set(point_list).intersection(set(teleport_list))):
# if res1 not in teleport_list and res2 not in teleport_list:
# # while True:
# # tmp = [x for x in point_list]
# # break
# teleport1, distance1 = res1.get_resource_distance(teleport_list)
# teleport2, distance2 = res2.get_resource_distance(teleport_list)
# if distance1 > distance2:
# self.map.line(
# (teleport1.x, teleport1.y, res1.x, res1.y),
# (255, 0, 0),
# width=1,
# )
# else:
# self.map.line(
# (teleport2.x, teleport2.y, res2.x, res2.y),
# (255, 0, 0),
# width=1,
# )
# self.map.line(xy, (255, 0, 0), width=3)
+2
View File
@@ -50,6 +50,8 @@ entertainment_help = {
"poetry": "突然文艺的真寻是否搞错了什么 --> 指令:念诗/来首诗/念首诗",
"comments_163": "生了个人,我很抱歉 --> 指令:到点了/12点了/网易云热评/网易云评论",
"pix_gallery": "偶尔也想看看美图? --> 指令:PIX [关键词/uid/pid:pid] [num]/查看pix图库 [关键词]/显示pix关键词",
'nbnhhsh': "会说话就多说点! --> 指令:nbnhhsh/能不能好好说话 [文本](空格划分)",
"roll": "让真寻来帮你决定吧! --> 指令:roll/ roll [文本](空格划分)"
}
# 其他
other_help = [
+49
View File
@@ -0,0 +1,49 @@
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
from services.log import logger
import ujson as json
import aiohttp
__plugin_name__ = "能不能好好说话"
__plugin_usage__ = "用法:\n nbnhhsh [文本]"
HHSH_GUESS_URL = "https://lab.magiconch.com/api/nbnhhsh/guess"
nbnhhsh = on_command("nbnhhsh", aliases={"能不能好好说话"}, priority=5, block=True)
@nbnhhsh.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json())
async with aiohttp.ClientSession(
headers={"content-type": "application/json"}
) as session:
async with session.post(
HHSH_GUESS_URL, data=json.dumps({"text": msg}), timeout=5
) as response:
if response.status == 200:
try:
data = await response.json()
tmp = ""
rst = ""
for x in data:
trans = ""
if x.get("trans"):
trans = x["trans"][0]
elif x.get("inputting"):
trans = ",".join(x["inputting"])
tmp += f'{x["name"]} -> {trans}\n'
rst += trans
logger.info(
f"(USER {event.user_id}, GROUP "
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 发送能不能好好说话: {msg} -> {rst}"
)
await nbnhhsh.send(f"{tmp}={rst}", at_sender=True)
except (IndexError, KeyError):
await nbnhhsh.finish("没有找到对应的翻译....")
else:
await nbnhhsh.finish("网络访问失败了....")
+4 -2
View File
@@ -25,8 +25,10 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
if await GroupRemind.get_status(event.group_id, "blpar") and get_message_json(
event.json()
):
data = json.loads(get_message_json(event.json())[0]["data"])
print(data)
try:
data = json.loads(get_message_json(event.json())[0]["data"])
except (IndexError, KeyError):
return
if data:
if data.get("desc") == "哔哩哔哩":
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
+49
View File
@@ -0,0 +1,49 @@
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
from services.log import logger
import random
import asyncio
__plugin_name__ = "roll"
__plugin_usage__ = (
"用法:\n" "\troll -> 随机数字\n" "\troll *[文本] -> 决定事件\n" "示例:roll 吃饭 睡觉 打游戏"
)
roll = on_command("roll", priority=5, block=True)
@roll.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json()).split()
if not msg:
await roll.finish(f"roll: {random.randint(0, 100)}", at_sender=True)
user_name = event.sender.card if event.sender.card else event.sender.nickname
await roll.send(
random.choice(
[
"转动命运的齿轮,拨开眼前迷雾...",
f"启动吧,命运的水晶球,为{user_name}指引方向!",
"嗯哼,在此刻转动吧!命运!",
f"在此祈愿,请为{user_name}降下指引...",
]
)
)
await asyncio.sleep(1)
x = random.choice(msg)
await roll.send(
random.choice(
[
f"让真寻看看是什么结果!答案是:‘{x}’",
f"根据命运的指引,接下来{user_name} ‘{x}’ 会比较好",
f"祈愿被回应了!是 ‘{x}’!",
f"结束了,{user_name},命运之轮停在了 ‘{x}’!",
]
)
)
logger.info(
f"(USER {event.user_id}, "
f"GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 发送roll:{msg}"
)
+8 -4
View File
@@ -11,6 +11,7 @@ from models.bag_user import BagUser
from services.log import logger
import time
from .data_source import rank
from configs.config import MAX_RUSSIAN_BET_GOLD
__plugin_name__ = '俄罗斯轮盘'
@@ -158,7 +159,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
except KeyError:
pass
if msg:
msg = msg.split(' ')
msg = msg.split()
if len(msg) == 1:
msg = msg[0]
if is_number(msg) and not (int(msg) < 1 or int(msg) > 6):
@@ -168,8 +169,11 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
msg = msg[0].strip()
if is_number(msg) and not (int(msg) < 1 or int(msg) > 6):
state['bullet_num'] = int(msg)
if is_number(money) and 0 < int(money) <= 1000:
if is_number(money) and 0 < int(money) <= MAX_RUSSIAN_BET_GOLD:
state['money'] = int(money)
else:
state['money'] = 200
await rssian.send(f'赌注金额超过限制(MAX_RUSSIAN_BET_GOLD),已改为200(默认)')
state['at'] = get_message_at(event.json())
@@ -182,8 +186,8 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
user_money = await BagUser.get_gold(event.user_id, event.group_id)
if bullet_num < 0 or bullet_num > 6:
await rssian.reject('子弹数量必须大于0小于7!速速重新装弹!')
if money > 1000:
await rssian.finish('太多了!单次金额不能超过1000!', at_sender=True)
if money > MAX_RUSSIAN_BET_GOLD:
await rssian.finish(f'太多了!单次金额不能超过{MAX_RUSSIAN_BET_GOLD}!', at_sender=True)
if money > user_money:
await rssian.finish('你没有足够的钱支撑起这场挑战', at_sender=True)
+1 -1
View File
@@ -73,7 +73,7 @@ async def arg_handle(bot: Bot, event: MessageEvent, state: T_State):
update_buff_session = on_command(
"更新cookie", rule=to_me(), permission=SUPERUSER, priority=1
"更新cookie", aliases={'设置cookie'}, rule=to_me(), permission=SUPERUSER, priority=1
)
+2
View File
@@ -90,6 +90,8 @@ async def search_online_setu(
index = random.randint(1, 100000) if id_ is None else id_
path_ = "temp" if not path_ else path_
file = f"{index}_temp_setu.jpg" if not path_ else f"{index}.jpg"
if not os.path.exists(f'{IMAGE_PATH}/{path_}'):
os.mkdir(f'{IMAGE_PATH}/{path_}')
async with aiofiles.open(
f"{IMAGE_PATH}/{path_}/{file}", "wb"
) as f:
+20 -17
View File
@@ -18,24 +18,27 @@ async def _(bot: Bot, event: Event, state: T_State):
3.广播 --> 指令:广播- [msg]
4.更新色图
5.回复 --> 指令:/t命令帮助
6.更新cookie --> 指令:更新cookie [cookie]
6.更新/设置cookie --> 指令:更新/设置cookie [cookie]
7.开启广播通知 --> 指令:开启广播通知 [群号]
8.退群 --> 指令:退群 [群号]
9.自检
10.更新好友信息
11.更新群群信息
12.重载原神/方舟/赛马娘/坎公骑冠剑卡池
13.添加商品 [名称]-[价格]-[描述]-[折扣]-[限时时间]
14.删除商品 [名称(序号)]
15.修改商品 -name [名称(序号)] -price [价格] -des [描述] -discount [折扣] -time [限时]
16.节日红包 [金额] [数量] [祝福语](可省) *[指定群](可省)
17.更新原神今日素材
18.更新原神资源信息
19.添加pix关键词/uid/pid *[关键词/uid/pid] [-f](强制通过不检测)
20.通过/取消pix关键词 [keyword/pid:pid/uid:uid]
21.删除pix关键词 [keyword/uid/pid:pid]
22.更新pix关键词 [keyword/pid:pid/uid:uid] [num]
23.删除pix图片 *[pid] [-b](同时加入黑名单)?
24.查看pix图库 [keyword]
25.pix检测更新 [update]"""
10.更新价格/更加图片 [武器箱]
11.更新好友信息
12.更新群群信息
13.重载原神/方舟/赛马娘/坎公骑冠剑卡池
14.添加商品 [名称]-[价格]-[描述]-[折扣]-[限时时间]
15.删除商品 [名称(序号)]
16.修改商品 -name [名称(序号)] -price [价格] -des [描述] -discount [折扣] -time [限时]
17.节日红包 [金额] [数量] [祝福语](可省) *[指定群](可省)
18.更新原神今日素材
19.更新原神资源信息
20.添加pix关键词/uid/pid *[关键词/uid/pid] [-f](强制通过不检测)
21.通过/取消pix关键词 [keyword/pid:pid/uid:uid]
22.删除pix关键词 [keyword/uid/pid:pid]
23.更新pix关键词 [keyword/pid:pid/uid:uid] [num]
24.删除pix图片 *[pid] [-b](同时加入黑名单)?
25.查看pix图库 [keyword]
26.pix检测更新 [update]
27.检查更新真寻
28.真寻重启"""
await super_help.finish(result, at_sender=True)
+5 -2
View File
@@ -88,12 +88,14 @@ async def update_setu_img():
_success = 0
error_info = []
error_type = []
count = 0
async with aiohttp.ClientSession(headers=headers) as session:
for image in image_list:
count += 1
path = _path / "_r18" if image.is_r18 else _path / "_setu"
rar_path = "r18_rar" if image.is_r18 else "rar"
local_image = path / f"{image.local_id}.jpg"
if not local_image.exists():
if not local_image.exists() or not image.img_hash:
for _ in range(3):
try:
async with session.get(
@@ -153,9 +155,10 @@ async def update_setu_img():
)
else:
logger.info(f'更新色图 {image.local_id}.jpg 已存在')
error_info = ['无报错..'] if not error_info else error_info
await get_bot().send_private_msg(
user_id=int(list(get_bot().config.superusers)[0]),
message=f'{str(datetime.now()).split(".")[0]} 更新 色图 完成,实际更新 {_success} 张,以下为更新时未知错误:\n'
message=f'{str(datetime.now()).split(".")[0]} 更新 色图 完成,本地群在 {count} 张,实际更新 {_success} 张,以下为更新时未知错误:\n'
+ "\n".join(error_info),
)
+3 -3
View File
@@ -81,12 +81,12 @@ async def update_city():
def _check_exists_city(city: str) -> int:
city = city if city[-1] != "市" else city[:-1]
for province in data.keys():
# 查询省份了
if city == province and len(data[province]) != 1:
return 999
for city_ in data[province]:
if city_ == city:
return 200
for province in data.keys():
if city == province:
return 999
return 998
+2 -1
View File
@@ -3,6 +3,7 @@ from .data_source import get_yiqing_data
from services.log import logger
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from nonebot.typing import T_State
from utils.utils import get_message_text
__plugin_name__ = "疫情查询"
__plugin_usage__ = "查询疫情帮助:\n\t对我说 查询疫情 省份/城市,我会回复疫情的实时数据\n\t示例: 查询疫情 温州"
@@ -13,7 +14,7 @@ yiqing = on_command("疫情", aliases={"查询疫情", "疫情查询"}, priority
@yiqing.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = str(event.get_message()).strip()
msg = get_message_text(event.json())
result = await get_yiqing_data(msg)
if result:
await yiqing.send(result)
+6 -6
View File
@@ -25,16 +25,16 @@ async def get_yiqing_data(area: str):
if area == '中国':
province = area
province_type = ""
elif area in data.keys():
province = area
if len(data[area]) == 1:
province_type = "市"
city = ""
else:
elif area[-1] != '省':
for p in data.keys():
if area in data[p]:
province = p
city = area
elif area in data.keys() or area[:-1] in data.keys():
province = area if area[-1] != '省' else area[:-1]
if len(data[province]) == 1:
province_type = "市"
city = ""
if not province and not city:
return "小真寻只支持国内的疫情查询喔..."
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
+3
View File
@@ -0,0 +1,3 @@
from .db_context import *
from .log import *
from .service_config import *
+17 -4
View File
@@ -1,5 +1,18 @@
{
"update_file": [],
"add_file": [],
"delete_file": ["plugins/ai", "plugins/bt"]
}
"update_file": [
"configs/config.py",
"plugins/auto_invite",
"plugins/ban",
"plugins/check_zhenxun_update",
"plugins/genshin/material_remind",
"plugins/genshin/query_resource_points",
"plugins/help",
"plugins/russian",
"plugins/search_buff_skin_price",
"plugins/super_help",
"plugins/update_setu",
"plugins/yiqing"
],
"add_file": ["plugins/nbnhhsh.py", "plugins/roll.py"],
"delete_file": []
}