Compare commits

...
47 Commits
Author SHA1 Message Date
HibiKier b63c05a509 Update requirements.txt 2021-12-01 14:17:11 +08:00
HibiKi 2a1a2ee8c5 update 0.0.6.5 2021-12-01 14:03:34 +08:00
HibiKier 8c4b515093 Update update_info.json 2021-12-01 10:53:15 +08:00
HibiKier 6d43989a4d Update update_info.json 2021-12-01 10:52:28 +08:00
HibiKier fb1f15bcb4 Update update_game_simple_info.py 2021-11-29 21:30:06 +08:00
HibiKier 81ad585a18 Update update_game_requests_info.py 2021-11-29 21:29:48 +08:00
HibiKier eb3bd2b4a6 Update update_game_info.py 2021-11-29 21:29:29 +08:00
HibiKier e401914790 Update README.md 2021-11-29 13:11:34 +08:00
HibiKier fef5dadaba Update __version__ 2021-11-29 13:10:43 +08:00
HibiKi c1348d08ed update 0.0.6.4 2021-11-29 13:09:47 +08:00
HibiKier fbd7c568d9 Update pix_update.py 2021-11-24 18:26:52 +08:00
HibiKier 2941774913 Update __init__.py 2021-11-24 18:26:38 +08:00
HibiKier b96d910401 Update __version__ 2021-11-24 14:40:53 +08:00
HibiKier 9275d0782b Update README.md 2021-11-24 14:40:39 +08:00
HibiKier 7acc6cf6af Update data_source.py 2021-11-24 14:33:10 +08:00
HibiKier d380a9aacc Update data_source.py 2021-11-24 14:32:46 +08:00
HibiKier 495377da13 Update README.md 2021-11-24 10:25:00 +08:00
HibiKier 218eed4068 Add files via upload 2021-11-24 10:24:40 +08:00
HibiKier 1e9c99dec1 Delete plugins/search_image directory 2021-11-24 10:07:47 +08:00
HibiKier 0326bc2831 Update __init__.py 2021-11-24 09:56:50 +08:00
HibiKier aed770a761 Update README.md 2021-11-23 21:48:11 +08:00
HibiKi 3de487fb24 update 0.0.6.2 2021-11-23 21:44:59 +08:00
HibiKier c802dfda22 Update README.md 2021-11-19 15:47:10 +08:00
HibiKier 3a4378e4c6 Update __init__.py 2021-11-18 14:41:54 +08:00
HibiKier 955a1f8a7f Update __init__.py 2021-11-18 14:41:13 +08:00
HibiKier ab69e5c477 Create README.md 2021-11-17 11:34:40 +08:00
HibiKier 55e42e8334 Update README.md 2021-11-17 11:33:26 +08:00
HibiKier a0f59bc2c2 Update README.md 2021-11-14 17:27:26 +08:00
HibiKier 66dabd0c8a Update plugins_manager.py 2021-11-14 17:25:45 +08:00
HibiKier 915d585e3a Merge pull request #77 from AkashiCoin/main
修复有免费游戏时不能获取免费游戏的问题
2021-11-13 16:12:49 +08:00
HibiKier 979080d281 Merge branch 'main' into main 2021-11-13 16:12:41 +08:00
HibiKier 335f76c532 Update data_source.py 2021-11-12 16:13:16 +08:00
AkashiCoin b50b934a12 Update data_source.py 2021-11-10 22:26:57 +08:00
AkashiCoin 6a1684d277 Update __init__.py 2021-11-10 22:26:29 +08:00
HibiKier 4926e4d69c Update pix_update.py 2021-11-10 21:33:10 +08:00
HibiKier b29a26551a Update README.md 2021-11-10 21:32:54 +08:00
HibiKier d1c1d93ab7 fix 2021-11-10 21:27:49 +08:00
HibiKier 907df4253c Update __version__ 2021-11-10 20:06:44 +08:00
HibiKier 658152fdc9 Update jitang.py 2021-11-10 16:45:19 +08:00
HibiKier 1a68ede632 Update README.md 2021-11-09 18:05:36 +08:00
HibiKier b70851b810 Update __init__.py 2021-11-09 18:04:33 +08:00
HibiKier 17506691a8 Update __init__.py 2021-11-07 20:45:34 +08:00
HibiKier 37a651da4e Update README.md 2021-11-05 16:52:33 +08:00
HibiKier c535a32230 Update update_info.json 2021-11-05 16:51:28 +08:00
HibiKier bb54781209 Add files via upload 2021-11-05 16:50:40 +08:00
HibiKier dcb538a3a9 Update data_source.py 2021-11-05 16:48:28 +08:00
HibiKier 185f7d9c31 Update README.md 2021-11-04 16:52:44 +08:00
257 changed files with 14612 additions and 14017 deletions
+145
View File
@@ -0,0 +1,145 @@
### Python template
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
test.py
server.py
member_activity_handle.py
Yu-Gi-Oh/
+93 -9
View File
@@ -1,4 +1,4 @@
<div align=center><img width="320" height="320" src="https://raw.githubusercontent.com/HibiKier/zhenxun_bot/main/docs/zhenxun.jpg"/></div> <div align=center><img width="320" height="320" src="https://raw.githubusercontent.com/HibiKier/zhenxun_bot/main/logo.png"/></div>
![maven](https://img.shields.io/badge/python-3.8%2B-blue) ![maven](https://img.shields.io/badge/python-3.8%2B-blue)
![maven](https://img.shields.io/badge/nonebot-2.0.0-yellow) ![maven](https://img.shields.io/badge/nonebot-2.0.0-yellow)
@@ -25,6 +25,10 @@
## 真寻的帮助 ## 真寻的帮助
请对真寻说: '真寻帮助' or '管理员帮助' or '超级用户帮助' or '真寻帮助 指令' 请对真寻说: '真寻帮助' or '管理员帮助' or '超级用户帮助' or '真寻帮助 指令'
## 提供符合真寻标准的插件仓库
[AkashiCoin/nonebot_plugins_zhenxun_bot](https://github.com/AkashiCoin/nonebot_plugins_zhenxun_bot)
## 功能列表 ## 功能列表
<details> <details>
@@ -96,6 +100,7 @@
- [x] 移动图片 (同上) - [x] 移动图片 (同上)
- [x] 删除图片 (同上) - [x] 删除图片 (同上)
- [x] 群内B站订阅 - [x] 群内B站订阅
- [x] 群词条
### 已实现的超级用户功能 ### 已实现的超级用户功能
- [x] 添加/删除权限(是真寻的管理员权限,不是群管理员) - [x] 添加/删除权限(是真寻的管理员权限,不是群管理员)
@@ -268,8 +273,10 @@
</details> </details>
## 详细配置请前往文档,以下为最简部署和配置,如果你有基础并学习过nonebot2的话
## 部署
## 简单部署
``` ```
@@ -294,8 +301,7 @@ pip install -r requirements.txt
python bot.py python bot.py
``` ```
## 配置 ## 简单配置
在 configs/config.py 中的 USE_CONFIG_FILE,默认为False
``` ```
1.在.env.dev文件中 1.在.env.dev文件中
@@ -303,12 +309,10 @@ python bot.py
SUPERUSERS = [""] # 填写你的QQ SUPERUSERS = [""] # 填写你的QQ
2.在configs/config.py文件中 2.在configs/config.py文件中
必填: * 数据库配置
1. API KEY
2.数据库配置
在./configs/config.py中配置基本配置(除API KEY ,数据库和代理外都含有默认值) 3.在configs/config.yaml文件中 # 该文件需要启动一次后生成
在./configs/path_config.py配置路径(含有默认配置) * 修改插件配置项
``` ```
@@ -317,6 +321,86 @@ python bot.py
## 更新 ## 更新
### 2021/12/1 \[v0.0.6.5]
* 群权限-1时超级用户命令依旧生效
* 修复以真寻为开头的词条不会被回复
* 修复购买道具可以为负数
* P站排行/搜图提供配置项,将略过大于指定张数的作品
* 昵称提供关键词屏蔽配置项,会将指定关键词替换为“*”
* 取消了自动更新,改为自动检测版本
### 2021/11/29 \[v0.0.6.4]
* 新增cos图撤回配置项
* 新增默认群权限配置项
* 修复权限等级类配置无法正常应用
### 2021/11/24 \[v0.0.6.3]
* 修复在线搜索色图出错
* 修复pix无法正确获取HIBIAPI
### 2021/11/23 \[v0.0.6.2]
* 替换cos API
* 提供私聊b了,即跨群b了用户
* 修复游戏抽卡导入角色失败(原神)
* 修复无Pixiv代理时报错
* 将项目中大部分aiohttp替换为httpx
* 删除了丘丘人翻译插件
* 新增群词条
* 修复游戏抽卡碧蓝航线bwiki格式更改导致获取报错
* 首次启动会生成配置文件后停止程序,配置后再次启动即可
### 2021/11/18
* 修复超级用户无法正确拉真寻入群
### 2021/11/14
* 修复功能总开关无法正确开启
### 2021/11/12
* 修复PIX无法url无法正确获取
### 2021/11/10
* 修复PIX表重复创建导致首次无法运行
* 检测Omage图库改为命令方式:检测omega图库
### 2021/11/9
* 修复管理员帮助无法正常响应
* 修复被ban时会一直回复被ban提醒
### 2021/11/5
* 修复ai没有图灵key时报错
* 提供图片路径resource/img/background/check
### 2021/11/4
* 通用排行榜改用图片消息,且可以自定义排行榜人数
* 优化CreateMat排行榜数据显示
* 修复了pix更新多余参数导致失败的问题
* 修复滴滴滴-注入风险
* 修复无法正常关闭滴滴滴,戳一戳
* 添加了发送图片撤回配置项WITHDRAW_IMAGE_TIME
* 修复了天气regex文本过长时会正则匹配过久导致nb卡顿
* message_build新增custom_forward_msg用于快捷生成转发消息
* 插件配置改为yaml存储,新增Config,用于获取和新增插件配置
* 新增 当插件加载失败时,会发送消息提醒超级用户,且在功能状态中对应失败插件写上[ERROR]
* 修复当查看-spuer插件帮助时无法正确回复
* 群内帮助图片会随群内功能开关和插件总开关变化
* 自检改为图像形式
* 更新色图删除了rar_setu,r18_rar和rar文件夹,压缩将统一在temp文件夹
* 更新色图只有在有更新数量或报错时才会提醒超级用户
* 群欢迎消息加入cd
* 加入资源管理resources_manager
* 新增 好友请求/群聊邀请 控制命令
### 2021/10/15 ### 2021/10/15
* 适配了原神资源查询米游社地图返回的新格式 * 适配了原神资源查询米游社地图返回的新格式
+1 -1
View File
@@ -1 +1 @@
__version__: v0.0.5.1 __version__: v0.0.6.5
Regular → Executable
View File
+1 -1
View File
@@ -4,7 +4,7 @@ import nonebot
Config.add_plugin_config( Config.add_plugin_config(
"admin_bot_manage:custom_welcome_message", "admin_bot_manage:custom_welcome_message",
"SET_GROUP_WELCOME_MESSAGE_LEVEL", "SET_GROUP_WELCOME_MESSAGE_LEVEL [LEVEL]",
2, 2,
name="群管理员操作", name="群管理员操作",
help_="设置群欢迎消息权限", help_="设置群欢迎消息权限",
View File
View File
+2 -8
View File
@@ -12,8 +12,7 @@ from models.level_user import LevelUser
from configs.config import Config from configs.config import Config
from utils.manager import group_manager, plugins2settings_manager, plugins_manager from utils.manager import group_manager, plugins2settings_manager, plugins_manager
from utils.image_utils import CreateImg from utils.image_utils import CreateImg
import aiofiles from utils.http_utils import AsyncHttpx
import aiohttp
import asyncio import asyncio
import time import time
import os import os
@@ -73,12 +72,7 @@ async def custom_group_welcome(
logger.info(f"USER {user_id} GROUP {group_id} 更换群欢迎消息 {msg}") logger.info(f"USER {user_id} GROUP {group_id} 更换群欢迎消息 {msg}")
result += msg result += msg
if img: if img:
async with aiohttp.ClientSession() as session: await AsyncHttpx.download_file(img, DATA_PATH + f"custom_welcome_msg/{group_id}.jpg")
async with session.get(img, proxy=get_local_proxy()) as response:
async with aiofiles.open(
DATA_PATH + f"custom_welcome_msg/{group_id}.jpg", "wb"
) as f:
await f.write(await response.read())
img_result = image(abspath=DATA_PATH + f"custom_welcome_msg/{group_id}.jpg") img_result = image(abspath=DATA_PATH + f"custom_welcome_msg/{group_id}.jpg")
logger.info(f"USER {user_id} GROUP {group_id} 更换群欢迎消息图片") logger.info(f"USER {user_id} GROUP {group_id} 更换群欢迎消息图片")
except Exception as e: except Exception as e:
View File
View File
View File
View File
View File
View File
View File
Regular → Executable
+14 -4
View File
@@ -3,7 +3,7 @@ from models.ban_user import BanUser
from models.level_user import LevelUser from models.level_user import LevelUser
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot from nonebot.adapters.cqhttp import Bot
from nonebot.adapters.cqhttp import GroupMessageEvent, PrivateMessageEvent from nonebot.adapters.cqhttp import GroupMessageEvent, PrivateMessageEvent, MessageEvent
from utils.utils import get_message_at, get_message_text, is_number from utils.utils import get_message_at, get_message_text, is_number
from configs.config import NICKNAME, Config from configs.config import NICKNAME, Config
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
@@ -24,10 +24,14 @@ usage:
""".strip() """.strip()
__plugin_superuser_usage__ = """ __plugin_superuser_usage__ = """
usage: usage:
屏蔽用户消息,相当于最上级.ban b了=屏蔽用户消息,相当于最上级.ban
跨群ban以及跨群b了
指令: 指令:
b了 [at] b了 [at/qq]
.ban [user_id] ?[小时] ?[分钟]
示例:b了 @user 示例:b了 @user
示例:b了 1234567
示例:.ban 12345567
""".strip() """.strip()
__plugin_des__ = '你被逮捕了!丢进小黑屋!' __plugin_des__ = '你被逮捕了!丢进小黑屋!'
__plugin_cmd__ = ['.ban [at] ?[小时] ?[分钟]', '.unban [at]', 'b了 [at] [_superuser]'] __plugin_cmd__ = ['.ban [at] ?[小时] ?[分钟]', '.unban [at]', 'b了 [at] [_superuser]']
@@ -182,8 +186,14 @@ async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
@super_ban.handle() @super_ban.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
if isinstance(event, GroupMessageEvent):
qq = get_message_at(event.json()) qq = get_message_at(event.json())
else:
qq = get_message_text(event.json())
if not is_number(qq):
await super_ban.finish("对象qq必须为纯数字...")
qq = [qq]
if qq: if qq:
qq = qq[0] qq = qq[0]
user = await bot.get_group_member_info(group_id=event.group_id, user_id=qq) user = await bot.get_group_member_info(group_id=event.group_id, user_id=qq)
View File
+6 -6
View File
@@ -30,15 +30,15 @@ __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
__plugin_task__ = {"group_welcome": "进群欢迎", "refund_group_remind": "退群提醒"} __plugin_task__ = {"group_welcome": "进群欢迎", "refund_group_remind": "退群提醒"}
Config.add_plugin_config( Config.add_plugin_config(
"auto_invite", "message", f"请不要未经同意就拉{NICKNAME}入群!告辞!", help_="强制拉群后进群回复的内容.." "invite_manager", "message", f"请不要未经同意就拉{NICKNAME}入群!告辞!", help_="强制拉群后进群回复的内容.."
) )
Config.add_plugin_config( Config.add_plugin_config(
"auto_invite", "flag", True, help_="被强制拉群后是否直接退出", default_value=True "invite_manager", "flag", True, help_="被强制拉群后是否直接退出", default_value=True
) )
Config.add_plugin_config( Config.add_plugin_config(
"auto_invite", "welcome_msg_cd", 5, help_="群欢迎消息cd", default_value=5 "invite_manager", "welcome_msg_cd", 5, help_="群欢迎消息cd", default_value=5
) )
_flmt = FreqLimiter(Config.get_config("auto_invite", "welcome_msg_cd")) _flmt = FreqLimiter(Config.get_config("invite_manager", "welcome_msg_cd"))
# 群员增加处理 # 群员增加处理
@@ -55,10 +55,10 @@ async def _(bot: Bot, event: GroupIncreaseNoticeEvent, state: dict):
group = await GroupInfo.get_group_info(event.group_id) group = await GroupInfo.get_group_info(event.group_id)
# 群聊不存在或被强制拉群,退出该群 # 群聊不存在或被强制拉群,退出该群
if (not group or group.group_flag == 0) and Config.get_config( if (not group or group.group_flag == 0) and Config.get_config(
"auto_invite", "flag" "invite_manager", "flag"
): ):
try: try:
msg = Config.get_config("auto_invite", "message") msg = Config.get_config("invite_manager", "message")
if msg: if msg:
await bot.send_group_msg(group_id=event.group_id, message=msg) await bot.send_group_msg(group_id=event.group_id, message=msg)
await bot.set_group_leave(group_id=event.group_id) await bot.set_group_leave(group_id=event.group_id)
Regular → Executable
View File
View File
Regular → Executable
View File
Regular → Executable
+13
View File
@@ -20,6 +20,7 @@ from models.ban_user import BanUser
from utils.utils import FreqLimiter from utils.utils import FreqLimiter
from utils.message_builder import at from utils.message_builder import at
from models.level_user import LevelUser from models.level_user import LevelUser
import nonebot
_flmt = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD")) _flmt = FreqLimiter(Config.get_config("hook", "CHECK_NOTICE_INFO_CD"))
@@ -46,6 +47,18 @@ async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State):
and not plugins2info_dict[module]["limit_superuser"] and not plugins2info_dict[module]["limit_superuser"]
): ):
return return
# 超级用户命令
try:
_plugin = nonebot.plugin.get_plugin(module)
_module = _plugin.module
plugin_name = _module.__getattribute__("__zx_plugin_name__")
if (
"[superuser]" in plugin_name.lower()
and str(event.user_id) in bot.config.superusers
):
return
except AttributeError:
pass
# 群黑名单检测 # 群黑名单检测
if isinstance(event, GroupMessageEvent): if isinstance(event, GroupMessageEvent):
if group_manager.get_group_level(event.group_id) < 0: if group_manager.get_group_level(event.group_id) < 0:
Regular → Executable
View File
View File
View File
View File
Regular → Executable
View File
View File
+10
View File
@@ -9,10 +9,13 @@ from .init_plugins_limit import (
init_plugins_count_limit, init_plugins_count_limit,
init_plugins_cd_limit, init_plugins_cd_limit,
) )
from .init import init
from .check_plugin_status import check_plugin_status from .check_plugin_status import check_plugin_status
from utils.manager import admin_manager
from nonebot.adapters.cqhttp import Bot from nonebot.adapters.cqhttp import Bot
from configs.path_config import DATA_PATH from configs.path_config import DATA_PATH
from services.log import logger from services.log import logger
from pathlib import Path
from nonebot import Driver from nonebot import Driver
import nonebot import nonebot
@@ -30,6 +33,11 @@ def _():
""" """
初始化数据 初始化数据
""" """
_flag = False
config_file = Path(DATA_PATH) / "configs" / "plugins2config.yaml"
if not config_file.exists():
_flag = True
init()
init_plugins_settings(DATA_PATH) init_plugins_settings(DATA_PATH)
init_plugins_cd_limit(DATA_PATH) init_plugins_cd_limit(DATA_PATH)
init_plugins_block_limit(DATA_PATH) init_plugins_block_limit(DATA_PATH)
@@ -42,6 +50,8 @@ def _():
if x: if x:
for key in x.keys(): for key in x.keys():
plugins_manager.block_plugin(key, block_type=x[key]) plugins_manager.block_plugin(key, block_type=x[key])
if _flag:
raise Exception("首次运行,已在configs目录下生成配置文件config.yaml,修改后重启即可...")
logger.info("初始化数据完成...") logger.info("初始化数据完成...")
View File
+14
View File
@@ -0,0 +1,14 @@
from utils.manager import plugins2settings_manager
def init():
if plugins2settings_manager.get("update_pic"):
plugins2settings_manager["update_picture"] = plugins2settings_manager["update_pic"]
plugins2settings_manager.delete("update_pic")
if plugins2settings_manager.get("white2black_img"):
plugins2settings_manager["white2black_image"] = plugins2settings_manager["white2black_img"]
plugins2settings_manager.delete("white2black_img")
if plugins2settings_manager.get("send_img"):
plugins2settings_manager["send_image"] = plugins2settings_manager["send_img"]
plugins2settings_manager.delete("send_img")
View File
View File
+3
View File
@@ -92,11 +92,14 @@ def init_plugins_config(data_path):
if user_config_file.exists(): if user_config_file.exists():
with open(user_config_file, "r", encoding="utf8") as f: with open(user_config_file, "r", encoding="utf8") as f:
_data = _yaml.load(f) _data = _yaml.load(f)
# 数据替换
for plugin in Config.keys(): for plugin in Config.keys():
_tmp_data[plugin] = {} _tmp_data[plugin] = {}
for k in Config[plugin].keys(): for k in Config[plugin].keys():
if _data.get(plugin) and k in _data[plugin].keys(): if _data.get(plugin) and k in _data[plugin].keys():
Config.set_config(plugin, k, _data[plugin][k]) Config.set_config(plugin, k, _data[plugin][k])
if level2module := Config.get_level2module(plugin, k):
admin_manager.set_admin_level(level2module, _data[plugin][k])
_tmp_data[plugin][k] = Config.get_config(plugin, k) _tmp_data[plugin][k] = Config.get_config(plugin, k)
Config.save() Config.save()
temp_file = Path() / "configs" / "temp_config.yaml" temp_file = Path() / "configs" / "temp_config.yaml"
View File
View File
View File
+12 -16
View File
@@ -17,23 +17,19 @@ def init_plugins_settings(data_path: str):
plugins2settings_file = Path(data_path) / "configs" / "plugins2settings.yaml" plugins2settings_file = Path(data_path) / "configs" / "plugins2settings.yaml"
plugins2settings_file.parent.mkdir(exist_ok=True, parents=True) plugins2settings_file.parent.mkdir(exist_ok=True, parents=True)
_matchers = get_matchers() _matchers = get_matchers()
_data = {}
if plugins2settings_file.exists():
with open(plugins2settings_file, "r", encoding="utf8") as f:
_data = _yaml.load(f)
_data = _data["PluginSettings"] if _data else {}
_tmp_module = {} _tmp_module = {}
_tmp = [] _tmp = []
for x in plugins2settings_manager.keys():
try:
_plugin = nonebot.plugin.get_plugin(x)
_module = _plugin.module
plugin_name = _module.__getattribute__("__zx_plugin_name__")
_tmp_module[x] = plugin_name
except (KeyError, AttributeError) as e:
logger.warning(f"配置文件 模块:{x} 获取 plugin_name 失败...{e}")
_tmp_module[x] = ""
for matcher in _matchers: for matcher in _matchers:
if matcher.module in _data.keys(): if matcher.module not in plugins2settings_manager.keys():
plugins2settings_manager.add_plugin_settings(
matcher.module,
plugin_type=_data[matcher.module]["plugin_type"],
data_dict=_data[matcher.module],
)
if _data[matcher.module]["cmd"]:
_tmp_module[matcher.module] = _data[matcher.module]["cmd"][0]
else:
_plugin = nonebot.plugin.get_plugin(matcher.module) _plugin = nonebot.plugin.get_plugin(matcher.module)
try: try:
_module = _plugin.module _module = _plugin.module
@@ -52,7 +48,7 @@ def init_plugins_settings(data_path: str):
except (AttributeError, KeyError): except (AttributeError, KeyError):
level = 5 level = 5
cmd = None cmd = None
if not level: if level is None:
level = 5 level = 5
admin_manager.add_admin_plugin_settings( admin_manager.add_admin_plugin_settings(
matcher.module, cmd, level matcher.module, cmd, level
@@ -76,7 +72,7 @@ def init_plugins_settings(data_path: str):
"__plugin_settings__" "__plugin_settings__"
) )
if ( if (
plugin_settings["cmd"] plugin_settings["cmd"] is not None
and plugin_name not in plugin_settings["cmd"] and plugin_name not in plugin_settings["cmd"]
): ):
plugin_settings["cmd"].append(plugin_name) plugin_settings["cmd"].append(plugin_name)
@@ -25,14 +25,13 @@ __plugin_configs__ = {
friend_req = on_request(priority=5, block=True) friend_req = on_request(priority=5, block=True)
group_req = on_request(priority=5, block=True) group_req = on_request(priority=5, block=True)
x = on_message(priority=5, block=False) x = on_message(priority=9, block=False)
exists_data = {"private": {}, "group": {}} exists_data = {"private": {}, "group": {}}
@friend_req.handle() @friend_req.handle()
async def _(bot: Bot, event: FriendRequestEvent, state: dict): async def _(bot: Bot, event: FriendRequestEvent, state: dict):
print(event)
global exists_data global exists_data
if exists_data["private"].get(event.user_id): if exists_data["private"].get(event.user_id):
if time.time() - exists_data["private"][event.user_id] < 60 * 5: if time.time() - exists_data["private"][event.user_id] < 60 * 5:
@@ -47,11 +46,11 @@ async def _(bot: Bot, event: FriendRequestEvent, state: dict):
user_id=int(list(bot.config.superusers)[0]), user_id=int(list(bot.config.superusers)[0]),
message=f"*****一份好友申请*****\n" message=f"*****一份好友申请*****\n"
f"昵称:{nickname}({event.user_id})\n" f"昵称:{nickname}({event.user_id})\n"
f"自动同意:{'√' if Config.get_config('auto_invite', 'AUTO_ADD_FRIEND') else '×'}\n" f"自动同意:{'√' if Config.get_config('invite_manager', 'AUTO_ADD_FRIEND') else '×'}\n"
f"日期:{str(datetime.now()).split('.')[0]}\n" f"日期:{str(datetime.now()).split('.')[0]}\n"
f"备注:{event.comment}", f"备注:{event.comment}",
) )
if Config.get_config("auto_invite", "AUTO_ADD_FRIEND"): if Config.get_config("invite_manager", "AUTO_ADD_FRIEND"):
await bot.set_friend_add_request(flag=event.flag, approve=True) await bot.set_friend_add_request(flag=event.flag, approve=True)
await FriendUser.add_friend_info(user["user_id"], user["nickname"]) await FriendUser.add_friend_info(user["user_id"], user["nickname"])
else: else:
@@ -72,9 +71,6 @@ async def _(bot: Bot, event: GroupRequestEvent, state: dict):
if event.sub_type == "invite": if event.sub_type == "invite":
if str(event.user_id) in bot.config.superusers: if str(event.user_id) in bot.config.superusers:
try: try:
await bot.set_group_add_request(
flag=event.flag, sub_type="invite", approve=True
)
if await GroupInfo.get_group_info(event.group_id): if await GroupInfo.get_group_info(event.group_id):
await GroupInfo.set_group_flag(event.group_id, 1) await GroupInfo.set_group_flag(event.group_id, 1)
else: else:
@@ -86,6 +82,9 @@ async def _(bot: Bot, event: GroupRequestEvent, state: dict):
group_info["member_count"], group_info["member_count"],
1, 1,
) )
await bot.set_group_add_request(
flag=event.flag, sub_type="invite", approve=True
)
except ActionFailed: except ActionFailed:
pass pass
else: else:
Regular → Executable
+18 -11
View File
@@ -8,7 +8,7 @@ from models.friend_user import FriendUser
import random import random
from models.ban_user import BanUser from models.ban_user import BanUser
from services.log import logger from services.log import logger
from configs.config import NICKNAME from configs.config import NICKNAME, Config
__zx_plugin_name__ = "昵称系统" __zx_plugin_name__ = "昵称系统"
@@ -23,6 +23,13 @@ __plugin_des__ = "区区昵称,才不想叫呢!"
__plugin_cmd__ = ["以后叫我 [昵称]", f"{NICKNAME}我是谁"] __plugin_cmd__ = ["以后叫我 [昵称]", f"{NICKNAME}我是谁"]
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = "HibiKier" __plugin_author__ = "HibiKier"
__plugin_configs__ = {
"BLACK_WORD": {
"value": ["爸", "妈", "爹", "爷"],
"help": "昵称所屏蔽的关键词,会被替换为 *",
"default_value": None
}
}
nickname = on_command( nickname = on_command(
"nickname", "nickname",
@@ -47,11 +54,19 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
await nickname.finish("叫你空白?叫你虚空?叫你无名??", at_sender=True) await nickname.finish("叫你空白?叫你虚空?叫你无名??", at_sender=True)
if len(msg) > 10: if len(msg) > 10:
await nickname.finish("昵称可不能超过10个字!", at_sender=True) await nickname.finish("昵称可不能超过10个字!", at_sender=True)
if msg in bot.config.superusers:
await nickname.finish("笨蛋!休想占用我的名字!#", at_sender=True)
_tmp = ""
black_word = Config.get_config("nickname", "BLACK_WORD")
for x in msg:
_tmp += "*" if x in black_word else x
msg = _tmp
if isinstance(event, GroupMessageEvent):
if await GroupInfoUser.set_group_member_nickname( if await GroupInfoUser.set_group_member_nickname(
event.user_id, event.group_id, msg event.user_id, event.group_id, msg
): ):
if len(msg) < 5: if len(msg) < 5:
if random.random() < 0.5: if random.random() < 0.3:
msg = "~".join(msg) msg = "~".join(msg)
await nickname.send( await nickname.send(
random.choice( random.choice(
@@ -68,15 +83,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
else: else:
await nickname.send("设置昵称失败,请更新群组成员信息!", at_sender=True) await nickname.send("设置昵称失败,请更新群组成员信息!", at_sender=True)
logger.warning(f"USER {event.user_id} GROUP {event.group_id} 设置群昵称 {msg} 失败") logger.warning(f"USER {event.user_id} GROUP {event.group_id} 设置群昵称 {msg} 失败")
else:
@nickname.handle()
async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
msg = get_message_text(event.json())
if not msg:
await nickname.finish("叫你空白?叫你虚空?叫你无名??", at_sender=True)
if len(msg) > 10:
await nickname.finish("不要超过10个字!", at_sender=True)
if await FriendUser.set_friend_nickname(event.user_id, msg): if await FriendUser.set_friend_nickname(event.user_id, msg):
await nickname.send( await nickname.send(
random.choice( random.choice(
Regular → Executable
+16 -24
View File
@@ -3,12 +3,11 @@ from services.db_context import db
from asyncpg.exceptions import DuplicateColumnError from asyncpg.exceptions import DuplicateColumnError
from models.group_info import GroupInfo from models.group_info import GroupInfo
from nonebot.adapters.cqhttp import Bot from nonebot.adapters.cqhttp import Bot
from utils.user_agent import get_user_agent
from services.log import logger from services.log import logger
from configs.path_config import TEXT_PATH from configs.path_config import TEXT_PATH
from asyncio.exceptions import TimeoutError from asyncio.exceptions import TimeoutError
from utils.http_utils import AsyncHttpx
from pathlib import Path from pathlib import Path
import aiohttp
import nonebot import nonebot
try: try:
@@ -25,30 +24,34 @@ async def update_city():
""" """
部分插件需要中国省份城市 部分插件需要中国省份城市
这里直接更新,避免插件内代码重复 这里直接更新,避免插件内代码重复
:return:
""" """
china_city = Path(TEXT_PATH) / "china_city.json" china_city = Path(TEXT_PATH) / "china_city.json"
data = {} data = {}
try: try:
async with aiohttp.ClientSession(headers=get_user_agent()) as session: res = await AsyncHttpx.get(
async with session.get(
"http://www.weather.com.cn/data/city3jdata/china.html", timeout=5 "http://www.weather.com.cn/data/city3jdata/china.html", timeout=5
) as res: )
provinces_data = json.loads(await res.text(encoding="utf8")) res.encoding = "utf8"
provinces_data = json.loads(res.text)
for province in provinces_data.keys(): for province in provinces_data.keys():
data[provinces_data[province]] = [] data[provinces_data[province]] = []
async with session.get( res = await AsyncHttpx.get(
f"http://www.weather.com.cn/data/city3jdata/provshi/{province}.html", f"http://www.weather.com.cn/data/city3jdata/provshi/{province}.html",
timeout=5, timeout=5,
) as res: )
city_data = json.loads(await res.text(encoding="utf8")) res.encoding = "utf8"
city_data = json.loads(res.text)
for city in city_data.keys(): for city in city_data.keys():
data[provinces_data[province]].append(city_data[city]) data[provinces_data[province]].append(city_data[city])
with open(china_city, "w", encoding="utf8") as f: with open(china_city, "w", encoding="utf8") as f:
json.dump(data, f, indent=4, ensure_ascii=False) json.dump(data, f, indent=4, ensure_ascii=False)
logger.info("自动更新城市列表完成.....") logger.info("自动更新城市列表完成.....")
except TimeoutError: except TimeoutError:
logger.info("自动更新城市列表超时.....") logger.warning("自动更新城市列表超时.....")
except ValueError:
logger.warning("自动城市列表失败.....")
except Exception as e:
logger.error(f"自动城市列表未知错误 {type(e)}:{e}")
@driver.on_startup @driver.on_startup
@@ -75,13 +78,7 @@ async def _(bot: Bot):
# 清空不存在的群聊信息,并将已所有已存在的群聊group_flag设置为1(认证所有已存在的群) # 清空不存在的群聊信息,并将已所有已存在的群聊group_flag设置为1(认证所有已存在的群)
if not await GroupInfo.get_group_info(114514): if not await GroupInfo.get_group_info(114514):
# 标识符,该功能只需执行一次 # 标识符,该功能只需执行一次
await GroupInfo.add_group_info( await GroupInfo.add_group_info(114514, "114514", 114514, 114514, 1)
114514,
"114514",
114514,
114514,
1
)
group_list = await bot.get_group_list() group_list = await bot.get_group_list()
group_list = [g["group_id"] for g in group_list] group_list = [g["group_id"] for g in group_list]
_gl = [x.group_id for x in await GroupInfo.get_all_group()] _gl = [x.group_id for x in await GroupInfo.get_all_group()]
@@ -98,14 +95,9 @@ async def _(bot: Bot):
group_info["group_name"], group_info["group_name"],
group_info["max_member_count"], group_info["max_member_count"],
group_info["member_count"], group_info["member_count"],
1 1,
) )
logger.info(f"已将群聊 {group_id} 添加认证...") logger.info(f"已将群聊 {group_id} 添加认证...")
else: else:
await GroupInfo.delete_group_info(group_id) await GroupInfo.delete_group_info(group_id)
logger.info(f"移除不存在的群聊信息:{group_id}") logger.info(f"移除不存在的群聊信息:{group_id}")
View File
View File
View File
View File
View File
+5 -1
View File
@@ -15,6 +15,10 @@ __zx_plugin_name__ = "重载插件配置 [Superuser]"
__plugin_usage__ = """ __plugin_usage__ = """
usage: usage:
重载插件配置 重载插件配置
plugins2settings,
plugins2cd
plugins2block
group_manager
指令: 指令:
重载插件配置 重载插件配置
""".strip() """.strip()
@@ -27,7 +31,7 @@ __plugin_author__ = "HibiKier"
reload_plugins_manager = on_command( reload_plugins_manager = on_command(
"重载插件限制", rule=to_me(), permission=SUPERUSER, priority=1, block=True "重载配置", rule=to_me(), permission=SUPERUSER, priority=1, block=True
) )
View File
View File
View File
View File
View File
Regular → Executable
View File
+15 -1
View File
@@ -29,7 +29,7 @@ class ConfigsManager:
name: Optional[str] = None, name: Optional[str] = None,
help_: Optional[str] = None, help_: Optional[str] = None,
default_value: Optional[str] = None, default_value: Optional[str] = None,
_override: bool = False _override: bool = False,
): ):
""" """
为插件添加一个配置,不会被覆盖,只有第一个生效 为插件添加一个配置,不会被覆盖,只有第一个生效
@@ -61,6 +61,7 @@ class ConfigsManager:
"name": name.strip() if isinstance(name, str) else name, "name": name.strip() if isinstance(name, str) else name,
"help": help_.strip() if isinstance(help_, str) else help_, "help": help_.strip() if isinstance(help_, str) else help_,
"default_value": default_value, "default_value": default_value,
"level_module": _module,
} }
def remove_plugin_config(self, module: str): def remove_plugin_config(self, module: str):
@@ -112,12 +113,24 @@ class ConfigsManager:
""" """
key = key.upper() key = key.upper()
if module in self._data.keys(): if module in self._data.keys():
for key in [key, f"{key} [LEVEL]"]:
if self._data[module].get(key) is not None: if self._data[module].get(key) is not None:
if self._data[module][key]["value"] is None: if self._data[module][key]["value"] is None:
return self._data[module][key]["default_value"] return self._data[module][key]["default_value"]
return self._data[module][key]["value"] return self._data[module][key]["value"]
return None return None
def get_level2module(self, module: str, key: str) -> Optional[str]:
"""
获取指定key所绑定的module,一般为权限等级
:param module: 模块名
:param key: 配置名称
:return:
"""
if self._data.get(module) is not None:
if self._data[module].get(key) is not None:
return self._data[module][key].get("level_module")
def get(self, key: str): def get(self, key: str):
""" """
获取插件配置数据 获取插件配置数据
@@ -157,3 +170,4 @@ class ConfigsManager:
def __getitem__(self, key): def __getitem__(self, key):
return self._data[key] return self._data[key]
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 694 KiB

Regular → Executable
View File
Regular → Executable
+1 -1
View File
@@ -82,7 +82,7 @@ class BanUser(db.Model):
参数: 参数:
:param user_qq: 目标用户qq号 :param user_qq: 目标用户qq号
:param ban_level: 使用ban命令用户的权限 :param ban_level: 使用ban命令用户的权限
:param duration: ban时长 :param duration: ban时长,秒
""" """
query = cls.query.where((cls.user_qq == user_qq)) query = cls.query.where((cls.user_qq == user_qq))
query = query.with_for_update() query = query.with_for_update()
Regular → Executable
+6 -1
View File
@@ -1,4 +1,5 @@
from services.db_context import db from services.db_context import db
from configs.config import Config
class FriendUser(db.Model): class FriendUser(db.Model):
@@ -80,7 +81,11 @@ class FriendUser(db.Model):
user = await query.gino.first() user = await query.gino.first()
if user: if user:
if user.nickname: if user.nickname:
return user.nickname _tmp = ""
black_word = Config.get_config("nickname", "BLACK_WORD")
for x in user.nickname:
_tmp += "*" if x in black_word else x
return _tmp
return "" return ""
@classmethod @classmethod
Regular → Executable
View File
Regular → Executable
+17 -2
View File
@@ -1,5 +1,5 @@
from datetime import datetime from datetime import datetime
from configs.config import Config
from services.db_context import db from services.db_context import db
from typing import List, Optional from typing import List, Optional
@@ -128,6 +128,17 @@ class GroupInfoUser(db.Model):
return True return True
return False return False
@classmethod
async def get_user_all_group(cls, user_qq: int) -> List[int]:
"""
获取该用户所在的所有群聊
:param user_qq: 用户qq
"""
query = await cls.query.where(cls.user_qq == user_qq).gino.all()
if query:
query = [x.belonging_group for x in query]
return query
@classmethod @classmethod
async def get_group_member_nickname(cls, user_qq: int, belonging_group: int) -> str: async def get_group_member_nickname(cls, user_qq: int, belonging_group: int) -> str:
""" """
@@ -143,7 +154,11 @@ class GroupInfoUser(db.Model):
user = await query.gino.first() user = await query.gino.first()
if user: if user:
if user.nickname: if user.nickname:
return user.nickname _tmp = ""
black_word = Config.get_config("nickname", "BLACK_WORD")
for x in user.nickname:
_tmp += "*" if x in black_word else x
return _tmp
return "" return ""
@classmethod @classmethod
Regular → Executable
View File
Regular → Executable
View File
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
-2
View File
@@ -24,8 +24,6 @@ __plugin_version__ = 0.1
__plugin_author__ = 'HibiKier' __plugin_author__ = 'HibiKier'
__plugin_settings__ = { __plugin_settings__ = {
"level": 5, "level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["Ai", "ai", "AI", "aI"], "cmd": ["Ai", "ai", "AI", "aI"],
} }
__plugin_configs__ = { __plugin_configs__ = {
Regular → Executable
+24 -23
View File
@@ -1,13 +1,12 @@
import os import os
import random import random
import re import re
from utils.http_utils import AsyncHttpx
import aiohttp
from aiohttp.client import ClientSession
from configs.path_config import IMAGE_PATH, DATA_PATH from configs.path_config import IMAGE_PATH, DATA_PATH
from services.log import logger from services.log import logger
from utils.message_builder import image, face from utils.message_builder import image, face
from configs.config import Config, NICKNAME from configs.config import Config, NICKNAME
from .utils import ai_message_manager
try: try:
import ujson as json import ujson as json
@@ -26,7 +25,7 @@ anime_data = json.load(open(DATA_PATH + "anime.json", "r", encoding="utf8"))
async def get_chat_result(text: str, img_url: str, user_id: int, nickname: str) -> str: async def get_chat_result(text: str, img_url: str, user_id: int, nickname: str) -> str:
""" """
获取 AI 返回值,顺序:图灵 -> 青云客 获取 AI 返回值,顺序: 特殊回复 -> 图灵 -> 青云客
:param text: 问题 :param text: 问题
:param img_url: 图片链接 :param img_url: 图片链接
:param user_id: 用户id :param user_id: 用户id
@@ -34,6 +33,11 @@ async def get_chat_result(text: str, img_url: str, user_id: int, nickname: str)
:return: 回答 :return: 回答
""" """
global index global index
ai_message_manager.add_message(user_id, text)
special_rst = await ai_message_manager.get_result(user_id, nickname)
if special_rst:
ai_message_manager.add_result(user_id, special_rst)
return special_rst
if index == 5: if index == 5:
index = 0 index = 0
if len(text) < 6 and random.random() < 0.6: if len(text) < 6 and random.random() < 0.6:
@@ -41,10 +45,9 @@ async def get_chat_result(text: str, img_url: str, user_id: int, nickname: str)
for key in keys: for key in keys:
if text.find(key) != -1: if text.find(key) != -1:
return random.choice(anime_data[key]).replace("你", nickname) return random.choice(anime_data[key]).replace("你", nickname)
async with aiohttp.ClientSession() as sess: rst = await tu_ling(text, img_url, user_id)
rst = await tu_ling(text, img_url, user_id, sess)
if not rst: if not rst:
rst = await xie_ai(text, sess) rst = await xie_ai(text)
if not rst: if not rst:
return no_result() return no_result()
if nickname: if nickname:
@@ -55,21 +58,24 @@ async def get_chat_result(text: str, img_url: str, user_id: int, nickname: str)
if nickname.find("大人") == -1: if nickname.find("大人") == -1:
nickname += "大~人~" nickname += "大~人~"
rst = rst.replace("小主人", nickname).replace("小朋友", nickname) rst = rst.replace("小主人", nickname).replace("小朋友", nickname)
ai_message_manager.add_result(user_id, rst)
return rst return rst
# 图灵接口 # 图灵接口
async def tu_ling(text: str, img_url: str, user_id: int, sess: ClientSession) -> str: async def tu_ling(text: str, img_url: str, user_id: int) -> str:
""" """
获取图灵接口的回复 获取图灵接口的回复
:param text: 问题 :param text: 问题
:param img_url: 图片链接 :param img_url: 图片链接
:param user_id: 用户id :param user_id: 用户id
:param sess: AIOHTTP SESSION
:return: 图灵回复 :return: 图灵回复
""" """
global index global index
TL_KEY = Config.get_config("ai", "TL_KEY") TL_KEY = Config.get_config("ai", "TL_KEY")
req = None
if not TL_KEY:
return ""
try: try:
if text: if text:
req = { req = {
@@ -96,10 +102,10 @@ async def tu_ling(text: str, img_url: str, user_id: int, sess: ClientSession) ->
index = 0 index = 0
return "" return ""
text = "" text = ""
async with sess.post(url, json=req) as response: response = await AsyncHttpx.post(url, json=req)
if response.status != 200: if response.status_code != 200:
return no_result() return no_result()
resp_payload = json.loads(await response.text()) resp_payload = json.loads(response.text)
if int(resp_payload["intent"]["code"]) in [4003]: if int(resp_payload["intent"]["code"]) in [4003]:
return "" return ""
if resp_payload["results"]: if resp_payload["results"]:
@@ -112,18 +118,15 @@ async def tu_ling(text: str, img_url: str, user_id: int, sess: ClientSession) ->
# 屑 AI # 屑 AI
async def xie_ai(text: str, sess: ClientSession) -> str: async def xie_ai(text: str) -> str:
""" """
获取青云客回复 获取青云客回复
:param text: 问题 :param text: 问题
:param sess: AIOHTTP SESSION
:return: 青云可回复 :return: 青云可回复
""" """
async with sess.get( res = await AsyncHttpx.get(f"http://api.qingyunke.com/api.php?key=free&appid=0&msg={text}")
f"http://api.qingyunke.com/api.php?key=free&appid=0&msg={text}"
) as res:
content = "" content = ""
data = json.loads(await res.text()) data = json.loads(res.text)
if data["result"] == 0: if data["result"] == 0:
content = data["content"] content = data["content"]
if "菲菲" in content: if "菲菲" in content:
@@ -150,7 +153,7 @@ async def xie_ai(text: str, sess: ClientSession) -> str:
return ( return (
content content
if not content and not Config.get_config("ai", "ALAPI_AI_CHECK") if not content and not Config.get_config("ai", "ALAPI_AI_CHECK")
else await check_text(content, sess) else await check_text(content)
) )
@@ -194,18 +197,16 @@ def no_result() -> str:
) )
async def check_text(text: str, sess: ClientSession) -> str: async def check_text(text: str) -> str:
""" """
ALAPI文本检测,主要针对青云客API,检测为恶俗文本改为无回复的回答 ALAPI文本检测,主要针对青云客API,检测为恶俗文本改为无回复的回答
:param text: 回复 :param text: 回复
:param sess: AIOHTTP SESSION
""" """
if not Config.get_config("alapi", "ALAPI_TOKEN"): if not Config.get_config("alapi", "ALAPI_TOKEN"):
return text return text
params = {"token": Config.get_config("alapi", "ALAPI_TOKEN"), "text": text} params = {"token": Config.get_config("alapi", "ALAPI_TOKEN"), "text": text}
try: try:
async with sess.get(check_url, timeout=2, params=params) as response: data = (await AsyncHttpx.get(check_url, timeout=2, params=params)).json()
data = await response.json()
if data["code"] == 200: if data["code"] == 200:
if data["data"]["conclusion_type"] == 2: if data["data"]["conclusion_type"] == 2:
return "" return ""
+137
View File
@@ -0,0 +1,137 @@
from utils.manager import StaticData
from configs.config import NICKNAME
from models.ban_user import BanUser
from typing import Optional
import random
import time
class AiMessageManager(StaticData):
def __init__(self):
super().__init__(None)
self._same_message = [
"为什么要发一样的话?",
"请不要再重复对我说一句话了,不然我就要生气了!",
"别再发这句话了,我已经知道了...",
"你是只会说这一句话吗?",
"[*],你发我也发!",
"[uname],[*]",
f"救命!有笨蛋一直给{NICKNAME}发一样的话!",
"这句话你已经给我发了{}次了,再发就生气!",
]
self._repeat_message = [
f"请不要学{NICKNAME}说话",
f"为什么要一直学{NICKNAME}说话?",
"你再学!你再学我就生气了!",
f"呜呜,你是想欺负{NICKNAME}嘛..",
"[uname]不要再学我说话了!",
"再学我说话,我就把你拉进黑名单(生气",
"你再学![uname]是个笨蛋!",
"你已经学我说话{}次了!别再学了!",
]
def add_message(self, user_id: int, message: str):
"""
添加用户消息
:param user_id: 用户id
:param message: 消息内容
"""
if message:
if self._data.get(user_id) is None:
self._data[user_id] = {
"time": time.time(),
"message": [],
"result": [],
"repeat_count": 0,
}
if time.time() - self._data[user_id]["time"] > 60 * 10:
self._data[user_id]["message"].clear()
self._data[user_id]["time"] = time.time()
self._data[user_id]["message"].append(message.strip())
def add_result(self, user_id: int, message: str):
"""
添加回复用户的消息
:param user_id: 用户id
:param message: 回复消息内容
"""
if message:
if self._data.get(user_id) is None:
self._data[user_id] = {
"time": time.time(),
"message": [],
"result": [],
"repeat_count": 0,
}
if time.time() - self._data[user_id]["time"] > 60 * 10:
self._data[user_id]["result"].clear()
self._data[user_id]["repeat_count"] = 0
self._data[user_id]["time"] = time.time()
self._data[user_id]["result"].append(message.strip())
async def get_result(self, user_id: int, nickname: str) -> Optional[str]:
"""
特殊消息特殊回复
:param user_id: 用户id
:param nickname: 用户昵称
"""
if len(self._data[user_id]["message"]) < 2:
return None
msg = await self._get_user_repeat_message_result(user_id)
if not msg:
msg = await self._get_user_same_message_result(user_id)
if msg:
if "[uname]" in msg:
msg = msg.replace("[uname]", nickname)
if not msg.startswith("生气了!你好烦,闭嘴!") and "[*]" in msg:
msg = msg.replace("[*]", self._data[user_id]["message"][-1])
return msg
async def _get_user_same_message_result(self, user_id: int) -> Optional[str]:
"""
重复消息回复
:param user_id: 用户id
"""
msg = self._data[user_id]["message"][-1]
cnt = 0
_tmp = self._data[user_id]["message"][:-1]
_tmp.reverse()
for s in _tmp:
if s == msg:
cnt += 1
else:
break
if cnt > 1:
if random.random() < 0.5 and cnt > 3:
rand = random.randint(60, 300)
await BanUser.ban(user_id, 9, rand)
self._data[user_id]["message"].clear()
return f"生气了!你好烦,闭嘴!给我老实安静{rand}秒"
return random.choice(self._same_message).format(cnt)
return None
async def _get_user_repeat_message_result(self, user_id: int) -> Optional[str]:
"""
复读真寻的消息回复
:param user_id: 用户id
"""
msg = self._data[user_id]["message"][-1]
if self._data[user_id]["result"]:
rst = self._data[user_id]["result"][-1]
else:
return None
if msg == rst:
self._data[user_id]["repeat_count"] += 1
cnt = self._data[user_id]["repeat_count"]
if cnt > 1:
if random.random() < 0.5 and cnt > 3:
rand = random.randint(60, 300)
await BanUser.ban(user_id, 9, rand)
self._data[user_id]["result"].clear()
self._data[user_id]["repeat_count"] = 0
return f"生气了!你好烦,闭嘴!给我老实安静{rand}秒"
return random.choice(self._repeat_message).format(cnt)
return None
ai_message_manager = AiMessageManager()
Regular → Executable
+4 -1
View File
@@ -1,7 +1,6 @@
from configs.config import Config from configs.config import Config
import nonebot import nonebot
nonebot.load_plugins("plugins/alapi")
Config.add_plugin_config( Config.add_plugin_config(
"alapi", "alapi",
@@ -9,3 +8,7 @@ Config.add_plugin_config(
None, None,
help_="在https://admin.alapi.cn/user/login登录后获取token" help_="在https://admin.alapi.cn/user/login登录后获取token"
) )
nonebot.load_plugins("plugins/alapi")
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
+2 -4
View File
@@ -4,7 +4,7 @@ from utils.message_builder import image
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from typing import Optional from typing import Optional
from configs.config import Config from configs.config import Config
import aiohttp from utils.http_utils import AsyncHttpx
async def get_data(url: str, params: Optional[dict] = None) -> "Union[dict, str], int": async def get_data(url: str, params: Optional[dict] = None) -> "Union[dict, str], int":
@@ -16,10 +16,8 @@ async def get_data(url: str, params: Optional[dict] = None) -> "Union[dict, str]
if not params: if not params:
params = {} params = {}
params["token"] = Config.get_config("alapi", "ALAPI_TOKEN") params["token"] = Config.get_config("alapi", "ALAPI_TOKEN")
async with aiohttp.ClientSession() as session:
try: try:
async with session.get(url, timeout=2, params=params) as response: data = (await AsyncHttpx.get(url, params=params, timeout=5)).json()
data = await response.json()
if data["code"] == 200: if data["code"] == 200:
if not data["data"]: if not data["data"]:
return "没有搜索到...", 997 return "没有搜索到...", 997
+48
View File
@@ -0,0 +1,48 @@
from nonebot import on_command
from services.log import logger
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from nonebot.typing import T_State
from utils.http_utils import AsyncHttpx
from configs.config import Config
from .data_source import get_data
__zx_plugin_name__ = "鸡汤"
__plugin_usage__ = """
usage:
不喝点什么感觉有点不舒服
指令:
鸡汤
""".strip()
__plugin_des__ = "喏,亲手为你煮的鸡汤"
__plugin_cmd__ = ["鸡汤"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["鸡汤", "毒鸡汤"],
}
url = "https://v2.alapi.cn/api/soul"
jitang = on_command("鸡汤", aliases={"毒鸡汤"}, priority=5, block=True)
@jitang.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
try:
data, code = await get_data(url)
if code != 200:
await jitang.finish(data, at_sender=True)
await jitang.send(data["data"]["content"])
logger.info(
f"(USER {event.user_id}, GROUP "
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 发送鸡汤:" + data["data"]["content"]
)
except Exception as e:
await jitang.send("鸡汤煮坏掉了...")
logger.error(f"鸡汤煮坏掉了 {type(e)}:{e}")
Regular → Executable
View File
Regular → Executable
+25 -30
View File
@@ -3,13 +3,13 @@ from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
from nonebot.typing import T_State from nonebot.typing import T_State
from services.log import logger from services.log import logger
from .data_source import get_data, gen_wbtop_pic from .data_source import get_data, gen_wbtop_pic
from utils.browser import get_browser
from utils.utils import get_message_text, is_number from utils.utils import get_message_text, is_number
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from utils.message_builder import image from utils.message_builder import image
from utils.http_utils import AsyncPlaywright
import asyncio import asyncio
__zx_plugin_name__ = '微博热搜' __zx_plugin_name__ = "微博热搜"
__plugin_usage__ = """ __plugin_usage__ = """
usage: usage:
在QQ上吃个瓜 在QQ上吃个瓜
@@ -18,21 +18,21 @@ usage:
微博热搜 [id]:截图该热搜页面 微博热搜 [id]:截图该热搜页面
示例:微博热搜 5 示例:微博热搜 5
""".strip() """.strip()
__plugin_des__ = '刚买完瓜,在吃瓜现场' __plugin_des__ = "刚买完瓜,在吃瓜现场"
__plugin_cmd__ = ['微博热搜', '微博热搜 [id]'] __plugin_cmd__ = ["微博热搜", "微博热搜 [id]"]
__plugin_version__ = 0.1 __plugin_version__ = 0.1
__plugin_author__ = 'HibiKier' __plugin_author__ = "HibiKier"
__plugin_settings__ = { __plugin_settings__ = {
"level": 5, "level": 5,
"default_status": True, "default_status": True,
"limit_superuser": False, "limit_superuser": False,
"cmd": ['微博热搜'], "cmd": ["微博热搜"],
} }
wbtop = on_command("wbtop", aliases={'微博热搜'}, priority=5, block=True) wbtop = on_command("wbtop", aliases={"微博热搜"}, priority=5, block=True)
wbtop_url = 'https://v2.alapi.cn/api/new/wbtop' wbtop_url = "https://v2.alapi.cn/api/new/wbtop"
wbtop_data = [] wbtop_data = []
@@ -45,32 +45,27 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
data, code = await get_data(wbtop_url) data, code = await get_data(wbtop_url)
if code != 200: if code != 200:
await wbtop.finish(data, at_sender=True) await wbtop.finish(data, at_sender=True)
wbtop_data = data['data'] wbtop_data = data["data"]
if not msg: if not msg:
img = await asyncio.get_event_loop().run_in_executor(None, gen_wbtop_pic, wbtop_data) img = await asyncio.get_event_loop().run_in_executor(
None, gen_wbtop_pic, wbtop_data
)
await wbtop.send(img) await wbtop.send(img)
logger.info( logger.info(
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})" f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 查询微博热搜") f" 查询微博热搜"
)
if is_number(msg) and 0 < int(msg) <= 50: if is_number(msg) and 0 < int(msg) <= 50:
url = wbtop_data[int(msg) - 1]['url'] url = wbtop_data[int(msg) - 1]["url"]
browser = await get_browser()
page = None
try: try:
if not browser: await wbtop.send("开始截取数据...")
logger.warning('获取 browser 失败,请部署至 linux 环境....') img = await AsyncPlaywright.screenshot(
await wbtop.finish('获取 browser 对象失败...') url,
page = await browser.new_page() f"{IMAGE_PATH}/temp/wbtop_{event.user_id}.png",
await page.goto(url, wait_until='networkidle', timeout=10000) "#pl_feedlist_index",
await page.set_viewport_size({"width": 2560, "height": 1080}) sleep=5
await asyncio.sleep(5) )
div = await page.query_selector("#pl_feedlist_index") await wbtop.send(img)
await div.screenshot(path=f'{IMAGE_PATH}/temp/wbtop_{event.user_id}.png', timeout=100000)
await page.close()
await wbtop.send(image(f'wbtop_{event.user_id}.png', 'temp'))
except Exception as e: except Exception as e:
logger.error(f'微博热搜截图出错... {type(e)}: {e}') logger.error(f"微博热搜截图出错... {type(e)}: {e}")
if page: await wbtop.send("发生了一些错误.....")
await page.close()
await wbtop.send('发生了一些错误.....')
Regular → Executable
+1
View File
@@ -206,6 +206,7 @@ async def _():
await sub_manager.reload_sub_data() await sub_manager.reload_sub_data()
sub = await sub_manager.random_sub_data() sub = await sub_manager.random_sub_data()
if sub: if sub:
logger.info(f"Bilibili订阅开始检测:{sub.sub_id}")
rst = await get_sub_status(sub.sub_id, sub.sub_type) rst = await get_sub_status(sub.sub_id, sub.sub_type)
await send_sub_msg(rst, sub, bot) await send_sub_msg(rst, sub, bot)
if sub.sub_type == "live": if sub.sub_type == "live":
+5 -8
View File
@@ -14,7 +14,7 @@ from datetime import datetime
from utils.browser import get_browser from utils.browser import get_browser
from services.db_context import db from services.db_context import db
from services.log import logger from services.log import logger
import aiohttp from utils.http_utils import AsyncHttpx
import random import random
@@ -150,7 +150,7 @@ async def delete_sub(sub_id: str, sub_user: str) -> str:
:param sub_id: 订阅 id :param sub_id: 订阅 id
:param sub_user: 订阅用户 id # 7384933:private or 7384933:2342344(group) :param sub_user: 订阅用户 id # 7384933:private or 7384933:2342344(group)
""" """
if await BilibiliSub.delete_bilibili_sub(sub_id, sub_user): if await BilibiliSub.delete_bilibili_sub(int(sub_id), sub_user):
return f"已成功取消订阅:{sub_id}" return f"已成功取消订阅:{sub_id}"
else: else:
return f"取消订阅:{sub_id} 失败,请检查是否订阅过该Id...." return f"取消订阅:{sub_id} 失败,请检查是否订阅过该Id...."
@@ -162,15 +162,12 @@ async def get_media_id(keyword: str) -> dict:
:param keyword: 番剧名称 :param keyword: 番剧名称
""" """
params = {"keyword": keyword} params = {"keyword": keyword}
async with aiohttp.ClientSession() as session:
for _ in range(3): for _ in range(3):
try: try:
_season_data = {} _season_data = {}
async with session.get( response = await AsyncHttpx.get(bilibili_search_url, params=params, timeout=5)
bilibili_search_url, timeout=5, params=params if response.status_code == 200:
) as response: data = response.json()
if response.status == 200:
data = await response.json()
if data.get("data"): if data.get("data"):
for item in data["data"]["result"]: for item in data["data"]["result"]:
if item["result_type"] == "media_bangumi": if item["result_type"] == "media_bangumi":
Regular → Executable
View File
Regular → Executable
+19 -20
View File
@@ -1,12 +1,12 @@
from utils.image_utils import CreateImg from utils.image_utils import CreateImg
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from utils.http_utils import AsyncHttpx
from pathlib import Path from pathlib import Path
from bilibili_api import user from bilibili_api import user
from io import BytesIO from io import BytesIO
import aiohttp
BORDER_PATH = Path(IMAGE_PATH) / 'border' BORDER_PATH = Path(IMAGE_PATH) / "border"
BORDER_PATH.mkdir(parents=True, exist_ok=True) BORDER_PATH.mkdir(parents=True, exist_ok=True)
@@ -16,9 +16,7 @@ async def get_pic(url: str) -> bytes:
:param url: 图像链接 :param url: 图像链接
:return: 图像二进制 :return: 图像二进制
""" """
async with aiohttp.ClientSession() as session: return (await AsyncHttpx.get(url, timeout=10)).content
async with session.get(url, timeout=2) as response:
return await response.read()
async def create_live_des_image(uid: int, title: str, cover: str, tags: str, des: str): async def create_live_des_image(uid: int, title: str, cover: str, tags: str, des: str):
@@ -33,17 +31,26 @@ async def create_live_des_image(uid: int, title: str, cover: str, tags: str, des
""" """
u = user.User(uid) u = user.User(uid)
user_info = await u.get_user_info() user_info = await u.get_user_info()
name = user_info['name'] name = user_info["name"]
sex = user_info['sex'] sex = user_info["sex"]
face = user_info['face'] face = user_info["face"]
sign = user_info['sign'] sign = user_info["sign"]
ava = CreateImg(100, 100, background=BytesIO(await get_pic(face))) ava = CreateImg(100, 100, background=BytesIO(await get_pic(face)))
ava.circle() ava.circle()
cover = CreateImg(470, 265, background=BytesIO(await get_pic(cover))) cover = CreateImg(470, 265, background=BytesIO(await get_pic(cover)))
print() print()
def _create_live_des_image(title: str, cover: CreateImg, tags: str, des: str, user_name: str, sex: str, sign: str, ava: CreateImg): def _create_live_des_image(
title: str,
cover: CreateImg,
tags: str,
des: str,
user_name: str,
sex: str,
sign: str,
ava: CreateImg,
):
""" """
生成主播简介图片 生成主播简介图片
:param title: 直播间标题 :param title: 直播间标题
@@ -56,17 +63,9 @@ def _create_live_des_image(title: str, cover: CreateImg, tags: str, des: str, us
:param ava: 主播头像 :param ava: 主播头像
:return: :return:
""" """
border = BORDER_PATH / '0.png' border = BORDER_PATH / "0.png"
border_img = None border_img = None
if border.exists(): if border.exists():
border_img = CreateImg(1772, 2657, background=border) border_img = CreateImg(1772, 2657, background=border)
bk = CreateImg(1772, 2657, font_size=30) bk = CreateImg(1772, 2657, font_size=30)
bk.paste(cover, (0, 100), center_type='by_width') bk.paste(cover, (0, 100), center_type="by_width")
Regular → Executable
+1 -4
View File
@@ -7,7 +7,6 @@ from nonebot.adapters.cqhttp import PrivateMessageEvent
from utils.utils import get_message_text from utils.utils import get_message_text
from nonebot.adapters.cqhttp.permission import PRIVATE from nonebot.adapters.cqhttp.permission import PRIVATE
from asyncio.exceptions import TimeoutError from asyncio.exceptions import TimeoutError
from aiohttp.client_exceptions import ServerDisconnectedError
__zx_plugin_name__ = "磁力搜索" __zx_plugin_name__ = "磁力搜索"
__plugin_usage__ = """ __plugin_usage__ = """
@@ -89,11 +88,9 @@ async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
send_flag = True send_flag = True
except TimeoutError: except TimeoutError:
await bt.finish(f"搜索 {keyword} 超时...") await bt.finish(f"搜索 {keyword} 超时...")
except ServerDisconnectedError:
await bt.finish(f"搜索 {keyword} 连接失败")
except Exception as e: except Exception as e:
await bt.finish(f"bt 其他未知错误..") await bt.finish(f"bt 其他未知错误..")
logger.error(f"bt 错误 e:{e}") logger.error(f"bt 错误 {type(e)}:{e}")
if not send_flag: if not send_flag:
await bt.send(f"{keyword} 未搜索到...") await bt.send(f"{keyword} 未搜索到...")
logger.info(f"USER {event.user_id} BT搜索 {keyword} 第 {page} 页") logger.info(f"USER {event.user_id} BT搜索 {keyword} 第 {page} 页")
Regular → Executable
+15 -14
View File
@@ -1,8 +1,6 @@
from utils.user_agent import get_user_agent from utils.http_utils import AsyncHttpx
import aiohttp
from configs.config import Config from configs.config import Config
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from utils.utils import get_local_proxy
import platform import platform
if platform.system() == "Windows": if platform.system() == "Windows":
@@ -15,11 +13,12 @@ url = "http://www.eclzz.world"
async def get_bt_info(keyword: str, page: str): async def get_bt_info(keyword: str, page: str):
async with aiohttp.ClientSession(headers=get_user_agent()) as session: """
async with session.get( 获取资源信息
f"{url}/s/{keyword}_rel_{page}.html", proxy=get_local_proxy(), timeout=5 :param keyword: 关键词
) as response: :param page: 页数
text = await response.text() """
text = (await AsyncHttpx.get(f"{url}/s/{keyword}_rel_{page}.html", timeout=5)).text
if text.find("大约0条结果") != -1: if text.find("大约0条结果") != -1:
return return
soup = BeautifulSoup(text, "lxml") soup = BeautifulSoup(text, "lxml")
@@ -38,13 +37,15 @@ async def get_bt_info(keyword: str, page: str):
itype = spans[0].text itype = spans[0].text
create_time = spans[1].find("b").text create_time = spans[1].find("b").text
file_size = spans[2].find("b").text file_size = spans[2].find("b").text
link = await get_download_link(divs[0].find("a")["href"], session) link = await get_download_link(divs[0].find("a")["href"])
yield title, itype, create_time, file_size, link yield title, itype, create_time, file_size, link
async def get_download_link(_url: str, session) -> str: async def get_download_link(_url: str) -> str:
async with session.get( """
f"{url}{_url}", proxy=get_local_proxy(), timeout=30 获取资源下载地址
) as response: :param _url: 链接
soup = BeautifulSoup(await response.text(), "lxml") """
text = (await AsyncHttpx.get(f"{url}{_url}")).text
soup = BeautifulSoup(text, "lxml")
return soup.find("a", {"id": "down-url"})["href"] return soup.find("a", {"id": "down-url"})["href"]
Regular → Executable
+6 -6
View File
@@ -25,22 +25,22 @@ __plugin_settings__ = {
} }
songpicker = on_command("点歌", priority=5, block=True) music = on_command("点歌", priority=5, block=True)
@songpicker.handle() @music.handle()
async def handle_first_receive(bot: Bot, event: Event, state: T_State): async def handle_first_receive(bot: Bot, event: Event, state: T_State):
args = str(event.get_message()).strip() args = str(event.get_message()).strip()
if args: if args:
state["song_name"] = args state["song_name"] = args
@songpicker.got("song_name", prompt="歌名是?") @music.got("song_name", prompt="歌名是?")
async def _(bot: Bot, event: Event, state: T_State): async def _(bot: Bot, event: Event, state: T_State):
song = state["song_name"] song = state["song_name"]
song_id = await get_song_id(song) song_id = await get_song_id(song)
if not song_id: if not song_id:
await songpicker.finish("没有找到这首歌!", at_sender=True) await music.finish("没有找到这首歌!", at_sender=True)
for _ in range(3): for _ in range(3):
song_content = [{"type": "music", "data": {"type": 163, "id": song_id}}] song_content = [{"type": "music", "data": {"type": 163, "id": song_id}}]
logger.info( logger.info(
@@ -48,9 +48,9 @@ async def _(bot: Bot, event: Event, state: T_State):
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})" f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 点歌 :{song}" f" 点歌 :{song}"
) )
await songpicker.finish(song_content) await music.finish(song_content)
else: else:
await songpicker.finish("网易云繁忙...") await music.finish("网易云繁忙...")
Regular → Executable
+16 -25
View File
@@ -1,4 +1,4 @@
import aiohttp from utils.http_utils import AsyncHttpx
import json import json
@@ -7,24 +7,22 @@ cookies = {"appver": "2.0.2"}
async def search_song(song_name: str): async def search_song(song_name: str):
async with aiohttp.ClientSession( """
headers=headers, cookies=cookies 搜索歌曲
) as session: :param song_name: 歌名
async with session.post( """
r = await AsyncHttpx.post(
f"http://music.163.com/api/search/get/", f"http://music.163.com/api/search/get/",
data={"s": song_name, "limit": 1, "type": 1, "offset": 0}, data={"s": song_name, "limit": 1, "type": 1, "offset": 0},
) as r: )
if r.status != 200: if r.status_code != 200:
return None return None
r = await r.text() return json.loads(r.text)
return json.loads(r)
async def get_song_id(songName: str) -> int: async def get_song_id(song_name: str) -> int:
""" """ """
根据用户输入的songName 获取候选songId列表 [默认songId数量:5] r = await search_song(song_name)
"""
r = await search_song(songName)
return r["result"]["songs"][0]["id"] return r["result"]["songs"][0]["id"]
@@ -32,16 +30,9 @@ async def get_song_info(songId: int):
""" """
获取歌曲信息 获取歌曲信息
""" """
async with aiohttp.ClientSession( r = await AsyncHttpx.post(
headers=headers, cookies=cookies
) as session:
async with session.post(
f"http://music.163.com/api/song/detail/?id={songId}&ids=%5B{songId}%5D", f"http://music.163.com/api/song/detail/?id={songId}&ids=%5B{songId}%5D",
) as r: )
if r.status != 200: if r.status_code != 200:
return None return None
r = await r.text() return json.loads(r.text)
return json.loads(r)
Regular → Executable
View File
Regular → Executable
+7 -18
View File
@@ -1,11 +1,7 @@
import psutil import psutil
import aiohttp
import time import time
from datetime import datetime from datetime import datetime
from utils.user_agent import get_user_agent from utils.http_utils import AsyncHttpx
from asyncio.exceptions import TimeoutError
from aiohttp.client_exceptions import ClientConnectorError
from utils.utils import get_local_proxy
from utils.image_utils import CreateImg from utils.image_utils import CreateImg
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from pathlib import Path from pathlib import Path
@@ -34,22 +30,15 @@ class Check:
self.disk = psutil.disk_usage("/").percent self.disk = psutil.disk_usage("/").percent
async def check_network(self): async def check_network(self):
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
try: try:
async with session.get( await AsyncHttpx.get("https://www.baidu.com/", timeout=5)
"https://www.baidu.com/", proxy=get_local_proxy(), timeout=3 except Exception as e:
) as response: logger.warning(f"访问BaiDu失败... {type(e)}: {e}")
pass
except (TimeoutError, ClientConnectorError) as e:
logger.warning(f"访问BaiDu失败... e: {e}")
self.baidu = 404 self.baidu = 404
try: try:
async with session.get( await AsyncHttpx.get("https://www.google.com/", timeout=5)
"https://www.google.com/", proxy=get_local_proxy(), timeout=3 except Exception as e:
) as response: logger.warning(f"访问Google失败... {type(e)}: {e}")
pass
except (TimeoutError, ClientConnectorError) as e:
logger.warning(f"访问Google失败... e: {e}")
self.google = 404 self.google = 404
def check_user(self): def check_user(self):
+14 -14
View File
@@ -110,17 +110,17 @@ async def _():
f"当前版本:{_version},最新版本:{latest_version}\n" f"当前版本:{_version},最新版本:{latest_version}\n"
f"尝试自动更新...", f"尝试自动更新...",
) )
try: # try:
code = await check_update(bot) # code = await check_update(bot)
except Exception as e: # except Exception as e:
logger.error(f"更新真寻未知错误 {type(e)}:{e}") # logger.error(f"更新真寻未知错误 {type(e)}:{e}")
await bot.send_private_msg( # await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]), # user_id=int(list(bot.config.superusers)[0]),
message=f"更新真寻未知错误 {type(e)}:{e}\n", # message=f"更新真寻未知错误 {type(e)}:{e}\n",
) # )
else: # else:
if code == 200: # if code == 200:
await bot.send_private_msg( # await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]), # user_id=int(list(bot.config.superusers)[0]),
message=f"更新完毕,请重启真寻....", # message=f"更新完毕,请重启真寻....",
) # )
+8 -27
View File
@@ -1,18 +1,14 @@
from aiohttp.client_exceptions import ClientConnectorError
from nonebot.adapters.cqhttp import Bot, Message from nonebot.adapters.cqhttp import Bot, Message
from utils.user_agent import get_user_agent
from utils.utils import get_local_proxy
from utils.image_utils import CreateImg from utils.image_utils import CreateImg
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from utils.message_builder import image from utils.message_builder import image
from utils.http_utils import AsyncHttpx
from typing import List from typing import List
from services.log import logger from services.log import logger
from pathlib import Path from pathlib import Path
import ujson as json import ujson as json
import nonebot import nonebot
import asyncio import asyncio
import aiofiles
import aiohttp
import platform import platform
import tarfile import tarfile
import shutil import shutil
@@ -77,7 +73,7 @@ async def check_update(bot: Bot) -> 'int, str':
message=f"检测真寻已更新,当前版本:{_version},最新版本:{latest_version}\n" f"开始更新.....", message=f"检测真寻已更新,当前版本:{_version},最新版本:{latest_version}\n" f"开始更新.....",
) )
logger.info(f"开始下载真寻最新版文件....") logger.info(f"开始下载真寻最新版文件....")
if await download_latest_file(tar_gz_url): if await AsyncHttpx.download_file(tar_gz_url, zhenxun_latest_tar_gz):
logger.info("下载真寻最新版文件完成....") logger.info("下载真寻最新版文件完成....")
error = await asyncio.get_event_loop().run_in_executor( error = await asyncio.get_event_loop().run_in_executor(
None, _file_handle, latest_version None, _file_handle, latest_version
@@ -194,38 +190,23 @@ def _file_handle(latest_version: str) -> str:
# 获取最新版本号 # 获取最新版本号
async def get_latest_version_data() -> dict: async def get_latest_version_data() -> dict:
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
for _ in range(3): for _ in range(3):
try: try:
async with session.get(release_url, proxy=get_local_proxy()) as res: res = await AsyncHttpx.get(release_url)
if res.status == 200: if res.status_code == 200:
return await res.json() return res.json()
except (TimeoutError, ClientConnectorError): except TimeoutError:
pass pass
except Exception as e:
logger.error(f"检查更新真寻获取版本失败 {type(e)}:{e}")
return {} 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: def check_old_lines(lines: List[str], line: str) -> str:
if "=" not in line: if "=" not in line:
return line return line
for l in lines: for l in lines:
if "=" in l and l.split("=")[0].strip() == line.split("=")[0].strip(): if "=" in l and l.split("=")[0].strip() == line.split("=")[0].strip():
if l.split("=")[1].strip() == 'None':
return l return l
return line return line
Regular → Executable
+18 -34
View File
@@ -1,13 +1,10 @@
from nonebot import on_command from nonebot import on_command
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent from nonebot.adapters.cqhttp import Bot, MessageEvent
from services.log import logger
from asyncio.exceptions import TimeoutError
from utils.message_builder import image from utils.message_builder import image
from configs.path_config import IMAGE_PATH from services.log import logger
from utils.utils import get_local_proxy from utils.manager import withdraw_message_manager
import aiohttp from configs.config import Config
import aiofiles
__zx_plugin_name__ = "coser" __zx_plugin_name__ = "coser"
__plugin_usage__ = """ __plugin_usage__ = """
@@ -26,44 +23,31 @@ __plugin_settings__ = {
"limit_superuser": False, "limit_superuser": False,
"cmd": ["cos", "coser", "括丝", "COS", "Cos", "cOS", "coS"], "cmd": ["cos", "coser", "括丝", "COS", "Cos", "cOS", "coS"],
} }
__plugin_configs__ = {
"WITHDRAW_COS_MESSAGE": {
"value": (0, 1),
"help": "自动撤回,参1:延迟撤回色图时间(秒),0 为关闭 | 参2:监控聊天类型,0(私聊) 1(群聊) 2(群聊+私聊)",
"default_value": (0, 1),
},
}
coser = on_command( coser = on_command(
"cos", aliases={"coser", "括丝", "COS", "Cos", "cOS", "coS"}, priority=5, block=True "cos", aliases={"coser", "括丝", "COS", "Cos", "cOS", "coS"}, priority=5, block=True
) )
url = "http://ovooa.com/API/cosplay/api.php" url = "http://iw233.cn/API/cos.php"
@coser.handle() @coser.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State): async def _(bot: Bot, event: MessageEvent, state: T_State):
async with aiohttp.ClientSession() as session:
try: try:
for _ in range(3): msg_id = await coser.send(image(url))
try: withdraw_message_manager.withdraw_message(
async with session.get(url, proxy=get_local_proxy(), timeout=2, verify_ssl=False) as response: event,
_url = (await response.json())['text'] msg_id["message_id"],
async with session.get( Config.get_config("coser", "WITHDRAW_COS_MESSAGE"),
_url, timeout=5, proxy=get_local_proxy(), verify_ssl=False
) as res:
if res.status == 200:
async with aiofiles.open(
f"{IMAGE_PATH}/temp/{event.user_id}_coser.jpg", "wb"
) as f:
await f.write(await res.read())
logger.info(
f"(USER {event.user_id}, "
f"GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 发送COSER"
) )
await coser.send(
image(f"{event.user_id}_coser.jpg", "temp")
)
break
except (TimeoutError, KeyError):
pass
else:
await coser.send("你cos给我看!")
except Exception as e: except Exception as e:
await coser.send("发生了预料之外的错误..请稍后再试或联系管理员修复...") await coser.send("你cos给我看!")
logger.error(f"coser 发送了未知错误 {type(e)}:{e}") logger.error(f"coser 发送了未知错误 {type(e)}:{e}")
-69
View File
@@ -1,69 +0,0 @@
from nonebot import on_command
from nonebot.typing import T_State
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, MessageEvent
from utils.utils import get_message_text, is_number
from .data_source import get_csgola_data, get_5e_data
from services.log import logger
__zx_plugin_name__ = "cs国服/平台信息查找"
__plugin_usage__ = """
usage:
快速查询csgo战绩和数据
指令:
cs国服查询 [steam主页个人id]
5e查询 [5e战绩个人名称]
示例:cs国服查询 23848238483
示例:5e查询 poster
"""
__plugin_des__ = "什么?你也是rush B玩家?"
__plugin_cmd__ = ["cs国服查询 [steam主页个人id]", "5e查询 [5e战绩个人名称]"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["csgo战绩查询", "cs国服查询", "5e查询"],
}
csgola = on_command("cs国服查询", priority=5, block=True)
csgo5e = on_command("5e查询", priority=5, block=True)
@csgola.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json())
if "http" in msg:
msg = msg[:-1] if msg[-1] == "/" else msg
msg = msg.split("/")[-1]
if not is_number(msg):
await csgola.finish("Id必须为数字!", at_sender=True)
await csgola.send("开始查找...")
img, code = await get_csgola_data(int(msg))
if code == 200:
await csgola.send(img, at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP "
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 查询csgo国服战绩:{msg}"
)
else:
await csgola.send(img, at_sender=True)
@csgo5e.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
msg = get_message_text(event.json())
await csgola.send("开始查找...")
img, code = await get_5e_data(msg)
if code == 200:
await csgo5e.send(img, at_sender=True)
logger.info(
f"(USER {event.user_id}, GROUP "
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
f" 查询csgo国服战绩:{msg}"
)
else:
await csgo5e.send(img, at_sender=True)
-130
View File
@@ -1,130 +0,0 @@
from configs.path_config import IMAGE_PATH
from utils.image_utils import CreateImg
from utils.message_builder import image
from services.log import logger
from utils.browser import get_browser
from playwright._impl._api_types import TimeoutError
csgola_url = "https://www.csgola.com/player/"
_5e_url = "https://arena.5eplay.com/data/player/"
async def get_csgola_data(uid: int) -> "str, int":
page = None
try:
browser = await get_browser()
if not browser:
return "", 997
page = await browser.new_page()
for _ in range(3):
try:
await page.goto(f"{csgola_url}{uid}", wait_until="networkidle", timeout=10000)
break
except TimeoutError:
pass
else:
return '连接超时...', 995
await page.set_viewport_size({"width": 2560, "height": 1080})
data = await page.query_selector_all(".panel-body")
if not data:
return "未查询到该Id....", 999
await data[0].screenshot(path=f"{IMAGE_PATH}/temp/{uid}_1.png", timeout=100000)
await data[3].screenshot(path=f"{IMAGE_PATH}/temp/{uid}_2.png", timeout=100000)
await data[5].screenshot(path=f"{IMAGE_PATH}/temp/{uid}_3.png", timeout=100000)
await data[7].screenshot(path=f"{IMAGE_PATH}/temp/{uid}_5.png", timeout=100000)
ava = await page.query_selector("div.container:nth-child(4) > div:nth-child(1)")
await ava.screenshot(path=f"{IMAGE_PATH}/temp/{uid}_0.png", timeout=100000)
weapon_data = await page.query_selector(".gun-stats-sec")
await weapon_data.screenshot(
path=f"{IMAGE_PATH}/temp/{uid}_4.png", timeout=100000
)
ava = CreateImg(0, 0, background=f"{IMAGE_PATH}/temp/{uid}_0.png")
statistical_data = CreateImg(0, 0, background=f"{IMAGE_PATH}/temp/{uid}_1.png")
combined_data = CreateImg(0, 0, background=f"{IMAGE_PATH}/temp/{uid}_2.png")
detailed_data = CreateImg(0, 0, background=f"{IMAGE_PATH}/temp/{uid}_3.png")
weapon_data = CreateImg(0, 0, background=f"{IMAGE_PATH}/temp/{uid}_4.png")
map_data = CreateImg(0, 0, background=f"{IMAGE_PATH}/temp/{uid}_5.png")
if statistical_data.h > 300:
statistical_data.crop((0, 0, statistical_data.w, 300))
if combined_data.h > 260:
combined_data.crop((0, 0, combined_data.w, 260))
if detailed_data.h > 400:
detailed_data.crop((0, 0, detailed_data.w, 400))
weapon_data.crop((0, 100, weapon_data.w, weapon_data.h))
map_data.crop((0, 310, map_data.w, map_data.h))
height = (
ava.h
+ statistical_data.h
+ combined_data.h
+ detailed_data.h
+ weapon_data.h
+ map_data.h
)
bk = CreateImg(1168, height)
current_h = 0
for img in [
ava,
statistical_data,
combined_data,
detailed_data,
weapon_data,
map_data,
]:
bk.paste(img, (0, current_h))
current_h += img.h
bk.save(f"{IMAGE_PATH}/temp/csgo_{uid}.png")
except Exception as e:
logger.error(f"生成csgola图片错误 {type(e)}:{e}")
if page:
await page.close()
return "发生了错误....", 998
if page:
await page.close()
return image(f"csgo_{uid}.png", "temp"), 200
async def get_5e_data(uname: str) -> "str, int":
page = None
try:
browser = await get_browser()
if not browser:
return "", 997
page = await browser.new_page()
await page.goto(f"{_5e_url}{uname}", wait_until="networkidle", timeout=10000)
if "HTTP ERROR 404" in await page.content():
return "未查询到该玩家...", 999
await page.set_viewport_size({"width": 2560, "height": 1080})
body = await page.query_selector("body")
await body.screenshot(
path=f"{IMAGE_PATH}/temp/csgo_{uname}_0.png", timeout=100000
)
await page.click("a.match-tab-item:nth-child(2)")
body = await page.query_selector("body")
await body.screenshot(
path=f"{IMAGE_PATH}/temp/csgo_{uname}_1.png", timeout=100000
)
await page.click("a.match-tab-item:nth-child(1)")
body = await page.query_selector("body")
await body.screenshot(
path=f"{IMAGE_PATH}/temp/csgo_{uname}_2.png", timeout=100000
)
bk = CreateImg(1344 * 3, 2307)
current_w = 0
for i in range(3):
body = CreateImg(0, 0, background=f"{IMAGE_PATH}/temp/csgo_{uname}_{i}.png")
body.crop((600, 90, body.w - 600, body.h - 410))
bk.paste(body, (current_w, 0))
current_w += 1344
bk.save(f"{IMAGE_PATH}/temp/csgo_{uname}.png")
except Exception as e:
logger.error(f"生成5e图片错误 {type(e)}:{e}")
if page:
await page.close()
return "发生了错误...", 998
if page:
await page.close()
return image(f"csgo_{uname}.png", "temp"), 200
Regular → Executable
View File
Regular → Executable
View File
+11 -18
View File
@@ -1,11 +1,11 @@
import aiohttp
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
import re
from datetime import datetime, timedelta from datetime import datetime, timedelta
from .config import DRAW_PATH from .config import DRAW_PATH
from pathlib import Path from pathlib import Path
from asyncio.exceptions import TimeoutError from asyncio.exceptions import TimeoutError
from services.log import logger from services.log import logger
from utils.http_utils import AsyncHttpx
import re
try: try:
import ujson as json import ujson as json
except ModuleNotFoundError: except ModuleNotFoundError:
@@ -66,16 +66,14 @@ class PrtsAnnouncement:
self.game_name = '明日方舟' self.game_name = '明日方舟'
async def _get_announcement_text(self): async def _get_announcement_text(self):
async with aiohttp.ClientSession(headers=headers) as session: text = (await AsyncHttpx.get(prts_url)).text
async with session.get(prts_url, timeout=7) as res: soup = BeautifulSoup(text, 'lxml')
soup = BeautifulSoup(await res.text(), 'lxml')
ol = soup.find('ol', {'class': 'articleList active', 'data-category-key': 'LATEST'}) ol = soup.find('ol', {'class': 'articleList active', 'data-category-key': 'LATEST'})
for li in ol: for li in ol:
itype = li.find('span', {'class': 'articleItemCate'}).text itype = li.find('span', {'class': 'articleItemCate'}).text
if itype == '活动': if itype == '活动':
a = li.find('a')['href'] a = li.find('a')['href']
async with session.get(f'https://ak.hypergryph.com{a}', headers=headers, timeout=7) as res: return (await AsyncHttpx.get(f'https://ak.hypergryph.com{a}')).text
return await res.text()
async def update_up_char(self): async def update_up_char(self):
prts_up_char.parent.mkdir(parents=True, exist_ok=True) prts_up_char.parent.mkdir(parents=True, exist_ok=True)
@@ -147,9 +145,7 @@ class GenshinAnnouncement:
self.game_name = '原神' self.game_name = '原神'
async def _get_announcement_text(self): async def _get_announcement_text(self):
async with aiohttp.ClientSession(headers=headers) as session: return (await AsyncHttpx.get(genshin_url)).text
async with session.get(genshin_url, timeout=7) as res:
return await res.text()
async def update_up_char(self): async def update_up_char(self):
genshin_up_char.parent.mkdir(exist_ok=True, parents=True) genshin_up_char.parent.mkdir(exist_ok=True, parents=True)
@@ -218,10 +214,10 @@ class PrettyAnnouncement:
self.game_name = '赛马娘' self.game_name = '赛马娘'
async def _get_announcement_text(self): async def _get_announcement_text(self):
async with aiohttp.ClientSession(headers=headers) as session: text = (await AsyncHttpx.get(pretty_url)).text
async with session.get(pretty_url, timeout=7) as res: soup = BeautifulSoup(text, 'lxml')
soup = BeautifulSoup(await res.text(), 'lxml')
divs = soup.find('div', {'id': 'mw-content-text'}).find('div').find_all('div') divs = soup.find('div', {'id': 'mw-content-text'}).find('div').find_all('div')
title = " "
for div in divs: for div in divs:
a = div.find('a') a = div.find('a')
try: try:
@@ -231,8 +227,7 @@ class PrettyAnnouncement:
if title.find('新角色追加') != -1: if title.find('新角色追加') != -1:
url = a['href'] url = a['href']
break break
async with session.get(f'https://wiki.biligame.com/{url}', timeout=7) as res: return (await AsyncHttpx.get(f'https://wiki.biligame.com/{url}')).text, title[:-2]
return await res.text(), title[:-2]
async def update_up_char(self): async def update_up_char(self):
pretty_up_char.parent.mkdir(exist_ok=True, parents=True) pretty_up_char.parent.mkdir(exist_ok=True, parents=True)
@@ -343,9 +338,7 @@ class GuardianAnnouncement:
self.game_name = '坎公骑冠剑' self.game_name = '坎公骑冠剑'
async def _get_announcement_text(self): async def _get_announcement_text(self):
async with aiohttp.ClientSession(headers=headers) as session: return (await AsyncHttpx.get(guardian_url)).text
async with session.get(guardian_url, timeout=7) as res:
return await res.text()
async def update_up_char(self): async def update_up_char(self):
data = { data = {
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
-2
View File
@@ -1,6 +1,5 @@
import os import os
from nonebot.adapters.cqhttp import MessageSegment, Message from nonebot.adapters.cqhttp import MessageSegment, Message
import nonebot
import random import random
from .update_game_info import update_info from .update_game_info import update_info
from .util import generate_img, init_star_rst, BaseData, set_list, get_star, init_up_char from .util import generate_img, init_star_rst, BaseData, set_list, get_star, init_up_char
@@ -15,7 +14,6 @@ try:
except ModuleNotFoundError: except ModuleNotFoundError:
import json import json
driver: nonebot.Driver = nonebot.get_driver()
announcement = GenshinAnnouncement() announcement = GenshinAnnouncement()
-2
View File
@@ -1,6 +1,5 @@
import os import os
import nonebot
from nonebot.adapters.cqhttp import MessageSegment, Message from nonebot.adapters.cqhttp import MessageSegment, Message
from .update_game_info import update_info from .update_game_info import update_info
from .announcement import GuardianAnnouncement from .announcement import GuardianAnnouncement
@@ -18,7 +17,6 @@ try:
except ModuleNotFoundError: except ModuleNotFoundError:
import json import json
driver: nonebot.Driver = nonebot.get_driver()
announcement = GuardianAnnouncement() announcement = GuardianAnnouncement()
+28
View File
@@ -2,6 +2,7 @@ from typing import Any
from .config import DATA_PATH from .config import DATA_PATH
from utils.utils import is_number from utils.utils import is_number
from pathlib import Path from pathlib import Path
from services.log import logger
try: try:
import ujson as json import ujson as json
except ModuleNotFoundError: except ModuleNotFoundError:
@@ -27,8 +28,11 @@ def init_game_pool(game: str, data: dict, Operator: Any):
limited = True limited = True
if key.find('阿米娅') != -1: if key.find('阿米娅') != -1:
continue continue
try:
tmp_lst.append(Operator(name=key, star=int(data[key]['星级']), tmp_lst.append(Operator(name=key, star=int(data[key]['星级']),
limited=limited, recruit_only=recruit_only, event_only=event_only)) limited=limited, recruit_only=recruit_only, event_only=event_only))
except Exception as e:
logger.warning(f"明日方舟导入角色 {key} 数据错误:{type(e)}:{e}")
if game == 'genshin': if game == 'genshin':
for key in data.keys(): for key in data.keys():
if key.find('旅行者') != -1: if key.find('旅行者') != -1:
@@ -36,17 +40,26 @@ def init_game_pool(game: str, data: dict, Operator: Any):
limited = False limited = False
if data[key]['常驻/限定'] == '限定UP': if data[key]['常驻/限定'] == '限定UP':
limited = True limited = True
try:
tmp_lst.append(Operator(name=key, star=int(data[key]['稀有度'][:1]), limited=limited)) tmp_lst.append(Operator(name=key, star=int(data[key]['稀有度'][:1]), limited=limited))
except Exception as e:
logger.warning(f"原神导入角色 {key} 数据错误:{type(e)}:{e}")
if game == 'genshin_arms': if game == 'genshin_arms':
for key in data.keys(): for key in data.keys():
if data[key]['获取途径'].find('祈愿') != -1: if data[key]['获取途径'].find('祈愿') != -1:
limited = False limited = False
if data[key]['获取途径'].find('限定祈愿') != -1: if data[key]['获取途径'].find('限定祈愿') != -1:
limited = True limited = True
try:
tmp_lst.append(Operator(name=key, star=int(data[key]['稀有度'][:1]), limited=limited)) tmp_lst.append(Operator(name=key, star=int(data[key]['稀有度'][:1]), limited=limited))
except Exception as e:
logger.warning(f"原神导入武器 {key} 数据错误:{type(e)}:{e}")
if game == 'pretty': if game == 'pretty':
for key in data.keys(): for key in data.keys():
try:
tmp_lst.append(Operator(name=key, star=data[key]['初始星级'], limited=False)) tmp_lst.append(Operator(name=key, star=data[key]['初始星级'], limited=False))
except Exception as e:
logger.warning(f"赛马娘导入角色 {key} 数据错误:{type(e)}:{e}")
if game == 'pretty_card': if game == 'pretty_card':
for key in data.keys(): for key in data.keys():
limited = False limited = False
@@ -54,7 +67,10 @@ def init_game_pool(game: str, data: dict, Operator: Any):
limited = True limited = True
if not data[key]['获取方式']: if not data[key]['获取方式']:
limited = False limited = False
try:
tmp_lst.append(Operator(name=data[key]['中文名'], star=len(data[key]['稀有度']), limited=limited)) tmp_lst.append(Operator(name=data[key]['中文名'], star=len(data[key]['稀有度']), limited=limited))
except Exception as e:
logger.warning(f"赛马娘导入卡片 {key} 数据错误:{type(e)}:{e}")
if game in ['guardian', 'guardian_arms']: if game in ['guardian', 'guardian_arms']:
for key in data.keys(): for key in data.keys():
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=False)) tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=False))
@@ -63,15 +79,21 @@ def init_game_pool(game: str, data: dict, Operator: Any):
limited = False limited = False
if key.find('(') != -1: if key.find('(') != -1:
limited = True limited = True
try:
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=limited)) tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=limited))
except Exception as e:
logger.warning(f"公主连接导入角色 {key} 数据错误:{type(e)}:{e}")
if game == 'azur': if game == 'azur':
for key in data.keys(): for key in data.keys():
if is_number(data[key]['星级']): if is_number(data[key]['星级']):
limited = False limited = False
if '可以建造' not in data[key]['获取途径']: if '可以建造' not in data[key]['获取途径']:
limited = True limited = True
try:
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']),
limited=limited, itype=data[key]['类型'])) limited=limited, itype=data[key]['类型']))
except Exception as e:
logger.warning(f"碧蓝航线导入角色 {key} 数据错误:{type(e)}:{e}")
if game in ['fgo', 'fgo_card']: if game in ['fgo', 'fgo_card']:
for key in data.keys(): for key in data.keys():
limited = False limited = False
@@ -80,14 +102,20 @@ def init_game_pool(game: str, data: dict, Operator: Any):
limited = True limited = True
except KeyError: except KeyError:
pass pass
try:
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=limited)) tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=limited))
except Exception as e:
logger.warning(f"FGO导入角色 {key} 数据错误:{type(e)}:{e}")
if game == 'onmyoji': if game == 'onmyoji':
for key in data.keys(): for key in data.keys():
limited = False limited = False
if key in ['奴良陆生', '卖药郎', '鬼灯', '阿香', '蜜桃&芥子', '犬夜叉', '杀生丸', '桔梗', '朽木露琪亚', '黑崎一护', if key in ['奴良陆生', '卖药郎', '鬼灯', '阿香', '蜜桃&芥子', '犬夜叉', '杀生丸', '桔梗', '朽木露琪亚', '黑崎一护',
'灶门祢豆子', '灶门炭治郎']: '灶门祢豆子', '灶门炭治郎']:
limited = True limited = True
try:
tmp_lst.append(Operator(name=data[key]['名称'], star=data[key]['星级'], limited=limited)) tmp_lst.append(Operator(name=data[key]['名称'], star=data[key]['星级'], limited=limited))
except Exception as e:
logger.warning(f"阴阳师导入角色 {key} 数据错误:{type(e)}:{e}")
# print(tmp_lst) # print(tmp_lst)
char_name_lst = [x.name for x in tmp_lst] char_name_lst = [x.name for x in tmp_lst]
up_char_file = Path(f'{DATA_PATH}/draw_card/draw_card_up/{game.split("_")[0]}_up_char.json') up_char_file = Path(f'{DATA_PATH}/draw_card/draw_card_up/{game.split("_")[0]}_up_char.json')

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