InGameInfoCommand

/igi 客户端命令:reload / load / save / enable / disable / taglist / config

基本信息

属性 值
路径 com.github.lunatrius.ingameinfo.command.InGameInfoCommand
行数 133
命令名 igi
注册方式 ClientProxy.init(:55)→ ClientCommandHandler.instance.registerCommand(...)

⚠️ 纯客户端命令 —— 用 ClientCommandHandler 而非 FMLServerStartingEvent.registerServerCommand。 所以 /igi 不需要 OP 权限,且在多人服务器上也能用 (只改自己的客户端)。

命令名与用法(:23-31)

方法 返回
getCommandName() Names.Command.NAME = igi
getCommandUsage(sender) commands.ingameinfoxml.usage(本地化 key)

权限(:33-36)

public boolean canCommandSenderUseCommand(ICommandSender par1ICommandSender) { return true; }

⚠️ 无条件 true —— 任何玩家都能用。 这是合理的(只影响自己的 HUD 配置),但 save 子命令能往配置目录写文件, 理论上可被用来覆盖配置。建议在多人服务器上留意。

7 个子命令

子命令 行 行为 成功反馈
reload :81-88 ConfigurationHandler.reload() + core.reloadConfig() success / failure
load <file> :89-99 core.loadConfig(args[1]),成功则写回 configName success / failure
save <file> :100-106 core.saveConfig(args[1]) success / failure
enable :107-111 showHUD = true + 存盘 enable
disable :112-116 showHUD = false + 存盘 disable
taglist :117-119 延迟 10 tick 打开 GuiTags 无
config :120-122 延迟 0 tick 打开 GuiModConfig 无

⚠️ 参数个数不校验:

  • load / save 直接读 args[1](:90、:101), 若玩家只打 /igi load,会抛 ArrayIndexOutOfBoundsException 而非友好的用法错误。
  • 无参数时(args.length == 0)落到 :126 的 throw new WrongUsageException(getCommandUsage(...)) —— 正确。

reload 的双重动作(:83-84)

ConfigurationHandler.reload();
final boolean success = this.core.reloadConfig();

两件事:

  1. 重读 Forge 配置文件(7 项 + 9 项偏移)
  2. 重新解析 HUD 配置文件

⚠️ ConfigurationHandler.reload() → loadConfiguration() + save(), 而 save() 只在 hasChanged() 时落盘。 所以「配置文件被外部改过」时,configuration.hasChanged() 未必为 true (它跟踪的是内存里的 Property 状态),可能不落盘。

延迟 GUI 打开

taglist 与 config 都用 LunatriusCore 的 DelayedGuiDisplayTicker:

子命令 延迟 tick 打开的界面
taglist 10 GuiTags
config 0 GuiModConfig

⚠️ taglist 延迟 10 tick(0.5 秒)而 config 延迟 0。 config 延迟 0 意味着在命令处理的同一 tick 就试图打开 GUI —— 若当时正处于某个 GUI 内(如从命令方块执行), mc.displayGuiScreen 会在 tick 内被后续逻辑覆盖。 taglist 的 10 tick 延迟正是为了避开这个时序问题。

Tab 补全(:38-63)

第一级(args.length == 1)

getListOfStringsMatchingLastWord 补全 7 个子命令 (不含 usage)。全部来自 Names.Command 常量。

第二级(args.length == 2)

首参数 补全内容
load getFilenames() —— 目录里实际存在的配置文件名
save 3 个固定名:InGameInfo.xml / InGameInfo.json / InGameInfo.txt
其它 null(不补全)

⚠️ load 与 save 的补全策略相反: load 列已存在的文件(getFilenames() 扫目录), save 列3 个默认名(覆盖式保存)。

save 之所以不扫目录:它需要 format 里的 value 树能正确反序列化, 而不同格式的往返可靠性不同(见 TextPrinter), 所以只提供默认的 3 个名。

getFilenames 的过滤条件(:65-76)

name.startsWith(Names.Files.NAME) && (endsWith(EXT_XML) || endsWith(EXT_JSON) || endsWith(EXT_TXT))

即必须以 InGameInfo 开头,且是三种扩展名之一。 所以 InGameInfo2.xml(切换键的「2 号配置」)能被补全出来 (它以 InGameInfo 开头), 但玩家自建的 myhud.xml 不会出现在补全里。

⚠️ listFiles 返回 null 时(目录不存在)返回空列表 —— 已判空(:71)。

compareTo(:129-132)

public int compareTo(Object obj) { return super.compareTo(obj); }

⚠️ 纯转发,零作用 —— 直接调父类实现。 CommandBase 实现了 Comparable<CommandBase>。 这是一个无意义的覆写(可能是 IDE 自动生成的)。

相关