Skip to content

Commit

Permalink
large refactoring to also process resolvers in embedded messages. Als…
Browse files Browse the repository at this point in the history
…o significant is Formattable.java interface and usage in Translator
  • Loading branch information
CubBossa committed Jan 14, 2024
1 parent a2114f2 commit 02e1ec9
Show file tree
Hide file tree
Showing 52 changed files with 911 additions and 457 deletions.
4 changes: 2 additions & 2 deletions TinyTranslations-bukkit/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>de.cubbossa</groupId>
<artifactId>TinyTranslations</artifactId>
<version>4.2.0</version>
<version>4.3.0</version>
</parent>

<artifactId>TinyTranslations-bukkit</artifactId>
Expand All @@ -28,7 +28,7 @@
<dependency>
<groupId>de.cubbossa</groupId>
<artifactId>TinyTranslations-common</artifactId>
<version>4.2.0</version>
<version>4.3.0</version>
</dependency>

<!--This adds the Spigot API artifact to the build -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.generator.WorldInfo;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.Nullable;
Expand All @@ -31,12 +32,15 @@ public final class TinyTranslationsBukkit extends TinyTranslations {
private TinyTranslationsBukkit() {}
private static BukkitAudiences audiences;

static {
applyBukkitObjectResolvers(NM.getObjectTypeResolverMap());
}

public static void enable(JavaPlugin plugin) {
audiences = BukkitAudiences.create(plugin);
TinyTranslations.enable(new File(plugin.getDataFolder(), "/../"));

global().addMessages(messageFieldsFromClass(BukkitGlobalMessages.class));
applyBukkitObjectResolvers(global().getObjectTypeResolverMap());
global().saveLocale(Locale.ENGLISH);
}

Expand All @@ -50,7 +54,6 @@ public static Translator application(JavaPlugin plugin) {
enable(plugin);
}
var app = application(plugin.getName());
applyBukkitObjectResolvers(app.getObjectTypeResolverMap());
return app;
}

Expand All @@ -75,11 +78,36 @@ public static void sendActionBar(CommandSender sender, ComponentLike message) {
audiences.sender(sender).sendActionBar(message);
}

public static void sendActionBarIfNotEmpty(CommandSender sender, ComponentLike message) {
Component c = message.asComponent();
if (c.equals(Component.empty())) {
return;
}
sendActionBar(sender, message);
}

public static void sendMessage(CommandSender sender, ComponentLike message) {
audiences.sender(sender).sendMessage(message);
}

public static void sendMessageIfNotEmpty(CommandSender sender, ComponentLike message) {
Component c = message.asComponent();
if (c.equals(Component.empty())) {
return;
}
sendMessage(sender, message);
}

