diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..e96534f --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Auction House.iml b/Auction House.iml index 1287a86..f6807d1 100644 --- a/Auction House.iml +++ b/Auction House.iml @@ -30,5 +30,6 @@ + \ No newline at end of file diff --git a/pom.xml b/pom.xml index f2c073f..133024c 100644 --- a/pom.xml +++ b/pom.xml @@ -72,5 +72,10 @@ 1.12.2-R0.1-SNAPSHOT provided + + commons-io + commons-io + 2.4 + diff --git a/src/main/java/com/massivestats/MassiveStats.java b/src/main/java/com/massivestats/MassiveStats.java new file mode 100644 index 0000000..8eb26dc --- /dev/null +++ b/src/main/java/com/massivestats/MassiveStats.java @@ -0,0 +1,490 @@ +/* + * Copyright 2018 (c) Massive Statistics LLC - All Rights Reserved + * This file may only be used in conjunction with the 'MassiveStats' service. + */ + +package com.massivestats; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitRunnable; + +import javax.net.ssl.HttpsURLConnection; +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; + +/** + * MassiveStats collects plugin and server information for plugin authors. + * You can learn more at our website: https://www.massivestats.com/ + * + * @version 3.0 + * @author Sam Jakob Harker, Brianna Hazel O'Keefe + */ +@SuppressWarnings("all") +public class MassiveStats implements Listener { + + /* START: MASSIVESTATS SETTINGS */ + public static final int CLIENT_VERSION = 0; // v3.0 + public static final String API_URL = "https://report.massivestats.com/v2/"; + + public static final String MASSIVE_UPDATE_PERMISSION = "massivestats.update"; + /* END: MASSIVESTATS SETTINGS */ + + private MassiveStatsUpdateTask task = null; + private int pingInterval; + + private MassiveStatsDataResponse lastResponse; + private boolean listenerDisabled; + + private final JavaPlugin plugin; + + private Class jsonElement; + private Class jsonParser; + private Class jsonObject; + private Class jsonPrimitive; + + /** + * @param plugin The plugin you wish to collect data for. + * @author Sam Jakob Harker + */ + public MassiveStats(JavaPlugin plugin){ + this(plugin, 900); // default value: 900 seconds (= 15 minutes) + } + + /** + * @param plugin The plugin you wish to collect data for. + * @param pingInterval Duration between requests. + * @author Sam Jakob Harker + */ + public MassiveStats(JavaPlugin plugin, int pingInterval){ + try { + jsonElement = Class.forName("com.google.gson.JsonElement"); + jsonParser = Class.forName("com.google.gson.JsonParser"); + jsonObject = Class.forName("com.google.gson.JsonObject"); + jsonPrimitive = Class.forName("com.google.gson.JsonPrimitive"); + }catch(ClassNotFoundException ex){ + // Gson not included in classpath (so use NMS version) + try { + jsonElement = Class.forName("net.minecraft.util.com.google.gson.JsonElement"); + jsonParser = Class.forName("net.minecraft.util.com.google.gson.JsonParser"); + jsonObject = Class.forName("net.minecraft.util.com.google.gson.JsonObject"); + jsonPrimitive = Class.forName("net.minecraft.util.com.google.gson.JsonPrimitive"); + }catch(ClassNotFoundException ignored){ + Bukkit.getLogger().severe("MassiveStats could not find an instance/version of Gson to use."); + this.plugin = null; + return; + } + } + + // Ensure the pingInterval that is set is reasonable. + if(pingInterval < 10 || pingInterval > 86400){ + pingInterval = 900; + } + + // Ensure that a plugin instance has been provided. + if(plugin == null){ + throw new IllegalArgumentException("You must provide a plugin for MassiveStats to collect data for!"); + } + + // Set the ping interval. + this.pingInterval = pingInterval; + // Set the plugin reference. + this.plugin = plugin; + // and start sending data to the MassiveStats server immediately. + start(); + + // Register join/leave events for the plugin + Bukkit.getServer().getPluginManager().registerEvents(this, plugin); + } + + /** + * Gets whether or not the built-in MassiveStats {@link org.bukkit.event.player.PlayerJoinEvent} listener is enabled. + * @return Whether or not the MassiveStats listener is enabled. + */ + public boolean isListenerDisabled(){ + return listenerDisabled; + } + + /** + * Sets whether or not the built-in MassiveStats {@link org.bukkit.event.player.PlayerJoinEvent} listener is enabled. + * @param listenerDisabled Whether or not the MassiveStats listener is enabled. + */ + public void setListenerDisabled(boolean listenerDisabled){ + this.listenerDisabled = listenerDisabled; + } + + /** + * Start the MassiveStats reporting timer. + * If the timer is already running, this method will do nothing. + * @author Sam Jakob Harker + */ + public void start(){ + if(this.plugin == null){ + Bukkit.getLogger().severe("MassiveStats could not find an instance/version of Gson to use and thus cannot start."); + return; + } + + if(task == null){ + // If the API endpoint URL is invalid, don't start a new task to prevent the user from being spammed. + try { + new URL(MassiveStats.API_URL); + }catch(MalformedURLException ex){ + getPlugin() + .getLogger().warning("You have specified an invalid API endpoint for MassiveStats."); + return; + } + + task = new MassiveStatsUpdateTask(this); + task.runTaskTimerAsynchronously(plugin, 0L, pingInterval * 20L); + } + } + + /** + * Stop the MassiveStats reporting timer. + * Requests will no longer be sent to the server - or until {@link #start()} is invoked. + * @author Sam Jakob Harker + */ + public void stop(){ + if(task == null){ + return; + } + + task.cancel(); + task = null; + } + + /** + * Sets the duration, in seconds, that MassiveStats should wait before sending another request to the server. + * @param pingInterval Duration between requests. + * @author Sam Jakob Harker + */ + public void setPingInterval(int pingInterval){ + this.pingInterval = pingInterval; + + stop(); + start(); + } + + /** + * Returns the duration, in seconds, that MassiveStats will wait before sending another request to the server. + * @return Duration between requests. + * @author Sam Jakob Harker + */ + public int getPingInterval(){ + return pingInterval; + } + + /** + * Returns the plugin that this MassiveStats instance is collecting data for. + * @return MassiveStats instance plugin. + * @author Sam Jakob Harker + */ + public JavaPlugin getPlugin(){ + return plugin; + } + + void setLastResponse(MassiveStatsDataResponse lastResponse){ + this.lastResponse = lastResponse; + } + + /** + * Returns the contents of the last response from the MassiveStats server. + * @return MassiveStats server response. + * @author Sam Jakob Harker + */ + public MassiveStatsDataResponse getLastResponse() { + return lastResponse; + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event){ + // Ensure the listener should be active + if(lastResponse == null || listenerDisabled){ + return; + } + + // Of course, only notify the user if the plugin is not up to date. + if(lastResponse.isUpToDate()){ + return; + } + + // and only notify operators - or players with the correct permission. + if(!event.getPlayer().isOp() && !event.getPlayer().hasPermission(MassiveStats.MASSIVE_UPDATE_PERMISSION)){ + return; + } + + event.getPlayer().sendMessage(lastResponse.getUpdateMessage()); + } + + Class getJsonElement(){ + return jsonElement; + } + + Class getJsonParser(){ + return jsonParser; + } + + Class getJsonObject(){ + return jsonObject; + } + + Class getJsonPrimitive(){ + return jsonPrimitive; + } + +} + +class MassiveStatsUpdateTask extends BukkitRunnable { + + private final MassiveStats instance; + + MassiveStatsUpdateTask(MassiveStats requester){ + instance = requester; + } + + @Override + @SuppressWarnings("all") + public void run(){ + try { + // Generate the request payload and serialize it as JSON. + String payload = new MassiveStatsDataRequest(instance).serialize(); + + // Then create a new HttpsUrlConnection to the API server and open it. + HttpsURLConnection connection = (HttpsURLConnection) new URL(MassiveStats.API_URL).openConnection(); + + // Ensure that we don't hang the server with our 'dang shenanigans'. + connection.setConnectTimeout(2500); + connection.setReadTimeout(3500); + + // Set the all-important request headers before we begin POSTing... + connection.setRequestMethod("POST"); + connection.setRequestProperty("Accept", "application/json"); + connection.setRequestProperty("Content-Type", "application/json; charset=utf-8"); + connection.setRequestProperty("User-Agent", "Massive/" + MassiveStats.CLIENT_VERSION); + + // Open the output stream, write the payload, and then close the stream. + connection.setDoOutput(true); + DataOutputStream output = new DataOutputStream(connection.getOutputStream()); + output.writeBytes(payload); + output.flush(); + output.close(); + + // Ensure that the server was happy with our data. + int responseCode = connection.getResponseCode(); + if(responseCode != 200){ + throw new IOException(); + } + + // Now, read the server's response to our payload... + BufferedReader input = new BufferedReader(new InputStreamReader(connection.getInputStream())); + StringBuilder response = new StringBuilder(); + + // ...line by line. + String line; + while((line = input.readLine()) != null){ + response.append(line); + } + input.close(); + + // Now, we parse the JSON object. + try { + if(response.toString().contains("ERR_DATA_MISSING")){ + Bukkit.getLogger().severe("MassiveStats has encountered an error for the following plugin: " + + instance.getPlugin().getName()); + instance.stop(); + return; + } + + Object parser = instance.getJsonParser().newInstance(); + + // JsonElement + Object serverResponseRaw = + parser.getClass().getMethod("parse", String.class).invoke(parser, response.toString()); + + // JsonObject + Object serverResponse = serverResponseRaw.getClass().getMethod("getAsJsonObject", null) + .invoke(serverResponseRaw, null); + + Method serverResponseGet = instance.getJsonObject().getMethod("get", String.class); + + Method getAsBoolean = + instance.getJsonPrimitive().getMethod("getAsBoolean", null); + Method getAsString = + instance.getJsonPrimitive().getMethod("getAsString", null); + + if(serverResponseGet.invoke(serverResponse, "upToDate") == null){ + Bukkit.getLogger().severe("MassiveStats has encountered an error for the following plugin: " + + instance.getPlugin().getName()); + instance.stop(); + return; + } + + if(serverResponseGet.invoke(serverResponse, "notice") != null) { + Bukkit.getLogger().severe( + (String) getAsString.invoke(serverResponseGet.invoke(serverResponse, "notice")) + ); + instance.stop(); + return; + } + + boolean upToDate = (boolean) getAsBoolean.invoke(serverResponseGet.invoke(serverResponse, "upToDate"), null); + String latestVersion = (String) getAsString.invoke(serverResponseGet.invoke(serverResponse, "latestVersion"), null); + String updateMessage = ChatColor.translateAlternateColorCodes( + '&', (String) getAsString.invoke(serverResponseGet.invoke(serverResponse, "updateMessage"), null) + ); + + instance.setLastResponse(new MassiveStatsDataResponse( + upToDate, latestVersion, updateMessage + )); + + }catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) { + instance.getPlugin() + .getLogger().warning("MassiveStats returned an invalid response for this plugin."); + } + + // Finally, call an event to mark the update. + } catch(MalformedURLException ex){ + instance.getPlugin() + .getLogger().warning("You have specified an invalid API endpoint for MassiveStats."); + }catch(IOException ex){ + instance.getPlugin() + .getLogger().warning("MassiveStats was unable to communicate with its API endpoint."); + } + } + +} + +class MassiveStatsDataRequest { + + private Object jsonObject; + + MassiveStatsDataRequest(MassiveStats requester){ + try { + jsonObject = requester.getJsonObject().newInstance(); + + Method add = + requester.getJsonObject().newInstance().getClass().getMethod("add", String.class, requester.getJsonElement()); + Method addPropertyString = + requester.getJsonObject().newInstance().getClass().getMethod("addProperty", String.class, String.class); + Method addPropertyNumber = + requester.getJsonObject().newInstance().getClass().getMethod("addProperty", String.class, Number.class); + Method addPropertyBoolean = + requester.getJsonObject().newInstance().getClass().getMethod("addProperty", String.class, Boolean.class); + + addPropertyNumber.invoke(jsonObject, "now", System.currentTimeMillis()); + + /* PLUGIN DATA */ + Object pluginObject = jsonObject.getClass().newInstance(); + addPropertyString.invoke(pluginObject, "name", requester.getPlugin().getDescription().getName()); + addPropertyString.invoke(pluginObject, "version", requester.getPlugin().getDescription().getVersion()); + add.invoke(jsonObject, "plugin", pluginObject); + + /* SERVER DATA */ + Object minecraftServerObject = jsonObject.getClass().newInstance(); + addPropertyNumber.invoke(minecraftServerObject, "players", Bukkit.getServer().getOnlinePlayers().size()); + addPropertyBoolean.invoke(minecraftServerObject, "onlineMode", Bukkit.getServer().getOnlineMode()); + addPropertyString.invoke(minecraftServerObject, "version", Bukkit.getServer().getVersion()); + + Object javaServerObject = jsonObject.getClass().newInstance(); + addPropertyString.invoke(javaServerObject, "version", System.getProperty("java.version")); + + Object osServerObject = jsonObject.getClass().newInstance(); + addPropertyString.invoke(osServerObject, "name", System.getProperty("os.name")); + addPropertyString.invoke(osServerObject, "arch", System.getProperty("os.arch")); + addPropertyString.invoke(osServerObject, "version", System.getProperty("os.version")); + + Object hardwareServerObject = jsonObject.getClass().newInstance(); + addPropertyNumber.invoke(hardwareServerObject, "cores", Runtime.getRuntime().availableProcessors()); + + Object serverObject = jsonObject.getClass().newInstance(); + add.invoke(serverObject, "minecraft", minecraftServerObject); + add.invoke(serverObject, "java", javaServerObject); + add.invoke(serverObject, "os", osServerObject); + add.invoke(serverObject,"hardware", hardwareServerObject); + + add.invoke(jsonObject, "server", serverObject); + + /* MASSIVE DATA */ + Object massiveObject = jsonObject.getClass().newInstance(); + addPropertyNumber.invoke(massiveObject, "version", MassiveStats.CLIENT_VERSION); + addPropertyNumber.invoke(massiveObject, "pingInterval", requester.getPingInterval()); + + //object.add("Massive", massiveObject); + add.invoke(jsonObject,"Massive", massiveObject); + } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) { + e.printStackTrace(); + } + } + + @SuppressWarnings("all") + public String serialize(){ + //return object.toString(); + try { + Method toString = jsonObject.getClass().getMethod("toString", null); + return (String) toString.invoke(jsonObject); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + + return null; + } + +} + +@SuppressWarnings("unused") +final class MassiveStatsDataResponse { + + private final boolean isUpToDate; + private final String newVersion; + private final String updateMessage; + + MassiveStatsDataResponse(boolean isUpToDate, String newVersion, String updateMessage){ + this.isUpToDate = isUpToDate; + + if(!isUpToDate) { + this.newVersion = newVersion; + this.updateMessage = updateMessage; + return; + } + + this.newVersion = null; + this.updateMessage = null; + } + + /** + * Indicates whether or not this version of the plugin is the latest. + * True = This is the latest version of the plugin. + * False = There is an update available. + * @return Whether or not there is an update available. + */ + public boolean isUpToDate() { + return isUpToDate; + } + + /** + * Gets the name of the latest version. If this is the latest version, it returns null. + * @return The name of the latest version. + */ + public String getLatestVersion(){ + return newVersion; + } + + /** + * Gets the message to display, convincing the user to update to the new version of the plugin. + * @return The update message to display. + */ + public String getUpdateMessage(){ + return updateMessage; + } + +} \ No newline at end of file diff --git a/src/main/java/com/shadebyte/auctionhouse/Core.java b/src/main/java/com/shadebyte/auctionhouse/Core.java index 1dbb55a..b7e9025 100644 --- a/src/main/java/com/shadebyte/auctionhouse/Core.java +++ b/src/main/java/com/shadebyte/auctionhouse/Core.java @@ -4,14 +4,21 @@ import org.bukkit.plugin.java.JavaPlugin; public final class Core extends JavaPlugin { + private static Core instance; + @Override public void onEnable() { // Plugin startup logic - + instance = this; } @Override public void onDisable() { // Plugin shutdown logic + instance = null; + } + + public static Core getInstance() { + return instance; } } diff --git a/src/main/java/com/shadebyte/auctionhouse/api/AuctionAPI.java b/src/main/java/com/shadebyte/auctionhouse/api/AuctionAPI.java new file mode 100644 index 0000000..ee8c5c0 --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/api/AuctionAPI.java @@ -0,0 +1,10 @@ +package com.shadebyte.auctionhouse.api; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:48 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public class AuctionAPI { +} diff --git a/src/main/java/com/shadebyte/auctionhouse/api/enums/Lang.java b/src/main/java/com/shadebyte/auctionhouse/api/enums/Lang.java new file mode 100644 index 0000000..c9fdc8f --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/api/enums/Lang.java @@ -0,0 +1,10 @@ +package com.shadebyte.auctionhouse.api.enums; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:52 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public enum Lang { +} diff --git a/src/main/java/com/shadebyte/auctionhouse/api/enums/Permissions.java b/src/main/java/com/shadebyte/auctionhouse/api/enums/Permissions.java new file mode 100644 index 0000000..dab0dd5 --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/api/enums/Permissions.java @@ -0,0 +1,22 @@ +package com.shadebyte.auctionhouse.api.enums; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:52 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public enum Permissions { + + BASE("AuctionHouse"); + + private String node; + + Permissions(String node) { + this.node = node; + } + + public String getNode() { + return node; + } +} diff --git a/src/main/java/com/shadebyte/auctionhouse/api/enums/Sounds.java b/src/main/java/com/shadebyte/auctionhouse/api/enums/Sounds.java new file mode 100644 index 0000000..c9e20be --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/api/enums/Sounds.java @@ -0,0 +1,231 @@ +package com.shadebyte.auctionhouse.api.enums; + +import org.bukkit.Sound; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:56 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ + +/** + * https://www.spigotmc.org/threads/1-8-to-1-9-sounds.142007/ + */ + +public enum Sounds { + AMBIENCE_CAVE("AMBIENCE_CAVE", "AMBIENT_CAVE"), + AMBIENCE_RAIN("AMBIENCE_RAIN", "WEATHER_RAIN"), + AMBIENCE_THUNDER("AMBIENCE_THUNDER", "ENTITY_LIGHTNING_THUNDER"), + ANVIL_BREAK("ANVIL_BREAK", "BLOCK_ANVIL_BREAK"), + ANVIL_LAND("ANVIL_LAND", "BLOCK_ANVIL_LAND"), + ANVIL_USE("ANVIL_USE", "BLOCK_ANVIL_USE"), + ARROW_HIT("ARROW_HIT", "ENTITY_ARROW_HIT"), + BURP("BURP", "ENTITY_PLAYER_BURP"), + CHEST_CLOSE("CHEST_CLOSE", "ENTITY_CHEST_CLOSE"), + CHEST_OPEN("CHEST_OPEN", "ENTITY_CHEST_OPEN"), + CLICK("CLICK", "UI_BUTTON_CLICK"), + DOOR_CLOSE("DOOR_CLOSE", "BLOCK_WOODEN_DOOR_CLOSE"), + DOOR_OPEN("DOOR_OPEN", "BLOCK_WOODEN_DOOR_OPEN"), + DRINK("DRINK", "ENTITY_GENERIC_DRINK"), + EAT("EAT", "ENTITY_GENERIC_EAT"), + EXPLODE("EXPLODE", "ENTITY_GENERIC_EXPLODE"), + FALL_BIG("FALL_BIG", "ENTITY_GENERIC_BIG_FALL"), + FALL_SMALL("FALL_SMALL", "ENTITY_GENERIC_SMALL_FALL"), + FIRE("FIRE", "BLOCK_FIRE_AMBIENT"), + FIRE_IGNITE("FIRE_IGNITE", "ITEM_FLINTANDSTEEL_USE"), + FIZZ("FIZZ", "BLOCK_FIRE_EXTINGUISH"), + FUSE("FUSE", "ENTITY_TNT_PRIMED"), + GLASS("GLASS", "BLOCK_GLASS_BREAK"), + HURT_FLESH("HURT_FLESH", "ENTITY_PLAYER_HURT"), + ITEM_BREAK("ITEM_BREAK", "ENTITY_ITEM_BREAK"), + ITEM_PICKUP("ITEM_PICKUP", "ENTITY_ITEM_PICKUP"), + LAVA("LAVA", "BLOCK_LAVA_AMBIENT"), + LAVA_POP("LAVA_POP", "BLOCK_LAVA_POP"), + LEVEL_UP("LEVEL_UP", "ENTITY_PLAYER_LEVELUP"), + MINECART_BASE("MINECART_BASE", "ENTITY_MINECART_RIDING"), + MINECART_INSIDE("MINECART_INSIDE", "ENTITY_MINECART_RIDING"), + NOTE_BASS("NOTE_BASS", "BLOCK_NOTE_BASS"), + NOTE_PIANO("NOTE_PIANO", "BLOCK_NOTE_HARP"), + NOTE_BASS_DRUM("NOTE_BASS_DRUM", "BLOCK_NOTE_BASEDRUM"), + NOTE_STICKS("NOTE_STICKS", "BLOCK_NOTE_HAT"), + NOTE_BASS_GUITAR("NOTE_BASS_GUITAR", "BLOCK_NOTE_BASS"), + NOTE_SNARE_DRUM("NOTE_SNARE_DRUM", "BLOCK_NOTE_SNARE"), + NOTE_PLING("NOTE_PLING", "BLOCK_NOTE_PLING"), + ORB_PICKUP("ORB_PICKUP", "ENTITY_EXPERIENCE_ORB_PICKUP"), + PISTON_EXTEND("PISTON_EXTEND", "BLOCK_PISTON_EXTEND"), + PISTON_RETRACT("PISTON_RETRACT", "BLOCK_PISTON_CONTRACT"), + PORTAL("PORTAL", "BLOCK_PORTAL_AMBIENT"), + PORTAL_TRAVEL("PORTAL_TRAVEL", "BLOCK_PORTAL_TRAVEL"), + PORTAL_TRIGGER("PORTAL_TRIGGER", "BLOCK_PORTAL_TRIGGER"), + SHOOT_ARROW("SHOOT_ARROW", "ENTITY_ARROW_SHOOT"), + SPLASH("SPLASH", "ENTITY_GENERIC_SPLASH"), + SPLASH2("SPLASH2", "ENTITY_BOBBER_SPLASH"), + STEP_GRASS("STEP_GRASS", "BLOCK_GRASS_STEP"), + STEP_GRAVEL("STEP_GRAVEL", "BLOCK_GRAVEL_STEP"), + STEP_LADDER("STEP_LADDER", "BLOCK_LADDER_STEP"), + STEP_SAND("STEP_SAND", "BLOCK_SAND_STEP"), + STEP_SNOW("STEP_SNOW", "BLOCK_SNOW_STEP"), + STEP_STONE("STEP_STONE", "BLOCK_STONE_STEP"), + STEP_WOOD("STEP_WOOD", "BLOCK_WOOD_STEP"), + STEP_WOOL("STEP_WOOL", "BLOCK_CLOTH_STEP"), + SWIM("SWIM", "ENTITY_GENERIC_SWIM"), + WATER("WATER", "BLOCK_WATER_AMBIENT"), + WOOD_CLICK("WOOD_CLICK", "BLOCK_WOOD_BUTTON_CLICK_ON"), + BAT_DEATH("BAT_DEATH", "ENTITY_BAT_DEATH"), + BAT_HURT("BAT_HURT", "ENTITY_BAT_HURT"), + BAT_IDLE("BAT_IDLE", "ENTITY_BAT_AMBIENT"), + BAT_LOOP("BAT_LOOP", "ENTITY_BAT_LOOP"), + BAT_TAKEOFF("BAT_TAKEOFF", "ENTITY_BAT_TAKEOFF"), + BLAZE_BREATH("BLAZE_BREATH", "ENTITY_BLAZE_AMBIENT"), + BLAZE_DEATH("BLAZE_DEATH", "ENTITY_BLAZE_DEATH"), + BLAZE_HIT("BLAZE_HIT", "ENTITY_BLAZE_HURT"), + CAT_HISS("CAT_HISS", "ENTITY_CAT_HISS"), + CAT_HIT("CAT_HIT", "ENTITY_CAT_HURT"), + CAT_MEOW("CAT_MEOW", "ENTITY_CAT_AMBIENT"), + CAT_PURR("CAT_PURR", "ENTITY_CAT_PURR"), + CAT_PURREOW("CAT_PURREOW", "ENTITY_CAT_PURREOW"), + CHICKEN_IDLE("CHICKEN_IDLE", "ENTITY_CHICKEN_AMBIENT"), + CHICKEN_HURT("CHICKEN_HURT", "ENTITY_CHICKEN_HURT"), + CHICKEN_EGG_POP("CHICKEN_EGG_POP", "ENTITY_CHICKEN_EGG"), + CHICKEN_WALK("CHICKEN_WALK", "ENTITY_CHICKEN_STEP"), + COW_IDLE("COW_IDLE", "ENTITY_COW_AMBIENT"), + COW_HURT("COW_HURT", "ENTITY_COW_HURT"), + COW_WALK("COW_WALK", "ENTITY_COW_STEP"), + CREEPER_HISS("CREEPER_HISS", "ENTITY_CREEPER_PRIMED"), + CREEPER_DEATH("CREEPER_DEATH", "ENTITY_CREEPER_DEATH"), + ENDERDRAGON_DEATH("ENDERDRAGON_DEATH", "ENTITY_ENDERDRAGON_DEATH"), + ENDERDRAGON_GROWL("ENDERDRAGON_GROWL", "ENTITY_ENDERDRAGON_GROWL"), + ENDERDRAGON_HIT("ENDERDRAGON_HIT", "ENTITY_ENDERDRAGON_HURT"), + ENDERDRAGON_WINGS("ENDERDRAGON_WINGS", "ENTITY_ENDERDRAGON_FLAP"), + ENDERMAN_DEATH("ENDERMAN_DEATH", "ENTITY_ENDERMEN_DEATH"), + ENDERMAN_HIT("ENDERMAN_HIT", "ENTITY_ENDERMEN_HURT"), + ENDERMAN_IDLE("ENDERMAN_IDLE", "ENTITY_ENDERMEN_AMBIENT"), + ENDERMAN_TELEPORT("ENDERMAN_TELEPORT", "ENTITY_ENDERMEN_TELEPORT"), + ENDERMAN_SCREAM("ENDERMAN_SCREAM", "ENTITY_ENDERMEN_SCREAM"), + ENDERMAN_STARE("ENDERMAN_STARE", "ENTITY_ENDERMEN_STARE"), + GHAST_SCREAM("GHAST_SCREAM", "ENTITY_GHAST_SCREAM"), + GHAST_SCREAM2("GHAST_SCREAM2", "ENTITY_GHAST_HURT"), + GHAST_CHARGE("GHAST_CHARGE", "ENTITY_GHAST_WARN"), + GHAST_DEATH("GHAST_DEATH", "ENTITY_GHAST_DEATH"), + GHAST_FIREBALL("GHAST_FIREBALL", "ENTITY_GHAST_SHOOT"), + GHAST_MOAN("GHAST_MOAN", "ENTITY_GHAST_AMBIENT"), + IRONGOLEM_DEATH("IRONGOLEM_DEATH", "ENTITY_IRONGOLEM_DEATH"), + IRONGOLEM_HIT("IRONGOLEM_HIT", "ENTITY_IRONGOLEM_HURT"), + IRONGOLEM_THROW("IRONGOLEM_THROW", "ENTITY_IRONGOLEM_ATTACK"), + IRONGOLEM_WALK("IRONGOLEM_WALK", "ENTITY_IRONGOLEM_STEP"), + MAGMACUBE_WALK("MAGMACUBE_WALK", "ENTITY_MAGMACUBE_SQUISH"), + MAGMACUBE_WALK2("MAGMACUBE_WALK2", "ENTITY_MAGMACUBE_SQUISH"), + MAGMACUBE_JUMP("MAGMACUBE_JUMP", "ENTITY_MAGMACUBE_JUMP"), + PIG_IDLE("PIG_IDLE", "ENTITY_PIG_AMBIENT"), + PIG_DEATH("PIG_DEATH", "ENTITY_PIG_DEATH"), + PIG_WALK("PIG_WALK", "ENTITY_PIG_STEP"), + SHEEP_IDLE("SHEEP_IDLE", "ENTITY_SHEEP_AMBIENT"), + SHEEP_SHEAR("SHEEP_SHEAR", "ENTITY_SHEEP_SHEAR"), + SHEEP_WALK("SHEEP_WALK", "ENTITY_SHEEP_STEP"), + SILVERFISH_HIT("SILVERFISH_HIT", "ENTITY_SILVERFISH_HURT"), + SILVERFISH_KILL("SILVERFISH_KILL", "ENTITY_SILVERFISH_DEATH"), + SILVERFISH_IDLE("SILVERFISH_IDLE", "ENTITY_SILVERFISH_AMBIENT"), + SILVERFISH_WALK("SILVERFISH_WALK", "ENTITY_SILVERFISH_STEP"), + SKELETON_IDLE("SKELETON_IDLE", "ENTITY_SKELETON_AMBIENT"), + SKELETON_DEATH("SKELETON_DEATH", "ENTITY_SKELETON_DEATH"), + SKELETON_HURT("SKELETON_HURT", "ENTITY_SKELETON_HURT"), + SKELETON_WALK("SKELETON_WALK", "ENTITY_SKELETON_STEP"), + SLIME_ATTACK("SLIME_ATTACK", "ENTITY_SLIME_ATTACK"), + SLIME_WALK("SLIME_WALK", "ENTITY_SLIME_JUMP"), + SLIME_WALK2("SLIME_WALK2", "ENTITY_SLIME_SQUISH"), + SPIDER_IDLE("SPIDER_IDLE", "ENTITY_SPIDER_AMBIENT"), + SPIDER_DEATH("SPIDER_DEATH", "ENTITY_SPIDER_DEATH"), + SPIDER_WALK("SPIDER_WALK", "ENTITY_SPIDER_STEP"), + WITHER_DEATH("WITHER_DEATH", "ENTITY_WITHER_DEATH"), + WITHER_HURT("WITHER_HURT", "ENTITY_WITHER_HURT"), + WITHER_IDLE("WITHER_IDLE", "ENTITY_WITHER_AMBIENT"), + WITHER_SHOOT("WITHER_SHOOT", "ENTITY_WITHER_SHOOT"), + WITHER_SPAWN("WITHER_SPAWN", "ENTITY_WITHER_SPAWN"), + WOLF_BARK("WOLF_BARK", "ENTITY_WOLF_AMBIENT"), + WOLF_DEATH("WOLF_DEATH", "ENTITY_WOLF_DEATH"), + WOLF_GROWL("WOLF_GROWL", "ENTITY_WOLF_GROWL"), + WOLF_HOWL("WOLF_HOWL", "ENTITY_WOLF_HOWL"), + WOLF_HURT("WOLF_HURT", "ENTITY_WOLF_HURT"), + WOLF_PANT("WOLF_PANT", "ENTITY_WOLF_PANT"), + WOLF_SHAKE("WOLF_SHAKE", "ENTITY_WOLF_SHAKE"), + WOLF_WALK("WOLF_WALK", "ENTITY_WOLF_STEP"), + WOLF_WHINE("WOLF_WHINE", "ENTITY_WOLF_WHINE"), + ZOMBIE_METAL("ZOMBIE_METAL", "ENTITY_ZOMBIE_ATTACK_IRON_DOOR"), + ZOMBIE_WOOD("ZOMBIE_WOOD", "ENTITY_ZOMBIE_ATTACK_DOOR_WOOD"), + ZOMBIE_WOODBREAK("ZOMBIE_WOODBREAK", "ENTITY_ZOMBIE_BREAK_DOOR_WOOD"), + ZOMBIE_IDLE("ZOMBIE_IDLE", "ENTITY_ZOMBIE_AMBIENT"), + ZOMBIE_DEATH("ZOMBIE_DEATH", "ENTITY_ZOMBIE_DEATH"), + ZOMBIE_HURT("ZOMBIE_HURT", "ENTITY_ZOMBIE_HURT"), + ZOMBIE_INFECT("ZOMBIE_INFECT", "ENTITY_ZOMBIE_INFECT"), + ZOMBIE_UNFECT("ZOMBIE_UNFECT", "ENTITY_ZOMBIE_VILLAGER_CONVERTED"), + ZOMBIE_REMEDY("ZOMBIE_REMEDY", "ENTITY_ZOMBIE_VILLAGER_CURE"), + ZOMBIE_WALK("ZOMBIE_WALK", "ENTITY_ZOMBIE_STEP"), + ZOMBIE_PIG_IDLE("ZOMBIE_PIG_IDLE", "ENTITY_ZOMBIE_PIG_AMBIENT"), + ZOMBIE_PIG_ANGRY("ZOMBIE_PIG_ANGRY", "ENTITY_ZOMBIE_PIG_ANGRY"), + ZOMBIE_PIG_DEATH("ZOMBIE_PIG_DEATH", "ENTITY_ZOMBIE_PIG_DEATH"), + ZOMBIE_PIG_HURT("ZOMBIE_PIG_HURT", "ENTITY_ZOMBIE_PIG_HURT"), + DIG_WOOL("DIG_WOOL", "BLOCK_CLOTH_BREAK"), + DIG_GRASS("DIG_GRASS", "BLOCK_GRASS_BREAK"), + DIG_GRAVEL("DIG_GRAVEL", "BLOCK_GRAVEL_BREAK"), + DIG_SAND("DIG_SAND", "BLOCK_SAND_BREAK"), + DIG_SNOW("DIG_SNOW", "BLOCK_SNOW_BREAK"), + DIG_STONE("DIG_STONE", "BLOCK_STONE_BREAK"), + DIG_WOOD("DIG_WOOD", "BLOCK_WOOD_BREAK"), + FIREWORK_BLAST("FIREWORK_BLAST", "ENTITY_FIREWORK_BLAST"), + FIREWORK_BLAST2("FIREWORK_BLAST2", "ENTITY_FIREWORK_BLAST_FAR"), + FIREWORK_LARGE_BLAST("FIREWORK_LARGE_BLAST", "ENTITY_FIREWORK_LARGE_BLAST"), + FIREWORK_LARGE_BLAST2("FIREWORK_LARGE_BLAST2", "ENTITY_FIREWORK_LARGE_BLAST_FAR"), + FIREWORK_TWINKLE("FIREWORK_TWINKLE", "ENTITY_FIREWORK_TWINKLE"), + FIREWORK_TWINKLE2("FIREWORK_TWINKLE2", "ENTITY_FIREWORK_TWINKLE_FAR"), + FIREWORK_LAUNCH("FIREWORK_LAUNCH", "ENTITY_FIREWORK_LAUNCH"), + SUCCESSFUL_HIT("SUCCESSFUL_HIT", "ENTITY_PLAYER_ATTACK_STRONG"), + HORSE_ANGRY("HORSE_ANGRY", "ENTITY_HORSE_ANGRY"), + HORSE_ARMOR("HORSE_ARMOR", "ENTITY_HORSE_ARMOR"), + HORSE_BREATHE("HORSE_BREATHE", "ENTITY_HORSE_BREATHE"), + HORSE_DEATH("HORSE_DEATH", "ENTITY_HORSE_DEATH"), + HORSE_GALLOP("HORSE_GALLOP", "ENTITY_HORSE_GALLOP"), + HORSE_HIT("HORSE_HIT", "ENTITY_HORSE_HURT"), + HORSE_IDLE("HORSE_IDLE", "ENTITY_HORSE_AMBIENT"), + HORSE_JUMP("HORSE_JUMP", "ENTITY_HORSE_JUMP"), + HORSE_LAND("HORSE_LAND", "ENTITY_HORSE_LAND"), + HORSE_SADDLE("HORSE_SADDLE", "ENTITY_HORSE_SADDLE"), + HORSE_SOFT("HORSE_SOFT", "ENTITY_HORSE_STEP"), + HORSE_WOOD("HORSE_WOOD", "ENTITY_HORSE_STEP_WOOD"), + DONKEY_ANGRY("DONKEY_ANGRY", "ENTITY_DONKEY_ANGRY"), + DONKEY_DEATH("DONKEY_DEATH", "ENTITY_DONKEY_DEATH"), + DONKEY_HIT("DONKEY_HIT", "ENTITY_DONKEY_HURT"), + DONKEY_IDLE("DONKEY_IDLE", "ENTITY_DONKEY_AMBIENT"), + HORSE_SKELETON_DEATH("HORSE_SKELETON_DEATH", "ENTITY_SKELETON_HORSE_DEATH"), + HORSE_SKELETON_HIT("HORSE_SKELETON_HIT", "ENTITY_SKELETON_HORSE_HURT"), + HORSE_SKELETON_IDLE("HORSE_SKELETON_IDLE", "ENTITY_SKELETON_HORSE_AMBIENT"), + HORSE_ZOMBIE_DEATH("HORSE_ZOMBIE_DEATH", "ENTITY_ZOMBIE_HORSE_DEATH"), + HORSE_ZOMBIE_HIT("HORSE_ZOMBIE_HIT", "ENTITY_ZOMBIE_HORSE_HURT"), + HORSE_ZOMBIE_IDLE("HORSE_ZOMBIE_IDLE", "ENTITY_ZOMBIE_HORSE_AMBIENT"), + VILLAGER_DEATH("VILLAGER_DEATH", "ENTITY_VILLAGER_DEATH"), + VILLAGER_HAGGLE("VILLAGER_HAGGLE", "ENTITY_VILLAGER_TRADING"), + VILLAGER_HIT("VILLAGER_HIT", "ENTITY_VILLAGER_HURT"), + VILLAGER_IDLE("VILLAGER_IDLE", "ENTITY_VILLAGER_AMBIENT"), + VILLAGER_NO("VILLAGER_NO", "ENTITY_VILLAGER_NO"), + VILLAGER_YES("VILLAGER_YES", "ENTITY_VILLAGER_YES"); + + private String pre19sound; + private String post19sound; + private Sound resolvedSound = null; + + Sounds(String pre19sound, String post19sound) { + this.pre19sound = pre19sound; + this.post19sound = post19sound; + } + + public Sound bukkitSound() { + if (resolvedSound != null) return resolvedSound; + + try { + return resolvedSound = Sound.valueOf(post19sound); + } catch (IllegalArgumentException e) { + //Try 1.8 sound + return resolvedSound = Sound.valueOf(pre19sound); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/shadebyte/auctionhouse/api/enums/Version.java b/src/main/java/com/shadebyte/auctionhouse/api/enums/Version.java new file mode 100644 index 0000000..1e309f4 --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/api/enums/Version.java @@ -0,0 +1,121 @@ +package com.shadebyte.auctionhouse.api.enums; + +import org.bukkit.Bukkit; + +//Created by Kicjow for crazy crates +public enum Version { + + TOO_OLD(-1), + v1_7_R1(171), v1_7_R2(172), v1_7_R3(173), v1_7_R4(174), + v1_8_R1(181), v1_8_R2(182), v1_8_R3(183), + v1_9_R1(191), v1_9_R2(192), + v1_10_R1(1101), + v1_11_R1(1111), + v1_12_R1(1121), + TOO_NEW(-2); + + private static Version latest; + private Integer versionInteger; + public static Version currentVersion; + + Version(int versionInteger) { + this.versionInteger = versionInteger; + } + + /** + * + * @return Get the server's Minecraft version. + */ + public static Version getCurrentVersion() { + if(currentVersion == null) { + String ver = Bukkit.getServer().getClass().getPackage().getName(); + int v = Integer.parseInt(ver.substring(ver.lastIndexOf('.') + 1).replaceAll("_", "").replaceAll("R", "").replaceAll("v", "")); + for(Version version : values()) { + if(version.getCurrentVersionInteger() == v) { + currentVersion = version; + break; + } + } + if(v > Version.getLatestVersion().getCurrentVersionInteger()) { + currentVersion = Version.getLatestVersion(); + } + if(currentVersion == null) { + currentVersion = Version.TOO_NEW; + } + } + return currentVersion; + } + + /** + * + * @return The server's minecraft version as an integer. + */ + public Integer getCurrentVersionInteger() { + return this.versionInteger; + } + + /** + * Get the latest version allowed by the Version class. + * @return The latest version. + */ + public static Version getLatestVersion() { + if(latest == null) { + Version v = Version.TOO_OLD; + for(Version version : values()) { + if(version.comparedTo(v) == 1) { + v = version; + } + } + return v; + }else { + return latest; + } + } + + /** + * This checks if the current version is older, newer, or is the checked version. + * @param version The version you are checking. + * @return -1 if older, 0 if the same, and 1 if newer. + */ + public Integer comparedTo(Version version) { + int resault = -1; + int current = this.getCurrentVersionInteger(); + int check = version.getCurrentVersionInteger(); + if(current > check || check == -2) {// check is newer then current + resault = 1; + }else if(current == check) {// check is the same as current + resault = 0; + }else if(current < check || check == -1) {// check is older then current + resault = -1; + } + return resault; + } + + /** + * Checks to see if the current version is newer then the checked version. + * @param version The version you are checking. + * @return True if newer then the checked version and false if the same or older. + */ + public Boolean isNewer(Version version) { + return this.versionInteger > version.versionInteger || this.versionInteger == -2; + } + + /** + * Checks to see if the current version is the same as the checked version. + * @param version The version you are checking. + * @return True if both the current and checked version is the same and false if otherwise. + */ + public Boolean isSame(Version version) { + return this.versionInteger.equals(version.versionInteger); + } + + /** + * Checks to see if the current version is older then the checked version. + * @param version The version you are checking. + * @return True if older then the checked version and false if the same or newer. + */ + public Boolean isOlder(Version version) { + return this.versionInteger < version.versionInteger || this.versionInteger == -1; + } + +} \ No newline at end of file diff --git a/src/main/java/com/shadebyte/auctionhouse/api/event/AuctionCancelEvent.java b/src/main/java/com/shadebyte/auctionhouse/api/event/AuctionCancelEvent.java new file mode 100644 index 0000000..5980f38 --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/api/event/AuctionCancelEvent.java @@ -0,0 +1,10 @@ +package com.shadebyte.auctionhouse.api.event; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:55 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public class AuctionCancelEvent { +} diff --git a/src/main/java/com/shadebyte/auctionhouse/api/event/AuctionEndEvent.java b/src/main/java/com/shadebyte/auctionhouse/api/event/AuctionEndEvent.java new file mode 100644 index 0000000..d4910fc --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/api/event/AuctionEndEvent.java @@ -0,0 +1,10 @@ +package com.shadebyte.auctionhouse.api.event; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:54 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public class AuctionEndEvent { +} diff --git a/src/main/java/com/shadebyte/auctionhouse/api/event/AuctionStartEvent.java b/src/main/java/com/shadebyte/auctionhouse/api/event/AuctionStartEvent.java new file mode 100644 index 0000000..93b2622 --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/api/event/AuctionStartEvent.java @@ -0,0 +1,10 @@ +package com.shadebyte.auctionhouse.api.event; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:54 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public class AuctionStartEvent { +} diff --git a/src/main/java/com/shadebyte/auctionhouse/auction/AuctionItem.java b/src/main/java/com/shadebyte/auctionhouse/auction/AuctionItem.java new file mode 100644 index 0000000..2431524 --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/auction/AuctionItem.java @@ -0,0 +1,10 @@ +package com.shadebyte.auctionhouse.auction; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:49 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public class AuctionItem { +} diff --git a/src/main/java/com/shadebyte/auctionhouse/auction/AuctionPlayer.java b/src/main/java/com/shadebyte/auctionhouse/auction/AuctionPlayer.java new file mode 100644 index 0000000..94e32e3 --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/auction/AuctionPlayer.java @@ -0,0 +1,10 @@ +package com.shadebyte.auctionhouse.auction; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:49 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public class AuctionPlayer { +} diff --git a/src/main/java/com/shadebyte/auctionhouse/cmds/CommandManager.java b/src/main/java/com/shadebyte/auctionhouse/cmds/CommandManager.java new file mode 100644 index 0000000..113f167 --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/cmds/CommandManager.java @@ -0,0 +1,99 @@ +package com.shadebyte.auctionhouse.cmds; + +import com.shadebyte.auctionhouse.Core; +import com.shadebyte.auctionhouse.api.enums.Permissions; +import com.shadebyte.auctionhouse.util.Debugger; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:50 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public class CommandManager implements CommandExecutor { + + private List commands = new ArrayList<>(); + + public CommandManager() { + } + + public final String main = "auctionhouse"; + + public final String expired = "expired"; + public final String help = "help"; + public final String listed = "listed"; + public final String reload = "reload"; + public final String sell = "sell"; + + public void initialize() { + Core.getInstance().getCommand(main).setExecutor(this); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + + if (!sender.hasPermission(Permissions.BASE.getNode())) { + //sender.sendMessage(Core.getInstance().getSettings().getPrefix() + Core.getInstance().getLocale().getMessage(Lang.NO_PERMISSION.getNode())); + return true; + } + + //Main command text + if (command.getName().equalsIgnoreCase(main)) { + if (args.length == 0) { + //OPEN + return true; + } + + //Handle Sub commands + SubCommand target = this.getSubcommand(args[0]); + + if (target == null) { + //sender.sendMessage(Core.getInstance().getSettings().getPrefix() + Core.getInstance().getLocale().getMessage(Lang.INVALID_SUBCOMMAND.getNode())); + return true; + } + + List list = new ArrayList<>(); + list.addAll(Arrays.asList(args)); + list.remove(0); + + try { + target.onCommand(sender, args); + } catch (Exception e) { + Debugger.report(e); + } + } + + return true; + } + + private SubCommand getSubcommand(String name) { + Iterator subcommands = this.commands.iterator(); + while (subcommands.hasNext()) { + SubCommand sc = subcommands.next(); + + if (sc.name().equalsIgnoreCase(name)) { + return sc; + } + + String[] aliases; + int length = (aliases = sc.aliases()).length; + + for (int var5 = 0; var5 < length; ++var5) { + String alias = aliases[var5]; + if (name.equalsIgnoreCase(alias)) { + return sc; + } + + } + } + return null; + } +} \ No newline at end of file diff --git a/src/main/java/com/shadebyte/auctionhouse/cmds/SubCommand.java b/src/main/java/com/shadebyte/auctionhouse/cmds/SubCommand.java new file mode 100644 index 0000000..89ddbe5 --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/cmds/SubCommand.java @@ -0,0 +1,26 @@ +package com.shadebyte.auctionhouse.cmds; + +import org.bukkit.command.CommandSender; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:50 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public abstract class SubCommand { + + /* + /command args[++] + */ + + public SubCommand() {} + + public abstract void onCommand(CommandSender sender, String[] args); + + public abstract String name(); + + public abstract String info(); + + public abstract String[] aliases(); +} diff --git a/src/main/java/com/shadebyte/auctionhouse/cmds/subcmds/ExpiredCommand.java b/src/main/java/com/shadebyte/auctionhouse/cmds/subcmds/ExpiredCommand.java new file mode 100644 index 0000000..4ec7215 --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/cmds/subcmds/ExpiredCommand.java @@ -0,0 +1,10 @@ +package com.shadebyte.auctionhouse.cmds.subcmds; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:51 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public class ExpiredCommand { +} diff --git a/src/main/java/com/shadebyte/auctionhouse/cmds/subcmds/HelpCommand.java b/src/main/java/com/shadebyte/auctionhouse/cmds/subcmds/HelpCommand.java new file mode 100644 index 0000000..2423a38 --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/cmds/subcmds/HelpCommand.java @@ -0,0 +1,10 @@ +package com.shadebyte.auctionhouse.cmds.subcmds; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:51 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public class HelpCommand { +} diff --git a/src/main/java/com/shadebyte/auctionhouse/cmds/subcmds/ListedCommand.java b/src/main/java/com/shadebyte/auctionhouse/cmds/subcmds/ListedCommand.java new file mode 100644 index 0000000..42fe686 --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/cmds/subcmds/ListedCommand.java @@ -0,0 +1,10 @@ +package com.shadebyte.auctionhouse.cmds.subcmds; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:51 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public class ListedCommand { +} diff --git a/src/main/java/com/shadebyte/auctionhouse/cmds/subcmds/ReloadCommand.java b/src/main/java/com/shadebyte/auctionhouse/cmds/subcmds/ReloadCommand.java new file mode 100644 index 0000000..21e437f --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/cmds/subcmds/ReloadCommand.java @@ -0,0 +1,10 @@ +package com.shadebyte.auctionhouse.cmds.subcmds; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:51 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public class ReloadCommand { +} diff --git a/src/main/java/com/shadebyte/auctionhouse/cmds/subcmds/SellCommand.java b/src/main/java/com/shadebyte/auctionhouse/cmds/subcmds/SellCommand.java new file mode 100644 index 0000000..66cea42 --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/cmds/subcmds/SellCommand.java @@ -0,0 +1,10 @@ +package com.shadebyte.auctionhouse.cmds.subcmds; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:50 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public class SellCommand { +} diff --git a/src/main/java/com/shadebyte/auctionhouse/inventory/AGUI.java b/src/main/java/com/shadebyte/auctionhouse/inventory/AGUI.java new file mode 100644 index 0000000..07112cc --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/inventory/AGUI.java @@ -0,0 +1,11 @@ +package com.shadebyte.auctionhouse.inventory; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:54 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public interface AGUI { + +} diff --git a/src/main/java/com/shadebyte/auctionhouse/inventory/inventories/AuctionGUI.java b/src/main/java/com/shadebyte/auctionhouse/inventory/inventories/AuctionGUI.java new file mode 100644 index 0000000..431aeaa --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/inventory/inventories/AuctionGUI.java @@ -0,0 +1,10 @@ +package com.shadebyte.auctionhouse.inventory.inventories; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:56 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public class AuctionGUI { +} diff --git a/src/main/java/com/shadebyte/auctionhouse/inventory/inventories/ConfirmationGUI.java b/src/main/java/com/shadebyte/auctionhouse/inventory/inventories/ConfirmationGUI.java new file mode 100644 index 0000000..4669832 --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/inventory/inventories/ConfirmationGUI.java @@ -0,0 +1,10 @@ +package com.shadebyte.auctionhouse.inventory.inventories; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:56 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public class ConfirmationGUI { +} diff --git a/src/main/java/com/shadebyte/auctionhouse/inventory/inventories/ExpiredGUI.java b/src/main/java/com/shadebyte/auctionhouse/inventory/inventories/ExpiredGUI.java new file mode 100644 index 0000000..74000f3 --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/inventory/inventories/ExpiredGUI.java @@ -0,0 +1,10 @@ +package com.shadebyte.auctionhouse.inventory.inventories; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:56 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public class ExpiredGUI { +} diff --git a/src/main/java/com/shadebyte/auctionhouse/inventory/inventories/ListingsGUI.java b/src/main/java/com/shadebyte/auctionhouse/inventory/inventories/ListingsGUI.java new file mode 100644 index 0000000..dd4cd83 --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/inventory/inventories/ListingsGUI.java @@ -0,0 +1,10 @@ +package com.shadebyte.auctionhouse.inventory.inventories; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:56 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public class ListingsGUI { +} diff --git a/src/main/java/com/shadebyte/auctionhouse/util/ConfigWrapper.java b/src/main/java/com/shadebyte/auctionhouse/util/ConfigWrapper.java new file mode 100644 index 0000000..b962c72 --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/util/ConfigWrapper.java @@ -0,0 +1,74 @@ +package com.shadebyte.auctionhouse.util; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:59 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.File; +import java.io.IOException; +import java.util.logging.Level; + +/* + Made by @Clip + */ + +public class ConfigWrapper { + + private final JavaPlugin plugin; + private FileConfiguration config; + private File configFile; + private final String folderName, fileName; + + public ConfigWrapper(final JavaPlugin instance, final String folderName, final String fileName) { + this.plugin = instance; + this.folderName = folderName; + this.fileName = fileName; + } + + public void createNewFile(final String message, final String header) { + reloadConfig(); + saveConfig(); + loadConfig(header); + + if (message != null) { + plugin.getLogger().info(message); + } + } + + public FileConfiguration getConfig() { + if (config == null) { + reloadConfig(); + } + return config; + } + + public void loadConfig(final String header) { + config.options().header(header); + config.options().copyDefaults(true); + saveConfig(); + } + + public void reloadConfig() { + if (configFile == null) { + configFile = new File(plugin.getDataFolder() + folderName, fileName); + } + config = YamlConfiguration.loadConfiguration(configFile); + } + + public void saveConfig() { + if (config == null || configFile == null) { + return; + } + try { + getConfig().save(configFile); + } catch (final IOException ex) { + plugin.getLogger().log(Level.SEVERE, "Could not save config to " + configFile, ex); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/shadebyte/auctionhouse/util/Debugger.java b/src/main/java/com/shadebyte/auctionhouse/util/Debugger.java new file mode 100644 index 0000000..d3bb229 --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/util/Debugger.java @@ -0,0 +1,29 @@ +package com.shadebyte.auctionhouse.util; + +import com.shadebyte.auctionhouse.Core; +import org.bukkit.Bukkit; + +import static org.bukkit.ChatColor.translateAlternateColorCodes; + +/** + * The current file has been created by Kiran Hart + * Date Created: 7/6/2018 + * Time Created: 11:59 AM + * Usage of any code found within this class is prohibited unless given explicit permission otherwise. + */ +public class Debugger { + + public static void report(Exception e) { + if (debugEnabled()) { + Bukkit.getConsoleSender().sendMessage(translateAlternateColorCodes('&', "&b================================================================")); + Bukkit.getConsoleSender().sendMessage(translateAlternateColorCodes('&', "&eAuction House has ran into an error, report this to the author.")); + Bukkit.getConsoleSender().sendMessage(translateAlternateColorCodes('&', "&b----------------------------------------------------------------")); + e.printStackTrace(); + Bukkit.getConsoleSender().sendMessage(translateAlternateColorCodes('&', "&b================================================================")); + } + } + + private static boolean debugEnabled() { + return Core.getInstance().getConfig().getBoolean("debugger"); + } +} diff --git a/src/main/java/com/shadebyte/auctionhouse/util/Locale.java b/src/main/java/com/shadebyte/auctionhouse/util/Locale.java new file mode 100644 index 0000000..abfc4f0 --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/util/Locale.java @@ -0,0 +1,364 @@ +package com.shadebyte.auctionhouse.util; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import org.apache.commons.io.IOUtils; +import org.bukkit.ChatColor; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * Assists in the creation of multiple localizations and languages, + * as well as the generation of default .lang files + * + * @author Parker Hawke - 2008Choco + */ +public class Locale { + + private static JavaPlugin plugin; + private static final List LOCALES = Lists.newArrayList(); + + private static final Pattern NODE_PATTERN = Pattern.compile("(\\w+(?:\\.\\w+)*)\\s*=\\s*\"(.*)\""); + private static final String FILE_EXTENSION = ".lang"; + private static File localeFolder; + + private static String defaultLocale; + + private final Map nodes = new HashMap<>(); + + private final File file; + private final String name, region; + + private Locale(String name, String region) { + if (plugin == null) + throw new IllegalStateException("Cannot generate locales without first initializing the class (Locale#init(JavaPlugin))"); + + this.name = name.toLowerCase(); + this.region = region.toUpperCase(); + + String fileName = name + "_" + region + FILE_EXTENSION; + this.file = new File(localeFolder, fileName); + + if (this.reloadMessages()) return; + + plugin.getLogger().info("Loaded locale " + fileName); + } + + /** + * Get the name of the language that this locale is based on. + * (i.e. "en" for English, or "fr" for French) + * + * @return the name of the language + */ + public String getName() { + return name; + } + + /** + * Get the name of the region that this locale is from. + * (i.e. "US" for United States or "CA" for Canada) + * + * @return the name of the region + */ + public String getRegion() { + return region; + } + + /** + * Return the entire locale tag (i.e. "en_US") + * + * @return the language tag + */ + public String getLanguageTag() { + return name + "_" + region; + } + + /** + * Get the file that represents this locale + * + * @return the locale file (.lang) + */ + public File getFile() { + return file; + } + + /** + * Get a message set for a specific node + * + * @param node the node to get + * @return the message for the specified node + */ + public String getMessage(String node) { + return ChatColor.translateAlternateColorCodes('&', this.getMessageOrDefault(node, node)); + } + + /** + * Get a message set for a specific node and replace its params with a supplied arguments. + * + * @param node the node to get + * @param args the replacement arguments + * @return the message for the specified node + */ + public String getMessage(String node, Object... args) { + String message = getMessage(node); + for (Object arg : args) { + message = message.replaceFirst("%.*?%", arg.toString()); + } + return message; + } + + /** + * Get a message set for a specific node + * + * @param node the node to get + * @param defaultValue the default value given that a value for the node was not found + * @return the message for the specified node. Default if none found + */ + public String getMessageOrDefault(String node, String defaultValue) { + return this.nodes.getOrDefault(node, defaultValue); + } + + /** + * Get the key-value map of nodes to messages + * + * @return node-message map + */ + public Map getMessageNodeMap() { + return ImmutableMap.copyOf(nodes); + } + + /** + * Clear the previous message cache and load new messages directly from file + * + * @return reload messages from file + */ + public boolean reloadMessages() { + if (!this.file.exists()) { + plugin.getLogger().warning("Could not find file for locale " + this.name); + return false; + } + + this.nodes.clear(); // Clear previous data (if any) + + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line; + for (int lineNumber = 0; (line = reader.readLine()) != null; lineNumber++) { + if (line.isEmpty() || line.startsWith("#") /* Comment */) continue; + + Matcher matcher = NODE_PATTERN.matcher(line); + if (!matcher.find()) { + System.err.println("Invalid locale syntax at (line=" + lineNumber + ")"); + continue; + } + + nodes.put(matcher.group(1), matcher.group(2)); + } + } catch (IOException e) { + e.printStackTrace(); + return false; + } + return true; + } + + /** + * Initialize the locale class to generate information and search for localizations. + * This must be called before any other methods in the Locale class can be invoked. + * Note that this will also call {@link #searchForLocales()}, so there is no need to + * invoke it for yourself after the initialization + * + * @param plugin the plugin instance + */ + public static void init(JavaPlugin plugin) { + Locale.plugin = plugin; + + if (localeFolder == null) { + localeFolder = new File(plugin.getDataFolder(), "locales/"); + } + + localeFolder.mkdirs(); + Locale.searchForLocales(); + } + + /** + * Find all .lang file locales under the "locales" folder + */ + public static void searchForLocales() { + if (!localeFolder.exists()) localeFolder.mkdirs(); + + for (File file : localeFolder.listFiles()) { + String name = file.getName(); + if (!name.endsWith(".lang")) continue; + + String fileName = name.substring(0, name.lastIndexOf('.')); + String[] localeValues = fileName.split("_"); + + if (localeValues.length != 2) continue; + if (localeExists(localeValues[0] + "_" + localeValues[1])) continue; + + LOCALES.add(new Locale(localeValues[0], localeValues[1])); + plugin.getLogger().info("Found and loaded locale \"" + fileName + "\""); + } + } + + /** + * Get a locale by its entire proper name (i.e. "en_US") + * + * @param name the full name of the locale + * @return locale of the specified name + */ + public static Locale getLocale(String name) { + for (Locale locale : LOCALES) + if (locale.getLanguageTag().equalsIgnoreCase(name)) return locale; + return null; + } + + /** + * Get a locale from the cache by its name (i.e. "en" from "en_US") + * + * @param name the name of the language + * @return locale of the specified language. Null if not cached + */ + public static Locale getLocaleByName(String name) { + for (Locale locale : LOCALES) + if (locale.getName().equalsIgnoreCase(name)) return locale; + return null; + } + + /** + * Get a locale from the cache by its region (i.e. "US" from "en_US") + * + * @param region the name of the region + * @return locale of the specified region. Null if not cached + */ + public static Locale getLocaleByRegion(String region) { + for (Locale locale : LOCALES) + if (locale.getRegion().equalsIgnoreCase(region)) return locale; + return null; + } + + /** + * Check whether a locale exists and is registered or not + * + * @param name the whole language tag (i.e. "en_US") + * @return true if it exists + */ + public static boolean localeExists(String name) { + for (Locale locale : LOCALES) + if (locale.getLanguageTag().equals(name)) return true; + return false; + } + + /** + * Get an immutable list of all currently loaded locales + * + * @return list of all locales + */ + public static List getLocales() { + return ImmutableList.copyOf(LOCALES); + } + + /** + * Save a default locale file from the project source directory, to the locale folder + * + * @param path the path to the file to save + * @param fileName the name of the file to save + * @return true if the operation was successful, false otherwise + */ + public static boolean saveDefaultLocale(String path, String fileName) { + if (!localeFolder.exists()) localeFolder.mkdirs(); + + if (!fileName.endsWith(FILE_EXTENSION)) + fileName = (fileName.lastIndexOf(".") == -1 ? fileName : fileName.substring(0, fileName.lastIndexOf('.'))) + FILE_EXTENSION; + + File destinationFile = new File(localeFolder, fileName); + if (destinationFile.exists()) { + return compareFiles(plugin.getResource(fileName), destinationFile); + } + + try (OutputStream outputStream = new FileOutputStream(destinationFile)) { + IOUtils.copy(plugin.getResource(fileName), outputStream); + + fileName = fileName.substring(0, fileName.lastIndexOf('.')); + String[] localeValues = fileName.split("_"); + + if (localeValues.length != 2) return false; + + LOCALES.add(new Locale(localeValues[0], localeValues[1])); + if (defaultLocale == null) defaultLocale = fileName; + + return true; + } catch (IOException e) { + return false; + } + } + + /** + * Save a default locale file from the project source directory, to the locale folder + * + * @param fileName the name of the file to save + * @return true if the operation was successful, false otherwise + */ + public static boolean saveDefaultLocale(String fileName) { + return saveDefaultLocale("", fileName); + } + + /** + * Clear all current locale data + */ + public static void clearLocaleData() { + for (Locale locale : LOCALES) + locale.nodes.clear(); + LOCALES.clear(); + } + + // Write new changes to existing files, if any at all + private static boolean compareFiles(InputStream defaultFile, File existingFile) { + // Look for default + if (defaultFile == null) { + defaultFile = plugin.getResource(defaultLocale != null ? defaultLocale : "en_US"); + if (defaultFile == null) return false; // No default at all + } + + boolean changed = false; + + List defaultLines, existingLines; + try (BufferedReader defaultReader = new BufferedReader(new InputStreamReader(defaultFile)); + BufferedReader existingReader = new BufferedReader(new FileReader(existingFile)); + BufferedWriter writer = new BufferedWriter(new FileWriter(existingFile, true))) { + defaultLines = defaultReader.lines().collect(Collectors.toList()); + existingLines = existingReader.lines().map(s -> s.split("\\s*=")[0]).collect(Collectors.toList()); + + for (String defaultValue : defaultLines) { + if (defaultValue.isEmpty() || defaultValue.startsWith("#")) continue; + + String key = defaultValue.split("\\s*=")[0]; + + if (!existingLines.contains(key)) { + if (!changed) { + writer.newLine(); + writer.newLine(); + writer.write("# New messages for " + plugin.getName() + " v" + plugin.getDescription().getVersion()); + } + + writer.newLine(); + writer.write(defaultValue); + + changed = true; + } + } + } catch (IOException e) { + return false; + } + + return changed; + } + +} \ No newline at end of file diff --git a/src/main/java/com/shadebyte/auctionhouse/util/NBTEditor.java b/src/main/java/com/shadebyte/auctionhouse/util/NBTEditor.java new file mode 100644 index 0000000..6cb2ba4 --- /dev/null +++ b/src/main/java/com/shadebyte/auctionhouse/util/NBTEditor.java @@ -0,0 +1,460 @@ +package com.shadebyte.auctionhouse.util; + +import com.google.common.primitives.Primitives; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.inventory.ItemStack; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Sets/Gets NBT tags from ItemStacks + * + * @author BananaPuncher714 + * @version 5.0 + */ +public class NBTEditor { + private static HashMap> classCache; + private static HashMap methodCache; + private static HashMap, Constructor> constructorCache; + private static HashMap, Class> NBTClasses; + private static HashMap, Field> NBTTagFieldCache; + private static Field NBTListData; + private static Field NBTCompoundMap; + private static String version; + + static { + version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; + + classCache = new HashMap>(); + try { + classCache.put("NBTBase", Class.forName("net.minecraft.server." + version + "." + "NBTBase")); + classCache.put("NBTTagCompound", Class.forName("net.minecraft.server." + version + "." + "NBTTagCompound")); + classCache.put("NBTTagList", Class.forName("net.minecraft.server." + version + "." + "NBTTagList")); + classCache.put("NBTBase", Class.forName("net.minecraft.server." + version + "." + "NBTBase")); + + classCache.put("ItemStack", Class.forName("net.minecraft.server." + version + "." + "ItemStack")); + classCache.put("CraftItemStack", Class.forName("org.bukkit.craftbukkit." + version + ".inventory." + "CraftItemStack")); + + classCache.put("Entity", Class.forName("net.minecraft.server." + version + "." + "Entity")); + classCache.put("CraftEntity", Class.forName("org.bukkit.craftbukkit." + version + ".entity." + "CraftEntity")); + classCache.put("EntityLiving", Class.forName("net.minecraft.server." + version + "." + "EntityLiving")); + + classCache.put("CraftWorld", Class.forName("org.bukkit.craftbukkit." + version + "." + "CraftWorld")); + classCache.put("CraftBlockState", Class.forName("org.bukkit.craftbukkit." + version + ".block." + "CraftBlockState")); + classCache.put("BlockPosition", Class.forName("net.minecraft.server." + version + "." + "BlockPosition")); + classCache.put("TileEntity", Class.forName("net.minecraft.server." + version + "." + "TileEntity")); + classCache.put("World", Class.forName("net.minecraft.server." + version + "." + "World")); + + classCache.put("TileEntitySkull", Class.forName("net.minecraft.server." + version + "." + "TileEntitySkull")); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + + NBTClasses = new HashMap, Class>(); + try { + NBTClasses.put(Byte.class, Class.forName("net.minecraft.server." + version + "." + "NBTTagByte")); + NBTClasses.put(String.class, Class.forName("net.minecraft.server." + version + "." + "NBTTagString")); + NBTClasses.put(Double.class, Class.forName("net.minecraft.server." + version + "." + "NBTTagDouble")); + NBTClasses.put(Integer.class, Class.forName("net.minecraft.server." + version + "." + "NBTTagInt")); + NBTClasses.put(Long.class, Class.forName("net.minecraft.server." + version + "." + "NBTTagLong")); + NBTClasses.put(Short.class, Class.forName("net.minecraft.server." + version + "." + "NBTTagShort")); + NBTClasses.put(Float.class, Class.forName("net.minecraft.server." + version + "." + "NBTTagFloat")); + NBTClasses.put(Class.forName("[B"), Class.forName("net.minecraft.server." + version + "." + "NBTTagByteArray")); + NBTClasses.put(Class.forName("[I"), Class.forName("net.minecraft.server." + version + "." + "NBTTagIntArray")); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + + methodCache = new HashMap(); + try { + methodCache.put("get", getNMSClass("NBTTagCompound").getMethod("get", String.class)); + methodCache.put("set", getNMSClass("NBTTagCompound").getMethod("set", String.class, getNMSClass("NBTBase"))); + methodCache.put("hasKey", getNMSClass("NBTTagCompound").getMethod("hasKey", String.class)); + methodCache.put("setIndex", getNMSClass("NBTTagList").getMethod("a", int.class, getNMSClass("NBTBase"))); + methodCache.put("add", getNMSClass("NBTTagList").getMethod("add", getNMSClass("NBTBase"))); + + methodCache.put("hasTag", getNMSClass("ItemStack").getMethod("hasTag")); + methodCache.put("getTag", getNMSClass("ItemStack").getMethod("getTag")); + methodCache.put("setTag", getNMSClass("ItemStack").getMethod("setTag", getNMSClass("NBTTagCompound"))); + methodCache.put("asNMSCopy", getNMSClass("CraftItemStack").getMethod("asNMSCopy", ItemStack.class)); + methodCache.put("asBukkitCopy", getNMSClass("CraftItemStack").getMethod("asBukkitCopy", getNMSClass("ItemStack"))); + + methodCache.put("getEntityHandle", getNMSClass("CraftEntity").getMethod("getHandle")); + methodCache.put("getEntityTag", getNMSClass("Entity").getMethod("c", getNMSClass("NBTTagCompound"))); + methodCache.put("setEntityTag", getNMSClass("Entity").getMethod("f", getNMSClass("NBTTagCompound"))); + + if (version.contains("1_12")) { + methodCache.put("setTileTag", getNMSClass("TileEntity").getMethod("load", getNMSClass("NBTTagCompound"))); + } else { + methodCache.put("setTileTag", getNMSClass("TileEntity").getMethod("a", getNMSClass("NBTTagCompound"))); + } + methodCache.put("getTileEntity", getNMSClass("World").getMethod("getTileEntity", getNMSClass("BlockPosition"))); + methodCache.put("getWorldHandle", getNMSClass("CraftWorld").getMethod("getHandle")); + + //methodCache.put( "setGameProfile", getNMSClass( "TileEntitySkull" ).getMethod( "setGameProfile", GameProfile.class ) ); + } catch (Exception e) { + e.printStackTrace(); + } + + try { + methodCache.put("getTileTag", getNMSClass("TileEntity").getMethod("save", getNMSClass("NBTTagCompound"))); + } catch (NoSuchMethodException exception) { + try { + methodCache.put("getTileTag", getNMSClass("TileEntity").getMethod("b", getNMSClass("NBTTagCompound"))); + } catch (Exception exception2) { + exception2.printStackTrace(); + } + } catch (Exception exception) { + exception.printStackTrace(); + } + + constructorCache = new HashMap, Constructor>(); + try { + constructorCache.put(getNBTTag(Byte.class), getNBTTag(Byte.class).getConstructor(byte.class)); + constructorCache.put(getNBTTag(String.class), getNBTTag(String.class).getConstructor(String.class)); + constructorCache.put(getNBTTag(Double.class), getNBTTag(Double.class).getConstructor(double.class)); + constructorCache.put(getNBTTag(Integer.class), getNBTTag(Integer.class).getConstructor(int.class)); + constructorCache.put(getNBTTag(Long.class), getNBTTag(Long.class).getConstructor(long.class)); + constructorCache.put(getNBTTag(Float.class), getNBTTag(Float.class).getConstructor(float.class)); + constructorCache.put(getNBTTag(Short.class), getNBTTag(Short.class).getConstructor(short.class)); + constructorCache.put(getNBTTag(Class.forName("[B")), getNBTTag(Class.forName("[B")).getConstructor(Class.forName("[B"))); + constructorCache.put(getNBTTag(Class.forName("[I")), getNBTTag(Class.forName("[I")).getConstructor(Class.forName("[I"))); + + constructorCache.put(getNMSClass("BlockPosition"), getNMSClass("BlockPosition").getConstructor(int.class, int.class, int.class)); + } catch (Exception e) { + e.printStackTrace(); + } + + NBTTagFieldCache = new HashMap, Field>(); + try { + for (Class clazz : NBTClasses.values()) { + Field data = clazz.getDeclaredField("data"); + data.setAccessible(true); + NBTTagFieldCache.put(clazz, data); + } + } catch (Exception e) { + e.printStackTrace(); + } + + try { + NBTListData = getNMSClass("NBTTagList").getDeclaredField("list"); + NBTListData.setAccessible(true); + NBTCompoundMap = getNMSClass("NBTTagCompound").getDeclaredField("map"); + NBTCompoundMap.setAccessible(true); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static Class getPrimitiveClass(Class clazz) { + return Primitives.unwrap(clazz); + } + + public static Class getNBTTag(Class primitiveType) { + if (NBTClasses.containsKey(primitiveType)) + return NBTClasses.get(primitiveType); + return primitiveType; + } + + public static Object getNBTVar(Object object) { + if (object == null) return null; + Class clazz = object.getClass(); + try { + if (NBTTagFieldCache.containsKey(clazz)) { + return NBTTagFieldCache.get(clazz).get(object); + } + } catch (Exception exception) { + exception.printStackTrace(); + } + return null; + } + + public static Method getMethod(String name) { + return methodCache.containsKey(name) ? methodCache.get(name) : null; + } + + public static Constructor getConstructor(Class clazz) { + return constructorCache.containsKey(clazz) ? constructorCache.get(clazz) : null; + } + + public static Class getNMSClass(String name) { + if (classCache.containsKey(name)) { + return classCache.get(name); + } + + try { + return Class.forName("net.minecraft.server." + version + "." + name); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + return null; + } + } + + public static String getMatch(String string, String regex) { + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(string); + if (matcher.find()) { + return matcher.group(1); + } else { + return null; + } + } + + /** + * Gets an NBT tag in a given item with the specified keys + * + * @param item The itemstack to get the keys from + * @param key The keys to fetch; an integer after a key value indicates that it should get the nth place of + * the previous compound because it is a list; + * @return The item represented by the keys, and an integer if it is showing how long a list is. + */ + public static Object getItemTag(ItemStack item, Object... keys) { + try { + Object stack = null; + stack = getMethod("asNMSCopy").invoke(null, item); + + Object tag = null; + + if (getMethod("hasTag").invoke(stack).equals(true)) { + tag = getMethod("getTag").invoke(stack); + } else { + tag = getNMSClass("NBTTagCompound").newInstance(); + } + + return getTag(tag, keys); + } catch (Exception exception) { + exception.printStackTrace(); + return null; + } + } + + /** + * Sets an NBT tag in an item with the provided keys and value + * + * @param item The itemstack to set + * @param key The keys to set, String for NBTCompound, int or null for an NBTTagList + * @param value The value to set + * @return A new ItemStack with the updated NBT tags + */ + public static ItemStack setItemTag(ItemStack item, Object value, Object... keys) { + try { + Object stack = getMethod("asNMSCopy").invoke(null, item); + + Object tag = null; + + if (getMethod("hasTag").invoke(stack).equals(true)) { + tag = getMethod("getTag").invoke(stack); + } else { + tag = getNMSClass("NBTTagCompound").newInstance(); + } + + setTag(tag, value, keys); + getMethod("setTag").invoke(stack, tag); + return (ItemStack) getMethod("asBukkitCopy").invoke(null, stack); + } catch (Exception exception) { + exception.printStackTrace(); + return null; + } + } + + /** + * Gets an NBT tag in a given entity with the specified keys + * + * @param block The entity to get the keys from + * @param key The keys to fetch; an integer after a key value indicates that it should get the nth place of + * the previous compound because it is a list; + * @return The item represented by the keys, and an integer if it is showing how long a list is. + */ + public static Object getEntityTag(Entity entity, Object... keys) { + try { + Object NMSEntity = getMethod("getEntityHandle").invoke(entity); + + Object tag = getNMSClass("NBTTagCompound").newInstance(); + + getMethod("getEntityTag").invoke(NMSEntity, tag); + + return getTag(tag, keys); + } catch (Exception exception) { + exception.printStackTrace(); + return null; + } + } + + /** + * Sets an NBT tag in an entity with the provided keys and value + * + * @param item The entity to set + * @param key The keys to set, String for NBTCompound, int or null for an NBTTagList + * @param value The value to set + * @return A new ItemStack with the updated NBT tags + */ + public static void setEntityTag(Entity entity, Object value, Object... keys) { + try { + Object NMSEntity = getMethod("getEntityHandle").invoke(entity); + + Object tag = getNMSClass("NBTTagCompound").newInstance(); + + getMethod("getEntityTag").invoke(NMSEntity, tag); + + setTag(tag, value, keys); + + getMethod("setEntityTag").invoke(NMSEntity, tag); + } catch (Exception exception) { + exception.printStackTrace(); + return; + } + } + + /** + * Gets an NBT tag in a given block with the specified keys + * + * @param block The block to get the keys from + * @param key The keys to fetch; an integer after a key value indicates that it should get the nth place of + * the previous compound because it is a list; + * @return The item represented by the keys, and an integer if it is showing how long a list is. + */ + public static Object getBlockTag(Block block, Object... keys) { + try { + if (!getNMSClass("CraftBlockState").isInstance(block.getState())) { + return null; + } + + Object tileEntity = getMethod("getTileEntity").invoke(block.getState()); + + Object tag = getMethod("getTileTag").invoke(tileEntity, getNMSClass("NBTTagCompound").newInstance()); + + return getTag(tag, keys); + } catch (Exception exception) { + exception.printStackTrace(); + return null; + } + } + + /** + * Sets an NBT tag in an block with the provided keys and value + * + * @param item The block to set + * @param key The keys to set, String for NBTCompound, int or null for an NBTTagList + * @param value The value to set + * @return A new ItemStack with the updated NBT tags + */ + public static void setBlockTag(Block block, Object value, Object... keys) { + try { + Location location = block.getLocation(); + + Object blockPosition = getConstructor(getNMSClass("BlockPosition")).newInstance(location.getBlockX(), location.getBlockY(), location.getBlockZ()); + + Object nmsWorld = getMethod("getWorldHandle").invoke(location.getWorld()); + + Object tileEntity = getMethod("getTileEntity").invoke(nmsWorld, blockPosition); + + Object tag = getMethod("getTileTag").invoke(tileEntity, getNMSClass("NBTTagCompound").newInstance()); + + setTag(tag, value, keys); + + getMethod("setTileTag").invoke(tileEntity, tag); + } catch (Exception exception) { + exception.printStackTrace(); + return; + } + } + + private static void setTag(Object tag, Object value, Object... keys) throws Exception { + Object notCompound = getConstructor(getNBTTag(value.getClass())).newInstance(value); + + Object compound = tag; + for (int index = 0; index < keys.length; index++) { + Object key = keys[index]; + if (index + 1 == keys.length) { + if (key == null) { + getMethod("add").invoke(compound, notCompound); + } else if (key instanceof Integer) { + getMethod("setIndex").invoke(compound, (int) key, notCompound); + } else { + getMethod("set").invoke(compound, (String) key, notCompound); + } + break; + } + Object oldCompound = compound; + if (key instanceof Integer) { + compound = ((List) NBTListData.get(compound)).get((int) key); + } else if (key != null) { + compound = getMethod("get").invoke(compound, (String) key); + } + if (compound == null || key == null) { + if (keys[index + 1] == null || keys[index + 1] instanceof Integer) { + compound = getNMSClass("NBTTagList").newInstance(); + } else { + compound = getNMSClass("NBTTagCompound").newInstance(); + } + if (oldCompound.getClass().getSimpleName().equals("NBTTagList")) { + getMethod("add").invoke(oldCompound, compound); + } else { + getMethod("set").invoke(oldCompound, (String) key, compound); + } + } + } + } + + private static Object getTag(Object tag, Object... keys) throws Exception { + if (keys.length == 0) return getTags(tag); + + Object notCompound = tag; + + for (Object key : keys) { + if (notCompound == null) return null; + if (getNMSClass("NBTTagCompound").isInstance(notCompound)) { + notCompound = getMethod("get").invoke(notCompound, (String) key); + } else if (getNMSClass("NBTTagList").isInstance(notCompound)) { + notCompound = ((List) NBTListData.get(notCompound)).get((int) key); + } else { + return getNBTVar(notCompound); + } + } + if (notCompound == null) return null; + if (getNMSClass("NBTTagList").isInstance(notCompound)) { + return getTags(notCompound); + } else if (getNMSClass("NBTTagCompound").isInstance(notCompound)) { + return getTags(notCompound); + } else { + return getNBTVar(notCompound); + } + } + + private static Object getTags(Object tag) { + HashMap tags = new HashMap(); + try { + if (getNMSClass("NBTTagCompound").isInstance(tag)) { + Map tagCompound = (Map) NBTCompoundMap.get(tag); + for (String key : tagCompound.keySet()) { + Object value = tagCompound.get(key); + if (getNMSClass("NBTTagEnd").isInstance(value)) continue; + tags.put(key, getTag(value)); + } + } else if (getNMSClass("NBTTagList").isInstance(tag)) { + List tagList = (List) NBTListData.get(tag); + for (int index = 0; index < tagList.size(); index++) { + Object value = tagList.get(index); + if (getNMSClass("NBTTagEnd").isInstance(value)) continue; + tags.put(index, getTag(value)); + } + } else { + return getNBTVar(tag); + } + return tags; + } catch (Exception e) { + e.printStackTrace(); + return tags; + } + } +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/en_US.lang b/src/main/resources/en_US.lang new file mode 100644 index 0000000..e69de29