mirror of
https://github.com/PlaceholderAPI/PlaceholderAPI
synced 2026-02-08 00:42:47 +01:00
Compare commits
4 Commits
master
...
feature/co
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d81cc443b | ||
|
|
2d686b679f | ||
|
|
5fbc5ee1cb | ||
|
|
4378a439fc |
6
.github/workflows/pr_build_jars.yml
vendored
6
.github/workflows/pr_build_jars.yml
vendored
@@ -5,10 +5,8 @@ on:
|
||||
branches:
|
||||
- development
|
||||
paths:
|
||||
- "../../spigot/**"
|
||||
- "../../paper/**"
|
||||
- "build.gradle.kts"
|
||||
- "settings.gradle.kts"
|
||||
- "src/**"
|
||||
- "build.gradle"
|
||||
|
||||
jobs:
|
||||
testBuilds:
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
Support for specific plugins are provided either by the plugin itself or through expansions. The expansions may be downloaded in-game through the PAPI Expansion Cloud. There are currently over 240+ expansions that support a wide variety of plugins, such as Essentials, Factions, LuckPerms, and Vault.
|
||||
|
||||
PlaceholderAPI has been downloaded over 2,000,000 times on Spigot and has been used concurrently on over 50,000 servers, which makes it a must-have for a server of any type or scale.
|
||||
PlaceholderAPI has been downloaded over 1,700,000 times on Spigot and has been used concurrently on over 45,000 servers, which makes it a must-have for a server of any type or scale.
|
||||
|
||||
## Contribute
|
||||
If you would like to contribute towards PlaceholderAPI should you take a look at our [Contributing file][contributing] for the ins and outs on how you can do that and what you need to keep in mind.
|
||||
|
||||
110
build.gradle.kts
110
build.gradle.kts
@@ -3,23 +3,15 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
plugins {
|
||||
`java-library`
|
||||
`maven-publish`
|
||||
// id("com.github.hierynomus.license") version "0.16.1"
|
||||
id("com.github.hierynomus.license") version "0.16.1"
|
||||
id("io.github.goooler.shadow") version "8.1.7"
|
||||
}
|
||||
|
||||
group = "me.clip"
|
||||
version = "2.12.2-DEV-${System.getProperty("BUILD_NUMBER")}"
|
||||
version = "2.11.8-DEV-${System.getProperty("BUILD_NUMBER")}"
|
||||
|
||||
description = "An awesome placeholder provider!"
|
||||
|
||||
val paper by sourceSets.creating {
|
||||
java.srcDir("src/paper/java")
|
||||
|
||||
// paper can see main code
|
||||
compileClasspath += sourceSets.main.get().output
|
||||
runtimeClasspath += output + compileClasspath
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven("https://oss.sonatype.org/content/repositories/snapshots/")
|
||||
|
||||
@@ -32,17 +24,17 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("org.bstats:bstats-bukkit:3.1.0")
|
||||
implementation("org.bstats:bstats-bukkit:3.0.1")
|
||||
implementation("net.kyori:adventure-platform-bukkit:4.4.1")
|
||||
|
||||
add(paper.compileOnlyConfigurationName, "net.kyori:adventure-platform-bukkit:4.4.1")
|
||||
add(paper.compileOnlyConfigurationName, "dev.folia:folia-api:1.21.11-R0.1-SNAPSHOT")
|
||||
|
||||
compileOnly("dev.folia:folia-api:1.21.11-R0.1-SNAPSHOT")
|
||||
//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")
|
||||
|
||||
testImplementation("org.openjdk.jmh:jmh-core:1.32")
|
||||
testImplementation("org.openjdk.jmh:jmh-generator-annprocess:1.32")
|
||||
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.8.2")
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1")
|
||||
}
|
||||
@@ -58,6 +50,19 @@ java {
|
||||
disableAutoTargetJvm()
|
||||
}
|
||||
|
||||
license {
|
||||
header = rootProject.file("config/headers/main.txt")
|
||||
|
||||
include("**/*.java")
|
||||
mapping("java", "JAVADOC_STYLE")
|
||||
|
||||
encoding = "UTF-8"
|
||||
|
||||
ext {
|
||||
set("year", 2024)
|
||||
}
|
||||
}
|
||||
|
||||
val javaComponent: SoftwareComponent = components["java"]
|
||||
|
||||
tasks {
|
||||
@@ -69,36 +74,14 @@ tasks {
|
||||
dependsOn(named("shadowJar"))
|
||||
}
|
||||
|
||||
register<JavaCompile>("compilePaper") {
|
||||
source = paper.java
|
||||
classpath = paper.compileClasspath
|
||||
destinationDirectory.set(layout.buildDirectory.dir("classes/java/paper"))
|
||||
withType<JavaCompile> {
|
||||
options.encoding = "UTF-8"
|
||||
options.release = 8
|
||||
}
|
||||
|
||||
val plainJar by registering(Jar::class) {
|
||||
dependsOn("compilePaper")
|
||||
|
||||
archiveClassifier.set("plain")
|
||||
from(sourceSets.main.get().output)
|
||||
from(paper.output)
|
||||
}
|
||||
|
||||
val combinedSourcesJar by registering(Jar::class) {
|
||||
archiveClassifier.set("sources")
|
||||
from(sourceSets.main.get().allSource)
|
||||
from(paper.allSource)
|
||||
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
}
|
||||
|
||||
val combinedJavadoc by registering(Javadoc::class) {
|
||||
withType<Javadoc> {
|
||||
isFailOnError = false
|
||||
|
||||
source = sourceSets.main.get().allJava + paper.allJava
|
||||
classpath = sourceSets.main.get().compileClasspath + paper.compileClasspath
|
||||
|
||||
with(options as StandardJavadocDocletOptions) {
|
||||
addStringOption("Xdoclint:none", "-quiet")
|
||||
addStringOption("encoding", "UTF-8")
|
||||
@@ -106,41 +89,18 @@ tasks {
|
||||
}
|
||||
}
|
||||
|
||||
val combinedJavadocJar by registering(Jar::class) {
|
||||
archiveClassifier.set("javadoc")
|
||||
dependsOn(combinedJavadoc)
|
||||
from(combinedJavadoc.get().destinationDir)
|
||||
}
|
||||
|
||||
withType<JavaCompile> {
|
||||
options.encoding = "UTF-8"
|
||||
options.release = 8
|
||||
}
|
||||
|
||||
withType<ShadowJar> {
|
||||
configurations = listOf(project.configurations.runtimeClasspath.get())
|
||||
|
||||
from(sourceSets.main.get().output)
|
||||
|
||||
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/**")
|
||||
|
||||
dependsOn("compilePaper")
|
||||
|
||||
doLast {
|
||||
val paperDir = layout.buildDirectory.dir("classes/java/paper").get().asFile
|
||||
val jarFile = archiveFile.get().asFile
|
||||
|
||||
ant.invokeMethod("zip", mapOf(
|
||||
"destfile" to jarFile,
|
||||
"update" to "true",
|
||||
"basedir" to paperDir
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
test {
|
||||
@@ -151,19 +111,7 @@ tasks {
|
||||
publications {
|
||||
create<MavenPublication>("maven") {
|
||||
artifactId = "placeholderapi"
|
||||
|
||||
artifact(plainJar) {
|
||||
builtBy(plainJar)
|
||||
classifier = ""
|
||||
}
|
||||
|
||||
artifact(combinedSourcesJar) {
|
||||
builtBy(combinedSourcesJar)
|
||||
}
|
||||
|
||||
artifact(combinedJavadocJar) {
|
||||
builtBy(combinedJavadocJar)
|
||||
}
|
||||
from(javaComponent)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2018-2026 Peter Blood
|
||||
Copyright (c) 2018-2024 Peter Blood
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
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;
|
||||
// }
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
@@ -21,7 +21,6 @@
|
||||
package me.clip.placeholderapi;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -29,13 +28,13 @@ import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import me.clip.placeholderapi.expansion.Relational;
|
||||
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;
|
||||
@@ -53,6 +52,7 @@ public final class PlaceholderAPI {
|
||||
static final Pattern RELATIONAL_PLACEHOLDER_PATTERN = Pattern
|
||||
.compile("[%](rel_)([^%]+)[%]");
|
||||
|
||||
private static final Replacer TEST = new ExactReplacer();
|
||||
|
||||
private PlaceholderAPI() {
|
||||
}
|
||||
@@ -298,21 +298,24 @@ public final class PlaceholderAPI {
|
||||
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
public static boolean registerExpansion(PlaceholderExpansion expansion) {
|
||||
public static boolean registerExpansion(PlaceholderExpansion expansion)
|
||||
{
|
||||
return expansion.register();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
public static boolean unregisterExpansion(PlaceholderExpansion expansion) {
|
||||
public static boolean unregisterExpansion(PlaceholderExpansion expansion)
|
||||
{
|
||||
return expansion.unregister();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get map of registered placeholders
|
||||
*
|
||||
* @return Map of registered placeholders
|
||||
* @deprecated Use {@link LocalExpansionManager#getExpansions()} instead.
|
||||
*
|
||||
* @return Map of registered placeholders
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -323,11 +326,12 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Please use {@link PlaceholderExpansion} to
|
||||
* register placeholders instead
|
||||
*
|
||||
* @param plugin The Plugin to register with this {@link PlaceholderHook}
|
||||
* @param placeholderHook The {@link PlaceholderHook} to register
|
||||
* @return always false
|
||||
* @deprecated Please use {@link PlaceholderExpansion} to
|
||||
* register placeholders instead
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -339,11 +343,12 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Please use {@link PlaceholderExpansion} to
|
||||
* register placeholders instead
|
||||
*
|
||||
* @param identifier The identifier to use for the {@link PlaceholderHook}
|
||||
* @param placeholderHook The {@link PlaceholderHook} to register
|
||||
* @return always false
|
||||
* @deprecated Please use {@link PlaceholderExpansion} to
|
||||
* register placeholders instead
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -355,10 +360,11 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param plugin The plugin to unregister
|
||||
* @return always false
|
||||
* @deprecated Please use {@link PlaceholderExpansion} to
|
||||
* unregister placeholders instead
|
||||
*
|
||||
* @param plugin The plugin to unregister
|
||||
* @return always false
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -370,10 +376,11 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param identifier The identifier to unregister
|
||||
* @return always false
|
||||
* @deprecated Please use {@link PlaceholderExpansion} to
|
||||
* unregister placeholders instead
|
||||
*
|
||||
* @param identifier The identifier to unregister
|
||||
* @return always false
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -385,8 +392,9 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Set of registered identifiers
|
||||
* @deprecated Will be removed in a future release.
|
||||
*
|
||||
* @return Set of registered identifiers
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -395,8 +403,9 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return always null
|
||||
* @deprecated Will be removed in a future release.
|
||||
*
|
||||
* @return always null
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -405,12 +414,13 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Please use {@link #setPlaceholders(OfflinePlayer, String)} instead
|
||||
*
|
||||
* @param player The offline player to parse the placeholders against
|
||||
* @param text The text to parse
|
||||
* @param pattern The Pattern to use
|
||||
* @param colorize If PlaceholderAPI should also parse color codes
|
||||
* @return String with the parsed placeholders
|
||||
* @deprecated Please use {@link #setPlaceholders(OfflinePlayer, String)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -420,12 +430,13 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Please use {@link #setPlaceholders(OfflinePlayer, List)} instead
|
||||
*
|
||||
* @param player The offline player to parse the placeholders against
|
||||
* @param text The List of text to parse
|
||||
* @param pattern The Pattern to use
|
||||
* @param colorize If PlaceholderAPI should also parse color codes
|
||||
* @return String with the parsed placeholders
|
||||
* @deprecated Please use {@link #setPlaceholders(OfflinePlayer, List)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -435,11 +446,12 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, List)} instead.
|
||||
*
|
||||
* @param player The offline player to parse the placeholders against
|
||||
* @param text The List of text to parse
|
||||
* @param colorize If PlaceholderAPI should also parse color codes
|
||||
* @return String with the parsed placeholders
|
||||
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, List)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -449,11 +461,12 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, List)} instead.
|
||||
*
|
||||
* @param player The offline player to parse the placeholders against
|
||||
* @param text The List of text to parse
|
||||
* @param pattern The Pattern to use
|
||||
* @return String with the parsed placeholders
|
||||
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, List)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -461,13 +474,13 @@ public final class PlaceholderAPI {
|
||||
Pattern pattern) {
|
||||
return setPlaceholders(player, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Will be removed in a future release.
|
||||
*
|
||||
* @param player The offline player to parse the placeholders against
|
||||
* @param text The text to parse
|
||||
* @param colorize If PlaceholderAPI should also parse color codes
|
||||
* @return String with the parsed placeholders
|
||||
* @deprecated Will be removed in a future release.
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -476,11 +489,12 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Will be removed in a future release.
|
||||
*
|
||||
* @param player The offline player to parse the placeholders against
|
||||
* @param text The List of text to parse
|
||||
* @param colorize If PlaceholderAPI should also parse color codes
|
||||
* @return String with the parsed placeholders
|
||||
* @deprecated Will be removed in a future release.
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -489,11 +503,12 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, String)} instead.
|
||||
*
|
||||
* @param player The offline player to parse the placeholders against
|
||||
* @param text The text to parse
|
||||
* @param colorize If PlaceholderAPI should also parse color codes
|
||||
* @return String with the parsed placeholders
|
||||
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, String)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -502,11 +517,12 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, String)} instead.
|
||||
*
|
||||
* @param player The offline player to parse the placeholders against
|
||||
* @param text The text to parse
|
||||
* @param pattern The Pattern to use
|
||||
* @return String with the parsed placeholders
|
||||
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, String)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -515,11 +531,12 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, List)} instead.
|
||||
*
|
||||
* @param player The offline player to parse the placeholders against
|
||||
* @param text The List of text to parse
|
||||
* @param colorize If PlaceholderAPI should also parse color codes
|
||||
* @return String with the parsed placeholders
|
||||
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, List)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -529,11 +546,12 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, String)} instead.
|
||||
*
|
||||
* @param player The offline player to parse the placeholders against
|
||||
* @param text The text to parse
|
||||
* @param colorize If PlaceholderAPI should also parse color codes
|
||||
* @return String with the parsed placeholders
|
||||
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, String)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -542,11 +560,12 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Will be removed in a future release.
|
||||
*
|
||||
* @param player The offline player to parse the placeholders against
|
||||
* @param text The text to parse
|
||||
* @param colorize If PlaceholderAPI should also parse color codes
|
||||
* @return String with the parsed placeholders
|
||||
* @deprecated Will be removed in a future release.
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -555,11 +574,12 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Will be removed in a future release.
|
||||
*
|
||||
* @param player The offline player to parse the placeholders against
|
||||
* @param text The List of text to parse
|
||||
* @param colorize If PlaceholderAPI should also parse color codes
|
||||
* @return String with the parsed placeholders
|
||||
* @deprecated Will be removed in a future release.
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
@@ -23,8 +23,8 @@ package me.clip.placeholderapi;
|
||||
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;
|
||||
@@ -44,7 +44,6 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -94,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
|
||||
@@ -151,6 +151,10 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
instance = this;
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
saveDefaultConfig();
|
||||
@@ -174,8 +178,6 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
setupMetrics();
|
||||
setupExpansions();
|
||||
|
||||
adventure = BukkitAudiences.create(this);
|
||||
|
||||
if (config.isCloudEnabled()) {
|
||||
getCloudExpansionManager().load();
|
||||
}
|
||||
@@ -185,6 +187,11 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
getCloudExpansionManager().kill();
|
||||
getLocalExpansionManager().kill();
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
if (safetyCheck) {
|
||||
@@ -194,8 +201,6 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
getCloudExpansionManager().kill();
|
||||
getLocalExpansionManager().kill();
|
||||
|
||||
HandlerList.unregisterAll(this);
|
||||
|
||||
scheduler.cancelTasks(this);
|
||||
|
||||
adventure.close();
|
||||
@@ -230,7 +235,7 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
|
||||
@NotNull
|
||||
public BukkitAudiences getAdventure() {
|
||||
if (adventure == null) {
|
||||
if(adventure == null) {
|
||||
throw new IllegalStateException("Tried to access Adventure when the plugin was disabled!");
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
@@ -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) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
@@ -32,7 +32,6 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.impl.cloud.CommandECloud;
|
||||
import me.clip.placeholderapi.commands.impl.local.CommandDump;
|
||||
@@ -120,18 +119,14 @@ public final class PlaceholderCommandRouter implements CommandExecutor, TabCompl
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull final CommandSender sender, @NotNull final Command command,
|
||||
@NotNull final String alias, @NotNull final String[] args) {
|
||||
public List<String> onTabComplete(@NotNull final CommandSender sender,
|
||||
@NotNull final Command command, @NotNull final String alias, @NotNull final String[] args) {
|
||||
final List<String> suggestions = new ArrayList<>();
|
||||
|
||||
if (args.length > 1) {
|
||||
final PlaceholderCommand target = this.commands.get(args[0].toLowerCase(Locale.ROOT));
|
||||
|
||||
if (target != null) {
|
||||
if (target.getPermission() != null && !target.getPermission().isEmpty() && !sender.hasPermission(target.getPermission())) {
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
target.complete(plugin, sender, args[0].toLowerCase(Locale.ROOT),
|
||||
Arrays.asList(Arrays.copyOfRange(args, 1, args.length)), suggestions);
|
||||
}
|
||||
|
||||
@@ -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)));
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
@@ -118,11 +118,6 @@ public final class CommandECloud extends PlaceholderCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!target.getLabel().equalsIgnoreCase("refresh") && plugin.getCloudExpansionManager().isEmpty()) {
|
||||
Msg.msg(sender, "&cThere is no available data from the eCloud. Please try running &f/papi ecloud refresh&c. If this does not resolve the issue, the eCloud may be blocked by your firewall, server host, or service provider.\n&r\n&cMore information: &fhttps://placeholderapi.com/ecloud-blocked");
|
||||
return;
|
||||
}
|
||||
|
||||
target.evaluate(plugin, sender, search, params.subList(1, params.size()));
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
@@ -65,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());
|
||||
@@ -96,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) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
@@ -56,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())
|
||||
@@ -103,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());
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
@@ -170,19 +170,20 @@ public final class CommandECloudExpansionList extends PlaceholderCommand {
|
||||
.append(newline()).append(newline())
|
||||
.append(text("Author: ", AQUA)).append(text(expansion.getAuthor(), WHITE))
|
||||
.append(newline())
|
||||
.append(text("Version: ", AQUA)).append(text(expansion.getVersion().getVersion(), WHITE))
|
||||
.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();
|
||||
|
||||
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();
|
||||
|
||||
Optional.ofNullable(expansion.getDescription())
|
||||
.filter(description -> !description.isEmpty())
|
||||
.ifPresent(description -> hoverText.append(newline()).append(newline())
|
||||
.append(text(description.replace("\r", "").trim(), WHITE))
|
||||
);
|
||||
|
||||
line.hoverEvent(HoverEvent.showText(hoverText.build()));
|
||||
|
||||
if (index != expansions.size() - 1) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
@@ -21,7 +21,6 @@
|
||||
package me.clip.placeholderapi.configuration;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
@@ -21,7 +21,6 @@
|
||||
package me.clip.placeholderapi.configuration;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -54,10 +53,6 @@ public final class PlaceholderAPIConfig {
|
||||
return plugin.getConfig().getBoolean("debug", false);
|
||||
}
|
||||
|
||||
public boolean useAdventureReplacer() {
|
||||
return plugin.getConfig().getBoolean("use_adventure_provided_replacer", false);
|
||||
}
|
||||
|
||||
|
||||
public Optional<ExpansionSort> getExpansionSort() {
|
||||
final String option = plugin.getConfig()
|
||||
@@ -91,11 +86,8 @@ public final class PlaceholderAPIConfig {
|
||||
return plugin.getConfig().getString("boolean.false", "false");
|
||||
}
|
||||
|
||||
public boolean useAdventureProvidedReplacer() {
|
||||
return plugin.getConfig().getBoolean("use_adventure_provided_replacer", false);
|
||||
}
|
||||
|
||||
public boolean detectMaliciousExpansions() {
|
||||
return plugin.getConfig().getBoolean("detect_malicious_expansions", true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
@@ -23,7 +23,6 @@ package me.clip.placeholderapi.expansion;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.PlaceholderHook;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -44,7 +43,6 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
|
||||
/**
|
||||
* The type is {@link Type#INTERNAL} by default.
|
||||
* For external expansions, the type is updated on {@link me.clip.placeholderapi.expansion.manager.LocalExpansionManager#register(Class) register}.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@@ -182,7 +180,6 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
|
||||
|
||||
/**
|
||||
* Set the type of the expansion
|
||||
*
|
||||
* @param expansionType the new type
|
||||
* @since 2.11.4
|
||||
*/
|
||||
@@ -433,8 +430,9 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
|
||||
// === Deprecated API ===
|
||||
|
||||
/**
|
||||
* @return The plugin name.
|
||||
* @deprecated As of versions greater than 2.8.7, use {@link #getRequiredPlugin()}
|
||||
*
|
||||
* @return The plugin name.
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -443,8 +441,9 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The description of the expansion.
|
||||
* @deprecated As of versions greater than 2.8.7, use the expansion cloud to show a description
|
||||
*
|
||||
* @return The description of the expansion.
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -453,8 +452,9 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The link for the expansion.
|
||||
* @deprecated As of versions greater than 2.8.7, use the expansion cloud to display a link
|
||||
*
|
||||
* @return The link for the expansion.
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
@@ -27,6 +27,7 @@ package me.clip.placeholderapi.expansion;
|
||||
* with that version.
|
||||
*
|
||||
* @author Ryan McCarthy
|
||||
*
|
||||
* @deprecated Will be removed in a future release.
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -37,6 +38,7 @@ public interface VersionSpecific {
|
||||
* will be passed to this method so you know what version the server is currently running.
|
||||
*
|
||||
* @param v The {@link Version} to check against
|
||||
*
|
||||
* @return true if your expansion is compatible with the version the server is running.
|
||||
*/
|
||||
boolean isCompatibleWith(Version v);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
@@ -195,6 +195,7 @@ public class CloudExpansion {
|
||||
public void setReleaseNotes(String release_notes) {
|
||||
this.release_notes = release_notes;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isVerified() {
|
||||
return verified;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
@@ -31,7 +31,6 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@@ -63,7 +62,7 @@ import org.jetbrains.annotations.Unmodifiable;
|
||||
public final class CloudExpansionManager {
|
||||
|
||||
@NotNull
|
||||
private static final String API_URL = "https://ecloud.placeholderapi.com/api/v3/?platform=bukkit";
|
||||
private static final String API_URL = "https://ecloud.placeholderapi.com/api/v3/";
|
||||
|
||||
@NotNull
|
||||
private static final Gson GSON = new Gson();
|
||||
@@ -116,10 +115,6 @@ public final class CloudExpansionManager {
|
||||
return ImmutableMap.copyOf(cache);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return cache.isEmpty();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Unmodifiable
|
||||
public Map<String, CloudExpansion> getCloudExpansionsInstalled() {
|
||||
@@ -202,8 +197,6 @@ public final class CloudExpansionManager {
|
||||
for (String name : toRemove) {
|
||||
values.remove(name);
|
||||
}
|
||||
} catch (UnknownHostException e) {
|
||||
plugin.getLogger().log(Level.WARNING, "There is no data available from the eCloud. Please try running /papi refresh. If this does not resolve the issue, the eCloud may be blocked by your firewall, server host, or service provider.\n\nMore information: https://placeholderapi.com/ecloud-blocked", e);
|
||||
} catch (Throwable e) {
|
||||
// ugly swallowing of every throwable, but we have to be defensive
|
||||
plugin.getLogger().log(Level.WARNING, "Failed to download expansion information", e);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
@@ -44,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);
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,3 @@
|
||||
/*
|
||||
* 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.expansion.PlaceholderExpansion;
|
||||
@@ -28,17 +8,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public final class ExactReplacer implements Replacer {
|
||||
public class ExactReplacer implements Replacer {
|
||||
private static final Pattern DELIMITER = Pattern.compile("_");
|
||||
|
||||
private final char start;
|
||||
private final char end;
|
||||
|
||||
public ExactReplacer(final char start, final char end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String apply(@NotNull String text, @Nullable final OfflinePlayer player,
|
||||
@@ -54,7 +26,7 @@ public final class ExactReplacer implements Replacer {
|
||||
}
|
||||
|
||||
if (expansion == null) {
|
||||
return start + text + end;
|
||||
return text;
|
||||
}
|
||||
|
||||
final String params;
|
||||
@@ -68,7 +40,7 @@ public final class ExactReplacer implements Replacer {
|
||||
final String result = expansion.onRequest(player, params);
|
||||
|
||||
if (result == null) {
|
||||
return start + text + end;
|
||||
return text;
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -27,9 +27,7 @@ import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||
import me.clip.placeholderapi.scheduler.scheduling.tasks.MyScheduledTask;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Just modified BukkitRunnable
|
||||
*/
|
||||
/** Just modified BukkitRunnable */
|
||||
public abstract class UniversalRunnable implements Runnable {
|
||||
MyScheduledTask task;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
@@ -25,9 +25,6 @@ import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||
import me.clip.placeholderapi.util.Msg;
|
||||
@@ -38,13 +35,12 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
public class UpdateChecker implements Listener {
|
||||
private static final String MODRINTH_URL = "https://api.modrinth.com/v2/project/lKEzGugV/version";
|
||||
|
||||
private static final int RESOURCE_ID = 6245;
|
||||
private final PlaceholderAPIPlugin plugin;
|
||||
private final TaskScheduler scheduler;
|
||||
private final String pluginVersion;
|
||||
private String modrinthVersion;
|
||||
private String spigotVersion;
|
||||
private boolean updateAvailable;
|
||||
|
||||
public UpdateChecker(PlaceholderAPIPlugin plugin) {
|
||||
@@ -57,27 +53,27 @@ public class UpdateChecker implements Listener {
|
||||
return updateAvailable;
|
||||
}
|
||||
|
||||
public String getModrinthVersion() {
|
||||
return modrinthVersion;
|
||||
public String getSpigotVersion() {
|
||||
return spigotVersion;
|
||||
}
|
||||
|
||||
public void fetch() {
|
||||
scheduler.runTaskAsynchronously(() -> {
|
||||
try {
|
||||
HttpsURLConnection con = (HttpsURLConnection) new URL(MODRINTH_URL).openConnection();
|
||||
HttpsURLConnection con = (HttpsURLConnection) new URL(
|
||||
"https://api.spigotmc.org/legacy/update.php?resource=" + RESOURCE_ID).openConnection();
|
||||
con.setRequestMethod("GET");
|
||||
final JsonElement json = JsonParser.parseReader(new BufferedReader(new InputStreamReader(con.getInputStream())));
|
||||
modrinthVersion = json.getAsJsonArray().get(0).getAsJsonObject().get("version_number").getAsString();
|
||||
spigotVersion = new BufferedReader(new InputStreamReader(con.getInputStream())).readLine();
|
||||
} catch (Exception ex) {
|
||||
plugin.getLogger().info("Failed to check for updates on modrinth.");
|
||||
plugin.getLogger().info("Failed to check for updates on spigot.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (modrinthVersion == null || modrinthVersion.isEmpty()) {
|
||||
if (spigotVersion == null || spigotVersion.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateAvailable = modrinthIsNewer();
|
||||
updateAvailable = spigotIsNewer();
|
||||
|
||||
if (!updateAvailable) {
|
||||
return;
|
||||
@@ -85,21 +81,21 @@ public class UpdateChecker implements Listener {
|
||||
|
||||
scheduler.runTask(() -> {
|
||||
plugin.getLogger()
|
||||
.info("An update for PlaceholderAPI (v" + getModrinthVersion() + ") is available at:");
|
||||
.info("An update for PlaceholderAPI (v" + getSpigotVersion() + ") is available at:");
|
||||
plugin.getLogger()
|
||||
.info("https://modrinth.com/plugin/placeholderapi");
|
||||
.info("https://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID + "/");
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private boolean modrinthIsNewer() {
|
||||
if (modrinthVersion == null || modrinthVersion.isEmpty()) {
|
||||
private boolean spigotIsNewer() {
|
||||
if (spigotVersion == null || spigotVersion.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int[] plV = toReadable(pluginVersion);
|
||||
int[] spV = toReadable(modrinthVersion);
|
||||
int[] spV = toReadable(spigotVersion);
|
||||
|
||||
if (plV[0] < spV[0]) {
|
||||
return true;
|
||||
@@ -122,9 +118,10 @@ public class UpdateChecker implements Listener {
|
||||
public void onJoin(PlayerJoinEvent e) {
|
||||
if (e.getPlayer().hasPermission("placeholderapi.updatenotify")) {
|
||||
Msg.msg(e.getPlayer(),
|
||||
"&bAn update for &fPlaceholder&7API &e(&fPlaceholder&7API &fv" + getModrinthVersion()
|
||||
"&bAn update for &fPlaceholder&7API &e(&fPlaceholder&7API &fv" + getSpigotVersion()
|
||||
+ "&e)"
|
||||
, "&bis available at &ehttps://modrinth.com/plugin/placeholderapi");
|
||||
, "&bis available at &ehttps://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID
|
||||
+ "/");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
# Expansions: https://placeholderapi.com/ecloud
|
||||
# Wiki: https://wiki.placeholderapi.com/
|
||||
# Discord: https://helpch.at/discord
|
||||
# If you're seeing performance issues with plugins that use component replacement, or things don't look quite right,
|
||||
# switch to the replacer provided by adventure itself by changing use_adventure_provided_replacer to true
|
||||
# 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"
|
||||
@@ -17,6 +17,6 @@ boolean:
|
||||
'true': 'yes'
|
||||
'false': 'no'
|
||||
date_format: MM/dd/yy HH:mm:ss
|
||||
use_regex_component_replacer: false
|
||||
detect_malicious_expansions: true
|
||||
use_adventure_provided_replacer: false
|
||||
debug: false
|
||||
|
||||
@@ -12,6 +12,8 @@ commands:
|
||||
placeholderapi:
|
||||
description: "PlaceholderAPI Command"
|
||||
aliases: ["papi"]
|
||||
test:
|
||||
description: "yes"
|
||||
|
||||
permissions:
|
||||
placeholderapi.*:
|
||||
|
||||
@@ -1,184 +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;
|
||||
|
||||
import me.clip.placeholderapi.replacer.ComponentReplacer;
|
||||
import me.clip.placeholderapi.replacer.ExactReplacer;
|
||||
import me.clip.placeholderapi.replacer.RelationalExactReplacer;
|
||||
import me.clip.placeholderapi.replacer.Replacer;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static me.clip.placeholderapi.PlaceholderAPI.RELATIONAL_PLACEHOLDER_PATTERN;
|
||||
|
||||
public final class PAPIComponents {
|
||||
private static final Replacer PERCENT_EXACT_REPLACER = new ExactReplacer('%', '%');
|
||||
private static final Replacer BRACKET_EXACT_REPLACER = new ExactReplacer('{', '}');
|
||||
private static final RelationalExactReplacer RELATIONAL_EXACT_REPLACER = new RelationalExactReplacer();
|
||||
|
||||
/**
|
||||
* Translates all placeholders into their corresponding values.
|
||||
* <br>The pattern of a valid placeholder is {@literal %<identifier>_<params>%}.
|
||||
*
|
||||
* @param player Player to parse the placeholders against
|
||||
* @param component Component to set the placeholder values in
|
||||
* @return Component containing all translated placeholders
|
||||
*/
|
||||
@NotNull
|
||||
public static Component setPlaceholders(final OfflinePlayer player, @NotNull final Component component) {
|
||||
if (PlaceholderAPIPlugin.getInstance().getPlaceholderAPIConfig().useAdventureProvidedReplacer()) {
|
||||
return component.replaceText(config -> config.match(PlaceholderAPI.PLACEHOLDER_PATTERN).replacement((result, builder) ->
|
||||
builder.content(PERCENT_EXACT_REPLACER.apply(result.group(), player, PlaceholderAPIPlugin.getInstance().getLocalExpansionManager()::getExpansion))));
|
||||
}
|
||||
|
||||
return ComponentReplacer.replace(component, str -> PlaceholderAPI.setPlaceholders(player, str));
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates all placeholders into their corresponding values.
|
||||
* <br>The pattern of a valid placeholder is {@literal %<identifier>_<params>%}.
|
||||
*
|
||||
* @param player Player to parse the placeholders against
|
||||
* @param components List of Components to set the placeholder values in
|
||||
* @return List of Components containing all translated placeholders
|
||||
*/
|
||||
@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());
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates all placeholders into their corresponding values.
|
||||
* <br>The pattern of a valid placeholder is {@literal %<identifier>_<params>%}.
|
||||
*
|
||||
* @param player Player to parse the placeholders against
|
||||
* @param component Component to set the placeholder values in
|
||||
* @return Component containing all translated placeholders
|
||||
*/
|
||||
@NotNull
|
||||
public static Component setPlaceholders(final Player player, @NotNull final Component component) {
|
||||
return setPlaceholders((OfflinePlayer) player, component);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates all placeholders into their corresponding values.
|
||||
* <br>The pattern of a valid placeholder is {@literal %<identifier>_<params>%}.
|
||||
*
|
||||
* @param player Player to parse the placeholders against
|
||||
* @param components List of Components to set the placeholder values in
|
||||
* @return List of components containing all translated placeholders
|
||||
*/
|
||||
@NotNull
|
||||
public static List<Component> setPlaceholders(final Player player, @NotNull final List<Component> components) {
|
||||
return setPlaceholders((OfflinePlayer) player, components);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates all placeholders into their corresponding values.
|
||||
* <br>The pattern of a valid placeholder is {@literal {<identifier>_<params>}}.
|
||||
*
|
||||
* @param player Player to parse the placeholders against
|
||||
* @param component Component to set the placeholder values in
|
||||
* @return Component containing all translated placeholders
|
||||
*/
|
||||
@NotNull
|
||||
public static Component setBracketPlaceholders(final OfflinePlayer player, @NotNull final Component component) {
|
||||
if (PlaceholderAPIPlugin.getInstance().getPlaceholderAPIConfig().useAdventureReplacer()) {
|
||||
return component.replaceText(config -> config.match(PlaceholderAPI.BRACKET_PLACEHOLDER_PATTERN).replacement((result, builder) ->
|
||||
builder.content(BRACKET_EXACT_REPLACER.apply(result.group(), player, PlaceholderAPIPlugin.getInstance().getLocalExpansionManager()::getExpansion))));
|
||||
}
|
||||
|
||||
return ComponentReplacer.replace(component, str -> PlaceholderAPI.setBracketPlaceholders(player, str));
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates all placeholders into their corresponding values.
|
||||
* <br>The pattern of a valid placeholder is {@literal {<identifier>_<params>}}.
|
||||
*
|
||||
* @param player Player to parse the placeholders against
|
||||
* @param components List of Components to set the placeholder values in
|
||||
* @return List of Components containing all translated placeholders
|
||||
*/
|
||||
@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());
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates all placeholders into their corresponding values.
|
||||
* <br>The pattern of a valid placeholder is {@literal {<identifier>_<params>}}.
|
||||
*
|
||||
* @param player Player to parse the placeholders against
|
||||
* @param component Component to set the placeholder values in
|
||||
* @return Component containing all translated placeholders
|
||||
*/
|
||||
@NotNull
|
||||
public static Component setBracketPlaceholders(final Player player, @NotNull final Component component) {
|
||||
return setBracketPlaceholders((OfflinePlayer) player, component);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates all placeholders into their corresponding values.
|
||||
* <br>The pattern of a valid placeholder is {@literal {<identifier>_<params>}}.
|
||||
*
|
||||
* @param player Player to parse the placeholders against
|
||||
* @param components List of Components to set the placeholder values in
|
||||
* @return List of Components containing all translated placeholders
|
||||
*/
|
||||
@NotNull
|
||||
public static List<Component> setBracketPlaceholders(final Player player, @NotNull final List<Component> components) {
|
||||
return setBracketPlaceholders((OfflinePlayer) player, components);
|
||||
}
|
||||
|
||||
/**
|
||||
* set relational placeholders in the text specified placeholders are matched with the pattern
|
||||
* {@literal %<rel_(identifier)_(params)>%} when set with this method
|
||||
*
|
||||
* @param one First player to compare
|
||||
* @param two Second player to compare
|
||||
* @param component Component to parse the placeholders in
|
||||
* @return The Component containing the parsed relational placeholders
|
||||
*/
|
||||
public static Component setRelationalPlaceholders(Player one, Player two, Component component) {
|
||||
//todo: custom replacer
|
||||
return component.replaceText(config -> config.match(RELATIONAL_PLACEHOLDER_PATTERN).replacement((result, builder) ->
|
||||
builder.content(RELATIONAL_EXACT_REPLACER.apply(result.group(2), one, two, PlaceholderAPIPlugin.getInstance().getLocalExpansionManager()::getExpansion))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate placeholders in the provided List based on the relation of the two provided players.
|
||||
* <br>The pattern of a valid placeholder is {@literal %rel_<identifier>_<param>%}.
|
||||
*
|
||||
* @param one Player to compare
|
||||
* @param two Player to compare
|
||||
* @param components List of Components to parse the placeholder values to
|
||||
* @return The List of Components containing the parsed relational placeholders
|
||||
*/
|
||||
public static List<Component> setRelationalPlaceholders(Player one, Player two, List<Component> components) {
|
||||
return components.stream().map(line -> setRelationalPlaceholders(one, two, line))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
package me.clip.placeholderapi.replacer;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.nbt.api.BinaryTagHolder;
|
||||
import net.kyori.adventure.text.*;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import net.kyori.adventure.text.event.DataComponentValue;
|
||||
import net.kyori.adventure.text.event.HoverEvent;
|
||||
import net.kyori.adventure.text.format.Style;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ComponentReplacer {
|
||||
@NotNull
|
||||
public static Component replace(@NotNull final Component component, @NotNull final Function<String, String> replacer) {
|
||||
return rebuild(component, replacer);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Component rebuild(@NotNull final Component component, @NotNull final Function<String, String> replacer) {
|
||||
Component rebuilt;
|
||||
|
||||
if (component instanceof TextComponent) {
|
||||
final TextComponent text = (TextComponent) component;
|
||||
final String replaced = replacer.apply(text.content());
|
||||
|
||||
rebuilt = Component.text(replaced);
|
||||
} else if (component instanceof TranslatableComponent) {
|
||||
final TranslatableComponent translatable = (TranslatableComponent) component;
|
||||
final List<Component> arguments = new ArrayList<>();
|
||||
|
||||
for (final ComponentLike arg : translatable.arguments()) {
|
||||
arguments.add(rebuild(arg.asComponent(), replacer));
|
||||
}
|
||||
|
||||
rebuilt = Component.translatable(translatable.key(), arguments);
|
||||
} else if (component instanceof KeybindComponent) {
|
||||
final KeybindComponent keybind = (KeybindComponent) component;
|
||||
rebuilt = Component.keybind(keybind.keybind());
|
||||
} else if (component instanceof ScoreComponent) {
|
||||
final ScoreComponent score = (ScoreComponent) component;
|
||||
rebuilt = Component.score(score.name(), score.objective());
|
||||
} else if (component instanceof SelectorComponent) {
|
||||
final SelectorComponent selector = (SelectorComponent) component;
|
||||
rebuilt = Component.selector(selector.pattern());
|
||||
} else {
|
||||
rebuilt = Component.empty();
|
||||
}
|
||||
|
||||
rebuilt = rebuilt.style(rebuildStyle(component.style(), replacer));
|
||||
|
||||
if (!component.children().isEmpty()) {
|
||||
final List<Component> children = new ArrayList<>();
|
||||
for (Component child : component.children()) {
|
||||
children.add(rebuild(child, replacer));
|
||||
}
|
||||
rebuilt = rebuilt.children(children);
|
||||
}
|
||||
|
||||
return rebuilt;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Style rebuildStyle(@NotNull final Style style, @NotNull final Function<String, String> replacer) {
|
||||
final Style.Builder builder = style.toBuilder();
|
||||
final ClickEvent click = style.clickEvent();
|
||||
|
||||
if (click != null) {
|
||||
builder.clickEvent(rebuildClickEvent(click, replacer));
|
||||
}
|
||||
|
||||
final HoverEvent<?> hover = style.hoverEvent();
|
||||
|
||||
if (hover != null) {
|
||||
builder.hoverEvent(rebuildHoverEvent(hover, replacer));
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ClickEvent rebuildClickEvent(@NotNull final ClickEvent click, @NotNull final Function<String, String> replacer) {
|
||||
final ClickEvent.Payload payload = click.payload();
|
||||
|
||||
if (!(payload instanceof ClickEvent.Payload.Text)) {
|
||||
return click;
|
||||
}
|
||||
|
||||
final String original = ((ClickEvent.Payload.Text) payload).value();
|
||||
final String replaced = replacer.apply(original);
|
||||
|
||||
final ClickEvent.Action action = click.action();
|
||||
|
||||
switch (action) {
|
||||
case OPEN_URL:
|
||||
return ClickEvent.openUrl(replaced);
|
||||
case OPEN_FILE:
|
||||
return ClickEvent.openFile(replaced);
|
||||
case RUN_COMMAND:
|
||||
return ClickEvent.runCommand(replaced);
|
||||
case SUGGEST_COMMAND:
|
||||
return ClickEvent.suggestCommand(replaced);
|
||||
case COPY_TO_CLIPBOARD:
|
||||
return ClickEvent.copyToClipboard(replaced);
|
||||
default:
|
||||
return click;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static HoverEvent<?> rebuildHoverEvent(@NotNull final HoverEvent<?> hover, @NotNull final Function<String, String> replacer) {
|
||||
final Object value = hover.value();
|
||||
|
||||
if (value instanceof Component) {
|
||||
final Component rebuilt = rebuild((Component) value, replacer);
|
||||
return HoverEvent.showText(rebuilt);
|
||||
}
|
||||
|
||||
if (value instanceof HoverEvent.ShowItem) {
|
||||
return rebuildShowItem((HoverEvent.ShowItem) value, replacer);
|
||||
}
|
||||
|
||||
if (value instanceof HoverEvent.ShowEntity) {
|
||||
final HoverEvent.ShowEntity entity = (HoverEvent.ShowEntity) value;
|
||||
|
||||
Component rebuiltName = null;
|
||||
if (entity.name() != null) {
|
||||
rebuiltName = rebuild(entity.name(), replacer);
|
||||
}
|
||||
|
||||
return HoverEvent.showEntity(entity.type(), entity.id(), rebuiltName);
|
||||
}
|
||||
|
||||
return hover;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static HoverEvent<?> rebuildShowItem(@NotNull final HoverEvent.ShowItem item, @NotNull final Function<String, String> replacer) {
|
||||
final BinaryTagHolder nbt = item.nbt();
|
||||
|
||||
if (nbt != null && !nbt.string().isEmpty()) {
|
||||
final String replaced = replacer.apply(nbt.string());
|
||||
|
||||
return HoverEvent.showItem(item.item(), item.count(), BinaryTagHolder.binaryTagHolder(replaced));
|
||||
}
|
||||
|
||||
//I'm not 100% sure this is how we're meant to support data components but let's give it a go and see if it causes any issues :)
|
||||
final Map<Key, DataComponentValue> components = item.dataComponents();
|
||||
|
||||
if (!components.isEmpty()) {
|
||||
final Map<Key, DataComponentValue> rebuilt = new HashMap<>();
|
||||
|
||||
for (final Map.Entry<Key, DataComponentValue> entry : components.entrySet()) {
|
||||
final DataComponentValue value = entry.getValue();
|
||||
|
||||
if (!(value instanceof BinaryTagHolder)) {
|
||||
rebuilt.put(entry.getKey(), value);
|
||||
continue;
|
||||
}
|
||||
|
||||
rebuilt.put(entry.getKey(), BinaryTagHolder.binaryTagHolder(replacer.apply(((BinaryTagHolder) value).string())));
|
||||
}
|
||||
|
||||
return HoverEvent.showItem(item.item(), item.count(), rebuilt);
|
||||
}
|
||||
|
||||
return HoverEvent.showItem(item);
|
||||
}
|
||||
}
|
||||
@@ -1,73 +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.expansion.PlaceholderExpansion;
|
||||
import me.clip.placeholderapi.expansion.Relational;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public final class RelationalExactReplacer {
|
||||
private static final Pattern DELIMITER = Pattern.compile("_");
|
||||
|
||||
@NotNull
|
||||
public String apply(@NotNull String text, @Nullable final Player player1,
|
||||
@Nullable final Player player2, @NotNull final Function<String,
|
||||
@Nullable PlaceholderExpansion> lookup) {
|
||||
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 "%rel_" + text + '%';
|
||||
}
|
||||
|
||||
if (!(expansion instanceof Relational)) {
|
||||
return "%rel_" + text + '%';
|
||||
}
|
||||
|
||||
final String params;
|
||||
|
||||
if (text.endsWith("_")) {
|
||||
params = "";
|
||||
} else {
|
||||
params = text.substring(text.indexOf('_') + 1);
|
||||
}
|
||||
|
||||
final String result = ((Relational) expansion).onPlaceholderRequest(player1, player2, params);
|
||||
|
||||
if (result == null) {
|
||||
return "%rel_" + text + '%';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
* Copyright (c) 2015 - 2024 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
|
||||
|
||||
Reference in New Issue
Block a user