From bab9298511a0fbee1f4d11283d6a38968bf0c255 Mon Sep 17 00:00:00 2001 From: "lxbpxylps@126.com" Date: Thu, 7 Oct 2021 21:39:01 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E4=BB=A3=E7=A0=81=E5=92=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 1 + .env.dev | 4 + .env.prod | 4 + bot.py | 25 ++ config/bilibililive_checker.json | 5 + config/cmd_alias.json | 40 +++ config/cmd_register.json | 58 +++ config/get_invitation.json | 11 + config/group.json | 5 + config/mc_event.json | 11 + config/mc_server.json | 13 + config/text.json | 67 ++++ data/advancement_translation.json | 358 +++++++++++++++++++ data/bind_qq.json | 1 + data/invitation.json | 1 + pyproject.toml | 22 ++ src/plugins/bilibililive_checker/__init__.py | 74 ++++ src/plugins/bind_qq/__init__.py | 75 ++++ src/plugins/call_admin/__init__.py | 66 ++++ src/plugins/cmd_register/__init__.py | 57 +++ src/plugins/get_invitation/__init__.py | 87 +++++ src/plugins/group_increase/__init__.py | 30 ++ src/plugins/help/__init__.py | 26 ++ src/plugins/issue_cmd/__init__.py | 75 ++++ src/plugins/mc_event/__init__.py | 192 ++++++++++ src/plugins/prism_api/__init__.py | 73 ++++ src/plugins/query_online/__init__.py | 37 ++ src/plugins/say_mc_msg/__init__.py | 51 +++ src/plugins/tell_mc_msg/__init__.py | 52 +++ src/plugins/utils/__init__.py | 40 +++ src/plugins/welcome/__init__.py | 28 ++ 31 files changed, 1589 insertions(+) create mode 100644 .env create mode 100644 .env.dev create mode 100644 .env.prod create mode 100644 bot.py create mode 100644 config/bilibililive_checker.json create mode 100644 config/cmd_alias.json create mode 100644 config/cmd_register.json create mode 100644 config/get_invitation.json create mode 100644 config/group.json create mode 100644 config/mc_event.json create mode 100644 config/mc_server.json create mode 100644 config/text.json create mode 100644 data/advancement_translation.json create mode 100644 data/bind_qq.json create mode 100644 data/invitation.json create mode 100644 pyproject.toml create mode 100644 src/plugins/bilibililive_checker/__init__.py create mode 100644 src/plugins/bind_qq/__init__.py create mode 100644 src/plugins/call_admin/__init__.py create mode 100644 src/plugins/cmd_register/__init__.py create mode 100644 src/plugins/get_invitation/__init__.py create mode 100644 src/plugins/group_increase/__init__.py create mode 100644 src/plugins/help/__init__.py create mode 100644 src/plugins/issue_cmd/__init__.py create mode 100644 src/plugins/mc_event/__init__.py create mode 100644 src/plugins/prism_api/__init__.py create mode 100644 src/plugins/query_online/__init__.py create mode 100644 src/plugins/say_mc_msg/__init__.py create mode 100644 src/plugins/tell_mc_msg/__init__.py create mode 100644 src/plugins/utils/__init__.py create mode 100644 src/plugins/welcome/__init__.py diff --git a/.env b/.env new file mode 100644 index 0000000..2237a08 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +ENVIRONMENT=prod diff --git a/.env.dev b/.env.dev new file mode 100644 index 0000000..7b5ee39 --- /dev/null +++ b/.env.dev @@ -0,0 +1,4 @@ +HOST=0.0.0.0 +PORT=4399 +DEBUG=true +COMMAND_START=["#"] \ No newline at end of file diff --git a/.env.prod b/.env.prod new file mode 100644 index 0000000..c64f388 --- /dev/null +++ b/.env.prod @@ -0,0 +1,4 @@ +HOST=0.0.0.0 +PORT=4399 +DEBUG=false +COMMAND_START=["#"] \ No newline at end of file diff --git a/bot.py b/bot.py new file mode 100644 index 0000000..20ea957 --- /dev/null +++ b/bot.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import os + +import nonebot +from nonebot import logger +from nonebot.adapters.cqhttp import Bot as CQHTTPBot + + +# 若 data 文件夹不存在则创建 +if os.path.exists('data') == False: + os.mkdir('data') + +# dev 环境下监控 src config 文件夹变动 +nonebot.init(fastapi_reload_dirs=['src', 'config']) + +logger.add("./logs/{time:YYYY-MM-DD}.log", rotation="0:00") + +app = nonebot.get_asgi() + +driver = nonebot.get_driver() +driver.register_adapter("cqhttp", CQHTTPBot) + +nonebot.load_from_toml("pyproject.toml") diff --git a/config/bilibililive_checker.json b/config/bilibililive_checker.json new file mode 100644 index 0000000..bf5decf --- /dev/null +++ b/config/bilibililive_checker.json @@ -0,0 +1,5 @@ +{ + "enable": false, + "group": [], + "liveroom": [] +} \ No newline at end of file diff --git a/config/cmd_alias.json b/config/cmd_alias.json new file mode 100644 index 0000000..3af1c9b --- /dev/null +++ b/config/cmd_alias.json @@ -0,0 +1,40 @@ +{ + "help": { + "cmd": "帮助", + "aliases": [] + }, + "bind_qq": { + "cmd": "绑定", + "aliases": [ + "绑定账号" + ] + }, + "call_admin": { + "cmd": "呼叫管理员", + "aliases": [] + }, + "get_invitation": { + "cmd": "邀请码", + "aliases": [] + }, + "issue_cmd": { + "cmd": "命令", + "aliases": [] + }, + "query_online": { + "cmd": "在线人数", + "aliases": [] + }, + "say_mc_msg": { + "cmd": "服务器", + "aliases": [] + }, + "tell_mc_msg": { + "cmd": "私聊", + "aliases": [] + }, + "welcome": { + "cmd": "欢迎", + "aliases": [] + } +} \ No newline at end of file diff --git a/config/cmd_register.json b/config/cmd_register.json new file mode 100644 index 0000000..b8b1176 --- /dev/null +++ b/config/cmd_register.json @@ -0,0 +1,58 @@ +[ + { + "cmd": "list", + "aliases": [ + "在线列表" + ], + "no_arg": true, + "num": 1, + "wait_time": 1, + "server_tag": "主服", + "allow_member": [], + "permission": "ALL" + }, + { + "cmd": "tps", + "aliases": [ + "运行状态" + ], + "no_arg": true, + "num": 1, + "wait_time": 1, + "server_tag": "主服", + "allow_member": [], + "permission": "ADMIN" + }, + { + "cmd": "op", + "aliases": [], + "no_arg": false, + "num": 1, + "wait_time": 1, + "server_tag": "主服", + "allow_member": [], + "permission": "OP" + }, + { + "cmd": "deop", + "aliases": [], + "no_arg": false, + "num": 1, + "wait_time": 1, + "server_tag": "主服", + "allow_member": [], + "permission": "OP" + }, + { + "cmd": "lp editor", + "aliases": [ + "权限编辑" + ], + "no_arg": true, + "num": 3, + "wait_time": 5, + "server_tag": "主服", + "allow_member": [], + "permission": "OP" + } +] \ No newline at end of file diff --git a/config/get_invitation.json b/config/get_invitation.json new file mode 100644 index 0000000..33b3a92 --- /dev/null +++ b/config/get_invitation.json @@ -0,0 +1,11 @@ +{ + "enable": false, + "blessing_skin_server_mysql": { + "host": "127.0.0.1", + "port": 3306, + "user": "skin", + "password": "", + "db": "skin" + }, + "initial_chance": 0 +} \ No newline at end of file diff --git a/config/group.json b/config/group.json new file mode 100644 index 0000000..f7fc4c2 --- /dev/null +++ b/config/group.json @@ -0,0 +1,5 @@ +{ + "main_group": 123456789, + "op_user": [], + "admin_user": [] +} \ No newline at end of file diff --git a/config/mc_event.json b/config/mc_event.json new file mode 100644 index 0000000..56bb6b8 --- /dev/null +++ b/config/mc_event.json @@ -0,0 +1,11 @@ +{ + "enable": { + "server_start": true, + "server_stop": true, + "player_join": true, + "player_advancement": true, + "player_chat": true, + "player_quit": true, + "player_quit_private": true + } +} \ No newline at end of file diff --git a/config/mc_server.json b/config/mc_server.json new file mode 100644 index 0000000..9f3f7e5 --- /dev/null +++ b/config/mc_server.json @@ -0,0 +1,13 @@ +{ + "main_server_tag": "主服", + "server": [ + { + "tag": "主服", + "url": "http://127.0.0.1:8520" + }, + { + "tag": "游戏服", + "url": "http://192.168.1.2:8520" + } + ] +} \ No newline at end of file diff --git a/config/text.json b/config/text.json new file mode 100644 index 0000000..3b397c2 --- /dev/null +++ b/config/text.json @@ -0,0 +1,67 @@ +{ + "not_enable": "此功能未开启!", + "bilibililive_checker": { + "message": "主播开播啦!\n房间标题:\n直播分区:<area>\n快去<url>围观吧!\n" + }, + "bind_qq": { + "help": "#绑定 ID | 将游戏 ID 和 QQ 号绑定", + "format_error": "发送格式错误!\n发送格式:#绑定 ID", + "not_bind_msg_in_game": "§4<player>,看起来您尚未将游戏账号和QQ号绑定,请在群内使用 #绑定 <player> 绑定您的账号\n如果您对此消息感到疑惑,请联系管理员", + "not_bind_when_send_msg": "请先通过 #绑定 ID 绑定您的游戏账号!", + "already_bind": "您已经绑定过账号!如果您对此感到疑惑,请联系管理员", + "player_not_exist": "您要绑定的玩家不存在!请确认曾登录过以及输入正确", + "success": "绑定成功!" + }, + "call_admin": { + "help": "#呼叫管理员 内容 | 向管理员发送消息", + "format_error": "发送格式错误!\n发送格式:#呼叫管理员 内容" + }, + "cmd_register": { + "help": "#在线排行 | 查询服务器在线排行\n#tps | 查询服务器 TPS", + "no_permission": "您没有向服务器发送此命令的权限!", + "extra_arg": "此命令不能添加参数!", + "answer": "已执行!\n<res>" + }, + "get_invitation": { + "help": "#邀请码 | 索取皮肤站邀请码", + "get_msg": "您的邀请码为:<code>", + "no_chance": "您已耗尽邀请码次数!请联系管理员" + }, + "help": { + "help": "#帮助 | 查看机器人帮助" + }, + "issue_cmd": { + "no_permission": "您没有向服务器发送命令的权限!", + "format_error": "发送格式错误!\n发送格式:#命令 命令,回传行数,等待执行时间,服务器tag", + "server_tag_not_exist": "服务器不存在!", + "answer": "已执行!\n<res>" + }, + "mc_event": { + "server_start": "<tag>已开启,用时<time>s", + "server_stop": "<tag>已关闭", + "player_join": "<player>加入了<tag>", + "player_advancement": "<player>在<tag>中取得了进度[<advancement>]", + "player_chat": "<tag>中的<player>:<message>", + "player_quit": "<player>退出了<tag>", + "player_quit_private": "你退出了<tag>,请检查是否为掉线" + }, + "query_online": { + "help": "#在线人数 | 查询服务器在线人数", + "no_player": "当前<tag>无人在线", + "list_player": "<tag>当前有<num>人在线:<list>" + }, + "say_mc_msg": { + "help": "#服务器 内容 | 向服务器发送消息", + "format_error": "发送格式错误!\n发送格式:#服务器 内容", + "msg_in_game": "§5[QQ] §f<bind_player> <msg>" + }, + "tell_mc_msg": { + "help": "#私聊 ID 内容 | 向服务器内玩家私发消息", + "format_error": "发送格式错误!\n发送格式:#私聊 ID 内容", + "msg_in_game": "§5[QQ] §f<bind_player> 向你私聊消息:<msg>" + }, + "welcome": { + "help": "#欢迎 @新人 | 欢迎新人", + "message": "欢迎来到服务器!" + } +} \ No newline at end of file diff --git a/data/advancement_translation.json b/data/advancement_translation.json new file mode 100644 index 0000000..82d90cd --- /dev/null +++ b/data/advancement_translation.json @@ -0,0 +1,358 @@ +[ + { + "en": "Stone Age", + "zh_cn": "石器时代" + }, + { + "en": "Getting an Upgrade", + "zh_cn": "获得升级" + }, + { + "en": "Acquire Hardware", + "zh_cn": "来硬的" + }, + { + "en": "Suit Up", + "zh_cn": "整装上阵" + }, + { + "en": "Hot Stuff", + "zh_cn": "热腾腾的" + }, + { + "en": "Isn't It Iron Pick", + "zh_cn": "这不是铁镐么" + }, + { + "en": "Not Today, Thank You", + "zh_cn": "不吃这套,谢谢" + }, + { + "en": "Ice Bucket Challenge", + "zh_cn": "冰桶挑战" + }, + { + "en": "Diamonds!", + "zh_cn": "钻石!" + }, + { + "en": "We Need to Go Deeper", + "zh_cn": "勇往直下" + }, + { + "en": "Cover Me With Diamonds", + "zh_cn": "钻石护体" + }, + { + "en": "Enchanter", + "zh_cn": "附魔师" + }, + { + "en": "Zombie Doctor", + "zh_cn": "僵尸科医生" + }, + { + "en": "Eye Spy", + "zh_cn": "隔墙有眼" + }, + { + "en": "The End?", + "zh_cn": "结束了?" + }, + { + "en": "Nether", + "zh_cn": "下界" + }, + { + "en": "Return to Sender", + "zh_cn": "见鬼去吧" + }, + { + "en": "Those Were the Days", + "zh_cn": "光辉岁月" + }, + { + "en": "Hidden in the Depths", + "zh_cn": "深藏不露" + }, + { + "en": "Subspace Bubble", + "zh_cn": "曲速泡" + }, + { + "en": "A Terrible Fortress", + "zh_cn": "阴森的要塞" + }, + { + "en": "Who is Cutting Onions?", + "zh_cn": "谁在切洋葱?" + }, + { + "en": "Oh Shiny", + "zh_cn": "金光闪闪" + }, + { + "en": "This Boat Has Legs", + "zh_cn": "画船添足" + }, + { + "en": "Uneasy Alliance", + "zh_cn": "脆弱的同盟" + }, + { + "en": "War Pigs", + "zh_cn": "战猪" + }, + { + "en": "Country Lode, Take Me Home", + "zh_cn": "天涯共此石" + }, + { + "en": "Cover Me in Debris", + "zh_cn": "残骸裹身" + }, + { + "en": "Spooky Scary Skeleton", + "zh_cn": "惊悚恐怖骷髅头" + }, + { + "en": "Into Fire", + "zh_cn": "与火共舞" + }, + { + "en": "Not Quite \"Nine\" Lives", + "zh_cn": "锚没有九条命" + }, + { + "en": "Hot Tourist Destinations", + "zh_cn": "热门景点" + }, + { + "en": "Withering Heights", + "zh_cn": "凋零山庄" + }, + { + "en": "Local Brewery", + "zh_cn": "本地酿造厂" + }, + { + "en": "Bring Home the Beacon", + "zh_cn": "带信标回家" + }, + { + "en": "A Furious Cocktail", + "zh_cn": "狂乱的鸡尾酒" + }, + { + "en": "Beaconator", + "zh_cn": "信标工程师" + }, + { + "en": "How Did We Get Here?", + "zh_cn": "为什么会变成这样呢?" + }, + { + "en": "The End", + "zh_cn": "末地" + }, + { + "en": "Free the End", + "zh_cn": "解放末地" + }, + { + "en": "The Next Generation", + "zh_cn": "下一世代" + }, + { + "en": "Remote Getaway", + "zh_cn": "远程折跃" + }, + { + "en": "The End... Again...", + "zh_cn": "结束了…再一次…" + }, + { + "en": "You Need a Mint", + "zh_cn": "你需要来点薄荷糖" + }, + { + "en": "The City at the End of the Game", + "zh_cn": "在游戏尽头的城市" + }, + { + "en": "Sky's the Limit", + "zh_cn": "天空即为极限" + }, + { + "en": "Great View From Up Here", + "zh_cn": "这上面的风景不错" + }, + { + "en": "Adventure", + "zh_cn": "冒险" + }, + { + "en": "Voluntary Exile", + "zh_cn": "自我放逐" + }, + { + "en": "Is It a Bird?", + "zh_cn": "那是鸟吗?" + }, + { + "en": "Monster Hunter", + "zh_cn": "怪物猎人" + }, + { + "en": "What a Deal!", + "zh_cn": "成交!" + }, + { + "en": "Sticky Situation", + "zh_cn": "胶着状态" + }, + { + "en": "Ol' Betsy", + "zh_cn": "扣下悬刀" + }, + { + "en": "Surge Protector", + "zh_cn": "电涌保护器" + }, + { + "en": "Sweet dreams", + "zh_cn": "甜蜜的梦" + }, + { + "en": "Hero of the Village", + "zh_cn": "村庄英雄" + }, + { + "en": "Is It a Balloon?", + "zh_cn": "那是气球吗?" + }, + { + "en": "Throwaway Joke", + "zh_cn": "抖包袱" + }, + { + "en": "Take Aim", + "zh_cn": "瞄准目标" + }, + { + "en": "Monsters Hunted", + "zh_cn": "资深怪物猎人" + }, + { + "en": "Postmortal", + "zh_cn": "超越生死" + }, + { + "en": "Hired Help", + "zh_cn": "招募援兵" + }, + { + "en": "Two Birds, One Arrow", + "zh_cn": "一箭双雕" + }, + { + "en": "Who's the Pillager Now?", + "zh_cn": "现在谁才是掠夺者?" + }, + { + "en": "Arbalistic", + "zh_cn": "劲弩手" + }, + { + "en": "Adventuring Time", + "zh_cn": "探索的时光" + }, + { + "en": "Is It a Plane?", + "zh_cn": "那是飞机吗?" + }, + { + "en": "Very Very Frightening", + "zh_cn": "魔女审判" + }, + { + "en": "Sniper Duel", + "zh_cn": "狙击手的对决" + }, + { + "en": "Bullseye", + "zh_cn": "正中靶心" + }, + { + "en": "Husbandry", + "zh_cn": "农牧业" + }, + { + "en": "Bee Our Guest", + "zh_cn": "与蜂共舞" + }, + { + "en": "The Parrots and the Bats", + "zh_cn": "我从哪儿来?" + }, + { + "en": "Whatever Floats Your Goat!", + "zh_cn": "羊帆起航!" + }, + { + "en": "Best Friends Forever", + "zh_cn": "永恒的伙伴" + }, + { + "en": "Glow and Behold!", + "zh_cn": "眼前一亮!" + }, + { + "en": "Fishy Business", + "zh_cn": "腥味十足的生意" + }, + { + "en": "Total Beelocation", + "zh_cn": "举巢搬迁" + }, + { + "en": "A Seedy Place", + "zh_cn": "开荒垦地" + }, + { + "en": "Wax On", + "zh_cn": "涂蜡" + }, + { + "en": "Two by Two", + "zh_cn": "成双成对" + }, + { + "en": "A Complete Catalogue", + "zh_cn": "百猫全书" + }, + { + "en": "Tactical fishing", + "zh_cn": "战术性钓鱼" + }, + { + "en": "A Balanced Diet", + "zh_cn": "均衡饮食" + }, + { + "en": "Serious Dedication", + "zh_cn": "终极奉献" + }, + { + "en": "Wax Off", + "zh_cn": "脱蜡" + }, + { + "en": "The Cutest Predator", + "zh_cn": "最萌捕食者" + }, + { + "en": "The Healing Power of Friendship!", + "zh_cn": "友谊的治愈力!" + } +] \ No newline at end of file diff --git a/data/bind_qq.json b/data/bind_qq.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/data/bind_qq.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/data/invitation.json b/data/invitation.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/data/invitation.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..bb1d03f --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,22 @@ +[tool.poetry] +name = "AkashicQQ" +version = "0.1.0" +description = "AkashicQQ" +authors = [] +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.7" +nonebot2 = "^2.0.0.a1" +nb-cli = "^0.1.0" + +[tool.poetry.dev-dependencies] +nonebot-test = "^0.1.0" + +[nonebot.plugins] +plugins = ["nonebot_plugin_apscheduler"] +plugin_dirs = ["src/plugins"] + +[build-system] +requires = ["poetry>=0.12"] +build-backend = "poetry.masonry.api" diff --git a/src/plugins/bilibililive_checker/__init__.py b/src/plugins/bilibililive_checker/__init__.py new file mode 100644 index 0000000..a60d264 --- /dev/null +++ b/src/plugins/bilibililive_checker/__init__.py @@ -0,0 +1,74 @@ +import json +import asyncio + +import nonebot +from nonebot.log import logger +from nonebot import require +from nonebot.adapters.cqhttp import Bot, MessageSegment +import httpx + + +config = json.loads(open('./config/bilibililive_checker.json', 'r').read()) +text: str = json.loads( + open('./config/text.json', 'r').read())['bilibililive_checker']['message'] + +live_status = [False for i in range(len(config['liveroom']))] + +scheduler = require("nonebot_plugin_apscheduler").scheduler + + +@scheduler.scheduled_job("cron", second="*/5") +async def bilibili_checker_handler(): + if config['enable'] == False: + return + + post_data = { + 'uids': config['liveroom'] + } + + async with httpx.AsyncClient() as client: + res = await client.post(url='https://api.live.bilibili.com/room/v1/Room/get_status_info_by_uids', json=post_data) + res = res.json() + + if res['code'] != 0: + return + + for i in range(len(config['liveroom'])): + if res['data'][str(config['liveroom'][i])]['live_status'] == 1: + logger.debug(f"uid为{config['liveroom'][i]}的主播正在直播!") + + if live_status[i] == False: + + live_status[i] = True + + at_msg = MessageSegment.at('all') + '' + + msg = text.replace('<name>', res['data'][str(config['liveroom'][i])]['uname']).replace( + '<title>', res['data'][str(config['liveroom'][i])]['title']).replace( + '<area>', res['data'][str(config['liveroom'][i])]['area_v2_name']).replace( + '<url>', f"https://live.bilibili.com/{res['data'][str(config['liveroom'][i])]['room_id']}") + \ + MessageSegment.image( + res['data'][str(config['liveroom'][i])]['cover_from_user']) + + # 获取机器人 + while True: + try: + bot: Bot = nonebot.get_bot() + except ValueError: + asyncio.sleep(0) + else: + break + + for group_id in config['group']: + # 单独发送 @全体成员,防止次数耗尽导致完全收不到消息 + await bot.send_group_msg(group_id=group_id, message=at_msg) + await bot.send_group_msg(group_id=group_id, message=msg) + + logger.info( + f"uid为{config['liveroom'][i]}的主播正在直播,发送消息到群{config['group']}") + + else: + logger.debug(f"uid为{config['liveroom'][i]}的主播未在直播!") + + if live_status[i] == True: + live_status[i] = False diff --git a/src/plugins/bind_qq/__init__.py b/src/plugins/bind_qq/__init__.py new file mode 100644 index 0000000..d26e9ce --- /dev/null +++ b/src/plugins/bind_qq/__init__.py @@ -0,0 +1,75 @@ +import json + +from nonebot import on_command +from nonebot.log import logger +from nonebot.adapters.cqhttp import Bot, MessageSegment, MessageEvent + +import utils +import prism_api + + +text: dict = json.loads(open('./config/text.json', 'r').read())['bind_qq'] + +cmd_set: dict = json.loads(open('./config/cmd_alias.json', 'r').read())['bind_qq'] +bind_qq = on_command(cmd_set['cmd'], aliases=set(cmd_set['aliases'])) + + +@bind_qq.handle() +async def handle_bind_qq(bot: Bot, event: MessageEvent): + # 发送者 user_id + user_id = event.user_id + at_msg = MessageSegment.at(user_id) + '\n' + + # 发送者要绑定的玩家 + player_to_bind = str(event.message).strip() + + # 检测格式 + if player_to_bind == '': + await bind_qq.send(at_msg + text['format_error']) + logger.info(f"{user_id}发送格式错误!绑定请求被拒绝") + return + + logger.info(f"{user_id}尝试绑定{player_to_bind}") + + # 检测是否绑定过 + try: + record = json.loads(open('./data/bind_qq.json', 'r').read()) + except FileNotFoundError: + record = {} + + if str(user_id) in record: + await bind_qq.send(at_msg + text['already_bind']) + logger.debug(f"bind_qq表:{record}") + logger.info(f"{user_id}已绑定过!绑定请求被拒绝") + return + + # 获取所有登录过的玩家列表,用于检测 ID 是否真实存在 + res = [] + + # 获取所有服务器的 usercache 表 + for server in prism_api.config['server']: + prism_res = await prism_api.get(api='/usercache', server_tag=server['tag']) + res += prism_res['data']['usercache'] + + players = [] + + for player in res: + players.append(player['name']) + + # ID 不存在 + if player_to_bind not in players: + await bind_qq.send(at_msg + text['player_not_exist']) + logger.debug(f"usercache表:{res}") + logger.info(f"{user_id}要绑定的玩家不存在!绑定请求被拒绝") + return + + record[str(user_id)] = player_to_bind + + with open('./data/bind_qq.json', 'w') as fp: + fp.write(json.dumps(record)) + fp.close() + + await bind_qq.send(at_msg + text['success']) + + # 通知管理员 + await utils.inform_admin(message='绑定了游戏账号:' + player_to_bind, member_user_id=user_id) diff --git a/src/plugins/call_admin/__init__.py b/src/plugins/call_admin/__init__.py new file mode 100644 index 0000000..be34b42 --- /dev/null +++ b/src/plugins/call_admin/__init__.py @@ -0,0 +1,66 @@ +import json + +from nonebot import on_command +from nonebot.log import logger +from nonebot.adapters.cqhttp import Bot, MessageSegment, MessageEvent + +import utils +import prism_api + + +not_bind_when_send_msg: str = json.loads( + open('./config/text.json', 'r').read())['bind_qq']['not_bind_when_send_msg'] +text: dict = json.loads(open('./config/text.json', 'r').read())['call_admin'] + +cmd_set: dict = json.loads(open('./config/cmd_alias.json', 'r').read())['call_admin'] +call_admin = on_command(cmd_set['cmd'], aliases=set(cmd_set['aliases'])) + + +@call_admin.handle() +async def handle_call_admin(bot: Bot, event: MessageEvent): + # 发送者 user_id + user_id = event.user_id + at_msg = MessageSegment.at(user_id) + '\n' + + # 内容 + msg_to_send = str(event.message).strip() + + # 检测格式 + if msg_to_send == '': + await call_admin.send(at_msg + text['format_error']) + logger.info(f"{user_id}发送格式错误!呼叫管理员请求被拒绝") + return + + logger.info(f"{user_id}尝试呼叫管理员:{msg_to_send}") + + # 检查发送者是否绑定账号 + try: + record = json.loads(open('./data/bind_qq.json', 'r').read()) + except FileNotFoundError: + record = {} + + if str(user_id) not in record: + logger.info(f"{user_id}试图向管理员发送消息但未绑定账号,已拒绝") + await call_admin.send(at_msg + not_bind_when_send_msg) + return + + # 在 QQ 中通知管理员 + await utils.inform_admin(message='向管理员发送消息:' + msg_to_send, member_user_id=user_id) + + # 获取群昵称 + res = await bot.get_group_member_info(group_id=utils.config['main_group'], user_id=user_id) + + if 'card' not in res: + user_card = res['nickname'] + else: + user_card = res['card'] + + # 尝试在游戏内通知管理员 + for admin_user_id in utils.config['admin_user']: + if str(admin_user_id) in record: + prism_data = { + 'message': f"§5[QQ] §f{user_card} 向管理员发送消息:" + msg_to_send, + 'selector': record[str(admin_user_id)] + } + + await prism_api.all_server_tellraw(data=prism_data) diff --git a/src/plugins/cmd_register/__init__.py b/src/plugins/cmd_register/__init__.py new file mode 100644 index 0000000..c588ce4 --- /dev/null +++ b/src/plugins/cmd_register/__init__.py @@ -0,0 +1,57 @@ +import json + +from nonebot import on_command +from nonebot.typing import T_State +from nonebot import logger +from nonebot.adapters.cqhttp import Bot, MessageSegment, MessageEvent + +import utils +import prism_api + + +config: list = json.loads(open('./config/cmd_register.json', 'r').read()) +text: dict = json.loads(open('./config/text.json', 'r').read())['cmd_register'] + +cmd_list: list = [one_cmd['cmd'] for one_cmd in config] + +for one_cmd in config: + cmd_list += one_cmd['aliases'] + +cmd_register = on_command('cmd_register', aliases=set(cmd_list)) + + +@cmd_register.handle() +async def handle_cmd_register(bot: Bot, event: MessageEvent, state: T_State): + # 发送者 user_card + user_id = event.user_id + at_msg = MessageSegment.at(user_id) + '\n' + + for cmd in config: + cmd_and_aliases = [cmd['cmd']] + cmd_and_aliases += cmd['aliases'] + + # 匹配到命令 + if state['_prefix']['command'][0] in cmd_and_aliases: + logger.info(f"{user_id}试图执行命令:{cmd['cmd']}") + + # 开始鉴权 + if cmd['permission'] == 'ALL' or \ + user_id in utils.config['op_user'] or \ + (cmd['permission'] == 'ADMIN' and user_id in utils.config['admin_user']) or \ + user_id in cmd['allow_member']: + arg = str(event.message).strip() + + if arg != '' and cmd['no_arg']: + logger.info(f"{user_id}试图为不可添加参数的命令添加参数") + await cmd_register.send(at_msg + text['extra_arg']) + return + + real_cmd = cmd['cmd'] + ' ' + arg + + res = await prism_api.server_cmd(cmd=real_cmd, num=cmd['num'], wait_time=cmd['wait_time'], server_tag=cmd['server_tag']) + msg = text['answer'].replace('<res>', res) + await cmd_register.send(at_msg + msg) + logger.info(f"命令执行结果:{res}") + else: + logger.info(f"{user_id}试图执行命令但无权限") + await cmd_register.send(at_msg + text['no_permission']) diff --git a/src/plugins/get_invitation/__init__.py b/src/plugins/get_invitation/__init__.py new file mode 100644 index 0000000..c7d13ce --- /dev/null +++ b/src/plugins/get_invitation/__init__.py @@ -0,0 +1,87 @@ +import time +import string +import random +import json + +from nonebot import on_command +from nonebot import logger +from nonebot.adapters.cqhttp import Bot, MessageSegment, MessageEvent +import aiomysql + +import utils + + +config: dict = json.loads(open('./config/get_invitation.json', 'r').read()) +text: dict = json.loads( + open('./config/text.json', 'r').read())['get_invitation'] + +cmd_set: dict = json.loads(open('./config/cmd_alias.json', 'r').read())['get_invitation'] +get_invitation = on_command(cmd_set['cmd'], aliases=set(cmd_set['aliases'])) + + +@get_invitation.handle() +async def handle_get_invitation(bot: Bot, event: MessageEvent): + # 发送者 user_id + user_id = event.user_id + at_msg = MessageSegment.at(user_id) + '\n' + + # 鉴定发起者是否有剩余次数 + try: + record = json.loads(open('./data/invitation.json', 'r').read()) + except FileNotFoundError: + record = {} + + # 不存在记录,设置为初始值 + if str(user_id) not in record: + if user_id not in utils.config['admin_user']: + record[str(user_id)] = config['initial_chance'] + else: + record[str(user_id)] = 1 + + # 有剩余机会或请求者为管理员,则为其生成邀请码 + if record[str(user_id)] > 0 or user_id in utils.config['admin_user']: + conn = await aiomysql.connect( + host=config['blessing_skin_server_mysql']['host'], + port=config['blessing_skin_server_mysql']['port'], + user=config['blessing_skin_server_mysql']['user'], + password=config['blessing_skin_server_mysql']['password'], + db=config['blessing_skin_server_mysql']['db'] + ) + + cur = await conn.cursor() + await cur.execute("SELECT id FROM invitation_codes") + res = await cur.fetchall() + + new_id = max(res)[0] + 1 + code = f"from{user_id}_" + \ + ''.join(random.sample(string.ascii_letters + string.digits, 8)) + time_stamp = time.strftime( + '%Y-%m-%d %H:%M:%S', time.localtime(time.time())) + + await cur.execute( + "INSERT INTO `invitation_codes` (`id`, `code`, `generated_at`, `used_by`, `used_at`) " + + f"VALUES ('{new_id}', '{code}', '{time_stamp}', '0', NULL)" + ) + await conn.commit() + conn.close() + + msg = text['get_msg'].replace('<code>', code) + await get_invitation.send(at_msg + msg) + + # 非管理员,次数减一 + if user_id not in utils.config['admin_user']: + record[str(user_id)] -= 1 + + with open('./data/invitation.json', 'w') as fp: + fp.write(json.dumps(record)) + fp.close() + + # 通知管理员 + await utils.inform_admin(message='索取了邀请码:' + code, member_user_id=user_id) + + else: + msg = text['no_chance'] + await get_invitation.send(at_msg + msg) + + # 通知管理员 + await utils.inform_admin(message='试图索取邀请码,但邀请次数已耗尽', member_user_id=user_id) diff --git a/src/plugins/group_increase/__init__.py b/src/plugins/group_increase/__init__.py new file mode 100644 index 0000000..f612209 --- /dev/null +++ b/src/plugins/group_increase/__init__.py @@ -0,0 +1,30 @@ +import json + +from nonebot import on_notice +from nonebot.log import logger +from nonebot.adapters.cqhttp import Bot, MessageSegment, GroupIncreaseNoticeEvent + +import utils + + +welcome_msg: str = json.loads( + open('./config/text.json', 'r').read())['welcome']['message'] + +group_increase = on_notice() + + +@group_increase.handle() +async def handle_group_increase(bot: Bot, event: GroupIncreaseNoticeEvent): + # 入群者 user_id + user_id = event.user_id + at_msg = MessageSegment.at(user_id) + '\n' + + # 发送入群欢迎消息 + await group_increase.send(at_msg + welcome_msg) + logger.info(f"向{user_id}发送入群欢迎消息") + logger.debug(f"欢迎消息:{welcome_msg}") + + # 向管理员提示新增成员 + user_id = event.user_id + group_id = event.group_id + await utils.inform_admin(message='进入群' + str(group_id), member_user_id=user_id) diff --git a/src/plugins/help/__init__.py b/src/plugins/help/__init__.py new file mode 100644 index 0000000..eb78533 --- /dev/null +++ b/src/plugins/help/__init__.py @@ -0,0 +1,26 @@ +import json +from typing import Dict + +from nonebot import on_command +from nonebot import logger +from nonebot.adapters.cqhttp import Bot, Message, MessageEvent + + +text: dict = json.loads(open('./config/text.json', 'r').read()) + +cmd_set: dict = json.loads(open('./config/cmd_alias.json', 'r').read())['help'] +help = on_command(cmd_set['cmd'], aliases=set(cmd_set['aliases'])) + + +@help.handle() +async def handle_help(bot: Bot, event: MessageEvent): + logger.info('请求帮助') + + msg = '' + + for key in text: + if type(text[key]) == type({}): + if 'help' in text[key]: + msg += text[key]['help'] + '\n' + + await help.send(msg) diff --git a/src/plugins/issue_cmd/__init__.py b/src/plugins/issue_cmd/__init__.py new file mode 100644 index 0000000..3add574 --- /dev/null +++ b/src/plugins/issue_cmd/__init__.py @@ -0,0 +1,75 @@ +import json + +from nonebot import on_command +from nonebot.log import logger +from nonebot.adapters.cqhttp import Bot, MessageSegment, MessageEvent + +import prism_api + + +op_user: list = json.loads(open('./config/group.json', 'r').read())['op_user'] +text: dict = json.loads(open('./config/text.json', 'r').read())['issue_cmd'] + +cmd_set: dict = json.loads( + open('./config/cmd_alias.json', 'r').read())['issue_cmd'] +issue_cmd = on_command(cmd_set['cmd'], aliases=set(cmd_set['aliases'])) + + +@issue_cmd.handle() +async def handle_issue_cmd(bot: Bot, event: MessageEvent): + # 发送者 user_id + user_id = event.user_id + at_msg = MessageSegment.at(user_id) + '\n' + + string = str(event.message).strip() + arg_list = string.split(',') + + logger.info(f"{user_id}试图执行命令:{arg_list}") + + # 鉴权 + if user_id not in op_user: + await issue_cmd.send(at_msg + text['no_permission']) + logger.debug(f"op_user为:{op_user}") + logger.info(f"{user_id}试图执行命令但无权限") + return + + # 处理命令格式,参数分别为 cmd num wait_time server_tag + cmd = arg_list[0] + + if cmd == '': + await issue_cmd.send(at_msg + text['format_error']) + logger.info(f"{user_id}发送格式错误!执行命令请求被拒绝") + return + + if len(arg_list) > 1: + num = int(arg_list[1]) + else: + num = 1 + + if len(arg_list) > 2: + wait_time = int(arg_list[2]) + else: + wait_time = 1 + + if len(arg_list) > 3: + server = arg_list[3] + + exist_server_tag_list = [] + for server in prism_api.config['server']: + exist_server_tag_list.append(server['tag']) + + if server not in exist_server_tag_list: + await issue_cmd.send(at_msg + text['server_tag_not_exist']) + logger.info("服务器不存在!执行命令请求被拒绝") + return + + else: + server = None + + # 发送命令 + res = await prism_api.server_cmd(cmd=cmd, num=num, wait_time=wait_time, server_tag=server) + + # 回传结果 + msg = text['answer'].replace('<res>', res) + await issue_cmd.send(at_msg + msg) + logger.info(f"命令执行结果:{res}") diff --git a/src/plugins/mc_event/__init__.py b/src/plugins/mc_event/__init__.py new file mode 100644 index 0000000..ffa151d --- /dev/null +++ b/src/plugins/mc_event/__init__.py @@ -0,0 +1,192 @@ +import json +import asyncio + +import nonebot +from nonebot.log import logger +from nonebot.adapters.cqhttp import Bot +from fastapi import Body, FastAPI + +import prism_api + + +config: dict = json.loads(open('./config/mc_event.json', 'r').read()) +group_config: dict = json.loads(open('./config/group.json', 'r').read()) +text: dict = json.loads(open('./config/text.json', 'r').read())['mc_event'] +not_bind_msg_in_game: str = json.loads( + open('./config/text.json', 'r').read())['bind_qq']['not_bind_msg_in_game'] + + +app: FastAPI = nonebot.get_app() + + +@app.post('/') +async def mc_event_handler(data: dict = Body(...)): + data = data['data'] + logger.info(f"收到MC事件: {data}") + + while True: + try: + bot: Bot = nonebot.get_bot() + except ValueError: + asyncio.sleep(0) + else: + break + + # 处理事件 + if data['type'] == 'ServerStart': + await server_start_handler(bot, data) + elif data['type'] == 'ServerStop': + await server_stop_handler(bot, data) + elif data['type'] == 'PlayerJoin': + await player_join_handler(bot, data) + elif data['type'] == 'PlayerAdvancement': + await player_advancement_handler(bot, data) + elif data['type'] == 'PlayerChat': + await player_chat_handler(bot, data) + elif data['type'] == 'PlayerQuit': + await player_quit_handler(bot, data) + + return { + "status": 200, + "msg": "success" + } + + +async def server_start_handler(bot: Bot, data: dict): + if config['enable']['server_start'] == False: + return + + message = text['server_start'].replace('<tag>', data['tag']).replace( + '<time>', str(data['start_use_time'])) + + await bot.send_group_msg(group_id=group_config['main_group'], message=message) + + +async def server_stop_handler(bot: Bot, data: dict): + if config['enable']['server_stop'] == False: + return + + message = text['server_stop'].replace('<tag>', data['tag']) + + await bot.send_group_msg(group_id=group_config['main_group'], message=message) + + +async def player_join_handler(bot: Bot, data: dict): + if config['enable']['player_join'] == False: + return + + message = text['player_join'].replace( + '<player>', data['player']).replace('<tag>', data['tag']) + + await bot.send_group_msg(group_id=group_config['main_group'], message=message) + + prism_data = { + 'message': f"§5[{data['tag']}] §f" + message, + 'selector': '@a' + } + + # 向其他服务器广播消息 + for server in prism_api.config['server']: + if data['tag'] != server['tag']: + await prism_api.post(api='/tellraw', data=prism_data, server_tag=server['tag']) + + # 检测玩家是否绑定账号 + try: + record = json.loads(open('./data/bind_qq.json', 'r').read()) + players = list(record.values()) + except FileNotFoundError: + players = [] + + # 玩家未绑定账号 + if data['player'] not in players: + prism_data = { + 'message': not_bind_msg_in_game.replace('<player>', data['player']), + 'selector': data['player'] + } + + await prism_api.post(api='/tellraw', data=prism_data, server_tag=data['tag']) + logger.info(f"加入服务器{data['tag']}的玩家{data['player']}未绑定账号,已向其发送提示") + + +async def player_advancement_handler(bot: Bot, data: dict): + if config['enable']['player_advancement'] == False: + return + + # 检查成就翻译 + try: + tranlation = json.loads( + open('./data/advancement_translation.json', 'r').read()) + except FileNotFoundError: + tranlation = {} + + for adv in tranlation: + if adv['en'].lower().strip() == data['advancement'].lower().strip(): + data['advancement'] = adv['zh_cn'] + break + + message = text['player_advancement'].replace( + '<player>', data['player']).replace('<advancement>', data['advancement']).replace('<tag>', data['tag']) + + await bot.send_group_msg(group_id=group_config['main_group'], message=message) + + prism_data = { + 'message': f"§5[{data['tag']}] §f" + message, + 'selector': '@a' + } + + # 向其他服务器广播消息 + for server in prism_api.config['server']: + if data['tag'] != server['tag']: + await prism_api.post(api='/tellraw', data=prism_data, server_tag=server['tag']) + + +async def player_chat_handler(bot: Bot, data: dict): + if config['enable']['player_chat'] == False: + return + + message = text['player_chat'].replace( + '<player>', data['player']).replace('<message>', data['message']).replace('<tag>', data['tag']) + + await bot.send_group_msg(group_id=group_config['main_group'], message=message) + + prism_data = { + 'message': f"§5[{data['tag']}] §f" + message, + 'selector': '@a' + } + + # 向其他服务器广播消息 + for server in prism_api.config['server']: + if data['tag'] != server['tag']: + await prism_api.post(api='/tellraw', data=prism_data, server_tag=server['tag']) + + +async def player_quit_handler(bot: Bot, data: dict): + if config['enable']['player_quit'] == True: + message = text['player_quit'].replace( + '<player>', data['player']).replace('<tag>', data['tag']) + + await bot.send_group_msg(group_id=group_config['main_group'], message=message) + + prism_data = { + 'message': f"§5[{data['tag']}] §f" + message, + 'selector': '@a' + } + + # 向其他服务器广播消息 + for server in prism_api.config['server']: + if data['tag'] != server['tag']: + await prism_api.post(api='/tellraw', data=prism_data, server_tag=server['tag']) + + if config['enable']['player_quit_private'] == True: + # 向本人发送消息,提醒下线 + try: + record = json.loads(open('./data/bind_qq.json', 'r').read()) + except FileNotFoundError: + record = {} + + for key in record: + if record[key] == data['player']: + message = text['player_quit_private'].replace( + '<player>', data['player']).replace('<tag>', data['tag']) + + await bot.send_private_msg(user_id=int(key), message=message) diff --git a/src/plugins/prism_api/__init__.py b/src/plugins/prism_api/__init__.py new file mode 100644 index 0000000..7c413cf --- /dev/null +++ b/src/plugins/prism_api/__init__.py @@ -0,0 +1,73 @@ +import json +import re + +from nonebot.log import logger +import httpx + + +config = json.loads(open('./config/mc_server.json', 'r').read()) + + +async def get(api: str, server_tag: str = None): + if server_tag == None: + server_tag = config['main_server_tag'] + + for server in config['server']: + if server['tag'] == server_tag: + url = server['url'] + + async with httpx.AsyncClient() as client: + logger.debug(f"发送prism_api.get:{url + api} server={server_tag}") + resp = await client.get(url=url + api, timeout=10) + resp = resp.json() + logger.debug(f"prism_api.get回复:{resp}") + return resp + + +async def post(api: str, data: dict = [], server_tag: str = None): + if server_tag == None: + server_tag = config['main_server_tag'] + + for server in config['server']: + if server['tag'] == server_tag: + url = server['url'] + + async with httpx.AsyncClient() as client: + logger.debug( + f"发送prism_api.post:{url + api} data={data} server={server_tag}") + resp = await client.post(url=url + api, json=data, timeout=10) + resp = resp.json() + logger.debug(f"prism_api.post回复:{resp}") + return resp + + +async def server_cmd(cmd: str, num: int = 1, wait_time: int = 1, server_tag: str = None): + data = { + 'cmd': cmd, + 'num': num, + 'wait_time': wait_time + } + + logger.debug(f"发送prism_api.server_cmd:data={data} server={server_tag}") + res = await post(api='/cmd', data=data, server_tag=server_tag) + + if res['status'] == 200: + res_str = '' + for string in res['data']['list']: + temp_list = re.findall("]: (.*?)$", string) + + if temp_list: + res_str += temp_list[0] + '\n' + + logger.debug(f"prism_api.server_cmd回复:{res_str}") + return res_str + else: + logger.debug(f"prism_api.server_cmd请求对应服务器未开启游戏,返回空值") + return '' + + +async def all_server_tellraw(data: dict = []): + logger.debug(f"prism_api.all_server_tellraw data={data}") + async with httpx.AsyncClient() as client: + for server in config['server']: + await client.post(url=server['url'] + '/tellraw', json=data, timeout=10) diff --git a/src/plugins/query_online/__init__.py b/src/plugins/query_online/__init__.py new file mode 100644 index 0000000..a5f4d03 --- /dev/null +++ b/src/plugins/query_online/__init__.py @@ -0,0 +1,37 @@ +import json + +from nonebot import on_command +from nonebot import logger +from nonebot.adapters.cqhttp import Bot, MessageSegment, MessageEvent + +import prism_api + + +text: dict = json.loads(open('./config/text.json', 'r').read())['query_online'] + +cmd_set: dict = json.loads(open('./config/cmd_alias.json', 'r').read())['query_online'] +query_online = on_command(cmd_set['cmd'], aliases=set(cmd_set['aliases'])) + + +@query_online.handle() +async def handle_query_online(bot: Bot, event: MessageEvent): + for server in prism_api.config['server']: + res = await prism_api.get(api='/list', server_tag=server['tag']) + tag = res['data']['tag'] + res = res['data']['player_list'] + + num = len(res) + if num == 0: + msg = text['no_player'].replace('<tag>', tag) + else: + player_list = '' + for i in range(num): + if i == 0: + player_list += res[i] + else: + player_list += ', ' + res[i] + msg = text['list_player'].replace( + '<num>', str(num)).replace('<list>', player_list).replace('<tag>', tag) + + logger.info(f"查询在线人数:{tag} {res}") + await query_online.send(msg) diff --git a/src/plugins/say_mc_msg/__init__.py b/src/plugins/say_mc_msg/__init__.py new file mode 100644 index 0000000..fc57b0c --- /dev/null +++ b/src/plugins/say_mc_msg/__init__.py @@ -0,0 +1,51 @@ +import json + +from nonebot import on_command +from nonebot import logger +from nonebot.adapters.cqhttp import Bot, MessageSegment, MessageEvent + +import prism_api + + +not_bind_when_send_msg: str = json.loads( + open('./config/text.json', 'r').read())['bind_qq']['not_bind_when_send_msg'] +text: dict = json.loads(open('./config/text.json', 'r').read())['say_mc_msg'] + +cmd_set: dict = json.loads(open('./config/cmd_alias.json', 'r').read())['say_mc_msg'] +say_mc_msg = on_command(cmd_set['cmd'], aliases=set(cmd_set['aliases'])) + + +@say_mc_msg.handle() +async def handle_say_mc_msg(bot: Bot, event: MessageEvent): + # 发送者 user_id + user_id = event.user_id + at_msg = MessageSegment.at(user_id) + '\n' + + # 检查发送者是否绑定账号 + try: + record = json.loads(open('./data/bind_qq.json', 'r').read()) + except FileNotFoundError: + record = {} + + if str(user_id) not in record: + logger.info(f"{user_id}试图向服务器发送消息但未绑定账号,已拒绝") + await say_mc_msg.send(at_msg + not_bind_when_send_msg) + return + + user_card = record[str(user_id)] + + # 发送消息 + msg_to_send = str(event.message).strip() + + if msg_to_send == '': + logger.info(f"{user_id}发送格式错误!发送消息请求被拒绝") + await say_mc_msg.send(at_msg + text['format_error']) + return + + data = { + 'message': text['msg_in_game'].replace('<bind_player>', user_card).replace('<msg>', msg_to_send), + 'selector': '@a' + } + + await prism_api.all_server_tellraw(data=data) + logger.info(f"{user_id}向服务器发送消息:{msg_to_send}") diff --git a/src/plugins/tell_mc_msg/__init__.py b/src/plugins/tell_mc_msg/__init__.py new file mode 100644 index 0000000..8a90da2 --- /dev/null +++ b/src/plugins/tell_mc_msg/__init__.py @@ -0,0 +1,52 @@ +import json + +from nonebot import on_command +from nonebot import logger +from nonebot.adapters.cqhttp import Bot, MessageSegment, MessageEvent + +import prism_api + + +not_bind_when_send_msg: str = json.loads( + open('./config/text.json', 'r').read())['bind_qq']['not_bind_when_send_msg'] +text: dict = json.loads(open('./config/text.json', 'r').read())['tell_mc_msg'] + +cmd_set: dict = json.loads(open('./config/cmd_alias.json', 'r').read())['tell_mc_msg'] +tell_mc_msg = on_command(cmd_set['cmd'], aliases=set(cmd_set['aliases'])) + + +@tell_mc_msg.handle() +async def handle_tell_mc_msg(bot: Bot, event: MessageEvent): + # 发送者 user_card + user_id = event.user_id + at_msg = MessageSegment.at(user_id) + '\n' + + # 检查发送者是否绑定账号 + record = json.loads(open('./data/bind_qq.json', 'r').read()) + + if str(user_id) not in record: + logger.info(f"{user_id}试图向服务器私聊消息但未绑定账号,已拒绝") + await tell_mc_msg.send(at_msg + not_bind_when_send_msg) + return + + user_card = record[str(user_id)] + + # 发送消息 + stripped_arg = str(event.message).strip() + + index = stripped_arg.find(' ') + player_id = stripped_arg[0:index] + msg_to_send = (stripped_arg[index + 1:len(stripped_arg)]) + + if player_id == '' or msg_to_send == '' or index == -1: + logger.info(f"{user_id}发送格式错误!私聊消息请求被拒绝") + await tell_mc_msg.send(at_msg + text['format_error']) + return + + data = { + 'message': text['msg_in_game'].replace('<bind_player>', user_card).replace('<msg>', msg_to_send), + 'selector': player_id + } + + await prism_api.all_server_tellraw(data=data) + logger.info(f"{user_id}向{player_id}私聊消息:{msg_to_send}") diff --git a/src/plugins/utils/__init__.py b/src/plugins/utils/__init__.py new file mode 100644 index 0000000..5fbb281 --- /dev/null +++ b/src/plugins/utils/__init__.py @@ -0,0 +1,40 @@ +import json +import asyncio + +import nonebot +from nonebot import logger +from nonebot.adapters.cqhttp import Bot + + +config = json.loads(open('./config/group.json', 'r').read()) + + +async def inform_admin(message: str, member_user_id: int = None): + while True: + try: + bot: Bot = nonebot.get_bot() + except ValueError: + asyncio.sleep(0) + else: + break + + # 指定 member_user_id + if member_user_id != None: + # 获取 member 群昵称 + res = await bot.get_group_member_info(group_id=config['main_group'], user_id=member_user_id) + + if 'card' not in res: + user_card = res['nickname'] + else: + user_card = res['card'] + + for i in range(len(config['admin_user'])): + await bot.send_private_msg(user_id=config['admin_user'][i], message=f"{user_card}({member_user_id}){message}") + + logger.info(f"{user_card}({member_user_id}){message}") + + else: + for i in range(len(config['admin_user'])): + await bot.send_private_msg(user_id=config['admin_user'][i], message=message) + + logger.info(message) diff --git a/src/plugins/welcome/__init__.py b/src/plugins/welcome/__init__.py new file mode 100644 index 0000000..ce433d1 --- /dev/null +++ b/src/plugins/welcome/__init__.py @@ -0,0 +1,28 @@ +import json + +from nonebot import on_command +from nonebot import logger +from nonebot.adapters.cqhttp import Bot, Message, MessageEvent + + +welcome_msg: str = json.loads( + open('./config/text.json', 'r').read())['welcome']['message'] + +cmd_set: dict = json.loads(open('./config/cmd_alias.json', 'r').read())['welcome'] +welcome = on_command(cmd_set['cmd'], aliases=set(cmd_set['aliases'])) + + +@welcome.handle() +async def handle_welcome(bot: Bot, event: MessageEvent): + arg = str(event.message).strip() + + if not arg: # 用户未发送参数 + at_msg = '' + + else: # 用户发送参数 + at_msg = Message(arg + '\n') + + logger.info('发送欢迎消息') + logger.debug(f"欢迎消息:{welcome_msg}") + + await welcome.send(at_msg + welcome_msg)