diff --git a/src/main/java/com/extendedae_plus/mixin/extendedae/container/ContainerExPatternProviderMixin.java b/src/main/java/com/extendedae_plus/mixin/extendedae/container/ContainerExPatternProviderMixin.java index 94fe85a..3b09bf8 100644 --- a/src/main/java/com/extendedae_plus/mixin/extendedae/container/ContainerExPatternProviderMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/extendedae/container/ContainerExPatternProviderMixin.java @@ -134,10 +134,12 @@ public abstract class ContainerExPatternProviderMixin extends PatternProviderMen } else { for (var stack : stacks) { if (stack != null) { - long upper = 999999L * stack.what().getAmountPerUnit(); - if (stack.amount() * scale > upper) { + long amt = stack.amount(); + // 先检查乘法是否会导致超出 Long.MAX_VALUE,避免溢出 + if (amt > Integer.MAX_VALUE / scale) { return false; } + // 已移除原有的业务上限检查(999999 * amountPerUnit),仅保留溢出检查 } } return true; @@ -150,7 +152,18 @@ public abstract class ContainerExPatternProviderMixin extends PatternProviderMen var stack = src[i]; if (stack != null) { long amt = stack.amount(); - long newAmt = div ? (amt / scale) : (amt * scale); + long newAmt; + if (div) { + newAmt = amt / scale; + } else { + // 防御性检查:虽然上游已检查过,但在此处再次确保不会溢出 + if (amt > Integer.MAX_VALUE / scale) { + // 遇到潜在溢出时跳过该项(保持原样为 null),调用方已通过 eap$checkModify 避免进入此分支 + dst[i] = null; + continue; + } + newAmt = amt * scale; + } dst[i] = new GenericStack(stack.what(), newAmt); } else { dst[i] = null; diff --git a/src/main/java/com/extendedae_plus/util/NumberFormatUtil.java b/src/main/java/com/extendedae_plus/util/NumberFormatUtil.java index 760b7be..b98d30d 100644 --- a/src/main/java/com/extendedae_plus/util/NumberFormatUtil.java +++ b/src/main/java/com/extendedae_plus/util/NumberFormatUtil.java @@ -1,5 +1,7 @@ package com.extendedae_plus.util; +import java.text.DecimalFormat; + /** * 数字格式化工具类,提供大数字和小数的格式化功能 */ @@ -7,46 +9,59 @@ public class NumberFormatUtil { private NumberFormatUtil() {throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");} /** - * 格式化数字,将大数字转换为k、m等格式 - * 支持小数显示,小数点后为0则不显示0 + * 格式化数字,将大数字转换为 k、M、G 等格式(物品用整数/一位小数显示规则) * @param number 要格式化的数字 * @return 格式化后的字符串 */ public static String formatNumber(long number) { if (number < 1000) { return String.valueOf(number); - } else if (number < 1000000) { - double value = number / 1000.0; - return formatDecimal(value, "k"); - } else { - double value = number / 1000000.0; - return formatDecimal(value, "m"); } + + String[] preFixes = new String[]{"k", "M", "G", "T", "P", "E", "Z", "Y"}; + double value = number; + String level = ""; + + for (int offset = 0; value >= 1000.0 && offset < preFixes.length; ++offset) { + value /= 1000.0; + level = preFixes[offset]; + } + + return formatDecimal(value, level); } /** - * 格式化带小数的数字,支持流体等需要显示小数的场景 + * 格式化带小数的数字,支持流体等需要显示小数的场景(保留至多两位小数) + * 流体显示规则不同于物品,统一使用两位小数的 DecimalFormat * @param value 小数值 * @return 格式化后的字符串 */ public static String formatNumberWithDecimal(double value) { if (value < 1000) { + DecimalFormat smallDf = new DecimalFormat("#.##"); + // 小于1000时,若是整数则显示整数,否则显示最多两位小数 if (value == (long) value) { return String.valueOf((long) value); } else { - return String.format("%.1f", value).replaceAll("\\.0$", ""); + return smallDf.format(value); } - } else if (value < 1000000) { - return formatDecimal(value / 1000.0, "k"); - } else { - return formatDecimal(value / 1000000.0, "m"); } + + String[] preFixes = new String[]{"k", "M", "G", "T", "P", "E", "Z", "Y"}; + String level = ""; + for (int offset = 0; value >= 1000.0 && offset < preFixes.length; ++offset) { + value /= 1000.0; + level = preFixes[offset]; + } + + DecimalFormat df = new DecimalFormat("#.##"); + return df.format(value) + level; } /** - * 格式化小数,如果小数点后为0则不显示0 + * 格式化小数(物品显示规则):如果小数点后接近 0 则显示为整数,否则显示一位小数 * @param value 小数值 - * @param suffix 后缀(k、m、g等) + * @param suffix 后缀(k、M、G 等) * @return 格式化后的字符串 */ private static String formatDecimal(double value, String suffix) { @@ -54,9 +69,9 @@ public class NumberFormatUtil { if (Math.abs(value - Math.round(value)) < 0.001) { return String.valueOf(Math.round(value)) + suffix; } else { - // 修复重复后缀问题:先格式化数字,再添加后缀 + // 使用一位小数显示,去掉末尾 .0 String formatted = String.format("%.1f", value).replaceAll("\\.0$", ""); return formatted + suffix; } } -} \ No newline at end of file +} \ No newline at end of file