
Packed Inventory
库存管理从未如此简单。
查看大图
紧凑背包
一个 Minecraft 模组,旨在通过直接在你的背包中管理潜影盒、末影箱等物品的内容,来缓解日益严重的背包问题。
哦,我们还为潜影盒、末影箱、地图等提供了精美的悬浮提示!
特性
- 无需放置潜影盒即可管理其背包。
- 无需放置末影箱即可管理你的末影箱背包。
- 快速将物品移入或移出潜影盒、末影箱及其他提供背包的物品。
- 直接从你的背包中使用工作台、切石机等工作站。
- 为潜影盒提供原版风格的悬浮提示。
- 为末影箱提供原版风格的悬浮提示。
- 为已填充的地图提供原版风格的悬浮提示。
- 为在创造模式下通过
Ctrl + 鼠标中键获得的包含 NBT 的物品提供原版风格的悬浮提示,例如箱子、木桶、熔炉、漏斗、发射器、投掷器等。 - 一个广泛而简单的 API,帮助其他模组作者为其方块和物品实现这些功能。
类似收纳袋的功能

如前所述,提供背包的物品 (例如潜影盒、末影箱,以及任何通过 Packed Inventory API 注册的物品) 会自动获得类似收纳袋的功能,允许你快速将物品移入或移出它们。
要将物品存入提供背包的物品中,你可以:
- 拾取该提供背包的物品,然后按下
k键点击要存放的物品,或 - 拾取该提供背包的物品,然后按下
k键点击要存放的提供背包的物品,或 - 拾取要存放的物品,然后按下
k键点击提供背包的物品。
要从提供背包的物品中取出物品:
- 拾取该提供背包的物品,然后按下
k键点击空槽位以取出物品,或 - 拾取该提供背包的物品,然后按下
l或ctrl + k键点击槽位以取出物品,或 - 按下
l或ctrl + k键点击提供背包的物品以取出物品。
要将提供背包的物品中的全部物品倒出到世界中:
- 拾取该提供背包的物品,将其移动到背包界面之外,然后按下
k键。
悬浮提示
以下是一些悬浮提示示例:
- 容器提示
- 彩色容器提示
- 紧凑容器提示
- 已填充地图提示

