From e6c9c519c9fb9cac1bbe1a1ea210f698ec1adba5 Mon Sep 17 00:00:00 2001 From: Eclipse Date: Fri, 10 May 2024 17:44:06 +0000 Subject: [PATCH 01/21] Move some functionality from non vanilla custom items to vanilla custom items - updating implementation soon --- .../api/item/custom/CustomItemData.java | 112 ++++++++++++++ .../item/custom/NonVanillaCustomItemData.java | 140 ------------------ 2 files changed, 112 insertions(+), 140 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java index 3b871cd74c5..4d8de7c9a07 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.api.item.custom; +import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.api.GeyserApi; @@ -114,6 +115,89 @@ public interface CustomItemData { */ @NonNull Set tags(); + /** + * Gets the stack size of the item. + * + * @return the stack size of the item + */ + @NonNegative + int stackSize(); + + /** + * Gets the max damage of the item. + * + * @return the max damage of the item + */ + int maxDamage(); + + /** + * Gets the attack damage of the item. + * This is purely visual, and only applied to tools + * + * @return the attack damage of the item + */ + int attackDamage(); + + /** + * Gets the tool type of the item. + * + * @return the tool type of the item + */ + @Nullable String toolType(); + + /** + * Gets the tool tier of the item. + * + * @return the tool tier of the item + */ + @Nullable String toolTier(); + + /** + * Gets the item's translation string. + * + * @return the item's translation string + */ + @Nullable String translationString(); + + /** + * Gets the armor protection value of the item. + * + * @return the armor protection value of the item + */ + int protectionValue(); + + /** + * Gets if the item is a foil. This is used to determine if the item should be rendered with an enchantment glint effect. + * + * @return if the item is a foil + */ + boolean isFoil(); + + /** + * Gets if the item is edible. + * + * @return if the item is edible + */ + boolean isEdible(); + + /** + * Gets if the food item can always be eaten. + * + * @return if the item is allowed to be eaten all the time + */ + boolean canAlwaysEat(); + + /** + * @deprecated Use {@link #displayHandheld()} instead. + * Gets if the item is a tool. This is used to set the render type of the item, if the item is handheld. + * + * @return if the item is a tool + */ + @Deprecated + default boolean isTool() { + return displayHandheld(); + } + static CustomItemData.Builder builder() { return GeyserApi.api().provider(CustomItemData.Builder.class); } @@ -144,6 +228,34 @@ interface Builder { Builder tags(@Nullable Set tags); + Builder stackSize(@NonNegative int stackSize); + + Builder maxDamage(int maxDamage); + + Builder attackDamage(int attackDamage); + + Builder toolType(@Nullable String toolType); + + Builder toolTier(@Nullable String toolTier); + + Builder protectionValue(int protectionValue); + + Builder translationString(@Nullable String translationString); + + Builder foil(boolean isFoil); + + Builder edible(boolean isEdible); + + Builder canAlwaysEat(boolean canAlwaysEat); + + /** + * @deprecated Use {@link #displayHandheld(boolean)} instead. + */ + @Deprecated + default Builder tool(boolean isTool) { + return displayHandheld(isTool); + } + CustomItemData build(); } } diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java index 2c283780cc1..19703d21ecd 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java @@ -50,42 +50,6 @@ public interface NonVanillaCustomItemData extends CustomItemData { */ @NonNegative int javaId(); - /** - * Gets the stack size of the item. - * - * @return the stack size of the item - */ - @NonNegative int stackSize(); - - /** - * Gets the max damage of the item. - * - * @return the max damage of the item - */ - int maxDamage(); - - /** - * Gets the attack damage of the item. - * This is purely visual, and only applied to tools - * - * @return the attack damage of the item - */ - int attackDamage(); - - /** - * Gets the tool type of the item. - * - * @return the tool type of the item - */ - @Nullable String toolType(); - - /** - * Gets the tool tier of the item. - * - * @return the tool tier of the item - */ - @Nullable String toolTier(); - /** * Gets the armor type of the item. * @@ -93,20 +57,6 @@ public interface NonVanillaCustomItemData extends CustomItemData { */ @Nullable String armorType(); - /** - * Gets the armor protection value of the item. - * - * @return the armor protection value of the item - */ - int protectionValue(); - - /** - * Gets the item's translation string. - * - * @return the item's translation string - */ - @Nullable String translationString(); - /** * Gets the repair materials of the item. * @@ -122,27 +72,6 @@ public interface NonVanillaCustomItemData extends CustomItemData { */ boolean isHat(); - /** - * Gets if the item is a foil. This is used to determine if the item should be rendered with an enchantment glint effect. - * - * @return if the item is a foil - */ - boolean isFoil(); - - /** - * Gets if the item is edible. - * - * @return if the item is edible - */ - boolean isEdible(); - - /** - * Gets if the food item can always be eaten. - * - * @return if the item is allowed to be eaten all the time - */ - boolean canAlwaysEat(); - /** * Gets if the item is chargable, like a bow. * @@ -150,17 +79,6 @@ public interface NonVanillaCustomItemData extends CustomItemData { */ boolean isChargeable(); - /** - * @deprecated Use {@link #displayHandheld()} instead. - * Gets if the item is a tool. This is used to set the render type of the item, if the item is handheld. - * - * @return if the item is a tool - */ - @Deprecated - default boolean isTool() { - return displayHandheld(); - } - /** * Gets the block the item places. * @@ -180,74 +98,16 @@ interface Builder extends CustomItemData.Builder { Builder javaId(@NonNegative int javaId); - Builder stackSize(@NonNegative int stackSize); - - Builder maxDamage(int maxDamage); - - Builder attackDamage(int attackDamage); - - Builder toolType(@Nullable String toolType); - - Builder toolTier(@Nullable String toolTier); - Builder armorType(@Nullable String armorType); - Builder protectionValue(int protectionValue); - - Builder translationString(@Nullable String translationString); - Builder repairMaterials(@Nullable Set repairMaterials); Builder hat(boolean isHat); - Builder foil(boolean isFoil); - - Builder edible(boolean isEdible); - - Builder canAlwaysEat(boolean canAlwaysEat); - Builder chargeable(boolean isChargeable); Builder block(String block); - /** - * @deprecated Use {@link #displayHandheld(boolean)} instead. - */ - @Deprecated - default Builder tool(boolean isTool) { - return displayHandheld(isTool); - } - - @Override - Builder creativeCategory(int creativeCategory); - - @Override - Builder creativeGroup(@Nullable String creativeGroup); - - @Override - Builder customItemOptions(@NonNull CustomItemOptions customItemOptions); - - @Override - Builder displayName(@NonNull String displayName); - - @Override - Builder icon(@NonNull String icon); - - @Override - Builder allowOffhand(boolean allowOffhand); - - @Override - Builder displayHandheld(boolean displayHandheld); - - @Override - Builder textureSize(int textureSize); - - @Override - Builder renderOffsets(@Nullable CustomRenderOffsets renderOffsets); - - @Override - Builder tags(@Nullable Set tags); - NonVanillaCustomItemData build(); } } From 9cd847e1e9918fac00753bcae48acb04c14957de Mon Sep 17 00:00:00 2001 From: Eclipse Date: Fri, 10 May 2024 20:10:30 +0000 Subject: [PATCH 02/21] Update implementations --- .../geyser/item/GeyserCustomItemData.java | 180 +++++++++++++++--- .../item/GeyserNonVanillaCustomItemData.java | 155 +-------------- 2 files changed, 157 insertions(+), 178 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java index a2054f78a6b..3063ef8dcd7 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java @@ -37,6 +37,7 @@ import java.util.Objects; import java.util.OptionalInt; import java.util.Set; +import org.geysermc.geyser.api.item.custom.NonVanillaCustomItemData; @EqualsAndHashCode @ToString @@ -52,29 +53,39 @@ public class GeyserCustomItemData implements CustomItemData { private final int textureSize; private final CustomRenderOffsets renderOffsets; private final Set tags; + private final int stackSize; + private final int maxDamage; + private final int attackDamage; + private final String toolType; + private final String toolTier; + private final String translationString; + private final int protectionValue; + private final boolean isFoil; + private final boolean isEdible; + private final boolean canAlwaysEat; - public GeyserCustomItemData(String name, - CustomItemOptions customItemOptions, - String displayName, - String icon, - boolean allowOffhand, - boolean displayHandheld, - OptionalInt creativeCategory, - String creativeGroup, - int textureSize, - CustomRenderOffsets renderOffsets, - Set tags) { - this.name = name; - this.customItemOptions = customItemOptions; - this.displayName = displayName; - this.icon = icon; - this.allowOffhand = allowOffhand; - this.displayHandheld = displayHandheld; - this.creativeCategory = creativeCategory; - this.creativeGroup = creativeGroup; - this.textureSize = textureSize; - this.renderOffsets = renderOffsets; - this.tags = tags; + public GeyserCustomItemData(Builder builder) { + this.name = builder.name; + this.customItemOptions = builder.customItemOptions; + this.displayName = builder.displayName; + this.icon = builder.icon; + this.allowOffhand = builder.allowOffhand; + this.displayHandheld = builder.displayHandheld; + this.creativeCategory = builder.creativeCategory; + this.creativeGroup = builder.creativeGroup; + this.textureSize = builder.textureSize; + this.renderOffsets = builder.renderOffsets; + this.tags = builder.tags; + this.stackSize = builder.stackSize; + this.maxDamage = builder.maxDamage; + this.attackDamage = builder.attackDamage; + this.toolType = builder.toolType; + this.toolTier = builder.toolTier; + this.translationString = builder.translationString; + this.protectionValue = builder.protectionValue; + this.isFoil = builder.foil; + this.isEdible = builder.edible; + this.canAlwaysEat = builder.canAlwaysEat; } @Override @@ -132,6 +143,56 @@ public CustomRenderOffsets renderOffsets() { return tags; } + @Override + public int stackSize() { + return stackSize; + } + + @Override + public int maxDamage() { + return maxDamage; + } + + @Override + public int attackDamage() { + return attackDamage; + } + + @Override + public String toolType() { + return toolType; + } + + @Override + public String toolTier() { + return toolTier; + } + + @Override + public int protectionValue() { + return protectionValue; + } + + @Override + public String translationString() { + return translationString; + } + + @Override + public boolean isFoil() { + return isFoil; + } + + @Override + public boolean isEdible() { + return isEdible; + } + + @Override + public boolean canAlwaysEat() { + return canAlwaysEat; + } + public static class Builder implements CustomItemData.Builder { protected String name = null; protected CustomItemOptions customItemOptions = null; @@ -144,6 +205,17 @@ public static class Builder implements CustomItemData.Builder { protected int textureSize = 16; protected CustomRenderOffsets renderOffsets = null; protected Set tags = new HashSet<>(); + private int stackSize = 64; + private int maxDamage = 0; + private int attackDamage = 0; + private String toolType = null; + private String toolTier = null; + private int protectionValue = 0; + private String translationString; + private boolean foil = false; + private boolean tool = false; + private boolean edible = false; + private boolean canAlwaysEat = false; @Override public Builder name(@NonNull String name) { @@ -211,6 +283,66 @@ public Builder tags(@Nullable Set tags) { return this; } + @Override + public Builder stackSize(int stackSize) { + this.stackSize = stackSize; + return this; + } + + @Override + public Builder maxDamage(int maxDamage) { + this.maxDamage = maxDamage; + return this; + } + + @Override + public Builder attackDamage(int attackDamage) { + this.attackDamage = attackDamage; + return this; + } + + @Override + public Builder toolType(@Nullable String toolType) { + this.toolType = toolType; + return this; + } + + @Override + public Builder toolTier(@Nullable String toolTier) { + this.toolTier = toolTier; + return this; + } + + @Override + public Builder protectionValue(int protectionValue) { + this.protectionValue = protectionValue; + return this; + } + + @Override + public Builder translationString(@Nullable String translationString) { + this.translationString = translationString; + return this; + } + + @Override + public Builder foil(boolean isFoil) { + this.foil = isFoil; + return this; + } + + @Override + public Builder edible(boolean isEdible) { + this.edible = isEdible; + return this; + } + + @Override + public Builder canAlwaysEat(boolean canAlwaysEat) { + this.canAlwaysEat = canAlwaysEat; + return this; + } + @Override public CustomItemData build() { if (this.name == null || this.customItemOptions == null) { @@ -223,8 +355,8 @@ public CustomItemData build() { if (this.icon == null) { this.icon = this.name; } - return new GeyserCustomItemData(this.name, this.customItemOptions, this.displayName, this.icon, this.allowOffhand, - this.displayHandheld, this.creativeCategory, this.creativeGroup, this.textureSize, this.renderOffsets, this.tags); + + return new GeyserCustomItemData(this); } } } diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java index 9c9269df363..160c74c10de 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java @@ -40,44 +40,20 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData implements NonVanillaCustomItemData { private final String identifier; private final int javaId; - private final int stackSize; - private final int maxDamage; - private final int attackDamage; - private final String toolType; - private final String toolTier; private final String armorType; - private final int protectionValue; - private final String translationString; private final Set repairMaterials; private final boolean isHat; - private final boolean isFoil; - private final boolean isTool; - private final boolean isEdible; - private final boolean canAlwaysEat; private final boolean isChargeable; private final String block; public GeyserNonVanillaCustomItemData(Builder builder) { - super(builder.name, builder.customItemOptions, builder.displayName, builder.icon, builder.allowOffhand, - builder.displayHandheld, builder.creativeCategory, builder.creativeGroup, - builder.textureSize, builder.renderOffsets, builder.tags); + super(builder); this.identifier = builder.identifier; this.javaId = builder.javaId; - this.stackSize = builder.stackSize; - this.maxDamage = builder.maxDamage; - this.attackDamage = builder.attackDamage; - this.toolType = builder.toolType; - this.toolTier = builder.toolTier; this.armorType = builder.armorType; - this.protectionValue = builder.protectionValue; - this.translationString = builder.translationString; this.repairMaterials = builder.repairMaterials; this.isHat = builder.hat; - this.isFoil = builder.foil; - this.isTool = builder.tool; - this.isEdible = builder.edible; - this.canAlwaysEat = builder.canAlwaysEat; this.isChargeable = builder.chargeable; this.block = builder.block; } @@ -92,46 +68,11 @@ public int javaId() { return javaId; } - @Override - public int stackSize() { - return stackSize; - } - - @Override - public int maxDamage() { - return maxDamage; - } - - @Override - public int attackDamage() { - return attackDamage; - } - - @Override - public String toolType() { - return toolType; - } - - @Override - public String toolTier() { - return toolTier; - } - @Override public @Nullable String armorType() { return armorType; } - @Override - public int protectionValue() { - return protectionValue; - } - - @Override - public String translationString() { - return translationString; - } - @Override public Set repairMaterials() { return repairMaterials; @@ -142,21 +83,6 @@ public boolean isHat() { return isHat; } - @Override - public boolean isFoil() { - return isFoil; - } - - @Override - public boolean isEdible() { - return isEdible; - } - - @Override - public boolean canAlwaysEat() { - return canAlwaysEat; - } - @Override public boolean isChargeable() { return isChargeable; @@ -170,28 +96,9 @@ public String block() { public static class Builder extends GeyserCustomItemData.Builder implements NonVanillaCustomItemData.Builder { private String identifier = null; private int javaId = -1; - - private int stackSize = 64; - - private int maxDamage = 0; - - private int attackDamage = 0; - - private String toolType = null; - private String toolTier = null; - private String armorType = null; - private int protectionValue = 0; - - private String translationString; - private Set repairMaterials; - private boolean hat = false; - private boolean foil = false; - private boolean tool = false; - private boolean edible = false; - private boolean canAlwaysEat = false; private boolean chargeable = false; private String block = null; @@ -253,54 +160,12 @@ public Builder javaId(int javaId) { return this; } - @Override - public Builder stackSize(int stackSize) { - this.stackSize = stackSize; - return this; - } - - @Override - public Builder maxDamage(int maxDamage) { - this.maxDamage = maxDamage; - return this; - } - - @Override - public NonVanillaCustomItemData.Builder attackDamage(int attackDamage) { - this.attackDamage = attackDamage; - return this; - } - - @Override - public Builder toolType(@Nullable String toolType) { - this.toolType = toolType; - return this; - } - - @Override - public Builder toolTier(@Nullable String toolTier) { - this.toolTier = toolTier; - return this; - } - @Override public Builder armorType(@Nullable String armorType) { this.armorType = armorType; return this; } - @Override - public Builder protectionValue(int protectionValue) { - this.protectionValue = protectionValue; - return this; - } - - @Override - public Builder translationString(@Nullable String translationString) { - this.translationString = translationString; - return this; - } - @Override public Builder repairMaterials(@Nullable Set repairMaterials) { this.repairMaterials = repairMaterials; @@ -323,24 +188,6 @@ public Builder hat(boolean isHat) { return this; } - @Override - public Builder foil(boolean isFoil) { - this.foil = isFoil; - return this; - } - - @Override - public Builder edible(boolean isEdible) { - this.edible = isEdible; - return this; - } - - @Override - public Builder canAlwaysEat(boolean canAlwaysEat) { - this.canAlwaysEat = canAlwaysEat; - return this; - } - @Override public Builder chargeable(boolean isChargeable) { this.chargeable = isChargeable; From 97e1bebcbd76927756af3dad4084327bd052805f Mon Sep 17 00:00:00 2001 From: Eclipse Date: Fri, 10 May 2024 21:08:21 +0000 Subject: [PATCH 03/21] Implement logic for new vanilla custom item components in custom item registry --- .../api/item/custom/CustomItemData.java | 6 ++++ .../geyser/item/GeyserCustomItemData.java | 4 +-- .../CustomItemRegistryPopulator.java | 33 ++++++++++++++----- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java index 4d8de7c9a07..26a5adc8d5d 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java @@ -118,6 +118,8 @@ public interface CustomItemData { /** * Gets the stack size of the item. * + * Returns 0 if not set. When not set (or 0), takes the Java item stack count when based of a vanilla item, or uses 64 when porting a modded item. + * * @return the stack size of the item */ @NonNegative @@ -126,6 +128,8 @@ public interface CustomItemData { /** * Gets the max damage of the item. * + * Returns -1 if not set. When not set (or below 0), takes the Java item max damage when based of a vanilla item, or uses 0 when porting a modded item. + * * @return the max damage of the item */ int maxDamage(); @@ -134,6 +138,8 @@ public interface CustomItemData { * Gets the attack damage of the item. * This is purely visual, and only applied to tools * + * Returns 0 if not set. When 0, takes the Java item attack damage when based of a vanilla item, or uses 0 when porting a modded item. + * * @return the attack damage of the item */ int attackDamage(); diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java index 3063ef8dcd7..dd95e3dc846 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java @@ -205,8 +205,8 @@ public static class Builder implements CustomItemData.Builder { protected int textureSize = 16; protected CustomRenderOffsets renderOffsets = null; protected Set tags = new HashSet<>(); - private int stackSize = 64; - private int maxDamage = 0; + private int stackSize = 0; + private int maxDamage = -1; private int attackDamage = 0; private String toolType = null; private String toolTier = null; diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java index 10d87a8a9d1..75d7fc2c681 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java @@ -131,8 +131,8 @@ public static NonVanillaItemRegistration registerCustomItem(NonVanillaCustomItem Set repairMaterials = customItemData.repairMaterials(); Item.Builder itemBuilder = Item.builder() - .stackSize(customItemData.stackSize()) - .maxDamage(customItemData.maxDamage()); + .stackSize(customItemData.stackSize() == 0 ? 64 : customItemData.stackSize()) + .maxDamage(Math.max(customItemData.maxDamage(), 0)); Item item = new Item(customIdentifier, itemBuilder) { @Override public boolean isValidRepairItem(Item other) { @@ -168,12 +168,24 @@ private static NbtMapBuilder createComponentNbt(CustomItemData customItemData, I NbtMapBuilder itemProperties = NbtMap.builder(); NbtMapBuilder componentBuilder = NbtMap.builder(); - setupBasicItemInfo(javaItem.maxDamage(), javaItem.maxStackSize(), mapping.getToolType() != null || customItemData.displayHandheld(), customItemData, itemProperties, componentBuilder, protocolVersion); + setupBasicItemInfo(customItemData.maxDamage() < 0 ? javaItem.maxDamage() : customItemData.maxDamage(), + customItemData.stackSize() == 0 ? javaItem.maxStackSize() : customItemData.stackSize(), + mapping.getToolType() != null || customItemData.displayHandheld(), + customItemData, itemProperties, componentBuilder, protocolVersion); boolean canDestroyInCreative = true; - if (mapping.getToolType() != null) { // This is not using the isTool boolean because it is not just a render type here. - canDestroyInCreative = computeToolProperties(mapping.getToolType(), itemProperties, componentBuilder, javaItem.attackDamage()); + String toolType = null; + if (mapping.getToolType() != null) { + toolType = mapping.getToolType(); + } else if (customItemData.toolType() != null) { + toolType = customItemData.toolType(); } + + if (toolType != null) { + canDestroyInCreative = computeToolProperties(toolType, itemProperties, componentBuilder, + customItemData.attackDamage() == 0 ? javaItem.attackDamage() : customItemData.attackDamage()); + } + itemProperties.putBoolean("can_destroy_in_creative", canDestroyInCreative); if (mapping.getArmorType() != null) { @@ -184,14 +196,18 @@ private static NbtMapBuilder createComponentNbt(CustomItemData customItemData, I computeBlockItemProperties(mapping.getBedrockIdentifier(), componentBuilder); } - if (mapping.isEdible()) { - computeConsumableProperties(itemProperties, componentBuilder, 1, false); + if (mapping.isEdible() || customItemData.isEdible()) { + computeConsumableProperties(itemProperties, componentBuilder, 1, customItemData.canAlwaysEat()); } if (mapping.isEntityPlacer()) { computeEntityPlacerProperties(componentBuilder); } + if (customItemData.isFoil()) { + itemProperties.putBoolean("foil", true); + } + switch (mapping.getBedrockIdentifier()) { case "minecraft:fire_charge", "minecraft:flint_and_steel" -> computeBlockItemProperties("minecraft:fire", componentBuilder); case "minecraft:bow", "minecraft:crossbow", "minecraft:trident" -> computeChargeableProperties(itemProperties, componentBuilder, mapping.getBedrockIdentifier(), protocolVersion); @@ -217,7 +233,8 @@ private static NbtMapBuilder createComponentNbt(NonVanillaCustomItemData customI NbtMapBuilder itemProperties = NbtMap.builder(); NbtMapBuilder componentBuilder = NbtMap.builder(); - setupBasicItemInfo(customItemData.maxDamage(), customItemData.stackSize(), displayHandheld, customItemData, itemProperties, componentBuilder, protocolVersion); + setupBasicItemInfo(Math.max(customItemData.maxDamage(), 0), customItemData.stackSize() == 0 ? 64 : customItemData.stackSize(), + displayHandheld, customItemData, itemProperties, componentBuilder, protocolVersion); boolean canDestroyInCreative = true; if (customItemData.toolType() != null) { // This is not using the isTool boolean because it is not just a render type here. From 965d11c7a122f341a6f0c4fe9b234136f0371248 Mon Sep 17 00:00:00 2001 From: Eclipse Date: Fri, 10 May 2024 21:23:46 +0000 Subject: [PATCH 04/21] Move armor type to super class and implement protection value and armor type in vanilla custom registry --- .../geyser/api/item/custom/CustomItemData.java | 9 +++++++++ .../item/custom/NonVanillaCustomItemData.java | 9 --------- .../geyser/item/GeyserCustomItemData.java | 16 ++++++++++++++-- .../item/GeyserNonVanillaCustomItemData.java | 14 -------------- .../populator/CustomItemRegistryPopulator.java | 12 +++++++++++- 5 files changed, 34 insertions(+), 26 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java index 26a5adc8d5d..5bb469abc89 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java @@ -165,6 +165,13 @@ public interface CustomItemData { */ @Nullable String translationString(); + /** + * Gets the armor type of the item. + * + * @return the armor type of the item + */ + @Nullable String armorType(); + /** * Gets the armor protection value of the item. * @@ -244,6 +251,8 @@ interface Builder { Builder toolTier(@Nullable String toolTier); + Builder armorType(@Nullable String armorType); + Builder protectionValue(int protectionValue); Builder translationString(@Nullable String translationString); diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java index 19703d21ecd..9a1a699c674 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java @@ -50,13 +50,6 @@ public interface NonVanillaCustomItemData extends CustomItemData { */ @NonNegative int javaId(); - /** - * Gets the armor type of the item. - * - * @return the armor type of the item - */ - @Nullable String armorType(); - /** * Gets the repair materials of the item. * @@ -98,8 +91,6 @@ interface Builder extends CustomItemData.Builder { Builder javaId(@NonNegative int javaId); - Builder armorType(@Nullable String armorType); - Builder repairMaterials(@Nullable Set repairMaterials); Builder hat(boolean isHat); diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java index dd95e3dc846..f1cf5088423 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java @@ -37,7 +37,6 @@ import java.util.Objects; import java.util.OptionalInt; import java.util.Set; -import org.geysermc.geyser.api.item.custom.NonVanillaCustomItemData; @EqualsAndHashCode @ToString @@ -59,6 +58,7 @@ public class GeyserCustomItemData implements CustomItemData { private final String toolType; private final String toolTier; private final String translationString; + private final String armorType; private final int protectionValue; private final boolean isFoil; private final boolean isEdible; @@ -82,6 +82,7 @@ public GeyserCustomItemData(Builder builder) { this.toolType = builder.toolType; this.toolTier = builder.toolTier; this.translationString = builder.translationString; + this.armorType = builder.armorType; this.protectionValue = builder.protectionValue; this.isFoil = builder.foil; this.isEdible = builder.edible; @@ -168,6 +169,11 @@ public String toolTier() { return toolTier; } + @Override + public @Nullable String armorType() { + return armorType; + } + @Override public int protectionValue() { return protectionValue; @@ -210,10 +216,10 @@ public static class Builder implements CustomItemData.Builder { private int attackDamage = 0; private String toolType = null; private String toolTier = null; + private String armorType = null; private int protectionValue = 0; private String translationString; private boolean foil = false; - private boolean tool = false; private boolean edible = false; private boolean canAlwaysEat = false; @@ -313,6 +319,12 @@ public Builder toolTier(@Nullable String toolTier) { return this; } + @Override + public Builder armorType(@Nullable String armorType) { + this.armorType = armorType; + return this; + } + @Override public Builder protectionValue(int protectionValue) { this.protectionValue = protectionValue; diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java index 160c74c10de..d727401b23d 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java @@ -40,7 +40,6 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData implements NonVanillaCustomItemData { private final String identifier; private final int javaId; - private final String armorType; private final Set repairMaterials; private final boolean isHat; private final boolean isChargeable; @@ -51,7 +50,6 @@ public GeyserNonVanillaCustomItemData(Builder builder) { this.identifier = builder.identifier; this.javaId = builder.javaId; - this.armorType = builder.armorType; this.repairMaterials = builder.repairMaterials; this.isHat = builder.hat; this.isChargeable = builder.chargeable; @@ -68,11 +66,6 @@ public int javaId() { return javaId; } - @Override - public @Nullable String armorType() { - return armorType; - } - @Override public Set repairMaterials() { return repairMaterials; @@ -96,7 +89,6 @@ public String block() { public static class Builder extends GeyserCustomItemData.Builder implements NonVanillaCustomItemData.Builder { private String identifier = null; private int javaId = -1; - private String armorType = null; private Set repairMaterials; private boolean hat = false; private boolean chargeable = false; @@ -160,12 +152,6 @@ public Builder javaId(int javaId) { return this; } - @Override - public Builder armorType(@Nullable String armorType) { - this.armorType = armorType; - return this; - } - @Override public Builder repairMaterials(@Nullable Set repairMaterials) { this.repairMaterials = repairMaterials; diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java index 75d7fc2c681..141965cbd2a 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java @@ -188,8 +188,18 @@ private static NbtMapBuilder createComponentNbt(CustomItemData customItemData, I itemProperties.putBoolean("can_destroy_in_creative", canDestroyInCreative); + String armorType = null; + int protectionValue = 0; if (mapping.getArmorType() != null) { - computeArmorProperties(mapping.getArmorType(), mapping.getProtectionValue(), itemProperties, componentBuilder); + armorType = mapping.getArmorType(); + protectionValue = mapping.getProtectionValue(); + } else if (customItemData.armorType() != null) { + armorType = customItemData.armorType(); + protectionValue = customItemData.protectionValue(); + } + + if (armorType != null) { + computeArmorProperties(armorType, protectionValue, itemProperties, componentBuilder); } if (mapping.getFirstBlockRuntimeId() != null) { From 72da5a576b8207966aa6c2bd38f31a3793255364 Mon Sep 17 00:00:00 2001 From: Eclipse Date: Sat, 11 May 2024 10:08:21 +0000 Subject: [PATCH 05/21] Move translation string back to non vanilla and move hat to vanilla --- .../api/item/custom/CustomItemData.java | 17 ++++++------ .../item/custom/NonVanillaCustomItemData.java | 17 ++++++------ .../geyser/item/GeyserCustomItemData.java | 14 +++++----- .../item/GeyserNonVanillaCustomItemData.java | 26 +++++++++---------- .../CustomItemRegistryPopulator.java | 8 +++--- 5 files changed, 41 insertions(+), 41 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java index 5bb469abc89..91663530804 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java @@ -158,13 +158,6 @@ public interface CustomItemData { */ @Nullable String toolTier(); - /** - * Gets the item's translation string. - * - * @return the item's translation string - */ - @Nullable String translationString(); - /** * Gets the armor type of the item. * @@ -179,6 +172,14 @@ public interface CustomItemData { */ int protectionValue(); + /** + * Gets if the item is a hat. This is used to determine if the item should be rendered on the player's head, and + * normally allow the player to equip it. This is not meant for armor. + * + * @return if the item is a hat + */ + boolean isHat(); + /** * Gets if the item is a foil. This is used to determine if the item should be rendered with an enchantment glint effect. * @@ -255,7 +256,7 @@ interface Builder { Builder protectionValue(int protectionValue); - Builder translationString(@Nullable String translationString); + Builder hat(boolean isHat); Builder foil(boolean isFoil); diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java index 9a1a699c674..778e8e6724d 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java @@ -51,19 +51,18 @@ public interface NonVanillaCustomItemData extends CustomItemData { @NonNegative int javaId(); /** - * Gets the repair materials of the item. + * Gets the item's translation string. * - * @return the repair materials of the item + * @return the item's translation string */ - @Nullable Set repairMaterials(); + @Nullable String translationString(); /** - * Gets if the item is a hat. This is used to determine if the item should be rendered on the player's head, and - * normally allow the player to equip it. This is not meant for armor. + * Gets the repair materials of the item. * - * @return if the item is a hat + * @return the repair materials of the item */ - boolean isHat(); + @Nullable Set repairMaterials(); /** * Gets if the item is chargable, like a bow. @@ -91,9 +90,9 @@ interface Builder extends CustomItemData.Builder { Builder javaId(@NonNegative int javaId); - Builder repairMaterials(@Nullable Set repairMaterials); + Builder translationString(@Nullable String translationString); - Builder hat(boolean isHat); + Builder repairMaterials(@Nullable Set repairMaterials); Builder chargeable(boolean isChargeable); diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java index f1cf5088423..08728b09152 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java @@ -57,9 +57,9 @@ public class GeyserCustomItemData implements CustomItemData { private final int attackDamage; private final String toolType; private final String toolTier; - private final String translationString; private final String armorType; private final int protectionValue; + private final boolean isHat; private final boolean isFoil; private final boolean isEdible; private final boolean canAlwaysEat; @@ -81,9 +81,9 @@ public GeyserCustomItemData(Builder builder) { this.attackDamage = builder.attackDamage; this.toolType = builder.toolType; this.toolTier = builder.toolTier; - this.translationString = builder.translationString; this.armorType = builder.armorType; this.protectionValue = builder.protectionValue; + this.isHat = builder.hat; this.isFoil = builder.foil; this.isEdible = builder.edible; this.canAlwaysEat = builder.canAlwaysEat; @@ -180,8 +180,8 @@ public int protectionValue() { } @Override - public String translationString() { - return translationString; + public boolean isHat() { + return isHat; } @Override @@ -218,7 +218,7 @@ public static class Builder implements CustomItemData.Builder { private String toolTier = null; private String armorType = null; private int protectionValue = 0; - private String translationString; + private boolean hat = false; private boolean foil = false; private boolean edible = false; private boolean canAlwaysEat = false; @@ -332,8 +332,8 @@ public Builder protectionValue(int protectionValue) { } @Override - public Builder translationString(@Nullable String translationString) { - this.translationString = translationString; + public Builder hat(boolean isHat) { + this.hat = isHat; return this; } diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java index d727401b23d..bcbd16b00b0 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java @@ -40,8 +40,8 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData implements NonVanillaCustomItemData { private final String identifier; private final int javaId; + private final String translationString; private final Set repairMaterials; - private final boolean isHat; private final boolean isChargeable; private final String block; @@ -50,8 +50,8 @@ public GeyserNonVanillaCustomItemData(Builder builder) { this.identifier = builder.identifier; this.javaId = builder.javaId; + this.translationString = builder.translationString; this.repairMaterials = builder.repairMaterials; - this.isHat = builder.hat; this.isChargeable = builder.chargeable; this.block = builder.block; } @@ -67,13 +67,13 @@ public int javaId() { } @Override - public Set repairMaterials() { - return repairMaterials; + public String translationString() { + return translationString; } @Override - public boolean isHat() { - return isHat; + public Set repairMaterials() { + return repairMaterials; } @Override @@ -89,8 +89,8 @@ public String block() { public static class Builder extends GeyserCustomItemData.Builder implements NonVanillaCustomItemData.Builder { private String identifier = null; private int javaId = -1; + private String translationString; private Set repairMaterials; - private boolean hat = false; private boolean chargeable = false; private String block = null; @@ -152,6 +152,12 @@ public Builder javaId(int javaId) { return this; } + @Override + public Builder translationString(@Nullable String translationString) { + this.translationString = translationString; + return this; + } + @Override public Builder repairMaterials(@Nullable Set repairMaterials) { this.repairMaterials = repairMaterials; @@ -168,12 +174,6 @@ public Builder creativeGroup(@Nullable String creativeGroup) { return (Builder) super.creativeGroup(creativeGroup); } - @Override - public Builder hat(boolean isHat) { - this.hat = isHat; - return this; - } - @Override public Builder chargeable(boolean isChargeable) { this.chargeable = isChargeable; diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java index 141965cbd2a..6bb29cd39d2 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java @@ -153,7 +153,7 @@ public boolean isValidRepairItem(Item other) { .build(); NbtMapBuilder builder = createComponentNbt(customItemData, customItemData.identifier(), customItemId, - customItemData.isHat(), customItemData.displayHandheld(), protocolVersion); + customItemData.displayHandheld(), protocolVersion); ComponentItemData componentItemData = new ComponentItemData(customIdentifier, builder.build()); return new NonVanillaItemRegistration(componentItemData, item, customItemMapping); @@ -226,7 +226,7 @@ private static NbtMapBuilder createComponentNbt(CustomItemData customItemData, I computeThrowableProperties(componentBuilder); } - computeRenderOffsets(false, customItemData, componentBuilder); + computeRenderOffsets(customItemData.isHat(), customItemData, componentBuilder); componentBuilder.putCompound("item_properties", itemProperties.build()); builder.putCompound("components", componentBuilder.build()); @@ -235,7 +235,7 @@ private static NbtMapBuilder createComponentNbt(CustomItemData customItemData, I } private static NbtMapBuilder createComponentNbt(NonVanillaCustomItemData customItemData, String customItemName, - int customItemId, boolean isHat, boolean displayHandheld, int protocolVersion) { + int customItemId, boolean displayHandheld, int protocolVersion) { NbtMapBuilder builder = NbtMap.builder(); builder.putString("name", customItemName) .putInt("id", customItemId); @@ -269,7 +269,7 @@ private static NbtMapBuilder createComponentNbt(NonVanillaCustomItemData customI computeChargeableProperties(itemProperties, componentBuilder, "minecraft:" + tooltype, protocolVersion); } - computeRenderOffsets(isHat, customItemData, componentBuilder); + computeRenderOffsets(customItemData.isHat(), customItemData, componentBuilder); if (customItemData.isFoil()) { itemProperties.putBoolean("foil", true); From 22f5ad12a8d0df4def01baf1ff33b469e59255ed Mon Sep 17 00:00:00 2001 From: Eclipse Date: Sat, 11 May 2024 10:28:01 +0000 Subject: [PATCH 06/21] Add overrides for backwards compatibility (testing needed) and reorder a bit --- .../item/custom/NonVanillaCustomItemData.java | 68 +++++++++++++++ .../item/GeyserNonVanillaCustomItemData.java | 83 +++++++++++++++---- 2 files changed, 137 insertions(+), 14 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java index 778e8e6724d..edd45b24907 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java @@ -86,6 +86,74 @@ interface Builder extends CustomItemData.Builder { @Override Builder name(@NonNull String name); + @Override + Builder customItemOptions(@NonNull CustomItemOptions customItemOptions); + + @Override + Builder displayName(@NonNull String displayName); + + @Override + Builder icon(@NonNull String icon); + + @Override + Builder allowOffhand(boolean allowOffhand); + + @Override + Builder displayHandheld(boolean displayHandheld); + + @Override + Builder creativeCategory(int creativeCategory); + + @Override + Builder creativeGroup(@Nullable String creativeGroup); + + @Override + Builder textureSize(int textureSize); + + @Override + Builder renderOffsets(@Nullable CustomRenderOffsets renderOffsets); + + @Override + Builder tags(@Nullable Set tags); + + @Override + Builder stackSize(@NonNegative int stackSize); + + @Override + Builder maxDamage(int maxDamage); + + @Override + Builder attackDamage(int attackDamage); + + @Override + Builder toolType(@Nullable String toolType); + + @Override + Builder toolTier(@Nullable String toolTier); + + @Override + Builder armorType(@Nullable String armorType); + + @Override + Builder protectionValue(int protectionValue); + + @Override + Builder hat(boolean isHat); + + @Override + Builder foil(boolean isFoil); + + @Override + Builder edible(boolean isEdible); + + @Override + Builder canAlwaysEat(boolean canAlwaysEat); + + @Override + default Builder tool(boolean isTool) { + return displayHandheld(isTool); + } + Builder identifier(@NonNull String identifier); Builder javaId(@NonNegative int javaId); diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java index bcbd16b00b0..63b1c693e35 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java @@ -105,6 +105,16 @@ public Builder customItemOptions(@NonNull CustomItemOptions customItemOptions) { return this; } + @Override + public Builder displayName(@NonNull String displayName) { + return (Builder) super.displayName(displayName); + } + + @Override + public Builder icon(@NonNull String icon) { + return (Builder) super.icon(icon); + } + @Override public Builder allowOffhand(boolean allowOffhand) { return (Builder) super.allowOffhand(allowOffhand); @@ -116,13 +126,13 @@ public Builder displayHandheld(boolean displayHandheld) { } @Override - public Builder displayName(@NonNull String displayName) { - return (Builder) super.displayName(displayName); + public Builder creativeCategory(int creativeCategory) { + return (Builder) super.creativeCategory(creativeCategory); } @Override - public Builder icon(@NonNull String icon) { - return (Builder) super.icon(icon); + public Builder creativeGroup(@Nullable String creativeGroup) { + return (Builder) super.creativeGroup(creativeGroup); } @Override @@ -140,6 +150,61 @@ public Builder tags(@Nullable Set tags) { return (Builder) super.tags(tags); } + @Override + public Builder stackSize(int stackSize) { + return (Builder) super.stackSize(stackSize); + } + + @Override + public Builder maxDamage(int maxDamage) { + return (Builder) super.maxDamage(maxDamage); + } + + @Override + public Builder attackDamage(int attackDamage) { + return (Builder) super.attackDamage(attackDamage); + } + + @Override + public Builder toolType(@Nullable String toolType) { + return (Builder) super.toolType(toolType); + } + + @Override + public Builder toolTier(@Nullable String toolTier) { + return (Builder) super.toolTier(toolTier); + } + + @Override + public Builder armorType(@Nullable String armorType) { + return (Builder) super.armorType(armorType); + } + + @Override + public Builder protectionValue(int protectionValue) { + return (Builder) super.protectionValue(protectionValue); + } + + @Override + public Builder hat(boolean isHat) { + return (Builder) super.hat(isHat); + } + + @Override + public Builder foil(boolean isFoil) { + return (Builder) super.foil(isFoil); + } + + @Override + public Builder edible(boolean isEdible) { + return (Builder) super.edible(isEdible); + } + + @Override + public Builder canAlwaysEat(boolean canAlwaysEat) { + return (Builder) super.canAlwaysEat(canAlwaysEat); + } + @Override public Builder identifier(@NonNull String identifier) { this.identifier = identifier; @@ -164,16 +229,6 @@ public Builder repairMaterials(@Nullable Set repairMaterials) { return this; } - @Override - public Builder creativeCategory(int creativeCategory) { - return (Builder) super.creativeCategory(creativeCategory); - } - - @Override - public Builder creativeGroup(@Nullable String creativeGroup) { - return (Builder) super.creativeGroup(creativeGroup); - } - @Override public Builder chargeable(boolean isChargeable) { this.chargeable = isChargeable; From 0a7a06a0443f0b4bc81731255c47557456c43279 Mon Sep 17 00:00:00 2001 From: Eclipse Date: Sat, 11 May 2024 10:35:06 +0000 Subject: [PATCH 07/21] Add new vanilla custom item properties to JSON reader, needs testing --- .../mappings/versions/MappingsReader_v1.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java index d32d5bc0944..1771378855d 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java +++ b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java @@ -225,6 +225,50 @@ public CustomItemData readItemMappingEntry(JsonNode node) throws InvalidCustomMa customItemData.tags(tagsSet); } + if (node.has("stack_size")) { + customItemData.stackSize(node.get("stack_size").asInt()); + } + + if (node.has("max_damage")) { + customItemData.maxDamage(node.get("max_damage").asInt()); + } + + if (node.has("attack_damage")) { + customItemData.maxDamage(node.get("attack_damage").asInt()); + } + + if (node.has("tool_type")) { + customItemData.toolType(node.get("tool_type").asText()); + } + + if (node.has("tool_tier")) { + customItemData.toolTier(node.get("tool_tier").asText()); + } + + if (node.has("armor_type")) { + customItemData.armorType(node.get("armor_type").asText()); + } + + if (node.has("protection_value")) { + customItemData.protectionValue(node.get("protection_value").asInt()); + } + + if (node.has("hat")) { + customItemData.hat(node.get("hat").asBoolean()); + } + + if (node.has("foil")) { + customItemData.foil(node.get("foil").asBoolean()); + } + + if (node.has("edible")) { + customItemData.edible(node.get("edible").asBoolean()); + } + + if (node.has("can_always_eat")) { + customItemData.canAlwaysEat(node.get("can_always_eat").asBoolean()); + } + return customItemData.build(); } From d31e94a7b120d055904163eddf8d48e7a3c6774d Mon Sep 17 00:00:00 2001 From: Eclipse Date: Sat, 11 May 2024 11:31:33 +0000 Subject: [PATCH 08/21] Fix edible animation --- .../populator/CustomItemRegistryPopulator.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java index 6bb29cd39d2..36918b51738 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java @@ -207,7 +207,8 @@ private static NbtMapBuilder createComponentNbt(CustomItemData customItemData, I } if (mapping.isEdible() || customItemData.isEdible()) { - computeConsumableProperties(itemProperties, componentBuilder, 1, customItemData.canAlwaysEat()); + computeConsumableProperties(itemProperties, componentBuilder, 1, + customItemData.canAlwaysEat(), protocolVersion); } if (mapping.isEntityPlacer()) { @@ -221,7 +222,7 @@ private static NbtMapBuilder createComponentNbt(CustomItemData customItemData, I switch (mapping.getBedrockIdentifier()) { case "minecraft:fire_charge", "minecraft:flint_and_steel" -> computeBlockItemProperties("minecraft:fire", componentBuilder); case "minecraft:bow", "minecraft:crossbow", "minecraft:trident" -> computeChargeableProperties(itemProperties, componentBuilder, mapping.getBedrockIdentifier(), protocolVersion); - case "minecraft:honey_bottle", "minecraft:milk_bucket", "minecraft:potion" -> computeConsumableProperties(itemProperties, componentBuilder, 2, true); + case "minecraft:honey_bottle", "minecraft:milk_bucket", "minecraft:potion" -> computeConsumableProperties(itemProperties, componentBuilder, 2, true, protocolVersion); case "minecraft:experience_bottle", "minecraft:egg", "minecraft:ender_pearl", "minecraft:ender_eye", "minecraft:lingering_potion", "minecraft:snowball", "minecraft:splash_potion" -> computeThrowableProperties(componentBuilder); } @@ -258,7 +259,7 @@ private static NbtMapBuilder createComponentNbt(NonVanillaCustomItemData customI } if (customItemData.isEdible()) { - computeConsumableProperties(itemProperties, componentBuilder, 1, customItemData.canAlwaysEat()); + computeConsumableProperties(itemProperties, componentBuilder, 1, customItemData.canAlwaysEat(), protocolVersion); } if (customItemData.isChargeable()) { @@ -515,7 +516,8 @@ private static void computeChargeableProperties(NbtMapBuilder itemProperties, Nb } } - private static void computeConsumableProperties(NbtMapBuilder itemProperties, NbtMapBuilder componentBuilder, int useAnimation, boolean canAlwaysEat) { + private static void computeConsumableProperties(NbtMapBuilder itemProperties, NbtMapBuilder componentBuilder, + int useAnimation, boolean canAlwaysEat, int protocolVersion) { // this is the duration of the use animation in ticks; note that in behavior packs this is set as a float in seconds, but over the network it is an int in ticks itemProperties.putInt("use_duration", 32); // this dictates that the item will use the eat or drink animation (in the first person) and play eat or drink sounds @@ -523,6 +525,13 @@ private static void computeConsumableProperties(NbtMapBuilder itemProperties, Nb itemProperties.putInt("use_animation", useAnimation); // this component is required to allow the eat animation to play componentBuilder.putCompound("minecraft:food", NbtMap.builder().putBoolean("can_always_eat", canAlwaysEat).build()); + + if (GameProtocol.is1_20_60orHigher(protocolVersion)) { + componentBuilder.putCompound("minecraft:use_modifiers", NbtMap.builder() + .putFloat("use_duration", 100F) + .putFloat("movement_modifier", 0.35F) + .build()); + } } private static void computeEntityPlacerProperties(NbtMapBuilder componentBuilder) { From e8266fff03e1bb45c9d7a883446354e0bc10d918 Mon Sep 17 00:00:00 2001 From: Eclipse Date: Sat, 11 May 2024 17:30:39 +0000 Subject: [PATCH 09/21] Move tool property back to non vanilla custom item --- .../api/item/custom/CustomItemData.java | 19 ------------------- .../item/custom/NonVanillaCustomItemData.java | 16 +++++++++++++++- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java index 91663530804..7dd0725e7e7 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java @@ -201,17 +201,6 @@ public interface CustomItemData { */ boolean canAlwaysEat(); - /** - * @deprecated Use {@link #displayHandheld()} instead. - * Gets if the item is a tool. This is used to set the render type of the item, if the item is handheld. - * - * @return if the item is a tool - */ - @Deprecated - default boolean isTool() { - return displayHandheld(); - } - static CustomItemData.Builder builder() { return GeyserApi.api().provider(CustomItemData.Builder.class); } @@ -264,14 +253,6 @@ interface Builder { Builder canAlwaysEat(boolean canAlwaysEat); - /** - * @deprecated Use {@link #displayHandheld(boolean)} instead. - */ - @Deprecated - default Builder tool(boolean isTool) { - return displayHandheld(isTool); - } - CustomItemData build(); } } diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java index edd45b24907..7cb3e629e15 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java @@ -78,6 +78,17 @@ public interface NonVanillaCustomItemData extends CustomItemData { */ String block(); + /** + * @deprecated Use {@link #displayHandheld()} instead. + * Gets if the item is a tool. This is used to set the render type of the item, if the item is handheld. + * + * @return if the item is a tool + */ + @Deprecated + default boolean isTool() { + return displayHandheld(); + } + static NonVanillaCustomItemData.Builder builder() { return GeyserApi.api().provider(NonVanillaCustomItemData.Builder.class); } @@ -149,7 +160,10 @@ interface Builder extends CustomItemData.Builder { @Override Builder canAlwaysEat(boolean canAlwaysEat); - @Override + /** + * @deprecated Use {@link #displayHandheld(boolean)} instead. + */ + @Deprecated default Builder tool(boolean isTool) { return displayHandheld(isTool); } From 6819d2b4c65f5bcc95306374c479b598726d3d91 Mon Sep 17 00:00:00 2001 From: Eclipse Date: Tue, 18 Jun 2024 08:24:54 +0000 Subject: [PATCH 10/21] Update to recent Geyser --- .../populator/CustomItemRegistryPopulator.java | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java index df63b6316ab..8d22562c47f 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java @@ -207,7 +207,7 @@ private static NbtMapBuilder createComponentNbt(CustomItemData customItemData, I if (mapping.isEdible() || customItemData.isEdible()) { computeConsumableProperties(itemProperties, componentBuilder, 1, - customItemData.canAlwaysEat(), protocolVersion); + customItemData.canAlwaysEat()); } if (mapping.isEntityPlacer()) { @@ -221,7 +221,7 @@ private static NbtMapBuilder createComponentNbt(CustomItemData customItemData, I switch (mapping.getBedrockIdentifier()) { case "minecraft:fire_charge", "minecraft:flint_and_steel" -> computeBlockItemProperties("minecraft:fire", componentBuilder); case "minecraft:bow", "minecraft:crossbow", "minecraft:trident" -> computeChargeableProperties(itemProperties, componentBuilder, mapping.getBedrockIdentifier(), protocolVersion); - case "minecraft:honey_bottle", "minecraft:milk_bucket", "minecraft:potion" -> computeConsumableProperties(itemProperties, componentBuilder, 2, true, protocolVersion); + case "minecraft:honey_bottle", "minecraft:milk_bucket", "minecraft:potion" -> computeConsumableProperties(itemProperties, componentBuilder, 2, true); case "minecraft:experience_bottle", "minecraft:egg", "minecraft:ender_pearl", "minecraft:ender_eye", "minecraft:lingering_potion", "minecraft:snowball", "minecraft:splash_potion" -> computeThrowableProperties(componentBuilder); } @@ -258,7 +258,7 @@ private static NbtMapBuilder createComponentNbt(NonVanillaCustomItemData customI } if (customItemData.isEdible()) { - computeConsumableProperties(itemProperties, componentBuilder, 1, customItemData.canAlwaysEat(), protocolVersion); + computeConsumableProperties(itemProperties, componentBuilder, 1, customItemData.canAlwaysEat()); } if (customItemData.isChargeable()) { @@ -501,7 +501,7 @@ private static void computeChargeableProperties(NbtMapBuilder itemProperties, Nb } private static void computeConsumableProperties(NbtMapBuilder itemProperties, NbtMapBuilder componentBuilder, - int useAnimation, boolean canAlwaysEat, int protocolVersion) { + int useAnimation, boolean canAlwaysEat) { // this is the duration of the use animation in ticks; note that in behavior packs this is set as a float in seconds, but over the network it is an int in ticks itemProperties.putInt("use_duration", 32); // this dictates that the item will use the eat or drink animation (in the first person) and play eat or drink sounds @@ -509,13 +509,6 @@ private static void computeConsumableProperties(NbtMapBuilder itemProperties, Nb itemProperties.putInt("use_animation", useAnimation); // this component is required to allow the eat animation to play componentBuilder.putCompound("minecraft:food", NbtMap.builder().putBoolean("can_always_eat", canAlwaysEat).build()); - - if (GameProtocol.is1_20_60orHigher(protocolVersion)) { - componentBuilder.putCompound("minecraft:use_modifiers", NbtMap.builder() - .putFloat("use_duration", 100F) - .putFloat("movement_modifier", 0.35F) - .build()); - } } private static void computeEntityPlacerProperties(NbtMapBuilder componentBuilder) { From e5f037e45f760d06763c705e199841303d59ee3e Mon Sep 17 00:00:00 2001 From: Eclipse Date: Sun, 21 Jul 2024 14:03:27 +0000 Subject: [PATCH 11/21] Move tool type and tool tier back to non vanilla items --- .../api/item/custom/CustomItemData.java | 18 --------- .../item/custom/NonVanillaCustomItemData.java | 24 +++++++++--- .../geyser/item/GeyserCustomItemData.java | 28 -------------- .../item/GeyserNonVanillaCustomItemData.java | 38 ++++++++++++++----- .../mappings/versions/MappingsReader_v1.java | 8 ---- .../CustomItemRegistryPopulator.java | 2 - 6 files changed, 46 insertions(+), 72 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java index 7dd0725e7e7..a55de0092ea 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java @@ -144,20 +144,6 @@ public interface CustomItemData { */ int attackDamage(); - /** - * Gets the tool type of the item. - * - * @return the tool type of the item - */ - @Nullable String toolType(); - - /** - * Gets the tool tier of the item. - * - * @return the tool tier of the item - */ - @Nullable String toolTier(); - /** * Gets the armor type of the item. * @@ -237,10 +223,6 @@ interface Builder { Builder attackDamage(int attackDamage); - Builder toolType(@Nullable String toolType); - - Builder toolTier(@Nullable String toolTier); - Builder armorType(@Nullable String armorType); Builder protectionValue(int protectionValue); diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java index 7cb3e629e15..98b4694c2ef 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java @@ -43,6 +43,20 @@ public interface NonVanillaCustomItemData extends CustomItemData { */ @NonNull String identifier(); + /** + * Gets the tool type of the item. + * + * @return the tool type of the item + */ + @Nullable String toolType(); + + /** + * Gets the tool tier of the item. + * + * @return the tool tier of the item + */ + @Nullable String toolTier(); + /** * Gets the java item id of the item. * @@ -136,12 +150,6 @@ interface Builder extends CustomItemData.Builder { @Override Builder attackDamage(int attackDamage); - @Override - Builder toolType(@Nullable String toolType); - - @Override - Builder toolTier(@Nullable String toolTier); - @Override Builder armorType(@Nullable String armorType); @@ -172,6 +180,10 @@ default Builder tool(boolean isTool) { Builder javaId(@NonNegative int javaId); + Builder toolType(@Nullable String toolType); + + Builder toolTier(@Nullable String toolTier); + Builder translationString(@Nullable String translationString); Builder repairMaterials(@Nullable Set repairMaterials); diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java index 08728b09152..406dc323461 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java @@ -55,8 +55,6 @@ public class GeyserCustomItemData implements CustomItemData { private final int stackSize; private final int maxDamage; private final int attackDamage; - private final String toolType; - private final String toolTier; private final String armorType; private final int protectionValue; private final boolean isHat; @@ -79,8 +77,6 @@ public GeyserCustomItemData(Builder builder) { this.stackSize = builder.stackSize; this.maxDamage = builder.maxDamage; this.attackDamage = builder.attackDamage; - this.toolType = builder.toolType; - this.toolTier = builder.toolTier; this.armorType = builder.armorType; this.protectionValue = builder.protectionValue; this.isHat = builder.hat; @@ -159,16 +155,6 @@ public int attackDamage() { return attackDamage; } - @Override - public String toolType() { - return toolType; - } - - @Override - public String toolTier() { - return toolTier; - } - @Override public @Nullable String armorType() { return armorType; @@ -214,8 +200,6 @@ public static class Builder implements CustomItemData.Builder { private int stackSize = 0; private int maxDamage = -1; private int attackDamage = 0; - private String toolType = null; - private String toolTier = null; private String armorType = null; private int protectionValue = 0; private boolean hat = false; @@ -307,18 +291,6 @@ public Builder attackDamage(int attackDamage) { return this; } - @Override - public Builder toolType(@Nullable String toolType) { - this.toolType = toolType; - return this; - } - - @Override - public Builder toolTier(@Nullable String toolTier) { - this.toolTier = toolTier; - return this; - } - @Override public Builder armorType(@Nullable String armorType) { this.armorType = armorType; diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java index 63b1c693e35..c5ac4f68e06 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java @@ -40,6 +40,8 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData implements NonVanillaCustomItemData { private final String identifier; private final int javaId; + private final String toolType; + private final String toolTier; private final String translationString; private final Set repairMaterials; private final boolean isChargeable; @@ -50,6 +52,8 @@ public GeyserNonVanillaCustomItemData(Builder builder) { this.identifier = builder.identifier; this.javaId = builder.javaId; + this.toolType = builder.toolType; + this.toolTier = builder.toolTier; this.translationString = builder.translationString; this.repairMaterials = builder.repairMaterials; this.isChargeable = builder.chargeable; @@ -66,6 +70,16 @@ public int javaId() { return javaId; } + @Override + public String toolType() { + return toolType; + } + + @Override + public String toolTier() { + return toolTier; + } + @Override public String translationString() { return translationString; @@ -89,6 +103,8 @@ public String block() { public static class Builder extends GeyserCustomItemData.Builder implements NonVanillaCustomItemData.Builder { private String identifier = null; private int javaId = -1; + private String toolType = null; + private String toolTier = null; private String translationString; private Set repairMaterials; private boolean chargeable = false; @@ -165,16 +181,6 @@ public Builder attackDamage(int attackDamage) { return (Builder) super.attackDamage(attackDamage); } - @Override - public Builder toolType(@Nullable String toolType) { - return (Builder) super.toolType(toolType); - } - - @Override - public Builder toolTier(@Nullable String toolTier) { - return (Builder) super.toolTier(toolTier); - } - @Override public Builder armorType(@Nullable String armorType) { return (Builder) super.armorType(armorType); @@ -217,6 +223,18 @@ public Builder javaId(int javaId) { return this; } + @Override + public Builder toolType(@Nullable String toolType) { + this.toolType = toolType; + return this; + } + + @Override + public Builder toolTier(@Nullable String toolTier) { + this.toolTier = toolTier; + return this; + } + @Override public Builder translationString(@Nullable String translationString) { this.translationString = translationString; diff --git a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java index 5d6bf4e327c..509af041760 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java +++ b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java @@ -225,14 +225,6 @@ public CustomItemData readItemMappingEntry(JsonNode node) throws InvalidCustomMa customItemData.maxDamage(node.get("attack_damage").asInt()); } - if (node.has("tool_type")) { - customItemData.toolType(node.get("tool_type").asText()); - } - - if (node.has("tool_tier")) { - customItemData.toolTier(node.get("tool_tier").asText()); - } - if (node.has("armor_type")) { customItemData.armorType(node.get("armor_type").asText()); } diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java index 8d22562c47f..8bb28673f2b 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java @@ -176,8 +176,6 @@ private static NbtMapBuilder createComponentNbt(CustomItemData customItemData, I String toolType = null; if (mapping.getToolType() != null) { toolType = mapping.getToolType(); - } else if (customItemData.toolType() != null) { - toolType = customItemData.toolType(); } if (toolType != null) { From 9bdf05aff43d888bb2039aa820d7b381fad8fe5a Mon Sep 17 00:00:00 2001 From: Eclipse Date: Sun, 21 Jul 2024 14:14:18 +0000 Subject: [PATCH 12/21] Adjust documentation --- .../geysermc/geyser/api/item/custom/CustomItemData.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java index a55de0092ea..72f73e0b2e6 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java @@ -118,7 +118,7 @@ public interface CustomItemData { /** * Gets the stack size of the item. * - * Returns 0 if not set. When not set (or 0), takes the Java item stack count when based of a vanilla item, or uses 64 when porting a modded item. + * Returns 0 if not set. When not set (or 0), it defaults to the stack count of the Java item when based of a vanilla item, or 64 when registering a non-vanilla item. * * @return the stack size of the item */ @@ -128,7 +128,7 @@ public interface CustomItemData { /** * Gets the max damage of the item. * - * Returns -1 if not set. When not set (or below 0), takes the Java item max damage when based of a vanilla item, or uses 0 when porting a modded item. + * Returns -1 if not set. When not set (or below 0), it defaults to the maximum damage of the Java item when based of a vanilla item, or uses 0 when registering a non-vanilla item. * * @return the max damage of the item */ @@ -147,6 +147,9 @@ public interface CustomItemData { /** * Gets the armor type of the item. * + * This can be "boots", "leggings", "chestplate", or "helmet", and makes the item able to be equipped into its respective equipment slot. + * This should only be set if the Java vanilla/non-vanilla item is able to fit into the specified equipment slot. + * * @return the armor type of the item */ @Nullable String armorType(); @@ -154,6 +157,8 @@ public interface CustomItemData { /** * Gets the armor protection value of the item. * + * Only has a function when {@link CustomItemData#armorType)} is set. + * * @return the armor protection value of the item */ int protectionValue(); From aa59f404af21869f0256afeed942e9a3db7b0ab5 Mon Sep 17 00:00:00 2001 From: Eclipse Date: Sun, 21 Jul 2024 14:19:00 +0000 Subject: [PATCH 13/21] Whoops --- .../org/geysermc/geyser/api/item/custom/CustomItemData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java index 72f73e0b2e6..f17c09df28c 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java @@ -157,7 +157,7 @@ public interface CustomItemData { /** * Gets the armor protection value of the item. * - * Only has a function when {@link CustomItemData#armorType)} is set. + * Only has a function when {@link CustomItemData#armorType} is set. * * @return the armor protection value of the item */ From e55eaa7b7a2468e4874c627b0615ab4f94014dc3 Mon Sep 17 00:00:00 2001 From: Eclipse Date: Sun, 21 Jul 2024 20:56:05 +0000 Subject: [PATCH 14/21] Simplify documentation of armor type property Co-authored-by: chris --- .../org/geysermc/geyser/api/item/custom/CustomItemData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java index f17c09df28c..179ad1d34fe 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java @@ -148,7 +148,7 @@ public interface CustomItemData { * Gets the armor type of the item. * * This can be "boots", "leggings", "chestplate", or "helmet", and makes the item able to be equipped into its respective equipment slot. - * This should only be set if the Java vanilla/non-vanilla item is able to fit into the specified equipment slot. + * This should only be set if the Java item can be placed into the specified equipment slot. * * @return the armor type of the item */ From 7d49af1653e0c431497a56a24a0c05778618fdeb Mon Sep 17 00:00:00 2001 From: Eclipse Date: Thu, 1 Aug 2024 10:15:46 +0000 Subject: [PATCH 15/21] Implement stack size and max damage restrictions --- .../geyser/api/item/custom/CustomItemData.java | 4 ++++ .../geyser/item/GeyserCustomItemData.java | 16 ++++++++++++++++ .../mappings/versions/MappingsReader_v1.java | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java index 179ad1d34fe..a7f386b38a3 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java @@ -120,6 +120,8 @@ public interface CustomItemData { * * Returns 0 if not set. When not set (or 0), it defaults to the stack count of the Java item when based of a vanilla item, or 64 when registering a non-vanilla item. * + * Note that, to copy Java behaviour, setting the stack size of an item to a value above 1 will set the max damage to 0. If a max damage value above 0 was explicitly set, an exception will be thrown. + * * @return the stack size of the item */ @NonNegative @@ -130,6 +132,8 @@ public interface CustomItemData { * * Returns -1 if not set. When not set (or below 0), it defaults to the maximum damage of the Java item when based of a vanilla item, or uses 0 when registering a non-vanilla item. * + * Note that, to copy Java behaviour, setting the max damage value of an item to a value above 0 will set the stack size to 1. If a stack size above 1 was explicitly set, an exception will be thrown. + * * @return the max damage of the item */ int maxDamage(); diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java index 406dc323461..2bba274084f 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java @@ -275,12 +275,28 @@ public Builder tags(@Nullable Set tags) { @Override public Builder stackSize(int stackSize) { + if (stackSize > 1) { + if (this.maxDamage > 0) { + throw new IllegalStateException("Stack size cannot be above 1 when max damage is above 0"); + } + // Explicitly set max damage to 0 instead of falling back to the Java vanilla item value + this.maxDamage = 0; + } + this.stackSize = stackSize; return this; } @Override public Builder maxDamage(int maxDamage) { + if (maxDamage > 0) { + if (this.stackSize > 1) { + throw new IllegalStateException("Max damage cannot be above 0 when stack size is above 1"); + } + // Explicitly set stack size to 1 instead of falling back to the Java vanilla item value + this.stackSize = 1; + } + this.maxDamage = maxDamage; return this; } diff --git a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java index 509af041760..5560fdb6de2 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java +++ b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java @@ -222,7 +222,7 @@ public CustomItemData readItemMappingEntry(JsonNode node) throws InvalidCustomMa } if (node.has("attack_damage")) { - customItemData.maxDamage(node.get("attack_damage").asInt()); + customItemData.attackDamage(node.get("attack_damage").asInt()); } if (node.has("armor_type")) { From 30df3349fdb1dad1b7958e2b72549e9d788c61cf Mon Sep 17 00:00:00 2001 From: Eclipse Date: Fri, 2 Aug 2024 13:10:57 +0000 Subject: [PATCH 16/21] Improve documentation and add more proper checks to stack size and max damage item values --- .../geyser/api/item/custom/CustomItemData.java | 16 ++++++++-------- .../geyser/item/GeyserCustomItemData.java | 8 ++++++-- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java index a7f386b38a3..a754e7e442f 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java @@ -118,9 +118,9 @@ public interface CustomItemData { /** * Gets the stack size of the item. * - * Returns 0 if not set. When not set (or 0), it defaults to the stack count of the Java item when based of a vanilla item, or 64 when registering a non-vanilla item. + *

Returns 0 if not set. When not set (or 0), Geyser defaults to the stack count of the Java item when based on a vanilla item, or 64 when registering a non-vanilla item.

* - * Note that, to copy Java behaviour, setting the stack size of an item to a value above 1 will set the max damage to 0. If a max damage value above 0 was explicitly set, an exception will be thrown. + *

Note that, to copy Java behaviour, setting the stack size of an item to a value above 1 will set the max damage to 0. If a max damage value above 0 was explicitly set, an exception will be thrown.

* * @return the stack size of the item */ @@ -130,9 +130,9 @@ public interface CustomItemData { /** * Gets the max damage of the item. * - * Returns -1 if not set. When not set (or below 0), it defaults to the maximum damage of the Java item when based of a vanilla item, or uses 0 when registering a non-vanilla item. + *

Returns -1 if not set. When not set (or below 0), Geyser defaults to the maximum damage of the Java item when based on a vanilla item, or uses 0 when registering a non-vanilla item.

* - * Note that, to copy Java behaviour, setting the max damage value of an item to a value above 0 will set the stack size to 1. If a stack size above 1 was explicitly set, an exception will be thrown. + *

Note that, to copy Java behaviour, setting the max damage value of an item to a value above 0 will set the stack size to 1. If a stack size above 1 was explicitly set, an exception will be thrown.

* * @return the max damage of the item */ @@ -142,7 +142,7 @@ public interface CustomItemData { * Gets the attack damage of the item. * This is purely visual, and only applied to tools * - * Returns 0 if not set. When 0, takes the Java item attack damage when based of a vanilla item, or uses 0 when porting a modded item. + *

Returns 0 if not set. When 0, Geyser takes the Java item attack damage when based on a vanilla item, or uses 0 when porting a modded item.

* * @return the attack damage of the item */ @@ -151,8 +151,8 @@ public interface CustomItemData { /** * Gets the armor type of the item. * - * This can be "boots", "leggings", "chestplate", or "helmet", and makes the item able to be equipped into its respective equipment slot. - * This should only be set if the Java item can be placed into the specified equipment slot. + *

This can be "boots", "leggings", "chestplate", or "helmet", and makes the item able to be equipped into its respective equipment slot. + * This should only be set if the Java item can be placed into the specified equipment slot.

* * @return the armor type of the item */ @@ -161,7 +161,7 @@ public interface CustomItemData { /** * Gets the armor protection value of the item. * - * Only has a function when {@link CustomItemData#armorType} is set. + *

Only has a function when {@link CustomItemData#armorType} is set.

* * @return the armor protection value of the item */ diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java index 2bba274084f..9762d78e51e 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java @@ -275,7 +275,9 @@ public Builder tags(@Nullable Set tags) { @Override public Builder stackSize(int stackSize) { - if (stackSize > 1) { + if (stackSize < 1) { + throw new IllegalArgumentException("Stack size cannot be below 1"); + } else if (stackSize > 1) { if (this.maxDamage > 0) { throw new IllegalStateException("Stack size cannot be above 1 when max damage is above 0"); } @@ -289,7 +291,9 @@ public Builder stackSize(int stackSize) { @Override public Builder maxDamage(int maxDamage) { - if (maxDamage > 0) { + if (maxDamage < 0) { + throw new IllegalArgumentException("Max damage cannot be below 0"); + } else if (maxDamage > 0) { if (this.stackSize > 1) { throw new IllegalStateException("Max damage cannot be above 0 when stack size is above 1"); } From 7394cf5a18ed846843bda7025d5bccddf4d57c17 Mon Sep 17 00:00:00 2001 From: Eclipse Date: Fri, 2 Aug 2024 13:12:01 +0000 Subject: [PATCH 17/21] Improve documentation slightly again --- .../org/geysermc/geyser/api/item/custom/CustomItemData.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java index a754e7e442f..e09e0c9b59f 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java @@ -118,7 +118,7 @@ public interface CustomItemData { /** * Gets the stack size of the item. * - *

Returns 0 if not set. When not set (or 0), Geyser defaults to the stack count of the Java item when based on a vanilla item, or 64 when registering a non-vanilla item.

+ *

Returns 0 if not set. When not set, Geyser defaults to the stack count of the Java item when based on a vanilla item, or 64 when registering a non-vanilla item.

* *

Note that, to copy Java behaviour, setting the stack size of an item to a value above 1 will set the max damage to 0. If a max damage value above 0 was explicitly set, an exception will be thrown.

* @@ -130,7 +130,7 @@ public interface CustomItemData { /** * Gets the max damage of the item. * - *

Returns -1 if not set. When not set (or below 0), Geyser defaults to the maximum damage of the Java item when based on a vanilla item, or uses 0 when registering a non-vanilla item.

+ *

Returns -1 if not set. When not set, Geyser defaults to the maximum damage of the Java item when based on a vanilla item, or uses 0 when registering a non-vanilla item.

* *

Note that, to copy Java behaviour, setting the max damage value of an item to a value above 0 will set the stack size to 1. If a stack size above 1 was explicitly set, an exception will be thrown.

* From 7ebbf538f20055880bee5889a8441937cbd94b8d Mon Sep 17 00:00:00 2001 From: Eclipse Date: Sun, 11 Aug 2024 10:44:40 +0100 Subject: [PATCH 18/21] Improve exception messages for stackSize and maxDamage builder methods, and add proper method argument annotations for these methods --- .../geysermc/geyser/api/item/custom/CustomItemData.java | 5 +++-- .../geyser/api/item/custom/NonVanillaCustomItemData.java | 5 +++-- .../org/geysermc/geyser/item/GeyserCustomItemData.java | 8 ++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java index e09e0c9b59f..bbf7e1f1cca 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.api.item.custom; import org.checkerframework.checker.index.qual.NonNegative; +import org.checkerframework.checker.index.qual.Positive; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.api.GeyserApi; @@ -226,9 +227,9 @@ interface Builder { Builder tags(@Nullable Set tags); - Builder stackSize(@NonNegative int stackSize); + Builder stackSize(@Positive int stackSize); - Builder maxDamage(int maxDamage); + Builder maxDamage(@NonNegative int maxDamage); Builder attackDamage(int attackDamage); diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java index 98b4694c2ef..9718b0653b0 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.api.item.custom; import org.checkerframework.checker.index.qual.NonNegative; +import org.checkerframework.checker.index.qual.Positive; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.api.GeyserApi; @@ -142,10 +143,10 @@ interface Builder extends CustomItemData.Builder { Builder tags(@Nullable Set tags); @Override - Builder stackSize(@NonNegative int stackSize); + Builder stackSize(@Positive int stackSize); @Override - Builder maxDamage(int maxDamage); + Builder maxDamage(@NonNegative int maxDamage); @Override Builder attackDamage(int attackDamage); diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java index 9762d78e51e..b43b921c524 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java @@ -276,10 +276,10 @@ public Builder tags(@Nullable Set tags) { @Override public Builder stackSize(int stackSize) { if (stackSize < 1) { - throw new IllegalArgumentException("Stack size cannot be below 1"); + throw new IllegalArgumentException("Stack size cannot be below 1 (" + stackSize + " was given)"); } else if (stackSize > 1) { if (this.maxDamage > 0) { - throw new IllegalStateException("Stack size cannot be above 1 when max damage is above 0"); + throw new IllegalArgumentException("Stack size cannot be above 1 when max damage is above 0 (" + stackSize + " was given)"); } // Explicitly set max damage to 0 instead of falling back to the Java vanilla item value this.maxDamage = 0; @@ -292,10 +292,10 @@ public Builder stackSize(int stackSize) { @Override public Builder maxDamage(int maxDamage) { if (maxDamage < 0) { - throw new IllegalArgumentException("Max damage cannot be below 0"); + throw new IllegalArgumentException("Max damage cannot be below 0 (" + maxDamage + " was given)"); } else if (maxDamage > 0) { if (this.stackSize > 1) { - throw new IllegalStateException("Max damage cannot be above 0 when stack size is above 1"); + throw new IllegalArgumentException("Max damage cannot be above 0 when stack size is above 1 (" + maxDamage + " was given)"); } // Explicitly set stack size to 1 instead of falling back to the Java vanilla item value this.stackSize = 1; From c890f064aeac94f5aba91b108aa9d2f857c23056 Mon Sep 17 00:00:00 2001 From: Eclipse Date: Tue, 13 Aug 2024 21:01:22 +0100 Subject: [PATCH 19/21] Add more annotations and proper validating of attack damage and protection value values --- .../geyser/api/item/custom/CustomItemData.java | 11 +++++------ .../item/custom/NonVanillaCustomItemData.java | 4 ++-- .../geyser/item/GeyserCustomItemData.java | 16 ++++++++++++---- .../item/GeyserNonVanillaCustomItemData.java | 10 ++++++---- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java index bbf7e1f1cca..0f80aae0a21 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java @@ -125,8 +125,7 @@ public interface CustomItemData { * * @return the stack size of the item */ - @NonNegative - int stackSize(); + @NonNegative int stackSize(); /** * Gets the max damage of the item. @@ -147,7 +146,7 @@ public interface CustomItemData { * * @return the attack damage of the item */ - int attackDamage(); + @NonNegative int attackDamage(); /** * Gets the armor type of the item. @@ -166,7 +165,7 @@ public interface CustomItemData { * * @return the armor protection value of the item */ - int protectionValue(); + @NonNegative int protectionValue(); /** * Gets if the item is a hat. This is used to determine if the item should be rendered on the player's head, and @@ -231,11 +230,11 @@ interface Builder { Builder maxDamage(@NonNegative int maxDamage); - Builder attackDamage(int attackDamage); + Builder attackDamage(@NonNegative int attackDamage); Builder armorType(@Nullable String armorType); - Builder protectionValue(int protectionValue); + Builder protectionValue(@NonNegative int protectionValue); Builder hat(boolean isHat); diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java index 9718b0653b0..51d6a984c91 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/NonVanillaCustomItemData.java @@ -149,13 +149,13 @@ interface Builder extends CustomItemData.Builder { Builder maxDamage(@NonNegative int maxDamage); @Override - Builder attackDamage(int attackDamage); + Builder attackDamage(@NonNegative int attackDamage); @Override Builder armorType(@Nullable String armorType); @Override - Builder protectionValue(int protectionValue); + Builder protectionValue(@NonNegative int protectionValue); @Override Builder hat(boolean isHat); diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java index b43b921c524..6fb020729e1 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java @@ -27,6 +27,8 @@ import lombok.EqualsAndHashCode; import lombok.ToString; +import org.checkerframework.checker.index.qual.NonNegative; +import org.checkerframework.checker.index.qual.Positive; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.api.item.custom.CustomItemData; @@ -274,7 +276,7 @@ public Builder tags(@Nullable Set tags) { } @Override - public Builder stackSize(int stackSize) { + public Builder stackSize(@Positive int stackSize) { if (stackSize < 1) { throw new IllegalArgumentException("Stack size cannot be below 1 (" + stackSize + " was given)"); } else if (stackSize > 1) { @@ -290,7 +292,7 @@ public Builder stackSize(int stackSize) { } @Override - public Builder maxDamage(int maxDamage) { + public Builder maxDamage(@NonNegative int maxDamage) { if (maxDamage < 0) { throw new IllegalArgumentException("Max damage cannot be below 0 (" + maxDamage + " was given)"); } else if (maxDamage > 0) { @@ -306,7 +308,10 @@ public Builder maxDamage(int maxDamage) { } @Override - public Builder attackDamage(int attackDamage) { + public Builder attackDamage(@NonNegative int attackDamage) { + if (attackDamage < 0) { + throw new IllegalArgumentException("Protection value cannot be below 0 (" + attackDamage + " was given)"); + } this.attackDamage = attackDamage; return this; } @@ -318,7 +323,10 @@ public Builder armorType(@Nullable String armorType) { } @Override - public Builder protectionValue(int protectionValue) { + public Builder protectionValue(@NonNegative int protectionValue) { + if (protectionValue < 0) { + throw new IllegalArgumentException("Protection value cannot be below 0 (" + protectionValue + " was given)"); + } this.protectionValue = protectionValue; return this; } diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java index c5ac4f68e06..5ae41479c1f 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserNonVanillaCustomItemData.java @@ -27,6 +27,8 @@ import lombok.EqualsAndHashCode; import lombok.ToString; +import org.checkerframework.checker.index.qual.NonNegative; +import org.checkerframework.checker.index.qual.Positive; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.geysermc.geyser.api.item.custom.CustomItemOptions; @@ -167,17 +169,17 @@ public Builder tags(@Nullable Set tags) { } @Override - public Builder stackSize(int stackSize) { + public Builder stackSize(@Positive int stackSize) { return (Builder) super.stackSize(stackSize); } @Override - public Builder maxDamage(int maxDamage) { + public Builder maxDamage(@NonNegative int maxDamage) { return (Builder) super.maxDamage(maxDamage); } @Override - public Builder attackDamage(int attackDamage) { + public Builder attackDamage(@NonNegative int attackDamage) { return (Builder) super.attackDamage(attackDamage); } @@ -187,7 +189,7 @@ public Builder armorType(@Nullable String armorType) { } @Override - public Builder protectionValue(int protectionValue) { + public Builder protectionValue(@NonNegative int protectionValue) { return (Builder) super.protectionValue(protectionValue); } From db92184d42673f30c151702dd9fa25de21b67858 Mon Sep 17 00:00:00 2001 From: Eclipse Date: Tue, 13 Aug 2024 21:04:23 +0100 Subject: [PATCH 20/21] Add validation for armor type --- .../java/org/geysermc/geyser/item/GeyserCustomItemData.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java index 6fb020729e1..4eaddaa6bd3 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.item; +import java.util.List; import lombok.EqualsAndHashCode; import lombok.ToString; import org.checkerframework.checker.index.qual.NonNegative; @@ -43,6 +44,8 @@ @EqualsAndHashCode @ToString public class GeyserCustomItemData implements CustomItemData { + private static final List VALID_ARMOR_TYPES = List.of("boots", "leggings", "chestplate", "helmet"); + private final String name; private final CustomItemOptions customItemOptions; private final String displayName; @@ -318,6 +321,9 @@ public Builder attackDamage(@NonNegative int attackDamage) { @Override public Builder armorType(@Nullable String armorType) { + if (!VALID_ARMOR_TYPES.contains(armorType)) { + throw new IllegalArgumentException("Invalid armor type " + armorType + "! Can be \"boots\", \"leggings\", \"chestplate\", or \"helmet\""); + } this.armorType = armorType; return this; } From 5b864ab88e2bf696af2f7e9909e22b2cd030fdbb Mon Sep 17 00:00:00 2001 From: Eclipse Date: Tue, 13 Aug 2024 21:10:34 +0100 Subject: [PATCH 21/21] Return -1 if not set for attack damage and protection value and implement proper fallbacks --- .../geyser/api/item/custom/CustomItemData.java | 10 ++++++---- .../org/geysermc/geyser/item/GeyserCustomItemData.java | 4 ++-- .../populator/CustomItemRegistryPopulator.java | 9 +++++---- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java index 0f80aae0a21..2fab74dd469 100644 --- a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java +++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java @@ -142,11 +142,11 @@ public interface CustomItemData { * Gets the attack damage of the item. * This is purely visual, and only applied to tools * - *

Returns 0 if not set. When 0, Geyser takes the Java item attack damage when based on a vanilla item, or uses 0 when porting a modded item.

+ *

Returns -1 if not set. When not set, Geyser takes the Java item attack damage when based on a vanilla item, or uses 0 when porting a modded item.

* * @return the attack damage of the item */ - @NonNegative int attackDamage(); + int attackDamage(); /** * Gets the armor type of the item. @@ -161,11 +161,13 @@ public interface CustomItemData { /** * Gets the armor protection value of the item. * - *

Only has a function when {@link CustomItemData#armorType} is set.

+ *

Only has a function when {@link CustomItemData#armorType} is set, or when the Java item is an armor item (when based on a vanilla item).

+ * + *

Returns -1 if not set. When not set, Geyser takes the Java item protection value when based on a vanilla item, or uses 0 when porting a modded item.

* * @return the armor protection value of the item */ - @NonNegative int protectionValue(); + int protectionValue(); /** * Gets if the item is a hat. This is used to determine if the item should be rendered on the player's head, and diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java index 4eaddaa6bd3..28fedb1452b 100644 --- a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java +++ b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java @@ -204,9 +204,9 @@ public static class Builder implements CustomItemData.Builder { protected Set tags = new HashSet<>(); private int stackSize = 0; private int maxDamage = -1; - private int attackDamage = 0; + private int attackDamage = -1; private String armorType = null; - private int protectionValue = 0; + private int protectionValue = -1; private boolean hat = false; private boolean foil = false; private boolean edible = false; diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java index f2d23331875..1f7bcf506d5 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java @@ -182,10 +182,11 @@ private static NbtMapBuilder createComponentNbt(CustomItemData customItemData, I int protectionValue = 0; if (mapping.getArmorType() != null) { armorType = mapping.getArmorType(); - protectionValue = mapping.getProtectionValue(); + protectionValue = customItemData.protectionValue() == -1 ? mapping.getProtectionValue() : customItemData.protectionValue(); } else if (customItemData.armorType() != null) { armorType = customItemData.armorType(); - protectionValue = customItemData.protectionValue(); + // Using 0 as fallback here because the Java item doesn't have an armor type - so its protection value would be 0 + protectionValue = customItemData.protectionValue() == -1 ? 0 : customItemData.protectionValue(); } if (armorType != null) { @@ -244,13 +245,13 @@ private static NbtMapBuilder createComponentNbt(NonVanillaCustomItemData customI boolean canDestroyInCreative = true; if (customItemData.toolType() != null) { // This is not using the isTool boolean because it is not just a render type here. - canDestroyInCreative = computeToolProperties(Objects.requireNonNull(customItemData.toolType()), itemProperties, componentBuilder, customItemData.attackDamage()); + canDestroyInCreative = computeToolProperties(Objects.requireNonNull(customItemData.toolType()), itemProperties, componentBuilder, Math.max(0, customItemData.attackDamage())); } itemProperties.putBoolean("can_destroy_in_creative", canDestroyInCreative); String armorType = customItemData.armorType(); if (armorType != null) { - computeArmorProperties(armorType, customItemData.protectionValue(), itemProperties, componentBuilder); + computeArmorProperties(armorType, Math.max(0, customItemData.protectionValue()), itemProperties, componentBuilder); } if (customItemData.isEdible()) {