mirror of
https://github.com/filoghost/HolographicDisplays.git
synced 2024-11-28 05:15:11 +01:00
Add new plugin classes
This commit is contained in:
parent
19b2839174
commit
686a69385a
@ -0,0 +1,260 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.SimpleUpdater.ResponseHandler;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.bridge.bungeecord.BungeeServerTracker;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.ProtocolLibHook;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.HologramsCommandHandler;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.disk.Configuration;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.disk.HologramDatabase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.disk.UnicodeSymbols;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.HologramNotFoundException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.InvalidFormatException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.WorldNotFoundException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.listener.MainListener;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.metrics.MetricsLite;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.NMSManager;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.placeholder.AnimationsRegister;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.placeholder.PlaceholdersManager;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.task.BungeeCleanupTask;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.task.WorldPlayerCounterTask;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.VersionUtils;
|
||||||
|
|
||||||
|
public class HolographicDisplays extends JavaPlugin {
|
||||||
|
|
||||||
|
// The main instance of the plugin.
|
||||||
|
private static HolographicDisplays instance;
|
||||||
|
|
||||||
|
// The manager for net.minecraft.server access.
|
||||||
|
private static NMSManager nmsManager;
|
||||||
|
|
||||||
|
// Since 1.8 we use armor stands instead of wither skulls.
|
||||||
|
private static boolean is1_8;
|
||||||
|
|
||||||
|
// True if ProtocolLib is installed and successfully loaded.
|
||||||
|
private static boolean useProtocolLib;
|
||||||
|
|
||||||
|
// The new version found by the updater, null if there is no new version.
|
||||||
|
private static String newVersion;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
|
||||||
|
// Blocks plugin reloaders and the /reload command.
|
||||||
|
if (instance != null) {
|
||||||
|
getLogger().warning("Please do not use /reload or plugin reloaders. Do \"/holograms reload\" instead.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance = this;
|
||||||
|
|
||||||
|
// Load placeholders.yml.
|
||||||
|
UnicodeSymbols.load(this);
|
||||||
|
|
||||||
|
// Load the configuration.
|
||||||
|
Configuration.load(this);
|
||||||
|
|
||||||
|
if (Configuration.updateNotification) {
|
||||||
|
new SimpleUpdater(this, 75097).checkForUpdates(new ResponseHandler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpdateFound(final String newVersion) {
|
||||||
|
|
||||||
|
HolographicDisplays.newVersion = newVersion;
|
||||||
|
getLogger().info("Found a new version available: " + newVersion);
|
||||||
|
getLogger().info("Download it on Bukkit Dev:");
|
||||||
|
getLogger().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 the plugin to disable itself.
|
||||||
|
version = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// It's simple, we don't need reflection.
|
||||||
|
if ("v1_6_R3".equals(version)) {
|
||||||
|
nmsManager = new com.gmail.filoghost.holographicdisplays.nms.v1_6_R3.NmsManagerImpl();
|
||||||
|
} else if ("v1_7_R1".equals(version)) {
|
||||||
|
nmsManager = new com.gmail.filoghost.holographicdisplays.nms.v1_7_R1.NmsManagerImpl();
|
||||||
|
} else if ("v1_7_R2".equals(version)) {
|
||||||
|
nmsManager = new com.gmail.filoghost.holographicdisplays.nms.v1_7_R2.NmsManagerImpl();
|
||||||
|
} else if ("v1_7_R3".equals(version)) {
|
||||||
|
nmsManager = new com.gmail.filoghost.holographicdisplays.nms.v1_7_R3.NmsManagerImpl();
|
||||||
|
} else if ("v1_7_R4".equals(version)) {
|
||||||
|
nmsManager = new com.gmail.filoghost.holographicdisplays.nms.v1_7_R4.NmsManagerImpl();
|
||||||
|
} else if ("v1_8_R1".equals(version)) {
|
||||||
|
is1_8 = true;
|
||||||
|
nmsManager = new com.gmail.filoghost.holographicdisplays.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")) {
|
||||||
|
useProtocolLib = ProtocolLibHook.load(nmsManager, this, is1_8);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
getLogger().warning("Failed to load ProtocolLib support. Is it updated?");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load animation files and the placeholder manager.
|
||||||
|
PlaceholdersManager.load(this);
|
||||||
|
try {
|
||||||
|
AnimationsRegister.loadAnimations(this);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
getLogger().warning("Failed to load animation files!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initalize other static classes.
|
||||||
|
HologramDatabase.loadYamlFile(this);
|
||||||
|
BungeeServerTracker.startTask(Configuration.bungeeRefreshSeconds);
|
||||||
|
|
||||||
|
// Start repeating tasks.
|
||||||
|
Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new BungeeCleanupTask(), 5 * 60 * 20, 5 * 60 * 20);
|
||||||
|
Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new WorldPlayerCounterTask(), 0L, 3 * 20);
|
||||||
|
|
||||||
|
Set<String> savedHologramsNames = HologramDatabase.getHolograms();
|
||||||
|
if (savedHologramsNames != null && savedHologramsNames.size() > 0) {
|
||||||
|
for (String singleHologramName : savedHologramsNames) {
|
||||||
|
try {
|
||||||
|
NamedHologram singleHologram = HologramDatabase.loadHologram(singleHologramName);
|
||||||
|
NamedHologramManager.addHologram(singleHologram);
|
||||||
|
} catch (HologramNotFoundException e) {
|
||||||
|
getLogger().warning("Hologram '" + singleHologramName + "' not found, skipping it.");
|
||||||
|
} catch (InvalidFormatException e) {
|
||||||
|
getLogger().warning("Hologram '" + singleHologramName + "' has an invalid location format.");
|
||||||
|
} catch (WorldNotFoundException e) {
|
||||||
|
getLogger().warning("Hologram '" + singleHologramName + "' was in the world '" + e.getMessage() + "' but it wasn't loaded.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
getLogger().warning("Unhandled exception while loading the hologram '" + singleHologramName + "'. Please contact the developer.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getCommand("holograms").setExecutor(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() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
for (NamedHologram hologram : NamedHologramManager.getHolograms()) {
|
||||||
|
hologram.refreshAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.runTaskLater(this, 10L);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
for (NamedHologram hologram : NamedHologramManager.getHolograms()) {
|
||||||
|
hologram.despawnEntities();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NMSManager getNMSManager() {
|
||||||
|
return nmsManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean is1_8() {
|
||||||
|
return is1_8;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 static String getNewVersion() {
|
||||||
|
return newVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean useProtocolLib() {
|
||||||
|
return useProtocolLib;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,173 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays;
|
||||||
|
|
||||||
|
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, without download features.
|
||||||
|
* @autor filoghost
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
* @param responseHandler the response handler
|
||||||
|
*/
|
||||||
|
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() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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
|
||||||
|
* @param remoteVersion the remote version of the plugin
|
||||||
|
* @return true if the remove version is newer
|
||||||
|
*/
|
||||||
|
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 until diff = 0.
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.bridge.bungeecord;
|
||||||
|
|
||||||
|
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.Plugin;
|
||||||
|
import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.HolographicDisplays;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.disk.Configuration;
|
||||||
|
|
||||||
|
public class BungeeChannel implements PluginMessageListener {
|
||||||
|
|
||||||
|
private static BungeeChannel instance;
|
||||||
|
|
||||||
|
public static BungeeChannel getInstance() {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new BungeeChannel(HolographicDisplays.getInstance());
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BungeeChannel(Plugin plugin) {
|
||||||
|
Bukkit.getMessenger().registerOutgoingPluginChannel(plugin, "BungeeCord");
|
||||||
|
Bukkit.getMessenger().registerIncomingPluginChannel(plugin, "BungeeCord", instance);
|
||||||
|
Bukkit.getMessenger().registerOutgoingPluginChannel(plugin, "RedisBungee");
|
||||||
|
Bukkit.getMessenger().registerIncomingPluginChannel(plugin, "RedisBungee", 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();
|
||||||
|
BungeeServerTracker.handlePing(server, online);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} 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.useRedisBungee ? "RedisBungee" : "BungeeCord", b.toByteArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.bridge.bungeecord;
|
||||||
|
|
||||||
|
public class BungeeServerInfo {
|
||||||
|
|
||||||
|
private int onlinePlayers;
|
||||||
|
private long lastRequest;
|
||||||
|
|
||||||
|
protected BungeeServerInfo(int onlinePlayers, long lastRequest) {
|
||||||
|
this.onlinePlayers = onlinePlayers;
|
||||||
|
this.lastRequest = lastRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOnlinePlayers() {
|
||||||
|
return onlinePlayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnlinePlayers(int onlinePlayers) {
|
||||||
|
this.onlinePlayers = onlinePlayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastRequest() {
|
||||||
|
return lastRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastRequest(long lastRequest) {
|
||||||
|
this.lastRequest = lastRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.bridge.bungeecord;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.HolographicDisplays;
|
||||||
|
|
||||||
|
public class BungeeServerTracker {
|
||||||
|
|
||||||
|
private static Map<String, BungeeServerInfo> trackedServers = new HashMap<String, BungeeServerInfo>();
|
||||||
|
private static int taskID = -1;
|
||||||
|
|
||||||
|
public static void resetTrackedServers() {
|
||||||
|
trackedServers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void track(String server) {
|
||||||
|
if (!trackedServers.containsKey(server)) {
|
||||||
|
BungeeServerInfo info = new BungeeServerInfo(0, System.currentTimeMillis());
|
||||||
|
trackedServers.put(server, info);
|
||||||
|
BungeeChannel.getInstance().askPlayerCount(server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void untrack(String server) {
|
||||||
|
trackedServers.remove(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle a successful ping.
|
||||||
|
protected static void handlePing(String server, int online) {
|
||||||
|
BungeeServerInfo info = trackedServers.get(server);
|
||||||
|
if (info == null) {
|
||||||
|
info = new BungeeServerInfo(online, System.currentTimeMillis());
|
||||||
|
trackedServers.put(server, info);
|
||||||
|
} else {
|
||||||
|
info.setOnlinePlayers(online);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getPlayersOnline(String server) {
|
||||||
|
BungeeServerInfo 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 Map<String, BungeeServerInfo> getTrackedServers() {
|
||||||
|
return trackedServers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void startTask(int refreshSeconds) {
|
||||||
|
|
||||||
|
if (taskID != -1) {
|
||||||
|
Bukkit.getScheduler().cancelTask(taskID);
|
||||||
|
}
|
||||||
|
|
||||||
|
taskID = Bukkit.getScheduler().scheduleSyncRepeatingTask(HolographicDisplays.getInstance(), new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
for (String server : trackedServers.keySet()) {
|
||||||
|
BungeeChannel.getInstance().askPlayerCount(server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 0, refreshSeconds * 20);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* PacketWrapper - Contains wrappers for each packet in Minecraft.
|
||||||
|
* Copyright (C) 2012 Kristian S. Stangeland
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program;
|
||||||
|
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
* 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.gmail.filoghost.holographicdisplays.bridge.protocollib;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.ProtocolLibrary;
|
||||||
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
|
||||||
|
public abstract class AbstractPacket {
|
||||||
|
// The packet we will be modifying
|
||||||
|
protected PacketContainer handle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new strongly typed wrapper for the given packet.
|
||||||
|
* @param handle - handle to the raw packet data.
|
||||||
|
* @param type - the packet type.
|
||||||
|
*/
|
||||||
|
protected AbstractPacket(PacketContainer handle, PacketType type) {
|
||||||
|
// Make sure we're given a valid packet
|
||||||
|
if (handle == null)
|
||||||
|
throw new IllegalArgumentException("Packet handle cannot be NULL.");
|
||||||
|
if (!Objects.equal(handle.getType(), type))
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
handle.getHandle() + " is not a packet of type " + type);
|
||||||
|
|
||||||
|
this.handle = handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a handle to the raw packet data.
|
||||||
|
* @return Raw packet data.
|
||||||
|
*/
|
||||||
|
public PacketContainer getHandle() {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send the current packet to the given receiver.
|
||||||
|
* @param receiver - the receiver.
|
||||||
|
* @throws RuntimeException If the packet cannot be sent.
|
||||||
|
*/
|
||||||
|
public void sendPacket(Player receiver) {
|
||||||
|
try {
|
||||||
|
ProtocolLibrary.getProtocolManager().sendServerPacket(receiver, getHandle());
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
throw new RuntimeException("Cannot send packet.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simulate receiving the current packet from the given sender.
|
||||||
|
* @param sender - the sender.
|
||||||
|
* @throws RuntimeException If the packet cannot be received.
|
||||||
|
*/
|
||||||
|
public void recievePacket(Player sender) {
|
||||||
|
try {
|
||||||
|
ProtocolLibrary.getProtocolManager().recieveClientPacket(sender, getHandle());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Cannot recieve packet.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,305 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.bridge.protocollib;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.ProtocolLibrary;
|
||||||
|
import com.comphenix.protocol.events.ListenerPriority;
|
||||||
|
import com.comphenix.protocol.events.PacketAdapter;
|
||||||
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
|
import com.comphenix.protocol.events.PacketEvent;
|
||||||
|
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
||||||
|
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.HolographicDisplays;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.WrapperPlayServerSpawnEntity.ObjectTypes;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.NMSManager;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.CraftHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftTextLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchableLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.Utils;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.VersionUtils;
|
||||||
|
|
||||||
|
public class ProtocolLibHook {
|
||||||
|
|
||||||
|
private static boolean hasProtocolLib;
|
||||||
|
private static NMSManager nmsManager;
|
||||||
|
|
||||||
|
private static int customNameWatcherIndex;
|
||||||
|
|
||||||
|
public static boolean load(NMSManager nmsManager, Plugin plugin, boolean is1_8) {
|
||||||
|
ProtocolLibHook.nmsManager = nmsManager;
|
||||||
|
|
||||||
|
if (Bukkit.getPluginManager().isPluginEnabled("ProtocolLib")) {
|
||||||
|
|
||||||
|
hasProtocolLib = true;
|
||||||
|
|
||||||
|
plugin.getLogger().info("Found ProtocolLib, adding support for player relative variables.");
|
||||||
|
if (is1_8) {
|
||||||
|
customNameWatcherIndex = 2;
|
||||||
|
} else {
|
||||||
|
customNameWatcherIndex = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.SPAWN_ENTITY_LIVING, PacketType.Play.Server.SPAWN_ENTITY, PacketType.Play.Server.ENTITY_METADATA) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPacketSending(PacketEvent event) {
|
||||||
|
|
||||||
|
PacketContainer packet = event.getPacket();
|
||||||
|
|
||||||
|
// Spawn entity packet
|
||||||
|
if (packet.getType() == PacketType.Play.Server.SPAWN_ENTITY_LIVING) {
|
||||||
|
|
||||||
|
WrapperPlayServerSpawnEntityLiving spawnEntityPacket = new WrapperPlayServerSpawnEntityLiving(packet);
|
||||||
|
Entity entity = spawnEntityPacket.getEntity(event);
|
||||||
|
|
||||||
|
if (entity == null || !isHologramType(entity.getType())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CraftHologram hologram = getHologram(entity);
|
||||||
|
if (hologram == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
if (!hologram.getVisibilityManager().isVisibleTo(player)) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WrappedDataWatcher dataWatcher = spawnEntityPacket.getMetadata();
|
||||||
|
String customName = dataWatcher.getString(customNameWatcherIndex);
|
||||||
|
|
||||||
|
if (customName.contains("{player}") || customName.contains("{displayname}")) {
|
||||||
|
|
||||||
|
WrappedDataWatcher dataWatcherClone = dataWatcher.deepClone();
|
||||||
|
dataWatcherClone.setObject(customNameWatcherIndex, customName.replace("{player}", player.getName()).replace("{displayname}", player.getDisplayName()));
|
||||||
|
spawnEntityPacket.setMetadata(dataWatcherClone);
|
||||||
|
event.setPacket(spawnEntityPacket.getHandle());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (packet.getType() == PacketType.Play.Server.SPAWN_ENTITY) {
|
||||||
|
|
||||||
|
WrapperPlayServerSpawnEntity spawnEntityPacket = new WrapperPlayServerSpawnEntity(packet);
|
||||||
|
int objectId = spawnEntityPacket.getType();
|
||||||
|
if (objectId != ObjectTypes.ITEM_STACK && objectId != ObjectTypes.WITHER_SKULL && objectId != ObjectTypes.ARMOR_STAND) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity entity = spawnEntityPacket.getEntity(event);
|
||||||
|
if (entity == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CraftHologram hologram = getHologram(entity);
|
||||||
|
if (hologram == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
if (!hologram.getVisibilityManager().isVisibleTo(player)) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (packet.getType() == PacketType.Play.Server.ENTITY_METADATA) {
|
||||||
|
|
||||||
|
WrapperPlayServerEntityMetadata entityMetadataPacket = new WrapperPlayServerEntityMetadata(packet);
|
||||||
|
Entity entity = entityMetadataPacket.getEntity(event);
|
||||||
|
|
||||||
|
if (entity == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity.getType() != EntityType.HORSE && !VersionUtils.isArmorstand(entity.getType())) {
|
||||||
|
// Enough, only horses and armorstands are used with custom names.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CraftHologram hologram = getHologram(entity);
|
||||||
|
if (hologram == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
if (!hologram.getVisibilityManager().isVisibleTo(player)) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<WrappedWatchableObject> dataWatcherValues = entityMetadataPacket.getEntityMetadata();
|
||||||
|
|
||||||
|
for (int i = 0; i < dataWatcherValues.size(); i++) {
|
||||||
|
|
||||||
|
if (dataWatcherValues.get(i).getIndex() == customNameWatcherIndex) {
|
||||||
|
|
||||||
|
Object customNameObject = dataWatcherValues.get(i).deepClone().getValue();
|
||||||
|
if (customNameObject instanceof String == false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String customName = (String) customNameObject;
|
||||||
|
|
||||||
|
if (customName.contains("{player}") || customName.contains("{displayname}")) {
|
||||||
|
|
||||||
|
entityMetadataPacket = new WrapperPlayServerEntityMetadata(packet.deepClone());
|
||||||
|
List<WrappedWatchableObject> clonedList = entityMetadataPacket.getEntityMetadata();
|
||||||
|
WrappedWatchableObject clonedElement = clonedList.get(i);
|
||||||
|
clonedElement.setValue(customName.replace("{player}", player.getName()).replace("{displayname}", player.getDisplayName()));
|
||||||
|
entityMetadataPacket.setEntityMetadata(clonedList);
|
||||||
|
event.setPacket(entityMetadataPacket.getHandle());
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendDestroyEntitiesPacket(Player player, CraftHologram hologram) {
|
||||||
|
if (!hasProtocolLib) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Integer> ids = Utils.newList();
|
||||||
|
for (CraftHologramLine line : hologram.getLinesUnsafe()) {
|
||||||
|
if (line.isSpawned()) {
|
||||||
|
for (int id : line.getEntitiesIDs()) {
|
||||||
|
ids.add(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ids.isEmpty()) {
|
||||||
|
WrapperPlayServerEntityDestroy packet = new WrapperPlayServerEntityDestroy();
|
||||||
|
packet.setEntities(ids);
|
||||||
|
packet.sendPacket(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendCreateEntitiesPacket(Player player, CraftHologram hologram) {
|
||||||
|
if (!hasProtocolLib) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (CraftHologramLine line : hologram.getLinesUnsafe()) {
|
||||||
|
if (line.isSpawned()) {
|
||||||
|
|
||||||
|
if (line instanceof CraftTextLine) {
|
||||||
|
CraftTextLine textLine = (CraftTextLine) line;
|
||||||
|
|
||||||
|
if (textLine.isSpawned()) {
|
||||||
|
|
||||||
|
AbstractPacket nameablePacket = new WrapperPlayServerSpawnEntityLiving(textLine.getNmsNameble().getBukkitEntityNMS());
|
||||||
|
nameablePacket.sendPacket(player);
|
||||||
|
|
||||||
|
if (textLine.getNmsSkullVehicle() != null) {
|
||||||
|
AbstractPacket vehiclePacket = new WrapperPlayServerSpawnEntity(textLine.getNmsSkullVehicle().getBukkitEntityNMS(), ObjectTypes.WITHER_SKULL, 0);
|
||||||
|
vehiclePacket.sendPacket(player);
|
||||||
|
|
||||||
|
WrapperPlayServerAttachEntity attachPacket = new WrapperPlayServerAttachEntity();
|
||||||
|
attachPacket.setVehicleId(textLine.getNmsSkullVehicle().getIdNMS());
|
||||||
|
attachPacket.setEntityId(textLine.getNmsNameble().getIdNMS());
|
||||||
|
attachPacket.sendPacket(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (line instanceof CraftItemLine) {
|
||||||
|
CraftItemLine itemLine = (CraftItemLine) line;
|
||||||
|
|
||||||
|
if (itemLine.isSpawned()) {
|
||||||
|
AbstractPacket itemPacket = new WrapperPlayServerSpawnEntity(itemLine.getNmsItem().getBukkitEntityNMS(), ObjectTypes.ITEM_STACK, 1);
|
||||||
|
itemPacket.sendPacket(player);
|
||||||
|
|
||||||
|
AbstractPacket vehiclePacket;
|
||||||
|
if (HolographicDisplays.is1_8()) {
|
||||||
|
// In 1.8 we have armor stands, that are living entities.
|
||||||
|
vehiclePacket = new WrapperPlayServerSpawnEntityLiving(itemLine.getNmsVehicle().getBukkitEntityNMS());
|
||||||
|
} else {
|
||||||
|
vehiclePacket = new WrapperPlayServerSpawnEntity(itemLine.getNmsVehicle().getBukkitEntityNMS(), ObjectTypes.WITHER_SKULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vehiclePacket.sendPacket(player);
|
||||||
|
|
||||||
|
WrapperPlayServerAttachEntity attachPacket = new WrapperPlayServerAttachEntity();
|
||||||
|
attachPacket.setVehicleId(itemLine.getNmsVehicle().getIdNMS());
|
||||||
|
attachPacket.setEntityId(itemLine.getNmsItem().getIdNMS());
|
||||||
|
attachPacket.sendPacket(player);
|
||||||
|
|
||||||
|
WrapperPlayServerEntityMetadata itemDataPacket = new WrapperPlayServerEntityMetadata();
|
||||||
|
|
||||||
|
List<WrappedWatchableObject> metadata = Utils.newList();
|
||||||
|
metadata.add(new WrappedWatchableObject(10, itemLine.getItemStack()));
|
||||||
|
metadata.add(new WrappedWatchableObject(1, (short) 300));
|
||||||
|
metadata.add(new WrappedWatchableObject(0, (byte) 0));
|
||||||
|
itemDataPacket.setEntityMetadata(metadata);
|
||||||
|
itemDataPacket.setEntityId(itemLine.getNmsItem().getIdNMS());
|
||||||
|
itemDataPacket.sendPacket(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unsafe cast, however both CraftTextLine and CraftItemLine are touchable.
|
||||||
|
CraftTouchableLine touchableLine = (CraftTouchableLine) line;
|
||||||
|
|
||||||
|
if (touchableLine.isSpawned() && touchableLine.getTouchSlime() != null) {
|
||||||
|
|
||||||
|
CraftTouchSlimeLine touchSlime = touchableLine.getTouchSlime();
|
||||||
|
|
||||||
|
if (touchSlime.isSpawned()) {
|
||||||
|
AbstractPacket vehiclePacket;
|
||||||
|
|
||||||
|
if (HolographicDisplays.is1_8()) {
|
||||||
|
// Armor stand vehicle
|
||||||
|
vehiclePacket = new WrapperPlayServerSpawnEntityLiving(touchSlime.getNmsVehicle().getBukkitEntityNMS());
|
||||||
|
} else {
|
||||||
|
// Wither skull vehicle
|
||||||
|
vehiclePacket = new WrapperPlayServerSpawnEntity(touchSlime.getNmsVehicle().getBukkitEntityNMS(), ObjectTypes.WITHER_SKULL, 0);
|
||||||
|
}
|
||||||
|
vehiclePacket.sendPacket(player);
|
||||||
|
|
||||||
|
AbstractPacket slimePacket = new WrapperPlayServerSpawnEntityLiving(touchSlime.getNmsSlime().getBukkitEntityNMS());
|
||||||
|
slimePacket.sendPacket(player);
|
||||||
|
|
||||||
|
WrapperPlayServerAttachEntity attachPacket = new WrapperPlayServerAttachEntity();
|
||||||
|
attachPacket.setVehicleId(touchSlime.getNmsVehicle().getIdNMS());
|
||||||
|
attachPacket.setEntityId(touchSlime.getNmsSlime().getIdNMS());
|
||||||
|
attachPacket.sendPacket(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isHologramType(EntityType type) {
|
||||||
|
return type == EntityType.HORSE || type == EntityType.WITHER_SKULL || type == EntityType.DROPPED_ITEM || type == EntityType.SLIME || VersionUtils.isArmorstand(type); // To maintain backwards compatibility
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CraftHologram getHologram(Entity bukkitEntity) {
|
||||||
|
NMSEntityBase entity = nmsManager.getNMSEntityBase(bukkitEntity);
|
||||||
|
if (entity != null) {
|
||||||
|
return entity.getHologramLine().getParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* PacketWrapper - Contains wrappers for each packet in Minecraft.
|
||||||
|
* Copyright (C) 2012 Kristian S. Stangeland
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program;
|
||||||
|
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
* 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.gmail.filoghost.holographicdisplays.bridge.protocollib;
|
||||||
|
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
|
import com.comphenix.protocol.events.PacketEvent;
|
||||||
|
|
||||||
|
public class WrapperPlayServerAttachEntity extends AbstractPacket {
|
||||||
|
public static final PacketType TYPE = PacketType.Play.Server.ATTACH_ENTITY;
|
||||||
|
|
||||||
|
public WrapperPlayServerAttachEntity() {
|
||||||
|
super(new PacketContainer(TYPE), TYPE);
|
||||||
|
handle.getModifier().writeDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrapperPlayServerAttachEntity(PacketContainer packet) {
|
||||||
|
super(packet, TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve whether or not the entity is leached onto the vehicle.
|
||||||
|
* @return TRUE if it is, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
public boolean getLeached() {
|
||||||
|
return handle.getIntegers().read(0) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether or not the entity is leached onto the vehicle.
|
||||||
|
* @param value - TRUE if it is leached, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
public void setLeached(boolean value) {
|
||||||
|
handle.getIntegers().write(0, value ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the player entity ID being attached.
|
||||||
|
* @return The current Entity ID
|
||||||
|
*/
|
||||||
|
public int getEntityId() {
|
||||||
|
return handle.getIntegers().read(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the player entity ID being attached.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setEntityId(int value) {
|
||||||
|
handle.getIntegers().write(1, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the entity being attached.
|
||||||
|
* @param world - the current world of the entity.
|
||||||
|
* @return The entity.
|
||||||
|
*/
|
||||||
|
public Entity getEntity(World world) {
|
||||||
|
return handle.getEntityModifier(world).read(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the entity being attached.
|
||||||
|
* @param event - the packet event.
|
||||||
|
* @return The entity.
|
||||||
|
*/
|
||||||
|
public Entity getEntity(PacketEvent event) {
|
||||||
|
return getEntity(event.getPlayer().getWorld());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the vehicle entity ID attached to (-1 for unattaching).
|
||||||
|
* @return The current Vehicle ID
|
||||||
|
*/
|
||||||
|
public int getVehicleId() {
|
||||||
|
return handle.getIntegers().read(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the vehicle entity ID attached to (-1 for unattaching).
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setVehicleId(int value) {
|
||||||
|
handle.getIntegers().write(2, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the vehicle entity attached to (NULL for unattaching).
|
||||||
|
* @param world - the current world of the entity.
|
||||||
|
* @return The vehicle.
|
||||||
|
*/
|
||||||
|
public Entity getVehicle(World world) {
|
||||||
|
return handle.getEntityModifier(world).read(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the vehicle entity attached to (NULL for unattaching).
|
||||||
|
* @param event - the packet event.
|
||||||
|
* @return The vehicle.
|
||||||
|
*/
|
||||||
|
public Entity getVehicle(PacketEvent event) {
|
||||||
|
return getVehicle(event.getPlayer().getWorld());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* PacketWrapper - Contains wrappers for each packet in Minecraft.
|
||||||
|
* Copyright (C) 2012 Kristian S. Stangeland
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program;
|
||||||
|
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
* 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.gmail.filoghost.holographicdisplays.bridge.protocollib;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
|
import com.google.common.primitives.Ints;
|
||||||
|
|
||||||
|
public class WrapperPlayServerEntityDestroy extends AbstractPacket {
|
||||||
|
public static final PacketType TYPE = PacketType.Play.Server.ENTITY_DESTROY;
|
||||||
|
|
||||||
|
public WrapperPlayServerEntityDestroy() {
|
||||||
|
super(new PacketContainer(TYPE), TYPE);
|
||||||
|
handle.getModifier().writeDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrapperPlayServerEntityDestroy(PacketContainer packet) {
|
||||||
|
super(packet, TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the IDs of the entities that will be destroyed.
|
||||||
|
* @return The current entities.
|
||||||
|
*/
|
||||||
|
public List<Integer> getEntities() {
|
||||||
|
return Ints.asList(handle.getIntegerArrays().read(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the entities that will be destroyed.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setEntities(int[] entities) {
|
||||||
|
handle.getIntegerArrays().write(0, entities);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the entities that will be destroyed.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setEntities(List<Integer> entities) {
|
||||||
|
setEntities(Ints.toArray(entities));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* PacketWrapper - Contains wrappers for each packet in Minecraft.
|
||||||
|
* Copyright (C) 2012 Kristian S. Stangeland
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program;
|
||||||
|
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
* 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.gmail.filoghost.holographicdisplays.bridge.protocollib;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
|
import com.comphenix.protocol.events.PacketEvent;
|
||||||
|
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
||||||
|
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
|
||||||
|
|
||||||
|
public class WrapperPlayServerEntityMetadata extends AbstractPacket {
|
||||||
|
public static final PacketType TYPE = PacketType.Play.Server.ENTITY_METADATA;
|
||||||
|
|
||||||
|
public WrapperPlayServerEntityMetadata() {
|
||||||
|
super(new PacketContainer(TYPE), TYPE);
|
||||||
|
handle.getModifier().writeDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrapperPlayServerEntityMetadata(PacketContainer packet) {
|
||||||
|
super(packet, TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve unique entity ID to update.
|
||||||
|
* @return The current Entity ID
|
||||||
|
*/
|
||||||
|
public int getEntityId() {
|
||||||
|
return handle.getIntegers().read(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set unique entity ID to update.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setEntityId(int value) {
|
||||||
|
handle.getIntegers().write(0, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the entity.
|
||||||
|
* @param world - the current world of the entity.
|
||||||
|
* @return The entity.
|
||||||
|
*/
|
||||||
|
public Entity getEntity(World world) {
|
||||||
|
return handle.getEntityModifier(world).read(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the entity.
|
||||||
|
* @param event - the packet event.
|
||||||
|
* @return The entity.
|
||||||
|
*/
|
||||||
|
public Entity getEntity(PacketEvent event) {
|
||||||
|
return getEntity(event.getPlayer().getWorld());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a list of all the watchable objects.
|
||||||
|
* <p>
|
||||||
|
* This can be converted to a data watcher using {@link WrappedDataWatcher#WrappedDataWatcher(List) WrappedDataWatcher(List)}
|
||||||
|
* @return The current metadata
|
||||||
|
*/
|
||||||
|
public List<WrappedWatchableObject> getEntityMetadata() {
|
||||||
|
return handle.getWatchableCollectionModifier().read(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the list of the watchable objects (meta data).
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setEntityMetadata(List<WrappedWatchableObject> value) {
|
||||||
|
handle.getWatchableCollectionModifier().write(0, value);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,334 @@
|
|||||||
|
/*
|
||||||
|
* PacketWrapper - Contains wrappers for each packet in Minecraft.
|
||||||
|
* Copyright (C) 2012 Kristian S. Stangeland
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program;
|
||||||
|
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
* 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.gmail.filoghost.holographicdisplays.bridge.protocollib;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.ProtocolLibrary;
|
||||||
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
|
import com.comphenix.protocol.events.PacketEvent;
|
||||||
|
import com.comphenix.protocol.injector.PacketConstructor;
|
||||||
|
import com.comphenix.protocol.reflect.IntEnum;
|
||||||
|
|
||||||
|
public class WrapperPlayServerSpawnEntity extends AbstractPacket {
|
||||||
|
public static final PacketType TYPE = PacketType.Play.Server.SPAWN_ENTITY;
|
||||||
|
|
||||||
|
private static PacketConstructor entityConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the different object types.
|
||||||
|
*
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
|
public static class ObjectTypes extends IntEnum {
|
||||||
|
public static final int BOAT = 1;
|
||||||
|
public static final int ITEM_STACK = 2;
|
||||||
|
public static final int MINECART = 10;
|
||||||
|
public static final int MINECART_STORAGE = 11;
|
||||||
|
public static final int MINECART_POWERED = 12;
|
||||||
|
public static final int ACTIVATED_TNT = 50;
|
||||||
|
public static final int ENDER_CRYSTAL = 51;
|
||||||
|
public static final int ARROW_PROJECTILE = 60;
|
||||||
|
public static final int SNOWBALL_PROJECTILE = 61;
|
||||||
|
public static final int EGG_PROJECTILE = 62;
|
||||||
|
public static final int FIRE_BALL_GHAST = 63;
|
||||||
|
public static final int FIRE_BALL_BLAZE = 64;
|
||||||
|
public static final int THROWN_ENDERPEARL = 65;
|
||||||
|
public static final int WITHER_SKULL = 66;
|
||||||
|
public static final int FALLING_BLOCK = 70;
|
||||||
|
public static final int ITEM_FRAME = 71;
|
||||||
|
public static final int EYE_OF_ENDER = 72;
|
||||||
|
public static final int THROWN_POTION = 73;
|
||||||
|
public static final int FALLING_DRAGON_EGG = 74;
|
||||||
|
public static final int THROWN_EXP_BOTTLE = 75;
|
||||||
|
public static final int FIREWORK = 76;
|
||||||
|
public static final int ARMOR_STAND = 78;
|
||||||
|
public static final int FISHING_FLOAT = 90;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The singleton instance. Can also be retrieved from the parent class.
|
||||||
|
*/
|
||||||
|
private static ObjectTypes INSTANCE = new ObjectTypes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve an instance of the object types enum.
|
||||||
|
* @return Object type enum.
|
||||||
|
*/
|
||||||
|
public static ObjectTypes getInstance() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrapperPlayServerSpawnEntity() {
|
||||||
|
super(new PacketContainer(TYPE), TYPE);
|
||||||
|
handle.getModifier().writeDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrapperPlayServerSpawnEntity(PacketContainer packet) {
|
||||||
|
super(packet, TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrapperPlayServerSpawnEntity(Entity entity, int type, int objectData) {
|
||||||
|
super(fromEntity(entity, type, objectData), TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Useful constructor
|
||||||
|
private static PacketContainer fromEntity(Entity entity, int type, int objectData) {
|
||||||
|
if (entityConstructor == null)
|
||||||
|
entityConstructor = ProtocolLibrary.getProtocolManager().createPacketConstructor(TYPE, entity, type, objectData);
|
||||||
|
return entityConstructor.createPacket(entity, type, objectData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve entity ID of the Object.
|
||||||
|
* @return The current EID
|
||||||
|
*/
|
||||||
|
public int getEntityID() {
|
||||||
|
return handle.getIntegers().read(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the entity that will be spawned.
|
||||||
|
* @param world - the current world of the entity.
|
||||||
|
* @return The spawned entity.
|
||||||
|
*/
|
||||||
|
public Entity getEntity(World world) {
|
||||||
|
return handle.getEntityModifier(world).read(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the entity that will be spawned.
|
||||||
|
* @param event - the packet event.
|
||||||
|
* @return The spawned entity.
|
||||||
|
*/
|
||||||
|
public Entity getEntity(PacketEvent event) {
|
||||||
|
return getEntity(event.getPlayer().getWorld());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set entity ID of the Object.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setEntityID(int value) {
|
||||||
|
handle.getIntegers().write(0, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the type of object. See {@link ObjectTypes}
|
||||||
|
* @return The current Type
|
||||||
|
*/
|
||||||
|
public int getType() {
|
||||||
|
return handle.getIntegers().read(9);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the type of object. See {@link ObjectTypes}.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setType(int value) {
|
||||||
|
handle.getIntegers().write(9, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the x position of the object.
|
||||||
|
* <p>
|
||||||
|
* Note that the coordinate is rounded off to the nearest 1/32 of a meter.
|
||||||
|
* @return The current X
|
||||||
|
*/
|
||||||
|
public double getX() {
|
||||||
|
return handle.getIntegers().read(1) / 32.0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the x position of the object.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setX(double value) {
|
||||||
|
handle.getIntegers().write(1, (int) Math.floor(value * 32.0D));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the y position of the object.
|
||||||
|
* <p>
|
||||||
|
* Note that the coordinate is rounded off to the nearest 1/32 of a meter.
|
||||||
|
* @return The current y
|
||||||
|
*/
|
||||||
|
public double getY() {
|
||||||
|
return handle.getIntegers().read(2) / 32.0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the y position of the object.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setY(double value) {
|
||||||
|
handle.getIntegers().write(2, (int) Math.floor(value * 32.0D));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the z position of the object.
|
||||||
|
* <p>
|
||||||
|
* Note that the coordinate is rounded off to the nearest 1/32 of a meter.
|
||||||
|
* @return The current z
|
||||||
|
*/
|
||||||
|
public double getZ() {
|
||||||
|
return handle.getIntegers().read(3) / 32.0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the z position of the object.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setZ(double value) {
|
||||||
|
handle.getIntegers().write(3, (int) Math.floor(value * 32.0D));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the optional speed x.
|
||||||
|
* <p>
|
||||||
|
* This is ignored if {@link #getObjectData()} is zero.
|
||||||
|
* @return The optional speed x.
|
||||||
|
*/
|
||||||
|
public double getOptionalSpeedX() {
|
||||||
|
return handle.getIntegers().read(4) / 8000.0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the optional speed x.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setOptionalSpeedX(double value) {
|
||||||
|
handle.getIntegers().write(4, (int) (value * 8000.0D));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the optional speed y.
|
||||||
|
* <p>
|
||||||
|
* This is ignored if {@link #getObjectData()} is zero.
|
||||||
|
* @return The optional speed y.
|
||||||
|
*/
|
||||||
|
public double getOptionalSpeedY() {
|
||||||
|
return handle.getIntegers().read(5) / 8000.0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the optional speed y.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setOptionalSpeedY(double value) {
|
||||||
|
handle.getIntegers().write(5, (int) (value * 8000.0D));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the optional speed z.
|
||||||
|
* <p>
|
||||||
|
* This is ignored if {@link #getObjectData()} is zero.
|
||||||
|
* @return The optional speed z.
|
||||||
|
*/
|
||||||
|
public double getOptionalSpeedZ() {
|
||||||
|
return handle.getIntegers().read(6) / 8000.0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the optional speed z.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setOptionalSpeedZ(double value) {
|
||||||
|
handle.getIntegers().write(6, (int) (value * 8000.0D));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the yaw.
|
||||||
|
* @return The current Yaw
|
||||||
|
*/
|
||||||
|
public float getYaw() {
|
||||||
|
return (handle.getIntegers().read(7) * 360.F) / 256.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the yaw of the object spawned.
|
||||||
|
* @param value - new yaw.
|
||||||
|
*/
|
||||||
|
public void setYaw(float value) {
|
||||||
|
handle.getIntegers().write(7, (int) (value * 256.0F / 360.0F));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the pitch.
|
||||||
|
* @return The current pitch.
|
||||||
|
*/
|
||||||
|
public float getPitch() {
|
||||||
|
return (handle.getIntegers().read(8) * 360.F) / 256.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the pitch.
|
||||||
|
* @param value - new pitch.
|
||||||
|
*/
|
||||||
|
public void setPitch(float value) {
|
||||||
|
handle.getIntegers().write(8, (int) (value * 256.0F / 360.0F));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve object data.
|
||||||
|
* <p>
|
||||||
|
* The content depends on the object type:
|
||||||
|
* <table border="1" cellpadding="4">
|
||||||
|
* <tr>
|
||||||
|
* <th>Object Type:</th>
|
||||||
|
* <th>Name:</th>
|
||||||
|
* <th>Description</th>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <td>ITEM_FRAME</td>
|
||||||
|
* <td>Orientation</td>
|
||||||
|
* <td>0-3: South, West, North, East</td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <td>FALLING_BLOCK</td>
|
||||||
|
* <td>Block Type</td>
|
||||||
|
* <td>BlockID | (Metadata << 0xC)</td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <td>Projectiles</td>
|
||||||
|
* <td>Entity ID</td>
|
||||||
|
* <td>The entity ID of the thrower</td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <td>Splash Potions</td>
|
||||||
|
* <td>Data Value</td>
|
||||||
|
* <td>Potion data value.</td>
|
||||||
|
* </tr>
|
||||||
|
* </table>
|
||||||
|
* @return The current object Data
|
||||||
|
*/
|
||||||
|
public int getObjectData() {
|
||||||
|
return handle.getIntegers().read(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set object Data.
|
||||||
|
* <p>
|
||||||
|
* The content depends on the object type. See {@link #getObjectData()} for more information.
|
||||||
|
* @param value - new object data.
|
||||||
|
*/
|
||||||
|
public void setObjectData(int value) {
|
||||||
|
handle.getIntegers().write(10, value);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,275 @@
|
|||||||
|
/*
|
||||||
|
* PacketWrapper - Contains wrappers for each packet in Minecraft.
|
||||||
|
* Copyright (C) 2012 Kristian S. Stangeland
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program;
|
||||||
|
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
* 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.gmail.filoghost.holographicdisplays.bridge.protocollib;
|
||||||
|
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.ProtocolLibrary;
|
||||||
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
|
import com.comphenix.protocol.events.PacketEvent;
|
||||||
|
import com.comphenix.protocol.injector.PacketConstructor;
|
||||||
|
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
||||||
|
|
||||||
|
public class WrapperPlayServerSpawnEntityLiving extends AbstractPacket {
|
||||||
|
public static final PacketType TYPE = PacketType.Play.Server.SPAWN_ENTITY_LIVING;
|
||||||
|
|
||||||
|
private static PacketConstructor entityConstructor;
|
||||||
|
|
||||||
|
public WrapperPlayServerSpawnEntityLiving() {
|
||||||
|
super(new PacketContainer(TYPE), TYPE);
|
||||||
|
handle.getModifier().writeDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrapperPlayServerSpawnEntityLiving(PacketContainer packet) {
|
||||||
|
super(packet, TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrapperPlayServerSpawnEntityLiving(Entity entity) {
|
||||||
|
super(fromEntity(entity), TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Useful constructor
|
||||||
|
private static PacketContainer fromEntity(Entity entity) {
|
||||||
|
if (entityConstructor == null)
|
||||||
|
entityConstructor = ProtocolLibrary.getProtocolManager().createPacketConstructor(TYPE, entity);
|
||||||
|
return entityConstructor.createPacket(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve entity ID.
|
||||||
|
* @return The current EID
|
||||||
|
*/
|
||||||
|
public int getEntityID() {
|
||||||
|
return handle.getIntegers().read(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the entity that will be spawned.
|
||||||
|
* @param world - the current world of the entity.
|
||||||
|
* @return The spawned entity.
|
||||||
|
*/
|
||||||
|
public Entity getEntity(World world) {
|
||||||
|
return handle.getEntityModifier(world).read(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the entity that will be spawned.
|
||||||
|
* @param event - the packet event.
|
||||||
|
* @return The spawned entity.
|
||||||
|
*/
|
||||||
|
public Entity getEntity(PacketEvent event) {
|
||||||
|
return getEntity(event.getPlayer().getWorld());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set entity ID.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setEntityID(int value) {
|
||||||
|
handle.getIntegers().write(0, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the type of mob.
|
||||||
|
* @return The current Type
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public EntityType getType() {
|
||||||
|
return EntityType.fromId(handle.getIntegers().read(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the type of mob.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public void setType(EntityType value) {
|
||||||
|
handle.getIntegers().write(1, (int) value.getTypeId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the x position of the object.
|
||||||
|
* <p>
|
||||||
|
* Note that the coordinate is rounded off to the nearest 1/32 of a meter.
|
||||||
|
* @return The current X
|
||||||
|
*/
|
||||||
|
public double getX() {
|
||||||
|
return handle.getIntegers().read(2) / 32.0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the x position of the object.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setX(double value) {
|
||||||
|
handle.getIntegers().write(2, (int) Math.floor(value * 32.0D));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the y position of the object.
|
||||||
|
* <p>
|
||||||
|
* Note that the coordinate is rounded off to the nearest 1/32 of a meter.
|
||||||
|
* @return The current y
|
||||||
|
*/
|
||||||
|
public double getY() {
|
||||||
|
return handle.getIntegers().read(3) / 32.0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the y position of the object.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setY(double value) {
|
||||||
|
handle.getIntegers().write(3, (int) Math.floor(value * 32.0D));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the z position of the object.
|
||||||
|
* <p>
|
||||||
|
* Note that the coordinate is rounded off to the nearest 1/32 of a meter.
|
||||||
|
* @return The current z
|
||||||
|
*/
|
||||||
|
public double getZ() {
|
||||||
|
return handle.getIntegers().read(4) / 32.0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the z position of the object.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setZ(double value) {
|
||||||
|
handle.getIntegers().write(4, (int) Math.floor(value * 32.0D));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the yaw.
|
||||||
|
* @return The current Yaw
|
||||||
|
*/
|
||||||
|
public float getYaw() {
|
||||||
|
return (handle.getBytes().read(0) * 360.F) / 256.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the yaw of the spawned mob.
|
||||||
|
* @param value - new yaw.
|
||||||
|
*/
|
||||||
|
public void setYaw(float value) {
|
||||||
|
handle.getBytes().write(0, (byte) (value * 256.0F / 360.0F));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the pitch.
|
||||||
|
* @return The current pitch
|
||||||
|
*/
|
||||||
|
public float getHeadPitch() {
|
||||||
|
return (handle.getBytes().read(1) * 360.F) / 256.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the pitch of the spawned mob.
|
||||||
|
* @param value - new pitch.
|
||||||
|
*/
|
||||||
|
public void setHeadPitch(float value) {
|
||||||
|
handle.getBytes().write(1, (byte) (value * 256.0F / 360.0F));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the yaw of the mob's head.
|
||||||
|
* @return The current yaw.
|
||||||
|
*/
|
||||||
|
public float getHeadYaw() {
|
||||||
|
return (handle.getBytes().read(2) * 360.F) / 256.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the yaw of the mob's head.
|
||||||
|
* @param value - new yaw.
|
||||||
|
*/
|
||||||
|
public void setHeadYaw(float value) {
|
||||||
|
handle.getBytes().write(2, (byte) (value * 256.0F / 360.0F));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the velocity in the x axis.
|
||||||
|
* @return The current velocity X
|
||||||
|
*/
|
||||||
|
public double getVelocityX() {
|
||||||
|
return handle.getIntegers().read(5) / 8000.0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the velocity in the x axis.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setVelocityX(double value) {
|
||||||
|
handle.getIntegers().write(5, (int) (value * 8000.0D));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the velocity in the y axis.
|
||||||
|
* @return The current velocity y
|
||||||
|
*/
|
||||||
|
public double getVelocityY() {
|
||||||
|
return handle.getIntegers().read(6) / 8000.0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the velocity in the y axis.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setVelocityY(double value) {
|
||||||
|
handle.getIntegers().write(6, (int) (value * 8000.0D));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the velocity in the z axis.
|
||||||
|
* @return The current velocity z
|
||||||
|
*/
|
||||||
|
public double getVelocityZ() {
|
||||||
|
return handle.getIntegers().read(7) / 8000.0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the velocity in the z axis.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setVelocityZ(double value) {
|
||||||
|
handle.getIntegers().write(7, (int) (value * 8000.0D));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the data watcher.
|
||||||
|
* <p>
|
||||||
|
* Content varies by mob, see Entities.
|
||||||
|
* @return The current Metadata
|
||||||
|
*/
|
||||||
|
public WrappedDataWatcher getMetadata() {
|
||||||
|
return handle.getDataWatcherModifier().read(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the data watcher.
|
||||||
|
* @param value - new value.
|
||||||
|
*/
|
||||||
|
public void setMetadata(WrappedDataWatcher value) {
|
||||||
|
handle.getDataWatcherModifier().write(0, value);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.commands;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
|
||||||
|
public class Colors {
|
||||||
|
|
||||||
|
public static final String
|
||||||
|
|
||||||
|
PRIMARY = "" + ChatColor.AQUA,
|
||||||
|
PRIMARY_SHADOW = "" + ChatColor.DARK_AQUA,
|
||||||
|
|
||||||
|
SECONDARY = "" + ChatColor.WHITE,
|
||||||
|
SECONDARY_SHADOW = "" + ChatColor.GRAY,
|
||||||
|
|
||||||
|
BOLD = "" + ChatColor.BOLD,
|
||||||
|
|
||||||
|
ERROR = "" + ChatColor.RED;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.commands;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.CommandException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.commands;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
public class Strings {
|
||||||
|
|
||||||
|
public static final String NO_SUCH_HOLOGRAM = ChatColor.RED + "A hologram with that name doesn't exist.";
|
||||||
|
|
||||||
|
public static final String BASE_PERM = "holograms.";
|
||||||
|
|
||||||
|
public static final String TIP_PREFIX = "" + ChatColor.YELLOW + ChatColor.BOLD + "TIP" + Colors.SECONDARY_SHADOW + " ";
|
||||||
|
|
||||||
|
|
||||||
|
public static String formatTitle(String input) {
|
||||||
|
return "" + Colors.PRIMARY_SHADOW + ChatColor.BOLD + "----- " + input + Colors.PRIMARY_SHADOW + ChatColor.BOLD + " -----";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendWarning(CommandSender recipient, String warning) {
|
||||||
|
recipient.sendMessage(ChatColor.RED + "( " + ChatColor.DARK_RED + ChatColor.BOLD + "!" + ChatColor.RED + " ) " + Colors.SECONDARY_SHADOW + warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.commands.main;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.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 label, 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,106 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.commands.main;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.HolographicDisplays;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Colors;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Strings;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.subs.AddlineCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.subs.AlignCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.subs.CreateCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.subs.DeleteCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.subs.EditCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.subs.FixCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.subs.HelpCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.subs.InsertlineCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.subs.ListCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.subs.MovehereCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.subs.NearCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.subs.ReadimageCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.subs.ReadtextCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.subs.ReloadCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.subs.RemovelineCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.subs.SetlineCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.subs.TeleportCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.CommandException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.Utils;
|
||||||
|
|
||||||
|
public class HologramsCommandHandler implements CommandExecutor {
|
||||||
|
|
||||||
|
private List<HologramSubCommand> subCommands;
|
||||||
|
|
||||||
|
public HologramsCommandHandler() {
|
||||||
|
subCommands = Utils.newList();
|
||||||
|
|
||||||
|
registerSubCommand(new AddlineCommand());
|
||||||
|
registerSubCommand(new CreateCommand());
|
||||||
|
registerSubCommand(new DeleteCommand());
|
||||||
|
registerSubCommand(new EditCommand(this));
|
||||||
|
registerSubCommand(new ListCommand());
|
||||||
|
registerSubCommand(new NearCommand());
|
||||||
|
registerSubCommand(new TeleportCommand());
|
||||||
|
registerSubCommand(new MovehereCommand());
|
||||||
|
registerSubCommand(new AlignCommand());
|
||||||
|
registerSubCommand(new FixCommand());
|
||||||
|
registerSubCommand(new ReloadCommand());
|
||||||
|
|
||||||
|
registerSubCommand(new RemovelineCommand());
|
||||||
|
registerSubCommand(new SetlineCommand());
|
||||||
|
registerSubCommand(new InsertlineCommand());
|
||||||
|
registerSubCommand(new ReadtextCommand());
|
||||||
|
registerSubCommand(new ReadimageCommand());
|
||||||
|
|
||||||
|
registerSubCommand(new HelpCommand(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
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(Colors.PRIMARY_SHADOW + "This server is running " + Colors.PRIMARY + "Holographic Displays " + Colors.PRIMARY_SHADOW + "v" + HolographicDisplays.getInstance().getDescription().getVersion() + " by " + Colors.PRIMARY + "filoghost");
|
||||||
|
if (sender.hasPermission(Strings.BASE_PERM + "help")) {
|
||||||
|
sender.sendMessage(Colors.PRIMARY_SHADOW + "Commands: " + Colors.PRIMARY + "/" + label + " help");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (HologramSubCommand subCommand : subCommands) {
|
||||||
|
if (subCommand.isValidTrigger(args[0])) {
|
||||||
|
|
||||||
|
if (!subCommand.hasPermission(sender)) {
|
||||||
|
sender.sendMessage(Colors.ERROR + "You don't have permission.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.length - 1 >= subCommand.getMinimumArguments()) {
|
||||||
|
try {
|
||||||
|
subCommand.execute(sender, label, Arrays.copyOfRange(args, 1, args.length));
|
||||||
|
} catch (CommandException e) {
|
||||||
|
sender.sendMessage(Colors.ERROR + e.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(Colors.ERROR + "Usage: /" + label + " " + subCommand.getName() + " " + subCommand.getPossibleArguments());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.sendMessage(Colors.ERROR + "Unknown sub-command. Type \"/" + label + " help\" for a list of commands.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.commands.main.subs;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Colors;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.CommandValidator;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Strings;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.HologramSubCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.disk.HologramDatabase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.CommandException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.Utils;
|
||||||
|
|
||||||
|
public class AddlineCommand extends HologramSubCommand {
|
||||||
|
|
||||||
|
public AddlineCommand() {
|
||||||
|
super("addline");
|
||||||
|
setPermission(Strings.BASE_PERM + "addline");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPossibleArguments() {
|
||||||
|
return "<hologramName> <text>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumArguments() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String label, String[] args) throws CommandException {
|
||||||
|
NamedHologram hologram = NamedHologramManager.getHologram(args[0].toLowerCase());
|
||||||
|
CommandValidator.notNull(hologram, Strings.NO_SUCH_HOLOGRAM);
|
||||||
|
|
||||||
|
hologram.getLinesUnsafe().add(HologramDatabase.readLineFromString(Utils.join(args, " ", 1, args.length), hologram));
|
||||||
|
hologram.refreshAll();
|
||||||
|
|
||||||
|
HologramDatabase.saveHologram(hologram);
|
||||||
|
HologramDatabase.trySaveToDisk();
|
||||||
|
sender.sendMessage(Colors.PRIMARY + "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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.commands.main.subs;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Colors;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.CommandValidator;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Strings;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.HologramSubCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.disk.HologramDatabase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.CommandException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager;
|
||||||
|
|
||||||
|
public class AlignCommand extends HologramSubCommand {
|
||||||
|
|
||||||
|
public AlignCommand() {
|
||||||
|
super("align");
|
||||||
|
setPermission(Strings.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 label, String[] args) throws CommandException {
|
||||||
|
NamedHologram hologram = NamedHologramManager.getHologram(args[1].toLowerCase());
|
||||||
|
NamedHologram referenceHologram = NamedHologramManager.getHologram(args[2].toLowerCase());
|
||||||
|
|
||||||
|
CommandValidator.notNull(hologram, Strings.NO_SUCH_HOLOGRAM + " (hologram to align)");
|
||||||
|
CommandValidator.notNull(referenceHologram, Strings.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.teleport(loc.getWorld(), loc.getX(), loc.getY(), loc.getZ());
|
||||||
|
hologram.despawnEntities();
|
||||||
|
hologram.refreshAll();
|
||||||
|
|
||||||
|
HologramDatabase.saveHologram(hologram);
|
||||||
|
HologramDatabase.trySaveToDisk();
|
||||||
|
sender.sendMessage(Colors.PRIMARY + "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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,113 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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.holographicdisplays.commands.Colors;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.CommandValidator;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Strings;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.HologramSubCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.disk.HologramDatabase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.CommandException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.InvalidCharactersException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.Utils;
|
||||||
|
|
||||||
|
public class CreateCommand extends HologramSubCommand {
|
||||||
|
|
||||||
|
private static final String VALID_HOLOGRAM_NAME_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
|
||||||
|
|
||||||
|
|
||||||
|
public CreateCommand() {
|
||||||
|
super("create");
|
||||||
|
setPermission(Strings.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 label, String[] args) throws CommandException {
|
||||||
|
Player player = CommandValidator.getPlayerSender(sender);
|
||||||
|
String name = args[0];
|
||||||
|
|
||||||
|
if (!name.matches("[a-zA-Z_\\-]+")) {
|
||||||
|
throw new CommandException("The name must contain only alphanumeric chars, underscores and hyphens.");
|
||||||
|
}
|
||||||
|
|
||||||
|
name = name.toLowerCase();
|
||||||
|
|
||||||
|
CommandValidator.isTrue(!NamedHologramManager.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
NamedHologram hologram = new NamedHologram(spawnLoc, name);
|
||||||
|
NamedHologramManager.addHologram(hologram);
|
||||||
|
|
||||||
|
if (args.length > 1) {
|
||||||
|
|
||||||
|
String text = Utils.join(args, " ", 1, args.length);
|
||||||
|
CommandValidator.isTrue(!text.equalsIgnoreCase("{empty}"), "The first line should not be empty.");
|
||||||
|
|
||||||
|
hologram.getLinesUnsafe().add(HologramDatabase.readLineFromString(text, hologram));
|
||||||
|
player.sendMessage(Colors.SECONDARY_SHADOW + "(Change the lines with /" + label + " edit " + hologram.getName() + ")");
|
||||||
|
} else {
|
||||||
|
hologram.appendTextLine("Default hologram. Change it with " + Colors.PRIMARY + "/" + label + " edit " + hologram.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
hologram.refreshAll();
|
||||||
|
|
||||||
|
HologramDatabase.saveHologram(hologram);
|
||||||
|
HologramDatabase.trySaveToDisk();
|
||||||
|
Location look = player.getLocation();
|
||||||
|
look.setPitch(90);
|
||||||
|
player.teleport(look, TeleportCause.PLUGIN);
|
||||||
|
player.sendMessage(Colors.PRIMARY + "You created a hologram named '" + hologram.getName() + "'.");
|
||||||
|
|
||||||
|
if (moveUp) {
|
||||||
|
player.sendMessage(Colors.SECONDARY_SHADOW + "(You were on the ground, the hologram was automatically moved up. If you use /" + label + " movehere " + hologram.getName() + ", the hologram will be moved to your feet)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String validateName(String name) throws InvalidCharactersException {
|
||||||
|
for (char c : name.toCharArray()) {
|
||||||
|
if (VALID_HOLOGRAM_NAME_CHARS.indexOf(c) < 0) {
|
||||||
|
throw new InvalidCharactersException(Character.toString(c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.commands.main.subs;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Colors;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.CommandValidator;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Strings;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.HologramSubCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.disk.HologramDatabase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.CommandException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager;
|
||||||
|
|
||||||
|
public class DeleteCommand extends HologramSubCommand {
|
||||||
|
|
||||||
|
public DeleteCommand() {
|
||||||
|
super("delete", "remove");
|
||||||
|
setPermission(Strings.BASE_PERM + "delete");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPossibleArguments() {
|
||||||
|
return "<hologramName>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumArguments() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String label, String[] args) throws CommandException {
|
||||||
|
NamedHologram hologram = NamedHologramManager.getHologram(args[0].toLowerCase());
|
||||||
|
CommandValidator.notNull(hologram, Strings.NO_SUCH_HOLOGRAM);
|
||||||
|
|
||||||
|
hologram.delete();
|
||||||
|
NamedHologramManager.removeHologram(hologram);
|
||||||
|
HologramDatabase.deleteHologram(hologram.getName());
|
||||||
|
|
||||||
|
HologramDatabase.trySaveToDisk();
|
||||||
|
sender.sendMessage(Colors.PRIMARY + "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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.commands.main.subs;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.util.com.google.common.base.Joiner;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.HolographicDisplays;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Colors;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.CommandValidator;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Strings;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.HologramSubCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.HologramsCommandHandler;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.CommandException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.Utils;
|
||||||
|
|
||||||
|
public class EditCommand extends HologramSubCommand {
|
||||||
|
|
||||||
|
private HologramsCommandHandler mainCommandHandler;
|
||||||
|
|
||||||
|
public EditCommand(HologramsCommandHandler mainCommandHandler) {
|
||||||
|
super("edit");
|
||||||
|
setPermission(Strings.BASE_PERM + "edit");
|
||||||
|
this.mainCommandHandler = mainCommandHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPossibleArguments() {
|
||||||
|
return "<hologramName>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumArguments() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String label, String[] args) throws CommandException {
|
||||||
|
String name = args[0].toLowerCase();
|
||||||
|
NamedHologram hologram = NamedHologramManager.getHologram(name);
|
||||||
|
CommandValidator.notNull(hologram, Strings.NO_SUCH_HOLOGRAM);
|
||||||
|
|
||||||
|
sender.sendMessage("");
|
||||||
|
sender.sendMessage(Strings.formatTitle("How to edit the hologram '" + name + "'"));
|
||||||
|
for (HologramSubCommand subCommand : mainCommandHandler.getSubCommands()) {
|
||||||
|
if (subCommand.getType() == SubCommandType.EDIT_LINES) {
|
||||||
|
String usage = "/" + label + " " + subCommand.getName() + (subCommand.getPossibleArguments().length() > 0 ? " " + subCommand.getPossibleArguments().replace("<hologramName>", hologram.getName()).replace("<hologram>", hologram.getName()) : "");
|
||||||
|
|
||||||
|
if (CommandValidator.isPlayerSender(sender)) {
|
||||||
|
|
||||||
|
List<String> help = Utils.newList();
|
||||||
|
help.add(Colors.PRIMARY + usage);
|
||||||
|
for (String tutLine : subCommand.getTutorial()) {
|
||||||
|
help.add(Colors.SECONDARY_SHADOW + tutLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
HolographicDisplays.getNMSManager().newFancyMessage(usage)
|
||||||
|
.color(ChatColor.AQUA)
|
||||||
|
.suggest(usage)
|
||||||
|
.tooltip(Joiner.on('\n').join(help))
|
||||||
|
.send((Player) sender);
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(Colors.PRIMARY + usage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CommandValidator.isPlayerSender(sender) && HolographicDisplays.getNMSManager().hasChatHoverFeature()) {
|
||||||
|
HelpCommand.sendHoverTip(sender);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getTutorial() {
|
||||||
|
return Arrays.asList("Shows the commands to manipulate an existing hologram.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubCommandType getType() {
|
||||||
|
return SubCommandType.GENERIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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.holographicdisplays.commands.Colors;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.CommandValidator;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Strings;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.HologramSubCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.CommandException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager;
|
||||||
|
|
||||||
|
public class FixCommand extends HologramSubCommand {
|
||||||
|
|
||||||
|
public FixCommand() {
|
||||||
|
super("fix");
|
||||||
|
setPermission(Strings.BASE_PERM + "fix");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPossibleArguments() {
|
||||||
|
return "<hologramName>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumArguments() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String label, String[] args) throws CommandException {
|
||||||
|
NamedHologram hologram = NamedHologramManager.getHologram(args[0].toLowerCase());
|
||||||
|
CommandValidator.notNull(hologram, Strings.NO_SUCH_HOLOGRAM);
|
||||||
|
|
||||||
|
if (args.length <= 1) {
|
||||||
|
sender.sendMessage(Colors.PRIMARY + "This command will put a glowstone 16 blocks above the hologram to fix the lightning.");
|
||||||
|
sender.sendMessage(Colors.PRIMARY + "If you're sure, type " + Colors.SECONDARY + "/" + label + " fix " + args[0].toLowerCase() + " confirm");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args[1].equalsIgnoreCase("confirm")) {
|
||||||
|
|
||||||
|
Block block = hologram.getWorld().getBlockAt((int) hologram.getX(), (int) hologram.getY() + 16, (int) hologram.getZ());
|
||||||
|
String oldType = block.getType().toString().replace("_", " ").toLowerCase();
|
||||||
|
block.setType(Material.GLOWSTONE);
|
||||||
|
|
||||||
|
sender.sendMessage(Colors.PRIMARY + "Changed the block 16 block above the hologram (" + oldType + ") to glowstone!");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new CommandException(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 (Only for 1.7 and lower).");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubCommandType getType() {
|
||||||
|
return SubCommandType.GENERIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.commands.main.subs;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.util.com.google.common.base.Joiner;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.HolographicDisplays;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Colors;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.CommandValidator;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Strings;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.HologramSubCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.HologramsCommandHandler;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.CommandException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.Utils;
|
||||||
|
|
||||||
|
public class HelpCommand extends HologramSubCommand {
|
||||||
|
|
||||||
|
private HologramsCommandHandler mainCommandHandler;
|
||||||
|
|
||||||
|
public HelpCommand(HologramsCommandHandler mainCommandHandler) {
|
||||||
|
super("help");
|
||||||
|
setPermission(Strings.BASE_PERM + "help");
|
||||||
|
this.mainCommandHandler = mainCommandHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPossibleArguments() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumArguments() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String label, String[] args) throws CommandException {
|
||||||
|
sender.sendMessage("");
|
||||||
|
sender.sendMessage(Strings.formatTitle("Holographic Displays Commands"));
|
||||||
|
for (HologramSubCommand subCommand : mainCommandHandler.getSubCommands()) {
|
||||||
|
if (subCommand.getType() == SubCommandType.GENERIC) {
|
||||||
|
String usage = "/" + label + " " + subCommand.getName() + (subCommand.getPossibleArguments().length() > 0 ? " " + subCommand.getPossibleArguments() : "");
|
||||||
|
|
||||||
|
if (CommandValidator.isPlayerSender(sender)) {
|
||||||
|
|
||||||
|
List<String> help = Utils.newList();
|
||||||
|
help.add(Colors.PRIMARY + usage);
|
||||||
|
for (String tutLine : subCommand.getTutorial()) {
|
||||||
|
help.add(Colors.SECONDARY_SHADOW + tutLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
HolographicDisplays.getNMSManager().newFancyMessage(usage)
|
||||||
|
.color(ChatColor.AQUA)
|
||||||
|
.suggest(usage)
|
||||||
|
.tooltip(Joiner.on('\n').join(help))
|
||||||
|
.send((Player) sender);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(Colors.PRIMARY + usage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CommandValidator.isPlayerSender(sender) && HolographicDisplays.getNMSManager().hasChatHoverFeature()) {
|
||||||
|
sendHoverTip(sender);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendHoverTip(CommandSender sender) {
|
||||||
|
sender.sendMessage("");
|
||||||
|
HolographicDisplays.getNMSManager().newFancyMessage("TIP").style(ChatColor.BOLD).color(ChatColor.YELLOW)
|
||||||
|
.then(" Try to ").color(ChatColor.GRAY)
|
||||||
|
.then("hover").color(ChatColor.WHITE).style(ChatColor.ITALIC, ChatColor.UNDERLINE)
|
||||||
|
.tooltip(ChatColor.LIGHT_PURPLE + "Hover on the commands to get info about them.")
|
||||||
|
.then(" or ").color(ChatColor.GRAY)
|
||||||
|
.then("click").color(ChatColor.WHITE).style(ChatColor.ITALIC, ChatColor.UNDERLINE)
|
||||||
|
.tooltip(ChatColor.LIGHT_PURPLE + "Click on the commands to insert them in the chat.")
|
||||||
|
.then(" on the commands!").color(ChatColor.GRAY)
|
||||||
|
.send((Player) sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getTutorial() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubCommandType getType() {
|
||||||
|
return SubCommandType.HIDDEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.commands.main.subs;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Colors;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.CommandValidator;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Strings;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.HologramSubCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.disk.HologramDatabase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.CommandException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.Utils;
|
||||||
|
|
||||||
|
public class InsertlineCommand extends HologramSubCommand {
|
||||||
|
|
||||||
|
|
||||||
|
public InsertlineCommand() {
|
||||||
|
super("insertline");
|
||||||
|
setPermission(Strings.BASE_PERM + "insertline");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPossibleArguments() {
|
||||||
|
return "<hologramName> <lineNumber> <text>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumArguments() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String label, String[] args) throws CommandException {
|
||||||
|
NamedHologram hologram = NamedHologramManager.getHologram(args[0].toLowerCase());
|
||||||
|
CommandValidator.notNull(hologram, Strings.NO_SUCH_HOLOGRAM);
|
||||||
|
|
||||||
|
int insertAfter = CommandValidator.getInteger(args[1]);
|
||||||
|
int oldLinesAmount = hologram.size();
|
||||||
|
|
||||||
|
CommandValidator.isTrue(insertAfter >= 0 && insertAfter <= oldLinesAmount, "The number must be between 0 and " + hologram.size() + "(amount of lines of the hologram).");
|
||||||
|
|
||||||
|
hologram.getLinesUnsafe().add(insertAfter, HologramDatabase.readLineFromString(Utils.join(args, " ", 2, args.length), hologram));
|
||||||
|
hologram.refreshAll();
|
||||||
|
|
||||||
|
HologramDatabase.saveHologram(hologram);
|
||||||
|
HologramDatabase.trySaveToDisk();
|
||||||
|
|
||||||
|
if (insertAfter == 0) {
|
||||||
|
sender.sendMessage(Colors.PRIMARY + "Line inserted before line n.1!");
|
||||||
|
} else if (insertAfter == oldLinesAmount) {
|
||||||
|
sender.sendMessage(Colors.PRIMARY + "Line appended at the end!");
|
||||||
|
sender.sendMessage(Strings.TIP_PREFIX + "Next time use /" + label + " addline to add a line at the end.");
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(Colors.PRIMARY + "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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.commands.main.subs;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Colors;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.CommandValidator;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Strings;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.HologramSubCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.CommandException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager;
|
||||||
|
|
||||||
|
public class ListCommand extends HologramSubCommand {
|
||||||
|
|
||||||
|
private static final int HOLOGRAMS_PER_PAGE = 10;
|
||||||
|
|
||||||
|
public ListCommand() {
|
||||||
|
super("list");
|
||||||
|
setPermission(Strings.BASE_PERM + "list");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPossibleArguments() {
|
||||||
|
return "[page]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumArguments() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String label, 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 = NamedHologramManager.size() / HOLOGRAMS_PER_PAGE;
|
||||||
|
if (NamedHologramManager.size() % HOLOGRAMS_PER_PAGE != 0) {
|
||||||
|
totalPages++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (NamedHologramManager.size() == 0) {
|
||||||
|
throw new CommandException("There are no holograms yet. Create one with /" + label + " create.");
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.sendMessage("");
|
||||||
|
sender.sendMessage(Strings.formatTitle("Holograms list " + Colors.SECONDARY + "(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 < NamedHologramManager.size()) {
|
||||||
|
NamedHologram hologram = NamedHologramManager.get(i);
|
||||||
|
sender.sendMessage(Colors.SECONDARY_SHADOW + "- " + Colors.SECONDARY + Colors.BOLD + hologram.getName() + " " + Colors.SECONDARY_SHADOW + "at x: " + (int) hologram.getX() + ", y: " + (int) hologram.getY() + ", z: " + (int) hologram.getZ() + " (lines: " + hologram.size() + ", world: \"" + hologram.getWorld().getName() + "\")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (page < totalPages) {
|
||||||
|
sender.sendMessage(Strings.TIP_PREFIX + "See the next page with /" + label + " list " + (page + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getTutorial() {
|
||||||
|
return Arrays.asList("Lists all the existing holograms.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubCommandType getType() {
|
||||||
|
return SubCommandType.GENERIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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.holographicdisplays.commands.Colors;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.CommandValidator;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Strings;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.HologramSubCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.disk.HologramDatabase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.CommandException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager;
|
||||||
|
|
||||||
|
public class MovehereCommand extends HologramSubCommand {
|
||||||
|
|
||||||
|
|
||||||
|
public MovehereCommand() {
|
||||||
|
super("movehere");
|
||||||
|
setPermission(Strings.BASE_PERM + "movehere");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPossibleArguments() {
|
||||||
|
return "<hologramName>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumArguments() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String label, String[] args) throws CommandException {
|
||||||
|
Player player = CommandValidator.getPlayerSender(sender);
|
||||||
|
NamedHologram hologram = NamedHologramManager.getHologram(args[0].toLowerCase());
|
||||||
|
CommandValidator.notNull(hologram, Strings.NO_SUCH_HOLOGRAM);
|
||||||
|
|
||||||
|
hologram.teleport(player.getWorld(), player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ());
|
||||||
|
hologram.despawnEntities();
|
||||||
|
hologram.refreshAll();
|
||||||
|
|
||||||
|
HologramDatabase.saveHologram(hologram);
|
||||||
|
HologramDatabase.trySaveToDisk();
|
||||||
|
Location to = player.getLocation();
|
||||||
|
to.setPitch(90);
|
||||||
|
player.teleport(to, TeleportCause.PLUGIN);
|
||||||
|
player.sendMessage(Colors.PRIMARY + "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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.commands.main.subs;
|
||||||
|
|
||||||
|
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.holographicdisplays.commands.Colors;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.CommandValidator;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Strings;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.HologramSubCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.CommandException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.Utils;
|
||||||
|
|
||||||
|
public class NearCommand extends HologramSubCommand {
|
||||||
|
|
||||||
|
public NearCommand() {
|
||||||
|
super("near");
|
||||||
|
setPermission(Strings.BASE_PERM + "near");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPossibleArguments() {
|
||||||
|
return "<radius>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumArguments() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String label, 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<NamedHologram> nearHolograms = Utils.newList();
|
||||||
|
|
||||||
|
for (NamedHologram hologram : NamedHologramManager.getHolograms()) {
|
||||||
|
if (hologram.getLocation().getWorld().equals(world) && hologram.getLocation().distanceSquared(player.getLocation()) <= radiusSquared) {
|
||||||
|
nearHolograms.add(hologram);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandValidator.isTrue(!nearHolograms.isEmpty(), "There are no holograms in the given radius.");
|
||||||
|
|
||||||
|
player.sendMessage(Strings.formatTitle("Near holograms"));
|
||||||
|
for (NamedHologram nearHologram : nearHolograms) {
|
||||||
|
player.sendMessage(Colors.SECONDARY_SHADOW + "- " + Colors.SECONDARY + Colors.BOLD + nearHologram.getName() + " " + Colors.SECONDARY_SHADOW + "at x: " + (int) nearHologram.getX() + ", y: " + (int) nearHologram.getY() + ", z: " + (int) nearHologram.getZ() + " (lines: " + nearHologram.size() + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getTutorial() {
|
||||||
|
return Arrays.asList("Get a list of near holograms.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubCommandType getType() {
|
||||||
|
return SubCommandType.GENERIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,157 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.commands.main.subs;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.util.com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.HolographicDisplays;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Colors;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.CommandValidator;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Strings;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.HologramSubCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.disk.HologramDatabase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.CommandException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.TooWideException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.UnreadableImageException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.image.ImageMessage;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.FileUtils;
|
||||||
|
|
||||||
|
public class ReadimageCommand extends HologramSubCommand {
|
||||||
|
|
||||||
|
|
||||||
|
public ReadimageCommand() {
|
||||||
|
super("readimage", "image");
|
||||||
|
setPermission(Strings.BASE_PERM + "readimage");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPossibleArguments() {
|
||||||
|
return "<hologram> <imageWithExtension> <width>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumArguments() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String label, String[] args) throws CommandException {
|
||||||
|
|
||||||
|
boolean append = false;
|
||||||
|
|
||||||
|
List<String> newArgs = Lists.newArrayList();
|
||||||
|
|
||||||
|
for (int i = 0; i < args.length; i++) {
|
||||||
|
if (args[i].equalsIgnoreCase("-a") || args[i].equalsIgnoreCase("-append")) {
|
||||||
|
append = true;
|
||||||
|
} else {
|
||||||
|
newArgs.add(args[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
args = newArgs.toArray(new String[0]);
|
||||||
|
|
||||||
|
NamedHologram hologram = NamedHologramManager.getHologram(args[0].toLowerCase());
|
||||||
|
CommandValidator.notNull(hologram, Strings.NO_SUCH_HOLOGRAM);
|
||||||
|
|
||||||
|
int width = CommandValidator.getInteger(args[2]);
|
||||||
|
|
||||||
|
CommandValidator.isTrue(width >= 2, "The width of the image must be 2 or greater.");
|
||||||
|
|
||||||
|
boolean isUrl = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
String fileName = args[1];
|
||||||
|
BufferedImage image = null;
|
||||||
|
|
||||||
|
if (fileName.startsWith("http://") || fileName.startsWith("https://")) {
|
||||||
|
isUrl = true;
|
||||||
|
image = FileUtils.readImage(new URL(fileName));
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (fileName.matches(".*[a-zA-Z0-9\\-]+\\.[a-zA-Z0-9\\-]{1,4}\\/.+")) {
|
||||||
|
Strings.sendWarning(sender, "The image path seems to be an URL. If so, please use http:// or https:// in the path.");
|
||||||
|
}
|
||||||
|
|
||||||
|
image = FileUtils.readImage(new File(HolographicDisplays.getInstance().getDataFolder(), fileName));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!append) {
|
||||||
|
hologram.clearLines();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageMessage imageMessage = new ImageMessage(image, width);
|
||||||
|
String[] newLines = imageMessage.getLines();
|
||||||
|
for (int i = 0; i < newLines.length; i++) {
|
||||||
|
hologram.appendTextLine(newLines[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
hologram.refreshAll();
|
||||||
|
|
||||||
|
if (newLines.length < 5) {
|
||||||
|
sender.sendMessage(Strings.TIP_PREFIX + "The image has a very low height. You can increase it by increasing the width, it will scale automatically.");
|
||||||
|
}
|
||||||
|
|
||||||
|
HologramDatabase.saveHologram(hologram);
|
||||||
|
HologramDatabase.trySaveToDisk();
|
||||||
|
|
||||||
|
if (append) {
|
||||||
|
sender.sendMessage(Colors.PRIMARY + "The image was appended int the end of the hologram!");
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(Colors.PRIMARY + "The image was drawn in the hologram!");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
throw new CommandException("The provided URL was not valid.");
|
||||||
|
} 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 " + ImageMessage.MAX_WIDTH + " 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." + (isUrl ? "Is the URL valid?" : "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. Tutorial:",
|
||||||
|
"1) Move the image in the plugin's folder",
|
||||||
|
"2) Do not use spaces in the name",
|
||||||
|
"3) Do /holograms read <hologram> <image> <width>",
|
||||||
|
"4) Choose <width> to automatically resize the image",
|
||||||
|
"5) (Optional) Use the flag '-a' if you only want to append",
|
||||||
|
" the image to the hologram without clearing the lines",
|
||||||
|
"",
|
||||||
|
"Example: you have an image named 'logo.png', you want to append",
|
||||||
|
"it to the lines of the hologram named 'test', with a width of",
|
||||||
|
"50 pixels. In this case you would execute the following command:",
|
||||||
|
ChatColor.YELLOW + "/holograms readimage test logo.png 50 -a",
|
||||||
|
"",
|
||||||
|
"The symbols used to create the image are taken from the config.yml.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubCommandType getType() {
|
||||||
|
return SubCommandType.EDIT_LINES;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.commands.main.subs;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.HolographicDisplays;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Colors;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.CommandValidator;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Strings;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.HologramSubCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.disk.HologramDatabase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.disk.StringConverter;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.CommandException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.FileUtils;
|
||||||
|
|
||||||
|
public class ReadtextCommand extends HologramSubCommand {
|
||||||
|
|
||||||
|
public ReadtextCommand() {
|
||||||
|
super("readtext", "readlines");
|
||||||
|
setPermission(Strings.BASE_PERM + "readtext");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPossibleArguments() {
|
||||||
|
return "<hologramName> <fileWithExtension>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumArguments() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String label, String[] args) throws CommandException {
|
||||||
|
NamedHologram hologram = NamedHologramManager.getHologram(args[0].toLowerCase());
|
||||||
|
CommandValidator.notNull(hologram, Strings.NO_SUCH_HOLOGRAM);
|
||||||
|
|
||||||
|
try {
|
||||||
|
List<String> lines = FileUtils.readLines(new File(HolographicDisplays.getInstance().getDataFolder(), args[1]));
|
||||||
|
hologram.clearLines();
|
||||||
|
|
||||||
|
int linesAmount = lines.size();
|
||||||
|
if (linesAmount > 40) {
|
||||||
|
Strings.sendWarning(sender, "The file contained more than 40 lines, that have been limited.");
|
||||||
|
linesAmount = 40;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < linesAmount; i++) {
|
||||||
|
hologram.appendTextLine(StringConverter.toReadableFormat(lines.get(i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
hologram.refreshAll();
|
||||||
|
|
||||||
|
HologramDatabase.saveHologram(hologram);
|
||||||
|
HologramDatabase.trySaveToDisk();
|
||||||
|
|
||||||
|
if (args[1].contains(".")) {
|
||||||
|
if (isImageExtension(args[1].substring(args[1].lastIndexOf('.') + 1))) {
|
||||||
|
Strings.sendWarning(sender, "The read file has an image's extension. If it is an image, you should use /" + label + " readimage.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.sendMessage(Colors.PRIMARY + "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. Tutorial:",
|
||||||
|
"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 /holograms readlines <hologramName> <fileWithExtension>",
|
||||||
|
"",
|
||||||
|
"Example: you have a file named 'info.txt', and you want",
|
||||||
|
"to paste it in the hologram named 'test'. In this case you",
|
||||||
|
"would execute "+ ChatColor.YELLOW + "/holograms readlines test info.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubCommandType getType() {
|
||||||
|
return SubCommandType.EDIT_LINES;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isImageExtension(String input) {
|
||||||
|
return Arrays.asList("jpg", "png", "jpeg", "gif").contains(input.toLowerCase());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.commands.main.subs;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.HolographicDisplays;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.bridge.bungeecord.BungeeServerTracker;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Colors;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Strings;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.HologramSubCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.disk.Configuration;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.disk.HologramDatabase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.disk.UnicodeSymbols;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.CommandException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.HologramNotFoundException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.InvalidFormatException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.WorldNotFoundException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.CraftHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.placeholder.AnimationsRegister;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.placeholder.PlaceholdersManager;
|
||||||
|
|
||||||
|
public class ReloadCommand extends HologramSubCommand {
|
||||||
|
|
||||||
|
public ReloadCommand() {
|
||||||
|
super("reload");
|
||||||
|
setPermission(Strings.BASE_PERM + "reload");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPossibleArguments() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumArguments() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String label, String[] args) throws CommandException {
|
||||||
|
try {
|
||||||
|
|
||||||
|
long startMillis = System.currentTimeMillis();
|
||||||
|
|
||||||
|
Configuration.load(HolographicDisplays.getInstance());
|
||||||
|
BungeeServerTracker.startTask(Configuration.bungeeRefreshSeconds);
|
||||||
|
UnicodeSymbols.load(HolographicDisplays.getInstance());
|
||||||
|
HologramDatabase.loadYamlFile(HolographicDisplays.getInstance());
|
||||||
|
AnimationsRegister.loadAnimations(HolographicDisplays.getInstance());
|
||||||
|
PlaceholdersManager.untrackAll();
|
||||||
|
|
||||||
|
NamedHologramManager.clearAll();
|
||||||
|
|
||||||
|
Set<String> savedHolograms = HologramDatabase.getHolograms();
|
||||||
|
if (savedHolograms != null && savedHolograms.size() > 0) {
|
||||||
|
for (String singleSavedHologram : savedHolograms) {
|
||||||
|
try {
|
||||||
|
NamedHologram singleHologramEntity = HologramDatabase.loadHologram(singleSavedHologram);
|
||||||
|
NamedHologramManager.addHologram(singleHologramEntity);
|
||||||
|
} catch (HologramNotFoundException e) {
|
||||||
|
Strings.sendWarning(sender, "Hologram '" + singleSavedHologram + "' not found, skipping it.");
|
||||||
|
} catch (InvalidFormatException e) {
|
||||||
|
Strings.sendWarning(sender, "Hologram '" + singleSavedHologram + "' has an invalid location format.");
|
||||||
|
} catch (WorldNotFoundException e) {
|
||||||
|
Strings.sendWarning(sender, "Hologram '" + singleSavedHologram + "' was in the world '" + e.getMessage() + "' but it wasn't loaded.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (CraftHologram hologram : NamedHologramManager.getHolograms()) {
|
||||||
|
hologram.refreshAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
long endMillis = System.currentTimeMillis();
|
||||||
|
|
||||||
|
sender.sendMessage(Colors.PRIMARY + "Configuration 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.commands.main.subs;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Colors;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.CommandValidator;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Strings;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.HologramSubCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.disk.HologramDatabase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.CommandException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager;
|
||||||
|
|
||||||
|
public class RemovelineCommand extends HologramSubCommand {
|
||||||
|
|
||||||
|
public RemovelineCommand() {
|
||||||
|
super("removeline");
|
||||||
|
setPermission(Strings.BASE_PERM + "removeline");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPossibleArguments() {
|
||||||
|
return "<hologramName> <lineNumber>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumArguments() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String label, String[] args) throws CommandException {
|
||||||
|
NamedHologram hologram = NamedHologramManager.getHologram(args[0].toLowerCase());
|
||||||
|
CommandValidator.notNull(hologram, Strings.NO_SUCH_HOLOGRAM);
|
||||||
|
|
||||||
|
int lineNumber = CommandValidator.getInteger(args[1]);
|
||||||
|
|
||||||
|
CommandValidator.isTrue(lineNumber >= 1 && lineNumber <= hologram.size(), "The line number must be between 1 and " + hologram.size() + ".");
|
||||||
|
int index = lineNumber - 1;
|
||||||
|
|
||||||
|
CommandValidator.isTrue(hologram.size() > 1, "The hologram should have at least 1 line. If you want to delete it, use /" + label + " delete.");
|
||||||
|
|
||||||
|
hologram.removeLine(index);
|
||||||
|
hologram.refreshAll();
|
||||||
|
|
||||||
|
HologramDatabase.saveHologram(hologram);
|
||||||
|
HologramDatabase.trySaveToDisk();
|
||||||
|
sender.sendMessage(Colors.PRIMARY + "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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.commands.main.subs;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Colors;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.CommandValidator;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Strings;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.HologramSubCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.disk.HologramDatabase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.CommandException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.Utils;
|
||||||
|
|
||||||
|
public class SetlineCommand extends HologramSubCommand {
|
||||||
|
|
||||||
|
public SetlineCommand() {
|
||||||
|
super("setline");
|
||||||
|
setPermission(Strings.BASE_PERM + "setline");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPossibleArguments() {
|
||||||
|
return "<hologramName> <lineNumber> <newText>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumArguments() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String label, String[] args) throws CommandException {
|
||||||
|
NamedHologram hologram = NamedHologramManager.getHologram(args[0].toLowerCase());
|
||||||
|
CommandValidator.notNull(hologram, Strings.NO_SUCH_HOLOGRAM);
|
||||||
|
|
||||||
|
|
||||||
|
int lineNumber = CommandValidator.getInteger(args[1]);
|
||||||
|
CommandValidator.isTrue(lineNumber >= 1 && lineNumber <= hologram.size(), "The line number must be between 1 and " + hologram.size() + ".");
|
||||||
|
int index = lineNumber - 1;
|
||||||
|
|
||||||
|
hologram.getLinesUnsafe().get(index).despawn();
|
||||||
|
hologram.getLinesUnsafe().set(index, HologramDatabase.readLineFromString(Utils.join(args, " ", 2, args.length), hologram));
|
||||||
|
hologram.refreshAll();
|
||||||
|
|
||||||
|
HologramDatabase.saveHologram(hologram);
|
||||||
|
HologramDatabase.trySaveToDisk();
|
||||||
|
sender.sendMessage(Colors.PRIMARY + "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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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.holographicdisplays.commands.Colors;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.CommandValidator;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Strings;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.main.HologramSubCommand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.CommandException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager;
|
||||||
|
|
||||||
|
|
||||||
|
public class TeleportCommand extends HologramSubCommand {
|
||||||
|
|
||||||
|
public TeleportCommand() {
|
||||||
|
super("teleport", "tp");
|
||||||
|
setPermission(Strings.BASE_PERM + "teleport");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPossibleArguments() {
|
||||||
|
return "<hologramName>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumArguments() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String label, String[] args) throws CommandException {
|
||||||
|
Player player = CommandValidator.getPlayerSender(sender);
|
||||||
|
NamedHologram hologram = NamedHologramManager.getHologram(args[0].toLowerCase());
|
||||||
|
CommandValidator.notNull(hologram, Strings.NO_SUCH_HOLOGRAM);
|
||||||
|
|
||||||
|
Location loc = hologram.getLocation();
|
||||||
|
loc.setPitch(90);
|
||||||
|
player.teleport(loc, TeleportCause.PLUGIN);
|
||||||
|
player.sendMessage(Colors.PRIMARY + "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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.disk;
|
||||||
|
|
||||||
|
public enum ConfigNode {
|
||||||
|
|
||||||
|
SPACE_BETWEEN_LINES("space-between-lines", 0.02),
|
||||||
|
IMAGES_SYMBOL("images.symbol", "[x]"),
|
||||||
|
TRANSPARENCY_SPACE("images.transparency.space", " [|] "),
|
||||||
|
TRANSPARENCY_COLOR("images.transparency.color", "&7"),
|
||||||
|
UPDATE_NOTIFICATION("update-notification", true),
|
||||||
|
BUNGEE_REFRESH_SECONDS("bungee.refresh-seconds", 3),
|
||||||
|
BUNGEE_USE_REDIS_BUNGEE("bungee.use-RedisBungee", false),
|
||||||
|
TIME_FORMAT("time.format", "H:mm"),
|
||||||
|
TIME_ZONE("time.zone", "GMT+1"),
|
||||||
|
DEBUG("debug", false);
|
||||||
|
|
||||||
|
private final String path;
|
||||||
|
private final Object value;
|
||||||
|
|
||||||
|
private ConfigNode(String path, Object defaultValue) {
|
||||||
|
this.path = path;
|
||||||
|
value = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPath() {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getDefaultValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,149 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.disk;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.configuration.InvalidConfigurationException;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just a bunch of static varibles to hold the settings.
|
||||||
|
* Useful for fast access.
|
||||||
|
*/
|
||||||
|
public class Configuration {
|
||||||
|
|
||||||
|
public static double spaceBetweenLines;
|
||||||
|
public static String imageSymbol;
|
||||||
|
public static String transparencySymbol;
|
||||||
|
public static boolean updateNotification;
|
||||||
|
public static ChatColor transparencyColor;
|
||||||
|
|
||||||
|
public static SimpleDateFormat timeFormat;
|
||||||
|
|
||||||
|
public static int bungeeRefreshSeconds;
|
||||||
|
public static String bungeeOnlineFormat;
|
||||||
|
public static String bungeeOfflineFormat;
|
||||||
|
public static boolean useRedisBungee;
|
||||||
|
|
||||||
|
public static boolean debug;
|
||||||
|
|
||||||
|
|
||||||
|
public static void load(Plugin plugin) {
|
||||||
|
File configFile = new File(plugin.getDataFolder(), "config.yml");
|
||||||
|
if (!configFile.exists()) {
|
||||||
|
plugin.getDataFolder().mkdirs();
|
||||||
|
plugin.saveResource("config.yml", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
YamlConfiguration config = new YamlConfiguration();
|
||||||
|
try {
|
||||||
|
config.load(configFile);
|
||||||
|
} catch (InvalidConfigurationException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
plugin.getLogger().warning("The configuration is not a valid YAML file! Please check it with a tool like http://yaml-online-parser.appspot.com/");
|
||||||
|
return;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
plugin.getLogger().warning("I/O error while reading the configuration. Was the file in use?");
|
||||||
|
return;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
plugin.getLogger().warning("Unhandled exception while reading the configuration!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean needsSave = false;
|
||||||
|
|
||||||
|
for (ConfigNode node : ConfigNode.values()) {
|
||||||
|
if (!config.isSet(node.getPath())) {
|
||||||
|
needsSave = true;
|
||||||
|
config.set(node.getPath(), node.getDefaultValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the old values.
|
||||||
|
List<String> nodesToRemove = Arrays.asList(
|
||||||
|
"vertical-spacing",
|
||||||
|
"time-format",
|
||||||
|
"bungee-refresh-seconds",
|
||||||
|
"using-RedisBungee",
|
||||||
|
"bungee-online-format",
|
||||||
|
"bungee-offline-format"
|
||||||
|
);
|
||||||
|
|
||||||
|
for (String oldNode : nodesToRemove) {
|
||||||
|
if (config.isSet(oldNode)) {
|
||||||
|
config.set(oldNode, null);
|
||||||
|
needsSave = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (needsSave) {
|
||||||
|
config.options().header(Joiner.on('\n').join(
|
||||||
|
".",
|
||||||
|
". Read the tutorial at: http://dev.bukkit.org/bukkit-plugins/holographic-displays/",
|
||||||
|
".",
|
||||||
|
". Plugin created by filoghost.",
|
||||||
|
"."
|
||||||
|
));
|
||||||
|
config.options().copyHeader(true);
|
||||||
|
try {
|
||||||
|
config.save(configFile);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
plugin.getLogger().warning("I/O error while saving the configuration. Was the file in use?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spaceBetweenLines = config.getDouble(ConfigNode.SPACE_BETWEEN_LINES.getPath());
|
||||||
|
updateNotification = config.getBoolean(ConfigNode.UPDATE_NOTIFICATION.getPath());
|
||||||
|
|
||||||
|
imageSymbol = StringConverter.toReadableFormat(config.getString(ConfigNode.IMAGES_SYMBOL.getPath()));
|
||||||
|
transparencySymbol = StringConverter.toReadableFormat(config.getString(ConfigNode.TRANSPARENCY_SPACE.getPath()));
|
||||||
|
bungeeRefreshSeconds = config.getInt(ConfigNode.BUNGEE_REFRESH_SECONDS.getPath());
|
||||||
|
useRedisBungee = config.getBoolean(ConfigNode.BUNGEE_USE_REDIS_BUNGEE.getPath());
|
||||||
|
|
||||||
|
debug = config.getBoolean(ConfigNode.DEBUG.getPath());
|
||||||
|
|
||||||
|
String tempColor = config.getString(ConfigNode.TRANSPARENCY_COLOR.getPath()).replace('&', ChatColor.COLOR_CHAR);
|
||||||
|
boolean foundColor = false;
|
||||||
|
for (ChatColor chatColor : ChatColor.values()) {
|
||||||
|
if (chatColor.toString().equals(tempColor)) {
|
||||||
|
Configuration.transparencyColor = chatColor;
|
||||||
|
foundColor = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundColor) {
|
||||||
|
Configuration.transparencyColor = ChatColor.GRAY;
|
||||||
|
plugin.getLogger().warning("You didn't set a valid chat color for transparency in the configuration, light gray (&7) will be used.");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
timeFormat = new SimpleDateFormat(config.getString(ConfigNode.TIME_FORMAT.getPath()));
|
||||||
|
timeFormat.setTimeZone(TimeZone.getTimeZone(config.getString(ConfigNode.TIME_ZONE.getPath())));
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
timeFormat = new SimpleDateFormat("H:mm");
|
||||||
|
plugin.getLogger().warning("Time format not valid in the configuration, using the default.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bungeeRefreshSeconds < 1) {
|
||||||
|
plugin.getLogger().warning("The minimum interval for pinging BungeeCord's servers is 1 second. It has been automatically set.");
|
||||||
|
bungeeRefreshSeconds = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bungeeRefreshSeconds > 60) {
|
||||||
|
plugin.getLogger().warning("The maximum interval for pinging BungeeCord's servers is 60 seconds. It has been automatically set.");
|
||||||
|
bungeeRefreshSeconds = 60;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,146 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.disk;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.HolographicDisplays;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.HologramNotFoundException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.InvalidFormatException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.WorldNotFoundException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.CraftHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftTextLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.ItemUtils;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.Utils;
|
||||||
|
|
||||||
|
public class HologramDatabase {
|
||||||
|
|
||||||
|
private static File file;
|
||||||
|
private static FileConfiguration config;
|
||||||
|
|
||||||
|
public static void loadYamlFile(Plugin plugin) {
|
||||||
|
file = new File(plugin.getDataFolder(), "database.yml");
|
||||||
|
|
||||||
|
if (!file.exists()) {
|
||||||
|
plugin.getDataFolder().mkdirs();
|
||||||
|
plugin.saveResource("database.yml", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
config = YamlConfiguration.loadConfiguration(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NamedHologram loadHologram(String name) throws HologramNotFoundException, InvalidFormatException, WorldNotFoundException {
|
||||||
|
|
||||||
|
ConfigurationSection configSection = config.getConfigurationSection(name);
|
||||||
|
|
||||||
|
if (configSection == null) {
|
||||||
|
throw new HologramNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> lines = configSection.getStringList("lines");
|
||||||
|
String locationString = configSection.getString("location");
|
||||||
|
|
||||||
|
if (lines == null || locationString == null || lines.size() == 0) {
|
||||||
|
throw new HologramNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
Location loc = LocationSerializer.locationFromString(locationString);
|
||||||
|
|
||||||
|
NamedHologram hologram = new NamedHologram(loc, name);
|
||||||
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
|
hologram.getLinesUnsafe().add(readLineFromString(lines.get(i), hologram));
|
||||||
|
}
|
||||||
|
|
||||||
|
return hologram;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CraftHologramLine readLineFromString(String rawText, CraftHologram hologram) {
|
||||||
|
if (rawText.toLowerCase().startsWith("icon:")) {
|
||||||
|
String iconMaterial = ItemUtils.stripSpacingChars(rawText.substring("icon:".length(), rawText.length()));
|
||||||
|
|
||||||
|
short dataValue = 0;
|
||||||
|
|
||||||
|
if (iconMaterial.contains(":")) {
|
||||||
|
try {
|
||||||
|
dataValue = (short) Integer.parseInt(iconMaterial.split(":")[1]);
|
||||||
|
} catch (NumberFormatException e) { }
|
||||||
|
iconMaterial = iconMaterial.split(":")[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
Material mat = ItemUtils.matchMaterial(iconMaterial);
|
||||||
|
if (mat == null) {
|
||||||
|
mat = Material.BEDROCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CraftItemLine(hologram, new ItemStack(mat, 1, dataValue));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (rawText.trim().equalsIgnoreCase("{empty}")) {
|
||||||
|
return new CraftTextLine(hologram, "");
|
||||||
|
} else {
|
||||||
|
return new CraftTextLine(hologram, StringConverter.toReadableFormat(rawText));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void deleteHologram(String name) {
|
||||||
|
config.set(name, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveHologram(NamedHologram hologram) {
|
||||||
|
|
||||||
|
ConfigurationSection configSection = config.isConfigurationSection(hologram.getName()) ? config.getConfigurationSection(hologram.getName()) : config.createSection(hologram.getName());
|
||||||
|
|
||||||
|
configSection.set("location", LocationSerializer.locationToString(hologram.getLocation()));
|
||||||
|
List<String> lines = Utils.newList();
|
||||||
|
|
||||||
|
for (CraftHologramLine line : hologram.getLinesUnsafe()) {
|
||||||
|
|
||||||
|
if (line instanceof CraftTextLine) {
|
||||||
|
lines.add(StringConverter.toSaveableFormat(((CraftTextLine) line).getText()));
|
||||||
|
|
||||||
|
} else if (line instanceof CraftItemLine) {
|
||||||
|
CraftItemLine itemLine = (CraftItemLine) line;
|
||||||
|
lines.add("ICON: " + itemLine.getItemStack().getType().toString().replace("_", " ").toLowerCase() + (itemLine.getItemStack().getDurability() != 0 ? String.valueOf(itemLine.getItemStack().getDurability()) : ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
configSection.set("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!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.disk;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.DecimalFormatSymbols;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.InvalidFormatException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.WorldNotFoundException;
|
||||||
|
|
||||||
|
public class LocationSerializer {
|
||||||
|
|
||||||
|
private static DecimalFormat decimalFormat;
|
||||||
|
static {
|
||||||
|
// More precision is not needed at all.
|
||||||
|
decimalFormat = new DecimalFormat("0.0000");
|
||||||
|
DecimalFormatSymbols formatSymbols = decimalFormat.getDecimalFormatSymbols();
|
||||||
|
formatSymbols.setDecimalSeparator('.');
|
||||||
|
decimalFormat.setDecimalFormatSymbols(formatSymbols);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Location locationFromString(String input) throws WorldNotFoundException, InvalidFormatException {
|
||||||
|
if (input == null) {
|
||||||
|
throw new InvalidFormatException();
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] parts = input.replace(" ", "").split(",");
|
||||||
|
|
||||||
|
if (parts.length != 4) {
|
||||||
|
throw new InvalidFormatException();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
double x = Double.parseDouble(parts[1]);
|
||||||
|
double y = Double.parseDouble(parts[2]);
|
||||||
|
double z = Double.parseDouble(parts[3]);
|
||||||
|
|
||||||
|
World world = Bukkit.getWorld(parts[0]);
|
||||||
|
if (world == null) {
|
||||||
|
throw new WorldNotFoundException(parts[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Location(world, x, y, z);
|
||||||
|
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
throw new InvalidFormatException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String locationToString(Location loc) {
|
||||||
|
return (loc.getWorld().getName() + ", " + decimalFormat.format(loc.getX()) + ", " + decimalFormat.format(loc.getY()) + ", " + decimalFormat.format(loc.getZ()));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.disk;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
|
||||||
|
public class StringConverter {
|
||||||
|
|
||||||
|
public static String toReadableFormat(String input) {
|
||||||
|
if (input == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
input = UnicodeSymbols.placeholdersToSymbols(input);
|
||||||
|
input = ChatColor.translateAlternateColorCodes('&', input);
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String toSaveableFormat(String input) {
|
||||||
|
if (input == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
input = UnicodeSymbols.symbolsToPlaceholders(input);
|
||||||
|
input = input.replace("§", "&");
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,102 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.disk;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringEscapeUtils;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.FileUtils;
|
||||||
|
|
||||||
|
public class UnicodeSymbols {
|
||||||
|
|
||||||
|
private static Map<String, String> placeholders = new HashMap<String, String>();
|
||||||
|
|
||||||
|
public static void load(Plugin plugin) {
|
||||||
|
placeholders.clear();
|
||||||
|
|
||||||
|
File file = new File(plugin.getDataFolder(), "symbols.yml");
|
||||||
|
|
||||||
|
if (!file.exists()) {
|
||||||
|
plugin.getDataFolder().mkdirs();
|
||||||
|
plugin.saveResource("symbols.yml", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> lines;
|
||||||
|
try {
|
||||||
|
lines = FileUtils.readLines(file);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
plugin.getLogger().warning("I/O error while reading symbols.yml. Was the file in use?");
|
||||||
|
return;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
plugin.getLogger().warning("Unhandled exception while reading symbols.yml!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String line : lines) {
|
||||||
|
|
||||||
|
// Comment or empty line.
|
||||||
|
if (line.length() == 0 || line.startsWith("#")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!line.contains(":")) {
|
||||||
|
plugin.getLogger().warning("Unable to parse a line(" + line + ") from symbols.yml: it must contain ':' to separate the placeholder and the replacement.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int indexOf = line.indexOf(':');
|
||||||
|
String placeholder = unquote(line.substring(0, indexOf).trim());
|
||||||
|
String replacement = StringEscapeUtils.unescapeJava(unquote(line.substring(indexOf + 1, line.length()).trim()));
|
||||||
|
|
||||||
|
if (placeholder.isEmpty() || replacement.isEmpty()) {
|
||||||
|
plugin.getLogger().warning("Unable to parse a line(" + line + ") from symbols.yml: the placeholder and the replacement must have both at least 1 character.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (placeholder.length() > 30) {
|
||||||
|
plugin.getLogger().warning("Unable to parse a line(" + line + ") from symbols.yml: the placeholder cannot be longer than 30 characters.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
placeholders.put(placeholder, replacement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected static String placeholdersToSymbols(String input) {
|
||||||
|
for (Entry<String, String> entry : placeholders.entrySet()) {
|
||||||
|
input = input.replace(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected static String symbolsToPlaceholders(String input) {
|
||||||
|
for (Entry<String, String> entry : placeholders.entrySet()) {
|
||||||
|
input = input.replace(entry.getValue(), entry.getKey());
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static String unquote(String input) {
|
||||||
|
if (input.length() < 2) {
|
||||||
|
// Cannot be quoted.
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
if (input.startsWith("'") && input.endsWith("'")) {
|
||||||
|
return input.substring(1, input.length() - 1);
|
||||||
|
} else if (input.startsWith("\"") && input.endsWith("\"")) {
|
||||||
|
return input.substring(1, input.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.exception;
|
||||||
|
|
||||||
|
public class CommandException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public CommandException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.exception;
|
||||||
|
|
||||||
|
public class HologramNotFoundException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.exception;
|
||||||
|
|
||||||
|
public class InvalidCharactersException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public InvalidCharactersException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.exception;
|
||||||
|
|
||||||
|
public class InvalidFormatException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.exception;
|
||||||
|
|
||||||
|
public class InvalidMaterialException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public InvalidMaterialException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.exception;
|
||||||
|
|
||||||
|
public class SpawnFailedException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.exception;
|
||||||
|
|
||||||
|
public class UnreadableImageException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.exception;
|
||||||
|
|
||||||
|
public class WorldNotFoundException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public WorldNotFoundException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,207 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.image;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.disk.Configuration;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.exception.TooWideException;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.Utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 {
|
||||||
|
|
||||||
|
public static final int MAX_WIDTH = 150;
|
||||||
|
|
||||||
|
private static final Map<ChatColor, Color> colorsMap = Utils.newMap();
|
||||||
|
|
||||||
|
private static final Map<ChatColor, Color> graysMap = Utils.newMap();
|
||||||
|
|
||||||
|
|
||||||
|
static {
|
||||||
|
colorsMap.put(ChatColor.DARK_BLUE, new Color(0, 0, 170));
|
||||||
|
colorsMap.put(ChatColor.DARK_GREEN, new Color(0, 170, 0));
|
||||||
|
colorsMap.put(ChatColor.DARK_AQUA, new Color(0, 170, 170));
|
||||||
|
colorsMap.put(ChatColor.DARK_RED, new Color(170, 0, 0));
|
||||||
|
colorsMap.put(ChatColor.DARK_PURPLE, new Color(170, 0, 170));
|
||||||
|
colorsMap.put(ChatColor.GOLD, new Color(255, 170, 0));
|
||||||
|
colorsMap.put(ChatColor.BLUE, new Color(85, 85, 255));
|
||||||
|
colorsMap.put(ChatColor.GREEN, new Color(85, 255, 85));
|
||||||
|
colorsMap.put(ChatColor.AQUA, new Color(85, 255, 255));
|
||||||
|
colorsMap.put(ChatColor.RED, new Color(255, 85, 85));
|
||||||
|
colorsMap.put(ChatColor.LIGHT_PURPLE, new Color(255, 85, 255));
|
||||||
|
colorsMap.put(ChatColor.YELLOW, new Color(255, 255, 85));
|
||||||
|
|
||||||
|
graysMap.put(ChatColor.BLACK, new Color(0, 0, 0));
|
||||||
|
graysMap.put(ChatColor.DARK_GRAY, new Color(85, 85, 85));
|
||||||
|
graysMap.put(ChatColor.GRAY, new Color(170, 170, 170));
|
||||||
|
graysMap.put(ChatColor.WHITE, 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_DEFAULT));
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
for (Entry<ChatColor, Color> entry : colorsMap.entrySet()) {
|
||||||
|
if (areIdentical(entry.getValue(), color)) {
|
||||||
|
return entry.getKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double bestGrayDistance = -1;
|
||||||
|
ChatColor bestGrayMatch = null;
|
||||||
|
|
||||||
|
for (Entry<ChatColor, Color> entry : graysMap.entrySet()) {
|
||||||
|
double distance = getDistance(color, entry.getValue());
|
||||||
|
|
||||||
|
if (distance < bestGrayDistance || bestGrayDistance == -1) {
|
||||||
|
bestGrayDistance = distance;
|
||||||
|
bestGrayMatch = entry.getKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestGrayDistance < 17500) {
|
||||||
|
return bestGrayMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
double bestColorDistance = -1;
|
||||||
|
ChatColor bestColorMatch = null;
|
||||||
|
|
||||||
|
for (Entry<ChatColor, Color> entry : colorsMap.entrySet()) {
|
||||||
|
double distance = getDistance(color, entry.getValue());
|
||||||
|
|
||||||
|
if (distance < bestColorDistance || bestColorDistance == -1) {
|
||||||
|
bestColorDistance = distance;
|
||||||
|
bestColorMatch = entry.getKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Minecraft has 15 colors
|
||||||
|
return bestColorMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String[] getLines() {
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,150 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.listener;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
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.player.PlayerQuitEvent;
|
||||||
|
import org.bukkit.event.world.ChunkLoadEvent;
|
||||||
|
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.HolographicDisplays;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.api.handler.PickupHandler;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Colors;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.commands.Strings;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.disk.Configuration;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.NMSManager;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.CraftHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.PluginHologram;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.PluginHologramManager;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.Utils;
|
||||||
|
|
||||||
|
public class MainListener implements Listener {
|
||||||
|
|
||||||
|
private NMSManager nmsManager;
|
||||||
|
|
||||||
|
private Map<Player, Long> anticlickSpam = Utils.newMap();
|
||||||
|
|
||||||
|
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()) {
|
||||||
|
NMSEntityBase entityBase = nmsManager.getNMSEntityBase(entity);
|
||||||
|
|
||||||
|
if (entityBase != null) {
|
||||||
|
entityBase.getHologramLine().getParent().despawnEntities();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler (priority = EventPriority.MONITOR)
|
||||||
|
public void onChunkLoad(ChunkLoadEvent event) {
|
||||||
|
Chunk chunk = event.getChunk();
|
||||||
|
NamedHologramManager.onChunkLoad(chunk);
|
||||||
|
PluginHologramManager.onChunkLoad(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler (priority = EventPriority.MONITOR, ignoreCancelled = false)
|
||||||
|
public void onCreatureSpawn(CreatureSpawnEvent event) {
|
||||||
|
if (nmsManager.isNMSEntityBase(event.getEntity())) {
|
||||||
|
if (event.isCancelled()) {
|
||||||
|
event.setCancelled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler (priority = EventPriority.MONITOR, ignoreCancelled = false)
|
||||||
|
public void onProjectileLaunch(ProjectileLaunchEvent event) {
|
||||||
|
if (nmsManager.isNMSEntityBase(event.getEntity())) {
|
||||||
|
if (event.isCancelled()) {
|
||||||
|
event.setCancelled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler (priority = EventPriority.MONITOR, ignoreCancelled = false)
|
||||||
|
public void onItemSpawn(ItemSpawnEvent event) {
|
||||||
|
if (nmsManager.isNMSEntityBase(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) {
|
||||||
|
|
||||||
|
NMSEntityBase entityBase = nmsManager.getNMSEntityBase(event.getRightClicked());
|
||||||
|
if (entityBase == null) return;
|
||||||
|
|
||||||
|
if (entityBase.getHologramLine() instanceof CraftTouchSlimeLine) {
|
||||||
|
|
||||||
|
CraftTouchSlimeLine touchSlime = (CraftTouchSlimeLine) entityBase.getHologramLine();
|
||||||
|
|
||||||
|
if (touchSlime.getTouchablePiece().getTouchHandler() != null && touchSlime.getParent().getVisibilityManager().isVisibleTo(event.getPlayer())) {
|
||||||
|
|
||||||
|
Long lastClick = anticlickSpam.get(event.getPlayer());
|
||||||
|
if (lastClick != null && System.currentTimeMillis() - lastClick.longValue() < 100) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
anticlickSpam.put(event.getPlayer(), System.currentTimeMillis());
|
||||||
|
|
||||||
|
try {
|
||||||
|
touchSlime.getTouchablePiece().getTouchHandler().onTouch(event.getPlayer());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Plugin plugin = touchSlime.getParent() instanceof PluginHologram ? ((PluginHologram) touchSlime.getParent()).getOwner() : HolographicDisplays.getInstance();
|
||||||
|
HolographicDisplays.getInstance().getLogger().log(Level.WARNING, "The plugin " + plugin.getName() + " generated an exception when the player " + event.getPlayer().getName() + " touched a hologram.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void handleItemLinePickup(Player player, PickupHandler pickupHandler, CraftHologram hologram) {
|
||||||
|
try {
|
||||||
|
if (hologram.getVisibilityManager().isVisibleTo(player)) {
|
||||||
|
pickupHandler.onPickup(player);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Plugin plugin = hologram instanceof PluginHologram ? ((PluginHologram) hologram).getOwner() : HolographicDisplays.getInstance();
|
||||||
|
HolographicDisplays.getInstance().getLogger().log(Level.WARNING, "The plugin " + plugin.getName() + " generated an exception when the player " + player.getName() + " picked up an item from a hologram.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onJoin(PlayerJoinEvent event) {
|
||||||
|
if (Configuration.updateNotification && HolographicDisplays.getNewVersion() != null) {
|
||||||
|
if (event.getPlayer().hasPermission(Strings.BASE_PERM + "update")) {
|
||||||
|
event.getPlayer().sendMessage(Colors.PRIMARY_SHADOW + "[HolographicDisplays] " + Colors.PRIMARY + "Found an update: " + HolographicDisplays.getNewVersion() + ". Download:");
|
||||||
|
event.getPlayer().sendMessage(Colors.PRIMARY_SHADOW + ">> " + Colors.PRIMARY + "http://dev.bukkit.org/bukkit-plugins/holographic-displays");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onLeave(PlayerQuitEvent event) {
|
||||||
|
anticlickSpam.remove(event.getPlayer());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,514 @@
|
|||||||
|
/*
|
||||||
|
* 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.holographicdisplays.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");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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;
|
||||||
|
|
||||||
|
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 tooltip(final String text);
|
||||||
|
|
||||||
|
public FancyMessage then(final Object obj);
|
||||||
|
|
||||||
|
public String toJSONString();
|
||||||
|
|
||||||
|
public void send(Player player);
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.interfaces;
|
||||||
|
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSHorse;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSItem;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSSlime;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSWitherSkull;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine;
|
||||||
|
|
||||||
|
public interface NMSManager {
|
||||||
|
|
||||||
|
// A method to register all the custom entities of the plugin, it may fail.
|
||||||
|
public void registerCustomEntities() throws Exception;
|
||||||
|
|
||||||
|
public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, CraftHologramLine parentPiece);
|
||||||
|
|
||||||
|
public NMSHorse spawnNMSHorse(org.bukkit.World world, double x, double y, double z, CraftHologramLine parentPiece);
|
||||||
|
|
||||||
|
public NMSWitherSkull spawnNMSWitherSkull(org.bukkit.World bukkitWorld, double x, double y, double z, CraftHologramLine parentPiece);
|
||||||
|
|
||||||
|
public NMSItem spawnNMSItem(org.bukkit.World bukkitWorld, double x, double y, double z, CraftItemLine parentPiece, ItemStack stack);
|
||||||
|
|
||||||
|
public NMSSlime spawnNMSSlime(org.bukkit.World bukkitWorld, double x, double y, double z, CraftTouchSlimeLine parentPiece);
|
||||||
|
|
||||||
|
public boolean isNMSEntityBase(org.bukkit.entity.Entity bukkitEntity);
|
||||||
|
|
||||||
|
public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity);
|
||||||
|
|
||||||
|
public FancyMessage newFancyMessage(String text);
|
||||||
|
|
||||||
|
public boolean hasChatHoverFeature();
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.interfaces.entity;
|
||||||
|
|
||||||
|
public interface NMSArmorStand extends NMSNameable, NMSRideable {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.interfaces.entity;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface to represent a custom NMS entity being part of a hologram.
|
||||||
|
*/
|
||||||
|
public interface NMSEntityBase {
|
||||||
|
|
||||||
|
// Returns the linked CraftHologramLine, all the entities are part of a piece. Should never be null.
|
||||||
|
public CraftHologramLine getHologramLine();
|
||||||
|
|
||||||
|
// Sets if the entity should tick or not.
|
||||||
|
public void setLockTick(boolean lock);
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
// Kills the entity through NMS.
|
||||||
|
public void killEntityNMS();
|
||||||
|
|
||||||
|
// The entity ID.
|
||||||
|
public int getIdNMS();
|
||||||
|
|
||||||
|
// Returns the bukkit entity.
|
||||||
|
public org.bukkit.entity.Entity getBukkitEntityNMS();
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.interfaces.entity;
|
||||||
|
|
||||||
|
public interface NMSHorse extends NMSNameable {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.interfaces.entity;
|
||||||
|
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
public interface NMSItem extends NMSEntityBase {
|
||||||
|
|
||||||
|
// Sets the bukkit ItemStack for this item.
|
||||||
|
public void setItemStackNMS(ItemStack stack);
|
||||||
|
|
||||||
|
// Sets if this item can be picked up by players.
|
||||||
|
public void allowPickup(boolean pickup);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.interfaces.entity;
|
||||||
|
|
||||||
|
public interface NMSNameable extends NMSEntityBase {
|
||||||
|
|
||||||
|
// Sets a custom name for this entity.
|
||||||
|
public void setCustomNameNMS(String name);
|
||||||
|
|
||||||
|
// Returns the custom name of this entity.
|
||||||
|
public String getCustomNameNMS();
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.interfaces.entity;
|
||||||
|
|
||||||
|
public interface NMSRideable extends NMSEntityBase {
|
||||||
|
|
||||||
|
// Sets the passenger of this entity through NMS.
|
||||||
|
public void setPassengerNMS(NMSEntityBase passenger);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.interfaces.entity;
|
||||||
|
|
||||||
|
public interface NMSSlime extends NMSEntityBase {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.interfaces.entity;
|
||||||
|
|
||||||
|
public interface NMSWitherSkull extends NMSRideable {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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 CraftNMSHorse extends CraftHorse {
|
||||||
|
|
||||||
|
public CraftNMSHorse(CraftServer server, EntityNMSHorse 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) { }
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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 CraftNMSItem extends CraftItem {
|
||||||
|
|
||||||
|
public CraftNMSItem(CraftServer server, EntityNMSItem 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) { }
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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 CraftNMSSlime extends CraftSlime {
|
||||||
|
|
||||||
|
public CraftNMSSlime(CraftServer server, EntityNMSSlime 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) { }
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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 CraftNMSWitherSkull extends CraftWitherSkull {
|
||||||
|
|
||||||
|
public CraftNMSWitherSkull(CraftServer server, EntityNMSWitherSkull 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) { }
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,157 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_6_R3;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_6_R3.EntityHorse;
|
||||||
|
import net.minecraft.server.v1_6_R3.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_6_R3.World;
|
||||||
|
|
||||||
|
import org.bukkit.craftbukkit.v1_6_R3.entity.CraftEntity;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSHorse;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
|
||||||
|
|
||||||
|
public class EntityNMSHorse extends EntityHorse implements NMSHorse {
|
||||||
|
|
||||||
|
private boolean lockTick;
|
||||||
|
private CraftHologramLine parentPiece;
|
||||||
|
|
||||||
|
public EntityNMSHorse(World world, CraftHologramLine parentPiece) {
|
||||||
|
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.
|
||||||
|
this.parentPiece = parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 setCustomNameNMS(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 CraftNMSHorse(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 int getIdNMS() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CraftHologramLine getHologramLine() {
|
||||||
|
return parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.bukkit.entity.Entity getBukkitEntityNMS() {
|
||||||
|
return getBukkitEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,183 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_6_R3;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_6_R3.Block;
|
||||||
|
import net.minecraft.server.v1_6_R3.EntityHuman;
|
||||||
|
import net.minecraft.server.v1_6_R3.EntityItem;
|
||||||
|
import net.minecraft.server.v1_6_R3.EntityPlayer;
|
||||||
|
import net.minecraft.server.v1_6_R3.ItemStack;
|
||||||
|
import net.minecraft.server.v1_6_R3.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_6_R3.NBTTagList;
|
||||||
|
import net.minecraft.server.v1_6_R3.NBTTagString;
|
||||||
|
import net.minecraft.server.v1_6_R3.World;
|
||||||
|
|
||||||
|
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.holographicdisplays.listener.MainListener;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSItem;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.ItemUtils;
|
||||||
|
|
||||||
|
public class EntityNMSItem extends EntityItem implements NMSItem {
|
||||||
|
|
||||||
|
private boolean lockTick;
|
||||||
|
private CraftItemLine parentPiece;
|
||||||
|
|
||||||
|
public EntityNMSItem(World world, CraftItemLine piece) {
|
||||||
|
super(world);
|
||||||
|
super.pickupDelay = Integer.MAX_VALUE;
|
||||||
|
this.parentPiece = piece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 (parentPiece.getPickupHandler() != null && human instanceof EntityPlayer) {
|
||||||
|
MainListener.handleItemLinePickup((Player) human.getBukkitEntity(), parentPiece.getPickupHandler(), parentPiece.getParent());
|
||||||
|
// 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 CraftNMSItem(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 int getIdNMS() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CraftItemLine getHologramLine() {
|
||||||
|
return parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void allowPickup(boolean pickup) {
|
||||||
|
if (pickup) {
|
||||||
|
super.pickupDelay = 0;
|
||||||
|
} else {
|
||||||
|
super.pickupDelay = Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.bukkit.entity.Entity getBukkitEntityNMS() {
|
||||||
|
return getBukkitEntity();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,144 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_6_R3;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_6_R3.EntitySlime;
|
||||||
|
import net.minecraft.server.v1_6_R3.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_6_R3.World;
|
||||||
|
|
||||||
|
import org.bukkit.craftbukkit.v1_6_R3.entity.CraftEntity;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSSlime;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine;
|
||||||
|
|
||||||
|
public class EntityNMSSlime extends EntitySlime implements NMSSlime {
|
||||||
|
|
||||||
|
private boolean lockTick;
|
||||||
|
private CraftTouchSlimeLine parentPiece;
|
||||||
|
|
||||||
|
public EntityNMSSlime(World world, CraftTouchSlimeLine parentPiece) {
|
||||||
|
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);
|
||||||
|
this.parentPiece = parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 CraftNMSSlime(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 int getIdNMS() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CraftHologramLine getHologramLine() {
|
||||||
|
return parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.bukkit.entity.Entity getBukkitEntityNMS() {
|
||||||
|
return getBukkitEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,177 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_6_R3;
|
||||||
|
|
||||||
|
import org.bukkit.craftbukkit.v1_6_R3.entity.CraftEntity;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSWitherSkull;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.Utils;
|
||||||
|
|
||||||
|
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 EntityNMSWitherSkull extends EntityWitherSkull implements NMSWitherSkull {
|
||||||
|
|
||||||
|
private boolean lockTick;
|
||||||
|
private CraftHologramLine parentPiece;
|
||||||
|
|
||||||
|
private int teleportedRecently;
|
||||||
|
|
||||||
|
public EntityNMSWitherSkull(World world, CraftHologramLine parentPiece) {
|
||||||
|
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);
|
||||||
|
this.parentPiece = parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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_() {
|
||||||
|
// Fixed the position being modified by random move packets.
|
||||||
|
if (teleportedRecently != -1) {
|
||||||
|
if (teleportedRecently++ > 10) {
|
||||||
|
teleportedRecently = -1;
|
||||||
|
Packet34EntityTeleport teleportPacket = new Packet34EntityTeleport(this);
|
||||||
|
|
||||||
|
for (Object obj : this.world.players) {
|
||||||
|
if (obj instanceof EntityPlayer) {
|
||||||
|
EntityPlayer nmsPlayer = (EntityPlayer) obj;
|
||||||
|
|
||||||
|
double distanceSquared = Utils.square(nmsPlayer.locX - this.locX) + Utils.square(nmsPlayer.locZ - this.locZ);
|
||||||
|
if (distanceSquared < 8192 && nmsPlayer.playerConnection != null) {
|
||||||
|
nmsPlayer.playerConnection.sendPacket(teleportPacket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 CraftNMSWitherSkull(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);
|
||||||
|
|
||||||
|
teleportedRecently = 0;
|
||||||
|
|
||||||
|
// Send a packet near 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 = Utils.square(nmsPlayer.locX - this.locX) + Utils.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(NMSEntityBase passenger) {
|
||||||
|
if (passenger instanceof Entity) {
|
||||||
|
((Entity) passenger).setPassengerOf(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIdNMS() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CraftHologramLine getHologramLine() {
|
||||||
|
return parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.bukkit.entity.Entity getBukkitEntityNMS() {
|
||||||
|
return getBukkitEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,95 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_6_R3;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.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));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl color(final ChatColor color) {
|
||||||
|
if (!color.isColor()) {
|
||||||
|
throw new IllegalArgumentException(color.name() + " is not a color");
|
||||||
|
}
|
||||||
|
latest().color = color;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl file(final String path) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl link(final String url) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl suggest(final String command) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl command(final String command) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl tooltip(final String text) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl then(final Object obj) {
|
||||||
|
messageParts.add(new MessagePart(obj.toString()));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void send(Player player) {
|
||||||
|
player.sendMessage(toJSONString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private MessagePart latest() {
|
||||||
|
return messageParts.get(messageParts.size() - 1);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,127 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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.holographicdisplays.nms.interfaces.FancyMessage;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.NMSManager;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSHorse;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSItem;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSWitherSkull;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.DebugHandler;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.ReflectionUtils;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.VersionUtils;
|
||||||
|
|
||||||
|
public class NmsManagerImpl implements NMSManager {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerCustomEntities() throws Exception {
|
||||||
|
registerCustomEntity(EntityNMSHorse.class, "EntityHorse", 100);
|
||||||
|
registerCustomEntity(EntityNMSWitherSkull.class, "WitherSkull", 19);
|
||||||
|
registerCustomEntity(EntityNMSItem.class, "Item", 1);
|
||||||
|
registerCustomEntity(EntityNMSSlime.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 NMSHorse spawnNMSHorse(org.bukkit.World world, double x, double y, double z, CraftHologramLine parentPiece) {
|
||||||
|
WorldServer nmsWorld = ((CraftWorld) world).getHandle();
|
||||||
|
EntityNMSHorse invisibleHorse = new EntityNMSHorse(nmsWorld, parentPiece);
|
||||||
|
invisibleHorse.setLocationNMS(x, y, z);
|
||||||
|
if (!nmsWorld.addEntity(invisibleHorse, SpawnReason.CUSTOM)) {
|
||||||
|
DebugHandler.handleSpawnFail(parentPiece);
|
||||||
|
}
|
||||||
|
return invisibleHorse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NMSWitherSkull spawnNMSWitherSkull(org.bukkit.World bukkitWorld, double x, double y, double z, CraftHologramLine parentPiece) {
|
||||||
|
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
|
||||||
|
EntityNMSWitherSkull staticWitherSkull = new EntityNMSWitherSkull(nmsWorld, parentPiece);
|
||||||
|
staticWitherSkull.setLocationNMS(x, y, z);
|
||||||
|
if (!nmsWorld.addEntity(staticWitherSkull, SpawnReason.CUSTOM)) {
|
||||||
|
DebugHandler.handleSpawnFail(parentPiece);
|
||||||
|
}
|
||||||
|
return staticWitherSkull;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NMSItem spawnNMSItem(org.bukkit.World bukkitWorld, double x, double y, double z, CraftItemLine parentPiece, ItemStack stack) {
|
||||||
|
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
|
||||||
|
EntityNMSItem customItem = new EntityNMSItem(nmsWorld, parentPiece);
|
||||||
|
customItem.setLocationNMS(x, y, z);
|
||||||
|
customItem.setItemStackNMS(stack);
|
||||||
|
if (!nmsWorld.addEntity(customItem, SpawnReason.CUSTOM)) {
|
||||||
|
DebugHandler.handleSpawnFail(parentPiece);
|
||||||
|
}
|
||||||
|
return customItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityNMSSlime spawnNMSSlime(org.bukkit.World bukkitWorld, double x, double y, double z, CraftTouchSlimeLine parentPiece) {
|
||||||
|
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
|
||||||
|
EntityNMSSlime touchSlime = new EntityNMSSlime(nmsWorld, parentPiece);
|
||||||
|
touchSlime.setLocationNMS(x, y, z);
|
||||||
|
if (!nmsWorld.addEntity(touchSlime, SpawnReason.CUSTOM)) {
|
||||||
|
DebugHandler.handleSpawnFail(parentPiece);
|
||||||
|
}
|
||||||
|
return touchSlime;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
|
||||||
|
return ((CraftEntity) bukkitEntity).getHandle() instanceof NMSEntityBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
|
||||||
|
|
||||||
|
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
|
||||||
|
if (nmsEntity instanceof NMSEntityBase) {
|
||||||
|
return ((NMSEntityBase) nmsEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessage newFancyMessage(String text) {
|
||||||
|
return new FancyMessageImpl(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasChatHoverFeature() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NMSArmorStand spawnNMSArmorStand(World world, double x, double y, double z, CraftHologramLine parentPiece) {
|
||||||
|
throw new NotImplementedException("Method can only be used on 1.8 or higher");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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 CraftNMSHorse extends CraftHorse {
|
||||||
|
|
||||||
|
public CraftNMSHorse(CraftServer server, EntityNMSHorse 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) { }
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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 CraftNMSItem extends CraftItem {
|
||||||
|
|
||||||
|
public CraftNMSItem(CraftServer server, EntityNMSItem 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) { }
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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 CraftNMSSlime extends CraftSlime {
|
||||||
|
|
||||||
|
public CraftNMSSlime(CraftServer server, EntityNMSSlime 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) { }
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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 CraftNMSWitherSkull extends CraftWitherSkull {
|
||||||
|
|
||||||
|
public CraftNMSWitherSkull(CraftServer server, EntityNMSWitherSkull 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) { }
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,156 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_7_R1;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_7_R1.EntityHorse;
|
||||||
|
import net.minecraft.server.v1_7_R1.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_7_R1.World;
|
||||||
|
|
||||||
|
import org.bukkit.craftbukkit.v1_7_R1.entity.CraftEntity;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSHorse;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
|
||||||
|
|
||||||
|
public class EntityNMSHorse extends EntityHorse implements NMSHorse {
|
||||||
|
|
||||||
|
private boolean lockTick;
|
||||||
|
private CraftHologramLine parentPiece;
|
||||||
|
|
||||||
|
public EntityNMSHorse(World world, CraftHologramLine parentPiece) {
|
||||||
|
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.
|
||||||
|
this.parentPiece = parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 setCustomNameNMS(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 CraftNMSHorse(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 int getIdNMS() {
|
||||||
|
return this.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CraftHologramLine getHologramLine() {
|
||||||
|
return parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.bukkit.entity.Entity getBukkitEntityNMS() {
|
||||||
|
return getBukkitEntity();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,183 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_7_R1;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_7_R1.Blocks;
|
||||||
|
import net.minecraft.server.v1_7_R1.EntityHuman;
|
||||||
|
import net.minecraft.server.v1_7_R1.EntityItem;
|
||||||
|
import net.minecraft.server.v1_7_R1.EntityPlayer;
|
||||||
|
import net.minecraft.server.v1_7_R1.ItemStack;
|
||||||
|
import net.minecraft.server.v1_7_R1.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_7_R1.NBTTagList;
|
||||||
|
import net.minecraft.server.v1_7_R1.NBTTagString;
|
||||||
|
import net.minecraft.server.v1_7_R1.World;
|
||||||
|
|
||||||
|
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.holographicdisplays.listener.MainListener;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSItem;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.ItemUtils;
|
||||||
|
|
||||||
|
public class EntityNMSItem extends EntityItem implements NMSItem {
|
||||||
|
|
||||||
|
private boolean lockTick;
|
||||||
|
private CraftItemLine parentPiece;
|
||||||
|
|
||||||
|
public EntityNMSItem(World world, CraftItemLine piece) {
|
||||||
|
super(world);
|
||||||
|
super.pickupDelay = Integer.MAX_VALUE;
|
||||||
|
this.parentPiece = piece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 (parentPiece.getPickupHandler() != null && human instanceof EntityPlayer) {
|
||||||
|
MainListener.handleItemLinePickup((Player) human.getBukkitEntity(), parentPiece.getPickupHandler(), parentPiece.getParent());
|
||||||
|
// 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 CraftNMSItem(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 int getIdNMS() {
|
||||||
|
return this.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CraftItemLine getHologramLine() {
|
||||||
|
return parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void allowPickup(boolean pickup) {
|
||||||
|
if (pickup) {
|
||||||
|
super.pickupDelay = 0;
|
||||||
|
} else {
|
||||||
|
super.pickupDelay = Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.bukkit.entity.Entity getBukkitEntityNMS() {
|
||||||
|
return getBukkitEntity();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,144 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_7_R1;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_7_R1.EntitySlime;
|
||||||
|
import net.minecraft.server.v1_7_R1.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_7_R1.World;
|
||||||
|
|
||||||
|
import org.bukkit.craftbukkit.v1_7_R1.entity.CraftEntity;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSSlime;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine;
|
||||||
|
|
||||||
|
public class EntityNMSSlime extends EntitySlime implements NMSSlime {
|
||||||
|
|
||||||
|
private boolean lockTick;
|
||||||
|
private CraftTouchSlimeLine parentPiece;
|
||||||
|
|
||||||
|
public EntityNMSSlime(World world, CraftTouchSlimeLine parentPiece) {
|
||||||
|
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);
|
||||||
|
this.parentPiece = parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 CraftNMSSlime(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 int getIdNMS() {
|
||||||
|
return this.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CraftHologramLine getHologramLine() {
|
||||||
|
return parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.bukkit.entity.Entity getBukkitEntityNMS() {
|
||||||
|
return getBukkitEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,166 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_7_R1;
|
||||||
|
|
||||||
|
import org.bukkit.craftbukkit.v1_7_R1.entity.CraftEntity;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSWitherSkull;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.Utils;
|
||||||
|
|
||||||
|
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.PacketPlayOutEntityTeleport;
|
||||||
|
import net.minecraft.server.v1_7_R1.World;
|
||||||
|
import net.minecraft.server.v1_7_R1.EntityPlayer;
|
||||||
|
|
||||||
|
public class EntityNMSWitherSkull extends EntityWitherSkull implements NMSWitherSkull {
|
||||||
|
|
||||||
|
private boolean lockTick;
|
||||||
|
private CraftHologramLine parentPiece;
|
||||||
|
|
||||||
|
public EntityNMSWitherSkull(World world, CraftHologramLine parentPiece) {
|
||||||
|
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);
|
||||||
|
this.parentPiece = parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 int getId() {
|
||||||
|
|
||||||
|
StackTraceElement[] elements = Thread.currentThread().getStackTrace();
|
||||||
|
if (elements.length > 2 && elements[2] != null && elements[2].getFileName().equals("EntityTrackerEntry.java") && elements[2].getLineNumber() > 134 && elements[2].getLineNumber() < 144) {
|
||||||
|
// Then this method is being called when creating a new packet, we return a fake ID!
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 CraftNMSWitherSkull(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);
|
||||||
|
|
||||||
|
// Send a packet near 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 = Utils.square(nmsPlayer.locX - this.locX) + Utils.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(NMSEntityBase passenger) {
|
||||||
|
if (passenger instanceof Entity) {
|
||||||
|
((Entity) passenger).setPassengerOf(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIdNMS() {
|
||||||
|
return this.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CraftHologramLine getHologramLine() {
|
||||||
|
return parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.bukkit.entity.Entity getBukkitEntityNMS() {
|
||||||
|
return getBukkitEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,125 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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.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.entity.Player;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.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));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl color(ChatColor color) {
|
||||||
|
if (!color.isColor()) {
|
||||||
|
throw new IllegalArgumentException(color.name() + " is not a color");
|
||||||
|
}
|
||||||
|
latest().color = color;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl file(String path) {
|
||||||
|
onClick("open_file", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl link(String url) {
|
||||||
|
onClick("open_url", url);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl suggest(String command) {
|
||||||
|
onClick("suggest_command", command);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl command(String command) {
|
||||||
|
onClick("run_command", command);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl tooltip(String text) {
|
||||||
|
onHover("show_text", text);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl then(Object obj) {
|
||||||
|
messageParts.add(new MessagePart(obj.toString()));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,127 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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.holographicdisplays.nms.interfaces.FancyMessage;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.NMSManager;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSHorse;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSItem;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSWitherSkull;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.DebugHandler;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.ReflectionUtils;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.VersionUtils;
|
||||||
|
|
||||||
|
public class NmsManagerImpl implements NMSManager {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerCustomEntities() throws Exception {
|
||||||
|
registerCustomEntity(EntityNMSHorse.class, "EntityHorse", 100);
|
||||||
|
registerCustomEntity(EntityNMSWitherSkull.class, "WitherSkull", 19);
|
||||||
|
registerCustomEntity(EntityNMSItem.class, "Item", 1);
|
||||||
|
registerCustomEntity(EntityNMSSlime.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 NMSHorse spawnNMSHorse(org.bukkit.World world, double x, double y, double z, CraftHologramLine parentPiece) {
|
||||||
|
WorldServer nmsWorld = ((CraftWorld) world).getHandle();
|
||||||
|
EntityNMSHorse invisibleHorse = new EntityNMSHorse(nmsWorld, parentPiece);
|
||||||
|
invisibleHorse.setLocationNMS(x, y, z);
|
||||||
|
if (!nmsWorld.addEntity(invisibleHorse, SpawnReason.CUSTOM)) {
|
||||||
|
DebugHandler.handleSpawnFail(parentPiece);
|
||||||
|
}
|
||||||
|
return invisibleHorse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NMSWitherSkull spawnNMSWitherSkull(org.bukkit.World bukkitWorld, double x, double y, double z, CraftHologramLine parentPiece) {
|
||||||
|
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
|
||||||
|
EntityNMSWitherSkull staticWitherSkull = new EntityNMSWitherSkull(nmsWorld, parentPiece);
|
||||||
|
staticWitherSkull.setLocationNMS(x, y, z);
|
||||||
|
if (!nmsWorld.addEntity(staticWitherSkull, SpawnReason.CUSTOM)) {
|
||||||
|
DebugHandler.handleSpawnFail(parentPiece);
|
||||||
|
}
|
||||||
|
return staticWitherSkull;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NMSItem spawnNMSItem(org.bukkit.World bukkitWorld, double x, double y, double z, CraftItemLine parentPiece, ItemStack stack) {
|
||||||
|
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
|
||||||
|
EntityNMSItem customItem = new EntityNMSItem(nmsWorld, parentPiece);
|
||||||
|
customItem.setLocationNMS(x, y, z);
|
||||||
|
customItem.setItemStackNMS(stack);
|
||||||
|
if (!nmsWorld.addEntity(customItem, SpawnReason.CUSTOM)) {
|
||||||
|
DebugHandler.handleSpawnFail(parentPiece);
|
||||||
|
}
|
||||||
|
return customItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityNMSSlime spawnNMSSlime(org.bukkit.World bukkitWorld, double x, double y, double z, CraftTouchSlimeLine parentPiece) {
|
||||||
|
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
|
||||||
|
EntityNMSSlime touchSlime = new EntityNMSSlime(nmsWorld, parentPiece);
|
||||||
|
touchSlime.setLocationNMS(x, y, z);
|
||||||
|
if (!nmsWorld.addEntity(touchSlime, SpawnReason.CUSTOM)) {
|
||||||
|
DebugHandler.handleSpawnFail(parentPiece);
|
||||||
|
}
|
||||||
|
return touchSlime;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
|
||||||
|
return ((CraftEntity) bukkitEntity).getHandle() instanceof NMSEntityBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
|
||||||
|
|
||||||
|
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
|
||||||
|
if (nmsEntity instanceof NMSEntityBase) {
|
||||||
|
return ((NMSEntityBase) nmsEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessage newFancyMessage(String text) {
|
||||||
|
return new FancyMessageImpl(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasChatHoverFeature() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NMSArmorStand spawnNMSArmorStand(World world, double x, double y, double z, CraftHologramLine parentPiece) {
|
||||||
|
throw new NotImplementedException("Method can only be used on 1.8 or higher");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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 CraftNMSHorse extends CraftHorse {
|
||||||
|
|
||||||
|
public CraftNMSHorse(CraftServer server, EntityNMSHorse 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) { }
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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 CraftNMSItem extends CraftItem {
|
||||||
|
|
||||||
|
public CraftNMSItem(CraftServer server, EntityNMSItem 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) { }
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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 CraftNMSSlime extends CraftSlime {
|
||||||
|
|
||||||
|
public CraftNMSSlime(CraftServer server, EntityNMSSlime 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) { }
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.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 CraftNMSWitherSkull extends CraftWitherSkull {
|
||||||
|
|
||||||
|
public CraftNMSWitherSkull(CraftServer server, EntityNMSWitherSkull 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) { }
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,157 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_7_R2;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_7_R2.EntityHorse;
|
||||||
|
import net.minecraft.server.v1_7_R2.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_7_R2.World;
|
||||||
|
|
||||||
|
import org.bukkit.craftbukkit.v1_7_R2.entity.CraftEntity;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSHorse;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
|
||||||
|
|
||||||
|
public class EntityNMSHorse extends EntityHorse implements NMSHorse {
|
||||||
|
|
||||||
|
private boolean lockTick;
|
||||||
|
private CraftHologramLine parentPiece;
|
||||||
|
|
||||||
|
public EntityNMSHorse(World world, CraftHologramLine parentPiece) {
|
||||||
|
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.
|
||||||
|
this.parentPiece = parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 setCustomNameNMS(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 CraftNMSHorse(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 int getIdNMS() {
|
||||||
|
return this.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CraftHologramLine getHologramLine() {
|
||||||
|
return parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.bukkit.entity.Entity getBukkitEntityNMS() {
|
||||||
|
return getBukkitEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,183 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_7_R2;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_7_R2.Blocks;
|
||||||
|
import net.minecraft.server.v1_7_R2.EntityHuman;
|
||||||
|
import net.minecraft.server.v1_7_R2.EntityItem;
|
||||||
|
import net.minecraft.server.v1_7_R2.EntityPlayer;
|
||||||
|
import net.minecraft.server.v1_7_R2.ItemStack;
|
||||||
|
import net.minecraft.server.v1_7_R2.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_7_R2.NBTTagList;
|
||||||
|
import net.minecraft.server.v1_7_R2.NBTTagString;
|
||||||
|
import net.minecraft.server.v1_7_R2.World;
|
||||||
|
|
||||||
|
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.holographicdisplays.listener.MainListener;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSItem;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.ItemUtils;
|
||||||
|
|
||||||
|
public class EntityNMSItem extends EntityItem implements NMSItem {
|
||||||
|
|
||||||
|
private boolean lockTick;
|
||||||
|
private CraftItemLine parentPiece;
|
||||||
|
|
||||||
|
public EntityNMSItem(World world, CraftItemLine piece) {
|
||||||
|
super(world);
|
||||||
|
super.pickupDelay = Integer.MAX_VALUE;
|
||||||
|
this.parentPiece = piece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 (parentPiece.getPickupHandler() != null && human instanceof EntityPlayer) {
|
||||||
|
MainListener.handleItemLinePickup((Player) human.getBukkitEntity(), parentPiece.getPickupHandler(), parentPiece.getParent());
|
||||||
|
// 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 CraftNMSItem(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 int getIdNMS() {
|
||||||
|
return this.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CraftItemLine getHologramLine() {
|
||||||
|
return parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void allowPickup(boolean pickup) {
|
||||||
|
if (pickup) {
|
||||||
|
super.pickupDelay = 0;
|
||||||
|
} else {
|
||||||
|
super.pickupDelay = Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.bukkit.entity.Entity getBukkitEntityNMS() {
|
||||||
|
return getBukkitEntity();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,144 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_7_R2;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_7_R2.EntitySlime;
|
||||||
|
import net.minecraft.server.v1_7_R2.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_7_R2.World;
|
||||||
|
|
||||||
|
import org.bukkit.craftbukkit.v1_7_R2.entity.CraftEntity;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSSlime;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine;
|
||||||
|
|
||||||
|
public class EntityNMSSlime extends EntitySlime implements NMSSlime {
|
||||||
|
|
||||||
|
private boolean lockTick;
|
||||||
|
private CraftTouchSlimeLine parentPiece;
|
||||||
|
|
||||||
|
public EntityNMSSlime(World world, CraftTouchSlimeLine parentPiece) {
|
||||||
|
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);
|
||||||
|
this.parentPiece = parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 CraftNMSSlime(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 int getIdNMS() {
|
||||||
|
return this.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CraftHologramLine getHologramLine() {
|
||||||
|
return parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.bukkit.entity.Entity getBukkitEntityNMS() {
|
||||||
|
return getBukkitEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,168 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_7_R2;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_7_R2.Entity;
|
||||||
|
import net.minecraft.server.v1_7_R2.EntityPlayer;
|
||||||
|
import net.minecraft.server.v1_7_R2.EntityWitherSkull;
|
||||||
|
import net.minecraft.server.v1_7_R2.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_7_R2.PacketPlayOutEntityTeleport;
|
||||||
|
import net.minecraft.server.v1_7_R2.World;
|
||||||
|
|
||||||
|
import org.bukkit.craftbukkit.v1_7_R2.entity.CraftEntity;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSWitherSkull;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.Utils;
|
||||||
|
|
||||||
|
public class EntityNMSWitherSkull extends EntityWitherSkull implements NMSWitherSkull {
|
||||||
|
|
||||||
|
private boolean lockTick;
|
||||||
|
private CraftHologramLine parentPiece;
|
||||||
|
|
||||||
|
public EntityNMSWitherSkull(World world, CraftHologramLine parentPiece) {
|
||||||
|
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);
|
||||||
|
this.parentPiece = parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@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 int getId() {
|
||||||
|
|
||||||
|
StackTraceElement[] elements = Thread.currentThread().getStackTrace();
|
||||||
|
if (elements.length > 2 && elements[2] != null && elements[2].getFileName().equals("EntityTrackerEntry.java") && elements[2].getLineNumber() > 134 && elements[2].getLineNumber() < 144) {
|
||||||
|
// Then this method is being called when creating a new packet, we return a fake ID!
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 CraftNMSWitherSkull(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);
|
||||||
|
|
||||||
|
// Send a packet near 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 = Utils.square(nmsPlayer.locX - this.locX) + Utils.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(NMSEntityBase passenger) {
|
||||||
|
if (passenger instanceof Entity) {
|
||||||
|
((Entity) passenger).setPassengerOf(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIdNMS() {
|
||||||
|
return this.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CraftHologramLine getHologramLine() {
|
||||||
|
return parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.bukkit.entity.Entity getBukkitEntityNMS() {
|
||||||
|
return getBukkitEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,125 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_7_R2;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_7_R2.ChatSerializer;
|
||||||
|
import net.minecraft.server.v1_7_R2.PacketPlayOutChat;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.craftbukkit.libs.com.google.gson.stream.JsonWriter;
|
||||||
|
import org.bukkit.craftbukkit.v1_7_R2.entity.CraftPlayer;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.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));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl color(ChatColor color) {
|
||||||
|
if (!color.isColor()) {
|
||||||
|
throw new IllegalArgumentException(color.name() + " is not a color");
|
||||||
|
}
|
||||||
|
latest().color = color;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl file(String path) {
|
||||||
|
onClick("open_file", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl link(String url) {
|
||||||
|
onClick("open_url", url);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl suggest(String command) {
|
||||||
|
onClick("suggest_command", command);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl command(String command) {
|
||||||
|
onClick("run_command", command);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl tooltip(String text) {
|
||||||
|
onHover("show_text", text);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessageImpl then(Object obj) {
|
||||||
|
messageParts.add(new MessagePart(obj.toString()));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,127 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_7_R2;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_7_R2.Entity;
|
||||||
|
import net.minecraft.server.v1_7_R2.EntityTypes;
|
||||||
|
import net.minecraft.server.v1_7_R2.WorldServer;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.NotImplementedException;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.craftbukkit.v1_7_R2.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.v1_7_R2.entity.CraftEntity;
|
||||||
|
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.FancyMessage;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.NMSManager;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSHorse;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSItem;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSWitherSkull;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.DebugHandler;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.ReflectionUtils;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.VersionUtils;
|
||||||
|
|
||||||
|
public class NmsManagerImpl implements NMSManager {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerCustomEntities() throws Exception {
|
||||||
|
registerCustomEntity(EntityNMSHorse.class, "EntityHorse", 100);
|
||||||
|
registerCustomEntity(EntityNMSWitherSkull.class, "WitherSkull", 19);
|
||||||
|
registerCustomEntity(EntityNMSItem.class, "Item", 1);
|
||||||
|
registerCustomEntity(EntityNMSSlime.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_R2.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 NMSHorse spawnNMSHorse(org.bukkit.World world, double x, double y, double z, CraftHologramLine parentPiece) {
|
||||||
|
WorldServer nmsWorld = ((CraftWorld) world).getHandle();
|
||||||
|
EntityNMSHorse invisibleHorse = new EntityNMSHorse(nmsWorld, parentPiece);
|
||||||
|
invisibleHorse.setLocationNMS(x, y, z);
|
||||||
|
if (!nmsWorld.addEntity(invisibleHorse, SpawnReason.CUSTOM)) {
|
||||||
|
DebugHandler.handleSpawnFail(parentPiece);
|
||||||
|
}
|
||||||
|
return invisibleHorse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NMSWitherSkull spawnNMSWitherSkull(org.bukkit.World bukkitWorld, double x, double y, double z, CraftHologramLine parentPiece) {
|
||||||
|
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
|
||||||
|
EntityNMSWitherSkull staticWitherSkull = new EntityNMSWitherSkull(nmsWorld, parentPiece);
|
||||||
|
staticWitherSkull.setLocationNMS(x, y, z);
|
||||||
|
if (!nmsWorld.addEntity(staticWitherSkull, SpawnReason.CUSTOM)) {
|
||||||
|
DebugHandler.handleSpawnFail(parentPiece);
|
||||||
|
}
|
||||||
|
return staticWitherSkull;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NMSItem spawnNMSItem(org.bukkit.World bukkitWorld, double x, double y, double z, CraftItemLine parentPiece, ItemStack stack) {
|
||||||
|
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
|
||||||
|
EntityNMSItem customItem = new EntityNMSItem(nmsWorld, parentPiece);
|
||||||
|
customItem.setLocationNMS(x, y, z);
|
||||||
|
customItem.setItemStackNMS(stack);
|
||||||
|
if (!nmsWorld.addEntity(customItem, SpawnReason.CUSTOM)) {
|
||||||
|
DebugHandler.handleSpawnFail(parentPiece);
|
||||||
|
}
|
||||||
|
return customItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityNMSSlime spawnNMSSlime(org.bukkit.World bukkitWorld, double x, double y, double z, CraftTouchSlimeLine parentPiece) {
|
||||||
|
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
|
||||||
|
EntityNMSSlime touchSlime = new EntityNMSSlime(nmsWorld, parentPiece);
|
||||||
|
touchSlime.setLocationNMS(x, y, z);
|
||||||
|
if (!nmsWorld.addEntity(touchSlime, SpawnReason.CUSTOM)) {
|
||||||
|
DebugHandler.handleSpawnFail(parentPiece);
|
||||||
|
}
|
||||||
|
return touchSlime;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
|
||||||
|
return ((CraftEntity) bukkitEntity).getHandle() instanceof NMSEntityBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
|
||||||
|
|
||||||
|
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
|
||||||
|
if (nmsEntity instanceof NMSEntityBase) {
|
||||||
|
return ((NMSEntityBase) nmsEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FancyMessage newFancyMessage(String text) {
|
||||||
|
return new FancyMessageImpl(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasChatHoverFeature() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NMSArmorStand spawnNMSArmorStand(World world, double x, double y, double z, CraftHologramLine parentPiece) {
|
||||||
|
throw new NotImplementedException("Method can only be used on 1.8 or higher");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_7_R3;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.bukkit.EntityEffect;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.craftbukkit.v1_7_R3.CraftServer;
|
||||||
|
import org.bukkit.craftbukkit.v1_7_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 CraftNMSHorse extends CraftHorse {
|
||||||
|
|
||||||
|
public CraftNMSHorse(CraftServer server, EntityNMSHorse 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) { }
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_7_R3;
|
||||||
|
|
||||||
|
import org.bukkit.EntityEffect;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.craftbukkit.v1_7_R3.CraftServer;
|
||||||
|
import org.bukkit.craftbukkit.v1_7_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 CraftNMSItem extends CraftItem {
|
||||||
|
|
||||||
|
public CraftNMSItem(CraftServer server, EntityNMSItem 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) { }
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_7_R3;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.bukkit.EntityEffect;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.craftbukkit.v1_7_R3.CraftServer;
|
||||||
|
import org.bukkit.craftbukkit.v1_7_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 CraftNMSSlime extends CraftSlime {
|
||||||
|
|
||||||
|
public CraftNMSSlime(CraftServer server, EntityNMSSlime 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) { }
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_7_R3;
|
||||||
|
|
||||||
|
import org.bukkit.EntityEffect;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.craftbukkit.v1_7_R3.CraftServer;
|
||||||
|
import org.bukkit.craftbukkit.v1_7_R3.entity.CraftWitherSkull;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
public class CraftNMSWitherSkull extends CraftWitherSkull {
|
||||||
|
|
||||||
|
public CraftNMSWitherSkull(CraftServer server, EntityNMSWitherSkull 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) { }
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,156 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_7_R3;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_7_R3.EntityHorse;
|
||||||
|
import net.minecraft.server.v1_7_R3.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_7_R3.World;
|
||||||
|
|
||||||
|
import org.bukkit.craftbukkit.v1_7_R3.entity.CraftEntity;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSHorse;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
|
||||||
|
|
||||||
|
public class EntityNMSHorse extends EntityHorse implements NMSHorse {
|
||||||
|
|
||||||
|
private boolean lockTick;
|
||||||
|
private CraftHologramLine parentPiece;
|
||||||
|
|
||||||
|
public EntityNMSHorse(World world, CraftHologramLine parentPiece) {
|
||||||
|
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.
|
||||||
|
this.parentPiece = parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 setCustomNameNMS(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 CraftNMSHorse(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 int getIdNMS() {
|
||||||
|
return this.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CraftHologramLine getHologramLine() {
|
||||||
|
return parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.bukkit.entity.Entity getBukkitEntityNMS() {
|
||||||
|
return getBukkitEntity();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,183 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_7_R3;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_7_R3.Blocks;
|
||||||
|
import net.minecraft.server.v1_7_R3.EntityHuman;
|
||||||
|
import net.minecraft.server.v1_7_R3.EntityItem;
|
||||||
|
import net.minecraft.server.v1_7_R3.EntityPlayer;
|
||||||
|
import net.minecraft.server.v1_7_R3.ItemStack;
|
||||||
|
import net.minecraft.server.v1_7_R3.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_7_R3.NBTTagList;
|
||||||
|
import net.minecraft.server.v1_7_R3.NBTTagString;
|
||||||
|
import net.minecraft.server.v1_7_R3.World;
|
||||||
|
|
||||||
|
import org.bukkit.craftbukkit.v1_7_R3.entity.CraftEntity;
|
||||||
|
import org.bukkit.craftbukkit.v1_7_R3.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.listener.MainListener;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSItem;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.ItemUtils;
|
||||||
|
|
||||||
|
public class EntityNMSItem extends EntityItem implements NMSItem {
|
||||||
|
|
||||||
|
private boolean lockTick;
|
||||||
|
private CraftItemLine parentPiece;
|
||||||
|
|
||||||
|
public EntityNMSItem(World world, CraftItemLine piece) {
|
||||||
|
super(world);
|
||||||
|
super.pickupDelay = Integer.MAX_VALUE;
|
||||||
|
this.parentPiece = piece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 (parentPiece.getPickupHandler() != null && human instanceof EntityPlayer) {
|
||||||
|
MainListener.handleItemLinePickup((Player) human.getBukkitEntity(), parentPiece.getPickupHandler(), parentPiece.getParent());
|
||||||
|
// 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 CraftNMSItem(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 int getIdNMS() {
|
||||||
|
return this.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CraftItemLine getHologramLine() {
|
||||||
|
return parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void allowPickup(boolean pickup) {
|
||||||
|
if (pickup) {
|
||||||
|
super.pickupDelay = 0;
|
||||||
|
} else {
|
||||||
|
super.pickupDelay = Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.bukkit.entity.Entity getBukkitEntityNMS() {
|
||||||
|
return getBukkitEntity();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,143 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_7_R3;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_7_R3.EntitySlime;
|
||||||
|
import net.minecraft.server.v1_7_R3.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_7_R3.World;
|
||||||
|
|
||||||
|
import org.bukkit.craftbukkit.v1_7_R3.entity.CraftEntity;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSSlime;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine;
|
||||||
|
|
||||||
|
public class EntityNMSSlime extends EntitySlime implements NMSSlime {
|
||||||
|
|
||||||
|
private boolean lockTick;
|
||||||
|
private CraftTouchSlimeLine parentPiece;
|
||||||
|
|
||||||
|
public EntityNMSSlime(World world, CraftTouchSlimeLine parentPiece) {
|
||||||
|
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);
|
||||||
|
this.parentPiece = parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 CraftNMSSlime(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 int getIdNMS() {
|
||||||
|
return this.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CraftHologramLine getHologramLine() {
|
||||||
|
return parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.bukkit.entity.Entity getBukkitEntityNMS() {
|
||||||
|
return getBukkitEntity();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,165 @@
|
|||||||
|
package com.gmail.filoghost.holographicdisplays.nms.v1_7_R3;
|
||||||
|
|
||||||
|
import org.bukkit.craftbukkit.v1_7_R3.entity.CraftEntity;
|
||||||
|
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSWitherSkull;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
|
||||||
|
import com.gmail.filoghost.holographicdisplays.util.Utils;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_7_R3.Entity;
|
||||||
|
import net.minecraft.server.v1_7_R3.EntityWitherSkull;
|
||||||
|
import net.minecraft.server.v1_7_R3.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_7_R3.PacketPlayOutEntityTeleport;
|
||||||
|
import net.minecraft.server.v1_7_R3.World;
|
||||||
|
import net.minecraft.server.v1_7_R3.EntityPlayer;
|
||||||
|
|
||||||
|
public class EntityNMSWitherSkull extends EntityWitherSkull implements NMSWitherSkull {
|
||||||
|
|
||||||
|
private boolean lockTick;
|
||||||
|
private CraftHologramLine parentPiece;
|
||||||
|
|
||||||
|
public EntityNMSWitherSkull(World world, CraftHologramLine parentPiece) {
|
||||||
|
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);
|
||||||
|
this.parentPiece = parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 int getId() {
|
||||||
|
|
||||||
|
StackTraceElement[] elements = Thread.currentThread().getStackTrace();
|
||||||
|
if (elements.length > 2 && elements[2] != null && elements[2].getFileName().equals("EntityTrackerEntry.java") && elements[2].getLineNumber() > 134 && elements[2].getLineNumber() < 144) {
|
||||||
|
// Then this method is being called when creating a new packet, we return a fake ID!
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 CraftNMSWitherSkull(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);
|
||||||
|
|
||||||
|
// Send a packet near 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 = Utils.square(nmsPlayer.locX - this.locX) + Utils.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(NMSEntityBase passenger) {
|
||||||
|
if (passenger instanceof Entity) {
|
||||||
|
((Entity) passenger).setPassengerOf(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIdNMS() {
|
||||||
|
return this.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CraftHologramLine getHologramLine() {
|
||||||
|
return parentPiece;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.bukkit.entity.Entity getBukkitEntityNMS() {
|
||||||
|
return getBukkitEntity();
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user