Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-26 00:00:41 +01:00
Fix anvils for 1.18.30 Bedrock
Dieser Commit ist enthalten in:
Ursprung
e923325246
Commit
575fe98c0f
@ -26,8 +26,14 @@
|
||||
package org.geysermc.geyser.inventory;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
import org.geysermc.geyser.util.ItemUtils;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Used to determine if rename packets should be sent and stores
|
||||
@ -48,6 +54,7 @@ public class AnvilContainer extends Container {
|
||||
/**
|
||||
* The new name of the item as received from Bedrock
|
||||
*/
|
||||
@Nullable
|
||||
private String newName = null;
|
||||
|
||||
private GeyserItemStack lastInput = GeyserItemStack.EMPTY;
|
||||
@ -59,6 +66,36 @@ public class AnvilContainer extends Container {
|
||||
super(title, id, size, containerType, playerInventory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name to use instead for renaming.
|
||||
*/
|
||||
public String checkForRename(GeyserSession session, String rename) {
|
||||
String correctRename;
|
||||
newName = rename;
|
||||
|
||||
String originalName = ItemUtils.getCustomName(getInput().getNbt());
|
||||
|
||||
String plainOriginalName = MessageTranslator.convertToPlainText(originalName, session.getLocale());
|
||||
String plainNewName = MessageTranslator.convertToPlainText(rename, session.getLocale());
|
||||
if (!plainOriginalName.equals(plainNewName)) {
|
||||
// Strip out formatting since Java Edition does not allow it
|
||||
correctRename = plainNewName;
|
||||
// Java Edition sends a packet every time an item is renamed even slightly in GUI. Fortunately, this works out for us now
|
||||
ServerboundRenameItemPacket renameItemPacket = new ServerboundRenameItemPacket(plainNewName);
|
||||
session.sendDownstreamPacket(renameItemPacket);
|
||||
} else {
|
||||
// Restore formatting for item since we're not renaming
|
||||
correctRename = MessageTranslator.convertMessageLenient(originalName);
|
||||
// Java Edition sends the original custom name when not renaming,
|
||||
// if there isn't a custom name an empty string is sent
|
||||
ServerboundRenameItemPacket renameItemPacket = new ServerboundRenameItemPacket(plainOriginalName);
|
||||
session.sendDownstreamPacket(renameItemPacket);
|
||||
}
|
||||
|
||||
useJavaLevelCost = false;
|
||||
return correctRename;
|
||||
}
|
||||
|
||||
public GeyserItemStack getInput() {
|
||||
return getItem(0);
|
||||
}
|
||||
|
@ -384,19 +384,19 @@ public class AnvilInventoryUpdater extends InventoryUpdater {
|
||||
if (enchantTag.get("id") instanceof StringTag javaEnchId) {
|
||||
JavaEnchantment enchantment = JavaEnchantment.getByJavaIdentifier(javaEnchId.getValue());
|
||||
if (enchantment == null) {
|
||||
GeyserImpl.getInstance().getLogger().debug("Unknown java enchantment: " + javaEnchId.getValue());
|
||||
GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment in anvil: " + javaEnchId.getValue());
|
||||
continue;
|
||||
}
|
||||
|
||||
Tag javaEnchLvl = enchantTag.get("lvl");
|
||||
if (!(javaEnchLvl instanceof ShortTag || javaEnchLvl instanceof IntTag))
|
||||
if (javaEnchLvl == null || !(javaEnchLvl.getValue() instanceof Number number))
|
||||
continue;
|
||||
|
||||
// Handle duplicate enchantments
|
||||
if (bedrock) {
|
||||
enchantments.putIfAbsent(enchantment, ((Number) javaEnchLvl.getValue()).intValue());
|
||||
enchantments.putIfAbsent(enchantment, number.intValue());
|
||||
} else {
|
||||
enchantments.mergeInt(enchantment, ((Number) javaEnchLvl.getValue()).intValue(), Math::max);
|
||||
enchantments.mergeInt(enchantment, number.intValue(), Math::max);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,12 @@ package org.geysermc.geyser.translator.inventory;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
|
||||
import com.nukkitx.protocol.bedrock.data.inventory.ContainerSlotType;
|
||||
import com.nukkitx.protocol.bedrock.data.inventory.ItemStackRequest;
|
||||
import com.nukkitx.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
|
||||
import com.nukkitx.protocol.bedrock.data.inventory.stackrequestactions.CraftRecipeOptionalStackRequestActionData;
|
||||
import com.nukkitx.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionData;
|
||||
import com.nukkitx.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionType;
|
||||
import com.nukkitx.protocol.bedrock.packet.ItemStackResponsePacket;
|
||||
import org.geysermc.geyser.inventory.AnvilContainer;
|
||||
import org.geysermc.geyser.inventory.Inventory;
|
||||
import org.geysermc.geyser.inventory.PlayerInventory;
|
||||
@ -35,12 +40,34 @@ import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||
import org.geysermc.geyser.inventory.updater.AnvilInventoryUpdater;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class AnvilInventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||
public AnvilInventoryTranslator() {
|
||||
super(3, "minecraft:anvil[facing=north]", com.nukkitx.protocol.bedrock.data.inventory.ContainerType.ANVIL, AnvilInventoryUpdater.INSTANCE,
|
||||
"minecraft:chipped_anvil", "minecraft:damaged_anvil");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
|
||||
return action.getType() == StackRequestActionType.CRAFT_RECIPE_OPTIONAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStackResponsePacket.Response translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
|
||||
// Guarded by shouldHandleRequestFirst check
|
||||
CraftRecipeOptionalStackRequestActionData data = (CraftRecipeOptionalStackRequestActionData) request.getActions()[0];
|
||||
AnvilContainer container = (AnvilContainer) inventory;
|
||||
|
||||
// Required as of 1.18.30 - FilterTextPackets no longer appear to be sent
|
||||
String name = request.getFilterStrings()[data.getFilteredStringIndex()];
|
||||
if (!Objects.equals(name, container.getNewName())) {
|
||||
container.checkForRename(session, name);
|
||||
}
|
||||
|
||||
return super.translateRequest(session, inventory, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) {
|
||||
return switch (slotInfoData.getContainer()) {
|
||||
|
@ -25,15 +25,12 @@
|
||||
|
||||
package org.geysermc.geyser.translator.protocol.bedrock;
|
||||
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.FilterTextPacket;
|
||||
import org.geysermc.geyser.inventory.AnvilContainer;
|
||||
import org.geysermc.geyser.inventory.CartographyContainer;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
import org.geysermc.geyser.util.ItemUtils;
|
||||
|
||||
/**
|
||||
* Used to send strings to the server and filter out unwanted words.
|
||||
@ -50,28 +47,7 @@ public class BedrockFilterTextTranslator extends PacketTranslator<FilterTextPack
|
||||
}
|
||||
packet.setFromServer(true);
|
||||
if (session.getOpenInventory() instanceof AnvilContainer anvilContainer) {
|
||||
anvilContainer.setNewName(packet.getText());
|
||||
|
||||
String originalName = ItemUtils.getCustomName(anvilContainer.getInput().getNbt());
|
||||
|
||||
String plainOriginalName = MessageTranslator.convertToPlainText(originalName, session.getLocale());
|
||||
String plainNewName = MessageTranslator.convertToPlainText(packet.getText(), session.getLocale());
|
||||
if (!plainOriginalName.equals(plainNewName)) {
|
||||
// Strip out formatting since Java Edition does not allow it
|
||||
packet.setText(plainNewName);
|
||||
// Java Edition sends a packet every time an item is renamed even slightly in GUI. Fortunately, this works out for us now
|
||||
ServerboundRenameItemPacket renameItemPacket = new ServerboundRenameItemPacket(plainNewName);
|
||||
session.sendDownstreamPacket(renameItemPacket);
|
||||
} else {
|
||||
// Restore formatting for item since we're not renaming
|
||||
packet.setText(MessageTranslator.convertMessageLenient(originalName));
|
||||
// Java Edition sends the original custom name when not renaming,
|
||||
// if there isn't a custom name an empty string is sent
|
||||
ServerboundRenameItemPacket renameItemPacket = new ServerboundRenameItemPacket(plainOriginalName);
|
||||
session.sendDownstreamPacket(renameItemPacket);
|
||||
}
|
||||
|
||||
anvilContainer.setUseJavaLevelCost(false);
|
||||
packet.setText(anvilContainer.checkForRename(session, packet.getText()));
|
||||
session.getInventoryTranslator().updateSlot(session, anvilContainer, 1);
|
||||
}
|
||||
session.sendUpstreamPacket(packet);
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren