Skip to content

Instantly share code, notes, and snippets.

@goteusz-maszyk
Last active July 15, 2023 14:15
Show Gist options
  • Save goteusz-maszyk/ca41414d8a4d323d76e6e60a9943a750 to your computer and use it in GitHub Desktop.
Save goteusz-maszyk/ca41414d8a4d323d76e6e60a9943a750 to your computer and use it in GitHub Desktop.
Placeholders API (custom)
package me.gotitim.guildscore.placeholders;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
/**
* Mini PlaceholderAPI
*/
public class Placeholders {
private static final HashMap<String, PlaceholderPlugin> plugins = new HashMap<>();
private final Map<String, String> customPlaceholders = new HashMap<>(); // additional part for session-dedicated placeholders
private Player player;
public static void clearPlugins() {
plugins.clear();
}
public void setPlayer(Player player) {
this.player = player;
}
public static void registerPlugin(PlaceholderPlugin plugin) {
plugins.put(plugin.getId().toLowerCase(Locale.ROOT), plugin);
}
private void set(String key, Object val) { // additional part for session-dedicated placeholders
customPlaceholders.put("%" + key + "%", val.toString());
}
public String apply(String text) {
for (Map.Entry<String, String> entry : customPlaceholders.entrySet()) { // additional part for session-dedicated placeholders
text = text.replace(entry.getKey(), entry.getValue());
}
// We convert our text to an iterable char array & initialise string builders
final char[] chars = text.toCharArray();
final StringBuilder builder = new StringBuilder(text.length());
// The ID/param system; placeholders are in following format: %id_param% - example: %player_display_name%
final StringBuilder identifier = new StringBuilder();
final StringBuilder parameters = new StringBuilder(); // may contain "_"
for (int i = 0; i < chars.length; i++) {
final char l = chars[i];
if (l != '%' || i + 1 >= chars.length) { // stop processing current char if it isn't a placeholder or if it's the end
builder.append(l);
continue;
}
boolean identified = false; // indicates that it's a placeholder with a valid ID
boolean invalid = true; // indicates that it's not closed
boolean hadSpace = false; // used for unidentified placeholders with a space
while (++i < chars.length) { // iterate through the placeholder
final char p = chars[i];
if (p == ' ' && !identified) { // break if the placeholder has space in the ID
hadSpace = true;
break;
}
if (p == '%') { // break if it's the end
invalid = false;
break;
}
if (p == '_' && !identified) { // mark as identified if we reach a '_'
identified = true;
continue;
}
if (identified) parameters.append(p);
else identifier.append(p);
}
// convert to strings
final String identifierString = identifier.toString();
final String parametersString = parameters.toString();
// reset builders
identifier.setLength(0);
parameters.setLength(0);
if (invalid) { // write raw placeholder if it's invalid
builder.append('%').append(identifierString);
if (identified) builder.append('_').append(parametersString);
if (hadSpace) builder.append(' ');
continue;
}
// Find a plugin & write raw placeholder if plugin not found; You can add some logging so you can fix the bug easier
final Plugin plugin = plugins.get(identifierString.toLowerCase(Locale.ROOT));
final String replacement = plugin == null ? null : plugin.apply(player, parametersString).toString();
if (replacement == null) {
builder.append('%').append(identifierString);
if (identified) builder.append('_');
builder.append(parametersString).append('%');
continue;
}
builder.append(replacement);
}
return builder.toString();
}
public static abstract class Plugin {
public abstract @NotNull String getId();
/**
* @param player The target of placeholder
* @param parametersString The placeholder to process
* @return Output of processing parametersString
*/
public abstract Object apply(Player player, String parametersString);
public final void register() {
registerPlugin(this);
}
}
}
package me.gotitim.guildscore.placeholders;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class PlayerPlaceholders extends Placeholders.Plugin {
@Override
public @NotNull String getId() {
return "player";
}
@Override
public Object apply(Player player, String parametersString) {
return switch (parametersString) {
case "name" ->
player.getName();
case "uuid" ->
player.getUniqueId();
case "x" ->
player.getLocation().getX();
case "y" ->
player.getLocation().getY();
case "z" ->
player.getLocation().getZ();
case "ping" ->
player.getPing();
default -> parametersString; // you can return null if you want to keep the whole placeholder
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment