diff --git a/ci-pom.xml b/ci-pom.xml index 5b6fb3dc..d1e8a4df 100644 --- a/ci-pom.xml +++ b/ci-pom.xml @@ -7,7 +7,7 @@ us.mytheria BlobLib - 1.697.0 + 1.697.3 pom.xml bloblib diff --git a/local-pom.xml b/local-pom.xml index c79f3e43..48fc30e3 100644 --- a/local-pom.xml +++ b/local-pom.xml @@ -5,7 +5,7 @@ us.mytheria BlobLib - 1.697.0 + 1.697.3 pom.xml bloblib diff --git a/pom.xml b/pom.xml index ae2beb19..85f3790b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 us.mytheria BlobLib - 1.697.0 + 1.697.3 pom diff --git a/src/main/java/us/mytheria/bloblib/BlobLib.java b/src/main/java/us/mytheria/bloblib/BlobLib.java index 0b5dee73..0084270c 100644 --- a/src/main/java/us/mytheria/bloblib/BlobLib.java +++ b/src/main/java/us/mytheria/bloblib/BlobLib.java @@ -9,6 +9,7 @@ import us.mytheria.bloblib.hologram.HologramManager; import us.mytheria.bloblib.managers.*; import us.mytheria.bloblib.managers.fillermanager.FillerManager; +import us.mytheria.bloblib.placeholderapi.TranslatablePH; import us.mytheria.bloblib.utilities.SerializationLib; import us.mytheria.bloblib.vault.VaultManager; @@ -44,6 +45,7 @@ public class BlobLib extends JavaPlugin { private SerializationLib serializationLib; private InventoryTrackerManager inventoryTrackerManager; private TranslatableManager translatableManager; + private TranslatablePH translatablePH; private static BlobLib instance; @@ -104,8 +106,10 @@ public void onEnable() { reload(); new BlobLibCmd(); - Bukkit.getScheduler().runTask(this, - () -> disguiseManager.load()); + Bukkit.getScheduler().runTask(this, () -> { + TranslatablePH.getInstance(this); + disguiseManager.load(); + }); } @Override @@ -120,6 +124,7 @@ public void reload() { configManager.reload(); listenerManager.reload(); soundManager.reload(); + translatableManager.reload(); messageManager.reload(); actionManager.reload(); inventoryManager.reload(); diff --git a/src/main/java/us/mytheria/bloblib/api/BlobLibTranslatableAPI.java b/src/main/java/us/mytheria/bloblib/api/BlobLibTranslatableAPI.java index 711d810a..6f6e210b 100644 --- a/src/main/java/us/mytheria/bloblib/api/BlobLibTranslatableAPI.java +++ b/src/main/java/us/mytheria/bloblib/api/BlobLibTranslatableAPI.java @@ -1,11 +1,15 @@ package us.mytheria.bloblib.api; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import us.mytheria.bloblib.BlobLib; import us.mytheria.bloblib.entities.translatable.TranslatableBlock; import us.mytheria.bloblib.entities.translatable.TranslatableSnippet; import us.mytheria.bloblib.managers.TranslatableManager; +import java.util.Objects; + public class BlobLibTranslatableAPI { private static BlobLibTranslatableAPI instance; @@ -44,7 +48,8 @@ public TranslatableManager getTranslatableManager() { * @return The TranslatableBlock */ @Nullable - public TranslatableBlock getTranslatableBlock(String key, String locale) { + public TranslatableBlock getTranslatableBlock(@NotNull String key, + @NotNull String locale) { return getTranslatableManager().getBlock(key, locale); } @@ -55,10 +60,24 @@ public TranslatableBlock getTranslatableBlock(String key, String locale) { * @return The TranslatableBlock */ @Nullable - public TranslatableBlock getTranslatableBlock(String key) { + public TranslatableBlock getTranslatableBlock(@NotNull String key) { return getTranslatableManager().getBlock(key); } + /** + * Will get a TranslatableBlock by its key and the player's locale. + * + * @param key The key of the translatable + * @param player The player to get the locale from + * @return The TranslatableBlock + */ + @Nullable + public TranslatableBlock getTranslatableBlock(@NotNull String key, + @NotNull Player player) { + Objects.requireNonNull(player); + return getTranslatableManager().getBlock(key, player.getLocale()); + } + /** * Will get a TranslatableSnippet by its key and locale. * If locale is not available, it will return the default locale. @@ -67,7 +86,8 @@ public TranslatableBlock getTranslatableBlock(String key) { * @return The TranslatableSnippet */ @Nullable - public TranslatableSnippet getTranslatableSnippet(String key, String locale) { + public TranslatableSnippet getTranslatableSnippet(@NotNull String key, + @NotNull String locale) { return getTranslatableManager().getSnippet(key, locale); } @@ -78,7 +98,21 @@ public TranslatableSnippet getTranslatableSnippet(String key, String locale) { * @return The TranslatableSnippet */ @Nullable - public TranslatableSnippet getTranslatableSnippet(String key) { + public TranslatableSnippet getTranslatableSnippet(@NotNull String key) { return getTranslatableManager().getSnippet(key); } + + /** + * Will get a TranslatableSnippet by its key and the player's locale. + * + * @param key The key of the translatable + * @param player The player to get the locale from + * @return The TranslatableSnippet + */ + @Nullable + public TranslatableSnippet getTranslatableSnippet(@NotNull String key, + @NotNull Player player) { + Objects.requireNonNull(player); + return getTranslatableManager().getSnippet(key, player.getLocale()); + } } diff --git a/src/main/java/us/mytheria/bloblib/entities/BlobPHExpansion.java b/src/main/java/us/mytheria/bloblib/entities/BlobPHExpansion.java index 8565202c..e25095d6 100644 --- a/src/main/java/us/mytheria/bloblib/entities/BlobPHExpansion.java +++ b/src/main/java/us/mytheria/bloblib/entities/BlobPHExpansion.java @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.BiFunction; import java.util.function.Function; public class BlobPHExpansion extends PlaceholderExpansion { @@ -17,7 +18,7 @@ public class BlobPHExpansion extends PlaceholderExpansion { private final String identifier; private final Map> simple; - private final Map> startsWith; + private final Map> startsWith; public BlobPHExpansion(JavaPlugin plugin, String identifier) { this.plugin = plugin; @@ -37,7 +38,7 @@ public Function putSimple(String key, Function putStartsWith(String key, Function function) { + public BiFunction putStartsWith(String key, BiFunction function) { return startsWith.put(key, function); } @@ -69,11 +70,20 @@ public String onRequest(OfflinePlayer player, @NotNull String identifier) { Function simpleFunction = simple.get(identifier); if (simpleFunction != null) return simpleFunction.apply(player); - return startsWith.entrySet().stream() - .filter(entry -> identifier.startsWith(entry.getKey())) - .filter(entry -> entry.getValue().apply(player) != null) - .findFirst() - .map(entry -> entry.getValue().apply(player)) - .orElse(null); + String dynamicKey; + for (Map.Entry> entry : startsWith.entrySet()) { + if (identifier.startsWith(entry.getKey())) { + dynamicKey = dynamicKey(entry.getKey(), identifier); + if (entry.getValue().apply(player, dynamicKey) != null) { + return entry.getValue().apply(player, dynamicKey); + } + } + } + return null; + } + + private String dynamicKey(String key, String identifier) { + int keyLength = key.length(); + return identifier.substring(keyLength); } } \ No newline at end of file diff --git a/src/main/java/us/mytheria/bloblib/entities/currency/BlobEconomyCommand.java b/src/main/java/us/mytheria/bloblib/entities/currency/BlobEconomyCommand.java index 935952ce..de706a98 100644 --- a/src/main/java/us/mytheria/bloblib/entities/currency/BlobEconomyCommand.java +++ b/src/main/java/us/mytheria/bloblib/entities/currency/BlobEconomyCommand.java @@ -139,7 +139,7 @@ public boolean command(ExecutorData data) { Player player = context.player(); walletOwner.deposit(currency, amount); BlobLibMessageAPI.getInstance().getMessage("Economy.Deposit").modify(s -> s.replace("%display%", currency.display(amount)) - .replace("%currency%", currency.getDisplayName()) + .replace("%currency%", currency.getDisplayName(player)) .replace("%player%", player.getName())).toCommandSender(sender); return true; } @@ -157,13 +157,13 @@ public boolean command(ExecutorData data) { if (!walletOwner.has(currency, amount)) { double missing = amount - walletOwner.getBalance(currency); BlobLibMessageAPI.getInstance().getMessage("Economy.Cannot-Bankrupt-Others").modify(s -> s.replace("%display%", currency.display(missing)) - .replace("%currency%", currency.getDisplayName()) + .replace("%currency%", currency.getDisplayName(player)) .replace("%player%", player.getName())).toCommandSender(sender); return true; } walletOwner.withdraw(currency, amount); BlobLibMessageAPI.getInstance().getMessage("Economy.Withdraw").modify(s -> s.replace("%display%", currency.display(amount)) - .replace("%currency%", currency.getDisplayName()) + .replace("%currency%", currency.getDisplayName(player)) .replace("%player%", player.getName())).toCommandSender(sender); return true; } @@ -178,7 +178,7 @@ public boolean command(ExecutorData data) { Player player = context.player(); context.walletOwner().setBalance(currency, amount); BlobLibMessageAPI.getInstance().getMessage("Economy.Set").modify(s -> s.replace("%display%", currency.display(amount)) - .replace("%currency%", currency.getDisplayName()) + .replace("%currency%", currency.getDisplayName(player)) .replace("%player%", player.getName())).toCommandSender(sender); return true; } @@ -192,7 +192,7 @@ public boolean command(ExecutorData data) { Player player = context.player(); context.walletOwner().reset(currency); BlobLibMessageAPI.getInstance().getMessage("Economy.Reset").modify(s -> s - .replace("%currency%", currency.getDisplayName()) + .replace("%currency%", currency.getDisplayName(player)) .replace("%player%", player.getName())).toCommandSender(sender); return true; } diff --git a/src/main/java/us/mytheria/bloblib/entities/currency/Currency.java b/src/main/java/us/mytheria/bloblib/entities/currency/Currency.java index 850848ac..ddc34c1b 100644 --- a/src/main/java/us/mytheria/bloblib/entities/currency/Currency.java +++ b/src/main/java/us/mytheria/bloblib/entities/currency/Currency.java @@ -4,6 +4,7 @@ import org.bukkit.NamespacedKey; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.persistence.PersistentDataContainer; @@ -25,7 +26,8 @@ import java.util.*; public class Currency implements BlobObject { - private final String display, key, displayName; + private final String display, key; + private final Map displayNames; private final double initialBalance; private final boolean isPersistent; private final DecimalFormat decimalFormat; @@ -45,11 +47,11 @@ public class Currency implements BlobObject { public Currency(String display, double initialBalance, boolean isPersistent, String pattern, String key, boolean isTangible, @Nullable Map tangibleShapes, - BlobPlugin plugin, String displayName) { + BlobPlugin plugin, Map displayNames) { this.plugin = plugin; this.display = display; this.key = key; - this.displayName = displayName; + this.displayNames = displayNames; this.initialBalance = initialBalance; this.isPersistent = isPersistent; this.decimalFormat = new DecimalFormat(pattern); @@ -180,11 +182,40 @@ private String getDisplay() { /** * Returns how its name is displayed in the game. + * Will use the locale to get the name. + * + * @param locale the to get the locale from + * @return the display name + */ + @NotNull + public String getDisplayName(@NotNull String locale) { + String result = displayNames.get(locale); + if (result == null) + result = displayNames.get("en_us"); + Objects.requireNonNull(result, "Default Display-Name for locale '" + locale + "' is missing"); + return result; + } + + /** + * Returns how its name is displayed in the game. + * Will use the player's locale to get the name. + * + * @param player the to get the locale from + * @return the display name + */ + @NotNull + public String getDisplayName(@NotNull Player player) { + return getDisplayName(player.getLocale()); + } + + /** + * Returns how its name is displayed in the game. + * Will use the default locale to get the name. * * @return the display name */ public String getDisplayName() { - return displayName; + return displayNames.get("en_us"); } /** @@ -254,9 +285,20 @@ public static Currency fromFile(File file, ManagerDirector director) { boolean isPersistent = yamlConfiguration.getBoolean("Persistent"); String pattern = yamlConfiguration.getString("Decimal-Format"); String key = FilenameUtils.removeExtension(fileName); - String displayName = key; - if (yamlConfiguration.isString("Display-Name")) - displayName = TextColor.PARSE(yamlConfiguration.getString("Display-Name")); + Map displayNames = new HashMap<>(); + if (!yamlConfiguration.isConfigurationSection("Display-Name")) + displayNames.put("en_us", key); + else { + ConfigurationSection namesSection = yamlConfiguration.getConfigurationSection("Display-Name"); + namesSection.getKeys(false).forEach(locale -> { + if (!namesSection.isString(locale)) + return; + String value = namesSection.getString(locale); + displayNames.put(locale, value); + }); + if (!displayNames.containsKey("en_us")) + displayNames.put("en_us", key); + } boolean isTangible = yamlConfiguration.getBoolean("Is-Tangible", false); final Map tangibleShape = new HashMap<>(); if (isTangible) { @@ -284,6 +326,6 @@ public static Currency fromFile(File file, ManagerDirector director) { }); } return new Currency(display, initialBalance, isPersistent, pattern, key, - isTangible, tangibleShape, director.getPlugin(), displayName); + isTangible, tangibleShape, director.getPlugin(), displayNames); } } \ No newline at end of file diff --git a/src/main/java/us/mytheria/bloblib/entities/currency/CurrencyBuilder.java b/src/main/java/us/mytheria/bloblib/entities/currency/CurrencyBuilder.java index a4a6f9e3..aee0cfad 100644 --- a/src/main/java/us/mytheria/bloblib/entities/currency/CurrencyBuilder.java +++ b/src/main/java/us/mytheria/bloblib/entities/currency/CurrencyBuilder.java @@ -10,6 +10,7 @@ import us.mytheria.bloblib.entities.inventory.ObjectBuilderButtonBuilder; import us.mytheria.bloblib.entities.message.BlobSound; +import java.util.Map; import java.util.UUID; public class CurrencyBuilder extends ObjectBuilder { @@ -76,6 +77,6 @@ public Currency construct() { return new Currency(display, initialBalanceValue, true, decimalFormatPattern, key, false, null, getObjectDirector().getPlugin(), - key); + Map.of("en_us", key)); } } \ No newline at end of file diff --git a/src/main/java/us/mytheria/bloblib/entities/currency/EconomyPHExpansion.java b/src/main/java/us/mytheria/bloblib/entities/currency/EconomyPHExpansion.java index 9f331d1e..3790c2bf 100644 --- a/src/main/java/us/mytheria/bloblib/entities/currency/EconomyPHExpansion.java +++ b/src/main/java/us/mytheria/bloblib/entities/currency/EconomyPHExpansion.java @@ -1,7 +1,9 @@ package us.mytheria.bloblib.entities.currency; import me.clip.placeholderapi.expansion.PlaceholderExpansion; +import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import java.util.Optional; @@ -30,18 +32,19 @@ public boolean canRegister() { return "1.0.1"; } - public String onRequest(OfflinePlayer player, String identifier) { + public String onRequest(OfflinePlayer offlinePlayer, String identifier) { String[] split = identifier.split("_"); if (split.length == 2) { Set customCrypto = ownerManager.currencyDirector.getObjectManager().keys(); if (!customCrypto.contains(split[0])) return "Invalid currency: " + split[0]; - Optional optional = ownerManager.isWalletOwner(player.getUniqueId()); + Optional optional = ownerManager.isWalletOwner(offlinePlayer.getUniqueId()); if (optional.isEmpty()) - return "Invalid player: " + player.getName(); + return "Invalid player: " + offlinePlayer.getName(); T walletOwner = optional.get(); Currency currency = ownerManager.currencyDirector.getObjectManager().getObject(split[0]); String subIdentifier = split[1]; + Player player = Bukkit.getPlayer(offlinePlayer.getUniqueId()); switch (subIdentifier) { case "display" -> { return currency.display(walletOwner.getBalance(currency)); @@ -49,6 +52,12 @@ public String onRequest(OfflinePlayer player, String identifier) { case "balance" -> { return walletOwner.getBalance(currency) + ""; } + case "displayName" -> { + if (player == null) + return currency.getDisplayName(); + else + return currency.getDisplayName(player); + } default -> { return "Invalid sub-identifier: " + subIdentifier; } diff --git a/src/main/java/us/mytheria/bloblib/entities/message/BlobActionbarMessage.java b/src/main/java/us/mytheria/bloblib/entities/message/BlobActionbarMessage.java index d330dd55..4d5eeede 100644 --- a/src/main/java/us/mytheria/bloblib/entities/message/BlobActionbarMessage.java +++ b/src/main/java/us/mytheria/bloblib/entities/message/BlobActionbarMessage.java @@ -5,6 +5,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import us.mytheria.bloblib.entities.translatable.BlobTranslatableSnippet; import java.util.function.Function; @@ -21,7 +22,7 @@ public class BlobActionbarMessage extends SerialBlobMessage { public BlobActionbarMessage(String message, BlobSound sound, String locale) { super(sound, locale); - this.actionbar = message; + this.actionbar = BlobTranslatableSnippet.PARSE(message, locale); } /** diff --git a/src/main/java/us/mytheria/bloblib/entities/message/BlobActionbarTitleMessage.java b/src/main/java/us/mytheria/bloblib/entities/message/BlobActionbarTitleMessage.java index 4f04af18..5d506334 100644 --- a/src/main/java/us/mytheria/bloblib/entities/message/BlobActionbarTitleMessage.java +++ b/src/main/java/us/mytheria/bloblib/entities/message/BlobActionbarTitleMessage.java @@ -5,6 +5,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import us.mytheria.bloblib.entities.translatable.BlobTranslatableSnippet; import java.util.function.Function; @@ -28,7 +29,7 @@ public BlobActionbarTitleMessage(String actionbar, String title, String subtitle int fadeIn, int stay, int fadeOut, BlobSound sound, String locale) { super(title, subtitle, fadeIn, stay, fadeOut, sound, locale); - this.actionbar = actionbar; + this.actionbar = BlobTranslatableSnippet.PARSE(actionbar, locale); } /** diff --git a/src/main/java/us/mytheria/bloblib/entities/message/BlobChatActionbarMessage.java b/src/main/java/us/mytheria/bloblib/entities/message/BlobChatActionbarMessage.java index 84456269..260c2bb9 100644 --- a/src/main/java/us/mytheria/bloblib/entities/message/BlobChatActionbarMessage.java +++ b/src/main/java/us/mytheria/bloblib/entities/message/BlobChatActionbarMessage.java @@ -5,6 +5,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import us.mytheria.bloblib.entities.translatable.BlobTranslatableSnippet; import java.util.function.Function; @@ -25,7 +26,7 @@ public class BlobChatActionbarMessage extends BlobChatMessage { public BlobChatActionbarMessage(String chat, String actionbar, BlobSound sound, String locale) { super(chat, sound, locale); - this.actionbar = actionbar; + this.actionbar = BlobTranslatableSnippet.PARSE(actionbar, locale); } /** diff --git a/src/main/java/us/mytheria/bloblib/entities/message/BlobChatActionbarTitleMessage.java b/src/main/java/us/mytheria/bloblib/entities/message/BlobChatActionbarTitleMessage.java index 706fe34e..e12e5e14 100644 --- a/src/main/java/us/mytheria/bloblib/entities/message/BlobChatActionbarTitleMessage.java +++ b/src/main/java/us/mytheria/bloblib/entities/message/BlobChatActionbarTitleMessage.java @@ -5,6 +5,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import us.mytheria.bloblib.entities.translatable.BlobTranslatableSnippet; import java.util.function.Function; @@ -32,8 +33,8 @@ public class BlobChatActionbarTitleMessage extends BlobChatMessage { public BlobChatActionbarTitleMessage(String chat, String actionbar, String title, String subtitle, int fadeIn, int stay, int fadeOut, BlobSound sound, String locale) { super(chat, sound, locale); - this.actionbar = actionbar; - this.title = title; + this.actionbar = BlobTranslatableSnippet.PARSE(actionbar, locale); + this.title = BlobTranslatableSnippet.PARSE(title, locale); this.subtitle = subtitle; this.fadeIn = fadeIn; this.stay = stay; diff --git a/src/main/java/us/mytheria/bloblib/entities/message/BlobChatMessage.java b/src/main/java/us/mytheria/bloblib/entities/message/BlobChatMessage.java index 66141606..f79f7a74 100644 --- a/src/main/java/us/mytheria/bloblib/entities/message/BlobChatMessage.java +++ b/src/main/java/us/mytheria/bloblib/entities/message/BlobChatMessage.java @@ -3,6 +3,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import us.mytheria.bloblib.entities.translatable.BlobTranslatableSnippet; import java.util.function.Function; @@ -24,7 +25,7 @@ public class BlobChatMessage extends SerialBlobMessage { */ public BlobChatMessage(String message, BlobSound sound, String locale) { super(sound, locale); - this.chat = message; + this.chat = BlobTranslatableSnippet.PARSE(message, locale); } /** diff --git a/src/main/java/us/mytheria/bloblib/entities/message/BlobChatTitleMessage.java b/src/main/java/us/mytheria/bloblib/entities/message/BlobChatTitleMessage.java index 9739474a..c5d783b0 100644 --- a/src/main/java/us/mytheria/bloblib/entities/message/BlobChatTitleMessage.java +++ b/src/main/java/us/mytheria/bloblib/entities/message/BlobChatTitleMessage.java @@ -3,6 +3,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import us.mytheria.bloblib.entities.translatable.BlobTranslatableSnippet; import java.util.function.Function; @@ -27,8 +28,8 @@ public class BlobChatTitleMessage extends BlobChatMessage { public BlobChatTitleMessage(String chat, String title, String subtitle, int fadeIn, int stay, int fadeOut, BlobSound sound, String locale) { super(chat, sound, locale); - this.title = title; - this.subtitle = subtitle; + this.title = BlobTranslatableSnippet.PARSE(title, locale); + this.subtitle = BlobTranslatableSnippet.PARSE(subtitle, locale); this.fadeIn = fadeIn; this.stay = stay; this.fadeOut = fadeOut; diff --git a/src/main/java/us/mytheria/bloblib/entities/message/BlobTitleMessage.java b/src/main/java/us/mytheria/bloblib/entities/message/BlobTitleMessage.java index 78aea18c..cd9c6ded 100644 --- a/src/main/java/us/mytheria/bloblib/entities/message/BlobTitleMessage.java +++ b/src/main/java/us/mytheria/bloblib/entities/message/BlobTitleMessage.java @@ -3,6 +3,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import us.mytheria.bloblib.entities.translatable.BlobTranslatableSnippet; import java.util.function.Function; @@ -13,8 +14,8 @@ public class BlobTitleMessage extends SerialBlobMessage { public BlobTitleMessage(String title, String subtitle, int fadeIn, int stay, int fadeOut, BlobSound sound, String locale) { super(sound, locale); - this.title = title; - this.subtitle = subtitle; + this.title = BlobTranslatableSnippet.PARSE(title, locale); + this.subtitle = BlobTranslatableSnippet.PARSE(subtitle, locale); this.fadeIn = fadeIn; this.stay = stay; this.fadeOut = fadeOut; diff --git a/src/main/java/us/mytheria/bloblib/entities/translatable/BlobTranslatableSnippet.java b/src/main/java/us/mytheria/bloblib/entities/translatable/BlobTranslatableSnippet.java index cd10d265..58e281e4 100644 --- a/src/main/java/us/mytheria/bloblib/entities/translatable/BlobTranslatableSnippet.java +++ b/src/main/java/us/mytheria/bloblib/entities/translatable/BlobTranslatableSnippet.java @@ -1,11 +1,38 @@ package us.mytheria.bloblib.entities.translatable; import org.jetbrains.annotations.NotNull; +import us.mytheria.bloblib.api.BlobLibTranslatableAPI; import java.util.Objects; import java.util.function.Function; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class BlobTranslatableSnippet implements TranslatableSnippet { + private static final Pattern pattern = Pattern.compile("\\{r=(.*?)}"); + + public static String PARSE(@NotNull String text, + @NotNull String locale) { + Objects.requireNonNull(text, "Text cannot be null"); + Objects.requireNonNull(locale, "Locale cannot be null"); + Matcher matcher = pattern.matcher(text); + StringBuilder replaced = new StringBuilder(); + while (matcher.find()) { + String key = matcher.group(1); + TranslatableSnippet result = BlobLibTranslatableAPI.getInstance() + .getTranslatableSnippet(key, locale); + String replacement = result == null ? "" : result + .get(); + matcher.appendReplacement(replaced, replacement); + } + matcher.appendTail(replaced); + return replaced.toString(); + } + + public static String PARSE(@NotNull String text) { + return PARSE(text, "en_us"); + } + @NotNull private final String locale, snippet; @@ -19,7 +46,7 @@ public static BlobTranslatableSnippet of(@NotNull String locale, private BlobTranslatableSnippet(@NotNull String locale, @NotNull String snippet) { this.locale = locale; - this.snippet = snippet; + this.snippet = PARSE(snippet, locale); } @Override diff --git a/src/main/java/us/mytheria/bloblib/entities/translatable/TranslatableReader.java b/src/main/java/us/mytheria/bloblib/entities/translatable/TranslatableReader.java index c5a269ff..529521ab 100644 --- a/src/main/java/us/mytheria/bloblib/entities/translatable/TranslatableReader.java +++ b/src/main/java/us/mytheria/bloblib/entities/translatable/TranslatableReader.java @@ -3,6 +3,7 @@ import org.bukkit.configuration.ConfigurationSection; import org.jetbrains.annotations.NotNull; import us.mytheria.bloblib.exception.ConfigurationFieldException; +import us.mytheria.bloblib.utilities.TextColor; import java.util.List; import java.util.Objects; @@ -20,6 +21,7 @@ public static TranslatableSnippet SNIPPET(@NotNull ConfigurationSection section, if (!section.isString("Snippet")) throw new ConfigurationFieldException("'Snippet' field is required for TranslatableSnippets at " + section.getCurrentPath()); String snippet = Objects.requireNonNull(section.getString("Snippet")); + snippet = TextColor.PARSE(snippet); return BlobTranslatableSnippet.of(locale, snippet); } @@ -31,7 +33,10 @@ public static TranslatableBlock BLOCK(@NotNull ConfigurationSection section, @NotNull String locale) { Objects.requireNonNull(section, "Section cannot be null"); Objects.requireNonNull(locale, "Locale cannot be null"); - List lines = section.getStringList("Lines"); + List lines = section.getStringList("Block"); + if (lines.isEmpty()) + throw new ConfigurationFieldException("'Block' field is required for TranslatableBlocks"); + lines = lines.stream().map(TextColor::PARSE).toList(); return BlobTranslatableBlock.of(locale, lines); } } diff --git a/src/main/java/us/mytheria/bloblib/entities/translatable/TranslatableRegistry.java b/src/main/java/us/mytheria/bloblib/entities/translatable/TranslatableRegistry.java index 817f9029..ac43911c 100644 --- a/src/main/java/us/mytheria/bloblib/entities/translatable/TranslatableRegistry.java +++ b/src/main/java/us/mytheria/bloblib/entities/translatable/TranslatableRegistry.java @@ -1,6 +1,7 @@ package us.mytheria.bloblib.entities.translatable; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.Map; @@ -59,7 +60,7 @@ public boolean process(@NotNull T translatable) { * @param locale the locale to get the carrier for * @return the carrier for the specified locale, or the default if it doesn't exist */ - @NotNull + @Nullable public T get(String locale) { T result = this.translatables.get(locale); if (result == null) diff --git a/src/main/java/us/mytheria/bloblib/managers/BlobLibFileManager.java b/src/main/java/us/mytheria/bloblib/managers/BlobLibFileManager.java index 3b1944ca..6a2f8f06 100644 --- a/src/main/java/us/mytheria/bloblib/managers/BlobLibFileManager.java +++ b/src/main/java/us/mytheria/bloblib/managers/BlobLibFileManager.java @@ -50,17 +50,23 @@ public void loadFiles() { if (!inventories.exists()) inventories.mkdir(); if (!metaInventories.exists()) metaInventories.mkdir(); if (!actions.exists()) actions.mkdir(); + if (!snippets.exists()) snippets.mkdir(); + if (!blocks.exists()) blocks.mkdir(); /////////////////////////////////////////// if (!defaultSounds.exists()) defaultSounds.createNewFile(); if (!defaultMessages.exists()) defaultMessages.createNewFile(); if (!defaultInventories.exists()) defaultInventories.createNewFile(); if (!defaultMetaInventories.exists()) defaultMetaInventories.createNewFile(); if (!defaultActions.exists()) defaultActions.createNewFile(); + if (!defaultSnippets.exists()) defaultSnippets.createNewFile(); + if (!defaultBlocks.exists()) defaultBlocks.createNewFile(); ResourceUtil.updateYml(sounds, "/tempbloblib_sounds.yml", "bloblib_sounds.yml", defaultSounds, plugin); ResourceUtil.updateYml(messages, "/tempbloblib_lang.yml", "bloblib_lang.yml", defaultMessages, plugin); ResourceUtil.updateYml(inventories, "/tempInventories.yml", "bloblib_inventories.yml", defaultInventories, plugin); ResourceUtil.updateYml(metaInventories, "/tempMetaInventories.yml", "bloblib_meta_inventories.yml", defaultMetaInventories, plugin); ResourceUtil.updateYml(actions, "/tempActions.yml", "bloblib_actions.yml", defaultActions, plugin); + ResourceUtil.updateYml(snippets, "/tempTranslatableSnippets.yml", "bloblib_translatable_snippets.yml", defaultSnippets, plugin); + ResourceUtil.updateYml(blocks, "/tempTranslatableBlocks.yml", "bloblib_translatable_blocks.yml", defaultBlocks, plugin); } catch (Exception e) { e.printStackTrace(); } diff --git a/src/main/java/us/mytheria/bloblib/managers/TranslatableManager.java b/src/main/java/us/mytheria/bloblib/managers/TranslatableManager.java index e5d33f8f..76e70ef9 100644 --- a/src/main/java/us/mytheria/bloblib/managers/TranslatableManager.java +++ b/src/main/java/us/mytheria/bloblib/managers/TranslatableManager.java @@ -12,10 +12,7 @@ import us.mytheria.bloblib.entities.translatable.TranslatableSnippet; import java.io.File; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; +import java.util.*; public class TranslatableManager { private final BlobLib main; @@ -136,8 +133,9 @@ private void loadBlocks(File path) { private void loadSnippet(BlobPlugin plugin, File file) { String fileName = FilenameUtils.removeExtension(file.getName()); YamlConfiguration yamlConfiguration = YamlConfiguration.loadConfiguration(file); - if (yamlConfiguration.contains("Size") && yamlConfiguration.isInt("Size")) { - addSnippet(fileName, TranslatableReader.SNIPPET(yamlConfiguration, fileName)); + String locale = yamlConfiguration.getString("Locale", "en_us"); + if (yamlConfiguration.isString("Snippet")) { + addSnippet(fileName, TranslatableReader.SNIPPET(yamlConfiguration, locale)); pluginSnippets.get(plugin.getName()).add(fileName); return; } @@ -145,9 +143,9 @@ private void loadSnippet(BlobPlugin plugin, File file) { if (!yamlConfiguration.isConfigurationSection(reference)) return; ConfigurationSection section = yamlConfiguration.getConfigurationSection(reference); - if (!section.contains("Size") && !section.isInt("Size")) + if (!section.isString("Snippet")) return; - addSnippet(reference, TranslatableReader.SNIPPET(section, reference)); + addSnippet(reference, TranslatableReader.SNIPPET(section, locale)); pluginSnippets.get(plugin.getName()).add(reference); }); } @@ -155,8 +153,9 @@ private void loadSnippet(BlobPlugin plugin, File file) { private void loadBlock(BlobPlugin plugin, File file) { String fileName = FilenameUtils.removeExtension(file.getName()); YamlConfiguration yamlConfiguration = YamlConfiguration.loadConfiguration(file); - if (yamlConfiguration.contains("Size") && yamlConfiguration.isInt("Size")) { - addBlock(fileName, TranslatableReader.BLOCK(yamlConfiguration, fileName)); + String locale = yamlConfiguration.getString("Locale", "en_us"); + if (!yamlConfiguration.getStringList("Block").isEmpty()) { + addBlock(fileName, TranslatableReader.BLOCK(yamlConfiguration, locale)); pluginBlocks.get(plugin.getName()).add(fileName); return; } @@ -164,9 +163,9 @@ private void loadBlock(BlobPlugin plugin, File file) { if (!yamlConfiguration.isConfigurationSection(reference)) return; ConfigurationSection section = yamlConfiguration.getConfigurationSection(reference); - if (!section.contains("Size") && !section.isInt("Size")) + if (section.getStringList("Block").isEmpty()) return; - addBlock(reference, TranslatableReader.BLOCK(section, reference)); + addBlock(reference, TranslatableReader.BLOCK(section, locale)); pluginBlocks.get(plugin.getName()).add(reference); }); } @@ -179,7 +178,6 @@ public static void continueLoadingSnippets(BlobPlugin plugin, boolean warnDuplic manager.loadSnippet(plugin, file); } catch (Throwable e) { e.printStackTrace(); - continue; } } if (warnDuplicates) @@ -199,7 +197,6 @@ public static void continueLoadingBlocks(BlobPlugin plugin, boolean warnDuplicat manager.loadBlock(plugin, file); } catch (Throwable e) { e.printStackTrace(); - continue; } } if (warnDuplicates) @@ -215,34 +212,36 @@ public static void continueLoadingBlocks(BlobPlugin plugin, File... files) { private void loadSnippet(File file) { String fileName = FilenameUtils.removeExtension(file.getName()); YamlConfiguration yamlConfiguration = YamlConfiguration.loadConfiguration(file); - if (yamlConfiguration.contains("Size") && yamlConfiguration.isInt("Size")) { - addSnippet(fileName, TranslatableReader.SNIPPET(yamlConfiguration, fileName)); + String locale = yamlConfiguration.getString("Locale", "en_us"); + if (yamlConfiguration.isString("Snippet")) { + addSnippet(fileName, TranslatableReader.SNIPPET(yamlConfiguration, locale)); return; } yamlConfiguration.getKeys(true).forEach(reference -> { if (!yamlConfiguration.isConfigurationSection(reference)) return; ConfigurationSection section = yamlConfiguration.getConfigurationSection(reference); - if (!section.contains("Size") && !section.isInt("Size")) + if (!section.isString("Snippet")) return; - addSnippet(reference, TranslatableReader.SNIPPET(section, reference)); + addSnippet(reference, TranslatableReader.SNIPPET(section, locale)); }); } private void loadBlock(File file) { String fileName = FilenameUtils.removeExtension(file.getName()); YamlConfiguration yamlConfiguration = YamlConfiguration.loadConfiguration(file); - if (yamlConfiguration.contains("Size") && yamlConfiguration.isInt("Size")) { - addBlock(fileName, TranslatableReader.BLOCK(yamlConfiguration, fileName)); + String locale = yamlConfiguration.getString("Locale", "en_us"); + if (!yamlConfiguration.getStringList("Block").isEmpty()) { + addBlock(fileName, TranslatableReader.BLOCK(yamlConfiguration, locale)); return; } yamlConfiguration.getKeys(true).forEach(reference -> { if (!yamlConfiguration.isConfigurationSection(reference)) return; ConfigurationSection section = yamlConfiguration.getConfigurationSection(reference); - if (!section.contains("Size") && !section.isInt("Size")) + if (section.getStringList("Block").isEmpty()) return; - addBlock(reference, TranslatableReader.BLOCK(section, reference)); + addBlock(reference, TranslatableReader.BLOCK(section, locale)); }); } @@ -264,7 +263,11 @@ public TranslatableSnippet getSnippet(String key, String locale) { TranslatableRegistry registry = getSnippetRegistry(key); if (registry == null) return null; - return registry.get(locale); + TranslatableSnippet snippet = registry.get(locale); + if (snippet == null) + return registry.getDefault(); + Objects.requireNonNull(snippet, "Snippet '" + key + "' does not have a default locale and is not available in '" + locale + "'"); + return snippet; } @Nullable @@ -285,7 +288,11 @@ public TranslatableBlock getBlock(String key, String locale) { TranslatableRegistry registry = getBlockRegistry(key); if (registry == null) return null; - return registry.get(locale); + TranslatableBlock block = registry.get(locale); + if (block == null) + return registry.getDefault(); + Objects.requireNonNull(block, "Block '" + key + "' does not have a default locale and is not available in '" + locale + "'"); + return block; } @Nullable @@ -296,25 +303,27 @@ public TranslatableBlock getBlock(String key) { return registry.getDefault(); } - private void addSnippet(String key, TranslatableSnippet inventory) { + private void addSnippet(String key, TranslatableSnippet snippet) { TranslatableRegistry registry = snippets.get(key); if (registry == null) registry = TranslatableRegistry.of("en_us", key); - if (!registry.process(inventory)) { + if (!registry.process(snippet)) { addDuplicate(key); return; } + BlobLib.getAnjoLogger().debug("loaded Snippet: " + key + " with locale: " + snippet.getLocale()); snippets.put(key, registry); } - private void addBlock(String key, TranslatableBlock inventory) { + private void addBlock(String key, TranslatableBlock block) { TranslatableRegistry registry = blocks.get(key); if (registry == null) registry = TranslatableRegistry.of("en_us", key); - if (!registry.process(inventory)) { + if (!registry.process(block)) { addDuplicate(key); return; } + BlobLib.getAnjoLogger().debug("loaded Block: " + key + " with locale: " + block.getLocale()); blocks.put(key, registry); } } diff --git a/src/main/java/us/mytheria/bloblib/placeholderapi/TranslatablePH.java b/src/main/java/us/mytheria/bloblib/placeholderapi/TranslatablePH.java new file mode 100644 index 00000000..94b0b7c5 --- /dev/null +++ b/src/main/java/us/mytheria/bloblib/placeholderapi/TranslatablePH.java @@ -0,0 +1,51 @@ +package us.mytheria.bloblib.placeholderapi; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import us.mytheria.bloblib.BlobLib; +import us.mytheria.bloblib.api.BlobLibTranslatableAPI; +import us.mytheria.bloblib.entities.BlobPHExpansion; +import us.mytheria.bloblib.entities.translatable.TranslatableSnippet; + +import java.util.Objects; + +public class TranslatablePH { + private static TranslatablePH instance; + private BlobPHExpansion expansion; + + @NotNull + public static TranslatablePH getInstance(@NotNull BlobLib plugin) { + if (instance == null) { + Objects.requireNonNull(plugin, "injected dependency is null"); + instance = new TranslatablePH(plugin); + } + return instance; + } + + private TranslatablePH(@NotNull BlobLib plugin) { + instance = this; + if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") == null) { + BlobLib.getAnjoLogger().log("PlaceholderAPI not found, not registering Translatabe PlaceholderAPI expansion"); + return; + } + BlobPHExpansion expansion = new BlobPHExpansion(plugin, "translatable"); + this.expansion = expansion; + expansion.putStartsWith("snippet_", (offlinePlayer, key) -> { + Player player = Bukkit.getPlayer(offlinePlayer.getUniqueId()); + TranslatableSnippet snippet; + if (player == null) + snippet = BlobLibTranslatableAPI.getInstance().getTranslatableSnippet(key); + else + snippet = BlobLibTranslatableAPI.getInstance().getTranslatableSnippet(key, player); + if (snippet == null) + return ChatColor.RED + key; + return snippet.get(); + }); + } + + public BlobPHExpansion getExpansion() { + return expansion; + } +} diff --git a/src/main/resources/bloblib_translatable_blocks.yml b/src/main/resources/bloblib_translatable_blocks.yml new file mode 100644 index 00000000..f1e59c55 --- /dev/null +++ b/src/main/resources/bloblib_translatable_blocks.yml @@ -0,0 +1,7 @@ +BlobLib: + Select-Element: + Block: + - '&7Click to select' + Remove-Element: + Block: + - '&7Click to remove' \ No newline at end of file diff --git a/src/main/resources/bloblib_translatable_snippets.yml b/src/main/resources/bloblib_translatable_snippets.yml new file mode 100644 index 00000000..3c23199a --- /dev/null +++ b/src/main/resources/bloblib_translatable_snippets.yml @@ -0,0 +1,7 @@ +BlobLib: + Boolean-True: + Snippet: 'true' + Boolean-False: + Snippet: 'false' + Player-Not-Online: + Snippet: 'not online' \ No newline at end of file