From c9efdaedcf5f52f15c0a2f48563aa2f4d9e531e7 Mon Sep 17 00:00:00 2001 From: molanp <104612722+molanp@users.noreply.github.com> Date: Tue, 7 Apr 2026 08:41:46 +0800 Subject: [PATCH] =?UTF-8?q?feat(nickname):=20=E5=88=A0=E9=99=A4=E6=98=B5?= =?UTF-8?q?=E7=A7=B0=E7=B3=BB=E7=BB=9F=E7=9B=B8=E5=85=B3=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=20(#2114)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 删除了昵称系统的完整实现,包括: - 移除 nickname.py 插件文件及其所有功能代码 - 从 FriendUser 和 GroupInfoUser 模型中删除 nickname 字段 - 移除相关的数据库配置 - 更新 GroupManager 中的操作者名称获取逻辑 - 简化平台处理的数据源代码 --- zhenxun/builtin_plugins/nickname.py | 285 ------------------ .../platform/qq/group_handle/data_source.py | 15 +- zhenxun/models/friend_user.py | 52 +--- zhenxun/models/group_member_info.py | 73 +---- 4 files changed, 11 insertions(+), 414 deletions(-) delete mode 100644 zhenxun/builtin_plugins/nickname.py diff --git a/zhenxun/builtin_plugins/nickname.py b/zhenxun/builtin_plugins/nickname.py deleted file mode 100644 index ce3f9be8..00000000 --- a/zhenxun/builtin_plugins/nickname.py +++ /dev/null @@ -1,285 +0,0 @@ -import random - -from nonebot.adapters import Bot -from nonebot.plugin import PluginMetadata -from nonebot.rule import to_me -from nonebot_plugin_alconna import ( - Alconna, - Args, - Arparma, - CommandMeta, - Option, - on_alconna, - store_true, -) -from nonebot_plugin_uninfo import Uninfo - -from zhenxun.configs.config import BotConfig, Config -from zhenxun.configs.utils import Command, PluginExtraData, RegisterConfig -from zhenxun.models.ban_console import BanConsole -from zhenxun.models.friend_user import FriendUser -from zhenxun.models.group_member_info import GroupInfoUser -from zhenxun.services.log import logger -from zhenxun.utils.depends import UserName -from zhenxun.utils.enum import PluginType -from zhenxun.utils.message import MessageUtils -from zhenxun.utils.platform import PlatformUtils - -__plugin_meta__ = PluginMetadata( - name="昵称系统", - description="区区昵称,才不想叫呢!", - usage=f""" - 个人昵称,将替换{BotConfig.self_nickname}称呼你的名称,群聊 与 私聊 昵称相互独立, - 全局昵称设置将更改您目前所有群聊中及私聊的昵称 - 指令: - 以后叫我 [昵称]: 设置当前群聊/私聊的昵称 - 全局昵称设置 [昵称]: 设置当前所有群聊和私聊的昵称 - {BotConfig.self_nickname}我是谁 - """.strip(), - extra=PluginExtraData( - author="HibiKier", - version="0.1", - plugin_type=PluginType.NORMAL, - menu_type="其他", - commands=[ - Command(command="以后叫我 [昵称]"), - Command(command="全局昵称设置 [昵称]"), - Command(command=f"{BotConfig.self_nickname}我是谁"), - ], - configs=[ - RegisterConfig( - key="BLACK_WORD", - value=["爸", "爹", "爷", "父"], - help="昵称所屏蔽的关键词,已设置的昵称会被替换为 *," - "未设置的昵称会在设置时提示", - default_value=None, - type=list[str], - ) - ], - ).to_dict(), -) - -_nickname_matcher = on_alconna( - Alconna( - "re:(?:以后)?(?:叫我|请叫我|称呼我)", - Args["name?", str], - meta=CommandMeta(compact=True), - ), - rule=to_me(), - priority=5, - block=True, -) - -_global_nickname_matcher = on_alconna( - Alconna("设置全局昵称", Args["name?", str], meta=CommandMeta(compact=True)), - rule=to_me(), - priority=5, - block=True, -) - -_matcher = on_alconna( - Alconna( - "nickname", - Option("--name", action=store_true, help_text="用户昵称"), - Option("--cancel", action=store_true, help_text="取消昵称"), - ), - rule=to_me(), - priority=5, - block=True, -) - -_matcher.shortcut( - "我(是谁|叫什么)", - command="nickname", - arguments=["--name"], - prefix=True, -) - -_matcher.shortcut( - "取消昵称", - command="nickname", - arguments=["--cancel"], - prefix=True, -) - - -CALL_NAME = [ - "好啦好啦,我知道啦,{},以后就这么叫你吧", - f"嗯嗯,{BotConfig.self_nickname}" + "记住你的昵称了哦,{}", - "好突然,突然要叫你昵称什么的...{}..", - f"{BotConfig.self_nickname}" + "会好好记住{}的,放心吧", - "好..好.,那窝以后就叫你{}了.", -] - -REMIND = [ - "我肯定记得你啊,你是{}啊", - "我不会忘记你的,你也不要忘记我!{}", - f"哼哼,{BotConfig.self_nickname}" + "记忆力可是很好的,{}", - "嗯?你是失忆了嘛...{}..", - f"不要小看{BotConfig.self_nickname}" + "的记忆力啊!笨蛋{}!QAQ", - "哎?{}..怎么了吗..突然这样问..", -] - -CANCEL = [ - f"呜..{BotConfig.self_nickname}" + "睡一觉就会忘记的..和梦一样..{}", - "窝知道了..{}..", - f"是{BotConfig.self_nickname}" + "哪里做的不好嘛..好吧..晚安{}", - "呃,{},下次我绝对绝对绝对不会再忘记你!", - "可..可恶!{}!太可恶了!呜", -] - - -async def CheckNickname( - bot: Bot, - session: Uninfo, - params: Arparma, -): - """ - 检查名称是否合法 - """ - black_word = Config.get_config("nickname", "BLACK_WORD") - name = params.query("name") - logger.debug(f"昵称检查: {name}", "昵称设置", session=session) - if not name: - await MessageUtils.build_message("叫你空白?叫你虚空?叫你无名??").finish( - at_sender=True - ) - if session.user.id in bot.config.superusers: - logger.debug( - f"超级用户设置昵称, 跳过合法检测: {name}", "昵称设置", session=session - ) - else: - if len(name) > 20: - await MessageUtils.build_message("昵称可不能超过20个字!").finish( - at_sender=True - ) - if name in bot.config.nickname: - await MessageUtils.build_message("笨蛋!休想占用我的名字! ").finish( - at_sender=True - ) - if black_word: - for x in name: - if x in black_word: - logger.debug("昵称设置禁止字符: [{x}]", "昵称设置", session=session) - await MessageUtils.build_message(f"字符 [{x}] 为禁止字符!").finish( - at_sender=True - ) - for word in black_word: - if word in name: - logger.debug( - "昵称设置禁止字符: [{word}]", "昵称设置", session=session - ) - await MessageUtils.build_message( - f"字符 [{word}] 为禁止字符!" - ).finish(at_sender=True) - return name - - -@_nickname_matcher.handle() -async def _( - bot: Bot, - session: Uninfo, - name_: Arparma, - uname: str = UserName(), -): - name = await CheckNickname(bot, session, name_) - if len(name) < 5 and random.random() < 0.3: - name = "~".join(name) - group_id = None - if session.group: - group_id = session.group.parent.id if session.group.parent else session.group.id - if group_id: - await GroupInfoUser.set_user_nickname( - session.user.id, - group_id, - name, - uname, - PlatformUtils.get_platform(session), - ) - logger.info(f"设置群昵称成功: {name}", "昵称设置", session=session) - else: - await FriendUser.set_user_nickname( - session.user.id, - name, - uname, - PlatformUtils.get_platform(session), - ) - logger.info(f"设置私聊昵称成功: {name}", "昵称设置", session=session) - await MessageUtils.build_message(random.choice(CALL_NAME).format(name)).finish( - reply_to=True - ) - - -@_global_nickname_matcher.handle() -async def _( - bot: Bot, - session: Uninfo, - name_: Arparma, - nickname: str = UserName(), -): - name = await CheckNickname(bot, session, name_) - await FriendUser.set_user_nickname( - session.user.id, - name, - nickname, - PlatformUtils.get_platform(session), - ) - await GroupInfoUser.filter(user_id=session.user.id).update(nickname=name) - logger.info(f"设置全局昵称成功: {name}", "设置全局昵称", session=session) - await MessageUtils.build_message(random.choice(CALL_NAME).format(name)).finish( - reply_to=True - ) - - -@_matcher.assign("name") -async def _(session: Uninfo, uname: str = UserName()): - group_id = None - if session.group: - group_id = session.group.parent.id if session.group.parent else session.group.id - if group_id: - nickname = await GroupInfoUser.get_user_nickname(session.user.id, group_id) - else: - nickname = await FriendUser.get_user_nickname(session.user.id) - if nickname: - await MessageUtils.build_message(random.choice(REMIND).format(nickname)).finish( - reply_to=True - ) - else: - card = uname - await MessageUtils.build_message( - random.choice( - [ - "没..没有昵称嘛,{}", - "啊,你是{}啊,我想叫你的昵称!", - "是{}啊,有什么事吗?", - "你是{}?", - ] - ).format(card) - ).finish(reply_to=True) - - -@_matcher.assign("cancel") -async def _(bot: Bot, session: Uninfo): - group_id = None - if session.group: - group_id = session.group.parent.id if session.group.parent else session.group.id - if group_id: - nickname = await GroupInfoUser.get_user_nickname(session.user.id, group_id) - else: - nickname = await FriendUser.get_user_nickname(session.user.id) - if nickname: - await MessageUtils.build_message(random.choice(CANCEL).format(nickname)).send( - reply_to=True - ) - if group_id: - await GroupInfoUser.set_user_nickname(session.user.id, group_id, "") - else: - await FriendUser.set_user_nickname(session.user.id, "") - await BanConsole.ban( - session.user.id, group_id, 9, "用户昵称违规", 60, bot.self_id - ) - return - else: - await MessageUtils.build_message("你在做梦吗?你没有昵称啊").finish( - reply_to=True - ) diff --git a/zhenxun/builtin_plugins/platform/qq/group_handle/data_source.py b/zhenxun/builtin_plugins/platform/qq/group_handle/data_source.py index 5a353ade..e940bc53 100644 --- a/zhenxun/builtin_plugins/platform/qq/group_handle/data_source.py +++ b/zhenxun/builtin_plugins/platform/qq/group_handle/data_source.py @@ -40,9 +40,7 @@ _REFRESH_TASKS: set[asyncio.Task] = set() def _normalize_platform(platform: str | set[str] | None) -> str | None: - if isinstance(platform, set): - return next(iter(platform), None) - return platform + return next(iter(platform), None) if isinstance(platform, set) else platform async def _safe_get_group_member_info(bot: Bot, group_id: str, user_id: str) -> dict: @@ -409,12 +407,11 @@ class GroupManager: operator_user = await GroupInfoUser.get_or_none( user_id=operator_id, group_id=group_id ) - if operator_user: - operator_name = ( - operator_user.nickname or operator_user.user_name or operator_id - ) - else: - operator_name = operator_id + operator_name = ( + (operator_user.user_name or operator_id) + if operator_user + else operator_id + ) else: operator_name = "" return f"{user_name} 被 {operator_name} 送走了." diff --git a/zhenxun/models/friend_user.py b/zhenxun/models/friend_user.py index c6d6f119..7b235466 100644 --- a/zhenxun/models/friend_user.py +++ b/zhenxun/models/friend_user.py @@ -1,6 +1,5 @@ from tortoise import fields -from zhenxun.configs.config import Config from zhenxun.services.db_context import Model @@ -11,8 +10,6 @@ class FriendUser(Model): """用户id""" user_name = fields.CharField(max_length=255, default="", description="用户名称") """用户名称""" - nickname = fields.CharField(max_length=255, null=True, description="用户自定义昵称") - """私聊下自定义昵称""" platform = fields.CharField(255, null=True, description="平台") """平台""" @@ -31,53 +28,6 @@ class FriendUser(Model): return user.user_name return "" - @classmethod - async def get_user_nickname(cls, user_id: str) -> str: - """获取用户昵称 - - 参数: - user_id: 用户id - """ - if user := await cls.get_or_none(user_id=user_id): - if user.nickname: - _tmp = "" - if black_word := Config.get_config("nickname", "BLACK_WORD"): - for x in user.nickname: - _tmp += "*" if x in black_word else x - return _tmp - return "" - - @classmethod - async def set_user_nickname( - cls, - user_id: str, - nickname: str, - uname: str | None = None, - platform: str | None = None, - ): - """设置用户昵称 - - 参数: - user_id: 用户id - nickname: 昵称 - uname: 用户昵称 - platform: 平台 - """ - defaults = {"nickname": nickname} - if uname is not None: - defaults["user_name"] = uname - if platform is not None: - defaults["platform"] = platform - await cls.update_or_create( - user_id=user_id, - defaults=defaults, - ) - @classmethod def _run_script(cls): - return [ - "ALTER TABLE friend_users " - "ALTER COLUMN user_id TYPE character varying(255);", - "ALTER TABLE friend_users " - "ADD COLUMN platform character varying(255) default 'qq';", - ] + return ["ALTER TABLE friend_users DROP COLUMN nickname;"] diff --git a/zhenxun/models/group_member_info.py b/zhenxun/models/group_member_info.py index 2bb3d46f..828b9f53 100644 --- a/zhenxun/models/group_member_info.py +++ b/zhenxun/models/group_member_info.py @@ -1,6 +1,5 @@ from tortoise import fields -from zhenxun.configs.config import Config from zhenxun.services.db_context import Model @@ -15,8 +14,6 @@ class GroupInfoUser(Model): """群聊id""" user_join_time = fields.DatetimeField(null=True) """用户入群时间""" - nickname = fields.CharField(255, null=True) - """群聊昵称""" uid = fields.BigIntField(null=True) """用户uid""" platform = fields.CharField(255, null=True, description="平台") @@ -28,7 +25,7 @@ class GroupInfoUser(Model): unique_together = ("user_id", "group_id") @classmethod - async def get_all_uid(cls, group_id: str) -> set[int]: + async def get_all_uid(cls, group_id: str) -> set[str]: """获取该群所有用户id 参数: @@ -39,78 +36,16 @@ class GroupInfoUser(Model): ) # type: ignore @classmethod - async def set_user_nickname( - cls, - user_id: str, - group_id: str, - nickname: str, - uname: str | None = None, - platform: str | None = None, - ): - """设置群员在该群内的昵称 - - 参数: - user_id: 用户id - group_id: 群号 - nickname: 昵称 - uname: 用户昵称 - platform: 平台 - """ - defaults = {"nickname": nickname} - if uname is not None: - defaults["user_name"] = uname - if platform is not None: - defaults["platform"] = platform - await cls.update_or_create( - user_id=user_id, - group_id=group_id, - defaults=defaults, - ) - - @classmethod - async def get_user_all_group(cls, user_id: str) -> list[int]: + async def get_user_all_group(cls, user_id: str) -> list[str]: """获取该用户所在的所有群聊 参数: user_id: 用户id """ return list( - await cls.filter(user_id=str(user_id)).values_list("group_id", flat=True) + await cls.filter(user_id=user_id).values_list("group_id", flat=True) ) # type: ignore - @classmethod - async def get_user_nickname(cls, user_id: str, group_id: str) -> str: - """获取用户在该群的昵称 - - 参数: - user_id: 用户id - group_id: 群号 - """ - if user := await cls.get_or_none(user_id=user_id, group_id=group_id): - if user.nickname: - nickname = "" - if black_word := Config.get_config("nickname", "BLACK_WORD"): - for x in user.nickname: - nickname += "*" if x in black_word else x - return nickname - return user.nickname - return "" - @classmethod async def _run_script(cls): - return [ - # 允许 user_join_time 为空 - "alter table group_info_users alter user_join_time drop not null;", - "ALTER TABLE group_info_users " - "ALTER COLUMN user_join_time TYPE timestamp with time zone " - "USING user_join_time::timestamp with time zone;", - # 将user_id改为user_id - "ALTER TABLE group_info_users RENAME COLUMN user_qq TO user_id;", - "ALTER TABLE group_info_users " - "ALTER COLUMN user_id TYPE character varying(255);", - # 将user_id字段类型改为character varying(255) - "ALTER TABLE group_info_users " - "ALTER COLUMN group_id TYPE character varying(255);", - "ALTER TABLE group_info_users " - "ADD COLUMN platform character varying(255) default 'qq';", - ] + return ["ALTER TABLE group_info_users DROP COLUMN nickname;"]