Skip to content

Защита от переполнения большого сундука

Проблема целочисленного переполнения

В Java и Minecraft вычисления предметов используют 32-битные знаковые целые числа (int). Максимальное представимое значение: $$I_{\max} = 2^{31} - 1 = 2,147,483,647$$

Когда большой сундук (54 слота) заполнен максимальными стаками, расчет суммы предметов внутри складывает все 54 слота.


🧮 Расчет порога безопасности

Если в каждом из 54 слотов лежит стак размера $L$: $$\text{Всего предметов в сундуке} = 54 \times L$$

Чтобы сумма не превысила $I_{\max}$: $$54 \times L \le 2,147,483,647$$ $$L \le \frac{2,147,483,647}{54} \approx 39,768,215.68$$

Таким образом, абсолютный безопасный порог стака составляет: $$L_{\text{safe}} = 39,768,215$$

Таблица последствий переполнения

Лимит стака ($L$)Всего предметов в сундукеСтатус числаРиск
128 (По умолчанию)$6,912$Безопасно ($< 2.14\text{ млрд}$)Нет риска
1,000,000$54,000,000$Безопасно ($< 2.14\text{ млрд}$)Нет риска
39,768,215$2,147,483,610$Безопасно ($< 2.14\text{ млрд}$)Рекомендуемый максимальный порог
40,000,000$2,160,000,000$Переполнение! (Переходит в $-2,134,967,296$)Пропадание предметов / сбой контейнера

🛠️ Быстрый крафт с двойной точностью

В AbstractContainerMenuMixin расчет быстрого распределения предметов переписан на 64-битную арифметику с плавающей точкой (double), что исключает потерю точности и уход в отрицательные числа:

java
@Mixin(AbstractContainerMenu.class)
public class AbstractContainerMenuMixin {
    @Overwrite
    public static int getQuickCraftPlaceCount(int quickCraftSlotsSize, int quickCraftingType, ItemStack itemStack) {
        return switch (quickCraftingType) {
            case 0 -> (int) ((double) itemStack.getCount() / (double) quickCraftSlotsSize);
            case 1 -> 1;
            case 2 -> itemStack.getMaxStackSize();
            default -> itemStack.getCount();
        };
    }
}

Official documentation & web portal for Dasik Igaijinn mods.