2019-07-29 22:20:48 +00:00
|
|
|
/*
|
2020-01-09 03:05:42 +00:00
|
|
|
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
|
2019-07-29 22:20:48 +00:00
|
|
|
*
|
2020-07-30 20:10:15 +00:00
|
|
|
* 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:
|
2019-07-29 22:20:48 +00:00
|
|
|
*
|
2020-07-30 20:10:15 +00:00
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
* all copies or substantial portions of the Software.
|
2019-07-29 22:20:48 +00:00
|
|
|
*
|
2020-07-30 20:10:15 +00:00
|
|
|
* 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.
|
2019-07-29 22:20:48 +00:00
|
|
|
*
|
2020-07-30 20:10:15 +00:00
|
|
|
* @author GeyserMC
|
|
|
|
* @link https://github.com/GeyserMC/Geyser
|
2019-07-29 22:20:48 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
package org.geysermc.connector.network.translators.item;
|
|
|
|
|
|
|
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
2020-07-06 22:36:04 +00:00
|
|
|
import com.github.steveice10.opennbt.tag.builtin.*;
|
2020-07-05 20:58:43 +00:00
|
|
|
import com.nukkitx.nbt.NbtList;
|
|
|
|
import com.nukkitx.nbt.NbtMap;
|
|
|
|
import com.nukkitx.nbt.NbtMapBuilder;
|
|
|
|
import com.nukkitx.nbt.NbtType;
|
2020-06-23 00:11:09 +00:00
|
|
|
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
2020-04-22 21:26:16 +00:00
|
|
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
|
|
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
2020-08-30 04:18:23 +00:00
|
|
|
import net.kyori.adventure.text.Component;
|
2020-07-06 22:36:04 +00:00
|
|
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
|
|
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
2019-12-21 17:35:48 +00:00
|
|
|
import org.geysermc.connector.GeyserConnector;
|
2020-04-22 21:26:16 +00:00
|
|
|
import org.geysermc.connector.network.session.GeyserSession;
|
2020-05-25 01:07:05 +00:00
|
|
|
import org.geysermc.connector.network.translators.ItemRemapper;
|
2020-09-15 00:50:07 +00:00
|
|
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
2020-08-28 18:36:24 +00:00
|
|
|
import org.geysermc.connector.utils.FileUtils;
|
2020-07-05 23:35:51 +00:00
|
|
|
import org.geysermc.connector.utils.LanguageUtils;
|
2020-11-16 23:57:57 +00:00
|
|
|
import org.geysermc.connector.network.translators.chat.MessageTranslator;
|
2020-04-22 21:26:16 +00:00
|
|
|
import org.reflections.Reflections;
|
2019-07-29 22:20:48 +00:00
|
|
|
|
2020-06-15 18:24:52 +00:00
|
|
|
import java.util.*;
|
2020-04-22 21:26:16 +00:00
|
|
|
import java.util.stream.Collectors;
|
2019-07-29 22:20:48 +00:00
|
|
|
|
2020-05-25 01:07:05 +00:00
|
|
|
public abstract class ItemTranslator {
|
|
|
|
private static final Int2ObjectMap<ItemTranslator> ITEM_STACK_TRANSLATORS = new Int2ObjectOpenHashMap<>();
|
|
|
|
private static final List<NbtItemStackTranslator> NBT_TRANSLATORS;
|
2020-04-29 15:58:29 +00:00
|
|
|
|
2020-05-25 01:07:05 +00:00
|
|
|
protected ItemTranslator() {
|
|
|
|
}
|
2019-12-31 03:55:17 +00:00
|
|
|
|
2020-05-25 01:07:05 +00:00
|
|
|
public static void init() {
|
|
|
|
// no-op
|
|
|
|
}
|
2019-12-31 03:55:17 +00:00
|
|
|
|
2020-05-25 01:07:05 +00:00
|
|
|
static {
|
|
|
|
/* Load item translators */
|
2020-10-07 22:51:36 +00:00
|
|
|
Reflections ref = GeyserConnector.getInstance().useXmlReflections() ? FileUtils.getReflections("org.geysermc.connector.network.translators.item") : new Reflections("org.geysermc.connector.network.translators.item");
|
2020-04-22 21:26:16 +00:00
|
|
|
|
|
|
|
Map<NbtItemStackTranslator, Integer> loadedNbtItemTranslators = new HashMap<>();
|
|
|
|
for (Class<?> clazz : ref.getTypesAnnotatedWith(ItemRemapper.class)) {
|
|
|
|
int priority = clazz.getAnnotation(ItemRemapper.class).priority();
|
|
|
|
|
|
|
|
GeyserConnector.getInstance().getLogger().debug("Found annotated item translator: " + clazz.getCanonicalName());
|
|
|
|
|
|
|
|
try {
|
|
|
|
if (NbtItemStackTranslator.class.isAssignableFrom(clazz)) {
|
|
|
|
NbtItemStackTranslator nbtItemTranslator = (NbtItemStackTranslator) clazz.newInstance();
|
|
|
|
loadedNbtItemTranslators.put(nbtItemTranslator, priority);
|
|
|
|
continue;
|
|
|
|
}
|
2020-05-25 01:07:05 +00:00
|
|
|
ItemTranslator itemStackTranslator = (ItemTranslator) clazz.newInstance();
|
2020-04-22 21:26:16 +00:00
|
|
|
List<ItemEntry> appliedItems = itemStackTranslator.getAppliedItems();
|
|
|
|
for (ItemEntry item : appliedItems) {
|
2020-05-25 01:07:05 +00:00
|
|
|
ItemTranslator registered = ITEM_STACK_TRANSLATORS.get(item.getJavaId());
|
2020-04-22 21:26:16 +00:00
|
|
|
if (registered != null) {
|
2020-07-05 23:35:51 +00:00
|
|
|
GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.item.already_registered", clazz.getCanonicalName(), registered.getClass().getCanonicalName(), item.getJavaIdentifier()));
|
2020-04-22 21:26:16 +00:00
|
|
|
continue;
|
|
|
|
}
|
2020-05-25 01:07:05 +00:00
|
|
|
ITEM_STACK_TRANSLATORS.put(item.getJavaId(), itemStackTranslator);
|
2020-04-22 21:26:16 +00:00
|
|
|
}
|
|
|
|
} catch (InstantiationException | IllegalAccessException e) {
|
2020-07-05 23:35:51 +00:00
|
|
|
GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.item.failed", clazz.getCanonicalName()));
|
2020-04-22 21:26:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-25 01:07:05 +00:00
|
|
|
NBT_TRANSLATORS = loadedNbtItemTranslators.keySet().stream().sorted(Comparator.comparingInt(loadedNbtItemTranslators::get)).collect(Collectors.toList());
|
2020-04-22 21:26:16 +00:00
|
|
|
}
|
|
|
|
|
2020-05-25 01:07:05 +00:00
|
|
|
public static ItemStack translateToJava(ItemData data) {
|
2020-04-22 21:26:16 +00:00
|
|
|
if (data == null) {
|
|
|
|
return new ItemStack(0);
|
|
|
|
}
|
2020-05-25 01:07:05 +00:00
|
|
|
ItemEntry javaItem = ItemRegistry.getItem(data);
|
2019-07-29 22:20:48 +00:00
|
|
|
|
2020-04-22 21:26:16 +00:00
|
|
|
ItemStack itemStack;
|
2020-05-25 01:07:05 +00:00
|
|
|
ItemTranslator itemStackTranslator = ITEM_STACK_TRANSLATORS.get(javaItem.getJavaId());
|
2020-04-22 21:26:16 +00:00
|
|
|
if (itemStackTranslator != null) {
|
|
|
|
itemStack = itemStackTranslator.translateToJava(data, javaItem);
|
|
|
|
} else {
|
|
|
|
itemStack = DEFAULT_TRANSLATOR.translateToJava(data, javaItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (itemStack != null && itemStack.getNbt() != null) {
|
2020-05-25 01:07:05 +00:00
|
|
|
for (NbtItemStackTranslator translator : NBT_TRANSLATORS) {
|
2020-04-22 21:26:16 +00:00
|
|
|
if (translator.acceptItem(javaItem)) {
|
|
|
|
translator.translateToJava(itemStack.getNbt(), javaItem);
|
|
|
|
}
|
2019-12-03 00:53:46 +00:00
|
|
|
}
|
2019-08-04 22:23:19 +00:00
|
|
|
}
|
2020-04-22 21:26:16 +00:00
|
|
|
return itemStack;
|
2019-07-29 22:20:48 +00:00
|
|
|
}
|
|
|
|
|
2020-06-02 20:33:37 +00:00
|
|
|
public static ItemData translateToBedrock(GeyserSession session, ItemStack stack) {
|
2019-07-29 22:20:48 +00:00
|
|
|
if (stack == null) {
|
2020-01-31 01:05:57 +00:00
|
|
|
return ItemData.AIR;
|
2019-07-29 22:20:48 +00:00
|
|
|
}
|
|
|
|
|
2020-05-25 01:07:05 +00:00
|
|
|
ItemEntry bedrockItem = ItemRegistry.getItem(stack);
|
2020-04-22 21:26:16 +00:00
|
|
|
|
2020-06-15 18:24:52 +00:00
|
|
|
com.github.steveice10.opennbt.tag.builtin.CompoundTag nbt = stack.getNbt() != null ? stack.getNbt().clone() : null;
|
|
|
|
|
|
|
|
// This is a fallback for maps with no nbt
|
|
|
|
if (nbt == null && bedrockItem.getJavaIdentifier().equals("minecraft:filled_map")) {
|
|
|
|
nbt = new com.github.steveice10.opennbt.tag.builtin.CompoundTag("");
|
|
|
|
nbt.put(new IntTag("map", 0));
|
|
|
|
}
|
|
|
|
|
|
|
|
ItemStack itemStack = new ItemStack(stack.getId(), stack.getAmount(), nbt);
|
2020-04-29 15:58:29 +00:00
|
|
|
|
2020-06-15 18:24:52 +00:00
|
|
|
if (nbt != null) {
|
2020-05-25 01:07:05 +00:00
|
|
|
for (NbtItemStackTranslator translator : NBT_TRANSLATORS) {
|
2020-04-22 21:26:16 +00:00
|
|
|
if (translator.acceptItem(bedrockItem)) {
|
2020-08-25 02:05:39 +00:00
|
|
|
translator.translateToBedrock(session, nbt, bedrockItem);
|
2019-12-02 09:48:27 +00:00
|
|
|
}
|
|
|
|
}
|
2019-08-04 22:23:19 +00:00
|
|
|
}
|
2020-04-04 20:23:02 +00:00
|
|
|
|
2020-08-25 02:05:39 +00:00
|
|
|
translateDisplayProperties(session, nbt);
|
|
|
|
|
2020-06-02 20:33:37 +00:00
|
|
|
ItemData itemData;
|
2020-05-25 01:07:05 +00:00
|
|
|
ItemTranslator itemStackTranslator = ITEM_STACK_TRANSLATORS.get(bedrockItem.getJavaId());
|
2020-04-22 21:26:16 +00:00
|
|
|
if (itemStackTranslator != null) {
|
2020-06-02 20:33:37 +00:00
|
|
|
itemData = itemStackTranslator.translateToBedrock(itemStack, bedrockItem);
|
2020-04-22 21:26:16 +00:00
|
|
|
} else {
|
2020-06-02 20:33:37 +00:00
|
|
|
itemData = DEFAULT_TRANSLATOR.translateToBedrock(itemStack, bedrockItem);
|
2020-04-12 00:45:31 +00:00
|
|
|
}
|
2020-06-02 20:33:37 +00:00
|
|
|
|
2020-09-15 00:50:07 +00:00
|
|
|
if (nbt != null) {
|
|
|
|
// Translate the canDestroy and canPlaceOn Java NBT
|
|
|
|
ListTag canDestroy = nbt.get("CanDestroy");
|
|
|
|
String[] canBreak = new String[0];
|
|
|
|
ListTag canPlaceOn = nbt.get("CanPlaceOn");
|
|
|
|
String[] canPlace = new String[0];
|
|
|
|
canBreak = getCanModify(canDestroy, canBreak);
|
|
|
|
canPlace = getCanModify(canPlaceOn, canPlace);
|
|
|
|
itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), itemData.getTag(), canPlace, canBreak);
|
|
|
|
}
|
|
|
|
|
2020-06-02 20:33:37 +00:00
|
|
|
return itemData;
|
2019-07-29 22:20:48 +00:00
|
|
|
}
|
|
|
|
|
2020-09-15 00:50:07 +00:00
|
|
|
/**
|
|
|
|
* Translates the Java NBT of canDestroy and canPlaceOn to its Bedrock counterparts.
|
|
|
|
* In Java, this is treated as normal NBT, but in Bedrock, these arguments are extra parts of the item data itself.
|
|
|
|
* @param canModifyJava the list of items in Java
|
|
|
|
* @param canModifyBedrock the empty list of items in Bedrock
|
|
|
|
* @return the new list of items in Bedrock
|
|
|
|
*/
|
|
|
|
private static String[] getCanModify(ListTag canModifyJava, String[] canModifyBedrock) {
|
|
|
|
if (canModifyJava != null && canModifyJava.size() > 0) {
|
|
|
|
canModifyBedrock = new String[canModifyJava.size()];
|
|
|
|
for (int i = 0; i < canModifyBedrock.length; i++) {
|
|
|
|
// Get the Java identifier of the block that can be placed
|
|
|
|
String block = ((StringTag) canModifyJava.get(i)).getValue();
|
|
|
|
// Sometimes this is done but it's still valid
|
|
|
|
if (!block.startsWith("minecraft:")) block = "minecraft:" + block;
|
|
|
|
// Get the Bedrock identifier of the item and replace it.
|
|
|
|
// This will unfortunately be limited - for example, beds and banners will be translated weirdly
|
|
|
|
canModifyBedrock[i] = BlockTranslator.getBedrockBlockIdentifier(block).replace("minecraft:", "");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return canModifyBedrock;
|
|
|
|
}
|
|
|
|
|
2020-05-25 01:07:05 +00:00
|
|
|
private static final ItemTranslator DEFAULT_TRANSLATOR = new ItemTranslator() {
|
|
|
|
@Override
|
|
|
|
public List<ItemEntry> getAppliedItems() {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) {
|
|
|
|
if (itemStack == null) {
|
|
|
|
return ItemData.AIR;
|
|
|
|
}
|
|
|
|
if (itemStack.getNbt() == null) {
|
|
|
|
return ItemData.of(itemEntry.getBedrockId(), (short) itemEntry.getBedrockData(), itemStack.getAmount());
|
2020-04-12 00:45:31 +00:00
|
|
|
}
|
2020-05-25 01:07:05 +00:00
|
|
|
return ItemData.of(itemEntry.getBedrockId(), (short) itemEntry.getBedrockData(), itemStack.getAmount(), this.translateNbtToBedrock(itemStack.getNbt()));
|
2019-07-29 22:20:48 +00:00
|
|
|
}
|
|
|
|
|
2020-05-25 01:07:05 +00:00
|
|
|
public ItemStack translateToJava(ItemData itemData, ItemEntry itemEntry) {
|
|
|
|
if (itemData == null) return null;
|
|
|
|
if (itemData.getTag() == null) {
|
|
|
|
return new ItemStack(itemEntry.getJavaId(), itemData.getCount(), new com.github.steveice10.opennbt.tag.builtin.CompoundTag(""));
|
|
|
|
}
|
2020-07-05 20:58:43 +00:00
|
|
|
return new ItemStack(itemEntry.getJavaId(), itemData.getCount(), this.translateToJavaNBT("", itemData.getTag()));
|
2019-07-29 22:20:48 +00:00
|
|
|
}
|
|
|
|
|
2020-05-25 01:07:05 +00:00
|
|
|
public abstract List<ItemEntry> getAppliedItems();
|
|
|
|
|
2020-07-05 20:58:43 +00:00
|
|
|
public NbtMap translateNbtToBedrock(com.github.steveice10.opennbt.tag.builtin.CompoundTag tag) {
|
2020-11-05 21:36:22 +00:00
|
|
|
NbtMapBuilder builder = NbtMap.builder();
|
2020-05-25 01:07:05 +00:00
|
|
|
if (tag.getValue() != null && !tag.getValue().isEmpty()) {
|
|
|
|
for (String str : tag.getValue().keySet()) {
|
|
|
|
com.github.steveice10.opennbt.tag.builtin.Tag javaTag = tag.get(str);
|
2020-07-05 20:58:43 +00:00
|
|
|
Object translatedTag = translateToBedrockNBT(javaTag);
|
2020-05-25 01:07:05 +00:00
|
|
|
if (translatedTag == null)
|
|
|
|
continue;
|
|
|
|
|
2020-11-05 21:36:22 +00:00
|
|
|
builder.put(javaTag.getName(), translatedTag);
|
2019-10-10 00:11:50 +00:00
|
|
|
}
|
2019-07-31 19:59:23 +00:00
|
|
|
}
|
2020-07-05 20:58:43 +00:00
|
|
|
return builder.build();
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
2020-07-05 20:58:43 +00:00
|
|
|
private Object translateToBedrockNBT(com.github.steveice10.opennbt.tag.builtin.Tag tag) {
|
2020-05-25 01:07:05 +00:00
|
|
|
if (tag instanceof ByteArrayTag) {
|
2020-07-05 20:58:43 +00:00
|
|
|
return ((ByteArrayTag) tag).getValue();
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (tag instanceof ByteTag) {
|
2020-07-05 20:58:43 +00:00
|
|
|
return ((ByteTag) tag).getValue();
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (tag instanceof DoubleTag) {
|
2020-07-05 20:58:43 +00:00
|
|
|
return ((DoubleTag) tag).getValue();
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (tag instanceof FloatTag) {
|
2020-07-05 20:58:43 +00:00
|
|
|
return ((FloatTag) tag).getValue();
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (tag instanceof IntArrayTag) {
|
2020-07-05 20:58:43 +00:00
|
|
|
return ((IntArrayTag) tag).getValue();
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (tag instanceof IntTag) {
|
2020-07-05 20:58:43 +00:00
|
|
|
return ((IntTag) tag).getValue();
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (tag instanceof LongArrayTag) {
|
2020-06-29 18:59:51 +00:00
|
|
|
//Long array tag does not exist in BE
|
|
|
|
//LongArrayTag longArrayTag = (LongArrayTag) tag;
|
|
|
|
//return new com.nukkitx.nbt.tag.LongArrayTag(longArrayTag.getName(), longArrayTag.getValue());
|
|
|
|
return null;
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (tag instanceof LongTag) {
|
2020-07-05 20:58:43 +00:00
|
|
|
return ((LongTag) tag).getValue();
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (tag instanceof ShortTag) {
|
2020-07-05 20:58:43 +00:00
|
|
|
return ((ShortTag) tag).getValue();
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (tag instanceof StringTag) {
|
2020-07-05 20:58:43 +00:00
|
|
|
return ((StringTag) tag).getValue();
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (tag instanceof ListTag) {
|
|
|
|
ListTag listTag = (ListTag) tag;
|
|
|
|
|
2020-07-05 20:58:43 +00:00
|
|
|
List<Object> tagList = new ArrayList<>();
|
2020-05-25 01:07:05 +00:00
|
|
|
for (com.github.steveice10.opennbt.tag.builtin.Tag value : listTag) {
|
|
|
|
tagList.add(translateToBedrockNBT(value));
|
2019-10-10 00:11:50 +00:00
|
|
|
}
|
2020-07-05 20:58:43 +00:00
|
|
|
NbtType<?> type = NbtType.COMPOUND;
|
2020-05-25 01:07:05 +00:00
|
|
|
if (!tagList.isEmpty()) {
|
2020-07-05 20:58:43 +00:00
|
|
|
type = NbtType.byClass(tagList.get(0).getClass());
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
2020-07-05 20:58:43 +00:00
|
|
|
return new NbtList(type, tagList);
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (tag instanceof com.github.steveice10.opennbt.tag.builtin.CompoundTag) {
|
|
|
|
com.github.steveice10.opennbt.tag.builtin.CompoundTag compoundTag = (com.github.steveice10.opennbt.tag.builtin.CompoundTag) tag;
|
|
|
|
return translateNbtToBedrock(compoundTag);
|
2019-07-31 19:59:23 +00:00
|
|
|
}
|
2019-07-29 22:20:48 +00:00
|
|
|
|
2020-05-25 01:07:05 +00:00
|
|
|
return null;
|
2019-07-29 22:20:48 +00:00
|
|
|
}
|
|
|
|
|
2020-07-05 20:58:43 +00:00
|
|
|
public com.github.steveice10.opennbt.tag.builtin.CompoundTag translateToJavaNBT(String name, NbtMap tag) {
|
|
|
|
com.github.steveice10.opennbt.tag.builtin.CompoundTag javaTag = new com.github.steveice10.opennbt.tag.builtin.CompoundTag(name);
|
2020-05-25 01:07:05 +00:00
|
|
|
Map<String, com.github.steveice10.opennbt.tag.builtin.Tag> javaValue = javaTag.getValue();
|
2020-07-05 20:58:43 +00:00
|
|
|
if (tag != null && !tag.isEmpty()) {
|
|
|
|
for (String str : tag.keySet()) {
|
|
|
|
Object bedrockTag = tag.get(str);
|
2020-07-14 07:18:11 +00:00
|
|
|
com.github.steveice10.opennbt.tag.builtin.Tag translatedTag = translateToJavaNBT(str, bedrockTag);
|
2020-05-25 01:07:05 +00:00
|
|
|
if (translatedTag == null)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
javaValue.put(translatedTag.getName(), translatedTag);
|
2020-04-15 19:24:57 +00:00
|
|
|
}
|
|
|
|
}
|
2019-07-29 22:20:48 +00:00
|
|
|
|
2020-05-25 01:07:05 +00:00
|
|
|
javaTag.setValue(javaValue);
|
|
|
|
return javaTag;
|
2019-07-29 22:20:48 +00:00
|
|
|
}
|
|
|
|
|
2020-07-05 20:58:43 +00:00
|
|
|
private com.github.steveice10.opennbt.tag.builtin.Tag translateToJavaNBT(String name, Object object) {
|
|
|
|
if (object instanceof int[]) {
|
|
|
|
return new IntArrayTag(name, (int[]) object);
|
2019-07-29 22:20:48 +00:00
|
|
|
}
|
2020-05-25 01:07:05 +00:00
|
|
|
|
2020-07-05 20:58:43 +00:00
|
|
|
if (object instanceof byte[]) {
|
|
|
|
return new ByteArrayTag(name, (byte[]) object);
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
2020-07-05 20:58:43 +00:00
|
|
|
|
|
|
|
if (object instanceof Byte) {
|
|
|
|
return new ByteTag(name, (byte) object);
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
2020-07-05 20:58:43 +00:00
|
|
|
if (object instanceof Float) {
|
|
|
|
return new FloatTag(name, (float) object);
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
2020-07-05 20:58:43 +00:00
|
|
|
if (object instanceof Double) {
|
|
|
|
return new DoubleTag(name, (double) object);
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
2020-07-05 20:58:43 +00:00
|
|
|
if (object instanceof Integer) {
|
|
|
|
return new IntTag(name, (int) object);
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
2020-07-05 20:58:43 +00:00
|
|
|
if (object instanceof long[]) {
|
|
|
|
return new LongArrayTag(name, (long[]) object);
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
2020-07-05 20:58:43 +00:00
|
|
|
if (object instanceof Long) {
|
|
|
|
return new LongTag(name, (long) object);
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
2020-07-05 20:58:43 +00:00
|
|
|
if (object instanceof Short) {
|
|
|
|
return new ShortTag(name, (short) object);
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
2020-07-05 20:58:43 +00:00
|
|
|
if (object instanceof String) {
|
|
|
|
return new StringTag(name, (String) object);
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
2020-07-05 20:58:43 +00:00
|
|
|
if (object instanceof List) {
|
2020-05-25 01:07:05 +00:00
|
|
|
List<com.github.steveice10.opennbt.tag.builtin.Tag> tags = new ArrayList<>();
|
|
|
|
|
2020-07-05 20:58:43 +00:00
|
|
|
for (Object value : (List<?>) object) {
|
|
|
|
com.github.steveice10.opennbt.tag.builtin.Tag javaTag = translateToJavaNBT("", value);
|
2020-05-25 01:07:05 +00:00
|
|
|
if (javaTag != null)
|
|
|
|
tags.add(javaTag);
|
|
|
|
}
|
2020-07-05 20:58:43 +00:00
|
|
|
return new ListTag(name, tags);
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
2020-07-05 20:58:43 +00:00
|
|
|
if (object instanceof NbtMap) {
|
|
|
|
NbtMap map = (NbtMap) object;
|
2020-07-14 07:18:11 +00:00
|
|
|
return translateToJavaNBT(name, map);
|
2020-05-25 01:07:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
2019-12-31 03:55:17 +00:00
|
|
|
}
|
|
|
|
|
2020-08-25 02:05:39 +00:00
|
|
|
/**
|
|
|
|
* Translates the display name of the item
|
|
|
|
* @param session the Bedrock client's session
|
|
|
|
* @param tag the tag to translate
|
|
|
|
*/
|
|
|
|
public static void translateDisplayProperties(GeyserSession session, CompoundTag tag) {
|
|
|
|
if (tag != null) {
|
|
|
|
CompoundTag display = tag.get("display");
|
2020-11-16 23:57:57 +00:00
|
|
|
if (display != null && display.contains("Name")) {
|
2020-08-25 02:05:39 +00:00
|
|
|
String name = ((StringTag) display.get("Name")).getValue();
|
|
|
|
|
2020-11-16 23:57:57 +00:00
|
|
|
// Get the translated name and prefix it with a reset char
|
|
|
|
name = MessageTranslator.convertMessageLenient(name, session.getLocale());
|
2020-08-25 02:05:39 +00:00
|
|
|
|
2020-11-16 23:57:57 +00:00
|
|
|
// Add the new name tag
|
|
|
|
display.put(new StringTag("Name", name));
|
2020-08-25 02:05:39 +00:00
|
|
|
|
2020-11-16 23:57:57 +00:00
|
|
|
// Add to the new root tag
|
|
|
|
tag.put(display);
|
2020-08-25 02:05:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-17 04:52:39 +00:00
|
|
|
/**
|
|
|
|
* Checks if an {@link ItemStack} is equal to another item stack
|
|
|
|
*
|
|
|
|
* @param itemStack the item stack to check
|
|
|
|
* @param equalsItemStack the item stack to check if equal to
|
|
|
|
* @param checkAmount if the amount should be taken into account
|
|
|
|
* @param trueIfAmountIsGreater if this should return true if the amount of the
|
|
|
|
* first item stack is greater than that of the second
|
|
|
|
* @param checkNbt if NBT data should be checked
|
|
|
|
* @return if an item stack is equal to another item stack
|
|
|
|
*/
|
|
|
|
public boolean equals(ItemStack itemStack, ItemStack equalsItemStack, boolean checkAmount, boolean trueIfAmountIsGreater, boolean checkNbt) {
|
|
|
|
if (itemStack.getId() != equalsItemStack.getId()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (checkAmount) {
|
|
|
|
if (trueIfAmountIsGreater) {
|
|
|
|
if (itemStack.getAmount() < equalsItemStack.getAmount()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (itemStack.getAmount() != equalsItemStack.getAmount()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!checkNbt) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if ((itemStack.getNbt() == null || itemStack.getNbt().isEmpty()) && (equalsItemStack.getNbt() != null && !equalsItemStack.getNbt().isEmpty())) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((itemStack.getNbt() != null && !itemStack.getNbt().isEmpty() && (equalsItemStack.getNbt() == null || !equalsItemStack.getNbt().isEmpty()))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (itemStack.getNbt() != null && equalsItemStack.getNbt() != null) {
|
|
|
|
return itemStack.getNbt().equals(equalsItemStack.getNbt());
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-07-29 22:20:48 +00:00
|
|
|
}
|