mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2025-07-06 23:54:43 +02:00

Updated gradle wrapper to 3.0 Updated Gradle files for Nukkit Added/cleaned minor Nukkit code Removed duplicate TitleManagement code Signed-off-by: MattBDev <mattbdev@outlook.com>
166 lines
6.9 KiB
Java
166 lines
6.9 KiB
Java
package com.plotsquared.bukkit.titles;
|
|
|
|
import com.plotsquared.bukkit.chat.Reflection;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.ChatColor;
|
|
import org.bukkit.entity.Player;
|
|
|
|
import java.lang.reflect.Field;
|
|
import java.lang.reflect.Method;
|
|
|
|
public class HackTitleManager extends TitleManager {
|
|
|
|
/**
|
|
* Create a new 1.8 title.
|
|
*
|
|
* @param title Title text
|
|
* @param subtitle Subtitle text
|
|
* @param fadeInTime Fade in time
|
|
* @param stayTime Stay on screen time
|
|
* @param fadeOutTime Fade out time
|
|
*/
|
|
HackTitleManager(String title, String subtitle, int fadeInTime, int stayTime, int fadeOutTime) {
|
|
super(title, subtitle, fadeInTime, stayTime, fadeOutTime);
|
|
}
|
|
|
|
/**
|
|
* Load spigot and NMS classes.
|
|
*/
|
|
@Override
|
|
void loadClasses() {
|
|
this.packetTitle = getClass("org.spigotmc.ProtocolInjector$PacketTitle");
|
|
this.packetActions = getClass("org.spigotmc.ProtocolInjector$PacketTitle$Action");
|
|
this.nmsChatSerializer = Reflection.getNMSClass("ChatSerializer");
|
|
}
|
|
|
|
@Override public void send(Player player) throws IllegalArgumentException, ReflectiveOperationException, SecurityException {
|
|
if ((getProtocolVersion(player) >= 47) && isSpigot() && (this.packetTitle != null)) {
|
|
// First reset previous settings
|
|
resetTitle(player);
|
|
// Send timings first
|
|
Object handle = getHandle(player);
|
|
Object connection = getField(handle.getClass(), "playerConnection").get(handle);
|
|
Object[] actions = this.packetActions.getEnumConstants();
|
|
Method sendPacket = getMethod(connection.getClass(), "sendPacket");
|
|
Object packet = this.packetTitle.getConstructor(this.packetActions, Integer.TYPE, Integer.TYPE, Integer.TYPE).newInstance(actions[2],
|
|
this.fadeInTime * (this.ticks ? 1 : 20),
|
|
this.stayTime * (this.ticks ? 1 : 20),
|
|
this.fadeOutTime * (this.ticks ? 1 : 20));
|
|
// Send if set
|
|
if ((this.fadeInTime != -1) && (this.fadeOutTime != -1) && (this.stayTime != -1)) {
|
|
sendPacket.invoke(connection, packet);
|
|
}
|
|
// Send title
|
|
Object serialized = getMethod(this.nmsChatSerializer, "a", String.class).invoke(null,
|
|
"{text:\"" + ChatColor.translateAlternateColorCodes('&', this.getTitle()) + "\",color:" + this.titleColor.name().toLowerCase()
|
|
+ "}");
|
|
packet = this.packetTitle.getConstructor(this.packetActions, Reflection.getNMSClass("IChatBaseComponent"))
|
|
.newInstance(actions[0], serialized);
|
|
sendPacket.invoke(connection, packet);
|
|
if (!this.getSubtitle().isEmpty()) {
|
|
// Send subtitle if present
|
|
serialized = getMethod(this.nmsChatSerializer, "a", String.class).invoke(null,
|
|
"{text:\"" + ChatColor.translateAlternateColorCodes('&', this.getSubtitle()) + "\",color:" + this.subtitleColor.name()
|
|
.toLowerCase() + "}");
|
|
packet = this.packetTitle.getConstructor(this.packetActions, Reflection.getNMSClass("IChatBaseComponent"))
|
|
.newInstance(actions[1], serialized);
|
|
sendPacket.invoke(connection, packet);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override public void clearTitle(Player player) throws IllegalArgumentException, ReflectiveOperationException, SecurityException {
|
|
if ((getProtocolVersion(player) >= 47) && isSpigot()) {
|
|
// Send timings first
|
|
Object handle = getHandle(player);
|
|
Object connection = getField(handle.getClass(), "playerConnection").get(handle);
|
|
Object[] actions = this.packetActions.getEnumConstants();
|
|
Method sendPacket = getMethod(connection.getClass(), "sendPacket");
|
|
Object packet = this.packetTitle.getConstructor(this.packetActions).newInstance(actions[3]);
|
|
sendPacket.invoke(connection, packet);
|
|
}
|
|
}
|
|
|
|
@Override public void resetTitle(Player player) throws IllegalArgumentException, ReflectiveOperationException, SecurityException {
|
|
if ((getProtocolVersion(player) >= 47) && isSpigot()) {
|
|
// Send timings first
|
|
Object handle = getHandle(player);
|
|
Object connection = getField(handle.getClass(), "playerConnection").get(handle);
|
|
Object[] actions = this.packetActions.getEnumConstants();
|
|
Method sendPacket = getMethod(connection.getClass(), "sendPacket");
|
|
Object packet = this.packetTitle.getConstructor(this.packetActions).newInstance(actions[4]);
|
|
sendPacket.invoke(connection, packet);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the protocol version of the player.
|
|
*
|
|
* @param player Player
|
|
* @return Protocol version
|
|
* @throws IllegalArgumentException
|
|
* @throws ReflectiveOperationException
|
|
* @throws SecurityException
|
|
*/
|
|
private int getProtocolVersion(Player player) throws IllegalArgumentException, ReflectiveOperationException, SecurityException {
|
|
Object handle = getHandle(player);
|
|
Object connection = getField(handle.getClass(), "playerConnection").get(handle);
|
|
Object networkManager = getValue("networkManager", connection);
|
|
return (Integer) getMethod("getVersion", networkManager.getClass()).invoke(networkManager);
|
|
}
|
|
|
|
/**
|
|
* Check if running spigot.
|
|
*
|
|
* @return Spigot
|
|
*/
|
|
private boolean isSpigot() {
|
|
return Bukkit.getVersion().contains("Spigot");
|
|
}
|
|
|
|
/**
|
|
* Get class by url.
|
|
*
|
|
* @param namespace Namespace url
|
|
* @return Class
|
|
*/
|
|
private Class<?> getClass(String namespace) {
|
|
try {
|
|
return Class.forName(namespace);
|
|
} catch (ClassNotFoundException ignored) {}
|
|
return null;
|
|
}
|
|
|
|
private Field getField(String name, Class<?> clazz) throws NoSuchFieldException, SecurityException {
|
|
return clazz.getDeclaredField(name);
|
|
}
|
|
|
|
private Object getValue(String name, Object obj) throws ReflectiveOperationException, SecurityException, IllegalArgumentException {
|
|
Field f = getField(name, obj.getClass());
|
|
f.setAccessible(true);
|
|
return f.get(obj);
|
|
}
|
|
|
|
private Field getField(Class<?> clazz, String name) {
|
|
try {
|
|
Field field = clazz.getDeclaredField(name);
|
|
field.setAccessible(true);
|
|
return field;
|
|
} catch (SecurityException | NoSuchFieldException e) {
|
|
e.printStackTrace();
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private Method getMethod(Class<?> clazz, String name, Class<?>... args) {
|
|
for (Method m : clazz.getMethods()) {
|
|
if (m.getName().equals(name) && ((args.length == 0) || classListEqual(args, m.getParameterTypes()))) {
|
|
m.setAccessible(true);
|
|
return m;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
}
|