diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/bridge/BridgeManager.java b/eternalcore-core/src/main/java/com/eternalcode/core/bridge/BridgeManager.java index b1a23aa70..750270bca 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/bridge/BridgeManager.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/bridge/BridgeManager.java @@ -2,7 +2,7 @@ import com.eternalcode.core.bridge.dynmap.DynmapBridgeInitializer; import com.eternalcode.core.bridge.placeholderapi.PlaceholderApiExtension; -import com.eternalcode.core.bridge.placeholderapi.PlaceholderApiReplacer; +import com.eternalcode.core.bridge.placeholderapi.PlaceholderAPIPlaceholder; import com.eternalcode.core.feature.vanish.VanishService; import com.eternalcode.core.placeholder.PlaceholderRegistry; import org.bukkit.Server; @@ -38,7 +38,7 @@ class BridgeManager { void init() { this.setupBridge("PlaceholderAPI", () -> { - this.placeholderRegistry.register(new PlaceholderApiReplacer()); + this.placeholderRegistry.register(new PlaceholderAPIPlaceholder()); new PlaceholderApiExtension(this.placeholderRegistry, this.pluginDescriptionFile).initialize(); }); diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/bridge/placeholderapi/PlaceholderApiReplacer.java b/eternalcore-core/src/main/java/com/eternalcode/core/bridge/placeholderapi/PlaceholderAPIPlaceholder.java similarity index 71% rename from eternalcore-core/src/main/java/com/eternalcode/core/bridge/placeholderapi/PlaceholderApiReplacer.java rename to eternalcore-core/src/main/java/com/eternalcode/core/bridge/placeholderapi/PlaceholderAPIPlaceholder.java index 232775b53..8eea3090d 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/bridge/placeholderapi/PlaceholderApiReplacer.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/bridge/placeholderapi/PlaceholderAPIPlaceholder.java @@ -1,11 +1,10 @@ package com.eternalcode.core.bridge.placeholderapi; -import com.eternalcode.core.placeholder.Placeholder; import me.clip.placeholderapi.PlaceholderAPI; import org.bukkit.entity.Player; -public class PlaceholderApiReplacer implements Placeholder { +public class PlaceholderAPIPlaceholder implements Placeholder { @Override public String apply(String text, Player targetPlayer) { diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/bridge/placeholderapi/PlaceholderApiExtension.java b/eternalcore-core/src/main/java/com/eternalcode/core/bridge/placeholderapi/PlaceholderApiExtension.java index 2eb14ccc6..cca53500f 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/bridge/placeholderapi/PlaceholderApiExtension.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/bridge/placeholderapi/PlaceholderApiExtension.java @@ -1,7 +1,7 @@ package com.eternalcode.core.bridge.placeholderapi; import com.eternalcode.core.bridge.BridgeInitializer; -import com.eternalcode.core.placeholder.PlaceholderRaw; +import com.eternalcode.core.placeholder.NamedPlaceholder; import com.eternalcode.core.placeholder.PlaceholderRegistry; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import org.bukkit.entity.Player; @@ -23,10 +23,10 @@ public PlaceholderApiExtension(PlaceholderRegistry placeholderRegistry, PluginDe @Override public @Nullable String onPlaceholderRequest(Player player, @NotNull String params) { - Optional optional = this.placeholderRegistry.getRawPlaceholder(params); + Optional optional = this.placeholderRegistry.getNamedPlaceholder(params); if (optional.isPresent()) { - return optional.get().rawApply(player); + return optional.get().provideValue(player); } return "Unknown placeholder!"; diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/afk/placeholder/AfkPlaceholderSetup.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/afk/placeholder/AfkPlaceholderSetup.java index 6a3215a83..cdc29320f 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/afk/placeholder/AfkPlaceholderSetup.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/afk/placeholder/AfkPlaceholderSetup.java @@ -8,7 +8,6 @@ import com.eternalcode.core.injector.annotations.Inject; import com.eternalcode.core.injector.annotations.component.Controller; import com.eternalcode.core.placeholder.PlaceholderRegistry; -import com.eternalcode.core.placeholder.Placeholder; import com.eternalcode.core.publish.Subscribe; import com.eternalcode.core.publish.event.EternalInitializeEvent; import com.eternalcode.core.translation.Translation; diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/home/HomePlaceholderSetup.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/home/HomePlaceholderSetup.java index 86f302c84..4f20ef28c 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/home/HomePlaceholderSetup.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/home/HomePlaceholderSetup.java @@ -5,7 +5,6 @@ import com.eternalcode.core.injector.annotations.Inject; import com.eternalcode.core.injector.annotations.component.Controller; import com.eternalcode.core.placeholder.PlaceholderRegistry; -import com.eternalcode.core.placeholder.Placeholder; import com.eternalcode.core.publish.Subscribe; import com.eternalcode.core.publish.event.EternalInitializeEvent; import com.eternalcode.core.translation.Translation; diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/MsgPlaceholderSetup.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/MsgPlaceholderSetup.java new file mode 100644 index 000000000..161c52b45 --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/MsgPlaceholderSetup.java @@ -0,0 +1,73 @@ +package com.eternalcode.core.feature.msg; + +import com.eternalcode.core.feature.msg.toggle.MsgState; +import com.eternalcode.core.feature.msg.toggle.MsgToggleRepository; +import com.eternalcode.core.injector.annotations.Inject; +import com.eternalcode.core.injector.annotations.component.Controller; +import com.eternalcode.core.placeholder.PlaceholderRegistry; +import com.eternalcode.core.placeholder.Placeholder; +import com.eternalcode.core.placeholder.watcher.PlaceholderWatcherKey; +import com.eternalcode.core.publish.Subscribe; +import com.eternalcode.core.publish.event.EternalInitializeEvent; +import com.eternalcode.core.translation.Translation; +import com.eternalcode.core.translation.TranslationManager; +import java.util.UUID; + +@Controller +public class MsgPlaceholderSetup { + + public static final PlaceholderWatcherKey MSG_STATE = PlaceholderWatcherKey.of("msg_state", MsgState.class); + + private final MsgService msgService; + private final MsgToggleRepository msgToggleRepository; + private final TranslationManager translationManager; + + @Inject + MsgPlaceholderSetup( + MsgService msgService, + MsgToggleRepository msgToggleRepository, + TranslationManager translationManager + ) { + this.msgService = msgService; + this.msgToggleRepository = msgToggleRepository; + this.translationManager = translationManager; + } + + @Subscribe(EternalInitializeEvent.class) + void setUpPlaceholders(PlaceholderRegistry registry) { + Translation translation = this.translationManager.getMessages(); + + registry.registerPlaceholder(Placeholder.of( + "socialspy_status", + player -> String.valueOf(this.msgService.isSpy(player.getUniqueId())) + )); + + registry.registerPlaceholder(Placeholder.of( + "socialspy_status_formatted", + player -> { + UUID uuid = player.getUniqueId(); + return this.msgService.isSpy(uuid) + ? translation.msg().placeholders().socialSpyEnabled() + : translation.msg().placeholders().socialSpyDisabled(); + } + )); + + registry.registerPlaceholder(Placeholder.async( + "msg_status", + MSG_STATE, + player -> msgToggleRepository.getPrivateChatState(player), + state -> state.name().toLowerCase() + )); + + registry.registerPlaceholder(Placeholder.async( + "msg_status_formatted", + MSG_STATE, + player -> msgToggleRepository.getPrivateChatState(player), + state -> state == MsgState.ENABLED + ? translation.msg().placeholders().msgEnabled() + : translation.msg().placeholders().msgDisabled() + ) + ); + } + +} diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/messages/ENMsgMessages.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/messages/ENMsgMessages.java index 5dcfdfcee..dc9a7e015 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/messages/ENMsgMessages.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/messages/ENMsgMessages.java @@ -38,4 +38,22 @@ public class ENMsgMessages extends OkaeriConfig implements MsgMessages { Notice socialSpyEnable = Notice.chat("SocialSpy has been {STATE}!"); Notice socialSpyDisable = Notice.chat("SocialSpy has been {STATE}!"); + @Comment("# Formatowanie placeholderów") + public ENPlaceholders placeholders = new ENPlaceholders(); + + @Getter + @Accessors(fluent = true) + public static class ENPlaceholders extends OkaeriConfig implements MsgMessages.Placeholders { + private String loading = "Loading..."; + + private String msgEnabled = "Enabled"; + private String msgDisabled = "Disabled"; + private String socialSpyEnabled = "Enabled"; + private String socialSpyDisabled = "Disabled"; + } + + public ENPlaceholders placeholders() { + return this.placeholders; + } + } diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/messages/MsgMessages.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/messages/MsgMessages.java index 070f0b391..9f5831a70 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/messages/MsgMessages.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/messages/MsgMessages.java @@ -17,4 +17,16 @@ public interface MsgMessages { Notice otherMessagesDisabled(); Notice otherMessagesEnabled(); + Placeholders placeholders(); + + interface Placeholders { + String loading(); + + String msgEnabled(); + String msgDisabled(); + + String socialSpyEnabled(); + String socialSpyDisabled(); + } + } diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/messages/PLMsgMessages.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/messages/PLMsgMessages.java index 4bdd0f4dc..0569a6d75 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/messages/PLMsgMessages.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/messages/PLMsgMessages.java @@ -38,4 +38,21 @@ public class PLMsgMessages extends OkaeriConfig implements MsgMessages { Notice otherMessagesEnabled = Notice.chat( "Wiadomości prywatne zostały włączone dla gracza {PLAYER}!"); + @Comment("# Formatowanie placeholderów") + public PLPlaceholders placeholders = new PLPlaceholders(); + + @Getter + @Accessors(fluent = true) + public static class PLPlaceholders extends OkaeriConfig implements MsgMessages.Placeholders { + private String loading = "Ładowanie..."; + + private String msgEnabled = "Włączone"; + private String msgDisabled = "Wyłączone"; + private String socialSpyEnabled = "Włączony"; + private String socialSpyDisabled = "Wyłączony"; + } + + public PLPlaceholders placeholders() { + return this.placeholders; + } } diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/toggle/MsgToggleRepository.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/toggle/MsgToggleRepository.java index 51c429ae0..efc4d6aad 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/toggle/MsgToggleRepository.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/toggle/MsgToggleRepository.java @@ -4,10 +4,10 @@ import java.util.UUID; import java.util.concurrent.CompletableFuture; -interface MsgToggleRepository { +public interface MsgToggleRepository { CompletableFuture getPrivateChatState(UUID uuid); - CompletableFuture setPrivateChatState(UUID uuid, MsgState toggledOff); + CompletableFuture setPrivateChatState(UUID uuid, MsgState state); } diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/toggle/MsgToggleRepositoryOrmLite.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/toggle/MsgToggleRepositoryOrmLite.java index effafef03..a28cc7a2b 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/toggle/MsgToggleRepositoryOrmLite.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/toggle/MsgToggleRepositoryOrmLite.java @@ -28,8 +28,8 @@ public CompletableFuture getPrivateChatState(UUID uuid) { } @Override - public CompletableFuture setPrivateChatState(UUID uuid, MsgState state) { + public CompletableFuture setPrivateChatState(UUID uuid, MsgState state) { return this.save(MsgStateTable.class, new MsgStateTable(uuid, state)) - .thenApply(status -> null); + .thenApply(status -> state); } } diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/toggle/MsgToggleServiceImpl.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/toggle/MsgToggleServiceImpl.java index 227d40e5d..cf253dea1 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/toggle/MsgToggleServiceImpl.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/msg/toggle/MsgToggleServiceImpl.java @@ -1,43 +1,34 @@ package com.eternalcode.core.feature.msg.toggle; +import com.eternalcode.core.feature.msg.MsgPlaceholderSetup; import com.eternalcode.core.injector.annotations.Inject; import com.eternalcode.core.injector.annotations.component.Service; +import com.eternalcode.core.placeholder.PlaceholderRegistry; +import com.eternalcode.core.placeholder.watcher.PlaceholderWatcher; import java.util.UUID; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; @Service class MsgToggleServiceImpl implements MsgToggleService { private final MsgToggleRepository msgToggleRepository; - private final ConcurrentHashMap cachedToggleStates; + private final PlaceholderWatcher watcher; @Inject - MsgToggleServiceImpl(MsgToggleRepository msgToggleRepository) { - this.cachedToggleStates = new ConcurrentHashMap<>(); + MsgToggleServiceImpl(MsgToggleRepository msgToggleRepository, PlaceholderRegistry registry) { this.msgToggleRepository = msgToggleRepository; - + this.watcher = registry.createWatcher(MsgPlaceholderSetup.MSG_STATE); } - @Override - public CompletableFuture getState(UUID playerUniqueId) { - if (this.cachedToggleStates.containsKey(playerUniqueId)) { - return CompletableFuture.completedFuture(this.cachedToggleStates.get(playerUniqueId)); - } - - return this.msgToggleRepository.getPrivateChatState(playerUniqueId); + public CompletableFuture getState(UUID player) { + return this.watcher.track(player, this.msgToggleRepository.getPrivateChatState(player)); } @Override - public CompletableFuture setState(UUID playerUniqueId, MsgState state) { - this.cachedToggleStates.put(playerUniqueId, state); - - return this.msgToggleRepository.setPrivateChatState(playerUniqueId, state) - .exceptionally(throwable -> { - this.cachedToggleStates.remove(playerUniqueId); - return null; - }); + public CompletableFuture setState(UUID player, MsgState state) { + return this.watcher.track(player, this.msgToggleRepository.setPrivateChatState(player, state)) + .thenApply(unused -> null); } @Override @@ -45,7 +36,8 @@ public CompletableFuture toggleState(UUID playerUniqueId) { return this.getState(playerUniqueId).thenCompose(state -> { MsgState newState = state.invert(); return this.setState(playerUniqueId, newState) - .thenApply(aVoid -> newState); + .thenApply(unused -> newState); }); } + } diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/NamedPlaceholder.java b/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/NamedPlaceholder.java new file mode 100644 index 000000000..6df52bac1 --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/NamedPlaceholder.java @@ -0,0 +1,16 @@ +package com.eternalcode.core.placeholder; + +import org.bukkit.entity.Player; + +public interface NamedPlaceholder extends Placeholder { + + @Override + default String apply(String text, Player targetPlayer) { + return text.replace("{" + this.getName() + "}", this.provideValue(targetPlayer)); + } + + String getName(); + + String provideValue(Player targetPlayer); + +} diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/Placeholder.java b/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/Placeholder.java index 84a12928d..644e5d2f3 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/Placeholder.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/Placeholder.java @@ -1,5 +1,8 @@ package com.eternalcode.core.placeholder; +import com.eternalcode.core.placeholder.watcher.PlaceholderWatcherKey; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; import org.bukkit.entity.Player; import java.util.function.Function; @@ -9,27 +12,36 @@ public interface Placeholder { String apply(String text, Player targetPlayer); static Placeholder of(String target, String replacement) { - return new PlaceholderRaw(target, player -> replacement); + return new StaticValuePlaceholder(target, player -> replacement); } static Placeholder of(String target, Function replacement) { - return new PlaceholderRaw(target, replacement); + return new StaticValuePlaceholder(target, replacement); } static Placeholder ofInt(String target, Function replacement) { - return new PlaceholderRaw(target, player -> String.valueOf(replacement.apply(player))); + return new StaticValuePlaceholder(target, player -> String.valueOf(replacement.apply(player))); } static Placeholder ofBoolean(String target, Function replacement) { - return new PlaceholderRaw(target, player -> String.valueOf(replacement.apply(player))); + return new StaticValuePlaceholder(target, player -> String.valueOf(replacement.apply(player))); } static Placeholder ofLong(String target, Function replacement) { - return new PlaceholderRaw(target, player -> String.valueOf(replacement.apply(player))); + return new StaticValuePlaceholder(target, player -> String.valueOf(replacement.apply(player))); } static Placeholder of(String target, Placeholder placeholder) { - return new PlaceholderRaw(target, player -> placeholder.apply(target, player)); + return new StaticValuePlaceholder(target, player -> placeholder.apply(target, player)); + } + + static Placeholder async( + String target, + PlaceholderWatcherKey key, + Function> loading, + Function mapper + ) { + return new PlaceholderAsync<>(target, key, loading, mapper); } } diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/PlaceholderAsync.java b/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/PlaceholderAsync.java new file mode 100644 index 000000000..14f0b7a23 --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/PlaceholderAsync.java @@ -0,0 +1,56 @@ +package com.eternalcode.core.placeholder; + +import com.eternalcode.core.placeholder.watcher.PlaceholderWatcherKey; +import com.github.benmanes.caffeine.cache.AsyncLoadingCache; +import com.github.benmanes.caffeine.cache.Caffeine; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import org.bukkit.entity.Player; + +class PlaceholderAsync implements NamedPlaceholder { + + private final String target; + private final PlaceholderWatcherKey key; + private final AsyncLoadingCache cache; + private final Function mapper; + + public PlaceholderAsync(String target, PlaceholderWatcherKey key, Function> loading, Function mapper) { + this.target = target; + this.key = key; + this.cache = Caffeine.newBuilder() + .refreshAfterWrite(1, TimeUnit.MINUTES) + .buildAsync((player, executor) -> loading.apply(player)); + this.mapper = mapper; + } + + @Override + public String getName() { + return this.target; + } + + public PlaceholderWatcherKey key() { + return key; + } + + @Override + public String apply(String text, Player targetPlayer) { + return text.replace(this.target, this.provideValue(targetPlayer)); + } + + @Override + public String provideValue(Player targetPlayer) { + CompletableFuture future = cache.get(targetPlayer.getUniqueId()); + if (future.isDone() && !future.isCompletedExceptionally()) { + return mapper.apply(future.join()); + } + + return null; + } + + public void update(UUID uuid, T value) { + cache.put(uuid, CompletableFuture.completedFuture(value)); + } + +} diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/PlaceholderBukkitRegistryImpl.java b/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/PlaceholderBukkitRegistryImpl.java index 2e376f19a..9a6193b83 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/PlaceholderBukkitRegistryImpl.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/PlaceholderBukkitRegistryImpl.java @@ -2,6 +2,8 @@ import com.eternalcode.core.injector.annotations.Inject; import com.eternalcode.core.injector.annotations.component.Service; +import com.eternalcode.core.placeholder.watcher.PlaceholderWatcher; +import com.eternalcode.core.placeholder.watcher.PlaceholderWatcherKey; import com.eternalcode.core.viewer.Viewer; import org.bukkit.Server; import org.bukkit.entity.Player; @@ -16,8 +18,9 @@ public class PlaceholderBukkitRegistryImpl implements PlaceholderRegistry { private final Server server; - private final Set replacerPlayers = new HashSet<>(); - private final Map rawPlaceholders = new HashMap<>(); + private final Set placeholders = new HashSet<>(); + private final Map namedPlaceholders = new HashMap<>(); + private final Map, Set>> asyncPlaceholders = new HashMap<>(); @Inject public PlaceholderBukkitRegistryImpl(Server server) { @@ -25,12 +28,29 @@ public PlaceholderBukkitRegistryImpl(Server server) { } @Override - public void register(Placeholder stack) { - this.replacerPlayers.add(stack); + public void register(Placeholder placeholder) { + this.placeholders.add(placeholder); - if (stack instanceof PlaceholderRaw raw) { - this.rawPlaceholders.put(raw.getRawTarget(), raw); + if (placeholder instanceof NamedPlaceholder namedPlaceholder) { + this.namedPlaceholders.put(namedPlaceholder.getName(), namedPlaceholder); } + + if (placeholder instanceof PlaceholderAsync placeholderAsync) { + PlaceholderWatcherKey key = placeholderAsync.key(); + this.asyncPlaceholders.computeIfAbsent(key, k -> new HashSet<>()).add(placeholderAsync); + } + } + + @Override + @SuppressWarnings("unchecked") + public PlaceholderWatcher createWatcher(PlaceholderWatcherKey key) { + return (player, value) -> { + PlaceholderAsync async = (PlaceholderAsync) asyncPlaceholders.get(key); + if (async != null) { + async.update(player, value); + } + return value; + }; } @Override @@ -39,7 +59,7 @@ public String format(String text, Viewer target) { Player playerTarget = this.server.getPlayer(target.getUniqueId()); if (playerTarget != null) { - for (Placeholder replacer : this.replacerPlayers) { + for (Placeholder replacer : this.placeholders) { text = replacer.apply(text, playerTarget); } } @@ -49,8 +69,8 @@ public String format(String text, Viewer target) { } @Override - public Optional getRawPlaceholder(String target) { - return Optional.ofNullable(this.rawPlaceholders.get(target)); + public Optional getNamedPlaceholder(String name) { + return Optional.ofNullable(this.namedPlaceholders.get(name)); } } diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/PlaceholderRaw.java b/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/PlaceholderRaw.java deleted file mode 100644 index 3e3bcf0ec..000000000 --- a/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/PlaceholderRaw.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.eternalcode.core.placeholder; - -import org.bukkit.entity.Player; - -import java.util.function.Function; - -public record PlaceholderRaw(String target, Function replacement) implements Placeholder { - - @Override - public String apply(String text, Player targetPlayer) { - return text.replace("{" + this.target + "}", this.replacement.apply(targetPlayer)); - } - - public String getRawTarget() { - return this.target; - } - - public String rawApply(Player targetPlayer) { - return this.replacement.apply(targetPlayer); - } - -} diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/PlaceholderRegistry.java b/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/PlaceholderRegistry.java index b7d3bcaa4..ccf88bd5a 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/PlaceholderRegistry.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/PlaceholderRegistry.java @@ -1,5 +1,7 @@ package com.eternalcode.core.placeholder; +import com.eternalcode.core.placeholder.watcher.PlaceholderWatcher; +import com.eternalcode.core.placeholder.watcher.PlaceholderWatcherKey; import com.eternalcode.core.viewer.Viewer; import java.util.Optional; @@ -8,8 +10,10 @@ public interface PlaceholderRegistry { void register(Placeholder stack); + PlaceholderWatcher createWatcher(PlaceholderWatcherKey name); + String format(String text, Viewer target); - Optional getRawPlaceholder(String target); + Optional getNamedPlaceholder(String name); } diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/StaticValuePlaceholder.java b/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/StaticValuePlaceholder.java new file mode 100644 index 000000000..114cc9d7e --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/StaticValuePlaceholder.java @@ -0,0 +1,32 @@ +package com.eternalcode.core.placeholder; + +import org.bukkit.entity.Player; + +import java.util.function.Function; + +class StaticValuePlaceholder implements NamedPlaceholder { + + private final String name; + private final Function replacement; + + StaticValuePlaceholder(String name, Function replacement) { + this.name = name; + this.replacement = replacement; + } + + @Override + public String apply(String text, Player targetPlayer) { + return text.replace("{" + this.name + "}", this.replacement.apply(targetPlayer)); + } + + @Override + public String getName() { + return this.name; + } + + @Override + public String provideValue(Player targetPlayer) { + return this.replacement.apply(targetPlayer); + } + +} diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/watcher/PlaceholderWatcher.java b/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/watcher/PlaceholderWatcher.java new file mode 100644 index 000000000..18ace9a69 --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/watcher/PlaceholderWatcher.java @@ -0,0 +1,14 @@ +package com.eternalcode.core.placeholder.watcher; + +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +public interface PlaceholderWatcher { + + T track(UUID player, T value); + + default CompletableFuture track(UUID player, CompletableFuture value) { + return value.thenApply(tracked -> this.track(player, tracked)); + } + +} diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/watcher/PlaceholderWatcherKey.java b/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/watcher/PlaceholderWatcherKey.java new file mode 100644 index 000000000..d62482035 --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/placeholder/watcher/PlaceholderWatcherKey.java @@ -0,0 +1,9 @@ +package com.eternalcode.core.placeholder.watcher; + +public record PlaceholderWatcherKey(String name, Class type) { + + public static PlaceholderWatcherKey of(String name, Class type) { + return new PlaceholderWatcherKey<>(name, type); + } + +} diff --git a/eternalcore-plugin/build.gradle.kts b/eternalcore-plugin/build.gradle.kts index eb9e70848..125cfb7ba 100644 --- a/eternalcore-plugin/build.gradle.kts +++ b/eternalcore-plugin/build.gradle.kts @@ -43,7 +43,11 @@ dependencies { tasks { runServer { minecraftVersion("1.21.11") - downloadPlugins.modrinth("luckperms", "v${Versions.LUCKPERMS}-bukkit") + + downloadPlugins { + modrinth("luckperms", "v${Versions.LUCKPERMS}-bukkit") + modrinth("placeholderapi", Versions.PLACEHOLDER_API) + } } }