Skip to content

Commit

Permalink
Fix: Looms modifying default data components causing visual bugs
Browse files Browse the repository at this point in the history
Closes #5273
  • Loading branch information
onebeastchris committed Feb 4, 2025
1 parent ea13e58 commit 0416b55
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.SlotDisplay;

import java.util.HashMap;
import java.util.function.Supplier;

@Data
public class GeyserItemStack {
Expand Down Expand Up @@ -169,9 +170,9 @@ public <T> T getComponent(@NonNull DataComponentType<T> type) {
return value;
}

public <T> T getComponentOrFallback(@NonNull DataComponentType<T> type, T def) {
public <T> T getComponentElseGet(@NonNull DataComponentType<T> type, Supplier<T> supplier) {
T value = getComponent(type);
return value == null ? def : value;
return value == null ? supplier.get() : value;
}

public int getNetId() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.HolderSet;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Unbreakable;
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket;

import java.util.List;
Expand Down Expand Up @@ -420,7 +419,7 @@ private boolean isRenaming(GeyserSession session, AnvilContainer anvilContainer,
}

private int getRepairCost(GeyserItemStack itemStack) {
return itemStack.getComponentOrFallback(DataComponentType.REPAIR_COST, 0);
return itemStack.getComponentElseGet(DataComponentType.REPAIR_COST, () -> 0);
}

private boolean hasDurability(GeyserItemStack itemStack) {
Expand All @@ -431,6 +430,6 @@ private boolean hasDurability(GeyserItemStack itemStack) {
}

private int getDamage(GeyserItemStack itemStack) {
return itemStack.getComponentOrFallback(DataComponentType.DAMAGE, 0);
return itemStack.getComponentElseGet(DataComponentType.DAMAGE, () -> 0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ private static Fraction calculateWeight(GeyserItemStack itemStack) {
return Fraction.ONE;
}
}
return Fraction.getFraction(1, itemStack.getComponentOrFallback(DataComponentType.MAX_STACK_SIZE, itemStack.asItem().defaultMaxStackSize()));
return Fraction.getFraction(1, itemStack.getComponentElseGet(DataComponentType.MAX_STACK_SIZE, () -> itemStack.asItem().defaultMaxStackSize()));
}

public static int capacityForItemStack(Fraction bundleWeight, GeyserItemStack itemStack) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,8 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator {
PATTERN_TO_INDEX.put("vhr", index++);
PATTERN_TO_INDEX.put("hhb", index++);
PATTERN_TO_INDEX.put("bo", index++);
index++; // Bordure indented, does not appear to exist in Bedrock?
PATTERN_TO_INDEX.put("gra", index++);
PATTERN_TO_INDEX.put("gru", index);
// Bricks do not appear to be a pattern on Bedrock, either
}

public LoomInventoryTranslator() {
Expand All @@ -120,7 +118,7 @@ protected boolean shouldRejectItemPlace(GeyserSession session, Inventory invento

@Override
protected boolean shouldHandleRequestFirst(ItemStackRequestAction action, Inventory inventory) {
// If the LOOM_MATERIAL slot is not empty, we are crafting a pattern that does not come from an item
// If the LOOM_MATERIAL slot is empty, we are crafting a pattern that does not come from an item
return action.getType() == ItemStackRequestActionType.CRAFT_LOOM && inventory.getItem(2).isEmpty();
}

Expand All @@ -135,17 +133,19 @@ public ItemStackResponse translateSpecialRequest(GeyserSession session, Inventor
return rejectRequest(request);
}

// Get the patterns compound tag
List<NbtMap> newBlockEntityTag = craftData.getResultItems()[0].getTag().getList("Patterns", NbtType.COMPOUND);
// Get the pattern that the Bedrock client requests - the last pattern in the Patterns list
NbtMap pattern = newBlockEntityTag.get(newBlockEntityTag.size() - 1);
String bedrockPattern = ((CraftLoomAction) headerData).getPatternId();

// Get the Java index of this pattern
int index = PATTERN_TO_INDEX.getOrDefault(bedrockPattern, -1);
if (index == -1) {
return rejectRequest(request);
}

// Get the patterns compound tag
List<NbtMap> newBlockEntityTag = craftData.getResultItems()[0].getTag().getList("Patterns", NbtType.COMPOUND);
// Get the pattern that the Bedrock client requests - the last pattern in the Patterns list
NbtMap pattern = newBlockEntityTag.get(newBlockEntityTag.size() - 1);

// Java's formula: 4 * row + col
// And the Java loom window has a fixed row/width of four
// So... Number / 4 = row (so we don't have to bother there), and number % 4 is our column, which leads us back to our index. :)
Expand All @@ -156,10 +156,7 @@ public ItemStackResponse translateSpecialRequest(GeyserSession session, Inventor
inputCopy.setNetId(session.getNextItemNetId());
BannerPatternLayer bannerPatternLayer = BannerItem.getJavaBannerPattern(session, pattern); // TODO
if (bannerPatternLayer != null) {
List<BannerPatternLayer> patternsList = inputCopy.getComponent(DataComponentType.BANNER_PATTERNS);
if (patternsList == null) {
patternsList = new ArrayList<>();
}
List<BannerPatternLayer> patternsList = new ArrayList<>(inputCopy.getComponentElseGet(DataComponentType.BANNER_PATTERNS, ArrayList::new));
patternsList.add(bannerPatternLayer);
inputCopy.getOrCreateComponents().put(DataComponentType.BANNER_PATTERNS, patternsList);
}
Expand Down

0 comments on commit 0416b55

Please sign in to comment.