插件主体部分
创建插件完成后, 可以开始编写插件主类。
python
from tooldelta import plugins, Plugin, ToolDelta
# 将插件注册进系统
@plugins.add_plugin
class NewPlugin(Plugin):
name = "插件名" # 必须设置插件名
author = "作者名" # 作者名, 可选
version = (0, 0, 1) # 插件版本号, 可选, 是一个三元整数元组
def __init__(self, frame: ToolDelta):
# 在此写插件配置文件的读取
# ...
# 就不需要处理可能发生配置文件的异常
# ToolDelta 会自动将报错转换为人类可读提示
super().__init__(frame)
def on_def(self):
# 在此写获取插件API (get_plugin_api) 方法,不用处理可能发生的异常
# 例如:
# 插件API接口 = plugin.get_plugin_api("插件API名")
pass
def on_inject(self):
# 会在 ToolDelta 初始化成功 (成功接入服务器) 后执行
print("已与游戏建立连接")
# 发送一条 Minecraft 指令 在游戏里说 hello
self.game_ctrl.sendcmd("/say hello everybody! tooldelta is ok!")
def on_player_message(self, player: str, msg: str):
# 在玩家发言后执行
self.game_ctrl.say_to(player, "你刚刚的发言是:" + msg)
def on_player_join(self, playername: str):
# 在玩家加入后执行
self.game_ctrl.say_to("@a", f"§a§l Hi, @{playername}")
def on_player_death(
self,
playername: str,
killer: str | None,
msg: str
):
# 在玩家死亡时执行
if killer is not None:
self.gamme_ctrl.say_to("@a", f"{playername} 被 {killer} 击败了")
else:
self.game_ctrl.say_to("@a", f"{playername} 死亡了")
def on_player_leave(self, playername: str):
# 在玩家退出游戏时执行
self.game_ctrl.say_to("@a", f"§a§l Bye, @{playername}")
@plugins.add_packet_listener(9)
def on_pkt(self, packet: dict):
# 接收游戏数据包
# 接收到 9 号数据包后执行
print(packet)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
插件主类里的特殊事件名方法
以上以 on_ 开头的方法属于 Plugin 类里的特殊方法:
在插件主类定义里,一部分特殊命名类方是ToolDelta的魔法方法,会在某些时候被传参和执行。
如下是对这些 “魔法方法” 的说明(这些方法必须是插件主类 Plugin
里的, 写在其他地方无效):
python
def __init__(self, frame)
1
- 这个方法会在插件被读取时执行
- 参数:
frame (ToolDelta): 这个参数会被传入ToolDelta框架, 以用于插件主类的frame
和game_ctrl
属性初始化(使用super().__init__(frame)
以初始化插件框架)。
python
def on_def(self)
1
- 这个方法会在所有插件被读取完毕、在连接游戏之前被执行
- 因为此时插件都已被读取完成,因此可在此处获取其他插件的 API (详见此处)
python
def on_inject(self)
1
- 这个方法会在 ToolDelta 初始化成功 (成功进入游戏服务器) 后执行
- 注意!这些函数都是堵塞式的,千万别在里面写
time.sleep
或者死循环,否则将会使得整个系统发生阻塞
python
def on_player_join(self, playername: str)
1
- 这个方法会在任意玩家进入服务器后被执行
- 参数:
playername (str): 进入的玩家名
python
def on_player_leave(self, playername: str)
1
- 这个方法会在任意玩家进入服务器后被执行
- 参数:
playername (str): 退出的玩家名
python
def on_player_message(self, playername: str, msg: str)
1
- 这个函数会在任意玩家发言后执行
- 参数:
playername (str): 发言的玩家名
msg (str): 玩家发言消息
python
@plugins.add_packet_listener(packet_id: int)
1
将下面的方法作为数据包监听器的装饰器,在接收到指定的数据包后执行下面的方法
在示例中,我们监听的是 9 号数据包 (聊天栏信息包: Text),
- 数据包英文ID对应数字ID可在 tooldelta/constants.py: PacketIDs 找到
装饰器参数:
packet_id (int): 数据包ID被装饰方法的参数:
packet (dict): 数据包包体信息被装饰方法的返回: (bool): 是否拦截此数据包, 不被系统和之后执行的方法捕获
python
def on_player_death(
self,
playername: str,
killer: str | None,
killmsg: str
)
1
2
3
4
5
6
2
3
4
5
6
- 这个方法在玩家死亡时执行
- 参数:
playername (str) :死亡的玩家名
killer (str | None):击杀者名, 没有则为 None killmsg (str):死亡消息, 通常是一个英文字符串, 表示死亡类型
现在你了解了插件主类的结构,可以进一步学习如何使用ToolDelta提供的众多方法来编写插件了!