Skip to content

Instantly share code, notes, and snippets.

@Goblom
Created February 4, 2020 00:39
Show Gist options
  • Save Goblom/ab204d3474823a0d51517809c3454912 to your computer and use it in GitHub Desktop.
Save Goblom/ab204d3474823a0d51517809c3454912 to your computer and use it in GitHub Desktop.
/*
* Copyright (C) 2020 Bryan Larson.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package codes.goblom.minecraft.chat;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.logging.Logger;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
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;
/**
*
* @author Bryan Larson
*/
public class ChatUtils {
private static final String[] SUPPORTED_SENDERS = {
"net.md_5.bungee.api.CommandSender",
"org.bukkit.command.CommandSender"
};
private static final String SEND_MESSAGE_METHOD_NAME = "sendMessage";
private static Method sendMessages, sendMessage;
private static Method spigot;
private static boolean onlyString = false;
private static Logger pluginLogger;
public static void hook() {
hook(null);
}
public static void hook(Logger logger) {
Class clazz = null;
for (String str : SUPPORTED_SENDERS) {
if (clazz != null) break;
try {
clazz = Class.forName(str);
} catch (Exception e) { }
}
if (clazz == null) {
throw new RuntimeException("ChatUtils not hooked. Unable to find a CommandSender class. Are you running on BungeeCord or Bukkit?");
} else {
hook(logger, clazz);
}
}
public static void hook(Logger log, Class sender) {
if (isHooked()) {
return;
}
pluginLogger = log == null ? Logger.getLogger(ChatUtils.class.getName()) : log;
boolean found = false;
// Try - BungeeCord
try {
sendMessages = sender.getMethod(SEND_MESSAGE_METHOD_NAME, BaseComponent[].class);
sendMessage = sender.getMethod(SEND_MESSAGE_METHOD_NAME, BaseComponent.class);
sendMessages.setAccessible(true);
sendMessage.setAccessible(true);
found = true;
} catch (Exception e) {
log(e);
}
if (!found) {
//Try - Spigot
try {
Class spigotClass = null;
for (Class clazzes : sender.getClasses()) {
if (clazzes.getName().contains("Spigot")) {
spigotClass = clazzes;
break;
}
}
spigot = sender.getMethod("spigot");
spigot.setAccessible(true);
sendMessages = spigotClass.getMethod(SEND_MESSAGE_METHOD_NAME, BaseComponent[].class);
sendMessage = spigotClass.getMethod(SEND_MESSAGE_METHOD_NAME, BaseComponent.class);
sendMessages.setAccessible(true);
sendMessage.setAccessible(true);
found = true;
} catch (Exception e) {
log(e);
}
}
if (!found) {
//Try - Bukkit
try {
sendMessages = sender.getMethod(SEND_MESSAGE_METHOD_NAME, String[].class);
sendMessage = sender.getMethod(SEND_MESSAGE_METHOD_NAME, String.class);
sendMessages.setAccessible(true);
sendMessage.setAccessible(true);
onlyString = true;
found = true;
} catch (Exception e) {
log(e);
}
}
if (!found) {
throw new RuntimeException("There was an error hooking ChatUtils... Using System.out.println... Because there was an error.");
} else {
log("Successfully Hooked ChatUtils with " + sender);
}
}
public static boolean isHooked() {
return sendMessages != null && sendMessage != null;
}
private static void log(Object message) {
pluginLogger.info(message.toString());
if (message instanceof Throwable) {
((Throwable) message).printStackTrace();
}
}
private static void invoke(Object instance, BaseComponent... components) {
if (!isHooked()) {
System.out.println("ChatUtils not Hooked... Printing.");
System.out.println(BaseComponent.toLegacyText(components));
return;
}
try {
if (spigot != null) {
instance = spigot.invoke(instance);
}
String[] array = new String[components.length];
for (int i = 0; i < components.length; i++) {
array[i] = BaseComponent.toLegacyText(components[i]);
}
sendMessages.invoke(instance, new Object[] { onlyString ? array : components } );
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
log(ex);
}
}
private static void invoke(Object instance, BaseComponent component) {
Object toSend = onlyString ? BaseComponent.toLegacyText(component) : component;
if (!isHooked()) {
System.out.println("ChatUtils not Hooked... Printing.");
System.out.println(toSend);
return;
}
try {
if (spigot != null) {
instance = spigot.invoke(instance);
}
sendMessage.invoke(instance, new Object[] { component } );
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
log(ex);
}
}
public static void sendMessage(Object sender, String message, ChatColor color) {
TextComponent comp = new TextComponent(message);
comp.setColor(color);
sendMessage(sender, comp);
}
public static void sendMessage(Object sender, String message) {
sendMessage(sender, TextComponent.fromLegacyText(message));
}
public static void sendMessage(Object sender, BaseComponent... components) {
ComponentBuilder chatBuilder = null;
if (sender.getClass().isArray()) {
String one = ((Object[]) sender)[0].toString();// Args...
Object two = ((Object[]) sender)[1]; // This should always be a instanceof CommandSender.
for (String str : one.split(",")) {
if (str.equalsIgnoreCase("No Prefix")) {
chatBuilder = new ComponentBuilder("");
}
}
sender = two;
}
if (chatBuilder == null) {
HoverEvent hover = new HoverEvent(
HoverEvent.Action.SHOW_TEXT,
new ComponentBuilder("Minecraft Auto Deploy Systems\n\n")
.append("Twitter: @DevGoblom")
.create()
);
chatBuilder = new ComponentBuilder("[")
.color(ChatColor.AQUA)
.append("MADS").event(hover).event(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://twitter.com/DevGoblom"))
.color(ChatColor.GRAY).append("] ").color(ChatColor.AQUA);
}
chatBuilder.append("").reset().append(components);
// sender.sendMessage(prefix.create());
invoke(sender, chatBuilder.create());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment