Compare commits

...

589 Commits

Author SHA1 Message Date
Andre_601 68f467ab29
Add 1.20.2 - 1.20.5 to NMSVersion.java (#1057) 2024-04-30 10:35:18 -05:00
PiggyPiglet 068b5a31b2
Fix #1034 & Deprecate VersionSpecific & update copyright (#1035)
Co-authored-by: Andre_601 <github@andre601.ch>
2024-04-30 10:34:43 -05:00
Gabriel Dumitru 882b7c5965
Merge pull request #1046 from PlaceholderAPI/feature/add-plugin-authors
Add Plugin Authors to /papi dump
2024-03-07 22:59:42 +02:00
Gabriel Dumitru 7a0be5edf8
Merge pull request #1040 from DevCyntrix/fix-class-cast-exception
Use the OfflinePlayer$getPlayer method instead of casting to Player class
2024-03-07 22:59:24 +02:00
Andre601 e94328935d
Add Plugin Authors to /papi dump 2024-02-25 14:42:48 +01:00
Andre_601 604fed36a4
Man, this file is outdated... 2024-02-25 00:14:41 +01:00
Ricardo Borutta 403622d205 Use the OfflinePlayer$getPlayer method instead of casting to Player class
You should use this to avoid a class cast exception if some other plugins uses an own Implementation of the offline player.
2024-01-29 10:21:24 +01:00
Funnycube 1cd4d93f7f
Merge pull request #1038 from Funny-cube/master
Update config.yml with papi domain for wiki and ecloud
2024-01-27 21:57:48 +11:00
Funnycube a83ef75bf9
Update config.yml 2024-01-27 20:45:10 +11:00
Andre_601 b96e535aaa
Update wiki link in PR template 2024-01-27 00:58:11 +01:00
Andre_601 2e67272aea
Fix logo and update link in README 2024-01-26 23:05:04 +01:00
Andre_601 2c7767e77d
fix github admonition blocks 2024-01-22 20:12:39 +01:00
Andre_601 c4a046ff24
Merge pull request #1006 from PlaceholderAPI/feature/add-new-download-pages
Add Hangar and BuiltByBit pages to readme
2023-11-26 16:58:08 +01:00
PiggyPiglet 57fa68c896
change version to .6-dev 2023-10-28 21:50:05 +08:00
PiggyPiglet b64f024eb2
fix config version variable and set release version 2023-10-28 21:49:39 +08:00
PiggyPiglet c7a4900aa3
remove ability to download unverified expansions 2023-10-28 21:42:18 +08:00
Andre_601 491abd6238
BuilT not BuilD 2023-09-25 15:11:49 +02:00
Andre_601 d3646a9874
Change Built By Bit to BuiltByBit Page 2023-09-25 15:07:13 +02:00
Andre_601 af0b475330
Add Hangar and BuiltByBit pages to readme 2023-09-25 14:58:30 +02:00
Funnycube d35a499e31
Update plugin.yml
remove unused toggle permissions
2023-09-24 13:49:40 +10:00
Funnycube c0f824450e
Update build.gradle.kts
start 2.11.5-DEV
2023-09-24 12:59:01 +10:00
Funnycube 5b1a8ef4ba
2.11.4 release 2023-09-24 12:40:46 +10:00
PiggyPiglet 5623a00f9b
Merge pull request #978 from JulianVennen/block-unverified-expansions
Add environment variable to override cloud_allowunverified_expansions
2023-09-21 17:38:54 +08:00
PiggyPiglet 4926907b47
Merge pull request #969 from PlaceholderAPI/feature/support-1.20
1.20 support
2023-09-04 17:26:11 +08:00
Andre_601 195158b18b
Use new format for note block [skip ci] 2023-08-01 03:27:15 +02:00
Gabriel Dumitru 36fa9ac96d
feat: distinguish expansions (external or internal) (fixes #945) (#953) 2023-07-24 11:48:29 +03:00
Julian 42cfe1dc80
simplify env values to true/false 2023-06-23 17:06:11 +02:00
Julian 92a7d54664
Add environment variable to override cloud_allowunverified_expansions
This adds the environment variable PAPI_ALLOW_UNVERIFIED_EXPANSIONS.
It allows overriding the option set in the config.yml.
2023-06-23 14:04:00 +02:00
Gabriel Dumitru f91b4e3752
feat: fetch all expansions (#952) 2023-06-21 21:26:52 +03:00
PiggyPiglet a497e05e55
Merge pull request #947 from JulianVennen/block-extensions-env
Add environment variable to block individual ecloud expansions.
2023-06-21 20:25:16 +08:00
Andre601 74d8fec6bd
Bump Spigot version 2023-06-10 18:13:10 +02:00
Andre601 28287c7fbd
1.20 NMS version support 2023-06-10 17:59:55 +02:00
Gabriel Dumitru 744cf6d8c0
Merge pull request #946 from JulianVennen/block-load-path-traversal
Prevent loading of extensions outside of the expansions folder using the register command
2023-04-04 17:28:00 +03:00
Julian ecd4c002c8
Add environment variable to block individual ecloud expansions.
This commit adds the environment variable "PAPI_BLOCKED_EXPANSIONS"
which can contain a case insensitive, comma separated list of blocked
expansions.
Expansions on this list can no longer be downloaded using commands.
2023-03-30 13:41:01 +02:00
Julian b4e60b7db5
Prevent loading of extensions outside of the expansions folder using the register command 2023-03-30 12:47:23 +02:00
darbyjack e862abe0b4
Start 2.11.4 DEV cycle 2023-03-17 20:07:24 -05:00
darbyjack 2d946646f0
Release 2.11.3 2023-03-17 20:03:47 -05:00
Glare 5ab61e0cd3
Update the NMS options up to the latest 1.19 R3 (#938) 2023-03-17 19:59:31 -05:00
Gabriel Dumitru 81ef464dad
fix: catch NoClassDefFoundError in order for the other expansions to be loaded (#936) 2023-03-17 15:44:41 -05:00
Gabriel Dumitru 0ae0ddc9cb
Merge pull request #935 from PlaceholderAPI/fix/kotlin-build-system 2023-03-17 22:16:10 +02:00
darbyjack 3d00d48106
Tell build to depend on shadowJar and publish for build 2023-03-17 14:13:49 -05:00
darbyjack 7e902cae66
Fixed variables in the plugin.yml not being created properly 2023-03-17 13:45:31 -05:00
Matt f4e4433b16
Feature/gradle kts (#934)
Co-authored-by: darbyjack <admin@glaremasters.me>
2023-03-17 13:25:47 -05:00
Andre_601 d5c371004c
Fix duplicate expansion loading (#866) 2023-03-17 12:47:27 -05:00
Glare e246473782
Merge pull request #933 from PlaceholderAPI/feature/update-adventure 2023-03-16 18:31:20 -05:00
Andre601 4afad7f7b0
Update Kyori Adventure to 4.3.0 2023-03-17 00:22:58 +01:00
PiggyPiglet a0b177bdd8
Merge pull request #869 from PlaceholderAPI/remove-ecloud-toggle-command
remove the eCloud toggle command
2023-02-23 21:29:06 +08:00
Gabriel Dumitru 40b1fe8d68
Merge pull request #901 from BlockyTheDev/fix-status-message 2023-02-23 13:36:05 +02:00
PiggyPiglet 9ee4afa1e9
Merge pull request #873 from PlaceholderAPI/fix/872-fix-inxonsisten-parsing
Fix inconsistent parsing command behaviour
2023-02-23 19:31:38 +08:00
BlockyTheDev 1cf66b130c
Add space to message 2022-12-25 21:31:55 +01:00
Andre601 c3cfc82eb3 Fix inconsistent parsing command behaviour 2022-08-14 16:30:22 +02:00
Gabriel Dumitru 3afb634e58
revert 4c228ca4fb 2022-08-10 16:01:41 +03:00
Gabriel Dumitru d888d9754b
remove from help 2022-08-09 01:20:04 +03:00
Gabriel Dumitru 4c228ca4fb make the eCloud disable by default 2022-08-09 01:08:45 +03:00
Gabriel Dumitru 6cf987586e remove the eCloud toggle command 2022-08-09 01:08:24 +03:00
Glare 46d9a69534
Merge pull request #862 from darbyjack/fix-ecloud-components
Updated Adventure
2022-07-26 18:49:45 -05:00
Glare af8cc09fca
Merge pull request #863 from darbyjack/bump-dev
Bump to 2.11.3-dev
2022-07-26 18:48:44 -05:00
darbyjack 452c8ccd42
Bump to 2.11.3-dev 2022-07-26 16:22:18 -05:00
darbyjack 054c780fd1
Updated Adventure 2022-07-26 12:57:11 -05:00
Andre_601 83261eee49
Update canned responses. 2022-07-03 20:12:45 +02:00
PiggyPiglet 3fca78626a
remove remaining colour shit and changed version so cube can release and we can be all happy and dandy 2022-07-03 20:34:12 +08:00
PiggyPiglet a2456c582d
Removed excess capitalisation 2022-07-02 21:45:53 +08:00
Andre_601 b987916328
Update Image link 2022-07-02 13:46:48 +02:00
Andre_601 23ef4ecb62
Remove wiki folder 2022-07-02 13:46:09 +02:00
PiggyPiglet 8b7a217796
Merge pull request #830 from montlikadani/improve-replacer-process
Remove regex replacer & associated tests
2022-07-01 23:33:35 +08:00
PiggyPiglet 74ebb0bec0
remove regex replacer & associated tests 2022-07-01 23:31:51 +08:00
Glare 794c8890e5
Merge pull request #801 from PlaceholderAPI/fix/papi-dump-expansion-order 2022-07-01 10:08:57 -05:00
Glare 013e566a85
Merge pull request #832 from PlaceholderAPI/feature/log-missing-plugin 2022-07-01 09:51:12 -05:00
Glare 5a4a8c2e7e
Merge pull request #793 from Rothes/master 2022-07-01 09:46:39 -05:00
Andre_601 0b068470ac
Update CODEOWNERS 2022-07-01 13:06:22 +02:00
Andre_601 f3cb7635c2
Update old links 2022-06-30 22:51:34 +02:00
Andre_601 8e21a76118
Update bug_report.yml 2022-06-30 22:26:13 +02:00
Andre_601 1dad2381e5
Delete wiki action (Not needed) 2022-06-30 22:16:06 +02:00
Andre_601 9767811cb9
Merge pull request #847 from JT122406/master
Gradle Bumps and stuff
2022-06-27 12:55:06 +02:00
J.T. McQuigg e6fb6d5ec6 Other small version bumps 2022-06-26 23:54:07 -04:00
J.T. McQuigg 1acc621f2e Bump Gradle from 7.3.1 to 7.4.2 2022-06-26 23:53:51 -04:00
Glare d9bab03e3b
Merge pull request #773 from PlaceholderAPI/feature/update-contributing 2022-06-25 15:47:54 -05:00
PiggyPiglet 9baf5f58ae
Merge pull request #844 from PlaceholderAPI/feature/1.19
1.19 support
2022-06-25 20:06:19 +08:00
Andre601 077d64dc68 Fix NMS version 2022-06-16 01:45:47 +02:00
Andre601 b8d5886cad 1.19 support 2022-06-16 01:31:33 +02:00
Andre_601 52119682f3
Use custom quote block in automatic replies 2022-05-20 17:04:38 +02:00
Andre601 651e14a797 Make plugin check before register to avoid possible exceptions 2022-05-19 02:46:40 +02:00
Andre601 0ac62d6b63 Log missing required plugin for expansion
+ some logger improvements
2022-05-18 21:11:09 +02:00
Andre601 0be6b721cf Use stream to get size padding 2022-05-04 18:36:46 +02:00
Andre601 0e0e36476a Change appended message for null jar array 2022-04-29 23:13:19 +02:00
Andre_601 a56b3b62b9
Update to v3 wiki action 2022-04-28 21:30:52 +02:00
Funnycube 883f1c1edf
One Million 🎉 2022-04-08 20:23:05 +10:00
Rothes bfc30a8703
`Locale.ROOT` param 2022-03-26 09:09:50 +08:00
Andre_601 37c39ab734
Update the flex 2022-03-26 01:36:07 +01:00
Glare 35c47a8745
Merge pull request #810 from PlaceholderAPI/feature/remove-escape-hex-test
Remove testCharsReplacerHandlesEscapedHex()
2022-03-13 05:48:30 -05:00
PiggyPiglet fadf14a316
Merge pull request #814 from PlaceholderAPI/fix/666-lowercasing
fix(replacer): Stop lowercasing replacements
2022-03-13 14:35:34 +08:00
Starmism 1388a5278f fix(replacer): Stop lowercasing replacements
This commit changes two lines but fixes the replacement of cased
    placeholders with non-cased ones that was accidentally happening.
    This was partially fixed in a few previous commits, but not fully as
    it was still replacing failed placeholder matches.
2022-03-12 12:42:56 -07:00
Andre_601 3bc6ad0f06
Also update label-commenter-config 2022-03-12 01:20:21 +01:00
Andre_601 bb149811d4
Update label-commenter-config.yml 2022-03-12 01:16:33 +01:00
Andre601 350a2be0ed Remove testCharsReplacerHandlesEscapedHex() 2022-02-22 11:48:51 +01:00
Gabriel Dumitru b73d72cec7
add missing java.util.Locale imports 2022-02-22 11:42:35 +02:00
Gabriel Dumitru 7afb8ee36d
Merge pull request #800 from PlaceholderAPI/feature/null-parse-option
Add --null argument for Parse command
2022-02-22 10:42:02 +02:00
Andre601 1241c33ba0 Add --null to command help 2022-02-05 20:55:48 +01:00
Andre601 631609af74 Improve expansion sorting in /papi dump 2022-02-05 14:08:43 +01:00
Andre601 fe8d865657 Add missing import 2022-02-05 13:57:30 +01:00
Andre601 50d4e14333 Add --null option for parse command 2022-02-05 13:57:05 +01:00
Andre_601 666ab468a1
Link to docs/wiki branch README 2022-01-30 12:03:42 +01:00
Rothes 151fb08db8
Fix PlaceholderExpansion may not unregistered 2022-01-28 13:40:39 +08:00
Andre_601 cd9074203c
Update label-commenter-config.yml 2022-01-03 00:19:58 +01:00
Andre_601 38d77ff4ca
Update label-commenter-config.yml 2022-01-03 00:17:23 +01:00
Glare 3ccbbe9c20
Bump to 2.11.2 DEV 2021-12-27 01:33:36 -08:00
Glare 358a3bcab3
Release 2.11.1 2021-12-27 01:32:00 -08:00
PiggyPiglet ca088227c3
Merge pull request #772 from PlaceholderAPI/fix/771-identifier-replacement
Fix #771
2021-12-27 15:21:30 +08:00
Andre_601 69fd180c9b
Update CONTRIBUTING.md 2021-12-25 16:55:05 +01:00
Andre_601 38e6e02e1b
Not sure how I missed that... 2021-12-25 15:53:07 +01:00
Andre_601 a71b8657f1
Update Contributing file 2021-12-25 15:50:17 +01:00
PiggyPiglet 850633e792
Fix #771 2021-12-24 12:34:36 +08:00
PiggyPiglet 348b075ac5
added glare's fancy pants dev string to ver 2021-12-24 12:32:01 +08:00
PiggyPiglet ce18d3b597
update licenses & bump deprecation ver 2021-12-24 12:26:22 +08:00
PiggyPiglet 9d66d9d9a1
bump ver 2021-12-24 12:24:40 +08:00
darbyjack 5fe9389dda
We're actually on 2.11.0 RELEASE 2021-12-19 18:59:38 -06:00
darbyjack e25a28b2a5
2.10.11 RELEASE 2021-12-19 18:53:25 -06:00
PiggyPiglet cfd289939e
Merge pull request #667 from PlaceholderAPI/fix/666-lowercase-issues
Fix issue with invalid placeholder pattern lowercasing text
2021-12-19 18:49:37 -06:00
PiggyPiglet d168be94b1
Merge pull request #752 from PlaceholderAPI/1.18
1.18 + Gradle Updates
2021-12-03 13:01:09 +08:00
PiggyPiglet 511717a8d6
Merge branch 'master' into 1.18 2021-12-03 13:01:02 +08:00
PiggyPiglet 18fb194ce6
Merge pull request #677 from PlaceholderAPI/feature/add-logging-options
Add logging options to PlaceholderExpansion
2021-12-03 13:00:15 +08:00
PiggyPiglet e11d551071
Merge pull request #717 from PlaceholderAPI/feature/log-expansio-version
Include version in registration message and other QOL changes
2021-12-03 12:59:20 +08:00
PiggyPiglet 020f14d82c
Merge branch 'master' into feature/log-expansio-version 2021-12-03 12:59:07 +08:00
darbyjack acb5728e65
1.18 + Gradle Updates 2021-12-02 21:55:12 -06:00
Andre_601 cc235cfc01
Merge Development into master (#758)
* Update development from master (#662)

* 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

* 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

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

* Update dependencies of PlaceholderAPI

* Add missing trailing /

Co-authored-by: PiggyPiglet <PiggyPiglet@users.noreply.github.com>
Co-authored-by: darbyjack <admin@glaremasters.me>
Co-authored-by: PiggyPiglet <noreply@piggypiglet.me>
2021-12-03 04:52:28 +01:00
PiggyPiglet 894dcd0a2f
Merge pull request #687 from PlaceholderAPI/java-version-dump
Add Java Version to /papi dump command
2021-12-03 11:40:11 +08:00
PiggyPiglet 41c9231664
Merge pull request #749 from itIsMaku/master
nullable annotation placeholderhook
2021-12-03 11:37:52 +08:00
Andre601 31deef2a62 Use completedFuture instead 2021-12-01 21:30:41 +01:00
Andre601 3ba29f1147 Fix possible NPE for findExpansionsOnDisk 2021-12-01 19:09:02 +01:00
Andre601 e969f37405 Improve StringBuilder and also fix possible NPE 2021-12-01 19:05:28 +01:00
Andre_601 b9a5f4445f
Merge pull request #731 from PlaceholderAPI/feature/automatic-release-drafting
Add release.yml for automatic release drafts
2021-11-29 01:36:03 +01:00
Adam Volkman (itIsMaku) 6f87955898
feat: nullable annotation placeholderhook 2021-11-17 14:10:19 +01:00
Andre_601 d68af58df5
Make name of job only show java version 2021-11-11 13:49:48 +01:00
Andre_601 6e1eb88585
Add release.yml for automatic release drafts 2021-10-09 18:39:13 +02:00
Andre_601 0798d94449
Update this flex too funnycube :) 2021-10-01 16:22:30 +02:00
Funnycube aa68a481ee
Update flex 2021-10-01 22:59:12 +10:00
Andre_601 6f5853746d
fix wiki action... again 2021-10-01 14:17:21 +02:00
Andre_601 416fbc0e3e
Merge branch 'docs/wiki' into master 2021-10-01 14:16:06 +02:00
Andre601 407714c13f Rename logo.png to wiki-logo.png 2021-10-01 14:14:41 +02:00
Andre_601 aa13ddf17e
Add files via upload 2021-10-01 14:10:19 +02:00
Andre_601 d9da5a706c
Update README.md 2021-10-01 14:01:59 +02:00
Andre_601 80446de15b
Merge pull request #718 from TheCashFire/patch-1
New Placeholder for %aach_total_commands%
2021-09-23 16:37:08 +02:00
Kris Stancy 0647f88de5
New Placeholder
Added %aach_total_commands% new placeholder to the total achievement placeholders section.
2021-09-19 22:06:01 -05:00
Andre601 38099198d6 Include version in registration message 2021-09-20 02:42:38 +02:00
Andre_601 6f2f1f1cf1
Update README.md 2021-09-12 02:17:58 +02:00
ThisKarolGajda 5e4d3f7135
Update Placeholders.md (#714) 2021-09-10 14:25:24 +02:00
Andre_601 327078d8dd
Update README.md 2021-09-10 03:30:03 +02:00
Andre_601 1b7fabf238
Update Wiki Readme... a lot 2021-09-10 03:23:11 +02:00
Andre_601 66025a6a1c
Update PlaceholderExpansion.md 2021-09-10 02:02:53 +02:00
Andre_601 04f2c85722
fix e-mail env 2021-09-10 01:58:46 +02:00
ThisKarolGajda 7b5ceb520f
Update Placeholders.md - OpEconomy (#713)
* Update Placeholders.md

* Add OpEconomy to "Plugins using PlaceholderAPI"

Co-authored-by: Andre_601 <11576465+Andre601@users.noreply.github.com>
2021-09-10 01:55:13 +02:00
Andre_601 f7dc184899
Update label-commenter-config.yml 2021-09-09 18:32:37 +02:00
Andre_601 4300bf7d1e
Pull latest changes from master into docs/wiki (#712)
* Update Javadoc documentation

* More comments... a lot more!

* Remove Gson

* Implemented working version for 1.8.8 - 1.16.3

* Improve ExpansionsLoadedEvent's docs

* 2021 🥳

* Add contributing and expansion section

* Fix invalid link tag

* Start using new Issue template system

* Create bug_report.yml

* Rename feature_request.md to feature_request_old.md

* Create feature_request.yml

* should it use setBracketPlaceholders??

* fix unique name

* Update feature_request_old.md

* Add Checkboxes

* Add checkboxes

* disable default issue body

* Delete bug_report_old.md

* Delete feature_request_old.md

* Rename bug_report_new.yml to bug_report.yml

* Check if deleting this fixed the PR...

* Use description in favour of about

* improve feature_request.md

* Update bug_report.yml

* Assign "Type: Issue (Unconfirmed)" label

* Use lists and not comma-separated string

* Update feature_request.yml

* Use id option for error and dump fields

* Add field for logs

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

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

* Undo renaming of boolean

* Remove deprecated issue_body type

* Update feature_request.yml

* Improve description of bug_report.yml

* Build jars on PR (Compile and build validation)

* Initial 1.17 Changes

* Extracted URLClassLoader out of try-with-resources block

* Close URLClassLoader if Expansion class was not found

* Build against Java 8, 11 and 16

* adoPt

I always make that mistake...

* add render

* Cleanup build.gradle

(cherry picked from commit 7750ba7033)

* 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 f5386d4ca5)

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

(cherry picked from commit ef5cd9d376)

* 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 ccf4f59343)

* Re-add NotNull's

(cherry picked from commit 2bfd8e7e5e)

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

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

* Add method implementation checking and nullchecking for fields.

* Appease the Pigman

* Revert build.gradle dependencies change

* Fixed duplicate files

* Sync Dev with master (#659)

* Add contributing and expansion section

* Start using new Issue template system

* Create bug_report.yml

* Rename feature_request.md to feature_request_old.md

* Create feature_request.yml

* fix unique name

* Update feature_request_old.md

* Add Checkboxes

* Add checkboxes

* disable default issue body

* Delete bug_report_old.md

* Delete feature_request_old.md

* Rename bug_report_new.yml to bug_report.yml

* Check if deleting this fixed the PR...

* Use description in favour of about

* improve feature_request.md

* Update bug_report.yml

* Assign "Type: Issue (Unconfirmed)" label

* Use lists and not comma-separated string

* Update feature_request.yml

* Use id option for error and dump fields

* Add field for logs

* Remove deprecated issue_body type

* Update feature_request.yml

* Improve description of bug_report.yml

* Initial 1.17 Changes

* add render

* Revert build.gradle dependencies change

* Fixed duplicate files

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

* Initial test on adventure

* started moving to pure adventure

* finished kyori impl

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

* removed dev for release

* added dev back

* Switch to differen wiki action

Co-authored-by: darbyjack <admin@glaremasters.me>
Co-authored-by: ElijahRus250 <64851720+ElijahRus250@users.noreply.github.com>
Co-authored-by: PiggyPiglet <PiggyPiglet@users.noreply.github.com>
Co-authored-by: Huynh Tien <huynhqtienvtag@gmail.com>
Co-authored-by: Vaishnav Anil <vaishnavanil7th@gmail.com>
Co-authored-by: Starmism <iamstarmism@gmail.com>
Co-authored-by: PiggyPiglet <noreply@piggypiglet.me>
2021-09-09 18:31:29 +02:00
Andre_601 5412b484f8
Merge pull request #706 from NotMyFault/feature/wiki/update-plotsquared
Update PlotSquared placeholders
2021-09-03 02:05:39 +02:00
NotMyFault af2f625224
Update PlotSquared placeholders 2021-09-03 00:05:42 +02:00
Andre_601 d2a4f038d0
Merge pull request #705 from DailyStruggle/Add-RTP-Placeholders
add RTP placeholders
2021-09-01 13:39:13 +02:00
Andre_601 7e28dc0a41
Merge pull request #698 from PlaceholderAPI/feature/change-wiki-action
Switch to differen wiki action
2021-09-01 13:38:30 +02:00
Andre_601 b82948c87a
fix link 2021-09-01 13:38:15 +02:00
Andre_601 39c68e8f87
fix url and padding 2021-09-01 13:37:19 +02:00
Leaf26 5a24387f3d fix spacing 2021-08-31 22:39:02 -04:00
Leaf26 cd429bd7d7 adding a few more 2021-08-31 22:38:03 -04:00
Leaf26 a383a73b24 add RTP placeholders 2021-08-31 21:41:32 -04:00
Andre_601 7baaa5233d
Merge pull request #703 from PyvesB/patch-1
Update Advanced Achievements information
2021-08-30 13:06:35 +02:00
Pierre-Yves B b35035390e
Simplify link format
Co-authored-by: Andre_601 <11576465+Andre601@users.noreply.github.com>
2021-08-30 12:05:14 +01:00
Pierre-Yves B 1b0a3bc09d
Simplify link format
Co-authored-by: Andre_601 <11576465+Andre601@users.noreply.github.com>
2021-08-30 12:05:04 +01:00
Pierre-Yves B 3817f52158
Add Advanced Achievements placeholders 2021-08-30 11:44:47 +01:00
Pierre-Yves B 663f149d74
Add Advanced Achievements placeholders 2021-08-30 11:43:26 +01:00
Pierre-Yves B 3da8f00664
Update Advanced Achievements links 2021-08-30 11:18:11 +01:00
Andre_601 c24c75c8c0
Merge pull request #701 from LielAmar/docs/wiki
Added Two Factor Authentication to PlaceholderAPI's wiki
2021-08-27 16:19:13 +02:00
Liel c401adee86 Added Two Factor Authentication to PlaceholderAPI's wiki 2021-08-27 16:24:51 +03:00
Andre_601 1dd3e1fc0d
Switch to differen wiki action 2021-08-26 22:42:05 +02:00
Andre_601 1f53daf416
Some more corrections 2021-08-23 01:58:15 +02:00
Andre_601 8105beeee0
Improve grammar of PlaceholderExpansion.md 2021-08-23 01:52:10 +02:00
Andre_601 8c9a20c035
Merge pull request #696 from TeamVK/docs/wiki
added new placeholders for TokenEnchant
2021-08-22 12:17:49 +02:00
vk2gpz c1d2effe7e
added new placeholders for TokenEnchant
renamed rawcost to fullcost.
added costmax 
```%tokenenchant_<enchantment>_costmax% : cost to increment the enchantmnt level to its maax one from the current level 
%tokenenchant_<enchantment>_fullcostmax% : cost to enchant the max level from 0 level 
%tokenenchant_<enchantment>_fullcost_<X>% : cost to enchant the <X> level from 0 level
```
2021-08-22 09:42:02 +10:00
Andre_601 2eda4b1335
Add missing commands to wiki 2021-08-15 15:44:27 +02:00
Andre_601 ff72450d3f
Merge pull request #692 from BlitzOffline/docs/wiki
Added placeholders from the String expansion
2021-08-15 00:00:41 +02:00
BlitzOffline a654262196
Added placeholders frmo the String expansion 2021-08-15 00:04:17 +03:00
Andre_601 fa705e4572
Merge pull request #689 from TeamVK/docs/wiki
added missing baltop related placeholders and multiplier related placeholders.
2021-08-08 23:24:37 +02:00
vk2gpz e687a06d6e
added missing baltop related placeholders 2021-08-09 07:19:25 +10:00
darbyjack 08c43d25e7
Add Java Version to /papi dump command 2021-08-04 14:16:15 -05:00
Andre_601 48da25659d
Merge pull request #685 from AfkF24/docs/wiki
Update Placeholders.md
2021-07-31 16:46:22 +02:00
AfkF24 905c9e83ee
Apply suggestions from code review
Woop, thanks

Co-authored-by: Andre_601 <11576465+Andre601@users.noreply.github.com>
2021-07-31 16:44:46 +02:00
AfkF24 54ddc9fd4d
Update Placeholders.md
Swap Kingdoms+ for KingdomsX and add link to wiki
2021-07-31 16:23:25 +02:00
Andre601 fe0bb12d53 Add missing [<expansion>] prefix 2021-07-31 00:11:24 +02:00
Andre_601 e6da5f291e
Merge pull request #683 from TeamVK/docs/wiki
Update Placeholders.md
2021-07-29 00:36:40 +02:00
vk2gpz d674893312
Update Placeholders.md
added %levelup_pickaxe_block_count%, %levelup_bow_kill_count%, %levelup_sword_kill_count%
2021-07-29 07:27:27 +10:00
Andre_601 9da9e8c20f
Merge pull request #680 from BlitzOffline/docs/wiki
added changeoutput expansion placeholders
2021-07-24 14:01:29 +02:00
BlitzOffline 33c309ee8e
used inline code instead 2021-07-24 14:17:14 +03:00
BlitzOffline 62c3261a00
added changeoutput expansion placeholders 2021-07-24 14:00:42 +03:00
Funnycube c393392b85
Update Placeholders.md 2021-07-24 17:39:38 +10:00
Funnycube fbf91d6393
Merge pull request #679 from TeamVK/docs/wiki
added RandomNumber and LevelUp entries.
2021-07-24 17:30:49 +10:00
vk2gpz 8d30c4c99d
added RandomNumber and LevelUp entries. 2021-07-24 17:12:03 +10:00
Andre601 721904335d Add overload for Throwable 2021-07-22 23:56:29 +02:00
Andre601 d79f9725bd Add logging options to PlaceholderExpansion 2021-07-22 23:31:48 +02:00
Andre_601 eb2decb93d
Merge pull request #676 from M0diis/docs/wiki
Update Placeholders.md
2021-07-22 22:14:10 +02:00
M0dii d2192e3195
Update Plugins-using-PlaceholderAPI.md
Added VenturaCalendar.
2021-07-22 23:11:09 +03:00
M0dii c01acfba77
Update Placeholders.md
Change resource ID.
2021-07-22 21:54:44 +03:00
M0dii a494add04c
Update Placeholders.md 2021-07-22 21:48:38 +03:00
Andre_601 059047905f
Update formatter placeholders 2021-07-22 17:28:06 +02:00
Andre_601 fa717c34ef
fix code examples 2021-07-22 12:56:56 +02:00
Andre_601 e16287405b
Update nav entries (#674)
* Update nav entries

* Update Home.md
2021-07-22 01:36:43 +02:00
Andre_601 afdf80bf00
Rework PlaceholderExpansion page (#654)
* Rework PlaceholderExpansion page

* typo

* Implement suggestions of FunnyCube

* Apply suggestions from code review

Co-authored-by: Star <iamstarmism@gmail.com>

* Update wiki/PlaceholderExpansion.md

Co-authored-by: Star <iamstarmism@gmail.com>

* Rename "With a Plugin (Internal Jar)" to "With a Plugin (Internal Class)"

Co-authored-by: Star <iamstarmism@gmail.com>
2021-07-22 01:29:30 +02:00
Andre_601 ec7943fe0a
Fix formatting too 2021-07-17 22:23:28 +02:00
Andre_601 6493963d8a
Forgot the list-entry 2021-07-17 22:22:22 +02:00
Andre_601 c48e11bd70
Add OreMarket placeholders (#671)
* Add OreMarket placeholders

* Update Plugins-using-PlaceholderAPI.md

* Add URL
2021-07-17 22:18:53 +02:00
Andre_601 b4f6831e54
Update development from master (#662)
* 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

* 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

Co-authored-by: PiggyPiglet <PiggyPiglet@users.noreply.github.com>
Co-authored-by: darbyjack <admin@glaremasters.me>
Co-authored-by: PiggyPiglet <noreply@piggypiglet.me>
2021-07-11 01:37:09 +02:00
PiggyPiglet 6348c88c6f
added dev back 2021-07-10 12:17:08 +08:00
PiggyPiglet 5fb45d13da
removed dev for release 2021-07-10 12:16:37 +08:00
PiggyPiglet 5710972288
Merge remote-tracking branch 'origin/master' 2021-07-10 11:27:08 +08:00
PiggyPiglet 63955511a8
added 1.17 to nmsversion (what does this even do) 2021-07-10 11:26:56 +08:00
PiggyPiglet 9a7790c808
Merge pull request #661 from PlaceholderAPI/adventure
Adventure
2021-07-09 17:00:44 +08:00
PiggyPiglet 3abc78ff64
Merge pull request #660 from PlaceholderAPI/development
Sync Dev with master (#659)
2021-07-09 15:50:01 +08:00
PiggyPiglet c4789b7db0
finished kyori impl 2021-07-09 12:24:36 +08:00
PiggyPiglet d7a4acc2f5
started moving to pure adventure 2021-07-07 15:37:35 +08:00
darbyjack dd7751332f
Initial test on adventure 2021-07-06 11:59:17 -05:00
Andre_601 7b50453294
Add new Essentials placeholders 2021-07-03 17:56:32 +02:00
Andre_601 fa7c30df80
Sync Dev with master (#659)
* Add contributing and expansion section

* Start using new Issue template system

* Create bug_report.yml

* Rename feature_request.md to feature_request_old.md

* Create feature_request.yml

* fix unique name

* Update feature_request_old.md

* Add Checkboxes

* Add checkboxes

* disable default issue body

* Delete bug_report_old.md

* Delete feature_request_old.md

* Rename bug_report_new.yml to bug_report.yml

* Check if deleting this fixed the PR...

* Use description in favour of about

* improve feature_request.md

* Update bug_report.yml

* Assign "Type: Issue (Unconfirmed)" label

* Use lists and not comma-separated string

* Update feature_request.yml

* Use id option for error and dump fields

* Add field for logs

* Remove deprecated issue_body type

* Update feature_request.yml

* Improve description of bug_report.yml

* Initial 1.17 Changes

* add render

* Revert build.gradle dependencies change

* Fixed duplicate files

Co-authored-by: PiggyPiglet <PiggyPiglet@users.noreply.github.com>
Co-authored-by: darbyjack <admin@glaremasters.me>
2021-07-01 21:03:01 +02:00
darbyjack 89053354e9
Fixed duplicate files 2021-07-01 09:24:01 -05:00
Andre_601 ead63ca763
Revert build.gradle dependencies change 2021-07-01 16:21:49 +02:00
Andre_601 0fa592383f
Merge branch 'development' into master 2021-07-01 16:16:29 +02:00
PiggyPiglet 7df3a5c6e0
Merge pull request #657 from Starmism/development
Small changes on the correct branch!
2021-07-01 22:08:04 +08:00
Starmism c4a2256fff Appease the Pigman 2021-07-01 07:54:42 -06:00
Starmism 9b6b558002 Add method implementation checking and nullchecking for fields. 2021-06-30 10:13:47 -06:00
Starmism 94bf5fea57 POJO to help with checking that expansions have all required methods implemented. 2021-06-30 10:13:29 -06:00
Starmism 252802dcbe Removed nullcheck from hashcode, and moved it up the chain. 2021-06-30 10:13:12 -06:00
PiggyPiglet 8932a92049
Merge pull request #658 from PlaceholderAPI/1.17
Initial 1.17 Changes
2021-06-30 21:16:12 +08:00
Starmism 679ef90091 Re-add NotNull's
(cherry picked from commit 2bfd8e7e5e)
2021-06-30 05:59:57 -06:00
Star ac9b0c42b7 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 ccf4f59343)
2021-06-30 05:59:52 -06:00
Starmism 14d885392c Fix version checker to compare the individual semver numbers instead of combining it together.
(cherry picked from commit ef5cd9d376)
2021-06-30 05:59:45 -06:00
Starmism 0c102a1823 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 f5386d4ca5)
2021-06-30 05:59:33 -06:00
Starmism 4c968f012d Cleanup build.gradle
(cherry picked from commit 7750ba7033)
2021-06-30 05:59:22 -06:00
Andre_601 ba71486151
Merge pull request #655 from LOOHP/docs/wiki
Update InteractionVisualizer placeholders
2021-06-30 11:35:46 +02:00
LOOHP e1269d6c86 Update InteractionVisualizer placeholders 2021-06-30 13:48:22 +08:00
Andre_601 438a665b74
add render 2021-06-27 14:31:15 +02:00
PiggyPiglet 247a5cde8f
Merge pull request #623 from PlaceholderAPI/feature/621-build-jars-on-pr
Build jars on PR (Compile and build validation)
2021-06-26 11:51:00 +08:00
Andre_601 aa9ac65d02
Merge pull request #650 from SaltyAimbOtter/patch-1
update BetonQuest docs link
2021-06-25 23:34:36 +02:00
SaltyAimbOtter ba983f7fb3
update BetonQuest docs link 2021-06-25 23:23:04 +02:00
Andre_601 af268c4941
adoPt
I always make that mistake...
2021-06-25 16:33:27 +02:00
Andre_601 4c4b1602d9
Build against Java 8, 11 and 16 2021-06-25 16:32:45 +02:00
PiggyPiglet 8c69a164b8
Merge pull request #649 from Vshnv/patch/expansion-classloader
Fixed issue with expansions not being able to access their resources
2021-06-25 22:11:58 +08:00
Vaishnav Anil df8583df57 Close URLClassLoader if Expansion class was not found 2021-06-25 05:08:14 +05:30
Vaishnav Anil 09e68e7510 Extracted URLClassLoader out of try-with-resources block 2021-06-25 05:07:14 +05:30
Andre_601 2c223ffc87
Merge pull request #647 from cj89898/docs/wiki
Added 2.3.0 Checkitem changes
2021-06-20 18:38:27 +02:00
cj89898 5571ba5d70
Added 2.3.0 Checkitem changes 2021-06-20 10:49:28 -05:00
Andre_601 b77b1b9649
Update Placeholders.md 2021-06-17 14:49:16 +02:00
Andre_601 bf9b34eb57
Merge pull request #645 from stumper66/docs/wiki
LevelledMobs Wiki Addition
2021-06-17 14:45:07 +02:00
Penal Buffalo 215fd7e3f0
Update wiki/Placeholders.md
Co-authored-by: Andre_601 <11576465+Andre601@users.noreply.github.com>
2021-06-17 07:44:14 -05:00
stumper66 aca624c2d3 LevelledMobs
Added LevelledMobs info to the wiki
2021-06-17 07:26:07 -05:00
Andre_601 5826390251
Merge pull request #642 from garagepoort/feature/add_staffplusplus_wiki
Add staff++ to the wiki
2021-06-15 21:59:55 +02:00
David Maes a91a5c85ba Better phrasing 2021-06-15 21:57:47 +02:00
David Maes 156243a549 Add staff++ to the wiki 2021-06-15 21:52:32 +02:00
Andre_601 eceb236121
Merge pull request #640 from cj89898/docs/wiki
Update Placeholders.md
2021-06-11 11:43:03 +02:00
darbyjack 71b5433326
Initial 1.17 Changes 2021-06-11 01:33:29 -05:00
cj89898 2c8314200f
Update Placeholders.md
Added 2.2.0 checkitem placeholder
2021-06-10 21:52:36 -05:00
Andre_601 0b70ea61aa
Merge pull request #639 from darbyjack/docs/wiki
Added in some missing placeholders for Player Expansion
2021-06-09 16:00:38 +02:00
darbyjack ac31e107ad
Added in some missing placeholders 2021-06-09 08:58:49 -05:00
Andre_601 b9230ef9c5
Merge pull request #631 from broken1arrow/docs/wiki
Docs/wiki
2021-05-13 14:58:20 +02:00
broken1arrow 06e6765870 Try for the 10 times to make it right
See if this work better
2021-05-13 14:45:46 +02:00
broken1arrow 5ac579e878 Revert "Has change and add descriptions"
This reverts commit a4d8009ce4.
2021-05-13 14:41:33 +02:00
broken1arrow a4d8009ce4 Has change and add descriptions
Try other way and see if this work better to pull uppdates.
2021-05-12 17:19:05 +02:00
Andre_601 0df265881a
Add CalculateNumbers 2021-05-12 00:03:34 +02:00
Andre_601 5dbd58076a
Add %rng_online_player% 2021-05-08 14:17:19 +02:00
Andre_601 c3922de323
Update Commands.md 2021-05-07 23:45:29 +02:00
Andre_601 0f118f12bc
Merge pull request #626 from Lorenzo0111/patch-1
Update RocketPlaceholders documentation url
2021-05-04 17:12:15 +02:00
Lorenzo edd3153acd
Update documentation url 2021-05-04 16:24:18 +02:00
Andre_601 748b9f33f7
Build jars on PR (Compile and build validation) 2021-04-26 18:05:42 +02:00
Andre601 230e36c55e [Wiki] Add Lands 2021-04-23 00:08:00 +02:00
Andre_601 0f7294972e
Merge pull request #618 from PlaceholderAPI/feature/improve-placeholders-page
Redesign Placeholders page and other pages
2021-04-22 23:53:37 +02:00
Andre_601 d14f319eb4
Improve description of bug_report.yml 2021-04-21 14:30:46 +02:00
Andre_601 0927760d76
Merge pull request #619 from PlaceholderAPI/feature/remove-issue-body-field
Remove deprecated issue_body type
2021-04-21 14:25:40 +02:00
Andre_601 91af12f575
Update feature_request.yml 2021-04-21 14:24:40 +02:00
Andre_601 5dbbe01b95
Remove deprecated issue_body type 2021-04-21 14:24:14 +02:00
Andre601 30b5abda19 Fix wrong links 2021-04-20 23:30:43 +02:00
Andre601 a8e996fa26 Redesign Placeholders page and other pages 2021-04-20 23:21:24 +02:00
Andre_601 3f83312454
Merge pull request #616 from Warriorrrr/update-towny-placeholders
Update Towny placeholders
2021-04-18 03:23:41 +02:00
Warrior 0b1bd1c265 Forgot the dot. 2021-04-18 02:40:30 +02:00
Warrior b747720f36 Update towny placeholders 2021-04-18 02:33:40 +02:00
Andre_601 be34f28fd3
Merge pull request #615 from Hempfest/docs/wiki
Docs/wiki
2021-04-17 11:45:31 +02:00
Hempfest 9843d84ac3
Updated Clans Pro Listing.
New placeholders.
2021-04-17 02:43:19 -07:00
Andre_601 37de42f4a7
Merge pull request #613 from MysteriousKyle/docs/wiki
Addition of a plugin using PalaceholderAPI
2021-04-14 18:01:05 +02:00
Kyle 5595bc144f Addition of a plugin using PalaceholderAPI 2021-04-14 10:56:27 -05:00
Andre_601 9b2e7bb3ca
Merge pull request #611 from thienbao860/patch-2
Update placeholders, clear Spectator expansion
2021-04-13 18:23:16 +02:00
thienbao860 8b5ead7a13
Update placeholders, clear Spectator expansion 2021-04-13 23:18:39 +07:00
Andre_601 0c6dd5466c
Merge pull request #610 from PlaceholderAPI/fix/update-missing-copyright
Update Copyright
2021-04-13 17:59:21 +02:00
Andre601 41275509b2 Undo renaming of boolean 2021-04-13 17:58:42 +02:00
Andre601 4e8b1b47d1 Re-add removed code
That should actually NOT be here...
2021-04-13 17:57:59 +02:00
Andre601 d0e62e6434 Update Copyright
~ Fixed a typo and updated missed files from #543
2021-04-13 17:54:57 +02:00
Andre_601 2086fcb299
Merge pull request #583 from HSGamer/patch-1
should it use setBracketPlaceholders??
2021-04-13 17:20:59 +02:00
Andre_601 b3ea920b41
Merge pull request #608 from CMPSCjg/patch-1
Add 2 New TokensPlus Placeholders
2021-04-12 17:52:22 +02:00
CMPSCjg 001fa6bcf2
Add 2 New TokensPlus Placeholders 2021-04-12 11:49:16 -04:00
PiggyPiglet 3a31c5cb78
Merge pull request #485 from PlaceholderAPI/fix/477-remove-gson
Remove Gson
2021-04-12 21:40:55 +08:00
PiggyPiglet 20b2a69b5e
Merge pull request #558 from PlaceholderAPI/development
Sync Master branch with Development (Possible Release)
2021-04-12 21:35:32 +08:00
PiggyPiglet 682717660f
Merge pull request #546 from PlaceholderAPI/feature/add-sections
Add contributing and expansion section
2021-04-12 21:16:18 +08:00
PiggyPiglet 7b7bfb7306
Merge pull request #543 from ElijahRus250/master
2021 🥳
2021-04-12 21:13:38 +08:00
Andre_601 09043c6aaf
Merge pull request #607 from RobinDeBaets/patch-1
Add %statistic_mob_kills%
2021-04-10 17:24:03 +02:00
RobinDeBaets f711500d80
Add %statistic_mob_kills% 2021-04-10 17:01:54 +02:00
Andre_601 8d6aa7c801
Merge pull request #606 from Lorenzo0111/patch-1
Edit RocketPlaceholders on the wiki
2021-04-02 19:36:09 +02:00
Lorenzo 04968cb437
Update Plugins-using-PlaceholderAPI.md 2021-04-02 17:01:52 +02:00
Andre_601 048c539fff
Merge pull request #604 from Paul19988/docs/wiki
Add entry for Expansion "TeamsExpansion"
2021-03-31 17:28:49 +02:00
Andre_601 501d1bbbdd
Add minor corrections 2021-03-31 17:28:14 +02:00
Paul Baird e4a6faa22a
Corrected ecloud link for name change 2021-03-31 16:09:15 +01:00
Paul Baird c3bdc90168
Corrected entry and added ecloud command 2021-03-31 15:59:44 +01:00
Paul Baird 79ec3c8f95
Added TeamExpansion in correct place 2021-03-31 15:29:46 +01:00
Paul Baird e9e4caf989
Add TeamsExpansion placeholder expansion 2021-03-31 15:24:25 +01:00
Andre_601 0b1a3ced9e
Merge pull request #602 from matahombres/patch-3
Update advancements placeholder
2021-03-27 17:14:34 +01:00
matahombres b55261a62f
Update advancements placeholder 2021-03-27 17:06:25 +01:00
Andre_601 8c633c8943
Merge pull request #600 from LOOHP/docs/wiki
Add %interactivechat_invdisplaylayout% placeholder
2021-03-26 14:58:56 +01:00
LOOHP 8757217fb6 Add %interactivechat_invdisplaylayout% placeholder 2021-03-26 21:53:43 +08:00
Andre_601 8f796e3940
Add field for logs 2021-03-26 14:53:02 +01:00
Andre_601 bf1527a40f
Use id option for error and dump fields 2021-03-26 14:42:20 +01:00
Andre_601 a65de95b16
Merge pull request #599 from Alpha018/wiki_update
modify: Change wiki to use new placeholder
2021-03-25 07:11:49 +01:00
Alpha018 fb8572313e modify: Change wiki to use new placeholder 2021-03-25 03:07:49 -03:00
vk2gpz 2fc28777b7
added %vkautopickup_autosmelt% and %vkautopickup_autoblock% to VKAutoPickup. 2021-03-25 12:56:26 +11:00
Andre_601 ffd493fea9
Merge pull request #597 from CMPSCjg/patch-2
Add TokensPlus Placeholder
2021-03-24 21:37:32 +01:00
Andre_601 b207cbf03e
Add plugin to Plugins using PlaceholderAPI page 2021-03-24 21:37:06 +01:00
CMPSCjg 72239801d8
Update Placeholders.md 2021-03-24 16:19:33 -04:00
CMPSCjg 33ff83d102
Update wiki/Placeholders.md
My bad, thought I updated the URL to reflect this format.

Co-authored-by: Andre_601 <11576465+Andre601@users.noreply.github.com>
2021-03-24 16:16:04 -04:00
CMPSCjg 031625e241
Add TokensPlus Placeholder 2021-03-24 15:58:13 -04:00
Andre_601 ec127dbeb1
Merge pull request #595 from PlaceholderAPI/docs/wiki
Sync Development and docs/wiki
2021-03-24 09:17:58 +01:00
Andre_601 5d80119fcd
Merge pull request #594 from PlaceholderAPI/feature/wiki-add-vkautopickup
Add VKAutoPickup
2021-03-24 09:14:56 +01:00
Andre_601 f6c972c9a2
Add VKAutoPickup 2021-03-24 09:12:31 +01:00
Andre_601 a0b256c17d
Merge pull request #593 from lucko/patch-1
Update LuckPerms placeholders
2021-03-21 14:58:22 +01:00
lucko a66cae9a6b
Update LuckPerms placeholders 2021-03-21 13:52:58 +00:00
Andre_601 7f6122f8b8
Merge pull request #591 from ajgeiss0702/docs/wiki
Update ajParkour + add ajLeaderboards placeholders
2021-03-19 16:53:14 +01:00
ajgeiss0702 ee7257208a Update ajParkour + add ajLeaderboards 2021-03-19 08:47:51 -07:00
Andre_601 87ea46a4dd
Merge pull request #585 from PlaceholderAPI/fix/change-to-stringlist
Use lists and not comma-separated string
2021-03-11 22:09:05 +01:00
Andre_601 d221a3f38a
Update feature_request.yml 2021-03-11 22:08:51 +01:00
Andre_601 f62980606a
Use lists and not comma-separated string 2021-03-11 22:07:48 +01:00
Andre_601 c2ab9f5b85
Assign "Type: Issue (Unconfirmed)" label 2021-03-08 18:08:35 +01:00
Andre_601 2c925983a8
Merge pull request #584 from PlaceholderAPI/fix/issue-form-about-deprecation
Use description in favour of about
2021-03-08 18:07:02 +01:00
Andre_601 375e743124
Update bug_report.yml 2021-03-08 18:06:10 +01:00
Andre_601 78f76c8343
improve feature_request.md 2021-03-08 17:51:42 +01:00
Andre_601 33e4743e89
Use description in favour of about 2021-03-08 17:36:34 +01:00
Andre_601 b9b7104f6b
Merge pull request #580 from PlaceholderAPI/feature/use-new-issue-system
Start using new Issue template system
2021-03-08 17:34:02 +01:00
Andre_601 a45f420069
Check if deleting this fixed the PR... 2021-03-08 17:26:21 +01:00
Andre_601 a7d92f569f
Rename bug_report_new.yml to bug_report.yml 2021-03-08 16:12:25 +01:00
Andre_601 73f55735b4
Delete feature_request_old.md 2021-03-08 16:10:43 +01:00
Andre_601 a15c6b4855
Delete bug_report_old.md 2021-03-08 16:10:34 +01:00
Andre_601 48f7ffe089
disable default issue body 2021-03-08 15:59:52 +01:00
Andre_601 c607338003
Add checkboxes 2021-03-08 15:56:26 +01:00
Andre_601 66a7a6d199
Add Checkboxes 2021-03-08 15:53:04 +01:00
Andre_601 1d7bf239ea
Update feature_request_old.md 2021-03-08 15:44:41 +01:00
Andre_601 43a5db7711
fix unique name 2021-03-08 15:44:10 +01:00
Huynh Tien 0e56ea9503
should it use setBracketPlaceholders?? 2021-03-06 20:37:43 +07:00
Andre_601 d640d801e6
Create feature_request.yml 2021-02-28 11:00:23 +01:00
Andre_601 b5c70dedcb
Rename feature_request.md to feature_request_old.md 2021-02-28 10:48:06 +01:00
Andre_601 a8bcf0e14d
Create bug_report.yml 2021-02-28 10:41:15 +01:00
Andre_601 0c13004040
Start using new Issue template system 2021-02-28 10:05:16 +01:00
Andre_601 cc05a3508b
Merge pull request #579 from LOOHP/docs/wiki
Adds and updates InteractiveChat, InteractionVisualizer and HoloMobHealth on the wiki
2021-02-28 07:56:43 +01:00
LOOHP 458030c575 Added HoloMobHealth 2021-02-28 14:50:38 +08:00
LOOHP 3b4641c26c Added InteractiveChat, Updated InteractionVisualizer 2021-02-28 14:41:13 +08:00
Andre_601 9b03af17b6
Merge pull request #576 from matahombres/patch-2
Added more placeholders to wiki
2021-02-18 19:25:00 +01:00
matahombres 72b2be4933
Added more placeholders to wiki
Add more advancements placeholders
2021-02-18 18:47:14 +01:00
Andre_601 2f0f717d44
Update formatter expansion list 2021-02-17 17:15:59 +01:00
Andre_601 e3bef564f2
Merge pull request #574 from Kqliber/patch-1
Added extra placeholders to wiki
2021-02-15 23:04:27 +01:00
Kqliber 319be0e043
Added extra placeholders
Added the RNG expansion 
Updated the chat reaction placeholders list
2021-02-15 21:54:44 +00:00
Andre_601 431483da89
Merge pull request #571 from Hempfest/master
PR to correct branch.
2021-02-14 17:57:04 +01:00
Hempfest d07376245c
minor edits 2021-02-14 08:37:00 -08:00
Hempfest 2aa6ac2b63
minor edit 2021-02-14 08:35:09 -08:00
Hempfest 03a362817c
Updated my plugin listings.
Updated listing for Clans [Free] and Clans [Pro] Listings. Both plugins are utilizing the API and are available on spigot as i type this.
2021-02-14 06:32:15 -08:00
Hempfest 2dc972423a
Updated listings for both of my plugins
Updated listing for Clans [Free] and Clans [Pro] Listings. Both plugins are utilizing the API and are available on spigot as i type this.
2021-02-14 06:30:38 -08:00
Andre_601 4b43d35bcc
Merge pull request #567 from ArVdC/docs/wiki
Add TimeManager placeholders
2021-02-13 21:36:54 +01:00
ArVdC 350ec10186
Update Plugins-using-PlaceholderAPI.md 2021-02-13 21:14:21 +01:00
ArVdC 0104e48b72
Update Placeholders.md 2021-02-13 21:13:43 +01:00
Andre_601 a88f7aab30
Merge pull request #562 from HappyRogelio7/patch-2
Update Placeholders.md
2021-02-10 22:48:51 +01:00
Andre_601 e91ed337cc
Merge pull request #563 from HappyRogelio7/patch-3
Update Plugins-using-PlaceholderAPI.md
2021-02-10 22:48:28 +01:00
HappyRogelio7 32d5b7697d
Update Plugins-using-PlaceholderAPI.md 2021-02-10 13:21:43 -03:00
HappyRogelio7 c23d35d219
Update Placeholders.md 2021-02-10 13:18:31 -03:00
Andre_601 6b04b6c39b
Use pull_request_target 2021-02-10 15:29:33 +01:00
Andre_601 021d5b1f47
Update label-commenter-config.yml 2021-02-10 15:29:03 +01:00
Andre_601 b0f14c6e4e
Merge pull request #559 from RoinujNosde/docs/wiki
Update Placeholders.md
2021-02-10 01:34:47 +01:00
Edson Passos cd3a0f52d5
Update Placeholders.md
Changes SimpleClans' resource page link
Adds link to wiki page listing placeholders
2021-02-09 19:41:36 -03:00
Andre_601 cc5835423f
Improve Wiki Readme 2021-02-09 04:46:18 +01:00
Andre_601 155fc0592a
Branch is actually called development 2021-02-09 04:01:29 +01:00
Andre_601 a163c72e93
Update Placeholders.md 2021-02-04 18:09:44 +01:00
Andre_601 562f6a852d
Add Shortcut expansion 2021-02-04 15:02:35 +01:00
Andre_601 bfb88781af
Improve placeholder pattern and info 2021-02-04 14:59:14 +01:00
Andre_601 ff4656bbe7
Update formatter placeholders 2021-02-02 22:17:32 +01:00
Andre_601 c44b08e2e9
Merge pull request #553 from SrBedrock/patch-1
Update GriefPrevention Expansion
2021-01-31 22:35:10 +01:00
ThiagoROX 4d14b583ff
Update GriefPrevention Expansion
Add %griefprevention_bonusclaims_formatted% from GriefPrevention Expansion version 1.5.2
2021-01-31 18:30:13 -03:00
Andre_601 892f0727e8
Fix invalid link tag 2021-01-29 03:29:35 +01:00
PiggyPiglet 3635ecb8b4
Merge pull request #528 from PlaceholderAPI/feature/add-faq-entry
Update FAQ
2021-01-29 10:11:19 +08:00
PiggyPiglet dd2981b13e
Merge pull request #443 from PlaceholderAPI/feature/update-documentation
Update Javadoc documentation
2021-01-29 10:10:12 +08:00
Andre_601 ff60343089
Add contributing and expansion section 2021-01-24 17:47:03 +01:00
Andre_601 fb77c42bba
Brag a bit more about this 2021-01-24 17:35:30 +01:00
Andre_601 a65b9ad49e
Merge pull request #545 from eggsy/master
🔧 update wrong (time_played) statistic types on wiki
2021-01-24 15:23:28 +01:00
EGGSY 0ed32c7ddd 🔧 update wrong statistic types 2021-01-24 15:15:44 +03:00
Andre601 f1350783fc Use repo links 2021-01-21 01:58:44 +01:00
Andre601 5ac2efd9c6 Trying out img folder in wiki 2021-01-21 01:54:34 +01:00
ElijahRus250 a7247acbb3 2021 🥳 2021-01-20 15:29:13 -05:00
Andre_601 0b3663ee87
Merge pull request #542 from cj89898/docs/wiki
Updated deluxemenus on wiki
2021-01-20 16:04:28 +01:00
cj89898 ba9b38dd0e
Update Plugins-using-PlaceholderAPI.md
Updated deluxemenus to providing placeholders
2021-01-20 08:58:59 -06:00
cj89898 62bb68ee94
Update Placeholders.md
Added deluxemenus
2021-01-20 08:57:39 -06:00
Andre_601 e96c6fb7ef
Merge pull request #540 from steve4744/docs/wiki
update parkour placeholders
2021-01-19 02:07:15 +01:00
BuildTools c04c101de5 update parkour placeholders 2021-01-19 00:19:36 +00:00
Andre_601 5ab2c05821
Merge pull request #539 from LeonMangler/patch-1
Update PremiumVanish placeholders
2021-01-18 22:25:42 +01:00
Leon Mangler 9b9e0e4b9e
Update PremiumVanish placeholders 2021-01-18 22:00:02 +01:00
Andre_601 c3ee5bbdc0
Actually was renamed too 2021-01-11 22:28:32 +01:00
Andre_601 fb70ba6403
Update invalid link 2021-01-11 22:22:34 +01:00
Andre_601 f605db479b
Improve message 2021-01-11 22:16:39 +01:00
Andre_601 175308ecf5
Merge pull request #533 from granny/docs/wiki
DiscordSRV placeholders are now integrated in DiscordSRV
2021-01-07 23:39:04 +01:00
granny 2adf2845fd DiscordSRV placeholders are now integrated in DiscordSRV 2021-01-07 14:04:27 -08:00
Andre_601 0438c67f7d
Markdown rendering 2021-01-06 17:33:24 +01:00
Andre_601 47d6928b9f
Mention headers 2021-01-06 17:30:14 +01:00
Andre_601 deee5a1c39
Use new message 2021-01-06 17:09:08 +01:00
Andre_601 c9492564e0
Mention Discussion entry 2021-01-06 16:42:32 +01:00
Andre_601 0c826a288e
Link to the wiki folder 2021-01-06 14:40:33 +01:00
PiggyPiglet 093ba4d68c
Merge pull request #530 from PlaceholderAPI/fix/515-proper-expansion-null-checks
Fix contract violations & add null checks which should close #515
2021-01-04 10:25:48 +08:00
PiggyPiglet 1478aabb5e
remove an from log message
Co-authored-by: Andre_601 <11576465+Andre601@users.noreply.github.com>
2021-01-04 10:25:38 +08:00
PiggyPiglet 07ac8e41c5 Fix contract violations & add null checks which should close #515 2021-01-03 23:42:23 +08:00
PiggyPiglet f0dccbd594 update gradle 2021-01-03 23:35:37 +08:00
PiggyPiglet 26fdedd989
Merge pull request #529 from PlaceholderAPI/fix/527-improve-parse-command
Fix resolvePlayer method
2021-01-03 23:28:52 +08:00
PiggyPiglet d342c73f24
Merge pull request #517 from PlaceholderAPI/fix/515-improve-logging
Fixing issues for logging when Expansion doesn't contain any classes.
2021-01-03 22:40:20 +08:00
Andre601 0a52ef7219 Use a generic log message for this 2021-01-03 15:38:10 +01:00
Andre601 6a69ec833f Use getPlayerExact 2021-01-01 18:19:07 +01:00
Andre_601 b540127651
Add a little © 2020-12-31 22:12:51 +01:00
Andre601 8fa0f73a46 Fix resolvePlayer method 2020-12-31 18:20:11 +01:00
Andre_601 077a221c3f
Update FAQ.md 2020-12-31 15:12:09 +01:00
Andre_601 301a1c9ac5
Merge pull request #526 from cj89898/docs/wiki
Update Placeholders.md
2020-12-30 11:51:36 +01:00
cj89898 0db15f96ae
Update Placeholders.md 2020-12-29 20:17:44 -06:00
Andre_601 9b2ea05875
Improve ExpansionsLoadedEvent's docs 2020-12-29 21:12:22 +01:00
Andre_601 27d8ae03e1
fix wrong var name 2020-12-29 18:54:39 +01:00
Andre_601 15e22ea115
Merge pull request #525 from Harieo/docs/wiki
Adds seasons plugin to Wiki
2020-12-29 18:31:54 +01:00
Harieo f398854c68 Added extra square brackets to match other links in Plugins-using-PlaceholderAPI.md 2020-12-29 16:57:12 +00:00
Harieo 29446c08b6 Reverted previous commit 2020-12-29 16:51:36 +00:00
Harieo 3d44f8ffdc Changed wiki.yml workflow to generate personal Wiki page 2020-12-29 16:48:29 +00:00
Harieo 61afb24d33 Added the Seasons plugin as a plugin using PlaceholderAPI 2020-12-29 16:42:32 +00:00
Andre_601 e8b5660eda
Use invalid on PR too 2020-12-28 22:17:01 +01:00
Andre_601 d4744838ee
Merge pull request #522 from PlaceholderAPI/master
Update docs/wiki from master
2020-12-28 22:12:50 +01:00
Andre_601 32f3e21ab7
Merge pull request #521 from weihao/docs/wiki
Added Ath wiki to docs branch
2020-12-28 22:11:48 +01:00
Weihao e6d57f81da
Update wiki/Placeholders.md
Co-authored-by: Andre_601 <11576465+Andre601@users.noreply.github.com>
2020-12-28 16:10:53 -05:00
Weihao 818bf91c93 Merge branch 'docs/wiki' of https://github.com/weihao/PlaceholderAPI into docs/wiki 2020-12-28 16:10:24 -05:00
Weihao ac2c2b324e Improvements 2020-12-28 16:10:10 -05:00
Weihao cf9d07a856
Update wiki/Plugins-using-PlaceholderAPI.md
Co-authored-by: Andre_601 <11576465+Andre601@users.noreply.github.com>
2020-12-28 16:08:19 -05:00
Weihao 860239fa2b Added Ath 2020-12-28 15:50:55 -05:00
Andre_601 69f0ede0c6
Also check for PRs 2020-12-28 21:45:54 +01:00
Andre_601 480f13a3ce
Now this should work 2020-12-28 15:46:06 +01:00
Andre601 b99335e5b2 First step at fixing #515 and for #516 2020-12-27 18:47:48 +01:00
Andre_601 e83eba9226
fix missing linebreak 2020-12-27 18:33:20 +01:00
Andre_601 278a5a4096
mention paste url 2020-12-27 14:12:01 +01:00
Andre_601 1cfa247f8c
Seems to not work as intended 2020-12-26 23:32:12 +01:00
Andre_601 a3b2777d16
Merge branch 'master' into feature/update-documentation 2020-12-26 23:01:03 +01:00
Andre_601 3c9f6ea520
Only work on non-closed issues 2020-12-25 15:09:25 +01:00
Andre_601 15d2452b19
Merge pull request #514 from steve4744/docs/wiki
update parkour and tntrun_reloaded placeholders
2020-12-23 00:19:01 +01:00
BuildTools f582474fb1 update parkour and tntrun_reloaded placeholders 2020-12-22 23:10:58 +00:00
BuildTools b1662676f1 update parkour and tntrun_reloaded placeholders 2020-12-22 23:01:45 +00:00
PiggyPiglet 23943f41ad
Merge pull request #513 from PlaceholderAPI/dont-fail-on-error
Javadoc Changes
2020-12-14 09:01:40 +08:00
darbyjack 3cd665a159
Javadoc Changes
- Don't fail on error
- Add license to new files that were merged
2020-12-13 18:58:55 -06:00
PiggyPiglet 4074192c0b
Merge pull request #512 from PlaceholderAPI/fix/javadoc-build-errors
Fix Javadoc build errors
2020-12-14 08:54:27 +08:00
Andre601 59cd5982ad Complete fix 2020-12-14 01:52:46 +01:00
Andre601 b3893c38db Hopefully fixing all the JD issues 2020-12-14 01:31:40 +01:00
PiggyPiglet a3d6426084
Merge pull request #473 from PlaceholderAPI/fix/469
Fix wrong expansion get in /papi info
2020-12-14 08:09:24 +08:00
Andre_601 30a194c75d
Update PlaceholderAPI.java 2020-12-14 01:08:40 +01:00
Glare 6431bcdeca
Merge pull request #460 from ignissak/444-add-expansionsLoadEvent 2020-12-13 18:07:24 -06:00
PiggyPiglet 0d1978cece
Merge pull request #454 from PlaceholderAPI/feature/add-getBoolean
Add missing getBoolean method
2020-12-14 08:04:49 +08:00
Andre_601 e7e9e81e85
Update VersionSpecific.java 2020-12-14 01:04:07 +01:00
Andre_601 ba22201311
Fix Javadoc build errors 2020-12-14 01:02:01 +01:00
PiggyPiglet f799835dd0
Merge pull request #429 from MrIvanPlays/patch/gradle-improvements
Attach sources and javadoc jar when deploying
2020-12-14 07:58:07 +08:00
PiggyPiglet 6f3dcf04fe
Merge pull request #407 from PlaceholderAPI/change/update-contributing
Update Contributing file
2020-12-14 07:56:36 +08:00
Andre_601 6b03c38e40
Update label commenter action 2020-12-13 17:21:52 +01:00
Andre_601 f756fbb43b
Update label-commenter-config.yml 2020-12-13 17:21:18 +01:00
Andre_601 f84702e3b2
Merge pull request #508 from PlaceholderAPI/feature/mention-github-discussions
Mention GitHub Discussions in Template chooser
2020-12-10 17:36:12 +01:00
Andre_601 9c750f50a2
Add Type:Question label 2020-12-09 18:10:19 +01:00
Andre_601 dcca454bad
Mention GitHub Discussions in Template chooser
Adds a link to the new [GitHub Discussions page](https://github.com/PlaceholderAPI/PlaceholderAPI/discussions) of this Repository.
2020-12-09 13:10:11 +01:00
BlitzGamer-88 ffef826c94
Merge pull request #503 from rbluer/patch-1
Adding Prison placeholders
2020-11-28 09:43:11 +02:00
RbR 15e0a293eb
Update Placeholders.md 2020-11-27 20:29:35 -05:00
RbR 11ed822845
Update Placeholders.md
Update the descriptions.
2020-11-27 20:25:37 -05:00
RbR 1e4af86172
Update Plugins-using-PlaceholderAPI.md
Added entry for Prison plugin.
2020-11-27 19:10:32 -05:00
RbR 5f9dffc3c7
Update Placeholders.md
Added the current placeholders for the Prison plugin.
2020-11-27 03:58:58 -05:00
Andre_601 93e83efb57
Rename label 2020-11-15 15:47:37 +01:00
Andre_601 0d9485ddec
Add action for inactive issues. 2020-11-15 15:45:49 +01:00
Andre_601 1248010566
Merge pull request #501 from Lauriichan/docs/wiki
Added RealisticWorldGenerator to Plugin Placeholders sections in wiki
2020-11-05 12:22:23 +01:00
Laura Endreß d68fe7067c
Update Plugins-using-PlaceholderAPI.md 2020-11-05 11:38:22 +01:00
Laura Endreß e16497618c
Update Placeholders.md 2020-11-05 11:36:38 +01:00
PiggyPiglet 4cfd419565
Merge pull request #500 from PlaceholderAPI/1.16.4
Compile under 1.16.4 + add new NMS support
2020-11-03 21:19:48 +08:00
darbyjack f52bdbc458
Compile under 1.16.4 + add new NMS support 2020-11-02 14:35:55 -06:00
Andre_601 433dd7020c
Merge pull request #499 from steve4744/docs/wiki
update tntrun_reloaded placeholders
2020-10-29 13:24:39 +01:00
BuildTools 4fef2dd82a update tntrun_reloaded placeholders 2020-10-29 12:21:19 +00:00
Andre_601 1e6fb502a6
Improve some text 2020-10-22 00:54:43 +02:00
Andre_601 b56ab1408e
Merge pull request #493 from N0tMyFaultOG/docs/wiki
Update PlotSquared placeholders
2020-10-15 19:39:01 +02:00
NotMyFault 5dae844181
Update PlotSquared placeholders 2020-10-15 19:27:46 +02:00
Andre_601 329b46c042
Merge pull request #491 from steve4744/docs/wiki
Update Placeholders.md for Parkour
2020-10-08 12:45:31 +02:00
steve4744 e2dd16cf1c
Update Placeholders.md 2020-10-08 10:56:35 +01:00
Andre_601 dc244849a1
Merge pull request #488 from PlaceholderAPI/change/improve-wiki-faq
Improve Wiki FAQ
2020-10-06 13:33:05 +02:00
Andre_601 736de5b633
Update FAQ.md 2020-10-02 11:58:38 +02:00
PiggyPiglet b31767ba4a
Merge pull request #487 from GiansCode/patch-1
Update README
2020-09-28 23:25:04 +08:00
Gianluca Falcomer ae06fcd807
Update README 2020-09-28 17:23:25 +02:00
Andre_601 7108ffbb31
Update Placeholders.md 2020-09-27 15:36:57 +02:00
Andre_601 7a6b6d7ce4
Merge pull request #486 from thienbao860/patch-1
Expansion name shorten request
2020-09-27 15:35:36 +02:00
thienbao860 549a30b502
Update Placeholders.md 2020-09-27 20:05:55 +07:00
darbyjack c64946173b
Implemented working version for 1.8.8 - 1.16.3 2020-09-25 19:08:56 -05:00
Andre_601 5bca9dc41f
Remove Gson 2020-09-24 22:31:26 +02:00
Andre_601 5c830d7102
Merge pull request #484 from PlaceholderAPI/feature/481-add-plugins
Add plugins to wiki
2020-09-24 17:15:21 +02:00
Andre_601 400c0d5b5d
Add plugins
- https://www.spigotmc.org/resources/83879/
- https://www.spigotmc.org/resources/67551/
- https://www.spigotmc.org/resources/68968/
- https://www.spigotmc.org/resources/21692/
2020-09-24 17:15:07 +02:00
Andre_601 c53d5b2abf
Add Boxing and TicketsGUI
- https://www.spigotmc.org/resources/83879/
- https://www.spigotmc.org/resources/68968/
2020-09-24 17:06:22 +02:00
Andre_601 a842095fff
Merge pull request #483 from PlaceholderAPI/fix/update-broken-links
Fix broken wiki links
2020-09-24 16:56:00 +02:00
Andre_601 c6e36fec2c
Fix broken wiki links 2020-09-24 16:55:22 +02:00
Andre_601 fa7eeb5852
Add AlonsoLevels 2020-09-24 16:51:24 +02:00
Andre_601 b6bfe3f3ef
Add AlonsoLevels 2020-09-24 16:49:10 +02:00
Andre_601 d6cfc8beae
Merge pull request #475 from stijnb1234/docs/wiki
Updated ThemePark
2020-09-13 21:58:26 +02:00
Stijn Bannink 83c35ced32
Moved to command 2020-09-13 21:57:11 +02:00
Andre_601 b9bdb3167a
Fix outdated Info 2020-09-13 21:48:02 +02:00
Stijn Bannink dfec6c4c8b
Updated ThemePark
v1.2 is live.
2020-09-13 19:19:04 +02:00
Andre_601 35838aa229
Fix wrong expansion get in /papi info 2020-09-13 00:30:27 +02:00
Andre_601 ee0df86f84
Merge pull request #472 from PlaceholderAPI/feature/470-add-BetonQuest
Add BetonQuest
2020-09-13 00:24:58 +02:00
Andre601 0650de95d6 Add BetonQuest 2020-09-13 00:22:51 +02:00
Andre_601 279f1d0c07
Merge pull request #471 from PlaceholderAPI/feature/468-add-SimpleCoins
Add SimpleCoins to wiki
2020-09-13 00:21:40 +02:00
Andre_601 5a8738e711
Remove useless empty line 2020-09-13 00:21:26 +02:00
Andre601 00b95461b6 Add SimpleCoins to the wiki 2020-09-13 00:11:52 +02:00
Andre_601 a74f78bd73
Update placeholders 2020-09-12 22:05:06 +02:00
Andre_601 9d35f4c3e6
Fix issue commenter 2020-09-12 22:02:25 +02:00
darbyjack 325cd2d284
Added support for 1.16.2 NMS changes 2020-09-06 16:39:15 -05:00
Andre_601 d4f0eb91ef
Merge pull request #466 from xknat/patch-1
Added SkinsRestorerPlaceholders
2020-09-06 22:37:15 +02:00
xknat 5ab228d1d8
Added SkinsRestorerPlaceholders 2020-09-06 21:30:12 +02:00
xknat 64e0f7e500
Added SkinsRestorerPlaceholders 2020-09-06 21:29:03 +02:00
xknat 7998d4d666
Add SkinsRestorerPlaceholders 2020-09-06 21:27:00 +02:00
xknat 2a91d34a65
Added SkinsRestorerPlaceholders 2020-09-06 21:25:06 +02:00
xknat ac717c7600
Added SkinsRestorerPlaceholsers 2020-09-06 21:18:26 +02:00
Andre_601 e13b91cb22
Merge pull request #465 from svenar-nl/docs/wiki
Docs/wiki
2020-09-05 00:53:33 +02:00
Sven Arends fdfca9da42
Update Plugins-using-PlaceholderAPI.md
Updated PowerRanks information
2020-09-05 00:49:21 +02:00
Sven Arends 1556e15a1a
Update Placeholders.md
Updated PowerRanks Placeholders
2020-09-05 00:48:42 +02:00
Andre_601 7691dd93ad
Add and improve responses 2020-09-02 12:08:50 +02:00
Jacob Bordas 2c13acfd30
Changes regarding review by Andre
Signed-off-by: Jacob Bordas <methalicity@gmail.com>
2020-09-01 01:31:52 +02:00
Andre_601 40f1fcbce2
Merge pull request #461 from Bimmr/docs/wiki
Updated McInfected Placeholders
2020-08-31 22:01:50 +02:00
Randy 456958d647
Updated McInfected Placeholders 2020-08-31 13:33:21 -04:00
Jacob Bordas 7c404db56b
Added event when all expansions are loaded for developers. 2020-08-31 13:32:11 +02:00
Andre_601 18cfd438b8
Update .github/CONTRIBUTING.md
Co-authored-by: PiggyPiglet <PiggyPiglet@users.noreply.github.com>
2020-08-31 03:00:24 +02:00
Andre_601 d5e27252cf
Fix wrong link 2020-08-31 02:52:16 +02:00
Andre_601 3fe0f0143c
Add note about wiki PRs 2020-08-31 02:50:30 +02:00
Andre_601 61a71b9e73
Add info about target branch. 2020-08-31 02:50:08 +02:00
Andre_601 e542dabd52
Merge pull request #459 from fredthedoggy/patch-1
Update BentoBox Placeholders
2020-08-31 02:46:10 +02:00
fredthedoggy 9cde086436
Update BentoBox Placeholders
Update the out of date BentoBox placeholders
2020-08-30 20:32:51 -04:00
Andre_601 fe02939466
Add missing getBoolean method 2020-08-28 15:16:03 +02:00
Andre_601 f1c2315055
Add missing line 2020-08-28 14:53:50 +02:00
Andre_601 9681c518fc
Merge pull request #453 from PlaceholderAPI/feature/451-add-streaming-drops
Add Streaming Drops (#451)
2020-08-28 14:51:02 +02:00
Andre_601 762bb409d3
Add Streaming Drop
https://www.spigotmc.org/resources/76996/
2020-08-28 14:50:48 +02:00
Andre_601 0394ba284b
Add Streaming Drops (#451) 2020-08-28 14:46:57 +02:00
Andre_601 3e9dcdb53c
Merge pull request #447 from steve4744/master
Update placeholders for tntrun_reloaded and parkour
2020-08-23 22:24:50 +02:00
BuildTools ddfaf4105d update placeholders for parkour 2020-08-23 17:44:23 +01:00
BuildTools 5b1df7c42a update placeholders for tntrun_reloaded 2020-08-23 17:27:55 +01:00
Andre_601 7555bb0f97
Update .github/CONTRIBUTING.md
Co-authored-by: PiggyPiglet <PiggyPiglet@users.noreply.github.com>
2020-08-19 16:27:48 +02:00
Andre601 ab96120911 More comments... a lot more! 2020-08-18 23:15:23 +02:00
Andre_601 7371a576d6
Update Javadoc documentation 2020-08-18 18:37:44 +02:00
Andre_601 5d5ceb5902
Merge pull request #439 from Lorenzo0111/patch-1
Added RocketPlaceholsers
2020-08-13 14:45:43 +02:00
Andre_601 125d02fecd
Add missing link 2020-08-13 14:45:02 +02:00
Andre_601 8c98a214f8
Add RocketPlaceholders
https://www.spigotmc.org/resources/82678/
2020-08-13 14:44:11 +02:00
Lorenzo 2a3e8dcec1
Added RocketPlaceholsers
Added RocketPlaceholsers which provides their own placeholders.  The placeholders are customizable from the config.
2020-08-13 10:10:17 +02:00
Andre_601 a996d9039e
Merge pull request #437 from PlaceholderAPI/feature/label-commenter
Adding Label commenter
2020-08-12 23:17:39 +02:00
Andre_601 cfba92bf14
Add missing info about automated response. 2020-08-12 15:26:40 +02:00
Andre_601 41f408226e
Update label-commenter-config.yml 2020-08-12 15:20:40 +02:00
Andre_601 58cfa92136
Add label-commenter-config.yml 2020-08-12 15:11:21 +02:00
Andre_601 f3309b76d1
Adding Label commenter 2020-08-12 14:58:04 +02:00
Andre_601 04bfa1e721
Update formatter placeholders 2020-08-12 13:48:31 +02:00
Andre_601 dc894c6212
Merge pull request #434 from PlaceholderAPI/master
Update docs/wiki from master
2020-08-10 22:30:00 +02:00
Andre_601 7c7025fdbb
Merge pull request #433 from RobinDeBaets/master
Fix Statistic download information
2020-08-10 22:27:42 +02:00
RobinDeBaets 97a4eca0a7
Add back Statistic link 2020-08-10 22:24:06 +02:00
RobinDeBaets 5e4110b1b3
Remove outdated Statistic information 2020-08-10 22:22:53 +02:00
Andre_601 d1e3047445
Update CONTRIBUTING.md 2020-08-10 21:29:42 +02:00
Andre_601 c72515912d
Add RocketJoin
https://www.spigotmc.org/resources/82520/
2020-08-10 21:21:48 +02:00
MrIvanPlays eb5a93dce2
Attach sources and javadoc jar when deploying 2020-08-09 10:22:21 +03:00
Andre_601 7cb3b3b7ec
Add missing expansions 2020-08-08 18:35:36 +02:00
Ivan Pekov c648d6a541
Fix trailing/leading space after placeholder once and for all (#427) 2020-08-06 14:45:27 -04:00
extendedclip 2d72e274e3 account for empty strings 2020-08-06 14:08:48 -04:00
extendedclip b73d00e169 bstats might have an issue? 2020-08-06 14:05:33 -04:00
Ivan Pekov 5065623ab0
Attempt at fixing 413 (#422)
* Attempt at fixing 413

This is my (miserable) attempt at fixing #413
These changes basically fix some potential threading issues and (probably) #413
Local tests went fine for me, but more tests are required.

* Remove delay, fixed -> cached thread pool
2020-08-06 13:54:35 -04:00
Federico López 8698449e5d
Refactorization of the TimeUtil utility class (#423)
* Refactored `TimeUtil` utility class.

* Minimized `TimeUtil#getRemaining`.
* Fixed a bug regarding how days and hours were calculated in `TimeUtil#getTime`.
* Ditched the use of `int`s and use `long`s instead.

* Implemented `int`-taking methods because my dumb ass didn't think it would break.
2020-08-06 13:43:14 -04:00
extendedclip 722e987b93 Dont trim 2020-08-06 13:27:58 -04:00
extendedclip a00cbf4be3 trim whitespaces 2020-08-06 11:44:34 -04:00
Andre_601 f235c60bef
Update World placeholders 2020-08-06 13:48:58 +02:00
extendedclip a1d69cd25f Remove hashcode method 2020-08-05 11:53:06 -04:00
extendedclip f7504b99ca Add registerExpansion and unregisterExpansion back 2020-08-05 11:45:58 -04:00
extendedclip 02669e2435 Set builds to 2.10.10-dev 2020-08-04 12:47:05 -04:00
Andre_601 3e6d10e203
Fix formatting 2020-08-04 16:10:51 +02:00
Andre_601 f828857ce3
Add BuyCraft
https://www.spigotmc.org/resources/82261/
2020-08-04 16:09:31 +02:00
Andre_601 ec9d6295fb
on their? Sounds better imo 2020-08-03 16:56:58 +02:00
Andre_601 19a80c2d26
Do some changes 2020-08-03 16:51:46 +02:00
Andre_601 e3d71843ac
Fix typos and more info 2020-08-03 13:41:35 +02:00
Andre_601 c2dc51c728
fix typo 2020-08-01 15:09:22 +02:00
Andre_601 cc02c126b5
Merge pull request #410 from PlaceholderAPI/master
Update wiki branch
2020-07-31 19:33:46 +02:00
Andre_601 b4a914314a
Update _Footer 2020-07-31 18:07:53 +02:00
Andre_601 f6ba24e46f
& instead of ? 2020-07-31 18:07:00 +02:00
Andre_601 745f7926a6
Fix label 2020-07-31 18:06:28 +02:00
Andre_601 62c93465f2
Update PlaceholderExpansion.md 2020-07-31 18:03:51 +02:00
Andre_601 c76baeae1c
Update CONTRIBUTING.md 2020-07-31 16:02:20 +02:00
Andre_601 d12c746630
Improve content 2020-07-31 16:00:35 +02:00
Andre_601 fbdd789dbe
Create CODE_OF_CONDUCT.md 2020-07-31 15:26:33 +02:00
Andre_601 b521fe4a1f
Update Contributing file 2020-07-31 15:24:07 +02:00
Andre_601 b24b127ad5
Merge pull request #406 from PlaceholderAPI/master
Trigger on docs/wiki branch
2020-07-31 14:51:15 +02:00
96 changed files with 2228 additions and 8900 deletions

4
.github/CODEOWNERS vendored
View File

@ -1,9 +1,9 @@
#
# Assigns extendedclip and PiggyPiglet for any PR unless a check below matches.
#
* @extendedclip @PiggyPiglet
* @PiggyPiglet @darbyjack
#
# Assigns Andre601 to any PR that targets the wiki folder.
#
/wiki/ @Andre601
*.md @Andre601

View File

@ -1,64 +1,67 @@
[issue]: https://github.com/PlaceholderAPI/PlaceholderAPI/issues/new?template=change_request_placeholderapi.md
[Discord]: https://helpch.at/discord
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/
[issue]: https://github.com/PlaceholderAPI/PlaceholderAPI/issues/new
[discord]: https://helpch.at/discord
[code of conduct]: https://github.com/PlaceholderAPI/PlaceholderAPI/blob/master/CODE_OF_CONDUCT.md
[wiki]: https://github.com/PlaceholderAPI/PlaceholderAPI/blob/wiki
[master]: https://github.com/PlaceholderAPI/PlaceholderAPI/tree/master
[docs-wiki]: https://github.com/PlaceholderAPI/PlaceholderAPI/tree/docs/wiki
[style]: https://github.com/PlaceholderAPI/PlaceholderAPI/tree/master/config/style
# Contributing
# Contributing Guidelines
We welcome everyone to contribute towards the PlaceholderAPI Project, but doing so will require you to follow specific rules to keep a consistent and welcoming way of contributing.
When contributing to this repository, please first discuss the change you wish to make via [issue] or through [Discord] with the owners of this repository before making a change.
If you have any questions about contributions towards the project, feel free to contact us on our [Discord Server][discord].
Please note we have a code of conduct, please follow it in all your interactions with the project.
## Issues
Like any other project can you encounter bugs or a feature is missing for you in the plugin.
For that, you can open an [issue] to report a bug, or suggest a new feature to be added.
## Pull Request Process
When doing so, make sure you follow rules below:
1. Update the README.md with details of changes if it is affected by those changes.
2. Try to prevent any breaking changes affecting the end-user (Developers using the API).
Mention any breaking changes that could affect the end-user.
3. Document any public methods that the end-user might use.
### Follow the template
We have issue templates to help us get the required information more easily. Please follow the provided template when either filing a bug report or feature request.
Your issue may be closed without warning for not following the template.
### Use the latest version
When it comes to bug reports should you always check first, that you're using the latest release of PlaceholderAPI.
Often the bug you've encountered, is fixed in a newer version.
The same rules apply when making a feature request.
### No duplicate issue
Make sure that there aren't any existing issues relating to the problem, which are still open, or are closed with a solution/explanation.
Opening a separate issue for a bug report or feature request, that already exists on the issue tracker only slows down the process of fixing the bug or implementing the feature.
If an issue with the bug or feature you want to report/suggest exists, comment on it with your info (bug reports) or give it a :thumbsup: (Feature Request) to show that this is important for you.
### Issue isn't caused by external source
PlaceholderAPI provides a feature to have expansions (separate jar files) for placeholders. This gives it a possability that an issue you encounter is caused by said expansions or a separate plugin that uses those expansions.
In those cases should you report the issue to the issue tracker of the expansion or plugin.
## Pull requests
As an open source project are we welcoming all contributions to improve PlaceholderAPI, being it changes to its code, or contributions to its documentation such as the [Wiki] or the Javadocs.
> [!IMPORTANT]
> When contributing, make sure to both base of and target the mentioned branch. Pull requests targeting the wrong branch may get closed without a warning.
### Code contributions
> **Source and Target Branch:** [`master`][master]
When contributing towards the code of PlaceholderAPI, be it new features or just bug fixes, your changes should follow the general code styling used in the project.
You can find the necessary files in the [`config/style`][style] directory of this repository.
### Javadocs contributions
> **Source and Target Branch:** [`master`][master]*
Javadocs changes should usually be combined with [code contributions](#code-contributions) when possible, but if not, make sure the changes are significant enough to warrant a new build on our CI server.
\*This branch may change in the future.
### Wiki contributions
> **Source and Target Branch:** [`wiki`][docs-wiki]
The Wiki of PlaceholderAPI is located on its own dedicated branch, hosting all the assets and files that get used to create it through the usage of GitHub Actions and GitHub Pages.
We welcome contributions that update outdated information, add new expansions/plugins supporting PlaceholderAPI or even correct spelling mistakes and typos.
## Code of Conduct
### Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
### Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
### Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
### Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
### Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at our [Discord]. All
complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
### Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]
We have a [Code of Conduct] to maintain a welcoming atmosphere in this project.
If your contributions go against the Code of Conduct, linked above, we reserve the right to deny or revert your contributions.

View File

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

103
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@ -0,0 +1,103 @@
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
- label: The [Common Issues](https://github.com/PlaceholderAPI/PlaceholderAPI/wiki/Common-Issues) page doesn't mention this issue.
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..."

View File

@ -12,3 +12,6 @@ contact_links:
- name: Update Wiki
url: https://github.com/PlaceholderAPI/PlaceholderAPI/pulls
about: Please make a Pull request towards the "wiki" folder to update the wiki.
- name: Questions
url: https://github.com/PlaceholderAPI/PlaceholderAPI/discussions
about: If you have any questions, ask them in our Discussions Page.

View File

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

View File

@ -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..."

View File

@ -25,4 +25,4 @@ Closes N/A <!-- If your PR is based on an issue, change "N/A" the the issue ID (
<!-- DO NOT ALTER ANYTHING BELOW THIS LINE! -->
[Wiki]: https://github.com/PlaceholderAPI/PlaceholderAPI/wiki
[Wiki]: https://wiki.placeholderapi.com

145
.github/label-commenter-config.yml vendored Normal file
View File

@ -0,0 +1,145 @@
comment:
footer: "\
----\n\n
> [!NOTE]\n
> *This is an automated response created by a **GitHub Action***<br>
> *Mentioning the bot won't have any effect!*
"
labels:
- name: 'Type: Issue (Expansion)'
labeled:
issue:
body: |-
Hello @{{ issue.user.login }},
The issue you encountered is caused by an Expansion and not PlaceholderAPI itself.
This issue-tracker is reserved for Bug reports and feature requests towards PlaceholderAPI.
Please report this issue to the Expansion's main issue-tracker.
A list of known Expansion repositories and their issue trackers can be found [here](https://github.com/PlaceholderAPI/PlaceholderAPI/discussions/510#discussion-63812).
action: close
- name: 'Type: Duplicate'
labeled:
issue:
body: |-
Your issue is already known and a separate issue with the exact same report/feature request already exist.
Please comment on the already existing issue with your information instead of opening your own.
action: close
- name: 'Problem: More info required'
labeled:
issue:
body: |-
Hello @{{ issue.user.login }},
Your issue unfortunately lacks certain information that we require in order to help you with your issue.
Please make sure you provide the following information:
- Currently used Versions of your server (`/version`) and PlaceholderAPI (`/version PlaceholderAPI`)
- Currently installed Expansions (`/papi list`)
- Currently installed Plugins (`/pl`)
- Any additional information requested by users in this issue.
The easiest way to provide those information is through the `/papi dump` command which posts the required information to https://paste.helpch.at and gives a URL to share.
unlabeled:
issue:
body: |-
Thank you for providing additional information.
We will take a look at the issue you encounter and come back to you with a possible solution.
- name: 'Type: Invalid'
labeled:
issue:
body: |-
Your issue has beeen marked as invalid.
This means that it either doesn't follow any provided template, or isn't related to PlaceholderAPI.
Please make sure to use one of the issue templates and provide the requested information.
Currently available Templates are:
- [Bug Report](https://github.com/PlaceholderAPI/PlaceholderAPI/issues/new?labels=Type%3A+Issue+%28Unconfirmed%29&template=bug_report.yml)
- [Feature Request](https://github.com/PlaceholderAPI/PlaceholderAPI/issues/new?labels=Type%3A+Enhancement&template=feature_request.yml)
If you want changes to be made towards the Wiki, would we encourage you to [Make a Pull request](https://github.com/PlaceholderAPI/PlaceholderAPI/pulls).
You can find more information about this process on the [Wiki's Readme](https://github.com/PlaceholderAPI/PlaceholderAPI/blob/wiki/README.md).
It is recommended to [join our Discord Server](https://helpch.at/discord) as you often receive a faster response compared to the issue tracker here.
Questions about PlaceholderAPI should be asked in our [Discussions](https://github.com/PlaceholderAPI/PlaceholderAPI/discussions).
action: close
pr:
body: |-
Your Pull request has been marked as **invalid**.
This means that it doesn't follow our [Contributing Guidelines](https://github.com/PlaceholderAPI/PlaceholderAPI/blob/master/.github/CONTRIBUTING.md).
Here is a small summary of what you should know:
- Pull requests for PlaceholderAPI should target the `master` branch.
- Pull requests for the Wiki should target the `wiki` branch.
Don't hesitate to ask us any questions.
action: close
- name: 'Type: Invalid (Wiki)'
labeled:
pr:
body: |-
Your Wiki Pull request has been marked as **invalid**.
Pull requests targeting the Wiki need to target the `wiki` branch.
More information can be found on the [Wiki README](https://github.com/PlaceholderAPI/PlaceholderAPI/blob/wiki/README.md).
action: close
- name: 'Target: Wiki'
labeled:
issue:
body: |-
Hello @{{ issue.user.login }},
Thank you for reaching out to us about the wiki.
We would like to inform you, that you are able to directly commit your changes to the wiki through a Pull request.
When doing so, make sure you follow these steps:
- The Pull request is based on AND targets the [`wiki`](https://github.com/PlaceholderAPI/PlaceholderAPI/tree/wiki) branch of the Repository.
- You followed the general Styling Guidelines mentioned in the wiki's [README](https://github.com/PlaceholderAPI/PlaceholderAPI/blob/wiki/README.md) file.
If you have any questions about submitting a PR for the wiki or have any other questions don't hesitate to ask us about it.
- name: 'Type: Not a bug'
labeled:
issue:
body: |-
The issue you encounter is not considered a bug and rather an intentional behaviour of PlaceholderAPI and/or one of its expansions.
If you still believe that it is a bug, provide more information and a maintainer of this repository may look at it more closely.
Before providing more info, always make sure to use the latest version of PlaceholderAPI, as the issue you encounter might already be fixed in a newer version.
Optionally can you also try out [development builds](https://ci.extendedclip.com/job/PlaceholderAPI/) and see if the issue was fixed there.
action: close
unlabeled:
issue:
body: After further investigation is the issue you encounter indeed considered a bug and we will try to fix it as soon as possible.
action: open
- name: 'Status: Inactive'
labeled:
issue:
body: |-
The issue has been marked as **inactive** which means it didn't recieve any responses from the Author ({{ issue.user.login }}) for a long period of time.
To keep the issue-tracker clean and up to date do we close issues that haven't received any responses for a long time.
If you're the Author of this issue and the reported problem is still present, make sure to respond with additional info to this issue, so that we can reopen it.
**Do not create a new issue for the same problem!**
action: close
unlabeled:
issue:
body: The issue received a response from the Author who confirms this to still be prominent and has therefore been reopened.
action: open
- name: 'Type: Question'
labeled:
issue:
body: |-
Hello @{{ issue.user.login }},
Thank you for reaching out to us for getting Support with PlaceholderAPI.
We would like to inform you, that we have [Discussions](https://github.com/PlaceholderAPI/PlaceholderAPI/discussions) that you can use for asking questions.
Just head over there and click the "New discussion" button to create a new post.
Remember to first read the [READ ME](https://github.com/PlaceholderAPI/PlaceholderAPI/discussions/507) post to not face any issues.
For questions do we recommend to use the [(2) Support](https://github.com/PlaceholderAPI/PlaceholderAPI/discussions/categories/-2-support) category.
You can also use the Discussion to submit Feature requests (Feature requests through issues are still accepted tho).

24
.github/release.yml vendored Normal file
View File

@ -0,0 +1,24 @@
#
# This file is used to automatically draft new release changelogs in GitHub.
# Read more: https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes
#
changelog:
exclude:
labels:
- 'Action: No Changelog'
categories:
- title: 'Breaking Changes'
labels:
- 'Type: Breaking'
- title: 'Additions'
labels:
- 'Type: New Feature'
- title: 'Changes'
labels:
- 'Type: Enhancement'
- title: 'Fixes'
labels:
- 'Type: Bugfix'
- title: 'Other changes'
labels:
- '*' # Catch every other PR not labeled with an "exclude" label.

25
.github/workflows/label_comment.yml vendored Normal file
View File

@ -0,0 +1,25 @@
name: Comment
on:
issues:
types:
- labeled
- unlabeled
pull_request_target:
types:
- labeled
- unlabeled
jobs:
give_comment:
if: github.event.issue.state == 'open' || github.event.pull_request.state == 'open'
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
with:
ref: master
- name: Send Issue/Pull request comment
uses: peaceiris/actions-label-commenter@v1.8.2
with:
github_token: ${{ secrets.GITHUB_TOKEN }}

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

@ -0,0 +1,31 @@
name: "Test compiling against Java 8, 11 and 16"
on:
pull_request:
branches:
- development
paths:
- "src/**"
- "build.gradle"
jobs:
testBuilds:
strategy:
fail-fast: false
max-parallel: 4
matrix:
java-version: [8, 11, 16]
name: "Compile jar against ${{ matrix.java-version }}"
runs-on: ubuntu-latest
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"

View File

@ -1,52 +0,0 @@
#
# This is a GitHub Action that allows us to auto-update the wiki
# when a Pull request changes specific files in a folder.
#
name: Update Wiki
on:
push:
#
# Only trigger when the push changes any files in the wiki-folder.
#
paths:
- 'wiki/**'
branches:
- 'docs/wiki'
#
# Releases cause this action to also fire.
# Using this prevents this problem.
#
tags-ignore:
- '**'
jobs:
update:
runs-on: ubuntu-latest
steps:
- name: 'Checkout Code'
uses: actions/Checkout@v2
- name: 'Update Wiki'
uses: docker://decathlon/wiki-page-creator-action:latest
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

51
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,51 @@
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/
[discord]: https://helpch.at/discord
## Code of Conduct
### Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
### Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
### Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
### Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
### Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team on their [discord server][discord]. All
complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
### Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]

View File

@ -7,6 +7,8 @@
[discord]: https://helpch.at/discord
[spigot]: https://www.spigotmc.org/resources/6245/
[hangar]: https://hangar.papermc.io/HelpChat/PlaceholderAPI
[bbb]: https://builtbybit.com/resources/placeholderapi.24306
[Expansions cloud]: https://api.extendedclip.com/home
[placeholder list]: https://helpch.at/placeholders
[statistics]: https://bstats.org/plugin/bukkit/PlaceholderAPI
@ -15,7 +17,10 @@
[ciImg]: http://ci.extendedclip.com/buildStatus/icon?job=PlaceholderAPI
[APIversionImg]: https://img.shields.io/nexus/placeholderapi/me.clip/placeholderapi?server=https%3A%2F%2Frepo.extendedclip.com&label=API%20Version
[logo]: https://i.imgur.com/Ea4PURv.png
[logo]: https://wiki.placeholderapi.com/assets/img/papi-logo.png
[contributing]: https://github.com/PlaceholderAPI/PlaceholderAPI/blob/master/.github/CONTRIBUTING.md
[placeholderexpansion]: https://wiki.placeholderapi.com/developers/creating-a-placeholderexpansion/
<!-- The stuff above isn't visible in the readme -->
[![logo]][spigot]
@ -25,12 +30,15 @@
# Information
[PlaceholderAPI][spigot] is a plugin for Spigot servers that allows server owners to display information from various plugins with a uniform format.
Support for specific plugins are provided either by the plugin itself or through expansions. The expansions may be downloaded in-game through the PAPI Expansion Cloud. There are currently over 150+ expansions that support a wide variety of plugins, such as Essentials, Factions, LuckPerms, and Vault.
Support for specific plugins are provided either by the plugin itself or through expansions. The expansions may be downloaded in-game through the PAPI Expansion Cloud. There are currently over 240+ expansions that support a wide variety of plugins, such as Essentials, Factions, LuckPerms, and Vault.
PlaceholderAPI has been downloaded over 400,000 times and has been used concurrently on over 20,000 servers, which makes it a must-have for a server of any type or scale.
PlaceholderAPI has been downloaded over 1,000,000 times and has been used concurrently on over 40,000 servers, which makes it a must-have for a server of any type or scale.
<!-- TODO: Add contributing section -->
<!-- TODO: Add expansion creation section (possibly add to a wiki?) -->
## 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]
@ -38,7 +46,9 @@ PlaceholderAPI has been downloaded over 400,000 times and has been used concurre
## Quick Links
- [CI Server][ci]
- [Expansions cloud]
- [Expansions Cloud]
- [Placeholder List]
- [Spigot Page][spigot]
- [Hangar Page][hangar]
- [BuiltByBit Page][bbb]
- [Plugin Statistics][statistics]

View File

@ -1,117 +0,0 @@
plugins {
id "java"
id "maven-publish"
id "net.minecrell.licenser" version "0.4.1"
id "com.github.johnrengelman.shadow" version "6.0.0"
}
group "me.clip"
version "2.10.9"
description "An awesome placeholder provider!"
repositories {
mavenCentral()
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"
compileOnly "org.spigotmc:spigot-api:1.16.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"
}
processResources {
from(sourceSets.main.resources.srcDirs) {
filter org.apache.tools.ant.filters.ReplaceTokens, tokens: [name: rootProject.name, version: project.version.toString(), description: project.description]
}
}
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
shadowJar {
archiveClassifier.set("")
relocate "org.bstats", "me.clip.placeholderapi.metrics"
relocate "com.google.gson", "me.clip.placeholderapi.libs.gson"
}
license {
include '**/*.java'
matching('**/*.java') {
header = file('config/headers/main.txt')
}
matching('**/JSONMessage.java') {
header = file('config/headers/jsonmessage.txt')
}
ext {
year = 2020
}
}
test {
useJUnitPlatform()
}
sourceSets {
test.compileClasspath += configurations.compileOnly
test.runtimeClasspath += configurations.compileOnly
}
publishing {
repositories {
maven {
if (version.contains("-DEV-")) {
url = uri("https://repo.extendedclip.com/content/repositories/dev/")
} else {
url = uri("https://repo.extendedclip.com/content/repositories/placeholderapi/")
}
credentials {
username = System.getenv("JENKINS_USER")
password = System.getenv("JENKINS_PASS")
}
}
}
publications {
mavenJava(MavenPublication) {
artifactId = "placeholderapi"
from components.java
pom.withXml {
asNode().appendNode("packaging", "jar")
asNode().remove(asNode().get("dependencies"))
def dependenciesNode = asNode().appendNode("dependencies")
// jetbrains annotations
def jetbrainsAnnotations = dependenciesNode.appendNode("dependency")
jetbrainsAnnotations.appendNode("groupId", "org.jetbrains")
jetbrainsAnnotations.appendNode("artifactId", "annotations")
jetbrainsAnnotations.appendNode("version", "19.0.0")
}
}
}
}
publish.dependsOn clean, test, jar

128
build.gradle.kts Normal file
View File

@ -0,0 +1,128 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
plugins {
`java-library`
`maven-publish`
id("com.github.hierynomus.license") version "0.16.1"
id("com.github.johnrengelman.shadow") version "8.1.0"
}
group = "me.clip"
version = "2.11.6-DEV-${System.getProperty("BUILD_NUMBER")}"
description = "An awesome placeholder provider!"
repositories {
maven("https://oss.sonatype.org/content/repositories/snapshots/")
mavenCentral()
mavenLocal()
maven("https://repo.codemc.org/repository/maven-public/")
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
}
dependencies {
implementation("org.bstats:bstats-bukkit:3.0.1")
implementation("net.kyori:adventure-platform-bukkit:4.3.1")
compileOnly("org.spigotmc:spigot-api:1.20-R0.1-SNAPSHOT")
compileOnlyApi("org.jetbrains:annotations:23.0.0")
testImplementation("org.openjdk.jmh:jmh-core:1.32")
testImplementation("org.openjdk.jmh:jmh-generator-annprocess:1.32")
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.8.2")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1")
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
withJavadocJar()
withSourcesJar()
}
license {
header = rootProject.file("config/headers/main.txt")
include("**/*.java")
mapping("java", "JAVADOC_STYLE")
encoding = "UTF-8"
ext {
set("year", 2024)
}
}
val javaComponent: SoftwareComponent = components["java"]
tasks {
processResources {
eachFile { expand("version" to project.version) }
}
build {
dependsOn(named("shadowJar"))
}
withType<JavaCompile> {
options.encoding = "UTF-8"
}
withType<Javadoc> {
isFailOnError = false
with(options as StandardJavadocDocletOptions) {
addStringOption("Xdoclint:none", "-quiet")
addStringOption("encoding", "UTF-8")
addStringOption("charSet", "UTF-8")
}
}
withType<ShadowJar> {
archiveClassifier.set("")
relocate("org.bstats", "me.clip.placeholderapi.metrics")
relocate("net.kyori", "me.clip.placeholderapi.libs.kyori")
}
test {
useJUnitPlatform()
}
publishing {
publications {
create<MavenPublication>("maven") {
artifactId = "placeholderapi"
from(javaComponent)
}
}
repositories {
maven {
if ("-DEV" in version.toString()) {
url = uri("https://repo.extendedclip.com/content/repositories/dev/")
} else {
url = uri("https://repo.extendedclip.com/content/repositories/placeholderapi/")
}
credentials {
username = System.getenv("JENKINS_USER")
password = System.getenv("JENKINS_PASS")
}
}
}
}
publish.get().setDependsOn(listOf(build.get()))
}
configurations {
testImplementation {
extendsFrom(compileOnly.get())
}
}

View File

@ -1,4 +1,4 @@
Copyright (c) 2018-2020 Peter Blood
Copyright (c) 2018-2024 Peter Blood
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

Binary file not shown.

View File

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

269
gradlew vendored Normal file → Executable file
View File

@ -1,7 +1,7 @@
#!/usr/bin/env sh
#!/bin/sh
#
# Copyright 2015 the original author or authors.
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -17,67 +17,101 @@
#
##############################################################################
##
## Gradle start up script for UN*X
##
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
MAX_FD=maximum
warn () {
echo "$*"
}
} >&2
die () {
echo
echo "$*"
echo
exit 1
}
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
@ -106,80 +140,95 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
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
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

21
gradlew.bat vendored
View File

@ -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

View File

@ -1 +0,0 @@
rootProject.name = 'PlaceholderAPI'

1
settings.gradle.kts Normal file
View File

@ -0,0 +1 @@
rootProject.name = "PlaceholderAPI"

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,6 +22,7 @@ package me.clip.placeholderapi;
import com.google.common.collect.ImmutableSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
@ -29,6 +30,7 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.clip.placeholderapi.expansion.Relational;
import me.clip.placeholderapi.expansion.manager.LocalExpansionManager;
import me.clip.placeholderapi.replacer.CharsReplacer;
import me.clip.placeholderapi.replacer.Replacer;
import me.clip.placeholderapi.replacer.Replacer.Closure;
@ -80,7 +82,7 @@ public final class PlaceholderAPI {
*/
@NotNull
public static List<String> setPlaceholders(final OfflinePlayer player,
@NotNull final List<@NotNull String> text) {
@NotNull final List<String> text) {
return text.stream().map(line -> setPlaceholders(player, line)).collect(Collectors.toList());
}
@ -135,22 +137,38 @@ public final class PlaceholderAPI {
*/
@NotNull
public static List<String> setBracketPlaceholders(final OfflinePlayer player,
@NotNull final List<@NotNull String> text) {
@NotNull final List<String> text) {
return text.stream().map(line -> setBracketPlaceholders(player, line))
.collect(Collectors.toList());
}
/**
* Translates all placeholders into their corresponding values.
* <br>The pattern of a valid placeholder is {@literal {<identifier>_<params>}}.
*
* @param player Player to parse the placeholders against
* @param text Text to set the placeholder values in
* @return String containing all translated placeholders
*/
public static String setBracketPlaceholders(Player player, String text) {
return setBracketPlaceholders((OfflinePlayer) player, text);
}
/**
* Translates all placeholders into their corresponding values.
* <br>The pattern of a valid placeholder is {@literal {<identifier>_<params>}}.
*
* @param player Player to parse the placeholders against
* @param text List of Strings to set the placeholder values in
* @return String containing all translated placeholders
*/
public static List<String> setBracketPlaceholders(Player player, List<String> text) {
return setPlaceholders((OfflinePlayer) player, text);
return setBracketPlaceholders((OfflinePlayer) player, text);
}
/**
* set relational placeholders in the text specified placeholders are matched with the pattern
* %<rel_(identifier)_(params)>% when set with this method
* {@literal %<rel_(identifier)_(params)>%} when set with this method
*
* @param one First player to compare
* @param two Second player to compare
@ -168,7 +186,7 @@ public final class PlaceholderAPI {
continue;
}
String identifier = format.substring(0, index).toLowerCase();
String identifier = format.substring(0, index).toLowerCase(Locale.ROOT);
String params = format.substring(index + 1);
final PlaceholderExpansion expansion = PlaceholderAPIPlugin.getInstance()
.getLocalExpansionManager().getExpansion(identifier);
@ -184,7 +202,7 @@ public final class PlaceholderAPI {
}
}
return Msg.color(text);
return text;
}
/**
@ -215,7 +233,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<String> getRegisteredIdentifiers() {
@ -225,6 +243,8 @@ public final class PlaceholderAPI {
/**
* Get the normal placeholder pattern.
*
* @return Regex Pattern of {@literal [%]([^%]+)[%]}
*/
public static Pattern getPlaceholderPattern() {
return PLACEHOLDER_PATTERN;
@ -232,6 +252,8 @@ public final class PlaceholderAPI {
/**
* Get the bracket placeholder pattern.
*
* @return Regex Pattern of {@literal [{]([^{}]+)[}]}
*/
public static Pattern getBracketPlaceholderPattern() {
return BRACKET_PLACEHOLDER_PATTERN;
@ -239,6 +261,8 @@ public final class PlaceholderAPI {
/**
* Get the relational placeholder pattern.
*
* @return Regex Pattern of {@literal [%](rel_)([^%]+)[%]}
*/
public static Pattern getRelationalPlaceholderPattern() {
return RELATIONAL_PLACEHOLDER_PATTERN;
@ -268,15 +292,29 @@ public final class PlaceholderAPI {
// === Deprecated API ===
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static boolean registerExpansion(PlaceholderExpansion expansion)
{
return expansion.register();
}
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static boolean unregisterExpansion(PlaceholderExpansion expansion)
{
return expansion.unregister();
}
/**
* Get map of registered placeholders
*
* @deprecated Use {@link LocalExpansionManager#getExpansions()} instead.
*
* @return Map of registered placeholders
* @deprecated Use {@link me.clip.placeholderapi.PlaceholderAPIPlugin().getLocalExpansionManager()
* .getExpansions()} instead.
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static Map<String, PlaceholderHook> getPlaceholders() {
return PlaceholderAPIPlugin.getInstance().getLocalExpansionManager()
.getExpansions().stream()
@ -284,81 +322,104 @@ public final class PlaceholderAPI {
}
/**
* @deprecated Please use {@link me.clip.placeholderapi.expansion.PlaceholderExpansion} to
* @deprecated Please use {@link PlaceholderExpansion} to
* register placeholders instead
*
* @param plugin The Plugin to register with this {@link PlaceholderHook}
* @param placeholderHook The {@link PlaceholderHook} to register
* @return always false
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static boolean registerPlaceholderHook(Plugin plugin, PlaceholderHook placeholderHook) {
PlaceholderAPIPlugin.getInstance().getLogger().warning(plugin.getName()
+ " is attempting to register placeholders via a PlaceholderHook class which is no longer supported!"
+ " Please reach out to " + plugin.getDescription().getAuthors().toString()
+ " and let them know that they need to update ASAP!");
Msg.warn("Nag author(s) %s of plugin %s about their usage of the deprecated PlaceholderHook"
+ " class! This class will be removed in v2.13.0!", plugin.getDescription().getAuthors(),
plugin.getName());
return false;
}
/**
* @deprecated Please use {@link me.clip.placeholderapi.expansion.PlaceholderExpansion} to
* @deprecated Please use {@link PlaceholderExpansion} to
* register placeholders instead
*
* @param identifier The identifier to use for the {@link PlaceholderHook}
* @param placeholderHook The {@link PlaceholderHook} to register
* @return always false
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static boolean registerPlaceholderHook(String identifier,
PlaceholderHook placeholderHook) {
PlaceholderAPIPlugin.getInstance().getLogger().warning(identifier
+ " is attempting to register placeholders via a PlaceholderHook class which is no longer supported!");
Msg.warn("%s is attempting to register placeholders via deprecated PlaceholderHook class."
+ " This class is no longer supported and will be removed in v2.13.0!", identifier);
return false;
}
/**
* @deprecated Please use {@link me.clip.placeholderapi.expansion.PlaceholderExpansion} to
* @deprecated Please use {@link PlaceholderExpansion} to
* unregister placeholders instead
*
* @param plugin The plugin to unregister
* @return always false
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static boolean unregisterPlaceholderHook(Plugin plugin) {
PlaceholderAPIPlugin.getInstance().getLogger().warning(plugin.getName()
+ " is attempting to unregister placeholders via the PlaceholderAPI class which is no longer supported!"
+ " Please reach out to " + plugin.getDescription().getAuthors().toString()
+ " and let them know that they need to update ASAP!");
Msg.warn("Nag author(s) %s of plugin %s about their usage of the PlaceholderAPI class."
+ " This way of unregistering placeholders is no longer supported and will be removed"
+ " in v2.13.0!", plugin.getDescription().getAuthors(), plugin.getName());
return false;
}
/**
* @deprecated Please use {@link me.clip.placeholderapi.expansion.PlaceholderExpansion} to
* @deprecated Please use {@link PlaceholderExpansion} to
* unregister placeholders instead
*
* @param identifier The identifier to unregister
* @return always false
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static boolean unregisterPlaceholderHook(String identifier) {
PlaceholderAPIPlugin.getInstance().getLogger().warning(identifier
+ " is attempting to unregister placeholders through the PlaceholderAPI class which is no longer supported!");
Msg.warn("%s is attempting to unregister placeholders via PlaceholderAPI class."
+ " This way of unregistering placeholders is no longer supported and will be removed"
+ " in v2.13.0!", identifier);
return false;
}
/**
* @deprecated Will be removed in a future release.
*
* @return Set of registered identifiers
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static Set<String> getRegisteredPlaceholderPlugins() {
return getRegisteredIdentifiers();
}
/**
* @deprecated Will be removed in a future release.
*
* @return always null
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static Set<String> getExternalPlaceholderPlugins() {
return null;
}
/**
* @deprecated Please use {@link #setPlaceholders(OfflinePlayer, String)} instead
*
* @param player The offline player to parse the placeholders against
* @param text The text to parse
* @param pattern The Pattern to use
* @param colorize If PlaceholderAPI should also parse color codes
* @return String with the parsed placeholders
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static String setPlaceholders(OfflinePlayer player,
String text, Pattern pattern, boolean colorize) {
return setPlaceholders(player, text);
@ -366,9 +427,15 @@ public final class PlaceholderAPI {
/**
* @deprecated Please use {@link #setPlaceholders(OfflinePlayer, List)} instead
*
* @param player The offline player to parse the placeholders against
* @param text The List of text to parse
* @param pattern The Pattern to use
* @param colorize If PlaceholderAPI should also parse color codes
* @return String with the parsed placeholders
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static List<String> setPlaceholders(OfflinePlayer player,
List<String> text, Pattern pattern, boolean colorize) {
return setPlaceholders(player, text);
@ -376,9 +443,14 @@ public final class PlaceholderAPI {
/**
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, List)} instead.
*
* @param player The offline player to parse the placeholders against
* @param text The List of text to parse
* @param colorize If PlaceholderAPI should also parse color codes
* @return String with the parsed placeholders
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static List<String> setPlaceholders(OfflinePlayer player, List<String> text,
boolean colorize) {
return setPlaceholders(player, text);
@ -386,54 +458,84 @@ public final class PlaceholderAPI {
/**
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, List)} instead.
*
* @param player The offline player to parse the placeholders against
* @param text The List of text to parse
* @param pattern The Pattern to use
* @return String with the parsed placeholders
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static List<String> setPlaceholders(OfflinePlayer player, List<String> text,
Pattern pattern) {
return setPlaceholders(player, text);
}
/**
* @deprecated Will be removed in a future release.
*
* @param player The offline player to parse the placeholders against
* @param text The text to parse
* @param colorize If PlaceholderAPI should also parse color codes
* @return String with the parsed placeholders
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static String setPlaceholders(Player player, String text, boolean colorize) {
return setPlaceholders(player, text);
}
/**
* @deprecated Will be removed in a future release.
*
* @param player The offline player to parse the placeholders against
* @param text The List of text to parse
* @param colorize If PlaceholderAPI should also parse color codes
* @return String with the parsed placeholders
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static List<String> setPlaceholders(Player player, List<String> text, boolean colorize) {
return setPlaceholders(player, text);
}
/**
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, String)} instead.
*
* @param player The offline player to parse the placeholders against
* @param text The text to parse
* @param colorize If PlaceholderAPI should also parse color codes
* @return String with the parsed placeholders
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static String setPlaceholders(OfflinePlayer player, String text, boolean colorize) {
return setPlaceholders(player, text);
}
/**
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, String)} instead.
*
* @param player The offline player to parse the placeholders against
* @param text The text to parse
* @param pattern The Pattern to use
* @return String with the parsed placeholders
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static String setPlaceholders(OfflinePlayer player, String text, Pattern pattern) {
return setPlaceholders(player, text);
}
/**
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, List)} instead.
*
* @param player The offline player to parse the placeholders against
* @param text The List of text to parse
* @param colorize If PlaceholderAPI should also parse color codes
* @return String with the parsed placeholders
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static List<String> setBracketPlaceholders(OfflinePlayer player, List<String> text,
boolean colorize) {
return setBracketPlaceholders(player, text);
@ -441,27 +543,42 @@ public final class PlaceholderAPI {
/**
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, String)} instead.
*
* @param player The offline player to parse the placeholders against
* @param text The text to parse
* @param colorize If PlaceholderAPI should also parse color codes
* @return String with the parsed placeholders
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static String setBracketPlaceholders(OfflinePlayer player, String text, boolean colorize) {
return setBracketPlaceholders(player, text);
}
/**
* @deprecated Will be removed in a future release.
*
* @param player The offline player to parse the placeholders against
* @param text The text to parse
* @param colorize If PlaceholderAPI should also parse color codes
* @return String with the parsed placeholders
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static String setBracketPlaceholders(Player player, String text, boolean colorize) {
return setBracketPlaceholders(player, text);
}
/**
* @deprecated Will be removed in a future release.
*
* @param player The offline player to parse the placeholders against
* @param text The List of text to parse
* @param colorize If PlaceholderAPI should also parse color codes
* @return String with the parsed placeholders
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static List<String> setBracketPlaceholders(Player player, List<String> text,
boolean colorize) {
return setBracketPlaceholders(player, text);
@ -469,17 +586,17 @@ public final class PlaceholderAPI {
/**
* set relational placeholders in the text specified placeholders are matched with the pattern
* %<rel_(identifier)_(params)>% when set with this method
* {@literal %<rel_(identifier)_(params)>%} when set with this method
*
* @param one Player to compare
* @param two Player to compare
* @param text Text to parse the placeholders in
* @param colorize If color codes (&[0-1a-fk-o]) should be translated
* @param colorize If color codes ({@literal &[0-1a-fk-o]}) should be translated
* @return The text containing the parsed relational placeholders
* @deprecated Use {@link #setPlaceholders(OfflinePlayer, String)} instead.
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static String setRelationalPlaceholders(Player one, Player two, String text,
boolean colorize) {
return setRelationalPlaceholders(one, two, text);
@ -492,12 +609,12 @@ public final class PlaceholderAPI {
* @param one First player to compare
* @param two Second player to compare
* @param text Text to parse the placeholders in
* @param colorize If color codes (&[0-1a-fk-o]) should be translated
* @param colorize If color codes ({@literal &[0-1a-fk-o]}) should be translated
* @return The text containing the parsed relational placeholders
* @deprecated Use {@link #setRelationalPlaceholders(Player, Player, List<String>)} instead.
* @deprecated Use {@link #setRelationalPlaceholders(Player, Player, List)} instead.
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public static List<String> setRelationalPlaceholders(Player one, Player two, List<String> text,
boolean colorize) {
return setRelationalPlaceholders(one, two, text);

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -21,9 +21,9 @@
package me.clip.placeholderapi;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import me.clip.placeholderapi.commands.PlaceholderCommandRouter;
import me.clip.placeholderapi.configuration.PlaceholderAPIConfig;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
@ -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 me.clip.placeholderapi.util.Msg;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
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;
@ -52,7 +56,18 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
private static PlaceholderAPIPlugin instance;
static {
final String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
String version = Bukkit.getServer().getBukkitVersion().split("-")[0];
String suffix;
if (version.chars()
.filter(c -> c == '.')
.count() == 1) {
suffix = "R1";
version = 'v' + version.replace('.', '_') + '_' + suffix;
} else {
int minor = Integer.parseInt(version.split("\\.")[2].charAt(0) + "");
version = 'v' + version.replace('.', '_').replace("_" + minor, "") + '_' + "R" + (minor - 1);
}
boolean isSpigot;
try {
@ -73,6 +88,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
@ -116,11 +133,13 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
try {
return new SimpleDateFormat(getInstance().getPlaceholderAPIConfig().dateFormat());
} catch (final IllegalArgumentException ex) {
getInstance().getLogger().log(Level.WARNING, "configured date format is invalid", ex);
Msg.warn("Configured date format ('%s') is invalid! Defaulting to 'MM/dd/yy HH:mm:ss'",
ex, getInstance().getPlaceholderAPIConfig().dateFormat());
return new SimpleDateFormat("MM/dd/yy HH:mm:ss");
}
}
@Deprecated
public static Version getServerVersion() {
return VERSION;
}
@ -138,6 +157,8 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
setupMetrics();
setupExpansions();
adventure = BukkitAudiences.create(this);
if (config.isCloudEnabled()) {
getCloudExpansionManager().load();
}
@ -156,6 +177,9 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
Bukkit.getScheduler().cancelTasks(this);
adventure.close();
adventure = null;
instance = null;
}
@ -183,6 +207,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 +238,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<String, Integer> values = new HashMap<>();
for (final PlaceholderExpansion expansion : getLocalExpansionManager().getExpansions()) {
@ -230,7 +262,7 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
try {
Class.forName("org.bukkit.event.server.ServerLoadEvent");
new ServerLoadEventListener(this);
} catch (final ExceptionInInitializerError | ClassNotFoundException ignored) {
} catch (final ClassNotFoundException ignored) {
Bukkit.getScheduler()
.runTaskLater(this, () -> getLocalExpansionManager().load(Bukkit.getConsoleSender()), 1);
}

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -23,17 +23,19 @@ package me.clip.placeholderapi;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class PlaceholderHook {
@Nullable
public String onRequest(final OfflinePlayer player, @NotNull final String params) {
if (player != null && player.isOnline()) {
return onPlaceholderRequest((Player) player, params);
return onPlaceholderRequest(player.getPlayer(), params);
}
return onPlaceholderRequest(null, params);
}
@Nullable
public String onPlaceholderRequest(final Player player, @NotNull final String params) {
return null;
}

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -23,6 +23,7 @@ package me.clip.placeholderapi.commands;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Stream;
import me.clip.placeholderapi.PlaceholderAPIPlugin;
@ -61,7 +62,7 @@ public abstract class PlaceholderCommand {
if (parameter == null) {
possible.forEach(suggestions::add);
} else {
possible.filter(suggestion -> suggestion.toLowerCase().startsWith(parameter.toLowerCase()))
possible.filter(suggestion -> suggestion.toLowerCase(Locale.ROOT).startsWith(parameter.toLowerCase(Locale.ROOT)))
.forEach(suggestions::add);
}
}

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -27,6 +27,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Stream;
import me.clip.placeholderapi.PlaceholderAPIPlugin;
@ -95,7 +96,7 @@ public final class PlaceholderCommandRouter implements CommandExecutor, TabCompl
return true;
}
final String search = args[0].toLowerCase();
final String search = args[0].toLowerCase(Locale.ROOT);
final PlaceholderCommand target = commands.get(search);
if (target == null) {
@ -121,10 +122,10 @@ public final class PlaceholderCommandRouter implements CommandExecutor, TabCompl
final List<String> suggestions = new ArrayList<>();
if (args.length > 1) {
final PlaceholderCommand target = this.commands.get(args[0].toLowerCase());
final PlaceholderCommand target = this.commands.get(args[0].toLowerCase(Locale.ROOT));
if (target != null) {
target.complete(plugin, sender, args[0].toLowerCase(),
target.complete(plugin, sender, args[0].toLowerCase(Locale.ROOT),
Arrays.asList(Arrays.copyOfRange(args, 1, args.length)), suggestions);
}

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,10 +22,6 @@ package me.clip.placeholderapi.commands.impl.cloud;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand;
import me.clip.placeholderapi.util.Msg;
@ -33,12 +29,17 @@ import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Stream;
public final class CommandECloud extends PlaceholderCommand {
@Unmodifiable
private static final List<PlaceholderCommand> COMMANDS = ImmutableList
.of(new CommandECloudClear(),
new CommandECloudToggle(),
new CommandECloudStatus(),
new CommandECloudUpdate(),
new CommandECloudRefresh(),
@ -78,8 +79,6 @@ public final class CommandECloud extends PlaceholderCommand {
Msg.msg(sender,
"&b&lPlaceholderAPI &8- &7eCloud Help Menu &8- ",
" ",
"&b/papi &fenable/disable/toggle",
" &7&oEnable or disable the eCloud",
"&b/papi &fecloud status",
" &7&oView status of the eCloud",
"&b/papi &fecloud list <all/{author}/installed> {page}",
@ -100,7 +99,7 @@ public final class CommandECloud extends PlaceholderCommand {
return;
}
final String search = params.get(0).toLowerCase();
final String search = params.get(0).toLowerCase(Locale.ROOT);
final PlaceholderCommand target = commands.get(search);
if (target == null) {
@ -114,10 +113,8 @@ public final class CommandECloud extends PlaceholderCommand {
return;
}
if (!(target instanceof CommandECloudToggle) && !plugin.getPlaceholderAPIConfig()
.isCloudEnabled()) {
Msg.msg(sender,
"&cThe eCloud Manager is not enabled!");
if (!plugin.getPlaceholderAPIConfig().isCloudEnabled()) {
Msg.msg(sender, "&cThe eCloud Manager is not enabled! To enable it, set 'cloud_enabled' to true and reload the plugin.");
return;
}
@ -136,7 +133,7 @@ public final class CommandECloud extends PlaceholderCommand {
return; // send sub commands
}
final String search = params.get(0).toLowerCase();
final String search = params.get(0).toLowerCase(Locale.ROOT);
final PlaceholderCommand target = commands.get(search);
if (target == null) {

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -20,6 +20,7 @@
package me.clip.placeholderapi.commands.impl.cloud;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
@ -37,6 +38,16 @@ public final class CommandECloudDownload extends PlaceholderCommand {
super("download");
}
private boolean isBlockedExpansion(String name) {
String env = System.getenv("PAPI_BLOCKED_EXPANSIONS");
if (env == null) {
return false;
}
return Arrays.stream(env.split(","))
.anyMatch(s -> s.equalsIgnoreCase(name));
}
@Override
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
@NotNull final CommandSender sender, @NotNull final String alias,
@ -47,6 +58,12 @@ public final class CommandECloudDownload extends PlaceholderCommand {
return;
}
if (isBlockedExpansion(params.get(0))) {
Msg.msg(sender,
"&cThis expansion can't be downloaded.");
return;
}
final CloudExpansion expansion = plugin.getCloudExpansionManager()
.findCloudExpansionByName(params.get(0)).orElse(null);
if (expansion == null) {
@ -55,6 +72,11 @@ public final class CommandECloudDownload extends PlaceholderCommand {
return;
}
if (!expansion.isVerified()) {
Msg.msg(sender, "&cThe expansion '&f" + params.get(0) + "&c' is not verified and can only be downloaded manually from &fhttps://placeholderapi.com/ecloud");
return;
}
final CloudExpansion.Version version;
if (params.size() < 2) {
version = expansion.getVersion(expansion.getLatestVersion());
@ -86,9 +108,7 @@ public final class CommandECloudDownload extends PlaceholderCommand {
.getVersion() + "] &ato file: &f" + file.getName(),
"&aMake sure to type &f/papi reload &ato enable your new expansion!");
plugin.getCloudExpansionManager().clean();
plugin.getCloudExpansionManager()
.fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions());
plugin.getCloudExpansionManager().load();
});
}

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -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;
@ -87,7 +87,7 @@ public final class CommandECloudExpansionList extends PlaceholderCommand {
@NotNull
private static Collection<CloudExpansion> getExpansions(@NotNull final String target,
@NotNull final PlaceholderAPIPlugin plugin) {
switch (target.toLowerCase()) {
switch (target.toLowerCase(Locale.ROOT)) {
case "all":
return plugin.getCloudExpansionManager().getCloudExpansions().values();
case "installed":
@ -112,7 +112,7 @@ public final class CommandECloudExpansionList extends PlaceholderCommand {
public static void addExpansionTitle(@NotNull final StringBuilder builder,
@NotNull final String target, final int page) {
switch (target.toLowerCase()) {
switch (target.toLowerCase(Locale.ROOT)) {
case "all":
builder.append("&bAll Expansions");
break;
@ -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<CloudExpansion> expansions,
private static Component getMessage(@NotNull final List<CloudExpansion> 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<CloudExpansion> 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

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -38,9 +38,7 @@ public final class CommandECloudRefresh extends PlaceholderCommand {
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
@NotNull final CommandSender sender, @NotNull final String alias,
@NotNull @Unmodifiable final List<String> params) {
plugin.getCloudExpansionManager().clean();
plugin.getCloudExpansionManager()
.fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions());
plugin.getCloudExpansionManager().load();
Msg.msg(sender,
"&aThe eCloud manager has been refreshed!");

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -54,7 +54,7 @@ public final class CommandECloudStatus extends PlaceholderCommand {
if (updateCount > 0) {
builder.append("&eYou have &f").append(updateCount)
.append(updateCount > 1 ? "&e expansions" : "&e expansion").append("installed that ")
.append(updateCount > 1 ? "&e expansions" : "&e expansion").append(" installed that ")
.append(updateCount > 1 ? "have an" : "has an").append(" update available.");
}

View File

@ -1,72 +0,0 @@
/*
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlaceholderAPI is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package me.clip.placeholderapi.commands.impl.cloud;
import java.util.List;
import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand;
import me.clip.placeholderapi.util.Msg;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable;
public final class CommandECloudToggle extends PlaceholderCommand {
public CommandECloudToggle() {
super("toggle", "enable", "disable");
}
@Override
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
@NotNull final CommandSender sender, @NotNull final String alias,
@NotNull @Unmodifiable final List<String> params) {
final boolean desiredState;
final boolean currentState = plugin.getPlaceholderAPIConfig().isCloudEnabled();
switch (alias.toLowerCase()) {
case "enable":
desiredState = true;
break;
case "disable":
desiredState = false;
break;
default:
desiredState = !currentState;
break;
}
if (desiredState == currentState) {
Msg.msg(sender, "&7The eCloud Manager is already " + (desiredState ? "enabled" : "disabled"));
return;
}
plugin.getPlaceholderAPIConfig().setCloudEnabled(desiredState);
if (desiredState) {
plugin.getCloudExpansionManager().load();
} else {
plugin.getCloudExpansionManager().kill();
}
Msg.msg(sender, "&aThe eCloud Manager has been " + (desiredState ? "enabled" : "disabled"));
}
}

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -23,6 +23,7 @@ package me.clip.placeholderapi.commands.impl.cloud;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@ -128,7 +129,7 @@ public final class CommandECloudUpdate extends PlaceholderCommand {
installed.removeIf(expansion -> !expansion.shouldUpdate());
if (!installed.isEmpty() && (params.isEmpty() || "all"
.startsWith(params.get(0).toLowerCase()))) {
.startsWith(params.get(0).toLowerCase(Locale.ROOT)))) {
suggestions.add("all");
}

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -21,7 +21,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)
@ -101,10 +106,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);
@ -130,18 +133,15 @@ public final class CommandDump extends PlaceholderCommand {
final List<PlaceholderExpansion> expansions = plugin.getLocalExpansionManager()
.getExpansions()
.stream()
.sorted(Comparator.comparing(PlaceholderExpansion::getIdentifier))
.sorted(Comparator.comparing(PlaceholderExpansion::getAuthor))
.sorted(
Comparator.comparing(PlaceholderExpansion::getIdentifier)
.thenComparing(PlaceholderExpansion::getAuthor)
)
.collect(Collectors.toList());
int size = 0;
for (final String name : expansions.stream().map(PlaceholderExpansion::getIdentifier)
.collect(Collectors.toList())) {
if (name.length() > size) {
size = name.length();
}
}
int size = expansions.stream().map(e -> e.getIdentifier().length())
.max(Integer::compareTo)
.orElse(0);
for (final PlaceholderExpansion expansion : expansions) {
builder.append(" ")
@ -161,12 +161,17 @@ public final class CommandDump extends PlaceholderCommand {
final String[] jars = plugin.getLocalExpansionManager()
.getExpansionsFolder()
.list((dir, name) -> name.toLowerCase().endsWith(".jar"));
.list((dir, name) -> name.toLowerCase(Locale.ROOT).endsWith(".jar"));
for (final String jar : jars) {
builder.append(" ")
.append(jar)
.append('\n');
if (jars == null) {
builder.append(" ¨[Warning]: Could not load jar files from expansions folder.");
} else {
for (final String jar : jars) {
builder.append(" ")
.append(jar)
.append('\n');
}
}
builder.append('\n');
@ -175,6 +180,10 @@ public final class CommandDump extends PlaceholderCommand {
.append(plugin.getServer().getBukkitVersion())
.append('/')
.append(plugin.getServer().getVersion())
.append("\n");
builder.append("Java Version: ")
.append(System.getProperty("java.version"))
.append("\n\n");
builder.append("Plugin Info:")
@ -183,18 +192,17 @@ public final class CommandDump extends PlaceholderCommand {
List<Plugin> plugins = Arrays.stream(plugin.getServer().getPluginManager().getPlugins())
.sorted(Comparator.comparing(Plugin::getName))
.collect(Collectors.toList());
for (final String pluginName : plugins.stream().map(Plugin::getName)
.collect(Collectors.toList())) {
if (pluginName.length() > size) {
size = pluginName.length();
}
}
size = plugins.stream().map(pl -> pl.getName().length())
.max(Integer::compareTo)
.orElse(0);
for (final Plugin other : plugins) {
builder.append(" ")
.append(String.format("%-" + size + "s", other.getName()))
.append(" [Version: ")
.append(" [Authors: [")
.append(String.join(", ", other.getDescription().getAuthors()))
.append("], Version: ")
.append(other.getDescription().getVersion())
.append("]")
.append("\n");

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -54,7 +54,7 @@ public final class CommandExpansionRegister extends PlaceholderCommand {
final LocalExpansionManager manager = plugin.getLocalExpansionManager();
final File file = new File(manager.getExpansionsFolder(), params.get(0));
if (!file.exists()) {
if (!file.exists() || !file.getParentFile().equals(manager.getExpansionsFolder())) {
Msg.msg(sender,
"&cThe file &f" + file.getName() + "&c doesn't exist!");
return;

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -45,9 +45,9 @@ public final class CommandHelp extends PlaceholderCommand {
Msg.msg(sender,
"&b&lPlaceholderAPI &8- &7Help Menu &8- &7(&f" + description.getVersion() + "&7)",
" ",
"&b/papi &fbcparse &9<me/player name> <message>",
"&b/papi &fbcparse &9<me|--null|player name> <message>",
" &7&oParse a message with placeholders and broadcast it",
"&b/papi &fcmdparse &9<me/player> <command with placeholders>",
"&b/papi &fcmdparse &9<me|player> <command with placeholders>",
" &7&oParse a message with relational placeholders",
"&b/papi &fdump",
" &7&oDump all relevant information needed to help debug issues into a paste link.",
@ -55,7 +55,7 @@ public final class CommandHelp extends PlaceholderCommand {
" &7&oView information for a specific expansion",
"&b/papi &flist",
" &7&oList active expansions",
"&b/papi &fparse &9<me/player name> <message>",
"&b/papi &fparse &9<me|--null|player name> <message>",
" &7&oParse a message with placeholders",
"&b/papi &fparserel &9<player one> <player two> <message>",
" &7&oParse a message with relational placeholders",

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -47,7 +47,7 @@ public final class CommandInfo extends PlaceholderCommand {
}
final PlaceholderExpansion expansion = plugin.getLocalExpansionManager()
.findExpansionByName(params.get(0)).orElse(null);
.findExpansionByIdentifier(params.get(0)).orElse(null);
if (expansion == null) {
Msg.msg(sender,
"&cThere is no expansion loaded with the identifier: &f" + params.get(0));

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,6 +22,7 @@ package me.clip.placeholderapi.commands.impl.local;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Stream;
import me.clip.placeholderapi.PlaceholderAPI;
@ -29,7 +30,6 @@ import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.clip.placeholderapi.util.Msg;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
@ -49,7 +49,7 @@ public final class CommandParse extends PlaceholderCommand {
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
@NotNull final CommandSender sender, @NotNull final String alias,
@NotNull @Unmodifiable final List<String> params) {
switch (alias.toLowerCase()) {
switch (alias.toLowerCase(Locale.ROOT)) {
case "parserel":
evaluateParseRelation(sender, params);
break;
@ -69,7 +69,7 @@ public final class CommandParse extends PlaceholderCommand {
public void complete(@NotNull final PlaceholderAPIPlugin plugin,
@NotNull final CommandSender sender, @NotNull final String alias,
@NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) {
switch (alias.toLowerCase()) {
switch (alias.toLowerCase(Locale.ROOT)) {
case "parserel":
completeParseRelation(params, suggestions);
break;
@ -92,7 +92,7 @@ public final class CommandParse extends PlaceholderCommand {
return;
}
@NotNull final OfflinePlayer player;
OfflinePlayer player;
if ("me".equalsIgnoreCase(params.get(0))) {
if (!(sender instanceof Player)) {
@ -101,6 +101,8 @@ public final class CommandParse extends PlaceholderCommand {
}
player = ((Player) sender);
} else if ("--null".equalsIgnoreCase(params.get(0))) {
player = null;
} else {
final OfflinePlayer target = resolvePlayer(params.get(0));
if (target == null) {
@ -120,13 +122,9 @@ public final class CommandParse extends PlaceholderCommand {
}
if (broadcast) {
Msg.broadcast(message);
Bukkit.broadcastMessage(message);
} else {
if (!(sender instanceof Player)) {
Msg.msg(sender, message);
} else {
((Player) sender).spigot().sendMessage(TextComponent.fromLegacyText(message));
}
sender.sendMessage(message);
}
}
@ -153,7 +151,8 @@ public final class CommandParse extends PlaceholderCommand {
final String message = PlaceholderAPI
.setRelationalPlaceholders(((Player) targetOne), ((Player) targetTwo),
String.join(" ", params.subList(2, params.size())));
Msg.msg(sender, message);
sender.sendMessage(message);
}
@ -161,10 +160,14 @@ public final class CommandParse extends PlaceholderCommand {
@NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) {
if (params.size() <= 1) {
if (sender instanceof Player && (params.isEmpty() || "me"
.startsWith(params.get(0).toLowerCase()))) {
.startsWith(params.get(0).toLowerCase(Locale.ROOT)))) {
suggestions.add("me");
}
if ("--null".startsWith(params.get(0).toLowerCase(Locale.ROOT))) {
suggestions.add("--null");
}
final Stream<String> names = Bukkit.getOnlinePlayers().stream().map(Player::getName);
suggestByParameter(names, suggestions, params.isEmpty() ? null : params.get(0));
@ -211,13 +214,16 @@ public final class CommandParse extends PlaceholderCommand {
@Nullable
private OfflinePlayer resolvePlayer(@NotNull final String name) {
OfflinePlayer target = Bukkit.getPlayer(name);
OfflinePlayer target = Bukkit.getPlayerExact(name);
if (target == null) {
target = Bukkit.getOfflinePlayer(name); // this is probably not a great idea.
// Not the best option, but Spigot doesn't offer a good replacement (as usual)
target = Bukkit.getOfflinePlayer(name);
return target.hasPlayedBefore() ? target : null;
}
return target.hasPlayedBefore() ? target : null;
return target;
}

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -38,10 +38,6 @@ public final class PlaceholderAPIConfig {
return plugin.getConfig().getBoolean("check_updates");
}
public boolean cloudAllowUnverifiedExpansions() {
return plugin.getConfig().getBoolean("cloud_allow_unverified_expansions");
}
public boolean isCloudEnabled() {
return plugin.getConfig().getBoolean("cloud_enabled");

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -26,6 +26,13 @@ import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* This event indicates that a <b>single</b> {@link PlaceholderExpansion PlaceholderExpansion} has
* been registered in PlaceholderAPI.
*
* <p>To know when <b>all</b> Expansions have been registered, use the
* {@link me.clip.placeholderapi.events.ExpansionsLoadedEvent ExpansionsLoadedEvent} instead.
*/
public final class ExpansionRegisterEvent extends Event implements Cancellable {
@NotNull
@ -42,12 +49,27 @@ public final class ExpansionRegisterEvent extends Event implements Cancellable {
public static HandlerList getHandlerList() {
return HANDLERS;
}
/**
* The {@link PlaceholderExpansion PlaceholderExpansion} that was registered in PlaceholderAPI.
* <br>The PlaceholderExpansion will be available for use when the event
* {@link #isCancelled() was not cancelled}!
*
* @return Current instance of the registered {@link PlaceholderExpansion PlaceholderExpansion}
*/
@NotNull
public PlaceholderExpansion getExpansion() {
return expansion;
}
/**
* Indicates if this event was cancelled or not.
* <br>A cancelled Event will result in the {@link #getExpansion() PlaceholderExpansion} NOT
* being added to PlaceholderAPI's internal list and will therefore be considered not registered
* anymore.
*
* @return Whether the event has been cancelled or not.
*/
@Override
public boolean isCancelled() {
return cancelled;

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -25,12 +25,20 @@ import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* This event indicates that a {@link PlaceholderExpansion PlaceholderExpansion} has been
* unregistered by PlaceholderAPI.
*
* <p>Note that this event is triggered <b>before</b> the PlaceholderExpansion is completely
* removed.
* <br>This includes removing any Listeners, stopping active tasks and clearing the cache of
* the PlaceholderExpansion.
*/
public final class ExpansionUnregisterEvent extends Event {
@NotNull
private static final HandlerList HANDLERS = new HandlerList();
@NotNull
private final PlaceholderExpansion expansion;
@ -42,7 +50,12 @@ public final class ExpansionUnregisterEvent extends Event {
public static HandlerList getHandlerList() {
return HANDLERS;
}
/**
* The {@link PlaceholderExpansion PlaceholderExpansion} that was unregistered.
*
* @return The {@link PlaceholderExpansion PlaceholderExpansion} instance.
*/
@NotNull
public PlaceholderExpansion getExpansion() {
return expansion;

View File

@ -0,0 +1,73 @@
/*
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlaceholderAPI is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package me.clip.placeholderapi.events;
import java.util.Collections;
import java.util.List;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* This event indicated that <b>all</b> {@link PlaceholderExpansion PlaceholderExpansions} have
* been registered in PlaceholderAPI and can now be used.
* <br>This even will also be triggered whenever PlaceholderAPI gets reloaded.
*
* <p>All PlaceholderExpansions, except for those loaded by plugins, are loaded
* after Spigot triggered its ServerLoadEvent (1.13+), or after PlaceholderAPI has been enabled.
*/
public class ExpansionsLoadedEvent extends Event {
private final List<PlaceholderExpansion> expansions;
public ExpansionsLoadedEvent(List<PlaceholderExpansion> expansions) {
this.expansions = Collections.unmodifiableList(expansions);
}
/**
* Returns a unmodifiable list of {@link PlaceholderExpansion PlaceholderExpansions} that
* have been registered by PlaceholderAPI.
*
* <p><b>This list does not include manually registered PlaceholderExpansions.</b>
*
* @return List of {@link PlaceholderExpansion registered PlaceholderExpansions}.
*/
@NotNull
public final List<PlaceholderExpansion> getExpansions(){
return expansions;
}
@NotNull
private static final HandlerList HANDLERS = new HandlerList();
@NotNull
@Override
public HandlerList getHandlers() {
return HANDLERS;
}
@NotNull
public static HandlerList getHandlerList() {
return HANDLERS;
}
}

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -21,9 +21,11 @@
package me.clip.placeholderapi.expansion;
/**
* This interface allows a class which extends a {@link PlaceholderExpansion} to have the clear
* method called when the implementing expansion is unregistered from PlaceholderAPI. This is useful
* if we want to do things when the implementing hook is unregistered
* Classes implementing this interface will have a {@link #clear() clear void} that is called
* by PlaceholderAPI whenever the {@link me.clip.placeholderapi.expansion.PlaceholderExpansion PlaceholderExpansion}
* is unregistered.
*
* <p>This allows you to execute things such as clearing internal caches, saving data to files, etc.
*
* @author Ryan McCarthy
*/

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -23,9 +23,11 @@ package me.clip.placeholderapi.expansion;
import org.bukkit.entity.Player;
/**
* This interface allows a class which extends a {@link PlaceholderExpansion} to have the cleanup
* method called every time a player leaves the server. This is useful if we want to clean up after
* the player
* Classes implementing this interface will have a {@link #cleanup(Player) cleanup void} that is
* called by PlaceholderAPI whenever a Player leaves the server.
*
* <p>This can be useful for cases where you keep data of the player in a cache or similar
* and want to free up space whenever they leave.
*
* @author Ryan McCarthy
*/

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -23,18 +23,32 @@ package me.clip.placeholderapi.expansion;
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
* Implementing this interface allows {@link me.clip.placeholderapi.expansion.PlaceholderExpansion PlaceholderExpansions}
* to set a list of default configuration values through the {@link #getDefaults() getDefaults method}
* that should be added to the config.yml of PlaceholderAPI.
*
* <p>The entries will be added under {@code expansions} as their own section.
* <h2>Example:</h2>
* returning a Map with key {@code foo} and value {@code bar} will result in the following config entry:
*
* <pre><code>
* expansions:
* myexpansion:
* foo: "bar"
* </code></pre>
*
* <p><b>The configuration is set before the PlaceholderExpansion is registered!</b>
*
* @author Ryan McCarthy
*/
public interface Configurable {
/**
* This method will be called before the implementing class is registered to obtain a map of
* configuration options that the implementing class needs These paths and values will be added to
* the PlaceholderAPI config.yml in the configuration section expansions.(placeholder
* identifier).(your key): (your value)
* The map returned by this method will be used to set config options in PlaceholderAPI's config.yml.
*
* <p>The key and value pairs are set under a section named after your
* {@link me.clip.placeholderapi.expansion.PlaceholderExpansion PlaceholderExpansion} in the
* {@code expansions} section of the config.
*
* @return Map of config path / values which need to be added / removed from the PlaceholderAPI
* config.yml file

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -39,7 +39,18 @@ public enum NMSVersion {
SPIGOT_1_13_R2("v1_13_R2"),
SPIGOT_1_14_R1("v1_14_R1"),
SPIGOT_1_15_R1("v1_15_R1"),
SPIGOT_1_16_R1("v1_16_R1");
SPIGOT_1_16_R1("v1_16_R1"),
SPIGOT_1_16_R2("v1_16_R2"),
SPIGOT_1_16_R3("v1_16_R3"),
SPIGOT_1_17_R1("v1_17_R1"),
SPIGOT_1_18_R1("v1_18_R1"),
SPIGOT_1_19_R1("v1_19_R1"),
SPIGOT_1_19_R2("v1_19_R2"),
SPIGOT_1_19_R3("v1_19_R3"),
SPIGOT_1_20_R1("v1_20_R1"),
SPIGOT_1_20_R2("v1_20_R2"),
SPIGOT_1_20_R3("v1_20_R3"),
SPIGOT_1_20_R4("v1_20_R4");
private final String version;

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,7 +22,7 @@ package me.clip.placeholderapi.expansion;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.logging.Level;
import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.PlaceholderHook;
import org.bukkit.Bukkit;
@ -32,10 +32,25 @@ import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Any class extending this will be able to get registered as a PlaceholderExpansion.
* <br>The registration either happens automatically when the jar file containing a
* class extending this one is located under the {@code PlaceholderAPI/expansions}
* directory or when the {@link #register()} method is called by said class.
*/
public abstract class PlaceholderExpansion extends PlaceholderHook {
/**
* The placeholder identifier of this expansion
* The type is {@link Type#INTERNAL} by default.
* For external expansions, the type is updated on {@link me.clip.placeholderapi.expansion.manager.LocalExpansionManager#register(Class) register}.
* @since 2.11.4
*/
@ApiStatus.Internal
protected Type expansionType = Type.INTERNAL;
/**
* The placeholder identifier of this expansion. May not contain {@literal %},
* {@literal {}} or _
*
* @return placeholder identifier that is associated with this expansion
*/
@ -152,59 +167,239 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
return PlaceholderAPIPlugin.getInstance();
}
// === Configuration ===
/**
* Get the type of the expansion
*
* @return the type of the expansion
* @since 2.11.4
*/
@ApiStatus.Internal
public Type getExpansionType() {
return expansionType;
}
/**
* Set the type of the expansion
* @param expansionType the new type
* @since 2.11.4
*/
@ApiStatus.Internal
public void setExpansionType(Type expansionType) {
this.expansionType = expansionType;
}
// === Configuration ===
/**
* Gets the ConfigurationSection of the expansion located in the config.yml of PlaceholderAPI or
* null when not specified.
* <br>You may use the {@link Configurable} interface to define default values set
*
* @return ConfigurationSection that this expansion has.
*/
@Nullable
public final ConfigurationSection getConfigSection() {
return getPlaceholderAPI().getConfig().getConfigurationSection("expansions." + getIdentifier());
}
/**
* Gets the ConfigurationSection relative to the {@link #getConfigSection() default one} set
* by the expansion or null when the default ConfigurationSection is null
*
* @param path The path to get the ConfigurationSection from. This is relative to the default section
* @return ConfigurationSection relative to the default section
*/
@Nullable
public final ConfigurationSection getConfigSection(@NotNull final String path) {
final ConfigurationSection section = getConfigSection();
return section == null ? null : section.getConfigurationSection(path);
}
/**
* Gets the Object relative to the {@link #getConfigSection() default ConfigurationSection} set
* by the expansion or the provided Default Object, when the default ConfigurationSection is null
*
* @param path The path to get the Object from. This is relative to the default section
* @param def The default Object to return when the ConfigurationSection returns null
* @return Object from the provided path or the default one provided
*/
@Nullable
@Contract("_, !null -> !null")
public final Object get(@NotNull final String path, final Object def) {
final ConfigurationSection section = getConfigSection();
return section == null ? def : section.get(path, def);
}
/**
* Gets the int relative to the {@link #getConfigSection() default ConfigurationSection} set
* by the expansion or the provided Default int, when the default ConfigurationSection is null
*
* @param path The path to get the int from. This is relative to the default section
* @param def The default int to return when the ConfigurationSection returns null
* @return int from the provided path or the default one provided
*/
public final int getInt(@NotNull final String path, final int def) {
final ConfigurationSection section = getConfigSection();
return section == null ? def : section.getInt(path, def);
}
/**
* Gets the long relative to the {@link #getConfigSection() default ConfigurationSection} set
* by the expansion or the provided Default long, when the default ConfigurationSection is null
*
* @param path The path to get the long from. This is relative to the default section
* @param def The default long to return when the ConfigurationSection returns null
* @return long from the provided path or the default one provided
*/
public final long getLong(@NotNull final String path, final long def) {
final ConfigurationSection section = getConfigSection();
return section == null ? def : section.getLong(path, def);
}
/**
* Gets the double relative to the {@link #getConfigSection() default ConfigurationSection} set
* by the expansion or the provided Default double, when the default ConfigurationSection is null
*
* @param path The path to get the double from. This is relative to the default section
* @param def The default double to return when the ConfigurationSection returns null
* @return double from the provided path or the default one provided
*/
public final double getDouble(@NotNull final String path, final double def) {
final ConfigurationSection section = getConfigSection();
return section == null ? def : section.getDouble(path, def);
}
/**
* Gets the String relative to the {@link #getConfigSection() default ConfigurationSection} set
* by the expansion or the provided Default String, when the default ConfigurationSection is null
*
* @param path The path to get the String from. This is relative to the default section
* @param def The default String to return when the ConfigurationSection returns null. Can be null
* @return String from the provided path or the default one provided
*/
@Nullable
@Contract("_, !null -> !null")
public final String getString(@NotNull final String path, @Nullable final String def) {
final ConfigurationSection section = getConfigSection();
return section == null ? def : section.getString(path, def);
}
/**
* Gets a String List relative to the {@link #getConfigSection() default ConfigurationSection} set
* by the expansion or an empty List, when the default ConfigurationSection is null
*
* @param path The path to get the String list from. This is relative to the default section
* @return String list from the provided path or an empty list
*/
@NotNull
public final List<String> getStringList(@NotNull final String path) {
final ConfigurationSection section = getConfigSection();
return section == null ? Collections.emptyList() : section.getStringList(path);
}
/**
* Gets the boolean relative to the {@link #getConfigSection() default ConfigurationSection} set
* by the expansion or the default boolean, when the default ConfigurationSection is null
*
* @param path The path to get the boolean from. This is relative to the default section
* @param def The default boolean to return when the ConfigurationSection is null
* @return boolean from the provided path or the default one provided
*/
public final boolean getBoolean(@NotNull final String path, final boolean def) {
final ConfigurationSection section = getConfigSection();
return section == null ? def : section.getBoolean(path, def);
}
/**
* Whether the {@link #getConfigSection() default ConfigurationSection} contains the provided path
* or not. This will return {@code false} when either the default section is null, or doesn't
* contain the provided path
*
* @param path The path to check
* @return true when the default ConfigurationSection is not null and contains the path, false otherwise
*/
public final boolean configurationContains(@NotNull final String path) {
final ConfigurationSection section = getConfigSection();
return section != null && section.contains(path);
}
/**
* Logs the provided message with the provided Level in the console.
* <br>The message will be prefixed with {@link #getName() <code>[&lt;expansion name&gt;]</code>}
*
* @param level The Level at which the message should be logged with
* @param msg The message to log
*/
public void log(Level level, String msg) {
getPlaceholderAPI().getLogger().log(level, "[" + getName() + "] " + msg);
}
/**
* Logs the provided message and Throwable with the provided Level in the console.
* <br>The message will be prefixed with {@link #getName() <code>[&lt;expansion name&gt;]</code>}
*
* @param level The Level at which the message should be logged with
* @param msg The message to log
* @param throwable The Throwable to log
*/
public void log(Level level, String msg, Throwable throwable) {
getPlaceholderAPI().getLogger().log(level, "[" + getName() + "] " + msg, throwable);
}
/**
* Logs the provided message with Level "info".
* <br>The message will be prefixed with {@link #getName() <code>[&lt;expansion name&gt;]</code>}
*
* @param msg The message to log
*/
public void info(String msg) {
log(Level.INFO, msg);
}
/**
* Logs the provided message with Level "warning".
* <br>The message will be prefixed with {@link #getName() <code>[&lt;expansion name&gt;]</code>}
*
* @param msg The message to log
*/
public void warning(String msg) {
log(Level.WARNING, msg);
}
/**
* Logs the provided message with Level "severe" (error).
* <br>The message will be prefixed with {@link #getName() <code>[&lt;expansion name&gt;]</code>}
*
* @param msg The message to log
*/
public void severe(String msg) {
log(Level.SEVERE, msg);
}
/**
* Logs the provided message and Throwable with Level "severe" (error).
* <br>The message will be prefixed with {@link #getName() <code>[&lt;expansion name&gt;]</code>}
*
* @param msg The message to log
* @param throwable The Throwable to log
*/
public void severe(String msg, Throwable throwable) {
log(Level.SEVERE, msg, throwable);
}
/**
* Whether the provided Object is an instance of this PlaceholderExpansion.
* <br>This method will perform the following checks in order:
* <br><ul>
* <li>Checks if Object equals the class. Returns true when equal and continues otherwise</li>
* <li>Checks if the Object is an instance of a PlaceholderExpansion. Returns false if not</li>
* <li>Checks if the Object's Identifier, Author and version equal the one of this class</li>
* </ul>
*
* @param o The Object to check
* @return true or false depending on the above mentioned checks
*/
@Override
public final boolean equals(final Object o) {
if (this == o) {
@ -220,45 +415,65 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
getAuthor().equals(expansion.getAuthor()) &&
getVersion().equals(expansion.getVersion());
}
@Override
public final int hashCode() {
return Objects.hash(getIdentifier(), getAuthor(), 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(),
getAuthor(), getVersion());
return String.format("PlaceholderExpansion[name: '%s', author: '%s', version: '%s', type: '%s']", getName(),
getAuthor(), getVersion(), getExpansionType());
}
// === Deprecated API ===
/**
* @deprecated As of versions greater than 2.8.7, use {@link #getRequiredPlugin()}
*
* @return The plugin name.
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public String getPlugin() {
return null;
}
/**
* @deprecated As of versions greater than 2.8.7, use the expansion cloud to show a description
*
* @return The description of the expansion.
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public String getDescription() {
return null;
}
/**
* @deprecated As of versions greater than 2.8.7, use the expansion cloud to display a link
*
* @return The link for the expansion.
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
@ApiStatus.ScheduledForRemoval(inVersion = "2.13.0")
public String getLink() {
return null;
}
public enum Type {
/**
* An expansion provided by a plugin is considered internal
*/
INTERNAL,
/**
* An expansion loaded from the expansions folder is considered external
*/
EXTERNAL
}
}

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,7 +22,22 @@ package me.clip.placeholderapi.expansion;
import org.bukkit.entity.Player;
/**
* Implementing this interface allows your {@link me.clip.placeholderapi.expansion.PlaceholderExpansion PlaceholderExpansion}
* to be used as a relational placeholder expansion.
*
* <p>Relational placeholders take two Players as input and are always prefixed with {@code rel_},
* so {@code %foo_bar%} becomes {@code %rel_foo_bar%}
*/
public interface Relational {
/**
* This method is called whenever a placeholder starting with {@code rel_} is called.
*
* @param one The first player used for the placeholder.
* @param two The second player used for the placeholder.
* @param identifier The text right after the expansion's name (%expansion_<b>identifier</b>%)
* @return Parsed String from the expansion.
*/
String onPlaceholderRequest(Player one, Player two, String identifier);
}

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -20,18 +20,24 @@
package me.clip.placeholderapi.expansion;
/**
* Implementing this interface adds the {@link #start() start} and {@link #stop() stop} void
* methods to your {@link me.clip.placeholderapi.expansion.PlaceholderExpansion PlaceholderExpansion}.
*
* <p>This can be used to execute methods and tasks whenever the PlaceholderExpansion has been
* successfully (un)registered.
*/
public interface Taskable {
/**
* Called when the implementing class has successfully been registered to the placeholder map
* Tasks that need to be performed when this expansion is registered should go here
* Called when the implementing class has successfully been registered to the placeholder map.
* <br>Tasks that need to be performed when this expansion is registered should go here
*/
void start();
/**
* Called when the implementing class has been unregistered from PlaceholderAPI Tasks that need to
* be performed when this expansion has unregistered should go here
* Called when the implementing class has been unregistered from PlaceholderAPI.
* <br>Tasks that need to be performed when this expansion has unregistered should go here
*/
void stop();
}

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -20,6 +20,7 @@
package me.clip.placeholderapi.expansion;
@Deprecated
public final class Version {
private final boolean isSpigot;

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -27,13 +27,18 @@ package me.clip.placeholderapi.expansion;
* with that version.
*
* @author Ryan McCarthy
*
* @deprecated Will be removed in a future release.
*/
@Deprecated
public interface VersionSpecific {
/**
* This method is called before the expansion is attempted to be registered The server version
* will be passed to this method so you know what version the server is currently running.
*
* @param v The {@link Version} to check against
*
* @return true if your expansion is compatible with the version the server is running.
*/
boolean isCompatibleWith(Version v);

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -171,7 +171,7 @@ public class CloudExpansion {
this.versions = versions;
}
public class Version {
public static class Version {
private String url, version, release_notes;

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,6 +22,7 @@ package me.clip.placeholderapi.expansion.manager;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.Resources;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.File;
@ -32,14 +33,19 @@ import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Function;
import java.util.logging.Level;
import java.util.stream.Collector;
@ -47,6 +53,7 @@ import java.util.stream.Collectors;
import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
import me.clip.placeholderapi.util.Msg;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable;
@ -73,6 +80,9 @@ public final class CloudExpansionManager {
@NotNull
private final Map<String, CompletableFuture<File>> await = new ConcurrentHashMap<>();
private final ExecutorService ASYNC_EXECUTOR =
Executors.newCachedThreadPool(
new ThreadFactoryBuilder().setNameFormat("placeholderapi-io-#%1$d").build());
public CloudExpansionManager(@NotNull final PlaceholderAPIPlugin plugin) {
this.plugin = plugin;
@ -80,7 +90,7 @@ public final class CloudExpansionManager {
@NotNull
private static String toIndexName(@NotNull final String name) {
return name.toLowerCase().replace(' ', '_');
return name.toLowerCase(Locale.ROOT).replace(' ', '_');
}
@NotNull
@ -90,7 +100,7 @@ public final class CloudExpansionManager {
public void load() {
clean();
fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions());
fetch();
}
public void kill() {
@ -160,61 +170,71 @@ public final class CloudExpansionManager {
await.clear();
}
public void fetch(final boolean allowUnverified) {
public void fetch() {
plugin.getLogger().info("Fetching available expansion information...");
CompletableFuture<Map<String, CloudExpansion>> future = CompletableFuture.supplyAsync(() -> {
final Map<String, CloudExpansion> values = new HashMap<>();
ASYNC_EXECUTOR.submit(
() -> {
// a defence tactic! use ConcurrentHashMap instead of normal HashMap
Map<String, CloudExpansion> values = new ConcurrentHashMap<>();
try {
//noinspection UnstableApiUsage
String json = Resources.toString(new URL(API_URL), StandardCharsets.UTF_8);
values.putAll(GSON.fromJson(json, TYPE));
try {
//noinspection UnstableApiUsage
final String json = Resources.toString(new URL(API_URL), StandardCharsets.UTF_8);
values.putAll(GSON.fromJson(json, TYPE));
} catch (final IOException ex) {
throw new CompletionException(ex);
}
List<String> toRemove = new ArrayList<>();
values.values().removeIf(value -> value.getLatestVersion() == null
|| value.getVersion(value.getLatestVersion()) == null);
for (Map.Entry<String, CloudExpansion> entry : values.entrySet()) {
CloudExpansion expansion = entry.getValue();
if (expansion.getLatestVersion() == null
|| expansion.getVersion(expansion.getLatestVersion()) == null) {
toRemove.add(entry.getKey());
}
}
return values;
});
for (String name : toRemove) {
values.remove(name);
}
} catch (Throwable e) {
// ugly swallowing of every throwable, but we have to be defensive
plugin.getLogger().log(Level.WARNING, "Failed to download expansion information", e);
}
if (!allowUnverified) {
future = future.thenApplyAsync((values) -> {
values.values().removeIf(expansion -> !expansion.isVerified());
return values;
});
}
// loop through what's left on the main thread
plugin
.getServer()
.getScheduler()
.runTask(
plugin,
() -> {
try {
for (Map.Entry<String, CloudExpansion> entry : values.entrySet()) {
String name = entry.getKey();
CloudExpansion expansion = entry.getValue();
future = future.thenApplyAsync((values) -> {
expansion.setName(name);
values.forEach((name, expansion) -> {
expansion.setName(name);
Optional<PlaceholderExpansion> localOpt =
plugin.getLocalExpansionManager().findExpansionByName(name);
if (localOpt.isPresent()) {
PlaceholderExpansion local = localOpt.get();
if (local.isRegistered()) {
expansion.setHasExpansion(true);
expansion.setShouldUpdate(
!local.getVersion().equalsIgnoreCase(expansion.getLatestVersion()));
}
}
final Optional<PlaceholderExpansion> local = plugin.getLocalExpansionManager()
.findExpansionByName(name);
if (local.isPresent() && local.get().isRegistered()) {
expansion.setHasExpansion(true);
expansion.setShouldUpdate(!local.get().getVersion().equals(expansion.getLatestVersion()));
}
});
return values;
});
future.whenComplete((expansions, exception) -> {
if (exception != null) {
plugin.getLogger()
.log(Level.WARNING, "failed to download expansion information", exception);
return;
}
for (final CloudExpansion expansion : expansions.values()) {
this.cache.put(toIndexName(expansion), expansion);
}
});
cache.put(toIndexName(expansion), expansion);
}
} catch (Throwable e) {
// ugly swallowing of every throwable, but we have to be defensive
plugin
.getLogger()
.log(Level.WARNING, "Failed to download expansion information", e);
}
});
});
}
public boolean isDownloading(@NotNull final CloudExpansion expansion) {
@ -240,16 +260,15 @@ public final class CloudExpansionManager {
throw new CompletionException(ex);
}
return file;
});
}, ASYNC_EXECUTOR);
download.whenCompleteAsync((value, exception) -> {
await.remove(toIndexName(expansion));
if (exception != null) {
plugin.getLogger().log(Level.SEVERE,
"failed to download " + expansion.getName() + ":" + version.getVersion(), exception);
Msg.severe("Failed to download %s:%s", exception, expansion.getName(), expansion.getVersion());
}
});
}, ASYNC_EXECUTOR);
await.put(toIndexName(expansion), download);

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -20,22 +20,28 @@
package me.clip.placeholderapi.expansion.manager;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import java.io.File;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.logging.Level;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.events.ExpansionRegisterEvent;
import me.clip.placeholderapi.events.ExpansionUnregisterEvent;
import me.clip.placeholderapi.events.ExpansionsLoadedEvent;
import me.clip.placeholderapi.expansion.Cacheable;
import me.clip.placeholderapi.expansion.Cleanable;
import me.clip.placeholderapi.expansion.Configurable;
@ -65,6 +71,11 @@ public final class LocalExpansionManager implements Listener {
@NotNull
private static final String EXPANSIONS_FOLDER_NAME = "expansions";
@NotNull
private static final Set<MethodSignature> ABSTRACT_EXPANSION_METHODS = Arrays.stream(PlaceholderExpansion.class.getDeclaredMethods())
.filter(method -> Modifier.isAbstract(method.getModifiers()))
.map(method -> new MethodSignature(method.getName(), method.getParameterTypes()))
.collect(Collectors.toSet());
@NotNull
private final File folder;
@ -72,7 +83,8 @@ public final class LocalExpansionManager implements Listener {
private final PlaceholderAPIPlugin plugin;
@NotNull
private final Map<String, PlaceholderExpansion> expansions = new HashMap<>();
private final Map<String, PlaceholderExpansion> expansions = new ConcurrentHashMap<>();
private final ReentrantLock expansionsLock = new ReentrantLock();
public LocalExpansionManager(@NotNull final PlaceholderAPIPlugin plugin) {
@ -80,7 +92,7 @@ public final class LocalExpansionManager implements Listener {
this.folder = new File(plugin.getDataFolder(), EXPANSIONS_FOLDER_NAME);
if (!this.folder.exists() && !folder.mkdirs()) {
plugin.getLogger().log(Level.WARNING, "failed to create expansions folder!");
Msg.warn("Failed to create expansions folder!");
}
}
@ -98,31 +110,54 @@ public final class LocalExpansionManager implements Listener {
return folder;
}
public int getExpansionsCount() {
return expansions.size();
}
@NotNull
@Unmodifiable
public Collection<String> getIdentifiers() {
return ImmutableSet.copyOf(expansions.keySet());
expansionsLock.lock();
try {
return ImmutableSet.copyOf(expansions.keySet());
} finally {
expansionsLock.unlock();
}
}
@NotNull
@Unmodifiable
public Collection<PlaceholderExpansion> getExpansions() {
return ImmutableSet.copyOf(expansions.values());
expansionsLock.lock();
try {
return ImmutableSet.copyOf(expansions.values());
} finally {
expansionsLock.unlock();
}
}
@Nullable
public PlaceholderExpansion getExpansion(@NotNull final String identifier) {
return ImmutableMap.copyOf(expansions).get(identifier.toLowerCase());
expansionsLock.lock();
try {
return expansions.get(identifier.toLowerCase(Locale.ROOT));
} finally {
expansionsLock.unlock();
}
}
@NotNull
public Optional<PlaceholderExpansion> findExpansionByName(@NotNull final String name) {
return getExpansions().stream().filter(expansion -> name.equalsIgnoreCase(expansion.getName())).findFirst();
expansionsLock.lock();
try {
PlaceholderExpansion bestMatch = null;
for (Map.Entry<String, PlaceholderExpansion> entry : expansions.entrySet()) {
PlaceholderExpansion expansion = entry.getValue();
if (expansion.getName().equalsIgnoreCase(name)) {
bestMatch = expansion;
break;
}
}
return Optional.ofNullable(bestMatch);
} finally {
expansionsLock.unlock();
}
}
@NotNull
@ -136,31 +171,65 @@ public final class LocalExpansionManager implements Listener {
@NotNull final Class<? extends PlaceholderExpansion> clazz) {
try {
final PlaceholderExpansion expansion = createExpansionInstance(clazz);
if (expansion == null || !expansion.register()) {
if(expansion == null){
return Optional.empty();
}
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.getRequiredPlugin() != null && !expansion.getRequiredPlugin().isEmpty()) {
if (!Bukkit.getPluginManager().isPluginEnabled(expansion.getRequiredPlugin())) {
Msg.warn("Cannot load expansion %s due to a missing plugin: %s", expansion.getIdentifier(),
expansion.getRequiredPlugin());
return Optional.empty();
}
}
expansion.setExpansionType(PlaceholderExpansion.Type.EXTERNAL);
if (!expansion.register()) {
Msg.warn("Cannot load expansion %s due to an unknown issue.", expansion.getIdentifier());
return Optional.empty();
}
return Optional.of(expansion);
} catch (final LinkageError ex) {
plugin.getLogger().severe("expansion class " + clazz.getSimpleName() + " is outdated: \n" +
"Failed to load due to a [" + ex.getClass().getSimpleName() + "], attempted to use " + 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!";
}
Msg.severe("Failed to load expansion class %s%s", ex, clazz.getSimpleName(), reason);
}
return Optional.empty();
}
/**
* Do not call this method yourself, use {@link PlaceholderExpansion#register()}
* Attempt to register a {@link PlaceholderExpansion}
* @param expansion the expansion to register
* @return if the expansion was registered
*/
@ApiStatus.Internal
public boolean register(@NotNull final PlaceholderExpansion expansion) {
final String identifier = expansion.getIdentifier().toLowerCase();
final String identifier = expansion.getIdentifier().toLowerCase(Locale.ROOT);
if (!expansion.canRegister()) {
return false;
}
// Avoid loading two external expansions with the same identifier
if (expansion.getExpansionType() == PlaceholderExpansion.Type.EXTERNAL && expansions.containsKey(identifier)) {
Msg.warn("Failed to load external expansion %s. Identifier is already in use.", expansion.getIdentifier());
return false;
}
if (expansion instanceof Configurable) {
Map<String, Object> defaults = ((Configurable) expansion).getDefaults();
String pre = "expansions." + identifier + ".";
@ -196,14 +265,13 @@ public final class LocalExpansionManager implements Listener {
if (expansion instanceof VersionSpecific) {
VersionSpecific nms = (VersionSpecific) expansion;
if (!nms.isCompatibleWith(PlaceholderAPIPlugin.getServerVersion())) {
plugin.getLogger().info(
"Your server version is not compatible with expansion: " + expansion.getIdentifier()
+ " version: " + expansion.getVersion());
Msg.warn("Your server version is incompatible with expansion %s %s",
expansion.getIdentifier(), expansion.getVersion());
return false;
}
}
final PlaceholderExpansion removed = expansions.get(identifier);
final PlaceholderExpansion removed = getExpansion(identifier);
if (removed != null && !removed.unregister()) {
return false;
}
@ -215,37 +283,44 @@ public final class LocalExpansionManager implements Listener {
return false;
}
expansions.put(identifier, expansion);
expansionsLock.lock();
try {
expansions.put(identifier, expansion);
} finally {
expansionsLock.unlock();
}
if (expansion instanceof Listener) {
Bukkit.getPluginManager().registerEvents(((Listener) expansion), plugin);
}
plugin.getLogger().info("Successfully registered expansion: " + expansion.getIdentifier());
Msg.info(
"Successfully registered %s expansion: %s [%s]",
expansion.getExpansionType().name().toLowerCase(),
expansion.getIdentifier(),
expansion.getVersion()
);
if (expansion instanceof Taskable) {
((Taskable) expansion).start();
}
if (plugin.getPlaceholderAPIConfig().isCloudEnabled()) {
final Optional<CloudExpansion> cloudExpansion = plugin.getCloudExpansionManager()
.findCloudExpansionByName(identifier);
if (cloudExpansion.isPresent()) {
cloudExpansion.get().setHasExpansion(true);
cloudExpansion.get().setShouldUpdate(
!cloudExpansion.get().getLatestVersion().equals(expansion.getVersion()));
// Check eCloud for updates only if the expansion is external
if (plugin.getPlaceholderAPIConfig().isCloudEnabled() && expansion.getExpansionType() == PlaceholderExpansion.Type.EXTERNAL) {
final Optional<CloudExpansion> cloudExpansionOptional = plugin.getCloudExpansionManager().findCloudExpansionByName(identifier);
if (cloudExpansionOptional.isPresent()) {
CloudExpansion cloudExpansion = cloudExpansionOptional.get();
cloudExpansion.setHasExpansion(true);
cloudExpansion.setShouldUpdate(!cloudExpansion.getLatestVersion().equals(expansion.getVersion()));
}
}
return true;
}
/**
* Do not call this method yourself, use {@link PlaceholderExpansion#unregister()}
*/
@ApiStatus.Internal
public boolean unregister(@NotNull final PlaceholderExpansion expansion) {
if (expansions.remove(expansion.getIdentifier()) == null) {
if (expansions.remove(expansion.getIdentifier().toLowerCase(Locale.ROOT)) == null) {
return false;
}
@ -274,22 +349,45 @@ public final class LocalExpansionManager implements Listener {
return true;
}
private void registerAll(@NotNull final CommandSender sender) {
plugin.getLogger().info("Placeholder expansion registration initializing...");
Msg.info("Placeholder expansion registration initializing...");
Futures.onMainThread(plugin, findExpansionsOnDisk(), (classes, exception) -> {
if (exception != null) {
plugin.getLogger().log(Level.SEVERE, "failed to load class files of expansions", exception);
Msg.severe("Failed to load class files of expansion.", exception);
return;
}
final List<PlaceholderExpansion> registered = classes.stream()
.filter(Objects::nonNull)
.map(this::register)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
final long registered = classes.stream().map(this::register).filter(Optional::isPresent)
final long needsUpdate = registered.stream()
.map(expansion -> plugin.getCloudExpansionManager().findCloudExpansionByName(expansion.getName()).orElse(null))
.filter(Objects::nonNull)
.filter(CloudExpansion::shouldUpdate)
.count();
Msg.msg(sender,
registered == 0 ? "&6No expansions were registered!"
: registered + "&a placeholder hooks successfully registered!");
StringBuilder message = new StringBuilder(registered.size() == 0 ? "&6" : "&a")
.append(registered.size())
.append(' ')
.append("placeholder hook(s) registered!");
if (needsUpdate > 0) {
message.append(' ')
.append("&6")
.append(needsUpdate)
.append(' ')
.append("placeholder hook(s) have an update available.");
}
Msg.msg(sender, message.toString());
Bukkit.getPluginManager().callEvent(new ExpansionsLoadedEvent(registered));
});
}
@ -303,10 +401,14 @@ public final class LocalExpansionManager implements Listener {
}
}
@NotNull
public CompletableFuture<@NotNull List<@NotNull Class<? extends PlaceholderExpansion>>> findExpansionsOnDisk() {
return Arrays.stream(folder.listFiles((dir, name) -> name.endsWith(".jar")))
public CompletableFuture<@NotNull List<@Nullable Class<? extends PlaceholderExpansion>>> findExpansionsOnDisk() {
File[] files = folder.listFiles((dir, name) -> name.endsWith(".jar"));
if (files == null) {
return CompletableFuture.completedFuture(Collections.emptyList());
}
return Arrays.stream(files)
.map(this::findExpansionInFile)
.collect(Futures.collector());
}
@ -316,14 +418,29 @@ public final class LocalExpansionManager implements Listener {
@NotNull final File file) {
return CompletableFuture.supplyAsync(() -> {
try {
return FileUtil.findClass(file, PlaceholderExpansion.class);
} catch (final VerifyError ex) {
plugin.getLogger().severe("expansion file " + file.getName() + " is outdated: \n" +
"Failed to load due to a [" + ex.getClass().getSimpleName() + "], attempted to use" + ex
.getMessage().substring(ex.getMessage().lastIndexOf(' ')));
final Class<? extends PlaceholderExpansion> expansionClass = FileUtil.findClass(file, PlaceholderExpansion.class);
if (expansionClass == null) {
Msg.severe("Failed to load expansion %s, as it does not have a class which"
+ " extends PlaceholderExpansion", file.getName());
return null;
}
Set<MethodSignature> expansionMethods = Arrays.stream(expansionClass.getDeclaredMethods())
.map(method -> new MethodSignature(method.getName(), method.getParameterTypes()))
.collect(Collectors.toSet());
if (!expansionMethods.containsAll(ABSTRACT_EXPANSION_METHODS)) {
Msg.severe("Failed to load expansion %s, as it does not have the required"
+ " methods declared for a PlaceholderExpansion.", file.getName());
return null;
}
return expansionClass;
} catch (VerifyError | NoClassDefFoundError e) {
Msg.severe("Failed to load expansion %s (is a dependency missing?)", e, file.getName());
return null;
} catch (final Exception ex) {
throw new CompletionException(ex);
} catch (Exception e) {
throw new CompletionException(e.getMessage() + " (expansion file: " + file.getAbsolutePath() + ")", e);
}
});
}
@ -338,10 +455,8 @@ public final class LocalExpansionManager implements Listener {
if (ex.getCause() instanceof LinkageError) {
throw ((LinkageError) ex.getCause());
}
plugin.getLogger()
.log(Level.SEVERE, "Failed to load placeholder expansion from class: " + clazz.getName(),
ex);
Msg.warn("There was an issue with loading an expansion.");
return null;
}
}
@ -371,7 +486,8 @@ public final class LocalExpansionManager implements Listener {
}
expansion.unregister();
plugin.getLogger().info("Unregistered placeholder expansion: " + expansion.getName());
Msg.info("Unregistered placeholder expansion %s", expansion.getIdentifier());
Msg.info("Reason: required plugin %s was disabled.", name);
}
}

View File

@ -0,0 +1,57 @@
/*
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlaceholderAPI is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package me.clip.placeholderapi.expansion.manager;
import java.util.Arrays;
import java.util.Objects;
public final class MethodSignature {
private final String name;
private final Class<?>[] params;
protected MethodSignature(String name, Class<?>[] params) {
this.name = name;
this.params = params;
}
public String getName() {
return name;
}
public Class<?>[] getParams() {
return params;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MethodSignature that = (MethodSignature) o;
return Objects.equals(name, that.name) && Arrays.equals(params, that.params);
}
@Override
public int hashCode() {
int result = Objects.hash(name);
result = 31 * result + Arrays.hashCode(params);
return result;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -39,16 +39,6 @@ public final class ServerLoadEventListener implements Listener {
Bukkit.getPluginManager().registerEvents(this, plugin);
}
/**
* This method will be called when the server is first loaded
* <p>
* The goal of the method is to register all the expansions as soon as possible especially before
* players can join
* <p>
* This will ensure no issues with expansions and hooks.
*
* @param event the server load event
*/
@EventHandler
public void onServerLoad(@NotNull final ServerLoadEvent event) {
HandlerList.unregisterAll(this);

View File

@ -1,174 +1,137 @@
/*
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlaceholderAPI is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package me.clip.placeholderapi.replacer;
import java.util.function.Function;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public final class CharsReplacer implements Replacer {
@NotNull
private final Closure closure;
public CharsReplacer(@NotNull final Closure closure) {
this.closure = closure;
}
@NotNull
@Override
public String apply(@NotNull final String text, @Nullable final OfflinePlayer player,
@NotNull final Function<String, @Nullable PlaceholderExpansion> lookup) {
final char[] chars = text.toCharArray();
final StringBuilder builder = new StringBuilder(text.length());
final StringBuilder identifier = new StringBuilder();
final StringBuilder parameters = new StringBuilder();
for (int i = 0; i < chars.length; i++) {
final char l = chars[i];
if (l == '&' && ++i < chars.length) {
final char c = Character.toLowerCase(chars[i]);
if (c != '0' && c != '1' && c != '2' && c != '3' && c != '4' && c != '5' && c != '6'
&& c != '7' && c != '8' && c != '9' && c != 'a' && c != 'b' && c != 'c' && c != 'd'
&& c != 'e' && c != 'f' && c != 'k' && c != 'l' && c != 'm' && c != 'n' && c != 'o' && c != 'r'
&& c != 'x') {
builder.append(l).append(chars[i]);
} else {
builder.append(ChatColor.COLOR_CHAR);
if (c != 'x') {
builder.append(chars[i]);
continue;
}
if ((i > 1 && chars[i - 2] == '\\') /*allow escaping &x*/) {
builder.setLength(builder.length() - 2);
builder.append('&').append(chars[i]);
continue;
}
builder.append(c);
int j = 0;
while (++j <= 6) {
if (i + j >= chars.length) {
break;
}
final char x = chars[i + j];
builder.append(ChatColor.COLOR_CHAR).append(x);
}
if (j == 7) {
i += 6;
} else {
builder.setLength(builder.length() - (j * 2)); // undo &x parsing
}
}
continue;
}
if (l != closure.head || i + 1 >= chars.length) {
builder.append(l);
continue;
}
boolean identified = false;
boolean oopsitsbad = true;
while (++i < chars.length) {
final char p = chars[i];
if (p == ' ' && !identified) {
break;
}
if (p == closure.tail) {
oopsitsbad = false;
break;
}
if (p == '_' && !identified) {
identified = true;
continue;
}
if (identified) {
parameters.append(p);
} else {
identifier.append(p);
}
}
final String identifierString = identifier.toString().toLowerCase();
final String parametersString = parameters.toString();
identifier.setLength(0);
parameters.setLength(0);
if (oopsitsbad) {
builder.append(closure.head).append(identifierString);
if (identified) {
builder.append('_').append(parametersString);
}
builder.append(' ');
continue;
}
final PlaceholderExpansion placeholder = lookup.apply(identifierString);
if (placeholder == null) {
builder.append(closure.head).append(identifierString);
if (identified) {
builder.append('_');
}
builder.append(parametersString).append(closure.tail);
continue;
}
final String replacement = placeholder.onRequest(player, parametersString);
if (replacement == null) {
builder.append(closure.head).append(identifierString);
if (identified) {
builder.append('_');
}
builder.append(parametersString).append(closure.tail);
continue;
}
builder.append(ChatColor.translateAlternateColorCodes('&', replacement));
}
return builder.toString();
}
}
/*
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlaceholderAPI is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package me.clip.placeholderapi.replacer;
import java.util.Locale;
import java.util.function.Function;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public final class CharsReplacer implements Replacer {
@NotNull
private final Closure closure;
public CharsReplacer(@NotNull final Closure closure) {
this.closure = closure;
}
@NotNull
@Override
public String apply(@NotNull final String text, @Nullable final OfflinePlayer player,
@NotNull final Function<String, @Nullable PlaceholderExpansion> lookup) {
final char[] chars = text.toCharArray();
final StringBuilder builder = new StringBuilder(text.length());
final StringBuilder identifier = new StringBuilder();
final StringBuilder parameters = new StringBuilder();
for (int i = 0; i < chars.length; i++) {
final char l = chars[i];
if (l != closure.head || i + 1 >= chars.length) {
builder.append(l);
continue;
}
boolean identified = false;
boolean invalid = true;
boolean hadSpace = false;
while (++i < chars.length) {
final char p = chars[i];
if (p == ' ' && !identified) {
hadSpace = true;
break;
}
if (p == closure.tail) {
invalid = false;
break;
}
if (p == '_' && !identified) {
identified = true;
continue;
}
if (identified) {
parameters.append(p);
} else {
identifier.append(p);
}
}
final String identifierString = identifier.toString();
final String lowercaseIdentifierString = identifierString.toLowerCase(Locale.ROOT);
final String parametersString = parameters.toString();
identifier.setLength(0);
parameters.setLength(0);
if (invalid) {
builder.append(closure.head).append(identifierString);
if (identified) {
builder.append('_').append(parametersString);
}
if (hadSpace) {
builder.append(' ');
}
continue;
}
final PlaceholderExpansion placeholder = lookup.apply(lowercaseIdentifierString);
if (placeholder == null) {
builder.append(closure.head).append(identifierString);
if (identified) {
builder.append('_');
}
builder.append(parametersString).append(closure.tail);
continue;
}
final String replacement = placeholder.onRequest(player, parametersString);
if (replacement == null) {
builder.append(closure.head).append(identifierString);
if (identified) {
builder.append('_');
}
builder.append(parametersString).append(closure.tail);
continue;
}
builder.append(replacement);
}
return builder.toString();
}
}

View File

@ -1,72 +0,0 @@
/*
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlaceholderAPI is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package me.clip.placeholderapi.replacer;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public final class RegexReplacer implements Replacer {
@NotNull
private final Pattern pattern;
public RegexReplacer(@NotNull final Closure closure) {
this.pattern = Pattern.compile(String
.format("\\%s((?<identifier>[a-zA-Z0-9]+)_)(?<parameters>[^%s%s]+)\\%s", closure.head,
closure.head, closure.tail, closure.tail));
}
@NotNull
@Override
public String apply(@NotNull final String text, @Nullable final OfflinePlayer player,
@NotNull final Function<String, @Nullable PlaceholderExpansion> lookup) {
final Matcher matcher = pattern.matcher(text);
if (!matcher.find()) {
return text;
}
final StringBuffer builder = new StringBuffer();
do {
final String identifier = matcher.group("identifier");
final String parameters = matcher.group("parameters");
final PlaceholderExpansion expansion = lookup.apply(identifier);
if (expansion == null) {
continue;
}
final String requested = expansion.onRequest(player, parameters);
matcher.appendReplacement(builder, requested != null ? requested : matcher.group(0));
}
while (matcher.find());
return ChatColor.translateAlternateColorCodes('&', matcher.appendTail(builder).toString());
}
}

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -23,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)

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -20,6 +20,9 @@
package me.clip.placeholderapi.util;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.net.URL;
@ -28,8 +31,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class FileUtil {
@ -41,17 +42,15 @@ public class FileUtil {
}
final URL jar = file.toURI().toURL();
final URLClassLoader loader = new URLClassLoader(new URL[]{jar}, clazz.getClassLoader());
final List<String> matches = new ArrayList<>();
final List<Class<? extends T>> 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();
if (name == null || name.isEmpty() || !name.endsWith(".class")) {
if (name.isEmpty() || !name.endsWith(".class")) {
continue;
}
@ -68,8 +67,11 @@ public class FileUtil {
}
}
}
return classes.isEmpty() ? null : classes.get(0);
if (classes.isEmpty()) {
loader.close();
return null;
}
return classes.get(0);
}
}

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -50,7 +50,7 @@ public final class Format {
}
@NotNull
private static String buildFormat(@NotNull final Align align, @NotNull final int[] spacing) {
private static String buildFormat(@NotNull final Align align, final int[] spacing) {
return stream(spacing)
.mapToObj(space -> "%" + (align == Align.LEFT ? "-" : "") + (space + 2) + "s")
.collect(joining());

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -21,14 +21,40 @@
package me.clip.placeholderapi.util;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.stream.Collectors;
import me.clip.placeholderapi.PlaceholderAPIPlugin;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
public final class Msg {
public static void log(Level level, String msg, Object... args) {
PlaceholderAPIPlugin.getInstance().getLogger().log(level, String.format(msg, args));
}
public static void info(String msg, Object... args) {
log(Level.INFO, msg, args);
}
public static void warn(String msg, Object... args) {
log(Level.WARNING, msg, args);
}
public static void warn(String msg, Throwable throwable, Object... args){
PlaceholderAPIPlugin.getInstance().getLogger().log(Level.WARNING, String.format(msg, args), throwable);
}
public static void severe(String msg, Object... args) {
log(Level.SEVERE, msg, args);
}
public static void severe(String msg, Throwable throwable, Object... args) {
PlaceholderAPIPlugin.getInstance().getLogger().log(Level.SEVERE, String.format(msg, args), throwable);
}
public static void msg(@NotNull final CommandSender sender, @NotNull final String... messages) {
if (messages.length == 0) {
return;

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,150 +22,75 @@ package me.clip.placeholderapi.util;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.StringJoiner;
public class TimeUtil {
public static String getRemaining(int seconds, TimeFormat type) {
if (seconds < 60) {
switch (type) {
case DAYS:
case HOURS:
case MINUTES:
return "0";
case SECONDS:
return String.valueOf(seconds);
}
return String.valueOf(seconds);
}
int minutes = seconds / 60;
int s = 60 * minutes;
int secondsLeft = seconds - s;
if (minutes < 60) {
switch (type) {
case DAYS:
case HOURS:
return "0";
case MINUTES:
return String.valueOf(minutes);
case SECONDS:
return String.valueOf(secondsLeft);
}
return String.valueOf(seconds);
}
if (minutes < 1440) {
int hours = minutes / 60;
int inMins = 60 * hours;
int leftOver = minutes - inMins;
switch (type) {
case DAYS:
return "0";
case HOURS:
return String.valueOf(hours);
case MINUTES:
return String.valueOf(leftOver);
case SECONDS:
return String.valueOf(secondsLeft);
}
return String.valueOf(seconds);
}
int days = minutes / 1440;
int inMins = 1440 * days;
int leftOver = minutes - inMins;
if (leftOver < 60) {
switch (type) {
case DAYS:
return String.valueOf(days);
case HOURS:
return String.valueOf(0);
case MINUTES:
return String.valueOf(leftOver);
case SECONDS:
return String.valueOf(secondsLeft);
}
return String.valueOf(seconds);
} else {
int hours = leftOver / 60;
int hoursInMins = 60 * hours;
int minsLeft = leftOver - hoursInMins;
switch (type) {
case DAYS:
return String.valueOf(days);
case HOURS:
return String.valueOf(hours);
case MINUTES:
return String.valueOf(minsLeft);
case SECONDS:
return String.valueOf(secondsLeft);
}
return String.valueOf(seconds);
}
public static String getRemaining(final int seconds, final TimeFormat type) {
return getRemaining((long) seconds, type);
}
public static String getTime(int seconds) {
return getTime(Duration.ofSeconds(seconds));
public static String getRemaining(final long seconds, final TimeFormat type) {
switch (type) {
default:
return String.valueOf(seconds);
case SECONDS:
return String.valueOf(seconds % 60);
case MINUTES:
return String.valueOf((seconds / 60) % 60);
case HOURS:
return String.valueOf((seconds / 3600) % 24);
case DAYS:
return String.valueOf(seconds / 86400);
}
}
/**
* Format the given value with s, m, h and d (seconds, minutes, hours and days)
*
* @param duration {@link Duration} (eg, Duration.of(20, {@link ChronoUnit#SECONDS}) for 20
* seconds)
* seconds)
* @return formatted time
*/
public static String getTime(final Duration duration) {
final StringBuilder builder = new StringBuilder();
return getTime(duration.getSeconds());
}
public static String getTime(final int seconds) {
return getTime((long) seconds);
}
public static String getTime(long seconds) {
final StringJoiner joiner = new StringJoiner(" ");
long seconds = duration.getSeconds();
long minutes = seconds / 60;
long hours = minutes / 60;
long days = hours / 24;
final long days = hours / 24;
seconds %= 60;
minutes %= 60;
hours %= 60;
days %= 24;
hours %= 24;
if (seconds > 0) {
builder.insert(0, seconds + "s");
}
if (minutes > 0) {
if (builder.length() > 0) {
builder.insert(0, ' ');
}
builder.insert(0, minutes + "m");
if (days > 0) {
joiner.add(days + "d");
}
if (hours > 0) {
if (builder.length() > 0) {
builder.insert(0, ' ');
}
builder.insert(0, hours + "h");
joiner.add(hours + "h");
}
if (days > 0) {
if (builder.length() > 0) {
builder.insert(0, ' ');
}
builder.insert(0, days + "d");
if (minutes > 0) {
joiner.add(minutes + "m");
}
return builder.toString();
if (seconds > 0) {
joiner.add(seconds + "s");
}
return joiner.toString();
}
}

View File

@ -1,17 +1,16 @@
# PlaceholderAPI
# Version: @version@
# Version: ${version}
# Created by: extended_clip
# Contributors: https://github.com/PlaceholderAPI/PlaceholderAPI/graphs/contributors
# Issues: https://github.com/PlaceholderAPI/PlaceholderAPI/issues
# Expansions: https://api.extendedclip.com/all/
# Wiki: https://github.com/PlaceholderAPI/PlaceholderAPI/wiki
# Expansions: https://placeholderapi.com/ecloud
# Wiki: https://wiki.placeholderapi.com/
# Discord: https://helpch.at/discord
# No placeholders are provided with this plugin by default.
# Download placeholders: /papi ecloud
check_updates: true
cloud_enabled: true
cloud_sorting: "name"
cloud_allow_unverified_expansions: false
boolean:
'true': 'yes'
'false': 'no'

View File

@ -1,11 +1,11 @@
name: "@name@"
name: PlaceholderAPI
main: "me.clip.placeholderapi.PlaceholderAPIPlugin"
version: "@version@"
version: ${version}
author: HelpChat
api-version: "1.13"
description: "@description@"
description: "An awesome placeholder provider!"
commands:
placeholderapi:
@ -37,7 +37,6 @@ permissions:
placeholderapi.ecloud.info: true
placeholderapi.ecloud.list: true
placeholderapi.ecloud.clear: true
placeholderapi.ecloud.toggle: true
placeholderapi.ecloud.status: true
placeholderapi.ecloud.update: true
placeholderapi.ecloud.refresh: true
@ -82,9 +81,6 @@ permissions:
placeholderapi.ecloud.clear:
default: "op"
description: "Allows you to clear the local eCloud expansion cache"
placeholderapi.ecloud.toggle:
default: "op"
description: "Allows you to toggle/enable/disable the eCloud manager"
placeholderapi.ecloud.status:
default: "op"
description: "Allows you to view the status of eCloud expansions"
@ -99,4 +95,4 @@ permissions:
description: "Allows you to download an expansion from the eCloud"
placeholderapi.ecloud.placeholders:
default: "op"
description: "Allows you to view the placeholders of a eCloud expansion"
description: "Allows you to view the placeholders of a eCloud expansion"

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -23,7 +23,6 @@ package me.clip.placeholderapi;
import com.google.common.collect.ImmutableMap;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.clip.placeholderapi.replacer.CharsReplacer;
import me.clip.placeholderapi.replacer.RegexReplacer;
import me.clip.placeholderapi.replacer.Replacer;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
@ -40,7 +39,6 @@ public interface Values {
Replacer CHARS_REPLACER = new CharsReplacer(Replacer.Closure.PERCENT);
Replacer REGEX_REPLACER = new RegexReplacer(Replacer.Closure.PERCENT);
final class MockPlayerPlaceholderExpansion extends PlaceholderExpansion {

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -30,19 +30,9 @@ public class ReplacerBenchmarks {
Values.CHARS_REPLACER.apply(Values.SMALL_TEXT, null, Values.PLACEHOLDERS::get);
}
@Benchmark
public void measureRegexReplacerSmallText() {
Values.REGEX_REPLACER.apply(Values.SMALL_TEXT, null, Values.PLACEHOLDERS::get);
}
@Benchmark
public void measureCharsReplacerLargeText() {
Values.CHARS_REPLACER.apply(Values.LARGE_TEXT, null, Values.PLACEHOLDERS::get);
}
@Benchmark
public void measureRegexReplacerLargeText() {
Values.REGEX_REPLACER.apply(Values.LARGE_TEXT, null, Values.PLACEHOLDERS::get);
}
}

View File

@ -2,7 +2,7 @@
* This file is part of PlaceholderAPI
*
* PlaceholderAPI
* Copyright (c) 2015 - 2020 PlaceholderAPI Team
* Copyright (c) 2015 - 2024 PlaceholderAPI Team
*
* PlaceholderAPI free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -37,12 +37,6 @@ public final class ReplacerUnitTester {
Values.CHARS_REPLACER.apply("%player_name%", null, Values.PLACEHOLDERS::get));
}
@Test
void testRegexReplacerProducesExpectedSingleValue() {
assertEquals(PLAYER_NAME,
Values.REGEX_REPLACER.apply("%player_name%", null, Values.PLACEHOLDERS::get));
}
@Test
void testCharsReplacerProducesExpectedSentence() {
assertEquals(String.format(
@ -51,36 +45,14 @@ public final class ReplacerUnitTester {
Values.CHARS_REPLACER.apply(Values.LARGE_TEXT, null, Values.PLACEHOLDERS::get));
}
@Test
void testRegexReplacerProducesExpectedSentence() {
assertEquals(String.format(
"My name is %s and my location is (%s, %s, %s), this placeholder is invalid %%server_name%%",
PLAYER_NAME, PLAYER_X, PLAYER_Y, PLAYER_Z),
Values.REGEX_REPLACER.apply(Values.LARGE_TEXT, null, Values.PLACEHOLDERS::get));
}
@Test
void testResultsAreTheSameAsReplacement() {
final String resultChars = Values.CHARS_REPLACER
.apply("%player_name%", null, Values.PLACEHOLDERS::get);
final String resultRegex = Values.REGEX_REPLACER
.apply("%player_name%", null, Values.PLACEHOLDERS::get);
assertEquals(resultChars, resultRegex);
assertEquals(PLAYER_NAME, resultChars);
}
@Test
void testResultsAreTheSameNoReplacement() {
final String resultChars = Values.CHARS_REPLACER
.apply("%player_location%", null, Values.PLACEHOLDERS::get);
final String resultRegex = Values.REGEX_REPLACER
.apply("%player_location%", null, Values.PLACEHOLDERS::get);
assertEquals(resultChars, resultRegex);
}
@Test
void testCharsReplacerIgnoresMalformed() {
final String text = "10% and %hello world 15%";
@ -88,12 +60,4 @@ public final class ReplacerUnitTester {
assertEquals(text, Values.CHARS_REPLACER.apply(text, null, Values.PLACEHOLDERS::get));
}
@Test
void testCharsReplacerHandlesEscapedHex() {
final String text = "\\&xffffffThis should not change.";
assertEquals(text.substring(1),
Values.CHARS_REPLACER.apply(text, null, Values.PLACEHOLDERS::get));
}
}

View File

@ -1,239 +0,0 @@
This page shows all commands, including with a detailed description of what every command does.
## Overview
- **[Parse Commands](#parse-commands)**
- [`/papi bcparse <player|me> <string>`](#papi-bcparse)
- [`/papi cmdparse <player|me> <string>`](#papi-cmdparse)
- [`/papi parse <player|me> <string>`](#papi-parse)
- [`/papi parserel <player> <player> <string>`](#papi-parserel)
- **[eCloud Commands](#ecloud-commands)**
- [`/papi ecloud clear`](#papi-ecloud-clear)
- [`/papi ecloud disable`](#papi-ecloud-disable)
- [`/papi ecloud download <expansion> [version]`](#papi-ecloud-download)
- [`/papi ecloud enable`](#papi-ecloud-enable)
- [`/papi ecloud info <expansion> [version]`](#papi-ecloud-info)
- [`/papi ecloud list <all|<author>|installed>`](#papi-ecloud-list)
- [`/papi ecloud placeholders <expansion>`](#papi-ecloud-placeholders)
- [`/papi ecloud refresh`](#papi-ecloud-refresh)
- [`/papi ecloud status`](#papi-ecloud-status)
- **[Expansion Commands](#expansion-commands)**
- [`/papi info <expansion>`](#papi-info)
- [`/papi list`](#papi-list)
- [`/papi register <jar file>`](#papi-register)
- [`/papi unregister <jar file>`](#papi-unregister)
- **[Other Commands](#other-commands)**
- [`/papi dump`](#papi-dump)
- [`/papi reload`](#papi-reload)
----
### Parse Commands
These commands are used to parse placeholders into their respective values. Useful for debugging.
#### `/papi bcparse`
**Description**:
Parses placeholders of a String and broadcasts the result to all players.
**Arguments**:
* `<player|me>` - The Player to parse values of the placeholder (Use `me` for yourself).
* `<Text with placeholders>` - The text to parse.
**Example**:
```
/papi bcparse funnycube My name is %player_name%!
```
----
#### `/papi cmdparse`
**Description**:
Parses placeholders of a String and executes it as a command.
**Arguments**:
- `<player|me>` - The player to parse placeholders against. Use `me` for yourself.
- `<Command with placeholders>` - The Text to parse and execute as command. Please leave away the `/` of the command.
**Example**:
```
/papi cmdparse funnycube say My name is %player_name%!
```
----
#### `/papi parse`
**Description**:
Parses the placeholders in a given text and shows the result.
**Arguments**:
* `<player|me>` - The Player to parse values of the placeholder (Use `me` for yourself).
* `<Text with placeholders>` - The text to parse.
**Example**:
```
/papi parse funnycube My group is %vault_group%
```
----
#### `/papi parserel`
**Description**:
Parses a relational placeholder.
**Arguments**:
* `<player1>` - The first player.
* `<player2>` - the second player to compare with.
* `<Text with placeholders>` - The actual placeholder to parse.
**Example**:
```
/papi parserel funnycube extended_clip %placeholder%
```
----
### eCloud Commands
These commands all start with `/papi ecloud` and are used for things related about the [[Expansion Cloud]].
#### `/papi ecloud clear`
**Description**:
Clears the cache for the eCloud.
----
#### `/papi ecloud disable`
**Description**:
Disables the connection to the eCloud.
----
#### `/papi ecloud download`
**Description**:
Allows you to download an expansion from the eCloud
**Arguments**:
- `<expansion>` - The expansion to download.
- `[version]` - The specific version of the expansion to download (Optional)
**Example**:
```
/papi ecloud download Vault
/papi ecloud download Vault 1.5.2
```
----
#### `/papi ecloud enable`
**Description**:
Enables the connection to the eCloud
----
#### `/papi ecloud info`
**Description**:
Gives information about a specific Expansion.
**Arguments**:
- `<expansion>` - The Expansion to retrieve information from.
- `[version]` - The Expansion's version to get information from.
**Example**:
```
/papi ecloud info Vault
```
----
#### `/papi ecloud list`
**Description**:
Lists either all Expansions on the eCloud, only those by a specific author or only those that you have [installed](#papi-ecloud-download).
Installed Expansions show as green in the list and Expansions that are installed and have an update available show as gold.
**Arguments**:
- `<all|<author>|installed>` - List all Expansions, Expansions of a specific author or all Expnansions you have installed.
**Example**:
```
/papi ecloud list all
/papi ecloud list clip
/papi ecloud list installed
```
----
#### `/papi ecloud placeholders`
**Description**:
List all placeholders of an Expansion.
**Arguments**:
- `<expansion>` - The Expansion to list placeholders of.
**Example**:
```
/papi ecloud placeholders Vault
```
----
#### `/papi ecloud refresh`
**Description**:
Refresh the cached data from the eCloud.
----
#### `/papi ecloud status`
**Description**:
Displays the actual Status of the eCloud.
----
### Expansion Commands
These commands can be used to manage the expansions that you have currently installed.
#### `/papi info`
**Description**:
Gives you information about the specified Expansion.
**Argument(s)**:
- `<expansion>` - The Expansion to get info from (Needs to be registered and active).
**Example**:
```
/papi info Vault
```
----
#### `/papi list`
**Description**:
Lists all active/registered expansions.
This is different to [/papi ecloud list installed](#papi-ecloud-list) in the fact, that it also includes expansions that were installed through a plugin (That aren't a separate jar-file) and it also doesn't show which one have updates available.
----
#### `/papi register`
**Description**:
Registers an expansion from a specified filename.
This is useful in cases, where you downloaded the expansion manually and don't want to restart the server.
The file needs to be inside `/plugins/PlaceholderAPI/expansions`.
**Arguments**:
- `<filename>` - The file to register (including the file-extension).
**Example**:
```
/papi register MyExpansion.jar
```
----
#### `/papi unregister`
**Description**:
Unregisters the specified expansion.
**Arguments**:
- `<filename>` - The expansion to unregister.
**Example**:
```
/papi unregister MyExpansion.jar
```
----
### Other Commands
These are other commands of PlaceholderAPI that don't fit any of the above categories.
#### `/papi dump`
**Description**:
Pastes useful information from PlaceholderAPI such as plugin version, server version and installed expansions to https://paste.helpch.at for simple sharing and support.
#### `/papi reload`
**Description**:
Reloads the config settings.
You need to use this command after [downloading Expansions](#papi-ecloud-download) from the eCloud or they won't be properly registered.

View File

@ -1,67 +0,0 @@
## About
PlaceholderAPI uses an expansion-cloud (A website that has all kinds of expansions stored), to download jar-files, that contain the placeholders for it to use.
The expansion-cloud can be seen under https://api.extendedclip.com/home
## How it works
PlaceholderAPI connects to the ecloud on startup of your server, to check if the cloud is available and how many expansions are available on it.
If you run `/papi ecloud download <expansion>` PlaceholderAPI will connect to the site to first check if the specified expansion exists and then downloads it if it does.
Note that not all listed expansions are on the ecloud. Some are in the corresponding plugin itself and are registered on the startup of the server.
You can disable the connection to the cloud by setting `cloud_enabled` in the config.yml to false.
## Adding your own expansion
You can add your own expansion to the expansion-cloud for others to use.
In order to do that, you have to follow those steps:
1. Make sure you have created a seperate jar-file like explained on the page [[PlaceholderExpansion]].
2. Create an account on the site, or log in, if you already have one.
3. Click on `Expansions` and then on [`Upload New`](https://api.extendedclip.com/manage/add/).
4. Fill out the required information. `Source URL` and `Dependency URL` are optional.
5. Click on the button that says `Choose an file...` and select the jar of your expansion.
* **Important**! Make sure, that the name of the jar-file contains the same version like you set in the version-field!
6. Click on `Submit Expansion`
Your expansion is now uploaded and will be reviewed by a moderator.
If everything is ok will your expansion be approved and will be available on the ecloud for PlaceholderAPI*.
> *You can only download verified Expansions through PlaceholderAPIs command, unless you enable the option `cloud_allow_unverified_expansions` in the config.yml
> Unverified expansions can be downloaded manually by going to the site and download it yourself.
## Updating your expansion
Before you update, please note the following:
If you aren't a verified dev and you upload an update, your expansion will become **unverified** until a moderator reviews the update and approves it!
It is recommended to only update the expansion, if it contains huge changes or bug fixes.
To update your expansion, you first have to go to the list of [your expansions](https://api.extendedclip.com/manage/).
For that click on `Expansions` and select `Your Expansions`.
After that, follow those steps:
1. Click the name of the expansion, that you want to update.
2. Click on the button that says `Version`
3. Click on `Add Version`
4. Fill out the fields and upload the new jar.
* **Important**! Make sure, that the name of the jar-file contains the same version like you set in the version-field!
5. Click on `Save Changes`
If you're a verified dev, your version will be approved and is available directly.
If you aren't a verified dev, you have to wait until a moderator approves the update.
## Downloading a specific expansion version
In some cases, you may want to use a specific, older version of expansion. Such a case could be for example, when you run an old server version and the newest version of an expansion uses methods that aren't available on that particular server version.
For that case is there a way, to download a specific version of expansion. You can download the expansion either manually, or through PlaceholderAPI itself.
Here is how you can do it for each.
### Download with PlaceholderAPI
This is the easiest of both methods since it requires the least amount of effort.
Run the following command in-game or in your console to download a specific version:
`/papi ecloud download <expansion> [version]`
To find out, what versions are available for the expansion, run `/papi ecloud info <expansion>`
You can then run `/papi ecloud versioninfo <expansion> <version>` to receive more infor about a specific version.
After you downloaded the specific version, run `/papi reload` to refresh the installed expansions.
### Download manually
To download an expansion manually, you first have to connect to the website and go to the expansion of your choice.
There, you click on the button that says `Version` and click on the download-icon of the version you want to download.
Finally, stop your server, upload the jar to the folder in `/plugins/PlaceholderAPI/expansions` (Make sure to delete the old jar, if there's already one) and start the server again.

View File

@ -1,22 +0,0 @@
Here are frequently asked questions about stuff related to PlaceholderAPI.
## It only shows %placeholder% and not the variable
Make sure, that you've tried the following steps:
- PlaceholderAPI is installed and running (Shows green in `/pl` and responds to the `/papi` command)
- You downloaded the expansion with `/papi ecloud download [expansion]`
A list of available expansions and their placeholders can be found [[here|Placeholders]]!
Also note that not all placeholders are in a seperate expansion. Some are "hardcoded" into a plugin.
- You reloaded PlaceholderAPI with `/papi reload` after downloading an expansion.
- Any possible dependency for the expansion (Plugin) is installed and running.
- The placeholder doesn't contain any typos.
- The plugin that should use the placeholder actually supports PlaceholderAPI.
For a list of plugins supporting PlaceholderAPI go [[here|Plugins-using-PlaceholderAPI]].
## I can't download the expansion
Make sure, that the connection to the cloud (https://api.extendedclip.com) isn't blocked by a firewall or similar.
Next step would be to check if the expansion actually exists on the cloud. Not all plugins provide their placeholders through a separate jar on the cloud. Some have them build in and register them on startup.
If both checks failed, go to the cloud-page and download the jar manually. Put it then in the `expansions` folder of PlaceholderAPI (`/plugins/PlaceholderAPI/expansions`)
## How can other plugins use my placeholders with PlaceholderAPI?
A tutorial can be found [[here|Hook into PlaceholderAPI]]!

View File

@ -1,78 +0,0 @@
<p align="center">
<img src="https://i.imgur.com/puadJ8Z.png" alt="PlaceholderAPI">
</p>
This wiki gives you information on how to create placeholders in your plugin that can be used in other plugins, how to use other placeholders inside your plugin, or how to make an expansion.
It also has a list with all available placeholders (Work in progress).
### Setup
**[[Hook into PlaceholderAPI]]**
- [[First steps|Hook-into-PlaceholderAPI#first-steps]]
- [[Adding placeholders to PlaceholderAPI|Hook-into-PlaceholderAPI#adding-placeholders-to-placeholderapi]]
- [[PlaceholderExpansion]]
- [[Without an external plugin|PlaceholderExpansion#without-an-external-plugin]]
- [[With external plugin|PlaceholderExpansion#with-external-plugin]]
- [[Setting placeholders in your plugin|Hook-into-PlaceholderAPI#setting-placeholders-in-your-plugin]]
### Other
**[[Commands]]**
**[[Expansion cloud]]**
**[[FAQ]]**
**[[Plugins using PlaceholderAPI]]**
**[[Placeholders]]**
- [[PAPI-placeholders|Placeholders#papi-placeholders-1]]
- [[Advancements|Placeholders#advancements]]
- [[Animations|Placeholders#animations]]
- [[Armor|Placeholders#armor]]
- [[ASCII|Placeholders#ASCII]]
- [[BungeeCord|Placeholders#bungeecord]]
- [[CheckItem|Placeholders#checkitem]]
- [[CooldownBar|Placeholders#cooldownbar]]
- [[Formatter|Placeholders#formatter]]
- [[Javascript|Placeholders#javascript]]
- [[ListPlayers|Placeholders#listplayer]]
- [[LocalTime|Placeholders#localtime]]
- [[Math|Placeholders#math]]
- [[MVdW placeholders|Placeholders#mvdw-placeholders]]
- [[OtherPlayer|Placeholders#otherplayer]]
- [[ParseNear|Placeholders#parsenear]]
- [[ParseOther|Placeholders#parseother]]
- [[Pinger|Placeholders#pinger]]
- [[Player|Placeholders#player]]
- [[PlayerList|Placeholders#playerlist]]
- [[Plugin|Placeholders#plugin]]
- [[Progress|Placeholders#progress]]
- [[RainbowColor|Placeholders#rainbowcolor]]
- [[RandomColor|Placeholders#randomcolor]]
- [[RedisBungee|Placeholders#redisbungee]]
- [[RelCon|Placeholders#relcon]]
- [[ScoreboardObjectives|Placeholders#scoreboardobjectives]]
- [[Server|Placeholders#server]]
- [[Sound|Placeholders#sound]]
- [[Spectators|Placeholders#spectators]]
- [[Statistic|Placeholders#statistic]]
- [[Plugin-placeholders|Placeholders#plugin-placeholders-1]]
- [[A|Placeholders#a]]
- [[B|Placeholders#b]]
- [[C|Placeholders#c]]
- [[D|Placeholders#d]]
- [[E|Placeholders#e]]
- [[F|Placeholders#f]]
- [[G|Placeholders#g]]
- [[H|Placeholders#h]]
- [[I|Placeholders#i]]
- [[J|Placeholders#j]]
- [[K|Placeholders#k]]
- [[L|Placeholders#l]]
- [[M|Placeholders#m]]
- [[N|Placeholders#n]]
- [[O|Placeholders#o]]
- [[P|Placeholders#p]]
- [[Q|Placeholders#q]]
- [[R|Placeholders#r]]
- [[S|Placeholders#s]]
- [[T|Placeholders#t]]
- [[U|Placeholders#u]]
- [[V|Placeholders#v]]
- [[W|Placeholders#w]]
- [[Z|Placeholders#z]]

View File

@ -1,142 +0,0 @@
[APIBadge]: https://img.shields.io/nexus/r/http/repo.extendedclip.com/me.clip/placeholderapi.svg?label=API-Version
[SpigotBadge]: https://img.shields.io/spiget/version/6245?label=Spigot
[Spigot]: https://spigotmc.org/resources/6245
[GitHubBadge]: https://img.shields.io/github/v/release/PlaceholderAPI/PlaceholderAPI?label=GitHub%20Release
[GitHub]: /PlaceholderAPI/PlaceholderAPI/releases/latest
> [![SpigotBadge]][Spigot] [![GitHubBadge]][GitHub]
>
> ![APIBadge]
>
> *The GitHub release may be different from the spigot release*
This page is about using PlaceholderAPI in your own plugin, to either let other plugins use your plugin, or just use placeholders from other plugins in your own.
Please note, that the examples in this page are only available for **PlaceholderAPI 2.10.0 or higher**!
## First steps
Before you can actually make use of PlaceholderAPI, you first have to import it into your project.
### Import with Maven
To import PlaceholderAPI, simply add the following code to your **pom.xml**
Replace `{VERSION}` with the version listed at the top of this page.
```xml
<repositories>
<repository>
<id>placeholderapi</id>
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>{VERSION}</version>
<scope>provided</scope>
</dependency>
</dependencies>
```
### Import with Gradle
Here is how you can import PlaceholderAPI through gradle.
Put this into your **Gradle.build**.
Replace `{VERSION}` with the version listed at the top of this page.
```gradle
repositories {
maven {
url = 'https://repo.extendedclip.com/content/repositories/placeholderapi/'
}
}
dependencies {
compileOnly 'me.clip:placeholderapi:{VERSION}'
}
```
### Set PlaceholderAPI as (soft)depend
Next step is to go to your plugin.yml and add PlaceholderAPI as a depend or softdepend, depending (no pun intended) on if it is optional or not.
**Example Softdepend**:
```yaml
name: ExamplePlugin
version: 1.0
author: author
main: your.main.path.here
softdepend: [PlaceholderAPI] # This is used, if your plugin works without PlaceholderAPI.
```
**Example Depend**:
```yaml
name: ExamplePlugin
version: 1.0
author: author
main: your.main.path.here
depend: [PlaceholderAPI] # If your plugin requires PlaceholderAPI, to work, use this.
```
## Adding placeholders to PlaceholderAPI
A full guide on how to create expansions can be found on the [[PlaceholderExpansion]] page of this wiki.
## Setting placeholders in your plugin
PlaceholderAPI offers the ability, to automatically parse placeholders from other plugins within your own plugin, giving the ability for your plugin to support thousands of other placeholders without depending on each plugin individually.
To use placeholders from other plugins in our own plugin, we simply have to [(soft)depend on PlaceholderAPI](#set-placeholderapi-as-softdepend) and use the `setPlaceholders` method.
It is also important to point out, that any required plugin/dependency for an expansion has to be on the server and enabled, or the `setPlaceholders` method will just return the placeholder itself (do nothing).
**Example**:
Let's assume we want to send an own join message that shows the group a player has.
To achieve that, we can do the following:
```java
package at.helpch.placeholderapi;
import me.clip.placeholderapi.PlaceholderAPI;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.java.JavaPlugin;
import me.clip.placeholderapi.PlaceholderAPI;
public class JoinExample extends JavaPlugin implements Listener {
@Override
public void onEnable() {
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
/*
* We register the EventListener here, when PlaceholderAPI is installed.
* Since all events are in the main class (this class), we simply use "this"
*/
Bukkit.getPluginManager().registerEvents(this, this);
} else {
/*
* We inform about the fact that PlaceholderAPI isn't installed and then
* disable this plugin to prevent issues.
*/
getLogger().warn("Could not find PlaceholderAPI! This plugin is required.");
Bukkit.getPluginManager().disablePlugin(this);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onJoin(PlayerJoinEvent event) {
String joinText = "%player_name% &ajoined the server! They are rank &f%vault_rank%";
/*
* We parse the placeholders using "setPlaceholders"
* This would turn %vault_rank% into the name of the Group, that the
* joining player has.
*/
joinText = PlaceholderAPI.setPlaceholders(event.getPlayer(), joinText);
event.setJoinMessage(withPlaceholdersSet);
}
}
```

View File

@ -1,411 +0,0 @@
## Overview
This page covers how you can use the `PlaceholderExpansion` to add own placeholders to PlaceholderAPI, which then can be used by other plugins.
PlaceholderAPI is using Expansions for its placeholders, with PlaceholderAPI providing the core. Users can download Expansions from the cloud server using commands in-game or by going [here](https://api.extendedclip.com/home/) if they want to use the placeholder.
## Note
You can either make a separate jar file, to upload it to the expansion-cloud (recommended) or have it as a local class inside your plugin.
## Examples
There are multiple methods and ways you can use the PlaceholderExpansion.
Those depend on what you want to display through the placeholders in the end.
* [Without external plugin](#without-external-plugin)
* [With external plugin](#with-external-plugin)
* [Separate jar](#separate-jar)
* [Internal class](#internal-class)
### Without an external plugin
This part here covers how you create an expansion that doesn't require any external/additional plugins to function.
Examples of such expansions are:
- [Player expansion](/PlaceholderAPI/Player-Expansion)
- [Math expansion](https://github.com/Andre601/Math-Expansion)
- [Statistics expansion](/PlaceholderAPI/Statistics-Expansion)
Since it would be weird (and also make no real sense) to have this inside your plugin, we assume you make a separate jar-file as an expansion.
To begin, first make the class extend the `PlaceholderExpansion` and add the required methods:
```java
package at.helpch.placeholderapi.example.expansions;
import org.bukkit.OfflinePlayer;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
/**
* This class will automatically register as a placeholder expansion
* when a jar including this class is added to the directory
* {@code /plugins/PlaceholderAPI/expansions} on your server.
* <br>
* <br>If you create such a class inside your own plugin, you have to
* register it manually in your plugins {@code onEnable()} by using
* {@code new YourExpansionClass().register();}
*/
public class SomeExpansion extends PlaceholderExpansion {
/**
* This method should always return true unless we
* have a dependency we need to make sure is on the server
* for our placeholders to work!
*
* @return always true since we do not have any dependencies.
*/
@Override
public boolean canRegister(){
return true;
}
/**
* The name of the person who created this expansion should go here.
*
* @return The name of the author as a String.
*/
@Override
public String getAuthor(){
return "someauthor";
}
/**
* The placeholder identifier should go here.
* <br>This is what tells PlaceholderAPI to call our onRequest
* method to obtain a value if a placeholder starts with our
* identifier.
* <br>This must be unique and can not contain % or _
*
* @return The identifier in {@code %<identifier>_<value>%} as String.
*/
@Override
public String getIdentifier(){
return "example";
}
/**
* This is the version of this expansion.
* <br>You don't have to use numbers, since it is set as a String.
*
* @return The version as a String.
*/
@Override
public String getVersion(){
return "1.0.0";
}
/**
* This is the method called when a placeholder with our identifier
* is found and needs a value.
* <br>We specify the value identifier in this method.
* <br>Since version 2.9.1 can you use OfflinePlayers in your requests.
*
* @param player
* A {@link org.bukkit.OfflinePlayer OfflinePlayer}.
* @param identifier
* A String containing the identifier/value.
*
* @return Possibly-null String of the requested identifier.
*/
@Override
public String onRequest(OfflinePlayer player, String identifier){
// %example_placeholder1%
if(identifier.equals("placeholder1")){
return "placeholder1 works";
}
// %example_placeholder2%
if(identifier.equals("placeholder2")){
return "placeholder2 works";
}
// We return null if an invalid placeholder (f.e. %example_placeholder3%)
// was provided
return null;
}
}
```
----
### With external plugin
Those examples here applies to people who want to provide information from their own plugin through placeholders from PlaceholderAPI.
There exists a repository showcasing an [example-expansion](/PlaceholderAPI/Example-Expansion) with what you can/should do.
In our examples do we have the plugin `SomePlugin` and want to show certain placeholders with it.
There are two ways to actually get information from your plugin and they only are different in if you have the expansion as a separate jar-file or as an internal class.
#### Separate jar
In our separate jar do we have to make some checks, to be sure, that the required plugin is installed and running.
The below code shows how the class can look like in case the plugin doesn't have a public and easy to access API.
```java
package at.helpch.placeholderapi.example.expansions;
import org.bukkit.OfflinePlayer;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import at.helpch.placeholderapi.example.SomePlugin;
/**
* This class will automatically register as a placeholder expansion
* when a jar including this class is added to the directory
* {@code /plugins/PlaceholderAPI/expansions} on your server.
* <br>
* <br>If you create such a class inside your own plugin, you have to
* register it manually in your plugins {@code onEbale()} by using
* {@code new YourExpansionClass().register();}
*/
public class SomeExpansion extends PlaceholderExpansion {
// We get an instance of the plugin later.
private SomePlugin plugin;
/**
* Since this expansion requires api access to the plugin "SomePlugin"
* we must check if said plugin is on the server or not.
*
* @return true or false depending on if the required plugin is installed.
*/
@Override
public boolean canRegister(){
return (plugin = (SomePlugin) Bukkit.getPluginManager().getPlugin(getRequiredPlugin())) != null;
}
/**
* The name of the person who created this expansion should go here.
*
* @return The name of the author as a String.
*/
@Override
public String getAuthor(){
return "someauthor";
}
/**
* The placeholder identifier should go here.
* <br>This is what tells PlaceholderAPI to call our onRequest
* method to obtain a value if a placeholder starts with our
* identifier.
* <br>This must be unique and can not contain % or _
*
* @return The identifier in {@code %<identifier>_<value>%} as String.
*/
@Override
public String getIdentifier(){
return "someplugin";
}
/**
* if the expansion requires another plugin as a dependency, the
* proper name of the dependency should go here.
* <br>Set this to {@code null} if your placeholders do not require
* another plugin to be installed on the server for them to work.
* <br>
* <br>This is extremely important to set your plugin here, since if
* you don't do it, your expansion will throw errors.
*
* @return The name of our dependency.
*/
@Override
public String getRequiredPlugin(){
return "SomePlugin";
}
/**
* This is the version of this expansion.
* <br>You don't have to use numbers, since it is set as a String.
*
* @return The version as a String.
*/
@Override
public String getVersion(){
return "1.0.0";
}
/**
* This is the method called when a placeholder with our identifier
* is found and needs a value.
* <br>We specify the value identifier in this method.
* <br>Since version 2.9.1 can you use OfflinePlayers in your requests.
*
* @param player
* A {@link org.bukkit.Player Player}.
* @param identifier
* A String containing the identifier/value.
*
* @return possibly-null String of the requested identifier.
*/
@Override
public String onPlaceholderRequest(Player player, String identifier){
if(p == null){
return "";
}
// %someplugin_placeholder1%
if(identifier.equals("placeholder1")){
return plugin.getConfig().getString("placeholder1", "value doesnt exist");
}
// %someplugin_placeholder2%
if(identifier.equals("placeholder2")){
return plugin.getConfig().getString("placeholder2", "value doesnt exist");
}
// We return null if an invalid placeholder (f.e. %someplugin_placeholder3%)
// was provided
return null;
}
}
```
----
#### Internal class
You can have the class inside your plugin.
This has some advantages but can also have some disadvantages.
If you include a PlaceholderExpansion class in your plugin, you MUST add an override the persist() method to return true
otherwise, if PlaceholderAPI is reloaded, your expansion will be unregistered and lost forever.
```java
package at.helpch.placeholderapi.example.expansions;
import org.bukkit.OfflinePlayer;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import at.helpch.placeholderapi.example.SomePlugin;
/**
* This class will be registered through the register-method in the
* plugins onEnable-method.
*/
public class SomeExpansion extends PlaceholderExpansion {
private SomePlugin plugin;
/**
* Since we register the expansion inside our own plugin, we
* can simply use this method here to get an instance of our
* plugin.
*
* @param plugin
* The instance of our plugin.
*/
public SomeExpansion(SomePlugin plugin){
this.plugin = plugin;
}
/**
* Because this is an internal class,
* you must override this method to let PlaceholderAPI know to not unregister your expansion class when
* PlaceholderAPI is reloaded
*
* @return true to persist through reloads
*/
@Override
public boolean persist(){
return true;
}
/**
* Because this is a internal class, this check is not needed
* and we can simply return {@code true}
*
* @return Always true since it's an internal class.
*/
@Override
public boolean canRegister(){
return true;
}
/**
* The name of the person who created this expansion should go here.
* <br>For convienience do we return the author from the plugin.yml
*
* @return The name of the author as a String.
*/
@Override
public String getAuthor(){
return plugin.getDescription().getAuthors().toString();
}
/**
* The placeholder identifier should go here.
* <br>This is what tells PlaceholderAPI to call our onRequest
* method to obtain a value if a placeholder starts with our
* identifier.
* <br>This must be unique and can not contain % or _
*
* @return The identifier in {@code %<identifier>_<value>%} as String.
*/
@Override
public String getIdentifier(){
return "someplugin";
}
/**
* This is the version of the expansion.
* <br>You don't have to use numbers, since it is set as a String.
*
* For convienience do we return the version from the plugin.yml
*
* @return The version as a String.
*/
@Override
public String getVersion(){
return plugin.getDescription().getVersion();
}
/**
* This is the method called when a placeholder with our identifier
* is found and needs a value.
* <br>We specify the value identifier in this method.
* <br>Since version 2.9.1 can you use OfflinePlayers in your requests.
*
* @param player
* A {@link org.bukkit.Player Player}.
* @param identifier
* A String containing the identifier/value.
*
* @return possibly-null String of the requested identifier.
*/
@Override
public String onPlaceholderRequest(Player player, String identifier){
if(player == null){
return "";
}
// %someplugin_placeholder1%
if(identifier.equals("placeholder1")){
return plugin.getConfig().getString("placeholder1", "value doesnt exist");
}
// %someplugin_placeholder2%
if(identifier.equals("placeholder2")){
return plugin.getConfig().getString("placeholder2", "value doesnt exist");
}
// We return null if an invalid placeholder (f.e. %someplugin_placeholder3%)
// was provided
return null;
}
}
```
As you can see is this method pretty similar to the one without any external plugins, since we can get an instance of our plugin much easier and also have a 100% guarantee that the plugin is installed and running.
Our final step now is to register the class and its placeholders. The plugin doesn't do this on its own.
To achieve this, add the following to your `onEnable()` section (Use your expansion name of course):
```java
package at.helpch.placeholderapi.example
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
public class SomePlugin extends JavaPlugin{
@Override
public void onEnable(){
// Small check to make sure that PlaceholderAPI is installed
if(Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null){
new SomeExpansion(this).register();
}
}
}
```

File diff suppressed because it is too large Load Diff

View File

@ -1,947 +0,0 @@
This here is a list of all plugins supporting PlaceholderAPI by either having their own placeholders added, or just allowing other placeholders to be used.
If your plugin isn't shown here and you want it to be added, [open an issue](/PlaceholderAPI/PlaceholderAPI/issues/new?template=change_request_wiki.md) and we will add it!
## Plugins
* **[A](#a)**
* **[B](#b)**
* **[C](#c)**
* **[D](#d)**
* **[E](#e)**
* **[F](#f)**
* **[G](#g)**
* **[H](#h)**
* **[I](#i)**
* **[J](#j)**
* **[K](#k)**
* **[L](#l)**
* **[M](#m)**
* **[N](#n)**
* **[O](#o)**
* **[P](#p)**
* **[Q](#q)**
* **[R](#r)**
* **[S](#s)**
* **[T](#t)**
* **[U](#u)**
* **[V](#v)**
* **[W](#w)**
* **[X](#X)**
----
## A
- **[AAC - AdvancedAntiCheat](https://www.spigotmc.org/resources/6442/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#aac]]**]
- **[AbstractMenus](https://www.spigotmc.org/resources/75107/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#abstractmenus]]**]
- **[AcidIsland](https://www.spigotmc.org/resources/581/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#acidisland]]**]
- **[Advanced Abilities](https://www.spigotmc.org/resources/21983/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#advanced-abilities]]**]
- **[Advanced Achievements](https://www.spigotmc.org/resources/6239/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[AdvancedAFK](https://www.spigotmc.org/resources/60761/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#advancedafk]]**]
- **[AdvancedCustomMenu+](https://www.spigotmc.org/resources/47945/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#advancedcustommenu]]**]
- **[AdvancedLottery](https://www.spigotmc.org/resources/43668/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#advancedlottery]]**]
- **[AdvancedModReq](https://www.spigotmc.org/resources/40528/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#advancedmodreq]]**]
- **[Advance Tab](https://www.spigotmc.org/resources/21958/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[ajParkour](https://www.spigotmc.org/resources/60909/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#ajparkour]]**]
- **[AnimatedBoard](https://www.spigotmc.org/resources/13632/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[AnimatedScoreboard](https://www.spigotmc.org/resources/20848/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[Animated Menu](https://www.spigotmc.org/resources/4690/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#amimated-menu]]**]
- **[AnimatedSpecialBar](https://www.spigotmc.org/resources/24654/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[AnnouncementsEverywhere](https://www.spigotmc.org/resources/59510/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[AParkour](https://www.spigotmc.org/resources/30923/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#aparkour]]**]
- **[ASkyBlock](https://www.spigotmc.org/resources/1220/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#askyblock]]**]
- **[AsyncKeepAlive](https://www.spigotmc.org/resources/64676/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#asynckeepalive]]**]
- **[AutoCommandsPlus](https://www.spigotmc.org/resources/11083/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[AutoRank](https://www.spigotmc.org/resources/3239/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#autorank]]**]
- **[AutoSell](https://www.spigotmc.org/resources/2157/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#autosell]]**]
----
## B
- **[BankSystem](https://www.spigotmc.org/resources/61580/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#banksystem]]**]
- **[BannerBoard](https://www.spigotmc.org/resources/20435/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[BattleLevels](https://www.spigotmc.org/resources/2218/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#battlelevels]]**]
- **[BeautyQuests](https://www.spigotmc.org/resources/39255/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#beautyquests]]**]
- **[BedWars1058](https://www.spigotmc.org/resources/50942/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#bedwars1058]]**]
- **[BentoBox](https://github.com/BentoBoxWorld/BentoBox)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#bentobox]]**]
- **[Big Doors Opener](https://www.spigotmc.org/resources/80805/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[BlockParty](https://www.spigotmc.org/resources/7264/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#blockparty]]**]
- **[BlockQuests](https://www.spigotmc.org/resources/32729/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#blockquests]]**]
- **[BookStats](https://www.spigotmc.org/resources/4313/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[BossBarSet](https://www.spigotmc.org/resources/26963/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[BossVote](https://www.spigotmc.org/resources/16497/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[Broadcaster Plugin](https://dev.bukkit.org/projects/broadcaster-plugin)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[BuildBattlePro](https://www.spigotmc.org/resources/49587/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#buildbattlepro]]**]
- **[BungeePerms](https://www.spigotmc.org/resources/25/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#bungeeperms]]**]
----
## C
- **[CarlTheCreeper](https://www.spigotmc.org/resources/18008/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#carlthecreeper]]**]
- **[Characters Premium](https://www.spigotmc.org/resources/45142/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[ChatBot](https://www.spigotmc.org/resources/55642/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[ChatColor+](https://www.spigotmc.org/resources/1546/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#chatcolor]]**]
- **[ChatColor+ Premium](https://www.spigotmc.org/resources/54093/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#chatcolor-premium]]**]
- **[ChatControl Pro](https://www.spigotmc.org/resources/10258/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[Chat Format](https://www.spigotmc.org/resources/11780/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [**[[Link|Placeholders#chat-format]]**]
- **[ChatManager](https://www.spigotmc.org/resources/52245/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[ChatReaction](https://www.spigotmc.org/resources/3748/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#chatreaction]]**]
- **[CheckNameHistory](https://www.spigotmc.org/resources/3768/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#checknamehistory]]**]
- **[ChestCommands](https://dev.bukkit.org/projects/chest-commands)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[CitizensBooks](https://www.spigotmc.org/resources/37465/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [**[[Link|Placeholders#citizensbooks]]**]
- **[Clans-API for Spigot/Clan tag in chat](https://www.spigotmc.org/resources/31547/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#clans-api-for-spigotclan-tag-in-chat]]**]
- **[Clans](https://www.spigotmc.org/resources/34696/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#clans]]**]
- **[Clans](https://www.spigotmc.org/resources/78415/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#clans-1]]**]
- **[ClicksPerSecond](https://www.spigotmc.org/resources/57214/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[CMI](https://www.spigotmc.org/resources/3742/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[CombatLogX](https://www.spigotmc.org/resources/31689/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#combatlogx]]**]
- **[CommandConditions](https://www.spigotmc.org/resources/41736/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[Compassance](https://www.spigotmc.org/resources/18327/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#compassance]]**]
- **[Country on Join](https://www.spigotmc.org/resources/34275/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#country-on-join]]**]
- **[CraftConomy](https://www.spigotmc.org/resources/2395/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#craftconomy]]**]
- **[CraftingStore.net](https://www.spigotmc.org/resources/31331/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#craftingstorenet]]**]
- **[CTSNC](https://www.spigotmc.org/resources/10714/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[CursedVIP](https://www.spigotmc.org/resources/67068/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#cursedvip]]**]
- **[CustomCommands](https://www.spigotmc.org/resources/14363/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[CustomGUI (Free)](https://www.spigotmc.org/resources/58440/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[CustomGUI (Paid)](https://www.spigotmc.org/resources/7386/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[CustomHelp](https://www.spigotmc.org/resources/20606/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[Custom Items](https://www.spigotmc.org/resources/63848/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#custom-items]]**]
- **[CustomSigns](https://www.spigotmc.org/resources/63569/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
----
## D
- **[Daily Rewards](https://www.spigotmc.org/resources/16708)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#daily-rewards]]**]
- **[DeliveryMan](https://www.spigotmc.org/resources/14131/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#deliveryman]]**]
- **[DeluxeChat](https://www.spigotmc.org/resources/1277/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#deluxechat]]**]
- **[DeluxeCombat](https://www.spigotmc.org/resources/63970/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#deluxecombat]]**]
- **[DeluxeCommands](https://www.spigotmc.org/resources/8033/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[DeluxeMenus](https://www.spigotmc.org/resources/11734/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[DeluxeTags](https://www.spigotmc.org/resources/4390/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#deluxetags]]**]
- **[Depinezen](/DenizenScript/Depenizen-For-Bukkit/blob/master/README.md) (For [Denizen](https://www.spigotmc.org/resources/21039/))**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#denizen]]**]
- **[DiscordSRV](https://www.spigotmc.org/resources/18494/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#discordsrv]]**]
- **[Disease](https://www.spigotmc.org/resources/3911/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#disease]]**]
- **DonationParty**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#donationparty]]**]
- **[Donations Holograms](https://www.spigotmc.org/resources/1956/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#donations-holograms]]**]
- **[DragonSlayer](https://www.spigotmc.org/resources/36250/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#dragonslayer]]**]
- **[DungeonsXL](https://www.spigotmc.org/resources/9488/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#dungeonsxl]]**]
----
## E
- **[Economy Bank](https://www.spigotmc.org/resources/7674/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#economy-bank]]**]
- **[Enjin & DonationCraft 2.x](https://dev.bukkit.org/projects/emp)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#enjin--donationcraft-2x]]**]
- **[Enhanced BalTop](https://www.spigotmc.org/resources/20168/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[Envoys](https://www.spigotmc.org/resources/20357/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#envoys]]**]
- **[EpicCraftingsPlus](https://www.spigotmc.org/resources/39967/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[EpicFriends](https://www.spigotmc.org/resources/11294/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#epicfriends]]**]
- **[EpicLevels](https://songoda.com/marketplace/product/44)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#epiclevels]]**]
- **[Ersatz](https://www.spigotmc.org/resources/49433/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[essCore](https://www.spigotmc.org/resources/37766/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#esscore]]**]
- **[Essentials](https://ci.ender.zone/job/EssentialsX/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#essentials]]**]
- **[EZBlocks](https://www.spigotmc.org/resources/1499/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#ezblocks]]**]
- **[EzChat](https://www.spigotmc.org/resources/75048/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders.
- **[EZPrestige](https://www.spigotmc.org/resources/1794/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#ezprestige]]**]
- **[EZRanksPro](https://www.spigotmc.org/resources/10731/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#ezrankspro]]**]
----
## F
- **[FactionMapScoreboard](https://www.spigotmc.org/resources/23071/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[Factions MCore](https://www.spigotmc.org/resources/1900/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#factions-mcore]]**]
- **[FactionsUUID](https://www.spigotmc.org/resources/1035/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#factionsuuid]]**]
- **[FunnyGuilds](https://github.com/FunnyGuilds/FunnyGuilds)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#funnyguilds]]**]
- **[FriendReferral](https://www.spigotmc.org/resources/21626/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
----
## G
- **[GangsPlus](https://www.spigotmc.org/resources/2604/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#gangsplus]]**]
- **[GemsEconomy](https://www.spigotmc.org/resources/19655/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#gemseconomy]]**]
- **[GriefDefender](https://www.spigotmc.org/resources/68900/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#griefdefender]]**]
- **[GriefPrevention](https://www.spigotmc.org/resources/1884/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#griefprevention]]**]
- **[Guilds](https://www.spigotmc.org/resources/48920/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#guilds]]**]
- **[GUIPlus](https://www.spigotmc.org/resources/38664/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders.
----
## H
- **[Hawn - Hub/Lobby Management](https://www.spigotmc.org/resources/66907/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[Head Database](https://www.spigotmc.org/resources/14280/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#head-database]]**]
- **[HelpGUI](https://www.spigotmc.org/resources/33245/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[HeroChat Premium]()**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [**[[Link|Placeholders#herochat-premium]]**]
- **[Heroes](https://www.spigotmc.org/resources/305/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#heroes]]**]
- **[HoloBlock](https://www.spigotmc.org/resources/43192/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#holoblock]]**]
- **[HPWizard](https://www.spigotmc.org/resources/26821/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#hpwizard]]**]
- **[Hugs](https://www.spigotmc.org/resources/hugs.39722/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#hugs]]**]
----
## I
- **[InteractionVisualizer](https://www.spigotmc.org/resources/77050/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#interactionvisualizer]]**]
- **[IslandRate (ASkyBlock Addon)](https://www.spigotmc.org/resources/53519/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#islandrate-askyblock-addon]]**]
- **[IslandRate (AcidIsland Addon)](https://www.spigotmc.org/resources/54913/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#islandrate-acidisland-addon]]**]
- **[ItemJoin](https://www.spigotmc.org/resources/12661/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
----
## J
- **[Jobs Reborn](https://www.spigotmc.org/resources/4216/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#jobs-reborn]]**]
- **[JSONChat](https://www.spigotmc.org/resources/17744/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
----
## K
- **[Karma](https://www.spigotmc.org/resources/71156/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#karma]]**]
- **[KillStats](http://dev.bukkit.org/bukkit-plugins/killstats-v1-0/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#killstats]]**]
- **[KitPvP](https://www.spigotmc.org/resources/27107/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#kitpvp]]**]
- **[Kingdoms+](https://www.spigotmc.org/resources/11833/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#kingdoms]]**]
- **[KP-PVP](https://www.spigotmc.org/resources/50969/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#kp-pvp]]**]
----
## L
- **[LastLoginAPI](https://www.spigotmc.org/resources/66348/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#lastloginapi]]**]
- **[LeaderHeads](https://www.spigotmc.org/resources/2079/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#leaderheads]]**]
- **[Leak Parkour](https://www.spigotmc.org/resources/12852/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders.
- **[LegendQuest](https://www.spigotmc.org/resources/2120/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#legendquest]]**]
- **[LemonMobCoins](https://www.spigotmc.org/resources/59402/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#lemonmobcoins]]**]
- **[LuckPerms](https://www.spigotmc.org/resources/28140/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#luckperms]]**]
- **[LWC (Modern LWC)](https://www.spigotmc.org/resources/2162/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#lwc]]**]
----
## M
- **[Marcely's Bedwars](https://www.spigotmc.org/resources/13622/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#marcelys-bedwars]]**]
- **[Marriage](https://www.spigotmc.org/resources/81807/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#marriage]]**]
- **[Marriage (reloaded)](https://www.spigotmc.org/resources/18998/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#marriage-reloaded]]**]
- **[MarriageMaster](http://dev.bukkit.org/bukkit-plugins/marriage-master/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#marriagemaster]]**]
- **[MCInfected](https://www.spigotmc.org/resources/2133/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#mcinfected]]**]
- **[MCInfected-Ranks](https://www.spigotmc.org/resources/2826/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#mcinfected-ranks]]**]
- **[McJobs](https://dev.bukkit.org/projects/mcjobs/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#mcjobs]]**]
- **[McMMO](https://www.spigotmc.org/resources/2445/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#mcmmo]]**]
- **[Menu](https://www.spigotmc.org/resources/50658/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[MineChess](https://www.spigotmc.org/resources/74178/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#minechess]]**]
- **[Minecord](https://www.spigotmc.org/resources/44055/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#minecord]]**]
- **[MineCrates](https://www.spigotmc.org/resources/4685/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#minecrates]]**]
- **[MinetopiaSDB](https://www.spigotmc.org/resources/28830/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[MixStepManager](https://www.spigotmc.org/resources/23531/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[MobHunting](https://www.spigotmc.org/resources/3582/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#mobhunting]]**]
- **[MultiChat](https://www.spigotmc.org/resources/26204/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[MultiClan 2.0](https://www.spigotmc.org/resources/23927/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[Multiverse-Core](https://www.spigotmc.org/resources/390/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#multiverse-core]]**]
- **[MurderMystery 2](https://www.spigotmc.org/resources/36894/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[MyCommand](http://dev.bukkit.org/bukkit-plugins/mycommand/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#mycommand]]**]
- **[MyPet](https://www.spigotmc.org/resources/12725/) [[Premium](https://www.spigotmc.org/resources/17566/)]**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#mypet-premium]]**]
- **[MyPrefixSystem](https://www.spigotmc.org/resources/46244/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#myprefixsystem]]**]
----
## N
- **[Nameless Plugin](https://www.spigotmc.org/resources/59032/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#nameless-plugin]]**]
- **[Nicknamer](https://www.spigotmc.org/resources/5341/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#nicknamer]]**]
- **[NickReloaded](https://www.spigotmc.org/resources/46335/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#nickreloaded]]**]
- **[Nicky](https://www.spigotmc.org/resources/590/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#nicky]]**]
----
## O
- **[OnePlayerSleep](https://www.spigotmc.org/resources/76534/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#oneplayersleep]]**]
- **[OneTimeUse](https://www.spigotmc.org/resources/13907/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[OnTime](http://dev.bukkit.org/bukkit-plugins/ontime/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#ontime]]**]
- **[OreAnnouncer](https://www.spigotmc.org/resources/33464/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#oreannouncer]]**]
- **[Outpost](https://www.spigotmc.org/resources/38657/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#outpost]]**]
----
## P
- **[Paintball Battle](https://www.spigotmc.org/resources/76676/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#paintball-battle]]**]
- **[Parkour](https://www.spigotmc.org/resources/23685/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#parkour]]**]
- **[Parties](https://www.spigotmc.org/resources/3709/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#parties]]**]
- **[Party and Friends](https://www.spigotmc.org/resources/11633/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#party-and-friends]]**]
- **[PingTest](https://www.spigotmc.org/resources/69580/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders.
- **[PixelVip](https://www.spigotmc.org/resources/30438/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#pixelvip]]**]
- **[Plan](https://www.spigotmc.org/resources/32536/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#plan]]**]
- **[PlayerBalancerAddon](https://www.spigotmc.org/resources/51220/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[PlayTime](https://www.spigotmc.org/resources/26016/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#playtime]]**]
- **[PlayerPoints](http://dev.bukkit.org/bukkit-plugins/playerpoints/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#playerpoints]]**]
- **[PlotSquared](https://www.spigotmc.org/resources/1177/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#plotsquared]]**]
- **[PointsAPI](https://www.spigotmc.org/resources/13957/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#pointsapi]]**]
- **[Potatoes](https://www.spigotmc.org/resources/12353/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[PowerRanks](https://www.spigotmc.org/resources/64696/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#powerranks]]**]
- **[PremiumVanish](https://www.spigotmc.org/resources/14404/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#premiumvanish]]**]
- **[PrisonMines](https://www.spigotmc.org/resources/4046/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#prisonmines]]**]
- **[PrisonRanksX](https://www.spigotmc.org/resources/55899/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#prisonranksx]]**]
- **[ProCosmetics](https://www.spigotmc.org/resources/49106/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#procosmetics]]**]
- **[ProdigyGadget](https://www.spigotmc.org/resources/1335/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[ProfessionalBans](https://www.spigotmc.org/resources/63657/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#professionalbans]]**]
- **[ProQuest](https://www.spigotmc.org/resources/18249/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#proquest]]**]
- **[ProtectionStones](https://www.spigotmc.org/resources/61797/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#protectionstones]]**]
- **[PurpleIRC](https://www.spigotmc.org/resources/2836/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[PvPLevels](https://www.spigotmc.org/resources/20807/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#pvplevels]]**]
- **[PvP Stats](http://dev.bukkit.org/bukkit-plugins/pvp-stats/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#pvp-stats]]**]
- **[PvPStats Plugin](https://www.spigotmc.org/resources/69984/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#pvpstats-plugin]]**]
- **[PyrCore](https://www.spigotmc.org/resources/24180/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
----
## Q
- **[Quests](https://www.spigotmc.org/resources/3711/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#quests]]**]
- **[QuestCreator](https://www.spigotmc.org/resources/38734/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#questcreator]]**]
- **[QuickBoard](https://www.spigotmc.org/resources/15057/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[QuickSell](https://www.spigotmc.org/resources/6107/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#quicksell]]**]
----
## R
- **[RabbitsVSPenguins](https://www.spigotmc.org/resources/65277/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#rabbitsvspenguins]]**]
- **[RageMode](https://www.spigotmc.org/resources/69169/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#ragemode]]**]
- **[RankedHelp](https://www.spigotmc.org/resources/61919/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[Rankup](https://www.spigotmc.org/resources/17933/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#rankup]]**]
- **[RawMSG](https://www.spigotmc.org/resources/35864/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders.
- **[RecentFind (Treasures Add-on)](https://www.spigotmc.org/resources/33366/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#recentfind]]**]
- **[RedProtect](http://spigotmc.org/resources/15841/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#redprotect]]**]
- **[ReporterGUI](https://www.spigotmc.org/resources/8596/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[RestrictedDimensions](http://spigotmc.org/resources/80574/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#restricteddimensions]]**]
- **[RogueParkour](https://www.spigotmc.org/resources/26563/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#rogueparkour]]**]
- **[RoyalCommands](https://www.spigotmc.org/resources/4113/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#royalcommands]]**]
- **[ReferralSystem](https://www.spigotmc.org/resources/29709/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#referralsystem]]**]
- **[Residence](https://www.spigotmc.org/resources/11480/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[RPGInventory](https://www.spigotmc.org/resources/12498/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#rpginventory]]**]
----
## S
- **[Scoreboard Sidebar API](https://www.spigotmc.org/resources/21042/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[ScrollBoard](https://www.spigotmc.org/resources/24697/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[Skellett (Skript Add-on)](https://forums.skunity.com/resources/24/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[SellAll](https://www.spigotmc.org/resources/1221/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#sellall]]**]
- **[Server List/Staff List](https://www.spigotmc.org/resources/15119/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[ServerSelectorX](https://www.spigotmc.org/resources/32853/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[SignLink](https://www.spigotmc.org/resources/39593/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#signlink]]**]
- **[SimpleBoard](https://www.spigotmc.org/resources/39597/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[SimpleClans](https://www.spigotmc.org/resources/5269/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#simpleclans]]**]
- **[SimpleCoinsAPI](https://www.spigotmc.org/resources/1432/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#simplecoinsapi]]**]
- **[SimpleKillTracker](https://www.spigotmc.org/resources/17651/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#simplekilltracker]]**]
- **[SimplePrefix](http://dev.bukkit.org/bukkit-plugins/simple-prefix/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#simpleprefix]]**]
- **[Simple Suffix](http://dev.bukkit.org/bukkit-plugins/simple-suffix/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#simple-suffix]]**]
- **[SkillAPI](https://www.spigotmc.org/resources/4824/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#skillapi]]**]
- **[Skript](https://github.com/bensku/Skript)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#skript]]**]
- **[SkyWars](https://www.spigotmc.org/resources/6525/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[SkyWarsReloaded](https://www.spigotmc.org/resources/3796/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#skywarsreloaded]]**]
- **[Spark](https://github.com/lucko/spark)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#spark]]**]
- **[SpigotBoard](https://www.spigotmc.org/resources/47497/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[SpigotLib](https://www.spigotmc.org/resources/5925/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[SpigotLobby](https://www.spigotmc.org/resources/58797/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[SQLPerms](https://www.spigotmc.org/resources/1462/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#sqlperms]]**]
- **[SQLTokens](https://www.spigotmc.org/resources/3482/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#sqltokens]]**]
- **[sTablist](https://www.spigotmc.org/resources/12234/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[Staff Facilities](https://www.spigotmc.org/resources/13097/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#staff-facilities]]**]
- **[Statz](https://www.spigotmc.org/resources/25969/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#statz]]**]
- **[StrikePractice 2](https://www.spigotmc.org/resources/46906/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#strikepractice-2]]**]
- **[stTitles](https://www.spigotmc.org/resources/8310/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#sttitles]]**]
- **[SubServers](https://github.com/ME1312/SubServers-2)**
- [ ] Supports Placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#subservers]]**]
- **[SuperbVote](https://www.spigotmc.org/resources/11626/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#superbvote]]**]
- **[SuperCredits](https://www.spigotmc.org/resources/31074/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#supercredits]]**]
- **[SuperScratch](https://www.spigotmc.org/resources/12250/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[SuperVanish](https://www.spigotmc.org/resources/1331/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#supervanish]]**]
----
## T
- **[TakaAntiCheat](https://www.spigotmc.org/resources/45167/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[The Time](https://www.spigotmc.org/resources/25146/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#the-time]]**]
- **[ThemePark](https://www.spigotmc.org/resources/48648/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#themepark]]**]
- **[Thirst](https://www.spigotmc.org/resources/3316/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#thirst]]**]
- **[Timed Rewards](https://www.spigotmc.org/resources/34008/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#timed-rewards]]**]
- **[Time Tokens](https://www.spigotmc.org/resources/75441/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#time-tokens]]**]
- **[TNTRun_Reloaded](https://www.spigotmc.org/resources/53359/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#tntrun_reloaded]]**]
- **[TokenEnchant](https://www.spigotmc.org/resources/2287/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#tokenenchant]]**]
- **[TokenManager](https://www.spigotmc.org/resources/8610/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#tokenmanager]]**]
- **[Tokens](https://www.spigotmc.org/resources/71941/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#tokens]]**]
- **[Towny](https://github.com/TownyAdvanced/Towny)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#towny]]**]
- **[TownyChat](https://github.com/TownyAdvanced/TownyChat)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#townychat]]**]
- **[TransmuteIt](https://www.spigotmc.org/resources/76287/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#transmuteIt]]**]
- **[Treasures](https://www.spigotmc.org/resources/14178/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#treasures]]**]
- **[Trey's Double Jump](https://www.spigotmc.org/resources/19630/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#treys-double-jump]]**]
- **[TrickOrTreat](https://www.spigotmc.org/resources/61370/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#trickortreat]]**]
----
## U
- **[UChat](https://www.spigotmc.org/resources/23767/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[UltimateAnnounce+](https://www.spigotmc.org/resources/7459/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[UltimateBossBar](https://www.spigotmc.org/resources/19303/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders.
- **[UltimateSigns](https://www.spigotmc.org/resources/72462/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders.
- **[UltraChatFormat](https://www.spigotmc.org/resources/57929/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[UltraMenu](https://www.spigotmc.org/resources/27856/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[Ultra Permissions](https://www.spigotmc.org/resources/42678/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[Ultra Simple Staff Chat](https://www.spigotmc.org/resources/22064/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[USkyBlock](https://www.spigotmc.org/resources/2280/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#uskyblock]]**]
- **[UltimateChat](https://www.spigotmc.org/resources/uchat.23767/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#ultimatechat]]**]
- **[UltimateVotes](https://www.spigotmc.org/resources/516)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#ultimatevote]]**]
- **[UnityGen](https://www.spigotmc.org/resources/26218/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#unitygen]]**]
----
## V
- **[VariableTriggers](https://dev.bukkit.org/projects/variabletriggers)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[Vault](http://dev.bukkit.org/bukkit-plugins/vault/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#vault]]**]
- **[VentureChat](https://www.spigotmc.org/resources/771/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[ViaVersion](https://www.spigotmc.org/resources/19254/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#viaversion]]**]
- **[VoteParty](https://www.spigotmc.org/resources/987/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#voteparty]]**]
- **[VoteRoulette](http://dev.bukkit.org/bukkit-plugins/voteroulette/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#voteroulette]]**]
- **[VotingPlugin](https://www.spigotmc.org/resources/15358/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#votingplugin]]**]
----
## W
- **[WickedSkyWars](https://www.spigotmc.org/resources/556/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#wickedskywars]]**]
- **[WonderHUD](https://www.spigotmc.org/resources/12220/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders. [Link]
- **[WorldGuard](https://dev.bukkit.org/bukkit-plugins/worldguard/)**
- [ ] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#worldguard]]**]
- **[WorldJoin](https://www.spigotmc.org/resources/63892/)**
- [x] Supports placeholders.
- [ ] Provides own placeholders.
----
## X
- **[XLTournaments](https://www.spigotmc.org/resources/70630/)**
- [x] Supports placeholders.
- [x] Provides own placeholders. [**[[Link|Placeholders#xltournaments]]**]

View File

@ -1,82 +0,0 @@
[Wiki]: https://github.com/PlaceholderAPI/PlaceholderAPI/wiki
[Placeholders]: https://github.com/PlaceholderAPI/PlaceholderAPI/wiki/Placeholders
[Plugins using PlaceholderAPI]: https://github.com/PlaceholderAPI/PlaceholderAPI/wiki/Placeholders
# Wiki
This is the wiki folder. It contains all pages that you can find in our [Wiki].
It allows you to suggest changes through Pull request while keeping a simple way for us to maintain the wiki, without granting everyone push rights to it.
If you want to contribute towards the wiki would we highly recommend to follow the below contributing Guidelines, to keep the overal style of the wiki intact.
## Adding your resource(s)
If you have one or multiple resources that support PlaceholderAPI (being it by just supporting placeholders from other plugins, or providing your own) can you add them to the wiki in the following ways.
### [Plugins using PlaceholderAPI]
You should always add your resource to this page, no matter if it only supports placeholders or also provides its own.
The format of a plugin is always as follows:
```md
- **[:name](:url)**
- [?] Supports placeholders.
- [?] Provides own placeholders. [:link]
```
A quick summary over the different parts:
- `:name` is the name of your resource. The resources are ordered by alphabet and if yours has the same name as another one listed, add it __below__ the other resource.
- `:url` should be replaced with a URL to your resource page (Spigot, dev.bukkit, etc.). If you use Spigot, make sure to remove any text after the `/resources/` and only leave the ID. For example will https://www.spigotmc.org/resources/placeholderapi.6245/ become https://www.spigotmc.org/resources/6245/.
If you don't have your resource on any resource page can you either ommit the URL (Just provide the name) or provide a link to its source, if available.
- `?` should be replaced with either an `x` or a space depending on wether your plugin supports the option or not. So the `[?]` becomes either `[x]` or `[ ]`
- `:link` depends on wether your plugin provides own placeholders or not. If it doesn't, then you can just give `Link`. If it does provide placeholders, make sure to provide `[[Link|Placeholders#:name]]` where `:name` would be the name of your resource in the [Placeholders] page.
### [Placeholders]
If your plugin provides its own placeholders through an extension is it recommendet to add this extension to the [Placeholders] page.
This page is split up into two sections: PAPI Placeholders and Plugin Placeholders.
PAPI Placeholders are extensions that don't require an external plugin or other dependency to function normally. Common examples are the Player or Server extensions.
The Plugin Placeholders are extensions that require a plugin or other dependency to function. They are often used to provide values from one pluging (e.g. Vault) to another plugin through the help of PlaceholderAPI.
The overall structure of an entry is always the same:
````md
- ### **[:name](:url)**
> :command
```
:placeholders
```
----
````
- `:name` is the name of your resource. The resources are ordered by alphabet and if yours has the same name as another one listed, add it __below__ the other resource.
- `:url` should be replaced with a URL to your resource page (Spigot, dev.bukkit, etc.). If you use Spigot, make sure to remove any text after the `/resources/` and only leave the ID. For example will https://www.spigotmc.org/resources/placeholderapi.6245/ become https://www.spigotmc.org/resources/6245/.
If you don't have your resource on any resource page can you either ommit the URL (Just provide the name) or provide a link to its source, if available.
- `:command` depends on if your extension is available on the eCloud or is build into your resource. If you have it on the eCloud should you provide `/papi ecloud download :name` where `:name` is the name your expansion has on the eCloud.
If your extension is build into your resource can you just set `NO DOWNLOAD COMMAND` instead.
- `:placeholders` would be a list of all placeholders that your extension offers (Sorted by alphabet). If your placeholders support multiple variables like item names, should you use either `<text>` or `[text]` depending on if it is required or optional.
Always keep an empty line in between the `----` and the next entry below it.
If your extension is at the very bottom of the page can you ommit the `----`.
You will also need to add your extension's name to the list at the very top in the format `- **[:name](#:name)**` where `:name` is the extension name.
## Other Wiki pages
Please follow these general guidelines when editing any other pages.
### Linking
Linking should always be done through either the reference option or through the Wiki link option.
When the link leads to a page on the wiki should you use either `[[:page]]` or `[[:name|:page]]` where `:page` would be the name of the Wiki page (Case sensitive) and `:name` the text that would be displayed instead.
When linking to a section within a Wiki page should you link to it using a hashtag (`#`). For example would linking to the player extension result in `[[Placeholders#player]]` (Always have the section lowercase.
However, when you link to a section in the same wiki page should you do it in the format `[:name](#:section)` where `:name` is the text to display and `:section` is the name of the section.
When you link to an external page that isn't part of the wiki should you do it as a reference link (Exception is the above mentioned cases for resources and extensions).
You do this by adding `[:name]: :url` at the top of the page where `:name` is the reference name to use and `:url` is the url to link to.
You can then just use either `[:name]` or `[:display_text][:name]` to link to the url you set (`:display_text` could be any text (including spaces) to display).
Reference links are case-insensitive.
This system allows us to easly maintain the links without the need to update a URL on several places within the page.
### Lists
Lists should always be started with a hyphen (`-`) to better distinguish it from other formatting characters like the asterisk (`*`) used for bold or italic text.

View File

@ -1,16 +0,0 @@
[discordImg]: https://img.shields.io/discord/164280494874165248.svg?logo=discord&label=Discord&colorB=7289DA
[discord]: https://helpch.at/discord
[jenkinsImg]: https://img.shields.io/badge/Download%20from-Jenkins-brightgreen.svg
[jenkins]: http://ci.extendedclip.com/job/PlaceholderAPI/
[licenseImg]: https://img.shields.io/github/license/PlaceholderAPI/PlaceholderAPI.svg
[license]: https://github.com/PlaceholderAPI/PlaceholderAPI/blob/master/LICENSE
[issuesImg]: https://img.shields.io/github/issues-raw/PlaceholderAPI/PlaceholderAPI.svg?logo=github&logoColor=white
[issues]: https://github.com/PlaceholderAPI/PlaceholderAPI/issues
[versionImg]: https://img.shields.io/nexus/r/http/repo.extendedclip.com/me.clip/placeholderapi.svg?label=API-Version
[plugin-page]: https://spigotmc.org/resources/6245
> Thanks for using PlaceholderAPI.
>
> **[Plugin-page]** | **[[Placeholders]]** | **[[Plugins using PlaceholderAPI]]** | **[[Hook into PlaceholderAPI]]**
![versionImg] [![jenkinsImg]][jenkins] [![licenseImg]][license] [![issuesImg]][issues] [![discordImg]][discord]

View File

@ -1,78 +0,0 @@
<p align="center">
<img src="https://i.imgur.com/Adp7xdh.png" alt="PlaceholderAPI">
</p>
**[[Main page|Home]]**
### Setup
**[[Hook into PlaceholderAPI]]**
- [[First steps|Hook-into-PlaceholderAPI#first-steps]]
- [[Adding placeholders to PlaceholderAPI|Hook-into-PlaceholderAPI#adding-placeholders-to-placeholderapi]]
- [[PlaceholderExpansion]]
- [[Without an external plugin|PlaceholderExpansion#without-an-external-plugin]]
- [[With external plugin|PlaceholderExpansion#with-external-plugin]]
- [[Setting placeholders in your plugin|Hook-into-PlaceholderAPI#setting-placeholders-in-your-plugin]]
### Other
**[[Commands]]**
**[[Expansion cloud]]**
**[[FAQ]]**
**[[Plugins using PlaceholderAPI]]**
**[[Placeholders]]**
- [[PAPI-placeholders|Placeholders#papi-placeholders-1]]
- [[Advancements|Placeholders#advancements]]
- [[Animations|Placeholders#animations]]
- [[Armor|Placeholders#armor]]
- [[ASCII|Placeholders#ASCII]]
- [[BungeeCord|Placeholders#bungeecord]]
- [[CheckItem|Placeholders#checkitem]]
- [[CooldownBar|Placeholders#cooldownbar]]
- [[Formatter|Placeholders#formatter]]
- [[Javascript|Placeholders#javascript]]
- [[ListPlayers|Placeholders#listplayer]]
- [[LocalTime|Placeholders#localtime]]
- [[Math|Placeholders#math]]
- [[MVdW placeholders|Placeholders#mvdw-placeholders]]
- [[OtherPlayer|Placeholders#otherplayer]]
- [[ParseNear|Placeholders#parsenear]]
- [[ParseOther|Placeholders#parseother]]
- [[Pinger|Placeholders#pinger]]
- [[Player|Placeholders#player]]
- [[PlayerList|Placeholders#playerlist]]
- [[Plugin|Placeholders#plugin]]
- [[Progress|Placeholders#progress]]
- [[RainbowColor|Placeholders#rainbowcolor]]
- [[RandomColor|Placeholders#randomcolor]]
- [[RedisBungee|Placeholders#redisbungee]]
- [[RelCon|Placeholders#relcon]]
- [[ScoreboardObjectives|Placeholders#scoreboardobjectives]]
- [[Server|Placeholders#server]]
- [[Sound|Placeholders#sound]]
- [[Spectators|Placeholders#spectators]]
- [[Statistic|Placeholders#statistic]]
- [[Plugin-placeholders|Placeholders#plugin-placeholders-1]]
- [[A|Placeholders#a]]
- [[B|Placeholders#b]]
- [[C|Placeholders#c]]
- [[D|Placeholders#d]]
- [[E|Placeholders#e]]
- [[F|Placeholders#f]]
- [[G|Placeholders#g]]
- [[H|Placeholders#h]]
- [[I|Placeholders#i]]
- [[J|Placeholders#j]]
- [[K|Placeholders#k]]
- [[L|Placeholders#l]]
- [[M|Placeholders#m]]
- [[N|Placeholders#n]]
- [[O|Placeholders#o]]
- [[P|Placeholders#p]]
- [[Q|Placeholders#q]]
- [[R|Placeholders#r]]
- [[S|Placeholders#s]]
- [[T|Placeholders#t]]
- [[U|Placeholders#u]]
- [[V|Placeholders#v]]
- [[W|Placeholders#w]]
- [[Z|Placeholders#z]]