注册指令
MSL 允许插件注册自定义指令,玩家可以在游戏中通过聊天或命令行触发这些指令。本章将详细介绍指令注册机制和使用方法。
指令概述
MSL 支持两种类型的自定义指令:
- 聊天指令:以
!开头,玩家在聊天中输入即可触发 - 命令指令:以
/开头,玩家执行命令时触发
基本用法
注册简单指令
使用 plugin_registerCommand 注册指令:
javascript
// 注册 !ping 指令
plugin_registerCommand("!ping", (player) => {
plugin_executeCommand(`say ${player} 请求了 ping!`);
});玩家在游戏中输入:
!ping服务器输出:
[Steve] 请求了 ping!指令格式
指令表达式格式:
<prefix><command> [参数...]prefix:指令前缀,必须是!或/command:指令名称参数:可选参数,使用<param>格式
带参数的指令
单参数指令
javascript
// 注册 !kick <player> 指令
plugin_registerCommand("!kick <player>", (player, target) => {
plugin_executeCommand(`kick ${target} 被 ${player} 踢出服务器`);
plugin_log("INFO", `${player} 踢出了 ${target}`);
});玩家输入:
!kick Alex多参数指令
javascript
// 注册 !ban <player> <reason> 指令
plugin_registerCommand("!ban <player> <reason>", (player, target, reason) => {
plugin_executeCommand(`ban ${target} ${reason}`);
plugin_log("INFO", `${player} 封禁了 ${target},原因:${reason}`);
});玩家输入:
!ban Alex 使用外挂混合固定文本和参数
javascript
// 注册 !tp to <player> 指令
plugin_registerCommand("!tp to <player>", (player, target) => {
plugin_executeCommand(`tp ${player} ${target}`);
plugin_log("INFO", `${player} 传送到 ${target}`);
});玩家输入:
!tp to Alex注意:to 是固定文本,必须完全匹配。
指令匹配规则
MSL 使用严格的指令匹配规则:
1. 前缀匹配
指令前缀必须完全匹配:
javascript
plugin_registerCommand("!ping", ...);
// 匹配:!ping
// 不匹配:/ping, ping2. 名称匹配
指令名称区分大小写:
javascript
plugin_registerCommand("!Ping", ...);
// 匹配:!Ping
// 不匹配:!ping, !PING3. 参数数量匹配
参数数量必须完全匹配:
javascript
plugin_registerCommand("!kick <player>", ...);
// 匹配:!kick Alex
// 不匹配:!kick, !kick Alex reason4. 固定文本匹配
固定文本必须完全匹配:
javascript
plugin_registerCommand("!tp to <player>", ...);
// 匹配:!tp to Alex
// 不匹配:!tp Alex, !tp from Alex实用示例
帮助系统
javascript
// 注册 !help 指令
plugin_registerCommand("!help", (player) => {
const helpMessages = [
"========== 服务器帮助 ==========",
"!help - 显示帮助信息",
"!online - 查看在线玩家",
"!home - 传送到家",
"!sethome - 设置家",
"================================"
];
helpMessages.forEach(msg => {
plugin_executeCommand(`tellraw ${player} {"text":"${msg}","color":"yellow"}`);
});
});在线玩家查询
javascript
// 注册 !online 指令
plugin_registerCommand("!online", (player) => {
plugin_executeCommand("list", (lines) => {
lines.forEach(line => {
if (line.includes("players online")) {
plugin_executeCommand(`tellraw ${player} {"text":"${line}","color":"green"}`);
}
});
});
});家系统
javascript
// 设置家
plugin_registerCommand("!sethome", (player) => {
// 注意:这里需要通过其他方式获取玩家坐标
// 可以通过监听玩家位置或使用其他插件配合
plugin_executeCommand(`tellraw ${player} {"text":"家已设置!","color":"green"}`);
});
// 回家
plugin_registerCommand("!home", (player) => {
const homes = plugin_pull("playerHomes") || {};
if (homes[player]) {
const home = homes[player];
plugin_executeCommand(`tp ${player} ${home.x} ${home.y} ${home.z}`);
plugin_executeCommand(`tellraw ${player} {"text":"欢迎回家!","color":"green"}`);
} else {
plugin_executeCommand(`tellraw ${player} {"text":"你还没有设置家!使用 !sethome 设置","color":"red"}`);
}
});私聊系统
javascript
// 注册 !msg <player> <message> 指令
plugin_registerCommand("!msg <player> <message>", (sender, target, message) => {
// 存储私聊消息
const privateMessages = plugin_pull("privateMessages") || {};
if (!privateMessages[target]) {
privateMessages[target] = [];
}
privateMessages[target].push({
from: sender,
message: message,
time: new Date().toISOString()
});
plugin_push("privateMessages", privateMessages);
// 发送消息给目标玩家
plugin_executeCommand(`tellraw ${target} {"text":"[私聊] ${sender}: ${message}","color":"light_purple"}`);
plugin_executeCommand(`tellraw ${sender} {"text":"[私聊] -> ${target}: ${message}","color":"light_purple"}`);
});管理员指令
javascript
// 注册 !admin <action> <player> 指令
plugin_registerCommand("!admin <action> <player>", (player, action, target) => {
// 检查权限(这里简化处理,实际应该检查玩家权限)
const admins = ["Steve", "Admin"];
if (!admins.includes(player)) {
plugin_executeCommand(`tellraw ${player} {"text":"你没有权限执行此命令","color":"red"}`);
return;
}
switch (action.toLowerCase()) {
case "kick":
plugin_executeCommand(`kick ${target} 被管理员踢出`);
break;
case "ban":
plugin_executeCommand(`ban ${target} 被管理员封禁`);
break;
case "op":
plugin_executeCommand(`op ${target}`);
break;
default:
plugin_executeCommand(`tellraw ${player} {"text":"未知操作: ${action}","color":"red"}`);
}
});指令权限控制
MSL 本身不提供权限系统,但你可以通过以下方式实现简单的权限控制:
基于玩家名的权限
javascript
const admins = ["Steve", "Admin", "Owner"];
plugin_registerCommand("!admin", (player) => {
if (!admins.includes(player)) {
plugin_executeCommand(`tellraw ${player} {"text":"权限不足","color":"red"}`);
return;
}
// 执行管理员操作
plugin_executeCommand("say 管理员指令已执行");
});基于配置的权限
javascript
// 在插件中定义权限配置
const permissions = {
"Steve": ["admin", "moderator"],
"Alex": ["moderator"],
"default": ["player"]
};
function hasPermission(player, permission) {
const playerPerms = permissions[player] || permissions["default"];
return playerPerms.includes(permission);
}
plugin_registerCommand("!ban <player>", (player, target) => {
if (!hasPermission(player, "admin")) {
plugin_executeCommand(`tellraw ${player} {"text":"权限不足","color":"red"}`);
return;
}
plugin_executeCommand(`ban ${target}`);
});权限节点
TIP
MSL正如原版mc服务器一样,不默认提供权限节点管理系统。你需要在MSL中安装类似于LuckPerms的插件来管理权限节点。
权限节点的全局数据键名都应该为permission:a.b.c...,即开头应为permission:,后续部分自行添加,但应保证条理。
权限节点机制应为:①MSL启动,拉起权限节点插件->②权限节点插件读取数据,将不同权限节点以及其对应的玩家名通过plugin_push推送到全局数据中->③用户调用某插件的指令->④插件通过plugin_pull拉取权限节点的玩家列表->⑤判断玩家是否具有权限并做出响应。
最佳实践
1. 指令命名规范
使用有意义的前缀避免冲突:
javascript
// 推荐:使用插件名作为前缀
plugin_registerCommand("!myplugin help", ...);
plugin_registerCommand("!myplugin reload", ...);
// 不推荐:通用名称可能冲突
plugin_registerCommand("!help", ...);2. 错误处理
在指令回调中添加错误处理:
javascript
plugin_registerCommand("!kick <player>", (player, target) => {
try {
plugin_executeCommand(`kick ${target}`);
plugin_log("INFO", `${player} 踢出了 ${target}`);
} catch (error) {
plugin_log("ERROR", `执行踢出指令失败: ${error.message}`);
plugin_executeCommand(`tellraw ${player} {"text":"执行失败","color":"red"}`);
}
});3. 反馈信息
为玩家提供清晰的反馈:
javascript
plugin_registerCommand("!home", (player) => {
const homes = plugin_pull("playerHomes") || {};
if (homes[player]) {
plugin_executeCommand(`tp ${player} ${homes[player].x} ${homes[player].y} ${homes[player].z}`);
plugin_executeCommand(`tellraw ${player} {"text":"已传送到你的家","color":"green"}`);
} else {
plugin_executeCommand(`tellraw ${player} {"text":"你还没有设置家","color":"yellow"}`);
plugin_executeCommand(`tellraw ${player} {"text":"使用 !sethome 设置你的家","color":"yellow"}`);
}
});4. 日志记录
记录指令使用情况:
javascript
plugin_registerCommand("!ban <player> <reason>", (player, target, reason) => {
// 记录日志
plugin_log("INFO", `[指令] ${player} 封禁了 ${target},原因:${reason}`);
// 存储到全局数据
const banLog = plugin_pull("banLog") || [];
banLog.push({
operator: player,
target: target,
reason: reason,
time: new Date().toISOString()
});
plugin_push("banLog", banLog);
// 执行封禁
plugin_executeCommand(`ban ${target} ${reason}`);
});下一步
- 执行指令 - 学习如何执行 Minecraft 指令
- API 参考 - plugin_registerCommand - 查看详细 API 文档