package com.w67clement.mineapi.nms.reflection.packets.play.out;
import com.w67clement.mineapi.api.wrappers.BlockPositionWrapper;
import com.w67clement.mineapi.api.wrappers.ChatComponentWrapper;
import com.w67clement.mineapi.packets.play.out.PacketUpdateSign;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Sign;
import org.bukkit.entity.Player;
import static com.w67clement.mineapi.api.ReflectionAPI.*;
/**
* Created by w67clement on 14/02/2016.
* <p>
* Class of project: MineAPI
*/
public class CraftPacketUpdateSign extends PacketUpdateSign<Object>
{
private static final Class<?> packetClass;
private static final Field worldField;
private static final Field blockPosField;
private static final Field contentsField;
private static final Method getWorldMethod;
private static final Method getHandleWorldMethod;
static
{
packetClass = getNmsClass("PacketPlayOutUpdateSign");
worldField = getField(packetClass, "a", true);
blockPosField = getField(packetClass, "b", true);
contentsField = getField(packetClass, "c", true);
getWorldMethod = getMethod(getNmsClass("World"), "getWorld");
getHandleWorldMethod = getMethod(getCraftClass("CraftWorld", CraftPackage.ORG_BUKKIT_CRAFTBUKKIT), "getHandle");
}
public CraftPacketUpdateSign(Object packet)
{
super(packet);
}
public CraftPacketUpdateSign(Sign sign)
{
this(sign.getLocation(), loadSignContents(sign));
}
public CraftPacketUpdateSign(Location location, String[] contents)
{
super(SunUnsafe.newInstance(packetClass));
setLocation(location);
setContents(contents);
}
public CraftPacketUpdateSign(int x, int y, int z, String[] contents)
{
this(new Location(null, x, y, z), contents);
}
private static String[] loadSignContents(Sign sign)
{
Object tileEntity = getValue(sign, getField(sign.getClass(), "sign", true));
Object array = getValue(tileEntity, getField(tileEntity.getClass(), "lines", false));
String[] contents = new String[4];
contents[0] = ChatComponentWrapper.makeJsonByChatComponent(Array.get(array, 0));
contents[1] = ChatComponentWrapper.makeJsonByChatComponent(Array.get(array, 1));
contents[2] = ChatComponentWrapper.makeJsonByChatComponent(Array.get(array, 2));
contents[3] = ChatComponentWrapper.makeJsonByChatComponent(Array.get(array, 3));
return contents;
}
@Override
public Location getLocation()
{
Object nmsWorld = getValue(packet, worldField);
World world = invokeMethodWithType(nmsWorld, getWorldMethod, World.class);
return new BlockPositionWrapper(getValue(packet, blockPosField)).toLocation(world);
}
@Override
public void setLocation(Location location)
{
setValue(packet, worldField, invokeMethod(location.getWorld(), getHandleWorldMethod));
setValue(packet, blockPosField, BlockPositionWrapper.fromLocation(location).toBlockPosition());
}
@Override
public String[] getContents()
{
Object nmsContents = getValue(packet, contentsField);
String[] contents = new String[4];
contents[0] = ChatComponentWrapper.makeJsonByChatComponent(Array.get(nmsContents, 0));
contents[1] = ChatComponentWrapper.makeJsonByChatComponent(Array.get(nmsContents, 1));
contents[2] = ChatComponentWrapper.makeJsonByChatComponent(Array.get(nmsContents, 2));
contents[3] = ChatComponentWrapper.makeJsonByChatComponent(Array.get(nmsContents, 3));
return contents;
}
@Override
public void setContents(String[] contents)
{
Object array = Array.newInstance(NmsClass.getIChatBaseComponentClass(), 4);
Array.set(array, 0, ChatComponentWrapper.makeChatComponentByJson(contents[0]));
Array.set(array, 1, ChatComponentWrapper.makeChatComponentByJson(contents[1]));
Array.set(array, 2, ChatComponentWrapper.makeChatComponentByJson(contents[2]));
Array.set(array, 3, ChatComponentWrapper.makeChatComponentByJson(contents[3]));
setValue(packet, getField(packetClass, "c", true), array);
}
@Override
public void send(Player player)
{
NmsClass.sendPacket(player, this.getHandle());
}
}