Add v2 API

This commit is contained in:
filoghost 2014-12-20 15:30:14 +01:00
parent 58ca049149
commit 19b2839174
170 changed files with 463 additions and 14501 deletions

View File

@ -0,0 +1,183 @@
package com.gmail.filoghost.holographicdisplays.api;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.inventory.ItemStack;
import com.gmail.filoghost.holographicdisplays.api.line.HologramLine;
import com.gmail.filoghost.holographicdisplays.api.line.ItemLine;
import com.gmail.filoghost.holographicdisplays.api.line.TextLine;
/**
* An object made of various lines, that can be items or holograms.
* Holographic lines appear as a nametag without any entity below.
* To create one, please see {@link HologramsAPI#createHologram(org.bukkit.plugin.Plugin, Location)}.
*/
public interface Hologram {
/**
* Appends a text line to end of this hologram.
*
* @param text the content of the line, can be null for an empty line
* @return the new TextLine appended
*/
public TextLine appendTextLine(String text);
/**
* Appends an item line to end of this hologram.
*
* @param itemStack the content of the line
* @return the new ItemLine appended
*/
public ItemLine appendItemLine(ItemStack itemStack);
/**
* Inserts a text line in this hologram.
*
* @param index the line is inserted before this index, that should be
* between 0 and size() - 1. If 0, the new line will be inserted before the
* first line.
* @param text the content of the line, can be null for an empty line
* @return the new TextLine inserted
*/
public TextLine insertTextLine(int index, String text);
/**
* Inserts an item line in this hologram.
*
* @param index the line is inserted before this index, that should be
* between 0 and size() - 1. If 0, the new line will be inserted before the
* first line.
* @param itemStack the content of the line
* @return the new ItemLine inserted
*/
public ItemLine insertItemLine(int index, ItemStack itemStack);
/**
* Finds the element at a given index in the lines.
*
* @param index the index of the line, that should be between 0 and size() - 1.
* @return the hologram line at the given index, can be an {@link ItemLine} or a {@link TextLine}.
*/
public HologramLine getLine(int index);
/**
* Removes all the lines from this hologram.
*/
public void clearLines();
/**
* Checks the amount of lines of the hologram.
*
* @return the amount of lines
*/
public int size();
/**
* Teleports a hologram to the given location.
*
* @param location the new location
*/
public void teleport(Location location);
/**
* Teleports a hologram to the given location.
*
* @param world the world where the hologram should be teleported,
* use {@link #getWorld()} to teleport it in the same world.
* @param x the X coordinate
* @param y the Y coordinate
* @param z the Z coordinate
*/
public void teleport(World world, double x, double y, double z);
/**
* Returns the X coordinate.
*
* @return the X coordinate of the hologram
*/
public double getX();
/**
* Returns the Y coordinate.
*
* @return the Y coordinate of the hologram
*/
public double getY();
/**
* Returns the Z coordinate.
*
* @return the Z coordinate of the hologram
*/
public double getZ();
/**
* Returns the world.
*
* @return the world of the hologram
*/
public World getWorld();
/**
* Returns the {@link VisibilityManager} of this hologram.
* <br><b style = "color: red">Note</b>: the usage of the VisibilityManager requires ProtocolLib.
* Without the plugin, holograms will be always visible.
*
* @return the VisibilityManager of this hologram
*/
public VisibilityManager getVisibilityManager();
/**
* Returns when the hologram was created. Useful for removing old holograms.
*
* @return the timestamp of when the hologram was created, in milliseconds
*/
public long getCreationTimestamp();
/**
* Checks if the hologram will track and replace placeholders.
* This is false by default.
*
* @return if the hologram allows placeholders
*/
public boolean isAllowPlaceholders();
/**
* Sets if the hologram should track and replace placeholders.
* By default if will not track them.
*
* @param allowPlaceholders if the hologram should track placeholders
*/
public void setAllowPlaceholders(boolean allowPlaceholders);
/**
* Deletes this hologram. Editing or teleporting the hologram when deleted
* will throw an exception. Lines will be automatically cleared.
* You should remove all the references of the hologram after deletion.
*/
public void delete();
/**
* Checks if a hologram was deleted.
*
* @return true if this hologram was deleted
*/
public boolean isDeleted();
}

View File

@ -0,0 +1,101 @@
package com.gmail.filoghost.holographicdisplays.api;
import java.util.Collection;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.plugin.Plugin;
import com.gmail.filoghost.holographicdisplays.api.placeholder.PlaceholderReplacer;
import com.gmail.filoghost.holographicdisplays.object.BackendAPI;
/**
* This the main class of the <b>Holographic Displays API</b>.
* It provides methods to create holograms and to register custom placeholders.
*/
public class HologramsAPI {
/**
* Creates a hologram at given location.
*
* @param plugin the plugin that creates it
* @param source the location where it will appear
* @return the new hologram created
*/
public static Hologram createHologram(Plugin plugin, Location source) {
return BackendAPI.createHologram(plugin, source);
}
/**
* Finds all the holograms created by a given plugin.
*
* @param plugin the plugin to search for in holograms
* @return the holograms created by a plugin
*/
public static Collection<Hologram> getHolograms(Plugin plugin) {
return BackendAPI.getHolograms(plugin);
}
/**
* Registers a new placeholder that can be used in holograms created with commands.
* With this method, you can basically expand the core of HolographicDisplays.
*
* @param plugin the owner plugin of the placeholder
* @param textPlaceholder the text that the placeholder will be associated to (e.g.: "{onlinePlayers}")
* @param refreshRate the refresh rate of the placeholder, in seconds. Keep in mind that the minimum is 0.1 seconds, and that will be rounded to tenths of seconds
* @param replacer the implementation that will return the text to replace the placeholder, where the update() method is called every <b>refreshRate</b> seconds
* @return true if the registration was successfull, false if it was already registered
*/
public static boolean registerPlaceholder(Plugin plugin, String textPlaceholder, double refreshRate, PlaceholderReplacer replacer) {
return BackendAPI.registerPlaceholder(plugin, textPlaceholder, refreshRate, replacer);
}
/**
* Finds all the placeholders registered by a given plugin.
*
* @param plugin the plugin to search for
* @return a collection of placeholders registered by the plugin
*/
public static Collection<String> getRegisteredPlaceholders(Plugin plugin) {
return BackendAPI.getRegisteredPlaceholders(plugin);
}
/**
* Unregister a placeholder created by a plugin.
*
* @param plugin the plugin that owns the placeholder
* @param textPlaceholder the placeholder to remove
* @return true if found and removed, false otherwise
*/
public static boolean unregisterPlaceholder(Plugin plugin, String textPlaceholder) {
return BackendAPI.unregisterPlaceholder(plugin, textPlaceholder);
}
/**
* Resets and removes all the placeholders registered by a plugin. This is useful
* when you have configurable placeholders and you want to remove all of them.
*
* @param plugin the plugin that owns the placeholders
*/
public static void unregisterPlaceholders(Plugin plugin) {
BackendAPI.unregisterPlaceholders(plugin);
}
/**
* Checks if an entity is part of a hologram.
*
* @param bukkitEntity the entity to check
* @return true if the entity is a part of a hologram
*/
public static boolean isHologramEntity(Entity bukkitEntity) {
return BackendAPI.isHologramEntity(bukkitEntity);
}
}

View File

@ -0,0 +1,66 @@
package com.gmail.filoghost.holographicdisplays.api;
import org.bukkit.entity.Player;
/**
* This object is used to manage the visibility of a hologram.
* It allows to hide/show the hologram to certain players, and the default behaviour
* (when a hologram is not specifically being hidden/shown to a player) can be customized.
*/
public interface VisibilityManager {
/**
* Returns if the hologram is visible by default. If not changed, this value
* is true by default so the hologram is visible to everyone.
*
* @return if the hologram hologram is visible by default
*/
public boolean isVisibleByDefault();
/**
* Sets if the hologram is visible by default. If not changed, this value
* is true by default so the hologram is visible to everyone.
*
* @param visibleByDefault the new behaviour
*/
public void setVisibleByDefault(boolean visibleByDefault);
/**
* Shows the hologram to a player, overriding the value of {@link #isVisibleByDefault()}.
* This is persistent if the players goes offline.
*
* @param player the involved player
*/
public void showTo(Player player);
/**
* Hides the hologram to a player, overriding the value of {@link #isVisibleByDefault()}.
* This is persistent if the players goes offline.
*
* @param player the involved player
*/
public void hideTo(Player player);
/**
* Checks if a hologram is visible to a player.
*
* @param player the involved player
* @return if the player can see the hologram
*/
public boolean isVisibleTo(Player player);
/**
* Resets the visibility to the default value. If you previously called {@link #showTo(Player)}
* or {@link #hideTo(Player)} to override the default visibility, this method will reset it
* to reflect the value of {@link #isVisibleByDefault()}.
*
* @param player the involved player
*/
public void resetVisibility(Player player);
/**
* Resets the visibility for all the players. See {@link #resetVisibility(Player)} for more details.
*/
public void resetVisibilityAll();
}

View File

@ -0,0 +1,16 @@
package com.gmail.filoghost.holographicdisplays.api.handler;
import org.bukkit.entity.Player;
/**
* Interface to handle items being picked up by players.
*/
public interface PickupHandler {
/**
* Called when a player picks up the item.
* @param player the player who picked up the item
*/
public void onPickup(Player player);
}

View File

@ -0,0 +1,16 @@
package com.gmail.filoghost.holographicdisplays.api.handler;
import org.bukkit.entity.Player;
/**
* Interface to handle touch holograms.
*/
public interface TouchHandler {
/**
* Called when a player interacts with the hologram (right click).
* @param player the player who interacts
*/
public void onTouch(Player player);
}

View File

@ -0,0 +1,14 @@
package com.gmail.filoghost.holographicdisplays.api.line;
import com.gmail.filoghost.holographicdisplays.api.handler.PickupHandler;
/**
* A piece of hologram that can be picked up.
*/
public interface CollectableLine extends HologramLine {
public void setPickupHandler(PickupHandler pickupHandler);
public PickupHandler getPickupHandler();
}

View File

@ -0,0 +1,9 @@
package com.gmail.filoghost.holographicdisplays.api.line;
import com.gmail.filoghost.holographicdisplays.api.Hologram;
public interface HologramLine {
public Hologram getParent();
}

View File

@ -0,0 +1,11 @@
package com.gmail.filoghost.holographicdisplays.api.line;
import org.bukkit.inventory.ItemStack;
public interface ItemLine extends CollectableLine, TouchableLine {
public ItemStack getItemStack();
public void setItemStack(ItemStack itemStack);
}

View File

@ -0,0 +1,9 @@
package com.gmail.filoghost.holographicdisplays.api.line;
public interface TextLine extends TouchableLine {
public String getText();
public void setText(String text);
}

View File

@ -0,0 +1,14 @@
package com.gmail.filoghost.holographicdisplays.api.line;
import com.gmail.filoghost.holographicdisplays.api.handler.TouchHandler;
/**
* A piece of hologram that can be touched.
*/
public interface TouchableLine extends HologramLine {
public void setTouchHandler(TouchHandler touchHandler);
public TouchHandler getTouchHandler();
}

View File

@ -0,0 +1,11 @@
package com.gmail.filoghost.holographicdisplays.api.placeholder;
public interface PlaceholderReplacer {
/**
* Called to update a placeholder's replacement.
* @return the replacement
*/
public String update();
}

View File

@ -0,0 +1,2 @@
/holographicdisplays/
/holograms/

View File

@ -1,9 +0,0 @@
Speed: 20
This is an example.
This line will change every 2 seconds...
because it's an animation.
You just have to put "{animation: example.txt}" in a hologram...
to see this animated text.
Each unit of speed will result in a 0.1 seconds delay...
for example 20 * 0.1 = 2 seconds, like in this example.
The fastest animation has speed 1, every 0.1 seconds.

View File

@ -3,13 +3,17 @@
#.
#. Plugin created by filoghost.
#.
vertical-spacing: 0.25
space-between-lines: 0.02
images:
symbol: '[x]'
transparency:
space: ' [|] '
color: '&7'
bungee-refresh-seconds: 3
time-format: 'H:mm'
bungee:
refresh-seconds: 3
use-RedisBungee: false
time:
format: H:mm
zone: GMT+1
update-notification: true
using-RedisBungee: false
debug: false

View File

@ -1,6 +1,6 @@
name: HolographicDisplays
main: com.gmail.filoghost.holograms.HolographicDisplays
version: 1.8.12
main: com.gmail.filoghost.holographicdisplays.HolographicDisplays
version: 1.9.9
softdepend: [Multiverse-Core, MultiWorld, My Worlds, My_Worlds, ProtocolLib]
@ -8,4 +8,4 @@ commands:
holograms:
description: Main command for HolographicDisplays.
usage: /<command> (Startup error)
aliases: [hd, holo, hologram]
aliases: [hd, holo, hologram, holograms]

View File

@ -1,23 +0,0 @@
package com.gmail.filoghost.holograms;
import java.text.SimpleDateFormat;
import org.bukkit.ChatColor;
public class Configuration {
public static double verticalLineSpacing;
public static String imageSymbol;
public static String transparencySymbol;
public static boolean updateNotification;
public static ChatColor transparencyColor;
public static int bungeeRefreshSeconds;
public static String bungeeOnlineFormat;
public static String bungeeOfflineFormat;
public static SimpleDateFormat timeFormat;
public static boolean redisBungee;
// Used for the updater.
public static String newVersion;
}

View File

@ -1,333 +0,0 @@
package com.gmail.filoghost.holograms;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Set;
import java.util.logging.Logger;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import com.gmail.filoghost.holograms.bungee.ServerInfoTimer;
import com.gmail.filoghost.holograms.commands.main.HologramsCommandHandler;
import com.gmail.filoghost.holograms.database.HologramDatabase;
import com.gmail.filoghost.holograms.exception.HologramNotFoundException;
import com.gmail.filoghost.holograms.exception.InvalidLocationException;
import com.gmail.filoghost.holograms.exception.WorldNotFoundException;
import com.gmail.filoghost.holograms.listener.MainListener;
import com.gmail.filoghost.holograms.metrics.MetricsLite;
import com.gmail.filoghost.holograms.nms.interfaces.NmsManager;
import com.gmail.filoghost.holograms.object.CraftHologram;
import com.gmail.filoghost.holograms.object.HologramManager;
import com.gmail.filoghost.holograms.placeholders.AnimationManager;
import com.gmail.filoghost.holograms.placeholders.PlaceholderManager;
import com.gmail.filoghost.holograms.placeholders.StaticPlaceholders;
import com.gmail.filoghost.holograms.protocol.ProtocolLibHook;
import com.gmail.filoghost.holograms.tasks.BungeeCleanupTask;
import com.gmail.filoghost.holograms.tasks.WorldPlayerCounterTask;
import com.gmail.filoghost.holograms.utils.StringUtils;
import com.gmail.filoghost.holograms.utils.VersionUtils;
import com.gmail.filoghost.holograms.utils.ConfigNode;
import com.gmail.filoghost.holograms.SimpleUpdater.ResponseHandler;
public class HolographicDisplays extends JavaPlugin {
private static Logger logger;
private static HolographicDisplays instance;
public static NmsManager nmsManager;
private HologramsCommandHandler mainCommandHandler;
private static PlaceholderManager placeholderManager;
public static boolean is1_8;
public void onEnable() {
if (instance != null) {
getLogger().warning("Please do not use /reload or plugin reloaders. Do \"/hd reload\" instead.");
return;
}
instance = this;
logger = getLogger();
try {
File oldItemDb = new File(getDataFolder(), "database-items.yml");
if (oldItemDb.exists()) {
oldItemDb.delete();
logger.info("Deleted old database-items.yml file.");
}
} catch (Exception e) {
}
// Load placeholders.yml.
try {
StaticPlaceholders.load();
} catch (Exception e) {
e.printStackTrace();
getLogger().severe("Unable to read placeholders.yml! Is the file in use?");
}
// Load the configuration.
loadConfiguration();
if (Configuration.updateNotification) {
new SimpleUpdater(this, 75097).checkForUpdates(new ResponseHandler() {
@Override
public void onUpdateFound(final String newVersion) {
Configuration.newVersion = newVersion;
logger.info("Found a new version available: " + newVersion);
logger.info("Download it on Bukkit Dev:");
logger.info("dev.bukkit.org/bukkit-plugins/holographic-displays");
}
});
}
String version = VersionUtils.getBukkitVersion();
if (version == null) {
// Caused by MCPC+ / Cauldron renaming packages, extract the version from Bukkit.getVersion()
version = VersionUtils.getMinecraftVersion();
if ("1.6.4".equals(version)) {
version = "v1_6_R3";
} else if ("1.7.2".equals(version)) {
version = "v1_7_R1";
} else if ("1.7.5".equals(version)) {
version = "v1_7_R2";
} else if ("1.7.8".equals(version)) {
version = "v1_7_R3";
} else if ("1.7.10".equals(version)) {
version = "v1_7_R4";
} else if ("1.8".equals(version)) {
version = "v1_8_R1";
} else {
// Cannot definitely get the version. This will cause HD to disable itself.
version = null;
}
}
// It's simple, we don't need reflection.
if ("v1_6_R3".equals(version)) {
nmsManager = new com.gmail.filoghost.holograms.nms.v1_6_R3.NmsManagerImpl();
} else if ("v1_7_R1".equals(version)) {
nmsManager = new com.gmail.filoghost.holograms.nms.v1_7_R1.NmsManagerImpl();
} else if ("v1_7_R2".equals(version)) {
nmsManager = new com.gmail.filoghost.holograms.nms.v1_7_R2.NmsManagerImpl();
} else if ("v1_7_R3".equals(version)) {
nmsManager = new com.gmail.filoghost.holograms.nms.v1_7_R3.NmsManagerImpl();
} else if ("v1_7_R4".equals(version)) {
nmsManager = new com.gmail.filoghost.holograms.nms.v1_7_R4.NmsManagerImpl();
} else if ("v1_8_R1".equals(version)) {
is1_8 = true;
nmsManager = new com.gmail.filoghost.holograms.nms.v1_8_R1.NmsManagerImpl();
} else {
printWarnAndDisable(
"******************************************************",
" This version of HolographicDisplays can",
" only work on these server versions:",
" 1.6.4, from 1.7 to 1.8.1.",
" The plugin will be disabled.",
"******************************************************"
);
return;
}
try {
if (VersionUtils.isMCPCOrCauldron()) {
getLogger().info("Trying to enable Cauldron/MCPC+ support...");
}
nmsManager.registerCustomEntities();
if (VersionUtils.isMCPCOrCauldron()) {
getLogger().info("Successfully added support for Cauldron/MCPC+!");
}
} catch (Exception e) {
e.printStackTrace();
printWarnAndDisable(
"******************************************************",
" HolographicDisplays was unable to register",
" custom entities, the plugin will be disabled.",
" Are you using the correct Bukkit version?",
"******************************************************"
);
return;
}
// ProtocolLib check.
try {
if (Bukkit.getPluginManager().isPluginEnabled("ProtocolLib")) {
ProtocolLibHook.initialize();
}
} catch (Exception ex) {
ex.printStackTrace();
logger.warning("Failed to load ProtocolLib support. Is it updated?");
}
// Load animation files.
try {
AnimationManager.loadAnimations();
} catch (Exception ex) {
ex.printStackTrace();
logger.warning("Failed to load animation files!");
}
// Instantiate a PlaceholderManager.
placeholderManager = new PlaceholderManager();
// Initalize other static classes.
HologramDatabase.initialize();
ServerInfoTimer.setRefreshSeconds(Configuration.bungeeRefreshSeconds);
ServerInfoTimer.startTask();
BungeeCleanupTask.start();
Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new WorldPlayerCounterTask(), 0L, 3 * 20L);
Set<String> savedHolograms = HologramDatabase.getHolograms();
if (savedHolograms != null && savedHolograms.size() > 0) {
for (String singleSavedHologram : savedHolograms) {
try {
CraftHologram singleHologramEntity = HologramDatabase.loadHologram(singleSavedHologram);
HologramManager.addHologram(singleHologramEntity);
} catch (HologramNotFoundException e) {
logger.warning("Hologram '" + singleSavedHologram + "' not found, skipping it.");
} catch (InvalidLocationException e) {
logger.warning("Hologram '" + singleSavedHologram + "' has an invalid location format.");
} catch (WorldNotFoundException e) {
logger.warning("Hologram '" + singleSavedHologram + "' was in the world '" + e.getMessage() + "' but it wasn't loaded.");
} catch (Exception e) {
e.printStackTrace();
logger.warning("Unhandled exception while loading '" + singleSavedHologram + "'. Please contact the developer.");
}
}
}
getCommand("holograms").setExecutor(mainCommandHandler = new HologramsCommandHandler());
Bukkit.getPluginManager().registerEvents(new MainListener(nmsManager), this);
try {
MetricsLite metrics = new MetricsLite(this);
metrics.start();
} catch (Exception ignore) { }
// The entities are loaded when the server is ready.
new BukkitRunnable() {
public void run() {
for (CraftHologram hologram : HologramManager.getHolograms()) {
if (!hologram.update()) {
logger.warning("Unable to spawn entities for the hologram '" + hologram.getName() + "'.");
}
}
}
}.runTaskLater(this, 10L);
}
public void loadConfiguration() {
saveDefaultConfig();
boolean needsSave = false;
for (ConfigNode node : ConfigNode.values()) {
if (!getConfig().isSet(node.getPath())) {
getConfig().set(node.getPath(), node.getDefault());
needsSave = true;
}
}
if (needsSave) {
getConfig().options().header(".\n"
+ ". Read the tutorial at: http://dev.bukkit.org/bukkit-plugins/holographic-displays/\n"
+ ".\n"
+ ". Plugin created by filoghost.\n"
+ ".");
getConfig().options().copyHeader(true);
saveConfig();
}
Configuration.updateNotification = ConfigNode.UPDATE_NOTIFICATION.getBoolean(getConfig());
Configuration.verticalLineSpacing = ConfigNode.VERTICAL_SPACING.getDouble(getConfig());
Configuration.imageSymbol = StringUtils.toReadableFormat(ConfigNode.IMAGES_SYMBOL.getString(getConfig()));
Configuration.transparencySymbol = StringUtils.toReadableFormat(ConfigNode.TRANSPARENCY_SPACE.getString(getConfig()));
Configuration.bungeeRefreshSeconds = ConfigNode.BUNGEE_REFRESH_SECONDS.getInt(getConfig());
Configuration.redisBungee = ConfigNode.BUNGEE_USE_REDIS_BUNGEE.getBoolean(getConfig());
try {
Configuration.timeFormat = new SimpleDateFormat(StringUtils.toReadableFormat(ConfigNode.TIME_FORMAT.getString(getConfig())));
} catch (IllegalArgumentException ex) {
Configuration.timeFormat = new SimpleDateFormat("H:mm");
logger.warning("Time format not valid, using the default.");
}
if (Configuration.bungeeRefreshSeconds < 1) {
logger.warning("The minimum interval for pinging BungeeCord's servers is 1 second. It has been automatically set.");
Configuration.bungeeRefreshSeconds = 1;
}
if (Configuration.bungeeRefreshSeconds > 30) {
logger.warning("The maximum interval for pinging BungeeCord's servers is 30 seconds. It has been automatically set.");
Configuration.bungeeRefreshSeconds = 30;
}
String tempColor = ConfigNode.TRANSPARENCY_COLOR.getString(getConfig()).replace("&", "§");
boolean foundColor = false;
for (ChatColor chatColor : ChatColor.values()) {
if (chatColor.toString().equals(tempColor)) {
Configuration.transparencyColor = chatColor;
foundColor = true;
}
}
if (!foundColor) {
Configuration.transparencyColor = ChatColor.GRAY;
logger.warning("You didn't set a valid chat color for the transparency, light gray will be used.");
}
}
public void onDisable() {
for (CraftHologram hologram : HologramManager.getHolograms()) {
hologram.hide();
}
}
private static void printWarnAndDisable(String... messages) {
StringBuffer buffer = new StringBuffer("\n ");
for (String message : messages) {
buffer.append('\n');
buffer.append(message);
}
buffer.append('\n');
System.out.println(buffer.toString());
try {
Thread.sleep(5000);
} catch (InterruptedException ex) { }
instance.setEnabled(false);
}
public static HolographicDisplays getInstance() {
return instance;
}
public HologramsCommandHandler getMainCommandHandler() {
return mainCommandHandler;
}
public static PlaceholderManager getPlaceholderManager() {
return placeholderManager;
}
public static void logInfo(String message) {
logger.info(message);
}
public static void logWarning(String message) {
logger.warning(message);
}
public static void logSevere(String message) {
logger.severe(message);
}
}

View File

@ -1,168 +0,0 @@
package com.gmail.filoghost.holograms;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
/**
* A very simple and lightweight updater.
*/
public final class SimpleUpdater {
public interface ResponseHandler {
/**
* Called when the updater finds a new version.
* @param newVersion - the new version
*/
public void onUpdateFound(final String newVersion);
}
private Plugin plugin;
private int projectId;
public SimpleUpdater(Plugin plugin, int projectId) {
if (plugin == null) {
throw new NullPointerException("Plugin cannot be null");
}
this.plugin = plugin;
this.projectId = projectId;
}
/**
* This method creates a new async thread to check for updates.
*/
public void checkForUpdates(final ResponseHandler responseHandler) {
Thread updaterThread = new Thread(new Runnable() {
@Override
public void run() {
try {
JSONArray filesArray = (JSONArray) readJson("https://api.curseforge.com/servermods/files?projectIds=" + projectId);
if (filesArray.size() == 0) {
// The array cannot be empty, there must be at least one file. The project ID is not valid.
plugin.getLogger().warning("The author of this plugin has misconfigured the Updater system.");
plugin.getLogger().warning("The project ID (" + projectId + ") provided for updating is invalid.");
plugin.getLogger().warning("Please notify the author of this error.");
return;
}
String updateName = (String) ((JSONObject) filesArray.get(filesArray.size() - 1)).get("name");
final String newVersion = extractVersion(updateName);
if (newVersion == null) {
throw new NumberFormatException();
}
if (isNewerVersion(newVersion)) {
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
public void run() {
responseHandler.onUpdateFound(newVersion);
}
});
}
} catch (IOException e) {
plugin.getLogger().warning("Could not contact BukkitDev to check for updates.");
} catch (NumberFormatException e) {
plugin.getLogger().warning("The author of this plugin has misconfigured the Updater system.");
plugin.getLogger().warning("File versions should follow the format 'PluginName vVERSION'");
plugin.getLogger().warning("Please notify the author of this error.");
} catch (Exception e) {
e.printStackTrace();
plugin.getLogger().warning("Unable to check for updates: unhandled exception.");
}
}
});
updaterThread.start();
}
private Object readJson(String url) throws MalformedURLException, IOException {
URLConnection conn = new URL(url).openConnection();
conn.setConnectTimeout(5000);
conn.setReadTimeout(8000);
conn.addRequestProperty("User-Agent", "Updater (by filoghost)");
conn.setDoOutput(true);
return JSONValue.parse(new BufferedReader(new InputStreamReader(conn.getInputStream())));
}
/**
* Compare the version found with the plugin's version, from an array of integer separated by full stops.
* Examples:
* v1.2 > v1.12
* v2.1 = v2.01
*/
private boolean isNewerVersion(String remoteVersion) {
String pluginVersion = plugin.getDescription().getVersion();
if (pluginVersion == null || !pluginVersion.matches("v?[0-9\\.]+")) {
// Do not throw exceptions, just consider it as v0.
pluginVersion = "0";
}
if (!remoteVersion.matches("v?[0-9\\.]+")) {
// Should always be checked before by this class.
throw new IllegalArgumentException("fetched version's format is incorrect");
}
// Remove all the "v" from the versions, replace multiple full stops with a single full stop, and split them.
String[] pluginVersionSplit = pluginVersion.replace("v", "").replaceAll("[\\.]{2,}", ".").split("\\.");
String[] remoteVersionSplit = remoteVersion.replace("v", "").replaceAll("[\\.]{2,}", ".").split("\\.");
int longest = Math.max(pluginVersionSplit.length, remoteVersionSplit.length);
int[] pluginVersionArray = new int[longest];
int[] remoteVersionArray = new int[longest];
for (int i = 0; i < pluginVersionSplit.length; i++) {
pluginVersionArray[i] = Integer.parseInt(pluginVersionSplit[i]);
}
for (int i = 0; i < remoteVersionSplit.length; i++) {
remoteVersionArray[i] = Integer.parseInt(remoteVersionSplit[i]);
}
for (int i = 0; i < longest; i++) {
int diff = remoteVersionArray[i] - pluginVersionArray[i];
if (diff > 0) {
return true;
} else if (diff < 0) {
return false;
}
// Continue the loop
}
return false;
}
private String extractVersion(String input) {
Matcher matcher = Pattern.compile("v[0-9\\.]+").matcher(input);
String result = null;
if (matcher.find()) {
result = matcher.group();
}
return result;
}
}

View File

@ -1,113 +0,0 @@
package com.gmail.filoghost.holograms.api;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.inventory.ItemStack;
public interface FloatingItem {
/**
* Updates the floating item. With floating items this method is not really needed.
* @return false if the spawn was blocked.
*/
public boolean update();
/**
* Hides the floating item. To show the floating item call update().
*/
public void hide();
/**
* Change the current itemStack of this floating item.
*/
public void setItemStack(ItemStack itemstack);
/**
* @return the current itemStack of this floating item.
*/
public ItemStack getItemStack();
/**
* @return the location of the floating item.
*/
public Location getLocation();
/**
* @return the X coordinate of the floating item.
*/
public double getX();
/**
* @return the Y coordinate of the floating item.
*/
public double getY();
/**
* @return the Z coordinate of the floating item.
*/
public double getZ();
/**
* @return the world of the floating item.
*/
public World getWorld();
/**
* Teleports the floating item to a new location, without creating new entities.
* You don't need to call update() after this.
* @param location - the new location of the floating item.
*/
public void teleport(Location location);
/**
* Sets the touch handler of the floating item: whenever a player right clicks it, the onTouch(...)
* method of the TouchHandler is called. If null, the previous touch handler will be removed.
* @param handler - the new TouchHandler.
*/
public void setTouchHandler(ItemTouchHandler handler);
/**
* @return the current touch handler, null if hasTouchHandler() is false.
*/
public ItemTouchHandler getTouchHandler();
/**
* @return true if the floating item has a touch handler.
*/
public boolean hasTouchHandler();
/**
* Sets the pickup handler of the floating item: if not null, when a player picks up the item
* the onPickup(...) method is called. If null, the previous pickup handler will be removed.
* This is very useful for powerups.
* NOTE: the floating item is NOT removed automatically and the player WON'T actually pickup the item,
* in fact the method is just called when the player is near to the floating item.
* @param handler - the new PickupHandler.
*/
public void setPickupHandler(PickupHandler handler);
/**
* @return the current touch handler, null if hasPickupHandler() is false.
*/
public PickupHandler getPickupHandler();
/**
* @return true if the floating item has a pickup handler.
*/
public boolean hasPickupHandler();
/**
* @return the timestamp of when the floating item was created, in milliseconds.
*/
public long getCreationTimestamp();
/**
* Deletes this floating item, removing it from the lists.
*/
public void delete();
/**
* @return true if this floating item was deleted. Calling update() on a deleted floating item will throw an exception.
*/
public boolean isDeleted();
}

View File

@ -1,132 +0,0 @@
package com.gmail.filoghost.holograms.api;
import org.bukkit.Location;
import org.bukkit.World;
public interface Hologram {
/**
* Updates the hologram. This must be used after changing the lines.
* @return false if the spawn was blocked.
*/
public boolean update();
/**
* Hides the hologram. To show the hologram call update().
*/
public void hide();
/**
* Appends a line at the end.
* @param text - the text to append.
*/
public void addLine(String text);
/**
* Removes a line at the given index (0 = first line)
* @param the index of the line to remove.
*/
public void removeLine(int index);
/**
* Changes a line at the given index (0 = first line).
* @param index - the index of the line to change.
* @param text - the new text of the line.
*/
public void setLine(int index, String text);
/**
* Adds a line before the given index (0 = insert before the first line).
* @param index - the text will be inserted before this index.
* @param text - the text to insert.
*/
public void insertLine(int index, String text);
/**
* @return a copy of the lines.
*/
public String[] getLines();
/**
* @return the amount of lines.
*/
public int getLinesLength();
/**
* Removes all the lines from the hologram.
*/
public void clearLines();
/**
* @return the location of the hologram.
*/
public Location getLocation();
/**
* @return the X coordinate of the hologram.
*/
public double getX();
/**
* @return the Y coordinate of the hologram.
*/
public double getY();
/**
* @return the Z coordinate of the hologram.
*/
public double getZ();
/**
* @return the world of the hologram.
*/
public World getWorld();
/**
* Change the location of the hologram. You have to call update() after this method.
* Please note that this method will create new entities every time, so use it wisely.
* @param location - the new location of the hologram.
* @deprecated use teleport(Location location) - it's better and doesn't create new entities
*/
@Deprecated
public void setLocation(Location location);
/**
* Teleports the hologram to a new location, without calling update() and with a smooth movement.
* @param location - the new location of the hologram.
*/
public void teleport(Location location);
/**
* Sets the touch handler of the hologram: whenever a player right clicks it, the onTouch()
* method of the TouchHandler is called. If null, the previous touch handler will be removed.
* @param handler - the new TouchHandler.
*/
public void setTouchHandler(TouchHandler handler);
/**
* @return the current touch handler, null if hasTouchHandler() is false.
*/
public TouchHandler getTouchHandler();
/**
* @return true if the hologram has a touch handler.
*/
public boolean hasTouchHandler();
/**
* @return the timestamp of when the hologram was created, in milliseconds.
*/
public long getCreationTimestamp();
/**
* Deletes this hologram, removing it from the lists.
*/
public void delete();
/**
* @return true if this hologram was deleted. Calling update() on a deleted hologram will throw an exception.
*/
public boolean isDeleted();
}

View File

@ -1,206 +0,0 @@
package com.gmail.filoghost.holograms.api;
import static com.gmail.filoghost.holograms.HolographicDisplays.nmsManager;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import com.gmail.filoghost.holograms.nms.interfaces.NmsManager;
import com.gmail.filoghost.holograms.object.APICraftHologram;
import com.gmail.filoghost.holograms.object.APIFloatingItemManager;
import com.gmail.filoghost.holograms.object.APIHologramManager;
import com.gmail.filoghost.holograms.object.CraftFloatingItem;
import com.gmail.filoghost.holograms.utils.Validator;
import com.gmail.filoghost.holograms.utils.VisibilityManager;
public class HolographicDisplaysAPI {
/**
* Creates a hologram at given location.
* @param plugin - the plugin that creates it.
* @param source - the location where it will appear.
* @param lines - the lines of the new hologram.
* @return the new hologram created.
*/
public static Hologram createHologram(Plugin plugin, Location source, String... lines) {
Validator.notNull(plugin, "plugin cannot be null");
Validator.notNull(source, "source cannot be null");
Validator.notNull(source.getWorld(), "source's world cannot be null");
APICraftHologram hologram = new APICraftHologram(source);
APIHologramManager.addHologram(plugin, hologram);
if (lines != null && lines.length > 0) {
for (String line : lines) {
hologram.addLine(line);
}
}
hologram.update();
return hologram;
}
/**
* Creates a floating item at given location.
* @param plugin - the plugin that creates it.
* @param source - the location where it will appear.
* @param itemstack - the floating item that will appear.
* @return the new floating item created.
*/
public static FloatingItem createFloatingItem(Plugin plugin, Location source, ItemStack itemstack) {
Validator.notNull(plugin, "plugin cannot be null");
Validator.notNull(source, "source cannot be null");
Validator.notNull(source.getWorld(), "source's world cannot be null");
Validator.notNull(itemstack, "itemstack cannot be null");
Validator.checkArgument(itemstack.getType() != Material.AIR, "itemstack cannot be AIR");
CraftFloatingItem floatingItem = new CraftFloatingItem(source, itemstack);
APIFloatingItemManager.addFloatingItem(plugin, floatingItem);
floatingItem.update();
return floatingItem;
}
/**
* Creates a hologram at given location that only a player can see. If the provided player is null, no one will be able to see it.
* IMPORTANT NOTE: Requires ProtocolLib.
* @param plugin - the plugin that creates it.
* @param source - the location where it will appear.
* @param whoCanSee - the player who can see it.
* @param lines - the lines of the new hologram.
* @return the new hologram created.
*/
public static Hologram createIndividualHologram(Plugin plugin, Location source, Player whoCanSee, String... lines) {
List<Player> whoCanSeeList = new ArrayList<Player>();
whoCanSeeList.add(whoCanSee);
return createIndividualHologram(plugin, source, whoCanSeeList, lines);
}
/**
* Creates a hologram at given location that only a list of players can see. If the provided list is null, no one will be able to see it.
* IMPORTANT NOTE: Requires ProtocolLib.
* @param plugin - the plugin that creates it.
* @param source - the location where it will appear.
* @param whoCanSee - a list of players who can see it.
* @param lines - the lines of the new hologram.
* @return the new hologram created.
*/
public static Hologram createIndividualHologram(Plugin plugin, Location source, List<Player> whoCanSee, String... lines) {
Validator.notNull(plugin, "plugin cannot be null");
Validator.notNull(source, "source cannot be null");
Validator.notNull(source.getWorld(), "source's world cannot be null");
APICraftHologram hologram = new APICraftHologram(source);
VisibilityManager visibilityManager = new VisibilityManager();
hologram.setVisibilityManager(visibilityManager);
if (whoCanSee != null) {
for (Player player : whoCanSee) {
hologram.getVisibilityManager().showTo(player);
}
}
APIHologramManager.addHologram(plugin, hologram);
if (lines != null && lines.length > 0) {
for (String line : lines) {
hologram.addLine(line);
}
}
hologram.update();
return hologram;
}
/**
* Creates a floating item at given location that only a player can see. If the provided player is null, no one will be able to see it.
* IMPORTANT NOTE: Requires ProtocolLib.
* @param plugin - the plugin that creates it.
* @param source - the location where it will appear.
* @param whoCanSee - the player who can see it.
* @param itemstack - the floating item that will appear.
* @return the new hologram created.
*/
public static FloatingItem createIndividualFloatingItem(Plugin plugin, Location source, Player whoCanSee, ItemStack itemstack) {
List<Player> whoCanSeeList = new ArrayList<Player>();
whoCanSeeList.add(whoCanSee);
return createIndividualFloatingItem(plugin, source, whoCanSeeList, itemstack);
}
/**
* Creates a floating item at given location that only a list of players can see. If the provided list is null, no one will be able to see it.
* IMPORTANT NOTE: Requires ProtocolLib.
* @param plugin - the plugin that creates it.
* @param source - the location where it will appear.
* @param whoCanSee - a list of players who can see it.
* @param itemstack - the floating item that will appear.
* @return the new hologram created.
*/
public static FloatingItem createIndividualFloatingItem(Plugin plugin, Location source, List<Player> whoCanSee, ItemStack itemstack) {
Validator.notNull(plugin, "plugin cannot be null");
Validator.notNull(source, "source cannot be null");
Validator.notNull(source.getWorld(), "source's world cannot be null");
Validator.notNull(itemstack, "itemstack cannot be null");
Validator.checkArgument(itemstack.getType() != Material.AIR, "itemstack cannot be AIR");
CraftFloatingItem floatingItem = new CraftFloatingItem(source, itemstack);
VisibilityManager visibilityManager = new VisibilityManager();
floatingItem.setVisibilityManager(visibilityManager);
if (whoCanSee != null) {
for (Player player : whoCanSee) {
floatingItem.getVisibilityManager().showTo(player);
}
}
APIFloatingItemManager.addFloatingItem(plugin, floatingItem);
floatingItem.update();
return floatingItem;
}
/**
* @return a copy of all the holograms created with the API by a plugin.
*/
public static Hologram[] getHolograms(Plugin plugin) {
Validator.notNull(plugin, "plugin cannot be null");
return APIHologramManager.getHolograms(plugin);
}
/**
* @return a copy of all the holograms created with the API by a plugin.
*/
public static FloatingItem[] getFloatingItems(Plugin plugin) {
Validator.notNull(plugin, "plugin cannot be null");
return APIFloatingItemManager.getFloatingItems(plugin);
}
/**
* @return if the entity is part of a hologram.
*/
public static boolean isHologramEntity(Entity bukkitEntity) {
Validator.notNull(bukkitEntity, "entity cannot be null");
return nmsManager.isHologramComponent(bukkitEntity);
}
/**
* @deprecated for advanced use only. May change in the future.
*/
@Deprecated
public static NmsManager getNmsManager() {
return nmsManager;
}
}

View File

@ -1,18 +0,0 @@
package com.gmail.filoghost.holograms.api;
import org.bukkit.entity.Player;
/**
* Interface to handle touch floating items.
* NOTE: this doesn't handle item pickup, just right click.
*/
public interface ItemTouchHandler {
/**
* Called when a player interacts with a floating item.
* @param floatingItem - the involved floating item
* @param player - the player who interacts
*/
public void onTouch(FloatingItem floatingItem, Player player);
}

View File

@ -1,17 +0,0 @@
package com.gmail.filoghost.holograms.api;
import org.bukkit.entity.Player;
/**
* Interface to handle floating items being picked up by players.
*/
public interface PickupHandler {
/**
* Called when a player picks up the floating item.
* @param floatingItem - the involved floating item
* @param player - the player who interacts
*/
public void onPickup(FloatingItem floatingItem, Player player);
}

View File

@ -1,17 +0,0 @@
package com.gmail.filoghost.holograms.api;
import org.bukkit.entity.Player;
/**
* Interface to handle touch holograms.
*/
public interface TouchHandler {
/**
* Called when a player interacts with the hologram.
* @param hologram - the involved hologram
* @param player - the player who interacts
*/
public void onTouch(Hologram hologram, Player player);
}

View File

@ -1,88 +0,0 @@
package com.gmail.filoghost.holograms.bungee;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.messaging.PluginMessageListener;
import com.gmail.filoghost.holograms.Configuration;
import com.gmail.filoghost.holograms.HolographicDisplays;
public class BungeeChannel implements PluginMessageListener {
private static BungeeChannel instance;
private static void initialize() {
instance = new BungeeChannel();
Bukkit.getMessenger().registerOutgoingPluginChannel(HolographicDisplays.getInstance(), "BungeeCord");
Bukkit.getMessenger().registerIncomingPluginChannel(HolographicDisplays.getInstance(), "BungeeCord", instance);
Bukkit.getMessenger().registerOutgoingPluginChannel(HolographicDisplays.getInstance(), "RedisBungee");
Bukkit.getMessenger().registerIncomingPluginChannel(HolographicDisplays.getInstance(), "RedisBungee", instance);
}
public static BungeeChannel instance() {
if (instance == null) {
initialize();
}
return instance;
}
@Override
public void onPluginMessageReceived(String channel, Player player, byte[] message) {
if (!channel.equals("BungeeCord") && !channel.equals("RedisBungee")) {
return;
}
DataInputStream in = new DataInputStream(new ByteArrayInputStream(message));
try {
String subChannel = in.readUTF();
if (subChannel.equals("PlayerCount")) {
String server = in.readUTF();
if (in.available() > 0) {
int online = in.readInt();
ServerInfoTimer.handlePing(server, online);
} else {
// If there are no bytes available it means that the server is offline.
ServerInfoTimer.handleOffline(server);
}
}
} catch (EOFException e) {
// Do nothing.
} catch (IOException e) {
// This should never happen.
e.printStackTrace();
}
}
@SuppressWarnings("deprecation")
public void askPlayerCount(String server) {
ByteArrayOutputStream b = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(b);
try {
out.writeUTF("PlayerCount");
out.writeUTF(server);
} catch (IOException e) {
// It should not happen.
e.printStackTrace();
HolographicDisplays.getInstance().getLogger().warning("I/O Exception while asking for player count on server '" + server + "'.");
}
// OR, if you don't need to send it to a specific player
Player[] players = Bukkit.getOnlinePlayers();
if (players.length > 0) {
players[0].sendPluginMessage(HolographicDisplays.getInstance(), Configuration.redisBungee ? "RedisBungee" : "BungeeCord", b.toByteArray());
}
}
}

View File

@ -1,47 +0,0 @@
package com.gmail.filoghost.holograms.bungee;
public class ServerInfo {
private int onlinePlayers;
private boolean isOnline;
private long lastPing;
private long lastRequest;
public ServerInfo(int onlinePlayers, boolean isOnline, long lastPing) {
this.onlinePlayers = onlinePlayers;
this.isOnline = isOnline;
this.lastPing = lastPing;
}
public int getOnlinePlayers() {
return onlinePlayers;
}
public void setOnlinePlayers(int onlinePlayers) {
this.onlinePlayers = onlinePlayers;
}
public long getLastPing() {
return lastPing;
}
public void setLastPing(long lastPing) {
this.lastPing = lastPing;
}
public long getLastRequest() {
return lastRequest;
}
public void setLastRequest(long lastRequest) {
this.lastRequest = lastRequest;
}
public void setOnline(boolean online) {
this.isOnline = online;
}
public boolean isOnline() {
return isOnline;
}
}

View File

@ -1,104 +0,0 @@
package com.gmail.filoghost.holograms.bungee;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Bukkit;
import com.gmail.filoghost.holograms.HolographicDisplays;
public class ServerInfoTimer {
private static Map<String, ServerInfo> trackedServers = new HashMap<String, ServerInfo>();
private static int taskID = -1;
private static int refreshSeconds = 3;
public static void resetTrackedServers() {
trackedServers.clear();
}
public static void track(String server) {
if (!trackedServers.containsKey(server)) {
ServerInfo info = new ServerInfo(0, false, 0);
info.setLastRequest(System.currentTimeMillis());
trackedServers.put(server, info);
BungeeChannel.instance().askPlayerCount(server);
}
}
public static void untrack(String server) {
trackedServers.remove(server);
}
public static void setRefreshSeconds(int seconds) {
if (seconds < 1) {
refreshSeconds = 1;
} else {
refreshSeconds = seconds;
}
}
// Handle a successful ping.
public static void handlePing(String server, int online) {
ServerInfo info = trackedServers.get(server);
if (info == null) {
info = new ServerInfo(online, true, System.currentTimeMillis());
trackedServers.put(server, info);
} else {
info.setLastPing(System.currentTimeMillis());
info.setOnline(true);
info.setOnlinePlayers(online);
}
}
public static void handleOffline(String server) {
ServerInfo info = trackedServers.get(server);
if (info != null) {
info.setOnlinePlayers(0);
info.setOnline(false);
}
}
public static int getPlayersOnline(String server) {
ServerInfo info = trackedServers.get(server);
if (info != null) {
info.setLastRequest(System.currentTimeMillis());
return info.getOnlinePlayers();
} else {
// It was not tracked, add it.
track(server);
return 0;
}
}
public static boolean getOnlineStatus(String server) {
ServerInfo info = trackedServers.get(server);
if (info != null) {
info.setLastRequest(System.currentTimeMillis());
return info.isOnline();
} else {
// It was not tracked, add it.
track(server);
return false;
}
}
public static Map<String, ServerInfo> getMap() {
return trackedServers;
}
public static void startTask() {
if (taskID != -1) {
Bukkit.getScheduler().cancelTask(taskID);
}
taskID = Bukkit.getScheduler().scheduleSyncRepeatingTask(HolographicDisplays.getInstance(), new Runnable() {
public void run() {
for (String server : trackedServers.keySet()) {
BungeeChannel.instance().askPlayerCount(server);
}
}
}, 0, refreshSeconds * 20);
}
}

View File

@ -1,86 +0,0 @@
package com.gmail.filoghost.holograms.commands;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.gmail.filoghost.holograms.exception.CommandException;
import com.gmail.filoghost.holograms.utils.ItemUtils;
public class CommandValidator {
public static void notNull(Object obj, String string) throws CommandException {
if (obj == null) {
throw new CommandException(string);
}
}
public static void isTrue(boolean b, String string) throws CommandException {
if (!b) {
throw new CommandException(string);
}
}
public static int getInteger(String integer) throws CommandException {
try {
return Integer.parseInt(integer);
} catch (NumberFormatException ex) {
throw new CommandException("Invalid number: '" + integer + "'.");
}
}
public static boolean isInteger(String integer) {
try {
Integer.parseInt(integer);
return true;
} catch (NumberFormatException ex) {
return false;
}
}
public static Player getPlayerSender(CommandSender sender) throws CommandException {
if (sender instanceof Player) {
return (Player) sender;
} else {
throw new CommandException("You must be a player to use this command.");
}
}
public static boolean isPlayerSender(CommandSender sender) {
return sender instanceof Player;
}
@SuppressWarnings("deprecation")
public static ItemStack matchItemStack(String input) throws CommandException {
input = input.replace(" ", ""); // Remove the spaces
int dataValue = 0;
if (input.contains(":")) {
String[] split = input.split(":", 2);
dataValue = getInteger(split[1]);
input = split[0];
}
Material match = null;
if (isInteger(input)) {
int id = getInteger(input);
for (Material mat : Material.values()) {
if (mat.getId() == id) {
match = mat;
break;
}
}
} else {
match = ItemUtils.matchMaterial(input);
}
if (match == null || match == Material.AIR) {
throw new CommandException("Invalid material: " + input);
}
return new ItemStack(match, 1, (short) dataValue);
}
}

View File

@ -1,13 +0,0 @@
package com.gmail.filoghost.holograms.commands;
import org.bukkit.ChatColor;
public class Messages {
public static final String NO_SUCH_FLOATING_ITEM = ChatColor.RED + "A floating item with that name doesn't exist.";
public static final String NO_SUCH_HOLOGRAM = ChatColor.RED + "A hologram with that name doesn't exist.";
public static final String FAILED_TO_SPAWN_HERE = ChatColor.GRAY + "(The entities failed to spawn. You MUST allow mobs to spawn here.)";
public static final String BASE_PERM = "holograms.";
}

View File

@ -1,72 +0,0 @@
package com.gmail.filoghost.holograms.commands.main;
import java.util.List;
import org.bukkit.command.CommandSender;
import com.gmail.filoghost.holograms.exception.CommandException;
public abstract class HologramSubCommand {
private String name;
private String permission;
private String[] aliases;
public HologramSubCommand(String name) {
this(name, new String[0]);
}
public HologramSubCommand(String name, String... aliases) {
this.name = name;
this.aliases = aliases;
}
public String getName() {
return name;
}
public void setPermission(String permission) {
this.permission = permission;
}
public String getPermission() {
return permission;
}
public final boolean hasPermission(CommandSender sender) {
if (permission == null) return true;
return sender.hasPermission(permission);
}
public abstract String getPossibleArguments();
public abstract int getMinimumArguments();
public abstract void execute(CommandSender sender, String[] args) throws CommandException;
public abstract List<String> getTutorial();
public abstract SubCommandType getType();
public enum SubCommandType {
GENERIC, EDIT_LINES, HIDDEN
}
public final boolean isValidTrigger(String name) {
if (this.name.equalsIgnoreCase(name)) {
return true;
}
if (aliases != null) {
for (String alias : aliases) {
if (alias.equalsIgnoreCase(name)) {
return true;
}
}
}
return false;
}
}

View File

@ -1,92 +0,0 @@
package com.gmail.filoghost.holograms.commands.main;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.bukkit.ChatColor.*;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import com.gmail.filoghost.holograms.HolographicDisplays;
import com.gmail.filoghost.holograms.commands.main.subs.*;
import com.gmail.filoghost.holograms.exception.CommandException;
import com.gmail.filoghost.holograms.utils.Format;
public class HologramsCommandHandler implements CommandExecutor {
private List<HologramSubCommand> subCommands;
public HologramsCommandHandler() {
subCommands = new ArrayList<HologramSubCommand>();
registerSubCommand(new AddlineCommand());
registerSubCommand(new CreateCommand());
registerSubCommand(new DeleteCommand());
registerSubCommand(new EditCommand());
registerSubCommand(new ListCommand());
registerSubCommand(new NearCommand());
registerSubCommand(new TeleportCommand());
registerSubCommand(new MovehereCommand());
registerSubCommand(new AlignCommand());
registerSubCommand(new FixCommand());
registerSubCommand(new SaveCommand());
registerSubCommand(new ReloadCommand());
registerSubCommand(new RemovelineCommand());
registerSubCommand(new SetlineCommand());
registerSubCommand(new InsertlineCommand());
registerSubCommand(new ReadtextCommand());
registerSubCommand(new ReadimageCommand());
registerSubCommand(new HelpCommand());
}
public void registerSubCommand(HologramSubCommand subCommand) {
subCommands.add(subCommand);
}
public List<HologramSubCommand> getSubCommands() {
return new ArrayList<HologramSubCommand>(subCommands);
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (args.length == 0) {
sender.sendMessage("");
sender.sendMessage(Format.formatTitle("Holographic Displays"));
sender.sendMessage(Format.HIGHLIGHT + "Version: §7" + HolographicDisplays.getInstance().getDescription().getVersion());
sender.sendMessage(Format.HIGHLIGHT + "Developer: §7filoghost");
sender.sendMessage(Format.HIGHLIGHT + "Commands: §7/hd help");
return true;
}
for (HologramSubCommand subCommand : subCommands) {
if (subCommand.isValidTrigger(args[0])) {
if (!subCommand.hasPermission(sender)) {
sender.sendMessage(RED + "You don't have permission.");
return true;
}
if (args.length - 1 >= subCommand.getMinimumArguments()) {
try {
subCommand.execute(sender, Arrays.copyOfRange(args, 1, args.length));
} catch (CommandException e) {
sender.sendMessage(RED + e.getMessage());
}
} else {
sender.sendMessage(RED + "Usage: /" + label + " " + subCommand.getName() + " " + subCommand.getPossibleArguments());
}
return true;
}
}
sender.sendMessage(RED + "Unknown sub-command. Type \"/hd help\" for a list of commands.");
return true;
}
}

View File

@ -1,64 +0,0 @@
package com.gmail.filoghost.holograms.commands.main.subs;
import java.util.Arrays;
import java.util.List;
import org.bukkit.command.CommandSender;
import com.gmail.filoghost.holograms.commands.CommandValidator;
import com.gmail.filoghost.holograms.commands.Messages;
import com.gmail.filoghost.holograms.commands.main.HologramSubCommand;
import com.gmail.filoghost.holograms.database.HologramDatabase;
import com.gmail.filoghost.holograms.exception.CommandException;
import com.gmail.filoghost.holograms.object.CraftHologram;
import com.gmail.filoghost.holograms.object.HologramManager;
import com.gmail.filoghost.holograms.utils.Format;
import com.gmail.filoghost.holograms.utils.StringUtils;
public class AddlineCommand extends HologramSubCommand {
public AddlineCommand() {
super("addline");
setPermission(Messages.BASE_PERM + "addline");
}
@Override
public String getPossibleArguments() {
return "<hologramName> <text>";
}
@Override
public int getMinimumArguments() {
return 2;
}
@Override
public void execute(CommandSender sender, String[] args) throws CommandException {
CraftHologram hologram = HologramManager.getHologram(args[0].toLowerCase());
CommandValidator.notNull(hologram, Messages.NO_SUCH_HOLOGRAM);
if (args[1].equalsIgnoreCase("{empty}")) {
hologram.addLine("");
} else {
hologram.addLine(StringUtils.toReadableFormat(StringUtils.join(args, " ", 1, args.length)));
}
if (!hologram.update()) {
sender.sendMessage(Messages.FAILED_TO_SPAWN_HERE);
}
HologramDatabase.saveHologram(hologram);
HologramDatabase.trySaveToDisk();
sender.sendMessage(Format.HIGHLIGHT + "Line added!");
}
@Override
public List<String> getTutorial() {
return Arrays.asList("Adds a line to an existing hologram.");
}
@Override
public SubCommandType getType() {
return SubCommandType.EDIT_LINES;
}
}

View File

@ -1,82 +0,0 @@
package com.gmail.filoghost.holograms.commands.main.subs;
import java.util.Arrays;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import com.gmail.filoghost.holograms.commands.CommandValidator;
import com.gmail.filoghost.holograms.commands.Messages;
import com.gmail.filoghost.holograms.commands.main.HologramSubCommand;
import com.gmail.filoghost.holograms.database.HologramDatabase;
import com.gmail.filoghost.holograms.exception.CommandException;
import com.gmail.filoghost.holograms.object.CraftHologram;
import com.gmail.filoghost.holograms.object.HologramManager;
import com.gmail.filoghost.holograms.utils.Format;
public class AlignCommand extends HologramSubCommand {
public AlignCommand() {
super("align");
setPermission(Messages.BASE_PERM + "align");
}
@Override
public String getPossibleArguments() {
return "<X|Y|Z|XZ> <hologram> <referenceHologram>";
}
@Override
public int getMinimumArguments() {
return 3;
}
@Override
public void execute(CommandSender sender, String[] args) throws CommandException {
CraftHologram hologram = HologramManager.getHologram(args[1].toLowerCase());
CraftHologram referenceHologram = HologramManager.getHologram(args[2].toLowerCase());
CommandValidator.notNull(hologram, Messages.NO_SUCH_HOLOGRAM + " (hologram to align)");
CommandValidator.notNull(referenceHologram, Messages.NO_SUCH_HOLOGRAM + " (reference hologram)");
CommandValidator.isTrue(hologram != referenceHologram, "The hologram must not be the same!");
Location loc = hologram.getLocation();
if (args[0].equalsIgnoreCase("x")) {
loc.setX(referenceHologram.getX());
} else if (args[0].equalsIgnoreCase("y")) {
loc.setY(referenceHologram.getY());
} else if (args[0].equalsIgnoreCase("z")) {
loc.setZ(referenceHologram.getZ());
} else if (args[0].equalsIgnoreCase("xz")) {
loc.setX(referenceHologram.getX());
loc.setZ(referenceHologram.getZ());
} else {
throw new CommandException("You must specify either X, Y, Z or XZ, " + args[0] + " is not a valid axis.");
}
hologram.setLocation(loc);
if (!hologram.update()) {
sender.sendMessage(Messages.FAILED_TO_SPAWN_HERE);
}
HologramDatabase.saveHologram(hologram);
HologramDatabase.trySaveToDisk();
sender.sendMessage(Format.HIGHLIGHT + "Hologram \"" + hologram.getName() + "\" aligned to the hologram \"" + referenceHologram.getName() + "\" on the " + args[0].toUpperCase() + " axis.");
}
@Override
public List<String> getTutorial() {
return Arrays.asList("Aligns the first hologram to the second, in the specified axis.");
}
@Override
public SubCommandType getType() {
return SubCommandType.GENERIC;
}
}

View File

@ -1,98 +0,0 @@
package com.gmail.filoghost.holograms.commands.main.subs;
import java.util.Arrays;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import com.gmail.filoghost.holograms.commands.CommandValidator;
import com.gmail.filoghost.holograms.commands.Messages;
import com.gmail.filoghost.holograms.commands.main.HologramSubCommand;
import com.gmail.filoghost.holograms.database.HologramDatabase;
import com.gmail.filoghost.holograms.exception.CommandException;
import com.gmail.filoghost.holograms.exception.InvalidCharactersException;
import com.gmail.filoghost.holograms.object.CraftHologram;
import com.gmail.filoghost.holograms.object.HologramManager;
import com.gmail.filoghost.holograms.utils.Format;
import com.gmail.filoghost.holograms.utils.StringUtils;
public class CreateCommand extends HologramSubCommand {
public CreateCommand() {
super("create");
setPermission(Messages.BASE_PERM + "create");
}
@Override
public String getPossibleArguments() {
return "<hologramName> [text]";
}
@Override
public int getMinimumArguments() {
return 1;
}
@SuppressWarnings("deprecation")
@Override
public void execute(CommandSender sender, String[] args) throws CommandException {
try {
Player player = CommandValidator.getPlayerSender(sender);
String name = StringUtils.validateName(args[0].toLowerCase());
CommandValidator.isTrue(!HologramManager.isExistingHologram(name), "A hologram with that name already exists.");
Location spawnLoc = player.getLocation();
boolean moveUp = player.isOnGround();
if (moveUp) {
spawnLoc.add(0.0, 1.2, 0.0);
}
CraftHologram hologram = new CraftHologram(name, spawnLoc);
HologramManager.addHologram(hologram);
if (args.length > 1) {
hologram.addLine(StringUtils.toReadableFormat(StringUtils.join(args, " ", 1, args.length)));
player.sendMessage("§7(Change the lines with /hd edit " + hologram.getName() + ")");
} else {
hologram.addLine("Default hologram. Change it with " + Format.HIGHLIGHT + "/hd edit " + hologram.getName());
}
if (!hologram.forceUpdate()) {
player.sendMessage(Messages.FAILED_TO_SPAWN_HERE);
}
HologramDatabase.saveHologram(hologram);
HologramDatabase.trySaveToDisk();
Location look = player.getLocation();
look.setPitch(90);
player.teleport(look, TeleportCause.PLUGIN);
player.sendMessage(Format.HIGHLIGHT + "You created a hologram named '" + hologram.getName() + "'.");
if (moveUp) {
player.sendMessage("§7(You were on the ground, the hologram was automatically moved up. If you use /hd movehere " + hologram.getName() + ", the hologram will be moved to your feet)");
}
} catch (InvalidCharactersException ex) {
throw new CommandException("The hologram's name must be alphanumeric. '" + ex.getMessage() + "' is not allowed.");
}
}
@Override
public List<String> getTutorial() {
return Arrays.asList("Creates a new hologram with the given name, that must",
"be alphanumeric. The name will be used as reference to",
"that hologram for editing commands.");
}
@Override
public SubCommandType getType() {
return SubCommandType.GENERIC;
}
}

View File

@ -1,57 +0,0 @@
package com.gmail.filoghost.holograms.commands.main.subs;
import java.util.Arrays;
import java.util.List;
import org.bukkit.command.CommandSender;
import com.gmail.filoghost.holograms.commands.CommandValidator;
import com.gmail.filoghost.holograms.commands.Messages;
import com.gmail.filoghost.holograms.commands.main.HologramSubCommand;
import com.gmail.filoghost.holograms.database.HologramDatabase;
import com.gmail.filoghost.holograms.exception.CommandException;
import com.gmail.filoghost.holograms.object.CraftHologram;
import com.gmail.filoghost.holograms.object.HologramManager;
import com.gmail.filoghost.holograms.utils.Format;
public class DeleteCommand extends HologramSubCommand {
public DeleteCommand() {
super("delete", "remove");
setPermission(Messages.BASE_PERM + "delete");
}
@Override
public String getPossibleArguments() {
return "<hologramName>";
}
@Override
public int getMinimumArguments() {
return 1;
}
@Override
public void execute(CommandSender sender, String[] args) throws CommandException {
CraftHologram hologram = HologramManager.getHologram(args[0].toLowerCase());
CommandValidator.notNull(hologram, Messages.NO_SUCH_HOLOGRAM);
hologram.hide();
HologramManager.remove(hologram);
HologramDatabase.deleteHologram(hologram);
HologramDatabase.trySaveToDisk();
sender.sendMessage(Format.HIGHLIGHT + "You deleted the hologram '" + hologram.getName() + "'.");
}
@Override
public List<String> getTutorial() {
return Arrays.asList("Deletes a hologram. Cannot be undone.");
}
@Override
public SubCommandType getType() {
return SubCommandType.GENERIC;
}
}

View File

@ -1,96 +0,0 @@
package com.gmail.filoghost.holograms.commands.main.subs;
import static org.bukkit.ChatColor.AQUA;
import static org.bukkit.ChatColor.BOLD;
import static org.bukkit.ChatColor.GOLD;
import static org.bukkit.ChatColor.ITALIC;
import static org.bukkit.ChatColor.UNDERLINE;
import static org.bukkit.ChatColor.WHITE;
import static org.bukkit.ChatColor.YELLOW;
import java.util.Arrays;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.gmail.filoghost.holograms.HolographicDisplays;
import com.gmail.filoghost.holograms.commands.CommandValidator;
import com.gmail.filoghost.holograms.commands.Messages;
import com.gmail.filoghost.holograms.commands.main.HologramSubCommand;
import com.gmail.filoghost.holograms.exception.CommandException;
import com.gmail.filoghost.holograms.object.CraftHologram;
import com.gmail.filoghost.holograms.object.HologramManager;
import com.gmail.filoghost.holograms.utils.Format;
import com.gmail.filoghost.holograms.utils.ItemUtils;
public class EditCommand extends HologramSubCommand {
public EditCommand() {
super("edit");
setPermission(Messages.BASE_PERM + "edit");
}
@Override
public String getPossibleArguments() {
return "<hologramName>";
}
@Override
public int getMinimumArguments() {
return 1;
}
@Override
public void execute(CommandSender sender, String[] args) throws CommandException {
String name = args[0].toLowerCase();
CraftHologram hologram = HologramManager.getHologram(name);
CommandValidator.notNull(hologram, Messages.NO_SUCH_HOLOGRAM);
sender.sendMessage("");
sender.sendMessage(Format.formatTitle("How to edit the hologram '" + name + "'"));
for (HologramSubCommand subCommand : HolographicDisplays.getInstance().getMainCommandHandler().getSubCommands()) {
if (subCommand.getType() == SubCommandType.EDIT_LINES) {
String usage = "/hd " + subCommand.getName() + (subCommand.getPossibleArguments().length() > 0 ? " " + subCommand.getPossibleArguments().replace("<hologramName>", hologram.getName()).replace("<hologram>", hologram.getName()) : "");
if (CommandValidator.isPlayerSender(sender)) {
HolographicDisplays.nmsManager.newFancyMessage(usage)
.color(AQUA)
.suggest(usage)
.itemTooltip(ItemUtils.getStone("§b" + usage, subCommand.getTutorial(), ChatColor.GRAY))
.send((Player) sender);
} else {
sender.sendMessage("§b" + usage);
}
}
}
if (CommandValidator.isPlayerSender(sender) && HolographicDisplays.nmsManager.hasChatHoverFeature()) {
sender.sendMessage("");
HolographicDisplays.nmsManager.newFancyMessage("[").color(GOLD)
.then("Tip").style(BOLD).color(YELLOW)
.then("]").color(GOLD)
.then(" Try to ").color(WHITE)
.then("hover").color(WHITE).style(ITALIC, UNDERLINE)
.tooltip("§dHover on the commands to get info about them.")
.then(" or ")
.then("click").color(WHITE).style(ITALIC, UNDERLINE)
.tooltip("§dClick on the commands to insert them in the chat.")
.then(" on the commands!")
.send((Player) sender);
}
}
@Override
public List<String> getTutorial() {
return Arrays.asList("Shows the commands to manipulate an existing hologram.");
}
@Override
public SubCommandType getType() {
return SubCommandType.GENERIC;
}
}

View File

@ -1,71 +0,0 @@
package com.gmail.filoghost.holograms.commands.main.subs;
import java.util.Arrays;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.command.CommandSender;
import com.gmail.filoghost.holograms.commands.CommandValidator;
import com.gmail.filoghost.holograms.commands.Messages;
import com.gmail.filoghost.holograms.commands.main.HologramSubCommand;
import com.gmail.filoghost.holograms.exception.CommandException;
import com.gmail.filoghost.holograms.object.CraftHologram;
import com.gmail.filoghost.holograms.object.HologramManager;
import com.gmail.filoghost.holograms.utils.Format;
public class FixCommand extends HologramSubCommand {
public FixCommand() {
super("fix", "light");
setPermission(Messages.BASE_PERM + "fix");
}
@Override
public String getPossibleArguments() {
return "<hologramName>";
}
@Override
public int getMinimumArguments() {
return 1;
}
@Override
public void execute(CommandSender sender, String[] args) throws CommandException {
CraftHologram hologram = HologramManager.getHologram(args[0].toLowerCase());
CommandValidator.notNull(hologram, Messages.NO_SUCH_HOLOGRAM);
if (args.length <= 1) {
sender.sendMessage(Format.HIGHLIGHT + "This command will put a glowstone 16 blocks above the hologram to fix the lightning.");
sender.sendMessage(Format.HIGHLIGHT + "If you're sure, type §f/hd fix " + args[0].toLowerCase() + " confirm");
return;
}
if (args[1].equalsIgnoreCase("confirm")) {
Block block = hologram.getWorld().getBlockAt(hologram.getBlockX(), hologram.getBlockY() + 16, hologram.getBlockZ());
String oldType = block.getType().toString().replace("_", " ").toLowerCase();
block.setType(Material.GLOWSTONE);
sender.sendMessage(Format.HIGHLIGHT + "Changed the block 16 block above the hologram (" + oldType + ") to glowstone!");
} else {
sender.sendMessage("§c" + args[1] + " is not a valid confirmation! Use \"confirm\".");
}
}
@Override
public List<String> getTutorial() {
return Arrays.asList("This command will fix the lightning of a hologram,",
"placing a glowstone block 16 blocks above it.",
"That's the only way to fix it.");
}
@Override
public SubCommandType getType() {
return SubCommandType.GENERIC;
}
}

View File

@ -1,85 +0,0 @@
package com.gmail.filoghost.holograms.commands.main.subs;
import static org.bukkit.ChatColor.*;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.gmail.filoghost.holograms.HolographicDisplays;
import com.gmail.filoghost.holograms.commands.CommandValidator;
import com.gmail.filoghost.holograms.commands.Messages;
import com.gmail.filoghost.holograms.commands.main.HologramSubCommand;
import com.gmail.filoghost.holograms.exception.CommandException;
import com.gmail.filoghost.holograms.utils.Format;
import com.gmail.filoghost.holograms.utils.ItemUtils;
public class HelpCommand extends HologramSubCommand {
public HelpCommand() {
super("help");
setPermission(Messages.BASE_PERM + "help");
}
@Override
public String getPossibleArguments() {
return "";
}
@Override
public int getMinimumArguments() {
return 0;
}
@Override
public void execute(CommandSender sender, String[] args) throws CommandException {
sender.sendMessage("");
sender.sendMessage(Format.formatTitle("Holographic Displays Commands"));
for (HologramSubCommand subCommand : HolographicDisplays.getInstance().getMainCommandHandler().getSubCommands()) {
if (subCommand.getType() == SubCommandType.GENERIC) {
String usage = "/hd " + subCommand.getName() + (subCommand.getPossibleArguments().length() > 0 ? " " + subCommand.getPossibleArguments() : "");
if (CommandValidator.isPlayerSender(sender)) {
HolographicDisplays.nmsManager.newFancyMessage(usage)
.color(AQUA)
.suggest(usage)
.itemTooltip(ItemUtils.getStone("§b" + usage, subCommand.getTutorial(), ChatColor.GRAY))
.send((Player) sender);
} else {
sender.sendMessage("§b" + usage);
}
}
}
if (CommandValidator.isPlayerSender(sender) && HolographicDisplays.nmsManager.hasChatHoverFeature()) {
sender.sendMessage("");
HolographicDisplays.nmsManager.newFancyMessage("[").color(GOLD)
.then("Tip").style(BOLD).color(YELLOW)
.then("]").color(GOLD)
.then(" Try to ").color(WHITE)
.then("hover").color(WHITE).style(ITALIC, UNDERLINE)
.tooltip("§dHover on the commands to get info about them.")
.then(" or ")
.then("click").color(WHITE).style(ITALIC, UNDERLINE)
.tooltip("§dClick on the commands to insert them in the chat.")
.then(" on the commands!")
.send((Player) sender);
}
}
@Override
public List<String> getTutorial() {
return null;
}
@Override
public SubCommandType getType() {
return SubCommandType.HIDDEN;
}
}

View File

@ -1,81 +0,0 @@
package com.gmail.filoghost.holograms.commands.main.subs;
import java.util.Arrays;
import java.util.List;
import org.bukkit.command.CommandSender;
import com.gmail.filoghost.holograms.commands.CommandValidator;
import com.gmail.filoghost.holograms.commands.Messages;
import com.gmail.filoghost.holograms.commands.main.HologramSubCommand;
import com.gmail.filoghost.holograms.database.HologramDatabase;
import com.gmail.filoghost.holograms.exception.CommandException;
import com.gmail.filoghost.holograms.object.CraftHologram;
import com.gmail.filoghost.holograms.object.HologramManager;
import com.gmail.filoghost.holograms.utils.Format;
import com.gmail.filoghost.holograms.utils.StringUtils;
public class InsertlineCommand extends HologramSubCommand {
public InsertlineCommand() {
super("insertline");
setPermission(Messages.BASE_PERM + "insertline");
}
@Override
public String getPossibleArguments() {
return "<hologramName> <lineNumber> <text>";
}
@Override
public int getMinimumArguments() {
return 3;
}
@Override
public void execute(CommandSender sender, String[] args) throws CommandException {
CraftHologram hologram = HologramManager.getHologram(args[0].toLowerCase());
CommandValidator.notNull(hologram, Messages.NO_SUCH_HOLOGRAM);
int insertAfter = CommandValidator.getInteger(args[1]);
int oldLinesAmount = hologram.getLinesLength();
CommandValidator.isTrue(insertAfter >= 0 && insertAfter <= oldLinesAmount, "The number must be between 0 and " + hologram.getLinesLength() + "(amount of lines of the hologram).");
if (args[2].equalsIgnoreCase("{empty}")) {
hologram.insertLine(insertAfter, "");
} else {
hologram.insertLine(insertAfter, StringUtils.toReadableFormat(StringUtils.join(args, " ", 2, args.length)));
}
if (!hologram.update()) {
sender.sendMessage(Messages.FAILED_TO_SPAWN_HERE);
}
HologramDatabase.saveHologram(hologram);
HologramDatabase.trySaveToDisk();
if (insertAfter == 0) {
sender.sendMessage(Format.HIGHLIGHT + "Line inserted before line n.1!");
} else if (insertAfter == oldLinesAmount) {
sender.sendMessage(Format.HIGHLIGHT + "Line appended at the end!");
sender.sendMessage("§7[Tip] Next time use /hd addline to add a line at the end.");
} else {
sender.sendMessage(Format.HIGHLIGHT + "Line inserted between lines " + insertAfter + " and " + (insertAfter+1) + "!");
}
}
@Override
public List<String> getTutorial() {
return Arrays.asList("Inserts a line after the specified index.",
"If the index is 0, the line will be put before",
"the first line of the hologram.");
}
@Override
public SubCommandType getType() {
return SubCommandType.EDIT_LINES;
}
}

View File

@ -1,81 +0,0 @@
package com.gmail.filoghost.holograms.commands.main.subs;
import java.util.Arrays;
import java.util.List;
import org.bukkit.command.CommandSender;
import com.gmail.filoghost.holograms.commands.CommandValidator;
import com.gmail.filoghost.holograms.commands.Messages;
import com.gmail.filoghost.holograms.commands.main.HologramSubCommand;
import com.gmail.filoghost.holograms.exception.CommandException;
import com.gmail.filoghost.holograms.object.CraftHologram;
import com.gmail.filoghost.holograms.object.HologramManager;
import com.gmail.filoghost.holograms.utils.Format;
public class ListCommand extends HologramSubCommand {
private static final int HOLOGRAMS_PER_PAGE = 10;
public ListCommand() {
super("list");
setPermission(Messages.BASE_PERM + "list");
}
@Override
public String getPossibleArguments() {
return "[page]";
}
@Override
public int getMinimumArguments() {
return 0;
}
@Override
public void execute(CommandSender sender, String[] args) throws CommandException {
int page = args.length > 0 ? CommandValidator.getInteger(args[0]) : 1;
if (page < 1) {
throw new CommandException("Page number must be 1 or greater.");
}
int totalPages = HologramManager.size() / HOLOGRAMS_PER_PAGE;
if (HologramManager.size() % HOLOGRAMS_PER_PAGE != 0) {
totalPages++;
}
if (HologramManager.size() == 0) {
throw new CommandException("There are no holograms yet. Create one with /hd create.");
}
sender.sendMessage("");
sender.sendMessage(Format.formatTitle("Holograms list §f(Page " + page + " of " + totalPages + ")"));
int fromIndex = (page - 1) * HOLOGRAMS_PER_PAGE;
int toIndex = fromIndex + HOLOGRAMS_PER_PAGE;
for (int i = fromIndex; i < toIndex; i++) {
if (i < HologramManager.size()) {
CraftHologram hologram = HologramManager.get(i);
sender.sendMessage("§3- §f'" + hologram.getName() + "' §7at x: " + hologram.getBlockX() + ", y: " + hologram.getBlockY() + ", z: " + hologram.getBlockZ() + " (" + hologram.getLinesLength() + " lines, world: \"" + hologram.getWorld().getName() + "\")");
}
}
if (page < totalPages) {
sender.sendMessage("§f[Tip] §7See the next page with /holograms list " + (page + 1));
}
}
@Override
public List<String> getTutorial() {
return Arrays.asList("Lists all the existing holograms.");
}
@Override
public SubCommandType getType() {
return SubCommandType.GENERIC;
}
}

