Give Command Handling
Overview
In vanilla Minecraft, the /give command is hardcoded with safety checks designed around small stack sizes (up to 100 stacks of item max stack size). When stack sizes are adjusted to thousands or millions, running /give without modification can cause memory exhaustion or drop massive item entities.
🛠️ Ground-Truth Command Helper Logic
GiveCommandMixin intercepts GiveCommand.giveItem and delegates execution to GiveCommandHelper.giveItem:
java
public class GiveCommandHelper {
public static int giveItem(CommandSourceStack source, ItemInput input, Collection<ServerPlayer> players, int count) throws CommandSyntaxException {
ItemStack prototypeItemStack = input.createItemStack(1);
int maxStackSize = prototypeItemStack.getMaxStackSize();
long maxAllowedCountLong = (long) maxStackSize * 100;
if (count > maxAllowedCountLong) {
int displayCount = (int) Math.min(maxAllowedCountLong, Integer.MAX_VALUE);
source.sendFailure(Component.translatable("commands.give.failed.toomanyitems", displayCount, prototypeItemStack.getDisplayName()));
return 0;
}
for (ServerPlayer player : players) {
int remaining = count;
while (remaining > 0) {
ItemEntity drop;
int size = Math.min(maxStackSize, remaining);
remaining -= size;
ItemStack copyToDrop = prototypeItemStack.copyWithCount(size);
boolean added = player.getInventory().add(copyToDrop);
if (!added || !copyToDrop.isEmpty()) {
drop = player.drop(copyToDrop, false);
if (drop == null) continue;
drop.setNoPickUpDelay();
drop.setTarget(player.getUUID());
continue;
}
drop = player.drop(prototypeItemStack.copy(), false);
if (drop != null) {
drop.makeFakeItem();
}
player.level().playSound(null, player.getX(), player.getY(), player.getZ(),
SoundEvents.ITEM_PICKUP, SoundSource.PLAYERS, 0.2f,
((player.getRandom().nextFloat() - player.getRandom().nextFloat()) * 0.7f + 1.0f) * 2.0f);
player.containerMenu.broadcastChanges();
}
}
...
}
}🧮 100x Multiplier Dynamic Cap
To prevent accidental command inputs (e.g. /give @p diamond 2000000000) from locking up the server, GiveCommandHelper enforces a dynamic maximum allowed give count:
$$\text{maxAllowedCount} = \text{maxStackSize} \times 100$$
Example Dynamic Limits
| Modified Stack Limit ($L$) | /give Max Allowed Item Count |
|---|---|
| 64 | $6,400$ |
| 128 | $12,800$ |
| 1,000 | $100,000$ |
| 1,000,000 | $100,000,000$ |
