Merge branch 'v6' into feature/v6/json

# Conflicts:
#	Bukkit/src/main/java/com/plotsquared/bukkit/chat/FancyMessage.java
This commit is contained in:
Alexander Söderberg 2020-07-08 15:22:02 +02:00
commit 090bd69be5
No known key found for this signature in database
GPG Key ID: C0207FF7EA146678
25 changed files with 1163 additions and 483 deletions

View File

@ -23,10 +23,12 @@ dependencies {
implementation(project(":PlotSquared-Core")) implementation(project(":PlotSquared-Core"))
compile("org.bstats:bstats-bukkit:1.7") compile("org.bstats:bstats-bukkit:1.7")
compile(project(":PlotSquared-Core")) compile(project(":PlotSquared-Core"))
compile("com.destroystokyo.paper:paper-api:1.15.2-R0.1-SNAPSHOT") compile("com.destroystokyo.paper:paper-api:1.16.1-R0.1-SNAPSHOT")
//implementation 'com.onarandombox.multiversecore:Multiverse-Core:3.0.0-SNAPSHOT' implementation("org.spigotmc:spigot-api:1.16.1-R0.1-SNAPSHOT")
implementation("org.spigotmc:spigot-api:1.15.2-R0.1-SNAPSHOT") compile(group: "com.sk89q.worldedit", name: "worldedit-bukkit", version: "7.1.0") {
compile(group: "com.sk89q.worldedit", name: "worldedit-bukkit", version: "7.0.1") exclude(module: "bukkit")
}
compile("io.papermc:paperlib:1.0.2") compile("io.papermc:paperlib:1.0.2")
implementation("net.kyori:text-adapter-bukkit:3.0.3") implementation("net.kyori:text-adapter-bukkit:3.0.3")
compile("com.github.MilkBowl:VaultAPI:1.7") { compile("com.github.MilkBowl:VaultAPI:1.7") {
@ -34,7 +36,9 @@ dependencies {
} }
implementation("me.clip:placeholderapi:2.10.6") implementation("me.clip:placeholderapi:2.10.6")
implementation("net.luckperms:api:5.1") implementation("net.luckperms:api:5.1")
implementation("net.ess3:EssentialsX:2.17.2") implementation("net.ess3:EssentialsX:2.17.2") {
exclude(group: "io.papermc", module: "paperlib")
}
implementation("net.alpenblock:BungeePerms:4.0-dev-106") implementation("net.alpenblock:BungeePerms:4.0-dev-106")
implementation("net.kyori:adventure-platform-bukkit:4.0.0-SNAPSHOT") implementation("net.kyori:adventure-platform-bukkit:4.0.0-SNAPSHOT")
implementation('net.kyori:adventure-text-minimessage:3.0.0-SNAPSHOT') implementation('net.kyori:adventure-text-minimessage:3.0.0-SNAPSHOT')

View File

@ -21,20 +21,26 @@
<dependency> <dependency>
<groupId>com.plotsquared</groupId> <groupId>com.plotsquared</groupId>
<artifactId>PlotSquared-Core</artifactId> <artifactId>PlotSquared-Core</artifactId>
<version>5.12.2</version> <version>5.12.3</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.destroystokyo.paper</groupId> <groupId>com.destroystokyo.paper</groupId>
<artifactId>paper-api</artifactId> <artifactId>paper-api</artifactId>
<version>1.15.2-R0.1-SNAPSHOT</version> <version>1.16.1-R0.1-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.sk89q.worldedit</groupId> <groupId>com.sk89q.worldedit</groupId>
<artifactId>worldedit-bukkit</artifactId> <artifactId>worldedit-bukkit</artifactId>
<version>7.0.1</version> <version>7.1.0</version>
<scope>compile</scope> <scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>bukkit</artifactId>
<groupId>*</groupId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.papermc</groupId> <groupId>io.papermc</groupId>
@ -131,7 +137,7 @@
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId> <artifactId>spigot-api</artifactId>
<version>1.15.2-R0.1-SNAPSHOT</version> <version>1.16.1-R0.1-SNAPSHOT</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -157,6 +163,12 @@
<artifactId>EssentialsX</artifactId> <artifactId>EssentialsX</artifactId>
<version>2.17.2</version> <version>2.17.2</version>
<scope>runtime</scope> <scope>runtime</scope>
<exclusions>
<exclusion>
<artifactId>paperlib</artifactId>
<groupId>io.papermc</groupId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.alpenblock</groupId> <groupId>net.alpenblock</groupId>

View File

@ -44,6 +44,7 @@ import com.plotsquared.bukkit.schematic.BukkitSchematicHandler;
import com.plotsquared.bukkit.util.BukkitChunkManager; import com.plotsquared.bukkit.util.BukkitChunkManager;
import com.plotsquared.bukkit.util.BukkitEconHandler; import com.plotsquared.bukkit.util.BukkitEconHandler;
import com.plotsquared.bukkit.util.BukkitInventoryUtil; import com.plotsquared.bukkit.util.BukkitInventoryUtil;
import com.plotsquared.bukkit.util.BukkitPermHandler;
import com.plotsquared.bukkit.util.BukkitRegionManager; import com.plotsquared.bukkit.util.BukkitRegionManager;
import com.plotsquared.bukkit.util.BukkitSetupUtils; import com.plotsquared.bukkit.util.BukkitSetupUtils;
import com.plotsquared.bukkit.util.BukkitTaskManager; import com.plotsquared.bukkit.util.BukkitTaskManager;
@ -91,6 +92,7 @@ import com.plotsquared.core.util.ConsoleColors;
import com.plotsquared.core.util.EconHandler; import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.InventoryUtil; import com.plotsquared.core.util.InventoryUtil;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.PermHandler;
import com.plotsquared.core.util.PlatformWorldManager; import com.plotsquared.core.util.PlatformWorldManager;
import com.plotsquared.core.util.PlayerManager; import com.plotsquared.core.util.PlayerManager;
import com.plotsquared.core.util.PremiumVerification; import com.plotsquared.core.util.PremiumVerification;
@ -177,6 +179,7 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain<
@Getter private PlatformWorldManager<World> worldManager; @Getter private PlatformWorldManager<World> worldManager;
private final BukkitPlayerManager playerManager = new BukkitPlayerManager(); private final BukkitPlayerManager playerManager = new BukkitPlayerManager();
private EconHandler econ; private EconHandler econ;
private PermHandler perm;
@Override public int[] getServerVersion() { @Override public int[] getServerVersion() {
if (this.version == null) { if (this.version == null) {
@ -348,7 +351,10 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain<
} }
impromptuPipeline.storeImmediately("*", DBFunc.EVERYONE); impromptuPipeline.storeImmediately("*", DBFunc.EVERYONE);
this.startUuidCatching(sqLiteUUIDService, cacheUUIDService);
if (Settings.UUID.BACKGROUND_CACHING_ENABLED) {
this.startUuidCaching(sqLiteUUIDService, cacheUUIDService);
}
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
new Placeholders().register(); new Placeholders().register();
@ -485,7 +491,7 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain<
} }
} }
private void startUuidCatching(@NotNull final SQLiteUUIDService sqLiteUUIDService, private void startUuidCaching(@NotNull final SQLiteUUIDService sqLiteUUIDService,
@NotNull final CacheUUIDService cacheUUIDService) { @NotNull final CacheUUIDService cacheUUIDService) {
// Load all uuids into a big chunky boi queue // Load all uuids into a big chunky boi queue
final Queue<UUID> uuidQueue = new LinkedBlockingQueue<>(); final Queue<UUID> uuidQueue = new LinkedBlockingQueue<>();
@ -625,46 +631,46 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain<
Iterator<Entity> iterator = entities.iterator(); Iterator<Entity> iterator = entities.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
Entity entity = iterator.next(); Entity entity = iterator.next();
switch (entity.getType()) { switch (entity.getType().toString()) {
case EGG: case "EGG":
case FISHING_HOOK: case "FISHING_HOOK":
case ENDER_SIGNAL: case "ENDER_SIGNAL":
case AREA_EFFECT_CLOUD: case "AREA_EFFECT_CLOUD":
case EXPERIENCE_ORB: case "EXPERIENCE_ORB":
case LEASH_HITCH: case "LEASH_HITCH":
case FIREWORK: case "FIREWORK":
case LIGHTNING: case "LIGHTNING":
case WITHER_SKULL: case "WITHER_SKULL":
case UNKNOWN: case "UNKNOWN":
case PLAYER: case "PLAYER":
// non moving / unmovable // non moving / unmovable
continue; continue;
case THROWN_EXP_BOTTLE: case "THROWN_EXP_BOTTLE":
case SPLASH_POTION: case "SPLASH_POTION":
case SNOWBALL: case "SNOWBALL":
case SHULKER_BULLET: case "SHULKER_BULLET":
case SPECTRAL_ARROW: case "SPECTRAL_ARROW":
case ENDER_PEARL: case "ENDER_PEARL":
case ARROW: case "ARROW":
case LLAMA_SPIT: case "LLAMA_SPIT":
case TRIDENT: case "TRIDENT":
// managed elsewhere | projectile // managed elsewhere | projectile
continue; continue;
case ITEM_FRAME: case "ITEM_FRAME":
case PAINTING: case "PAINTING":
// Not vehicles // Not vehicles
continue; continue;
case ARMOR_STAND: case "ARMOR_STAND":
// Temporarily classify as vehicle // Temporarily classify as vehicle
case MINECART: case "MINECART":
case MINECART_CHEST: case "MINECART_CHEST":
case MINECART_COMMAND: case "MINECART_COMMAND":
case MINECART_FURNACE: case "MINECART_FURNACE":
case MINECART_HOPPER: case "MINECART_HOPPER":
case MINECART_MOB_SPAWNER: case "MINECART_MOB_SPAWNER":
case ENDER_CRYSTAL: case "ENDER_CRYSTAL":
case MINECART_TNT: case "MINECART_TNT":
case BOAT: case "BOAT":
if (Settings.Enabled_Components.KILL_ROAD_VEHICLES) { if (Settings.Enabled_Components.KILL_ROAD_VEHICLES) {
com.plotsquared.core.location.Location location = com.plotsquared.core.location.Location location =
BukkitUtil.getLocation(entity.getLocation()); BukkitUtil.getLocation(entity.getLocation());
@ -693,10 +699,10 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain<
} }
} }
continue; continue;
case SMALL_FIREBALL: case "SMALL_FIREBALL":
case FIREBALL: case "FIREBALL":
case DRAGON_FIREBALL: case "DRAGON_FIREBALL":
case DROPPED_ITEM: case "DROPPED_ITEM":
if (Settings.Enabled_Components.KILL_ROAD_ITEMS && plotArea if (Settings.Enabled_Components.KILL_ROAD_ITEMS && plotArea
.getOwnedPlotAbs(BukkitUtil.getLocation(entity.getLocation())) .getOwnedPlotAbs(BukkitUtil.getLocation(entity.getLocation()))
== null) { == null) {
@ -704,11 +710,11 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain<
} }
// dropped item // dropped item
continue; continue;
case PRIMED_TNT: case "PRIMED_TNT":
case FALLING_BLOCK: case "FALLING_BLOCK":
// managed elsewhere // managed elsewhere
continue; continue;
case SHULKER: case "SHULKER":
if (Settings.Enabled_Components.KILL_ROAD_MOBS) { if (Settings.Enabled_Components.KILL_ROAD_MOBS) {
LivingEntity livingEntity = (LivingEntity) entity; LivingEntity livingEntity = (LivingEntity) entity;
List<MetadataValue> meta = entity.getMetadata("shulkerPlot"); List<MetadataValue> meta = entity.getMetadata("shulkerPlot");
@ -756,71 +762,76 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain<
} }
} }
continue; continue;
case LLAMA: case "ZOMBIFIED_PIGLIN":
case DONKEY: case "LLAMA":
case MULE: case "DONKEY":
case ZOMBIE_HORSE: case "MULE":
case SKELETON_HORSE: case "ZOMBIE_HORSE":
case HUSK: case "SKELETON_HORSE":
case ELDER_GUARDIAN: case "HUSK":
case WITHER_SKELETON: case "ELDER_GUARDIAN":
case STRAY: case "WITHER_SKELETON":
case ZOMBIE_VILLAGER: case "STRAY":
case EVOKER: case "ZOMBIE_VILLAGER":
case EVOKER_FANGS: case "EVOKER":
case VEX: case "EVOKER_FANGS":
case VINDICATOR: case "VEX":
case POLAR_BEAR: case "VINDICATOR":
case BAT: case "POLAR_BEAR":
case BLAZE: case "BAT":
case CAVE_SPIDER: case "BLAZE":
case CHICKEN: case "CAVE_SPIDER":
case COW: case "CHICKEN":
case CREEPER: case "COW":
case ENDERMAN: case "CREEPER":
case ENDERMITE: case "ENDERMAN":
case ENDER_DRAGON: case "ENDERMITE":
case GHAST: case "ENDER_DRAGON":
case GIANT: case "GHAST":
case GUARDIAN: case "GIANT":
case HORSE: case "GUARDIAN":
case IRON_GOLEM: case "HORSE":
case MAGMA_CUBE: case "IRON_GOLEM":
case MUSHROOM_COW: case "MAGMA_CUBE":
case OCELOT: case "MUSHROOM_COW":
case PIG: case "OCELOT":
case PIG_ZOMBIE: case "PIG":
case RABBIT: case "PIG_ZOMBIE":
case SHEEP: case "RABBIT":
case SILVERFISH: case "SHEEP":
case SKELETON: case "SILVERFISH":
case SLIME: case "SKELETON":
case SNOWMAN: case "SLIME":
case SPIDER: case "SNOWMAN":
case SQUID: case "SPIDER":
case VILLAGER: case "SQUID":
case WITCH: case "VILLAGER":
case WITHER: case "WITCH":
case WOLF: case "WITHER":
case ZOMBIE: case "WOLF":
case PARROT: case "ZOMBIE":
case SALMON: case "PARROT":
case DOLPHIN: case "SALMON":
case TROPICAL_FISH: case "DOLPHIN":
case DROWNED: case "TROPICAL_FISH":
case COD: case "DROWNED":
case TURTLE: case "COD":
case PUFFERFISH: case "TURTLE":
case PHANTOM: case "PUFFERFISH":
case ILLUSIONER: case "PHANTOM":
case CAT: case "ILLUSIONER":
case PANDA: case "CAT":
case FOX: case "PANDA":
case PILLAGER: case "FOX":
case TRADER_LLAMA: case "PILLAGER":
case WANDERING_TRADER: case "TRADER_LLAMA":
case RAVAGER: case "WANDERING_TRADER":
//case BEE: case "RAVAGER":
case "BEE":
case "HOGLIN":
case "PIGLIN":
case "ZOGLIN":
break;
default: { default: {
if (Settings.Enabled_Components.KILL_ROAD_MOBS) { if (Settings.Enabled_Components.KILL_ROAD_MOBS) {
Location location = entity.getLocation(); Location location = entity.getLocation();
@ -902,7 +913,7 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain<
@Override public EconHandler getEconomyHandler() { @Override public EconHandler getEconomyHandler() {
if (econ != null) { if (econ != null) {
if (econ.init() /* is inited*/) { if (econ.init() /* is inited */) {
return econ; return econ;
} else { } else {
return null; return null;
@ -920,6 +931,26 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain<
return null; return null;
} }
@Override public PermHandler getPermissionHandler() {
if (perm != null) {
if (perm.init() /* is inited */) {
return perm;
} else {
return null;
}
}
try {
perm = new BukkitPermHandler();
if (perm.init()) {
return perm;
}
} catch (Throwable ignored) {
PlotSquared.debug("No permissions detected!");
}
return null;
}
@Override public QueueProvider initBlockQueue() { @Override public QueueProvider initBlockQueue() {
//TODO Figure out why this code is still here yet isn't being called anywhere. //TODO Figure out why this code is still here yet isn't being called anywhere.
// try { // try {

View File

@ -103,51 +103,51 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
if (!entity.hasGravity()) { if (!entity.hasGravity()) {
this.noGravity = true; this.noGravity = true;
} }
switch (entity.getType()) { switch (entity.getType().toString()) {
case BOAT: case "BOAT":
Boat boat = (Boat) entity; Boat boat = (Boat) entity;
this.dataByte = getOrdinal(TreeSpecies.values(), boat.getWoodType()); this.dataByte = getOrdinal(TreeSpecies.values(), boat.getWoodType());
return; return;
case ARROW: case "ARROW":
case EGG: case "EGG":
case ENDER_CRYSTAL: case "ENDER_CRYSTAL":
case ENDER_PEARL: case "ENDER_PEARL":
case ENDER_SIGNAL: case "ENDER_SIGNAL":
case EXPERIENCE_ORB: case "EXPERIENCE_ORB":
case FALLING_BLOCK: case "FALLING_BLOCK":
case FIREBALL: case "FIREBALL":
case FIREWORK: case "FIREWORK":
case FISHING_HOOK: case "FISHING_HOOK":
case LEASH_HITCH: case "LEASH_HITCH":
case LIGHTNING: case "LIGHTNING":
case MINECART: case "MINECART":
case MINECART_COMMAND: case "MINECART_COMMAND":
case MINECART_MOB_SPAWNER: case "MINECART_MOB_SPAWNER":
case MINECART_TNT: case "MINECART_TNT":
case PLAYER: case "PLAYER":
case PRIMED_TNT: case "PRIMED_TNT":
case SLIME: case "SLIME":
case SMALL_FIREBALL: case "SMALL_FIREBALL":
case SNOWBALL: case "SNOWBALL":
case MINECART_FURNACE: case "MINECART_FURNACE":
case SPLASH_POTION: case "SPLASH_POTION":
case THROWN_EXP_BOTTLE: case "THROWN_EXP_BOTTLE":
case WITHER_SKULL: case "WITHER_SKULL":
case UNKNOWN: case "UNKNOWN":
case SPECTRAL_ARROW: case "SPECTRAL_ARROW":
case SHULKER_BULLET: case "SHULKER_BULLET":
case DRAGON_FIREBALL: case "DRAGON_FIREBALL":
case AREA_EFFECT_CLOUD: case "AREA_EFFECT_CLOUD":
case TRIDENT: case "TRIDENT":
case LLAMA_SPIT: case "LLAMA_SPIT":
// Do this stuff later // Do this stuff later
return; return;
// MISC // // MISC //
case DROPPED_ITEM: case "DROPPED_ITEM":
Item item = (Item) entity; Item item = (Item) entity;
this.stack = item.getItemStack(); this.stack = item.getItemStack();
return; return;
case ITEM_FRAME: case "ITEM_FRAME":
this.x = Math.floor(this.x); this.x = Math.floor(this.x);
this.y = Math.floor(this.y); this.y = Math.floor(this.y);
this.z = Math.floor(this.z); this.z = Math.floor(this.z);
@ -155,7 +155,7 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
this.dataByte = getOrdinal(Rotation.values(), itemFrame.getRotation()); this.dataByte = getOrdinal(Rotation.values(), itemFrame.getRotation());
this.stack = itemFrame.getItem().clone(); this.stack = itemFrame.getItem().clone();
return; return;
case PAINTING: case "PAINTING":
this.x = Math.floor(this.x); this.x = Math.floor(this.x);
this.y = Math.floor(this.y); this.y = Math.floor(this.y);
this.z = Math.floor(this.z); this.z = Math.floor(this.z);
@ -170,18 +170,18 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
return; return;
// END MISC // // END MISC //
// INVENTORY HOLDER // // INVENTORY HOLDER //
case MINECART_CHEST: case "MINECART_CHEST":
case MINECART_HOPPER: case "MINECART_HOPPER":
storeInventory((InventoryHolder) entity); storeInventory((InventoryHolder) entity);
return; return;
// START LIVING ENTITY // // START LIVING ENTITY //
// START AGEABLE // // START AGEABLE //
// START TAMEABLE // // START TAMEABLE //
case HORSE: case "HORSE":
case DONKEY: case "DONKEY":
case LLAMA: case "LLAMA":
case MULE: case "MULE":
case SKELETON_HORSE: case "SKELETON_HORSE":
AbstractHorse horse = (AbstractHorse) entity; AbstractHorse horse = (AbstractHorse) entity;
this.horse = new HorseStats(); this.horse = new HorseStats();
this.horse.jump = horse.getJumpStrength(); this.horse.jump = horse.getJumpStrength();
@ -199,15 +199,15 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
storeInventory(horse); storeInventory(horse);
return; return;
// END INVENTORY HOLDER // // END INVENTORY HOLDER //
case WOLF: case "WOLF":
case OCELOT: case "OCELOT":
storeTameable((Tameable) entity); storeTameable((Tameable) entity);
storeAgeable((Ageable) entity); storeAgeable((Ageable) entity);
storeLiving((LivingEntity) entity); storeLiving((LivingEntity) entity);
return; return;
// END TAMEABLE // // END TAMEABLE //
//todo fix sheep //todo fix sheep
case SHEEP: case "SHEEP":
Sheep sheep = (Sheep) entity; Sheep sheep = (Sheep) entity;
if (sheep.isSheared()) { if (sheep.isSheared()) {
this.dataByte = (byte) 1; this.dataByte = (byte) 1;
@ -218,23 +218,23 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
storeAgeable(sheep); storeAgeable(sheep);
storeLiving(sheep); storeLiving(sheep);
return; return;
case VILLAGER: case "VILLAGER":
case CHICKEN: case "CHICKEN":
case COW: case "COW":
case MUSHROOM_COW: case "MUSHROOM_COW":
case PIG: case "PIG":
case TURTLE: case "TURTLE":
case POLAR_BEAR: case "POLAR_BEAR":
storeAgeable((Ageable) entity); storeAgeable((Ageable) entity);
storeLiving((LivingEntity) entity); storeLiving((LivingEntity) entity);
return; return;
case RABBIT: case "RABBIT":
this.dataByte = getOrdinal(Rabbit.Type.values(), ((Rabbit) entity).getRabbitType()); this.dataByte = getOrdinal(Rabbit.Type.values(), ((Rabbit) entity).getRabbitType());
storeAgeable((Ageable) entity); storeAgeable((Ageable) entity);
storeLiving((LivingEntity) entity); storeLiving((LivingEntity) entity);
return; return;
// END AGEABLE // // END AGEABLE //
case ARMOR_STAND: case "ARMOR_STAND":
ArmorStand stand = (ArmorStand) entity; ArmorStand stand = (ArmorStand) entity;
this.inventory = this.inventory =
new ItemStack[] {stand.getItemInHand().clone(), stand.getHelmet().clone(), new ItemStack[] {stand.getItemInHand().clone(), stand.getHelmet().clone(),
@ -286,42 +286,45 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
this.stand.small = true; this.stand.small = true;
} }
return; return;
case ENDERMITE: case "ENDERMITE":
return; return;
case BAT: case "BAT":
if (((Bat) entity).isAwake()) { if (((Bat) entity).isAwake()) {
this.dataByte = (byte) 1; this.dataByte = (byte) 1;
} else { } else {
this.dataByte = (byte) 0; this.dataByte = (byte) 0;
} }
return; return;
case ENDER_DRAGON: case "ENDER_DRAGON":
EnderDragon entity1 = (EnderDragon) entity; EnderDragon entity1 = (EnderDragon) entity;
this.dataByte = (byte) entity1.getPhase().ordinal(); this.dataByte = (byte) entity1.getPhase().ordinal();
return; return;
case SKELETON: case "SKELETON":
case WITHER_SKELETON: case "WITHER_SKELETON":
case GUARDIAN: case "GUARDIAN":
case ELDER_GUARDIAN: case "ELDER_GUARDIAN":
case GHAST: case "GHAST":
case MAGMA_CUBE: case "MAGMA_CUBE":
case SQUID: case "SQUID":
case PIG_ZOMBIE: case "PIG_ZOMBIE":
case ZOMBIE: case "HOGLIN":
case WITHER: case "ZOMBIFIED_PIGLIN":
case WITCH: case "PIGLIN":
case SPIDER: case "ZOMBIE":
case CAVE_SPIDER: case "WITHER":
case SILVERFISH: case "WITCH":
case GIANT: case "SPIDER":
case ENDERMAN: case "CAVE_SPIDER":
case CREEPER: case "SILVERFISH":
case BLAZE: case "GIANT":
case SHULKER: case "ENDERMAN":
case SNOWMAN: case "CREEPER":
case "BLAZE":
case "SHULKER":
case "SNOWMAN":
storeLiving((LivingEntity) entity); storeLiving((LivingEntity) entity);
return; return;
case IRON_GOLEM: case "IRON_GOLEM":
if (((IronGolem) entity).isPlayerCreated()) { if (((IronGolem) entity).isPlayerCreated()) {
this.dataByte = (byte) 1; this.dataByte = (byte) 1;
} else { } else {
@ -463,16 +466,16 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
return null; return null;
} }
Entity entity; Entity entity;
switch (this.getType()) { switch (this.getType().toString()) {
case DROPPED_ITEM: case "DROPPED_ITEM":
return world.dropItem(location, this.stack); return world.dropItem(location, this.stack);
case PLAYER: case "PLAYER":
case LEASH_HITCH: case "LEASH_HITCH":
return null; return null;
case ITEM_FRAME: case "ITEM_FRAME":
entity = world.spawn(location, ItemFrame.class); entity = world.spawn(location, ItemFrame.class);
break; break;
case PAINTING: case "PAINTING":
entity = world.spawn(location, Painting.class); entity = world.spawn(location, Painting.class);
break; break;
default: default:
@ -504,73 +507,73 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
if (this.noGravity) { if (this.noGravity) {
entity.setGravity(false); entity.setGravity(false);
} }
switch (entity.getType()) { switch (entity.getType().toString()) {
case BOAT: case "BOAT":
Boat boat = (Boat) entity; Boat boat = (Boat) entity;
boat.setWoodType(TreeSpecies.values()[dataByte]); boat.setWoodType(TreeSpecies.values()[dataByte]);
return entity; return entity;
case SLIME: case "SLIME":
((Slime) entity).setSize(this.dataByte); ((Slime) entity).setSize(this.dataByte);
return entity; return entity;
case ARROW: case "ARROW":
case EGG: case "EGG":
case ENDER_CRYSTAL: case "ENDER_CRYSTAL":
case ENDER_PEARL: case "ENDER_PEARL":
case ENDER_SIGNAL: case "ENDER_SIGNAL":
case DROPPED_ITEM: case "DROPPED_ITEM":
case EXPERIENCE_ORB: case "EXPERIENCE_ORB":
case FALLING_BLOCK: case "FALLING_BLOCK":
case FIREBALL: case "FIREBALL":
case FIREWORK: case "FIREWORK":
case FISHING_HOOK: case "FISHING_HOOK":
case LEASH_HITCH: case "LEASH_HITCH":
case LIGHTNING: case "LIGHTNING":
case MINECART: case "MINECART":
case MINECART_COMMAND: case "MINECART_COMMAND":
case MINECART_MOB_SPAWNER: case "MINECART_MOB_SPAWNER":
case MINECART_TNT: case "MINECART_TNT":
case PLAYER: case "PLAYER":
case PRIMED_TNT: case "PRIMED_TNT":
case SMALL_FIREBALL: case "SMALL_FIREBALL":
case SNOWBALL: case "SNOWBALL":
case SPLASH_POTION: case "SPLASH_POTION":
case THROWN_EXP_BOTTLE: case "THROWN_EXP_BOTTLE":
case SPECTRAL_ARROW: case "SPECTRAL_ARROW":
case SHULKER_BULLET: case "SHULKER_BULLET":
case AREA_EFFECT_CLOUD: case "AREA_EFFECT_CLOUD":
case DRAGON_FIREBALL: case "DRAGON_FIREBALL":
case WITHER_SKULL: case "WITHER_SKULL":
case MINECART_FURNACE: case "MINECART_FURNACE":
case LLAMA_SPIT: case "LLAMA_SPIT":
case TRIDENT: case "TRIDENT":
case UNKNOWN: case "UNKNOWN":
// Do this stuff later // Do this stuff later
return entity; return entity;
// MISC // // MISC //
case ITEM_FRAME: case "ITEM_FRAME":
ItemFrame itemframe = (ItemFrame) entity; ItemFrame itemframe = (ItemFrame) entity;
itemframe.setRotation(Rotation.values()[this.dataByte]); itemframe.setRotation(Rotation.values()[this.dataByte]);
itemframe.setItem(this.stack); itemframe.setItem(this.stack);
return entity; return entity;
case PAINTING: case "PAINTING":
Painting painting = (Painting) entity; Painting painting = (Painting) entity;
painting.setFacingDirection(BlockFace.values()[this.dataByte], true); painting.setFacingDirection(BlockFace.values()[this.dataByte], true);
painting.setArt(Art.getByName(this.dataString), true); painting.setArt(Art.getByName(this.dataString), true);
return entity; return entity;
// END MISC // // END MISC //
// INVENTORY HOLDER // // INVENTORY HOLDER //
case MINECART_CHEST: case "MINECART_CHEST":
case MINECART_HOPPER: case "MINECART_HOPPER":
restoreInventory((InventoryHolder) entity); restoreInventory((InventoryHolder) entity);
return entity; return entity;
// START LIVING ENTITY // // START LIVING ENTITY //
// START AGEABLE // // START AGEABLE //
// START TAMEABLE // // START TAMEABLE //
case HORSE: case "HORSE":
case LLAMA: case "LLAMA":
case SKELETON_HORSE: case "SKELETON_HORSE":
case DONKEY: case "DONKEY":
case MULE: case "MULE":
AbstractHorse horse = (AbstractHorse) entity; AbstractHorse horse = (AbstractHorse) entity;
horse.setJumpStrength(this.horse.jump); horse.setJumpStrength(this.horse.jump);
if (horse instanceof ChestedHorse) { if (horse instanceof ChestedHorse) {
@ -586,14 +589,14 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
restoreInventory(horse); restoreInventory(horse);
return entity; return entity;
// END INVENTORY HOLDER // // END INVENTORY HOLDER //
case WOLF: case "WOLF":
case OCELOT: case "OCELOT":
restoreTameable((Tameable) entity); restoreTameable((Tameable) entity);
restoreAgeable((Ageable) entity); restoreAgeable((Ageable) entity);
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
// END AGEABLE // // END AGEABLE //
case SHEEP: case "SHEEP":
Sheep sheep = (Sheep) entity; Sheep sheep = (Sheep) entity;
if (this.dataByte == 1) { if (this.dataByte == 1) {
sheep.setSheared(true); sheep.setSheared(true);
@ -604,25 +607,25 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
restoreAgeable(sheep); restoreAgeable(sheep);
restoreLiving(sheep); restoreLiving(sheep);
return sheep; return sheep;
case VILLAGER: case "VILLAGER":
case CHICKEN: case "CHICKEN":
case COW: case "COW":
case TURTLE: case "TURTLE":
case POLAR_BEAR: case "POLAR_BEAR":
case MUSHROOM_COW: case "MUSHROOM_COW":
case PIG: case "PIG":
restoreAgeable((Ageable) entity); restoreAgeable((Ageable) entity);
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
// END AGEABLE // // END AGEABLE //
case RABBIT: case "RABBIT":
if (this.dataByte != 0) { if (this.dataByte != 0) {
((Rabbit) entity).setRabbitType(Rabbit.Type.values()[this.dataByte]); ((Rabbit) entity).setRabbitType(Rabbit.Type.values()[this.dataByte]);
} }
restoreAgeable((Ageable) entity); restoreAgeable((Ageable) entity);
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
case ARMOR_STAND: case "ARMOR_STAND":
// CHECK positions // CHECK positions
ArmorStand stand = (ArmorStand) entity; ArmorStand stand = (ArmorStand) entity;
if (this.inventory[0] != null) { if (this.inventory[0] != null) {
@ -688,42 +691,45 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
} }
restoreLiving(stand); restoreLiving(stand);
return stand; return stand;
case BAT: case "BAT":
if (this.dataByte != 0) { if (this.dataByte != 0) {
((Bat) entity).setAwake(true); ((Bat) entity).setAwake(true);
} }
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
case ENDER_DRAGON: case "ENDER_DRAGON":
if (this.dataByte != 0) { if (this.dataByte != 0) {
((EnderDragon) entity).setPhase(EnderDragon.Phase.values()[this.dataByte]); ((EnderDragon) entity).setPhase(EnderDragon.Phase.values()[this.dataByte]);
} }
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
case ENDERMITE: case "ENDERMITE":
case GHAST: case "GHAST":
case MAGMA_CUBE: case "MAGMA_CUBE":
case SQUID: case "SQUID":
case PIG_ZOMBIE: case "PIG_ZOMBIE":
case ZOMBIE: case "HOGLIN":
case WITHER: case "PIGLIN":
case WITCH: case "ZOMBIFIED_PIGLIN":
case SPIDER: case "ZOMBIE":
case CAVE_SPIDER: case "WITHER":
case SILVERFISH: case "WITCH":
case GIANT: case "SPIDER":
case ENDERMAN: case "CAVE_SPIDER":
case CREEPER: case "SILVERFISH":
case BLAZE: case "GIANT":
case SNOWMAN: case "ENDERMAN":
case SHULKER: case "CREEPER":
case GUARDIAN: case "BLAZE":
case ELDER_GUARDIAN: case "SNOWMAN":
case SKELETON: case "SHULKER":
case WITHER_SKELETON: case "GUARDIAN":
case "ELDER_GUARDIAN":
case "SKELETON":
case "WITHER_SKELETON":
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
case IRON_GOLEM: case "IRON_GOLEM":
if (this.dataByte != 0) { if (this.dataByte != 0) {
((IronGolem) entity).setPlayerCreated(true); ((IronGolem) entity).setPlayerCreated(true);
} }

View File

@ -43,6 +43,7 @@ import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotHandler; import com.plotsquared.core.plot.PlotHandler;
import com.plotsquared.core.plot.PlotId; import com.plotsquared.core.plot.PlotId;
import com.plotsquared.core.plot.PlotInventory; import com.plotsquared.core.plot.PlotInventory;
import com.plotsquared.core.plot.flag.FlagContainer;
import com.plotsquared.core.plot.flag.implementations.AnimalAttackFlag; import com.plotsquared.core.plot.flag.implementations.AnimalAttackFlag;
import com.plotsquared.core.plot.flag.implementations.AnimalCapFlag; import com.plotsquared.core.plot.flag.implementations.AnimalCapFlag;
import com.plotsquared.core.plot.flag.implementations.AnimalInteractFlag; import com.plotsquared.core.plot.flag.implementations.AnimalInteractFlag;
@ -226,8 +227,8 @@ import java.util.regex.Pattern;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class PlayerEvents extends PlotListener implements Listener { public class PlayerEvents extends PlotListener implements Listener {
public static final com.sk89q.worldedit.world.entity.EntityType FAKE_ENTITY_TYPE public static final com.sk89q.worldedit.world.entity.EntityType FAKE_ENTITY_TYPE =
= new com.sk89q.worldedit.world.entity.EntityType("plotsquared:fake"); new com.sk89q.worldedit.world.entity.EntityType("plotsquared:fake");
private boolean pistonBlocks = true; private boolean pistonBlocks = true;
private float lastRadius; private float lastRadius;
@ -342,6 +343,9 @@ public class PlayerEvents extends PlotListener implements Listener {
} }
Plot plot = location.getOwnedPlot(); Plot plot = location.getOwnedPlot();
if (plot == null) { if (plot == null) {
if (area.isRoadFlags() && area.getRoadFlag(RedstoneFlag.class)) {
event.setNewCurrent(0);
}
return; return;
} }
if (!plot.getFlag(RedstoneFlag.class)) { if (!plot.getFlag(RedstoneFlag.class)) {
@ -361,7 +365,9 @@ public class PlayerEvents extends PlotListener implements Listener {
} }
} }
} else { } else {
disable = PlotSquared.imp().getPlayerManager().getPlayerIfExists(plot.getOwnerAbs()) == null; disable =
PlotSquared.imp().getPlayerManager().getPlayerIfExists(plot.getOwnerAbs())
== null;
} }
} }
if (disable) { if (disable) {
@ -373,7 +379,8 @@ public class PlayerEvents extends PlotListener implements Listener {
} }
if (disable) { if (disable) {
event.setNewCurrent(0); event.setNewCurrent(0);
plot.debug("Redstone event was cancelled because no trusted player was in the plot"); plot.debug(
"Redstone event was cancelled because no trusted player was in the plot");
return; return;
} }
} }
@ -464,7 +471,8 @@ public class PlayerEvents extends PlotListener implements Listener {
Plot newPlot = area.getOwnedPlotAbs(location); Plot newPlot = area.getOwnedPlotAbs(location);
if (!plot.equals(newPlot)) { if (!plot.equals(newPlot)) {
event.setCancelled(true); event.setCancelled(true);
plot.debug("Prevented piston update because of invalid edge piston detection"); plot.debug(
"Prevented piston update because of invalid edge piston detection");
return; return;
} }
} }
@ -569,11 +577,13 @@ public class PlayerEvents extends PlotListener implements Listener {
return; return;
} }
} }
if (plot == null) { if (plot == null && !area.isRoadFlags()) {
return; return;
} }
List<String> blockedCommands = plot.getFlag(BlockedCmdsFlag.class); List<String> blockedCommands = plot != null ?
plot.getFlag(BlockedCmdsFlag.class) :
area.getFlag(BlockedCmdsFlag.class);
if (!blockedCommands.isEmpty() && !Permissions if (!blockedCommands.isEmpty() && !Permissions
.hasPermission(plotPlayer, Captions.PERMISSION_ADMIN_INTERACT_BLOCKED_CMDS)) { .hasPermission(plotPlayer, Captions.PERMISSION_ADMIN_INTERACT_BLOCKED_CMDS)) {
String part = parts[0]; String part = parts[0];
@ -618,10 +628,10 @@ public class PlayerEvents extends PlotListener implements Listener {
} }
if (pattern.matcher(msg).matches()) { if (pattern.matcher(msg).matches()) {
String perm; String perm;
if (plot.isAdded(plotPlayer.getUUID())) { if (plot != null && plot.isAdded(plotPlayer.getUUID())) {
perm = "plots.admin.command.blocked-cmds.shared"; perm = "plots.admin.command.blocked-cmds.shared";
} else { } else {
perm = "plots.admin.command.blocked-cmds.other"; perm = "plots.admin.command.blocked-cmds.road";
} }
if (!Permissions.hasPermission(plotPlayer, perm)) { if (!Permissions.hasPermission(plotPlayer, perm)) {
MainUtil.sendMessage(plotPlayer, Captions.COMMAND_BLOCKED); MainUtil.sendMessage(plotPlayer, Captions.COMMAND_BLOCKED);
@ -638,11 +648,11 @@ public class PlayerEvents extends PlotListener implements Listener {
final UUID uuid; final UUID uuid;
if (Settings.UUID.OFFLINE) { if (Settings.UUID.OFFLINE) {
if (Settings.UUID.FORCE_LOWERCASE) { if (Settings.UUID.FORCE_LOWERCASE) {
uuid = UUID.nameUUIDFromBytes(("OfflinePlayer:" + uuid = UUID.nameUUIDFromBytes(
event.getName().toLowerCase()).getBytes(Charsets.UTF_8)); ("OfflinePlayer:" + event.getName().toLowerCase()).getBytes(Charsets.UTF_8));
} else { } else {
uuid = UUID.nameUUIDFromBytes(("OfflinePlayer:" + uuid = UUID.nameUUIDFromBytes(
event.getName()).getBytes(Charsets.UTF_8)); ("OfflinePlayer:" + event.getName()).getBytes(Charsets.UTF_8));
} }
} else { } else {
uuid = event.getUniqueId(); uuid = event.getUniqueId();
@ -1328,8 +1338,8 @@ public class PlayerEvents extends PlotListener implements Listener {
.hasPermission(plotPlayer, Captions.PERMISSION_ADMIN_DESTROY_OTHER)) { .hasPermission(plotPlayer, Captions.PERMISSION_ADMIN_DESTROY_OTHER)) {
return; return;
} }
plot.debug(player.getName() + " could not break " + block.getType() + plot.debug(player.getName() + " could not break " + block.getType()
" because it was not in the break flag"); + " because it was not in the break flag");
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
@ -1389,6 +1399,11 @@ public class PlayerEvents extends PlotListener implements Listener {
case BUBBLE_CORAL_FAN: case BUBBLE_CORAL_FAN:
case FIRE_CORAL_FAN: case FIRE_CORAL_FAN:
case HORN_CORAL_FAN: case HORN_CORAL_FAN:
case BRAIN_CORAL_WALL_FAN:
case BUBBLE_CORAL_WALL_FAN:
case FIRE_CORAL_WALL_FAN:
case HORN_CORAL_WALL_FAN:
case TUBE_CORAL_WALL_FAN:
if (!plot.getFlag(CoralDryFlag.class)) { if (!plot.getFlag(CoralDryFlag.class)) {
plot.debug("Coral could not dry because coral-dry = false"); plot.debug("Coral could not dry because coral-dry = false");
event.setCancelled(true); event.setCancelled(true);
@ -1433,7 +1448,8 @@ public class PlayerEvents extends PlotListener implements Listener {
return; return;
} }
if (plot.getFlag(DisablePhysicsFlag.class)) { if (plot.getFlag(DisablePhysicsFlag.class)) {
plot.debug(event.getBlock().getType() + " could not update because disable-physics = true"); plot.debug(event.getBlock().getType()
+ " could not update because disable-physics = true");
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
@ -1714,13 +1730,24 @@ public class PlayerEvents extends PlotListener implements Listener {
if (event.getClick() == ClickType.CREATIVE) { if (event.getClick() == ClickType.CREATIVE) {
final Plot plot = pp.getCurrentPlot(); final Plot plot = pp.getCurrentPlot();
if (plot != null && if (plot != null) {
plot.getFlag(PreventCreativeCopyFlag.class) && if (plot.getFlag(PreventCreativeCopyFlag.class) && !plot
!plot.isAdded(player.getUniqueId()) && .isAdded(player.getUniqueId()) && !Permissions
!Permissions.hasPermission(pp, Captions.PERMISSION_ADMIN_INTERACT_OTHER)) { .hasPermission(pp, Captions.PERMISSION_ADMIN_INTERACT_OTHER)) {
final ItemStack newStack = new ItemStack(newItem.getType(), newItem.getAmount()); final ItemStack newStack =
event.setCursor(newStack); new ItemStack(newItem.getType(), newItem.getAmount());
plot.debug(player.getName() + " could not creative-copy an item because prevent-creative-copy = true"); event.setCursor(newStack);
plot.debug(player.getName()
+ " could not creative-copy an item because prevent-creative-copy = true");
}
} else {
PlotArea area = pp.getPlotAreaAbs();
if (area != null && area.isRoadFlags() && area
.getRoadFlag(PreventCreativeCopyFlag.class)) {
final ItemStack newStack =
new ItemStack(newItem.getType(), newItem.getAmount());
event.setCursor(newStack);
}
} }
return; return;
} }
@ -1837,7 +1864,8 @@ public class PlayerEvents extends PlotListener implements Listener {
Plot plot = location.getPlotAbs(); Plot plot = location.getPlotAbs();
BukkitPlayer pp = BukkitUtil.getPlayer(e.getPlayer()); BukkitPlayer pp = BukkitUtil.getPlayer(e.getPlayer());
if (plot == null) { if (plot == null) {
if (!Permissions.hasPermission(pp, "plots.admin.interact.road")) { if (!area.isRoadFlags() && !area.getRoadFlag(MiscInteractFlag.class)
&& !Permissions.hasPermission(pp, "plots.admin.interact.road")) {
MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT, "plots.admin.interact.road"); MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT, "plots.admin.interact.road");
e.setCancelled(true); e.setCancelled(true);
} }
@ -1850,7 +1878,8 @@ public class PlayerEvents extends PlotListener implements Listener {
return; return;
} }
} }
if (!plot.hasOwner()) { if (!plot.hasOwner() && !area.isRoadFlags() && !area
.getRoadFlag(MiscInteractFlag.class)) {
if (!Permissions.hasPermission(pp, "plots.admin.interact.unowned")) { if (!Permissions.hasPermission(pp, "plots.admin.interact.unowned")) {
MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT, MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT,
"plots.admin.interact.unowned"); "plots.admin.interact.unowned");
@ -1868,7 +1897,8 @@ public class PlayerEvents extends PlotListener implements Listener {
MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT, MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT,
"plots.admin.interact.other"); "plots.admin.interact.other");
e.setCancelled(true); e.setCancelled(true);
plot.debug(pp.getName() + " could not interact with " + entity.getType() + " bcause misc-interact = false"); plot.debug(pp.getName() + " could not interact with " + entity.getType()
+ " bcause misc-interact = false");
} }
} }
} }
@ -2200,7 +2230,9 @@ public class PlayerEvents extends PlotListener implements Listener {
Plot plot = location.getOwnedPlot(); Plot plot = location.getOwnedPlot();
if (plot == null || !plot.getFlag(BlockBurnFlag.class)) { if (plot == null || !plot.getFlag(BlockBurnFlag.class)) {
plot.debug("Block burning was cancelled because block-burn = false"); if (plot != null) {
plot.debug("Block burning was cancelled because block-burn = false");
}
event.setCancelled(true); event.setCancelled(true);
} }
@ -2505,7 +2537,8 @@ public class PlayerEvents extends PlotListener implements Listener {
MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT, MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT,
Captions.PERMISSION_ADMIN_DESTROY_OTHER); Captions.PERMISSION_ADMIN_DESTROY_OTHER);
event.setCancelled(true); event.setCancelled(true);
plot.debug(p.getName() + " could not break hanging entity because hanging-break = false"); plot.debug(p.getName()
+ " could not break hanging entity because hanging-break = false");
} }
} }
} else if (remover instanceof Projectile) { } else if (remover instanceof Projectile) {
@ -2534,7 +2567,8 @@ public class PlayerEvents extends PlotListener implements Listener {
MainUtil.sendMessage(player, Captions.NO_PERMISSION_EVENT, MainUtil.sendMessage(player, Captions.NO_PERMISSION_EVENT,
Captions.PERMISSION_ADMIN_DESTROY_OTHER); Captions.PERMISSION_ADMIN_DESTROY_OTHER);
event.setCancelled(true); event.setCancelled(true);
plot.debug(player.getName() + " could not break hanging entity because hanging-break = false"); plot.debug(player.getName()
+ " could not break hanging entity because hanging-break = false");
} }
} }
} }
@ -2555,57 +2589,66 @@ public class PlayerEvents extends PlotListener implements Listener {
Player p = event.getPlayer(); Player p = event.getPlayer();
BukkitPlayer pp = BukkitUtil.getPlayer(p); BukkitPlayer pp = BukkitUtil.getPlayer(p);
Plot plot = area.getPlot(location); Plot plot = area.getPlot(location);
if (plot == null) { if (plot == null && !area.isRoadFlags()) {
if (!Permissions.hasPermission(pp, Captions.PERMISSION_ADMIN_INTERACT_ROAD)) { if (!Permissions.hasPermission(pp, Captions.PERMISSION_ADMIN_INTERACT_ROAD)) {
MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT, MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT,
Captions.PERMISSION_ADMIN_INTERACT_ROAD); Captions.PERMISSION_ADMIN_INTERACT_ROAD);
event.setCancelled(true); event.setCancelled(true);
} }
} else if (!plot.hasOwner()) { } else if (plot != null && !plot.hasOwner()) {
if (!Permissions.hasPermission(pp, Captions.PERMISSION_ADMIN_INTERACT_UNOWNED)) { if (!Permissions.hasPermission(pp, Captions.PERMISSION_ADMIN_INTERACT_UNOWNED)) {
MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT, MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT,
Captions.PERMISSION_ADMIN_INTERACT_UNOWNED); Captions.PERMISSION_ADMIN_INTERACT_UNOWNED);
event.setCancelled(true); event.setCancelled(true);
} }
} else if (!plot.isAdded(pp.getUUID())) { } else if ((plot != null && !plot.isAdded(pp.getUUID())) || area
.isRoadFlags()) {
final Entity entity = event.getRightClicked(); final Entity entity = event.getRightClicked();
final com.sk89q.worldedit.world.entity.EntityType entityType = final com.sk89q.worldedit.world.entity.EntityType entityType =
BukkitAdapter.adapt(entity.getType()); BukkitAdapter.adapt(entity.getType());
if (EntityCategories.HOSTILE.contains(entityType) && plot FlagContainer flagContainer;
.getFlag(HostileInteractFlag.class)) { if (plot == null) {
flagContainer = area.getRoadFlagContainer();
} else {
flagContainer = plot.getFlagContainer();
}
if (EntityCategories.HOSTILE.contains(entityType) && flagContainer
.getFlag(HostileInteractFlag.class).getValue()) {
return; return;
} }
if (EntityCategories.ANIMAL.contains(entityType) && plot if (EntityCategories.ANIMAL.contains(entityType) && flagContainer
.getFlag(AnimalInteractFlag.class)) { .getFlag(AnimalInteractFlag.class).getValue()) {
return; return;
} }
// This actually makes use of the interface, so we don't use the // This actually makes use of the interface, so we don't use the
// category // category
if (entity instanceof Tameable && ((Tameable) entity).isTamed() && plot if (entity instanceof Tameable && ((Tameable) entity).isTamed() && flagContainer
.getFlag(TamedInteractFlag.class)) { .getFlag(TamedInteractFlag.class).getValue()) {
return; return;
} }
if (EntityCategories.VEHICLE.contains(entityType) && plot if (EntityCategories.VEHICLE.contains(entityType) && flagContainer
.getFlag(VehicleUseFlag.class)) { .getFlag(VehicleUseFlag.class).getValue()) {
return; return;
} }
if (EntityCategories.PLAYER.contains(entityType) && plot if (EntityCategories.PLAYER.contains(entityType) && flagContainer
.getFlag(PlayerInteractFlag.class)) { .getFlag(PlayerInteractFlag.class).getValue()) {
return; return;
} }
if (EntityCategories.VILLAGER.contains(entityType) && plot if (EntityCategories.VILLAGER.contains(entityType) && flagContainer
.getFlag(VillagerInteractFlag.class)) { .getFlag(VillagerInteractFlag.class).getValue()) {
return; return;
} }
if ((EntityCategories.HANGING.contains(entityType) || EntityCategories.OTHER if ((EntityCategories.HANGING.contains(entityType) || EntityCategories.OTHER
.contains(entityType)) && plot.getFlag(MiscInteractFlag.class)) { .contains(entityType)) && flagContainer.getFlag(MiscInteractFlag.class)
.getValue()) {
return; return;
} }
@ -2653,7 +2696,8 @@ public class PlayerEvents extends PlotListener implements Listener {
MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT, MainUtil.sendMessage(pp, Captions.NO_PERMISSION_EVENT,
"plots.admin.vehicle.break.other"); "plots.admin.vehicle.break.other");
event.setCancelled(true); event.setCancelled(true);
plot.debug(pp.getName() + " could not break vehicle because vehicle-break = false"); plot.debug(pp.getName()
+ " could not break vehicle because vehicle-break = false");
} }
} }
} }
@ -2755,12 +2799,14 @@ public class PlayerEvents extends PlotListener implements Listener {
Plot plot; Plot plot;
String stub; String stub;
boolean isPlot = true;
if (dplot == null && vplot == null) { if (dplot == null && vplot == null) {
if (dArea == null) { if (dArea == null) {
return true; return true;
} }
plot = null; plot = null;
stub = "road"; stub = "road";
isPlot = false;
} else { } else {
// Prioritize plots for close to seamless pvp zones // Prioritize plots for close to seamless pvp zones
if (victim.getTicksLived() > damager.getTicksLived()) { if (victim.getTicksLived() > damager.getTicksLived()) {
@ -2790,6 +2836,8 @@ public class PlayerEvents extends PlotListener implements Listener {
stub = "unowned"; stub = "unowned";
} }
} }
boolean roadFlags = vArea != null ? vArea.isRoadFlags() : dArea.isRoadFlags();
PlotArea area = vArea != null ? vArea : dArea;
Player player; Player player;
if (damager instanceof Player) { // attacker is player if (damager instanceof Player) { // attacker is player
@ -2823,8 +2871,8 @@ public class PlayerEvents extends PlotListener implements Listener {
} }
if (EntityCategories.HANGING.contains(entityType)) { // hanging if (EntityCategories.HANGING.contains(entityType)) { // hanging
if (plot != null && (plot.getFlag(HangingBreakFlag.class)) || plot if (plot != null && (plot.getFlag(HangingBreakFlag.class) || plot
.isAdded(plotPlayer.getUUID())) { .isAdded(plotPlayer.getUUID()))) {
if (Settings.Done.RESTRICT_BUILDING && DoneFlag.isDone(plot)) { if (Settings.Done.RESTRICT_BUILDING && DoneFlag.isDone(plot)) {
if (!Permissions if (!Permissions
.hasPermission(plotPlayer, Captions.PERMISSION_ADMIN_BUILD_OTHER)) { .hasPermission(plotPlayer, Captions.PERMISSION_ADMIN_BUILD_OTHER)) {
@ -2849,47 +2897,63 @@ public class PlayerEvents extends PlotListener implements Listener {
MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT, MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT,
"plots.admin.destroy." + stub); "plots.admin.destroy." + stub);
if (plot != null) { if (plot != null) {
plot.debug(player.getName() + " could not break armor stand because misc-break = false"); plot.debug(player.getName()
+ " could not break armor stand because misc-break = false");
} }
return false; return false;
} }
} else if (EntityCategories.HOSTILE.contains(entityType)) { } else if (EntityCategories.HOSTILE.contains(entityType)) {
if (plot != null && (plot.getFlag(HostileAttackFlag.class) || plot if (isPlot) {
.getFlag(PveFlag.class) || plot.isAdded(plotPlayer.getUUID()))) { if (plot.getFlag(HostileAttackFlag.class) || plot.getFlag(PveFlag.class) || plot
.isAdded(plotPlayer.getUUID())) {
return true;
}
} else if (roadFlags && (area.getRoadFlag(HostileAttackFlag.class) || area
.getFlag(PveFlag.class))) {
return true; return true;
} }
if (!Permissions.hasPermission(plotPlayer, "plots.admin.pve." + stub)) { if (!Permissions.hasPermission(plotPlayer, "plots.admin.pve." + stub)) {
MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT, MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT,
"plots.admin.pve." + stub); "plots.admin.pve." + stub);
if (plot != null) { if (plot != null) {
plot.debug(player.getName() + " could not attack " + entityType + " because pve = false OR hostile-attack = false"); plot.debug(player.getName() + " could not attack " + entityType
+ " because pve = false OR hostile-attack = false");
} }
return false; return false;
} }
} else if (EntityCategories.TAMEABLE.contains(entityType)) { // victim is tameable } else if (EntityCategories.TAMEABLE.contains(entityType)) { // victim is tameable
if (plot != null && (plot.getFlag(TamedAttackFlag.class) || plot if (isPlot) {
.getFlag(PveFlag.class) || plot.isAdded(plotPlayer.getUUID()))) { if (plot.getFlag(TamedAttackFlag.class) || plot.getFlag(PveFlag.class) || plot
.isAdded(plotPlayer.getUUID())) {
return true;
}
} else if (roadFlags && (area.getRoadFlag(TamedAttackFlag.class) || area
.getFlag(PveFlag.class))) {
return true; return true;
} }
if (!Permissions.hasPermission(plotPlayer, "plots.admin.pve." + stub)) { if (!Permissions.hasPermission(plotPlayer, "plots.admin.pve." + stub)) {
MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT, MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT,
"plots.admin.pve." + stub); "plots.admin.pve." + stub);
if (plot != null) { if (plot != null) {
plot.debug(player.getName() + " could not attack " + entityType + " because pve = false OR tamned-attack = false"); plot.debug(player.getName() + " could not attack " + entityType
+ " because pve = false OR tamned-attack = false");
} }
return false; return false;
} }
} else if (EntityCategories.PLAYER.contains(entityType)) { } else if (EntityCategories.PLAYER.contains(entityType)) {
if (plot != null) { if (isPlot) {
if (!plot.getFlag(PvpFlag.class) && !Permissions if (!plot.getFlag(PvpFlag.class) && !Permissions
.hasPermission(plotPlayer, "plots.admin.pvp." + stub)) { .hasPermission(plotPlayer, "plots.admin.pvp." + stub)) {
MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT, MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT,
"plots.admin.pvp." + stub); "plots.admin.pvp." + stub);
plot.debug(player.getName() + " could not attack " + entityType + " because pve = false"); plot.debug(player.getName() + " could not attack " + entityType
+ " because pve = false");
return false; return false;
} else { } else {
return true; return true;
} }
} else if (roadFlags && area.getRoadFlag(PvpFlag.class)) {
return true;
} }
if (!Permissions.hasPermission(plotPlayer, "plots.admin.pvp." + stub)) { if (!Permissions.hasPermission(plotPlayer, "plots.admin.pvp." + stub)) {
MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT, MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT,
@ -2897,29 +2961,38 @@ public class PlayerEvents extends PlotListener implements Listener {
return false; return false;
} }
} else if (EntityCategories.ANIMAL.contains(entityType)) { // victim is animal } else if (EntityCategories.ANIMAL.contains(entityType)) { // victim is animal
if (plot != null && (plot.getFlag(AnimalAttackFlag.class) || plot if (isPlot) {
.getFlag(PveFlag.class) || plot.isAdded(plotPlayer.getUUID()))) { if (plot.getFlag(AnimalAttackFlag.class) || plot.getFlag(PveFlag.class) || plot
plot.debug(player.getName() + " could not attack " + entityType + " because pve = false OR animal-attack = false"); .isAdded(plotPlayer.getUUID())) {
return true; plot.debug(player.getName() + " could not attack " + entityType
} + " because pve = false OR animal-attack = false");
if (!Permissions.hasPermission(plotPlayer, "plots.admin.pve." + stub)) { return true;
MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT, }
"plots.admin.pve." + stub); } else if (roadFlags && (area.getRoadFlag(AnimalAttackFlag.class) || area
return false; .getFlag(PveFlag.class))) {
if (!Permissions.hasPermission(plotPlayer, "plots.admin.pve." + stub)) {
MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT,
"plots.admin.pve." + stub);
return false;
}
} }
} else if (EntityCategories.VEHICLE } else if (EntityCategories.VEHICLE
.contains(entityType)) { // Vehicles are managed in vehicle destroy event .contains(entityType)) { // Vehicles are managed in vehicle destroy event
return true; return true;
} else { // victim is something else } else { // victim is something else
if (plot != null && (plot.getFlag(PveFlag.class) || plot if (isPlot) {
.isAdded(plotPlayer.getUUID()))) { if (plot.getFlag(PveFlag.class) || plot.isAdded(plotPlayer.getUUID())) {
return true;
}
} else if (roadFlags && area.getRoadFlag(PveFlag.class)) {
return true; return true;
} }
if (!Permissions.hasPermission(plotPlayer, "plots.admin.pve." + stub)) { if (!Permissions.hasPermission(plotPlayer, "plots.admin.pve." + stub)) {
MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT, MainUtil.sendMessage(plotPlayer, Captions.NO_PERMISSION_EVENT,
"plots.admin.pve." + stub); "plots.admin.pve." + stub);
if (plot != null) { if (plot != null) {
plot.debug(player.getName() + " could not attack " + entityType + " because pve = false"); plot.debug(player.getName() + " could not attack " + entityType
+ " because pve = false");
} }
return false; return false;
} }
@ -2936,6 +3009,9 @@ public class PlayerEvents extends PlotListener implements Listener {
return false; return false;
} }
} }
if (vplot == null && roadFlags && area.getRoadFlag(PveFlag.class)) {
return true;
}
return ((vplot != null && vplot.getFlag(PveFlag.class)) || !(damager instanceof Arrow return ((vplot != null && vplot.getFlag(PveFlag.class)) || !(damager instanceof Arrow
&& !(victim instanceof Creature))); && !(victim instanceof Creature)));
} }
@ -3025,7 +3101,8 @@ public class PlayerEvents extends PlotListener implements Listener {
Block block = event.getBlockPlaced(); Block block = event.getBlockPlaced();
if (block.getType().hasGravity()) { if (block.getType().hasGravity()) {
sendBlockChange(block.getLocation(), block.getBlockData()); sendBlockChange(block.getLocation(), block.getBlockData());
plot.debug(event.getBlock().getType() + " did not fall because of disable-physics = true"); plot.debug(event.getBlock().getType()
+ " did not fall because of disable-physics = true");
} }
} }
} else if (!Permissions.hasPermission(pp, Captions.PERMISSION_ADMIN_BUILD_ROAD)) { } else if (!Permissions.hasPermission(pp, Captions.PERMISSION_ADMIN_BUILD_ROAD)) {
@ -3039,12 +3116,21 @@ public class PlayerEvents extends PlotListener implements Listener {
if (event.getEntityType() != EntityType.PLAYER) { if (event.getEntityType() != EntityType.PLAYER) {
return; return;
} }
Plot plot = BukkitUtil.getLocation(event.getEntity()).getOwnedPlot(); Location location = BukkitUtil.getLocation(event.getEntity());
PlotArea area = location.getPlotArea();
if (area == null) {
return;
}
Plot plot = location.getOwnedPlot();
if (plot == null) { if (plot == null) {
if (area.isRoadFlags() && area.getRoadFlag(InvincibleFlag.class)) {
event.setCancelled(true);
}
return; return;
} }
if (plot.getFlag(InvincibleFlag.class)) { if (plot.getFlag(InvincibleFlag.class)) {
plot.debug(event.getEntity().getName() + " could not take damage because invincible = true"); plot.debug(
event.getEntity().getName() + " could not take damage because invincible = true");
event.setCancelled(true); event.setCancelled(true);
} }
} }
@ -3052,8 +3138,16 @@ public class PlayerEvents extends PlotListener implements Listener {
@EventHandler public void onItemDrop(PlayerDropItemEvent event) { @EventHandler public void onItemDrop(PlayerDropItemEvent event) {
Player player = event.getPlayer(); Player player = event.getPlayer();
BukkitPlayer pp = BukkitUtil.getPlayer(player); BukkitPlayer pp = BukkitUtil.getPlayer(player);
Plot plot = BukkitUtil.getLocation(player).getOwnedPlot(); Location location = pp.getLocation();
PlotArea area = location.getPlotArea();
if (area == null) {
return;
}
Plot plot = location.getOwnedPlot();
if (plot == null) { if (plot == null) {
if (area.isRoadFlags() && area.getRoadFlag(ItemDropFlag.class)) {
event.setCancelled(true);
}
return; return;
} }
UUID uuid = pp.getUUID(); UUID uuid = pp.getUUID();
@ -3070,24 +3164,46 @@ public class PlayerEvents extends PlotListener implements Listener {
if (ent instanceof Player) { if (ent instanceof Player) {
Player player = (Player) ent; Player player = (Player) ent;
BukkitPlayer pp = BukkitUtil.getPlayer(player); BukkitPlayer pp = BukkitUtil.getPlayer(player);
Plot plot = BukkitUtil.getLocation(player).getOwnedPlot(); Location location = pp.getLocation();
PlotArea area = location.getPlotArea();
if (area == null) {
return;
}
Plot plot = location.getOwnedPlot();
if (plot == null) { if (plot == null) {
if (area.isRoadFlags() && area.getRoadFlag(DropProtectionFlag.class)) {
event.setCancelled(true);
}
return; return;
} }
UUID uuid = pp.getUUID(); UUID uuid = pp.getUUID();
if (!plot.isAdded(uuid) && plot.getFlag(DropProtectionFlag.class)) { if (!plot.isAdded(uuid) && plot.getFlag(DropProtectionFlag.class)) {
plot.debug(player.getName() + " could not pick up item because of drop-protection = true"); plot.debug(
player.getName() + " could not pick up item because of drop-protection = true");
event.setCancelled(true); event.setCancelled(true);
} }
} }
} }
@EventHandler public void onDeath(final PlayerDeathEvent event) { @EventHandler public void onDeath(final PlayerDeathEvent event) {
final Plot plot = BukkitUtil.getPlayer(event.getEntity()).getCurrentPlot(); Location location = BukkitUtil.getLocation(event.getEntity());
if (plot != null && plot.getFlag(KeepInventoryFlag.class)) { PlotArea area = location.getPlotArea();
plot.debug(event.getEntity().getName() + " kept their inventory because of keep-inventory = true"); if (area == null) {
event.setKeepInventory(true); return;
}
Plot plot = location.getOwnedPlot();
if (plot == null) {
if (area.isRoadFlags() && area.getRoadFlag(KeepInventoryFlag.class)) {
event.setCancelled(true);
}
return;
}
if (plot.getFlag(KeepInventoryFlag.class)) {
if (plot.getFlag(KeepInventoryFlag.class)) {
plot.debug(event.getEntity().getName()
+ " kept their inventory because of keep-inventory = true");
event.setKeepInventory(true);
}
} }
} }
} }

