Compare commits

..

35 Commits

Author SHA1 Message Date
Pierre Maurice Schwang
6c06d5f11d chore: start work on flexible entity type wrapper 2025-10-27 22:09:55 +01:00
Pigaut
df15203f2b Ignore already cancelled block breaks to improve plugin compatibility (#4781) 2025-10-26 20:54:10 +01:00
Jordan
f5696b7671 feat: add a placeholder to provide the absolute plot's x/y (#4741) 2025-10-25 10:15:15 +01:00
Jordan
9ed0c7fa13 feat: allow gen schematics to be located under the paths.schematics location (#4742)
* feat: allow gen schematics to be located under the paths.schematics location
 - closes #4408

* Fix typo
2025-10-25 10:15:03 +01:00
renovate[bot]
1f32909ffd Update fawe to v2.14.0 (#4783)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-20 00:58:28 +00:00
renovate[bot]
1785693fe4 Update dependency com.github.spotbugs:spotbugs-annotations to v4.9.8 (#4782)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-20 00:57:53 +00:00
Hannes Greule
df738b279d fix: missing fallback if current plot is not explicitly overridden (#4779) 2025-10-19 15:00:24 +02:00
renovate[bot]
b7b25252c6 Update dependency com.gradleup.shadow to v9 (#4760)
* Update dependency com.gradleup.shadow to v9

* Fix missing shadow runtimes on Gradle 9

Signed-off-by: Alexander Brandes <mc.cache@web.de>

---------

Signed-off-by: Alexander Brandes <mc.cache@web.de>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Alexander Brandes <mc.cache@web.de>
2025-10-13 20:58:00 +00:00
renovate[bot]
7123f51bb5 Update gradle/actions action to v5 (#4776)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-13 20:48:31 +00:00
renovate[bot]
897afa894e Update junit-framework monorepo to v6 (major) (#4777)
Update junit-framework monorepo to v6

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-13 20:48:17 +00:00
renovate[bot]
2238609551 Update github/codeql-action action to v4 (#4775)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-13 20:47:56 +00:00
renovate[bot]
255959232b Update Gradle to v9 (#4768)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Alexander Brandes <mc.cache@web.de>
2025-10-13 22:43:06 +02:00
FlorianMichael
622c9f1d13 fix: don't break cow shearing if mob-spawning flag is set to false (#4752) 2025-10-13 22:25:12 +02:00
renovate[bot]
e7aff3982e Update adventure to v4.25.0 (#4774)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-13 00:38:22 +00:00
renovate[bot]
db7ea780f9 Update dependency xyz.jpenilla.run-paper to v3.0.2 (#4773)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-13 00:37:50 +00:00
renovate[bot]
db188150d7 Update dependency xyz.jpenilla.run-paper to v3.0.1 (#4766)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-06 15:34:41 +00:00
renovate[bot]
cfd8401515 Update dependency org.checkerframework:checker-qual to v3.51.1 (#4765)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-06 15:34:23 +00:00
renovate[bot]
c887cbe28c Update junit-framework monorepo (#4767)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-06 17:33:19 +02:00
renovate[bot]
59183c1412 Update dependency com.diffplug.spotless to v8 (#4763)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-29 01:13:36 +00:00
renovate[bot]
439fb3a8ea Update dependency xyz.jpenilla.run-paper to v3 (#4764)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-29 01:11:55 +00:00
renovate[bot]
78d6ca1deb Update dependency com.github.spotbugs:spotbugs-annotations to v4.9.6 (#4759)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 00:41:24 +00:00
Alexander Brandes
03aa1be5a3 Back to snapshot for development
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2025-09-19 21:56:38 +02:00
Alexander Brandes
2e3832f1bd Release 7.5.8
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2025-09-19 21:55:57 +02:00
Pierre Maurice Schwang
05af41f832 fix: binary incompatibility on 1.21.1 (#4758) 2025-09-19 08:55:39 +02:00
renovate[bot]
b613318a29 Update fawe to v2.13.2 (#4754)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-15 01:06:16 +00:00
renovate[bot]
c2f8356042 Update dependency org.checkerframework:checker-qual to v3.51.0 (#4755)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-15 01:05:57 +00:00
Alexander Brandes
109e6059f8 Back to snapshot for development
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2025-09-09 21:56:03 +02:00
Alexander Brandes
f01c287f89 Release 7.5.7
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2025-09-09 21:55:30 +02:00
renovate[bot]
fd8cf3c475 Update dependency org.checkerframework:checker-qual to v3.50.0 (#4749)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-08 01:36:33 +00:00
renovate[bot]
8c9957edeb Update actions/setup-java action to v5 (#4750)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-08 01:36:15 +00:00
Jordan
aaba2b5b1a fix: improve error handling in backups (#4740)
* fix: improve error handling in backups
 - fixes #4460

* cleanup

* Update Core/src/main/java/com/plotsquared/core/backup/Backup.java

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Alexander Brandes <mc.cache@web.de>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-01 20:29:52 +02:00
Jordan
02a65c8855 fix: use PlotPlayer#getCurrentPlot across commands to allow /<command> <id> usage (#4738)
* fix: use PlotPlayer#getCurrentPlot across commands to allow /<command> <id> usage
 - fixes #4526
 - supersedes #4675

* cleanup
2025-08-30 20:33:13 +02:00
Jordan
8a5fa26796 fix: allow extended world height when teleporting player on join (#4739) 2025-08-30 20:32:40 +02:00
renovate[bot]
13cbb7e083 Update actions/checkout action to v5 (#4746)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-25 01:08:14 +00:00
EnZaXD
4d8d5b3a9f fix: special handle thrown eggs for projectile hit checks (#4728)
Cancelling the ProjectileHitEvent will not cover for thrown eggs spawning chickens due to how Bukkit has these events structured. The provided patch calls the same code used for normal projectiles in the specialized egg event to prevent unwanted chickens from spawning on other plots.

Signed-off-by: FlorianMichael <florian.michael07@gmail.com>
2025-08-23 13:08:28 +02:00
60 changed files with 894 additions and 604 deletions

View File

@@ -9,11 +9,11 @@ jobs:
os: [ ubuntu-latest, windows-latest, macos-latest ]
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@v4
uses: gradle/actions/wrapper-validation@v5
- name: Setup Java
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21

View File

@@ -9,11 +9,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@v4
uses: gradle/actions/wrapper-validation@v5
- name: Setup Java
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21

View File

@@ -20,17 +20,17 @@ jobs:
language: [ 'java' ]
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Setup Java
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
- name: Autobuild
uses: github/codeql-action/autobuild@v3
uses: github/codeql-action/autobuild@v4
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v4

View File

@@ -17,6 +17,19 @@ repositories {
}
}
// Make sure we control the exact version of paper being included, while dropping spigot + bukkit
configurations.all {
exclude("org.bukkit")
exclude("org.spigotmc")
resolutionStrategy.eachDependency {
if (requested.group == "io.papermc.paper" && requested.name == "paper-api") {
useVersion(checkNotNull(libs.paper.orNull?.version))
because("specific paper version is required to prevent binary incompatibilities on older versions")
}
}
}
dependencies {
api(projects.plotsquaredCore)
@@ -28,20 +41,13 @@ dependencies {
implementation(libs.paperlib)
// Plugins
compileOnly(libs.worldeditBukkit) {
exclude(group = "org.bukkit")
exclude(group = "org.spigotmc")
}
compileOnly(libs.worldeditBukkit)
compileOnly(libs.faweBukkit) { isTransitive = false }
testImplementation(libs.faweBukkit) { isTransitive = false }
compileOnly(libs.vault) {
exclude(group = "org.bukkit")
}
compileOnly(libs.vault)
compileOnly(libs.placeholderapi)
compileOnly(libs.luckperms)
compileOnly(libs.essentialsx) {
exclude(group = "org.spigotmc")
}
compileOnly(libs.essentialsx)
compileOnly(libs.mvdwapi) { isTransitive = false }
// Other libraries

View File

@@ -24,6 +24,7 @@ import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Singleton;
import com.google.inject.Stage;
import com.plotsquared.bukkit.entity.EntityType;
import com.plotsquared.bukkit.generator.BukkitPlotGenerator;
import com.plotsquared.bukkit.inject.BackupModule;
import com.plotsquared.bukkit.inject.BukkitModule;
@@ -794,60 +795,29 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
if (entity.getMetadata("ps_custom_spawned").stream().anyMatch(MetadataValue::asBoolean)) {
continue;
}
// TODO: use (type) pattern matching when targeting java 21
switch (entity.getType().toString()) {
case "EGG":
case "FISHING_HOOK", "FISHING_BOBBER":
case "ENDER_SIGNAL", "EYE_OF_ENDER":
case "AREA_EFFECT_CLOUD":
case "EXPERIENCE_ORB":
case "LEASH_HITCH", "LEASH_KNOT":
case "FIREWORK", "FIREWORK_ROCKET":
case "LIGHTNING", "LIGHTNING_BOLT":
case "WITHER_SKULL":
case "UNKNOWN":
case "PLAYER":
switch (EntityType.of(entity.getType())) {
case EGG, FISHING_BOBBER, EYE_OF_ENDER, AREA_EFFECT_CLOUD, EXPERIENCE_ORB, LEASH_KNOT, FIREWORK_ROCKET,
LIGHTNING_BOLT, WITHER_SKULL, UNKNOWN, PLAYER, MANNEQUIN, BLOCK_DISPLAY, INTERACTION, ITEM_DISPLAY,
GLOW_ITEM_FRAME, TEXT_DISPLAY, OMINOUS_ITEM_SPAWNER, MARKER -> {
// non moving / unmovable
continue;
case "THROWN_EXP_BOTTLE", "EXPERIENCE_BOTTLE":
case "SPLASH_POTION", "POTION":
case "SNOWBALL":
case "SHULKER_BULLET":
case "SPECTRAL_ARROW":
case "ENDER_PEARL":
case "ARROW":
case "LLAMA_SPIT":
case "TRIDENT":
}
case EXPERIENCE_BOTTLE, SPLASH_POTION, LINGERING_POTION, SNOWBALL, SHULKER_BULLET, SPECTRAL_ARROW,
ENDER_PEARL, ARROW, LLAMA_SPIT, TRIDENT -> {
// managed elsewhere | projectile
continue;
case "ITEM_FRAME":
case "PAINTING":
}
case TNT, FALLING_BLOCK -> {
// managed elsewhere
}
case ITEM_FRAME, PAINTING -> {
// Not vehicles
continue;
case "ARMOR_STAND":
// Temporarily classify as vehicle
case "MINECART":
case "MINECART_CHEST":
case "CHEST_MINECART":
case "MINECART_COMMAND":
case "COMMAND_BLOCK_MINECART":
case "MINECART_FURNACE":
case "FURNACE_MINECART":
case "MINECART_HOPPER":
case "HOPPER_MINECART":
case "MINECART_MOB_SPAWNER":
case "SPAWNER_MINECART":
case "END_CRYSTAL":
case "ENDER_CRYSTAL": // Backwards compatibility for 1.20.4
case "MINECART_TNT":
case "TNT_MINECART":
case "CHEST_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":
}
// ARMOR_STAND temporarily classified as vehicle
case ARMOR_STAND, MINECART, CHEST_MINECART, COMMAND_BLOCK_MINECART, FURNACE_MINECART, HOPPER_MINECART,
SPAWNER_MINECART, END_CRYSTAL, TNT_MINECART, ACACIA_BOAT, BIRCH_BOAT, CHERRY_BOAT, DARK_OAK_BOAT,
JUNGLE_BOAT, MANGROVE_BOAT, OAK_BOAT, PALE_OAK_BOAT, SPRUCE_BOAT, BAMBOO_RAFT, 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) {
com.plotsquared.core.location.Location location = BukkitUtil.adapt(entity.getLocation());
Plot plot = location.getPlot();
@@ -872,22 +842,15 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
this.removeRoadEntity(entity, iterator);
}
}
continue;
case "SMALL_FIREBALL":
case "FIREBALL":
case "DRAGON_FIREBALL":
case "DROPPED_ITEM", "ITEM":
}
case SMALL_FIREBALL, FIREBALL, DRAGON_FIREBALL, ITEM, WIND_CHARGE, BREEZE_WIND_CHARGE -> {
if (Settings.Enabled_Components.KILL_ROAD_ITEMS
&& plotArea.getOwnedPlotAbs(BukkitUtil.adapt(entity.getLocation())) == null) {
this.removeRoadEntity(entity, iterator);
}
// dropped item
continue;
case "PRIMED_TNT", "TNT":
case "FALLING_BLOCK":
// managed elsewhere
continue;
case "SHULKER":
}
case SHULKER -> {
if (Settings.Enabled_Components.KILL_ROAD_MOBS && (Settings.Enabled_Components.KILL_NAMED_ROAD_MOBS || entity.getCustomName() == null)) {
LivingEntity livingEntity = (LivingEntity) entity;
List<MetadataValue> meta = entity.getMetadata("shulkerPlot");
@@ -928,80 +891,16 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
}
}
}
continue;
case "ZOMBIFIED_PIGLIN":
case "PIGLIN_BRUTE":
case "LLAMA":
case "DONKEY":
case "MULE":
case "ZOMBIE_HORSE":
case "SKELETON_HORSE":
case "HUSK":
case "ELDER_GUARDIAN":
case "WITHER_SKELETON":
case "STRAY":
case "ZOMBIE_VILLAGER":
case "EVOKER":
case "EVOKER_FANGS":
case "VEX":
case "VINDICATOR":
case "POLAR_BEAR":
case "BAT":
case "BLAZE":
case "CAVE_SPIDER":
case "CHICKEN":
case "COW":
case "CREEPER":
case "ENDERMAN":
case "ENDERMITE":
case "ENDER_DRAGON":
case "GHAST":
case "HAPPY_GHAST": // 1.21.6+
case "GHASTLING": // 1.21.6+
case "GIANT":
case "GUARDIAN":
case "HORSE":
case "IRON_GOLEM":
case "MAGMA_CUBE":
case "MUSHROOM_COW", "MOOSHROOM":
case "OCELOT":
case "PIG":
case "PIG_ZOMBIE":
case "RABBIT":
case "SHEEP":
case "SILVERFISH":
case "SKELETON":
case "SLIME":
case "SNOWMAN", "SNOW_GOLEM":
case "SPIDER":
case "SQUID":
case "VILLAGER":
case "WITCH":
case "WITHER":
case "WOLF":
case "ZOMBIE":
case "PARROT":
case "SALMON":
case "DOLPHIN":
case "TROPICAL_FISH":
case "DROWNED":
case "COD":
case "TURTLE":
case "PUFFERFISH":
case "PHANTOM":
case "ILLUSIONER":
case "CAT":
case "PANDA":
case "FOX":
case "PILLAGER":
case "TRADER_LLAMA":
case "WANDERING_TRADER":
case "RAVAGER":
case "BEE":
case "HOGLIN":
case "PIGLIN":
case "ZOGLIN":
default: {
}
case ZOMBIFIED_PIGLIN, PIGLIN_BRUTE, LLAMA, DONKEY, MULE, ZOMBIE_HORSE, SKELETON_HORSE, HUSK,
ELDER_GUARDIAN, WITHER_SKELETON, STRAY, ZOMBIE_VILLAGER, EVOKER, EVOKER_FANGS, VEX, VINDICATOR,
POLAR_BEAR, BAT, BLAZE, CAVE_SPIDER, CHICKEN, COW, CREEPER, ENDERMAN, ENDERMITE, ENDER_DRAGON, GHAST,
HAPPY_GHAST, GIANT, GUARDIAN, HORSE, IRON_GOLEM, MAGMA_CUBE, MOOSHROOM, OCELOT, PIG, RABBIT, SHEEP,
SILVERFISH, SKELETON, SLIME, SNOW_GOLEM, SPIDER, SQUID, VILLAGER, WITCH, WITHER, WOLF, ZOMBIE,
PARROT, SALMON, DOLPHIN, TROPICAL_FISH, DROWNED, COD, TURTLE, PUFFERFISH, PHANTOM, ILLUSIONER, CAT,
PANDA, FOX, PILLAGER, TRADER_LLAMA, WANDERING_TRADER, RAVAGER, BEE, HOGLIN, PIGLIN, ZOGLIN, FROG,
GOAT, WARDEN, TADPOLE, ALLAY, ARMADILLO, AXOLOTL, STRIDER, SNIFFER, CAMEL, BOGGED, COPPER_GOLEM,
GLOW_SQUID, BREEZE, CREAKING -> {
if (Settings.Enabled_Components.KILL_ROAD_MOBS) {
Location location = entity.getLocation();
if (BukkitUtil.adapt(location).isPlotRoad()) {

View File

@@ -0,0 +1,261 @@
package com.plotsquared.bukkit.entity;
import com.sk89q.worldedit.util.Enums;
import org.bukkit.entity.Entity;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.EnumMap;
/**
* Wrapper Class for Bukkit {@link org.bukkit.entity.EntityType EntityTypes}.
* <br>
* Intended for a backwards compatible way to interact with entity types. Enum Constants should always be named after the
* constants of bukkits EntityType enum in the latest supported versions. Backwards compatible enum constants identifiers
* should have a comment assigned to them, so they can be removed in future versions.
*/
@ApiStatus.Internal
public enum EntityType {
ACACIA_BOAT,
ACACIA_CHEST_BOAT,
ALLAY,
AREA_EFFECT_CLOUD,
ARMADILLO,
ARMOR_STAND,
ARROW,
AXOLOTL,
BAMBOO_CHEST_RAFT,
BAMBOO_RAFT,
BAT,
BEE,
BIRCH_BOAT,
BIRCH_CHEST_BOAT,
BLAZE,
BLOCK_DISPLAY,
BOGGED,
BREEZE,
BREEZE_WIND_CHARGE,
CAMEL,
CAT,
CAVE_SPIDER,
CHERRY_BOAT,
CHERRY_CHEST_BOAT,
// 1.20.5: MINECART_CHEST -> CHEST_MINECART
CHEST_MINECART("MINECART_CHEST"),
CHICKEN,
COD,
// 1.20.5: MINECART_COMMAND -> COMMAND_BLOCK_MINECART
COMMAND_BLOCK_MINECART("MINECART_COMMAND"),
COPPER_GOLEM,
COW,
CREAKING,
CREEPER,
DARK_OAK_BOAT,
DARK_OAK_CHEST_BOAT,
DOLPHIN,
DONKEY,
DRAGON_FIREBALL,
DROWNED,
EGG,
ELDER_GUARDIAN,
// 1.20.5: ENDER_CRYSTAL -> END_CRYSTAL
END_CRYSTAL("ENDER_CRYSTAL"),
ENDER_DRAGON,
ENDER_PEARL,
ENDERMAN,
ENDERMITE,
EVOKER,
EVOKER_FANGS,
// 1.20.5: THROWN_EXP_BOTTLE -> EXPERIENCE_BOTTLE
EXPERIENCE_BOTTLE("THROWN_EXP_BOTTLE"),
EXPERIENCE_ORB,
// 1.20.5: ENDER_SIGNAL -> EYE_OF_ENDER
EYE_OF_ENDER("ENDER_SIGNAL"),
FALLING_BLOCK,
FIREBALL,
// 1.20.5: FIREWORK -> FIREWORK_ROCKET
FIREWORK_ROCKET("FIREWORK"),
// 1.20.5: FISHING_HOOK -> FISHING_BOBBER
FISHING_BOBBER("FISHING_HOOK"),
FOX,
FROG,
// 1.20.5: MINECART_FURNACE -> FURNACE_MINECART
FURNACE_MINECART("MINECART_FURNACE"),
GHAST,
GIANT,
GLOW_ITEM_FRAME,
GLOW_SQUID,
GOAT,
GUARDIAN,
HAPPY_GHAST,
HOGLIN,
// 1.20.5: MINECART_HOPPER -> HOPPER_MINECART
HOPPER_MINECART("MINECART_HOPPER"),
HORSE,
HUSK,
ILLUSIONER,
INTERACTION,
IRON_GOLEM,
// 1.20.5: DROPPED_ITEM -> ITEM
ITEM("DROPPED_ITEM"),
ITEM_DISPLAY,
ITEM_FRAME,
JUNGLE_BOAT,
JUNGLE_CHEST_BOAT,
// 1.20.5: LEASH_HITCH -> LEASH_KNOT
LEASH_KNOT("LEASH_HITCH"),
// 1.20.5: LIGHTNING -> LIGHTNING_BOLT
LIGHTNING_BOLT("LIGHTNING"),
LINGERING_POTION,
LLAMA,
LLAMA_SPIT,
MAGMA_CUBE,
MANGROVE_BOAT,
MANGROVE_CHEST_BOAT,
MANNEQUIN,
MARKER,
MINECART,
// 1.20.5: MUSHROOM_COW -> MOOSHROOM
MOOSHROOM("MUSHROOM_COW"),
MULE,
// 1.21.3: BOAT -> boat subvariants (oak, dark_oak, ...)
OAK_BOAT("BOAT"),
// 1.21.3: CHEST_BOAT -> chest boat subvariants (oak, dark_oak, ...)
OAK_CHEST_BOAT("CHEST_BOAT"),
OCELOT,
OMINOUS_ITEM_SPAWNER,
PAINTING,
PALE_OAK_BOAT,
PALE_OAK_CHEST_BOAT,
PANDA,
PARROT,
PHANTOM,
PIG,
PIGLIN,
PIGLIN_BRUTE,
PILLAGER,
PLAYER,
POLAR_BEAR,
PUFFERFISH,
RABBIT,
RAVAGER,
SALMON,
SHEEP,
SHULKER,
SHULKER_BULLET,
SILVERFISH,
SKELETON,
SKELETON_HORSE,
SLIME,
SMALL_FIREBALL,
SNIFFER,
// 1.20.5: SNOWMAN -> SNOW_GOLEM
SNOW_GOLEM("SNOWMAN"),
SNOWBALL,
// 1.20.5: MINECART_MOB_SPAWNER -> SPAWNER_MINECART
SPAWNER_MINECART("MINECART_MOB_SPAWNER"),
SPECTRAL_ARROW,
SPIDER,
// 1.21.5: POTION -> SPLASH_POTION + LINGERING_POTION (use SPLASH_POTION FOR compatibility)
SPLASH_POTION("POTION"),
SPRUCE_BOAT,
SPRUCE_CHEST_BOAT,
SQUID,
STRAY,
STRIDER,
TADPOLE,
TEXT_DISPLAY,
// 1.20.5: PRIMED_TNT -> TNT
TNT("PRIMED_TNT"),
// 1.20.5: MINECART_TNT -> TNT_MINECART
TNT_MINECART("MINECART_TNT"),
TRADER_LLAMA,
TRIDENT,
TROPICAL_FISH,
TURTLE,
UNKNOWN,
VEX,
VILLAGER,
VINDICATOR,
WANDERING_TRADER,
WARDEN,
WIND_CHARGE,
WITCH,
WITHER,
WITHER_SKELETON,
WITHER_SKULL,
WOLF,
ZOGLIN,
ZOMBIE,
ZOMBIE_HORSE,
ZOMBIE_VILLAGER,
ZOMBIFIED_PIGLIN;
private static final Logger LOGGER = LoggerFactory.getLogger("PlotSquared/" + EntityType.class.getSimpleName());
private static final EnumMap<org.bukkit.entity.EntityType, EntityType> BUKKIT_TO_INTERNAL =
new EnumMap<>(org.bukkit.entity.EntityType.class);
private final org.bukkit.entity.EntityType bukkitType;
EntityType(final String... additionalBukkitEnumFields) {
org.bukkit.entity.EntityType temp = null;
try {
temp = org.bukkit.entity.EntityType.valueOf(name());
} catch (IllegalArgumentException ignored) {
if (additionalBukkitEnumFields.length > 0) {
temp = Enums.findByValue(org.bukkit.entity.EntityType.class, additionalBukkitEnumFields);
}
}
bukkitType = temp;
}
public @Nullable org.bukkit.entity.EntityType bukkitType() {
return bukkitType;
}
public boolean isAlive() {
return this.bukkitType != null && this.bukkitType.isAlive();
}
public boolean isSpawnable() {
return this.bukkitType != null && this.bukkitType.isSpawnable();
}
@Override
public String toString() {
return "EntityType{name=" + name() + "}";
}
public static EntityType of(org.bukkit.entity.EntityType bukkitType) {
return BUKKIT_TO_INTERNAL.get(bukkitType);
}
public static EntityType of(Entity entity) {
return of(entity.getType());
}
static {
// Register all entity types with their aliases
for (final EntityType value : values()) {
org.bukkit.entity.EntityType bukkitType = value.bukkitType();
if (bukkitType != null) {
BUKKIT_TO_INTERNAL.put(bukkitType, value);
}
}
// Make sure this wrapper contains EVERY possible entity type available by the server
for (final org.bukkit.entity.EntityType bukkitType : org.bukkit.entity.EntityType.values()) {
if (!BUKKIT_TO_INTERNAL.containsKey(bukkitType)) {
LOGGER.error(
"EntityType {} provided by server has no wrapper equivalent. Is this server version supported? " +
"Falling back to 'UNKNOWN' type.",
bukkitType
);
BUKKIT_TO_INTERNAL.put(bukkitType, EntityType.UNKNOWN);
}
}
}
}

View File

@@ -21,7 +21,6 @@ package com.plotsquared.bukkit.entity;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.checkerframework.checker.nullness.qual.NonNull;
public abstract class EntityWrapper {
@@ -36,7 +35,7 @@ public abstract class EntityWrapper {
EntityWrapper(final @NonNull Entity entity) {
this.entity = entity;
this.type = entity.getType();
this.type = EntityType.of(entity.getType());
final Location location = entity.getLocation();
this.x = location.getX();
@@ -49,7 +48,7 @@ public abstract class EntityWrapper {
@SuppressWarnings("deprecation")
@Override
public String toString() {
return String.format("[%s, x=%s, y=%s, z=%s]", type.getName(), x, y, z);
return String.format("[%s, x=%s, y=%s, z=%s]", type, x, y, z);
}
public abstract Entity spawn(World world, int xOffset, int zOffset);

View File

@@ -37,6 +37,7 @@ import org.bukkit.entity.ChestBoat;
import org.bukkit.entity.ChestedHorse;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.Entity;
import org.bukkit.entity.GlowItemFrame;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Item;
import org.bukkit.entity.ItemFrame;
@@ -52,6 +53,7 @@ import org.bukkit.util.EulerAngle;
import org.bukkit.util.Vector;
import java.util.List;
import java.util.Objects;
public final class ReplicatingEntityWrapper extends EntityWrapper {
@@ -85,7 +87,7 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
return;
}
List<Entity> passengers = entity.getPassengers();
if (passengers.size() > 0) {
if (!passengers.isEmpty()) {
this.base.passenger = new ReplicatingEntityWrapper(passengers.get(0), depth);
}
this.base.fall = entity.getFallDistance();
@@ -101,44 +103,40 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
if (!entity.hasGravity()) {
this.noGravity = true;
}
switch (entity.getType().toString()) {
case "BOAT", "ACACIA_BOAT", "BIRCH_BOAT", "CHERRY_BOAT", "DARK_OAK_BOAT", "JUNGLE_BOAT", "MANGROVE_BOAT",
"OAK_BOAT", "PALE_OAK_BOAT", "SPRUCE_BOAT", "BAMBOO_RAFT" -> {
switch (EntityType.of(entity.getType())) {
case 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;
this.dataByte = getOrdinal(Boat.Type.values(), boat.getBoatType());
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" -> {
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", "END_CRYSTAL", "ENDER_CRYSTAL", "ENDER_PEARL", "ENDER_SIGNAL", "EXPERIENCE_ORB", "FALLING_BLOCK", "FIREBALL",
"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",
"THROWN_EXP_BOTTLE", "WITHER_SKULL", "UNKNOWN", "SPECTRAL_ARROW", "SHULKER_BULLET", "DRAGON_FIREBALL", "AREA_EFFECT_CLOUD",
"TRIDENT", "LLAMA_SPIT" -> {
case ARROW, EGG, END_CRYSTAL, ENDER_PEARL, EYE_OF_ENDER, EXPERIENCE_ORB, FALLING_BLOCK, FIREBALL,
FIREWORK_ROCKET, FISHING_BOBBER, LEASH_KNOT, LIGHTNING_BOLT, MINECART, COMMAND_BLOCK_MINECART,
SPAWNER_MINECART, TNT_MINECART, PLAYER, TNT, SLIME, SMALL_FIREBALL, SNOWBALL, FURNACE_MINECART, SPLASH_POTION,
EXPERIENCE_BOTTLE, WITHER_SKULL, UNKNOWN, SPECTRAL_ARROW, SHULKER_BULLET, DRAGON_FIREBALL, AREA_EFFECT_CLOUD,
TRIDENT, LLAMA_SPIT -> {
// Do this stuff later
return;
}
// MISC //
case "DROPPED_ITEM", "ITEM" -> {
case ITEM -> {
Item item = (Item) entity;
this.stack = item.getItemStack();
return;
}
case "ITEM_FRAME" -> {
case ITEM_FRAME, GLOW_ITEM_FRAME -> {
this.x = Math.floor(this.getX());
this.y = Math.floor(this.getY());
this.z = Math.floor(this.getZ());
ItemFrame itemFrame = (ItemFrame) entity;
this.dataByte = getOrdinal(Rotation.values(), itemFrame.getRotation());
this.stack = itemFrame.getItem().clone();
return;
}
case "PAINTING" -> {
case PAINTING -> {
this.x = Math.floor(this.getX());
this.y = Math.floor(this.getY());
this.z = Math.floor(this.getZ());
@@ -150,18 +148,16 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
this.y -= 1;
}
this.dataString = art.name();
return;
}
// END MISC //
// INVENTORY HOLDER //
case "MINECART_CHEST", "CHEST_MINECART", "MINECART_HOPPER", "HOPPER_MINECART" -> {
case CHEST_MINECART, HOPPER_MINECART -> {
storeInventory((InventoryHolder) entity);
return;
}
// START LIVING ENTITY //
// START AGEABLE //
// START TAMEABLE //
case "CAMEL", "HORSE", "DONKEY", "LLAMA", "TRADER_LLAMA", "MULE", "SKELETON_HORSE", "ZOMBIE_HORSE" -> {
case CAMEL, HORSE, DONKEY, LLAMA, TRADER_LLAMA, MULE, SKELETON_HORSE, ZOMBIE_HORSE -> {
AbstractHorse horse = (AbstractHorse) entity;
this.horse = new HorseStats();
this.horse.jump = horse.getJumpStrength();
@@ -176,17 +172,15 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
storeBreedable(horse);
storeLiving(horse);
storeInventory(horse);
return;
}
// END INVENTORY HOLDER //
case "WOLF", "OCELOT", "CAT", "PARROT" -> {
case WOLF, OCELOT, CAT, PARROT -> {
storeTameable((Tameable) entity);
storeBreedable((Breedable) entity);
storeLiving((LivingEntity) entity);
return;
}
// END TAMEABLE //
case "SHEEP" -> {
case SHEEP -> {
Sheep sheep = (Sheep) entity;
if (sheep.isSheared()) {
this.dataByte = (byte) 1;
@@ -196,21 +190,18 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
this.dataByte2 = getOrdinal(DyeColor.values(), sheep.getColor());
storeBreedable(sheep);
storeLiving(sheep);
return;
}
case "VILLAGER", "CHICKEN", "COW", "MUSHROOM_COW", "PIG", "TURTLE", "POLAR_BEAR" -> {
case VILLAGER, CHICKEN, COW, MOOSHROOM, PIG, TURTLE, POLAR_BEAR -> {
storeBreedable((Breedable) entity);
storeLiving((LivingEntity) entity);
return;
}
case "RABBIT" -> {
case RABBIT -> {
this.dataByte = getOrdinal(Rabbit.Type.values(), ((Rabbit) entity).getRabbitType());
storeBreedable((Breedable) entity);
storeLiving((LivingEntity) entity);
return;
}
// END AGEABLE //
case "ARMOR_STAND" -> {
case ARMOR_STAND -> {
ArmorStand stand = (ArmorStand) entity;
this.inventory =
new ItemStack[]{stand.getItemInHand().clone(), stand.getHelmet().clone(),
@@ -254,31 +245,26 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
if (stand.isSmall()) {
this.stand.small = true;
}
return;
}
case "ENDERMITE" -> {
return;
case ENDERMITE -> {
}
case "BAT" -> {
case BAT -> {
if (((Bat) entity).isAwake()) {
this.dataByte = (byte) 1;
} else {
this.dataByte = (byte) 0;
}
return;
}
case "ENDER_DRAGON" -> {
case ENDER_DRAGON -> {
EnderDragon entity1 = (EnderDragon) entity;
this.dataByte = (byte) entity1.getPhase().ordinal();
return;
}
case "SKELETON", "WITHER_SKELETON", "GUARDIAN", "ELDER_GUARDIAN", "GHAST", "HAPPY_GHAST", "GHASTLING", "MAGMA_CUBE", "SQUID", "PIG_ZOMBIE", "HOGLIN",
"ZOMBIFIED_PIGLIN", "PIGLIN", "PIGLIN_BRUTE", "ZOMBIE", "WITHER", "WITCH", "SPIDER", "CAVE_SPIDER", "SILVERFISH",
"GIANT", "ENDERMAN", "CREEPER", "BLAZE", "SHULKER", "SNOWMAN", "SNOW_GOLEM" -> {
case SKELETON, WITHER_SKELETON, GUARDIAN, ELDER_GUARDIAN, GHAST, HAPPY_GHAST, MAGMA_CUBE,
SQUID, HOGLIN, ZOMBIFIED_PIGLIN, PIGLIN, PIGLIN_BRUTE, ZOMBIE, WITHER, WITCH, SPIDER, CAVE_SPIDER, SILVERFISH,
GIANT, ENDERMAN, CREEPER, BLAZE, SHULKER, SNOW_GOLEM -> {
storeLiving((LivingEntity) entity);
return;
}
case "IRON_GOLEM" -> {
case IRON_GOLEM -> {
if (((IronGolem) entity).isPlayerCreated()) {
this.dataByte = (byte) 1;
} else {
@@ -390,8 +376,8 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
}
/**
* @deprecated Use {@link #restoreBreedable(Breedable)} instead
* @since 7.1.0
* @deprecated Use {@link #restoreBreedable(Breedable)} instead
*/
@Deprecated(forRemoval = true, since = "7.1.0")
private void restoreAgeable(Ageable entity) {
@@ -405,8 +391,8 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
}
/**
* @deprecated Use {@link #storeBreedable(Breedable)} instead
* @since 7.1.0
* @deprecated Use {@link #storeBreedable(Breedable)} instead
*/
@Deprecated(forRemoval = true, since = "7.1.0")
public void storeAgeable(Ageable aged) {
@@ -455,16 +441,17 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
return null;
}
Entity entity;
switch (this.getType().toString()) {
case "DROPPED_ITEM", "ITEM" -> {
switch (this.getType()) {
case ITEM -> {
return world.dropItem(location, this.stack);
}
case "PLAYER", "LEASH_HITCH" -> {
case PLAYER, LEASH_KNOT -> {
return null;
}
case "ITEM_FRAME" -> entity = world.spawn(location, ItemFrame.class);
case "PAINTING" -> entity = world.spawn(location, Painting.class);
default -> entity = world.spawnEntity(location, this.getType());
case ITEM_FRAME -> entity = world.spawn(location, ItemFrame.class);
case GLOW_ITEM_FRAME -> entity = world.spawn(location, GlowItemFrame.class);
case PAINTING -> entity = world.spawn(location, Painting.class);
default -> entity = world.spawnEntity(location, Objects.requireNonNull(this.getType().bukkitType()));
}
if (this.depth == 0) {
return entity;
@@ -491,16 +478,16 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
if (this.noGravity) {
entity.setGravity(false);
}
switch (entity.getType().toString()) {
case "BOAT", "ACACIA_BOAT", "BIRCH_BOAT", "CHERRY_BOAT", "DARK_OAK_BOAT", "JUNGLE_BOAT", "MANGROVE_BOAT",
"OAK_BOAT", "PALE_OAK_BOAT", "SPRUCE_BOAT", "BAMBOO_RAFT" -> {
switch (EntityType.of(entity.getType())) {
case 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.setBoatType(Boat.Type.values()[dataByte]);
return entity;
}
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" -> {
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);
@@ -511,22 +498,22 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
((Slime) entity).setSize(this.dataByte);
return entity;
} */
case "ARROW", "EGG", "END_CRYSTAL", "ENDER_CRYSTAL", "ENDER_PEARL", "ENDER_SIGNAL", "DROPPED_ITEM", "EXPERIENCE_ORB", "FALLING_BLOCK",
"FIREBALL", "FIREWORK", "FISHING_HOOK", "LEASH_HITCH", "LIGHTNING", "MINECART", "MINECART_COMMAND",
"MINECART_MOB_SPAWNER", "MINECART_TNT", "PLAYER", "PRIMED_TNT", "SMALL_FIREBALL", "SNOWBALL",
"SPLASH_POTION", "THROWN_EXP_BOTTLE", "SPECTRAL_ARROW", "SHULKER_BULLET", "AREA_EFFECT_CLOUD",
"DRAGON_FIREBALL", "WITHER_SKULL", "MINECART_FURNACE", "LLAMA_SPIT", "TRIDENT", "UNKNOWN" -> {
case ARROW, EGG, END_CRYSTAL, ENDER_PEARL, EYE_OF_ENDER, ITEM, EXPERIENCE_ORB, FALLING_BLOCK, FIREBALL,
FIREWORK_ROCKET, FISHING_BOBBER, LEASH_KNOT, LIGHTNING_BOLT, MINECART, COMMAND_BLOCK_MINECART, SPAWNER_MINECART,
TNT_MINECART, PLAYER, TNT, SMALL_FIREBALL, SNOWBALL, SPLASH_POTION, EXPERIENCE_BOTTLE, SPECTRAL_ARROW,
SHULKER_BULLET, AREA_EFFECT_CLOUD, DRAGON_FIREBALL, WITHER_SKULL, FURNACE_MINECART, LLAMA_SPIT, TRIDENT,
UNKNOWN -> {
// Do this stuff later
return entity;
}
// MISC //
case "ITEM_FRAME" -> {
case ITEM_FRAME, GLOW_ITEM_FRAME -> {
ItemFrame itemframe = (ItemFrame) entity;
itemframe.setRotation(Rotation.values()[this.dataByte]);
itemframe.setItem(this.stack);
return entity;
}
case "PAINTING" -> {
case PAINTING -> {
Painting painting = (Painting) entity;
painting.setFacingDirection(BlockFace.values()[this.dataByte], true);
painting.setArt(Art.getByName(this.dataString), true);
@@ -534,14 +521,14 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
}
// END MISC //
// INVENTORY HOLDER //
case "MINECART_CHEST", "CHEST_MINECART", "MINECART_HOPPER", "HOPPER_MINECART" -> {
case CHEST_MINECART, HOPPER_MINECART -> {
restoreInventory((InventoryHolder) entity);
return entity;
}
// START LIVING ENTITY //
// START AGEABLE //
// START TAMEABLE //
case "CAMEL", "HORSE", "DONKEY", "LLAMA", "TRADER_LLAMA", "MULE", "SKELETON_HORSE", "ZOMBIE_HORSE" -> {
case CAMEL, HORSE, DONKEY, LLAMA, TRADER_LLAMA, MULE, SKELETON_HORSE, ZOMBIE_HORSE -> {
AbstractHorse horse = (AbstractHorse) entity;
horse.setJumpStrength(this.horse.jump);
if (horse instanceof ChestedHorse) {
@@ -558,14 +545,14 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
return entity;
}
// END INVENTORY HOLDER //
case "WOLF", "OCELOT", "CAT", "PARROT" -> {
case WOLF, OCELOT, CAT, PARROT -> {
restoreTameable((Tameable) entity);
restoreBreedable((Breedable) entity);
restoreLiving((LivingEntity) entity);
return entity;
}
// END AGEABLE //
case "SHEEP" -> {
case SHEEP -> {
Sheep sheep = (Sheep) entity;
if (this.dataByte == 1) {
sheep.setSheared(true);
@@ -577,13 +564,13 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
restoreLiving(sheep);
return sheep;
}
case "VILLAGER", "CHICKEN", "COW", "TURTLE", "POLAR_BEAR", "MUSHROOM_COW", "PIG" -> {
case VILLAGER, CHICKEN, COW, TURTLE, POLAR_BEAR, MOOSHROOM, PIG -> {
restoreBreedable((Breedable) entity);
restoreLiving((LivingEntity) entity);
return entity;
}
// END AGEABLE //
case "RABBIT" -> {
case RABBIT -> {
if (this.dataByte != 0) {
((Rabbit) entity).setRabbitType(Rabbit.Type.values()[this.dataByte]);
}
@@ -591,7 +578,7 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
restoreLiving((LivingEntity) entity);
return entity;
}
case "ARMOR_STAND" -> {
case ARMOR_STAND -> {
// CHECK positions
ArmorStand stand = (ArmorStand) entity;
if (this.inventory[0] != null) {
@@ -610,41 +597,27 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
stand.setBoots(this.inventory[4]);
}
if (this.stand.head[0] != 0 || this.stand.head[1] != 0 || this.stand.head[2] != 0) {
EulerAngle pose =
new EulerAngle(this.stand.head[0], this.stand.head[1], this.stand.head[2]);
EulerAngle pose = new EulerAngle(this.stand.head[0], this.stand.head[1], this.stand.head[2]);
stand.setHeadPose(pose);
}
if (this.stand.body[0] != 0 || this.stand.body[1] != 0 || this.stand.body[2] != 0) {
EulerAngle pose =
new EulerAngle(this.stand.body[0], this.stand.body[1], this.stand.body[2]);
EulerAngle pose = new EulerAngle(this.stand.body[0], this.stand.body[1], this.stand.body[2]);
stand.setBodyPose(pose);
}
if (this.stand.leftLeg[0] != 0 || this.stand.leftLeg[1] != 0
|| this.stand.leftLeg[2] != 0) {
EulerAngle pose = new EulerAngle(this.stand.leftLeg[0], this.stand.leftLeg[1],
this.stand.leftLeg[2]
);
if (this.stand.leftLeg[0] != 0 || this.stand.leftLeg[1] != 0 || this.stand.leftLeg[2] != 0) {
EulerAngle pose = new EulerAngle(this.stand.leftLeg[0], this.stand.leftLeg[1], this.stand.leftLeg[2]);
stand.setLeftLegPose(pose);
}
if (this.stand.rightLeg[0] != 0 || this.stand.rightLeg[1] != 0
|| this.stand.rightLeg[2] != 0) {
EulerAngle pose = new EulerAngle(this.stand.rightLeg[0], this.stand.rightLeg[1],
this.stand.rightLeg[2]
);
if (this.stand.rightLeg[0] != 0 || this.stand.rightLeg[1] != 0 || this.stand.rightLeg[2] != 0) {
EulerAngle pose = new EulerAngle(this.stand.rightLeg[0], this.stand.rightLeg[1], this.stand.rightLeg[2]);
stand.setRightLegPose(pose);
}
if (this.stand.leftArm[0] != 0 || this.stand.leftArm[1] != 0
|| this.stand.leftArm[2] != 0) {
EulerAngle pose = new EulerAngle(this.stand.leftArm[0], this.stand.leftArm[1],
this.stand.leftArm[2]
);
if (this.stand.leftArm[0] != 0 || this.stand.leftArm[1] != 0 || this.stand.leftArm[2] != 0) {
EulerAngle pose = new EulerAngle(this.stand.leftArm[0], this.stand.leftArm[1], this.stand.leftArm[2]);
stand.setLeftArmPose(pose);
}
if (this.stand.rightArm[0] != 0 || this.stand.rightArm[1] != 0
|| this.stand.rightArm[2] != 0) {
EulerAngle pose = new EulerAngle(this.stand.rightArm[0], this.stand.rightArm[1],
this.stand.rightArm[2]
);
if (this.stand.rightArm[0] != 0 || this.stand.rightArm[1] != 0 || this.stand.rightArm[2] != 0) {
EulerAngle pose = new EulerAngle(this.stand.rightArm[0], this.stand.rightArm[1], this.stand.rightArm[2]);
stand.setRightArmPose(pose);
}
if (this.stand.invisible) {
@@ -662,25 +635,28 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
restoreLiving(stand);
return stand;
}
case "BAT" -> {
case BAT -> {
if (this.dataByte != 0) {
((Bat) entity).setAwake(true);
}
restoreLiving((LivingEntity) entity);
return entity;
}
case "ENDER_DRAGON" -> {
case ENDER_DRAGON -> {
if (this.dataByte != 0) {
((EnderDragon) entity).setPhase(EnderDragon.Phase.values()[this.dataByte]);
}
restoreLiving((LivingEntity) entity);
return entity;
}
case "ENDERMITE", "GHAST", "HAPPY_GHAST", "GHASTLING", "MAGMA_CUBE", "SQUID", "PIG_ZOMBIE", "HOGLIN", "PIGLIN", "ZOMBIFIED_PIGLIN", "PIGLIN_BRUTE", "ZOMBIE", "WITHER", "WITCH", "SPIDER", "CAVE_SPIDER", "SILVERFISH", "GIANT", "ENDERMAN", "CREEPER", "BLAZE", "SNOWMAN", "SHULKER", "GUARDIAN", "ELDER_GUARDIAN", "SKELETON", "WITHER_SKELETON" -> {
case ENDERMITE, GHAST, HAPPY_GHAST, MAGMA_CUBE, SQUID, HOGLIN, PIGLIN,
ZOMBIFIED_PIGLIN, PIGLIN_BRUTE, ZOMBIE, WITHER, WITCH, SPIDER, CAVE_SPIDER, SILVERFISH, GIANT,
ENDERMAN, CREEPER, BLAZE, SNOW_GOLEM, SHULKER, GUARDIAN, ELDER_GUARDIAN, SKELETON,
WITHER_SKELETON -> {
restoreLiving((LivingEntity) entity);
return entity;
}
case "IRON_GOLEM" -> {
case IRON_GOLEM -> {
if (this.dataByte != 0) {
((IronGolem) entity).setPlayerCreated(true);
}

View File

@@ -219,7 +219,7 @@ public class BlockEventListener implements Listener {
}
}
@EventHandler(priority = EventPriority.LOWEST)
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void blockDestroy(BlockBreakEvent event) {
Player player = event.getPlayer();
Location location = BukkitUtil.adapt(event.getBlock().getLocation());

View File

@@ -20,6 +20,7 @@ package com.plotsquared.bukkit.listener;
import com.google.inject.Inject;
import com.plotsquared.bukkit.BukkitPlatform;
import com.plotsquared.bukkit.entity.EntityType;
import com.plotsquared.bukkit.player.BukkitPlayer;
import com.plotsquared.bukkit.util.BukkitEntityUtil;
import com.plotsquared.bukkit.util.BukkitUtil;
@@ -52,7 +53,6 @@ import org.bukkit.block.Block;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.Boat;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
@@ -148,8 +148,8 @@ public class EntityEventListener implements Listener {
if (area == null) {
return;
}
// Armour-stands are handled elsewhere and should not be handled by area-wide entity-spawn options
if (entity.getType() == EntityType.ARMOR_STAND) {
// Armor-stands are handled elsewhere and should not be handled by area-wide entity-spawn options
if (EntityType.of(event.getEntityType()) == EntityType.ARMOR_STAND) {
return;
}
CreatureSpawnEvent.SpawnReason reason = event.getSpawnReason();
@@ -160,7 +160,7 @@ public class EntityEventListener implements Listener {
return;
}
}
case "REINFORCEMENTS", "NATURAL", "MOUNT", "PATROL", "RAID", "SHEARED", "SILVERFISH_BLOCK", "ENDER_PEARL",
case "REINFORCEMENTS", "NATURAL", "MOUNT", "PATROL", "RAID", "SILVERFISH_BLOCK", "ENDER_PEARL",
"TRAP", "VILLAGE_DEFENSE", "VILLAGE_INVASION", "BEEHIVE", "CHUNK_GEN", "NETHER_PORTAL",
"FROZEN", "SPELL", "DEFAULT" -> {
if (!area.isMobSpawning()) {
@@ -212,7 +212,7 @@ public class EntityEventListener implements Listener {
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onEntityFall(EntityChangeBlockEvent event) {
if (event.getEntityType() != EntityType.FALLING_BLOCK) {
if (EntityType.of(event.getEntityType()) != EntityType.FALLING_BLOCK) {
return;
}
Block block = event.getBlock();
@@ -278,7 +278,7 @@ public class EntityEventListener implements Listener {
@EventHandler(priority = EventPriority.HIGH)
public void onDamage(EntityDamageEvent event) {
if (event.getEntityType() != EntityType.PLAYER) {
if (EntityType.of(event.getEntityType()) != EntityType.PLAYER) {
return;
}
Location location = BukkitUtil.adapt(event.getEntity().getLocation());

View File

@@ -18,6 +18,7 @@
*/
package com.plotsquared.bukkit.listener;
import com.plotsquared.bukkit.entity.EntityType;
import com.plotsquared.bukkit.util.BukkitEntityUtil;
import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.core.PlotSquared;
@@ -33,7 +34,6 @@ import org.bukkit.block.Block;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.EnderCrystal;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Item;
import org.bukkit.entity.Vehicle;
import org.bukkit.event.EventHandler;
@@ -84,6 +84,7 @@ public class EntitySpawnListener implements Listener {
public static void test(Entity entity) {
@NonNull World world = entity.getWorld();
List<MetadataValue> meta = entity.getMetadata(KEY);
final EntityType entityType = EntityType.of(entity);
if (meta.isEmpty()) {
if (PlotSquared.get().getPlotAreaManager().hasPlotArea(world.getName())) {
entity.setMetadata(KEY, new FixedMetadataValue((Plugin) PlotSquared.platform(), entity.getLocation()));
@@ -94,7 +95,7 @@ public class EntitySpawnListener implements Listener {
if (!originWorld.equals(world)) {
if (!ignoreTP) {
if (!world.getName().equalsIgnoreCase(originWorld + "_the_end")) {
if (entity.getType() == EntityType.PLAYER) {
if (entityType == EntityType.PLAYER) {
return;
}
try {
@@ -108,7 +109,7 @@ public class EntitySpawnListener implements Listener {
}
}
} else {
if (entity.getType() == EntityType.PLAYER) {
if (entityType == EntityType.PLAYER) {
return;
}
entity.remove();
@@ -132,7 +133,7 @@ public class EntitySpawnListener implements Listener {
}
}
Plot plot = location.getOwnedPlotAbs();
EntityType type = entity.getType();
EntityType type = EntityType.of(entity);
if (plot == null) {
if (entity instanceof Item) {
if (Settings.Enabled_Components.KILL_ROAD_ITEMS) {
@@ -201,15 +202,16 @@ public class EntitySpawnListener implements Listener {
final PlotArea fromArea = fromLocLocation.getPlotArea();
Location toLocLocation = BukkitUtil.adapt(toLocation.getLocation());
PlotArea toArea = toLocLocation.getPlotArea();
final EntityType entityType = EntityType.of(entity);
if (toArea == null) {
if (fromLocation.getType() == EntityType.SHULKER && fromArea != null) {
if (entityType == EntityType.SHULKER && fromArea != null) {
event.setCancelled(true);
}
return;
}
Plot toPlot = toArea.getOwnedPlot(toLocLocation);
if (fromLocation.getType() == EntityType.SHULKER && fromArea != null) {
if (entityType == EntityType.SHULKER && fromArea != null) {
final Plot fromPlot = fromArea.getOwnedPlot(fromLocLocation);
if (fromPlot != null || toPlot != null) {
@@ -231,7 +233,7 @@ public class EntitySpawnListener implements Listener {
@EventHandler
public void spawn(CreatureSpawnEvent event) {
if (event.getEntityType() == EntityType.ARMOR_STAND) {
if (EntityType.of(event.getEntityType()) == EntityType.ARMOR_STAND) {
testCreate(event.getEntity());
}
}

View File

@@ -28,6 +28,7 @@ import com.destroystokyo.paper.event.entity.SlimePathfindEvent;
import com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent;
import com.destroystokyo.paper.event.server.AsyncTabCompleteEvent;
import com.google.inject.Inject;
import com.plotsquared.bukkit.entity.EntityType;
import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.command.Command;
@@ -55,11 +56,9 @@ import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Chunk;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Block;
import org.bukkit.block.TileState;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.Slime;
@@ -84,9 +83,6 @@ import java.util.regex.Pattern;
@SuppressWarnings("unused")
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 Chunk lastChunk;
@@ -128,7 +124,7 @@ public class PaperListener implements Listener {
return;
}
handleEntityMovement(event, event.getEntity().getLocation(), b.getLocation());
handleEntityMovement(event, event.getEntity().getLocation(), b.getLocation());
}
@EventHandler
@@ -182,8 +178,9 @@ public class PaperListener implements Listener {
if (area == null) {
return;
}
// Armour-stands are handled elsewhere and should not be handled by area-wide entity-spawn options
if (event.getType() == EntityType.ARMOR_STAND) {
final EntityType entityType = EntityType.of(event.getType());
// Armor-stands are handled elsewhere and should not be handled by area-wide entity-spawn options
if (entityType == EntityType.ARMOR_STAND) {
return;
}
// If entities are spawning... the chunk should be loaded?
@@ -202,7 +199,8 @@ public class PaperListener implements Listener {
return;
}
}
case "REINFORCEMENTS", "NATURAL", "MOUNT", "PATROL", "RAID", "SHEARED", "SILVERFISH_BLOCK", "ENDER_PEARL", "TRAP", "VILLAGE_DEFENSE", "VILLAGE_INVASION", "BEEHIVE", "CHUNK_GEN" -> {
case "REINFORCEMENTS", "NATURAL", "MOUNT", "PATROL", "RAID", "SILVERFISH_BLOCK", "ENDER_PEARL", "TRAP",
"VILLAGE_DEFENSE", "VILLAGE_INVASION", "BEEHIVE", "CHUNK_GEN" -> {
if (!area.isMobSpawning()) {
event.setShouldAbortSpawn(true);
event.setCancelled(true);
@@ -233,24 +231,23 @@ public class PaperListener implements Listener {
}
Plot plot = location.getOwnedPlotAbs();
if (plot == null) {
EntityType type = event.getType();
// PreCreatureSpawnEvent **should** not be called for DROPPED_ITEM, just for the sake of consistency
if (type.getKey().equals(ITEM)) {
if (entityType == EntityType.ITEM) {
if (Settings.Enabled_Components.KILL_ROAD_ITEMS) {
event.setCancelled(true);
}
return;
}
if (!area.isMobSpawning()) {
if (type == EntityType.PLAYER) {
if (entityType == EntityType.PLAYER) {
return;
}
if (type.isAlive()) {
if (entityType.isAlive()) {
event.setShouldAbortSpawn(true);
event.setCancelled(true);
}
}
if (!area.isMiscSpawnUnowned() && !type.isAlive()) {
if (!area.isMiscSpawnUnowned() && !entityType.isAlive()) {
event.setShouldAbortSpawn(true);
event.setCancelled(true);
}
@@ -322,6 +319,7 @@ public class PaperListener implements Listener {
return;
}
Projectile entity = event.getProjectile();
EntityType entityType = EntityType.of(entity);
ProjectileSource shooter = entity.getShooter();
if (!(shooter instanceof Player)) {
return;
@@ -361,7 +359,7 @@ public class PaperListener implements Listener {
event.setCancelled(true);
}
} else if (!plot.isAdded(pp.getUUID())) {
if (entity.getType().getKey().equals(FISHING_BOBBER)) {
if (entityType == EntityType.FISHING_BOBBER) {
if (plot.getFlag(FishingFlag.class)) {
return;
}

View File

@@ -21,6 +21,7 @@ package com.plotsquared.bukkit.listener;
import com.destroystokyo.paper.MaterialTags;
import com.google.common.base.Charsets;
import com.google.inject.Inject;
import com.plotsquared.bukkit.entity.EntityType;
import com.plotsquared.bukkit.player.BukkitPlayer;
import com.plotsquared.bukkit.util.BukkitEntityUtil;
import com.plotsquared.bukkit.util.BukkitUtil;
@@ -79,7 +80,6 @@ import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.task.TaskTime;
import com.sk89q.worldedit.WorldEdit;
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.BlockTypes;
import io.papermc.lib.PaperLib;
@@ -98,7 +98,6 @@ import org.bukkit.command.PluginCommand;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Boat;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.LivingEntity;
@@ -160,7 +159,6 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
@@ -186,14 +184,6 @@ public class PlayerEventListener implements Listener {
Material.WRITTEN_BOOK
);
/**
* The correct EntityType for End Crystal, determined once at class loading time.
* Tries END_CRYSTAL first (1.21+), falls back to ENDER_CRYSTAL (1.20.4 and older).
*/
private static final EntityType END_CRYSTAL_ENTITY_TYPE = Objects.requireNonNull(
Enums.findByValue(EntityType.class, "END_CRYSTAL", "ENDER_CRYSTAL")
);
private static final Set<String> DYES;
static {
@@ -1328,7 +1318,7 @@ public class PlayerEventListener implements Listener {
// reset the player's hand item if spawning needs to be cancelled.
if (type == Material.ARMOR_STAND || type == Material.END_CRYSTAL) {
Plot plot = location.getOwnedPlotAbs();
EntityType entityType = type == Material.ARMOR_STAND ? EntityType.ARMOR_STAND : END_CRYSTAL_ENTITY_TYPE;
EntityType entityType = type == Material.ARMOR_STAND ? EntityType.ARMOR_STAND : EntityType.END_CRYSTAL;
if (BukkitEntityUtil.checkEntity(entityType, plot)) {
event.setCancelled(true);
break;
@@ -1709,7 +1699,7 @@ public class PlayerEventListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
if (event.getRightClicked().getType() == EntityType.UNKNOWN) {
if (EntityType.of(event.getRightClicked().getType()) == EntityType.UNKNOWN) {
return;
}
Location location = BukkitUtil.adapt(event.getRightClicked().getLocation());

View File

@@ -47,6 +47,7 @@ import org.bukkit.event.entity.LingeringPotionSplashEvent;
import org.bukkit.event.entity.PotionSplashEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.event.entity.ProjectileLaunchEvent;
import org.bukkit.event.player.PlayerEggThrowEvent;
import org.bukkit.projectiles.BlockProjectileSource;
import org.bukkit.projectiles.ProjectileSource;
import org.checkerframework.checker.nullness.qual.NonNull;
@@ -157,14 +158,26 @@ public class ProjectileEventListener implements Listener {
@EventHandler
public void onProjectileHit(ProjectileHitEvent event) {
Projectile entity = event.getEntity();
if (cancelProjectileHit(event.getEntity())) {
event.setCancelled(true);
}
}
@EventHandler
public void onPlayerEggThrow(PlayerEggThrowEvent event) {
if (cancelProjectileHit(event.getEgg())) {
event.setHatching(false);
}
}
private boolean cancelProjectileHit(Projectile entity) {
Location location = BukkitUtil.adapt(entity.getLocation());
if (!this.plotAreaManager.hasPlotArea(location.getWorldName())) {
return;
return false;
}
PlotArea area = location.getPlotArea();
if (area == null) {
return;
return false;
}
Plot plot = area.getPlot(location);
ProjectileSource shooter = entity.getShooter();
@@ -172,15 +185,14 @@ public class ProjectileEventListener implements Listener {
if (!((Player) shooter).isOnline()) {
if (plot != null) {
if (plot.isAdded(((Player) shooter).getUniqueId()) || plot.getFlag(ProjectilesFlag.class)) {
return;
return false;
}
} else if (PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, ProjectilesFlag.class, true)) {
return;
return false;
}
entity.remove();
event.setCancelled(true);
return;
return true;
}
PlotPlayer<?> pp = BukkitUtil.adapt((Player) shooter);
@@ -189,38 +201,36 @@ public class ProjectileEventListener implements Listener {
Permission.PERMISSION_ADMIN_PROJECTILE_UNOWNED
)) {
entity.remove();
event.setCancelled(true);
return true;
}
return;
return false;
}
if (plot.isAdded(pp.getUUID()) || pp.hasPermission(Permission.PERMISSION_ADMIN_PROJECTILE_OTHER) || plot.getFlag(
ProjectilesFlag.class) || (entity instanceof FishHook && plot.getFlag(
FishingFlag.class))) {
return;
return false;
}
entity.remove();
event.setCancelled(true);
return;
return true;
}
if (!(shooter instanceof Entity) && shooter != null) {
if (plot == null) {
entity.remove();
event.setCancelled(true);
return;
return true;
}
Location sLoc =
BukkitUtil.adapt(((BlockProjectileSource) shooter).getBlock().getLocation());
if (!area.contains(sLoc.getX(), sLoc.getZ())) {
entity.remove();
event.setCancelled(true);
return;
return true;
}
Plot sPlot = area.getOwnedPlotAbs(sLoc);
if (sPlot == null || !PlotHandler.sameOwners(plot, sPlot)) {
entity.remove();
event.setCancelled(true);
return true;
}
}
return false;
}
}

View File

@@ -18,6 +18,7 @@
*/
package com.plotsquared.bukkit.util;
import com.plotsquared.bukkit.entity.EntityType;
import com.plotsquared.bukkit.player.BukkitPlayer;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
@@ -48,7 +49,6 @@ import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Creature;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Firework;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
@@ -189,7 +189,7 @@ public class BukkitEntityUtil {
);
return false;
}
} else if (victim.getType() == EntityType.ARMOR_STAND) {
} else if (EntityType.of(victim.getType()) == EntityType.ARMOR_STAND) {
if (plot != null && (plot.getFlag(MiscBreakFlag.class) || plot
.isAdded(plotPlayer.getUUID()))) {
return true;
@@ -354,7 +354,7 @@ public class BukkitEntityUtil {
}
public static boolean checkEntity(Entity entity, Plot plot) {
return checkEntity(entity.getType(), plot);
return checkEntity(EntityType.of(entity.getType()), plot);
}
public static boolean checkEntity(EntityType type, Plot plot) {
@@ -364,7 +364,7 @@ public class BukkitEntityUtil {
}
final com.sk89q.worldedit.world.entity.EntityType entityType =
BukkitAdapter.adapt(type);
BukkitAdapter.adapt(type.bukkitType());
if (EntityCategories.PLAYER.contains(entityType)) {
return false;

View File

@@ -18,6 +18,8 @@
*/
package com.plotsquared.core.backup;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.io.IOException;
@@ -30,12 +32,14 @@ import java.nio.file.Path;
*/
public class Backup {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + Backup.class.getSimpleName());
private final BackupProfile owner;
private final long creationTime;
@Nullable
private final Path file;
Backup(final BackupProfile owner, final long creationTime, final Path file) {
Backup(final BackupProfile owner, final long creationTime, @Nullable final Path file) {
this.owner = owner;
this.creationTime = creationTime;
this.file = file;
@@ -49,7 +53,7 @@ public class Backup {
try {
Files.deleteIfExists(file);
} catch (final IOException e) {
e.printStackTrace();
LOGGER.error("Error deleting backup at {}", file, e);
}
}
}

View File

@@ -21,14 +21,15 @@ package com.plotsquared.core.backup;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.player.ConsolePlayer;
import com.plotsquared.core.exception.PlotSquaredException;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.schematic.Schematic;
import com.plotsquared.core.util.SchematicHandler;
import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.TaskManager;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -51,7 +52,7 @@ import java.util.concurrent.CompletableFuture;
*/
public class PlayerBackupProfile implements BackupProfile {
static final MiniMessage MINI_MESSAGE = MiniMessage.builder().build();
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + PlayerBackupProfile.class.getSimpleName());
private final UUID owner;
private final Plot plot;
@@ -87,7 +88,7 @@ public class PlayerBackupProfile implements BackupProfile {
Files.createDirectory(path);
}
} catch (final Exception e) {
e.printStackTrace();
LOGGER.error("Error resolving {} from {}", child, parent, e);
}
return path;
}
@@ -104,7 +105,7 @@ public class PlayerBackupProfile implements BackupProfile {
try {
Files.createDirectories(path);
} catch (IOException e) {
e.printStackTrace();
LOGGER.error("Error creating directory {}", path, e);
return Collections.emptyList();
}
}
@@ -117,11 +118,11 @@ public class PlayerBackupProfile implements BackupProfile {
backups.add(
new Backup(this, basicFileAttributes.creationTime().toMillis(), file));
} catch (IOException e) {
e.printStackTrace();
LOGGER.error("Error getting attributes for file {} to create backup", file, e);
}
});
} catch (IOException e) {
e.printStackTrace();
LOGGER.error("Error walking files from {}", path, e);
}
backups.sort(Comparator.comparingLong(Backup::getCreationTime).reversed());
return (this.backupCache = backups);
@@ -133,7 +134,7 @@ public class PlayerBackupProfile implements BackupProfile {
public void destroy() {
this.listBackups().whenCompleteAsync((backups, error) -> {
if (error != null) {
error.printStackTrace();
LOGGER.error("Error while listing backups", error);
}
backups.forEach(Backup::delete);
this.backupCache = null;
@@ -141,10 +142,12 @@ public class PlayerBackupProfile implements BackupProfile {
}
public @NonNull Path getBackupDirectory() {
return resolve(resolve(
resolve(backupManager.getBackupPath(), Objects.requireNonNull(plot.getArea().toString(), "plot area id")),
Objects.requireNonNull(plot.getId().toDashSeparatedString(), "plot id")
), Objects.requireNonNull(owner.toString(), "owner"));
return resolve(
resolve(
resolve(backupManager.getBackupPath(), Objects.requireNonNull(plot.getArea().toString(), "plot area id")),
Objects.requireNonNull(plot.getId().toDashSeparatedString(), "plot id")
), Objects.requireNonNull(owner.toString(), "owner")
);
}
@Override
@@ -156,7 +159,8 @@ public class PlayerBackupProfile implements BackupProfile {
backups.get(backups.size() - 1).delete();
}
final List<Plot> plots = Collections.singletonList(plot);
final boolean result = this.schematicHandler.exportAll(plots, getBackupDirectory().toFile(),
final boolean result = this.schematicHandler.exportAll(
plots, getBackupDirectory().toFile(),
"%world%-%id%-" + System.currentTimeMillis(), () ->
future.complete(new Backup(this, System.currentTimeMillis(), null))
);
@@ -180,7 +184,7 @@ public class PlayerBackupProfile implements BackupProfile {
try {
schematic = this.schematicHandler.getSchematic(backup.getFile().toFile());
} catch (SchematicHandler.UnsupportedFormatException e) {
e.printStackTrace();
LOGGER.error("Unsupported format for backup {}", backup.getFile(), e);
}
if (schematic == null) {
future.completeExceptionally(new IllegalArgumentException(
@@ -200,10 +204,9 @@ public class PlayerBackupProfile implements BackupProfile {
if (value) {
future.complete(null);
} else {
future.completeExceptionally(new RuntimeException(MINI_MESSAGE.escapeTags(
future.completeExceptionally(new PlotSquaredException(
TranslatableCaption
.of("schematics.schematic_paste_failed")
.getComponent(ConsolePlayer.getConsole()))));
.of("schematics.schematic_paste_failed")));
}
}
}

View File

@@ -32,6 +32,8 @@ import com.plotsquared.core.util.task.TaskManager;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -47,6 +49,7 @@ import java.util.concurrent.TimeUnit;
@Singleton
public class SimpleBackupManager implements BackupManager {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + SimpleBackupManager.class.getSimpleName());
private final Path backupPath;
private final boolean automaticBackup;
private final int backupLimit;
@@ -112,7 +115,12 @@ public class SimpleBackupManager implements BackupManager {
TagResolver.resolver("reason", Tag.inserting(Component.text(throwable.getMessage())))
);
}
throwable.printStackTrace();
LOGGER.error(
"Error creating backup for plot {};{} and player {}",
plot.getArea(),
plot.getId(),
player == null ? "null" : player.getName(), throwable
);
} else {
if (player != null) {
player.sendMessage(TranslatableCaption.of("backups.backup_automatic_finished"));
@@ -128,6 +136,7 @@ public class SimpleBackupManager implements BackupManager {
return this.automaticBackup;
}
@NonNull
public Path getBackupPath() {
return this.backupPath;
}

View File

@@ -21,7 +21,6 @@ package com.plotsquared.core.command;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
@@ -58,8 +57,7 @@ public class Alias extends SubCommand {
return false;
}
Location location = player.getLocation();
Plot plot = location.getPlotAbs();
Plot plot = player.getCurrentPlot();
if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false;

View File

@@ -24,6 +24,7 @@ import com.plotsquared.core.backup.BackupProfile;
import com.plotsquared.core.backup.NullBackupProfile;
import com.plotsquared.core.backup.PlayerBackupProfile;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.exception.PlotSquaredException;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
@@ -32,6 +33,8 @@ import com.plotsquared.core.util.task.RunnableVal3;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.nio.file.Files;
@@ -57,6 +60,8 @@ import java.util.stream.Stream;
permission = "plots.backup")
public final class Backup extends Command {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + Backup.class.getSimpleName());
private final BackupManager backupManager;
@Inject
@@ -326,20 +331,43 @@ public final class Backup extends Command {
if (backupProfile instanceof NullBackupProfile) {
player.sendMessage(
TranslatableCaption.of("backups.backup_impossible"),
TagResolver.resolver("plot", Tag.inserting(
TranslatableCaption.of("generic.generic_other").toComponent(player)
))
TagResolver.resolver(
"plot", Tag.inserting(
TranslatableCaption.of("generic.generic_other").toComponent(player)
)
)
);
} else {
backupProfile.listBackups().whenComplete((backups, throwable) -> {
if (throwable != null) {
Component reason;
if (throwable instanceof PlotSquaredException pe) {
reason = pe.getCaption().toComponent(player);
} else {
reason = Component.text(throwable.getMessage());
}
player.sendMessage(
TranslatableCaption.of("backups.backup_load_failure"),
TagResolver.resolver("reason", Tag.inserting(Component.text(throwable.getMessage())))
TagResolver.resolver("reason", Tag.inserting(reason))
);
LOGGER.error("Error loading player ({}) backup", player.getName(), throwable);
return;
}
if (number < 1 || number > backups.size()) {
player.sendMessage(
TranslatableCaption.of("backups.backup_impossible"),
TagResolver.resolver(
"plot",
Tag.inserting(TranslatableCaption
.of("generic.generic_invalid_choice")
.toComponent(player))
)
);
throwable.printStackTrace();
} else {
if (number < 1 || number > backups.size()) {
final com.plotsquared.core.backup.Backup backup =
backups.get(number - 1);
if (backup == null || backup.getFile() == null || !Files
.exists(backup.getFile())) {
player.sendMessage(
TranslatableCaption.of("backups.backup_impossible"),
TagResolver.resolver(
@@ -350,37 +378,23 @@ public final class Backup extends Command {
)
);
} else {
final com.plotsquared.core.backup.Backup backup =
backups.get(number - 1);
if (backup == null || backup.getFile() == null || !Files
.exists(backup.getFile())) {
player.sendMessage(
TranslatableCaption.of("backups.backup_impossible"),
TagResolver.resolver(
"plot",
Tag.inserting(TranslatableCaption
.of("generic.generic_invalid_choice")
.toComponent(player))
)
);
} else {
CmdConfirm.addPending(player, "/plot backup load " + number,
() -> backupProfile.restoreBackup(backup, player)
.whenComplete((n, error) -> {
if (error != null) {
player.sendMessage(
TranslatableCaption.of("backups.backup_load_failure"),
TagResolver.resolver(
"reason",
Tag.inserting(Component.text(error.getMessage()))
)
);
} else {
player.sendMessage(TranslatableCaption.of("backups.backup_load_success"));
}
})
);
}
CmdConfirm.addPending(
player, "/plot backup load " + number,
() -> backupProfile.restoreBackup(backup, player)
.whenComplete((n, error) -> {
if (error != null) {
player.sendMessage(
TranslatableCaption.of("backups.backup_load_failure"),
TagResolver.resolver(
"reason",
Tag.inserting(Component.text(error.getMessage()))
)
);
} else {
player.sendMessage(TranslatableCaption.of("backups.backup_load_success"));
}
})
);
}
}
});

View File

@@ -20,6 +20,7 @@ package com.plotsquared.core.command;
import com.google.inject.Inject;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.events.PlayerBuyPlotEvent;
import com.plotsquared.core.events.Result;
@@ -84,8 +85,9 @@ public class Buy extends Command {
checkTrue(plot.hasOwner(), TranslatableCaption.of("info.plot_unowned"));
checkTrue(!plot.isOwner(player.getUUID()), TranslatableCaption.of("economy.cannot_buy_own"));
Set<Plot> plots = plot.getConnectedPlots();
int plotCount = Settings.Limit.GLOBAL ? player.getPlotCount() : player.getPlotCount(plot.getWorldName());
checkTrue(
player.getPlotCount() + plots.size() <= player.getAllowedPlots(),
plotCount + plots.size() <= player.getAllowedPlots(),
TranslatableCaption.of("permission.cant_claim_more_plots"),
TagResolver.resolver("amount", Tag.inserting(Component.text(player.getAllowedPlots())))
);

View File

@@ -26,7 +26,6 @@ import com.plotsquared.core.events.PlayerClaimPlotEvent;
import com.plotsquared.core.events.PlotMergeEvent;
import com.plotsquared.core.events.Result;
import com.plotsquared.core.location.Direction;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.PlayerMetaDataKeys;
@@ -72,8 +71,7 @@ public class Claim extends SubCommand {
if (args.length >= 1) {
schematic = args[0];
}
Location location = player.getLocation();
Plot plot = location.getPlotAbs();
Plot plot = player.getCurrentPlot();
if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false;
@@ -90,7 +88,7 @@ public class Claim extends SubCommand {
boolean force = event.getEventResult() == Result.FORCE;
int currentPlots = Settings.Limit.GLOBAL ?
player.getPlotCount() :
player.getPlotCount(location.getWorldName());
player.getPlotCount(plot.getWorldName());
final PlotArea area = plot.getArea();

View File

@@ -68,8 +68,8 @@ public class Continue extends SubCommand {
return false;
}
int size = plot.getConnectedPlots().size();
if (!Settings.Done.COUNTS_TOWARDS_LIMIT && (player.getAllowedPlots()
< player.getPlotCount() + size)) {
int plotCount = Settings.Limit.GLOBAL ? player.getPlotCount() : player.getPlotCount(plot.getWorldName());
if (!Settings.Done.COUNTS_TOWARDS_LIMIT && (player.getAllowedPlots() < plotCount + size)) {
player.sendMessage(
TranslatableCaption.of("permission.cant_claim_more_plots"),
TagResolver.resolver("amount", Tag.inserting(Component.text(player.getAllowedPlots())))

View File

@@ -19,7 +19,6 @@
package com.plotsquared.core.command;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
@@ -37,8 +36,7 @@ public class Copy extends SubCommand {
@Override
public boolean onCommand(final PlotPlayer<?> player, String[] args) {
Location location = player.getLocation();
Plot plot1 = location.getPlotAbs();
Plot plot1 = player.getCurrentPlot();
if (plot1 == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false;

View File

@@ -22,7 +22,6 @@ import com.google.inject.Inject;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.generator.HybridPlotWorld;
import com.plotsquared.core.generator.HybridUtils;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import net.kyori.adventure.text.Component;
@@ -47,8 +46,7 @@ public class CreateRoadSchematic extends SubCommand {
@Override
public boolean onCommand(PlotPlayer<?> player, String[] args) {
Location location = player.getLocation();
Plot plot = location.getPlotAbs();
Plot plot = player.getCurrentPlot();
if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false;
@@ -57,7 +55,7 @@ public class CreateRoadSchematic extends SubCommand {
player.sendMessage(TranslatableCaption.of("schematics.schematic_too_large"));
return false;
}
if (!(location.getPlotArea() instanceof HybridPlotWorld)) {
if (!(plot.getArea() instanceof HybridPlotWorld)) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot_world"));
}
this.hybridUtils.setupRoadSchematic(plot);

View File

@@ -22,7 +22,6 @@ import com.google.inject.Inject;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.generator.HybridPlotManager;
import com.plotsquared.core.generator.HybridUtils;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea;
@@ -57,8 +56,7 @@ public class DebugRoadRegen extends SubCommand {
@Override
public boolean onCommand(PlotPlayer<?> player, String[] args) {
Location location = player.getLocation();
Plot plot = location.getPlotAbs();
Plot plot = player.getCurrentPlot();
if (args.length < 1) {
player.sendMessage(
TranslatableCaption.of("commandconfig.command_syntax"),
@@ -92,8 +90,7 @@ public class DebugRoadRegen extends SubCommand {
}
public boolean regenPlot(PlotPlayer<?> player) {
Location location = player.getLocation();
PlotArea area = location.getPlotArea();
PlotArea area = player.getContextualPlotArea();
if (area == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot_world"));
return false;
@@ -148,10 +145,10 @@ public class DebugRoadRegen extends SubCommand {
return false;
}
Location location = player.getLocation();
PlotArea area = location.getPlotArea();
PlotArea area = player.getContextualPlotArea();
if (area == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot_world"));
return false;
}
Plot plot = player.getCurrentPlot();
PlotManager manager = area.getPlotManager();

View File

@@ -23,7 +23,6 @@ import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.events.Result;
import com.plotsquared.core.events.TeleportCause;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
@@ -61,8 +60,7 @@ public class Delete extends SubCommand {
@Override
public boolean onCommand(final PlotPlayer<?> player, String[] args) {
Location location = player.getLocation();
final Plot plot = location.getPlotAbs();
final Plot plot = player.getCurrentPlot();
if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false;
@@ -92,7 +90,7 @@ public class Delete extends SubCommand {
final java.util.Set<Plot> plots = plot.getConnectedPlots();
final int currentPlots = Settings.Limit.GLOBAL ?
player.getPlotCount() :
player.getPlotCount(location.getWorldName());
player.getPlotCount(plot.getWorldName());
Runnable run = () -> {
if (plot.getRunning() > 0) {
player.sendMessage(TranslatableCaption.of("errors.wait_for_timer"));

View File

@@ -70,8 +70,7 @@ public class Deny extends SubCommand {
@Override
public boolean onCommand(PlotPlayer<?> player, String[] args) {
Location location = player.getLocation();
final Plot plot = location.getPlotAbs();
final Plot plot = player.getCurrentPlot();
if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false;

View File

@@ -26,7 +26,6 @@ import com.plotsquared.core.events.PlotDoneEvent;
import com.plotsquared.core.events.PlotFlagAddEvent;
import com.plotsquared.core.events.Result;
import com.plotsquared.core.generator.HybridUtils;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
@@ -61,8 +60,7 @@ public class Done extends SubCommand {
@Override
public boolean onCommand(final PlotPlayer<?> player, String[] args) {
Location location = player.getLocation();
final Plot plot = location.getPlotAbs();
final Plot plot = player.getCurrentPlot();
if ((plot == null) || !plot.hasOwner()) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false;

View File

@@ -73,7 +73,7 @@ public class Download extends SubCommand {
@Override
public boolean onCommand(final PlotPlayer<?> player, String[] args) {
String world = player.getLocation().getWorldName();
String world = player.getCurrentPlot().getWorldName();
if (!this.plotAreaManager.hasPlotArea(world)) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot_world"));
return false;

View File

@@ -27,7 +27,6 @@ import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.events.PlotFlagAddEvent;
import com.plotsquared.core.events.PlotFlagRemoveEvent;
import com.plotsquared.core.events.Result;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
@@ -179,8 +178,7 @@ public final class FlagCommand extends Command {
* @return {@code true} if the player is allowed to modify the flags at their current location
*/
private static boolean checkRequirements(final @NonNull PlotPlayer<?> player) {
final Location location = player.getLocation();
final Plot plot = location.getPlotAbs();
final Plot plot = player.getCurrentPlot();
if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false;
@@ -344,7 +342,7 @@ public final class FlagCommand extends Command {
if (plotFlag == null) {
return;
}
Plot plot = player.getLocation().getPlotAbs();
Plot plot = player.getCurrentPlot();
PlotFlagAddEvent event = eventDispatcher.callFlagAdd(plotFlag, plot);
if (event.getEventResult() == Result.DENY) {
player.sendMessage(
@@ -409,7 +407,7 @@ public final class FlagCommand extends Command {
if (plotFlag == null) {
return;
}
Plot plot = player.getLocation().getPlotAbs();
Plot plot = player.getCurrentPlot();
PlotFlagAddEvent event = eventDispatcher.callFlagAdd(plotFlag, plot);
if (event.getEventResult() == Result.DENY) {
player.sendMessage(
@@ -419,7 +417,7 @@ public final class FlagCommand extends Command {
return;
}
boolean force = event.getEventResult() == Result.FORCE;
final PlotFlag localFlag = player.getLocation().getPlotAbs().getFlagContainer()
final PlotFlag localFlag = player.getCurrentPlot().getFlagContainer()
.getFlag(event.getFlag().getClass());
if (!force) {
for (String entry : args[1].split(",")) {
@@ -444,7 +442,7 @@ public final class FlagCommand extends Command {
return;
}
boolean result =
player.getLocation().getPlotAbs().setFlag(localFlag.merge(parsed.getValue()));
player.getCurrentPlot().setFlag(localFlag.merge(parsed.getValue()));
if (!result) {
player.sendMessage(TranslatableCaption.of("flag.flag_not_added"));
return;
@@ -484,7 +482,7 @@ public final class FlagCommand extends Command {
if (flag == null) {
return;
}
final Plot plot = player.getLocation().getPlotAbs();
final Plot plot = player.getCurrentPlot();
final PlotFlag<?, ?> flagWithOldValue = plot.getFlagContainer().getFlag(flag.getClass());
PlotFlagRemoveEvent event = eventDispatcher.callFlagRemove(flag, plot);
if (event.getEventResult() == Result.DENY) {
@@ -687,7 +685,7 @@ public final class FlagCommand extends Command {
.build()
);
// Default value
final String defaultValue = player.getLocation().getPlotArea().getFlagContainer()
final String defaultValue = player.getCurrentPlot().getArea().getFlagContainer()
.getFlagErased(plotFlag.getClass()).toString();
player.sendMessage(
TranslatableCaption.of("flag.flag_info_default_value"),

View File

@@ -65,8 +65,7 @@ public class Kick extends SubCommand {
@Override
public boolean onCommand(PlotPlayer<?> player, String[] args) {
Location location = player.getLocation();
Plot plot = location.getPlot();
Plot plot = player.getCurrentPlot();
if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false;
@@ -124,7 +123,7 @@ public class Kick extends SubCommand {
);
return;
}
Location spawn = this.worldUtil.getSpawn(location.getWorldName());
Location spawn = this.worldUtil.getSpawn(plot.getWorldName());
player2.sendMessage(TranslatableCaption.of("kick.you_got_kicked"));
if (plot.equals(spawn.getPlot())) {
Location newSpawn = this.worldUtil.getSpawn(this.plotAreaManager.getAllWorlds()[0]);
@@ -148,8 +147,7 @@ public class Kick extends SubCommand {
@Override
public Collection<Command> tab(final PlotPlayer<?> player, final String[] args, final boolean space) {
Location location = player.getLocation();
Plot plot = location.getPlotAbs();
Plot plot = player.getCurrentPlot();
if (plot == null) {
return Collections.emptyList();
}

View File

@@ -150,8 +150,8 @@ public class ListCmd extends SubCommand {
page = 0;
}
String world = player.getLocation().getWorldName();
PlotArea area = player.getApplicablePlotArea();
PlotArea area = player.getContextualPlotArea();
String world = area != null ? area.getWorldName() : "";
String arg = args[0].toLowerCase();
final boolean[] sort = new boolean[]{true};

View File

@@ -68,11 +68,6 @@ public class Load extends SubCommand {
@Override
public boolean onCommand(final PlotPlayer<?> player, final String[] args) {
final String world = player.getLocation().getWorldName();
if (!this.plotAreaManager.hasPlotArea(world)) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot_world"));
return false;
}
final Plot plot = player.getCurrentPlot();
if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));

View File

@@ -20,7 +20,6 @@ package com.plotsquared.core.command;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.events.TeleportCause;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
@@ -36,8 +35,7 @@ public class Middle extends SubCommand {
@Override
public boolean onCommand(PlotPlayer<?> player, String[] arguments) {
Location location = player.getLocation();
Plot plot = location.getPlot();
Plot plot = player.getCurrentPlot();
if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false;

View File

@@ -20,7 +20,6 @@ package com.plotsquared.core.command;
import com.google.inject.Inject;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
@@ -55,8 +54,7 @@ public class Move extends SubCommand {
RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone
) {
Location location = player.getLocation();
Plot plot1 = location.getPlotAbs();
Plot plot1 = player.getCurrentPlot();
if (plot1 == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return CompletableFuture.completedFuture(false);

View File

@@ -23,7 +23,6 @@ import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.events.PlotFlagAddEvent;
import com.plotsquared.core.events.PlotFlagRemoveEvent;
import com.plotsquared.core.events.Result;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
@@ -74,8 +73,7 @@ public class Music extends SubCommand {
@Override
public boolean onCommand(PlotPlayer<?> player, String[] args) {
Location location = player.getLocation();
final Plot plot = location.getPlotAbs();
final Plot plot = player.getCurrentPlot();
if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false;

View File

@@ -21,7 +21,6 @@ package com.plotsquared.core.command;
import com.google.inject.Inject;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.database.DBFunc;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
@@ -56,8 +55,7 @@ public class Remove extends SubCommand {
@Override
public boolean onCommand(PlotPlayer<?> player, String[] args) {
Location location = player.getLocation();
Plot plot = location.getPlotAbs();
Plot plot = player.getCurrentPlot();
if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false;
@@ -132,8 +130,7 @@ public class Remove extends SubCommand {
@Override
public Collection<Command> tab(final PlotPlayer<?> player, final String[] args, final boolean space) {
Location location = player.getLocation();
Plot plot = location.getPlotAbs();
Plot plot = player.getCurrentPlot();
if (plot == null) {
return Collections.emptyList();
}

View File

@@ -22,7 +22,6 @@ import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.ConsolePlayer;
import com.plotsquared.core.player.PlotPlayer;
@@ -102,8 +101,7 @@ public class SchematicCmd extends SubCommand {
);
break;
}
Location loc = player.getLocation();
final Plot plot = loc.getPlotAbs();
final Plot plot = player.getCurrentPlot();
if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false;
@@ -247,8 +245,7 @@ public class SchematicCmd extends SubCommand {
player.sendMessage(TranslatableCaption.of("error.task_in_process"));
return false;
}
Location location = player.getLocation();
Plot plot = location.getPlotAbs();
Plot plot = player.getCurrentPlot();
if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false;

View File

@@ -78,7 +78,7 @@ public class Set extends SubCommand {
@Override
public boolean set(PlotPlayer<?> player, final Plot plot, String value) {
final PlotArea plotArea = player.getLocation().getPlotArea();
final PlotArea plotArea = player.getContextualPlotArea();
if (plotArea == null) {
return false;
}

View File

@@ -19,7 +19,6 @@
package com.plotsquared.core.command;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
@@ -32,8 +31,7 @@ public abstract class SetCommand extends SubCommand {
@Override
public boolean onCommand(PlotPlayer<?> player, String[] args) {
Location location = player.getLocation();
Plot plot = location.getPlotAbs();
Plot plot = player.getCurrentPlot();
if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false;

View File

@@ -19,7 +19,6 @@
package com.plotsquared.core.command;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
@@ -44,8 +43,7 @@ public class Swap extends SubCommand {
RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone
) {
Location location = player.getLocation();
Plot plot1 = location.getPlotAbs();
Plot plot1 = player.getCurrentPlot();
if (plot1 == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return CompletableFuture.completedFuture(false);
@@ -79,8 +77,10 @@ public class Swap extends SubCommand {
String p1 = plot1.toString();
String p2 = plot2.toString();
return plot1.getPlotModificationManager().move(plot2, player, () -> {
}, true).thenApply(result -> {
return plot1.getPlotModificationManager().move(
plot2, player, () -> {
}, true
).thenApply(result -> {
if (result) {
player.sendMessage(
TranslatableCaption.of("swap.swap_success"),

View File

@@ -22,7 +22,6 @@ import com.google.inject.Inject;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.events.PlotUnlinkEvent;
import com.plotsquared.core.events.Result;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
@@ -51,8 +50,7 @@ public class Unlink extends SubCommand {
@Override
public boolean onCommand(final PlotPlayer<?> player, String[] args) {
Location location = player.getLocation();
final Plot plot = location.getPlotAbs();
final Plot plot = player.getCurrentPlot();
if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false;

View File

@@ -435,6 +435,11 @@ public class Settings extends Config {
public static String SCHEMATICS = "schematics";
public static String TEMPLATES = "templates";
@Comment({"If schematics used for generation should be searched for in the path.schematics location",
" - This setting exists and is `false` by default for backwards compatibility.",
" - If false then generation schematics must be located in `schematics`",
" - Schematics must still always be under GEN_ROAD_SCHEMATIC/<world> etc."})
public static boolean USE_SCHEMATICS_PATH_FOR_GEN_SCHEMATICS = false;
}

View File

@@ -0,0 +1,62 @@
/*
* 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.exception;
import com.plotsquared.core.configuration.caption.Caption;
import com.plotsquared.core.configuration.caption.LocaleHolder;
/**
* Internal use only. Used to allow adventure captions to be used in an exception
*
* @since 7.5.7
*/
public final class PlotSquaredException extends RuntimeException {
private final Caption caption;
/**
* Create a new instance with the given caption
*
* @param caption caption
*/
public PlotSquaredException(Caption caption) {
this.caption = caption;
}
/**
* Create a new instance with the given caption and cause
*
* @param caption caption
* @param cause cause
*/
public PlotSquaredException(Caption caption, Exception cause) {
super(cause);
this.caption = caption;
}
@Override
public String getMessage() {
return caption.getComponent(LocaleHolder.console());
}
public Caption getCaption() {
return caption;
}
}

View File

@@ -164,9 +164,6 @@ public abstract class ClassicPlotWorld extends SquarePlotWorld {
: getMinBuildHeight();
}
/**
* Get the lowest height of plot, road, and wall. Accounts for {@link Settings.Schematics#USE_WALL_IN_ROAD_SCHEM_HEIGHT}
*/
int schematicStartHeight() {
int plotRoadMin = Math.min(PLOT_HEIGHT, ROAD_HEIGHT);
if (!Settings.Schematics.USE_WALL_IN_ROAD_SCHEM_HEIGHT) {

View File

@@ -140,7 +140,8 @@ public class HybridPlotWorld extends ClassicPlotWorld {
@NonNull
@Override
protected PlotManager createManager() {
return new HybridPlotManager(this, PlotSquared.platform().regionManager(),
return new HybridPlotManager(
this, PlotSquared.platform().regionManager(),
PlotSquared.platform().injector().getInstance(ProgressSubscriberFactory.class)
);
}
@@ -215,15 +216,16 @@ public class HybridPlotWorld extends ClassicPlotWorld {
// Try to determine root. This means that plot areas can have separate schematic
// directories
String schematicFolder = Settings.Paths.USE_SCHEMATICS_PATH_FOR_GEN_SCHEMATICS ? Settings.Paths.SCHEMATICS : "schematics";
if (!(root =
FileUtils.getFile(
PlotSquared.platform().getDirectory(),
"schematics/GEN_ROAD_SCHEMATIC/" + this.getWorldName() + "/" + this.getId()
schematicFolder + File.separator + "GEN_ROAD_SCHEMATIC" + File.separator + this.getWorldName() + File.separator + this.getId()
))
.exists()) {
root = FileUtils.getFile(
PlotSquared.platform().getDirectory(),
"schematics/GEN_ROAD_SCHEMATIC/" + this.getWorldName()
schematicFolder + File.separator + "GEN_ROAD_SCHEMATIC" + File.separator + this.getWorldName()
);
}
@@ -274,8 +276,7 @@ public class HybridPlotWorld extends ClassicPlotWorld {
SCHEM_Y = getMinGenHeight();
plotY = 0;
} else if (!Settings.Schematics.PASTE_ON_TOP) {
// Schematics should generate/be pasted from build height
SCHEM_Y = getMinBuildHeight();
SCHEM_Y = getMinGenHeight();
plotY = 0;
}
}
@@ -292,14 +293,18 @@ public class HybridPlotWorld extends ClassicPlotWorld {
roadY = 0; // Road is the lowest schematic
if (schematic3 != null && schematic3.getClipboard().getDimensions().getY() != worldGenHeight) {
// Road is the lowest schematic. Normalize plotY to it.
plotY = (Settings.Schematics.PASTE_ON_TOP ? PLOT_HEIGHT : getMinBuildHeight()) - SCHEM_Y;
if (Settings.Schematics.PASTE_ON_TOP) {
plotY = PLOT_HEIGHT - getMinGenHeight();
}
}
} else if (!Settings.Schematics.PASTE_ROAD_ON_TOP) {
roadY = 0;
SCHEM_Y = getMinGenHeight();
if (schematic3 != null && schematic3.getClipboard().getDimensions().getY() != worldGenHeight) {
// Road is the lowest schematic. Normalize plotY to it.
plotY = (Settings.Schematics.PASTE_ON_TOP ? PLOT_HEIGHT : getMinBuildHeight()) - SCHEM_Y;
if (schematic3 != null) {
if (Settings.Schematics.PASTE_ON_TOP) {
// Road is the lowest schematic. Normalize plotY to it.
plotY = PLOT_HEIGHT - SCHEM_Y;
}
}
} else {
roadY = minRoadWall - SCHEM_Y;

View File

@@ -68,7 +68,6 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -530,7 +529,7 @@ public class HybridUtils {
final QueueCoordinator queue = blockQueue.getNewQueue(worldUtil.getWeWorld(world));
Location bot = plot.getBottomAbs().subtract(1, 0, 1);
Location top = plot.getTopAbs();
final HybridPlotWorld plotworld = Objects.requireNonNull((HybridPlotWorld) plot.getArea());
final HybridPlotWorld plotworld = (HybridPlotWorld) plot.getArea();
// Do not use plotworld#schematicStartHeight() here as we want to restore the pre 6.1.4 way of doing it if
// USE_WALL_IN_ROAD_SCHEM_HEIGHT is false
int schemY = Settings.Schematics.USE_WALL_IN_ROAD_SCHEM_HEIGHT ?

View File

@@ -290,7 +290,7 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
*
* @return the plot the player is standing on or null if standing on a road or not in a {@link PlotArea}
*/
public Plot getCurrentPlot() {
public @Nullable Plot getCurrentPlot() {
try (final MetaDataAccess<Plot> lastPlotAccess =
this.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
if (lastPlotAccess.get().orElse(null) == null && !Settings.Enabled_Components.EVENTS) {
@@ -319,7 +319,7 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
*/
public int getPlotCount() {
if (!Settings.Limit.GLOBAL) {
return getPlotCount(getLocation().getWorldName());
return getPlotCount(getContextualWorldName());
}
final AtomicInteger count = new AtomicInteger(0);
final UUID uuid = getUUID();
@@ -339,7 +339,7 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
public int getClusterCount() {
if (!Settings.Limit.GLOBAL) {
return getClusterCount(getLocation().getWorldName());
return getClusterCount(getContextualWorldName());
}
final AtomicInteger count = new AtomicInteger(0);
this.plotAreaManager.forEachPlotArea(value -> {
@@ -352,6 +352,34 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
return count.get();
}
/**
* {@return the world name at the player's contextual position}
* The contextual position can be affected when using a command with
* an explicit plot override, e.g., `/plot &ltid&gt info`.
*/
private @NonNull String getContextualWorldName() {
Plot current = getCurrentPlot();
if (current != null) {
return current.getWorldName();
}
return getLocation().getWorldName();
}
/**
* {@return the plot area at the player's contextual position}
* The contextual position can be affected when using a command with
* an explicit plot override, e.g., `/plot &ltid&gt info`.
*
* @since TODO
*/
public @Nullable PlotArea getContextualPlotArea() {
Plot current = getCurrentPlot();
if (current != null) {
return current.getArea();
}
return getLocation().getPlotArea();
}
/**
* Get the number of plots this player owns in the world.
*
@@ -408,7 +436,11 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
}
public PlotArea getApplicablePlotArea() {
return this.plotAreaManager.getApplicablePlotArea(getLocation());
Plot plot = getCurrentPlot();
if (plot == null) {
return this.plotAreaManager.getApplicablePlotArea(getLocation());
}
return plot.getArea();
}
@Override
@@ -614,16 +646,16 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
PlotId id = plot.getId();
int x = id.getX();
int z = id.getY();
ByteBuffer buffer = ByteBuffer.allocate(13);
ByteBuffer buffer = ByteBuffer.allocate(14);
buffer.putShort((short) x);
buffer.putShort((short) z);
Location location = getLocation();
buffer.putInt(location.getX());
buffer.put((byte) location.getY());
buffer.putShort((short) location.getY());
buffer.putInt(location.getZ());
setPersistentMeta("quitLoc", buffer.array());
} else if (hasPersistentMeta("quitLoc")) {
removePersistentMeta("quitLoc");
setPersistentMeta("quitLocV2", buffer.array());
} else if (hasPersistentMeta("quitLocV2")) {
removePersistentMeta("quitLocV2");
}
if (plot != null) {
this.eventDispatcher.callLeave(this, plot);
@@ -678,80 +710,89 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
public void populatePersistentMetaMap() {
if (Settings.Enabled_Components.PERSISTENT_META) {
DBFunc.getPersistentMeta(getUUID(), new RunnableVal<>() {
@Override
public void run(Map<String, byte[]> value) {
try {
PlotPlayer.this.metaMap = value;
if (value.isEmpty()) {
return;
}
if (PlotPlayer.this.getAttribute("debug")) {
debugModeEnabled.add(PlotPlayer.this);
}
if (!Settings.Teleport.ON_LOGIN) {
return;
}
PlotAreaManager manager = PlotPlayer.this.plotAreaManager;
if (!(manager instanceof SinglePlotAreaManager)) {
return;
}
PlotArea area = ((SinglePlotAreaManager) manager).getArea();
byte[] arr = PlotPlayer.this.getPersistentMeta("quitLoc");
if (arr == null) {
return;
}
removePersistentMeta("quitLoc");
if (!getMeta("teleportOnLogin", true)) {
return;
}
ByteBuffer quitWorld = ByteBuffer.wrap(arr);
final int plotX = quitWorld.getShort();
final int plotZ = quitWorld.getShort();
PlotId id = PlotId.of(plotX, plotZ);
int x = quitWorld.getInt();
int y = quitWorld.get() & 0xFF;
int z = quitWorld.getInt();
Plot plot = area.getOwnedPlot(id);
if (plot == null) {
return;
}
final Location location = Location.at(plot.getWorldName(), x, y, z);
if (plot.isLoaded()) {
TaskManager.runTask(() -> {
if (getMeta("teleportOnLogin", true)) {
teleport(location, TeleportCause.LOGIN);
sendMessage(
TranslatableCaption.of("teleport.teleported_to_plot"));
DBFunc.getPersistentMeta(
getUUID(), new RunnableVal<>() {
@Override
public void run(Map<String, byte[]> value) {
try {
PlotPlayer.this.metaMap = value;
if (value.isEmpty()) {
return;
}
});
} else if (!PlotSquared.get().isMainThread(Thread.currentThread())) {
if (getMeta("teleportOnLogin", true)) {
plot.teleportPlayer(
PlotPlayer.this,
result -> TaskManager.runTask(() -> {
if (getMeta("teleportOnLogin", true)) {
if (plot.isLoaded()) {
teleport(location, TeleportCause.LOGIN);
sendMessage(TranslatableCaption
.of("teleport.teleported_to_plot"));
}
}
})
);
if (PlotPlayer.this.getAttribute("debug")) {
debugModeEnabled.add(PlotPlayer.this);
}
if (!Settings.Teleport.ON_LOGIN) {
return;
}
PlotAreaManager manager = PlotPlayer.this.plotAreaManager;
if (!(manager instanceof SinglePlotAreaManager)) {
return;
}
PlotArea area = ((SinglePlotAreaManager) manager).getArea();
boolean V2 = false;
byte[] arr = PlotPlayer.this.getPersistentMeta("quitLoc");
if (arr == null) {
arr = PlotPlayer.this.getPersistentMeta("quitLocV2");
if (arr == null) {
return;
}
V2 = true;
removePersistentMeta("quitLocV2");
} else {
removePersistentMeta("quitLoc");
}
if (!getMeta("teleportOnLogin", true)) {
return;
}
ByteBuffer quitWorld = ByteBuffer.wrap(arr);
final int plotX = quitWorld.getShort();
final int plotZ = quitWorld.getShort();
PlotId id = PlotId.of(plotX, plotZ);
int x = quitWorld.getInt();
int y = V2 ? quitWorld.getShort() : (quitWorld.get() & 0xFF);
int z = quitWorld.getInt();
Plot plot = area.getOwnedPlot(id);
if (plot == null) {
return;
}
final Location location = Location.at(plot.getWorldName(), x, y, z);
if (plot.isLoaded()) {
TaskManager.runTask(() -> {
if (getMeta("teleportOnLogin", true)) {
teleport(location, TeleportCause.LOGIN);
sendMessage(
TranslatableCaption.of("teleport.teleported_to_plot"));
}
});
} else if (!PlotSquared.get().isMainThread(Thread.currentThread())) {
if (getMeta("teleportOnLogin", true)) {
plot.teleportPlayer(
PlotPlayer.this,
result -> TaskManager.runTask(() -> {
if (getMeta("teleportOnLogin", true)) {
if (plot.isLoaded()) {
teleport(location, TeleportCause.LOGIN);
sendMessage(TranslatableCaption
.of("teleport.teleported_to_plot"));
}
}
})
);
}
}
} catch (Throwable e) {
LOGGER.error("Error populating persistent meta for player {}", PlotPlayer.this.getName(), e);
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
});
);
}
}
@@ -819,7 +860,8 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
}
@SuppressWarnings("unchecked")
@Nullable <T> T getPersistentMeta(final @NonNull MetaDataKey<T> key) {
@Nullable
<T> T getPersistentMeta(final @NonNull MetaDataKey<T> key) {
final byte[] value = this.getPersistentMeta(key.toString());
if (value == null) {
return null;
@@ -989,9 +1031,11 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
if (throwable != null) {
sendMessage(
TranslatableCaption.of("errors.error"),
TagResolver.resolver("value", Tag.inserting(
Component.text("Failed to resolve asynchronous caption replacements")
))
TagResolver.resolver(
"value", Tag.inserting(
Component.text("Failed to resolve asynchronous caption replacements")
)
)
);
LOGGER.error("Failed to resolve asynchronous tagresolver(s) for " + caption, throwable);
} else {

View File

@@ -541,7 +541,7 @@ public class Plot {
*
* @return World name
*/
public @Nullable String getWorldName() {
public @NonNull String getWorldName() {
return area.getWorldName();
}

View File

@@ -58,7 +58,7 @@ public class SinglePlot extends Plot {
}
@Override
public String getWorldName() {
public @NonNull String getWorldName() {
return getId().toUnderscoreSeparatedString();
}

View File

@@ -135,6 +135,7 @@ public abstract class SchematicHandler {
}
final String filename;
final String website;
final @Nullable UUID finalUuid = uuid;
if (uuid == null) {
uuid = UUID.randomUUID();
website = Settings.Web.URL + "upload.php?" + uuid;
@@ -144,10 +145,11 @@ public abstract class SchematicHandler {
filename = file + '.' + extension;
}
final URL url;
String uri = Settings.Web.URL + "?key=" + uuid + "&type=" + extension;
try {
url = URI.create(Settings.Web.URL + "?key=" + uuid + "&type=" + extension).toURL();
url = URI.create(uri).toURL();
} catch (MalformedURLException e) {
e.printStackTrace();
LOGGER.error("Malformed URI `{}`", uri, e);
whenDone.run();
return;
}
@@ -193,7 +195,7 @@ public abstract class SchematicHandler {
}
TaskManager.runTask(whenDone);
} catch (IOException e) {
e.printStackTrace();
LOGGER.error("Error while uploading schematic for UUID {}", finalUuid, e);
TaskManager.runTask(whenDone);
}
});
@@ -388,8 +390,14 @@ public abstract class SchematicHandler {
}
queue.enqueue();
} catch (Exception e) {
e.printStackTrace();
TaskManager.runTask(whenDone);
LOGGER.error(
"Error pasting schematic to plot {};{} for player {}",
plot.getArea(),
plot.getId(),
actor == null ? "null" : actor.getName(),
e
);
}
}
@@ -456,7 +464,7 @@ public abstract class SchematicHandler {
Clipboard clip = reader.read();
return new Schematic(clip);
} catch (IOException e) {
e.printStackTrace();
LOGGER.error("Error reading schematic from file {}", file.getAbsolutePath(), e);
}
} else {
throw new UnsupportedFormatException("This schematic format is not recognised or supported.");
@@ -470,7 +478,7 @@ public abstract class SchematicHandler {
InputStream inputStream = Channels.newInputStream(readableByteChannel);
return getSchematic(inputStream);
} catch (IOException e) {
e.printStackTrace();
LOGGER.error("Error reading schematic from {}", url, e);
}
return null;
}
@@ -486,7 +494,7 @@ public abstract class SchematicHandler {
Clipboard clip = schematicReader.read();
return new Schematic(clip);
} catch (IOException e) {
e.printStackTrace();
LOGGER.error("Error reading schematic", e);
}
}
return null;
@@ -515,7 +523,7 @@ public abstract class SchematicHandler {
}
return schematics;
} catch (JsonParseException | IOException e) {
e.printStackTrace();
LOGGER.error("Error retrieving saves for UUID {}", uuid, e);
}
return null;
}
@@ -532,7 +540,7 @@ public abstract class SchematicHandler {
try (NBTOutputStream nos = new NBTOutputStream(new GZIPOutputStream(output, true))) {
nos.writeNamedTag("Schematic", tag);
} catch (IOException e1) {
e1.printStackTrace();
LOGGER.error("Error uploading schematic for UUID {}", uuid, e1);
}
}
}, whenDone);
@@ -556,9 +564,9 @@ public abstract class SchematicHandler {
nbtStream.writeNamedTag("Schematic", tag);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
LOGGER.error("Error saving schematic at {}", path, e);
} catch (IOException e) {
e.printStackTrace();
LOGGER.error("Error saving schematic at {}", path, e);
return false;
}
return true;
@@ -581,7 +589,7 @@ public abstract class SchematicHandler {
schematic.put("BlockData", new ByteArrayTag(buffer.toByteArray()));
schematic.put("BlockEntities", new ListTag(CompoundTag.class, tileEntities));
if (biomeBuffer.size() == 0 || biomePalette.size() == 0) {
if (biomeBuffer.size() == 0 || biomePalette.isEmpty()) {
return;
}
@@ -733,10 +741,7 @@ public abstract class SchematicHandler {
}
BaseBlock block = aabb.getWorld().getFullBlock(point);
if (block.getNbtData() != null) {
Map<String, Tag> values = new HashMap<>();
for (Map.Entry<String, Tag> entry : block.getNbtData().getValue().entrySet()) {
values.put(entry.getKey(), entry.getValue());
}
Map<String, Tag> values = new HashMap<>(block.getNbtData().getValue());
// Positions are kept in NBT, we don't want that.
values.remove("x");

View File

@@ -204,6 +204,9 @@ public final class PlaceholderRegistry {
this.createPlaceholder("currentplot_x", (player, plot) -> Integer.toString(plot.getId().getX()));
this.createPlaceholder("currentplot_y", (player, plot) -> Integer.toString(plot.getId().getY()));
this.createPlaceholder("currentplot_xy", (player, plot) -> plot.getId().toString());
this.createPlaceholder("currentplot_abs_x", (player, plot) -> Integer.toString(plot.getId().getX()), true);
this.createPlaceholder("currentplot_abs_y", (player, plot) -> Integer.toString(plot.getId().getY()), true);
this.createPlaceholder("currentplot_abs_xy", (player, plot) -> plot.getId().toString(), true);
this.createPlaceholder("currentplot_rating", (player, plot) -> {
if (Double.isNaN(plot.getAverageRating())) {
return legacyComponent(TranslatableCaption.of("placeholder.nan"), player);
@@ -253,7 +256,23 @@ public final class PlaceholderRegistry {
final @NonNull String key,
final @NonNull BiFunction<PlotPlayer<?>, Plot, String> placeholderFunction
) {
this.registerPlaceholder(new PlotSpecificPlaceholder(key) {
this.createPlaceholder(key, placeholderFunction, false);
}
/**
* Create a functional placeholder
*
* @param key Placeholder key
* @param placeholderFunction Placeholder generator. Cannot return null
* @param requireAbsolute If the plot given to the placeholder should be the absolute (not base) plot
* @since TODO
*/
public void createPlaceholder(
final @NonNull String key,
final @NonNull BiFunction<PlotPlayer<?>, Plot, String> placeholderFunction,
final boolean requireAbsolute
) {
this.registerPlaceholder(new PlotSpecificPlaceholder(key, requireAbsolute) {
@Override
public @NonNull String getValue(final @NonNull PlotPlayer<?> player, final @NonNull Plot plot) {
return placeholderFunction.apply(player, plot);

View File

@@ -27,14 +27,28 @@ import org.checkerframework.checker.nullness.qual.NonNull;
*/
public abstract class PlotSpecificPlaceholder extends Placeholder {
private final boolean requireAbsolute;
public PlotSpecificPlaceholder(final @NonNull String key) {
this(key, false);
}
/**
* Create a functional placeholder
*
* @param key Placeholder key
* @param requireAbsolute If the plot given to the placeholder should be the absolute (not base) plot
* @since TODO
*/
public PlotSpecificPlaceholder(final @NonNull String key, final boolean requireAbsolute) {
super(key);
this.requireAbsolute = requireAbsolute;
}
@Override
public @NonNull
final String getValue(final @NonNull PlotPlayer<?> player) {
final Plot plot = player.getCurrentPlot();
final Plot plot = requireAbsolute ? player.getLocation().getPlotAbs() : player.getCurrentPlot();
if (plot == null) {
return "";
}

View File

@@ -20,7 +20,7 @@ plugins {
}
group = "com.intellectualsites.plotsquared"
version = "7.5.7-SNAPSHOT"
version = "7.5.9-SNAPSHOT"
if (!File("$rootDir/.git").exists()) {
logger.lifecycle("""
@@ -65,10 +65,16 @@ subprojects {
plugin<IdeaPlugin>()
}
configurations.matching { it.name == "signatures" }.configureEach {
attributes {
attribute(Attribute.of("signatures-unique", String::class.java), "true")
}
}
dependencies {
// Tests
testImplementation("org.junit.jupiter:junit-jupiter:5.13.4")
testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.13.4")
testImplementation("org.junit.jupiter:junit-jupiter:6.0.0")
testRuntimeOnly("org.junit.platform:junit-platform-launcher:6.0.0")
}
plugins.withId("java") {
@@ -95,9 +101,15 @@ subprojects {
}
}
val javaComponent = components["java"] as AdhocComponentWithVariants
javaComponent.withVariantsFromConfiguration(configurations["shadowRuntimeElements"]) {
skip()
afterEvaluate {
val javaComponent = components["java"] as AdhocComponentWithVariants
configurations.findByName("shadowRuntimeElements")?.let { shadowRuntimeElements ->
javaComponent.withVariantsFromConfiguration(shadowRuntimeElements) {
skip()
}
} ?: run {
logger.warn("Configuration 'shadowRuntimeElements' does not exist.")
}
}
signing {

View File

@@ -2,18 +2,18 @@
# Platform expectations
paper = "1.20.4-R0.1-SNAPSHOT"
guice = "7.0.0"
spotbugs = "4.9.4"
checkerqual = "3.49.5"
spotbugs = "4.9.8"
checkerqual = "3.51.1"
gson = "2.10"
guava = "31.1-jre"
snakeyaml = "2.0"
adventure = "4.24.0"
adventure = "4.25.0"
adventure-bukkit = "4.4.1"
log4j = "2.19.0"
# Plugins
worldedit = "7.2.20"
fawe = "2.13.1"
fawe = "2.14.0"
placeholderapi = "2.11.6"
luckperms = "5.5"
essentialsx = "2.21.2"
@@ -33,11 +33,11 @@ vault = "1.7.1"
serverlib = "2.3.7"
# Gradle plugins
shadow = "8.3.9"
shadow = "9.2.2"
grgit = "4.1.1"
spotless = "7.2.1"
spotless = "8.0.0"
publish = "0.34.0"
runPaper = "2.3.1"
runPaper = "3.0.2"
[libraries]
# Platform expectations

Binary file not shown.

View File

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

5
gradlew vendored
View File

@@ -1,7 +1,7 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
# Copyright © 2015 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -114,7 +114,6 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
@@ -172,7 +171,6 @@ fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
@@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"

3
gradlew.bat vendored
View File

@@ -70,11 +70,10 @@ goto fail
:execute
@rem Setup the command line
set CLASSPATH=
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell