Skip to content

Commit

Permalink
Add placeholders api
Browse files Browse the repository at this point in the history
  • Loading branch information
fullwall committed Feb 26, 2023
1 parent 5b5d6bd commit c7af9f8
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/main/java/net/citizensnpcs/api/npc/NPC.java
Expand Up @@ -470,11 +470,11 @@ public enum Metadata {
* The Minecart item data. Byte.
*/
MINECART_ITEM_DATA("minecart-item-data"),

/**
* The Minecart item offset as defined by Minecraft. {@link Minecart#setDisplayBlockOffset(int)}
*/
MINECART_OFFSET("minecart-item-offset"),

/**
* Whether the NPC's nameplate should be visible. Boolean.
*/
Expand Down
42 changes: 41 additions & 1 deletion src/main/java/net/citizensnpcs/api/util/Placeholders.java
Expand Up @@ -12,21 +12,50 @@
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

import me.clip.placeholderapi.PlaceholderAPI;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.event.CitizensDisableEvent;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.trait.trait.Owner;

public class Placeholders {
public class Placeholders implements Listener {
public static interface PlaceholderFunction {
public String apply(NPC npc, CommandSender sender, String input);
}

private static class PlaceholderProvider {
PlaceholderFunction func;
Pattern regex;

PlaceholderProvider(Pattern regex, PlaceholderFunction func) {
this.regex = regex;
this.func = func;
}
}

private static OfflinePlayer getPlayer(BlockCommandSender sender) {
return CitizensAPI.getNMSHelper().getPlayer(sender);
}

@EventHandler
private static void onCitizensDisable(CitizensDisableEvent event) {
PLACEHOLDERS.clear();
}

public static void registerNPCPlaceholder(Pattern regex, PlaceholderFunction func) {
if (regex.pattern().charAt(0) != '<') {
regex = Pattern.compile('<' + regex.pattern() + '>', regex.flags());
}
PLACEHOLDERS.add(new PlaceholderProvider(regex, func));
}

public static String replace(String text, CommandSender sender, NPC npc) {
text = replace(text, sender instanceof OfflinePlayer ? (OfflinePlayer) sender
: sender instanceof BlockCommandSender ? getPlayer((BlockCommandSender) sender) : null);
Expand All @@ -49,6 +78,16 @@ public static String replace(String text, CommandSender sender, NPC npc) {
out.append(replacement);
}
matcher.appendTail(out);
for (PlaceholderProvider entry : PLACEHOLDERS) {
matcher = entry.regex.matcher(out.toString());
out = new StringBuffer();
while (matcher.find()) {
String group = matcher.group().substring(1, matcher.group().length() - 1);
matcher.appendReplacement(out, "");
out.append(entry.func.apply(npc, sender, group));
}
matcher.appendTail(out);
}
return out.toString();
}

Expand Down Expand Up @@ -130,6 +169,7 @@ private static String setPlaceholderAPIPlaceholders(String text, OfflinePlayer p

private static final Pattern PLACEHOLDER_MATCHER = Pattern.compile("<(id|npc|owner)>");
private static boolean PLACEHOLDERAPI_ENABLED = true;
private static final List<PlaceholderProvider> PLACEHOLDERS = Lists.newArrayList();
private static final Pattern PLAYER_PLACEHOLDER_MATCHER = Pattern.compile(
"(<player>|<p>|@p|%player%|<random_player>|<random_npc>|<random_npc_id>|<nearest_player>|<world>)");
private static final String[] PLAYER_PLACEHOLDERS = { "<player>", "<p>", "@p", "%player%" };
Expand Down

0 comments on commit c7af9f8

Please sign in to comment.