View File

@ -1,68 +0,0 @@
package com.gmail.filoghost.holograms.commands.main.subs;
import java.util.Arrays;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import com.gmail.filoghost.holograms.commands.CommandValidator;
import com.gmail.filoghost.holograms.commands.Messages;
import com.gmail.filoghost.holograms.commands.main.HologramSubCommand;
import com.gmail.filoghost.holograms.database.HologramDatabase;
import com.gmail.filoghost.holograms.exception.CommandException;
import com.gmail.filoghost.holograms.object.CraftHologram;
import com.gmail.filoghost.holograms.object.HologramManager;
import com.gmail.filoghost.holograms.utils.Format;
public class MovehereCommand extends HologramSubCommand {
public MovehereCommand() {
super("movehere");
setPermission(Messages.BASE_PERM + "movehere");
}
@Override
public String getPossibleArguments() {
return "<hologramName>";
}
@Override
public int getMinimumArguments() {
return 1;
}
@Override
public void execute(CommandSender sender, String[] args) throws CommandException {
Player player = CommandValidator.getPlayerSender(sender);
CraftHologram hologram = HologramManager.getHologram(args[0].toLowerCase());
CommandValidator.notNull(hologram, Messages.NO_SUCH_HOLOGRAM);
hologram.setLocation(player.getLocation());
if (!hologram.update()) {
player.sendMessage(Messages.FAILED_TO_SPAWN_HERE);
}
HologramDatabase.saveHologram(hologram);
HologramDatabase.trySaveToDisk();
Location to = player.getLocation();
to.setPitch(90);
player.teleport(to, TeleportCause.PLUGIN);
player.sendMessage(Format.HIGHLIGHT + "You moved the hologram '" + hologram.getName() + "' near to you.");
}
@Override
public List<String> getTutorial() {
return Arrays.asList("Moves a hologram to your location.");
}
@Override
public SubCommandType getType() {
return SubCommandType.GENERIC;
}
}

View File

@ -1,72 +0,0 @@
package com.gmail.filoghost.holograms.commands.main.subs;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.gmail.filoghost.holograms.commands.CommandValidator;
import com.gmail.filoghost.holograms.commands.Messages;
import com.gmail.filoghost.holograms.commands.main.HologramSubCommand;
import com.gmail.filoghost.holograms.exception.CommandException;
import com.gmail.filoghost.holograms.object.CraftHologram;
import com.gmail.filoghost.holograms.object.HologramManager;
import com.gmail.filoghost.holograms.utils.Format;
public class NearCommand extends HologramSubCommand {
public NearCommand() {
super("near");
setPermission(Messages.BASE_PERM + "near");
}
@Override
public String getPossibleArguments() {
return "<radius>";
}
@Override
public int getMinimumArguments() {
return 1;
}
@Override
public void execute(CommandSender sender, String[] args) throws CommandException {
Player player = CommandValidator.getPlayerSender(sender);
int radius = CommandValidator.getInteger(args[0]);
CommandValidator.isTrue(radius > 0, "Radius must be at least 1.");
World world = player.getWorld();
int radiusSquared = radius * radius;
List<CraftHologram> nearHolograms = new ArrayList<CraftHologram>();
for (CraftHologram hologram : HologramManager.getHolograms()) {
if (hologram.getLocation().getWorld().equals(world) && hologram.getLocation().distanceSquared(player.getLocation()) <= radiusSquared) {
nearHolograms.add(hologram);
}
}
if (nearHolograms.size() > 0) {
player.sendMessage(Format.formatTitle("Near holograms"));
for (CraftHologram nearHologram : nearHolograms) {
player.sendMessage("§3- §f'" + nearHologram.getName() + "' §7at x: " + nearHologram.getBlockX() + ", y: " + nearHologram.getBlockY() + ", z: " + nearHologram.getBlockZ() + " (lines: " + nearHologram.getLinesLength() + ")");
}
} else {
player.sendMessage("§cThere are no holograms in the given radius.");
}
}
@Override
public List<String> getTutorial() {
return Arrays.asList("Get a list of near holograms.");
}
@Override
public SubCommandType getType() {
return SubCommandType.GENERIC;
}
}

View File

@ -1,112 +0,0 @@
package com.gmail.filoghost.holograms.commands.main.subs;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import org.bukkit.command.CommandSender;
import com.gmail.filoghost.holograms.commands.CommandValidator;
import com.gmail.filoghost.holograms.commands.Messages;
import com.gmail.filoghost.holograms.commands.main.HologramSubCommand;
import com.gmail.filoghost.holograms.database.HologramDatabase;
import com.gmail.filoghost.holograms.exception.CommandException;
import com.gmail.filoghost.holograms.exception.TooWideException;
import com.gmail.filoghost.holograms.exception.UnreadableImageException;
import com.gmail.filoghost.holograms.image.ImageMessage;
import com.gmail.filoghost.holograms.object.CraftHologram;
import com.gmail.filoghost.holograms.object.HologramManager;
import com.gmail.filoghost.holograms.utils.FileUtils;
import com.gmail.filoghost.holograms.utils.Format;
public class ReadimageCommand extends HologramSubCommand {
public ReadimageCommand() {
super("readimage", "image");
setPermission(Messages.BASE_PERM + "readimage");
}
@Override
public String getPossibleArguments() {
return "<hologram> <imageWithExtension> <width>";
}
@Override
public int getMinimumArguments() {
return 3;
}
@Override
public void execute(CommandSender sender, String[] args) throws CommandException {
CraftHologram hologram = HologramManager.getHologram(args[0].toLowerCase());
CommandValidator.notNull(hologram, Messages.NO_SUCH_HOLOGRAM);
int width = CommandValidator.getInteger(args[2]);
CommandValidator.isTrue(width >= 3, "The width of the image must be 3 or greater.");
try {
BufferedImage image = FileUtils.readImage(args[1]);
hologram.clearLines();
ImageMessage imageMessage = new ImageMessage(image, width);
String[] newLines = imageMessage.getLines();
for (int i = 0; i < newLines.length; i++) {
hologram.addLine(newLines[i]);
}
if (!hologram.update()) {
sender.sendMessage(Messages.FAILED_TO_SPAWN_HERE);
}
if (newLines.length < 5) {
sender.sendMessage("§6[§eTip§6] §fSeems that the image has a very low height. You can increase it by increasing the width.");
}
HologramDatabase.saveHologram(hologram);
HologramDatabase.trySaveToDisk();
sender.sendMessage(Format.HIGHLIGHT + "The image was drawn in the hologram!");
} catch (FileNotFoundException e) {
throw new CommandException("The image '" + args[1] + "' doesn't exist in the plugin's folder.");
} catch (TooWideException e) {
throw new CommandException("The image is too large. Max width allowed is 100 pixels.");
} catch (UnreadableImageException e) {
throw new CommandException("The plugin was unable to read the image. Be sure that the format is supported.");
} catch (IOException e) {
throw new CommandException("I/O exception while reading the image. Is it in use?");
} catch (Exception e) {
e.printStackTrace();
throw new CommandException("Unhandled exception while reading the image! Please look the console.");
}
}
@Override
public List<String> getTutorial() {
return Arrays.asList("Reads an image from a file. §fTutorial:",
"1) Move the image in the plugin's folder",
"2) Do not use spaces in the name",
"3) Do /hd read <hologram> <image> <width>",
"4) Choose <width> to automatically resize the image",
"",
"§fExample: §7you have an image named §f'logo.png'§7, you want",
"to paste it in the hologram named §f'test'§7, with a width of 50",
"pixels. In this case you would execute the following command:",
"§e/hd readimage test logo.png 50",
"",
"The symbols used to create the image are taken from the config.yml.",
"",
"§c§l§nNOTE:§f Do not use big images, as they can cause lag to clients.");
}
@Override
public SubCommandType getType() {
return SubCommandType.EDIT_LINES;
}
}

View File

@ -1,110 +0,0 @@
package com.gmail.filoghost.holograms.commands.main.subs;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import org.bukkit.command.CommandSender;
import com.gmail.filoghost.holograms.commands.CommandValidator;
import com.gmail.filoghost.holograms.commands.Messages;
import com.gmail.filoghost.holograms.commands.main.HologramSubCommand;
import com.gmail.filoghost.holograms.database.HologramDatabase;
import com.gmail.filoghost.holograms.exception.CommandException;
import com.gmail.filoghost.holograms.object.CraftHologram;
import com.gmail.filoghost.holograms.object.HologramManager;
import com.gmail.filoghost.holograms.utils.FileUtils;
import com.gmail.filoghost.holograms.utils.Format;
import com.gmail.filoghost.holograms.utils.StringUtils;
public class ReadtextCommand extends HologramSubCommand {
public ReadtextCommand() {
super("readtext", "readlines");
setPermission(Messages.BASE_PERM + "readtext");
}
@Override
public String getPossibleArguments() {
return "<hologramName> <fileWithExtension>";
}
@Override
public int getMinimumArguments() {
return 2;
}
@Override
public void execute(CommandSender sender, String[] args) throws CommandException {
CraftHologram hologram = HologramManager.getHologram(args[0].toLowerCase());
CommandValidator.notNull(hologram, Messages.NO_SUCH_HOLOGRAM);
try {
List<String> lines = FileUtils.readLines(args[1]);
hologram.clearLines();
int linesAmount = lines.size();
if (linesAmount > 40) {
sender.sendMessage("§eThe file contained more than 40 lines, that have been limited.");
linesAmount = 40;
}
for (int i = 0; i < linesAmount; i++) {
hologram.addLine(StringUtils.toReadableFormat(lines.get(i)));
}
if (!hologram.update()) {
sender.sendMessage(Messages.FAILED_TO_SPAWN_HERE);
}
HologramDatabase.saveHologram(hologram);
HologramDatabase.trySaveToDisk();
if (args[1].contains(".")) {
if (isImageExtension(args[1].substring(args[1].lastIndexOf('.') + 1))) {
sender.sendMessage("§eSeems that the file read was an image. If so, you should use /hd readimage.");
}
}
sender.sendMessage(Format.HIGHLIGHT + "The lines were pasted into the hologram!");
} catch (FileNotFoundException e) {
throw new CommandException("A file named '" + args[1] + "' doesn't exist in the plugin's folder.");
} catch (IOException e) {
throw new CommandException("I/O exception while reading the file. Is it in use?");
} catch (Exception e) {
e.printStackTrace();
throw new CommandException("Unhandled exception while reading the file! Please look the console.");
}
}
@Override
public List<String> getTutorial() {
return Arrays.asList("Reads the lines from a text file. §fTutorial:",
"1) Create a new text file in the plugin's folder",
"2) Do not use spaces in the name",
"3) Each line will be a line in the hologram",
"4) Do /hd readlines <hologramName> <fileWithExtension>",
"",
"§fExample: §7you have a file named §f'info.txt'§7, and you want",
"to paste it in the hologram named §f'test'§7. In this case you",
"would execute §e/hd readlines test info.txt");
}
@Override
public SubCommandType getType() {
return SubCommandType.EDIT_LINES;
}
private boolean isImageExtension(String input) {
String[] imageExtensions = new String[]{"jpg", "png", "jpeg", "gif"};
for (String ext : imageExtensions) {
if (input.equalsIgnoreCase(ext)) {
return true;
}
}
return false;
}
}

View File

@ -1,102 +0,0 @@
package com.gmail.filoghost.holograms.commands.main.subs;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import org.bukkit.command.CommandSender;
import com.gmail.filoghost.holograms.Configuration;
import com.gmail.filoghost.holograms.HolographicDisplays;
import com.gmail.filoghost.holograms.bungee.ServerInfoTimer;
import com.gmail.filoghost.holograms.commands.Messages;
import com.gmail.filoghost.holograms.commands.main.HologramSubCommand;
import com.gmail.filoghost.holograms.database.HologramDatabase;
import com.gmail.filoghost.holograms.exception.CommandException;
import com.gmail.filoghost.holograms.exception.HologramNotFoundException;
import com.gmail.filoghost.holograms.exception.InvalidLocationException;
import com.gmail.filoghost.holograms.exception.WorldNotFoundException;
import com.gmail.filoghost.holograms.object.CraftHologram;
import com.gmail.filoghost.holograms.object.HologramManager;
import com.gmail.filoghost.holograms.placeholders.AnimationManager;
import com.gmail.filoghost.holograms.placeholders.StaticPlaceholders;
import com.gmail.filoghost.holograms.utils.Format;
public class ReloadCommand extends HologramSubCommand {
public ReloadCommand() {
super("reload");
setPermission(Messages.BASE_PERM + "reload");
}
@Override
public String getPossibleArguments() {
return "";
}
@Override
public int getMinimumArguments() {
return 0;
}
@Override
public void execute(CommandSender sender, String[] args) throws CommandException {
try {
long startMillis = System.currentTimeMillis();
HolographicDisplays.getInstance().reloadConfig();
HolographicDisplays.getInstance().loadConfiguration();
ServerInfoTimer.setRefreshSeconds(Configuration.bungeeRefreshSeconds);
ServerInfoTimer.startTask();
StaticPlaceholders.load();
HologramDatabase.initialize();
HologramManager.clearAll();
AnimationManager.loadAnimations();
Set<String> savedHolograms = HologramDatabase.getHolograms();
if (savedHolograms != null && savedHolograms.size() > 0) {
for (String singleSavedHologram : savedHolograms) {
try {
CraftHologram singleHologramEntity = HologramDatabase.loadHologram(singleSavedHologram);
HologramManager.addHologram(singleHologramEntity);
} catch (HologramNotFoundException e) {
Format.sendWarning(sender, "Hologram '" + singleSavedHologram + "' not found, skipping it.");
} catch (InvalidLocationException e) {
Format.sendWarning(sender, "Hologram '" + singleSavedHologram + "' has an invalid location format.");
} catch (WorldNotFoundException e) {
Format.sendWarning(sender, "Hologram '" + singleSavedHologram + "' was in the world '" + e.getMessage() + "' but it wasn't loaded.");
}
}
}
for (CraftHologram hologram : HologramManager.getHolograms()) {
if (!hologram.update()) {
sender.sendMessage("§c[ ! ] §7Unable to spawn entities for the hologram '" + hologram.getName() + "'.");
}
}
long endMillis = System.currentTimeMillis();
sender.sendMessage("§bConfiguration reloaded successfully in " + (endMillis - startMillis) + "ms!");
} catch (Exception ex) {
ex.printStackTrace();
throw new CommandException("Exception while reloading the configuration. Please look the console.");
}
}
@Override
public List<String> getTutorial() {
return Arrays.asList("Reloads the holograms from the database.");
}
@Override
public SubCommandType getType() {
return SubCommandType.GENERIC;
}
}

View File

@ -1,68 +0,0 @@
package com.gmail.filoghost.holograms.commands.main.subs;
import java.util.Arrays;
import java.util.List;
import org.bukkit.command.CommandSender;
import com.gmail.filoghost.holograms.commands.CommandValidator;
import com.gmail.filoghost.holograms.commands.Messages;
import com.gmail.filoghost.holograms.commands.main.HologramSubCommand;
import com.gmail.filoghost.holograms.database.HologramDatabase;
import com.gmail.filoghost.holograms.exception.CommandException;
import com.gmail.filoghost.holograms.object.CraftHologram;
import com.gmail.filoghost.holograms.object.HologramManager;
import com.gmail.filoghost.holograms.utils.Format;
public class RemovelineCommand extends HologramSubCommand {
public RemovelineCommand() {
super("removeline");
setPermission(Messages.BASE_PERM + "removeline");
}
@Override
public String getPossibleArguments() {
return "<hologramName> <lineNumber>";
}
@Override
public int getMinimumArguments() {
return 2;
}
@Override
public void execute(CommandSender sender, String[] args) throws CommandException {
CraftHologram hologram = HologramManager.getHologram(args[0].toLowerCase());
CommandValidator.notNull(hologram, Messages.NO_SUCH_HOLOGRAM);
int lineNumber = CommandValidator.getInteger(args[1]);
CommandValidator.isTrue(lineNumber >= 1 && lineNumber <= hologram.getLinesLength(), "The line number must be between 1 and " + hologram.getLinesLength() + ".");
int index = lineNumber - 1;
CommandValidator.isTrue(hologram.getLinesLength() > 1, "The hologram should have at least 1 line.");
hologram.removeLine(index);
if (!hologram.update()) {
sender.sendMessage(Messages.FAILED_TO_SPAWN_HERE);
}
HologramDatabase.saveHologram(hologram);
HologramDatabase.trySaveToDisk();
sender.sendMessage(Format.HIGHLIGHT + "Line " + lineNumber + " removed!");
}
@Override
public List<String> getTutorial() {
return Arrays.asList("Removes a line from a hologram.");
}
@Override
public SubCommandType getType() {
return SubCommandType.EDIT_LINES;
}
}

View File

@ -1,56 +0,0 @@
package com.gmail.filoghost.holograms.commands.main.subs;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import org.bukkit.command.CommandSender;
import com.gmail.filoghost.holograms.commands.Messages;
import com.gmail.filoghost.holograms.commands.main.HologramSubCommand;
import com.gmail.filoghost.holograms.database.HologramDatabase;
import com.gmail.filoghost.holograms.exception.CommandException;
import com.gmail.filoghost.holograms.utils.Format;
public class SaveCommand extends HologramSubCommand {
public SaveCommand() {
super("save");
setPermission(Messages.BASE_PERM + "save");
}
@Override
public String getPossibleArguments() {
return "";
}
@Override
public int getMinimumArguments() {
return 0;
}
@Override
public void execute(CommandSender sender, String[] args) throws CommandException {
try {
HologramDatabase.saveToDisk();
sender.sendMessage(Format.HIGHLIGHT + "Holograms saved!");
} catch (IOException e) {
e.printStackTrace();
throw new CommandException("Unable to save holograms to database.yml! Was the file in use? Look the console for more info.");
}
}
@Override
public List<String> getTutorial() {
return Arrays.asList("Saves all the holograms to the database. You usually",
"don't need to use this command, because the holograms",
"are automatically saved to disk every 10 minutes.");
}
@Override
public SubCommandType getType() {
return SubCommandType.HIDDEN;
}
}

View File

@ -1,72 +0,0 @@
package com.gmail.filoghost.holograms.commands.main.subs;
import java.util.Arrays;
import java.util.List;
import org.bukkit.command.CommandSender;
import com.gmail.filoghost.holograms.commands.CommandValidator;
import com.gmail.filoghost.holograms.commands.Messages;
import com.gmail.filoghost.holograms.commands.main.HologramSubCommand;
import com.gmail.filoghost.holograms.database.HologramDatabase;
import com.gmail.filoghost.holograms.exception.CommandException;
import com.gmail.filoghost.holograms.object.CraftHologram;
import com.gmail.filoghost.holograms.object.HologramManager;
import com.gmail.filoghost.holograms.utils.Format;
import com.gmail.filoghost.holograms.utils.StringUtils;
public class SetlineCommand extends HologramSubCommand {
public SetlineCommand() {
super("setline");
setPermission(Messages.BASE_PERM + "setline");
}
@Override
public String getPossibleArguments() {
return "<hologramName> <lineNumber> <newText>";
}
@Override
public int getMinimumArguments() {
return 3;
}
@Override
public void execute(CommandSender sender, String[] args) throws CommandException {
CraftHologram hologram = HologramManager.getHologram(args[0].toLowerCase());
CommandValidator.notNull(hologram, Messages.NO_SUCH_HOLOGRAM);
int lineNumber = CommandValidator.getInteger(args[1]);
CommandValidator.isTrue(lineNumber >= 1 && lineNumber <= hologram.getLinesLength(), "The line number must be between 1 and " + hologram.getLinesLength() + ".");
int index = lineNumber - 1;
if (args[2].equalsIgnoreCase("{empty}")) {
hologram.setLine(index, "");
} else {
hologram.setLine(index, StringUtils.toReadableFormat(org.apache.commons.lang.StringUtils.join(args, " ", 2, args.length)));
}
if (!hologram.update()) {
sender.sendMessage(Messages.FAILED_TO_SPAWN_HERE);
}
HologramDatabase.saveHologram(hologram);
HologramDatabase.trySaveToDisk();
sender.sendMessage(Format.HIGHLIGHT + "Line " + lineNumber + " changed!");
}
@Override
public List<String> getTutorial() {
return Arrays.asList("Changes a line of a hologram.");
}
@Override
public SubCommandType getType() {
return SubCommandType.EDIT_LINES;
}
}

View File

@ -1,59 +0,0 @@
package com.gmail.filoghost.holograms.commands.main.subs;
import java.util.Arrays;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import com.gmail.filoghost.holograms.commands.CommandValidator;
import com.gmail.filoghost.holograms.commands.Messages;
import com.gmail.filoghost.holograms.commands.main.HologramSubCommand;
import com.gmail.filoghost.holograms.exception.CommandException;
import com.gmail.filoghost.holograms.object.CraftHologram;
import com.gmail.filoghost.holograms.object.HologramManager;
import com.gmail.filoghost.holograms.utils.Format;
public class TeleportCommand extends HologramSubCommand {
public TeleportCommand() {
super("teleport", "tp");
setPermission(Messages.BASE_PERM + "teleport");
}
@Override
public String getPossibleArguments() {
return "<hologramName>";
}
@Override
public int getMinimumArguments() {
return 1;
}
@Override
public void execute(CommandSender sender, String[] args) throws CommandException {
Player player = CommandValidator.getPlayerSender(sender);
CraftHologram hologram = HologramManager.getHologram(args[0].toLowerCase());
CommandValidator.notNull(hologram, Messages.NO_SUCH_HOLOGRAM);
Location loc = hologram.getLocation();
loc.setPitch(90);
player.teleport(loc, TeleportCause.PLUGIN);
player.sendMessage(Format.HIGHLIGHT + "You were teleported to the hologram named '" + hologram.getName() + "'.");
}
@Override
public List<String> getTutorial() {
return Arrays.asList("Teleports you to the given hologram.");
}
@Override
public SubCommandType getType() {
return SubCommandType.GENERIC;
}
}

View File

@ -1,95 +0,0 @@
package com.gmail.filoghost.holograms.database;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.bukkit.Location;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import com.gmail.filoghost.holograms.HolographicDisplays;
import com.gmail.filoghost.holograms.exception.HologramNotFoundException;
import com.gmail.filoghost.holograms.exception.InvalidLocationException;
import com.gmail.filoghost.holograms.exception.WorldNotFoundException;
import com.gmail.filoghost.holograms.object.CraftHologram;
import com.gmail.filoghost.holograms.utils.LocationUtils;
import com.gmail.filoghost.holograms.utils.StringUtils;
public class HologramDatabase {
private static File file;
private static FileConfiguration config;
private HologramDatabase() { }
public static void initialize() {
file = new File(HolographicDisplays.getInstance().getDataFolder(), "database.yml");
if (!file.exists()) {
HolographicDisplays.getInstance().saveResource("database.yml", false);
}
config = YamlConfiguration.loadConfiguration(file);
}
public static CraftHologram loadHologram(String name) throws HologramNotFoundException, InvalidLocationException, WorldNotFoundException {
List<String> lines = config.getStringList(name + ".lines");
String locationString = config.getString(name + ".location");
if (lines == null || locationString == null || lines.size() == 0) {
throw new HologramNotFoundException();
}
Location loc;
try {
loc = LocationUtils.locationFromString(locationString);
} catch (WorldNotFoundException ex) {
throw ex;
} catch (Exception ex) {
throw new InvalidLocationException();
}
CraftHologram hologram = new CraftHologram(name, loc);
for (int i = 0; i < lines.size(); i++) {
hologram.addLine(StringUtils.toReadableFormat(lines.get(i)));
}
return hologram;
}
public static void deleteHologram(CraftHologram hologram) {
config.set(hologram.getName(), null);
}
public static void saveHologram(CraftHologram hologram) {
config.set(hologram.getName() + ".location", LocationUtils.locationToString(hologram.getLocation()));
List<String> lines = new ArrayList<String>();
for (String hologramLine : hologram.getLines()) {
lines.add(StringUtils.toSaveableFormat(hologramLine));
}
config.set(hologram.getName() + ".lines", lines);
}
public static Set<String> getHolograms() {
return config.getKeys(false);
}
public static boolean isExistingHologram(String name) {
return config.isConfigurationSection(name);
}
public static void saveToDisk() throws IOException {
if (config != null && file != null) {
config.save(file);
}
}
public static void trySaveToDisk() {
try {
saveToDisk();
} catch (IOException ex) {
ex.printStackTrace();
HolographicDisplays.getInstance().getLogger().severe("Unable to save database.yml to disk!");
}
}
}