更多截图可以在 这里 找到。
按键绑定
按键绑定可以像原版一样配置:
- 进入
选项。 - 选择
控制。 - 然后选择
按键绑定。 - 向下滚动到
Packed Inventory部分。 - 配置可用的按键绑定。
| 名称 | 描述 | 默认 |
|---|---|---|
与物品交互 |
与当前快捷栏槽位中的物品交互。或者,如果背包界面已打开,则与鼠标悬停的物品交互。根据上下文,此操作可以:
|
k |
切换交互模式(按住) |
使 与物品交互 按键绑定行为如同 从物品中提取 |
Left Control |
从物品中提取 |
从选定的提供背包的物品中提取一个物品 | l |
反转提示可见性(按住) |
按下时反转提示可见性 | Left Shift |
反转提示紧凑模式(按住) |
按下时反转提示紧凑模式 | c |
请注意,这些按键绑定与其他按键冲突是完全正常的,因为它们仅在你的背包界面打开时生效,而其他按键绑定通常在该界面下无效。
配置
如果你安装了 Cloth Config,你可以自定义本模组的行为。配置文件通常位于 ./config/packed-inventory.json,默认内容如下:
{
"defaultTooltipConfig": {
"showWhenEmpty": false,
"rows": -1,
"columns": -1,
"usePredefinedColor": false,
"enable": true,
"compact": false
},
"tooltips": {
"minecraft:shulker_box": {
"showWhenEmpty": false,
"rows": -1,
"columns": -1,
"usePredefinedColor": false,
"enable": true,
"compact": false
},
"minecraft:ender_chest": {
"syncInterval": 5000,
"showWhenEmpty": false,
"rows": -1,
"columns": -1,
"usePredefinedColor": false,
"enable": true,
"compact": false
},
"minecraft:filled_map": {
"size": 128,
"enable": false,
"compact": false
}
},
"defaultValidationConfig": {
"suppressValidationInCreative": true,
"requiresPlayerOnGround": true,
"enable": true
},
"validation": {
"minecraft:shulker_box": {
"suppressValidationInCreative": true,
"requiresPlayerOnGround": true,
"enable": true
},
"minecraft:ender_chest": {
"requiresSilkTouch": true,
"suppressValidationInCreative": true,
"requiresPlayerOnGround": true,
"enable": true
}
}
}
| 名称 | 描述 | 客户端/服务器 | 默认值 |
|---|---|---|---|
tooltip.enable |
指示此提示是否默认启用 | 客户端 |
true |
tooltip.compact |
指示此提示是否默认启用紧凑模式 | 客户端 |
false |
tooltip.showWhenEmpty |
指示当内容为空时是否应显示此提示 | 客户端 |
false |
tooltip.rows |
指定用于显示提示内容所需的行数 | 客户端 |
-1 |
tooltip.columns |
指定用于显示提示内容所需的列数 | 客户端 |
-1 |
tooltip.usePredefinedColor |
指示此提示是否应使用物品颜色 | 客户端 |
false |
tooltip.color |
当 usePredefinedColor 设置为 false 或无法自动确定物品颜色时,指定默认的提示颜色 |
客户端 |
NONE |
tooltip.syncInterval |
指定同步发生的频率 | 客户端 |
5000 |
tooltip.size |
指定此提示的大小(如适用) | 客户端 |
128 |
| | | | |
validation.enable |
指示是否允许与此验证规则关联的操作 | 服务器 |
true |
validation.suppressValidationInCreative |
指示是否应抑制对创造模式玩家的此验证规则 | 服务器 |
true |
validation.requiresPlayerOnGround |
指示玩家是否应站在地面上以满足此验证规则 | 服务器 |
true |
validation.requiresSilkTouch |
指示玩家是否应手持带有精准采集附魔的工具以满足此验证规则 | 服务器 |
true |
你可以直接在配置文件中编辑这些值中的任何一个,或者通过 ModMenu 进行编辑。
开发
依赖安装
要使用 API,请在你的构建脚本中将 Packed Inventory 添加为依赖:
build.gradle:
repositories {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
content {
includeGroup "maven.modrinth"
}
}
}
dependencies {
modImplementation "maven.modrinth:packed-inventory:${project.packed_inventory_version}"
}
gradle.properties:
packed_inventory_version=/* 版本(例如,0.3.0+1.20.3) */
入口点
该 API 引入了两个新的入口点,你可以在模组元数据中指定:
| 名称 | 描述 | 接口 | 端 |
|---|---|---|---|
packed-inventory |
将在任何环境中首先运行 | PackedInventoryInitializer |
* |
packed-inventory-client |
将仅在客户端侧第二个运行 | PackedInventoryClientInitializer |
client |
fabric.mod.json:
{
"entrypoints": {
"packed-inventory": [
"a.b.c.MyMod"
],
"packed-inventory-client": [
"a.b.c.MyClientMod"
]
}
}
背包视图
来认识一下背包视图!这是本模组的核心概念,使我们无需与对应方块的方块形式交互,即可编辑各自物品提供的背包。
让我们为末影箱物品注册一个简单的背包查看器 (提供背包视图的组件):
public class MyMod implements PackedInventoryInitializer {
@Override
public void registerInventoryViewers(InventoryViewerRegistry registry, PackedInventoryApiConfig config) {
registry.register(
// 我们需要从给定的上下文中“提取”一个背包。
// 在这种情况下,这很简单,因为末影箱有一个
// 可以从玩家那里获取的共享背包。
(inventory, slot, player) -> player.getEnderChestInventory(),
// 虽然这绝对可以是一个谓词 -
// `(inventory, slot, player) -> inventory.getStack(slot).isOf(Items.ENDER_CHEST)`,
// 但这种形式更受青睐。
Items.ENDER_CHEST
);
}
}
就这样!你应该能够打开游戏,将鼠标悬停在背包中的末影箱上,按下 k,这将会弹出背包编辑界面。
接下来,让我们建立一些规则,以确保我们的背包查看器公平且不赖皮地运行。要编辑末影箱背包,玩家应该:
- 站在地面上,并且
- 手持带有精准采集附魔的镐,或者
- 处于创造模式。
为了实现这一点,我们将使用 InventoryValidators 类,其中包含一些有用的预定义背包验证器。请记住,你随时可以从头开始创建新的验证器。
public class MyMod implements PackedInventoryInitializer {
@Override
public void registerInventoryViewers(InventoryViewerRegistry registry, PackedInventoryApiConfig config) {
registry.register(
(inventory, slot, player) -> player.getEnderChestInventory(),
// isInCreative || isOnGround && hasSilkTouch
InventoryValidators.IS_IN_CREATIVE.or(
InventoryValidators.IS_ON_GROUND.and(InventoryValidators.HAS_PICKAXE_WITH_SILK_TOUCH)
),
Items.ENDER_CHEST
);
}
}
我们快成功了!现在,当你尝试在半空中和/或不手持带有精准采集附魔的镐时打开末影箱,将会看到一条友好的错误消息。但是,一旦你切换到创造模式,所有限制都将消失。
最后要做的一件事是让我们的背包查看器可配置。毕竟,我们有 config 参数,这是有原因的 ;)
public class MyMod implements PackedInventoryInitializer {
@Override
public void registerInventoryViewers(InventoryViewerRegistry registry, PackedInventoryApiConfig config) {
// 让我们为末影箱物品注册一个验证配置条目。
// API 提供了这些预定义配置(尽管你可以创建新的):
// - ValidationConfig:可以启用/禁用。
// - GenericValidationConfig:扩展 ValidationConfig,定义了在地面上的规则以及抑制对创造模式玩家的验证。
// - SilkTouchableGenericValidationConfig:扩展 GenericValidationConfig,定义了背包中拥有精准采集工具的规定。
config.registerValidationConfig(Items.ENDER_CHEST, SilkTouchableGenericValidationConfig::new);
// 用户可以在配置中完全禁用背包查看器。
var isEnabled = InventoryValidators.config(Items.ENDER_CHEST, config, ValidationConfig.DEFAULT, ValidationConfig::isEnabled);
// 仅当配置允许时才抑制对创造模式玩家的验证。
var isInCreative = InventoryValidators.config(Items.ENDER_CHEST, config, GenericValidationConfig.DEFAULT, GenericValidationConfig::isSuppressedInCreative).and(InventoryValidators.IS_IN_CREATIVE);
// 仅当配置允许时才要求玩家在地面上。
var isOnGround = InventoryValidators.config(Items.ENDER_CHEST, config, GenericValidationConfig.DEFAULT, x -> !x.requiresPlayerOnGround()).or(InventoryValidators.IS_ON_GROUND);
// 仅当配置允许时才要求玩家背包中有精准采集工具。
var hasSilkTouch = InventoryValidators.config(Items.ENDER_CHEST, config, SilkTouchableGenericValidationConfig.DEFAULT, x -> !x.requiresSilkTouch()).or(InventoryValidators.HAS_PICKAXE_WITH_SILK_TOUCH);
registry.register(
(inventory, slot, player) -> player.getEnderChestInventory(),
isEnabled.and(isInCreative.or(isOnGround.and(hasSilkTouch))),
Items.ENDER_CHEST
);
}
}
这样,所有限制都可以通过 ModMenu 或直接在配置文件中进行配置。
之后,你就成功地将一个物品与 Packed Inventory 集成完毕。恭喜!
背包视图处理器
我们已经了解了背包视图,但那个背包编辑界面是从哪里来的?那就是 InventoryViewHandler 的用武之地。
大多数情况下,如果你的背包满足以下条件,则无需注册自定义处理器:
- 实现了
NamedScreenHandlerFactory,或者 - 实现了
ScreenHandlerFactory,或者 - 具有可由
GenericContainerScreenHandler处理的常规大小 (即 9、18、27、36、45 或 54)。
但是,和往常一样,你可以注册自己的 InventoryViewHandler:
public class MyMod implements PackedInventoryInitializer {
@Override
public void registerInventoryViewHandlers(InventoryViewHandlerRegistry registry, PackedInventoryApiConfig config) {
registry.register(
(inventoryView, parentInventory, slot, player) -> {
var name = parentInventory.getStack(slot).getName();
var playerInventory = player.getInventory();
var namedFactory = new SimpleNamedScreenHandlerFactory((sId, inv, p) -> new GenericContainerScreenHandler(ScreenHandlerType.GENERIC_9X3, sId, playerInventory, inventoryView, 3), name);
player.openHandledScreen(namedFactory);
},
Items.ENDER_CHEST
);
}
}
请注意,你不仅限于打开一个处理界面;你可以对提供的背包视图做任何你想做的事情。
背包验证失败处理器
我们可以自定义背包视图的处理,那么失败处理呢?当然,你也可以调整。
默认情况下,错误会发送到相应玩家的操作栏,但你可以更改此行为:
public class MyMod implements PackedInventoryInitializer {
@Override
public void registerInventoryValidationFailureHandlers(InventoryValidationFailureHandlerRegistry registry, PackedInventoryApiConfig config) {
registry.register(
(failureReason, inventory, slot, player) -> {
var text = failureReason.toText();
if (text != null) {
player.sendMessage(text, false);
}
},
Items.ENDER_CHEST
);
}
}
悬浮提示
没有描述性悬浮提示的背包管理算什么?让我们使用 TooltipProvider 为末影箱创建一个!
// 请注意,悬浮提示完全是客户端的,所以这里我们使用
// `PackedInventoryClientInitializer` 而不是 `PackedInventoryInitializer`。
public class MyClientMod implements PackedInventoryClientInitializer {
@Override
public void registerTooltipProviders(TooltipProviderRegistry registry, PackedInventoryApiConfig config) {
registry.register(
TooltipProvider.builder()
.tooltipText((stack, context) -> List.of(Text.of("这是一个末影箱")))
.build()
Items.ENDER_CHEST
);
}
}
这样,末影箱的提示将被替换为文本“这是一个末影箱”。然而,这并没有帮助,不是吗?末影箱的问题在于客户端没有任何关于其内容的信息。那么,这是死胡同吗?当然不是。我们将使用一些魔法:
public class MyClientMod implements PackedInventoryClientInitializer {
@Override
public void registerTooltipProviders(TooltipProviderRegistry registry, PackedInventoryApiConfig config) {
registry.register(
TooltipProvider.builder()
.useSyncData(GenericContainerTooltipSyncData::of)
.tooltipData((stack, context, syncData) -> GenericContainerTooltipData.of(syncData.getInventory()))
.build()
Items.ENDER_CHEST
);
}
}
在指定我们的 TooltipProvider 需要 TooltipSyncData (在这种情况下,我使用预定义的 GenericContainerTooltipSyncData,因为我们只关心末影箱的背包) 之后,我们可以在后续的 tooltipData、tooltipText 等调用中使用它。我们将稍后深入探讨 TooltipSyncData;现在,让我们假设一切都能正常工作。
请注意,我们用 GenericContainerTooltipData 覆盖了末影箱的 TooltipData。如果你不熟悉原版对此类事物的处理方式,当物品提供 TooltipData 时,Minecraft 会寻找相应的 TooltipComponent。此组件允许你在提示中渲染任何你想要的内容。GenericContainerTooltipData 由 API 提供,因此你无需担心为其向游戏提供提示组件。但是,如果你想使用自定义提示数据,你需要像这样通过 Fabric API 手动注册一个提示组件:
TooltipComponentCallback.EVENT.register(tooltipData -> {
if (tooltipData instanceof MyTooltipData) {
return new MyTooltipComponent((MyTooltipData)tooltipData);
}
return null;
});
好了,现在我们有了一个花哨的提示,可以显示末影箱的内容。再次,是时候让一切可配置了:
public class MyClientMod implements PackedInventoryClientInitializer {
@Override
public void registerTooltipProviders(TooltipProviderRegistry registry, PackedInventoryApiConfig config) {
// 让我们为末影箱物品注册一个提示配置条目。
// API 提供了这些预定义配置(尽管你可以创建新的):
// - TooltipConfig:可以启用/禁用;紧凑模式可以开启或关闭。
// - GenericTooltipConfig:扩展 TooltipConfig,定义了容器常用的属性。
// - GenericSyncedTooltipConfig:扩展 GenericTooltipConfig,定义了需要同步数据的提示提供者使用的 `syncInterval` 属性。
config.registerTooltipConfig(Items.ENDER_CHEST, GenericSyncedTooltipConfig::new);
registry.register(
TooltipProvider.builder()
// 提示可以在配置中或通过按键(默认为 `Left Shift`)启用/禁用
.when((stack, context) -> config.getTooltipConfigOrDefault(stack.getItem()).isEnabled())
.useSyncData(GenericContainerTooltipSyncData::of)
.tooltipData((stack, context, syncData) -> {
var cfg = config.getTooltipConfigOrDefault(stack.getItem());
var inventory = syncData.getInventory();
if (!cfg.shouldShowWhenEmpty() && inventory.isEmpty()) {
return null;
}
var color = cfg.usePredefinedColor() ? DyeColor.GRAY : cfg.color();
if (cfg.isCompact()) {
return GenericContainerTooltipData.ofZipped(inventory, cfg.rows(), cfg.columns(), color);
} else {
return GenericContainerTooltipData.of(inventory, cfg.rows(), cfg.columns(), color);
}
})
// 使此 TooltipProvider 的同步间隔可配置
.syncInterval(stack -> config.getTooltipConfigOrDefault(stack.getItem(), GenericSyncedTooltipConfig.DEFAULT).syncInterval())
.build(),
Items.ENDER_CHEST
);
}
}
提示同步数据提供者
如前所述,为了使上面的示例工作,我们需要来自服务器的一些信息。这就是 TooltipSyncData 和 TooltipSyncDataProviders 的用武之地。
我们在末影箱的提示提供者中已经使用了 GenericContainerTooltipSyncData,所以让我们回到服务器端,教它如何处理它:
public class MyMod implements PackedInventoryInitializer {
@Override
public void registerTooltipSyncDataProviders(TooltipSyncDataProviderRegistry registry, PackedInventoryApiConfig config) {
registry.register(
// 在服务器端,我们需要创建相同的 TooltipSyncData
// 并用客户端不存在的内容填充它。
// 其他一切将由 Packed Inventory 自动处理。
(stack, player) -> GenericContainerTooltipSyncData.of(player.getEnderChestInventory()),
Items.ENDER_CHEST
);
}
}
只需几行代码,一切都能按预期工作。
安装
要求:
- Minecraft
1.20.x - Fabric Loader
>=0.15.0 - Fabric API
>=0.83.0
你可以从以下位置下载模组:
- GitHub Releases
- Modrinth
- CurseForge
- GitHub Actions (这些构建可能不稳定,但它们代表了开发的实际状态)
从源码构建
要求:
- JDK
17
Linux/MacOS
git clone https://github.com/Kir-Antipov/packed-inventory.git
cd packed-inventory
chmod +x ./gradlew
./gradlew build
cd build/libs
Windows
git clone https://github.com/Kir-Antipov/packed-inventory.git
cd packed-inventory
gradlew build
cd build/libs
正在加载版本记录…


















正在加载评论…
评论在新手盒子客户端中发表,这里同步展示。