nonebot_plugin_mc_server_status 0.2.11__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,116 @@
1
+ Metadata-Version: 2.1
2
+ Name: nonebot_plugin_mc_server_status
3
+ Version: 0.2.11
4
+ Summary: Nonebot2查询MC服务器在线信息插件
5
+ Home-page: https://github.com/nikissXI/nonebot_plugins/tree/main/nonebot_plugin_mc_server_status
6
+ License: MIT
7
+ Author: nikissXI
8
+ Author-email: 1299577815@qq.com
9
+ Requires-Python: >=3.8
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Requires-Dist: mcstatus (>=10.0.0)
18
+ Requires-Dist: nonebot-adapter-onebot (>=2.0.0)
19
+ Requires-Dist: nonebot2 (>=2.0.0rc1)
20
+ Project-URL: Documentation, https://github.com/nikissXI/nonebot_plugins/tree/main/nonebot_plugin_mc_server_status#README.md
21
+ Project-URL: Repository, https://github.com/nikissXI/nonebot_plugins/tree/main/nonebot_plugin_mc_server_status
22
+ Description-Content-Type: text/markdown
23
+
24
+ <p align="center">
25
+ <a href="https://v2.nonebot.dev/store">
26
+ <img src="https://user-images.githubusercontent.com/44545625/209862575-acdc9feb-3c76-471d-ad89-cc78927e5875.png" width="180" height="180" alt="NoneBotPluginLogo"></a>
27
+ </p>
28
+
29
+ <div align="center">
30
+
31
+ # nonebot_plugin_mc_server_status
32
+
33
+ _✨ Nonebot2查询MC服务器在线信息插件 ✨_
34
+
35
+ </div>
36
+
37
+ <p align="center">
38
+ <a href="https://opensource.org/licenses/MIT">
39
+ <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="license">
40
+ </a>
41
+ <a href="https://v2.nonebot.dev/">
42
+ <img src="https://img.shields.io/static/v1?label=nonebot&message=v2rc1%2B&color=green" alt="nonebot2">
43
+ </a>
44
+ <img src="https://img.shields.io/static/v1?label=python+&message=3.8%2B&color=blue" alt="python">
45
+ </p>
46
+
47
+ ## 开发者信息
48
+ - nikiss,个人QQ 1299577815,插件反馈QQ群 226462236,插件有问题到群里反馈响应更快哦
49
+ - <img width="100" src="https://avatars.githubusercontent.com/u/31379266"/>
50
+
51
+ ## 简介
52
+ 使用mcstatus库,支持Java和Bedrock服务器的服务器查询。
53
+
54
+ <img width="300" src="https://raw.githubusercontent.com/nikissXI/nonebot_plugins/main/nonebot_plugin_mc_server_status/readme_img/xinxi.jpg"/>
55
+
56
+ ## 安装
57
+
58
+ 使用nb-cli安装
59
+ ```bash
60
+ nb plugin install nonebot_plugin_mc_server_status
61
+ ```
62
+
63
+ 或者
64
+ 直接把插件clone下来放进去plugins文件夹,记得把依赖装上 pip install mcstatus
65
+
66
+ ## 使用
67
+
68
+ 添加了服务器信息后,会在bot根目录下的data目录创建一个mc_status_data.json文件,用于存储插件信息
69
+ 在bot对应的.env文件修改
70
+
71
+ ```bash
72
+ # 管理员的QQ号(别问我为什么要另外写)
73
+ mc_status_admin_qqnum = 114514
74
+
75
+ # 可选配置
76
+ # 机器人的QQ号列表,如果有多个bot连接,会按照填写的list,左边的机器人QQ优先级最高 1234 > 5678 > 6666,会自动切换
77
+ # 如果不填该配置则由第一个连上的bot响应
78
+ mc_status_bot_qqnum_list = [1234, 5678, 6666]
79
+ ```
80
+
81
+ ## 插件命令
82
+ | 指令 | 说明 |
83
+ |:-----:|:----:|
84
+ | 信息|所有人都能使用,查看当前群添加的服务器状态,需要加命令前缀,默认/|
85
+ | 信息数据|查看已添加的群和服务器信息,bot超级管理员用,需要加命令前缀,默认/|
86
+ | 添加服务器|字面意思,bot超级管理员用,一个群可以添加多个服务器|
87
+ | 删除服务器|字面意思,bot超级管理员用|
88
+
89
+ ## 更新日志
90
+ ### 2023/2/11 \[v0.2.9]
91
+
92
+ * 信息和信息数据的增加命令前缀
93
+
94
+ ### 2023/1/24 \[v0.2.8]
95
+
96
+ * 修复多bot处理bug
97
+
98
+ ### 2023/1/20 \[v0.2.7]
99
+
100
+ * gocq插件版不支持base64图片发送,改为BytesIO发送服务器图标
101
+
102
+ ### 2023/1/17 \[v0.2.4]
103
+
104
+ * 又忘记删东西导致无法运行,已修复
105
+
106
+ ### 2023/1/16 \[v0.2.3]
107
+
108
+ * 最低python版本兼容至3.8
109
+
110
+ ### 2023/1/15 \[v0.2.2]
111
+
112
+ * 优化多bot逻辑,机器人qq号配置改为可选
113
+
114
+ ### 2023/1/15 \[v0.2.1]
115
+
116
+ * 插件重构
@@ -0,0 +1,93 @@
1
+ <p align="center">
2
+ <a href="https://v2.nonebot.dev/store">
3
+ <img src="https://user-images.githubusercontent.com/44545625/209862575-acdc9feb-3c76-471d-ad89-cc78927e5875.png" width="180" height="180" alt="NoneBotPluginLogo"></a>
4
+ </p>
5
+
6
+ <div align="center">
7
+
8
+ # nonebot_plugin_mc_server_status
9
+
10
+ _✨ Nonebot2查询MC服务器在线信息插件 ✨_
11
+
12
+ </div>
13
+
14
+ <p align="center">
15
+ <a href="https://opensource.org/licenses/MIT">
16
+ <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="license">
17
+ </a>
18
+ <a href="https://v2.nonebot.dev/">
19
+ <img src="https://img.shields.io/static/v1?label=nonebot&message=v2rc1%2B&color=green" alt="nonebot2">
20
+ </a>
21
+ <img src="https://img.shields.io/static/v1?label=python+&message=3.8%2B&color=blue" alt="python">
22
+ </p>
23
+
24
+ ## 开发者信息
25
+ - nikiss,个人QQ 1299577815,插件反馈QQ群 226462236,插件有问题到群里反馈响应更快哦
26
+ - <img width="100" src="https://avatars.githubusercontent.com/u/31379266"/>
27
+
28
+ ## 简介
29
+ 使用mcstatus库,支持Java和Bedrock服务器的服务器查询。
30
+
31
+ <img width="300" src="https://raw.githubusercontent.com/nikissXI/nonebot_plugins/main/nonebot_plugin_mc_server_status/readme_img/xinxi.jpg"/>
32
+
33
+ ## 安装
34
+
35
+ 使用nb-cli安装
36
+ ```bash
37
+ nb plugin install nonebot_plugin_mc_server_status
38
+ ```
39
+
40
+ 或者
41
+ 直接把插件clone下来放进去plugins文件夹,记得把依赖装上 pip install mcstatus
42
+
43
+ ## 使用
44
+
45
+ 添加了服务器信息后,会在bot根目录下的data目录创建一个mc_status_data.json文件,用于存储插件信息
46
+ 在bot对应的.env文件修改
47
+
48
+ ```bash
49
+ # 管理员的QQ号(别问我为什么要另外写)
50
+ mc_status_admin_qqnum = 114514
51
+
52
+ # 可选配置
53
+ # 机器人的QQ号列表,如果有多个bot连接,会按照填写的list,左边的机器人QQ优先级最高 1234 > 5678 > 6666,会自动切换
54
+ # 如果不填该配置则由第一个连上的bot响应
55
+ mc_status_bot_qqnum_list = [1234, 5678, 6666]
56
+ ```
57
+
58
+ ## 插件命令
59
+ | 指令 | 说明 |
60
+ |:-----:|:----:|
61
+ | 信息|所有人都能使用,查看当前群添加的服务器状态,需要加命令前缀,默认/|
62
+ | 信息数据|查看已添加的群和服务器信息,bot超级管理员用,需要加命令前缀,默认/|
63
+ | 添加服务器|字面意思,bot超级管理员用,一个群可以添加多个服务器|
64
+ | 删除服务器|字面意思,bot超级管理员用|
65
+
66
+ ## 更新日志
67
+ ### 2023/2/11 \[v0.2.9]
68
+
69
+ * 信息和信息数据的增加命令前缀
70
+
71
+ ### 2023/1/24 \[v0.2.8]
72
+
73
+ * 修复多bot处理bug
74
+
75
+ ### 2023/1/20 \[v0.2.7]
76
+
77
+ * gocq插件版不支持base64图片发送,改为BytesIO发送服务器图标
78
+
79
+ ### 2023/1/17 \[v0.2.4]
80
+
81
+ * 又忘记删东西导致无法运行,已修复
82
+
83
+ ### 2023/1/16 \[v0.2.3]
84
+
85
+ * 最低python版本兼容至3.8
86
+
87
+ ### 2023/1/15 \[v0.2.2]
88
+
89
+ * 优化多bot逻辑,机器人qq号配置改为可选
90
+
91
+ ### 2023/1/15 \[v0.2.1]
92
+
93
+ * 插件重构
@@ -0,0 +1,188 @@
1
+ from re import findall
2
+ from mcstatus import BedrockServer, JavaServer
3
+ from nonebot import on_command, on_regex
4
+ from nonebot.adapters.onebot.v11 import (
5
+ MessageSegment as MS,
6
+ Bot,
7
+ Message,
8
+ GroupMessageEvent,
9
+ MessageEvent,
10
+ )
11
+ from nonebot.log import logger
12
+ from nonebot.params import RegexGroup
13
+ from nonebot.plugin import PluginMetadata
14
+ from .config import var, pc, save_file
15
+ from asyncio import gather
16
+ from base64 import b64decode
17
+ from io import BytesIO
18
+ from typing import Union
19
+
20
+ __plugin_meta__ = PluginMetadata(
21
+ name="MC服务器查询插件",
22
+ description="如名",
23
+ usage=f"""插件命令如下:
24
+ 信息 # 字面意思,需要加命令前缀,默认/
25
+ 信息数据 # 查看已启用群以及服务器信息,需要加命令前缀,默认/
26
+ 添加服务器 # 字面意思
27
+ 删除服务器 # 字面意思
28
+ """,
29
+ )
30
+
31
+
32
+ async def group_check(event: GroupMessageEvent, bot: Bot) -> bool:
33
+ return event.group_id in var.group_list and bot == var.handle_bot
34
+
35
+
36
+ async def admin_check(event: MessageEvent, bot: Bot) -> bool:
37
+ return bot == var.handle_bot and event.user_id == pc.mc_status_admin_qqnum
38
+
39
+
40
+ xinxi = on_command("信息", rule=group_check)
41
+ list_all = on_command("信息数据", rule=admin_check)
42
+ add_server = on_regex(r"^添加服务器\s*((\d+)\s+(\S+)\s+(\S+)\s+(\S+))?", rule=admin_check)
43
+ del_server = on_regex(r"^删除服务器\s*((\d+)\s+(\S+))?", rule=admin_check)
44
+
45
+
46
+ @xinxi.handle()
47
+ async def handle_xinxi(event: GroupMessageEvent):
48
+ group = event.group_id
49
+ task_list = []
50
+ for server_name in var.group_list[group]:
51
+ server_host = var.group_list[group][server_name][0]
52
+ server_type = var.group_list[group][server_name][1]
53
+ task_list.append(
54
+ check_mc_status(
55
+ server_name,
56
+ server_host,
57
+ server_type,
58
+ )
59
+ )
60
+ result = await gather(*task_list)
61
+ count = 0
62
+ msg = ""
63
+ for r in result:
64
+ count += 1
65
+ if count > 1:
66
+ msg += "\n=== 分割线 ===\n"
67
+ msg += r
68
+ await xinxi.finish(msg)
69
+
70
+
71
+ @add_server.handle()
72
+ async def handle_add_server(matchgroup=RegexGroup()):
73
+ if not matchgroup[0]:
74
+ await add_server.finish(
75
+ f"添加服务器 [群号] [名称] [服务器地址] [类型]\n类型写js或bds,js是Java服务器,bds是基岩服务器\n服务器地址如果知道端口号把端口加上,否则查询速度会慢一点\n添加例子:\nexp1: 添加服务器 114514 哈皮咳嗽 mc.hypixel.net js\nexp2: 添加服务器 114514 某基岩服 mc.bds.net bds\nexp3: 添加服务器 114514 某Java服 mc.java.net:25577 js"
76
+ )
77
+ else:
78
+ group = int(matchgroup[1])
79
+ new_server_name = matchgroup[2]
80
+ server_host = matchgroup[3]
81
+ server_type = matchgroup[4].lower()
82
+
83
+ if server_type not in ["js", "bds"]:
84
+ await add_server.finish("类型请填js或bds")
85
+
86
+ if group not in var.group_list:
87
+ var.group_list[group] = {new_server_name: [server_host, server_type]}
88
+ else:
89
+ for server_name in var.group_list[group]:
90
+ if new_server_name == server_name:
91
+ await add_server.finish("有同名服务器啦!")
92
+ var.group_list[group][new_server_name] = [server_host, server_type]
93
+ save_file()
94
+ await add_server.finish("添加成功")
95
+
96
+
97
+ @del_server.handle()
98
+ async def handle_del_server(matchgroup=RegexGroup()):
99
+ if not matchgroup[0]:
100
+ await del_server.finish(f"删除服务器 [群号] [名称]")
101
+ else:
102
+ group = int(matchgroup[1])
103
+ name = matchgroup[2]
104
+
105
+ if group not in var.group_list:
106
+ await del_server.finish("这个群没有添加服务器")
107
+ else:
108
+ if name in var.group_list[group]:
109
+ var.group_list[group].pop(name)
110
+ if not var.group_list[group]:
111
+ var.group_list.pop(group)
112
+ save_file()
113
+ await del_server.finish("删除成功")
114
+ else:
115
+ await del_server.finish("没找到该名称的服务器")
116
+
117
+
118
+ @list_all.handle()
119
+ async def handle_list_all():
120
+ msg = ""
121
+ for group_id in var.group_list:
122
+ msg += f"群{group_id}服务器列表\n"
123
+ for server_name in var.group_list[group_id]:
124
+ server_host, server_type = var.group_list[group_id][server_name]
125
+ msg += f"{server_name} {server_host} {server_type}\n"
126
+ msg += "\n"
127
+ if not msg:
128
+ msg = "无数据"
129
+ await list_all.finish(f"mc_status数据\n{msg}")
130
+
131
+
132
+ async def check_mc_status(
133
+ name: str, host: str, server_type: str
134
+ ) -> Union[str, Message]:
135
+ try:
136
+ if server_type == "js":
137
+ js = await JavaServer.async_lookup(host, timeout=5)
138
+ status = js.status()
139
+ # if status.description.strip():
140
+ # print(f"des: {status.description}")
141
+ version_list = findall(r"\d+\.\d+(?:\.[\dxX]+)?", status.version.name)
142
+ if len(version_list) != 1:
143
+ version = f"{version_list[0]}-{version_list[-1]}"
144
+ else:
145
+ version = version_list[0]
146
+
147
+ online = f"{status.players.online}/{status.players.max}"
148
+ player_list = []
149
+ if status.players.online:
150
+ if status.players.sample:
151
+ player_list = [
152
+ p.name
153
+ for p in status.players.sample
154
+ if p.id != "00000000-0000-0000-0000-000000000000"
155
+ ]
156
+ if player_list:
157
+ player_list = ", ".join(player_list)
158
+ else:
159
+ player_list = "没返回玩家列表"
160
+ else:
161
+ player_list = "没人在线"
162
+ latency = round(status.latency)
163
+ # base64图标
164
+ if status.favicon:
165
+ aa, bb = status.favicon.split("base64,")
166
+ icon = MS.image(BytesIO(b64decode(bb))) + "\n"
167
+ else:
168
+ icon = ""
169
+ msg = (
170
+ icon
171
+ + f"名称:{name} 【{version}】\n在线:{online} 延迟:{latency}ms\n◤ {player_list} ◢"
172
+ )
173
+
174
+ else:
175
+ if host.find(":") != -1:
176
+ host, port = host.split(":")
177
+ else:
178
+ host, port = host, 19132
179
+ bds = BedrockServer(host=host, port=int(port))
180
+ status = await bds.async_status()
181
+ online = f"{status.players_online}/{status.players_max}"
182
+ latency = round(status.latency)
183
+ version = status.version.version
184
+ msg = f"名称:{name} 【{version}】\n在线:{online} 延迟:{latency}ms"
185
+ except Exception as e:
186
+ msg = f"名称:{name} 查询失败!\n错误:{repr(e)}"
187
+
188
+ return msg
@@ -0,0 +1,111 @@
1
+ from json import dump, load
2
+ from os import makedirs, path
3
+ from nonebot import get_driver, get_bot, get_bots
4
+ from nonebot.log import logger
5
+ from pydantic import BaseModel, Extra
6
+ from typing import List, Dict, Optional
7
+ from nonebot.adapters import Bot
8
+
9
+
10
+ class Config(BaseModel, extra=Extra.ignore):
11
+ # 管理员的QQ号(别问我为什么)
12
+ mc_status_admin_qqnum: int = 0 # 必填
13
+ # 机器人的QQ号(如果写了就按优先级响应,否则就第一个连上的响应) ['1234','5678','6666']
14
+ mc_status_bot_qqnum_list: List[str] = [] # 可选
15
+ # 数据文件名
16
+ mc_status_data_filename: str = "mc_status_data.json"
17
+
18
+
19
+ class Var:
20
+ # 处理消息的bot
21
+ handle_bot: Optional[Bot] = None
22
+ # {"123456": {"提肛": ["mc.hypixel.net:25565","java"]}}
23
+ group_list = {}
24
+
25
+
26
+ driver = get_driver()
27
+ global_config = driver.config
28
+ pc = Config.parse_obj(global_config)
29
+ var = Var()
30
+
31
+
32
+ @driver.on_startup
33
+ async def on_startup():
34
+ if not path.exists(f"data"):
35
+ makedirs(f"data")
36
+
37
+ if not path.exists(f"data/{pc.mc_status_data_filename}"):
38
+ save_file()
39
+ else:
40
+ load_file()
41
+
42
+
43
+ def load_file():
44
+ with open(f"data/{pc.mc_status_data_filename}", "r", encoding="utf-8") as r:
45
+ tmp_data = load(r)
46
+ for i in tmp_data:
47
+ var.group_list[int(i)] = tmp_data[i]
48
+
49
+
50
+ def save_file():
51
+ with open(f"data/{pc.mc_status_data_filename}", "w", encoding="utf-8") as w:
52
+ dump(var.group_list, w, indent=4, ensure_ascii=False)
53
+
54
+
55
+ # qq机器人连接时执行
56
+ @driver.on_bot_connect
57
+ async def on_bot_connect(bot: Bot):
58
+ # 是否有写bot qq,如果写了只处理bot qq在列表里的
59
+ if pc.mc_status_bot_qqnum_list and bot.self_id in pc.mc_status_bot_qqnum_list:
60
+ # 如果已经有bot连了
61
+ if var.handle_bot:
62
+ # 当前bot qq 下标
63
+ handle_bot_id_index = pc.mc_status_bot_qqnum_list.index(
64
+ var.handle_bot.self_id
65
+ )
66
+ # 新连接的bot qq 下标
67
+ new_bot_id_index = pc.mc_status_bot_qqnum_list.index(bot.self_id)
68
+ # 判断优先级,下标越低优先级越高
69
+ if new_bot_id_index < handle_bot_id_index:
70
+ var.handle_bot = bot
71
+
72
+ # 没bot连就直接给
73
+ else:
74
+ var.handle_bot = bot
75
+
76
+ # 不写就给第一个连的
77
+ elif not pc.mc_status_bot_qqnum_list and not var.handle_bot:
78
+ var.handle_bot = bot
79
+
80
+
81
+ # qq机器人断开时执行
82
+ @driver.on_bot_disconnect
83
+ async def on_bot_disconnect(bot: Bot):
84
+ # 判断掉线的是否为handle bot
85
+ if bot == var.handle_bot:
86
+ # 如果有写bot qq列表
87
+ if pc.mc_status_bot_qqnum_list:
88
+ # 获取当前连着的bot列表(需要bot是在bot qq列表里)
89
+ available_bot_id_list = [
90
+ bot_id for bot_id in get_bots() if bot_id in pc.mc_status_bot_qqnum_list
91
+ ]
92
+ if available_bot_id_list:
93
+ # 打擂台排序?
94
+ new_bot_index = pc.mc_status_bot_qqnum_list.index(available_bot_id_list[0])
95
+ for bot_id in available_bot_id_list:
96
+ now_bot_index = pc.mc_status_bot_qqnum_list.index(bot_id)
97
+ if now_bot_index < new_bot_index:
98
+ new_bot_index = now_bot_index
99
+ # 取下标在qq列表里最小的bot qq为新的handle bot
100
+ var.handle_bot = get_bot(pc.mc_status_bot_qqnum_list[new_bot_index])
101
+
102
+ else:
103
+ var.handle_bot = None
104
+
105
+ # 不写就随便给一个连着的(如果有)
106
+ elif var.handle_bot:
107
+ try:
108
+ new_bot = get_bot()
109
+ var.handle_bot = new_bot
110
+ except ValueError:
111
+ var.handle_bot = None
@@ -0,0 +1,21 @@
1
+ [tool.poetry]
2
+ name = "nonebot_plugin_mc_server_status"
3
+ version = "0.2.11"
4
+ description = "Nonebot2查询MC服务器在线信息插件"
5
+ authors = ["nikissXI <1299577815@qq.com>"]
6
+ license = "MIT"
7
+ readme = "README.md"
8
+ packages = [{include = "nonebot_plugin_mc_server_status"}]
9
+ homepage = "https://github.com/nikissXI/nonebot_plugins/tree/main/nonebot_plugin_mc_server_status"
10
+ repository = "https://github.com/nikissXI/nonebot_plugins/tree/main/nonebot_plugin_mc_server_status"
11
+ documentation = "https://github.com/nikissXI/nonebot_plugins/tree/main/nonebot_plugin_mc_server_status#README.md"
12
+
13
+ [tool.poetry.dependencies]
14
+ python = ">=3.8"
15
+ nonebot2 = ">=2.0.0rc1"
16
+ nonebot-adapter-onebot = ">=2.0.0"
17
+ mcstatus = ">=10.0.0"
18
+
19
+ [build-system]
20
+ requires = ["poetry-core"]
21
+ build-backend = "poetry.core.masonry.api"