From 66130b2f63a1bcbb814f9a9a89668ef9ddf03a0d Mon Sep 17 00:00:00 2001 From: Lilly <46890129+RainbowDashLabs@users.noreply.github.com> Date: Sat, 27 Jul 2024 11:52:58 +0200 Subject: [PATCH] Add per user locale --- build.gradle.kts | 2 +- .../localization/ILocalizer.java | 64 ++++++- .../eldoutilities/localization/Localizer.java | 163 ++++++++++++++---- .../localization/LocalizerBuilder.java | 45 +++++ .../eldoutilities/messages/MessageSender.java | 48 ++++-- .../messages/MessageSenderBuilder.java | 11 -- .../eldoutilities/messages/Replacement.java | 75 +++++++- .../messages/impl/PaperMessageSender.java | 8 +- .../messages/impl/SpigotMessageSender.java | 8 +- 9 files changed, 347 insertions(+), 77 deletions(-) create mode 100644 localization/src/main/java/de/eldoria/eldoutilities/localization/LocalizerBuilder.java diff --git a/build.gradle.kts b/build.gradle.kts index 4f94a9fd..f5be4d26 100755 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -17,7 +17,7 @@ plugins { publishData { addRepo(Repo.main("", "", false)) addRepo(Repo.snapshot("SNAPSHOT", "", false)) - publishingVersion = "2.0.11" + publishingVersion = "2.1.0" } version = publishData.getVersion() diff --git a/core/src/main/java/de/eldoria/eldoutilities/localization/ILocalizer.java b/core/src/main/java/de/eldoria/eldoutilities/localization/ILocalizer.java index b473cddd..a90026d9 100644 --- a/core/src/main/java/de/eldoria/eldoutilities/localization/ILocalizer.java +++ b/core/src/main/java/de/eldoria/eldoutilities/localization/ILocalizer.java @@ -6,13 +6,13 @@ package de.eldoria.eldoutilities.localization; +import org.bukkit.command.CommandSender; import org.bukkit.plugin.Plugin; -import org.intellij.lang.annotations.Language; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.PropertyKey; import java.util.HashMap; import java.util.Map; +import java.util.ResourceBundle; import java.util.regex.Pattern; /** @@ -78,9 +78,23 @@ static boolean isLocaleCode(String message) { */ void addLocaleCodes(Map runtimeLocaleCodes); + String getMessage(String key, CommandSender sender); + @Nullable String getValue(String key); + String getMessage(String key, String language); + + @Nullable + String getValue(String key, CommandSender sender); + + @Nullable + String getValue(String key, String language); + + ResourceBundle localeBundle(String language); + + ResourceBundle defaultBundle(); + /** * Translates a String with Placeholders. Can handle multiple messages with replacements. Add replacements in the * right order. @@ -89,7 +103,19 @@ static boolean isLocaleCode(String message) { * @return Replaced Messages * @since 1.2.3 */ - String localize(String message); + default String localize(String message) { + return localize(null, message); + } + + /** + * Translates a String with Placeholders. Can handle multiple messages with replacements. Add replacements in the + * right order. + * + * @param message Message to translate + * @return Replaced Messages + * @since 1.2.3 + */ + String localize(CommandSender sender, String message); void registerChild(ILocalizer localizer); @@ -112,13 +138,43 @@ public String[] getIncludedLocales() { public void addLocaleCodes(Map runtimeLocaleCodes) { } + @Override + public String getMessage(String key, CommandSender sender) { + return key; + } + @Override public @Nullable String getValue(String key) { + return key; + } + + @Override + public String getMessage(String key, String language) { + return key; + } + + @Override + public @Nullable String getValue(String key, CommandSender sender) { + return key; + } + + @Override + public @Nullable String getValue(String key, String language) { + return key; + } + + @Override + public ResourceBundle localeBundle(String language) { + return null; + } + + @Override + public ResourceBundle defaultBundle() { return null; } @Override - public String localize(String message) { + public String localize(CommandSender sender, String message) { return message; } diff --git a/localization/src/main/java/de/eldoria/eldoutilities/localization/Localizer.java b/localization/src/main/java/de/eldoria/eldoutilities/localization/Localizer.java index 4614da93..28a01d27 100644 --- a/localization/src/main/java/de/eldoria/eldoutilities/localization/Localizer.java +++ b/localization/src/main/java/de/eldoria/eldoutilities/localization/Localizer.java @@ -6,6 +6,8 @@ package de.eldoria.eldoutilities.localization; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -30,6 +32,7 @@ import java.util.ResourceBundle; import java.util.Set; import java.util.TreeMap; +import java.util.function.Function; import java.util.logging.Level; import java.util.regex.Pattern; @@ -41,7 +44,7 @@ * Easy to use and fully automatic setup and updating of locales. *

* Requires to have at least one default locale and one fallback locale in the resources. Use the {@link - * #Localizer(Plugin, String, String, Locale, String...)} constructor for initial setup. This will create missing files + * #create(Plugin, String...) constructor for initial setup. This will create missing files * and updates existing files. *

* You can change the currently used locale every time via {@link #setLocale(String)}. @@ -53,26 +56,27 @@ @SuppressWarnings("unused") public class Localizer implements ILocalizer { - private final ResourceBundle fallbackBundle; + private String defaultLanguage; private final Plugin plugin; private final String localesPath; private final String localesPrefix; private final String[] includedLocales; private final Pattern localePattern = Pattern.compile("_(([a-zA-Z]{2})(_[a-zA-Z]{2})?)\\.properties"); private final Map runtimeLocaleCodes = new HashMap<>(); - List childs = new ArrayList<>(); - private ResourceBundle bundle; + private final Map languages = new HashMap<>(); + private final Function userLocale; + private final List childs = new ArrayList<>(); private boolean checked; /** * Create a new localizer instance. *

- * This instance will create locale files, which are provided in the resources directory. + * This instance will create locale files, which are provided in the "resources" directory. *

* After this it will update all locale files inside the locales directory. For this the ref keys from the internal * default locale file will be used. *

- * After a update check and a update if needed it will load the provided language or the fallback language if the + * After an update check and a update if needed it will load the provided language or the fallback language if the * provided language does not exist. * * @param plugin instance of plugin @@ -82,20 +86,22 @@ public class Localizer implements ILocalizer { * @param includedLocales internal provided locales */ Localizer(Plugin plugin, String localesPath, - String localesPrefix, Locale fallbackLocale, String... includedLocales) { + String localesPrefix, String fallbackLocale, Function userLocale, String... includedLocales) { this.plugin = plugin; this.localesPath = localesPath; this.localesPrefix = localesPrefix; + this.userLocale = userLocale; this.includedLocales = includedLocales; - ResourceBundle fallbackBundle = new DummyResourceBundle(); - try { - fallbackBundle = getBundle(fallbackLocale); - } catch (IOException e) { - plugin.getLogger().log(Level.SEVERE, "Could not read fallback file", e); + defaultLanguage = fallbackLocale; + loadLanguage(fallbackLocale); + if (languages.containsKey(fallbackLocale)) { + plugin.getLogger().log(Level.SEVERE, "Could not load default locale"); } - this.fallbackBundle = fallbackBundle; LOCALIZER.put(plugin.getClass(), this); createDefaults(); + for (String locale : includedLocales) { + loadLanguage(locale); + } } /** @@ -103,7 +109,7 @@ public class Localizer implements ILocalizer { *

* The message path and prefix will be "messages" and the fallback language the "en_US" locale. *

- * This instance will create locale files, which are provided in the resources directory. + * This instance will create locale files, which are provided in the "resources" directory. *

* After this it will update all locale files inside the locales directory. For this the ref keys from the internal * default locale file will be used. @@ -114,7 +120,9 @@ public class Localizer implements ILocalizer { * @param plugin instance of plugin * @param includedLocales internal provided locales * @return the created localizer instance + * @deprecated Use the builder provided by {@link #builder(Plugin, String)} */ + @Deprecated(forRemoval = true) public static ILocalizer create(Plugin plugin, String... includedLocales) { return create(plugin, "messages", "messages", Locale.US, includedLocales); @@ -123,7 +131,7 @@ public static ILocalizer create(Plugin plugin, /** * Create a new localizer instance. *

- * This instance will create locale files, which are provided in the resources directory. + * This instance will create locale files, which are provided in the "resources" directory. *

* After this it will update all locale files inside the locales directory. For this the ref keys from the internal * default locale file will be used. @@ -137,14 +145,20 @@ public static ILocalizer create(Plugin plugin, * @param fallbackLocale fallbackLocale * @param includedLocales internal provided locales * @return the created localizer instance + * @deprecated Use the builder provided by {@link #builder(Plugin, String)} */ + @Deprecated(forRemoval = true) public static ILocalizer create(Plugin plugin, String localesPath, String localesPrefix, Locale fallbackLocale, String... includedLocales) { - ILocalizer localizer = new Localizer(plugin, localesPath, localesPrefix, fallbackLocale, includedLocales); + ILocalizer localizer = new LocalizerBuilder(plugin, fallbackLocale.toLanguageTag()).setLocalesPath(localesPath).setLocalesPrefix(localesPrefix).setUserLocale(e -> fallbackLocale.toLanguageTag()).setIncludedLocales(includedLocales).build(); LOCALIZER.put(plugin.getClass(), localizer); return localizer; } + public static LocalizerBuilder builder(Plugin plugin, String defaultLocale) { + return new LocalizerBuilder(plugin, defaultLocale); + } + private void createDefaults() { Map locales = new HashMap<>(); locales.put("error.invalidArguments", "Invalid arguments.\nSyntax: "); @@ -183,30 +197,54 @@ private void createDefaults() { * Change the locale to the language. If the locale is not present the fallback locale will be used. * * @param language language to be used + * @deprecated Use */ @Override + @Deprecated(forRemoval = true) public void setLocale(String language) { if (!checked) { createOrUpdateLocaleFiles(); checked = true; } - try { - this.bundle = getBundle(getLocaleFile(language)); - } catch (IOException e) { - plugin.getLogger().log(Level.WARNING, "Could not load locale file " + getLocaleFile(language), e); - this.bundle = fallbackBundle; - } + setDefaultLocale(language); } - /** - * Translates a String with Placeholders. Can handle multiple messages with replacements. - * - * @param key Key of message - * @return Replaced Messages - */ @Override public String getMessage(String key) { + return getMessage(key, (CommandSender) null); + } + + + public void setDefaultLocale(String language) { + if (!checked) { + createOrUpdateLocaleFiles(); + checked = true; + } + + if (!languages.containsKey(language)) { + plugin.getLogger().log(Level.WARNING, "Language %s does not exist".formatted(language)); + return; + } + this.defaultLanguage = language; + } + + + @Override + public String getMessage(String key, @Nullable CommandSender sender) { + if (sender instanceof Player player) { + return getMessage(key, userLocale.apply(player)); + } + return getMessage(key, defaultLanguage); + } + + @Override + public @Nullable String getValue(String key) { + return getValue(key, (CommandSender) null); + } + + @Override + public String getMessage(String key, String language) { var result = getValue(key); if (result == null && LOCALIZATION_CODE.matcher(key).matches()) { @@ -220,18 +258,27 @@ public String getMessage(String key) { @Override @Nullable - public String getValue(String key) { + public String getValue(String key, CommandSender sender) { + if (sender instanceof Player player) { + return getValue(key, userLocale.apply(player)); + } + return getValue(key, defaultLanguage); + } + + @Override + @Nullable + public String getValue(String key, String language) { String result = null; - if (bundle.containsKey(key)) { + if (localeBundle(language).containsKey(key)) { try { - result = bundle.getString(key); + result = localeBundle(key).getString(key); } catch (MissingResourceException e) { // ignore } } - if (result == null && fallbackBundle.containsKey(key)) { + if (result == null && localeBundle(defaultLanguage).containsKey(key)) { try { - result = fallbackBundle.getString(key); + result = localeBundle(defaultLanguage).getString(key); } catch (MissingResourceException e) { // ignore } @@ -239,13 +286,39 @@ public String getValue(String key) { if (result == null) { for (var child : childs) { - result = child.getValue(key); + result = child.getValue(key, language); if (result != null) break; } } return result; } + @Override + public ResourceBundle localeBundle(String language) { + ResourceBundle resourceBundle = languages.get(language); + if (resourceBundle == null) { + plugin.getLogger().severe("Language %s not found".formatted(language)); + if (language.equals(defaultLanguage)) { + throw new RuntimeException("Fallback language is not registered."); + } + return localeBundle(defaultLanguage); + } + return resourceBundle; + } + + @Override + public ResourceBundle defaultBundle() { + return localeBundle(defaultLanguage); + } + + private void loadLanguage(String language) { + try { + languages.put(language, getBundle(getLocaleFile(language))); + } catch (IOException e) { + plugin.getLogger().log(Level.WARNING, "Failed to load language %s.".formatted(language), e); + } + } + private Path getLocalePath() { return plugin.getDataFolder().toPath().resolve(localesPath); } @@ -286,7 +359,7 @@ private boolean isLocaleFile(Path path) { return false; } - private ResourceBundle getDefaultBundle() throws IOException { + private ResourceBundle getDefaultLanguage() throws IOException { try (var input = plugin.getResource(localesPrefix + ".properties")) { if (input == null) { plugin.getLogger().severe("Could not load locale file " + localesPrefix + ".properties. Does it exist?"); @@ -301,7 +374,7 @@ private ResourceBundle getBundle(String locale) throws IOException { try (var input = plugin.getResource(getLocaleFileName(locale))) { if (input == null) { plugin.getLogger().severe("Could not load locale file " + getLocaleFileName(locale) + ".properties. Does it exist?"); - return getDefaultBundle(); + return getDefaultLanguage(); } return new PropertyResourceBundle(input); } @@ -309,7 +382,7 @@ private ResourceBundle getBundle(String locale) throws IOException { private ResourceBundle getBundle(Locale locale) throws IOException { if (locale == null) { - return getDefaultBundle(); + return getDefaultLanguage(); } return getBundle(locale.toString()); } @@ -329,7 +402,7 @@ private Map bundleMap(Path path) throws IOException { } private Set getDefaultKeys() throws IOException { - Set defaultKeys = new HashSet<>(Collections.list(getDefaultBundle().getKeys())); + Set defaultKeys = new HashSet<>(Collections.list(getDefaultLanguage().getKeys())); defaultKeys.addAll(runtimeLocaleCodes.keySet()); return defaultKeys; } @@ -454,6 +527,20 @@ public String localize(String message) { return message; } + @Override + public String localize(CommandSender sender, String message) { + if (message == null) { + return null; + } + + // Check if input is a locale key. + if (isLocaleCode(message)) { + message = getMessage(message, sender); + } + + return message; + } + /** * Get currently registered locales. * diff --git a/localization/src/main/java/de/eldoria/eldoutilities/localization/LocalizerBuilder.java b/localization/src/main/java/de/eldoria/eldoutilities/localization/LocalizerBuilder.java new file mode 100644 index 00000000..d91cd167 --- /dev/null +++ b/localization/src/main/java/de/eldoria/eldoutilities/localization/LocalizerBuilder.java @@ -0,0 +1,45 @@ +package de.eldoria.eldoutilities.localization; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import java.util.function.Function; + +public class LocalizerBuilder { + private Plugin plugin; + private String localesPath = "messages"; + private String localesPrefix = "messages"; + private String fallbackLocale; + private Function userLocale; + private String[] includedLocales = new String[0]; + + LocalizerBuilder(Plugin plugin, String fallbackLocale) { + this.plugin = plugin; + this.fallbackLocale = fallbackLocale; + userLocale = p -> fallbackLocale; + } + + public LocalizerBuilder setLocalesPath(String localesPath) { + this.localesPath = localesPath; + return this; + } + + public LocalizerBuilder setLocalesPrefix(String localesPrefix) { + this.localesPrefix = localesPrefix; + return this; + } + + public LocalizerBuilder setUserLocale(Function userLocale) { + this.userLocale = userLocale; + return this; + } + + public LocalizerBuilder setIncludedLocales(String... includedLocales) { + this.includedLocales = includedLocales; + return this; + } + + public Localizer build() { + return new Localizer(plugin, localesPath, localesPrefix, fallbackLocale, userLocale, includedLocales); + } +} diff --git a/messaging/src/main/java/de/eldoria/eldoutilities/messages/MessageSender.java b/messaging/src/main/java/de/eldoria/eldoutilities/messages/MessageSender.java index 94fc406f..19b42995 100644 --- a/messaging/src/main/java/de/eldoria/eldoutilities/messages/MessageSender.java +++ b/messaging/src/main/java/de/eldoria/eldoutilities/messages/MessageSender.java @@ -12,7 +12,10 @@ import net.kyori.adventure.audience.Audience; import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.Context; import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.Tag; +import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import net.kyori.adventure.title.Title; @@ -113,7 +116,7 @@ private MessageSender update(MiniMessage miniMessage, TagResolver messageTagReso * @param message message with optional color codes */ public void sendMessage(CommandSender sender, String message, TagResolver... placeholder) { - sendMessage(sender, serialize(message, messageTagResolver, placeholder)); + sendMessage(sender, serialize(sender, message, messageTagResolver, placeholder)); } @@ -131,7 +134,7 @@ public void sendMessage(CommandSender sender, String message, TagResolver... pla * @param composer message composer */ public void sendMessage(CommandSender sender, IMessageComposer composer) { - sendMessage(sender, serialize(composer.build(), messageTagResolver, + sendMessage(sender, serialize(sender, composer.build(), messageTagResolver, composer.replacements().toArray(new TagResolver[0]))); } @@ -149,7 +152,7 @@ public void sendMessage(CommandSender sender, IMessageComposer composer) { * @param message message with optinal color codes */ public void sendError(CommandSender sender, String message, TagResolver... placeholder) { - sendMessage(sender, serialize(message, errorTagResolver, placeholder)); + sendMessage(sender, serialize(sender, message, errorTagResolver, placeholder)); } /** @@ -166,7 +169,7 @@ public void sendError(CommandSender sender, String message, TagResolver... place * @param composer message composer */ public void sendError(CommandSender sender, IMessageComposer composer) { - sendMessage(sender, serialize(composer.build(), errorTagResolver, + sendMessage(sender, serialize(sender, composer.build(), errorTagResolver, composer.replacements().toArray(new TagResolver[0]))); } @@ -181,7 +184,7 @@ public void sendError(CommandSender sender, IMessageComposer composer) { * @param title title to send */ public void sendTitle(Player player, String title, String subtitle, Title.Times times, TagResolver... placeholder) { - sendTitle(player, Title.title(serialize(title, messageTagResolver, placeholder), serialize(subtitle, messageTagResolver, placeholder), times)); + sendTitle(player, Title.title(serialize(player, title, messageTagResolver, placeholder), serialize(player, subtitle, messageTagResolver, placeholder), times)); } /** @@ -218,7 +221,7 @@ private ILocalizer loc() { return ILocalizer.getPluginLocalizer(ownerPlugin); } - protected Component serialize(String message, TagResolver resolver, TagResolver... placeholder) { + protected Component serialize(CommandSender sender, String message, TagResolver resolver, TagResolver... placeholder) { var converted = MiniMessageConversion.convertLegacyColorCodes(message); if (!converted.equals(message)) { plugin.getLogger().warning("Found legacy color codes in message."); @@ -235,7 +238,7 @@ protected Component serialize(String message, TagResolver resolver, TagResolver. tags[tags.length - 1] = resolver; finalResolver = tags; } - return resolveTags(message, finalResolver); + return resolveTags(message, addI18nTag(sender, TagResolver.resolver(finalResolver))); } private Component resolveTags(String message, TagResolver... resolver) { @@ -255,22 +258,47 @@ protected Component applyPrefix(Component component) { return prefix.appendSpace().append(component); } + public String translatePlain(String message, TagResolver... replacements) { - return PlainTextComponentSerializer.plainText().serialize(serialize(message, messageTagResolver, replacements)); + return translatePlain(null, message, replacements); + } + + public String translatePlain(@Nullable CommandSender sender, String message, TagResolver... replacements) { + return PlainTextComponentSerializer.plainText().serialize(serialize(sender, message, messageTagResolver, replacements)); } public Component serializeMessage(String message, TagResolver... placeholder) { - return serialize(message, messageTagResolver, placeholder); + return serializeMessage(null, message, placeholder); + } + public Component serializeMessage(@Nullable CommandSender sender, String message, TagResolver... placeholder) { + return serialize(sender, message, messageTagResolver, placeholder); } public Component serializeError(String message, TagResolver... placeholder) { - return serialize(message, errorTagResolver, placeholder); + return serializeError(null, message, placeholder); + } + + public Component serializeError(@Nullable CommandSender sender, String message, TagResolver... placeholder) { + return serialize(sender, message, errorTagResolver, placeholder); } public MiniMessage miniMessage() { return miniMessage; } + private TagResolver addI18nTag(CommandSender sender, TagResolver resolvers) { + if (loc() != ILocalizer.DEFAULT) { + return TagResolver.resolver(resolvers, TagResolver.builder() + .tag("i18n", (argumentQueue, context) -> localizeTag(sender, argumentQueue, context)).build()); + } + return resolvers; + } + + private net.kyori.adventure.text.minimessage.tag.Tag localizeTag(CommandSender sender, ArgumentQueue args, Context ctx) { + return Tag.selfClosingInserting(ctx.deserialize(loc().localize(sender, args.popOr("locale tag required").value()))); + } + + public boolean isAnonymous() { return ownerPlugin == null; } diff --git a/messaging/src/main/java/de/eldoria/eldoutilities/messages/MessageSenderBuilder.java b/messaging/src/main/java/de/eldoria/eldoutilities/messages/MessageSenderBuilder.java index e68f0318..208466e7 100644 --- a/messaging/src/main/java/de/eldoria/eldoutilities/messages/MessageSenderBuilder.java +++ b/messaging/src/main/java/de/eldoria/eldoutilities/messages/MessageSenderBuilder.java @@ -116,7 +116,6 @@ public MessageSenderBuilder preProcessor(@NotNull UnaryOperator preProce * @return registered message sender */ public MessageSender register() { - addI18nTag(); var defaultResolver = defaultTagResolver .resolver(StandardTags.defaults()) .build(); @@ -141,14 +140,4 @@ public MessageSender register() { MessageSender.register(messageSender); return messageSender; } - - private void addI18nTag() { - if (localizer != ILocalizer.DEFAULT) { - defaultTagResolver.tag("i18n", this::localizeTag); - } - } - - private Tag localizeTag(ArgumentQueue args, Context ctx) { - return Tag.selfClosingInserting(ctx.deserialize(localizer.localize(args.popOr("locale tag required").value()))); - } } diff --git a/messaging/src/main/java/de/eldoria/eldoutilities/messages/Replacement.java b/messaging/src/main/java/de/eldoria/eldoutilities/messages/Replacement.java index 4c6829ef..dabc81c8 100644 --- a/messaging/src/main/java/de/eldoria/eldoutilities/messages/Replacement.java +++ b/messaging/src/main/java/de/eldoria/eldoutilities/messages/Replacement.java @@ -6,8 +6,6 @@ package de.eldoria.eldoutilities.messages; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.bukkit.World; @@ -31,7 +29,18 @@ private Replacement() { * @return replacement with registered replacement */ public static TagResolver create(String key, String value) { - return Placeholder.parsed(sanatizeKey(key), value); + return Placeholder.parsed(sanitizeKey(key), value); + } + + /** + * Creates a new replacement. + * + * @param key key of replacement + * @param value value for replacement + * @return replacement with registered replacement + */ + public static TagResolver replacement(String key, String value) { + return create(key, value); } /** @@ -42,13 +51,36 @@ public static TagResolver create(String key, String value) { * @return replacement with registered replacement */ public static TagResolver create(String key, Object value) { - return Placeholder.parsed(sanatizeKey(key), String.valueOf(value)); + return Placeholder.parsed(sanitizeKey(key), String.valueOf(value)); + } + + /** + * Creates a new replacement. + * + * @param key key of replacement + * @param value value for replacement + * @return replacement with registered replacement + */ + public static TagResolver replacement(String key, Object value) { + return create(key, value); } public static TagResolver create(String key, Double value) { return create(key, String.format("%.2f", value)); } + public static TagResolver create(String key, Float value) { + return create(key, String.format("%.2f", value)); + } + + public static TagResolver number(String key, Double value) { + return create(key, value); + } + + public static TagResolver number(String key, Float value) { + return create(key, value); + } + /** * Creates a new replacement. * @@ -60,6 +92,17 @@ public static TagResolver create(String key, Enum anEnum) { return create(key, anEnum.name()); } + /** + * Creates a new replacement. + * + * @param key key of replacement + * @param anEnum value which provides a string via {@link Enum#name()} + * @return replacement with registered replacement + */ + public static TagResolver name(String key, Enum anEnum) { + return create(key, anEnum); + } + /** * Creates a new replacement for a player. * @@ -71,6 +114,17 @@ public static TagResolver create(String key, Player player) { return create(key, player.getName()); } + /** + * Creates a new replacement for a player. + * + * @param key key of replacement + * @param player value which provides the name of the player + * @return replacement with registered replacement + */ + public static TagResolver player(String key, Player player) { + return create(key, player); + } + /** * Creates a new replacement for a player. * @@ -82,7 +136,18 @@ public static TagResolver create(String key, World world) { return create(key, world.getName()); } - private static String sanatizeKey(String key){ + /** + * Creates a new replacement for a player. + * + * @param key key of replacement + * @param world world which provides the name of the world + * @return replacement with registered replacement + */ + public static TagResolver world(String key, World world) { + return create(key, world); + } + + private static String sanitizeKey(String key) { return key.toLowerCase(Locale.ROOT).replaceAll(" ", "_"); } } diff --git a/messaging/src/main/java/de/eldoria/eldoutilities/messages/impl/PaperMessageSender.java b/messaging/src/main/java/de/eldoria/eldoutilities/messages/impl/PaperMessageSender.java index 2f8166ab..729dd451 100644 --- a/messaging/src/main/java/de/eldoria/eldoutilities/messages/impl/PaperMessageSender.java +++ b/messaging/src/main/java/de/eldoria/eldoutilities/messages/impl/PaperMessageSender.java @@ -30,7 +30,7 @@ public void sendMessage(CommandSender sender, Component component) { } public void broadcast(String message) { - plugin().getServer().broadcast(serialize(message, messageTagResolver())); + plugin().getServer().broadcast(serialize(null, message, messageTagResolver())); } /** @@ -50,7 +50,7 @@ public void sendTitle(Player player, Title title) { * @param message message to send */ public void sendActionBar(Player player, String message, TagResolver... placeholder) { - player.sendActionBar(serialize(message, messageTagResolver(), placeholder)); + player.sendActionBar(serialize(player, message, messageTagResolver(), placeholder)); } /** @@ -60,7 +60,7 @@ public void sendActionBar(Player player, String message, TagResolver... placehol * @param message message to send */ public void sendErrorActionBar(Player player, String message, TagResolver... placeholder) { - player.sendActionBar(serialize(message, errorTagResolver(), placeholder)); + player.sendActionBar(serialize(player, message, errorTagResolver(), placeholder)); } public void sendBossBar(Player player, BossBar bossBar) { @@ -68,7 +68,7 @@ public void sendBossBar(Player player, BossBar bossBar) { } public BossBar sendBossBar(Player player, String message, float progress, BossBar.Color color, BossBar.Overlay overlay, Set flags) { - var bossBar = BossBar.bossBar(serialize(message, messageTagResolver()), progress, color, overlay, flags); + var bossBar = BossBar.bossBar(serialize(player, message, messageTagResolver()), progress, color, overlay, flags); player.showBossBar(bossBar); return bossBar; } diff --git a/messaging/src/main/java/de/eldoria/eldoutilities/messages/impl/SpigotMessageSender.java b/messaging/src/main/java/de/eldoria/eldoutilities/messages/impl/SpigotMessageSender.java index cf326ba4..acd36032 100644 --- a/messaging/src/main/java/de/eldoria/eldoutilities/messages/impl/SpigotMessageSender.java +++ b/messaging/src/main/java/de/eldoria/eldoutilities/messages/impl/SpigotMessageSender.java @@ -32,7 +32,7 @@ public void sendMessage(CommandSender sender, Component component) { } public void broadcast(String message) { - audiences.all().sendMessage(serialize(message, messageTagResolver())); + audiences.all().sendMessage(serialize(null, message, messageTagResolver())); } /** @@ -52,7 +52,7 @@ public void sendTitle(Player player, Title title) { * @param message message to send */ public void sendActionBar(Player player, String message, TagResolver... placeholder) { - audiences.player(player).sendActionBar(serialize(message, messageTagResolver(), placeholder)); + audiences.player(player).sendActionBar(serialize(player, message, messageTagResolver(), placeholder)); } /** @@ -62,7 +62,7 @@ public void sendActionBar(Player player, String message, TagResolver... placehol * @param message message to send */ public void sendErrorActionBar(Player player, String message, TagResolver... placeholder) { - audiences.player(player).sendActionBar(serialize(message, errorTagResolver(), placeholder)); + audiences.player(player).sendActionBar(serialize(player, message, errorTagResolver(), placeholder)); } public void sendBossBar(Player player, BossBar bossBar) { @@ -70,7 +70,7 @@ public void sendBossBar(Player player, BossBar bossBar) { } public BossBar sendBossBar(Player player, String message, float progress, BossBar.Color color, BossBar.Overlay overlay, Set flags) { - var bossBar = BossBar.bossBar(serialize(message, messageTagResolver()), progress, color, overlay, flags); + var bossBar = BossBar.bossBar(serialize(player, message, messageTagResolver()), progress, color, overlay, flags); audiences.player(player).showBossBar(bossBar); return bossBar; }