mirror of
https://e.coding.net/circlecloud/TellRaw.git
synced 2025-11-25 20:46:01 +00:00
refactor(*): 格式化代码 清理文件...
This commit is contained in:
@@ -233,11 +233,6 @@ public abstract class FancyMessage implements JsonRepresentedObject, Cloneable,
|
|||||||
|
|
||||||
protected List<MessagePart> messageParts;
|
protected List<MessagePart> messageParts;
|
||||||
|
|
||||||
public FancyMessage(final TextualComponent firstPartText) {
|
|
||||||
messageParts = new ArrayList<MessagePart>();
|
|
||||||
messageParts.add(new MessagePart(firstPartText));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deserializes a JSON-represented message from a mapping of key-value
|
* Deserializes a JSON-represented message from a mapping of key-value
|
||||||
* pairs.
|
* pairs.
|
||||||
@@ -353,6 +348,11 @@ public abstract class FancyMessage implements JsonRepresentedObject, Cloneable,
|
|||||||
return newFM().text(firstPartText);
|
return newFM().text(firstPartText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FancyMessage(final TextualComponent firstPartText) {
|
||||||
|
messageParts = new ArrayList<MessagePart>();
|
||||||
|
messageParts.add(new MessagePart(firstPartText));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在客户端显示一个成就.
|
* 在客户端显示一个成就.
|
||||||
* </p>
|
* </p>
|
||||||
|
|||||||
@@ -13,52 +13,52 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
|||||||
* @author 喵♂呜
|
* @author 喵♂呜
|
||||||
*/
|
*/
|
||||||
public class PluginHelperConfig {
|
public class PluginHelperConfig {
|
||||||
public static YamlConfiguration a;
|
public static YamlConfiguration a;
|
||||||
public static File configfile = new File(Bukkit.getUpdateFolderFile().getParentFile(), "PluginHelper" + File.separatorChar + "config.yml");
|
public static File configfile = new File(Bukkit.getUpdateFolderFile().getParentFile(), "PluginHelper" + File.separatorChar + "config.yml");
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
if (!configfile.exists()) {
|
if (!configfile.exists()) {
|
||||||
configfile.createNewFile();
|
configfile.createNewFile();
|
||||||
}
|
}
|
||||||
a = YamlConfiguration.loadConfiguration(configfile);
|
a = YamlConfiguration.loadConfiguration(configfile);
|
||||||
initFile(a);
|
initFile(a);
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
a = new YamlConfiguration();
|
a = new YamlConfiguration();
|
||||||
try {
|
try {
|
||||||
initFile(a);
|
initFile(a);
|
||||||
} catch (final IOException e1) {
|
} catch (final IOException e1) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static YamlConfiguration getConfig() {
|
public static YamlConfiguration getConfig() {
|
||||||
try {
|
try {
|
||||||
return YamlConfiguration.loadConfiguration(configfile);
|
return YamlConfiguration.loadConfiguration(configfile);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getGUID() {
|
public static String getGUID() {
|
||||||
return a.getString("guid");
|
return a.getString("guid");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void initFile(final YamlConfiguration config) throws IOException {
|
private static void initFile(final YamlConfiguration config) throws IOException {
|
||||||
if (config.getString("guid") == null) {
|
if (config.getString("guid") == null) {
|
||||||
config.options().header("数据中心 http://yum.citycraft.cn 收集的数据仅用于统计插件使用情况").copyDefaults(true);
|
config.options().header("数据中心 http://www.yumc.pw 收集的数据仅用于统计插件使用情况").copyDefaults(true);
|
||||||
config.set("guid", UUID.randomUUID().toString());
|
config.set("guid", UUID.randomUUID().toString());
|
||||||
config.set("debug", false);
|
config.set("debug", false);
|
||||||
config.save(configfile);
|
config.save(configfile);
|
||||||
}
|
}
|
||||||
if (!config.contains("YumAccount")) {
|
if (!config.contains("YumAccount")) {
|
||||||
config.set("YumAccount.username", "Username Not Set");
|
config.set("YumAccount.username", "Username Not Set");
|
||||||
config.set("YumAccount.password", "Password NotSet");
|
config.set("YumAccount.password", "Password NotSet");
|
||||||
config.save(configfile);
|
config.save(configfile);
|
||||||
}
|
}
|
||||||
if (!config.contains("TellrawManualHandle")) {
|
if (!config.contains("TellrawManualHandle")) {
|
||||||
config.set("TellrawManualHandle", false);
|
config.set("TellrawManualHandle", false);
|
||||||
config.save(configfile);
|
config.save(configfile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,98 +20,98 @@ import org.apache.commons.lang.Validate;
|
|||||||
*/
|
*/
|
||||||
public final class ArrayWrapper<E> {
|
public final class ArrayWrapper<E> {
|
||||||
|
|
||||||
private E[] _array;
|
private E[] _array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an array wrapper with some elements.
|
* Converts an iterable element collection to an array of elements.
|
||||||
*
|
* The iteration order of the specified object will be used as the array
|
||||||
* @param elements
|
* element order.
|
||||||
* The elements of the array.
|
*
|
||||||
*/
|
* @param list
|
||||||
@SafeVarargs
|
* The iterable of objects which will be converted to an array.
|
||||||
public ArrayWrapper(final E... elements) {
|
* @param c
|
||||||
setArray(elements);
|
* The type of the elements of the array.
|
||||||
}
|
* @return An array of elements in the specified iterable.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> T[] toArray(final Iterable<? extends T> list, final Class<T> c) {
|
||||||
|
int size = -1;
|
||||||
|
if (list instanceof Collection<?>) {
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
final Collection coll = (Collection) list;
|
||||||
|
size = coll.size();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
if (size < 0) {
|
||||||
* Converts an iterable element collection to an array of elements.
|
size = 0;
|
||||||
* The iteration order of the specified object will be used as the array
|
// Ugly hack: Count it ourselves
|
||||||
* element order.
|
for (@SuppressWarnings("unused")
|
||||||
*
|
final T element : list) {
|
||||||
* @param list
|
size++;
|
||||||
* The iterable of objects which will be converted to an array.
|
}
|
||||||
* @param c
|
}
|
||||||
* The type of the elements of the array.
|
|
||||||
* @return An array of elements in the specified iterable.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static <T> T[] toArray(final Iterable<? extends T> list, final Class<T> c) {
|
|
||||||
int size = -1;
|
|
||||||
if (list instanceof Collection<?>) {
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
final Collection coll = (Collection) list;
|
|
||||||
size = coll.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size < 0) {
|
final T[] result = (T[]) Array.newInstance(c, size);
|
||||||
size = 0;
|
int i = 0;
|
||||||
// Ugly hack: Count it ourselves
|
for (final T element : list) { // Assumes iteration order is consistent
|
||||||
for (@SuppressWarnings("unused")
|
result[i++] = element; // Assign array element at index THEN increment counter
|
||||||
final T element : list) {
|
}
|
||||||
size++;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
final T[] result = (T[]) Array.newInstance(c, size);
|
/**
|
||||||
int i = 0;
|
* Creates an array wrapper with some elements.
|
||||||
for (final T element : list) { // Assumes iteration order is consistent
|
*
|
||||||
result[i++] = element; // Assign array element at index THEN increment counter
|
* @param elements
|
||||||
}
|
* The elements of the array.
|
||||||
return result;
|
*/
|
||||||
}
|
@SafeVarargs
|
||||||
|
public ArrayWrapper(final E... elements) {
|
||||||
|
setArray(elements);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if this object has a value equivalent to another object.
|
* Determines if this object has a value equivalent to another object.
|
||||||
*
|
*
|
||||||
* @see Arrays#equals(Object[], Object[])
|
* @see Arrays#equals(Object[], Object[])
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object other) {
|
public boolean equals(final Object other) {
|
||||||
if (!(other instanceof ArrayWrapper)) {
|
if (!(other instanceof ArrayWrapper)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return Arrays.equals(_array, ((ArrayWrapper) other)._array);
|
return Arrays.equals(_array, ((ArrayWrapper) other)._array);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a reference to the wrapped array instance.
|
* Retrieves a reference to the wrapped array instance.
|
||||||
*
|
*
|
||||||
* @return The array wrapped by this instance.
|
* @return The array wrapped by this instance.
|
||||||
*/
|
*/
|
||||||
public E[] getArray() {
|
public E[] getArray() {
|
||||||
return _array;
|
return _array;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the hash code represented by this objects value.
|
* Gets the hash code represented by this objects value.
|
||||||
*
|
*
|
||||||
* @see Arrays#hashCode(Object[])
|
* @see Arrays#hashCode(Object[])
|
||||||
* @return This object's hash code.
|
* @return This object's hash code.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Arrays.hashCode(_array);
|
return Arrays.hashCode(_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set this wrapper to wrap a new array instance.
|
* Set this wrapper to wrap a new array instance.
|
||||||
*
|
*
|
||||||
* @param array
|
* @param array
|
||||||
* The new wrapped array.
|
* The new wrapped array.
|
||||||
*/
|
*/
|
||||||
public void setArray(final E[] array) {
|
public void setArray(final E[] array) {
|
||||||
Validate.notNull(array, "The array must not be null.");
|
Validate.notNull(array, "The array must not be null.");
|
||||||
_array = array;
|
_array = array;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ import cn.citycraft.GsonAgent.api.stream.JsonWriter;
|
|||||||
*/
|
*/
|
||||||
public interface JsonRepresentedObject {
|
public interface JsonRepresentedObject {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the JSON representation of this object to the specified writer.
|
* Writes the JSON representation of this object to the specified writer.
|
||||||
*
|
*
|
||||||
* @param writer
|
* @param writer
|
||||||
* The JSON writer which will receive the object.
|
* The JSON writer which will receive the object.
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* If an error occurs writing to the stream.
|
* If an error occurs writing to the stream.
|
||||||
*/
|
*/
|
||||||
public void writeJson(JsonWriter writer) throws IOException;
|
public void writeJson(JsonWriter writer) throws IOException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,35 +16,35 @@ import cn.citycraft.GsonAgent.api.stream.JsonWriter;
|
|||||||
*/
|
*/
|
||||||
public final class JsonString implements JsonRepresentedObject, ConfigurationSerializable {
|
public final class JsonString implements JsonRepresentedObject, ConfigurationSerializable {
|
||||||
|
|
||||||
private final String _value;
|
private final String _value;
|
||||||
|
|
||||||
public JsonString(final CharSequence value) {
|
public static JsonString deserialize(final Map<String, Object> map) {
|
||||||
_value = value == null ? null : value.toString();
|
return new JsonString(map.get("stringValue").toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JsonString deserialize(final Map<String, Object> map) {
|
public JsonString(final CharSequence value) {
|
||||||
return new JsonString(map.get("stringValue").toString());
|
_value = value == null ? null : value.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getValue() {
|
public String getValue() {
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> serialize() {
|
public Map<String, Object> serialize() {
|
||||||
final HashMap<String, Object> theSingleValue = new HashMap<String, Object>();
|
final HashMap<String, Object> theSingleValue = new HashMap<String, Object>();
|
||||||
theSingleValue.put("stringValue", _value);
|
theSingleValue.put("stringValue", _value);
|
||||||
return theSingleValue;
|
return theSingleValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeJson(final JsonWriter writer) throws IOException {
|
public void writeJson(final JsonWriter writer) throws IOException {
|
||||||
writer.value(getValue());
|
writer.value(getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,137 +23,137 @@ import cn.citycraft.TellRaw.internal.FancyMessageInternal;
|
|||||||
*/
|
*/
|
||||||
public final class MessagePart implements JsonRepresentedObject, ConfigurationSerializable, Cloneable {
|
public final class MessagePart implements JsonRepresentedObject, ConfigurationSerializable, Cloneable {
|
||||||
|
|
||||||
public static final BiMap<ChatColor, String> stylesToNames;
|
public static final BiMap<ChatColor, String> stylesToNames;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
final ImmutableBiMap.Builder<ChatColor, String> builder = ImmutableBiMap.builder();
|
final ImmutableBiMap.Builder<ChatColor, String> builder = ImmutableBiMap.builder();
|
||||||
for (final ChatColor style : ChatColor.values()) {
|
for (final ChatColor style : ChatColor.values()) {
|
||||||
if (!style.isFormat()) {
|
if (!style.isFormat()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
String styleName;
|
String styleName;
|
||||||
switch (style) {
|
switch (style) {
|
||||||
case MAGIC:
|
case MAGIC:
|
||||||
styleName = "obfuscated";
|
styleName = "obfuscated";
|
||||||
break;
|
break;
|
||||||
case UNDERLINE:
|
case UNDERLINE:
|
||||||
styleName = "underlined";
|
styleName = "underlined";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
styleName = style.name().toLowerCase();
|
styleName = style.name().toLowerCase();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.put(style, styleName);
|
builder.put(style, styleName);
|
||||||
}
|
}
|
||||||
stylesToNames = builder.build();
|
stylesToNames = builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
static {
|
static {
|
||||||
ConfigurationSerialization.registerClass(MessagePart.class);
|
ConfigurationSerialization.registerClass(MessagePart.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String clickActionData = null;
|
public String clickActionData = null;
|
||||||
public String clickActionName = null;
|
public String clickActionName = null;
|
||||||
public ChatColor color = ChatColor.WHITE;
|
public ChatColor color = ChatColor.WHITE;
|
||||||
public JsonRepresentedObject hoverActionData = null;
|
public JsonRepresentedObject hoverActionData = null;
|
||||||
public String hoverActionName = null;
|
public String hoverActionName = null;
|
||||||
public String insertionData = null;
|
public String insertionData = null;
|
||||||
|
|
||||||
public ArrayList<ChatColor> styles = new ArrayList<ChatColor>();
|
public ArrayList<ChatColor> styles = new ArrayList<ChatColor>();
|
||||||
|
|
||||||
public TextualComponent text = null;
|
public TextualComponent text = null;
|
||||||
|
|
||||||
public ArrayList<JsonRepresentedObject> translationReplacements = new ArrayList<JsonRepresentedObject>();
|
public ArrayList<JsonRepresentedObject> translationReplacements = new ArrayList<JsonRepresentedObject>();
|
||||||
|
|
||||||
public MessagePart() {
|
@SuppressWarnings("unchecked")
|
||||||
this.text = null;
|
public static MessagePart deserialize(final Map<String, Object> serialized) {
|
||||||
}
|
final MessagePart part = new MessagePart((TextualComponent) serialized.get("text"));
|
||||||
|
part.styles = (ArrayList<ChatColor>) serialized.get("styles");
|
||||||
|
part.color = ChatColor.getByChar(serialized.get("color").toString());
|
||||||
|
part.hoverActionName = (String) serialized.get("hoverActionName");
|
||||||
|
part.hoverActionData = (JsonRepresentedObject) serialized.get("hoverActionData");
|
||||||
|
part.clickActionName = (String) serialized.get("clickActionName");
|
||||||
|
part.clickActionData = (String) serialized.get("clickActionData");
|
||||||
|
part.insertionData = (String) serialized.get("insertion");
|
||||||
|
part.translationReplacements = (ArrayList<JsonRepresentedObject>) serialized.get("translationReplacements");
|
||||||
|
return part;
|
||||||
|
}
|
||||||
|
|
||||||
public MessagePart(final TextualComponent text) {
|
public MessagePart() {
|
||||||
this.text = text;
|
this.text = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
public MessagePart(final TextualComponent text) {
|
||||||
public static MessagePart deserialize(final Map<String, Object> serialized) {
|
this.text = text;
|
||||||
final MessagePart part = new MessagePart((TextualComponent) serialized.get("text"));
|
}
|
||||||
part.styles = (ArrayList<ChatColor>) serialized.get("styles");
|
|
||||||
part.color = ChatColor.getByChar(serialized.get("color").toString());
|
|
||||||
part.hoverActionName = (String) serialized.get("hoverActionName");
|
|
||||||
part.hoverActionData = (JsonRepresentedObject) serialized.get("hoverActionData");
|
|
||||||
part.clickActionName = (String) serialized.get("clickActionName");
|
|
||||||
part.clickActionData = (String) serialized.get("clickActionData");
|
|
||||||
part.insertionData = (String) serialized.get("insertion");
|
|
||||||
part.translationReplacements = (ArrayList<JsonRepresentedObject>) serialized.get("translationReplacements");
|
|
||||||
return part;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public MessagePart clone() throws CloneNotSupportedException {
|
public MessagePart clone() throws CloneNotSupportedException {
|
||||||
final MessagePart obj = (MessagePart) super.clone();
|
final MessagePart obj = (MessagePart) super.clone();
|
||||||
obj.styles = (ArrayList<ChatColor>) styles.clone();
|
obj.styles = (ArrayList<ChatColor>) styles.clone();
|
||||||
if (hoverActionData instanceof JsonString) {
|
if (hoverActionData instanceof JsonString) {
|
||||||
obj.hoverActionData = new JsonString(((JsonString) hoverActionData).getValue());
|
obj.hoverActionData = new JsonString(((JsonString) hoverActionData).getValue());
|
||||||
} else if (hoverActionData instanceof FancyMessageInternal) {
|
} else if (hoverActionData instanceof FancyMessageInternal) {
|
||||||
obj.hoverActionData = ((FancyMessageInternal) hoverActionData).clone();
|
obj.hoverActionData = ((FancyMessageInternal) hoverActionData).clone();
|
||||||
}
|
}
|
||||||
obj.translationReplacements = (ArrayList<JsonRepresentedObject>) translationReplacements.clone();
|
obj.translationReplacements = (ArrayList<JsonRepresentedObject>) translationReplacements.clone();
|
||||||
return obj;
|
return obj;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasText() {
|
public boolean hasText() {
|
||||||
return text != null;
|
return text != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> serialize() {
|
public Map<String, Object> serialize() {
|
||||||
final HashMap<String, Object> map = new HashMap<String, Object>();
|
final HashMap<String, Object> map = new HashMap<String, Object>();
|
||||||
map.put("text", text);
|
map.put("text", text);
|
||||||
map.put("styles", styles);
|
map.put("styles", styles);
|
||||||
map.put("color", color.getChar());
|
map.put("color", color.getChar());
|
||||||
map.put("hoverActionName", hoverActionName);
|
map.put("hoverActionName", hoverActionName);
|
||||||
map.put("hoverActionData", hoverActionData);
|
map.put("hoverActionData", hoverActionData);
|
||||||
map.put("clickActionName", clickActionName);
|
map.put("clickActionName", clickActionName);
|
||||||
map.put("clickActionData", clickActionData);
|
map.put("clickActionData", clickActionData);
|
||||||
map.put("insertion", insertionData);
|
map.put("insertion", insertionData);
|
||||||
map.put("translationReplacements", translationReplacements);
|
map.put("translationReplacements", translationReplacements);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeJson(final JsonWriter json) {
|
public void writeJson(final JsonWriter json) {
|
||||||
try {
|
try {
|
||||||
json.beginObject();
|
json.beginObject();
|
||||||
text.writeJson(json);
|
text.writeJson(json);
|
||||||
json.name("color").value(color.name().toLowerCase());
|
json.name("color").value(color.name().toLowerCase());
|
||||||
for (final ChatColor style : styles) {
|
for (final ChatColor style : styles) {
|
||||||
json.name(stylesToNames.get(style)).value(true);
|
json.name(stylesToNames.get(style)).value(true);
|
||||||
}
|
}
|
||||||
if (clickActionName != null && clickActionData != null) {
|
if (clickActionName != null && clickActionData != null) {
|
||||||
json.name("clickEvent").beginObject().name("action").value(clickActionName).name("value").value(clickActionData).endObject();
|
json.name("clickEvent").beginObject().name("action").value(clickActionName).name("value").value(clickActionData).endObject();
|
||||||
}
|
}
|
||||||
if (hoverActionName != null && hoverActionData != null) {
|
if (hoverActionName != null && hoverActionData != null) {
|
||||||
json.name("hoverEvent").beginObject().name("action").value(hoverActionName).name("value");
|
json.name("hoverEvent").beginObject().name("action").value(hoverActionName).name("value");
|
||||||
hoverActionData.writeJson(json);
|
hoverActionData.writeJson(json);
|
||||||
json.endObject();
|
json.endObject();
|
||||||
}
|
}
|
||||||
if (insertionData != null) {
|
if (insertionData != null) {
|
||||||
json.name("insertion").value(insertionData);
|
json.name("insertion").value(insertionData);
|
||||||
}
|
}
|
||||||
if (translationReplacements.size() > 0 && text != null && TextualComponent.isTranslatableText(text)) {
|
if (translationReplacements.size() > 0 && text != null && TextualComponent.isTranslatableText(text)) {
|
||||||
json.name("with").beginArray();
|
json.name("with").beginArray();
|
||||||
for (final JsonRepresentedObject obj : translationReplacements) {
|
for (final JsonRepresentedObject obj : translationReplacements) {
|
||||||
obj.writeJson(json);
|
obj.writeJson(json);
|
||||||
}
|
}
|
||||||
json.endArray();
|
json.endArray();
|
||||||
}
|
}
|
||||||
json.endObject();
|
json.endObject();
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
Bukkit.getLogger().log(Level.WARNING, "A problem occured during writing of JSON string", e);
|
Bukkit.getLogger().log(Level.WARNING, "A problem occured during writing of JSON string", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,285 +16,285 @@ import org.bukkit.Bukkit;
|
|||||||
* Unless otherwise noted, upon failure methods will return {@code null}.
|
* Unless otherwise noted, upon failure methods will return {@code null}.
|
||||||
*/
|
*/
|
||||||
public final class Reflection {
|
public final class Reflection {
|
||||||
private static final Map<Class<?>, Map<String, Field>> _loadedFields = new HashMap<Class<?>, Map<String, Field>>();
|
private static final Map<Class<?>, Map<String, Field>> _loadedFields = new HashMap<Class<?>, Map<String, Field>>();
|
||||||
/**
|
/**
|
||||||
* Contains loaded methods in a cache.
|
* Contains loaded methods in a cache.
|
||||||
* The map maps [types to maps of [method names to maps of [parameter types
|
* The map maps [types to maps of [method names to maps of [parameter types
|
||||||
* to method instances]]].
|
* to method instances]]].
|
||||||
*/
|
*/
|
||||||
private static final Map<Class<?>, Map<String, Map<ArrayWrapper<Class<?>>, Method>>> _loadedMethods = new HashMap<Class<?>, Map<String, Map<ArrayWrapper<Class<?>>, Method>>>();
|
private static final Map<Class<?>, Map<String, Map<ArrayWrapper<Class<?>>, Method>>> _loadedMethods = new HashMap<Class<?>, Map<String, Map<ArrayWrapper<Class<?>>, Method>>>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores loaded classes from the {@code net.minecraft.server} package.
|
* Stores loaded classes from the {@code net.minecraft.server} package.
|
||||||
*/
|
*/
|
||||||
private static final Map<String, Class<?>> _loadedNMSClasses = new HashMap<String, Class<?>>();
|
private static final Map<String, Class<?>> _loadedNMSClasses = new HashMap<String, Class<?>>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores loaded classes from the {@code org.bukkit.craftbukkit} package
|
* Stores loaded classes from the {@code org.bukkit.craftbukkit} package
|
||||||
* (and subpackages).
|
* (and subpackages).
|
||||||
*/
|
*/
|
||||||
private static final Map<String, Class<?>> _loadedOBCClasses = new HashMap<String, Class<?>>();
|
private static final Map<String, Class<?>> _loadedOBCClasses = new HashMap<String, Class<?>>();
|
||||||
private static String _versionString;
|
private static String _versionString;
|
||||||
|
|
||||||
private Reflection() {
|
@SuppressWarnings("rawtypes")
|
||||||
|
public static List<Field> getDeclaredFieldByType(final Class source, final Class type) {
|
||||||
|
final List<Field> list = new ArrayList<>();
|
||||||
|
for (final Field field : source.getDeclaredFields()) {
|
||||||
|
if (field.getType() == type) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
list.add(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
/**
|
||||||
|
* Retrieves a {@link Field} instance declared by the specified class with
|
||||||
|
* the specified name.
|
||||||
|
* Java access modifiers are ignored during this retrieval. No guarantee is
|
||||||
|
* made as to whether the field
|
||||||
|
* returned will be an instance or static field.
|
||||||
|
* <p>
|
||||||
|
* A global caching mechanism within this class is used to store fields.
|
||||||
|
* Combined with synchronization, this guarantees that no field will be
|
||||||
|
* reflectively looked up twice.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* If a field is deemed suitable for return,
|
||||||
|
* {@link Field#setAccessible(boolean) setAccessible} will be invoked with
|
||||||
|
* an argument of {@code true} before it is returned. This ensures that
|
||||||
|
* callers do not have to check or worry about Java access modifiers when
|
||||||
|
* dealing with the returned instance.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param clazz
|
||||||
|
* The class which contains the field to retrieve.
|
||||||
|
* @param name
|
||||||
|
* The declared name of the field in the class.
|
||||||
|
* @return A field object with the specified name declared by the specified
|
||||||
|
* class.
|
||||||
|
* @throws Exception
|
||||||
|
* @see Class#getDeclaredField(String)
|
||||||
|
*/
|
||||||
|
public synchronized static Field getField(final Class<?> clazz, final String name) throws Exception {
|
||||||
|
Map<String, Field> loaded;
|
||||||
|
if (!_loadedFields.containsKey(clazz)) {
|
||||||
|
loaded = new HashMap<String, Field>();
|
||||||
|
_loadedFields.put(clazz, loaded);
|
||||||
|
} else {
|
||||||
|
loaded = _loadedFields.get(clazz);
|
||||||
|
}
|
||||||
|
if (loaded.containsKey(name)) {
|
||||||
|
// If the field is loaded (or cached as not existing), return the
|
||||||
|
// relevant value, which might be null
|
||||||
|
return loaded.get(name);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
final Field field = clazz.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
loaded.put(name, field);
|
||||||
|
return field;
|
||||||
|
} catch (final Exception e) {
|
||||||
|
// Cache field as not existing
|
||||||
|
loaded.put(name, null);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
/**
|
||||||
public static List<Field> getDeclaredFieldByType(final Class source, final Class type) {
|
* Attempts to get the NMS handle of a CraftBukkit object.
|
||||||
final List<Field> list = new ArrayList<>();
|
* <p>
|
||||||
for (final Field field : source.getDeclaredFields()) {
|
* The only match currently attempted by this method is a retrieval by using
|
||||||
if (field.getType() == type) {
|
* a parameterless {@code getHandle()} method implemented by the runtime
|
||||||
field.setAccessible(true);
|
* type of the specified object.
|
||||||
list.add(field);
|
* </p>
|
||||||
}
|
*
|
||||||
}
|
* @param obj
|
||||||
return list;
|
* The object for which to retrieve an NMS handle.
|
||||||
}
|
* @return The NMS handle of the specified object, or {@code null} if it
|
||||||
|
* could not be retrieved using {@code getHandle()}.
|
||||||
|
*/
|
||||||
|
public synchronized static Object getHandle(final Object obj) {
|
||||||
|
try {
|
||||||
|
return getMethod(obj.getClass(), "getHandle").invoke(obj);
|
||||||
|
} catch (final Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a {@link Field} instance declared by the specified class with
|
* Retrieves a {@link Method} instance declared by the specified class with
|
||||||
* the specified name.
|
* the specified name and argument types.
|
||||||
* Java access modifiers are ignored during this retrieval. No guarantee is
|
* Java access modifiers are ignored during this retrieval. No guarantee is
|
||||||
* made as to whether the field
|
* made as to whether the field
|
||||||
* returned will be an instance or static field.
|
* returned will be an instance or static field.
|
||||||
* <p>
|
* <p>
|
||||||
* A global caching mechanism within this class is used to store fields.
|
* A global caching mechanism within this class is used to store method.
|
||||||
* Combined with synchronization, this guarantees that no field will be
|
* Combined with synchronization, this guarantees that no method will be
|
||||||
* reflectively looked up twice.
|
* reflectively looked up twice.
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* If a field is deemed suitable for return,
|
* If a method is deemed suitable for return,
|
||||||
* {@link Field#setAccessible(boolean) setAccessible} will be invoked with
|
* {@link Method#setAccessible(boolean) setAccessible} will be invoked with
|
||||||
* an argument of {@code true} before it is returned. This ensures that
|
* an argument of {@code true} before it is returned. This ensures that
|
||||||
* callers do not have to check or worry about Java access modifiers when
|
* callers do not have to check or worry about Java access modifiers when
|
||||||
* dealing with the returned instance.
|
* dealing with the returned instance.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
* <p>
|
||||||
* @param clazz
|
* This method does <em>not</em> search superclasses of the specified type
|
||||||
* The class which contains the field to retrieve.
|
* for methods with the specified signature. Callers wishing this behavior
|
||||||
* @param name
|
* should use {@link Class#getDeclaredMethod(String, Class...)}.
|
||||||
* The declared name of the field in the class.
|
*
|
||||||
* @return A field object with the specified name declared by the specified
|
* @param clazz
|
||||||
* class.
|
* The class which contains the method to retrieve.
|
||||||
* @throws Exception
|
* @param name
|
||||||
* @see Class#getDeclaredField(String)
|
* The declared name of the method in the class.
|
||||||
*/
|
* @param args
|
||||||
public synchronized static Field getField(final Class<?> clazz, final String name) throws Exception {
|
* The formal argument types of the method.
|
||||||
Map<String, Field> loaded;
|
* @return A method object with the specified name declared by the specified
|
||||||
if (!_loadedFields.containsKey(clazz)) {
|
* class.
|
||||||
loaded = new HashMap<String, Field>();
|
*/
|
||||||
_loadedFields.put(clazz, loaded);
|
public synchronized static Method getMethod(final Class<?> clazz, final String name, final Class<?>... args) {
|
||||||
} else {
|
if (!_loadedMethods.containsKey(clazz)) {
|
||||||
loaded = _loadedFields.get(clazz);
|
_loadedMethods.put(clazz, new HashMap<String, Map<ArrayWrapper<Class<?>>, Method>>());
|
||||||
}
|
}
|
||||||
if (loaded.containsKey(name)) {
|
|
||||||
// If the field is loaded (or cached as not existing), return the
|
|
||||||
// relevant value, which might be null
|
|
||||||
return loaded.get(name);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
final Field field = clazz.getDeclaredField(name);
|
|
||||||
field.setAccessible(true);
|
|
||||||
loaded.put(name, field);
|
|
||||||
return field;
|
|
||||||
} catch (final Exception e) {
|
|
||||||
// Cache field as not existing
|
|
||||||
loaded.put(name, null);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
final Map<String, Map<ArrayWrapper<Class<?>>, Method>> loadedMethodNames = _loadedMethods.get(clazz);
|
||||||
* Attempts to get the NMS handle of a CraftBukkit object.
|
if (!loadedMethodNames.containsKey(name)) {
|
||||||
* <p>
|
loadedMethodNames.put(name, new HashMap<ArrayWrapper<Class<?>>, Method>());
|
||||||
* The only match currently attempted by this method is a retrieval by using
|
}
|
||||||
* a parameterless {@code getHandle()} method implemented by the runtime
|
|
||||||
* type of the specified object.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param obj
|
|
||||||
* The object for which to retrieve an NMS handle.
|
|
||||||
* @return The NMS handle of the specified object, or {@code null} if it
|
|
||||||
* could not be retrieved using {@code getHandle()}.
|
|
||||||
*/
|
|
||||||
public synchronized static Object getHandle(final Object obj) {
|
|
||||||
try {
|
|
||||||
return getMethod(obj.getClass(), "getHandle").invoke(obj);
|
|
||||||
} catch (final Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
final Map<ArrayWrapper<Class<?>>, Method> loadedSignatures = loadedMethodNames.get(name);
|
||||||
* Retrieves a {@link Method} instance declared by the specified class with
|
final ArrayWrapper<Class<?>> wrappedArg = new ArrayWrapper<Class<?>>(args);
|
||||||
* the specified name and argument types.
|
if (loadedSignatures.containsKey(wrappedArg)) {
|
||||||
* Java access modifiers are ignored during this retrieval. No guarantee is
|
return loadedSignatures.get(wrappedArg);
|
||||||
* made as to whether the field
|
}
|
||||||
* returned will be an instance or static field.
|
|
||||||
* <p>
|
|
||||||
* A global caching mechanism within this class is used to store method.
|
|
||||||
* Combined with synchronization, this guarantees that no method will be
|
|
||||||
* reflectively looked up twice.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* If a method is deemed suitable for return,
|
|
||||||
* {@link Method#setAccessible(boolean) setAccessible} will be invoked with
|
|
||||||
* an argument of {@code true} before it is returned. This ensures that
|
|
||||||
* callers do not have to check or worry about Java access modifiers when
|
|
||||||
* dealing with the returned instance.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* This method does <em>not</em> search superclasses of the specified type
|
|
||||||
* for methods with the specified signature. Callers wishing this behavior
|
|
||||||
* should use {@link Class#getDeclaredMethod(String, Class...)}.
|
|
||||||
*
|
|
||||||
* @param clazz
|
|
||||||
* The class which contains the method to retrieve.
|
|
||||||
* @param name
|
|
||||||
* The declared name of the method in the class.
|
|
||||||
* @param args
|
|
||||||
* The formal argument types of the method.
|
|
||||||
* @return A method object with the specified name declared by the specified
|
|
||||||
* class.
|
|
||||||
*/
|
|
||||||
public synchronized static Method getMethod(final Class<?> clazz, final String name, final Class<?>... args) {
|
|
||||||
if (!_loadedMethods.containsKey(clazz)) {
|
|
||||||
_loadedMethods.put(clazz, new HashMap<String, Map<ArrayWrapper<Class<?>>, Method>>());
|
|
||||||
}
|
|
||||||
|
|
||||||
final Map<String, Map<ArrayWrapper<Class<?>>, Method>> loadedMethodNames = _loadedMethods.get(clazz);
|
for (final Method m : clazz.getMethods()) {
|
||||||
if (!loadedMethodNames.containsKey(name)) {
|
if (m.getName().equals(name) && Arrays.equals(args, m.getParameterTypes())) {
|
||||||
loadedMethodNames.put(name, new HashMap<ArrayWrapper<Class<?>>, Method>());
|
m.setAccessible(true);
|
||||||
}
|
loadedSignatures.put(wrappedArg, m);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loadedSignatures.put(wrappedArg, null);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
final Map<ArrayWrapper<Class<?>>, Method> loadedSignatures = loadedMethodNames.get(name);
|
@SuppressWarnings("rawtypes")
|
||||||
final ArrayWrapper<Class<?>> wrappedArg = new ArrayWrapper<Class<?>>(args);
|
public static List<Method> getMethodByParamsAndType(final Class source, final Class returnType, final Class... args) {
|
||||||
if (loadedSignatures.containsKey(wrappedArg)) {
|
final List<Method> list = new ArrayList<>();
|
||||||
return loadedSignatures.get(wrappedArg);
|
for (final Method method : findMethodByParams(source.getMethods(), args)) {
|
||||||
}
|
if (method.getReturnType().equals(returnType)) {
|
||||||
|
list.add(method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
for (final Method m : clazz.getMethods()) {
|
/**
|
||||||
if (m.getName().equals(name) && Arrays.equals(args, m.getParameterTypes())) {
|
* Gets a {@link Class} object representing a type contained within the
|
||||||
m.setAccessible(true);
|
* {@code net.minecraft.server} versioned package.
|
||||||
loadedSignatures.put(wrappedArg, m);
|
* The class instances returned by this method are cached, such that no
|
||||||
return m;
|
* lookup will be done twice (unless multiple threads are accessing this
|
||||||
}
|
* method simultaneously).
|
||||||
}
|
*
|
||||||
loadedSignatures.put(wrappedArg, null);
|
* @param className
|
||||||
return null;
|
* The name of the class, excluding the package, within NMS.
|
||||||
}
|
* @return The class instance representing the specified NMS class, or
|
||||||
|
* {@code null} if it could not be loaded.
|
||||||
|
*/
|
||||||
|
public synchronized static Class<?> getNMSClass(final String className) {
|
||||||
|
if (_loadedNMSClasses.containsKey(className)) {
|
||||||
|
return _loadedNMSClasses.get(className);
|
||||||
|
}
|
||||||
|
final String fullName = "net.minecraft.server." + getVersion() + className;
|
||||||
|
Class<?> clazz = null;
|
||||||
|
try {
|
||||||
|
clazz = Class.forName(fullName);
|
||||||
|
} catch (final Exception | NoClassDefFoundError | NoSuchMethodError e) {
|
||||||
|
_loadedNMSClasses.put(className, null);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
_loadedNMSClasses.put(className, clazz);
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
/**
|
||||||
public static List<Method> getMethodByParamsAndType(final Class source, final Class returnType, final Class... args) {
|
* Gets a {@link Class} object representing a type contained within the
|
||||||
final List<Method> list = new ArrayList<>();
|
* {@code org.bukkit.craftbukkit} versioned package.
|
||||||
for (final Method method : findMethodByParams(source.getMethods(), args)) {
|
* The class instances returned by this method are cached, such that no
|
||||||
if (method.getReturnType().equals(returnType)) {
|
* lookup will be done twice (unless multiple threads are accessing this
|
||||||
list.add(method);
|
* method simultaneously).
|
||||||
}
|
*
|
||||||
}
|
* @param className
|
||||||
return list;
|
* The name of the class, excluding the package, within OBC. This
|
||||||
}
|
* name may contain a subpackage name, such as
|
||||||
|
* {@code inventory.CraftItemStack}.
|
||||||
|
* @return The class instance representing the specified OBC class, or
|
||||||
|
* {@code null} if it could not be loaded.
|
||||||
|
*/
|
||||||
|
public synchronized static Class<?> getOBCClass(final String className) {
|
||||||
|
if (_loadedOBCClasses.containsKey(className)) {
|
||||||
|
return _loadedOBCClasses.get(className);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
final String fullName = "org.bukkit.craftbukkit." + getVersion() + className;
|
||||||
* Gets a {@link Class} object representing a type contained within the
|
Class<?> clazz = null;
|
||||||
* {@code net.minecraft.server} versioned package.
|
try {
|
||||||
* The class instances returned by this method are cached, such that no
|
clazz = Class.forName(fullName);
|
||||||
* lookup will be done twice (unless multiple threads are accessing this
|
} catch (final Exception e) {
|
||||||
* method simultaneously).
|
e.printStackTrace();
|
||||||
*
|
_loadedOBCClasses.put(className, null);
|
||||||
* @param className
|
return null;
|
||||||
* The name of the class, excluding the package, within NMS.
|
}
|
||||||
* @return The class instance representing the specified NMS class, or
|
_loadedOBCClasses.put(className, clazz);
|
||||||
* {@code null} if it could not be loaded.
|
return clazz;
|
||||||
*/
|
}
|
||||||
public synchronized static Class<?> getNMSClass(final String className) {
|
|
||||||
if (_loadedNMSClasses.containsKey(className)) {
|
|
||||||
return _loadedNMSClasses.get(className);
|
|
||||||
}
|
|
||||||
final String fullName = "net.minecraft.server." + getVersion() + className;
|
|
||||||
Class<?> clazz = null;
|
|
||||||
try {
|
|
||||||
clazz = Class.forName(fullName);
|
|
||||||
} catch (final Exception | NoClassDefFoundError | NoSuchMethodError e) {
|
|
||||||
_loadedNMSClasses.put(className, null);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
_loadedNMSClasses.put(className, clazz);
|
|
||||||
return clazz;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a {@link Class} object representing a type contained within the
|
* Gets the version string from the package name of the CraftBukkit server
|
||||||
* {@code org.bukkit.craftbukkit} versioned package.
|
* implementation.
|
||||||
* The class instances returned by this method are cached, such that no
|
* This is needed to bypass the JAR package name changing on each update.
|
||||||
* lookup will be done twice (unless multiple threads are accessing this
|
*
|
||||||
* method simultaneously).
|
* @return The version string of the OBC and NMS packages,
|
||||||
*
|
* <em>including the trailing dot</em>.
|
||||||
* @param className
|
*/
|
||||||
* The name of the class, excluding the package, within OBC. This
|
public synchronized static String getVersion() {
|
||||||
* name may contain a subpackage name, such as
|
if (_versionString == null) {
|
||||||
* {@code inventory.CraftItemStack}.
|
if (Bukkit.getServer() == null) {
|
||||||
* @return The class instance representing the specified OBC class, or
|
// The server hasn't started, static initializer call?
|
||||||
* {@code null} if it could not be loaded.
|
return null;
|
||||||
*/
|
}
|
||||||
public synchronized static Class<?> getOBCClass(final String className) {
|
final String name = Bukkit.getServer().getClass().getPackage().getName();
|
||||||
if (_loadedOBCClasses.containsKey(className)) {
|
_versionString = name.substring(name.lastIndexOf('.') + 1) + ".";
|
||||||
return _loadedOBCClasses.get(className);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
final String fullName = "org.bukkit.craftbukkit." + getVersion() + className;
|
return _versionString;
|
||||||
Class<?> clazz = null;
|
}
|
||||||
try {
|
|
||||||
clazz = Class.forName(fullName);
|
|
||||||
} catch (final Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
_loadedOBCClasses.put(className, null);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
_loadedOBCClasses.put(className, clazz);
|
|
||||||
return clazz;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
@SuppressWarnings("rawtypes")
|
||||||
* Gets the version string from the package name of the CraftBukkit server
|
private static List<Method> findMethodByParams(final Method[] methods, final Class... args) {
|
||||||
* implementation.
|
final List<Method> list = new ArrayList<>();
|
||||||
* This is needed to bypass the JAR package name changing on each update.
|
start:
|
||||||
*
|
for (final Method method : methods) {
|
||||||
* @return The version string of the OBC and NMS packages,
|
if (method.getParameterTypes().length == args.length) {
|
||||||
* <em>including the trailing dot</em>.
|
final Class[] array = method.getParameterTypes();
|
||||||
*/
|
for (int i = 0; i < args.length; i++) {
|
||||||
public synchronized static String getVersion() {
|
if (array[i] != args[i]) {
|
||||||
if (_versionString == null) {
|
continue start;
|
||||||
if (Bukkit.getServer() == null) {
|
}
|
||||||
// The server hasn't started, static initializer call?
|
}
|
||||||
return null;
|
method.setAccessible(true);
|
||||||
}
|
list.add(method);
|
||||||
final String name = Bukkit.getServer().getClass().getPackage().getName();
|
}
|
||||||
_versionString = name.substring(name.lastIndexOf('.') + 1) + ".";
|
}
|
||||||
}
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
return _versionString;
|
private Reflection() {
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
}
|
||||||
private static List<Method> findMethodByParams(final Method[] methods, final Class... args) {
|
|
||||||
final List<Method> list = new ArrayList<>();
|
|
||||||
start:
|
|
||||||
for (final Method method : methods) {
|
|
||||||
if (method.getParameterTypes().length == args.length) {
|
|
||||||
final Class[] array = method.getParameterTypes();
|
|
||||||
for (int i = 0; i < args.length; i++) {
|
|
||||||
if (array[i] != args[i]) {
|
|
||||||
continue start;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
method.setAccessible(true);
|
|
||||||
list.add(method);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,331 +22,331 @@ import cn.citycraft.GsonAgent.api.stream.JsonWriter;
|
|||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public abstract class TextualComponent implements Cloneable {
|
public abstract class TextualComponent implements Cloneable {
|
||||||
static {
|
static {
|
||||||
ConfigurationSerialization.registerClass(TextualComponent.ArbitraryTextTypeComponent.class);
|
ConfigurationSerialization.registerClass(TextualComponent.ArbitraryTextTypeComponent.class);
|
||||||
ConfigurationSerialization.registerClass(TextualComponent.ComplexTextTypeComponent.class);
|
ConfigurationSerialization.registerClass(TextualComponent.ComplexTextTypeComponent.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TextualComponent deserialize(final Map<String, Object> map) {
|
public static TextualComponent deserialize(final Map<String, Object> map) {
|
||||||
if (map.containsKey("key") && map.size() == 2 && map.containsKey("value")) {
|
if (map.containsKey("key") && map.size() == 2 && map.containsKey("value")) {
|
||||||
// Arbitrary text component
|
// Arbitrary text component
|
||||||
return ArbitraryTextTypeComponent.deserialize(map);
|
return ArbitraryTextTypeComponent.deserialize(map);
|
||||||
} else if (map.size() >= 2 && map.containsKey("key") && !map.containsKey("value")) {
|
} else if (map.size() >= 2 && map.containsKey("key") && !map.containsKey("value")) {
|
||||||
// Complex JSON object
|
// Complex JSON object
|
||||||
return ComplexTextTypeComponent.deserialize(map);
|
return ComplexTextTypeComponent.deserialize(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isTextKey(final String key) {
|
public static boolean isTextKey(final String key) {
|
||||||
return key.equals("translate") || key.equals("text") || key.equals("score") || key.equals("selector");
|
return key.equals("translate") || key.equals("text") || key.equals("score") || key.equals("selector");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a textual component representing a localized string.
|
* Create a textual component representing a localized string.
|
||||||
* The client will see this text component as their localized version of the
|
* The client will see this text component as their localized version of the
|
||||||
* specified string <em>key</em>, which can be overridden by a resource
|
* specified string <em>key</em>, which can be overridden by a resource
|
||||||
* pack.
|
* pack.
|
||||||
* <p>
|
* <p>
|
||||||
* If the specified translation key is not present on the client resource
|
* If the specified translation key is not present on the client resource
|
||||||
* pack, the translation key will be displayed as a string literal to the
|
* pack, the translation key will be displayed as a string literal to the
|
||||||
* client.
|
* client.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param translateKey
|
* @param translateKey
|
||||||
* The string key which maps to localized text.
|
* The string key which maps to localized text.
|
||||||
* @return The text component representing the specified localized text.
|
* @return The text component representing the specified localized text.
|
||||||
*/
|
*/
|
||||||
public static TextualComponent localizedText(final String translateKey) {
|
public static TextualComponent localizedText(final String translateKey) {
|
||||||
return new ArbitraryTextTypeComponent("translate", translateKey);
|
return new ArbitraryTextTypeComponent("translate", translateKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a textual component representing a scoreboard value.
|
* Create a textual component representing a scoreboard value.
|
||||||
* The client will see their own score for the specified objective as the
|
* The client will see their own score for the specified objective as the
|
||||||
* text represented by this component.
|
* text represented by this component.
|
||||||
* <p>
|
* <p>
|
||||||
* <b>This method is currently guaranteed to throw an
|
* <b>This method is currently guaranteed to throw an
|
||||||
* {@code UnsupportedOperationException} as it is only supported on snapshot
|
* {@code UnsupportedOperationException} as it is only supported on snapshot
|
||||||
* clients.</b>
|
* clients.</b>
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param scoreboardObjective
|
* @param scoreboardObjective
|
||||||
* The name of the objective for which to display the score.
|
* The name of the objective for which to display the score.
|
||||||
* @return The text component representing the specified scoreboard score
|
* @return The text component representing the specified scoreboard score
|
||||||
* (for the viewing player), or {@code null} if an error occurs
|
* (for the viewing player), or {@code null} if an error occurs
|
||||||
* during JSON serialization.
|
* during JSON serialization.
|
||||||
*/
|
*/
|
||||||
public static TextualComponent objectiveScore(final String scoreboardObjective) {
|
public static TextualComponent objectiveScore(final String scoreboardObjective) {
|
||||||
return objectiveScore("*", scoreboardObjective);
|
return objectiveScore("*", scoreboardObjective);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a textual component representing a scoreboard value.
|
* Create a textual component representing a scoreboard value.
|
||||||
* The client will see the score of the specified player for the specified
|
* The client will see the score of the specified player for the specified
|
||||||
* objective as the text represented by this component.
|
* objective as the text represented by this component.
|
||||||
* <p>
|
* <p>
|
||||||
* <b>This method is currently guaranteed to throw an
|
* <b>This method is currently guaranteed to throw an
|
||||||
* {@code UnsupportedOperationException} as it is only supported on snapshot
|
* {@code UnsupportedOperationException} as it is only supported on snapshot
|
||||||
* clients.</b>
|
* clients.</b>
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param playerName
|
* @param playerName
|
||||||
* The name of the player whos score will be shown. If this
|
* The name of the player whos score will be shown. If this
|
||||||
* string represents the single-character sequence "*", the
|
* string represents the single-character sequence "*", the
|
||||||
* viewing player's score will be displayed.
|
* viewing player's score will be displayed.
|
||||||
* Standard minecraft selectors (@a, @p, etc) are <em>not</em>
|
* Standard minecraft selectors (@a, @p, etc) are <em>not</em>
|
||||||
* supported.
|
* supported.
|
||||||
* @param scoreboardObjective
|
* @param scoreboardObjective
|
||||||
* The name of the objective for which to display the score.
|
* The name of the objective for which to display the score.
|
||||||
* @return The text component representing the specified scoreboard score
|
* @return The text component representing the specified scoreboard score
|
||||||
* for the specified player, or {@code null} if an error occurs
|
* for the specified player, or {@code null} if an error occurs
|
||||||
* during JSON serialization.
|
* during JSON serialization.
|
||||||
*/
|
*/
|
||||||
public static TextualComponent objectiveScore(final String playerName, final String scoreboardObjective) {
|
public static TextualComponent objectiveScore(final String playerName, final String scoreboardObjective) {
|
||||||
throwUnsupportedSnapshot(); // Remove this line when the feature is
|
throwUnsupportedSnapshot(); // Remove this line when the feature is
|
||||||
// released to non-snapshot versions, in
|
// released to non-snapshot versions, in
|
||||||
// addition to updating ALL THE OVERLOADS
|
// addition to updating ALL THE OVERLOADS
|
||||||
// documentation accordingly
|
// documentation accordingly
|
||||||
|
|
||||||
return new ComplexTextTypeComponent("score", ImmutableMap.<String, String> builder().put("name", playerName).put("objective", scoreboardObjective).build());
|
return new ComplexTextTypeComponent("score", ImmutableMap.<String, String> builder().put("name", playerName).put("objective", scoreboardObjective).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a textual component representing a string literal.
|
* Create a textual component representing a string literal.
|
||||||
* This is the default type of textual component when a single string
|
* This is the default type of textual component when a single string
|
||||||
* literal is given to a method.
|
* literal is given to a method.
|
||||||
*
|
*
|
||||||
* @param textValue
|
* @param textValue
|
||||||
* The text which will be represented.
|
* The text which will be represented.
|
||||||
* @return The text component representing the specified literal text.
|
* @return The text component representing the specified literal text.
|
||||||
*/
|
*/
|
||||||
public static TextualComponent rawText(final String textValue) {
|
public static TextualComponent rawText(final String textValue) {
|
||||||
return new ArbitraryTextTypeComponent("text", textValue);
|
return new ArbitraryTextTypeComponent("text", textValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a textual component representing a player name, retrievable by
|
* Create a textual component representing a player name, retrievable by
|
||||||
* using a standard minecraft selector.
|
* using a standard minecraft selector.
|
||||||
* The client will see the players or entities captured by the specified
|
* The client will see the players or entities captured by the specified
|
||||||
* selector as the text represented by this component.
|
* selector as the text represented by this component.
|
||||||
* <p>
|
* <p>
|
||||||
* <b>This method is currently guaranteed to throw an
|
* <b>This method is currently guaranteed to throw an
|
||||||
* {@code UnsupportedOperationException} as it is only supported on snapshot
|
* {@code UnsupportedOperationException} as it is only supported on snapshot
|
||||||
* clients.</b>
|
* clients.</b>
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param selector
|
* @param selector
|
||||||
* The minecraft player or entity selector which will capture the
|
* The minecraft player or entity selector which will capture the
|
||||||
* entities whose string representations will be displayed in the
|
* entities whose string representations will be displayed in the
|
||||||
* place of this text component.
|
* place of this text component.
|
||||||
* @return The text component representing the name of the entities captured
|
* @return The text component representing the name of the entities captured
|
||||||
* by the selector.
|
* by the selector.
|
||||||
*/
|
*/
|
||||||
public static TextualComponent selector(final String selector) {
|
public static TextualComponent selector(final String selector) {
|
||||||
throwUnsupportedSnapshot(); // Remove this line when the feature is
|
throwUnsupportedSnapshot(); // Remove this line when the feature is
|
||||||
// released to non-snapshot versions, in
|
// released to non-snapshot versions, in
|
||||||
// addition to updating ALL THE OVERLOADS
|
// addition to updating ALL THE OVERLOADS
|
||||||
// documentation accordingly
|
// documentation accordingly
|
||||||
|
|
||||||
return new ArbitraryTextTypeComponent("selector", selector);
|
return new ArbitraryTextTypeComponent("selector", selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void throwUnsupportedSnapshot() {
|
private static void throwUnsupportedSnapshot() {
|
||||||
throw new UnsupportedOperationException("This feature is only supported in snapshot releases.");
|
throw new UnsupportedOperationException("This feature is only supported in snapshot releases.");
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean isTranslatableText(final TextualComponent component) {
|
static boolean isTranslatableText(final TextualComponent component) {
|
||||||
return component instanceof ComplexTextTypeComponent && ((ComplexTextTypeComponent) component).getKey().equals("translate");
|
return component instanceof ComplexTextTypeComponent && ((ComplexTextTypeComponent) component).getKey().equals("translate");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clones a textual component instance.
|
* Clones a textual component instance.
|
||||||
* The returned object should not reference this textual component instance,
|
* The returned object should not reference this textual component instance,
|
||||||
* but should maintain the same key and value.
|
* but should maintain the same key and value.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public abstract TextualComponent clone() throws CloneNotSupportedException;
|
public abstract TextualComponent clone() throws CloneNotSupportedException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The JSON key used to represent text components of this type.
|
* @return The JSON key used to represent text components of this type.
|
||||||
*/
|
*/
|
||||||
public abstract String getKey();
|
public abstract String getKey();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return A readable String
|
* @return A readable String
|
||||||
*/
|
*/
|
||||||
public abstract String getReadableString();
|
public abstract String getReadableString();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getReadableString();
|
return getReadableString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the text data represented by this textual component to the
|
* Writes the text data represented by this textual component to the
|
||||||
* specified JSON writer object.
|
* specified JSON writer object.
|
||||||
* A new object within the writer is not started.
|
* A new object within the writer is not started.
|
||||||
*
|
*
|
||||||
* @param writer
|
* @param writer
|
||||||
* The object to which to write the JSON data.
|
* The object to which to write the JSON data.
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* If an error occurs while writing to the stream.
|
* If an error occurs while writing to the stream.
|
||||||
*/
|
*/
|
||||||
public abstract void writeJson(JsonWriter writer) throws IOException;
|
public abstract void writeJson(JsonWriter writer) throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal class used to represent all types of text components.
|
* Internal class used to represent all types of text components.
|
||||||
* Exception validating done is on keys and values.
|
* Exception validating done is on keys and values.
|
||||||
*/
|
*/
|
||||||
private static final class ArbitraryTextTypeComponent extends TextualComponent implements ConfigurationSerializable {
|
private static final class ArbitraryTextTypeComponent extends TextualComponent implements ConfigurationSerializable {
|
||||||
|
|
||||||
private String _key;
|
private String _key;
|
||||||
|
|
||||||
private String _value;
|
private String _value;
|
||||||
|
|
||||||
public ArbitraryTextTypeComponent(final String key, final String value) {
|
public static ArbitraryTextTypeComponent deserialize(final Map<String, Object> map) {
|
||||||
setKey(key);
|
return new ArbitraryTextTypeComponent(map.get("key").toString(), map.get("value").toString());
|
||||||
setValue(value);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static ArbitraryTextTypeComponent deserialize(final Map<String, Object> map) {
|
public ArbitraryTextTypeComponent(final String key, final String value) {
|
||||||
return new ArbitraryTextTypeComponent(map.get("key").toString(), map.get("value").toString());
|
setKey(key);
|
||||||
}
|
setValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TextualComponent clone() throws CloneNotSupportedException {
|
public TextualComponent clone() throws CloneNotSupportedException {
|
||||||
// Since this is a private and final class, we can just
|
// Since this is a private and final class, we can just
|
||||||
// reinstantiate this class instead of casting super.clone
|
// reinstantiate this class instead of casting super.clone
|
||||||
return new ArbitraryTextTypeComponent(getKey(), getValue());
|
return new ArbitraryTextTypeComponent(getKey(), getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getKey() {
|
public String getKey() {
|
||||||
return _key;
|
return _key;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getReadableString() {
|
public String getReadableString() {
|
||||||
return getValue();
|
return getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getValue() {
|
public String getValue() {
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public Map<String, Object> serialize() {
|
public Map<String, Object> serialize() {
|
||||||
return new HashMap<String, Object>() {
|
return new HashMap<String, Object>() {
|
||||||
{
|
{
|
||||||
put("key", getKey());
|
put("key", getKey());
|
||||||
put("value", getValue());
|
put("value", getValue());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setKey(final String key) {
|
public void setKey(final String key) {
|
||||||
Preconditions.checkArgument(key != null && !key.isEmpty(), "The key must be specified.");
|
Preconditions.checkArgument(key != null && !key.isEmpty(), "The key must be specified.");
|
||||||
_key = key;
|
_key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setValue(final String value) {
|
public void setValue(final String value) {
|
||||||
Preconditions.checkArgument(value != null, "The value must be specified.");
|
Preconditions.checkArgument(value != null, "The value must be specified.");
|
||||||
_value = value;
|
_value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeJson(final JsonWriter writer) throws IOException {
|
public void writeJson(final JsonWriter writer) throws IOException {
|
||||||
writer.name(getKey()).value(getValue());
|
writer.name(getKey()).value(getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal class used to represent a text component with a nested JSON
|
* Internal class used to represent a text component with a nested JSON
|
||||||
* value.
|
* value.
|
||||||
* Exception validating done is on keys and values.
|
* Exception validating done is on keys and values.
|
||||||
*/
|
*/
|
||||||
private static final class ComplexTextTypeComponent extends TextualComponent implements ConfigurationSerializable {
|
private static final class ComplexTextTypeComponent extends TextualComponent implements ConfigurationSerializable {
|
||||||
|
|
||||||
private String _key;
|
private String _key;
|
||||||
|
|
||||||
private Map<String, String> _value;
|
private Map<String, String> _value;
|
||||||
|
|
||||||
public ComplexTextTypeComponent(final String key, final Map<String, String> values) {
|
public static ComplexTextTypeComponent deserialize(final Map<String, Object> map) {
|
||||||
setKey(key);
|
String key = null;
|
||||||
setValue(values);
|
final Map<String, String> value = new HashMap<String, String>();
|
||||||
}
|
for (final Map.Entry<String, Object> valEntry : map.entrySet()) {
|
||||||
|
if (valEntry.getKey().equals("key")) {
|
||||||
|
key = (String) valEntry.getValue();
|
||||||
|
} else if (valEntry.getKey().startsWith("value.")) {
|
||||||
|
value.put(valEntry.getKey().substring(6) /*
|
||||||
|
* Strips out the
|
||||||
|
* value prefix
|
||||||
|
*/, valEntry.getValue().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new ComplexTextTypeComponent(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
public static ComplexTextTypeComponent deserialize(final Map<String, Object> map) {
|
public ComplexTextTypeComponent(final String key, final Map<String, String> values) {
|
||||||
String key = null;
|
setKey(key);
|
||||||
final Map<String, String> value = new HashMap<String, String>();
|
setValue(values);
|
||||||
for (final Map.Entry<String, Object> valEntry : map.entrySet()) {
|
}
|
||||||
if (valEntry.getKey().equals("key")) {
|
|
||||||
key = (String) valEntry.getValue();
|
|
||||||
} else if (valEntry.getKey().startsWith("value.")) {
|
|
||||||
value.put(valEntry.getKey().substring(6) /*
|
|
||||||
* Strips out the
|
|
||||||
* value prefix
|
|
||||||
*/, valEntry.getValue().toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new ComplexTextTypeComponent(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TextualComponent clone() throws CloneNotSupportedException {
|
public TextualComponent clone() throws CloneNotSupportedException {
|
||||||
// Since this is a private and final class, we can just
|
// Since this is a private and final class, we can just
|
||||||
// reinstantiate this class instead of casting super.clone
|
// reinstantiate this class instead of casting super.clone
|
||||||
return new ComplexTextTypeComponent(getKey(), getValue());
|
return new ComplexTextTypeComponent(getKey(), getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getKey() {
|
public String getKey() {
|
||||||
return _key;
|
return _key;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getReadableString() {
|
public String getReadableString() {
|
||||||
return getKey();
|
return getKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getValue() {
|
public Map<String, String> getValue() {
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public Map<String, Object> serialize() {
|
public Map<String, Object> serialize() {
|
||||||
return new java.util.HashMap<String, Object>() {
|
return new java.util.HashMap<String, Object>() {
|
||||||
{
|
{
|
||||||
put("key", getKey());
|
put("key", getKey());
|
||||||
for (final Map.Entry<String, String> valEntry : getValue().entrySet()) {
|
for (final Map.Entry<String, String> valEntry : getValue().entrySet()) {
|
||||||
put("value." + valEntry.getKey(), valEntry.getValue());
|
put("value." + valEntry.getKey(), valEntry.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setKey(final String key) {
|
public void setKey(final String key) {
|
||||||
Preconditions.checkArgument(key != null && !key.isEmpty(), "The key must be specified.");
|
Preconditions.checkArgument(key != null && !key.isEmpty(), "The key must be specified.");
|
||||||
_key = key;
|
_key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setValue(final Map<String, String> value) {
|
public void setValue(final Map<String, String> value) {
|
||||||
Preconditions.checkArgument(value != null, "The value must be specified.");
|
Preconditions.checkArgument(value != null, "The value must be specified.");
|
||||||
_value = value;
|
_value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeJson(final JsonWriter writer) throws IOException {
|
public void writeJson(final JsonWriter writer) throws IOException {
|
||||||
writer.name(getKey());
|
writer.name(getKey());
|
||||||
writer.beginObject();
|
writer.beginObject();
|
||||||
for (final Map.Entry<String, String> jsonPair : _value.entrySet()) {
|
for (final Map.Entry<String, String> jsonPair : _value.entrySet()) {
|
||||||
writer.name(jsonPair.getKey()).value(jsonPair.getValue());
|
writer.name(jsonPair.getKey()).value(jsonPair.getValue());
|
||||||
}
|
}
|
||||||
writer.endObject();
|
writer.endObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,185 +39,185 @@ import cn.citycraft.TellRaw.common.TextualComponent;
|
|||||||
*/
|
*/
|
||||||
public class FancyMessageInternal extends FancyMessage {
|
public class FancyMessageInternal extends FancyMessage {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新建自动序列化类
|
* 新建自动序列化类
|
||||||
*/
|
*/
|
||||||
public FancyMessageInternal() {
|
public FancyMessageInternal() {
|
||||||
this("");
|
this("");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新建自动序列化类
|
* 新建自动序列化类
|
||||||
*
|
*
|
||||||
* @param firstPartText
|
* @param firstPartText
|
||||||
* 第一个文本串
|
* 第一个文本串
|
||||||
*/
|
*/
|
||||||
public FancyMessageInternal(final String firstPartText) {
|
public FancyMessageInternal(final String firstPartText) {
|
||||||
super(TextualComponent.rawText(firstPartText));
|
super(TextualComponent.rawText(firstPartText));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FancyMessage achievementTooltip(final Achievement which) {
|
public FancyMessage achievementTooltip(final Achievement which) {
|
||||||
try {
|
try {
|
||||||
final Object achievement = getNMSAchievementMethod.invoke(null, which);
|
final Object achievement = getNMSAchievementMethod.invoke(null, which);
|
||||||
return achievementTooltip((String) nmsAchievement_NameField.get(achievement));
|
return achievementTooltip((String) nmsAchievement_NameField.get(achievement));
|
||||||
} catch (final IllegalAccessException e) {
|
} catch (final IllegalAccessException e) {
|
||||||
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
|
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
|
||||||
return this;
|
return this;
|
||||||
} catch (final IllegalArgumentException e) {
|
} catch (final IllegalArgumentException e) {
|
||||||
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
|
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
|
||||||
return this;
|
return this;
|
||||||
} catch (final InvocationTargetException e) {
|
} catch (final InvocationTargetException e) {
|
||||||
Bukkit.getLogger().log(Level.WARNING, "A error has occured durring invoking of method.", e);
|
Bukkit.getLogger().log(Level.WARNING, "A error has occured durring invoking of method.", e);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FancyMessage itemTooltip(final ItemStack itemStack) {
|
public FancyMessage itemTooltip(final ItemStack itemStack) {
|
||||||
try {
|
try {
|
||||||
final Object nmsItem = getOBCasNMSCopyMethod.invoke(null, itemStack);
|
final Object nmsItem = getOBCasNMSCopyMethod.invoke(null, itemStack);
|
||||||
return itemTooltip(getNMSSaveNBTMethod.invoke(nmsItem, nmsNBTTagCompound.newInstance()).toString());
|
return itemTooltip(getNMSSaveNBTMethod.invoke(nmsItem, nmsNBTTagCompound.newInstance()).toString());
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void send(final CommandSender sender, final String jsonString) {
|
public void send(final CommandSender sender, final String jsonString) {
|
||||||
if (!(sender instanceof Player)) {
|
if (!(sender instanceof Player)) {
|
||||||
sender.sendMessage(toOldMessageFormat());
|
sender.sendMessage(toOldMessageFormat());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Player player = (Player) sender;
|
final Player player = (Player) sender;
|
||||||
try {
|
try {
|
||||||
final Object handle = Reflection.getHandle(player);
|
final Object handle = Reflection.getHandle(player);
|
||||||
if (nmsPlayerConnectionField == null) {
|
if (nmsPlayerConnectionField == null) {
|
||||||
try {
|
try {
|
||||||
nmsPlayerConnectionField = Reflection.getField(handle.getClass(), "playerConnection");
|
nmsPlayerConnectionField = Reflection.getField(handle.getClass(), "playerConnection");
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
for (final Field field : handle.getClass().getDeclaredFields()) {
|
for (final Field field : handle.getClass().getDeclaredFields()) {
|
||||||
if (field.getType().getSimpleName().contains("NetHandlerPlayServer")) {
|
if (field.getType().getSimpleName().contains("NetHandlerPlayServer")) {
|
||||||
nmsPlayerConnectionField = field;
|
nmsPlayerConnectionField = field;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final Object connection = nmsPlayerConnectionField.get(handle);
|
final Object connection = nmsPlayerConnectionField.get(handle);
|
||||||
if (nmsSendPacketMethod == null) {
|
if (nmsSendPacketMethod == null) {
|
||||||
try {
|
try {
|
||||||
nmsSendPacketMethod = Reflection.getMethod(connection.getClass(), "sendPacket", nmsPacketClass);
|
nmsSendPacketMethod = Reflection.getMethod(connection.getClass(), "sendPacket", nmsPacketClass);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
nmsSendPacketMethod = Reflection.getMethodByParamsAndType(connection.getClass(), Void.TYPE, nmsPacketClass).get(0);
|
nmsSendPacketMethod = Reflection.getMethodByParamsAndType(connection.getClass(), Void.TYPE, nmsPacketClass).get(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nmsSendPacketMethod == null) {
|
if (nmsSendPacketMethod == null) {
|
||||||
throw new RuntimeException("could find field: sendPacket in EntityPlayer class");
|
throw new RuntimeException("could find field: sendPacket in EntityPlayer class");
|
||||||
}
|
}
|
||||||
nmsSendPacketMethod.invoke(connection, createChatPacket(jsonString));
|
nmsSendPacketMethod.invoke(connection, createChatPacket(jsonString));
|
||||||
} catch (final IllegalArgumentException e) {
|
} catch (final IllegalArgumentException e) {
|
||||||
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
|
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
|
||||||
} catch (final IllegalAccessException e) {
|
} catch (final IllegalAccessException e) {
|
||||||
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
|
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
|
||||||
} catch (final InstantiationException e) {
|
} catch (final InstantiationException e) {
|
||||||
Bukkit.getLogger().log(Level.WARNING, "Underlying class is abstract.", e);
|
Bukkit.getLogger().log(Level.WARNING, "Underlying class is abstract.", e);
|
||||||
} catch (final InvocationTargetException e) {
|
} catch (final InvocationTargetException e) {
|
||||||
Bukkit.getLogger().log(Level.WARNING, "A error has occured durring invoking of method.", e);
|
Bukkit.getLogger().log(Level.WARNING, "A error has occured durring invoking of method.", e);
|
||||||
} catch (final NoSuchMethodException e) {
|
} catch (final NoSuchMethodException e) {
|
||||||
Bukkit.getLogger().log(Level.WARNING, "Could not find method.", e);
|
Bukkit.getLogger().log(Level.WARNING, "Could not find method.", e);
|
||||||
} catch (final ClassNotFoundException e) {
|
} catch (final ClassNotFoundException e) {
|
||||||
Bukkit.getLogger().log(Level.WARNING, "Could not find class.", e);
|
Bukkit.getLogger().log(Level.WARNING, "Could not find class.", e);
|
||||||
} catch (final SecurityException ex) {
|
} catch (final SecurityException ex) {
|
||||||
Logger.getLogger(FancyMessageInternal.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(FancyMessageInternal.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FancyMessage statisticTooltip(final Statistic which) {
|
public FancyMessage statisticTooltip(final Statistic which) {
|
||||||
final Type type = which.getType();
|
final Type type = which.getType();
|
||||||
if (type != Type.UNTYPED) {
|
if (type != Type.UNTYPED) {
|
||||||
throw new IllegalArgumentException("That statistic requires an additional " + type + " parameter!");
|
throw new IllegalArgumentException("That statistic requires an additional " + type + " parameter!");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final Object statistic = getNMSStatisticMethod.invoke(null, which);
|
final Object statistic = getNMSStatisticMethod.invoke(null, which);
|
||||||
return achievementTooltip((String) nmsStatistic_NameField.get(statistic));
|
return achievementTooltip((String) nmsStatistic_NameField.get(statistic));
|
||||||
} catch (final IllegalAccessException e) {
|
} catch (final IllegalAccessException e) {
|
||||||
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
|
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
|
||||||
return this;
|
return this;
|
||||||
} catch (final IllegalArgumentException e) {
|
} catch (final IllegalArgumentException e) {
|
||||||
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
|
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
|
||||||
return this;
|
return this;
|
||||||
} catch (final InvocationTargetException e) {
|
} catch (final InvocationTargetException e) {
|
||||||
Bukkit.getLogger().log(Level.WARNING, "A error has occured durring invoking of method.", e);
|
Bukkit.getLogger().log(Level.WARNING, "A error has occured durring invoking of method.", e);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FancyMessage statisticTooltip(final Statistic which, final EntityType entity) {
|
public FancyMessage statisticTooltip(final Statistic which, final EntityType entity) {
|
||||||
final Type type = which.getType();
|
final Type type = which.getType();
|
||||||
if (type == Type.UNTYPED) {
|
if (type == Type.UNTYPED) {
|
||||||
throw new IllegalArgumentException("That statistic needs no additional parameter!");
|
throw new IllegalArgumentException("That statistic needs no additional parameter!");
|
||||||
}
|
}
|
||||||
if (type != Type.ENTITY) {
|
if (type != Type.ENTITY) {
|
||||||
throw new IllegalArgumentException("Wrong parameter type for that statistic - needs " + type + "!");
|
throw new IllegalArgumentException("Wrong parameter type for that statistic - needs " + type + "!");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final Object statistic = getNMSEntityStatisticMethod.invoke(null, which, entity);
|
final Object statistic = getNMSEntityStatisticMethod.invoke(null, which, entity);
|
||||||
return achievementTooltip((String) nmsStatistic_NameField.get(statistic));
|
return achievementTooltip((String) nmsStatistic_NameField.get(statistic));
|
||||||
} catch (final IllegalAccessException e) {
|
} catch (final IllegalAccessException e) {
|
||||||
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
|
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
|
||||||
return this;
|
return this;
|
||||||
} catch (final IllegalArgumentException e) {
|
} catch (final IllegalArgumentException e) {
|
||||||
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
|
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
|
||||||
return this;
|
return this;
|
||||||
} catch (final InvocationTargetException e) {
|
} catch (final InvocationTargetException e) {
|
||||||
Bukkit.getLogger().log(Level.WARNING, "A error has occured durring invoking of method.", e);
|
Bukkit.getLogger().log(Level.WARNING, "A error has occured durring invoking of method.", e);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FancyMessage statisticTooltip(final Statistic which, final Material item) {
|
public FancyMessage statisticTooltip(final Statistic which, final Material item) {
|
||||||
final Type type = which.getType();
|
final Type type = which.getType();
|
||||||
if (type == Type.UNTYPED) {
|
if (type == Type.UNTYPED) {
|
||||||
throw new IllegalArgumentException("That statistic needs no additional parameter!");
|
throw new IllegalArgumentException("That statistic needs no additional parameter!");
|
||||||
}
|
}
|
||||||
if ((type == Type.BLOCK && item.isBlock()) || type == Type.ENTITY) {
|
if ((type == Type.BLOCK && item.isBlock()) || type == Type.ENTITY) {
|
||||||
throw new IllegalArgumentException("Wrong parameter type for that statistic - needs " + type + "!");
|
throw new IllegalArgumentException("Wrong parameter type for that statistic - needs " + type + "!");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final Object statistic = getNMSMaterialStatisticMethod.invoke(null, which, item);
|
final Object statistic = getNMSMaterialStatisticMethod.invoke(null, which, item);
|
||||||
return achievementTooltip((String) nmsStatistic_NameField.get(statistic));
|
return achievementTooltip((String) nmsStatistic_NameField.get(statistic));
|
||||||
} catch (final IllegalAccessException e) {
|
} catch (final IllegalAccessException e) {
|
||||||
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
|
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
|
||||||
return this;
|
return this;
|
||||||
} catch (final IllegalArgumentException e) {
|
} catch (final IllegalArgumentException e) {
|
||||||
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
|
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
|
||||||
return this;
|
return this;
|
||||||
} catch (final InvocationTargetException e) {
|
} catch (final InvocationTargetException e) {
|
||||||
Bukkit.getLogger().log(Level.WARNING, "A error has occured durring invoking of method.", e);
|
Bukkit.getLogger().log(Level.WARNING, "A error has occured durring invoking of method.", e);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建Chat数据包
|
* 创建Chat数据包
|
||||||
*
|
*
|
||||||
* @param json
|
* @param json
|
||||||
* 需要创建的数据包
|
* 需要创建的数据包
|
||||||
* @return 创建发包对象
|
* @return 创建发包对象
|
||||||
* @throws IllegalArgumentException
|
* @throws IllegalArgumentException
|
||||||
* @throws IllegalAccessException
|
* @throws IllegalAccessException
|
||||||
* @throws InstantiationException
|
* @throws InstantiationException
|
||||||
* @throws InvocationTargetException
|
* @throws InvocationTargetException
|
||||||
* @throws NoSuchMethodException
|
* @throws NoSuchMethodException
|
||||||
* @throws ClassNotFoundException
|
* @throws ClassNotFoundException
|
||||||
*/
|
*/
|
||||||
private Object createChatPacket(final String json) throws IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException {
|
private Object createChatPacket(final String json) throws IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException {
|
||||||
final Object serializedChatComponent = fromJsonMethod.invoke(nmsChatSerializerGsonInstance, json, nmsIChatBaseComponentClass);
|
final Object serializedChatComponent = fromJsonMethod.invoke(nmsChatSerializerGsonInstance, json, nmsIChatBaseComponentClass);
|
||||||
return nmsPacketPlayOutChatConstructor.newInstance(serializedChatComponent);
|
return nmsPacketPlayOutChatConstructor.newInstance(serializedChatComponent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,55 +31,55 @@ import cn.citycraft.TellRaw.common.TextualComponent;
|
|||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public class FancyMessageManual extends FancyMessage {
|
public class FancyMessageManual extends FancyMessage {
|
||||||
/**
|
/**
|
||||||
* 新建手动序列化类
|
* 新建手动序列化类
|
||||||
*/
|
*/
|
||||||
public FancyMessageManual() {
|
public FancyMessageManual() {
|
||||||
this("");
|
this("");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新建手动序列化类
|
* 新建手动序列化类
|
||||||
*
|
*
|
||||||
* @param firstPartText
|
* @param firstPartText
|
||||||
* 第一个文本串
|
* 第一个文本串
|
||||||
*/
|
*/
|
||||||
public FancyMessageManual(final String firstPartText) {
|
public FancyMessageManual(final String firstPartText) {
|
||||||
super(TextualComponent.rawText(firstPartText));
|
super(TextualComponent.rawText(firstPartText));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FancyMessage achievementTooltip(final Achievement which) {
|
public FancyMessage achievementTooltip(final Achievement which) {
|
||||||
throw new UnsupportedOperationException("暂时不支持当前操作."); // To change body of generated methods, choose Tools | Templates.
|
throw new UnsupportedOperationException("暂时不支持当前操作."); // To change body of generated methods, choose Tools | Templates.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FancyMessage itemTooltip(final ItemStack itemStack) {
|
public FancyMessage itemTooltip(final ItemStack itemStack) {
|
||||||
this.itemTooltip(new GItemStack(itemStack).toString());
|
this.itemTooltip(new GItemStack(itemStack).toString());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void send(final CommandSender sender, final String jsonString) {
|
public void send(final CommandSender sender, final String jsonString) {
|
||||||
if (sender instanceof Player) {
|
if (sender instanceof Player) {
|
||||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender.getName() + " " + jsonString);
|
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender.getName() + " " + jsonString);
|
||||||
} else {
|
} else {
|
||||||
sender.sendMessage(toOldMessageFormat());
|
sender.sendMessage(toOldMessageFormat());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FancyMessage statisticTooltip(final Statistic which) {
|
public FancyMessage statisticTooltip(final Statistic which) {
|
||||||
throw new UnsupportedOperationException("暂时不支持当前操作.");
|
throw new UnsupportedOperationException("暂时不支持当前操作.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FancyMessage statisticTooltip(final Statistic which, final EntityType entity) {
|
public FancyMessage statisticTooltip(final Statistic which, final EntityType entity) {
|
||||||
throw new UnsupportedOperationException("暂时不支持当前操作.");
|
throw new UnsupportedOperationException("暂时不支持当前操作.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FancyMessage statisticTooltip(final Statistic which, final Material item) {
|
public FancyMessage statisticTooltip(final Statistic which, final Material item) {
|
||||||
throw new UnsupportedOperationException("暂时不支持当前操作.");
|
throw new UnsupportedOperationException("暂时不支持当前操作.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,65 +21,65 @@ import cn.citycraft.TellRaw.common.JsonRepresentedObject;
|
|||||||
* @author 许凯
|
* @author 许凯
|
||||||
*/
|
*/
|
||||||
public class GItemStack implements JsonRepresentedObject {
|
public class GItemStack implements JsonRepresentedObject {
|
||||||
private final ItemStack item;
|
private final ItemStack item;
|
||||||
private final String jsonString;
|
private final String jsonString;
|
||||||
|
|
||||||
protected GItemStack(final ItemStack item) {
|
protected GItemStack(final ItemStack item) {
|
||||||
this.item = item.clone();
|
this.item = item.clone();
|
||||||
final StringWriter string = new StringWriter();
|
final StringWriter string = new StringWriter();
|
||||||
final JsonWriter json = GsonAgent.newJsonWriter(string);
|
final JsonWriter json = GsonAgent.newJsonWriter(string);
|
||||||
try {
|
try {
|
||||||
this.writeJson(json);
|
this.writeJson(json);
|
||||||
json.close();
|
json.close();
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
throw new RuntimeException("invalid message:", e);
|
throw new RuntimeException("invalid message:", e);
|
||||||
}
|
}
|
||||||
this.jsonString = string.toString();
|
this.jsonString = string.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return this.jsonString;
|
return this.jsonString;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeJson(final JsonWriter json) throws IOException {
|
public void writeJson(final JsonWriter json) throws IOException {
|
||||||
try {
|
try {
|
||||||
json.beginObject();
|
json.beginObject();
|
||||||
json.nameWithoutQuotes("id").value(this.item.getTypeId());
|
json.nameWithoutQuotes("id").value(this.item.getTypeId());
|
||||||
json.nameWithoutQuotes("Damage").value(this.item.getDurability());
|
json.nameWithoutQuotes("Damage").value(this.item.getDurability());
|
||||||
if (this.item.getAmount() > 1) {
|
if (this.item.getAmount() > 1) {
|
||||||
json.nameWithoutQuotes("Count").value(this.item.getAmount());
|
json.nameWithoutQuotes("Count").value(this.item.getAmount());
|
||||||
}
|
}
|
||||||
if (this.item.hasItemMeta()) {
|
if (this.item.hasItemMeta()) {
|
||||||
json.nameWithoutQuotes("tag").beginObject();
|
json.nameWithoutQuotes("tag").beginObject();
|
||||||
final ItemMeta im = item.getItemMeta();
|
final ItemMeta im = item.getItemMeta();
|
||||||
if (im.hasEnchants()) {
|
if (im.hasEnchants()) {
|
||||||
json.nameWithoutQuotes("ench").beginArray();
|
json.nameWithoutQuotes("ench").beginArray();
|
||||||
for (final Map.Entry<Enchantment, Integer> ench : im.getEnchants().entrySet()) {
|
for (final Map.Entry<Enchantment, Integer> ench : im.getEnchants().entrySet()) {
|
||||||
json.beginObject().nameWithoutQuotes("id").value(ench.getKey().getId()).nameWithoutQuotes("lvl").value(ench.getValue()).endObject();
|
json.beginObject().nameWithoutQuotes("id").value(ench.getKey().getId()).nameWithoutQuotes("lvl").value(ench.getValue()).endObject();
|
||||||
}
|
}
|
||||||
json.endArray();
|
json.endArray();
|
||||||
}
|
}
|
||||||
if (im.hasDisplayName() || im.hasLore()) {
|
if (im.hasDisplayName() || im.hasLore()) {
|
||||||
json.nameWithoutQuotes("display").beginObject();
|
json.nameWithoutQuotes("display").beginObject();
|
||||||
if (im.hasDisplayName()) {
|
if (im.hasDisplayName()) {
|
||||||
json.nameWithoutQuotes("Name").value(im.getDisplayName());
|
json.nameWithoutQuotes("Name").value(im.getDisplayName());
|
||||||
}
|
}
|
||||||
if (im.hasLore()) {
|
if (im.hasLore()) {
|
||||||
json.nameWithoutQuotes("Lore").beginArray();
|
json.nameWithoutQuotes("Lore").beginArray();
|
||||||
for (final String line : im.getLore()) {
|
for (final String line : im.getLore()) {
|
||||||
json.value(line);
|
json.value(line);
|
||||||
}
|
}
|
||||||
json.endArray();
|
json.endArray();
|
||||||
}
|
}
|
||||||
json.endObject();
|
json.endObject();
|
||||||
}
|
}
|
||||||
json.endObject();
|
json.endObject();
|
||||||
}
|
}
|
||||||
json.endObject();
|
json.endObject();
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
Bukkit.getLogger().log(Level.WARNING, "A problem occured during writing of JSON string", e);
|
Bukkit.getLogger().log(Level.WARNING, "A problem occured during writing of JSON string", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
Data:
|
|
||||||
#数据保存方式 [sqlite|MySQL]
|
|
||||||
FileSystem: sqlite
|
|
||||||
#MySQL数据库配置 只有当FileSystem配置为MySQL时有效
|
|
||||||
MySQL:
|
|
||||||
#数据库需要自行建立
|
|
||||||
database: minecraft
|
|
||||||
#数据表需要自行建立
|
|
||||||
tablename: prefixs
|
|
||||||
username: root
|
|
||||||
password:
|
|
||||||
ip: localhost
|
|
||||||
port: 3306
|
|
||||||
Reference in New Issue
Block a user