private static void applyBukkitObjectResolvers(ObjectTagResolverMap map) {
map.put(PluginDescriptionFile.class, Map.of(
"name", PluginDescriptionFile::getName,
"fullName", PluginDescriptionFile::getFullName,
"authors", d -> String.join(", ", d.getAuthors()),
"version", PluginDescriptionFile::getVersion,
"api-version", PluginDescriptionFile::getAPIVersion,
"website", PluginDescriptionFile::getWebsite,
"contributors", PluginDescriptionFile::getContributors
));
map.put(Player.class, Map.of(
"name", Player::getName,
"uuid", Entity::getUniqueId,
Expand Down
2 changes: 1 addition & 1 deletion TinyTranslations-common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>de.cubbossa</groupId>
<artifactId>TinyTranslations</artifactId>
<version>4.2.0</version>
<version>4.3.0</version>
</parent>

<artifactId>TinyTranslations-common</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package de.cubbossa.tinytranslations;

import de.cubbossa.tinytranslations.nanomessage.Context;
import de.cubbossa.tinytranslations.nanomessage.tag.NanoResolver;
import de.cubbossa.tinytranslations.nanomessage.tag.ObjectTag;
import de.cubbossa.tinytranslations.util.ListSection;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentLike;
import net.kyori.adventure.text.JoinConfiguration;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.Formatter;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.jetbrains.annotations.NotNull;

import java.time.temporal.Temporal;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import static net.kyori.adventure.text.Component.text;

public interface Formattable<ReturnT> {

Collection<NanoResolver> getResolvers();


ReturnT formatted(TagResolver... resolver);

ReturnT formatted(NanoResolver... nanoResolver);

default ReturnT insertString(final @NotNull String key, String value) {
return formatted(Placeholder.unparsed(key, value));
}

default ReturnT insertStringLazy(final @NotNull String key, Supplier<String> value) {
return formatted(TagResolver.resolver(key, (argumentQueue, context) -> {
return Tag.preProcessParsed(value.get());
}));
}

default ReturnT insertComponent(final @NotNull String key, ComponentLike value) {
return formatted(Placeholder.component(key, value));
}

default ReturnT insertComponentLazy(final @NotNull String key, Supplier<ComponentLike> value) {
return formatted(TagResolver.resolver(key, (argumentQueue, context) -> {
return Tag.inserting(value.get());
}));
}

default ReturnT insertNumber(final @NotNull String key, Number value) {
return formatted(Formatter.number(key, value));
}

default ReturnT insertNumberLazy(final @NotNull String key, Supplier<Number> value) {
return formatted(TagResolver.resolver(key, (argumentQueue, context) -> {
return Formatter.number(key, value.get()).resolve(key, argumentQueue, context);
}));
}

@Deprecated
default ReturnT insertNumberChoice(final @NotNull String key, Number number) {
return formatted(Formatter.choice(key, number));
}

default ReturnT insertTemporal(final @NotNull String key, Temporal value) {
return formatted(Formatter.date(key, value));
}

default ReturnT insertBool(final @NotNull String key, Boolean value) {
return formatted(Formatter.booleanChoice(key, value));
}

default ReturnT insertTag(final @NotNull String key, Tag tag) {
return formatted(TagResolver.resolver(key, tag));
}

default <T> ReturnT insertObject(final @NotNull String key, T obj) {
return formatted(ObjectTag.resolver(key, obj));

}

default <E> ReturnT insertList(final @NotNull String key, List<E> elements, Function<E, ComponentLike> renderer) {
return this.insertList(key, elements, ListSection.paged(0, elements.size()), renderer);
}

default <E> ReturnT insertList(final @NotNull String key, List<E> elements, ListSection section, Function<E, ComponentLike> renderer) {
return formatted(
Formatter.choice("has-pages", section.getMaxPages(elements.size())),
Formatter.number("page", section.getPage() + 1),
Formatter.number("pages", section.getMaxPages(elements.size())),
Formatter.number("next-page", Math.min(section.getMaxPages(elements.size()), section.getPage() + 2)),
Formatter.number("prev-page", Math.max(1, section.getPage())),
Formatter.number("offset", section.getOffset()),
Formatter.number("range", section.getRange()),
TagResolver.resolver(key, (argumentQueue, context) -> {
String separator = argumentQueue.hasNext() ? argumentQueue.pop().value() : null;
Component separatorParsed = separator == null ? text(", ") : context.deserialize(separator);

List<E> sublist = section.apply(elements);
Component content = Component.join(JoinConfiguration.separator(separatorParsed), sublist.stream()
.map(renderer)
.collect(Collectors.toList())
);
return Tag.selfClosingInserting(content);
}));
}

default <E> ReturnT insertListLazy(final @NotNull String key, Function<ListSection, List<E>> elementSupplier, ListSection section, Function<E, ComponentLike> renderer) {
return formatted(
Formatter.number("page", section.getPage() + 1),
Formatter.number("next-page", section.getPage() + 2),
Formatter.number("prev-page", Math.max(0, section.getPage())),
Formatter.number("offset", section.getOffset()),
Formatter.number("range", section.getRange()),
TagResolver.resolver(key, (argumentQueue, context) -> {
String separator = argumentQueue.hasNext() ? argumentQueue.pop().value() : null;
Component separatorParsed = separator == null ? text(", ") : context.deserialize(separator);

AtomicInteger startIndex = new AtomicInteger(section.getOffset());
List<E> sublist = elementSupplier.apply(section);
Component content = Component.join(JoinConfiguration.separator(separatorParsed), sublist.stream()
.map(renderer)
.map(componentLike -> {
if (componentLike instanceof Message m) {
return m.insertNumber("index", startIndex.incrementAndGet());
}
return componentLike;
})
.collect(Collectors.toList())
);
return Tag.selfClosingInserting(content);
}));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

import static net.kyori.adventure.text.Component.text;

public interface Message extends ComponentLike, Cloneable, Comparable<Message> {
public interface Message extends ComponentLike, Cloneable, Comparable<Message>, Formattable<Message> {


@KeyPattern
Expand All @@ -45,147 +45,10 @@ public interface Message extends ComponentLike, Cloneable, Comparable<Message> {
String toString(MessageFormat format);


@Contract(pure = true)
Message formatted(Audience audience);

@Contract(pure = true)
Message formatted(TagResolver... resolver);

@Contract(pure = true)
default Message insertString(final @NotNull String key, String value) {
return formatted(Placeholder.unparsed(key, value));
}

@Contract(pure = true)
default Message insertStringLazy(final @NotNull String key, Supplier<String> value) {
return formatted(TagResolver.resolver(key, (argumentQueue, context) -> {
return Tag.preProcessParsed(value.get());
}));
}

@Contract(pure = true)
default Message insertComponent(final @NotNull String key, ComponentLike value) {
return formatted(Placeholder.component(key, value));
}

@Contract(pure = true)
default Message insertComponentLazy(final @NotNull String key, Supplier<ComponentLike> value) {
return formatted(TagResolver.resolver(key, (argumentQueue, context) -> {
return Tag.inserting(value.get());
}));
}

@Contract(pure = true)
default Message insertNumber(final @NotNull String key, Number value) {
return formatted(Formatter.number(key, value));
}

@Contract(pure = true)
default Message insertNumberLazy(final @NotNull String key, Supplier<Number> value) {
return formatted(TagResolver.resolver(key, (argumentQueue, context) -> {
return Formatter.number(key, value.get()).resolve(key, argumentQueue, context);
}));
}

@Contract(pure = true)
@Deprecated
default Message insertNumberChoice(final @NotNull String key, Number number) {
return formatted(Formatter.choice(key, number));
}

@Contract(pure = true)
default Message insertTemporal(final @NotNull String key, Temporal value) {
return formatted(Formatter.date(key, value));
}

@Contract(pure = true)
default Message insertBool(final @NotNull String key, Boolean value) {
return formatted(Formatter.booleanChoice(key, value));
}

@Contract(pure = true)
default Message insertTag(final @NotNull String key, Tag tag) {
return formatted(TagResolver.resolver(key, tag));
}

default <T> Message insertObject(final @NotNull String key, T obj) {
return formatted(TagResolver.resolver(key, (argumentQueue, context) -> {
Queue<String> path = new LinkedList<>();
while (argumentQueue.hasNext()) {
path.add(argumentQueue.pop().value());
}
argumentQueue.reset();
Object resolved = getTranslator().getObjectTypeResolverMap().resolve(obj, path);
if (resolved == null) {
return Tag.inserting(Component.text("<" + key + ":" + String.join(":", path) + "/>"));
}
if (resolved instanceof ComponentLike componentLike) {
return Tag.inserting(componentLike);
}
return Tag.inserting(Component.text(resolved.toString()));
}));

}

@Contract(pure = true)
default <E> Message insertList(final @NotNull String key, List<E> elements, Function<E, ComponentLike> renderer) {
return this.insertList(key, elements, ListSection.paged(0, elements.size()), renderer);
}

@Contract(pure = true)
default <E> Message insertList(final @NotNull String key, List<E> elements, ListSection section, Function<E, ComponentLike> renderer) {
return formatted(
Formatter.choice("has-pages", section.getMaxPages(elements.size())),
Formatter.number("page", section.getPage() + 1),
Formatter.number("pages", section.getMaxPages(elements.size())),
Formatter.number("next-page", Math.min(section.getMaxPages(elements.size()), section.getPage() + 2)),
Formatter.number("prev-page", Math.max(1, section.getPage())),
Formatter.number("offset", section.getOffset()),
Formatter.number("range", section.getRange()),
TagResolver.resolver(key, (argumentQueue, context) -> {
String separator = argumentQueue.hasNext() ? argumentQueue.pop().value() : null;
Component separatorParsed = separator == null ? text(", ") : context.deserialize(separator);

List<E> sublist = section.apply(elements);
Component content = Component.join(JoinConfiguration.separator(separatorParsed), sublist.stream()
.map(renderer)
.collect(Collectors.toList())
);
return Tag.selfClosingInserting(content);
}));
}

@Contract(pure = true)
default <E> Message insertListLazy(final @NotNull String key, Function<ListSection, List<E>> elementSupplier, ListSection section, Function<E, ComponentLike> renderer) {
return formatted(
Formatter.number("page", section.getPage() + 1),
Formatter.number("next-page", section.getPage() + 2),
Formatter.number("prev-page", Math.max(0, section.getPage())),
Formatter.number("offset", section.getOffset()),
Formatter.number("range", section.getRange()),
TagResolver.resolver(key, (argumentQueue, context) -> {
String separator = argumentQueue.hasNext() ? argumentQueue.pop().value() : null;
Component separatorParsed = separator == null ? text(", ") : context.deserialize(separator);

AtomicInteger startIndex = new AtomicInteger(section.getOffset());
List<E> sublist = elementSupplier.apply(section);
Component content = Component.join(JoinConfiguration.separator(separatorParsed), sublist.stream()
.map(renderer)
.map(componentLike -> {
if (componentLike instanceof Message m) {
return m.insertNumber("index", startIndex.incrementAndGet());
}
return componentLike;
})
.collect(Collectors.toList())
);
return Tag.selfClosingInserting(content);
}));
}

@Nullable Audience getTarget();

Collection<TagResolver> getResolvers();
@Contract(pure = true)
Message formatted(Audience audience);


Map<Locale, String> getDictionary();
Expand Down
Loading

0 comments on commit 02e1ec9

Please sign in to comment.