Created
February 4, 2020 00:39
-
-
Save Goblom/ab204d3474823a0d51517809c3454912 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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