diff options
| author | fatpigsarefat <fatpigsarefat@outlook.com> | 2018-10-20 22:08:50 +0100 |
|---|---|---|
| committer | fatpigsarefat <fatpigsarefat@outlook.com> | 2018-10-20 22:08:53 +0100 |
| commit | 6a1bc9583140b6266df1ddf154b81970fd7ddb88 (patch) | |
| tree | bea85a0acdca464358bcde6d6e0cab4e53355803 /src/main/java/com/leonardobishop | |
| parent | bcbb43392cd45e03a68bc581396fc5bbac691080 (diff) | |
Namespace has changed
- Changed package to com.leonardobishop.quests
- Incremented version number
- No longer in beta
Diffstat (limited to 'src/main/java/com/leonardobishop')
64 files changed, 5644 insertions, 0 deletions
diff --git a/src/main/java/com/leonardobishop/quests/Quests.java b/src/main/java/com/leonardobishop/quests/Quests.java new file mode 100644 index 00000000..c5b46ff6 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/Quests.java @@ -0,0 +1,461 @@ +package com.leonardobishop.quests; + +import com.leonardobishop.quests.bstats.Metrics; +import com.leonardobishop.quests.events.EventInventory; +import com.leonardobishop.quests.events.EventPlayerJoin; +import com.leonardobishop.quests.events.EventPlayerLeave; +import com.leonardobishop.quests.obj.misc.QItemStack; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.QPlayerManager; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Category; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.QuestManager; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.TaskTypeManager; +import com.fatpigsarefat.quests.quests.tasktypes.types.*; +import com.leonardobishop.quests.title.Title; +import com.leonardobishop.quests.title.Title_Bukkit; +import com.leonardobishop.quests.title.Title_BukkitNoTimings; +import com.leonardobishop.quests.title.Title_Other; +import com.google.common.io.ByteStreams; +import com.leonardobishop.quests.blocktype.SimilarBlocks; +import com.leonardobishop.quests.commands.CommandQuests; +import com.leonardobishop.quests.quests.tasktypes.types.*; +import me.fatpigsarefat.quests.quests.tasktypes.types.*; +import me.fatpigsarefat.quests.title.*; +import com.leonardobishop.quests.updater.Updater; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitRunnable; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; + +public class Quests extends JavaPlugin { + + private static Quests instance; + private static QuestManager questManager; + private static QPlayerManager qPlayerManager; + private static TaskTypeManager taskTypeManager; + private static Updater updater; + private static Title title; + private boolean brokenConfig = false; + + public static Quests getInstance() { + return instance; + } + + public static QuestManager getQuestManager() { + return questManager; + } + + public static QPlayerManager getPlayerManager() { + return qPlayerManager; + } + + public static TaskTypeManager getTaskTypeManager() { + return taskTypeManager; + } + + public boolean isBrokenConfig() { + return brokenConfig; + } + + public static Title getTitle() { + return title; + } + + public static Updater getUpdater() { + return updater; + } + + public static String convertToFormat(long m) { + long hours = m / 60; + long minutesLeft = m - hours * 60; + + String formattedTime = ""; + + if (hours < 10) + formattedTime = formattedTime + "0"; + formattedTime = formattedTime + hours + "h"; + + formattedTime = formattedTime + " "; + + if (minutesLeft < 10) + formattedTime = formattedTime + "0"; + formattedTime = formattedTime + minutesLeft + "m"; + + return formattedTime; + } + + @Override + public void onEnable() { + instance = this; + taskTypeManager = new TaskTypeManager(); + questManager = new QuestManager(); + qPlayerManager = new QPlayerManager(); + + dataGenerator(); + setupTitle(); + + taskTypeManager.registerTaskType(new MiningTaskType()); + taskTypeManager.registerTaskType(new MiningCertainTaskType()); + taskTypeManager.registerTaskType(new BuildingTaskType()); + taskTypeManager.registerTaskType(new BuildingCertainTaskType()); + taskTypeManager.registerTaskType(new MobkillingTaskType()); + taskTypeManager.registerTaskType(new MobkillingCertainTaskType()); + taskTypeManager.registerTaskType(new PlayerkillingTaskType()); + taskTypeManager.registerTaskType(new FishingTaskType()); + taskTypeManager.registerTaskType(new InventoryTaskType()); + taskTypeManager.registerTaskType(new WalkingTaskType()); + taskTypeManager.registerTaskType(new TamingTaskType()); + taskTypeManager.registerTaskType(new MilkingTaskType()); + taskTypeManager.registerTaskType(new ShearingTaskType()); + taskTypeManager.registerTaskType(new PositionTaskType()); + taskTypeManager.registerTaskType(new PlaytimeTaskType()); + taskTypeManager.registerTaskType(new BrewingTaskType()); + // TODO: FIX + // taskTypeManager.registerTaskType(new BrewingCertainTaskType()); + if (Bukkit.getPluginManager().isPluginEnabled("ASkyBlock")) { + taskTypeManager.registerTaskType(new ASkyBlockLevelType()); + } + if (Bukkit.getPluginManager().isPluginEnabled("uSkyBlock")) { + taskTypeManager.registerTaskType(new uSkyBlockLevelType()); + } + + Bukkit.getPluginCommand("quests").setExecutor(new CommandQuests()); + Bukkit.getPluginManager().registerEvents(new EventPlayerJoin(), this); + Bukkit.getPluginManager().registerEvents(new EventInventory(), this); + Bukkit.getPluginManager().registerEvents(new EventPlayerLeave(), this); + + Metrics metrics = new Metrics(this); + this.getLogger().log(Level.INFO, "Metrics started. This can be disabled at /plugins/bStats/config.yml."); + + SimilarBlocks.addBlocks(); + + new BukkitRunnable() { + @Override + public void run() { + reloadQuests(); + + for (Player player : Bukkit.getOnlinePlayers()) { + qPlayerManager.loadPlayer(player.getUniqueId()); + } + } + }.runTask(this); + new BukkitRunnable() { + @Override + public void run() { + for (QPlayer qPlayer : qPlayerManager.getQPlayers()) { + if (qPlayer.isOnlyDataLoaded()) { + continue; + } + qPlayer.getQuestProgressFile().saveToDisk(); + } + } + }.runTaskTimerAsynchronously(this, 12000L, 12000L); + new BukkitRunnable() { + @Override + public void run() { + for (QPlayer qPlayer : qPlayerManager.getQPlayers()) { + if (qPlayer.isOnlyDataLoaded()) { + continue; + } + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); + for (Map.Entry<String, Quest> entry : Quests.getQuestManager().getQuests().entrySet()) { + String id = entry.getKey(); + Quest quest = entry.getValue(); + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); + if (questProgress != null && questProgress.isStarted()) { + boolean complete = true; + for (TaskProgress taskProgress : questProgress.getTaskProgress()) { + if (!taskProgress.isCompleted()) { + complete = false; + break; + } + } + if (complete) { + questProgressFile.completeQuest(quest); + } + } + } + } + } + }.runTaskTimerAsynchronously(this, 20L, 20L); + new BukkitRunnable() { + @Override + public void run() { + updater = new Updater(Quests.this); + updater.check(); + } + }.runTaskAsynchronously(this); + } + + @Override + public void onDisable() { + for (QPlayer qPlayer : qPlayerManager.getQPlayers()) { + if (qPlayer.isOnlyDataLoaded()) { + continue; + } + qPlayer.getQuestProgressFile().saveToDisk(); + } + } + + public void reloadQuests() { + questManager.getQuests().clear(); + questManager.getCategories().clear(); + taskTypeManager.resetTaskTypes(); + + // test file integrity + try { + YamlConfiguration config = new YamlConfiguration(); + config.load(new File(String.valueOf(Quests.this.getDataFolder() + File.separator + "config.yml"))); + } catch (Exception ex) { + Quests.this.getLogger().log(Level.SEVERE, "You have a YAML error in your Quests config. If this is your first time using Quests, please remove the Quests folder and RESTART (not reload!) the server and try again."); + brokenConfig = true; + } + + for (String id : getConfig().getConfigurationSection("categories").getKeys(false)) { + ItemStack displayItem = getItemStack("categories." + id + ".display"); + Category category = new Category(id, displayItem); + questManager.registerCategory(category); + } + + for (String id : getConfig().getConfigurationSection("quests").getKeys(false)) { + String root = "quests." + id; + + QItemStack displayItem = getQItemStack(root + ".display"); + List<String> rewards = getConfig().getStringList(root + ".rewards"); + List<String> requirements = getConfig().getStringList(root + ".options.requires"); + List<String> rewardString = getConfig().getStringList(root + ".rewardstring"); + boolean repeatable = getConfig().getBoolean(root + ".options.repeatable", false); + boolean cooldown = getConfig().getBoolean(root + ".options.cooldown.enabled", false); + int cooldownTime = getConfig().getInt(root + ".options.cooldown.time", 10); + String category = getConfig().getString(root + ".options.category"); + + if (rewardString == null) { + rewardString = new ArrayList<>(); + } + if (requirements == null) { + requirements = new ArrayList<>(); + } + if (rewards == null) { + rewards = new ArrayList<>(); + } + if (category == null) { + category = ""; + } + + + Quest quest; + if (category.equals("")) { + quest = new Quest(id, displayItem, rewards, requirements, repeatable, cooldown, cooldownTime, rewardString); + } else { + quest = new Quest(id, displayItem, rewards, requirements, repeatable, cooldown, cooldownTime, rewardString, category); + Category c = questManager.getCategoryById(category); + if (c != null) { + c.registerQuestId(id); + } + } + + for (String taskId : getConfig().getConfigurationSection(root + ".tasks").getKeys(false)) { + String taskRoot = root + ".tasks." + taskId; + String taskType = getConfig().getString(taskRoot + ".type"); + + Task task = new Task(taskId, taskType); + + for (String key : getConfig().getConfigurationSection(taskRoot).getKeys(false)) { + task.addConfigValue(key, getConfig().get(taskRoot + "." + key)); + } + + quest.registerTask(task); + } + + this.getLogger().log(Level.INFO, "Registering quest " + quest.getId() + " with " + quest.getTasks().size() + " tasks."); + questManager.registerQuest(quest); + taskTypeManager.registerQuestTasksWithTaskTypes(quest); + } + } + + private QItemStack getQItemStack(String path) { + String cName = this.getConfig().getString(path + ".name", path + ".name"); + String cType = this.getConfig().getString(path + ".type", path + ".type"); + List<String> cLoreNormal = this.getConfig().getStringList(path + ".lore-normal"); + List<String> cLoreStarted = this.getConfig().getStringList(path + ".lore-started"); + + String name; + Material type = null; + int data = 0; + List<String> loreNormal = new ArrayList<>(); + if (cLoreNormal != null) { + for (String s : cLoreNormal) { + loreNormal.add(ChatColor.translateAlternateColorCodes('&', s)); + } + } + List<String> loreStarted = new ArrayList<>(); + if (cLoreStarted != null) { + for (String s : cLoreStarted) { + loreStarted.add(ChatColor.translateAlternateColorCodes('&', s)); + } + } + name = ChatColor.translateAlternateColorCodes('&', cName); + + if (StringUtils.isNumeric(cType)) { + type = Material.getMaterial(Integer.parseInt(cType)); + } else if (Material.getMaterial(cType) != null) { + type = Material.getMaterial(cType); + } else if (cType.contains(":")) { + String[] parts = cType.split(":"); + if (parts.length > 1) { + if (StringUtils.isNumeric(parts[0])) { + type = Material.getMaterial(Integer.parseInt(parts[0])); + } else if (Material.getMaterial(parts[0]) != null) { + type = Material.getMaterial(parts[0]); + } + if (StringUtils.isNumeric(parts[1])) { + data = Integer.parseInt(parts[1]); + } + } + } + + if (type == null) { + type = Material.STONE; + } + + QItemStack is = new QItemStack(name, loreNormal, loreStarted, type, data); + + return is; + } + + public ItemStack getItemStack(String path) { + String cName = this.getConfig().getString(path + ".name", path + ".name"); + String cType = this.getConfig().getString(path + ".type", path + ".type"); + List<String> cLore = this.getConfig().getStringList(path + ".lore"); + + String name; + Material type = null; + int data = 0; + List<String> lore = new ArrayList<>(); + if (cLore != null) { + for (String s : cLore) { + lore.add(ChatColor.translateAlternateColorCodes('&', s)); + } + } + name = ChatColor.translateAlternateColorCodes('&', cName); + + if (StringUtils.isNumeric(cType)) { + type = Material.getMaterial(Integer.parseInt(cType)); + } else if (Material.getMaterial(cType) != null) { + type = Material.getMaterial(cType); + } else if (cType.contains(":")) { + String[] parts = cType.split(":"); + if (parts.length > 1) { + if (StringUtils.isNumeric(parts[0])) { + type = Material.getMaterial(Integer.parseInt(parts[0])); + } else if (Material.getMaterial(parts[0]) != null) { + type = Material.getMaterial(parts[0]); + } + if (StringUtils.isNumeric(parts[1])) { + data = Integer.parseInt(parts[1]); + } + } + } + + if (type == null) { + type = Material.STONE; + } + + ItemStack is = new ItemStack(type, 1, (short) data); + ItemMeta ism = is.getItemMeta(); + ism.setLore(lore); + ism.setDisplayName(name); + is.setItemMeta(ism); + + return is; + } + + private boolean setupTitle() { + String version; + try { + version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3]; + } catch (ArrayIndexOutOfBoundsException e) { + return false; + } + boolean success = false; + getLogger().info("Your server is running version " + version + "."); + if (version.equals("v1_8_R3")) { + title = new Title_BukkitNoTimings(); + success = true; + } else if (version.equals("v1_8_R2")) { + title = new Title_BukkitNoTimings(); + success = true; + } else if (version.equals("v1_8_R1")) { + title = new Title_BukkitNoTimings(); + success = true; + } else if (version.equals("v1_9_R2")) { + title = new Title_BukkitNoTimings(); + success = true; + } else if (version.equals("v1_9_R1")) { + title = new Title_BukkitNoTimings(); + success = true; + } else if (version.equals("v1_10_R1")) { + title = new Title_BukkitNoTimings(); + success = true; + } else if (version.equals("v1_11_R1")) { + title = new Title_Bukkit(); + success = true; + } else if (version.equals("v1_12_R1")) { + title = new Title_Bukkit(); + success = true; + } else if (version.equals("v1_13_R1")) { + title = new Title_Bukkit(); + success = true; + } else { + title = new Title_Other(); + } + if (title instanceof Title_Bukkit) { + getLogger().info("Titles have been enabled."); + } else if (title instanceof Title_BukkitNoTimings) { + getLogger().info("Titles have been enabled, although they have limited timings."); + } else { + getLogger().info("Titles are not supported for this version."); + } + return success; + } + + private void dataGenerator() { + File directory = new File(String.valueOf(this.getDataFolder())); + if (!directory.exists() && !directory.isDirectory()) { + directory.mkdir(); + } + + File config = new File(this.getDataFolder() + File.separator + "config.yml"); + if (!config.exists()) { + try { + config.createNewFile(); + try (InputStream in = Quests.class.getClassLoader().getResourceAsStream("config.yml")) { + OutputStream out = new FileOutputStream(config); + ByteStreams.copy(in, out); + } catch (IOException e) { + e.printStackTrace(); + } + } catch (IOException e) { + e.printStackTrace(); + return; + } + } + } +} diff --git a/src/main/java/com/leonardobishop/quests/blocktype/Block.java b/src/main/java/com/leonardobishop/quests/blocktype/Block.java new file mode 100644 index 00000000..4fa71515 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/blocktype/Block.java @@ -0,0 +1,34 @@ +package com.leonardobishop.quests.blocktype; + +import org.bukkit.Material; + +public class Block { + + private Material material; + private short data; + + public Block(Material material, short data) { + this.material = material; + this.data = data; + } + + public Block(Material material) { + this.material = material; + } + + public Material getMaterial() { + return material; + } + + public short getData() { + return data; + } + + public void setMaterial(Material material) { + this.material = material; + } + + public void setData(short data) { + this.data = data; + } +} diff --git a/src/main/java/com/leonardobishop/quests/blocktype/SimilarBlocks.java b/src/main/java/com/leonardobishop/quests/blocktype/SimilarBlocks.java new file mode 100644 index 00000000..caa71333 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/blocktype/SimilarBlocks.java @@ -0,0 +1,93 @@ +package com.leonardobishop.quests.blocktype; + +import org.bukkit.Material; + +import java.util.HashMap; +import java.util.Map; + +public class SimilarBlocks { + + private static HashMap<Block, Block> similarBlocks = new HashMap<>(); + + public static void addBlocks() { + // Redstone Ore + similarBlocks.put(new Block(Material.REDSTONE_ORE), new Block(Material.GLOWING_REDSTONE_ORE)); + similarBlocks.put(new Block(Material.GLOWING_REDSTONE_ORE), new Block(Material.REDSTONE_ORE)); + + // Oak Door + similarBlocks.put(new Block(Material.WOODEN_DOOR, (short) 0), new Block(Material.WOODEN_DOOR)); + similarBlocks.put(new Block(Material.WOODEN_DOOR, (short) 1), new Block(Material.WOODEN_DOOR)); + similarBlocks.put(new Block(Material.WOODEN_DOOR, (short) 2), new Block(Material.WOODEN_DOOR)); + similarBlocks.put(new Block(Material.WOODEN_DOOR, (short) 3), new Block(Material.WOODEN_DOOR)); + + // Dark Oak Door + similarBlocks.put(new Block(Material.DARK_OAK_DOOR, (short) 0), new Block(Material.DARK_OAK_DOOR)); + similarBlocks.put(new Block(Material.DARK_OAK_DOOR, (short) 1), new Block(Material.DARK_OAK_DOOR)); + similarBlocks.put(new Block(Material.DARK_OAK_DOOR, (short) 2), new Block(Material.DARK_OAK_DOOR)); + similarBlocks.put(new Block(Material.DARK_OAK_DOOR, (short) 3), new Block(Material.DARK_OAK_DOOR)); + + // Acacia Door + similarBlocks.put(new Block(Material.ACACIA_DOOR, (short) 0), new Block(Material.ACACIA_DOOR)); + similarBlocks.put(new Block(Material.ACACIA_DOOR, (short) 1), new Block(Material.ACACIA_DOOR)); + similarBlocks.put(new Block(Material.ACACIA_DOOR, (short) 2), new Block(Material.ACACIA_DOOR)); + similarBlocks.put(new Block(Material.ACACIA_DOOR, (short) 3), new Block(Material.ACACIA_DOOR)); + + // Birch Door + similarBlocks.put(new Block(Material.BIRCH_DOOR, (short) 0), new Block(Material.BIRCH_DOOR)); + similarBlocks.put(new Block(Material.BIRCH_DOOR, (short) 1), new Block(Material.BIRCH_DOOR)); + similarBlocks.put(new Block(Material.BIRCH_DOOR, (short) 2), new Block(Material.BIRCH_DOOR)); + similarBlocks.put(new Block(Material.BIRCH_DOOR, (short) 3), new Block(Material.BIRCH_DOOR)); + + // Jungle Door + similarBlocks.put(new Block(Material.JUNGLE_DOOR, (short) 0), new Block(Material.JUNGLE_DOOR)); + similarBlocks.put(new Block(Material.JUNGLE_DOOR, (short) 1), new Block(Material.JUNGLE_DOOR)); + similarBlocks.put(new Block(Material.JUNGLE_DOOR, (short) 2), new Block(Material.JUNGLE_DOOR)); + similarBlocks.put(new Block(Material.JUNGLE_DOOR, (short) 3), new Block(Material.JUNGLE_DOOR)); + + // Spruce Door + similarBlocks.put(new Block(Material.SPRUCE_DOOR, (short) 0), new Block(Material.SPRUCE_DOOR)); + similarBlocks.put(new Block(Material.SPRUCE_DOOR, (short) 1), new Block(Material.SPRUCE_DOOR)); + similarBlocks.put(new Block(Material.SPRUCE_DOOR, (short) 2), new Block(Material.SPRUCE_DOOR)); + similarBlocks.put(new Block(Material.SPRUCE_DOOR, (short) 3), new Block(Material.SPRUCE_DOOR)); + + // Iron Door + similarBlocks.put(new Block(Material.IRON_DOOR, (short) 0), new Block(Material.IRON_DOOR)); + similarBlocks.put(new Block(Material.IRON_DOOR, (short) 1), new Block(Material.IRON_DOOR)); + similarBlocks.put(new Block(Material.IRON_DOOR, (short) 2), new Block(Material.IRON_DOOR)); + similarBlocks.put(new Block(Material.IRON_DOOR, (short) 3), new Block(Material.IRON_DOOR)); + + // Oak Log + similarBlocks.put(new Block(Material.LOG, (short) 4), new Block(Material.LOG, (short) 0)); + similarBlocks.put(new Block(Material.LOG, (short) 8), new Block(Material.LOG, (short) 0)); + + // Spruce Log + similarBlocks.put(new Block(Material.LOG, (short) 5), new Block(Material.LOG, (short) 1)); + similarBlocks.put(new Block(Material.LOG, (short) 9), new Block(Material.LOG, (short) 1)); + + // Birch Log + similarBlocks.put(new Block(Material.LOG, (short) 6), new Block(Material.LOG, (short) 2)); + similarBlocks.put(new Block(Material.LOG, (short) 10), new Block(Material.LOG, (short) 2)); + + // Jungle Log + similarBlocks.put(new Block(Material.LOG, (short) 7), new Block(Material.LOG, (short) 3)); + similarBlocks.put(new Block(Material.LOG, (short) 11), new Block(Material.LOG, (short) 3)); + + // Acacia Log + similarBlocks.put(new Block(Material.LOG_2, (short) 4), new Block(Material.LOG, (short) 0)); + similarBlocks.put(new Block(Material.LOG_2, (short) 8), new Block(Material.LOG, (short) 0)); + + // Dark Oak Log + similarBlocks.put(new Block(Material.LOG_2, (short) 5), new Block(Material.LOG, (short) 1)); + similarBlocks.put(new Block(Material.LOG_2, (short) 9), new Block(Material.LOG, (short) 1)); + } + + public static Block getSimilarBlock(Block block) { + for (Map.Entry<Block, Block> entry : similarBlocks.entrySet()) { + if (entry.getKey().getMaterial() == block.getMaterial() && entry.getKey().getData() == block.getData()) { + return entry.getValue(); + } + } + return null; + } + +} diff --git a/src/main/java/com/leonardobishop/quests/bstats/Metrics.java b/src/main/java/com/leonardobishop/quests/bstats/Metrics.java new file mode 100644 index 00000000..a84fea79 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/bstats/Metrics.java @@ -0,0 +1,661 @@ +package com.leonardobishop.quests.bstats; + +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.RegisteredServiceProvider; +import org.bukkit.plugin.ServicePriority; +import org.bukkit.plugin.java.JavaPlugin; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import javax.net.ssl.HttpsURLConnection; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.util.*; +import java.util.concurrent.Callable; +import java.util.logging.Level; +import java.util.zip.GZIPOutputStream; + +/** + * bStats collects some data for plugin authors. + * + * Check out https://bStats.org/ to learn more about bStats! + */ +public class Metrics { + + static { + // You can use the property to disable the check in your test environment + if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) { + // Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D + final String defaultPackage = new String( + new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'}); + final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'}); + // We want to make sure nobody just copy & pastes the example and use the wrong package names + if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) { + throw new IllegalStateException("bStats Metrics class has not been relocated correctly!"); + } + } + } + + // The version of this bStats class + public static final int B_STATS_VERSION = 1; + + // The url to which the data is sent + private static final String URL = "https://bStats.org/submitData/bukkit"; + + // Should failed requests be logged? + private static boolean logFailedRequests; + + // The uuid of the server + private static String serverUUID; + + // The plugin + private final JavaPlugin plugin; + + // A list with all custom charts + private final List<CustomChart> charts = new ArrayList<>(); + + /** + * Class constructor. + * + * @param plugin The plugin which stats should be submitted. + */ + public Metrics(JavaPlugin plugin) { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null!"); + } + this.plugin = plugin; + + // Get the config file + File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats"); + File configFile = new File(bStatsFolder, "config.yml"); + YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile); + + // Check if the config file exists + if (!config.isSet("serverUuid")) { + + // Add default values + config.addDefault("enabled", true); + // Every server gets it's unique random id. + config.addDefault("serverUuid", UUID.randomUUID().toString()); + // Should failed request be logged? + config.addDefault("logFailedRequests", false); + + // Inform the server owners about bStats + config.options().header( + "bStats collects some data for plugin authors like how many servers are using their plugins.\n" + + "To honor their work, you should not disable it.\n" + + "This has nearly no effect on the server performance!\n" + + "Check out https://bStats.org/ to learn more :)" + ).copyDefaults(true); + try { + config.save(configFile); + } catch (IOException ignored) { } + } + + // Load the data + serverUUID = config.getString("serverUuid"); + logFailedRequests = config.getBoolean("logFailedRequests", false); + if (config.getBoolean("enabled", true)) { + boolean found = false; + // Search for all other bStats Metrics classes to see if we are the first one + for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) { + try { + service.getField("B_STATS_VERSION"); // Our identifier :) + found = true; // We aren't the first + break; + } catch (NoSuchFieldException ignored) { } + } + // Register our service + Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal); + if (!found) { + // We are the first! + startSubmitting(); + } + } + } + + /** + * Adds a custom chart. + * + * @param chart The chart to add. + */ + public void addCustomChart(CustomChart chart) { + if (chart == null) { + throw new IllegalArgumentException("Chart cannot be null!"); + } + charts.add(chart); + } + + /** + * Starts the Scheduler which submits our data every 30 minutes. + */ + private void startSubmitting() { + final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags + timer.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + if (!plugin.isEnabled()) { // Plugin was disabled + timer.cancel(); + return; + } + // Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler + // Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;) + Bukkit.getScheduler().runTask(plugin, new Runnable() { + @Override + public void run() { + submitData(); + } + }); + } + }, 1000*60*5, 1000*60*30); + // Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start + // WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted! + // WARNING: Just don't do it! + } + + /** + * Gets the plugin specific data. + * This method is called using Reflection. + * + * @return The plugin specific data. + */ + public JSONObject getPluginData() { + JSONObject data = new JSONObject(); + + String pluginName = plugin.getDescription().getName(); + String pluginVersion = plugin.getDescription().getVersion(); + + data.put("pluginName", pluginName); // Append the name of the plugin + data.put("pluginVersion", pluginVersion); // Append the version of the plugin + JSONArray customCharts = new JSONArray(); + for (CustomChart customChart : charts) { + // Add the data of the custom charts + JSONObject chart = customChart.getRequestJsonObject(); + if (chart == null) { // If the chart is null, we skip it + continue; + } + customCharts.add(chart); + } + data.put("customCharts", customCharts); + + return data; + } + + /** + * Gets the server specific data. + * + * @return The server specific data. + */ + private JSONObject getServerData() { + // Minecraft specific data + int playerAmount; + try { + // Around MC 1.8 the return type was changed to a collection from an array, + // This fixes java.lang.NoSuchMethodError: org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection; + Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers"); + playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class) + ? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size() + : ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length; + } catch (Exception e) { + playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed + } + int onlineMode = Bukkit.getOnlineMode() ? 1 : 0; + String bukkitVersion = org.bukkit.Bukkit.getVersion(); + bukkitVersion = bukkitVersion.substring(bukkitVersion.indexOf("MC: ") + 4, bukkitVersion.length() - 1); + + // OS/Java specific data + String javaVersion = System.getProperty("java.version"); + String osName = System.getProperty("os.name"); + String osArch = System.getProperty("os.arch"); + String osVersion = System.getProperty("os.version"); + int coreCount = Runtime.getRuntime().availableProcessors(); + + JSONObject data = new JSONObject(); + + data.put("serverUUID", serverUUID); + + data.put("playerAmount", playerAmount); + data.put("onlineMode", onlineMode); + data.put("bukkitVersion", bukkitVersion); + + data.put("javaVersion", javaVersion); + data.put("osName", osName); + data.put("osArch", osArch); + data.put("osVersion", osVersion); + data.put("coreCount", coreCount); + + return data; + } + + /** + * Collects the data and sends it afterwards. + */ + private void submitData() { + final JSONObject data = getServerData(); + + JSONArray pluginData = new JSONArray(); + // Search for all other bStats Metrics classes to get their plugin data + for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) { + try { + service.getField("B_STATS_VERSION"); // Our identifier :) + + for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) { + try { + pluginData.add(provider.getService().getMethod("getPluginData").invoke(provider.getProvider())); + } catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { } + } + } catch (NoSuchFieldException ignored) { } + } + + data.put("plugins", pluginData); + + // Create a new thread for the connection to the bStats server + new Thread(new Runnable() { + @Override + public void run() { + try { + // Send the data + sendData(data); + } catch (Exception e) { + // Something went wrong! :( + if (logFailedRequests) { + plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e); + } + } + } + }).start(); + } + + /** + * Sends the data to the bStats server. + * + * @param data The data to send. + * @throws Exception If the request failed. + */ + private static void sendData(JSONObject data) throws Exception { + if (data == null) { + throw new IllegalArgumentException("Data cannot be null!"); + } + if (Bukkit.isPrimaryThread()) { + throw new IllegalAccessException("This method must not be called from the main thread!"); + } + HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection(); + + // Compress the data to save bandwidth + byte[] compressedData = compress(data.toString()); + + // Add headers + connection.setRequestMethod("POST"); + connection.addRequestProperty("Accept", "application/json"); + connection.addRequestProperty("Connection", "close"); + connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request + connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length)); + connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format + connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION); + + // Send data + connection.setDoOutput(true); + DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream()); + outputStream.write(compressedData); + outputStream.flush(); + outputStream.close(); + + connection.getInputStream().close(); // We don't care about the response - Just send our data :) + } + + /** + * Gzips the given String. + * + * @param str The string to gzip. + * @return The gzipped String. + * @throws IOException If the compression failed. + */ + private static byte[] compress(final String str) throws IOException { + if (str == null) { + return null; + } + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + GZIPOutputStream gzip = new GZIPOutputStream(outputStream); + gzip.write(str.getBytes("UTF-8")); + gzip.close(); + return outputStream.toByteArray(); + } + + /** + * Represents a custom chart. + */ + public static abstract class CustomChart { + + // The id of the chart + final String chartId; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + */ + CustomChart(String chartId) { + if (chartId == null || chartId.isEmpty()) { + throw new IllegalArgumentException("ChartId cannot be null or empty!"); + } + this.chartId = chartId; + } + + private JSONObject getRequestJsonObject() { + JSONObject chart = new JSONObject(); + chart.put("chartId", chartId); + try { + JSONObject data = getChartData(); + if (data == null) { + // If the data is null we don't send the chart. + return null; + } + chart.put("data", data); + } catch (Throwable t) { + if (logFailedRequests) { + Bukkit.getLogger().log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t); + } + return null; + } + return chart; + } + + protected abstract JSONObject getChartData() throws Exception; + + } + + /** + * Represents a custom simple pie. + */ + public static class SimplePie extends CustomChart { + + private final Callable<String> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public SimplePie(String chartId, Callable<String> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JSONObject getChartData() throws Exception { + JSONObject data = new JSONObject(); + String value = callable.call(); + if (value == null || value.isEmpty()) { + // Null = skip the chart + return null; + } + data.put("value", value); + return data; + } + } + + /** + * Represents a custom advanced pie. + */ + public static class AdvancedPie extends CustomChart { + + private final Callable<Map<String, Integer>> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JSONObject getChartData() throws Exception { + JSONObject data = new JSONObject(); + JSONObject values = new JSONObject(); + Map<String, Integer> map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean allSkipped = true; + for (Map.Entry<String, Integer> entry : map.entrySet()) { + if (entry.getValue() == 0) { + continue; // Skip this invalid + } + allSkipped = false; + values.put(entry.getKey(), entry.getValue()); + } + if (allSkipped) { + // Null = skip the chart + return null; + } + data.put("values", values); + return data; + } + } + + /** + * Represents a custom drilldown pie. + */ + public static class DrilldownPie extends CustomChart { + + private final Callable<Map<String, Map<String, Integer>>> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) { + super(chartId); + this.callable = callable; + } + + @Override + public JSONObject getChartData() throws Exception { + JSONObject data = new JSONObject(); + JSONObject values = new JSONObject(); + Map<String, Map<String, Integer>> map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean reallyAllSkipped = true; + for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) { + JSONObject value = new JSONObject(); + boolean allSkipped = true; + for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) { + value.put(valueEntry.getKey(), valueEntry.getValue()); + allSkipped = false; + } + if (!allSkipped) { + reallyAllSkipped = false; + values.put(entryValues.getKey(), value); + } + } + if (reallyAllSkipped) { + // Null = skip the chart + return null; + } + data.put("values", values); + return data; + } + } + + /** + * Represents a custom single line chart. + */ + public static class SingleLineChart extends CustomChart { + + private final Callable<Integer> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public SingleLineChart(String chartId, Callable<Integer> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JSONObject getChartData() throws Exception { + JSONObject data = new JSONObject(); + int value = callable.call(); + if (value == 0) { + // Null = skip the chart + return null; + } + data.put("value", value); + return data; + } + + } + + /** + * Represents a custom multi line chart. + */ + public static class MultiLineChart extends CustomChart { + + private final Callable<Map<String, Integer>> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JSONObject getChartData() throws Exception { + JSONObject data = new JSONObject(); + JSONObject values = new JSONObject(); + Map<String, Integer> map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean allSkipped = true; + for (Map.Entry<String, Integer> entry : map.entrySet()) { + if (entry.getValue() == 0) { + continue; // Skip this invalid + } + allSkipped = false; + values.put(entry.getKey(), entry.getValue()); + } + if (allSkipped) { + // Null = skip the chart + return null; + } + data.put("values", values); + return data; + } + + } + + /** + * Represents a custom simple bar chart. + */ + public static class SimpleBarChart extends CustomChart { + + private final Callable<Map<String, Integer>> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JSONObject getChartData() throws Exception { + JSONObject data = new JSONObject(); + JSONObject values = new JSONObject(); + Map<String, Integer> map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + for (Map.Entry<String, Integer> entry : map.entrySet()) { + JSONArray categoryValues = new JSONArray(); + categoryValues.add(entry.getValue()); + values.put(entry.getKey(), categoryValues); + } + data.put("values", values); + return data; + } + + } + + /** + * Represents a custom advanced bar chart. + */ + public static class AdvancedBarChart extends CustomChart { + + private final Callable<Map<String, int[]>> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JSONObject getChartData() throws Exception { + JSONObject data = new JSONObject(); + JSONObject values = new JSONObject(); + Map<String, int[]> map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean allSkipped = true; + for (Map.Entry<String, int[]> entry : map.entrySet()) { + if (entry.getValue().length == 0) { + continue; // Skip this invalid + } + allSkipped = false; + JSONArray categoryValues = new JSONArray(); + for (int categoryValue : entry.getValue()) { + categoryValues.add(categoryValue); + } + values.put(entry.getKey(), categoryValues); + } + if (allSkipped) { + // Null = skip the chart + return null; + } + data.put("values", values); + return data; + } + + } +}
\ No newline at end of file diff --git a/src/main/java/com/leonardobishop/quests/commands/CommandQuests.java b/src/main/java/com/leonardobishop/quests/commands/CommandQuests.java new file mode 100644 index 00000000..71d53be6 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/commands/CommandQuests.java @@ -0,0 +1,345 @@ +package com.leonardobishop.quests.commands; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.obj.Messages; +import com.leonardobishop.quests.obj.Options; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.quests.Category; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.UUID; + +public class CommandQuests implements CommandExecutor { + + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (Quests.getInstance().isBrokenConfig()) { + sender.sendMessage(ChatColor.RED + "You have a YAML error in your config and Quests cannot load. If this is your first time using Quests, please " + + "delete the Quests folder and RESTART (not reload!) the server. If you have modified the config, check for errors in a YAML parser."); + return true; + } + + if (args.length >= 1 && args[0].equalsIgnoreCase("help")) { + showHelp(sender); + return true; + } + + if (args.length == 0 && sender instanceof Player) { + Player player = (Player) sender; + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(player.getUniqueId()); + qPlayer.openQuests(); + return true; + } else if (args.length >= 1) { + if ((args[0].equalsIgnoreCase("a") || args[0].equalsIgnoreCase("admin")) && sender.hasPermission("quests.admin")) { + if (args.length == 2) { + if (args[1].equalsIgnoreCase("opengui")) { + showAdminHelp(sender, "opengui"); + return true; + } else if (args[1].equalsIgnoreCase("moddata")) { + showAdminHelp(sender, "moddata"); + return true; + } else if (args[1].equalsIgnoreCase("reload")) { + Quests.getInstance().reloadConfig(); + Quests.getInstance().reloadQuests(); + sender.sendMessage(ChatColor.GRAY + "Quests was reloaded."); + return true; + } else if (args[1].equalsIgnoreCase("types")) { + sender.sendMessage(ChatColor.GRAY + "Registered task types:"); + for (TaskType taskType : Quests.getTaskTypeManager().getTaskTypes()) { + sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + taskType.getType()); + } + sender.sendMessage(ChatColor.DARK_GRAY + "View info using /q a types [type]."); + return true; + } else if (args[1].equalsIgnoreCase("update")) { + sender.sendMessage(ChatColor.GRAY + "Checking for updates..."); + new BukkitRunnable() { + @Override + public void run() { + Quests.getUpdater().check(); + if (Quests.getUpdater().isUpdateReady()) { + sender.sendMessage(Quests.getUpdater().getMessage()); + } else { + sender.sendMessage(ChatColor.GRAY + "No updates were found."); + } + } + }.runTaskAsynchronously(Quests.getInstance()); + return true; + } + } else if (args.length == 3) { + if (args[1].equalsIgnoreCase("opengui")) { + showAdminHelp(sender, "opengui"); + return true; + } else if (args[1].equalsIgnoreCase("moddata")) { + showAdminHelp(sender, "moddata"); + return true; + } else if (args[1].equalsIgnoreCase("types")) { + TaskType taskType = null; + for (TaskType task : Quests.getTaskTypeManager().getTaskTypes()) { + if (task.getType().equals(args[2])) { + taskType = task; + } + } + if (taskType == null) { + sender.sendMessage(Messages.COMMAND_TASKVIEW_ADMIN_FAIL.getMessage().replace("{task}", args[2])); + } else { + sender.sendMessage(ChatColor.RED + "Task type: " + ChatColor.GRAY + taskType.getType()); + sender.sendMessage(ChatColor.RED + "Author: " + ChatColor.GRAY + taskType.getAuthor()); + sender.sendMessage(ChatColor.RED + "Description: " + ChatColor.GRAY + taskType.getDescription()); + } + return true; + } + } else if (args.length == 4) { + if (args[1].equalsIgnoreCase("opengui")) { + if (args[2].equalsIgnoreCase("q") || args[2].equalsIgnoreCase("quests")) { + Player player = Bukkit.getPlayer(args[3]); + if (player != null) { + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(player.getUniqueId()); + if (qPlayer != null) { + qPlayer.openQuests(); + sender.sendMessage(Messages.COMMAND_QUEST_OPENQUESTS_ADMIN_SUCCESS.getMessage().replace("{player}", player.getName())); + return true; + } + } + sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_PLAYERNOTFOUND.getMessage().replace("{player}", args[3])); + return true; + } + showAdminHelp(sender, "opengui"); + return true; + } else if (args[1].equalsIgnoreCase("moddata")) { + Player player; + OfflinePlayer ofp; + UUID uuid; + String name; + if ((player = Bukkit.getPlayer(args[3])) != null) { + uuid = player.getUniqueId(); + name = player.getName(); + } else if ((ofp = Bukkit.getOfflinePlayer(args[3])) != null) { + uuid = ofp.getUniqueId(); + name = ofp.getName(); + } else { + sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_PLAYERNOTFOUND.getMessage().replace("{player}", args[3])); + return true; + } + if (args[2].equalsIgnoreCase("fullreset")) { + if (Quests.getPlayerManager().getPlayer(uuid) == null) { + sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_LOADDATA.getMessage().replace("{player}", name)); + Quests.getPlayerManager().loadPlayer(uuid, true); + } + if (Quests.getPlayerManager().getPlayer(uuid) == null) { + sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_NODATA.getMessage().replace("{player}", name)); + return true; + } + QuestProgressFile questProgressFile = Quests.getPlayerManager().getPlayer(uuid).getQuestProgressFile(); + questProgressFile.clear(); + questProgressFile.saveToDisk(); + sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_FULLRESET.getMessage().replace("{player}", name)); + return true; + } + if (Quests.getPlayerManager().getPlayer(uuid).isOnlyDataLoaded()) { + Quests.getPlayerManager().removePlayer(uuid); + } + showAdminHelp(sender, "moddata"); + return true; + } + } else if (args.length == 5) { + if (args[1].equalsIgnoreCase("opengui")) { + if (args[2].equalsIgnoreCase("c") || args[2].equalsIgnoreCase("category")) { + if (!Options.CATEGORIES_ENABLED.getBooleanValue()) { + sender.sendMessage(Messages.COMMAND_CATEGORY_OPEN_DISABLED.getMessage()); + return true; + } + Category category = Quests.getQuestManager().getCategoryById(args[4]); + if (category == null) { + sender.sendMessage(Messages.COMMAND_CATEGORY_OPEN_DOESNTEXIST.getMessage().replace("{category}", args[4])); + return true; + } + Player player = Bukkit.getPlayer(args[3]); + if (player != null) { + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(player.getUniqueId()); + if (qPlayer != null) { + qPlayer.openCategory(category); + sender.sendMessage(Messages.COMMAND_QUEST_OPENCATEGORY_ADMIN_SUCCESS.getMessage().replace("{player}", player.getName()) + .replace("{category}", category.getId())); + return true; + } + } + sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_PLAYERNOTFOUND.getMessage().replace("{player}", args[3])); + return true; + } + } else if (args[1].equalsIgnoreCase("moddata")) { + boolean success = false; + Player player; + OfflinePlayer ofp; + UUID uuid; + String name; + if ((player = Bukkit.getPlayer(args[3])) != null) { + uuid = player.getUniqueId(); + name = player.getName(); + } else if ((ofp = Bukkit.getOfflinePlayer(args[3])) != null) { + uuid = ofp.getUniqueId(); + name = ofp.getName(); + } else { + sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_PLAYERNOTFOUND.getMessage().replace("{player}", args[3])); + return true; + } + if (Quests.getPlayerManager().getPlayer(uuid) == null) { + sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_LOADDATA.getMessage().replace("{player}", name)); + Quests.getPlayerManager().loadPlayer(uuid, true); + } + if (Quests.getPlayerManager().getPlayer(uuid) == null) { + sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_NODATA.getMessage().replace("{player}", name)); + success = true; + } + QuestProgressFile questProgressFile = Quests.getPlayerManager().getPlayer(uuid).getQuestProgressFile(); + Quest quest = Quests.getQuestManager().getQuestById(args[4]); + if (quest == null) { + sender.sendMessage(Messages.COMMAND_QUEST_START_DOESNTEXIST.getMessage().replace("{quest}", args[4])); + success = true; + return true; + } + if (args[2].equalsIgnoreCase("reset")) { + questProgressFile.generateBlankQuestProgress(quest.getId()); + questProgressFile.saveToDisk(); + sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_RESET_SUCCESS.getMessage().replace("{player}", name).replace("{quest}", quest.getId())); + success = true; + } else if (args[2].equalsIgnoreCase("start")) { + int response = questProgressFile.startQuest(quest); + if (response == 1) { + sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_START_FAILLIMIT.getMessage().replace("{player}", name).replace("{quest}", quest.getId())); + return true; + } else if (response == 2) { + sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_START_FAILCOMPLETE.getMessage().replace("{player}", name).replace("{quest}", quest.getId())); + return true; + } else if (response == 3) { + sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_START_FAILCOOLDOWN.getMessage().replace("{player}", name).replace("{quest}", quest.getId())); + return true; + } else if (response == 4) { + sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_START_FAILLOCKED.getMessage().replace("{player}", name).replace("{quest}", quest.getId())); + return true; + } else if (response == 5) { + sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_START_FAILSTARTED.getMessage().replace("{player}", name).replace("{quest}", quest.getId())); + return true; + } + questProgressFile.saveToDisk(); + sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_START_SUCCESS.getMessage().replace("{player}", name).replace("{quest}", quest.getId())); + success = true; + } else if (args[2].equalsIgnoreCase("complete")) { + questProgressFile.completeQuest(quest); + questProgressFile.saveToDisk(); + sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_COMPLETE_SUCCESS.getMessage().replace("{player}", name).replace("{quest}", quest.getId())); + success = true; + } + if (Quests.getPlayerManager().getPlayer(uuid).isOnlyDataLoaded()) { + Quests.getPlayerManager().removePlayer(uuid); + } + if (!success) { + showAdminHelp(sender, "moddata"); + } + return true; + } + } + showAdminHelp(sender, null); + return true; + } + if (sender instanceof Player && (args[0].equalsIgnoreCase("q") || args[0].equalsIgnoreCase("quests"))) { + Player player = (Player) sender; + if (args.length >= 2) { + Quest quest = Quests.getQuestManager().getQuestById(args[1]); + if (quest == null) { + sender.sendMessage(Messages.COMMAND_QUEST_START_DOESNTEXIST.getMessage().replace("{quest}", args[1])); + } else { + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(player.getUniqueId()); + if (qPlayer == null) { + // shit + fan + sender.sendMessage(ChatColor.RED + "An error occurred finding your player."); + } else { + qPlayer.getQuestProgressFile().startQuest(quest); + } + } + return true; + } + } else if (sender instanceof Player && (args[0].equalsIgnoreCase("c") || args[0].equalsIgnoreCase("category"))) { + if (!Options.CATEGORIES_ENABLED.getBooleanValue()) { + sender.sendMessage(Messages.COMMAND_CATEGORY_OPEN_DISABLED.getMessage()); + return true; + } + Player player = (Player) sender; + if (args.length >= 2) { + Category category = Quests.getQuestManager().getCategoryById(args[1]); + if (category == null) { + sender.sendMessage(Messages.COMMAND_CATEGORY_OPEN_DOESNTEXIST.getMessage().replace("{category}", args[1])); + } else { + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(player.getUniqueId()); + qPlayer.openCategory(category); + return true; + } + return true; + } + } + showHelp(sender); + return true; + } else { + sender.sendMessage(ChatColor.RED + "Only admin commands are available to non-player senders."); + } + return true; + } + + private void showHelp(CommandSender sender) { + sender.sendMessage(ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH + "------------=[" + ChatColor.RED + " Quests v" + Quests.getInstance() + .getDescription().getVersion() + " " + ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH + "]=------------"); + sender.sendMessage(ChatColor.GRAY + "The following commands are available: "); + sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests " + ChatColor.DARK_GRAY + ": show quests"); + sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests c/category <categoryid> " + ChatColor.DARK_GRAY + ": open category by ID"); + sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests q/quest <questid> " + ChatColor.DARK_GRAY + ": start quest by ID"); + sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a/admin " + ChatColor.DARK_GRAY + ": view help for admins"); + sender.sendMessage(ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH + "-----=[" + ChatColor.RED + " made with <3 by fatpigsarefat " + ChatColor + .GRAY.toString() + ChatColor.STRIKETHROUGH + "]=-----"); + } + + private void showAdminHelp(CommandSender sender, String command) { + if (command != null && command.equalsIgnoreCase("opengui")) { + sender.sendMessage(ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH + "------------=[" + ChatColor.RED + " Quests Admin: opengui " + ChatColor + .GRAY.toString() + ChatColor.STRIKETHROUGH + "]=------------"); + sender.sendMessage(ChatColor.GRAY + "The following commands are available: "); + sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a opengui q/quest <player> " + ChatColor.DARK_GRAY + ": forcefully show" + + " quests for player"); + sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a opengui c/category <player> <category> " + ChatColor.DARK_GRAY + ": " + + "forcefully " + + "open category by ID for player"); + sender.sendMessage(ChatColor.GRAY + "These commands are useful for command NPCs. These will bypass the usual quests.command permission."); + } else if (command != null && command.equalsIgnoreCase("moddata")) { + sender.sendMessage(ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH + "------------=[" + ChatColor.RED + " Quests Admin: moddata " + ChatColor + .GRAY.toString() + ChatColor.STRIKETHROUGH + "]=------------"); + sender.sendMessage(ChatColor.GRAY + "The following commands are available: "); + sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a moddata fullreset <player> " + ChatColor.DARK_GRAY + ": clear a " + + "players quest data file"); + sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a moddata reset <player> <questid>" + ChatColor.DARK_GRAY + ": clear a " + + "players data for specifc quest"); + sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a moddata start <player> <questid>" + ChatColor.DARK_GRAY + ": start a " + + "quest for a player"); + sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a moddata complete <player> <questid>" + ChatColor.DARK_GRAY + ": " + + "complete a quest for a player"); + sender.sendMessage(ChatColor.GRAY + "These commands modify quest progress for players. Use them cautiously. Changes are irreversible."); + } else { + sender.sendMessage(ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH + "------------=[" + ChatColor.RED + " Quests Admin " + ChatColor.GRAY + .toString() + ChatColor.STRIKETHROUGH + "]=------------"); + sender.sendMessage(ChatColor.GRAY + "The following commands are available: "); + sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a opengui " + ChatColor.DARK_GRAY + ": view help for opengui"); + sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a moddata " + ChatColor.DARK_GRAY + ": view help for quest progression"); + sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a types [type]" + ChatColor.DARK_GRAY + ": view registered task types"); + sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a reload " + ChatColor.DARK_GRAY + ": reload Quests configuration"); + sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a update " + ChatColor.DARK_GRAY + ": check for updates"); + } + sender.sendMessage(ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH + "-----=[" + ChatColor.RED + " requires permission: quests.admin " + + ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH + "]=-----"); + } +} diff --git a/src/main/java/com/leonardobishop/quests/events/EventInventory.java b/src/main/java/com/leonardobishop/quests/events/EventInventory.java new file mode 100644 index 00000000..ffa299bd --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/events/EventInventory.java @@ -0,0 +1,103 @@ +package com.leonardobishop.quests.events; + +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.obj.Options; +import com.leonardobishop.quests.obj.misc.QMenu; +import com.leonardobishop.quests.obj.misc.QMenuCancel; +import com.leonardobishop.quests.obj.misc.QMenuCategory; +import com.leonardobishop.quests.obj.misc.QMenuQuest; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.UUID; + +public class EventInventory implements Listener { + + private static HashMap<UUID, QMenu> tracker = new HashMap<>(); + private ArrayList<UUID> buffer = new ArrayList<>(); + + public static void track(UUID uuid, QMenu qMenu) { + tracker.put(uuid, qMenu); + } + + @EventHandler + public void onEvent(InventoryClickEvent event) { + if (tracker.containsKey(event.getWhoClicked().getUniqueId())) { + event.setCancelled(true); + QMenu qMenu = tracker.get(event.getWhoClicked().getUniqueId()); + + if (qMenu instanceof QMenuQuest) { + QMenuQuest qMenuQuest = (QMenuQuest) qMenu; + + if (qMenuQuest.getPagePrevLocation() == event.getSlot()) { + buffer.add(event.getWhoClicked().getUniqueId()); + event.getWhoClicked().openInventory(qMenuQuest.toInventory(qMenuQuest.getCurrentPage() - 1)); + + } else if (qMenuQuest.getPageNextLocation() == event.getSlot()) { + buffer.add(event.getWhoClicked().getUniqueId()); + event.getWhoClicked().openInventory(qMenuQuest.toInventory(qMenuQuest.getCurrentPage() + 1)); + + } else if (Options.CATEGORIES_ENABLED.getBooleanValue() && qMenuQuest.getBackButtonLocation() == event.getSlot()) { + QMenuCategory qMenuCategory = qMenuQuest.getSuperMenu(); + buffer.add(event.getWhoClicked().getUniqueId()); + event.getWhoClicked().openInventory(qMenuCategory.toInventory(1)); + tracker.put(event.getWhoClicked().getUniqueId(), qMenuCategory); + + } else if (event.getSlot() < qMenuQuest.getPageSize() && qMenuQuest.getSlotsToMenu().containsKey(event.getSlot() + (((qMenuQuest + .getCurrentPage()) - 1) * qMenuQuest.getPageSize()))) { + String questid = qMenuQuest.getSlotsToMenu().get(event.getSlot() + (((qMenuQuest.getCurrentPage()) - 1) * qMenuQuest.getPageSize())); + Quest quest = Quests.getQuestManager().getQuestById(questid); + if (event.getClick() == ClickType.LEFT) { + if (qMenuQuest.getOwner().getQuestProgressFile().startQuest(quest) == 0) { + event.getWhoClicked().closeInventory(); + } + } else if (event.getClick() == ClickType.RIGHT && Options.ALLOW_QUEST_CANCEL.getBooleanValue()) { + QMenuCancel qMenuCancel = new QMenuCancel(qMenuQuest.getOwner(), qMenuQuest, quest); + buffer.add(event.getWhoClicked().getUniqueId()); + event.getWhoClicked().openInventory(qMenuCancel.toInventory()); + tracker.put(event.getWhoClicked().getUniqueId(), qMenuCancel); + } + } + } else if (qMenu instanceof QMenuCategory) { + QMenuCategory qMenuCategory = (QMenuCategory) qMenu; + + if (qMenuCategory.getSlotsToMenu().containsKey(event.getSlot())) { + QMenuQuest qMenuQuest = qMenuCategory.getSlotsToMenu().get(event.getSlot()); + buffer.add(event.getWhoClicked().getUniqueId()); + event.getWhoClicked().openInventory(qMenuQuest.toInventory(1)); + tracker.put(event.getWhoClicked().getUniqueId(), qMenuQuest); + } + } else if (qMenu instanceof QMenuCancel) { + QMenuCancel qMenuCancel = (QMenuCancel) qMenu; + + event.setCancelled(true); + if (event.getSlot() == 10 || event.getSlot() == 11 || event.getSlot() == 12) { + QMenuQuest qMenuQuest = qMenuCancel.getSuperMenu(); + buffer.add(event.getWhoClicked().getUniqueId()); + event.getWhoClicked().openInventory(qMenuQuest.toInventory(1)); + tracker.put(event.getWhoClicked().getUniqueId(), qMenuQuest); + } else if (event.getSlot() == 14 || event.getSlot() == 15 || event.getSlot() == 16) { + if (qMenuCancel.getOwner().getQuestProgressFile().cancelQuest(qMenuCancel.getQuest())) { + event.getWhoClicked().closeInventory(); + } + } + } + } + } + + @EventHandler + public void onEvent(InventoryCloseEvent event) { + if (buffer.contains(event.getPlayer().getUniqueId())) { + buffer.remove(event.getPlayer().getUniqueId()); + } else if (tracker.containsKey(event.getPlayer().getUniqueId())) { + tracker.remove(event.getPlayer().getUniqueId()); + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/events/EventPlayerJoin.java b/src/main/java/com/leonardobishop/quests/events/EventPlayerJoin.java new file mode 100644 index 00000000..3a083456 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/events/EventPlayerJoin.java @@ -0,0 +1,25 @@ +package com.leonardobishop.quests.events; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.obj.Messages; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; + +import java.util.UUID; + +public class EventPlayerJoin implements Listener { + + @EventHandler + public void onEvent(PlayerJoinEvent event) { + UUID playerUuid = event.getPlayer().getUniqueId(); + Quests.getPlayerManager().loadPlayer(playerUuid); + if (Quests.getInstance().getDescription().getVersion().contains("beta") && event.getPlayer().hasPermission("quests.admin")) { + event.getPlayer().sendMessage(Messages.BETA_REMINDER.getMessage()); + } + if (Quests.getUpdater().isUpdateReady() && event.getPlayer().hasPermission("quests.admin")) { + event.getPlayer().sendMessage(Quests.getUpdater().getMessage()); + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/events/EventPlayerLeave.java b/src/main/java/com/leonardobishop/quests/events/EventPlayerLeave.java new file mode 100644 index 00000000..c121ef64 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/events/EventPlayerLeave.java @@ -0,0 +1,25 @@ +package com.leonardobishop.quests.events; + +import com.leonardobishop.quests.Quests; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.UUID; + +public class EventPlayerLeave implements Listener { + + @EventHandler + public void onEvent(PlayerQuitEvent event) { + UUID playerUuid = event.getPlayer().getUniqueId(); + new BukkitRunnable() { + @Override + public void run() { + Quests.getPlayerManager().getPlayer(playerUuid).getQuestProgressFile().saveToDisk(); + Quests.getPlayerManager().removePlayer(playerUuid); + } + }.runTaskAsynchronously(Quests.getInstance()); + } + +} diff --git a/src/main/java/com/leonardobishop/quests/obj/Items.java b/src/main/java/com/leonardobishop/quests/obj/Items.java new file mode 100644 index 00000000..e63ffb8f --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/obj/Items.java @@ -0,0 +1,28 @@ +package com.leonardobishop.quests.obj; + +import com.leonardobishop.quests.Quests; +import org.bukkit.inventory.ItemStack; + +public enum Items { + + BACK_BUTTON("gui.back-button"), + QUEST_LOCKED("gui.quest-locked-display"), + QUEST_COOLDOWN("gui.quest-cooldown-display"), + QUEST_COMPLETED("gui.quest-completed-display"), + PAGE_PREV("gui.page-prev"), + PAGE_NEXT("gui.page-next"), + PAGE_DESCRIPTION("gui.page-desc"), + QUEST_CANCEL_YES("gui.quest-cancel-yes"), + QUEST_CANCEL_NO("gui.quest-cancel-no"); + + String path; + + Items(String path) { + this.path = path; + } + + public ItemStack getItem() { + return Quests.getInstance().getItemStack(path); + } + +} diff --git a/src/main/java/com/leonardobishop/quests/obj/Messages.java b/src/main/java/com/leonardobishop/quests/obj/Messages.java new file mode 100644 index 00000000..1838eb94 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/obj/Messages.java @@ -0,0 +1,60 @@ +package com.leonardobishop.quests.obj; + +import com.leonardobishop.quests.Quests; +import org.bukkit.ChatColor; + +public enum Messages { + + QUEST_START("messages.quest-start"), + QUEST_COMPLETE("messages.quest-complete"), + QUEST_CANCEL("messages.quest-cancel"), + QUEST_START_LIMIT("messages.quest-start-limit"), + QUEST_START_DISABLED("messages.quest-start-disabled"), + QUEST_START_LOCKED("messages.quest-start-locked"), + QUEST_START_COOLDOWN("messages.quest-start-cooldown"), + QUEST_START_STARTED("messages.quest-start-started"), + QUEST_CANCEL_NOTSTARTED("messages.quest-cancel-notstarted"), + QUEST_UPDATER("messages.quest-updater"), + COMMAND_QUEST_START_DOESNTEXIST("messages.command-quest-start-doesntexist"), + COMMAND_QUEST_OPENCATEGORY_ADMIN_SUCCESS("messages.command-quest-opencategory-admin-success"), + COMMAND_QUEST_OPENQUESTS_ADMIN_SUCCESS("messages.command-quest-openquests-admin-success"), + COMMAND_QUEST_ADMIN_PLAYERNOTFOUND("messages.command-quest-admin-playernotfound"), + COMMAND_CATEGORY_OPEN_DOESNTEXIST("messages.command-category-open-doesntexist"), + COMMAND_CATEGORY_OPEN_DISABLED("messages.command-category-open-disabled"), + COMMAND_QUEST_START_ADMIN_SUCCESS("messages.command-quest-start-admin-success"), + COMMAND_TASKVIEW_ADMIN_FAIL("messages.command-taskview-admin-fail"), + COMMAND_QUEST_START_ADMIN_FAIL("messages.command-quest-start-admin-fail"), + TITLE_QUEST_START_TITLE("titles.quest-start.title"), + TITLE_QUEST_START_SUBTITLE("titles.quest-start.subtitle"), + TITLE_QUEST_COMPLETE_TITLE("titles.quest-complete.title"), + TITLE_QUEST_COMPLETE_SUBTITLE("titles.quest-complete.subtitle"), + BETA_REMINDER("messages.beta-reminder"), + COMMAND_QUEST_ADMIN_LOADDATA("messages.command-quest-admin-loaddata"), + COMMAND_QUEST_ADMIN_NODATA("messages.command-quest-admin-nodata"), + COMMAND_QUEST_ADMIN_FULLRESET("messages.command-quest-admin-fullreset"), + COMMAND_QUEST_ADMIN_START_FAILLOCKED("messages.command-quest-admin-start-faillocked"), + COMMAND_QUEST_ADMIN_START_FAILCOOLDOWN("messages.command-quest-admin-start-failcooldown"), + COMMAND_QUEST_ADMIN_START_FAILCOMPLETE("messages.command-quest-admin-start-failcomplete"), + COMMAND_QUEST_ADMIN_START_FAILLIMIT("messages.command-quest-admin-start-faillimit"), + COMMAND_QUEST_ADMIN_START_FAILSTARTED("messages.command-quest-admin-start-failstarted"), + COMMAND_QUEST_ADMIN_START_SUCCESS("messages.command-quest-admin-start-success"), + COMMAND_QUEST_ADMIN_COMPLETE_SUCCESS("messages.command-quest-admin-complete-success"), + COMMAND_QUEST_ADMIN_RESET_SUCCESS("messages.command-quest-admin-reset-success"); + + private String path; + + Messages(String path) { + this.path = path; + } + + public String getMessage() { + if (Quests.getInstance().getConfig().contains(path)) { + String message = Quests.getInstance().getConfig().getString(path); + if (message != null) { + return ChatColor.translateAlternateColorCodes('&', message); + } + } + return path; + } + +} diff --git a/src/main/java/com/leonardobishop/quests/obj/Options.java b/src/main/java/com/leonardobishop/quests/obj/Options.java new file mode 100644 index 00000000..2c7fde6b --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/obj/Options.java @@ -0,0 +1,54 @@ +package com.leonardobishop.quests.obj; + +import com.leonardobishop.quests.Quests; +import org.bukkit.ChatColor; + +import java.util.ArrayList; +import java.util.List; + +public enum Options { + + CATEGORIES_ENABLED("options.categories-enabled"), + TRIM_GUI_SIZE("options.trim-gui-size"), + QUESTS_START_LIMIT("options.quest-started-limit"), + TITLES_ENABLED("options.titles-enabled"), + GUI_HIDE_LOCKED("options.gui-hide-locked"), + GUITITLE_QUESTS_CATEGORY("options.guinames.quests-category"), + GUITITLE_QUESTS("options.guinames.quests-menu"), + GUITITLE_DAILY_QUESTS("options.guinames.daily-quests"), + GUITITLE_QUEST_CANCEL("options.guinames.quest-cancel"), + ALLOW_QUEST_CANCEL("options.allow-quest-cancel"); + + private String path; + + Options(String path) { + this.path = path; + } + + public int getIntValue() { + return Quests.getInstance().getConfig().getInt(path); + } + + public String getStringValue() { + return Quests.getInstance().getConfig().getString(path); + } + + public boolean getBooleanValue() { + return Quests.getInstance().getConfig().getBoolean(path); + } + + public List<String> getStringListValue() { + return Quests.getInstance().getConfig().getStringList(path); + } + + public static String color(String s) { + return ChatColor.translateAlternateColorCodes('&', s); + } + public static List<String> color(List<String> s) { + List<String> colored = new ArrayList<>(); + for (String line : s) { + colored.add(ChatColor.translateAlternateColorCodes('&', line)); + } + return colored; + } +} diff --git a/src/main/java/com/leonardobishop/quests/obj/misc/QItemStack.java b/src/main/java/com/leonardobishop/quests/obj/misc/QItemStack.java new file mode 100644 index 00000000..8d5c82e9 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/obj/misc/QItemStack.java @@ -0,0 +1,114 @@ +package com.leonardobishop.quests.obj.misc; + +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class QItemStack { + + private String name; + private List<String> loreNormal; + private List<String> loreStarted; + private Material type; + private int data; + + public QItemStack(String name, List<String> loreNormal, List<String> loreStarted, Material type, int data) { + this.name = name; + this.loreNormal = loreNormal; + this.loreStarted = loreStarted; + this.type = type; + this.data = data; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List<String> getLoreNormal() { + return loreNormal; + } + + public void setLoreNormal(List<String> loreNormal) { + this.loreNormal = loreNormal; + } + + public List<String> getLoreStarted() { + return loreStarted; + } + + public void setLoreStarted(List<String> loreStarted) { + this.loreStarted = loreStarted; + } + + public Material getType() { + return type; + } + + public void setType(Material type) { + this.type = type; + } + + public int getData() { + return data; + } + + public void setData(int data) { + this.data = data; + } + + public ItemStack toItemStack(QuestProgress questProgress) { + ItemStack is = new ItemStack(type, 1, (short) data); + ItemMeta ism = is.getItemMeta(); + ism.setDisplayName(name); + List<String> formattedLore = new ArrayList<>(); + List<String> tempLore = new ArrayList<>(); + tempLore.addAll(loreNormal); + if (questProgress != null && questProgress.isStarted()) { + tempLore.addAll(loreStarted); + ism.addEnchant(Enchantment.ARROW_INFINITE, 1, true); + try { + ism.addItemFlags(ItemFlag.HIDE_ENCHANTS); + ism.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); + } catch (Exception ignored) { + + } + } + if (questProgress != null) { + for (String s : tempLore) { + Matcher m = Pattern.compile("\\{([^}]+)\\}").matcher(s); + while (m.find()) { + String[] parts = m.group(1).split(":"); + if (parts.length > 1) { + if (questProgress.getTaskProgress(parts[0]) == null) { + continue; + } + if (parts[1].equals("progress")) { + String str = String.valueOf(questProgress.getTaskProgress(parts[0]).getProgress()); + s = s.replace("{" + m.group(1) + "}", (str.equals("null") ? String.valueOf(0) : str)); + } + if (parts[1].equals("complete")) { + String str = String.valueOf(questProgress.getTaskProgress(parts[0]).isCompleted()); + s = s.replace("{" + m.group(1) + "}", str); + } + } + } + formattedLore.add(s); + } + } + ism.setLore(formattedLore); + is.setItemMeta(ism); + return is; + } +} diff --git a/src/main/java/com/leonardobishop/quests/obj/misc/QMenu.java b/src/main/java/com/leonardobishop/quests/obj/misc/QMenu.java new file mode 100644 index 00000000..9ce5452b --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/obj/misc/QMenu.java @@ -0,0 +1,12 @@ +package com.leonardobishop.quests.obj.misc; + +import com.leonardobishop.quests.player.QPlayer; + +import java.util.HashMap; + +public interface QMenu { + + QPlayer getOwner(); + HashMap<?, ?> getSlotsToMenu(); + +} diff --git a/src/main/java/com/leonardobishop/quests/obj/misc/QMenuCancel.java b/src/main/java/com/leonardobishop/quests/obj/misc/QMenuCancel.java new file mode 100644 index 00000000..b23911fc --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/obj/misc/QMenuCancel.java @@ -0,0 +1,99 @@ +package com.leonardobishop.quests.obj.misc; + +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.obj.Items; +import com.leonardobishop.quests.obj.Options; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class QMenuCancel implements QMenu { + + private HashMap<Integer, String> slotsToQuestIds = new HashMap<>(); + private QMenuQuest superMenu; + private QPlayer owner; + private Quest quest; + + public QMenuCancel(QPlayer owner, QMenuQuest superMenu, Quest quest) { + this.owner = owner; + this.superMenu = superMenu; + this.quest = quest; + } + + public void populate(List<Quest> quests) { + /* ignored */ + } + + @Override + public HashMap<Integer, String> getSlotsToMenu() { + return slotsToQuestIds; + } + + public Quest getQuest() { + return quest; + } + + @Override + public QPlayer getOwner() { + return owner; + } + + public Inventory toInventory() { + String title = Options.color(Options.GUITITLE_QUEST_CANCEL.getStringValue()); + + ItemStack yes = Items.QUEST_CANCEL_YES.getItem(); + ItemStack no = Items.QUEST_CANCEL_NO.getItem(); + + ItemStack is = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 7); + ItemMeta ism = is.getItemMeta(); + ism.setDisplayName(" "); + is.setItemMeta(ism); + + Inventory inventory = Bukkit.createInventory(null, 27, title); + + for (int i = 0; i < inventory.getSize(); i++) { + inventory.setItem(i, is); + } + + inventory.setItem(10, no); + inventory.setItem(11, no); + inventory.setItem(12, no); + inventory.setItem(13, quest.getDisplayItem().toItemStack(owner.getQuestProgressFile().getQuestProgress(quest))); + inventory.setItem(14, yes); + inventory.setItem(15, yes); + inventory.setItem(16, yes); + + return inventory; + } + + public QMenuQuest getSuperMenu() { + return superMenu; + } + + public ItemStack replaceItemStack(ItemStack is, Map<String, String> placeholders) { + ItemStack newItemStack = is.clone(); + List<String> lore = newItemStack.getItemMeta().getLore(); + List<String> newLore = new ArrayList<>(); + ItemMeta ism = newItemStack.getItemMeta(); + if (lore != null) { + for (String s : lore) { + for (Map.Entry<String, String> entry : placeholders.entrySet()) { + s = s.replace(entry.getKey(), entry.getValue()); + ism.setDisplayName(ism.getDisplayName().replace(entry.getKey(), entry.getValue())); + } + newLore.add(s); + } + } + ism.setLore(newLore); + newItemStack.setItemMeta(ism); + return newItemStack; + } +} diff --git a/src/main/java/com/leonardobishop/quests/obj/misc/QMenuCategory.java b/src/main/java/com/leonardobishop/quests/obj/misc/QMenuCategory.java new file mode 100644 index 00000000..dec9002b --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/obj/misc/QMenuCategory.java @@ -0,0 +1,92 @@ +package com.leonardobishop.quests.obj.misc; + +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.quests.Category; +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.obj.Options; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; +import java.util.List; + +public class QMenuCategory implements QMenu { + + private final int pageSize = 45; + private HashMap<Integer, QMenuQuest> slotsToMenuQuest = new HashMap<>(); + private QPlayer owner; + + public QMenuCategory(QPlayer owner) { + this.owner = owner; + } + + public void populate(List<QMenuQuest> menuQuests) { + int slot = 0; + for (QMenuQuest qMenuQuest : menuQuests) { + slotsToMenuQuest.put(slot, qMenuQuest); + slot++; + } + } + + @Override + public HashMap<Integer, QMenuQuest> getSlotsToMenu() { + return slotsToMenuQuest; + } + + @Override + public QPlayer getOwner() { + return owner; + } + + public Inventory toInventory(int page) { + int pageMin = pageSize * (page - 1); + int pageMax = pageSize * page; + String title = Options.color(Options.GUITITLE_QUESTS_CATEGORY.getStringValue()); + + ItemStack pageIs = new ItemStack(Material.DIRT); + + Inventory inventory = Bukkit.createInventory(null, 54, title); + + for (int pointer = pageMin; pointer < pageMax; pointer++) { + if (slotsToMenuQuest.containsKey(pointer)) { + Category category = Quests.getQuestManager().getCategoryById(slotsToMenuQuest.get(pointer).getCategoryName()); + if (category != null) { + inventory.setItem(pointer, category.getDisplayItem()); + } + } + } + + inventory.setItem(49, pageIs); + + if (Options.TRIM_GUI_SIZE.getBooleanValue() && page == 1) { + int slotsUsed = 0; + for (int pointer = 0; pointer < pageMax; pointer++) { + if (inventory.getItem(pointer) != null) { + slotsUsed++; + } + } + + int inventorySize = (slotsUsed >= 54) ? 54 : slotsUsed + (9 - slotsUsed % 9) * Math.min(1, slotsUsed % 9); + inventorySize = inventorySize <= 0 ? 9 : inventorySize; + if (inventorySize == 54) { + return inventory; + } + + Inventory trimmedInventory = Bukkit.createInventory(null, inventorySize, title); + + for (int slot = 0; slot < pageMax; slot++) { + if (slot >= trimmedInventory.getSize()){ + break; + } + trimmedInventory.setItem(slot, inventory.getItem(slot)); + } + return trimmedInventory; + } else { + return inventory; + } + + } + +} diff --git a/src/main/java/com/leonardobishop/quests/obj/misc/QMenuDaily.java b/src/main/java/com/leonardobishop/quests/obj/misc/QMenuDaily.java new file mode 100644 index 00000000..6c0f21e8 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/obj/misc/QMenuDaily.java @@ -0,0 +1,117 @@ +package com.leonardobishop.quests.obj.misc; + +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.obj.Options; +import org.bukkit.Bukkit; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class QMenuDaily implements QMenu { + + private HashMap<Integer, String> slotsToQuestIds = new HashMap<>(); + private int backButtonLocation = -1; + private boolean backButtonEnabled = true; + private QMenuCategory superMenu; + private String categoryName; + private final int pageSize = 45; + private QPlayer owner; + + public QMenuDaily(QPlayer owner, QMenuCategory superMenu) { + this.owner = owner; + this.superMenu = superMenu; + } + + public void populate(List<Quest> quests) { + int slot = 11; + for (Quest quest : quests) { + slotsToQuestIds.put(slot, quest.getId()); + slot++; + if (slot == 16) { + break; + } + } + } + + @Override + public HashMap<Integer, String> getSlotsToMenu() { + return slotsToQuestIds; + } + + @Override + public QPlayer getOwner() { + return owner; + } + + public String getCategoryName() { + return categoryName; + } + + public Inventory toInventory(int page) { + int pageMin = pageSize * (page - 1); + int pageMax = pageSize * page; + String title = Options.GUITITLE_DAILY_QUESTS.toString(); + + Inventory inventory = Bukkit.createInventory(null, 27, title); + + //TODO daily quests + +// int invSlot = 11; +// for (int pointer = pageMin; pointer < pageMax; pointer++) { +// if (slotsToQuestIds.containsKey(pointer)) { +// Quest quest = Quests.getQuestManager().getQuestById(slotsToQuestIds.get(pointer)); +// QuestProgress questProgress = owner.getQuestProgressFile().getQuestProgress(quest); +// long cooldown = owner.getQuestProgressFile().getCooldownFor(quest); +// if (!owner.getQuestProgressFile().hasMetRequirements(quest)) { +// List<String> quests = new ArrayList<>(); +// for (String requirement : quest.getRequirements()) { +// quests.add(Quests.getQuestManager().getQuestById(requirement).getDisplayNameStripped()); +// } +// Map<String, String> placeholders = new HashMap<>(); +// placeholders.put("{quest}", quest.getDisplayNameStripped()); +// placeholders.put("{requirements}", String.join(", ", quests)); +// ItemStack is = replaceItemStack(Items.QUEST_LOCKED.getItem(), placeholders); +// inventory.setItem(invSlot, is); +// } else if (!quest.isRepeatable() && questProgress.isCompletedBefore()) { +// Map<String, String> placeholders = new HashMap<>(); +// placeholders.put("{quest}", quest.getDisplayNameStripped()); +// ItemStack is = replaceItemStack(Items.QUEST_COMPLETED.getItem(), placeholders); +// inventory.setItem(invSlot, is); +// } else if (cooldown > 0) { +// Map<String, String> placeholders = new HashMap<>(); +// placeholders.put("{time}", Quests.convertToFormat(TimeUnit.MINUTES.convert(cooldown, TimeUnit.MILLISECONDS))); +// placeholders.put("{quest}", quest.getDisplayNameStripped()); +// ItemStack is = replaceItemStack(Items.QUEST_COOLDOWN.getItem(), placeholders); +// inventory.setItem(invSlot, is); +// } else { +// inventory.setItem(invSlot, Quests.getQuestManager().getQuestById(quest.getId()).getDisplayItem().toItemStack(questProgress)); +// } +// } +// invSlot++; +// } + + return inventory; + } + + public ItemStack replaceItemStack(ItemStack is, Map<String, String> placeholders) { + ItemStack newItemStack = is.clone(); + List<String> lore = newItemStack.getItemMeta().getLore(); + List<String> newLore = new ArrayList<>(); + for (String s : lore) { + for (Map.Entry<String, String> entry : placeholders.entrySet()) { + s = s.replace(entry.getKey(), entry.getValue()); + } + newLore.add(s); + } + ItemMeta ism = newItemStack.getItemMeta(); + ism.setLore(newLore); + newItemStack.setItemMeta(ism); + return newItemStack; + } +} diff --git a/src/main/java/com/leonardobishop/quests/obj/misc/QMenuQuest.java b/src/main/java/com/leonardobishop/quests/obj/misc/QMenuQuest.java new file mode 100644 index 00000000..ebc14648 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/obj/misc/QMenuQuest.java @@ -0,0 +1,224 @@ +package com.leonardobishop.quests.obj.misc; + +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.obj.Items; +import com.leonardobishop.quests.obj.Options; +import org.bukkit.Bukkit; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +public class QMenuQuest implements QMenu { + + private HashMap<Integer, String> slotsToQuestIds = new HashMap<>(); + private int backButtonLocation = -1; + private int pagePrevLocation = -1; + private int pageNextLocation = -1; + private int currentPage = -1; + private boolean backButtonEnabled = true; + private QMenuCategory superMenu; + private String categoryName; + private final int pageSize = 45; + private QPlayer owner; + + public QMenuQuest(QPlayer owner, String categoryName, QMenuCategory superMenu) { + this.owner = owner; + this.categoryName = categoryName; + this.superMenu = superMenu; + } + + public void populate(List<Quest> quests) { + int slot = 0; + for (Quest quest : quests) { + if (Options.GUI_HIDE_LOCKED.getBooleanValue()) { + QuestProgress questProgress = owner.getQuestProgressFile().getQuestProgress(quest); + long cooldown = owner.getQuestProgressFile().getCooldownFor(quest); + if (!owner.getQuestProgressFile().hasMetRequirements(quest) || (!quest.isRepeatable() && questProgress.isCompletedBefore()) || cooldown > 0) { + continue; + } + } + slotsToQuestIds.put(slot, quest.getId()); + slot++; + } + } + + @Override + public HashMap<Integer, String> getSlotsToMenu() { + return slotsToQuestIds; + } + + @Override + public QPlayer getOwner() { + return owner; + } + + public String getCategoryName() { + return categoryName; + } + + public int getPagePrevLocation() { + return pagePrevLocation; + } + + public int getPageNextLocation() { + return pageNextLocation; + } + + public int getCurrentPage() { + return currentPage; + } + + public int getPageSize() { + return pageSize; + } + + public Inventory toInventory(int page) { + currentPage = page; + int pageMin = pageSize * (page - 1); + int pageMax = pageSize * page; + String title = Options.color(Options.GUITITLE_QUESTS.getStringValue()); + + ItemStack pageIs; + ItemStack pagePrevIs; + ItemStack pageNextIs; + ItemStack back = Items.BACK_BUTTON.getItem(); + + Inventory inventory = Bukkit.createInventory(null, 54, title); + + int invSlot = 0; + for (int pointer = pageMin; pointer < pageMax; pointer++) { + if (slotsToQuestIds.containsKey(pointer)) { + Quest quest = Quests.getQuestManager().getQuestById(slotsToQuestIds.get(pointer)); + QuestProgress questProgress = owner.getQuestProgressFile().getQuestProgress(quest); + long cooldown = owner.getQuestProgressFile().getCooldownFor(quest); + if (!owner.getQuestProgressFile().hasMetRequirements(quest)) { + List<String> quests = new ArrayList<>(); + for (String requirement : quest.getRequirements()) { + quests.add(Quests.getQuestManager().getQuestById(requirement).getDisplayNameStripped()); + } + Map<String, String> placeholders = new HashMap<>(); + placeholders.put("{quest}", quest.getDisplayNameStripped()); + placeholders.put("{requirements}", String.join(", ", quests)); + ItemStack is = replaceItemStack(Items.QUEST_LOCKED.getItem(), placeholders); + inventory.setItem(invSlot, is); + } else if (!quest.isRepeatable() && questProgress.isCompletedBefore()) { + Map<String, String> placeholders = new HashMap<>(); + placeholders.put("{quest}", quest.getDisplayNameStripped()); + ItemStack is = replaceItemStack(Items.QUEST_COMPLETED.getItem(), placeholders); + inventory.setItem(invSlot, is); + } else if (cooldown > 0) { + Map<String, String> placeholders = new HashMap<>(); + placeholders.put("{time}", Quests.convertToFormat(TimeUnit.MINUTES.convert(cooldown, TimeUnit.MILLISECONDS))); + placeholders.put("{quest}", quest.getDisplayNameStripped()); + ItemStack is = replaceItemStack(Items.QUEST_COOLDOWN.getItem(), placeholders); + inventory.setItem(invSlot, is); + } else { + inventory.setItem(invSlot, Quests.getQuestManager().getQuestById(quest.getId()).getDisplayItem().toItemStack(questProgress)); + } + } + invSlot++; + } + + pageNextLocation = -1; + pagePrevLocation = -1; + + Map<String, String> pageplaceholders = new HashMap<>(); + pageplaceholders.put("{prevpage}", String.valueOf(page - 1)); + pageplaceholders.put("{nextpage}", String.valueOf(page + 1)); + pageplaceholders.put("{page}", String.valueOf(page)); + pageIs = replaceItemStack(Items.PAGE_DESCRIPTION.getItem(), pageplaceholders); + pagePrevIs = replaceItemStack(Items.PAGE_PREV.getItem(), pageplaceholders); + pageNextIs = replaceItemStack(Items.PAGE_NEXT.getItem(), pageplaceholders); + + if (Options.CATEGORIES_ENABLED.getBooleanValue() && backButtonEnabled) { + inventory.setItem(45, back); + backButtonLocation = 45; + } + if (slotsToQuestIds.size() > pageSize) { + inventory.setItem(49, pageIs); + if (page != 1) { + inventory.setItem(48, pagePrevIs); + pagePrevLocation = 48; + } + if (Math.ceil((double) slotsToQuestIds.size() / ((double) 45)) != page) { + inventory.setItem(50, pageNextIs); + pageNextLocation = 50; + } + } else if (Options.TRIM_GUI_SIZE.getBooleanValue() && page == 1) { + int slotsUsed = 0; + for (int pointer = 0; pointer < pageMax; pointer++) { + if (inventory.getItem(pointer) != null) { + slotsUsed++; + } + } + + int inventorySize = (slotsUsed >= 54) ? 54 : slotsUsed + (9 - slotsUsed % 9) * Math.min(1, slotsUsed % 9); + inventorySize = inventorySize <= 0 ? 9 : inventorySize; + if (inventorySize == 54) { + return inventory; + } else if (Options.CATEGORIES_ENABLED.getBooleanValue() && backButtonEnabled) { + inventorySize += 9; + } + + Inventory trimmedInventory = Bukkit.createInventory(null, inventorySize, title); + + for (int slot = 0; slot < trimmedInventory.getSize(); slot++) { + if (slot >= (trimmedInventory.getSize() - 9) && backButtonEnabled){ + if (Options.CATEGORIES_ENABLED.getBooleanValue()) { + trimmedInventory.setItem(slot, back); + backButtonLocation = slot; + } + break; + } + trimmedInventory.setItem(slot, inventory.getItem(slot)); + } + return trimmedInventory; + } + + return inventory; + } + + public boolean isBackButtonEnabled() { + return backButtonEnabled; + } + + public void setBackButtonEnabled(boolean backButtonEnabled) { + this.backButtonEnabled = backButtonEnabled; + } + + public int getBackButtonLocation() { + return backButtonLocation; + } + + public QMenuCategory getSuperMenu() { + return superMenu; + } + + public ItemStack replaceItemStack(ItemStack is, Map<String, String> placeholders) { + ItemStack newItemStack = is.clone(); + List<String> lore = newItemStack.getItemMeta().getLore(); + List<String> newLore = new ArrayList<>(); + ItemMeta ism = newItemStack.getItemMeta(); + if (lore != null) { + for (String s : lore) { + for (Map.Entry<String, String> entry : placeholders.entrySet()) { + s = s.replace(entry.getKey(), entry.getValue()); + ism.setDisplayName(ism.getDisplayName().replace(entry.getKey(), entry.getValue())); + } + newLore.add(s); + } + } + ism.setLore(newLore); + newItemStack.setItemMeta(ism); + return newItemStack; + } +} diff --git a/src/main/java/com/leonardobishop/quests/obj/misc/creator/QMenuCreator.java b/src/main/java/com/leonardobishop/quests/obj/misc/creator/QMenuCreator.java new file mode 100644 index 00000000..86fffd12 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/obj/misc/creator/QMenuCreator.java @@ -0,0 +1,70 @@ +package com.leonardobishop.quests.obj.misc.creator; + +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.obj.misc.QMenu; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class QMenuCreator implements QMenu { + + private QPlayer owner; + + public QMenuCreator(QPlayer owner) { + this.owner = owner; + } + + @Override + public HashMap<Integer, String> getSlotsToMenu() { + return null; + } + + @Override + public QPlayer getOwner() { + return owner; + } + + public Inventory toInventory(int page) { + String title = "Quest Creator"; + + Inventory inventory = Bukkit.createInventory(null, 9, title); + + ItemStack newQuest = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 5); + ItemMeta newQuestM = newQuest.getItemMeta(); + List<String> newQuestL = new ArrayList<>(); + newQuestM.setDisplayName(ChatColor.GREEN.toString() + ChatColor.BOLD + "New Quest"); + newQuestL.add(ChatColor.GRAY + "Click to make a new quest."); + newQuestM.setLore(newQuestL); + newQuest.setItemMeta(newQuestM); + + ItemStack editQuest = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 1); + ItemMeta editQuestM = editQuest.getItemMeta(); + List<String> editQuestL = new ArrayList<>(); + editQuestM.setDisplayName(ChatColor.GREEN.toString() + ChatColor.BOLD + "Edit Quest"); + editQuestL.add(ChatColor.GRAY + "Click to edit an existing quest."); + editQuestM.setLore(editQuestL); + editQuest.setItemMeta(editQuestM); + + ItemStack removeQuest = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 14); + ItemMeta removeQuestM = removeQuest.getItemMeta(); + List<String> removeQuestL = new ArrayList<>(); + removeQuestM.setDisplayName(ChatColor.GREEN.toString() + ChatColor.BOLD + "Delete Quest"); + removeQuestL.add(ChatColor.GRAY + "Click to delete an existing quest."); + removeQuestM.setLore(removeQuestL); + removeQuest.setItemMeta(removeQuestM); + + inventory.setItem(2, newQuest); + inventory.setItem(4, editQuest); + inventory.setItem(6, removeQuest); + + return inventory; + } + +} diff --git a/src/main/java/com/leonardobishop/quests/player/QPlayer.java b/src/main/java/com/leonardobishop/quests/player/QPlayer.java new file mode 100644 index 00000000..65b007db --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/player/QPlayer.java @@ -0,0 +1,122 @@ +package com.leonardobishop.quests.player; + +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.quests.Category; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.events.EventInventory; +import com.leonardobishop.quests.obj.Options; +import com.leonardobishop.quests.obj.misc.QMenuCategory; +import com.leonardobishop.quests.obj.misc.QMenuQuest; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +public class QPlayer { + + private UUID uuid; + private QuestProgressFile questProgressFile; + private boolean onlyDataLoaded; + + public QPlayer(UUID uuid, QuestProgressFile questProgressFile) { + this(uuid, questProgressFile, false); + } + + public QPlayer(UUID uuid, QuestProgressFile questProgressFile, boolean onlyDataLoaded) { + this.uuid = uuid; + this.questProgressFile = questProgressFile; + this.onlyDataLoaded = onlyDataLoaded; + } + + public UUID getUuid() { + return uuid; + } + + public void openCategory(Category category) { + if (onlyDataLoaded) { + return; + } + + Player player = Bukkit.getPlayer(uuid); + if (player == null) { + return; + } + + QMenuQuest qMenuQuest = new QMenuQuest(Quests.getPlayerManager().getPlayer(player.getUniqueId()), category.getId(), null); + List<Quest> quests = new ArrayList<>(); + for (String questid : category.getRegisteredQuestIds()) { + Quest quest = Quests.getQuestManager().getQuestById(questid); + if (quest != null) { + quests.add(quest); + } + } + qMenuQuest.populate(quests); + qMenuQuest.setBackButtonEnabled(false); + + player.openInventory(qMenuQuest.toInventory(1)); + EventInventory.track(player.getUniqueId(), qMenuQuest); + } + + public void openQuests() { + if (onlyDataLoaded) { + return; + } + + Player player = Bukkit.getPlayer(uuid); + if (player == null) { + return; + } + + if (Options.CATEGORIES_ENABLED.getBooleanValue()) { + QMenuCategory qMenuCategory = new QMenuCategory(Quests.getPlayerManager().getPlayer(player.getUniqueId())); + List<QMenuQuest> questMenus = new ArrayList<>(); + for (Category category : Quests.getQuestManager().getCategories()) { + QMenuQuest qMenuQuest = new QMenuQuest(Quests.getPlayerManager().getPlayer(player.getUniqueId()), category.getId(), qMenuCategory); + List<Quest> quests = new ArrayList<>(); + for (String questid : category.getRegisteredQuestIds()) { + Quest quest = Quests.getQuestManager().getQuestById(questid); + if (quest != null) { + quests.add(quest); + } + } + qMenuQuest.populate(quests); + questMenus.add(qMenuQuest); + } + qMenuCategory.populate(questMenus); + + player.openInventory(qMenuCategory.toInventory(1)); + EventInventory.track(player.getUniqueId(), qMenuCategory); + } else { + QMenuQuest qMenuQuest = new QMenuQuest(Quests.getPlayerManager().getPlayer(player.getUniqueId()), "", null); + List<Quest> quests = new ArrayList<>(); + for (Map.Entry<String, Quest> entry : Quests.getQuestManager().getQuests().entrySet()) { + quests.add(entry.getValue()); + } + qMenuQuest.populate(quests); + qMenuQuest.setBackButtonEnabled(false); + + player.openInventory(qMenuQuest.toInventory(1)); + EventInventory.track(player.getUniqueId(), qMenuQuest); + } + } + + public boolean isOnlyDataLoaded() { + return onlyDataLoaded; + } + + public void setOnlyDataLoaded(boolean onlyDataLoaded) { + this.onlyDataLoaded = onlyDataLoaded; + } + + public QuestProgressFile getQuestProgressFile() { + return questProgressFile; + } + + public QuestProgressFile setQuestProgressFile() { + return questProgressFile; + } +} diff --git a/src/main/java/com/leonardobishop/quests/player/QPlayerManager.java b/src/main/java/com/leonardobishop/quests/player/QPlayerManager.java new file mode 100644 index 00000000..295f3c5b --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/player/QPlayerManager.java @@ -0,0 +1,78 @@ +package com.leonardobishop.quests.player; + +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.Quests; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.util.*; + +public class QPlayerManager { + + private Map<UUID, QPlayer> qPlayers = new HashMap<>(); + + public void addPlayer(QPlayer qPlayer) { + qPlayers.put(qPlayer.getUuid(), qPlayer); + } + + public QPlayer getPlayer(UUID uuid) { + return qPlayers.get(uuid); + } + + public void removePlayer(UUID uuid) { + qPlayers.remove(uuid); + } + + public Collection<QPlayer> getQPlayers() { + return qPlayers.values(); + } + + public void loadPlayer(UUID uuid) { + loadPlayer(uuid, false); + } + + public void loadPlayer(UUID uuid, boolean onlyData) { + if (getPlayer(uuid) == null || getPlayer(uuid).isOnlyDataLoaded()) { + QuestProgressFile questProgressFile = new QuestProgressFile(uuid); + + try { + File directory = new File(Quests.getInstance().getDataFolder() + File.separator + "playerdata"); + if (directory.exists() && directory.isDirectory()) { + File file = new File(Quests.getInstance().getDataFolder() + File.separator + "playerdata" + File.separator + uuid.toString() + ".yml"); + if (file.exists()) { + YamlConfiguration data = YamlConfiguration.loadConfiguration(file); + if (data.contains("quest-progress")) { + for (String id : data.getConfigurationSection("quest-progress").getKeys(false)) { + boolean started = data.getBoolean("quest-progress." + id + ".started"); + boolean completed = data.getBoolean("quest-progress." + id + ".completed"); + boolean completedBefore = data.getBoolean("quest-progress." + id + ".completed-before"); + long completionDate = data.getLong("quest-progress." + id + ".completion-date"); + + QuestProgress questProgress = new QuestProgress(id, completed, completedBefore, completionDate, uuid, started, true); + + for (String taskid : data.getConfigurationSection("quest-progress." + id + ".task-progress").getKeys(false)) { + boolean taskCompleted = data.getBoolean("quest-progress." + id + ".task-progress." + taskid + ".completed"); + Object taskProgression = data.get("quest-progress." + id + ".task-progress." + taskid + ".progress"); + + TaskProgress taskProgress = new TaskProgress(taskid, taskProgression, uuid, taskCompleted); + questProgress.addTaskProgress(taskProgress); + } + + questProgressFile.addQuestProgress(questProgress); + } + } + } + } + } catch (Exception ignored) { + // fuck + } + + QPlayer qPlayer = new QPlayer(uuid, questProgressFile, onlyData); + + addPlayer(qPlayer); + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgress.java b/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgress.java new file mode 100644 index 00000000..26326269 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgress.java @@ -0,0 +1,106 @@ +package com.leonardobishop.quests.player.questprogressfile; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class QuestProgress { + + private Map<String, TaskProgress> taskProgress = new HashMap<>(); + private String questid; + private boolean started; + private boolean completed; + private boolean completedBefore; + private long completionDate; + private UUID player; + private boolean modified; + + public QuestProgress(String questid, boolean completed, boolean completedBefore, long completionDate, UUID player, boolean started) { + this.questid = questid; + this.completed = completed; + this.completedBefore = completedBefore; + this.completionDate = completionDate; + this.player = player; + this.started = started; + } + + public QuestProgress(String questid, boolean completed, boolean completedBefore, long completionDate, UUID player, boolean started, boolean modified) { + this(questid, completed, completedBefore, completionDate, player, started); + this.modified = modified; + } + + public String getQuestId() { + return questid; + } + + public boolean isCompleted() { + return completed; + } + + public void setCompleted(boolean completed) { + this.completed = completed; + this.modified = true; + } + + public boolean isStarted() { + return started; + } + + public void setStarted(boolean started) { + this.started = started; + this.modified = true; + } + + public long getCompletionDate() { + return completionDate; + } + + public void setCompletionDate(long completionDate) { + this.completionDate = completionDate; + this.modified = true; + } + + public UUID getPlayer() { + return player; + } + + public boolean isCompletedBefore() { + return completedBefore; + } + + public void setCompletedBefore(boolean completedBefore) { + this.completedBefore = completedBefore; + this.modified = true; + } + + public void addTaskProgress(TaskProgress taskProgress) { + this.taskProgress.put(taskProgress.getTaskId(), taskProgress); + } + + public Collection<TaskProgress> getTaskProgress() { + return taskProgress.values(); + } + + public TaskProgress getTaskProgress(String taskId) { + TaskProgress tP = taskProgress.getOrDefault(taskId, null); + if (tP == null) { + repairTaskProgress(taskId); + tP = taskProgress.getOrDefault(taskId, null); + } + return tP; + } + + public void repairTaskProgress(String taskid) { + TaskProgress taskProgress = new TaskProgress(taskid, null, player, false); + this.addTaskProgress(taskProgress); + } + + public boolean isWorthSaving() { + return modified; + } + + public void setWorthSaving(boolean modified) { + this.modified = modified; + } +} diff --git a/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgressFile.java b/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgressFile.java new file mode 100644 index 00000000..bba02878 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgressFile.java @@ -0,0 +1,257 @@ +package com.leonardobishop.quests.player.questprogressfile; + +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.obj.Messages; +import com.leonardobishop.quests.obj.Options; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; + +import java.io.File; +import java.io.IOException; +import java.util.*; +import java.util.concurrent.TimeUnit; + +public class QuestProgressFile { + + private Map<String, QuestProgress> questProgress = new HashMap<>(); + private UUID player; + + public QuestProgressFile(UUID player) { + this.player = player; + } + + //TODO change back to quest id to save performance + + public boolean completeQuest(Quest quest) { + QuestProgress questProgress = getQuestProgress(quest); + questProgress.setStarted(false); + questProgress.setCompleted(true); + questProgress.setCompletedBefore(true); + questProgress.setCompletionDate(System.currentTimeMillis()); + if (Bukkit.getPlayer(player) != null) { + Player player = Bukkit.getPlayer(this.player); + Bukkit.getServer().getScheduler().runTask(Quests.getInstance(), () -> { + for (String s : quest.getRewards()) { + Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), s.replace("{player}", player.getName())); + } + }); + player.sendMessage(Messages.QUEST_COMPLETE.getMessage().replace("{quest}", quest.getDisplayNameStripped())); + if (Options.TITLES_ENABLED.getBooleanValue()) { + Quests.getTitle().sendTitle(player, Messages.TITLE_QUEST_COMPLETE_TITLE.getMessage().replace("{quest}", quest + .getDisplayNameStripped()), Messages.TITLE_QUEST_COMPLETE_SUBTITLE.getMessage().replace("{quest}", quest + .getDisplayNameStripped())); + } + for (String s : quest.getRewardString()) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', s)); + } + } + return true; + } + + /** + * Start a quest for the player. + * + * @param quest the quest to check + * @return 0 if successful, 1 if limit reached, 2 if quest is already completed, 3 if quest has cooldown, 4 if still locked, 5 if already started + */ + public int startQuest(Quest quest) { + Player p = Bukkit.getPlayer(player); + if (getStartedQuests().size() >= Options.QUESTS_START_LIMIT.getIntValue()) { + if (player != null) { + p.sendMessage(Messages.QUEST_START_LIMIT.getMessage().replace("{limit}", String.valueOf(Options.QUESTS_START_LIMIT.getIntValue()))); + } + return 1; + } + QuestProgress questProgress = getQuestProgress(quest); + if (!quest.isRepeatable() && questProgress.isCompletedBefore()) { + if (player != null) { + p.sendMessage(Messages.QUEST_START_DISABLED.getMessage()); + } + return 2; + } + long cooldown = getCooldownFor(quest); + if (cooldown > 0) { + if (player != null) { + p.sendMessage(Messages.QUEST_START_COOLDOWN.getMessage().replace("{time}", String.valueOf(Quests.convertToFormat(TimeUnit.MINUTES.convert(cooldown, TimeUnit.MILLISECONDS))))); + } + return 3; + } + if (!hasMetRequirements(quest)) { + if (player != null) { + p.sendMessage(Messages.QUEST_START_LOCKED.getMessage()); + } + return 4; + } + if (!questProgress.isStarted()) { + if (player != null) { + p.sendMessage(Messages.QUEST_START_STARTED.getMessage()); + } + return 5; + } + questProgress.setStarted(true); + for (TaskProgress taskProgress : questProgress.getTaskProgress()) { + taskProgress.setCompleted(false); + taskProgress.setProgress(null); + } + questProgress.setCompleted(false); + if (Bukkit.getPlayer(player) != null) { + Player player = Bukkit.getPlayer(getPlayer()); + player.sendMessage(Messages.QUEST_START.getMessage().replace("{quest}", quest.getDisplayNameStripped())); + if (Options.TITLES_ENABLED.getBooleanValue()) { + Quests.getTitle().sendTitle(player, Messages.TITLE_QUEST_START_TITLE.getMessage().replace("{quest}", quest + .getDisplayNameStripped()), Messages.TITLE_QUEST_START_SUBTITLE.getMessage().replace("{quest}", quest + .getDisplayNameStripped())); + } + } + return 0; + } + + public boolean cancelQuest(Quest quest) { + QuestProgress questProgress = getQuestProgress(quest); + if (!questProgress.isStarted()) { + if (Bukkit.getPlayer(player) != null) { + Bukkit.getPlayer(getPlayer()).sendMessage(Messages.QUEST_CANCEL_NOTSTARTED.getMessage()); + } + return false; + } + questProgress.setStarted(false); + for (TaskProgress taskProgress : questProgress.getTaskProgress()) { + taskProgress.setProgress(null); + } + if (Bukkit.getPlayer(player) != null) { + Bukkit.getPlayer(getPlayer()).sendMessage(Messages.QUEST_CANCEL.getMessage().replace("{quest}", quest.getDisplayNameStripped())); + } + return true; + } + + public void addQuestProgress(QuestProgress questProgress) { + this.questProgress.put(questProgress.getQuestId(), questProgress); + } + + public List<Quest> getStartedQuests() { + List<Quest> startedQuests = new ArrayList<>(); + for (QuestProgress questProgress : questProgress.values()) { + if (questProgress.isStarted()) { + startedQuests.add(Quests.getQuestManager().getQuestById(questProgress.getQuestId())); + } + } + return startedQuests; + } + + public boolean hasQuestProgress(Quest quest) { + return questProgress.containsKey(quest.getId()); + } + + public boolean hasStartedQuest(Quest quest) { + //TODO always return true if the need for starting quests is disabled & requirements are met + if (hasQuestProgress(quest)) { + if (getQuestProgress(quest).isStarted()) { + return true; + } + } + return false; + } + + public long getCooldownFor(Quest quest) { + QuestProgress questProgress = getQuestProgress(quest); + if (quest.isCooldownEnabled() && questProgress.isCompleted()) { + if (questProgress.getCompletionDate() > 0) { + long date = questProgress.getCompletionDate(); + return (date + TimeUnit.MILLISECONDS.convert(quest.getCooldown(), TimeUnit.MINUTES)) - System.currentTimeMillis(); + } + } + return 0; + } + + public boolean hasMetRequirements(Quest quest) { + for (String id : quest.getRequirements()) { + Quest q = Quests.getQuestManager().getQuestById(id); + if (q == null) { + continue; + } + if (hasQuestProgress(q) && !getQuestProgress(q).isCompletedBefore()) { + return false; + } else if (!hasQuestProgress(q)) { + return false; + } + } + return true; + } + + public UUID getPlayer() { + return player; + } + + public QuestProgress getQuestProgress(Quest quest) { + if (questProgress.containsKey(quest.getId())) { + return questProgress.get(quest.getId()); + } else if (generateBlankQuestProgress(quest.getId())) { + return getQuestProgress(quest); + } + return null; + } + + public boolean generateBlankQuestProgress(String questid) { + if (Quests.getQuestManager().getQuestById(questid) != null) { + Quest quest = Quests.getQuestManager().getQuestById(questid); + QuestProgress questProgress = new QuestProgress(quest.getId(), false, false, 0, player, false, false); + for (Task task : quest.getTasks()) { + TaskProgress taskProgress = new TaskProgress(task.getId(), null, player, false); + questProgress.addTaskProgress(taskProgress); + } + + addQuestProgress(questProgress); + return true; + } + return false; + } + + public void saveToDisk() { + File directory = new File(Quests.getInstance().getDataFolder() + File.separator + "playerdata"); + if (!directory.exists() && !directory.isDirectory()) { + directory.mkdirs(); + } + File file = new File(Quests.getInstance().getDataFolder() + File.separator + "playerdata" + File.separator + player.toString() + ".yml"); + if (!file.exists()) { + try { + file.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + YamlConfiguration data = YamlConfiguration.loadConfiguration(file); + data.set("quest-progress", null); + for (QuestProgress questProgress : questProgress.values()) { + if (!questProgress.isWorthSaving()) { + continue; + } + data.set("quest-progress." + questProgress.getQuestId() + ".started", questProgress.isStarted()); + data.set("quest-progress." + questProgress.getQuestId() + ".completed", questProgress.isCompleted()); + data.set("quest-progress." + questProgress.getQuestId() + ".completed-before", questProgress.isCompletedBefore()); + data.set("quest-progress." + questProgress.getQuestId() + ".completion-date", questProgress.getCompletionDate()); + for (TaskProgress taskProgress : questProgress.getTaskProgress()) { + data.set("quest-progress." + questProgress.getQuestId() + ".task-progress." + taskProgress.getTaskId() + ".completed", taskProgress + .isCompleted()); + data.set("quest-progress." + questProgress.getQuestId() + ".task-progress." + taskProgress.getTaskId() + ".progress", taskProgress + .getProgress()); + } + } + + try { + data.save(file); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void clear() { + questProgress.clear(); + } + +} + diff --git a/src/main/java/com/leonardobishop/quests/player/questprogressfile/TaskProgress.java b/src/main/java/com/leonardobishop/quests/player/questprogressfile/TaskProgress.java new file mode 100644 index 00000000..d85c8599 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/player/questprogressfile/TaskProgress.java @@ -0,0 +1,41 @@ +package com.leonardobishop.quests.player.questprogressfile; + +import java.util.UUID; + +public class TaskProgress { + + private String taskid; + private Object progress; + private UUID player; + private boolean completed; + + public TaskProgress(String taskid, Object progress, UUID player, boolean completed) { + this.taskid = taskid; + this.progress = progress; + this.completed = completed; + } + + public String getTaskId() { + return taskid; + } + + public Object getProgress() { + return progress; + } + + public void setProgress(Object progress) { + this.progress = progress; + } + + public UUID getPlayer() { + return player; + } + + public boolean isCompleted() { + return completed; + } + + public void setCompleted(boolean complete) { + this.completed = complete; + } +} diff --git a/src/main/java/com/leonardobishop/quests/quests/Category.java b/src/main/java/com/leonardobishop/quests/quests/Category.java new file mode 100644 index 00000000..ede6a4c2 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/Category.java @@ -0,0 +1,42 @@ +package com.leonardobishop.quests.quests; + +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.List; + +public class Category { + + private String id; + private ItemStack displayItem; + private List<String> registeredQuestIds = new ArrayList<>(); + + public Category(String id, ItemStack displayItem) { + this.id = id; + this.displayItem = displayItem; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public ItemStack getDisplayItem() { + return displayItem; + } + + public void setDisplayItem(ItemStack displayItem) { + this.displayItem = displayItem; + } + + public void registerQuestId(String questid) { + registeredQuestIds.add(questid); + } + + public List<String> getRegisteredQuestIds() { + return registeredQuestIds; + } +} diff --git a/src/main/java/com/leonardobishop/quests/quests/Quest.java b/src/main/java/com/leonardobishop/quests/quests/Quest.java new file mode 100644 index 00000000..0c102156 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/Quest.java @@ -0,0 +1,96 @@ +package com.leonardobishop.quests.quests; + +import com.leonardobishop.quests.obj.misc.QItemStack; +import org.bukkit.ChatColor; + +import java.util.*; + +public class Quest { + + private Map<String, Task> tasks = new HashMap<>(); + //TODO: maybe store by <tasktypename (string), list<task>> since we never get task by id, but always get tasks by type. + private String id; + private QItemStack displayItem; + private List<String> rewards; + private List<String> requirements; + private List<String> rewardString; + private boolean repeatable; + private boolean cooldownEnabled; + private int cooldown; + private String categoryid; + + + public Quest(String id, QItemStack displayItem, List<String> rewards, List<String> requirements, boolean repeatable, boolean cooldownEnabled, int cooldown, List<String> rewardString, String categoryid) { + this(id, displayItem, rewards, requirements, repeatable, cooldownEnabled, cooldown, rewardString); + this.categoryid = categoryid; + } + + public Quest(String id, QItemStack displayItem, List<String> rewards, List<String> requirements, boolean repeatable, boolean cooldownEnabled, int cooldown, List<String> rewardString) { + this.id = id; + this.displayItem = displayItem; + this.rewards = rewards; + this.requirements = requirements; + this.repeatable = repeatable; + this.cooldownEnabled = cooldownEnabled; + this.cooldown = cooldown; + this.rewardString = rewardString; + } + + public void registerTask(Task task) { + tasks.put(task.getId(), task); + } + + public Collection<Task> getTasks() { + return tasks.values(); + } + + public List<Task> getTasksOfType(String type) { + List<Task> tasks = new ArrayList<>(); + for (Task task : getTasks()) { + if (task.getType().equals(type)) { + tasks.add(task); + } + } + return tasks; + } + + public List<String> getRewardString() { + return rewardString; + } + + public String getId() { + return id; + } + + public QItemStack getDisplayItem() { + return displayItem; + } + + public List<String> getRewards() { + return rewards; + } + + public List<String> getRequirements() { + return requirements; + } + + public boolean isRepeatable() { + return repeatable; + } + + public boolean isCooldownEnabled() { + return cooldownEnabled; + } + + public int getCooldown() { + return cooldown; + } + + public String getCategoryId() { + return categoryid; + } + + public String getDisplayNameStripped() { + return ChatColor.stripColor(this.displayItem.getName()); + } +} diff --git a/src/main/java/com/leonardobishop/quests/quests/QuestManager.java b/src/main/java/com/leonardobishop/quests/quests/QuestManager.java new file mode 100644 index 00000000..fd01711c --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/QuestManager.java @@ -0,0 +1,38 @@ +package com.leonardobishop.quests.quests; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class QuestManager { + + private Map<String, Quest> quests = new LinkedHashMap<>(); + private List<Category> categories = new ArrayList<>(); + + public void registerQuest(Quest quest) { + quests.put(quest.getId(), quest); + } + + public Quest getQuestById(String id) { + return quests.get(id); + } + + public Map<String, Quest> getQuests() { + return quests; + } + + public void registerCategory(Category category) { categories.add(category); } + + public List<Category> getCategories() { + return categories; + } + + public Category getCategoryById(String id) { + for (Category category : categories) { + if (category.getId().equals(id)) return category; + } + return null; + } + +} diff --git a/src/main/java/com/leonardobishop/quests/quests/Task.java b/src/main/java/com/leonardobishop/quests/quests/Task.java new file mode 100644 index 00000000..55b6845f --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/Task.java @@ -0,0 +1,38 @@ +package com.leonardobishop.quests.quests; + +import java.util.HashMap; +import java.util.Map; + +public class Task { + + private Map<String, Object> configValues = new HashMap<>(); + + private String id; + private String type; + + public Task(String id, String type) { + this.id = id; + this.type = type; + } + + public String getId() { + return id; + } + + public String getType() { + return type; + } + + public Object getConfigValue(String key) { + return configValues.getOrDefault(key, null); + } + + public Map<String, Object> getConfigValues() { + return configValues; + } + + public void addConfigValue(String key, Object value) { + configValues.put(key, value); + } + +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/ConfigValue.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/ConfigValue.java new file mode 100644 index 00000000..e4bfb08e --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/ConfigValue.java @@ -0,0 +1,29 @@ +package com.leonardobishop.quests.quests.tasktypes; + +/** + * This is for the quest creator and is purely cosmetic. + */ +public final class ConfigValue { + + private String key; + private boolean required; + private String description; + + public ConfigValue(String key, boolean required, String description) { + this.key = key; + this.required = required; + this.description = description; + } + + public String getKey() { + return key; + } + + public boolean isRequired() { + return required; + } + + public String getDescription() { + return description; + } +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskType.java new file mode 100644 index 00000000..51770401 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskType.java @@ -0,0 +1,56 @@ +package com.leonardobishop.quests.quests.tasktypes; + +import com.leonardobishop.quests.quests.Quest; +import org.bukkit.event.Listener; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public abstract class TaskType implements Listener { + + private List<Quest> quests = new ArrayList<>(); + private String type; + private String author; + private String description; + + public TaskType(String type, String author, String description) { + this.type = type; + this.author = author; + this.description = description; + } + + public TaskType(String type) { + this.type = type; + } + + public final void registerQuest(Quest quest) { + if (!quests.contains(quest)) { + quests.add(quest); + } + } + + public final void unregisterAll() { + quests.clear(); + } + + public final List<Quest> getRegisteredQuests() { + return quests; + } + + public final String getType() { + return type; + } + + public String getAuthor() { + return author; + } + + public String getDescription() { + return description; + } + + public List<ConfigValue> getCreatorConfigValues() { + return Collections.emptyList(); + } +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskTypeManager.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskTypeManager.java new file mode 100644 index 00000000..a5141460 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskTypeManager.java @@ -0,0 +1,40 @@ +package com.leonardobishop.quests.quests.tasktypes; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import org.bukkit.Bukkit; + +import java.util.ArrayList; +import java.util.logging.Level; + +public class TaskTypeManager { + + private ArrayList<TaskType> taskTypes = new ArrayList<>(); + + public ArrayList<TaskType> getTaskTypes() { + return taskTypes; + } + + public void resetTaskTypes() { + for (TaskType taskType : taskTypes) { + taskType.getRegisteredQuests().clear(); + } + } + + public void registerTaskType(TaskType taskType) { + Bukkit.getPluginManager().registerEvents(taskType, Quests.getInstance()); + Quests.getInstance().getLogger().log(Level.INFO, "Task type " + taskType.getType() + " has been registered."); + taskTypes.add(taskType); + } + + public void registerQuestTasksWithTaskTypes(Quest quest) { + for (Task task : quest.getTasks()) { + for (TaskType taskType : taskTypes) { + if (taskType.getType().equalsIgnoreCase(task.getType())) { + taskType.registerQuest(quest); + } + } + } + } +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/ASkyBlockLevelType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/ASkyBlockLevelType.java new file mode 100644 index 00000000..0b14e1cb --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/ASkyBlockLevelType.java @@ -0,0 +1,64 @@ +package com.leonardobishop.quests.quests.tasktypes.types; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.ConfigValue; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import com.wasteofplastic.askyblock.events.IslandPostLevelEvent; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; + +import java.util.ArrayList; +import java.util.List; + +public final class ASkyBlockLevelType extends TaskType { + + private List<ConfigValue> creatorConfigValues = new ArrayList<>(); + + public ASkyBlockLevelType() { + super("askyblock_level", "fatpigsarefat", "Reach a certain island level for ASkyBlock."); + this.creatorConfigValues.add(new ConfigValue("level", true, "Minimum island level needed.")); + } + + @Override + public List<ConfigValue> getCreatorConfigValues() { + return creatorConfigValues; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onIslandLevel(IslandPostLevelEvent event) { + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(event.getPlayer()); + if (qPlayer == null) { + return; + } + + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); + + for (Quest quest : super.getRegisteredQuests()) { + if (questProgressFile.hasStartedQuest(quest)) { + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); + + for (Task task : quest.getTasksOfType(super.getType())) { + TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); + + if (taskProgress.isCompleted()) { + continue; + } + + long islandLevelNeeded = (long) (int) task.getConfigValue("level"); + + taskProgress.setProgress(event.getLongLevel()); + + if (((long) taskProgress.getProgress()) >= islandLevelNeeded) { + taskProgress.setCompleted(true); + } + } + } + } + } +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BrewingCertainTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BrewingCertainTaskType.java new file mode 100644 index 00000000..2c36f55a --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BrewingCertainTaskType.java @@ -0,0 +1,114 @@ +// TODO: fix +// +//package me.fatpigsarefat.quests.quests.tasktypes.types; +// +//import Quests; +//import QPlayer; +//import QuestProgress; +//import QuestProgressFile; +//import TaskProgress; +//import Quest; +//import Task; +//import ConfigValue; +//import TaskType; +//import org.bukkit.Bukkit; +//import org.bukkit.Location; +//import org.bukkit.Material; +//import org.bukkit.entity.Player; +//import org.bukkit.event.EventHandler; +//import org.bukkit.event.EventPriority; +//import org.bukkit.event.block.Action; +//import org.bukkit.event.inventory.BrewEvent; +//import org.bukkit.event.player.PlayerInteractEvent; +//import org.bukkit.inventory.ItemStack; +// +//import java.util.ArrayList; +//import java.util.HashMap; +//import java.util.List; +//import java.util.UUID; +// +//public final class BrewingCertainTaskType extends TaskType { +// +// private List<ConfigValue> creatorConfigValues = new ArrayList<>(); +// private HashMap<Location, UUID> brewingStands = new HashMap<>(); +// +// public BrewingCertainTaskType() { +// super("brewingcertain", "fatpigsarefat", "Brew a certain type of potion."); +// this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of potions to be brewed.")); +// this.creatorConfigValues.add(new ConfigValue("potion", true, "ID of potion to be brewed.")); +// } +// +// @Override +// public List<ConfigValue> getCreatorConfigValues() { +// return creatorConfigValues; +// } +// +// @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) +// public void onBlockPlace(PlayerInteractEvent event) { +// if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { +// if (event.getClickedBlock().getType() == Material.BREWING_STAND) { +// brewingStands.put(event.getClickedBlock().getLocation(), event.getPlayer().getUniqueId()); +// } +// } +// } +// +// @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) +// public void onBlockPlace(BrewEvent event) { +// UUID uuid; +// if ((uuid = brewingStands.get(event.getBlock().getLocation())) != null) { +// Player player = Bukkit.getPlayer(uuid); +// +// if (player == null) { +// return; +// } +// +// QPlayer qPlayer = Quests.getPlayerManager().getPlayer(player.getUniqueId()); +// QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); +// +// for (Quest quest : super.getRegisteredQuests()) { +// if (questProgressFile.hasStartedQuest(quest)) { +// QuestProgress questProgress = questProgressFile.getQuestProgress(quest); +// +// for (Task task : quest.getTasksOfType(super.getType())) { +// TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); +// +// if (taskProgress.isCompleted()) { +// continue; +// } +// +// int potionsNeeded = (int) task.getConfigValue("amount"); +// +// int progress; +// if (taskProgress.getProgress() == null) { +// progress = 0; +// } else { +// progress = (int) taskProgress.getProgress(); +// } +// +// int potionType = (int) task.getConfigValue("potion"); +// +// ItemStack potion1 = event.getContents().getItem(0); +// if (potion1.getDurability() != potionType) { +// potion1 = null; +// } +// ItemStack potion2 = event.getContents().getItem(1); +// if (potion2.getDurability() != potionType) { +// potion2 = null; +// } +// ItemStack potion3 = event.getContents().getItem(2); +// if (potion3.getDurability() != potionType) { +// potion3 = null; +// } +// +// taskProgress.setProgress(progress + (potion1 == null ? 0 : 1) + (potion2 == null ? 0 : 1) + (potion3 == null ? 0 : 1)); +// +// if (((int) taskProgress.getProgress()) >= potionsNeeded) { +// taskProgress.setCompleted(true); +// } +// } +// } +// } +// } +// } +// +//} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BrewingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BrewingTaskType.java new file mode 100644 index 00000000..4dafd7e2 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BrewingTaskType.java @@ -0,0 +1,100 @@ +package com.leonardobishop.quests.quests.tasktypes.types; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.ConfigValue; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.Action; +import org.bukkit.event.inventory.BrewEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.UUID; + +public final class BrewingTaskType extends TaskType { + + private List<ConfigValue> creatorConfigValues = new ArrayList<>(); + private HashMap<Location, UUID> brewingStands = new HashMap<>(); + + public BrewingTaskType() { + super("brewing", "fatpigsarefat", "Brew a potion."); + this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of potions to be brewed.")); + } + + @Override + public List<ConfigValue> getCreatorConfigValues() { + return creatorConfigValues; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onBlockPlace(PlayerInteractEvent event) { + if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { + if (event.getClickedBlock().getType() == Material.BREWING_STAND) { + brewingStands.put(event.getClickedBlock().getLocation(), event.getPlayer().getUniqueId()); + } + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onBlockPlace(BrewEvent event) { + UUID uuid; + if ((uuid = brewingStands.get(event.getBlock().getLocation())) != null) { + Player player = Bukkit.getPlayer(uuid); + + if (player == null) { + return; + } + + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(player.getUniqueId()); + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); + + for (Quest quest : super.getRegisteredQuests()) { + if (questProgressFile.hasStartedQuest(quest)) { + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); + + for (Task task : quest.getTasksOfType(super.getType())) { + TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); + + if (taskProgress.isCompleted()) { + continue; + } + + int potionsNeeded = (int) task.getConfigValue("amount"); + + int progress; + if (taskProgress.getProgress() == null) { + progress = 0; + } else { + progress = (int) taskProgress.getProgress(); + } + + ItemStack potion1 = event.getContents().getItem(0); + ItemStack potion2 = event.getContents().getItem(1); + ItemStack potion3 = event.getContents().getItem(2); + + taskProgress.setProgress(progress + (potion1 == null ? 0 : 1) + (potion2 == null ? 0 : 1) + (potion3 == null ? 0 : 1)); + + if (((int) taskProgress.getProgress()) >= potionsNeeded) { + taskProgress.setCompleted(true); + } + } + } + } + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BuildingCertainTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BuildingCertainTaskType.java new file mode 100644 index 00000000..28a97186 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BuildingCertainTaskType.java @@ -0,0 +1,102 @@ +package com.leonardobishop.quests.quests.tasktypes.types; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.blocktype.Block; +import com.leonardobishop.quests.blocktype.SimilarBlocks; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.ConfigValue; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockPlaceEvent; + +import java.util.ArrayList; +import java.util.List; + +public final class BuildingCertainTaskType extends TaskType { + + private List<ConfigValue> creatorConfigValues = new ArrayList<>(); + + public BuildingCertainTaskType() { + super("blockplacecertain", "fatpigsarefat", "Place a set amount of a specific block."); + this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of blocks to be placed.")); + this.creatorConfigValues.add(new ConfigValue("block", true, "Name or ID of block.")); + this.creatorConfigValues.add(new ConfigValue("data", false, "Data code for block.")); + this.creatorConfigValues.add(new ConfigValue("use-similar-blocks", false, "If true, this will ignore orientation of doors, logs etc.")); + } + + @Override + public List<ConfigValue> getCreatorConfigValues() { + return creatorConfigValues; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onBlockPlace(BlockPlaceEvent event) { + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(event.getPlayer().getUniqueId()); + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); + + for (Quest quest : super.getRegisteredQuests()) { + if (questProgressFile.hasStartedQuest(quest)) { + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); + + for (Task task : quest.getTasksOfType(super.getType())) { + TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); + + if (taskProgress.isCompleted()) { + continue; + } + + Material material; + Object configBlock = task.getConfigValue("block"); + Object configData = task.getConfigValue("data"); + Object configSimilarBlocks = task.getConfigValue("use-similar-blocks"); + + if (StringUtils.isNumeric(String.valueOf(configBlock))) { + material = Material.getMaterial((int) configBlock); + } else { + material = Material.getMaterial(String.valueOf(configBlock)); + } + + Material blockType = event.getBlock().getType(); + short blockData = event.getBlock().getData(); + + if (configSimilarBlocks != null && ((Boolean) configSimilarBlocks)) { + Block block; + if ((block = SimilarBlocks.getSimilarBlock(new Block(blockType, blockData))) != null) { + blockType = block.getMaterial(); + blockData = block.getData(); + } + } + + if (blockType.equals(material)) { + if (configData != null && (((int) blockData) != ((int) configData))) { + continue; + } + int brokenBlocksNeeded = (int) task.getConfigValue("amount"); + + int progressBlocksBroken; + if (taskProgress.getProgress() == null) { + progressBlocksBroken = 0; + } else { + progressBlocksBroken = (int) taskProgress.getProgress(); + } + + taskProgress.setProgress(progressBlocksBroken + 1); + + if (((int) taskProgress.getProgress()) >= brokenBlocksNeeded) { + taskProgress.setCompleted(true); + } + } + } + } + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BuildingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BuildingTaskType.java new file mode 100644 index 00000000..af1877c8 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BuildingTaskType.java @@ -0,0 +1,68 @@ +package com.leonardobishop.quests.quests.tasktypes.types; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.ConfigValue; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockPlaceEvent; + +import java.util.ArrayList; +import java.util.List; + +public final class BuildingTaskType extends TaskType { + + private List<ConfigValue> creatorConfigValues = new ArrayList<>(); + + public BuildingTaskType() { + super("blockplace", "fatpigsarefat", "Place a set amount of blocks."); + this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of blocks to be placed.")); + } + + @Override + public List<ConfigValue> getCreatorConfigValues() { + return creatorConfigValues; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onBlockPlace(BlockPlaceEvent event) { + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(event.getPlayer().getUniqueId()); + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); + + for (Quest quest : super.getRegisteredQuests()) { + if (questProgressFile.hasStartedQuest(quest)) { + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); + + for (Task task : quest.getTasksOfType(super.getType())) { + TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); + + if (taskProgress.isCompleted()) { + continue; + } + + int brokenBlocksNeeded = (int) task.getConfigValue("amount"); + + int progressBlocksBroken; + if (taskProgress.getProgress() == null) { + progressBlocksBroken = 0; + } else { + progressBlocksBroken = (int) taskProgress.getProgress(); + } + + taskProgress.setProgress(progressBlocksBroken + 1); + + if (((int) taskProgress.getProgress()) >= brokenBlocksNeeded) { + taskProgress.setCompleted(true); + } + } + } + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/DistancefromTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/DistancefromTaskType.java new file mode 100644 index 00000000..9f7744ff --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/DistancefromTaskType.java @@ -0,0 +1,83 @@ +package com.leonardobishop.quests.quests.tasktypes.types; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.ConfigValue; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerMoveEvent; + +import java.util.ArrayList; +import java.util.List; + +public final class DistancefromTaskType extends TaskType { + + private List<ConfigValue> creatorConfigValues = new ArrayList<>(); + + public DistancefromTaskType() { + super("distancefrom", "fatpigsarefat", "Distance yourself from a set of co-ordinates."); + this.creatorConfigValues.add(new ConfigValue("x", true, "X position.")); + this.creatorConfigValues.add(new ConfigValue("y", true, "Y position.")); + this.creatorConfigValues.add(new ConfigValue("z", true, "Z position.")); + this.creatorConfigValues.add(new ConfigValue("world", true, "Name of world.")); + this.creatorConfigValues.add(new ConfigValue("distance", true, "Distance the player needs to be from the co-ordinates.")); + } + + @Override + public List<ConfigValue> getCreatorConfigValues() { + return creatorConfigValues; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onMove(PlayerMoveEvent event) { + if (event.getFrom().getBlockX() == event.getTo().getBlockX() && event.getFrom().getBlockZ() == event.getTo().getBlockZ()) { + return; + } + + Player player = event.getPlayer(); + + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(player.getUniqueId()); + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); + + for (Quest quest : super.getRegisteredQuests()) { + if (questProgressFile.hasStartedQuest(quest)) { + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); + + for (Task task : quest.getTasksOfType(super.getType())) { + TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); + + if (taskProgress.isCompleted()) { + continue; + } + + int x = (int) task.getConfigValue("x"); + int y = (int) task.getConfigValue("y"); + int z = (int) task.getConfigValue("z"); + String worldString = (String) task.getConfigValue("world"); + int distance = (int) task.getConfigValue("distance"); + + World world = Bukkit.getWorld(worldString); + if (world == null) { + return; + } + + Location location = new Location(world, x, y, z); + if (player.getWorld().equals(world) && player.getLocation().distance(location) > distance) { + taskProgress.setCompleted(true); + } + } + } + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/FarmingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/FarmingTaskType.java new file mode 100644 index 00000000..b3553be6 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/FarmingTaskType.java @@ -0,0 +1,94 @@ +package com.leonardobishop.quests.quests.tasktypes.types; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.ConfigValue; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.material.Crops; + +import java.util.ArrayList; +import java.util.List; + +public final class FarmingTaskType extends TaskType { + + private List<ConfigValue> creatorConfigValues = new ArrayList<>(); + + public FarmingTaskType() { + super("farming", "fatpigsarefat", "Break a set amount of a crop."); + this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of crops to be broken.")); + this.creatorConfigValues.add(new ConfigValue("crop", true, "Name or ID of crop.")); + } + + @Override + public List<ConfigValue> getCreatorConfigValues() { + return creatorConfigValues; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent event) { + //TODO: finish this + if (!(event.getBlock().getState() instanceof Crops)) { + return; + } + Crops crop = (Crops) event.getBlock().getState(); + + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(event.getPlayer().getUniqueId()); + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); + + for (Quest quest : super.getRegisteredQuests()) { + if (questProgressFile.hasStartedQuest(quest)) { + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); + + for (Task task : quest.getTasksOfType(super.getType())) { + TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); + + if (taskProgress.isCompleted()) { + continue; + } + + Material material; + Object configBlock = task.getConfigValue("block"); + Object configData = task.getConfigValue("data"); + + if (StringUtils.isNumeric(String.valueOf(configBlock))) { + material = Material.getMaterial((int) configBlock); + } else { + material = Material.getMaterial(String.valueOf(configBlock)); + } + + if (material != null && event.getBlock().getType().equals(material)) { + + if (configData != null && (((int) event.getBlock().getData()) != ((int) configData))) { + continue; + } + int brokenBlocksNeeded = (int) task.getConfigValue("amount"); + + int progressBlocksBroken; + if (taskProgress.getProgress() == null) { + progressBlocksBroken = 0; + } else { + progressBlocksBroken = (int) taskProgress.getProgress(); + } + + taskProgress.setProgress(progressBlocksBroken + 1); + + if (((int) taskProgress.getProgress()) >= brokenBlocksNeeded) { + taskProgress.setCompleted(true); + } + } + } + } + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/FishingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/FishingTaskType.java new file mode 100644 index 00000000..0bac30ee --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/FishingTaskType.java @@ -0,0 +1,74 @@ +package com.leonardobishop.quests.quests.tasktypes.types; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.ConfigValue; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerFishEvent; + +import java.util.ArrayList; +import java.util.List; + +public final class FishingTaskType extends TaskType { + + private List<ConfigValue> creatorConfigValues = new ArrayList<>(); + + public FishingTaskType() { + super("fishing", "fatpigsarefat", "Catch a set amount of items from the sea."); + this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of fish to be caught.")); + } + + @Override + public List<ConfigValue> getCreatorConfigValues() { + return creatorConfigValues; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onFishCaught(PlayerFishEvent event) { + if (event.getState() == PlayerFishEvent.State.CAUGHT_FISH) { + return; + } + Player player = event.getPlayer(); + + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(player.getUniqueId()); + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); + + for (Quest quest : super.getRegisteredQuests()) { + if (questProgressFile.hasStartedQuest(quest)) { + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); + + for (Task task : quest.getTasksOfType(super.getType())) { + TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); + + if (taskProgress.isCompleted()) { + continue; + } + + int catchesNeeded = (int) task.getConfigValue("amount"); + + int progressCatches; + if (taskProgress.getProgress() == null) { + progressCatches = 0; + } else { + progressCatches = (int) taskProgress.getProgress(); + } + + taskProgress.setProgress(progressCatches + 1); + + if (((int) taskProgress.getProgress()) >= catchesNeeded) { + taskProgress.setCompleted(true); + } + } + } + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/InventoryTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/InventoryTaskType.java new file mode 100644 index 00000000..9e3863ae --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/InventoryTaskType.java @@ -0,0 +1,116 @@ +package com.leonardobishop.quests.quests.tasktypes.types; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.ConfigValue; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.inventory.InventoryInteractEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.List; + +public final class InventoryTaskType extends TaskType { + + private List<ConfigValue> creatorConfigValues = new ArrayList<>(); + + public InventoryTaskType() { + super("inventory", "fatpigsarefat", "Obtain a set of items."); + this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of item to retrieve.")); + this.creatorConfigValues.add(new ConfigValue("item", true, "Name or ID of item.")); + this.creatorConfigValues.add(new ConfigValue("remove-items-when-complete", false, "Take the items away from the player on completion (true/false, " + + "default = false).")); + } + + @Override + public List<ConfigValue> getCreatorConfigValues() { + return creatorConfigValues; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onItemPickup(PlayerPickupItemEvent event) { + new BukkitRunnable() { + @Override + public void run() { + checkInventory(event.getPlayer()); + } + }.runTaskLater(Quests.getInstance(), 1L); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onInventoryClick(InventoryInteractEvent event) { + new BukkitRunnable() { + @Override + public void run() { + checkInventory((Player) event.getWhoClicked()); + } + }.runTaskLater(Quests.getInstance(), 1L); + } + + private void checkInventory(Player player) { + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(player.getUniqueId()); + if (qPlayer == null) { + return; + } + + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); + + for (Quest quest : super.getRegisteredQuests()) { + if (questProgressFile.hasStartedQuest(quest)) { + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); + + for (Task task : quest.getTasksOfType(super.getType())) { + TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); + + if (taskProgress.isCompleted()) { + continue; + } + + Material material; + int amount = (int) task.getConfigValue("amount"); + Object configBlock = task.getConfigValue("item"); + Object configData = task.getConfigValue("data"); + Object remove = task.getConfigValue("remove-items-when-complete"); + + if (StringUtils.isNumeric(String.valueOf(configBlock))) { + material = Material.getMaterial((int) configBlock); + } else { + material = Material.getMaterial(String.valueOf(configBlock)); + } + + if (material == null) { + continue; + } + ItemStack is; + if (configData != null) { + is = new ItemStack(material, 1, ((Integer) configData).shortValue()); + } else { + is = new ItemStack(material, 1); + } + + if (player.getInventory().containsAtLeast(is, amount)) { + is.setAmount(amount); + taskProgress.setCompleted(true); + + if (remove != null && ((Boolean) remove)) { + player.getInventory().removeItem(is); + } + } + } + } + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MilkingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MilkingTaskType.java new file mode 100644 index 00000000..421051ff --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MilkingTaskType.java @@ -0,0 +1,77 @@ +package com.leonardobishop.quests.quests.tasktypes.types; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.ConfigValue; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import org.bukkit.Material; +import org.bukkit.entity.Cow; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerInteractEntityEvent; + +import java.util.ArrayList; +import java.util.List; + +public final class MilkingTaskType extends TaskType { + + private List<ConfigValue> creatorConfigValues = new ArrayList<>(); + + public MilkingTaskType() { + super("milking", "fatpigsarefat", "Milk a set amount of cows."); + this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of cows to be milked.")); + } + + @Override + public List<ConfigValue> getCreatorConfigValues() { + return creatorConfigValues; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onMilk(PlayerInteractEntityEvent event) { + if (!(event.getRightClicked() instanceof Cow) || (event.getPlayer().getItemInHand().getType() != Material.BUCKET)) { + return; + } + + Player player = event.getPlayer(); + + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(player.getUniqueId()); + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); + + for (Quest quest : super.getRegisteredQuests()) { + if (questProgressFile.hasStartedQuest(quest)) { + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); + + for (Task task : quest.getTasksOfType(super.getType())) { + TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); + + if (taskProgress.isCompleted()) { + continue; + } + + int cowsNeeded = (int) task.getConfigValue("amount"); + + int progressMilked; + if (taskProgress.getProgress() == null) { + progressMilked = 0; + } else { + progressMilked = (int) taskProgress.getProgress(); + } + + taskProgress.setProgress(progressMilked + 1); + + if (((int) taskProgress.getProgress()) >= cowsNeeded) { + taskProgress.setCompleted(true); + } + } + } + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MiningCertainTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MiningCertainTaskType.java new file mode 100644 index 00000000..8739bad8 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MiningCertainTaskType.java @@ -0,0 +1,102 @@ +package com.leonardobishop.quests.quests.tasktypes.types; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.blocktype.Block; +import com.leonardobishop.quests.blocktype.SimilarBlocks; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.ConfigValue; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; + +import java.util.ArrayList; +import java.util.List; + +public final class MiningCertainTaskType extends TaskType { + + private List<ConfigValue> creatorConfigValues = new ArrayList<>(); + + public MiningCertainTaskType() { + super("blockbreakcertain", "fatpigsarefat", "Break a set amount of a specific block."); + this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of blocks to be broken.")); + this.creatorConfigValues.add(new ConfigValue("block", true, "Name or ID of block.")); + this.creatorConfigValues.add(new ConfigValue("data", false, "Data code for block.")); + this.creatorConfigValues.add(new ConfigValue("use-similar-blocks", false, "If true, this will ignore orientation of doors, logs etc.")); + } + + @Override + public List<ConfigValue> getCreatorConfigValues() { + return creatorConfigValues; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent event) { + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(event.getPlayer().getUniqueId()); + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); + + for (Quest quest : super.getRegisteredQuests()) { + if (questProgressFile.hasStartedQuest(quest)) { + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); + + for (Task task : quest.getTasksOfType(super.getType())) { + TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); + + if (taskProgress.isCompleted()) { + continue; + } + + Material material; + Object configBlock = task.getConfigValue("block"); + Object configData = task.getConfigValue("data"); + Object configSimilarBlocks = task.getConfigValue("use-similar-blocks"); + + if (StringUtils.isNumeric(String.valueOf(configBlock))) { + material = Material.getMaterial((int) configBlock); + } else { + material = Material.getMaterial(String.valueOf(configBlock)); + } + + Material blockType = event.getBlock().getType(); + short blockData = event.getBlock().getData(); + + if (configSimilarBlocks != null && ((Boolean) configSimilarBlocks)) { + Block block; + if ((block = SimilarBlocks.getSimilarBlock(new Block(blockType, blockData))) != null) { + blockType = block.getMaterial(); + blockData = block.getData(); + } + } + + if (blockType.equals(material)) { + if (configData != null && (((int) blockData) != ((int) configData))) { + continue; + } + int brokenBlocksNeeded = (int) task.getConfigValue("amount"); + + int progressBlocksBroken; + if (taskProgress.getProgress() == null) { + progressBlocksBroken = 0; + } else { + progressBlocksBroken = (int) taskProgress.getProgress(); + } + + taskProgress.setProgress(progressBlocksBroken + 1); + + if (((int) taskProgress.getProgress()) >= brokenBlocksNeeded) { + taskProgress.setCompleted(true); + } + } + } + } + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MiningTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MiningTaskType.java new file mode 100644 index 00000000..4cb147e3 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MiningTaskType.java @@ -0,0 +1,72 @@ +package com.leonardobishop.quests.quests.tasktypes.types; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.ConfigValue; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; + +import java.util.ArrayList; +import java.util.List; + +public final class MiningTaskType extends TaskType { + + private List<ConfigValue> creatorConfigValues = new ArrayList<>(); + + public MiningTaskType() { + // type, author, description + super("blockbreak", "fatpigsarefat", "Break a set amount of blocks."); + + // config values for the quest creator to use, if unspecified then the quest creator will not know what to put here (and will require users to + // go into the config and manually configure there) + this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of blocks to be broken.")); + } + + @Override + public List<ConfigValue> getCreatorConfigValues() { + return creatorConfigValues; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent event) { + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(event.getPlayer().getUniqueId()); // get the qplayer so you can get their progress + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); // the quest progress file stores progress about all quests and tasks + + for (Quest quest : super.getRegisteredQuests()) { // iterate through all quests which are registered to use this task type + if (questProgressFile.hasStartedQuest(quest)) { // check if the player has actually started the quest before progressing it + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); // get their progress for the specific quest + + for (Task task : quest.getTasksOfType(super.getType())) { // get all tasks of this type + TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); // get the task progress and increment progress by 1 + + if (taskProgress.isCompleted()) { // dont need to increment a completed task + continue; + } + + int brokenBlocksNeeded = (int) task.getConfigValue("amount"); // this will retrieve a value from the config under the key "value" + + int progressBlocksBroken; + if (taskProgress.getProgress() == null) { // note: if the player has never progressed before, getProgress() will return null + progressBlocksBroken = 0; + } else { + progressBlocksBroken = (int) taskProgress.getProgress(); + } + + taskProgress.setProgress(progressBlocksBroken + 1); // the progress does not have to be an int, although must be serializable by the yaml provider + + if (((int) taskProgress.getProgress()) >= brokenBlocksNeeded) { // completion statement, if true the task is complete + taskProgress.setCompleted(true); + } + } + } + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MobkillingCertainTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MobkillingCertainTaskType.java new file mode 100644 index 00000000..c444631d --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MobkillingCertainTaskType.java @@ -0,0 +1,108 @@ +package com.leonardobishop.quests.quests.tasktypes.types; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.ConfigValue; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import org.bukkit.ChatColor; +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.entity.EntityDeathEvent; + +import java.util.ArrayList; +import java.util.List; + +public final class MobkillingCertainTaskType extends TaskType { + + private List<ConfigValue> creatorConfigValues = new ArrayList<>(); + + public MobkillingCertainTaskType() { + super("mobkillingcertain", "fatpigsarefat", "Kill a set amount of a specific entity type."); + this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of mobs to be killed.")); + this.creatorConfigValues.add(new ConfigValue("mob", true, "Name of mob.")); + this.creatorConfigValues.add(new ConfigValue("name", false, "Only allow a specific name for mob (unspecified = any name allowed).")); + } + + @Override + public List<ConfigValue> getCreatorConfigValues() { + return creatorConfigValues; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onMobKill(EntityDeathEvent event) { + Entity killer = event.getEntity().getKiller(); + Entity mob = event.getEntity(); + + if (mob == null || mob instanceof Player) { + return; + } + + if (killer == null) { + return; + } + + Player player = event.getEntity().getKiller(); + + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(player.getUniqueId()); + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); + + for (Quest quest : super.getRegisteredQuests()) { + if (questProgressFile.hasStartedQuest(quest)) { + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); + + for (Task task : quest.getTasksOfType(super.getType())) { + TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); + + if (taskProgress.isCompleted()) { + continue; + } + + String configEntity = (String) task.getConfigValue("mob"); + String configName = (String) task.getConfigValue("name"); + + EntityType entity; + try { + entity = EntityType.valueOf(configEntity); + } catch (IllegalArgumentException ex) { + continue; + } + + if (configName != null) { + configName = ChatColor.translateAlternateColorCodes('&', configName); + if (mob.getCustomName() != null && !mob.getCustomName().equals(configName)) { + return; + } + } + + if (mob.getType() != entity) { + continue; + } + + int mobKillsNeeded = (int) task.getConfigValue("amount"); + + int progressKills; + if (taskProgress.getProgress() == null) { + progressKills = 0; + } else { + progressKills = (int) taskProgress.getProgress(); + } + + taskProgress.setProgress(progressKills + 1); + + if (((int) taskProgress.getProgress()) >= mobKillsNeeded) { + taskProgress.setCompleted(true); + } + } + } + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MobkillingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MobkillingTaskType.java new file mode 100644 index 00000000..d9a00f4a --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MobkillingTaskType.java @@ -0,0 +1,101 @@ +package com.leonardobishop.quests.quests.tasktypes.types; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.ConfigValue; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import org.bukkit.entity.Animals; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Monster; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDeathEvent; + +import java.util.ArrayList; +import java.util.List; + +public final class MobkillingTaskType extends TaskType { + + private List<ConfigValue> creatorConfigValues = new ArrayList<>(); + + public MobkillingTaskType() { + super("mobkilling", "fatpigsarefat", "Kill a set amount of entities."); + this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of mobs to be killed.")); + this.creatorConfigValues.add(new ConfigValue("hostile", false, "Only allow hostile or non-hostile mobs (unspecified = any type allowed).")); + } + + @Override + public List<ConfigValue> getCreatorConfigValues() { + return creatorConfigValues; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onMobKill(EntityDeathEvent event) { + Entity killer = event.getEntity().getKiller(); + Entity mob = event.getEntity(); + + if (mob instanceof Player) { + return; + } + + if (killer == null) { + return; + } + + Player player = event.getEntity().getKiller(); + + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(player.getUniqueId()); + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); + + for (Quest quest : super.getRegisteredQuests()) { + if (questProgressFile.hasStartedQuest(quest)) { + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); + + for (Task task : quest.getTasksOfType(super.getType())) { + TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); + + if (taskProgress.isCompleted()) { + continue; + } + + boolean hostilitySpecified = false; + boolean hostile = false; + if (task.getConfigValue("hostile") != null) { + hostilitySpecified = true; + hostile = (boolean) task.getConfigValue("hostile"); + } + + if (hostilitySpecified) { + if (!hostile && !(mob instanceof Animals)) { + continue; + } else if (hostile && !(mob instanceof Monster)) { + continue; + } + } + + int mobKillsNeeded = (int) task.getConfigValue("amount"); + + int progressKills; + if (taskProgress.getProgress() == null) { + progressKills = 0; + } else { + progressKills = (int) taskProgress.getProgress(); + } + + taskProgress.setProgress(progressKills + 1); + + if (((int) taskProgress.getProgress()) >= mobKillsNeeded) { + taskProgress.setCompleted(true); + } + } + } + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PlayerkillingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PlayerkillingTaskType.java new file mode 100644 index 00000000..f373108a --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PlayerkillingTaskType.java @@ -0,0 +1,84 @@ +package com.leonardobishop.quests.quests.tasktypes.types; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.ConfigValue; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDeathEvent; + +import java.util.ArrayList; +import java.util.List; + +public final class PlayerkillingTaskType extends TaskType { + + private List<ConfigValue> creatorConfigValues = new ArrayList<>(); + + public PlayerkillingTaskType() { + super("playerkilling", "fatpigsarefat", "Kill a set amount of players."); + this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of mobs to be killed.")); + this.creatorConfigValues.add(new ConfigValue("hostile", false, "Only allow hostile or non-hostile mobs (unspecified = any type allowed).")); + } + + @Override + public List<ConfigValue> getCreatorConfigValues() { + return creatorConfigValues; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onMobKill(EntityDeathEvent event) { + Entity killer = event.getEntity().getKiller(); + Entity mob = event.getEntity(); + + if (!(mob instanceof Player)) { + return; + } + + if (killer == null) { + return; + } + + Player player = event.getEntity().getKiller(); + + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(player.getUniqueId()); + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); + + for (Quest quest : super.getRegisteredQuests()) { + if (questProgressFile.hasStartedQuest(quest)) { + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); + + for (Task task : quest.getTasksOfType(super.getType())) { + TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); + + if (taskProgress.isCompleted()) { + continue; + } + + int playerKillsNeeded = (int) task.getConfigValue("amount"); + + int progressKills; + if (taskProgress.getProgress() == null) { + progressKills = 0; + } else { + progressKills = (int) taskProgress.getProgress(); + } + + taskProgress.setProgress(progressKills + 1); + + if (((int) taskProgress.getProgress()) >= playerKillsNeeded) { + taskProgress.setCompleted(true); + } + } + } + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PlaytimeTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PlaytimeTaskType.java new file mode 100644 index 00000000..e2e3117c --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PlaytimeTaskType.java @@ -0,0 +1,54 @@ +package com.leonardobishop.quests.quests.tasktypes.types; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +public final class PlaytimeTaskType extends TaskType { + + public PlaytimeTaskType() { + super("playtime", "Reinatix", "Track the amount of playing time a user has been on"); + playTime(); + } + + public void playTime() { + new BukkitRunnable() { + @Override + public void run() { + for (Player player : Bukkit.getOnlinePlayers()) { + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(player.getUniqueId()); + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); + for (Quest quest : PlaytimeTaskType.super.getRegisteredQuests()) { + if (questProgressFile.hasStartedQuest(quest)) { + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); + for (Task task : quest.getTasksOfType(PlaytimeTaskType.super.getType())) { + TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); + if (taskProgress.isCompleted()) { + continue; + } + int minutes = (int) task.getConfigValue("minutes"); + if (taskProgress.getProgress() == null) { + taskProgress.setProgress(1); + } else { + taskProgress.setProgress((int) taskProgress.getProgress() + 1); + } + if (((int) taskProgress.getProgress()) >= minutes) { + taskProgress.setCompleted(true); + } + } + } + } + } + } + }.runTaskTimer(Quests.getInstance(), 1200L, 1200L); + } + +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PositionTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PositionTaskType.java new file mode 100644 index 00000000..f812d927 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PositionTaskType.java @@ -0,0 +1,87 @@ +package com.leonardobishop.quests.quests.tasktypes.types; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.ConfigValue; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerMoveEvent; + +import java.util.ArrayList; +import java.util.List; + +public final class PositionTaskType extends TaskType { + + private List<ConfigValue> creatorConfigValues = new ArrayList<>(); + + public PositionTaskType() { + super("position", "fatpigsarefat", "Reach a set of co-ordinates."); + this.creatorConfigValues.add(new ConfigValue("x", true, "X position.")); + this.creatorConfigValues.add(new ConfigValue("y", true, "Y position.")); + this.creatorConfigValues.add(new ConfigValue("z", true, "Z position.")); + this.creatorConfigValues.add(new ConfigValue("world", true, "Name of world.")); + this.creatorConfigValues.add(new ConfigValue("distance-padding", false, "Padding zone in meters/blocks (default/unspecified = 0).")); + } + + @Override + public List<ConfigValue> getCreatorConfigValues() { + return creatorConfigValues; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onMove(PlayerMoveEvent event) { + if (event.getFrom().getBlockX() == event.getTo().getBlockX() && event.getFrom().getBlockZ() == event.getTo().getBlockZ()) { + return; + } + + Player player = event.getPlayer(); + + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(player.getUniqueId()); + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); + + for (Quest quest : super.getRegisteredQuests()) { + if (questProgressFile.hasStartedQuest(quest)) { + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); + + for (Task task : quest.getTasksOfType(super.getType())) { + TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); + + if (taskProgress.isCompleted()) { + continue; + } + + int x = (int) task.getConfigValue("x"); + int y = (int) task.getConfigValue("y"); + int z = (int) task.getConfigValue("z"); + String worldString = (String) task.getConfigValue("world"); + int padding = 0; + if (task.getConfigValue("distance-padding") != null) { + padding = (int) task.getConfigValue("distance-padding"); + } + World world = Bukkit.getWorld(worldString); + if (world == null) { + return; + } + + Location location = new Location(world, x, y, z); + if (player.getWorld().equals(world) && player.getLocation().getBlockX() == location.getBlockX() && player.getLocation().getBlockY() == location.getBlockY() && player.getLocation().getBlockZ() == location.getBlockZ()) { + taskProgress.setCompleted(true); + } else if (player.getWorld().equals(world) && player.getLocation().distance(location) < padding) { + taskProgress.setCompleted(true); + } + } + } + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/ShearingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/ShearingTaskType.java new file mode 100644 index 00000000..49c4864f --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/ShearingTaskType.java @@ -0,0 +1,76 @@ +package com.leonardobishop.quests.quests.tasktypes.types; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.ConfigValue; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import org.bukkit.entity.Player; +import org.bukkit.entity.Sheep; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerShearEntityEvent; + +import java.util.ArrayList; +import java.util.List; + +public final class ShearingTaskType extends TaskType { + + private List<ConfigValue> creatorConfigValues = new ArrayList<>(); + + public ShearingTaskType() { + super("shearing", "fatpigsarefat", "Shear a set amount of sheep."); + this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of cows to be milked.")); + } + + @Override + public List<ConfigValue> getCreatorConfigValues() { + return creatorConfigValues; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onShear(PlayerShearEntityEvent event) { + if (!(event.getEntity() instanceof Sheep)) { + return; + } + + Player player = event.getPlayer(); + + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(player.getUniqueId()); + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); + + for (Quest quest : super.getRegisteredQuests()) { + if (questProgressFile.hasStartedQuest(quest)) { + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); + + for (Task task : quest.getTasksOfType(super.getType())) { + TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); + + if (taskProgress.isCompleted()) { + continue; + } + + int sheepNeeded = (int) task.getConfigValue("amount"); + + int progressSheared; + if (taskProgress.getProgress() == null) { + progressSheared = 0; + } else { + progressSheared = (int) taskProgress.getProgress(); + } + + taskProgress.setProgress(progressSheared + 1); + + if (((int) taskProgress.getProgress()) >= sheepNeeded) { + taskProgress.setCompleted(true); + } + } + } + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/TamingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/TamingTaskType.java new file mode 100644 index 00000000..86365c38 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/TamingTaskType.java @@ -0,0 +1,75 @@ +package com.leonardobishop.quests.quests.tasktypes.types; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.ConfigValue; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityTameEvent; + +import java.util.ArrayList; +import java.util.List; + +public final class TamingTaskType extends TaskType { + + private List<ConfigValue> creatorConfigValues = new ArrayList<>(); + + public TamingTaskType() { + super("taming", "fatpigsarefat", "Tame a set amount of animals."); + this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of animals to be tamed.")); + } + + @Override + public List<ConfigValue> getCreatorConfigValues() { + return creatorConfigValues; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onTame(EntityTameEvent event) { + if (!(event.getOwner() instanceof Player)) { + return; + } + + Player player = (Player) event.getOwner(); + + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(player.getUniqueId()); + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); + + for (Quest quest : super.getRegisteredQuests()) { + if (questProgressFile.hasStartedQuest(quest)) { + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); + + for (Task task : quest.getTasksOfType(super.getType())) { + TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); + + if (taskProgress.isCompleted()) { + continue; + } + + int tamesNeeded = (int) task.getConfigValue("amount"); + + int progressTamed; + if (taskProgress.getProgress() == null) { + progressTamed = 0; + } else { + progressTamed = (int) taskProgress.getProgress(); + } + + taskProgress.setProgress(progressTamed + 1); + + if (((int) taskProgress.getProgress()) >= tamesNeeded) { + taskProgress.setCompleted(true); + } + } + } + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/WalkingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/WalkingTaskType.java new file mode 100644 index 00000000..83a89c78 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/WalkingTaskType.java @@ -0,0 +1,75 @@ +package com.leonardobishop.quests.quests.tasktypes.types; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.ConfigValue; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerMoveEvent; + +import java.util.ArrayList; +import java.util.List; + +public final class WalkingTaskType extends TaskType { + + private List<ConfigValue> creatorConfigValues = new ArrayList<>(); + + public WalkingTaskType() { + super("walking", "fatpigsarefat", "Walk a set distance."); + this.creatorConfigValues.add(new ConfigValue("distance", true, "Amount of meters (blocks) to be travelled.")); + } + + @Override + public List<ConfigValue> getCreatorConfigValues() { + return creatorConfigValues; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onMove(PlayerMoveEvent event) { + if (event.getFrom().getBlockX() == event.getTo().getBlockX() && event.getFrom().getBlockZ() == event.getTo().getBlockZ()) { + return; + } + + Player player = event.getPlayer(); + + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(player.getUniqueId()); + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); + + for (Quest quest : super.getRegisteredQuests()) { + if (questProgressFile.hasStartedQuest(quest)) { + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); + + for (Task task : quest.getTasksOfType(super.getType())) { + TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); + + if (taskProgress.isCompleted()) { + continue; + } + + int distanceNeeded = (int) task.getConfigValue("distance"); + + int progressDistance; + if (taskProgress.getProgress() == null) { + progressDistance = 0; + } else { + progressDistance = (int) taskProgress.getProgress(); + } + + taskProgress.setProgress(progressDistance + 1); + + if (((int) taskProgress.getProgress()) >= distanceNeeded) { + taskProgress.setCompleted(true); + } + } + } + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/uSkyBlockLevelType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/uSkyBlockLevelType.java new file mode 100644 index 00000000..baa666a3 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/uSkyBlockLevelType.java @@ -0,0 +1,65 @@ +package com.leonardobishop.quests.quests.tasktypes.types; + +import com.leonardobishop.quests.Quests; +import com.leonardobishop.quests.player.QPlayer; +import com.leonardobishop.quests.player.questprogressfile.QuestProgress; +import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile; +import com.leonardobishop.quests.player.questprogressfile.TaskProgress; +import com.leonardobishop.quests.quests.Quest; +import com.leonardobishop.quests.quests.Task; +import com.leonardobishop.quests.quests.tasktypes.ConfigValue; +import com.leonardobishop.quests.quests.tasktypes.TaskType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import us.talabrek.ultimateskyblock.api.event.uSkyBlockScoreChangedEvent; + +import java.util.ArrayList; +import java.util.List; + +public final class uSkyBlockLevelType extends TaskType { + + private List<ConfigValue> creatorConfigValues = new ArrayList<>(); + + public uSkyBlockLevelType() { + super("uskyblock_level", "fatpigsarefat", "Reach a certain island level for uSkyBlock."); + this.creatorConfigValues.add(new ConfigValue("level", true, "Minimum island level needed.")); + } + + @Override + public List<ConfigValue> getCreatorConfigValues() { + return creatorConfigValues; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onIslandLevel(uSkyBlockScoreChangedEvent event) { + QPlayer qPlayer = Quests.getPlayerManager().getPlayer(event.getPlayer().getUniqueId()); + if (qPlayer == null) { + return; + } + + QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); + + for (Quest quest : super.getRegisteredQuests()) { + if (questProgressFile.hasStartedQuest(quest)) { + QuestProgress questProgress = questProgressFile.getQuestProgress(quest); + + for (Task task : quest.getTasksOfType(super.getType())) { + TaskProgress taskProgress = questProgress.getTaskProgress(task.getId()); + + if (taskProgress.isCompleted()) { + continue; + } + + double islandLevelNeeded = (double) (int) task.getConfigValue("level"); + + taskProgress.setProgress(event.getScore().getScore()); + + if (((double) taskProgress.getProgress()) >= islandLevelNeeded) { + taskProgress.setCompleted(true); + } + } + } + } + } + +} diff --git a/src/main/java/com/leonardobishop/quests/title/Title.java b/src/main/java/com/leonardobishop/quests/title/Title.java new file mode 100644 index 00000000..e2178735 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/title/Title.java @@ -0,0 +1,8 @@ +package com.leonardobishop.quests.title; + +import org.bukkit.entity.Player; + +public interface Title { + + public void sendTitle(Player player, String message, String submessage); +}
\ No newline at end of file diff --git a/src/main/java/com/leonardobishop/quests/title/Title_Bukkit.java b/src/main/java/com/leonardobishop/quests/title/Title_Bukkit.java new file mode 100644 index 00000000..d88de717 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/title/Title_Bukkit.java @@ -0,0 +1,11 @@ +package com.leonardobishop.quests.title; + +import org.bukkit.entity.Player; + +public class Title_Bukkit implements Title { + + @Override + public void sendTitle(Player player, String message, String submessage) { + player.sendTitle(message, submessage, 10, 100, 10); + } +} diff --git a/src/main/java/com/leonardobishop/quests/title/Title_BukkitNoTimings.java b/src/main/java/com/leonardobishop/quests/title/Title_BukkitNoTimings.java new file mode 100644 index 00000000..6bbbc32f --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/title/Title_BukkitNoTimings.java @@ -0,0 +1,13 @@ +package com.leonardobishop.quests.title; + +import org.bukkit.entity.Player; + +public class Title_BukkitNoTimings implements Title { + + // this one is for 1.8, 1.9 and 1.10 where there was no timings method + @Override + public void sendTitle(Player player, String message, String submessage) { + player.sendTitle(message, submessage); + } + +} diff --git a/src/main/java/com/leonardobishop/quests/title/Title_Other.java b/src/main/java/com/leonardobishop/quests/title/Title_Other.java new file mode 100644 index 00000000..96d9914e --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/title/Title_Other.java @@ -0,0 +1,19 @@ +package com.leonardobishop.quests.title; + +import org.bukkit.entity.Player; + +public class Title_Other implements Title { + + @Override + public void sendTitle(Player player, String message, String submessage) { + /* + I'm too lazy to do a null check each time I want to send a title, so here. + Anyway, hello there programmer! I see you're rummaging through my source code. + Try not to leave a mess please. If you see anything dodgy or looks like it + could do with a little improvement make a pull request. + Also join my discord: https://discord.gg/8amrJnX + Have a great day! + - fatpigsarefat + */ + } +} diff --git a/src/main/java/com/leonardobishop/quests/title/Title_v1_10_R1.java b/src/main/java/com/leonardobishop/quests/title/Title_v1_10_R1.java new file mode 100644 index 00000000..0343ccbd --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/title/Title_v1_10_R1.java @@ -0,0 +1,22 @@ +//package me.fatpigsarefat.quests.title; +// +//import net.minecraft.server.v1_10_R1.IChatBaseComponent.ChatSerializer; +//import net.minecraft.server.v1_10_R1.PacketPlayOutTitle; +//import net.minecraft.server.v1_10_R1.PacketPlayOutTitle.EnumTitleAction; +//import org.bukkit.craftbukkit.v1_10_R1.entity.CraftPlayer; +//import org.bukkit.entity.Player; +// +//public class Title_v1_10_R1 implements Title { +// +// @Override +// public void sendTitle(Player player, String message, String submessage) { +// message = "{\"text\":\"" + message + "\"}"; +// PacketPlayOutTitle title = new PacketPlayOutTitle(EnumTitleAction.TITLE, ChatSerializer.a(message), 10, 100, +// 10); +// ((CraftPlayer) player).getHandle().playerConnection.sendPacket(title); +// submessage = "{\"text\":\"" + submessage + "\"}"; +// PacketPlayOutTitle subtitle = new PacketPlayOutTitle(EnumTitleAction.SUBTITLE, ChatSerializer.a(submessage), 10, +// 100, 10); +// ((CraftPlayer) player).getHandle().playerConnection.sendPacket(subtitle); +// } +//} diff --git a/src/main/java/com/leonardobishop/quests/title/Title_v1_11_R1.java b/src/main/java/com/leonardobishop/quests/title/Title_v1_11_R1.java new file mode 100644 index 00000000..edb7e9e7 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/title/Title_v1_11_R1.java @@ -0,0 +1,22 @@ +//package me.fatpigsarefat.quests.title; +// +//import net.minecraft.server.v1_11_R1.IChatBaseComponent.ChatSerializer; +//import net.minecraft.server.v1_11_R1.PacketPlayOutTitle; +//import net.minecraft.server.v1_11_R1.PacketPlayOutTitle.EnumTitleAction; +//import org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer; +//import org.bukkit.entity.Player; +// +//public class Title_v1_11_R1 implements Title { +// +// @Override +// public void sendTitle(Player player, String message, String submessage) { +// message = "{\"text\":\"" + message + "\"}"; +// PacketPlayOutTitle title = new PacketPlayOutTitle(EnumTitleAction.TITLE, ChatSerializer.a(message), 10, 100, +// 10); +// ((CraftPlayer) player).getHandle().playerConnection.sendPacket(title); +// submessage = "{\"text\":\"" + submessage + "\"}"; +// PacketPlayOutTitle subtitle = new PacketPlayOutTitle(EnumTitleAction.SUBTITLE, ChatSerializer.a(submessage), 10, +// 100, 10); +// ((CraftPlayer) player).getHandle().playerConnection.sendPacket(subtitle); +// } +//} diff --git a/src/main/java/com/leonardobishop/quests/title/Title_v1_12_R1.java b/src/main/java/com/leonardobishop/quests/title/Title_v1_12_R1.java new file mode 100644 index 00000000..daebefa3 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/title/Title_v1_12_R1.java @@ -0,0 +1,22 @@ +//package me.fatpigsarefat.quests.title; +// +//import net.minecraft.server.v1_12_R1.IChatBaseComponent.ChatSerializer; +//import net.minecraft.server.v1_12_R1.PacketPlayOutTitle; +//import net.minecraft.server.v1_12_R1.PacketPlayOutTitle.EnumTitleAction; +//import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; +//import org.bukkit.entity.Player; +// +//public class Title_v1_12_R1 implements Title { +// +// @Override +// public void sendTitle(Player player, String message, String submessage) { +// message = "{\"text\":\"" + message + "\"}"; +// PacketPlayOutTitle title = new PacketPlayOutTitle(EnumTitleAction.TITLE, ChatSerializer.a(message), 10, 100, +// 10); +// ((CraftPlayer) player).getHandle().playerConnection.sendPacket(title); +// submessage = "{\"text\":\"" + submessage + "\"}"; +// PacketPlayOutTitle subtitle = new PacketPlayOutTitle(EnumTitleAction.SUBTITLE, ChatSerializer.a(submessage), 10, +// 100, 10); +// ((CraftPlayer) player).getHandle().playerConnection.sendPacket(subtitle); +// } +//} diff --git a/src/main/java/com/leonardobishop/quests/title/Title_v1_8_R1.java b/src/main/java/com/leonardobishop/quests/title/Title_v1_8_R1.java new file mode 100644 index 00000000..4de97c98 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/title/Title_v1_8_R1.java @@ -0,0 +1,23 @@ +//package me.fatpigsarefat.quests.title; +// +//import net.minecraft.server.v1_8_R1.ChatSerializer; +//import net.minecraft.server.v1_8_R1.EnumTitleAction; +//import net.minecraft.server.v1_8_R1.PacketPlayOutTitle; +//import org.bukkit.craftbukkit.v1_8_R1.entity.CraftPlayer; +//import org.bukkit.entity.Player; +// +//public class Title_v1_8_R1 implements Title { +// +// @Override +// public void sendTitle(Player player, String message, String submessage) { +// message = "{\"text\":\"" + message + "\"}"; +// PacketPlayOutTitle title = new PacketPlayOutTitle(EnumTitleAction.TITLE, ChatSerializer.a(message), 10, 100, +// 10); +// ((CraftPlayer) player).getHandle().playerConnection.sendPacket(title); +// submessage = "{\"text\":\"" + submessage + "\"}"; +// PacketPlayOutTitle subtitle = new PacketPlayOutTitle(EnumTitleAction.SUBTITLE, ChatSerializer.a(submessage), 10, +// 100, 10); +// ((CraftPlayer) player).getHandle().playerConnection.sendPacket(subtitle); +// } +// +//}
\ No newline at end of file diff --git a/src/main/java/com/leonardobishop/quests/title/Title_v1_8_R2.java b/src/main/java/com/leonardobishop/quests/title/Title_v1_8_R2.java new file mode 100644 index 00000000..acda3c70 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/title/Title_v1_8_R2.java @@ -0,0 +1,22 @@ +//package me.fatpigsarefat.quests.title; +// +//import net.minecraft.server.v1_8_R2.IChatBaseComponent.ChatSerializer; +//import net.minecraft.server.v1_8_R2.PacketPlayOutTitle; +//import net.minecraft.server.v1_8_R2.PacketPlayOutTitle.EnumTitleAction; +//import org.bukkit.craftbukkit.v1_8_R2.entity.CraftPlayer; +//import org.bukkit.entity.Player; +// +//public class Title_v1_8_R2 implements Title { +// +// @Override +// public void sendTitle(Player player, String message, String submessage) { +// message = "{\"text\":\"" + message + "\"}"; +// PacketPlayOutTitle title = new PacketPlayOutTitle(EnumTitleAction.TITLE, ChatSerializer.a(message), 10, 100, +// 10); +// ((CraftPlayer) player).getHandle().playerConnection.sendPacket(title); +// submessage = "{\"text\":\"" + submessage + "\"}"; +// PacketPlayOutTitle subtitle = new PacketPlayOutTitle(EnumTitleAction.SUBTITLE, ChatSerializer.a(submessage), 10, +// 100, 10); +// ((CraftPlayer) player).getHandle().playerConnection.sendPacket(subtitle); +// } +//}
\ No newline at end of file diff --git a/src/main/java/com/leonardobishop/quests/title/Title_v1_8_R3.java b/src/main/java/com/leonardobishop/quests/title/Title_v1_8_R3.java new file mode 100644 index 00000000..0bc56b5f --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/title/Title_v1_8_R3.java @@ -0,0 +1,22 @@ +//package me.fatpigsarefat.quests.title; +// +//import net.minecraft.server.v1_8_R3.IChatBaseComponent.ChatSerializer; +//import net.minecraft.server.v1_8_R3.PacketPlayOutTitle; +//import net.minecraft.server.v1_8_R3.PacketPlayOutTitle.EnumTitleAction; +//import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; +//import org.bukkit.entity.Player; +// +//public class Title_v1_8_R3 implements Title { +// +// @Override +// public void sendTitle(Player player, String message, String submessage) { +// message = "{\"text\":\"" + message + "\"}"; +// PacketPlayOutTitle title = new PacketPlayOutTitle(EnumTitleAction.TITLE, ChatSerializer.a(message), 10, 100, +// 10); +// ((CraftPlayer) player).getHandle().playerConnection.sendPacket(title); +// submessage = "{\"text\":\"" + submessage + "\"}"; +// PacketPlayOutTitle subtitle = new PacketPlayOutTitle(EnumTitleAction.SUBTITLE, ChatSerializer.a(submessage), 10, +// 100, 10); +// ((CraftPlayer) player).getHandle().playerConnection.sendPacket(subtitle); +// } +//} diff --git a/src/main/java/com/leonardobishop/quests/title/Title_v1_9_R1.java b/src/main/java/com/leonardobishop/quests/title/Title_v1_9_R1.java new file mode 100644 index 00000000..80e25392 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/title/Title_v1_9_R1.java @@ -0,0 +1,22 @@ +//package me.fatpigsarefat.quests.title; +// +//import net.minecraft.server.v1_9_R1.IChatBaseComponent.ChatSerializer; +//import net.minecraft.server.v1_9_R1.PacketPlayOutTitle; +//import net.minecraft.server.v1_9_R1.PacketPlayOutTitle.EnumTitleAction; +//import org.bukkit.craftbukkit.v1_9_R1.entity.CraftPlayer; +//import org.bukkit.entity.Player; +// +//public class Title_v1_9_R1 implements Title { +// +// @Override +// public void sendTitle(Player player, String message, String submessage) { +// message = "{\"text\":\"" + message + "\"}"; +// PacketPlayOutTitle title = new PacketPlayOutTitle(EnumTitleAction.TITLE, ChatSerializer.a(message), 10, 100, +// 10); +// ((CraftPlayer) player).getHandle().playerConnection.sendPacket(title); +// submessage = "{\"text\":\"" + submessage + "\"}"; +// PacketPlayOutTitle subtitle = new PacketPlayOutTitle(EnumTitleAction.SUBTITLE, ChatSerializer.a(submessage), 10, +// 100, 10); +// ((CraftPlayer) player).getHandle().playerConnection.sendPacket(subtitle); +// } +//} diff --git a/src/main/java/com/leonardobishop/quests/title/Title_v1_9_R2.java b/src/main/java/com/leonardobishop/quests/title/Title_v1_9_R2.java new file mode 100644 index 00000000..29b52bbd --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/title/Title_v1_9_R2.java @@ -0,0 +1,22 @@ +//package me.fatpigsarefat.quests.title; +// +//import net.minecraft.server.v1_9_R2.IChatBaseComponent.ChatSerializer; +//import net.minecraft.server.v1_9_R2.PacketPlayOutTitle; +//import net.minecraft.server.v1_9_R2.PacketPlayOutTitle.EnumTitleAction; +//import org.bukkit.craftbukkit.v1_9_R2.entity.CraftPlayer; +//import org.bukkit.entity.Player; +// +//public class Title_v1_9_R2 implements Title { +// +// @Override +// public void sendTitle(Player player, String message, String submessage) { +// message = "{\"text\":\"" + message + "\"}"; +// PacketPlayOutTitle title = new PacketPlayOutTitle(EnumTitleAction.TITLE, ChatSerializer.a(message), 10, 100, +// 10); +// ((CraftPlayer) player).getHandle().playerConnection.sendPacket(title); +// submessage = "{\"text\":\"" + submessage + "\"}"; +// PacketPlayOutTitle subtitle = new PacketPlayOutTitle(EnumTitleAction.SUBTITLE, ChatSerializer.a(submessage), 10, +// 100, 10); +// ((CraftPlayer) player).getHandle().playerConnection.sendPacket(subtitle); +// } +//} diff --git a/src/main/java/com/leonardobishop/quests/updater/Updater.java b/src/main/java/com/leonardobishop/quests/updater/Updater.java new file mode 100644 index 00000000..03eded7f --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/updater/Updater.java @@ -0,0 +1,65 @@ +package com.leonardobishop.quests.updater; + +import com.leonardobishop.quests.obj.Messages; +import org.bukkit.plugin.Plugin; + +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.concurrent.TimeUnit; +import java.util.logging.Level; + +public class Updater { + + private static final int PROJECT_ID = 23696; + private String installedVersion; + private String returnedVersion; + private URL api; + private Plugin plugin; + private boolean updateReady; + private long lastCheck; + + public Updater(Plugin plugin) { + this.plugin = plugin; + this.installedVersion = plugin.getDescription().getVersion(); + try { + this.api = new URL("https://api.spigotmc.org/legacy/update.php?resource=" + PROJECT_ID); + } catch (MalformedURLException ignored) { + // shit + fan + } + } + + public String getLink() { + return "https://www.spigotmc.org/resources/" + PROJECT_ID; + } + + public boolean check() { + if (lastCheck != 0 && TimeUnit.MINUTES.convert(System.currentTimeMillis() - lastCheck, TimeUnit.MILLISECONDS) < 10) { + return updateReady; + } + try { + lastCheck = System.currentTimeMillis(); + URLConnection con = api.openConnection(); + returnedVersion = new BufferedReader(new InputStreamReader(con.getInputStream())).readLine(); + if (!returnedVersion.equals(installedVersion)) { + plugin.getLogger().log(Level.INFO, "A new version " + returnedVersion + " was found on Spigot (your version: " + installedVersion + "). Please update me! <3 - Link: " + getLink()); + updateReady = true; + } + } catch (IOException e) { + plugin.getLogger().log(Level.WARNING, "Failed to check for updates. You can check manually at " + getLink()); + // probably offline + } + return false; + } + + public boolean isUpdateReady() { + return updateReady; + } + + public String getMessage() { + return Messages.QUEST_UPDATER.getMessage().replace("{newver}", returnedVersion).replace("{oldver}", installedVersion).replace("{link}", getLink()); + } +}
\ No newline at end of file |
