nonebot-plugin-terralink 0.1.0__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.
- nonebot_plugin_terralink-0.1.0/PKG-INFO +382 -0
- nonebot_plugin_terralink-0.1.0/README.md +366 -0
- nonebot_plugin_terralink-0.1.0/nonebot_plugin_terralink/__init__.py +21 -0
- nonebot_plugin_terralink-0.1.0/nonebot_plugin_terralink/config.py +34 -0
- nonebot_plugin_terralink-0.1.0/nonebot_plugin_terralink.egg-info/PKG-INFO +382 -0
- nonebot_plugin_terralink-0.1.0/nonebot_plugin_terralink.egg-info/SOURCES.txt +9 -0
- nonebot_plugin_terralink-0.1.0/nonebot_plugin_terralink.egg-info/dependency_links.txt +1 -0
- nonebot_plugin_terralink-0.1.0/nonebot_plugin_terralink.egg-info/requires.txt +4 -0
- nonebot_plugin_terralink-0.1.0/nonebot_plugin_terralink.egg-info/top_level.txt +1 -0
- nonebot_plugin_terralink-0.1.0/pyproject.toml +28 -0
- nonebot_plugin_terralink-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nonebot-plugin-terralink
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: 实现泰拉瑞亚 TModLoader 服务器与 QQ 群双向互通的 NoneBot2 插件
|
|
5
|
+
Author-email: newcovid <280310454@qq.com>
|
|
6
|
+
License: GPL-3.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/newcovid/nonebot-plugin-terralink
|
|
8
|
+
Project-URL: Documentation, https://github.com/newcovid/nonebot-plugin-terralink#readme
|
|
9
|
+
Keywords: nonebot,terraria,tmodloader,bridge,server,websocket
|
|
10
|
+
Requires-Python: >=3.9
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
Requires-Dist: nonebot2>=2.3.0
|
|
13
|
+
Requires-Dist: nonebot-adapter-onebot>=2.3.0
|
|
14
|
+
Requires-Dist: websockets>=11.0
|
|
15
|
+
Requires-Dist: pydantic>=1.10.0
|
|
16
|
+
|
|
17
|
+
<div align="center">
|
|
18
|
+
<a href="https://v2.nonebot.dev/store"><img src="https://github.com/A-kirami/nonebot-plugin-template/blob/resources/nbp_logo.png" width="180" height="180" alt="NoneBotPluginLogo"></a>
|
|
19
|
+
<br>
|
|
20
|
+
<p><img src="https://github.com/A-kirami/nonebot-plugin-template/blob/resources/NoneBotPlugin.svg" width="240" alt="NoneBotPluginText"></p>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<div align="center">
|
|
24
|
+
|
|
25
|
+
# nonebot-plugin-terralink
|
|
26
|
+
|
|
27
|
+
_✨ 泰拉瑞亚 TModLoader 服务器与 QQ 群双向互通的 NoneBot2 插件 ✨_
|
|
28
|
+
|
|
29
|
+
<a href="./LICENSE">
|
|
30
|
+
<img src="https://img.shields.io/github/license/newcovid/nonebot-plugin-terralink.svg" alt="license">
|
|
31
|
+
</a>
|
|
32
|
+
<a href="https://pypi.python.org/pypi/nonebot-plugin-terralink">
|
|
33
|
+
<img src="https://img.shields.io/pypi/v/nonebot-plugin-terralink.svg" alt="pypi">
|
|
34
|
+
</a>
|
|
35
|
+
<img src="https://img.shields.io/badge/python-3.9+-blue.svg" alt="python">
|
|
36
|
+
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
## 📖 介绍
|
|
40
|
+
|
|
41
|
+
**TerraLink** 是一个 NoneBot2 插件,用于实现泰拉瑞亚 TModLoader 服务器与 QQ 群的双向互通。通过 WebSocket 协议连接 TML 模组客户端,将游戏内的聊天消息、事件通知同步到 QQ 群,同时支持从 QQ 群发送指令到游戏服务器进行管理操作。
|
|
42
|
+
|
|
43
|
+
### 核心特性
|
|
44
|
+
|
|
45
|
+
- 🔗 **双向通信**:游戏消息 ↔ QQ 群消息实时同步
|
|
46
|
+
- 🎮 **完整的指令系统**:支持 15+ 个服务器管理和查询指令
|
|
47
|
+
- 🔐 **安全的认证机制**:Token-based 鉴权系统
|
|
48
|
+
- 📱 **多服务器支持**:一个 Bot 可同时管理多个 TML 服务器,绑定到不同的 QQ 群
|
|
49
|
+
- ⚙️ **灵活的配置**:支持自定义端口、指令前缀、多服务器映射
|
|
50
|
+
- 🚀 **高效的异步架构**:基于 asyncio 和 websockets 的高性能实现
|
|
51
|
+
|
|
52
|
+
## 💿 安装
|
|
53
|
+
|
|
54
|
+
<details open>
|
|
55
|
+
<summary>使用 nb-cli 安装</summary>
|
|
56
|
+
|
|
57
|
+
在 nonebot2 项目的根目录下打开命令行,输入以下指令即可安装
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
nb plugin install nonebot-plugin-terralink
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
</details>
|
|
64
|
+
|
|
65
|
+
<details>
|
|
66
|
+
<summary>使用包管理器安装</summary>
|
|
67
|
+
|
|
68
|
+
在 nonebot2 项目的插件目录下,打开命令行,根据你使用的包管理器,输入相应的安装命令
|
|
69
|
+
|
|
70
|
+
<details>
|
|
71
|
+
<summary>pip</summary>
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pip install nonebot-plugin-terralink
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
</details>
|
|
78
|
+
|
|
79
|
+
<details>
|
|
80
|
+
<summary>pdm</summary>
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pdm add nonebot-plugin-terralink
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
</details>
|
|
87
|
+
|
|
88
|
+
<details>
|
|
89
|
+
<summary>poetry</summary>
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
poetry add nonebot-plugin-terralink
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
</details>
|
|
96
|
+
|
|
97
|
+
<details>
|
|
98
|
+
<summary>conda</summary>
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
conda install nonebot-plugin-terralink
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
</details>
|
|
105
|
+
|
|
106
|
+
</details>
|
|
107
|
+
|
|
108
|
+
## ⚙️ 配置
|
|
109
|
+
|
|
110
|
+
在 NoneBot 的 `.env` 或 `.env.prod` 文件中配置以下选项:
|
|
111
|
+
|
|
112
|
+
```env
|
|
113
|
+
# 插件总开关
|
|
114
|
+
terralink_enabled=true
|
|
115
|
+
|
|
116
|
+
# WebSocket 监听端口
|
|
117
|
+
terralink_port=7778
|
|
118
|
+
|
|
119
|
+
# 指令前缀 (用于识别指令消息)
|
|
120
|
+
terralink_cmd_prefix=/
|
|
121
|
+
|
|
122
|
+
# 多服务器映射列表 (JSON 格式)
|
|
123
|
+
terralink_links=[
|
|
124
|
+
{"token": "server_survival", "group_id": 11111, "name": "生存服"},
|
|
125
|
+
{"token": "server_calamity", "group_id": 22222, "name": "灾厄服"}
|
|
126
|
+
]
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### 配置说明
|
|
130
|
+
|
|
131
|
+
| 配置项 | 类型 | 默认值 | 说明 |
|
|
132
|
+
| ---------------------- | ---------------- | ------ | ---------------------- |
|
|
133
|
+
| `terralink_enabled` | bool | `true` | 插件是否启用 |
|
|
134
|
+
| `terralink_port` | int | `7778` | WebSocket 服务监听端口 |
|
|
135
|
+
| `terralink_cmd_prefix` | str | `/` | 指令前缀符号 |
|
|
136
|
+
| `terralink_links` | List[LinkConfig] | `[]` | 服务器配置列表 |
|
|
137
|
+
|
|
138
|
+
### LinkConfig (服务器配置)
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
{
|
|
142
|
+
"token": str, # TML 端配置的 AccessToken (作为唯一识别码)
|
|
143
|
+
"group_id": int, # 绑定的 QQ 群号
|
|
144
|
+
"name": str # 服务器名称 (用于日志和消息前缀)
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## 🎮 使用指南
|
|
149
|
+
|
|
150
|
+
### 游戏方(TML 服务器)配置
|
|
151
|
+
|
|
152
|
+
1. 在 TML 服务器中安装 **TerraNoneBridge** 模组
|
|
153
|
+
2. 在模组配置中设置:
|
|
154
|
+
- 服务器地址:Bot 所在服务器的 IP 地址
|
|
155
|
+
- 端口号:与 `terralink_port` 配置一致(默认 7778)
|
|
156
|
+
- AccessToken:与 `terralink_links` 中对应的 token 一致
|
|
157
|
+
|
|
158
|
+
### QQ 群管理指令
|
|
159
|
+
|
|
160
|
+
#### 超级用户指令(管理指令)
|
|
161
|
+
|
|
162
|
+
只有超级用户 (SuperUser) 可以执行以下指令:
|
|
163
|
+
|
|
164
|
+
| 指令 | 用法 | 功能 |
|
|
165
|
+
| ---------- | ---------------------------------- | ---------------- |
|
|
166
|
+
| `/kick` | `/kick <玩家名> [原因]` | 踢出玩家 |
|
|
167
|
+
| `/butcher` | `/butcher` | 清理所有敌对生物 |
|
|
168
|
+
| `/give` | `/give <玩家> <物品名> [数量]` | 给予玩家物品 |
|
|
169
|
+
| `/buff` | `/buff <玩家/all> <Buff名> [秒数]` | 给玩家添加 Buff |
|
|
170
|
+
| `/save` | `/save` | 强制保存世界存档 |
|
|
171
|
+
| `/settle` | `/settle` | 强制沉降所有液体 |
|
|
172
|
+
| `/time` | `/time <dawn/noon/dusk/midnight>` | 修改世界时间 |
|
|
173
|
+
| `/cmd` | `/cmd <指令> [参数]` | 原生指令透传 |
|
|
174
|
+
|
|
175
|
+
#### 普通用户指令(查询指令)
|
|
176
|
+
|
|
177
|
+
所有群成员都可以执行以下指令:
|
|
178
|
+
|
|
179
|
+
| 指令 | 别名 | 用法 | 功能 |
|
|
180
|
+
| --------- | ----------------- | -------------------- | -------------------- |
|
|
181
|
+
| `/help` | 帮助, 菜单 | `/help` | 查看指令列表 |
|
|
182
|
+
| `/list` | 在线, who, ls | `/list` | 查看在线玩家列表 |
|
|
183
|
+
| `/tps` | status, 性能 | `/tps` | 查看服务器性能数据 |
|
|
184
|
+
| `/boss` | bosses, 进度 | `/boss` | 查看已击败 Boss 列表 |
|
|
185
|
+
| `/inv` | inventory, 查背包 | `/inv <玩家名>` | 查看玩家背包 |
|
|
186
|
+
| `/search` | 搜索, 查找 | `/search <关键词>` | 搜索物品 |
|
|
187
|
+
| `/query` | 查询, 合成 | `/query <物品名/ID>` | 查询物品属性和合成表 |
|
|
188
|
+
|
|
189
|
+
### 聊天同步
|
|
190
|
+
|
|
191
|
+
- 玩家在游戏内发送的聊天消息会自动转发到绑定的 QQ 群
|
|
192
|
+
- QQ 群内的文本消息会转发到游戏内(格式:`<昵称> 消息内容`)
|
|
193
|
+
- 指令消息(以 `/`、`#`、`.` 开头)不会被转发
|
|
194
|
+
|
|
195
|
+
## 🔌 协议细节
|
|
196
|
+
|
|
197
|
+
### WebSocket 连接流程
|
|
198
|
+
|
|
199
|
+
1. **建立连接**:TML 客户端连接到 `ws://<bot-ip>:<port>`
|
|
200
|
+
|
|
201
|
+
2. **鉴权阶段**:
|
|
202
|
+
```json
|
|
203
|
+
// 客户端 -> 服务器
|
|
204
|
+
{
|
|
205
|
+
"type": "auth",
|
|
206
|
+
"token": "server_survival",
|
|
207
|
+
"timestamp": 1678888888
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// 服务器 -> 客户端 (成功)
|
|
211
|
+
{
|
|
212
|
+
"type": "auth_response",
|
|
213
|
+
"success": true,
|
|
214
|
+
"message": "Authentication Successful!",
|
|
215
|
+
"timestamp": 1678888890
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
3. **数据交换**:鉴权成功后即可进行双向数据传输
|
|
220
|
+
|
|
221
|
+
### 数据包格式
|
|
222
|
+
|
|
223
|
+
#### 聊天消息 (Chat)
|
|
224
|
+
|
|
225
|
+
```json
|
|
226
|
+
{
|
|
227
|
+
"type": "chat",
|
|
228
|
+
"user_name": "玩家名/System",
|
|
229
|
+
"message": "消息内容",
|
|
230
|
+
"color": "FFFFFF",
|
|
231
|
+
"timestamp": 1678888888
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
#### 系统事件 (Event)
|
|
236
|
+
|
|
237
|
+
```json
|
|
238
|
+
{
|
|
239
|
+
"type": "event",
|
|
240
|
+
"event_type": "boss_spawn",
|
|
241
|
+
"world_name": "My World",
|
|
242
|
+
"motd": "Boss Eye of Cthulhu has appeared!",
|
|
243
|
+
"timestamp": 1678889000
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
支持的事件类型:
|
|
248
|
+
- `server_ready` - 连接就绪
|
|
249
|
+
- `world_load` - 世界加载完成
|
|
250
|
+
- `world_unload` - 世界卸载/服务器关闭
|
|
251
|
+
- `boss_spawn` - Boss 生成
|
|
252
|
+
- `boss_kill` - Boss 被击败
|
|
253
|
+
|
|
254
|
+
#### 执行指令 (Command)
|
|
255
|
+
|
|
256
|
+
```json
|
|
257
|
+
{
|
|
258
|
+
"type": "command",
|
|
259
|
+
"command": "give",
|
|
260
|
+
"args": ["PlayerName", "Zenith", "1"],
|
|
261
|
+
"timestamp": 1678888888
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## 📂 项目结构
|
|
266
|
+
|
|
267
|
+
```
|
|
268
|
+
nonebot_plugin_terralink/
|
|
269
|
+
├── __init__.py # 插件入口和元数据
|
|
270
|
+
├── config.py # 配置模型定义
|
|
271
|
+
├── core/
|
|
272
|
+
│ ├── connection.py # WebSocket 连接管理
|
|
273
|
+
│ ├── models.py # 数据包模型
|
|
274
|
+
│ └── server.py # WebSocket 服务器
|
|
275
|
+
├── matchers/
|
|
276
|
+
│ ├── admin.py # 超级用户管理指令
|
|
277
|
+
│ ├── chat.py # 聊天转发处理
|
|
278
|
+
│ └── query.py # 查询指令处理
|
|
279
|
+
└── services/
|
|
280
|
+
└── bridge.py # 业务逻辑层(消息转发和处理)
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## 🔧 架构设计
|
|
284
|
+
|
|
285
|
+
### 核心模块
|
|
286
|
+
|
|
287
|
+
- **Server** (`core/server.py`):WebSocket 服务器,处理 TML 客户端连接和断开
|
|
288
|
+
- **Connection** (`core/connection.py`):连接会话管理,维护 TML 连接状态和群绑定关系
|
|
289
|
+
- **Models** (`core/models.py`):数据包的 Pydantic 模型定义
|
|
290
|
+
- **Bridge** (`services/bridge.py`):业务逻辑层,处理数据包转发和 QQ 消息发送
|
|
291
|
+
|
|
292
|
+
### 关键特性
|
|
293
|
+
|
|
294
|
+
1. **多服务器支持**:通过 Token-based 认证和 Group-based 映射实现多服务器同时管理
|
|
295
|
+
2. **会话管理**:SessionManager 维护所有 TML 连接的状态和群绑定信息
|
|
296
|
+
3. **异步架构**:使用 asyncio 和 websockets 实现高效的并发处理
|
|
297
|
+
4. **错误恢复**:自动处理连接异常,提供重连机制
|
|
298
|
+
|
|
299
|
+
## ⚠️ 注意事项
|
|
300
|
+
|
|
301
|
+
1. **网络配置**:确保 Bot 运行的主机和 TML 服务器之间网络通畅
|
|
302
|
+
2. **防火墙配置**:需要开放 WebSocket 端口(默认 7778)
|
|
303
|
+
3. **Token 安全**:不要泄露 AccessToken,建议在生产环境中使用强随机 Token
|
|
304
|
+
4. **群号配置**:确保 `group_id` 与实际 QQ 群号一致
|
|
305
|
+
5. **鉴权机制**:TML 客户端必须先发送鉴权请求,否则其他消息会被丢弃
|
|
306
|
+
|
|
307
|
+
## 🐛 故障排除
|
|
308
|
+
|
|
309
|
+
### 常见问题
|
|
310
|
+
|
|
311
|
+
**Q: 连接后无法收到游戏消息**
|
|
312
|
+
- A: 检查 TML 端配置的 Token 是否与 `terralink_links` 中的 token 一致
|
|
313
|
+
- 检查网络连接是否畅通
|
|
314
|
+
- 查看 NoneBot 日志是否有错误信息
|
|
315
|
+
|
|
316
|
+
**Q: 指令发送后没有回显**
|
|
317
|
+
- A: 确认当前群已绑定服务器且服务器连接状态正常
|
|
318
|
+
- 检查是否有相应的权限(部分指令需要超级用户权限)
|
|
319
|
+
- 查看 TML 服务器的日志
|
|
320
|
+
|
|
321
|
+
**Q: WebSocket 端口被占用**
|
|
322
|
+
- A: 修改 `terralink_port` 配置为其他未使用的端口
|
|
323
|
+
- 或关闭占用该端口的其他进程
|
|
324
|
+
|
|
325
|
+
**Q: 鉴权失败**
|
|
326
|
+
- A: 检查 Token 是否正确且未包含特殊字符
|
|
327
|
+
- 确认服务器配置中的 Token 与客户端发送的 Token 一致
|
|
328
|
+
|
|
329
|
+
## 📝 开发信息
|
|
330
|
+
|
|
331
|
+
### 依赖项
|
|
332
|
+
|
|
333
|
+
- `nonebot2 >= 2.3.0`
|
|
334
|
+
- `nonebot-adapter-onebot >= 2.3.0`
|
|
335
|
+
- `websockets >= 11.0`
|
|
336
|
+
- `pydantic >= 1.10.0`
|
|
337
|
+
|
|
338
|
+
### Python 版本要求
|
|
339
|
+
|
|
340
|
+
- Python >= 3.9
|
|
341
|
+
|
|
342
|
+
### 许可证
|
|
343
|
+
|
|
344
|
+
GPL-3.0
|
|
345
|
+
|
|
346
|
+
### 作者
|
|
347
|
+
|
|
348
|
+
- **newcovid** <280310454@qq.com>
|
|
349
|
+
|
|
350
|
+
### 项目链接
|
|
351
|
+
|
|
352
|
+
- GitHub: https://github.com/newcovid/nonebot-plugin-terralink
|
|
353
|
+
- PyPI: https://pypi.org/project/nonebot-plugin-terralink/
|
|
354
|
+
|
|
355
|
+
## 📚 相关文档
|
|
356
|
+
|
|
357
|
+
- [NoneBot2 官方文档](https://v2.nonebot.dev/)
|
|
358
|
+
- [OneBot 适配器文档](https://adapter.onebot.dev/)
|
|
359
|
+
- [WebSocket 协议详细说明](./TerraNoneBridge通信文档.md)
|
|
360
|
+
|
|
361
|
+
## 🎯 未来计划
|
|
362
|
+
|
|
363
|
+
- [ ] 支持更多的服务器查询功能
|
|
364
|
+
- [ ] 添加数据库支持以记录历史消息
|
|
365
|
+
- [ ] 实现玩家排行榜功能
|
|
366
|
+
- [ ] 增加消息过滤和关键词拦截功能
|
|
367
|
+
- [ ] Web 管理后台界面
|
|
368
|
+
|
|
369
|
+
## 💬 反馈与支持
|
|
370
|
+
|
|
371
|
+
如有任何问题或建议,欢迎通过以下方式联系:
|
|
372
|
+
|
|
373
|
+
- 在 GitHub 上提交 [Issue](https://github.com/newcovid/nonebot-plugin-terralink/issues)
|
|
374
|
+
- 提交 [Pull Request](https://github.com/newcovid/nonebot-plugin-terralink/pulls) 贡献代码
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
<div align="center">
|
|
379
|
+
|
|
380
|
+
Made with ❤️ by newcovid
|
|
381
|
+
|
|
382
|
+
</div>
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<a href="https://v2.nonebot.dev/store"><img src="https://github.com/A-kirami/nonebot-plugin-template/blob/resources/nbp_logo.png" width="180" height="180" alt="NoneBotPluginLogo"></a>
|
|
3
|
+
<br>
|
|
4
|
+
<p><img src="https://github.com/A-kirami/nonebot-plugin-template/blob/resources/NoneBotPlugin.svg" width="240" alt="NoneBotPluginText"></p>
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
<div align="center">
|
|
8
|
+
|
|
9
|
+
# nonebot-plugin-terralink
|
|
10
|
+
|
|
11
|
+
_✨ 泰拉瑞亚 TModLoader 服务器与 QQ 群双向互通的 NoneBot2 插件 ✨_
|
|
12
|
+
|
|
13
|
+
<a href="./LICENSE">
|
|
14
|
+
<img src="https://img.shields.io/github/license/newcovid/nonebot-plugin-terralink.svg" alt="license">
|
|
15
|
+
</a>
|
|
16
|
+
<a href="https://pypi.python.org/pypi/nonebot-plugin-terralink">
|
|
17
|
+
<img src="https://img.shields.io/pypi/v/nonebot-plugin-terralink.svg" alt="pypi">
|
|
18
|
+
</a>
|
|
19
|
+
<img src="https://img.shields.io/badge/python-3.9+-blue.svg" alt="python">
|
|
20
|
+
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
## 📖 介绍
|
|
24
|
+
|
|
25
|
+
**TerraLink** 是一个 NoneBot2 插件,用于实现泰拉瑞亚 TModLoader 服务器与 QQ 群的双向互通。通过 WebSocket 协议连接 TML 模组客户端,将游戏内的聊天消息、事件通知同步到 QQ 群,同时支持从 QQ 群发送指令到游戏服务器进行管理操作。
|
|
26
|
+
|
|
27
|
+
### 核心特性
|
|
28
|
+
|
|
29
|
+
- 🔗 **双向通信**:游戏消息 ↔ QQ 群消息实时同步
|
|
30
|
+
- 🎮 **完整的指令系统**:支持 15+ 个服务器管理和查询指令
|
|
31
|
+
- 🔐 **安全的认证机制**:Token-based 鉴权系统
|
|
32
|
+
- 📱 **多服务器支持**:一个 Bot 可同时管理多个 TML 服务器,绑定到不同的 QQ 群
|
|
33
|
+
- ⚙️ **灵活的配置**:支持自定义端口、指令前缀、多服务器映射
|
|
34
|
+
- 🚀 **高效的异步架构**:基于 asyncio 和 websockets 的高性能实现
|
|
35
|
+
|
|
36
|
+
## 💿 安装
|
|
37
|
+
|
|
38
|
+
<details open>
|
|
39
|
+
<summary>使用 nb-cli 安装</summary>
|
|
40
|
+
|
|
41
|
+
在 nonebot2 项目的根目录下打开命令行,输入以下指令即可安装
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
nb plugin install nonebot-plugin-terralink
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
</details>
|
|
48
|
+
|
|
49
|
+
<details>
|
|
50
|
+
<summary>使用包管理器安装</summary>
|
|
51
|
+
|
|
52
|
+
在 nonebot2 项目的插件目录下,打开命令行,根据你使用的包管理器,输入相应的安装命令
|
|
53
|
+
|
|
54
|
+
<details>
|
|
55
|
+
<summary>pip</summary>
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pip install nonebot-plugin-terralink
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
</details>
|
|
62
|
+
|
|
63
|
+
<details>
|
|
64
|
+
<summary>pdm</summary>
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pdm add nonebot-plugin-terralink
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
</details>
|
|
71
|
+
|
|
72
|
+
<details>
|
|
73
|
+
<summary>poetry</summary>
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
poetry add nonebot-plugin-terralink
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
</details>
|
|
80
|
+
|
|
81
|
+
<details>
|
|
82
|
+
<summary>conda</summary>
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
conda install nonebot-plugin-terralink
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
</details>
|
|
89
|
+
|
|
90
|
+
</details>
|
|
91
|
+
|
|
92
|
+
## ⚙️ 配置
|
|
93
|
+
|
|
94
|
+
在 NoneBot 的 `.env` 或 `.env.prod` 文件中配置以下选项:
|
|
95
|
+
|
|
96
|
+
```env
|
|
97
|
+
# 插件总开关
|
|
98
|
+
terralink_enabled=true
|
|
99
|
+
|
|
100
|
+
# WebSocket 监听端口
|
|
101
|
+
terralink_port=7778
|
|
102
|
+
|
|
103
|
+
# 指令前缀 (用于识别指令消息)
|
|
104
|
+
terralink_cmd_prefix=/
|
|
105
|
+
|
|
106
|
+
# 多服务器映射列表 (JSON 格式)
|
|
107
|
+
terralink_links=[
|
|
108
|
+
{"token": "server_survival", "group_id": 11111, "name": "生存服"},
|
|
109
|
+
{"token": "server_calamity", "group_id": 22222, "name": "灾厄服"}
|
|
110
|
+
]
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 配置说明
|
|
114
|
+
|
|
115
|
+
| 配置项 | 类型 | 默认值 | 说明 |
|
|
116
|
+
| ---------------------- | ---------------- | ------ | ---------------------- |
|
|
117
|
+
| `terralink_enabled` | bool | `true` | 插件是否启用 |
|
|
118
|
+
| `terralink_port` | int | `7778` | WebSocket 服务监听端口 |
|
|
119
|
+
| `terralink_cmd_prefix` | str | `/` | 指令前缀符号 |
|
|
120
|
+
| `terralink_links` | List[LinkConfig] | `[]` | 服务器配置列表 |
|
|
121
|
+
|
|
122
|
+
### LinkConfig (服务器配置)
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
{
|
|
126
|
+
"token": str, # TML 端配置的 AccessToken (作为唯一识别码)
|
|
127
|
+
"group_id": int, # 绑定的 QQ 群号
|
|
128
|
+
"name": str # 服务器名称 (用于日志和消息前缀)
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## 🎮 使用指南
|
|
133
|
+
|
|
134
|
+
### 游戏方(TML 服务器)配置
|
|
135
|
+
|
|
136
|
+
1. 在 TML 服务器中安装 **TerraNoneBridge** 模组
|
|
137
|
+
2. 在模组配置中设置:
|
|
138
|
+
- 服务器地址:Bot 所在服务器的 IP 地址
|
|
139
|
+
- 端口号:与 `terralink_port` 配置一致(默认 7778)
|
|
140
|
+
- AccessToken:与 `terralink_links` 中对应的 token 一致
|
|
141
|
+
|
|
142
|
+
### QQ 群管理指令
|
|
143
|
+
|
|
144
|
+
#### 超级用户指令(管理指令)
|
|
145
|
+
|
|
146
|
+
只有超级用户 (SuperUser) 可以执行以下指令:
|
|
147
|
+
|
|
148
|
+
| 指令 | 用法 | 功能 |
|
|
149
|
+
| ---------- | ---------------------------------- | ---------------- |
|
|
150
|
+
| `/kick` | `/kick <玩家名> [原因]` | 踢出玩家 |
|
|
151
|
+
| `/butcher` | `/butcher` | 清理所有敌对生物 |
|
|
152
|
+
| `/give` | `/give <玩家> <物品名> [数量]` | 给予玩家物品 |
|
|
153
|
+
| `/buff` | `/buff <玩家/all> <Buff名> [秒数]` | 给玩家添加 Buff |
|
|
154
|
+
| `/save` | `/save` | 强制保存世界存档 |
|
|
155
|
+
| `/settle` | `/settle` | 强制沉降所有液体 |
|
|
156
|
+
| `/time` | `/time <dawn/noon/dusk/midnight>` | 修改世界时间 |
|
|
157
|
+
| `/cmd` | `/cmd <指令> [参数]` | 原生指令透传 |
|
|
158
|
+
|
|
159
|
+
#### 普通用户指令(查询指令)
|
|
160
|
+
|
|
161
|
+
所有群成员都可以执行以下指令:
|
|
162
|
+
|
|
163
|
+
| 指令 | 别名 | 用法 | 功能 |
|
|
164
|
+
| --------- | ----------------- | -------------------- | -------------------- |
|
|
165
|
+
| `/help` | 帮助, 菜单 | `/help` | 查看指令列表 |
|
|
166
|
+
| `/list` | 在线, who, ls | `/list` | 查看在线玩家列表 |
|
|
167
|
+
| `/tps` | status, 性能 | `/tps` | 查看服务器性能数据 |
|
|
168
|
+
| `/boss` | bosses, 进度 | `/boss` | 查看已击败 Boss 列表 |
|
|
169
|
+
| `/inv` | inventory, 查背包 | `/inv <玩家名>` | 查看玩家背包 |
|
|
170
|
+
| `/search` | 搜索, 查找 | `/search <关键词>` | 搜索物品 |
|
|
171
|
+
| `/query` | 查询, 合成 | `/query <物品名/ID>` | 查询物品属性和合成表 |
|
|
172
|
+
|
|
173
|
+
### 聊天同步
|
|
174
|
+
|
|
175
|
+
- 玩家在游戏内发送的聊天消息会自动转发到绑定的 QQ 群
|
|
176
|
+
- QQ 群内的文本消息会转发到游戏内(格式:`<昵称> 消息内容`)
|
|
177
|
+
- 指令消息(以 `/`、`#`、`.` 开头)不会被转发
|
|
178
|
+
|
|
179
|
+
## 🔌 协议细节
|
|
180
|
+
|
|
181
|
+
### WebSocket 连接流程
|
|
182
|
+
|
|
183
|
+
1. **建立连接**:TML 客户端连接到 `ws://<bot-ip>:<port>`
|
|
184
|
+
|
|
185
|
+
2. **鉴权阶段**:
|
|
186
|
+
```json
|
|
187
|
+
// 客户端 -> 服务器
|
|
188
|
+
{
|
|
189
|
+
"type": "auth",
|
|
190
|
+
"token": "server_survival",
|
|
191
|
+
"timestamp": 1678888888
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// 服务器 -> 客户端 (成功)
|
|
195
|
+
{
|
|
196
|
+
"type": "auth_response",
|
|
197
|
+
"success": true,
|
|
198
|
+
"message": "Authentication Successful!",
|
|
199
|
+
"timestamp": 1678888890
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
3. **数据交换**:鉴权成功后即可进行双向数据传输
|
|
204
|
+
|
|
205
|
+
### 数据包格式
|
|
206
|
+
|
|
207
|
+
#### 聊天消息 (Chat)
|
|
208
|
+
|
|
209
|
+
```json
|
|
210
|
+
{
|
|
211
|
+
"type": "chat",
|
|
212
|
+
"user_name": "玩家名/System",
|
|
213
|
+
"message": "消息内容",
|
|
214
|
+
"color": "FFFFFF",
|
|
215
|
+
"timestamp": 1678888888
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
#### 系统事件 (Event)
|
|
220
|
+
|
|
221
|
+
```json
|
|
222
|
+
{
|
|
223
|
+
"type": "event",
|
|
224
|
+
"event_type": "boss_spawn",
|
|
225
|
+
"world_name": "My World",
|
|
226
|
+
"motd": "Boss Eye of Cthulhu has appeared!",
|
|
227
|
+
"timestamp": 1678889000
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
支持的事件类型:
|
|
232
|
+
- `server_ready` - 连接就绪
|
|
233
|
+
- `world_load` - 世界加载完成
|
|
234
|
+
- `world_unload` - 世界卸载/服务器关闭
|
|
235
|
+
- `boss_spawn` - Boss 生成
|
|
236
|
+
- `boss_kill` - Boss 被击败
|
|
237
|
+
|
|
238
|
+
#### 执行指令 (Command)
|
|
239
|
+
|
|
240
|
+
```json
|
|
241
|
+
{
|
|
242
|
+
"type": "command",
|
|
243
|
+
"command": "give",
|
|
244
|
+
"args": ["PlayerName", "Zenith", "1"],
|
|
245
|
+
"timestamp": 1678888888
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## 📂 项目结构
|
|
250
|
+
|
|
251
|
+
```
|
|
252
|
+
nonebot_plugin_terralink/
|
|
253
|
+
├── __init__.py # 插件入口和元数据
|
|
254
|
+
├── config.py # 配置模型定义
|
|
255
|
+
├── core/
|
|
256
|
+
│ ├── connection.py # WebSocket 连接管理
|
|
257
|
+
│ ├── models.py # 数据包模型
|
|
258
|
+
│ └── server.py # WebSocket 服务器
|
|
259
|
+
├── matchers/
|
|
260
|
+
│ ├── admin.py # 超级用户管理指令
|
|
261
|
+
│ ├── chat.py # 聊天转发处理
|
|
262
|
+
│ └── query.py # 查询指令处理
|
|
263
|
+
└── services/
|
|
264
|
+
└── bridge.py # 业务逻辑层(消息转发和处理)
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## 🔧 架构设计
|
|
268
|
+
|
|
269
|
+
### 核心模块
|
|
270
|
+
|
|
271
|
+
- **Server** (`core/server.py`):WebSocket 服务器,处理 TML 客户端连接和断开
|
|
272
|
+
- **Connection** (`core/connection.py`):连接会话管理,维护 TML 连接状态和群绑定关系
|
|
273
|
+
- **Models** (`core/models.py`):数据包的 Pydantic 模型定义
|
|
274
|
+
- **Bridge** (`services/bridge.py`):业务逻辑层,处理数据包转发和 QQ 消息发送
|
|
275
|
+
|
|
276
|
+
### 关键特性
|
|
277
|
+
|
|
278
|
+
1. **多服务器支持**:通过 Token-based 认证和 Group-based 映射实现多服务器同时管理
|
|
279
|
+
2. **会话管理**:SessionManager 维护所有 TML 连接的状态和群绑定信息
|
|
280
|
+
3. **异步架构**:使用 asyncio 和 websockets 实现高效的并发处理
|
|
281
|
+
4. **错误恢复**:自动处理连接异常,提供重连机制
|
|
282
|
+
|
|
283
|
+
## ⚠️ 注意事项
|
|
284
|
+
|
|
285
|
+
1. **网络配置**:确保 Bot 运行的主机和 TML 服务器之间网络通畅
|
|
286
|
+
2. **防火墙配置**:需要开放 WebSocket 端口(默认 7778)
|
|
287
|
+
3. **Token 安全**:不要泄露 AccessToken,建议在生产环境中使用强随机 Token
|
|
288
|
+
4. **群号配置**:确保 `group_id` 与实际 QQ 群号一致
|
|
289
|
+
5. **鉴权机制**:TML 客户端必须先发送鉴权请求,否则其他消息会被丢弃
|
|
290
|
+
|
|
291
|
+
## 🐛 故障排除
|
|
292
|
+
|
|
293
|
+
### 常见问题
|
|
294
|
+
|
|
295
|
+
**Q: 连接后无法收到游戏消息**
|
|
296
|
+
- A: 检查 TML 端配置的 Token 是否与 `terralink_links` 中的 token 一致
|
|
297
|
+
- 检查网络连接是否畅通
|
|
298
|
+
- 查看 NoneBot 日志是否有错误信息
|
|
299
|
+
|
|
300
|
+
**Q: 指令发送后没有回显**
|
|
301
|
+
- A: 确认当前群已绑定服务器且服务器连接状态正常
|
|
302
|
+
- 检查是否有相应的权限(部分指令需要超级用户权限)
|
|
303
|
+
- 查看 TML 服务器的日志
|
|
304
|
+
|
|
305
|
+
**Q: WebSocket 端口被占用**
|
|
306
|
+
- A: 修改 `terralink_port` 配置为其他未使用的端口
|
|
307
|
+
- 或关闭占用该端口的其他进程
|
|
308
|
+
|
|
309
|
+
**Q: 鉴权失败**
|
|
310
|
+
- A: 检查 Token 是否正确且未包含特殊字符
|
|
311
|
+
- 确认服务器配置中的 Token 与客户端发送的 Token 一致
|
|
312
|
+
|
|
313
|
+
## 📝 开发信息
|
|
314
|
+
|
|
315
|
+
### 依赖项
|
|
316
|
+
|
|
317
|
+
- `nonebot2 >= 2.3.0`
|
|
318
|
+
- `nonebot-adapter-onebot >= 2.3.0`
|
|
319
|
+
- `websockets >= 11.0`
|
|
320
|
+
- `pydantic >= 1.10.0`
|
|
321
|
+
|
|
322
|
+
### Python 版本要求
|
|
323
|
+
|
|
324
|
+
- Python >= 3.9
|
|
325
|
+
|
|
326
|
+
### 许可证
|
|
327
|
+
|
|
328
|
+
GPL-3.0
|
|
329
|
+
|
|
330
|
+
### 作者
|
|
331
|
+
|
|
332
|
+
- **newcovid** <280310454@qq.com>
|
|
333
|
+
|
|
334
|
+
### 项目链接
|
|
335
|
+
|
|
336
|
+
- GitHub: https://github.com/newcovid/nonebot-plugin-terralink
|
|
337
|
+
- PyPI: https://pypi.org/project/nonebot-plugin-terralink/
|
|
338
|
+
|
|
339
|
+
## 📚 相关文档
|
|
340
|
+
|
|
341
|
+
- [NoneBot2 官方文档](https://v2.nonebot.dev/)
|
|
342
|
+
- [OneBot 适配器文档](https://adapter.onebot.dev/)
|
|
343
|
+
- [WebSocket 协议详细说明](./TerraNoneBridge通信文档.md)
|
|
344
|
+
|
|
345
|
+
## 🎯 未来计划
|
|
346
|
+
|
|
347
|
+
- [ ] 支持更多的服务器查询功能
|
|
348
|
+
- [ ] 添加数据库支持以记录历史消息
|
|
349
|
+
- [ ] 实现玩家排行榜功能
|
|
350
|
+
- [ ] 增加消息过滤和关键词拦截功能
|
|
351
|
+
- [ ] Web 管理后台界面
|
|
352
|
+
|
|
353
|
+
## 💬 反馈与支持
|
|
354
|
+
|
|
355
|
+
如有任何问题或建议,欢迎通过以下方式联系:
|
|
356
|
+
|
|
357
|
+
- 在 GitHub 上提交 [Issue](https://github.com/newcovid/nonebot-plugin-terralink/issues)
|
|
358
|
+
- 提交 [Pull Request](https://github.com/newcovid/nonebot-plugin-terralink/pulls) 贡献代码
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
<div align="center">
|
|
363
|
+
|
|
364
|
+
Made with ❤️ by newcovid
|
|
365
|
+
|
|
366
|
+
</div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from nonebot.plugin import PluginMetadata
|
|
2
|
+
|
|
3
|
+
from .config import Config
|
|
4
|
+
|
|
5
|
+
# 导入 Server 以注册生命周期钩子
|
|
6
|
+
from .core import server
|
|
7
|
+
|
|
8
|
+
# 导入 Matchers 以注册指令和事件响应
|
|
9
|
+
from .matchers import admin, query, chat
|
|
10
|
+
|
|
11
|
+
__plugin_meta__ = PluginMetadata(
|
|
12
|
+
name="TerraLink",
|
|
13
|
+
description="泰拉瑞亚 TModLoader 群服互通插件",
|
|
14
|
+
usage=(
|
|
15
|
+
"【管理指令 (SuperUser)】\n"
|
|
16
|
+
"/kick, /butcher, /give, /buff, /save, /settle, /time, /cmd\n\n"
|
|
17
|
+
"【查询指令】\n"
|
|
18
|
+
"/list, /tps, /boss, /inv, /search, /query, /help"
|
|
19
|
+
),
|
|
20
|
+
config=Config,
|
|
21
|
+
)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from pydantic import BaseModel, Extra
|
|
2
|
+
from typing import List, Optional
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class LinkConfig(BaseModel):
|
|
6
|
+
"""
|
|
7
|
+
单组连接配置:定义一个 TML 服务器与一个 QQ 群的绑定关系
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# TML 端配置的 AccessToken,作为唯一识别码
|
|
11
|
+
token: str
|
|
12
|
+
# 绑定的 QQ 群号
|
|
13
|
+
group_id: int
|
|
14
|
+
# 服务器名称(用于日志和消息前缀区分)
|
|
15
|
+
name: str = "Terraria Server"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Config(BaseModel, extra=Extra.ignore):
|
|
19
|
+
# 插件总开关
|
|
20
|
+
terralink_enabled: bool = True
|
|
21
|
+
|
|
22
|
+
# WebSocket 监听端口 (所有 TML 客户端都连接到这个端口)
|
|
23
|
+
terralink_port: int = 7778
|
|
24
|
+
|
|
25
|
+
# [核心] 多服务器映射列表
|
|
26
|
+
# 示例:
|
|
27
|
+
# [
|
|
28
|
+
# {"token": "server_survival", "group_id": 11111, "name": "生存服"},
|
|
29
|
+
# {"token": "server_calamity", "group_id": 22222, "name": "灾厄服"}
|
|
30
|
+
# ]
|
|
31
|
+
terralink_links: List[LinkConfig] = []
|
|
32
|
+
|
|
33
|
+
# 指令前缀 (用于 QQ 发消息转为游戏指令的标识,如 /say)
|
|
34
|
+
terralink_cmd_prefix: str = "/"
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nonebot-plugin-terralink
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: 实现泰拉瑞亚 TModLoader 服务器与 QQ 群双向互通的 NoneBot2 插件
|
|
5
|
+
Author-email: newcovid <280310454@qq.com>
|
|
6
|
+
License: GPL-3.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/newcovid/nonebot-plugin-terralink
|
|
8
|
+
Project-URL: Documentation, https://github.com/newcovid/nonebot-plugin-terralink#readme
|
|
9
|
+
Keywords: nonebot,terraria,tmodloader,bridge,server,websocket
|
|
10
|
+
Requires-Python: >=3.9
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
Requires-Dist: nonebot2>=2.3.0
|
|
13
|
+
Requires-Dist: nonebot-adapter-onebot>=2.3.0
|
|
14
|
+
Requires-Dist: websockets>=11.0
|
|
15
|
+
Requires-Dist: pydantic>=1.10.0
|
|
16
|
+
|
|
17
|
+
<div align="center">
|
|
18
|
+
<a href="https://v2.nonebot.dev/store"><img src="https://github.com/A-kirami/nonebot-plugin-template/blob/resources/nbp_logo.png" width="180" height="180" alt="NoneBotPluginLogo"></a>
|
|
19
|
+
<br>
|
|
20
|
+
<p><img src="https://github.com/A-kirami/nonebot-plugin-template/blob/resources/NoneBotPlugin.svg" width="240" alt="NoneBotPluginText"></p>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<div align="center">
|
|
24
|
+
|
|
25
|
+
# nonebot-plugin-terralink
|
|
26
|
+
|
|
27
|
+
_✨ 泰拉瑞亚 TModLoader 服务器与 QQ 群双向互通的 NoneBot2 插件 ✨_
|
|
28
|
+
|
|
29
|
+
<a href="./LICENSE">
|
|
30
|
+
<img src="https://img.shields.io/github/license/newcovid/nonebot-plugin-terralink.svg" alt="license">
|
|
31
|
+
</a>
|
|
32
|
+
<a href="https://pypi.python.org/pypi/nonebot-plugin-terralink">
|
|
33
|
+
<img src="https://img.shields.io/pypi/v/nonebot-plugin-terralink.svg" alt="pypi">
|
|
34
|
+
</a>
|
|
35
|
+
<img src="https://img.shields.io/badge/python-3.9+-blue.svg" alt="python">
|
|
36
|
+
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
## 📖 介绍
|
|
40
|
+
|
|
41
|
+
**TerraLink** 是一个 NoneBot2 插件,用于实现泰拉瑞亚 TModLoader 服务器与 QQ 群的双向互通。通过 WebSocket 协议连接 TML 模组客户端,将游戏内的聊天消息、事件通知同步到 QQ 群,同时支持从 QQ 群发送指令到游戏服务器进行管理操作。
|
|
42
|
+
|
|
43
|
+
### 核心特性
|
|
44
|
+
|
|
45
|
+
- 🔗 **双向通信**:游戏消息 ↔ QQ 群消息实时同步
|
|
46
|
+
- 🎮 **完整的指令系统**:支持 15+ 个服务器管理和查询指令
|
|
47
|
+
- 🔐 **安全的认证机制**:Token-based 鉴权系统
|
|
48
|
+
- 📱 **多服务器支持**:一个 Bot 可同时管理多个 TML 服务器,绑定到不同的 QQ 群
|
|
49
|
+
- ⚙️ **灵活的配置**:支持自定义端口、指令前缀、多服务器映射
|
|
50
|
+
- 🚀 **高效的异步架构**:基于 asyncio 和 websockets 的高性能实现
|
|
51
|
+
|
|
52
|
+
## 💿 安装
|
|
53
|
+
|
|
54
|
+
<details open>
|
|
55
|
+
<summary>使用 nb-cli 安装</summary>
|
|
56
|
+
|
|
57
|
+
在 nonebot2 项目的根目录下打开命令行,输入以下指令即可安装
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
nb plugin install nonebot-plugin-terralink
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
</details>
|
|
64
|
+
|
|
65
|
+
<details>
|
|
66
|
+
<summary>使用包管理器安装</summary>
|
|
67
|
+
|
|
68
|
+
在 nonebot2 项目的插件目录下,打开命令行,根据你使用的包管理器,输入相应的安装命令
|
|
69
|
+
|
|
70
|
+
<details>
|
|
71
|
+
<summary>pip</summary>
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pip install nonebot-plugin-terralink
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
</details>
|
|
78
|
+
|
|
79
|
+
<details>
|
|
80
|
+
<summary>pdm</summary>
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pdm add nonebot-plugin-terralink
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
</details>
|
|
87
|
+
|
|
88
|
+
<details>
|
|
89
|
+
<summary>poetry</summary>
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
poetry add nonebot-plugin-terralink
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
</details>
|
|
96
|
+
|
|
97
|
+
<details>
|
|
98
|
+
<summary>conda</summary>
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
conda install nonebot-plugin-terralink
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
</details>
|
|
105
|
+
|
|
106
|
+
</details>
|
|
107
|
+
|
|
108
|
+
## ⚙️ 配置
|
|
109
|
+
|
|
110
|
+
在 NoneBot 的 `.env` 或 `.env.prod` 文件中配置以下选项:
|
|
111
|
+
|
|
112
|
+
```env
|
|
113
|
+
# 插件总开关
|
|
114
|
+
terralink_enabled=true
|
|
115
|
+
|
|
116
|
+
# WebSocket 监听端口
|
|
117
|
+
terralink_port=7778
|
|
118
|
+
|
|
119
|
+
# 指令前缀 (用于识别指令消息)
|
|
120
|
+
terralink_cmd_prefix=/
|
|
121
|
+
|
|
122
|
+
# 多服务器映射列表 (JSON 格式)
|
|
123
|
+
terralink_links=[
|
|
124
|
+
{"token": "server_survival", "group_id": 11111, "name": "生存服"},
|
|
125
|
+
{"token": "server_calamity", "group_id": 22222, "name": "灾厄服"}
|
|
126
|
+
]
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### 配置说明
|
|
130
|
+
|
|
131
|
+
| 配置项 | 类型 | 默认值 | 说明 |
|
|
132
|
+
| ---------------------- | ---------------- | ------ | ---------------------- |
|
|
133
|
+
| `terralink_enabled` | bool | `true` | 插件是否启用 |
|
|
134
|
+
| `terralink_port` | int | `7778` | WebSocket 服务监听端口 |
|
|
135
|
+
| `terralink_cmd_prefix` | str | `/` | 指令前缀符号 |
|
|
136
|
+
| `terralink_links` | List[LinkConfig] | `[]` | 服务器配置列表 |
|
|
137
|
+
|
|
138
|
+
### LinkConfig (服务器配置)
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
{
|
|
142
|
+
"token": str, # TML 端配置的 AccessToken (作为唯一识别码)
|
|
143
|
+
"group_id": int, # 绑定的 QQ 群号
|
|
144
|
+
"name": str # 服务器名称 (用于日志和消息前缀)
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## 🎮 使用指南
|
|
149
|
+
|
|
150
|
+
### 游戏方(TML 服务器)配置
|
|
151
|
+
|
|
152
|
+
1. 在 TML 服务器中安装 **TerraNoneBridge** 模组
|
|
153
|
+
2. 在模组配置中设置:
|
|
154
|
+
- 服务器地址:Bot 所在服务器的 IP 地址
|
|
155
|
+
- 端口号:与 `terralink_port` 配置一致(默认 7778)
|
|
156
|
+
- AccessToken:与 `terralink_links` 中对应的 token 一致
|
|
157
|
+
|
|
158
|
+
### QQ 群管理指令
|
|
159
|
+
|
|
160
|
+
#### 超级用户指令(管理指令)
|
|
161
|
+
|
|
162
|
+
只有超级用户 (SuperUser) 可以执行以下指令:
|
|
163
|
+
|
|
164
|
+
| 指令 | 用法 | 功能 |
|
|
165
|
+
| ---------- | ---------------------------------- | ---------------- |
|
|
166
|
+
| `/kick` | `/kick <玩家名> [原因]` | 踢出玩家 |
|
|
167
|
+
| `/butcher` | `/butcher` | 清理所有敌对生物 |
|
|
168
|
+
| `/give` | `/give <玩家> <物品名> [数量]` | 给予玩家物品 |
|
|
169
|
+
| `/buff` | `/buff <玩家/all> <Buff名> [秒数]` | 给玩家添加 Buff |
|
|
170
|
+
| `/save` | `/save` | 强制保存世界存档 |
|
|
171
|
+
| `/settle` | `/settle` | 强制沉降所有液体 |
|
|
172
|
+
| `/time` | `/time <dawn/noon/dusk/midnight>` | 修改世界时间 |
|
|
173
|
+
| `/cmd` | `/cmd <指令> [参数]` | 原生指令透传 |
|
|
174
|
+
|
|
175
|
+
#### 普通用户指令(查询指令)
|
|
176
|
+
|
|
177
|
+
所有群成员都可以执行以下指令:
|
|
178
|
+
|
|
179
|
+
| 指令 | 别名 | 用法 | 功能 |
|
|
180
|
+
| --------- | ----------------- | -------------------- | -------------------- |
|
|
181
|
+
| `/help` | 帮助, 菜单 | `/help` | 查看指令列表 |
|
|
182
|
+
| `/list` | 在线, who, ls | `/list` | 查看在线玩家列表 |
|
|
183
|
+
| `/tps` | status, 性能 | `/tps` | 查看服务器性能数据 |
|
|
184
|
+
| `/boss` | bosses, 进度 | `/boss` | 查看已击败 Boss 列表 |
|
|
185
|
+
| `/inv` | inventory, 查背包 | `/inv <玩家名>` | 查看玩家背包 |
|
|
186
|
+
| `/search` | 搜索, 查找 | `/search <关键词>` | 搜索物品 |
|
|
187
|
+
| `/query` | 查询, 合成 | `/query <物品名/ID>` | 查询物品属性和合成表 |
|
|
188
|
+
|
|
189
|
+
### 聊天同步
|
|
190
|
+
|
|
191
|
+
- 玩家在游戏内发送的聊天消息会自动转发到绑定的 QQ 群
|
|
192
|
+
- QQ 群内的文本消息会转发到游戏内(格式:`<昵称> 消息内容`)
|
|
193
|
+
- 指令消息(以 `/`、`#`、`.` 开头)不会被转发
|
|
194
|
+
|
|
195
|
+
## 🔌 协议细节
|
|
196
|
+
|
|
197
|
+
### WebSocket 连接流程
|
|
198
|
+
|
|
199
|
+
1. **建立连接**:TML 客户端连接到 `ws://<bot-ip>:<port>`
|
|
200
|
+
|
|
201
|
+
2. **鉴权阶段**:
|
|
202
|
+
```json
|
|
203
|
+
// 客户端 -> 服务器
|
|
204
|
+
{
|
|
205
|
+
"type": "auth",
|
|
206
|
+
"token": "server_survival",
|
|
207
|
+
"timestamp": 1678888888
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// 服务器 -> 客户端 (成功)
|
|
211
|
+
{
|
|
212
|
+
"type": "auth_response",
|
|
213
|
+
"success": true,
|
|
214
|
+
"message": "Authentication Successful!",
|
|
215
|
+
"timestamp": 1678888890
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
3. **数据交换**:鉴权成功后即可进行双向数据传输
|
|
220
|
+
|
|
221
|
+
### 数据包格式
|
|
222
|
+
|
|
223
|
+
#### 聊天消息 (Chat)
|
|
224
|
+
|
|
225
|
+
```json
|
|
226
|
+
{
|
|
227
|
+
"type": "chat",
|
|
228
|
+
"user_name": "玩家名/System",
|
|
229
|
+
"message": "消息内容",
|
|
230
|
+
"color": "FFFFFF",
|
|
231
|
+
"timestamp": 1678888888
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
#### 系统事件 (Event)
|
|
236
|
+
|
|
237
|
+
```json
|
|
238
|
+
{
|
|
239
|
+
"type": "event",
|
|
240
|
+
"event_type": "boss_spawn",
|
|
241
|
+
"world_name": "My World",
|
|
242
|
+
"motd": "Boss Eye of Cthulhu has appeared!",
|
|
243
|
+
"timestamp": 1678889000
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
支持的事件类型:
|
|
248
|
+
- `server_ready` - 连接就绪
|
|
249
|
+
- `world_load` - 世界加载完成
|
|
250
|
+
- `world_unload` - 世界卸载/服务器关闭
|
|
251
|
+
- `boss_spawn` - Boss 生成
|
|
252
|
+
- `boss_kill` - Boss 被击败
|
|
253
|
+
|
|
254
|
+
#### 执行指令 (Command)
|
|
255
|
+
|
|
256
|
+
```json
|
|
257
|
+
{
|
|
258
|
+
"type": "command",
|
|
259
|
+
"command": "give",
|
|
260
|
+
"args": ["PlayerName", "Zenith", "1"],
|
|
261
|
+
"timestamp": 1678888888
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## 📂 项目结构
|
|
266
|
+
|
|
267
|
+
```
|
|
268
|
+
nonebot_plugin_terralink/
|
|
269
|
+
├── __init__.py # 插件入口和元数据
|
|
270
|
+
├── config.py # 配置模型定义
|
|
271
|
+
├── core/
|
|
272
|
+
│ ├── connection.py # WebSocket 连接管理
|
|
273
|
+
│ ├── models.py # 数据包模型
|
|
274
|
+
│ └── server.py # WebSocket 服务器
|
|
275
|
+
├── matchers/
|
|
276
|
+
│ ├── admin.py # 超级用户管理指令
|
|
277
|
+
│ ├── chat.py # 聊天转发处理
|
|
278
|
+
│ └── query.py # 查询指令处理
|
|
279
|
+
└── services/
|
|
280
|
+
└── bridge.py # 业务逻辑层(消息转发和处理)
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## 🔧 架构设计
|
|
284
|
+
|
|
285
|
+
### 核心模块
|
|
286
|
+
|
|
287
|
+
- **Server** (`core/server.py`):WebSocket 服务器,处理 TML 客户端连接和断开
|
|
288
|
+
- **Connection** (`core/connection.py`):连接会话管理,维护 TML 连接状态和群绑定关系
|
|
289
|
+
- **Models** (`core/models.py`):数据包的 Pydantic 模型定义
|
|
290
|
+
- **Bridge** (`services/bridge.py`):业务逻辑层,处理数据包转发和 QQ 消息发送
|
|
291
|
+
|
|
292
|
+
### 关键特性
|
|
293
|
+
|
|
294
|
+
1. **多服务器支持**:通过 Token-based 认证和 Group-based 映射实现多服务器同时管理
|
|
295
|
+
2. **会话管理**:SessionManager 维护所有 TML 连接的状态和群绑定信息
|
|
296
|
+
3. **异步架构**:使用 asyncio 和 websockets 实现高效的并发处理
|
|
297
|
+
4. **错误恢复**:自动处理连接异常,提供重连机制
|
|
298
|
+
|
|
299
|
+
## ⚠️ 注意事项
|
|
300
|
+
|
|
301
|
+
1. **网络配置**:确保 Bot 运行的主机和 TML 服务器之间网络通畅
|
|
302
|
+
2. **防火墙配置**:需要开放 WebSocket 端口(默认 7778)
|
|
303
|
+
3. **Token 安全**:不要泄露 AccessToken,建议在生产环境中使用强随机 Token
|
|
304
|
+
4. **群号配置**:确保 `group_id` 与实际 QQ 群号一致
|
|
305
|
+
5. **鉴权机制**:TML 客户端必须先发送鉴权请求,否则其他消息会被丢弃
|
|
306
|
+
|
|
307
|
+
## 🐛 故障排除
|
|
308
|
+
|
|
309
|
+
### 常见问题
|
|
310
|
+
|
|
311
|
+
**Q: 连接后无法收到游戏消息**
|
|
312
|
+
- A: 检查 TML 端配置的 Token 是否与 `terralink_links` 中的 token 一致
|
|
313
|
+
- 检查网络连接是否畅通
|
|
314
|
+
- 查看 NoneBot 日志是否有错误信息
|
|
315
|
+
|
|
316
|
+
**Q: 指令发送后没有回显**
|
|
317
|
+
- A: 确认当前群已绑定服务器且服务器连接状态正常
|
|
318
|
+
- 检查是否有相应的权限(部分指令需要超级用户权限)
|
|
319
|
+
- 查看 TML 服务器的日志
|
|
320
|
+
|
|
321
|
+
**Q: WebSocket 端口被占用**
|
|
322
|
+
- A: 修改 `terralink_port` 配置为其他未使用的端口
|
|
323
|
+
- 或关闭占用该端口的其他进程
|
|
324
|
+
|
|
325
|
+
**Q: 鉴权失败**
|
|
326
|
+
- A: 检查 Token 是否正确且未包含特殊字符
|
|
327
|
+
- 确认服务器配置中的 Token 与客户端发送的 Token 一致
|
|
328
|
+
|
|
329
|
+
## 📝 开发信息
|
|
330
|
+
|
|
331
|
+
### 依赖项
|
|
332
|
+
|
|
333
|
+
- `nonebot2 >= 2.3.0`
|
|
334
|
+
- `nonebot-adapter-onebot >= 2.3.0`
|
|
335
|
+
- `websockets >= 11.0`
|
|
336
|
+
- `pydantic >= 1.10.0`
|
|
337
|
+
|
|
338
|
+
### Python 版本要求
|
|
339
|
+
|
|
340
|
+
- Python >= 3.9
|
|
341
|
+
|
|
342
|
+
### 许可证
|
|
343
|
+
|
|
344
|
+
GPL-3.0
|
|
345
|
+
|
|
346
|
+
### 作者
|
|
347
|
+
|
|
348
|
+
- **newcovid** <280310454@qq.com>
|
|
349
|
+
|
|
350
|
+
### 项目链接
|
|
351
|
+
|
|
352
|
+
- GitHub: https://github.com/newcovid/nonebot-plugin-terralink
|
|
353
|
+
- PyPI: https://pypi.org/project/nonebot-plugin-terralink/
|
|
354
|
+
|
|
355
|
+
## 📚 相关文档
|
|
356
|
+
|
|
357
|
+
- [NoneBot2 官方文档](https://v2.nonebot.dev/)
|
|
358
|
+
- [OneBot 适配器文档](https://adapter.onebot.dev/)
|
|
359
|
+
- [WebSocket 协议详细说明](./TerraNoneBridge通信文档.md)
|
|
360
|
+
|
|
361
|
+
## 🎯 未来计划
|
|
362
|
+
|
|
363
|
+
- [ ] 支持更多的服务器查询功能
|
|
364
|
+
- [ ] 添加数据库支持以记录历史消息
|
|
365
|
+
- [ ] 实现玩家排行榜功能
|
|
366
|
+
- [ ] 增加消息过滤和关键词拦截功能
|
|
367
|
+
- [ ] Web 管理后台界面
|
|
368
|
+
|
|
369
|
+
## 💬 反馈与支持
|
|
370
|
+
|
|
371
|
+
如有任何问题或建议,欢迎通过以下方式联系:
|
|
372
|
+
|
|
373
|
+
- 在 GitHub 上提交 [Issue](https://github.com/newcovid/nonebot-plugin-terralink/issues)
|
|
374
|
+
- 提交 [Pull Request](https://github.com/newcovid/nonebot-plugin-terralink/pulls) 贡献代码
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
<div align="center">
|
|
379
|
+
|
|
380
|
+
Made with ❤️ by newcovid
|
|
381
|
+
|
|
382
|
+
</div>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
nonebot_plugin_terralink/__init__.py
|
|
4
|
+
nonebot_plugin_terralink/config.py
|
|
5
|
+
nonebot_plugin_terralink.egg-info/PKG-INFO
|
|
6
|
+
nonebot_plugin_terralink.egg-info/SOURCES.txt
|
|
7
|
+
nonebot_plugin_terralink.egg-info/dependency_links.txt
|
|
8
|
+
nonebot_plugin_terralink.egg-info/requires.txt
|
|
9
|
+
nonebot_plugin_terralink.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
nonebot_plugin_terralink
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "nonebot-plugin-terralink"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "实现泰拉瑞亚 TModLoader 服务器与 QQ 群双向互通的 NoneBot2 插件"
|
|
5
|
+
authors = [
|
|
6
|
+
{ name = "newcovid", email = "280310454@qq.com" },
|
|
7
|
+
]
|
|
8
|
+
readme = "README.md"
|
|
9
|
+
requires-python = ">=3.9"
|
|
10
|
+
license = { text = "GPL-3.0" }
|
|
11
|
+
keywords = ["nonebot", "terraria", "tmodloader", "bridge", "server", "websocket"]
|
|
12
|
+
dependencies = [
|
|
13
|
+
"nonebot2>=2.3.0",
|
|
14
|
+
"nonebot-adapter-onebot>=2.3.0",
|
|
15
|
+
"websockets>=11.0",
|
|
16
|
+
"pydantic>=1.10.0"
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.urls]
|
|
20
|
+
Homepage = "https://github.com/newcovid/nonebot-plugin-terralink"
|
|
21
|
+
Documentation = "https://github.com/newcovid/nonebot-plugin-terralink#readme"
|
|
22
|
+
|
|
23
|
+
[build-system]
|
|
24
|
+
requires = ["setuptools"]
|
|
25
|
+
build-backend = "setuptools.build_meta"
|
|
26
|
+
|
|
27
|
+
[tool.setuptools]
|
|
28
|
+
packages = ["nonebot_plugin_terralink"]
|