TabooLib/src/main/scala/io/izzel/taboolib/module/tellraw/internal/InternalTellraw.java

140 lines
6.4 KiB
Java

package io.izzel.taboolib.module.tellraw.internal;
import io.izzel.taboolib.Version;
import io.izzel.taboolib.util.item.Items;
import io.izzel.taboolib.module.lite.SimpleReflection;
import io.izzel.taboolib.module.packet.TPacketHandler;
import io.izzel.taboolib.module.tellraw.TellrawVersion;
import net.minecraft.server.v1_8_R3.*;
import org.bukkit.Material;
import org.bukkit.block.ShulkerBox;
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BlockStateMeta;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.List;
import java.util.Map;
/**
* @Author 坏黑
* @Since 2018-11-07 22:54
*/
public class InternalTellraw implements AbstractTellraw {
public InternalTellraw() {
SimpleReflection.saveField(NBTTagCompound.class, "map");
SimpleReflection.saveField(NBTTagList.class, "list");
}
@Override
public void sendRawMessage(Player player, String rawMessage) {
TPacketHandler.sendPacket(player, new PacketPlayOutChat(IChatBaseComponent.ChatSerializer.a(rawMessage)));
}
@Override
public String getItemComponent(ItemStack itemStack) {
return getItemComponent(itemStack, TellrawVersion.CURRENT_VERSION);
}
@Override
public String getItemComponent(ItemStack itemStack, TellrawVersion version) {
return nbtToString(CraftItemStack.asNMSCopy(itemStack).save(new NBTTagCompound()), version);
}
@Override
public ItemStack optimizeNBT(ItemStack itemStack, List<String> nbtWhitelist) {
Object nmsItem = CraftItemStack.asNMSCopy(itemStack);
if (((net.minecraft.server.v1_8_R3.ItemStack) nmsItem).hasTag()) {
Object nbtTag = new NBTTagCompound();
Map<String, NBTBase> mapNew = (Map) SimpleReflection.getFieldValue(NBTTagCompound.class, nbtTag, "map");
Map<String, NBTBase> mapOrigin = (Map) SimpleReflection.getFieldValue(NBTTagCompound.class, ((net.minecraft.server.v1_8_R3.ItemStack) nmsItem).getTag(), "map");
for (Map.Entry<String, NBTBase> entry : mapOrigin.entrySet()) {
if (nbtWhitelist.contains(entry.getKey())) {
mapNew.put(entry.getKey(), entry.getValue());
}
}
((net.minecraft.server.v1_8_R3.ItemStack) nmsItem).setTag((NBTTagCompound) nbtTag);
return CraftItemStack.asBukkitCopy(((net.minecraft.server.v1_8_R3.ItemStack) nmsItem));
}
return itemStack;
}
@Override
public ItemStack optimizeShulkerBox(ItemStack item) {
try {
if (item.getType().name().endsWith("SHULKER_BOX")) {
ItemStack itemClone = item.clone();
BlockStateMeta blockStateMeta = (BlockStateMeta) itemClone.getItemMeta();
ShulkerBox shulkerBox = (ShulkerBox) blockStateMeta.getBlockState();
ItemStack[] contents = shulkerBox.getInventory().getContents();
ItemStack[] contentsClone = new ItemStack[contents.length];
for (int i = 0; i < contents.length; i++) {
ItemStack content = contents[i];
if (!Items.isNull(content)) {
ItemStack contentClone = new ItemStack(Material.STONE, content.getAmount(), content.getDurability());
if (content.getItemMeta().hasDisplayName()) {
ItemMeta itemMeta = contentClone.getItemMeta();
itemMeta.setDisplayName(content.getItemMeta().getDisplayName());
contentClone.setItemMeta(itemMeta);
}
contentsClone[i] = contentClone;
}
}
shulkerBox.getInventory().setContents(contentsClone);
blockStateMeta.setBlockState(shulkerBox);
itemClone.setItemMeta(blockStateMeta);
return itemClone;
} else if (item.getItemMeta() instanceof BlockStateMeta && ((BlockStateMeta) item.getItemMeta()).getBlockState() instanceof InventoryHolder) {
ItemStack itemClone = item.clone();
BlockStateMeta blockStateMeta = (BlockStateMeta) itemClone.getItemMeta();
InventoryHolder inventoryHolder = (InventoryHolder) blockStateMeta.getBlockState();
inventoryHolder.getInventory().clear();
blockStateMeta.setBlockState((org.bukkit.block.BlockState) inventoryHolder);
itemClone.setItemMeta(blockStateMeta);
return itemClone;
}
} catch (Throwable ignored) {
}
return item;
}
private String nbtToString(Object nbtTagCompound, TellrawVersion version) {
StringBuilder builder = new StringBuilder("{");
Map map = (Map) SimpleReflection.getFieldValue(NBTTagCompound.class, nbtTagCompound, "map");
int index = 0;
for (Object nbtBaseEntry : map.entrySet()) {
if (index++ != 0) {
builder.append(",");
}
Object value = ((Map.Entry) nbtBaseEntry).getValue();
if (value instanceof NBTTagList ) {
builder.append(((Map.Entry) nbtBaseEntry).getKey()).append(":").append(nbtListToString(value, version));
} else if (value instanceof NBTTagCompound) {
builder.append(((Map.Entry) nbtBaseEntry).getKey()).append(":").append(nbtToString(value, version));
} else {
builder.append(((Map.Entry) nbtBaseEntry).getKey()).append(":").append(value);
}
}
return builder.append('}').toString();
}
private String nbtListToString(Object nbtTagList, TellrawVersion version) {
StringBuilder builder = new StringBuilder("[");
List list = (List) SimpleReflection.getFieldValue(NBTTagList.class, nbtTagList, "list");
for (int i = 0; i < list.size(); ++i) {
if (i != 0) {
builder.append(',');
}
if (version == TellrawVersion.HIGH_VERSION || (Version.isAfter(Version.v1_12) && version == TellrawVersion.CURRENT_VERSION)) {
builder.append(list.get(i));
} else {
builder.append(i).append(':').append(list.get(i));
}
}
return builder.append(']').toString();
}
}