224 lines
8.5 KiB
Java
224 lines
8.5 KiB
Java
package cn.citycraft.TellRaw.internal;
|
|
|
|
import java.lang.reflect.Field;
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
|
|
import org.bukkit.Achievement;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.Statistic;
|
|
import org.bukkit.Statistic.Type;
|
|
import org.bukkit.command.CommandSender;
|
|
import org.bukkit.entity.EntityType;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.inventory.ItemStack;
|
|
|
|
import cn.citycraft.TellRaw.FancyMessage;
|
|
import cn.citycraft.TellRaw.common.Reflection;
|
|
import cn.citycraft.TellRaw.common.TextualComponent;
|
|
|
|
/**
|
|
* Represents a formattable message. Such messages can use elements such as
|
|
* colors, formatting codes, hover and click data, and other features provided
|
|
* by the vanilla Minecraft <a
|
|
* href="http://minecraft.gamepedia.com/Tellraw#Raw_JSON_Text">JSON message
|
|
* formatter</a>.
|
|
* This class allows plugins to emulate the functionality of the vanilla
|
|
* Minecraft <a href="http://minecraft.gamepedia.com/Commands#tellraw">tellraw
|
|
* command</a>.
|
|
* <p>
|
|
* This class follows the builder pattern, allowing for method chaining. It is
|
|
* set up such that invocations of property-setting methods will affect the
|
|
* current editing component, and a call to {@link #then()} or
|
|
* {@link #then(Object)} will append a new editing component to the end of the
|
|
* message, optionally initializing it with text. Further property-setting
|
|
* method calls will affect that editing component.
|
|
* </p>
|
|
*/
|
|
public class FancyMessageInternal extends FancyMessage {
|
|
|
|
/**
|
|
* 新建自动序列化类
|
|
*/
|
|
public FancyMessageInternal() {
|
|
this("");
|
|
}
|
|
|
|
/**
|
|
* 新建自动序列化类
|
|
*
|
|
* @param firstPartText
|
|
* 第一个文本串
|
|
*/
|
|
public FancyMessageInternal(final String firstPartText) {
|
|
super(TextualComponent.rawText(firstPartText));
|
|
}
|
|
|
|
@Override
|
|
public FancyMessage achievementTooltip(final Achievement which) {
|
|
try {
|
|
final Object achievement = getNMSAchievementMethod.invoke(null, which);
|
|
return achievementTooltip((String) nmsAchievement_NameField.get(achievement));
|
|
} catch (final IllegalAccessException e) {
|
|
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
|
|
return this;
|
|
} catch (final IllegalArgumentException e) {
|
|
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
|
|
return this;
|
|
} catch (final InvocationTargetException e) {
|
|
Bukkit.getLogger().log(Level.WARNING, "A error has occured durring invoking of method.", e);
|
|
return this;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public FancyMessage itemTooltip(final ItemStack itemStack) {
|
|
try {
|
|
final Object nmsItem = getOBCasNMSCopyMethod.invoke(null, itemStack);
|
|
return itemTooltip(getNMSsaveNBTMethod.invoke(nmsItem, nmsNBTTagCompound.newInstance()).toString());
|
|
} catch (final Exception e) {
|
|
e.printStackTrace();
|
|
return this;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void send(final CommandSender sender, final String jsonString) {
|
|
if (!(sender instanceof Player)) {
|
|
sender.sendMessage(toOldMessageFormat());
|
|
return;
|
|
}
|
|
final Player player = (Player) sender;
|
|
try {
|
|
final Object handle = Reflection.getHandle(player);
|
|
if (nmsPlayerConnectionField == null) {
|
|
try {
|
|
nmsPlayerConnectionField = Reflection.getField(handle.getClass(), "playerConnection");
|
|
} catch (final Exception e) {
|
|
for (final Field field : handle.getClass().getDeclaredFields()) {
|
|
if (field.getType().getSimpleName().contains("NetHandlerPlayServer")) {
|
|
nmsPlayerConnectionField = field;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
final Object connection = nmsPlayerConnectionField.get(handle);
|
|
if (nmsSendPacketMethod == null) {
|
|
try {
|
|
nmsSendPacketMethod = Reflection.getMethod(connection.getClass(), "sendPacket", nmsPacketClass);
|
|
} catch (final Exception e) {
|
|
nmsSendPacketMethod = Reflection.getMethodByParamsAndType(connection.getClass(), Void.TYPE, nmsPacketClass).get(0);
|
|
}
|
|
}
|
|
if (nmsSendPacketMethod == null) {
|
|
throw new RuntimeException("could find field: sendPacket in EntityPlayer class");
|
|
}
|
|
nmsSendPacketMethod.invoke(connection, createChatPacket(jsonString));
|
|
} catch (final IllegalArgumentException e) {
|
|
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
|
|
} catch (final IllegalAccessException e) {
|
|
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
|
|
} catch (final InstantiationException e) {
|
|
Bukkit.getLogger().log(Level.WARNING, "Underlying class is abstract.", e);
|
|
} catch (final InvocationTargetException e) {
|
|
Bukkit.getLogger().log(Level.WARNING, "A error has occured durring invoking of method.", e);
|
|
} catch (final NoSuchMethodException e) {
|
|
Bukkit.getLogger().log(Level.WARNING, "Could not find method.", e);
|
|
} catch (final ClassNotFoundException e) {
|
|
Bukkit.getLogger().log(Level.WARNING, "Could not find class.", e);
|
|
} catch (final SecurityException ex) {
|
|
Logger.getLogger(FancyMessageInternal.class.getName()).log(Level.SEVERE, null, ex);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public FancyMessage statisticTooltip(final Statistic which) {
|
|
final Type type = which.getType();
|
|
if (type != Type.UNTYPED) {
|
|
throw new IllegalArgumentException("That statistic requires an additional " + type + " parameter!");
|
|
}
|
|
try {
|
|
final Object statistic = getNMSStatisticMethod.invoke(null, which);
|
|
return achievementTooltip((String) nmsStatistic_NameField.get(statistic));
|
|
} catch (final IllegalAccessException e) {
|
|
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
|
|
return this;
|
|
} catch (final IllegalArgumentException e) {
|
|
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
|
|
return this;
|
|
} catch (final InvocationTargetException e) {
|
|
Bukkit.getLogger().log(Level.WARNING, "A error has occured durring invoking of method.", e);
|
|
return this;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public FancyMessage statisticTooltip(final Statistic which, final EntityType entity) {
|
|
final Type type = which.getType();
|
|
if (type == Type.UNTYPED) {
|
|
throw new IllegalArgumentException("That statistic needs no additional parameter!");
|
|
}
|
|
if (type != Type.ENTITY) {
|
|
throw new IllegalArgumentException("Wrong parameter type for that statistic - needs " + type + "!");
|
|
}
|
|
try {
|
|
final Object statistic = getNMSEntityStatisticMethod.invoke(null, which, entity);
|
|
return achievementTooltip((String) nmsStatistic_NameField.get(statistic));
|
|
} catch (final IllegalAccessException e) {
|
|
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
|
|
return this;
|
|
} catch (final IllegalArgumentException e) {
|
|
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
|
|
return this;
|
|
} catch (final InvocationTargetException e) {
|
|
Bukkit.getLogger().log(Level.WARNING, "A error has occured durring invoking of method.", e);
|
|
return this;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public FancyMessage statisticTooltip(final Statistic which, final Material item) {
|
|
final Type type = which.getType();
|
|
if (type == Type.UNTYPED) {
|
|
throw new IllegalArgumentException("That statistic needs no additional parameter!");
|
|
}
|
|
if ((type == Type.BLOCK && item.isBlock()) || type == Type.ENTITY) {
|
|
throw new IllegalArgumentException("Wrong parameter type for that statistic - needs " + type + "!");
|
|
}
|
|
try {
|
|
final Object statistic = getNMSMaterialStatisticMethod.invoke(null, which, item);
|
|
return achievementTooltip((String) nmsStatistic_NameField.get(statistic));
|
|
} catch (final IllegalAccessException e) {
|
|
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
|
|
return this;
|
|
} catch (final IllegalArgumentException e) {
|
|
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
|
|
return this;
|
|
} catch (final InvocationTargetException e) {
|
|
Bukkit.getLogger().log(Level.WARNING, "A error has occured durring invoking of method.", e);
|
|
return this;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 创建Chat数据包
|
|
*
|
|
* @param json
|
|
* 需要创建的数据包
|
|
* @return 创建发包对象
|
|
* @throws IllegalArgumentException
|
|
* @throws IllegalAccessException
|
|
* @throws InstantiationException
|
|
* @throws InvocationTargetException
|
|
* @throws NoSuchMethodException
|
|
* @throws ClassNotFoundException
|
|
*/
|
|
private Object createChatPacket(final String json) throws IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException {
|
|
final Object serializedChatComponent = fromJsonMethod.invoke(nmsChatSerializerGsonInstance, json, nmsIChatBaseComponentClass);
|
|
return nmsPacketPlayOutChatConstructor.newInstance(serializedChatComponent);
|
|
}
|
|
}
|