Pull latest changes from master into docs/wiki (#712)

* Update Javadoc documentation

* More comments... a lot more!

* Remove Gson

* Implemented working version for 1.8.8 - 1.16.3

* Improve ExpansionsLoadedEvent's docs

* 2021 🥳

* Add contributing and expansion section

* Fix invalid link tag

* Start using new Issue template system

* Create bug_report.yml

* Rename feature_request.md to feature_request_old.md

* Create feature_request.yml

* should it use setBracketPlaceholders??

* fix unique name

* Update feature_request_old.md

* Add Checkboxes

* Add checkboxes

* disable default issue body

* Delete bug_report_old.md

* Delete feature_request_old.md

* Rename bug_report_new.yml to bug_report.yml

* Check if deleting this fixed the PR...

* Use description in favour of about

* improve feature_request.md

* Update bug_report.yml

* Assign "Type: Issue (Unconfirmed)" label

* Use lists and not comma-separated string

* Update feature_request.yml

* Use id option for error and dump fields

* Add field for logs

* Update Copyright
~ Fixed a typo and updated missed files from #543

* Re-add removed code
That should actually NOT be here...

* Undo renaming of boolean

* Remove deprecated issue_body type

* Update feature_request.yml

* Improve description of bug_report.yml

* Build jars on PR (Compile and build validation)

* Initial 1.17 Changes

* Extracted URLClassLoader out of try-with-resources block

* Close URLClassLoader if Expansion class was not found

* Build against Java 8, 11 and 16

* adoPt

I always make that mistake...

* add render

* Cleanup build.gradle

(cherry picked from commit 7750ba7033dc9fdf40d55fcd9ecc20a94819a7c1)

* Remove the @NotNull's because they are overridden by expansion devs anyways, and it turns out people can make them null anyways. This adds a hashcode check and pretty error for it.

(cherry picked from commit f5386d4ca55c23b54f3c5f952f08040b0967f4a3)

* Fix version checker to compare the individual semver numbers instead of combining it together.

(cherry picked from commit ef5cd9d37680cc6cc1321ef2e04af09b44a2c681)

* Update src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java

Co-authored-by: Andre_601 <11576465+Andre601@users.noreply.github.com>
(cherry picked from commit ccf4f5934386b005831757d298e2da9d8f46cb1a)

* Re-add NotNull's

(cherry picked from commit 2bfd8e7e5efb25f648b8a6de934b1eff675481b1)

* Removed nullcheck from hashcode, and moved it up the chain.

* POJO to help with checking that expansions have all required methods implemented.

* Add method implementation checking and nullchecking for fields.

* Appease the Pigman

* Revert build.gradle dependencies change

* Fixed duplicate files

* Sync Dev with master (#659)

* Add contributing and expansion section

* Start using new Issue template system

* Create bug_report.yml

* Rename feature_request.md to feature_request_old.md

* Create feature_request.yml

* fix unique name

* Update feature_request_old.md

* Add Checkboxes

* Add checkboxes

* disable default issue body

* Delete bug_report_old.md

* Delete feature_request_old.md

* Rename bug_report_new.yml to bug_report.yml

* Check if deleting this fixed the PR...

* Use description in favour of about

* improve feature_request.md

* Update bug_report.yml

* Assign "Type: Issue (Unconfirmed)" label

* Use lists and not comma-separated string

* Update feature_request.yml

* Use id option for error and dump fields

* Add field for logs

* Remove deprecated issue_body type

* Update feature_request.yml

* Improve description of bug_report.yml

* Initial 1.17 Changes

* add render

* Revert build.gradle dependencies change

* Fixed duplicate files

Co-authored-by: PiggyPiglet <PiggyPiglet@users.noreply.github.com>
Co-authored-by: darbyjack <admin@glaremasters.me>

* Initial test on adventure

* started moving to pure adventure

* finished kyori impl

* added 1.17 to nmsversion (what does this even do)

* removed dev for release

* added dev back

* Switch to differen wiki action

Co-authored-by: darbyjack <admin@glaremasters.me>
Co-authored-by: ElijahRus250 <64851720+ElijahRus250@users.noreply.github.com>
Co-authored-by: PiggyPiglet <PiggyPiglet@users.noreply.github.com>
Co-authored-by: Huynh Tien <huynhqtienvtag@gmail.com>
Co-authored-by: Vaishnav Anil <vaishnavanil7th@gmail.com>
Co-authored-by: Starmism <iamstarmism@gmail.com>
Co-authored-by: PiggyPiglet <noreply@piggypiglet.me>
This commit is contained in:
Andre_601 2021-09-09 18:31:29 +02:00 committed by GitHub
parent 5412b484f8
commit 4300bf7d1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
72 changed files with 709 additions and 1494 deletions

@ -1,43 +0,0 @@
---
name: Bug Report
about: Report bugs of PlaceholderAPI with this template
---
<!--
### Please read ###
This template is only for reporting bugs of PlaceholderAPI!
If you want to request changes to the code of PlaceholderAPI, use the "Request change (PlaceholderAPI)" template.
For changes to the wiki consider making a Pull request towards the "wiki" folder containing your changes.
Please also make sure that you use the latest Spigot release or the latest developement build and that your bug isn't already reported on the issues page.
You may get Releases from following sources:
- Spigot: https://www.spigotmc.org/resources/6245/
- Jenkins: http://ci.extendedclip.com/job/PlaceholderAPI/
NOTE:
PLEASE REPORT ISSUES WITH EXPANSIONS AND/OR PLACEHOLDERS TO THEIR CORRESPONDING REPOSITORY/ISSUE TRACKER.
THIS REPOSITORY IS NOT FOR SUCH ISSUES.
-->
## Bug Report
### Issue
<!-- What is the issue? Describe it like you would tell a friend. -->
### Expected behaviour
<!-- What should PlaceholderAPI do? -->
### Actual behaviour
<!-- What does PlaceholderAPI actually do? -->
### How to reproduce
<!-- What steps did you made, to get this bug? -->
1.
### `/papi dump` output
<!-- Please provide the URL that was generated when using /papi dump -->

101
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file

@ -0,0 +1,101 @@
name: Bug Report
description: Found a Bug about PlaceholderAPI? Use this template to report it!
labels:
- "Type: Issue (Unconfirmed)"
body:
- type: markdown
attributes:
value: |-
Thank you for taking your time and opening a Bug Report.
In order for us to process this Bug Report as fast and efficient as possible do we ask you to read the form carefully and provide any requested information.
Required fields are marked with an asterisk symbol (`*`)
Also, always make sure to use the latest Release from [Spigot](https://www.spigotmc.org/resources/6245/) or the latest Development Build from our [Jenkins Server](http://ci.extendedclip.com/job/PlaceholderAPI/) to make sure that your issue isn't already fixed.
**DO NOT REPORT ISSUES WITH EXPANSIONS AND/OR PLACEHOLDERS. USE THE APPROPRIATE ISSUE TRACKER FOR THOSE!**
- type: checkboxes
attributes:
label: Confirmation
description: Please make sure to have followed the following checks.
options:
- label: My issue isn't already found on the Issue tracker.
required: true
- label: My issue is about **PlaceholderAPI** and not any expansion or external plugin
required: true
- label: The issue isn't already fixed in a Spigot Release or Development Build.
required: true
- type: dropdown
attributes:
label: "Type"
description: |-
What kind of Bug do you encounter?
- `Plugin Bug`: PlaceholderAPI doesn't startup properly.
- `API Bug`: A method you use didn't work or has an unexpected result.
- `Plugin/Server Incompatability`: PlaceholderAPI either doesn't support a specific Server Type/Version or has conflicts with another plugin.
multiple: false
options:
- "Plugin Bug"
- "API Bug"
- "Plugin/Server Incompatability"
validations:
required: true
- type: textarea
attributes:
label: "What happens?"
description: "What bug are you encountering? Try to explain it as detailed as possible."
placeholder: "PlaceholderAPI does this when I do that..."
validations:
required: true
- type: textarea
attributes:
label: "Expected Behaviour"
description: "What behaviour did you expect from PlaceholderAPI?"
placeholder: "PlaceholderAPI should actually do..."
validations:
required: true
- type: textarea
attributes:
label: "How to Reproduce"
description: |-
List the steps on how to reproduce this Bug.
Post any Code-examples in the `Additional Information` field below when you selected `API Bug`.
placeholder: |-
1. Do this
2. ...
3. Profit!
validations:
required: true
- type: input
id: "dump"
attributes:
label: "`/papi dump` Output"
description: |-
Please execute the `/papi dump` command and provide the generated URL from it.
If you can't execute the command (i.e. PlaceholderAPI doesn't start up) can you put N/A here and mention the issue in the `Additional Information` field.
placeholder: "https://paste.helpch.at/dump.log"
validations:
required: true
- type: input
id: "console"
attributes:
label: "Console Log"
description: |-
Get the latest content of your `latest.log` file an upload it to https://paste.helpch.at
Take the generated URL and paste it into this field.
placeholder: "https://paste.helpch.at/latest.log"
- type: input
id: "error"
attributes:
label: "Errors"
description: |-
Upload any errors you find to https://paste.helpch.at and post the link in the field below.
placeholder: "https://paste.helpch.at/error.log"
- type: textarea
attributes:
label: "Additional Info"
description: |-
Add any extra info you think is nessesary for this Bug report.
- If you selected `API Bug` will you need to include code-examples here to reproduce the issue.
- If you selected `Plugin/Server Incompatability` should you include extra Server info such as a Timings or Spark-Report or info about the plugin in question.
placeholder: "Put any extra info you like into this field..."

@ -1,31 +0,0 @@
---
name: Feature Request
about: Request a update/change of the PlaceholderAPI-code
---
<!--
### Please read ###
Before suggesting any new features, make sure that it wasn't suggested before and that no open issue with it exists already.
If possible would we suggest to create a Pull request instead.
When doing so, make sure to follow our Contributing Guidelines: https://github.com/PlaceholderAPI/PlaceholderAPI/blob/master/.github/CONTRIBUTING.md
-->
## Feature Request
### Type
<!-- What kind of request is this? (Multiple selections possible) -->
<!-- To select an option change the [ ] to [x] -->
- [ ] New function for PlaceholderAPI.
A new function that developers could use.
- [ ] Change to code (Internal).
Changes to code that won't affect the end-user.
- [ ] Change to code (External).
Changes to code that will affect the end-user (breaks stuff).
- [ ] Other: __________ <!-- Use this if none of the above matches your request -->
### Description
<!-- Describe what this suggested change should do and why it would be useful -->
<!-- When possible, add some code-examples to better illustrate the change -->

@ -0,0 +1,62 @@
name: Feature Request
description: Suggest a new Feature for PlaceholderAPI
labels:
- "Type: Enhancement"
body:
- type: markdown
attributes:
value: |-
Thank you for taking the time in creating this Feature Request.
In order to process your feature request as fast and efficiently as possible do we ask you to fill out any required fields (Indicated with a red asterisk (`*`)) with the requested information.
If you have any further questions should you either [join our Discord Server](https://helpch.at/discord) or [ask in our Discussions](https://github.com/PlaceholderAPI/PlaceholderAPI/discussions).
- type: checkboxes
attributes:
label: Confirmation
description: Please make sure to have followed the following checks.
options:
- label: I checked the Issues and Pull request tab for any existing issues or PRs.
required: true
- label: My Feature Request is for **PlaceholderAPI** and not any expansion or other plugin.
required: true
- type: dropdown
attributes:
label: "Type"
description: "What type is your Suggestion? Select all that match."
multiple: true
options:
- "New API feature"
- "New config option"
- "Minor Code improvement (Won't affect Servers)"
- "Major Code improvement (Will affect Servers)"
validations:
required: true
- type: textarea
attributes:
label: "Description"
description: |-
Give a detailed explanation about your Feature request and why it would be beneficial for PlaceholderAPI.
Just saying "It's cool!" or "I need it" don't count as valid reasons. It needs to have a clear benefit for **other** players too.
validations:
required: true
- type: textarea
attributes:
label: "Code Example"
description: |-
Do you have any Code Snippets that you want to share with us? Paste it here!
Note that the input will automatically be rendered as Java code, so you won't need to put it into a code block yourself.
render: java
- type: input
attributes:
label: "Jar file"
description: |-
If you already have a PlaceholderAPI Jar with the requested changes would we love to get a download link for it.
If you don't have a download link can you leave this field empty or provide "N/A" as a response.
placeholder: "https://cdn.discordapp.com/..."
- type: textarea
attributes:
label: "Additional Information"
description: |-
Add any extra info you think is nessesary for this Feature request.
- When you selected `Major Code improvement (Will affect Servers)` should you mention what will break when people update.
placeholder: "Put any extra info you like into this field..."

31
.github/workflows/pr_build_jars.yml vendored Normal file

@ -0,0 +1,31 @@
name: "Test compiling against Java 8, 11 and 16"
on:
pull_request:
branches:
- development
paths:
- "src/**"
- "build.gradle"
jobs:
testBuilds:
name: "Test-compile against Java 8, 11 and 16"
runs-on: ubuntu-latest
strategy:
fail-fast: false
max-parallel: 4
matrix:
java-version: [8, 11, 16]
steps:
- name: "Checkout Code"
uses: actions/checkout@v2
- name: "Prepare Java ${{ matrix.java-version }}"
uses: actions/setup-java@v2
with:
distribution: "adopt"
java-version: "${{ matrix.java-version }}"
- name: "Make build.gradle executable"
run: "chmod +x gradlew"
- name: "Build jar with Java ${{ matrix.java-version }}"
run: "./gradlew shadowJar"

@ -27,26 +27,10 @@ jobs:
- name: 'Checkout Code' - name: 'Checkout Code'
uses: actions/Checkout@v2 uses: actions/Checkout@v2
- name: 'Update Wiki' - name: 'Update Wiki'
uses: docker://decathlon/wiki-page-creator-action:latest uses: Andrew-Chen-Wang/github-wiki-action@v2
env: env:
# WIKI_DIR: wiki/
# We can use the E-Mail and Name of the GitHub Actions account GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# for our convenience. GH_EMAIL: 'actions@github.com'
# GH_NAME: 'github-actions[bot]'
ACTION_MAIL: 'actions@github.com' EXCLUDED_FILES: 'README.md'
ACTION_NAME: 'github-actions[bot]'
#
# We (sadly) have to use a PAT (Personal Access Token) for this action.
#
GH_PAT: '${{ secrets.WORKFLOWPAT }}'
OWNER: 'PlaceholderAPI'
REPO_NAME: 'PlaceholderAPI'
#
# We only want to target files in the wiki folder
#
MD_FOLDER: 'wiki'
WIKI_PUSH_MESSAGE: '${{ github.event.commits[0].message }}'
#
# We skip/ignore the README.md file in the Wiki folder
#
SKIP_MD: README.md

@ -16,6 +16,9 @@
[APIversionImg]: https://img.shields.io/nexus/placeholderapi/me.clip/placeholderapi?server=https%3A%2F%2Frepo.extendedclip.com&label=API%20Version [APIversionImg]: https://img.shields.io/nexus/placeholderapi/me.clip/placeholderapi?server=https%3A%2F%2Frepo.extendedclip.com&label=API%20Version
[logo]: https://i.imgur.com/Ea4PURv.png [logo]: https://i.imgur.com/Ea4PURv.png
[contributing]: https://github.com/PlaceholderAPI/PlaceholderAPI/blob/master/.github/CONTRIBUTING.md
[placeholderexpansion]: https://github.com/PlaceholderAPI/PlaceholderAPI/wiki/PlaceholderExpansion
<!-- The stuff above isn't visible in the readme --> <!-- The stuff above isn't visible in the readme -->
[![logo]][spigot] [![logo]][spigot]
@ -29,8 +32,11 @@ Support for specific plugins are provided either by the plugin itself or through
PlaceholderAPI has been downloaded over 500,000 times and has been used concurrently on over 20,000 servers, which makes it a must-have for a server of any type or scale. PlaceholderAPI has been downloaded over 500,000 times and has been used concurrently on over 20,000 servers, which makes it a must-have for a server of any type or scale.
<!-- TODO: Add contributing section --> ## Contribute
<!-- TODO: Add expansion creation section (possibly add to a wiki?) --> 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.
## Create an Expansion
If you would like to create your own Placeholder Expansion for PlaceholderAPI, take a look at our [Wiki][placeholderexpansion] which contains a detailed tutorial on how you can achieve this.
## Support ## Support
- [Issue Tracker][issues] - [Issue Tracker][issues]

@ -1,8 +1,10 @@
import org.apache.tools.ant.filters.ReplaceTokens
plugins { plugins {
id "java" id "java"
id "maven-publish" id "maven-publish"
id "net.minecrell.licenser" version "0.4.1" id "org.cadixdev.licenser" version "0.6.0"
id "com.github.johnrengelman.shadow" version "6.0.0" id "com.github.johnrengelman.shadow" version "7.0.0"
} }
group "me.clip" group "me.clip"
@ -11,30 +13,32 @@ version "2.10.10-DEV-${System.getProperty("BUILD_NUMBER")}"
description "An awesome placeholder provider!" description "An awesome placeholder provider!"
repositories { repositories {
maven({ url = "https://oss.sonatype.org/content/repositories/snapshots/" })
mavenCentral() mavenCentral()
mavenLocal()
maven({ url = "https://repo.codemc.org/repository/maven-public" }) maven({ url = "https://repo.codemc.org/repository/maven-public" })
maven({ url = "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" }) maven({ url = "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" })
} }
dependencies { dependencies {
implementation "com.google.code.gson:gson:2.8.6" implementation "org.bstats:bstats-bukkit:2.2.1"
implementation "org.bstats:bstats-bukkit:1.5"
compileOnly "org.spigotmc:spigot-api:1.16.4-R0.1-SNAPSHOT" implementation "net.kyori:adventure-platform-bukkit:4.0.0-SNAPSHOT"
compileOnly "org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT"
compileOnly "org.jetbrains:annotations:19.0.0" compileOnly "org.jetbrains:annotations:19.0.0"
testImplementation "org.openjdk.jmh:jmh-core:1.23" testImplementation "org.openjdk.jmh:jmh-core:1.23"
testImplementation "org.openjdk.jmh:jmh-generator-annprocess:1.23" testImplementation "org.openjdk.jmh:jmh-generator-annprocess:1.23"
testCompile "org.junit.jupiter:junit-jupiter-engine:5.6.2" testImplementation "org.junit.jupiter:junit-jupiter-engine:5.6.2"
testRuntime "org.junit.jupiter:junit-jupiter-engine:5.6.2" testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.6.2"
} }
processResources { processResources {
from(sourceSets.main.resources.srcDirs) { filter ReplaceTokens, tokens: [name: rootProject.name, version: project.version.toString(), description: project.description]
filter org.apache.tools.ant.filters.ReplaceTokens, tokens: [name: rootProject.name, version: project.version.toString(), description: project.description]
}
} }
java { java {
@ -60,7 +64,7 @@ shadowJar {
archiveClassifier.set("") archiveClassifier.set("")
relocate "org.bstats", "me.clip.placeholderapi.metrics" relocate "org.bstats", "me.clip.placeholderapi.metrics"
relocate "com.google.gson", "me.clip.placeholderapi.libs.gson" relocate "net.kyori", "me.clip.placeholderapi.libs.kyori"
} }
license { license {
@ -70,12 +74,8 @@ license {
header = file('config/headers/main.txt') header = file('config/headers/main.txt')
} }
matching('**/JSONMessage.java') {
header = file('config/headers/jsonmessage.txt')
}
ext { ext {
year = 2020 year = 2021
} }
} }
@ -83,15 +83,16 @@ test {
useJUnitPlatform() useJUnitPlatform()
} }
sourceSets { configurations {
test.compileClasspath += configurations.compileOnly testImplementation {
test.runtimeClasspath += configurations.compileOnly extendsFrom(compileOnly)
}
} }
publishing { publishing {
repositories { repositories {
maven { maven {
if (version.contains("-DEV-")) { if (version.contains("-DEV")) {
url = uri("https://repo.extendedclip.com/content/repositories/dev/") url = uri("https://repo.extendedclip.com/content/repositories/dev/")
} else { } else {
url = uri("https://repo.extendedclip.com/content/repositories/placeholderapi/") url = uri("https://repo.extendedclip.com/content/repositories/placeholderapi/")

@ -1,4 +1,4 @@
Copyright (c) 2018-2020 Peter Blood Copyright (c) 2018-2021 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:

Binary file not shown.

@ -1,6 +1,5 @@
#Tue Jul 14 23:27:02 AWST 2020
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

0
gradlew vendored Normal file → Executable file

21
gradlew.bat vendored

@ -40,7 +40,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 init if "%ERRORLEVEL%" == "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.
@ -54,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init if exist "%JAVA_EXE%" goto execute
echo. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@ -64,21 +64,6 @@ echo location of your Java installation.
goto fail goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute :execute
@rem Setup the command line @rem Setup the command line
@ -86,7 +71,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
@ -141,12 +141,28 @@ public final class PlaceholderAPI {
.collect(Collectors.toList()); .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 text Text to set the placeholder values in
* @return String containing all translated placeholders
*/
public static String setBracketPlaceholders(Player player, String text) { public static String setBracketPlaceholders(Player player, String text) {
return setBracketPlaceholders((OfflinePlayer) player, text); return setBracketPlaceholders((OfflinePlayer) player, text);
} }
/**
* 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 text List of Strings to set the placeholder values in
* @return String containing all translated placeholders
*/
public static List<String> setBracketPlaceholders(Player player, List<String> text) { public static List<String> setBracketPlaceholders(Player player, List<String> text) {
return setPlaceholders((OfflinePlayer) player, text); return setBracketPlaceholders((OfflinePlayer) player, text);
} }
/** /**
@ -216,7 +232,7 @@ public final class PlaceholderAPI {
/** /**
* Get all registered placeholder identifiers * Get all registered placeholder identifiers
* *
* @return All registered placeholder identifiers * @return A Set of type String containing the identifiers of all registered expansions.
*/ */
@NotNull @NotNull
public static Set<String> getRegisteredIdentifiers() { public static Set<String> getRegisteredIdentifiers() {
@ -227,7 +243,7 @@ public final class PlaceholderAPI {
/** /**
* Get the normal placeholder pattern. * Get the normal placeholder pattern.
* *
* @return The default Placeholder Pattern * @return Regex Pattern of {@literal [%]([^%]+)[%]}
*/ */
public static Pattern getPlaceholderPattern() { public static Pattern getPlaceholderPattern() {
return PLACEHOLDER_PATTERN; return PLACEHOLDER_PATTERN;
@ -236,7 +252,7 @@ public final class PlaceholderAPI {
/** /**
* Get the bracket placeholder pattern. * Get the bracket placeholder pattern.
* *
* @return the Bracket Placeholder Pattern * @return Regex Pattern of {@literal [{]([^{}]+)[}]}
*/ */
public static Pattern getBracketPlaceholderPattern() { public static Pattern getBracketPlaceholderPattern() {
return BRACKET_PLACEHOLDER_PATTERN; return BRACKET_PLACEHOLDER_PATTERN;
@ -245,7 +261,7 @@ public final class PlaceholderAPI {
/** /**
* Get the relational placeholder pattern. * Get the relational placeholder pattern.
* *
* @return The Relational Placeholder Pattern * @return Regex Pattern of {@literal [%](rel_)([^%]+)[%]}
*/ */
public static Pattern getRelationalPlaceholderPattern() { public static Pattern getRelationalPlaceholderPattern() {
return RELATIONAL_PLACEHOLDER_PATTERN; return RELATIONAL_PLACEHOLDER_PATTERN;

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
@ -32,7 +32,11 @@ 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.updatechecker.UpdateChecker; import me.clip.placeholderapi.updatechecker.UpdateChecker;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.serializer.craftbukkit.MinecraftComponentSerializer;
import org.bstats.bukkit.Metrics; import org.bstats.bukkit.Metrics;
import org.bstats.charts.AdvancedPie;
import org.bstats.charts.SimplePie;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginCommand; import org.bukkit.command.PluginCommand;
@ -73,6 +77,8 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
@NotNull @NotNull
private final CloudExpansionManager cloudExpansionManager = new CloudExpansionManager(this); private final CloudExpansionManager cloudExpansionManager = new CloudExpansionManager(this);
private BukkitAudiences adventure;
/** /**
* 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
* class, this is the main class that extends JavaPlugin. For most API methods, use static methods * class, this is the main class that extends JavaPlugin. For most API methods, use static methods
@ -138,6 +144,8 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
setupMetrics(); setupMetrics();
setupExpansions(); setupExpansions();
adventure = BukkitAudiences.create(this);
if (config.isCloudEnabled()) { if (config.isCloudEnabled()) {
getCloudExpansionManager().load(); getCloudExpansionManager().load();
} }
@ -156,6 +164,9 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
Bukkit.getScheduler().cancelTasks(this); Bukkit.getScheduler().cancelTasks(this);
adventure.close();
adventure = null;
instance = null; instance = null;
} }
@ -183,6 +194,15 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
return cloudExpansionManager; return cloudExpansionManager;
} }
@NotNull
public BukkitAudiences getAdventure() {
if(adventure == null) {
throw new IllegalStateException("Tried to access Adventure when the plugin was disabled!");
}
return adventure;
}
/** /**
* Obtain the configuration class for PlaceholderAPI. * Obtain the configuration class for PlaceholderAPI.
* *
@ -205,14 +225,13 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
} }
private void setupMetrics() { private void setupMetrics() {
final Metrics metrics = new Metrics(this); final Metrics metrics = new Metrics(this, 438);
metrics.addCustomChart(new Metrics.SimplePie("using_expansion_cloud", metrics.addCustomChart(new SimplePie("using_expansion_cloud",
() -> getPlaceholderAPIConfig().isCloudEnabled() ? "yes" : "no")); () -> getPlaceholderAPIConfig().isCloudEnabled() ? "yes" : "no"));
metrics.addCustomChart( metrics.addCustomChart(new SimplePie("using_spigot", () -> getServerVersion().isSpigot() ? "yes" : "no"));
new Metrics.SimplePie("using_spigot", () -> getServerVersion().isSpigot() ? "yes" : "no"));
metrics.addCustomChart(new Metrics.AdvancedPie("expansions_used", () -> { metrics.addCustomChart(new AdvancedPie("expansions_used", () -> {
final Map<String, Integer> values = new HashMap<>(); final Map<String, Integer> values = new HashMap<>();
for (final PlaceholderExpansion expansion : getLocalExpansionManager().getExpansions()) { for (final PlaceholderExpansion expansion : getLocalExpansionManager().getExpansions()) {

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
@ -26,14 +26,7 @@ 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.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
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;
@ -43,15 +36,22 @@ import me.clip.placeholderapi.commands.PlaceholderCommand;
import me.clip.placeholderapi.configuration.ExpansionSort; import me.clip.placeholderapi.configuration.ExpansionSort;
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;
import me.clip.placeholderapi.libs.JSONMessage;
import me.clip.placeholderapi.util.Format; import me.clip.placeholderapi.util.Format;
import me.clip.placeholderapi.util.Msg; import me.clip.placeholderapi.util.Msg;
import org.bukkit.ChatColor; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import static net.kyori.adventure.text.Component.*;
import static net.kyori.adventure.text.format.NamedTextColor.*;
public final class CommandECloudExpansionList extends PlaceholderCommand { public final class CommandECloudExpansionList extends PlaceholderCommand {
private static final int PAGE_SIZE = 10; private static final int PAGE_SIZE = 10;
@ -132,77 +132,81 @@ public final class CommandECloudExpansionList extends PlaceholderCommand {
builder.append(" &bPage&7: &a") builder.append(" &bPage&7: &a")
.append(page) .append(page)
.append("&r") .append("&r");
.append('\n');
} }
@NotNull private static Component getMessage(@NotNull final List<CloudExpansion> expansions,
private static JSONMessage getMessage(@NotNull final List<CloudExpansion> expansions,
final int page, final int limit, @NotNull final String target) { final int page, final int limit, @NotNull final String target) {
final SimpleDateFormat format = PlaceholderAPIPlugin.getDateFormat(); final SimpleDateFormat format = PlaceholderAPIPlugin.getDateFormat();
final StringBuilder tooltip = new StringBuilder(); final TextComponent.Builder message = text();
final JSONMessage message = JSONMessage.create();
for (int index = 0; index < expansions.size(); index++) { for (int index = 0; index < expansions.size(); index++) {
final CloudExpansion expansion = expansions.get(index); final CloudExpansion expansion = expansions.get(index);
final TextComponent.Builder line = text();
tooltip.append("&bClick to download this expansion!") final int expansionNumber = index + ((page - 1) * PAGE_SIZE) + 1;
.append('\n') line.append(text(expansionNumber + ". ", DARK_GRAY));
.append('\n')
.append("&bAuthor: &f")
.append(expansion.getAuthor())
.append('\n')
.append("&bVerified: ")
.append(expansion.isVerified() ? "&a&l✔&r" : "&c&l❌&r")
.append('\n')
.append("&bLatest Version: &f")
.append(expansion.getLatestVersion())
.append('\n')
.append("&bReleased: &f")
.append(format.format(expansion.getLastUpdate()));
final String description = expansion.getDescription(); final NamedTextColor expansionColour;
if (description != null && !description.isEmpty()) {
tooltip.append('\n') if (expansion.shouldUpdate()) {
.append('\n') expansionColour = GOLD;
.append("&f") } else {
.append(description.replace("\r", "").trim()); if (expansion.hasExpansion()) {
expansionColour = GREEN;
} else {
expansionColour = GRAY;
}
} }
message.then(Msg.color( line.append(text(expansion.getName(), expansionColour));
"&8" + (index + ((page - 1) * PAGE_SIZE) + 1) + ".&r " + (expansion.shouldUpdate() ? "&6"
: expansion.hasExpansion() ? "&a" : "&7") + expansion.getName()));
message.tooltip(Msg.color(tooltip.toString())); line.clickEvent(ClickEvent.suggestCommand("/papi ecloud download " + expansion.getName()));
message.suggestCommand("/papi ecloud download " + expansion.getName());
if (index < expansions.size() - 1) { final TextComponent.Builder hoverText = text("Click to download this expansion!", AQUA)
message.newline(); .append(newline()).append(newline())
.append(text("Author: ", AQUA)).append(text(expansion.getAuthor(), WHITE))
.append(newline())
.append(text("Verified: ", AQUA)).append(text(expansion.isVerified() ? "" : "", expansion.isVerified() ? GREEN : RED, TextDecoration.BOLD))
.append(newline())
.append(text("Released: ", AQUA)).append(text(format.format(expansion.getLastUpdate()), WHITE))
.toBuilder();
Optional.ofNullable(expansion.getDescription())
.filter(description -> !description.isEmpty())
.ifPresent(description -> hoverText.append(newline()).append(newline())
.append(text(description.replace("\r", "").trim(), WHITE))
);
line.hoverEvent(HoverEvent.showText(hoverText.build()));
if (index != expansions.size() - 1) {
line.append(newline());
} }
tooltip.setLength(0); message.append(line.build());
} }
if (limit > 1) { if (limit > 1) {
message.newline(); message.append(newline());
final TextComponent.Builder left = text("", page > 1 ? GRAY : DARK_GRAY).toBuilder();
message.then("")
.color(page > 1 ? ChatColor.GRAY : ChatColor.DARK_GRAY);
if (page > 1) { if (page > 1) {
message.runCommand("/papi ecloud list " + target + " " + (page - 1)); left.clickEvent(ClickEvent.runCommand("/papi ecloud list " + target + " " + (page - 1)));
} }
message.then(" " + page + " ").color(ChatColor.GREEN); final TextComponent.Builder right = text("", page < limit ? GRAY : DARK_GRAY).toBuilder();
message.then("")
.color(page < limit ? ChatColor.GRAY : ChatColor.DARK_GRAY);
if (page < limit) { if (page < limit) {
message.runCommand("/papi ecloud list " + target + " " + (page + 1)); right.clickEvent(ClickEvent.runCommand("/papi ecloud list " + target + " " + (page + 1)));
} }
message.append(left, text(" " + page + " ", GREEN), right);
} }
return message; return message.build();
} }
private static void addExpansionTable(@NotNull final List<CloudExpansion> expansions, private static void addExpansionTable(@NotNull final List<CloudExpansion> expansions,
@ -321,8 +325,8 @@ public final class CommandECloudExpansionList extends PlaceholderCommand {
final int limit = (int) Math.ceil((double) expansions.size() / PAGE_SIZE); final int limit = (int) Math.ceil((double) expansions.size() / PAGE_SIZE);
final JSONMessage message = getMessage(values, page, limit, params.get(0)); final Component message = getMessage(values, page, limit, params.get(0));
message.send(((Player) sender)); plugin.getAdventure().player((Player) sender).sendMessage(message);
} }
@Override @Override

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
@ -21,7 +21,17 @@
package me.clip.placeholderapi.commands.impl.local; package me.clip.placeholderapi.commands.impl.local;
import com.google.common.io.CharStreams; import com.google.common.io.CharStreams;
import com.google.gson.JsonParser; import com.google.gson.Gson;
import com.google.gson.JsonObject;
import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.clip.placeholderapi.util.Msg;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@ -41,20 +51,15 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionException;
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.commands.PlaceholderCommand;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.clip.placeholderapi.util.Msg;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable;
public final class CommandDump extends PlaceholderCommand { public final class CommandDump extends PlaceholderCommand {
@NotNull @NotNull
private static final String URL = "https://paste.helpch.at/"; private static final String URL = "https://paste.helpch.at/";
@NotNull
private static final Gson gson = new Gson();
@NotNull @NotNull
private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter
.ofLocalizedDateTime(FormatStyle.LONG) .ofLocalizedDateTime(FormatStyle.LONG)
@ -102,9 +107,8 @@ public final class CommandDump extends PlaceholderCommand {
try (final InputStream stream = connection.getInputStream()) { try (final InputStream stream = connection.getInputStream()) {
//noinspection UnstableApiUsage //noinspection UnstableApiUsage
final String json = CharStreams final String json = CharStreams.toString(new InputStreamReader(stream, StandardCharsets.UTF_8));
.toString(new InputStreamReader(stream, StandardCharsets.UTF_8)); return gson.fromJson(json, JsonObject.class).get("key").getAsString();
return JsonParser.parseString(json).getAsJsonObject().get("key").getAsString();
} }
} catch (final IOException ex) { } catch (final IOException ex) {
throw new CompletionException(ex); throw new CompletionException(ex);

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
@ -26,6 +26,10 @@ import org.bukkit.event.Event;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/**
* Indicates that a {@link PlaceholderExpansion} has been registered by
* PlaceholderAPI.
*/
public final class ExpansionRegisterEvent extends Event implements Cancellable { public final class ExpansionRegisterEvent extends Event implements Cancellable {
@NotNull @NotNull
@ -43,6 +47,11 @@ public final class ExpansionRegisterEvent extends Event implements Cancellable {
return HANDLERS; return HANDLERS;
} }
/**
* The {@link PlaceholderExpansion expansion} that was registered.
*
* @return The {@link PlaceholderExpansion} instance.
*/
@NotNull @NotNull
public PlaceholderExpansion getExpansion() { public PlaceholderExpansion getExpansion() {
return expansion; return expansion;

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
@ -25,6 +25,10 @@ import org.bukkit.event.Event;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/**
* Indicates that a {@link PlaceholderExpansion} had been unregistered by
* PlaceholderAPI.
*/
public final class ExpansionUnregisterEvent extends Event { public final class ExpansionUnregisterEvent extends Event {
@NotNull @NotNull
@ -43,6 +47,11 @@ public final class ExpansionUnregisterEvent extends Event {
return HANDLERS; return HANDLERS;
} }
/**
* The {@link PlaceholderExpansion expansion} that was unregistered.
*
* @return The {@link PlaceholderExpansion} instance.
*/
@NotNull @NotNull
public PlaceholderExpansion getExpansion() { public PlaceholderExpansion getExpansion() {
return expansion; return expansion;

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
@ -26,7 +26,10 @@ import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
* This event is called when all expansions are loaded (when reloading config, on plugin start and on server load). * Indicates that <b>all</b> {@link me.clip.placeholderapi.expansion.PlaceholderExpansion PlayceholderExpansions}
* have been loaded.
* <br/>This event is fired on Server load and when reloading the
* confiuration.
*/ */
public class ExpansionsLoadedEvent extends Event { public class ExpansionsLoadedEvent extends Event {

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
@ -24,7 +24,7 @@ import java.util.Map;
/** /**
* Any {@link PlaceholderExpansion} class which implements configurable will have any options listed * Any {@link PlaceholderExpansion} class which implements configurable will have any options listed
* in the getDefaults map automatically added to the PlaceholderAPI config.yml file * in the {@link #getDefaults()} map automatically added to the PlaceholderAPI config.yml file
* *
* @author Ryan McCarthy * @author Ryan McCarthy
*/ */

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
@ -41,7 +41,8 @@ public enum NMSVersion {
SPIGOT_1_15_R1("v1_15_R1"), SPIGOT_1_15_R1("v1_15_R1"),
SPIGOT_1_16_R1("v1_16_R1"), SPIGOT_1_16_R1("v1_16_R1"),
SPIGOT_1_16_R2("v1_16_R2"), SPIGOT_1_16_R2("v1_16_R2"),
SPIGOT_1_16_R3("v1_16_R3"); SPIGOT_1_16_R3("v1_16_R3"),
SPIGOT_1_17_R1("v1_17_R1");
private final String version; private final String version;

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
@ -22,7 +22,6 @@ package me.clip.placeholderapi.expansion;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects;
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;
@ -32,10 +31,17 @@ import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
/**
* Any class extending this will be able to get registered as a PlaceholderExpansion.
* <br>The registration either happens automatically when the jar file containing a
* class extending this one is located under the {@code PlaceholderAPI/expansions}
* directory or when the {@link #register()} method is called by said class.
*/
public abstract class PlaceholderExpansion extends PlaceholderHook { public abstract class PlaceholderExpansion extends PlaceholderHook {
/** /**
* The placeholder identifier of this expansion * The placeholder identifier of this expansion. May not contain {@literal %},
* {@literal {}} or _
* *
* @return placeholder identifier that is associated with this expansion * @return placeholder identifier that is associated with this expansion
*/ */
@ -154,17 +160,39 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
// === Configuration === // === Configuration ===
/**
* Gets the ConfigurationSection of the expansion located in the config.yml of PlaceholderAPI or
* null when not specified.
* <br>You may use the {@link Configurable} interface to define default values set
*
* @return ConfigurationSection that this epxpansion has.
*/
@Nullable @Nullable
public final ConfigurationSection getConfigSection() { public final ConfigurationSection getConfigSection() {
return getPlaceholderAPI().getConfig().getConfigurationSection("expansions." + getIdentifier()); return getPlaceholderAPI().getConfig().getConfigurationSection("expansions." + getIdentifier());
} }
/**
* Gets the ConfigurationSection relative to the {@link #getConfigSection() default one} set
* by the expansion or null when the default ConfigurationSection is null
*
* @param path The path to get the ConfigurationSection from. This is relative to the default section
* @return ConfigurationSection relative to the default section
*/
@Nullable @Nullable
public final ConfigurationSection getConfigSection(@NotNull final String path) { public final ConfigurationSection getConfigSection(@NotNull final String path) {
final ConfigurationSection section = getConfigSection(); final ConfigurationSection section = getConfigSection();
return section == null ? null : section.getConfigurationSection(path); return section == null ? null : section.getConfigurationSection(path);
} }
/**
* Gets the Object relative to the {@link #getConfigSection() default ConfigurationSection} set
* by the expansion or the provided Default Object, when the default ConfigurationSection is null
*
* @param path The path to get the Object from. This is relative to the default section
* @param def The default Object to return when the ConfigurationSection returns null
* @return Object from the provided path or the default one provided
*/
@Nullable @Nullable
@Contract("_, !null -> !null") @Contract("_, !null -> !null")
public final Object get(@NotNull final String path, final Object def) { public final Object get(@NotNull final String path, final Object def) {
@ -172,21 +200,53 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
return section == null ? def : section.get(path, def); return section == null ? def : section.get(path, def);
} }
/**
* Gets the int relative to the {@link #getConfigSection() default ConfigurationSection} set
* by the expansion or the provided Default int, when the default ConfigurationSection is null
*
* @param path The path to get the int from. This is relative to the default section
* @param def The default int to return when the ConfigurationSection returns null
* @return int from the provided path or the default one provided
*/
public final int getInt(@NotNull final String path, final int def) { public final int getInt(@NotNull final String path, final int def) {
final ConfigurationSection section = getConfigSection(); final ConfigurationSection section = getConfigSection();
return section == null ? def : section.getInt(path, def); return section == null ? def : section.getInt(path, def);
} }
/**
* Gets the long relative to the {@link #getConfigSection() default ConfigurationSection} set
* by the expansion or the provided Default long, when the default ConfigurationSection is null
*
* @param path The path to get the long from. This is relative to the default section
* @param def The default long to return when the ConfigurationSection returns null
* @return long from the provided path or the default one provided
*/
public final long getLong(@NotNull final String path, final long def) { public final long getLong(@NotNull final String path, final long def) {
final ConfigurationSection section = getConfigSection(); final ConfigurationSection section = getConfigSection();
return section == null ? def : section.getLong(path, def); return section == null ? def : section.getLong(path, def);
} }
/**
* Gets the double relative to the {@link #getConfigSection() default ConfigurationSection} set
* by the expansion or the provided Default double, when the default ConfigurationSection is null
*
* @param path The path to get the double from. This is relative to the default section
* @param def The default double to return when the ConfigurationSection returns null
* @return double from the provided path or the default one provided
*/
public final double getDouble(@NotNull final String path, final double def) { public final double getDouble(@NotNull final String path, final double def) {
final ConfigurationSection section = getConfigSection(); final ConfigurationSection section = getConfigSection();
return section == null ? def : section.getDouble(path, def); return section == null ? def : section.getDouble(path, def);
} }
/**
* Gets the String relative to the {@link #getConfigSection() default ConfigurationSection} set
* by the expansion or the provided Default String, when the default ConfigurationSection is null
*
* @param path The path to get the String from. This is relative to the default section
* @param def The default String to return when the ConfigurationSection returns null. Can be null
* @return String from the provided path or the default one provided
*/
@Nullable @Nullable
@Contract("_, !null -> !null") @Contract("_, !null -> !null")
public final String getString(@NotNull final String path, @Nullable final String def) { public final String getString(@NotNull final String path, @Nullable final String def) {
@ -194,23 +254,58 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
return section == null ? def : section.getString(path, def); return section == null ? def : section.getString(path, def);
} }
/**
* Gets a String List relative to the {@link #getConfigSection() default ConfigurationSection} set
* by the expansion or an empty List, when the default ConfigurationSection is null
*
* @param path The path to get the String list from. This is relative to the default section
* @return String list from the provided path or an empty list
*/
@NotNull @NotNull
public final List<String> getStringList(@NotNull final String path) { public final List<String> getStringList(@NotNull final String path) {
final ConfigurationSection section = getConfigSection(); final ConfigurationSection section = getConfigSection();
return section == null ? Collections.emptyList() : section.getStringList(path); return section == null ? Collections.emptyList() : section.getStringList(path);
} }
/**
* Gets the boolean relative to the {@link #getConfigSection() default ConfigurationSection} set
* by the expansion or the default boolean, when the default ConfigurationSection is null
*
* @param path The path to get the boolean from. This is relative to the default section
* @param def The default boolean to return when the ConfigurationSection is null
* @return boolean from the provided path or the default one provided
*/
@NotNull @NotNull
public final boolean getBoolean(@NotNull final String path, final boolean def) { public final boolean getBoolean(@NotNull final String path, final boolean def) {
final ConfigurationSection section = getConfigSection(); final ConfigurationSection section = getConfigSection();
return section == null ? def : section.getBoolean(path, def); return section == null ? def : section.getBoolean(path, def);
} }
/**
* Whether the {@link #getConfigSection() default ConfigurationSection} contains the provided path
* or not. This will return {@code false} when either the default section is null, or doesn't
* contain the provided path
*
* @param path The path to check
* @return true when the default ConfigurationSection is not null and contains the path, false otherwise
*/
public final boolean configurationContains(@NotNull final String path) { public final boolean configurationContains(@NotNull final String path) {
final ConfigurationSection section = getConfigSection(); final ConfigurationSection section = getConfigSection();
return section != null && section.contains(path); return section != null && section.contains(path);
} }
/**
* Whether the provided Object is an instance of this PlaceholderExpansion.
* <br>This method will perform the following checks in order:
* <br><ul>
* <li>Checks if Object equals the class. Returns true when equal and continues otherwise</li>
* <li>Checks if the Object is an instance of a PlaceholderExpansion. Returns false if not</li>
* <li>Checks if the Object's Identifier, Author and version equal the one of this class</li>
* </ul>
*
* @param o The Object to check
* @return true or false depending on the above mentioned checks
*/
@Override @Override
public final boolean equals(final Object o) { public final boolean equals(final Object o) {
if (this == o) { if (this == o) {
@ -227,6 +322,11 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
getVersion().equals(expansion.getVersion()); getVersion().equals(expansion.getVersion());
} }
/**
* Returns a String containing the Expansion's name, author and version
*
* @return String containing name, author and version of the expansion
*/
@Override @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']", getName(),
@ -267,5 +367,4 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
public String getLink() { public String getLink() {
return null; return null;
} }
} }

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
@ -46,18 +46,25 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.io.File; import java.io.File;
import java.lang.reflect.Modifier;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException; 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.logging.Level;
import java.util.stream.Collectors;
public final class LocalExpansionManager implements Listener { public final class LocalExpansionManager implements Listener {
@NotNull @NotNull
private static final String EXPANSIONS_FOLDER_NAME = "expansions"; private static final String EXPANSIONS_FOLDER_NAME = "expansions";
@NotNull
private static final Set<MethodSignature> ABSTRACT_EXPANSION_METHODS = Arrays.stream(PlaceholderExpansion.class.getDeclaredMethods())
.filter(method -> Modifier.isAbstract(method.getModifiers()))
.map(method -> new MethodSignature(method.getName(), method.getParameterTypes()))
.collect(Collectors.toSet());
@NotNull @NotNull
private final File folder; private final File folder;
@ -153,15 +160,28 @@ public final class LocalExpansionManager implements Listener {
@NotNull final Class<? extends PlaceholderExpansion> clazz) { @NotNull final Class<? extends PlaceholderExpansion> clazz) {
try { try {
final PlaceholderExpansion expansion = createExpansionInstance(clazz); final PlaceholderExpansion expansion = createExpansionInstance(clazz);
if (expansion == null || !expansion.register()) {
Objects.requireNonNull(expansion.getAuthor(), "The expansion author is null!");
Objects.requireNonNull(expansion.getIdentifier(), "The expansion identifier is null!");
Objects.requireNonNull(expansion.getVersion(), "The expansion version is null!");
if (!expansion.register()) {
return Optional.empty(); return Optional.empty();
} }
return Optional.of(expansion); return Optional.of(expansion);
} catch (final LinkageError ex) { } catch (LinkageError | NullPointerException ex) {
plugin.getLogger().severe("Failed to load Expansion class " + clazz.getSimpleName() + final String reason;
" (Is a dependency missing?)");
plugin.getLogger().severe("Cause: " + ex.getClass().getSimpleName() + " " + ex.getMessage()); if (ex instanceof LinkageError) {
reason = " (Is a dependency missing?)";
} else {
reason = " - One of its properties is null which is not allowed!";
}
plugin.getLogger().severe("Failed to load expansion class " + clazz.getSimpleName() +
reason);
plugin.getLogger().log(Level.SEVERE, "", ex);
} }
return Optional.empty(); return Optional.empty();
@ -341,6 +361,16 @@ public final class LocalExpansionManager implements Listener {
if (expansionClass == null) { if (expansionClass == null) {
plugin.getLogger().severe("Failed to load Expansion: " + file.getName() + ", as it does not have" + plugin.getLogger().severe("Failed to load Expansion: " + file.getName() + ", as it does not have" +
" a class which extends PlaceholderExpansion."); " a class which extends PlaceholderExpansion.");
return null;
}
Set<MethodSignature> expansionMethods = Arrays.stream(expansionClass.getDeclaredMethods())
.map(method -> new MethodSignature(method.getName(), method.getParameterTypes()))
.collect(Collectors.toSet());
if (!expansionMethods.containsAll(ABSTRACT_EXPANSION_METHODS)) {
plugin.getLogger().severe("Failed to load Expansion: " + file.getName() + ", as it does not have the" +
" required methods declared for a PlaceholderExpansion.");
return null;
} }
return expansionClass; return expansionClass;
@ -366,7 +396,7 @@ public final class LocalExpansionManager implements Listener {
throw ((LinkageError) ex.getCause()); throw ((LinkageError) ex.getCause());
} }
plugin.getLogger().warning("There was an issue with loading an expansion"); plugin.getLogger().warning("There was an issue with loading an expansion.");
return null; return null;
} }

@ -0,0 +1,37 @@
package me.clip.placeholderapi.expansion.manager;
import java.util.Arrays;
import java.util.Objects;
public final class MethodSignature {
private final String name;
private final Class<?>[] params;
protected MethodSignature(String name, Class<?>[] params) {
this.name = name;
this.params = params;
}
public String getName() {
return name;
}
public Class<?>[] getParams() {
return params;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MethodSignature that = (MethodSignature) o;
return Objects.equals(name, that.name) && Arrays.equals(params, that.params);
}
@Override
public int hashCode() {
int result = Objects.hash(name);
result = 31 * result + Arrays.hashCode(params);
return result;
}
}

File diff suppressed because it is too large Load Diff

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
@ -23,6 +23,7 @@ package me.clip.placeholderapi.updatechecker;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.URL; import java.net.URL;
import java.util.Arrays;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.util.Msg; import me.clip.placeholderapi.util.Msg;
@ -90,17 +91,24 @@ public class UpdateChecker implements Listener {
return false; return false;
} }
String plV = toReadable(pluginVersion); int[] plV = toReadable(pluginVersion);
String spV = toReadable(spigotVersion); int[] spV = toReadable(spigotVersion);
return plV.compareTo(spV) < 0;
if (plV[0] < spV[0]) {
return true;
} else if ((plV[1] < spV[1])) {
return true;
} else {
return plV[2] < spV[2];
}
} }
private String toReadable(String version) { private int[] toReadable(String version) {
if (version.contains("-DEV-")) { if (version.contains("-DEV")) {
version = version.split("-DEV-")[0]; version = version.split("-DEV")[0];
} }
return version.replaceAll("\\.", ""); return Arrays.stream(version.split("\\.")).mapToInt(Integer::parseInt).toArray();
} }
@EventHandler(priority = EventPriority.MONITOR) @EventHandler(priority = EventPriority.MONITOR)

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
@ -42,13 +42,11 @@ public class FileUtil {
} }
final URL jar = file.toURI().toURL(); final URL jar = file.toURI().toURL();
final URLClassLoader loader = new URLClassLoader(new URL[]{jar}, clazz.getClassLoader());
final List<String> matches = new ArrayList<>(); final List<String> matches = new ArrayList<>();
final List<Class<? extends T>> classes = new ArrayList<>(); final List<Class<? extends T>> classes = new ArrayList<>();
try (final JarInputStream stream = new JarInputStream( try (final JarInputStream stream = new JarInputStream(jar.openStream())) {
jar.openStream()); final URLClassLoader loader = new URLClassLoader(new URL[]{jar},
clazz.getClassLoader())) {
JarEntry entry; JarEntry entry;
while ((entry = stream.getNextJarEntry()) != null) { while ((entry = stream.getNextJarEntry()) != null) {
final String name = entry.getName(); final String name = entry.getName();
@ -69,8 +67,11 @@ public class FileUtil {
} }
} }
} }
if (classes.isEmpty()) {
return classes.isEmpty() ? null : classes.get(0); loader.close();
return null;
}
return classes.get(0);
} }
} }

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,9 +2,9 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 PlaceholderAPI Team
* *
* PlaceholderAPI free software: you can redistribute it and/or modify * PlaceholderAPI is 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
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI * This file is part of PlaceholderAPI
* *
* PlaceholderAPI * PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 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 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 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 - 2020 PlaceholderAPI Team * Copyright (c) 2015 - 2021 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