diff --git a/build.gradle b/build.gradle index af2a02a2..416596c8 100644 --- a/build.gradle +++ b/build.gradle @@ -64,6 +64,7 @@ dependencies { compileOnly('com.willfp:eco:6.38.3') compileOnly('com.github.Zrips:Jobs:4.17.2') compileOnly('com.github.LoneDev6:api-itemsadder:3.2.3c') + compileOnly('net.objecthunter:exp4j:0.4.8') implementation('net.kyori:adventure-api:4.11.0') implementation('net.kyori:adventure-platform-bukkit:4.1.2') implementation('net.kyori:adventure-text-minimessage:4.11.0') diff --git a/libs/oraxen(premium).txt b/libs/oraxen(premium).txt index 399f3be5..d1c9fc67 100644 --- a/libs/oraxen(premium).txt +++ b/libs/oraxen(premium).txt @@ -1 +1 @@ -https://www.spigotmc.org/resources/%E2%9C%85-10-%E2%98%84%EF%B8%8F-oraxen-add-items-blocks-armors-hats-food-furnitures-plants-and-gui.72448/ \ No newline at end of file +https://www.spigotmc.org/resources/%E2%9C%85-10-%E2%98%84%EF%B8%8F-oraxen-add-items-blocks-armors-hats-food-furnitures-plants-and-sellFishGui.72448/ \ No newline at end of file diff --git a/src/main/java/net/momirealms/customfishing/CustomFishing.java b/src/main/java/net/momirealms/customfishing/CustomFishing.java index accca61f..1be27992 100644 --- a/src/main/java/net/momirealms/customfishing/CustomFishing.java +++ b/src/main/java/net/momirealms/customfishing/CustomFishing.java @@ -20,7 +20,9 @@ package net.momirealms.customfishing; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolManager; import net.kyori.adventure.platform.bukkit.BukkitAudiences; +import net.momirealms.customfishing.commands.FishingBagCommand; import net.momirealms.customfishing.commands.PluginCommand; +import net.momirealms.customfishing.commands.SellFishCommand; import net.momirealms.customfishing.helper.LibraryLoader; import net.momirealms.customfishing.manager.*; import net.momirealms.customfishing.util.AdventureUtil; @@ -43,6 +45,7 @@ public final class CustomFishing extends JavaPlugin { private LayoutManager layoutManager; private DataManager dataManager; private TotemManager totemManager; + private SellManager sellManager; // _ooOoo_ // o8888888o @@ -71,6 +74,7 @@ public final class CustomFishing extends JavaPlugin { LibraryLoader.load("org.apache.commons","commons-pool2","2.11.1","https://repo.maven.apache.org/maven2/"); LibraryLoader.load("dev.dejvokep","boosted-yaml","1.3","https://repo.maven.apache.org/maven2/"); LibraryLoader.load("com.zaxxer","HikariCP","5.0.1","https://repo.maven.apache.org/maven2/"); + LibraryLoader.load("net.objecthunter","exp4j","0.4.8","https://repo.maven.apache.org/maven2/"); } @Override @@ -85,23 +89,43 @@ public final class CustomFishing extends JavaPlugin { this.layoutManager = new LayoutManager(); this.dataManager = new DataManager(); this.totemManager = new TotemManager(); + this.sellManager = new SellManager(); ConfigUtil.reload(); + registerCommands(); - PluginCommand pluginCommand = new PluginCommand(); - Bukkit.getPluginCommand("customfishing").setExecutor(pluginCommand); - Bukkit.getPluginCommand("customfishing").setTabCompleter(pluginCommand); AdventureUtil.consoleMessage("[CustomFishing] Plugin Enabled!"); new Metrics(this, 16648); } @Override public void onDisable() { + this.fishingManager.unload(); + this.integrationManager.unload(); + this.competitionManager.unload(); + this.bonusManager.unload(); + this.lootManager.unload(); + this.layoutManager.unload(); + this.dataManager.unload(); + this.totemManager.unload(); + this.sellManager.unload(); if (adventure != null) { adventure.close(); adventure = null; } } + private void registerCommands() { + PluginCommand pluginCommand = new PluginCommand(); + Bukkit.getPluginCommand("customfishing").setExecutor(pluginCommand); + Bukkit.getPluginCommand("customfishing").setTabCompleter(pluginCommand); + FishingBagCommand fishingBagCommand = new FishingBagCommand(); + Bukkit.getPluginCommand("fishingbag").setExecutor(fishingBagCommand); + Bukkit.getPluginCommand("fishingbag").setTabCompleter(fishingBagCommand); + SellFishCommand sellFishCommand = new SellFishCommand(); + Bukkit.getPluginCommand("sellfish").setExecutor(sellFishCommand); + Bukkit.getPluginCommand("sellfish").setTabCompleter(sellFishCommand); + } + public IntegrationManager getIntegrationManager() { return integrationManager; } @@ -133,4 +157,8 @@ public final class CustomFishing extends JavaPlugin { public TotemManager getTotemManager() { return totemManager; } + + public SellManager getSellManager() { + return sellManager; + } } diff --git a/src/main/java/net/momirealms/customfishing/commands/FishingBagCommand.java b/src/main/java/net/momirealms/customfishing/commands/FishingBagCommand.java new file mode 100644 index 00000000..9ba8a9e1 --- /dev/null +++ b/src/main/java/net/momirealms/customfishing/commands/FishingBagCommand.java @@ -0,0 +1,66 @@ +package net.momirealms.customfishing.commands; + +import net.momirealms.customfishing.commands.subcmd.OpenCommand; +import net.momirealms.customfishing.manager.MessageManager; +import net.momirealms.customfishing.util.AdventureUtil; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabExecutor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +public class FishingBagCommand implements TabExecutor { + + private final Map subCommandMap; + + public FishingBagCommand() { + subCommandMap = new ConcurrentHashMap<>(); + regDefaultSubCommands(); + } + + private void regDefaultSubCommands() { + regSubCommand(OpenCommand.INSTANCE); + } + + public void regSubCommand(SubCommand executor) { + subCommandMap.put(executor.getSubCommand(), executor); + } + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + List argList = Arrays.asList(args); + if (argList.size() < 1) { + AdventureUtil.sendMessage(sender, MessageManager.prefix + MessageManager.nonArgs); + return true; + } + SubCommand subCommand = subCommandMap.get(argList.get(0)); + if (subCommand != null) + return subCommand.onCommand(sender, argList.subList(1, argList.size())); + else { + AdventureUtil.sendMessage(sender, MessageManager.prefix + MessageManager.unavailableArgs); + return true; + } + } + + @Override + public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { + List argList = Arrays.asList(args); + if (argList.size() <= 1) { + List returnList = new ArrayList<>(subCommandMap.keySet()); + returnList.removeIf(str -> !str.startsWith(args[0])); + return returnList; + } + SubCommand subCommand = subCommandMap.get(argList.get(0)); + if (subCommand != null) + return subCommand.onTabComplete(sender, argList.subList(1, argList.size())); + else + return Collections.singletonList(""); + } + + public Map getSubCommandMap() { + return subCommandMap; + } +} diff --git a/src/main/java/net/momirealms/customfishing/commands/SellFishCommand.java b/src/main/java/net/momirealms/customfishing/commands/SellFishCommand.java new file mode 100644 index 00000000..e589e5c7 --- /dev/null +++ b/src/main/java/net/momirealms/customfishing/commands/SellFishCommand.java @@ -0,0 +1,31 @@ +package net.momirealms.customfishing.commands; + +import net.momirealms.customfishing.CustomFishing; +import net.momirealms.customfishing.manager.MessageManager; +import net.momirealms.customfishing.util.AdventureUtil; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabExecutor; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class SellFishCommand implements TabExecutor { + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + if (!(sender instanceof Player player)) { + AdventureUtil.sendMessage(sender, MessageManager.prefix + MessageManager.noConsole); + return true; + } + CustomFishing.plugin.getSellManager().openGuiForPlayer(player); + return true; + } + + @Override + public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { + return null; + } +} diff --git a/src/main/java/net/momirealms/customfishing/commands/subcmd/OpenCommand.java b/src/main/java/net/momirealms/customfishing/commands/subcmd/OpenCommand.java new file mode 100644 index 00000000..e468b1f4 --- /dev/null +++ b/src/main/java/net/momirealms/customfishing/commands/subcmd/OpenCommand.java @@ -0,0 +1,24 @@ +package net.momirealms.customfishing.commands.subcmd; + +import net.momirealms.customfishing.commands.AbstractSubCommand; +import net.momirealms.customfishing.commands.SubCommand; +import org.bukkit.command.CommandSender; + +import java.util.List; + +public class OpenCommand extends AbstractSubCommand { + + public static final SubCommand INSTANCE = new OpenCommand(); + + private OpenCommand() { + super("open", null); + } + + @Override + public boolean onCommand(CommandSender sender, List args) { + if (args.size() < 1) { + + } + return true; + } +} diff --git a/src/main/java/net/momirealms/customfishing/data/PlayerData.java b/src/main/java/net/momirealms/customfishing/data/PlayerData.java new file mode 100644 index 00000000..4527044e --- /dev/null +++ b/src/main/java/net/momirealms/customfishing/data/PlayerData.java @@ -0,0 +1,4 @@ +package net.momirealms.customfishing.data; + +public class PlayerData { +} diff --git a/src/main/java/net/momirealms/customfishing/integration/VaultHook.java b/src/main/java/net/momirealms/customfishing/integration/VaultHook.java new file mode 100644 index 00000000..70564b41 --- /dev/null +++ b/src/main/java/net/momirealms/customfishing/integration/VaultHook.java @@ -0,0 +1,19 @@ +package net.momirealms.customfishing.integration; + +import net.milkbowl.vault.economy.Economy; +import net.momirealms.customfishing.CustomFishing; +import org.bukkit.plugin.RegisteredServiceProvider; + +public class VaultHook { + + public static Economy economy; + + public static boolean initialize() { + RegisteredServiceProvider rsp = CustomFishing.plugin.getServer().getServicesManager().getRegistration(Economy.class); + if (rsp == null) { + return false; + } + economy = rsp.getProvider(); + return true; + } +} diff --git a/src/main/java/net/momirealms/customfishing/manager/BonusManager.java b/src/main/java/net/momirealms/customfishing/manager/BonusManager.java index c4eed82d..a1073f79 100644 --- a/src/main/java/net/momirealms/customfishing/manager/BonusManager.java +++ b/src/main/java/net/momirealms/customfishing/manager/BonusManager.java @@ -10,6 +10,7 @@ import net.momirealms.customfishing.util.ConfigUtil; import net.momirealms.customfishing.util.ItemStackUtil; import org.bukkit.Material; import org.bukkit.NamespacedKey; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; @@ -184,7 +185,7 @@ public class BonusManager extends Function { AdventureUtil.consoleMessage("[CustomFishing] Loaded " + RODITEMS.size() + " rods"); } - public static void setItemProperties(YamlConfiguration config, String key, Item item) { + public static void setItemProperties(ConfigurationSection config, String key, Item item) { item.setUnbreakable(config.getBoolean(key + ".unbreakable", false)); if (config.contains(key + ".display.lore")) item.setLore(config.getStringList(key + ".display.lore")); if (config.contains(key + ".display.name")) item.setName(config.getString(key + ".display.name")); diff --git a/src/main/java/net/momirealms/customfishing/manager/ConfigManager.java b/src/main/java/net/momirealms/customfishing/manager/ConfigManager.java index 6c80f206..c0bde9de 100644 --- a/src/main/java/net/momirealms/customfishing/manager/ConfigManager.java +++ b/src/main/java/net/momirealms/customfishing/manager/ConfigManager.java @@ -1,5 +1,7 @@ package net.momirealms.customfishing.manager; +import net.momirealms.customfishing.integration.VaultHook; +import net.momirealms.customfishing.util.AdventureUtil; import net.momirealms.customfishing.util.ConfigUtil; import net.momirealms.customfishing.util.JedisUtil; import org.bukkit.Bukkit; @@ -25,7 +27,6 @@ public class ConfigManager { public static boolean needRodForLoots; public static boolean needRodToFish; public static boolean rodLoseDurability; - public static int fishFinderCoolDown; public static boolean enableCompetition; public static boolean disableJobsXp; public static boolean convertMMOItems; @@ -47,6 +48,9 @@ public class ConfigManager { public static boolean useRedis; public static int lavaMaxTime; public static int lavaMinTime; + public static boolean addTagToFish; + public static boolean logEarning; + public static boolean vaultHook; public static void load() { ConfigUtil.update("config.yml"); @@ -79,13 +83,14 @@ public class ConfigManager { needRodForLoots = config.getBoolean("mechanics.need-special-rod.for-loots", false); needRodToFish = config.getBoolean("mechanics.need-special-rod.to-fish", false); rodLoseDurability = config.getBoolean("mechanics.rod-lose-durability", true); - fishFinderCoolDown = config.getInt("mechanics.fishfinder-cooldown", 3000); enableCompetition = config.getBoolean("mechanics.fishing-competition.enable", true); priority = config.getString("other-settings.event-priority", "NORMAL").toUpperCase(); disableJobsXp = config.getBoolean("other-settings.disable-JobsReborn-fishing-exp", false); preventPickUp = config.getBoolean("other-settings.prevent-other-players-pick-up-loot", false); convertMMOItems = config.getBoolean("other-settings.convert-MMOItems-rods", false); + logEarning = config.getBoolean("other-settings.log-earnings", true); + vaultHook = config.getBoolean("integration.Vault", true); successTitle = config.getStringList("titles.success.title").toArray(new String[0]); successSubTitle = config.getStringList("titles.success.subtitle").toArray(new String[0]); @@ -99,8 +104,10 @@ public class ConfigManager { failureFadeStay = config.getInt("titles.failure.fade.stay", 30) * 50; failureFadeOut = config.getInt("titles.failure.fade.out", 10) * 50; - lavaMinTime = config.getInt("mechanics.lava-fishing.min-time", 100); - lavaMaxTime = config.getInt("mechanics.lava-fishing.max-time", 600) - lavaMinTime; + lavaMinTime = config.getInt("mechanics.lava-fishing.min-wait-time", 100); + lavaMaxTime = config.getInt("mechanics.lava-fishing.max-wait-time", 600) - lavaMinTime; + + addTagToFish = config.getBoolean("mechanics.fishing-bag.can-store-fish", false); useRedis = false; if (enableCompetition && config.getBoolean("mechanics.fishing-competition.redis", false)) { @@ -108,6 +115,13 @@ public class ConfigManager { JedisUtil.initializeRedis(configuration); useRedis = true; } + + if (vaultHook) { + if (!VaultHook.initialize()) { + vaultHook = false; + AdventureUtil.consoleMessage("[CustomFishing] Failed to hook into Vault!"); + } + } } public static List getWorldsList() { if (whiteOrBlack) { diff --git a/src/main/java/net/momirealms/customfishing/manager/FishingManager.java b/src/main/java/net/momirealms/customfishing/manager/FishingManager.java index ff95d50a..ce9afb65 100644 --- a/src/main/java/net/momirealms/customfishing/manager/FishingManager.java +++ b/src/main/java/net/momirealms/customfishing/manager/FishingManager.java @@ -18,7 +18,6 @@ import net.momirealms.customfishing.object.Function; import net.momirealms.customfishing.object.action.ActionInterface; import net.momirealms.customfishing.object.fishing.*; import net.momirealms.customfishing.object.loot.DroppedItem; -import net.momirealms.customfishing.object.fishing.BobberCheckTask; import net.momirealms.customfishing.object.loot.Loot; import net.momirealms.customfishing.object.loot.Mob; import net.momirealms.customfishing.object.requirements.RequirementInterface; @@ -395,6 +394,9 @@ public class FishingManager extends Function { Competition.currentCompetition.getBossBarManager().tryJoin(player); } + ItemStackUtil.addExtraMeta(drop, droppedItem); + if (ConfigManager.addTagToFish) ItemStackUtil.addIdentifier(drop, "loot", droppedItem.getKey()); + dropItem(player, location, fishResultEvent.isDouble(), drop); for (ActionInterface action : droppedItem.getSuccessActions()) action.doOn(player, null); @@ -753,7 +755,7 @@ public class FishingManager extends Function { } private void useFinder(Player player) { - if (isCoolDown(player, ConfigManager.fishFinderCoolDown)) return; + if (isCoolDown(player, 1000)) return; List possibleLoots = getPossibleWaterLootList(new FishingCondition(player.getLocation(), player), true); FishFinderEvent fishFinderEvent = new FishFinderEvent(player, possibleLoots); diff --git a/src/main/java/net/momirealms/customfishing/manager/LootManager.java b/src/main/java/net/momirealms/customfishing/manager/LootManager.java index de8ebaf8..640d6ccb 100644 --- a/src/main/java/net/momirealms/customfishing/manager/LootManager.java +++ b/src/main/java/net/momirealms/customfishing/manager/LootManager.java @@ -127,6 +127,18 @@ public class LootManager extends Function { if (config.contains(key + ".nick")) loot.setNick(config.getString(key + ".nick")); else loot.setNick(ChatColor.stripColor(config.getString(key + ".display.name", key))); loot.setRandomDurability(config.getBoolean(key + ".random-durability", false)); + if (config.contains(key + ".size")) { + String[] size = StringUtils.split(config.getString(key + ".size", "1~10"), "~"); + if (size.length != 2) { + AdventureUtil.consoleMessage("[CustomFishing] Wrong size found at " + key); + continue; + } + loot.setSize(size); + } + if (config.contains(key + ".price")) { + loot.setBasicPrice((float) config.getDouble(key + ".price.basic", 0)); + loot.setSizeBonus((float) config.getDouble(key + ".price.bonus", 0)); + } if (config.contains(key + ".random-enchantments")){ List randomEnchants = new ArrayList<>(); config.getConfigurationSection(key + ".random-enchantments").getValues(false).forEach((order, enchant) -> { diff --git a/src/main/java/net/momirealms/customfishing/manager/SellManager.java b/src/main/java/net/momirealms/customfishing/manager/SellManager.java index 8f742cae..3a61cc91 100644 --- a/src/main/java/net/momirealms/customfishing/manager/SellManager.java +++ b/src/main/java/net/momirealms/customfishing/manager/SellManager.java @@ -1,4 +1,304 @@ package net.momirealms.customfishing.manager; -public class SellManager { +import de.tr7zw.changeme.nbtapi.NBTCompound; +import de.tr7zw.changeme.nbtapi.NBTItem; +import net.kyori.adventure.key.Key; +import net.kyori.adventure.sound.Sound; +import net.momirealms.customfishing.CustomFishing; +import net.momirealms.customfishing.integration.VaultHook; +import net.momirealms.customfishing.object.Function; +import net.momirealms.customfishing.object.loot.Item; +import net.momirealms.customfishing.object.sell.ContainerPacketListener; +import net.momirealms.customfishing.object.sell.InventoryListener; +import net.momirealms.customfishing.util.AdventureUtil; +import net.momirealms.customfishing.util.ConfigUtil; +import net.momirealms.customfishing.util.ItemStackUtil; +import net.objecthunter.exp4j.Expression; +import net.objecthunter.exp4j.ExpressionBuilder; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.inventory.*; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.*; + +public class SellManager extends Function { + + private final ContainerPacketListener containerPacketListener; + private final InventoryListener inventoryListener; + public static String formula; + public static String title; + public static int guiSize; + public static String msgNotification; + public static String actionbarNotification; + public static String titleNotification; + public static String subtitleNotification; + public static int titleIn; + public static int titleStay; + public static int titleOut; + public static String[] commands; + public static Item sellIcon; + public static Item denyIcon; + public static Key closeKey; + public static Key openKey; + public static Key successKey; + public static Key denyKey; + public static Sound.Source soundSource; + public static HashMap guiItems; + public static HashSet functionIconSlots; + public static HashMap vanillaPrices = new HashMap<>(); + private final HashMap inventoryCache; + private final HashMap coolDown; + + public SellManager() { + this.containerPacketListener = new ContainerPacketListener(); + this.inventoryListener = new InventoryListener(this); + this.inventoryCache = new HashMap<>(); + this.coolDown = new HashMap<>(); + } + + @Override + public void load() { + loadConfig(); + CustomFishing.protocolManager.addPacketListener(containerPacketListener); + Bukkit.getPluginManager().registerEvents(inventoryListener, CustomFishing.plugin); + } + + @Override + public void unload() { + for (Player player : this.inventoryCache.keySet()) { + player.closeInventory(); + } + this.inventoryCache.clear(); + CustomFishing.protocolManager.removePacketListener(containerPacketListener); + HandlerList.unregisterAll(inventoryListener); + } + + private void loadConfig() { + functionIconSlots = new HashSet<>(); + guiItems = new HashMap<>(); + vanillaPrices = new HashMap<>(); + YamlConfiguration config = ConfigUtil.getConfig("sell-fish.yml"); + formula = config.getString("price-formula", "{base} + {bonus} * {size}"); + title = config.getString("container-title"); + guiSize = config.getInt("rows") * 9; + openKey = config.contains("sounds.open") ? Key.key(config.getString("sounds.open")) : null; + closeKey = config.contains("sounds.close") ? Key.key(config.getString("sounds.close")) : null; + successKey = config.contains("sounds.success") ? Key.key(config.getString("sounds.success")) : null; + denyKey = config.contains("sounds.deny") ? Key.key(config.getString("sounds.deny")) : null; + soundSource = Sound.Source.valueOf(config.getString("sounds.type","player").toUpperCase()); + if (config.contains("decorative-icons")){ + config.getConfigurationSection("decorative-icons").getKeys(false).forEach(key -> { + Item item = new Item(Material.valueOf(config.getString("decorative-icons." + key + ".material", "PAPER").toUpperCase())); + if (config.contains("decorative-icons." + key + ".display.name")) item.setName(config.getString("decorative-icons." + key + ".display.name")); + if (config.contains("decorative-icons." + key + ".display.lore")) item.setLore(config.getStringList("decorative-icons." + key + ".display.lore")); + if (config.contains("decorative-icons." + key + ".custom-model-data")) item.setCustomModelData(config.getInt("decorative-icons." + key + ".custom-model-data")); + ItemStack itemStack = ItemStackUtil.getFromItem(item); + for (int slot : config.getIntegerList("decorative-icons." + key + ".slot")) { + guiItems.put(slot - 1, itemStack); + } + }); + } + + sellIcon = new Item(Material.valueOf(config.getString("functional-icons.sell.material", "PAPER").toUpperCase())); + if (config.contains("functional-icons.sell.display.name")) sellIcon.setName(config.getString("functional-icons.sell.display.name")); + if (config.contains("functional-icons.sell.display.lore")) sellIcon.setLore(config.getStringList("functional-icons.sell.display.lore")); + if (config.contains("functional-icons.sell.custom-model-data")) sellIcon.setCustomModelData(config.getInt("functional-icons.sell.custom-model-data")); + denyIcon = new Item(Material.valueOf(config.getString("functional-icons.deny.material", "PAPER").toUpperCase())); + if (config.contains("functional-icons.deny.display.name")) denyIcon.setName(config.getString("functional-icons.deny.display.name")); + if (config.contains("functional-icons.deny.display.lore")) denyIcon.setLore(config.getStringList("functional-icons.deny.display.lore")); + if (config.contains("functional-icons.deny.custom-model-data")) denyIcon.setCustomModelData(config.getInt("functional-icons.deny.custom-model-data")); + + for (int slot : config.getIntegerList("functional-icons.slots")) { + guiItems.put(slot - 1, ItemStackUtil.getFromItem(sellIcon)); + functionIconSlots.add(slot - 1); + } + + if (config.getBoolean("actions.message.enable", false)) { + msgNotification = config.getString("actions.message.text"); + } else msgNotification = null; + if (config.getBoolean("actions.actionbar.enable", false)) { + actionbarNotification = config.getString("actions.actionbar.text"); + } else actionbarNotification = null; + if (config.getBoolean("actions.title.enable", false)) { + titleNotification = config.getString("actions.title.title"); + subtitleNotification = config.getString("actions.title.subtitle"); + titleIn = config.getInt("actions.title.in"); + titleStay = config.getInt("actions.title.stay"); + titleOut = config.getInt("actions.title.out"); + } else actionbarNotification = null; + if (config.getBoolean("actions.commands.enable")) { + commands = config.getStringList("actions.commands.value").toArray(new String[0]); + } else commands = null; + + ConfigurationSection configurationSection = config.getConfigurationSection("vanilla-item-price"); + if (configurationSection != null) { + for (String vanilla : configurationSection.getKeys(false)) { + vanillaPrices.put(Material.valueOf(vanilla.toUpperCase()), (float) configurationSection.getDouble(vanilla)); + } + } + } + + public void openGuiForPlayer(Player player) { + player.closeInventory(); + Inventory inventory = Bukkit.createInventory(player, guiSize, "{CustomFishing}"); + for (Map.Entry entry : guiItems.entrySet()) { + inventory.setItem(entry.getKey(), entry.getValue()); + } + inventoryCache.put(player, inventory); + player.openInventory(inventory); + if (openKey != null) AdventureUtil.playerSound(player, soundSource, openKey, 1, 1); + } + + public void onOpen(InventoryOpenEvent event) { + final Player player = (Player) event.getPlayer(); + Inventory inventory = inventoryCache.get(player); + if (inventory == null) return; + if (inventory == event.getInventory()) { + for (int slot : functionIconSlots) { + inventory.setItem(slot, ItemStackUtil.getFromItem(sellIcon.cloneWithPrice(getTotalPrice(getPlayerItems(inventory))))); + } + } + } + + public void onClick(InventoryClickEvent event) { + final Player player = (Player) event.getView().getPlayer(); + Inventory inventory = inventoryCache.get(player); + if (inventory == null) return; + boolean update = true; + if (inventory == event.getClickedInventory()) { + int clickedSlot = event.getSlot(); + if (guiItems.containsKey(clickedSlot)) { + event.setCancelled(true); + } + if (functionIconSlots.contains(clickedSlot)) { + List playerItems = getPlayerItems(inventory); + float totalPrice = getTotalPrice(playerItems); + if (totalPrice > 0) { + for (ItemStack playerItem : playerItems) { + if (playerItem == null || playerItem.getType() == Material.AIR) continue; + if (getSingleItemPrice(playerItem) == 0) continue; + playerItem.setAmount(0); + } + doActions(player, totalPrice); + inventory.close(); + } + else { + for (int slot : functionIconSlots) { + inventory.setItem(slot, ItemStackUtil.getFromItem(denyIcon)); + } + update = false; + if (denyKey != null) AdventureUtil.playerSound(player, soundSource, denyKey, 1, 1); + } + } + } + if (update && !isCoolDown(player, 1000)) { + Bukkit.getScheduler().runTaskLater(CustomFishing.plugin, () -> { + ItemStack icon = ItemStackUtil.getFromItem(sellIcon.cloneWithPrice(getTotalPrice(getPlayerItems(inventory)))); + for (int slot : functionIconSlots) { + inventory.setItem(slot, icon); + } + }, 1); + } + } + + public boolean isCoolDown(Player player, long delay) { + long time = System.currentTimeMillis(); + if (time - (coolDown.getOrDefault(player, time - delay)) < delay) return true; + coolDown.put(player, time); + return false; + } + + public void onClose(InventoryCloseEvent event) { + final Player player = (Player) event.getPlayer(); + Inventory inventory = inventoryCache.remove(player); + if (inventory == null) return; + coolDown.remove(player); + if (event.getInventory() == inventory) { + returnItems(getPlayerItems(event.getInventory()), player); + if (closeKey != null) AdventureUtil.playerSound(player, soundSource, closeKey, 1, 1); + } + } + + private List getPlayerItems(Inventory inventory) { + List items = new ArrayList<>(); + for (int i = 0; i < guiSize; i++) { + if (guiItems.containsKey(i)) continue; + items.add(inventory.getItem(i)); + } + return items; + } + + private void returnItems(List itemStacks, Player player){ + Inventory inventory = player.getInventory(); + for (ItemStack stack : itemStacks) { + if (stack == null || stack.getType() == Material.AIR) continue; + inventory.addItem(stack); + } + } + + private float getTotalPrice(List itemStacks){ + float totalPrice = 0; + for (ItemStack stack : itemStacks) { + if (stack == null || stack.getType() == Material.AIR) continue; + float price = getSingleItemPrice(stack); + price *= stack.getAmount(); + totalPrice += price; + } + return totalPrice; + } + + private float getSingleItemPrice(ItemStack itemStack) { + NBTItem nbtItem = new NBTItem(itemStack); + NBTCompound fishMeta = nbtItem.getCompound("FishMeta"); + float price = 0; + if (fishMeta != null) { + float base = fishMeta.getFloat("base"); + float bonus = fishMeta.getFloat("bonus"); + float size = fishMeta.getFloat("size"); + Expression expression = new ExpressionBuilder(formula) + .variables("base", "bonus","size") + .build() + .setVariable("base", base) + .setVariable("bonus", bonus) + .setVariable("size", size); + price = (float) expression.evaluate(); + } + if (price == 0) { + price = Optional.ofNullable(vanillaPrices.get(itemStack.getType())).orElse(0f); + } + return price; + } + + private void doActions(Player player, float earnings) { + if (titleNotification != null) AdventureUtil.playerTitle( + player, + titleNotification.replace("{money}", String.format("%.2f", earnings)), + subtitleNotification.replace("{money}", String.format("%.2f", earnings)), + titleIn * 50, + titleStay * 50, + titleOut * 50 + ); + if (msgNotification != null) { + AdventureUtil.playerMessage(player, msgNotification.replace("{money}", String.format("%.2f", earnings))); + } + if (actionbarNotification != null) { + AdventureUtil.playerActionbar(player, actionbarNotification.replace("{money}", String.format("%.2f", earnings))); + } + if (commands != null) { + for (String cmd : commands) { + Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), cmd.replace("{player}", player.getName()).replace("{money}", String.format("%.2f", earnings))); + } + } + if (ConfigManager.logEarning) { + AdventureUtil.consoleMessage("[CustomFishing] Log: " + player.getName() + " earns " + String.format("%.2f", earnings) + " from selling fish"); + } + if (successKey != null) AdventureUtil.playerSound(player, soundSource, successKey, 1, 1); + if (ConfigManager.vaultHook) VaultHook.economy.depositPlayer(player, earnings); + } } diff --git a/src/main/java/net/momirealms/customfishing/object/fishing/BobberCheckTask.java b/src/main/java/net/momirealms/customfishing/object/fishing/BobberCheckTask.java index df272716..ed1014fa 100644 --- a/src/main/java/net/momirealms/customfishing/object/fishing/BobberCheckTask.java +++ b/src/main/java/net/momirealms/customfishing/object/fishing/BobberCheckTask.java @@ -1,6 +1,5 @@ package net.momirealms.customfishing.object.fishing; -import com.plotsquared.core.plot.PlotId; import net.momirealms.customfishing.CustomFishing; import net.momirealms.customfishing.manager.ConfigManager; import net.momirealms.customfishing.manager.FishingManager; @@ -71,8 +70,10 @@ public class BobberCheckTask extends BukkitRunnable { return; } if (fishHook.isInWater()) { - List possibleLoots = fishingManager.getPossibleWaterLootList(new FishingCondition(fishHook.getLocation(), player), false); - fishingManager.getNextLoot(player, bonus, possibleLoots); + Bukkit.getScheduler().runTaskAsynchronously(CustomFishing.plugin, () -> { + List possibleLoots = fishingManager.getPossibleWaterLootList(new FishingCondition(fishHook.getLocation(), player), false); + fishingManager.getNextLoot(player, bonus, possibleLoots); + }); stop(); return; } @@ -106,8 +107,10 @@ public class BobberCheckTask extends BukkitRunnable { } private void randomTime() { - List possibleLoots = fishingManager.getPossibleLavaLootList(new FishingCondition(fishHook.getLocation(), player), false); - fishingManager.getNextLoot(player, bonus, possibleLoots); + Bukkit.getScheduler().runTaskAsynchronously(CustomFishing.plugin, () -> { + List possibleLoots = fishingManager.getPossibleLavaLootList(new FishingCondition(fishHook.getLocation(), player), false); + fishingManager.getNextLoot(player, bonus, possibleLoots); + }); cancelTask(); int random = new Random().nextInt(ConfigManager.lavaMaxTime) + ConfigManager.lavaMinTime; random -= lureLevel * 100; diff --git a/src/main/java/net/momirealms/customfishing/object/loot/DroppedItem.java b/src/main/java/net/momirealms/customfishing/object/loot/DroppedItem.java index a6767f48..e43ad3ac 100644 --- a/src/main/java/net/momirealms/customfishing/object/loot/DroppedItem.java +++ b/src/main/java/net/momirealms/customfishing/object/loot/DroppedItem.java @@ -8,6 +8,9 @@ public class DroppedItem extends Loot{ private boolean randomDurability; private LeveledEnchantment[] randomEnchants; private final String material; + private String[] size; + private float basicPrice; + private float sizeBonus; public DroppedItem(String key, Difficulty difficulty, int time, int weight, String material) { super(key, difficulty, time, weight); @@ -34,4 +37,28 @@ public class DroppedItem extends Loot{ public String getMaterial() { return material; } + + public String[] getSize() { + return size; + } + + public void setSize(String[] size) { + this.size = size; + } + + public float getBasicPrice() { + return basicPrice; + } + + public void setBasicPrice(float basicPrice) { + this.basicPrice = basicPrice; + } + + public float getSizeBonus() { + return sizeBonus; + } + + public void setSizeBonus(float sizeBonus) { + this.sizeBonus = sizeBonus; + } } diff --git a/src/main/java/net/momirealms/customfishing/object/loot/Item.java b/src/main/java/net/momirealms/customfishing/object/loot/Item.java index fdbddea3..d1b79ba6 100644 --- a/src/main/java/net/momirealms/customfishing/object/loot/Item.java +++ b/src/main/java/net/momirealms/customfishing/object/loot/Item.java @@ -3,6 +3,7 @@ package net.momirealms.customfishing.object.loot; import org.bukkit.Material; import org.bukkit.inventory.ItemFlag; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -80,4 +81,20 @@ public class Item { public void setNbt(Map nbt) { this.nbt = nbt; } + + public Item cloneWithPrice(double price){ + Item newItem = new Item(this.material); + if (this.lore != null){ + List lore = new ArrayList<>(); + for (String text : this.lore) { + lore.add(text.replace("{money}", String.format("%.2f", price))); + } + newItem.setLore(lore); + } + if (this.name != null){ + newItem.setName(this.name.replace("{money}", String.format("%.2f", price))); + } + newItem.setCustomModelData(this.customModelData); + return newItem; + } } \ No newline at end of file diff --git a/src/main/java/net/momirealms/customfishing/object/sell/ContainerPacketListener.java b/src/main/java/net/momirealms/customfishing/object/sell/ContainerPacketListener.java new file mode 100644 index 00000000..66baca0f --- /dev/null +++ b/src/main/java/net/momirealms/customfishing/object/sell/ContainerPacketListener.java @@ -0,0 +1,44 @@ +package net.momirealms.customfishing.object.sell; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.reflect.StructureModifier; +import com.comphenix.protocol.wrappers.WrappedChatComponent; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; +import net.momirealms.customfishing.CustomFishing; +import net.momirealms.customfishing.integration.papi.PlaceholderManager; +import net.momirealms.customfishing.manager.SellManager; +import net.momirealms.customfishing.util.ItemStackUtil; +import org.bukkit.entity.Player; + +public class ContainerPacketListener extends PacketAdapter { + + public ContainerPacketListener() { + super(CustomFishing.plugin, PacketType.Play.Server.OPEN_WINDOW); + } + + @Override + public void onPacketSending(PacketEvent event) { + PacketContainer packet = event.getPacket(); + StructureModifier wrappedChatComponentStructureModifier = packet.getChatComponents(); + WrappedChatComponent component = wrappedChatComponentStructureModifier.getValues().get(0); + if (component.getJson().equals("{\"text\":\"{CustomFishing}\"}")) { + PlaceholderManager placeholderManager = CustomFishing.plugin.getIntegrationManager().getPlaceholderManager(); + Player player = event.getPlayer(); + String text = SellManager.title.replace("{player}", player.getName()); + if (placeholderManager != null) placeholderManager.parse(player, text); + wrappedChatComponentStructureModifier.write(0, + WrappedChatComponent.fromJson( + GsonComponentSerializer.gson().serialize( + MiniMessage.miniMessage().deserialize( + ItemStackUtil.replaceLegacy(text) + ) + ) + ) + ); + } + } +} diff --git a/src/main/java/net/momirealms/customfishing/object/sell/InventoryListener.java b/src/main/java/net/momirealms/customfishing/object/sell/InventoryListener.java new file mode 100644 index 00000000..b37313c3 --- /dev/null +++ b/src/main/java/net/momirealms/customfishing/object/sell/InventoryListener.java @@ -0,0 +1,30 @@ +package net.momirealms.customfishing.object.sell; + +import net.momirealms.customfishing.manager.SellManager; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.*; + +public class InventoryListener implements Listener { + + private final SellManager sellManager; + + public InventoryListener(SellManager sellManager) { + this.sellManager = sellManager; + } + + @EventHandler + public void onOpen(InventoryOpenEvent event){ + sellManager.onOpen(event); + } + + @EventHandler + public void onClick(InventoryClickEvent event) { + sellManager.onClick(event); + } + + @EventHandler + public void onClose(InventoryCloseEvent event){ + sellManager.onClose(event); + } +} diff --git a/src/main/java/net/momirealms/customfishing/util/AdventureUtil.java b/src/main/java/net/momirealms/customfishing/util/AdventureUtil.java index ada046f9..0b336b2a 100644 --- a/src/main/java/net/momirealms/customfishing/util/AdventureUtil.java +++ b/src/main/java/net/momirealms/customfishing/util/AdventureUtil.java @@ -40,14 +40,14 @@ public class AdventureUtil { public static void consoleMessage(String s) { Audience au = CustomFishing.adventure.sender(Bukkit.getConsoleSender()); MiniMessage mm = MiniMessage.miniMessage(); - Component parsed = mm.deserialize(s); + Component parsed = mm.deserialize(ItemStackUtil.replaceLegacy(s)); au.sendMessage(parsed); } public static void playerMessage(Player player, String s) { Audience au = CustomFishing.adventure.player(player); MiniMessage mm = MiniMessage.miniMessage(); - Component parsed = mm.deserialize(s); + Component parsed = mm.deserialize(ItemStackUtil.replaceLegacy(s)); au.sendMessage(parsed); } @@ -55,7 +55,7 @@ public class AdventureUtil { Audience au = CustomFishing.adventure.player(player); MiniMessage mm = MiniMessage.miniMessage(); Title.Times times = Title.Times.times(Duration.ofMillis(in), Duration.ofMillis(duration), Duration.ofMillis(out)); - Title title = Title.title(mm.deserialize(s1), mm.deserialize(s2), times); + Title title = Title.title(mm.deserialize(ItemStackUtil.replaceLegacy(s1)), mm.deserialize(ItemStackUtil.replaceLegacy(s2)), times); au.showTitle(title); } @@ -69,7 +69,7 @@ public class AdventureUtil { public static void playerActionbar(Player player, String s) { Audience au = CustomFishing.adventure.player(player); MiniMessage mm = MiniMessage.miniMessage(); - au.sendActionBar(mm.deserialize(s)); + au.sendActionBar(mm.deserialize(ItemStackUtil.replaceLegacy(s))); } public static void playerSound(Player player, Sound.Source source, Key key, float volume, float pitch) { diff --git a/src/main/java/net/momirealms/customfishing/util/ConfigUtil.java b/src/main/java/net/momirealms/customfishing/util/ConfigUtil.java index 344a2112..963c41bc 100644 --- a/src/main/java/net/momirealms/customfishing/util/ConfigUtil.java +++ b/src/main/java/net/momirealms/customfishing/util/ConfigUtil.java @@ -40,6 +40,8 @@ public class ConfigUtil { CustomFishing.plugin.getTotemManager().load(); CustomFishing.plugin.getIntegrationManager().unload(); CustomFishing.plugin.getIntegrationManager().load(); + CustomFishing.plugin.getSellManager().unload(); + CustomFishing.plugin.getSellManager().load(); try { Reflection.load(); } diff --git a/src/main/java/net/momirealms/customfishing/util/ItemStackUtil.java b/src/main/java/net/momirealms/customfishing/util/ItemStackUtil.java index f2149297..cad2cd70 100644 --- a/src/main/java/net/momirealms/customfishing/util/ItemStackUtil.java +++ b/src/main/java/net/momirealms/customfishing/util/ItemStackUtil.java @@ -51,7 +51,6 @@ public class ItemStackUtil { NBTCompound display = nbtItem.addCompound("display"); String name = item.getName(); if (name.contains("&") || name.contains("§")){ - name = name.replaceAll("&","§"); name = replaceLegacy(name); } display.setString("Name", GsonComponentSerializer.gson().serialize(MiniMessage.miniMessage().deserialize("" + name))); @@ -61,7 +60,6 @@ public class ItemStackUtil { List lore = display.getStringList("Lore"); item.getLore().forEach(line -> { if (line.contains("&") || line.contains("§")){ - line = line.replaceAll("&","§"); line = replaceLegacy(line); } lore.add(GsonComponentSerializer.gson().serialize(MiniMessage.miniMessage().deserialize("" + line))); @@ -200,6 +198,40 @@ public class ItemStackUtil { return true; } + public static void addExtraMeta(ItemStack itemStack, DroppedItem droppedItem) { + NBTItem nbtItem = new NBTItem(itemStack); + boolean changed = replaceSizeLore(droppedItem.getSize(), nbtItem); + if (droppedItem.getBasicPrice() != 0) { + NBTCompound fishMetaCompound = nbtItem.addCompound("FishMeta"); + fishMetaCompound.setFloat("base", droppedItem.getBasicPrice()); + changed = true; + } + if (droppedItem.getSizeBonus() != 0) { + NBTCompound fishMetaCompound = nbtItem.addCompound("FishMeta"); + fishMetaCompound.setFloat("bonus", droppedItem.getSizeBonus()); + changed = true; + } + if (changed) { + itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); + } + } + + private static boolean replaceSizeLore(String[] sizes, NBTItem nbtItem) { + if (sizes == null) return false; + float min = Float.parseFloat(sizes[0]); + float max = Float.parseFloat(sizes[1]); + if (max - min < 0) return false; + float size = (float) (min + Math.random() * (max - min)); + String sizeText = String.format("%.1f", size); + NBTCompound nbtCompound = nbtItem.getCompound("display"); + if (nbtCompound == null || !nbtCompound.hasKey("Lore")) return false; + List lore = nbtCompound.getStringList("Lore"); + lore.replaceAll(s -> s.replace("{size}", sizeText)); + NBTCompound fishMetaCompound = nbtItem.addCompound("FishMeta"); + fishMetaCompound.setFloat("size", size); + return true; + } + public static Map compoundToMap(NBTCompound nbtCompound){ Map map = new HashMap<>(); nbtCompound.getKeys().forEach(key -> { @@ -243,7 +275,7 @@ public class ItemStackUtil { public static String replaceLegacy(String s) { StringBuilder stringBuilder = new StringBuilder(); - char[] chars = s.toCharArray(); + char[] chars = s.replaceAll("&","§").toCharArray(); for (int i = 0; i < chars.length; i++) { if (chars[i] == '§') { if (i + 1 < chars.length) { diff --git a/src/main/resources/competition.yml b/src/main/resources/competition.yml index c2ef726d..922de0a0 100644 --- a/src/main/resources/competition.yml +++ b/src/main/resources/competition.yml @@ -10,6 +10,7 @@ example: start-time: - '12:30' - '18:30' + #seconds duration: 300 diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 926f3de5..5079d55c 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,11 +1,13 @@ # don't change -config-version: '9' - +config-version: '10' +# cn/en/es lang: en - +# Plugin hooks integration: + # Sell fish + Vault: true # Skill-xp mcMMO: false MMOCore: false @@ -15,8 +17,19 @@ integration: # Season condition CustomCrops: false RealisticSeasons: false + # Prevent players from activating totems in some regions + Residence: false + WorldGuard: false + Kingdoms: false + GriefDefender: false + PlotSquared: false + Towny: false + Lands: false + GriefPrevention: false + CrashClaim: false + BentoBox: false - +# Worlds where fishing mechanic takes effects worlds: # Mode: whitelist/blacklist mode: whitelist @@ -24,21 +37,17 @@ worlds: - world - world_nether - +# Mechanic settings mechanics: - other-loots: - # Should other loots have the same fishing mechanic CustomFishing provides fishing-bar: true - vanilla: # Vanilla loot is available only when 'double-reel-in' is true enable: true # 0.4 means 40% of the loots are from vanilla # and 60% are from CustomFishing Loot system ratio: 0.4 - mcMMO: # mcMMO treasure system # chance represents the chance to try to be a mcMMO treasure @@ -46,42 +55,35 @@ mechanics: # mcMMO has a complex treasure system enable: false chance: 0.5 - - # The same to vanilla (refer to the wiki) + # The same to vanilla mechanic (refer to the wiki) # https://technical-minecraft.fandom.com/wiki/Fishing need-open-water: false - need-special-rod: # Players must use rods with CustomFishing's NBT Tags to get loots in CustomFishing but they can experience the special fishing mechanic. for-loots: false # Players must use rods with CustomFishing's NBT Tags to experience the special fishing mechanic. Otherwise they can only fish in a vanilla way to-fish: false - # does rod lose durability when player successfully fish rod-lose-durability: true - - # Cool down time of fish finder(ms) - fishfinder-cooldown: 3000 - # Competition fishing-competition: enable: true + # Enable redis server for syncing data between servers redis: false - # Fishing bag is a place where players can store their baits, utils, rods (Fish optional) fishing-bag: enable: true # This would add additional NBT Tags to the fish can-store-fish: false - # File/SQLite/MySql + # File/MySql data-storage-mode: File - + # Lava fishing settings lava-fishing: # ticks - min-time: 100 - max-time: 600 - + min-wait-time: 100 + max-wait-time: 600 +# Fishing result titles titles: success: title: @@ -98,7 +100,7 @@ titles: out: 10 failure: title: - - 'Real food!' + - 'Be concentrated!' - 'Failure!' - 'Try next time!' subtitle: @@ -109,20 +111,17 @@ titles: stay: 30 out: 10 - - +# Other settings other-settings: - # MONITOR HIGHEST HIGH NORMAL LOW LOWEST event-priority: NORMAL - # If enabled, players would not be able to get job exp in vanilla way disable-JobsReborn-fishing-exp: false - # Convert MMOItems' rod into CustomFishing's rod # keep the same key name both in MMOItems and CustomFishing so rods can extend the bonus of those in CustomFishing convert-MMOItems-rods: false - # Prevent other players to pick up your fishing loot # This is useful for players to fish in a public area - prevent-other-players-pick-up-loot: false \ No newline at end of file + prevent-other-players-pick-up-loot: false + # Log the money player get from selling the fish in the console + log-earnings: true \ No newline at end of file diff --git a/src/main/resources/database.yml b/src/main/resources/database.yml index 24134efc..7512884a 100644 --- a/src/main/resources/database.yml +++ b/src/main/resources/database.yml @@ -19,21 +19,9 @@ MySQL: maximum-lifetime: 180000 idle-timeout: 60000 -# SQLite settings -SQLite: - file-name: data - table: customfishing_data - -# MongoDB settings -MongoDB: - client: 'mongodb://localhost:3307' - database: customfishing - collection: customfishing.statistics - # Redis server # Sync competition scores between servers without lag! Redis: - enable: false host: localhost port: 6379 MaxTotal: 10 diff --git a/src/main/resources/loots/example.yml b/src/main/resources/loots/example.yml index 3ddbd98f..276bcb8e 100644 --- a/src/main/resources/loots/example.yml +++ b/src/main/resources/loots/example.yml @@ -17,7 +17,7 @@ rainbow_fish: score: 10 # Specify the bar. If not specified, it will be random layout: - - bar1 + - bar_1 # Difficulty # '1' represents the pointer moves every 1 tick # '7' represents the pointer moves 7 pixels each time @@ -34,8 +34,17 @@ rainbow_fish: name: '✖Example Rainbow Fish✖' lore: - 'This is a rainbow fish!' + - 'It is {size}cm long!' custom-model-data: 1 + # Optional + size: 10~200 + + # Optional + price: + base: 50 + bonus: 0.3 + # Custom NBT tags # If you are not sure about the NBT tag. You can use command '/cfishing import xxx' # (Int) (Byte) (String) (Float) (String) (Double) (Short) (Long) (UUID) (Boolean) (IntArray) (ByteArray) @@ -43,11 +52,6 @@ rainbow_fish: itemsadder: namespace: '(String) momirealms' id: '(String) rainbow_fish' - SomeNBT: - NBTS: - byte: '(Byte) 127' - float: '(Float) 3.14159' - Price: '(Double) 10' # Available events: success/failure/hook # Available actions: message/command/exp/mending/skill-xp diff --git a/src/main/resources/messages/messages_cn.yml b/src/main/resources/messages/messages_cn.yml index ffca6f24..375f33d6 100644 --- a/src/main/resources/messages/messages_cn.yml +++ b/src/main/resources/messages/messages_cn.yml @@ -14,7 +14,6 @@ messages: lack-args: '参数不足.' none-args: '非空参数!' invalid-args: '无效参数!' - cooldown: '你使用找鱼器的速度太快了!' possible-loots: '此处可能钓到: ' split-char: ',' no-loot: '这个地方什么鱼都没有!' @@ -28,5 +27,5 @@ messages: force-competition-cancel: '已强制取消当前正在进行的比赛!' hook-other-entity: '你的鱼钩被其他生物钩走了!' no-rod: '你必须使用特殊鱼竿才能获得战利品!' - no-player: '无' - no-score: '无' \ No newline at end of file + no-player: '虚位以待' + no-score: '无分数' \ No newline at end of file diff --git a/src/main/resources/messages/messages_en.yml b/src/main/resources/messages/messages_en.yml index a6544dcb..0f29b439 100644 --- a/src/main/resources/messages/messages_en.yml +++ b/src/main/resources/messages/messages_en.yml @@ -14,7 +14,6 @@ messages: lack-args: 'Insufficient parameters.' none-args: 'None arguments!' invalid-args: 'Invalid arguments!' - cooldown: 'You''re using the fish finder too fast!' possible-loots: 'Possible loots here: ' split-char: ', ' no-loot: 'There''s no fish in this place!' diff --git a/src/main/resources/messages/messages_es.yml b/src/main/resources/messages/messages_es.yml index f9d4ed16..561a3388 100644 --- a/src/main/resources/messages/messages_es.yml +++ b/src/main/resources/messages/messages_es.yml @@ -14,7 +14,6 @@ messages: lack-args: 'Parámetros insuficientes.' none-args: '¡Ningún argumento!' invalid-args: 'Argumentos no válidos' - cooldown: '¡Estás usando el buscador de peces demasiado rápido!' possible-loots: 'Posible pesca aquí: ' split-char: ', ' no-loot: '¡No hay peces en este lugar!' diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 5837e011..7cd0dfb3 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -19,6 +19,8 @@ softdepend: - MMOItems - eco - Jobs + - Vault + commands: customfishing: usage: /customfishing @@ -29,4 +31,23 @@ commands: fishingbag: usage: /fishingbag open description: fishing bag command - permission: customfishing.user \ No newline at end of file + permission: customfishing.fishingbag + sellfish: + usage: /sellfish + description: fishing bag command + permission: customfishing.sellfish + +permissions: + customfishing.*: + description: Gives access to all customfishing commands + children: + customfishing.admin: true + customfishing.fishingbag: true + customfishing.sellfish: true + + customfishing.admin: + default: op + customfishing.fishingbag: + default: true + customfishing.sellfish: + default: true \ No newline at end of file diff --git a/src/main/resources/sell-fish.yml b/src/main/resources/sell-fish.yml new file mode 100644 index 00000000..95951b11 --- /dev/null +++ b/src/main/resources/sell-fish.yml @@ -0,0 +1,89 @@ +container-title: 'Sell Fish' + +rows: 6 + +price-formula: '{base} + {bonus} * {size}' + +sounds: + open: minecraft:block.chest.open + close: minecraft:block.chest.close + success: minecraft:block.amethyst_block.break + deny: minecraft:block.anvil.destroy + confirm: minecraft:entity.villager.trade + type: player + +actions: + message: + enable: true + text: 'You earned {money} from selling the fish' + title: + enable: true + title: 'Success' + subtitle: 'You earned {money} from selling the fish' + in: 20 + stay: 40 + out: 20 + actionbar: + enable: true + text: 'You earned {money} from selling the fish' + commands: + enable: false + value: + - 'money give {player} {money}' + +functional-icons: + slots: + - 50 + sell: + material: IRON_BLOCK + display: + name: '<#00CED1>Sell the fish' + lore: + - 'You will gain {money}$' + custom-model-data: 1 + deny: + material: REDSTONE_BLOCK + display: + name: 'Denied' + lore: + - 'Nothing to sell!' + custom-model-data: 1 + + +decorative-icons: + glass-pane: + material: BLACK_STAINED_GLASS_PANE + display: + name: ' ' + slot: + - 1 + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + - 8 + - 9 + - 10 + - 18 + - 19 + - 27 + - 28 + - 36 + - 37 + - 45 + - 46 + - 47 + - 48 + - 49 + - 51 + - 52 + - 53 + - 54 + +vanilla-item-price: + COD: 10 + PUFFERFISH: 10 + SALMON: 10 + TROPICAL_FISH: 10 \ No newline at end of file