/reloadServerConfigs

基本信息

属性 值
服务端指令名 /reloadServerConfigs
客户端指令名 /reloadConfigs(仅客户端)
实现类 CommandReloadConfigs extends CommandBase
源码 com/enderio/core/common/command/CommandReloadConfigs.java
权限等级 2(getRequiredPermissionLevel,:57-59)
权限检查 player.getEntityWorld().isRemote || super.canCommandSenderUseCommand(player)(:62-64)
注册位置 EnderCore.java:125-129(init 阶段)
客户端入口 ClientCommandHandler.instance.registerCommand(CommandReloadConfigs.CLIENT)(:125)
服务端入口 MinecraftServer.getServer().getCommandManager() → registerCommand(...)(:126-128)

同一个类被实例化成两份,按 Side 区分指令名(:22-23):

public static final CommandReloadConfigs SERVER = new CommandReloadConfigs(Side.SERVER);
public static final CommandReloadConfigs CLIENT = new CommandReloadConfigs(Side.CLIENT);

getCommandName()(:47-49)返回 side == Side.SERVER ? "reloadServerConfigs" : "reloadConfigs"。

[!NOTE] 客户端指令 /reloadConfigs 由 Forge 的 ClientCommandHandler 承载,不需要 OP 权限(:62-64 的 isRemote 短路)。服务端指令 /reloadServerConfigs 需要权限等级 2。

功能

对指定的一个或多个 modid 发送 ConfigFileChangedEvent,让这些 mod 重新读取各自的配置文件。用法(getCommandUsage,:52-54):

/reloadServerConfigs <modid> (<modid2> <modid3> ...)

processCommand(:83-105)对每个参数逐个处理:

步骤 行为 源码
1 用 Loader.instance().getModObjectList() 校验 modid 是否存在 :86-90
2 无效 → 输出 invalid :101-103
3 有效 → 向 FML 总线发送 ConfigFileChangedEvent(modid) :92-94
4 事件未调用 setSuccessful() → 输出 fail :98-100
5 事件调用了 setSuccessful() → 输出 success :96-97

三种结果的语言键(en_US.lang:5-7):

键 文案
endercore.command.config.result.success Reloading configs for %s was successful
endercore.command.config.result.fail Reloading configs for %s failed
endercore.command.config.result.invalid Modid %s is not valid

%s 由 EnderCore.lang.localize(key, modid) 填充(CommandReloadConfigs.java:107-109)。

交互

静态初始化时的全 mod 探测

类的静态初始化块(:29-40)在类首次加载时,会无条件遍历所有已加载 mod 并各发一次 ConfigFileChangedEvent:

static {
    EnderCore.logger.info("Sending dummy event to all mods");
    for (ModContainer mod : Loader.instance().getActiveModList()) {
        ConfigFileChangedEvent event = new ConfigFileChangedEvent(mod.getModId());
        FMLCommonHandler.instance().bus().post(event);
        if (event.isSuccessful()) validModIDs.add(mod.getModId());
    }
}

日志明确称之为 “dummy event”。用途是探测哪些 mod 支持本事件,把结果缓存进 validModIDs,供 Tab 补全使用(:70-76)。

[!IMPORTANT] 这意味着只要 CommandReloadConfigs 类被加载一次,所有 mod 都会收到一次无效的配置重载事件,与是否执行指令无关。类在 EnderCore.init 中因 registerCommand 被引用而加载(EnderCore.java:125-128),即每次进入游戏都会触发。

Tab 补全

addTabCompletionOptions(:68-80)把 validModIDs 逐个与已输入参数比对,用 ArrayUtils.removeElement 剔除已输入项后返回匹配列表。args.length < 1 时返回 null。

事件契约

ConfigFileChangedEvent extends ConfigChangedEvent(com/enderio/core/common/event/ConfigFileChangedEvent.java:18-33):

属性 值
构造父类参数 super(modID, "null", true, false) —— isModSet = true,requiresMcRestart = false
isSuccessful() 初始 false
setSuccessful() 置为 true,监听方不调用即视为失败

类注释(ConfigFileChangedEvent.java:9-10)要求监听方先调用 config.load() 再重新解析,以从磁盘重读。注释同时警告(:14)requiresMcRestart 恒为 false,因此并非所有配置项都能靠本指令生效,可能出现「成功但未真正重载」。

源码缺陷

  • 静态块无条件发送 dummy 事件(:29-40):在游戏启动阶段向所有 mod 发一次无意义事件,部分 mod 可能因此重复读盘或重复弹出配置 GUI 提示。
  • super(modID, "null", ...) 的配置文件名传字面量 "null"(ConfigFileChangedEvent.java:23):沿用 FML 构造器签名,父类不会实际使用该值。
  • isRemote 短路使客户端指令免权限(:62-64):客户端 /reloadConfigs 对任何玩家开放,在多人服务器上单机客户端的本地 config 会被重载,这是预期行为(客户端只影响本地),但服务端不会转发该指令。

相关条目