From 4300bf7d1e519fc7ef348bc538422795991510a5 Mon Sep 17 00:00:00 2001 From: Andre_601 <11576465+Andre601@users.noreply.github.com> Date: Thu, 9 Sep 2021 18:31:29 +0200 Subject: [PATCH] Pull latest changes from master into docs/wiki (#712) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 Co-authored-by: darbyjack * 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 Co-authored-by: ElijahRus250 <64851720+ElijahRus250@users.noreply.github.com> Co-authored-by: PiggyPiglet Co-authored-by: Huynh Tien Co-authored-by: Vaishnav Anil Co-authored-by: Starmism Co-authored-by: PiggyPiglet --- .github/ISSUE_TEMPLATE/bug_report.md | 43 - .github/ISSUE_TEMPLATE/bug_report.yml | 101 ++ .github/ISSUE_TEMPLATE/feature_request.md | 31 - .github/ISSUE_TEMPLATE/feature_request.yml | 62 + .github/workflows/pr_build_jars.yml | 31 + .github/workflows/wiki.yml | 28 +- README.md | 10 +- build.gradle | 41 +- config/headers/jsonmessage.txt | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 58910 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 5 +- gradlew | 2 +- gradlew.bat | 21 +- .../clip/placeholderapi/PlaceholderAPI.java | 40 +- .../placeholderapi/PlaceholderAPIPlugin.java | 33 +- .../clip/placeholderapi/PlaceholderHook.java | 4 +- .../commands/PlaceholderCommand.java | 4 +- .../commands/PlaceholderCommandRouter.java | 4 +- .../commands/impl/cloud/CommandECloud.java | 4 +- .../impl/cloud/CommandECloudClear.java | 4 +- .../impl/cloud/CommandECloudDownload.java | 4 +- .../cloud/CommandECloudExpansionInfo.java | 4 +- .../cloud/CommandECloudExpansionList.java | 118 +- .../CommandECloudExpansionPlaceholders.java | 4 +- .../impl/cloud/CommandECloudRefresh.java | 4 +- .../impl/cloud/CommandECloudStatus.java | 4 +- .../impl/cloud/CommandECloudToggle.java | 4 +- .../impl/cloud/CommandECloudUpdate.java | 4 +- .../commands/impl/local/CommandDump.java | 32 +- .../impl/local/CommandExpansionRegister.java | 4 +- .../local/CommandExpansionUnregister.java | 4 +- .../commands/impl/local/CommandHelp.java | 4 +- .../commands/impl/local/CommandInfo.java | 4 +- .../commands/impl/local/CommandList.java | 4 +- .../commands/impl/local/CommandParse.java | 4 +- .../commands/impl/local/CommandReload.java | 4 +- .../commands/impl/local/CommandVersion.java | 4 +- .../configuration/ExpansionSort.java | 4 +- .../configuration/PlaceholderAPIConfig.java | 4 +- .../events/ExpansionRegisterEvent.java | 15 +- .../events/ExpansionUnregisterEvent.java | 15 +- .../events/ExpansionsLoadedEvent.java | 9 +- .../events/PlaceholderHookUnloadEvent.java | 4 +- .../exceptions/NoDefaultCommandException.java | 4 +- .../placeholderapi/expansion/Cacheable.java | 4 +- .../placeholderapi/expansion/Cleanable.java | 4 +- .../expansion/Configurable.java | 6 +- .../placeholderapi/expansion/NMSVersion.java | 7 +- .../expansion/PlaceholderExpansion.java | 129 +- .../placeholderapi/expansion/Relational.java | 4 +- .../placeholderapi/expansion/Taskable.java | 4 +- .../placeholderapi/expansion/Version.java | 4 +- .../expansion/VersionSpecific.java | 4 +- .../expansion/cloud/CloudExpansion.java | 4 +- .../manager/CloudExpansionManager.java | 4 +- .../manager/LocalExpansionManager.java | 50 +- .../expansion/manager/MethodSignature.java | 37 + .../clip/placeholderapi/libs/JSONMessage.java | 1120 ----------------- .../listeners/ServerLoadEventListener.java | 4 +- .../replacer/CharsReplacer.java | 6 +- .../replacer/RegexReplacer.java | 4 +- .../placeholderapi/replacer/Replacer.java | 4 +- .../updatechecker/UpdateChecker.java | 26 +- .../me/clip/placeholderapi/util/FileUtil.java | 17 +- .../me/clip/placeholderapi/util/Format.java | 4 +- .../me/clip/placeholderapi/util/Futures.java | 4 +- .../java/me/clip/placeholderapi/util/Msg.java | 4 +- .../clip/placeholderapi/util/TimeFormat.java | 4 +- .../me/clip/placeholderapi/util/TimeUtil.java | 4 +- .../java/me/clip/placeholderapi/Values.java | 2 +- .../replacer/ReplacerBenchmarks.java | 2 +- .../replacer/ReplacerUnitTester.java | 2 +- 72 files changed, 709 insertions(+), 1494 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .github/workflows/pr_build_jars.yml mode change 100644 => 100755 gradlew create mode 100644 src/main/java/me/clip/placeholderapi/expansion/manager/MethodSignature.java delete mode 100644 src/main/java/me/clip/placeholderapi/libs/JSONMessage.java diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index c4ab045..0000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -name: Bug Report -about: Report bugs of PlaceholderAPI with this template - ---- - - -## Bug Report - -### Issue - - - -### Expected behaviour - - - -### Actual behaviour - - - -### How to reproduce - - -1. - -### `/papi dump` output - diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..bb353aa --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -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..." diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index c66b3e4..0000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -name: Feature Request -about: Request a update/change of the PlaceholderAPI-code - ---- - - - -## Feature Request - -### Type - - - -- [ ] 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: __________ - -### Description - - diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..d6f6087 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -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..." diff --git a/.github/workflows/pr_build_jars.yml b/.github/workflows/pr_build_jars.yml new file mode 100644 index 0000000..ba543f6 --- /dev/null +++ b/.github/workflows/pr_build_jars.yml @@ -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" diff --git a/.github/workflows/wiki.yml b/.github/workflows/wiki.yml index 02864b8..63abe4c 100644 --- a/.github/workflows/wiki.yml +++ b/.github/workflows/wiki.yml @@ -27,26 +27,10 @@ jobs: - name: 'Checkout Code' uses: actions/Checkout@v2 - name: 'Update Wiki' - uses: docker://decathlon/wiki-page-creator-action:latest + uses: Andrew-Chen-Wang/github-wiki-action@v2 env: - # - # We can use the E-Mail and Name of the GitHub Actions account - # for our convenience. - # - ACTION_MAIL: 'actions@github.com' - 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 + WIKI_DIR: wiki/ + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_EMAIL: 'actions@github.com' + GH_NAME: 'github-actions[bot]' + EXCLUDED_FILES: 'README.md' diff --git a/README.md b/README.md index a6c7930..2ea8404 100644 --- a/README.md +++ b/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 [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 [![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. - - +## Contribute +If you would like to contribute towards PlaceholderAPI should you take a look at our [Contributing file][contributing] for the ins and outs on how you can do that and what you need to keep in mind. + +## 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 - [Issue Tracker][issues] diff --git a/build.gradle b/build.gradle index 41ba3ca..5df263f 100644 --- a/build.gradle +++ b/build.gradle @@ -1,8 +1,10 @@ +import org.apache.tools.ant.filters.ReplaceTokens + plugins { id "java" id "maven-publish" - id "net.minecrell.licenser" version "0.4.1" - id "com.github.johnrengelman.shadow" version "6.0.0" + id "org.cadixdev.licenser" version "0.6.0" + id "com.github.johnrengelman.shadow" version "7.0.0" } group "me.clip" @@ -11,30 +13,32 @@ version "2.10.10-DEV-${System.getProperty("BUILD_NUMBER")}" description "An awesome placeholder provider!" repositories { + maven({ url = "https://oss.sonatype.org/content/repositories/snapshots/" }) + mavenCentral() + mavenLocal() maven({ url = "https://repo.codemc.org/repository/maven-public" }) maven({ url = "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" }) } dependencies { - implementation "com.google.code.gson:gson:2.8.6" - implementation "org.bstats:bstats-bukkit:1.5" + implementation "org.bstats:bstats-bukkit:2.2.1" - 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" testImplementation "org.openjdk.jmh:jmh-core:1.23" testImplementation "org.openjdk.jmh:jmh-generator-annprocess:1.23" - testCompile "org.junit.jupiter:junit-jupiter-engine:5.6.2" - testRuntime "org.junit.jupiter:junit-jupiter-engine:5.6.2" + testImplementation "org.junit.jupiter:junit-jupiter-engine:5.6.2" + testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.6.2" } processResources { - from(sourceSets.main.resources.srcDirs) { - filter org.apache.tools.ant.filters.ReplaceTokens, tokens: [name: rootProject.name, version: project.version.toString(), description: project.description] - } + filter ReplaceTokens, tokens: [name: rootProject.name, version: project.version.toString(), description: project.description] } java { @@ -60,7 +64,7 @@ shadowJar { archiveClassifier.set("") 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 { @@ -70,12 +74,8 @@ license { header = file('config/headers/main.txt') } - matching('**/JSONMessage.java') { - header = file('config/headers/jsonmessage.txt') - } - ext { - year = 2020 + year = 2021 } } @@ -83,15 +83,16 @@ test { useJUnitPlatform() } -sourceSets { - test.compileClasspath += configurations.compileOnly - test.runtimeClasspath += configurations.compileOnly +configurations { + testImplementation { + extendsFrom(compileOnly) + } } publishing { repositories { maven { - if (version.contains("-DEV-")) { + if (version.contains("-DEV")) { url = uri("https://repo.extendedclip.com/content/repositories/dev/") } else { url = uri("https://repo.extendedclip.com/content/repositories/placeholderapi/") diff --git a/config/headers/jsonmessage.txt b/config/headers/jsonmessage.txt index ec15330..9fddec6 100644 --- a/config/headers/jsonmessage.txt +++ b/config/headers/jsonmessage.txt @@ -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: diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 62d4c053550b91381bbd28b1afc82d634bf73a8a..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f 100644 GIT binary patch delta 6656 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 Yte!%o?r4GTrVtxD61Ym!|5fq-1K$0e!T1w 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c78a2b9..0f80bbf 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -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 distributionPath=wrapper/dists -zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 index fbd7c51..4f906e0 --- a/gradlew +++ b/gradlew @@ -130,7 +130,7 @@ fi if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath diff --git a/gradlew.bat b/gradlew.bat index 5093609..107acd3 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. 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_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -64,21 +64,6 @@ echo location of your Java installation. 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 @rem Setup the command line @@ -86,7 +71,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @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 @rem End local scope for the variables with windows NT shell diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java index e162d09..beb93ce 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. @@ -140,13 +140,29 @@ public final class PlaceholderAPI { return text.stream().map(line -> setBracketPlaceholders(player, line)) .collect(Collectors.toList()); } - + + /** + * Translates all placeholders into their corresponding values. + *
The pattern of a valid placeholder is {@literal {_}}. + * + * @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) { return setBracketPlaceholders((OfflinePlayer) player, text); } - + + /** + * Translates all placeholders into their corresponding values. + *
The pattern of a valid placeholder is {@literal {_}}. + * + * @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 setBracketPlaceholders(Player player, List text) { - return setPlaceholders((OfflinePlayer) player, text); + return setBracketPlaceholders((OfflinePlayer) player, text); } /** @@ -216,7 +232,7 @@ public final class PlaceholderAPI { /** * Get all registered placeholder identifiers * - * @return All registered placeholder identifiers + * @return A Set of type String containing the identifiers of all registered expansions. */ @NotNull public static Set getRegisteredIdentifiers() { @@ -226,8 +242,8 @@ public final class PlaceholderAPI { /** * Get the normal placeholder pattern. - * - * @return The default Placeholder Pattern + * + * @return Regex Pattern of {@literal [%]([^%]+)[%]} */ public static Pattern getPlaceholderPattern() { return PLACEHOLDER_PATTERN; @@ -235,8 +251,8 @@ public final class PlaceholderAPI { /** * Get the bracket placeholder pattern. - * - * @return the Bracket Placeholder Pattern + * + * @return Regex Pattern of {@literal [{]([^{}]+)[}]} */ public static Pattern getBracketPlaceholderPattern() { return BRACKET_PLACEHOLDER_PATTERN; @@ -244,8 +260,8 @@ public final class PlaceholderAPI { /** * Get the relational placeholder pattern. - * - * @return The Relational Placeholder Pattern + * + * @return Regex Pattern of {@literal [%](rel_)([^%]+)[%]} */ public static Pattern getRelationalPlaceholderPattern() { return RELATIONAL_PLACEHOLDER_PATTERN; diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java b/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java index fe07931..b121bd3 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (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.listeners.ServerLoadEventListener; 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.charts.AdvancedPie; +import org.bstats.charts.SimplePie; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.command.PluginCommand; @@ -73,6 +77,8 @@ public final class PlaceholderAPIPlugin extends JavaPlugin { @NotNull 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 * 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(); setupExpansions(); + adventure = BukkitAudiences.create(this); + if (config.isCloudEnabled()) { getCloudExpansionManager().load(); } @@ -156,6 +164,9 @@ public final class PlaceholderAPIPlugin extends JavaPlugin { Bukkit.getScheduler().cancelTasks(this); + adventure.close(); + adventure = null; + instance = null; } @@ -183,6 +194,15 @@ public final class PlaceholderAPIPlugin extends JavaPlugin { 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. * @@ -205,14 +225,13 @@ public final class PlaceholderAPIPlugin extends JavaPlugin { } private void setupMetrics() { - final Metrics metrics = new Metrics(this); - metrics.addCustomChart(new Metrics.SimplePie("using_expansion_cloud", + final Metrics metrics = new Metrics(this, 438); + metrics.addCustomChart(new SimplePie("using_expansion_cloud", () -> getPlaceholderAPIConfig().isCloudEnabled() ? "yes" : "no")); - metrics.addCustomChart( - new Metrics.SimplePie("using_spigot", () -> getServerVersion().isSpigot() ? "yes" : "no")); + metrics.addCustomChart(new SimplePie("using_spigot", () -> getServerVersion().isSpigot() ? "yes" : "no")); - metrics.addCustomChart(new Metrics.AdvancedPie("expansions_used", () -> { + metrics.addCustomChart(new AdvancedPie("expansions_used", () -> { final Map values = new HashMap<>(); for (final PlaceholderExpansion expansion : getLocalExpansionManager().getExpansions()) { diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderHook.java b/src/main/java/me/clip/placeholderapi/PlaceholderHook.java index 0087590..91c3263 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderHook.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderHook.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/commands/PlaceholderCommand.java b/src/main/java/me/clip/placeholderapi/commands/PlaceholderCommand.java index 016a37c..2d6b78a 100644 --- a/src/main/java/me/clip/placeholderapi/commands/PlaceholderCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/PlaceholderCommand.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/commands/PlaceholderCommandRouter.java b/src/main/java/me/clip/placeholderapi/commands/PlaceholderCommandRouter.java index 3c32314..2a81e85 100644 --- a/src/main/java/me/clip/placeholderapi/commands/PlaceholderCommandRouter.java +++ b/src/main/java/me/clip/placeholderapi/commands/PlaceholderCommandRouter.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloud.java b/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloud.java index 7a89a34..0cfbc16 100644 --- a/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloud.java +++ b/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloud.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudClear.java b/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudClear.java index 251ae43..3296657 100644 --- a/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudClear.java +++ b/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudClear.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudDownload.java b/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudDownload.java index 7bbb872..ee9e6ca 100644 --- a/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudDownload.java +++ b/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudDownload.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudExpansionInfo.java b/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudExpansionInfo.java index 569c0ce..267505e 100644 --- a/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudExpansionInfo.java +++ b/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudExpansionInfo.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudExpansionList.java b/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudExpansionList.java index e4cb193..cb4d38c 100644 --- a/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudExpansionList.java +++ b/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudExpansionList.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (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.primitives.Ints; import java.text.SimpleDateFormat; -import java.util.ArrayList; -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.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; 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.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.cloud.CloudExpansion; -import me.clip.placeholderapi.libs.JSONMessage; import me.clip.placeholderapi.util.Format; 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.entity.Player; import org.jetbrains.annotations.NotNull; 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 { private static final int PAGE_SIZE = 10; @@ -132,77 +132,81 @@ public final class CommandECloudExpansionList extends PlaceholderCommand { builder.append(" &bPage&7: &a") .append(page) - .append("&r") - .append('\n'); + .append("&r"); } - @NotNull - private static JSONMessage getMessage(@NotNull final List expansions, + private static Component getMessage(@NotNull final List expansions, final int page, final int limit, @NotNull final String target) { final SimpleDateFormat format = PlaceholderAPIPlugin.getDateFormat(); - final StringBuilder tooltip = new StringBuilder(); - final JSONMessage message = JSONMessage.create(); + final TextComponent.Builder message = text(); for (int index = 0; index < expansions.size(); index++) { final CloudExpansion expansion = expansions.get(index); + final TextComponent.Builder line = text(); - tooltip.append("&bClick to download this expansion!") - .append('\n') - .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 int expansionNumber = index + ((page - 1) * PAGE_SIZE) + 1; + line.append(text(expansionNumber + ". ", DARK_GRAY)); - final String description = expansion.getDescription(); - if (description != null && !description.isEmpty()) { - tooltip.append('\n') - .append('\n') - .append("&f") - .append(description.replace("\r", "").trim()); + final NamedTextColor expansionColour; + + if (expansion.shouldUpdate()) { + expansionColour = GOLD; + } else { + if (expansion.hasExpansion()) { + expansionColour = GREEN; + } else { + expansionColour = GRAY; + } } - message.then(Msg.color( - "&8" + (index + ((page - 1) * PAGE_SIZE) + 1) + ".&r " + (expansion.shouldUpdate() ? "&6" - : expansion.hasExpansion() ? "&a" : "&7") + expansion.getName())); + line.append(text(expansion.getName(), expansionColour)); - message.tooltip(Msg.color(tooltip.toString())); - message.suggestCommand("/papi ecloud download " + expansion.getName()); + line.clickEvent(ClickEvent.suggestCommand("/papi ecloud download " + expansion.getName())); - if (index < expansions.size() - 1) { - message.newline(); + final TextComponent.Builder hoverText = text("Click to download this expansion!", AQUA) + .append(newline()).append(newline()) + .append(text("Author: ", AQUA)).append(text(expansion.getAuthor(), WHITE)) + .append(newline()) + .append(text("Verified: ", AQUA)).append(text(expansion.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) { - 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) { - 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) { - 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 expansions, @@ -321,8 +325,8 @@ public final class CommandECloudExpansionList extends PlaceholderCommand { final int limit = (int) Math.ceil((double) expansions.size() / PAGE_SIZE); - final JSONMessage message = getMessage(values, page, limit, params.get(0)); - message.send(((Player) sender)); + final Component message = getMessage(values, page, limit, params.get(0)); + plugin.getAdventure().player((Player) sender).sendMessage(message); } @Override diff --git a/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudExpansionPlaceholders.java b/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudExpansionPlaceholders.java index 9d51966..46eda28 100644 --- a/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudExpansionPlaceholders.java +++ b/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudExpansionPlaceholders.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudRefresh.java b/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudRefresh.java index 2185d88..77f023e 100644 --- a/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudRefresh.java +++ b/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudRefresh.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudStatus.java b/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudStatus.java index 47aafa6..f1e6333 100644 --- a/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudStatus.java +++ b/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudStatus.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudToggle.java b/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudToggle.java index 5cbd754..57539d5 100644 --- a/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudToggle.java +++ b/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudToggle.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudUpdate.java b/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudUpdate.java index 6b4d21a..0cb4a10 100644 --- a/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudUpdate.java +++ b/src/main/java/me/clip/placeholderapi/commands/impl/cloud/CommandECloudUpdate.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandDump.java b/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandDump.java index d3c3637..d30699d 100644 --- a/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandDump.java +++ b/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandDump.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. @@ -21,7 +21,17 @@ package me.clip.placeholderapi.commands.impl.local; 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.InputStream; import java.io.InputStreamReader; @@ -41,20 +51,15 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.logging.Level; 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 { @NotNull private static final String URL = "https://paste.helpch.at/"; + @NotNull + private static final Gson gson = new Gson(); + @NotNull private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter .ofLocalizedDateTime(FormatStyle.LONG) @@ -102,9 +107,8 @@ public final class CommandDump extends PlaceholderCommand { try (final InputStream stream = connection.getInputStream()) { //noinspection UnstableApiUsage - final String json = CharStreams - .toString(new InputStreamReader(stream, StandardCharsets.UTF_8)); - return JsonParser.parseString(json).getAsJsonObject().get("key").getAsString(); + final String json = CharStreams.toString(new InputStreamReader(stream, StandardCharsets.UTF_8)); + return gson.fromJson(json, JsonObject.class).get("key").getAsString(); } } catch (final IOException ex) { throw new CompletionException(ex); diff --git a/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandExpansionRegister.java b/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandExpansionRegister.java index 84cf1bf..9f0bcbd 100644 --- a/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandExpansionRegister.java +++ b/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandExpansionRegister.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandExpansionUnregister.java b/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandExpansionUnregister.java index 4b59fac..3d03283 100644 --- a/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandExpansionUnregister.java +++ b/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandExpansionUnregister.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandHelp.java b/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandHelp.java index d43e2fe..aeb53e7 100644 --- a/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandHelp.java +++ b/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandHelp.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandInfo.java b/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandInfo.java index ca0903a..d4dc03a 100644 --- a/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandInfo.java +++ b/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandInfo.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandList.java b/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandList.java index f401e7f..5a5b28a 100644 --- a/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandList.java +++ b/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandList.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandParse.java b/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandParse.java index 3bd8bc2..60c4ff8 100644 --- a/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandParse.java +++ b/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandParse.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandReload.java b/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandReload.java index 5bb6d97..77ac57a 100644 --- a/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandReload.java +++ b/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandReload.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandVersion.java b/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandVersion.java index 6804f1c..4ad73dd 100644 --- a/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandVersion.java +++ b/src/main/java/me/clip/placeholderapi/commands/impl/local/CommandVersion.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/configuration/ExpansionSort.java b/src/main/java/me/clip/placeholderapi/configuration/ExpansionSort.java index c663f47..79b1f2a 100644 --- a/src/main/java/me/clip/placeholderapi/configuration/ExpansionSort.java +++ b/src/main/java/me/clip/placeholderapi/configuration/ExpansionSort.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/configuration/PlaceholderAPIConfig.java b/src/main/java/me/clip/placeholderapi/configuration/PlaceholderAPIConfig.java index 78b728e..9d9a057 100644 --- a/src/main/java/me/clip/placeholderapi/configuration/PlaceholderAPIConfig.java +++ b/src/main/java/me/clip/placeholderapi/configuration/PlaceholderAPIConfig.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/events/ExpansionRegisterEvent.java b/src/main/java/me/clip/placeholderapi/events/ExpansionRegisterEvent.java index e1e556f..6f812dc 100644 --- a/src/main/java/me/clip/placeholderapi/events/ExpansionRegisterEvent.java +++ b/src/main/java/me/clip/placeholderapi/events/ExpansionRegisterEvent.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. @@ -26,6 +26,10 @@ import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; +/** + * Indicates that a {@link PlaceholderExpansion} has been registered by + * PlaceholderAPI. + */ public final class ExpansionRegisterEvent extends Event implements Cancellable { @NotNull @@ -42,7 +46,12 @@ public final class ExpansionRegisterEvent extends Event implements Cancellable { public static HandlerList getHandlerList() { return HANDLERS; } - + + /** + * The {@link PlaceholderExpansion expansion} that was registered. + * + * @return The {@link PlaceholderExpansion} instance. + */ @NotNull public PlaceholderExpansion getExpansion() { return expansion; diff --git a/src/main/java/me/clip/placeholderapi/events/ExpansionUnregisterEvent.java b/src/main/java/me/clip/placeholderapi/events/ExpansionUnregisterEvent.java index b9bebac..4c0beb1 100644 --- a/src/main/java/me/clip/placeholderapi/events/ExpansionUnregisterEvent.java +++ b/src/main/java/me/clip/placeholderapi/events/ExpansionUnregisterEvent.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. @@ -25,6 +25,10 @@ import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; +/** + * Indicates that a {@link PlaceholderExpansion} had been unregistered by + * PlaceholderAPI. + */ public final class ExpansionUnregisterEvent extends Event { @NotNull @@ -42,7 +46,12 @@ public final class ExpansionUnregisterEvent extends Event { public static HandlerList getHandlerList() { return HANDLERS; } - + + /** + * The {@link PlaceholderExpansion expansion} that was unregistered. + * + * @return The {@link PlaceholderExpansion} instance. + */ @NotNull public PlaceholderExpansion getExpansion() { return expansion; diff --git a/src/main/java/me/clip/placeholderapi/events/ExpansionsLoadedEvent.java b/src/main/java/me/clip/placeholderapi/events/ExpansionsLoadedEvent.java index 157b0a0..b173007 100644 --- a/src/main/java/me/clip/placeholderapi/events/ExpansionsLoadedEvent.java +++ b/src/main/java/me/clip/placeholderapi/events/ExpansionsLoadedEvent.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. @@ -26,7 +26,10 @@ import org.bukkit.event.HandlerList; 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 all {@link me.clip.placeholderapi.expansion.PlaceholderExpansion PlayceholderExpansions} + * have been loaded. + *
This event is fired on Server load and when reloading the + * confiuration. */ public class ExpansionsLoadedEvent extends Event { diff --git a/src/main/java/me/clip/placeholderapi/events/PlaceholderHookUnloadEvent.java b/src/main/java/me/clip/placeholderapi/events/PlaceholderHookUnloadEvent.java index 0452d29..24a8a0b 100644 --- a/src/main/java/me/clip/placeholderapi/events/PlaceholderHookUnloadEvent.java +++ b/src/main/java/me/clip/placeholderapi/events/PlaceholderHookUnloadEvent.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/exceptions/NoDefaultCommandException.java b/src/main/java/me/clip/placeholderapi/exceptions/NoDefaultCommandException.java index 8ba6a9f..d4ceebd 100644 --- a/src/main/java/me/clip/placeholderapi/exceptions/NoDefaultCommandException.java +++ b/src/main/java/me/clip/placeholderapi/exceptions/NoDefaultCommandException.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/expansion/Cacheable.java b/src/main/java/me/clip/placeholderapi/expansion/Cacheable.java index e002c44..aa105f8 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Cacheable.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Cacheable.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/expansion/Cleanable.java b/src/main/java/me/clip/placeholderapi/expansion/Cleanable.java index e08f0d6..b408acf 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Cleanable.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Cleanable.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/expansion/Configurable.java b/src/main/java/me/clip/placeholderapi/expansion/Configurable.java index 5660f64..a20b73b 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Configurable.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Configurable.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (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 - * 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 */ diff --git a/src/main/java/me/clip/placeholderapi/expansion/NMSVersion.java b/src/main/java/me/clip/placeholderapi/expansion/NMSVersion.java index acd7e0d..541a004 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/NMSVersion.java +++ b/src/main/java/me/clip/placeholderapi/expansion/NMSVersion.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. @@ -41,7 +41,8 @@ public enum NMSVersion { SPIGOT_1_15_R1("v1_15_R1"), SPIGOT_1_16_R1("v1_16_R1"), SPIGOT_1_16_R2("v1_16_R2"), - SPIGOT_1_16_R3("v1_16_R3"); + SPIGOT_1_16_R3("v1_16_R3"), + SPIGOT_1_17_R1("v1_17_R1"); private final String version; diff --git a/src/main/java/me/clip/placeholderapi/expansion/PlaceholderExpansion.java b/src/main/java/me/clip/placeholderapi/expansion/PlaceholderExpansion.java index 84e50e3..1e71a45 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/PlaceholderExpansion.java +++ b/src/main/java/me/clip/placeholderapi/expansion/PlaceholderExpansion.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. @@ -22,7 +22,6 @@ package me.clip.placeholderapi.expansion; import java.util.Collections; import java.util.List; -import java.util.Objects; import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderHook; import org.bukkit.Bukkit; @@ -32,10 +31,17 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +/** + * Any class extending this will be able to get registered as a PlaceholderExpansion. + *
The registration either happens automatically when the jar file containing a + * class extending this one is located under the {@code PlaceholderAPI/expansions} + * directory or when the {@link #register()} method is called by said class. + */ public abstract class PlaceholderExpansion extends PlaceholderHook { /** - * The 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 */ @@ -153,64 +159,153 @@ public abstract class PlaceholderExpansion extends PlaceholderHook { } // === Configuration === - + + /** + * Gets the ConfigurationSection of the expansion located in the config.yml of PlaceholderAPI or + * null when not specified. + *
You may use the {@link Configurable} interface to define default values set + * + * @return ConfigurationSection that this epxpansion has. + */ @Nullable public final ConfigurationSection getConfigSection() { return getPlaceholderAPI().getConfig().getConfigurationSection("expansions." + getIdentifier()); } - + + /** + * Gets the ConfigurationSection relative to the {@link #getConfigSection() default one} set + * by the expansion or null when the default ConfigurationSection is null + * + * @param path The path to get the ConfigurationSection from. This is relative to the default section + * @return ConfigurationSection relative to the default section + */ @Nullable public final ConfigurationSection getConfigSection(@NotNull final String path) { final ConfigurationSection section = getConfigSection(); return section == null ? null : section.getConfigurationSection(path); } - + + /** + * Gets the Object relative to the {@link #getConfigSection() default ConfigurationSection} set + * by the expansion or the provided Default Object, when the default ConfigurationSection is null + * + * @param path The path to get the Object from. This is relative to the default section + * @param def The default Object to return when the ConfigurationSection returns null + * @return Object from the provided path or the default one provided + */ @Nullable @Contract("_, !null -> !null") public final Object get(@NotNull final String path, final Object def) { final ConfigurationSection section = getConfigSection(); return section == null ? def : section.get(path, def); } - + + /** + * Gets the int relative to the {@link #getConfigSection() default ConfigurationSection} set + * by the expansion or the provided Default int, when the default ConfigurationSection is null + * + * @param path The path to get the int from. This is relative to the default section + * @param def The default int to return when the ConfigurationSection returns null + * @return int from the provided path or the default one provided + */ public final int getInt(@NotNull final String path, final int def) { final ConfigurationSection section = getConfigSection(); return section == null ? def : section.getInt(path, def); } - + + /** + * Gets the long relative to the {@link #getConfigSection() default ConfigurationSection} set + * by the expansion or the provided Default long, when the default ConfigurationSection is null + * + * @param path The path to get the long from. This is relative to the default section + * @param def The default long to return when the ConfigurationSection returns null + * @return long from the provided path or the default one provided + */ public final long getLong(@NotNull final String path, final long def) { final ConfigurationSection section = getConfigSection(); return section == null ? def : section.getLong(path, def); } - + + /** + * Gets the double relative to the {@link #getConfigSection() default ConfigurationSection} set + * by the expansion or the provided Default double, when the default ConfigurationSection is null + * + * @param path The path to get the double from. This is relative to the default section + * @param def The default double to return when the ConfigurationSection returns null + * @return double from the provided path or the default one provided + */ public final double getDouble(@NotNull final String path, final double def) { final ConfigurationSection section = getConfigSection(); return section == null ? def : section.getDouble(path, def); } - + + /** + * Gets the String relative to the {@link #getConfigSection() default ConfigurationSection} set + * by the expansion or the provided Default String, when the default ConfigurationSection is null + * + * @param path The path to get the String from. This is relative to the default section + * @param def The default String to return when the ConfigurationSection returns null. Can be null + * @return String from the provided path or the default one provided + */ @Nullable @Contract("_, !null -> !null") public final String getString(@NotNull final String path, @Nullable final String def) { final ConfigurationSection section = getConfigSection(); return section == null ? def : section.getString(path, def); } - + + /** + * Gets a String List relative to the {@link #getConfigSection() default ConfigurationSection} set + * by the expansion or an empty List, when the default ConfigurationSection is null + * + * @param path The path to get the String list from. This is relative to the default section + * @return String list from the provided path or an empty list + */ @NotNull public final List getStringList(@NotNull final String path) { final ConfigurationSection section = getConfigSection(); return section == null ? Collections.emptyList() : section.getStringList(path); } + /** + * Gets the boolean relative to the {@link #getConfigSection() default ConfigurationSection} set + * by the expansion or the default boolean, when the default ConfigurationSection is null + * + * @param path The path to get the boolean from. This is relative to the default section + * @param def The default boolean to return when the ConfigurationSection is null + * @return boolean from the provided path or the default one provided + */ @NotNull public final boolean getBoolean(@NotNull final String path, final boolean def) { final ConfigurationSection section = getConfigSection(); return section == null ? def : section.getBoolean(path, def); } + /** + * Whether the {@link #getConfigSection() default ConfigurationSection} contains the provided path + * or not. This will return {@code false} when either the default section is null, or doesn't + * contain the provided path + * + * @param path The path to check + * @return true when the default ConfigurationSection is not null and contains the path, false otherwise + */ public final boolean configurationContains(@NotNull final String path) { final ConfigurationSection section = getConfigSection(); return section != null && section.contains(path); } - + + /** + * Whether the provided Object is an instance of this PlaceholderExpansion. + *
This method will perform the following checks in order: + *
    + *
  • Checks if Object equals the class. Returns true when equal and continues otherwise
  • + *
  • Checks if the Object is an instance of a PlaceholderExpansion. Returns false if not
  • + *
  • Checks if the Object's Identifier, Author and version equal the one of this class
  • + *
+ * + * @param o The Object to check + * @return true or false depending on the above mentioned checks + */ @Override public final boolean equals(final Object o) { if (this == o) { @@ -226,7 +321,12 @@ public abstract class PlaceholderExpansion extends PlaceholderHook { getAuthor().equals(expansion.getAuthor()) && getVersion().equals(expansion.getVersion()); } - + + /** + * Returns a String containing the Expansion's name, author and version + * + * @return String containing name, author and version of the expansion + */ @Override public final String toString() { return String.format("PlaceholderExpansion[name: '%s', author: '%s', version: '%s']", getName(), @@ -267,5 +367,4 @@ public abstract class PlaceholderExpansion extends PlaceholderHook { public String getLink() { return null; } - } diff --git a/src/main/java/me/clip/placeholderapi/expansion/Relational.java b/src/main/java/me/clip/placeholderapi/expansion/Relational.java index ca80f6e..6d05e94 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Relational.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Relational.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/expansion/Taskable.java b/src/main/java/me/clip/placeholderapi/expansion/Taskable.java index f32a6a9..fa0ac21 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Taskable.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Taskable.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/expansion/Version.java b/src/main/java/me/clip/placeholderapi/expansion/Version.java index e789243..0ba9029 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Version.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Version.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/expansion/VersionSpecific.java b/src/main/java/me/clip/placeholderapi/expansion/VersionSpecific.java index 84d28ba..7c91500 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/VersionSpecific.java +++ b/src/main/java/me/clip/placeholderapi/expansion/VersionSpecific.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/expansion/cloud/CloudExpansion.java b/src/main/java/me/clip/placeholderapi/expansion/cloud/CloudExpansion.java index b6516b9..b9e9566 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/cloud/CloudExpansion.java +++ b/src/main/java/me/clip/placeholderapi/expansion/cloud/CloudExpansion.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/expansion/manager/CloudExpansionManager.java b/src/main/java/me/clip/placeholderapi/expansion/manager/CloudExpansionManager.java index 36603e9..c79ee11 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/manager/CloudExpansionManager.java +++ b/src/main/java/me/clip/placeholderapi/expansion/manager/CloudExpansionManager.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/expansion/manager/LocalExpansionManager.java b/src/main/java/me/clip/placeholderapi/expansion/manager/LocalExpansionManager.java index 2557ae2..872215c 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/manager/LocalExpansionManager.java +++ b/src/main/java/me/clip/placeholderapi/expansion/manager/LocalExpansionManager.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. @@ -46,18 +46,25 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Unmodifiable; import java.io.File; +import java.lang.reflect.Modifier; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Level; +import java.util.stream.Collectors; public final class LocalExpansionManager implements Listener { @NotNull private static final String EXPANSIONS_FOLDER_NAME = "expansions"; + @NotNull + private static final Set 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 private final File folder; @@ -153,20 +160,33 @@ public final class LocalExpansionManager implements Listener { @NotNull final Class clazz) { try { 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.of(expansion); - } catch (final LinkageError ex) { - plugin.getLogger().severe("Failed to load Expansion class " + clazz.getSimpleName() + - " (Is a dependency missing?)"); - plugin.getLogger().severe("Cause: " + ex.getClass().getSimpleName() + " " + ex.getMessage()); + } catch (LinkageError | NullPointerException ex) { + final String reason; + + 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(); } - + @ApiStatus.Internal public boolean register(@NotNull final PlaceholderExpansion expansion) { final String identifier = expansion.getIdentifier().toLowerCase(); @@ -341,6 +361,16 @@ public final class LocalExpansionManager implements Listener { if (expansionClass == null) { plugin.getLogger().severe("Failed to load Expansion: " + file.getName() + ", as it does not have" + " a class which extends PlaceholderExpansion."); + return null; + } + + Set 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; @@ -365,8 +395,8 @@ public final class LocalExpansionManager implements Listener { if (ex.getCause() instanceof LinkageError) { 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; } diff --git a/src/main/java/me/clip/placeholderapi/expansion/manager/MethodSignature.java b/src/main/java/me/clip/placeholderapi/expansion/manager/MethodSignature.java new file mode 100644 index 0000000..8a7d735 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/expansion/manager/MethodSignature.java @@ -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; + } +} diff --git a/src/main/java/me/clip/placeholderapi/libs/JSONMessage.java b/src/main/java/me/clip/placeholderapi/libs/JSONMessage.java deleted file mode 100644 index b07a31c..0000000 --- a/src/main/java/me/clip/placeholderapi/libs/JSONMessage.java +++ /dev/null @@ -1,1120 +0,0 @@ -/* - * Copyright (c) 2018-2020 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: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -package me.clip.placeholderapi.libs; - -import com.google.common.base.Strings; -import com.google.common.collect.BiMap; -import com.google.common.collect.ImmutableBiMap; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonPrimitive; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.UUID; -import java.util.Vector; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.entity.Player; - -/** - * This is a complete JSON message builder class. To create a new JSONMessage do {@link - * #create(String)} - * - * @author Rayzr - */ -@SuppressWarnings({"WeakerAccess", "unused"}) -public class JSONMessage { - - private static final BiMap stylesToNames; - - static { - ImmutableBiMap.Builder builder = ImmutableBiMap.builder(); - for (final ChatColor style : ChatColor.values()) { - if (!style.isFormat()) { - continue; - } - - String styleName; - switch (style) { - case MAGIC: - styleName = "obfuscated"; - break; - case UNDERLINE: - styleName = "underlined"; - break; - default: - styleName = style.name().toLowerCase(); - break; - } - - builder.put(style, styleName); - } - stylesToNames = builder.build(); - } - - - private final List parts = new ArrayList<>(); - private int centeringStartIndex = -1; - - /** - * Creates a new {@link JSONMessage} object - * - * @param text The text to start with - */ - private JSONMessage(String text) { - parts.add(new MessagePart(text)); - } - - /** - * Creates a new {@link JSONMessage} object - * - * @param text The text to start with - * @return A new {@link JSONMessage} object - */ - public static JSONMessage create(String text) { - return new JSONMessage(text); - } - - /** - * Creates a new {@link JSONMessage} object - * - * @return A new {@link JSONMessage} object - */ - public static JSONMessage create() { - return create(""); - } - - /** - * Sends an action bar message - * - * @param message The message to send - * @param players The players you want to send it to - */ - public static void actionbar(String message, Player... players) { - ReflectionHelper.sendPacket(ReflectionHelper - .createActionbarPacket(ChatColor.translateAlternateColorCodes('&', message)), players); - } - - /** - * @return The latest {@link MessagePart} - * @throws ArrayIndexOutOfBoundsException If {@code parts.size() <= 0}. - */ - public MessagePart last() { - if (parts.size() <= 0) { - throw new ArrayIndexOutOfBoundsException("No MessageParts exist!"); - } - return parts.get(parts.size() - 1); - } - - /** - * Converts this {@link JSONMessage} instance to actual JSON - * - * @return The JSON representation of this {@link JSONMessage} - */ - public JsonObject toJSON() { - JsonObject obj = new JsonObject(); - - obj.addProperty("text", ""); - - JsonArray array = new JsonArray(); - - parts.stream() - .map(MessagePart::toJSON) - .forEach(array::add); - - obj.add("extra", array); - - return obj; - } - - /** - * Converts this {@link JSONMessage} object to a String representation of the JSON. This is an - * alias of {@code toJSON().toString()}. - */ - @Override - public String toString() { - return toJSON().toString(); - } - - /** - * Converts this {@link JSONMessage} object to the legacy formatting system, which uses formatting - * codes (like &6, &l, &4, etc.) - * - * @return This {@link JSONMessage} instance {@link JSONMessage} in legacy format - */ - public String toLegacy() { - StringBuilder output = new StringBuilder(); - - parts.stream() - .map(MessagePart::toLegacy) - .forEach(output::append); - - return output.toString(); - } - - /** - * Sends this {@link JSONMessage} to all the players specified - * - * @param players The players you want to send this to - */ - public void send(Player... players) { - if (ReflectionHelper.MAJOR_VER >= 16) { -// ReflectionHelper.sendTextPacket(toString(), players); -// return; - } - - ReflectionHelper.sendPacket(ReflectionHelper.createTextPacket(toString()), players); - } - - /** - * Sends this as a title to all the players specified - * - * @param fadeIn How many ticks to fade in - * @param stay How many ticks to stay - * @param fadeOut How many ticks to fade out - * @param players The players to send this to - */ - public void title(int fadeIn, int stay, int fadeOut, Player... players) { - ReflectionHelper - .sendPacket(ReflectionHelper.createTitleTimesPacket(fadeIn, stay, fadeOut), players); - ReflectionHelper.sendPacket(ReflectionHelper.createTitlePacket(toString()), players); - } - - /** - * Sends this as a subtitle to all the players specified. Must be used after sending a {@link - * #title(int, int, int, Player...) title}. - * - * @param players The players to send this to - */ - public void subtitle(Player... players) { - ReflectionHelper.sendPacket(ReflectionHelper.createSubtitlePacket(toString()), players); - } - - /** - * Sends an action bar message - * - * @param players The players you want to send this to - */ - public void actionbar(Player... players) { - actionbar(toLegacy(), players); - } - - /** - * Sets the color of the current message part. - * - * @param color The color to set - * @return This {@link JSONMessage} instance - */ - public JSONMessage color(ChatColor color) { - if (!color.isColor()) { - throw new IllegalArgumentException(color.name() + " is not a color."); - } - - last().setColor(color); - return this; - } - - /** - * Sets the color of the current message part. - *
If the provided color is a hex color ({@code #rrggbb}) but the major version of MC is older - * than 1.16 will this - * default to the color WHITE. - * - * @param color The color to set - * @return This {@link JSONMessage} instance - */ - public JSONMessage color(String color) { - return color(color, ChatColor.WHITE); - } - - /** - * Sets the color of the current message part. - *
If the provided color is a hex color ({@code #rrggbb}) but the major version of MC is older - * than 1.16 will the provided - * default ChatColor be used instead. - * - * @param color The color to set - * @param def The default ChatColor to use, when MC version is older than 1.16 - * @return This {@link JSONMessage} instance - */ - public JSONMessage color(String color, ChatColor def) { - if (color.startsWith("#") && ReflectionHelper.MAJOR_VER < 16) { - return color(def); - } - - last().setColor(color); - return this; - } - - /** - * Sets the font of the current message part. - *
When this is used on versions older than 1.16 will this do nothing. - * - * @param font The font to set - * @return This {@link JSONMessage} instance - */ - public JSONMessage font(String font) { - if (ReflectionHelper.MAJOR_VER < 16) { - return this; - } - - last().setFont(font); - return this; - } - - /** - * Adds a style to the current message part. - * - * @param style The style to add - * @return This {@link JSONMessage} instance - */ - public JSONMessage style(ChatColor style) { - last().addStyle(style); - return this; - } - - /** - * Makes the text run a command. - * - * @param command The command to run - * @return This {@link JSONMessage} instance - */ - public JSONMessage runCommand(String command) { - last().setOnClick(ClickEvent.runCommand(command)); - return this; - } - - /** - * Makes the text suggest a command. - * - * @param command The command to suggest - * @return This {@link JSONMessage} instance - */ - public JSONMessage suggestCommand(String command) { - last().setOnClick(ClickEvent.suggestCommand(command)); - return this; - } - - /** - * Opens a URL. - * - * @param url The url to open - * @return This {@link JSONMessage} instance - */ - public JSONMessage openURL(String url) { - last().setOnClick(ClickEvent.openURL(url)); - return this; - } - - /** - * Copies the provided text to the Clipboard of the player. - *
When this is used on versions older than 1.15 will this default to {@link - * #suggestCommand(String) suggestCommand(String)}. - * - * @param text The text to copy - * @return This {@link JSONMessage} instance - */ - public JSONMessage copyText(String text) { - last().setOnClick(ClickEvent.copyText(text)); - return this; - } - - /** - * Changes the page of a book. Using this in a non-book context is useless and will probably - * error. - * - * @param page The page to change to - * @return This {@link JSONMessage} instance - */ - public JSONMessage changePage(int page) { - last().setOnClick(ClickEvent.changePage(page)); - return this; - } - - /** - * Shows text when you hover over it - * - * @param text The text to show - * @return This {@link JSONMessage} instance - */ - public JSONMessage tooltip(String text) { - last().setOnHover(HoverEvent.showText(text)); - return this; - } - - /** - * Shows text when you hover over it - * - * @param message The text to show - * @return This {@link JSONMessage} instance - */ - public JSONMessage tooltip(JSONMessage message) { - last().setOnHover(HoverEvent.showText(message)); - return this; - } - - /** - * Shows an achievement when you hover over it - * - * @param id The id of the achievement - * @return This {@link JSONMessage} instance - */ - public JSONMessage achievement(String id) { - last().setOnHover(HoverEvent.showAchievement(id)); - return this; - } - - /** - * Adds another part to this {@link JSONMessage} - * - * @param text The text to start the next {@link MessagePart} with - * @return This {@link JSONMessage} instance - */ - public JSONMessage then(String text) { - return then(new MessagePart(text)); - } - - /** - * Adds another part to this {@link JSONMessage} - * - * @param nextPart The next {@link MessagePart} - * @return This {@link JSONMessage} instance - */ - public JSONMessage then(MessagePart nextPart) { - parts.add(nextPart); - return this; - } - - /** - * Adds a horizontal bar to the message of the given length - * - * @param length The length of the horizontal bar - * @return This {@link JSONMessage} instance - */ - public JSONMessage bar(int length) { - return then(Strings.repeat("-", length)).color(ChatColor.DARK_GRAY) - .style(ChatColor.STRIKETHROUGH); - } - - /** - * Adds a horizontal bar to the message that's 53 characters long. This is the default width of - * the player's chat window. - * - * @return This {@link JSONMessage} instance - */ - public JSONMessage bar() { - return bar(53); - } - - /** - * Adds a blank line to the message - * - * @return This {@link JSONMessage} instance - */ - public JSONMessage newline() { - return then("\n"); - } - - /** - * Sets the starting point to begin centering JSONMessages. - * - * @return This {@link JSONMessage} instance - */ - public JSONMessage beginCenter() { - // Start with the NEXT message part. - centeringStartIndex = parts.size(); - return this; - } - - /** - * Ends the centering of the JSONMessage text. - * - * @return This {@link JSONMessage} instance - */ - public JSONMessage endCenter() { - int current = centeringStartIndex; - - while (current < parts.size()) { - Vector currentLine = new Vector<>(); - int totalLineLength = 0; - - for (; ; current++) { - MessagePart part = current < parts.size() ? parts.get(current) : null; - String raw = part == null ? null : ChatColor.stripColor(part.toLegacy()); - int rawLength = raw == null ? 0 : raw.length(); - - if (current >= parts.size() || totalLineLength + rawLength >= 53) { - int padding = Math.max(0, (53 - totalLineLength) / 2); - currentLine.firstElement() - .setText(Strings.repeat(" ", padding) + currentLine.firstElement().getText()); - currentLine.lastElement().setText(currentLine.lastElement().getText() + "\n"); - currentLine.clear(); - break; - } - - totalLineLength += rawLength; - currentLine.add(part); - } - } - - MessagePart last = parts.get(parts.size() - 1); - last.setText(last.getText().substring(0, last.getText().length() - 1)); - - centeringStartIndex = -1; - - return this; - } - - /////////////////////////// - // BEGIN UTILITY CLASSES // - /////////////////////////// - - /** - * Represents the JSON format that all click/hover events in JSON messages must follow. - *
- *
- * Reference - * - * @author Rayzr - */ - public static class MessageEvent { - - private String action; - private Object value; - - public MessageEvent(String action, Object value) { - this.action = action; - this.value = value; - } - - /** - * @return A {@link JsonObject} representing the properties of this {@link MessageEvent} - */ - public JsonObject toJSON() { - JsonObject obj = new JsonObject(); - obj.addProperty("action", action); - /* - * MC 1.16 changed "value" to "contents", but only for Hover events... Don't ask why. - * Since this lib only has tooltip and achievement can we simply check if action starts with "show_" - */ - String valueType = - (ReflectionHelper.MAJOR_VER >= 16 && action.startsWith("show_")) ? "contents" : "value"; - - if (value instanceof JsonElement) { - obj.add(valueType, (JsonElement) value); - } else { - obj.addProperty(valueType, value.toString()); - } - return obj; - } - - /** - * @return The action - */ - public String getAction() { - return action; - } - - /** - * @param action The action to set - */ - public void setAction(String action) { - this.action = action; - } - - /** - * @return The value - */ - public Object getValue() { - return value; - } - - /** - * @param value The value to set - */ - public void setValue(Object value) { - this.value = value; - } - - } - - public static class ClickEvent { - - /** - * Runs a command. - * - * @param command The command to run - * @return The {@link MessageEvent} - */ - public static MessageEvent runCommand(String command) { - return new MessageEvent("run_command", command); - } - - /** - * Suggests a command by inserting it in chat. - * - * @param command The command to suggest - * @return The {@link MessageEvent} - */ - public static MessageEvent suggestCommand(String command) { - return new MessageEvent("suggest_command", command); - } - - /** - * Requires web links to be enabled on the client. - * - * @param url The url to open - * @return The {@link MessageEvent} - */ - public static MessageEvent openURL(String url) { - return new MessageEvent("open_url", url); - } - - /** - * Only used with written books. - * - * @param page The page to switch to - * @return The {@link MessageEvent} - */ - public static MessageEvent changePage(int page) { - return new MessageEvent("change_page", page); - } - - /** - * Copies the provided text to the clipboard of the player. - *
When used on versions older than 1.15 will this {@link #suggestCommand(String) suggest - * the text} instead. - * - * @param text The text to copy. - * @return The {@link MessageEvent} - */ - public static MessageEvent copyText(String text) { - if (ReflectionHelper.MAJOR_VER < 15) { - return suggestCommand(text); - } - - return new MessageEvent("copy_to_clipboard", text); - } - - } - - public static class HoverEvent { - - /** - * Shows text when you hover over it - * - * @param text The text to show - * @return The {@link MessageEvent} - */ - public static MessageEvent showText(String text) { - return new MessageEvent("show_text", text); - } - - /** - * Shows text when you hover over it - * - * @param message The {@link JSONMessage} to show - * @return The {@link MessageEvent} - */ - public static MessageEvent showText(JSONMessage message) { - JsonArray arr = new JsonArray(); - arr.add(new JsonPrimitive("")); - arr.add(message.toJSON()); - return new MessageEvent("show_text", arr); - } - - /** - * Shows an achievement when you hover over it - * - * @param id The id of the achievement - * @return The {@link MessageEvent} - */ - public static MessageEvent showAchievement(String id) { - return new MessageEvent("show_achievement", id); - } - - } - - private static class ReflectionHelper { - - private static final String version; - private static Constructor chatComponentText; - - private static Class packetPlayOutChat; - private static Field packetPlayOutChatComponent; - private static Field packetPlayOutChatMessageType; - private static Field packetPlayOutChatUuid; - private static Object enumChatMessageTypeMessage; - private static Object enumChatMessageTypeActionbar; - - private static Constructor titlePacketConstructor; - private static Constructor titleTimesPacketConstructor; - private static Object enumActionTitle; - private static Object enumActionSubtitle; - - private static Field connection; - private static MethodHandle GET_HANDLE; - private static MethodHandle SEND_PACKET; - private static MethodHandle STRING_TO_CHAT; - private static boolean SETUP; - private static int MAJOR_VER = -1; - - static { - String[] split = Bukkit.getServer().getClass().getPackage().getName().split("\\."); - version = split[split.length - 1]; - - try { - MAJOR_VER = Integer.parseInt(version.split("_")[1]); - - final Class craftPlayer = getClass("{obc}.entity.CraftPlayer"); - Method getHandle = craftPlayer.getMethod("getHandle"); - connection = getHandle.getReturnType().getField("playerConnection"); - Method sendPacket = connection.getType().getMethod("sendPacket", getClass("{nms}.Packet")); - - chatComponentText = getClass("{nms}.ChatComponentText").getConstructor(String.class); - - final Class iChatBaseComponent = getClass("{nms}.IChatBaseComponent"); - - Method stringToChat; - - if (MAJOR_VER < 8) { - stringToChat = getClass("{nms}.ChatSerializer").getMethod("a", String.class); - } else { - stringToChat = getClass("{nms}.IChatBaseComponent$ChatSerializer") - .getMethod("a", String.class); - } - - GET_HANDLE = MethodHandles.lookup().unreflect(getHandle); - SEND_PACKET = MethodHandles.lookup().unreflect(sendPacket); - STRING_TO_CHAT = MethodHandles.lookup().unreflect(stringToChat); - - packetPlayOutChat = getClass("{nms}.PacketPlayOutChat"); - packetPlayOutChatComponent = getField(packetPlayOutChat, "a"); - packetPlayOutChatMessageType = getField(packetPlayOutChat, "b"); - packetPlayOutChatUuid = MAJOR_VER >= 16 ? getField(packetPlayOutChat, "c") : null; - - Class packetPlayOutTitle = getClass("{nms}.PacketPlayOutTitle"); - Class titleAction = getClass("{nms}.PacketPlayOutTitle$EnumTitleAction"); - - titlePacketConstructor = packetPlayOutTitle.getConstructor(titleAction, iChatBaseComponent); - titleTimesPacketConstructor = packetPlayOutTitle - .getConstructor(int.class, int.class, int.class); - - enumActionTitle = titleAction.getField("TITLE").get(null); - enumActionSubtitle = titleAction.getField("SUBTITLE").get(null); - - if (MAJOR_VER >= 12) { - Method getChatMessageType = getClass("{nms}.ChatMessageType").getMethod("a", byte.class); - - enumChatMessageTypeMessage = getChatMessageType.invoke(null, (byte) 1); - enumChatMessageTypeActionbar = getChatMessageType.invoke(null, (byte) 2); - } - - SETUP = true; - } catch (Exception e) { - e.printStackTrace(); - SETUP = false; - } - } - - static void sendPacket(Object packet, Player... players) { - assertIsSetup(); - - if (packet == null) { - return; - } - - for (Player player : players) { - try { - SEND_PACKET.bindTo(connection.get(GET_HANDLE.bindTo(player).invoke())).invoke(packet); - } catch (Throwable e) { - System.err.println("Failed to send packet"); - e.printStackTrace(); - } - } - - } - - static Object createActionbarPacket(String message) { - assertIsSetup(); - - Object packet = createTextPacket(message); - setType(packet, (byte) 2); - return packet; - } - - static Object createTextPacket(String message) { - assertIsSetup(); - - try { - Object packet = packetPlayOutChat.newInstance(); - setFieldValue(packetPlayOutChatComponent, packet, fromJson(message)); - setFieldValue(packetPlayOutChatUuid, packet, UUID.randomUUID()); - setType(packet, (byte) 1); - return packet; - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - static Object createTitlePacket(String message) { - assertIsSetup(); - - try { - return titlePacketConstructor.newInstance(enumActionTitle, fromJson(message)); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - static Object createTitleTimesPacket(int fadeIn, int stay, int fadeOut) { - assertIsSetup(); - - try { - return titleTimesPacketConstructor.newInstance(fadeIn, stay, fadeOut); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - static Object createSubtitlePacket(String message) { - assertIsSetup(); - - try { - return titlePacketConstructor.newInstance(enumActionSubtitle, fromJson(message)); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - private static void setType(Object chatPacket, byte type) { - assertIsSetup(); - - if (MAJOR_VER < 12) { - setFieldValue(packetPlayOutChatMessageType, chatPacket, type); - return; - } - - switch (type) { - case 1: - setFieldValue(packetPlayOutChatMessageType, chatPacket, enumChatMessageTypeMessage); - break; - case 2: - setFieldValue(packetPlayOutChatMessageType, chatPacket, enumChatMessageTypeActionbar); - break; - default: - throw new IllegalArgumentException("type must be 1 or 2"); - } - } - - /** - * Creates a ChatComponentText from plain text - * - * @param message The text to convert to a chat component - * @return The chat component - */ - static Object componentText(String message) { - assertIsSetup(); - - try { - return chatComponentText.newInstance(message); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - - } - - /** - * Attempts to convert a String representing a JSON message into a usable object - * - * @param json The JSON to attempt to parse - * @return The object representing the text in JSON form, or null if something went - * wrong converting the String to JSON data - */ - static Object fromJson(String json) { - assertIsSetup(); - - if (!json.trim().startsWith("{")) { - return componentText(json); - } - - try { - return STRING_TO_CHAT.invoke(json); - } catch (Throwable e) { - e.printStackTrace(); - return null; - } - } - - private static void assertIsSetup() { - if (!SETUP) { - throw new IllegalStateException("JSONMessage.ReflectionHelper is not set up yet!"); - } - } - - private static Class getClass(String path) throws ClassNotFoundException { - return Class.forName(path.replace("{nms}", "net.minecraft.server." + version) - .replace("{obc}", "org.bukkit.craftbukkit." + version)); - } - - private static void setFieldValue(Field field, Object instance, Object value) { - if (field == null) { - // useful for fields that might not exist - return; - } - - try { - field.set(instance, value); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - } - - private static Field getField(Class classObject, String fieldName) { - try { - Field field = classObject.getDeclaredField(fieldName); - field.setAccessible(true); - return field; - } catch (NoSuchFieldException e) { - e.printStackTrace(); - return null; - } - } - - private static int getVersion() { - return MAJOR_VER; - } - } - - /** - * Defines a section of the message, and represents the format that all JSON messages must follow - * in Minecraft. - *
- *
- * Reference - * - * @author Rayzr - */ - public static class MessagePart { - - private final List styles = new ArrayList<>(); - private MessageEvent onClick; - private MessageEvent onHover; - private String color; - private ChatColor legacyColor; - private String font; - private String text; - - public MessagePart(String text) { - this.text = text == null ? "null" : text; - } - - /** - * Converts this {@link MessagePart} into a {@link JsonObject} - * - * @return The Minecraft-compatible {@link JsonObject} - */ - public JsonObject toJSON() { - Objects.requireNonNull(text); - - JsonObject obj = new JsonObject(); - obj.addProperty("text", text); - - if (color != null && !color.isEmpty()) { - obj.addProperty("color", color.toLowerCase()); - } - - for (ChatColor style : styles) { - obj.addProperty(stylesToNames.get(style), true); - } - - if (onClick != null) { - obj.add("clickEvent", onClick.toJSON()); - } - - if (onHover != null) { - obj.add("hoverEvent", onHover.toJSON()); - } - - if (font != null) { - obj.addProperty("font", font); - } - - return obj; - - } - - /** - * @return This {@link MessagePart} in legacy-style color/formatting codes - */ - public String toLegacy() { - StringBuilder output = new StringBuilder(); - ChatColor legacyColor = getColor(); - - if (legacyColor != null) { - output.append(legacyColor); - } - - styles.stream() - .map(ChatColor::toString) - .forEach(output::append); - - return output.append(text).toString(); - } - - /** - * @return The click event bound - */ - public MessageEvent getOnClick() { - return onClick; - } - - /** - * @param onClick The new click event to bind - */ - public void setOnClick(MessageEvent onClick) { - this.onClick = onClick; - } - - /** - * @return The hover event bound - */ - public MessageEvent getOnHover() { - return onHover; - } - - /** - * @param onHover The new hover event to bind - */ - public void setOnHover(MessageEvent onHover) { - this.onHover = onHover; - } - - /** - * @return The color - */ - public String getColorValue() { - return color; - } - - /** - * @return The color - * @deprecated Use {@link #getColorValue()} instead - */ - @Deprecated - public ChatColor getColor() { - if (legacyColor != null) { - return legacyColor; - } - - if (this.color.startsWith("#") && ReflectionHelper.MAJOR_VER < 16) { - throw new IllegalStateException( - "Custom Hex colors can only be used in Minecraft 1.16 or newer!"); - } - - try { - return ChatColor.valueOf(this.color.toUpperCase()); - } catch (Exception ex) { - return null; - } - } - - /** - * @param color The color to set - * @deprecated Use {@link #setColor(String)} instead - */ - @Deprecated - public void setColor(ChatColor color) { - setColor(color == null ? null : color.name().toLowerCase()); - setLegacyColor(color); - } - - /** - * @param color The color to set - */ - public void setColor(String color) { - if (color != null && color.isEmpty()) { - throw new IllegalArgumentException("Color cannot be null!"); - } - this.color = color; - } - - /** - * @param color The legacy ChatColor to set - * @deprecated Use {@link #setColor(String)} instead - */ - @Deprecated - public void setLegacyColor(ChatColor color) { - legacyColor = color; - } - - /** - * @return The list of styles - */ - public List getStyles() { - return styles; - } - - /** - * @param style The new style to add - */ - public void addStyle(ChatColor style) { - if (style == null) { - throw new IllegalArgumentException("Style cannot be null!"); - } - if (!style.isFormat()) { - throw new IllegalArgumentException(style.name() + " is not a style!"); - } - styles.add(style); - } - - /** - * @return The font used - */ - public String getFont() { - return font; - } - - /** - * @param font The font to use - */ - public void setFont(String font) { - this.font = font; - } - - /** - * @return The raw text - */ - public String getText() { - return text; - } - - /** - * @param text The raw text to set - */ - public void setText(String text) { - this.text = text; - } - - } -} \ No newline at end of file diff --git a/src/main/java/me/clip/placeholderapi/listeners/ServerLoadEventListener.java b/src/main/java/me/clip/placeholderapi/listeners/ServerLoadEventListener.java index b76d2ef..f7141d8 100644 --- a/src/main/java/me/clip/placeholderapi/listeners/ServerLoadEventListener.java +++ b/src/main/java/me/clip/placeholderapi/listeners/ServerLoadEventListener.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/replacer/CharsReplacer.java b/src/main/java/me/clip/placeholderapi/replacer/CharsReplacer.java index 98ff409..0b3bb0c 100644 --- a/src/main/java/me/clip/placeholderapi/replacer/CharsReplacer.java +++ b/src/main/java/me/clip/placeholderapi/replacer/CharsReplacer.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. @@ -49,7 +49,7 @@ public final class CharsReplacer implements Replacer { for (int i = 0; i < chars.length; i++) { final char l = chars[i]; - + if (l == '&' && ++i < chars.length) { final char c = Character.toLowerCase(chars[i]); diff --git a/src/main/java/me/clip/placeholderapi/replacer/RegexReplacer.java b/src/main/java/me/clip/placeholderapi/replacer/RegexReplacer.java index 3e3bee5..8eccfbe 100644 --- a/src/main/java/me/clip/placeholderapi/replacer/RegexReplacer.java +++ b/src/main/java/me/clip/placeholderapi/replacer/RegexReplacer.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/replacer/Replacer.java b/src/main/java/me/clip/placeholderapi/replacer/Replacer.java index d25402e..339088f 100644 --- a/src/main/java/me/clip/placeholderapi/replacer/Replacer.java +++ b/src/main/java/me/clip/placeholderapi/replacer/Replacer.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java b/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java index 206dcd1..2163be2 100644 --- a/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java +++ b/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. @@ -23,6 +23,7 @@ package me.clip.placeholderapi.updatechecker; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; +import java.util.Arrays; import javax.net.ssl.HttpsURLConnection; import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.util.Msg; @@ -90,17 +91,24 @@ public class UpdateChecker implements Listener { return false; } - String plV = toReadable(pluginVersion); - String spV = toReadable(spigotVersion); - return plV.compareTo(spV) < 0; + int[] plV = toReadable(pluginVersion); + int[] spV = toReadable(spigotVersion); + + if (plV[0] < spV[0]) { + return true; + } else if ((plV[1] < spV[1])) { + return true; + } else { + return plV[2] < spV[2]; + } } - private String toReadable(String version) { - if (version.contains("-DEV-")) { - version = version.split("-DEV-")[0]; + private int[] toReadable(String version) { + if (version.contains("-DEV")) { + version = version.split("-DEV")[0]; } - return version.replaceAll("\\.", ""); + return Arrays.stream(version.split("\\.")).mapToInt(Integer::parseInt).toArray(); } @EventHandler(priority = EventPriority.MONITOR) diff --git a/src/main/java/me/clip/placeholderapi/util/FileUtil.java b/src/main/java/me/clip/placeholderapi/util/FileUtil.java index 7e20de1..825ff54 100644 --- a/src/main/java/me/clip/placeholderapi/util/FileUtil.java +++ b/src/main/java/me/clip/placeholderapi/util/FileUtil.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. @@ -42,13 +42,11 @@ public class FileUtil { } final URL jar = file.toURI().toURL(); - + final URLClassLoader loader = new URLClassLoader(new URL[]{jar}, clazz.getClassLoader()); final List matches = new ArrayList<>(); final List> classes = new ArrayList<>(); - try (final JarInputStream stream = new JarInputStream( - jar.openStream()); final URLClassLoader loader = new URLClassLoader(new URL[]{jar}, - clazz.getClassLoader())) { + try (final JarInputStream stream = new JarInputStream(jar.openStream())) { JarEntry entry; while ((entry = stream.getNextJarEntry()) != null) { final String name = entry.getName(); @@ -69,8 +67,11 @@ public class FileUtil { } } } - - return classes.isEmpty() ? null : classes.get(0); + if (classes.isEmpty()) { + loader.close(); + return null; + } + return classes.get(0); } } diff --git a/src/main/java/me/clip/placeholderapi/util/Format.java b/src/main/java/me/clip/placeholderapi/util/Format.java index 1d959c2..1167375 100644 --- a/src/main/java/me/clip/placeholderapi/util/Format.java +++ b/src/main/java/me/clip/placeholderapi/util/Format.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/util/Futures.java b/src/main/java/me/clip/placeholderapi/util/Futures.java index 01a3586..8f07e32 100644 --- a/src/main/java/me/clip/placeholderapi/util/Futures.java +++ b/src/main/java/me/clip/placeholderapi/util/Futures.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/util/Msg.java b/src/main/java/me/clip/placeholderapi/util/Msg.java index 702b251..31aa49f 100644 --- a/src/main/java/me/clip/placeholderapi/util/Msg.java +++ b/src/main/java/me/clip/placeholderapi/util/Msg.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/util/TimeFormat.java b/src/main/java/me/clip/placeholderapi/util/TimeFormat.java index e0b9717..9558daa 100644 --- a/src/main/java/me/clip/placeholderapi/util/TimeFormat.java +++ b/src/main/java/me/clip/placeholderapi/util/TimeFormat.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/main/java/me/clip/placeholderapi/util/TimeUtil.java b/src/main/java/me/clip/placeholderapi/util/TimeUtil.java index 33b14fc..85e07df 100644 --- a/src/main/java/me/clip/placeholderapi/util/TimeUtil.java +++ b/src/main/java/me/clip/placeholderapi/util/TimeUtil.java @@ -2,9 +2,9 @@ * This file is part of 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 * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. diff --git a/src/test/java/me/clip/placeholderapi/Values.java b/src/test/java/me/clip/placeholderapi/Values.java index 73d26bc..da23a34 100644 --- a/src/test/java/me/clip/placeholderapi/Values.java +++ b/src/test/java/me/clip/placeholderapi/Values.java @@ -2,7 +2,7 @@ * This file is part of PlaceholderAPI * * PlaceholderAPI - * Copyright (c) 2015 - 2020 PlaceholderAPI Team + * Copyright (c) 2015 - 2021 PlaceholderAPI Team * * PlaceholderAPI free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/test/java/me/clip/placeholderapi/replacer/ReplacerBenchmarks.java b/src/test/java/me/clip/placeholderapi/replacer/ReplacerBenchmarks.java index 2afc016..cec02bf 100644 --- a/src/test/java/me/clip/placeholderapi/replacer/ReplacerBenchmarks.java +++ b/src/test/java/me/clip/placeholderapi/replacer/ReplacerBenchmarks.java @@ -2,7 +2,7 @@ * This file is part of PlaceholderAPI * * PlaceholderAPI - * Copyright (c) 2015 - 2020 PlaceholderAPI Team + * Copyright (c) 2015 - 2021 PlaceholderAPI Team * * PlaceholderAPI free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/test/java/me/clip/placeholderapi/replacer/ReplacerUnitTester.java b/src/test/java/me/clip/placeholderapi/replacer/ReplacerUnitTester.java index 09524f3..7ff36bc 100644 --- a/src/test/java/me/clip/placeholderapi/replacer/ReplacerUnitTester.java +++ b/src/test/java/me/clip/placeholderapi/replacer/ReplacerUnitTester.java @@ -2,7 +2,7 @@ * This file is part of PlaceholderAPI * * PlaceholderAPI - * Copyright (c) 2015 - 2020 PlaceholderAPI Team + * Copyright (c) 2015 - 2021 PlaceholderAPI Team * * PlaceholderAPI free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by