Compare commits

...

222 Commits

Author SHA1 Message Date
9de1ea8232 add world-specific variant 2024-02-10 18:52:50 +01:00
2f64af7ebb Introduce base plot count placeholder 2024-02-10 18:32:33 +01:00
7f1f1e025e feat: configurable accounting for bedrock layer when setting components (#4266)
- Add configuration option to force plot components to be set only above bedrock level
 - Account for build height < gen height where it is not wanted for components to be set at/below bedrock
2024-02-09 13:48:56 +01:00
59787fe7f3 Back to snapshot for development
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2024-02-06 14:33:42 +01:00
6783d5ece6 Release 7.3.3
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2024-02-05 23:04:06 +01:00
d9aa2a496c Update dependency gradle to v8.6 (#4321)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-05 23:00:08 +01:00
809ed6778c Update release-drafter/release-drafter action to v6 (#4322)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-05 22:53:29 +01:00
2fe44053a2 Update junit5 monorepo (#4320)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-05 22:53:19 +01:00
c36b87ca14 Update dependency xyz.jpenilla.run-paper to v2.2.3 (#4319)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-05 22:53:06 +01:00
5aec7653b6 Update dependency com.diffplug.spotless to v6.25.0 (#4308)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-02 18:05:41 +01:00
cc5d01e225 Update gradle/wrapper-validation-action action to v2 (#4309)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-02 18:05:30 +01:00
448577774a Entity#getEntitySpawnReason compatibility for spigot (#4305)
chore: Entity#getEntitySpawnReason compatibility for spigot
2024-02-02 16:46:39 +01:00
966c878a72 Back to snapshot for development
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2024-01-22 20:37:31 +01:00
5021f5b379 Release 7.3.2
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2024-01-22 20:32:39 +01:00
76ea9e0d3c PostPlotClearEvent added (#4268)
* PostPlotClearEvent added

* Made requested changes

* Clear.java changed

* Changed to PlotPlayer Event

* Removed methods

* Removed methods

* Removed useless import
2024-01-21 15:22:38 +01:00
951f08bc8b Add events for plot buying (#4291)
* cancelable event results are nullable

* chore: add javadocs to CancellablePlotEvent#

* feat: events for plot buy process
2024-01-21 15:21:36 +01:00
ae941e67a4 Fallback to areas QueueCoordinator when passing null (#4300)
* fix: fallback to area QueueCoordinator if null passed

* chore: add annotations to suppress IDE warnings
2024-01-21 12:40:38 +01:00
9566af5fda Use MUSIC soundcategory for plot music flag (#4302)
chore/fix: use MUSIC sound category for plot music
2024-01-21 12:38:46 +01:00
fccc146053 Do not remove entitys with CUSTOM spawn-reason on CreatureSpawnEvent. (#4297)
Do not remove entitys with CUSTOM spawn-reason.
2024-01-21 12:33:53 +01:00
a1d94af242 Fix home command reset (#4295)
* Add location not null check
The issue lies within the equals implementation

* Fix setposition method with default value.
Also add a comment too.

---------

Co-authored-by: OneLiteFeather <seelenretterin@onelitefeather.net>
2024-01-20 00:34:46 +01:00
6371cd4c5a Update fawe to v2.8.4 (#4278)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-13 17:04:44 +01:00
e4613cfc62 Fix minimessage tag resolver in list command (#4290)
fix: update resolver tag names for list command
2024-01-12 09:35:11 +01:00
8c44b2d2d2 feat: add specific admin permissions for placing vehicles (#4258)
- fixes #3850
2024-01-07 14:57:36 +00:00
449af2f3a4 Add admin permission override to edit signs (#4287)
* add admin permission override to edit signs

* include sign dying
2024-01-06 11:28:33 +01:00
ead7acdd76 fix: allow pistons on merged plot road if detect-invalid-edge-pistons true (#4257)
- fixes #4232
2023-12-31 18:50:29 +00:00
1991142d48 refactor: move leave event dispact to after logic (#4260)
- closes #4171
2023-12-26 15:26:31 +00:00
63ae11b3d3 Back to snapshot for development 2023-12-25 19:54:00 +01:00
86fe3c6846 Release 7.3.1 2023-12-25 19:49:36 +01:00
a90e179338 Relocate net.kyori.options (Support newer 1.20.4 builds) (#4280)
chore/fix: relocate net.kyori.option
2023-12-25 18:32:29 +01:00
a6ae287908 Back to snapshot for development 2023-12-22 17:59:33 +01:00
1a33997099 Release 7.3.0 2023-12-22 17:54:28 +01:00
6edd4b8220 Update dependency net.kyori:adventure-platform-bukkit to v4.3.2 (#4276)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-22 17:51:28 +01:00
9b0d1e484c Update dependency com.github.spotbugs:spotbugs-annotations to v4.8.3 (#4275)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-22 17:51:20 +01:00
6971fa4c10 Update github/codeql-action action to v3 (#4274)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-22 17:36:22 +01:00
3c818f3e33 Update dependency org.checkerframework:checker-qual to v3.42.0 (#4273)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-22 17:36:14 +01:00
31be2e5eb3 Update adventure to v4.15.0 (#4272)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-22 17:36:08 +01:00
945a8ad306 Update worldedit to v7.2.18 (#4271)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-22 17:35:54 +01:00
c6b0b99cd6 Fix MM update in plot condensation 2023-12-22 17:28:00 +01:00
dbfc43e3cd feat: allow for custom plot limit handling (#4261)
* feat: allow for custom plot limit handling

* feat: allow for custom plot limit handling

* chore: use fluent setter
2023-12-18 21:07:41 +01:00
c8b4a2fa39 feat: Allow admin done permission to override requiring plot complexity calculation (#4267)
Co-authored-by: MrJoshuaT <josh@jmt.me>
2023-12-16 21:04:11 +00:00
d851e27aed Fix checkerframework javadoc URL 2023-12-16 17:34:56 +01:00
4a45729c9e feat: add projectile-change-block flag (#4185)
- closes #4081
2023-12-12 13:53:10 +00:00
7931c0864e Update dependency org.checkerframework:checker-qual to v3.41.0 (#4265)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-09 10:26:00 +01:00
1456b29d93 Update fawe to v2.8.3 (#4264)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-09 10:25:53 +01:00
761477b76d Update dependency com.diffplug.spotless to v6.23.3 (#4263)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-09 10:25:46 +01:00
e61bcf905f Back to snapshot for development 2023-12-09 10:21:05 +01:00
85bec710df Release 7.2.1 2023-12-09 10:13:42 +01:00
d130794453 Prepare for 1.20.3/4 2023-12-08 07:29:19 +01:00
f5f875eb11 feat: add HasOwner PlotFilter filter (#4259)
* feat: add HasOwner PlotFilter filter
 - closes #3831

* change since to TODO

* Address feedback

---------

Co-authored-by: Alexander Brandes <mc.cache@web.de>
2023-12-07 18:29:10 +01:00
89511f07f9 Fix: disable sign-coloring when edit-sign flag is false (#4252)
* Initial commit

* Update Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEventListener.java

Co-authored-by: powercas_gamer <cas@mizule.dev>

* Relocated Item check

* Added version check when building list of items

* Use mutable set and copy to immutable

---------

Co-authored-by: powercas_gamer <cas@mizule.dev>
2023-12-06 22:56:22 +01:00
1a18adcd95 Declare explicit runtime dependency on 'junit-platform-launcher' (#4255) 2023-12-02 00:17:28 +01:00
65858c5f3e Update dependency com.github.spotbugs:spotbugs-annotations to v4.8.2 (#4245)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-02 00:00:21 +01:00
5c7520b5f5 Update dependency org.junit.jupiter:junit-jupiter to v5.10.1 (#4246)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-02 00:00:13 +01:00
f3b9cd5ded Update dependency xyz.jpenilla.run-paper to v2.2.2 (#4248)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-01 23:47:33 +01:00
8a3eb25805 Update fawe to v2.8.2 (#4249)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-01 23:47:26 +01:00
48bbd3c018 Update dependency com.diffplug.spotless to v6.23.2 (#4250)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-01 23:47:17 +01:00
bf85013f70 Update dependency gradle to v8.5 (#4251)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-01 23:47:10 +01:00
d36a2d236b Update dependency org.checkerframework:checker-qual to v3.40.0 (#4253)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-01 23:46:59 +01:00
79f111ec0a Update actions/setup-java action to v4 (#4254)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-01 23:46:38 +01:00
31ae62b62c Introduce edit-sign flag (#4236) 2023-11-26 12:36:01 +00:00
cdb44d4884 fix: re-add default spawn option and disclude armour stands (#4240)
- Fixes #4238
2023-11-25 20:30:48 +00:00
eb63e4351d Feat(API): Mutable Location in PlayerTeleportToPlotEvent (#4196)
* feat: ability to overwrite spawn location for plot teleports

* chore/feat: migrate to LocationTransformer to resolve unnecessary chunk loads

* chore: simplify transform type
2023-11-21 17:26:30 +00:00
ba7880241b Fix: permission check for integer flags (#4217)
* Changing numeric check to support '0'

* Adding notes

* More detailed description of 'max-plots' setting
2023-11-21 17:26:15 +00:00
be6838f29e Make '/plot download world' clickable (#4239) 2023-11-19 14:43:07 +01:00
dc73116401 Fix: remove everyone command (#4106)
Fixing remove everyone command
2023-11-19 13:42:11 +00:00
b6a87df072 Fixup renovate warnings 2023-11-19 09:49:55 +01:00
8195afaa2f Fix: chest_boat not removing (#4231) 2023-11-06 14:38:32 +01:00
561eac2fbd Back to snapshot for development 2023-11-03 15:06:30 +01:00
fdc887850c Release 7.2.0 2023-11-03 15:01:50 +01:00
e3bfd9b8bf Add info about service providers to debugpaste (#4226) 2023-11-03 14:58:38 +01:00
e689337188 Update dependency me.clip:placeholderapi to v2.11.5 (#4220)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-02 21:25:40 +01:00
ee6ae6cba0 Update worldedit to v7.2.17 (#4222)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-02 21:25:30 +01:00
dc8d7809bd Update dependency com.github.spotbugs:spotbugs-annotations to v4.8.0 (#4223)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-02 07:55:10 +01:00
dcd63ed4d9 Update fawe to v2.8.1 (#4221)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-02 07:55:03 +01:00
3cc770970f feat: add configurable border size (#4213)
- allows players to travel past border, but not claim
 - closes #2962
2023-10-31 10:51:19 +00:00
1c3776b605 Delay economy initialization to server load (#4216) 2023-10-29 10:55:31 +01:00
95c7f621fb Fix: including "highestLimit" number (#4218)
Including "highestLimit" number
2023-10-29 10:55:01 +01:00
15b4cbdb0f Simplify Plot#getConnectedPlots and share cache between connected plots (#4212)
* Simplify Plot#getConnectedPlots and share cache between connected plots

* add missing isMerged check
2023-10-23 16:38:41 +02:00
812eac18d3 Label PRs with merge conflicts 2023-10-22 12:53:43 +02:00
16a4ee835c chore/fix(:runServer): cache fawe artifact and fix java 21 (#4209)
chore/fix: cache fawe artifact and fix java 21
2023-10-16 19:23:25 +02:00
c013b92e62 Address deprecated 'Times#of()' in 'PlotPlayer' (#4207) 2023-10-15 12:05:04 +00:00
b00a46b286 chore: remove poorly implemented /ps debug loadedchunks command (#4180)
- the same (but correctly implemented) functionality exists in other plugins
 - closes #4140
2023-10-10 11:06:22 +01:00
44b1127181 Back to snapshot for development 2023-10-09 17:14:17 +02:00
c7bfd48a21 Release 7.1.0 2023-10-09 17:03:09 +02:00
dc13783db8 chore: mitigate possible future sqlite driver problems (#4200)
* chore: mitigate possible future sqlite driver problems

* chore/feat: log driver version on error

---------

Co-authored-by: Alexander Brandes <mc.cache@web.de>
2023-10-09 16:55:09 +02:00
0a390ab342 Update dependency gradle to v8.4 (#4202)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-07 21:08:28 +02:00
d111740f64 Updater checkerqual 2023-10-07 20:48:53 +02:00
28e97e8441 Replace deprecated ageable with breedable (#4193)
* [#4164] Replace deprecated ageable with breedable

* [#4164] Correct methods and usage based on issue

* [#4164] Add since tag to deprecated and new methods

* [#4164] Add to deprecated annotation since argument with todo value

* [#4164] Change since to todo for changed code

* [#4164] Change access of storeBreedable to private
2023-10-07 20:15:26 +02:00
a30cdb37d6 fix: load flags after we is initialised (#4186)
* fix: load flags after we is initliased
 - fixes #4073
 - it could be possible to add a callback in the WE initilised event listener, but that overcomplicates it a bit and this is fine tbh

* Extract method
2023-10-07 20:14:54 +02:00
f848162066 Default to latest version of informative-annotations (#4199)
* Default to latest version of informative-annotations

* Update Core/build.gradle.kts
2023-10-07 20:14:10 +02:00
40c70aa98d Replace javadoc.io with javadocs.dev 2023-10-05 20:48:49 +02:00
0d2b36bac8 Fix: No response to errors in plot user group modifications (#4197) 2023-10-05 14:54:11 +01:00
d7e5bcdaa5 Update publishing profile 2023-10-04 13:45:11 +02:00
fc783574a3 Migrate 'EntityUtil#capNumeral' to an enhanced switch (#4195)
* Migrate 'EntityUtil#capNumeral' to an enhanced switch

* Apply feedback
2023-10-04 11:34:50 +02:00
5f7bb784f0 feat: add concrete-harden flag (#4184) 2023-10-04 09:41:47 +01:00
26c55a318f feat: add placeholder for plot size (#4181) 2023-10-02 20:37:00 +01:00
ee68bc3d9e Fix 'ChunkCoordinatorBuilder#unloadAfter()' javadocs (#4194) 2023-10-02 19:37:43 +02:00
a3bc3968a5 Update Paper javadoc URL to 1.20 (#4187) 2023-10-01 14:07:55 +02:00
79454da1a6 Address deprecated 'Project.buildDir' in build scripts (#4191) 2023-10-01 14:07:36 +02:00
12a4c92ad9 Update dependency com.diffplug.spotless to v6.22.0 (#4188)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-01 14:00:26 +02:00
167692d464 Update dependency org.checkerframework:checker-qual to v3.38.0 (#4189)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-01 14:00:03 +02:00
ae26e8155c Update fawe to v2.8.0 (#4190)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-01 13:59:52 +02:00
286ea62a21 Update actions/checkout action to v4 (#4192)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-01 13:59:43 +02:00
d95c74d8c9 Addresses issues related to maven publish scm block (#4179)
- Fixes https://github.com/IntellectualSites/PlotSquared/issues/4158
- Fixes https://github.com/IntellectualSites/PlotSquared/issues/4159
- Resolves https://github.com/IntellectualSites/PlotSquared/issues/4160
2023-10-01 11:54:47 +02:00
c1555ddbc7 Fix #isAccessible() deprecation in HybridPlotWorld (#4177)
Fixes https://github.com/IntellectualSites/PlotSquared/issues/4165
2023-10-01 11:50:19 +02:00
4fe0c586d9 Address deprecated URL instantiation (#4178)
Fixes https://github.com/IntellectualSites/PlotSquared/issues/4166
2023-10-01 11:50:12 +02:00
aae6ea4fee Update dependency net.kyori:adventure-platform-bukkit to v4.3.1 (#4182)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-01 11:50:03 +02:00
385d018504 Update worldedit to v7.2.16 (#4183)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-01 11:49:53 +02:00
f4def082c1 Update dependency cloud.commandframework:cloud-services to v1.8.4 (#4175)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-01 11:25:05 +02:00
69c9f1df83 Update dependency me.clip:placeholderapi to v2.11.4 (#4176)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-01 11:24:58 +02:00
e138dc0267 Update runServer gradle tasks (#4173)
* chore/feat: download fawe & only use latest patch versions in runServer

* chore: gitignore runServer-1.20 folder as well

* chore: exclude minor versions >= 10 by default (no need for < 10)

* chore: update gradle plugin
2023-09-30 01:32:50 +02:00
ca50b53f94 Update api.spigotmc.org from 0.1 to 0.2 (#4167) 2023-09-17 20:14:30 +02:00
f705487055 Ignore deprecations we can't address (yet) 2023-09-16 21:48:13 +02:00
b7c9453a1a Rewrite javadocs for PlotId class (#4157) 2023-09-15 13:17:42 -04:00
1aa370d562 Fixup bad commit d3dab0d736 2023-09-13 21:13:30 +02:00
d3dab0d736 Added documentation for PlotWeather 2023-09-12 21:13:04 -04:00
764156b267 Minor doc rewrite 2023-09-12 20:58:24 -04:00
665f5251bf Added docs to PlotItemStack 2023-09-12 20:42:58 -04:00
7c328095d7 *actually 10s 2023-09-06 17:46:56 +01:00
7884c91d52 fix: run world unload task every 10 seconds, not 1 second
- Every second meant worlds would be unloaded whilst a player attempted to teleport to it
2023-09-06 17:09:01 +01:00
e9a19e0821 Update dependency dev.notmyfault.serverlib:ServerLib to v2.3.4 (#4152)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-01 08:36:43 +02:00
022847fc4b Update fawe to v2.7.1 (#4153)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-01 08:36:29 +02:00
1ee673be58 Update dependency com.diffplug.spotless to v6.21.0 (#4154)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-01 08:33:17 +02:00
3c2aa99e86 Fix javadoc for 'PlotModificationManager#setComponent()' 2023-08-26 11:30:56 +02:00
11fac3f060 Remove repository-level CoC in favor with organization-level CoC (#4148)
Remove repository-level CoC in favor with organization-level Coc
2023-08-23 16:54:21 +02:00
3e57e524b9 Back to snapshot for development 2023-08-23 13:02:45 +02:00
f582ec03c5 Release 7.0.0 2023-08-23 12:50:00 +02:00
893be136f0 Update dependency gradle to v8.3 (#4147)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-23 12:22:47 +02:00
b74ba30281 Fixed NPE in DebugRoadRegen command 2023-08-21 19:09:35 -04:00
ba9dab1f73 Fixed a typo. 2023-08-18 00:28:51 -04:00
8e60fdb477 Merge remote-tracking branch 'origin/main' 2023-08-18 00:10:03 -04:00
443fe8dd47 Added deprecation 2023-08-18 00:09:48 -04:00
e56e52ba4f Fix 'grant' placeholder 2023-08-11 14:05:23 +02:00
cd008bed9b Update dependency net.essentialsx:EssentialsX to v2.20.1 (#4139)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-11 09:52:49 +02:00
d4c90283d6 Cleanup dependencies 2023-08-08 22:33:24 +02:00
dc04ec955a Back to snapshot for development 2023-08-02 13:57:50 +02:00
72f511ce99 Release 7.0.0-rc.4 2023-08-02 13:51:03 +02:00
0d63c2bdb6 feat: allow bypass of econ costs (#4126) 2023-08-02 13:48:07 +02:00
49e13384cf fix: remove "default" spawn reason (#4132) 2023-08-02 13:47:53 +02:00
1ddc19ff69 Update dependency com.intellectualsites.bom:bom-newest to v1.34 (#4130)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-01 10:45:47 +02:00
a6d436e841 Update dependency org.junit.jupiter:junit-jupiter to v5.10.0 (#4131)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-01 10:45:38 +02:00
9b0b39ac2e feat: add a permission requirement to /plot merge all (#4127) 2023-07-31 14:04:08 +02:00
638f0bd078 fix: do not use overall max schem height for checking road schem height (#4124) 2023-07-30 12:17:35 +02:00
c27b838dad fix: add missing method in UncheckedWorldLocation (#4112)
Co-authored-by: Alexander Brandes <mc.cache@web.de>
2023-07-24 18:00:56 +00:00
e0cb2949df fix: switch to consistent heights for schematic generation (#4113) 2023-07-24 16:56:53 +01:00
59be582c28 fix: correct reflected fields for chunk needs saving (#4111) 2023-07-24 16:56:46 +01:00
f6cbb3792f [ci skip] Update documentation location 2023-07-22 11:40:01 +02:00
a68918f830 Update dependency gradle to v8.2.1 (#4117)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-22 11:16:24 +02:00
1a7ded864e Update dependency com.diffplug.spotless to v6.20.0 (#4118)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-22 09:11:22 +00:00
cbc8bc8879 [ci skip] Publish javadocs for releases only 2023-07-22 11:05:30 +02:00
21f79d1c13 Back to snapshot for development 2023-07-22 11:01:11 +02:00
293d7acf2d Release 7.0.0-rc.3 2023-07-22 10:56:35 +02:00
d876d3722a Fix default flags registration for third parties (#4114)
Co-authored-by: Leomixer17 <leonardo.dgs@yahoo.com>
2023-07-17 22:30:02 +02:00
dffb7672ff fix: add missing spawn event reasons (#4110) 2023-07-16 15:25:07 +01:00
f867867a42 Fix typo in comment 2023-07-15 19:56:44 +02:00
59eefd6865 fix: even better handling of schematic heights (#4102) 2023-07-10 23:13:36 +02:00
587a286d05 Back to snapsho for development 2023-07-05 13:35:51 +02:00
e10caf6aa0 Release 7.0.0-rc.2 2023-07-05 13:28:13 +02:00
08b325e37d feat: improvement of kick messages (#4099)
* Adding new player_not_in_plot message

* Adding new cannot_kick_player message

* Small typo

* Rejection: renaming of the player placeholder
2023-07-04 18:44:45 +02:00
c394108ba6 feat: add a sculk sensor flag (#4095) 2023-07-04 16:56:28 +01:00
31e89019f1 Update worldedit to v7.2.15 (#4096)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-01 10:43:53 +02:00
3a7075e28d Update dependency com.intellectualsites.bom:bom-newest to v1.31 (#4097)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-01 10:43:36 +02:00
8373b7874e Update dependency gradle to v8.2 (#4098)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-01 10:42:20 +02:00
fe13882b97 Update renovate.json 2023-07-01 10:28:10 +02:00
f45064c4c4 fix: P2 areas are in worlds.yml 2023-06-23 14:11:12 +01:00
af32399dd2 Correct calculating the plot price, if 'merge' differs from 'claim' 2023-06-23 10:40:40 +02:00
f3c03348d9 fix: return on null plot on big boom (#4085)
- Fixes #4084
2023-06-22 20:09:31 +02:00
a53330e39b Disable update checker for RC phase 2023-06-22 20:08:43 +02:00
e2ba93dab9 Update unsupported MiniMessage syntax 2023-06-22 19:55:36 +02:00
9d43434e40 Add 1.20.1 to the issue template 2023-06-17 18:45:42 +02:00
4f421167d1 Move renovate to .github folder 2023-06-17 18:43:53 +02:00
94f4619c2c Publish javadocs for v7 2023-06-15 17:30:27 +02:00
9885d3e506 Fill in 'since' annotations 2023-06-15 17:24:21 +02:00
a54276d3b2 Strip legacy color codes if message cannot be parsed by MiniMessage (#4077) 2023-06-15 10:23:09 +02:00
cbb284b0fd Properly drop unsupported biomes from biome list (#4074)
* Drop CUSTOM from biome list

* Drop cherry_grove if present on pre 1.20 versions
2023-06-14 15:12:34 +02:00
ed22b22e9c [ci skip] Update bug_report.yml 2023-06-11 12:06:33 +02:00
444ccda807 Add support for 1.20 (#4061)
1.20 fixes
2023-06-09 13:22:55 +02:00
db361cc420 Wrong biome list for 1.19.4 if datapacks are not enabled (#4016)
* Remove cherry grove for 1.20 below

* Handle PR feedback. Replace version check with registry check

* Simplify the biomes list

* Update Bukkit/src/main/java/com/plotsquared/bukkit/generator/BukkitPlotGenerator.java

Co-authored-by: Hannes Greule <SirYwell@users.noreply.github.com>

* Handle pr feedback

---------

Co-authored-by: Hannes Greule <SirYwell@users.noreply.github.com>
2023-06-09 13:22:23 +02:00
079dc02cfe Update dependency net.essentialsx:EssentialsX to v2.20.0 (#4063)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-09 11:09:06 +00:00
e98791c865 Update top level group id and lowercaswe artifact names (#4060)
* Update top level group Id (#4055)

* Lowercase artifact names
2023-06-08 10:40:02 +02:00
7c3112f30f Update gradle (#4044)
* Update gradle

* Update codeQL

* *
2023-06-04 13:57:39 +02:00
c01f5f5c7d Update dependency com.diffplug.spotless to v6.19.0 (#4052)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-01 09:21:53 +02:00
95caa19505 Update guice to v7 (major) (#4053)
Update guice to v7

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-01 09:21:43 +02:00
b8055201df fix: do not reset the connectedCache every time Plot#getRegions is called (#4046)
* fix: do not reset the connectedCache every time Plot#getRegions is called
 - Fixes IntellectualSites/FastAsyncWorldEdit#2188

* Remove unused import
2023-05-25 19:05:20 +02:00
81daefae4a fix: do not overwrite bedrock with wall (#4048)
- Fixes #4047
2023-05-25 19:04:53 +02:00
02437a8c72 feat: add cost for the merge when using plot auto-merge (#3841)
* feat: add cost for the merge when using plot auto-merge
 - Closes #3814

* fix: Don't charge for auto merge if there is no auto merge

---------

Co-authored-by: Alexander Brandes <mc.cache@web.de>
2023-05-21 17:57:46 +02:00
958c66b28f Road-Schematic-Generation now shows correct skull skins and banner patterns (#4026)
* fix: Preserve NBT Data for Banners and Skulls on Chunk Generation

* Update Bukkit/src/main/java/com/plotsquared/bukkit/schematic/StateWrapper.java

* Make it compile

---------

Co-authored-by: Alexander Brandes <mc.cache@web.de>
2023-05-13 22:32:33 +02:00
c656190e14 Fix plot done success flag being false when complexity is higher than… (#4040)
Fix plot done success flag being false when complexity is higher than the threshold

Co-authored-by: MrJoshuaT <josh@jmt.me>
2023-05-13 22:23:11 +02:00
e914cb210e Update announce-release-on-discord.yml (#4036) 2023-05-01 10:16:29 +02:00
94c6af74d2 Update build.yml 2023-05-01 10:15:50 +02:00
ebb82bd66d Update build-pr.yml 2023-05-01 10:15:20 +02:00
66f907eb5d Update codeql 2023-05-01 10:15:04 +02:00
9ffede2c5c Update dependency org.junit.jupiter:junit-jupiter to v5.9.3 (#4032)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-01 10:14:20 +02:00
97172df0dc Update dependency com.intellectualsites.bom:bom-newest to v1.27 (#4033)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-01 10:03:01 +02:00
c9746b182c Update plugin xyz.jpenilla.run-paper to v2.1.0 (#4034)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-01 10:02:48 +02:00
10a2b80ffc Update dependency com.diffplug.spotless to v6.18.0 (#4030)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-29 15:30:00 +02:00
ca0f38255d Fix /plot area create <name> without passing a specific terrain type (#4025)
fix: Ensure PlotAreaBuilder#plotAreaType returns non-null value
2023-04-29 15:27:49 +02:00
0484ac73af Improve testability for different versions (#4018)
* Ignore run folders

* Add a bulk of supported test environments

* Fix gitignore

* Fix gitignore

* Fix gitignore
2023-04-22 11:33:00 +02:00
1a712ad3c1 fix: account for false permissions when checking range (#4014) 2023-04-21 23:24:14 +01:00
2d1f483469 fix: clear above and below plot gen heights if build heights are larger (#3991)
- Fixes #3985
2023-04-13 17:34:49 +01:00
91830e233b Fix Misaligned SVG In IJ project view (#4011) 2023-04-10 11:54:29 +02:00
561edb83bf Update renovate.json (#4005) 2023-04-01 17:52:58 +02:00
0e09cf223a Update dependency org.enginehub:squirrelid to v0.3.2 (#4002)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-27 10:43:58 +02:00
d78360d6eb fix: correct variable check in schematic dimensions
- Fixes #3999
2023-03-26 13:31:01 +01:00
1464804c11 Update dependency me.clip:placeholderapi to v2.11.3 (#3994)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-21 23:04:41 +00:00
8629eae5fc Update dependency com.diffplug.spotless to v6.17.0 (#3989)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-21 23:56:01 +01:00
7b8ba7c3ac Update github/codeql-action digest to 168b99b (#3992)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-21 23:54:31 +01:00
77c7466c17 Update dependency cloud.commandframework:cloud-services to v1.8.3 (#3993)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-21 23:54:22 +01:00
82fe76fd37 Update dependency com.intellectualsites.bom:bom-newest to v1.25 (#3995)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-21 23:53:15 +01:00
3f81ea4ef8 Update worldedit to v7.2.14 (#3996)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-21 23:52:56 +01:00
745b06a008 fix: fix generation by re-adding important method 2023-03-16 17:42:48 +00:00
77b2bd166a Update dependency io.github.gradle-nexus.publish-plugin to v1.3.0 (#3987)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-15 09:43:41 +00:00
8e02336c44 Reapply stash 2023-03-15 10:30:38 +01:00
3adfbde45a Don't format JSON files 2023-03-06 11:49:18 +01:00
e6db8e2750 Perform code formatting according to editorconfig (#3981)
* Perform code reformatting

* Fix javadoc errors
2023-03-06 11:38:30 +01:00
9cd0ee9b49 Cleanup deprecated methods (#3980) 2023-03-06 11:21:14 +01:00
d455d1fcd7 Merge branch 'v6' into v7 2023-03-06 10:48:51 +01:00
ea19ff783f Back to snapshot for development 2023-03-06 10:47:51 +01:00
447e4c7d58 Release 6.11.1 2023-03-06 10:40:17 +01:00
89031447f2 Migrate left over occurrences to enhanced switches (#3979)
* Migrate left-overs to enhanced switches

* More
2023-03-06 10:25:02 +01:00
4210a3a555 Deprecate unused methods for removal (#3977) 2023-03-06 10:13:03 +01:00
42e146b8c7 Delete unused HyperverseWorldManager file 2023-03-05 20:53:00 +01:00
180 changed files with 2841 additions and 2041 deletions

View File

@ -7,8 +7,8 @@ body:
attributes: attributes:
value: | value: |
Thanks for taking the time to fill out this bug report for PlotSquared! Fill out the following form to your best ability to help us fix the problem. Thanks for taking the time to fill out this bug report for PlotSquared! Fill out the following form to your best ability to help us fix the problem.
Only use this if you're absolutely sure that you found a bug and can reproduce it. For anything else, use: [our Discord server](https://discord.gg/intellectualsites) or [the wiki](https://intellectualsites.github.io/plotsquared-documentation/). Only use this if you're absolutely sure that you found a bug and can reproduce it. For anything else, use: [our Discord server](https://discord.gg/intellectualsites) or [the wiki](https://intellectualsites.gitbook.io/plotsquared/).
Do NOT use the public issue tracker to report security vulnerabilities! They are disclosed using [this](https://forms.gle/btgdRn9yhGtzEiGW8) form! Do NOT use the public issue tracker to report security vulnerabilities! They are disclosed using [this](https://github.com/IntellectualSites/PlotSquared/security/policy) GitHub form!
- type: dropdown - type: dropdown
attributes: attributes:
@ -27,6 +27,9 @@ body:
description: Which server version version you using? If your server version is not listed, it is not supported. Update to a supported version first. description: Which server version version you using? If your server version is not listed, it is not supported. Update to a supported version first.
multiple: false multiple: false
options: options:
- '1.20.4'
- '1.20'
- '1.19.4'
- '1.19.3' - '1.19.3'
- '1.19.2' - '1.19.2'
- '1.19.1' - '1.19.1'

View File

@ -4,5 +4,5 @@ contact_links:
url: https://discord.gg/intellectualsites url: https://discord.gg/intellectualsites
about: Our support Discord, please ask questions and seek support here. about: Our support Discord, please ask questions and seek support here.
- name: PlotSquared Wiki - name: PlotSquared Wiki
url: https://intellectualsites.github.io/plotsquared-documentation/ url: https://intellectualsites.gitbook.io/plotsquared/
about: Take a look at the wiki page for instructions how to setup PlotSquared and use its commands. about: Take a look at the wiki page for instructions how to setup PlotSquared and use its commands.

View File

@ -7,7 +7,7 @@ body:
attributes: attributes:
value: | value: |
Thanks for taking the time to fill out this feature request for PlotSquared! Fill out the following form to your best ability to help us understand your feature request and greately improve the change of it getting added. Thanks for taking the time to fill out this feature request for PlotSquared! Fill out the following form to your best ability to help us understand your feature request and greately improve the change of it getting added.
For anything else than a feature request, use: [our Discord server](https://discord.gg/intellectualsites) or [the wiki](https://intellectualsites.github.io/plotsquared-documentation/). For anything else than a feature request, use: [our Discord server](https://discord.gg/intellectualsites) or [the wiki](https://intellectualsites.gitbook.io/plotsquared/).
- type: textarea - type: textarea
attributes: attributes:

19
.github/renovate.json vendored Normal file
View File

@ -0,0 +1,19 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base",
":semanticCommitsDisabled"
],
"automerge": true,
"labels": [
"dependencies"
],
"rebaseWhen": "conflicted",
"schedule": ["on the first day of the month"],
"ignoreDeps": [
"com.google.code.gson:gson",
"com.google.guava:guava",
"org.yaml:snakeyaml",
"org.apache.logging.log4j:log4j-api"
]
}

View File

@ -1,7 +1,7 @@
name: Announce release on discord name: Announce release on discord
on: on:
release: release:
types: [published] types: [ published ]
jobs: jobs:
send_announcement: send_announcement:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -11,7 +11,7 @@ jobs:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
DISCORD_USERNAME: PlotSquared Release DISCORD_USERNAME: PlotSquared Release
DISCORD_AVATAR: https://raw.githubusercontent.com/IntellectualSites/Assets/main/plugins/PlotSquared/PlotSquared.png DISCORD_AVATAR: https://raw.githubusercontent.com/IntellectualSites/Assets/main/plugins/PlotSquared/PlotSquared.png
uses: Ilshidur/action-discord@08d9328877d6954120eef2b07abbc79249bb6210 # ratchet:Ilshidur/action-discord@0.3.2 uses: Ilshidur/action-discord@0.3.2
with: with:
args: | args: |
"<@&525015541815967744> <@&679322738552471574> <@&699293353862496266>" "<@&525015541815967744> <@&679322738552471574> <@&699293353862496266>"

View File

@ -1,19 +1,19 @@
name: Build PR name: Build PR
on: [pull_request] on: [ pull_request ]
jobs: jobs:
build_pr: build_pr:
if: github.repository_owner == 'IntellectualSites' if: github.repository_owner == 'IntellectualSites'
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
matrix: matrix:
os: [ubuntu-latest, windows-latest, macos-latest] os: [ ubuntu-latest, windows-latest, macos-latest ]
steps: steps:
- name: Checkout Repository - name: Checkout Repository
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Validate Gradle Wrapper - name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@55e685c48d84285a5b0418cd094606e199cca3b6 # v1 uses: gradle/wrapper-validation-action@v2
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v3 uses: actions/setup-java@v4
with: with:
distribution: temurin distribution: temurin
java-version: 17 java-version: 17

View File

@ -2,18 +2,18 @@ name: build
on: on:
push: push:
branches: branches:
- v7 - main
jobs: jobs:
build: build:
if: github.repository_owner == 'IntellectualSites' if: github.repository_owner == 'IntellectualSites'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout Repository - name: Checkout Repository
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Validate Gradle Wrapper - name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@55e685c48d84285a5b0418cd094606e199cca3b6 # v1 uses: gradle/wrapper-validation-action@v2
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v3 uses: actions/setup-java@v4
with: with:
distribution: temurin distribution: temurin
java-version: 17 java-version: 17
@ -28,7 +28,7 @@ jobs:
echo "STATUS=release" >> $GITHUB_ENV echo "STATUS=release" >> $GITHUB_ENV
fi fi
- name: Publish Release - name: Publish Release
if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/v7'}} if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/main'}}
run: ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository run: ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository
env: env:
ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USERNAME }} ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USERNAME }}
@ -36,20 +36,14 @@ jobs:
ORG_GRADLE_PROJECT_signingKey: ${{ secrets.SIGNING_KEY }} ORG_GRADLE_PROJECT_signingKey: ${{ secrets.SIGNING_KEY }}
ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.SIGNING_PASSWORD }} ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.SIGNING_PASSWORD }}
- name: Publish Snapshot - name: Publish Snapshot
if: ${{ runner.os == 'Linux' && env.STATUS != 'release' && github.event_name == 'push' && github.ref == 'refs/heads/v7' }} if: ${{ runner.os == 'Linux' && env.STATUS != 'release' && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
run: ./gradlew publishToSonatype run: ./gradlew publishToSonatype
env: env:
ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USERNAME }} ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USERNAME }}
ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.SONATYPE_PASSWORD }} ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.SONATYPE_PASSWORD }}
- name: Publish core javadoc - name: Publish core javadoc
<<<<<<< HEAD if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/main'}}
# if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/v7'}}
if: ${{ runner.os == 'Linux' && env.STATUS == 'snapshot' && github.event_name == 'push' && github.ref == 'refs/heads/v7'}}
uses: cpina/github-action-push-to-another-repository@main uses: cpina/github-action-push-to-another-repository@main
=======
if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/v6'}}
uses: cpina/github-action-push-to-another-repository@0a14457bb28b04dfa1652e0ffdfda866d2845c73 # main
>>>>>>> v6
env: env:
SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }} SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }}
with: with:
@ -60,9 +54,8 @@ jobs:
target-branch: main target-branch: main
target-directory: v7/core target-directory: v7/core
- name: Publish bukkit javadoc - name: Publish bukkit javadoc
# if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/v7'}} if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/main'}}
if: ${{ runner.os == 'Linux' && env.STATUS == 'snapshot' && github.event_name == 'push' && github.ref == 'refs/heads/v7'}} uses: cpina/github-action-push-to-another-repository@main
uses: cpina/github-action-push-to-another-repository@0a14457bb28b04dfa1652e0ffdfda866d2845c73 # main
env: env:
SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }} SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }}
with: with:

View File

@ -1,10 +1,10 @@
name: "CodeQL" name: "CodeQL"
on: on:
push: push:
branches: [ v7 ] branches: [ main ]
pull_request: pull_request:
# The branches below must be a subset of the branches above # The branches below must be a subset of the branches above
branches: [ v7 ] branches: [ main ]
jobs: jobs:
analyze: analyze:
@ -17,15 +17,20 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
language: ['java'] language: [ 'java' ]
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@32dc499307d133bb5085bae78498c0ac2cf762d5 # v2 uses: github/codeql-action/init@v3
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@32dc499307d133bb5085bae78498c0ac2cf762d5 # v2 uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@32dc499307d133bb5085bae78498c0ac2cf762d5 # v2 uses: github/codeql-action/analyze@v3

View File

@ -0,0 +1,23 @@
name: "Label conflicting PRs"
on:
push:
pull_request_target:
types: [ synchronize ]
pull_request:
types: [ synchronize ]
permissions:
pull-requests: write
jobs:
main:
if: github.event.pull_request.user.login != 'dependabot[bot]'
runs-on: ubuntu-latest
steps:
- name: Label conflicting PRs
uses: eps1lon/actions-label-merge-conflict@v2.1.0
with:
dirtyLabel: "unresolved-merge-conflict"
repoToken: "${{ secrets.GITHUB_TOKEN }}"
commentOnDirty: "Please take a moment and address the merge conflicts of your pull request. Thanks!"
continueOnMissingPermissions: true

View File

@ -2,16 +2,16 @@ name: draft release
on: on:
push: push:
branches: branches:
- v6 - main
pull_request: pull_request:
types: [opened, reopened, synchronize] types: [ opened, reopened, synchronize ]
pull_request_target: pull_request_target:
types: [opened, reopened, synchronize] types: [ opened, reopened, synchronize ]
jobs: jobs:
update_release_draft: update_release_draft:
if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }} if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: release-drafter/release-drafter@v5 - uses: release-drafter/release-drafter@v6
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

3
.gitignore vendored
View File

@ -137,3 +137,6 @@ docs/
build/ build/
.DS_Store .DS_Store
# Ignore run folders
run-[0-9].[0-9][0-9]/
run-[0-9].[0-9][0-9].[0-9]/

154
.idea/icon.svg generated
View File

@ -1,48 +1,144 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.1" id="svg2" xml:space="preserve" width="4000" height="3333.3333" viewBox="0 0 4000 3333.3333" sodipodi:docname="PlotSquared.ai"> <svg
<metadata id="metadata8"> version="1.1"
id="svg2"
xml:space="preserve"
width="512"
height="512"
viewBox="0 0 512 512.00001"
sodipodi:docname="icon.svg"
inkscape:version="1.1.2 (b8e25be8, 2022-02-05)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata
id="metadata8">
<rdf:RDF> <rdf:RDF>
<cc:Work rdf:about=""> <cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format> <dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work> </cc:Work>
</rdf:RDF> </rdf:RDF>
</metadata> </metadata>
<defs id="defs6"> <defs
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath18"> id="defs6">
<path d="M 0,2500 H 3000 V 0 H 0 Z" id="path16" /> <clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath18">
<path
d="M 0,2500 H 3000 V 0 H 0 Z"
id="path16" />
</clipPath> </clipPath>
</defs> </defs>
<sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="640" inkscape:window-height="480" id="namedview4" /> <sodipodi:namedview
<g id="g10" inkscape:groupmode="layer" inkscape:label="PlotSquared" transform="matrix(1.3333333,0,0,-1.3333333,0,3333.3333)"> pagecolor="#ffffff"
<g id="g12"> bordercolor="#666666"
<g id="g14" clip-path="url(#clipPath18)"> borderopacity="1"
<g id="g20" transform="translate(1486.1511,2242.6453)"> objecttolerance="10"
<path d="m 0,0 c 16.533,10.846 33.211,21.453 50.104,31.699 78.972,-48.281 153.985,-102.704 227.269,-159.144 148.61,-115.422 287.884,-243.01 414.393,-382.333 111.39,-122.861 212.751,-255.152 298.898,-396.971 52.744,-87.322 100.544,-177.884 139.514,-272.214 -11.638,-3.551 -23.108,-7.655 -34.362,-12.286 l -0.24,0.288 c -11.135,12.982 -24.141,24.212 -34.915,37.506 -22.557,23.013 -45.425,45.737 -68.03,68.678 -19.725,20.253 -40.601,39.45 -58.958,60.974 -36.355,36.451 -72.517,73.093 -108.944,109.471 -22.628,26.013 -48.064,49.385 -71.965,74.197 -19.029,19.485 -38.706,38.346 -57.519,57.999 -12.166,14.998 -26.684,27.716 -39.93,41.658 -27.668,27.524 -54.903,55.479 -82.571,82.979 -23.924,27.956 -51.664,52.264 -76.692,79.164 -4.68,4.487 -8.855,10.774 -15.886,11.326 -22.34,34.027 -58.311,57.327 -97.377,67.502 -104.312,99.153 -215.487,191.202 -332.661,274.782 -117.942,-83.94 -229.476,-176.781 -334.484,-276.39 -26.684,-0.024 -53.368,0.024 -80.076,-0.024 0.024,-26.564 0.048,-53.104 0,-79.668 -72.229,-73.021 -139.491,-150.937 -202.385,-232.092 -63.758,-82.619 -121.973,-169.51 -173.541,-260.264 131.932,-69.061 257.864,-149.521 375.926,-240.275 0.096,-26.444 -0.12,-52.888 0.096,-79.332 l 0.744,-0.984 c 20.109,-24.14 43.409,-45.233 65.126,-67.861 15.118,-15.382 30.571,-30.404 45.569,-45.881 17.565,-20.733 37.698,-39.042 56.607,-58.503 19.917,-20.781 41.25,-40.218 59.967,-62.151 29.156,-29.299 58.167,-58.815 87.515,-87.922 29.155,-33.043 61.502,-63.111 92.169,-94.738 13.726,-12.67 25.124,-27.571 38.634,-40.457 25.029,-25.365 50.129,-50.657 75.325,-75.853 -37.914,-51.208 -73.741,-103.952 -107.192,-158.183 -167.83,273.317 -397.235,507.305 -662.37,687.158 -81.875,55.335 -167.23,105.584 -255.681,149.641 -52.815,26.276 -106.831,50.248 -162.239,70.381 99.393,233.628 242.795,446.715 410.289,636.79 93.562,106.088 194.634,205.433 301.466,298.13 C -217.335,-155.808 -111.439,-73.789 0,0" style="fill:#062f4c;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path22" /> gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1440"
inkscape:window-height="900"
id="namedview4"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="0.1632"
inkscape:cx="1087.6225"
inkscape:cy="1666.6666"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="g10" />
<g
id="g10"
inkscape:groupmode="layer"
inkscape:label="PlotSquared"
transform="matrix(1.3333333,0,0,-1.3333333,0,3333.3333)">
<g
id="g12"
transform="matrix(0.16955078,0,0,0.16955078,-68.456969,2101.8529)">
<g
id="g14"
clip-path="url(#clipPath18)">
<g
id="g20"
transform="translate(1486.1511,2242.6453)">
<path
d="m 0,0 c 16.533,10.846 33.211,21.453 50.104,31.699 78.972,-48.281 153.985,-102.704 227.269,-159.144 148.61,-115.422 287.884,-243.01 414.393,-382.333 111.39,-122.861 212.751,-255.152 298.898,-396.971 52.744,-87.322 100.544,-177.884 139.514,-272.214 -11.638,-3.551 -23.108,-7.655 -34.362,-12.286 l -0.24,0.288 c -11.135,12.982 -24.141,24.212 -34.915,37.506 -22.557,23.013 -45.425,45.737 -68.03,68.678 -19.725,20.253 -40.601,39.45 -58.958,60.974 -36.355,36.451 -72.517,73.093 -108.944,109.471 -22.628,26.013 -48.064,49.385 -71.965,74.197 -19.029,19.485 -38.706,38.346 -57.519,57.999 -12.166,14.998 -26.684,27.716 -39.93,41.658 -27.668,27.524 -54.903,55.479 -82.571,82.979 -23.924,27.956 -51.664,52.264 -76.692,79.164 -4.68,4.487 -8.855,10.774 -15.886,11.326 -22.34,34.027 -58.311,57.327 -97.377,67.502 -104.312,99.153 -215.487,191.202 -332.661,274.782 -117.942,-83.94 -229.476,-176.781 -334.484,-276.39 -26.684,-0.024 -53.368,0.024 -80.076,-0.024 0.024,-26.564 0.048,-53.104 0,-79.668 -72.229,-73.021 -139.491,-150.937 -202.385,-232.092 -63.758,-82.619 -121.973,-169.51 -173.541,-260.264 131.932,-69.061 257.864,-149.521 375.926,-240.275 0.096,-26.444 -0.12,-52.888 0.096,-79.332 l 0.744,-0.984 c 20.109,-24.14 43.409,-45.233 65.126,-67.861 15.118,-15.382 30.571,-30.404 45.569,-45.881 17.565,-20.733 37.698,-39.042 56.607,-58.503 19.917,-20.781 41.25,-40.218 59.967,-62.151 29.156,-29.299 58.167,-58.815 87.515,-87.922 29.155,-33.043 61.502,-63.111 92.169,-94.738 13.726,-12.67 25.124,-27.571 38.634,-40.457 25.029,-25.365 50.129,-50.657 75.325,-75.853 -37.914,-51.208 -73.741,-103.952 -107.192,-158.183 -167.83,273.317 -397.235,507.305 -662.37,687.158 -81.875,55.335 -167.23,105.584 -255.681,149.641 -52.815,26.276 -106.831,50.248 -162.239,70.381 99.393,233.628 242.795,446.715 410.289,636.79 93.562,106.088 194.634,205.433 301.466,298.13 C -217.335,-155.808 -111.439,-73.789 0,0"
style="fill:#062f4c;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path22" />
</g> </g>
<g id="g24" transform="translate(1201.7948,1741.5303)"> <g
<path d="M 0,0 C 105.008,99.609 216.543,192.45 334.485,276.39 451.659,192.81 562.833,100.76 667.146,1.608 c -34.987,8.83 -71.51,9.718 -107.264,6.431 -41.202,-4.296 -82.907,-19.077 -112.543,-48.953 -33.019,-32.155 -49.456,-77.604 -55.311,-122.501 -28.124,27.908 -56.104,55.983 -84.035,84.083 -2.976,2.976 -6.839,4.823 -10.391,6.911 -19.029,26.348 -45.953,46.673 -76.62,57.495 C 187.555,-2.472 151.513,-0.12 116.166,0 Z" style="fill:#4c8fcc;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path26" /> id="g24"
transform="translate(1201.7948,1741.5303)">
<path
d="M 0,0 C 105.008,99.609 216.543,192.45 334.485,276.39 451.659,192.81 562.833,100.76 667.146,1.608 c -34.987,8.83 -71.51,9.718 -107.264,6.431 -41.202,-4.296 -82.907,-19.077 -112.543,-48.953 -33.019,-32.155 -49.456,-77.604 -55.311,-122.501 -28.124,27.908 -56.104,55.983 -84.035,84.083 -2.976,2.976 -6.839,4.823 -10.391,6.911 -19.029,26.348 -45.953,46.673 -76.62,57.495 C 187.555,-2.472 151.513,-0.12 116.166,0 Z"
style="fill:#4c8fcc;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path26" />
</g> </g>
<g id="g28" transform="translate(919.3342,1429.7462)"> <g
<path d="m 0,0 c 62.894,81.156 130.156,159.072 202.385,232.092 0.048,-244.21 0.024,-488.421 0,-732.631 C 84.323,-409.785 -41.61,-329.325 -173.541,-260.264 -121.973,-169.51 -63.758,-82.619 0,0" style="fill:#4c8fcc;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path30" /> id="g28"
transform="translate(919.3342,1429.7462)">
<path
d="m 0,0 c 62.894,81.156 130.156,159.072 202.385,232.092 0.048,-244.21 0.024,-488.421 0,-732.631 C 84.323,-409.785 -41.61,-329.325 -173.541,-260.264 -121.973,-169.51 -63.758,-82.619 0,0"
style="fill:#4c8fcc;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path30" />
</g> </g>
<g id="g32" transform="translate(1649.134,1700.6166)"> <g
<path d="m 0,0 c 29.635,29.875 71.341,44.657 112.543,48.952 35.754,3.288 72.277,2.4 107.263,-6.431 39.066,-10.174 75.037,-33.474 97.377,-67.501 11.879,-17.661 20.181,-37.411 26.42,-57.687 10.871,-38.802 11.95,-79.356 11.446,-119.358 -44.345,-0.072 -88.69,0.048 -133.035,-0.072 -1.032,30.907 3.263,63.686 -10.175,92.626 -9.526,20.325 -32.107,31.243 -53.751,32.131 -21.453,1.44 -45.065,-4.32 -59.175,-21.597 -12.79,-15.861 -15.382,-37.002 -16.558,-56.655 -1.295,-29.132 3.696,-59.031 17.518,-84.923 16.821,-30.619 39.378,-57.783 64.526,-81.9 31.387,-32.634 67.501,-60.374 97.857,-94.041 27.332,-28.988 51.256,-61.479 68.005,-97.785 20.541,-41.13 26.972,-87.827 25.82,-133.372 -0.912,-32.107 -5.231,-64.406 -16.149,-94.737 -11.59,-31.699 -31.123,-61.047 -58.335,-81.371 -25.124,-19.125 -55.696,-29.852 -86.651,-34.771 -49.552,-6.743 -101.888,-4.847 -148.465,14.854 -35.227,14.829 -64.238,42.689 -81.708,76.548 -20.996,40.242 -27.115,86.339 -27.259,131.212 0.048,17.829 0,35.658 0.048,53.463 44.345,0.048 88.69,-0.023 133.059,0.048 1.728,-35.538 -4.055,-72.06 5.663,-106.807 5.783,-22.173 26.204,-37.794 48.185,-41.754 20.733,-3.431 43.577,-2.015 61.622,9.791 15.502,9.43 23.949,26.78 26.78,44.225 5.903,35.922 1.872,74.293 -15.381,106.688 -16.918,30.595 -39.474,57.711 -64.55,81.899 -33.187,34.099 -71.173,63.254 -102.585,99.081 -26.756,28.867 -49.408,61.646 -65.486,97.641 -24.572,52.48 -26.731,112.422 -20.18,169.102 C -49.456,-77.604 -33.019,-32.155 0,0" style="fill:#feeeee;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path34" /> id="g32"
transform="translate(1649.134,1700.6166)">
<path
d="m 0,0 c 29.635,29.875 71.341,44.657 112.543,48.952 35.754,3.288 72.277,2.4 107.263,-6.431 39.066,-10.174 75.037,-33.474 97.377,-67.501 11.879,-17.661 20.181,-37.411 26.42,-57.687 10.871,-38.802 11.95,-79.356 11.446,-119.358 -44.345,-0.072 -88.69,0.048 -133.035,-0.072 -1.032,30.907 3.263,63.686 -10.175,92.626 -9.526,20.325 -32.107,31.243 -53.751,32.131 -21.453,1.44 -45.065,-4.32 -59.175,-21.597 -12.79,-15.861 -15.382,-37.002 -16.558,-56.655 -1.295,-29.132 3.696,-59.031 17.518,-84.923 16.821,-30.619 39.378,-57.783 64.526,-81.9 31.387,-32.634 67.501,-60.374 97.857,-94.041 27.332,-28.988 51.256,-61.479 68.005,-97.785 20.541,-41.13 26.972,-87.827 25.82,-133.372 -0.912,-32.107 -5.231,-64.406 -16.149,-94.737 -11.59,-31.699 -31.123,-61.047 -58.335,-81.371 -25.124,-19.125 -55.696,-29.852 -86.651,-34.771 -49.552,-6.743 -101.888,-4.847 -148.465,14.854 -35.227,14.829 -64.238,42.689 -81.708,76.548 -20.996,40.242 -27.115,86.339 -27.259,131.212 0.048,17.829 0,35.658 0.048,53.463 44.345,0.048 88.69,-0.023 133.059,0.048 1.728,-35.538 -4.055,-72.06 5.663,-106.807 5.783,-22.173 26.204,-37.794 48.185,-41.754 20.733,-3.431 43.577,-2.015 61.622,9.791 15.502,9.43 23.949,26.78 26.78,44.225 5.903,35.922 1.872,74.293 -15.381,106.688 -16.918,30.595 -39.474,57.711 -64.55,81.899 -33.187,34.099 -71.173,63.254 -102.585,99.081 -26.756,28.867 -49.408,61.646 -65.486,97.641 -24.572,52.48 -26.731,112.422 -20.18,169.102 C -49.456,-77.604 -33.019,-32.155 0,0"
style="fill:#feeeee;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path34" />
</g> </g>
<g id="g36" transform="translate(1262.7214,1613.126)"> <g
<path d="m 0,0 v -301.13 c 23.204,0.024 46.409,-0.048 69.613,0.024 18.525,0.288 38.202,6.575 50.153,21.429 12.43,17.277 13.917,39.522 14.613,60.111 0.024,43.985 -0.048,87.994 0.024,131.979 -0.48,23.637 -0.983,50.369 -17.277,69.23 C 104.864,-5.711 86.867,-0.24 69.589,0 46.385,0.048 23.204,0.024 0,0 m -141.002,128.38 c 26.708,0.048 53.392,0 80.075,0.024 H 55.24 c 35.346,-0.12 71.389,-2.471 104.815,-14.925 30.668,-10.823 57.592,-31.148 76.621,-57.496 26.852,-39.09 36.69,-87.202 38.058,-133.947 0.024,-48.833 0.096,-97.689 -0.024,-146.521 -1.728,-47.993 -11.974,-97.953 -41.514,-136.971 -22.748,-30.644 -57.495,-50.801 -94.281,-59.583 -45.377,-11.878 -92.578,-6.791 -138.891,-7.847 -0.072,-111.799 0,-223.574 -0.024,-335.373 -13.942,0 -27.86,0.024 -41.778,-0.024 -32.802,0.072 -65.605,0 -98.384,0.048 l -0.744,0.984 c -0.216,26.444 0,52.888 -0.096,79.332 0.024,244.211 0.048,488.421 0,732.632 0.048,26.563 0.024,53.103 0,79.667" style="fill:#feeeee;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path38" /> id="g36"
transform="translate(1262.7214,1613.126)">
<path
d="m 0,0 v -301.13 c 23.204,0.024 46.409,-0.048 69.613,0.024 18.525,0.288 38.202,6.575 50.153,21.429 12.43,17.277 13.917,39.522 14.613,60.111 0.024,43.985 -0.048,87.994 0.024,131.979 -0.48,23.637 -0.983,50.369 -17.277,69.23 C 104.864,-5.711 86.867,-0.24 69.589,0 46.385,0.048 23.204,0.024 0,0 m -141.002,128.38 c 26.708,0.048 53.392,0 80.075,0.024 H 55.24 c 35.346,-0.12 71.389,-2.471 104.815,-14.925 30.668,-10.823 57.592,-31.148 76.621,-57.496 26.852,-39.09 36.69,-87.202 38.058,-133.947 0.024,-48.833 0.096,-97.689 -0.024,-146.521 -1.728,-47.993 -11.974,-97.953 -41.514,-136.971 -22.748,-30.644 -57.495,-50.801 -94.281,-59.583 -45.377,-11.878 -92.578,-6.791 -138.891,-7.847 -0.072,-111.799 0,-223.574 -0.024,-335.373 -13.942,0 -27.86,0.024 -41.778,-0.024 -32.802,0.072 -65.605,0 -98.384,0.048 l -0.744,0.984 c -0.216,26.444 0,52.888 -0.096,79.332 0.024,244.211 0.048,488.421 0,732.632 0.048,26.563 0.024,53.103 0,79.667"
style="fill:#feeeee;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path38" />
</g> </g>
<g id="g40" transform="translate(1966.3174,1675.6364)"> <g
<path d="m 0,0 c 7.031,-0.552 11.206,-6.839 15.885,-11.326 25.029,-26.9 52.768,-51.208 76.693,-79.164 27.667,-27.5 54.903,-55.456 82.571,-82.979 13.246,-13.942 27.764,-26.66 39.93,-41.658 18.813,-19.653 38.49,-38.514 57.519,-57.999 23.9,-24.812 49.337,-48.185 71.965,-74.197 36.427,-36.378 72.589,-73.02 108.943,-109.471 18.358,-21.524 39.234,-40.722 58.959,-60.974 22.605,-22.941 45.473,-45.665 68.03,-68.678 10.774,-13.294 23.78,-24.524 34.914,-37.506 -103.904,-41.97 -203.488,-94.114 -298.922,-152.761 -246.994,-152.28 -466.224,-350.298 -639.333,-583.398 -25.197,25.196 -50.297,50.488 -75.325,75.852 -13.51,12.886 -24.908,27.788 -38.634,40.458 -30.667,31.627 -63.014,61.695 -92.17,94.738 -29.347,29.107 -58.359,58.623 -87.514,87.922 -18.717,21.933 -40.05,41.37 -59.967,62.151 -18.909,19.461 -39.042,37.77 -56.607,58.503 -14.998,15.477 -30.452,30.499 -45.569,45.88 -21.717,22.629 -45.017,43.722 -65.126,67.862 32.779,-0.048 65.582,0.024 98.384,-0.048 114.391,-98.097 220.407,-205.984 315.384,-322.99 92.914,114.318 196.242,220.022 307.753,316.271 30.955,4.919 61.526,15.646 86.65,34.771 27.212,20.325 46.745,49.672 58.335,81.371 107.312,77.988 219.327,149.929 337.509,210.376 -35.299,64.67 -75.829,126.437 -118.254,186.643 C 176.253,-228.037 104.24,-140.115 26.42,-57.687 20.181,-37.41 11.878,-17.661 0,0" style="fill:#042338;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path42" /> id="g40"
transform="translate(1966.3174,1675.6364)">
<path
d="m 0,0 c 7.031,-0.552 11.206,-6.839 15.885,-11.326 25.029,-26.9 52.768,-51.208 76.693,-79.164 27.667,-27.5 54.903,-55.456 82.571,-82.979 13.246,-13.942 27.764,-26.66 39.93,-41.658 18.813,-19.653 38.49,-38.514 57.519,-57.999 23.9,-24.812 49.337,-48.185 71.965,-74.197 36.427,-36.378 72.589,-73.02 108.943,-109.471 18.358,-21.524 39.234,-40.722 58.959,-60.974 22.605,-22.941 45.473,-45.665 68.03,-68.678 10.774,-13.294 23.78,-24.524 34.914,-37.506 -103.904,-41.97 -203.488,-94.114 -298.922,-152.761 -246.994,-152.28 -466.224,-350.298 -639.333,-583.398 -25.197,25.196 -50.297,50.488 -75.325,75.852 -13.51,12.886 -24.908,27.788 -38.634,40.458 -30.667,31.627 -63.014,61.695 -92.17,94.738 -29.347,29.107 -58.359,58.623 -87.514,87.922 -18.717,21.933 -40.05,41.37 -59.967,62.151 -18.909,19.461 -39.042,37.77 -56.607,58.503 -14.998,15.477 -30.452,30.499 -45.569,45.88 -21.717,22.629 -45.017,43.722 -65.126,67.862 32.779,-0.048 65.582,0.024 98.384,-0.048 114.391,-98.097 220.407,-205.984 315.384,-322.99 92.914,114.318 196.242,220.022 307.753,316.271 30.955,4.919 61.526,15.646 86.65,34.771 27.212,20.325 46.745,49.672 58.335,81.371 107.312,77.988 219.327,149.929 337.509,210.376 -35.299,64.67 -75.829,126.437 -118.254,186.643 C 176.253,-228.037 104.24,-140.115 26.42,-57.687 20.181,-37.41 11.878,-17.661 0,0"
style="fill:#042338;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path42" />
</g> </g>
<g id="g44" transform="translate(1499.3971,1669.1094)"> <g
<path d="m 0,0 c 3.551,-2.088 7.415,-3.935 10.39,-6.911 27.932,-28.1 55.912,-56.175 84.036,-84.083 -6.551,-56.679 -4.392,-116.622 20.18,-169.102 16.078,-35.994 38.73,-68.774 65.486,-97.641 31.412,-35.826 69.398,-64.982 102.585,-99.081 25.076,-24.188 47.632,-51.304 64.55,-81.899 17.253,-32.395 21.284,-70.765 15.381,-106.688 -2.831,-17.445 -11.278,-34.794 -26.78,-44.225 -18.045,-11.806 -40.889,-13.222 -61.622,-9.79 -21.981,3.959 -42.402,19.58 -48.185,41.753 -9.718,34.747 -3.935,71.269 -5.663,106.808 -44.369,-0.072 -88.714,0 -133.059,-0.048 -0.048,-17.806 0,-35.635 -0.048,-53.464 0.144,-44.873 6.263,-90.97 27.259,-131.212 17.47,-33.859 46.481,-61.718 81.708,-76.548 46.577,-19.701 98.913,-21.597 148.465,-14.854 -111.511,-96.249 -214.839,-201.953 -307.753,-316.271 -94.977,117.006 -200.993,224.893 -315.383,322.99 13.918,0.048 27.836,0.024 41.777,0.024 0.024,111.799 -0.048,223.574 0.024,335.372 46.313,1.056 93.514,-4.031 138.891,7.847 36.786,8.783 71.533,28.94 94.282,59.583 29.539,39.018 39.785,88.978 41.513,136.971 0.12,48.833 0.048,97.689 0.024,146.522 C 36.69,-87.203 26.852,-39.09 0,0" style="fill:#1c72ba;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path46" /> id="g44"
transform="translate(1499.3971,1669.1094)">
<path
d="m 0,0 c 3.551,-2.088 7.415,-3.935 10.39,-6.911 27.932,-28.1 55.912,-56.175 84.036,-84.083 -6.551,-56.679 -4.392,-116.622 20.18,-169.102 16.078,-35.994 38.73,-68.774 65.486,-97.641 31.412,-35.826 69.398,-64.982 102.585,-99.081 25.076,-24.188 47.632,-51.304 64.55,-81.899 17.253,-32.395 21.284,-70.765 15.381,-106.688 -2.831,-17.445 -11.278,-34.794 -26.78,-44.225 -18.045,-11.806 -40.889,-13.222 -61.622,-9.79 -21.981,3.959 -42.402,19.58 -48.185,41.753 -9.718,34.747 -3.935,71.269 -5.663,106.808 -44.369,-0.072 -88.714,0 -133.059,-0.048 -0.048,-17.806 0,-35.635 -0.048,-53.464 0.144,-44.873 6.263,-90.97 27.259,-131.212 17.47,-33.859 46.481,-61.718 81.708,-76.548 46.577,-19.701 98.913,-21.597 148.465,-14.854 -111.511,-96.249 -214.839,-201.953 -307.753,-316.271 -94.977,117.006 -200.993,224.893 -315.383,322.99 13.918,0.048 27.836,0.024 41.777,0.024 0.024,111.799 -0.048,223.574 0.024,335.372 46.313,1.056 93.514,-4.031 138.891,7.847 36.786,8.783 71.533,28.94 94.282,59.583 29.539,39.018 39.785,88.978 41.513,136.971 0.12,48.833 0.048,97.689 0.024,146.522 C 36.69,-87.203 26.852,-39.09 0,0"
style="fill:#1c72ba;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path46" />
</g> </g>
<g id="g48" transform="translate(1748.0469,1601.6797)"> <g
<path d="M 0,0 C 14.11,17.277 37.722,23.036 59.175,21.597 80.82,20.709 103.4,9.791 112.927,-10.534 c 13.438,-28.94 9.142,-61.719 10.174,-92.626 44.345,0.12 88.691,0 133.036,0.072 0.504,40.002 -0.576,80.556 -11.447,119.358 77.82,-82.428 149.833,-170.35 215.583,-262.664 42.426,-60.207 82.956,-121.973 118.254,-186.643 -118.182,-60.447 -230.196,-132.388 -337.508,-210.376 10.918,30.331 15.238,62.63 16.149,94.737 1.152,45.545 -5.279,92.242 -25.82,133.372 -16.749,36.306 -40.673,68.797 -68.005,97.785 -30.355,33.667 -66.47,61.406 -97.857,94.041 -25.148,24.117 -47.705,51.28 -64.526,81.9 -13.822,25.892 -18.813,55.791 -17.517,84.923 C -15.382,-37.002 -12.79,-15.862 0,0" style="fill:#1c72ba;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path50" /> id="g48"
transform="translate(1748.0469,1601.6797)">
<path
d="M 0,0 C 14.11,17.277 37.722,23.036 59.175,21.597 80.82,20.709 103.4,9.791 112.927,-10.534 c 13.438,-28.94 9.142,-61.719 10.174,-92.626 44.345,0.12 88.691,0 133.036,0.072 0.504,40.002 -0.576,80.556 -11.447,119.358 77.82,-82.428 149.833,-170.35 215.583,-262.664 42.426,-60.207 82.956,-121.973 118.254,-186.643 -118.182,-60.447 -230.196,-132.388 -337.508,-210.376 10.918,30.331 15.238,62.63 16.149,94.737 1.152,45.545 -5.279,92.242 -25.82,133.372 -16.749,36.306 -40.673,68.797 -68.005,97.785 -30.355,33.667 -66.47,61.406 -97.857,94.041 -25.148,24.117 -47.705,51.28 -64.526,81.9 -13.822,25.892 -18.813,55.791 -17.517,84.923 C -15.382,-37.002 -12.79,-15.862 0,0"
style="fill:#1c72ba;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path50" />
</g> </g>
<g id="g52" transform="translate(1262.7214,1613.126)"> <g
<path d="m 0,0 c 23.204,0.024 46.385,0.048 69.589,0 17.278,-0.24 35.275,-5.711 47.537,-18.357 16.294,-18.861 16.797,-45.593 17.277,-69.23 -0.072,-43.985 0,-87.994 -0.024,-131.979 -0.696,-20.589 -2.183,-42.834 -14.613,-60.111 -11.951,-14.854 -31.628,-21.141 -50.153,-21.429 -23.204,-0.072 -46.409,0 -69.613,-0.024 z" style="fill:#1c72ba;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path54" /> id="g52"
transform="translate(1262.7214,1613.126)">
<path
d="m 0,0 c 23.204,0.024 46.385,0.048 69.589,0 17.278,-0.24 35.275,-5.711 47.537,-18.357 16.294,-18.861 16.797,-45.593 17.277,-69.23 -0.072,-43.985 0,-87.994 -0.024,-131.979 -0.696,-20.589 -2.183,-42.834 -14.613,-60.111 -11.951,-14.854 -31.628,-21.141 -50.153,-21.429 -23.204,-0.072 -46.409,0 -69.613,-0.024 z"
style="fill:#1c72ba;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path54" />
</g> </g>
</g> </g>
</g> </g>

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -18,23 +18,23 @@ repositories {
} }
dependencies { dependencies {
api(projects.plotSquaredCore) api(projects.plotsquaredCore)
// Metrics // Metrics
implementation("org.bstats:bstats-bukkit") implementation(libs.bstatsBukkit)
// Paper // Paper
compileOnly("io.papermc.paper:paper-api") compileOnly(libs.paper)
implementation("io.papermc:paperlib") implementation(libs.paperlib)
// Plugins // Plugins
compileOnly(libs.worldeditBukkit) { compileOnly(libs.worldeditBukkit) {
exclude(group = "org.bukkit") exclude(group = "org.bukkit")
exclude(group = "org.spigotmc") exclude(group = "org.spigotmc")
} }
compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Bukkit") { isTransitive = false } compileOnly(libs.faweBukkit) { isTransitive = false }
testImplementation("com.fastasyncworldedit:FastAsyncWorldEdit-Bukkit") { isTransitive = false } testImplementation(libs.faweBukkit) { isTransitive = false }
compileOnly("com.github.MilkBowl:VaultAPI") { compileOnly(libs.vault) {
exclude(group = "org.bukkit") exclude(group = "org.bukkit")
} }
compileOnly(libs.placeholderapi) compileOnly(libs.placeholderapi)
@ -44,15 +44,15 @@ dependencies {
// Other libraries // Other libraries
implementation(libs.squirrelid) { isTransitive = false } implementation(libs.squirrelid) { isTransitive = false }
implementation("dev.notmyfault.serverlib:ServerLib") implementation(libs.serverlib)
// Our libraries // Our libraries
implementation(libs.arkitektonika) implementation(libs.arkitektonika)
implementation("com.intellectualsites.paster:Paster") implementation(libs.paster)
implementation("com.intellectualsites.informative-annotations:informative-annotations") implementation(libs.informativeAnnotations)
// Adventure // Adventure
implementation("net.kyori:adventure-platform-bukkit") implementation(libs.adventureBukkit)
} }
tasks.processResources { tasks.processResources {
@ -62,10 +62,12 @@ tasks.processResources {
} }
tasks.named<ShadowJar>("shadowJar") { tasks.named<ShadowJar>("shadowJar") {
dependsOn(":plotsquared-core:shadowJar")
dependencies { dependencies {
exclude(dependency("org.checkerframework:")) exclude(dependency("org.checkerframework:"))
} }
relocate("net.kyori.option", "com.plotsquared.core.configuration.option")
relocate("net.kyori.adventure", "com.plotsquared.core.configuration.adventure") relocate("net.kyori.adventure", "com.plotsquared.core.configuration.adventure")
relocate("net.kyori.examination", "com.plotsquared.core.configuration.examination") relocate("net.kyori.examination", "com.plotsquared.core.configuration.examination")
relocate("io.papermc.lib", "com.plotsquared.bukkit.paperlib") relocate("io.papermc.lib", "com.plotsquared.bukkit.paperlib")
@ -99,12 +101,12 @@ tasks {
withType<Javadoc> { withType<Javadoc> {
val isRelease = if (rootProject.version.toString().endsWith("-SNAPSHOT")) "TODO" else rootProject.version.toString() val isRelease = if (rootProject.version.toString().endsWith("-SNAPSHOT")) "TODO" else rootProject.version.toString()
val opt = options as StandardJavadocDocletOptions val opt = options as StandardJavadocDocletOptions
opt.links("https://jd.papermc.io/paper/1.19/") opt.links("https://jd.papermc.io/paper/1.20/")
opt.links("https://docs.enginehub.org/javadoc/com.sk89q.worldedit/worldedit-bukkit/" + libs.worldeditBukkit.get().versionConstraint.toString()) opt.links("https://docs.enginehub.org/javadoc/com.sk89q.worldedit/worldedit-bukkit/" + libs.worldeditBukkit.get().versionConstraint.toString())
opt.links("https://intellectualsites.github.io/plotsquared-javadocs/core/") opt.links("https://intellectualsites.github.io/plotsquared-javadocs/core/")
opt.links("https://jd.adventure.kyori.net/api/4.12.0/") opt.links("https://jd.advntr.dev/api/4.14.0/")
opt.links("https://google.github.io/guice/api-docs/" + libs.guice.get().versionConstraint.toString() + "/javadoc/") opt.links("https://google.github.io/guice/api-docs/" + libs.guice.get().versionConstraint.toString() + "/javadoc/")
opt.links("https://checkerframework.org/api/") // opt.links("https://checkerframework.org/api/")
opt.isLinkSource = true opt.isLinkSource = true
opt.bottom(File("$rootDir/javadocfooter.html").readText()) opt.bottom(File("$rootDir/javadocfooter.html").readText())
opt.isUse = true opt.isUse = true

View File

@ -37,6 +37,7 @@ import com.plotsquared.bukkit.listener.EntityEventListener;
import com.plotsquared.bukkit.listener.EntitySpawnListener; import com.plotsquared.bukkit.listener.EntitySpawnListener;
import com.plotsquared.bukkit.listener.PaperListener; import com.plotsquared.bukkit.listener.PaperListener;
import com.plotsquared.bukkit.listener.PlayerEventListener; import com.plotsquared.bukkit.listener.PlayerEventListener;
import com.plotsquared.bukkit.listener.PlayerEventListener1201;
import com.plotsquared.bukkit.listener.ProjectileEventListener; import com.plotsquared.bukkit.listener.ProjectileEventListener;
import com.plotsquared.bukkit.listener.ServerListener; import com.plotsquared.bukkit.listener.ServerListener;
import com.plotsquared.bukkit.listener.SingleWorldListener; import com.plotsquared.bukkit.listener.SingleWorldListener;
@ -49,8 +50,8 @@ import com.plotsquared.bukkit.player.BukkitPlayerManager;
import com.plotsquared.bukkit.util.BukkitUtil; import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.bukkit.util.BukkitWorld; import com.plotsquared.bukkit.util.BukkitWorld;
import com.plotsquared.bukkit.util.SetGenCB; import com.plotsquared.bukkit.util.SetGenCB;
import com.plotsquared.bukkit.util.UpdateUtility;
import com.plotsquared.bukkit.util.TranslationUpdateManager; import com.plotsquared.bukkit.util.TranslationUpdateManager;
import com.plotsquared.bukkit.util.UpdateUtility;
import com.plotsquared.bukkit.util.task.BukkitTaskManager; import com.plotsquared.bukkit.util.task.BukkitTaskManager;
import com.plotsquared.bukkit.util.task.PaperTimeConverter; import com.plotsquared.bukkit.util.task.PaperTimeConverter;
import com.plotsquared.bukkit.util.task.SpigotTimeConverter; import com.plotsquared.bukkit.util.task.SpigotTimeConverter;
@ -135,6 +136,7 @@ import org.bukkit.generator.ChunkGenerator;
import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.metadata.MetadataValue; import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -252,6 +254,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
} }
@Override @Override
@SuppressWarnings("deprecation") // Paper deprecation
public void onEnable() { public void onEnable() {
this.pluginName = getDescription().getName(); this.pluginName = getDescription().getName();
@ -357,6 +360,9 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
if (Settings.Enabled_Components.EVENTS) { if (Settings.Enabled_Components.EVENTS) {
getServer().getPluginManager().registerEvents(injector().getInstance(PlayerEventListener.class), this); getServer().getPluginManager().registerEvents(injector().getInstance(PlayerEventListener.class), this);
if ((serverVersion()[1] == 20 && serverVersion()[2] >= 1) || serverVersion()[1] > 20) {
getServer().getPluginManager().registerEvents(injector().getInstance(PlayerEventListener1201.class), this);
}
getServer().getPluginManager().registerEvents(injector().getInstance(BlockEventListener.class), this); getServer().getPluginManager().registerEvents(injector().getInstance(BlockEventListener.class), this);
if (serverVersion()[1] >= 17) { if (serverVersion()[1] >= 17) {
getServer().getPluginManager().registerEvents(injector().getInstance(BlockEventListener117.class), this); getServer().getPluginManager().registerEvents(injector().getInstance(BlockEventListener117.class), this);
@ -366,7 +372,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
getServer().getPluginManager().registerEvents(injector().getInstance(ServerListener.class), this); getServer().getPluginManager().registerEvents(injector().getInstance(ServerListener.class), this);
getServer().getPluginManager().registerEvents(injector().getInstance(EntitySpawnListener.class), this); getServer().getPluginManager().registerEvents(injector().getInstance(EntitySpawnListener.class), this);
if (PaperLib.isPaper() && Settings.Paper_Components.PAPER_LISTENERS) { if (PaperLib.isPaper() && Settings.Paper_Components.PAPER_LISTENERS) {
getServer().getPluginManager().registerEvents(injector().getInstance(PaperListener.class), this); getServer().getPluginManager().registerEvents(injector().getInstance(PaperListener.class), this);
} else { } else {
getServer().getPluginManager().registerEvents(injector().getInstance(SpigotListener.class), this); getServer().getPluginManager().registerEvents(injector().getInstance(SpigotListener.class), this);
} }
@ -550,7 +556,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
this.startMetrics(); this.startMetrics();
if (Settings.Enabled_Components.WORLDS) { if (Settings.Enabled_Components.WORLDS) {
TaskManager.getPlatformImplementation().taskRepeat(this::unload, TaskTime.seconds(1L)); TaskManager.getPlatformImplementation().taskRepeat(this::unload, TaskTime.seconds(10L));
try { try {
singleWorldListener = injector().getInstance(SingleWorldListener.class); singleWorldListener = injector().getInstance(SingleWorldListener.class);
Bukkit.getPluginManager().registerEvents(singleWorldListener, this); Bukkit.getPluginManager().registerEvents(singleWorldListener, this);
@ -773,6 +779,13 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
Iterator<Entity> iterator = entities.iterator(); Iterator<Entity> iterator = entities.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
Entity entity = iterator.next(); Entity entity = iterator.next();
if (PaperLib.isPaper() && "CUSTOM".equals(entity.getEntitySpawnReason().name())) {
continue;
}
// Fallback for Spigot not having Entity#getEntitySpawnReason
if (entity.getMetadata("ps_custom_spawned").stream().anyMatch(MetadataValue::asBoolean)) {
continue;
}
switch (entity.getType().toString()) { switch (entity.getType().toString()) {
case "EGG": case "EGG":
case "FISHING_HOOK": case "FISHING_HOOK":
@ -812,6 +825,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
case "MINECART_MOB_SPAWNER": case "MINECART_MOB_SPAWNER":
case "ENDER_CRYSTAL": case "ENDER_CRYSTAL":
case "MINECART_TNT": case "MINECART_TNT":
case "CHEST_BOAT":
case "BOAT": case "BOAT":
if (Settings.Enabled_Components.KILL_ROAD_VEHICLES) { if (Settings.Enabled_Components.KILL_ROAD_VEHICLES) {
com.plotsquared.core.location.Location location = BukkitUtil.adapt(entity.getLocation()); com.plotsquared.core.location.Location location = BukkitUtil.adapt(entity.getLocation());
@ -860,8 +874,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
if (livingEntity.isLeashed() && !Settings.Enabled_Components.KILL_OWNED_ROAD_MOBS) { if (livingEntity.isLeashed() && !Settings.Enabled_Components.KILL_OWNED_ROAD_MOBS) {
continue; continue;
} }
List<MetadataValue> keep = entity.getMetadata("keep"); if (entity.hasMetadata("keep")) {
if (!keep.isEmpty()) {
continue; continue;
} }
@ -1160,6 +1173,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
return new BukkitPlotGenerator(world, generator, this.plotAreaManager); return new BukkitPlotGenerator(world, generator, this.plotAreaManager);
} }
@SuppressWarnings("deprecation") // Paper deprecation
@Override @Override
public @NonNull String pluginsFormatted() { public @NonNull String pluginsFormatted() {
StringBuilder msg = new StringBuilder(); StringBuilder msg = new StringBuilder();
@ -1176,18 +1190,37 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
.append(" • Load Before: ").append(p.getDescription().getLoadBefore()).append("\n") .append(" • Load Before: ").append(p.getDescription().getLoadBefore()).append("\n")
.append(" • Dependencies: ").append(p.getDescription().getDepend()).append("\n") .append(" • Dependencies: ").append(p.getDescription().getDepend()).append("\n")
.append(" • Soft Dependencies: ").append(p.getDescription().getSoftDepend()).append("\n"); .append(" • Soft Dependencies: ").append(p.getDescription().getSoftDepend()).append("\n");
List<RegisteredServiceProvider<?>> providers = Bukkit.getServicesManager().getRegistrations(p);
if (!providers.isEmpty()) {
msg.append(" • Provided Services: \n");
for (RegisteredServiceProvider<?> provider : providers) {
msg.append("")
.append(provider.getService().getName()).append(" = ")
.append(provider.getProvider().getClass().getName())
.append(" (priority: ").append(provider.getPriority()).append(")")
.append("\n");
}
}
} }
return msg.toString(); return msg.toString();
} }
@Override @Override
@SuppressWarnings("ConstantConditions") @SuppressWarnings({"ConstantConditions", "deprecation"}) // Paper deprecation
public @NonNull String worldEditImplementations() { public @NonNull String worldEditImplementations() {
StringBuilder msg = new StringBuilder(); StringBuilder msg = new StringBuilder();
if (Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit") != null) { if (Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit") != null) {
msg.append("FastAsyncWorldEdit: ").append(Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit").getDescription().getVersion()); msg.append("FastAsyncWorldEdit: ").append(Bukkit
.getPluginManager()
.getPlugin("FastAsyncWorldEdit")
.getDescription()
.getVersion());
} else if (Bukkit.getPluginManager().getPlugin("AsyncWorldEdit") != null) { } else if (Bukkit.getPluginManager().getPlugin("AsyncWorldEdit") != null) {
msg.append("AsyncWorldEdit: ").append(Bukkit.getPluginManager().getPlugin("AsyncWorldEdit").getDescription().getVersion()).append("\n"); msg.append("AsyncWorldEdit: ").append(Bukkit
.getPluginManager()
.getPlugin("AsyncWorldEdit")
.getDescription()
.getVersion()).append("\n");
msg.append("WorldEdit: ").append(Bukkit.getPluginManager().getPlugin("WorldEdit").getDescription().getVersion()); msg.append("WorldEdit: ").append(Bukkit.getPluginManager().getPlugin("WorldEdit").getDescription().getVersion());
} else { } else {
msg.append("WorldEdit: ").append(Bukkit.getPluginManager().getPlugin("WorldEdit").getDescription().getVersion()); msg.append("WorldEdit: ").append(Bukkit.getPluginManager().getPlugin("WorldEdit").getDescription().getVersion());

View File

@ -33,6 +33,7 @@ import org.bukkit.entity.Ageable;
import org.bukkit.entity.ArmorStand; import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Bat; import org.bukkit.entity.Bat;
import org.bukkit.entity.Boat; import org.bukkit.entity.Boat;
import org.bukkit.entity.Breedable;
import org.bukkit.entity.ChestedHorse; import org.bukkit.entity.ChestedHorse;
import org.bukkit.entity.EnderDragon; import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
@ -74,6 +75,7 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
private HorseStats horse; private HorseStats horse;
private boolean noGravity; private boolean noGravity;
@SuppressWarnings("deprecation") // Deprecation exists since 1.20, while we support 1.16 onwards
public ReplicatingEntityWrapper(Entity entity, short depth) { public ReplicatingEntityWrapper(Entity entity, short depth) {
super(entity); super(entity);
@ -101,50 +103,26 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
this.noGravity = true; this.noGravity = true;
} }
switch (entity.getType().toString()) { switch (entity.getType().toString()) {
case "BOAT": case "BOAT" -> {
Boat boat = (Boat) entity; Boat boat = (Boat) entity;
this.dataByte = getOrdinal(TreeSpecies.values(), boat.getWoodType()); this.dataByte = getOrdinal(TreeSpecies.values(), boat.getWoodType());
return; return;
case "ARROW": }
case "EGG": case "ARROW", "EGG", "ENDER_CRYSTAL", "ENDER_PEARL", "ENDER_SIGNAL", "EXPERIENCE_ORB", "FALLING_BLOCK", "FIREBALL",
case "ENDER_CRYSTAL": "FIREWORK", "FISHING_HOOK", "LEASH_HITCH", "LIGHTNING", "MINECART", "MINECART_COMMAND", "MINECART_MOB_SPAWNER",
case "ENDER_PEARL": "MINECART_TNT", "PLAYER", "PRIMED_TNT", "SLIME", "SMALL_FIREBALL", "SNOWBALL", "MINECART_FURNACE", "SPLASH_POTION",
case "ENDER_SIGNAL": "THROWN_EXP_BOTTLE", "WITHER_SKULL", "UNKNOWN", "SPECTRAL_ARROW", "SHULKER_BULLET", "DRAGON_FIREBALL", "AREA_EFFECT_CLOUD",
case "EXPERIENCE_ORB": "TRIDENT", "LLAMA_SPIT" -> {
case "FALLING_BLOCK":
case "FIREBALL":
case "FIREWORK":
case "FISHING_HOOK":
case "LEASH_HITCH":
case "LIGHTNING":
case "MINECART":
case "MINECART_COMMAND":
case "MINECART_MOB_SPAWNER":
case "MINECART_TNT":
case "PLAYER":
case "PRIMED_TNT":
case "SLIME":
case "SMALL_FIREBALL":
case "SNOWBALL":
case "MINECART_FURNACE":
case "SPLASH_POTION":
case "THROWN_EXP_BOTTLE":
case "WITHER_SKULL":
case "UNKNOWN":
case "SPECTRAL_ARROW":
case "SHULKER_BULLET":
case "DRAGON_FIREBALL":
case "AREA_EFFECT_CLOUD":
case "TRIDENT":
case "LLAMA_SPIT":
// Do this stuff later // Do this stuff later
return; return;
}
// MISC // // MISC //
case "DROPPED_ITEM": case "DROPPED_ITEM" -> {
Item item = (Item) entity; Item item = (Item) entity;
this.stack = item.getItemStack(); this.stack = item.getItemStack();
return; return;
case "ITEM_FRAME": }
case "ITEM_FRAME" -> {
this.x = Math.floor(this.getX()); this.x = Math.floor(this.getX());
this.y = Math.floor(this.getY()); this.y = Math.floor(this.getY());
this.z = Math.floor(this.getZ()); this.z = Math.floor(this.getZ());
@ -152,7 +130,8 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
this.dataByte = getOrdinal(Rotation.values(), itemFrame.getRotation()); this.dataByte = getOrdinal(Rotation.values(), itemFrame.getRotation());
this.stack = itemFrame.getItem().clone(); this.stack = itemFrame.getItem().clone();
return; return;
case "PAINTING": }
case "PAINTING" -> {
this.x = Math.floor(this.getX()); this.x = Math.floor(this.getX());
this.y = Math.floor(this.getY()); this.y = Math.floor(this.getY());
this.z = Math.floor(this.getZ()); this.z = Math.floor(this.getZ());
@ -165,20 +144,17 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
} }
this.dataString = art.name(); this.dataString = art.name();
return; return;
}
// END MISC // // END MISC //
// INVENTORY HOLDER // // INVENTORY HOLDER //
case "MINECART_CHEST": case "MINECART_CHEST", "MINECART_HOPPER" -> {
case "MINECART_HOPPER":
storeInventory((InventoryHolder) entity); storeInventory((InventoryHolder) entity);
return; return;
}
// START LIVING ENTITY // // START LIVING ENTITY //
// START AGEABLE // // START AGEABLE //
// START TAMEABLE // // START TAMEABLE //
case "HORSE": case "HORSE", "DONKEY", "LLAMA", "MULE", "SKELETON_HORSE" -> {
case "DONKEY":
case "LLAMA":
case "MULE":
case "SKELETON_HORSE":
AbstractHorse horse = (AbstractHorse) entity; AbstractHorse horse = (AbstractHorse) entity;
this.horse = new HorseStats(); this.horse = new HorseStats();
this.horse.jump = horse.getJumpStrength(); this.horse.jump = horse.getJumpStrength();
@ -190,20 +166,21 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
//this.horse.style = horse.getStyle(); //this.horse.style = horse.getStyle();
//this.horse.color = horse.getColor(); //this.horse.color = horse.getColor();
storeTameable(horse); storeTameable(horse);
storeAgeable(horse); storeBreedable(horse);
storeLiving(horse); storeLiving(horse);
storeInventory(horse); storeInventory(horse);
return; return;
}
// END INVENTORY HOLDER // // END INVENTORY HOLDER //
case "WOLF": case "WOLF", "OCELOT" -> {
case "OCELOT":
storeTameable((Tameable) entity); storeTameable((Tameable) entity);
storeAgeable((Ageable) entity); storeBreedable((Breedable) entity);
storeLiving((LivingEntity) entity); storeLiving((LivingEntity) entity);
return; return;
}
// END TAMEABLE // // END TAMEABLE //
//todo fix sheep //todo fix sheep
case "SHEEP": case "SHEEP" -> {
Sheep sheep = (Sheep) entity; Sheep sheep = (Sheep) entity;
if (sheep.isSheared()) { if (sheep.isSheared()) {
this.dataByte = (byte) 1; this.dataByte = (byte) 1;
@ -211,26 +188,23 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
this.dataByte = (byte) 0; this.dataByte = (byte) 0;
} }
this.dataByte2 = sheep.getColor().getDyeData(); this.dataByte2 = sheep.getColor().getDyeData();
storeAgeable(sheep); storeBreedable(sheep);
storeLiving(sheep); storeLiving(sheep);
return; return;
case "VILLAGER": }
case "CHICKEN": case "VILLAGER", "CHICKEN", "COW", "MUSHROOM_COW", "PIG", "TURTLE", "POLAR_BEAR" -> {
case "COW": storeBreedable((Breedable) entity);
case "MUSHROOM_COW":
case "PIG":
case "TURTLE":
case "POLAR_BEAR":
storeAgeable((Ageable) entity);
storeLiving((LivingEntity) entity); storeLiving((LivingEntity) entity);
return; return;
case "RABBIT": }
case "RABBIT" -> {
this.dataByte = getOrdinal(Rabbit.Type.values(), ((Rabbit) entity).getRabbitType()); this.dataByte = getOrdinal(Rabbit.Type.values(), ((Rabbit) entity).getRabbitType());
storeAgeable((Ageable) entity); storeBreedable((Breedable) entity);
storeLiving((LivingEntity) entity); storeLiving((LivingEntity) entity);
return; return;
}
// END AGEABLE // // END AGEABLE //
case "ARMOR_STAND": case "ARMOR_STAND" -> {
ArmorStand stand = (ArmorStand) entity; ArmorStand stand = (ArmorStand) entity;
this.inventory = this.inventory =
new ItemStack[]{stand.getItemInHand().clone(), stand.getHelmet().clone(), new ItemStack[]{stand.getItemInHand().clone(), stand.getHelmet().clone(),
@ -238,37 +212,30 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
stand.getBoots().clone()}; stand.getBoots().clone()};
storeLiving(stand); storeLiving(stand);
this.stand = new ArmorStandStats(); this.stand = new ArmorStandStats();
EulerAngle head = stand.getHeadPose(); EulerAngle head = stand.getHeadPose();
this.stand.head[0] = (float) head.getX(); this.stand.head[0] = (float) head.getX();
this.stand.head[1] = (float) head.getY(); this.stand.head[1] = (float) head.getY();
this.stand.head[2] = (float) head.getZ(); this.stand.head[2] = (float) head.getZ();
EulerAngle body = stand.getBodyPose(); EulerAngle body = stand.getBodyPose();
this.stand.body[0] = (float) body.getX(); this.stand.body[0] = (float) body.getX();
this.stand.body[1] = (float) body.getY(); this.stand.body[1] = (float) body.getY();
this.stand.body[2] = (float) body.getZ(); this.stand.body[2] = (float) body.getZ();
EulerAngle leftLeg = stand.getLeftLegPose(); EulerAngle leftLeg = stand.getLeftLegPose();
this.stand.leftLeg[0] = (float) leftLeg.getX(); this.stand.leftLeg[0] = (float) leftLeg.getX();
this.stand.leftLeg[1] = (float) leftLeg.getY(); this.stand.leftLeg[1] = (float) leftLeg.getY();
this.stand.leftLeg[2] = (float) leftLeg.getZ(); this.stand.leftLeg[2] = (float) leftLeg.getZ();
EulerAngle rightLeg = stand.getRightLegPose(); EulerAngle rightLeg = stand.getRightLegPose();
this.stand.rightLeg[0] = (float) rightLeg.getX(); this.stand.rightLeg[0] = (float) rightLeg.getX();
this.stand.rightLeg[1] = (float) rightLeg.getY(); this.stand.rightLeg[1] = (float) rightLeg.getY();
this.stand.rightLeg[2] = (float) rightLeg.getZ(); this.stand.rightLeg[2] = (float) rightLeg.getZ();
EulerAngle leftArm = stand.getLeftArmPose(); EulerAngle leftArm = stand.getLeftArmPose();
this.stand.leftArm[0] = (float) leftArm.getX(); this.stand.leftArm[0] = (float) leftArm.getX();
this.stand.leftArm[1] = (float) leftArm.getY(); this.stand.leftArm[1] = (float) leftArm.getY();
this.stand.leftArm[2] = (float) leftArm.getZ(); this.stand.leftArm[2] = (float) leftArm.getZ();
EulerAngle rightArm = stand.getRightArmPose(); EulerAngle rightArm = stand.getRightArmPose();
this.stand.rightArm[0] = (float) rightArm.getX(); this.stand.rightArm[0] = (float) rightArm.getX();
this.stand.rightArm[1] = (float) rightArm.getY(); this.stand.rightArm[1] = (float) rightArm.getY();
this.stand.rightArm[2] = (float) rightArm.getZ(); this.stand.rightArm[2] = (float) rightArm.getZ();
if (stand.hasArms()) { if (stand.hasArms()) {
this.stand.arms = true; this.stand.arms = true;
} }
@ -282,53 +249,38 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
this.stand.small = true; this.stand.small = true;
} }
return; return;
case "ENDERMITE": }
case "ENDERMITE" -> {
return; return;
case "BAT": }
case "BAT" -> {
if (((Bat) entity).isAwake()) { if (((Bat) entity).isAwake()) {
this.dataByte = (byte) 1; this.dataByte = (byte) 1;
} else { } else {
this.dataByte = (byte) 0; this.dataByte = (byte) 0;
} }
return; return;
case "ENDER_DRAGON": }
case "ENDER_DRAGON" -> {
EnderDragon entity1 = (EnderDragon) entity; EnderDragon entity1 = (EnderDragon) entity;
this.dataByte = (byte) entity1.getPhase().ordinal(); this.dataByte = (byte) entity1.getPhase().ordinal();
return; return;
case "SKELETON": }
case "WITHER_SKELETON": case "SKELETON", "WITHER_SKELETON", "GUARDIAN", "ELDER_GUARDIAN", "GHAST", "MAGMA_CUBE", "SQUID", "PIG_ZOMBIE", "HOGLIN",
case "GUARDIAN": "ZOMBIFIED_PIGLIN", "PIGLIN", "PIGLIN_BRUTE", "ZOMBIE", "WITHER", "WITCH", "SPIDER", "CAVE_SPIDER", "SILVERFISH",
case "ELDER_GUARDIAN": "GIANT", "ENDERMAN", "CREEPER", "BLAZE", "SHULKER", "SNOWMAN" -> {
case "GHAST":
case "MAGMA_CUBE":
case "SQUID":
case "PIG_ZOMBIE":
case "HOGLIN":
case "ZOMBIFIED_PIGLIN":
case "PIGLIN":
case "PIGLIN_BRUTE":
case "ZOMBIE":
case "WITHER":
case "WITCH":
case "SPIDER":
case "CAVE_SPIDER":
case "SILVERFISH":
case "GIANT":
case "ENDERMAN":
case "CREEPER":
case "BLAZE":
case "SHULKER":
case "SNOWMAN":
storeLiving((LivingEntity) entity); storeLiving((LivingEntity) entity);
return; return;
case "IRON_GOLEM": }
case "IRON_GOLEM" -> {
if (((IronGolem) entity).isPlayerCreated()) { if (((IronGolem) entity).isPlayerCreated()) {
this.dataByte = (byte) 1; this.dataByte = (byte) 1;
} else { } else {
this.dataByte = (byte) 0; this.dataByte = (byte) 0;
} }
storeLiving((LivingEntity) entity); storeLiving((LivingEntity) entity);
// END LIVING // }
// END LIVING //
} }
} }
@ -431,6 +383,11 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
} }
} }
/**
* @deprecated Use {@link #restoreBreedable(Breedable)} instead
* @since 7.1.0
*/
@Deprecated(forRemoval = true, since = "7.1.0")
private void restoreAgeable(Ageable entity) { private void restoreAgeable(Ageable entity) {
if (!this.aged.adult) { if (!this.aged.adult) {
entity.setBaby(); entity.setBaby();
@ -441,6 +398,11 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
} }
} }
/**
* @deprecated Use {@link #storeBreedable(Breedable)} instead
* @since 7.1.0
*/
@Deprecated(forRemoval = true, since = "7.1.0")
public void storeAgeable(Ageable aged) { public void storeAgeable(Ageable aged) {
this.aged = new AgeableStats(); this.aged = new AgeableStats();
this.aged.age = aged.getAge(); this.aged.age = aged.getAge();
@ -448,6 +410,29 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
this.aged.adult = aged.isAdult(); this.aged.adult = aged.isAdult();
} }
/**
* @since 7.1.0
*/
private void restoreBreedable(Breedable entity) {
if (!this.aged.adult) {
entity.setBaby();
}
entity.setAgeLock(this.aged.locked);
if (this.aged.age > 0) {
entity.setAge(this.aged.age);
}
}
/**
* @since 7.1.0
*/
private void storeBreedable(Breedable breedable) {
this.aged = new AgeableStats();
this.aged.age = breedable.getAge();
this.aged.locked = breedable.getAgeLock();
this.aged.adult = breedable.isAdult();
}
public void storeTameable(Tameable tamed) { public void storeTameable(Tameable tamed) {
this.tamed = new TameableStats(); this.tamed = new TameableStats();
this.tamed.owner = tamed.getOwner(); this.tamed.owner = tamed.getOwner();
@ -465,20 +450,15 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
} }
Entity entity; Entity entity;
switch (this.getType().toString()) { switch (this.getType().toString()) {
case "DROPPED_ITEM": case "DROPPED_ITEM" -> {
return world.dropItem(location, this.stack); return world.dropItem(location, this.stack);
case "PLAYER": }
case "LEASH_HITCH": case "PLAYER", "LEASH_HITCH" -> {
return null; return null;
case "ITEM_FRAME": }
entity = world.spawn(location, ItemFrame.class); case "ITEM_FRAME" -> entity = world.spawn(location, ItemFrame.class);
break; case "PAINTING" -> entity = world.spawn(location, Painting.class);
case "PAINTING": default -> entity = world.spawnEntity(location, this.getType());
entity = world.spawn(location, Painting.class);
break;
default:
entity = world.spawnEntity(location, this.getType());
break;
} }
if (this.depth == 0) { if (this.depth == 0) {
return entity; return entity;
@ -506,72 +486,46 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
entity.setGravity(false); entity.setGravity(false);
} }
switch (entity.getType().toString()) { switch (entity.getType().toString()) {
case "BOAT": case "BOAT" -> {
Boat boat = (Boat) entity; Boat boat = (Boat) entity;
boat.setWoodType(TreeSpecies.values()[dataByte]); boat.setWoodType(TreeSpecies.values()[dataByte]);
return entity; return entity;
case "SLIME": }
case "SLIME" -> {
((Slime) entity).setSize(this.dataByte); ((Slime) entity).setSize(this.dataByte);
return entity; return entity;
case "ARROW": }
case "EGG": case "ARROW", "EGG", "ENDER_CRYSTAL", "ENDER_PEARL", "ENDER_SIGNAL", "DROPPED_ITEM", "EXPERIENCE_ORB", "FALLING_BLOCK",
case "ENDER_CRYSTAL": "FIREBALL", "FIREWORK", "FISHING_HOOK", "LEASH_HITCH", "LIGHTNING", "MINECART", "MINECART_COMMAND",
case "ENDER_PEARL": "MINECART_MOB_SPAWNER", "MINECART_TNT", "PLAYER", "PRIMED_TNT", "SMALL_FIREBALL", "SNOWBALL",
case "ENDER_SIGNAL": "SPLASH_POTION", "THROWN_EXP_BOTTLE", "SPECTRAL_ARROW", "SHULKER_BULLET", "AREA_EFFECT_CLOUD",
case "DROPPED_ITEM": "DRAGON_FIREBALL", "WITHER_SKULL", "MINECART_FURNACE", "LLAMA_SPIT", "TRIDENT", "UNKNOWN" -> {
case "EXPERIENCE_ORB":
case "FALLING_BLOCK":
case "FIREBALL":
case "FIREWORK":
case "FISHING_HOOK":
case "LEASH_HITCH":
case "LIGHTNING":
case "MINECART":
case "MINECART_COMMAND":
case "MINECART_MOB_SPAWNER":
case "MINECART_TNT":
case "PLAYER":
case "PRIMED_TNT":
case "SMALL_FIREBALL":
case "SNOWBALL":
case "SPLASH_POTION":
case "THROWN_EXP_BOTTLE":
case "SPECTRAL_ARROW":
case "SHULKER_BULLET":
case "AREA_EFFECT_CLOUD":
case "DRAGON_FIREBALL":
case "WITHER_SKULL":
case "MINECART_FURNACE":
case "LLAMA_SPIT":
case "TRIDENT":
case "UNKNOWN":
// Do this stuff later // Do this stuff later
return entity; return entity;
}
// MISC // // MISC //
case "ITEM_FRAME": case "ITEM_FRAME" -> {
ItemFrame itemframe = (ItemFrame) entity; ItemFrame itemframe = (ItemFrame) entity;
itemframe.setRotation(Rotation.values()[this.dataByte]); itemframe.setRotation(Rotation.values()[this.dataByte]);
itemframe.setItem(this.stack); itemframe.setItem(this.stack);
return entity; return entity;
case "PAINTING": }
case "PAINTING" -> {
Painting painting = (Painting) entity; Painting painting = (Painting) entity;
painting.setFacingDirection(BlockFace.values()[this.dataByte], true); painting.setFacingDirection(BlockFace.values()[this.dataByte], true);
painting.setArt(Art.getByName(this.dataString), true); painting.setArt(Art.getByName(this.dataString), true);
return entity; return entity;
}
// END MISC // // END MISC //
// INVENTORY HOLDER // // INVENTORY HOLDER //
case "MINECART_CHEST": case "MINECART_CHEST", "MINECART_HOPPER" -> {
case "MINECART_HOPPER":
restoreInventory((InventoryHolder) entity); restoreInventory((InventoryHolder) entity);
return entity; return entity;
}
// START LIVING ENTITY // // START LIVING ENTITY //
// START AGEABLE // // START AGEABLE //
// START TAMEABLE // // START TAMEABLE //
case "HORSE": case "HORSE", "LLAMA", "SKELETON_HORSE", "DONKEY", "MULE" -> {
case "LLAMA":
case "SKELETON_HORSE":
case "DONKEY":
case "MULE":
AbstractHorse horse = (AbstractHorse) entity; AbstractHorse horse = (AbstractHorse) entity;
horse.setJumpStrength(this.horse.jump); horse.setJumpStrength(this.horse.jump);
if (horse instanceof ChestedHorse) { if (horse instanceof ChestedHorse) {
@ -582,19 +536,20 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
//horse.setStyle(this.horse.style); //horse.setStyle(this.horse.style);
//horse.setColor(this.horse.color); //horse.setColor(this.horse.color);
restoreTameable(horse); restoreTameable(horse);
restoreAgeable(horse); restoreBreedable(horse);
restoreLiving(horse); restoreLiving(horse);
restoreInventory(horse); restoreInventory(horse);
return entity; return entity;
}
// END INVENTORY HOLDER // // END INVENTORY HOLDER //
case "WOLF": case "WOLF", "OCELOT" -> {
case "OCELOT":
restoreTameable((Tameable) entity); restoreTameable((Tameable) entity);
restoreAgeable((Ageable) entity); restoreBreedable((Breedable) entity);
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
}
// END AGEABLE // // END AGEABLE //
case "SHEEP": case "SHEEP" -> {
Sheep sheep = (Sheep) entity; Sheep sheep = (Sheep) entity;
if (this.dataByte == 1) { if (this.dataByte == 1) {
sheep.setSheared(true); sheep.setSheared(true);
@ -602,28 +557,25 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
if (this.dataByte2 != 0) { if (this.dataByte2 != 0) {
sheep.setColor(DyeColor.getByDyeData(this.dataByte2)); sheep.setColor(DyeColor.getByDyeData(this.dataByte2));
} }
restoreAgeable(sheep); restoreBreedable(sheep);
restoreLiving(sheep); restoreLiving(sheep);
return sheep; return sheep;
case "VILLAGER": }
case "CHICKEN": case "VILLAGER", "CHICKEN", "COW", "TURTLE", "POLAR_BEAR", "MUSHROOM_COW", "PIG" -> {
case "COW": restoreBreedable((Breedable) entity);
case "TURTLE":
case "POLAR_BEAR":
case "MUSHROOM_COW":
case "PIG":
restoreAgeable((Ageable) entity);
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
}
// END AGEABLE // // END AGEABLE //
case "RABBIT": case "RABBIT" -> {
if (this.dataByte != 0) { if (this.dataByte != 0) {
((Rabbit) entity).setRabbitType(Rabbit.Type.values()[this.dataByte]); ((Rabbit) entity).setRabbitType(Rabbit.Type.values()[this.dataByte]);
} }
restoreAgeable((Ageable) entity); restoreBreedable((Breedable) entity);
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
case "ARMOR_STAND": }
case "ARMOR_STAND" -> {
// CHECK positions // CHECK positions
ArmorStand stand = (ArmorStand) entity; ArmorStand stand = (ArmorStand) entity;
if (this.inventory[0] != null) { if (this.inventory[0] != null) {
@ -693,56 +645,38 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
} }
restoreLiving(stand); restoreLiving(stand);
return stand; return stand;
case "BAT": }
case "BAT" -> {
if (this.dataByte != 0) { if (this.dataByte != 0) {
((Bat) entity).setAwake(true); ((Bat) entity).setAwake(true);
} }
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
case "ENDER_DRAGON": }
case "ENDER_DRAGON" -> {
if (this.dataByte != 0) { if (this.dataByte != 0) {
((EnderDragon) entity).setPhase(EnderDragon.Phase.values()[this.dataByte]); ((EnderDragon) entity).setPhase(EnderDragon.Phase.values()[this.dataByte]);
} }
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
case "ENDERMITE": }
case "GHAST": case "ENDERMITE", "GHAST", "MAGMA_CUBE", "SQUID", "PIG_ZOMBIE", "HOGLIN", "PIGLIN", "ZOMBIFIED_PIGLIN", "PIGLIN_BRUTE", "ZOMBIE", "WITHER", "WITCH", "SPIDER", "CAVE_SPIDER", "SILVERFISH", "GIANT", "ENDERMAN", "CREEPER", "BLAZE", "SNOWMAN", "SHULKER", "GUARDIAN", "ELDER_GUARDIAN", "SKELETON", "WITHER_SKELETON" -> {
case "MAGMA_CUBE":
case "SQUID":
case "PIG_ZOMBIE":
case "HOGLIN":
case "PIGLIN":
case "ZOMBIFIED_PIGLIN":
case "PIGLIN_BRUTE":
case "ZOMBIE":
case "WITHER":
case "WITCH":
case "SPIDER":
case "CAVE_SPIDER":
case "SILVERFISH":
case "GIANT":
case "ENDERMAN":
case "CREEPER":
case "BLAZE":
case "SNOWMAN":
case "SHULKER":
case "GUARDIAN":
case "ELDER_GUARDIAN":
case "SKELETON":
case "WITHER_SKELETON":
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
case "IRON_GOLEM": }
case "IRON_GOLEM" -> {
if (this.dataByte != 0) { if (this.dataByte != 0) {
((IronGolem) entity).setPlayerCreated(true); ((IronGolem) entity).setPlayerCreated(true);
} }
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
default: }
default -> {
if (Settings.DEBUG) { if (Settings.DEBUG) {
LOGGER.info("Could not identify entity: {}", entity.getType()); LOGGER.info("Could not identify entity: {}", entity.getType());
} }
return entity; return entity;
}
// END LIVING // END LIVING
} }
} }

View File

@ -34,9 +34,12 @@ import com.plotsquared.core.queue.ZeroedDelegateScopedQueueCoordinator;
import com.plotsquared.core.util.ChunkManager; import com.plotsquared.core.util.ChunkManager;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.bukkit.HeightMap; import org.bukkit.HeightMap;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.generator.BiomeProvider; import org.bukkit.generator.BiomeProvider;
@ -48,13 +51,17 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import static java.util.function.Predicate.not;
public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrapper<ChunkGenerator> { public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrapper<ChunkGenerator> {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + BukkitPlotGenerator.class.getSimpleName()); private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + BukkitPlotGenerator.class.getSimpleName());
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final boolean PAPER_ASYNC_SAFE = true; public final boolean PAPER_ASYNC_SAFE = true;
@ -185,12 +192,6 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
world.setWaterAnimalSpawnLimit(limit); world.setWaterAnimalSpawnLimit(limit);
} }
/**
* The entire method is deprecated, but kept for compatibility with versions lower than or equal to 1.16.2.
* The method will be removed in future versions, because WorldEdit and FastAsyncWorldEdit only support the latest point
* release.
*/
@Deprecated(forRemoval = true, since = "6.11.0")
@Override @Override
public void generateNoise( public void generateNoise(
@NotNull final WorldInfo worldInfo, @NotNull final WorldInfo worldInfo,
@ -283,9 +284,14 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
return super.getBaseHeight(worldInfo, random, x, z, heightMap); return super.getBaseHeight(worldInfo, random, x, z, heightMap);
} }
/**
* The entire method is deprecated, but kept for compatibility with versions lower than or equal to 1.16.2.
* The method will be removed in future versions, because WorldEdit and FastAsyncWorldEdit only support the latest point
* release.
*/
@SuppressWarnings("deprecation") // The entire method is deprecated, but kept for compatibility with <=1.16.2 @SuppressWarnings("deprecation") // The entire method is deprecated, but kept for compatibility with <=1.16.2
@Override @Override
@Deprecated(since = "TODO") @Deprecated(since = "7.0.0")
public @NonNull ChunkData generateChunkData( public @NonNull ChunkData generateChunkData(
@NonNull World world, @NonNull Random random, int x, int z, @NonNull BiomeGrid biome @NonNull World world, @NonNull Random random, int x, int z, @NonNull BiomeGrid biome
) { ) {
@ -293,8 +299,8 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
if (this.platformGenerator != this) { if (this.platformGenerator != this) {
return this.platformGenerator.generateChunkData(world, random, x, z, biome); return this.platformGenerator.generateChunkData(world, random, x, z, biome);
} else { } else {
// Return super as it will throw an exception caught by the server that will mean this method is no longer used. // Throw exception to be caught by the server that indicates the new generation API is being used.
return super.generateChunkData(world, random, x, z, biome); throw new UnsupportedOperationException("Using new generation methods. This method is unsupported.");
} }
} }
@ -415,9 +421,14 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
if (lastPlotArea != null && name.equals(this.levelName) && chunkX == lastChunkX && chunkZ == lastChunkZ) { if (lastPlotArea != null && name.equals(this.levelName) && chunkX == lastChunkX && chunkZ == lastChunkZ) {
return lastPlotArea; return lastPlotArea;
} }
PlotArea area = UncheckedWorldLocation.at(name, chunkX << 4, 0, chunkZ << 4).getPlotArea(); BlockVector3 loc = BlockVector3.at(chunkX << 4, 0, chunkZ << 4);
if (lastPlotArea != null && lastPlotArea.getRegion().contains(loc) && lastPlotArea.getRegion().contains(loc)) {
return lastPlotArea;
}
PlotArea area = UncheckedWorldLocation.at(name, loc).getPlotArea();
if (area == null) { if (area == null) {
throw new IllegalStateException(String.format("Cannot generate chunk that does not belong to a plot area. World: %s", throw new IllegalStateException(String.format(
"Cannot generate chunk that does not belong to a plot area. World: %s",
name name
)); ));
} }
@ -434,9 +445,16 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
private static final List<Biome> BIOMES; private static final List<Biome> BIOMES;
static { static {
ArrayList<Biome> biomes = new ArrayList<>(List.of(Biome.values())); Set<Biome> disabledBiomes = EnumSet.of(Biome.CUSTOM);
biomes.remove(Biome.CUSTOM); if (PlotSquared.platform().serverVersion()[1] <= 19) {
BIOMES = List.copyOf(biomes); final Biome cherryGrove = Registry.BIOME.get(NamespacedKey.minecraft("cherry_grove"));
if (cherryGrove != null) {
disabledBiomes.add(cherryGrove);
}
}
BIOMES = Arrays.stream(Biome.values())
.filter(not(disabledBiomes::contains))
.toList();
} }
@Override @Override

View File

@ -23,13 +23,13 @@ import com.google.inject.Provides;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import com.google.inject.assistedinject.FactoryModuleBuilder; import com.google.inject.assistedinject.FactoryModuleBuilder;
import com.plotsquared.bukkit.BukkitPlatform; import com.plotsquared.bukkit.BukkitPlatform;
import com.plotsquared.bukkit.listener.ServerListener;
import com.plotsquared.bukkit.listener.SingleWorldListener; import com.plotsquared.bukkit.listener.SingleWorldListener;
import com.plotsquared.bukkit.player.BukkitPlayerManager; import com.plotsquared.bukkit.player.BukkitPlayerManager;
import com.plotsquared.bukkit.queue.BukkitChunkCoordinator; import com.plotsquared.bukkit.queue.BukkitChunkCoordinator;
import com.plotsquared.bukkit.queue.BukkitQueueCoordinator; import com.plotsquared.bukkit.queue.BukkitQueueCoordinator;
import com.plotsquared.bukkit.schematic.BukkitSchematicHandler; import com.plotsquared.bukkit.schematic.BukkitSchematicHandler;
import com.plotsquared.bukkit.util.BukkitChunkManager; import com.plotsquared.bukkit.util.BukkitChunkManager;
import com.plotsquared.bukkit.util.BukkitEconHandler;
import com.plotsquared.bukkit.util.BukkitInventoryUtil; import com.plotsquared.bukkit.util.BukkitInventoryUtil;
import com.plotsquared.bukkit.util.BukkitRegionManager; import com.plotsquared.bukkit.util.BukkitRegionManager;
import com.plotsquared.bukkit.util.BukkitSetupUtils; import com.plotsquared.bukkit.util.BukkitSetupUtils;
@ -47,6 +47,9 @@ import com.plotsquared.core.inject.factory.ChunkCoordinatorBuilderFactory;
import com.plotsquared.core.inject.factory.ChunkCoordinatorFactory; import com.plotsquared.core.inject.factory.ChunkCoordinatorFactory;
import com.plotsquared.core.inject.factory.HybridPlotWorldFactory; import com.plotsquared.core.inject.factory.HybridPlotWorldFactory;
import com.plotsquared.core.inject.factory.ProgressSubscriberFactory; import com.plotsquared.core.inject.factory.ProgressSubscriberFactory;
import com.plotsquared.core.player.OfflinePlotPlayer;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.world.DefaultPlotAreaManager; import com.plotsquared.core.plot.world.DefaultPlotAreaManager;
import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.plot.world.PlotAreaManager;
import com.plotsquared.core.plot.world.SinglePlotAreaManager; import com.plotsquared.core.plot.world.SinglePlotAreaManager;
@ -72,6 +75,8 @@ import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Objects;
public class BukkitModule extends AbstractModule { public class BukkitModule extends AbstractModule {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + BukkitModule.class.getSimpleName()); private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + BukkitModule.class.getSimpleName());
@ -128,21 +133,64 @@ public class BukkitModule extends AbstractModule {
@Provides @Provides
@Singleton @Singleton
@NonNull EconHandler provideEconHandler() { @NonNull EconHandler provideEconHandler() {
if (!Settings.Enabled_Components.ECONOMY) { if (!Settings.Enabled_Components.ECONOMY || !Bukkit.getPluginManager().isPluginEnabled("Vault")) {
return EconHandler.nullEconHandler(); return EconHandler.nullEconHandler();
} }
if (Bukkit.getPluginManager().isPluginEnabled("Vault")) { // Guice eagerly initializes singletons, so we need to bring the laziness ourselves
try { return new LazyEconHandler();
BukkitEconHandler econHandler = new BukkitEconHandler(); }
if (!econHandler.init()) {
LOGGER.warn("Economy is enabled but no plugin is providing an economy service. Falling back..."); private static final class LazyEconHandler extends EconHandler implements ServerListener.MutableEconHandler {
return EconHandler.nullEconHandler(); private volatile EconHandler implementation;
}
return econHandler; public void setImplementation(EconHandler econHandler) {
} catch (final Exception ignored) { this.implementation = econHandler;
}
} }
return EconHandler.nullEconHandler();
@Override
public boolean init() {
return get().init();
}
@Override
public double getBalance(final PlotPlayer<?> player) {
return get().getBalance(player);
}
@Override
public void withdrawMoney(final PlotPlayer<?> player, final double amount) {
get().withdrawMoney(player, amount);
}
@Override
public void depositMoney(final PlotPlayer<?> player, final double amount) {
get().depositMoney(player, amount);
}
@Override
public void depositMoney(final OfflinePlotPlayer player, final double amount) {
get().depositMoney(player, amount);
}
@Override
public boolean isEnabled(final PlotArea plotArea) {
return get().isEnabled(plotArea);
}
@Override
public @NonNull String format(final double balance) {
return get().format(balance);
}
@Override
public boolean isSupported() {
return get().isSupported();
}
private EconHandler get() {
return Objects.requireNonNull(this.implementation, "EconHandler not ready yet.");
}
} }
} }

View File

@ -33,6 +33,7 @@ import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.flag.implementations.BlockBurnFlag; import com.plotsquared.core.plot.flag.implementations.BlockBurnFlag;
import com.plotsquared.core.plot.flag.implementations.BlockIgnitionFlag; import com.plotsquared.core.plot.flag.implementations.BlockIgnitionFlag;
import com.plotsquared.core.plot.flag.implementations.BreakFlag; import com.plotsquared.core.plot.flag.implementations.BreakFlag;
import com.plotsquared.core.plot.flag.implementations.ConcreteHardenFlag;
import com.plotsquared.core.plot.flag.implementations.CoralDryFlag; import com.plotsquared.core.plot.flag.implementations.CoralDryFlag;
import com.plotsquared.core.plot.flag.implementations.CropGrowFlag; import com.plotsquared.core.plot.flag.implementations.CropGrowFlag;
import com.plotsquared.core.plot.flag.implementations.DisablePhysicsFlag; import com.plotsquared.core.plot.flag.implementations.DisablePhysicsFlag;
@ -260,7 +261,10 @@ public class BlockEventListener implements Listener {
final BlockFace facing = piston.getFacing(); final BlockFace facing = piston.getFacing();
location = location.add(facing.getModX(), facing.getModY(), facing.getModZ()); location = location.add(facing.getModX(), facing.getModY(), facing.getModZ());
Plot newPlot = area.getOwnedPlotAbs(location); Plot newPlot = area.getOwnedPlotAbs(location);
if (!plot.equals(newPlot)) { if (plot.equals(newPlot)) {
return;
}
if (!plot.isMerged() || !plot.getConnectedPlots().contains(newPlot)) {
event.setCancelled(true); event.setCancelled(true);
plot.debug("Prevented piston update because of invalid edge piston detection"); plot.debug("Prevented piston update because of invalid edge piston detection");
} }
@ -586,6 +590,12 @@ public class BlockEventListener implements Listener {
event.setCancelled(true); event.setCancelled(true);
} }
} }
if (event.getNewState().getType().toString().endsWith("CONCRETE")) {
if (!plot.getFlag(ConcreteHardenFlag.class)) {
plot.debug("Concrete powder could not harden because concrete-harden = false");
event.setCancelled(true);
}
}
} }
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
@ -759,7 +769,9 @@ public class BlockEventListener implements Listener {
return; return;
} }
if (block.getBlockData() instanceof Farmland farmland && event.getNewState().getBlockData() instanceof Farmland newFarmland) { if (block.getBlockData() instanceof Farmland farmland && event
.getNewState()
.getBlockData() instanceof Farmland newFarmland) {
int currentMoisture = farmland.getMoisture(); int currentMoisture = farmland.getMoisture();
int newMoisture = newFarmland.getMoisture(); int newMoisture = newFarmland.getMoisture();
@ -1114,6 +1126,7 @@ public class BlockEventListener implements Listener {
if (plot != null) { if (plot != null) {
plot.debug("Explosion was cancelled because explosion = false"); plot.debug("Explosion was cancelled because explosion = false");
} }
return;
} }
event.blockList().removeIf(blox -> !plot.equals(area.getOwnedPlot(BukkitUtil.adapt(blox.getLocation())))); event.blockList().removeIf(blox -> !plot.equals(area.getOwnedPlot(BukkitUtil.adapt(blox.getLocation()))));
} }

View File

@ -26,6 +26,7 @@ import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.flag.implementations.CopperOxideFlag; import com.plotsquared.core.plot.flag.implementations.CopperOxideFlag;
import com.plotsquared.core.plot.flag.implementations.MiscInteractFlag; import com.plotsquared.core.plot.flag.implementations.MiscInteractFlag;
import com.plotsquared.core.plot.flag.implementations.SculkSensorInteractFlag;
import com.plotsquared.core.util.PlotFlagUtil; import com.plotsquared.core.util.PlotFlagUtil;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@ -92,12 +93,16 @@ public class BlockEventListener117 implements Listener {
} }
Plot plot = location.getOwnedPlot(); Plot plot = location.getOwnedPlot();
if (plot == null && !PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, MiscInteractFlag.class, true) || plot != null && !plot.getFlag( if (plot == null && !PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(
MiscInteractFlag.class)) { area,
MiscInteractFlag.class,
true
) || plot != null && (!plot.getFlag(MiscInteractFlag.class) || !plot.getFlag(SculkSensorInteractFlag.class))) {
if (plotPlayer != null) { if (plotPlayer != null) {
if (plot != null) { if (plot != null) {
if (!plot.isAdded(plotPlayer.getUUID())) { if (!plot.isAdded(plotPlayer.getUUID())) {
plot.debug(plotPlayer.getName() + " couldn't trigger sculk sensors because misc-interact = false"); plot.debug(plotPlayer.getName() + " couldn't trigger sculk sensors because both " +
"sculk-sensor-interact and misc-interact = false");
event.setCancelled(true); event.setCancelled(true);
} }
} }
@ -108,13 +113,15 @@ public class BlockEventListener117 implements Listener {
if (plot != null) { if (plot != null) {
if (itemThrower == null && (itemThrower = item.getOwner()) == null) { if (itemThrower == null && (itemThrower = item.getOwner()) == null) {
plot.debug( plot.debug(
"A thrown item couldn't trigger sculk sensors because misc-interact = false and the item's owner could not be resolved."); "A thrown item couldn't trigger sculk sensors because both sculk-sensor-interact and " +
"misc-interact = false and the item's owner could not be resolved.");
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
if (!plot.isAdded(itemThrower)) { if (!plot.isAdded(itemThrower)) {
if (!plot.isAdded(itemThrower)) { if (!plot.isAdded(itemThrower)) {
plot.debug("A thrown item couldn't trigger sculk sensors because misc-interact = false"); plot.debug("A thrown item couldn't trigger sculk sensors because both sculk-sensor-interact and " +
"misc-interact = false");
event.setCancelled(true); event.setCancelled(true);
} }
} }
@ -133,7 +140,6 @@ public class BlockEventListener117 implements Listener {
if (area == null) { if (area == null) {
for (int i = blocks.size() - 1; i >= 0; i--) { for (int i = blocks.size() - 1; i >= 0; i--) {
Location blockLocation = BukkitUtil.adapt(blocks.get(i).getLocation()); Location blockLocation = BukkitUtil.adapt(blocks.get(i).getLocation());
blockLocation = BukkitUtil.adapt(blocks.get(i).getLocation());
if (blockLocation.isPlotArea()) { if (blockLocation.isPlotArea()) {
blocks.remove(i); blocks.remove(i);
} }

View File

@ -26,6 +26,7 @@ import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.plot.world.PlotAreaManager;
import com.plotsquared.core.plot.world.SinglePlotArea; import com.plotsquared.core.plot.world.SinglePlotArea;
import com.plotsquared.core.util.ReflectionUtils;
import com.plotsquared.core.util.ReflectionUtils.RefClass; import com.plotsquared.core.util.ReflectionUtils.RefClass;
import com.plotsquared.core.util.ReflectionUtils.RefField; import com.plotsquared.core.util.ReflectionUtils.RefField;
import com.plotsquared.core.util.ReflectionUtils.RefMethod; import com.plotsquared.core.util.ReflectionUtils.RefMethod;
@ -64,9 +65,11 @@ public class ChunkListener implements Listener {
private final PlotAreaManager plotAreaManager; private final PlotAreaManager plotAreaManager;
private final int version; private final int version;
private RefMethod methodSetUnsaved;
private RefMethod methodGetHandleChunk; private RefMethod methodGetHandleChunk;
private RefMethod methodGetHandleWorld; private RefMethod methodGetHandleWorld;
private RefField mustSave; private RefField mustNotSave;
private Object objChunkStatusFull = null;
/* /*
private RefMethod methodGetFullChunk; private RefMethod methodGetFullChunk;
private RefMethod methodGetBukkitChunk; private RefMethod methodGetBukkitChunk;
@ -79,7 +82,6 @@ public class ChunkListener implements Listener {
*/ */
private Chunk lastChunk; private Chunk lastChunk;
private boolean ignoreUnload = false; private boolean ignoreUnload = false;
private boolean isTrueForNotSave = true;
@Inject @Inject
public ChunkListener(final @NonNull PlotAreaManager plotAreaManager) { public ChunkListener(final @NonNull PlotAreaManager plotAreaManager) {
@ -90,22 +92,27 @@ public class ChunkListener implements Listener {
} }
try { try {
RefClass classCraftWorld = getRefClass("{cb}.CraftWorld"); RefClass classCraftWorld = getRefClass("{cb}.CraftWorld");
this.methodGetHandleWorld = classCraftWorld.getMethod("getHandle");
RefClass classCraftChunk = getRefClass("{cb}.CraftChunk"); RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle"); ReflectionUtils.RefClass classChunkAccess = getRefClass("net.minecraft.world.level.chunk.IChunkAccess");
this.methodSetUnsaved = classChunkAccess.getMethod("a", boolean.class);
try {
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle");
} catch (NoSuchMethodException ignored) {
try {
RefClass classChunkStatus = getRefClass("net.minecraft.world.level.chunk.ChunkStatus");
this.objChunkStatusFull = classChunkStatus.getRealClass().getField("n").get(null);
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle", classChunkStatus.getRealClass());
} catch (NoSuchMethodException ex) {
throw new RuntimeException(ex);
}
}
try { try {
if (version < 17) { if (version < 17) {
RefClass classChunk = getRefClass("{nms}.Chunk"); RefClass classChunk = getRefClass("{nms}.Chunk");
if (version == 13) { this.mustNotSave = classChunk.getField("mustNotSave");
this.mustSave = classChunk.getField("mustSave");
this.isTrueForNotSave = false;
} else {
this.mustSave = classChunk.getField("mustNotSave");
}
} else { } else {
RefClass classChunk = getRefClass("net.minecraft.world.level.chunk.Chunk"); RefClass classChunk = getRefClass("net.minecraft.world.level.chunk.Chunk");
this.mustSave = classChunk.getField("mustNotSave"); this.mustNotSave = classChunk.getField("mustNotSave");
} }
} catch (NoSuchFieldException e) { } catch (NoSuchFieldException e) {
e.printStackTrace(); e.printStackTrace();
@ -167,10 +174,13 @@ public class ChunkListener implements Listener {
if (safe && shouldSave(world, chunk.getX(), chunk.getZ())) { if (safe && shouldSave(world, chunk.getX(), chunk.getZ())) {
return false; return false;
} }
Object c = this.methodGetHandleChunk.of(chunk).call(); Object c = objChunkStatusFull != null
RefField.RefExecutor field = this.mustSave.of(c); ? this.methodGetHandleChunk.of(chunk).call(objChunkStatusFull)
if ((Boolean) field.get() != isTrueForNotSave) { : this.methodGetHandleChunk.of(chunk).call();
field.set(isTrueForNotSave); RefField.RefExecutor field = this.mustNotSave.of(c);
methodSetUnsaved.of(c).call(false);
if (!((Boolean) field.get())) {
field.set(true);
if (chunk.isLoaded()) { if (chunk.isLoaded()) {
ignoreUnload = true; ignoreUnload = true;
chunk.unload(false); chunk.unload(false);
@ -234,7 +244,8 @@ public class ChunkListener implements Listener {
Chunk chunk = event.getChunk(); Chunk chunk = event.getChunk();
if (Settings.Chunk_Processor.AUTO_TRIM) { if (Settings.Chunk_Processor.AUTO_TRIM) {
String world = chunk.getWorld().getName(); String world = chunk.getWorld().getName();
if ((!Settings.Enabled_Components.WORLDS || !SinglePlotArea.isSinglePlotWorld(world)) && this.plotAreaManager.hasPlotArea(world)) { if ((!Settings.Enabled_Components.WORLDS || !SinglePlotArea.isSinglePlotWorld(world)) && this.plotAreaManager.hasPlotArea(
world)) {
if (unloadChunk(world, chunk, true)) { if (unloadChunk(world, chunk, true)) {
return; return;
} }

View File

@ -19,6 +19,7 @@
package com.plotsquared.bukkit.listener; package com.plotsquared.bukkit.listener;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.plotsquared.bukkit.BukkitPlatform;
import com.plotsquared.bukkit.player.BukkitPlayer; import com.plotsquared.bukkit.player.BukkitPlayer;
import com.plotsquared.bukkit.util.BukkitEntityUtil; import com.plotsquared.bukkit.util.BukkitEntityUtil;
import com.plotsquared.bukkit.util.BukkitUtil; import com.plotsquared.bukkit.util.BukkitUtil;
@ -35,11 +36,13 @@ import com.plotsquared.core.plot.flag.implementations.DisablePhysicsFlag;
import com.plotsquared.core.plot.flag.implementations.EntityChangeBlockFlag; import com.plotsquared.core.plot.flag.implementations.EntityChangeBlockFlag;
import com.plotsquared.core.plot.flag.implementations.ExplosionFlag; import com.plotsquared.core.plot.flag.implementations.ExplosionFlag;
import com.plotsquared.core.plot.flag.implementations.InvincibleFlag; import com.plotsquared.core.plot.flag.implementations.InvincibleFlag;
import com.plotsquared.core.plot.flag.implementations.ProjectileChangeBlockFlag;
import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.plot.world.PlotAreaManager;
import com.plotsquared.core.util.EventDispatcher; import com.plotsquared.core.util.EventDispatcher;
import com.plotsquared.core.util.PlotFlagUtil; import com.plotsquared.core.util.PlotFlagUtil;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import io.papermc.lib.PaperLib;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Particle; import org.bukkit.Particle;
import org.bukkit.World; import org.bukkit.World;
@ -77,15 +80,18 @@ import java.util.List;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class EntityEventListener implements Listener { public class EntityEventListener implements Listener {
private final BukkitPlatform platform;
private final PlotAreaManager plotAreaManager; private final PlotAreaManager plotAreaManager;
private final EventDispatcher eventDispatcher; private final EventDispatcher eventDispatcher;
private float lastRadius; private float lastRadius;
@Inject @Inject
public EntityEventListener( public EntityEventListener(
final @NonNull BukkitPlatform platform,
final @NonNull PlotAreaManager plotAreaManager, final @NonNull PlotAreaManager plotAreaManager,
final @NonNull EventDispatcher eventDispatcher final @NonNull EventDispatcher eventDispatcher
) { ) {
this.platform = platform;
this.plotAreaManager = plotAreaManager; this.plotAreaManager = plotAreaManager;
this.eventDispatcher = eventDispatcher; this.eventDispatcher = eventDispatcher;
} }
@ -143,56 +149,55 @@ public class EntityEventListener implements Listener {
if (area == null) { if (area == null) {
return; return;
} }
// Armour-stands are handled elsewhere and should not be handled by area-wide entity-spawn options
if (entity.getType() == EntityType.ARMOR_STAND) {
return;
}
CreatureSpawnEvent.SpawnReason reason = event.getSpawnReason(); CreatureSpawnEvent.SpawnReason reason = event.getSpawnReason();
switch (reason.toString()) { switch (reason.toString()) {
case "DISPENSE_EGG": case "DISPENSE_EGG", "EGG", "OCELOT_BABY", "SPAWNER_EGG" -> {
case "EGG":
case "OCELOT_BABY":
case "SPAWNER_EGG":
if (!area.isSpawnEggs()) { if (!area.isSpawnEggs()) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
break; }
case "REINFORCEMENTS": case "REINFORCEMENTS", "NATURAL", "MOUNT", "PATROL", "RAID", "SHEARED", "SILVERFISH_BLOCK", "ENDER_PEARL",
case "NATURAL": "TRAP", "VILLAGE_DEFENSE", "VILLAGE_INVASION", "BEEHIVE", "CHUNK_GEN", "NETHER_PORTAL",
case "MOUNT": "DUPLICATION", "FROZEN", "SPELL", "DEFAULT" -> {
case "PATROL":
case "RAID":
case "SHEARED":
case "SILVERFISH_BLOCK":
case "ENDER_PEARL":
case "TRAP":
case "VILLAGE_DEFENSE":
case "VILLAGE_INVASION":
case "BEEHIVE":
case "CHUNK_GEN":
if (!area.isMobSpawning()) { if (!area.isMobSpawning()) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
break; }
case "BREEDING": case "BREEDING" -> {
if (!area.isSpawnBreeding()) { if (!area.isSpawnBreeding()) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
break; }
case "BUILD_IRONGOLEM": case "CUSTOM" -> {
case "BUILD_SNOWMAN": if (!area.isSpawnCustom()) {
case "BUILD_WITHER":
case "CUSTOM":
if (!area.isSpawnCustom() && entity.getType() != EntityType.ARMOR_STAND) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
break; // No need to clutter metadata if running paper
case "SPAWNER": if (!PaperLib.isPaper()) {
entity.setMetadata("ps_custom_spawned", new FixedMetadataValue(this.platform, true));
}
return; // Don't cancel if mob spawning is disabled
}
case "BUILD_IRONGOLEM", "BUILD_SNOWMAN", "BUILD_WITHER" -> {
if (!area.isSpawnCustom()) {
event.setCancelled(true);
return;
}
}
case "SPAWNER" -> {
if (!area.isMobSpawnerSpawning()) { if (!area.isMobSpawnerSpawning()) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
break; }
} }
Plot plot = area.getOwnedPlotAbs(location); Plot plot = area.getOwnedPlotAbs(location);
if (plot == null) { if (plot == null) {
@ -370,13 +375,13 @@ public class EntityEventListener implements Listener {
if (shooter instanceof Player) { if (shooter instanceof Player) {
PlotPlayer<?> pp = BukkitUtil.adapt((Player) shooter); PlotPlayer<?> pp = BukkitUtil.adapt((Player) shooter);
if (plot == null) { if (plot == null) {
if (!pp.hasPermission(Permission.PERMISSION_ADMIN_PROJECTILE_UNOWNED)) { if (area.isRoadFlags() && !area.getRoadFlag(ProjectileChangeBlockFlag.class) && !pp.hasPermission(Permission.PERMISSION_ADMIN_PROJECTILE_UNOWNED)) {
entity.remove(); entity.remove();
event.setCancelled(true); event.setCancelled(true);
} }
return; return;
} }
if (plot.isAdded(pp.getUUID()) || pp.hasPermission(Permission.PERMISSION_ADMIN_PROJECTILE_OTHER)) { if (plot.isAdded(pp.getUUID()) || plot.getFlag(ProjectileChangeBlockFlag.class) || pp.hasPermission(Permission.PERMISSION_ADMIN_PROJECTILE_OTHER)) {
return; return;
} }
entity.remove(); entity.remove();

View File

@ -120,9 +120,14 @@ public class EntitySpawnListener implements Listener {
Entity entity = event.getEntity(); Entity entity = event.getEntity();
Location location = BukkitUtil.adapt(entity.getLocation()); Location location = BukkitUtil.adapt(entity.getLocation());
PlotArea area = location.getPlotArea(); PlotArea area = location.getPlotArea();
if (!location.isPlotArea()) { if (!location.isPlotArea() || area == null) {
return; return;
} }
if (PaperLib.isPaper()) {
if (area.isSpawnCustom() && "CUSTOM".equals(entity.getEntitySpawnReason().name())) {
return;
}
}
Plot plot = location.getOwnedPlotAbs(); Plot plot = location.getOwnedPlotAbs();
EntityType type = entity.getType(); EntityType type = entity.getType();
if (plot == null) { if (plot == null) {

View File

@ -43,10 +43,10 @@ import com.plotsquared.core.plot.flag.implementations.DoneFlag;
import com.plotsquared.core.plot.flag.implementations.ProjectilesFlag; import com.plotsquared.core.plot.flag.implementations.ProjectilesFlag;
import com.plotsquared.core.plot.flag.types.BooleanFlag; import com.plotsquared.core.plot.flag.types.BooleanFlag;
import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.plot.world.PlotAreaManager;
import com.plotsquared.core.util.PlotFlagUtil;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import com.plotsquared.core.util.PlotFlagUtil;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.TileState; import org.bukkit.block.TileState;
@ -124,7 +124,7 @@ public class PaperListener implements Listener {
} }
Slime slime = event.getEntity(); Slime slime = event.getEntity();
Block b = slime.getTargetBlock(4); Block b = slime.getTargetBlockExact(4);
if (b == null) { if (b == null) {
return; return;
} }
@ -166,71 +166,57 @@ public class PaperListener implements Listener {
} }
Location location = BukkitUtil.adapt(event.getSpawnLocation()); Location location = BukkitUtil.adapt(event.getSpawnLocation());
PlotArea area = location.getPlotArea(); PlotArea area = location.getPlotArea();
if (!location.isPlotArea()) { if (area == null) {
return; return;
} }
//If entities are spawning... the chunk should be loaded? // Armour-stands are handled elsewhere and should not be handled by area-wide entity-spawn options
if (event.getType() == EntityType.ARMOR_STAND) {
return;
}
// If entities are spawning... the chunk should be loaded?
Entity[] entities = event.getSpawnLocation().getChunk().getEntities(); Entity[] entities = event.getSpawnLocation().getChunk().getEntities();
if (entities.length > Settings.Chunk_Processor.MAX_ENTITIES) { if (entities.length >= Settings.Chunk_Processor.MAX_ENTITIES) {
event.setShouldAbortSpawn(true); event.setShouldAbortSpawn(true);
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
CreatureSpawnEvent.SpawnReason reason = event.getReason(); CreatureSpawnEvent.SpawnReason reason = event.getReason();
switch (reason.toString()) { switch (reason.toString()) {
case "DISPENSE_EGG": case "DISPENSE_EGG", "EGG", "OCELOT_BABY", "SPAWNER_EGG" -> {
case "EGG":
case "OCELOT_BABY":
case "SPAWNER_EGG":
if (!area.isSpawnEggs()) { if (!area.isSpawnEggs()) {
event.setShouldAbortSpawn(true); event.setShouldAbortSpawn(true);
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
break; }
case "REINFORCEMENTS": case "REINFORCEMENTS", "NATURAL", "MOUNT", "PATROL", "RAID", "SHEARED", "SILVERFISH_BLOCK", "ENDER_PEARL", "TRAP", "VILLAGE_DEFENSE", "VILLAGE_INVASION", "BEEHIVE", "CHUNK_GEN" -> {
case "NATURAL":
case "MOUNT":
case "PATROL":
case "RAID":
case "SHEARED":
case "SILVERFISH_BLOCK":
case "ENDER_PEARL":
case "TRAP":
case "VILLAGE_DEFENSE":
case "VILLAGE_INVASION":
case "BEEHIVE":
case "CHUNK_GEN":
if (!area.isMobSpawning()) { if (!area.isMobSpawning()) {
event.setShouldAbortSpawn(true); event.setShouldAbortSpawn(true);
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
break; }
case "BREEDING": case "BREEDING" -> {
if (!area.isSpawnBreeding()) { if (!area.isSpawnBreeding()) {
event.setShouldAbortSpawn(true); event.setShouldAbortSpawn(true);
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
break; }
case "BUILD_IRONGOLEM": case "BUILD_IRONGOLEM", "BUILD_SNOWMAN", "BUILD_WITHER", "CUSTOM" -> {
case "BUILD_SNOWMAN": if (!area.isSpawnCustom()) {
case "BUILD_WITHER":
case "CUSTOM":
if (!area.isSpawnCustom() && event.getType() != EntityType.ARMOR_STAND) {
event.setShouldAbortSpawn(true); event.setShouldAbortSpawn(true);
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
break; }
case "SPAWNER": case "SPAWNER" -> {
if (!area.isMobSpawnerSpawning()) { if (!area.isMobSpawnerSpawning()) {
event.setShouldAbortSpawn(true); event.setShouldAbortSpawn(true);
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
break; }
} }
Plot plot = location.getOwnedPlotAbs(); Plot plot = location.getOwnedPlotAbs();
if (plot == null) { if (plot == null) {
@ -457,9 +443,11 @@ public class PaperListener implements Listener {
} }
} }
private boolean getBooleanFlagValue(@NonNull FlagContainer container, private boolean getBooleanFlagValue(
@NonNull Class<? extends BooleanFlag<?>> flagClass, @NonNull FlagContainer container,
boolean defaultValue) { @NonNull Class<? extends BooleanFlag<?>> flagClass,
boolean defaultValue
) {
BooleanFlag<?> flag = container.getFlag(flagClass); BooleanFlag<?> flag = container.getFlag(flagClass);
return flag == null ? defaultValue : flag.getValue(); return flag == null ? defaultValue : flag.getValue();
} }

View File

@ -50,6 +50,7 @@ import com.plotsquared.core.plot.flag.implementations.DenyPortalsFlag;
import com.plotsquared.core.plot.flag.implementations.DenyTeleportFlag; import com.plotsquared.core.plot.flag.implementations.DenyTeleportFlag;
import com.plotsquared.core.plot.flag.implementations.DoneFlag; import com.plotsquared.core.plot.flag.implementations.DoneFlag;
import com.plotsquared.core.plot.flag.implementations.DropProtectionFlag; import com.plotsquared.core.plot.flag.implementations.DropProtectionFlag;
import com.plotsquared.core.plot.flag.implementations.EditSignFlag;
import com.plotsquared.core.plot.flag.implementations.HangingBreakFlag; import com.plotsquared.core.plot.flag.implementations.HangingBreakFlag;
import com.plotsquared.core.plot.flag.implementations.HangingPlaceFlag; import com.plotsquared.core.plot.flag.implementations.HangingPlaceFlag;
import com.plotsquared.core.plot.flag.implementations.HostileInteractFlag; import com.plotsquared.core.plot.flag.implementations.HostileInteractFlag;
@ -87,6 +88,7 @@ import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
import org.bukkit.block.Sign;
import org.bukkit.block.data.Waterlogged; import org.bukkit.block.data.Waterlogged;
import org.bukkit.command.PluginCommand; import org.bukkit.command.PluginCommand;
import org.bukkit.entity.ArmorStand; import org.bukkit.entity.ArmorStand;
@ -175,6 +177,33 @@ public class PlayerEventListener implements Listener {
Material.WRITABLE_BOOK, Material.WRITABLE_BOOK,
Material.WRITTEN_BOOK Material.WRITTEN_BOOK
); );
private static final Set<String> DYES;
static {
Set<String> mutableDyes = new HashSet<>(Set.of(
"WHITE_DYE",
"LIGHT_GRAY_DYE",
"GRAY_DYE",
"BLACK_DYE",
"BROWN_DYE",
"RED_DYE",
"ORANGE_DYE",
"YELLOW_DYE",
"LIME_DYE",
"GREEN_DYE",
"CYAN_DYE",
"LIGHT_BLUE_DYE",
"BLUE_DYE",
"PURPLE_DYE",
"MAGENTA_DYE",
"PINK_DYE",
"GLOW_INK_SAC"
));
int[] version = PlotSquared.platform().serverVersion();
if (version[1] >= 20 && version[2] >= 1) {
mutableDyes.add("HONEYCOMB");
}
DYES = Set.copyOf(mutableDyes);
}
private final EventDispatcher eventDispatcher; private final EventDispatcher eventDispatcher;
private final WorldEdit worldEdit; private final WorldEdit worldEdit;
private final PlotAreaManager plotAreaManager; private final PlotAreaManager plotAreaManager;
@ -207,6 +236,40 @@ public class PlayerEventListener implements Listener {
this.plotListener = plotListener; this.plotListener = plotListener;
} }
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onPlayerDyeSign(PlayerInteractEvent event) {
ItemStack itemStack = event.getItem();
if (itemStack == null) {
return;
}
Block block = event.getClickedBlock();
if (block != null && block.getState() instanceof Sign) {
if (DYES.contains(itemStack.getType().toString())) {
Location location = BukkitUtil.adapt(block.getLocation());
PlotArea area = location.getPlotArea();
if (area == null) {
return;
}
Plot plot = location.getOwnedPlot();
if (plot == null) {
if (PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, EditSignFlag.class, false)
&& !event.getPlayer().hasPermission(Permission.PERMISSION_ADMIN_INTERACT_ROAD.toString())) {
event.setCancelled(true);
}
return;
}
if (plot.isAdded(event.getPlayer().getUniqueId())) {
return; // allow for added players
}
if (!plot.getFlag(EditSignFlag.class)
&& !event.getPlayer().hasPermission(Permission.PERMISSION_ADMIN_INTERACT_OTHER.toString())) {
plot.debug(event.getPlayer().getName() + " could not color the sign because of edit-sign = false");
event.setCancelled(true);
}
}
}
}
@EventHandler(ignoreCancelled = true) @EventHandler(ignoreCancelled = true)
public void onEffect(@NonNull EntityPotionEffectEvent event) { public void onEffect(@NonNull EntityPotionEffectEvent event) {
if (Settings.Enabled_Components.DISABLE_BEACON_EFFECT_OVERFLOW || if (Settings.Enabled_Components.DISABLE_BEACON_EFFECT_OVERFLOW ||
@ -273,8 +336,7 @@ public class PlayerEventListener implements Listener {
Plot plot = plotPlayer.getCurrentPlot(); Plot plot = plotPlayer.getCurrentPlot();
// Check WorldEdit // Check WorldEdit
switch (parts[0]) { switch (parts[0]) {
case "up": case "up", "worldedit:up" -> {
case "worldedit:up":
if (plot == null || (!plot.isAdded(plotPlayer.getUUID()) && !plotPlayer.hasPermission( if (plot == null || (!plot.isAdded(plotPlayer.getUUID()) && !plotPlayer.hasPermission(
Permission.PERMISSION_ADMIN_BUILD_OTHER, Permission.PERMISSION_ADMIN_BUILD_OTHER,
true true
@ -282,6 +344,7 @@ public class PlayerEventListener implements Listener {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
}
} }
if (plot == null && !area.isRoadFlags()) { if (plot == null && !area.isRoadFlags()) {
return; return;
@ -369,6 +432,7 @@ public class PlayerEventListener implements Listener {
} }
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
@SuppressWarnings("deprecation") // Paper deprecation
public void onConnect(PlayerJoinEvent event) { public void onConnect(PlayerJoinEvent event) {
final Player player = event.getPlayer(); final Player player = event.getPlayer();
PlotSquared.platform().playerManager().removePlayer(player.getUniqueId()); PlotSquared.platform().playerManager().removePlayer(player.getUniqueId());
@ -572,7 +636,8 @@ public class PlayerEventListener implements Listener {
if (now == null) { if (now == null) {
try (final MetaDataAccess<Boolean> kickAccess = try (final MetaDataAccess<Boolean> kickAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_KICK)) { pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_KICK)) {
if (lastPlot != null && !plotListener.plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse(false)) { if (lastPlot != null && !plotListener.plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse(
false)) {
pp.sendMessage( pp.sendMessage(
TranslatableCaption.of("permission.no_permission_event"), TranslatableCaption.of("permission.no_permission_event"),
TagResolver.resolver( TagResolver.resolver(
@ -606,7 +671,7 @@ public class PlayerEventListener implements Listener {
this.tmpTeleport = true; this.tmpTeleport = true;
return; return;
} }
int border = area.getBorder(); int border = area.getBorder(true);
int x1; int x1;
if (x2 > border && this.tmpTeleport) { if (x2 > border && this.tmpTeleport) {
if (!pp.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_BORDER)) { if (!pp.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_BORDER)) {
@ -665,7 +730,8 @@ public class PlayerEventListener implements Listener {
if (plot == null) { if (plot == null) {
try (final MetaDataAccess<Boolean> kickAccess = try (final MetaDataAccess<Boolean> kickAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_KICK)) { pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_KICK)) {
if (lastPlot != null && !plotListener.plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse(false)) { if (lastPlot != null && !plotListener.plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse(
false)) {
pp.sendMessage( pp.sendMessage(
TranslatableCaption.of("permission.no_permission_event"), TranslatableCaption.of("permission.no_permission_event"),
TagResolver.resolver( TagResolver.resolver(
@ -700,7 +766,7 @@ public class PlayerEventListener implements Listener {
this.tmpTeleport = true; this.tmpTeleport = true;
return; return;
} }
int border = area.getBorder(); int border = area.getBorder(true);
int z1; int z1;
if (z2 > border && this.tmpTeleport) { if (z2 > border && this.tmpTeleport) {
if (!pp.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_BORDER)) { if (!pp.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_BORDER)) {
@ -731,6 +797,7 @@ public class PlayerEventListener implements Listener {
} }
@EventHandler(priority = EventPriority.LOW) @EventHandler(priority = EventPriority.LOW)
@SuppressWarnings("deprecation") // Paper deprecation
public void onChat(AsyncPlayerChatEvent event) { public void onChat(AsyncPlayerChatEvent event) {
if (event.isCancelled()) { if (event.isCancelled()) {
return; return;
@ -1061,6 +1128,7 @@ public class PlayerEventListener implements Listener {
} }
@EventHandler(priority = EventPriority.LOW) @EventHandler(priority = EventPriority.LOW)
@SuppressWarnings("deprecation") // Paper deprecation
public void onCancelledInteract(PlayerInteractEvent event) { public void onCancelledInteract(PlayerInteractEvent event) {
if (event.isCancelled() && event.getAction() == Action.RIGHT_CLICK_AIR) { if (event.isCancelled() && event.getAction() == Action.RIGHT_CLICK_AIR) {
Player player = event.getPlayer(); Player player = event.getPlayer();
@ -1114,13 +1182,13 @@ public class PlayerEventListener implements Listener {
Location location = BukkitUtil.adapt(block.getLocation()); Location location = BukkitUtil.adapt(block.getLocation());
Action action = event.getAction(); Action action = event.getAction();
switch (action) { switch (action) {
case PHYSICAL: { case PHYSICAL -> {
eventType = PlayerBlockEventType.TRIGGER_PHYSICAL; eventType = PlayerBlockEventType.TRIGGER_PHYSICAL;
blocktype1 = BukkitAdapter.asBlockType(block.getType()); blocktype1 = BukkitAdapter.asBlockType(block.getType());
break;
} }
//todo rearrange the right click code. it is all over the place. //todo rearrange the right click code. it is all over the place.
case RIGHT_CLICK_BLOCK: { case RIGHT_CLICK_BLOCK -> {
Material blockType = block.getType(); Material blockType = block.getType();
eventType = PlayerBlockEventType.INTERACT_BLOCK; eventType = PlayerBlockEventType.INTERACT_BLOCK;
blocktype1 = BukkitAdapter.asBlockType(block.getType()); blocktype1 = BukkitAdapter.asBlockType(block.getType());
@ -1142,21 +1210,16 @@ public class PlayerEventListener implements Listener {
// in the following, lb needs to have the material of the item in hand i.e. type // in the following, lb needs to have the material of the item in hand i.e. type
switch (type.toString()) { switch (type.toString()) {
case "REDSTONE": case "REDSTONE", "STRING", "PUMPKIN_SEEDS", "MELON_SEEDS", "COCOA_BEANS", "WHEAT_SEEDS", "BEETROOT_SEEDS",
case "STRING": "SWEET_BERRIES", "GLOW_BERRIES" -> {
case "PUMPKIN_SEEDS":
case "MELON_SEEDS":
case "COCOA_BEANS":
case "WHEAT_SEEDS":
case "BEETROOT_SEEDS":
case "SWEET_BERRIES":
case "GLOW_BERRIES":
return; return;
default: }
default -> {
//eventType = PlayerBlockEventType.PLACE_BLOCK; //eventType = PlayerBlockEventType.PLACE_BLOCK;
if (type.isBlock()) { if (type.isBlock()) {
return; return;
} }
}
} }
if (PaperLib.isPaper()) { if (PaperLib.isPaper()) {
if (MaterialTags.SPAWN_EGGS.isTagged(type) || Material.EGG.equals(type)) { if (MaterialTags.SPAWN_EGGS.isTagged(type) || Material.EGG.equals(type)) {
@ -1170,7 +1233,7 @@ public class PlayerEventListener implements Listener {
} }
} }
if (type.isEdible()) { if (type.isEdible()) {
//Allow all players to eat while also allowing the block place event ot be fired //Allow all players to eat while also allowing the block place event to be fired
return; return;
} }
if (type == Material.ARMOR_STAND) { if (type == Material.ARMOR_STAND) {
@ -1189,9 +1252,8 @@ public class PlayerEventListener implements Listener {
eventType = PlayerBlockEventType.READ; eventType = PlayerBlockEventType.READ;
break; break;
} }
break;
} }
case LEFT_CLICK_BLOCK: { case LEFT_CLICK_BLOCK -> {
Material blockType = block.getType(); Material blockType = block.getType();
// todo: when the code above is rearranged, it would be great to beautify this as well. // todo: when the code above is rearranged, it would be great to beautify this as well.
@ -1202,10 +1264,10 @@ public class PlayerEventListener implements Listener {
eventType = PlayerBlockEventType.INTERACT_BLOCK; eventType = PlayerBlockEventType.INTERACT_BLOCK;
blocktype1 = BukkitAdapter.asBlockType(block.getType()); blocktype1 = BukkitAdapter.asBlockType(block.getType());
break;
} }
default: default -> {
return; return;
}
} }
if (this.worldEdit != null && pp.getAttribute("worldedit")) { if (this.worldEdit != null && pp.getAttribute("worldedit")) {
if (event.getMaterial() == Material.getMaterial(this.worldEdit.getConfiguration().wandItem)) { if (event.getMaterial() == Material.getMaterial(this.worldEdit.getConfiguration().wandItem)) {

View File

@ -0,0 +1,66 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.listener;
import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.flag.implementations.EditSignFlag;
import com.plotsquared.core.util.PlotFlagUtil;
import org.bukkit.block.Sign;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerSignOpenEvent;
/**
* For events since 1.20.1
* @since 7.2.1
*/
public class PlayerEventListener1201 implements Listener {
@EventHandler(ignoreCancelled = true)
@SuppressWarnings({"removal", "UnstableApiUsage"}) // thanks Paper, thanks Spigot
public void onPlayerSignOpenEvent(PlayerSignOpenEvent event) {
Sign sign = event.getSign();
Location location = BukkitUtil.adapt(sign.getLocation());
PlotArea area = location.getPlotArea();
if (area == null) {
return;
}
Plot plot = location.getOwnedPlot();
if (plot == null) {
if (PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, EditSignFlag.class, false)
&& !event.getPlayer().hasPermission(Permission.PERMISSION_ADMIN_INTERACT_ROAD.toString())) {
event.setCancelled(true);
}
return;
}
if (plot.isAdded(event.getPlayer().getUniqueId())) {
return; // allow for added players
}
if (!plot.getFlag(EditSignFlag.class)
&& !event.getPlayer().hasPermission(Permission.PERMISSION_ADMIN_INTERACT_OTHER.toString())) {
plot.debug(event.getPlayer().getName() + " could not edit the sign because of edit-sign = false");
event.setCancelled(true);
}
}
}

View File

@ -30,9 +30,9 @@ import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotHandler; import com.plotsquared.core.plot.PlotHandler;
import com.plotsquared.core.plot.flag.implementations.ProjectilesFlag; import com.plotsquared.core.plot.flag.implementations.ProjectilesFlag;
import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.plot.world.PlotAreaManager;
import com.plotsquared.core.util.PlotFlagUtil;
import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import com.plotsquared.core.util.PlotFlagUtil;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;

View File

@ -21,9 +21,14 @@ package com.plotsquared.bukkit.listener;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.plotsquared.bukkit.BukkitPlatform; import com.plotsquared.bukkit.BukkitPlatform;
import com.plotsquared.bukkit.placeholder.MVdWPlaceholders; import com.plotsquared.bukkit.placeholder.MVdWPlaceholders;
import com.plotsquared.bukkit.util.BukkitEconHandler;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.player.ConsolePlayer; import com.plotsquared.core.player.ConsolePlayer;
import com.plotsquared.core.util.EconHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@ -32,6 +37,8 @@ import org.checkerframework.checker.nullness.qual.NonNull;
public class ServerListener implements Listener { public class ServerListener implements Listener {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + ServerListener.class.getSimpleName());
private final BukkitPlatform plugin; private final BukkitPlatform plugin;
@Inject @Inject
@ -45,6 +52,29 @@ public class ServerListener implements Listener {
new MVdWPlaceholders(this.plugin, this.plugin.placeholderRegistry()); new MVdWPlaceholders(this.plugin, this.plugin.placeholderRegistry());
ConsolePlayer.getConsole().sendMessage(TranslatableCaption.of("placeholder.hooked")); ConsolePlayer.getConsole().sendMessage(TranslatableCaption.of("placeholder.hooked"));
} }
if (Settings.Enabled_Components.ECONOMY && Bukkit.getPluginManager().isPluginEnabled("Vault")) {
EconHandler econHandler = new BukkitEconHandler();
try {
if (!econHandler.init()) {
LOGGER.warn("Economy is enabled but no plugin is providing an economy service. Falling back...");
econHandler = EconHandler.nullEconHandler();
}
} catch (final Exception ignored) {
econHandler = EconHandler.nullEconHandler();
}
if (PlotSquared.platform().econHandler() instanceof MutableEconHandler meh) {
meh.setImplementation(econHandler);
}
}
}
/**
* Internal use only. Required to implement lazy econ loading using Guice.
*
* @since 7.2.0
*/
public interface MutableEconHandler {
void setImplementation(EconHandler econHandler);
} }
} }

View File

@ -31,45 +31,39 @@ import org.bukkit.event.Listener;
import org.bukkit.event.world.ChunkEvent; import org.bukkit.event.world.ChunkEvent;
import org.bukkit.event.world.ChunkLoadEvent; import org.bukkit.event.world.ChunkLoadEvent;
import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import static com.plotsquared.core.util.ReflectionUtils.getRefClass; import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
public class SingleWorldListener implements Listener { public class SingleWorldListener implements Listener {
private final Method methodGetHandleChunk; private final Method methodSetUnsaved;
private Field shouldSave = null; private Method methodGetHandleChunk;
private Object objChunkStatusFull = null;
public SingleWorldListener() throws Exception { public SingleWorldListener() throws Exception {
ReflectionUtils.RefClass classCraftChunk = getRefClass("{cb}.CraftChunk"); ReflectionUtils.RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle").getRealMethod(); ReflectionUtils.RefClass classChunkAccess = getRefClass("net.minecraft.world.level.chunk.IChunkAccess");
this.methodSetUnsaved = classChunkAccess.getMethod("a", boolean.class).getRealMethod();
try { try {
if (PlotSquared.platform().serverVersion()[1] < 17) { this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle").getRealMethod();
ReflectionUtils.RefClass classChunk = getRefClass("{nms}.Chunk"); } catch (NoSuchMethodException ignored) {
if (PlotSquared.platform().serverVersion()[1] == 13) { try {
this.shouldSave = classChunk.getField("mustSave").getRealField(); ReflectionUtils.RefClass classChunkStatus = getRefClass("net.minecraft.world.level.chunk.ChunkStatus");
} else { this.objChunkStatusFull = classChunkStatus.getRealClass().getField("n").get(null);
this.shouldSave = classChunk.getField("s").getRealField(); this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle", classChunkStatus.getRealClass()).getRealMethod();
} } catch (NoSuchMethodException ex) {
} else if (PlotSquared.platform().serverVersion()[1] == 17) { throw new RuntimeException(ex);
ReflectionUtils.RefClass classChunk = getRefClass("net.minecraft.world.level.chunk.Chunk");
this.shouldSave = classChunk.getField("r").getRealField();
} else if (PlotSquared.platform().serverVersion()[1] == 18) {
ReflectionUtils.RefClass classChunk = getRefClass("net.minecraft.world.level.chunk.IChunkAccess");
this.shouldSave = classChunk.getField("b").getRealField();
} }
} catch (NoSuchFieldException e) {
e.printStackTrace();
} }
} }
public void markChunkAsClean(Chunk chunk) { public void markChunkAsClean(Chunk chunk) {
try { try {
Object nmsChunk = methodGetHandleChunk.invoke(chunk); Object nmsChunk = objChunkStatusFull != null
if (shouldSave != null) { ? this.methodGetHandleChunk.invoke(chunk, objChunkStatusFull)
this.shouldSave.set(nmsChunk, false); : this.methodGetHandleChunk.invoke(chunk);
} methodSetUnsaved.invoke(nmsChunk, false);
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -85,7 +79,12 @@ public class SingleWorldListener implements Listener {
if (!SinglePlotArea.isSinglePlotWorld(name)) { if (!SinglePlotArea.isSinglePlotWorld(name)) {
return; return;
} }
int x = event.getChunk().getX();
int z = event.getChunk().getZ();
if (x < 16 && x > -16 && z < 16 && z > -16) {
// Allow spawn to generate
return;
}
markChunkAsClean(event.getChunk()); markChunkAsClean(event.getChunk());
} }

View File

@ -1,63 +0,0 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.managers;
/*
import com.google.inject.Singleton;
import org.bukkit.World;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import se.hyperver.hyperverse.Hyperverse;
import se.hyperver.hyperverse.world.WorldConfiguration;
import se.hyperver.hyperverse.world.WorldConfigurationBuilder;
import se.hyperver.hyperverse.world.WorldFeatures;
import se.hyperver.hyperverse.world.WorldType;
Hyperverse implementation is currently put on ice until Hyperverse is released on a stable line and deployed to the central
repository.
@Singleton
public class HyperverseWorldManager extends BukkitWorldManager {
@Override
public @Nullable World handleWorldCreation(@NonNull String worldName, @Nullable String generator) {
// First let Bukkit register the world
this.setGenerator(worldName, generator);
// Create the world
final WorldConfigurationBuilder worldConfigurationBuilder = WorldConfiguration.builder()
.setName(worldName).setType(WorldType.OVER_WORLD);
if (generator != null) {
worldConfigurationBuilder.setGenerator(generator).setWorldFeatures(WorldFeatures.FLATLAND);
}
try {
return Hyperverse.getApi().createWorld(worldConfigurationBuilder.createWorldConfiguration())
.getBukkitWorld();
} catch (final Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public String getName() {
return "bukkit-hyperverse";
}
}
*/

View File

@ -20,6 +20,8 @@ package com.plotsquared.bukkit.placeholder;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.flag.implementations.DoneFlag;
import com.plotsquared.core.util.query.PlotQuery;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -83,6 +85,20 @@ public class PAPIPlaceholders extends PlaceholderExpansion {
return String.valueOf(pl.getPlotCount(identifier)); return String.valueOf(pl.getPlotCount(identifier));
} }
if (identifier.startsWith("base_plot_count_")) {
identifier = identifier.substring("base_plot_count_".length());
if (identifier.isEmpty()) {
return "";
}
return String.valueOf(PlotQuery.newQuery()
.ownedBy(pl)
.inWorld(identifier)
.whereBasePlot()
.thatPasses(plot -> !DoneFlag.isDone(plot))
.count());
}
// PlotSquared placeholders // PlotSquared placeholders
return PlotSquared.platform().placeholderRegistry().getPlaceholderValue(identifier, pl); return PlotSquared.platform().placeholderRegistry().getPlaceholderValue(identifier, pl);
} }

View File

@ -43,7 +43,7 @@ public class BukkitOfflinePlayer implements OfflinePlotPlayer {
*/ */
public BukkitOfflinePlayer( public BukkitOfflinePlayer(
final @NonNull OfflinePlayer player, final @NonNull final @NonNull OfflinePlayer player, final @NonNull
PermissionHandler permissionHandler PermissionHandler permissionHandler
) { ) {
this.player = player; this.player = player;
this.permissionProfile = permissionHandler.getPermissionProfile(this) this.permissionProfile = permissionHandler.getPermissionProfile(this)

View File

@ -40,6 +40,7 @@ import io.papermc.lib.PaperLib;
import net.kyori.adventure.audience.Audience; import net.kyori.adventure.audience.Audience;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.SoundCategory;
import org.bukkit.WeatherType; import org.bukkit.WeatherType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Event; import org.bukkit.event.Event;
@ -51,7 +52,6 @@ import org.bukkit.potion.PotionEffectType;
import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.index.qual.NonNegative;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Arrays;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
@ -158,6 +158,7 @@ public class BukkitPlayer extends PlotPlayer<Player> {
} }
final String[] nodes = stub.split("\\."); final String[] nodes = stub.split("\\.");
final StringBuilder n = new StringBuilder(); final StringBuilder n = new StringBuilder();
// Wildcard check from less specific permission to more specific permission
for (int i = 0; i < (nodes.length - 1); i++) { for (int i = 0; i < (nodes.length - 1); i++) {
n.append(nodes[i]).append("."); n.append(nodes[i]).append(".");
if (!stub.equals(n + Permission.PERMISSION_STAR.toString())) { if (!stub.equals(n + Permission.PERMISSION_STAR.toString())) {
@ -166,9 +167,11 @@ public class BukkitPlayer extends PlotPlayer<Player> {
} }
} }
} }
// Wildcard check for the full permission
if (hasPermission(stub + ".*")) { if (hasPermission(stub + ".*")) {
return Integer.MAX_VALUE; return Integer.MAX_VALUE;
} }
// Permission value cache for iterative check
int max = 0; int max = 0;
if (CHECK_EFFECTIVE) { if (CHECK_EFFECTIVE) {
boolean hasAny = false; boolean hasAny = false;
@ -176,6 +179,10 @@ public class BukkitPlayer extends PlotPlayer<Player> {
final Set<PermissionAttachmentInfo> effective = player.getEffectivePermissions(); final Set<PermissionAttachmentInfo> effective = player.getEffectivePermissions();
if (!effective.isEmpty()) { if (!effective.isEmpty()) {
for (PermissionAttachmentInfo attach : effective) { for (PermissionAttachmentInfo attach : effective) {
// Ignore all "false" permissions
if (!attach.getValue()) {
continue;
}
String permStr = attach.getPermission(); String permStr = attach.getPermission();
if (permStr.startsWith(stubPlus)) { if (permStr.startsWith(stubPlus)) {
hasAny = true; hasAny = true;
@ -302,18 +309,21 @@ public class BukkitPlayer extends PlotPlayer<Player> {
@Override @Override
public void playMusic(final @NonNull Location location, final @NonNull ItemType id) { public void playMusic(final @NonNull Location location, final @NonNull ItemType id) {
if (id == ItemTypes.AIR) { if (id == ItemTypes.AIR) {
// Let's just stop all the discs because why not? if (PlotSquared.platform().serverVersion()[1] >= 19) {
for (final Sound sound : Arrays.stream(Sound.values()) player.stopSound(SoundCategory.MUSIC);
.filter(sound -> sound.name().contains("DISC")).toList()) { return;
player.stopSound(sound);
} }
// this.player.playEffect(BukkitUtil.getLocation(location), Effect.RECORD_PLAY, Material.AIR); // 1.18 and downwards require a specific Sound to stop (even tho the packet does not??)
} else { for (final Sound sound : Sound.values()) {
// this.player.playEffect(BukkitUtil.getLocation(location), Effect.RECORD_PLAY, id.to(Material.class)); if (sound.name().startsWith("MUSIC_DISC")) {
this.player.playSound(BukkitUtil.adapt(location), this.player.stopSound(sound, SoundCategory.MUSIC);
Sound.valueOf(BukkitAdapter.adapt(id).name()), Float.MAX_VALUE, 1f }
); }
return;
} }
this.player.playSound(BukkitUtil.adapt(location), Sound.valueOf(BukkitAdapter.adapt(id).name()),
SoundCategory.MUSIC, 1f, 1f
);
} }
@SuppressWarnings("deprecation") // Needed for Spigot compatibility @SuppressWarnings("deprecation") // Needed for Spigot compatibility

View File

@ -270,7 +270,7 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
if (getChunkObject() instanceof Chunk chunkObject) { if (getChunkObject() instanceof Chunk chunkObject) {
existing = chunkObject.getBlock(x & 15, y, z & 15); existing = chunkObject.getBlock(x & 15, y, z & 15);
} else { } else {
existing = getBukkitWorld().getBlockAt(x, y, z); existing = getBukkitWorld().getBlockAt(x, y, z);
} }
final BlockState existingBaseBlock = BukkitAdapter.adapt(existing.getBlockData()); final BlockState existingBaseBlock = BukkitAdapter.adapt(existing.getBlockData());
if (BukkitBlockUtil.get(existing).equals(existingBaseBlock) && existing.getBlockData().matches(blockData)) { if (BukkitBlockUtil.get(existing).equals(existingBaseBlock) && existing.getBlockData().matches(blockData)) {

View File

@ -62,7 +62,6 @@ public class GenChunk extends ZeroedDelegateScopedQueueCoordinator {
/** /**
* @param minY minimum world Y, inclusive * @param minY minimum world Y, inclusive
* @param maxY maximum world Y, inclusive * @param maxY maximum world Y, inclusive
*
* @since 6.6.0 * @since 6.6.0
*/ */
public GenChunk(int minY, int maxY) { public GenChunk(int minY, int maxY) {

View File

@ -18,6 +18,8 @@
*/ */
package com.plotsquared.bukkit.schematic; package com.plotsquared.bukkit.schematic;
import com.destroystokyo.paper.profile.PlayerProfile;
import com.destroystokyo.paper.profile.ProfileProperty;
import com.plotsquared.bukkit.util.BukkitUtil; import com.plotsquared.bukkit.util.BukkitUtil;
import com.sk89q.jnbt.ByteTag; import com.sk89q.jnbt.ByteTag;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
@ -28,13 +30,20 @@ import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.item.ItemType;
import io.papermc.lib.PaperLib;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.DyeColor;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Banner;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.Container; import org.bukkit.block.Container;
import org.bukkit.block.Sign; import org.bukkit.block.Sign;
import org.bukkit.block.Skull; import org.bukkit.block.Skull;
import org.bukkit.block.banner.Pattern;
import org.bukkit.block.banner.PatternType;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -45,11 +54,15 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Objects;
import java.util.UUID;
public class StateWrapper { public class StateWrapper {
public org.bukkit.block.BlockState state = null; public CompoundTag tag;
public CompoundTag tag = null;
private boolean paperErrorTextureSent = false;
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + StateWrapper.class.getSimpleName());
public StateWrapper(CompoundTag tag) { public StateWrapper(CompoundTag tag) {
this.tag = tag; this.tag = tag;
@ -227,15 +240,64 @@ public class StateWrapper {
return true; return true;
} }
String player = skullOwner.getString("Name"); String player = skullOwner.getString("Name");
if (player == null || player.isEmpty()) {
if (player != null && !player.isEmpty()) {
try {
skull.setOwningPlayer(Bukkit.getOfflinePlayer(player));
skull.update(true);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
final CompoundTag properties = (CompoundTag) skullOwner.getValue().get("Properties");
if (properties == null) {
return false; return false;
} }
try { final ListTag textures = properties.getListTag("textures");
skull.setOwningPlayer(Bukkit.getOfflinePlayer(player)); if (textures.getValue().isEmpty()) {
skull.update(true); return false;
} catch (Exception e) {
e.printStackTrace();
} }
final CompoundTag textureCompound = (CompoundTag) textures.getValue().get(0);
if (textureCompound == null) {
return false;
}
String textureValue = textureCompound.getString("Value");
if (textureValue == null) {
return false;
}
if (!PaperLib.isPaper()) {
if (!paperErrorTextureSent) {
paperErrorTextureSent = true;
LOGGER.error("Failed to populate skull data in your road schematic - This is a Spigot limitation.");
}
return false;
}
final PlayerProfile profile = Bukkit.createProfile(UUID.randomUUID());
profile.setProperty(new ProfileProperty("textures", textureValue));
skull.setPlayerProfile(profile);
skull.update(true);
return true;
}
return false;
}
case "banner" -> {
if (state instanceof Banner banner) {
List<Tag> patterns = this.tag.getListTag("Patterns").getValue();
if (patterns == null || patterns.isEmpty()) {
return false;
}
banner.setPatterns(patterns.stream().map(t -> (CompoundTag) t).map(compoundTag -> {
DyeColor color = DyeColor.getByWoolData((byte) compoundTag.getInt("Color"));
PatternType patternType = PatternType.getByIdentifier(compoundTag.getString("Pattern"));
if (color == null || patternType == null) {
return null;
}
return new Pattern(color, patternType);
}).filter(Objects::nonNull).toList());
banner.update(true);
return true; return true;
} }
return false; return false;

View File

@ -44,6 +44,7 @@ import java.util.stream.IntStream;
@Singleton @Singleton
public class BukkitInventoryUtil extends InventoryUtil { public class BukkitInventoryUtil extends InventoryUtil {
@SuppressWarnings("deprecation") // Paper deprecation
private static @Nullable ItemStack getItem(PlotItemStack item) { private static @Nullable ItemStack getItem(PlotItemStack item) {
if (item == null) { if (item == null) {
return null; return null;

View File

@ -70,7 +70,7 @@ public class BukkitRegionManager extends RegionManager {
@Inject @Inject
public BukkitRegionManager( public BukkitRegionManager(
@NonNull WorldUtil worldUtil, @NonNull GlobalBlockQueue blockQueue, @NonNull @NonNull WorldUtil worldUtil, @NonNull GlobalBlockQueue blockQueue, @NonNull
ProgressSubscriberFactory subscriberFactory ProgressSubscriberFactory subscriberFactory
) { ) {
super(worldUtil, blockQueue, subscriberFactory); super(worldUtil, blockQueue, subscriberFactory);
this.blockQueue = blockQueue; this.blockQueue = blockQueue;

View File

@ -67,6 +67,7 @@ public class BukkitSetupUtils extends SetupUtils {
this.worldFile = worldFile; this.worldFile = worldFile;
} }
@SuppressWarnings("deprecation") // Paper deprecation
@Override @Override
public void updateGenerators(final boolean force) { public void updateGenerators(final boolean force) {
if (loaded && !SetupUtils.generators.isEmpty() && !force) { if (loaded && !SetupUtils.generators.isEmpty() && !force) {

View File

@ -28,24 +28,58 @@ import java.nio.file.Paths;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
* This is a helper class which replaces occurrences of 'suggest_command' with 'run_command' in messages_%.json. * This is a helper class which replaces older syntax no longer supported by MiniMessage with replacements in messages_%.json.
* MiniMessage changed the syntax between major releases. To warrant a smooth upgrade, we attempt to replace any occurrences * MiniMessage changed the syntax between major releases. To warrant a smooth upgrade, we attempt to replace any occurrences
* while loading PlotSquared. * while loading PlotSquared.
* *
* @since TODO * @since 7.0.0
*/ */
@NotPublic @NotPublic
public class TranslationUpdateManager { public class TranslationUpdateManager {
public static void upgradeTranslationFile() throws IOException { public static void upgradeTranslationFile() throws IOException {
String searchText = "suggest_command"; String suggestCommand = "suggest_command";
String replacementText = "run_command"; String suggestCommandReplacement = "run_command";
String minHeight = "minHeight";
String minheightReplacement = "minheight";
String maxHeight = "maxHeight";
String maxheightReplacement = "maxheight";
String usedGrants = "usedGrants";
String usedGrantsReplacement = "used_grants";
String remainingGrants = "remainingGrants";
String remainingGrantsReplacement = "remaining_grants";
String minimumRadius = "minimumRadius";
String minimumRadiusReplacement = "minimum_radius";
String maximumMoves = "maximumMoves";
String maximumMovesReplacement = "maximum_moves";
String userMove = "userMove";
String userMoveReplacement = "user_move";
// tag opening / closing characters are important, as the locale keys exist as well, which should not be replaced
String listInfoUnknown = "<info.unknown>";
String listInfoUnknownReplacement = "<unknown>";
String listInfoServer = "<info.server>";
String listInfoServerReplacement = "<server>";
String listInfoEveryone = "<info.everyone>";
String listInfoEveryoneReplacement = "<everyone>";
try (Stream<Path> paths = Files.walk(Paths.get(PlotSquared.platform().getDirectory().toPath().resolve("lang").toUri()))) { try (Stream<Path> paths = Files.walk(Paths.get(PlotSquared.platform().getDirectory().toPath().resolve("lang").toUri()))) {
paths paths
.filter(Files::isRegularFile) .filter(Files::isRegularFile)
.filter(p -> p.getFileName().toString().matches("messages_[a-z]{2}\\.json")) .filter(p -> p.getFileName().toString().matches("messages_[a-z]{2}\\.json"))
.forEach(p -> replaceInFile(p, searchText, replacementText)); .forEach(p -> {
replaceInFile(p, suggestCommand, suggestCommandReplacement);
replaceInFile(p, minHeight, minheightReplacement);
replaceInFile(p, maxHeight, maxheightReplacement);
replaceInFile(p, usedGrants, usedGrantsReplacement);
replaceInFile(p, remainingGrants, remainingGrantsReplacement);
replaceInFile(p, minimumRadius, minimumRadiusReplacement);
replaceInFile(p, maximumMoves, maximumMovesReplacement);
replaceInFile(p, userMove, userMoveReplacement);
replaceInFile(p, listInfoUnknown, listInfoUnknownReplacement);
replaceInFile(p, listInfoServer, listInfoServerReplacement);
replaceInFile(p, listInfoEveryone, listInfoEveryoneReplacement);
});
} }
} }
@ -60,4 +94,5 @@ public class TranslationUpdateManager {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }

View File

@ -35,7 +35,7 @@ import org.bukkit.scheduler.BukkitTask;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.URL; import java.net.URI;
public class UpdateUtility implements Listener { public class UpdateUtility implements Listener {
@ -54,12 +54,14 @@ public class UpdateUtility implements Listener {
internalVersion = PlotSquared.get().getVersion(); internalVersion = PlotSquared.get().getVersion();
} }
@SuppressWarnings({"deprecation", "DefaultCharset"}) // Suppress Json deprecation, we can't use features from gson 2.8.1 and newer yet @SuppressWarnings({"deprecation", "DefaultCharset"})
// Suppress Json deprecation, we can't use features from gson 2.8.1 and newer yet
public void updateChecker() { public void updateChecker() {
task = Bukkit.getScheduler().runTaskTimerAsynchronously(this.javaPlugin, () -> { task = Bukkit.getScheduler().runTaskTimerAsynchronously(this.javaPlugin, () -> {
try { try {
HttpsURLConnection connection = (HttpsURLConnection) new URL( HttpsURLConnection connection = (HttpsURLConnection) URI.create(
"https://api.spigotmc.org/simple/0.1/index.php?action=getResource&id=77506") "https://api.spigotmc.org/simple/0.2/index.php?action=getResource&id=77506")
.toURL()
.openConnection(); .openConnection();
connection.setRequestMethod("GET"); connection.setRequestMethod("GET");
JsonObject result = new JsonParser() JsonObject result = new JsonParser()

View File

@ -37,7 +37,9 @@ import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
import java.util.Set; import java.util.Set;
public class FaweRegionManager extends BukkitRegionManager { public class FaweRegionManager extends BukkitRegionManager {
@ -59,7 +61,10 @@ public class FaweRegionManager extends BukkitRegionManager {
@Nullable PlotPlayer<?> actor, @Nullable PlotPlayer<?> actor,
@Nullable QueueCoordinator queue @Nullable QueueCoordinator queue
) { ) {
return delegate.setCuboids(area, regions, blocks, minY, maxY, queue.getCompleteTask()); return delegate.setCuboids(
area, regions, blocks, minY, maxY,
Objects.requireNonNullElseGet(queue, area::getQueue).getCompleteTask()
);
} }
@Override @Override
@ -111,7 +116,7 @@ public class FaweRegionManager extends BukkitRegionManager {
} }
@Override @Override
public boolean regenerateRegion(final Location pos1, final Location pos2, boolean ignore, final Runnable whenDone) { public boolean regenerateRegion(final @NotNull Location pos1, final @NotNull Location pos2, boolean ignore, final Runnable whenDone) {
return delegate.regenerateRegion(pos1, pos2, ignore, whenDone); return delegate.regenerateRegion(pos1, pos2, ignore, whenDone);
} }

View File

@ -4,16 +4,16 @@ api-version: "1.13"
version: "${version}" version: "${version}"
load: STARTUP load: STARTUP
description: "Easy, yet powerful Plot World generation and management." description: "Easy, yet powerful Plot World generation and management."
authors: [Citymonstret, Empire92, MattBDev, dordsor21, NotMyFault, SirYwell] authors: [ Citymonstret, Empire92, MattBDev, dordsor21, NotMyFault, SirYwell ]
website: https://www.spigotmc.org/resources/77506/ website: https://www.spigotmc.org/resources/77506/
softdepend: [Vault, PlaceholderAPI, Essentials, LuckPerms, BungeePerms, MVdWPlaceholderAPI] softdepend: [ Vault, PlaceholderAPI, Essentials, LuckPerms, BungeePerms, MVdWPlaceholderAPI ]
loadbefore: [MultiWorld, Multiverse-Core] loadbefore: [ MultiWorld, Multiverse-Core ]
depend: [WorldEdit] depend: [ WorldEdit ]
database: false database: false
commands: commands:
plots: plots:
description: Plot command. description: Plot command.
aliases: [p,plot,ps,plotsquared,p2,2,plotme] aliases: [ p,plot,ps,plotsquared,p2,2,plotme ]
permission: plots.use permission: plots.use
permission-message: "You are lacking the permission node 'plots.use'" permission-message: "You are lacking the permission node 'plots.use'"
permissions: permissions:

View File

@ -1,76 +0,0 @@
# Contributor Covenant 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, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, 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 contact<at>intellectualsites.com. 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 https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

View File

@ -2,18 +2,18 @@ import java.time.format.DateTimeFormatter
dependencies { dependencies {
// Expected everywhere. // Expected everywhere.
compileOnlyApi("org.checkerframework:checker-qual") compileOnlyApi(libs.checkerqual)
// Minecraft expectations // Minecraft expectations
compileOnlyApi("com.google.code.gson:gson") compileOnlyApi(libs.gson)
compileOnly("com.google.guava:guava") compileOnly(libs.guava)
// Platform expectations // Platform expectations
compileOnlyApi("org.yaml:snakeyaml") compileOnlyApi(libs.snakeyaml)
// Adventure // Adventure
api("net.kyori:adventure-api") api(libs.adventureApi)
api("net.kyori:adventure-text-minimessage") api(libs.adventureMiniMessage)
// Guice // Guice
api(libs.guice) { api(libs.guice) {
@ -31,19 +31,19 @@ dependencies {
exclude(group = "dummypermscompat") exclude(group = "dummypermscompat")
} }
testImplementation(libs.worldeditCore) testImplementation(libs.worldeditCore)
compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Core") { isTransitive = false } compileOnly(libs.faweBukkit) { isTransitive = false }
testImplementation("com.fastasyncworldedit:FastAsyncWorldEdit-Core") { isTransitive = false } testImplementation(libs.faweCore) { isTransitive = false }
// Logging // Logging
compileOnlyApi("org.apache.logging.log4j:log4j-api") compileOnlyApi(libs.log4j)
// Other libraries // Other libraries
api(libs.prtree) api(libs.prtree)
api(libs.aopalliance) api(libs.aopalliance)
api(libs.cloudServices) api(libs.cloudServices)
api(libs.arkitektonika) api(libs.arkitektonika)
api("com.intellectualsites.paster:Paster") api(libs.paster)
api("com.intellectualsites.informative-annotations:informative-annotations") api(libs.informativeAnnotations)
} }
tasks.processResources { tasks.processResources {
@ -57,8 +57,8 @@ tasks.processResources {
doLast { doLast {
copy { copy {
from(File("$rootDir/LICENSE")) from(layout.buildDirectory.file("$rootDir/LICENSE"))
into("$buildDir/resources/main/") into(layout.buildDirectory.dir("resources/main"))
} }
} }
} }
@ -68,11 +68,10 @@ tasks {
val isRelease = if (rootProject.version.toString().endsWith("-SNAPSHOT")) "TODO" else rootProject.version.toString() val isRelease = if (rootProject.version.toString().endsWith("-SNAPSHOT")) "TODO" else rootProject.version.toString()
val opt = options as StandardJavadocDocletOptions val opt = options as StandardJavadocDocletOptions
opt.links("https://docs.enginehub.org/javadoc/com.sk89q.worldedit/worldedit-core/" + libs.worldeditCore.get().versionConstraint.toString()) opt.links("https://docs.enginehub.org/javadoc/com.sk89q.worldedit/worldedit-core/" + libs.worldeditCore.get().versionConstraint.toString())
opt.links("https://jd.adventure.kyori.net/api/4.12.0/") opt.links("https://jd.advntr.dev/api/4.14.0/")
opt.links("https://jd.adventure.kyori.net/text-minimessage/4.12.0/") opt.links("https://jd.advntr.dev/text-minimessage/4.14.0/")
opt.links("https://google.github.io/guice/api-docs/" + libs.guice.get().versionConstraint.toString() + "/javadoc/") opt.links("https://google.github.io/guice/api-docs/" + libs.guice.get().versionConstraint.toString() + "/javadoc/")
opt.links("https://checkerframework.org/api/") // opt.links("https://checkerframework.org/api/")
opt.links("https://javadoc.io/doc/com.intellectualsites.informative-annotations/informative-annotations/latest/")
opt.isLinkSource = true opt.isLinkSource = true
opt.bottom(File("$rootDir/javadocfooter.html").readText()) opt.bottom(File("$rootDir/javadocfooter.html").readText())
opt.isUse = true opt.isUse = true

View File

@ -84,7 +84,7 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.net.MalformedURLException; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.nio.file.Files; import java.nio.file.Files;
@ -210,9 +210,10 @@ public class PlotSquared {
try { try {
URL logurl = PlotSquared.class.getProtectionDomain().getCodeSource().getLocation(); URL logurl = PlotSquared.class.getProtectionDomain().getCodeSource().getLocation();
this.jarFile = new File( this.jarFile = new File(
new URL(logurl.toURI().toString().split("\\!")[0].replaceAll("jar:file", "file")) URI.create(
.toURI().getPath()); logurl.toURI().toString().split("\\!")[0].replaceAll("jar:file", "file"))
} catch (MalformedURLException | URISyntaxException | SecurityException e) { .getPath());
} catch (URISyntaxException | SecurityException e) {
e.printStackTrace(); e.printStackTrace();
this.jarFile = new File(this.platform.getDirectory().getParentFile(), "PlotSquared.jar"); this.jarFile = new File(this.platform.getDirectory().getParentFile(), "PlotSquared.jar");
if (!this.jarFile.exists()) { if (!this.jarFile.exists()) {
@ -270,7 +271,11 @@ public class PlotSquared {
captionMap = this.captionLoader.loadAll(this.platform.getDirectory().toPath().resolve("lang")); captionMap = this.captionLoader.loadAll(this.platform.getDirectory().toPath().resolve("lang"));
} else { } else {
String fileName = "messages_" + Settings.Enabled_Components.DEFAULT_LOCALE + ".json"; String fileName = "messages_" + Settings.Enabled_Components.DEFAULT_LOCALE + ".json";
captionMap = this.captionLoader.loadOrCreateSingle(this.platform.getDirectory().toPath().resolve("lang").resolve(fileName)); captionMap = this.captionLoader.loadOrCreateSingle(this.platform
.getDirectory()
.toPath()
.resolve("lang")
.resolve(fileName));
} }
this.captionMaps.put(TranslatableCaption.DEFAULT_NAMESPACE, captionMap); this.captionMaps.put(TranslatableCaption.DEFAULT_NAMESPACE, captionMap);
LOGGER.info( LOGGER.info(
@ -1011,7 +1016,7 @@ public class PlotSquared {
/** /**
* Setup the configuration for a plot world based on world arguments. * Setup the configuration for a plot world based on world arguments.
* * <p>
* *
* <i>e.g. /mv create &lt;world&gt; normal -g PlotSquared:&lt;args&gt;</i> * <i>e.g. /mv create &lt;world&gt; normal -g PlotSquared:&lt;args&gt;</i>
* *
@ -1277,7 +1282,7 @@ public class PlotSquared {
} }
/** /**
* Setup the database connection. * Set up the database connection.
*/ */
public void setupDatabase() { public void setupDatabase() {
try { try {

View File

@ -141,24 +141,24 @@ public class SimpleBackupManager implements BackupManager {
) { ) {
@Override @Override
public boolean equals(final Object o) { public boolean equals(final Object o) {
if (this == o) { if (this == o) {
return true; return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final PlotCacheKey that = (PlotCacheKey) o;
return Objects.equals(plot.getArea(), that.plot.getArea())
&& Objects.equals(plot.getId(), that.plot.getId())
&& Objects.equals(plot.getOwnerAbs(), that.plot.getOwnerAbs());
} }
if (o == null || getClass() != o.getClass()) {
@Override return false;
public int hashCode() {
return Objects.hash(plot.getArea(), plot.getId(), plot.getOwnerAbs());
} }
final PlotCacheKey that = (PlotCacheKey) o;
return Objects.equals(plot.getArea(), that.plot.getArea())
&& Objects.equals(plot.getId(), that.plot.getId())
&& Objects.equals(plot.getOwnerAbs(), that.plot.getOwnerAbs());
} }
@Override
public int hashCode() {
return Objects.hash(plot.getArea(), plot.getId(), plot.getOwnerAbs());
}
}
} }

View File

@ -19,6 +19,7 @@
package com.plotsquared.core.command; package com.plotsquared.core.command;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.database.DBFunc; import com.plotsquared.core.database.DBFunc;
@ -70,7 +71,8 @@ public class Add extends Command {
plot.isOwner(player.getUUID()) || player.hasPermission(Permission.PERMISSION_ADMIN_COMMAND_TRUST), plot.isOwner(player.getUUID()) || player.hasPermission(Permission.PERMISSION_ADMIN_COMMAND_TRUST),
TranslatableCaption.of("permission.no_plot_perms") TranslatableCaption.of("permission.no_plot_perms")
); );
checkTrue(args.length == 1, checkTrue(
args.length == 1,
TranslatableCaption.of("commandconfig.command_syntax"), TranslatableCaption.of("commandconfig.command_syntax"),
TagResolver.resolver("value", Tag.inserting(Component.text("/plot add <player | *>"))) TagResolver.resolver("value", Tag.inserting(Component.text("/plot add <player | *>")))
); );
@ -100,9 +102,14 @@ public class Add extends Command {
Permission.PERMISSION_ADMIN_COMMAND_TRUST))) { Permission.PERMISSION_ADMIN_COMMAND_TRUST))) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("errors.invalid_player"), TranslatableCaption.of("errors.invalid_player"),
TagResolver.resolver("value", Tag.inserting( PlotSquared
PlayerManager.resolveName(uuid).toComponent(player) .platform()
)) .playerManager()
.getUsernameCaption(uuid)
.thenApply(caption -> TagResolver.resolver(
"value",
Tag.inserting(caption.toComponent(player))
))
); );
iterator.remove(); iterator.remove();
continue; continue;
@ -110,9 +117,11 @@ public class Add extends Command {
if (plot.isOwner(uuid)) { if (plot.isOwner(uuid)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("member.already_added"), TranslatableCaption.of("member.already_added"),
TagResolver.resolver("player", Tag.inserting( PlotSquared.platform().playerManager().getUsernameCaption(uuid)
PlayerManager.resolveName(uuid).toComponent(player) .thenApply(caption -> TagResolver.resolver(
)) "player",
Tag.inserting(caption.toComponent(player))
))
); );
iterator.remove(); iterator.remove();
continue; continue;
@ -120,9 +129,11 @@ public class Add extends Command {
if (plot.getMembers().contains(uuid)) { if (plot.getMembers().contains(uuid)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("member.already_added"), TranslatableCaption.of("member.already_added"),
TagResolver.resolver("player", Tag.inserting( PlotSquared.platform().playerManager().getUsernameCaption(uuid)
PlayerManager.resolveName(uuid).toComponent(player) .thenApply(caption -> TagResolver.resolver(
)) "player",
Tag.inserting(caption.toComponent(player))
))
); );
iterator.remove(); iterator.remove();
continue; continue;

View File

@ -131,8 +131,8 @@ public class Auto extends SubCommand {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("economy.removed_granted_plot"), TranslatableCaption.of("economy.removed_granted_plot"),
TagResolver.builder() TagResolver.builder()
.tag("usedGrants", Tag.inserting(Component.text(grantedPlots - left))) .tag("used_grants", Tag.inserting(Component.text(grantedPlots - left)))
.tag("remainingGrants", Tag.inserting(Component.text(left))) .tag("remaining_grants", Tag.inserting(Component.text(left)))
.build() .build()
); );
} }
@ -294,12 +294,15 @@ public class Auto extends SubCommand {
return true; return true;
} }
} }
if (this.econHandler != null && plotarea.useEconomy()) { if (this.econHandler != null && plotarea.useEconomy() && !player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_ECON)) {
PlotExpression costExp = plotarea.getPrices().get("claim"); PlotExpression costExp = plotarea.getPrices().get("claim");
PlotExpression mergeCostExp = plotarea.getPrices().get("merge");
int size = sizeX * sizeZ;
double mergeCost = size <= 1 || mergeCostExp == null ? 0d : mergeCostExp.evaluate(size);
double cost = costExp.evaluate(Settings.Limit.GLOBAL ? double cost = costExp.evaluate(Settings.Limit.GLOBAL ?
player.getPlotCount() : player.getPlotCount() :
player.getPlotCount(plotarea.getWorldName())); player.getPlotCount(plotarea.getWorldName()));
cost = (sizeX * sizeZ) * cost; cost = size * cost + mergeCost;
if (cost > 0d) { if (cost > 0d) {
if (!this.econHandler.isSupported()) { if (!this.econHandler.isSupported()) {
player.sendMessage(TranslatableCaption.of("economy.vault_or_consumer_null")); player.sendMessage(TranslatableCaption.of("economy.vault_or_consumer_null"));

View File

@ -21,8 +21,9 @@ package com.plotsquared.core.command;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.events.PlotFlagRemoveEvent; import com.plotsquared.core.events.PlayerBuyPlotEvent;
import com.plotsquared.core.events.Result; import com.plotsquared.core.events.Result;
import com.plotsquared.core.player.OfflinePlotPlayer;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
@ -88,22 +89,30 @@ public class Buy extends Command {
TranslatableCaption.of("permission.cant_claim_more_plots"), TranslatableCaption.of("permission.cant_claim_more_plots"),
TagResolver.resolver("amount", Tag.inserting(Component.text(player.getAllowedPlots()))) TagResolver.resolver("amount", Tag.inserting(Component.text(player.getAllowedPlots())))
); );
double price = plot.getFlag(PriceFlag.class); double priceFlag = plot.getFlag(PriceFlag.class);
if (price <= 0) { if (priceFlag <= 0) {
throw new CommandException(TranslatableCaption.of("economy.not_for_sale")); throw new CommandException(TranslatableCaption.of("economy.not_for_sale"));
} }
checkTrue( checkTrue(
this.econHandler.isSupported(), this.econHandler.isSupported(),
TranslatableCaption.of("economy.vault_or_consumer_null") TranslatableCaption.of("economy.vault_or_consumer_null")
); );
checkTrue(
this.econHandler.getMoney(player) >= price, PlayerBuyPlotEvent event = this.eventDispatcher.callPlayerBuyPlot(player, plot, priceFlag);
TranslatableCaption.of("economy.cannot_afford_plot"), if (event.getEventResult() == Result.DENY) {
TagResolver.builder() throw new CommandException(TranslatableCaption.of("economy.cannot_buy_blocked"));
.tag("money", Tag.inserting(Component.text(this.econHandler.format(price)))) }
.tag("balance", Tag.inserting(Component.text(this.econHandler.format(this.econHandler.getMoney(player)))))
.build() double price = event.getEventResult() == Result.FORCE ? 0 : event.price();
); if (this.econHandler.getMoney(player) < price) {
throw new CommandException(
TranslatableCaption.of("economy.cannot_afford_plot"),
TagResolver.builder()
.tag("money", Tag.inserting(Component.text(this.econHandler.format(price))))
.tag("balance", Tag.inserting(Component.text(this.econHandler.format(this.econHandler.getMoney(player)))))
.build()
);
}
this.econHandler.withdrawMoney(player, price); this.econHandler.withdrawMoney(player, price);
// Failure // Failure
// Success // Success
@ -113,7 +122,8 @@ public class Buy extends Command {
TagResolver.resolver("money", Tag.inserting(Component.text(this.econHandler.format(price)))) TagResolver.resolver("money", Tag.inserting(Component.text(this.econHandler.format(price))))
); );
this.econHandler.depositMoney(PlotSquared.platform().playerManager().getOfflinePlayer(plot.getOwnerAbs()), price); OfflinePlotPlayer previousOwner = PlotSquared.platform().playerManager().getOfflinePlayer(plot.getOwnerAbs());
this.econHandler.depositMoney(previousOwner, price);
PlotPlayer<?> owner = PlotSquared.platform().playerManager().getPlayerIfExists(plot.getOwnerAbs()); PlotPlayer<?> owner = PlotSquared.platform().playerManager().getPlayerIfExists(plot.getOwnerAbs());
if (owner != null) { if (owner != null) {
@ -127,9 +137,8 @@ public class Buy extends Command {
); );
} }
PlotFlag<?, ?> plotFlag = plot.getFlagContainer().getFlag(PriceFlag.class); PlotFlag<?, ?> plotFlag = plot.getFlagContainer().getFlag(PriceFlag.class);
PlotFlagRemoveEvent event = this.eventDispatcher.callFlagRemove(plotFlag, plot); if (this.eventDispatcher.callFlagRemove(plotFlag, plot).getEventResult() != Result.DENY) {
if (event.getEventResult() != Result.DENY) { plot.removeFlag(plotFlag);
plot.removeFlag(event.getFlag());
} }
plot.setOwner(player.getUUID()); plot.setOwner(player.getUUID());
plot.getPlotModificationManager().setSign(player.getName()); plot.getPlotModificationManager().setSign(player.getName());
@ -137,6 +146,7 @@ public class Buy extends Command {
TranslatableCaption.of("working.claimed"), TranslatableCaption.of("working.claimed"),
TagResolver.resolver("plot", Tag.inserting(Component.text(plot.getId().toString()))) TagResolver.resolver("plot", Tag.inserting(Component.text(plot.getId().toString())))
); );
this.eventDispatcher.callPostPlayerBuyPlot(player, previousOwner, plot, price);
whenDone.run(Buy.this, CommandResult.SUCCESS); whenDone.run(Buy.this, CommandResult.SUCCESS);
}, () -> { }, () -> {
this.econHandler.depositMoney(player, price); this.econHandler.depositMoney(player, price);

View File

@ -141,7 +141,7 @@ public class Claim extends SubCommand {
} }
} }
} }
if (this.econHandler.isEnabled(area) && !force) { if (this.econHandler.isEnabled(area) && !force && !player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_ECON)) {
PlotExpression costExr = area.getPrices().get("claim"); PlotExpression costExr = area.getPrices().get("claim");
double cost = costExr.evaluate(currentPlots); double cost = costExr.evaluate(currentPlots);
if (cost > 0d) { if (cost > 0d) {
@ -186,14 +186,14 @@ public class Claim extends SubCommand {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("economy.removed_granted_plot"), TranslatableCaption.of("economy.removed_granted_plot"),
TagResolver.builder() TagResolver.builder()
.tag("usedGrants", Tag.inserting(Component.text(grants - 1))) .tag("used_grants", Tag.inserting(Component.text(grants - 1)))
.tag("remainingGrants", Tag.inserting(Component.text(grants))) .tag("remaining_grants", Tag.inserting(Component.text(grants)))
.build() .build()
); );
} }
} }
if (!player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_BORDER)) { if (!player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_BORDER)) {
int border = area.getBorder(); int border = area.getBorder(false);
if (border != Integer.MAX_VALUE && plot.getDistanceFromOrigin() > border && !force) { if (border != Integer.MAX_VALUE && plot.getDistanceFromOrigin() > border && !force) {
player.sendMessage(TranslatableCaption.of("border.denied")); player.sendMessage(TranslatableCaption.of("border.denied"));
return false; return false;

View File

@ -107,37 +107,36 @@ public class Clear extends Command {
} }
BackupManager.backup(player, plot, () -> { BackupManager.backup(player, plot, () -> {
final long start = System.currentTimeMillis(); final long start = System.currentTimeMillis();
boolean result = plot.getPlotModificationManager().clear(true, false, player, () -> { boolean result = plot.getPlotModificationManager().clear(true, false, player, () -> TaskManager.runTask(() -> {
TaskManager.runTask(() -> { plot.removeRunning();
plot.removeRunning(); // If the state changes, then mark it as no longer done
// If the state changes, then mark it as no longer done if (DoneFlag.isDone(plot)) {
if (DoneFlag.isDone(plot)) { PlotFlag<?, ?> plotFlag =
PlotFlag<?, ?> plotFlag = plot.getFlagContainer().getFlag(DoneFlag.class);
plot.getFlagContainer().getFlag(DoneFlag.class); PlotFlagRemoveEvent event = this.eventDispatcher
PlotFlagRemoveEvent event = this.eventDispatcher .callFlagRemove(plotFlag, plot);
.callFlagRemove(plotFlag, plot); if (event.getEventResult() != Result.DENY) {
if (event.getEventResult() != Result.DENY) { plot.removeFlag(event.getFlag());
plot.removeFlag(event.getFlag());
}
} }
if (!plot.getFlag(AnalysisFlag.class).isEmpty()) { }
PlotFlag<?, ?> plotFlag = if (!plot.getFlag(AnalysisFlag.class).isEmpty()) {
plot.getFlagContainer().getFlag(AnalysisFlag.class); PlotFlag<?, ?> plotFlag =
PlotFlagRemoveEvent event = this.eventDispatcher plot.getFlagContainer().getFlag(AnalysisFlag.class);
.callFlagRemove(plotFlag, plot); PlotFlagRemoveEvent event = this.eventDispatcher
if (event.getEventResult() != Result.DENY) { .callFlagRemove(plotFlag, plot);
plot.removeFlag(event.getFlag()); if (event.getEventResult() != Result.DENY) {
} plot.removeFlag(event.getFlag());
} }
player.sendMessage( }
TranslatableCaption.of("working.clearing_done"), player.sendMessage(
TagResolver.builder() TranslatableCaption.of("working.clearing_done"),
.tag("amount", Tag.inserting(Component.text(System.currentTimeMillis() - start))) TagResolver.builder()
.tag("plot", Tag.inserting(Component.text(plot.getId().toString()))) .tag("amount", Tag.inserting(Component.text(System.currentTimeMillis() - start)))
.build() .tag("plot", Tag.inserting(Component.text(plot.getId().toString())))
); .build()
}); );
}); this.eventDispatcher.callPostPlotClear(player, plot);
}));
if (!result) { if (!result) {
player.sendMessage(TranslatableCaption.of("errors.wait_for_timer")); player.sendMessage(TranslatableCaption.of("errors.wait_for_timer"));
} else { } else {

View File

@ -46,6 +46,7 @@ import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
@ -77,8 +78,7 @@ public class Cluster extends SubCommand {
} }
String sub = args[0].toLowerCase(); String sub = args[0].toLowerCase();
switch (sub) { switch (sub) {
case "l": case "l", "list" -> {
case "list": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_LIST)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_LIST)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),
@ -133,8 +133,7 @@ public class Cluster extends SubCommand {
} }
return true; return true;
} }
case "c": case "c", "create" -> {
case "create": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_CREATE)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_CREATE)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),
@ -269,9 +268,7 @@ public class Cluster extends SubCommand {
); );
return true; return true;
} }
case "disband": case "disband", "del", "delete" -> {
case "del":
case "delete": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_DELETE)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_DELETE)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),
@ -330,8 +327,7 @@ public class Cluster extends SubCommand {
)); ));
return true; return true;
} }
case "res": case "res", "resize" -> {
case "resize": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_RESIZE)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_RESIZE)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),
@ -452,9 +448,7 @@ public class Cluster extends SubCommand {
player.sendMessage(TranslatableCaption.of("cluster.cluster_resized")); player.sendMessage(TranslatableCaption.of("cluster.cluster_resized"));
return true; return true;
} }
case "add": case "add", "inv", "invite" -> {
case "inv":
case "invite": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_INVITE)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_INVITE)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),
@ -523,9 +517,7 @@ public class Cluster extends SubCommand {
}); });
return true; return true;
} }
case "k": case "k", "remove", "kick" -> {
case "remove":
case "kick": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_KICK)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_KICK)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),
@ -605,8 +597,7 @@ public class Cluster extends SubCommand {
}); });
return true; return true;
} }
case "quit": case "quit", "leave" -> {
case "leave": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_LEAVE)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_LEAVE)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),
@ -667,7 +658,7 @@ public class Cluster extends SubCommand {
removePlayerPlots(cluster, uuid, player.getLocation().getWorldName()); removePlayerPlots(cluster, uuid, player.getLocation().getWorldName());
return true; return true;
} }
case "members": { case "members" -> {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_HELPERS)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_HELPERS)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),
@ -728,9 +719,7 @@ public class Cluster extends SubCommand {
}); });
return true; return true;
} }
case "spawn": case "spawn", "home", "tp" -> {
case "home":
case "tp": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_TP)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_TP)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),
@ -778,10 +767,7 @@ public class Cluster extends SubCommand {
player.sendMessage(TranslatableCaption.of("cluster.cluster_teleporting")); player.sendMessage(TranslatableCaption.of("cluster.cluster_teleporting"));
return true; return true;
} }
case "i": case "i", "info", "show", "information" -> {
case "info":
case "show":
case "information": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_INFO)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_INFO)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),
@ -828,11 +814,7 @@ public class Cluster extends SubCommand {
player.sendMessage(TranslatableCaption.of("players.fetching_players_timeout")); player.sendMessage(TranslatableCaption.of("players.fetching_players_timeout"));
} else { } else {
final String owner; final String owner;
if (username == null) { owner = Objects.requireNonNullElse(username, "unknown");
owner = "unknown";
} else {
owner = username;
}
String name = cluster.getName(); String name = cluster.getName();
String size = (cluster.getP2().getX() - cluster.getP1().getX() + 1) + "x" + ( String size = (cluster.getP2().getX() - cluster.getP1().getX() + 1) + "x" + (
cluster.getP2().getY() - cluster.getP1().getY() + 1); cluster.getP2().getY() - cluster.getP1().getY() + 1);
@ -850,9 +832,7 @@ public class Cluster extends SubCommand {
}); });
return true; return true;
} }
case "sh": case "sh", "setspawn", "sethome" -> {
case "setspawn":
case "sethome": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_SETHOME)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_SETHOME)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),

View File

@ -559,9 +559,10 @@ public abstract class Command {
public Collection<Command> tab(PlotPlayer<?> player, String[] args, boolean space) { public Collection<Command> tab(PlotPlayer<?> player, String[] args, boolean space) {
switch (args.length) { switch (args.length) {
case 0: case 0 -> {
return this.allCommands; return this.allCommands;
case 1: }
case 1 -> {
String arg = args[0].toLowerCase(); String arg = args[0].toLowerCase();
if (space) { if (space) {
Command cmd = getCommand(arg); Command cmd = getCommand(arg);
@ -580,13 +581,15 @@ public abstract class Command {
} }
return commands; return commands;
} }
default: }
default -> {
Command cmd = getCommand(args[0]); Command cmd = getCommand(args[0]);
if (cmd != null) { if (cmd != null) {
return cmd.tab(player, Arrays.copyOfRange(args, 1, args.length), space); return cmd.tab(player, Arrays.copyOfRange(args, 1, args.length), space);
} else { } else {
return null; return null;
} }
}
} }
} }

View File

@ -25,6 +25,7 @@ import com.plotsquared.core.player.PlotPlayer;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.jetbrains.annotations.NotNull;
/** /**
* CommandCategory. * CommandCategory.
@ -82,7 +83,7 @@ public enum CommandCategory implements Caption {
// TODO this method shouldn't be invoked // TODO this method shouldn't be invoked
@Deprecated @Deprecated
@Override @Override
public String toString() { public @NotNull String toString() {
return this.caption.getComponent(LocaleHolder.console()); return this.caption.getComponent(LocaleHolder.console());
} }
@ -108,4 +109,5 @@ public enum CommandCategory implements Caption {
return !MainCommand.getInstance().getCommands(this, player).isEmpty(); return !MainCommand.getInstance().getCommands(this, player).isEmpty();
} }
} }

View File

@ -256,11 +256,11 @@ public class Condense extends SubCommand {
player.sendMessage(TranslatableCaption.of("condense.default_eval")); player.sendMessage(TranslatableCaption.of("condense.default_eval"));
player.sendMessage( player.sendMessage(
TranslatableCaption.of("condense.minimum_radius"), TranslatableCaption.of("condense.minimum_radius"),
TagResolver.resolver("minimumRadius", Tag.inserting(Component.text(minimumRadius))) TagResolver.resolver("minimum_radius", Tag.inserting(Component.text(minimumRadius)))
); );
player.sendMessage( player.sendMessage(
TranslatableCaption.of("condense.maximum_moved"), TranslatableCaption.of("condense.maximum_moved"),
TagResolver.resolver("maxMove", Tag.inserting(Component.text(maxMove))) TagResolver.resolver("maximum_moves", Tag.inserting(Component.text(maxMove)))
); );
player.sendMessage(TranslatableCaption.of("condense.input_eval")); player.sendMessage(TranslatableCaption.of("condense.input_eval"));
player.sendMessage( player.sendMessage(
@ -269,7 +269,7 @@ public class Condense extends SubCommand {
); );
player.sendMessage( player.sendMessage(
TranslatableCaption.of("condense.estimated_moves"), TranslatableCaption.of("condense.estimated_moves"),
TagResolver.resolver("userMove", Tag.inserting(Component.text(userMove))) TagResolver.resolver("user_move", Tag.inserting(Component.text(userMove)))
); );
player.sendMessage(TranslatableCaption.of("condense.eta")); player.sendMessage(TranslatableCaption.of("condense.eta"));
player.sendMessage(TranslatableCaption.of("condense.radius_measured")); player.sendMessage(TranslatableCaption.of("condense.radius_measured"));

View File

@ -69,7 +69,8 @@ public class Copy extends SubCommand {
plot1.getPlotModificationManager().copy(plot2, player).thenAccept(result -> { plot1.getPlotModificationManager().copy(plot2, player).thenAccept(result -> {
if (result) { if (result) {
player.sendMessage(TranslatableCaption.of("move.copy_success"), player.sendMessage(
TranslatableCaption.of("move.copy_success"),
TagResolver.builder() TagResolver.builder()
.tag("origin", Tag.inserting(Component.text(plot1.toString()))) .tag("origin", Tag.inserting(Component.text(plot1.toString())))
.tag("target", Tag.inserting(Component.text(plot2.toString()))) .tag("target", Tag.inserting(Component.text(plot2.toString())))

View File

@ -29,7 +29,6 @@ import com.plotsquared.core.util.WorldUtil;
import com.plotsquared.core.util.entity.EntityCategories; import com.plotsquared.core.util.entity.EntityCategories;
import com.plotsquared.core.util.entity.EntityCategory; import com.plotsquared.core.util.entity.EntityCategory;
import com.plotsquared.core.util.query.PlotQuery; import com.plotsquared.core.util.query.PlotQuery;
import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.uuid.UUIDMapping; import com.plotsquared.core.uuid.UUIDMapping;
import com.sk89q.worldedit.world.entity.EntityType; import com.sk89q.worldedit.world.entity.EntityType;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -71,7 +70,7 @@ public class Debug extends SubCommand {
TranslatableCaption.of("commandconfig.command_syntax"), TranslatableCaption.of("commandconfig.command_syntax"),
TagResolver.resolver( TagResolver.resolver(
"value", "value",
Tag.inserting(Component.text("/plot debug <loadedchunks | player | debug-players | entitytypes | msg>")) Tag.inserting(Component.text("/plot debug <player | debug-players | entitytypes | msg>"))
) )
); );
} }
@ -85,16 +84,6 @@ public class Debug extends SubCommand {
return true; return true;
} }
} }
if (args.length > 0 && "loadedchunks".equalsIgnoreCase(args[0])) {
final long start = System.currentTimeMillis();
player.sendMessage(TranslatableCaption.of("debug.fetching_loaded_chunks"));
TaskManager.runTaskAsync(() -> player.sendMessage(StaticCaption
.of("Loaded chunks: " + this.worldUtil
.getChunkChunks(player.getLocation().getWorldName())
.size() + " (" + (System.currentTimeMillis()
- start) + "ms) using thread: " + Thread.currentThread().getName())));
return true;
}
if (args.length > 0 && "uuids".equalsIgnoreCase(args[0])) { if (args.length > 0 && "uuids".equalsIgnoreCase(args[0])) {
final Collection<UUIDMapping> mappings = PlotSquared.get().getImpromptuUUIDPipeline().getAllImmediately(); final Collection<UUIDMapping> mappings = PlotSquared.get().getImpromptuUUIDPipeline().getAllImmediately();
player.sendMessage( player.sendMessage(
@ -196,7 +185,7 @@ public class Debug extends SubCommand {
@Override @Override
public Collection<Command> tab(final PlotPlayer<?> player, String[] args, boolean space) { public Collection<Command> tab(final PlotPlayer<?> player, String[] args, boolean space) {
return Stream.of("loadedchunks", "debug-players", "entitytypes") return Stream.of("debug-players", "entitytypes")
.filter(value -> value.startsWith(args[0].toLowerCase(Locale.ENGLISH))) .filter(value -> value.startsWith(args[0].toLowerCase(Locale.ENGLISH)))
.map(value -> new Command(null, false, value, "plots.admin", RequiredType.NONE, null) { .map(value -> new Command(null, false, value, "plots.admin", RequiredType.NONE, null) {
}).collect(Collectors.toList()); }).collect(Collectors.toList());

View File

@ -71,9 +71,9 @@ public class DebugPaste extends SubCommand {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
b.append( b.append(
""" """
# Welcome to this paste # Welcome to this paste
# It is meant to provide us at IntellectualSites with better information about your problem # It is meant to provide us at IntellectualSites with better information about your problem
""" """
); );
b.append("# PlotSquared Information\n"); b.append("# PlotSquared Information\n");
b.append("PlotSquared Version: ").append(PlotSquared.get().getVersion()) b.append("PlotSquared Version: ").append(PlotSquared.get().getVersion())

View File

@ -75,16 +75,19 @@ public class DebugRoadRegen extends SubCommand {
} }
String kind = args[0].toLowerCase(); String kind = args[0].toLowerCase();
switch (kind) { switch (kind) {
case "plot": case "plot" -> {
return regenPlot(player); return regenPlot(player);
case "region": }
case "region" -> {
return regenRegion(player, Arrays.copyOfRange(args, 1, args.length)); return regenRegion(player, Arrays.copyOfRange(args, 1, args.length));
default: }
default -> {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("commandconfig.command_syntax"), TranslatableCaption.of("commandconfig.command_syntax"),
TagResolver.resolver("value", Tag.inserting(Component.text(DebugRoadRegen.USAGE))) TagResolver.resolver("value", Tag.inserting(Component.text(DebugRoadRegen.USAGE)))
); );
return false; return false;
}
} }
} }
@ -93,6 +96,7 @@ public class DebugRoadRegen extends SubCommand {
PlotArea area = location.getPlotArea(); PlotArea area = location.getPlotArea();
if (area == null) { if (area == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot_world")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot_world"));
return false;
} }
Plot plot = player.getCurrentPlot(); Plot plot = player.getCurrentPlot();
if (plot == null) { if (plot == null) {

View File

@ -117,10 +117,11 @@ public class Deny extends SubCommand {
} else if (plot.getDenied().contains(uuid)) { } else if (plot.getDenied().contains(uuid)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("member.already_added"), TranslatableCaption.of("member.already_added"),
TagResolver.resolver( PlotSquared.platform().playerManager().getUsernameCaption(uuid)
.thenApply(caption -> TagResolver.resolver(
"player", "player",
Tag.inserting(PlayerManager.resolveName(uuid).toComponent(player)) Tag.inserting(caption.toComponent(player))
) ))
); );
return; return;
} else { } else {

View File

@ -94,7 +94,7 @@ public class Done extends SubCommand {
TagResolver.resolver("plot", Tag.inserting(Component.text(plot.getId().toString()))) TagResolver.resolver("plot", Tag.inserting(Component.text(plot.getId().toString())))
); );
final Settings.Auto_Clear doneRequirements = Settings.AUTO_CLEAR.get("done"); final Settings.Auto_Clear doneRequirements = Settings.AUTO_CLEAR.get("done");
if (PlotSquared.platform().expireManager() == null || doneRequirements == null) { if (PlotSquared.platform().expireManager() == null || doneRequirements == null || player.hasPermission(Permission.PERMISSION_ADMIN_COMMAND_DONE)) {
finish(plot, player, true); finish(plot, player, true);
plot.removeRunning(); plot.removeRunning();
} else { } else {
@ -103,7 +103,7 @@ public class Done extends SubCommand {
public void run(PlotAnalysis value) { public void run(PlotAnalysis value) {
plot.removeRunning(); plot.removeRunning();
boolean result = boolean result =
value.getComplexity(doneRequirements) <= doneRequirements.THRESHOLD; value.getComplexity(doneRequirements) >= doneRequirements.THRESHOLD;
finish(plot, player, result); finish(plot, player, result);
} }
}); });

View File

@ -136,7 +136,9 @@ public class Download extends SubCommand {
} }
player.sendMessage( player.sendMessage(
TranslatableCaption.of("web.generation_link_success_legacy_world"), TranslatableCaption.of("web.generation_link_success_legacy_world"),
TagResolver.resolver("url", Tag.inserting(Component.text(url.toString()))) TagResolver.builder()
.tag("url", Tag.preProcessParsed(url.toString()))
.build()
); );
} }
}); });
@ -185,22 +187,25 @@ public class Download extends SubCommand {
if (Settings.Web.LEGACY_WEBINTERFACE) { if (Settings.Web.LEGACY_WEBINTERFACE) {
schematicHandler schematicHandler
.getCompoundTag(plot) .getCompoundTag(plot)
.whenComplete((compoundTag, throwable) -> { .whenComplete((compoundTag, throwable) -> schematicHandler.upload(
schematicHandler.upload(compoundTag, null, null, new RunnableVal<>() { compoundTag,
@Override null,
public void run(URL value) { null,
plot.removeRunning(); new RunnableVal<>() {
player.sendMessage( @Override
TranslatableCaption.of("web.generation_link_success"), public void run(URL value) {
TagResolver.builder() plot.removeRunning();
.tag("download", Tag.preProcessParsed(value.toString())) player.sendMessage(
.tag("delete", Tag.preProcessParsed("Not available")) TranslatableCaption.of("web.generation_link_success"),
.build() TagResolver.builder()
); .tag("download", Tag.preProcessParsed(value.toString()))
player.sendMessage(StaticCaption.of(value.toString())); .tag("delete", Tag.preProcessParsed("Not available"))
.build()
);
player.sendMessage(StaticCaption.of(value.toString()));
}
} }
}); ));
});
return; return;
} }
// TODO legacy support // TODO legacy support

View File

@ -103,9 +103,10 @@ public final class FlagCommand extends Command {
if (flag instanceof IntegerFlag && MathMan.isInteger(value)) { if (flag instanceof IntegerFlag && MathMan.isInteger(value)) {
try { try {
int numeric = Integer.parseInt(value); int numeric = Integer.parseInt(value);
// Getting full permission without ".<amount>" at the end
perm = perm.substring(0, perm.length() - value.length() - 1); perm = perm.substring(0, perm.length() - value.length() - 1);
boolean result = false; boolean result = false;
if (numeric > 0) { if (numeric >= 0) {
int checkRange = PlotSquared.get().getPlatform().equalsIgnoreCase("bukkit") ? int checkRange = PlotSquared.get().getPlatform().equalsIgnoreCase("bukkit") ?
numeric : numeric :
Settings.Limit.MAX_PLOTS; Settings.Limit.MAX_PLOTS;

View File

@ -60,9 +60,10 @@ public class Help extends Command {
RunnableVal2<Command, CommandResult> whenDone RunnableVal2<Command, CommandResult> whenDone
) { ) {
switch (args.length) { switch (args.length) {
case 0: case 0 -> {
return displayHelp(player, null, 0); return displayHelp(player, null, 0);
case 1: }
case 1 -> {
if (MathMan.isInteger(args[0])) { if (MathMan.isInteger(args[0])) {
try { try {
return displayHelp(player, null, Integer.parseInt(args[0])); return displayHelp(player, null, Integer.parseInt(args[0]));
@ -72,7 +73,8 @@ public class Help extends Command {
} else { } else {
return displayHelp(player, args[0], 1); return displayHelp(player, args[0], 1);
} }
case 2: }
case 2 -> {
if (MathMan.isInteger(args[1])) { if (MathMan.isInteger(args[1])) {
try { try {
return displayHelp(player, args[0], Integer.parseInt(args[1])); return displayHelp(player, args[0], Integer.parseInt(args[1]));
@ -81,8 +83,8 @@ public class Help extends Command {
} }
} }
return CompletableFuture.completedFuture(false); return CompletableFuture.completedFuture(false);
default: }
sendUsage(player); default -> sendUsage(player);
} }
return CompletableFuture.completedFuture(true); return CompletableFuture.completedFuture(true);
} }
@ -132,7 +134,12 @@ public class Help extends Command {
TagResolver.builder() TagResolver.builder()
.tag("command", Tag.inserting(Component.text("/plot help"))) .tag("command", Tag.inserting(Component.text("/plot help")))
.tag("category", Tag.inserting(Component.text("all"))) .tag("category", Tag.inserting(Component.text("all")))
.tag("category_desc", Tag.inserting(TranslatableCaption.of("help.help_display_all_commands").toComponent(player))) .tag(
"category_desc",
Tag.inserting(TranslatableCaption
.of("help.help_display_all_commands")
.toComponent(player))
)
.build() .build()
)); ));
builder.append(Component.newline()).append(MINI_MESSAGE.deserialize(TranslatableCaption builder.append(Component.newline()).append(MINI_MESSAGE.deserialize(TranslatableCaption

View File

@ -190,7 +190,7 @@ public class Inbox extends SubCommand {
final int page; final int page;
if (args.length > 1) { if (args.length > 1) {
switch (args[1].toLowerCase()) { switch (args[1].toLowerCase()) {
case "delete": case "delete" -> {
if (!inbox.canModify(plot, player)) { if (!inbox.canModify(plot, player)) {
player.sendMessage(TranslatableCaption.of("comment.no_perm_inbox_modify")); player.sendMessage(TranslatableCaption.of("comment.no_perm_inbox_modify"));
return false; return false;
@ -225,7 +225,6 @@ public class Inbox extends SubCommand {
); );
return false; return false;
} }
if (!inbox.getComments(plot, new RunnableVal<>() { if (!inbox.getComments(plot, new RunnableVal<>() {
@Override @Override
public void run(List<PlotComment> value) { public void run(List<PlotComment> value) {
@ -254,7 +253,8 @@ public class Inbox extends SubCommand {
return false; return false;
} }
return true; return true;
case "clear": }
case "clear" -> {
if (!inbox.canModify(plot, player)) { if (!inbox.canModify(plot, player)) {
player.sendMessage(TranslatableCaption.of("comment.no_perm_inbox_modify")); player.sendMessage(TranslatableCaption.of("comment.no_perm_inbox_modify"));
} }
@ -268,13 +268,15 @@ public class Inbox extends SubCommand {
plot.getPlotCommentContainer().removeComments(comments); plot.getPlotCommentContainer().removeComments(comments);
} }
return true; return true;
default: }
default -> {
try { try {
page = Integer.parseInt(args[1]); page = Integer.parseInt(args[1]);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
sendUsage(player); sendUsage(player);
return false; return false;
} }
}
} }
} else { } else {
page = 1; page = 1;

View File

@ -52,8 +52,9 @@ public class Info extends SubCommand {
arg = args[0]; arg = args[0];
switch (arg) { switch (arg) {
// TODO: (re?)implement /plot info inv. (it was never properly implemented) // TODO: (re?)implement /plot info inv. (it was never properly implemented)
case "trusted", "alias", "biome", "denied", "flags", "id", "size", "members", "creationdate", "seen", "owner", "rating", "likes" -> plot = Plot case "trusted", "alias", "biome", "denied", "flags", "id", "size", "members", "creationdate", "seen", "owner", "rating", "likes" ->
.getPlotFromString(player, null, false); plot = Plot
.getPlotFromString(player, null, false);
default -> { default -> {
plot = Plot.getPlotFromString(player, arg, false); plot = Plot.getPlotFromString(player, arg, false);
if (args.length == 2) { if (args.length == 2) {

View File

@ -112,15 +112,15 @@ public class Kick extends SubCommand {
for (PlotPlayer<?> player2 : players) { for (PlotPlayer<?> player2 : players) {
if (!plot.equals(player2.getCurrentPlot())) { if (!plot.equals(player2.getCurrentPlot())) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("errors.invalid_player"), TranslatableCaption.of("kick.player_not_in_plot"),
TagResolver.resolver("value", Tag.inserting(Component.text(args[0]))) TagResolver.resolver("player", Tag.inserting(Component.text(player2.getName())))
); );
return; return;
} }
if (player2.hasPermission(Permission.PERMISSION_ADMIN_ENTRY_DENIED)) { if (player2.hasPermission(Permission.PERMISSION_ADMIN_ENTRY_DENIED)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("cluster.cannot_kick_player"), TranslatableCaption.of("kick.cannot_kick_player"),
TagResolver.resolver("name", Tag.inserting(Component.text(player2.getName()))) TagResolver.resolver("player", Tag.inserting(Component.text(player2.getName())))
); );
return; return;
} }

View File

@ -465,7 +465,7 @@ public class ListCmd extends SubCommand {
TextComponent.Builder builder = Component.text(); TextComponent.Builder builder = Component.text();
if (plot.getFlag(ServerPlotFlag.class)) { if (plot.getFlag(ServerPlotFlag.class)) {
TagResolver serverResolver = TagResolver.resolver( TagResolver serverResolver = TagResolver.resolver(
"info.server", "server",
Tag.inserting(TranslatableCaption.of("info.server").toComponent(player)) Tag.inserting(TranslatableCaption.of("info.server").toComponent(player))
); );
builder.append(MINI_MESSAGE.deserialize(server, serverResolver)); builder.append(MINI_MESSAGE.deserialize(server, serverResolver));
@ -476,20 +476,20 @@ public class ListCmd extends SubCommand {
for (final UUIDMapping uuidMapping : names) { for (final UUIDMapping uuidMapping : names) {
PlotPlayer<?> pp = PlotSquared.platform().playerManager().getPlayerIfExists(uuidMapping.uuid()); PlotPlayer<?> pp = PlotSquared.platform().playerManager().getPlayerIfExists(uuidMapping.uuid());
TagResolver resolver = TagResolver.builder() TagResolver resolver = TagResolver.builder()
.tag("prefix", Tag.inserting(Component.text(prefix))) .tag("prefix", Tag.inserting(Component.text(prefix)))
.tag("player", Tag.inserting(Component.text(uuidMapping.username()))) .tag("player", Tag.inserting(Component.text(uuidMapping.username())))
.build(); .build();
if (pp != null) { if (pp != null) {
builder.append(MINI_MESSAGE.deserialize(online, resolver)); builder.append(MINI_MESSAGE.deserialize(online, resolver));
} else if (uuidMapping.username().equalsIgnoreCase("unknown")) { } else if (uuidMapping.username().equalsIgnoreCase("unknown")) {
TagResolver unknownResolver = TagResolver.resolver( TagResolver unknownResolver = TagResolver.resolver(
"info.unknown", "unknown",
Tag.inserting(TranslatableCaption.of("info.unknown").toComponent(player)) Tag.inserting(TranslatableCaption.of("info.unknown").toComponent(player))
); );
builder.append(MINI_MESSAGE.deserialize(unknown, unknownResolver)); builder.append(MINI_MESSAGE.deserialize(unknown, unknownResolver));
} else if (uuidMapping.uuid().equals(DBFunc.EVERYONE)) { } else if (uuidMapping.uuid().equals(DBFunc.EVERYONE)) {
TagResolver everyoneResolver = TagResolver.resolver( TagResolver everyoneResolver = TagResolver.resolver(
"info.everyone", "everyone",
Tag.inserting(TranslatableCaption.of("info.everyone").toComponent(player)) Tag.inserting(TranslatableCaption.of("info.everyone").toComponent(player))
); );
builder.append(MINI_MESSAGE.deserialize(everyone, everyoneResolver)); builder.append(MINI_MESSAGE.deserialize(everyone, everyoneResolver));
@ -517,6 +517,7 @@ public class ListCmd extends SubCommand {
} }
} }
finalResolver.tag("players", Tag.inserting(builder.asComponent())); finalResolver.tag("players", Tag.inserting(builder.asComponent()));
finalResolver.tag("size", Tag.inserting(Component.text(plot.getConnectedPlots().size())));
caption.set(TranslatableCaption.of("info.plot_list_item")); caption.set(TranslatableCaption.of("info.plot_list_item"));
caption.setTagResolvers(finalResolver.build()); caption.setTagResolvers(finalResolver.build());
} }

View File

@ -41,6 +41,7 @@ import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL; import java.net.URL;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -116,7 +117,7 @@ public class Load extends SubCommand {
} }
final URL url; final URL url;
try { try {
url = new URL(Settings.Web.URL + "saves/" + player.getUUID() + '/' + schematic); url = URI.create(Settings.Web.URL + "saves/" + player.getUUID() + '/' + schematic).toURL();
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
e.printStackTrace(); e.printStackTrace();
player.sendMessage(TranslatableCaption.of("web.load_failed")); player.sendMessage(TranslatableCaption.of("web.load_failed"));

View File

@ -183,7 +183,7 @@ public class MainCommand extends Command {
if (cmd.hasConfirmation(player)) { if (cmd.hasConfirmation(player)) {
CmdConfirm.addPending(player, cmd.getUsage(), () -> { CmdConfirm.addPending(player, cmd.getUsage(), () -> {
PlotArea area = player.getApplicablePlotArea(); PlotArea area = player.getApplicablePlotArea();
if (area != null && econHandler.isEnabled(area)) { if (area != null && econHandler.isEnabled(area) && !player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_ECON)) {
PlotExpression priceEval = PlotExpression priceEval =
area.getPrices().get(cmd.getFullId()); area.getPrices().get(cmd.getFullId());
double price = priceEval != null ? priceEval.evaluate(0d) : 0d; double price = priceEval != null ? priceEval.evaluate(0d) : 0d;
@ -201,7 +201,7 @@ public class MainCommand extends Command {
return; return;
} }
PlotArea area = player.getApplicablePlotArea(); PlotArea area = player.getApplicablePlotArea();
if (area != null && econHandler.isEnabled(area)) { if (area != null && econHandler.isEnabled(area) && !player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_ECON)) {
PlotExpression priceEval = area.getPrices().get(cmd.getFullId()); PlotExpression priceEval = area.getPrices().get(cmd.getFullId());
double price = priceEval != null ? priceEval.evaluate(0d) : 0d; double price = priceEval != null ? priceEval.evaluate(0d) : 0d;
if (price != 0d && econHandler.getMoney(player) < price) { if (price != 0d && econHandler.getMoney(player) < price) {

View File

@ -109,7 +109,7 @@ public class Merge extends SubCommand {
} }
} }
if (direction == null && (args[0].equalsIgnoreCase("all") || args[0] if (direction == null && (args[0].equalsIgnoreCase("all") || args[0]
.equalsIgnoreCase("auto"))) { .equalsIgnoreCase("auto")) && player.hasPermission(Permission.PERMISSION_MERGE_ALL)) {
direction = Direction.ALL; direction = Direction.ALL;
} }
} }
@ -178,7 +178,7 @@ public class Merge extends SubCommand {
return true; return true;
} }
if (plot.getPlotModificationManager().autoMerge(Direction.ALL, maxSize, uuid, player, terrain)) { if (plot.getPlotModificationManager().autoMerge(Direction.ALL, maxSize, uuid, player, terrain)) {
if (this.econHandler.isEnabled(plotArea) && price > 0d) { if (this.econHandler.isEnabled(plotArea) && !player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_ECON) && price > 0d) {
this.econHandler.withdrawMoney(player, price); this.econHandler.withdrawMoney(player, price);
player.sendMessage( player.sendMessage(
TranslatableCaption.of("economy.removed_balance"), TranslatableCaption.of("economy.removed_balance"),
@ -196,8 +196,8 @@ public class Merge extends SubCommand {
player.sendMessage(TranslatableCaption.of("merge.no_available_automerge")); player.sendMessage(TranslatableCaption.of("merge.no_available_automerge"));
return false; return false;
} }
if (!force && this.econHandler.isEnabled(plotArea) && price > 0d if (!force && this.econHandler.isEnabled(plotArea) && !player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_ECON) && price > 0d && this.econHandler.getMoney(
&& this.econHandler.getMoney(player) < price) { player) < price) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("economy.cannot_afford_merge"), TranslatableCaption.of("economy.cannot_afford_merge"),
TagResolver.resolver("money", Tag.inserting(Component.text(this.econHandler.format(price)))) TagResolver.resolver("money", Tag.inserting(Component.text(this.econHandler.format(price))))
@ -218,7 +218,7 @@ public class Merge extends SubCommand {
return true; return true;
} }
if (plot.getPlotModificationManager().autoMerge(direction, maxSize - size, uuid, player, terrain)) { if (plot.getPlotModificationManager().autoMerge(direction, maxSize - size, uuid, player, terrain)) {
if (this.econHandler.isEnabled(plotArea) && price > 0d) { if (this.econHandler.isEnabled(plotArea) && !player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_ECON) && price > 0d) {
this.econHandler.withdrawMoney(player, price); this.econHandler.withdrawMoney(player, price);
player.sendMessage( player.sendMessage(
TranslatableCaption.of("economy.removed_balance"), TranslatableCaption.of("economy.removed_balance"),
@ -259,7 +259,7 @@ public class Merge extends SubCommand {
accepter.sendMessage(TranslatableCaption.of("merge.merge_not_valid")); accepter.sendMessage(TranslatableCaption.of("merge.merge_not_valid"));
return; return;
} }
if (this.econHandler.isEnabled(plotArea) && price > 0d) { if (this.econHandler.isEnabled(plotArea) && !player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_ECON) && price > 0d) {
if (!force && this.econHandler.getMoney(player) < price) { if (!force && this.econHandler.getMoney(player) < price) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("economy.cannot_afford_merge"), TranslatableCaption.of("economy.cannot_afford_merge"),
@ -303,7 +303,7 @@ public class Merge extends SubCommand {
player, player,
terrain terrain
)) { )) {
if (this.econHandler.isEnabled(plotArea) && price > 0d) { if (this.econHandler.isEnabled(plotArea) && !player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_ECON) && price > 0d) {
if (!force && this.econHandler.getMoney(player) < price) { if (!force && this.econHandler.getMoney(player) < price) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("economy.cannot_afford_merge"), TranslatableCaption.of("economy.cannot_afford_merge"),

View File

@ -56,7 +56,7 @@ public class Music extends SubCommand {
.asList("music_disc_13", "music_disc_cat", "music_disc_blocks", "music_disc_chirp", .asList("music_disc_13", "music_disc_cat", "music_disc_blocks", "music_disc_chirp",
"music_disc_far", "music_disc_mall", "music_disc_mellohi", "music_disc_stal", "music_disc_far", "music_disc_mall", "music_disc_mellohi", "music_disc_stal",
"music_disc_strad", "music_disc_ward", "music_disc_11", "music_disc_wait", "music_disc_otherside", "music_disc_strad", "music_disc_ward", "music_disc_11", "music_disc_wait", "music_disc_otherside",
"music_disc_pigstep", "music_disc_5" "music_disc_pigstep", "music_disc_5", "music_disc_relic"
); );
private final InventoryUtil inventoryUtil; private final InventoryUtil inventoryUtil;

View File

@ -31,7 +31,6 @@ import com.plotsquared.core.player.PlayerMetaDataKeys;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.EventDispatcher; import com.plotsquared.core.util.EventDispatcher;
import com.plotsquared.core.util.PlayerManager;
import com.plotsquared.core.util.TabCompletions; import com.plotsquared.core.util.TabCompletions;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -136,10 +135,11 @@ public class Owner extends SetCommand {
if (plot.isOwner(uuid)) { if (plot.isOwner(uuid)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("member.already_owner"), TranslatableCaption.of("member.already_owner"),
TagResolver.resolver( PlotSquared.platform().playerManager().getUsernameCaption(uuid)
.thenApply(caption -> TagResolver.resolver(
"player", "player",
Tag.inserting(PlayerManager.resolveName(uuid, false).toComponent(player)) Tag.inserting(caption.toComponent(player))
) ))
); );
return; return;
} }
@ -147,10 +147,11 @@ public class Owner extends SetCommand {
if (other == null) { if (other == null) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("errors.invalid_player_offline"), TranslatableCaption.of("errors.invalid_player_offline"),
TagResolver.resolver( PlotSquared.platform().playerManager().getUsernameCaption(uuid)
.thenApply(caption -> TagResolver.resolver(
"player", "player",
Tag.inserting(PlayerManager.resolveName(uuid).toComponent(player)) Tag.inserting(caption.toComponent(player))
) ))
); );
return; return;
} }

View File

@ -46,7 +46,7 @@ public class PluginCmd extends SubCommand {
player.sendMessage(StaticCaption.of( player.sendMessage(StaticCaption.of(
"<gray>>> </gray><gold><bold>Authors<reset><gray>: </gray><gold>Citymonstret </gold><gray>& </gray><gold>Empire92 </gold><gray>& </gray><gold>MattBDev </gold><gray>& </gray><gold>dordsor21 </gold><gray>& </gray><gold>NotMyFault </gold><gray>& </gray><gold>SirYwell</gold>")); "<gray>>> </gray><gold><bold>Authors<reset><gray>: </gray><gold>Citymonstret </gold><gray>& </gray><gold>Empire92 </gold><gray>& </gray><gold>MattBDev </gold><gray>& </gray><gold>dordsor21 </gold><gray>& </gray><gold>NotMyFault </gold><gray>& </gray><gold>SirYwell</gold>"));
player.sendMessage(StaticCaption.of( player.sendMessage(StaticCaption.of(
"<gray>>> </gray><gold><bold>Wiki<reset><gray>: </gray><gold><click:open_url:https://intellectualsites.github.io/plotsquared-documentation/>https://intellectualsites.github.io/plotsquared-documentation/</gold>")); "<gray>>> </gray><gold><bold>Wiki<reset><gray>: </gray><gold><click:open_url:https://intellectualsites.gitbook.io/plotsquared/>https://intellectualsites.gitbook.io/plotsquared/</gold>"));
player.sendMessage(StaticCaption.of( player.sendMessage(StaticCaption.of(
"<gray>>> </gray><gold><bold>Discord<reset><gray>: </gray><gold><click:open_url:https://discord.gg/intellectualsites>https://discord.gg/intellectualsites</gold>")); "<gray>>> </gray><gold><bold>Discord<reset><gray>: </gray><gold><click:open_url:https://discord.gg/intellectualsites>https://discord.gg/intellectualsites</gold>"));
player.sendMessage( player.sendMessage(

View File

@ -90,12 +90,8 @@ public class Purge extends SubCommand {
return false; return false;
} }
switch (split[0].toLowerCase()) { switch (split[0].toLowerCase()) {
case "world": case "world", "w" -> world = split[1];
case "w": case "area", "a" -> {
world = split[1];
break;
case "area":
case "a":
area = this.plotAreaManager.getPlotAreaByString(split[1]); area = this.plotAreaManager.getPlotAreaByString(split[1]);
if (area == null) { if (area == null) {
player.sendMessage( player.sendMessage(
@ -104,9 +100,8 @@ public class Purge extends SubCommand {
); );
return false; return false;
} }
break; }
case "plotid": case "plotid", "id" -> {
case "id":
try { try {
id = PlotId.fromString(split[1]); id = PlotId.fromString(split[1]);
} catch (IllegalArgumentException ignored) { } catch (IllegalArgumentException ignored) {
@ -116,9 +111,8 @@ public class Purge extends SubCommand {
); );
return false; return false;
} }
break; }
case "owner": case "owner", "o" -> {
case "o":
UUIDMapping ownerMapping = PlotSquared.get().getImpromptuUUIDPipeline().getImmediately(split[1]); UUIDMapping ownerMapping = PlotSquared.get().getImpromptuUUIDPipeline().getImmediately(split[1]);
if (ownerMapping == null) { if (ownerMapping == null) {
player.sendMessage( player.sendMessage(
@ -128,9 +122,8 @@ public class Purge extends SubCommand {
return false; return false;
} }
owner = ownerMapping.uuid(); owner = ownerMapping.uuid();
break; }
case "shared": case "shared", "s" -> {
case "s":
UUIDMapping addedMapping = PlotSquared.get().getImpromptuUUIDPipeline().getImmediately(split[1]); UUIDMapping addedMapping = PlotSquared.get().getImpromptuUUIDPipeline().getImmediately(split[1]);
if (addedMapping == null) { if (addedMapping == null) {
player.sendMessage( player.sendMessage(
@ -140,22 +133,13 @@ public class Purge extends SubCommand {
return false; return false;
} }
added = addedMapping.uuid(); added = addedMapping.uuid();
break; }
case "clear": case "clear", "c", "delete", "d", "del" -> clear = Boolean.parseBoolean(split[1]);
case "c": case "unknown", "?", "u" -> unknown = Boolean.parseBoolean(split[1]);
case "delete": default -> {
case "d":
case "del":
clear = Boolean.parseBoolean(split[1]);
break;
case "unknown":
case "?":
case "u":
unknown = Boolean.parseBoolean(split[1]);
break;
default:
sendUsage(player); sendUsage(player);
return false; return false;
}
} }
} }
final HashSet<Plot> toDelete = new HashSet<>(); final HashSet<Plot> toDelete = new HashSet<>();
@ -236,9 +220,9 @@ public class Purge extends SubCommand {
try { try {
ids.add(plot.temp); ids.add(plot.temp);
if (finalClear) { if (finalClear) {
plot.getPlotModificationManager().clear(false, true, player, () -> { plot.getPlotModificationManager().clear(false, true, player,
LOGGER.info("Plot {} cleared by purge", plot.getId()); () -> LOGGER.info("Plot {} cleared by purge", plot.getId())
}); );
} else { } else {
plot.getPlotModificationManager().removeSign(); plot.getPlotModificationManager().removeSign();
} }

View File

@ -100,15 +100,17 @@ public class Remove extends SubCommand {
count++; count++;
} }
} else if (uuid == DBFunc.EVERYONE) { } else if (uuid == DBFunc.EVERYONE) {
count += plot.getTrusted().size();
if (plot.removeTrusted(uuid)) { if (plot.removeTrusted(uuid)) {
this.eventDispatcher.callTrusted(player, plot, uuid, false); this.eventDispatcher.callTrusted(player, plot, uuid, false);
count++; }
} else if (plot.removeMember(uuid)) { count += plot.getMembers().size();
if (plot.removeMember(uuid)) {
this.eventDispatcher.callMember(player, plot, uuid, false); this.eventDispatcher.callMember(player, plot, uuid, false);
count++; }
} else if (plot.removeDenied(uuid)) { count += plot.getDenied().size();
if (plot.removeDenied(uuid)) {
this.eventDispatcher.callDenied(player, plot, uuid, false); this.eventDispatcher.callDenied(player, plot, uuid, false);
count++;
} }
} }
} }

View File

@ -40,6 +40,7 @@ import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.net.URI;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -130,8 +131,7 @@ public class SchematicCmd extends SubCommand {
if (location.startsWith("url:")) { if (location.startsWith("url:")) {
try { try {
UUID uuid = UUID.fromString(location.substring(4)); UUID uuid = UUID.fromString(location.substring(4));
URL base = new URL(Settings.Web.URL); URL url = URI.create(Settings.Web.URL + "uploads/" + uuid + ".schematic").toURL();
URL url = new URL(base, "uploads/" + uuid + ".schematic");
schematic = this.schematicHandler.getSchematic(url); schematic = this.schematicHandler.getSchematic(url);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -19,6 +19,7 @@
package com.plotsquared.core.command; package com.plotsquared.core.command;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.database.DBFunc; import com.plotsquared.core.database.DBFunc;
@ -103,10 +104,11 @@ public class Trust extends Command {
player.hasPermission(Permission.PERMISSION_TRUST_EVERYONE) || player.hasPermission(Permission.PERMISSION_ADMIN_COMMAND_TRUST))) { player.hasPermission(Permission.PERMISSION_TRUST_EVERYONE) || player.hasPermission(Permission.PERMISSION_ADMIN_COMMAND_TRUST))) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("errors.invalid_player"), TranslatableCaption.of("errors.invalid_player"),
TagResolver.resolver( PlotSquared.platform().playerManager().getUsernameCaption(uuid)
.thenApply(caption -> TagResolver.resolver(
"value", "value",
Tag.inserting(PlayerManager.resolveName(uuid).toComponent(player)) Tag.inserting(caption.toComponent(player))
) ))
); );
iterator.remove(); iterator.remove();
continue; continue;
@ -114,10 +116,11 @@ public class Trust extends Command {
if (currentPlot.isOwner(uuid)) { if (currentPlot.isOwner(uuid)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("member.already_added"), TranslatableCaption.of("member.already_added"),
TagResolver.resolver( PlotSquared.platform().playerManager().getUsernameCaption(uuid)
"value", .thenApply(caption -> TagResolver.resolver(
Tag.inserting(PlayerManager.resolveName(uuid).toComponent(player)) "player",
) Tag.inserting(caption.toComponent(player))
))
); );
iterator.remove(); iterator.remove();
continue; continue;
@ -125,10 +128,11 @@ public class Trust extends Command {
if (currentPlot.getTrusted().contains(uuid)) { if (currentPlot.getTrusted().contains(uuid)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("member.already_added"), TranslatableCaption.of("member.already_added"),
TagResolver.resolver( PlotSquared.platform().playerManager().getUsernameCaption(uuid)
"value", .thenApply(caption -> TagResolver.resolver(
Tag.inserting(PlayerManager.resolveName(uuid).toComponent(player)) "player",
) Tag.inserting(caption.toComponent(player))
))
); );
iterator.remove(); iterator.remove();
continue; continue;

View File

@ -49,7 +49,8 @@ public record ComponentPreset(
public static ComponentPreset deserialize(final @NonNull Map<String, Object> map) { public static ComponentPreset deserialize(final @NonNull Map<String, Object> map) {
final ClassicPlotManagerComponent classicPlotManagerComponent = ClassicPlotManagerComponent final ClassicPlotManagerComponent classicPlotManagerComponent = ClassicPlotManagerComponent
.fromString(map.getOrDefault("component", "").toString()).orElseThrow(() -> .fromString(map.getOrDefault("component", "").toString()).orElseThrow(() ->
new IllegalArgumentException("The preset in components.yml needs a valid target component, got: " + map.get("component"))); new IllegalArgumentException("The preset in components.yml needs a valid target component, got: " + map.get(
"component")));
final String pattern = map.getOrDefault("pattern", "").toString(); final String pattern = map.getOrDefault("pattern", "").toString();
final double cost = Double.parseDouble(map.getOrDefault("cost", "0.0").toString()); final double cost = Double.parseDouble(map.getOrDefault("cost", "0.0").toString());
final String permission = map.getOrDefault("permission", "").toString(); final String permission = map.getOrDefault("permission", "").toString();

View File

@ -206,7 +206,7 @@ public class ComponentPresetManager {
return false; return false;
} }
if (componentPreset.cost() > 0.0D) { if (componentPreset.cost() > 0.0D && !player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_ECON)) {
if (!econHandler.isEnabled(plot.getArea())) { if (!econHandler.isEnabled(plot.getArea())) {
getPlayer().sendMessage( getPlayer().sendMessage(
TranslatableCaption.of("preset.economy_disabled"), TranslatableCaption.of("preset.economy_disabled"),

View File

@ -42,32 +42,6 @@ public class Config {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + Config.class.getSimpleName()); private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + Config.class.getSimpleName());
/**
* Get the value for a node<br>
* Probably throws some error if you try to get a non existent key
*
* @param key configuration key
* @param root configuration class
* @param <T> value type
* @return value
*/
@SuppressWarnings("unchecked")
public static <T> T get(String key, Class<?> root) {
String[] split = key.split("\\.");
Object instance = getInstance(split, root);
if (instance != null) {
Field field = getField(split, instance);
if (field != null) {
try {
return (T) field.get(instance);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
return null;
}
/** /**
* Set the value of a specific node<br> * Set the value of a specific node<br>
* Probably throws some error if you supply non existing keys or invalid values * Probably throws some error if you supply non existing keys or invalid values
@ -259,7 +233,6 @@ public class Config {
* *
* @param split the node (split by period) * @param split the node (split by period)
* @param instance the instance * @param instance the instance
* @return
*/ */
private static Field getField(String[] split, Object instance) { private static Field getField(String[] split, Object instance) {
try { try {
@ -445,10 +418,6 @@ public class Config {
return INSTANCES.values(); return INSTANCES.values();
} }
public Collection<String> getSections() {
return INSTANCES.keySet();
}
private Map<String, T> getRaw() { private Map<String, T> getRaw() {
return INSTANCES; return INSTANCES;
} }

View File

@ -194,7 +194,7 @@ public class Settings extends Config {
public List<String> WORLDS = new ArrayList<>(Collections.singletonList("*")); public List<String> WORLDS = new ArrayList<>(Collections.singletonList("*"));
@Comment("See: https://intellectualsites.github.io/plotsquared-documentation/optimization/plot-analysis for a description of each value.") @Comment("See: https://intellectualsites.gitbook.io/plotsquared/optimization/plot-analysis for a description of each value.")
public static final class CALIBRATION { public static final class CALIBRATION {
public int VARIETY = 0; public int VARIETY = 0;
@ -214,7 +214,7 @@ public class Settings extends Config {
@Comment({"Chunk processor related settings", @Comment({"Chunk processor related settings",
"See https://intellectualsites.github.io/plotsquared-documentation/optimization/chunk-processor for more information."}) "See https://intellectualsites.gitbook.io/plotsquared/optimization/chunk-processor for more information."})
public static class Chunk_Processor { public static class Chunk_Processor {
@Comment("Auto trim will not save chunks which aren't claimed") @Comment("Auto trim will not save chunks which aren't claimed")
@ -280,7 +280,7 @@ public class Settings extends Config {
@Comment("Always show explosion Particles, even if explosion flag is set to false") @Comment("Always show explosion Particles, even if explosion flag is set to false")
public static boolean ALWAYS_SHOW_EXPLOSIONS = false; public static boolean ALWAYS_SHOW_EXPLOSIONS = false;
@Comment({"Blocks that may not be used in plot components", @Comment({"Blocks that may not be used in plot components",
"Checkout the wiki article regarding plot components before modifying: https://intellectualsites.github.io/plotsquared-documentation/customization/plot-components"}) "Checkout the wiki article regarding plot components before modifying: https://intellectualsites.gitbook.io/plotsquared/customization/plot-components"})
public static List<String> public static List<String>
INVALID_BLOCKS = Arrays.asList( INVALID_BLOCKS = Arrays.asList(
// Acacia Stuff // Acacia Stuff
@ -402,7 +402,7 @@ public class Settings extends Config {
@Comment({"Schematic Settings", @Comment({"Schematic Settings",
"See https://intellectualsites.github.io/plotsquared-documentation/schematics/schematic-on-claim for more information."}) "See https://intellectualsites.gitbook.io/plotsquared/schematics/schematic-on-claim for more information."})
public static final class Schematics { public static final class Schematics {
@Comment( @Comment(
@ -522,7 +522,7 @@ public class Settings extends Config {
@Comment("Should the limit be global (over multiple worlds)") @Comment("Should the limit be global (over multiple worlds)")
public static boolean GLOBAL = public static boolean GLOBAL =
false; false;
@Comment({"The max range of permissions to check for, e.g. plots.plot.127", @Comment({"The max range of integer permissions to check for, e.g. 'plots.plot.127' or 'plots.set.flag.mob-cap.127'",
"The value covers the permission range to check, you need to assign the permission to players/groups still", "The value covers the permission range to check, you need to assign the permission to players/groups still",
"Modifying the value does NOT change the amount of plots players can claim"}) "Modifying the value does NOT change the amount of plots players can claim"})
public static int MAX_PLOTS = 127; public static int MAX_PLOTS = 127;
@ -531,7 +531,7 @@ public class Settings extends Config {
@Comment({"Backup related settings", @Comment({"Backup related settings",
"See https://intellectualsites.github.io/plotsquared-documentation/plot-backups for more information."}) "See https://intellectualsites.gitbook.io/plotsquared/plot-backups for more information."})
public static final class Backup { public static final class Backup {
@Comment("Automatically backup plots when destructive commands are performed, e.g. /plot clear") @Comment("Automatically backup plots when destructive commands are performed, e.g. /plot clear")
@ -783,7 +783,7 @@ public class Settings extends Config {
public static boolean public static boolean
PERSISTENT_ROAD_REGEN = true; PERSISTENT_ROAD_REGEN = true;
@Comment({"Enable the `/plot component` preset GUI", @Comment({"Enable the `/plot component` preset GUI",
"Read more about components here: https://intellectualsites.github.io/plotsquared-documentation/customization/plot-components"}) "Read more about components here: https://intellectualsites.gitbook.io/plotsquared/customization/plot-components"})
public static boolean COMPONENT_PRESETS = true; public static boolean COMPONENT_PRESETS = true;
@Comment("Enable per user locale") @Comment("Enable per user locale")
public static boolean PER_USER_LOCALE = false; public static boolean PER_USER_LOCALE = false;

View File

@ -40,8 +40,10 @@ public interface Caption {
* *
* @param localeHolder Locale holder * @param localeHolder Locale holder
* @return {@link ComponentLike} * @return {@link ComponentLike}
* @since TODO * @since 7.0.0
*/ */
@NonNull Component toComponent(@NonNull LocaleHolder localeHolder); @NonNull Component toComponent(@NonNull LocaleHolder localeHolder);
@NonNull String toString();
} }

View File

@ -51,7 +51,7 @@ public class CaptionHolder {
* Get the {@link TagResolver}s to use when resolving tags in the {@link Caption}. * Get the {@link TagResolver}s to use when resolving tags in the {@link Caption}.
* *
* @return The tag resolvers to use. * @return The tag resolvers to use.
* @since TODO * @since 7.0.0
*/ */
public TagResolver[] getTagResolvers() { public TagResolver[] getTagResolvers() {
return this.tagResolvers; return this.tagResolvers;
@ -61,7 +61,7 @@ public class CaptionHolder {
* Set the {@link TagResolver}s to use when resolving tags in the {@link Caption}. * Set the {@link TagResolver}s to use when resolving tags in the {@link Caption}.
* *
* @param tagResolvers The tag resolvers to use. * @param tagResolvers The tag resolvers to use.
* @since TODO * @since 7.0.0
*/ */
public void setTagResolvers(TagResolver... tagResolvers) { public void setTagResolvers(TagResolver... tagResolvers) {
this.tagResolvers = tagResolvers; this.tagResolvers = tagResolvers;

View File

@ -28,16 +28,20 @@ import com.plotsquared.core.plot.flag.implementations.PlotTitleFlag;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.ParsingException;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern;
import static com.plotsquared.core.configuration.caption.ComponentTransform.nested; import static com.plotsquared.core.configuration.caption.ComponentTransform.nested;
import static com.plotsquared.core.configuration.caption.ComponentTransform.stripClicks; import static com.plotsquared.core.configuration.caption.ComponentTransform.stripClicks;
public class CaptionUtility { public class CaptionUtility {
private static final Pattern LEGACY_FORMATTING = Pattern.compile("§[a-gklmnor0-9]");
// flags which values are parsed by minimessage // flags which values are parsed by minimessage
private static final Set<Class<? extends PlotFlag<?, ?>>> MINI_MESSAGE_FLAGS = Set.of( private static final Set<Class<? extends PlotFlag<?, ?>>> MINI_MESSAGE_FLAGS = Set.of(
GreetingFlag.class, GreetingFlag.class,
@ -100,7 +104,14 @@ public class CaptionUtility {
*/ */
public static String stripClickEvents(final @NonNull String miniMessageString) { public static String stripClickEvents(final @NonNull String miniMessageString) {
// parse, transform and serialize again // parse, transform and serialize again
Component component = MiniMessage.miniMessage().deserialize(miniMessageString); Component component;
try {
component = MiniMessage.miniMessage().deserialize(miniMessageString);
} catch (ParsingException e) {
// if the String cannot be parsed, we try stripping legacy colors
String legacyStripped = LEGACY_FORMATTING.matcher(miniMessageString).replaceAll("");
component = MiniMessage.miniMessage().deserialize(legacyStripped);
}
component = CLICK_STRIP_TRANSFORM.transform(component); component = CLICK_STRIP_TRANSFORM.transform(component);
return MiniMessage.miniMessage().serialize(component); return MiniMessage.miniMessage().serialize(component);
} }

View File

@ -51,4 +51,9 @@ public final class StaticCaption implements Caption {
return MiniMessage.miniMessage().deserialize(this.value); return MiniMessage.miniMessage().deserialize(this.value);
} }
@Override
public @NonNull String toString() {
return "StaticCaption(" + value + ")";
}
} }

View File

@ -25,6 +25,7 @@ import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.jetbrains.annotations.NotNull;
import java.util.Locale; import java.util.Locale;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -132,4 +133,9 @@ public final class TranslatableCaption implements NamespacedCaption {
return Objects.hashCode(this.getNamespace(), this.getKey()); return Objects.hashCode(this.getNamespace(), this.getKey());
} }
@Override
public @NotNull String toString() {
return "TranslatableCaption(" + getNamespace() + ":" + getKey() + ")";
}
} }

View File

@ -225,7 +225,7 @@ public final class CaptionLoader {
*/ */
public @NonNull CaptionMap loadOrCreateSingle(final @NonNull Path file) throws IOException { public @NonNull CaptionMap loadOrCreateSingle(final @NonNull Path file) throws IOException {
final Locale locale = this.localeExtractor.apply(file); final Locale locale = this.localeExtractor.apply(file);
if (!Files.exists(file) ) { if (!Files.exists(file)) {
Map<String, String> map = new LinkedHashMap<>(); Map<String, String> map = new LinkedHashMap<>();
patch(map, locale); patch(map, locale);
save(file, map); save(file, map);

View File

@ -56,7 +56,8 @@ final class ClassLoaderCaptionProvider implements DefaultCaptionProvider {
LOGGER.info("No resource for locale '{}' found in the plugin file." + LOGGER.info("No resource for locale '{}' found in the plugin file." +
"Please ensure you have placed the latest version of the file messages_{}.json in the 'lang' folder." + "Please ensure you have placed the latest version of the file messages_{}.json in the 'lang' folder." +
"You may be able to find completed translations at https://intellectualsites.crowdin.com/plotsquared", "You may be able to find completed translations at https://intellectualsites.crowdin.com/plotsquared",
locale, locale); locale, locale
);
return null; return null;
} }
try (final BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) { try (final BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {

View File

@ -19,6 +19,7 @@
package com.plotsquared.core.configuration.file; package com.plotsquared.core.configuration.file;
import com.plotsquared.core.configuration.serialization.ConfigurationSerialization; import com.plotsquared.core.configuration.serialization.ConfigurationSerialization;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.constructor.SafeConstructor; import org.yaml.snakeyaml.constructor.SafeConstructor;
import org.yaml.snakeyaml.error.YAMLException; import org.yaml.snakeyaml.error.YAMLException;
import org.yaml.snakeyaml.nodes.Node; import org.yaml.snakeyaml.nodes.Node;
@ -30,6 +31,7 @@ import java.util.Map;
public class YamlConstructor extends SafeConstructor { public class YamlConstructor extends SafeConstructor {
YamlConstructor() { YamlConstructor() {
super(new LoaderOptions());
yamlConstructors.put(Tag.MAP, new ConstructCustomObject()); yamlConstructors.put(Tag.MAP, new ConstructCustomObject());
} }

View File

@ -21,6 +21,7 @@ package com.plotsquared.core.configuration.file;
import com.plotsquared.core.configuration.ConfigurationSection; import com.plotsquared.core.configuration.ConfigurationSection;
import com.plotsquared.core.configuration.serialization.ConfigurationSerializable; import com.plotsquared.core.configuration.serialization.ConfigurationSerializable;
import com.plotsquared.core.configuration.serialization.ConfigurationSerialization; import com.plotsquared.core.configuration.serialization.ConfigurationSerialization;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.nodes.Node; import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.representer.Representer; import org.yaml.snakeyaml.representer.Representer;
@ -30,6 +31,7 @@ import java.util.Map;
class YamlRepresenter extends Representer { class YamlRepresenter extends Representer {
YamlRepresenter() { YamlRepresenter() {
super(new DumperOptions());
this.multiRepresenters.put(ConfigurationSection.class, new RepresentConfigurationSection()); this.multiRepresenters.put(ConfigurationSection.class, new RepresentConfigurationSection());
this.multiRepresenters this.multiRepresenters
.put(ConfigurationSerializable.class, new RepresentConfigurationSerializable()); .put(ConfigurationSerializable.class, new RepresentConfigurationSerializable());

View File

@ -130,6 +130,7 @@ public class SQLManager implements AbstractDB {
public volatile ConcurrentHashMap<PlotCluster, Queue<UniqueStatement>> clusterTasks; public volatile ConcurrentHashMap<PlotCluster, Queue<UniqueStatement>> clusterTasks;
// Private // Private
private Connection connection; private Connection connection;
private boolean supportsGetGeneratedKeys;
private boolean closed = false; private boolean closed = false;
/** /**
@ -154,6 +155,8 @@ public class SQLManager implements AbstractDB {
this.worldConfiguration = worldConfiguration; this.worldConfiguration = worldConfiguration;
this.database = database; this.database = database;
this.connection = database.openConnection(); this.connection = database.openConnection();
final DatabaseMetaData databaseMetaData = this.connection.getMetaData();
this.supportsGetGeneratedKeys = databaseMetaData.supportsGetGeneratedKeys();
this.mySQL = database instanceof MySQL; this.mySQL = database instanceof MySQL;
this.globalTasks = new ConcurrentLinkedQueue<>(); this.globalTasks = new ConcurrentLinkedQueue<>();
this.notifyTasks = new ConcurrentLinkedQueue<>(); this.notifyTasks = new ConcurrentLinkedQueue<>();
@ -161,6 +164,14 @@ public class SQLManager implements AbstractDB {
this.playerTasks = new ConcurrentHashMap<>(); this.playerTasks = new ConcurrentHashMap<>();
this.clusterTasks = new ConcurrentHashMap<>(); this.clusterTasks = new ConcurrentHashMap<>();
this.prefix = prefix; this.prefix = prefix;
if (mySQL && !supportsGetGeneratedKeys) {
String driver = databaseMetaData.getDriverName();
String driverVersion = databaseMetaData.getDriverVersion();
throw new SQLException("Database Driver for MySQL does not support Statement#getGeneratedKeys - which breaks " +
"PlotSquared functionality (Using " + driver + ":" + driverVersion + ")");
}
this.SET_OWNER = "UPDATE `" + this.prefix this.SET_OWNER = "UPDATE `" + this.prefix
+ "plot` SET `owner` = ? WHERE `plot_id_x` = ? AND `plot_id_z` = ? AND `world` = ?"; + "plot` SET `owner` = ? WHERE `plot_id_x` = ? AND `plot_id_z` = ? AND `world` = ?";
this.GET_ALL_PLOTS = this.GET_ALL_PLOTS =
@ -171,20 +182,32 @@ public class SQLManager implements AbstractDB {
"INSERT INTO `" + this.prefix + "plot_settings` (`plot_plot_id`) values "; "INSERT INTO `" + this.prefix + "plot_settings` (`plot_plot_id`) values ";
this.CREATE_TIERS = this.CREATE_TIERS =
"INSERT INTO `" + this.prefix + "plot_%tier%` (`plot_plot_id`, `user_uuid`) values "; "INSERT INTO `" + this.prefix + "plot_%tier%` (`plot_plot_id`, `user_uuid`) values ";
this.CREATE_PLOT = "INSERT INTO `" + this.prefix String tempCreatePlot = "INSERT INTO `" + this.prefix
+ "plot`(`plot_id_x`, `plot_id_z`, `owner`, `world`, `timestamp`) VALUES(?, ?, ?, ?, ?)"; + "plot`(`plot_id_x`, `plot_id_z`, `owner`, `world`, `timestamp`) VALUES(?, ?, ?, ?, ?)";
if (!supportsGetGeneratedKeys) {
tempCreatePlot += " RETURNING `id`";
}
this.CREATE_PLOT = tempCreatePlot;
if (mySQL) { if (mySQL) {
this.CREATE_PLOT_SAFE = "INSERT IGNORE INTO `" + this.prefix this.CREATE_PLOT_SAFE = "INSERT IGNORE INTO `" + this.prefix
+ "plot`(`plot_id_x`, `plot_id_z`, `owner`, `world`, `timestamp`) SELECT ?, ?, ?, ?, ? FROM DUAL WHERE NOT EXISTS (SELECT null FROM `" + "plot`(`plot_id_x`, `plot_id_z`, `owner`, `world`, `timestamp`) SELECT ?, ?, ?, ?, ? FROM DUAL WHERE NOT EXISTS (SELECT null FROM `"
+ this.prefix + "plot` WHERE `world` = ? AND `plot_id_x` = ? AND `plot_id_z` = ?)"; + this.prefix + "plot` WHERE `world` = ? AND `plot_id_x` = ? AND `plot_id_z` = ?)";
} else { } else {
this.CREATE_PLOT_SAFE = "INSERT INTO `" + this.prefix String tempCreatePlotSafe = "INSERT INTO `" + this.prefix
+ "plot`(`plot_id_x`, `plot_id_z`, `owner`, `world`, `timestamp`) SELECT ?, ?, ?, ?, ? WHERE NOT EXISTS (SELECT null FROM `" + "plot`(`plot_id_x`, `plot_id_z`, `owner`, `world`, `timestamp`) SELECT ?, ?, ?, ?, ? WHERE NOT EXISTS (SELECT null FROM `"
+ this.prefix + "plot` WHERE `world` = ? AND `plot_id_x` = ? AND `plot_id_z` = ?)"; + this.prefix + "plot` WHERE `world` = ? AND `plot_id_x` = ? AND `plot_id_z` = ?)";
if (!supportsGetGeneratedKeys) {
tempCreatePlotSafe += " RETURNING `id`";
}
this.CREATE_PLOT_SAFE = tempCreatePlotSafe;
} }
this.CREATE_CLUSTER = "INSERT INTO `" + this.prefix String tempCreateCluster = "INSERT INTO `" + this.prefix
+ "cluster`(`pos1_x`, `pos1_z`, `pos2_x`, `pos2_z`, `owner`, `world`) VALUES(?, ?, ?, ?, ?, ?)"; + "cluster`(`pos1_x`, `pos1_z`, `pos2_x`, `pos2_z`, `owner`, `world`) VALUES(?, ?, ?, ?, ?, ?)";
if (!supportsGetGeneratedKeys) {
tempCreateCluster += " RETURNING `id`";
}
this.CREATE_CLUSTER = tempCreateCluster;
try { try {
createTables(); createTables();
} catch (SQLException e) { } catch (SQLException e) {
@ -1073,9 +1096,8 @@ public class SQLManager implements AbstractDB {
@Override @Override
public void addBatch(PreparedStatement statement) throws SQLException { public void addBatch(PreparedStatement statement) throws SQLException {
int inserted = statement.executeUpdate(); if (statement.execute() || statement.getUpdateCount() > 0) {
if (inserted > 0) { try (ResultSet keys = supportsGetGeneratedKeys ? statement.getGeneratedKeys() : statement.getResultSet()) {
try (ResultSet keys = statement.getGeneratedKeys()) {
if (keys.next()) { if (keys.next()) {
plot.temp = keys.getInt(1); plot.temp = keys.getInt(1);
addPlotTask(plot, new UniqueStatement( addPlotTask(plot, new UniqueStatement(
@ -1145,8 +1167,8 @@ public class SQLManager implements AbstractDB {
@Override @Override
public void addBatch(PreparedStatement statement) throws SQLException { public void addBatch(PreparedStatement statement) throws SQLException {
statement.executeUpdate(); statement.execute();
try (ResultSet keys = statement.getGeneratedKeys()) { try (ResultSet keys = supportsGetGeneratedKeys ? statement.getGeneratedKeys() : statement.getResultSet()) {
if (keys.next()) { if (keys.next()) {
plot.temp = keys.getInt(1); plot.temp = keys.getInt(1);
} }
@ -2379,7 +2401,8 @@ public class SQLManager implements AbstractDB {
addPlotTask(plot, new UniqueStatement("setPosition") { addPlotTask(plot, new UniqueStatement("setPosition") {
@Override @Override
public void set(PreparedStatement statement) throws SQLException { public void set(PreparedStatement statement) throws SQLException {
statement.setString(1, position == null ? "" : position); // Please see the table creation statement. There is the default value of "default"
statement.setString(1, position == null ? "DEFAULT" : position);
statement.setInt(2, getId(plot)); statement.setInt(2, getId(plot));
} }
@ -3058,8 +3081,8 @@ public class SQLManager implements AbstractDB {
@Override @Override
public void addBatch(PreparedStatement statement) throws SQLException { public void addBatch(PreparedStatement statement) throws SQLException {
statement.executeUpdate(); statement.execute();
try (ResultSet keys = statement.getGeneratedKeys()) { try (ResultSet keys = supportsGetGeneratedKeys ? statement.getGeneratedKeys() : statement.getResultSet()) {
if (keys.next()) { if (keys.next()) {
cluster.temp = keys.getInt(1); cluster.temp = keys.getInt(1);
} }

View File

@ -18,17 +18,34 @@
*/ */
package com.plotsquared.core.events; package com.plotsquared.core.events;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* PlotSquared event with {@link Result} to cancel, force, or allow. * PlotSquared event with {@link Result} to cancel, force, or allow.
*/ */
public interface CancellablePlotEvent { public interface CancellablePlotEvent {
Result getEventResult(); /**
* The currently set {@link Result} for this event (as set by potential previous event listeners).
*
* @return the current result.
*/
@Nullable Result getEventResult();
void setEventResult(Result eventResult); /**
* Set the {@link Result} for this event.
*
* @param eventResult the new result.
*/
void setEventResult(@Nullable Result eventResult);
/**
* @deprecated No usage and not null-safe
*/
@Deprecated(since = "7.3.2")
default int getEventResultRaw() { default int getEventResultRaw() {
return getEventResult().getValue(); return getEventResult() != null ? getEventResult().getValue() : -1;
} }
} }

View File

@ -22,7 +22,7 @@ import com.sk89q.worldedit.entity.Entity;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
/** /**
* @since TODO * @since 6.11.1
*/ */
public abstract class EntityEvent { public abstract class EntityEvent {
@ -53,7 +53,8 @@ public abstract class EntityEvent {
* @return the event class name * @return the event class name
* @since 6.11.0 * @since 6.11.0
*/ */
@NonNull public String getEventName() { @NonNull
public String getEventName() {
if (this.name == null) { if (this.name == null) {
this.name = this.getClass().getSimpleName(); this.name = this.getClass().getSimpleName();
} }

View File

@ -0,0 +1,88 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.events;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import org.checkerframework.checker.index.qual.NonNegative;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Called when a user attempts to buy a plot.
* <p>
* Setting the {@link #setEventResult(Result) Result} to {@link Result#FORCE} ignores the price and players account balance and does not charge the
* player anything. {@link Result#DENY} blocks the purchase completely, {@link Result#ACCEPT} and {@code null} do not modify
* the behaviour.
* <p>
* Setting the {@link #setPrice(double) price} to {@code 0} makes the plot practically free.
*
* @since 7.3.2
*/
public class PlayerBuyPlotEvent extends PlotPlayerEvent implements CancellablePlotEvent {
private Result result;
private double price;
public PlayerBuyPlotEvent(final PlotPlayer<?> plotPlayer, final Plot plot, @NonNegative final double price) {
super(plotPlayer, plot);
this.price = price;
}
/**
* Sets the price required to buy the plot.
*
* @param price the new price.
* @since 7.3.2
*/
public void setPrice(@NonNegative final double price) {
//noinspection ConstantValue - the annotation does not ensure a non-negative runtime value
if (price < 0) {
throw new IllegalArgumentException("price must be non-negative");
}
this.price = price;
}
/**
* Returns the currently set price required to buy the plot.
*
* @return the price.
* @since 7.3.2
*/
public @NonNegative double price() {
return price;
}
/**
* {@inheritDoc}
*/
@Override
public void setEventResult(@Nullable final Result eventResult) {
this.result = eventResult;
}
/**
* {@inheritDoc}
*/
@Override
public @Nullable Result getEventResult() {
return this.result;
}
}

View File

@ -0,0 +1,77 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.events;
import com.plotsquared.core.player.PlotPlayer;
import org.checkerframework.checker.index.qual.NonNegative;
import org.checkerframework.checker.nullness.qual.NonNull;
/**
* Called every time after PlotSquared calculated a players plot limit based on their permission.
* <p>
* May be used to grant a player more plots based on another rank or bought feature.
*
* @since 7.3.0
*/
public class PlayerPlotLimitEvent {
private final PlotPlayer<?> player;
private int limit;
public PlayerPlotLimitEvent(@NonNull final PlotPlayer<?> player, @NonNegative final int limit) {
this.player = player;
this.limit = limit;
}
/**
* Overrides the previously calculated or set plot limit for {@link #player()}.
*
* @param limit The amount of plots a player may claim. Must be {@code 0} or greater.
* @since 7.3.0
*/
public void limit(@NonNegative final int limit) {
if (limit < 0) {
throw new IllegalArgumentException("Player plot limit must be greater or equal 0");
}
this.limit = limit;
}
/**
* Returns the previous set limit, if none was overridden before this event handler the default limit based on the players
* permissions node is returned.
*
* @return The currently defined plot limit of this player.
* @since 7.3.0
*/
public @NonNegative int limit() {
return limit;
}
/**
* The player for which the limit is queried.
*
* @return the player.
* @since 7.3.0
*/
public @NonNull PlotPlayer<?> player() {
return player;
}
}

View File

@ -21,21 +21,26 @@ package com.plotsquared.core.events;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.function.UnaryOperator;
/** /**
* Called when a player teleports to a plot * Called when a player teleports to a plot
*/ */
public class PlayerTeleportToPlotEvent extends PlotPlayerEvent implements CancellablePlotEvent { public class PlayerTeleportToPlotEvent extends PlotPlayerEvent implements CancellablePlotEvent {
private final Location from;
private final TeleportCause cause; private final TeleportCause cause;
private Result eventResult; private Result eventResult;
private final Location from;
private UnaryOperator<Location> locationTransformer;
/** /**
* PlayerTeleportToPlotEvent: Called when a player teleports to a plot * PlayerTeleportToPlotEvent: Called when a player teleports to a plot
* *
* @param player That was teleported * @param player That was teleported
* @param from Start location * @param from The origin location, from where the teleport was triggered (players location most likely)
* @param plot Plot to which the player was teleported * @param plot Plot to which the player was teleported
* @param cause Why the teleport is being completed * @param cause Why the teleport is being completed
* @since 6.1.0 * @since 6.1.0
@ -57,7 +62,8 @@ public class PlayerTeleportToPlotEvent extends PlotPlayerEvent implements Cancel
} }
/** /**
* Get the from location * Get the location, from where the teleport was triggered
* (the players current location when executing the home command for example)
* *
* @return Location * @return Location
*/ */
@ -65,6 +71,27 @@ public class PlayerTeleportToPlotEvent extends PlotPlayerEvent implements Cancel
return this.from; return this.from;
} }
/**
* Gets the currently applied {@link UnaryOperator<Location> transformer} or null, if none was set
*
* @return LocationTransformer
* @since 7.2.1
*/
public @Nullable UnaryOperator<Location> getLocationTransformer() {
return this.locationTransformer;
}
/**
* Sets the {@link UnaryOperator<Location> transformer} to mutate the location where the player will be teleported to.
* May be {@code null}, if any previous set transformations should be discarded.
*
* @param locationTransformer The new transformer
* @since 7.2.1
*/
public void setLocationTransformer(@Nullable UnaryOperator<Location> locationTransformer) {
this.locationTransformer = locationTransformer;
}
@Override @Override
public Result getEventResult() { public Result getEventResult() {
return eventResult; return eventResult;

View File

@ -0,0 +1,64 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.events.post;
import com.plotsquared.core.events.PlotPlayerEvent;
import com.plotsquared.core.player.OfflinePlotPlayer;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import org.checkerframework.checker.index.qual.NonNegative;
/**
* Called after a player has successfully bought a plot.
*
* @since 7.3.2
*/
public class PostPlayerBuyPlotEvent extends PlotPlayerEvent {
private final OfflinePlotPlayer previousOwner;
private final double price;
public PostPlayerBuyPlotEvent(
final PlotPlayer<?> plotPlayer, final OfflinePlotPlayer previousOwner, final Plot plot,
@NonNegative final double price
) {
super(plotPlayer, plot);
this.previousOwner = previousOwner;
this.price = price;
}
/**
* The previous owner of the bought plot.
*
* @return the previous owner.
*/
public OfflinePlotPlayer previousOwner() {
return previousOwner;
}
/**
* Returns the price after potential modifications by {@link com.plotsquared.core.events.PlayerBuyPlotEvent}.
*
* @return the price the player had to pay to buy the plot.
*/
public double price() {
return price;
}
}

View File

@ -0,0 +1,43 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.events.post;
import com.plotsquared.core.events.PlotPlayerEvent;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
/**
* Called after a {@link Plot} was cleared.
*
* @since 7.3.2
*/
public class PostPlotClearEvent extends PlotPlayerEvent {
/**
* Instantiate a new PostPlotClearEvent.
*
* @param plotPlayer The {@link PlotPlayer} that initiated the clear.
* @param plot The clearing plot.
*/
public PostPlotClearEvent(final PlotPlayer<?> plotPlayer, final Plot plot) {
super(plotPlayer, plot);
}
}

View File

@ -143,7 +143,7 @@ public class ClassicPlotManager extends SquarePlotManager {
classicPlotWorld, classicPlotWorld,
plot.getRegions(), plot.getRegions(),
blocks, blocks,
classicPlotWorld.getMinBuildHeight(), classicPlotWorld.getMinComponentHeight(),
classicPlotWorld.getMaxBuildHeight() - 1, classicPlotWorld.getMaxBuildHeight() - 1,
actor, actor,
queue queue
@ -204,7 +204,7 @@ public class ClassicPlotManager extends SquarePlotManager {
classicPlotWorld, classicPlotWorld,
plot.getRegions(), plot.getRegions(),
blocks, blocks,
classicPlotWorld.getMinBuildHeight(), classicPlotWorld.getMinComponentHeight(),
classicPlotWorld.PLOT_HEIGHT - 1, classicPlotWorld.PLOT_HEIGHT - 1,
actor, actor,
queue queue
@ -379,10 +379,11 @@ public class ClassicPlotManager extends SquarePlotManager {
} }
} }
int yStart = classicPlotWorld.getMinComponentHeight();
if (!plot.isMerged(Direction.NORTH)) { if (!plot.isMerged(Direction.NORTH)) {
int z = bot.getZ(); int z = bot.getZ();
for (int x = bot.getX(); x < top.getX(); x++) { for (int x = bot.getX(); x < top.getX(); x++) {
for (int y = classicPlotWorld.getMinBuildHeight(); y <= classicPlotWorld.WALL_HEIGHT; y++) { for (int y = yStart; y <= classicPlotWorld.WALL_HEIGHT; y++) {
queue.setBlock(x, y, z, blocks); queue.setBlock(x, y, z, blocks);
} }
} }
@ -390,7 +391,7 @@ public class ClassicPlotManager extends SquarePlotManager {
if (!plot.isMerged(Direction.WEST)) { if (!plot.isMerged(Direction.WEST)) {
int x = bot.getX(); int x = bot.getX();
for (int z = bot.getZ(); z < top.getZ(); z++) { for (int z = bot.getZ(); z < top.getZ(); z++) {
for (int y = classicPlotWorld.getMinBuildHeight(); y <= classicPlotWorld.WALL_HEIGHT; y++) { for (int y = yStart; y <= classicPlotWorld.WALL_HEIGHT; y++) {
queue.setBlock(x, y, z, blocks); queue.setBlock(x, y, z, blocks);
} }
} }
@ -398,7 +399,7 @@ public class ClassicPlotManager extends SquarePlotManager {
if (!plot.isMerged(Direction.SOUTH)) { if (!plot.isMerged(Direction.SOUTH)) {
int z = top.getZ(); int z = top.getZ();
for (int x = bot.getX(); x < top.getX() + (plot.isMerged(Direction.EAST) ? 0 : 1); x++) { for (int x = bot.getX(); x < top.getX() + (plot.isMerged(Direction.EAST) ? 0 : 1); x++) {
for (int y = classicPlotWorld.getMinBuildHeight(); y <= classicPlotWorld.WALL_HEIGHT; y++) { for (int y = yStart; y <= classicPlotWorld.WALL_HEIGHT; y++) {
queue.setBlock(x, y, z, blocks); queue.setBlock(x, y, z, blocks);
} }
} }
@ -406,7 +407,7 @@ public class ClassicPlotManager extends SquarePlotManager {
if (!plot.isMerged(Direction.EAST)) { if (!plot.isMerged(Direction.EAST)) {
int x = top.getX(); int x = top.getX();
for (int z = bot.getZ(); z < top.getZ() + (plot.isMerged(Direction.SOUTH) ? 0 : 1); z++) { for (int z = bot.getZ(); z < top.getZ() + (plot.isMerged(Direction.SOUTH) ? 0 : 1); z++) {
for (int y = classicPlotWorld.getMinBuildHeight(); y <= classicPlotWorld.WALL_HEIGHT; y++) { for (int y = yStart; y <= classicPlotWorld.WALL_HEIGHT; y++) {
queue.setBlock(x, y, z, blocks); queue.setBlock(x, y, z, blocks);
} }
} }

Some files were not shown because too many files have changed in this diff Show More