View File

@ -27,34 +27,25 @@ package com.plotsquared.bukkit.util;
import com.plotsquared.bukkit.player.BukkitOfflinePlayer; import com.plotsquared.bukkit.player.BukkitOfflinePlayer;
import com.plotsquared.bukkit.player.BukkitPlayer; import com.plotsquared.bukkit.player.BukkitPlayer;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.player.OfflinePlotPlayer; import com.plotsquared.core.player.OfflinePlotPlayer;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.util.EconHandler; import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.PermHandler;
import net.milkbowl.vault.economy.Economy; import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.RegisteredServiceProvider;
public class BukkitEconHandler extends EconHandler { public class BukkitEconHandler extends EconHandler {
private Economy econ; private Economy econ;
private Permission perms;
@Override @Override
public boolean init() { public boolean init() {
if (this.econ == null || this.perms == null) { if (this.econ == null) {
setupPermissions();
setupEconomy(); setupEconomy();
} }
return this.econ != null && this.perms != null; return this.econ != null;
}
private void setupPermissions() {
RegisteredServiceProvider<Permission> permissionProvider =
Bukkit.getServer().getServicesManager().getRegistration(Permission.class);
if (permissionProvider != null) {
this.perms = permissionProvider.getProvider();
}
} }
private void setupEconomy() { private void setupEconomy() {
@ -88,20 +79,19 @@ public class BukkitEconHandler extends EconHandler {
this.econ.depositPlayer(((BukkitOfflinePlayer) player).player, amount); this.econ.depositPlayer(((BukkitOfflinePlayer) player).player, amount);
} }
@Override public boolean hasPermission(String world, String player, String perm) { /**
return this.perms.playerHas(world, Bukkit.getOfflinePlayer(player), perm); * @deprecated Use {@link PermHandler#hasPermission(String, String, String)} instead
*/
@Deprecated @Override public boolean hasPermission(String world, String player, String perm) {
if (PlotSquared.imp().getPermissionHandler() != null) {
return PlotSquared.imp().getPermissionHandler().hasPermission(world, player, perm);
} else {
return false;
}
} }
@Override public double getBalance(PlotPlayer<?> player) { @Override public double getBalance(PlotPlayer<?> player) {
return this.econ.getBalance(player.getName()); return this.econ.getBalance(player.getName());
} }
@Deprecated public void setPermission(String world, String player, String perm, boolean value) {
if (value) {
this.perms.playerAdd(world, player, perm);
} else {
this.perms.playerRemove(world, player, perm);
}
}
} }

View File

@ -0,0 +1,59 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.util;
import com.plotsquared.core.util.PermHandler;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider;
public class BukkitPermHandler extends PermHandler {
private Permission perms;
@Override
public boolean init() {
if (this.perms == null) {
setupPermissions();
}
return this.perms != null;
}
private void setupPermissions() {
if (Bukkit.getServer().getPluginManager().getPlugin("Vault") == null) {
return;
}
RegisteredServiceProvider<Permission> permissionProvider =
Bukkit.getServer().getServicesManager().getRegistration(Permission.class);
if (permissionProvider != null) {
this.perms = permissionProvider.getProvider();
}
}
@Override public boolean hasPermission(String world, String player, String perm) {
return this.perms.playerHas(world, Bukkit.getOfflinePlayer(player), perm);
}
}

View File

@ -32,6 +32,7 @@ import com.plotsquared.core.location.Location;
import com.plotsquared.core.location.PlotLoc; import com.plotsquared.core.location.PlotLoc;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotManager;
import com.plotsquared.core.queue.GlobalBlockQueue; import com.plotsquared.core.queue.GlobalBlockQueue;
import com.plotsquared.core.queue.LocalBlockQueue; import com.plotsquared.core.queue.LocalBlockQueue;
import com.plotsquared.core.queue.ScopedLocalBlockQueue; import com.plotsquared.core.queue.ScopedLocalBlockQueue;
@ -109,6 +110,10 @@ public class BukkitRegionManager extends RegionManager {
return chunks; return chunks;
} }
@Override public boolean handleClear(Plot plot, Runnable whenDone, PlotManager manager) {
return false;
}
@Override public int[] countEntities(Plot plot) { @Override public int[] countEntities(Plot plot) {
int[] existing = (int[]) plot.getMeta("EntityCount"); int[] existing = (int[]) plot.getMeta("EntityCount");
if (existing != null && (System.currentTimeMillis() - (long) plot.getMeta("EntityCountTime") if (existing != null && (System.currentTimeMillis() - (long) plot.getMeta("EntityCountTime")

View File

@ -34,6 +34,7 @@ import com.plotsquared.core.queue.QueueProvider;
import com.plotsquared.core.util.ChunkManager; import com.plotsquared.core.util.ChunkManager;
import com.plotsquared.core.util.EconHandler; import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.InventoryUtil; import com.plotsquared.core.util.InventoryUtil;
import com.plotsquared.core.util.PermHandler;
import com.plotsquared.core.util.PlatformWorldManager; import com.plotsquared.core.util.PlatformWorldManager;
import com.plotsquared.core.util.PlayerManager; import com.plotsquared.core.util.PlayerManager;
import com.plotsquared.core.util.RegionManager; import com.plotsquared.core.util.RegionManager;
@ -173,6 +174,13 @@ public interface IPlotMain<P> extends ILogger {
*/ */
@Nullable EconHandler getEconomyHandler(); @Nullable EconHandler getEconomyHandler();
/**
* Gets the permission provider, if there is one
*
* @return the PlotSquared permission manager
*/
@Nullable PermHandler getPermissionHandler();
/** /**
* Gets the {@link QueueProvider} class. * Gets the {@link QueueProvider} class.
*/ */

View File

@ -33,17 +33,24 @@ import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.Permissions;
import com.plotsquared.core.util.query.PlotQuery;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
@CommandDeclaration(command = "setalias", @CommandDeclaration(command = "alias",
permission = "plots.alias", permission = "plots.alias",
description = "Set the plot name", description = "Set the plot name",
usage = "/plot alias <set|remove> <alias>", usage = "/plot alias <set|remove> <alias>",
aliases = {"alias", "sa", "name", "rename", "setname", "seta", "nameplot"}, aliases = {"setalias", "sa", "name", "rename", "setname", "seta", "nameplot"},
category = CommandCategory.SETTINGS, category = CommandCategory.SETTINGS,
requiredType = RequiredType.PLAYER) requiredType = RequiredType.PLAYER)
public class Alias extends SubCommand { public class Alias extends SubCommand {
private static final Command SET_COMMAND = new Command(null, false, "set", null, RequiredType.NONE, null) {};
private static final Command REMOVE_COMMAND = new Command(null, false, "remove", null, RequiredType.NONE, null) {};
@Override public boolean onCommand(PlotPlayer<?> player, String[] args) { @Override public boolean onCommand(PlotPlayer<?> player, String[] args) {
@ -63,13 +70,11 @@ public class Alias extends SubCommand {
return false; return false;
} }
if (!plot.isOwner(player.getUUID())) {
MainUtil.sendMessage(player, Captions.NO_PLOT_PERMS);
return false;
}
boolean result = false; boolean result = false;
boolean owner = plot.isOwner(player.getUUID());
boolean permission;
boolean admin;
switch (args[0].toLowerCase()) { switch (args[0].toLowerCase()) {
case "set": case "set":
if (args.length != 2) { if (args.length != 2) {
@ -77,18 +82,34 @@ public class Alias extends SubCommand {
return false; return false;
} }
if (canExecuteCommand(player, Captions.PERMISSION_ALIAS_SET, false) permission = isPermitted(player, Captions.PERMISSION_ALIAS_SET)
|| canExecuteCommand(player, Captions.PERMISSION_ALIAS_SET_OBSOLETE, false)) { || isPermitted(player, Captions.PERMISSION_ALIAS_SET_OBSOLETE);
admin = isPermitted(player, Captions.PERMISSION_ADMIN_ALIAS_SET);
if (!admin && !owner) {
MainUtil.sendMessage(player, Captions.NO_PLOT_PERMS);
return false;
}
if (permission) { // is either admin or owner
setAlias(player, plot, args[1]); setAlias(player, plot, args[1]);
return true; return true;
} else { } else {
MainUtil.sendMessage(player, Captions.NO_PERMISSION); MainUtil.sendMessage(player, Captions.NO_PERMISSION,
Captions.PERMISSION_ALIAS_SET.getTranslated());
} }
break; break;
case "remove": case "remove":
if (canExecuteCommand(player, Captions.PERMISSION_ALIAS_REMOVE, true)) { permission = isPermitted(player, Captions.PERMISSION_ALIAS_REMOVE);
admin = isPermitted(player, Captions.PERMISSION_ADMIN_ALIAS_REMOVE);
if (!admin && !owner) {
MainUtil.sendMessage(player, Captions.NO_PLOT_PERMS);
return false;
}
if (permission) {
result = removeAlias(player, plot); result = removeAlias(player, plot);
} else {
MainUtil.sendMessage(player, Captions.NO_PERMISSION,
Captions.PERMISSION_ALIAS_REMOVE.getTranslated());
} }
break; break;
default: default:
@ -99,6 +120,20 @@ public class Alias extends SubCommand {
return result; return result;
} }
@Override
public Collection<Command> tab(PlotPlayer player, String[] args, boolean space) {
final List<Command> commands = new ArrayList<>(2);
if (args.length == 1) {
if ("set".startsWith(args[0])) {
commands.add(SET_COMMAND);
}
if ("remove".startsWith(args[0])) {
commands.add(REMOVE_COMMAND);
}
return commands;
}
return Collections.emptySet();
}
private void setAlias(PlotPlayer player, Plot plot, String alias) { private void setAlias(PlotPlayer player, Plot plot, String alias) {
if (alias.isEmpty()) { if (alias.isEmpty()) {
@ -110,11 +145,11 @@ public class Alias extends SubCommand {
} else if (MathMan.isInteger(alias)) { } else if (MathMan.isInteger(alias)) {
Captions.NOT_VALID_VALUE.send(player); Captions.NOT_VALID_VALUE.send(player);
} else { } else {
for (Plot p : PlotSquared.get().getPlots(plot.getArea())) { if (PlotQuery.newQuery().inArea(plot.getArea())
if (p.getAlias().equalsIgnoreCase(alias)) { .withAlias(alias)
MainUtil.sendMessage(player, Captions.ALIAS_IS_TAKEN); .anyMatch()) {
return; MainUtil.sendMessage(player, Captions.ALIAS_IS_TAKEN);
} return;
} }
PlotSquared.get().getImpromptuUUIDPipeline().getSingle(alias, ((uuid, throwable) -> { PlotSquared.get().getImpromptuUUIDPipeline().getSingle(alias, ((uuid, throwable) -> {
if (throwable instanceof TimeoutException) { if (throwable instanceof TimeoutException) {
@ -130,19 +165,13 @@ public class Alias extends SubCommand {
} }
} }
private boolean removeAlias(PlotPlayer player, Plot plot) { private boolean removeAlias(PlotPlayer<?> player, Plot plot) {
plot.setAlias(null); plot.setAlias(null);
MainUtil.sendMessage(player, Captions.ALIAS_REMOVED.getTranslated()); MainUtil.sendMessage(player, Captions.ALIAS_REMOVED.getTranslated());
return true; return true;
} }
private boolean canExecuteCommand(PlotPlayer player, Captions caption, boolean sendMessage) { private boolean isPermitted(PlotPlayer<?> player, Captions caption) {
if (!Permissions.hasPermission(player, caption)) { return Permissions.hasPermission(player, caption);
if (sendMessage) {
MainUtil.sendMessage(player, Captions.NO_PERMISSION);
}
return false;
}
return true;
} }
} }

View File

@ -0,0 +1,202 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.command;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.events.TeleportCause;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotId;
import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.Permissions;
import com.plotsquared.core.util.TabCompletions;
import com.plotsquared.core.util.query.PlotQuery;
import com.plotsquared.core.util.query.SortingStrategy;
import com.plotsquared.core.util.task.RunnableVal2;
import com.plotsquared.core.util.task.RunnableVal3;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@CommandDeclaration(command = "home",
description = "Teleport to your plot(s)",
permission = "plots.home",
usage = "/plot home [<page>|<alias>|<area;x;y>|<area> <x;y>|<area> <page>]",
aliases = {"h"},
requiredType = RequiredType.PLAYER,
category = CommandCategory.TELEPORT)
public class HomeCommand extends Command {
public HomeCommand() {
super(MainCommand.getInstance(), true);
}
private void home(@NotNull final PlotPlayer<?> player,
@NotNull final PlotQuery query, final int page,
final RunnableVal3<Command, Runnable, Runnable> confirm,
final RunnableVal2<Command, CommandResult> whenDone) {
List<Plot> plots = query.asList();
if (plots.isEmpty()) {
Captions.FOUND_NO_PLOTS.send(player);
return;
} else if (plots.size() < page) {
MainUtil.sendMessage(player,
String.format(Captions.NUMBER_NOT_IN_RANGE.getTranslated(), "1", plots.size()));
return;
}
Plot plot = plots.get(page - 1);
confirm.run(this, () -> plot.teleportPlayer(player, TeleportCause.COMMAND, result -> {
if (result) {
whenDone.run(this, CommandResult.SUCCESS);
} else {
whenDone.run(HomeCommand.this, CommandResult.FAILURE);
}
}), () -> whenDone.run(HomeCommand.this, CommandResult.FAILURE));
}
@NotNull private PlotQuery query(@NotNull final PlotPlayer<?> player) {
// everything plots need to have in common here
return PlotQuery.newQuery().ownedBy(player).whereBasePlot();
}
@Override public CompletableFuture<Boolean> execute(PlotPlayer<?> player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) throws CommandException {
// /plot home <number> (or page, whatever it's called)
// /plot home <alias>
// /plot home <[area;]x;y>
// /plot home <area> <x;y>
// /plot home <area> <page>
if (!Permissions.hasPermission(player, Captions.PERMISSION_VISIT_OWNED) && !Permissions
.hasPermission(player, Captions.PERMISSION_HOME)) {
Captions.NO_PERMISSION.send(player, Captions.PERMISSION_VISIT_OWNED);
return CompletableFuture.completedFuture(false);
}
if (args.length > 2) {
Captions.COMMAND_SYNTAX.send(player, getUsage());
return CompletableFuture.completedFuture(false);
}
PlotQuery query = query(player);
int page = 1; // page = index + 1
String identifier;
switch (args.length) {
case 1:
identifier = args[0];
if (MathMan.isInteger(identifier)) {
try {
page = Integer.parseInt(identifier);
} catch (NumberFormatException ignored) {
Captions.NOT_A_NUMBER.send(player, identifier);
return CompletableFuture.completedFuture(false);
}
query.withSortingStrategy(SortingStrategy.SORT_BY_CREATION);
break;
}
// either plot id or alias
Plot fromId = MainUtil.getPlotFromString(player, identifier, false);
if (fromId != null && fromId.isOwner(player.getUUID())) {
// it was a valid plot id
query.withPlot(fromId);
break;
}
// it wasn't a valid plot id, trying to find plot by alias
query.withAlias(identifier);
break;
case 2:
// we assume args[0] is a plot area and args[1] an identifier
PlotArea plotArea = PlotSquared.get().getPlotAreaByString(args[0]);
identifier = args[1];
if (plotArea == null) {
// invalid command, therefore no plots
query.noPlots();
break;
}
query.inArea(plotArea);
if (MathMan.isInteger(identifier)) {
// identifier is a page number
try {
page = Integer.parseInt(identifier);
} catch (NumberFormatException ignored) {
Captions.NOT_A_NUMBER.send(player, identifier);
return CompletableFuture.completedFuture(false);
}
query.withSortingStrategy(SortingStrategy.SORT_BY_CREATION);
break;
}
// identifier needs to be a plot id then
PlotId id = PlotId.fromStringOrNull(identifier);
if (id == null) {
// invalid command, therefore no plots
query.noPlots();
break;
}
// we can try to get this plot
Plot plot = plotArea.getPlot(id);
if (plot == null) {
query.noPlots();
break;
}
// as the query already filters by owner, this is fine
query.withPlot(plot);
break;
case 0:
query.withSortingStrategy(SortingStrategy.SORT_BY_CREATION);
break;
}
home(player, query, page, confirm, whenDone);
return CompletableFuture.completedFuture(true);
}
@Override
public Collection<Command> tab(PlotPlayer player, String[] args, boolean space) {
final List<Command> completions = new ArrayList<>();
switch (args.length - 1) {
case 0:
completions.addAll(
TabCompletions.completeAreas(args[0]));
if (args[0].isEmpty()) {
// if no input is given, only suggest 1 - 3
completions.addAll(
TabCompletions.asCompletions("1", "2", "3"));
break;
}
// complete more numbers from the already given input
completions.addAll(
TabCompletions.completeNumbers(args[0], 10, 999));
break;
case 1:
completions.addAll(
TabCompletions.completeNumbers(args[1], 10, 999));
break;
}
return completions;
}
}

View File

@ -77,6 +77,7 @@ public class MainCommand extends Command {
new RegenAllRoads(); new RegenAllRoads();
new Claim(); new Claim();
new Auto(); new Auto();
new HomeCommand();
new Visit(); new Visit();
new Set(); new Set();
new Clear(); new Clear();

View File

@ -40,12 +40,11 @@ import com.plotsquared.core.util.query.PlotQuery;
import com.plotsquared.core.util.query.SortingStrategy; import com.plotsquared.core.util.query.SortingStrategy;
import com.plotsquared.core.util.task.RunnableVal2; import com.plotsquared.core.util.task.RunnableVal2;
import com.plotsquared.core.util.task.RunnableVal3; import com.plotsquared.core.util.task.RunnableVal3;
import com.plotsquared.core.uuid.UUIDMapping;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -54,8 +53,8 @@ import java.util.concurrent.TimeoutException;
@CommandDeclaration(command = "visit", @CommandDeclaration(command = "visit",
permission = "plots.visit", permission = "plots.visit",
description = "Visit someones plot", description = "Visit someones plot",
usage = "/plot visit [<player>|<alias>|<world>|<id>] [#]", usage = "/plot visit <player>|<alias>|<plot> [area]|[#] [#]",
aliases = {"v", "tp", "teleport", "goto", "home", "h", "warp"}, aliases = {"v", "tp", "teleport", "goto", "warp"},
requiredType = RequiredType.PLAYER, requiredType = RequiredType.PLAYER,
category = CommandCategory.TELEPORT) category = CommandCategory.TELEPORT)
public class Visit extends Command { public class Visit extends Command {
@ -153,9 +152,9 @@ public class Visit extends Command {
int page = Integer.MIN_VALUE; int page = Integer.MIN_VALUE;
switch (args.length) { switch (args.length) {
// /p v [...] [...] <page> // /p v <user> <area> <page>
case 3: case 3:
if (!MathMan.isInteger(args[1])) { if (!MathMan.isInteger(args[2])) {
Captions.NOT_VALID_NUMBER.send(player, "(1, ∞)"); Captions.NOT_VALID_NUMBER.send(player, "(1, ∞)");
Captions.COMMAND_SYNTAX.send(player, getUsage()); Captions.COMMAND_SYNTAX.send(player, getUsage());
return CompletableFuture.completedFuture(false); return CompletableFuture.completedFuture(false);
@ -188,24 +187,13 @@ public class Visit extends Command {
} }
page = Integer.parseInt(args[1]); page = Integer.parseInt(args[1]);
// /p v <name> [page] // /p v <name> [page]
// /p v <page> [page]
// /p v <uuid> [page] // /p v <uuid> [page]
// /p v <plot> [page] // /p v <plot> [page]
// /p v <alias>
case 1: case 1:
final String[] finalArgs = args; final String[] finalArgs = args;
int finalPage = page; int finalPage = page;
// Try to determine whether the given argument is a username if (args[0].length() >= 2 && !args[0].contains(";") && !args[0].contains(",")) {
// or an ordinal
boolean isNumber = false;
if (args[0].length() < 2) {
isNumber = true;
} else if (args[0].length() <= 4 && MathMan.isInteger(args[0])) {
// Check if it's an all-digit username that is stored in cache
final UUIDMapping mapping = PlotSquared.get().getImpromptuUUIDPipeline().getImmediately(args[0]);
// If no UUID could be found, then we assume it's a number and not a username
isNumber = mapping == null;
}
if (!isNumber && args[0].length() >= 2 && !args[0].contains(";") && !args[0].contains(",")) {
PlotSquared.get().getImpromptuUUIDPipeline().getSingle(args[0], (uuid, throwable) -> { PlotSquared.get().getImpromptuUUIDPipeline().getSingle(args[0], (uuid, throwable) -> {
if (throwable instanceof TimeoutException) { if (throwable instanceof TimeoutException) {
// The request timed out // The request timed out
@ -214,79 +202,61 @@ public class Visit extends Command {
// It was a valid UUID but the player has no plots // It was a valid UUID but the player has no plots
MainUtil.sendMessage(player, Captions.PLAYER_NO_PLOTS); MainUtil.sendMessage(player, Captions.PLAYER_NO_PLOTS);
} else if (uuid == null) { } else if (uuid == null) {
if (finalPage == Integer.MIN_VALUE && MathMan.isInteger(finalArgs[0])) { // player not found, so we assume it's an alias if no page was provided
// The argument was a number, so we assume it's the page number if (finalPage == Integer.MIN_VALUE) {
int parsedPage; this.visit(player, PlotQuery.newQuery().withAlias(finalArgs[0]), player.getApplicablePlotArea(), confirm, whenDone, 1);
try {
parsedPage = Integer.parseInt(finalArgs[0]);
} catch (final Throwable t) {
MainUtil.sendMessage(player, Captions.NOT_A_NUMBER, finalArgs[0]);
return;
}
this.visit(player, PlotQuery.newQuery().ownedBy(player).whereBasePlot(), null,
confirm, whenDone, parsedPage);
} else { } else {
// Try to parse a plot MainUtil.sendMessage(player, Captions.INVALID_PLAYER, finalArgs[0]);
final Plot plot = MainUtil.getPlotFromString(player, finalArgs[0], true);
if (plot == null) {
MainUtil.sendMessage(player, Captions.NOT_VALID_PLOT_ID);
return;
}
this.visit(player, PlotQuery.newQuery().withPlot(plot), null, confirm, whenDone, 1);
} }
} else { } else {
this.visit(player, PlotQuery.newQuery().ownedBy(uuid).whereBasePlot(), null, confirm, whenDone, finalPage); this.visit(player, PlotQuery.newQuery().ownedBy(uuid).whereBasePlot(), null, confirm, whenDone, finalPage);
} }
}); });
} else { } else {
if (finalPage == Integer.MIN_VALUE && MathMan.isInteger(finalArgs[0])) { // Try to parse a plot
// The argument was a number, so we assume it's the page number final Plot plot = MainUtil.getPlotFromString(player, finalArgs[0], true);
int parsedPage; if (plot != null) {
try { this.visit(player, PlotQuery.newQuery().withPlot(plot), null, confirm, whenDone, 1);
parsedPage = Integer.parseInt(finalArgs[0]);
this.visit(player, PlotQuery.newQuery().ownedBy(player).whereBasePlot(), null, confirm,
whenDone, parsedPage);
} catch (final Throwable throwable) {
MainUtil.sendMessage(player, Captions.NOT_A_NUMBER, finalArgs[0]);
}
} else {
// Try to parse a plot
final Plot plot = MainUtil.getPlotFromString(player, finalArgs[0], true);
if (plot != null) {
this.visit(player, PlotQuery.newQuery().withPlot(plot), null, confirm, whenDone, 1);
}
} }
} }
break; break;
case 0: case 0:
// /p v // /p v is invalid
this.visit(player, PlotQuery.newQuery().ownedBy(player), null, confirm, whenDone); Captions.COMMAND_SYNTAX.send(player, getUsage());
break; return CompletableFuture.completedFuture(false);
default: default:
} }
return CompletableFuture.completedFuture(true); return CompletableFuture.completedFuture(true);
} }
public Collection<Command> tab(PlotPlayer player, String[] args, boolean space) { @Override public Collection<Command> tab(PlotPlayer player, String[] args, boolean space) {
final List<Command> completions = new LinkedList<>(); final List<Command> completions = new ArrayList<>();
switch (args.length - 1) { switch (args.length - 1) {
case 0: case 0:
this.completeNumbers(completions, args[0], 0);
completions.addAll(TabCompletions.completePlayers(args[0], Collections.emptyList())); completions.addAll(TabCompletions.completePlayers(args[0], Collections.emptyList()));
break; break;
case 1: case 1:
if (MathMan.isInteger(args[0])) { completions.addAll(
TabCompletions.completeAreas(args[1]));
if (args[1].isEmpty()) {
// if no input is given, only suggest 1 - 3
completions.addAll(
TabCompletions.asCompletions("1", "2", "3"));
break; break;
} }
this.completeNumbers(completions, args[1], 0); completions.addAll(
this.completeAreas(completions, args[1]); TabCompletions.completeNumbers(args[1], 10, 999));
break; break;
case 2: case 2:
if (MathMan.isInteger(args[1])) { if (args[2].isEmpty()) {
// if no input is given, only suggest 1 - 3
completions.addAll(
TabCompletions.asCompletions("1", "2", "3"));
break; break;
} }
this.completeNumbers(completions, args[2], 0); completions.addAll(
TabCompletions.completeNumbers(args[2], 10, 999));
break; break;
} }

View File

@ -182,7 +182,9 @@ public enum Captions implements Caption {
PERMISSION_HOME("plots.home", "static.permissions"), PERMISSION_HOME("plots.home", "static.permissions"),
PERMISSION_ALIAS_SET_OBSOLETE("plots.set.alias", "static.permissions"), // Note this is for backwards compatibility PERMISSION_ALIAS_SET_OBSOLETE("plots.set.alias", "static.permissions"), // Note this is for backwards compatibility
PERMISSION_ALIAS_SET("plots.alias.set", "static.permissions"), PERMISSION_ALIAS_SET("plots.alias.set", "static.permissions"),
PERMISSION_ADMIN_ALIAS_SET("plots.admin.alias.set", "static.permissions"),
PERMISSION_ALIAS_REMOVE("plots.alias.remove", "static.permissions"), PERMISSION_ALIAS_REMOVE("plots.alias.remove", "static.permissions"),
PERMISSION_ADMIN_ALIAS_REMOVE("plots.admin.alias.remove", "static.permissions"),
PERMISSION_ADMIN_CHAT_BYPASS("plots.admin.chat.bypass", "static.permissions"), PERMISSION_ADMIN_CHAT_BYPASS("plots.admin.chat.bypass", "static.permissions"),
PERMISSION_BACKUP("plots.backup", "static.permissions"), PERMISSION_BACKUP("plots.backup", "static.permissions"),
PERMISSION_BACKUP_SAVE("plots.backup.save", "static.permissions"), PERMISSION_BACKUP_SAVE("plots.backup.save", "static.permissions"),

View File

@ -257,6 +257,9 @@ public class Settings extends Config {
public static boolean LEGACY_DATABASE_SUPPORT = true; public static boolean LEGACY_DATABASE_SUPPORT = true;
@Comment("Whether or not PlotSquared should return Unknown if it fails to fulfill a request") @Comment("Whether or not PlotSquared should return Unknown if it fails to fulfill a request")
public static boolean UNKNOWN_AS_DEFAULT = true; public static boolean UNKNOWN_AS_DEFAULT = true;
@Comment("Whether or not automatic background caching should be enabled. It is HIGHLY recommended to keep this turned on."
+ " This should only be disabled if the server has a very large number of plots (>100k)")
public static boolean BACKGROUND_CACHING_ENABLED = true;
} }

View File

@ -40,12 +40,14 @@ import com.plotsquared.core.util.ChunkManager;
import com.plotsquared.core.util.FileBytes; import com.plotsquared.core.util.FileBytes;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.RegionManager;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import lombok.Getter;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -56,7 +58,7 @@ public class HybridPlotManager extends ClassicPlotManager {
public static boolean REGENERATIVE_CLEAR = true; public static boolean REGENERATIVE_CLEAR = true;
private final HybridPlotWorld hybridPlotWorld; @Getter private final HybridPlotWorld hybridPlotWorld;
public HybridPlotManager(HybridPlotWorld hybridPlotWorld) { public HybridPlotManager(HybridPlotWorld hybridPlotWorld) {
super(hybridPlotWorld); super(hybridPlotWorld);
@ -199,6 +201,12 @@ public class HybridPlotManager extends ClassicPlotManager {
* </p> * </p>
*/ */
@Override public boolean clearPlot(Plot plot, final Runnable whenDone) { @Override public boolean clearPlot(Plot plot, final Runnable whenDone) {
if (RegionManager.manager.notifyClear(this)) {
//If this returns false, the clear didn't work
if (RegionManager.manager.handleClear(plot, whenDone, this)) {
return true;
}
}
final String world = hybridPlotWorld.getWorldName(); final String world = hybridPlotWorld.getWorldName();
Location pos1 = plot.getBottomAbs(); Location pos1 = plot.getBottomAbs();
Location pos2 = plot.getExtendedTopAbs(); Location pos2 = plot.getExtendedTopAbs();

View File

@ -50,6 +50,7 @@ import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import lombok.Getter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.File; import java.io.File;
@ -69,6 +70,7 @@ public class HybridPlotWorld extends ClassicPlotWorld {
public HashMap<Integer, BiomeType> G_SCH_B; public HashMap<Integer, BiomeType> G_SCH_B;
public int SCHEM_Y; public int SCHEM_Y;
private Location SIGN_LOCATION; private Location SIGN_LOCATION;
@Getter private File root = null;
public HybridPlotWorld(String worldName, String id, @NotNull IndependentPlotGenerator generator, public HybridPlotWorld(String worldName, String id, @NotNull IndependentPlotGenerator generator,
PlotId min, PlotId max) { PlotId min, PlotId max) {
@ -198,7 +200,6 @@ public class HybridPlotWorld extends ClassicPlotWorld {
// Try to determine root. This means that plot areas can have separate schematic // Try to determine root. This means that plot areas can have separate schematic
// directories // directories
File root;
if (!(root = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), "schematics/GEN_ROAD_SCHEMATIC/" + if (!(root = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), "schematics/GEN_ROAD_SCHEMATIC/" +
this.getWorldName() + "/" + this.getId())).exists()) { this.getWorldName() + "/" + this.getId())).exists()) {
root = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), root = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(),

View File

@ -118,6 +118,7 @@ public abstract class PlotArea {
@Getter private GameMode gameMode = GameModes.CREATIVE; @Getter private GameMode gameMode = GameModes.CREATIVE;
@Getter private Map<String, Expression<Double>> prices = new HashMap<>(); @Getter private Map<String, Expression<Double>> prices = new HashMap<>();
@Getter(AccessLevel.PROTECTED) private List<String> schematics = new ArrayList<>(); @Getter(AccessLevel.PROTECTED) private List<String> schematics = new ArrayList<>();
@Getter private boolean roadFlags = false;
private boolean worldBorder = false; private boolean worldBorder = false;
private boolean useEconomy = false; private boolean useEconomy = false;
private int hash; private int hash;
@ -127,7 +128,9 @@ public abstract class PlotArea {
/** /**
* Area flag container * Area flag container
*/ */
@Getter private FlagContainer flagContainer = @Getter private final FlagContainer flagContainer =
new FlagContainer(GlobalFlagContainer.getInstance());
@Getter private final FlagContainer roadFlagContainer =
new FlagContainer(GlobalFlagContainer.getInstance()); new FlagContainer(GlobalFlagContainer.getInstance());
public PlotArea(@NotNull final String worldName, @Nullable final String id, public PlotArea(@NotNull final String worldName, @Nullable final String id,
@ -370,6 +373,40 @@ public abstract class PlotArea {
this.spawnEggs = config.getBoolean("event.spawn.egg"); this.spawnEggs = config.getBoolean("event.spawn.egg");
this.spawnCustom = config.getBoolean("event.spawn.custom"); this.spawnCustom = config.getBoolean("event.spawn.custom");
this.spawnBreeding = config.getBoolean("event.spawn.breeding"); this.spawnBreeding = config.getBoolean("event.spawn.breeding");
List<String> roadflags = config.getStringList("flags.default");
if (roadflags.isEmpty()) {
roadflags = config.getStringList("road.flags");
if (roadflags.isEmpty()) {
roadflags = new ArrayList<>();
ConfigurationSection section = config.getConfigurationSection("road.flags");
Set<String> keys = section.getKeys(false);
for (String key : keys) {
if (!"default".equals(key)) {
roadflags.add(key + ';' + section.get(key));
}
}
}
}
this.getRoadFlagContainer().addAll(parseFlags(roadflags));
StringBuilder roadFlagBuilder = new StringBuilder();
Collection<PlotFlag<?, ?>> roadFlagCollection = this.getFlagContainer().getFlagMap().values();
if (roadFlagCollection.isEmpty()) {
roadFlagBuilder.append(Captions.NONE.getTranslated());
} else {
roadFlags = true;
String prefix = " ";
for (final PlotFlag<?, ?> flag : roadFlagCollection) {
Object value = flag.toString();
roadFlagBuilder.append(prefix).append(CaptionUtility
.format(null, Captions.PLOT_FLAG_LIST.getTranslated(), flag.getName(),
CaptionUtility.formatRaw(null, value.toString(), "")));
prefix = ", ";
}
}
PlotSquared.log(Captions.PREFIX + "&3 - road flags: &7" + roadFlagBuilder.toString());
loadConfiguration(config); loadConfiguration(config);
} }
@ -413,6 +450,7 @@ public abstract class PlotArea {
options.put("world.max_height", this.getMaxBuildHeight()); options.put("world.max_height", this.getMaxBuildHeight());
options.put("world.min_height", this.getMinBuildHeight()); options.put("world.min_height", this.getMinBuildHeight());
options.put("world.gamemode", this.getGameMode().getName().toLowerCase()); options.put("world.gamemode", this.getGameMode().getName().toLowerCase());
options.put("road.flags.default", null);
if (this.getType() != PlotAreaType.NORMAL) { if (this.getType() != PlotAreaType.NORMAL) {
options.put("generator.terrain", this.getTerrain()); options.put("generator.terrain", this.getTerrain());
@ -434,6 +472,9 @@ public abstract class PlotArea {
config.set("flags.use", config.set("flags.use",
"63,64,68,69,71,77,96,143,167,193,194,195,196,197,77,143,69,70,72,147,148,107,183,184,185,186,187,132"); "63,64,68,69,71,77,96,143,167,193,194,195,196,197,77,143,69,70,72,147,148,107,183,184,185,186,187,132");
} }
if (!config.contains("road.flags")) {
config.set("road.flags.liquid-flow", false);
}
} }
@NotNull @Override public String toString() { @NotNull @Override public String toString() {
@ -1069,4 +1110,52 @@ public abstract class PlotArea {
} }
return flags; return flags;
} }
/**
* Get the value associated with the specified flag. This will look at
* the default values stored in {@link GlobalFlagContainer}.
*
* @param flagClass The flag type (Class)
* @return The flag value
*/
public <T> T getFlag(final Class<? extends PlotFlag<T, ?>> flagClass) {
return this.flagContainer.getFlag(flagClass).getValue();
}
/**
* Get the value associated with the specified flag. This will look at
* the default values stored in {@link GlobalFlagContainer}.
*
* @param flag The flag type (Any instance of the flag)
* @return The flag value
*/
public <T, V extends PlotFlag<T, ?>> T getFlag(final V flag) {
final Class<?> flagClass = flag.getClass();
final PlotFlag<?, ?> flagInstance = this.flagContainer.getFlagErased(flagClass);
return FlagContainer.<T, V>castUnsafe(flagInstance).getValue();
}
/**
* Get the value associated with the specified road flag. This will look at
* the default values stored in {@link GlobalFlagContainer}.
*
* @param flagClass The flag type (Class)
* @return The flag value
*/
public <T> T getRoadFlag(final Class<? extends PlotFlag<T, ?>> flagClass) {
return this.roadFlagContainer.getFlag(flagClass).getValue();
}
/**
* Get the value associated with the specified road flag. This will look at
* the default values stored in {@link GlobalFlagContainer}.
*
* @param flag The flag type (Any instance of the flag)
* @return The flag value
*/
public <T, V extends PlotFlag<T, ?>> T getRoadFlag(final V flag) {
final Class<?> flagClass = flag.getClass();
final PlotFlag<?, ?> flagInstance = this.roadFlagContainer.getFlagErased(flagClass);
return FlagContainer.<T, V>castUnsafe(flagInstance).getValue();
}
} }

View File

@ -77,9 +77,15 @@ public abstract class EconHandler {
public abstract void depositMoney(OfflinePlotPlayer player, double amount); public abstract void depositMoney(OfflinePlotPlayer player, double amount);
public abstract boolean hasPermission(String world, String player, String perm); /**
* @deprecated Use {@link PermHandler#hasPermission(String, String, String)} instead
*/
@Deprecated public abstract boolean hasPermission(String world, String player, String perm);
public boolean hasPermission(String player, String perm) { /**
* @deprecated Use {@link PermHandler#hasPermission(String, String)} instead
*/
@Deprecated public boolean hasPermission(String player, String perm) {
return hasPermission(null, player, perm); return hasPermission(null, player, perm);
} }
} }

View File

@ -0,0 +1,37 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.util;
public abstract class PermHandler {
public abstract boolean init();
public abstract boolean hasPermission(String world, String player, String perm);
public boolean hasPermission(String player, String perm) {
return hasPermission(null, player, perm);
}
}

View File

@ -29,6 +29,7 @@ import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotManager;
import com.plotsquared.core.queue.LocalBlockQueue; import com.plotsquared.core.queue.LocalBlockQueue;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
@ -163,6 +164,22 @@ public abstract class RegionManager {
return queue.enqueue(); return queue.enqueue();
} }
/**
* Notify any plugins that may want to modify clear behaviour that a clear is occuring
*
* @return true if the notified will accept the clear task
*/
public boolean notifyClear(PlotManager manager) {
return false;
}
/**
* Only called when {@link RegionManager#notifyClear(PlotManager)} returns true in specific PlotManagers
*
* @return true if the clear worked. False if someone went wrong so P2 can then handle the clear
*/
public abstract boolean handleClear(Plot plot, final Runnable whenDone, PlotManager manager);
/** /**
* Copy a region to a new location (in the same world) * Copy a region to a new location (in the same world)
*/ */

View File

@ -34,6 +34,7 @@ import com.plotsquared.core.command.RequiredType;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.uuid.UUIDMapping; import com.plotsquared.core.uuid.UUIDMapping;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -136,6 +137,65 @@ public class TabCompletions {
return Collections.emptyList(); return Collections.emptyList();
} }
/**
* Get a list of integer numbers matching the given input. If the input string
* is empty, nothing will be returned. The list is unmodifiable.
*
* @param input Input to filter with
* @param amountLimit Maximum amount of suggestions
* @param highestLimit Highest number to include
* @return Unmodifiable list of number completions
*/
@NotNull public List<Command> completeNumbers(@NotNull final String input,
final int amountLimit, final int highestLimit) {
if (input.isEmpty() || input.length() > highestLimit || !MathMan.isInteger(input)) {
return Collections.emptyList();
}
int offset;
try {
offset = Integer.parseInt(input) * 10;
} catch (NumberFormatException ignored) {
return Collections.emptyList();
}
final List<String> commands = new ArrayList<>();
for (int i = offset; i < highestLimit && (offset - i + amountLimit) > 0; i++) {
commands.add(String.valueOf(i));
}
return asCompletions(commands.toArray(new String[0]));
}
/**
* Get a list of plot areas matching the given input.
* The list is unmodifiable.
*
* @param input Input to filter with
* @return Unmodifiable list of area completions
*/
@NotNull public List<Command> completeAreas(@NotNull final String input) {
final List<Command> completions = new ArrayList<>();
for (final PlotArea area : PlotSquared.get().getPlotAreas()) {
String areaName = area.getWorldName();
if (area.getId() != null) {
areaName += ";" + area.getId();
}
if (!areaName.toLowerCase().startsWith(input.toLowerCase())) {
continue;
}
completions.add(new Command(null, false, areaName, "",
RequiredType.NONE, null) {});
}
return Collections.unmodifiableList(completions);
}
@NotNull public List<Command> asCompletions(String... toFilter) {
final List<Command> completions = new ArrayList<>();
for (String completion : toFilter) {
completions.add(new Command(null, false, completion, "",
RequiredType.NONE, null) {});
}
return Collections.unmodifiableList(completions);
}
/** /**
* @param cacheIdentifier Cache key * @param cacheIdentifier Cache key
* @param input Command input * @param input Command input

View File

@ -376,6 +376,30 @@ public final class PlotQuery {
return this.asList(); return this.asList();
} }
/**
* Get whether any provided plot matches the given filters.
* If no plot was provided, false will be returned.
*
* @return true if any provided plot matches the filters.
*/
public boolean anyMatch() {
if (this.filters.isEmpty()) {
return !this.plotProvider.getPlots().isEmpty();
} else {
final Collection<Plot> plots = this.plotProvider.getPlots();
outer: for (final Plot plot : plots) {
// a plot must pass all filters to match the criteria
for (final PlotFilter filter : this.filters) {
if (!filter.accepts(plot)) {
continue outer;
}
}
return true; // a plot passed all filters, so we have a match
}
return false;
}
}
@NotNull private PlotQuery addFilter(@NotNull final PlotFilter filter) { @NotNull private PlotQuery addFilter(@NotNull final PlotFilter filter) {
this.filters.add(filter); this.filters.add(filter);
return this; return this;

View File

@ -30,7 +30,7 @@ ext {
git = Grgit.open(dir: new File(rootDir.toString() + "/.git")) git = Grgit.open(dir: new File(rootDir.toString() + "/.git"))
} }
def ver = "5.12.2" def ver = "5.12.3"
def versuffix = "" def versuffix = ""
ext { ext {
if (project.hasProperty("versionsuffix")) { if (project.hasProperty("versionsuffix")) {

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.4-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists