mirror of
https://github.com/PlaceholderAPI/PlaceholderAPI
synced 2026-02-25 17:41:13 +01:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
94
src/jmh/java/me/clip/placeholderapi/Values.java
Normal file
94
src/jmh/java/me/clip/placeholderapi/Values.java
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
*
|
||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PlaceholderAPI is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import me.clip.placeholderapi.replacer.CharsReplacer;
|
||||
import me.clip.placeholderapi.replacer.OldCharsReplacer;
|
||||
import me.clip.placeholderapi.replacer.Replacer;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface Values {
|
||||
|
||||
String SMALL_TEXT = "My name is %player_name%";
|
||||
String LARGE_TEXT = "My name is %player_name% and my location is (%player_x%, %player_y%, %player_z%), this placeholder is invalid %server_name%";
|
||||
|
||||
ImmutableMap<String, PlaceholderExpansion> PLACEHOLDERS = ImmutableMap.<String, PlaceholderExpansion>builder()
|
||||
.put("player", new MockPlayerPlaceholderExpansion())
|
||||
.build();
|
||||
|
||||
|
||||
Replacer CHARS_REPLACER = new CharsReplacer(Replacer.Closure.PERCENT);
|
||||
Replacer OLD_CHARS_REPLACER = new OldCharsReplacer(Replacer.Closure.PERCENT);
|
||||
|
||||
final class MockPlayerPlaceholderExpansion extends PlaceholderExpansion {
|
||||
|
||||
public static final String PLAYER_X = "10";
|
||||
public static final String PLAYER_Y = "20";
|
||||
public static final String PLAYER_Z = "30";
|
||||
public static final String PLAYER_NAME = "Sxtanna";
|
||||
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "player";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getAuthor() {
|
||||
return "Sxtanna";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return "1.0";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onRequest(@Nullable final OfflinePlayer player, @NotNull final String params) {
|
||||
final String[] parts = params.split("_");
|
||||
if (parts.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (parts[0]) {
|
||||
case "name":
|
||||
return PLAYER_NAME;
|
||||
case "x":
|
||||
return PLAYER_X;
|
||||
case "y":
|
||||
return PLAYER_Y;
|
||||
case "z":
|
||||
return PLAYER_Z;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package me.clip.placeholderapi.replacer;
|
||||
|
||||
/*
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
*
|
||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PlaceholderAPI is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.function.Function;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class OldCharsReplacer implements Replacer {
|
||||
|
||||
@NotNull
|
||||
private final Closure closure;
|
||||
|
||||
public OldCharsReplacer(@NotNull final Closure closure) {
|
||||
this.closure = closure;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String apply(@NotNull final String text, @Nullable final OfflinePlayer player,
|
||||
@NotNull final Function<String, @Nullable PlaceholderExpansion> lookup) {
|
||||
final char[] chars = text.toCharArray();
|
||||
final StringBuilder builder = new StringBuilder(text.length());
|
||||
|
||||
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 != closure.head || i + 1 >= chars.length) {
|
||||
builder.append(l);
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean identified = false;
|
||||
boolean invalid = true;
|
||||
boolean hadSpace = false;
|
||||
|
||||
while (++i < chars.length) {
|
||||
final char p = chars[i];
|
||||
|
||||
if (p == ' ' && !identified) {
|
||||
hadSpace = true;
|
||||
break;
|
||||
}
|
||||
if (p == closure.tail) {
|
||||
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) {
|
||||
builder.append(closure.head).append(identifierString);
|
||||
|
||||
if (identified) {
|
||||
builder.append('_').append(parametersString);
|
||||
}
|
||||
|
||||
if (hadSpace) {
|
||||
builder.append(' ');
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
final PlaceholderExpansion placeholder = lookup.apply(lowercaseIdentifierString);
|
||||
if (placeholder == null) {
|
||||
builder.append(closure.head).append(identifierString);
|
||||
|
||||
if (identified) {
|
||||
builder.append('_');
|
||||
}
|
||||
|
||||
builder.append(parametersString).append(closure.tail);
|
||||
continue;
|
||||
}
|
||||
|
||||
final String replacement = placeholder.onRequest(player, parametersString);
|
||||
if (replacement == null) {
|
||||
builder.append(closure.head).append(identifierString);
|
||||
|
||||
if (identified) {
|
||||
builder.append('_');
|
||||
}
|
||||
|
||||
builder.append(parametersString).append(closure.tail);
|
||||
continue;
|
||||
}
|
||||
|
||||
builder.append(replacement);
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
*
|
||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PlaceholderAPI is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.replacer;
|
||||
|
||||
import me.clip.placeholderapi.Values;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.openjdk.jmh.annotations.*;
|
||||
import org.openjdk.jmh.infra.Blackhole;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
@BenchmarkMode({Mode.AverageTime, Mode.Throughput})
|
||||
@Fork(value = 3, warmups = 1)
|
||||
@Warmup(iterations = 5, time = 1)
|
||||
@Measurement(iterations = 10, time = 1)
|
||||
public class ReplacerBenchmarks {
|
||||
|
||||
private Function<String, @Nullable PlaceholderExpansion> expansionFunction;
|
||||
|
||||
@Setup
|
||||
public void setup() {
|
||||
this.expansionFunction = Values.PLACEHOLDERS::get;
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void measureCharsReplacerSmallText(final Blackhole blackhole) {
|
||||
blackhole.consume(Values.CHARS_REPLACER.apply(Values.SMALL_TEXT, null, expansionFunction));
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void measureCharsReplacerLargeText(final Blackhole blackhole) {
|
||||
blackhole.consume(Values.CHARS_REPLACER.apply(Values.LARGE_TEXT, null, expansionFunction));
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void measureCharsReplacerSmallTextOld(final Blackhole blackhole) {
|
||||
blackhole.consume(Values.OLD_CHARS_REPLACER.apply(Values.SMALL_TEXT, null, expansionFunction));
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void measureCharsReplacerLargeTextOld(final Blackhole blackhole) {
|
||||
blackhole.consume(Values.OLD_CHARS_REPLACER.apply(Values.LARGE_TEXT, null, expansionFunction));
|
||||
}
|
||||
}
|
||||
@@ -20,12 +20,7 @@
|
||||
|
||||
package me.clip.placeholderapi;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -85,7 +80,11 @@ public final class PlaceholderAPI {
|
||||
@NotNull
|
||||
public static List<String> setPlaceholders(final OfflinePlayer player,
|
||||
@NotNull final List<String> text) {
|
||||
return text.stream().map(line -> setPlaceholders(player, line)).collect(Collectors.toList());
|
||||
final List<String> result = new ArrayList<>(text.size());
|
||||
for (final String line : text) {
|
||||
result.add(setPlaceholders(player, line));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,8 +139,11 @@ public final class PlaceholderAPI {
|
||||
@NotNull
|
||||
public static List<@NotNull String> setBracketPlaceholders(final OfflinePlayer player,
|
||||
@NotNull final List<@NotNull String> text) {
|
||||
return text.stream().map(line -> setBracketPlaceholders(player, line))
|
||||
.collect(Collectors.toList());
|
||||
final List<String> result = new ArrayList<>(text.size());
|
||||
for (final String line : text) {
|
||||
result.add(setBracketPlaceholders(player, line));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -179,14 +181,14 @@ public final class PlaceholderAPI {
|
||||
* @param text Text to parse the placeholders in
|
||||
* @return The text containing the parsed relational placeholders
|
||||
*/
|
||||
public static String setRelationalPlaceholders(Player one, Player two, String text) {
|
||||
public static String setRelationalPlaceholders(final Player one, final Player two, @NotNull String text) {
|
||||
final Matcher matcher = RELATIONAL_PLACEHOLDER_PATTERN.matcher(text);
|
||||
|
||||
while (matcher.find()) {
|
||||
final String format = matcher.group(2);
|
||||
final int index = format.indexOf("_");
|
||||
final int index = format.indexOf('_');
|
||||
|
||||
if (index <= 0 || index >= format.length()) {
|
||||
if (index <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -218,9 +220,12 @@ public final class PlaceholderAPI {
|
||||
* @param text text to parse the placeholder values to
|
||||
* @return The text containing the parsed relational placeholders
|
||||
*/
|
||||
public static List<String> setRelationalPlaceholders(Player one, Player two, List<String> text) {
|
||||
return text.stream().map(line -> setRelationalPlaceholders(one, two, line))
|
||||
.collect(Collectors.toList());
|
||||
public static List<String> setRelationalPlaceholders(final Player one, final Player two, final @NotNull List<String> text) {
|
||||
final List<String> result = new ArrayList<>(text.size());
|
||||
for (final String line : text) {
|
||||
result.add(setRelationalPlaceholders(one, two, line));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -241,8 +246,7 @@ public final class PlaceholderAPI {
|
||||
*/
|
||||
@NotNull
|
||||
public static Set<String> getRegisteredIdentifiers() {
|
||||
return ImmutableSet
|
||||
.copyOf(PlaceholderAPIPlugin.getInstance().getLocalExpansionManager().getIdentifiers());
|
||||
return PlaceholderAPIPlugin.getInstance().getLocalExpansionManager().getIdentifiers();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -279,8 +283,15 @@ public final class PlaceholderAPI {
|
||||
* @param text String to check
|
||||
* @return true if String contains any matches to the normal placeholder pattern, false otherwise
|
||||
*/
|
||||
public static boolean containsPlaceholders(String text) {
|
||||
return text != null && PLACEHOLDER_PATTERN.matcher(text).find();
|
||||
public static boolean containsPlaceholders(final String text) {
|
||||
if (text == null) {
|
||||
return false;
|
||||
}
|
||||
final int firstPercent = text.indexOf('%');
|
||||
if (firstPercent == -1) {
|
||||
return false;
|
||||
}
|
||||
return text.indexOf('%', firstPercent + 1) != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -290,8 +301,15 @@ public final class PlaceholderAPI {
|
||||
* @param text String to check
|
||||
* @return true if String contains any matches to the bracket placeholder pattern, false otherwise
|
||||
*/
|
||||
public static boolean containsBracketPlaceholders(String text) {
|
||||
return text != null && BRACKET_PLACEHOLDER_PATTERN.matcher(text).find();
|
||||
public static boolean containsBracketPlaceholders(final String text) {
|
||||
if (text == null) {
|
||||
return false;
|
||||
}
|
||||
final int openBracket = text.indexOf('{');
|
||||
if (openBracket == -1) {
|
||||
return false;
|
||||
}
|
||||
return text.indexOf('}', openBracket + 1) != -1;
|
||||
}
|
||||
|
||||
// === Deprecated API ===
|
||||
|
||||
@@ -114,7 +114,7 @@ public final class LocalExpansionManager implements Listener {
|
||||
|
||||
@NotNull
|
||||
@Unmodifiable
|
||||
public Collection<String> getIdentifiers() {
|
||||
public Set<String> getIdentifiers() {
|
||||
expansionsLock.lock();
|
||||
try {
|
||||
return ImmutableSet.copyOf(expansions.keySet());
|
||||
@@ -136,12 +136,7 @@ public final class LocalExpansionManager implements Listener {
|
||||
|
||||
@Nullable
|
||||
public PlaceholderExpansion getExpansion(@NotNull final String identifier) {
|
||||
expansionsLock.lock();
|
||||
try {
|
||||
return expansions.get(identifier.toLowerCase(Locale.ROOT));
|
||||
} finally {
|
||||
expansionsLock.unlock();
|
||||
}
|
||||
return expansions.get(identifier.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -36,102 +36,113 @@ public final class CharsReplacer implements Replacer {
|
||||
this.closure = closure;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translates placeholders within the provided text using a high-performance
|
||||
* character-scanning approach.
|
||||
* * <p>The method identifies placeholders delimited by the defined {@link Closure}
|
||||
* (e.g., %identifier_params% or {identifier_params}). If a placeholder is
|
||||
* successfully identified, the provided lookup function is used to fetch the
|
||||
* corresponding {@link PlaceholderExpansion}.</p>
|
||||
*
|
||||
* @param text The raw text containing potential placeholders to be replaced.
|
||||
* @param player The {@link OfflinePlayer} to contextually parse the placeholders against.
|
||||
* May be {@code null} if no player context is available.
|
||||
* @param lookup A function that maps a lowercase identifier string to a registered
|
||||
* {@link PlaceholderExpansion}.
|
||||
* @return A string with all valid placeholders replaced by their respective values.
|
||||
* Returns the original text if no placeholders are found.
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
public String apply(@NotNull final String text, @Nullable final OfflinePlayer player,
|
||||
@NotNull final Function<String, @Nullable PlaceholderExpansion> lookup) {
|
||||
final char[] chars = text.toCharArray();
|
||||
final StringBuilder builder = new StringBuilder(text.length());
|
||||
final char head = closure.head;
|
||||
int startPlaceholder = text.indexOf(head);
|
||||
|
||||
final StringBuilder identifier = new StringBuilder();
|
||||
final StringBuilder parameters = new StringBuilder();
|
||||
if (startPlaceholder == -1) {
|
||||
return text;
|
||||
}
|
||||
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
final char l = chars[i];
|
||||
final int length = text.length();
|
||||
final StringBuilder builder = new StringBuilder(length + (length >> 3));
|
||||
int cursor = 0;
|
||||
|
||||
if (l != closure.head || i + 1 >= chars.length) {
|
||||
builder.append(l);
|
||||
final char tail = closure.tail;
|
||||
|
||||
loop: do {
|
||||
// Append plain text preceding the placeholder
|
||||
if (startPlaceholder > cursor) {
|
||||
builder.append(text, cursor, startPlaceholder);
|
||||
}
|
||||
|
||||
final int endPlaceholder = text.indexOf(tail, startPlaceholder + 1);
|
||||
|
||||
if (endPlaceholder == -1) {
|
||||
builder.append(text, startPlaceholder, length);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
int underscoreIndex = -1;
|
||||
|
||||
for (int i = startPlaceholder + 1; i < endPlaceholder; i++) {
|
||||
final char current = text.charAt(i);
|
||||
|
||||
if (current == ' ') {
|
||||
// Invalid placeholder (contains space).
|
||||
// Treat the opening symbol as literal text and search for the next one.
|
||||
builder.append(head);
|
||||
cursor = startPlaceholder + 1;
|
||||
startPlaceholder = text.indexOf(head, cursor);
|
||||
|
||||
// Safety check: If no more placeholders exist, break to finalize
|
||||
if (startPlaceholder == -1) {
|
||||
break loop;
|
||||
}
|
||||
continue loop;
|
||||
}
|
||||
|
||||
if (current == '_' && underscoreIndex == -1) {
|
||||
underscoreIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (underscoreIndex == -1) {
|
||||
builder.append(text, startPlaceholder, endPlaceholder + 1);
|
||||
cursor = endPlaceholder + 1;
|
||||
startPlaceholder = text.indexOf(head, cursor);
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean identified = false;
|
||||
boolean invalid = true;
|
||||
boolean hadSpace = false;
|
||||
String identifier = text.substring(startPlaceholder + 1, underscoreIndex);
|
||||
String parameters = "";
|
||||
|
||||
while (++i < chars.length) {
|
||||
final char p = chars[i];
|
||||
|
||||
if (p == ' ' && !identified) {
|
||||
hadSpace = true;
|
||||
break;
|
||||
}
|
||||
if (p == closure.tail && identified) {
|
||||
invalid = false;
|
||||
break;
|
||||
}
|
||||
if (p == closure.tail) {
|
||||
identifier.append(p);
|
||||
break;
|
||||
}
|
||||
|
||||
if (p == '_' && !identified) {
|
||||
identified = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (identified) {
|
||||
parameters.append(p);
|
||||
} else {
|
||||
identifier.append(p);
|
||||
}
|
||||
if (underscoreIndex + 1 < endPlaceholder) {
|
||||
parameters = text.substring(underscoreIndex + 1, endPlaceholder);
|
||||
}
|
||||
|
||||
final String identifierString = identifier.toString();
|
||||
final String lowercaseIdentifierString = identifierString.toLowerCase(Locale.ROOT);
|
||||
final String parametersString = parameters.toString();
|
||||
final PlaceholderExpansion expansion = lookup.apply(identifier.toLowerCase(Locale.ROOT));
|
||||
String replacement = null;
|
||||
|
||||
identifier.setLength(0);
|
||||
parameters.setLength(0);
|
||||
|
||||
if (invalid) {
|
||||
builder.append(closure.head).append(identifierString);
|
||||
|
||||
if (identified) {
|
||||
builder.append('_').append(parametersString);
|
||||
}
|
||||
|
||||
if (hadSpace) {
|
||||
builder.append(' ');
|
||||
}
|
||||
continue;
|
||||
if (expansion != null) {
|
||||
replacement = expansion.onRequest(player, parameters);
|
||||
}
|
||||
|
||||
final PlaceholderExpansion placeholder = lookup.apply(lowercaseIdentifierString);
|
||||
if (placeholder == null) {
|
||||
builder.append(closure.head).append(identifierString);
|
||||
|
||||
if (identified) {
|
||||
builder.append('_');
|
||||
}
|
||||
|
||||
builder.append(parametersString).append(closure.tail);
|
||||
continue;
|
||||
if (replacement != null) {
|
||||
builder.append(replacement);
|
||||
} else {
|
||||
// Fallback: Restore original placeholder format
|
||||
builder.append(head).append(identifier);
|
||||
builder.append('_').append(parameters);
|
||||
builder.append(tail);
|
||||
}
|
||||
|
||||
final String replacement = placeholder.onRequest(player, parametersString);
|
||||
if (replacement == null) {
|
||||
builder.append(closure.head).append(identifierString);
|
||||
cursor = endPlaceholder + 1;
|
||||
startPlaceholder = text.indexOf(head, cursor);
|
||||
|
||||
if (identified) {
|
||||
builder.append('_');
|
||||
}
|
||||
} while (startPlaceholder != -1);
|
||||
|
||||
builder.append(parametersString).append(closure.tail);
|
||||
continue;
|
||||
}
|
||||
|
||||
builder.append(replacement);
|
||||
if (cursor < length) {
|
||||
builder.append(text, cursor, length);
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
*
|
||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PlaceholderAPI is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.replacer;
|
||||
|
||||
import me.clip.placeholderapi.Values;
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
|
||||
public class ReplacerBenchmarks {
|
||||
|
||||
@Benchmark
|
||||
public void measureCharsReplacerSmallText() {
|
||||
Values.CHARS_REPLACER.apply(Values.SMALL_TEXT, null, Values.PLACEHOLDERS::get);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void measureCharsReplacerLargeText() {
|
||||
Values.CHARS_REPLACER.apply(Values.LARGE_TEXT, null, Values.PLACEHOLDERS::get);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user