Add fading 1.11 titles

This commit is contained in:
Jesse Boyd 2016-11-30 16:28:50 +11:00
parent 81418b07a8
commit dea0a452df
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
5 changed files with 564 additions and 45 deletions

View File

@ -16,21 +16,7 @@ import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RunnableVal;
import com.intellectualcrafters.plot.object.SetupObject;
import com.intellectualcrafters.plot.object.chat.PlainChatManager;
import com.intellectualcrafters.plot.util.AbstractTitle;
import com.intellectualcrafters.plot.util.ChatManager;
import com.intellectualcrafters.plot.util.ChunkManager;
import com.intellectualcrafters.plot.util.ConsoleColors;
import com.intellectualcrafters.plot.util.EconHandler;
import com.intellectualcrafters.plot.util.EventUtil;
import com.intellectualcrafters.plot.util.InventoryUtil;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.SchematicHandler;
import com.intellectualcrafters.plot.util.SetupUtils;
import com.intellectualcrafters.plot.util.StringMan;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.intellectualcrafters.plot.util.UUIDHandlerImplementation;
import com.intellectualcrafters.plot.util.WorldUtil;
import com.intellectualcrafters.plot.util.*;
import com.intellectualcrafters.plot.util.block.QueueProvider;
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
import com.plotsquared.bukkit.database.plotme.ClassicPlotMeConnector;
@ -45,22 +31,8 @@ import com.plotsquared.bukkit.listeners.PlayerEvents_1_8;
import com.plotsquared.bukkit.listeners.PlayerEvents_1_9;
import com.plotsquared.bukkit.listeners.PlotPlusListener;
import com.plotsquared.bukkit.listeners.WorldEvents;
import com.plotsquared.bukkit.titles.DefaultTitle_19;
import com.plotsquared.bukkit.util.BukkitChatManager;
import com.plotsquared.bukkit.util.BukkitChunkManager;
import com.plotsquared.bukkit.util.BukkitCommand;
import com.plotsquared.bukkit.util.BukkitEconHandler;
import com.plotsquared.bukkit.util.BukkitEventUtil;
import com.plotsquared.bukkit.util.BukkitHybridUtils;
import com.plotsquared.bukkit.util.BukkitInventoryUtil;
import com.plotsquared.bukkit.util.BukkitSchematicHandler;
import com.plotsquared.bukkit.util.BukkitSetupUtils;
import com.plotsquared.bukkit.util.BukkitTaskManager;
import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.bukkit.util.BukkitVersion;
import com.plotsquared.bukkit.util.Metrics;
import com.plotsquared.bukkit.util.SendChunk;
import com.plotsquared.bukkit.util.SetGenCB;
import com.plotsquared.bukkit.titles.DefaultTitle_111;
import com.plotsquared.bukkit.util.*;
import com.plotsquared.bukkit.util.block.BukkitLocalQueue;
import com.plotsquared.bukkit.util.block.BukkitLocalQueue_1_7;
import com.plotsquared.bukkit.util.block.BukkitLocalQueue_1_8;
@ -72,6 +44,15 @@ import com.plotsquared.bukkit.uuid.LowerOfflineUUIDWrapper;
import com.plotsquared.bukkit.uuid.OfflineUUIDWrapper;
import com.plotsquared.bukkit.uuid.SQLUUIDHandler;
import com.sk89q.worldedit.WorldEdit;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
@ -88,16 +69,6 @@ import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain {
private static ConcurrentHashMap<String, Plugin> pluginMap;
@ -604,7 +575,7 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
PS.log(C.PREFIX + " &c[WARN] Titles are disabled - please update your version of Bukkit to support this feature.");
Settings.TITLES = false;
} else {
AbstractTitle.TITLE_CLASS = new DefaultTitle_19();
AbstractTitle.TITLE_CLASS = new DefaultTitle_111();
if (wrapper instanceof DefaultUUIDWrapper || wrapper.getClass() == OfflineUUIDWrapper.class && !Bukkit.getOnlineMode()) {
Settings.UUID.NATIVE_UUID_PROVIDER = true;
}

View File

@ -4,7 +4,7 @@ import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.AbstractTitle;
import com.plotsquared.bukkit.object.BukkitPlayer;
public class DefaultTitle extends AbstractTitle {
public class DefaultTitle_110 extends AbstractTitle {
@Override
public void sendTitle(PlotPlayer player, String head, String sub, int in, int delay, int out) {
@ -12,7 +12,7 @@ public class DefaultTitle extends AbstractTitle {
DefaultTitleManager title = new DefaultTitleManager(head, sub, in, delay, out);
title.send(((BukkitPlayer) player).player);
} catch (Exception ignored) {
AbstractTitle.TITLE_CLASS = new DefaultTitle_183();
AbstractTitle.TITLE_CLASS = new DefaultTitle_19();
AbstractTitle.TITLE_CLASS.sendTitle(player, head, sub, in, delay, out);
}
}

View File

@ -0,0 +1,22 @@
package com.plotsquared.bukkit.titles;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.AbstractTitle;
import com.plotsquared.bukkit.object.BukkitPlayer;
import org.bukkit.entity.Player;
@SuppressWarnings("deprecation")
public class DefaultTitle_111 extends AbstractTitle {
@Override
public void sendTitle(PlotPlayer player, String head, String sub, int in, int delay, int out) {
try {
final Player playerObj = ((BukkitPlayer) player).player;
TitleManager_1_11 title = new TitleManager_1_11(head, sub, in, delay, out);
title.send(playerObj);
} catch (Throwable ignored) {
AbstractTitle.TITLE_CLASS = new DefaultTitle_110();
AbstractTitle.TITLE_CLASS.sendTitle(player, head, sub, in, delay, out);
}
}
}

View File

@ -21,7 +21,7 @@ public class DefaultTitle_19 extends AbstractTitle {
}
}, delay * 20);
} catch (Throwable ignored) {
AbstractTitle.TITLE_CLASS = new DefaultTitle();
AbstractTitle.TITLE_CLASS = new DefaultTitle_183();
AbstractTitle.TITLE_CLASS.sendTitle(player, head, sub, in, delay, out);
}
}

View File

@ -0,0 +1,526 @@
package com.plotsquared.bukkit.titles;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
/**
* Minecraft 1.8 Title
* For 1.11
*
* @author Maxim Van de Wynckel
* @version 1.1.0
*/
public class TitleManager_1_11 {
/* Title packet */
private static Class<?> packetTitle;
/* Title packet actions ENUM */
private static Class<?> packetActions;
/* Chat serializer */
private static Class<?> nmsChatSerializer;
private static Class<?> chatBaseComponent;
/* NMS player and connection */
private static Class<?> nmsPlayer;
private static Class<?> nmsPlayerConnection;
private static Field playerConnection;
private static Method sendPacket;
private static Class<?> obcPlayer;
private static Method methodPlayerGetHandle;
/* Title text and color */
private String title = "";
private ChatColor titleColor = ChatColor.WHITE;
/* Subtitle text and color */
private String subtitle = "";
private ChatColor subtitleColor = ChatColor.WHITE;
/* Title timings */
private int fadeInTime = -1;
private int stayTime = -1;
private int fadeOutTime = -1;
private boolean ticks = false;
private static final Map<Class<?>, Class<?>> CORRESPONDING_TYPES = new HashMap<Class<?>, Class<?>>();
public TitleManager_1_11() {
loadClasses();
}
/**
* Create a new 1.8 title
*
* @param title Title
*/
public TitleManager_1_11(String title) {
this.title = title;
loadClasses();
}
/**
* Create a new 1.8 title
*
* @param title Title text
* @param subtitle Subtitle text
*/
public TitleManager_1_11(String title, String subtitle) {
this.title = title;
this.subtitle = subtitle;
loadClasses();
}
/**
* Copy 1.8 title
*
* @param title Title
*/
public TitleManager_1_11(TitleManager_1_11 title) {
// Copy title
this.title = title.getTitle();
this.subtitle = title.getSubtitle();
this.titleColor = title.getTitleColor();
this.subtitleColor = title.getSubtitleColor();
this.fadeInTime = title.getFadeInTime();
this.fadeOutTime = title.getFadeOutTime();
this.stayTime = title.getStayTime();
this.ticks = title.isTicks();
loadClasses();
}
/**
* 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
*/
public TitleManager_1_11(String title, String subtitle, int fadeInTime, int stayTime, int fadeOutTime) {
this.title = title;
this.subtitle = subtitle;
this.fadeInTime = fadeInTime;
this.stayTime = stayTime;
this.fadeOutTime = fadeOutTime;
loadClasses();
}
/**
* Load spigot and NMS classes
*/
private void loadClasses() {
if (packetTitle == null) {
packetTitle = getNMSClass("PacketPlayOutTitle");
packetActions = getNMSClass("PacketPlayOutTitle$EnumTitleAction");
chatBaseComponent = getNMSClass("IChatBaseComponent");
nmsChatSerializer = getNMSClass("ChatComponentText");
nmsPlayer = getNMSClass("EntityPlayer");
nmsPlayerConnection = getNMSClass("PlayerConnection");
playerConnection = getField(nmsPlayer,
"playerConnection");
sendPacket = getMethod(nmsPlayerConnection, "sendPacket");
obcPlayer = getOBCClass("entity.CraftPlayer");
methodPlayerGetHandle = getMethod("getHandle", obcPlayer);
}
}
/**
* Set title text
*
* @param title Title
*/
public void setTitle(String title) {
this.title = title;
}
/**
* Get title text
*
* @return Title text
*/
public String getTitle() {
return this.title;
}
/**
* Set subtitle text
*
* @param subtitle Subtitle text
*/
public void setSubtitle(String subtitle) {
this.subtitle = subtitle;
}
/**
* Get subtitle text
*
* @return Subtitle text
*/
public String getSubtitle() {
return this.subtitle;
}
/**
* Set the title color
*
* @param color Chat color
*/
public void setTitleColor(ChatColor color) {
this.titleColor = color;
}
/**
* Set the subtitle color
*
* @param color Chat color
*/
public void setSubtitleColor(ChatColor color) {
this.subtitleColor = color;
}
/**
* Set title fade in time
*
* @param time Time
*/
public void setFadeInTime(int time) {
this.fadeInTime = time;
}
/**
* Set title fade out time
*
* @param time Time
*/
public void setFadeOutTime(int time) {
this.fadeOutTime = time;
}
/**
* Set title stay time
*
* @param time Time
*/
public void setStayTime(int time) {
this.stayTime = time;
}
/**
* Set timings to ticks
*/
public void setTimingsToTicks() {
ticks = true;
}
/**
* Set timings to seconds
*/
public void setTimingsToSeconds() {
ticks = false;
}
/**
* Send the title to a player
*
* @param player Player
*/
public void send(Player player) {
if (packetTitle != null) {
// First reset previous settings
resetTitle(player);
try {
// Send timings first
Object handle = getHandle(player);
Object connection = playerConnection.get(handle);
Object[] actions = packetActions.getEnumConstants();
Object packet = packetTitle.getConstructor(packetActions,
chatBaseComponent, Integer.TYPE, Integer.TYPE,
Integer.TYPE).newInstance(actions[3], null,
fadeInTime * (ticks ? 1 : 20),
stayTime * (ticks ? 1 : 20),
fadeOutTime * (ticks ? 1 : 20));
// Send if set
if (fadeInTime != -1 && fadeOutTime != -1 && stayTime != -1)
sendPacket.invoke(connection, packet);
Object serialized;
if (!subtitle.equals("")) {
// Send subtitle if present
serialized = nmsChatSerializer.getConstructor(String.class)
.newInstance(subtitleColor +
ChatColor.translateAlternateColorCodes('&',
subtitle));
packet = packetTitle.getConstructor(packetActions,
chatBaseComponent).newInstance(actions[1],
serialized);
sendPacket.invoke(connection, packet);
}
// Send title
serialized = nmsChatSerializer.getConstructor(
String.class).newInstance(titleColor +
ChatColor.translateAlternateColorCodes('&', title));
packet = packetTitle.getConstructor(packetActions,
chatBaseComponent).newInstance(actions[0], serialized);
sendPacket.invoke(connection, packet);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void updateTimes(Player player) {
if (TitleManager_1_11.packetTitle != null) {
try {
Object handle = getHandle(player);
Object connection = playerConnection.get(handle);
Object[] actions = TitleManager_1_11.packetActions.getEnumConstants();
Object packet = TitleManager_1_11.packetTitle.getConstructor(
new Class[]{TitleManager_1_11.packetActions, chatBaseComponent,
Integer.TYPE, Integer.TYPE, Integer.TYPE})
.newInstance(
actions[3],
null,
this.fadeInTime
* (this.ticks ? 1 : 20),
this.stayTime
* (this.ticks ? 1 : 20),
this.fadeOutTime
* (this.ticks ? 1 : 20));
if ((this.fadeInTime != -1) && (this.fadeOutTime != -1)
&& (this.stayTime != -1)) {
sendPacket.invoke(connection, packet);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void updateTitle(Player player) {
if (TitleManager_1_11.packetTitle != null) {
try {
Object handle = getHandle(player);
Object connection = getField(handle.getClass(),
"playerConnection").get(handle);
Object[] actions = TitleManager_1_11.packetActions.getEnumConstants();
Method sendPacket = getMethod(connection.getClass(),
"sendPacket");
Object serialized = nmsChatSerializer.getConstructor(
String.class)
.newInstance(titleColor +
ChatColor.translateAlternateColorCodes('&',
this.title));
Object packet = TitleManager_1_11.packetTitle
.getConstructor(
new Class[]{TitleManager_1_11.packetActions,
chatBaseComponent}).newInstance(
actions[0], serialized);
sendPacket.invoke(connection, packet);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void updateSubtitle(Player player) {
if (TitleManager_1_11.packetTitle != null) {
try {
Object handle = getHandle(player);
Object connection = playerConnection.get(handle);
Object[] actions = TitleManager_1_11.packetActions.getEnumConstants();
Object serialized = nmsChatSerializer.getConstructor(
String.class)
.newInstance(subtitleColor +
ChatColor.translateAlternateColorCodes('&',
this.subtitle));
Object packet = TitleManager_1_11.packetTitle
.getConstructor(
new Class[]{TitleManager_1_11.packetActions,
chatBaseComponent}).newInstance(
actions[1], serialized);
sendPacket.invoke(connection, packet);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* Broadcast the title to all players
*/
public void broadcast() {
for (Player p : Bukkit.getOnlinePlayers()) {
send(p);
}
}
/**
* Clear the title
*
* @param player Player
*/
public void clearTitle(Player player) {
try {
// Send timings first
Object handle = getHandle(player);
Object connection = playerConnection.get(handle);
Object[] actions = packetActions.getEnumConstants();
Object packet = packetTitle.getConstructor(packetActions,
chatBaseComponent).newInstance(actions[4], null);
sendPacket.invoke(connection, packet);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Reset the title settings
*
* @param player Player
*/
public void resetTitle(Player player) {
try {
// Send timings first
Object handle = getHandle(player);
Object connection = playerConnection.get(handle);
Object[] actions = packetActions.getEnumConstants();
Object packet = packetTitle.getConstructor(packetActions,
chatBaseComponent).newInstance(actions[5], null);
sendPacket.invoke(connection, packet);
} catch (Exception e) {
e.printStackTrace();
}
}
private Class<?> getPrimitiveType(Class<?> clazz) {
return CORRESPONDING_TYPES.containsKey(clazz) ? CORRESPONDING_TYPES
.get(clazz) : clazz;
}
private Class<?>[] toPrimitiveTypeArray(Class<?>[] classes) {
int a = classes != null ? classes.length : 0;
Class<?>[] types = new Class<?>[a];
for (int i = 0; i < a; i++)
types[i] = getPrimitiveType(classes[i]);
return types;
}
private static boolean equalsTypeArray(Class<?>[] a, Class<?>[] o) {
if (a.length != o.length)
return false;
for (int i = 0; i < a.length; i++)
if (!a[i].equals(o[i]) && !a[i].isAssignableFrom(o[i]))
return false;
return true;
}
private Object getHandle(Player player) {
try {
return methodPlayerGetHandle.invoke(player);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private Method getMethod(String name, Class<?> clazz,
Class<?>... paramTypes) {
Class<?>[] t = toPrimitiveTypeArray(paramTypes);
for (Method m : clazz.getMethods()) {
Class<?>[] types = toPrimitiveTypeArray(m.getParameterTypes());
if (m.getName().equals(name) && equalsTypeArray(types, t))
return m;
}
return null;
}
private String getVersion() {
String name = Bukkit.getServer().getClass().getPackage().getName();
String version = name.substring(name.lastIndexOf('.') + 1) + ".";
return version;
}
private Class<?> getNMSClass(String className) {
String fullName = "net.minecraft.server." + getVersion() + className;
Class<?> clazz = null;
try {
clazz = Class.forName(fullName);
} catch (Exception e) {
e.printStackTrace();
}
return clazz;
}
private Class<?> getOBCClass(String className) {
String fullName = "org.bukkit.craftbukkit." + getVersion() + className;
Class<?> clazz = null;
try {
clazz = Class.forName(fullName);
} catch (Exception e) {
e.printStackTrace();
}
return clazz;
}
private Field getField(Class<?> clazz, String name) {
try {
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
return field;
} catch (Exception 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;
}
private boolean ClassListEqual(Class<?>[] l1, Class<?>[] l2) {
boolean equal = true;
if (l1.length != l2.length)
return false;
for (int i = 0; i < l1.length; i++)
if (l1[i] != l2[i]) {
equal = false;
break;
}
return equal;
}
public ChatColor getTitleColor() {
return titleColor;
}
public ChatColor getSubtitleColor() {
return subtitleColor;
}
public int getFadeInTime() {
return fadeInTime;
}
public int getFadeOutTime() {
return fadeOutTime;
}
public int getStayTime() {
return stayTime;
}
public boolean isTicks() {
return ticks;
}
}