mirror of
https://github.com/PlaceholderAPI/PlaceholderAPI
synced 2026-02-08 00:42:47 +01:00
Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9022daf07f | ||
|
|
675b305cac | ||
|
|
d49c76c560 | ||
|
|
13e492cf44 | ||
|
|
d561afbb63 | ||
|
|
2a3f4482a0 | ||
|
|
4ee2840a0a | ||
|
|
c52d117f12 | ||
|
|
e307aba414 | ||
|
|
5ea5a18fe8 | ||
|
|
9c1db4b48a | ||
|
|
b233c92ca1 | ||
|
|
1b1d2e61b9 | ||
|
|
2dc5b93133 | ||
|
|
880ddc22b5 | ||
|
|
d378f782b4 | ||
|
|
1f2d969a69 | ||
|
|
cac79a26af | ||
|
|
8b078f9058 | ||
|
|
d3a5d01f55 | ||
|
|
9a677d46a1 | ||
|
|
8116cbb385 | ||
|
|
b9affd0879 | ||
|
|
ec8657015c | ||
|
|
38a86e6d2d | ||
|
|
35376e43ca | ||
|
|
1c233ec297 | ||
|
|
967dec09ff | ||
|
|
85aa6ae8ae | ||
|
|
83aad38b09 | ||
|
|
b0fb784079 | ||
|
|
84948101f4 | ||
|
|
5dea70532c | ||
|
|
403adeb217 | ||
|
|
a81ed63c0f | ||
|
|
38da700168 | ||
|
|
4a085682dc | ||
|
|
cfed3ce31b | ||
|
|
4c62318338 | ||
|
|
7247cbb9f7 | ||
|
|
9ed7a7ae56 | ||
|
|
9a356ceecf | ||
|
|
e0ac7b1c66 | ||
|
|
82230d8156 | ||
|
|
cda55f20aa | ||
|
|
0df7a01fd8 | ||
|
|
b49668ddee | ||
|
|
f14b081f0b | ||
|
|
b51fbf4e13 | ||
|
|
e48b6fe702 | ||
|
|
984f944daf |
2
.github/CONTRIBUTING.md
vendored
2
.github/CONTRIBUTING.md
vendored
@@ -38,7 +38,7 @@ PlaceholderAPI provides a feature to have expansions (separate jar files) for pl
|
||||
In those cases should you report the issue to the issue tracker of the expansion or plugin.
|
||||
|
||||
## Pull requests
|
||||
As an open source project are we welcoming all contributions to improve PlaceholderAPI, being it changes to its code, or contributions to its documentation such as the [Wiki] or the Javadocs.
|
||||
As an open source project we are welcoming all contributions to improve PlaceholderAPI, being it changes to its code, or contributions to its documentation such as the [Wiki] or the Javadocs.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> When contributing, make sure to both base of and target the mentioned branch. Pull requests targeting the wrong branch may get closed without a warning.
|
||||
|
||||
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -21,7 +21,7 @@
|
||||
### Description
|
||||
<!-- What does your Pull request change? -->
|
||||
|
||||
Closes N/A <!-- If your PR is based on an issue, change "N/A" the the issue ID (#id) -->
|
||||
Closes N/A <!-- If your PR is based on an issue, change "N/A" to the issue ID (#id) -->
|
||||
|
||||
|
||||
<!-- DO NOT ALTER ANYTHING BELOW THIS LINE! -->
|
||||
|
||||
6
.github/workflows/pr_build_jars.yml
vendored
6
.github/workflows/pr_build_jars.yml
vendored
@@ -5,8 +5,10 @@ on:
|
||||
branches:
|
||||
- development
|
||||
paths:
|
||||
- "src/**"
|
||||
- "build.gradle"
|
||||
- "../../spigot/**"
|
||||
- "../../paper/**"
|
||||
- "build.gradle.kts"
|
||||
- "settings.gradle.kts"
|
||||
|
||||
jobs:
|
||||
testBuilds:
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
[discord]: https://helpch.at/discord
|
||||
[spigot]: https://www.spigotmc.org/resources/6245/
|
||||
[hangar]: https://hangar.papermc.io/HelpChat/PlaceholderAPI
|
||||
[bbb]: https://builtbybit.com/resources/placeholderapi.24306
|
||||
[Expansions cloud]: https://api.extendedclip.com/home
|
||||
[modrinth]: https://modrinth.com/plugin/placeholderapi
|
||||
[Expansions cloud]: https://ecloud.placeholderapi.com
|
||||
[placeholder list]: https://helpch.at/placeholders
|
||||
[statistics]: https://bstats.org/plugin/bukkit/PlaceholderAPI
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
Support for specific plugins are provided either by the plugin itself or through expansions. The expansions may be downloaded in-game through the PAPI Expansion Cloud. There are currently over 240+ expansions that support a wide variety of plugins, such as Essentials, Factions, LuckPerms, and Vault.
|
||||
|
||||
PlaceholderAPI has been downloaded over 1,700,000 times on Spigot and has been used concurrently on over 45,000 servers, which makes it a must-have for a server of any type or scale.
|
||||
PlaceholderAPI has been downloaded over 2,000,000 times on Spigot and has been used concurrently on over 50,000 servers, which makes it a must-have for a server of any type or scale.
|
||||
|
||||
## Contribute
|
||||
If you would like to contribute towards PlaceholderAPI should you take a look at our [Contributing file][contributing] for the ins and outs on how you can do that and what you need to keep in mind.
|
||||
@@ -50,5 +50,5 @@ If you would like to create your own Placeholder Expansion for PlaceholderAPI, t
|
||||
- [Placeholder List]
|
||||
- [Spigot Page][spigot]
|
||||
- [Hangar Page][hangar]
|
||||
- [BuiltByBit Page][bbb]
|
||||
- [Modrinth Page][modrinth]
|
||||
- [Plugin Statistics][statistics]
|
||||
|
||||
104
build.gradle.kts
104
build.gradle.kts
@@ -3,15 +3,23 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
plugins {
|
||||
`java-library`
|
||||
`maven-publish`
|
||||
id("com.github.hierynomus.license") version "0.16.1"
|
||||
// id("com.github.hierynomus.license") version "0.16.1"
|
||||
id("io.github.goooler.shadow") version "8.1.7"
|
||||
}
|
||||
|
||||
group = "me.clip"
|
||||
version = "2.11.7-DEV-${System.getProperty("BUILD_NUMBER")}"
|
||||
version = "2.12.2-DEV-${System.getProperty("BUILD_NUMBER")}"
|
||||
|
||||
description = "An awesome placeholder provider!"
|
||||
|
||||
val paper by sourceSets.creating {
|
||||
java.srcDir("src/paper/java")
|
||||
|
||||
// paper can see main code
|
||||
compileClasspath += sourceSets.main.get().output
|
||||
runtimeClasspath += output + compileClasspath
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven("https://oss.sonatype.org/content/repositories/snapshots/")
|
||||
|
||||
@@ -24,16 +32,17 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("org.bstats:bstats-bukkit:3.0.1")
|
||||
implementation("net.kyori:adventure-platform-bukkit:4.3.3")
|
||||
implementation("org.bstats:bstats-bukkit:3.1.0")
|
||||
implementation("net.kyori:adventure-platform-bukkit:4.4.1")
|
||||
|
||||
//compileOnly("org.spigotmc:spigot-api:1.21-R0.1-SNAPSHOT")
|
||||
compileOnly("dev.folia:folia-api:1.20.1-R0.1-SNAPSHOT")
|
||||
add(paper.compileOnlyConfigurationName, "net.kyori:adventure-platform-bukkit:4.4.1")
|
||||
add(paper.compileOnlyConfigurationName, "dev.folia:folia-api:1.21.11-R0.1-SNAPSHOT")
|
||||
|
||||
compileOnly("dev.folia:folia-api:1.21.11-R0.1-SNAPSHOT")
|
||||
compileOnlyApi("org.jetbrains:annotations:23.0.0")
|
||||
|
||||
testImplementation("org.openjdk.jmh:jmh-core:1.32")
|
||||
testImplementation("org.openjdk.jmh:jmh-generator-annprocess:1.32")
|
||||
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.8.2")
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1")
|
||||
}
|
||||
@@ -45,19 +54,8 @@ java {
|
||||
|
||||
withJavadocJar()
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
license {
|
||||
header = rootProject.file("config/headers/main.txt")
|
||||
|
||||
include("**/*.java")
|
||||
mapping("java", "JAVADOC_STYLE")
|
||||
|
||||
encoding = "UTF-8"
|
||||
|
||||
ext {
|
||||
set("year", 2024)
|
||||
}
|
||||
disableAutoTargetJvm()
|
||||
}
|
||||
|
||||
val javaComponent: SoftwareComponent = components["java"]
|
||||
@@ -71,14 +69,36 @@ tasks {
|
||||
dependsOn(named("shadowJar"))
|
||||
}
|
||||
|
||||
withType<JavaCompile> {
|
||||
register<JavaCompile>("compilePaper") {
|
||||
source = paper.java
|
||||
classpath = paper.compileClasspath
|
||||
destinationDirectory.set(layout.buildDirectory.dir("classes/java/paper"))
|
||||
options.encoding = "UTF-8"
|
||||
options.release = 8
|
||||
}
|
||||
|
||||
withType<Javadoc> {
|
||||
val plainJar by registering(Jar::class) {
|
||||
dependsOn("compilePaper")
|
||||
|
||||
archiveClassifier.set("plain")
|
||||
from(sourceSets.main.get().output)
|
||||
from(paper.output)
|
||||
}
|
||||
|
||||
val combinedSourcesJar by registering(Jar::class) {
|
||||
archiveClassifier.set("sources")
|
||||
from(sourceSets.main.get().allSource)
|
||||
from(paper.allSource)
|
||||
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
}
|
||||
|
||||
val combinedJavadoc by registering(Javadoc::class) {
|
||||
isFailOnError = false
|
||||
|
||||
source = sourceSets.main.get().allJava + paper.allJava
|
||||
classpath = sourceSets.main.get().compileClasspath + paper.compileClasspath
|
||||
|
||||
with(options as StandardJavadocDocletOptions) {
|
||||
addStringOption("Xdoclint:none", "-quiet")
|
||||
addStringOption("encoding", "UTF-8")
|
||||
@@ -86,13 +106,41 @@ tasks {
|
||||
}
|
||||
}
|
||||
|
||||
val combinedJavadocJar by registering(Jar::class) {
|
||||
archiveClassifier.set("javadoc")
|
||||
dependsOn(combinedJavadoc)
|
||||
from(combinedJavadoc.get().destinationDir)
|
||||
}
|
||||
|
||||
withType<JavaCompile> {
|
||||
options.encoding = "UTF-8"
|
||||
options.release = 8
|
||||
}
|
||||
|
||||
withType<ShadowJar> {
|
||||
configurations = listOf(project.configurations.runtimeClasspath.get())
|
||||
|
||||
from(sourceSets.main.get().output)
|
||||
|
||||
archiveClassifier.set("")
|
||||
|
||||
relocate("org.bstats", "me.clip.placeholderapi.metrics")
|
||||
relocate("net.kyori", "me.clip.placeholderapi.libs.kyori")
|
||||
|
||||
exclude("META-INF/versions/**")
|
||||
|
||||
dependsOn("compilePaper")
|
||||
|
||||
doLast {
|
||||
val paperDir = layout.buildDirectory.dir("classes/java/paper").get().asFile
|
||||
val jarFile = archiveFile.get().asFile
|
||||
|
||||
ant.invokeMethod("zip", mapOf(
|
||||
"destfile" to jarFile,
|
||||
"update" to "true",
|
||||
"basedir" to paperDir
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
test {
|
||||
@@ -103,7 +151,19 @@ tasks {
|
||||
publications {
|
||||
create<MavenPublication>("maven") {
|
||||
artifactId = "placeholderapi"
|
||||
from(javaComponent)
|
||||
|
||||
artifact(plainJar) {
|
||||
builtBy(plainJar)
|
||||
classifier = ""
|
||||
}
|
||||
|
||||
artifact(combinedSourcesJar) {
|
||||
builtBy(combinedSourcesJar)
|
||||
}
|
||||
|
||||
artifact(combinedJavadocJar) {
|
||||
builtBy(combinedJavadocJar)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2018-2024 Peter Blood
|
||||
Copyright (c) 2018-2026 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:
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -21,6 +21,7 @@
|
||||
package me.clip.placeholderapi;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -28,6 +29,7 @@ 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;
|
||||
@@ -46,9 +48,9 @@ public final class PlaceholderAPI {
|
||||
private static final Replacer REPLACER_PERCENT = new CharsReplacer(Closure.PERCENT);
|
||||
private static final Replacer REPLACER_BRACKET = new CharsReplacer(Closure.BRACKET);
|
||||
|
||||
private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("[%]([^%]+)[%]");
|
||||
private static final Pattern BRACKET_PLACEHOLDER_PATTERN = Pattern.compile("[{]([^{}]+)[}]");
|
||||
private static final Pattern RELATIONAL_PLACEHOLDER_PATTERN = Pattern
|
||||
static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("[%]([^%]+)[%]");
|
||||
static final Pattern BRACKET_PLACEHOLDER_PATTERN = Pattern.compile("[{]([^{}]+)[}]");
|
||||
static final Pattern RELATIONAL_PLACEHOLDER_PATTERN = Pattern
|
||||
.compile("[%](rel_)([^%]+)[%]");
|
||||
|
||||
|
||||
@@ -296,24 +298,21 @@ 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
|
||||
*
|
||||
* @deprecated Use {@link LocalExpansionManager#getExpansions()} instead.
|
||||
*
|
||||
* @return Map of registered placeholders
|
||||
* @deprecated Use {@link LocalExpansionManager#getExpansions()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -324,12 +323,11 @@ 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")
|
||||
@@ -341,12 +339,11 @@ 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")
|
||||
@@ -358,11 +355,10 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Please use {@link PlaceholderExpansion} to
|
||||
* unregister placeholders instead
|
||||
*
|
||||
* @param plugin The plugin to unregister
|
||||
* @return always false
|
||||
* @deprecated Please use {@link PlaceholderExpansion} to
|
||||
* unregister placeholders instead
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -374,11 +370,10 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Please use {@link PlaceholderExpansion} to
|
||||
* unregister placeholders instead
|
||||
*
|
||||
* @param identifier The identifier to unregister
|
||||
* @return always false
|
||||
* @deprecated Please use {@link PlaceholderExpansion} to
|
||||
* unregister placeholders instead
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -390,9 +385,8 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Will be removed in a future release.
|
||||
*
|
||||
* @return Set of registered identifiers
|
||||
* @deprecated Will be removed in a future release.
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -401,9 +395,8 @@ public final class PlaceholderAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Will be removed in a future release.
|
||||
*
|
||||
* @return always null
|
||||
* @deprecated Will be removed in a future release.
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -412,13 +405,12 @@ 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")
|
||||
@@ -428,13 +420,12 @@ 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")
|
||||
@@ -444,12 +435,11 @@ 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")
|
||||
@@ -459,12 +449,11 @@ 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")
|
||||
@@ -472,13 +461,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")
|
||||
@@ -487,12 +476,11 @@ 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")
|
||||
@@ -501,12 +489,11 @@ 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")
|
||||
@@ -515,12 +502,11 @@ 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")
|
||||
@@ -529,12 +515,11 @@ 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")
|
||||
@@ -544,12 +529,11 @@ 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")
|
||||
@@ -558,12 +542,11 @@ 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")
|
||||
@@ -572,12 +555,11 @@ 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 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -21,9 +21,9 @@
|
||||
package me.clip.placeholderapi;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommandRouter;
|
||||
import me.clip.placeholderapi.configuration.PlaceholderAPIConfig;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
@@ -34,6 +34,7 @@ import me.clip.placeholderapi.listeners.ServerLoadEventListener;
|
||||
import me.clip.placeholderapi.scheduler.UniversalScheduler;
|
||||
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||
import me.clip.placeholderapi.updatechecker.UpdateChecker;
|
||||
import me.clip.placeholderapi.util.ExpansionSafetyCheck;
|
||||
import me.clip.placeholderapi.util.Msg;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
@@ -43,6 +44,7 @@ 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;
|
||||
|
||||
@@ -92,6 +94,7 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
private final TaskScheduler scheduler = UniversalScheduler.getScheduler(this);
|
||||
|
||||
private BukkitAudiences adventure;
|
||||
private boolean safetyCheck = false;
|
||||
|
||||
|
||||
/**
|
||||
@@ -150,13 +153,23 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
instance = this;
|
||||
|
||||
saveDefaultConfig();
|
||||
|
||||
safetyCheck = new ExpansionSafetyCheck(this).runChecks();
|
||||
|
||||
if (safetyCheck) {
|
||||
return;
|
||||
}
|
||||
|
||||
instance = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
if (safetyCheck) {
|
||||
return;
|
||||
}
|
||||
|
||||
setupCommand();
|
||||
setupMetrics();
|
||||
setupExpansions();
|
||||
@@ -174,6 +187,10 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
if (safetyCheck) {
|
||||
return;
|
||||
}
|
||||
|
||||
getCloudExpansionManager().kill();
|
||||
getLocalExpansionManager().kill();
|
||||
|
||||
@@ -213,7 +230,7 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
|
||||
@NotNull
|
||||
public BukkitAudiences getAdventure() {
|
||||
if(adventure == null) {
|
||||
if (adventure == null) {
|
||||
throw new IllegalStateException("Tried to access Adventure when the plugin was disabled!");
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -22,10 +22,12 @@ package me.clip.placeholderapi.commands;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -22,6 +22,7 @@ package me.clip.placeholderapi.commands;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -30,6 +31,8 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.impl.cloud.CommandECloud;
|
||||
import me.clip.placeholderapi.commands.impl.local.CommandDump;
|
||||
@@ -117,14 +120,18 @@ public final class PlaceholderCommandRouter implements CommandExecutor, TabCompl
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull final CommandSender sender,
|
||||
@NotNull final Command command, @NotNull final String alias, @NotNull final String[] args) {
|
||||
public List<String> onTabComplete(@NotNull final CommandSender sender, @NotNull final Command command,
|
||||
@NotNull final String alias, @NotNull final String[] args) {
|
||||
final List<String> suggestions = new ArrayList<>();
|
||||
|
||||
if (args.length > 1) {
|
||||
final PlaceholderCommand target = this.commands.get(args[0].toLowerCase(Locale.ROOT));
|
||||
|
||||
if (target != null) {
|
||||
if (target.getPermission() != null && !target.getPermission().isEmpty() && !sender.hasPermission(target.getPermission())) {
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
target.complete(plugin, sender, args[0].toLowerCase(Locale.ROOT),
|
||||
Arrays.asList(Arrays.copyOfRange(args, 1, args.length)), suggestions);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -118,6 +118,11 @@ public final class CommandECloud extends PlaceholderCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!target.getLabel().equalsIgnoreCase("refresh") && plugin.getCloudExpansionManager().isEmpty()) {
|
||||
Msg.msg(sender, "&cThere is no available data from the eCloud. Please try running &f/papi ecloud refresh&c. If this does not resolve the issue, the eCloud may be blocked by your firewall, server host, or service provider.\n&r\n&cMore information: &fhttps://placeholderapi.com/ecloud-blocked");
|
||||
return;
|
||||
}
|
||||
|
||||
target.evaluate(plugin, sender, search, params.subList(1, params.size()));
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -21,6 +21,7 @@
|
||||
package me.clip.placeholderapi.commands.impl.cloud;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.util.Msg;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -24,6 +24,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
||||
@@ -72,11 +73,6 @@ public final class CommandECloudDownload extends PlaceholderCommand {
|
||||
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());
|
||||
@@ -95,6 +91,11 @@ public final class CommandECloudDownload extends PlaceholderCommand {
|
||||
}
|
||||
}
|
||||
|
||||
if (!version.isVerified()) {
|
||||
Msg.msg(sender, "&cThe expansion '&f" + params.get(0) + "&c' is not verified and can only be downloaded manually from &fhttps://ecloud.placeholderapi.com");
|
||||
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 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -23,6 +23,7 @@ package me.clip.placeholderapi.commands.impl.cloud;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
||||
@@ -63,9 +64,6 @@ public final class CommandECloudExpansionInfo extends PlaceholderCommand {
|
||||
.append('\n')
|
||||
.append("&bAuthor: &f")
|
||||
.append(expansion.getAuthor())
|
||||
.append('\n')
|
||||
.append("&bVerified: ")
|
||||
.append(expansion.isVerified() ? "&a&l✔" : "&c&l❌")
|
||||
.append('\n');
|
||||
|
||||
if (params.size() < 2) {
|
||||
@@ -76,6 +74,9 @@ public final class CommandECloudExpansionInfo extends PlaceholderCommand {
|
||||
.append(expansion.getTimeSinceLastUpdate())
|
||||
.append(" ago")
|
||||
.append('\n')
|
||||
.append("&bVerified: ")
|
||||
.append(expansion.getVersion().isVerified() ? "&a&l✔" : "&c&l❌")
|
||||
.append('\n')
|
||||
.append("&bRelease Notes: &f")
|
||||
.append(expansion.getVersion().getReleaseNotes())
|
||||
.append('\n');
|
||||
@@ -91,6 +92,9 @@ public final class CommandECloudExpansionInfo extends PlaceholderCommand {
|
||||
builder.append("&bVersion: &f")
|
||||
.append(version.getVersion())
|
||||
.append('\n')
|
||||
.append("&bVerified: ")
|
||||
.append(version.isVerified() ? "&a&l✔" : "&c&l❌")
|
||||
.append('\n')
|
||||
.append("&bRelease Notes: &f")
|
||||
.append(version.getReleaseNotes())
|
||||
.append('\n')
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -25,12 +25,14 @@ import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.primitives.Ints;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.configuration.ExpansionSort;
|
||||
@@ -65,7 +67,7 @@ public final class CommandECloudExpansionList extends PlaceholderCommand {
|
||||
expansion -> "&f" + expansion.getAuthor();
|
||||
@NotNull
|
||||
private static final Function<CloudExpansion, Object> EXPANSION_VERIFIED =
|
||||
expansion -> expansion.isVerified() ? "&aY" : "&cN";
|
||||
expansion -> expansion.getVersion().isVerified() ? "&aY" : "&cN";
|
||||
@NotNull
|
||||
private static final Function<CloudExpansion, Object> EXPANSION_LATEST_VERSION =
|
||||
expansion -> "&f" + expansion.getLatestVersion();
|
||||
@@ -168,7 +170,9 @@ 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.isVerified() ? "✔" : "❌", expansion.isVerified() ? GREEN : RED, TextDecoration.BOLD))
|
||||
.append(text("Version: ", AQUA)).append(text(expansion.getVersion().getVersion(), 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();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -21,9 +21,11 @@
|
||||
package me.clip.placeholderapi.commands.impl.cloud;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -21,6 +21,7 @@
|
||||
package me.clip.placeholderapi.commands.impl.cloud;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.util.Msg;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -21,6 +21,7 @@
|
||||
package me.clip.placeholderapi.commands.impl.cloud;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.expansion.manager.CloudExpansionManager;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -21,6 +21,7 @@
|
||||
package me.clip.placeholderapi.commands.impl.cloud;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -28,6 +29,7 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -25,6 +25,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -22,6 +22,7 @@ package me.clip.placeholderapi.commands.impl.local;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -21,6 +21,7 @@
|
||||
package me.clip.placeholderapi.commands.impl.local;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.util.Msg;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -21,6 +21,7 @@
|
||||
package me.clip.placeholderapi.commands.impl.local;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -21,9 +21,11 @@
|
||||
package me.clip.placeholderapi.commands.impl.local;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -25,6 +25,7 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -21,8 +21,10 @@
|
||||
package me.clip.placeholderapi.commands.impl.local;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.util.ExpansionSafetyCheck;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
@@ -37,7 +39,9 @@ public final class CommandReload extends PlaceholderCommand {
|
||||
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
|
||||
@NotNull final CommandSender sender, @NotNull final String alias,
|
||||
@NotNull @Unmodifiable final List<String> params) {
|
||||
if (!new ExpansionSafetyCheck(plugin).runChecks()) {
|
||||
plugin.reloadConf(sender);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -21,6 +21,7 @@
|
||||
package me.clip.placeholderapi.commands.impl.local;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||
import me.clip.placeholderapi.util.Msg;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -21,6 +21,7 @@
|
||||
package me.clip.placeholderapi.configuration;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -21,6 +21,7 @@
|
||||
package me.clip.placeholderapi.configuration;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -53,6 +54,10 @@ public final class PlaceholderAPIConfig {
|
||||
return plugin.getConfig().getBoolean("debug", false);
|
||||
}
|
||||
|
||||
public boolean useAdventureReplacer() {
|
||||
return plugin.getConfig().getBoolean("use_adventure_provided_replacer", false);
|
||||
}
|
||||
|
||||
|
||||
public Optional<ExpansionSort> getExpansionSort() {
|
||||
final String option = plugin.getConfig()
|
||||
@@ -86,4 +91,11 @@ public final class PlaceholderAPIConfig {
|
||||
return plugin.getConfig().getString("boolean.false", "false");
|
||||
}
|
||||
|
||||
public boolean useAdventureProvidedReplacer() {
|
||||
return plugin.getConfig().getBoolean("use_adventure_provided_replacer", false);
|
||||
}
|
||||
|
||||
public boolean detectMaliciousExpansions() {
|
||||
return plugin.getConfig().getBoolean("detect_malicious_expansions", true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -23,6 +23,7 @@ package me.clip.placeholderapi.events;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
@@ -53,7 +54,7 @@ public class ExpansionsLoadedEvent extends Event {
|
||||
* @return List of {@link PlaceholderExpansion registered PlaceholderExpansions}.
|
||||
*/
|
||||
@NotNull
|
||||
public final List<PlaceholderExpansion> getExpansions(){
|
||||
public final List<PlaceholderExpansion> getExpansions() {
|
||||
return expansions;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -51,7 +51,12 @@ public enum NMSVersion {
|
||||
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_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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -23,6 +23,7 @@ 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;
|
||||
@@ -43,6 +44,7 @@ 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
|
||||
@@ -180,6 +182,7 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
|
||||
|
||||
/**
|
||||
* Set the type of the expansion
|
||||
*
|
||||
* @param expansionType the new type
|
||||
* @since 2.11.4
|
||||
*/
|
||||
@@ -430,9 +433,8 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
|
||||
// === Deprecated API ===
|
||||
|
||||
/**
|
||||
* @deprecated As of versions greater than 2.8.7, use {@link #getRequiredPlugin()}
|
||||
*
|
||||
* @return The plugin name.
|
||||
* @deprecated As of versions greater than 2.8.7, use {@link #getRequiredPlugin()}
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||
@@ -441,9 +443,8 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated As of versions greater than 2.8.7, use the expansion cloud to show a description
|
||||
*
|
||||
* @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")
|
||||
@@ -452,9 +453,8 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated As of versions greater than 2.8.7, use the expansion cloud to display a link
|
||||
*
|
||||
* @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")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -27,7 +27,6 @@ package me.clip.placeholderapi.expansion;
|
||||
* with that version.
|
||||
*
|
||||
* @author Ryan McCarthy
|
||||
*
|
||||
* @deprecated Will be removed in a future release.
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -38,7 +37,6 @@ 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 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -23,6 +23,7 @@ package me.clip.placeholderapi.expansion.cloud;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.clip.placeholderapi.util.TimeUtil;
|
||||
|
||||
|
||||
@@ -36,8 +37,7 @@ public class CloudExpansion {
|
||||
dependency_url;
|
||||
|
||||
private boolean hasExpansion,
|
||||
shouldUpdate,
|
||||
verified;
|
||||
shouldUpdate;
|
||||
|
||||
private long last_update,
|
||||
ratings_count;
|
||||
@@ -135,10 +135,6 @@ public class CloudExpansion {
|
||||
this.shouldUpdate = shouldUpdate;
|
||||
}
|
||||
|
||||
public boolean isVerified() {
|
||||
return verified;
|
||||
}
|
||||
|
||||
public long getLastUpdate() {
|
||||
return last_update;
|
||||
}
|
||||
@@ -174,6 +170,7 @@ public class CloudExpansion {
|
||||
public static class Version {
|
||||
|
||||
private String url, version, release_notes;
|
||||
private boolean verified;
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
@@ -198,5 +195,13 @@ public class CloudExpansion {
|
||||
public void setReleaseNotes(String release_notes) {
|
||||
this.release_notes = release_notes;
|
||||
}
|
||||
|
||||
public boolean isVerified() {
|
||||
return verified;
|
||||
}
|
||||
|
||||
public void setVerified(boolean verified) {
|
||||
this.verified = verified;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -25,11 +25,13 @@ import com.google.common.io.Resources;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@@ -50,6 +52,7 @@ import java.util.function.Function;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
||||
@@ -60,7 +63,7 @@ import org.jetbrains.annotations.Unmodifiable;
|
||||
public final class CloudExpansionManager {
|
||||
|
||||
@NotNull
|
||||
private static final String API_URL = "http://api.extendedclip.com/v2/";
|
||||
private static final String API_URL = "https://ecloud.placeholderapi.com/api/v3/?platform=bukkit";
|
||||
|
||||
@NotNull
|
||||
private static final Gson GSON = new Gson();
|
||||
@@ -113,6 +116,10 @@ public final class CloudExpansionManager {
|
||||
return ImmutableMap.copyOf(cache);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return cache.isEmpty();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Unmodifiable
|
||||
public Map<String, CloudExpansion> getCloudExpansionsInstalled() {
|
||||
@@ -195,6 +202,8 @@ public final class CloudExpansionManager {
|
||||
for (String name : toRemove) {
|
||||
values.remove(name);
|
||||
}
|
||||
} catch (UnknownHostException e) {
|
||||
plugin.getLogger().log(Level.WARNING, "There is no data available from the eCloud. Please try running /papi refresh. If this does not resolve the issue, the eCloud may be blocked by your firewall, server host, or service provider.\n\nMore information: https://placeholderapi.com/ecloud-blocked", e);
|
||||
} catch (Throwable e) {
|
||||
// ugly swallowing of every throwable, but we have to be defensive
|
||||
plugin.getLogger().log(Level.WARNING, "Failed to download expansion information", e);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -22,6 +22,7 @@ package me.clip.placeholderapi.expansion.manager;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
@@ -38,6 +39,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.events.ExpansionRegisterEvent;
|
||||
import me.clip.placeholderapi.events.ExpansionUnregisterEvent;
|
||||
@@ -172,7 +174,7 @@ public final class LocalExpansionManager implements Listener {
|
||||
try {
|
||||
final PlaceholderExpansion expansion = createExpansionInstance(clazz);
|
||||
|
||||
if(expansion == null){
|
||||
if (expansion == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@@ -213,6 +215,7 @@ public final class LocalExpansionManager implements Listener {
|
||||
|
||||
/**
|
||||
* Attempt to register a {@link PlaceholderExpansion}
|
||||
*
|
||||
* @param expansion the expansion to register
|
||||
* @return if the expansion was registered
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -22,6 +22,7 @@ package me.clip.placeholderapi.replacer;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.function.Function;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -21,6 +21,7 @@
|
||||
package me.clip.placeholderapi.replacer;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -27,7 +27,9 @@ 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;
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ public interface TaskScheduler {
|
||||
|
||||
/**
|
||||
* <b>Folia</b>: Returns whether the current thread is ticking the global region <br>
|
||||
* <b>Paper & Bukkit</b>: Returns {@link org.bukkit.Server#isPrimaryThread}
|
||||
* <b>Paper and Bukkit</b>: Returns {@link org.bukkit.Server#isPrimaryThread}
|
||||
*/
|
||||
boolean isGlobalThread();
|
||||
|
||||
@@ -49,7 +49,7 @@ public interface TaskScheduler {
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Returns whether the current thread is ticking a region and that the region
|
||||
* <b>Folia and Paper</b>: Returns whether the current thread is ticking a region and that the region
|
||||
* being ticked owns the specified entity. Note that this function is the only appropriate method of
|
||||
* checking for ownership of an entity, as retrieving the entity's location is undefined unless the
|
||||
* entity is owned by the current region
|
||||
@@ -61,7 +61,7 @@ public interface TaskScheduler {
|
||||
boolean isEntityThread(Entity entity);
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Returns whether the current thread is ticking a region and that the region
|
||||
* <b>Folia and Paper</b>: Returns whether the current thread is ticking a region and that the region
|
||||
* being ticked owns the chunk at the specified world and block position as included in the specified location
|
||||
* <p>
|
||||
* <b>Bukkit</b>: returns {@link org.bukkit.Server#isPrimaryThread}
|
||||
@@ -72,7 +72,7 @@ public interface TaskScheduler {
|
||||
|
||||
/**
|
||||
* Schedules a task to be executed on the next tick <br>
|
||||
* <b>Folia & Paper</b>: ...on the global region <br>
|
||||
* <b>Folia and Paper</b>: ...on the global region <br>
|
||||
* <b>Bukkit</b>: ...on the main thread
|
||||
*
|
||||
* @param runnable The task to execute
|
||||
@@ -81,7 +81,7 @@ public interface TaskScheduler {
|
||||
|
||||
/**
|
||||
* Schedules a task to be executed after the specified delay in ticks <br>
|
||||
* <b>Folia & Paper</b>: ...on the global region <br>
|
||||
* <b>Folia and Paper</b>: ...on the global region <br>
|
||||
* <b>Bukkit</b>: ...on the main thread
|
||||
*
|
||||
* @param runnable The task to execute
|
||||
@@ -91,7 +91,7 @@ public interface TaskScheduler {
|
||||
|
||||
/**
|
||||
* Schedules a repeating task to be executed after the initial delay with the specified period <br>
|
||||
* <b>Folia & Paper</b>: ...on the global region <br>
|
||||
* <b>Folia and Paper</b>: ...on the global region <br>
|
||||
* <b>Bukkit</b>: ...on the main thread
|
||||
*
|
||||
* @param runnable The task to execute
|
||||
@@ -125,7 +125,7 @@ public interface TaskScheduler {
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Schedules a task to be executed on the region which owns the location on the next tick
|
||||
* <b>Folia and Paper</b>: Schedules a task to be executed on the region which owns the location on the next tick
|
||||
* <p>
|
||||
* <b>Bukkit</b>: same as {@link #runTask(Runnable)}
|
||||
*
|
||||
@@ -137,7 +137,7 @@ public interface TaskScheduler {
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Schedules a task to be executed on the region which owns the location after the
|
||||
* <b>Folia and Paper</b>: Schedules a task to be executed on the region which owns the location after the
|
||||
* specified delay in ticks
|
||||
* <p>
|
||||
* <b>Bukkit</b>: same as {@link #runTaskLater(Runnable, long)}
|
||||
@@ -151,7 +151,7 @@ public interface TaskScheduler {
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Schedules a repeating task to be executed on the region which owns the location
|
||||
* <b>Folia and Paper</b>: Schedules a repeating task to be executed on the region which owns the location
|
||||
* after the initial delay with the specified period
|
||||
* <p>
|
||||
* <b>Bukkit</b>: same as {@link #runTaskTimer(Runnable, long, long)}
|
||||
@@ -190,7 +190,7 @@ public interface TaskScheduler {
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Schedules a task to be executed on the region which owns the location
|
||||
* <b>Folia and Paper</b>: Schedules a task to be executed on the region which owns the location
|
||||
* of given entity on the next tick
|
||||
* <p>
|
||||
* <b>Bukkit</b>: same as {@link #runTask(Runnable)}
|
||||
@@ -203,7 +203,7 @@ public interface TaskScheduler {
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Schedules a task to be executed on the region which owns the location
|
||||
* <b>Folia and Paper</b>: Schedules a task to be executed on the region which owns the location
|
||||
* of given entity after the specified delay in ticks
|
||||
* <p>
|
||||
* <b>Bukkit</b>: same as {@link #runTaskLater(Runnable, long)}
|
||||
@@ -217,7 +217,7 @@ public interface TaskScheduler {
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Schedules a repeating task to be executed on the region which owns the
|
||||
* <b>Folia and Paper</b>: Schedules a repeating task to be executed on the region which owns the
|
||||
* location of given entity after the initial delay with the specified period
|
||||
* <p>
|
||||
* <b>Bukkit</b>: same as {@link #runTaskTimer(Runnable, long, long)}
|
||||
@@ -285,7 +285,7 @@ public interface TaskScheduler {
|
||||
|
||||
/**
|
||||
* Calls a method on the main thread and returns a Future object. This task will be executed
|
||||
* by the main(Bukkit)/global(Folia&Paper) server thread.
|
||||
* by the main(Bukkit)/global(FoliaandPaper) server thread.
|
||||
* <p>
|
||||
* Note: The Future.get() methods must NOT be called from the main thread.
|
||||
* <p>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -25,6 +25,9 @@ import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||
import me.clip.placeholderapi.util.Msg;
|
||||
@@ -35,12 +38,13 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
public class UpdateChecker implements Listener {
|
||||
private static final String MODRINTH_URL = "https://api.modrinth.com/v2/project/lKEzGugV/version";
|
||||
|
||||
private static final int RESOURCE_ID = 6245;
|
||||
private final PlaceholderAPIPlugin plugin;
|
||||
private final TaskScheduler scheduler;
|
||||
private final String pluginVersion;
|
||||
private String spigotVersion;
|
||||
private String modrinthVersion;
|
||||
private boolean updateAvailable;
|
||||
|
||||
public UpdateChecker(PlaceholderAPIPlugin plugin) {
|
||||
@@ -53,27 +57,27 @@ public class UpdateChecker implements Listener {
|
||||
return updateAvailable;
|
||||
}
|
||||
|
||||
public String getSpigotVersion() {
|
||||
return spigotVersion;
|
||||
public String getModrinthVersion() {
|
||||
return modrinthVersion;
|
||||
}
|
||||
|
||||
public void fetch() {
|
||||
scheduler.runTaskAsynchronously(() -> {
|
||||
try {
|
||||
HttpsURLConnection con = (HttpsURLConnection) new URL(
|
||||
"https://api.spigotmc.org/legacy/update.php?resource=" + RESOURCE_ID).openConnection();
|
||||
HttpsURLConnection con = (HttpsURLConnection) new URL(MODRINTH_URL).openConnection();
|
||||
con.setRequestMethod("GET");
|
||||
spigotVersion = new BufferedReader(new InputStreamReader(con.getInputStream())).readLine();
|
||||
final JsonElement json = JsonParser.parseReader(new BufferedReader(new InputStreamReader(con.getInputStream())));
|
||||
modrinthVersion = json.getAsJsonArray().get(0).getAsJsonObject().get("version_number").getAsString();
|
||||
} catch (Exception ex) {
|
||||
plugin.getLogger().info("Failed to check for updates on spigot.");
|
||||
plugin.getLogger().info("Failed to check for updates on modrinth.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (spigotVersion == null || spigotVersion.isEmpty()) {
|
||||
if (modrinthVersion == null || modrinthVersion.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateAvailable = spigotIsNewer();
|
||||
updateAvailable = modrinthIsNewer();
|
||||
|
||||
if (!updateAvailable) {
|
||||
return;
|
||||
@@ -81,21 +85,21 @@ public class UpdateChecker implements Listener {
|
||||
|
||||
scheduler.runTask(() -> {
|
||||
plugin.getLogger()
|
||||
.info("An update for PlaceholderAPI (v" + getSpigotVersion() + ") is available at:");
|
||||
.info("An update for PlaceholderAPI (v" + getModrinthVersion() + ") is available at:");
|
||||
plugin.getLogger()
|
||||
.info("https://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID + "/");
|
||||
.info("https://modrinth.com/plugin/placeholderapi");
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private boolean spigotIsNewer() {
|
||||
if (spigotVersion == null || spigotVersion.isEmpty()) {
|
||||
private boolean modrinthIsNewer() {
|
||||
if (modrinthVersion == null || modrinthVersion.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int[] plV = toReadable(pluginVersion);
|
||||
int[] spV = toReadable(spigotVersion);
|
||||
int[] spV = toReadable(modrinthVersion);
|
||||
|
||||
if (plV[0] < spV[0]) {
|
||||
return true;
|
||||
@@ -118,10 +122,9 @@ public class UpdateChecker implements Listener {
|
||||
public void onJoin(PlayerJoinEvent e) {
|
||||
if (e.getPlayer().hasPermission("placeholderapi.updatenotify")) {
|
||||
Msg.msg(e.getPlayer(),
|
||||
"&bAn update for &fPlaceholder&7API &e(&fPlaceholder&7API &fv" + getSpigotVersion()
|
||||
"&bAn update for &fPlaceholder&7API &e(&fPlaceholder&7API &fv" + getModrinthVersion()
|
||||
+ "&e)"
|
||||
, "&bis available at &ehttps://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID
|
||||
+ "/");
|
||||
, "&bis available at &ehttps://modrinth.com/plugin/placeholderapi");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
package me.clip.placeholderapi.util;
|
||||
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.common.io.Resources;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class ExpansionSafetyCheck {
|
||||
private static final String MESSAGE =
|
||||
"\n###############################################\n" +
|
||||
"###############################################\n" +
|
||||
"PlaceholderAPI performs checks at startup and /papi reload for known malicious expansions. If you're seeing this message, there are the following malicious expansions in plugins/PlaceholderAPI/expansions.\n" +
|
||||
"%s" +
|
||||
"To prevent further infection PlaceholderAPI has stopped the server.\n" +
|
||||
"If you're seeing this message after updating PAPI, your server may have been infected for some time, so best practice is a complete system wipe and reinstall of your server software and plugins to be safe.\n" +
|
||||
"If you're seeing this after downloading an expansion however, PAPI hasn't loaded any of the malicious expansions above so you should be safe to simply delete the expansion in question.\n" +
|
||||
"###############################################\n" +
|
||||
"###############################################";
|
||||
|
||||
private final PlaceholderAPIPlugin main;
|
||||
|
||||
public ExpansionSafetyCheck(@NotNull final PlaceholderAPIPlugin main) {
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
public boolean runChecks() {
|
||||
if (!main.getPlaceholderAPIConfig().detectMaliciousExpansions()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final File expansionsFolder = new File(main.getDataFolder(), "expansions");
|
||||
|
||||
if (!expansionsFolder.exists()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Set<String> knownMaliciousExpansions;
|
||||
|
||||
try {
|
||||
final String hashes = Resources.toString(new URL("https://check.placeholderapi.com"), StandardCharsets.UTF_8);
|
||||
knownMaliciousExpansions = Arrays.stream(hashes.split("\n")).collect(Collectors.toSet());
|
||||
} catch (Exception e) {
|
||||
main.getLogger().log(Level.SEVERE, "Failed to download anti malware hash check list from https://check.placeholderapi.com", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
final Set<String> maliciousPaths = new HashSet<>();
|
||||
|
||||
for (File file : expansionsFolder.listFiles()) {
|
||||
try {
|
||||
final String hash = Hashing.sha256().hashBytes(Files.asByteSource(file).read()).toString();
|
||||
|
||||
if (knownMaliciousExpansions.contains(hash)) {
|
||||
maliciousPaths.add(file.getAbsolutePath());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
main.getLogger().log(Level.SEVERE, "Error occurred while trying to read " + file.getAbsolutePath(), e);
|
||||
}
|
||||
}
|
||||
|
||||
if (maliciousPaths.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
main.getLogger().severe(String.format(MESSAGE, maliciousPaths.stream().map(p -> "HASH OF " + p + " MATCHES KNOWN MALICIOUS EXPANSION DELETE IMMEDIATELY\n").collect(Collectors.joining())));
|
||||
|
||||
main.getServer().shutdown();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -29,6 +29,7 @@ import static java.util.stream.IntStream.range;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
@@ -23,6 +23,7 @@ package me.clip.placeholderapi.util;
|
||||
import java.util.Arrays;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
@@ -43,7 +44,7 @@ public final class Msg {
|
||||
log(Level.WARNING, msg, args);
|
||||
}
|
||||
|
||||
public static void warn(String msg, Throwable throwable, Object... args){
|
||||
public static void warn(String msg, Throwable throwable, Object... args) {
|
||||
PlaceholderAPIPlugin.getInstance().getLogger().log(Level.WARNING, String.format(msg, args), throwable);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
# Expansions: https://placeholderapi.com/ecloud
|
||||
# Wiki: https://wiki.placeholderapi.com/
|
||||
# Discord: https://helpch.at/discord
|
||||
# If you're seeing performance issues with plugins that use component replacement, or things don't look quite right,
|
||||
# switch to the replacer provided by adventure itself by changing use_adventure_provided_replacer to true
|
||||
# No placeholders are provided with this plugin by default.
|
||||
# Download placeholders: /papi ecloud
|
||||
check_updates: true
|
||||
@@ -15,4 +17,6 @@ boolean:
|
||||
'true': 'yes'
|
||||
'false': 'no'
|
||||
date_format: MM/dd/yy HH:mm:ss
|
||||
detect_malicious_expansions: true
|
||||
use_adventure_provided_replacer: false
|
||||
debug: false
|
||||
|
||||
184
src/paper/java/me/clip/placeholderapi/PAPIComponents.java
Normal file
184
src/paper/java/me/clip/placeholderapi/PAPIComponents.java
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
*
|
||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PlaceholderAPI is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi;
|
||||
|
||||
import me.clip.placeholderapi.replacer.ComponentReplacer;
|
||||
import me.clip.placeholderapi.replacer.ExactReplacer;
|
||||
import me.clip.placeholderapi.replacer.RelationalExactReplacer;
|
||||
import me.clip.placeholderapi.replacer.Replacer;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static me.clip.placeholderapi.PlaceholderAPI.RELATIONAL_PLACEHOLDER_PATTERN;
|
||||
|
||||
public final class PAPIComponents {
|
||||
private static final Replacer PERCENT_EXACT_REPLACER = new ExactReplacer('%', '%');
|
||||
private static final Replacer BRACKET_EXACT_REPLACER = new ExactReplacer('{', '}');
|
||||
private static final RelationalExactReplacer RELATIONAL_EXACT_REPLACER = new RelationalExactReplacer();
|
||||
|
||||
/**
|
||||
* Translates all placeholders into their corresponding values.
|
||||
* <br>The pattern of a valid placeholder is {@literal %<identifier>_<params>%}.
|
||||
*
|
||||
* @param player Player to parse the placeholders against
|
||||
* @param component Component to set the placeholder values in
|
||||
* @return Component containing all translated placeholders
|
||||
*/
|
||||
@NotNull
|
||||
public static Component setPlaceholders(final OfflinePlayer player, @NotNull final Component component) {
|
||||
if (PlaceholderAPIPlugin.getInstance().getPlaceholderAPIConfig().useAdventureProvidedReplacer()) {
|
||||
return component.replaceText(config -> config.match(PlaceholderAPI.PLACEHOLDER_PATTERN).replacement((result, builder) ->
|
||||
builder.content(PERCENT_EXACT_REPLACER.apply(result.group(), player, PlaceholderAPIPlugin.getInstance().getLocalExpansionManager()::getExpansion))));
|
||||
}
|
||||
|
||||
return ComponentReplacer.replace(component, str -> PlaceholderAPI.setPlaceholders(player, str));
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates all placeholders into their corresponding values.
|
||||
* <br>The pattern of a valid placeholder is {@literal %<identifier>_<params>%}.
|
||||
*
|
||||
* @param player Player to parse the placeholders against
|
||||
* @param components List of Components to set the placeholder values in
|
||||
* @return List of Components containing all translated placeholders
|
||||
*/
|
||||
@NotNull
|
||||
public static List<Component> setPlaceholders(final OfflinePlayer player, @NotNull final List<Component> components) {
|
||||
return components.stream().map(component -> setPlaceholders(player, component)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates all placeholders into their corresponding values.
|
||||
* <br>The pattern of a valid placeholder is {@literal %<identifier>_<params>%}.
|
||||
*
|
||||
* @param player Player to parse the placeholders against
|
||||
* @param component Component to set the placeholder values in
|
||||
* @return Component containing all translated placeholders
|
||||
*/
|
||||
@NotNull
|
||||
public static Component setPlaceholders(final Player player, @NotNull final Component component) {
|
||||
return setPlaceholders((OfflinePlayer) player, component);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates all placeholders into their corresponding values.
|
||||
* <br>The pattern of a valid placeholder is {@literal %<identifier>_<params>%}.
|
||||
*
|
||||
* @param player Player to parse the placeholders against
|
||||
* @param components List of Components to set the placeholder values in
|
||||
* @return List of components containing all translated placeholders
|
||||
*/
|
||||
@NotNull
|
||||
public static List<Component> setPlaceholders(final Player player, @NotNull final List<Component> components) {
|
||||
return setPlaceholders((OfflinePlayer) player, components);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates all placeholders into their corresponding values.
|
||||
* <br>The pattern of a valid placeholder is {@literal {<identifier>_<params>}}.
|
||||
*
|
||||
* @param player Player to parse the placeholders against
|
||||
* @param component Component to set the placeholder values in
|
||||
* @return Component containing all translated placeholders
|
||||
*/
|
||||
@NotNull
|
||||
public static Component setBracketPlaceholders(final OfflinePlayer player, @NotNull final Component component) {
|
||||
if (PlaceholderAPIPlugin.getInstance().getPlaceholderAPIConfig().useAdventureReplacer()) {
|
||||
return component.replaceText(config -> config.match(PlaceholderAPI.BRACKET_PLACEHOLDER_PATTERN).replacement((result, builder) ->
|
||||
builder.content(BRACKET_EXACT_REPLACER.apply(result.group(), player, PlaceholderAPIPlugin.getInstance().getLocalExpansionManager()::getExpansion))));
|
||||
}
|
||||
|
||||
return ComponentReplacer.replace(component, str -> PlaceholderAPI.setBracketPlaceholders(player, str));
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates all placeholders into their corresponding values.
|
||||
* <br>The pattern of a valid placeholder is {@literal {<identifier>_<params>}}.
|
||||
*
|
||||
* @param player Player to parse the placeholders against
|
||||
* @param components List of Components to set the placeholder values in
|
||||
* @return List of Components containing all translated placeholders
|
||||
*/
|
||||
@NotNull
|
||||
public static List<Component> setBracketPlaceholders(final OfflinePlayer player, @NotNull final List<Component> components) {
|
||||
return components.stream().map(component -> setBracketPlaceholders(player, component)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates all placeholders into their corresponding values.
|
||||
* <br>The pattern of a valid placeholder is {@literal {<identifier>_<params>}}.
|
||||
*
|
||||
* @param player Player to parse the placeholders against
|
||||
* @param component Component to set the placeholder values in
|
||||
* @return Component containing all translated placeholders
|
||||
*/
|
||||
@NotNull
|
||||
public static Component setBracketPlaceholders(final Player player, @NotNull final Component component) {
|
||||
return setBracketPlaceholders((OfflinePlayer) player, component);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates all placeholders into their corresponding values.
|
||||
* <br>The pattern of a valid placeholder is {@literal {<identifier>_<params>}}.
|
||||
*
|
||||
* @param player Player to parse the placeholders against
|
||||
* @param components List of Components to set the placeholder values in
|
||||
* @return List of Components containing all translated placeholders
|
||||
*/
|
||||
@NotNull
|
||||
public static List<Component> setBracketPlaceholders(final Player player, @NotNull final List<Component> components) {
|
||||
return setBracketPlaceholders((OfflinePlayer) player, components);
|
||||
}
|
||||
|
||||
/**
|
||||
* set relational placeholders in the text specified placeholders are matched with the pattern
|
||||
* {@literal %<rel_(identifier)_(params)>%} when set with this method
|
||||
*
|
||||
* @param one First player to compare
|
||||
* @param two Second player to compare
|
||||
* @param component Component to parse the placeholders in
|
||||
* @return The Component containing the parsed relational placeholders
|
||||
*/
|
||||
public static Component setRelationalPlaceholders(Player one, Player two, Component component) {
|
||||
//todo: custom replacer
|
||||
return component.replaceText(config -> config.match(RELATIONAL_PLACEHOLDER_PATTERN).replacement((result, builder) ->
|
||||
builder.content(RELATIONAL_EXACT_REPLACER.apply(result.group(2), one, two, PlaceholderAPIPlugin.getInstance().getLocalExpansionManager()::getExpansion))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate placeholders in the provided List based on the relation of the two provided players.
|
||||
* <br>The pattern of a valid placeholder is {@literal %rel_<identifier>_<param>%}.
|
||||
*
|
||||
* @param one Player to compare
|
||||
* @param two Player to compare
|
||||
* @param components List of Components to parse the placeholder values to
|
||||
* @return The List of Components containing the parsed relational placeholders
|
||||
*/
|
||||
public static List<Component> setRelationalPlaceholders(Player one, Player two, List<Component> components) {
|
||||
return components.stream().map(line -> setRelationalPlaceholders(one, two, line))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
package me.clip.placeholderapi.replacer;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.nbt.api.BinaryTagHolder;
|
||||
import net.kyori.adventure.text.*;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import net.kyori.adventure.text.event.DataComponentValue;
|
||||
import net.kyori.adventure.text.event.HoverEvent;
|
||||
import net.kyori.adventure.text.format.Style;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ComponentReplacer {
|
||||
@NotNull
|
||||
public static Component replace(@NotNull final Component component, @NotNull final Function<String, String> replacer) {
|
||||
return rebuild(component, replacer);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Component rebuild(@NotNull final Component component, @NotNull final Function<String, String> replacer) {
|
||||
Component rebuilt;
|
||||
|
||||
if (component instanceof TextComponent) {
|
||||
final TextComponent text = (TextComponent) component;
|
||||
final String replaced = replacer.apply(text.content());
|
||||
|
||||
rebuilt = Component.text(replaced);
|
||||
} else if (component instanceof TranslatableComponent) {
|
||||
final TranslatableComponent translatable = (TranslatableComponent) component;
|
||||
final List<Component> arguments = new ArrayList<>();
|
||||
|
||||
for (final ComponentLike arg : translatable.arguments()) {
|
||||
arguments.add(rebuild(arg.asComponent(), replacer));
|
||||
}
|
||||
|
||||
rebuilt = Component.translatable(translatable.key(), arguments);
|
||||
} else if (component instanceof KeybindComponent) {
|
||||
final KeybindComponent keybind = (KeybindComponent) component;
|
||||
rebuilt = Component.keybind(keybind.keybind());
|
||||
} else if (component instanceof ScoreComponent) {
|
||||
final ScoreComponent score = (ScoreComponent) component;
|
||||
rebuilt = Component.score(score.name(), score.objective());
|
||||
} else if (component instanceof SelectorComponent) {
|
||||
final SelectorComponent selector = (SelectorComponent) component;
|
||||
rebuilt = Component.selector(selector.pattern());
|
||||
} else {
|
||||
rebuilt = Component.empty();
|
||||
}
|
||||
|
||||
rebuilt = rebuilt.style(rebuildStyle(component.style(), replacer));
|
||||
|
||||
if (!component.children().isEmpty()) {
|
||||
final List<Component> children = new ArrayList<>();
|
||||
for (Component child : component.children()) {
|
||||
children.add(rebuild(child, replacer));
|
||||
}
|
||||
rebuilt = rebuilt.children(children);
|
||||
}
|
||||
|
||||
return rebuilt;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Style rebuildStyle(@NotNull final Style style, @NotNull final Function<String, String> replacer) {
|
||||
final Style.Builder builder = style.toBuilder();
|
||||
final ClickEvent click = style.clickEvent();
|
||||
|
||||
if (click != null) {
|
||||
builder.clickEvent(rebuildClickEvent(click, replacer));
|
||||
}
|
||||
|
||||
final HoverEvent<?> hover = style.hoverEvent();
|
||||
|
||||
if (hover != null) {
|
||||
builder.hoverEvent(rebuildHoverEvent(hover, replacer));
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ClickEvent rebuildClickEvent(@NotNull final ClickEvent click, @NotNull final Function<String, String> replacer) {
|
||||
final ClickEvent.Payload payload = click.payload();
|
||||
|
||||
if (!(payload instanceof ClickEvent.Payload.Text)) {
|
||||
return click;
|
||||
}
|
||||
|
||||
final String original = ((ClickEvent.Payload.Text) payload).value();
|
||||
final String replaced = replacer.apply(original);
|
||||
|
||||
final ClickEvent.Action action = click.action();
|
||||
|
||||
switch (action) {
|
||||
case OPEN_URL:
|
||||
return ClickEvent.openUrl(replaced);
|
||||
case OPEN_FILE:
|
||||
return ClickEvent.openFile(replaced);
|
||||
case RUN_COMMAND:
|
||||
return ClickEvent.runCommand(replaced);
|
||||
case SUGGEST_COMMAND:
|
||||
return ClickEvent.suggestCommand(replaced);
|
||||
case COPY_TO_CLIPBOARD:
|
||||
return ClickEvent.copyToClipboard(replaced);
|
||||
default:
|
||||
return click;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static HoverEvent<?> rebuildHoverEvent(@NotNull final HoverEvent<?> hover, @NotNull final Function<String, String> replacer) {
|
||||
final Object value = hover.value();
|
||||
|
||||
if (value instanceof Component) {
|
||||
final Component rebuilt = rebuild((Component) value, replacer);
|
||||
return HoverEvent.showText(rebuilt);
|
||||
}
|
||||
|
||||
if (value instanceof HoverEvent.ShowItem) {
|
||||
return rebuildShowItem((HoverEvent.ShowItem) value, replacer);
|
||||
}
|
||||
|
||||
if (value instanceof HoverEvent.ShowEntity) {
|
||||
final HoverEvent.ShowEntity entity = (HoverEvent.ShowEntity) value;
|
||||
|
||||
Component rebuiltName = null;
|
||||
if (entity.name() != null) {
|
||||
rebuiltName = rebuild(entity.name(), replacer);
|
||||
}
|
||||
|
||||
return HoverEvent.showEntity(entity.type(), entity.id(), rebuiltName);
|
||||
}
|
||||
|
||||
return hover;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static HoverEvent<?> rebuildShowItem(@NotNull final HoverEvent.ShowItem item, @NotNull final Function<String, String> replacer) {
|
||||
final BinaryTagHolder nbt = item.nbt();
|
||||
|
||||
if (nbt != null && !nbt.string().isEmpty()) {
|
||||
final String replaced = replacer.apply(nbt.string());
|
||||
|
||||
return HoverEvent.showItem(item.item(), item.count(), BinaryTagHolder.binaryTagHolder(replaced));
|
||||
}
|
||||
|
||||
//I'm not 100% sure this is how we're meant to support data components but let's give it a go and see if it causes any issues :)
|
||||
final Map<Key, DataComponentValue> components = item.dataComponents();
|
||||
|
||||
if (!components.isEmpty()) {
|
||||
final Map<Key, DataComponentValue> rebuilt = new HashMap<>();
|
||||
|
||||
for (final Map.Entry<Key, DataComponentValue> entry : components.entrySet()) {
|
||||
final DataComponentValue value = entry.getValue();
|
||||
|
||||
if (!(value instanceof BinaryTagHolder)) {
|
||||
rebuilt.put(entry.getKey(), value);
|
||||
continue;
|
||||
}
|
||||
|
||||
rebuilt.put(entry.getKey(), BinaryTagHolder.binaryTagHolder(replacer.apply(((BinaryTagHolder) value).string())));
|
||||
}
|
||||
|
||||
return HoverEvent.showItem(item.item(), item.count(), rebuilt);
|
||||
}
|
||||
|
||||
return HoverEvent.showItem(item);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
*
|
||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PlaceholderAPI is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.replacer;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public final 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,
|
||||
@NotNull final Function<String, @Nullable PlaceholderExpansion> lookup) {
|
||||
text = text.substring(1, text.length() - 1);
|
||||
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 start + text + end;
|
||||
}
|
||||
|
||||
final String params;
|
||||
|
||||
if (text.endsWith("_")) {
|
||||
params = "";
|
||||
} else {
|
||||
params = text.substring(text.indexOf('_') + 1);
|
||||
}
|
||||
|
||||
final String result = expansion.onRequest(player, params);
|
||||
|
||||
if (result == null) {
|
||||
return start + text + end;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||
*
|
||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PlaceholderAPI is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.replacer;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import me.clip.placeholderapi.expansion.Relational;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public final class RelationalExactReplacer {
|
||||
private static final Pattern DELIMITER = Pattern.compile("_");
|
||||
|
||||
@NotNull
|
||||
public String apply(@NotNull String text, @Nullable final Player player1,
|
||||
@Nullable final Player player2, @NotNull final Function<String,
|
||||
@Nullable PlaceholderExpansion> lookup) {
|
||||
final String[] parts = DELIMITER.split(text);
|
||||
final PlaceholderExpansion expansion;
|
||||
|
||||
if (parts.length == 0) {
|
||||
expansion = lookup.apply(text);
|
||||
} else {
|
||||
expansion = lookup.apply(parts[0]);
|
||||
}
|
||||
|
||||
if (expansion == null) {
|
||||
return "%rel_" + text + '%';
|
||||
}
|
||||
|
||||
if (!(expansion instanceof Relational)) {
|
||||
return "%rel_" + text + '%';
|
||||
}
|
||||
|
||||
final String params;
|
||||
|
||||
if (text.endsWith("_")) {
|
||||
params = "";
|
||||
} else {
|
||||
params = text.substring(text.indexOf('_') + 1);
|
||||
}
|
||||
|
||||
final String result = ((Relational) expansion).onPlaceholderRequest(player1, player2, params);
|
||||
|
||||
if (result == null) {
|
||||
return "%rel_" + text + '%';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of PlaceholderAPI
|
||||
*
|
||||
* PlaceholderAPI
|
||||
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
|
||||
* 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
|
||||
|
||||
Reference in New Issue
Block a user