1
mirror of https://github.com/CarmJos/MineConfiguration.git synced 2024-09-19 20:05:49 +00:00

feat(notify): 尝试实现整合的消息配置 #39

This commit is contained in:
Carm Jos 2023-12-25 02:33:37 +08:00
parent b737e4dda2
commit 38292052f5
15 changed files with 419 additions and 6 deletions

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>mineconfiguration-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>2.8.9</version>
<version>2.9.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>

View File

@ -37,7 +37,7 @@ public class PreparedMessage<R, M> {
*
* @param receivers 消息的接收者们
*/
public void to(@NotNull Iterable<R> receivers) {
public void to(@NotNull Iterable<? extends R> receivers) {
receivers.forEach(this::to);
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>mineconfiguration-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>2.8.9</version>
<version>2.9.1</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -0,0 +1,51 @@
package cc.carm.lib.mineconfiguration.bukkit.data;
import cc.carm.lib.mineconfiguration.bukkit.value.notify.ConfiguredNotify;
import cc.carm.lib.mineconfiguration.bukkit.value.notify.NotifyType;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import java.util.regex.Matcher;
public class NotifyConfig<T extends NotifyType<M>, M> {
public static @Nullable NotifyConfig<?, ?> deserialize(@NotNull String config) {
// parse config with config_format
Matcher matcher = NotifyType.CONFIG_FORMAT.matcher(config.trim());
if (!matcher.matches()) return of("MESSAGE", null, config);
else return of(matcher.group("type"), matcher.group("param"), matcher.group("content"));
}
public static @Nullable NotifyConfig<?, ?> of(@NotNull String key, @Nullable String param, @Nullable String content) {
NotifyType<?> type = ConfiguredNotify.getType(key);
if (type == null) return null;
return NotifyConfig.of(type, param, content);
}
public static <T extends NotifyType<M>, M> NotifyConfig<T, M> of(@NotNull T type, @Nullable String param, @Nullable String content) {
return new NotifyConfig<>(type, type.parseMeta(param, content));
}
public static <T extends NotifyType<M>, M> NotifyConfig<T, M> of(@NotNull T type, @Nullable M meta) {
return new NotifyConfig<>(type, meta);
}
protected final @NotNull T type;
protected final @Nullable M meta;
public NotifyConfig(@NotNull T type, @Nullable M meta) {
this.type = type;
this.meta = meta;
}
public void execute(@NotNull Player player, @NotNull Map<String, Object> placeholders) {
type.execute(player, meta, placeholders);
}
public String serialize() {
return type.serializeConfig(meta);
}
}

View File

@ -58,6 +58,30 @@ public class TitleConfig {
this.fadeOut = fadeOut;
}
public int getFadeIn() {
return fadeIn;
}
public int getFadeOut() {
return fadeOut;
}
public int getStay() {
return stay;
}
public boolean isStandardTime() {
return this.fadeIn == 10 && this.stay == 60 && this.fadeOut == 10;
}
public @Nullable TextConfig getLine1() {
return line1;
}
public @Nullable TextConfig getLine2() {
return line2;
}
public void send(@NotNull Player player,
@NotNull Map<String, Object> placeholders,
@Nullable ConfiguredTitle.TitleConsumer sendConsumer) {

View File

@ -7,6 +7,9 @@ import java.util.List;
public class PlaceholderAPIHelper {
private PlaceholderAPIHelper() {
}
public static String parseMessages(Player player, String message) {
try {
return PlaceholderAPI.setPlaceholders(player, message);

View File

@ -15,6 +15,9 @@ import java.util.stream.Collectors;
public class TextParser {
private TextParser() {
}
@Contract("_,!null,_->!null")
public static @Nullable String parseText(@Nullable CommandSender sender, @Nullable String message, @NotNull Map<String, Object> placeholders) {
if (message == null) return null;

View File

@ -0,0 +1,60 @@
package cc.carm.lib.mineconfiguration.bukkit.value.notify;
import cc.carm.lib.configuration.core.value.ValueManifest;
import cc.carm.lib.configuration.core.value.type.ConfiguredList;
import cc.carm.lib.mineconfiguration.bukkit.data.NotifyConfig;
import cc.carm.lib.mineconfiguration.bukkit.value.notify.type.SoundNotify;
import cc.carm.lib.mineconfiguration.bukkit.value.notify.type.StringNotify;
import cc.carm.lib.mineconfiguration.bukkit.value.notify.type.TitleNotify;
import cc.carm.lib.mineconfiguration.common.utils.ParamsUtils;
import com.cryptomorin.xseries.messages.ActionBar;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.*;
@SuppressWarnings("rawtypes")
public class ConfiguredNotify extends ConfiguredList<NotifyConfig> {
public static final Set<NotifyType<?>> TYPES = new HashSet<>();
static {
TYPES.add(StringNotify.of("MESSAGE", Player::sendMessage, content -> Optional.ofNullable(content).orElse(" ")));
TYPES.add(StringNotify.of("MSG", Player::sendMessage));
TYPES.add(StringNotify.of("ACTIONBAR", ActionBar::sendActionBar));
TYPES.add(new TitleNotify("TITLE"));
TYPES.add(new SoundNotify("SOUND"));
}
public static NotifyType<?> getType(@NotNull String key) {
return TYPES.stream().filter(type -> type.key.equals(key)).findFirst().orElse(null);
}
protected final @NotNull String[] params;
public ConfiguredNotify(@NotNull ValueManifest<List<NotifyConfig>> manifest, @NotNull String[] params) {
super(manifest, NotifyConfig.class, obj -> Objects.requireNonNull(NotifyConfig.deserialize(String.valueOf(obj))), NotifyConfig::serialize);
this.params = params;
}
public String[] getParams() {
return params;
}
public @NotNull PreparedNotify prepare(@NotNull String... values) {
return new PreparedNotify(getNotNull(), ParamsUtils.buildParams(getParams(), values));
}
public void send(@NotNull Player player, @NotNull String... values) {
prepare(values).to(player);
}
public void send(@NotNull Iterable<? extends Player> players, @NotNull String... values) {
prepare(values).to(players);
}
public void sendAll(@NotNull String... values) {
prepare(values).toAll();
}
}

View File

@ -0,0 +1,65 @@
package cc.carm.lib.mineconfiguration.bukkit.value.notify;
import cc.carm.lib.mineconfiguration.bukkit.utils.TextParser;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import java.util.regex.Pattern;
public abstract class NotifyType<M> {
// Notify config format: [TYPE(@PARAM)] CONTENTS...
public static final @NotNull Pattern CONFIG_FORMAT = Pattern.compile("^\\[(?<type>[^@\\]]+)(@(?<param>[^]]+))?] (?<content>.*)$");
protected final @NotNull String key;
protected final @NotNull Class<M> metaClass;
protected NotifyType(@NotNull String key, @NotNull Class<M> metaClass) {
this.key = key;
this.metaClass = metaClass;
}
public @NotNull String getKey() {
return key;
}
public @NotNull Class<M> getMetaClass() {
return metaClass;
}
/**
* Parse metadata from string.
* <br> e.g. "[TYPE-KEY@PARAM] CONTENTS..."
*
* @param param The param of the notify config.
* @param content The content of the notify config.
* @return The parsed metadata.
*/
public abstract @Nullable M parseMeta(@Nullable String param, @Nullable String content);
/**
* Serialize the metadata to singleton string to storage on configs.
*
* @param meta The parsed metadata.
* @return The serialized string.
*/
public abstract @NotNull String serializeConfig(@Nullable M meta);
/**
* Execute the notify content to specific player.
*
* @param player The player who receive the notification.
* @param meta The parsed metadata.
*/
public abstract void execute(@NotNull Player player, @Nullable M meta, @NotNull Map<String, Object> placeholders);
@Contract("_, _, null -> null; _, _, !null -> !null")
protected String setPlaceholders(@NotNull Player player, @Nullable String content,
@NotNull Map<String, Object> placeholders) {
return TextParser.parseText(player, content, placeholders);
}
}

View File

@ -0,0 +1,46 @@
package cc.carm.lib.mineconfiguration.bukkit.value.notify;
import cc.carm.lib.mineconfiguration.bukkit.data.NotifyConfig;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Map;
@SuppressWarnings({"rawtypes", "unchecked"})
public class PreparedNotify {
protected final @NotNull List<NotifyConfig> notifications;
protected final @NotNull Map<String, Object> placeholders;
protected PreparedNotify(@NotNull List<NotifyConfig> notifications, @NotNull Map<String, Object> placeholders) {
this.notifications = notifications;
this.placeholders = placeholders;
}
/**
* 向某位接收者发送消息
*
* @param receiver 消息的接收者
*/
public void to(@NotNull Player receiver) {
notifications.forEach(config -> config.execute(receiver, placeholders));
}
/**
* 向某位接收者发送消息
*
* @param receivers 消息的接收者们
*/
public void to(@NotNull Iterable<? extends Player> receivers) {
receivers.forEach(this::to);
}
public void toAll() {
to(Bukkit.getOnlinePlayers());
}
}

View File

@ -0,0 +1,48 @@
package cc.carm.lib.mineconfiguration.bukkit.value.notify.type;
import cc.carm.lib.mineconfiguration.bukkit.data.SoundConfig;
import cc.carm.lib.mineconfiguration.bukkit.value.notify.NotifyType;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
public class SoundNotify extends NotifyType<SoundConfig> {
public SoundNotify(@NotNull String key) {
super(key, SoundConfig.class);
}
@Override
public @Nullable SoundConfig parseMeta(@Nullable String param, @Nullable String content) {
if (content == null) return null;
String[] args = content.split(",");
try {
return new SoundConfig(content,
(args.length >= 1) ? Float.parseFloat(args[0]) : 1,
(args.length >= 2) ? Float.parseFloat(args[1]) : 1
);
} catch (Exception exception) {
return null;
}
}
@Override
public @NotNull String serializeConfig(@Nullable SoundConfig meta) {
if (meta == null) return "[" + key + "] ";
if (meta.getVolume() == 1 && meta.getPitch() == 1) {
return "[" + key + "] " + meta.getTypeName();
} else {
return "[" + key + "@" + +meta.getVolume() + "," + meta.getPitch() + "] " + meta.getTypeName();
}
}
@Override
public void execute(@NotNull Player player, @Nullable SoundConfig meta, @NotNull Map<String, Object> placeholders) {
if (meta != null) meta.playTo(player);
}
}

View File

@ -0,0 +1,52 @@
package cc.carm.lib.mineconfiguration.bukkit.value.notify.type;
import cc.carm.lib.mineconfiguration.bukkit.value.notify.NotifyType;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.UnaryOperator;
public abstract class StringNotify extends NotifyType<String> {
public static StringNotify of(String key, BiConsumer<Player, String> consumer) {
return of(key, consumer, (content) -> "[" + key + "] " + (content == null ? " " : content));
}
public static StringNotify of(String key,
BiConsumer<Player, String> consumer,
UnaryOperator<String> serializer) {
return new StringNotify(key) {
@Override
public @NotNull String serializeConfig(@Nullable String meta) {
return serializer.apply(meta);
}
@Override
public void send(@NotNull Player player, @NotNull String parsedContent) {
consumer.accept(player, parsedContent);
}
};
}
protected StringNotify(String key) {
super(key, String.class);
}
public abstract void send(@NotNull Player player, @NotNull String parsedContent);
@Override
public @Nullable String parseMeta(@Nullable String param, @Nullable String content) {
return content;
}
@Override
public void execute(@NotNull Player player, @Nullable String content, @NotNull Map<String, Object> placeholders) {
if (content == null) return;
send(player, setPlaceholders(player, content, placeholders));
}
}

View File

@ -0,0 +1,61 @@
package cc.carm.lib.mineconfiguration.bukkit.value.notify.type;
import cc.carm.lib.mineconfiguration.bukkit.data.TitleConfig;
import cc.carm.lib.mineconfiguration.bukkit.value.notify.NotifyType;
import com.cryptomorin.xseries.messages.Titles;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
public class TitleNotify extends NotifyType<TitleConfig> {
//Title param format fadeIn,Stay,FadeOut
public static final String PARAM_FORMAT = "(?<fadeIn>\\d+),(?<stay>\\d+),(?<fadeOut>\\d+)";
public TitleNotify(String key) {
super(key, TitleConfig.class);
}
@Override
public @Nullable TitleConfig parseMeta(@Nullable String param, @Nullable String content) {
if (content == null) return null;
String[] lines = content.split("\\{n}");
if (param == null) {
return TitleConfig.of(content, null);
} else {
String[] params = param.split(",");
if (params.length == 3) {
try {
return TitleConfig.of(content, null,
Integer.parseInt(params[0]),
Integer.parseInt(params[1]),
Integer.parseInt(params[2]));
} catch (Exception ex) {
return TitleConfig.of(content, null);
}
}
}
return null;
}
@Override
public @NotNull String serializeConfig(@Nullable TitleConfig meta) {
if (meta == null || (meta.getLine1() == null && meta.getLine2() == null)) return "[" + key + "] ";
String line1 = meta.getLine1() == null ? "" : meta.getLine1().getMessage();
String line2 = meta.getLine2() == null ? "" : meta.getLine2().getMessage();
if (meta.isStandardTime()) {
return "[" + key + "] " + line1 + "{n}" + line1;
} else
return "[" + key + "@" + meta.getFadeIn() + "," + meta.getStay() + "," + meta.getFadeOut() + "] " + line1 + "{n}" + line1;
}
@Override
public void execute(@NotNull Player player, @Nullable TitleConfig meta, @NotNull Map<String, Object> placeholders) {
if (meta != null) meta.send(player, placeholders, Titles::sendTitle);
}
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>mineconfiguration-parent</artifactId>
<groupId>cc.carm.lib</groupId>
<version>2.8.9</version>
<version>2.9.1</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -10,14 +10,14 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<deps.easyconfifuration.version>3.8.1</deps.easyconfifuration.version>
<deps.easyconfifuration.version>3.9.1</deps.easyconfifuration.version>
<deps.easyplugin.version>1.5.11</deps.easyplugin.version>
<deps.yamlcommentwriter.version>1.0.1</deps.yamlcommentwriter.version>
</properties>
<groupId>cc.carm.lib</groupId>
<artifactId>mineconfiguration-parent</artifactId>
<version>2.8.9</version>
<version>2.9.1</version>
<packaging>pom</packaging>
<modules>
<module>common</module>