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.
This commit is contained in:
AJ Ferguson 2019-12-02 00:48:27 -09:00
parent d07404406b
commit 4eeadc6d21
3 changed files with 225 additions and 2 deletions

View File

@ -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;
}
}

View File

@ -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<com.nukkitx.nbt.tag.CompoundTag> 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<com.nukkitx.nbt.tag.StringTag> tags = new ArrayList<>();
for (Object value : listTag.getValue()) {
if (!(value instanceof Tag))

View File

@ -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;
}
}