Compare commits

...
19 Commits
Author SHA1 Message Date
Elikill58 342060b86e Upgrade to 2.4.2 2022-06-30 16:10:38 +02:00
Elikill58 b5b30bd9d8 Fix hex color 2022-06-27 18:28:17 +02:00
Elikill58 55eaac0bd4 Update players 2022-06-25 18:27:29 +02:00
Elikill58 7583aeade7 Update constructor 2022-06-25 18:27:04 +02:00
Elikill58 4be3712082 Fix compatibility with old PL 2022-06-23 16:22:51 +02:00
Elikill58 c1e28709ac Fix array as string 2022-06-23 01:01:06 +02:00
Elikill58 f0965efe73 Fix wrong constructor used 2022-06-23 00:20:09 +02:00
Elikill58 529cdd1e04 Second wave to fix with other plugins 2022-06-22 17:35:23 +02:00
Elikill58 ce867d4065 Remove tag for adventure 2022-06-21 17:29:08 +02:00
Elikill58 1eefb78157 Fix adventure not found 2022-06-21 16:44:08 +02:00
Elikill58 ff0c8d2a8d Upgrade to snapshot 2022-06-21 15:29:22 +02:00
Elikill58 5a250d854d Upgrade to 2.4.1 2022-06-15 00:53:36 +02:00
Elikill58 caacf0d8ae Don't use deprecated things 2022-06-15 00:52:18 +02:00
Elikill58 0f7d4a0548 Remove strange char 2022-06-15 00:49:33 +02:00
Elikill58 4529f74f0a Update dependencies 2022-06-15 00:49:06 +02:00
Elikill58 1eaf32983a Fix purpur issue 2022-06-14 10:15:49 +02:00
Elikill58 24b0682e8b Go to snapshot 2022-06-14 09:25:28 +02:00
Elikill58 cbf3326de6 Fix, again 2022-06-13 19:12:40 +02:00
Elikill58 c4ae9198a4 Fix #41 (included in spigot release) 2022-06-13 15:28:15 +02:00
17 changed files with 220 additions and 58 deletions

No files matched your search

