NoHotbarNeeded
[!INFO] Git Commit:
57ff1d5| Updated: 2026-10-01
NoHotbarNeeded(modid nohotbarneeded)是 Minecraft 1.7.10 上的一个极小的纯客户端 NEI 扩展模组,作者 SinTho0r4s。它解决一个具体 annoyance:某些物品(如背包)必须先移动到快捷栏、关掉背包、切到该快捷栏才能右键使用;装上本模组后,只要物品实现了它提供的接口,玩家就能在背包界面里直接用鼠标指着该物品 + 按一个热键就地触发。
它自己不提供任何物品——完全是一个「给别的 mod 的物品加一个就地激活入口」的粘合层。
核心结论
| 问题 | 答案 |
|---|---|
| 它注册了什么方块 | 没有任何方块 |
| 它注册了什么实体 / TileEntity | 没有 |
| 它注册了几个物品 | 0 个(GameRegistry.register 全仓 0 处) |
| 它有自己的 GUI 吗 | 没有(不实现 IGuiHandler) |
| 它有热键吗 | 有 1 个(Activate item inventory → 实为 "Activate item in inventory",默认 G) |
| 它有自己的网络包吗 | 有 1 条(ActivateItemRequest,仅 C→S) |
| 它有指令吗 | 没有 |
| 它有配置文件吗 | 没有(Configuration / @Config 全仓 0 处) |
| 它是 core mod 吗 | 不是(coreModClass = 空) |
| Java 文件数 | 8 |
依赖
| 模组 | 强度 | 声明位置 |
|---|---|---|
| NotEnoughItems | required-after:@[2.8.93,) |
NoHotbarNeeded.java:13;Gradle 侧 api("com.github.GTNewHorizons:NotEnoughItems:2.8.93-GTNH:dev") |
| ForestryMC | 仅 devOnlyNonPublishable |
dependencies.gradle,不参与任何门控 |
NEI 是硬依赖:整个功能就是通过 GuiContainerManager.addInputHandler 挂在 NEI 的输入分发链上的。
工作流程
玩家在任意容器 GUI 内按下 G
↓
NEI 分发到 KeyboardEventHandler.lastKeyTyped
↓
比对 keyBinding.getKeyCode()(为 0 则短路)
↓
GuiContainerManager.getSlotMouseOver(gui) 取鼠标所指 Slot
↓
slotIdx 必须在 0..35,否则放弃
↓
slot.inventory == player.inventory?
↓
stack.getItem() instanceof ActivatableFromInventoryServerSide?
↓
sendToServer(ActivateItemRequest(slotIdx)) → return true
↓
【服务端】ActivateItemHandler 重新取该槽位真实 ItemStack
↓
二次 instanceof 通过 → item.activateFromInventory(playerMP, slotIdx)
前后端各做一次 instanceof,服务端不信任客户端传来的槽位内容,只信槽位号。
物品列表
无。本模组不注册任何 Item。
对外 API
- ActivatableFromInventoryServerSide - 唯一的对外接口,
void activateFromInventory(EntityPlayerMP, int slotIdx)
物品效果
无。
游戏设定
- NEI 输入处理器注册 - 8 个接口方法的实现情况,依赖与代理分工
- 激活物品热键 - G 键绑定与 0–35 槽位限制
网络包
- ActivateItemRequest 网络包 - 通道
nohotbarneeded,判别符 0,仅 C→S,载荷 1 个 int
本 mod 没有的内容(附 grep 证据)
以下维度在源码中确认不存在,因此没有创建对应目录。
没有方块、物品、实体
$ grep -rn "registerBlock\|GameRegistry.register\|registerTileEntity\|EntityRegistry" src/main/java
(无输出)
没有 GUI
$ grep -rn "registerGuiHandler\|IGuiHandler" src/main/java
(无输出)
它只作为输入处理器挂在别人的 GUI 上,从不开自己的界面。
没有指令
$ grep -rn "ICommand\|CommandBase\|addChatCommand" src/main/java
(无输出)
没有配置文件
$ grep -rn "Configuration\|@Config" src/main/java
(无输出)
无法通过配置改热键或开关行为,热键只能在 Minecraft 键位设置里改。
没有 Forge 事件订阅、没有附魔/药水/群系/结构/成就/世界生成
$ for kw in @SubscribeEvent registerWorldGenerator Enchantment Potion Achievement; do ... done
每一个都是 0
ClientProxy 里唯一的事件侧动作是 GuiContainerManager.addInputHandler,那不是 Forge 事件总线。
不是 core mod、没有 Mixin、没有 AT
gradle.properties 中 coreModClass =、usesMixins = false、accessTransformersFile =(三者均为空值)。
服务端几乎无事可做
CommonProxy.init 是空方法(CommonProxy.java:7)。服务端只加载网络处理器,没有任何客户端行为。
源码缺陷
- 创造模式下完全失效——
KeyboardEventHandler.java:50-54。源码注释与 TODO 明示:创造模式快捷栏槽位索引会变成 36+,被slotIdx > 35的硬检查直接拒绝。TODO 未修复。 - 服务端缺少槽位范围校验——
ActivateItemHandler.java:17-18。客户端有 0–35 检查,服务端拿到slotIdx后直接player.inventory.getStackInSlot(slotIdx),无边界防护。 mcmod.info描述是模板残留——src/main/resources/mcmod.info中"description"为"An example mod for Minecraft 1.7.10 with Forge focused on a stable setup.",即 GTNH 脚手架模板原文,与本模组实际功能无关。同时"authorList": ["SinTho0r4s"]与仓库/类名Erixonich也不一致。- API 包未在 Gradle 声明——
gradle.properties中apiPackage =留空,尽管源码确实有api包。注释掉的replaceGradleTokenInFile段落里public static final String VERSION也仍是注释状态(实际由generateGradleTokenClass生成为net.xonich.mc.nohotbarneeded.Tags)。 - Javadoc 残句——
ActivatableFromInventoryServerSide.java:9-10的Each item will define后无内容;:5-7的类注释里 “be able activated” 缺 “to”。 - 热键可被按键吞掉——
lastKeyTyped仅在keyCode == keyID时消费;关闭绑定(getKeyCode()为 0)时整条链路静默失效,无任何提示。
相关条目
- ActivatableFromInventoryServerSide - 别的 mod 想接入就实现这个接口
- NEI 输入处理器注册 - 与 NEI 的全部耦合面
- ActivateItemRequest 网络包 - 唯一的通信通道