个人背包快捷键

[!INFO] 实现类:de.eydamos.backpack.handler.KeyInputHandler(@SideOnly(Side.CLIENT)) 注册:ClientProxy.registerKeybindings() → ClientRegistry.registerKeyBinding(KeyInputHandler.personalBackpack)

基本信息

属性 值
字段 public static KeyBinding personalBackpack
显示名 Localizations.KEY_PERSONAL(本地化,非字面量)
默认按键 Keyboard.KEY_NONE(默认未绑定)
分类 Localizations.KEY_CATEGORY
注册时机 preInit → proxy.registerKeybindings()

⚠️ 默认按键是 KEY_NONE,玩家必须自行在选项→控制里绑定才能使用。 代码中不存在任何默认按键赋值。

监听两个输入事件

KeyInputHandler 同时订阅键盘与鼠标事件,且两者调用同一个 onInput():

@SubscribeEvent public void handleKeyInputEvent(KeyInputEvent event) { onInput(); }
@SubscribeEvent public void handleMouseInputEvent(MouseInputEvent event) { onInput(); }

因为 onInput() 内部用 personalBackpack.isPressed() 判据, 而鼠标事件触发时该绑定通常未被按下,所以鼠标订阅实际上是冗余的。 注册处理器是 FMLCommonHandler.instance().bus().register(new KeyInputHandler()) (注意用的是 FML 总线而非 MinecraftForge.EVENT_BUS, 因为 InputEvent 属于 FML 的 cpw.mods.fml.common.eventhandler 包)。

潜行决定打开哪一个界面

onInput() 的分支逻辑:

条件 发送的字节常量 打开的界面
player.isSneaking() Constants.Guis.OPEN_PERSONAL_SLOT = 1 额外穿戴槽(个人背包槽)
否则 Constants.Guis.OPEN_PERSONAL_BACKPACK = 0 个人背包本体
if (player.isSneaking()) {
    GuiHelper.sendOpenPersonalGui(Constants.Guis.OPEN_PERSONAL_SLOT);
} else {
    GuiHelper.sendOpenPersonalGui(Constants.Guis.OPEN_PERSONAL_BACKPACK);
}

两个字节常量定义在 Constants.Guis 内部类中(OPEN_PERSONAL_BACKPACK = 0、 OPEN_PERSONAL_SLOT = 1),由服务端解析后决定实例化哪个 AbstractFactory 子类。

双重守卫

onInput() 在触发前检查了两层条件:

  1. if (mc.inGameHasFocus) —— 任何界面打开时(背包、箱子、聊天)都不触发, 避免与其它 GUI 抢输入。
  2. if (player != null) —— 防止在主菜单/加载阶段 NPE。

未通过守卫时静默返回,不打任何日志。

与 openOnlyWornBackpacks 配置的关系

Backpack 配置 中的 openOnlyWornBackpacks = true 时:

  • ItemBackpackBase.onItemRightClick 不再打开背包 GUI(该配置下服务端分支被跳过);
  • ItemBackpackBase.activateFromInventory 开头直接 return。

即该配置把「打开背包」的所有路径收敛到穿戴槽与本快捷键, 而 KeyInputHandler 是唯一不受该配置影响的客户端入口。

相关条目