diff --git a/src/main/java/be/maximvdw/placeholderapi/EventAPI.java b/src/main/java/be/maximvdw/placeholderapi/EventAPI.java new file mode 100644 index 0000000..c1720df --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/EventAPI.java @@ -0,0 +1,32 @@ +package be.maximvdw.placeholderapi; + +import be.maximvdw.placeholderapi.internal.eventhooks.BaseEventHook; +import be.maximvdw.placeholderapi.internal.eventhooks.TriggerEvent; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +public class EventAPI { + + /** + * Trigger an event on another plugin + * + * @param plugin Plugin instance (FeatherBoard, AnimatedNames,...) not your plugin + * @param player Player to trigger the action for + * @param action Action to trigger(scoreboard, group ,...) + * @param enable Enable or disable event? + * @return True when success + */ + public static boolean triggerEvent(Plugin plugin, Player player, String action, boolean enable){ + TriggerEvent event = BaseEventHook.getHook(plugin.getClass().getProtectionDomain().getCodeSource().getLocation()); + if (event == null){ + return false; // Plugin is not found. Are you sure you have not passed your own plugin instance + } + if (enable){ + event.enableEvent(player,action); + }else{ + event.disableEvent(player,action); + } + return true; + } + +} diff --git a/src/main/java/be/maximvdw/placeholderapi/PlaceholderAPI.java b/src/main/java/be/maximvdw/placeholderapi/PlaceholderAPI.java new file mode 100644 index 0000000..93a55d8 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/PlaceholderAPI.java @@ -0,0 +1,242 @@ +package be.maximvdw.placeholderapi; + +import be.maximvdw.placeholderapi.events.PlaceholderAddedEvent; +import be.maximvdw.placeholderapi.internal.CustomPlaceholdersPack; +import be.maximvdw.placeholderapi.internal.PlaceholderPack; +import be.maximvdw.placeholderapi.internal.PlaceholderPlugin; +import be.maximvdw.placeholderapi.internal.ui.SendConsole; +// Import entfernt, da Bibliothek fehlt: import be.maximvdw.placeholderapi.internal.updater.MVdWUpdaterHook; +import be.maximvdw.placeholderapi.internal.utils.DateUtils; +import be.maximvdw.placeholderapi.internal.utils.NumberUtils; +import be.maximvdw.placeholderapi.internal.utils.bukkit.BukkitUtils; +import be.maximvdw.placeholderapi.internal.utils.chat.ColorUtils; +import org.bstats.bukkit.Metrics; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * MVdWPlaceholderAPI + * + * @author Maxim Van de Wynckel (Maximvdw) + */ +public class PlaceholderAPI extends JavaPlugin{ + /* Placeholder container */ + private static List placeholderPlugins = new ArrayList<>(); + /* Custom placeholders registered in the API */ + private static PlaceholderPack customPlaceholders = null; + /* Placeholder change listeners */ + private static List placeholderAddedHandlers = new ArrayList(); + + @Override + public void onEnable() { + super.onEnable(); + new SendConsole(this); + PlaceholderAPI.initialize(this); + SendConsole.info("Initializing placeholders ..."); + + // Prevent linkage errors + new ColorUtils(); + new BukkitUtils(); + new DateUtils(); + new NumberUtils(); + + /* Updater Code entfernt/auskommentiert, da die Abhängigkeit fehlt und das Repo offline ist. + int resource = 11182; + try { + if (Bukkit.getPluginManager().isPluginEnabled("MVdWUpdater")) + new MVdWUpdaterHook(this, resource); + } catch (Throwable ex) { + // No updater + } + */ + + SendConsole.info("Sending metrics ..."); + try { + new Metrics(this, 11182); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public static void initialize(PlaceholderAPI api) { + customPlaceholders = new CustomPlaceholdersPack(api); + } + + /** + * Register an MVdW Plugin + * + * @param plugin Plugin + * @param placeholderPlugin Placeholder plugin container + * @return success + */ + public boolean registerMVdWPlugin(Plugin plugin, PlaceholderPlugin placeholderPlugin) { + if (customPlaceholders == null){ + SendConsole.severe("Unable to hook into MVdW Placeholder plugin!"); + } + if (!placeholderPlugins.contains(placeholderPlugin)) { + placeholderPlugin.registerPlaceHolder(customPlaceholders); + placeholderPlugins.add(placeholderPlugin); + SendConsole.info("Hooked into MVdW plugin: " + plugin.getName()); + return true; + } else { + placeholderPlugin.registerPlaceHolder(customPlaceholders); + SendConsole.info("Hooked into MVdW plugin again: " + plugin.getName()); + return false; + } + } + + /** + * Replace placeholders in input + * + * @param offlinePlayer Player to replace placeholders for + * @param input Placeholder format {placeholder} + * @return Return result with replaced placeholders + */ + public static String replacePlaceholders(OfflinePlayer offlinePlayer, String input) { + if (placeholderPlugins.size() == 0) { + return input; + } + return placeholderPlugins.get(0).getPlaceholderResult(input, + offlinePlayer); + } + + /** + * Returns the amount of placeholders loaded into the memory + * + * @return Placeholder count + */ + public static int getLoadedPlaceholderCount() { + if (placeholderPlugins.size() == 0) { + return 0; + } + return placeholderPlugins.get(0).getPlaceHolderCount(); + } + /** + * Register a custom placeholder + * + * @param plugin Plugin that is registering the placeholder + * @param placeholder Placeholder to be registered WITHOUT { } + * @return Returns if the placeholder is added or not + */ + public static boolean registerPlaceholder(Plugin plugin, String placeholder, PlaceholderReplacer replacer) { + return PlaceholderAPI.registerPlaceholder(plugin, placeholder, replacer, new ArrayList()); + } + + /** + * Register a custom placeholder + * + * @param plugin Plugin that is registering the placeholder + * @param placeholder Placeholder to be registered WITHOUT { } + * @return Returns if the placeholder is added or not + */ + public static boolean registerPlaceholder(Plugin plugin, String placeholder, PlaceholderReplacer replacer, PlaceholderOptions ...options) { + return PlaceholderAPI.registerPlaceholder(plugin, placeholder, replacer, new ArrayList()); + } + + + /** + * Register a custom placeholder + * + * @param plugin Plugin that is registering the placeholder + * @param placeholder Placeholder to be registered WITHOUT { } + * @return Returns if the placeholder is added or not + */ + private static boolean registerPlaceholder(Plugin plugin, String placeholder, PlaceholderReplacer replacer, Collection options) { + if (plugin == null) + return false; + if (placeholder == null) + return false; + if (placeholder.equals("")) + return false; + if (replacer == null) + return false; + SendConsole.info(plugin.getName() + " added custom placeholder {" + + placeholder.toLowerCase() + "}"); + be.maximvdw.placeholderapi.internal.PlaceholderReplacer internalReplacer = new be.maximvdw.placeholderapi.internal.PlaceholderReplacer(String.class, + replacer) { + @Override + public String getResult(PlaceholderReplaceEvent event) { + PlaceholderReplacer replacer = (PlaceholderReplacer) getArguments()[0]; + return replacer.onPlaceholderReplace(event); + } + }; + + // Enable placeholder options + for (PlaceholderOptions option : options) { + switch (option) { + case RELATIONAL_PLACEHOLDER: + internalReplacer.isRelationalPlaceholder(true); + break; + case ONLINE_PLACEHOLDER: + internalReplacer.setOnline(true); + break; + } + } + + customPlaceholders.addOfflinePlaceholder( + placeholder, + "Custom MVdWPlaceholderAPI placeholder", + false, + internalReplacer); + for (PlaceholderAddedEvent event : placeholderAddedHandlers) { + if (event != null) + event.onPlaceholderAdded(plugin, placeholder.toLowerCase(), replacer); + } + return true; // Placeholder registered + } + + /** + * Register a static custom placeholder + * + * @param plugin Plugin that is registering the placeholder + * @param placeholder Placeholder to be registered WITHOUT { } + * @param value Placeholder value + * @return Returns if the placeholder is added or not + */ + public static boolean registerStaticPlaceholders(Plugin plugin, String placeholder, final String value) { + if (plugin == null) + return false; + if (placeholder == null) + return false; + if (placeholder.equals("")) + return false; + PlaceholderReplacer replacer = new PlaceholderReplacer() { + @Override + public String onPlaceholderReplace(PlaceholderReplaceEvent event) { + return value; + } + }; + customPlaceholders.addOfflinePlaceholder( + placeholder, + "Custom MVdWPlaceholderAPI placeholder", + false, + new be.maximvdw.placeholderapi.internal.PlaceholderReplacer(String.class, + replacer) { + @Override + public String getResult(PlaceholderReplaceEvent replaceEvent) { + PlaceholderReplacer replacer = (PlaceholderReplacer) getArguments()[0]; + return replacer.onPlaceholderReplace(replaceEvent); + } + }); + for (PlaceholderAddedEvent event : placeholderAddedHandlers) { + if (event != null) + event.onPlaceholderAdded(plugin, placeholder.toLowerCase(), replacer); + } + return true; // Placeholder registered + } + + /** + * Add a placeholder listener + * + * @param handler placeholder added handler + */ + public void addPlaceholderListener(PlaceholderAddedEvent handler) { + placeholderAddedHandlers.add(handler); + } +} \ No newline at end of file diff --git a/src/main/java/be/maximvdw/placeholderapi/PlaceholderOptions.java b/src/main/java/be/maximvdw/placeholderapi/PlaceholderOptions.java new file mode 100644 index 0000000..49b7646 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/PlaceholderOptions.java @@ -0,0 +1,6 @@ +package be.maximvdw.placeholderapi; + +public enum PlaceholderOptions { + RELATIONAL_PLACEHOLDER, + ONLINE_PLACEHOLDER +} diff --git a/src/main/java/be/maximvdw/placeholderapi/PlaceholderReplaceEvent.java b/src/main/java/be/maximvdw/placeholderapi/PlaceholderReplaceEvent.java new file mode 100644 index 0000000..2f0eb20 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/PlaceholderReplaceEvent.java @@ -0,0 +1,106 @@ +package be.maximvdw.placeholderapi; + +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +/** + * Placeholder replace event + * + * @author Maxim Van de Wynckel + */ +public class PlaceholderReplaceEvent { + private OfflinePlayer offlinePlayer = null; // The offline player if player is not null + private OfflinePlayer offlineViewingPlayer = null; // The offline player that is viewing the user. In most cases this is the user itself + private String placeholder = ""; // The placeholder (with or without wildcards) + + public PlaceholderReplaceEvent(OfflinePlayer offlinePlayer, + String placeholder) { + setOfflineViewingPlayer(offlinePlayer); + setOfflinePlayer(offlinePlayer); + setPlaceholder(placeholder); + } + + public PlaceholderReplaceEvent(OfflinePlayer offlinePlayer, OfflinePlayer viewingPlayer, + String placeholder) { + setOfflineViewingPlayer(viewingPlayer); + setOfflinePlayer(offlinePlayer); + setPlaceholder(placeholder); + } + + + /** + * Get the placeholder that is requested to be replaced + * + * @return Placeholder without { } + */ + public String getPlaceholder() { + return placeholder; + } + + private void setPlaceholder(String placeholder) { + this.placeholder = placeholder; + } + + /** + * Get the offline player instance + * + * @return Offline player + */ + public OfflinePlayer getOfflinePlayer() { + return offlinePlayer; + } + + private void setOfflinePlayer(OfflinePlayer offlinePlayer) { + this.offlinePlayer = offlinePlayer; + } + + /** + * Get the offline viewing player instance + * + * @return Offline player + */ + public OfflinePlayer getOfflineViewingPlayer() { + return offlineViewingPlayer; + } + + private void setOfflineViewingPlayer(OfflinePlayer offlinePlayer) { + this.offlineViewingPlayer = offlinePlayer; + } + + /** + * Get the online player instance + * + * @return Online player + */ + public Player getPlayer() { + if (offlinePlayer != null) { + if (offlinePlayer.isOnline()) + return getOfflinePlayer().getPlayer(); + } + return null; + } + + /** + * Get the online player instance + * + * @return Online viewing player + */ + public Player getViewingPlayer() { + if (offlineViewingPlayer != null) { + if (offlineViewingPlayer.isOnline()) + return getOfflineViewingPlayer().getPlayer(); + } + return null; + } + + /** + * Check if the player is online + * + * @return Player is online + */ + public boolean isOnline() { + if (offlinePlayer == null) + return false; + return offlinePlayer.isOnline(); + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/PlaceholderReplacer.java b/src/main/java/be/maximvdw/placeholderapi/PlaceholderReplacer.java new file mode 100644 index 0000000..2876748 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/PlaceholderReplacer.java @@ -0,0 +1,16 @@ +package be.maximvdw.placeholderapi; + +/** + * PlaceholderReplacer interface + * + * @author Maxim Van de Wynckel + */ +public interface PlaceholderReplacer { + /** + * On placeholder replace event + * + * @param event PlaceholderReplaceEvent holding the player and placeholder + * @return Return result of the placeholder + */ + String onPlaceholderReplace(PlaceholderReplaceEvent event); +} diff --git a/src/main/java/be/maximvdw/placeholderapi/events/PlaceholderAddedEvent.java b/src/main/java/be/maximvdw/placeholderapi/events/PlaceholderAddedEvent.java new file mode 100644 index 0000000..7cb8d52 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/events/PlaceholderAddedEvent.java @@ -0,0 +1,22 @@ +package be.maximvdw.placeholderapi.events; + +import org.bukkit.plugin.Plugin; + +import be.maximvdw.placeholderapi.PlaceholderReplacer; + +/** + * Placeholder Added event + * + * @author Maxim Van de Wynckel + */ +public interface PlaceholderAddedEvent { + /** + * Called when a custom placeholder is added + * + * @param plugin Plugin that added it + * @param placeholder Placeholder that is added + * @param replacer Replacer for the plugin + */ + void onPlaceholderAdded(Plugin plugin, String placeholder, + PlaceholderReplacer replacer); +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/CustomPlaceholdersPack.java b/src/main/java/be/maximvdw/placeholderapi/internal/CustomPlaceholdersPack.java new file mode 100644 index 0000000..562d682 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/CustomPlaceholdersPack.java @@ -0,0 +1,43 @@ +package be.maximvdw.placeholderapi.internal; + +import be.maximvdw.placeholderapi.internal.annotations.*; +import org.bukkit.plugin.Plugin; + +/** + * CustomPlaceholdersPack + * Created by Maxim on 3/10/2017. + */ + +@ModuleName("CustomPlaceholdersPack") +@ModuleAuthor("Maximvdw") +@ModuleVersion("2.0.0") +@ModuleDescription("MVdWPlaceholderAPI placeholders") +@ModulePermalink("https://www.spigotmc.org/resources/mvdwplaceholderapi.11182/") +public class CustomPlaceholdersPack extends PlaceholderPack { + private static CustomPlaceholdersPack instance = null; + + public static CustomPlaceholdersPack getInstance() { + return instance; + } + + public CustomPlaceholdersPack(Plugin plugin) { + super(plugin, 1); + setEnabled(true); + instance = this; + } + + @Override + public void onDisable() { + + } + + @Override + public void onDelete() { + + } + + @Override + public void onEnable() { + + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/OnlinePlaceholderReplacer.java b/src/main/java/be/maximvdw/placeholderapi/internal/OnlinePlaceholderReplacer.java new file mode 100644 index 0000000..dca6f9c --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/OnlinePlaceholderReplacer.java @@ -0,0 +1,64 @@ +package be.maximvdw.placeholderapi.internal; + +import be.maximvdw.placeholderapi.PlaceholderReplaceEvent; +import be.maximvdw.placeholderapi.internal.ui.SendConsole; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +public abstract class OnlinePlaceholderReplacer extends + PlaceholderReplacer { + + public OnlinePlaceholderReplacer(Class type) { + super(type); + } + + public OnlinePlaceholderReplacer(Class type, Object... args) { + super(type, args); + } + + /** + * Get placeholder result + * + * @param event Placeholder replace event + * @return placeholder result + */ + @Override + public T getResult(PlaceholderReplaceEvent event){ + // Will be implemented by newer placeholder versions + // Will not be called by older versions + // Compensated by redirecting to older call + // Because one of these three "getResult" functions will be implemented + // it is not going to cause a recursive loop + return this.getResult(event.getPlaceholder(),event.getPlayer()); + } + + /** + * Get placeholder result + * + * @param player + * Player + * @return placeholder result + */ + @Deprecated + @Override + public T getResult(String placeholder, Player player){ + PlaceholderReplaceEvent replaceEvent = new PlaceholderReplaceEvent(player,placeholder); + return this.getResult(replaceEvent); + } + + /** + * Get placeholder result + * + * @param player + * Player + * @return placeholder result + */ + @Deprecated + @Override + public T getResult(String placeholder, OfflinePlayer player) { + if (player.isOnline()){ + return this.getResult(new PlaceholderReplaceEvent(player,placeholder)); + } + return null; + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/PlaceholderConversion.java b/src/main/java/be/maximvdw/placeholderapi/internal/PlaceholderConversion.java new file mode 100644 index 0000000..304d198 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/PlaceholderConversion.java @@ -0,0 +1,1588 @@ +package be.maximvdw.placeholderapi.internal; + +import be.maximvdw.placeholderapi.PlaceholderReplaceEvent; +import be.maximvdw.placeholderapi.internal.utils.ListUtils; +import org.bukkit.Location; +import org.bukkit.OfflinePlayer; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.Calendar; + +public class PlaceholderConversion { + public static void convertOnlineCalendarPlaceholders(PlaceholderPack placeholderPackObj, String placeholder, String description, + final PlaceholderReplacer replacer) { + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_week", description + " week in year", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.getWeekYear(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_timeinmillis", description + " time in millis", + new OnlinePlaceholderReplacer(Long.class) { + + @Override + public Long getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0L; + return cal.getTimeInMillis(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_firstdayofweek", description + " first day of the week", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.getFirstDayOfWeek(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_dayofmonth", description + " day of month", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.DAY_OF_MONTH); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_dayofweek", description + " day of week", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.DAY_OF_WEEK); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_dayofweekinmonth", description + " day of week in month", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.DAY_OF_WEEK_IN_MONTH); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_dayofyear", description + " day of year", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.DAY_OF_YEAR); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_hour", description + " hour (am/pm)", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.HOUR); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_dayofmonth", description + " hour (24h)", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.HOUR_OF_DAY); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_era", description + " era", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.ERA); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_millisecond", description + " millisecond", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.MILLISECOND); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_minute", description + " minute", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.MINUTE); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_month", description + " month", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.MONTH); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_second", description + " second", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.SECOND); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_weekofmonth", description + " week of month", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.WEEK_OF_MONTH); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_weekofyear", description + " week of year", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.WEEK_OF_YEAR); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_year", description + " year", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.YEAR); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_dstoffset", description + " DST Offset", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.DST_OFFSET); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_zoneoffset", description + " zone offset", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.ZONE_OFFSET); + } + }); + } + + public static void convertOfflineCalendarPlaceholders(PlaceholderPack placeholderPackObj, String placeholder, String description, boolean requiresplayer, + final PlaceholderReplacer replacer) { + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_week", description + " week in year", requiresplayer, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.getWeekYear(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_timeinmillis", description + " time in millis", + requiresplayer, new PlaceholderReplacer(Long.class) { + + @Override + public Long getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0L; + return cal.getTimeInMillis(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_firstdayofweek", description + " first day of the week", + requiresplayer, new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.getFirstDayOfWeek(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_dayofmonth", description + " day of month", requiresplayer, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.DAY_OF_MONTH); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_dayofweek", description + " day of week", requiresplayer, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.DAY_OF_WEEK); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_dayofweekinmonth", description + " day of week in month", + requiresplayer, new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.DAY_OF_WEEK_IN_MONTH); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_dayofyear", description + " day of year", requiresplayer, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.DAY_OF_YEAR); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_hour", description + " hour (am/pm)", requiresplayer, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.HOUR); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_dayofmonth", description + " hour (24h)", requiresplayer, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.HOUR_OF_DAY); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_era", description + " era", requiresplayer, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.ERA); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_millisecond", description + " millisecond", requiresplayer, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.MILLISECOND); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_minute", description + " minute", requiresplayer, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.MINUTE); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_month", description + " month", requiresplayer, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.MONTH); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_second", description + " second", requiresplayer, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.SECOND); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_weekofmonth", description + " week of month", + requiresplayer, new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.WEEK_OF_MONTH); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_weekofyear", description + " week of year", requiresplayer, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.WEEK_OF_YEAR); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_year", description + " year", requiresplayer, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.YEAR); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_dstoffset", description + " DST Offset", requiresplayer, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.DST_OFFSET); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_zoneoffset", description + " zone offset", requiresplayer, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Calendar cal = (Calendar) replacer.getResult(event); + if (cal == null) + return 0; + return cal.get(Calendar.ZONE_OFFSET); + } + }); + } + + public static void convertOnlineLocationPlaceholders(PlaceholderPack placeholderPackObj, String placeholder, String description, + final PlaceholderReplacer replacer) { + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_x", description + " X", + new OnlinePlaceholderReplacer(Double.class) { + + @Override + public Double getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0.0; + return loc.getX(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_y", description + " X", + new OnlinePlaceholderReplacer(Double.class) { + + @Override + public Double getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0.0; + return loc.getY(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_z", description + " X", + new OnlinePlaceholderReplacer(Double.class) { + + @Override + public Double getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0.0; + return loc.getZ(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_blockx", description + " X rounded", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0; + return loc.getBlockX(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_blocky", description + " Y rounded", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0; + return loc.getBlockY(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_blockz", description + " Z rounded", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0; + return loc.getBlockZ(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_world", description, + new OnlinePlaceholderReplacer(World.class) { + + @Override + public World getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return null; + return loc.getWorld(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_yaw", description + " yaw", + new OnlinePlaceholderReplacer(Float.class) { + + @Override + public Float getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0F; + return loc.getYaw(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_pitch", description + " pitch", + new OnlinePlaceholderReplacer(Float.class) { + + @Override + public Float getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0F; + return loc.getPitch(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_chunk_x", description + " chunk X", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0; + return loc.getChunk().getX(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_chunk_z", description + " chunk Z", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0; + return loc.getChunk().getZ(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_chunk_entities", description + " chunk amount of entities", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0; + return loc.getChunk().getEntities().length; + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_chunk_tileentities", + description + " chunk amount of tile entities", new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0; + return loc.getChunk().getTileEntities().length; + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_chunk_isloaded", description + " chunk is loaded", + new OnlinePlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return false; + return loc.getChunk().isLoaded(); + } + }); + } + + public static void convertOnlineStringListPlaceholders(PlaceholderPack placeholderPackObj, String placeholder, String description, + final PlaceholderReplacer replacer) { + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "#*", + description + " (example: {" + placeholder.toLowerCase() + "#1} )", + new OnlinePlaceholderReplacer(String.class, placeholder) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + int idx = Integer.parseInt(event.getPlaceholder().replace(getArguments()[0].toString() + "#", "")); + String[] list = (String[]) replacer.getResult(event); + if (list == null) + return ""; + if (list.length < idx) + return ""; + + return list[idx - 1]; + } + }); + } + + public static void convertOfflineStringListPlaceholders(PlaceholderPack placeholderPackObj, String placeholder, String description, boolean playerrequired, + final PlaceholderReplacer replacer) { + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "#*", + description + " (example: {" + placeholder.toLowerCase() + "#1} )", playerrequired, + new PlaceholderReplacer(String.class, placeholder) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + int idx = Integer.parseInt(event.getPlaceholder().substring(event.getPlaceholder().indexOf("#") + 1)); + String[] list = (String[]) replacer.getResult(event); + if (list == null) + return ""; + if (list.length < idx) + return ""; + if (idx <= 0) + return ""; + return list[idx - 1]; + } + }); + } + + public static void convertOnlineIntegerListPlaceholders(PlaceholderPack placeholderPackObj, String placeholder, String description, + final PlaceholderReplacer replacer) { + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "#*", + description + " (example: {" + placeholder.toLowerCase() + "#1} )", + new OnlinePlaceholderReplacer(Integer.class, placeholder) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + int idx = Integer.parseInt(event.getPlaceholder().replace(getArguments()[0].toString() + "#", "")); + Integer[] list = (Integer[]) replacer.getResult(event); + if (list == null) + return 0; + if (list.length < idx) + return 0; + + return list[idx - 1]; + } + }); + } + + public static void convertOfflineIntegerListPlaceholders(PlaceholderPack placeholderPackObj, String placeholder, String description, boolean playerrequired, + final PlaceholderReplacer replacer) { + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "#*", + description + " (example: {" + placeholder.toLowerCase() + "#1} )", playerrequired, + new PlaceholderReplacer(Integer.class, placeholder) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + int idx = Integer.parseInt(event.getPlaceholder().replace(getArguments()[0].toString() + "#", "")); + Integer[] list = (Integer[]) replacer.getResult(event); + if (list == null) + return 0; + if (list.length < idx) + return 0; + + return list[idx - 1]; + } + }); + } + + public static void convertOnlineBooleanListPlaceholders(PlaceholderPack placeholderPackObj, String placeholder, String description, + final PlaceholderReplacer replacer) { + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "#*", + description + " (example: {" + placeholder.toLowerCase() + "#1} )", + new OnlinePlaceholderReplacer(Boolean.class, placeholder) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + int idx = Integer.parseInt(event.getPlaceholder().replace(getArguments()[0].toString() + "#", "")); + Boolean[] list = (Boolean[]) replacer.getResult(event); + if (list == null) + return false; + if (list.length < idx) + return false; + + return list[idx - 1]; + } + }.setDefaultFalseOutput(replacer.getDefaultFalseOutput()) + .setDefaultTrueOutput(replacer.getDefaultTrueOutput())); + } + + public static void convertOfflineBooleanListPlaceholders(PlaceholderPack placeholderPackObj, String placeholder, String description, boolean playerrequired, + final PlaceholderReplacer replacer) { + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "#*", + description + " (example: {" + placeholder.toLowerCase() + "#1} )", playerrequired, + new PlaceholderReplacer(Boolean.class, placeholder) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + int idx = Integer.parseInt(event.getPlaceholder().replace(getArguments()[0].toString() + "#", "")); + Boolean[] list = (Boolean[]) replacer.getResult(event); + if (list == null) + return false; + if (list.length < idx) + return false; + + return list[idx - 1]; + } + }.setDefaultFalseOutput(replacer.getDefaultFalseOutput()) + .setDefaultTrueOutput(replacer.getDefaultTrueOutput())); + } + + public static void convertOfflineItemPlaceholders(PlaceholderPack placeholderPackObj, String placeholder, String description, boolean playerrequired, + final PlaceholderReplacer replacer) { + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + ":amount", description + " amount", playerrequired, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return 0; + return item.getAmount(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + ":type", description + " type name", playerrequired, + new PlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return ""; + return item.getType().name(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + ":typeid", description + " type id", playerrequired, + new PlaceholderReplacer(Integer.class) { + + @SuppressWarnings("deprecation") + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return 0; + return item.getType().ordinal(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + ":maxsize", description + " max size", playerrequired, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return 0; + return item.getMaxStackSize(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + ":durability", description + " durability", playerrequired, + new PlaceholderReplacer(Short.class) { + + @Override + public Short getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return 0; + return item.getDurability(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + ":maxdurability", description + " max durability", + playerrequired, new PlaceholderReplacer(Short.class) { + + @Override + public Short getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return 0; + return item.getType().getMaxDurability(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "remainingdurability", description + " remainingdurability", + playerrequired, new PlaceholderReplacer(Short.class) { + + @Override + public Short getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return 0; + return (short) (item.getType().getMaxDurability() - item.getDurability()); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + ":maxstacksize", description + " max stack size", + playerrequired, new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return 0; + return item.getType().getMaxStackSize(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + ":material", description + " material", playerrequired, + new PlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return ""; + return item.getType().name(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + ":isblock", description + " is block", playerrequired, + new PlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return false; + return item.getType().isBlock(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + ":hasgravity", description + " has gravity", playerrequired, + new PlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return false; + return item.getType().hasGravity(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + ":isburnable", description + " is burnable", playerrequired, + new PlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return false; + return item.getType().isBurnable(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + ":isedible", description + " is edible", playerrequired, + new PlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return false; + return item.getType().isEdible(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + ":isflammable", description + " is flammable", playerrequired, + new PlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return false; + return item.getType().isFlammable(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + ":isoccluding", description + " is occluding", playerrequired, + new PlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return false; + return item.getType().isOccluding(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + ":isrecord", description + " is record", playerrequired, + new PlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return false; + return item.getType().isRecord(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + ":issolid", description + " is solid", playerrequired, + new PlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return false; + return item.getType().isSolid(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + ":istransparent", description + " is transparent", + playerrequired, new PlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return false; + return item.getType().isTransparent(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + ":displayname", description + " display name", playerrequired, + new PlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return ""; + if (item.getItemMeta() == null) + return ""; + return item.getItemMeta().getDisplayName(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + ":lore", description + " lore", playerrequired, + new PlaceholderReplacer(String[].class) { + + @Override + public String[] getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return new String[0]; + if (item.getItemMeta() == null) + return new String[0]; + if (item.getItemMeta().getLore() == null) + return new String[0]; + return ListUtils.listToArray(item.getItemMeta().getLore()); + } + }); + } + + public static void convertOfflineWorldPlaceholder(PlaceholderPack placeholderPackObj, String placeholder, String description, boolean playerrequired, + final PlaceholderReplacer replacer) { + placeholderPackObj.addOfflinePlaceholder(placeholder, description + " world name", playerrequired, + new PlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + World world = (World) replacer.getResult(event); + if (world == null) + return ""; + return world.getName(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder + "_name", description + " world name", playerrequired, + new PlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + World world = (World) replacer.getResult(event); + if (world == null) + return ""; + return world.getName(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder + "_UID", description + " world unique ID", playerrequired, + new PlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + World world = (World) replacer.getResult(event); + if (world == null) + return ""; + return world.getUID().toString(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder + "_players", description + " players in world", playerrequired, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + World world = (World) replacer.getResult(event); + if (world == null) + return 0; + return world.getPlayers().size(); + } + }); + } + + public static void convertOnlineWorldPlaceholder(PlaceholderPack placeholderPackObj, String placeholder, String description, + final PlaceholderReplacer replacer) { + placeholderPackObj.addPlaceholder(placeholder, description + " world name", new OnlinePlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + World world = (World) replacer.getResult(event); + if (world == null) + return ""; + return world.getName(); + } + }); + placeholderPackObj.addPlaceholder(placeholder + "_name", description + " world name", + new OnlinePlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + World world = (World) replacer.getResult(event); + if (world == null) + return ""; + return world.getName(); + } + }); + placeholderPackObj.addPlaceholder(placeholder + "_UID", description + " world unique ID", + new OnlinePlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + World world = (World) replacer.getResult(event); + if (world == null) + return ""; + return world.getUID().toString(); + } + }); + placeholderPackObj.addPlaceholder(placeholder + "_players", description + " players in world", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + World world = (World) replacer.getResult(event); + if (world == null) + return 0; + return world.getPlayers().size(); + } + }); + } + + public static void convertOnlineItemPlaceholders(PlaceholderPack placeholderPackObj, String placeholder, String description, + final PlaceholderReplacer replacer) { + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + ":amount", description + " amount", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return 0; + return item.getAmount(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + ":type", description + " type name", + new OnlinePlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return ""; + return item.getType().name(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + ":typeid", description + " type id", + new OnlinePlaceholderReplacer(Integer.class) { + + @SuppressWarnings("deprecation") + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return 0; + return item.getType().ordinal(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + ":maxsize", description + " max size", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return 0; + return item.getMaxStackSize(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + ":durability", description + " durability", + new OnlinePlaceholderReplacer(Short.class) { + + @Override + public Short getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return 0; + return item.getDurability(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + ":maxdurability", description + " max durability", + new OnlinePlaceholderReplacer(Short.class) { + + @Override + public Short getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return 0; + return item.getType().getMaxDurability(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "remainingdurability", description + " remainingdurability", + new OnlinePlaceholderReplacer(Short.class) { + + @Override + public Short getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return 0; + return (short) (item.getType().getMaxDurability() - item.getDurability()); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + ":maxstacksize", description + " max stack size", + new OnlinePlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return 0; + return item.getType().getMaxStackSize(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + ":material", description + " material", + new OnlinePlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return ""; + return item.getType().name(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + ":isblock", description + " is block", + new OnlinePlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return false; + return item.getType().isBlock(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + ":hasgravity", description + " has gravity", + new OnlinePlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return false; + return item.getType().hasGravity(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + ":isburnable", description + " is burnable", + new OnlinePlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return false; + return item.getType().isBurnable(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + ":isedible", description + " is edible", + new OnlinePlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return false; + return item.getType().isEdible(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + ":isflammable", description + " is flammable", + new OnlinePlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return false; + return item.getType().isFlammable(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + ":isoccluding", description + " is occluding", + new OnlinePlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return false; + return item.getType().isOccluding(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + ":isrecord", description + " is record", + new OnlinePlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return false; + return item.getType().isRecord(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + ":issolid", description + " is solid", + new OnlinePlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return false; + return item.getType().isSolid(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + ":istransparent", description + " is transparent", + new OnlinePlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return false; + return item.getType().isTransparent(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + ":displayname", description + " display name", + new OnlinePlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return ""; + if (item.getItemMeta() == null) + return ""; + return item.getItemMeta().getDisplayName(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + ":lore", description + " lore", + new OnlinePlaceholderReplacer(String[].class) { + + @Override + public String[] getResult(PlaceholderReplaceEvent event) { + ItemStack item = (ItemStack) replacer.getResult(event); + if (item == null) + return new String[0]; + if (item.getItemMeta() == null) + return new String[0]; + if (item.getItemMeta().getLore() == null) + return new String[0]; + return ListUtils.listToArray(item.getItemMeta().getLore()); + } + }); + } + + public static void convertOfflineBooleanPlaceholders(final PlaceholderPack placeholderPackObj, final String placeholder, String description, boolean requiresplayer, + final PlaceholderReplacer replacer) { + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase(), description, requiresplayer, + new PlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + Boolean result = (Boolean) replacer.getResult(event); + String resultString = result + ? placeholderPackObj.getConfig().getString( + placeholder.replace("*", "").replace("@", "").replace("#", "") + ".true") + : placeholderPackObj.getConfig().getString( + placeholder.replace("*", "").replace("@", "").replace("#", "") + ".false"); + return resultString; + } + }.setDefaultTrueOutput(replacer.getDefaultTrueOutput()) + .setDefaultFalseOutput(replacer.getDefaultFalseOutput())); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_raw", description + " [Raw frue/false]", requiresplayer, + new PlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + Boolean result = (Boolean) replacer.getResult(event); + return String.valueOf(result); + } + }.setDefaultTrueOutput("true").setDefaultFalseOutput("false")); + } + + public static void convertOnlineBooleanPlaceholders(final PlaceholderPack placeholderPackObj, final String placeholder, String description, + final PlaceholderReplacer replacer) { + placeholderPackObj.addPlaceholder(placeholder.toLowerCase(), description, new OnlinePlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + Boolean result = (Boolean) replacer.getResult(event); + + String resultString = result + ? placeholderPackObj.getConfig() + .getString(placeholder.replace("*", "").replace("@", "").replace("#", "") + ".true") + : placeholderPackObj.getConfig() + .getString(placeholder.replace("*", "").replace("@", "").replace("#", "") + ".false"); + return resultString; + } + }.setDefaultTrueOutput(replacer.getDefaultTrueOutput()) + .setDefaultFalseOutput(replacer.getDefaultFalseOutput())); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_raw", description + " [Raw frue/false]", + new OnlinePlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + Boolean result = (Boolean) replacer.getResult(event); + return String.valueOf(result); + } + }.setDefaultTrueOutput("true").setDefaultFalseOutput("false")); + } + + public static void convertOnlineOfflinePlayerPlaceholders(PlaceholderPack placeholderPackObj, String placeholder, String description, + final PlaceholderReplacer replacer) { + placeholderPackObj.addPlaceholder(placeholder.toLowerCase(), description, new OnlinePlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + OfflinePlayer returnPlayer = (OfflinePlayer) replacer.getResult(event); + if (returnPlayer == null) + return ""; + return returnPlayer.getName(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_name", " player name", + new OnlinePlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + OfflinePlayer returnPlayer = (OfflinePlayer) replacer.getResult(event); + if (returnPlayer == null) + return ""; + return returnPlayer.getName(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_uuid", " player UUID", + new OnlinePlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + OfflinePlayer returnPlayer = (OfflinePlayer) replacer.getResult(event); + if (returnPlayer == null) + return ""; + return returnPlayer.getUniqueId().toString(); + } + }); + placeholderPackObj.addPlaceholder(placeholder.toLowerCase() + "_isonline", " player is online", + new OnlinePlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + OfflinePlayer returnPlayer = (OfflinePlayer) replacer.getResult(event); + if (returnPlayer == null) + return false; + return returnPlayer.isOnline(); + } + }); + } + + public static void convertOfflineOfflinePlayerPlaceholders(PlaceholderPack placeholderPackObj, String placeholder, String description, boolean playerrequired, + final PlaceholderReplacer replacer) { + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase(), description, playerrequired, + new PlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + OfflinePlayer returnPlayer = (OfflinePlayer) replacer.getResult(event); + if (returnPlayer == null) + return ""; + return returnPlayer.getName(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_name", " player name", playerrequired, + new PlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + OfflinePlayer returnPlayer = (OfflinePlayer) replacer.getResult(event); + if (returnPlayer == null) + return ""; + return returnPlayer.getName(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_uuid", " player UUID", playerrequired, + new PlaceholderReplacer(String.class) { + + @Override + public String getResult(PlaceholderReplaceEvent event) { + OfflinePlayer returnPlayer = (OfflinePlayer) replacer.getResult(event); + if (returnPlayer == null) + return ""; + return returnPlayer.getUniqueId().toString(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_isonline", " player is online", playerrequired, + new PlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + OfflinePlayer returnPlayer = (OfflinePlayer) replacer.getResult(event); + if (returnPlayer == null) + return false; + return returnPlayer.isOnline(); + } + }); + } + + public static void convertOfflineLocationPlaceholders(PlaceholderPack placeholderPackObj, String placeholder, String description, boolean playerrequired, + final PlaceholderReplacer replacer) { + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_x", description + " X", playerrequired, + new PlaceholderReplacer(Double.class) { + + @Override + public Double getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0.0; + return loc.getX(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_y", description + " X", playerrequired, + new PlaceholderReplacer(Double.class) { + + @Override + public Double getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0.0; + return loc.getY(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_z", description + " X", playerrequired, + new PlaceholderReplacer(Double.class) { + + @Override + public Double getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0.0; + return loc.getZ(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_blockx", description + " X rounded", playerrequired, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0; + return loc.getBlockX(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_blocky", description + " Y rounded", playerrequired, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0; + return loc.getBlockY(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_blockz", description + " Z rounded", playerrequired, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0; + return loc.getBlockZ(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_world", description, playerrequired, + new PlaceholderReplacer(World.class) { + + @Override + public World getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return null; + return loc.getWorld(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_yaw", description + " yaw", playerrequired, + new PlaceholderReplacer(Float.class) { + + @Override + public Float getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0F; + return loc.getYaw(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_pitch", description + " pitch", playerrequired, + new PlaceholderReplacer(Float.class) { + + @Override + public Float getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0F; + return loc.getPitch(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_chunk_x", description + " chunk X", playerrequired, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0; + return loc.getChunk().getX(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_chunk_z", description + " chunk Z", playerrequired, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0; + return loc.getChunk().getZ(); + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_chunk_entities", description + " chunk amount of entities", + playerrequired, new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0; + return loc.getChunk().getEntities().length; + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_chunk_tileentities", + description + " chunk amount of tile entities", playerrequired, + new PlaceholderReplacer(Integer.class) { + + @Override + public Integer getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return 0; + return loc.getChunk().getTileEntities().length; + } + }); + placeholderPackObj.addOfflinePlaceholder(placeholder.toLowerCase() + "_chunk_isloaded", description + " chunk is loaded", + playerrequired, new PlaceholderReplacer(Boolean.class) { + + @Override + public Boolean getResult(PlaceholderReplaceEvent event) { + Location loc = (Location) replacer.getResult(event); + if (loc == null) + return false; + return loc.getChunk().isLoaded(); + } + }); + + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/PlaceholderPack.java b/src/main/java/be/maximvdw/placeholderapi/internal/PlaceholderPack.java new file mode 100644 index 0000000..0899c95 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/PlaceholderPack.java @@ -0,0 +1,527 @@ +package be.maximvdw.placeholderapi.internal; + +import be.maximvdw.placeholderapi.internal.annotations.*; +import be.maximvdw.placeholderapi.internal.storage.YamlBuilder; +import be.maximvdw.placeholderapi.internal.storage.YamlStorage; +import org.bukkit.Location; +import org.bukkit.OfflinePlayer; +import org.bukkit.World; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; + +import java.io.File; +import java.io.InvalidClassException; +import java.lang.annotation.Annotation; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +/** + * PlaceholderPack + *

+ * A placeholder pack contains multiple placeholders that are grouped together + */ + +public abstract class PlaceholderPack { + private String id = ""; + private String actionName = ""; + private String author = ""; + private String version = ""; + private boolean module = false; + private File jarFile = null; + + /** + * PlaceholderPack string + */ + private Map> placeholders = new ConcurrentHashMap<>(); + /** + * Plugin instance + */ + protected Plugin plugin = null; + /** + * PlaceholderPack settings + */ + private YamlStorage storage = null; + private YamlBuilder configBuilder = null; + private String name = ""; + private List placeholderConditions = new ArrayList<>(); + private boolean enabled = true; + private boolean actionPlaceholder = false; + private boolean containsWildcards = false; + private String description = ""; + private String pluginURL = ""; + private int configVersion = 1; + + public PlaceholderPack(Plugin plugin, int version) { + this.plugin = plugin; + setConfigVersion(version); + // Check annotations + Class componentClass = this.getClass().asSubclass(PlaceholderPack.class); + // Load the module constraints + Annotation[] annotations = componentClass.getAnnotations(); + if (annotations.length == 0) { + new InvalidClassException("Placeholder pack does not contain annotation information!").printStackTrace(); + return; + } + for (Annotation annotation : annotations) { + if (annotation instanceof ModuleConstraint) { + addCondition((ModuleConstraint) annotation); + } else if (annotation instanceof ModuleAuthor) { + setAuthor(((ModuleAuthor) annotation).value()); + } else if (annotation instanceof ModuleVersion) { + setVersion(((ModuleVersion) annotation).value()); + } else if (annotation instanceof ModuleConstraints) { + ModuleConstraint[] subConstraints = ((ModuleConstraints) annotation).value(); + for (ModuleConstraint subConstraint : subConstraints) { + addCondition(subConstraint); + } + } else if (annotation instanceof ModuleName) { + name = ((ModuleName) annotation).value().toLowerCase(); + if (actionName.equals("")) { + actionName = name; + } + } else if (annotation instanceof ModuleActionName) { + actionName = ((ModuleActionName) annotation).value().toLowerCase(); + if (name.equals("")) { + name = actionName; + } + } else if (annotation instanceof ModuleDescription) { + setDescription(((ModuleDescription) annotation).value()); + }else if (annotation instanceof ModulePermalink){ + setPluginURL(((ModulePermalink) annotation).value()); + } + } + } + + public PlaceholderPack() { + this(null, 1); + } + + + /** + * Triggers on disable + */ + public abstract void onDisable(); + + /** + * Triggers on delete + */ + public abstract void onDelete(); + + /** + * Triggers on enable + */ + public abstract void onEnable(); + + /** + * Get config + * + * @return Config + */ + public YamlConfiguration getConfig() { + if (storage == null) + return null; + return storage.getConfig(); + } + + /** + * Get config storage + * + * @return config storage + */ + public YamlStorage getStorage() { + return storage; + } + + /** + * Set config storage + * + * @param storage config storage + */ + public void setStorage(YamlStorage storage) { + this.storage = storage; + } + + /** + * Get plugin + * + * @return Plugin + */ + public Plugin getPlugin() { + return plugin; + } + + /** + * Get placeholder replacer by placeholder + * + * @param placeholder Placeholder string without {} + * @return Placeholder replacer + */ + public PlaceholderReplacer getPlaceholderReplacer(String placeholder) { + if (placeholders.containsKey(placeholder.toLowerCase())) + return placeholders.get(placeholder.toLowerCase()); + return null; + } + + /** + * Get placeholder + * + * @return placeholder + */ + public Set getOfflinePlaceholder() { + Set placeholdersList = new HashSet(); + for (String placeholder : getPlaceholder()) { + if (placeholders.containsKey(placeholder.toLowerCase())) + if (!placeholders.get(placeholder.toLowerCase()).isOnline()) + placeholdersList.add(placeholder); + } + return placeholdersList; + } + + /** + * Get placeholder + * + * @return placeholder + */ + public Set getOnlinePlaceholder() { + Set placeholdersList = new HashSet(); + for (String placeholder : getPlaceholder()) { + if (placeholders.containsKey(placeholder.toLowerCase())) + if (placeholders.get(placeholder.toLowerCase()).isOnline()) + placeholdersList.add(placeholder); + } + return placeholdersList; + } + + /** + * Get placeholder + * + * @return placeholder + */ + public Set getPlaceholder() { + return placeholders.keySet(); + } + + public Map getPlaceholderDescriptions() { + Map placeholdersList = new HashMap(); + for (String placeholder : placeholders.keySet()) { + String description = placeholders.get(placeholder).getDescription(); + placeholdersList.put(placeholder, description); + } + return placeholdersList; + } + + /** + * Add a placeholder condition + * + * @param condition Condition + */ + private PlaceholderPack addCondition(ModuleConstraint condition) { + placeholderConditions.add(condition); + return this; + } + + /** + * Set placeholder + * + * @param placeholder Place holder + * @param description Description + */ + public PlaceholderPack addPlaceholder(String placeholder, String description, OnlinePlaceholderReplacer replacer) { + return addPlaceholder(placeholder, description, (PlaceholderReplacer) replacer); + } + + /** + * Set placeholder + * + * @param placeholder Place holder + * @param description Description + */ + public PlaceholderPack addPlaceholder(String placeholder, String description, PlaceholderReplacer replacer) { + replacer.setDescription(description); + replacer.setOnline(true); + replacer.setRequiresPlayer(true); + if (replacer.getReturnType().equals(Location.class)) { + PlaceholderConversion.convertOnlineLocationPlaceholders(this, placeholder, description, replacer); + return this; + } else if (replacer.getReturnType().equals(OfflinePlayer.class)) { + PlaceholderConversion.convertOnlineOfflinePlayerPlaceholders(this, placeholder, description, replacer); + return this; + } else if (replacer.getReturnType().equals(ItemStack.class)) { + PlaceholderConversion.convertOnlineItemPlaceholders(this, placeholder, description, replacer); + return this; + } else if (replacer.getReturnType().equals(String[].class)) { + PlaceholderConversion.convertOnlineStringListPlaceholders(this, placeholder, description, replacer); + return this; + } else if (replacer.getReturnType().equals(Integer[].class)) { + PlaceholderConversion.convertOnlineIntegerListPlaceholders(this, placeholder, description, replacer); + return this; + } else if (replacer.getReturnType().equals(Boolean[].class)) { + PlaceholderConversion.convertOnlineBooleanListPlaceholders(this, placeholder, description, replacer); + return this; + } else if (replacer.getReturnType().equals(World.class)) { + PlaceholderConversion.convertOnlineWorldPlaceholder(this, placeholder, description, replacer); + return this; + } else if (replacer.getReturnType().equals(Calendar.class)) { + PlaceholderConversion.convertOnlineCalendarPlaceholders(this, placeholder, description, replacer); + return this; + } else if (replacer.getReturnType().equals(Boolean.class)) { + PlaceholderConversion.convertOnlineBooleanPlaceholders(this, placeholder, description, replacer); + return this; + } + if (!placeholder.startsWith("{")) + placeholder = "{" + placeholder; + if (!placeholder.endsWith("}")) + placeholder += "}"; + placeholders.put(placeholder.toLowerCase(), replacer); + if (placeholder.contains("*")) + setContainsWildcards(true); + return this; + } + + /** + * Add a new offline placeholder + * + * @param placeholder Place holder + * @param description Description + */ + public PlaceholderPack addOfflinePlaceholder(String placeholder, String description, boolean requiresplayer, + PlaceholderReplacer replacer) { + replacer.setDescription(description); + replacer.setOnline(false); + replacer.setRequiresPlayer(requiresplayer); + if (replacer.getReturnType().equals(Location.class)) { + PlaceholderConversion.convertOfflineLocationPlaceholders(this, placeholder, description, requiresplayer, replacer); + return this; + } else if (replacer.getReturnType().equals(OfflinePlayer.class)) { + PlaceholderConversion.convertOfflineOfflinePlayerPlaceholders(this, placeholder, description, requiresplayer, replacer); + return this; + } else if (replacer.getReturnType().equals(ItemStack.class)) { + PlaceholderConversion.convertOfflineItemPlaceholders(this, placeholder, description, requiresplayer, replacer); + return this; + } else if (replacer.getReturnType().equals(String[].class)) { + PlaceholderConversion.convertOfflineStringListPlaceholders(this, placeholder, description, requiresplayer, replacer); + return this; + } else if (replacer.getReturnType().equals(Integer[].class)) { + PlaceholderConversion.convertOfflineIntegerListPlaceholders(this, placeholder, description, requiresplayer, replacer); + return this; + } else if (replacer.getReturnType().equals(Boolean[].class)) { + PlaceholderConversion.convertOfflineBooleanListPlaceholders(this, placeholder, description, requiresplayer, replacer); + return this; + } else if (replacer.getReturnType().equals(World.class)) { + PlaceholderConversion.convertOfflineWorldPlaceholder(this, placeholder, description, requiresplayer, replacer); + return this; + } else if (replacer.getReturnType().equals(Calendar.class)) { + PlaceholderConversion.convertOfflineCalendarPlaceholders(this, placeholder, description, requiresplayer, replacer); + return this; + } else if (replacer.getReturnType().equals(Boolean.class)) { + PlaceholderConversion.convertOfflineBooleanPlaceholders(this, placeholder, description, requiresplayer, replacer); + return this; + } + if (!placeholder.startsWith("{")) + placeholder = "{" + placeholder; + if (!placeholder.endsWith("}")) + placeholder += "}"; + placeholders.put(placeholder.toLowerCase(), replacer); + if (placeholder.contains("*")) + setContainsWildcards(true); + return this; + } + + public void generateConfig() { + if (getConfigBuilder() != null) + return; + this.configBuilder = new YamlBuilder(); + getConfigBuilder().addPart("# --------------------------------------- ##"); + getConfigBuilder().addPart("# " + getDescription() + " Placeholders"); + if (!getPluginURL().equals("")) + getConfigBuilder().addPart("# " + getPluginURL()); + getConfigBuilder().addPart("# About: This configuration allows you to"); + getConfigBuilder().addPart("# configure what certain placeholders return."); + getConfigBuilder().addPart("# --------------------------------------- ##"); + getConfigBuilder().addEmptyPart(); + getConfigBuilder().addPart(" DO NOT EDIT THE CONFIG VERSION"); + getConfigBuilder().addPart("config", getConfigVersion()); + getConfigBuilder().addEmptyPart(); + getConfigBuilder().addPart(" Enable/Disable the placeholder group"); + getConfigBuilder().addPart(" Placeholder groups will not be loaded into the memory"); + getConfigBuilder().addPart(" when not used."); + getConfigBuilder().addPart("enabled", true); + getConfigBuilder().addEmptyPart(); + for (Map.Entry> entry : placeholders.entrySet()) { + String placeholderString = entry.getKey().replace("{", "").replace("}", "") + .replace("*", "").replace("@", "").replace("#", "").replace(":","_"); + PlaceholderReplacer replacerVal = entry.getValue(); + if (replacerVal.getDefaultTrueOutput() != null) { + // Create true or false + getConfigBuilder().addPart(" Define what the boolean placeholder {" + placeholderString + "} returns"); + YamlBuilder.YamlSectionPart placeholderSection = new YamlBuilder.YamlSectionPart(placeholderString); + if (replacerVal.getDefaultOutput() != null) { + placeholderSection.addPart(" Default return value"); + placeholderSection.addPart("default", replacerVal.getDefaultOutput()); + } + + placeholderSection.addPart(" This will be shown when the placeholder is 'True'"); + placeholderSection.addPart("true", + replacerVal.getDefaultTrueOutput() == null ? "True" : replacerVal.getDefaultTrueOutput()); + placeholderSection.addPart(" This will be shown when the placeholder is 'False'"); + placeholderSection.addPart("false", + replacerVal.getDefaultFalseOutput() == null ? "False" : replacerVal.getDefaultFalseOutput()); + + getConfigBuilder().addPart(placeholderSection); + getConfigBuilder().addEmptyPart(); + } else if (replacerVal.getDefaultOutput() != null) { + getConfigBuilder().addPart(" Placeholder settings {" + placeholderString + "} returns"); + YamlBuilder.YamlSectionPart placeholderSection = new YamlBuilder.YamlSectionPart(placeholderString); + placeholderSection.addPart(" Default return value"); + placeholderSection.addPart("default", replacerVal.getDefaultOutput()); + getConfigBuilder().addPart(placeholderSection); + getConfigBuilder().addEmptyPart(); + } + } + } + + public boolean isOffline(String placeholder) { + return (!getPlaceholderReplacer(placeholder).isOnline()); + } + + public String getName() { + return name; + } + + /** + * Set placeholder name + * + * @param name Name + */ + public void setName(String name) { + this.name = name; + } + + /** + * Remove a placeholder replacer + * + * @param placeholder PlaceholderPack + */ + public void removePlaceholder(String placeholder) { + placeholders.remove(placeholder); + } + + public List getPlaceholderConditions() { + return placeholderConditions; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public boolean isActionPlaceholder() { + return actionPlaceholder; + } + + public void setActionPlaceholder(boolean actionPlaceholder) { + this.actionPlaceholder = actionPlaceholder; + } + + public boolean hasWildcards() { + return containsWildcards; + } + + public void setContainsWildcards(boolean containsWildcards) { + this.containsWildcards = containsWildcards; + } + + public String getDescription() { + return description; + } + + private void setDescription(String description) { + this.description = description; + } + + public String getPluginURL() { + return pluginURL; + } + + private void setPluginURL(String pluginURL) { + this.pluginURL = pluginURL; + } + + public YamlBuilder getConfigBuilder() { + return configBuilder; + } + + public void setConfigBuilder(YamlBuilder configBuilder) { + this.configBuilder = configBuilder; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public File getJarFile() { + return jarFile; + } + + public void setJarFile(File jarFile) { + this.jarFile = jarFile; + } + + public boolean isModule() { + return module; + } + + public void setModule(boolean module) { + this.module = module; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getActionName() { + return actionName; + } + + public void setActionName(String actionName) { + this.actionName = actionName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + /** + * Get config version + * + * @return config version + */ + public int getConfigVersion() { + return configVersion; + } + + /** + * Set config version + * + * @param configVersion config version + */ + public void setConfigVersion(int configVersion) { + this.configVersion = configVersion; + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/PlaceholderPlugin.java b/src/main/java/be/maximvdw/placeholderapi/internal/PlaceholderPlugin.java new file mode 100644 index 0000000..948c48f --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/PlaceholderPlugin.java @@ -0,0 +1,47 @@ +package be.maximvdw.placeholderapi.internal; + +import org.bukkit.OfflinePlayer; + +import java.util.List; + +/** + * PlaceholderPlugin + * Created by Maxim on 2/11/2017. + */ +public interface PlaceholderPlugin { + /** + * Get placeholder result + * + * @param input + * @param player + * @return + */ + String getPlaceholderResult(String input, OfflinePlayer player); + + /** + * Get a list of all placeholders + * + * @return PlaceholderPack list + */ + List getPlaceholderPacks(); + + /** + * Get enabled placeholder count + * + * @return amount + */ + int getPlaceHolderEnabledCount(); + + /** + * Get placeholder count + * @return placeholder count + */ + int getPlaceHolderCount(); + + /** + * Register a placeholderPack + * + * @param placeholderPack Place holder + */ + void registerPlaceHolder(PlaceholderPack placeholderPack); +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/PlaceholderReplacer.java b/src/main/java/be/maximvdw/placeholderapi/internal/PlaceholderReplacer.java new file mode 100644 index 0000000..6177c9d --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/PlaceholderReplacer.java @@ -0,0 +1,162 @@ +package be.maximvdw.placeholderapi.internal; + +import be.maximvdw.placeholderapi.PlaceholderReplaceEvent; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +public abstract class PlaceholderReplacer { + private String description = ""; + private boolean online = true; + private boolean requiresPlayer = false; + protected Object[] args = null; + private Class returnType = null; + private DataType dataType = DataType.NORMAL; + private T defaultOutput = null; + private String defaultTrueOutput = null; + private String defaultFalseOutput = null; + private boolean relationalPlaceholder = false; + + public PlaceholderReplacer(Class type) { + this.returnType = type; + } + + public PlaceholderReplacer(Class type, Object... args) { + this.returnType = type; + this.args = args; + } + + /** + * Get the return class type + * + * @return class type + */ + public Class getReturnType() { + return returnType; + } + + /** + * Get description + * + * @return Description + */ + public String getDescription() { + return description; + } + + /** + * Set placeholder description + * + * @param description Description + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * Get placeholder result + * + * @param event Placeholder replace event + * @return placeholder result + */ + public T getResult(PlaceholderReplaceEvent event){ + // Will be implemented by newer placeholder versions + // Will not be called by older versions + // Compensated by redirecting to older call + // Because one of these three "getResult" functions will be implemented + // it is not going to cause a recursive loop + return this.getResult(event.getPlaceholder(), event.getOfflinePlayer()); + } + + @Deprecated + public T getResult(String placeholder, OfflinePlayer player){ + PlaceholderReplaceEvent replaceEvent = new PlaceholderReplaceEvent(player,placeholder); + return this.getResult(replaceEvent); + } + + /** + * Get placeholder result + * + * @param player + * Player + * @return placeholder result + */ + @Deprecated + public T getResult(String placeholder, Player player){ + PlaceholderReplaceEvent replaceEvent = new PlaceholderReplaceEvent(player,placeholder); + return this.getResult(replaceEvent); + } + + public Object[] getArguments() { + return args; + } + + /** + * Check if a player is required + * + * @return requires player + */ + public boolean isPlayerRequired() { + return requiresPlayer; + } + + public void setRequiresPlayer(boolean requiresPlayer) { + this.requiresPlayer = requiresPlayer; + } + + public boolean isOnline() { + return online; + } + + public void setOnline(boolean online) { + this.online = online; + } + + public PlaceholderReplacer setDataType(DataType type) { + this.dataType = type; + return this; + } + + public DataType getDataType() { + return dataType; + } + + public T getDefaultOutput() { + return defaultOutput; + } + + public PlaceholderReplacer setDefaultOutput(T defaultOutput) { + this.defaultOutput = defaultOutput; + return this; + } + + public String getDefaultTrueOutput() { + return defaultTrueOutput; + } + + public PlaceholderReplacer setDefaultTrueOutput(String defaultTrueOutput) { + this.defaultTrueOutput = defaultTrueOutput; + return this; + } + + public PlaceholderReplacer isRelationalPlaceholder(boolean relationalPlaceholder) { + this.relationalPlaceholder = relationalPlaceholder; + return this; + } + + public boolean isRelationalPlaceholder() { + return this.relationalPlaceholder; + } + + public String getDefaultFalseOutput() { + return defaultFalseOutput; + } + + public PlaceholderReplacer setDefaultFalseOutput(String defaultFalseOutput) { + this.defaultFalseOutput = defaultFalseOutput; + return this; + } + + public enum DataType { + NORMAL, BOOLEAN, UNIXTIME + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleActionName.java b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleActionName.java new file mode 100644 index 0000000..2435ffa --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleActionName.java @@ -0,0 +1,21 @@ +package be.maximvdw.placeholderapi.internal.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * ModuleActionName + * + * Created by maxim on 15-Jan-17. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ModuleActionName { + /** + * Module action name + * @return value + */ + String value(); +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleAuthor.java b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleAuthor.java new file mode 100644 index 0000000..75362ac --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleAuthor.java @@ -0,0 +1,21 @@ +package be.maximvdw.placeholderapi.internal.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * ModuleAuthor + * + * Created by maxim on 15-Jan-17. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ModuleAuthor { + /** + * Module author + * @return value + */ + String value(); +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleConstraint.java b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleConstraint.java new file mode 100644 index 0000000..1f55002 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleConstraint.java @@ -0,0 +1,94 @@ +package be.maximvdw.placeholderapi.internal.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Module Constraint + *

+ * Created by maxim on 15-Jan-17. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ModuleConstraint { + /** + * Constraint type of the module + */ + ContraintType type(); + + /** + * Constraint value + * + * @return constraint value + */ + String value(); + + /** + * Module constraint type + */ + enum ContraintType { + /** + * Make sure this plugin is loaded + */ + PLUGIN(1, "Plugin"), + /** + * Make sure the plugin CONTAINS this version string + */ + PLUGIN_VERSION(3, "Plugin version"), + /** + * Make sure the plugin version is lower + */ + PLUGIN_VERSION_IS_LOWER(4, "Plugin version lower"), + /** + * Make sure the plugin version is higher + */ + PLUGIN_VERSION_IS_HIGHER(5, "Plugin version higher"), + /** + * Make sure the plugin has this class for main (written like in plugin.yml) + */ + PLUGIN_MAIN(6, "Plugin main"), + /** + * Make sure the plugin has the following author + */ + PLUGIN_AUTHOR(7, "Plugin author"), + /** + * PlaceholderAPIBungee version higher + */ + PLACEHOLDERAPI_VERSION(2, "PlaceholderAPIBungee version"), + SERVER_VERSION_IS_LOWER(1,"Server version is lower"), + SERVER_VERSION_IS_HIGHER(1,"Server version is higher"), + /** + * Required module + */ + MODULE(3,"Module"), + MODULE_VERSION(4,"Module version"), + MODULE_VERSION_IS_LOWER(5,"Module version lower"), + MODULE_VERSION_IS_HIGHER(6,"Module version higher"); + + private int priority = 0; + private String name = ""; + + ContraintType(int priority, String name) { + setPriority(priority); + setName(name); + } + + public int getPriority() { + return priority; + } + + public void setPriority(int priority) { + this.priority = priority; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleConstraintComparator.java b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleConstraintComparator.java new file mode 100644 index 0000000..d233c28 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleConstraintComparator.java @@ -0,0 +1,17 @@ +package be.maximvdw.placeholderapi.internal.annotations; + +import java.util.Comparator; + +/** + * ModuleConstraintComparator + * + * Created by maxim on 25-Jan-17. + */ +public class ModuleConstraintComparator implements Comparator{ + @Override + public int compare(ModuleConstraint o1, ModuleConstraint o2) { + int priority1 = o1.type().getPriority(); + int priority2 = o2.type().getPriority(); + return priority1 > priority2 ? 1 : priority1 < priority2 ? -1 : 0; + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleConstraints.java b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleConstraints.java new file mode 100644 index 0000000..10c87bf --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleConstraints.java @@ -0,0 +1,17 @@ +package be.maximvdw.placeholderapi.internal.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Module Constraints + *

+ * Created by maxim on 15-Jan-17. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ModuleConstraints { + ModuleConstraint[] value(); +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleDescription.java b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleDescription.java new file mode 100644 index 0000000..4dc7fd1 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleDescription.java @@ -0,0 +1,21 @@ +package be.maximvdw.placeholderapi.internal.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * ModuleDescription + * + * Created by maxim on 15-Jan-17. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ModuleDescription { + /** + * Module description + * @return value + */ + String value(); +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleIdentifier.java b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleIdentifier.java new file mode 100644 index 0000000..b22b324 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleIdentifier.java @@ -0,0 +1,21 @@ +package be.maximvdw.placeholderapi.internal.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * ModuleIdentifier + * + * Created by maxim on 15-Jan-17. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ModuleIdentifier { + /** + * Module identifier + * @return value + */ + String value(); +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleName.java b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleName.java new file mode 100644 index 0000000..5e94b86 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleName.java @@ -0,0 +1,21 @@ +package be.maximvdw.placeholderapi.internal.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * ModuleName + * + * Created by maxim on 15-Jan-17. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ModuleName { + /** + * Module name + * @return value + */ + String value(); +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModulePermalink.java b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModulePermalink.java new file mode 100644 index 0000000..5ad2735 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModulePermalink.java @@ -0,0 +1,22 @@ +package be.maximvdw.placeholderapi.internal.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * ModulePermalink + *

+ * Created by maxim on 16-Jan-17. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ModulePermalink { + /** + * Module permalink + * + * @return value + */ + String value(); +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleScreenshots.java b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleScreenshots.java new file mode 100644 index 0000000..86f1f75 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleScreenshots.java @@ -0,0 +1,22 @@ +package be.maximvdw.placeholderapi.internal.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * ModuleScreenshots + *

+ * Created by maxim on 16-Jan-17. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ModuleScreenshots { + /** + * Screenshot links + * + * @return screenshot links + */ + String[] value(); +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleVersion.java b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleVersion.java new file mode 100644 index 0000000..1403016 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleVersion.java @@ -0,0 +1,21 @@ +package be.maximvdw.placeholderapi.internal.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * ModuleVersion + * + * Created by maxim on 15-Jan-17. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ModuleVersion { + /** + * Module version + * @return value + */ + String value(); +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleVersionChange.java b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleVersionChange.java new file mode 100644 index 0000000..5cf2272 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleVersionChange.java @@ -0,0 +1,29 @@ +package be.maximvdw.placeholderapi.internal.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * ModuleVersionChange + *

+ * Created by maxim on 15-Jan-17. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ModuleVersionChange { + /** + * Version of change + * + * @return version + */ + String version(); + + /** + * Module changelog + * + * @return value + */ + String value(); +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleVersionChanges.java b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleVersionChanges.java new file mode 100644 index 0000000..a6bd50e --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleVersionChanges.java @@ -0,0 +1,17 @@ +package be.maximvdw.placeholderapi.internal.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * ModuleVersionChanges + *

+ * Created by maxim on 16-Jan-17. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ModuleVersionChanges { + ModuleVersionChange[] value(); +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleVideos.java b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleVideos.java new file mode 100644 index 0000000..865e9a6 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/annotations/ModuleVideos.java @@ -0,0 +1,22 @@ +package be.maximvdw.placeholderapi.internal.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * ModuleVideos + *

+ * Created by maxim on 16-Jan-17. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ModuleVideos { + /** + * Videos links + * + * @return videos links + */ + String[] value(); +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/eventhooks/BaseEventHook.java b/src/main/java/be/maximvdw/placeholderapi/internal/eventhooks/BaseEventHook.java new file mode 100644 index 0000000..6898f33 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/eventhooks/BaseEventHook.java @@ -0,0 +1,245 @@ +package be.maximvdw.placeholderapi.internal.eventhooks; + +import be.maximvdw.placeholderapi.internal.storage.YamlBuilder; +import be.maximvdw.placeholderapi.internal.storage.YamlBuilder.YamlEmptyPart; +import be.maximvdw.placeholderapi.internal.storage.YamlStorage; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; +import org.bukkit.plugin.Plugin; + +import java.util.HashMap; +import java.util.Map; + +public abstract class BaseEventHook implements Listener { + private static Map hooks = new HashMap<>(); + private Map eventConditions = new HashMap(); + /* Plugin information */ + private String name = ""; + private String url = ""; + private String description = ""; + private String shortName = ""; + private String when = ""; + private String who = ""; + private boolean enabled = true; + + private Map placeholders = new HashMap(); + + private YamlBuilder configTemplate = null; + private int configVersion = 1; + private Plugin plugin = null; + + private YamlStorage storage = null; + + // TODO: Workaround legacy + private Object legacyPlugin = null; + + public BaseEventHook(Plugin plugin, String shortName, int version) { + setPlugin(plugin); + this.legacyPlugin = plugin.getClass().getProtectionDomain().getCodeSource().getLocation(); + setShortName(shortName); + this.configVersion = version; + } + + public int getConfigVersion() { + return configVersion; + } + + public Map getEventConditions() { + return this.eventConditions; + } + + public void loadConfig() { + if (storage.getConfig().getBoolean("enabled")) { + setEnabled(true); + } else { + setEnabled(false); + } + } + + public abstract void start(); + + public void generateConfig() { + if (getConfigTemplate() == null) { + YamlBuilder builder = new YamlBuilder(); + builder.addPart("----------------------------------------"); + builder.addPart(" " + getName()); + builder.addPart(" " + getDescription()); + builder.addPart(" " + getUrl()); + builder.addPart("----------------------------------------"); + builder.addPart(new YamlEmptyPart()); + builder.addPart(" DO NOT EDIT THIS CONFIG VERSION!"); + builder.addPart("config", configVersion); + builder.addPart(new YamlEmptyPart()); + builder.addPart(new YamlEmptyPart()); + builder.addPart(" Do you want to enable this event hook?"); + builder.addPart(" Enabling this hook will trigger"); + builder.addPart(" when " + getWhen()); + builder.addPart(" for " + getWho()); + builder.addPart("enabled", false); + builder.addPart(new YamlEmptyPart()); + builder.addPart(" What do you want to trigger?"); + builder.addPart("trigger", "default"); + builder.addPart(new YamlEmptyPart()); + builder.addPart(new YamlEmptyPart()); + setConfigTemplate(builder); + } + } + + public void enableEvent(Player player) { + TriggerEvent event = getHook(legacyPlugin); + if (event != null) + event.enableEvent(player, getConfig().getString("trigger")); + } + + public void disableEvent(Player player) { + TriggerEvent event = getHook(legacyPlugin); + if (event != null) + event.disableEvent(player, getConfig().getString("trigger")); + } + + @Deprecated + public static void registerTriggerEvent(TriggerEvent event) { + // TODO: Workaround for backwards compatibility. Replace with plugin in the future + Object plugin = event.getClass().getProtectionDomain().getCodeSource().getLocation(); + hooks.put(plugin, event); + } + + public static TriggerEvent getHook(Object plugin) { + return hooks.get(plugin); + } + + /** + * Get config + * + * @return Config + */ + public YamlConfiguration getConfig() { + return storage.getConfig(); + } + + /** + * Get event hook name + * + * @return Hook name + */ + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getShortName() { + return shortName; + } + + public void setShortName(String shortName) { + this.shortName = shortName; + } + + public YamlStorage getStorage() { + return storage; + } + + public void setStorage(YamlStorage storage) { + this.storage = storage; + } + + public String getWhen() { + return when; + } + + public void setWhen(String action) { + this.when = action; + } + + public String getWho() { + return who; + } + + public void setWho(String playersAction) { + this.who = playersAction; + } + + public YamlBuilder getConfigTemplate() { + return configTemplate; + } + + public void setConfigTemplate(YamlBuilder configTemplate) { + this.configTemplate = configTemplate; + } + + public Plugin getPlugin() { + return plugin; + } + + public void setPlugin(Plugin plugin) { + this.plugin = plugin; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + /** + * Add a placeholder condition + * + * @param condition Condition + * @param value Value + */ + public BaseEventHook addCondition(EventCondition condition, String value) { + eventConditions.put(condition, value); + return this; + } + + public Map getPlaceholders() { + return placeholders; + } + + public void setPlaceholders(Map placeholders) { + this.placeholders = placeholders; + } + + public static enum EventCondition { + PLUGIN, VERSION, AUTHOR, OFFLINEPLAYER, PLAYER, MAIN, VERSION_IS_LOWER, VERSION_IS_HIGHER + } + + public class EventPlaceholderContainer { + private Map placeholders = new HashMap(); + + public Map getPlaceholders() { + return placeholders; + } + + public void setPlaceholders(Map placeholders) { + this.placeholders = placeholders; + } + + public EventPlaceholderContainer addStaticPlaceholder(String key, Object value) { + placeholders.put(key, value); + return this; + } + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/eventhooks/TriggerEvent.java b/src/main/java/be/maximvdw/placeholderapi/internal/eventhooks/TriggerEvent.java new file mode 100644 index 0000000..f1d8361 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/eventhooks/TriggerEvent.java @@ -0,0 +1,9 @@ +package be.maximvdw.placeholderapi.internal.eventhooks; + +import org.bukkit.entity.Player; + +public interface TriggerEvent { + void enableEvent(Player player, String action); + + void disableEvent(Player player, String action); +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/hooks/PluginHook.java b/src/main/java/be/maximvdw/placeholderapi/internal/hooks/PluginHook.java new file mode 100644 index 0000000..ad975ad --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/hooks/PluginHook.java @@ -0,0 +1,30 @@ +package be.maximvdw.placeholderapi.internal.hooks; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; + +public class PluginHook { + /** + * Check if a plugin is loaded + * + * @param pluginName + * Plugin name + * @return Plugin loaded + */ + public static boolean isLoaded(String pluginName) { + Plugin pl = Bukkit.getPluginManager().getPlugin(pluginName); + return pl != null; + } + + /** + * Laod plugin + * + * @param pluginName + * Plugin name + * @return Plugin + */ + public static Plugin loadPlugin(String pluginName) { + Plugin pl = Bukkit.getPluginManager().getPlugin(pluginName); + return pl; + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/storage/YamlBuilder.java b/src/main/java/be/maximvdw/placeholderapi/internal/storage/YamlBuilder.java new file mode 100644 index 0000000..d6d1279 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/storage/YamlBuilder.java @@ -0,0 +1,388 @@ +package be.maximvdw.placeholderapi.internal.storage; + +import be.maximvdw.placeholderapi.internal.utils.NumberUtils; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; + +/** + * YamlBuilder + *

+ * YAML Builder + * + * @author Maxim Van de Wynckel (Maximvdw) + * @version 25-08-2014 + * @project MVdW Software Plugin Interface + * @site http://www.mvdw-software.be/ + */ +public class YamlBuilder extends YamlSection { + private int idx = 0; + + public YamlBuilder() { + + } + + public YamlBuilder(String config, int indentSpaces) { + try (BufferedReader br = new BufferedReader(new StringReader(config))) { + String line; + List lines = new ArrayList<>(); + while ((line = br.readLine()) != null) { + lines.add(line); + } + for (int i = idx; i < lines.size(); i++) { + YamlPart part = readPart(null, lines, 0, indentSpaces); + if (part != null) { + addPart(part); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + public YamlPart readPart(YamlSection parent, List lines, int level, int indentSpaces) throws IOException { + if (idx >= lines.size()) { + return parent; + } + String comment = null; + String line = lines.get(idx); + if (line.contains("#")) { + comment = line.substring(line.indexOf("#", 0) + 1); + line = line.substring(0, line.indexOf("#", 0)); + } + + String tabCheck = ""; + for (int i = 0; i < level; i++) { + tabCheck += " "; + } + + if (line.trim().equals("") && comment != null) { + if (!line.startsWith(tabCheck)) { + return parent; + } + // Comment + if (parent == null) { + idx++; + return new YamlCommentPart(comment); + } else { + parent.addPart(comment); + idx++; + return readPart(parent, lines, level, indentSpaces); + } + } else if (line.trim().equals("")) { + // Empty line + if (parent == null) { + idx++; + return new YamlEmptyPart(); + } else { + parent.addEmptyPart(); + idx++; + return readPart(parent, lines, level, indentSpaces); + } + } else { + if (line.trim().startsWith("-")) { + // List + YamlStringListPart newParent = new YamlStringListPart(((YamlSectionPart) parent).getKey()); + return readList(newParent, lines); + } else if (line.contains(":")) { + if (!line.startsWith(tabCheck)) { + return parent; + } + // Key/value or section + if (line.trim().endsWith(":")) { + // Section + YamlSection newParent = new YamlSectionPart(line.trim().substring(0, line.trim().length() - 1)); + if (parent == null) { + idx++; + return readPart(newParent, lines, level + 1, indentSpaces); + } else { + idx++; + YamlPart part = readPart(newParent, lines, level + 1, indentSpaces); + if (part != null) { + parent.addPart(part); + } + return readPart(parent, lines, level, indentSpaces); + } + } else { + String key = line.trim().substring(0, line.trim().indexOf(":", 0)); + String value = line.trim().substring(key.length() + 1).trim(); + if ((value.startsWith("\"") && value.endsWith("\"")) || (value.startsWith("'") && value.endsWith("'"))) { + // String + value = value.substring(1, value.length() - 1); + if (parent == null) { + idx++; + return new YamlKeyValuePart(key, value); + } else { + parent.addPart(key, value); + idx++; + return readPart(parent, lines, level, indentSpaces); + } + } else if (value.equals("true") || value.equals("false")) { + boolean valueBool = Boolean.valueOf(value); + if (parent == null) { + idx++; + return new YamlKeyValuePart(key, valueBool); + } else { + parent.addPart(key, valueBool); + idx++; + return readPart(parent, lines, level, indentSpaces); + } + } else { + // Something else + if (NumberUtils.isInteger(value)) { + if (parent == null) { + idx++; + return new YamlKeyValuePart(key, Integer.parseInt(value)); + } else { + parent.addPart(key, Integer.parseInt(value)); + idx++; + return readPart(parent, lines, level, indentSpaces); + } + } else if (NumberUtils.isNumber(value)) { + if (parent == null) { + idx++; + return new YamlKeyValuePart(key, Double.parseDouble(value)); + } else { + parent.addPart(key, Double.parseDouble(value)); + idx++; + return readPart(parent, lines, level, indentSpaces); + } + } + } + } + } + } + return new YamlEmptyPart(); + } + + private YamlStringListPart readList(YamlStringListPart list, List lines) throws IOException { + if (idx >= lines.size()) { + return list; + } + String line = lines.get(idx); + if (line.trim().startsWith("-")) { + String item = line.trim().substring(1).trim().substring(1); + item = item.substring(0, item.length() - 1); + list.addItem(item); + idx++; + return readList(list, lines); + } else { + return list; + } + } + + + public boolean writeToFile(File file) { + FileOutputStream fop = null; + + try { + fop = new FileOutputStream(file); + + // if file doesnt exists, then create it + if (!file.exists()) { + file.createNewFile(); + } + + // get the content in bytes + byte[] contentInBytes = toString().getBytes(); + + fop.write(contentInBytes); + fop.flush(); + fop.close(); + + } catch (IOException e) { + e.printStackTrace(); + return false; + } finally { + try { + if (fop != null) { + fop.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return true; + } + + + public static class YamlCommentPart extends YamlPart { + private String comment = ""; + + public YamlCommentPart(String comment) { + setComment(comment); + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + + @Override + public String toString() { + return "#" + comment; + } + } + + public static class YamlKeyValuePart extends YamlPart { + private String key = ""; + private Object value = ""; + + public YamlKeyValuePart(String key, Object value) { + setKey(key); + setValue(value); + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + @Override + public String toString() { + if (value instanceof String) { + return new YamlStringPart(key, value.toString()).toString(); + } + return getKey() + ": " + value; + } + + public void loadConfig(String path, YamlConfiguration config) { + setValue(config.get(path.equals("") ? getKey() : path + "." + getKey())); + } + + public void loadNewConfig(String path, String key, YamlConfiguration config) { + setValue(config.get(path.equals("") ? getKey() : path + "." + key)); + setKey(key); + } + } + + public static class YamlStringPart extends YamlKeyValuePart { + + public YamlStringPart(String key, String value) { + super(key, value); + } + + @Override + public String toString() { + return getKey() + ": \"" + sanitize(getValue().toString()) + "\""; + } + } + + public static class YamlIntegerPart extends YamlKeyValuePart { + + public YamlIntegerPart(String key, int value) { + super(key, value); + } + + } + + public static class YamlEmptyPart extends YamlPart { + @Override + public String toString() { + return ""; + } + } + + public static class YamlStringListPart extends YamlPart { + private String key = ""; + private List items = new ArrayList(); + + public YamlStringListPart(String key) { + setKey(key); + } + + public YamlStringListPart addItem(String item) { + items.add(item); + return this; + } + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public void loadConfig(String path, YamlConfiguration config) { + setItems(config.getStringList(path.equals("") ? getKey() : path + "." + getKey())); + } + + public void loadNewConfig(String path, String key, YamlConfiguration config) { + setKey(key); + setItems(config.getStringList(path.equals("") ? getKey() : path + "." + getKey())); + } + + public String toString() { + String result = getKey() + ": "; + if (getItems().size() == 0) + result += "[]" + System.getProperty("line.separator"); + else { + result += System.getProperty("line.separator"); + for (String item : getItems()) { + result += "- \"" + sanitize(item) + "\"" + System.getProperty("line.separator"); + + } + } + return result; + } + } + + public static class YamlSectionPart extends YamlSection { + private String key = ""; + + public YamlSectionPart(String key) { + setKey(key); + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String toString() { + String result = getKey() + ":" + System.getProperty("line.separator"); + for (YamlPart part : getParts()) { + String[] lines = part.toString().split(System.getProperty("line.separator")); + for (String line : lines) { + result += " " + line + System.getProperty("line.separator"); + } + } + + return result; + } + } + + private static String sanitize(String input) { + String output = input; + output = output.replace("\"", "\\\""); + return output; + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/storage/YamlPart.java b/src/main/java/be/maximvdw/placeholderapi/internal/storage/YamlPart.java new file mode 100644 index 0000000..be792f3 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/storage/YamlPart.java @@ -0,0 +1,38 @@ +package be.maximvdw.placeholderapi.internal.storage; + +public class YamlPart { + private YamlPart parent = null; + + /** + * Get parrent + * + * @return parrent + */ + public YamlPart parent() { + return parent; + } + + public void setParent(YamlPart parent){ + this.parent = parent; + } + + /** + * Get builder + * + * @return + */ + public YamlPart builder() { + YamlBuilder builder = null; + + YamlPart lastPart = parent; + do { + if (lastPart instanceof YamlBuilder) { + builder = (YamlBuilder) lastPart; + } else { + lastPart = lastPart.parent(); + } + } while (builder == null); + + return builder; + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/storage/YamlSection.java b/src/main/java/be/maximvdw/placeholderapi/internal/storage/YamlSection.java new file mode 100644 index 0000000..830e5a2 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/storage/YamlSection.java @@ -0,0 +1,172 @@ +package be.maximvdw.placeholderapi.internal.storage; + +import be.maximvdw.placeholderapi.internal.storage.YamlBuilder.*; + +import java.util.ArrayList; +import java.util.List; + +public class YamlSection extends YamlPart{ + // Yaml parts + private List parts = new ArrayList(); + + /** + * Add a YAML part + * + * @param part + * YAML part + * @return Yaml Builder + */ + public YamlSection addPart(YamlPart part) { + part.setParent(this); + parts.add(part); + return this; + } + + /** + * Add a YAML part + * + * @param part + * comment + * @return Yaml Builder + */ + public YamlSection addPart(String comment) { + addPart(new YamlCommentPart(comment)); + return this; + } + + /** + * Add an empty YAML part + * + * @return Yaml builder + */ + public YamlSection addEmptyPart() { + addPart(new YamlEmptyPart()); + return this; + } + + /** + * Add a part + * + * @param key + * Key + * @param value + * Value + * @return YamlBuilder + */ + public YamlSection addPart(String key, Object value) { + addPart(new YamlKeyValuePart(key, value)); + return this; + } + + /** + * Add a yaml section + * @param section section + * @return Yaml section part + */ + public YamlSection addSection(String section){ + YamlSectionPart sectionPart = new YamlSectionPart(section); + sectionPart.setParent(this); + addPart(sectionPart); + return sectionPart; + } + + /** + * Add a YAML part + * + * @param part + * comment + * @return Yaml Builder + */ + public YamlSection comment(String comment){ + addPart(comment); + return this; + } + + /** + * Create a list + * @param name list name + * @return list name + */ + public YamlStringListPart list(String name){ + YamlStringListPart list = new YamlStringListPart(name); + addPart(list); + return list; + } + + /** + * Get Value + * + * @param path + * Path + * @return Object + */ + public Object getValue(String path) { + String[] keys = path.split("."); + if (keys.length == 0) + return null; + for (YamlPart part : getParts()) { + if (part instanceof YamlSectionPart) { + if (keys.length > 1) { + String newPath = keys[1]; + for (int i = 2; i < keys.length; i++) { + newPath += "." + keys[i]; + } + return getValue(newPath); + } else { + return null; + } + } else if (part instanceof YamlKeyValuePart && keys.length == 1) { + if (((YamlKeyValuePart) part).getKey().equalsIgnoreCase(keys[0])) { + return ((YamlKeyValuePart) part).getValue(); + } + } + } + + return null; + } + + + /** + * Does the yaml part has parts + * + * @return Parts + */ + public boolean hasParts() { + return parts.size() > 0; + } + + + /** + * Get YAML Parts + * + * @return yaml parts + */ + public List getParts(){ + return parts; + } + + /** + * Set YAML Parts + * + * @param parts + * yaml parts + */ + public void setParts(List parts){ + this.parts = parts; + } + + @Override + public String toString(){ + String result = ""; + for (YamlPart part : getParts()) { + result += part.toString() + System.getProperty("line.separator"); + } + return result; + } + + public String toCode(){ + String code = ""; + + return code; + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/storage/YamlStorage.java b/src/main/java/be/maximvdw/placeholderapi/internal/storage/YamlStorage.java new file mode 100644 index 0000000..d09b134 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/storage/YamlStorage.java @@ -0,0 +1,337 @@ +package be.maximvdw.placeholderapi.internal.storage; + +import be.maximvdw.placeholderapi.internal.ui.SendConsole; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.Plugin; + +import java.io.*; +import java.util.Date; + +/** + * YamlStorage + *

+ * YAML File storage + * + * @author Maxim Van de Wynckel (Maximvdw) + * @version 12-04-2014 + * @project MVdW Software Plugin Interface + * @site http://www.mvdw-software.be/ + */ +public class YamlStorage { + private Plugin plugin = null; // Plugin instance + private String configName = ""; // Configuration name + private String pluginFolder = ""; // Plugin folder + private String folder = ""; // Folder + private String resourceFolder = ""; // Resource folder + private boolean resources = false; + private int configVersion = -1; + private YamlBuilder template = null; + + /** + * Initialize the Yaml Configuration + * + * @param plugin Plugin + */ + public YamlStorage(Plugin plugin, String configName) { + this(plugin, "", configName); + } + + /** + * Initialize the Yaml Configuration + * + * @param plugin Plugin + */ + public YamlStorage(Plugin plugin, String folder, String configName) { + this(plugin, folder, configName, false); + } + + /** + * Initialize the Yaml Configuration + * + * @param plugin Plugin + */ + public YamlStorage(Plugin plugin, String folder, String configName, boolean resources) { + this(plugin, folder, configName, resources, 0); + } + + /** + * Initialize the Yaml Configuration + * + * @param plugin Plugin + */ + public YamlStorage(Plugin plugin, String folder, String configName, boolean resources, int version, int errorLevel) { + this.plugin = plugin; + this.folder = folder; + this.configName = configName; + this.resources = resources; + this.setConfigVersion(version); + loadConfig(errorLevel); + if (version != -1) + if (getConfig().getInt("config") < version) { + updateConfig(); + } + } + + + /** + * Initialize the Yaml Configuration + * + * @param plugin Plugin + */ + public YamlStorage(Plugin plugin, String folder, String configName, boolean resources, int version) { + this(plugin, folder, configName, resources, version, 0); + } + + + /** + * Initialize the Yaml Configuration + * + * @param plugin Plugin + */ + public YamlStorage(Plugin plugin, String folder, String configName, int version, YamlBuilder builder) { + this(plugin, folder, configName, version, builder, 0); + } + + /** + * Initialize the Yaml Configuration + * + * @param plugin Plugin + */ + public YamlStorage(Plugin plugin, String folder, String configName, int version, YamlBuilder builder, int errorLevel) { + this.plugin = plugin; + this.folder = folder; + this.configName = configName; + setTemplate(builder); + + loadConfig(errorLevel); + if (getConfig().getInt("config") < version) { + updateConfig(); + } + } + + /** + * Initialize the Yaml Configuration + * + * @param plugin Plugin + */ + public YamlStorage(Plugin plugin, String folder, String configName, String resourceFolder, boolean resources) { + this.plugin = plugin; + this.folder = folder; + this.configName = configName; + this.resourceFolder = resourceFolder; + this.resources = resources; + loadConfig(); + } + + /** + * Initialize the Yaml Configuration + * + * @param plugin Plugin + */ + public YamlStorage(Plugin plugin, String folder, String configName, String resourceFolder, boolean resources, + int version) { + this(plugin, folder, configName, resourceFolder, resources, version, 0); + } + + public YamlStorage(Plugin plugin, String folder, String configName, String resourceFolder, boolean resources, + int version, int errorLevel) { + this.plugin = plugin; + this.folder = folder; + this.configName = configName; + this.resourceFolder = resourceFolder; + this.resources = resources; + this.setConfigVersion(version); + loadConfig(errorLevel); + if (getConfig().getInt("config") < version) { + updateConfig(); + } + } + + /** + * Initialize the Yaml Configuration + * + * @param plugin Plugin + */ + public YamlStorage(String pluginFolder, String folder, String configName) { + this.folder = folder; + this.pluginFolder = pluginFolder; + this.configName = configName; + loadConfig(); + } + + // Yaml Configuration + private YamlConfiguration pluginConfig; + private File configFile; + private boolean loaded = false; + + /** + * Gets the configuration file. + * + * @return the myConfig + */ + public YamlConfiguration getConfig() { + if (!loaded) { + loadConfig(); + } + return pluginConfig; + } + + /** + * Gets the configuration file. + * + * @return Configuration file + */ + public File getConfigFile() { + return configFile; + } + + /** + * Get file contents + * + * @return Contents + */ + public String getContents() { + try { + FileInputStream fis = new FileInputStream(configFile); + byte[] data = new byte[(int) configFile.length()]; + fis.read(data); + fis.close(); + // + String s = new String(data, "UTF-8"); + return s; + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return ""; + } + + /** + * Loads the configuration file + */ + public void loadConfig() { + loadConfig(0); + } + + /** + * Loads the configuration file + */ + public void loadConfig(int errorLevel) { + if (plugin != null) + configFile = new File(plugin.getDataFolder() + "/" + folder, configName + ".yml"); + else + configFile = new File("plugins/" + pluginFolder + "/" + folder, configName + ".yml"); + if (configFile.exists()) { + pluginConfig = new YamlConfiguration(); + try { + pluginConfig.load(configFile); + } catch (FileNotFoundException ex) { + if (errorLevel < 1) + SendConsole.severe("Error in [" + configName + "] - File not found!"); + } catch (IOException ex) { + if (errorLevel < 2) + SendConsole.severe("Error in [" + configName + "] - Error while reading!"); + } catch (InvalidConfigurationException ex) { + if (errorLevel < 3) + SendConsole.severe("Error in [" + configName + "] - Corrupted YML!"); + ex.printStackTrace(); + } + loaded = true; + } else { + try { + InputStream jarURL = null; + if (plugin != null) { + plugin.getDataFolder().mkdir(); + new File(plugin.getDataFolder() + "/" + folder).mkdirs(); + jarURL = plugin.getClass().getResourceAsStream( + "/" + resourceFolder + (resourceFolder == "" ? "" : "/") + configName + ".yml"); + } else { + new File("plugins/" + pluginFolder + "/" + folder).mkdirs(); + } + if (jarURL != null) { + SendConsole.info("Copying '" + configFile + "' from the resources!"); + copyFile(jarURL, configFile); + } else { + if (!resources) { + SendConsole.info("Creating new file '" + configFile + "'!"); + configFile.createNewFile(); + if (getTemplate() != null) { + SendConsole.info("Using template for file '" + configFile + "' ..."); + getTemplate().writeToFile(getConfigFile()); + } + } else { + return; + } + } + + pluginConfig = new YamlConfiguration(); + pluginConfig.load(configFile); + loaded = true; + if (jarURL != null) { + jarURL.close(); + } + } catch (Exception e) { + if (errorLevel < 1) { + SendConsole.severe("Error while loading " + configFile + "!"); + e.printStackTrace(); + } + } + } + } + + /** + * Update configuration + */ + public void updateConfig() { + SendConsole.warning("Updating " + getConfigFile().getName() + "!"); + configFile.renameTo(new File((plugin == null ? "plugins/ " : plugin.getDataFolder()) + "/" + folder, + configFile.getName().replace(".yml", "") + new Date().getTime() + ".yml")); + configFile = null; + loadConfig(); + } + + /** + * Copies a file to a new location. + * + * @param in InputStream + * @param out File + * @throws Exception + */ + static private void copyFile(InputStream in, File out) throws Exception { + InputStream fis = in; + FileOutputStream fos = new FileOutputStream(out); + try { + byte[] buf = new byte[1024]; + int i = 0; + while ((i = fis.read(buf)) != -1) { + fos.write(buf, 0, i); + } + } catch (Exception e) { + throw e; + } finally { + if (fis != null) { + fis.close(); + } + if (fos != null) { + fos.close(); + } + } + } + + public int getConfigVersion() { + return configVersion; + } + + public void setConfigVersion(int configVersion) { + this.configVersion = configVersion; + } + + public YamlBuilder getTemplate() { + return template; + } + + public void setTemplate(YamlBuilder template) { + this.template = template; + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/ui/SendConsole.java b/src/main/java/be/maximvdw/placeholderapi/internal/ui/SendConsole.java new file mode 100644 index 0000000..bf9b4ce --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/ui/SendConsole.java @@ -0,0 +1,101 @@ +package be.maximvdw.placeholderapi.internal.ui; + +import be.maximvdw.placeholderapi.internal.utils.chat.ColorUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.plugin.Plugin; + +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * SendConsole + * + * Log to the console. + * + * @project BasePlugin + * @version 1.0 + * @author Maxim Van de Wynckel (Maximvdw) + * @site http://www.mvdw-software.be/ + */ +public class SendConsole { + static boolean enableLogging = false; // Enable logging + static String prefix = "[MVdW] "; // Message prefix + static Plugin plugin = null; // Plugin instance + + /** + * Initialize the console logger + * + * @param plugin + * Plugin + */ + public SendConsole(Plugin plugin) { + SendConsole.plugin = plugin; + SendConsole.prefix = "[" + plugin.getName() + "] "; + } + + /** + * Send a colored message to the console + * + * @param message + * Message + */ + public static void message(String message) { + ConsoleCommandSender console = SendConsole.plugin.getServer().getConsoleSender(); + console.sendMessage(ChatColor.translateAlternateColorCodes('&', message)); + } + + public static void stacktraceLog(Throwable ex) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + ex.printStackTrace(pw); + } + + public static void stacktrace(Throwable ex) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + ex.printStackTrace(pw); + severe(sw.toString()); + } + + /** + * Send an INFO message to the console + * + * @param message + * Info message + */ + public static void info(String message) { + if (plugin == null) + System.out.println(prefix + message); + else + Bukkit.getLogger().info(prefix + message); + } + + /** + * Send an WARNING message to the console + * + * @param message + * Warning message + */ + public static void warning(String message) { + if (plugin == null) + System.out.println(prefix + message); + else + Bukkit.getLogger().warning(prefix + message); + } + + /** + * Send an SEVERE message to the console + * + * @param message + * Severe message + */ + public static void severe(String message) { + message = ColorUtils.removeColors(message); // Remove colors + if (plugin == null) + System.out.println(prefix + message); + else + Bukkit.getLogger().severe(prefix + message); + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/ui/SendGame.java b/src/main/java/be/maximvdw/placeholderapi/internal/ui/SendGame.java new file mode 100644 index 0000000..41ead4b --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/ui/SendGame.java @@ -0,0 +1,100 @@ +package be.maximvdw.placeholderapi.internal.ui; + +import be.maximvdw.placeholderapi.internal.utils.bukkit.BukkitUtils; +import be.maximvdw.placeholderapi.internal.utils.chat.ColorUtils; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.entity.Player; +import java.util.Set; + +/** + * SendGame + *

+ * Send a message to ingame. + * + * @author Maxim Van de Wynckel (Maximvdw) + * @version 1.0 + * @project BasePlugin + * @site http://www.mvdw-software.be/ + */ +public class SendGame { + + /** + * Send a private message + * + * @param message Message to send + */ + public static void toPlayer(String message, Player player) { + message = ColorUtils.toColors(message); // Color the message + player.sendMessage(message); + } + + + /** + * Send a private message + * + * @param message Message to send + */ + public static void toPlayers(String message, Set players) { + for (Player player : players) { + toPlayer(message, player); + } + } + + + /** + * Send a private message + * + * @param message Message to send + * @param permission Permission + */ + public static void toPermission(String message, String permission) { + message = ColorUtils.toColors(message); // Color the message + Bukkit.broadcast(message, permission); + } + + /** + * Send a broadcast to the server + * + * @param message Message to broadcast + */ + public static void toServer(String message) { + message = ColorUtils.toColors(message); // Color the message + Bukkit.broadcastMessage(message); + } + + /** + * Send a message to a specific world + * + * @param message Message + * @param world World + */ + public static void toWorld(String message, World world) { + message = ColorUtils.toColors(message); // Color the message + for (Player player : BukkitUtils.getOnlinePlayers()) { + if (player.getWorld().equals(world)) { + player.sendMessage(message); + } + } + } + + /** + * Send a message to a specific world + * + * @param message Message + * @param world World + */ + public static void toWorldGroup(String message, World world) { + message = ColorUtils.toColors(message); // Color the message + for (Player player : BukkitUtils.getOnlinePlayers()) { + if (player.getWorld().equals(world) + || player.getWorld().equals( + Bukkit.getWorld(world.getName() + "_nether")) + || player.getWorld().equals( + Bukkit.getWorld(world.getName() + "_the_end"))) { + player.sendMessage(message); + } + } + } + +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/ui/SendUnknown.java b/src/main/java/be/maximvdw/placeholderapi/internal/ui/SendUnknown.java new file mode 100644 index 0000000..08c425f --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/ui/SendUnknown.java @@ -0,0 +1,31 @@ +package be.maximvdw.placeholderapi.internal.ui; + +import org.bukkit.entity.Player; + +/** + * SendUnknown + * + * Send a message to an unknown receiver. + * + * @project BasePlugin + * @version 1.0 + * @author Maxim Van de Wynckel (Maximvdw) + * @site http://www.mvdw-software.be/ + */ +public class SendUnknown { + /** + * Send a message to an unkown receiver + * + * @param message + * Message to send + * @param sender + * Reciever + */ + public static void toSender(String message, Object sender) { + if (sender instanceof Player) { + SendGame.toPlayer(message, (Player) sender); // Send to game + } else { + SendConsole.message(message); // Send to console + } + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/utils/DateUtils.java b/src/main/java/be/maximvdw/placeholderapi/internal/utils/DateUtils.java new file mode 100644 index 0000000..093fed3 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/utils/DateUtils.java @@ -0,0 +1,47 @@ +package be.maximvdw.placeholderapi.internal.utils; + +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class DateUtils { + public static String toString(Date date, String format) { + SimpleDateFormat sdf = new SimpleDateFormat(format); + return sdf.format(date); + } + + public static float nanosToSeconds(float nanos) { + return (float) (Math.round((nanos / 1000000000) * 100.0) / 100.0); + } + + public static float millisToSeconds(float millis) { + return (float) (Math.round((millis / 1000) * 100.0) / 100.0); + } + + public static String toString(long seconds, String format) { + Date date = new Date(seconds); + return toString(date, format); + } + + public static int[] splitToHMS(BigDecimal biggy) { + long longVal = biggy.longValue(); + int hours = (int) longVal / 3600; + int remainder = (int) longVal - hours * 3600; + int mins = remainder / 60; + remainder = remainder - mins * 60; + int secs = remainder; + + int[] ints = { hours, mins, secs }; + return ints; + } + + public static int[] splitToMS(BigDecimal biggy) { + long longVal = biggy.longValue(); + int mins = (int) (longVal / 60); + int remainder = (int) (longVal - (mins * 60)); + int secs = remainder; + + int[] ints = { mins, secs }; + return ints; + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/utils/HtmlResponse.java b/src/main/java/be/maximvdw/placeholderapi/internal/utils/HtmlResponse.java new file mode 100644 index 0000000..9cc7d77 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/utils/HtmlResponse.java @@ -0,0 +1,35 @@ +package be.maximvdw.placeholderapi.internal.utils; + +/** + * HtmlResponse + * + * HTML Utilities + * + * @project NMFC API + * @version 07-2014 + * @author Maxim Van de Wynckel (Maximvdw) + * @site http://www.mvdw-software.be/ + */ +public class HtmlResponse { + private String source = ""; + private int code = 0; + private String[] cookies = new String[0]; + + public HtmlResponse(String source, int code, String[] cookies) { + this.source = source; + this.code = code; + this.cookies = cookies; + } + + public String getSource() { + return source; + } + + public int getCode() { + return code; + } + + public String[] getCookies() { + return cookies; + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/utils/HtmlUtils.java b/src/main/java/be/maximvdw/placeholderapi/internal/utils/HtmlUtils.java new file mode 100644 index 0000000..3d66033 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/utils/HtmlUtils.java @@ -0,0 +1,187 @@ +package be.maximvdw.placeholderapi.internal.utils; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.lang.reflect.Field; +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.net.URL; +import java.net.URLConnection; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.util.Map; + +public class HtmlUtils { + /** + * User Agent + */ + private final static String USER_AGENT = "Mozilla/5.0"; + + /** + * Get the body contents of an url + * + * @param url + * URL Link + * @return String with the body + * @throws IOException + */ + public static String getHtmlSource(String url) throws IOException { + URL yahoo = new URL(url); + URLConnection yc = yahoo.openConnection(); + BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream(), "UTF-8")); + String inputLine; + StringBuilder a = new StringBuilder(); + while ((inputLine = in.readLine()) != null) + a.append(inputLine); + in.close(); + + return a.toString(); + } + + public static HtmlResponse sendGetRequest(String url, String[] inputcookies, int timeout) throws Exception { + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + // optional default is GET + con.setRequestMethod("GET"); + + // add request header + con.setRequestProperty("User-Agent", USER_AGENT); + con.setReadTimeout(timeout); + con.setConnectTimeout(timeout); + + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + StringBuffer response = new StringBuffer(); + + String[] cookies = new String[0]; + if (con.getHeaderField("Set-Cookie") != null) + cookies = con.getHeaderField("Set-Cookie").split(";"); + + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + + return new HtmlResponse(response.toString(), con.getResponseCode(), cookies); + } + + /** + * Send a get request + * + * @param url + * Url + * @return Response + * @throws Exception + * Exception + */ + public static HtmlResponse sendGetRequest(String url, String[] inputcookies) throws Exception { + return sendGetRequest(url, inputcookies, 2500); + } + + /** + * Send post request + * + * @param url + * Url + * @param params + * Params + * @return Response + * @throws Exception + * Exception + */ + public static HtmlResponse sendPostRequest(String url, Map params, String[] inputcookies) + throws Exception { + + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + // add reuqest header + con.setRequestMethod("POST"); + con.setRequestProperty("User-Agent", USER_AGENT); + con.setRequestProperty("Accept-Language", "en-US,en;q=0.5"); + + String urlParameters = ""; + for (String key : params.keySet()) { + String value = params.get(key); + urlParameters += key + "=" + value + "&"; + } + urlParameters = urlParameters.substring(0, urlParameters.length() - 1); + + // Send post request + con.setDoOutput(true); + DataOutputStream wr = new DataOutputStream(con.getOutputStream()); + wr.writeBytes(urlParameters); + wr.flush(); + wr.close(); + + String[] cookies = new String[0]; + if (con.getHeaderField("Set-Cookie") != null) + cookies = con.getHeaderField("Set-Cookie").split(";"); + + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + StringBuffer response = new StringBuffer(); + + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + + return new HtmlResponse(response.toString(), con.getResponseCode(), cookies); + + } + + public static String unsetURLStreamHandlerFactory() { + try { + Field f = URL.class.getDeclaredField("factory"); + f.setAccessible(true); + Object curFac = f.get(null); + f.set(null, null); + URL.setURLStreamHandlerFactory(null); + return curFac.getClass().getName(); + } catch (Exception e) { + + } + return null; + } + + /** + * Download a file + * + * @param url + * URL + * @param location + * Output location + * @throws IOException + * Input Output exception + */ + public static void downloadFile(String url, String location) throws IOException { + URL website = new URL(url); + URLConnection connection = website.openConnection(); + connection.addRequestProperty("User-Agent",USER_AGENT); + ReadableByteChannel rbc = Channels.newChannel(connection.getInputStream()); + File yourFile = new File(location); + yourFile.getParentFile().mkdirs(); + if (!yourFile.exists()) { + yourFile.createNewFile(); + } + FileOutputStream fos = new FileOutputStream(yourFile); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + } + + public static String getIPFromHost(String host) { + try { + InetAddress address = InetAddress.getByName(host); + return (address.getHostAddress()); + } catch (Exception ex) { + + } + return "0.0.0.0"; + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/utils/ListUtils.java b/src/main/java/be/maximvdw/placeholderapi/internal/utils/ListUtils.java new file mode 100644 index 0000000..1dfac80 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/utils/ListUtils.java @@ -0,0 +1,17 @@ +package be.maximvdw.placeholderapi.internal.utils; + +import java.util.List; + +public class ListUtils { + public static String[] listToArray(List list) { + return list.toArray(new String[list.size()]); + } + + public static Boolean[] booleanListToArray(List list) { + return list.toArray(new Boolean[list.size()]); + } + + public static Integer[] integerListToArray(List list) { + return list.toArray(new Integer[list.size()]); + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/utils/NumberUtils.java b/src/main/java/be/maximvdw/placeholderapi/internal/utils/NumberUtils.java new file mode 100644 index 0000000..073ba12 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/utils/NumberUtils.java @@ -0,0 +1,50 @@ +package be.maximvdw.placeholderapi.internal.utils; + +public class NumberUtils { + public static boolean isInteger(String s) { + return isInteger(s, 10); + } + + public static boolean isNumber(String s) { + return isNumber(s, 10); + } + + public static boolean isInteger(String s, int radix) { + if (s.isEmpty()) + return false; + for (int i = 0; i < s.length(); i++) { + if (i == 0 && s.charAt(i) == '-') { + if (s.length() == 1) + return false; + else + continue; + } + if (Character.digit(s.charAt(i), radix) < 0) + return false; + } + return true; + } + + public static int floor(double d1) { + int i = (int) d1; + return d1 >= i ? i : i - 1; + } + + public static boolean isNumber(String s, int radix) { + if (s.isEmpty()) + return false; + s = s.replace(".", "").replace(",", ""); + for (int i = 0; i < s.length(); i++) { + if (i == 0 && s.charAt(i) == '-') { + if (s.length() == 1) + return false; + else + continue; + } + if (Character.digit(s.charAt(i), radix) < 0) + return false; + } + return true; + } + +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/utils/ReflectionUtil.java b/src/main/java/be/maximvdw/placeholderapi/internal/utils/ReflectionUtil.java new file mode 100644 index 0000000..ffa8684 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/utils/ReflectionUtil.java @@ -0,0 +1,309 @@ +package be.maximvdw.placeholderapi.internal.utils; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +public abstract class ReflectionUtil { + private static volatile Map, Class> CORRESPONDING_TYPES = new HashMap, Class>(); + + public static Class obcPlayer = ReflectionUtil.getOBCClass("entity.CraftPlayer"); + public static Method methodPlayerGetHandle = getMethod("getHandle", obcPlayer); + + static { + CORRESPONDING_TYPES.put(Byte.class, byte.class); + CORRESPONDING_TYPES.put(Short.class, short.class); + CORRESPONDING_TYPES.put(Integer.class, int.class); + CORRESPONDING_TYPES.put(Long.class, long.class); + CORRESPONDING_TYPES.put(Character.class, char.class); + CORRESPONDING_TYPES.put(Float.class, float.class); + CORRESPONDING_TYPES.put(Double.class, double.class); + CORRESPONDING_TYPES.put(Boolean.class, boolean.class); + } + + public enum DynamicPackage { + MINECRAFT_SERVER { + @Override + public String toString() { + return "net.minecraft.server." + Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; + } + }, + CRAFTBUKKIT { + @Override + public String toString() { + return Bukkit.getServer().getClass().getPackage().getName(); + } + } + } + + public static class FieldEntry { + String key; + Object value; + + public FieldEntry(String key, Object value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return this.key; + } + + public Object getValue() { + return this.value; + } + } + + private static Class getPrimitiveType(Class clazz) { + return CORRESPONDING_TYPES.containsKey(clazz) ? CORRESPONDING_TYPES.get(clazz) : clazz; + } + + private static Class[] toPrimitiveTypeArray(Object[] objects) { + int a = objects != null ? objects.length : 0; + Class[] types = new Class[a]; + for (int i = 0; i < a; i++) + types[i] = getPrimitiveType(objects[i].getClass()); + return types; + } + + private static 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; + } + + public static Class getClass(String name, DynamicPackage pack, String subPackage) throws Exception { + return Class + .forName(pack + (subPackage != null && subPackage.length() > 0 ? "." + subPackage : "") + "." + name); + } + + public static Class getClass(String name, DynamicPackage pack) { + try { + return getClass(name, pack, null); + } catch (Exception e) { + } + return null; + } + + public static Class getClass(String name, String namespace) throws Exception { + return Class.forName(namespace + "." + name); + } + + public static Object getHandle(Object obj) { + try { + return getMethod("getHandle", obj.getClass()).invoke(obj); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public static Object getHandle(Player player) { + try { + return methodPlayerGetHandle.invoke(player); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public static Constructor getConstructor(Class clazz, Class... paramTypes) { + Class[] t = toPrimitiveTypeArray(paramTypes); + for (Constructor c : clazz.getConstructors()) { + Class[] types = toPrimitiveTypeArray(c.getParameterTypes()); + if (equalsTypeArray(types, t)) + return c; + } + return null; + } + + public static Object newInstance(Class clazz, Object... args) throws Exception { + return getConstructor(clazz, toPrimitiveTypeArray(args)).newInstance(args); + } + + public static Object newInstance(String name, DynamicPackage pack, String subPackage, Object... args) + throws Exception { + return newInstance(getClass(name, pack, subPackage), args); + } + + public static Object newInstance(String name, DynamicPackage pack, Object... args) throws Exception { + return newInstance(getClass(name, pack, null), args); + } + + public static 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; + } + + public static Object invokeMethod(String name, Class clazz, Object obj, Object... args) throws Exception { + return getMethod(name, clazz, toPrimitiveTypeArray(args)).invoke(obj, args); + } + + public static Field getField(String name, Class clazz) throws Exception { + return clazz.getDeclaredField(name); + } + + public static Object getValue(String name, Object obj) throws Exception { + Field f = getField(name, obj.getClass()); + if (!f.isAccessible()) + f.setAccessible(true); + return f.get(obj); + } + + public static Object getValueFromClass(String name, Object obj, Class clazz) throws Exception { + Field f = getField(name, clazz); + if (!f.isAccessible()) + f.setAccessible(true); + return f.get(obj); + } + + public static Object getValue(String name, Class clazz) throws Exception { + Field f = getField(name, clazz); + if (!f.isAccessible()) + f.setAccessible(true); + return f.get(clazz); + } + + public static void setValue(Object obj, FieldEntry entry) throws Exception { + Field f = getField(entry.getKey(), obj.getClass()); + if (!f.isAccessible()) + f.setAccessible(true); + f.set(obj, entry.getValue()); + } + + public static void setValue(String name, Object value, Object obj) throws Exception { + Field f = getField(name, obj.getClass()); + if (!f.isAccessible()) + f.setAccessible(true); + f.set(obj, value); + } + + public static void setFinalValue(String name, Object value, Object obj) throws Exception { + Field f = obj.getClass().getDeclaredField(name); + if (!f.isAccessible()) + f.setAccessible(true); + f.set(obj, value); + } + + public static void setValues(Object obj, FieldEntry... entrys) throws Exception { + for (FieldEntry f : entrys) + setValue(obj, f); + } + + public static String getVersion() { + String name = Bukkit.getServer().getClass().getPackage().getName(); + String version = name.substring(name.lastIndexOf('.') + 1) + "."; + return version; + } + + public static 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; + } + + public static 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; + } + + + public static Class getNMSClassWithException(String className) throws Exception { + String fullName = "net.minecraft.server." + getVersion() + className; + Class clazz = Class.forName(fullName); + return clazz; + } + + + public static Field getField(Class clazz, String name) { + try { + Field field = clazz.getDeclaredField(name); + field.setAccessible(true); + return field; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public static 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; + } + + /** + * Set a specified Field accessible + * + * @param f + * Field set accessible + */ + public static Field setAccessible(Field f) + throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { + f.setAccessible(true); + Field modifiersField = Field.class.getDeclaredField("modifiers"); + modifiersField.setAccessible(true); + modifiersField.setInt(f, f.getModifiers() & 0xFFFFFFEF); + return f; + } + + /** + * Set a specified Method accessible + * + * @param m + * Method set accessible + */ + public static Method setAccessible(Method m) + throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { + m.setAccessible(true); + return m; + } + + public static 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; + } + +} \ No newline at end of file diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/utils/TimeFormat.java b/src/main/java/be/maximvdw/placeholderapi/internal/utils/TimeFormat.java new file mode 100644 index 0000000..472a560 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/utils/TimeFormat.java @@ -0,0 +1,5 @@ +package be.maximvdw.placeholderapi.internal.utils; + +public enum TimeFormat { + DAYS, HOURS, MINUTES, SECONDS; +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/utils/TimeUtil.java b/src/main/java/be/maximvdw/placeholderapi/internal/utils/TimeUtil.java new file mode 100644 index 0000000..642a2fe --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/utils/TimeUtil.java @@ -0,0 +1,153 @@ +package be.maximvdw.placeholderapi.internal.utils; + +public class TimeUtil { + public static String getRemaining(int seconds, TimeFormat type) { + if (seconds < 60) { + switch (type) { + case DAYS: + return "0"; + case HOURS: + return "0"; + case MINUTES: + return "0"; + case SECONDS: + return String.valueOf(seconds); + } + return String.valueOf(seconds); + } + int minutes = seconds / 60; + + int s = 60 * minutes; + + int secondsLeft = seconds - s; + if (minutes < 60) { + switch (type) { + case DAYS: + return "0"; + case HOURS: + return "0"; + case MINUTES: + return String.valueOf(minutes); + case SECONDS: + return String.valueOf(secondsLeft); + } + return String.valueOf(seconds); + } + if (minutes < 1440) { + int hours = minutes / 60; + + int inMins = 60 * hours; + + int leftOver = minutes - inMins; + switch (type) { + case DAYS: + return "0"; + case HOURS: + return String.valueOf(hours); + case MINUTES: + return String.valueOf(leftOver); + case SECONDS: + return String.valueOf(secondsLeft); + } + return String.valueOf(seconds); + } + int days = minutes / 1440; + + int inMins = 1440 * days; + + int leftOver = minutes - inMins; + if (leftOver < 60) { + switch (type) { + case DAYS: + return String.valueOf(days); + case HOURS: + return String.valueOf(0); + case MINUTES: + return String.valueOf(leftOver); + case SECONDS: + return String.valueOf(secondsLeft); + } + return String.valueOf(seconds); + } + int hours = leftOver / 60; + + int hoursInMins = 60 * hours; + + int minsLeft = leftOver - hoursInMins; + switch (type) { + case DAYS: + return String.valueOf(days); + case HOURS: + return String.valueOf(hours); + case MINUTES: + return String.valueOf(minsLeft); + case SECONDS: + return String.valueOf(secondsLeft); + } + return String.valueOf(seconds); + } + + public static String getTime(int seconds) { + if (seconds < 60) { + return seconds + "s"; + } + int minutes = seconds / 60; + + int s = 60 * minutes; + + int secondsLeft = seconds - s; + if (minutes < 60) { + if (secondsLeft > 0) { + return String.valueOf(minutes + "m " + secondsLeft + "s"); + } + return String.valueOf(minutes + "m"); + } + if (minutes < 1440) { + String time = ""; + + int hours = minutes / 60; + + time = hours + "h"; + + int inMins = 60 * hours; + + int leftOver = minutes - inMins; + if (leftOver >= 1) { + time = time + " " + leftOver + "m"; + } + if (secondsLeft > 0) { + time = time + " " + secondsLeft + "s"; + } + return time; + } + String time = ""; + + int days = minutes / 1440; + + time = days + "d"; + + int inMins = 1440 * days; + + int leftOver = minutes - inMins; + if (leftOver >= 1) { + if (leftOver < 60) { + time = time + " " + leftOver + "m"; + } else { + int hours = leftOver / 60; + + time = time + " " + hours + "h"; + + int hoursInMins = 60 * hours; + + int minsLeft = leftOver - hoursInMins; + if (leftOver >= 1) { + time = time + " " + minsLeft + "m"; + } + } + } + if (secondsLeft > 0) { + time = time + " " + secondsLeft + "s"; + } + return time; + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/utils/bukkit/BukkitUtils.java b/src/main/java/be/maximvdw/placeholderapi/internal/utils/bukkit/BukkitUtils.java new file mode 100644 index 0000000..361f62e --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/utils/bukkit/BukkitUtils.java @@ -0,0 +1,452 @@ +package be.maximvdw.placeholderapi.internal.utils.bukkit; + +import be.maximvdw.placeholderapi.internal.ui.SendConsole; +import be.maximvdw.placeholderapi.internal.utils.NumberUtils; +import be.maximvdw.placeholderapi.internal.utils.ReflectionUtil; +import be.maximvdw.placeholderapi.internal.utils.ReflectionUtil.DynamicPackage; +import com.google.common.base.Charsets; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Collection; +import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * BukkitUtils + *

+ * Bukkit server utillities + * + * @author Maxim Van de Wynckel (Maximvdw) + * @version 1.0 + * @project BasePlugin + * @site http://www.mvdw-software.be/ + */ +public class BukkitUtils { + private static String version = ""; + private static boolean uuidSupport = true; + private static boolean legacyOnlinePlayers = false; + + private static Method getOnlinePlayers = null; + private static Class bukkitClass = null; + private static Class minecraftServerClass; + private static Method getServerMethod = null; + private static Class gameProfileClass = null; + private static Constructor gameProfileClassConstructor = null; + + private static int versionMajor = -1; + private static int versionMinor = -1; + private static int versionBuild = 0; + + static { + try { + getVersion(); + }catch(Throwable ex){ + SendConsole.severe("Something happened while trying to get the version of the server!"); + SendConsole.severe("Please create a ticket with the following information:"); + SendConsole.severe(Bukkit.getServer().getClass().getPackage().getName()); + ex.printStackTrace(); + throw ex; + } + try { + bukkitClass = ReflectionUtil.getClass("Bukkit", "org.bukkit"); + getOnlinePlayers = ReflectionUtil.getMethod(bukkitClass, "getOnlinePlayers"); + minecraftServerClass = ReflectionUtil.getClass("MinecraftServer", DynamicPackage.MINECRAFT_SERVER); + getServerMethod = ReflectionUtil.getMethod(minecraftServerClass, "getServer"); + if (version.contains("v1_7")) { + gameProfileClass = ReflectionUtil.getClass("GameProfile", "net.minecraft.util.com.mojang.authlib"); + } else if (version.contains("v1_8")) { + gameProfileClass = ReflectionUtil.getClass("GameProfile", "com.mojang.authlib"); + } + if (gameProfileClass != null) { + gameProfileClassConstructor = ReflectionUtil.getConstructor(gameProfileClass, UUID.class, String.class); + } + } catch (Throwable e) { + } + } + public static String getVersion() { + if (Bukkit.getServer() == null) { + return ""; + } + + if (version.equals("")) { + version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; + + String[] data = BukkitUtils.getVersion().substring(1).split("_"); + if (NumberUtils.isInteger(data[1]) && NumberUtils.isInteger(data[0])) { + versionMinor = Integer.parseInt(data[1]); + versionMajor = Integer.parseInt(data[0]); + if (data[2].startsWith("R")) { + versionBuild = Integer.parseInt(data[2].replace("R", "")) + 1; + } + } + boolean latest = false; + if (BukkitUtils.getVersionMajor() >= 1 && BukkitUtils.getVersionMinor() >= 8) { + latest = true; + } + + if (latest + || BukkitUtils.getVersion().contains("v1_7_R3") || BukkitUtils.getVersion().contains("v1_7_R4")) { + uuidSupport = true; + } else { + uuidSupport = false; + } + if (BukkitUtils.getVersion().contains("v1_6") || BukkitUtils.getVersion().contains("v1_7")) { + legacyOnlinePlayers = true; + } + } + return version; + } + + /** + * Get server name + * + * @return Server Name + */ + public static String getServerName() { + return Bukkit.getServer().getName(); + } + + public static boolean disablePlugin(Plugin plugin) { + Bukkit.getPluginManager().disablePlugin(plugin); + return Bukkit.getPluginManager().isPluginEnabled(plugin); + } + + /** + * Get server motd + * + * @return MOTD + */ + public static String getMotd() { + return Bukkit.getMotd(); + } + + /** + * Get max playeres + * + * @return Maximum players + */ + public static int getMaxPlayers() { + return Bukkit.getMaxPlayers(); + } + + /** + * Get bukkit plugins + * + * @return Plugin Array + */ + public static Plugin[] getPlugins() { + return Bukkit.getPluginManager().getPlugins(); + } + + /** + * Get server port + * + * @return Port + */ + public static int getPort() { + return Bukkit.getPort(); + } + + /** + * Get bukkit plugin count + * + * @return Plugin count + */ + public static int getPluginCount() { + return Bukkit.getPluginManager().getPlugins().length; + } + + /** + * Get total player count + * + * @return Player Count + */ + public static int getTotalPlayerCount() { + return Bukkit.getOfflinePlayers().length; + } + + /** + * Get operator count + * + * @return Operator count + */ + public static int getOPCount() { + return Bukkit.getOperators().size(); + } + + /** + * Get operators + * + * @return Operator array + */ + public static Player[] getOperators() { + return (Player[]) Bukkit.getOperators().toArray(); + } + + /** + * Get ip + * + * @return IP address + */ + public static String getIp() { + String bukkitIP = Bukkit.getServer().getIp(); + return (bukkitIP == null || bukkitIP == "") ? "127.0.0.1" : bukkitIP; + } + + /** + * Get players with a specific game mode + * + * @param mode Game Mode + * @return Player Count + */ + public static int getPlayerCount(GameMode mode) { + int size = 0; + for (Player p : getOnlinePlayers()) { + if (p.getGameMode() == mode) { + size++; + } + } + return size; + } + + public static Collection getOnlinePlayers() { + if (legacyOnlinePlayers) { + Player[] players = {}; + try { + Object pObj = getOnlinePlayers.invoke(null); + if (pObj instanceof Player[]) { + players = (Player[]) getOnlinePlayers.invoke(null); + } else { + legacyOnlinePlayers = true; + return Bukkit.getOnlinePlayers(); + } + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + e.printStackTrace(); + } + return Arrays.asList(players); + } else { + return Bukkit.getOnlinePlayers(); + } + } + + /** + * Check if server has whitelist + * + * @return Whitelist + */ + public static boolean hasWhitelist() { + return Bukkit.hasWhitelist(); + } + + public static int getBuild() { + if (isSpigot()) + return getSpigotBuild(); + else + return getBukkitBuild(); + } + + public static void setVersion(String version) { + BukkitUtils.version = version; + } + + public static boolean hasUUIDSupport() { + boolean latest = false; + if (BukkitUtils.getVersionMajor() >= 1 && BukkitUtils.getVersionMinor() >= 8) { + latest = true; + } + + if (!version.equals("")) + return uuidSupport; + else if (latest || BukkitUtils.getVersion().contains("v1_7_R3") + || BukkitUtils.getVersion().contains("v1_7_R4")) { + uuidSupport = true; + return true; + } + uuidSupport = false; + return false; + } + + /** + * Get bukkit build + * + * @return Bukkit build + */ + public static int getBukkitBuild() { + String version = Bukkit.getVersion(); + Pattern pattern = Pattern.compile("(b)([0-9]+)(jnks)"); + Matcher matcher = pattern.matcher(version); + + if (matcher.find()) { + return Integer.parseInt(matcher.group(2)); + } + + return 0; + } + + public static int getSpigotBuild() { + String version = Bukkit.getVersion(); + Pattern pattern = Pattern.compile("(git-Spigot-)([0-9]+)"); + Matcher matcher = pattern.matcher(version); + if (matcher.find()) { + return Integer.parseInt(matcher.group(2)); + } + + return 0; + } + + public static int getPaperSpigotBuild() { + String version = Bukkit.getVersion(); + Pattern pattern = Pattern.compile("(git-Paper-)([0-9]+)"); + Matcher matcher = pattern.matcher(version); + if (matcher.find()) { + return Integer.parseInt(matcher.group(2)); + } + + return 0; + } + + /** + * Check if running spigot + * + * @return Spigot + */ + public static boolean isSpigot() { + return Bukkit.getVersion().toLowerCase().contains("spigot") || Bukkit.getVersion().toLowerCase().contains("paper"); + } + + /** + * Get minecraft server version + *

+ * This will get the minecraft server version as shown in the server list. + * + * @return Server version + */ + public static String getServerVersion() { + return version; + } + + /** + * Get server mod name + * + * @return Server mod name + */ + public static String getServerModName() { + String mod = ""; + try { + Class minecraftServerClass = ReflectionUtil.getClass("MinecraftServer", DynamicPackage.MINECRAFT_SERVER); + Object serverInstance = ReflectionUtil.getMethod(minecraftServerClass, "getServer") + .invoke(minecraftServerClass); + + mod = (String) ReflectionUtil.getMethod("getServerModName", minecraftServerClass).invoke(serverInstance); + } catch (Exception ex) { + } + return mod; + } + + /** + * Change server version + * + * @param version Version + */ + public static void changeVersion(String version) { + try { + SendConsole.info("Preparing version change ..."); + Class serverPing = ReflectionUtil.getClass("ServerPing", DynamicPackage.MINECRAFT_SERVER); + Class serverPingData = ReflectionUtil.getClass("ServerPingServerData", DynamicPackage.MINECRAFT_SERVER); + Class minecraftServerClass = ReflectionUtil.getClass("MinecraftServer", DynamicPackage.MINECRAFT_SERVER); + Object serverInstance = ReflectionUtil.getMethod(minecraftServerClass, "getServer") + .invoke(minecraftServerClass); + Field[] fields = minecraftServerClass.getDeclaredFields(); + SendConsole.info("Searching for ping packet ..."); + for (Field field : fields) { + if (field.getType().equals(serverPing)) { + SendConsole.info("Ping information found! Searching for current version ..."); + Object value = ReflectionUtil.getValueFromClass(field.getName(), serverInstance, + minecraftServerClass); + Field[] fields_value = value.getClass().getDeclaredFields(); + for (Field field_value : fields_value) { + if (field_value.getType().equals(serverPingData)) { + SendConsole.info("Server version information found!"); + Object serverData = ReflectionUtil.getValueFromClass(field_value.getName(), value, + value.getClass()); + String curVersion = (String) ReflectionUtil.getValue("a", serverData); + SendConsole.info("Current server version: " + curVersion); + SendConsole.info("Performing change ..."); + ReflectionUtil.setValue("a", version, serverData); + ReflectionUtil.setValue("b", 4, serverData); + break; + } + } + break; + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public static int getVersionMajor() { + if (versionMajor == -1) { + getVersion(); + } + return versionMajor; + } + + public static void setVersionMajor(int versionMajor) { + BukkitUtils.versionMajor = versionMajor; + } + + public static int getVersionMinor() { + if (versionMinor == -1) { + getVersion(); + } + return versionMinor; + } + + public static void setVersionMinor(int versionMinor) { + BukkitUtils.versionMinor = versionMinor; + } + + public static int getVersionBuild() { + return versionBuild; + } + + public static void setVersionBuild(int versionBuild) { + BukkitUtils.versionBuild = versionBuild; + } + + @SuppressWarnings("deprecation") + public OfflinePlayer getOfflinePlayer(String name) { + UUID uuid = UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8)); + try { + if (version.contains("v1_7")) { + + } else if (version.contains("v1_8")) { + + } else { + return Bukkit.getOfflinePlayer(name); + } + + Object gameProfile = gameProfileClassConstructor + .newInstance(uuid, name); + Object serverInstance = getServerMethod + .invoke(minecraftServerClass); + OfflinePlayer player = (OfflinePlayer) ReflectionUtil.invokeMethod("getOfflinePlayer", minecraftServerClass, + serverInstance, gameProfile); + return player; + } catch (Exception ex) { + ex.printStackTrace(); + } + return Bukkit.getOfflinePlayer(uuid); + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/utils/bukkit/Version.java b/src/main/java/be/maximvdw/placeholderapi/internal/utils/bukkit/Version.java new file mode 100644 index 0000000..3131f71 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/utils/bukkit/Version.java @@ -0,0 +1,206 @@ +package be.maximvdw.placeholderapi.internal.utils.bukkit; + +import be.maximvdw.placeholderapi.internal.utils.NumberUtils; + +/** + * Version + * + * Version container + * + * @project BasePlugin + * @version 1.0 + * @author Maxim Van de Wynckel (Maximvdw) + * @site http://www.mvdw-software.be/ + */ +public class Version implements Comparable { + /** + * Major minor and release + */ + private short major, minor, release; + /** + * Alpha or beta release + */ + private boolean alpha, beta; + + /** + * Create version + */ + public Version() { + + } + + /** + * Create version from string + * + * @param version + * Version string + */ + public Version(String version) { + String[] data = version.split("\\."); + if (data.length == 3) { + if (NumberUtils.isInteger(data[0])) { + major = (short) Integer.parseInt(data[0]); + } + if (major == 0) + alpha = true; + if (NumberUtils.isInteger(data[1])) { + minor = (short) Integer.parseInt(data[1]); + } + if (data[2].contains("b")) + beta = true; + if (NumberUtils.isInteger(data[2].replace("b", ""))) { + release = (short) Integer.parseInt(data[2].replace("b", "")); + } + } + } + + /** + * Is beta release + * + * @return Beta release + */ + public boolean isBeta() { + return beta; + } + + /** + * Is alpha release + * + * @return Alpha + */ + public boolean isAlpha() { + return alpha; + } + + /** + * Get major version + * + * @return Major + */ + public short getMajor() { + return major; + } + + /** + * Set major version + * + * @param major + * Major + * @return Version + */ + public Version setMajor(short major) { + this.major = major; + return this; + } + + /** + * Get minor version + * + * @return Minor + */ + public short getMinor() { + return minor; + } + + /** + * Set minor version + * + * @param minor + * Minor + * @return Version + */ + public Version setMinor(short minor) { + this.minor = minor; + return this; + } + + /** + * Get release + * + * @return release + */ + public short getRelease() { + return release; + } + + /** + * Set release version + * + * @param release + * Release + * @return Version + */ + public Version setRelease(short release) { + this.release = release; + return this; + } + + public int compare(Version otherVersion) { + if (otherVersion.getMajor() > this.getMajor()) { + return 1; + } else if (otherVersion.getMajor() < this.getMajor()) { + return -1; + } else { + if (otherVersion.getMinor() > this.getMinor()) { + return 1; + } else if (otherVersion.getMinor() < this.getMinor()) { + return -1; + } else { + if (otherVersion.getRelease() > this.getRelease()) { + return 1; + } else if (otherVersion.getRelease() < this.getRelease()) { + return -1; + } else { + if (otherVersion.isBeta() == this.isBeta()) { + return 0; + } else { + if (otherVersion.isBeta()) + return -1; + else + return 1; + } + } + } + } + } + + /** + * Version to string + */ + public String toString() { + String version = major + "." + minor + "." + release; + if (isBeta()) + version += "b"; + return version; + } + + @Override + public int compareTo(Version otherVersion) { + if (otherVersion.getMajor() > this.getMajor()) { + return 1; + } else if (otherVersion.getMajor() < this.getMajor()) { + return -1; + } else { + if (otherVersion.getMinor() > this.getMinor()) { + return 1; + } else if (otherVersion.getMinor() < this.getMinor()) { + return -1; + } else { + if (otherVersion.getRelease() > this.getRelease()) { + return 1; + } else if (otherVersion.getRelease() < this.getRelease()) { + return -1; + } else { + if (otherVersion.isBeta() == this.isBeta()) { + return 0; + } else { + if (otherVersion.isBeta()) + return -1; + else + return 1; + } + } + } + } + } +} diff --git a/src/main/java/be/maximvdw/placeholderapi/internal/utils/chat/ColorUtils.java b/src/main/java/be/maximvdw/placeholderapi/internal/utils/chat/ColorUtils.java new file mode 100644 index 0000000..3d70508 --- /dev/null +++ b/src/main/java/be/maximvdw/placeholderapi/internal/utils/chat/ColorUtils.java @@ -0,0 +1,138 @@ +package be.maximvdw.placeholderapi.internal.utils.chat; + +import org.bukkit.ChatColor; + +import java.util.ArrayList; +import java.util.List; + +/** + * MVdW Software Color Utilities + * + * @project BasePlugin + * @version 1.0 + * @author Maxim Van de Wynckel (Maximvdw) + * @site http://www.mvdw-software.be/ + */ +public class ColorUtils { + /** + * Convert string to colors + * + * @param input + * String + * @return Colored String + */ + public static String toColors(String input) { + if (input == null) { + return null; + } + return ChatColor.translateAlternateColorCodes('&', input); + } + + public static String getLastColors(String input) { + String result = ""; + int length = input.length(); + boolean foundColor = false; + for (int index = length - 1; index > -1; --index) { + char section = input.charAt(index); + if (section == 167 && index < length - 1) { + char c = input.charAt(index + 1); + ChatColor color = ChatColor.getByChar(c); + if (color != null) { + result = color.toString() + result; + if (color.isColor() || color.equals(ChatColor.RESET)) { + foundColor = true; + break; + } + } + } + } + if (!foundColor) { + result = ChatColor.WHITE + result; + } + return result; + } + + /** + * Get last color + * + * @param input + * Input string + * @return Chat color + */ + public static ChatColor getLastColor(String input) { + if (input == null) + return ChatColor.RESET; + int length = input.length(); + // Search backwards from the end as it is faster + for (int index = length - 1; index > -1; index--) { + char section = input.charAt(index); + if (section == ChatColor.COLOR_CHAR && index < length - 1) { + char c = input.charAt(index + 1); + ChatColor color = ChatColor.getByChar(c); + if (color.isColor()) + if (color != null) { + return color; + } + } + } + return ChatColor.RESET; + } + + public static ChatColor getLastEffect(String input) { + if (input == null) + return ChatColor.RESET; + int length = input.length(); + // Search backwards from the end as it is faster + for (int index = length - 1; index > -1; index--) { + char section = input.charAt(index); + if (section == ChatColor.COLOR_CHAR && index < length - 1) { + char c = input.charAt(index + 1); + ChatColor color = ChatColor.getByChar(c); + if (color != null) { + if (color.isColor()) + return ChatColor.RESET; + if (color.isFormat()) + return color; + } + } + } + return ChatColor.RESET; + } + + public static List getLastEffects(String input) { + List effects = new ArrayList(); + if (input == null){ + return effects; + } + int length = input.length(); + // Search backwards from the end as it is faster + for (int index = length - 1; index > -1; index--) { + char section = input.charAt(index); + if (section == ChatColor.COLOR_CHAR && index < length - 1) { + char c = input.charAt(index + 1); + ChatColor color = ChatColor.getByChar(c); + if (color != null) { + if (color.isColor()) + return effects; + if (color.isFormat()) + effects.add(color); + } + } + } + return effects; + } + + /** + * Remove colors from string + * + * @param input + * String + * @return Cleared string + */ + public static String removeColors(String input) { + if (input == null) { + return null; + } + return ChatColor.stripColor(input.replaceAll("(&([A-FK-Oa-fk-or0-9]))", "")); + } +}