View File

@ -1,10 +0,0 @@
package com.gmail.filoghost.holograms.exception;
public class CommandException extends Exception {
private static final long serialVersionUID = 1L;
public CommandException(String message) {
super(message);
}
}

View File

@ -1,7 +0,0 @@
package com.gmail.filoghost.holograms.exception;
public class HologramNotFoundException extends Exception {
private static final long serialVersionUID = 1L;
}

View File

@ -1,10 +0,0 @@
package com.gmail.filoghost.holograms.exception;
public class InvalidCharactersException extends Exception {
private static final long serialVersionUID = 1L;
public InvalidCharactersException(String message) {
super(message);
}
}

View File

@ -1,7 +0,0 @@
package com.gmail.filoghost.holograms.exception;
public class InvalidLocationException extends Exception {
private static final long serialVersionUID = 1L;
}

View File

@ -1,11 +0,0 @@
package com.gmail.filoghost.holograms.exception;
public class InvalidMaterialException extends Exception {
private static final long serialVersionUID = 1L;
public InvalidMaterialException(String message) {
super(message);
}
}

View File

@ -1,7 +0,0 @@
package com.gmail.filoghost.holograms.exception;
public class SpawnFailedException extends Exception {
private static final long serialVersionUID = 1L;
}

View File

@ -1,17 +0,0 @@
package com.gmail.filoghost.holograms.exception;
public class TooWideException extends Exception {
private static final long serialVersionUID = 1L;
private int width;
public TooWideException(int width) {
this.width = width;
}
public int getWidth() {
return width;
}
}

View File

@ -1,7 +0,0 @@
package com.gmail.filoghost.holograms.exception;
public class UnreadableImageException extends Exception {
private static final long serialVersionUID = 1L;
}

View File

@ -1,11 +0,0 @@
package com.gmail.filoghost.holograms.exception;
public class WorldNotFoundException extends Exception {
private static final long serialVersionUID = 1L;
public WorldNotFoundException(String message) {
super(message);
}
}

View File

@ -1,180 +0,0 @@
package com.gmail.filoghost.holograms.image;
import org.bukkit.ChatColor;
import com.gmail.filoghost.holograms.Configuration;
import com.gmail.filoghost.holograms.exception.TooWideException;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
/**
* Huge thanks to bobacadodl for this awesome library!
* Bukkit thread: https://forums.bukkit.org/threads/lib-imagemessage-v2-1-send-images-to-players-via-the-chat.204902
*/
public class ImageMessage {
private static final int MAX_WIDTH = 100;
private final Color[] colors = {
new Color(0, 0, 0),
new Color(0, 0, 170),
new Color(0, 170, 0),
new Color(0, 170, 170),
new Color(170, 0, 0),
new Color(170, 0, 170),
new Color(255, 170, 0),
new Color(170, 170, 170),
new Color(85, 85, 85),
new Color(85, 85, 255),
new Color(85, 255, 85),
new Color(85, 255, 255),
new Color(255, 85, 85),
new Color(255, 85, 255),
new Color(255, 255, 85),
new Color(255, 255, 255),
};
private String[] lines;
public ImageMessage(BufferedImage image, int width) throws TooWideException {
ChatColor[][] chatColors = toChatColorArray(image, width);
lines = toImgMessage(chatColors);
}
private ChatColor[][] toChatColorArray(BufferedImage image, int width) throws TooWideException {
double ratio = (double) image.getHeight() / image.getWidth();
int height = (int) (((double)width) * ratio);
if (height == 0) {
height = 1;
}
if (width > MAX_WIDTH) {
throw new TooWideException(width);
}
BufferedImage resized = resizeImage(image, width, height);
ChatColor[][] chatImg = new ChatColor[resized.getWidth()][resized.getHeight()];
for (int x = 0; x < resized.getWidth(); x++) {
for (int y = 0; y < resized.getHeight(); y++) {
int rgb = resized.getRGB(x, y);
chatImg[x][y] = getClosestChatColor(new Color(rgb, true));
}
}
return chatImg;
}
private String[] toImgMessage(ChatColor[][] colors) {
String[] lines = new String[colors[0].length];
ChatColor transparencyColor = Configuration.transparencyColor;
String transparencySymbol = Configuration.transparencySymbol;
String imageSymbol = Configuration.imageSymbol;
for (int y = 0; y < colors[0].length; y++) {
StringBuffer line = new StringBuffer();
ChatColor previous = ChatColor.RESET;
for (int x = 0; x < colors.length; x++) {
ChatColor currentColor = colors[x][y];
if (currentColor == null) {
// Use the trasparent char
if (previous != transparencyColor) {
// Change the previous chat color and append the newer
line.append(transparencyColor);
previous = transparencyColor;
}
line.append(transparencySymbol);
} else {
if (previous != currentColor) {
line.append(currentColor.toString());
previous = currentColor;
}
line.append(imageSymbol);
}
}
lines[y] = line.toString();
}
return lines;
}
private BufferedImage resizeImage(BufferedImage originalImage, int width, int height) {
return toBufferedImage(originalImage.getScaledInstance(width, height, Image.SCALE_AREA_AVERAGING));
}
private BufferedImage toBufferedImage(Image img) {
// Creates a buffered image with transparency.
BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
// Draws the image on to the buffered image.
Graphics2D graphics = bimage.createGraphics();
graphics.drawImage(img, 0, 0, null);
graphics.dispose();
// Returns the buffered image.
return bimage;
}
private double getDistance(Color c1, Color c2) {
double rmean = (c1.getRed() + c2.getRed()) / 2.0;
double r = c1.getRed() - c2.getRed();
double g = c1.getGreen() - c2.getGreen();
int b = c1.getBlue() - c2.getBlue();
double weightR = 2 + rmean / 256.0;
double weightG = 4.0;
double weightB = 2 + (255 - rmean) / 256.0;
return weightR * r * r + weightG * g * g + weightB * b * b;
}
private boolean areIdentical(Color c1, Color c2) {
return Math.abs(c1.getRed() - c2.getRed()) <= 5 &&
Math.abs(c1.getGreen() - c2.getGreen()) <= 5 &&
Math.abs(c1.getBlue() - c2.getBlue()) <= 5;
}
private ChatColor getClosestChatColor(Color color) {
if (color.getAlpha() < 80) return null;
int index = 0;
double best = -1;
for (int i = 0; i < colors.length; i++) {
if (areIdentical(colors[i], color)) {
return ChatColor.values()[i];
}
}
for (int i = 0; i < colors.length; i++) {
double distance = getDistance(color, colors[i]);
if (distance < best || best == -1) {
best = distance;
index = i;
}
}
// Minecraft has 15 colors
return ChatColor.values()[index];
}
public String[] getLines() {
return lines;
}
}

View File

@ -1,118 +0,0 @@
package com.gmail.filoghost.holograms.listener;
import org.bukkit.Chunk;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.entity.ProjectileLaunchEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import com.gmail.filoghost.holograms.Configuration;
import com.gmail.filoghost.holograms.HolographicDisplays;
import com.gmail.filoghost.holograms.api.FloatingItem;
import com.gmail.filoghost.holograms.api.Hologram;
import com.gmail.filoghost.holograms.commands.Messages;
import com.gmail.filoghost.holograms.nms.interfaces.NmsManager;
import com.gmail.filoghost.holograms.object.APIFloatingItemManager;
import com.gmail.filoghost.holograms.object.APIHologramManager;
import com.gmail.filoghost.holograms.object.HologramBase;
import com.gmail.filoghost.holograms.object.HologramManager;
public class MainListener implements Listener {
private NmsManager nmsManager;
public MainListener(NmsManager nmsManager) {
this.nmsManager = nmsManager;
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onChunkUnload(ChunkUnloadEvent event) {
for (Entity entity : event.getChunk().getEntities()) {
if (!entity.isDead()) {
HologramBase multiEntity = nmsManager.getParentHologram(entity);
if (multiEntity != null) {
multiEntity.hide();
}
}
}
}
@EventHandler (priority = EventPriority.MONITOR)
public void onChunkLoad(ChunkLoadEvent event) {
Chunk chunk = event.getChunk();
HologramManager.onChunkLoad(chunk);
APIHologramManager.onChunkLoad(chunk);
APIFloatingItemManager.onChunkLoad(chunk);
}
@EventHandler (priority = EventPriority.MONITOR, ignoreCancelled = false)
public void onCreatureSpawn(CreatureSpawnEvent event) {
if (nmsManager.isBasicEntityNMS(event.getEntity())) {
if (event.isCancelled()) {
event.setCancelled(false);
}
}
}
@EventHandler (priority = EventPriority.MONITOR, ignoreCancelled = false)
public void onProjectileLaunch(ProjectileLaunchEvent event) {
if (nmsManager.isBasicEntityNMS(event.getEntity())) {
if (event.isCancelled()) {
event.setCancelled(false);
}
}
}
@EventHandler (priority = EventPriority.MONITOR, ignoreCancelled = false)
public void onItemSpawn(ItemSpawnEvent event) {
if (nmsManager.isBasicEntityNMS(event.getEntity())) {
if (event.isCancelled()) {
event.setCancelled(false);
}
}
}
@EventHandler (priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onSlimeInteract(PlayerInteractEntityEvent event) {
if (event.getRightClicked().getType() == EntityType.SLIME) {
HologramBase base = nmsManager.getParentHologram(event.getRightClicked());
if (base == null) return;
if (base instanceof Hologram) {
Hologram textHologram = (Hologram) base;
if (textHologram.hasTouchHandler()) {
try {
textHologram.getTouchHandler().onTouch(textHologram, event.getPlayer());
} catch (Exception ex) {
ex.printStackTrace();
HolographicDisplays.getInstance().getLogger().warning("An exception occured while a player was touching a hologram. It's probably caused by another plugin using Holographic Displays as library.");
}
}
} else if (base instanceof FloatingItem) {
FloatingItem floatingItem = (FloatingItem) base;
if (floatingItem.hasTouchHandler()) {
floatingItem.getTouchHandler().onTouch(floatingItem, event.getPlayer());
}
}
}
}
@EventHandler
public void onJoin(PlayerJoinEvent event) {
if (Configuration.updateNotification && Configuration.newVersion != null) {
if (event.getPlayer().hasPermission(Messages.BASE_PERM + "update")) {
event.getPlayer().sendMessage("§3[HolographicDisplays] §bFound an update: " + Configuration.newVersion + ". Download:");
event.getPlayer().sendMessage("§3>> §bhttp://dev.bukkit.org/bukkit-plugins/holographic-displays");
}
}
}
}

View File

@ -1,514 +0,0 @@
/*
* Copyright 2011-2013 Tyler Blair. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and contributors and should not be interpreted as representing official policies,
* either expressed or implied, of anybody else.
*/
package com.gmail.filoghost.holograms.metrics;
import org.bukkit.Bukkit;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.scheduler.BukkitTask;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.UUID;
import java.util.logging.Level;
import java.util.zip.GZIPOutputStream;
public class MetricsLite {
/**
* The current revision number
*/
private final static int REVISION = 7;
/**
* The base url of the metrics domain
*/
private static final String BASE_URL = "http://report.mcstats.org";
/**
* The url used to report a server's status
*/
private static final String REPORT_URL = "/plugin/%s";
/**
* Interval of time to ping (in minutes)
*/
private final static int PING_INTERVAL = 15;
/**
* The plugin this metrics submits for
*/
private final Plugin plugin;
/**
* The plugin configuration file
*/
private final YamlConfiguration configuration;
/**
* The plugin configuration file
*/
private final File configurationFile;
/**
* Unique server id
*/
private final String guid;
/**
* Debug mode
*/
private final boolean debug;
/**
* Lock for synchronization
*/
private final Object optOutLock = new Object();
/**
* Id of the scheduled task
*/
private volatile BukkitTask task = null;
public MetricsLite(Plugin plugin) throws IOException {
if (plugin == null) {
throw new IllegalArgumentException("Plugin cannot be null");
}
this.plugin = plugin;
// load the config
configurationFile = getConfigFile();
configuration = YamlConfiguration.loadConfiguration(configurationFile);
// add some defaults
configuration.addDefault("opt-out", false);
configuration.addDefault("guid", UUID.randomUUID().toString());
configuration.addDefault("debug", false);
// Do we need to create the file?
if (configuration.get("guid", null) == null) {
configuration.options().header("http://mcstats.org").copyDefaults(true);
configuration.save(configurationFile);
}
// Load the guid then
guid = configuration.getString("guid");
debug = configuration.getBoolean("debug", false);
}
/**
* Start measuring statistics. This will immediately create an async repeating task as the plugin and send
* the initial data to the metrics backend, and then after that it will post in increments of
* PING_INTERVAL * 1200 ticks.
*
* @return True if statistics measuring is running, otherwise false.
*/
public boolean start() {
synchronized (optOutLock) {
// Did we opt out?
if (isOptOut()) {
return false;
}
// Is metrics already running?
if (task != null) {
return true;
}
// Begin hitting the server with glorious data
task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, new Runnable() {
private boolean firstPost = true;
public void run() {
try {
// This has to be synchronized or it can collide with the disable method.
synchronized (optOutLock) {
// Disable Task, if it is running and the server owner decided to opt-out
if (isOptOut() && task != null) {
task.cancel();
task = null;
}
}
// We use the inverse of firstPost because if it is the first time we are posting,
// it is not a interval ping, so it evaluates to FALSE
// Each time thereafter it will evaluate to TRUE, i.e PING!
postPlugin(!firstPost);
// After the first post we set firstPost to false
// Each post thereafter will be a ping
firstPost = false;
} catch (IOException e) {
if (debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage());
}
}
}
}, 0, PING_INTERVAL * 1200);
return true;
}
}
/**
* Has the server owner denied plugin metrics?
*
* @return true if metrics should be opted out of it
*/
public boolean isOptOut() {
synchronized (optOutLock) {
try {
// Reload the metrics file
configuration.load(getConfigFile());
} catch (IOException ex) {
if (debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
}
return true;
} catch (InvalidConfigurationException ex) {
if (debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
}
return true;
}
return configuration.getBoolean("opt-out", false);
}
}
/**
* Enables metrics for the server by setting "opt-out" to false in the config file and starting the metrics task.
*
* @throws java.io.IOException
*/
public void enable() throws IOException {
// This has to be synchronized or it can collide with the check in the task.
synchronized (optOutLock) {
// Check if the server owner has already set opt-out, if not, set it.
if (isOptOut()) {
configuration.set("opt-out", false);
configuration.save(configurationFile);
}
// Enable Task, if it is not running
if (task == null) {
start();
}
}
}
/**
* Disables metrics for the server by setting "opt-out" to true in the config file and canceling the metrics task.
*
* @throws java.io.IOException
*/
public void disable() throws IOException {
// This has to be synchronized or it can collide with the check in the task.
synchronized (optOutLock) {
// Check if the server owner has already set opt-out, if not, set it.
if (!isOptOut()) {
configuration.set("opt-out", true);
configuration.save(configurationFile);
}
// Disable Task, if it is running
if (task != null) {
task.cancel();
task = null;
}
}
}
/**
* Gets the File object of the config file that should be used to store data such as the GUID and opt-out status
*
* @return the File object for the config file
*/
public File getConfigFile() {
// I believe the easiest way to get the base folder (e.g craftbukkit set via -P) for plugins to use
// is to abuse the plugin object we already have
// plugin.getDataFolder() => base/plugins/PluginA/
// pluginsFolder => base/plugins/
// The base is not necessarily relative to the startup directory.
File pluginsFolder = plugin.getDataFolder().getParentFile();
// return => base/plugins/PluginMetrics/config.yml
return new File(new File(pluginsFolder, "PluginMetrics"), "config.yml");
}
/**
* Generic method that posts a plugin to the metrics website
*/
@SuppressWarnings("deprecation")
private void postPlugin(boolean isPing) throws IOException {
// Server software specific section
PluginDescriptionFile description = plugin.getDescription();
String pluginName = description.getName();
boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE if online mode is enabled
String pluginVersion = description.getVersion();
String serverVersion = Bukkit.getVersion();
int playersOnline = Bukkit.getServer().getOnlinePlayers().length;
// END server software specific section -- all code below does not use any code outside of this class / Java
// Construct the post data
StringBuilder json = new StringBuilder(1024);
json.append('{');
// The plugin's description file containg all of the plugin data such as name, version, author, etc
appendJSONPair(json, "guid", guid);
appendJSONPair(json, "plugin_version", pluginVersion);
appendJSONPair(json, "server_version", serverVersion);
appendJSONPair(json, "players_online", Integer.toString(playersOnline));
// New data as of R6
String osname = System.getProperty("os.name");
String osarch = System.getProperty("os.arch");
String osversion = System.getProperty("os.version");
String java_version = System.getProperty("java.version");
int coreCount = Runtime.getRuntime().availableProcessors();
// normalize os arch .. amd64 -> x86_64
if (osarch.equals("amd64")) {
osarch = "x86_64";
}
appendJSONPair(json, "osname", osname);
appendJSONPair(json, "osarch", osarch);
appendJSONPair(json, "osversion", osversion);
appendJSONPair(json, "cores", Integer.toString(coreCount));
appendJSONPair(json, "auth_mode", onlineMode ? "1" : "0");
appendJSONPair(json, "java_version", java_version);
// If we're pinging, append it
if (isPing) {
appendJSONPair(json, "ping", "1");
}
// close json
json.append('}');
// Create the url
URL url = new URL(BASE_URL + String.format(REPORT_URL, urlEncode(pluginName)));
// Connect to the website
URLConnection connection;
// Mineshafter creates a socks proxy, so we can safely bypass it
// It does not reroute POST requests so we need to go around it
if (isMineshafterPresent()) {
connection = url.openConnection(Proxy.NO_PROXY);
} else {
connection = url.openConnection();
}
byte[] uncompressed = json.toString().getBytes();
byte[] compressed = gzip(json.toString());
// Headers
connection.addRequestProperty("User-Agent", "MCStats/" + REVISION);
connection.addRequestProperty("Content-Type", "application/json");
connection.addRequestProperty("Content-Encoding", "gzip");
connection.addRequestProperty("Content-Length", Integer.toString(compressed.length));
connection.addRequestProperty("Accept", "application/json");
connection.addRequestProperty("Connection", "close");
connection.setDoOutput(true);
if (debug) {
System.out.println("[Metrics] Prepared request for " + pluginName + " uncompressed=" + uncompressed.length + " compressed=" + compressed.length);
}
// Write the data
OutputStream os = connection.getOutputStream();
os.write(compressed);
os.flush();
// Now read the response
final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String response = reader.readLine();
// close resources
os.close();
reader.close();
if (response == null || response.startsWith("ERR") || response.startsWith("7")) {
if (response == null) {
response = "null";
} else if (response.startsWith("7")) {
response = response.substring(response.startsWith("7,") ? 2 : 1);
}
throw new IOException(response);
}
}
/**
* GZip compress a string of bytes
*
* @param input
* @return
*/
public static byte[] gzip(String input) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzos = null;
try {
gzos = new GZIPOutputStream(baos);
gzos.write(input.getBytes("UTF-8"));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (gzos != null) try {
gzos.close();
} catch (IOException ignore) {
}
}
return baos.toByteArray();
}
/**
* Check if mineshafter is present. If it is, we need to bypass it to send POST requests
*
* @return true if mineshafter is installed on the server
*/
private boolean isMineshafterPresent() {
try {
Class.forName("mineshafter.MineServer");
return true;
} catch (Exception e) {
return false;
}
}
/**
* Appends a json encoded key/value pair to the given string builder.
*
* @param json
* @param key
* @param value
* @throws UnsupportedEncodingException
*/
private static void appendJSONPair(StringBuilder json, String key, String value) throws UnsupportedEncodingException {
boolean isValueNumeric = false;
try {
if (value.equals("0") || !value.endsWith("0")) {
Double.parseDouble(value);
isValueNumeric = true;
}
} catch (NumberFormatException e) {
isValueNumeric = false;
}
if (json.charAt(json.length() - 1) != '{') {
json.append(',');
}
json.append(escapeJSON(key));
json.append(':');
if (isValueNumeric) {
json.append(value);
} else {
json.append(escapeJSON(value));
}
}
/**
* Escape a string to create a valid JSON string
*
* @param text
* @return
*/
private static String escapeJSON(String text) {
StringBuilder builder = new StringBuilder();
builder.append('"');
for (int index = 0; index < text.length(); index++) {
char chr = text.charAt(index);
switch (chr) {
case '"':
case '\\':
builder.append('\\');
builder.append(chr);
break;
case '\b':
builder.append("\\b");
break;
case '\t':
builder.append("\\t");
break;
case '\n':
builder.append("\\n");
break;
case '\r':
builder.append("\\r");
break;
default:
if (chr < ' ') {
String t = "000" + Integer.toHexString(chr);
builder.append("\\u" + t.substring(t.length() - 4));
} else {
builder.append(chr);
}
break;
}
}
builder.append('"');
return builder.toString();
}
/**
* Encode text as UTF-8
*
* @param text the text to encode
* @return the encoded text, as UTF-8
*/
private static String urlEncode(final String text) throws UnsupportedEncodingException {
return URLEncoder.encode(text, "UTF-8");
}
}

View File

@ -1,17 +0,0 @@
package com.gmail.filoghost.holograms.nms.interfaces;
public interface BasicEntityNMS {
// Locks the tick of the entities.
public void setLockTick(boolean lock);
// Kills the entity through NMS.
public void killEntityNMS();
// Sets the location through NMS.
public void setLocationNMS(double x, double y, double z);
// Returns if the entity is dead through NMS.
public boolean isDeadNMS();
}

View File

@ -1,11 +0,0 @@
package com.gmail.filoghost.holograms.nms.interfaces;
import org.bukkit.inventory.ItemStack;
public interface CustomItem extends HologramComponent {
public void setItemStackNMS(ItemStack stack);
public void allowPickup(boolean pickup);
}

View File

@ -1,81 +0,0 @@
package com.gmail.filoghost.holograms.nms.interfaces;
import java.io.IOException;
import org.bukkit.ChatColor;
import org.bukkit.craftbukkit.libs.com.google.gson.stream.JsonWriter;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public interface FancyMessage {
public FancyMessage color(final ChatColor color);
public FancyMessage style(final ChatColor... styles);
public FancyMessage file(final String path);
public FancyMessage link(final String url);
public FancyMessage suggest(final String command);
public FancyMessage command(final String command);
public FancyMessage achievementTooltip(final String name);
public FancyMessage itemTooltip(final String itemJSON);
public FancyMessage itemTooltip(final ItemStack itemStack);
public FancyMessage tooltip(final String text);
public FancyMessage then(final Object obj);
public String toJSONString();
public void send(Player player);
public static class MessagePart {
public ChatColor color = null;
public ChatColor[] styles = null;
public String clickActionName = null;
public String clickActionData = null;
public String hoverActionName = null;
public String hoverActionData = null;
public final String text;
public MessagePart(final String text) {
this.text = text;
}
public JsonWriter writeJson(final JsonWriter json) throws IOException {
json.beginObject().name("text").value(text);
if (color != null) {
json.name("color").value(color.name().toLowerCase());
}
if (styles != null) {
for (final ChatColor style : styles) {
json.name(style == ChatColor.UNDERLINE ? "underlined" : style.name().toLowerCase()).value(true);
}
}
if (clickActionName != null && clickActionData != null) {
json.name("clickEvent")
.beginObject()
.name("action").value(clickActionName)
.name("value").value(clickActionData)
.endObject();
}
if (hoverActionName != null && hoverActionData != null) {
json.name("hoverEvent")
.beginObject()
.name("action").value(hoverActionName)
.name("value").value(hoverActionData)
.endObject();
}
return json.endObject();
}
}
}

View File

@ -1,13 +0,0 @@
package com.gmail.filoghost.holograms.nms.interfaces;
import org.bukkit.entity.Entity;
public interface HologramArmorStand extends NameableEntityNMS {
// Sets the passenger of this entity through NMS.
public void setPassengerNMS(BasicEntityNMS passenger);
// Sets the passenger of this entity through NMS.
public void setPassengerNMS(Entity bukkitEntity);
}

View File

@ -1,14 +0,0 @@
package com.gmail.filoghost.holograms.nms.interfaces;
import com.gmail.filoghost.holograms.object.HologramBase;
// Represents an entity that is part of a hologram.
public interface HologramComponent extends BasicEntityNMS {
// Returns the linked HologramBase. Can be null.
public HologramBase getParentHologram();
// Sets the linked HologramBase.
public void setParentHologram(HologramBase base);
}

View File

@ -1,5 +0,0 @@
package com.gmail.filoghost.holograms.nms.interfaces;
public interface HologramHorse extends NameableEntityNMS {
}

View File

@ -1,15 +0,0 @@
package com.gmail.filoghost.holograms.nms.interfaces;
import org.bukkit.entity.Entity;
public interface HologramWitherSkull extends HologramComponent {
// Sets the passenger of this entity through NMS.
public void setPassengerNMS(BasicEntityNMS passenger);
// Sets the passenger of this entity through NMS.
public void setPassengerNMS(Entity bukkitEntity);
public void sendUpdatePacketNear();
}

View File

@ -1,9 +0,0 @@
package com.gmail.filoghost.holograms.nms.interfaces;
public interface NameableEntityNMS extends HologramComponent {
public void forceSetCustomName(String name);
public String getCustomNameNMS();
}

View File

