mirror of
https://github.com/MiniPlaceholders/MiniPlaceholders.git
synced 2026-11-04 16:50:11 -05:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a31d98149 | ||
|
|
ae5a8e235e | ||
|
|
da6256def1 | ||
|
|
40fd7e7873 | ||
|
|
aa47088828 | ||
|
|
fff5acdb7b |
No files matched your search
@@ -34,361 +34,390 @@ import java.util.Collection;
|
||||
* TagResolver resolver = expansion.resolver();
|
||||
* player.sendMessage(MiniMessage.miniMessage().deserialize("Hello {@literal <luckperms_prefix> <player_name>}", player, resolver));
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@NullMarked
|
||||
public sealed interface Expansion permits ExpansionImpl {
|
||||
/**
|
||||
* Get the expansion name
|
||||
*
|
||||
* @return the expansion name
|
||||
* @since 1.0.0
|
||||
*/
|
||||
String name();
|
||||
/**
|
||||
* Get the expansion name
|
||||
*
|
||||
* @return the expansion name
|
||||
* @since 1.0.0
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* Get the author of this expansion
|
||||
*
|
||||
* @return the author or null
|
||||
* @since 2.3.0
|
||||
*/
|
||||
@Nullable String author();
|
||||
|
||||
/**
|
||||
* Get the version of this expansion
|
||||
*
|
||||
* @return the version or null
|
||||
* @since 2.3.0
|
||||
*/
|
||||
@Nullable String version();
|
||||
|
||||
/**
|
||||
* Get the {@link TagResolver} of an {@link Audience}
|
||||
*
|
||||
* @return A TagResolver with variable placeholders of an Audience
|
||||
* @since 1.0.0
|
||||
*/
|
||||
TagResolver audiencePlaceholders();
|
||||
|
||||
/**
|
||||
* Get the relational placeholders based on two audiences
|
||||
*
|
||||
* <p>The resulting TagResolver will give results according
|
||||
* to the 2 {@link Audience} provided and when called
|
||||
* at any time will retrieve the required values</p>
|
||||
*
|
||||
* @return A TagResolver with variable placeholders between 2 {@link Audience}s
|
||||
* @since 1.0.0
|
||||
*/
|
||||
TagResolver relationalPlaceholders();
|
||||
|
||||
/**
|
||||
* Get global placeholders
|
||||
*
|
||||
* @return the global placeholders
|
||||
* @since 1.0.0
|
||||
*/
|
||||
TagResolver globalPlaceholders();
|
||||
|
||||
/**
|
||||
* Register this expansion
|
||||
*
|
||||
* @throws IllegalStateException if the expansion you are trying to register is already registered
|
||||
* @see Expansion#registered()
|
||||
* @since 1.0.0
|
||||
*/
|
||||
void register();
|
||||
|
||||
/**
|
||||
* Unregisters this expansion
|
||||
*
|
||||
* @throws IllegalStateException if the expansion you are trying to unregister is not registered
|
||||
* @see Expansion#registered()
|
||||
* @since 2.1.0
|
||||
*/
|
||||
void unregister();
|
||||
|
||||
/**
|
||||
* Get the registration status of this expansion
|
||||
*
|
||||
* @return true if the expansion is registered, otherwise false
|
||||
* @since 2.1.0
|
||||
*/
|
||||
boolean registered();
|
||||
|
||||
/**
|
||||
* Get the registered audience placeholders
|
||||
*
|
||||
* @return registered audience placeholders
|
||||
*/
|
||||
Collection<AudiencePlaceholder<?>> registeredAudiencePlaceholders();
|
||||
|
||||
/**
|
||||
* Get the registered relational placeholders
|
||||
*
|
||||
* @return registered relational placeholders
|
||||
*/
|
||||
Collection<RelationalPlaceholder<?>> registeredRelationalPlaceholders();
|
||||
|
||||
/**
|
||||
* Get an Audience Placeholder by name
|
||||
*
|
||||
* <pre>{@code
|
||||
* Expansion expansion = MiniPlaceholders.expansionByName("player")
|
||||
* AudiencePlaceholder<?> placeholder = expansion.audiencePlaceholderByName("name");
|
||||
* }</pre>
|
||||
*
|
||||
* @param name the name of the placeholder to search
|
||||
* @return the desired placeholder or null
|
||||
*/
|
||||
@Nullable AudiencePlaceholder<?> audiencePlaceholderByName(final String name);
|
||||
|
||||
/**
|
||||
* Get a Relational Placeholder by name
|
||||
*
|
||||
* <pre>{@code
|
||||
* Expansion expansion = MiniPlaceholders.expansionByName("expansion")
|
||||
* RelationalPlaceholder<?> placeholder = expansion.relationalPlaceholderByName("placeholder");
|
||||
* }</pre>
|
||||
*
|
||||
* @param name the name of the placeholder to search
|
||||
* @return the desired placeholder or null
|
||||
* @apiNote The name of a relational placeholder does not contain the prefix “rel”,
|
||||
* just the name assigned when it was created
|
||||
*/
|
||||
@Nullable RelationalPlaceholder<?> relationalPlaceholderByName(final String name);
|
||||
|
||||
/**
|
||||
* Get a Global Placeholder by name
|
||||
*
|
||||
* <pre>{@code
|
||||
* Expansion expansion = MiniPlaceholders.expansionByName("player")
|
||||
* GlobalPlaceholder placeholder = expansion.globalPlaceholderByName("name");
|
||||
* }</pre>
|
||||
*
|
||||
* @param name the name of the placeholder to search
|
||||
* @return the desired placeholder or null
|
||||
*/
|
||||
@Nullable GlobalPlaceholder globalPlaceholderByName(final String name);
|
||||
|
||||
/**
|
||||
* Checks whether an audience placeholder with the specified name has been registered in this expansion.
|
||||
*
|
||||
* @param name the name of the placeholder to check
|
||||
* @return true if the placeholder is registered, else false
|
||||
*/
|
||||
default boolean hasAudiencePlaceholder(final String name) {
|
||||
return audiencePlaceholderByName(name) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a relational placeholder with the specified name has been registered in this expansion.
|
||||
*
|
||||
* @param name the name of the placeholder to check
|
||||
* @return true if the placeholder is registered, else false
|
||||
*/
|
||||
default boolean hasRelationalPlaceholder(final String name) {
|
||||
return relationalPlaceholderByName(name) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a global placeholder with the specified name has been registered in this expansion.
|
||||
*
|
||||
* @param name the name of the placeholder to check
|
||||
* @return true if the placeholder is registered, else false
|
||||
*/
|
||||
default boolean hasGlobalPlaceholder(final String name) {
|
||||
return globalPlaceholderByName(name) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a TagResolver that contains all placeholders of a specific type in this expansion.
|
||||
*
|
||||
* @param type the desired type
|
||||
* @return a TagResolver containing all placeholder of a specific type
|
||||
*/
|
||||
TagResolver placeholdersByType(PlaceholderType type);
|
||||
|
||||
/**
|
||||
* Creates a new Expansion Builder
|
||||
*
|
||||
* @param name the expansion name
|
||||
* @return a new expansion builder
|
||||
* @since 1.0.0
|
||||
*/
|
||||
static Expansion.Builder builder(final String name) {
|
||||
return new ExpansionImpl.Builder(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a shorter ToString with the details of this expansion.
|
||||
*
|
||||
* @return a shorter ToString
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@Deprecated(forRemoval = true, since = "3.1.0")
|
||||
default String shortToString() {
|
||||
final StringBuilder builder = new StringBuilder(name()).append('[');
|
||||
if (author() != null) {
|
||||
builder.append("Author: ").append(author());
|
||||
}
|
||||
if (version() != null) {
|
||||
if (author() != null) {
|
||||
builder.append(", ");
|
||||
}
|
||||
builder.append("Version: ").append(version());
|
||||
}
|
||||
builder.append(']');
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Expansion Builder
|
||||
* <p>Example use:</p>
|
||||
* <pre>
|
||||
* Expansion.Builder builder = Expansion.builder("player");
|
||||
* builder
|
||||
* // Thanks to this filter, a cast can be performed without the probability of a ClassCastException
|
||||
* .filter(Player.class)
|
||||
* .resolver("name", (audience, queue, ctx) -> Tag.selfClosingInserting(Component.text(((Player)audience).getUsername())));
|
||||
* Expansion expansion = builder.build();
|
||||
* </pre>
|
||||
* <p>
|
||||
* then use it:
|
||||
*
|
||||
* <pre>
|
||||
* Player player = event.getPlayer();
|
||||
* TagResolver resolver = expansion.resolver(player);
|
||||
* Component messageReplaced = MiniMessage.deserialize({@link String}, resolver);
|
||||
* </pre>
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@NullMarked
|
||||
interface Builder extends AbstractBuilder<Expansion> {
|
||||
|
||||
/**
|
||||
* Get the author of this expansion
|
||||
* Adds an audience placeholder
|
||||
*
|
||||
* @return the author or null
|
||||
* <p>This type of Placeholder depends on a specific audience to obtain its values</p>
|
||||
*
|
||||
* <p>The content of this Placeholder is cached
|
||||
* and can mutate depending on when it is invoked</p>
|
||||
*
|
||||
* @param targetClass the target class
|
||||
* @param key the placeholder key, cannot be an empty or black string
|
||||
* @param audiencePlaceholder the single placeholder
|
||||
* @param <A> the type of audience that this placeholder supports, must be the same as targetClass
|
||||
* @return the {@link Builder} itself
|
||||
* @since 1.0.0
|
||||
*/
|
||||
<A extends Audience> Builder audiencePlaceholder(
|
||||
final @Nullable Class<A> targetClass,
|
||||
final String key,
|
||||
final AudienceTagResolver<A> audiencePlaceholder
|
||||
);
|
||||
|
||||
/**
|
||||
* Adds an audience placeholder
|
||||
*
|
||||
* <p>This type of Placeholder depends on a specific audience to obtain its values</p>
|
||||
*
|
||||
* <p>The content of this Placeholder is cached
|
||||
* and can mutate depending on when it is invoked</p>
|
||||
*
|
||||
* @param key the placeholder key, cannot be an empty or black string
|
||||
* @param audiencePlaceholder the single placeholder
|
||||
* @return the {@link Builder} itself
|
||||
* @since 3.0.0
|
||||
*/
|
||||
default Builder audiencePlaceholder(final String key, final AudienceTagResolver<Audience> audiencePlaceholder) {
|
||||
return this.audiencePlaceholder(null, key, audiencePlaceholder);
|
||||
}
|
||||
|
||||
<A extends Audience> Builder audiencePlaceholder(
|
||||
final Class<A> targetClass,
|
||||
final AudiencePlaceholder.Builder.Provider<A> builderProvider
|
||||
);
|
||||
|
||||
default Builder audiencePlaceholder(final AudiencePlaceholder.Builder.Provider<Audience> builderProvider) {
|
||||
return audiencePlaceholder(Audience.class, builderProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Relational Placeholder based on two audiences
|
||||
*
|
||||
* <p>This type of placeholder allows you to create
|
||||
* components based on a 2-audiences relationship,
|
||||
* one is the one on which the placeholder
|
||||
* is based and the other is the one on which
|
||||
* the placeholder is displayed.</p>
|
||||
*
|
||||
* <p>The content of this Placeholder is cached
|
||||
* and can mutate depending on when it is invoked</p>
|
||||
*
|
||||
* @param targetClass the target class
|
||||
* @param key the placeholder key, cannot be an empty or black string
|
||||
* @param relationalPlaceholder the relational placeholder
|
||||
* @param <A> the type of audience that this placeholder supports, must be the same as targetClass
|
||||
* @return the {@link Builder} itself
|
||||
* @since 3.0.0
|
||||
*/
|
||||
<A extends Audience> Builder relationalPlaceholder(
|
||||
final @Nullable Class<A> targetClass,
|
||||
final String key,
|
||||
final RelationalTagResolver<A> relationalPlaceholder
|
||||
);
|
||||
|
||||
/**
|
||||
* Adds a Relational Placeholder based on two audiences
|
||||
*
|
||||
* <p>This type of placeholder allows you to create
|
||||
* components based on a 2-audiences relationship,
|
||||
* one is the one on which the placeholder
|
||||
* is based and the other is the one on which
|
||||
* the placeholder is displayed.</p>
|
||||
*
|
||||
* <p>The content of this Placeholder is cached
|
||||
* and can mutate depending on when it is invoked</p>
|
||||
*
|
||||
* @param key the placeholder key, cannot be an empty or black string
|
||||
* @param relationalResolver the relational placeholder
|
||||
* @return the {@link Builder} itself
|
||||
* @since 3.0.0
|
||||
*/
|
||||
default Builder relationalPlaceholder(
|
||||
final String key,
|
||||
final RelationalTagResolver<Audience> relationalResolver
|
||||
) {
|
||||
return this.relationalPlaceholder(null, key, relationalResolver);
|
||||
}
|
||||
|
||||
<A extends Audience> Builder relationalPlaceholder(
|
||||
final Class<A> targetClass,
|
||||
final RelationalPlaceholder.Builder.Provider<A> builderProvider
|
||||
);
|
||||
|
||||
default Builder relationalPlaceholder(final RelationalPlaceholder.Builder.Provider<Audience> builderProvider) {
|
||||
return relationalPlaceholder(Audience.class, builderProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a global placeholder
|
||||
*
|
||||
* <p>The content of this Placeholder is cached
|
||||
* and can mutate depending on when it is invoked</p>
|
||||
*
|
||||
* @param key the placeholder key, cannot be an empty or black string
|
||||
* @param resolver the function
|
||||
* @return the {@link Builder} itself
|
||||
* @since 3.0.0
|
||||
*/
|
||||
Builder globalPlaceholder(final String key, final GlobalTagResolver resolver);
|
||||
|
||||
/**
|
||||
* Adds a global placeholder
|
||||
*
|
||||
* <p>This placeholder is not cached and is immutable</p>
|
||||
*
|
||||
* @param key the placeholder key, cannot be an empty or black string
|
||||
* @param tag the tag of this placeholder
|
||||
* @return the {@link Builder} itself
|
||||
* @since 1.1.0
|
||||
*/
|
||||
default Builder globalPlaceholder(final String key, final Tag tag) {
|
||||
return this.globalPlaceholder(key, (queue, context) -> tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the author of this expansion
|
||||
*
|
||||
* @param author the author of this expansion
|
||||
* @return the {@link Builder} itself
|
||||
* @since 2.3.0
|
||||
*/
|
||||
@Nullable String author();
|
||||
@Contract("_ -> this")
|
||||
Builder author(final @Nullable String author);
|
||||
|
||||
/**
|
||||
* Get the version of this expansion
|
||||
* Sets the version of this expansion
|
||||
*
|
||||
* @return the version or null
|
||||
* @param version the version of this expansion
|
||||
* @return the {@link Builder} itself
|
||||
* @since 2.3.0
|
||||
*/
|
||||
@Nullable String version();
|
||||
|
||||
/**
|
||||
* Get the {@link TagResolver} of an {@link Audience}
|
||||
* @return A TagResolver with variable placeholders of an Audience
|
||||
* @since 1.0.0
|
||||
*/
|
||||
TagResolver audiencePlaceholders();
|
||||
|
||||
/**
|
||||
* Get the relational placeholders based on two audiences
|
||||
*
|
||||
* <p>The resulting TagResolver will give results according
|
||||
* to the 2 {@link Audience} provided and when called
|
||||
* at any time will retrieve the required values</p>
|
||||
* @return A TagResolver with variable placeholders between 2 {@link Audience}s
|
||||
* @since 1.0.0
|
||||
*/
|
||||
TagResolver relationalPlaceholders();
|
||||
|
||||
/**
|
||||
* Get global placeholders
|
||||
* @return the global placeholders
|
||||
* @since 1.0.0
|
||||
*/
|
||||
TagResolver globalPlaceholders();
|
||||
|
||||
/**
|
||||
* Register this expansion
|
||||
* @since 1.0.0
|
||||
* @throws IllegalStateException if the expansion you are trying to register is already registered
|
||||
* @see Expansion#registered()
|
||||
*/
|
||||
void register();
|
||||
|
||||
/**
|
||||
* Unregisters this expansion
|
||||
* @since 2.1.0
|
||||
* @throws IllegalStateException if the expansion you are trying to unregister is not registered
|
||||
* @see Expansion#registered()
|
||||
*/
|
||||
void unregister();
|
||||
|
||||
/**
|
||||
* Get the registration status of this expansion
|
||||
* @return true if the expansion is registered, otherwise false
|
||||
* @since 2.1.0
|
||||
*/
|
||||
boolean registered();
|
||||
|
||||
// TODO: Docs and Tests
|
||||
|
||||
/**
|
||||
* Get the registered audience placeholders
|
||||
*
|
||||
* @return registered audience placeholders
|
||||
*/
|
||||
Collection<AudiencePlaceholder<?>> registeredAudiencePlaceholders();
|
||||
|
||||
/**
|
||||
* Get the registered relational placeholders
|
||||
*
|
||||
* @return registered relational placeholders
|
||||
*/
|
||||
Collection<RelationalPlaceholder<?>> registeredRelationalPlaceholders();
|
||||
|
||||
/**
|
||||
* Get an Audience Placeholder by name
|
||||
*
|
||||
* <pre>{@code
|
||||
* Expansion expansion = MiniPlaceholders.expansionByName("player")
|
||||
* AudiencePlaceholder<?> placeholder = expansion.audiencePlaceholderByName("name");
|
||||
* }</pre>
|
||||
* @param name the name of the placeholder to search
|
||||
* @return the desired placeholder or null
|
||||
*/
|
||||
@Nullable AudiencePlaceholder<?> audiencePlaceholderByName(final String name);
|
||||
|
||||
/**
|
||||
* Get a Relational Placeholder by name
|
||||
*
|
||||
* <pre>{@code
|
||||
* Expansion expansion = MiniPlaceholders.expansionByName("expansion")
|
||||
* RelationalPlaceholder<?> placeholder = expansion.relationalPlaceholderByName("placeholder");
|
||||
* }</pre>
|
||||
* @param name the name of the placeholder to search
|
||||
* @return the desired placeholder or null
|
||||
* @apiNote The name of a relational placeholder does not contain the prefix “rel”,
|
||||
* just the name assigned when it was created
|
||||
*/
|
||||
@Nullable RelationalPlaceholder<?> relationalPlaceholderByName(final String name);
|
||||
|
||||
/**
|
||||
* Get a Global Placeholder by name
|
||||
*
|
||||
* <pre>{@code
|
||||
* Expansion expansion = MiniPlaceholders.expansionByName("player")
|
||||
* GlobalPlaceholder placeholder = expansion.globalPlaceholderByName("name");
|
||||
* }</pre>
|
||||
* @param name the name of the placeholder to search
|
||||
* @return the desired placeholder or null
|
||||
*/
|
||||
@Nullable GlobalPlaceholder globalPlaceholderByName(final String name);
|
||||
|
||||
/**
|
||||
* Checks whether an audience placeholder with the specified name has been registered in this expansion.
|
||||
*
|
||||
* @param name the name of the placeholder to check
|
||||
* @return true if the placeholder is registered, else false
|
||||
*/
|
||||
default boolean hasAudiencePlaceholder(final String name) {
|
||||
return audiencePlaceholderByName(name) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a relational placeholder with the specified name has been registered in this expansion.
|
||||
*
|
||||
* @param name the name of the placeholder to check
|
||||
* @return true if the placeholder is registered, else false
|
||||
*/
|
||||
default boolean hasRelationalPlaceholder(final String name) {
|
||||
return relationalPlaceholderByName(name) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a global placeholder with the specified name has been registered in this expansion.
|
||||
*
|
||||
* @param name the name of the placeholder to check
|
||||
* @return true if the placeholder is registered, else false
|
||||
*/
|
||||
default boolean hasGlobalPlaceholder(final String name) {
|
||||
return globalPlaceholderByName(name) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a TagResolver that contains all placeholders of a specific type in this expansion.
|
||||
*
|
||||
* @param type the desired type
|
||||
* @return a TagResolver containing all placeholder of a specific type
|
||||
*/
|
||||
TagResolver placeholdersByType(PlaceholderType type);
|
||||
|
||||
/**
|
||||
* Creates a new Expansion Builder
|
||||
* @param name the expansion name
|
||||
* @return a new expansion builder
|
||||
* @since 1.0.0
|
||||
*/
|
||||
static Expansion.Builder builder(final String name){
|
||||
return new ExpansionImpl.Builder(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a shorter ToString with the details of this expansion.
|
||||
* @return a shorter ToString
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@Deprecated(forRemoval = true, since = "3.1.0")
|
||||
default String shortToString() {
|
||||
final StringBuilder builder = new StringBuilder(name()).append('[');
|
||||
if (author() != null) {
|
||||
builder.append("Author: ").append(author());
|
||||
}
|
||||
if (version() != null) {
|
||||
if (author() != null) {
|
||||
builder.append(", ");
|
||||
}
|
||||
builder.append("Version: ").append(version());
|
||||
}
|
||||
builder.append(']');
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Expansion Builder
|
||||
* <p>Example use:</p>
|
||||
* <pre>
|
||||
* Expansion.Builder builder = Expansion.builder("player");
|
||||
* builder
|
||||
* // Thanks to this filter, a cast can be performed without the probability of a ClassCastException
|
||||
* .filter(Player.class)
|
||||
* .resolver("name", (audience, queue, ctx) -> Tag.selfClosingInserting(Component.text(((Player)audience).getUsername())));
|
||||
* Expansion expansion = builder.build();
|
||||
* </pre>
|
||||
*
|
||||
* then use it:
|
||||
*
|
||||
* <pre>
|
||||
* Player player = event.getPlayer();
|
||||
* TagResolver resolver = expansion.resolver(player);
|
||||
* Component messageReplaced = MiniMessage.deserialize({@link String}, resolver);
|
||||
* </pre>
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@NullMarked
|
||||
interface Builder extends AbstractBuilder<Expansion> {
|
||||
|
||||
/**
|
||||
* Adds an audience placeholder
|
||||
*
|
||||
* <p>This type of Placeholder depends on a specific audience to obtain its values</p>
|
||||
*
|
||||
* <p>The content of this Placeholder is cached
|
||||
* and can mutate depending on when it is invoked</p>
|
||||
*
|
||||
* @param targetClass the target class
|
||||
* @param key the placeholder key, cannot be an empty or black string
|
||||
* @param audiencePlaceholder the single placeholder
|
||||
* @param <A> the type of audience that this placeholder supports, must be the same as targetClass
|
||||
* @return the {@link Builder} itself
|
||||
* @since 1.0.0
|
||||
*/
|
||||
<A extends Audience> Builder audiencePlaceholder(
|
||||
final @Nullable Class<A> targetClass,
|
||||
final String key,
|
||||
final AudienceTagResolver<A> audiencePlaceholder
|
||||
);
|
||||
|
||||
/**
|
||||
* Adds an audience placeholder
|
||||
*
|
||||
* <p>This type of Placeholder depends on a specific audience to obtain its values</p>
|
||||
*
|
||||
* <p>The content of this Placeholder is cached
|
||||
* and can mutate depending on when it is invoked</p>
|
||||
*
|
||||
* @param key the placeholder key, cannot be an empty or black string
|
||||
* @param audiencePlaceholder the single placeholder
|
||||
* @return the {@link Builder} itself
|
||||
* @since 3.0.0
|
||||
*/
|
||||
default Builder audiencePlaceholder(final String key, final AudienceTagResolver<Audience> audiencePlaceholder) {
|
||||
return this.audiencePlaceholder(null, key, audiencePlaceholder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Relational Placeholder based on two audiences
|
||||
*
|
||||
* <p>This type of placeholder allows you to create
|
||||
* components based on a 2-audiences relationship,
|
||||
* one is the one on which the placeholder
|
||||
* is based and the other is the one on which
|
||||
* the placeholder is displayed.</p>
|
||||
*
|
||||
* <p>The content of this Placeholder is cached
|
||||
* and can mutate depending on when it is invoked</p>
|
||||
*
|
||||
* @param targetClass the target class
|
||||
* @param key the placeholder key, cannot be an empty or black string
|
||||
* @param relationalPlaceholder the relational placeholder
|
||||
* @param <A> the type of audience that this placeholder supports, must be the same as targetClass
|
||||
* @return the {@link Builder} itself
|
||||
* @since 3.0.0
|
||||
*/
|
||||
<A extends Audience> Builder relationalPlaceholder(
|
||||
final @Nullable Class<A> targetClass,
|
||||
final String key,
|
||||
final RelationalTagResolver<A> relationalPlaceholder
|
||||
);
|
||||
|
||||
/**
|
||||
* Adds a Relational Placeholder based on two audiences
|
||||
*
|
||||
* <p>This type of placeholder allows you to create
|
||||
* components based on a 2-audiences relationship,
|
||||
* one is the one on which the placeholder
|
||||
* is based and the other is the one on which
|
||||
* the placeholder is displayed.</p>
|
||||
*
|
||||
* <p>The content of this Placeholder is cached
|
||||
* and can mutate depending on when it is invoked</p>
|
||||
*
|
||||
* @param key the placeholder key, cannot be an empty or black string
|
||||
* @param relationalResolver the relational placeholder
|
||||
* @return the {@link Builder} itself
|
||||
* @since 3.0.0
|
||||
*/
|
||||
default Builder relationalPlaceholder(
|
||||
final String key,
|
||||
final RelationalTagResolver<Audience> relationalResolver
|
||||
) {
|
||||
return this.relationalPlaceholder(null, key, relationalResolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a global placeholder
|
||||
*
|
||||
* <p>The content of this Placeholder is cached
|
||||
* and can mutate depending on when it is invoked</p>
|
||||
* @param key the placeholder key, cannot be an empty or black string
|
||||
* @param resolver the function
|
||||
* @return the {@link Builder} itself
|
||||
* @since 3.0.0
|
||||
*/
|
||||
Builder globalPlaceholder(final String key, final GlobalTagResolver resolver);
|
||||
|
||||
/**
|
||||
* Adds a global placeholder
|
||||
*
|
||||
* <p>This placeholder is not cached and is immutable</p>
|
||||
* @param key the placeholder key, cannot be an empty or black string
|
||||
* @param tag the tag of this placeholder
|
||||
* @return the {@link Builder} itself
|
||||
* @since 1.1.0
|
||||
*/
|
||||
default Builder globalPlaceholder(final String key, final Tag tag) {
|
||||
return this.globalPlaceholder(key, (queue, context) -> tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the author of this expansion
|
||||
*
|
||||
* @param author the author of this expansion
|
||||
* @return the {@link Builder} itself
|
||||
* @since 2.3.0
|
||||
*/
|
||||
@Contract("_ -> this")
|
||||
Builder author(final @Nullable String author);
|
||||
|
||||
/**
|
||||
* Sets the version of this expansion
|
||||
*
|
||||
* @param version the version of this expansion
|
||||
* @return the {@link Builder} itself
|
||||
* @since 2.3.0
|
||||
*/
|
||||
@Contract("_ -> this")
|
||||
Builder version(final @Nullable String version);
|
||||
}
|
||||
@Contract("_ -> this")
|
||||
Builder version(final @Nullable String version);
|
||||
}
|
||||
}
|
||||
@@ -164,7 +164,7 @@ final class ExpansionImpl implements Expansion {
|
||||
}
|
||||
|
||||
@NullUnmarked
|
||||
static final class Builder implements Expansion.Builder {
|
||||
public static final class Builder implements Expansion.Builder {
|
||||
private final String expansionName;
|
||||
@Subst("server")
|
||||
private final String expansionPrefix;
|
||||
@@ -179,18 +179,36 @@ final class ExpansionImpl implements Expansion {
|
||||
this.expansionPrefix = name.toLowerCase(Locale.ROOT).concat("_");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends Audience> Expansion.Builder audiencePlaceholder(
|
||||
final Class<A> targetClass,
|
||||
final @NotNull @Subst("placeholder") String key,
|
||||
final @NotNull AudienceTagResolver<@NotNull A> audiencePlaceholder
|
||||
) {
|
||||
nonNullOrEmptyString(key, "Placeholder key");
|
||||
requireNonNull(audiencePlaceholder, "the audience placeholder cannot be null");
|
||||
|
||||
if (this.audiencePlaceholders == null) this.audiencePlaceholders = new HashSet<>();
|
||||
|
||||
this.audiencePlaceholders.add(AudiencePlaceholder.single(targetClass, expansionPrefix + key, key, audiencePlaceholder));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends Audience> @NotNull Builder audiencePlaceholder(
|
||||
final @Nullable Class<A> targetClass,
|
||||
@Subst("name") final @NotNull String key,
|
||||
final @NotNull AudienceTagResolver<@NotNull A> audiencePlaceholder
|
||||
public <A extends Audience> Expansion.Builder audiencePlaceholder(
|
||||
final @NotNull Class<A> targetClass,
|
||||
final @NotNull AudiencePlaceholder.Builder.Provider<A> builderProvider
|
||||
) {
|
||||
nonNullOrEmptyString(key, "Placeholder key");
|
||||
requireNonNull(audiencePlaceholder, "the audience placeholder cannot be null");
|
||||
requireNonNull(targetClass, "target class");
|
||||
requireNonNull(builderProvider, "builder");
|
||||
|
||||
if (this.audiencePlaceholders == null) this.audiencePlaceholders = new HashSet<>();
|
||||
|
||||
this.audiencePlaceholders.add(AudiencePlaceholder.single(targetClass, expansionPrefix + key, key, audiencePlaceholder));
|
||||
final AudiencePlaceholder.Builder<A> builder = AudiencePlaceholder.builder(targetClass);
|
||||
builderProvider.provide(builder);
|
||||
final AudiencePlaceholder<@NotNull A> placeholder = builder.build(expansionPrefix);
|
||||
|
||||
this.audiencePlaceholders.add(placeholder);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -210,6 +228,24 @@ final class ExpansionImpl implements Expansion {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends Audience> Expansion.Builder relationalPlaceholder(
|
||||
final @NotNull Class<A> targetClass,
|
||||
final @NotNull RelationalPlaceholder.Builder.Provider<A> builderProvider
|
||||
) {
|
||||
requireNonNull(targetClass, "target class");
|
||||
requireNonNull(builderProvider, "builder");
|
||||
|
||||
if (this.relationalPlaceholders == null) this.relationalPlaceholders = new HashSet<>();
|
||||
|
||||
final RelationalPlaceholder.Builder<A> builder = RelationalPlaceholder.builder(targetClass);
|
||||
builderProvider.provide(builder);
|
||||
final RelationalPlaceholder<@NotNull A> placeholder = builder.build(expansionPrefix);
|
||||
|
||||
this.relationalPlaceholders.add(placeholder);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Builder globalPlaceholder(
|
||||
@Subst("time") @NotNull final String key,
|
||||
|
||||
@@ -8,6 +8,7 @@ import net.kyori.adventure.audience.Audience;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -236,6 +237,7 @@ public final class MiniPlaceholders {
|
||||
* @return all available registered expansions
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@Unmodifiable
|
||||
public static Collection<Expansion> expansionsAvailable() {
|
||||
return Collections.unmodifiableSet(expansions);
|
||||
}
|
||||
|
||||
+124
-22
@@ -8,47 +8,90 @@ import net.kyori.adventure.text.minimessage.Context;
|
||||
import net.kyori.adventure.text.minimessage.tag.Tag;
|
||||
import net.kyori.adventure.text.minimessage.tag.TagPattern;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue;
|
||||
import org.intellij.lang.annotations.Subst;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.NullUnmarked;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* A placeholder that can be applied based on an audience of the specified type.
|
||||
*
|
||||
* @param targetClass the type of audience from which this placeholder can obtain information
|
||||
* @param key the full placeholder key
|
||||
* @param name the name of this placeholder
|
||||
* @param resolver the object responsible for obtaining audience information
|
||||
* @param <A> the parametrized type
|
||||
* @param targetClass the type of audience from which this placeholder can obtain information
|
||||
* @param targetFilter the filter that will be applied to the audience before being able to evaluate its return tag
|
||||
* @param key the full placeholder key
|
||||
* @param name the name of this placeholder
|
||||
* @param resolver the object responsible for obtaining audience information
|
||||
* @param <A> the parametrized type
|
||||
*/
|
||||
@NullMarked
|
||||
public record AudiencePlaceholder<A extends Audience>(
|
||||
@Nullable Class<A> targetClass,
|
||||
@TagPattern String key,
|
||||
String name,
|
||||
AudienceTagResolver<A> resolver
|
||||
@Nullable Class<A> targetClass,
|
||||
@Nullable Predicate<A> targetFilter,
|
||||
@TagPattern String key,
|
||||
@TagPattern String name,
|
||||
AudienceTagResolver<A> resolver,
|
||||
@Nullable PlaceholderMetadata placeholderMetadata
|
||||
) implements Placeholder {
|
||||
|
||||
/**
|
||||
* A placeholder that can be applied based on an audience of the specified type.
|
||||
*
|
||||
* @param targetClass the type of audience from which this placeholder can obtain information
|
||||
* @param key the full placeholder key
|
||||
* @param name the name of this placeholder
|
||||
* @param resolver the object responsible for obtaining audience information
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public AudiencePlaceholder(
|
||||
final @Nullable Class<A> targetClass,
|
||||
final @TagPattern String key,
|
||||
final @TagPattern String name,
|
||||
final AudienceTagResolver<A> resolver
|
||||
) {
|
||||
this(targetClass, null, key, name, resolver, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new AudiencePlaceholder.
|
||||
*
|
||||
* @param targetClass the type of audience from which this placeholder can obtain information
|
||||
* @param key the placeholder key
|
||||
* @param name the name of this placeholder
|
||||
* @param resolver the object responsible for obtaining audience information
|
||||
* @param key the placeholder key
|
||||
* @param name the name of this placeholder
|
||||
* @param resolver the object responsible for obtaining audience information
|
||||
* @param <A> the parametrized type
|
||||
* @return a new AudiencePlaceholder
|
||||
* @param <A> the parametrized type
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public static <A extends Audience> AudiencePlaceholder<A> single(
|
||||
@Nullable Class<A> targetClass,
|
||||
@TagPattern String key,
|
||||
String name,
|
||||
AudienceTagResolver<A> resolver
|
||||
@Nullable Class<A> targetClass,
|
||||
@TagPattern String key,
|
||||
@TagPattern String name,
|
||||
AudienceTagResolver<A> resolver
|
||||
) {
|
||||
return new AudiencePlaceholder<>(targetClass, requireNonNull(key), requireNonNull(name), requireNonNull(resolver));
|
||||
return new AudiencePlaceholder<>(
|
||||
targetClass,
|
||||
null,
|
||||
requireNonNull(key),
|
||||
requireNonNull(name),
|
||||
requireNonNull(resolver),
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
public static <A extends Audience> Builder<A> builder(final Class<A> clazz) {
|
||||
requireNonNull(clazz);
|
||||
return new Builder<>(clazz);
|
||||
}
|
||||
|
||||
public static Builder<Audience> builder() {
|
||||
return new Builder<>(Audience.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -65,13 +108,16 @@ public record AudiencePlaceholder<A extends Audience>(
|
||||
if (audience == null) {
|
||||
return null;
|
||||
}
|
||||
if (targetFilter != null && !targetFilter.test(audience)) {
|
||||
return null;
|
||||
}
|
||||
return resolveA(name, audience, arguments, ctx);
|
||||
}
|
||||
|
||||
private @Nullable Tag resolveA(String key, A audience, ArgumentQueue queue, Context ctx) {
|
||||
return this.has(key)
|
||||
? resolver.tag(audience, queue, ctx)
|
||||
: null;
|
||||
? resolver.tag(audience, queue, ctx)
|
||||
: null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("OverrideOnly")
|
||||
@@ -106,7 +152,63 @@ public record AudiencePlaceholder<A extends Audience>(
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AudiencePlaceholder{" +
|
||||
"key='" + key + '\'' +
|
||||
'}';
|
||||
"key='" + key + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
@NullUnmarked
|
||||
public static final class Builder<A extends Audience> {
|
||||
@NotNull
|
||||
private final Class<A> targetClass;
|
||||
@TagPattern
|
||||
private String name;
|
||||
@Nullable
|
||||
private Predicate<A> targetFilter;
|
||||
private AudienceTagResolver<@NotNull A> resolver;
|
||||
@Nullable
|
||||
private PlaceholderMetadata metadata;
|
||||
|
||||
Builder(final @NotNull Class<A> targetClass) {
|
||||
this.targetClass = targetClass;
|
||||
}
|
||||
|
||||
public Builder<A> name(final @NonNull @TagPattern String name) {
|
||||
this.name = requireNonNull(name, "placeholder name");
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<A> targetFilter(final Predicate<A> targetFilter) {
|
||||
this.targetFilter = targetFilter;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<A> resolver(final @NotNull AudienceTagResolver<@NotNull A> resolver) {
|
||||
this.resolver = requireNonNull(resolver);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<A> metadata(final PlaceholderMetadata metadata) {
|
||||
this.metadata = metadata;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull AudiencePlaceholder<@NonNull A> build(final @NotNull @Subst("expansion") String expansionPrefix) {
|
||||
requireNonNull(this.name, "name");
|
||||
requireNonNull(this.resolver, "resolver");
|
||||
return new AudiencePlaceholder<>(
|
||||
targetClass,
|
||||
targetFilter,
|
||||
expansionPrefix+name,
|
||||
name,
|
||||
resolver,
|
||||
metadata
|
||||
);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Provider<A extends Audience> {
|
||||
void provide(Builder<A> builderProvider);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package io.github.miniplaceholders.api.placeholder;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
@NullMarked
|
||||
public record PlaceholderMetadata(String displayName, String description) {
|
||||
public PlaceholderMetadata {
|
||||
requireNonNull(displayName);
|
||||
requireNonNull(description);
|
||||
}
|
||||
|
||||
public static PlaceholderMetadata data(final String displayName, final String description) {
|
||||
return new PlaceholderMetadata(displayName, description);
|
||||
}
|
||||
}
|
||||
+112
-31
@@ -1,7 +1,7 @@
|
||||
package io.github.miniplaceholders.api.placeholder;
|
||||
|
||||
import io.github.miniplaceholders.api.types.RelationalAudience;
|
||||
import io.github.miniplaceholders.api.resolver.RelationalTagResolver;
|
||||
import io.github.miniplaceholders.api.types.RelationalAudience;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import net.kyori.adventure.audience.ForwardingAudience;
|
||||
import net.kyori.adventure.pointer.Pointered;
|
||||
@@ -9,11 +9,15 @@ import net.kyori.adventure.text.minimessage.Context;
|
||||
import net.kyori.adventure.text.minimessage.tag.Tag;
|
||||
import net.kyori.adventure.text.minimessage.tag.TagPattern;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue;
|
||||
import org.intellij.lang.annotations.Subst;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.NullUnmarked;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
@@ -24,45 +28,64 @@ import static java.util.Objects.requireNonNull;
|
||||
* using a type-safe filter and a relational resolver.
|
||||
*
|
||||
* @param targetClass the target class, can be null
|
||||
* @param key the key of the entire placeholder
|
||||
* @param name the name of this placeholder
|
||||
* @param resolver the relational resolver,
|
||||
* in charge of obtaining data based on a relationship of 2 audiences
|
||||
* @param <A> the audience type, if not specified, will be a generic {@linkplain Audience}
|
||||
* @see RelationalTagResolver
|
||||
* @param key the key of the entire placeholder
|
||||
* @param name the name of this placeholder
|
||||
* @param resolver the relational resolver,
|
||||
* in charge of obtaining data based on a relationship of 2 audiences
|
||||
* @param <A> the audience type, if not specified, will be a generic {@linkplain Audience}
|
||||
* @apiNote The {@link #key()} method returns the full name of the placeholder,
|
||||
* for example, if the placeholder is {@code <server_name>},
|
||||
* the {@linkplain #key()} method will return {@code server_name}.
|
||||
* @see RelationalTagResolver
|
||||
*/
|
||||
@NullMarked
|
||||
public record RelationalPlaceholder<A extends Audience>(
|
||||
@Nullable Class<A> targetClass,
|
||||
@TagPattern String key,
|
||||
String name,
|
||||
RelationalTagResolver<A> resolver
|
||||
@Nullable Class<A> targetClass,
|
||||
@Nullable Predicate<A> targetFilter,
|
||||
@TagPattern String key,
|
||||
@TagPattern String name,
|
||||
RelationalTagResolver<A> resolver,
|
||||
@Nullable PlaceholderMetadata placeholderMetadata
|
||||
) implements Placeholder {
|
||||
|
||||
public RelationalPlaceholder(
|
||||
@Nullable Class<A> targetClass,
|
||||
@TagPattern String key,
|
||||
@TagPattern String name,
|
||||
RelationalTagResolver<A> resolver
|
||||
) {
|
||||
this(targetClass, null, key, name, resolver, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method capable of creating an instance of a relational placeholder.
|
||||
*
|
||||
* @param targetClass the target class, can be null
|
||||
* @param key the key of the entire placeholder
|
||||
* @param name the name of this placeholder
|
||||
* @param resolver the relational resolver,
|
||||
* in charge of obtaining data based on a relationship of 2 audiences
|
||||
* @param key the key of the entire placeholder
|
||||
* @param name the name of this placeholder
|
||||
* @param resolver the relational resolver,
|
||||
* in charge of obtaining data based on a relationship of 2 audiences
|
||||
* @param <A> the audience type, if not specified, will be a generic {@linkplain Audience}
|
||||
* @return a new RelationalPlaceholder
|
||||
* @param <A> the audience type, if not specified, will be a generic {@linkplain Audience}
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public static <A extends Audience> RelationalPlaceholder<A> relational(
|
||||
@Nullable Class<A> targetClass,
|
||||
@TagPattern String key,
|
||||
String name,
|
||||
RelationalTagResolver<A> resolver
|
||||
@Nullable Class<A> targetClass,
|
||||
@TagPattern String key,
|
||||
@TagPattern String name,
|
||||
RelationalTagResolver<A> resolver
|
||||
) {
|
||||
return new RelationalPlaceholder<>(targetClass, requireNonNull(key), name, requireNonNull(resolver));
|
||||
}
|
||||
|
||||
public static <A extends Audience> Builder<A> builder(Class<A> targetClazz) {
|
||||
return new Builder<>(targetClazz);
|
||||
}
|
||||
|
||||
public static Builder<Audience> builder() {
|
||||
return new Builder<>(Audience.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Tag resolve(String name, ArgumentQueue arguments, Context ctx) {
|
||||
final Pointered targetRaw = ctx.target();
|
||||
@@ -74,7 +97,7 @@ public record RelationalPlaceholder<A extends Audience>(
|
||||
}
|
||||
if (targetClass == null) {
|
||||
//noinspection unchecked
|
||||
return this.resolveA(name, (A)a, (A)b, arguments, ctx);
|
||||
return this.resolveA(name, (A) a, (A) b, arguments, ctx);
|
||||
}
|
||||
final @Nullable A audience = forwardingFilter(a);
|
||||
if (audience == null) {
|
||||
@@ -84,19 +107,22 @@ public record RelationalPlaceholder<A extends Audience>(
|
||||
if (relationalAudience == null) {
|
||||
return null;
|
||||
}
|
||||
if (targetFilter != null && (!targetFilter.test(audience) || !targetFilter.test(relationalAudience))) {
|
||||
return null;
|
||||
}
|
||||
return this.resolveA(name, audience, relationalAudience, arguments, ctx);
|
||||
}
|
||||
|
||||
private @Nullable Tag resolveA(
|
||||
String name,
|
||||
A audience,
|
||||
A relationalAudience,
|
||||
ArgumentQueue arguments,
|
||||
Context ctx
|
||||
String name,
|
||||
A audience,
|
||||
A relationalAudience,
|
||||
ArgumentQueue arguments,
|
||||
Context ctx
|
||||
) {
|
||||
return this.has(name)
|
||||
? resolver.tag(audience, relationalAudience, arguments, ctx)
|
||||
: null;
|
||||
? resolver.tag(audience, relationalAudience, arguments, ctx)
|
||||
: null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("OverrideOnly")
|
||||
@@ -112,7 +138,7 @@ public record RelationalPlaceholder<A extends Audience>(
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(@NotNull String name) {
|
||||
public boolean has(String name) {
|
||||
return key.equalsIgnoreCase(name);
|
||||
}
|
||||
|
||||
@@ -131,7 +157,62 @@ public record RelationalPlaceholder<A extends Audience>(
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RelationalPlaceholder{" +
|
||||
"key='" + key + '\'' +
|
||||
'}';
|
||||
"key='" + key + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
@NullUnmarked
|
||||
public static final class Builder<A extends Audience> {
|
||||
@NotNull
|
||||
private final Class<A> targetClass;
|
||||
@TagPattern
|
||||
private String name;
|
||||
@Nullable
|
||||
private Predicate<A> targetFilter;
|
||||
private RelationalTagResolver<@NotNull A> resolver;
|
||||
@Nullable
|
||||
private PlaceholderMetadata metadata;
|
||||
|
||||
Builder(final @NotNull Class<A> targetClass) {
|
||||
this.targetClass = targetClass;
|
||||
}
|
||||
|
||||
public Builder<A> name(final @NonNull @TagPattern String name) {
|
||||
this.name = requireNonNull(name, "placeholder name");
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<A> targetFilter(final Predicate<A> targetFilter) {
|
||||
this.targetFilter = targetFilter;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<A> resolver(final @NotNull RelationalTagResolver<@NotNull A> resolver) {
|
||||
this.resolver = requireNonNull(resolver);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<A> metadata(final PlaceholderMetadata metadata) {
|
||||
this.metadata = metadata;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull RelationalPlaceholder<@NonNull A> build(final @NotNull @Subst("expansion") String expansionPrefix) {
|
||||
requireNonNull(this.name, "name");
|
||||
requireNonNull(this.resolver, "resolver");
|
||||
return new RelationalPlaceholder<>(
|
||||
targetClass,
|
||||
targetFilter,
|
||||
expansionPrefix + name,
|
||||
name,
|
||||
resolver,
|
||||
metadata
|
||||
);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Provider<A extends Audience> {
|
||||
void provide(final Builder<A> builderProvider);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,28 +9,27 @@ import static java.util.Objects.requireNonNull;
|
||||
/**
|
||||
* A relationship between 2 Audiences.
|
||||
*
|
||||
* @param audience the principal audience
|
||||
* @param audience the principal audience
|
||||
* @param relational the secondary audience, with which the relationship will be evaluated
|
||||
* @param <A> the audiences type
|
||||
* @param <A> the audiences type
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@NullMarked
|
||||
public record RelationalAudience<A extends Audience>(A audience, A relational) implements ForwardingAudience.Single {
|
||||
public RelationalAudience {
|
||||
requireNonNull(audience);
|
||||
requireNonNull(relational);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new relation between two audiences.
|
||||
*
|
||||
* @param audience the principal audience
|
||||
* @param relational the secondary audience, with which the relationship will be evaluated
|
||||
* @return a new relation
|
||||
* @param <A> the audiences type
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public static <A extends Audience> RelationalAudience<A> from(A audience, A relational) {
|
||||
return new RelationalAudience<>(audience, relational);
|
||||
}
|
||||
public RelationalAudience {
|
||||
requireNonNull(audience);
|
||||
requireNonNull(relational);
|
||||
}
|
||||
/**
|
||||
* Creates a new relation between two audiences.
|
||||
*
|
||||
* @param audience the principal audience
|
||||
* @param relational the secondary audience, with which the relationship will be evaluated
|
||||
* @param <A> the audiences type
|
||||
* @return a new relation
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public static <A extends Audience> RelationalAudience<A> from(A audience, A relational) {
|
||||
return new RelationalAudience<>(audience, relational);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package io.github.miniplaceholders.test;
|
||||
|
||||
import io.github.miniplaceholders.api.Expansion;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.tag.Tag;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static net.kyori.adventure.text.minimessage.MiniMessage.miniMessage;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class ArgumentTest implements MiniTest {
|
||||
@Test
|
||||
@DisplayName("Empty Arguments")
|
||||
void testEmptyArguments() {
|
||||
final Expansion expansion = Expansion.builder("test")
|
||||
.globalPlaceholder("testing", (queue, ctx) -> {
|
||||
int arguments = 0;
|
||||
while (queue.hasNext()) {
|
||||
arguments++;
|
||||
Tag.Argument argument = queue.pop();
|
||||
assertTrue(argument.value().isBlank());
|
||||
}
|
||||
return Tag.selfClosingInserting(Component.text("Arguments: " + arguments));
|
||||
})
|
||||
.build();
|
||||
|
||||
Component parsed = miniMessage().deserialize("<test_testing::>", expansion.globalPlaceholders());
|
||||
|
||||
assertContentEquals(parsed, Component.text("Arguments: 2"));
|
||||
}
|
||||
}
|
||||
@@ -14,13 +14,13 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
class ExpansionsTest implements MiniTest {
|
||||
@Test
|
||||
@DisplayName("Expansion Equality")
|
||||
void equalsExpansions(){
|
||||
void equalsExpansions() {
|
||||
final Expansion firstExpansion = Expansion.builder("equals")
|
||||
.audiencePlaceholder("test", Tags.emptyAudienceResolver())
|
||||
.build();
|
||||
.audiencePlaceholder("test", Tags.emptyAudienceResolver())
|
||||
.build();
|
||||
final Expansion secondExpansion = Expansion.builder("equals")
|
||||
.audiencePlaceholder("test", Tags.emptyAudienceResolver())
|
||||
.build();
|
||||
.audiencePlaceholder("test", Tags.emptyAudienceResolver())
|
||||
.build();
|
||||
|
||||
assertEquals(firstExpansion, secondExpansion);
|
||||
}
|
||||
|
||||
@@ -1,83 +1,22 @@
|
||||
package io.github.miniplaceholders.test;
|
||||
|
||||
import static net.kyori.adventure.text.minimessage.MiniMessage.miniMessage;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import io.github.miniplaceholders.api.types.RelationalAudience;
|
||||
import io.github.miniplaceholders.test.instances.TestAudience;
|
||||
import io.github.miniplaceholders.test.instances.TestAudienceHolder;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
|
||||
import io.github.miniplaceholders.api.Expansion;
|
||||
import io.github.miniplaceholders.api.MiniPlaceholders;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.tag.Tag;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class PlaceholderTest implements MiniTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Audience Placeholder Test")
|
||||
void audienceExpansionPlaceholdersTest() {
|
||||
TestAudience player = new TestAudience("4drian3d");
|
||||
|
||||
Expansion expansion = Expansion.builder("example")
|
||||
.audiencePlaceholder("name", (aud, queue, ctx) -> {
|
||||
TestAudience audience = (TestAudience) aud;
|
||||
return Tag.selfClosingInserting(Component.text(audience.name()));
|
||||
}).build();
|
||||
|
||||
final Component expected = Component.text("Player Name: 4drian3d");
|
||||
final Component result = miniMessage().deserialize("Player Name: <example_name>", player, expansion.audiencePlaceholders());
|
||||
|
||||
assertContentEquals(expected, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Relational Placeholder Test")
|
||||
void relationalExpansionPlaceholdersTest() {
|
||||
Audience p1 = new TestAudience("PlayerOne");
|
||||
Audience p2 = new TestAudience("PlayerTwo");
|
||||
|
||||
Expansion expansion = Expansion.builder("relational")
|
||||
.relationalPlaceholder(TestAudience.class, "enemy",
|
||||
(aud, relational, queue, ctx) ->
|
||||
Tag.selfClosingInserting(this.isEnemy(aud, relational)
|
||||
? Component.text("Enemy", NamedTextColor.RED)
|
||||
: Component.text("Neutral", NamedTextColor.GREEN)
|
||||
))
|
||||
.build();
|
||||
|
||||
assertEquals(
|
||||
MiniMessage.miniMessage().deserialize("You are <red>Enemy"),
|
||||
MiniMessage.miniMessage().deserialize("You are <relational_rel_enemy>",
|
||||
RelationalAudience.from(p1, p2),
|
||||
expansion.relationalPlaceholders()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Global Placeholder Test")
|
||||
void globalExpansionPlaceholderTest() {
|
||||
Expansion expansion = Expansion.builder("global")
|
||||
.globalPlaceholder("players", (queue, ctx) -> Tag.selfClosingInserting(Component.text(1305)))
|
||||
.globalPlaceholder("servers", (queue, ctx) -> Tag.selfClosingInserting(Component.text(7)))
|
||||
.build();
|
||||
|
||||
final Component expected = Component.text("Online players: 1305 | Servers: 7");
|
||||
final Component actual = MiniMessage.miniMessage().deserialize("Online players: <global_players> | Servers: <global_servers>",
|
||||
expansion.globalPlaceholders());
|
||||
|
||||
assertContentEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Registered Placeholders")
|
||||
void instancePlaceholdersTest() {
|
||||
Expansion.builder("instance")
|
||||
.globalPlaceholder("hello", (queue, ctx) -> Tag.selfClosingInserting(Component.text("hello", NamedTextColor.RED)))
|
||||
.globalPlaceholder("hello", (queue, ctx) ->
|
||||
Tag.selfClosingInserting(Component.text("hello", NamedTextColor.RED)))
|
||||
.build()
|
||||
.register();
|
||||
|
||||
@@ -87,65 +26,4 @@ class PlaceholderTest implements MiniTest {
|
||||
assertContentEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Filtered Expansion")
|
||||
void filteredExpansion() {
|
||||
Expansion expansion = Expansion.builder("filter")
|
||||
.audiencePlaceholder(TestAudience.class, "name",
|
||||
(aud, queue, ctx) -> Tag.selfClosingInserting(Component.text(aud.name())))
|
||||
.build();
|
||||
|
||||
Audience player = new TestAudience("TestPlayer04");
|
||||
Audience emptyAudience = Audience.empty();
|
||||
|
||||
String string = "Player Name: <filter_name>";
|
||||
|
||||
Component playerExpected = Component.text("Player Name: TestPlayer04");
|
||||
Component emptyExpected = Component.text("Player Name: <filter_name>");
|
||||
|
||||
assertContentEquals(playerExpected, MiniMessage.miniMessage().deserialize(string, player, expansion.audiencePlaceholders()));
|
||||
assertContentEquals(emptyExpected, MiniMessage.miniMessage().deserialize(string, emptyAudience, expansion.audiencePlaceholders()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Empty Arguments")
|
||||
void testEmptyArguments() {
|
||||
final Expansion expansion = Expansion.builder("test")
|
||||
.globalPlaceholder("testing", (queue, ctx) -> {
|
||||
int arguments = 0;
|
||||
while (queue.hasNext()) {
|
||||
arguments++;
|
||||
Tag.Argument argument = queue.pop();
|
||||
assertTrue(argument.value().isBlank());
|
||||
}
|
||||
return Tag.selfClosingInserting(Component.text("Arguments: " + arguments));
|
||||
})
|
||||
.build();
|
||||
|
||||
Component parsed = miniMessage().deserialize("<test_testing::>", expansion.globalPlaceholders());
|
||||
|
||||
assertContentEquals(parsed, Component.text("Arguments: 2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Forwarding Audience Parsing Test")
|
||||
void forwardingAudienceTest() {
|
||||
Expansion expansion = Expansion.builder("test")
|
||||
.audiencePlaceholder(TestAudience.class, "testing",
|
||||
(audience, queue, ctx) -> Tag.selfClosingInserting(Component.text("Name: " + audience.name())))
|
||||
.build();
|
||||
|
||||
TestAudience testAudience = new TestAudience("4drian3d");
|
||||
Audience forward = new TestAudienceHolder(testAudience);
|
||||
|
||||
Component parsed = miniMessage().deserialize("<test_testing>.", forward, expansion.audiencePlaceholders());
|
||||
Component expected = Component.text("Name: 4drian3d.");
|
||||
|
||||
assertContentEquals(parsed, expected);
|
||||
}
|
||||
|
||||
private boolean isEnemy(TestAudience a1, TestAudience a2) {
|
||||
return a1.name().equals("PlayerOne") && a2.name().equals("PlayerTwo");
|
||||
}
|
||||
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
package io.github.miniplaceholders.test.placeholder;
|
||||
|
||||
import io.github.miniplaceholders.api.Expansion;
|
||||
import io.github.miniplaceholders.api.placeholder.PlaceholderMetadata;
|
||||
import io.github.miniplaceholders.test.MiniTest;
|
||||
import io.github.miniplaceholders.test.instances.TestAudience;
|
||||
import io.github.miniplaceholders.test.instances.TestAudienceHolder;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.tag.Tag;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static net.kyori.adventure.text.minimessage.MiniMessage.miniMessage;
|
||||
|
||||
public class AudiencePlaceholderTest implements MiniTest {
|
||||
@Test
|
||||
@DisplayName("Audience Placeholder Test")
|
||||
void audienceExpansionPlaceholdersTest() {
|
||||
TestAudience player = new TestAudience("4drian3d");
|
||||
|
||||
Expansion expansion = Expansion.builder("example")
|
||||
.audiencePlaceholder("name", (aud, queue, ctx) -> {
|
||||
TestAudience audience = (TestAudience) aud;
|
||||
return Tag.selfClosingInserting(Component.text(audience.name()));
|
||||
}).build();
|
||||
|
||||
final Component expected = Component.text("Player Name: 4drian3d");
|
||||
final Component result = miniMessage().deserialize("Player Name: <example_name>", player, expansion.audiencePlaceholders());
|
||||
|
||||
assertContentEquals(expected, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Forwarding Audience Parsing Test")
|
||||
void forwardingAudienceTest() {
|
||||
Expansion expansion = Expansion.builder("test")
|
||||
.audiencePlaceholder(TestAudience.class, "testing",
|
||||
(audience, queue, ctx) -> Tag.selfClosingInserting(Component.text("Name: " + audience.name())))
|
||||
.build();
|
||||
|
||||
TestAudience testAudience = new TestAudience("4drian3d");
|
||||
Audience forward = new TestAudienceHolder(testAudience);
|
||||
|
||||
Component parsed = miniMessage().deserialize("<test_testing>.", forward, expansion.audiencePlaceholders());
|
||||
Component expected = Component.text("Name: 4drian3d.");
|
||||
|
||||
assertContentEquals(parsed, expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Filtered Expansion")
|
||||
void filteredExpansion() {
|
||||
Expansion expansion = Expansion.builder("filter")
|
||||
.audiencePlaceholder(TestAudience.class, "name",
|
||||
(aud, queue, ctx) -> Tag.selfClosingInserting(Component.text(aud.name())))
|
||||
.build();
|
||||
|
||||
Audience player = new TestAudience("TestPlayer04");
|
||||
Audience emptyAudience = Audience.empty();
|
||||
|
||||
String string = "Player Name: <filter_name>";
|
||||
|
||||
Component playerExpected = Component.text("Player Name: TestPlayer04");
|
||||
Component emptyExpected = Component.text("Player Name: <filter_name>");
|
||||
|
||||
assertContentEquals(playerExpected, MiniMessage.miniMessage().deserialize(string, player, expansion.audiencePlaceholders()));
|
||||
assertContentEquals(emptyExpected, MiniMessage.miniMessage().deserialize(string, emptyAudience, expansion.audiencePlaceholders()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("AudiencePlaceholder Builder creation")
|
||||
void builderAudiencePlaceholderCreation() {
|
||||
final Expansion expansion = Expansion.builder("builder")
|
||||
.audiencePlaceholder(
|
||||
TestAudience.class,
|
||||
builder -> builder.name("test")
|
||||
.resolver((audience, queue, ctx) -> {
|
||||
final String name = audience.name();
|
||||
return Tag.preProcessParsed(name);
|
||||
})
|
||||
.metadata(PlaceholderMetadata.data("Builder Test", "Returns the Audience Name"))
|
||||
.targetFilter(target -> target.name().length() <= 16)
|
||||
).build();
|
||||
final TestAudience audience = new TestAudience("4drian3d");
|
||||
|
||||
Component expected = Component.text("My name is: 4drian3d");
|
||||
Component parsed = miniMessage().deserialize("My name is: <builder_test>", audience, expansion.audiencePlaceholders());
|
||||
|
||||
assertContentEquals(expected, parsed);
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package io.github.miniplaceholders.test.placeholder;
|
||||
|
||||
import io.github.miniplaceholders.api.Expansion;
|
||||
import io.github.miniplaceholders.test.MiniTest;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.tag.Tag;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class GlobalPlaceholderTest implements MiniTest {
|
||||
@Test
|
||||
@DisplayName("Global Placeholder Test")
|
||||
void globalExpansionPlaceholderTest() {
|
||||
Expansion expansion = Expansion.builder("global")
|
||||
.globalPlaceholder("players", (queue, ctx) -> Tag.selfClosingInserting(Component.text(1305)))
|
||||
.globalPlaceholder("servers", (queue, ctx) -> Tag.selfClosingInserting(Component.text(7)))
|
||||
.build();
|
||||
|
||||
final Component expected = Component.text("Online players: 1305 | Servers: 7");
|
||||
final Component actual = MiniMessage.miniMessage().deserialize("Online players: <global_players> | Servers: <global_servers>",
|
||||
expansion.globalPlaceholders());
|
||||
|
||||
assertContentEquals(expected, actual);
|
||||
}
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
package io.github.miniplaceholders.test.placeholder;
|
||||
|
||||
import io.github.miniplaceholders.api.Expansion;
|
||||
import io.github.miniplaceholders.api.placeholder.PlaceholderMetadata;
|
||||
import io.github.miniplaceholders.api.types.RelationalAudience;
|
||||
import io.github.miniplaceholders.test.MiniTest;
|
||||
import io.github.miniplaceholders.test.instances.TestAudience;
|
||||
import io.github.miniplaceholders.test.instances.TestAudienceHolder;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.tag.Tag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static net.kyori.adventure.text.minimessage.MiniMessage.miniMessage;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class RelationalPlaceholderTest implements MiniTest {
|
||||
@Test
|
||||
@DisplayName("Relational Placeholder Test")
|
||||
void relationalExpansionPlaceholdersTest() {
|
||||
Audience p1 = new TestAudience("PlayerOne");
|
||||
Audience p2 = new TestAudience("PlayerTwo");
|
||||
|
||||
Expansion expansion = Expansion.builder("relational")
|
||||
.relationalPlaceholder(TestAudience.class, "enemy",
|
||||
(aud, relational, queue, ctx) ->
|
||||
Tag.selfClosingInserting(this.isEnemy(aud, relational)
|
||||
? Component.text("Enemy", NamedTextColor.RED)
|
||||
: Component.text("Neutral", NamedTextColor.GREEN)
|
||||
))
|
||||
.build();
|
||||
|
||||
assertEquals(
|
||||
MiniMessage.miniMessage().deserialize("You are <red>Enemy"),
|
||||
MiniMessage.miniMessage().deserialize("You are <relational_rel_enemy>",
|
||||
RelationalAudience.from(p1, p2),
|
||||
expansion.relationalPlaceholders()));
|
||||
}
|
||||
|
||||
private boolean isEnemy(TestAudience a1, TestAudience a2) {
|
||||
return a1.name().equals("PlayerOne") && a2.name().equals("PlayerTwo");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Relational Forwarding Audience Parsing Test")
|
||||
void relationalForwardingAudienceTest() {
|
||||
Expansion expansion = Expansion.builder("test")
|
||||
.relationalPlaceholder(TestAudience.class, "testing",
|
||||
(audience, another, queue, ctx) ->
|
||||
Tag.selfClosingInserting(Component.text("Name: " + audience.name() + ", Other Name: " + another.name())))
|
||||
.build();
|
||||
|
||||
TestAudience testAudience = new TestAudience("4drian3d");
|
||||
TestAudience secondAudience = new TestAudience("PepitoAlcachofa");
|
||||
Audience forward = new TestAudienceHolder(testAudience);
|
||||
Audience secondForward = new TestAudienceHolder(secondAudience);
|
||||
|
||||
Component parsed = miniMessage().deserialize("<test_rel_testing>.",
|
||||
RelationalAudience.from(forward, secondForward), expansion.relationalPlaceholders());
|
||||
Component expected = Component.text("Name: 4drian3d, Other Name: PepitoAlcachofa.");
|
||||
|
||||
assertContentEquals(expected, parsed);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Relational Filtered Expansion")
|
||||
void relationalFilteredExpansion() {
|
||||
Expansion expansion = Expansion.builder("filter")
|
||||
.relationalPlaceholder(TestAudience.class, "name",
|
||||
(aud, another, queue, ctx) ->
|
||||
Tag.selfClosingInserting(Component.text(aud.name().replace(another.name(), ""))))
|
||||
.build();
|
||||
|
||||
Audience player = new TestAudience("TestPlayer04");
|
||||
Audience second = new TestAudience("Player");
|
||||
Audience emptyAudience = Audience.empty();
|
||||
|
||||
String string = "Player Name: <filter_rel_name>";
|
||||
|
||||
Component playerExpected = Component.text("Player Name: Test04");
|
||||
Component emptyExpected = Component.text("Player Name: <filter_rel_name>");
|
||||
|
||||
assertContentEquals(playerExpected, MiniMessage.miniMessage().deserialize(string,
|
||||
RelationalAudience.from(player, second), expansion.relationalPlaceholders()));
|
||||
assertContentEquals(emptyExpected, MiniMessage.miniMessage().deserialize(string,
|
||||
RelationalAudience.from(player, emptyAudience), expansion.relationalPlaceholders()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("RelationalPlaceholder Builder creation")
|
||||
void builderRelationalPlaceholderCreation() {
|
||||
final Expansion expansion = Expansion.builder("builder")
|
||||
.relationalPlaceholder(
|
||||
TestAudience.class,
|
||||
builder -> builder.name("test")
|
||||
.resolver((audience, relational, queue, ctx) -> {
|
||||
final String name = audience.name();
|
||||
final String relationalName = relational.name();
|
||||
return Tag.preProcessParsed(name + " and " + relationalName);
|
||||
})
|
||||
.metadata(PlaceholderMetadata.data("Builder Test", "Returns the Audience plus the Relational Audience combined Names"))
|
||||
.targetFilter(target -> target.name().length() <= 16)
|
||||
).build();
|
||||
final TestAudience audience = new TestAudience("4drian3d");
|
||||
final TestAudience relational = new TestAudience("PepitoAlcachofa");
|
||||
final RelationalAudience<@NotNull TestAudience> relationalAudience = RelationalAudience.from(audience, relational);
|
||||
|
||||
Component expected = Component.text("Our names are: 4drian3d and PepitoAlcachofa");
|
||||
Component parsed = miniMessage().deserialize("Our names are: <builder_test>", relationalAudience, expansion.relationalPlaceholders());
|
||||
|
||||
assertContentEquals(expected, parsed);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user