+5 -5
View File
@@ -6,7 +6,7 @@
<groupId>me.dadus33</groupId>
<artifactId>chatitem</artifactId>
<version>2.4</version>
<version>2.4.2</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -73,13 +73,13 @@
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.1</version>
<version>2.17.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.1</version>
<version>2.17.2</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -133,7 +133,7 @@
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.10.1</version>
<version>4.11.0</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -145,7 +145,7 @@
<dependency>
<groupId>com.discordsrv</groupId>
<artifactId>discordsrv</artifactId>
<version>1.24.1-SNAPSHOT</version>
<version>1.25.1</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -56,7 +56,7 @@ public class ChatItem extends JavaPlugin {
public static void debug(String msg) {
if (getInstance().getStorage().DEBUG)
getInstance().getLogger().info("[Debug] " + msg);
getInstance().getLogger().info("[Debug] " + msg.replace(ChatManager.SEPARATOR, 'S'));
}
private void chooseManagers() {
@@ -145,7 +145,7 @@ public class ChatItem extends JavaPlugin {
getServer().getMessenger().registerIncomingPluginChannel(this, brandChannelName, (chan, p, msg) -> {
String client = new String(msg);
String client = new String(msg).substring(1);
ChatItem.debug("Detected client " + client + " for " + p.getName());
ItemPlayer.getPlayer(p).setClientName(client);
});
@@ -1,7 +1,7 @@
package me.dadus33.chatitem;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
@@ -11,7 +11,7 @@ import me.dadus33.chatitem.utils.Version;
public class ItemPlayer {
private static final HashMap<UUID, ItemPlayer> PLAYERS = new HashMap<>();
private static final ConcurrentHashMap<UUID, ItemPlayer> PLAYERS = new ConcurrentHashMap<>();
public static ItemPlayer getPlayer(Player p) {
return PLAYERS.computeIfAbsent(p.getUniqueId(), ItemPlayer::new);
}
@@ -1,6 +1,8 @@
package me.dadus33.chatitem.chatmanager.v1.basecomp.hook;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.stream.Collectors;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
@@ -8,15 +10,18 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.chatmanager.v1.basecomp.IBaseComponentGetter;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
import me.dadus33.chatitem.utils.PacketUtils;
import me.dadus33.chatitem.utils.ReflectionUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
import net.md_5.bungee.chat.ComponentSerializer;
public class AdventureComponentGetter implements IBaseComponentGetter {
private boolean useExtra = false;
@Override
public boolean hasConditions() {
try {
@@ -26,36 +31,70 @@ public class AdventureComponentGetter implements IBaseComponentGetter {
} catch (ClassNotFoundException e) { // can't support this, adventure comp not found
return false;
}
try {
PacketUtils.getNmsClass("PacketPlayOutChat", "network.protocol.game.").getField("adventure$message");
} catch (NoSuchFieldException e) {
return false;
}
return true;
}
@Override
public String getBaseComponentAsJSON(ChatItemPacket packet) {
Component comp = packet.getContent().getSpecificModifier(Component.class).readSafely(0);
if(comp == null)
if(comp == null) {
ChatItem.debug("The component is null.");
return null;
}
String json = ComponentSerializer.toString(BungeeComponentSerializer.legacy().serialize(comp).clone());
ChatItem.debug("AdventureJSON : " + json.replace(ChatManager.SEPARATOR, 'S'));
JsonObject jsonObj = JsonParser.parseString(json).getAsJsonObject();
JsonObject next = new JsonObject();
next.add("extra", jsonObj.get("with"));
return next.toString();
if(jsonObj.has("with")) {
JsonObject next = new JsonObject();
next.add("extra", jsonObj.get("with"));
return next.toString();
}
useExtra = true;
return json;
}
@Override
public void writeJson(ChatItemPacket packet, String json) {
JsonObject next = new JsonObject();
/*JsonObject next = new JsonObject();
next.addProperty("translate", "chat.type.text");
next.add("with", fixParsedArray(JsonParser.parseString(json).getAsJsonObject().getAsJsonArray("extra")));
ChatItem.debug("Adventure Json: " + next.toString());
packet.getContent().getSpecificModifier(Component.class).write(0, BungeeComponentSerializer.legacy().deserialize(ComponentSerializer.parse(next.toString())));
if(useExtra)
next.add("with", fixParsedArray(JsonParser.parseString(json).getAsJsonObject().getAsJsonArray("extra")));
else
next.add("extra", fixParsedArray(JsonParser.parseString(json).getAsJsonObject().getAsJsonArray("extra")));*/
JsonElement globalElement = JsonParser.parseString(json);
JsonArray extraArray = fixParsedArray(globalElement.getAsJsonObject().getAsJsonArray("extra"));
String localJson;
if(useExtra) {
globalElement.getAsJsonObject().add("extra", extraArray);
localJson = globalElement.toString();
} else {
JsonObject next = new JsonObject();
next.addProperty("translate", "chat.type.text");
next.add("with", extraArray);
localJson = next.toString();
}
ChatItem.debug("Adventure Json: " + json);
try {
Class<?> packetClass = packet.getPacket().getClass();
if(packetClass.getSimpleName().equalsIgnoreCase("PacketPlayOutChat")) {
Field componentField = ReflectionUtils.getFirstFieldWith(packetClass, Component.class);
if(componentField != null) {
componentField.setAccessible(true);
componentField.set(packet.getPacket(), BungeeComponentSerializer.legacy().deserialize(ComponentSerializer.parse(localJson)));
} else {
throw new UnsupportedOperationException("The packet PacketPlayOutChat doesn't have Kyori's field. It has: " + Arrays.asList(packetClass.getDeclaredFields()).stream().map(f -> f.getName() + ": " + f.getType().getName()).collect(Collectors.toList()));
}
} else if(packetClass.getSimpleName().equalsIgnoreCase("CliendboundSystemChatPacket")) {
packet.setPacket(packetClass.getConstructor(Component.class, String.class, int.class).newInstance(BungeeComponentSerializer.legacy().deserialize(ComponentSerializer.parse(localJson)), null, 1));
} else {
throw new UnsupportedOperationException("The packet " + packetClass.getSimpleName() + " insupported by the AdventureGetter. Please report this.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
private JsonArray fixParsedArray(JsonArray arr) {
public JsonArray fixParsedArray(JsonArray arr) {
JsonArray next = new JsonArray();
for(JsonElement e : arr) {
if(e.isJsonArray()) {
@@ -90,7 +129,30 @@ public class AdventureComponentGetter implements IBaseComponentGetter {
val = val.replaceAll("\\\"", "\"");
ChatItem.debug("Fixed json: " + ("{" + val.substring(1, val.length() - 1) + "}"));
hoverObject.remove("value");
hoverObject.add("contents", JsonParser.parseString("{" + val.substring(1, val.length() - 1) + "}"));
JsonElement tagElement = JsonParser.parseString("{" + val.substring(1, val.length() - 1) + "}");
tagElement.getAsJsonObject().remove("tag");
/*if(tagElement.getAsJsonObject().has("tag")) {
JsonElement tag = tagElement.getAsJsonObject().get("tag");
if(tag.isJsonObject()) {
JsonObject tagObj = tag.getAsJsonObject();
tagObj.entrySet().forEach(entry -> {
ChatItem.debug("Tag json: " + entry.getKey() + " > " + entry.getValue());
JsonElement value = entry.getValue();
String sval = value.getAsString();
if(Utils.isInteger(sval)) {
if(Utils.isByte(sval))
tagObj.addProperty(entry.getKey(), sval + "b");
else if(Utils.isShort(sval))
tagObj.addProperty(entry.getKey(), sval + "s");
else if(Utils.isLong(sval))
tagObj.addProperty(entry.getKey(), sval + "l");
else
tagObj.addProperty(entry.getKey(), value + "i");
}
});
}
}*/
hoverObject.add("contents", tagElement);
o.add("hoverEvent", hoverObject);
}
}
@@ -1,21 +1,41 @@
package me.dadus33.chatitem.chatmanager.v1.basecomp.hook;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.chatmanager.v1.basecomp.IBaseComponentGetter;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
import me.dadus33.chatitem.utils.PacketUtils;
import net.kyori.adventure.text.Component;
public class StringComponentGetter implements IBaseComponentGetter{
@Override
public String getBaseComponentAsJSON(ChatItemPacket packet) {
return packet.getContent().getStrings().read(0);
String json = packet.getContent().getStrings().readSafely(0);
if(json != null && json.startsWith("[") && json.endsWith("]")) { // if used as array instead of json obj
JsonArray extra = new JsonArray();
for(JsonElement element : JsonParser.parseString(json).getAsJsonArray()) {
if(element.isJsonObject()) { // ignore this
extra.add(element);
} else {
ChatItem.debug("Ignoring element " + element);
}
}
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("text", "");
jsonObject.add("extra", extra);
json = jsonObject.toString();
}
return json;
}
@Override
public void writeJson(ChatItemPacket packet, String json) {
try {
Class<?> packetClass = PacketUtils.getNmsClass("ClientboundSystemChatPacket", "network.protocol.game.");
packet.setPacket(packetClass.getConstructor(String.class, int.class).newInstance(json, 1));
packet.setPacket(packet.getPacket().getClass().getConstructor(Component.class, String.class, int.class).newInstance(null, json, 1));
} catch (Exception e) {
e.printStackTrace();
}
@@ -46,7 +46,6 @@ public class JSONManipulatorCurrent {
public String parse(String json, String placeholder, ItemStack item, String replacement, int protocol)
throws Exception {
ChatItem.debug("Parsing: " + json);
JsonObject obj = JsonParser.parseString(json).getAsJsonObject();
JsonArray array = obj.has("extra") ? obj.getAsJsonArray("extra") : new JsonArray();
final AbstractMap.SimpleEntry<Version, ItemStack> p = new AbstractMap.SimpleEntry<>(
@@ -83,7 +83,7 @@ public class ChatEventListener implements Listener {
}
e.setMessage(msg.toString());
e.setFormat(e.getFormat().replace(oldMsg, e.getMessage())); // set own message for plugin that already put the message into the format
ChatItem.debug("Message: " + e.getMessage() + ", format: " + e.getFormat());
ChatItem.debug("Message: " + e.getMessage().replace(SEPARATOR, 'S') + ", format: " + e.getFormat());
} catch (Exception exc) {
exc.printStackTrace();
}
@@ -8,6 +8,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@@ -65,11 +66,12 @@ public class ChatPacketManager extends PacketHandler {
} catch (Exception e) {
e.printStackTrace();
}
for(IBaseComponentGetter getter : Arrays.asList(new IChatBaseComponentGetter(), new BaseComponentGetter(), new ComponentGetter(), new AdventureComponentGetter())) {
for(IBaseComponentGetter getter : Arrays.asList(new IChatBaseComponentGetter(), new BaseComponentGetter(), new ComponentGetter(), new AdventureComponentGetter(), new StringComponentGetter())) {
if(getter.hasConditions())
baseComponentGetter.add(getter);
}
ChatItem.getInstance().getLogger().info("Loaded " + baseComponentGetter.size() + " getter for base components.");
ChatItem.debug("BaseComponentGetters: " + String.join(", ", baseComponentGetter.stream().map(IBaseComponentGetter::getClass).map(Class::getSimpleName).collect(Collectors.toList())));
}
@Override
@@ -83,11 +85,10 @@ public class ChatPacketManager extends PacketHandler {
String json = "{}";
IBaseComponentGetter choosedGetter = null;
if (version.isNewerOrEquals(Version.V1_19)) {
if(packet.getIntegers().readSafely(0) != 1)
if(packet.getIntegers().readSafely(0, 0) != 1)
return;
String foundedJson = packet.getStrings().read(0); // for final things
json = foundedJson;
choosedGetter = new StringComponentGetter();
json = choosedGetter.getBaseComponentAsJSON(e); // if null, will be re-checked so anyway
} else if (version.isNewerOrEquals(Version.V1_12)) {
// only if action bar messages are supported in this version of minecraft
try {
@@ -106,7 +107,6 @@ public class ChatPacketManager extends PacketHandler {
for(IBaseComponentGetter getters : baseComponentGetter) {
String tmpJson = getters.getBaseComponentAsJSON(e);
if(tmpJson != null) {
ChatItem.debug("Found " + tmpJson + " with " + getters.getClass().getName());
json = tmpJson;
choosedGetter = getters;
break;
@@ -122,8 +122,18 @@ public class ChatPacketManager extends PacketHandler {
}
if (!found) {
ChatItem.debug("No placeholders founded in " + json);
ChatItem.debug("String: " + packet.getStrings().getContent());
try {
Class<?> c = Class.forName("net.kyori.adventure.text.Component");
ChatItem.debug("Component: " + packet.getSpecificModifier(c).getContent());
} catch (ClassNotFoundException exc) {
ChatItem.debug("Can't find Kyori's component");
} catch(Exception exc) {
exc.printStackTrace();
}
return; // then it's just a normal message without placeholders, so we leave it alone
}
ChatItem.debug("Found " + json + " with " + choosedGetter.getClass().getName());
Object toReplace = null;
if (json.lastIndexOf(SEPARATOR) != -1)
toReplace = SEPARATOR;
@@ -133,7 +143,6 @@ public class ChatPacketManager extends PacketHandler {
ChatItem.debug("Not containing bell " + json);
return;
}
ChatItem.debug("Add packet meta to json: " + json);
IBaseComponentGetter fchoosedGetter = choosedGetter;
String fjson = json, toReplaceStr = toReplace.toString();
e.setCancelled(true); // We cancel the packet as we're going to resend it anyways (ignoring listeners
@@ -16,7 +16,11 @@ public class ChatItemPacketManager {
public ChatItemPacketManager(ChatItem pl) {
Plugin protocolLibPlugin = Bukkit.getPluginManager().getPlugin("ProtocolLib");
if (protocolLibPlugin != null) {
if(checkProtocollibConditions()) {
String version = protocolLibPlugin.getDescription().getVersion();
if(version.contains("5.0.0-SNAPSHOT")) {
pl.getLogger().warning("ProtocolLib have been detected, but actually, snapshot have issues with chat packet. More informations here: https://github.com/dmulloy2/ProtocolLib/issues/1670.");
packetManager = new CustomPacketManager(pl);
} else if(checkProtocollibConditions()) {
pl.getLogger().info("The plugin ProtocolLib has been detected. Loading Protocollib support ...");
packetManager = new ProtocollibPacketManager(pl);
} else {
@@ -43,7 +43,7 @@ public interface PacketType {
public static enum Server implements PacketType {
CHAT("Chat", "ClientboundSystemChatPacket"),
CHAT("Chat", "ClientboundPlayerChatPacket", "ClientboundSystemChatPacket"),
UNSET("Unset");
private final String packetName, fullName;
@@ -10,7 +10,6 @@ import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.Plugin;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketManager;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketType;
@@ -84,7 +83,6 @@ public class CustomPacketManager extends PacketManager implements Listener {
public ChatItemPacket onPacketSent(PacketType type, Player sender, Object packet) {
if(type == null) {
ChatItem.debug("Failed to find packet type for " + packet.getClass().getSimpleName());
return null;
}
ChatItemPacket customPacket = new ChatItemPacket(type, packet, sender);
@@ -1,6 +1,7 @@
package me.dadus33.chatitem.chatmanager.v1.packets.protocollib;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.entity.Player;
@@ -23,14 +24,20 @@ public class ProtocollibPacketManager extends PacketManager {
public ProtocollibPacketManager(ChatItem pl) {
protocolManager = ProtocolLibrary.getProtocolManager();
protocolManager.addPacketListener(new PacketAdapter(pl, ListenerPriority.LOWEST, Arrays.asList(Play.Server.CHAT)) {
List<com.comphenix.protocol.PacketType> list = new ArrayList<>();
list.add(Play.Server.CHAT);
try {
list.add((com.comphenix.protocol.PacketType) Play.Server.class.getDeclaredField("SYSTEM_CHAT").get(null));
} catch (Exception e) {
// ignore because using old version
}
protocolManager.addPacketListener(new PacketAdapter(pl, ListenerPriority.LOWEST, list) {
@Override
public void onPacketSending(PacketEvent e) {
Player p = e.getPlayer();
if (p == null || e.isPlayerTemporary())
return;
ChatItemPacket packet = onPacketSent(PacketType.getType(e.getPacket().getHandle().getClass().getSimpleName()),
p, e.getPacket().getHandle());
ChatItemPacket packet = onPacketSent(PacketType.getType(e.getPacket().getHandle().getClass().getSimpleName()), p, e.getPacket().getHandle());
if(packet == null) {
ChatItem.debug("Can't find packet: " + e.getPacket().getHandle().getClass().getName());
return;
@@ -154,9 +154,9 @@ public class ChatListener implements Listener {
private void showItem(Player to, Player origin, ItemStack item, String msg) {
ComponentBuilder builder = new ComponentBuilder("");
ChatColor color = ChatColor.RESET;
ChatColor color = ChatColor.WHITE;
String colorCode = "", text = "";
boolean waiting = false, isHex = false;
boolean waiting = false;
for (char args : msg.toCharArray()) {
if (args == '§') { // begin of color
if (colorCode.isEmpty() && !text.isEmpty()) { // text before this char
@@ -172,15 +172,23 @@ public class ChatListener implements Listener {
color = ChatColor.RESET;
continue;
}
if(args == 'x' && colorCode.isEmpty())
isHex = true;
colorCode += args; // a color by itself
if(args == 'x' && !colorCode.isEmpty()) {
text += ColorManager.getColorString(colorCode);
colorCode = "x";
} else
colorCode += args; // a color by itself
} else {
waiting = false;
if(!colorCode.isEmpty()) {
if(isHex && colorCode.length() >= 7)
color = ColorManager.getColor(colorCode);
else if(colorCode.length() == 1) // if only one color code
if(colorCode.startsWith("x") && colorCode.length() >= 7) {
if(colorCode.length() == 7)
color = ColorManager.getColor(colorCode);
else {
color = ColorManager.getColor(colorCode.substring(0, 7)); // only the hex code
ChatItem.debug("Adding color for " + colorCode.substring(7, colorCode.length()) + " (in " + colorCode + ")");
text += ColorManager.getColorString(colorCode.substring(7, colorCode.length()));
}
} else if(colorCode.length() == 1) // if only one color code
color = ColorManager.getColor(colorCode);
else
text += ColorManager.getColorString(colorCode);
@@ -20,10 +20,10 @@ import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.hover.content.Text;
public class ChatItemCommand implements CommandExecutor, TabExecutor {
@SuppressWarnings("deprecation")
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (!(sender instanceof Player)) {
@@ -47,7 +47,7 @@ public class ChatItemCommand implements CommandExecutor, TabExecutor {
String hover = Storage.color(linkConfig.getString("hover"));
if (hover != null)
linkComp.setHoverEvent(
new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(hover).create()));
new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(new ComponentBuilder(hover).create())));
String link = linkConfig.getString("link");
if (link != null)
linkComp.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, link));
@@ -12,10 +12,10 @@ import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.hover.content.Text;
public class JoinListener implements Listener {
@SuppressWarnings("deprecation")
@EventHandler
public void onJoin(PlayerJoinEvent e) {
Player p = e.getPlayer();
@@ -24,7 +24,7 @@ public class JoinListener implements Listener {
ChatItem pl = ChatItem.getInstance();
if(pl.isHasNewVersion()) {
TextComponent text = new TextComponent(pl.getStorage().JOIN_UPDATE_MESSAGE);
text.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(pl.getStorage().JOIN_UPDATE_HOVER).create()));
text.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(new ComponentBuilder(pl.getStorage().JOIN_UPDATE_HOVER).create())));
text.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://www.spigotmc.org/resources/19064/"));
p.spigot().sendMessage(text);
}
@@ -84,7 +84,7 @@ public class ReflectionUtils {
}
/**
* Get the first field which have the searching for class type
* Get the first object which have the searching for class type
*
* @param from the object where we will try to find the field
* @param clazz the class that have to define the field
@@ -102,4 +102,23 @@ public class ReflectionUtils {
}
return null;
}
/**
* Get the first field which have the searching for class type
*
* @param from the object where we will try to find the field
* @param clazz the class that have to define the field
* @param searchingFor the class of the required field
* @return the field (or null if not found)
* @throws Exception if something gone wrong
*/
public static Field getFirstFieldWith(Class<?> clazz, Class<?> searchingFor) throws Exception {
for (Field f : clazz.getDeclaredFields()) {
if (f.getType().equals(searchingFor) && !Modifier.isStatic(f.getModifiers())) {
f.setAccessible(true);
return f;
}
}
return null;
}
}
@@ -138,4 +138,40 @@ public class Utils {
}
return b;
}
public static boolean isInteger(String s) {
try {
Integer.parseInt(s);
return true;
} catch (Exception e) {
return false;
}
}
public static boolean isByte(String s) {
try {
Byte.parseByte(s);
return true;
} catch (Exception e) {
return false;
}
}
public static boolean isShort(String s) {
try {
Short.parseShort(s);
return true;
} catch (Exception e) {
return false;
}
}
public static boolean isLong(String s) {
try {
Long.parseLong(s);
return true;
} catch (Exception e) {
return false;
}
}
}