@ -1,33 +0,0 @@
package com.gmail.filoghost.holograms.nms.interfaces;
import org.bukkit.inventory.ItemStack;
import com.gmail.filoghost.holograms.exception.SpawnFailedException;
import com.gmail.filoghost.holograms.object.HologramBase;
public interface NmsManager {
public void registerCustomEntities() throws Exception;
public HologramArmorStand spawnHologramArmorStand(org.bukkit.World world, double x, double y, double z, HologramBase parent) throws SpawnFailedException;
public HologramHorse spawnHologramHorse(org.bukkit.World world, double x, double y, double z, HologramBase parent) throws SpawnFailedException;
public HologramWitherSkull spawnHologramWitherSkull(org.bukkit.World bukkitWorld, double x, double y, double z, HologramBase parent) throws SpawnFailedException;
public CustomItem spawnCustomItem(org.bukkit.World bukkitWorld, double x, double y, double z, HologramBase parent, ItemStack stack) throws SpawnFailedException;
public TouchSlime spawnTouchSlime(org.bukkit.World bukkitWorld, double x, double y, double z, HologramBase parent) throws SpawnFailedException;
public boolean isHologramComponent(org.bukkit.entity.Entity bukkitEntity);
public boolean isBasicEntityNMS(org.bukkit.entity.Entity bukkitEntity);
// Return null if not a hologram's (or floating item's) part.
public HologramBase getParentHologram(org.bukkit.entity.Entity bukkitEntity);
public FancyMessage newFancyMessage(String text);
public boolean hasChatHoverFeature();
}

View File

@ -1,5 +0,0 @@
package com.gmail.filoghost.holograms.nms.interfaces;
public interface TouchSlime extends HologramComponent {
}

View File

@ -1,40 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_6_R3;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_6_R3.CraftServer;
import org.bukkit.craftbukkit.v1_6_R3.entity.CraftItem;
import org.bukkit.entity.Entity;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
public class CraftCustomItem extends CraftItem {
public CraftCustomItem(CraftServer server, EntityCustomItem entity) {
super(server, entity);
}
// Disallow all the bukkit methods.
@Override
public void remove() {
// Cannot be removed, this is the most important to override.
}
// Methods from Entity
@Override public void setVelocity(Vector vel) { }
@Override public boolean teleport(Location loc) { return false; }
@Override public boolean teleport(Entity entity) { return false; }
@Override public boolean teleport(Location loc, TeleportCause cause) { return false; }
@Override public boolean teleport(Entity entity, TeleportCause cause) { return false; }
@Override public void setFireTicks(int ticks) { }
@Override public boolean setPassenger(Entity entity) { return false; }
@Override public boolean eject() { return false; }
@Override public boolean leaveVehicle() { return false; }
@Override public void playEffect(EntityEffect effect) { }
// Methods from Item
@Override public void setItemStack(ItemStack stack) { }
@Override public void setPickupDelay(int delay) { }
}

View File

@ -1,64 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_6_R3;
import java.util.Collection;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_6_R3.CraftServer;
import org.bukkit.craftbukkit.v1_6_R3.entity.CraftHorse;
import org.bukkit.entity.AnimalTamer;
import org.bukkit.entity.Entity;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.potion.PotionEffect;
import org.bukkit.util.Vector;
public class CraftHologramHorse extends CraftHorse {
public CraftHologramHorse(CraftServer server, EntityHologramHorse entity) {
super(server, entity);
}
// Disallow all the bukkit methods.
@Override
public void remove() {
// Cannot be removed, this is the most important to override.
}
// Methods from Horse class
@Override public void setVariant(Variant variant) { }
@Override public void setColor(Color color) { }
@Override public void setStyle(Style style) { }
@Override public void setCarryingChest(boolean chest) { }
@Override public void setDomestication(int domestication) { }
@Override public void setJumpStrength(double jump) { }
// Methods form Ageable class
@Override public void setAge(int age) { }
@Override public void setAgeLock(boolean lock) { }
@Override public void setBreed(boolean breed) { }
@Override public void setAdult() { }
@Override public void setBaby() { }
// Methods from LivingEntity class
@Override public boolean addPotionEffect(PotionEffect effect) { return false; }
@Override public boolean addPotionEffect(PotionEffect effect, boolean param) { return false; }
@Override public boolean addPotionEffects(Collection<PotionEffect> effects) { return false; }
@Override public void setRemoveWhenFarAway(boolean remove) { }
// Methods from Entity
@Override public void setVelocity(Vector vel) { }
@Override public boolean teleport(Location loc) { return false; }
@Override public boolean teleport(Entity entity) { return false; }
@Override public boolean teleport(Location loc, TeleportCause cause) { return false; }
@Override public boolean teleport(Entity entity, TeleportCause cause) { return false; }
@Override public void setFireTicks(int ticks) { }
@Override public boolean setPassenger(Entity entity) { return false; }
@Override public boolean eject() { return false; }
@Override public boolean leaveVehicle() { return false; }
@Override public void playEffect(EntityEffect effect) { }
// Methods from Tameable
@Override public void setTamed(boolean tame) { }
@Override public void setOwner(AnimalTamer owner) { }
}

View File

@ -1,46 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_6_R3;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_6_R3.CraftServer;
import org.bukkit.craftbukkit.v1_6_R3.entity.CraftWitherSkull;
import org.bukkit.entity.Entity;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.util.Vector;
public class CraftHologramWitherSkull extends CraftWitherSkull {
public CraftHologramWitherSkull(CraftServer server, EntityHologramWitherSkull entity) {
super(server, entity);
}
// Disallow all the bukkit methods.
@Override
public void remove() {
// Cannot be removed, this is the most important to override.
}
// Method from Fireball
@Override public void setDirection(Vector dir) { }
// Method from Projectile
@Override public void setBounce(boolean bounce) { }
// Methods from Explosive
@Override public void setYield(float yield) { }
@Override public void setIsIncendiary(boolean fire) { }
// Methods from Entity
@Override public void setVelocity(Vector vel) { }
@Override public boolean teleport(Location loc) { return false; }
@Override public boolean teleport(Entity entity) { return false; }
@Override public boolean teleport(Location loc, TeleportCause cause) { return false; }
@Override public boolean teleport(Entity entity, TeleportCause cause) { return false; }
@Override public void setFireTicks(int ticks) { }
@Override public boolean setPassenger(Entity entity) { return false; }
@Override public boolean eject() { return false; }
@Override public boolean leaveVehicle() { return false; }
@Override public void playEffect(EntityEffect effect) { }
}

View File

@ -1,47 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_6_R3;
import java.util.Collection;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_6_R3.CraftServer;
import org.bukkit.craftbukkit.v1_6_R3.entity.CraftSlime;
import org.bukkit.entity.Entity;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.potion.PotionEffect;
import org.bukkit.util.Vector;
public class CraftTouchSlime extends CraftSlime {
public CraftTouchSlime(CraftServer server, EntityTouchSlime entity) {
super(server, entity);
}
// Disallow all the bukkit methods.
@Override
public void remove() {
// Cannot be removed, this is the most important to override.
}
// Methods from LivingEntity class
@Override public boolean addPotionEffect(PotionEffect effect) { return false; }
@Override public boolean addPotionEffect(PotionEffect effect, boolean param) { return false; }
@Override public boolean addPotionEffects(Collection<PotionEffect> effects) { return false; }
@Override public void setRemoveWhenFarAway(boolean remove) { }
// Methods from Entity
@Override public void setVelocity(Vector vel) { }
@Override public boolean teleport(Location loc) { return false; }
@Override public boolean teleport(Entity entity) { return false; }
@Override public boolean teleport(Location loc, TeleportCause cause) { return false; }
@Override public boolean teleport(Entity entity, TeleportCause cause) { return false; }
@Override public void setFireTicks(int ticks) { }
@Override public boolean setPassenger(Entity entity) { return false; }
@Override public boolean eject() { return false; }
@Override public boolean leaveVehicle() { return false; }
@Override public void playEffect(EntityEffect effect) { }
// Methods from Slime
@Override public void setSize(int size) { }
}

View File

