From 4eeadc6d21233baaffabd5194566b4522f181339 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Mon, 2 Dec 2019 00:48:27 -0900 Subject: [PATCH] Start working on translating enchantments and potions Translation is only (java -> bedrock) for now. Only regular potions will translate correctly. More work will be needed to translate custom potions. --- .../network/translators/item/Enchantment.java | 85 +++++++++++++++ .../translators/item/ItemTranslator.java | 40 ++++++- .../network/translators/item/Potion.java | 102 ++++++++++++++++++ 3 files changed, 225 insertions(+), 2 deletions(-) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/item/Enchantment.java create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/item/Potion.java diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/Enchantment.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/Enchantment.java new file mode 100644 index 00000000..79b8514a --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/Enchantment.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.network.translators.item; + +import lombok.Getter; + +import java.util.Locale; + +@Getter +enum Enchantment { + PROTECTION, + FIRE_PROTECTION, + FEATHER_FALLING, + BLAST_PROTECTION, + PROJECTILE_PROTECTION, + THORNS, + RESPIRATION, + DEPTH_STRIDER, + AQUA_AFFINITY, + SHARPNESS, + SMITE, + BANE_OF_ARTHROPODS, + KNOCKBACK, + FIRE_ASPECT, + LOOTING, + EFFICIENCY, + SILK_TOUCH, + UNBREAKING, + FORTUNE, + POWER, + PUNCH, + FLAME, + INFINITY, + LUCK_OF_THE_SEA, + LURE, + FROST_WALKER, + MENDING, + BINDING_CURSE, + VANISHING_CURSE, + IMPALING, + RIPTIDE, + LOYALTY, + CHANNELING, + MULTISHOT, + PIERCING, + QUICK_CHARGE; + + private final String javaIdentifier; + + Enchantment() { + this.javaIdentifier = "minecraft:" + this.name().toLowerCase(Locale.ENGLISH); + } + + public static Enchantment getByJavaIdentifier(String javaIdentifier) { + for (Enchantment enchantment : Enchantment.values()) { + if (enchantment.javaIdentifier.equals(javaIdentifier)) { + return enchantment; + } + } + return null; + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java index 472287b7..5478a278 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java @@ -41,6 +41,7 @@ import com.github.steveice10.opennbt.tag.builtin.ShortTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import com.nukkitx.protocol.bedrock.data.ItemData; +import org.geysermc.api.Geyser; import org.geysermc.connector.console.GeyserLogger; import org.geysermc.connector.utils.MessageUtils; import org.geysermc.connector.utils.Toolbox; @@ -70,6 +71,15 @@ public class ItemTranslator { ItemEntry bedrockItem = getItem(stack); if (stack.getNbt() == null) { return ItemData.of(bedrockItem.getBedrockId(), (short) bedrockItem.getBedrockData(), stack.getAmount()); + } else if (bedrockItem.getJavaIdentifier().endsWith("potion")) { + Tag potionTag = stack.getNbt().get("Potion"); + if (potionTag instanceof StringTag) { + Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue()); + if (potion != null) { + return ItemData.of(bedrockItem.getBedrockId(), potion.getBedrockId(), stack.getAmount(), translateToBedrockNBT(stack.getNbt())); + } + Geyser.getLogger().debug("Unknown java potion: " + potionTag.getValue()); + } } return ItemData.of(bedrockItem.getBedrockId(), (short) bedrockItem.getBedrockData(), stack.getAmount(), translateToBedrockNBT(stack.getNbt())); } @@ -80,7 +90,7 @@ public class ItemTranslator { public ItemEntry getItem(ItemData data) { for (ItemEntry itemEntry : Toolbox.ITEM_ENTRIES.values()) { - if (itemEntry.getBedrockId() == data.getId() && itemEntry.getBedrockData() == data.getDamage()) { + if (itemEntry.getBedrockId() == data.getId() && (itemEntry.getBedrockData() == data.getDamage() || itemEntry.getJavaIdentifier().endsWith("potion"))) { return itemEntry; } } @@ -251,7 +261,33 @@ public class ItemTranslator { if (tag instanceof ListTag) { ListTag listTag = (ListTag) tag; - if (listTag.getName().equalsIgnoreCase("Lore")) { + if (listTag.getName().equalsIgnoreCase("Enchantments") || listTag.getName().equalsIgnoreCase("StoredEnchantments")) { + List tags = new ArrayList<>(); + for (Object value : listTag.getValue()) { + if (!(value instanceof CompoundTag)) + continue; + + Tag javaEnchLvl = ((CompoundTag) value).get("lvl"); + if (!(javaEnchLvl instanceof ShortTag)) + continue; + + Tag javaEnchId = ((CompoundTag) value).get("id"); + if (!(javaEnchId instanceof StringTag)) + continue; + + Enchantment enchantment = Enchantment.getByJavaIdentifier(((StringTag) javaEnchId).getValue()); + if (enchantment == null) { + Geyser.getLogger().debug("Unknown java enchantment: " + javaEnchId.getValue()); + continue; + } + + com.nukkitx.nbt.CompoundTagBuilder builder = com.nukkitx.nbt.tag.CompoundTag.EMPTY.toBuilder(); + builder.shortTag("lvl", ((ShortTag) javaEnchLvl).getValue()); + builder.shortTag("id", (short) enchantment.ordinal()); + tags.add(builder.buildRootTag()); + } + return new com.nukkitx.nbt.tag.ListTag<>("ench", com.nukkitx.nbt.tag.CompoundTag.class, tags); + } else if (listTag.getName().equalsIgnoreCase("Lore")) { List tags = new ArrayList<>(); for (Object value : listTag.getValue()) { if (!(value instanceof Tag)) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/Potion.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/Potion.java new file mode 100644 index 00000000..ca5cd5c0 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/Potion.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.network.translators.item; + +import lombok.Getter; + +import java.util.Locale; + +@Getter +enum Potion { + WATER(0), + MUNDANE(1), + THICK(3), + AWKWARD(4), + NIGHT_VISION(5), + LONG_NIGHT_VISION(6), + INVISIBILITY(7), + LONG_INVISIBILITY(8), + LEAPING(9), + STRONG_LEAPING(11), + LONG_LEAPING(10), + FIRE_RESISTANCE(12), + LONG_FIRE_RESISTANCE(13), + SWIFTNESS(14), + STRONG_SWIFTNESS(16), + LONG_SWIFTNESS(15), + SLOWNESS(17), + STRONG_SLOWNESS(18), //does not exist + LONG_SLOWNESS(18), + WATER_BREATHING(19), + LONG_WATER_BREATHING(20), + HEALING(21), + STRONG_HEALING(22), + HARMING(23), + STRONG_HARMING(24), + POISON(25), + STRONG_POISON(27), + LONG_POISON(26), + REGENERATION(28), + STRONG_REGENERATION(30), + LONG_REGENERATION(29), + STRENGTH(31), + STRONG_STRENGTH(33), + LONG_STRENGTH(32), + WEAKNESS(34), + LONG_WEAKNESS(35), + LUCK(2), //does not exist + TURTLE_MASTER(37), + STRONG_TURTLE_MASTER(39), + LONG_TURTLE_MASTER(38), + SLOW_FALLING(40), + LONG_SLOW_FALLING(41); + + private final String javaIdentifier; + private final short bedrockId; + + Potion(int bedrockId) { + this.javaIdentifier = "minecraft:" + this.name().toLowerCase(Locale.ENGLISH); + this.bedrockId = (short) bedrockId; + } + + public static Potion getByJavaIdentifier(String javaIdentifier) { + for (Potion potion : Potion.values()) { + if (potion.javaIdentifier.equals(javaIdentifier)) { + return potion; + } + } + return null; + } + + public static Potion getByBedrockId(short bedrockId) { + for (Potion potion : Potion.values()) { + if (potion.bedrockId == bedrockId) { + return potion; + } + } + return null; + } +}