diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotMain.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotMain.java index b2f84b171..5cc8d86ee 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotMain.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotMain.java @@ -95,6 +95,8 @@ import com.intellectualcrafters.plot.object.PlotGenerator; import com.intellectualcrafters.plot.object.PlotId; import com.intellectualcrafters.plot.object.PlotManager; import com.intellectualcrafters.plot.object.PlotWorld; +import com.intellectualcrafters.plot.titles.AbstractTitle; +import com.intellectualcrafters.plot.titles.DefaultTitle; import com.intellectualcrafters.plot.util.ConsoleColors; import com.intellectualcrafters.plot.util.ExpireManager; import com.intellectualcrafters.plot.util.Lag; @@ -117,7 +119,7 @@ import com.sk89q.worldguard.bukkit.WorldGuardPlugin; * @author Citymonstret * @author Empire92 */ -@SuppressWarnings("unused") public class PlotMain extends JavaPlugin implements Listener { +public class PlotMain extends JavaPlugin implements Listener { /** * Permission that allows for "everything" */ @@ -1528,11 +1530,14 @@ import com.sk89q.worldguard.bukkit.WorldGuardPlugin; // Handle UUIDS { boolean checkVersion = checkVersion(); - if (!checkVersion && Settings.TITLES) { - sendConsoleSenderMessage(C.PREFIX.s()+" &c[WARN] Titles are enabled - please update your version of Bukkit to support this feature."); + if (!checkVersion) { + sendConsoleSenderMessage(C.PREFIX.s()+" &c[WARN] Titles are disabled - please update your version of Bukkit to support this feature."); Settings.TITLES = false; FlagManager.removeFlag(FlagManager.getFlag("titles")); } + else { + AbstractTitle.TITLE_CLASS = new DefaultTitle(); + } if (Settings.OFFLINE_MODE) { UUIDHandler.uuidWrapper = new OfflineUUIDWrapper(); Settings.OFFLINE_MODE = true; diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Delete.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Delete.java index 978b36a31..e6d41006a 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Delete.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Delete.java @@ -65,9 +65,6 @@ public class Delete extends SubCommand { if (result) { plot.clear(plr, true); DBFunc.delete(plr.getWorld().getName(), plot); - if ((Math.abs(plot.id.x) <= Math.abs(Auto.lastPlot.x)) && (Math.abs(plot.id.y) <= Math.abs(Auto.lastPlot.y))) { - Auto.lastPlot = plot.id; - } } else { PlayerFunctions.sendMessage(plr, "Plot deletion has been denied."); } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Unclaim.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Unclaim.java index 594623225..918a4b78a 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Unclaim.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Unclaim.java @@ -64,9 +64,6 @@ public class Unclaim extends SubCommand { final boolean result = PlotMain.removePlot(plr.getWorld().getName(), plot.id, true); if (result) { DBFunc.delete(plr.getWorld().getName(), plot); - if ((Math.abs(plot.id.x) <= Math.abs(Auto.lastPlot.x)) && (Math.abs(plot.id.y) <= Math.abs(Auto.lastPlot.y))) { - Auto.lastPlot = plot.id; - } } else { PlayerFunctions.sendMessage(plr, "Plot removal has been denied."); } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/flag/FlagManager.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/flag/FlagManager.java index 4400e99cd..d54e1443a 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/flag/FlagManager.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/flag/FlagManager.java @@ -188,12 +188,6 @@ import com.intellectualcrafters.plot.object.PlotWorld; return newflags; } - // FIXME get resultant flags for a plot (with DB change) - - // remove a flag - - // add a flag - /** * Get a list of registered AbstractFlag objects * diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/ForceFieldListener.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/ForceFieldListener.java index 4ee7103d8..8be57a19e 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/ForceFieldListener.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/ForceFieldListener.java @@ -97,7 +97,6 @@ public class ForceFieldListener implements Listener { } @EventHandler - @SuppressWarnings("unused") public void onPlotEntry(final PlayerMoveEvent event) { final Player player = event.getPlayer(); if (!PlayerFunctions.isInPlot(player)) { diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlotListener.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlotListener.java index b68ec0ac3..7b866b2ab 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlotListener.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlotListener.java @@ -46,7 +46,7 @@ import com.intellectualcrafters.plot.object.Plot; import com.intellectualcrafters.plot.object.PlotId; import com.intellectualcrafters.plot.object.PlotManager; import com.intellectualcrafters.plot.object.PlotWorld; -import com.intellectualcrafters.plot.object.Title; +import com.intellectualcrafters.plot.titles.AbstractTitle; import com.intellectualcrafters.plot.util.PlayerFunctions; import com.intellectualcrafters.plot.util.UUIDHandler; @@ -207,11 +207,9 @@ import com.intellectualcrafters.plot.util.UUIDHandler; final String sTitleSub = C.TITLE_ENTERED_PLOT_SUB.s().replaceFirst("%s", getName(plot.owner)); final ChatColor sTitleMainColor = ChatColor.valueOf(C.TITLE_ENTERED_PLOT_COLOR.s()); final ChatColor sTitleSubColor = ChatColor.valueOf(C.TITLE_ENTERED_PLOT_SUB_COLOR.s()); - final Title title = new Title(sTitleMain, sTitleSub, 10, 20, 10); - title.setTitleColor(sTitleMainColor); - title.setSubtitleColor(sTitleSubColor); - title.setTimingsToTicks(); - title.send(player); + if (AbstractTitle.TITLE_CLASS != null) { + AbstractTitle.TITLE_CLASS.sendTitle(player, sTitleMain, sTitleSub, ChatColor.valueOf(C.TITLE_ENTERED_PLOT_COLOR.s()), ChatColor.valueOf(C.TITLE_ENTERED_PLOT_SUB_COLOR.s())); + } } { final PlayerEnterPlotEvent callEvent = new PlayerEnterPlotEvent(player, plot); diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/titles/AbstractTitle.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/titles/AbstractTitle.java new file mode 100644 index 000000000..de5de8ca0 --- /dev/null +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/titles/AbstractTitle.java @@ -0,0 +1,10 @@ +package com.intellectualcrafters.plot.titles; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +public abstract class AbstractTitle { + public static AbstractTitle TITLE_CLASS; + + public abstract void sendTitle(Player player, String head, String sub, ChatColor head_color, ChatColor sub_color); +} diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/titles/DefaultTitle.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/titles/DefaultTitle.java new file mode 100644 index 000000000..38b91cbd4 --- /dev/null +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/titles/DefaultTitle.java @@ -0,0 +1,14 @@ +package com.intellectualcrafters.plot.titles; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +public class DefaultTitle extends AbstractTitle { + @Override + public void sendTitle(Player player, String head, String sub, ChatColor head_color, ChatColor sub_color) { + DefaultTitleManager title = new DefaultTitleManager(head,sub,1, 2, 1); + title.setTitleColor(head_color); + title.setSubtitleColor(sub_color); + title.send(player); + } +} diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/titles/DefaultTitleManager.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/titles/DefaultTitleManager.java new file mode 100644 index 000000000..796f40211 --- /dev/null +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/titles/DefaultTitleManager.java @@ -0,0 +1,410 @@ +package com.intellectualcrafters.plot.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; + +/** + * [ PlotSquared DefaultTitleManager by Maxim Van de Wynckel ] + * + * @version 1.1.0 + * @author Maxim Van de Wynckel + * + */ +public class DefaultTitleManager { + /* Title packet */ + private Class packetTitle; + /* Title packet actions ENUM */ + private Class packetActions; + /* Chat serializer */ + private Class nmsChatSerializer; + private Class chatBaseComponent; + /* 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> CORRESPONDING_TYPES = new HashMap, Class>(); + + /** + * Create a new 1.8 title + * + * @param title + * Title + */ + public DefaultTitleManager(String title) { + this.title = title; + loadClasses(); + } + + /** + * Create a new 1.8 title + * + * @param title + * Title text + * @param subtitle + * Subtitle text + */ + public DefaultTitleManager(String title, String subtitle) { + this.title = title; + this.subtitle = subtitle; + loadClasses(); + } + + /** + * Copy 1.8 title + * + * @param title + * Title + */ + public DefaultTitleManager(DefaultTitleManager title) { + // Copy title + this.title = title.title; + this.subtitle = title.subtitle; + this.titleColor = title.titleColor; + this.subtitleColor = title.subtitleColor; + this.fadeInTime = title.fadeInTime; + this.fadeOutTime = title.fadeOutTime; + this.stayTime = title.stayTime; + this.ticks = title.ticks; + 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 DefaultTitleManager(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() { + packetTitle = getNMSClass("PacketPlayOutTitle"); + packetActions = getNMSClass("EnumTitleAction"); + chatBaseComponent = getNMSClass("IChatBaseComponent"); + nmsChatSerializer = getNMSClass("ChatSerializer"); + } + + /** + * 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 = getField(handle.getClass(), "playerConnection").get(handle); + Object[] actions = packetActions.getEnumConstants(); + Method sendPacket = getMethod(connection.getClass(), "sendPacket"); + Object packet = + packetTitle.getConstructor(packetActions, chatBaseComponent, Integer.TYPE, Integer.TYPE, Integer.TYPE).newInstance(actions[2], 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); + + // Send title + Object serialized = + getMethod(nmsChatSerializer, "a", String.class).invoke(null, "{text:\"" + + ChatColor.translateAlternateColorCodes('&', title) + "\",color:" + + titleColor.name().toLowerCase() + "}"); + packet = + packetTitle.getConstructor(packetActions, chatBaseComponent).newInstance(actions[0], serialized); + sendPacket.invoke(connection, packet); + if (subtitle != "") { + // Send subtitle if present + serialized = + getMethod(nmsChatSerializer, "a", String.class).invoke(null, "{text:\"" + + ChatColor.translateAlternateColorCodes('&', subtitle) + "\",color:" + + subtitleColor.name().toLowerCase() + "}"); + packet = + packetTitle.getConstructor(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 = getField(handle.getClass(), "playerConnection").get(handle); + Object[] actions = packetActions.getEnumConstants(); + Method sendPacket = getMethod(connection.getClass(), "sendPacket"); + Object packet = packetTitle.getConstructor(packetActions, chatBaseComponent).newInstance(actions[3], 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 = getField(handle.getClass(), "playerConnection").get(handle); + Object[] actions = packetActions.getEnumConstants(); + Method sendPacket = getMethod(connection.getClass(), "sendPacket"); + Object packet = packetTitle.getConstructor(packetActions, chatBaseComponent).newInstance(actions[4], 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(Object obj) { + try { + return getMethod("getHandle", obj.getClass()).invoke(obj); + } + 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 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; + } +} diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/Title.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/unused/Title.java similarity index 99% rename from PlotSquared/src/main/java/com/intellectualcrafters/plot/object/Title.java rename to PlotSquared/src/main/java/com/intellectualcrafters/plot/unused/Title.java index 551e1d662..233ed792c 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/Title.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/unused/Title.java @@ -19,7 +19,7 @@ // You can contact us via: support@intellectualsites.com / //////////////////////////////////////////////////////////////////////////////////////////////////// -package com.intellectualcrafters.plot.object; +package com.intellectualcrafters.plot.unused; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -36,7 +36,7 @@ import org.bukkit.entity.Player; * @author Maxim Van de Wynckel * @version 1.0.3 */ -@SuppressWarnings("unused") public class Title { +public class Title { private static final Map, Class> CORRESPONDING_TYPES; static {