diff --git a/api/src/main/java/com/viaversion/viaversion/api/configuration/ViaVersionConfig.java b/api/src/main/java/com/viaversion/viaversion/api/configuration/ViaVersionConfig.java index ab564277a..aae080b9d 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/configuration/ViaVersionConfig.java +++ b/api/src/main/java/com/viaversion/viaversion/api/configuration/ViaVersionConfig.java @@ -457,4 +457,11 @@ public interface ViaVersionConfig extends Config { * @return the value sent to 1.19+ clients on join */ boolean enforceSecureChat(); + + /** + * Handles items with invalid count values (higher than max stack size) on 1.20.3 servers. + * + * @return true if enabled + */ + boolean handleInvalidItemCount(); } diff --git a/common/src/main/java/com/viaversion/viaversion/configuration/AbstractViaConfig.java b/common/src/main/java/com/viaversion/viaversion/configuration/AbstractViaConfig.java index fb3cf95ba..7800ab8d1 100644 --- a/common/src/main/java/com/viaversion/viaversion/configuration/AbstractViaConfig.java +++ b/common/src/main/java/com/viaversion/viaversion/configuration/AbstractViaConfig.java @@ -90,6 +90,7 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf private boolean cache1_17Light; private boolean translateOcelotToCat; private boolean enforceSecureChat; + private boolean handleInvalidItemCount; protected AbstractViaConfig(final File configFile, final Logger logger) { super(configFile, logger); @@ -159,6 +160,7 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf cache1_17Light = getBoolean("cache-1_17-light", true); translateOcelotToCat = getBoolean("translate-ocelot-to-cat", true); enforceSecureChat = getBoolean("enforce-secure-chat", false); + handleInvalidItemCount = getBoolean("handle-invalid-item-count", false); } private BlockedProtocolVersions loadBlockedProtocolVersions() { @@ -535,4 +537,9 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf public boolean enforceSecureChat() { return enforceSecureChat; } + + @Override + public boolean handleInvalidItemCount() { + return handleInvalidItemCount; + } } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/data/MaxStackSize1_20_3.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/data/MaxStackSize1_20_3.java new file mode 100644 index 000000000..f98228853 --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/data/MaxStackSize1_20_3.java @@ -0,0 +1,79 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2016-2024 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data; + +import java.util.HashMap; +import java.util.Map; + +public final class MaxStackSize1_20_3 { + + private static final Map mapping = new HashMap<>(); + + static { + fill(521, 537, 1); + fill(764, 790, 1); + mapping.put(793, 1); + mapping.put(795, 1); + mapping.put(797, 1); + fill(814, 843, 1); + mapping.put(846, 1); + mapping.put(853, 1); + fill(854, 876, 1); + fill(883, 905, 16); + fill(906, 908, 1); + mapping.put(909, 16); + fill(911, 917, 1); + mapping.put(924, 16); + mapping.put(927, 1); + mapping.put(928, 1); + mapping.put(930, 1); + fill(960, 976, 1); + mapping.put(980, 1); + mapping.put(990, 16); + mapping.put(995, 1); + mapping.put(1085, 1); + mapping.put(1086, 16); + mapping.put(1107, 1); + mapping.put(1113, 1); + mapping.put(1116, 16); + fill(1117, 1120, 1); + mapping.put(1123, 1); + fill(1126, 1141, 16); + mapping.put(1149, 1); + mapping.put(1151, 1); + fill(1154, 1156, 1); + fill(1159, 1176, 1); + mapping.put(1178, 1); + mapping.put(1182, 1); + mapping.put(1183, 1); + fill(1185, 1191, 1); + mapping.put(1212, 16); + mapping.put(1256, 1); + } + + public static int getMaxStackSize(final int identifier) { + return mapping.getOrDefault(identifier, 64); + } + + private static void fill(final int start, final int end, final int value) { + for (int i = start; i <= end; i++) { + mapping.put(i, value); + } + } + +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/BlockItemPacketRewriter1_20_5.java b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/BlockItemPacketRewriter1_20_5.java index ef37ba84f..2ef61a497 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/BlockItemPacketRewriter1_20_5.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/v1_20_3to1_20_5/rewriter/BlockItemPacketRewriter1_20_5.java @@ -88,6 +88,7 @@ import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.BannerPatterns1_ import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.DyeColors; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.Enchantments1_20_5; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.EquipmentSlots1_20_5; +import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.MaxStackSize1_20_3; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.Instruments1_20_3; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.MapDecorations1_20_5; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.PotionEffects1_20_5; @@ -364,6 +365,14 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter MaxStackSize1_20_3.getMaxStackSize(structuredItem.identifier())) { + structuredItem.structuredData().set(StructuredDataKey.MAX_STACK_SIZE, structuredItem.amount()); + } + } return super.handleItemToClient(connection, structuredItem); } diff --git a/common/src/main/resources/assets/viaversion/config.yml b/common/src/main/resources/assets/viaversion/config.yml index aa2637a3b..1cdff3356 100644 --- a/common/src/main/resources/assets/viaversion/config.yml +++ b/common/src/main/resources/assets/viaversion/config.yml @@ -182,6 +182,9 @@ translate-ocelot-to-cat: false # It is not recommended to fake this value if your server is running 1.19 or later, as 1.20.5 have stricter chat handling and may get kicked otherwise. enforce-secure-chat: false # +# Handles items with invalid count values (higher than max stack size) on 1.20.3 servers. +handle-invalid-item-count: false +# #----------------------------------------------------------# # 1.9+ CLIENTS ON 1.8 SERVERS OPTIONS # #----------------------------------------------------------#