mirror of
https://github.com/PlaceholderAPI/PlaceholderAPI
synced 2026-02-06 00:07:20 +01:00
Compare commits
4 Commits
master
...
feature/co
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d81cc443b | ||
|
|
2d686b679f | ||
|
|
5fbc5ee1cb | ||
|
|
4378a439fc |
@@ -28,6 +28,7 @@ dependencies {
|
||||
implementation("net.kyori:adventure-platform-bukkit:4.4.1")
|
||||
|
||||
//compileOnly("org.spigotmc:spigot-api:1.21-R0.1-SNAPSHOT")
|
||||
compileOnly("io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT")
|
||||
compileOnly("dev.folia:folia-api:1.20.1-R0.1-SNAPSHOT")
|
||||
compileOnlyApi("org.jetbrains:annotations:23.0.0")
|
||||
|
||||
@@ -92,7 +93,12 @@ tasks {
|
||||
archiveClassifier.set("")
|
||||
|
||||
relocate("org.bstats", "me.clip.placeholderapi.metrics")
|
||||
relocate("net.kyori", "me.clip.placeholderapi.libs.kyori")
|
||||
// relocate("net.kyori", "me.clip.placeholderapi.libs.kyori") {
|
||||
// exclude("me/clip/placeholderapi/PAPIComponents.java")
|
||||
// exclude("me/clip/placeholderapi/commands/TestCommand.java")
|
||||
// }
|
||||
|
||||
destinationDirectory = file("server/1.21/plugins/")
|
||||
|
||||
exclude("META-INF/versions/**")
|
||||
}
|
||||
|
||||
121
src/main/java/me/clip/placeholderapi/PAPIComponents.java
Normal file
121
src/main/java/me/clip/placeholderapi/PAPIComponents.java
Normal file
@@ -0,0 +1,121 @@
|
||||
package me.clip.placeholderapi;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import me.clip.placeholderapi.expansion.Relational;
|
||||
import me.clip.placeholderapi.replacer.ExactReplacer;
|
||||
import me.clip.placeholderapi.replacer.Replacer;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.checkerframework.checker.units.qual.N;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class PAPIComponents {
|
||||
private static final Replacer EXACT_REPLACER = new ExactReplacer();
|
||||
|
||||
@NotNull
|
||||
public static Component setPlaceholders(final OfflinePlayer player, @NotNull final Component component) {
|
||||
// TODO: explore a custom TextReplacementRenderer which doesn't use regex for performance benefits i.e. merge CharsReplacer with kyori TextReplacementRenderer
|
||||
return component.replaceText(config -> config.match(PlaceholderAPI.PLACEHOLDER_PATTERN).replacement((result, builder) ->
|
||||
builder.content(EXACT_REPLACER.apply(result.group(), player, PlaceholderAPIPlugin.getInstance().getLocalExpansionManager()::getExpansion))));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<Component> setPlaceholders(final OfflinePlayer player, @NotNull final List<Component> components) {
|
||||
return components.stream().map(component -> setPlaceholders(player, component)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Component setPlaceholders(final Player player, @NotNull final Component component) {
|
||||
return setPlaceholders((OfflinePlayer) player, component);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<Component> setPlaceholders(final Player player, @NotNull final List<Component> components) {
|
||||
return setPlaceholders((OfflinePlayer) player, components);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Component setBracketPlaceholders(final OfflinePlayer player, @NotNull final Component component) {
|
||||
return component.replaceText(config -> config.match(PlaceholderAPI.BRACKET_PLACEHOLDER_PATTERN).replacement((result, builder) ->
|
||||
builder.content(EXACT_REPLACER.apply(result.group(), player, PlaceholderAPIPlugin.getInstance().getLocalExpansionManager()::getExpansion))));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<Component> setBracketPlaceholders(final OfflinePlayer player, @NotNull final List<Component> components) {
|
||||
return components.stream().map(component -> setBracketPlaceholders(player, component)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Component setBracketPlaceholders(final Player player, @NotNull final Component component) {
|
||||
return setBracketPlaceholders((OfflinePlayer) player, component);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<Component> setBracketPlaceholders(final Player player, @NotNull final List<Component> components) {
|
||||
return setBracketPlaceholders((OfflinePlayer) player, components);
|
||||
}
|
||||
|
||||
// public static Component setRelationalPlaceholders(Player one, Player two, Component component) {
|
||||
// return component.replaceText(config -> config.match(PlaceholderAPI.RELATIONAL_PLACEHOLDER_PATTERN).replacement((result, builder) -> {
|
||||
//
|
||||
// final String format = result.group(2);
|
||||
// final int index = format.indexOf("_");
|
||||
//
|
||||
// if (index <= 0 || index >= format.length()) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// String identifier = format.substring(0, index).toLowerCase(Locale.ROOT);
|
||||
// String params = format.substring(index + 1);
|
||||
// final PlaceholderExpansion expansion = PlaceholderAPIPlugin.getInstance()
|
||||
// .getLocalExpansionManager().getExpansion(identifier);
|
||||
//
|
||||
// if (!(expansion instanceof Relational)) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// final String value = ((Relational) expansion).onPlaceholderRequest(one, two, params);
|
||||
//
|
||||
// if (value != null) {
|
||||
// text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value));
|
||||
// }
|
||||
//
|
||||
//
|
||||
// }));
|
||||
//
|
||||
// final Matcher matcher = PlaceholderAPI.RELATIONAL_PLACEHOLDER_PATTERN.matcher(text);
|
||||
//
|
||||
// while (matcher.find()) {
|
||||
// final String format = matcher.group(2);
|
||||
// final int index = format.indexOf("_");
|
||||
//
|
||||
// if (index <= 0 || index >= format.length()) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// String identifier = format.substring(0, index).toLowerCase(Locale.ROOT);
|
||||
// String params = format.substring(index + 1);
|
||||
// final PlaceholderExpansion expansion = PlaceholderAPIPlugin.getInstance()
|
||||
// .getLocalExpansionManager().getExpansion(identifier);
|
||||
//
|
||||
// if (!(expansion instanceof Relational)) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// final String value = ((Relational) expansion).onPlaceholderRequest(one, two, params);
|
||||
//
|
||||
// if (value != null) {
|
||||
// text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return text;
|
||||
// }
|
||||
}
|
||||
@@ -34,6 +34,7 @@ import me.clip.placeholderapi.expansion.manager.LocalExpansionManager;
|
||||
import me.clip.placeholderapi.replacer.CharsReplacer;
|
||||
import me.clip.placeholderapi.replacer.Replacer;
|
||||
import me.clip.placeholderapi.replacer.Replacer.Closure;
|
||||
import me.clip.placeholderapi.replacer.ExactReplacer;
|
||||
import me.clip.placeholderapi.util.Msg;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -46,11 +47,12 @@ public final class PlaceholderAPI {
|
||||
private static final Replacer REPLACER_PERCENT = new CharsReplacer(Closure.PERCENT);
|
||||
private static final Replacer REPLACER_BRACKET = new CharsReplacer(Closure.BRACKET);
|
||||
|
||||
private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("[%]([^%]+)[%]");
|
||||
private static final Pattern BRACKET_PLACEHOLDER_PATTERN = Pattern.compile("[{]([^{}]+)[}]");
|
||||
private static final Pattern RELATIONAL_PLACEHOLDER_PATTERN = Pattern
|
||||
static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("[%]([^%]+)[%]");
|
||||
static final Pattern BRACKET_PLACEHOLDER_PATTERN = Pattern.compile("[{]([^{}]+)[}]");
|
||||
static final Pattern RELATIONAL_PLACEHOLDER_PATTERN = Pattern
|
||||
.compile("[%](rel_)([^%]+)[%]");
|
||||
|
||||
private static final Replacer TEST = new ExactReplacer();
|
||||
|
||||
private PlaceholderAPI() {
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.text.SimpleDateFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommandRouter;
|
||||
import me.clip.placeholderapi.commands.TestCommand;
|
||||
import me.clip.placeholderapi.configuration.PlaceholderAPIConfig;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import me.clip.placeholderapi.expansion.Version;
|
||||
@@ -92,8 +93,9 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
private final TaskScheduler scheduler = UniversalScheduler.getScheduler(this);
|
||||
|
||||
private BukkitAudiences adventure;
|
||||
private boolean safetyCheck = false;
|
||||
|
||||
private BukkitAudiences adventure;
|
||||
private boolean safetyCheck = false;
|
||||
|
||||
/**
|
||||
* Gets the static instance of the main class for PlaceholderAPI. This class is not the actual API
|
||||
@@ -149,6 +151,10 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
instance = this;
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
saveDefaultConfig();
|
||||
@@ -172,8 +178,6 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
setupMetrics();
|
||||
setupExpansions();
|
||||
|
||||
adventure = BukkitAudiences.create(this);
|
||||
|
||||
if (config.isCloudEnabled()) {
|
||||
getCloudExpansionManager().load();
|
||||
}
|
||||
@@ -183,6 +187,11 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
getCloudExpansionManager().kill();
|
||||
getLocalExpansionManager().kill();
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
if (safetyCheck) {
|
||||
@@ -192,8 +201,6 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
getCloudExpansionManager().kill();
|
||||
getLocalExpansionManager().kill();
|
||||
|
||||
HandlerList.unregisterAll(this);
|
||||
|
||||
scheduler.cancelTasks(this);
|
||||
|
||||
adventure.close();
|
||||
|
||||
@@ -20,11 +20,14 @@
|
||||
|
||||
package me.clip.placeholderapi;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public abstract class PlaceholderHook {
|
||||
@Nullable
|
||||
public String onRequest(final OfflinePlayer player, @NotNull final String params) {
|
||||
|
||||
@@ -22,10 +22,12 @@ package me.clip.placeholderapi.commands;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -22,6 +22,7 @@ package me.clip.placeholderapi.commands;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -30,6 +31,7 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.impl.cloud.CommandECloud;
|
||||
import me.clip.placeholderapi.commands.impl.local.CommandDump;
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package me.clip.placeholderapi.commands;
|
||||
|
||||
import io.papermc.paper.command.brigadier.BasicCommand;
|
||||
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||
import me.clip.placeholderapi.PAPIComponents;
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.HoverEvent;
|
||||
import net.kyori.adventure.text.event.HoverEventSource;
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
public class TestCommand implements BasicCommand {
|
||||
private static final MiniMessage MINI = MiniMessage.miniMessage();
|
||||
|
||||
@Override
|
||||
public void execute(final CommandSourceStack commandSourceStack, final String[] strings) {
|
||||
// final Component component = Component.text("Woo! Test: %player_name%").color(TextColor.color(50, 168, 82)).hoverEvent(HoverEvent.showText(Component.text("OMG %player_gamemode%")));
|
||||
final Component component = Component.text("Woo! Test: %player_name%");
|
||||
|
||||
String ser = MINI.serialize(component);
|
||||
System.out.println(ser);
|
||||
|
||||
commandSourceStack.getSender().sendMessage(
|
||||
PAPIComponents.setPlaceholders((OfflinePlayer) commandSourceStack.getSender(), component)
|
||||
);
|
||||
|
||||
long tmp = System.currentTimeMillis();
|
||||
for (int i = 0; i < 100000; ++i) {
|
||||
PAPIComponents.setPlaceholders((OfflinePlayer) commandSourceStack.getSender(), component);
|
||||
}
|
||||
commandSourceStack.getSender().sendMessage(String.valueOf(System.currentTimeMillis() - tmp));
|
||||
|
||||
tmp = System.currentTimeMillis();
|
||||
for (int i = 0; i < 100000; ++i) {
|
||||
PlaceholderAPI.setPlaceholders((OfflinePlayer) commandSourceStack.getSender(), "Woo! Test: %player_name%");
|
||||
}
|
||||
commandSourceStack.getSender().sendMessage(String.valueOf(System.currentTimeMillis() - tmp));
|
||||
|
||||
tmp = System.currentTimeMillis();
|
||||
for (int i = 0; i < 100000; ++i) {
|
||||
final String serr = MINI.serialize(component);
|
||||
final String repl = PlaceholderAPI.setPlaceholders((OfflinePlayer) commandSourceStack.getSender(), serr);
|
||||
MINI.deserialize(repl);
|
||||
}
|
||||
commandSourceStack.getSender().sendMessage(String.valueOf(System.currentTimeMillis() - tmp));
|
||||
|
||||
|
||||
Component.text()
|
||||
.append(Component.text().content("yes ").color(TextColor.color(50,50,50)))
|
||||
.append(Component.text("%player_name%"))
|
||||
.append(Component.text(" omg").color(TextColor.color(200,200,200)));
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
package me.clip.placeholderapi.commands.impl.cloud;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.util.Msg;
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
||||
@@ -64,14 +65,6 @@ public final class CommandECloudDownload extends PlaceholderCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
final CloudExpansion expansion = plugin.getCloudExpansionManager()
|
||||
.findCloudExpansionByName(params.get(0)).orElse(null);
|
||||
if (expansion == null) {
|
||||
Msg.msg(sender,
|
||||
"&cFailed to find an expansion named: &f" + params.get(0));
|
||||
return;
|
||||
}
|
||||
|
||||
final CloudExpansion.Version version;
|
||||
if (params.size() < 2) {
|
||||
version = expansion.getVersion(expansion.getLatestVersion());
|
||||
@@ -95,6 +88,37 @@ public final class CommandECloudDownload extends PlaceholderCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.getCloudExpansionManager().downloadExpansion(expansion, version)
|
||||
.whenComplete((file, exception) -> {
|
||||
if (exception != null) {
|
||||
Msg.msg(sender,
|
||||
"&cFailed to find an expansion named: &f" + params.get(0));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!expansion.isVerified()) {
|
||||
Msg.msg(sender, "&cThe expansion '&f" + params.get(0) + "&c' is not verified and can only be downloaded manually from &fhttps://placeholderapi.com/ecloud");
|
||||
return;
|
||||
}
|
||||
|
||||
final CloudExpansion.Version version;
|
||||
if (params.size() < 2) {
|
||||
version = expansion.getVersion(expansion.getLatestVersion());
|
||||
if (version == null) {
|
||||
Msg.msg(sender,
|
||||
"&cCould not find latest version for expansion.");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
version = expansion.getVersion(params.get(1));
|
||||
if (version == null) {
|
||||
Msg.msg(sender,
|
||||
"&cCould not find specified version: &f" + params.get(1),
|
||||
"&7Available versions: &f" + expansion.getAvailableVersions());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getCloudExpansionManager().downloadExpansion(expansion, version)
|
||||
.whenComplete((file, exception) -> {
|
||||
if (exception != null) {
|
||||
|
||||
@@ -23,6 +23,7 @@ package me.clip.placeholderapi.commands.impl.cloud;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
||||
@@ -55,8 +56,6 @@ public final class CommandECloudExpansionInfo extends PlaceholderCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
|
||||
builder.append("&bExpansion: &f")
|
||||
.append(expansion.shouldUpdate() ? "&e" : "&a")
|
||||
.append(expansion.getName())
|
||||
@@ -102,6 +101,17 @@ public final class CommandECloudExpansionInfo extends PlaceholderCommand {
|
||||
.append('\n');
|
||||
}
|
||||
|
||||
builder.append("&bVersion: &f")
|
||||
.append(version.getVersion())
|
||||
.append('\n')
|
||||
.append("&bRelease Notes: &f")
|
||||
.append(version.getReleaseNotes())
|
||||
.append('\n')
|
||||
.append("&bDownload URL: &f")
|
||||
.append(version.getUrl())
|
||||
.append('\n');
|
||||
}
|
||||
|
||||
Msg.msg(sender, builder.toString());
|
||||
}
|
||||
|
||||
|
||||
@@ -25,12 +25,14 @@ import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.primitives.Ints;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.configuration.ExpansionSort;
|
||||
@@ -168,16 +170,19 @@ public final class CommandECloudExpansionList extends PlaceholderCommand {
|
||||
.append(newline()).append(newline())
|
||||
.append(text("Author: ", AQUA)).append(text(expansion.getAuthor(), WHITE))
|
||||
.append(newline())
|
||||
.append(text("Verified: ", AQUA)).append(text(expansion.getVersion().isVerified() ? "✔" : "❌", expansion.getVersion().isVerified() ? GREEN : RED, TextDecoration.BOLD))
|
||||
.append(text("Verified: ", AQUA)).append(text(expansion.isVerified() ? "✔" : "❌", expansion.isVerified() ? GREEN : RED, TextDecoration.BOLD))
|
||||
.append(newline())
|
||||
.append(text("Released: ", AQUA)).append(text(format.format(expansion.getLastUpdate()), WHITE))
|
||||
.toBuilder();
|
||||
|
||||
Optional.ofNullable(expansion.getDescription())
|
||||
.filter(description -> !description.isEmpty())
|
||||
.ifPresent(description -> hoverText.append(newline()).append(newline())
|
||||
.append(text(description.replace("\r", "").trim(), WHITE))
|
||||
);
|
||||
final TextComponent.Builder hoverText = text("Click to download this expansion!", AQUA)
|
||||
.append(newline()).append(newline())
|
||||
.append(text("Author: ", AQUA)).append(text(expansion.getAuthor(), WHITE))
|
||||
.append(newline())
|
||||
.append(text("Verified: ", AQUA)).append(text(expansion.getVersion().isVerified() ? "✔" : "❌", expansion.getVersion().isVerified() ? GREEN : RED, TextDecoration.BOLD))
|
||||
.append(newline())
|
||||
.append(text("Released: ", AQUA)).append(text(format.format(expansion.getLastUpdate()), WHITE))
|
||||
.toBuilder();
|
||||
|
||||
line.hoverEvent(HoverEvent.showText(hoverText.build()));
|
||||
|
||||
|
||||
@@ -21,9 +21,11 @@
|
||||
package me.clip.placeholderapi.commands.impl.cloud;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
package me.clip.placeholderapi.commands.impl.cloud;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.util.Msg;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
package me.clip.placeholderapi.commands.impl.cloud;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.expansion.manager.CloudExpansionManager;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
package me.clip.placeholderapi.commands.impl.cloud;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -28,6 +29,7 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
|
||||
@@ -22,6 +22,7 @@ package me.clip.placeholderapi.commands.impl.local;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
package me.clip.placeholderapi.commands.impl.local;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.util.Msg;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
package me.clip.placeholderapi.commands.impl.local;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
|
||||
@@ -21,9 +21,11 @@
|
||||
package me.clip.placeholderapi.commands.impl.local;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
package me.clip.placeholderapi.commands.impl.local;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.util.ExpansionSafetyCheck;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
package me.clip.placeholderapi.commands.impl.local;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.util.Msg;
|
||||
|
||||
@@ -23,6 +23,7 @@ package me.clip.placeholderapi.events;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
@@ -23,6 +23,7 @@ package me.clip.placeholderapi.expansion.cloud;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.clip.placeholderapi.util.TimeUtil;
|
||||
|
||||
|
||||
@@ -194,6 +195,7 @@ public class CloudExpansion {
|
||||
public void setReleaseNotes(String release_notes) {
|
||||
this.release_notes = release_notes;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isVerified() {
|
||||
return verified;
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.google.common.io.Resources;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -50,6 +51,7 @@ import java.util.function.Function;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
||||
|
||||
@@ -22,6 +22,7 @@ package me.clip.placeholderapi.expansion.manager;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
@@ -38,6 +39,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.events.ExpansionRegisterEvent;
|
||||
import me.clip.placeholderapi.events.ExpansionUnregisterEvent;
|
||||
@@ -213,6 +215,7 @@ public final class LocalExpansionManager implements Listener {
|
||||
|
||||
/**
|
||||
* Attempt to register a {@link PlaceholderExpansion}
|
||||
*
|
||||
* @param expansion the expansion to register
|
||||
* @return if the expansion was registered
|
||||
*/
|
||||
|
||||
@@ -22,6 +22,7 @@ package me.clip.placeholderapi.replacer;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.function.Function;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
@@ -43,6 +44,8 @@ public final class CharsReplacer implements Replacer {
|
||||
public String apply(@NotNull final String text, @Nullable final OfflinePlayer player,
|
||||
@NotNull final Function<String, @Nullable PlaceholderExpansion> lookup) {
|
||||
final char[] chars = text.toCharArray();
|
||||
// Woo! Hlello %player_name%
|
||||
// Woo! GHsda PiggyPiglet
|
||||
final StringBuilder builder = new StringBuilder(text.length());
|
||||
|
||||
final StringBuilder identifier = new StringBuilder();
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
package me.clip.placeholderapi.replacer;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import net.kyori.adventure.text.*;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import net.kyori.adventure.text.event.HoverEvent;
|
||||
import net.kyori.adventure.text.format.Style;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.function.Function;
|
||||
|
||||
public final class ComponentReplacer {
|
||||
public Component replace(Component component, OfflinePlayer player, Function<String, PlaceholderExpansion> function) {
|
||||
Component modified = component;
|
||||
|
||||
final List<Component> oldChildren = component.children();
|
||||
final int oldChildrenSize = oldChildren.size();
|
||||
List<Component> children = null;
|
||||
|
||||
if (component instanceof TextComponent) {
|
||||
TextComponent tc = (TextComponent) component;
|
||||
final String content = tc.content();
|
||||
|
||||
final char[] chars = content.toCharArray();
|
||||
|
||||
final StringBuilder identifier = new StringBuilder();
|
||||
final StringBuilder parameters = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
final char l = chars[i];
|
||||
|
||||
if (l != '%' || i + 1 >= chars.length) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final int start = i;
|
||||
|
||||
boolean identified = false;
|
||||
boolean invalid = true;
|
||||
|
||||
while (++i < chars.length) {
|
||||
final char p = chars[i];
|
||||
|
||||
if (p == ' ' && !identified) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (p == '%') {
|
||||
invalid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (p == '_' && !identified) {
|
||||
identified = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (identified) {
|
||||
parameters.append(p);
|
||||
} else {
|
||||
identifier.append(p);
|
||||
}
|
||||
}
|
||||
|
||||
final String identifierString = identifier.toString();
|
||||
final String lowercaseIdentifierString = identifierString.toLowerCase(Locale.ROOT);
|
||||
final String parametersString = parameters.toString();
|
||||
|
||||
identifier.setLength(0);
|
||||
parameters.setLength(0);
|
||||
|
||||
if (invalid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final PlaceholderExpansion expansion = function.apply(lowercaseIdentifierString);
|
||||
|
||||
if (expansion == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String placeholderValue = expansion.onRequest(player, parametersString);
|
||||
|
||||
if (placeholderValue == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (start == 0) {
|
||||
// if we're a full match, modify the component directly
|
||||
if (i == content.length() - 1) {
|
||||
final ComponentLike replacement = Component.text(placeholderValue).style(component.style());
|
||||
|
||||
modified = replacement.asComponent();
|
||||
Style modStyle = modified.style();
|
||||
|
||||
if (modStyle.hoverEvent() != null) {
|
||||
Object hoverValue = modStyle.hoverEvent().value();
|
||||
|
||||
if (hoverValue instanceof Component) {
|
||||
final Object replacedValue = replace((Component) hoverValue, player, function);
|
||||
|
||||
if (replacedValue != hoverValue) {
|
||||
((HoverEvent<Object>) modified.style().hoverEvent()).value(replacedValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (modStyle.clickEvent() != null) {
|
||||
final ClickEvent.Payload payload = modStyle.clickEvent().payload();
|
||||
|
||||
if (payload instanceof ClickEvent.Payload.Text) {
|
||||
final ClickEvent.Payload.Text replacedPayload = ClickEvent.Payload.string(PlaceholderAPI.setPlaceholders(player, ((ClickEvent.Payload.Text) payload).value()));
|
||||
modStyle.clickEvent(ClickEvent.clickEvent(modStyle.clickEvent().action(), replacedPayload));
|
||||
} else if (payload instanceof ClickEvent.Payload.Dialog) {
|
||||
final ClickEvent.Payload.Dialog replacedPayload;
|
||||
|
||||
// ((ClickEvent.Payload.Dialog) payload).dialog()
|
||||
// apparently adventure doesn't have dialog support yet
|
||||
}
|
||||
}
|
||||
|
||||
if (children == null) {
|
||||
children = new ArrayList<>(oldChildrenSize + modified.children().size());
|
||||
children.addAll(modified.children());
|
||||
}
|
||||
} else {
|
||||
modified = Component.text("", component.style());
|
||||
// final ComponentLike child =
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (component instanceof TranslatableComponent) {
|
||||
TranslatableComponent tc = (TranslatableComponent) component;
|
||||
final List<TranslationArgument> args = tc.arguments();
|
||||
List<TranslationArgument> newArgs = null;
|
||||
for (int i = 0, size = args.size(); i < size; i++) {
|
||||
final TranslationArgument original = args.get(i);
|
||||
TranslationArgument replacement = original instanceof Component ? TranslationArgument.component(replace((Component) original, player, function)) : original;
|
||||
|
||||
if (original != replacement) {
|
||||
if (newArgs == null) {
|
||||
newArgs = new ArrayList<>(size);
|
||||
|
||||
if (i > 0) {
|
||||
newArgs.addAll(args.subList(0, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newArgs != null) {
|
||||
newArgs.add(replacement);
|
||||
}
|
||||
}
|
||||
|
||||
if (newArgs != null) {
|
||||
modified = ((TranslatableComponent) modified).arguments(newArgs);
|
||||
}
|
||||
}
|
||||
|
||||
return modified;
|
||||
}
|
||||
|
||||
private static <V> void test(HoverEvent<V> event, V value) {
|
||||
event.value(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package me.clip.placeholderapi.replacer;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ExactReplacer implements Replacer {
|
||||
private static final Pattern DELIMITER = Pattern.compile("_");
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String apply(@NotNull String text, @Nullable final OfflinePlayer player,
|
||||
@NotNull final Function<String, @Nullable PlaceholderExpansion> lookup) {
|
||||
text = text.substring(1, text.length() - 1);
|
||||
final String[] parts = DELIMITER.split(text);
|
||||
final PlaceholderExpansion expansion;
|
||||
|
||||
if (parts.length == 0) {
|
||||
expansion = lookup.apply(text);
|
||||
} else {
|
||||
expansion = lookup.apply(parts[0]);
|
||||
}
|
||||
|
||||
if (expansion == null) {
|
||||
return text;
|
||||
}
|
||||
|
||||
final String params;
|
||||
|
||||
if (text.endsWith("_")) {
|
||||
params = "";
|
||||
} else {
|
||||
params = text.substring(text.indexOf('_') + 1);
|
||||
}
|
||||
|
||||
final String result = expansion.onRequest(player, params);
|
||||
|
||||
if (result == null) {
|
||||
return text;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
package me.clip.placeholderapi.replacer;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -29,6 +29,7 @@ import static java.util.stream.IntStream.range;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,6 +23,7 @@ package me.clip.placeholderapi.util;
|
||||
import java.util.Arrays;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
# Discord: https://helpch.at/discord
|
||||
# No placeholders are provided with this plugin by default.
|
||||
# Download placeholders: /papi ecloud
|
||||
#
|
||||
# CHANGE use_regex_component_replacer to true if you notice new minecraft text features not getting their placeholders replaced properly -- may cause performance issues
|
||||
check_updates: true
|
||||
cloud_enabled: true
|
||||
cloud_sorting: "name"
|
||||
@@ -15,5 +17,6 @@ boolean:
|
||||
'true': 'yes'
|
||||
'false': 'no'
|
||||
date_format: MM/dd/yy HH:mm:ss
|
||||
use_regex_component_replacer: false
|
||||
detect_malicious_expansions: true
|
||||
debug: false
|
||||
|
||||
@@ -12,6 +12,8 @@ commands:
|
||||
placeholderapi:
|
||||
description: "PlaceholderAPI Command"
|
||||
aliases: ["papi"]
|
||||
test:
|
||||
description: "yes"
|
||||
|
||||
permissions:
|
||||
placeholderapi.*:
|
||||
|
||||
Reference in New Issue
Block a user