From ccbfa68e0444efcb702c2c501af12caefd7611dc Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Wed, 12 Jun 2024 02:24:09 +0800 Subject: [PATCH] checkpoint - 13 --- .../mechanic/competition/CompetitionGoal.java | 10 +- .../competition/CompetitionManager.java | 4 + .../api/mechanic/config/ConfigManager.java | 2 +- .../api/mechanic/config/ConfigType.java | 6 +- .../api/mechanic/context/ContextKeys.java | 6 +- .../common/locale/MessageConstants.java | 7 +- .../common/locale/TranslationManager.java | 5 + common/src/main/resources/database.yml | 77 -------- common/src/main/resources/translations/en.yml | 55 ------ .../bukkit/BukkitCustomFishingPluginImpl.java | 2 - .../bukkit/bag/BukkitBagManager.java | 14 +- .../bukkit/command/BukkitCommandManager.java | 12 +- .../feature/EndCompetitionCommand.java | 37 ++++ .../command/feature/GetItemCommand.java | 2 +- .../command/feature/GiveItemCommand.java | 2 +- .../command/feature/OpenBagCommand.java | 36 ++++ .../command/feature/OpenMarketCommand.java | 36 ++++ .../feature/StartCompetitionCommand.java | 53 +++++ .../feature/StopCompetitionCommand.java | 37 ++++ .../competition/BukkitCompetitionManager.java | 8 +- .../bukkit/competition/Competition.java | 5 +- .../bukkit/config/BukkitConfigManager.java | 11 +- .../integration/BukkitIntegrationManager.java | 2 + .../bukkit/market/BukkitMarketManager.java | 44 ++++- core/src/main/resources/commands.yml | 41 +++- core/src/main/resources/config.yml | 184 +++++++++++++++--- .../main/resources/contents/rod/default.yml | 12 +- core/src/main/resources/market.yml | 158 --------------- core/src/main/resources/translations/en.yml | 39 +++- 29 files changed, 545 insertions(+), 362 deletions(-) delete mode 100644 common/src/main/resources/database.yml delete mode 100644 common/src/main/resources/translations/en.yml create mode 100644 core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/EndCompetitionCommand.java create mode 100644 core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/OpenBagCommand.java create mode 100644 core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/OpenMarketCommand.java create mode 100644 core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/StartCompetitionCommand.java create mode 100644 core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/StopCompetitionCommand.java delete mode 100644 core/src/main/resources/market.yml diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/CompetitionGoal.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/CompetitionGoal.java index 2938292d..9180f366 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/CompetitionGoal.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/CompetitionGoal.java @@ -24,17 +24,19 @@ import org.apache.logging.log4j.util.Supplier; import org.apache.logging.log4j.util.TriConsumer; import org.bukkit.entity.Player; +import java.util.Optional; + public final class CompetitionGoal { public static final CompetitionGoal CATCH_AMOUNT = new CompetitionGoal( "catch_amount", ((rankingProvider, player, score) -> rankingProvider.refreshData(player, 1)), - () -> StandardLocales.GOAL_CATCH_AMOUNT + () -> Optional.ofNullable(StandardLocales.GOAL_CATCH_AMOUNT).orElse("catch_amount") ); public static final CompetitionGoal TOTAL_SCORE = new CompetitionGoal( "total_score", (RankingProvider::refreshData), - () -> StandardLocales.GOAL_TOTAL_SCORE + () -> Optional.ofNullable(StandardLocales.GOAL_TOTAL_SCORE).orElse("total_score") ); public static final CompetitionGoal MAX_SIZE = new CompetitionGoal( "max_size", @@ -43,12 +45,12 @@ public final class CompetitionGoal { rankingProvider.setData(player, score); } }), - () -> StandardLocales.GOAL_MAX_SIZE + () -> Optional.ofNullable(StandardLocales.GOAL_MAX_SIZE).orElse("max_size") ); public static final CompetitionGoal TOTAL_SIZE = new CompetitionGoal( "total_size", (RankingProvider::refreshData), - () -> StandardLocales.GOAL_TOTAL_SIZE + () -> Optional.ofNullable(StandardLocales.GOAL_TOTAL_SIZE).orElse("total_size") ); public static final CompetitionGoal RANDOM = new CompetitionGoal( "random", diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/CompetitionManager.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/CompetitionManager.java index ba735dcd..91efc706 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/CompetitionManager.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/competition/CompetitionManager.java @@ -20,6 +20,8 @@ package net.momirealms.customfishing.api.mechanic.competition; import net.momirealms.customfishing.common.plugin.feature.Reloadable; import org.jetbrains.annotations.Nullable; +import java.util.Collection; + public interface CompetitionManager extends Reloadable { boolean startCompetition(String competition, boolean force, @Nullable String serverGroup); @@ -33,4 +35,6 @@ public interface CompetitionManager extends Reloadable { @Nullable CompetitionConfig getCompetition(String key); + + Collection getCompetitionIDs(); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/config/ConfigManager.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/config/ConfigManager.java index 23dac5c2..ea2456f0 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/config/ConfigManager.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/config/ConfigManager.java @@ -45,7 +45,7 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable { } public static int placeholderLimit() { - return 0; + return 3; } public static boolean redisRanking() { diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/config/ConfigType.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/config/ConfigType.java index 256f6b63..571e62b1 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/config/ConfigType.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/config/ConfigType.java @@ -98,13 +98,17 @@ public class ConfigType { } private final String path; - private final TriConsumer>> argumentConsumer; + private TriConsumer>> argumentConsumer; public ConfigType(String path, TriConsumer>> argumentConsumer) { this.path = path; this.argumentConsumer = argumentConsumer; } + public void argumentConsumer(TriConsumer>> argumentConsumer) { + this.argumentConsumer = argumentConsumer; + } + public static ConfigType of(String path, TriConsumer>> argumentConsumer) { return new ConfigType(path, argumentConsumer); } diff --git a/api/src/main/java/net/momirealms/customfishing/api/mechanic/context/ContextKeys.java b/api/src/main/java/net/momirealms/customfishing/api/mechanic/context/ContextKeys.java index 41f8c8ed..eb1471bc 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/mechanic/context/ContextKeys.java +++ b/api/src/main/java/net/momirealms/customfishing/api/mechanic/context/ContextKeys.java @@ -32,8 +32,10 @@ public class ContextKeys { public static final ContextKeys ID = of("id", String.class); public static final ContextKeys OPEN_WATER = of("open_water", Boolean.class); public static final ContextKeys TYPE = of("type", String.class); - public static final ContextKeys SIZE = of("size", Float.class); - public static final ContextKeys PRICE = of("price", Double.class); + public static final ContextKeys SIZE = of("SIZE", Float.class); + public static final ContextKeys SIZE_FORMATTED = of("size", String.class); + public static final ContextKeys PRICE = of("PRICE", Double.class); + public static final ContextKeys PRICE_FORMATTED = of("price", String.class); public static final ContextKeys SURROUNDING = of("surrounding", String.class); public static final ContextKeys TEMP_NEAR_PLAYER = of("near", String.class); public static final ContextKeys ROD = of("rod", String.class); diff --git a/common/src/main/java/net/momirealms/customfishing/common/locale/MessageConstants.java b/common/src/main/java/net/momirealms/customfishing/common/locale/MessageConstants.java index f6c121a2..10f5f76f 100644 --- a/common/src/main/java/net/momirealms/customfishing/common/locale/MessageConstants.java +++ b/common/src/main/java/net/momirealms/customfishing/common/locale/MessageConstants.java @@ -15,11 +15,12 @@ public interface MessageConstants { TranslatableComponent.Builder COMMAND_FISH_FINDER_SPLIT_CHAR = Component.translatable().key("command.fish_finder.split_char"); TranslatableComponent.Builder COMMAND_COMPETITION_FAILURE_NOT_EXIST = Component.translatable().key("command.competition.failure.not_exist"); TranslatableComponent.Builder COMMAND_COMPETITION_FAILURE_NO_COMPETITION = Component.translatable().key("command.competition.failure.no_competition"); - TranslatableComponent.Builder COMMAND_COMPETITION_FAILURE_STOP_SUCCESS = Component.translatable().key("command.competition.failure.stop.success"); - TranslatableComponent.Builder COMMAND_COMPETITION_FAILURE_END_SUCCESS = Component.translatable().key("command.competition.failure.end.success"); + TranslatableComponent.Builder COMMAND_COMPETITION_START_SUCCESS = Component.translatable().key("command.competition.start.success"); + TranslatableComponent.Builder COMMAND_COMPETITION_STOP_SUCCESS = Component.translatable().key("command.competition.stop.success"); + TranslatableComponent.Builder COMMAND_COMPETITION_END_SUCCESS = Component.translatable().key("command.competition.end.success"); TranslatableComponent.Builder COMMAND_BAG_EDIT_FAILURE_UNSAFE = Component.translatable().key("command.bag.edit.failure.unsafe"); TranslatableComponent.Builder COMMAND_BAG_EDIT_FAILURE_NEVER_PLAYED = Component.translatable().key("command.bag.edit.failure.never_played"); - TranslatableComponent.Builder COMMAND_BAG_OPEN_SUCCESS = Component.translatable().key("command.bag.edit.open.success"); + TranslatableComponent.Builder COMMAND_BAG_OPEN_SUCCESS = Component.translatable().key("command.bag.open.success"); TranslatableComponent.Builder COMMAND_DATA_FAILURE_NOT_LOAD = Component.translatable().key("command.data.failure.not_load"); TranslatableComponent.Builder COMMAND_MARKET_OPEN_SUCCESS = Component.translatable().key("command.market.open.success"); TranslatableComponent.Builder GUI_SELECT_FILE = Component.translatable().key("gui.select_file"); diff --git a/common/src/main/java/net/momirealms/customfishing/common/locale/TranslationManager.java b/common/src/main/java/net/momirealms/customfishing/common/locale/TranslationManager.java index ad7ac762..4b2e5a7c 100644 --- a/common/src/main/java/net/momirealms/customfishing/common/locale/TranslationManager.java +++ b/common/src/main/java/net/momirealms/customfishing/common/locale/TranslationManager.java @@ -98,6 +98,11 @@ public class TranslationManager { } } }); + + Locale localLocale = Locale.getDefault(); + if (!this.installed.contains(localLocale)) { + plugin.getPluginLogger().warn(localLocale.toString().toLowerCase(Locale.ENGLISH) + ".yml not exists, using en.yml as default locale. Consider contributing if you have time for that. We appreciate your work!"); + } } public static boolean isTranslationFile(Path path) { diff --git a/common/src/main/resources/database.yml b/common/src/main/resources/database.yml deleted file mode 100644 index af8f3715..00000000 --- a/common/src/main/resources/database.yml +++ /dev/null @@ -1,77 +0,0 @@ -# file: -# JSON -# YAML -# -# local database -# SQLite -# H2 (preferred over SQLite) -# -# remote database -# MySQL -# MariaDB (preferred over MySQL) -# MongoDB -# -data-storage-method: H2 - -SQLite: - file: 'sqlite' - table-prefix: customfishing - -H2: - file: 'h2' - table-prefix: customfishing - -MySQL: - host: 'localhost' - port: '3306' - user: 'root' - password: 'password' - database: 'minecraft' - connection-parameters: '?autoReconnect=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8' - Pool-Settings: - max-pool-size: 10 - min-idle: 10 - max-lifetime: 180000 - keep-alive-time: 60000 - time-out: 20000 - table-prefix: customfishing - -MariaDB: - host: 'localhost' - port: '3306' - user: 'root' - password: 'password' - database: 'minecraft' - connection-parameters: '?autoReconnect=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8' - Pool-Settings: - max-pool-size: 10 - min-idle: 10 - max-lifetime: 180000 - keep-alive-time: 60000 - time-out: 20000 - table-prefix: customfishing - -MongoDB: - host: 'localhost' - port: '27017' - #user: 'root' - #password: 'password' - database: 'minecraft' - # If this section is not empty, it would override the configs above - # https://www.mongodb.com/docs/manual/reference/connection-string/ - connection-uri: '' - collection-prefix: customfishing - -# Redis is optional if you are using remote database -# If you do not know how to use Redis, please do not enable it -Redis: - enable: false - host: localhost - #password: "123456" - port: 6379 - use-ssl: false - MaxTotal: 10 - MaxIdle: 10 - MinIdle: 1 - MaxWaitMillis: 30000 - MinEvictableIdleTimeMillis: 1800000 \ No newline at end of file diff --git a/common/src/main/resources/translations/en.yml b/common/src/main/resources/translations/en.yml deleted file mode 100644 index 7319af91..00000000 --- a/common/src/main/resources/translations/en.yml +++ /dev/null @@ -1,55 +0,0 @@ -# -# Don't change this -# -config-version: "${config_version}" - -# -# Text format: https://docs.advntr.dev/minimessage/format -# -# You can disable the message by setting the value to "" (empty) for example -# commands.player.anvil.success: "" -# -# Methods for multiple lines: -# 1. "First lineSecond line" -# 2. key: -# - First line -# - Second line -# -exception.invalid_syntax: "Invalid syntax. Correct syntax: " -exception.invalid_argument: "Invalid argument. Reason: " -exception.invalid_sender: " is not allowed to execute that command. Must be of type " -exception.unexpected: "An internal error occurred while attempting to perform this command" -exception.no_permission: "I'm sorry, but you do not have permission to perform this command" -exception.no_such_command: "Unknown command." -argument.entity.notfound.player: "" -argument.entity.notfound.entity: "" -argument.parse.failure.time: "'' is not a valid time format" -argument.parse.failure.material: "'' is not a valid material name" -argument.parse.failure.enchantment: "'' is not a valid enchantment" -argument.parse.failure.offlineplayer: "No player found for input ''" -argument.parse.failure.player: "No player found for input ''" -argument.parse.failure.world: "'' is not a valid Minecraft world" -argument.parse.failure.location.invalid_format: "'' is not a valid location. Required format is ' " -argument.parse.failure.location.mixed_local_absolute: "Cannot mix local and absolute coordinates. (either all coordinates use '^' or none do)" -argument.parse.failure.namespacedkey.namespace: "Invalid namespace ''. Must be [a-z0-9._-]" -argument.parse.failure.namespacedkey.key: "Invalid key ''. Must be [a-z0-9/._-]" -argument.parse.failure.namespacedkey.need_namespace: "Invalid input '', requires an explicit namespace" -argument.parse.failure.boolean: "Could not parse boolean from ''" -argument.parse.failure.number: "'' is not a valid number in the range to " -argument.parse.failure.char: "'' is not a valid character" -argument.parse.failure.string: "'' is not a valid string of type " -argument.parse.failure.uuid: "'' is not a valid UUID" -argument.parse.failure.enum: "'' is not one of the following: " -argument.parse.failure.regex: "'' does not match ''" -argument.parse.failure.flag.unknown: "Unknown flag ''" -argument.parse.failure.flag.duplicate_flag: "Duplicate flag ''" -argument.parse.failure.flag.no_flag_started: "No flag started. Don't know what to do with ''" -argument.parse.failure.flag.missing_argument: "Missing argument for ''" -argument.parse.failure.flag.no_permission: "You don't have permission to use ''" -argument.parse.failure.color: "'' is not a valid color" -argument.parse.failure.duration: "'' is not a duration format" -argument.parse.failure.aggregate.missing: "Missing component ''" -argument.parse.failure.aggregate.failure: "Invalid component '': " -argument.parse.failure.either: "Could not resolve or from ''" -argument.parse.failure.url: "'' is not a valid URL" -argument.parse.failure.namedtextcolor: "'' is not a named text color" \ No newline at end of file diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/BukkitCustomFishingPluginImpl.java b/core/src/main/java/net/momirealms/customfishing/bukkit/BukkitCustomFishingPluginImpl.java index 7bb5669a..a838c5cb 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/BukkitCustomFishingPluginImpl.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/BukkitCustomFishingPluginImpl.java @@ -113,8 +113,6 @@ public class BukkitCustomFishingPluginImpl extends BukkitCustomFishingPlugin { else this.getPluginLogger().warn("Update is available: https://polymart.org/resource/2723"); }); } - - this.integrationManager.load(); } @Override diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/bag/BukkitBagManager.java b/core/src/main/java/net/momirealms/customfishing/bukkit/bag/BukkitBagManager.java index db4b7dc2..c4c64602 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/bag/BukkitBagManager.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/bag/BukkitBagManager.java @@ -73,8 +73,18 @@ public class BukkitBagManager implements BagManager, Listener { public CompletableFuture openBag(Player viewer, UUID owner) { CompletableFuture future = new CompletableFuture<>(); Optional onlineUser = plugin.getStorageManager().getOnlineUser(owner); - onlineUser.ifPresentOrElse(userData -> { - viewer.openInventory(userData.holder().getInventory()); + onlineUser.ifPresentOrElse(data -> { + viewer.openInventory(data.holder().getInventory()); + SparrowHeart.getInstance().updateInventoryTitle(viewer, + plugin.getPlaceholderManager().parse( + Bukkit.getOfflinePlayer(owner), + ConfigManager.bagTitle(), + Map.of( + "{uuid}", owner.toString(), + "{player}", data.name() + ) + ) + ); future.complete(true); }, () -> plugin.getStorageManager().getOfflineUserData(owner, true).thenAccept(result -> result.ifPresentOrElse(data -> { if (data.isLocked()) { diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/command/BukkitCommandManager.java b/core/src/main/java/net/momirealms/customfishing/bukkit/command/BukkitCommandManager.java index 59010132..fca1ac6c 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/command/BukkitCommandManager.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/command/BukkitCommandManager.java @@ -2,10 +2,7 @@ package net.momirealms.customfishing.bukkit.command; import net.kyori.adventure.util.Index; import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; -import net.momirealms.customfishing.bukkit.command.feature.GetItemCommand; -import net.momirealms.customfishing.bukkit.command.feature.GiveItemCommand; -import net.momirealms.customfishing.bukkit.command.feature.ReloadCommand; -import net.momirealms.customfishing.bukkit.command.feature.SellFishCommand; +import net.momirealms.customfishing.bukkit.command.feature.*; import net.momirealms.customfishing.common.command.AbstractCommandManager; import net.momirealms.customfishing.common.command.CommandFeature; import net.momirealms.customfishing.common.sender.Sender; @@ -24,7 +21,12 @@ public class BukkitCommandManager extends AbstractCommandManager new ReloadCommand(this), new SellFishCommand(this), new GetItemCommand(this), - new GiveItemCommand(this) + new GiveItemCommand(this), + new EndCompetitionCommand(this), + new StopCompetitionCommand(this), + new StartCompetitionCommand(this), + new OpenMarketCommand(this), + new OpenBagCommand(this) ); private final Index> INDEX = Index.create(CommandFeature::getFeatureID, FEATURES); diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/EndCompetitionCommand.java b/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/EndCompetitionCommand.java new file mode 100644 index 00000000..a1ea10b5 --- /dev/null +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/EndCompetitionCommand.java @@ -0,0 +1,37 @@ +package net.momirealms.customfishing.bukkit.command.feature; + +import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; +import net.momirealms.customfishing.api.mechanic.competition.FishingCompetition; +import net.momirealms.customfishing.bukkit.command.BukkitCommandFeature; +import net.momirealms.customfishing.common.command.CustomFishingCommandManager; +import net.momirealms.customfishing.common.locale.MessageConstants; +import org.bukkit.command.CommandSender; +import org.incendo.cloud.Command; +import org.incendo.cloud.CommandManager; + +public class EndCompetitionCommand extends BukkitCommandFeature { + + public EndCompetitionCommand(CustomFishingCommandManager commandManager) { + super(commandManager); + } + + @Override + public Command.Builder assembleCommand(CommandManager manager, Command.Builder builder) { + return builder + .flag(manager.flagBuilder("silent").withAliases("s").build()) + .handler(context -> { + FishingCompetition competition = BukkitCustomFishingPlugin.getInstance().getCompetitionManager().getOnGoingCompetition(); + if (competition == null) { + handleFeedback(context, MessageConstants.COMMAND_COMPETITION_FAILURE_NO_COMPETITION); + } else { + competition.end(true); + handleFeedback(context, MessageConstants.COMMAND_COMPETITION_END_SUCCESS); + } + }); + } + + @Override + public String getFeatureID() { + return "end_competition"; + } +} diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/GetItemCommand.java b/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/GetItemCommand.java index 3c7e8d44..6492be52 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/GetItemCommand.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/GetItemCommand.java @@ -69,6 +69,6 @@ public class GetItemCommand extends BukkitCommandFeature { @Override public String getFeatureID() { - return "getitem"; + return "get_item"; } } diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/GiveItemCommand.java b/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/GiveItemCommand.java index 2a6c46f6..88f3dbf3 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/GiveItemCommand.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/GiveItemCommand.java @@ -72,6 +72,6 @@ public class GiveItemCommand extends BukkitCommandFeature { @Override public String getFeatureID() { - return "giveitem"; + return "give_item"; } } diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/OpenBagCommand.java b/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/OpenBagCommand.java new file mode 100644 index 00000000..603e6056 --- /dev/null +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/OpenBagCommand.java @@ -0,0 +1,36 @@ +package net.momirealms.customfishing.bukkit.command.feature; + +import net.kyori.adventure.text.Component; +import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; +import net.momirealms.customfishing.bukkit.command.BukkitCommandFeature; +import net.momirealms.customfishing.common.command.CustomFishingCommandManager; +import net.momirealms.customfishing.common.locale.MessageConstants; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.incendo.cloud.Command; +import org.incendo.cloud.CommandManager; +import org.incendo.cloud.bukkit.parser.PlayerParser; + +public class OpenBagCommand extends BukkitCommandFeature { + + public OpenBagCommand(CustomFishingCommandManager commandManager) { + super(commandManager); + } + + @Override + public Command.Builder assembleCommand(CommandManager manager, Command.Builder builder) { + return builder + .required("player", PlayerParser.playerParser()) + .flag(manager.flagBuilder("silent").withAliases("s").build()) + .handler(context -> { + final Player player = context.get("player"); + BukkitCustomFishingPlugin.getInstance().getBagManager().openBag(player, player.getUniqueId()); + handleFeedback(context, MessageConstants.COMMAND_BAG_OPEN_SUCCESS, Component.text(player.getName())); + }); + } + + @Override + public String getFeatureID() { + return "open_bag"; + } +} diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/OpenMarketCommand.java b/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/OpenMarketCommand.java new file mode 100644 index 00000000..95270c58 --- /dev/null +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/OpenMarketCommand.java @@ -0,0 +1,36 @@ +package net.momirealms.customfishing.bukkit.command.feature; + +import net.kyori.adventure.text.Component; +import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; +import net.momirealms.customfishing.bukkit.command.BukkitCommandFeature; +import net.momirealms.customfishing.common.command.CustomFishingCommandManager; +import net.momirealms.customfishing.common.locale.MessageConstants; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.incendo.cloud.Command; +import org.incendo.cloud.CommandManager; +import org.incendo.cloud.bukkit.parser.PlayerParser; + +public class OpenMarketCommand extends BukkitCommandFeature { + + public OpenMarketCommand(CustomFishingCommandManager commandManager) { + super(commandManager); + } + + @Override + public Command.Builder assembleCommand(CommandManager manager, Command.Builder builder) { + return builder + .required("player", PlayerParser.playerParser()) + .flag(manager.flagBuilder("silent").withAliases("s").build()) + .handler(context -> { + final Player player = context.get("player"); + BukkitCustomFishingPlugin.getInstance().getMarketManager().openMarketGUI(player); + handleFeedback(context, MessageConstants.COMMAND_MARKET_OPEN_SUCCESS, Component.text(player.getName())); + }); + } + + @Override + public String getFeatureID() { + return "open_market"; + } +} diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/StartCompetitionCommand.java b/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/StartCompetitionCommand.java new file mode 100644 index 00000000..33ad528f --- /dev/null +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/StartCompetitionCommand.java @@ -0,0 +1,53 @@ +package net.momirealms.customfishing.bukkit.command.feature; + +import net.kyori.adventure.text.Component; +import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; +import net.momirealms.customfishing.api.mechanic.competition.FishingCompetition; +import net.momirealms.customfishing.bukkit.command.BukkitCommandFeature; +import net.momirealms.customfishing.common.command.CustomFishingCommandManager; +import net.momirealms.customfishing.common.locale.MessageConstants; +import org.bukkit.command.CommandSender; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.Command; +import org.incendo.cloud.CommandManager; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.context.CommandInput; +import org.incendo.cloud.parser.standard.StringParser; +import org.incendo.cloud.suggestion.Suggestion; +import org.incendo.cloud.suggestion.SuggestionProvider; + +import java.util.concurrent.CompletableFuture; + +public class StartCompetitionCommand extends BukkitCommandFeature { + + public StartCompetitionCommand(CustomFishingCommandManager commandManager) { + super(commandManager); + } + + @Override + public Command.Builder assembleCommand(CommandManager manager, Command.Builder builder) { + return builder + .required("id", StringParser.stringComponent().suggestionProvider(new SuggestionProvider<>() { + @Override + public @NonNull CompletableFuture> suggestionsFuture(@NonNull CommandContext context, @NonNull CommandInput input) { + return CompletableFuture.completedFuture(BukkitCustomFishingPlugin.getInstance().getCompetitionManager().getCompetitionIDs().stream().map(Suggestion::suggestion).toList()); + } + })) + .optional("group", StringParser.stringParser()) + .flag(manager.flagBuilder("silent").withAliases("s").build()) + .handler(context -> { + String id = context.get("id"); + String group = context.getOrDefault("group", null); + if (BukkitCustomFishingPlugin.getInstance().getCompetitionManager().startCompetition(id, true, group)) { + handleFeedback(context, MessageConstants.COMMAND_COMPETITION_START_SUCCESS); + } else { + handleFeedback(context, MessageConstants.COMMAND_COMPETITION_FAILURE_NOT_EXIST, Component.text(id)); + } + }); + } + + @Override + public String getFeatureID() { + return "start_competition"; + } +} diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/StopCompetitionCommand.java b/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/StopCompetitionCommand.java new file mode 100644 index 00000000..daa60228 --- /dev/null +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/command/feature/StopCompetitionCommand.java @@ -0,0 +1,37 @@ +package net.momirealms.customfishing.bukkit.command.feature; + +import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; +import net.momirealms.customfishing.api.mechanic.competition.FishingCompetition; +import net.momirealms.customfishing.bukkit.command.BukkitCommandFeature; +import net.momirealms.customfishing.common.command.CustomFishingCommandManager; +import net.momirealms.customfishing.common.locale.MessageConstants; +import org.bukkit.command.CommandSender; +import org.incendo.cloud.Command; +import org.incendo.cloud.CommandManager; + +public class StopCompetitionCommand extends BukkitCommandFeature { + + public StopCompetitionCommand(CustomFishingCommandManager commandManager) { + super(commandManager); + } + + @Override + public Command.Builder assembleCommand(CommandManager manager, Command.Builder builder) { + return builder + .flag(manager.flagBuilder("silent").withAliases("s").build()) + .handler(context -> { + FishingCompetition competition = BukkitCustomFishingPlugin.getInstance().getCompetitionManager().getOnGoingCompetition(); + if (competition == null) { + handleFeedback(context, MessageConstants.COMMAND_COMPETITION_FAILURE_NO_COMPETITION); + } else { + competition.stop(true); + handleFeedback(context, MessageConstants.COMMAND_COMPETITION_STOP_SUCCESS); + } + }); + } + + @Override + public String getFeatureID() { + return "stop_competition"; + } +} diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/competition/BukkitCompetitionManager.java b/core/src/main/java/net/momirealms/customfishing/bukkit/competition/BukkitCompetitionManager.java index 54e18722..05fae539 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/competition/BukkitCompetitionManager.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/competition/BukkitCompetitionManager.java @@ -44,6 +44,8 @@ import java.time.LocalDateTime; import java.util.*; import java.util.concurrent.TimeUnit; +import static java.util.Objects.requireNonNull; + public class BukkitCompetitionManager implements CompetitionManager { private final BukkitCustomFishingPlugin plugin; @@ -216,7 +218,6 @@ public class BukkitCompetitionManager implements CompetitionManager { public boolean startCompetition(String competition, boolean force, String serverGroup) { CompetitionConfig config = commandConfigMap.get(competition); if (config == null) { - plugin.getPluginLogger().warn("Competition " + competition + " doesn't exist."); return false; } return startCompetition(config, force, serverGroup); @@ -291,4 +292,9 @@ public class BukkitCompetitionManager implements CompetitionManager { public CompetitionConfig getCompetition(String key) { return commandConfigMap.get(key); } + + @Override + public Collection getCompetitionIDs() { + return commandConfigMap.keySet(); + } } diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/competition/Competition.java b/core/src/main/java/net/momirealms/customfishing/bukkit/competition/Competition.java index 55bf387f..792c76b8 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/competition/Competition.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/competition/Competition.java @@ -67,10 +67,7 @@ public class Competition implements FishingCompetition { if (ConfigManager.redisRanking()) this.rankingProvider = new RedisRankingProvider(); else this.rankingProvider = new LocalRankingProvider(); this.publicContext = Context.player(null, true); - this.publicContext.arg( - ContextKeys.GOAL, - goal - ); + this.publicContext.arg(ContextKeys.GOAL, goal); } @Override diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/config/BukkitConfigManager.java b/core/src/main/java/net/momirealms/customfishing/bukkit/config/BukkitConfigManager.java index c44ca20a..bca30a03 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/config/BukkitConfigManager.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/config/BukkitConfigManager.java @@ -29,6 +29,12 @@ import java.util.function.BiFunction; public class BukkitConfigManager extends ConfigManager { + private static YamlDocument MAIN_CONFIG; + + public static YamlDocument getMainConfig() { + return MAIN_CONFIG; + } + public BukkitConfigManager(BukkitCustomFishingPlugin plugin) { super(plugin); this.registerBuiltInItemProperties(); @@ -42,6 +48,7 @@ public class BukkitConfigManager extends ConfigManager { @Override public void load() { this.loadConfigs(); + MAIN_CONFIG = loadConfig("config.yml"); } private void loadConfigs() { @@ -114,6 +121,7 @@ public class BukkitConfigManager extends ConfigManager { float size = (float) RandomUtils.generateRandomDouble(minSize, maxSize); item.setTag(size, "CustomFishing", "size"); context.arg(ContextKeys.SIZE, size); + context.arg(ContextKeys.SIZE_FORMATTED, String.format("%.2f", size)); }; }, 1_000, "size"); this.registerItemParser(arg -> { @@ -125,8 +133,9 @@ public class BukkitConfigManager extends ConfigManager { double bonusPrice = bonus.evaluate(context); float size = Optional.ofNullable(context.arg(ContextKeys.SIZE)).orElse(0f); double price = basePrice + bonusPrice * size; - item.setTag(price, "CustomFishing", "price"); + item.setTag(price, "Price"); context.arg(ContextKeys.PRICE, price); + context.arg(ContextKeys.PRICE_FORMATTED, String.format("%.2f", price)); }; }, 1_500, "price"); } diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/integration/BukkitIntegrationManager.java b/core/src/main/java/net/momirealms/customfishing/bukkit/integration/BukkitIntegrationManager.java index cb2882b3..849353be 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/integration/BukkitIntegrationManager.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/integration/BukkitIntegrationManager.java @@ -59,11 +59,13 @@ public class BukkitIntegrationManager implements IntegrationManager { this.load(); } + @Override public void disable() { this.enchantmentProviders.clear(); this.levelerProviders.clear(); } + @Override public void load() { if (isHooked("ItemsAdder")) { registerItemProvider(new ItemsAdderItemProvider()); diff --git a/core/src/main/java/net/momirealms/customfishing/bukkit/market/BukkitMarketManager.java b/core/src/main/java/net/momirealms/customfishing/bukkit/market/BukkitMarketManager.java index 14644e8d..a60c5ac0 100644 --- a/core/src/main/java/net/momirealms/customfishing/bukkit/market/BukkitMarketManager.java +++ b/core/src/main/java/net/momirealms/customfishing/bukkit/market/BukkitMarketManager.java @@ -33,12 +33,14 @@ import net.momirealms.customfishing.api.mechanic.misc.value.MathValue; import net.momirealms.customfishing.api.mechanic.misc.value.TextValue; import net.momirealms.customfishing.api.storage.data.EarningData; import net.momirealms.customfishing.api.storage.user.UserData; +import net.momirealms.customfishing.bukkit.config.BukkitConfigManager; import net.momirealms.customfishing.bukkit.item.BukkitItemFactory; import net.momirealms.customfishing.common.item.Item; import net.momirealms.customfishing.common.plugin.scheduler.SchedulerTask; import net.momirealms.customfishing.common.util.Pair; import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.block.ShulkerBox; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.HandlerList; @@ -47,6 +49,8 @@ import org.bukkit.event.inventory.*; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BlockStateMeta; +import org.bukkit.inventory.meta.BundleMeta; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -89,6 +93,9 @@ public class BukkitMarketManager implements MarketManager, Listener { private SchedulerTask resetEarningsTask; private int cachedDate; + private boolean allowBundle; + private boolean allowShulkerBox; + public BukkitMarketManager(BukkitCustomFishingPlugin plugin) { this.plugin = plugin; this.priceMap = new HashMap<>(); @@ -127,18 +134,16 @@ public class BukkitMarketManager implements MarketManager, Listener { this.resetEarningsTask.cancel(); } - // Load configuration from the plugin's config file private void loadConfig() { - YamlDocument config = plugin.getConfigManager().loadConfig("market.yml"); - this.enable = config.getBoolean("enable", true); - this.formula = config.getString("price-formula", "{base} + {bonus} * {size}"); - if (!this.enable) return; + Section config = BukkitConfigManager.getMainConfig().getSection("mechanics.market"); - // Load various configuration settings + this.formula = config.getString("price-formula", "{base} + {bonus} * {size}"); this.layout = config.getStringList("layout").toArray(new String[0]); this.title = TextValue.auto(config.getString("title", "market.title")); this.itemSlot = config.getString("item-slot.symbol", "I").charAt(0); this.allowItemWithNoPrice = config.getBoolean("item-slot.allow-items-with-no-price", true); + this.allowBundle = config.getBoolean("allow-bundle", true); + this.allowShulkerBox = config.getBoolean("allow-shulker-box", true); Section sellAllSection = config.getSection("sell-all-icons"); if (sellAllSection != null) { @@ -202,7 +207,7 @@ public class BukkitMarketManager implements MarketManager, Listener { public void openMarketGUI(Player player) { Optional optionalUserData = plugin.getStorageManager().getOnlineUser(player.getUniqueId()); if (optionalUserData.isEmpty()) { - plugin.getPluginLogger().warn("Player " + player.getName() + "'s market data is not loaded yet."); + plugin.getPluginLogger().warn("Player " + player.getName() + "'s market data has not been loaded yet."); return; } Context context = Context.player(player); @@ -447,6 +452,18 @@ public class BukkitMarketManager implements MarketManager, Listener { return price * itemStack.getAmount(); } + if (allowBundle && itemStack.getItemMeta() instanceof BundleMeta bundleMeta) { + Pair pair = getItemsToSell(context, bundleMeta.getItems()); + return pair.right(); + } + + if (allowShulkerBox && itemStack.getItemMeta() instanceof BlockStateMeta stateMeta) { + if (stateMeta.getBlockState() instanceof ShulkerBox shulkerBox) { + Pair pair = getItemsToSell(context, Arrays.stream(shulkerBox.getInventory().getStorageContents()).filter(Objects::nonNull).toList()); + return pair.right(); + } + } + // If no custom price is defined, attempt to fetch the price from a predefined price map. String itemID = itemStack.getType().name(); Optional optionalCMD = wrapped.customModelData(); @@ -487,6 +504,19 @@ public class BukkitMarketManager implements MarketManager, Listener { for (ItemStack itemStack : itemStacks) { double price = getItemPrice(context, itemStack); if (price > 0 && itemStack != null) { + if (allowBundle && itemStack.getItemMeta() instanceof BundleMeta bundleMeta) { + clearWorthyItems(context, bundleMeta.getItems()); + itemStack.setItemMeta(bundleMeta); + continue; + } + if (allowShulkerBox && itemStack.getItemMeta() instanceof BlockStateMeta stateMeta) { + if (stateMeta.getBlockState() instanceof ShulkerBox shulkerBox) { + clearWorthyItems(context, Arrays.stream(shulkerBox.getInventory().getStorageContents()).filter(Objects::nonNull).toList()); + stateMeta.setBlockState(shulkerBox); + itemStack.setItemMeta(stateMeta); + continue; + } + } itemStack.setAmount(0); } } diff --git a/core/src/main/resources/commands.yml b/core/src/main/resources/commands.yml index 3888797d..b42343fa 100644 --- a/core/src/main/resources/commands.yml +++ b/core/src/main/resources/commands.yml @@ -19,16 +19,51 @@ sellfish: usage: - /sellfish -getitem: +get_item: enable: true permission: customfishing.command.getitem usage: - /customfishing items get - /cfishing items get -giveitem: +give_item: enable: true permission: customfishing.command.giveitem usage: - /customfishing items give - - /cfishing items give \ No newline at end of file + - /cfishing items give + +stop_competition: + enable: true + permission: customfishing.command.competition + usage: + - /customfishing competition stop + - /cfishing competition stop + +end_competition: + enable: true + permission: customfishing.command.competition + usage: + - /customfishing competition end + - /cfishing competition end + +start_competition: + enable: true + permission: customfishing.command.competition + usage: + - /customfishing competition start + - /cfishing competition start + +open_market: + enable: true + permission: customfishing.command.open.market + usage: + - /customfishing open market + - /cfishing open market + +open_bag: + enable: true + permission: customfishing.command.open.bag + usage: + - /customfishing open bag + - /cfishing open bag \ No newline at end of file diff --git a/core/src/main/resources/config.yml b/core/src/main/resources/config.yml index 932ee29c..361c7286 100644 --- a/core/src/main/resources/config.yml +++ b/core/src/main/resources/config.yml @@ -1,18 +1,13 @@ +# Don"t change this config-version: '${config_version}' # Debug debug: false - # BStats metrics: true - # Check updates update-checker: true -# Language -# https://github.com/Xiao-MoMi/Custom-Fishing/tree/main/plugin/src/main/resources/messages -lang: en - # Mechanic settings mechanics: # Specifies the conditions required for the plugin mechanics to work. @@ -23,7 +18,6 @@ mechanics: type: '!world' value: - blacklist_world - # Configures global effects. This is useful if you want to give all the players certain effects based on certain conditions global-effects: effect_1: @@ -156,7 +150,6 @@ mechanics: # Other whitelist-items whitelist-items: - fishing_rod - # Can fishing bag store fishing loots? can-store-loot: false # Requirements for automatically collecting @@ -193,31 +186,178 @@ mechanics: message_action: type: message value: "<#EEE8AA>[Fishing Bag] Your fishing bag has been full." - - # Fishing wait time + market: + # Market GUI title + title: 'Fish Market' + # Whether to enable limitations + limitation: + enable: true + earnings: '10000' # You can use expressions here + # Market menu layout + layout: + - 'AAAAAAAAA' + - 'AIIIIIIIA' + - 'AIIIIIIIA' + - 'AIIIIIIIA' + - 'AAAABAAAA' + # Price formula (For CustomFishing loots) + price-formula: '{BASE} + {BONUS} * {SIZE}' + # Allow player to sell fish in bundles + allow-bundle: true + # Allow player to sell fish in shulker boxes + allow-shulker-box: true + # Item price (For vanilla items & other plugin items that have CustomModelData) + item-price: + # Vanilla Items + COD: 10 + PUFFERFISH: 10 + SALMON: 10 + TROPICAL_FISH: 10 + # PAPER (CustomModelData: 999) + PAPER:999: 5 + # Slots to put items in + item-slot: + symbol: 'I' + allow-items-with-no-price: true + # This is an icon that allows players to sell all the fish from their inventory and fishingbag + # You can enable it by putting the symbol into layout + sell-all-icons: + symbol: 'S' + # Should the fish in fishing bag be sold + fishingbag: true + allow-icon: + material: IRON_BLOCK + display: + name: '<#00CED1>Ship the fish' + lore: + - 'You will get {money_formatted} coins from the fish in inventory and bag' + action: + sound_action: + type: sound + value: + key: 'minecraft:block.amethyst_block.place' + source: 'player' + volume: 1 + pitch: 1 + message_action: + type: message + value: 'You earned {money_formatted} coins from the fish! You can get {rest_formatted} more coins from market today' + command_action: + type: command + value: 'money give {player} {money}' + # Requires Vault and any economy plugin + # money_action: + # type: give-money + # value: '{money}' + deny-icon: + material: REDSTONE_BLOCK + display: + name: 'Denied trade' + lore: + - 'Nothing to sell!' + action: + sound_action: + type: sound + value: + key: 'minecraft:entity.villager.no' + source: 'player' + volume: 1 + pitch: 1 + limit-icon: + material: REDSTONE_BLOCK + display: + name: 'Denied trade' + lore: + - 'The worth of items exceeds the money that can be earned for the rest of today!' + action: + sound_action: + type: sound + value: + key: 'minecraft:block.anvil.land' + source: 'player' + volume: 1 + pitch: 1 + # Sell icon + sell-icons: + symbol: 'B' + allow-icon: + material: IRON_BLOCK + display: + name: '<#00CED1>Ship the fish' + lore: + - 'You will get {money_formatted} coins from the fish' + action: + sound_action: + type: sound + value: + key: 'minecraft:block.amethyst_block.place' + source: 'player' + volume: 1 + pitch: 1 + message_action: + type: message + value: 'You earned {money_formatted} coins from the fish! You can get {rest_formatted} more coins from market today' + command_action: + type: command + value: 'money give {player} {money}' + # Requires Vault and any economy plugin + # money_action: + # type: give-money + # value: '{money}' + deny-icon: + material: REDSTONE_BLOCK + display: + name: 'Denied trade' + lore: + - 'Nothing to sell!' + action: + sound_action: + type: sound + value: + key: 'minecraft:entity.villager.no' + source: 'player' + volume: 1 + pitch: 1 + limit-icon: + material: REDSTONE_BLOCK + display: + name: 'Denied trade' + lore: + - 'The worth of items exceeds the money that can be earned for the rest of today!' + action: + sound_action: + type: sound + value: + key: 'minecraft:block.anvil.land' + source: 'player' + volume: 1 + pitch: 1 + # Decorative icons + decorative-icons: + glass-pane: + symbol: 'A' + material: BLACK_STAINED_GLASS_PANE + display: + name: ' ' # This section would take effect if you set "override-vanilla" to true # That also means vanilla mechanics for example lure enchantment - # would no longer take effect, so you have to configurate its effect - # in enchantment effects. + # would no longer take effect, so you have to configure its effect in CustomFishing fishing-wait-time: # override vanilla mechanic override-vanilla: false # ticks min-wait-time: 100 max-wait-time: 600 - # Lava fishing settings # To modify vanilla fishing time, you should edit paper-world-defaults.yml where there's a section called fishing-time-range lava-fishing: # ticks min-wait-time: 100 max-wait-time: 600 - # Size settings size: # Some effects would increase/decrease size so the option decides whether they could ignore the limit restricted-size-range: true - # Competition settings competition: # Use redis for cross server data synchronization @@ -226,8 +366,7 @@ mechanics: server-group: default # Increase this value would allow you to use more placeholders like {4_player} {5_score} in sacrifice of some performance placeholder-limit: 3 - - # If a player could get multiple loots from fishing, should the loots spawn at the same time or have delays for each (tick) + # If a player could get multiple loots from fishing, should the loots spawn at the same time or have delay for each (measured in ticks) multiple-loot-spawn-delay: 4 # Other settings @@ -235,7 +374,6 @@ other-settings: # It's recommended to use MiniMessage format. If you insist on using legacy color code "&", enable the support below. # Disable this would improve performance legacy-color-code-support: true - # Thread pool settings thread-pool-settings: # The size of the core Thread pool, that is, the size of the Thread pool when there is no task to execute @@ -245,21 +383,16 @@ other-settings: maximumPoolSize: 10 # If a thread is idle for more than this attribute value, it will exit due to timeout keepAliveTime: 30 - # Event priority: MONITOR HIGHEST HIGH NORMAL LOW LOWEST event-priority: NORMAL - # Save the data from cache to file periodically to minimize the data loss if server crashes # -1 to disable data-saving-interval: 600 - # Log the consumption of time on data saving log-data-saving: true - # Lock player's data if a player is playing on a server that connected to database # If you can ensure low database link latency and fast processing, you can consider disabling this option to improve performance lock-data: true - # Requires PlaceholderAPI to work placeholder-register: '{record}': '%fishingstats_size-record_{loot}%' @@ -267,7 +400,6 @@ other-settings: '{date}': '%server_time_yyyy-MM-dd-HH:mm:ss%' # Requires player expansion '{yaw}': '%player_yaw%' - # CustomFishing supports using items/blocks from other plugins # If items share the same id, they would inherit the effects # Check the wiki for examples @@ -276,13 +408,11 @@ other-settings: - vanilla block-detection-order: - vanilla - # Custom durability format custom-durability-format: - '' - 'Durability: {dur} / {max}' - - # Offset characters' unicodes + # Offset characters # Never edit this unless you know what you are doing offset-characters: font: customfishing:offset_chars diff --git a/core/src/main/resources/contents/rod/default.yml b/core/src/main/resources/contents/rod/default.yml index 27c9c8fa..88bde615 100644 --- a/core/src/main/resources/contents/rod/default.yml +++ b/core/src/main/resources/contents/rod/default.yml @@ -26,14 +26,14 @@ beginner_rod: - ' - novice angler''s best friend.' - '' - '<#FFD700>Effects:' - - ' - Increase the hook time' + - ' - Increase the waiting time' - ' - Reduces the challenge of fishing' custom-model-data: 50001 max-durability: 64 effects: effect_1: type: wait-time-multiplier - value: 1.8 + value: 1.5 effect_2: type: difficulty value: -8 @@ -117,8 +117,8 @@ bone_rod: - ' - regular rods.' - '' - '<#FFD700>Effects:' - - ' - Fishing in lava' - - ' - Sometimes skeleton would grab the hook' + - ' - Fish in lava' + - ' - Attract skeletons' custom-model-data: 50005 max-durability: 32 effects: @@ -140,7 +140,7 @@ magical_rod: - '' - '<#FFD700>Effects:' - ' - Get an enchantment book from fishing.' - - ' - Require a long time to get hooked.' + - ' - The waiting time is very long.' - '' - '<#CD5C5C>Requirements:' - ' - 1x book bait' @@ -193,7 +193,7 @@ master_rod: - ' - time it takes for a fish to bite.' - '' - '<#FFD700>Effects:' - - ' - Reduce the hook time' + - ' - Reduce the waiting time' - ' - Increase the challenge of fishing' - ' - Higher chance of getting quality fish' custom-model-data: 50007 diff --git a/core/src/main/resources/market.yml b/core/src/main/resources/market.yml deleted file mode 100644 index c658b6cb..00000000 --- a/core/src/main/resources/market.yml +++ /dev/null @@ -1,158 +0,0 @@ -config-version: '${config_version}' - -# Container title -title: 'Fish Market' - -limitation: - enable: true - # Support expression and placeholders - earnings: '10000' - -# Market menu layout -layout: - - 'AAAAAAAAA' - - 'AIIIIIIIA' - - 'AIIIIIIIA' - - 'AIIIIIIIA' - - 'AAAABAAAA' - -# Price formula (For CustomFishing loots) -price-formula: '{BASE} + {BONUS} * {SIZE}' - -# Item price (For vanilla items & other plugin items that have CustomModelData) -item-price: - # Vanilla Items - COD: 10 - PUFFERFISH: 10 - SALMON: 10 - TROPICAL_FISH: 10 - # PAPER (CustomModelData: 999) - PAPER:999: 5 - -# Slots to put items in -item-slot: - symbol: 'I' - allow-items-with-no-price: true - -# This is an icon that allows players to sell all the fish from their inventory and fishingbag -# You can enable it by putting the symbol into layout -sell-all-icons: - symbol: 'S' - # Should the fish in fishing bag be sold - fishingbag: true - allow-icon: - material: IRON_BLOCK - display: - name: '<#00CED1>Ship the fish' - lore: - - 'You will get {money_formatted} coins by selling the fish from inventory and bag' - action: - sound_action: - type: sound - value: - key: 'minecraft:block.amethyst_block.place' - source: 'player' - volume: 1 - pitch: 1 - message_action: - type: message - value: 'You earned {money_formatted} coins by selling the fish! You can still get {rest_formatted} coins from market today' - command_action: - type: command - value: 'money give {player} {money}' -# Requires Vault and any economy plugin -# money_action: -# type: give-money -# value: '{money}' - deny-icon: - material: REDSTONE_BLOCK - display: - name: 'Denied trade' - lore: - - 'Nothing to sell!' - action: - sound_action: - type: sound - value: - key: 'minecraft:entity.villager.no' - source: 'player' - volume: 1 - pitch: 1 - limit-icon: - material: REDSTONE_BLOCK - display: - name: 'Denied trade' - lore: - - 'The worth of items exceeds the money that can be earned for the rest of today!' - action: - sound_action: - type: sound - value: - key: 'minecraft:block.anvil.land' - source: 'player' - volume: 1 - pitch: 1 - -# Sell icon -sell-icons: - symbol: 'B' - allow-icon: - material: IRON_BLOCK - display: - name: '<#00CED1>Ship the fish' - lore: - - 'You will get {money_formatted} coins by selling the fish' - action: - sound_action: - type: sound - value: - key: 'minecraft:block.amethyst_block.place' - source: 'player' - volume: 1 - pitch: 1 - message_action: - type: message - value: 'You earned {money_formatted} coins by selling the fish! You can still get {rest_formatted} coins from market today' - command_action: - type: command - value: 'money give {player} {money}' -# Requires Vault and any economy plugin -# money_action: -# type: give-money -# value: '{money}' - deny-icon: - material: REDSTONE_BLOCK - display: - name: 'Denied trade' - lore: - - 'Nothing to sell!' - action: - sound_action: - type: sound - value: - key: 'minecraft:entity.villager.no' - source: 'player' - volume: 1 - pitch: 1 - limit-icon: - material: REDSTONE_BLOCK - display: - name: 'Denied trade' - lore: - - 'The worth of items exceeds the money that can be earned for the rest of today!' - action: - sound_action: - type: sound - value: - key: 'minecraft:block.anvil.land' - source: 'player' - volume: 1 - pitch: 1 - -# Decorative icons -decorative-icons: - glass-pane: - symbol: 'A' - material: BLACK_STAINED_GLASS_PANE - display: - name: ' ' \ No newline at end of file diff --git a/core/src/main/resources/translations/en.yml b/core/src/main/resources/translations/en.yml index 876ce41b..33edd3a5 100644 --- a/core/src/main/resources/translations/en.yml +++ b/core/src/main/resources/translations/en.yml @@ -1,7 +1,43 @@ # Don"t change this config-version: "31" -command.prefix: "[CustomFishing] " +exception.invalid_syntax: "Invalid syntax. Correct syntax: " +exception.invalid_argument: "Invalid argument. Reason: " +exception.invalid_sender: " is not allowed to execute that command. Must be of type " +exception.unexpected: "An internal error occurred while attempting to perform this command" +exception.no_permission: "I'm sorry, but you do not have permission to perform this command" +exception.no_such_command: "Unknown command." +argument.entity.notfound.player: "" +argument.entity.notfound.entity: "" +argument.parse.failure.time: "'' is not a valid time format" +argument.parse.failure.material: "'' is not a valid material name" +argument.parse.failure.enchantment: "'' is not a valid enchantment" +argument.parse.failure.offlineplayer: "No player found for input ''" +argument.parse.failure.player: "No player found for input ''" +argument.parse.failure.world: "'' is not a valid Minecraft world" +argument.parse.failure.location.invalid_format: "'' is not a valid location. Required format is ' " +argument.parse.failure.location.mixed_local_absolute: "Cannot mix local and absolute coordinates. (either all coordinates use '^' or none do)" +argument.parse.failure.namespacedkey.namespace: "Invalid namespace ''. Must be [a-z0-9._-]" +argument.parse.failure.namespacedkey.key: "Invalid key ''. Must be [a-z0-9/._-]" +argument.parse.failure.namespacedkey.need_namespace: "Invalid input '', requires an explicit namespace" +argument.parse.failure.boolean: "Could not parse boolean from ''" +argument.parse.failure.number: "'' is not a valid number in the range to " +argument.parse.failure.char: "'' is not a valid character" +argument.parse.failure.string: "'' is not a valid string of type " +argument.parse.failure.uuid: "'' is not a valid UUID" +argument.parse.failure.enum: "'' is not one of the following: " +argument.parse.failure.regex: "'' does not match ''" +argument.parse.failure.flag.unknown: "Unknown flag ''" +argument.parse.failure.flag.duplicate_flag: "Duplicate flag ''" +argument.parse.failure.flag.no_flag_started: "No flag started. Don't know what to do with ''" +argument.parse.failure.flag.missing_argument: "Missing argument for ''" +argument.parse.failure.flag.no_permission: "You don't have permission to use ''" +argument.parse.failure.color: "'' is not a valid color" +argument.parse.failure.duration: "'' is not a duration format" +argument.parse.failure.aggregate.missing: "Missing component ''" +argument.parse.failure.aggregate.failure: "Invalid component '': " +argument.parse.failure.either: "Could not resolve or from ''" +argument.parse.failure.namedtextcolor: "'' is not a named text color" command.reload.success: "Reloaded. Took ms." command.item.failure.not_exist: "Item [] not exists." command.item.give.success: "Successfully given x ." @@ -13,6 +49,7 @@ command.competition.failure.not_exist: "Competition does not exist. command.competition.failure.no_competition: "There's no competition ongoing." command.competition.stop.success: "Stopped the current competition." command.competition.end.success: "Ended the current competition." +command.competition.start.success: "Started the competition." command.bag.edit.failure.unsafe: "Cannot edit a player's fishing bag if they're active on another linked server." command.bag.edit.failure.never_played: "The player hasn't joined the server before. Can't modify a nonexistent player's fishing bag." command.bag.open.success: "Successfully opened the fishing bag for "