From 5124d7d0782b5bc74518b4fb7b17e979eb01698f Mon Sep 17 00:00:00 2001 From: BenceX100 Date: Tue, 14 Jan 2025 19:00:42 +0100 Subject: [PATCH] 1.4.0 part 3 --- .../axplayerwarps/InputConverter.java | 2 +- .../commands/subcommands/Create.java | 56 +++++++++++++++++-- .../axplayerwarps/guis/impl/EditWarpGui.java | 15 ++++- .../placeholders/Placeholders.java | 5 +- .../axplayerwarps/utils/FormatUtils.java | 12 ++++ .../axplayerwarps/utils/WarpNameUtils.java | 25 +++++++++ src/main/resources/config.yml | 20 ++++++- src/main/resources/input.yml | 26 ++++----- src/main/resources/lang.yml | 7 ++- 9 files changed, 145 insertions(+), 23 deletions(-) create mode 100644 src/main/java/com/artillexstudios/axplayerwarps/utils/FormatUtils.java create mode 100644 src/main/java/com/artillexstudios/axplayerwarps/utils/WarpNameUtils.java diff --git a/src/main/java/com/artillexstudios/axplayerwarps/InputConverter.java b/src/main/java/com/artillexstudios/axplayerwarps/InputConverter.java index d0cdb5f..e181318 100644 --- a/src/main/java/com/artillexstudios/axplayerwarps/InputConverter.java +++ b/src/main/java/com/artillexstudios/axplayerwarps/InputConverter.java @@ -7,7 +7,7 @@ import static com.artillexstudios.axplayerwarps.AxPlayerWarps.LANG; public class InputConverter { - private static Map mapping = Map.of( + private static final Map mapping = Map.of( "rating-sign", "rate", "search-sign", "search", "rename-sign", "rename", diff --git a/src/main/java/com/artillexstudios/axplayerwarps/commands/subcommands/Create.java b/src/main/java/com/artillexstudios/axplayerwarps/commands/subcommands/Create.java index 5b8f416..7e91892 100644 --- a/src/main/java/com/artillexstudios/axplayerwarps/commands/subcommands/Create.java +++ b/src/main/java/com/artillexstudios/axplayerwarps/commands/subcommands/Create.java @@ -1,9 +1,14 @@ package com.artillexstudios.axplayerwarps.commands.subcommands; +import com.artillexstudios.axapi.utils.Cooldown; import com.artillexstudios.axplayerwarps.AxPlayerWarps; import com.artillexstudios.axplayerwarps.enums.Access; +import com.artillexstudios.axplayerwarps.hooks.HookManager; +import com.artillexstudios.axplayerwarps.hooks.currency.CurrencyHook; import com.artillexstudios.axplayerwarps.user.Users; import com.artillexstudios.axplayerwarps.user.WarpUser; +import com.artillexstudios.axplayerwarps.utils.FormatUtils; +import com.artillexstudios.axplayerwarps.utils.WarpNameUtils; import com.artillexstudios.axplayerwarps.warps.Warp; import com.artillexstudios.axplayerwarps.warps.WarpManager; import org.bukkit.OfflinePlayer; @@ -11,12 +16,15 @@ import org.jetbrains.annotations.Nullable; import java.util.Map; +import java.util.Optional; +import static com.artillexstudios.axplayerwarps.AxPlayerWarps.CONFIG; import static com.artillexstudios.axplayerwarps.AxPlayerWarps.MESSAGEUTILS; public enum Create { INSTANCE; + private final Cooldown cooldown = new Cooldown<>(); public void execute(Player sender, String warpName, @Nullable OfflinePlayer setPlayer) { WarpUser user = Users.get(sender); long limit = user.getWarpLimit(); @@ -27,15 +35,55 @@ public void execute(Player sender, String warpName, @Nullable OfflinePlayer setP return; } - AxPlayerWarps.getThreadedQueue().submit(() -> { - if (AxPlayerWarps.getDatabase().warpExists(warpName)) { - MESSAGEUTILS.sendLang(sender, "errors.name-exists"); + switch (WarpNameUtils.isAllowed(warpName)) { + case CONTAINS_SPACES -> { + MESSAGEUTILS.sendLang(sender, "errors.disallowed-name-space"); + return; + } + case INVALID_LENGTH -> { + MESSAGEUTILS.sendLang(sender, "errors.disallowed-name-length"); return; } + } + + Optional warpOpt = WarpManager.getWarps().stream().filter(warp -> warp.getName().equals(warpName)).findAny(); + if (warpOpt.isPresent()) { + MESSAGEUTILS.sendLang(sender, "errors.name-exists"); + return; + } + + double price; + CurrencyHook currencyHook; + if (CONFIG.getBoolean("warp-creation-cost.enabled", false)) { + price = CONFIG.getDouble("warp-creation-cost.price", 1000); + String currStr = CONFIG.getString("warp-creation-cost.currency", "Experience"); + currencyHook = HookManager.getCurrencyHook(currStr); + if (currencyHook != null) { + // not enough balance + if (currencyHook.getBalance(sender.getUniqueId()) < price) { + MESSAGEUTILS.sendLang(sender, "errors.create-not-enough-currency", + Map.of("%price%", FormatUtils.formatCurrency(currencyHook, price))); + return; + } + // confirmation + if (CONFIG.getBoolean("warp-creation-cost.confirm", true) && !cooldown.hasCooldown(sender)) { + cooldown.addCooldown(sender, 10_000L); + MESSAGEUTILS.sendLang(sender, "create.confirm", + Map.of("%price%", FormatUtils.formatCurrency(currencyHook, price))); + return; + } + currencyHook.takeBalance(sender.getUniqueId(), price); + } + } else { + currencyHook = null; + price = 0; + } + + AxPlayerWarps.getThreadedQueue().submit(() -> { OfflinePlayer usedPlayer = setPlayer == null ? sender : setPlayer; int id = AxPlayerWarps.getDatabase().createWarp(usedPlayer, sender.getLocation(), warpName); Warp warp = new Warp(id, System.currentTimeMillis(), null, warpName, sender.getLocation(), null, usedPlayer.getUniqueId(), usedPlayer.getName(), Access.PUBLIC, null, 0, 0, null); - MESSAGEUTILS.sendLang(sender, "create.created", Map.of("%warp%", warpName)); + MESSAGEUTILS.sendLang(sender, "create.created", Map.of("%warp%", warpName, "%price%", FormatUtils.formatCurrency(currencyHook, price))); WarpManager.getWarps().add(warp); }); } diff --git a/src/main/java/com/artillexstudios/axplayerwarps/guis/impl/EditWarpGui.java b/src/main/java/com/artillexstudios/axplayerwarps/guis/impl/EditWarpGui.java index db8a5e7..3c46035 100644 --- a/src/main/java/com/artillexstudios/axplayerwarps/guis/impl/EditWarpGui.java +++ b/src/main/java/com/artillexstudios/axplayerwarps/guis/impl/EditWarpGui.java @@ -24,6 +24,7 @@ import com.artillexstudios.axplayerwarps.input.InputManager; import com.artillexstudios.axplayerwarps.placeholders.Placeholders; import com.artillexstudios.axplayerwarps.utils.StarUtils; +import com.artillexstudios.axplayerwarps.utils.WarpNameUtils; import com.artillexstudios.axplayerwarps.warps.Warp; import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.GuiItem; @@ -110,6 +111,18 @@ public void open() { open(); return; } + + switch (WarpNameUtils.isAllowed(result)) { + case CONTAINS_SPACES -> { + MESSAGEUTILS.sendLang(player, "errors.disallowed-name-space"); + return; + } + case INVALID_LENGTH -> { + MESSAGEUTILS.sendLang(player, "errors.disallowed-name-length"); + return; + } + } + AxPlayerWarps.getThreadedQueue().submit(() -> { if (!warp.setName(result.replace(" ", "_"))) { MESSAGEUTILS.sendLang(player, "errors.name-exists"); @@ -213,7 +226,7 @@ public void open() { int idx = currency == null ? -1 : currencies.indexOf(currency); if (event.isLeftClick()) { if (event.isShiftClick()) { - InputManager.getInput(player, "transfer", result -> { + InputManager.getInput(player, "price", result -> { if (!NumberUtils.isInt(result)) { MESSAGEUTILS.sendLang(player, "errors.not-a-number"); } else { diff --git a/src/main/java/com/artillexstudios/axplayerwarps/placeholders/Placeholders.java b/src/main/java/com/artillexstudios/axplayerwarps/placeholders/Placeholders.java index 4e4dbb0..34ccfd0 100644 --- a/src/main/java/com/artillexstudios/axplayerwarps/placeholders/Placeholders.java +++ b/src/main/java/com/artillexstudios/axplayerwarps/placeholders/Placeholders.java @@ -6,6 +6,7 @@ import com.artillexstudios.axapi.utils.StringUtils; import com.artillexstudios.axplayerwarps.AxPlayerWarps; import com.artillexstudios.axplayerwarps.database.impl.Base; +import com.artillexstudios.axplayerwarps.utils.FormatUtils; import com.artillexstudios.axplayerwarps.utils.StarUtils; import com.artillexstudios.axplayerwarps.utils.TimeUtils; import com.artillexstudios.axplayerwarps.warps.Warp; @@ -56,11 +57,11 @@ public static String parse(Warp warp, @Nullable OfflinePlayer player, String t) boolean isFree = warp.getCurrency() == null || warp.getTeleportPrice() == 0; t = t.replace("%price%", isFree ? LANG.getString("placeholders.free") : warp.getCurrency().getDisplayName().replace("%price%", df.format(price))); - t = t.replace("%price-full%", warp.getCurrency() == null ? df.format(warp.getTeleportPrice()) : warp.getCurrency().getDisplayName().replace("%price%", df.format(warp.getTeleportPrice()))); + t = t.replace("%price-full%", FormatUtils.formatCurrency(warp.getCurrency(), warp.getTeleportPrice())); t = t.replace("%access%", LANG.getString("access." + warp.getAccess().name().toLowerCase())); double earned = warp.getEarnedMoney(); - t = t.replace("%earned_money%", warp.getCurrency() == null ? df.format(earned) : warp.getCurrency().getDisplayName().replace("%price%", df.format(earned))); + t = t.replace("%earned_money%", FormatUtils.formatCurrency(warp.getCurrency(), earned)); float rating = warp.getRating(); t = t.replace("%rating_decimal%", df.format(rating)); diff --git a/src/main/java/com/artillexstudios/axplayerwarps/utils/FormatUtils.java b/src/main/java/com/artillexstudios/axplayerwarps/utils/FormatUtils.java new file mode 100644 index 0000000..cc065d7 --- /dev/null +++ b/src/main/java/com/artillexstudios/axplayerwarps/utils/FormatUtils.java @@ -0,0 +1,12 @@ +package com.artillexstudios.axplayerwarps.utils; + +import com.artillexstudios.axplayerwarps.hooks.currency.CurrencyHook; +import com.artillexstudios.axplayerwarps.placeholders.Placeholders; + +public class FormatUtils { + + public static String formatCurrency(CurrencyHook currencyHook, double amount) { + return currencyHook == null ? Placeholders.df.format(amount) : currencyHook.getDisplayName() + .replace("%price%", Placeholders.df.format(amount)); + } +} diff --git a/src/main/java/com/artillexstudios/axplayerwarps/utils/WarpNameUtils.java b/src/main/java/com/artillexstudios/axplayerwarps/utils/WarpNameUtils.java new file mode 100644 index 0000000..4933897 --- /dev/null +++ b/src/main/java/com/artillexstudios/axplayerwarps/utils/WarpNameUtils.java @@ -0,0 +1,25 @@ +package com.artillexstudios.axplayerwarps.utils; + +import static com.artillexstudios.axplayerwarps.AxPlayerWarps.CONFIG; + +public class WarpNameUtils { + public enum ValidationResult { + ALLOWED, + CONTAINS_SPACES, + INVALID_LENGTH + } + + public static ValidationResult isAllowed(String name) { + if (!CONFIG.getBoolean("warp-naming.allow-spaces", false) && name.contains(" ")) { + return ValidationResult.CONTAINS_SPACES; + } + + if (name.length() < CONFIG.getInt("warp-naming.length.min", 1) + || name.length() > CONFIG.getInt("warp-naming.length.max", 16) + ) { + return ValidationResult.INVALID_LENGTH; + } + + return ValidationResult.ALLOWED; + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 11406ee..88a2331 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -40,6 +40,24 @@ admin-command-aliases: - "pwarpadmin" - "pwarpsadmin" +warp-creation-cost: + # should creating warps cost money? + enabled: false + # ask player for a confirmation to make sure + # that they are aware of the price of the warp creation + confirm: true + # price of creation + price: 1000 + # currencies are defined in the currencies.yml + currency: Vault + +warp-naming: + # allowing spaces might make it hard to tab complete warps + allow-spaces: false + length: + min: 1 + max: 16 + # which material should we use if the player doesn't define an icon for their warp? # PLAYER_HEAD will default to the owner's skull (note: sometimes it may not load) default-material: "PLAYER_HEAD" @@ -171,4 +189,4 @@ update-notifier: debug: false # do not change this -version: 2 \ No newline at end of file +version: 3 \ No newline at end of file diff --git a/src/main/resources/input.yml b/src/main/resources/input.yml index d06430e..a60a874 100644 --- a/src/main/resources/input.yml +++ b/src/main/resources/input.yml @@ -25,7 +25,7 @@ rate: item: material: PAPER glow: true - name: "&f" + name: "&fRATING HERE" lore: - "!EEBBValid values: 1-5" chat: @@ -45,9 +45,9 @@ search: item: material: PAPER glow: true - name: "&f" + name: "&fSEARCH HERE" lore: - - "!EEBB/\ searching for" + - "!EEBB↑ searching for" chat: - "!EEBBWhat do you want to search for? &#DDDDDD(write !EEBBcancel &#DDDDDDto stop)" @@ -64,9 +64,9 @@ rename: item: material: PAPER glow: true - name: "&f" + name: "&fNEW NAME HERE" lore: - - "!EEBB/\ new name" + - "!EEBB↑ new name" chat: - "!EEBBWrite the new warp name in the chat: &#DDDDDD(write !EEBBcancel &#DDDDDDto stop)" @@ -83,9 +83,9 @@ price: item: material: PAPER glow: true - name: "&f" + name: "&fPRICE HERE" lore: - - "!EEBB/\ price" + - "!EEBB↑ price" chat: - "!EEBBWrite the new price in the chat: &#DDDDDD(write !EEBBcancel &#DDDDDDto stop)" @@ -102,9 +102,9 @@ add-line: item: material: PAPER glow: true - name: "&f" + name: "&fNEW LINE HERE" lore: - - "!EEBB/\ new line" + - "!EEBB↑ new line" chat: - "!EEBBWrite the new line in the chat: &#DDDDDD(write !EEBBcancel &#DDDDDDto stop)" @@ -121,9 +121,9 @@ add-player: item: material: PAPER glow: true - name: "&f" + name: "&fPLAYER'S NAME HERE" lore: - - "!EEBB/\ name of player" + - "!EEBB↑ name of player" chat: - "!EEBBWrite the name of the player in the chat: &#DDDDDD(write !EEBBcancel &#DDDDDDto stop)" @@ -140,9 +140,9 @@ transfer: item: material: PAPER glow: true - name: "&f" + name: "&fPLAYER'S NAME HERE" lore: - - "!EEBB/\ name of player" + - "!EEBB↑ name of player" chat: - "!EEBBWrite the name of the player in the chat: &#DDDDDD(write !EEBBcancel &#DDDDDDto stop)" diff --git a/src/main/resources/lang.yml b/src/main/resources/lang.yml index dde6354..b07ac2c 100644 --- a/src/main/resources/lang.yml +++ b/src/main/resources/lang.yml @@ -58,6 +58,7 @@ info: create: created: "&#BBFFDDYou have successfully created the !EEBB%warp% &#BBFFDDwarp!" + confirm: "&#BBFFDDCreating a warp will cost you !EEBB%price%&#BBFFDD! If you still want to create the warp, type this command again!" whitelist: clear: "&#BBFFDDYou have removed all players from the whitelist!" @@ -109,6 +110,8 @@ admin: setowner: "&#FF4444You have transferred the &#FF0000%warp% &#FF4444warp to &#FF0000%player%&#FF4444!" errors: + disallowed-name-space: "&#FF4444The given warp name cannot contain spaces!" + disallowed-name-length: "&#FF4444The length of the given warp name is too short or too long!" blacklist-self: "&#FF4444You can't blacklist yourself!" whitelist-self: "&#FF4444You can't whitelist yourself!" player-not-found: "&#FF4444This player has never played on the server!" @@ -118,6 +121,8 @@ errors: name-exists: "&#FF4444A warp with this name already exists." max-lines: "&#FF4444You can not add more lines to the warp's description!" not-enough-balance: "&#FF4444You do not have enough money to teleport to this warp!" + create-not-enough-currency: "&#FF4444You need to have &#FF0000%price% &#FF4444to create a warp!" + cannot-create-here: "&#FF4444You can't create a warp here, because it is in a protected area." blacklisted: "&#FF4444You can not teleport to the &#FF0000%warp% &#FF4444warp, because you are blacklisted!" whitelisted: "&#FF4444You can not teleport to the &#FF0000%warp% &#FF4444warp, because it is whitelisted and you are not on the whitelist!" private: "&#FF4444The &#FF0000%warp% &#FF4444is currently set to private, only the owner can teleport to it!" @@ -153,4 +158,4 @@ commands: update-notifier: "XCCFFThere is a new version of AxPlayerWarps available! &#DDDDDD(&#FFFFFFcurrent: &#FF0000%current% &#DDDDDD| &#FFFFFFlatest: �FF00%latest%&#DDDDDD)" # do not change this -version: 1 \ No newline at end of file +version: 2 \ No newline at end of file