Compare commits

..

81 Commits

Author SHA1 Message Date
9127e472b8 Fix IndexOutOfBoundsException on BlockFertilizeEvent 2025-02-24 16:59:23 +01:00
a0a3d8828a Back to snapshot for development 2025-02-23 20:57:47 +00:00
8741bfcf88 Release 7.5.1 2025-02-23 20:46:30 +00:00
6a6c113e5b fix: use orTimeout instead of completing null in chunk coordinator 2025-02-23 20:25:17 +00:00
3f573b4d46 Update fawe to v2.13.0 (#4607)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-23 14:35:55 +00:00
2f6db9c3db Back to snapshot for development
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2025-02-23 11:27:30 +01:00
2f050b7b47 Release 7.5.0
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2025-02-23 11:25:22 +01:00
eb0d854870 fix: allow queues to not generate chunks (#4599)
- initially apply to regenallroads
 - additionally add a 10s timeout for requesting a chunk before resubmitting it to the queue
 - addresses #4310
2025-02-23 11:21:18 +01:00
d4f10422e3 1.21.4 (#4582)
* chore: bump api to 1.21.4

* fix: replace (removed) constants with backwards compatible alternatives

* chore: cleanup import

* chore: update javadoc link for paper

* chore: i like this more

* fix: check for vehicle

* chore: compile against 1.20.4 again

* chore: add 1.21.4 to bug report issue template

* chore: add 1.21.4 to runServer supported versions array

* chore: update entity type enum name switch

* chore: remove 1.18 from supportedVersions for runServer task

* fix: attempt to update ReplicatingEntityWrapper

* fix/chore: missing boat handling on spawn

* chore: cleanup imports
2025-02-23 11:20:33 +01:00
4e2ea67992 fix: update error message of /p remove <player> if player does not need to be removed (#4592) 2025-02-22 19:25:49 +00:00
f533e194f4 Update junit5 monorepo (#4598)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-21 14:18:09 +00:00
98bc2e7407 Update adventure to v4.19.0 (#4597)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-17 03:18:04 +00:00
1b9d0d5317 Improve teleport behavior for home command (#4369) 2025-02-15 15:29:21 +00:00
8bb15d5c65 Back to snapshot for development
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2025-02-12 21:15:51 +01:00
e9baa802ec Release 7.4.2
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2025-02-12 21:09:27 +01:00
63e2d325cf Update dependency com.github.spotbugs:spotbugs-annotations to v4.9.1 (#4591)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-08 21:50:50 +00:00
94abd69e22 Update dependency org.checkerframework:checker-qual to v3.49.0 (#4587)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-03 22:23:37 +00:00
661e4ae8d3 Update dependency com.gradleup.shadow to v8.3.6 (#4585)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-02 21:38:30 +00:00
974c639a51 fix: grow music inventory dynamically (#4583) 2025-01-26 12:51:54 +01:00
11b806bd4d Update dependency gradle to v8.12.1 (#4581)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-24 14:14:20 +00:00
0275372051 Update dependency com.github.spotbugs:spotbugs-annotations to v4.9.0 (#4572)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-16 13:14:02 +00:00
c18cf3acfe Update dependency com.diffplug.spotless to v7.0.2 (#4571)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-14 21:41:40 +00:00
fa52149394 Update dependency com.diffplug.spotless to v7.0.1 (#4566)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-07 20:31:41 +00:00
f5108ec253 Update dependency com.diffplug.spotless to v7 (#4565)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-07 09:10:19 +00:00
a7058eeff2 Update eps1lon/actions-label-merge-conflict action to v3.0.3 (#4564)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-07 08:01:24 +00:00
eabae8db44 Update dependency org.checkerframework:checker-qual to v3.48.4 (#4563)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-07 08:01:08 +00:00
a836e8e763 Back to snapshot for development
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2024-12-30 21:07:08 +01:00
6930a9cecb Release 7.4.1
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2024-12-30 21:03:23 +01:00
effbacb823 Force-enable NETWORK side effect to ensure blocks are instantly visible (#4558) 2024-12-30 21:01:10 +01:00
47d1f1e0cb Update fawe to v2.12.3 (#4561)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-29 13:17:37 +00:00
6bedd9b25f Update adventure to v4.18.0 (#4559)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-23 00:23:50 +00:00
960b7b2a8b Add option to prevent entities from being moved from plot (#4554) 2024-12-22 11:12:10 +01:00
198052b7a8 Update dependency gradle to v8.12 (#4555)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-20 20:51:53 +00:00
a5af3a9d16 Update junit5 monorepo (#4553)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-16 15:52:35 +00:00
bc4e2c51da fix: update to changes in 1.21 class paths (#4546) 2024-12-06 17:52:17 +01:00
c46b4ddeaa Add 1.21 music discs (Fixes #4551)
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2024-12-06 17:51:31 +01:00
c8e7367987 Update dependency org.checkerframework:checker-qual to v3.48.3 (#4549)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-02 20:52:26 +00:00
1a0450eefb Migrate renovate config (#4543)
Migrate config .github/renovate.json

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Pierre Maurice Schwang <mail@pschwang.eu>
2024-11-30 00:00:16 +01:00
0cb8075184 Update dependency com.fastasyncworldedit:FastAsyncWorldEdit-Core to v2.12.2 (#4547)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-25 05:11:54 +00:00
5d979b0a4f Update dependency com.fastasyncworldedit:FastAsyncWorldEdit-Core to v2.12.1 (#4545)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-21 02:14:56 +00:00
fe1554c03c Update dependency gradle to v8.11.1 (#4544)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-20 19:44:50 +00:00
f0fd9986b4 Back to snapshot for development
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2024-11-19 16:53:39 +01:00
bab6f20a5d Release 7.4.0
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2024-11-19 16:52:43 +01:00
32d36b28fa feat: add InteractionInteractFlag (#4538) 2024-11-19 16:48:03 +01:00
a11c560d4e Support 1.21.3 (#4537)
* Fix Biome ABI break

* Update issue template

* add run-task for 1.21.3
2024-11-18 18:44:00 +01:00
66bb0a6214 Update dependency gradle to v8.11 (#4540)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-11 16:40:08 +00:00
7218e9829f Update dependency com.gradleup.shadow to v8.3.5 2024-11-03 03:27:24 +00:00
2e17c941fc Update dependency org.checkerframework:checker-qual to v3.48.2 2024-11-01 23:06:01 +00:00
5e628cc758 Restriction: Adding "weaving-death-place" flag (#4519)
* Adding "weaving-death-place" flag

* Improving spelling of flag description

* Reworking event listener for Weaving effect

* Undoing import optimization

* Fixing weaving-death-place check for plots
2024-11-01 11:06:46 +00:00
a42e08dc0e Adding "entity-change-block" flag check for roads (#4527)
Adding check for plot flag
2024-11-01 11:05:33 +00:00
10bf45c128 Update dependency com.gradleup.shadow to v8.3.4 2024-10-29 06:17:48 +00:00
9fe61e5053 Update fawe to v2.12.0 2024-10-25 21:38:23 +00:00
8f5bdf5dbb Back to snapshot for development
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2024-10-25 19:58:55 +02:00
9df1387f81 Release 7.3.12
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2024-10-25 19:57:54 +02:00
dcf5a7d940 Update junit5 monorepo 2024-10-21 17:00:43 +00:00
641e3840cb Do not check interactions outside plot areas (#4515) 2024-10-13 10:31:08 +02:00
5642061d6f Update dependency org.checkerframework:checker-qual to v3.48.1 2024-10-11 21:58:05 +00:00
003898f6a7 Update junit5 monorepo 2024-10-04 16:31:07 +00:00
fecf8104e9 Update dependency org.checkerframework:checker-qual to v3.48.0 2024-10-02 18:08:14 +00:00
8a9dab4f8e Update dependency com.gradleup.shadow to v8.3.3 2024-10-02 07:08:25 +00:00
0832656a12 Update junit5 monorepo 2024-09-25 08:24:14 +00:00
5525085e6d Update dependency gradle to v8.10.2 2024-09-24 01:08:25 +00:00
7a429fd05c Update dependency org.bstats:bstats-bukkit to v3.1.0 2024-09-22 18:27:56 +00:00
2c0ad36939 Update dependency com.gradleup.shadow to v8.3.2 2024-09-18 14:32:21 +00:00
5e0957c14a Update fawe to v2.11.2 2024-09-15 18:25:38 +00:00
c83306a2ea Back to snapshot for development
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2024-09-15 17:10:27 +02:00
6f4c156585 Release 7.3.11
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2024-09-15 17:09:58 +02:00
afb36d98c7 Read Adventure version from version catalogue
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2024-09-15 14:22:31 +02:00
001ae78fb2 fix: load single plot areas on creation (#4490)
* fix: load single plot areas on creation

* fix: don't allow overlapping plot areas
2024-09-14 10:46:27 +02:00
5fc8e06c22 Update dependency com.gradleup.shadow to v8.3.1 2024-09-10 14:49:56 +00:00
f9401dda94 Update dependency gradle to v8.10.1 2024-09-09 10:50:42 +00:00
d1a48dba4d Update dependency org.checkerframework:checker-qual to v3.47.0 2024-09-04 19:07:03 +00:00
db9b51a535 Back to snapshot for development
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2024-08-31 11:31:51 +02:00
511db0af37 Release 7.3.10
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2024-08-31 11:27:05 +02:00
e1ccda3e6d Prevent vanished players from being in plot kick autocompletion (#4485) 2024-08-30 17:50:23 +02:00
a69cd609b9 fix: rename minecart EntityType enum constants (#4471)
* fix: rename minecart EntityType enum constants

* chore: re-add older minecart entity type names
2024-08-25 22:12:25 +02:00
5d4e6c5819 Update shadow
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2024-08-25 11:39:14 +02:00
db05f1481a Update MySQL properties URL
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2024-08-25 11:35:59 +02:00
ee3dd00225 Update dependency org.bstats:bstats-bukkit to v3.0.3 2024-08-19 08:35:39 +00:00
346a48225d Update dependency xyz.jpenilla.run-paper to v2.3.1 2024-08-18 22:38:48 +00:00
dfd80c4723 Reenable checkerframewowkr javadoc linking (#4483)
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2024-08-18 01:11:22 +02:00
46 changed files with 440 additions and 157 deletions

View File

@ -27,6 +27,8 @@ body:
description: Which server version are you using? If your server version is not listed, it is not supported. Update to a supported version first. description: Which server version are 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.21.4'
- '1.21.3'
- '1.21.1' - '1.21.1'
- '1.20.6' - '1.20.6'
- '1.20.4' - '1.20.4'

View File

@ -1,7 +1,7 @@
{ {
"$schema": "https://docs.renovatebot.com/renovate-schema.json", "$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [ "extends": [
"config:base", "config:recommended",
":semanticCommitsDisabled" ":semanticCommitsDisabled"
], ],
"automerge": true, "automerge": true,

View File

@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Label conflicting PRs - name: Label conflicting PRs
uses: eps1lon/actions-label-merge-conflict@v3.0.2 uses: eps1lon/actions-label-merge-conflict@v3.0.3
with: with:
dirtyLabel: "unresolved-merge-conflict" dirtyLabel: "unresolved-merge-conflict"
repoToken: "${{ secrets.GITHUB_TOKEN }}" repoToken: "${{ secrets.GITHUB_TOKEN }}"

View File

@ -39,7 +39,9 @@ dependencies {
} }
compileOnly(libs.placeholderapi) compileOnly(libs.placeholderapi)
compileOnly(libs.luckperms) compileOnly(libs.luckperms)
compileOnly(libs.essentialsx) compileOnly(libs.essentialsx) {
exclude(group = "org.spigotmc")
}
compileOnly(libs.mvdwapi) { isTransitive = false } compileOnly(libs.mvdwapi) { isTransitive = false }
// Other libraries // Other libraries
@ -101,10 +103,10 @@ 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.20/") opt.links("https://jd.papermc.io/paper/1.20.4/")
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.advntr.dev/api/4.14.0/") opt.links("https://jd.advntr.dev/api/" + libs.adventureApi.get().versionConstraint.toString())
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

View File

@ -789,22 +789,23 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
if (entity.getMetadata("ps_custom_spawned").stream().anyMatch(MetadataValue::asBoolean)) { if (entity.getMetadata("ps_custom_spawned").stream().anyMatch(MetadataValue::asBoolean)) {
continue; continue;
} }
// TODO: use (type) pattern matching when targeting java 21
switch (entity.getType().toString()) { switch (entity.getType().toString()) {
case "EGG": case "EGG":
case "FISHING_HOOK": case "FISHING_HOOK", "FISHING_BOBBER":
case "ENDER_SIGNAL": case "ENDER_SIGNAL", "EYE_OF_ENDER":
case "AREA_EFFECT_CLOUD": case "AREA_EFFECT_CLOUD":
case "EXPERIENCE_ORB": case "EXPERIENCE_ORB":
case "LEASH_HITCH": case "LEASH_HITCH", "LEASH_KNOT":
case "FIREWORK": case "FIREWORK", "FIREWORK_ROCKET":
case "LIGHTNING": case "LIGHTNING", "LIGHTNING_BOLT":
case "WITHER_SKULL": case "WITHER_SKULL":
case "UNKNOWN": case "UNKNOWN":
case "PLAYER": case "PLAYER":
// non moving / unmovable // non moving / unmovable
continue; continue;
case "THROWN_EXP_BOTTLE": case "THROWN_EXP_BOTTLE", "EXPERIENCE_BOTTLE":
case "SPLASH_POTION": case "SPLASH_POTION", "POTION":
case "SNOWBALL": case "SNOWBALL":
case "SHULKER_BULLET": case "SHULKER_BULLET":
case "SPECTRAL_ARROW": case "SPECTRAL_ARROW":
@ -822,14 +823,25 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
// Temporarily classify as vehicle // Temporarily classify as vehicle
case "MINECART": case "MINECART":
case "MINECART_CHEST": case "MINECART_CHEST":
case "CHEST_MINECART":
case "MINECART_COMMAND": case "MINECART_COMMAND":
case "COMMAND_BLOCK_MINECART":
case "MINECART_FURNACE": case "MINECART_FURNACE":
case "FURNACE_MINECART":
case "MINECART_HOPPER": case "MINECART_HOPPER":
case "HOPPER_MINECART":
case "MINECART_MOB_SPAWNER": case "MINECART_MOB_SPAWNER":
case "SPAWNER_MINECART":
case "ENDER_CRYSTAL": case "ENDER_CRYSTAL":
case "MINECART_TNT": case "MINECART_TNT":
case "TNT_MINECART":
case "CHEST_BOAT": case "CHEST_BOAT":
case "BOAT": case "BOAT":
case "ACACIA_BOAT", "BIRCH_BOAT", "CHERRY_BOAT", "DARK_OAK_BOAT", "JUNGLE_BOAT", "MANGROVE_BOAT",
"OAK_BOAT", "PALE_OAK_BOAT", "SPRUCE_BOAT", "BAMBOO_RAFT":
case "ACACIA_CHEST_BOAT", "BIRCH_CHEST_BOAT", "CHERRY_CHEST_BOAT", "DARK_OAK_CHEST_BOAT",
"JUNGLE_CHEST_BOAT", "MANGROVE_CHEST_BOAT", "OAK_CHEST_BOAT", "PALE_OAK_CHEST_BOAT",
"SPRUCE_CHEST_BOAT", "BAMBOO_CHEST_RAFT":
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());
Plot plot = location.getPlot(); Plot plot = location.getPlot();
@ -858,14 +870,14 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
case "SMALL_FIREBALL": case "SMALL_FIREBALL":
case "FIREBALL": case "FIREBALL":
case "DRAGON_FIREBALL": case "DRAGON_FIREBALL":
case "DROPPED_ITEM": case "DROPPED_ITEM", "ITEM":
if (Settings.Enabled_Components.KILL_ROAD_ITEMS if (Settings.Enabled_Components.KILL_ROAD_ITEMS
&& plotArea.getOwnedPlotAbs(BukkitUtil.adapt(entity.getLocation())) == null) { && plotArea.getOwnedPlotAbs(BukkitUtil.adapt(entity.getLocation())) == null) {
this.removeRoadEntity(entity, iterator); this.removeRoadEntity(entity, iterator);
} }
// dropped item // dropped item
continue; continue;
case "PRIMED_TNT": case "PRIMED_TNT", "TNT":
case "FALLING_BLOCK": case "FALLING_BLOCK":
// managed elsewhere // managed elsewhere
continue; continue;
@ -943,7 +955,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
case "HORSE": case "HORSE":
case "IRON_GOLEM": case "IRON_GOLEM":
case "MAGMA_CUBE": case "MAGMA_CUBE":
case "MUSHROOM_COW": case "MUSHROOM_COW", "MOOSHROOM":
case "OCELOT": case "OCELOT":
case "PIG": case "PIG":
case "PIG_ZOMBIE": case "PIG_ZOMBIE":
@ -952,7 +964,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
case "SILVERFISH": case "SILVERFISH":
case "SKELETON": case "SKELETON":
case "SLIME": case "SLIME":
case "SNOWMAN": case "SNOWMAN", "SNOW_GOLEM":
case "SPIDER": case "SPIDER":
case "SQUID": case "SQUID":
case "VILLAGER": case "VILLAGER":
@ -1165,7 +1177,9 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
@Override @Override
public @NonNull String serverNativePackage() { public @NonNull String serverNativePackage() {
final String name = Bukkit.getServer().getClass().getPackage().getName(); final String name = Bukkit.getServer().getClass().getPackage().getName();
return name.substring(name.lastIndexOf('.') + 1); String ver = name.substring(name.lastIndexOf('.') + 1);
// org.bukkit.craftbukkit is no longer suffixed by a version
return ver.equals("craftbukkit") ? "" : ver;
} }
@Override @Override

View File

@ -25,7 +25,6 @@ import org.bukkit.Art;
import org.bukkit.DyeColor; import org.bukkit.DyeColor;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Rotation; import org.bukkit.Rotation;
import org.bukkit.TreeSpecies;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.entity.AbstractHorse; import org.bukkit.entity.AbstractHorse;
@ -34,6 +33,7 @@ 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.Breedable;
import org.bukkit.entity.ChestBoat;
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;
@ -44,7 +44,6 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Painting; import org.bukkit.entity.Painting;
import org.bukkit.entity.Rabbit; import org.bukkit.entity.Rabbit;
import org.bukkit.entity.Sheep; import org.bukkit.entity.Sheep;
import org.bukkit.entity.Slime;
import org.bukkit.entity.Tameable; import org.bukkit.entity.Tameable;
import org.bukkit.inventory.EntityEquipment; import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.InventoryHolder;
@ -103,11 +102,19 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
this.noGravity = true; this.noGravity = true;
} }
switch (entity.getType().toString()) { switch (entity.getType().toString()) {
case "BOAT" -> { case "BOAT", "ACACIA_BOAT", "BIRCH_BOAT", "CHERRY_BOAT", "DARK_OAK_BOAT", "JUNGLE_BOAT", "MANGROVE_BOAT",
"OAK_BOAT", "PALE_OAK_BOAT", "SPRUCE_BOAT", "BAMBOO_RAFT" -> {
Boat boat = (Boat) entity; Boat boat = (Boat) entity;
this.dataByte = getOrdinal(TreeSpecies.values(), boat.getWoodType()); this.dataByte = getOrdinal(Boat.Type.values(), boat.getBoatType());
return; return;
} }
case "ACACIA_CHEST_BOAT", "BIRCH_CHEST_BOAT", "CHERRY_CHEST_BOAT", "DARK_OAK_CHEST_BOAT",
"JUNGLE_CHEST_BOAT", "MANGROVE_CHEST_BOAT", "OAK_CHEST_BOAT", "PALE_OAK_CHEST_BOAT",
"SPRUCE_CHEST_BOAT", "BAMBOO_CHEST_RAFT" -> {
ChestBoat boat = (ChestBoat) entity;
this.dataByte = getOrdinal(Boat.Type.values(), boat.getBoatType());
storeInventory(boat);
}
case "ARROW", "EGG", "ENDER_CRYSTAL", "ENDER_PEARL", "ENDER_SIGNAL", "EXPERIENCE_ORB", "FALLING_BLOCK", "FIREBALL", case "ARROW", "EGG", "ENDER_CRYSTAL", "ENDER_PEARL", "ENDER_SIGNAL", "EXPERIENCE_ORB", "FALLING_BLOCK", "FIREBALL",
"FIREWORK", "FISHING_HOOK", "LEASH_HITCH", "LIGHTNING", "MINECART", "MINECART_COMMAND", "MINECART_MOB_SPAWNER", "FIREWORK", "FISHING_HOOK", "LEASH_HITCH", "LIGHTNING", "MINECART", "MINECART_COMMAND", "MINECART_MOB_SPAWNER",
"MINECART_TNT", "PLAYER", "PRIMED_TNT", "SLIME", "SMALL_FIREBALL", "SNOWBALL", "MINECART_FURNACE", "SPLASH_POTION", "MINECART_TNT", "PLAYER", "PRIMED_TNT", "SLIME", "SMALL_FIREBALL", "SNOWBALL", "MINECART_FURNACE", "SPLASH_POTION",
@ -117,7 +124,7 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
return; return;
} }
// MISC // // MISC //
case "DROPPED_ITEM" -> { case "DROPPED_ITEM", "ITEM" -> {
Item item = (Item) entity; Item item = (Item) entity;
this.stack = item.getItemStack(); this.stack = item.getItemStack();
return; return;
@ -147,14 +154,14 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
} }
// END MISC // // END MISC //
// INVENTORY HOLDER // // INVENTORY HOLDER //
case "MINECART_CHEST", "MINECART_HOPPER" -> { case "MINECART_CHEST", "CHEST_MINECART", "MINECART_HOPPER", "HOPPER_MINECART" -> {
storeInventory((InventoryHolder) entity); storeInventory((InventoryHolder) entity);
return; return;
} }
// START LIVING ENTITY // // START LIVING ENTITY //
// START AGEABLE // // START AGEABLE //
// START TAMEABLE // // START TAMEABLE //
case "HORSE", "DONKEY", "LLAMA", "MULE", "SKELETON_HORSE" -> { case "CAMEL", "HORSE", "DONKEY", "LLAMA", "TRADER_LLAMA", "MULE", "SKELETON_HORSE", "ZOMBIE_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();
@ -172,14 +179,13 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
return; return;
} }
// END INVENTORY HOLDER // // END INVENTORY HOLDER //
case "WOLF", "OCELOT" -> { case "WOLF", "OCELOT", "CAT", "PARROT" -> {
storeTameable((Tameable) entity); storeTameable((Tameable) entity);
storeBreedable((Breedable) entity); storeBreedable((Breedable) entity);
storeLiving((LivingEntity) entity); storeLiving((LivingEntity) entity);
return; return;
} }
// END TAMEABLE // // END TAMEABLE //
//todo fix sheep
case "SHEEP" -> { case "SHEEP" -> {
Sheep sheep = (Sheep) entity; Sheep sheep = (Sheep) entity;
if (sheep.isSheared()) { if (sheep.isSheared()) {
@ -187,7 +193,7 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
} else { } else {
this.dataByte = (byte) 0; this.dataByte = (byte) 0;
} }
this.dataByte2 = sheep.getColor().getDyeData(); this.dataByte2 = getOrdinal(DyeColor.values(), sheep.getColor());
storeBreedable(sheep); storeBreedable(sheep);
storeLiving(sheep); storeLiving(sheep);
return; return;
@ -268,7 +274,7 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
} }
case "SKELETON", "WITHER_SKELETON", "GUARDIAN", "ELDER_GUARDIAN", "GHAST", "MAGMA_CUBE", "SQUID", "PIG_ZOMBIE", "HOGLIN", case "SKELETON", "WITHER_SKELETON", "GUARDIAN", "ELDER_GUARDIAN", "GHAST", "MAGMA_CUBE", "SQUID", "PIG_ZOMBIE", "HOGLIN",
"ZOMBIFIED_PIGLIN", "PIGLIN", "PIGLIN_BRUTE", "ZOMBIE", "WITHER", "WITCH", "SPIDER", "CAVE_SPIDER", "SILVERFISH", "ZOMBIFIED_PIGLIN", "PIGLIN", "PIGLIN_BRUTE", "ZOMBIE", "WITHER", "WITCH", "SPIDER", "CAVE_SPIDER", "SILVERFISH",
"GIANT", "ENDERMAN", "CREEPER", "BLAZE", "SHULKER", "SNOWMAN" -> { "GIANT", "ENDERMAN", "CREEPER", "BLAZE", "SHULKER", "SNOWMAN", "SNOW_GOLEM" -> {
storeLiving((LivingEntity) entity); storeLiving((LivingEntity) entity);
return; return;
} }
@ -450,7 +456,7 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
} }
Entity entity; Entity entity;
switch (this.getType().toString()) { switch (this.getType().toString()) {
case "DROPPED_ITEM" -> { case "DROPPED_ITEM", "ITEM" -> {
return world.dropItem(location, this.stack); return world.dropItem(location, this.stack);
} }
case "PLAYER", "LEASH_HITCH" -> { case "PLAYER", "LEASH_HITCH" -> {
@ -486,15 +492,25 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
entity.setGravity(false); entity.setGravity(false);
} }
switch (entity.getType().toString()) { switch (entity.getType().toString()) {
case "BOAT" -> { case "BOAT", "ACACIA_BOAT", "BIRCH_BOAT", "CHERRY_BOAT", "DARK_OAK_BOAT", "JUNGLE_BOAT", "MANGROVE_BOAT",
"OAK_BOAT", "PALE_OAK_BOAT", "SPRUCE_BOAT", "BAMBOO_RAFT" -> {
Boat boat = (Boat) entity; Boat boat = (Boat) entity;
boat.setWoodType(TreeSpecies.values()[dataByte]); boat.setBoatType(Boat.Type.values()[dataByte]);
return entity; return entity;
} }
case "SLIME" -> { case "ACACIA_CHEST_BOAT", "BIRCH_CHEST_BOAT", "CHERRY_CHEST_BOAT", "DARK_OAK_CHEST_BOAT",
"JUNGLE_CHEST_BOAT", "MANGROVE_CHEST_BOAT", "OAK_CHEST_BOAT", "PALE_OAK_CHEST_BOAT",
"SPRUCE_CHEST_BOAT", "BAMBOO_CHEST_RAFT" -> {
ChestBoat boat = (ChestBoat) entity;
boat.setBoatType(Boat.Type.values()[dataByte]);
restoreInventory(boat);
return entity;
}
// SLIME is not even stored
/* case "SLIME" -> {
((Slime) entity).setSize(this.dataByte); ((Slime) entity).setSize(this.dataByte);
return entity; return entity;
} } */
case "ARROW", "EGG", "ENDER_CRYSTAL", "ENDER_PEARL", "ENDER_SIGNAL", "DROPPED_ITEM", "EXPERIENCE_ORB", "FALLING_BLOCK", case "ARROW", "EGG", "ENDER_CRYSTAL", "ENDER_PEARL", "ENDER_SIGNAL", "DROPPED_ITEM", "EXPERIENCE_ORB", "FALLING_BLOCK",
"FIREBALL", "FIREWORK", "FISHING_HOOK", "LEASH_HITCH", "LIGHTNING", "MINECART", "MINECART_COMMAND", "FIREBALL", "FIREWORK", "FISHING_HOOK", "LEASH_HITCH", "LIGHTNING", "MINECART", "MINECART_COMMAND",
"MINECART_MOB_SPAWNER", "MINECART_TNT", "PLAYER", "PRIMED_TNT", "SMALL_FIREBALL", "SNOWBALL", "MINECART_MOB_SPAWNER", "MINECART_TNT", "PLAYER", "PRIMED_TNT", "SMALL_FIREBALL", "SNOWBALL",
@ -518,14 +534,14 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
} }
// END MISC // // END MISC //
// INVENTORY HOLDER // // INVENTORY HOLDER //
case "MINECART_CHEST", "MINECART_HOPPER" -> { case "MINECART_CHEST", "CHEST_MINECART", "MINECART_HOPPER", "HOPPER_MINECART" -> {
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", "LLAMA", "SKELETON_HORSE", "DONKEY", "MULE" -> { case "CAMEL", "HORSE", "DONKEY", "LLAMA", "TRADER_LLAMA", "MULE", "SKELETON_HORSE", "ZOMBIE_HORSE" -> {
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) {
@ -542,7 +558,7 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
return entity; return entity;
} }
// END INVENTORY HOLDER // // END INVENTORY HOLDER //
case "WOLF", "OCELOT" -> { case "WOLF", "OCELOT", "CAT", "PARROT" -> {
restoreTameable((Tameable) entity); restoreTameable((Tameable) entity);
restoreBreedable((Breedable) entity); restoreBreedable((Breedable) entity);
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
@ -555,7 +571,7 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
sheep.setSheared(true); sheep.setSheared(true);
} }
if (this.dataByte2 != 0) { if (this.dataByte2 != 0) {
sheep.setColor(DyeColor.getByDyeData(this.dataByte2)); sheep.setColor(DyeColor.values()[this.dataByte2]);
} }
restoreBreedable(sheep); restoreBreedable(sheep);
restoreLiving(sheep); restoreLiving(sheep);

View File

@ -52,7 +52,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.EnumSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
@ -445,7 +445,7 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
private static final List<Biome> BIOMES; private static final List<Biome> BIOMES;
static { static {
Set<Biome> disabledBiomes = EnumSet.of(Biome.CUSTOM); Set<Biome> disabledBiomes = new HashSet<>(List.of(Biome.CUSTOM));
if (PlotSquared.platform().serverVersion()[1] <= 19) { if (PlotSquared.platform().serverVersion()[1] <= 19) {
final Biome cherryGrove = Registry.BIOME.get(NamespacedKey.minecraft("cherry_grove")); final Biome cherryGrove = Registry.BIOME.get(NamespacedKey.minecraft("cherry_grove"));
if (cherryGrove != null) { if (cherryGrove != null) {

View File

@ -134,7 +134,7 @@ public class BlockEventListener117 implements Listener {
public void onBlockFertilize(BlockFertilizeEvent event) { public void onBlockFertilize(BlockFertilizeEvent event) {
Block block = event.getBlock(); Block block = event.getBlock();
List<org.bukkit.block.BlockState> blocks = event.getBlocks(); List<org.bukkit.block.BlockState> blocks = event.getBlocks();
Location location = BukkitUtil.adapt(blocks.get(0).getLocation()); Location location = BukkitUtil.adapt(block.getLocation());
PlotArea area = location.getPlotArea(); PlotArea area = location.getPlotArea();
if (area == null) { if (area == null) {

View File

@ -37,10 +37,12 @@ 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.flag.implementations.ProjectileChangeBlockFlag;
import com.plotsquared.core.plot.flag.implementations.WeavingDeathPlace;
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.util.Enums;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import org.bukkit.Material; import org.bukkit.Material;
@ -56,6 +58,7 @@ import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile; import org.bukkit.entity.Projectile;
import org.bukkit.entity.TNTPrimed; import org.bukkit.entity.TNTPrimed;
import org.bukkit.entity.Vehicle; import org.bukkit.entity.Vehicle;
import org.bukkit.entity.minecart.ExplosiveMinecart;
import org.bukkit.event.Cancellable; import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
@ -77,10 +80,17 @@ import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Objects;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class EntityEventListener implements Listener { public class EntityEventListener implements Listener {
private static final Particle EXPLOSION_HUGE = Objects.requireNonNull(Enums.findByValue(
Particle.class,
"EXPLOSION_EMITTER",
"EXPLOSION_HUGE"
));
private final BukkitPlatform platform; private final BukkitPlatform platform;
private final PlotAreaManager plotAreaManager; private final PlotAreaManager plotAreaManager;
private final EventDispatcher eventDispatcher; private final EventDispatcher eventDispatcher;
@ -151,8 +161,8 @@ public class EntityEventListener implements Listener {
} }
} }
case "REINFORCEMENTS", "NATURAL", "MOUNT", "PATROL", "RAID", "SHEARED", "SILVERFISH_BLOCK", "ENDER_PEARL", case "REINFORCEMENTS", "NATURAL", "MOUNT", "PATROL", "RAID", "SHEARED", "SILVERFISH_BLOCK", "ENDER_PEARL",
"TRAP", "VILLAGE_DEFENSE", "VILLAGE_INVASION", "BEEHIVE", "CHUNK_GEN", "NETHER_PORTAL", "TRAP", "VILLAGE_DEFENSE", "VILLAGE_INVASION", "BEEHIVE", "CHUNK_GEN", "NETHER_PORTAL",
"FROZEN", "SPELL", "DEFAULT" -> { "FROZEN", "SPELL", "DEFAULT" -> {
if (!area.isMobSpawning()) { if (!area.isMobSpawning()) {
event.setCancelled(true); event.setCancelled(true);
return; return;
@ -243,6 +253,29 @@ public class EntityEventListener implements Listener {
} }
} }
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onWeavingEffect(EntityChangeBlockEvent event) {
if (event.getTo() != Material.COBWEB) {
return;
}
Location location = BukkitUtil.adapt(event.getBlock().getLocation());
PlotArea area = location.getPlotArea();
if (area == null) {
return;
}
Plot plot = location.getOwnedPlot();
if (plot == null) {
if (PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, WeavingDeathPlace.class, false)) {
event.setCancelled(true);
}
return;
}
if (!plot.getFlag(WeavingDeathPlace.class)) {
plot.debug(event.getTo() + " could not spawn because weaving-death-place = false");
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGH) @EventHandler(priority = EventPriority.HIGH)
public void onDamage(EntityDamageEvent event) { public void onDamage(EntityDamageEvent event) {
if (event.getEntityType() != EntityType.PLAYER) { if (event.getEntityType() != EntityType.PLAYER) {
@ -290,7 +323,7 @@ public class EntityEventListener implements Listener {
if (this.lastRadius != 0) { if (this.lastRadius != 0) {
List<Entity> nearby = event.getEntity().getNearbyEntities(this.lastRadius, this.lastRadius, this.lastRadius); List<Entity> nearby = event.getEntity().getNearbyEntities(this.lastRadius, this.lastRadius, this.lastRadius);
for (Entity near : nearby) { for (Entity near : nearby) {
if (near instanceof TNTPrimed || near.getType().equals(EntityType.MINECART_TNT)) { if (near instanceof TNTPrimed || near instanceof ExplosiveMinecart) {
if (!near.hasMetadata("plot")) { if (!near.hasMetadata("plot")) {
near.setMetadata("plot", new FixedMetadataValue((Plugin) PlotSquared.platform(), plot)); near.setMetadata("plot", new FixedMetadataValue((Plugin) PlotSquared.platform(), plot));
} }
@ -314,7 +347,7 @@ public class EntityEventListener implements Listener {
event.setCancelled(true); event.setCancelled(true);
//Spawn Explosion Particles when enabled in settings //Spawn Explosion Particles when enabled in settings
if (Settings.General.ALWAYS_SHOW_EXPLOSIONS) { if (Settings.General.ALWAYS_SHOW_EXPLOSIONS) {
event.getLocation().getWorld().spawnParticle(Particle.EXPLOSION_HUGE, event.getLocation(), 0); event.getLocation().getWorld().spawnParticle(EXPLOSION_HUGE, event.getLocation(), 0);
} }
} }
@ -401,7 +434,13 @@ public class EntityEventListener implements Listener {
} }
Plot plot = area.getOwnedPlot(location); Plot plot = area.getOwnedPlot(location);
if (plot != null && !plot.getFlag(EntityChangeBlockFlag.class)) { if (plot == null) {
if (PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, EntityChangeBlockFlag.class, false)) {
event.setCancelled(true);
}
return;
}
if (!plot.getFlag(EntityChangeBlockFlag.class)) {
plot.debug(e.getType() + " could not change block because entity-change-block = false"); plot.debug(e.getType() + " could not change block because entity-change-block = false");
event.setCancelled(true); event.setCancelled(true);
} }

View File

@ -31,8 +31,10 @@ import org.bukkit.Chunk;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.ArmorStand; import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.EnderCrystal;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.Item;
import org.bukkit.entity.Vehicle; import org.bukkit.entity.Vehicle;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
@ -132,7 +134,7 @@ public class EntitySpawnListener implements Listener {
Plot plot = location.getOwnedPlotAbs(); Plot plot = location.getOwnedPlotAbs();
EntityType type = entity.getType(); EntityType type = entity.getType();
if (plot == null) { if (plot == null) {
if (type == EntityType.DROPPED_ITEM) { if (entity instanceof Item) {
if (Settings.Enabled_Components.KILL_ROAD_ITEMS) { if (Settings.Enabled_Components.KILL_ROAD_ITEMS) {
event.setCancelled(true); event.setCancelled(true);
} }
@ -154,7 +156,7 @@ public class EntitySpawnListener implements Listener {
if (Settings.Done.RESTRICT_BUILDING && DoneFlag.isDone(plot)) { if (Settings.Done.RESTRICT_BUILDING && DoneFlag.isDone(plot)) {
event.setCancelled(true); event.setCancelled(true);
} }
if (type == EntityType.ENDER_CRYSTAL || type == EntityType.ARMOR_STAND) { if (entity instanceof EnderCrystal || type == EntityType.ARMOR_STAND) {
if (BukkitEntityUtil.checkEntity(entity, plot)) { if (BukkitEntityUtil.checkEntity(entity, plot)) {
event.setCancelled(true); event.setCancelled(true);
} }

View File

@ -47,10 +47,12 @@ import com.plotsquared.core.plot.flag.implementations.TileDropFlag;
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 com.plotsquared.core.util.PlotFlagUtil;
import io.papermc.paper.event.entity.EntityMoveEvent;
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 org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.TileState; import org.bukkit.block.TileState;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
@ -58,6 +60,7 @@ import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile; import org.bukkit.entity.Projectile;
import org.bukkit.entity.Slime; import org.bukkit.entity.Slime;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@ -78,6 +81,9 @@ import java.util.regex.Pattern;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class PaperListener implements Listener { public class PaperListener implements Listener {
private static final NamespacedKey ITEM = NamespacedKey.minecraft("item");
private static final NamespacedKey FISHING_BOBBER = NamespacedKey.minecraft("fishing_bobber");
private final PlotAreaManager plotAreaManager; private final PlotAreaManager plotAreaManager;
private Chunk lastChunk; private Chunk lastChunk;
@ -104,33 +110,7 @@ public class PaperListener implements Listener {
if (!Settings.Paper_Components.ENTITY_PATHING) { if (!Settings.Paper_Components.ENTITY_PATHING) {
return; return;
} }
Location toLoc = BukkitUtil.adapt(event.getLoc()); handleEntityMovement(event, event.getEntity().getLocation(), event.getLoc());
Location fromLoc = BukkitUtil.adapt(event.getEntity().getLocation());
PlotArea tarea = toLoc.getPlotArea();
if (tarea == null) {
return;
}
PlotArea farea = fromLoc.getPlotArea();
if (farea == null) {
return;
}
if (tarea != farea) {
event.setCancelled(true);
return;
}
Plot tplot = toLoc.getPlot();
Plot fplot = fromLoc.getPlot();
if (tplot == null ^ fplot == null) {
event.setCancelled(true);
return;
}
if (tplot == null || tplot.getId().hashCode() == fplot.getId().hashCode()) {
return;
}
if (fplot.isMerged() && fplot.getConnectedPlots().contains(fplot)) {
return;
}
event.setCancelled(true);
} }
@EventHandler @EventHandler
@ -145,8 +125,23 @@ public class PaperListener implements Listener {
return; return;
} }
Location toLoc = BukkitUtil.adapt(b.getLocation()); handleEntityMovement(event, event.getEntity().getLocation(), b.getLocation());
Location fromLoc = BukkitUtil.adapt(event.getEntity().getLocation()); }
@EventHandler
public void onEntityMove(EntityMoveEvent event) {
if (!Settings.Paper_Components.ENTITY_MOVEMENT) {
return;
}
if (!event.hasExplicitlyChangedBlock()) {
return;
}
handleEntityMovement(event, event.getFrom(), event.getTo());
}
private static void handleEntityMovement(Cancellable event, org.bukkit.Location from, org.bukkit.Location target) {
Location toLoc = BukkitUtil.adapt(target);
Location fromLoc = BukkitUtil.adapt(from);
PlotArea tarea = toLoc.getPlotArea(); PlotArea tarea = toLoc.getPlotArea();
if (tarea == null) { if (tarea == null) {
return; return;
@ -155,7 +150,6 @@ public class PaperListener implements Listener {
if (farea == null) { if (farea == null) {
return; return;
} }
if (tarea != farea) { if (tarea != farea) {
event.setCancelled(true); event.setCancelled(true);
return; return;
@ -166,10 +160,10 @@ public class PaperListener implements Listener {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
if (tplot == null || tplot.getId().hashCode() == fplot.getId().hashCode()) { if (tplot == null || tplot.getId().equals(fplot.getId())) {
return; return;
} }
if (fplot.isMerged() && fplot.getConnectedPlots().contains(fplot)) { if (fplot.isMerged() && fplot.getConnectedPlots().contains(tplot)) {
return; return;
} }
event.setCancelled(true); event.setCancelled(true);
@ -238,7 +232,7 @@ public class PaperListener implements Listener {
if (plot == null) { if (plot == null) {
EntityType type = event.getType(); EntityType type = event.getType();
// PreCreatureSpawnEvent **should** not be called for DROPPED_ITEM, just for the sake of consistency // PreCreatureSpawnEvent **should** not be called for DROPPED_ITEM, just for the sake of consistency
if (type == EntityType.DROPPED_ITEM) { if (type.getKey().equals(ITEM)) {
if (Settings.Enabled_Components.KILL_ROAD_ITEMS) { if (Settings.Enabled_Components.KILL_ROAD_ITEMS) {
event.setCancelled(true); event.setCancelled(true);
} }
@ -364,7 +358,7 @@ public class PaperListener implements Listener {
event.setCancelled(true); event.setCancelled(true);
} }
} else if (!plot.isAdded(pp.getUUID())) { } else if (!plot.isAdded(pp.getUUID())) {
if (entity.getType().equals(EntityType.FISHING_HOOK)) { if (entity.getType().getKey().equals(FISHING_BOBBER)) {
if (plot.getFlag(FishingFlag.class)) { if (plot.getFlag(FishingFlag.class)) {
return; return;
} }

View File

@ -54,6 +54,7 @@ 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;
import com.plotsquared.core.plot.flag.implementations.InteractionInteractFlag;
import com.plotsquared.core.plot.flag.implementations.ItemDropFlag; import com.plotsquared.core.plot.flag.implementations.ItemDropFlag;
import com.plotsquared.core.plot.flag.implementations.KeepInventoryFlag; import com.plotsquared.core.plot.flag.implementations.KeepInventoryFlag;
import com.plotsquared.core.plot.flag.implementations.LecternReadBookFlag; import com.plotsquared.core.plot.flag.implementations.LecternReadBookFlag;
@ -375,7 +376,7 @@ public class PlayerEventListener implements Listener {
@EventHandler @EventHandler
public void onVehicleEntityCollision(VehicleEntityCollisionEvent e) { public void onVehicleEntityCollision(VehicleEntityCollisionEvent e) {
if (e.getVehicle().getType() == EntityType.BOAT) { if (e.getVehicle() instanceof Boat) {
Location location = BukkitUtil.adapt(e.getEntity().getLocation()); Location location = BukkitUtil.adapt(e.getEntity().getLocation());
if (location.isPlotArea()) { if (location.isPlotArea()) {
if (e.getEntity() instanceof Player) { if (e.getEntity() instanceof Player) {
@ -1737,6 +1738,11 @@ public class PlayerEventListener implements Listener {
return; return;
} }
if (EntityCategories.INTERACTION.contains(entityType) && flagContainer
.getFlag(InteractionInteractFlag.class).getValue()) {
return;
}
if (EntityCategories.VILLAGER.contains(entityType) && flagContainer if (EntityCategories.VILLAGER.contains(entityType) && flagContainer
.getFlag(VillagerInteractFlag.class).getValue()) { .getFlag(VillagerInteractFlag.class).getValue()) {
return; return;

View File

@ -35,7 +35,7 @@ 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 org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType; import org.bukkit.entity.FishHook;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile; import org.bukkit.entity.Projectile;
@ -134,7 +134,7 @@ public class ProjectileEventListener implements Listener {
event.setCancelled(true); event.setCancelled(true);
} }
} else if (!plot.isAdded(pp.getUUID())) { } else if (!plot.isAdded(pp.getUUID())) {
if (entity.getType().equals(EntityType.FISHING_HOOK)) { if (entity instanceof FishHook) {
if (plot.getFlag(FishingFlag.class)) { if (plot.getFlag(FishingFlag.class)) {
return; return;
} }
@ -194,7 +194,7 @@ public class ProjectileEventListener implements Listener {
return; return;
} }
if (plot.isAdded(pp.getUUID()) || pp.hasPermission(Permission.PERMISSION_ADMIN_PROJECTILE_OTHER) || plot.getFlag( if (plot.isAdded(pp.getUUID()) || pp.hasPermission(Permission.PERMISSION_ADMIN_PROJECTILE_OTHER) || plot.getFlag(
ProjectilesFlag.class) || (entity.getType().equals(EntityType.FISHING_HOOK) && plot.getFlag( ProjectilesFlag.class) || (entity instanceof FishHook && plot.getFlag(
FishingFlag.class))) { FishingFlag.class))) {
return; return;
} }

View File

@ -49,9 +49,14 @@ public class SingleWorldListener implements Listener {
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle").getRealMethod(); this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle").getRealMethod();
} catch (NoSuchMethodException ignored) { } catch (NoSuchMethodException ignored) {
try { try {
ReflectionUtils.RefClass classChunkStatus = getRefClass("net.minecraft.world.level.chunk.ChunkStatus"); String chunkStatus = PlotSquared.platform().serverVersion()[1] < 21
? "net.minecraft.world.level.chunk" + ".ChunkStatus"
: "net.minecraft.world.level.chunk.status.ChunkStatus";
ReflectionUtils.RefClass classChunkStatus = getRefClass(chunkStatus);
this.objChunkStatusFull = classChunkStatus.getRealClass().getField("n").get(null); this.objChunkStatusFull = classChunkStatus.getRealClass().getField("n").get(null);
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle", classChunkStatus.getRealClass()).getRealMethod(); this.methodGetHandleChunk = classCraftChunk
.getMethod("getHandle", classChunkStatus.getRealClass())
.getRealMethod();
} catch (NoSuchMethodException ex) { } catch (NoSuchMethodException ex) {
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }

View File

@ -30,6 +30,8 @@ import com.plotsquared.core.util.task.TaskTime;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import io.papermc.lib.PaperLib; 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.Chunk; import org.bukkit.Chunk;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
@ -41,6 +43,8 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -55,6 +59,8 @@ import java.util.function.Consumer;
**/ **/
public final class BukkitChunkCoordinator extends ChunkCoordinator { public final class BukkitChunkCoordinator extends ChunkCoordinator {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + BukkitChunkCoordinator.class.getSimpleName());
private final List<ProgressSubscriber> progressSubscribers = new LinkedList<>(); private final List<ProgressSubscriber> progressSubscribers = new LinkedList<>();
private final Queue<BlockVector2> requestedChunks; private final Queue<BlockVector2> requestedChunks;
@ -70,6 +76,7 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator {
private final AtomicInteger expectedSize; private final AtomicInteger expectedSize;
private final AtomicInteger loadingChunks = new AtomicInteger(); private final AtomicInteger loadingChunks = new AtomicInteger();
private final boolean forceSync; private final boolean forceSync;
private final boolean shouldGen;
private int batchSize; private int batchSize;
private PlotSquaredTask task; private PlotSquaredTask task;
@ -87,7 +94,8 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator {
@Assisted final @NonNull Consumer<Throwable> throwableConsumer, @Assisted final @NonNull Consumer<Throwable> throwableConsumer,
@Assisted("unloadAfter") final boolean unloadAfter, @Assisted("unloadAfter") final boolean unloadAfter,
@Assisted final @NonNull Collection<ProgressSubscriber> progressSubscribers, @Assisted final @NonNull Collection<ProgressSubscriber> progressSubscribers,
@Assisted("forceSync") final boolean forceSync @Assisted("forceSync") final boolean forceSync,
@Assisted("shouldGen") final boolean shouldGen
) { ) {
this.requestedChunks = new LinkedBlockingQueue<>(requestedChunks); this.requestedChunks = new LinkedBlockingQueue<>(requestedChunks);
this.availableChunks = new LinkedBlockingQueue<>(); this.availableChunks = new LinkedBlockingQueue<>();
@ -103,6 +111,7 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator {
this.bukkitWorld = Bukkit.getWorld(world.getName()); this.bukkitWorld = Bukkit.getWorld(world.getName());
this.progressSubscribers.addAll(progressSubscribers); this.progressSubscribers.addAll(progressSubscribers);
this.forceSync = forceSync; this.forceSync = forceSync;
this.shouldGen = shouldGen;
} }
@Override @Override
@ -212,18 +221,28 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator {
* Requests a batch of chunks to be loaded * Requests a batch of chunks to be loaded
*/ */
private void requestBatch() { private void requestBatch() {
BlockVector2 chunk; for (int i = 0; i < this.batchSize && this.requestedChunks.peek() != null; i++) {
for (int i = 0; i < this.batchSize && (chunk = this.requestedChunks.poll()) != null; i++) {
// This required PaperLib to be bumped to version 1.0.4 to mark the request as urgent // This required PaperLib to be bumped to version 1.0.4 to mark the request as urgent
final BlockVector2 chunk = this.requestedChunks.poll();
loadingChunks.incrementAndGet(); loadingChunks.incrementAndGet();
PaperLib PaperLib
.getChunkAtAsync(this.bukkitWorld, chunk.getX(), chunk.getZ(), true, true) .getChunkAtAsync(this.bukkitWorld, chunk.getX(), chunk.getZ(), shouldGen, true)
.orTimeout(10L, TimeUnit.SECONDS)
.whenComplete((chunkObject, throwable) -> { .whenComplete((chunkObject, throwable) -> {
loadingChunks.decrementAndGet(); loadingChunks.decrementAndGet();
if (throwable != null) { if (throwable != null) {
throwable.printStackTrace(); if (throwable instanceof TimeoutException) {
// We want one less because this couldn't be processed LOGGER.warn("Timed out awaiting chunk load {}", chunk);
this.expectedSize.decrementAndGet(); this.requestedChunks.offer(chunk);
} else {
LOGGER.error("Failed to load chunk {}", chunk, throwable);
// We want one less because this couldn't be processed
this.expectedSize.decrementAndGet();
}
} else if (chunkObject == null) {
if (shouldGen) {
LOGGER.error("Null chunk returned for chunk at {}", chunk);
}
} else if (PlotSquared.get().isMainThread(Thread.currentThread())) { } else if (PlotSquared.get().isMainThread(Thread.currentThread())) {
this.processChunk(chunkObject); this.processChunk(chunkObject);
} else { } else {

View File

@ -62,19 +62,28 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
private static final SideEffectSet EDGE_LIGHTING_SIDE_EFFECT_SET; private static final SideEffectSet EDGE_LIGHTING_SIDE_EFFECT_SET;
static { static {
NO_SIDE_EFFECT_SET = SideEffectSet.none().with(SideEffect.LIGHTING, SideEffect.State.OFF).with( NO_SIDE_EFFECT_SET = enableNetworkIfNeeded()
SideEffect.NEIGHBORS, .with(SideEffect.LIGHTING, SideEffect.State.OFF)
SideEffect.State.OFF .with(SideEffect.NEIGHBORS, SideEffect.State.OFF);
); EDGE_SIDE_EFFECT_SET = NO_SIDE_EFFECT_SET
EDGE_SIDE_EFFECT_SET = SideEffectSet.none().with(SideEffect.UPDATE, SideEffect.State.ON).with( .with(SideEffect.UPDATE, SideEffect.State.ON)
SideEffect.NEIGHBORS, .with(SideEffect.NEIGHBORS, SideEffect.State.ON);
SideEffect.State.ON LIGHTING_SIDE_EFFECT_SET = NO_SIDE_EFFECT_SET
); .with(SideEffect.NEIGHBORS, SideEffect.State.OFF);
LIGHTING_SIDE_EFFECT_SET = SideEffectSet.none().with(SideEffect.NEIGHBORS, SideEffect.State.OFF); EDGE_LIGHTING_SIDE_EFFECT_SET = NO_SIDE_EFFECT_SET
EDGE_LIGHTING_SIDE_EFFECT_SET = SideEffectSet.none().with(SideEffect.UPDATE, SideEffect.State.ON).with( .with(SideEffect.UPDATE, SideEffect.State.ON)
SideEffect.NEIGHBORS, .with(SideEffect.NEIGHBORS, SideEffect.State.ON);
SideEffect.State.ON }
);
// make sure block changes are sent
private static SideEffectSet enableNetworkIfNeeded() {
SideEffect network;
try {
network = SideEffect.valueOf("NETWORK");
} catch (IllegalArgumentException ignored) {
return SideEffectSet.none();
}
return SideEffectSet.none().with(network, SideEffect.State.ON);
} }
private org.bukkit.World bukkitWorld; private org.bukkit.World bukkitWorld;
@ -229,6 +238,7 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
.unloadAfter(isUnloadAfter()) .unloadAfter(isUnloadAfter())
.withProgressSubscribers(getProgressSubscribers()) .withProgressSubscribers(getProgressSubscribers())
.forceSync(isForceSync()) .forceSync(isForceSync())
.shouldGen(isShouldGen())
.build(); .build();
return super.enqueue(); return super.enqueue();
} }

View File

@ -49,6 +49,7 @@ import org.bukkit.entity.Arrow;
import org.bukkit.entity.Creature; import org.bukkit.entity.Creature;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.Firework;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile; import org.bukkit.entity.Projectile;
import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent;
@ -341,8 +342,7 @@ public class BukkitEntityUtil {
} }
//disable the firework damage. too much of a headache to support at the moment. //disable the firework damage. too much of a headache to support at the moment.
if (vplot != null) { if (vplot != null) {
if (EntityDamageEvent.DamageCause.ENTITY_EXPLOSION == cause if (EntityDamageEvent.DamageCause.ENTITY_EXPLOSION == cause && damager instanceof Firework) {
&& damager.getType() == EntityType.FIREWORK) {
return false; return false;
} }
} }

View File

@ -75,6 +75,7 @@ import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Firework; import org.bukkit.entity.Firework;
import org.bukkit.entity.Ghast; import org.bukkit.entity.Ghast;
import org.bukkit.entity.Hanging; import org.bukkit.entity.Hanging;
import org.bukkit.entity.Interaction;
import org.bukkit.entity.IronGolem; import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Item; import org.bukkit.entity.Item;
import org.bukkit.entity.LightningStrike; import org.bukkit.entity.LightningStrike;
@ -261,6 +262,11 @@ public class BukkitUtil extends WorldUtil {
}); });
} }
@Override
public boolean isSmallBlock(Location location) {
return adapt(location).getBlock().getBoundingBox().getHeight() < 0.25;
}
@Override @Override
@NonNegative @NonNegative
public int getHighestBlockSynchronous(final @NonNull String world, final int x, final int z) { public int getHighestBlockSynchronous(final @NonNull String world, final int x, final int z) {
@ -432,6 +438,7 @@ public class BukkitUtil extends WorldUtil {
@Override @Override
public @NonNull Set<com.sk89q.worldedit.world.entity.EntityType> getTypesInCategory(final @NonNull String category) { public @NonNull Set<com.sk89q.worldedit.world.entity.EntityType> getTypesInCategory(final @NonNull String category) {
final Collection<Class<?>> allowedInterfaces = new HashSet<>(); final Collection<Class<?>> allowedInterfaces = new HashSet<>();
final int[] version = PlotSquared.platform().serverVersion();
switch (category) { switch (category) {
case "animal" -> { case "animal" -> {
allowedInterfaces.add(IronGolem.class); allowedInterfaces.add(IronGolem.class);
@ -439,7 +446,7 @@ public class BukkitUtil extends WorldUtil {
allowedInterfaces.add(Animals.class); allowedInterfaces.add(Animals.class);
allowedInterfaces.add(WaterMob.class); allowedInterfaces.add(WaterMob.class);
allowedInterfaces.add(Ambient.class); allowedInterfaces.add(Ambient.class);
if (PlotSquared.platform().serverVersion()[1] >= 19) { if (version[1] >= 19) {
allowedInterfaces.add(Allay.class); allowedInterfaces.add(Allay.class);
} }
} }
@ -470,6 +477,11 @@ public class BukkitUtil extends WorldUtil {
allowedInterfaces.add(Firework.class); allowedInterfaces.add(Firework.class);
} }
case "player" -> allowedInterfaces.add(Player.class); case "player" -> allowedInterfaces.add(Player.class);
case "interaction" -> {
if ((version[1] > 19) || (version[1] == 19 && version[2] >= 4)) {
allowedInterfaces.add(Interaction.class);
}
}
default -> LOGGER.error("Unknown entity category requested: {}", category); default -> LOGGER.error("Unknown entity category requested: {}", category);
} }
final Set<com.sk89q.worldedit.world.entity.EntityType> types = new HashSet<>(); final Set<com.sk89q.worldedit.world.entity.EntityType> types = new HashSet<>();

View File

@ -68,8 +68,8 @@ 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.advntr.dev/api/4.14.0/") opt.links("https://jd.advntr.dev/api/" + libs.adventureApi.get().versionConstraint.toString())
opt.links("https://jd.advntr.dev/text-minimessage/4.14.0/") opt.links("https://jd.advntr.dev/text-minimessage/" + libs.adventureApi.get().versionConstraint.toString())
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

View File

@ -206,7 +206,8 @@ public class PlotSquared {
GlobalFlagContainer.setup(); GlobalFlagContainer.setup();
try { try {
new ReflectionUtils(this.platform.serverNativePackage()); String ver = this.platform.serverNativePackage();
new ReflectionUtils(ver.isEmpty() ? null : ver);
try { try {
URL logurl = PlotSquared.class.getProtectionDomain().getCodeSource().getLocation(); URL logurl = PlotSquared.class.getProtectionDomain().getCodeSource().getLocation();
this.jarFile = new File( this.jarFile = new File(
@ -214,7 +215,7 @@ public class PlotSquared {
logurl.toURI().toString().split("\\!")[0].replaceAll("jar:file", "file")) logurl.toURI().toString().split("\\!")[0].replaceAll("jar:file", "file"))
.getPath()); .getPath());
} catch (URISyntaxException | SecurityException e) { } catch (URISyntaxException | SecurityException e) {
e.printStackTrace(); LOGGER.error(e);
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()) {
this.jarFile = new File( this.jarFile = new File(
@ -238,7 +239,7 @@ public class PlotSquared {
copyFile("skyblock.template", Settings.Paths.TEMPLATES); copyFile("skyblock.template", Settings.Paths.TEMPLATES);
showDebug(); showDebug();
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); LOGGER.error(e);
} }
} }
@ -795,9 +796,8 @@ public class PlotSquared {
if (world.equals("CheckingPlotSquaredGenerator")) { if (world.equals("CheckingPlotSquaredGenerator")) {
return; return;
} }
if (!this.getPlotAreaManager().addWorld(world)) { // Don't check the return result -> breaks runtime loading of single plot areas on creation
return; this.getPlotAreaManager().addWorld(world);
}
Set<String> worlds; Set<String> worlds;
if (this.worldConfiguration.contains("worlds")) { if (this.worldConfiguration.contains("worlds")) {
worlds = this.worldConfiguration.getConfigurationSection("worlds").getKeys(false); worlds = this.worldConfiguration.getConfigurationSection("worlds").getKeys(false);

View File

@ -184,6 +184,7 @@ public class Area extends SubCommand {
CuboidRegion.makeCuboid(playerSelectedRegion) CuboidRegion.makeCuboid(playerSelectedRegion)
).length != 0) { ).length != 0) {
player.sendMessage(TranslatableCaption.of("single.single_area_overlapping")); player.sendMessage(TranslatableCaption.of("single.single_area_overlapping"));
return false;
} }
// Alter the region // Alter the region
final BlockVector3 playerSelectionMin = playerSelectedRegion.getMinimumPoint(); final BlockVector3 playerSelectionMin = playerSelectedRegion.getMinimumPoint();

View File

@ -153,7 +153,7 @@ public class Kick extends SubCommand {
if (plot == null) { if (plot == null) {
return Collections.emptyList(); return Collections.emptyList();
} }
return TabCompletions.completePlayersInPlot(plot, String.join(",", args).trim(), return TabCompletions.completePlayersInPlot(player, plot, String.join(",", args).trim(),
Collections.singletonList(player.getName()) Collections.singletonList(player.getName())
); );
} }

View File

@ -56,9 +56,13 @@ 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_relic" "music_disc_pigstep", "music_disc_5", "music_disc_relic", "music_disc_creator",
"music_disc_creator_music_box", "music_disc_precipice"
); );
// make sure all discs and the bedrock ("cancel") fit into the inventory
private static final int INVENTORY_ROWS = (int) Math.ceil((DISCS.size() + 1) / 9.0);
private final InventoryUtil inventoryUtil; private final InventoryUtil inventoryUtil;
private final EventDispatcher eventDispatcher; private final EventDispatcher eventDispatcher;
@ -93,7 +97,7 @@ public class Music extends SubCommand {
PlotInventory inv = new PlotInventory( PlotInventory inv = new PlotInventory(
this.inventoryUtil, this.inventoryUtil,
player, player,
2, INVENTORY_ROWS,
TranslatableCaption.of("plotjukebox.jukebox_header").getComponent(player) TranslatableCaption.of("plotjukebox.jukebox_header").getComponent(player)
) { ) {
@Override @Override

View File

@ -117,8 +117,8 @@ public class Remove extends SubCommand {
} }
if (count == 0) { if (count == 0) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("errors.invalid_player"), TranslatableCaption.of("member.player_not_removed"),
TagResolver.resolver("value", Tag.inserting(Component.text(args[0]))) TagResolver.resolver("player", Tag.inserting(Component.text(args[0])))
); );
} else { } else {
player.sendMessage( player.sendMessage(

View File

@ -26,6 +26,7 @@ import org.apache.logging.log4j.Logger;
import java.io.File; import java.io.File;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
@ -372,6 +373,7 @@ public class Config {
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE}) @Target({ElementType.FIELD, ElementType.TYPE})
@Documented
public @interface Comment { public @interface Comment {
String[] value(); String[] value();

View File

@ -582,6 +582,8 @@ public class Settings extends Config {
public static boolean PER_WORLD_VISIT = false; public static boolean PER_WORLD_VISIT = false;
@Comment("Search merged plots for having multiple owners when using the visit command") @Comment("Search merged plots for having multiple owners when using the visit command")
public static boolean VISIT_MERGED_OWNERS = true; public static boolean VISIT_MERGED_OWNERS = true;
@Comment("Allows to teleport based on block size instead to spawn on the highest block at the home command")
public static boolean SIZED_BASED = true;
} }
@ -651,6 +653,8 @@ public class Settings extends Config {
public static boolean PAPER_LISTENERS = true; public static boolean PAPER_LISTENERS = true;
@Comment("Prevent entities from leaving plots") @Comment("Prevent entities from leaving plots")
public static boolean ENTITY_PATHING = true; public static boolean ENTITY_PATHING = true;
@Comment("Prevent entities from leaving plots, even by pushing or pulling")
public static boolean ENTITY_MOVEMENT = false;
@Comment( @Comment(
"Cancel entity spawns when the chunk is loaded if the PlotArea's mob spawning is off") "Cancel entity spawns when the chunk is loaded if the PlotArea's mob spawning is off")
public static boolean CANCEL_CHUNK_SPAWN = true; public static boolean CANCEL_CHUNK_SPAWN = true;

View File

@ -46,7 +46,7 @@ public class Storage extends Config {
public static String PASSWORD = "password"; public static String PASSWORD = "password";
public static String DATABASE = "plot_db"; public static String DATABASE = "plot_db";
@Comment("Set additional properties: https://goo.gl/wngtN8") @Comment("Set additional properties: https://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html")
public static List<String> public static List<String>
PROPERTIES = new ArrayList<>(Collections.singletonList("useSSL=false")); PROPERTIES = new ArrayList<>(Collections.singletonList("useSSL=false"));

View File

@ -432,6 +432,7 @@ public class HybridUtils {
if (!UPDATE) { if (!UPDATE) {
Iterator<BlockVector2> iter = chunks.iterator(); Iterator<BlockVector2> iter = chunks.iterator();
QueueCoordinator queue = blockQueue.getNewQueue(worldUtil.getWeWorld(area.getWorldName())); QueueCoordinator queue = blockQueue.getNewQueue(worldUtil.getWeWorld(area.getWorldName()));
queue.setShouldGen(false);
while (iter.hasNext()) { while (iter.hasNext()) {
BlockVector2 chunk = iter.next(); BlockVector2 chunk = iter.next();
iter.remove(); iter.remove();
@ -474,6 +475,7 @@ public class HybridUtils {
Iterator<BlockVector2> iterator = chunks.iterator(); Iterator<BlockVector2> iterator = chunks.iterator();
if (chunks.size() >= 32) { if (chunks.size() >= 32) {
QueueCoordinator queue = blockQueue.getNewQueue(worldUtil.getWeWorld(area.getWorldName())); QueueCoordinator queue = blockQueue.getNewQueue(worldUtil.getWeWorld(area.getWorldName()));
queue.setShouldGen(false);
for (int i = 0; i < 32; i++) { for (int i = 0; i < 32; i++) {
final BlockVector2 chunk = iterator.next(); final BlockVector2 chunk = iterator.next();
iterator.remove(); iterator.remove();
@ -487,6 +489,7 @@ public class HybridUtils {
return null; return null;
} }
QueueCoordinator queue = blockQueue.getNewQueue(worldUtil.getWeWorld(area.getWorldName())); QueueCoordinator queue = blockQueue.getNewQueue(worldUtil.getWeWorld(area.getWorldName()));
queue.setShouldGen(false);
while (!chunks.isEmpty()) { while (!chunks.isEmpty()) {
final BlockVector2 chunk = iterator.next(); final BlockVector2 chunk = iterator.next();
iterator.remove(); iterator.remove();
@ -502,7 +505,6 @@ public class HybridUtils {
return; return;
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace();
Iterator<BlockVector2> iterator = HybridUtils.regions.iterator(); Iterator<BlockVector2> iterator = HybridUtils.regions.iterator();
BlockVector2 loc = iterator.next(); BlockVector2 loc = iterator.next();
iterator.remove(); iterator.remove();
@ -510,7 +512,8 @@ public class HybridUtils {
"Error! Could not update '{}/region/r.{}.{}.mca' (Corrupt chunk?)", "Error! Could not update '{}/region/r.{}.{}.mca' (Corrupt chunk?)",
area.getWorldHash(), area.getWorldHash(),
loc.getX(), loc.getX(),
loc.getZ() loc.getZ(),
e
); );
} }
TaskManager.runTaskLater(task, TaskTime.seconds(1L)); TaskManager.runTaskLater(task, TaskTime.seconds(1L));
@ -558,7 +561,7 @@ public class HybridUtils {
try { try {
plotworld.setupSchematics(); plotworld.setupSchematics();
} catch (SchematicHandler.UnsupportedFormatException e) { } catch (SchematicHandler.UnsupportedFormatException e) {
e.printStackTrace(); LOGGER.error(e);
} }
}); });
}); });

View File

@ -40,7 +40,8 @@ public interface ChunkCoordinatorFactory {
final @NonNull Consumer<Throwable> throwableConsumer, final @NonNull Consumer<Throwable> throwableConsumer,
@Assisted("unloadAfter") final boolean unloadAfter, @Assisted("unloadAfter") final boolean unloadAfter,
final @NonNull Collection<ProgressSubscriber> progressSubscribers, final @NonNull Collection<ProgressSubscriber> progressSubscribers,
@Assisted("forceSync") final boolean forceSync @Assisted("forceSync") final boolean forceSync,
@Assisted("shouldGen") final boolean shouldGen
); );
} }

View File

@ -1407,6 +1407,9 @@ public class Plot {
); );
} }
Location location = toHomeLocation(bottom, home); Location location = toHomeLocation(bottom, home);
if (Settings.Teleport.SIZED_BASED && this.worldUtil.isSmallBlock(location) && this.worldUtil.isSmallBlock(location.add(0,1,0))) {
return location;
}
if (!this.worldUtil.getBlockSynchronous(location).getBlockType().getMaterial().isAir()) { if (!this.worldUtil.getBlockSynchronous(location).getBlockType().getMaterial().isAir()) {
location = location.withY( location = location.withY(
Math.max(1 + this.worldUtil.getHighestBlockSynchronous( Math.max(1 + this.worldUtil.getHighestBlockSynchronous(
@ -1440,15 +1443,21 @@ public class Plot {
} }
Location bottom = this.getBottomAbs(); Location bottom = this.getBottomAbs();
Location location = toHomeLocation(bottom, home); Location location = toHomeLocation(bottom, home);
this.worldUtil.getBlock(location, block -> { if (Settings.Teleport.SIZED_BASED && this.worldUtil.isSmallBlock(location) && this.worldUtil.isSmallBlock(location.add(0,1,0))) {
if (!block.getBlockType().getMaterial().isAir()) { result.accept(location);
this.worldUtil.getHighestBlock(this.getWorldName(), location.getX(), location.getZ(), } else {
y -> result.accept(location.withY(Math.max(1 + y, bottom.getY()))) this.worldUtil.getBlock(location, block -> {
);
} else { if (!block.getBlockType().getMaterial().isAir()) {
result.accept(location); this.worldUtil.getHighestBlock(this.getWorldName(), location.getX(), location.getZ(),
} y -> result.accept(location.withY(Math.max(1 + y, bottom.getY())))
}); );
} else {
result.accept(location);
}
});
}
} }
} }

View File

@ -65,6 +65,7 @@ import com.plotsquared.core.plot.flag.implementations.HostileInteractFlag;
import com.plotsquared.core.plot.flag.implementations.IceFormFlag; import com.plotsquared.core.plot.flag.implementations.IceFormFlag;
import com.plotsquared.core.plot.flag.implementations.IceMeltFlag; import com.plotsquared.core.plot.flag.implementations.IceMeltFlag;
import com.plotsquared.core.plot.flag.implementations.InstabreakFlag; import com.plotsquared.core.plot.flag.implementations.InstabreakFlag;
import com.plotsquared.core.plot.flag.implementations.InteractionInteractFlag;
import com.plotsquared.core.plot.flag.implementations.InvincibleFlag; import com.plotsquared.core.plot.flag.implementations.InvincibleFlag;
import com.plotsquared.core.plot.flag.implementations.ItemDropFlag; import com.plotsquared.core.plot.flag.implementations.ItemDropFlag;
import com.plotsquared.core.plot.flag.implementations.KeepFlag; import com.plotsquared.core.plot.flag.implementations.KeepFlag;
@ -92,6 +93,7 @@ import com.plotsquared.core.plot.flag.implementations.PreventCreativeCopyFlag;
import com.plotsquared.core.plot.flag.implementations.PriceFlag; import com.plotsquared.core.plot.flag.implementations.PriceFlag;
import com.plotsquared.core.plot.flag.implementations.ProjectileChangeBlockFlag; import com.plotsquared.core.plot.flag.implementations.ProjectileChangeBlockFlag;
import com.plotsquared.core.plot.flag.implementations.ProjectilesFlag; import com.plotsquared.core.plot.flag.implementations.ProjectilesFlag;
import com.plotsquared.core.plot.flag.implementations.WeavingDeathPlace;
import com.plotsquared.core.plot.flag.implementations.PveFlag; import com.plotsquared.core.plot.flag.implementations.PveFlag;
import com.plotsquared.core.plot.flag.implementations.PvpFlag; import com.plotsquared.core.plot.flag.implementations.PvpFlag;
import com.plotsquared.core.plot.flag.implementations.RedstoneFlag; import com.plotsquared.core.plot.flag.implementations.RedstoneFlag;
@ -171,6 +173,7 @@ public final class GlobalFlagContainer extends FlagContainer {
this.addFlag(IceFormFlag.ICE_FORM_FALSE); this.addFlag(IceFormFlag.ICE_FORM_FALSE);
this.addFlag(IceMeltFlag.ICE_MELT_FALSE); this.addFlag(IceMeltFlag.ICE_MELT_FALSE);
this.addFlag(InstabreakFlag.INSTABREAK_FALSE); this.addFlag(InstabreakFlag.INSTABREAK_FALSE);
this.addFlag(InteractionInteractFlag.INTERACTION_INTERACT_FALSE);
this.addFlag(InvincibleFlag.INVINCIBLE_FALSE); this.addFlag(InvincibleFlag.INVINCIBLE_FALSE);
this.addFlag(ItemDropFlag.ITEM_DROP_TRUE); this.addFlag(ItemDropFlag.ITEM_DROP_TRUE);
this.addFlag(KeepInventoryFlag.KEEP_INVENTORY_FALSE); this.addFlag(KeepInventoryFlag.KEEP_INVENTORY_FALSE);
@ -207,6 +210,7 @@ public final class GlobalFlagContainer extends FlagContainer {
this.addFlag(VillagerInteractFlag.VILLAGER_INTERACT_FALSE); this.addFlag(VillagerInteractFlag.VILLAGER_INTERACT_FALSE);
this.addFlag(VineGrowFlag.VINE_GROW_TRUE); this.addFlag(VineGrowFlag.VINE_GROW_TRUE);
this.addFlag(ProjectilesFlag.PROJECTILES_FALSE); this.addFlag(ProjectilesFlag.PROJECTILES_FALSE);
this.addFlag(WeavingDeathPlace.WEAVING_DEATH_PLACE_FALSE);
// Double flags // Double flags
this.addFlag(PriceFlag.PRICE_NOT_BUYABLE); this.addFlag(PriceFlag.PRICE_NOT_BUYABLE);

View File

@ -0,0 +1,39 @@
/*
* 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.plot.flag.implementations;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.plot.flag.types.BooleanFlag;
import org.checkerframework.checker.nullness.qual.NonNull;
public class InteractionInteractFlag extends BooleanFlag<InteractionInteractFlag> {
public static final InteractionInteractFlag INTERACTION_INTERACT_TRUE = new InteractionInteractFlag(true);
public static final InteractionInteractFlag INTERACTION_INTERACT_FALSE = new InteractionInteractFlag(false);
private InteractionInteractFlag(boolean value) {
super(value, TranslatableCaption.of("flags.flag_description_interaction_interact"));
}
@Override
protected InteractionInteractFlag flagOf(@NonNull Boolean value) {
return value ? INTERACTION_INTERACT_TRUE : INTERACTION_INTERACT_FALSE;
}
}

View File

@ -0,0 +1,39 @@
/*
* 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.plot.flag.implementations;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.plot.flag.types.BooleanFlag;
import org.checkerframework.checker.nullness.qual.NonNull;
public class WeavingDeathPlace extends BooleanFlag<WeavingDeathPlace> {
public static final WeavingDeathPlace WEAVING_DEATH_PLACE_TRUE = new WeavingDeathPlace(true);
public static final WeavingDeathPlace WEAVING_DEATH_PLACE_FALSE = new WeavingDeathPlace(false);
private WeavingDeathPlace(boolean value) {
super(value, TranslatableCaption.of("flags.flag_description_weaving_death_place"));
}
@Override
protected WeavingDeathPlace flagOf(@NonNull Boolean value) {
return value ? WEAVING_DEATH_PLACE_TRUE : WEAVING_DEATH_PLACE_FALSE;
}
}

View File

@ -52,6 +52,7 @@ public class ChunkCoordinatorBuilder {
private int initialBatchSize = Settings.QUEUE.INITIAL_BATCH_SIZE; private int initialBatchSize = Settings.QUEUE.INITIAL_BATCH_SIZE;
private boolean unloadAfter = true; private boolean unloadAfter = true;
private boolean forceSync = false; private boolean forceSync = false;
private boolean shouldGen = true;
@Inject @Inject
public ChunkCoordinatorBuilder(@NonNull ChunkCoordinatorFactory chunkCoordinatorFactory) { public ChunkCoordinatorBuilder(@NonNull ChunkCoordinatorFactory chunkCoordinatorFactory) {
@ -203,6 +204,19 @@ public class ChunkCoordinatorBuilder {
return this; return this;
} }
/**
* Set whether chunks should be generated as part of this operation. Default is true. Disabling this may not be supported
* depending on server implementation. (i.e. setting to false may not actually disable generation as part of this operation
* - this is just a catch-all in case of future differing server implementations; the option will work on Spigot/Paper).
*
* @param shouldGen should generate new chunks or not
* @since 7.5.0
*/
public @NonNull ChunkCoordinatorBuilder shouldGen(final boolean shouldGen) {
this.shouldGen = shouldGen;
return this;
}
public @NonNull ChunkCoordinatorBuilder withProgressSubscriber(ProgressSubscriber progressSubscriber) { public @NonNull ChunkCoordinatorBuilder withProgressSubscriber(ProgressSubscriber progressSubscriber) {
this.progressSubscribers.add(progressSubscriber); this.progressSubscribers.add(progressSubscriber);
return this; return this;
@ -234,7 +248,8 @@ public class ChunkCoordinatorBuilder {
this.throwableConsumer, this.throwableConsumer,
this.unloadAfter, this.unloadAfter,
this.progressSubscribers, this.progressSubscribers,
this.forceSync this.forceSync,
this.shouldGen
); );
} }

View File

@ -51,6 +51,7 @@ public class DelegateQueueCoordinator extends QueueCoordinator {
if (parent != null) { if (parent != null) {
this.setForceSync(parent.isForceSync()); this.setForceSync(parent.isForceSync());
this.setShouldGen(parent.isShouldGen());
} }
} }

View File

@ -45,6 +45,7 @@ public abstract class QueueCoordinator {
private final AtomicBoolean enqueued = new AtomicBoolean(); private final AtomicBoolean enqueued = new AtomicBoolean();
private boolean forceSync = false; private boolean forceSync = false;
private boolean shouldGen = true;
@Nullable @Nullable
private Object chunkObject; private Object chunkObject;
@SuppressWarnings({"unused", "FieldCanBeLocal"}) @SuppressWarnings({"unused", "FieldCanBeLocal"})
@ -110,6 +111,30 @@ public abstract class QueueCoordinator {
this.forceSync = forceSync; this.forceSync = forceSync;
} }
/**
* Get whether chunks should be generated as part of this operation. Default is true. Disabling this may not be supported
* depending on server implementation. (i.e. setting to false may not actually disable generation as part of this operation
* - this is just a catch-all in case of future differing server implementations; the option will work on Spigot/Paper).
*
* @since 7.5.0
*/
public boolean isShouldGen() {
return shouldGen;
}
/**
* Set whether chunks should be generated as part of this operation. Default is true. Disabling this may not be supported
* depending on server implementation. (i.e. setting to false may not actually disable generation as part of this operation
* - this is just a catch-all in case of future differing server implementations; the option will work on Spigot/Paper).
*
* @param shouldGen should generate new chunks or not
* @since 7.5.0
*/
public void setShouldGen(boolean shouldGen) {
this.shouldGen = shouldGen;
}
/** /**
* Get the Chunk Object set to the queue * Get the Chunk Object set to the queue
* *

View File

@ -371,7 +371,10 @@ public class EventDispatcher {
Location location, BlockType blockType, boolean notifyPerms Location location, BlockType blockType, boolean notifyPerms
) { ) {
PlotArea area = location.getPlotArea(); PlotArea area = location.getPlotArea();
assert area != null; // the interaction target location might be outside a plot area
if (area == null) {
return true;
}
if (!area.buildRangeContainsY(location.getY()) && !player.hasPermission(Permission.PERMISSION_ADMIN_BUILD_HEIGHT_LIMIT)) { if (!area.buildRangeContainsY(location.getY()) && !player.hasPermission(Permission.PERMISSION_ADMIN_BUILD_HEIGHT_LIMIT)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("height.height_limit"), TranslatableCaption.of("height.height_limit"),

View File

@ -107,6 +107,7 @@ public final class TabCompletions {
} }
public static @NonNull List<Command> completePlayersInPlot( public static @NonNull List<Command> completePlayersInPlot(
final @NonNull PlotPlayer<?> issuer,
final @NonNull Plot plot, final @NonNull Plot plot,
final @NonNull String input, final @NonNull List<String> existing final @NonNull String input, final @NonNull List<String> existing
) { ) {
@ -115,7 +116,9 @@ public final class TabCompletions {
final List<PlotPlayer<?>> inPlot = plot.getPlayersInPlot(); final List<PlotPlayer<?>> inPlot = plot.getPlayersInPlot();
players = new ArrayList<>(inPlot.size()); players = new ArrayList<>(inPlot.size());
for (PlotPlayer<?> player : inPlot) { for (PlotPlayer<?> player : inPlot) {
players.add(player.getName()); if (issuer.canSee(player)) {
players.add(player.getName());
}
} }
cachedCompletionValues.put("inPlot" + plot, players); cachedCompletionValues.put("inPlot" + plot, players);
} }

View File

@ -177,6 +177,13 @@ public abstract class WorldUtil {
*/ */
public abstract void getBlock(@NonNull Location location, @NonNull Consumer<BlockState> result); public abstract void getBlock(@NonNull Location location, @NonNull Consumer<BlockState> result);
/**
* Checks if the block smaller as a slab
* @param location Block location
* @return true if it smaller as a slab
*/
public abstract boolean isSmallBlock(@NonNull Location location);
/** /**
* Get the block at a given location (synchronously) * Get the block at a given location (synchronously)
* *

View File

@ -41,6 +41,7 @@ public class EntityCategories {
public static final EntityCategory PROJECTILE = register("projectile"); public static final EntityCategory PROJECTILE = register("projectile");
public static final EntityCategory OTHER = register("other"); public static final EntityCategory OTHER = register("other");
public static final EntityCategory PLAYER = register("player"); public static final EntityCategory PLAYER = register("player");
public static final EntityCategory INTERACTION = register("interaction");
public static EntityCategory register(final String id) { public static EntityCategory register(final String id) {
final EntityCategory entityCategory = new EntityCategory(PlotSquared.platform().worldUtil(), id); final EntityCategory entityCategory = new EntityCategory(PlotSquared.platform().worldUtil(), id);

View File

@ -572,6 +572,7 @@
"flags.flag_description_ice_form": "<gray>Set to `true` to allow ice to form in the plot.</gray>", "flags.flag_description_ice_form": "<gray>Set to `true` to allow ice to form in the plot.</gray>",
"flags.flag_description_ice_melt": "<gray>Set to `false` to disable ice melting in the plot.</gray>", "flags.flag_description_ice_melt": "<gray>Set to `false` to disable ice melting in the plot.</gray>",
"flags.flag_description_instabreak": "<gray>Set to `true` to allow blocks to be instantaneously broken in survival mode.</gray>", "flags.flag_description_instabreak": "<gray>Set to `true` to allow blocks to be instantaneously broken in survival mode.</gray>",
"flags.flag_description_interaction_interact": "<gray>Set to `true` to allow guests to interact with interaction entities in the plot.</gray>",
"flags.flag_description_invincible": "<gray>Set to `true` to prevent players from taking damage inside the plot.</gray>", "flags.flag_description_invincible": "<gray>Set to `true` to prevent players from taking damage inside the plot.</gray>",
"flags.flag_description_item_drop": "<gray>Set to `false` to prevent items from being dropped inside the plot.</gray>", "flags.flag_description_item_drop": "<gray>Set to `false` to prevent items from being dropped inside the plot.</gray>",
"flags.flag_description_kelp_grow": "<gray>Set to `false` to prevent kelp from growing in the plot.</gray>", "flags.flag_description_kelp_grow": "<gray>Set to `false` to prevent kelp from growing in the plot.</gray>",
@ -628,6 +629,7 @@
"flags.flag_description_prevent_creative_copy": "<gray>Prevents people from copying item NBT data in the plot unless they're added as members.</gray>", "flags.flag_description_prevent_creative_copy": "<gray>Prevents people from copying item NBT data in the plot unless they're added as members.</gray>",
"flags.flag_description_leaf_decay": "<gray>Set to `false` to prevent leaves from decaying.", "flags.flag_description_leaf_decay": "<gray>Set to `false` to prevent leaves from decaying.",
"flags.flag_description_projectiles": "<gray>Prevents guests from shooting projectiles on the plot when set to false.</gray>", "flags.flag_description_projectiles": "<gray>Prevents guests from shooting projectiles on the plot when set to false.</gray>",
"flags.flag_description_weaving_death_place": "<gray>Set to `false` to prevent spawning of cobwebs by the Weaving status effect on the death of an entity.</gray>",
"flags.flag_description_beacon_effect": "<gray>Enables beacon effects on the plot.</gray>", "flags.flag_description_beacon_effect": "<gray>Enables beacon effects on the plot.</gray>",
"flags.flag_error_boolean": "Flag value must be a boolean (true | false).", "flags.flag_error_boolean": "Flag value must be a boolean (true | false).",
"flags.flag_error_enum": "Must be one of: <list>", "flags.flag_error_enum": "Must be one of: <list>",

View File

@ -22,7 +22,7 @@ plugins {
} }
group = "com.intellectualsites.plotsquared" group = "com.intellectualsites.plotsquared"
version = "7.3.10-SNAPSHOT" version = "7.5.2-SNAPSHOT"
if (!File("$rootDir/.git").exists()) { if (!File("$rootDir/.git").exists()) {
logger.lifecycle(""" logger.lifecycle("""
@ -79,8 +79,8 @@ subprojects {
dependencies { dependencies {
// Tests // Tests
testImplementation("org.junit.jupiter:junit-jupiter:5.11.0") testImplementation("org.junit.jupiter:junit-jupiter:5.12.0")
testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.11.0") testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.12.0")
} }
plugins.withId("java") { plugins.withId("java") {
@ -230,7 +230,7 @@ tasks.getByName<Jar>("jar") {
enabled = false enabled = false
} }
val supportedVersions = listOf("1.18.2", "1.19.4", "1.20.6", "1.21.1") val supportedVersions = listOf("1.19.4", "1.20.6", "1.21.1", "1.21.3", "1.21.4")
tasks { tasks {
register("cacheLatestFaweArtifact") { register("cacheLatestFaweArtifact") {
val lastSuccessfulBuildUrl = uri("https://ci.athion.net/job/FastAsyncWorldEdit/lastSuccessfulBuild/api/json").toURL() val lastSuccessfulBuildUrl = uri("https://ci.athion.net/job/FastAsyncWorldEdit/lastSuccessfulBuild/api/json").toURL()

View File

@ -2,18 +2,18 @@
# Platform expectations # Platform expectations
paper = "1.20.4-R0.1-SNAPSHOT" paper = "1.20.4-R0.1-SNAPSHOT"
guice = "7.0.0" guice = "7.0.0"
spotbugs = "4.8.6" spotbugs = "4.9.1"
checkerqual = "3.46.0" checkerqual = "3.49.0"
gson = "2.10" gson = "2.10"
guava = "31.1-jre" guava = "31.1-jre"
snakeyaml = "2.0" snakeyaml = "2.0"
adventure = "4.17.0" adventure = "4.19.0"
adventure-bukkit = "4.3.4" adventure-bukkit = "4.3.4"
log4j = "2.19.0" log4j = "2.19.0"
# Plugins # Plugins
worldedit = "7.2.20" worldedit = "7.2.20"
fawe = "2.11.0" fawe = "2.13.0"
placeholderapi = "2.11.6" placeholderapi = "2.11.6"
luckperms = "5.4" luckperms = "5.4"
essentialsx = "2.20.1" essentialsx = "2.20.1"
@ -26,18 +26,18 @@ cloud-services = "1.8.4"
arkitektonika = "2.1.3" arkitektonika = "2.1.3"
squirrelid = "0.3.2" squirrelid = "0.3.2"
paster = "1.1.6" paster = "1.1.6"
bstats = "3.0.2" bstats = "3.1.0"
paperlib = "1.0.8" paperlib = "1.0.8"
informative-annotations = "1.5" informative-annotations = "1.5"
vault = "1.7.1" vault = "1.7.1"
serverlib = "2.3.6" serverlib = "2.3.6"
# Gradle plugins # Gradle plugins
shadow = "8.1.1" shadow = "8.3.6"
grgit = "4.1.1" grgit = "4.1.1"
spotless = "6.25.0" spotless = "7.0.2"
nexus = "2.0.0" nexus = "2.0.0"
runPaper = "2.3.0" runPaper = "2.3.1"
[libraries] [libraries]
# Platform expectations # Platform expectations
@ -78,7 +78,7 @@ vault = { group = "com.github.MilkBowl", name = "VaultAPI", version.ref = "vault
serverlib = { group = "dev.notmyfault.serverlib", name = "ServerLib", version.ref = "serverlib" } serverlib = { group = "dev.notmyfault.serverlib", name = "ServerLib", version.ref = "serverlib" }
[plugins] [plugins]
shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" } shadow = { id = "com.gradleup.shadow", version.ref = "shadow" }
grgit = { id = "org.ajoberstar.grgit", version.ref = "grgit" } grgit = { id = "org.ajoberstar.grgit", version.ref = "grgit" }
spotless = { id = "com.diffplug.spotless", version.ref = "spotless" } spotless = { id = "com.diffplug.spotless", version.ref = "spotless" }
nexus = { id = "io.github.gradle-nexus.publish-plugin", version.ref = "nexus" } nexus = { id = "io.github.gradle-nexus.publish-plugin", version.ref = "nexus" }

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

3
gradlew vendored
View File

@ -86,8 +86,7 @@ done
# shellcheck disable=SC2034 # shellcheck disable=SC2034
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum

View File

@ -1,4 +1,4 @@
Javadocs generated for Javadocs generated for
<a href="https://github.com/IntellectualSites/PlotSquared/" rel="noopener nofollow noreferrer" target="_blank"> PlotSquared</a> | <a href="https://github.com/IntellectualSites/PlotSquared/" rel="noopener nofollow noreferrer" target="_blank"> PlotSquared</a> |
<a href="https://intellectualsites.gitbook.io/plotsquared/" rel="noopener nofollow noreferrer"> Documentation </a> | <a href="https://intellectualsites.gitbook.io/plotsquared/" rel="noopener nofollow noreferrer"> Documentation </a> |
Visit us on our <a href="https://discord.gg/intellectualsites" rel="noopener nofollow noreferrer"> Discord server</a> :) &nbsp;Visit us on our <a href="https://discord.gg/intellectualsites" rel="noopener nofollow noreferrer"> Discord server</a> :)