mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-15 14:22:55 +08:00
update 0.0.6.2
This commit is contained in:
parent
c802dfda22
commit
3de487fb24
15
README.md
15
README.md
@ -100,6 +100,7 @@
|
|||||||
- [x] 移动图片 (同上)
|
- [x] 移动图片 (同上)
|
||||||
- [x] 删除图片 (同上)
|
- [x] 删除图片 (同上)
|
||||||
- [x] 群内B站订阅
|
- [x] 群内B站订阅
|
||||||
|
- [x] 群词条
|
||||||
|
|
||||||
### 已实现的超级用户功能
|
### 已实现的超级用户功能
|
||||||
- [x] 添加/删除权限(是真寻的管理员权限,不是群管理员)
|
- [x] 添加/删除权限(是真寻的管理员权限,不是群管理员)
|
||||||
@ -272,7 +273,7 @@
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## 详细配置请前往文档,以下为最简部署和配置
|
## 详细配置请前往文档,以下为最简部署和配置,如果你有基础并学习过nonebot2的话
|
||||||
|
|
||||||
|
|
||||||
## 简单部署
|
## 简单部署
|
||||||
@ -320,6 +321,18 @@ python bot.py
|
|||||||
|
|
||||||
## 更新
|
## 更新
|
||||||
|
|
||||||
|
### 2021/11/23
|
||||||
|
|
||||||
|
* 替换cos API
|
||||||
|
* 提供私聊b了,即跨群b了用户
|
||||||
|
* 修复游戏抽卡导入角色失败(原神)
|
||||||
|
* 修复无Pixiv代理时报错
|
||||||
|
* 将项目中大部分aiohttp替换为httpx
|
||||||
|
* 删除了丘丘人翻译插件
|
||||||
|
* 新增群词条
|
||||||
|
* 修复游戏抽卡碧蓝航线bwiki格式更改导致获取报错
|
||||||
|
* 首次启动会生成配置文件后停止程序,配置后再次启动即可
|
||||||
|
|
||||||
### 2021/11/18
|
### 2021/11/18
|
||||||
|
|
||||||
* 修复超级用户无法正确拉真寻入群
|
* 修复超级用户无法正确拉真寻入群
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
__version__: v0.0.6.1
|
__version__: v0.0.6.2
|
||||||
|
|||||||
0
basic_plugins/__init__.py
Normal file → Executable file
0
basic_plugins/__init__.py
Normal file → Executable file
2
basic_plugins/admin_bot_manage/__init__.py
Normal file → Executable file
2
basic_plugins/admin_bot_manage/__init__.py
Normal file → Executable 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_="设置群欢迎消息权限",
|
||||||
|
|||||||
0
basic_plugins/admin_bot_manage/admin_config.py
Normal file → Executable file
0
basic_plugins/admin_bot_manage/admin_config.py
Normal file → Executable file
0
basic_plugins/admin_bot_manage/custom_welcome_message.py
Normal file → Executable file
0
basic_plugins/admin_bot_manage/custom_welcome_message.py
Normal file → Executable file
10
basic_plugins/admin_bot_manage/data_source.py
Normal file → Executable file
10
basic_plugins/admin_bot_manage/data_source.py
Normal file → Executable 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:
|
||||||
|
|||||||
0
basic_plugins/admin_bot_manage/rule.py
Normal file → Executable file
0
basic_plugins/admin_bot_manage/rule.py
Normal file → Executable file
0
basic_plugins/admin_bot_manage/switch_rule.py
Normal file → Executable file
0
basic_plugins/admin_bot_manage/switch_rule.py
Normal file → Executable file
0
basic_plugins/admin_bot_manage/timing_task.py
Normal file → Executable file
0
basic_plugins/admin_bot_manage/timing_task.py
Normal file → Executable file
0
basic_plugins/admin_bot_manage/update_group_member_info.py
Normal file → Executable file
0
basic_plugins/admin_bot_manage/update_group_member_info.py
Normal file → Executable file
0
basic_plugins/admin_help/__init__.py
Normal file → Executable file
0
basic_plugins/admin_help/__init__.py
Normal file → Executable file
0
basic_plugins/admin_help/data_source.py
Normal file → Executable file
0
basic_plugins/admin_help/data_source.py
Normal file → Executable file
0
basic_plugins/apscheduler/__init__.py
Normal file → Executable file
0
basic_plugins/apscheduler/__init__.py
Normal file → Executable file
20
basic_plugins/ban/__init__.py
Normal file → Executable file
20
basic_plugins/ban/__init__.py
Normal file → Executable 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):
|
||||||
qq = get_message_at(event.json())
|
if isinstance(event, GroupMessageEvent):
|
||||||
|
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)
|
||||||
|
|||||||
0
basic_plugins/broadcast/__init__.py
Normal file → Executable file
0
basic_plugins/broadcast/__init__.py
Normal file → Executable file
12
basic_plugins/group_handle/__init__.py
Normal file → Executable file
12
basic_plugins/group_handle/__init__.py
Normal file → Executable 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)
|
||||||
|
|||||||
0
basic_plugins/help/__init__.py
Normal file → Executable file
0
basic_plugins/help/__init__.py
Normal file → Executable file
0
basic_plugins/help/data_source.py
Normal file → Executable file
0
basic_plugins/help/data_source.py
Normal file → Executable file
0
basic_plugins/hooks/__init__.py
Normal file → Executable file
0
basic_plugins/hooks/__init__.py
Normal file → Executable file
0
basic_plugins/hooks/auth_hook.py
Normal file → Executable file
0
basic_plugins/hooks/auth_hook.py
Normal file → Executable file
0
basic_plugins/hooks/ban_hook.py
Normal file → Executable file
0
basic_plugins/hooks/ban_hook.py
Normal file → Executable file
0
basic_plugins/hooks/chkdsk_hook.py
Normal file → Executable file
0
basic_plugins/hooks/chkdsk_hook.py
Normal file → Executable file
0
basic_plugins/hooks/limit_hook.py
Normal file → Executable file
0
basic_plugins/hooks/limit_hook.py
Normal file → Executable file
0
basic_plugins/hooks/other_hook.py
Normal file → Executable file
0
basic_plugins/hooks/other_hook.py
Normal file → Executable file
0
basic_plugins/hooks/utils.py
Normal file → Executable file
0
basic_plugins/hooks/utils.py
Normal file → Executable file
0
basic_plugins/hooks/withdraw_message_hook.py
Normal file → Executable file
0
basic_plugins/hooks/withdraw_message_hook.py
Normal file → Executable file
9
basic_plugins/init_plugin_config/__init__.py
Normal file → Executable file
9
basic_plugins/init_plugin_config/__init__.py
Normal file → Executable file
@ -9,10 +9,12 @@ 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 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 +32,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 +49,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("初始化数据完成...")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
0
basic_plugins/init_plugin_config/check_plugin_status.py
Normal file → Executable file
0
basic_plugins/init_plugin_config/check_plugin_status.py
Normal file → Executable file
14
basic_plugins/init_plugin_config/init.py
Normal file
14
basic_plugins/init_plugin_config/init.py
Normal 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")
|
||||||
|
|
||||||
0
basic_plugins/init_plugin_config/init_group_manager.py
Normal file → Executable file
0
basic_plugins/init_plugin_config/init_group_manager.py
Normal file → Executable file
0
basic_plugins/init_plugin_config/init_none_plugin_count_manager.py
Normal file → Executable file
0
basic_plugins/init_plugin_config/init_none_plugin_count_manager.py
Normal file → Executable file
0
basic_plugins/init_plugin_config/init_plugins_config.py
Normal file → Executable file
0
basic_plugins/init_plugin_config/init_plugins_config.py
Normal file → Executable file
0
basic_plugins/init_plugin_config/init_plugins_data.py
Normal file → Executable file
0
basic_plugins/init_plugin_config/init_plugins_data.py
Normal file → Executable file
0
basic_plugins/init_plugin_config/init_plugins_limit.py
Normal file → Executable file
0
basic_plugins/init_plugin_config/init_plugins_limit.py
Normal file → Executable file
0
basic_plugins/init_plugin_config/init_plugins_resources.py
Normal file → Executable file
0
basic_plugins/init_plugin_config/init_plugins_resources.py
Normal file → Executable file
28
basic_plugins/init_plugin_config/init_plugins_settings.py
Normal file → Executable file
28
basic_plugins/init_plugin_config/init_plugins_settings.py
Normal file → Executable 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.error(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)
|
||||||
|
|||||||
4
basic_plugins/auto_invite/__init__.py → basic_plugins/invite_manager/__init__.py
Normal file → Executable file
4
basic_plugins/auto_invite/__init__.py → basic_plugins/invite_manager/__init__.py
Normal file → Executable file
@ -46,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:
|
||||||
0
basic_plugins/nickname.py
Normal file → Executable file
0
basic_plugins/nickname.py
Normal file → Executable file
56
basic_plugins/scripts.py
Normal file → Executable file
56
basic_plugins/scripts.py
Normal file → Executable 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:
|
res.encoding = "utf8"
|
||||||
provinces_data = json.loads(await res.text(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"
|
||||||
for city in city_data.keys():
|
city_data = json.loads(res.text)
|
||||||
data[provinces_data[province]].append(city_data[city])
|
for city in city_data.keys():
|
||||||
|
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
|
||||||
@ -57,7 +60,7 @@ async def _():
|
|||||||
数据库表结构变换
|
数据库表结构变换
|
||||||
"""
|
"""
|
||||||
sql_str = [
|
sql_str = [
|
||||||
"ALTER TABLE group_info ADD group_flag Integer NOT NULL DEFAULT 0;" # group_info表添加一个group_flag
|
"ALTER TABLE group_info ADD group_flag Integer NOT NULL DEFAULT 0;" # group_info表添加一个group_flag
|
||||||
]
|
]
|
||||||
for sql in sql_str:
|
for sql in sql_str:
|
||||||
try:
|
try:
|
||||||
@ -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}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
0
basic_plugins/super_cmd/__init__.py
Normal file → Executable file
0
basic_plugins/super_cmd/__init__.py
Normal file → Executable file
0
basic_plugins/super_cmd/bot_friend_group.py
Normal file → Executable file
0
basic_plugins/super_cmd/bot_friend_group.py
Normal file → Executable file
0
basic_plugins/super_cmd/clear_data.py
Normal file → Executable file
0
basic_plugins/super_cmd/clear_data.py
Normal file → Executable file
0
basic_plugins/super_cmd/data_source.py
Normal file → Executable file
0
basic_plugins/super_cmd/data_source.py
Normal file → Executable file
0
basic_plugins/super_cmd/manager_group.py
Normal file → Executable file
0
basic_plugins/super_cmd/manager_group.py
Normal file → Executable file
0
basic_plugins/super_cmd/reload_setting.py
Normal file → Executable file
0
basic_plugins/super_cmd/reload_setting.py
Normal file → Executable file
0
basic_plugins/super_cmd/set_admin_permissions.py
Normal file → Executable file
0
basic_plugins/super_cmd/set_admin_permissions.py
Normal file → Executable file
0
basic_plugins/super_cmd/super_task_switch.py
Normal file → Executable file
0
basic_plugins/super_cmd/super_task_switch.py
Normal file → Executable file
0
basic_plugins/super_cmd/update_friend_group_info.py
Normal file → Executable file
0
basic_plugins/super_cmd/update_friend_group_info.py
Normal file → Executable file
0
basic_plugins/super_help/__init__.py
Normal file → Executable file
0
basic_plugins/super_help/__init__.py
Normal file → Executable file
0
basic_plugins/super_help/data_source.py
Normal file → Executable file
0
basic_plugins/super_help/data_source.py
Normal file → Executable file
0
basic_plugins/update_info.py
Normal file → Executable file
0
basic_plugins/update_info.py
Normal file → Executable file
0
models/bag_user.py
Normal file → Executable file
0
models/bag_user.py
Normal file → Executable file
2
models/ban_user.py
Normal file → Executable file
2
models/ban_user.py
Normal file → Executable 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()
|
||||||
|
|||||||
0
models/friend_user.py
Normal file → Executable file
0
models/friend_user.py
Normal file → Executable file
0
models/group_info.py
Normal file → Executable file
0
models/group_info.py
Normal file → Executable file
0
models/group_member_info.py
Normal file → Executable file
0
models/group_member_info.py
Normal file → Executable file
0
models/level_user.py
Normal file → Executable file
0
models/level_user.py
Normal file → Executable file
0
models/sign_group_user.py
Normal file → Executable file
0
models/sign_group_user.py
Normal file → Executable file
0
plugins/__init__.py
Normal file → Executable file
0
plugins/__init__.py
Normal file → Executable file
0
plugins/aconfig/__init__.py
Normal file → Executable file
0
plugins/aconfig/__init__.py
Normal file → Executable file
2
plugins/ai/__init__.py
Normal file → Executable file
2
plugins/ai/__init__.py
Normal file → Executable 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__ = {
|
||||||
|
|||||||
130
plugins/ai/data_source.py
Normal file → Executable file
130
plugins/ai/data_source.py
Normal file → Executable 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)
|
||||||
rst = await xie_ai(text, sess)
|
|
||||||
if not rst:
|
if not rst:
|
||||||
return no_result()
|
return no_result()
|
||||||
if nickname:
|
if nickname:
|
||||||
@ -55,23 +58,25 @@ 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)
|
||||||
|
print(ai_message_manager)
|
||||||
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:
|
if not TL_KEY:
|
||||||
return ''
|
return ""
|
||||||
try:
|
try:
|
||||||
if text:
|
if text:
|
||||||
req = {
|
req = {
|
||||||
@ -98,62 +103,59 @@ 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"]:
|
||||||
for result in resp_payload["results"]:
|
for result in resp_payload["results"]:
|
||||||
if result["resultType"] == "text":
|
if result["resultType"] == "text":
|
||||||
text = result["values"]["text"]
|
text = result["values"]["text"]
|
||||||
if "请求次数超过" in text:
|
if "请求次数超过" in text:
|
||||||
text = ""
|
text = ""
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
# 屑 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}"
|
content = ""
|
||||||
) as res:
|
data = json.loads(res.text)
|
||||||
content = ""
|
if data["result"] == 0:
|
||||||
data = json.loads(await res.text())
|
content = data["content"]
|
||||||
if data["result"] == 0:
|
if "菲菲" in content:
|
||||||
content = data["content"]
|
content = content.replace("菲菲", NICKNAME)
|
||||||
if "菲菲" in content:
|
if "艳儿" in content:
|
||||||
content = content.replace("菲菲", NICKNAME)
|
content = content.replace("艳儿", NICKNAME)
|
||||||
if "艳儿" in content:
|
if "公众号" in content:
|
||||||
content = content.replace("艳儿", NICKNAME)
|
content = ""
|
||||||
if "公众号" in content:
|
if "{br}" in content:
|
||||||
content = ""
|
content = content.replace("{br}", "\n")
|
||||||
if "{br}" in content:
|
if "提示" in content:
|
||||||
content = content.replace("{br}", "\n")
|
content = content[: content.find("提示")]
|
||||||
if "提示" in content:
|
if "淘宝" in content:
|
||||||
content = content[: content.find("提示")]
|
return ""
|
||||||
if "淘宝" in content:
|
while True:
|
||||||
return ""
|
r = re.search("{face:(.*)}", content)
|
||||||
while True:
|
if r:
|
||||||
r = re.search("{face:(.*)}", content)
|
id_ = r.group(1)
|
||||||
if r:
|
content = content.replace(
|
||||||
id_ = r.group(1)
|
"{" + f"face:{id_}" + "}", str(face(int(id_)))
|
||||||
content = content.replace(
|
)
|
||||||
"{" + f"face:{id_}" + "}", str(face(int(id_)))
|
else:
|
||||||
)
|
break
|
||||||
else:
|
return (
|
||||||
break
|
content
|
||||||
return (
|
if not content and not Config.get_config("ai", "ALAPI_AI_CHECK")
|
||||||
content
|
else await check_text(content)
|
||||||
if not content and not Config.get_config("ai", "ALAPI_AI_CHECK")
|
)
|
||||||
else await check_text(content, sess)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def hello() -> str:
|
def hello() -> str:
|
||||||
@ -196,21 +198,19 @@ 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 ""
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"检测违规文本错误...{type(e)}:{e}")
|
logger.error(f"检测违规文本错误...{type(e)}:{e}")
|
||||||
return text
|
return text
|
||||||
|
|||||||
137
plugins/ai/utils.py
Executable file
137
plugins/ai/utils.py
Executable 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()
|
||||||
0
plugins/alapi/__init__.py
Normal file → Executable file
0
plugins/alapi/__init__.py
Normal file → Executable file
0
plugins/alapi/comments_163.py
Normal file → Executable file
0
plugins/alapi/comments_163.py
Normal file → Executable file
0
plugins/alapi/cover.py
Normal file → Executable file
0
plugins/alapi/cover.py
Normal file → Executable file
24
plugins/alapi/data_source.py
Normal file → Executable file
24
plugins/alapi/data_source.py
Normal file → Executable 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,18 +16,16 @@ 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:
|
data = (await AsyncHttpx.get(url, params=params, timeout=5)).json()
|
||||||
async with session.get(url, timeout=2, params=params) as response:
|
if data["code"] == 200:
|
||||||
data = await response.json()
|
if not data["data"]:
|
||||||
if data["code"] == 200:
|
return "没有搜索到...", 997
|
||||||
if not data["data"]:
|
return data, 200
|
||||||
return "没有搜索到...", 997
|
else:
|
||||||
return data, 200
|
return f'发生了错误...code:{data["code"]}', 999
|
||||||
else:
|
except TimeoutError:
|
||||||
return f'发生了错误...code:{data["code"]}', 999
|
return "超时了....", 998
|
||||||
except TimeoutError:
|
|
||||||
return "超时了....", 998
|
|
||||||
|
|
||||||
|
|
||||||
def gen_wbtop_pic(data: dict) -> MessageSegment:
|
def gen_wbtop_pic(data: dict) -> MessageSegment:
|
||||||
|
|||||||
48
plugins/alapi/jitang.py
Executable file
48
plugins/alapi/jitang.py
Executable 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}")
|
||||||
0
plugins/alapi/poetry.py
Normal file → Executable file
0
plugins/alapi/poetry.py
Normal file → Executable file
55
plugins/alapi/wbtop.py
Normal file → Executable file
55
plugins/alapi/wbtop.py
Normal file → Executable 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('发生了一些错误.....')
|
|
||||||
|
|
||||||
|
|||||||
1
plugins/bilibili_sub/__init__.py
Normal file → Executable file
1
plugins/bilibili_sub/__init__.py
Normal file → Executable 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":
|
||||||
|
|||||||
49
plugins/bilibili_sub/data_source.py
Normal file → Executable file
49
plugins/bilibili_sub/data_source.py
Normal file → Executable 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,30 +162,27 @@ 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 = {}
|
response = await AsyncHttpx.get(bilibili_search_url, params=params, timeout=5)
|
||||||
async with session.get(
|
if response.status_code == 200:
|
||||||
bilibili_search_url, timeout=5, params=params
|
data = response.json()
|
||||||
) as response:
|
if data.get("data"):
|
||||||
if response.status == 200:
|
for item in data["data"]["result"]:
|
||||||
data = await response.json()
|
if item["result_type"] == "media_bangumi":
|
||||||
if data.get("data"):
|
idx = 0
|
||||||
for item in data["data"]["result"]:
|
for x in item["data"]:
|
||||||
if item["result_type"] == "media_bangumi":
|
_season_data[idx] = {
|
||||||
idx = 0
|
"media_id": x["media_id"],
|
||||||
for x in item["data"]:
|
"title": x["title"]
|
||||||
_season_data[idx] = {
|
.replace('<em class="keyword">', "")
|
||||||
"media_id": x["media_id"],
|
.replace("</em>", ""),
|
||||||
"title": x["title"]
|
}
|
||||||
.replace('<em class="keyword">', "")
|
idx += 1
|
||||||
.replace("</em>", ""),
|
return _season_data
|
||||||
}
|
except TimeoutError:
|
||||||
idx += 1
|
pass
|
||||||
return _season_data
|
|
||||||
except TimeoutError:
|
|
||||||
pass
|
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
0
plugins/bilibili_sub/model.py
Normal file → Executable file
0
plugins/bilibili_sub/model.py
Normal file → Executable file
39
plugins/bilibili_sub/utils.py
Normal file → Executable file
39
plugins/bilibili_sub/utils.py
Normal file → Executable 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")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
5
plugins/bt/__init__.py
Normal file → Executable file
5
plugins/bt/__init__.py
Normal file → Executable 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} 页")
|
||||||
|
|||||||
69
plugins/bt/data_source.py
Normal file → Executable file
69
plugins/bt/data_source.py
Normal file → Executable 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,36 +13,39 @@ 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()
|
"""
|
||||||
if text.find("大约0条结果") != -1:
|
text = (await AsyncHttpx.get(f"{url}/s/{keyword}_rel_{page}.html", timeout=5)).text
|
||||||
return
|
if text.find("大约0条结果") != -1:
|
||||||
soup = BeautifulSoup(text, "lxml")
|
return
|
||||||
item_lst = soup.find_all("div", {"class": "search-item"})
|
soup = BeautifulSoup(text, "lxml")
|
||||||
bt_max_num = Config.get_config("bt", "BT_MAX_NUM")
|
item_lst = soup.find_all("div", {"class": "search-item"})
|
||||||
bt_max_num = bt_max_num if bt_max_num < len(item_lst) else len(item_lst)
|
bt_max_num = Config.get_config("bt", "BT_MAX_NUM")
|
||||||
for item in item_lst[:bt_max_num]:
|
bt_max_num = bt_max_num if bt_max_num < len(item_lst) else len(item_lst)
|
||||||
divs = item.find_all("div")
|
for item in item_lst[:bt_max_num]:
|
||||||
title = (
|
divs = item.find_all("div")
|
||||||
str(divs[0].find("a").text)
|
title = (
|
||||||
.replace("<em>", "")
|
str(divs[0].find("a").text)
|
||||||
.replace("</em>", "")
|
.replace("<em>", "")
|
||||||
.strip()
|
.replace("</em>", "")
|
||||||
)
|
.strip()
|
||||||
spans = divs[2].find_all("span")
|
)
|
||||||
itype = spans[0].text
|
spans = divs[2].find_all("span")
|
||||||
create_time = spans[1].find("b").text
|
itype = spans[0].text
|
||||||
file_size = spans[2].find("b").text
|
create_time = spans[1].find("b").text
|
||||||
link = await get_download_link(divs[0].find("a")["href"], session)
|
file_size = spans[2].find("b").text
|
||||||
yield title, itype, create_time, file_size, link
|
link = await get_download_link(divs[0].find("a")["href"])
|
||||||
|
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")
|
"""
|
||||||
return soup.find("a", {"id": "down-url"})["href"]
|
text = (await AsyncHttpx.get(f"{url}{_url}")).text
|
||||||
|
soup = BeautifulSoup(text, "lxml")
|
||||||
|
return soup.find("a", {"id": "down-url"})["href"]
|
||||||
|
|||||||
12
plugins/c_song/__init__.py
Normal file → Executable file
12
plugins/c_song/__init__.py
Normal file → Executable 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("网易云繁忙...")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
51
plugins/c_song/music_163.py
Normal file → Executable file
51
plugins/c_song/music_163.py
Normal file → Executable 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(
|
"""
|
||||||
f"http://music.163.com/api/search/get/",
|
r = await AsyncHttpx.post(
|
||||||
data={"s": song_name, "limit": 1, "type": 1, "offset": 0},
|
f"http://music.163.com/api/search/get/",
|
||||||
) as r:
|
data={"s": song_name, "limit": 1, "type": 1, "offset": 0},
|
||||||
if r.status != 200:
|
)
|
||||||
return None
|
if r.status_code != 200:
|
||||||
r = await r.text()
|
return None
|
||||||
return json.loads(r)
|
return json.loads(r.text)
|
||||||
|
|
||||||
|
|
||||||
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
|
f"http://music.163.com/api/song/detail/?id={songId}&ids=%5B{songId}%5D",
|
||||||
) as session:
|
)
|
||||||
async with session.post(
|
if r.status_code != 200:
|
||||||
f"http://music.163.com/api/song/detail/?id={songId}&ids=%5B{songId}%5D",
|
return None
|
||||||
) as r:
|
return json.loads(r.text)
|
||||||
if r.status != 200:
|
|
||||||
return None
|
|
||||||
r = await r.text()
|
|
||||||
return json.loads(r)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
0
plugins/check/__init__.py
Normal file → Executable file
0
plugins/check/__init__.py
Normal file → Executable file
33
plugins/check/data_source.py
Normal file → Executable file
33
plugins/check/data_source.py
Normal file → Executable 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,23 +30,16 @@ 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:
|
await AsyncHttpx.get("https://www.baidu.com/", timeout=5)
|
||||||
async with session.get(
|
except Exception as e:
|
||||||
"https://www.baidu.com/", proxy=get_local_proxy(), timeout=3
|
logger.warning(f"访问BaiDu失败... {type(e)}: {e}")
|
||||||
) as response:
|
self.baidu = 404
|
||||||
pass
|
try:
|
||||||
except (TimeoutError, ClientConnectorError) as e:
|
await AsyncHttpx.get("https://www.google.com/", timeout=5)
|
||||||
logger.warning(f"访问BaiDu失败... e: {e}")
|
except Exception as e:
|
||||||
self.baidu = 404
|
logger.warning(f"访问Google失败... {type(e)}: {e}")
|
||||||
try:
|
self.google = 404
|
||||||
async with session.get(
|
|
||||||
"https://www.google.com/", proxy=get_local_proxy(), timeout=3
|
|
||||||
) as response:
|
|
||||||
pass
|
|
||||||
except (TimeoutError, ClientConnectorError) as e:
|
|
||||||
logger.warning(f"访问Google失败... e: {e}")
|
|
||||||
self.google = 404
|
|
||||||
|
|
||||||
def check_user(self):
|
def check_user(self):
|
||||||
rst = ""
|
rst = ""
|
||||||
|
|||||||
0
plugins/check_zhenxun_update/__init__.py
Normal file → Executable file
0
plugins/check_zhenxun_update/__init__.py
Normal file → Executable file
43
plugins/check_zhenxun_update/data_source.py
Normal file → Executable file
43
plugins/check_zhenxun_update/data_source.py
Normal file → Executable 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:
|
res = await AsyncHttpx.get(release_url)
|
||||||
async with session.get(release_url, proxy=get_local_proxy()) as res:
|
if res.status_code == 200:
|
||||||
if res.status == 200:
|
return res.json()
|
||||||
return await res.json()
|
except TimeoutError:
|
||||||
except (TimeoutError, ClientConnectorError):
|
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
|
||||||
|
|||||||
46
plugins/coser/__init__.py
Normal file → Executable file
46
plugins/coser/__init__.py
Normal file → Executable file
@ -1,13 +1,8 @@
|
|||||||
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
|
|
||||||
import aiohttp
|
|
||||||
import aiofiles
|
|
||||||
|
|
||||||
__zx_plugin_name__ = "coser"
|
__zx_plugin_name__ = "coser"
|
||||||
__plugin_usage__ = """
|
__plugin_usage__ = """
|
||||||
@ -32,38 +27,13 @@ coser = on_command(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
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:
|
await coser.send(image(url))
|
||||||
for _ in range(3):
|
except Exception as e:
|
||||||
try:
|
await coser.send("你cos给我看!")
|
||||||
async with session.get(url, proxy=get_local_proxy(), timeout=2, verify_ssl=False) as response:
|
logger.error(f"coser 发送了未知错误 {type(e)}:{e}")
|
||||||
_url = (await response.json())['text']
|
|
||||||
async with session.get(
|
|
||||||
_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:
|
|
||||||
await coser.send("发生了预料之外的错误..请稍后再试或联系管理员修复...")
|
|
||||||
logger.error(f"coser 发送了未知错误 {type(e)}:{e}")
|
|
||||||
|
|||||||
@ -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)
|
|
||||||
@ -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
|
|
||||||
0
plugins/dialogue/__init__.py
Normal file → Executable file
0
plugins/dialogue/__init__.py
Normal file → Executable file
0
plugins/draw_card/__init__.py
Normal file → Executable file
0
plugins/draw_card/__init__.py
Normal file → Executable file
59
plugins/draw_card/announcement.py
Normal file → Executable file
59
plugins/draw_card/announcement.py
Normal file → Executable 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']
|
return (await AsyncHttpx.get(f'https://ak.hypergryph.com{a}')).text
|
||||||
async with session.get(f'https://ak.hypergryph.com{a}', headers=headers, timeout=7) as res:
|
|
||||||
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,21 +214,20 @@ 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:
|
||||||
title = a['title']
|
title = a['title']
|
||||||
except (KeyError, TypeError):
|
except (KeyError, TypeError):
|
||||||
continue
|
continue
|
||||||
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 = {
|
||||||
|
|||||||
0
plugins/draw_card/async_update_game_info.py
Normal file → Executable file
0
plugins/draw_card/async_update_game_info.py
Normal file → Executable file
0
plugins/draw_card/azur_handle.py
Normal file → Executable file
0
plugins/draw_card/azur_handle.py
Normal file → Executable file
0
plugins/draw_card/config.py
Normal file → Executable file
0
plugins/draw_card/config.py
Normal file → Executable file
0
plugins/draw_card/fgo_handle.py
Normal file → Executable file
0
plugins/draw_card/fgo_handle.py
Normal file → Executable file
0
plugins/draw_card/genshin_handle.py
Normal file → Executable file
0
plugins/draw_card/genshin_handle.py
Normal file → Executable file
0
plugins/draw_card/guardian_handle.py
Normal file → Executable file
0
plugins/draw_card/guardian_handle.py
Normal file → Executable file
50
plugins/draw_card/init_card_pool.py
Normal file → Executable file
50
plugins/draw_card/init_card_pool.py
Normal file → Executable 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
|
||||||
tmp_lst.append(Operator(name=key, star=int(data[key]['星级']),
|
try:
|
||||||
limited=limited, recruit_only=recruit_only, event_only=event_only))
|
tmp_lst.append(Operator(name=key, star=int(data[key]['星级']),
|
||||||
|
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
|
||||||
tmp_lst.append(Operator(name=key, star=int(data[key]['稀有度'][:1]), limited=limited))
|
try:
|
||||||
|
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
|
||||||
tmp_lst.append(Operator(name=key, star=int(data[key]['稀有度'][:1]), limited=limited))
|
try:
|
||||||
|
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():
|
||||||
tmp_lst.append(Operator(name=key, star=data[key]['初始星级'], limited=False))
|
try:
|
||||||
|
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
|
||||||
tmp_lst.append(Operator(name=data[key]['中文名'], star=len(data[key]['稀有度']), limited=limited))
|
try:
|
||||||
|
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
|
||||||
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=limited))
|
try:
|
||||||
|
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
|
||||||
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']),
|
try:
|
||||||
limited=limited, itype=data[key]['类型']))
|
tmp_lst.append(Operator(name=data[key]['名称'], star=int(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
|
||||||
tmp_lst.append(Operator(name=data[key]['名称'], star=int(data[key]['星级']), limited=limited))
|
try:
|
||||||
|
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
|
||||||
tmp_lst.append(Operator(name=data[key]['名称'], star=data[key]['星级'], limited=limited))
|
try:
|
||||||
|
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')
|
||||||
|
|||||||
1
plugins/draw_card/onmyoji_handle.py
Normal file → Executable file
1
plugins/draw_card/onmyoji_handle.py
Normal file → Executable file
@ -6,7 +6,6 @@ from .util import generate_img, init_star_rst, BaseData, set_list, get_star, max
|
|||||||
from .config import ONMYOJI_SR, ONMYOJI_SSR, ONMYOJI_SP, ONMYOJI_R, DRAW_PATH, ONMYOJI_FLAG
|
from .config import ONMYOJI_SR, ONMYOJI_SSR, ONMYOJI_SP, ONMYOJI_R, DRAW_PATH, ONMYOJI_FLAG
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from .init_card_pool import init_game_pool
|
from .init_card_pool import init_game_pool
|
||||||
import nonebot
|
|
||||||
try:
|
try:
|
||||||
import ujson as json
|
import ujson as json
|
||||||
except ModuleNotFoundError:
|
except ModuleNotFoundError:
|
||||||
|
|||||||
3
plugins/draw_card/pcr_handle.py
Normal file → Executable file
3
plugins/draw_card/pcr_handle.py
Normal file → Executable file
@ -1,7 +1,5 @@
|
|||||||
import ujson as json
|
import ujson as json
|
||||||
import os
|
|
||||||
from nonebot.adapters.cqhttp import MessageSegment
|
from nonebot.adapters.cqhttp import MessageSegment
|
||||||
import nonebot
|
|
||||||
import random
|
import random
|
||||||
from .update_game_info import update_info
|
from .update_game_info import update_info
|
||||||
from .update_game_simple_info import update_simple_info
|
from .update_game_simple_info import update_simple_info
|
||||||
@ -10,7 +8,6 @@ from .config import PCR_TWO_P, PCR_THREE_P, PCR_ONE_P, DRAW_PATH, PCR_FLAG, PCR_
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from .init_card_pool import init_game_pool
|
from .init_card_pool import init_game_pool
|
||||||
|
|
||||||
driver: nonebot.Driver = nonebot.get_driver()
|
|
||||||
|
|
||||||
ALL_CHAR = []
|
ALL_CHAR = []
|
||||||
|
|
||||||
|
|||||||
0
plugins/draw_card/pretty_handle.py
Normal file → Executable file
0
plugins/draw_card/pretty_handle.py
Normal file → Executable file
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user