指令系统
基本信息
| 属性 | 值 |
|---|---|
| 指令名 | minetweaker |
| 别名 | mt、crafttweaker、ct(MineTweakerImplementationAPI.java:653) |
| 权限 | 仅 OP(MineTweakerImplementationAPI.java:677-684) |
| 注册时机 | 每次 reload() 时按需注册,已存在则跳过(MineTweakerImplementationAPI.java:649) |
| 注册位置 | IServer.addCommand → MCServer.addCommand(api/server/IServer.java:14-16、mc1710/server/MCServer.java:44-48) |
| 1.7.10 底层 | net.minecraft.command.ICommand 实现类 MCServer.MCCommand(mc1710/server/MCServer.java:83-149,文件共 193 行) |
| 本模组自带子命令 | 1 个:help(+ 脚本通过 addMineTweakerCommand 注册的自定义命令) |
| 脚本可注册自定义命令 | 是,server.addMineTweakerCommand(name, description, function) |
/minetweaker 主指令
reload() 内的匿名 ICommandFunction(MineTweakerImplementationAPI.java:656-676)实现分发:
| 参数 | 行为 | 源码行 |
|---|---|---|
| 无参数 | 回一句 Please provide a command. Use /mt help for more info. |
:658-659 |
help |
列出所有已注册自定义命令的描述文本(键名先 Arrays.sort 排序) |
:660-667 |
| 其他 | 在 minetweakerCommands 查找;命中则 command.function.execute(args[1..], player),未命中回 No such minetweaker command available |
:668-675 |
注意 help 打印的是每个命令的 description 字符串数组内容,不打印命令名本身。
权限校验由配套的匿名 ICommandValidator(MineTweakerImplementationAPI.java:677-684)完成:
public boolean canExecute(IPlayer player) {
return server.isOp(player);
}
非 OP 玩家在 Forge 指令层即被拦下,不会进入分发逻辑。isOp 的 1.7.10 实现见 MCServer(mc1710/server/MCServer.java),最终查 Minecraft 服务器的 op 列表。
两种自定义命令注册
| API | 脚本名 | 效果 | 源码行 |
|---|---|---|---|
IServer.addCommand(name, usage, aliases, function, validator, completion) |
server.addCommand(...) |
注册为原版指令,走 CommandHandler,支持别名、权限校验、Tab 补全 |
IServer.java:14-16 |
IServer.addMineTweakerCommand(name, usage, function) |
server.addMineTweakerCommand(...) |
注册为 /minetweaker 的子命令 |
IServer.java:18-19 |
AbstractServer(api/server/AbstractServer.java:14-17)把 addMineTweakerCommand 声明为 final 并直接转发到 MineTweakerImplementationAPI.addMineTweakerCommand(:710-712),后者包一层 AddMineTweakerCommandAction 存入 minetweakerCommands 静态 Map。
AddMineTweakerCommandAction(MineTweakerImplementationAPI.java:738-772)是 IUndoableAction:apply()(:747-750)仅在键不存在时 put,undo()(:759)是空实现 —— 子命令注册不可撤销,重载后仍留在表里。同名重复注册时 describe()(:762-767)返回空串、describeUndo()(:769-772)返回 "tried to remove command: <name> failed. THIS IS NOT AN ERROR!"(:771)。
回调与校验器类型
三个脚本类型(均在 api/server/):
| 脚本名 | Java 接口 | 抽象方法 | 注解 |
|---|---|---|---|
minetweaker.server.ICommandFunction |
ICommandFunction.java:10 |
void execute(String[] arguments, IPlayer player) |
无 @ZenMethod |
minetweaker.server.ICommandValidator |
ICommandValidator.java |
boolean canExecute(IPlayer player) |
— |
minetweaker.server.ICommandTabCompletion |
ICommandTabCompletion.java |
Tab 补全 | — |
ICommandFunction.execute 没有 @ZenMethod(ICommandFunction.java:12-14)—— 与 IEventHandle.close() 形成对照,说明并非所有回调都标注了。
内置校验器
api/server/CommandValidators.java 全文提供 1 个:
@ZenClass("minetweaker.server.CommandValidators")
public class CommandValidators {
public static final ICommandValidator ISOP = player -> MineTweakerAPI.server.isOp(player);
@ZenGetter
public static ICommandValidator isOp() {
return ISOP;
}
}
即脚本写 CommandValidators.isOp(属性形式)拿到 OP 校验器,传给 server.addCommand(...)。
1.7.10 的命令发送者适配
MCServer.getPlayer(ICommandSender)(mc1710/server/MCServer.java:67-81)把 4 种发送者映射为 IPlayer:
| 发送者类型 | 包装类 |
|---|---|
EntityPlayer |
MCPlayer |
DedicatedServer |
— |
RConConsoleSource |
RconPlayer(mc1710/player/RconPlayer.java) |
CommandBlockLogic |
CommandBlockPlayer(mc1710/player/CommandBlockPlayer.java) |
| 其他 | 往 stdout 打两行警告(:77-78),player 保持 null |
因此 /minetweaker 从命令方块执行时 player 不会是真实玩家,脚本里取玩家名需自行判空。
相关条目
- 重载生命周期 - 指令在
reload()步骤 6 注册 - 配置项 -
antiStuck影响重载时是否重复执行 - Minecraft 层 API -
IServer的 6 个脚本方法