mirror of
https://github.com/PlaceholderAPI/PlaceholderAPI
synced 2026-02-08 00:42:47 +01:00
Compare commits
118 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 | ||
|
|
0575c8cf41 | ||
|
|
c181d18f5e | ||
|
|
2e0d9eb846 | ||
|
|
33d1009d6a | ||
|
|
b16d62fb75 | ||
|
|
e019d6370c | ||
|
|
581b73dbc7 | ||
|
|
25f7eafe32 | ||
|
|
ef22d564f3 | ||
|
|
787a053d98 | ||
|
|
f31dd2bea9 | ||
|
|
5c8086150a | ||
|
|
b838d1c52a | ||
|
|
0a712e6530 | ||
|
|
272e2e7904 | ||
|
|
98082398fc | ||
|
|
c66806ecf8 | ||
|
|
c97f5aa5a6 | ||
|
|
c1487898a9 | ||
|
|
907ced6d7d | ||
|
|
ac771207c3 | ||
|
|
8b031576aa | ||
|
|
2d1a0ee157 | ||
|
|
b9e2bf9429 | ||
|
|
a35923a117 | ||
|
|
d5e96bd6a6 | ||
|
|
2523b6c094 | ||
|
|
7b230fc679 | ||
|
|
68f467ab29 | ||
|
|
068b5a31b2 | ||
|
|
882b7c5965 | ||
|
|
7a0be5edf8 | ||
|
|
e94328935d | ||
|
|
604fed36a4 | ||
|
|
403622d205 | ||
|
|
1cd4d93f7f | ||
|
|
a83ef75bf9 | ||
|
|
b96e535aaa | ||
|
|
2e67272aea | ||
|
|
2c7767e77d | ||
|
|
c4a046ff24 | ||
|
|
57fa68c896 | ||
|
|
b64f024eb2 | ||
|
|
c7a4900aa3 | ||
|
|
491abd6238 | ||
|
|
d3646a9874 | ||
|
|
af0b475330 | ||
|
|
d35a499e31 | ||
|
|
c0f824450e | ||
|
|
5b1a8ef4ba | ||
|
|
5623a00f9b | ||
|
|
4926907b47 | ||
|
|
32f3d14682 | ||
|
|
152105017d | ||
|
|
be956f52b0 | ||
|
|
195158b18b | ||
|
|
36fa9ac96d | ||
|
|
42cfe1dc80 | ||
|
|
92a7d54664 | ||
|
|
f91b4e3752 | ||
|
|
a497e05e55 | ||
|
|
74d8fec6bd | ||
|
|
28287c7fbd | ||
|
|
744cf6d8c0 | ||
|
|
ecd4c002c8 | ||
|
|
b4e60b7db5 | ||
|
|
e862abe0b4 |
15
.github/CONTRIBUTING.md
vendored
15
.github/CONTRIBUTING.md
vendored
@@ -1,7 +1,7 @@
|
|||||||
[issue]: https://github.com/PlaceholderAPI/PlaceholderAPI/issues/new
|
[issue]: https://github.com/PlaceholderAPI/PlaceholderAPI/issues/new
|
||||||
[discord]: https://helpch.at/discord
|
[discord]: https://helpch.at/discord
|
||||||
[code of conduct]: https://github.com/PlaceholderAPI/PlaceholderAPI/blob/master/CODE_OF_CONDUCT.md
|
[code of conduct]: https://github.com/PlaceholderAPI/PlaceholderAPI/blob/master/CODE_OF_CONDUCT.md
|
||||||
[wiki]: https://github.com/PlaceholderAPI/PlaceholderAPI/blob/docs/wiki/wiki
|
[wiki]: https://github.com/PlaceholderAPI/PlaceholderAPI/blob/wiki
|
||||||
[master]: https://github.com/PlaceholderAPI/PlaceholderAPI/tree/master
|
[master]: https://github.com/PlaceholderAPI/PlaceholderAPI/tree/master
|
||||||
[docs-wiki]: https://github.com/PlaceholderAPI/PlaceholderAPI/tree/docs/wiki
|
[docs-wiki]: https://github.com/PlaceholderAPI/PlaceholderAPI/tree/docs/wiki
|
||||||
[style]: https://github.com/PlaceholderAPI/PlaceholderAPI/tree/master/config/style
|
[style]: https://github.com/PlaceholderAPI/PlaceholderAPI/tree/master/config/style
|
||||||
@@ -38,9 +38,10 @@ 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.
|
In those cases should you report the issue to the issue tracker of the expansion or plugin.
|
||||||
|
|
||||||
## Pull requests
|
## 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.
|
||||||
|
|
||||||
**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.**
|
> [!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.
|
||||||
|
|
||||||
### Code contributions
|
### Code contributions
|
||||||
> **Source and Target Branch:** [`master`][master]
|
> **Source and Target Branch:** [`master`][master]
|
||||||
@@ -56,12 +57,10 @@ Javadocs changes should usually be combined with [code contributions](#code-cont
|
|||||||
\*This branch may change in the future.
|
\*This branch may change in the future.
|
||||||
|
|
||||||
### Wiki contributions
|
### Wiki contributions
|
||||||
> **Source and Target Branch:** [`docs/wiki`][docs-wiki]
|
> **Source and Target Branch:** [`wiki`][docs-wiki]
|
||||||
|
|
||||||
The Wiki of PlaceholderAPI has a unique quirk by having a dedicated [`wiki` folder][wiki] hosting the pages found on the actual wiki itself.
|
The Wiki of PlaceholderAPI is located on its own dedicated branch, hosting all the assets and files that get used to create it through the usage of GitHub Actions and GitHub Pages.
|
||||||
If you find outdated information, want to add missing expansions/plugins or just like to correct some wrong spelling should you both base of and target your contributions on the `docs/wiki` branch.
|
We welcome contributions that update outdated information, add new expansions/plugins supporting PlaceholderAPI or even correct spelling mistakes and typos.
|
||||||
|
|
||||||
**Please only PR changes for the `wiki` folder on the `docs/wiki` branch! Pull requests not following this guidelines will be closed unnanounced.**
|
|
||||||
|
|
||||||
## Code of Conduct
|
## Code of Conduct
|
||||||
We have a [Code of Conduct] to maintain a welcoming atmosphere in this project.
|
We have a [Code of Conduct] to maintain a welcoming atmosphere in this project.
|
||||||
|
|||||||
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -21,8 +21,8 @@
|
|||||||
### Description
|
### Description
|
||||||
<!-- What does your Pull request change? -->
|
<!-- 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! -->
|
<!-- DO NOT ALTER ANYTHING BELOW THIS LINE! -->
|
||||||
[Wiki]: https://github.com/PlaceholderAPI/PlaceholderAPI/wiki
|
[Wiki]: https://wiki.placeholderapi.com
|
||||||
|
|||||||
4
.github/label-commenter-config.yml
vendored
4
.github/label-commenter-config.yml
vendored
@@ -1,8 +1,8 @@
|
|||||||
comment:
|
comment:
|
||||||
footer: "\
|
footer: "\
|
||||||
----\n\n
|
----\n\n
|
||||||
> **Note**\n
|
> [!NOTE]\n
|
||||||
> *This is an automated response created by a **GitHub Action***\n
|
> *This is an automated response created by a **GitHub Action***<br>
|
||||||
> *Mentioning the bot won't have any effect!*
|
> *Mentioning the bot won't have any effect!*
|
||||||
"
|
"
|
||||||
|
|
||||||
|
|||||||
6
.github/workflows/pr_build_jars.yml
vendored
6
.github/workflows/pr_build_jars.yml
vendored
@@ -5,8 +5,10 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- development
|
- development
|
||||||
paths:
|
paths:
|
||||||
- "src/**"
|
- "../../spigot/**"
|
||||||
- "build.gradle"
|
- "../../paper/**"
|
||||||
|
- "build.gradle.kts"
|
||||||
|
- "settings.gradle.kts"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
testBuilds:
|
testBuilds:
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -7,18 +7,20 @@
|
|||||||
|
|
||||||
[discord]: https://helpch.at/discord
|
[discord]: https://helpch.at/discord
|
||||||
[spigot]: https://www.spigotmc.org/resources/6245/
|
[spigot]: https://www.spigotmc.org/resources/6245/
|
||||||
[Expansions cloud]: https://api.extendedclip.com/home
|
[hangar]: https://hangar.papermc.io/HelpChat/PlaceholderAPI
|
||||||
|
[modrinth]: https://modrinth.com/plugin/placeholderapi
|
||||||
|
[Expansions cloud]: https://ecloud.placeholderapi.com
|
||||||
[placeholder list]: https://helpch.at/placeholders
|
[placeholder list]: https://helpch.at/placeholders
|
||||||
[statistics]: https://bstats.org/plugin/bukkit/PlaceholderAPI
|
[statistics]: https://bstats.org/plugin/bukkit/PlaceholderAPI
|
||||||
|
|
||||||
[ci]: http://ci.extendedclip.com/job/PlaceholderAPI/
|
[ci]: http://ci.extendedclip.com/job/PlaceholderAPI/
|
||||||
[ciImg]: http://ci.extendedclip.com/buildStatus/icon?job=PlaceholderAPI
|
[ciImg]: http://ci.extendedclip.com/buildStatus/icon?job=PlaceholderAPI
|
||||||
|
|
||||||
[APIversionImg]: https://img.shields.io/nexus/placeholderapi/me.clip/placeholderapi?server=https%3A%2F%2Frepo.extendedclip.com&label=API%20Version
|
[APIversionImg]: https://repo.extendedclip.com/api/badge/latest/releases/me/clip/placeholderapi?name=API%20Version
|
||||||
[logo]: https://raw.githubusercontent.com/PlaceholderAPI/PlaceholderAPI/wiki/img/papi-logo.png
|
[logo]: https://wiki.placeholderapi.com/assets/img/papi-logo.png
|
||||||
|
|
||||||
[contributing]: https://github.com/PlaceholderAPI/PlaceholderAPI/blob/master/.github/CONTRIBUTING.md
|
[contributing]: https://github.com/PlaceholderAPI/PlaceholderAPI/blob/master/.github/CONTRIBUTING.md
|
||||||
[placeholderexpansion]: https://github.com/PlaceholderAPI/PlaceholderAPI/wiki/PlaceholderExpansion
|
[placeholderexpansion]: https://wiki.placeholderapi.com/developers/creating-a-placeholderexpansion/
|
||||||
<!-- The stuff above isn't visible in the readme -->
|
<!-- The stuff above isn't visible in the readme -->
|
||||||
|
|
||||||
[![logo]][spigot]
|
[![logo]][spigot]
|
||||||
@@ -30,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.
|
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,000,000 times and has been used concurrently on over 40,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
|
## 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.
|
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.
|
||||||
@@ -47,4 +49,6 @@ If you would like to create your own Placeholder Expansion for PlaceholderAPI, t
|
|||||||
- [Expansions Cloud]
|
- [Expansions Cloud]
|
||||||
- [Placeholder List]
|
- [Placeholder List]
|
||||||
- [Spigot Page][spigot]
|
- [Spigot Page][spigot]
|
||||||
|
- [Hangar Page][hangar]
|
||||||
|
- [Modrinth Page][modrinth]
|
||||||
- [Plugin Statistics][statistics]
|
- [Plugin Statistics][statistics]
|
||||||
|
|||||||
113
build.gradle.kts
113
build.gradle.kts
@@ -3,15 +3,23 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
|||||||
plugins {
|
plugins {
|
||||||
`java-library`
|
`java-library`
|
||||||
`maven-publish`
|
`maven-publish`
|
||||||
id("com.github.hierynomus.license") version "0.16.1"
|
// id("com.github.hierynomus.license") version "0.16.1"
|
||||||
id("com.github.johnrengelman.shadow") version "8.1.0"
|
id("io.github.goooler.shadow") version "8.1.7"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "me.clip"
|
group = "me.clip"
|
||||||
version = "2.11.3"
|
version = "2.12.2-DEV-${System.getProperty("BUILD_NUMBER")}"
|
||||||
|
|
||||||
description = "An awesome placeholder provider!"
|
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 {
|
repositories {
|
||||||
maven("https://oss.sonatype.org/content/repositories/snapshots/")
|
maven("https://oss.sonatype.org/content/repositories/snapshots/")
|
||||||
|
|
||||||
@@ -20,18 +28,21 @@ repositories {
|
|||||||
|
|
||||||
maven("https://repo.codemc.org/repository/maven-public/")
|
maven("https://repo.codemc.org/repository/maven-public/")
|
||||||
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
|
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
|
||||||
|
maven("https://repo.papermc.io/repository/maven-public/")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("org.bstats:bstats-bukkit:3.0.1")
|
implementation("org.bstats:bstats-bukkit:3.1.0")
|
||||||
implementation("net.kyori:adventure-platform-bukkit:4.3.0")
|
implementation("net.kyori:adventure-platform-bukkit:4.4.1")
|
||||||
|
|
||||||
compileOnly("org.spigotmc:spigot-api:1.19-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")
|
compileOnlyApi("org.jetbrains:annotations:23.0.0")
|
||||||
|
|
||||||
testImplementation("org.openjdk.jmh:jmh-core:1.32")
|
testImplementation("org.openjdk.jmh:jmh-core:1.32")
|
||||||
testImplementation("org.openjdk.jmh:jmh-generator-annprocess:1.32")
|
testImplementation("org.openjdk.jmh:jmh-generator-annprocess:1.32")
|
||||||
|
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.8.2")
|
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.8.2")
|
||||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1")
|
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1")
|
||||||
}
|
}
|
||||||
@@ -43,19 +54,8 @@ java {
|
|||||||
|
|
||||||
withJavadocJar()
|
withJavadocJar()
|
||||||
withSourcesJar()
|
withSourcesJar()
|
||||||
}
|
|
||||||
|
|
||||||
license {
|
disableAutoTargetJvm()
|
||||||
header = rootProject.file("config/headers/main.txt")
|
|
||||||
|
|
||||||
include("**/*.java")
|
|
||||||
mapping("java", "JAVADOC_STYLE")
|
|
||||||
|
|
||||||
encoding = "UTF-8"
|
|
||||||
|
|
||||||
ext {
|
|
||||||
set("year", 2021)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val javaComponent: SoftwareComponent = components["java"]
|
val javaComponent: SoftwareComponent = components["java"]
|
||||||
@@ -69,13 +69,36 @@ tasks {
|
|||||||
dependsOn(named("shadowJar"))
|
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.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
|
isFailOnError = false
|
||||||
|
|
||||||
|
source = sourceSets.main.get().allJava + paper.allJava
|
||||||
|
classpath = sourceSets.main.get().compileClasspath + paper.compileClasspath
|
||||||
|
|
||||||
with(options as StandardJavadocDocletOptions) {
|
with(options as StandardJavadocDocletOptions) {
|
||||||
addStringOption("Xdoclint:none", "-quiet")
|
addStringOption("Xdoclint:none", "-quiet")
|
||||||
addStringOption("encoding", "UTF-8")
|
addStringOption("encoding", "UTF-8")
|
||||||
@@ -83,11 +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> {
|
withType<ShadowJar> {
|
||||||
|
configurations = listOf(project.configurations.runtimeClasspath.get())
|
||||||
|
|
||||||
|
from(sourceSets.main.get().output)
|
||||||
|
|
||||||
archiveClassifier.set("")
|
archiveClassifier.set("")
|
||||||
|
|
||||||
relocate("org.bstats", "me.clip.placeholderapi.metrics")
|
relocate("org.bstats", "me.clip.placeholderapi.metrics")
|
||||||
relocate("net.kyori", "me.clip.placeholderapi.libs.kyori")
|
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 {
|
test {
|
||||||
@@ -98,16 +151,28 @@ tasks {
|
|||||||
publications {
|
publications {
|
||||||
create<MavenPublication>("maven") {
|
create<MavenPublication>("maven") {
|
||||||
artifactId = "placeholderapi"
|
artifactId = "placeholderapi"
|
||||||
from(javaComponent)
|
|
||||||
|
artifact(plainJar) {
|
||||||
|
builtBy(plainJar)
|
||||||
|
classifier = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
artifact(combinedSourcesJar) {
|
||||||
|
builtBy(combinedSourcesJar)
|
||||||
|
}
|
||||||
|
|
||||||
|
artifact(combinedJavadocJar) {
|
||||||
|
builtBy(combinedJavadocJar)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
if ("-DEV" in version.toString()) {
|
if ("-DEV" in version.toString()) {
|
||||||
url = uri("https://repo.extendedclip.com/content/repositories/dev/")
|
url = uri("https://repo.extendedclip.com/snapshots")
|
||||||
} else {
|
} else {
|
||||||
url = uri("https://repo.extendedclip.com/content/repositories/placeholderapi/")
|
url = uri("https://repo.extendedclip.com/releases")
|
||||||
}
|
}
|
||||||
|
|
||||||
credentials {
|
credentials {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2018-2021 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:
|
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:
|
||||||
|
|
||||||
|
|||||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
||||||
|
networkTimeout=10000
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
28
gradlew
vendored
28
gradlew
vendored
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright <EFBFBD> 2015-2021 the original authors.
|
# Copyright © 2015-2021 the original authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@@ -32,10 +32,10 @@
|
|||||||
# Busybox and similar reduced shells will NOT work, because this script
|
# Busybox and similar reduced shells will NOT work, because this script
|
||||||
# requires all of these POSIX shell features:
|
# requires all of these POSIX shell features:
|
||||||
# * functions;
|
# * functions;
|
||||||
# * expansions <EFBFBD>$var<EFBFBD>, <EFBFBD>${var}<EFBFBD>, <EFBFBD>${var:-default}<EFBFBD>, <EFBFBD>${var+SET}<EFBFBD>,
|
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||||
# <EFBFBD>${var#prefix}<EFBFBD>, <EFBFBD>${var%suffix}<EFBFBD>, and <EFBFBD>$( cmd )<EFBFBD>;
|
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||||
# * compound commands having a testable exit status, especially <EFBFBD>case<EFBFBD>;
|
# * compound commands having a testable exit status, especially «case»;
|
||||||
# * various built-in commands including <EFBFBD>command<EFBFBD>, <EFBFBD>set<EFBFBD>, and <EFBFBD>ulimit<EFBFBD>.
|
# * various built-in commands including «command», «set», and «ulimit».
|
||||||
#
|
#
|
||||||
# Important for patching:
|
# Important for patching:
|
||||||
#
|
#
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (3) This script is generated from the Groovy template
|
||||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
# within the Gradle project.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
@@ -80,10 +80,10 @@ do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
# This is normally unused
|
||||||
|
# shellcheck disable=SC2034
|
||||||
APP_NAME="Gradle"
|
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
|
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
@@ -143,12 +143,16 @@ fi
|
|||||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
max*)
|
max*)
|
||||||
|
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||||
|
# shellcheck disable=SC3045
|
||||||
MAX_FD=$( ulimit -H -n ) ||
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
warn "Could not query maximum file descriptor limit"
|
warn "Could not query maximum file descriptor limit"
|
||||||
esac
|
esac
|
||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
'' | soft) :;; #(
|
'' | soft) :;; #(
|
||||||
*)
|
*)
|
||||||
|
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||||
|
# shellcheck disable=SC3045
|
||||||
ulimit -n "$MAX_FD" ||
|
ulimit -n "$MAX_FD" ||
|
||||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
esac
|
esac
|
||||||
@@ -205,6 +209,12 @@ set -- \
|
|||||||
org.gradle.wrapper.GradleWrapperMain \
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
"$@"
|
"$@"
|
||||||
|
|
||||||
|
# Stop when "xargs" is not available.
|
||||||
|
if ! command -v xargs >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "xargs is not available"
|
||||||
|
fi
|
||||||
|
|
||||||
# Use "xargs" to parse quoted args.
|
# Use "xargs" to parse quoted args.
|
||||||
#
|
#
|
||||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
|||||||
15
gradlew.bat
vendored
15
gradlew.bat
vendored
@@ -14,7 +14,7 @@
|
|||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%" == "" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@rem
|
@rem
|
||||||
@rem Gradle startup script for Windows
|
@rem Gradle startup script for Windows
|
||||||
@@ -25,7 +25,8 @@
|
|||||||
if "%OS%"=="Windows_NT" setlocal
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
set DIRNAME=%~dp0
|
||||||
if "%DIRNAME%" == "" set DIRNAME=.
|
if "%DIRNAME%"=="" set DIRNAME=.
|
||||||
|
@rem This is normally unused
|
||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
@@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
|||||||
|
|
||||||
set JAVA_EXE=java.exe
|
set JAVA_EXE=java.exe
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if "%ERRORLEVEL%" == "0" goto execute
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
@@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
|||||||
|
|
||||||
:end
|
:end
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||||
|
|
||||||
:fail
|
:fail
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
rem the _cmd.exe /c_ return code!
|
rem the _cmd.exe /c_ return code!
|
||||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
set EXIT_CODE=%ERRORLEVEL%
|
||||||
exit /b 1
|
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||||
|
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||||
|
exit /b %EXIT_CODE%
|
||||||
|
|
||||||
:mainEnd
|
:mainEnd
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
package me.clip.placeholderapi;
|
package me.clip.placeholderapi;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -28,6 +29,7 @@ import java.util.Set;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||||
import me.clip.placeholderapi.expansion.Relational;
|
import me.clip.placeholderapi.expansion.Relational;
|
||||||
import me.clip.placeholderapi.expansion.manager.LocalExpansionManager;
|
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_PERCENT = new CharsReplacer(Closure.PERCENT);
|
||||||
private static final Replacer REPLACER_BRACKET = new CharsReplacer(Closure.BRACKET);
|
private static final Replacer REPLACER_BRACKET = new CharsReplacer(Closure.BRACKET);
|
||||||
|
|
||||||
private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("[%]([^%]+)[%]");
|
static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("[%]([^%]+)[%]");
|
||||||
private static final Pattern BRACKET_PLACEHOLDER_PATTERN = Pattern.compile("[{]([^{}]+)[}]");
|
static final Pattern BRACKET_PLACEHOLDER_PATTERN = Pattern.compile("[{]([^{}]+)[}]");
|
||||||
private static final Pattern RELATIONAL_PLACEHOLDER_PATTERN = Pattern
|
static final Pattern RELATIONAL_PLACEHOLDER_PATTERN = Pattern
|
||||||
.compile("[%](rel_)([^%]+)[%]");
|
.compile("[%](rel_)([^%]+)[%]");
|
||||||
|
|
||||||
|
|
||||||
@@ -136,8 +138,8 @@ public final class PlaceholderAPI {
|
|||||||
* @return String containing all translated placeholders
|
* @return String containing all translated placeholders
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public static List<String> setBracketPlaceholders(final OfflinePlayer player,
|
public static List<@NotNull String> setBracketPlaceholders(final OfflinePlayer player,
|
||||||
@NotNull final List<String> text) {
|
@NotNull final List<@NotNull String> text) {
|
||||||
return text.stream().map(line -> setBracketPlaceholders(player, line))
|
return text.stream().map(line -> setBracketPlaceholders(player, line))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
@@ -150,7 +152,8 @@ public final class PlaceholderAPI {
|
|||||||
* @param text Text to set the placeholder values in
|
* @param text Text to set the placeholder values in
|
||||||
* @return String containing all translated placeholders
|
* @return String containing all translated placeholders
|
||||||
*/
|
*/
|
||||||
public static String setBracketPlaceholders(Player player, String text) {
|
@NotNull
|
||||||
|
public static String setBracketPlaceholders(Player player, @NotNull String text) {
|
||||||
return setBracketPlaceholders((OfflinePlayer) player, text);
|
return setBracketPlaceholders((OfflinePlayer) player, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +165,8 @@ public final class PlaceholderAPI {
|
|||||||
* @param text List of Strings to set the placeholder values in
|
* @param text List of Strings to set the placeholder values in
|
||||||
* @return String containing all translated placeholders
|
* @return String containing all translated placeholders
|
||||||
*/
|
*/
|
||||||
public static List<String> setBracketPlaceholders(Player player, List<String> text) {
|
@NotNull
|
||||||
|
public static List<String> setBracketPlaceholders(Player player, @NotNull List<String> text) {
|
||||||
return setBracketPlaceholders((OfflinePlayer) player, text);
|
return setBracketPlaceholders((OfflinePlayer) player, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,24 +298,21 @@ public final class PlaceholderAPI {
|
|||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
public static boolean registerExpansion(PlaceholderExpansion expansion)
|
public static boolean registerExpansion(PlaceholderExpansion expansion) {
|
||||||
{
|
|
||||||
return expansion.register();
|
return expansion.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
public static boolean unregisterExpansion(PlaceholderExpansion expansion)
|
public static boolean unregisterExpansion(PlaceholderExpansion expansion) {
|
||||||
{
|
|
||||||
return expansion.unregister();
|
return expansion.unregister();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get map of registered placeholders
|
* Get map of registered placeholders
|
||||||
*
|
*
|
||||||
* @deprecated Use {@link LocalExpansionManager#getExpansions()} instead.
|
|
||||||
*
|
|
||||||
* @return Map of registered placeholders
|
* @return Map of registered placeholders
|
||||||
|
* @deprecated Use {@link LocalExpansionManager#getExpansions()} instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
@@ -322,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 plugin The Plugin to register with this {@link PlaceholderHook}
|
||||||
* @param placeholderHook The {@link PlaceholderHook} to register
|
* @param placeholderHook The {@link PlaceholderHook} to register
|
||||||
* @return always false
|
* @return always false
|
||||||
|
* @deprecated Please use {@link PlaceholderExpansion} to
|
||||||
|
* register placeholders instead
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
@@ -339,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 identifier The identifier to use for the {@link PlaceholderHook}
|
||||||
* @param placeholderHook The {@link PlaceholderHook} to register
|
* @param placeholderHook The {@link PlaceholderHook} to register
|
||||||
* @return always false
|
* @return always false
|
||||||
|
* @deprecated Please use {@link PlaceholderExpansion} to
|
||||||
|
* register placeholders instead
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
@@ -356,11 +355,10 @@ public final class PlaceholderAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Please use {@link PlaceholderExpansion} to
|
|
||||||
* unregister placeholders instead
|
|
||||||
*
|
|
||||||
* @param plugin The plugin to unregister
|
* @param plugin The plugin to unregister
|
||||||
* @return always false
|
* @return always false
|
||||||
|
* @deprecated Please use {@link PlaceholderExpansion} to
|
||||||
|
* unregister placeholders instead
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
@@ -372,11 +370,10 @@ public final class PlaceholderAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Please use {@link PlaceholderExpansion} to
|
|
||||||
* unregister placeholders instead
|
|
||||||
*
|
|
||||||
* @param identifier The identifier to unregister
|
* @param identifier The identifier to unregister
|
||||||
* @return always false
|
* @return always false
|
||||||
|
* @deprecated Please use {@link PlaceholderExpansion} to
|
||||||
|
* unregister placeholders instead
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
@@ -388,9 +385,8 @@ public final class PlaceholderAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Will be removed in a future release.
|
|
||||||
*
|
|
||||||
* @return Set of registered identifiers
|
* @return Set of registered identifiers
|
||||||
|
* @deprecated Will be removed in a future release.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
@@ -399,9 +395,8 @@ public final class PlaceholderAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Will be removed in a future release.
|
|
||||||
*
|
|
||||||
* @return always null
|
* @return always null
|
||||||
|
* @deprecated Will be removed in a future release.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
@@ -410,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 player The offline player to parse the placeholders against
|
||||||
* @param text The text to parse
|
* @param text The text to parse
|
||||||
* @param pattern The Pattern to use
|
* @param pattern The Pattern to use
|
||||||
* @param colorize If PlaceholderAPI should also parse color codes
|
* @param colorize If PlaceholderAPI should also parse color codes
|
||||||
* @return String with the parsed placeholders
|
* @return String with the parsed placeholders
|
||||||
|
* @deprecated Please use {@link #setPlaceholders(OfflinePlayer, String)} instead
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
@@ -426,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 player The offline player to parse the placeholders against
|
||||||
* @param text The List of text to parse
|
* @param text The List of text to parse
|
||||||
* @param pattern The Pattern to use
|
* @param pattern The Pattern to use
|
||||||
* @param colorize If PlaceholderAPI should also parse color codes
|
* @param colorize If PlaceholderAPI should also parse color codes
|
||||||
* @return String with the parsed placeholders
|
* @return String with the parsed placeholders
|
||||||
|
* @deprecated Please use {@link #setPlaceholders(OfflinePlayer, List)} instead
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
@@ -442,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 player The offline player to parse the placeholders against
|
||||||
* @param text The List of text to parse
|
* @param text The List of text to parse
|
||||||
* @param colorize If PlaceholderAPI should also parse color codes
|
* @param colorize If PlaceholderAPI should also parse color codes
|
||||||
* @return String with the parsed placeholders
|
* @return String with the parsed placeholders
|
||||||
|
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, List)} instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
@@ -457,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 player The offline player to parse the placeholders against
|
||||||
* @param text The List of text to parse
|
* @param text The List of text to parse
|
||||||
* @param pattern The Pattern to use
|
* @param pattern The Pattern to use
|
||||||
* @return String with the parsed placeholders
|
* @return String with the parsed placeholders
|
||||||
|
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, List)} instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
@@ -470,13 +461,13 @@ public final class PlaceholderAPI {
|
|||||||
Pattern pattern) {
|
Pattern pattern) {
|
||||||
return setPlaceholders(player, text);
|
return setPlaceholders(player, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Will be removed in a future release.
|
|
||||||
*
|
|
||||||
* @param player The offline player to parse the placeholders against
|
* @param player The offline player to parse the placeholders against
|
||||||
* @param text The text to parse
|
* @param text The text to parse
|
||||||
* @param colorize If PlaceholderAPI should also parse color codes
|
* @param colorize If PlaceholderAPI should also parse color codes
|
||||||
* @return String with the parsed placeholders
|
* @return String with the parsed placeholders
|
||||||
|
* @deprecated Will be removed in a future release.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
@@ -485,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 player The offline player to parse the placeholders against
|
||||||
* @param text The List of text to parse
|
* @param text The List of text to parse
|
||||||
* @param colorize If PlaceholderAPI should also parse color codes
|
* @param colorize If PlaceholderAPI should also parse color codes
|
||||||
* @return String with the parsed placeholders
|
* @return String with the parsed placeholders
|
||||||
|
* @deprecated Will be removed in a future release.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
@@ -499,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 player The offline player to parse the placeholders against
|
||||||
* @param text The text to parse
|
* @param text The text to parse
|
||||||
* @param colorize If PlaceholderAPI should also parse color codes
|
* @param colorize If PlaceholderAPI should also parse color codes
|
||||||
* @return String with the parsed placeholders
|
* @return String with the parsed placeholders
|
||||||
|
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, String)} instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
@@ -513,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 player The offline player to parse the placeholders against
|
||||||
* @param text The text to parse
|
* @param text The text to parse
|
||||||
* @param pattern The Pattern to use
|
* @param pattern The Pattern to use
|
||||||
* @return String with the parsed placeholders
|
* @return String with the parsed placeholders
|
||||||
|
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, String)} instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
@@ -527,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 player The offline player to parse the placeholders against
|
||||||
* @param text The List of text to parse
|
* @param text The List of text to parse
|
||||||
* @param colorize If PlaceholderAPI should also parse color codes
|
* @param colorize If PlaceholderAPI should also parse color codes
|
||||||
* @return String with the parsed placeholders
|
* @return String with the parsed placeholders
|
||||||
|
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, List)} instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
@@ -542,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 player The offline player to parse the placeholders against
|
||||||
* @param text The text to parse
|
* @param text The text to parse
|
||||||
* @param colorize If PlaceholderAPI should also parse color codes
|
* @param colorize If PlaceholderAPI should also parse color codes
|
||||||
* @return String with the parsed placeholders
|
* @return String with the parsed placeholders
|
||||||
|
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, String)} instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
@@ -556,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 player The offline player to parse the placeholders against
|
||||||
* @param text The text to parse
|
* @param text The text to parse
|
||||||
* @param colorize If PlaceholderAPI should also parse color codes
|
* @param colorize If PlaceholderAPI should also parse color codes
|
||||||
* @return String with the parsed placeholders
|
* @return String with the parsed placeholders
|
||||||
|
* @deprecated Will be removed in a future release.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
@@ -570,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 player The offline player to parse the placeholders against
|
||||||
* @param text The List of text to parse
|
* @param text The List of text to parse
|
||||||
* @param colorize If PlaceholderAPI should also parse color codes
|
* @param colorize If PlaceholderAPI should also parse color codes
|
||||||
* @return String with the parsed placeholders
|
* @return String with the parsed placeholders
|
||||||
|
* @deprecated Will be removed in a future release.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -23,6 +23,7 @@ package me.clip.placeholderapi;
|
|||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import me.clip.placeholderapi.commands.PlaceholderCommandRouter;
|
import me.clip.placeholderapi.commands.PlaceholderCommandRouter;
|
||||||
import me.clip.placeholderapi.configuration.PlaceholderAPIConfig;
|
import me.clip.placeholderapi.configuration.PlaceholderAPIConfig;
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||||
@@ -30,7 +31,10 @@ import me.clip.placeholderapi.expansion.Version;
|
|||||||
import me.clip.placeholderapi.expansion.manager.CloudExpansionManager;
|
import me.clip.placeholderapi.expansion.manager.CloudExpansionManager;
|
||||||
import me.clip.placeholderapi.expansion.manager.LocalExpansionManager;
|
import me.clip.placeholderapi.expansion.manager.LocalExpansionManager;
|
||||||
import me.clip.placeholderapi.listeners.ServerLoadEventListener;
|
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.updatechecker.UpdateChecker;
|
||||||
|
import me.clip.placeholderapi.util.ExpansionSafetyCheck;
|
||||||
import me.clip.placeholderapi.util.Msg;
|
import me.clip.placeholderapi.util.Msg;
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
import org.bstats.bukkit.Metrics;
|
import org.bstats.bukkit.Metrics;
|
||||||
@@ -40,6 +44,7 @@ import org.bukkit.Bukkit;
|
|||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.PluginCommand;
|
import org.bukkit.command.PluginCommand;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@@ -55,7 +60,17 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
|||||||
private static PlaceholderAPIPlugin instance;
|
private static PlaceholderAPIPlugin instance;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
final String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
|
String version = Bukkit.getServer().getBukkitVersion().split("-")[0];
|
||||||
|
String suffix;
|
||||||
|
if (version.chars()
|
||||||
|
.filter(c -> c == '.')
|
||||||
|
.count() == 1) {
|
||||||
|
suffix = "R1";
|
||||||
|
version = 'v' + version.replace('.', '_') + '_' + suffix;
|
||||||
|
} else {
|
||||||
|
int minor = Integer.parseInt(version.split("\\.")[2].charAt(0) + "");
|
||||||
|
version = 'v' + version.replace('.', '_').replace("_" + minor, "") + '_' + "R" + (minor - 1);
|
||||||
|
}
|
||||||
|
|
||||||
boolean isSpigot;
|
boolean isSpigot;
|
||||||
try {
|
try {
|
||||||
@@ -75,8 +90,12 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
|||||||
private final LocalExpansionManager localExpansionManager = new LocalExpansionManager(this);
|
private final LocalExpansionManager localExpansionManager = new LocalExpansionManager(this);
|
||||||
@NotNull
|
@NotNull
|
||||||
private final CloudExpansionManager cloudExpansionManager = new CloudExpansionManager(this);
|
private final CloudExpansionManager cloudExpansionManager = new CloudExpansionManager(this);
|
||||||
|
@NotNull
|
||||||
|
private final TaskScheduler scheduler = UniversalScheduler.getScheduler(this);
|
||||||
|
|
||||||
private BukkitAudiences adventure;
|
private BukkitAudiences adventure;
|
||||||
|
private boolean safetyCheck = false;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the static instance of the main class for PlaceholderAPI. This class is not the actual API
|
* Gets the static instance of the main class for PlaceholderAPI. This class is not the actual API
|
||||||
@@ -127,19 +146,30 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public static Version getServerVersion() {
|
public static Version getServerVersion() {
|
||||||
return VERSION;
|
return VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
instance = this;
|
|
||||||
|
|
||||||
saveDefaultConfig();
|
saveDefaultConfig();
|
||||||
|
|
||||||
|
safetyCheck = new ExpansionSafetyCheck(this).runChecks();
|
||||||
|
|
||||||
|
if (safetyCheck) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
|
if (safetyCheck) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setupCommand();
|
setupCommand();
|
||||||
setupMetrics();
|
setupMetrics();
|
||||||
setupExpansions();
|
setupExpansions();
|
||||||
@@ -157,12 +187,16 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
|
if (safetyCheck) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
getCloudExpansionManager().kill();
|
getCloudExpansionManager().kill();
|
||||||
getLocalExpansionManager().kill();
|
getLocalExpansionManager().kill();
|
||||||
|
|
||||||
HandlerList.unregisterAll(this);
|
HandlerList.unregisterAll(this);
|
||||||
|
|
||||||
Bukkit.getScheduler().cancelTasks(this);
|
scheduler.cancelTasks(this);
|
||||||
|
|
||||||
adventure.close();
|
adventure.close();
|
||||||
adventure = null;
|
adventure = null;
|
||||||
@@ -196,13 +230,18 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public BukkitAudiences getAdventure() {
|
public BukkitAudiences getAdventure() {
|
||||||
if(adventure == null) {
|
if (adventure == null) {
|
||||||
throw new IllegalStateException("Tried to access Adventure when the plugin was disabled!");
|
throw new IllegalStateException("Tried to access Adventure when the plugin was disabled!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return adventure;
|
return adventure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public TaskScheduler getScheduler() {
|
||||||
|
return scheduler;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain the configuration class for PlaceholderAPI.
|
* Obtain the configuration class for PlaceholderAPI.
|
||||||
*
|
*
|
||||||
@@ -250,8 +289,8 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
|||||||
Class.forName("org.bukkit.event.server.ServerLoadEvent");
|
Class.forName("org.bukkit.event.server.ServerLoadEvent");
|
||||||
new ServerLoadEventListener(this);
|
new ServerLoadEventListener(this);
|
||||||
} catch (final ClassNotFoundException ignored) {
|
} catch (final ClassNotFoundException ignored) {
|
||||||
Bukkit.getScheduler()
|
scheduler
|
||||||
.runTaskLater(this, () -> getLocalExpansionManager().load(Bukkit.getConsoleSender()), 1);
|
.runTaskLater(() -> getLocalExpansionManager().load(Bukkit.getConsoleSender()), 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -29,7 +29,7 @@ public abstract class PlaceholderHook {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public String onRequest(final OfflinePlayer player, @NotNull final String params) {
|
public String onRequest(final OfflinePlayer player, @NotNull final String params) {
|
||||||
if (player != null && player.isOnline()) {
|
if (player != null && player.isOnline()) {
|
||||||
return onPlaceholderRequest((Player) player, params);
|
return onPlaceholderRequest(player.getPlayer(), params);
|
||||||
}
|
}
|
||||||
|
|
||||||
return onPlaceholderRequest(null, params);
|
return onPlaceholderRequest(null, params);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* 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.ImmutableSet;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* 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.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -30,6 +31,8 @@ import java.util.List;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import me.clip.placeholderapi.commands.impl.cloud.CommandECloud;
|
import me.clip.placeholderapi.commands.impl.cloud.CommandECloud;
|
||||||
import me.clip.placeholderapi.commands.impl.local.CommandDump;
|
import me.clip.placeholderapi.commands.impl.local.CommandDump;
|
||||||
@@ -117,14 +120,18 @@ public final class PlaceholderCommandRouter implements CommandExecutor, TabCompl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(@NotNull final CommandSender sender,
|
public List<String> onTabComplete(@NotNull final CommandSender sender, @NotNull final Command command,
|
||||||
@NotNull final Command command, @NotNull final String alias, @NotNull final String[] args) {
|
@NotNull final String alias, @NotNull final String[] args) {
|
||||||
final List<String> suggestions = new ArrayList<>();
|
final List<String> suggestions = new ArrayList<>();
|
||||||
|
|
||||||
if (args.length > 1) {
|
if (args.length > 1) {
|
||||||
final PlaceholderCommand target = this.commands.get(args[0].toLowerCase(Locale.ROOT));
|
final PlaceholderCommand target = this.commands.get(args[0].toLowerCase(Locale.ROOT));
|
||||||
|
|
||||||
if (target != null) {
|
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),
|
target.complete(plugin, sender, args[0].toLowerCase(Locale.ROOT),
|
||||||
Arrays.asList(Arrays.copyOfRange(args, 1, args.length)), suggestions);
|
Arrays.asList(Arrays.copyOfRange(args, 1, args.length)), suggestions);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -118,6 +118,11 @@ public final class CommandECloud extends PlaceholderCommand {
|
|||||||
return;
|
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()));
|
target.evaluate(plugin, sender, search, params.subList(1, params.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
package me.clip.placeholderapi.commands.impl.cloud;
|
package me.clip.placeholderapi.commands.impl.cloud;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||||
import me.clip.placeholderapi.util.Msg;
|
import me.clip.placeholderapi.util.Msg;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -20,9 +20,11 @@
|
|||||||
|
|
||||||
package me.clip.placeholderapi.commands.impl.cloud;
|
package me.clip.placeholderapi.commands.impl.cloud;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||||
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
||||||
@@ -37,6 +39,16 @@ public final class CommandECloudDownload extends PlaceholderCommand {
|
|||||||
super("download");
|
super("download");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isBlockedExpansion(String name) {
|
||||||
|
String env = System.getenv("PAPI_BLOCKED_EXPANSIONS");
|
||||||
|
if (env == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Arrays.stream(env.split(","))
|
||||||
|
.anyMatch(s -> s.equalsIgnoreCase(name));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
|
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
|
||||||
@NotNull final CommandSender sender, @NotNull final String alias,
|
@NotNull final CommandSender sender, @NotNull final String alias,
|
||||||
@@ -47,6 +59,12 @@ public final class CommandECloudDownload extends PlaceholderCommand {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isBlockedExpansion(params.get(0))) {
|
||||||
|
Msg.msg(sender,
|
||||||
|
"&cThis expansion can't be downloaded.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final CloudExpansion expansion = plugin.getCloudExpansionManager()
|
final CloudExpansion expansion = plugin.getCloudExpansionManager()
|
||||||
.findCloudExpansionByName(params.get(0)).orElse(null);
|
.findCloudExpansionByName(params.get(0)).orElse(null);
|
||||||
if (expansion == null) {
|
if (expansion == null) {
|
||||||
@@ -73,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)
|
plugin.getCloudExpansionManager().downloadExpansion(expansion, version)
|
||||||
.whenComplete((file, exception) -> {
|
.whenComplete((file, exception) -> {
|
||||||
if (exception != null) {
|
if (exception != null) {
|
||||||
@@ -86,9 +109,7 @@ public final class CommandECloudDownload extends PlaceholderCommand {
|
|||||||
.getVersion() + "] &ato file: &f" + file.getName(),
|
.getVersion() + "] &ato file: &f" + file.getName(),
|
||||||
"&aMake sure to type &f/papi reload &ato enable your new expansion!");
|
"&aMake sure to type &f/papi reload &ato enable your new expansion!");
|
||||||
|
|
||||||
plugin.getCloudExpansionManager().clean();
|
plugin.getCloudExpansionManager().load();
|
||||||
plugin.getCloudExpansionManager()
|
|
||||||
.fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions());
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* 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.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||||
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
||||||
@@ -63,9 +64,6 @@ public final class CommandECloudExpansionInfo extends PlaceholderCommand {
|
|||||||
.append('\n')
|
.append('\n')
|
||||||
.append("&bAuthor: &f")
|
.append("&bAuthor: &f")
|
||||||
.append(expansion.getAuthor())
|
.append(expansion.getAuthor())
|
||||||
.append('\n')
|
|
||||||
.append("&bVerified: ")
|
|
||||||
.append(expansion.isVerified() ? "&a&l✔" : "&c&l❌")
|
|
||||||
.append('\n');
|
.append('\n');
|
||||||
|
|
||||||
if (params.size() < 2) {
|
if (params.size() < 2) {
|
||||||
@@ -76,6 +74,9 @@ public final class CommandECloudExpansionInfo extends PlaceholderCommand {
|
|||||||
.append(expansion.getTimeSinceLastUpdate())
|
.append(expansion.getTimeSinceLastUpdate())
|
||||||
.append(" ago")
|
.append(" ago")
|
||||||
.append('\n')
|
.append('\n')
|
||||||
|
.append("&bVerified: ")
|
||||||
|
.append(expansion.getVersion().isVerified() ? "&a&l✔" : "&c&l❌")
|
||||||
|
.append('\n')
|
||||||
.append("&bRelease Notes: &f")
|
.append("&bRelease Notes: &f")
|
||||||
.append(expansion.getVersion().getReleaseNotes())
|
.append(expansion.getVersion().getReleaseNotes())
|
||||||
.append('\n');
|
.append('\n');
|
||||||
@@ -91,6 +92,9 @@ public final class CommandECloudExpansionInfo extends PlaceholderCommand {
|
|||||||
builder.append("&bVersion: &f")
|
builder.append("&bVersion: &f")
|
||||||
.append(version.getVersion())
|
.append(version.getVersion())
|
||||||
.append('\n')
|
.append('\n')
|
||||||
|
.append("&bVerified: ")
|
||||||
|
.append(version.isVerified() ? "&a&l✔" : "&c&l❌")
|
||||||
|
.append('\n')
|
||||||
.append("&bRelease Notes: &f")
|
.append("&bRelease Notes: &f")
|
||||||
.append(version.getReleaseNotes())
|
.append(version.getReleaseNotes())
|
||||||
.append('\n')
|
.append('\n')
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* 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.Lists;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.google.common.primitives.Ints;
|
import com.google.common.primitives.Ints;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||||
import me.clip.placeholderapi.configuration.ExpansionSort;
|
import me.clip.placeholderapi.configuration.ExpansionSort;
|
||||||
@@ -65,7 +67,7 @@ public final class CommandECloudExpansionList extends PlaceholderCommand {
|
|||||||
expansion -> "&f" + expansion.getAuthor();
|
expansion -> "&f" + expansion.getAuthor();
|
||||||
@NotNull
|
@NotNull
|
||||||
private static final Function<CloudExpansion, Object> EXPANSION_VERIFIED =
|
private static final Function<CloudExpansion, Object> EXPANSION_VERIFIED =
|
||||||
expansion -> expansion.isVerified() ? "&aY" : "&cN";
|
expansion -> expansion.getVersion().isVerified() ? "&aY" : "&cN";
|
||||||
@NotNull
|
@NotNull
|
||||||
private static final Function<CloudExpansion, Object> EXPANSION_LATEST_VERSION =
|
private static final Function<CloudExpansion, Object> EXPANSION_LATEST_VERSION =
|
||||||
expansion -> "&f" + expansion.getLatestVersion();
|
expansion -> "&f" + expansion.getLatestVersion();
|
||||||
@@ -168,7 +170,9 @@ public final class CommandECloudExpansionList extends PlaceholderCommand {
|
|||||||
.append(newline()).append(newline())
|
.append(newline()).append(newline())
|
||||||
.append(text("Author: ", AQUA)).append(text(expansion.getAuthor(), WHITE))
|
.append(text("Author: ", AQUA)).append(text(expansion.getAuthor(), WHITE))
|
||||||
.append(newline())
|
.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(newline())
|
||||||
.append(text("Released: ", AQUA)).append(text(format.format(expansion.getLastUpdate()), WHITE))
|
.append(text("Released: ", AQUA)).append(text(format.format(expansion.getLastUpdate()), WHITE))
|
||||||
.toBuilder();
|
.toBuilder();
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,9 +21,11 @@
|
|||||||
package me.clip.placeholderapi.commands.impl.cloud;
|
package me.clip.placeholderapi.commands.impl.cloud;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||||
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
package me.clip.placeholderapi.commands.impl.cloud;
|
package me.clip.placeholderapi.commands.impl.cloud;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||||
import me.clip.placeholderapi.util.Msg;
|
import me.clip.placeholderapi.util.Msg;
|
||||||
@@ -38,9 +39,7 @@ public final class CommandECloudRefresh extends PlaceholderCommand {
|
|||||||
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
|
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
|
||||||
@NotNull final CommandSender sender, @NotNull final String alias,
|
@NotNull final CommandSender sender, @NotNull final String alias,
|
||||||
@NotNull @Unmodifiable final List<String> params) {
|
@NotNull @Unmodifiable final List<String> params) {
|
||||||
plugin.getCloudExpansionManager().clean();
|
plugin.getCloudExpansionManager().load();
|
||||||
plugin.getCloudExpansionManager()
|
|
||||||
.fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions());
|
|
||||||
|
|
||||||
Msg.msg(sender,
|
Msg.msg(sender,
|
||||||
"&aThe eCloud manager has been refreshed!");
|
"&aThe eCloud manager has been refreshed!");
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
package me.clip.placeholderapi.commands.impl.cloud;
|
package me.clip.placeholderapi.commands.impl.cloud;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||||
import me.clip.placeholderapi.expansion.manager.CloudExpansionManager;
|
import me.clip.placeholderapi.expansion.manager.CloudExpansionManager;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
package me.clip.placeholderapi.commands.impl.cloud;
|
package me.clip.placeholderapi.commands.impl.cloud;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@@ -28,6 +29,7 @@ import java.util.Objects;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -200,7 +200,9 @@ public final class CommandDump extends PlaceholderCommand {
|
|||||||
for (final Plugin other : plugins) {
|
for (final Plugin other : plugins) {
|
||||||
builder.append(" ")
|
builder.append(" ")
|
||||||
.append(String.format("%-" + size + "s", other.getName()))
|
.append(String.format("%-" + size + "s", other.getName()))
|
||||||
.append(" [Version: ")
|
.append(" [Authors: [")
|
||||||
|
.append(String.join(", ", other.getDescription().getAuthors()))
|
||||||
|
.append("], Version: ")
|
||||||
.append(other.getDescription().getVersion())
|
.append(other.getDescription().getVersion())
|
||||||
.append("]")
|
.append("]")
|
||||||
.append("\n");
|
.append("\n");
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* 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.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||||
@@ -54,7 +55,7 @@ public final class CommandExpansionRegister extends PlaceholderCommand {
|
|||||||
final LocalExpansionManager manager = plugin.getLocalExpansionManager();
|
final LocalExpansionManager manager = plugin.getLocalExpansionManager();
|
||||||
|
|
||||||
final File file = new File(manager.getExpansionsFolder(), params.get(0));
|
final File file = new File(manager.getExpansionsFolder(), params.get(0));
|
||||||
if (!file.exists()) {
|
if (!file.exists() || !file.getParentFile().equals(manager.getExpansionsFolder())) {
|
||||||
Msg.msg(sender,
|
Msg.msg(sender,
|
||||||
"&cThe file &f" + file.getName() + "&c doesn't exist!");
|
"&cThe file &f" + file.getName() + "&c doesn't exist!");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* 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.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPI;
|
import me.clip.placeholderapi.PlaceholderAPI;
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
package me.clip.placeholderapi.commands.impl.local;
|
package me.clip.placeholderapi.commands.impl.local;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||||
import me.clip.placeholderapi.util.Msg;
|
import me.clip.placeholderapi.util.Msg;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
package me.clip.placeholderapi.commands.impl.local;
|
package me.clip.placeholderapi.commands.impl.local;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPI;
|
import me.clip.placeholderapi.PlaceholderAPI;
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,9 +21,11 @@
|
|||||||
package me.clip.placeholderapi.commands.impl.local;
|
package me.clip.placeholderapi.commands.impl.local;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPI;
|
import me.clip.placeholderapi.PlaceholderAPI;
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* 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.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPI;
|
import me.clip.placeholderapi.PlaceholderAPI;
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||||
@@ -87,7 +88,8 @@ public final class CommandParse extends PlaceholderCommand {
|
|||||||
final boolean command) {
|
final boolean command) {
|
||||||
if (params.size() < 2) {
|
if (params.size() < 2) {
|
||||||
Msg.msg(sender,
|
Msg.msg(sender,
|
||||||
"&cYou must supply a target, and a message: &b/papi " + (broadcast ? "bcparse" : "parse")
|
"&cYou must provide a target and message: &b/papi "
|
||||||
|
+ (command ? "cmdparse" : (broadcast ? "bcparse" : "parse"))
|
||||||
+ " &7{target} &a{message}");
|
+ " &7{target} &a{message}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -132,24 +134,49 @@ public final class CommandParse extends PlaceholderCommand {
|
|||||||
@NotNull @Unmodifiable final List<String> params) {
|
@NotNull @Unmodifiable final List<String> params) {
|
||||||
if (params.size() < 3) {
|
if (params.size() < 3) {
|
||||||
Msg.msg(sender,
|
Msg.msg(sender,
|
||||||
"&cYou must supply two targets, and a message: &b/papi parserel &7{target one} {target two} &a{message}");
|
"&cYou must supply two targets, and a message: &b/papi parserel &7{target one} "
|
||||||
|
+ "{target two} &a{message}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final OfflinePlayer targetOne = resolvePlayer(params.get(0));
|
OfflinePlayer playerOne;
|
||||||
if (targetOne == null || !targetOne.isOnline()) {
|
|
||||||
|
if ("me".equalsIgnoreCase(params.get(0))) {
|
||||||
|
if (!(sender instanceof Player)) {
|
||||||
|
Msg.msg(sender, "&cYou must be a player to use &7me&c as a target!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
playerOne = ((Player) sender);
|
||||||
|
} else {
|
||||||
|
playerOne = resolvePlayer(params.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (playerOne == null || !playerOne.isOnline()) {
|
||||||
Msg.msg(sender, "&cFailed to find player: &f" + params.get(0));
|
Msg.msg(sender, "&cFailed to find player: &f" + params.get(0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final OfflinePlayer targetTwo = resolvePlayer(params.get(1));
|
OfflinePlayer playerTwo;
|
||||||
if (targetTwo == null || !targetTwo.isOnline()) {
|
|
||||||
|
if ("me".equalsIgnoreCase(params.get(1))) {
|
||||||
|
if (!(sender instanceof Player)) {
|
||||||
|
Msg.msg(sender, "&cYou must be a player to use &7me&c as a target!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
playerTwo = ((Player) sender);
|
||||||
|
} else {
|
||||||
|
playerTwo = resolvePlayer(params.get(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (playerTwo == null || !playerTwo.isOnline()) {
|
||||||
Msg.msg(sender, "&cFailed to find player: &f" + params.get(1));
|
Msg.msg(sender, "&cFailed to find player: &f" + params.get(1));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String message = PlaceholderAPI
|
final String message = PlaceholderAPI
|
||||||
.setRelationalPlaceholders(((Player) targetOne), ((Player) targetTwo),
|
.setRelationalPlaceholders((Player) playerOne, (Player) playerTwo,
|
||||||
String.join(" ", params.subList(2, params.size())));
|
String.join(" ", params.subList(2, params.size())));
|
||||||
|
|
||||||
sender.sendMessage(message);
|
sender.sendMessage(message);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,8 +21,10 @@
|
|||||||
package me.clip.placeholderapi.commands.impl.local;
|
package me.clip.placeholderapi.commands.impl.local;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||||
|
import me.clip.placeholderapi.util.ExpansionSafetyCheck;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Unmodifiable;
|
import org.jetbrains.annotations.Unmodifiable;
|
||||||
@@ -37,7 +39,9 @@ public final class CommandReload extends PlaceholderCommand {
|
|||||||
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
|
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
|
||||||
@NotNull final CommandSender sender, @NotNull final String alias,
|
@NotNull final CommandSender sender, @NotNull final String alias,
|
||||||
@NotNull @Unmodifiable final List<String> params) {
|
@NotNull @Unmodifiable final List<String> params) {
|
||||||
|
if (!new ExpansionSafetyCheck(plugin).runChecks()) {
|
||||||
plugin.reloadConf(sender);
|
plugin.reloadConf(sender);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
package me.clip.placeholderapi.commands.impl.local;
|
package me.clip.placeholderapi.commands.impl.local;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
import me.clip.placeholderapi.commands.PlaceholderCommand;
|
||||||
import me.clip.placeholderapi.util.Msg;
|
import me.clip.placeholderapi.util.Msg;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
package me.clip.placeholderapi.configuration;
|
package me.clip.placeholderapi.configuration;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
package me.clip.placeholderapi.configuration;
|
package me.clip.placeholderapi.configuration;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@@ -38,10 +39,6 @@ public final class PlaceholderAPIConfig {
|
|||||||
return plugin.getConfig().getBoolean("check_updates");
|
return plugin.getConfig().getBoolean("check_updates");
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean cloudAllowUnverifiedExpansions() {
|
|
||||||
return plugin.getConfig().getBoolean("cloud_allow_unverified_expansions");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isCloudEnabled() {
|
public boolean isCloudEnabled() {
|
||||||
return plugin.getConfig().getBoolean("cloud_enabled");
|
return plugin.getConfig().getBoolean("cloud_enabled");
|
||||||
@@ -57,6 +54,10 @@ public final class PlaceholderAPIConfig {
|
|||||||
return plugin.getConfig().getBoolean("debug", false);
|
return plugin.getConfig().getBoolean("debug", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean useAdventureReplacer() {
|
||||||
|
return plugin.getConfig().getBoolean("use_adventure_provided_replacer", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public Optional<ExpansionSort> getExpansionSort() {
|
public Optional<ExpansionSort> getExpansionSort() {
|
||||||
final String option = plugin.getConfig()
|
final String option = plugin.getConfig()
|
||||||
@@ -90,4 +91,11 @@ public final class PlaceholderAPIConfig {
|
|||||||
return plugin.getConfig().getString("boolean.false", "false");
|
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
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* 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.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
@@ -53,7 +54,7 @@ public class ExpansionsLoadedEvent extends Event {
|
|||||||
* @return List of {@link PlaceholderExpansion registered PlaceholderExpansions}.
|
* @return List of {@link PlaceholderExpansion registered PlaceholderExpansions}.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public final List<PlaceholderExpansion> getExpansions(){
|
public final List<PlaceholderExpansion> getExpansions() {
|
||||||
return expansions;
|
return expansions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -46,7 +46,17 @@ public enum NMSVersion {
|
|||||||
SPIGOT_1_18_R1("v1_18_R1"),
|
SPIGOT_1_18_R1("v1_18_R1"),
|
||||||
SPIGOT_1_19_R1("v1_19_R1"),
|
SPIGOT_1_19_R1("v1_19_R1"),
|
||||||
SPIGOT_1_19_R2("v1_19_R2"),
|
SPIGOT_1_19_R2("v1_19_R2"),
|
||||||
SPIGOT_1_19_R3("v1_19_R3");
|
SPIGOT_1_19_R3("v1_19_R3"),
|
||||||
|
SPIGOT_1_20_R1("v1_20_R1"),
|
||||||
|
SPIGOT_1_20_R2("v1_20_R2"),
|
||||||
|
SPIGOT_1_20_R3("v1_20_R3"),
|
||||||
|
SPIGOT_1_20_R4("v1_20_R4"),
|
||||||
|
SPIGOT_1_21_R1("v1_21_R1"),
|
||||||
|
SPIGOT_1_21_R2("V1_21_R2"),
|
||||||
|
SPIGOT_1_21_R3("V1_21_R3"),
|
||||||
|
SPIGOT_1_21_R4("V1_21_R4"),
|
||||||
|
SPIGOT_1_21_R5("V1_21_R5"),
|
||||||
|
SPIGOT_1_21_R6("V1_21_R6");
|
||||||
|
|
||||||
private final String version;
|
private final String version;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* 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.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import me.clip.placeholderapi.PlaceholderHook;
|
import me.clip.placeholderapi.PlaceholderHook;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@@ -40,6 +41,15 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
*/
|
*/
|
||||||
public abstract class PlaceholderExpansion extends PlaceholderHook {
|
public abstract class PlaceholderExpansion extends PlaceholderHook {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type is {@link Type#INTERNAL} by default.
|
||||||
|
* For external expansions, the type is updated on {@link me.clip.placeholderapi.expansion.manager.LocalExpansionManager#register(Class) register}.
|
||||||
|
*
|
||||||
|
* @since 2.11.4
|
||||||
|
*/
|
||||||
|
@ApiStatus.Internal
|
||||||
|
protected Type expansionType = Type.INTERNAL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The placeholder identifier of this expansion. May not contain {@literal %},
|
* The placeholder identifier of this expansion. May not contain {@literal %},
|
||||||
* {@literal {}} or _
|
* {@literal {}} or _
|
||||||
@@ -159,6 +169,28 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
|
|||||||
return PlaceholderAPIPlugin.getInstance();
|
return PlaceholderAPIPlugin.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type of the expansion
|
||||||
|
*
|
||||||
|
* @return the type of the expansion
|
||||||
|
* @since 2.11.4
|
||||||
|
*/
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public Type getExpansionType() {
|
||||||
|
return expansionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the type of the expansion
|
||||||
|
*
|
||||||
|
* @param expansionType the new type
|
||||||
|
* @since 2.11.4
|
||||||
|
*/
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public void setExpansionType(Type expansionType) {
|
||||||
|
this.expansionType = expansionType;
|
||||||
|
}
|
||||||
|
|
||||||
// === Configuration ===
|
// === Configuration ===
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -166,7 +198,7 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
|
|||||||
* null when not specified.
|
* null when not specified.
|
||||||
* <br>You may use the {@link Configurable} interface to define default values set
|
* <br>You may use the {@link Configurable} interface to define default values set
|
||||||
*
|
*
|
||||||
* @return ConfigurationSection that this epxpansion has.
|
* @return ConfigurationSection that this expansion has.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public final ConfigurationSection getConfigSection() {
|
public final ConfigurationSection getConfigSection() {
|
||||||
@@ -394,16 +426,15 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final String toString() {
|
public final String toString() {
|
||||||
return String.format("PlaceholderExpansion[name: '%s', author: '%s', version: '%s']", getName(),
|
return String.format("PlaceholderExpansion[name: '%s', author: '%s', version: '%s', type: '%s']", getName(),
|
||||||
getAuthor(), getVersion());
|
getAuthor(), getVersion(), getExpansionType());
|
||||||
}
|
}
|
||||||
|
|
||||||
// === Deprecated API ===
|
// === Deprecated API ===
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated As of versions greater than 2.8.7, use {@link #getRequiredPlugin()}
|
|
||||||
*
|
|
||||||
* @return The plugin name.
|
* @return The plugin name.
|
||||||
|
* @deprecated As of versions greater than 2.8.7, use {@link #getRequiredPlugin()}
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
@@ -412,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.
|
* @return The description of the expansion.
|
||||||
|
* @deprecated As of versions greater than 2.8.7, use the expansion cloud to show a description
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
@@ -423,13 +453,27 @@ 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.
|
* @return The link for the expansion.
|
||||||
|
* @deprecated As of versions greater than 2.8.7, use the expansion cloud to display a link
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
|
||||||
public String getLink() {
|
public String getLink() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum Type {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An expansion provided by a plugin is considered internal
|
||||||
|
*/
|
||||||
|
INTERNAL,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An expansion loaded from the expansions folder is considered external
|
||||||
|
*/
|
||||||
|
EXTERNAL
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
package me.clip.placeholderapi.expansion;
|
package me.clip.placeholderapi.expansion;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public final class Version {
|
public final class Version {
|
||||||
|
|
||||||
private final boolean isSpigot;
|
private final boolean isSpigot;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -27,7 +27,9 @@ package me.clip.placeholderapi.expansion;
|
|||||||
* with that version.
|
* with that version.
|
||||||
*
|
*
|
||||||
* @author Ryan McCarthy
|
* @author Ryan McCarthy
|
||||||
|
* @deprecated Will be removed in a future release.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public interface VersionSpecific {
|
public interface VersionSpecific {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -35,7 +37,6 @@ public interface VersionSpecific {
|
|||||||
* will be passed to this method so you know what version the server is currently running.
|
* will be passed to this method so you know what version the server is currently running.
|
||||||
*
|
*
|
||||||
* @param v The {@link Version} to check against
|
* @param v The {@link Version} to check against
|
||||||
*
|
|
||||||
* @return true if your expansion is compatible with the version the server is running.
|
* @return true if your expansion is compatible with the version the server is running.
|
||||||
*/
|
*/
|
||||||
boolean isCompatibleWith(Version v);
|
boolean isCompatibleWith(Version v);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* 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.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import me.clip.placeholderapi.util.TimeUtil;
|
import me.clip.placeholderapi.util.TimeUtil;
|
||||||
|
|
||||||
|
|
||||||
@@ -36,8 +37,7 @@ public class CloudExpansion {
|
|||||||
dependency_url;
|
dependency_url;
|
||||||
|
|
||||||
private boolean hasExpansion,
|
private boolean hasExpansion,
|
||||||
shouldUpdate,
|
shouldUpdate;
|
||||||
verified;
|
|
||||||
|
|
||||||
private long last_update,
|
private long last_update,
|
||||||
ratings_count;
|
ratings_count;
|
||||||
@@ -135,10 +135,6 @@ public class CloudExpansion {
|
|||||||
this.shouldUpdate = shouldUpdate;
|
this.shouldUpdate = shouldUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isVerified() {
|
|
||||||
return verified;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getLastUpdate() {
|
public long getLastUpdate() {
|
||||||
return last_update;
|
return last_update;
|
||||||
}
|
}
|
||||||
@@ -174,6 +170,7 @@ public class CloudExpansion {
|
|||||||
public static class Version {
|
public static class Version {
|
||||||
|
|
||||||
private String url, version, release_notes;
|
private String url, version, release_notes;
|
||||||
|
private boolean verified;
|
||||||
|
|
||||||
public String getUrl() {
|
public String getUrl() {
|
||||||
return url;
|
return url;
|
||||||
@@ -198,5 +195,13 @@ public class CloudExpansion {
|
|||||||
public void setReleaseNotes(String release_notes) {
|
public void setReleaseNotes(String release_notes) {
|
||||||
this.release_notes = 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
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* 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.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
import java.nio.channels.Channels;
|
import java.nio.channels.Channels;
|
||||||
import java.nio.channels.ReadableByteChannel;
|
import java.nio.channels.ReadableByteChannel;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
@@ -50,6 +52,7 @@ import java.util.function.Function;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collector;
|
import java.util.stream.Collector;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||||
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
||||||
@@ -60,7 +63,7 @@ import org.jetbrains.annotations.Unmodifiable;
|
|||||||
public final class CloudExpansionManager {
|
public final class CloudExpansionManager {
|
||||||
|
|
||||||
@NotNull
|
@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
|
@NotNull
|
||||||
private static final Gson GSON = new Gson();
|
private static final Gson GSON = new Gson();
|
||||||
@@ -100,7 +103,7 @@ public final class CloudExpansionManager {
|
|||||||
|
|
||||||
public void load() {
|
public void load() {
|
||||||
clean();
|
clean();
|
||||||
fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions());
|
fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void kill() {
|
public void kill() {
|
||||||
@@ -113,6 +116,10 @@ public final class CloudExpansionManager {
|
|||||||
return ImmutableMap.copyOf(cache);
|
return ImmutableMap.copyOf(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return cache.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Unmodifiable
|
@Unmodifiable
|
||||||
public Map<String, CloudExpansion> getCloudExpansionsInstalled() {
|
public Map<String, CloudExpansion> getCloudExpansionsInstalled() {
|
||||||
@@ -170,7 +177,7 @@ public final class CloudExpansionManager {
|
|||||||
await.clear();
|
await.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fetch(final boolean allowUnverified) {
|
public void fetch() {
|
||||||
plugin.getLogger().info("Fetching available expansion information...");
|
plugin.getLogger().info("Fetching available expansion information...");
|
||||||
|
|
||||||
ASYNC_EXECUTOR.submit(
|
ASYNC_EXECUTOR.submit(
|
||||||
@@ -190,25 +197,22 @@ public final class CloudExpansionManager {
|
|||||||
|| expansion.getVersion(expansion.getLatestVersion()) == null) {
|
|| expansion.getVersion(expansion.getLatestVersion()) == null) {
|
||||||
toRemove.add(entry.getKey());
|
toRemove.add(entry.getKey());
|
||||||
}
|
}
|
||||||
if (!allowUnverified && !expansion.isVerified()) {
|
|
||||||
toRemove.add(entry.getKey());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String name : toRemove) {
|
for (String name : toRemove) {
|
||||||
values.remove(name);
|
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) {
|
} catch (Throwable e) {
|
||||||
// ugly swallowing of every throwable, but we have to be defensive
|
// ugly swallowing of every throwable, but we have to be defensive
|
||||||
plugin.getLogger().log(Level.WARNING, "Failed to download expansion information", e);
|
plugin.getLogger().log(Level.WARNING, "Failed to download expansion information", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop thru what's left on the main thread
|
// loop through what's left on the main thread
|
||||||
plugin
|
plugin
|
||||||
.getServer()
|
|
||||||
.getScheduler()
|
.getScheduler()
|
||||||
.runTask(
|
.runTask(
|
||||||
plugin,
|
|
||||||
() -> {
|
() -> {
|
||||||
try {
|
try {
|
||||||
for (Map.Entry<String, CloudExpansion> entry : values.entrySet()) {
|
for (Map.Entry<String, CloudExpansion> entry : values.entrySet()) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* 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.ImmutableSet;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -34,10 +35,11 @@ import java.util.Objects;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.CompletionException;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import me.clip.placeholderapi.events.ExpansionRegisterEvent;
|
import me.clip.placeholderapi.events.ExpansionRegisterEvent;
|
||||||
import me.clip.placeholderapi.events.ExpansionUnregisterEvent;
|
import me.clip.placeholderapi.events.ExpansionUnregisterEvent;
|
||||||
@@ -172,7 +174,7 @@ public final class LocalExpansionManager implements Listener {
|
|||||||
try {
|
try {
|
||||||
final PlaceholderExpansion expansion = createExpansionInstance(clazz);
|
final PlaceholderExpansion expansion = createExpansionInstance(clazz);
|
||||||
|
|
||||||
if(expansion == null){
|
if (expansion == null) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,6 +190,8 @@ public final class LocalExpansionManager implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expansion.setExpansionType(PlaceholderExpansion.Type.EXTERNAL);
|
||||||
|
|
||||||
if (!expansion.register()) {
|
if (!expansion.register()) {
|
||||||
Msg.warn("Cannot load expansion %s due to an unknown issue.", expansion.getIdentifier());
|
Msg.warn("Cannot load expansion %s due to an unknown issue.", expansion.getIdentifier());
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
@@ -209,6 +213,12 @@ public final class LocalExpansionManager implements Listener {
|
|||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to register a {@link PlaceholderExpansion}
|
||||||
|
*
|
||||||
|
* @param expansion the expansion to register
|
||||||
|
* @return if the expansion was registered
|
||||||
|
*/
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Internal
|
||||||
public boolean register(@NotNull final PlaceholderExpansion expansion) {
|
public boolean register(@NotNull final PlaceholderExpansion expansion) {
|
||||||
final String identifier = expansion.getIdentifier().toLowerCase(Locale.ROOT);
|
final String identifier = expansion.getIdentifier().toLowerCase(Locale.ROOT);
|
||||||
@@ -217,9 +227,9 @@ public final class LocalExpansionManager implements Listener {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expansions.containsKey(identifier)) {
|
// Avoid loading two external expansions with the same identifier
|
||||||
Msg.warn("Failed to load expansion %s. Identifier is already in use.",
|
if (expansion.getExpansionType() == PlaceholderExpansion.Type.EXTERNAL && expansions.containsKey(identifier)) {
|
||||||
expansion.getIdentifier());
|
Msg.warn("Failed to load external expansion %s. Identifier is already in use.", expansion.getIdentifier());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,21 +297,24 @@ public final class LocalExpansionManager implements Listener {
|
|||||||
Bukkit.getPluginManager().registerEvents(((Listener) expansion), plugin);
|
Bukkit.getPluginManager().registerEvents(((Listener) expansion), plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
Msg.info("Successfully registered expansion: %s [%s]", expansion.getIdentifier(),
|
Msg.info(
|
||||||
expansion.getVersion());
|
"Successfully registered %s expansion: %s [%s]",
|
||||||
|
expansion.getExpansionType().name().toLowerCase(),
|
||||||
|
expansion.getIdentifier(),
|
||||||
|
expansion.getVersion()
|
||||||
|
);
|
||||||
|
|
||||||
if (expansion instanceof Taskable) {
|
if (expansion instanceof Taskable) {
|
||||||
((Taskable) expansion).start();
|
((Taskable) expansion).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plugin.getPlaceholderAPIConfig().isCloudEnabled()) {
|
// Check eCloud for updates only if the expansion is external
|
||||||
final Optional<CloudExpansion> cloudExpansionOptional =
|
if (plugin.getPlaceholderAPIConfig().isCloudEnabled() && expansion.getExpansionType() == PlaceholderExpansion.Type.EXTERNAL) {
|
||||||
plugin.getCloudExpansionManager().findCloudExpansionByName(identifier);
|
final Optional<CloudExpansion> cloudExpansionOptional = plugin.getCloudExpansionManager().findCloudExpansionByName(identifier);
|
||||||
if (cloudExpansionOptional.isPresent()) {
|
if (cloudExpansionOptional.isPresent()) {
|
||||||
CloudExpansion cloudExpansion = cloudExpansionOptional.get();
|
CloudExpansion cloudExpansion = cloudExpansionOptional.get();
|
||||||
cloudExpansion.setHasExpansion(true);
|
cloudExpansion.setHasExpansion(true);
|
||||||
cloudExpansion.setShouldUpdate(
|
cloudExpansion.setShouldUpdate(!cloudExpansion.getLatestVersion().equals(expansion.getVersion()));
|
||||||
!cloudExpansion.getLatestVersion().equals(expansion.getVersion()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,7 +443,8 @@ public final class LocalExpansionManager implements Listener {
|
|||||||
Msg.severe("Failed to load expansion %s (is a dependency missing?)", e, file.getName());
|
Msg.severe("Failed to load expansion %s (is a dependency missing?)", e, file.getName());
|
||||||
return null;
|
return null;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new CompletionException(e.getMessage() + " (expansion file: " + file.getAbsolutePath() + ")", e);
|
plugin.getLogger().log(Level.SEVERE, "Failed to load expansion file: " + file.getAbsolutePath(), e);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* 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.Locale;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
package me.clip.placeholderapi.replacer;
|
package me.clip.placeholderapi.replacer;
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|||||||
@@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 Sevastjan
|
||||||
|
*
|
||||||
|
* 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:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.clip.placeholderapi.scheduler;
|
||||||
|
|
||||||
|
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||||
|
import me.clip.placeholderapi.scheduler.scheduling.tasks.MyScheduledTask;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just modified BukkitRunnable
|
||||||
|
*/
|
||||||
|
public abstract class UniversalRunnable implements Runnable {
|
||||||
|
MyScheduledTask task;
|
||||||
|
|
||||||
|
public synchronized void cancel() throws IllegalStateException {
|
||||||
|
checkScheduled();
|
||||||
|
task.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this task has been cancelled.
|
||||||
|
*
|
||||||
|
* @return true if the task has been cancelled
|
||||||
|
* @throws IllegalStateException if task was not scheduled yet
|
||||||
|
*/
|
||||||
|
public synchronized boolean isCancelled() throws IllegalStateException {
|
||||||
|
checkScheduled();
|
||||||
|
return task.isCancelled();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules this in the Bukkit scheduler to run on next tick.
|
||||||
|
*
|
||||||
|
* @param plugin the reference to the plugin scheduling task
|
||||||
|
* @return {@link MyScheduledTask}
|
||||||
|
* @throws IllegalArgumentException if plugin is null
|
||||||
|
* @throws IllegalStateException if this was already scheduled
|
||||||
|
* @see TaskScheduler#runTask(Runnable)
|
||||||
|
*/
|
||||||
|
|
||||||
|
public synchronized MyScheduledTask runTask(Plugin plugin) throws IllegalArgumentException, IllegalStateException {
|
||||||
|
checkNotYetScheduled();
|
||||||
|
return setupTask(UniversalScheduler.getScheduler(plugin).runTask(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>Asynchronous tasks should never access any API in Bukkit. Great care
|
||||||
|
* should be taken to assure the thread-safety of asynchronous tasks.</b>
|
||||||
|
* <p>
|
||||||
|
* Schedules this in the Bukkit scheduler to run asynchronously.
|
||||||
|
*
|
||||||
|
* @param plugin the reference to the plugin scheduling task
|
||||||
|
* @return {@link MyScheduledTask}
|
||||||
|
* @throws IllegalArgumentException if plugin is null
|
||||||
|
* @throws IllegalStateException if this was already scheduled
|
||||||
|
* @see TaskScheduler#runTaskAsynchronously(Runnable)
|
||||||
|
*/
|
||||||
|
|
||||||
|
public synchronized MyScheduledTask runTaskAsynchronously(Plugin plugin) throws IllegalArgumentException, IllegalStateException {
|
||||||
|
checkNotYetScheduled();
|
||||||
|
return setupTask(UniversalScheduler.getScheduler(plugin).runTaskAsynchronously(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules this to run after the specified number of server ticks.
|
||||||
|
*
|
||||||
|
* @param plugin the reference to the plugin scheduling task
|
||||||
|
* @param delay the ticks to wait before running the task
|
||||||
|
* @return {@link MyScheduledTask}
|
||||||
|
* @throws IllegalArgumentException if plugin is null
|
||||||
|
* @throws IllegalStateException if this was already scheduled
|
||||||
|
* @see TaskScheduler#runTaskLater(Runnable, long)
|
||||||
|
*/
|
||||||
|
|
||||||
|
public synchronized MyScheduledTask runTaskLater(Plugin plugin, long delay) throws IllegalArgumentException, IllegalStateException {
|
||||||
|
checkNotYetScheduled();
|
||||||
|
return setupTask(UniversalScheduler.getScheduler(plugin).runTaskLater(this, delay));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>Asynchronous tasks should never access any API in Bukkit. Great care
|
||||||
|
* should be taken to assure the thread-safety of asynchronous tasks.</b>
|
||||||
|
* <p>
|
||||||
|
* Schedules this to run asynchronously after the specified number of
|
||||||
|
* server ticks.
|
||||||
|
*
|
||||||
|
* @param plugin the reference to the plugin scheduling task
|
||||||
|
* @param delay the ticks to wait before running the task
|
||||||
|
* @return {@link MyScheduledTask}
|
||||||
|
* @throws IllegalArgumentException if plugin is null
|
||||||
|
* @throws IllegalStateException if this was already scheduled
|
||||||
|
* @see TaskScheduler#runTaskLaterAsynchronously(Runnable, long)
|
||||||
|
*/
|
||||||
|
|
||||||
|
public synchronized MyScheduledTask runTaskLaterAsynchronously(Plugin plugin, long delay) throws IllegalArgumentException, IllegalStateException {
|
||||||
|
checkNotYetScheduled();
|
||||||
|
return setupTask(UniversalScheduler.getScheduler(plugin).runTaskLaterAsynchronously(this, delay));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules this to repeatedly run until cancelled, starting after the
|
||||||
|
* specified number of server ticks.
|
||||||
|
*
|
||||||
|
* @param plugin the reference to the plugin scheduling task
|
||||||
|
* @param delay the ticks to wait before running the task
|
||||||
|
* @param period the ticks to wait between runs
|
||||||
|
* @return {@link MyScheduledTask}
|
||||||
|
* @throws IllegalArgumentException if plugin is null
|
||||||
|
* @throws IllegalStateException if this was already scheduled
|
||||||
|
* @see TaskScheduler#runTaskTimer(Runnable, long, long)
|
||||||
|
*/
|
||||||
|
|
||||||
|
public synchronized MyScheduledTask runTaskTimer(Plugin plugin, long delay, long period) throws IllegalArgumentException, IllegalStateException {
|
||||||
|
checkNotYetScheduled();
|
||||||
|
return setupTask(UniversalScheduler.getScheduler(plugin).runTaskTimer(this, delay, period));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>Asynchronous tasks should never access any API in Bukkit. Great care
|
||||||
|
* should be taken to assure the thread-safety of asynchronous tasks.</b>
|
||||||
|
* <p>
|
||||||
|
* Schedules this to repeatedly run asynchronously until cancelled,
|
||||||
|
* starting after the specified number of server ticks.
|
||||||
|
*
|
||||||
|
* @param plugin the reference to the plugin scheduling task
|
||||||
|
* @param delay the ticks to wait before running the task for the first
|
||||||
|
* time
|
||||||
|
* @param period the ticks to wait between runs
|
||||||
|
* @return {@link MyScheduledTask}
|
||||||
|
* @throws IllegalArgumentException if plugin is null
|
||||||
|
* @throws IllegalStateException if this was already scheduled
|
||||||
|
* @see TaskScheduler#runTaskTimerAsynchronously(Runnable, long, long)
|
||||||
|
*/
|
||||||
|
|
||||||
|
public synchronized MyScheduledTask runTaskTimerAsynchronously(Plugin plugin, long delay, long period) throws IllegalArgumentException, IllegalStateException {
|
||||||
|
checkNotYetScheduled();
|
||||||
|
return setupTask(UniversalScheduler.getScheduler(plugin).runTaskTimerAsynchronously(this, delay, period));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkScheduled() {
|
||||||
|
if (task == null) {
|
||||||
|
throw new IllegalStateException("Not scheduled yet");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkNotYetScheduled() {
|
||||||
|
if (task != null) {
|
||||||
|
throw new IllegalStateException("Already scheduled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private MyScheduledTask setupTask(final MyScheduledTask task) {
|
||||||
|
this.task = task;
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 Sevastjan
|
||||||
|
*
|
||||||
|
* 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:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.clip.placeholderapi.scheduler;
|
||||||
|
|
||||||
|
import me.clip.placeholderapi.scheduler.bukkit.BukkitScheduler;
|
||||||
|
import me.clip.placeholderapi.scheduler.folia.FoliaScheduler;
|
||||||
|
import me.clip.placeholderapi.scheduler.paper.PaperScheduler;
|
||||||
|
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||||
|
import me.clip.placeholderapi.scheduler.utils.JavaUtil;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
public class UniversalScheduler {
|
||||||
|
private static final boolean IS_FOLIA = JavaUtil.classExists("io.papermc.paper.threadedregions.RegionizedServer");
|
||||||
|
private static final boolean IS_CANVAS = JavaUtil.classExists("io.canvasmc.canvas.server.ThreadedServer");
|
||||||
|
private static final boolean IS_EXPANDED_SCHEDULING_AVAILABLE = JavaUtil.classExists("io.papermc.paper.threadedregions.scheduler.ScheduledTask");
|
||||||
|
|
||||||
|
public static TaskScheduler getScheduler(Plugin plugin) {
|
||||||
|
return IS_FOLIA || IS_CANVAS ? new FoliaScheduler(plugin) : (IS_EXPANDED_SCHEDULING_AVAILABLE ? new PaperScheduler(plugin) : new BukkitScheduler(plugin));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 Sevastjan
|
||||||
|
*
|
||||||
|
* 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:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.clip.placeholderapi.scheduler.bukkit;
|
||||||
|
|
||||||
|
import me.clip.placeholderapi.scheduler.scheduling.tasks.MyScheduledTask;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
|
|
||||||
|
public class BukkitScheduledTask implements MyScheduledTask {
|
||||||
|
|
||||||
|
BukkitTask task;
|
||||||
|
|
||||||
|
boolean isRepeating;
|
||||||
|
|
||||||
|
public BukkitScheduledTask(final BukkitTask task) {
|
||||||
|
this.task = task;
|
||||||
|
this.isRepeating = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BukkitScheduledTask(final BukkitTask task, boolean isRepeating) {
|
||||||
|
this.task = task;
|
||||||
|
this.isRepeating = isRepeating;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
task.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return task.isCancelled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Plugin getOwningPlugin() {
|
||||||
|
return task.getOwner();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCurrentlyRunning() {
|
||||||
|
return Bukkit.getServer().getScheduler().isCurrentlyRunning(this.task.getTaskId()); //There's no other way. Fuck bukkit
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRepeatingTask() {
|
||||||
|
return isRepeating;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 Sevastjan
|
||||||
|
*
|
||||||
|
* 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:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.clip.placeholderapi.scheduler.bukkit;
|
||||||
|
|
||||||
|
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||||
|
import me.clip.placeholderapi.scheduler.scheduling.tasks.MyScheduledTask;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
public class BukkitScheduler implements TaskScheduler {
|
||||||
|
final Plugin plugin;
|
||||||
|
|
||||||
|
public BukkitScheduler(Plugin plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isGlobalThread() {
|
||||||
|
return Bukkit.getServer().isPrimaryThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEntityThread(Entity entity) {
|
||||||
|
return Bukkit.getServer().isPrimaryThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRegionThread(Location location) {
|
||||||
|
return Bukkit.getServer().isPrimaryThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTask(Runnable runnable) {
|
||||||
|
return new BukkitScheduledTask(Bukkit.getScheduler().runTask(plugin, runnable));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskLater(Runnable runnable, long delay) {
|
||||||
|
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskLater(plugin, runnable, delay));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskTimer(Runnable runnable, long delay, long period) {
|
||||||
|
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskTimer(plugin, runnable, delay, period));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskAsynchronously(Runnable runnable) {
|
||||||
|
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskAsynchronously(plugin, runnable));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskLaterAsynchronously(Runnable runnable, long delay) {
|
||||||
|
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, runnable, delay));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskTimerAsynchronously(Runnable runnable, long delay, long period) {
|
||||||
|
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, runnable, delay, period));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Useless? Or...
|
||||||
|
public MyScheduledTask runTask(Plugin plugin, Runnable runnable) {
|
||||||
|
return new BukkitScheduledTask(Bukkit.getScheduler().runTask(plugin, runnable));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskLater(Plugin plugin, Runnable runnable, long delay) {
|
||||||
|
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskLater(plugin, runnable, delay));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskTimer(Plugin plugin, Runnable runnable, long delay, long period) {
|
||||||
|
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskTimer(plugin, runnable, delay, period));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskAsynchronously(Plugin plugin, Runnable runnable) {
|
||||||
|
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskAsynchronously(plugin, runnable));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskLaterAsynchronously(Plugin plugin, Runnable runnable, long delay) {
|
||||||
|
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, runnable, delay));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskTimerAsynchronously(Plugin plugin, Runnable runnable, long delay, long period) {
|
||||||
|
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, runnable, delay, period));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Runnable runnable) {
|
||||||
|
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelTasks() {
|
||||||
|
Bukkit.getScheduler().cancelTasks(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelTasks(Plugin plugin) {
|
||||||
|
Bukkit.getScheduler().cancelTasks(plugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 Sevastjan
|
||||||
|
*
|
||||||
|
* 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:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.clip.placeholderapi.scheduler.folia;
|
||||||
|
|
||||||
|
import me.clip.placeholderapi.scheduler.scheduling.tasks.MyScheduledTask;
|
||||||
|
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
public class FoliaScheduledTask implements MyScheduledTask {
|
||||||
|
private final ScheduledTask task;
|
||||||
|
|
||||||
|
public FoliaScheduledTask(final ScheduledTask task) {
|
||||||
|
this.task = task;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancel() {
|
||||||
|
this.task.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return this.task.isCancelled();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Plugin getOwningPlugin() {
|
||||||
|
return this.task.getOwningPlugin();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCurrentlyRunning() {
|
||||||
|
final ScheduledTask.ExecutionState state = this.task.getExecutionState();
|
||||||
|
return state == ScheduledTask.ExecutionState.RUNNING || state == ScheduledTask.ExecutionState.CANCELLED_RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRepeatingTask() {
|
||||||
|
return this.task.isRepeatingTask();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,220 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 Sevastjan
|
||||||
|
*
|
||||||
|
* 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:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.clip.placeholderapi.scheduler.folia;
|
||||||
|
|
||||||
|
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||||
|
import me.clip.placeholderapi.scheduler.scheduling.tasks.MyScheduledTask;
|
||||||
|
import io.papermc.paper.threadedregions.scheduler.AsyncScheduler;
|
||||||
|
import io.papermc.paper.threadedregions.scheduler.GlobalRegionScheduler;
|
||||||
|
import io.papermc.paper.threadedregions.scheduler.RegionScheduler;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class FoliaScheduler implements TaskScheduler {
|
||||||
|
|
||||||
|
final Plugin plugin;
|
||||||
|
|
||||||
|
public FoliaScheduler(Plugin plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final RegionScheduler regionScheduler = Bukkit.getServer().getRegionScheduler();
|
||||||
|
private final GlobalRegionScheduler globalRegionScheduler = Bukkit.getServer().getGlobalRegionScheduler();
|
||||||
|
private final AsyncScheduler asyncScheduler = Bukkit.getServer().getAsyncScheduler();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isGlobalThread() {
|
||||||
|
return Bukkit.getServer().isGlobalTickThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTickThread() {
|
||||||
|
return Bukkit.getServer().isPrimaryThread(); // The Paper implementation checks whether this is a tick thread, this method exists to avoid confusion.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEntityThread(Entity entity) {
|
||||||
|
return Bukkit.getServer().isOwnedByCurrentRegion(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRegionThread(Location location) {
|
||||||
|
return Bukkit.getServer().isOwnedByCurrentRegion(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTask(Runnable runnable) {
|
||||||
|
return new FoliaScheduledTask(globalRegionScheduler.run(plugin, task -> runnable.run()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskLater(Runnable runnable, long delay) {
|
||||||
|
//Folia exception: Delay ticks may not be <= 0
|
||||||
|
if (delay <= 0) {
|
||||||
|
return runTask(runnable);
|
||||||
|
}
|
||||||
|
return new FoliaScheduledTask(globalRegionScheduler.runDelayed(plugin, task -> runnable.run(), delay));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskTimer(Runnable runnable, long delay, long period) {
|
||||||
|
//Folia exception: Delay ticks may not be <= 0
|
||||||
|
delay = getOneIfNotPositive(delay);
|
||||||
|
return new FoliaScheduledTask(globalRegionScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay, period));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTask(Plugin plugin, Runnable runnable) {
|
||||||
|
return new FoliaScheduledTask(globalRegionScheduler.run(plugin, task -> runnable.run()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskLater(Plugin plugin, Runnable runnable, long delay) {
|
||||||
|
//Folia exception: Delay ticks may not be <= 0
|
||||||
|
if (delay <= 0) {
|
||||||
|
return runTask(plugin, runnable);
|
||||||
|
}
|
||||||
|
return new FoliaScheduledTask(globalRegionScheduler.runDelayed(plugin, task -> runnable.run(), delay));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskTimer(Plugin plugin, Runnable runnable, long delay, long period) {
|
||||||
|
//Folia exception: Delay ticks may not be <= 0
|
||||||
|
delay = getOneIfNotPositive(delay);
|
||||||
|
return new FoliaScheduledTask(globalRegionScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay, period));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTask(Location location, Runnable runnable) {
|
||||||
|
return new FoliaScheduledTask(regionScheduler.run(plugin, location, task -> runnable.run()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskLater(Location location, Runnable runnable, long delay) {
|
||||||
|
//Folia exception: Delay ticks may not be <= 0
|
||||||
|
if (delay <= 0) {
|
||||||
|
return runTask(runnable);
|
||||||
|
}
|
||||||
|
return new FoliaScheduledTask(regionScheduler.runDelayed(plugin, location, task -> runnable.run(), delay));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskTimer(Location location, Runnable runnable, long delay, long period) {
|
||||||
|
//Folia exception: Delay ticks may not be <= 0
|
||||||
|
delay = getOneIfNotPositive(delay);
|
||||||
|
return new FoliaScheduledTask(regionScheduler.runAtFixedRate(plugin, location, task -> runnable.run(), delay, period));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTask(Entity entity, Runnable runnable) {
|
||||||
|
return new FoliaScheduledTask(entity.getScheduler().run(plugin, task -> runnable.run(), null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskLater(Entity entity, Runnable runnable, long delay) {
|
||||||
|
//Folia exception: Delay ticks may not be <= 0
|
||||||
|
if (delay <= 0) {
|
||||||
|
return runTask(entity, runnable);
|
||||||
|
}
|
||||||
|
return new FoliaScheduledTask(entity.getScheduler().runDelayed(plugin, task -> runnable.run(), null, delay));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskTimer(Entity entity, Runnable runnable, long delay, long period) {
|
||||||
|
//Folia exception: Delay ticks may not be <= 0
|
||||||
|
delay = getOneIfNotPositive(delay);
|
||||||
|
return new FoliaScheduledTask(entity.getScheduler().runAtFixedRate(plugin, task -> runnable.run(), null, delay, period));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskAsynchronously(Runnable runnable) {
|
||||||
|
return new FoliaScheduledTask(asyncScheduler.runNow(plugin, task -> runnable.run()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskLaterAsynchronously(Runnable runnable, long delay) {
|
||||||
|
//Folia exception: Delay ticks may not be <= 0
|
||||||
|
delay = getOneIfNotPositive(delay);
|
||||||
|
return new FoliaScheduledTask(asyncScheduler.runDelayed(plugin, task -> runnable.run(), delay * 50L, TimeUnit.MILLISECONDS));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskTimerAsynchronously(Runnable runnable, long delay, long period) {
|
||||||
|
return new FoliaScheduledTask(asyncScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay * 50, period * 50, TimeUnit.MILLISECONDS));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskAsynchronously(Plugin plugin, Runnable runnable) {
|
||||||
|
return new FoliaScheduledTask(asyncScheduler.runNow(plugin, task -> runnable.run()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskLaterAsynchronously(Plugin plugin, Runnable runnable, long delay) {
|
||||||
|
//Folia exception: Delay ticks may not be <= 0
|
||||||
|
delay = getOneIfNotPositive(delay);
|
||||||
|
return new FoliaScheduledTask(asyncScheduler.runDelayed(plugin, task -> runnable.run(), delay * 50L, TimeUnit.MILLISECONDS));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MyScheduledTask runTaskTimerAsynchronously(Plugin plugin, Runnable runnable, long delay, long period) {
|
||||||
|
//Folia exception: Delay ticks may not be <= 0
|
||||||
|
delay = getOneIfNotPositive(delay);
|
||||||
|
return new FoliaScheduledTask(asyncScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay * 50, period * 50, TimeUnit.MILLISECONDS));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Runnable runnable) {
|
||||||
|
globalRegionScheduler.execute(plugin, runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Location location, Runnable runnable) {
|
||||||
|
regionScheduler.execute(plugin, location, runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Entity entity, Runnable runnable) {
|
||||||
|
entity.getScheduler().execute(plugin, runnable, null, 1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelTasks() {
|
||||||
|
globalRegionScheduler.cancelTasks(plugin);
|
||||||
|
asyncScheduler.cancelTasks(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelTasks(Plugin plugin) {
|
||||||
|
globalRegionScheduler.cancelTasks(plugin);
|
||||||
|
asyncScheduler.cancelTasks(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getOneIfNotPositive(long x) {
|
||||||
|
return x <= 0 ? 1L : x;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 Sevastjan
|
||||||
|
*
|
||||||
|
* 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:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.clip.placeholderapi.scheduler.paper;
|
||||||
|
|
||||||
|
import me.clip.placeholderapi.scheduler.folia.FoliaScheduler;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
//Thanks to Towny
|
||||||
|
public class PaperScheduler extends FoliaScheduler {
|
||||||
|
public PaperScheduler(Plugin plugin) {
|
||||||
|
super(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isGlobalThread() {
|
||||||
|
// isGlobalThread does not exist on paper, match the bukkit task scheduler's behaviour.
|
||||||
|
return Bukkit.getServer().isPrimaryThread();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,346 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 Sevastjan
|
||||||
|
*
|
||||||
|
* 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:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.clip.placeholderapi.scheduler.scheduling.schedulers;
|
||||||
|
|
||||||
|
import me.clip.placeholderapi.scheduler.scheduling.tasks.MyScheduledTask;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
public interface TaskScheduler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>Folia</b>: Returns whether the current thread is ticking the global region <br>
|
||||||
|
* <b>Paper and Bukkit</b>: Returns {@link org.bukkit.Server#isPrimaryThread}
|
||||||
|
*/
|
||||||
|
boolean isGlobalThread();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link org.bukkit.Server#isPrimaryThread}
|
||||||
|
*/
|
||||||
|
default boolean isTickThread() {
|
||||||
|
return Bukkit.getServer().isPrimaryThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <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
|
||||||
|
* <p>
|
||||||
|
* <b>Bukkit</b>: returns {@link org.bukkit.Server#isPrimaryThread}
|
||||||
|
*
|
||||||
|
* @param entity Specified entity
|
||||||
|
*/
|
||||||
|
boolean isEntityThread(Entity entity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <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}
|
||||||
|
*
|
||||||
|
* @param location Specified location, must have a non-null world.
|
||||||
|
*/
|
||||||
|
boolean isRegionThread(Location location);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules a task to be executed on the next tick <br>
|
||||||
|
* <b>Folia and Paper</b>: ...on the global region <br>
|
||||||
|
* <b>Bukkit</b>: ...on the main thread
|
||||||
|
*
|
||||||
|
* @param runnable The task to execute
|
||||||
|
*/
|
||||||
|
MyScheduledTask runTask(Runnable runnable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules a task to be executed after the specified delay in ticks <br>
|
||||||
|
* <b>Folia and Paper</b>: ...on the global region <br>
|
||||||
|
* <b>Bukkit</b>: ...on the main thread
|
||||||
|
*
|
||||||
|
* @param runnable The task to execute
|
||||||
|
* @param delay The delay, in ticks
|
||||||
|
*/
|
||||||
|
MyScheduledTask runTaskLater(Runnable runnable, long delay);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules a repeating task to be executed after the initial delay with the specified period <br>
|
||||||
|
* <b>Folia and Paper</b>: ...on the global region <br>
|
||||||
|
* <b>Bukkit</b>: ...on the main thread
|
||||||
|
*
|
||||||
|
* @param runnable The task to execute
|
||||||
|
* @param delay The initial delay, in ticks.
|
||||||
|
* @param period The period, in ticks.
|
||||||
|
*/
|
||||||
|
MyScheduledTask runTaskTimer(Runnable runnable, long delay, long period);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated: use {@link #runTask(Runnable)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default MyScheduledTask runTask(Plugin plugin, Runnable runnable) {
|
||||||
|
return runTask(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated: use {@link #runTaskLater(Runnable, long)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default MyScheduledTask runTaskLater(Plugin plugin, Runnable runnable, long delay) {
|
||||||
|
return runTaskLater(runnable, delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated: use {@link #runTaskTimer(Runnable, long, long)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default MyScheduledTask runTaskTimer(Plugin plugin, Runnable runnable, long delay, long period) {
|
||||||
|
return runTaskTimer(runnable, delay, period);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <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)}
|
||||||
|
*
|
||||||
|
* @param location The location which the region executing should own
|
||||||
|
* @param runnable The task to execute
|
||||||
|
*/
|
||||||
|
default MyScheduledTask runTask(Location location, Runnable runnable) {
|
||||||
|
return runTask(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <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)}
|
||||||
|
*
|
||||||
|
* @param location The location which the region executing should own
|
||||||
|
* @param runnable The task to execute
|
||||||
|
* @param delay The delay, in ticks.
|
||||||
|
*/
|
||||||
|
default MyScheduledTask runTaskLater(Location location, Runnable runnable, long delay) {
|
||||||
|
return runTaskLater(runnable, delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <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)}
|
||||||
|
*
|
||||||
|
* @param location The location which the region executing should own
|
||||||
|
* @param runnable The task to execute
|
||||||
|
* @param delay The initial delay, in ticks.
|
||||||
|
* @param period The period, in ticks.
|
||||||
|
*/
|
||||||
|
default MyScheduledTask runTaskTimer(Location location, Runnable runnable, long delay, long period) {
|
||||||
|
return runTaskTimer(runnable, delay, period);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated: use {@link #runTaskLater(Runnable, long)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default MyScheduledTask scheduleSyncDelayedTask(Runnable runnable, long delay) {
|
||||||
|
return runTaskLater(runnable, delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated: use {@link #execute(Runnable)} or {@link #runTask(Runnable)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default MyScheduledTask scheduleSyncDelayedTask(Runnable runnable) {
|
||||||
|
return runTask(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated: use {@link #runTaskTimer(Runnable, long, long)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default MyScheduledTask scheduleSyncRepeatingTask(Runnable runnable, long delay, long period) {
|
||||||
|
return runTaskTimer(runnable, delay, period);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <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)}
|
||||||
|
*
|
||||||
|
* @param entity The entity whose location the region executing should own
|
||||||
|
* @param runnable The task to execute
|
||||||
|
*/
|
||||||
|
default MyScheduledTask runTask(Entity entity, Runnable runnable) {
|
||||||
|
return runTask(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <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)}
|
||||||
|
*
|
||||||
|
* @param entity The entity whose location the region executing should own
|
||||||
|
* @param runnable The task to execute
|
||||||
|
* @param delay The delay, in ticks.
|
||||||
|
*/
|
||||||
|
default MyScheduledTask runTaskLater(Entity entity, Runnable runnable, long delay) {
|
||||||
|
return runTaskLater(runnable, delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <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)}
|
||||||
|
*
|
||||||
|
* @param entity The entity whose location the region executing should own
|
||||||
|
* @param runnable The task to execute
|
||||||
|
* @param delay The initial delay, in ticks.
|
||||||
|
* @param period The period, in ticks.
|
||||||
|
*/
|
||||||
|
default MyScheduledTask runTaskTimer(Entity entity, Runnable runnable, long delay, long period) {
|
||||||
|
return runTaskTimer(runnable, delay, period);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules the specified task to be executed asynchronously immediately
|
||||||
|
*
|
||||||
|
* @param runnable The task to execute
|
||||||
|
* @return The {@link MyScheduledTask} that represents the scheduled task
|
||||||
|
*/
|
||||||
|
MyScheduledTask runTaskAsynchronously(Runnable runnable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules the specified task to be executed asynchronously after the time delay has passed
|
||||||
|
*
|
||||||
|
* @param runnable The task to execute
|
||||||
|
* @param delay The time delay to pass before the task should be executed
|
||||||
|
* @return The {@link MyScheduledTask} that represents the scheduled task
|
||||||
|
*/
|
||||||
|
MyScheduledTask runTaskLaterAsynchronously(Runnable runnable, long delay);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules the specified task to be executed asynchronously after the initial delay has passed,
|
||||||
|
* and then periodically executed with the specified period
|
||||||
|
*
|
||||||
|
* @param runnable The task to execute
|
||||||
|
* @param delay The time delay to pass before the first execution of the task, in ticks
|
||||||
|
* @param period The time between task executions after the first execution of the task, in ticks
|
||||||
|
* @return The {@link MyScheduledTask} that represents the scheduled task
|
||||||
|
*/
|
||||||
|
MyScheduledTask runTaskTimerAsynchronously(Runnable runnable, long delay, long period);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated: use {@link #runTaskAsynchronously(Runnable)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default MyScheduledTask runTaskAsynchronously(Plugin plugin, Runnable runnable) {
|
||||||
|
return runTaskAsynchronously(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated: use {@link #runTaskLaterAsynchronously(Runnable, long)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default MyScheduledTask runTaskLaterAsynchronously(Plugin plugin, Runnable runnable, long delay) {
|
||||||
|
return runTaskLaterAsynchronously(runnable, delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated: use {@link #runTaskTimerAsynchronously(Runnable, long, long)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default MyScheduledTask runTaskTimerAsynchronously(Plugin plugin, Runnable runnable, long delay, long period) {
|
||||||
|
return runTaskTimerAsynchronously(runnable, delay, period);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls a method on the main thread and returns a Future object. This task will be executed
|
||||||
|
* by the main(Bukkit)/global(FoliaandPaper) server thread.
|
||||||
|
* <p>
|
||||||
|
* Note: The Future.get() methods must NOT be called from the main thread.
|
||||||
|
* <p>
|
||||||
|
* Note2: There is at least an average of 10ms latency until the isDone() method returns true.
|
||||||
|
*
|
||||||
|
* @param task Task to be executed
|
||||||
|
*/
|
||||||
|
default <T> Future<T> callSyncMethod(final Callable<T> task) {
|
||||||
|
CompletableFuture<T> completableFuture = new CompletableFuture<>();
|
||||||
|
execute(() -> {
|
||||||
|
try {
|
||||||
|
completableFuture.complete(task.call());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return completableFuture;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules a task to be executed on the global region
|
||||||
|
*
|
||||||
|
* @param runnable The task to execute
|
||||||
|
*/
|
||||||
|
void execute(Runnable runnable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules a task to be executed on the region which owns the location
|
||||||
|
*
|
||||||
|
* @param location The location which the region executing should own
|
||||||
|
* @param runnable The task to execute
|
||||||
|
*/
|
||||||
|
default void execute(Location location, Runnable runnable) {
|
||||||
|
execute(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules a task to be executed on the region which owns the location of given entity
|
||||||
|
*
|
||||||
|
* @param entity The entity which location the region executing should own
|
||||||
|
* @param runnable The task to execute
|
||||||
|
*/
|
||||||
|
default void execute(Entity entity, Runnable runnable) {
|
||||||
|
execute(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to cancel all tasks scheduled by this plugin
|
||||||
|
*/
|
||||||
|
void cancelTasks();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to cancel all tasks scheduled by the specified plugin
|
||||||
|
*
|
||||||
|
* @param plugin specified plugin
|
||||||
|
*/
|
||||||
|
void cancelTasks(Plugin plugin);
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 Sevastjan
|
||||||
|
*
|
||||||
|
* 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:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.clip.placeholderapi.scheduler.scheduling.tasks;
|
||||||
|
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
public interface MyScheduledTask {
|
||||||
|
/**
|
||||||
|
* Cancels executing task
|
||||||
|
*/
|
||||||
|
void cancel();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if task is cancelled, false otherwise
|
||||||
|
*/
|
||||||
|
boolean isCancelled();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The plugin under which the task was scheduled.
|
||||||
|
*/
|
||||||
|
Plugin getOwningPlugin();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if task is currently executing, false otherwise
|
||||||
|
*/
|
||||||
|
boolean isCurrentlyRunning();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if task is repeating, false otherwise
|
||||||
|
*/
|
||||||
|
boolean isRepeatingTask();
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package me.clip.placeholderapi.scheduler.utils;
|
||||||
|
|
||||||
|
public class JavaUtil {
|
||||||
|
public static boolean classExists(String className) {
|
||||||
|
try {
|
||||||
|
Class.forName(className);
|
||||||
|
return true;
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -25,7 +25,11 @@ import java.io.InputStreamReader;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
|
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||||
import me.clip.placeholderapi.util.Msg;
|
import me.clip.placeholderapi.util.Msg;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
@@ -34,65 +38,68 @@ import org.bukkit.event.Listener;
|
|||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
|
||||||
public class UpdateChecker implements Listener {
|
public class UpdateChecker implements Listener {
|
||||||
|
private static final String MODRINTH_URL = "https://api.modrinth.com/v2/project/lKEzGugV/version";
|
||||||
|
|
||||||
private final int RESOURCE_ID = 6245;
|
private static final int RESOURCE_ID = 6245;
|
||||||
private final PlaceholderAPIPlugin plugin;
|
private final PlaceholderAPIPlugin plugin;
|
||||||
|
private final TaskScheduler scheduler;
|
||||||
private final String pluginVersion;
|
private final String pluginVersion;
|
||||||
private String spigotVersion;
|
private String modrinthVersion;
|
||||||
private boolean updateAvailable;
|
private boolean updateAvailable;
|
||||||
|
|
||||||
public UpdateChecker(PlaceholderAPIPlugin i) {
|
public UpdateChecker(PlaceholderAPIPlugin plugin) {
|
||||||
plugin = i;
|
this.plugin = plugin;
|
||||||
pluginVersion = i.getDescription().getVersion();
|
scheduler = plugin.getScheduler();
|
||||||
|
pluginVersion = plugin.getDescription().getVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasUpdateAvailable() {
|
public boolean hasUpdateAvailable() {
|
||||||
return updateAvailable;
|
return updateAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSpigotVersion() {
|
public String getModrinthVersion() {
|
||||||
return spigotVersion;
|
return modrinthVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fetch() {
|
public void fetch() {
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
scheduler.runTaskAsynchronously(() -> {
|
||||||
try {
|
try {
|
||||||
HttpsURLConnection con = (HttpsURLConnection) new URL(
|
HttpsURLConnection con = (HttpsURLConnection) new URL(MODRINTH_URL).openConnection();
|
||||||
"https://api.spigotmc.org/legacy/update.php?resource=" + RESOURCE_ID).openConnection();
|
|
||||||
con.setRequestMethod("GET");
|
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) {
|
} catch (Exception ex) {
|
||||||
plugin.getLogger().info("Failed to check for updates on spigot.");
|
plugin.getLogger().info("Failed to check for updates on modrinth.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spigotVersion == null || spigotVersion.isEmpty()) {
|
if (modrinthVersion == null || modrinthVersion.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAvailable = spigotIsNewer();
|
updateAvailable = modrinthIsNewer();
|
||||||
|
|
||||||
if (!updateAvailable) {
|
if (!updateAvailable) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bukkit.getScheduler().runTask(plugin, () -> {
|
scheduler.runTask(() -> {
|
||||||
plugin.getLogger()
|
plugin.getLogger()
|
||||||
.info("An update for PlaceholderAPI (v" + getSpigotVersion() + ") is available at:");
|
.info("An update for PlaceholderAPI (v" + getModrinthVersion() + ") is available at:");
|
||||||
plugin.getLogger()
|
plugin.getLogger()
|
||||||
.info("https://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID + "/");
|
.info("https://modrinth.com/plugin/placeholderapi");
|
||||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean spigotIsNewer() {
|
private boolean modrinthIsNewer() {
|
||||||
if (spigotVersion == null || spigotVersion.isEmpty()) {
|
if (modrinthVersion == null || modrinthVersion.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int[] plV = toReadable(pluginVersion);
|
int[] plV = toReadable(pluginVersion);
|
||||||
int[] spV = toReadable(spigotVersion);
|
int[] spV = toReadable(modrinthVersion);
|
||||||
|
|
||||||
if (plV[0] < spV[0]) {
|
if (plV[0] < spV[0]) {
|
||||||
return true;
|
return true;
|
||||||
@@ -115,10 +122,9 @@ public class UpdateChecker implements Listener {
|
|||||||
public void onJoin(PlayerJoinEvent e) {
|
public void onJoin(PlayerJoinEvent e) {
|
||||||
if (e.getPlayer().hasPermission("placeholderapi.updatenotify")) {
|
if (e.getPlayer().hasPermission("placeholderapi.updatenotify")) {
|
||||||
Msg.msg(e.getPlayer(),
|
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)"
|
+ "&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
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* 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.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -27,6 +27,8 @@ import java.util.function.BiConsumer;
|
|||||||
import java.util.stream.Collector;
|
import java.util.stream.Collector;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -36,14 +38,14 @@ public final class Futures {
|
|||||||
private Futures() {}
|
private Futures() {}
|
||||||
|
|
||||||
|
|
||||||
public static <T> void onMainThread(@NotNull final Plugin plugin,
|
public static <T> void onMainThread(@NotNull final PlaceholderAPIPlugin plugin,
|
||||||
@NotNull final CompletableFuture<T> future,
|
@NotNull final CompletableFuture<T> future,
|
||||||
@NotNull final BiConsumer<T, Throwable> consumer) {
|
@NotNull final BiConsumer<T, Throwable> consumer) {
|
||||||
future.whenComplete((value, exception) -> {
|
future.whenComplete((value, exception) -> {
|
||||||
if (Bukkit.isPrimaryThread()) {
|
if (Bukkit.isPrimaryThread()) {
|
||||||
consumer.accept(value, exception);
|
consumer.accept(value, exception);
|
||||||
} else {
|
} else {
|
||||||
Bukkit.getScheduler().runTask(plugin, () -> consumer.accept(value, exception));
|
plugin.getScheduler().runTask(() -> consumer.accept(value, exception));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* 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.Arrays;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
@@ -43,7 +44,7 @@ public final class Msg {
|
|||||||
log(Level.WARNING, msg, args);
|
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);
|
PlaceholderAPIPlugin.getInstance().getLogger().log(Level.WARNING, String.format(msg, args), throwable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,19 +1,22 @@
|
|||||||
# PlaceholderAPI
|
# PlaceholderAPI
|
||||||
# Version: @version@
|
# Version: ${version}
|
||||||
# Created by: extended_clip
|
# Created by: extended_clip
|
||||||
# Contributors: https://github.com/PlaceholderAPI/PlaceholderAPI/graphs/contributors
|
# Contributors: https://github.com/PlaceholderAPI/PlaceholderAPI/graphs/contributors
|
||||||
# Issues: https://github.com/PlaceholderAPI/PlaceholderAPI/issues
|
# Issues: https://github.com/PlaceholderAPI/PlaceholderAPI/issues
|
||||||
# Expansions: https://api.extendedclip.com/all/
|
# Expansions: https://placeholderapi.com/ecloud
|
||||||
# Wiki: https://github.com/PlaceholderAPI/PlaceholderAPI/wiki
|
# Wiki: https://wiki.placeholderapi.com/
|
||||||
# Discord: https://helpch.at/discord
|
# 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.
|
# No placeholders are provided with this plugin by default.
|
||||||
# Download placeholders: /papi ecloud
|
# Download placeholders: /papi ecloud
|
||||||
check_updates: true
|
check_updates: true
|
||||||
cloud_enabled: true
|
cloud_enabled: true
|
||||||
cloud_sorting: "name"
|
cloud_sorting: "name"
|
||||||
cloud_allow_unverified_expansions: false
|
|
||||||
boolean:
|
boolean:
|
||||||
'true': 'yes'
|
'true': 'yes'
|
||||||
'false': 'no'
|
'false': 'no'
|
||||||
date_format: MM/dd/yy HH:mm:ss
|
date_format: MM/dd/yy HH:mm:ss
|
||||||
|
detect_malicious_expansions: true
|
||||||
|
use_adventure_provided_replacer: false
|
||||||
debug: false
|
debug: false
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
name: PlaceholderAPI
|
name: PlaceholderAPI
|
||||||
main: "me.clip.placeholderapi.PlaceholderAPIPlugin"
|
main: "me.clip.placeholderapi.PlaceholderAPIPlugin"
|
||||||
|
folia-supported: true
|
||||||
|
|
||||||
version: ${version}
|
version: ${version}
|
||||||
author: HelpChat
|
author: HelpChat
|
||||||
@@ -37,7 +38,6 @@ permissions:
|
|||||||
placeholderapi.ecloud.info: true
|
placeholderapi.ecloud.info: true
|
||||||
placeholderapi.ecloud.list: true
|
placeholderapi.ecloud.list: true
|
||||||
placeholderapi.ecloud.clear: true
|
placeholderapi.ecloud.clear: true
|
||||||
placeholderapi.ecloud.toggle: true
|
|
||||||
placeholderapi.ecloud.status: true
|
placeholderapi.ecloud.status: true
|
||||||
placeholderapi.ecloud.update: true
|
placeholderapi.ecloud.update: true
|
||||||
placeholderapi.ecloud.refresh: true
|
placeholderapi.ecloud.refresh: true
|
||||||
@@ -82,9 +82,6 @@ permissions:
|
|||||||
placeholderapi.ecloud.clear:
|
placeholderapi.ecloud.clear:
|
||||||
default: "op"
|
default: "op"
|
||||||
description: "Allows you to clear the local eCloud expansion cache"
|
description: "Allows you to clear the local eCloud expansion cache"
|
||||||
placeholderapi.ecloud.toggle:
|
|
||||||
default: "op"
|
|
||||||
description: "Allows you to toggle/enable/disable the eCloud manager"
|
|
||||||
placeholderapi.ecloud.status:
|
placeholderapi.ecloud.status:
|
||||||
default: "op"
|
default: "op"
|
||||||
description: "Allows you to view the status of eCloud expansions"
|
description: "Allows you to view the status of eCloud expansions"
|
||||||
|
|||||||
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
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* This file is part of PlaceholderAPI
|
* This file is part of PlaceholderAPI
|
||||||
*
|
*
|
||||||
* PlaceholderAPI
|
* PlaceholderAPI
|
||||||
* Copyright (c) 2015 - 2021 PlaceholderAPI Team
|
* Copyright (c) 2015 - 2026 PlaceholderAPI Team
|
||||||
*
|
*
|
||||||
* PlaceholderAPI free software: you can redistribute it and/or modify
|
* PlaceholderAPI free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
Reference in New Issue
Block a user