mirror of
https://github.com/PlaceholderAPI/PlaceholderAPI
synced 2026-02-07 12:37:14 +01:00
Compare commits
4 Commits
feature/co
...
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:
|
||||
|
||||
@@ -7,12 +7,6 @@ plugins {
|
||||
id("io.github.goooler.shadow") version "8.1.7"
|
||||
}
|
||||
|
||||
subprojects {
|
||||
apply(plugin = "java-library")
|
||||
apply(plugin = "maven-publish")
|
||||
apply(plugin = "com.github.hierynomus.license")
|
||||
apply(plugin = "io.github.goooler.shadow")
|
||||
|
||||
group = "me.clip"
|
||||
version = "2.11.8-DEV-${System.getProperty("BUILD_NUMBER")}"
|
||||
|
||||
@@ -33,7 +27,9 @@ subprojects {
|
||||
implementation("org.bstats:bstats-bukkit:3.0.1")
|
||||
implementation("net.kyori:adventure-platform-bukkit:4.4.1")
|
||||
|
||||
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")
|
||||
@@ -63,10 +59,12 @@ subprojects {
|
||||
encoding = "UTF-8"
|
||||
|
||||
ext {
|
||||
set("year", 2026)
|
||||
set("year", 2024)
|
||||
}
|
||||
}
|
||||
|
||||
val javaComponent: SoftwareComponent = components["java"]
|
||||
|
||||
tasks {
|
||||
processResources {
|
||||
eachFile { expand("version" to project.version) }
|
||||
@@ -91,9 +89,49 @@ subprojects {
|
||||
}
|
||||
}
|
||||
|
||||
withType<ShadowJar> {
|
||||
archiveClassifier.set("")
|
||||
|
||||
relocate("org.bstats", "me.clip.placeholderapi.metrics")
|
||||
// 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/**")
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
create<MavenPublication>("maven") {
|
||||
artifactId = "placeholderapi"
|
||||
from(javaComponent)
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
if ("-DEV" in version.toString()) {
|
||||
url = uri("https://repo.extendedclip.com/snapshots")
|
||||
} else {
|
||||
url = uri("https://repo.extendedclip.com/releases")
|
||||
}
|
||||
|
||||
credentials {
|
||||
username = System.getenv("JENKINS_USER")
|
||||
password = System.getenv("JENKINS_PASS")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publish.get().setDependsOn(listOf(build.get()))
|
||||
}
|
||||
|
||||
configurations {
|
||||
@@ -101,5 +139,3 @@ subprojects {
|
||||
extendsFrom(compileOnly.get())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
|
||||
dependencies {
|
||||
api(project(":spigot"))
|
||||
}
|
||||
|
||||
val javaComponent: SoftwareComponent = components["java"]
|
||||
|
||||
tasks {
|
||||
withType<ShadowJar> {
|
||||
archiveClassifier.set("")
|
||||
archiveBaseName.set("PlaceholderAPI-Paper")
|
||||
|
||||
relocate("org.bstats", "me.clip.placeholderapi.metrics")
|
||||
|
||||
exclude("META-INF/versions/**")
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
create<MavenPublication>("maven") {
|
||||
artifactId = "placeholderapi-paper"
|
||||
from(javaComponent)
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
if ("-DEV" in version.toString()) {
|
||||
url = uri("https://repo.extendedclip.com/snapshots")
|
||||
} else {
|
||||
url = uri("https://repo.extendedclip.com/releases")
|
||||
}
|
||||
|
||||
credentials {
|
||||
username = System.getenv("JENKINS_USER")
|
||||
password = System.getenv("JENKINS_PASS")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publish.get().setDependsOn(listOf(build.get()))
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
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.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) {
|
||||
// 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(PERCENT_EXACT_REPLACER.apply(result.group(), player, PlaceholderAPIPlugin.getInstance().getLocalExpansionManager()::getExpansion))));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
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))));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
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());
|
||||
}
|
||||
|
||||
// kyori doesn't seem to have a method that can do a contains with regex, we don't want to do a more expensive replace
|
||||
// public static boolean containsPlaceholders(@Nullable final Component text) {
|
||||
// return text != null && text.replaceText()
|
||||
// }
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1 @@
|
||||
rootProject.name = "PlaceholderAPI"
|
||||
|
||||
include("spigot", "paper")
|
||||
@@ -1,41 +0,0 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
|
||||
val javaComponent: SoftwareComponent = components["java"]
|
||||
|
||||
tasks {
|
||||
withType<ShadowJar> {
|
||||
archiveClassifier.set("")
|
||||
archiveBaseName.set("PlaceholderAPI-Spigot")
|
||||
|
||||
relocate("org.bstats", "me.clip.placeholderapi.metrics")
|
||||
relocate("net.kyori", "me.clip.placeholderapi.libs.kyori")
|
||||
|
||||
exclude("META-INF/versions/**")
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
create<MavenPublication>("maven") {
|
||||
artifactId = "placeholderapi"
|
||||
from(javaComponent)
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
if ("-DEV" in version.toString()) {
|
||||
url = uri("https://repo.extendedclip.com/snapshots")
|
||||
} else {
|
||||
url = uri("https://repo.extendedclip.com/releases")
|
||||
}
|
||||
|
||||
credentials {
|
||||
username = System.getenv("JENKINS_USER")
|
||||
password = System.getenv("JENKINS_PASS")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publish.get().setDependsOn(listOf(build.get()))
|
||||
}
|
||||
@@ -1,94 +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.configuration;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class PlaceholderAPIConfig {
|
||||
|
||||
@NotNull
|
||||
private final PlaceholderAPIPlugin plugin;
|
||||
|
||||
public PlaceholderAPIConfig(@NotNull final PlaceholderAPIPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
|
||||
public boolean checkUpdates() {
|
||||
return plugin.getConfig().getBoolean("check_updates");
|
||||
}
|
||||
|
||||
|
||||
public boolean isCloudEnabled() {
|
||||
return plugin.getConfig().getBoolean("cloud_enabled");
|
||||
}
|
||||
|
||||
public void setCloudEnabled(boolean state) {
|
||||
plugin.getConfig().set("cloud_enabled", state);
|
||||
plugin.saveConfig();
|
||||
}
|
||||
|
||||
|
||||
public boolean isDebugMode() {
|
||||
return plugin.getConfig().getBoolean("debug", false);
|
||||
}
|
||||
|
||||
|
||||
public Optional<ExpansionSort> getExpansionSort() {
|
||||
final String option = plugin.getConfig()
|
||||
.getString("cloud_sorting", ExpansionSort.LATEST.name());
|
||||
|
||||
try {
|
||||
//noinspection ConstantConditions (bad spigot annotation)
|
||||
return Optional.of(ExpansionSort.valueOf(option.toUpperCase()));
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public String dateFormat() {
|
||||
//noinspection ConstantConditions (bad spigot annotation)
|
||||
return plugin.getConfig().getString("date_format", "MM/dd/yy HH:mm:ss");
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public String booleanTrue() {
|
||||
//noinspection ConstantConditions (bad spigot annotation)
|
||||
return plugin.getConfig().getString("boolean.true", "true");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String booleanFalse() {
|
||||
//noinspection ConstantConditions (bad spigot annotation)
|
||||
return plugin.getConfig().getString("boolean.false", "false");
|
||||
}
|
||||
|
||||
public boolean detectMaliciousExpansions() {
|
||||
return plugin.getConfig().getBoolean("detect_malicious_expansions", true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,81 +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.expansion;
|
||||
|
||||
public enum NMSVersion {
|
||||
|
||||
UNKNOWN("unknown"),
|
||||
SPIGOT_1_7_R1("v1_7_R1"),
|
||||
SPIGOT_1_7_R2("v1_7_R2"),
|
||||
SPIGOT_1_7_R3("v1_7_R3"),
|
||||
SPIGOT_1_7_R4("v1_7_R4"),
|
||||
SPIGOT_1_8_R1("v1_8_R1"),
|
||||
SPIGOT_1_8_R2("v1_8_R2"),
|
||||
SPIGOT_1_8_R3("v1_8_R3"),
|
||||
SPIGOT_1_9_R1("v1_9_R1"),
|
||||
SPIGOT_1_9_R2("v1_9_R2"),
|
||||
SPIGOT_1_10_R1("v1_10_R1"),
|
||||
SPIGOT_1_11_R1("v1_11_R1"),
|
||||
SPIGOT_1_12_R1("v1_12_R1"),
|
||||
SPIGOT_1_13_R1("v1_13_R1"),
|
||||
SPIGOT_1_13_R2("v1_13_R2"),
|
||||
SPIGOT_1_14_R1("v1_14_R1"),
|
||||
SPIGOT_1_15_R1("v1_15_R1"),
|
||||
SPIGOT_1_16_R1("v1_16_R1"),
|
||||
SPIGOT_1_16_R2("v1_16_R2"),
|
||||
SPIGOT_1_16_R3("v1_16_R3"),
|
||||
SPIGOT_1_17_R1("v1_17_R1"),
|
||||
SPIGOT_1_18_R1("v1_18_R1"),
|
||||
SPIGOT_1_19_R1("v1_19_R1"),
|
||||
SPIGOT_1_19_R2("v1_19_R2"),
|
||||
SPIGOT_1_19_R3("v1_19_R3"),
|
||||
SPIGOT_1_20_R1("v1_20_R1"),
|
||||
SPIGOT_1_20_R2("v1_20_R2"),
|
||||
SPIGOT_1_20_R3("v1_20_R3"),
|
||||
SPIGOT_1_20_R4("v1_20_R4"),
|
||||
SPIGOT_1_21_R1("v1_21_R1"),
|
||||
SPIGOT_1_21_R2("V1_21_R2"),
|
||||
SPIGOT_1_21_R3("V1_21_R3"),
|
||||
SPIGOT_1_21_R4("V1_21_R4"),
|
||||
SPIGOT_1_21_R5("V1_21_R5"),
|
||||
SPIGOT_1_21_R6("V1_21_R6");
|
||||
|
||||
private final String version;
|
||||
|
||||
NMSVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public static NMSVersion getVersion(String version) {
|
||||
for (NMSVersion v : values()) {
|
||||
if (v.getVersion().equalsIgnoreCase(version)) {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
return NMSVersion.UNKNOWN;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,479 +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.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;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Any class extending this will be able to get registered as a PlaceholderExpansion.
|
||||
* <br>The registration either happens automatically when the jar file containing a
|
||||
* class extending this one is located under the {@code PlaceholderAPI/expansions}
|
||||
* directory or when the {@link #register()} method is called by said class.
|
||||
*/
|
||||
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
|
||||
protected Type expansionType = Type.INTERNAL;
|
||||
|
||||
/**
|
||||
* The placeholder identifier of this expansion. May not contain {@literal %},
|
||||
* {@literal {}} or _
|
||||
*
|
||||
* @return placeholder identifier that is associated with this expansion
|
||||
*/
|
||||
@NotNull
|
||||
public abstract String getIdentifier();
|
||||
|
||||
/**
|
||||
* The author of this expansion
|
||||
*
|
||||
* @return name of the author for this expansion
|
||||
*/
|
||||
@NotNull
|
||||
public abstract String getAuthor();
|
||||
|
||||
/**
|
||||
* The version of this expansion
|
||||
*
|
||||
* @return current version of this expansion
|
||||
*/
|
||||
@NotNull
|
||||
public abstract String getVersion();
|
||||
|
||||
/**
|
||||
* The name of this expansion
|
||||
*
|
||||
* @return {@link #getIdentifier()} by default, name of this expansion if specified
|
||||
*/
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return getIdentifier();
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the plugin that this expansion hooks into. by default will null
|
||||
*
|
||||
* @return plugin name that this expansion requires to function
|
||||
*/
|
||||
@Nullable
|
||||
public String getRequiredPlugin() {
|
||||
return getPlugin();
|
||||
}
|
||||
|
||||
/**
|
||||
* The placeholders associated with this expansion
|
||||
*
|
||||
* @return placeholder list that this expansion provides
|
||||
*/
|
||||
@NotNull
|
||||
public List<String> getPlaceholders() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Expansions that do not use the ecloud and instead register from the dependency should set this
|
||||
* to true to ensure that your placeholder expansion is not unregistered when the papi reload
|
||||
* command is used
|
||||
*
|
||||
* @return if this expansion should persist through placeholder reloads
|
||||
*/
|
||||
public boolean persist() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if this placeholder identifier has already been registered
|
||||
*
|
||||
* @return true if the identifier for this expansion is already registered
|
||||
*/
|
||||
public final boolean isRegistered() {
|
||||
return getPlaceholderAPI().getLocalExpansionManager().findExpansionByIdentifier(getIdentifier())
|
||||
.map(it -> it.equals(this)).orElse(false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If any requirements need to be checked before this expansion should register, you can check
|
||||
* them here
|
||||
*
|
||||
* @return true if this hook meets all the requirements to register
|
||||
*/
|
||||
public boolean canRegister() {
|
||||
return getRequiredPlugin() == null
|
||||
|| Bukkit.getPluginManager().getPlugin(getRequiredPlugin()) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to register this PlaceholderExpansion
|
||||
*
|
||||
* @return true if this expansion is now registered with PlaceholderAPI
|
||||
*/
|
||||
public boolean register() {
|
||||
return getPlaceholderAPI().getLocalExpansionManager().register(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to unregister this PlaceholderExpansion
|
||||
*
|
||||
* @return true if this expansion is now unregistered with PlaceholderAPI
|
||||
*/
|
||||
public final boolean unregister() {
|
||||
return getPlaceholderAPI().getLocalExpansionManager().unregister(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Quick getter for the {@link PlaceholderAPIPlugin} instance
|
||||
*
|
||||
* @return {@link PlaceholderAPIPlugin} instance
|
||||
*/
|
||||
@NotNull
|
||||
public final PlaceholderAPIPlugin getPlaceholderAPI() {
|
||||
return PlaceholderAPIPlugin.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of the expansion
|
||||
*
|
||||
* @return the type of the expansion
|
||||
* @since 2.11.4
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public Type getExpansionType() {
|
||||
return expansionType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type of the expansion
|
||||
*
|
||||
* @param expansionType the new type
|
||||
* @since 2.11.4
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public void setExpansionType(Type expansionType) {
|
||||
this.expansionType = expansionType;
|
||||
}
|
||||
|
||||
// === Configuration ===
|
||||
|
||||
/**
|
||||
* Gets the ConfigurationSection of the expansion located in the config.yml of PlaceholderAPI or
|
||||
* null when not specified.
|
||||
* <br>You may use the {@link Configurable} interface to define default values set
|
||||
*
|
||||
* @return ConfigurationSection that this expansion has.
|
||||
*/
|
||||
@Nullable
|
||||
public final ConfigurationSection getConfigSection() {
|
||||
return getPlaceholderAPI().getConfig().getConfigurationSection("expansions." + getIdentifier());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ConfigurationSection relative to the {@link #getConfigSection() default one} set
|
||||
* by the expansion or null when the default ConfigurationSection is null
|
||||
*
|
||||
* @param path The path to get the ConfigurationSection from. This is relative to the default section
|
||||
* @return ConfigurationSection relative to the default section
|
||||
*/
|
||||
@Nullable
|
||||
public final ConfigurationSection getConfigSection(@NotNull final String path) {
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? null : section.getConfigurationSection(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Object relative to the {@link #getConfigSection() default ConfigurationSection} set
|
||||
* by the expansion or the provided Default Object, when the default ConfigurationSection is null
|
||||
*
|
||||
* @param path The path to get the Object from. This is relative to the default section
|
||||
* @param def The default Object to return when the ConfigurationSection returns null
|
||||
* @return Object from the provided path or the default one provided
|
||||
*/
|
||||
@Nullable
|
||||
@Contract("_, !null -> !null")
|
||||
public final Object get(@NotNull final String path, final Object def) {
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? def : section.get(path, def);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the int relative to the {@link #getConfigSection() default ConfigurationSection} set
|
||||
* by the expansion or the provided Default int, when the default ConfigurationSection is null
|
||||
*
|
||||
* @param path The path to get the int from. This is relative to the default section
|
||||
* @param def The default int to return when the ConfigurationSection returns null
|
||||
* @return int from the provided path or the default one provided
|
||||
*/
|
||||
public final int getInt(@NotNull final String path, final int def) {
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? def : section.getInt(path, def);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the long relative to the {@link #getConfigSection() default ConfigurationSection} set
|
||||
* by the expansion or the provided Default long, when the default ConfigurationSection is null
|
||||
*
|
||||
* @param path The path to get the long from. This is relative to the default section
|
||||
* @param def The default long to return when the ConfigurationSection returns null
|
||||
* @return long from the provided path or the default one provided
|
||||
*/
|
||||
public final long getLong(@NotNull final String path, final long def) {
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? def : section.getLong(path, def);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the double relative to the {@link #getConfigSection() default ConfigurationSection} set
|
||||
* by the expansion or the provided Default double, when the default ConfigurationSection is null
|
||||
*
|
||||
* @param path The path to get the double from. This is relative to the default section
|
||||
* @param def The default double to return when the ConfigurationSection returns null
|
||||
* @return double from the provided path or the default one provided
|
||||
*/
|
||||
public final double getDouble(@NotNull final String path, final double def) {
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? def : section.getDouble(path, def);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the String relative to the {@link #getConfigSection() default ConfigurationSection} set
|
||||
* by the expansion or the provided Default String, when the default ConfigurationSection is null
|
||||
*
|
||||
* @param path The path to get the String from. This is relative to the default section
|
||||
* @param def The default String to return when the ConfigurationSection returns null. Can be null
|
||||
* @return String from the provided path or the default one provided
|
||||
*/
|
||||
@Nullable
|
||||
@Contract("_, !null -> !null")
|
||||
public final String getString(@NotNull final String path, @Nullable final String def) {
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? def : section.getString(path, def);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a String List relative to the {@link #getConfigSection() default ConfigurationSection} set
|
||||
* by the expansion or an empty List, when the default ConfigurationSection is null
|
||||
*
|
||||
* @param path The path to get the String list from. This is relative to the default section
|
||||
* @return String list from the provided path or an empty list
|
||||
*/
|
||||
@NotNull
|
||||
public final List<String> getStringList(@NotNull final String path) {
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? Collections.emptyList() : section.getStringList(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the boolean relative to the {@link #getConfigSection() default ConfigurationSection} set
|
||||
* by the expansion or the default boolean, when the default ConfigurationSection is null
|
||||
*
|
||||
* @param path The path to get the boolean from. This is relative to the default section
|
||||
* @param def The default boolean to return when the ConfigurationSection is null
|
||||
* @return boolean from the provided path or the default one provided
|
||||
*/
|
||||
public final boolean getBoolean(@NotNull final String path, final boolean def) {
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? def : section.getBoolean(path, def);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the {@link #getConfigSection() default ConfigurationSection} contains the provided path
|
||||
* or not. This will return {@code false} when either the default section is null, or doesn't
|
||||
* contain the provided path
|
||||
*
|
||||
* @param path The path to check
|
||||
* @return true when the default ConfigurationSection is not null and contains the path, false otherwise
|
||||
*/
|
||||
public final boolean configurationContains(@NotNull final String path) {
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section != null && section.contains(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the provided message with the provided Level in the console.
|
||||
* <br>The message will be prefixed with {@link #getName() <code>[<expansion name>]</code>}
|
||||
*
|
||||
* @param level The Level at which the message should be logged with
|
||||
* @param msg The message to log
|
||||
*/
|
||||
public void log(Level level, String msg) {
|
||||
getPlaceholderAPI().getLogger().log(level, "[" + getName() + "] " + msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the provided message and Throwable with the provided Level in the console.
|
||||
* <br>The message will be prefixed with {@link #getName() <code>[<expansion name>]</code>}
|
||||
*
|
||||
* @param level The Level at which the message should be logged with
|
||||
* @param msg The message to log
|
||||
* @param throwable The Throwable to log
|
||||
*/
|
||||
public void log(Level level, String msg, Throwable throwable) {
|
||||
getPlaceholderAPI().getLogger().log(level, "[" + getName() + "] " + msg, throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the provided message with Level "info".
|
||||
* <br>The message will be prefixed with {@link #getName() <code>[<expansion name>]</code>}
|
||||
*
|
||||
* @param msg The message to log
|
||||
*/
|
||||
public void info(String msg) {
|
||||
log(Level.INFO, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the provided message with Level "warning".
|
||||
* <br>The message will be prefixed with {@link #getName() <code>[<expansion name>]</code>}
|
||||
*
|
||||
* @param msg The message to log
|
||||
*/
|
||||
public void warning(String msg) {
|
||||
log(Level.WARNING, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the provided message with Level "severe" (error).
|
||||
* <br>The message will be prefixed with {@link #getName() <code>[<expansion name>]</code>}
|
||||
*
|
||||
* @param msg The message to log
|
||||
*/
|
||||
public void severe(String msg) {
|
||||
log(Level.SEVERE, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the provided message and Throwable with Level "severe" (error).
|
||||
* <br>The message will be prefixed with {@link #getName() <code>[<expansion name>]</code>}
|
||||
*
|
||||
* @param msg The message to log
|
||||
* @param throwable The Throwable to log
|
||||
*/
|
||||
public void severe(String msg, Throwable throwable) {
|
||||
log(Level.SEVERE, msg, throwable);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Whether the provided Object is an instance of this PlaceholderExpansion.
|
||||
* <br>This method will perform the following checks in order:
|
||||
* <br><ul>
|
||||
* <li>Checks if Object equals the class. Returns true when equal and continues otherwise</li>
|
||||
* <li>Checks if the Object is an instance of a PlaceholderExpansion. Returns false if not</li>
|
||||
* <li>Checks if the Object's Identifier, Author and version equal the one of this class</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param o The Object to check
|
||||
* @return true or false depending on the above mentioned checks
|
||||
*/
|
||||
@Override
|
||||
public final boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof PlaceholderExpansion)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PlaceholderExpansion expansion = (PlaceholderExpansion) o;
|
||||
|
||||
return getIdentifier().equals(expansion.getIdentifier()) &&
|
||||
getAuthor().equals(expansion.getAuthor()) &&
|
||||
getVersion().equals(expansion.getVersion());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a String containing the Expansion's name, author and version
|
||||
*
|
||||
* @return String containing name, author and version of the expansion
|
||||
*/
|
||||
@Override
|
||||
public final String toString() {
|
||||
return String.format("PlaceholderExpansion[name: '%s', author: '%s', version: '%s', type: '%s']", getName(),
|
||||
getAuthor(), getVersion(), getExpansionType());
|
||||
}
|
||||
|
||||
// === Deprecated API ===
|
||||
|
||||
/**
|
||||
* @return The plugin name.
|
||||
* @deprecated As of versions greater than 2.8.7, use {@link #getRequiredPlugin()}
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
public String getPlugin() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The description of the expansion.
|
||||
* @deprecated As of versions greater than 2.8.7, use the expansion cloud to show a description
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
public String getDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The link for the expansion.
|
||||
* @deprecated As of versions greater than 2.8.7, use the expansion cloud to display a link
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
public String getLink() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
|
||||
/**
|
||||
* An expansion provided by a plugin is considered internal
|
||||
*/
|
||||
INTERNAL,
|
||||
|
||||
/**
|
||||
* An expansion loaded from the expansions folder is considered external
|
||||
*/
|
||||
EXTERNAL
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,128 +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.updatechecker;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||
import me.clip.placeholderapi.util.Msg;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
public class UpdateChecker implements Listener {
|
||||
|
||||
private static final int RESOURCE_ID = 6245;
|
||||
private final PlaceholderAPIPlugin plugin;
|
||||
private final TaskScheduler scheduler;
|
||||
private final String pluginVersion;
|
||||
private String spigotVersion;
|
||||
private boolean updateAvailable;
|
||||
|
||||
public UpdateChecker(PlaceholderAPIPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
scheduler = plugin.getScheduler();
|
||||
pluginVersion = plugin.getDescription().getVersion();
|
||||
}
|
||||
|
||||
public boolean hasUpdateAvailable() {
|
||||
return updateAvailable;
|
||||
}
|
||||
|
||||
public String getSpigotVersion() {
|
||||
return spigotVersion;
|
||||
}
|
||||
|
||||
public void fetch() {
|
||||
scheduler.runTaskAsynchronously(() -> {
|
||||
try {
|
||||
HttpsURLConnection con = (HttpsURLConnection) new URL(
|
||||
"https://api.spigotmc.org/legacy/update.php?resource=" + RESOURCE_ID).openConnection();
|
||||
con.setRequestMethod("GET");
|
||||
spigotVersion = new BufferedReader(new InputStreamReader(con.getInputStream())).readLine();
|
||||
} catch (Exception ex) {
|
||||
plugin.getLogger().info("Failed to check for updates on spigot.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (spigotVersion == null || spigotVersion.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateAvailable = spigotIsNewer();
|
||||
|
||||
if (!updateAvailable) {
|
||||
return;
|
||||
}
|
||||
|
||||
scheduler.runTask(() -> {
|
||||
plugin.getLogger()
|
||||
.info("An update for PlaceholderAPI (v" + getSpigotVersion() + ") is available at:");
|
||||
plugin.getLogger()
|
||||
.info("https://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID + "/");
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private boolean spigotIsNewer() {
|
||||
if (spigotVersion == null || spigotVersion.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int[] plV = toReadable(pluginVersion);
|
||||
int[] spV = toReadable(spigotVersion);
|
||||
|
||||
if (plV[0] < spV[0]) {
|
||||
return true;
|
||||
} else if ((plV[1] < spV[1])) {
|
||||
return true;
|
||||
} else {
|
||||
return plV[2] < spV[2];
|
||||
}
|
||||
}
|
||||
|
||||
private int[] toReadable(String version) {
|
||||
if (version.contains("-DEV")) {
|
||||
version = version.split("-DEV")[0];
|
||||
}
|
||||
|
||||
return Arrays.stream(version.split("\\.")).mapToInt(Integer::parseInt).toArray();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onJoin(PlayerJoinEvent e) {
|
||||
if (e.getPlayer().hasPermission("placeholderapi.updatenotify")) {
|
||||
Msg.msg(e.getPlayer(),
|
||||
"&bAn update for &fPlaceholder&7API &e(&fPlaceholder&7API &fv" + getSpigotVersion()
|
||||
+ "&e)"
|
||||
, "&bis available at &ehttps://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID
|
||||
+ "/");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,93 +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 com.google.common.collect.ImmutableMap;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import me.clip.placeholderapi.replacer.CharsReplacer;
|
||||
import me.clip.placeholderapi.replacer.Replacer;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface Values {
|
||||
|
||||
String SMALL_TEXT = "My name is %player_name%";
|
||||
String LARGE_TEXT = "My name is %player_name% and my location is (%player_x%, %player_y%, %player_z%), this placeholder is invalid %server_name%";
|
||||
|
||||
ImmutableMap<String, PlaceholderExpansion> PLACEHOLDERS = ImmutableMap.<String, PlaceholderExpansion>builder()
|
||||
.put("player", new MockPlayerPlaceholderExpansion())
|
||||
.build();
|
||||
|
||||
|
||||
Replacer CHARS_REPLACER = new CharsReplacer(Replacer.Closure.PERCENT);
|
||||
|
||||
|
||||
final class MockPlayerPlaceholderExpansion extends PlaceholderExpansion {
|
||||
|
||||
public static final String PLAYER_X = "10";
|
||||
public static final String PLAYER_Y = "20";
|
||||
public static final String PLAYER_Z = "30";
|
||||
public static final String PLAYER_NAME = "Sxtanna";
|
||||
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "player";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getAuthor() {
|
||||
return "Sxtanna";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return "1.0";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onRequest(@Nullable final OfflinePlayer player, @NotNull final String params) {
|
||||
final String[] parts = params.split("_");
|
||||
if (parts.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (parts[0]) {
|
||||
case "name":
|
||||
return PLAYER_NAME;
|
||||
case "x":
|
||||
return PLAYER_X;
|
||||
case "y":
|
||||
return PLAYER_Y;
|
||||
case "z":
|
||||
return PLAYER_Z;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
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();
|
||||
@@ -261,12 +266,6 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
final PlaceholderCommandRouter router = new PlaceholderCommandRouter(this);
|
||||
pluginCommand.setExecutor(router);
|
||||
pluginCommand.setTabCompleter(router);
|
||||
|
||||
try {
|
||||
getServer().getPluginManager().registerEvents((Listener) Class.forName("me.clip.placeholderapi.TestListener").newInstance(), this);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void setupMetrics() {
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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,16 +170,19 @@ public final class CommandECloudExpansionList extends PlaceholderCommand {
|
||||
.append(newline()).append(newline())
|
||||
.append(text("Author: ", AQUA)).append(text(expansion.getAuthor(), WHITE))
|
||||
.append(newline())
|
||||
.append(text("Verified: ", AQUA)).append(text(expansion.getVersion().isVerified() ? "✔" : "❌", expansion.getVersion().isVerified() ? GREEN : RED, TextDecoration.BOLD))
|
||||
.append(text("Verified: ", AQUA)).append(text(expansion.isVerified() ? "✔" : "❌", expansion.isVerified() ? GREEN : RED, TextDecoration.BOLD))
|
||||
.append(newline())
|
||||
.append(text("Released: ", AQUA)).append(text(format.format(expansion.getLastUpdate()), WHITE))
|
||||
.toBuilder();
|
||||
|
||||
Optional.ofNullable(expansion.getDescription())
|
||||
.filter(description -> !description.isEmpty())
|
||||
.ifPresent(description -> hoverText.append(newline()).append(newline())
|
||||
.append(text(description.replace("\r", "").trim(), WHITE))
|
||||
);
|
||||
final TextComponent.Builder hoverText = text("Click to download this expansion!", AQUA)
|
||||
.append(newline()).append(newline())
|
||||
.append(text("Author: ", AQUA)).append(text(expansion.getAuthor(), WHITE))
|
||||
.append(newline())
|
||||
.append(text("Verified: ", AQUA)).append(text(expansion.getVersion().isVerified() ? "✔" : "❌", expansion.getVersion().isVerified() ? GREEN : RED, TextDecoration.BOLD))
|
||||
.append(newline())
|
||||
.append(text("Released: ", AQUA)).append(text(format.format(expansion.getLastUpdate()), WHITE))
|
||||
.toBuilder();
|
||||
|
||||
line.hoverEvent(HoverEvent.showText(hoverText.build()));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* 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
|
||||
* 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.configuration;
|
||||
|
||||
import java.util.Optional;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class PlaceholderAPIConfig {
|
||||
|
||||
@NotNull
|
||||
private final PlaceholderAPIPlugin plugin;
|
||||
|
||||
public PlaceholderAPIConfig(@NotNull final PlaceholderAPIPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
|
||||
public boolean checkUpdates() {
|
||||
return plugin.getConfig().getBoolean("check_updates");
|
||||
}
|
||||
|
||||
|
||||
public boolean isCloudEnabled() {
|
||||
return plugin.getConfig().getBoolean("cloud_enabled");
|
||||
}
|
||||
|
||||
public void setCloudEnabled(boolean state) {
|
||||
plugin.getConfig().set("cloud_enabled", state);
|
||||
plugin.saveConfig();
|
||||
}
|
||||
|
||||
|
||||
public boolean isDebugMode() {
|
||||
return plugin.getConfig().getBoolean("debug", false);
|
||||
}
|
||||
|
||||
|
||||
public Optional<ExpansionSort> getExpansionSort() {
|
||||
final String option = plugin.getConfig()
|
||||
.getString("cloud_sorting", ExpansionSort.LATEST.name());
|
||||
|
||||
try {
|
||||
//noinspection ConstantConditions (bad spigot annotation)
|
||||
return Optional.of(ExpansionSort.valueOf(option.toUpperCase()));
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public String dateFormat() {
|
||||
//noinspection ConstantConditions (bad spigot annotation)
|
||||
return plugin.getConfig().getString("date_format", "MM/dd/yy HH:mm:ss");
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public String booleanTrue() {
|
||||
//noinspection ConstantConditions (bad spigot annotation)
|
||||
return plugin.getConfig().getString("boolean.true", "true");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String booleanFalse() {
|
||||
//noinspection ConstantConditions (bad spigot annotation)
|
||||
return plugin.getConfig().getString("boolean.false", "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
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* 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
|
||||
* 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.expansion;
|
||||
|
||||
public enum NMSVersion {
|
||||
|
||||
UNKNOWN("unknown"),
|
||||
SPIGOT_1_7_R1("v1_7_R1"),
|
||||
SPIGOT_1_7_R2("v1_7_R2"),
|
||||
SPIGOT_1_7_R3("v1_7_R3"),
|
||||
SPIGOT_1_7_R4("v1_7_R4"),
|
||||
SPIGOT_1_8_R1("v1_8_R1"),
|
||||
SPIGOT_1_8_R2("v1_8_R2"),
|
||||
SPIGOT_1_8_R3("v1_8_R3"),
|
||||
SPIGOT_1_9_R1("v1_9_R1"),
|
||||
SPIGOT_1_9_R2("v1_9_R2"),
|
||||
SPIGOT_1_10_R1("v1_10_R1"),
|
||||
SPIGOT_1_11_R1("v1_11_R1"),
|
||||
SPIGOT_1_12_R1("v1_12_R1"),
|
||||
SPIGOT_1_13_R1("v1_13_R1"),
|
||||
SPIGOT_1_13_R2("v1_13_R2"),
|
||||
SPIGOT_1_14_R1("v1_14_R1"),
|
||||
SPIGOT_1_15_R1("v1_15_R1"),
|
||||
SPIGOT_1_16_R1("v1_16_R1"),
|
||||
SPIGOT_1_16_R2("v1_16_R2"),
|
||||
SPIGOT_1_16_R3("v1_16_R3"),
|
||||
SPIGOT_1_17_R1("v1_17_R1"),
|
||||
SPIGOT_1_18_R1("v1_18_R1"),
|
||||
SPIGOT_1_19_R1("v1_19_R1"),
|
||||
SPIGOT_1_19_R2("v1_19_R2"),
|
||||
SPIGOT_1_19_R3("v1_19_R3"),
|
||||
SPIGOT_1_20_R1("v1_20_R1"),
|
||||
SPIGOT_1_20_R2("v1_20_R2"),
|
||||
SPIGOT_1_20_R3("v1_20_R3"),
|
||||
SPIGOT_1_20_R4("v1_20_R4"),
|
||||
SPIGOT_1_21_R1("v1_21_R1"),
|
||||
SPIGOT_1_21_R2("V1_21_R2"),
|
||||
SPIGOT_1_21_R3("V1_21_R3"),
|
||||
SPIGOT_1_21_R4("V1_21_R4"),
|
||||
SPIGOT_1_21_R5("V1_21_R5"),
|
||||
SPIGOT_1_21_R6("V1_21_R6");
|
||||
|
||||
private final String version;
|
||||
|
||||
NMSVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public static NMSVersion getVersion(String version) {
|
||||
for (NMSVersion v : values()) {
|
||||
if (v.getVersion().equalsIgnoreCase(version)) {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
return NMSVersion.UNKNOWN;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,479 @@
|
||||
/*
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* 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
|
||||
* 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.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;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Any class extending this will be able to get registered as a PlaceholderExpansion.
|
||||
* <br>The registration either happens automatically when the jar file containing a
|
||||
* class extending this one is located under the {@code PlaceholderAPI/expansions}
|
||||
* directory or when the {@link #register()} method is called by said class.
|
||||
*/
|
||||
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
|
||||
protected Type expansionType = Type.INTERNAL;
|
||||
|
||||
/**
|
||||
* The placeholder identifier of this expansion. May not contain {@literal %},
|
||||
* {@literal {}} or _
|
||||
*
|
||||
* @return placeholder identifier that is associated with this expansion
|
||||
*/
|
||||
@NotNull
|
||||
public abstract String getIdentifier();
|
||||
|
||||
/**
|
||||
* The author of this expansion
|
||||
*
|
||||
* @return name of the author for this expansion
|
||||
*/
|
||||
@NotNull
|
||||
public abstract String getAuthor();
|
||||
|
||||
/**
|
||||
* The version of this expansion
|
||||
*
|
||||
* @return current version of this expansion
|
||||
*/
|
||||
@NotNull
|
||||
public abstract String getVersion();
|
||||
|
||||
/**
|
||||
* The name of this expansion
|
||||
*
|
||||
* @return {@link #getIdentifier()} by default, name of this expansion if specified
|
||||
*/
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return getIdentifier();
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the plugin that this expansion hooks into. by default will null
|
||||
*
|
||||
* @return plugin name that this expansion requires to function
|
||||
*/
|
||||
@Nullable
|
||||
public String getRequiredPlugin() {
|
||||
return getPlugin();
|
||||
}
|
||||
|
||||
/**
|
||||
* The placeholders associated with this expansion
|
||||
*
|
||||
* @return placeholder list that this expansion provides
|
||||
*/
|
||||
@NotNull
|
||||
public List<String> getPlaceholders() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Expansions that do not use the ecloud and instead register from the dependency should set this
|
||||
* to true to ensure that your placeholder expansion is not unregistered when the papi reload
|
||||
* command is used
|
||||
*
|
||||
* @return if this expansion should persist through placeholder reloads
|
||||
*/
|
||||
public boolean persist() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if this placeholder identifier has already been registered
|
||||
*
|
||||
* @return true if the identifier for this expansion is already registered
|
||||
*/
|
||||
public final boolean isRegistered() {
|
||||
return getPlaceholderAPI().getLocalExpansionManager().findExpansionByIdentifier(getIdentifier())
|
||||
.map(it -> it.equals(this)).orElse(false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If any requirements need to be checked before this expansion should register, you can check
|
||||
* them here
|
||||
*
|
||||
* @return true if this hook meets all the requirements to register
|
||||
*/
|
||||
public boolean canRegister() {
|
||||
return getRequiredPlugin() == null
|
||||
|| Bukkit.getPluginManager().getPlugin(getRequiredPlugin()) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to register this PlaceholderExpansion
|
||||
*
|
||||
* @return true if this expansion is now registered with PlaceholderAPI
|
||||
*/
|
||||
public boolean register() {
|
||||
return getPlaceholderAPI().getLocalExpansionManager().register(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to unregister this PlaceholderExpansion
|
||||
*
|
||||
* @return true if this expansion is now unregistered with PlaceholderAPI
|
||||
*/
|
||||
public final boolean unregister() {
|
||||
return getPlaceholderAPI().getLocalExpansionManager().unregister(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Quick getter for the {@link PlaceholderAPIPlugin} instance
|
||||
*
|
||||
* @return {@link PlaceholderAPIPlugin} instance
|
||||
*/
|
||||
@NotNull
|
||||
public final PlaceholderAPIPlugin getPlaceholderAPI() {
|
||||
return PlaceholderAPIPlugin.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of the expansion
|
||||
*
|
||||
* @return the type of the expansion
|
||||
* @since 2.11.4
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public Type getExpansionType() {
|
||||
return expansionType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type of the expansion
|
||||
* @param expansionType the new type
|
||||
* @since 2.11.4
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public void setExpansionType(Type expansionType) {
|
||||
this.expansionType = expansionType;
|
||||
}
|
||||
|
||||
// === Configuration ===
|
||||
|
||||
/**
|
||||
* Gets the ConfigurationSection of the expansion located in the config.yml of PlaceholderAPI or
|
||||
* null when not specified.
|
||||
* <br>You may use the {@link Configurable} interface to define default values set
|
||||
*
|
||||
* @return ConfigurationSection that this expansion has.
|
||||
*/
|
||||
@Nullable
|
||||
public final ConfigurationSection getConfigSection() {
|
||||
return getPlaceholderAPI().getConfig().getConfigurationSection("expansions." + getIdentifier());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ConfigurationSection relative to the {@link #getConfigSection() default one} set
|
||||
* by the expansion or null when the default ConfigurationSection is null
|
||||
*
|
||||
* @param path The path to get the ConfigurationSection from. This is relative to the default section
|
||||
* @return ConfigurationSection relative to the default section
|
||||
*/
|
||||
@Nullable
|
||||
public final ConfigurationSection getConfigSection(@NotNull final String path) {
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? null : section.getConfigurationSection(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Object relative to the {@link #getConfigSection() default ConfigurationSection} set
|
||||
* by the expansion or the provided Default Object, when the default ConfigurationSection is null
|
||||
*
|
||||
* @param path The path to get the Object from. This is relative to the default section
|
||||
* @param def The default Object to return when the ConfigurationSection returns null
|
||||
* @return Object from the provided path or the default one provided
|
||||
*/
|
||||
@Nullable
|
||||
@Contract("_, !null -> !null")
|
||||
public final Object get(@NotNull final String path, final Object def) {
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? def : section.get(path, def);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the int relative to the {@link #getConfigSection() default ConfigurationSection} set
|
||||
* by the expansion or the provided Default int, when the default ConfigurationSection is null
|
||||
*
|
||||
* @param path The path to get the int from. This is relative to the default section
|
||||
* @param def The default int to return when the ConfigurationSection returns null
|
||||
* @return int from the provided path or the default one provided
|
||||
*/
|
||||
public final int getInt(@NotNull final String path, final int def) {
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? def : section.getInt(path, def);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the long relative to the {@link #getConfigSection() default ConfigurationSection} set
|
||||
* by the expansion or the provided Default long, when the default ConfigurationSection is null
|
||||
*
|
||||
* @param path The path to get the long from. This is relative to the default section
|
||||
* @param def The default long to return when the ConfigurationSection returns null
|
||||
* @return long from the provided path or the default one provided
|
||||
*/
|
||||
public final long getLong(@NotNull final String path, final long def) {
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? def : section.getLong(path, def);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the double relative to the {@link #getConfigSection() default ConfigurationSection} set
|
||||
* by the expansion or the provided Default double, when the default ConfigurationSection is null
|
||||
*
|
||||
* @param path The path to get the double from. This is relative to the default section
|
||||
* @param def The default double to return when the ConfigurationSection returns null
|
||||
* @return double from the provided path or the default one provided
|
||||
*/
|
||||
public final double getDouble(@NotNull final String path, final double def) {
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? def : section.getDouble(path, def);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the String relative to the {@link #getConfigSection() default ConfigurationSection} set
|
||||
* by the expansion or the provided Default String, when the default ConfigurationSection is null
|
||||
*
|
||||
* @param path The path to get the String from. This is relative to the default section
|
||||
* @param def The default String to return when the ConfigurationSection returns null. Can be null
|
||||
* @return String from the provided path or the default one provided
|
||||
*/
|
||||
@Nullable
|
||||
@Contract("_, !null -> !null")
|
||||
public final String getString(@NotNull final String path, @Nullable final String def) {
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? def : section.getString(path, def);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a String List relative to the {@link #getConfigSection() default ConfigurationSection} set
|
||||
* by the expansion or an empty List, when the default ConfigurationSection is null
|
||||
*
|
||||
* @param path The path to get the String list from. This is relative to the default section
|
||||
* @return String list from the provided path or an empty list
|
||||
*/
|
||||
@NotNull
|
||||
public final List<String> getStringList(@NotNull final String path) {
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? Collections.emptyList() : section.getStringList(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the boolean relative to the {@link #getConfigSection() default ConfigurationSection} set
|
||||
* by the expansion or the default boolean, when the default ConfigurationSection is null
|
||||
*
|
||||
* @param path The path to get the boolean from. This is relative to the default section
|
||||
* @param def The default boolean to return when the ConfigurationSection is null
|
||||
* @return boolean from the provided path or the default one provided
|
||||
*/
|
||||
public final boolean getBoolean(@NotNull final String path, final boolean def) {
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? def : section.getBoolean(path, def);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the {@link #getConfigSection() default ConfigurationSection} contains the provided path
|
||||
* or not. This will return {@code false} when either the default section is null, or doesn't
|
||||
* contain the provided path
|
||||
*
|
||||
* @param path The path to check
|
||||
* @return true when the default ConfigurationSection is not null and contains the path, false otherwise
|
||||
*/
|
||||
public final boolean configurationContains(@NotNull final String path) {
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section != null && section.contains(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the provided message with the provided Level in the console.
|
||||
* <br>The message will be prefixed with {@link #getName() <code>[<expansion name>]</code>}
|
||||
*
|
||||
* @param level The Level at which the message should be logged with
|
||||
* @param msg The message to log
|
||||
*/
|
||||
public void log(Level level, String msg) {
|
||||
getPlaceholderAPI().getLogger().log(level, "[" + getName() + "] " + msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the provided message and Throwable with the provided Level in the console.
|
||||
* <br>The message will be prefixed with {@link #getName() <code>[<expansion name>]</code>}
|
||||
*
|
||||
* @param level The Level at which the message should be logged with
|
||||
* @param msg The message to log
|
||||
* @param throwable The Throwable to log
|
||||
*/
|
||||
public void log(Level level, String msg, Throwable throwable) {
|
||||
getPlaceholderAPI().getLogger().log(level, "[" + getName() + "] " + msg, throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the provided message with Level "info".
|
||||
* <br>The message will be prefixed with {@link #getName() <code>[<expansion name>]</code>}
|
||||
*
|
||||
* @param msg The message to log
|
||||
*/
|
||||
public void info(String msg) {
|
||||
log(Level.INFO, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the provided message with Level "warning".
|
||||
* <br>The message will be prefixed with {@link #getName() <code>[<expansion name>]</code>}
|
||||
*
|
||||
* @param msg The message to log
|
||||
*/
|
||||
public void warning(String msg) {
|
||||
log(Level.WARNING, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the provided message with Level "severe" (error).
|
||||
* <br>The message will be prefixed with {@link #getName() <code>[<expansion name>]</code>}
|
||||
*
|
||||
* @param msg The message to log
|
||||
*/
|
||||
public void severe(String msg) {
|
||||
log(Level.SEVERE, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the provided message and Throwable with Level "severe" (error).
|
||||
* <br>The message will be prefixed with {@link #getName() <code>[<expansion name>]</code>}
|
||||
*
|
||||
* @param msg The message to log
|
||||
* @param throwable The Throwable to log
|
||||
*/
|
||||
public void severe(String msg, Throwable throwable) {
|
||||
log(Level.SEVERE, msg, throwable);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Whether the provided Object is an instance of this PlaceholderExpansion.
|
||||
* <br>This method will perform the following checks in order:
|
||||
* <br><ul>
|
||||
* <li>Checks if Object equals the class. Returns true when equal and continues otherwise</li>
|
||||
* <li>Checks if the Object is an instance of a PlaceholderExpansion. Returns false if not</li>
|
||||
* <li>Checks if the Object's Identifier, Author and version equal the one of this class</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param o The Object to check
|
||||
* @return true or false depending on the above mentioned checks
|
||||
*/
|
||||
@Override
|
||||
public final boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof PlaceholderExpansion)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PlaceholderExpansion expansion = (PlaceholderExpansion) o;
|
||||
|
||||
return getIdentifier().equals(expansion.getIdentifier()) &&
|
||||
getAuthor().equals(expansion.getAuthor()) &&
|
||||
getVersion().equals(expansion.getVersion());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a String containing the Expansion's name, author and version
|
||||
*
|
||||
* @return String containing name, author and version of the expansion
|
||||
*/
|
||||
@Override
|
||||
public final String toString() {
|
||||
return String.format("PlaceholderExpansion[name: '%s', author: '%s', version: '%s', type: '%s']", getName(),
|
||||
getAuthor(), getVersion(), getExpansionType());
|
||||
}
|
||||
|
||||
// === Deprecated API ===
|
||||
|
||||
/**
|
||||
* @deprecated As of versions greater than 2.8.7, use {@link #getRequiredPlugin()}
|
||||
*
|
||||
* @return The plugin name.
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
public String getPlugin() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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")
|
||||
public String getDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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")
|
||||
public String getLink() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
|
||||
/**
|
||||
* An expansion provided by a plugin is considered internal
|
||||
*/
|
||||
INTERNAL,
|
||||
|
||||
/**
|
||||
* An expansion loaded from the expansions folder is considered external
|
||||
*/
|
||||
EXTERNAL
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -8,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,
|
||||
@@ -34,7 +26,7 @@ public final class ExactReplacer implements Replacer {
|
||||
}
|
||||
|
||||
if (expansion == null) {
|
||||
return start + text + end;
|
||||
return text;
|
||||
}
|
||||
|
||||
final String params;
|
||||
@@ -48,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;
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* 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
|
||||
* 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.updatechecker;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||
import me.clip.placeholderapi.util.Msg;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
public class UpdateChecker implements Listener {
|
||||
|
||||
private static final int RESOURCE_ID = 6245;
|
||||
private final PlaceholderAPIPlugin plugin;
|
||||
private final TaskScheduler scheduler;
|
||||
private final String pluginVersion;
|
||||
private String spigotVersion;
|
||||
private boolean updateAvailable;
|
||||
|
||||
public UpdateChecker(PlaceholderAPIPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
scheduler = plugin.getScheduler();
|
||||
pluginVersion = plugin.getDescription().getVersion();
|
||||
}
|
||||
|
||||
public boolean hasUpdateAvailable() {
|
||||
return updateAvailable;
|
||||
}
|
||||
|
||||
public String getSpigotVersion() {
|
||||
return spigotVersion;
|
||||
}
|
||||
|
||||
public void fetch() {
|
||||
scheduler.runTaskAsynchronously(() -> {
|
||||
try {
|
||||
HttpsURLConnection con = (HttpsURLConnection) new URL(
|
||||
"https://api.spigotmc.org/legacy/update.php?resource=" + RESOURCE_ID).openConnection();
|
||||
con.setRequestMethod("GET");
|
||||
spigotVersion = new BufferedReader(new InputStreamReader(con.getInputStream())).readLine();
|
||||
} catch (Exception ex) {
|
||||
plugin.getLogger().info("Failed to check for updates on spigot.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (spigotVersion == null || spigotVersion.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateAvailable = spigotIsNewer();
|
||||
|
||||
if (!updateAvailable) {
|
||||
return;
|
||||
}
|
||||
|
||||
scheduler.runTask(() -> {
|
||||
plugin.getLogger()
|
||||
.info("An update for PlaceholderAPI (v" + getSpigotVersion() + ") is available at:");
|
||||
plugin.getLogger()
|
||||
.info("https://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID + "/");
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private boolean spigotIsNewer() {
|
||||
if (spigotVersion == null || spigotVersion.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int[] plV = toReadable(pluginVersion);
|
||||
int[] spV = toReadable(spigotVersion);
|
||||
|
||||
if (plV[0] < spV[0]) {
|
||||
return true;
|
||||
} else if ((plV[1] < spV[1])) {
|
||||
return true;
|
||||
} else {
|
||||
return plV[2] < spV[2];
|
||||
}
|
||||
}
|
||||
|
||||
private int[] toReadable(String version) {
|
||||
if (version.contains("-DEV")) {
|
||||
version = version.split("-DEV")[0];
|
||||
}
|
||||
|
||||
return Arrays.stream(version.split("\\.")).mapToInt(Integer::parseInt).toArray();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onJoin(PlayerJoinEvent e) {
|
||||
if (e.getPlayer().hasPermission("placeholderapi.updatenotify")) {
|
||||
Msg.msg(e.getPlayer(),
|
||||
"&bAn update for &fPlaceholder&7API &e(&fPlaceholder&7API &fv" + getSpigotVersion()
|
||||
+ "&e)"
|
||||
, "&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
|
||||
@@ -8,6 +8,8 @@
|
||||
# Discord: https://helpch.at/discord
|
||||
# No placeholders are provided with this plugin by default.
|
||||
# Download placeholders: /papi ecloud
|
||||
#
|
||||
# CHANGE use_regex_component_replacer to true if you notice new minecraft text features not getting their placeholders replaced properly -- may cause performance issues
|
||||
check_updates: true
|
||||
cloud_enabled: true
|
||||
cloud_sorting: "name"
|
||||
@@ -15,5 +17,6 @@ boolean:
|
||||
'true': 'yes'
|
||||
'false': 'no'
|
||||
date_format: MM/dd/yy HH:mm:ss
|
||||
use_regex_component_replacer: false
|
||||
detect_malicious_expansions: true
|
||||
debug: false
|
||||
@@ -12,6 +12,8 @@ commands:
|
||||
placeholderapi:
|
||||
description: "PlaceholderAPI Command"
|
||||
aliases: ["papi"]
|
||||
test:
|
||||
description: "yes"
|
||||
|
||||
permissions:
|
||||
placeholderapi.*:
|
||||
93
src/test/java/me/clip/placeholderapi/Values.java
Normal file
93
src/test/java/me/clip/placeholderapi/Values.java
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PlaceholderAPI is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import me.clip.placeholderapi.replacer.CharsReplacer;
|
||||
import me.clip.placeholderapi.replacer.Replacer;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface Values {
|
||||
|
||||
String SMALL_TEXT = "My name is %player_name%";
|
||||
String LARGE_TEXT = "My name is %player_name% and my location is (%player_x%, %player_y%, %player_z%), this placeholder is invalid %server_name%";
|
||||
|
||||
ImmutableMap<String, PlaceholderExpansion> PLACEHOLDERS = ImmutableMap.<String, PlaceholderExpansion>builder()
|
||||
.put("player", new MockPlayerPlaceholderExpansion())
|
||||
.build();
|
||||
|
||||
|
||||
Replacer CHARS_REPLACER = new CharsReplacer(Replacer.Closure.PERCENT);
|
||||
|
||||
|
||||
final class MockPlayerPlaceholderExpansion extends PlaceholderExpansion {
|
||||
|
||||
public static final String PLAYER_X = "10";
|
||||
public static final String PLAYER_Y = "20";
|
||||
public static final String PLAYER_Z = "30";
|
||||
public static final String PLAYER_NAME = "Sxtanna";
|
||||
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "player";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getAuthor() {
|
||||
return "Sxtanna";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return "1.0";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onRequest(@Nullable final OfflinePlayer player, @NotNull final String params) {
|
||||
final String[] parts = params.split("_");
|
||||
if (parts.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (parts[0]) {
|
||||
case "name":
|
||||
return PLAYER_NAME;
|
||||
case "x":
|
||||
return PLAYER_X;
|
||||
case "y":
|
||||
return PLAYER_Y;
|
||||
case "z":
|
||||
return PLAYER_Z;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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