3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-12-27 08:30:12 +01:00

Fix anvils for 1.18.30 Bedrock

Dieser Commit ist enthalten in:
Camotoy 2022-04-20 21:39:35 -04:00
Ursprung e923325246
Commit 575fe98c0f
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 7EEFB66FE798081F
4 geänderte Dateien mit 69 neuen und 29 gelöschten Zeilen

Datei anzeigen

@ -26,8 +26,14 @@
package org.geysermc.geyser.inventory; package org.geysermc.geyser.inventory;
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; 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.Getter;
import lombok.Setter; 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 * 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 * The new name of the item as received from Bedrock
*/ */
@Nullable
private String newName = null; private String newName = null;
private GeyserItemStack lastInput = GeyserItemStack.EMPTY; private GeyserItemStack lastInput = GeyserItemStack.EMPTY;
@ -59,6 +66,36 @@ public class AnvilContainer extends Container {
super(title, id, size, containerType, playerInventory); 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() { public GeyserItemStack getInput() {
return getItem(0); return getItem(0);
} }

Datei anzeigen

@ -384,19 +384,19 @@ public class AnvilInventoryUpdater extends InventoryUpdater {
if (enchantTag.get("id") instanceof StringTag javaEnchId) { if (enchantTag.get("id") instanceof StringTag javaEnchId) {
JavaEnchantment enchantment = JavaEnchantment.getByJavaIdentifier(javaEnchId.getValue()); JavaEnchantment enchantment = JavaEnchantment.getByJavaIdentifier(javaEnchId.getValue());
if (enchantment == null) { if (enchantment == null) {
GeyserImpl.getInstance().getLogger().debug("Unknown java enchantment: " + javaEnchId.getValue()); GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment in anvil: " + javaEnchId.getValue());
continue; continue;
} }
Tag javaEnchLvl = enchantTag.get("lvl"); Tag javaEnchLvl = enchantTag.get("lvl");
if (!(javaEnchLvl instanceof ShortTag || javaEnchLvl instanceof IntTag)) if (javaEnchLvl == null || !(javaEnchLvl.getValue() instanceof Number number))
continue; continue;
// Handle duplicate enchantments // Handle duplicate enchantments
if (bedrock) { if (bedrock) {
enchantments.putIfAbsent(enchantment, ((Number) javaEnchLvl.getValue()).intValue()); enchantments.putIfAbsent(enchantment, number.intValue());
} else { } else {
enchantments.mergeInt(enchantment, ((Number) javaEnchLvl.getValue()).intValue(), Math::max); enchantments.mergeInt(enchantment, number.intValue(), Math::max);
} }
} }
} }

Datei anzeigen

@ -27,7 +27,12 @@ package org.geysermc.geyser.translator.inventory;
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; 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.ContainerSlotType;
import com.nukkitx.protocol.bedrock.data.inventory.ItemStackRequest;
import com.nukkitx.protocol.bedrock.data.inventory.StackRequestSlotInfoData; 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.AnvilContainer;
import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.Inventory;
import org.geysermc.geyser.inventory.PlayerInventory; 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.BedrockContainerSlot;
import org.geysermc.geyser.inventory.updater.AnvilInventoryUpdater; import org.geysermc.geyser.inventory.updater.AnvilInventoryUpdater;
import java.util.Objects;
public class AnvilInventoryTranslator extends AbstractBlockInventoryTranslator { public class AnvilInventoryTranslator extends AbstractBlockInventoryTranslator {
public AnvilInventoryTranslator() { public AnvilInventoryTranslator() {
super(3, "minecraft:anvil[facing=north]", com.nukkitx.protocol.bedrock.data.inventory.ContainerType.ANVIL, AnvilInventoryUpdater.INSTANCE, super(3, "minecraft:anvil[facing=north]", com.nukkitx.protocol.bedrock.data.inventory.ContainerType.ANVIL, AnvilInventoryUpdater.INSTANCE,
"minecraft:chipped_anvil", "minecraft:damaged_anvil"); "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 @Override
public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) { public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) {
return switch (slotInfoData.getContainer()) { return switch (slotInfoData.getContainer()) {

Datei anzeigen

@ -25,15 +25,12 @@
package org.geysermc.geyser.translator.protocol.bedrock; 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 com.nukkitx.protocol.bedrock.packet.FilterTextPacket;
import org.geysermc.geyser.inventory.AnvilContainer; import org.geysermc.geyser.inventory.AnvilContainer;
import org.geysermc.geyser.inventory.CartographyContainer; import org.geysermc.geyser.inventory.CartographyContainer;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator; 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. * 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); packet.setFromServer(true);
if (session.getOpenInventory() instanceof AnvilContainer anvilContainer) { if (session.getOpenInventory() instanceof AnvilContainer anvilContainer) {
anvilContainer.setNewName(packet.getText()); packet.setText(anvilContainer.checkForRename(session, 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);
session.getInventoryTranslator().updateSlot(session, anvilContainer, 1); session.getInventoryTranslator().updateSlot(session, anvilContainer, 1);
} }
session.sendUpstreamPacket(packet); session.sendUpstreamPacket(packet);