@ -1,189 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_6_R3;
import net.minecraft.server.v1_6_R3.Block;
import net.minecraft.server.v1_6_R3.EntityItem;
import net.minecraft.server.v1_6_R3.ItemStack;
import net.minecraft.server.v1_6_R3.NBTTagCompound;
import net.minecraft.server.v1_6_R3.World;
import net.minecraft.server.v1_6_R3.EntityHuman;
import net.minecraft.server.v1_6_R3.EntityPlayer;
import net.minecraft.server.v1_6_R3.NBTTagList;
import net.minecraft.server.v1_6_R3.NBTTagString;
import org.bukkit.craftbukkit.v1_6_R3.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_6_R3.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import com.gmail.filoghost.holograms.HolographicDisplays;
import com.gmail.filoghost.holograms.api.FloatingItem;
import com.gmail.filoghost.holograms.nms.interfaces.BasicEntityNMS;
import com.gmail.filoghost.holograms.nms.interfaces.CustomItem;
import com.gmail.filoghost.holograms.object.HologramBase;
import com.gmail.filoghost.holograms.utils.ItemUtils;
public class EntityCustomItem extends EntityItem implements CustomItem, BasicEntityNMS {
private boolean lockTick;
private HologramBase parent;
public EntityCustomItem(World world) {
super(world);
super.pickupDelay = Integer.MAX_VALUE;
}
@Override
public void l_() {
// Checks every 20 ticks.
if (ticksLived % 20 == 0) {
// The item dies without a vehicle.
if (this.vehicle == null) {
die();
}
}
if (!lockTick) {
super.l_();
}
}
@Override
public ItemStack getItemStack() {
// Dirty method to check if the icon is being picked up
StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace();
if (stacktrace.length > 2 && stacktrace[2].getClassName().contains("EntityInsentient")) {
return null; // Try to pickup this, dear entity ignoring the pickupDelay!
}
return super.getItemStack();
}
// Method called when a player is near.
@Override
public void b_(EntityHuman human) {
if (parent instanceof FloatingItem && human instanceof EntityPlayer) {
FloatingItem floatingItemParent = (FloatingItem) parent;
if (floatingItemParent.hasPickupHandler()) {
try {
floatingItemParent.getPickupHandler().onPickup(floatingItemParent, (Player) human.getBukkitEntity());
} catch (Exception ex) {
ex.printStackTrace();
HolographicDisplays.getInstance().getLogger().warning("An exception occurred while a player was picking up a floating item. It's probably caused by another plugin using Holographic Displays as library.");
}
}
// It is never added to the inventory.
}
}
@Override
public void b(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean c(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public boolean d(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public void e(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean isInvulnerable() {
/*
* The field Entity.invulnerable is private.
* It's only used while saving NBTTags, but since the entity would be killed
* on chunk unload, we prefer to override isInvulnerable().
*/
return true;
}
@Override
public void setLockTick(boolean lock) {
lockTick = lock;
}
@Override
public void die() {
setLockTick(false);
super.die();
}
@Override
public CraftEntity getBukkitEntity() {
if (super.bukkitEntity == null) {
this.bukkitEntity = new CraftCustomItem(this.world.getServer(), this);
}
return this.bukkitEntity;
}
@Override
public boolean isDeadNMS() {
return this.dead;
}
@Override
public void killEntityNMS() {
die();
}
@Override
public void setLocationNMS(double x, double y, double z) {
super.setPosition(x, y, z);
}
@Override
public void setItemStackNMS(org.bukkit.inventory.ItemStack stack) {
ItemStack newItem = CraftItemStack.asNMSCopy(stack);
if (newItem == null) {
newItem = new ItemStack(Block.BEDROCK);
}
if (newItem.tag == null) {
newItem.tag = new NBTTagCompound();
}
NBTTagCompound display = newItem.tag.getCompound("display");
if (!newItem.tag.hasKey("display")) {
newItem.tag.set("display", display);
}
NBTTagList tagList = new NBTTagList();
tagList.add(new NBTTagString(ItemUtils.ANTISTACK_LORE)); // Antistack lore
display.set("Lore", tagList);
newItem.count = 0;
setItemStack(newItem);
}
@Override
public HologramBase getParentHologram() {
return parent;
}
@Override
public void setParentHologram(HologramBase base) {
this.parent = base;
}
@Override
public void allowPickup(boolean pickup) {
if (pickup) {
super.pickupDelay = 0;
} else {
super.pickupDelay = Integer.MAX_VALUE;
}
}
}

View File

@ -1,151 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_6_R3;
import org.bukkit.craftbukkit.v1_6_R3.entity.CraftEntity;
import com.gmail.filoghost.holograms.nms.interfaces.HologramHorse;
import com.gmail.filoghost.holograms.object.HologramBase;
import net.minecraft.server.v1_6_R3.EntityHorse;
import net.minecraft.server.v1_6_R3.NBTTagCompound;
import net.minecraft.server.v1_6_R3.World;
public class EntityHologramHorse extends EntityHorse implements HologramHorse {
private boolean lockTick;
private HologramBase parent;
public EntityHologramHorse(World world) {
super(world);
super.ageLocked = true;
super.persistent = true;
super.boundingBox.a = 0.0;
super.boundingBox.b = 0.0;
super.boundingBox.c = 0.0;
super.boundingBox.d = 0.0;
super.boundingBox.e = 0.0;
super.boundingBox.f = 0.0;
a(0.0F, 0.0F);
setAge(-1700000); // This is a magic value. No one will see the real horse.
}
@Override
public void l_() {
// Checks every 20 ticks.
if (ticksLived % 20 == 0) {
// The horse dies without a vehicle.
if (this.vehicle == null) {
die();
}
}
if (!lockTick) {
super.l_();
}
}
@Override
public void b(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean c(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public boolean d(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public void e(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean isInvulnerable() {
/*
* The field Entity.invulnerable is private.
* It's only used while saving NBTTags, but since the entity would be killed
* on chunk unload, we prefer to override isInvulnerable().
*/
return true;
}
@Override
public void setCustomName(String customName) {
// Locks the custom name.
}
@Override
public void setCustomNameVisible(boolean visible) {
// Locks the custom name.
}
@Override
public void makeSound(String sound, float volume, float pitch) {
// Remove sounds.
}
@Override
public void setLockTick(boolean lock) {
lockTick = lock;
}
@Override
public void die() {
setLockTick(false);
super.die();
}
@Override
public void forceSetCustomName(String name) {
if (name != null && name.length() > 64) {
name = name.substring(0, 64);
}
super.setCustomName(name);
super.setCustomNameVisible(name != null);
}
@Override
public CraftEntity getBukkitEntity() {
if (super.bukkitEntity == null) {
this.bukkitEntity = new CraftHologramHorse(this.world.getServer(), this);
}
return this.bukkitEntity;
}
@Override
public boolean isDeadNMS() {
return super.dead;
}
@Override
public String getCustomNameNMS() {
return super.getCustomName();
}
@Override
public void killEntityNMS() {
die();
}
@Override
public void setLocationNMS(double x, double y, double z) {
super.setPosition(x, y, z);
}
@Override
public HologramBase getParentHologram() {
return parent;
}
@Override
public void setParentHologram(HologramBase base) {
this.parent = base;
}
}

View File

@ -1,160 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_6_R3;
import org.bukkit.craftbukkit.v1_6_R3.entity.CraftEntity;
import com.gmail.filoghost.holograms.nms.interfaces.BasicEntityNMS;
import com.gmail.filoghost.holograms.nms.interfaces.HologramWitherSkull;
import com.gmail.filoghost.holograms.object.HologramBase;
import com.gmail.filoghost.holograms.utils.GenericUtils;
import net.minecraft.server.v1_6_R3.Entity;
import net.minecraft.server.v1_6_R3.EntityWitherSkull;
import net.minecraft.server.v1_6_R3.NBTTagCompound;
import net.minecraft.server.v1_6_R3.Packet34EntityTeleport;
import net.minecraft.server.v1_6_R3.World;
import net.minecraft.server.v1_6_R3.EntityPlayer;
public class EntityHologramWitherSkull extends EntityWitherSkull implements HologramWitherSkull {
private boolean lockTick;
private HologramBase parent;
public EntityHologramWitherSkull(World world) {
super(world);
super.motX = 0.0;
super.motY = 0.0;
super.motZ = 0.0;
super.dirX = 0.0;
super.dirY = 0.0;
super.dirZ = 0.0;
super.boundingBox.a = 0.0;
super.boundingBox.b = 0.0;
super.boundingBox.c = 0.0;
super.boundingBox.d = 0.0;
super.boundingBox.e = 0.0;
super.boundingBox.f = 0.0;
a(0.0F, 0.0F);
}
@Override
public void b(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean c(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public boolean d(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public void e(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean isInvulnerable() {
/*
* The field Entity.invulnerable is private.
* It's only used while saving NBTTags, but since the entity would be killed
* on chunk unload, we prefer to override isInvulnerable().
*/
return true;
}
@Override
public void l_() {
if (!lockTick) {
super.l_();
}
}
@Override
public void makeSound(String sound, float f1, float f2) {
// Remove sounds.
}
@Override
public void setLockTick(boolean lock) {
lockTick = lock;
}
@Override
public void die() {
setLockTick(false);
super.die();
}
@Override
public CraftEntity getBukkitEntity() {
if (super.bukkitEntity == null) {
this.bukkitEntity = new CraftHologramWitherSkull(this.world.getServer(), this);
}
return this.bukkitEntity;
}
@Override
public void killEntityNMS() {
die();
}
@Override
public void setLocationNMS(double x, double y, double z) {
super.setPosition(x, y, z);
}
@Override
public void sendUpdatePacketNear() {
// Send a packet to update the position.
Packet34EntityTeleport teleportPacket = new Packet34EntityTeleport(this);
for (Object obj : this.world.players) {
if (obj instanceof EntityPlayer) {
EntityPlayer nmsPlayer = (EntityPlayer) obj;
double distanceSquared = GenericUtils.square(nmsPlayer.locX - this.locX) + GenericUtils.square(nmsPlayer.locZ - this.locZ);
if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
nmsPlayer.playerConnection.sendPacket(teleportPacket);
}
}
}
}
@Override
public boolean isDeadNMS() {
return this.dead;
}
@Override
public void setPassengerNMS(BasicEntityNMS passenger) {
if (passenger instanceof Entity) {
((Entity) passenger).setPassengerOf(this);
}
}
@Override
public void setPassengerNMS(org.bukkit.entity.Entity bukkitEntity) {
((CraftEntity) bukkitEntity).getHandle().setPassengerOf(this);
}
@Override
public HologramBase getParentHologram() {
return parent;
}
@Override
public void setParentHologram(HologramBase base) {
this.parent = base;
}
}

View File

@ -1,138 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_6_R3;
import org.bukkit.craftbukkit.v1_6_R3.entity.CraftEntity;
import com.gmail.filoghost.holograms.nms.interfaces.TouchSlime;
import com.gmail.filoghost.holograms.object.HologramBase;
import net.minecraft.server.v1_6_R3.EntitySlime;
import net.minecraft.server.v1_6_R3.NBTTagCompound;
import net.minecraft.server.v1_6_R3.World;
public class EntityTouchSlime extends EntitySlime implements TouchSlime {
private boolean lockTick;
private HologramBase parent;
public EntityTouchSlime(World world) {
super(world);
super.persistent = true;
super.boundingBox.a = 0.0;
super.boundingBox.b = 0.0;
super.boundingBox.c = 0.0;
super.boundingBox.d = 0.0;
super.boundingBox.e = 0.0;
super.boundingBox.f = 0.0;
a(0.0F, 0.0F);
setSize(1);
setInvisible(true);
}
@Override
public void l_() {
// Checks every 20 ticks.
if (ticksLived % 20 == 0) {
// The slime dies without a vehicle.
if (this.vehicle == null) {
die();
}
}
if (!lockTick) {
super.l_();
}
}
@Override
public void b(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean c(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public boolean d(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public void e(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean isInvulnerable() {
/*
* The field Entity.invulnerable is private.
* It's only used while saving NBTTags, but since the entity would be killed
* on chunk unload, we prefer to override isInvulnerable().
*/
return true;
}
@Override
public void setCustomName(String customName) {
// Locks the custom name.
}
@Override
public void setCustomNameVisible(boolean visible) {
// Locks the custom name.
}
@Override
public void makeSound(String sound, float volume, float pitch) {
// Remove sounds.
}
@Override
public void setLockTick(boolean lock) {
lockTick = lock;
}
@Override
public void die() {
setLockTick(false);
super.die();
}
@Override
public CraftEntity getBukkitEntity() {
if (super.bukkitEntity == null) {
this.bukkitEntity = new CraftTouchSlime(this.world.getServer(), this);
}
return this.bukkitEntity;
}
@Override
public boolean isDeadNMS() {
return super.dead;
}
@Override
public void killEntityNMS() {
die();
}
@Override
public void setLocationNMS(double x, double y, double z) {
super.setPosition(x, y, z);
}
@Override
public HologramBase getParentHologram() {
return parent;
}
@Override
public void setParentHologram(HologramBase base) {
this.parent = base;
}
}

View File

@ -1,99 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_6_R3;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.gmail.filoghost.holograms.nms.interfaces.FancyMessage;
public class FancyMessageImpl implements FancyMessage {
private final List<MessagePart> messageParts;
public FancyMessageImpl(final String firstPartText) {
messageParts = new ArrayList<MessagePart>();
messageParts.add(new MessagePart(firstPartText));
}
public FancyMessageImpl color(final ChatColor color) {
if (!color.isColor()) {
throw new IllegalArgumentException(color.name() + " is not a color");
}
latest().color = color;
return this;
}
public FancyMessageImpl style(final ChatColor... styles) {
for (final ChatColor style : styles) {
if (!style.isFormat()) {
throw new IllegalArgumentException(style.name() + " is not a style");
}
}
latest().styles = styles;
return this;
}
public FancyMessageImpl file(final String path) {
return this;
}
public FancyMessageImpl link(final String url) {
return this;
}
public FancyMessageImpl suggest(final String command) {
return this;
}
public FancyMessageImpl command(final String command) {
return this;
}
public FancyMessageImpl achievementTooltip(final String name) {
return this;
}
public FancyMessageImpl itemTooltip(final String itemJSON) {
return this;
}
public FancyMessageImpl itemTooltip(final ItemStack itemStack) {
return this;
}
public FancyMessageImpl tooltip(final String text) {
return this;
}
public FancyMessageImpl then(final Object obj) {
messageParts.add(new MessagePart(obj.toString()));
return this;
}
public String toJSONString() {
StringBuilder sb = new StringBuilder();
for (MessagePart part : messageParts) {
if (part.color != null) {
sb.append(part.color.toString());
}
if (part.styles != null && part.styles.length > 0) {
for (ChatColor style : part.styles) {
sb.append(style.toString());
}
}
sb.append(part.text);
}
return sb.toString();
}
public void send(Player player) {
player.sendMessage(toJSONString());
}
private MessagePart latest() {
return messageParts.get(messageParts.size() - 1);
}
}

View File

@ -1,136 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_6_R3;
import net.minecraft.server.v1_6_R3.Entity;
import net.minecraft.server.v1_6_R3.EntityTypes;
import net.minecraft.server.v1_6_R3.WorldServer;
import org.apache.commons.lang.NotImplementedException;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_6_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_6_R3.entity.CraftEntity;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.inventory.ItemStack;
import com.gmail.filoghost.holograms.exception.SpawnFailedException;
import com.gmail.filoghost.holograms.nms.interfaces.BasicEntityNMS;
import com.gmail.filoghost.holograms.nms.interfaces.CustomItem;
import com.gmail.filoghost.holograms.nms.interfaces.FancyMessage;
import com.gmail.filoghost.holograms.nms.interfaces.HologramArmorStand;
import com.gmail.filoghost.holograms.nms.interfaces.HologramComponent;
import com.gmail.filoghost.holograms.nms.interfaces.HologramHorse;
import com.gmail.filoghost.holograms.nms.interfaces.HologramWitherSkull;
import com.gmail.filoghost.holograms.nms.interfaces.NmsManager;
import com.gmail.filoghost.holograms.object.HologramBase;
import com.gmail.filoghost.holograms.utils.ReflectionUtils;
import com.gmail.filoghost.holograms.utils.VersionUtils;
public class NmsManagerImpl implements NmsManager {
@Override
public void registerCustomEntities() throws Exception {
registerCustomEntity(EntityHologramHorse.class, "EntityHorse", 100);
registerCustomEntity(EntityHologramWitherSkull.class, "WitherSkull", 19);
registerCustomEntity(EntityCustomItem.class, "Item", 1);
registerCustomEntity(EntityTouchSlime.class, "Slime", 55);
}
@SuppressWarnings("rawtypes")
public void registerCustomEntity(Class entityClass, String name, int id) throws Exception {
if (VersionUtils.isMCPCOrCauldron()) {
// MCPC+ / Cauldron entity registration.
Class<?> entityTypesClass = Class.forName("net.minecraft.server.v1_6_R3.EntityTypes");
ReflectionUtils.putInPrivateStaticMap(entityTypesClass, "field_75626_c", entityClass, name);
ReflectionUtils.putInPrivateStaticMap(entityTypesClass, "field_75624_e", entityClass, Integer.valueOf(id));
} else {
// Normal entity registration.
ReflectionUtils.putInPrivateStaticMap(EntityTypes.class, "c", entityClass, name);
ReflectionUtils.putInPrivateStaticMap(EntityTypes.class, "e", entityClass, Integer.valueOf(id));
}
}
@Override
public HologramHorse spawnHologramHorse(org.bukkit.World world, double x, double y, double z, HologramBase parent) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityHologramHorse invisibleHorse = new EntityHologramHorse(nmsWorld);
invisibleHorse.setParentHologram(parent);
invisibleHorse.setLocationNMS(x, y, z);
if (!nmsWorld.addEntity(invisibleHorse, SpawnReason.CUSTOM)) {
throw new SpawnFailedException();
}
return invisibleHorse;
}
@Override
public HologramWitherSkull spawnHologramWitherSkull(org.bukkit.World bukkitWorld, double x, double y, double z, HologramBase parent) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityHologramWitherSkull staticWitherSkull = new EntityHologramWitherSkull(nmsWorld);
staticWitherSkull.setParentHologram(parent);
staticWitherSkull.setLocationNMS(x, y, z);
if (!nmsWorld.addEntity(staticWitherSkull, SpawnReason.CUSTOM)) {
throw new SpawnFailedException();
}
return staticWitherSkull;
}
@Override
public CustomItem spawnCustomItem(org.bukkit.World bukkitWorld, double x, double y, double z, HologramBase parent, ItemStack stack) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityCustomItem customItem = new EntityCustomItem(nmsWorld);
customItem.setParentHologram(parent);
customItem.setLocationNMS(x, y, z);
customItem.setItemStackNMS(stack);
if (!nmsWorld.addEntity(customItem, SpawnReason.CUSTOM)) {
throw new SpawnFailedException();
}
return customItem;
}
@Override
public EntityTouchSlime spawnTouchSlime(org.bukkit.World bukkitWorld, double x, double y, double z, HologramBase parent) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityTouchSlime touchSlime = new EntityTouchSlime(nmsWorld);
touchSlime.setParentHologram(parent);
touchSlime.setLocationNMS(x, y, z);
if (!nmsWorld.addEntity(touchSlime, SpawnReason.CUSTOM)) {
throw new SpawnFailedException();
}
return touchSlime;
}
@Override
public boolean isHologramComponent(org.bukkit.entity.Entity bukkitEntity) {
return ((CraftEntity) bukkitEntity).getHandle() instanceof HologramComponent;
}
@Override
public boolean isBasicEntityNMS(org.bukkit.entity.Entity bukkitEntity) {
return ((CraftEntity) bukkitEntity).getHandle() instanceof BasicEntityNMS;
}
@Override
public HologramBase getParentHologram(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof HologramComponent) {
return ((HologramComponent) nmsEntity).getParentHologram();
}
return null;
}
@Override
public FancyMessage newFancyMessage(String text) {
return new FancyMessageImpl(text);
}
@Override
public boolean hasChatHoverFeature() {
return false;
}
@Override
public HologramArmorStand spawnHologramArmorStand(World world, double x, double y, double z, HologramBase parent) throws SpawnFailedException {
throw new NotImplementedException("Method can only be used on 1.8 or greater");
}
}

View File

@ -1,40 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_7_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_7_R1.CraftServer;
import org.bukkit.craftbukkit.v1_7_R1.entity.CraftItem;
import org.bukkit.entity.Entity;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
public class CraftCustomItem extends CraftItem {
public CraftCustomItem(CraftServer server, EntityCustomItem entity) {
super(server, entity);
}
// Disallow all the bukkit methods.
@Override
public void remove() {
// Cannot be removed, this is the most important to override.
}
// Methods from Entity
@Override public void setVelocity(Vector vel) { }
@Override public boolean teleport(Location loc) { return false; }
@Override public boolean teleport(Entity entity) { return false; }
@Override public boolean teleport(Location loc, TeleportCause cause) { return false; }
@Override public boolean teleport(Entity entity, TeleportCause cause) { return false; }
@Override public void setFireTicks(int ticks) { }
@Override public boolean setPassenger(Entity entity) { return false; }
@Override public boolean eject() { return false; }
@Override public boolean leaveVehicle() { return false; }
@Override public void playEffect(EntityEffect effect) { }
// Methods from Item
@Override public void setItemStack(ItemStack stack) { }
@Override public void setPickupDelay(int delay) { }
}

View File

@ -1,64 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_7_R1;
import java.util.Collection;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_7_R1.CraftServer;
import org.bukkit.craftbukkit.v1_7_R1.entity.CraftHorse;
import org.bukkit.entity.AnimalTamer;
import org.bukkit.entity.Entity;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.potion.PotionEffect;
import org.bukkit.util.Vector;
public class CraftHologramHorse extends CraftHorse {
public CraftHologramHorse(CraftServer server, EntityHologramHorse entity) {
super(server, entity);
}
// Disallow all the bukkit methods.
@Override
public void remove() {
// Cannot be removed, this is the most important to override.
}
// Methods from Horse class
@Override public void setVariant(Variant variant) { }
@Override public void setColor(Color color) { }
@Override public void setStyle(Style style) { }
@Override public void setCarryingChest(boolean chest) { }
@Override public void setDomestication(int domestication) { }
@Override public void setJumpStrength(double jump) { }
// Methods form Ageable class
@Override public void setAge(int age) { }
@Override public void setAgeLock(boolean lock) { }
@Override public void setBreed(boolean breed) { }
@Override public void setAdult() { }
@Override public void setBaby() { }
// Methods from LivingEntity class
@Override public boolean addPotionEffect(PotionEffect effect) { return false; }
@Override public boolean addPotionEffect(PotionEffect effect, boolean param) { return false; }
@Override public boolean addPotionEffects(Collection<PotionEffect> effects) { return false; }
@Override public void setRemoveWhenFarAway(boolean remove) { }
// Methods from Entity
@Override public void setVelocity(Vector vel) { }
@Override public boolean teleport(Location loc) { return false; }
@Override public boolean teleport(Entity entity) { return false; }
@Override public boolean teleport(Location loc, TeleportCause cause) { return false; }
@Override public boolean teleport(Entity entity, TeleportCause cause) { return false; }
@Override public void setFireTicks(int ticks) { }
@Override public boolean setPassenger(Entity entity) { return false; }
@Override public boolean eject() { return false; }
@Override public boolean leaveVehicle() { return false; }
@Override public void playEffect(EntityEffect effect) { }
// Methods from Tameable
@Override public void setTamed(boolean tame) { }
@Override public void setOwner(AnimalTamer owner) { }
}

View File

@ -1,46 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_7_R1;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_7_R1.CraftServer;
import org.bukkit.craftbukkit.v1_7_R1.entity.CraftWitherSkull;
import org.bukkit.entity.Entity;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.util.Vector;
public class CraftHologramWitherSkull extends CraftWitherSkull {
public CraftHologramWitherSkull(CraftServer server, EntityHologramWitherSkull entity) {
super(server, entity);
}
// Disallow all the bukkit methods.
@Override
public void remove() {
// Cannot be removed, this is the most important to override.
}
// Method from Fireball
@Override public void setDirection(Vector dir) { }
// Method from Projectile
@Override public void setBounce(boolean bounce) { }
// Methods from Explosive
@Override public void setYield(float yield) { }
@Override public void setIsIncendiary(boolean fire) { }
// Methods from Entity
@Override public void setVelocity(Vector vel) { }
@Override public boolean teleport(Location loc) { return false; }
@Override public boolean teleport(Entity entity) { return false; }
@Override public boolean teleport(Location loc, TeleportCause cause) { return false; }
@Override public boolean teleport(Entity entity, TeleportCause cause) { return false; }
@Override public void setFireTicks(int ticks) { }
@Override public boolean setPassenger(Entity entity) { return false; }
@Override public boolean eject() { return false; }
@Override public boolean leaveVehicle() { return false; }
@Override public void playEffect(EntityEffect effect) { }
}

View File

@ -1,48 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_7_R1;
import java.util.Collection;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_7_R1.CraftServer;
import org.bukkit.craftbukkit.v1_7_R1.entity.CraftSlime;
import org.bukkit.entity.Entity;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.potion.PotionEffect;
import org.bukkit.util.Vector;
public class CraftTouchSlime extends CraftSlime {
public CraftTouchSlime(CraftServer server, EntityTouchSlime entity) {
super(server, entity);
}
// Disallow all the bukkit methods.
@Override
public void remove() {
// Cannot be removed, this is the most important to override.
}
// Methods from LivingEntity class
@Override public boolean addPotionEffect(PotionEffect effect) { return false; }
@Override public boolean addPotionEffect(PotionEffect effect, boolean param) { return false; }
@Override public boolean addPotionEffects(Collection<PotionEffect> effects) { return false; }
@Override public void setRemoveWhenFarAway(boolean remove) { }
// Methods from Entity
@Override public void setVelocity(Vector vel) { }
@Override public boolean teleport(Location loc) { return false; }
@Override public boolean teleport(Entity entity) { return false; }
@Override public boolean teleport(Location loc, TeleportCause cause) { return false; }
@Override public boolean teleport(Entity entity, TeleportCause cause) { return false; }
@Override public void setFireTicks(int ticks) { }
@Override public boolean setPassenger(Entity entity) { return false; }
@Override public boolean eject() { return false; }
@Override public boolean leaveVehicle() { return false; }
@Override public void playEffect(EntityEffect effect) { }
// Methods from Slime
@Override public void setSize(int size) { }
}

View File

@ -1,190 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_7_R1;
import org.bukkit.craftbukkit.v1_7_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_7_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import com.gmail.filoghost.holograms.HolographicDisplays;
import com.gmail.filoghost.holograms.api.FloatingItem;
import com.gmail.filoghost.holograms.nms.interfaces.BasicEntityNMS;
import com.gmail.filoghost.holograms.nms.interfaces.CustomItem;
import com.gmail.filoghost.holograms.object.HologramBase;
import com.gmail.filoghost.holograms.utils.ItemUtils;
import net.minecraft.server.v1_7_R1.EntityItem;
import net.minecraft.server.v1_7_R1.ItemStack;
import net.minecraft.server.v1_7_R1.NBTTagCompound;
import net.minecraft.server.v1_7_R1.World;
import net.minecraft.server.v1_7_R1.EntityHuman;
import net.minecraft.server.v1_7_R1.EntityPlayer;
import net.minecraft.server.v1_7_R1.NBTTagList;
import net.minecraft.server.v1_7_R1.NBTTagString;
import net.minecraft.server.v1_7_R1.Blocks;
public class EntityCustomItem extends EntityItem implements CustomItem, BasicEntityNMS {
private boolean lockTick;
private HologramBase parent;
public EntityCustomItem(World world) {
super(world);
super.pickupDelay = Integer.MAX_VALUE;
}
@Override
public void h() {
// Checks every 20 ticks.
if (ticksLived % 20 == 0) {
// The item dies without a vehicle.
if (this.vehicle == null) {
die();
}
}
if (!lockTick) {
super.h();
}
}
@Override
public ItemStack getItemStack() {
// Dirty method to check if the icon is being picked up
StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace();
if (stacktrace.length > 2 && stacktrace[2].getClassName().contains("EntityInsentient")) {
return null; // Try to pickup this, dear entity ignoring the pickupDelay!
}
return super.getItemStack();
}
// Method called when a player is near.
@Override
public void b_(EntityHuman human) {
if (parent instanceof FloatingItem && human instanceof EntityPlayer) {
FloatingItem floatingItemParent = (FloatingItem) parent;
if (floatingItemParent.hasPickupHandler()) {
try {
floatingItemParent.getPickupHandler().onPickup(floatingItemParent, (Player) human.getBukkitEntity());
} catch (Exception ex) {
ex.printStackTrace();
HolographicDisplays.getInstance().getLogger().warning("An exception occurred while a player was picking up a floating item. It's probably caused by another plugin using Holographic Displays as library.");
}
}
// It is never added to the inventory.
}
}
@Override
public void b(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean c(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public boolean d(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public void e(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean isInvulnerable() {
/*
* The field Entity.invulnerable is private.
* It's only used while saving NBTTags, but since the entity would be killed
* on chunk unload, we prefer to override isInvulnerable().
*/
return true;
}
@Override
public void setLockTick(boolean lock) {
lockTick = lock;
}
@Override
public void die() {
setLockTick(false);
super.die();
}
@Override
public CraftEntity getBukkitEntity() {
if (super.bukkitEntity == null) {
this.bukkitEntity = new CraftCustomItem(this.world.getServer(), this);
}
return this.bukkitEntity;
}
@Override
public boolean isDeadNMS() {
return this.dead;
}
@Override
public void killEntityNMS() {
die();
}
@Override
public void setLocationNMS(double x, double y, double z) {
super.setPosition(x, y, z);
}
@Override
public void setItemStackNMS(org.bukkit.inventory.ItemStack stack) {
ItemStack newItem = CraftItemStack.asNMSCopy(stack);
if (newItem == null) {
newItem = new ItemStack(Blocks.BEDROCK);
}
if (newItem.tag == null) {
newItem.tag = new NBTTagCompound();
}
NBTTagCompound display = newItem.tag.getCompound("display");
if (!newItem.tag.hasKey("display")) {
newItem.tag.set("display", display);
}
NBTTagList tagList = new NBTTagList();
tagList.add(new NBTTagString(ItemUtils.ANTISTACK_LORE)); // Antistack lore
display.set("Lore", tagList);
newItem.count = 0;
setItemStack(newItem);
}
@Override
public HologramBase getParentHologram() {
return parent;
}
@Override
public void setParentHologram(HologramBase base) {
this.parent = base;
}
@Override
public void allowPickup(boolean pickup) {
if (pickup) {
super.pickupDelay = 0;
} else {
super.pickupDelay = Integer.MAX_VALUE;
}
}
}

View File

@ -1,150 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_7_R1;
import org.bukkit.craftbukkit.v1_7_R1.entity.CraftEntity;
import com.gmail.filoghost.holograms.nms.interfaces.HologramHorse;
import com.gmail.filoghost.holograms.object.HologramBase;
import net.minecraft.server.v1_7_R1.EntityHorse;
import net.minecraft.server.v1_7_R1.NBTTagCompound;
import net.minecraft.server.v1_7_R1.World;
public class EntityHologramHorse extends EntityHorse implements HologramHorse {
private boolean lockTick;
private HologramBase parent;
public EntityHologramHorse(World world) {
super(world);
super.ageLocked = true;
super.persistent = true;
super.boundingBox.a = 0.0;
super.boundingBox.b = 0.0;
super.boundingBox.c = 0.0;
super.boundingBox.d = 0.0;
super.boundingBox.e = 0.0;
super.boundingBox.f = 0.0;
a(0.0F, 0.0F);
setAge(-1700000); // This is a magic value. No one will see the real horse.
}
@Override
public void h() {
// Checks every 20 ticks.
if (super.ticksLived % 20 == 0) {
// The horse dies without a valid vehicle.
if (super.vehicle == null) {
die();
}
}
if (!lockTick) {
super.h();
}
}
@Override
public void b(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean c(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public boolean d(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public void e(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean isInvulnerable() {
/*
* The field Entity.invulnerable is private.
* It's only used while saving NBTTags, but since the entity would be killed
* on chunk unload, we prefer to override isInvulnerable().
*/
return true;
}
@Override
public void setCustomName(String customName) {
// Locks the custom name.
}
@Override
public void setCustomNameVisible(boolean visible) {
// Locks the custom name.
}
@Override
public void makeSound(String sound, float volume, float pitch) {
// Remove sounds.
}
@Override
public void setLockTick(boolean lock) {
lockTick = lock;
}
@Override
public void die() {
setLockTick(false);
super.die();
}
@Override
public void forceSetCustomName(String name) {
if (name != null && name.length() > 300) {
name = name.substring(0, 300);
}
super.setCustomName(name);
super.setCustomNameVisible(name != null);
}
@Override
public CraftEntity getBukkitEntity() {
if (super.bukkitEntity == null) {
super.bukkitEntity = new CraftHologramHorse(this.world.getServer(), this);
}
return super.bukkitEntity;
}
@Override
public boolean isDeadNMS() {
return this.dead;
}
@Override
public String getCustomNameNMS() {
return super.getCustomName();
}
@Override
public void killEntityNMS() {
die();
}
@Override
public void setLocationNMS(double x, double y, double z) {
super.setPosition(x, y, z);
}
@Override
public HologramBase getParentHologram() {
return parent;
}
@Override
public void setParentHologram(HologramBase base) {
this.parent = base;
}
}

View File

@ -1,158 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_7_R1;
import org.bukkit.craftbukkit.v1_7_R1.entity.CraftEntity;
import com.gmail.filoghost.holograms.nms.interfaces.BasicEntityNMS;
import com.gmail.filoghost.holograms.nms.interfaces.HologramWitherSkull;
import com.gmail.filoghost.holograms.object.HologramBase;
import com.gmail.filoghost.holograms.utils.GenericUtils;
import net.minecraft.server.v1_7_R1.Entity;
import net.minecraft.server.v1_7_R1.EntityWitherSkull;
import net.minecraft.server.v1_7_R1.NBTTagCompound;
import net.minecraft.server.v1_7_R1.World;
import net.minecraft.server.v1_7_R1.EntityPlayer;
import net.minecraft.server.v1_7_R1.PacketPlayOutEntityTeleport;
public class EntityHologramWitherSkull extends EntityWitherSkull implements HologramWitherSkull {
private boolean lockTick;
private HologramBase parent;
public EntityHologramWitherSkull(World world) {
super(world);
super.motX = 0.0;
super.motY = 0.0;
super.motZ = 0.0;
super.dirX = 0.0;
super.dirY = 0.0;
super.dirZ = 0.0;
super.boundingBox.a = 0.0;
super.boundingBox.b = 0.0;
super.boundingBox.c = 0.0;
super.boundingBox.d = 0.0;
super.boundingBox.e = 0.0;
super.boundingBox.f = 0.0;
a(0.0F, 0.0F);
}
@Override
public void b(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean c(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public boolean d(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public void e(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean isInvulnerable() {
/*
* The field Entity.invulnerable is private.
* It's only used while saving NBTTags, but since the entity would be killed
* on chunk unload, we prefer to override isInvulnerable().
*/
return true;
}
@Override
public void h() {
if (!lockTick) {
super.h();
}
}
@Override
public void makeSound(String sound, float f1, float f2) {
// Remove sounds.
}
@Override
public void setLockTick(boolean lock) {
lockTick = lock;
}
@Override
public void die() {
setLockTick(false);
super.die();
}
@Override
public CraftEntity getBukkitEntity() {
if (super.bukkitEntity == null) {
this.bukkitEntity = new CraftHologramWitherSkull(this.world.getServer(), this);
}
return this.bukkitEntity;
}
@Override
public void killEntityNMS() {
die();
}
@Override
public void setLocationNMS(double x, double y, double z) {
super.setPosition(x, y, z);
}
@Override
public void sendUpdatePacketNear() {
// Send a packet to update the position.
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this);
for (Object obj : this.world.players) {
if (obj instanceof EntityPlayer) {
EntityPlayer nmsPlayer = (EntityPlayer) obj;
double distanceSquared = GenericUtils.square(nmsPlayer.locX - this.locX) + GenericUtils.square(nmsPlayer.locZ - this.locZ);
if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
nmsPlayer.playerConnection.sendPacket(teleportPacket);
}
}
}
}
@Override
public boolean isDeadNMS() {
return this.dead;
}
@Override
public void setPassengerNMS(BasicEntityNMS passenger) {
if (passenger instanceof Entity) {
((Entity) passenger).setPassengerOf(this);
}
}
@Override
public void setPassengerNMS(org.bukkit.entity.Entity bukkitEntity) {
((CraftEntity) bukkitEntity).getHandle().setPassengerOf(this);
}
@Override
public HologramBase getParentHologram() {
return parent;
}
@Override
public void setParentHologram(HologramBase base) {
this.parent = base;
}
}

View File

@ -1,136 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_7_R1;
import org.bukkit.craftbukkit.v1_7_R1.entity.CraftEntity;
import com.gmail.filoghost.holograms.nms.interfaces.TouchSlime;
import com.gmail.filoghost.holograms.object.HologramBase;
import net.minecraft.server.v1_7_R1.EntitySlime;
import net.minecraft.server.v1_7_R1.NBTTagCompound;
import net.minecraft.server.v1_7_R1.World;
public class EntityTouchSlime extends EntitySlime implements TouchSlime {
private boolean lockTick;
private HologramBase parent;
public EntityTouchSlime(World world) {
super(world);
super.persistent = true;
super.boundingBox.a = 0.0;
super.boundingBox.b = 0.0;
super.boundingBox.c = 0.0;
super.boundingBox.d = 0.0;
super.boundingBox.e = 0.0;
super.boundingBox.f = 0.0;
a(0.0F, 0.0F);
setSize(1);
setInvisible(true);
}
@Override
public void h() {
// Checks every 20 ticks.
if (ticksLived % 20 == 0) {
// The slime dies without a vehicle.
if (this.vehicle == null) {
die();
}
}
if (!lockTick) {
super.h();
}
}
@Override
public void b(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean c(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public boolean d(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public void e(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean isInvulnerable() {
/*
* The field Entity.invulnerable is private.
* It's only used while saving NBTTags, but since the entity would be killed
* on chunk unload, we prefer to override isInvulnerable().
*/
return true;
}
@Override
public void setCustomName(String customName) {
// Locks the custom name.
}
@Override
public void setCustomNameVisible(boolean visible) {
// Locks the custom name.
}
@Override
public void makeSound(String sound, float volume, float pitch) {
// Remove sounds.
}
@Override
public void setLockTick(boolean lock) {
lockTick = lock;
}
@Override
public void die() {
setLockTick(false);
super.die();
}
@Override
public CraftEntity getBukkitEntity() {
if (super.bukkitEntity == null) {
this.bukkitEntity = new CraftTouchSlime(this.world.getServer(), this);
}
return this.bukkitEntity;
}
@Override
public boolean isDeadNMS() {
return super.dead;
}
@Override
public void killEntityNMS() {
die();
}
@Override
public void setLocationNMS(double x, double y, double z) {
super.setPosition(x, y, z);
}
@Override
public HologramBase getParentHologram() {
return parent;
}
@Override
public void setParentHologram(HologramBase base) {
this.parent = base;
}
}

View File

@ -1,158 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_7_R1;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.server.v1_7_R1.ChatSerializer;
import net.minecraft.server.v1_7_R1.NBTTagCompound;
import net.minecraft.server.v1_7_R1.PacketPlayOutChat;
import org.bukkit.ChatColor;
import org.bukkit.craftbukkit.libs.com.google.gson.stream.JsonWriter;
import org.bukkit.craftbukkit.v1_7_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_7_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.gmail.filoghost.holograms.nms.interfaces.FancyMessage;
public class FancyMessageImpl implements FancyMessage {
private List<MessagePart> messageParts;
public FancyMessageImpl(String firstPartText) {
messageParts = new ArrayList<MessagePart>();
messageParts.add(new MessagePart(firstPartText));
}
public FancyMessageImpl color(ChatColor color) {
if (!color.isColor()) {
throw new IllegalArgumentException(color.name() + " is not a color");
}
latest().color = color;
return this;
}
public FancyMessageImpl style(ChatColor... styles) {
for (ChatColor style : styles) {
if (!style.isFormat()) {
throw new IllegalArgumentException(style.name() + " is not a style");
}
}
latest().styles = styles;
return this;
}
public FancyMessageImpl file(String path) {
onClick("open_file", path);
return this;
}
public FancyMessageImpl link(String url) {
onClick("open_url", url);
return this;
}
public FancyMessageImpl suggest(String command) {
onClick("suggest_command", command);
return this;
}
public FancyMessageImpl command(String command) {
onClick("run_command", command);
return this;
}
public FancyMessageImpl achievementTooltip(String name) {
onHover("show_achievement", "achievement." + name);
return this;
}
public FancyMessageImpl itemTooltip(String itemJSON) {
onHover("show_item", itemJSON);
return this;
}
public FancyMessageImpl itemTooltip(ItemStack itemStack) {
return itemTooltip(CraftItemStack.asNMSCopy(itemStack).save(new NBTTagCompound()).toString());
}
public FancyMessageImpl tooltip(String text) {
String[] lines = text.split("\\n");
if (lines.length <= 1) {
onHover("show_text", text);
} else {
itemTooltip(makeMultilineTooltip(lines));
}
return this;
}
public FancyMessageImpl then(Object obj) {
messageParts.add(new MessagePart(obj.toString()));
return this;
}
public String toJSONString() {
StringWriter stringWriter = new StringWriter();
JsonWriter json = new JsonWriter(stringWriter);
try {
if (messageParts.size() == 1) {
latest().writeJson(json);
} else {
json.beginObject().name("text").value("").name("extra").beginArray();
for (MessagePart part : messageParts) {
part.writeJson(json);
}
json.endArray().endObject();
}
} catch (IOException e) {
throw new RuntimeException("invalid message");
}
return stringWriter.toString();
}
public void send(Player player){
((CraftPlayer) player).getHandle().playerConnection.sendPacket(new PacketPlayOutChat(ChatSerializer.a(toJSONString())));
}
private MessagePart latest() {
return messageParts.get(messageParts.size() - 1);
}
private String makeMultilineTooltip(String[] lines) {
StringWriter stringWriter = new StringWriter();
JsonWriter json = new JsonWriter(stringWriter);
try {
json.beginObject().name("id").value(1);
json.name("tag").beginObject().name("display").beginObject();
json.name("Name").value("\\u00A7f" + lines[0].replace("\"", "\\\""));
json.name("Lore").beginArray();
for (int i = 1; i < lines.length; i++) {
String line = lines[i];
json.value(line.isEmpty() ? " " : line.replace("\"", "\\\""));
}
json.endArray().endObject().endObject().endObject();
json.close();
} catch (IOException e) {
throw new RuntimeException("invalid tooltip");
}
return stringWriter.toString();
}
private void onClick(String name, String data) {
MessagePart latest = latest();
latest.clickActionName = name;
latest.clickActionData = data;
}
private void onHover(String name, String data) {
MessagePart latest = latest();
latest.hoverActionName = name;
latest.hoverActionData = data;
}
}

View File

@ -1,135 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_7_R1;
import net.minecraft.server.v1_7_R1.Entity;
import net.minecraft.server.v1_7_R1.EntityTypes;
import net.minecraft.server.v1_7_R1.WorldServer;
import org.apache.commons.lang.NotImplementedException;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_7_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_7_R1.entity.CraftEntity;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.inventory.ItemStack;
import com.gmail.filoghost.holograms.exception.SpawnFailedException;
import com.gmail.filoghost.holograms.nms.interfaces.BasicEntityNMS;
import com.gmail.filoghost.holograms.nms.interfaces.CustomItem;
import com.gmail.filoghost.holograms.nms.interfaces.FancyMessage;
import com.gmail.filoghost.holograms.nms.interfaces.HologramArmorStand;
import com.gmail.filoghost.holograms.nms.interfaces.HologramComponent;
import com.gmail.filoghost.holograms.nms.interfaces.HologramHorse;
import com.gmail.filoghost.holograms.nms.interfaces.HologramWitherSkull;
import com.gmail.filoghost.holograms.nms.interfaces.NmsManager;
import com.gmail.filoghost.holograms.object.HologramBase;
import com.gmail.filoghost.holograms.utils.ReflectionUtils;
import com.gmail.filoghost.holograms.utils.VersionUtils;
public class NmsManagerImpl implements NmsManager {
@Override
public void registerCustomEntities() throws Exception {
registerCustomEntity(EntityHologramHorse.class, "EntityHorse", 100);
registerCustomEntity(EntityHologramWitherSkull.class, "WitherSkull", 19);
registerCustomEntity(EntityCustomItem.class, "Item", 1);
registerCustomEntity(EntityTouchSlime.class, "Slime", 55);
}
@SuppressWarnings("rawtypes")
public void registerCustomEntity(Class entityClass, String name, int id) throws Exception {
if (VersionUtils.isMCPCOrCauldron()) {
// MCPC+ / Cauldron entity registration.
Class<?> entityTypesClass = Class.forName("net.minecraft.server.v1_7_R1.EntityTypes");
ReflectionUtils.putInPrivateStaticMap(entityTypesClass, "field_75626_c", entityClass, name);
ReflectionUtils.putInPrivateStaticMap(entityTypesClass, "field_75624_e", entityClass, Integer.valueOf(id));
} else {
// Normal entity registration.
ReflectionUtils.putInPrivateStaticMap(EntityTypes.class, "d", entityClass, name);
ReflectionUtils.putInPrivateStaticMap(EntityTypes.class, "f", entityClass, Integer.valueOf(id));
}
}
@Override
public HologramHorse spawnHologramHorse(org.bukkit.World world, double x, double y, double z, HologramBase parent) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) world).getHandle();
EntityHologramHorse invisibleHorse = new EntityHologramHorse(nmsWorld);
invisibleHorse.setParentHologram(parent);
invisibleHorse.setLocationNMS(x, y, z);
if (!nmsWorld.addEntity(invisibleHorse, SpawnReason.CUSTOM)) {
throw new SpawnFailedException();
}
return invisibleHorse;
}
@Override
public HologramWitherSkull spawnHologramWitherSkull(org.bukkit.World bukkitWorld, double x, double y, double z, HologramBase parent) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityHologramWitherSkull staticWitherSkull = new EntityHologramWitherSkull(nmsWorld);
staticWitherSkull.setParentHologram(parent);
staticWitherSkull.setLocationNMS(x, y, z);
if (!nmsWorld.addEntity(staticWitherSkull, SpawnReason.CUSTOM)) {
throw new SpawnFailedException();
}
return staticWitherSkull;
}
@Override
public CustomItem spawnCustomItem(org.bukkit.World bukkitWorld, double x, double y, double z, HologramBase parent, ItemStack stack) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityCustomItem customItem = new EntityCustomItem(nmsWorld);
customItem.setParentHologram(parent);
customItem.setLocationNMS(x, y, z);
customItem.setItemStackNMS(stack);
if (!nmsWorld.addEntity(customItem, SpawnReason.CUSTOM)) {
throw new SpawnFailedException();
}
return customItem;
}
@Override
public EntityTouchSlime spawnTouchSlime(org.bukkit.World bukkitWorld, double x, double y, double z, HologramBase parent) throws SpawnFailedException {
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
EntityTouchSlime touchSlime = new EntityTouchSlime(nmsWorld);
touchSlime.setParentHologram(parent);
touchSlime.setLocationNMS(x, y, z);
if (!nmsWorld.addEntity(touchSlime, SpawnReason.CUSTOM)) {
throw new SpawnFailedException();
}
return touchSlime;
}
@Override
public boolean isHologramComponent(org.bukkit.entity.Entity bukkitEntity) {
return ((CraftEntity) bukkitEntity).getHandle() instanceof HologramComponent;
}
@Override
public boolean isBasicEntityNMS(org.bukkit.entity.Entity bukkitEntity) {
return ((CraftEntity) bukkitEntity).getHandle() instanceof BasicEntityNMS;
}
@Override
public HologramBase getParentHologram(org.bukkit.entity.Entity bukkitEntity) {
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
if (nmsEntity instanceof HologramComponent) {
return ((HologramComponent) nmsEntity).getParentHologram();
}
return null;
}
@Override
public FancyMessage newFancyMessage(String text) {
return new FancyMessageImpl(text);
}
@Override
public boolean hasChatHoverFeature() {
return true;
}
@Override
public HologramArmorStand spawnHologramArmorStand(World world, double x, double y, double z, HologramBase parent) throws SpawnFailedException {
throw new NotImplementedException("Method can only be used on 1.8 or greater");
}
}

View File

@ -1,41 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_7_R2;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_7_R2.CraftServer;
import org.bukkit.craftbukkit.v1_7_R2.entity.CraftItem;
import org.bukkit.entity.Entity;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
public class CraftCustomItem extends CraftItem {
public CraftCustomItem(CraftServer server, EntityCustomItem entity) {
super(server, entity);
}
// Disallow all the bukkit methods.
@Override
public void remove() {
// Cannot be removed, this is the most important to override.
}
// Methods from Entity
@Override public void setVelocity(Vector vel) { }
@Override public boolean teleport(Location loc) { return false; }
@Override public boolean teleport(Entity entity) { return false; }
@Override public boolean teleport(Location loc, TeleportCause cause) { return false; }
@Override public boolean teleport(Entity entity, TeleportCause cause) { return false; }
@Override public void setFireTicks(int ticks) { }
@Override public boolean setPassenger(Entity entity) { return false; }
@Override public boolean eject() { return false; }
@Override public boolean leaveVehicle() { return false; }
@Override public void playEffect(EntityEffect effect) { }
// Methods from Item
@Override public void setItemStack(ItemStack stack) { }
@Override public void setPickupDelay(int delay) { }
}

View File

@ -1,64 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_7_R2;
import java.util.Collection;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_7_R2.CraftServer;
import org.bukkit.craftbukkit.v1_7_R2.entity.CraftHorse;
import org.bukkit.entity.AnimalTamer;
import org.bukkit.entity.Entity;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.potion.PotionEffect;
import org.bukkit.util.Vector;
public class CraftHologramHorse extends CraftHorse {
public CraftHologramHorse(CraftServer server, EntityHologramHorse entity) {
super(server, entity);
}
// Disallow all the bukkit methods.
@Override
public void remove() {
// Cannot be removed, this is the most important to override.
}
// Methods from Horse class
@Override public void setVariant(Variant variant) { }
@Override public void setColor(Color color) { }
@Override public void setStyle(Style style) { }
@Override public void setCarryingChest(boolean chest) { }
@Override public void setDomestication(int domestication) { }
@Override public void setJumpStrength(double jump) { }
// Methods form Ageable class
@Override public void setAge(int age) { }
@Override public void setAgeLock(boolean lock) { }
@Override public void setBreed(boolean breed) { }
@Override public void setAdult() { }
@Override public void setBaby() { }
// Methods from LivingEntity class
@Override public boolean addPotionEffect(PotionEffect effect) { return false; }
@Override public boolean addPotionEffect(PotionEffect effect, boolean param) { return false; }
@Override public boolean addPotionEffects(Collection<PotionEffect> effects) { return false; }
@Override public void setRemoveWhenFarAway(boolean remove) { }
// Methods from Entity
@Override public void setVelocity(Vector vel) { }
@Override public boolean teleport(Location loc) { return false; }
@Override public boolean teleport(Entity entity) { return false; }
@Override public boolean teleport(Location loc, TeleportCause cause) { return false; }
@Override public boolean teleport(Entity entity, TeleportCause cause) { return false; }
@Override public void setFireTicks(int ticks) { }
@Override public boolean setPassenger(Entity entity) { return false; }
@Override public boolean eject() { return false; }
@Override public boolean leaveVehicle() { return false; }
@Override public void playEffect(EntityEffect effect) { }
// Methods from Tameable
@Override public void setTamed(boolean tame) { }
@Override public void setOwner(AnimalTamer owner) { }
}

View File

@ -1,45 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_7_R2;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_7_R2.CraftServer;
import org.bukkit.craftbukkit.v1_7_R2.entity.CraftWitherSkull;
import org.bukkit.entity.Entity;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.util.Vector;
public class CraftHologramWitherSkull extends CraftWitherSkull {
public CraftHologramWitherSkull(CraftServer server, EntityHologramWitherSkull entity) {
super(server, entity);
}
// Disallow all the bukkit methods.
@Override
public void remove() {
// Cannot be removed, this is the most important to override.
}
// Method from Fireball
@Override public void setDirection(Vector dir) { }
// Method from Projectile
@Override public void setBounce(boolean bounce) { }
// Methods from Explosive
@Override public void setYield(float yield) { }
@Override public void setIsIncendiary(boolean fire) { }
// Methods from Entity
@Override public void setVelocity(Vector vel) { }
@Override public boolean teleport(Location loc) { return false; }
@Override public boolean teleport(Entity entity) { return false; }
@Override public boolean teleport(Location loc, TeleportCause cause) { return false; }
@Override public boolean teleport(Entity entity, TeleportCause cause) { return false; }
@Override public void setFireTicks(int ticks) { }
@Override public boolean setPassenger(Entity entity) { return false; }
@Override public boolean eject() { return false; }
@Override public boolean leaveVehicle() { return false; }
@Override public void playEffect(EntityEffect effect) { }
}

View File

@ -1,48 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_7_R2;
import java.util.Collection;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_7_R2.CraftServer;
import org.bukkit.craftbukkit.v1_7_R2.entity.CraftSlime;
import org.bukkit.entity.Entity;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.potion.PotionEffect;
import org.bukkit.util.Vector;
public class CraftTouchSlime extends CraftSlime {
public CraftTouchSlime(CraftServer server, EntityTouchSlime entity) {
super(server, entity);
}
// Disallow all the bukkit methods.
@Override
public void remove() {
// Cannot be removed, this is the most important to override.
}
// Methods from LivingEntity class
@Override public boolean addPotionEffect(PotionEffect effect) { return false; }
@Override public boolean addPotionEffect(PotionEffect effect, boolean param) { return false; }
@Override public boolean addPotionEffects(Collection<PotionEffect> effects) { return false; }
@Override public void setRemoveWhenFarAway(boolean remove) { }
// Methods from Entity
@Override public void setVelocity(Vector vel) { }
@Override public boolean teleport(Location loc) { return false; }
@Override public boolean teleport(Entity entity) { return false; }
@Override public boolean teleport(Location loc, TeleportCause cause) { return false; }
@Override public boolean teleport(Entity entity, TeleportCause cause) { return false; }
@Override public void setFireTicks(int ticks) { }
@Override public boolean setPassenger(Entity entity) { return false; }
@Override public boolean eject() { return false; }
@Override public boolean leaveVehicle() { return false; }
@Override public void playEffect(EntityEffect effect) { }
// Methods from Slime
@Override public void setSize(int size) { }
}

View File

@ -1,189 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_7_R2;
import org.bukkit.craftbukkit.v1_7_R2.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_7_R2.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import com.gmail.filoghost.holograms.HolographicDisplays;
import com.gmail.filoghost.holograms.api.FloatingItem;
import com.gmail.filoghost.holograms.nms.interfaces.BasicEntityNMS;
import com.gmail.filoghost.holograms.nms.interfaces.CustomItem;
import com.gmail.filoghost.holograms.object.HologramBase;
import com.gmail.filoghost.holograms.utils.ItemUtils;
import net.minecraft.server.v1_7_R2.EntityItem;
import net.minecraft.server.v1_7_R2.ItemStack;
import net.minecraft.server.v1_7_R2.NBTTagCompound;
import net.minecraft.server.v1_7_R2.World;
import net.minecraft.server.v1_7_R2.EntityHuman;
import net.minecraft.server.v1_7_R2.EntityPlayer;
import net.minecraft.server.v1_7_R2.NBTTagList;
import net.minecraft.server.v1_7_R2.NBTTagString;
import net.minecraft.server.v1_7_R2.Blocks;
public class EntityCustomItem extends EntityItem implements CustomItem, BasicEntityNMS {
private boolean lockTick;
private HologramBase parent;
public EntityCustomItem(World world) {
super(world);
super.pickupDelay = Integer.MAX_VALUE;
}
@Override
public void h() {
// Checks every 20 ticks.
if (ticksLived % 20 == 0) {
// The item dies without a vehicle.
if (this.vehicle == null) {
die();
}
}
if (!lockTick) {
super.h();
}
}
@Override
public ItemStack getItemStack() {
// Dirty method to check if the icon is being picked up
StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace();
if (stacktrace.length > 2 && stacktrace[2].getClassName().contains("EntityInsentient")) {
return null; // Try to pickup this, dear entity ignoring the pickupDelay!
}
return super.getItemStack();
}
// Method called when a player is near.
@Override
public void b_(EntityHuman human) {
if (parent instanceof FloatingItem && human instanceof EntityPlayer) {
FloatingItem floatingItemParent = (FloatingItem) parent;
if (floatingItemParent.hasPickupHandler()) {
try {
floatingItemParent.getPickupHandler().onPickup(floatingItemParent, (Player) human.getBukkitEntity());
} catch (Exception ex) {
ex.printStackTrace();
HolographicDisplays.getInstance().getLogger().warning("An exception occurred while a player was picking up a floating item. It's probably caused by another plugin using Holographic Displays as library.");
}
}
// It is never added to the inventory.
}
}
@Override
public void b(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean c(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public boolean d(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public void e(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean isInvulnerable() {
/*
* The field Entity.invulnerable is private.
* It's only used while saving NBTTags, but since the entity would be killed
* on chunk unload, we prefer to override isInvulnerable().
*/
return true;
}
@Override
public void setLockTick(boolean lock) {
lockTick = lock;
}
@Override
public void die() {
setLockTick(false);
super.die();
}
@Override
public CraftEntity getBukkitEntity() {
if (super.bukkitEntity == null) {
this.bukkitEntity = new CraftCustomItem(this.world.getServer(), this);
}
return this.bukkitEntity;
}
@Override
public boolean isDeadNMS() {
return this.dead;
}
@Override
public void killEntityNMS() {
die();
}
@Override
public void setLocationNMS(double x, double y, double z) {
super.setPosition(x, y, z);
}
@Override
public void setItemStackNMS(org.bukkit.inventory.ItemStack stack) {
ItemStack newItem = CraftItemStack.asNMSCopy(stack);
if (newItem == null) {
newItem = new ItemStack(Blocks.BEDROCK);
}
if (newItem.tag == null) {
newItem.tag = new NBTTagCompound();
}
NBTTagCompound display = newItem.tag.getCompound("display");
if (!newItem.tag.hasKey("display")) {
newItem.tag.set("display", display);
}
NBTTagList tagList = new NBTTagList();
tagList.add(new NBTTagString(ItemUtils.ANTISTACK_LORE)); // Antistack lore
display.set("Lore", tagList);
newItem.count = 0;
setItemStack(newItem);
}
@Override
public HologramBase getParentHologram() {
return parent;
}
@Override
public void setParentHologram(HologramBase base) {
this.parent = base;
}
@Override
public void allowPickup(boolean pickup) {
if (pickup) {
super.pickupDelay = 0;
} else {
super.pickupDelay = Integer.MAX_VALUE;
}
}
}

View File

@ -1,151 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_7_R2;
import org.bukkit.craftbukkit.v1_7_R2.entity.CraftEntity;
import com.gmail.filoghost.holograms.nms.interfaces.HologramHorse;
import com.gmail.filoghost.holograms.object.HologramBase;
import net.minecraft.server.v1_7_R2.EntityHorse;
import net.minecraft.server.v1_7_R2.NBTTagCompound;
import net.minecraft.server.v1_7_R2.World;
public class EntityHologramHorse extends EntityHorse implements HologramHorse {
private boolean lockTick;
private HologramBase parent;
public EntityHologramHorse(World world) {
super(world);
super.ageLocked = true;
super.persistent = true;
super.boundingBox.a = 0.0;
super.boundingBox.b = 0.0;
super.boundingBox.c = 0.0;
super.boundingBox.d = 0.0;
super.boundingBox.e = 0.0;
super.boundingBox.f = 0.0;
a(0.0F, 0.0F);
setAge(-1700000); // This is a magic value. No one will see the real horse.
}
@Override
public void h() {
// Checks every 20 ticks.
if (ticksLived % 20 == 0) {
// The horse dies without a vehicle.
if (this.vehicle == null) {
die();
}
}
if (!lockTick) {
super.h();
}
}
@Override
public void b(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean c(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public boolean d(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public void e(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean isInvulnerable() {
/*
* The field Entity.invulnerable is private.
* It's only used while saving NBTTags, but since the entity would be killed
* on chunk unload, we prefer to override isInvulnerable().
*/
return true;
}
@Override
public void setCustomName(String customName) {
// Locks the custom name.
}
@Override
public void setCustomNameVisible(boolean visible) {
// Locks the custom name.
}
@Override
public void makeSound(String sound, float volume, float pitch) {
// Remove sounds.
}
@Override
public void setLockTick(boolean lock) {
lockTick = lock;
}
@Override
public void die() {
setLockTick(false);
super.die();
}
@Override
public void forceSetCustomName(String name) {
if (name != null && name.length() > 300) {
name = name.substring(0, 300);
}
super.setCustomName(name);
super.setCustomNameVisible(name != null);
}
@Override
public CraftEntity getBukkitEntity() {
if (super.bukkitEntity == null) {
this.bukkitEntity = new CraftHologramHorse(this.world.getServer(), this);
}
return this.bukkitEntity;
}
@Override
public boolean isDeadNMS() {
return this.dead;
}
@Override
public String getCustomNameNMS() {
return super.getCustomName();
}
@Override
public void killEntityNMS() {
die();
}
@Override
public void setLocationNMS(double x, double y, double z) {
super.setPosition(x, y, z);
}
@Override
public HologramBase getParentHologram() {
return parent;
}
@Override
public void setParentHologram(HologramBase base) {
this.parent = base;
}
}

View File

@ -1,159 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_7_R2;
import org.bukkit.craftbukkit.v1_7_R2.entity.CraftEntity;
import com.gmail.filoghost.holograms.nms.interfaces.BasicEntityNMS;
import com.gmail.filoghost.holograms.nms.interfaces.HologramWitherSkull;
import com.gmail.filoghost.holograms.object.HologramBase;
import com.gmail.filoghost.holograms.utils.GenericUtils;
import net.minecraft.server.v1_7_R2.Entity;
import net.minecraft.server.v1_7_R2.EntityWitherSkull;
import net.minecraft.server.v1_7_R2.NBTTagCompound;
import net.minecraft.server.v1_7_R2.World;
import net.minecraft.server.v1_7_R2.EntityPlayer;
import net.minecraft.server.v1_7_R2.PacketPlayOutEntityTeleport;
public class EntityHologramWitherSkull extends EntityWitherSkull implements HologramWitherSkull {
private boolean lockTick;
private HologramBase parent;
public EntityHologramWitherSkull(World world) {
super(world);
super.motX = 0.0;
super.motY = 0.0;
super.motZ = 0.0;
super.dirX = 0.0;
super.dirY = 0.0;
super.dirZ = 0.0;
super.boundingBox.a = 0.0;
super.boundingBox.b = 0.0;
super.boundingBox.c = 0.0;
super.boundingBox.d = 0.0;
super.boundingBox.e = 0.0;
super.boundingBox.f = 0.0;
a(0.0F, 0.0F);
}
@Override
public void b(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean c(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public boolean d(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public void e(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean isInvulnerable() {
/*
* The field Entity.invulnerable is private.
* It's only used while saving NBTTags, but since the entity would be killed
* on chunk unload, we prefer to override isInvulnerable().
*/
return true;
}
@Override
public void h() {
if (!lockTick) {
super.h();
}
}
@Override
public void makeSound(String sound, float f1, float f2) {
// Remove sounds.
}
@Override
public void setLockTick(boolean lock) {
lockTick = lock;
}
@Override
public void die() {
setLockTick(false);
super.die();
}
@Override
public CraftEntity getBukkitEntity() {
if (super.bukkitEntity == null) {
this.bukkitEntity = new CraftHologramWitherSkull(this.world.getServer(), this);
}
return this.bukkitEntity;
}
@Override
public void killEntityNMS() {
die();
}
@Override
public void setLocationNMS(double x, double y, double z) {
super.setPosition(x, y, z);
}
@Override
public void sendUpdatePacketNear() {
// Send a packet to update the position.
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this);
for (Object obj : this.world.players) {
if (obj instanceof EntityPlayer) {
EntityPlayer nmsPlayer = (EntityPlayer) obj;
double distanceSquared = GenericUtils.square(nmsPlayer.locX - this.locX) + GenericUtils.square(nmsPlayer.locZ - this.locZ);
if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
nmsPlayer.playerConnection.sendPacket(teleportPacket);
}
}
}
}
@Override
public boolean isDeadNMS() {
return this.dead;
}
@Override
public void setPassengerNMS(BasicEntityNMS passenger) {
if (passenger instanceof Entity) {
((Entity) passenger).setPassengerOf(this);
}
}
@Override
public void setPassengerNMS(org.bukkit.entity.Entity bukkitEntity) {
((CraftEntity) bukkitEntity).getHandle().setPassengerOf(this);
}
@Override
public HologramBase getParentHologram() {
return parent;
}
@Override
public void setParentHologram(HologramBase base) {
this.parent = base;
}
}

View File

@ -1,137 +0,0 @@
package com.gmail.filoghost.holograms.nms.v1_7_R2;
import org.bukkit.craftbukkit.v1_7_R2.entity.CraftEntity;
import com.gmail.filoghost.holograms.nms.interfaces.TouchSlime;
import com.gmail.filoghost.holograms.object.HologramBase;
import net.minecraft.server.v1_7_R2.EntitySlime;
import net.minecraft.server.v1_7_R2.NBTTagCompound;
import net.minecraft.server.v1_7_R2.World;
public class EntityTouchSlime extends EntitySlime implements TouchSlime {
private boolean lockTick;
private HologramBase parent;
public EntityTouchSlime(World world) {
super(world);
super.persistent = true;
super.boundingBox.a = 0.0;
super.boundingBox.b = 0.0;
super.boundingBox.c = 0.0;
super.boundingBox.d = 0.0;
super.boundingBox.e = 0.0;
super.boundingBox.f = 0.0;
a(0.0F, 0.0F);
setSize(1);
setInvisible(true);
}
@Override
public void h() {
// Checks every 20 ticks.
if (ticksLived % 20 == 0) {
// The slime dies without a vehicle.
if (this.vehicle == null) {
die();
}
}
if (!lockTick) {
super.h();
}
}
@Override
public void b(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean c(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public boolean d(NBTTagCompound nbttagcompound) {
// Do not save NBT.
return false;
}
@Override
public void e(NBTTagCompound nbttagcompound) {
// Do not save NBT.
}
@Override
public boolean isInvulnerable() {
/*
* The field Entity.invulnerable is private.
* It's only used while saving NBTTags, but since the entity would be killed
* on chunk unload, we prefer to override isInvulnerable().
*/
return true;
}
@Override
public void setCustomName(String customName) {
// Locks the custom name.
}
@Override
public void setCustomNameVisible(boolean visible) {
// Locks the custom name.
}
@Override
public void makeSound(String sound, float volume, float pitch) {
// Remove sounds.
}
@Override
public void setLockTick(boolean lock) {
lockTick = lock;
}
@Override
public void die() {
setLockTick(false);
super.die();
}
@Override
public CraftEntity getBukkitEntity() {
if (super.bukkitEntity == null) {
this.bukkitEntity = new CraftTouchSlime(this.world.getServer(), this);
}
return this.bukkitEntity;
}
@Override
public boolean isDeadNMS() {
return super.dead;
}
@Override
public void killEntityNMS() {
die();
}
@Override
public void setLocationNMS(double x, double y, double z) {
super.setPosition(x, y, z);
}
@Override
public HologramBase getParentHologram() {
return parent;
}
@Override
public void setParentHologram(HologramBase base) {
this.parent = base;
}
}

Some files were not shown because too many files have changed in this diff Show More