Merge branch 'v6' into feature/v6/slf4j

This commit is contained in:
Alexander Söderberg 2020-07-13 23:11:40 +02:00 committed by GitHub
commit 33f2ff7e6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 1629 additions and 809 deletions

View File

@ -2,10 +2,10 @@
<!-- Please describe which issue this Pull Request targets <!-- Please describe which issue this Pull Request targets
If there is no issue, please create one so we can look into it before approving your PR. If there is no issue, please create one so we can look into it before approving your PR.
You can do so here: https://github.com/IntellectualSites/PlotSquared/issues/new/choose You can do so here: https://issues.intellectualsites.com/projects/ps
--> -->
**Fixes #{issue number}** **Fixes {Link to issue}**
## Description ## Description

View File

@ -22,10 +22,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") {
@ -33,7 +35,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")
compile("se.hyperver.hyperverse:Core:0.6.0-SNAPSHOT"){ transitive = false } compile("se.hyperver.hyperverse:Core:0.6.0-SNAPSHOT"){ transitive = false }
compile('com.sk89q:squirrelid:1.0.0-SNAPSHOT'){ transitive = false } compile('com.sk89q:squirrelid:1.0.0-SNAPSHOT'){ transitive = false }

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.5</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

@ -45,6 +45,7 @@ import com.plotsquared.bukkit.util.BukkitChatManager;
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;
@ -94,6 +95,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;
@ -181,6 +183,8 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain<
@Getter private BackupManager backupManager; @Getter private BackupManager backupManager;
@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 PermHandler perm;
@Override public int[] getServerVersion() { @Override public int[] getServerVersion() {
if (this.version == null) { if (this.version == null) {
@ -343,7 +347,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();
@ -476,7 +483,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<>();
@ -613,46 +620,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());
@ -681,10 +688,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) {
@ -692,11 +699,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");
@ -744,71 +751,75 @@ 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":
default: { default: {
if (Settings.Enabled_Components.KILL_ROAD_MOBS) { if (Settings.Enabled_Components.KILL_ROAD_MOBS) {
Location location = entity.getLocation(); Location location = entity.getLocation();
@ -889,8 +900,16 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain<
} }
@Override public EconHandler getEconomyHandler() { @Override public EconHandler getEconomyHandler() {
if (econ != null) {
if (econ.init() /* is inited */) {
return econ;
} else {
return null;
}
}
try { try {
BukkitEconHandler econ = new BukkitEconHandler(); econ = new BukkitEconHandler();
if (econ.init()) { if (econ.init()) {
return econ; return econ;
} }
@ -899,6 +918,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() {
return QueueProvider.of(BukkitLocalQueue.class, BukkitLocalQueue.class); return QueueProvider.of(BukkitLocalQueue.class, BukkitLocalQueue.class);
} }

View File

@ -56,6 +56,7 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import java.util.logging.Level; import java.util.logging.Level;
/** /**
@ -74,6 +75,7 @@ public class FancyMessage
private static Constructor<?> nmsPacketPlayOutChatConstructor; private static Constructor<?> nmsPacketPlayOutChatConstructor;
// The ChatSerializer's instance of Gson // The ChatSerializer's instance of Gson
private static Object nmsChatSerializerGsonInstance; private static Object nmsChatSerializerGsonInstance;
private static Object chatMessageType;
private static Method fromJsonMethod; private static Method fromJsonMethod;
private static JsonParser _stringParser = new JsonParser(); private static JsonParser _stringParser = new JsonParser();
@ -101,8 +103,16 @@ public class FancyMessage
dirty = false; dirty = false;
if (nmsPacketPlayOutChatConstructor == null) { if (nmsPacketPlayOutChatConstructor == null) {
try { try {
Class<?> componentClass = Reflection.getNMSClass("IChatBaseComponent");
if (!Reflection.getVersion().startsWith("v1_16")) { // < 1.16 TODO needs to be fixed before 1.17 :P
nmsPacketPlayOutChatConstructor = Reflection.getNMSClass("PacketPlayOutChat") nmsPacketPlayOutChatConstructor = Reflection.getNMSClass("PacketPlayOutChat")
.getDeclaredConstructor(Reflection.getNMSClass("IChatBaseComponent")); .getDeclaredConstructor(componentClass);
} else {
Class<Enum> chatMessageTypeClass = (Class<Enum>) Reflection.getNMSClass("ChatMessageType");
nmsPacketPlayOutChatConstructor = Reflection.getNMSClass("PacketPlayOutChat")
.getDeclaredConstructor(componentClass, chatMessageTypeClass, UUID.class);
chatMessageType = Enum.valueOf(chatMessageTypeClass, "SYSTEM");
}
nmsPacketPlayOutChatConstructor.setAccessible(true); nmsPacketPlayOutChatConstructor.setAccessible(true);
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
Bukkit.getLogger() Bukkit.getLogger()
@ -773,7 +783,7 @@ public class FancyMessage
Reflection.getField(handle.getClass(), "playerConnection").get(handle); Reflection.getField(handle.getClass(), "playerConnection").get(handle);
Reflection Reflection
.getMethod(connection.getClass(), "sendPacket", Reflection.getNMSClass("Packet")) .getMethod(connection.getClass(), "sendPacket", Reflection.getNMSClass("Packet"))
.invoke(connection, createChatPacket(jsonString)); .invoke(connection, createChatPacket(jsonString, ((Player) sender).getUniqueId()));
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e); Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
@ -790,7 +800,7 @@ public class FancyMessage
} }
} }
private Object createChatPacket(String json) private Object createChatPacket(String json, UUID receiver)
throws IllegalArgumentException, IllegalAccessException, InstantiationException, throws IllegalArgumentException, IllegalAccessException, InstantiationException,
InvocationTargetException, NoSuchMethodException, ClassNotFoundException { InvocationTargetException, NoSuchMethodException, ClassNotFoundException {
if (nmsChatSerializerGsonInstance == null) { if (nmsChatSerializerGsonInstance == null) {
@ -838,7 +848,11 @@ public class FancyMessage
Object serializedChatComponent = fromJsonMethod.invoke(nmsChatSerializerGsonInstance, json, Object serializedChatComponent = fromJsonMethod.invoke(nmsChatSerializerGsonInstance, json,
Reflection.getNMSClass("IChatBaseComponent")); Reflection.getNMSClass("IChatBaseComponent"));
if (!Reflection.getVersion().startsWith("v1_16")) {
return nmsPacketPlayOutChatConstructor.newInstance(serializedChatComponent); return nmsPacketPlayOutChatConstructor.newInstance(serializedChatComponent);
} else {
return nmsPacketPlayOutChatConstructor.newInstance(serializedChatComponent, chatMessageType, receiver);
}
} }
/** /**

View File

@ -107,51 +107,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);
@ -159,7 +159,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);
@ -174,18 +174,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();
@ -203,15 +203,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;
@ -222,23 +222,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(),
@ -290,42 +290,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 {
@ -464,16 +467,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:
@ -505,73 +508,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) {
@ -587,14 +590,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);
@ -605,25 +608,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) {
@ -689,42 +692,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,10 +227,9 @@ 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 float lastRadius; private float lastRadius;
// To prevent recursion // To prevent recursion
private boolean tmpTeleport = true; private boolean tmpTeleport = true;
@ -342,6 +342,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 +364,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 +378,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 +470,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 +576,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 +627,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 +647,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();
@ -812,7 +821,9 @@ public class PlayerEvents extends PlotListener implements Listener {
Player player = event.getPlayer(); Player player = event.getPlayer();
BukkitPlayer pp = BukkitUtil.getPlayer(player); BukkitPlayer pp = BukkitUtil.getPlayer(player);
// Cancel teleport // Cancel teleport
TaskManager.TELEPORT_QUEUE.remove(pp.getName()); if (TaskManager.TELEPORT_QUEUE.remove(pp.getName())) {
MainUtil.sendMessage(pp, Captions.TELEPORT_FAILED);
}
// Set last location // Set last location
Location location = BukkitUtil.getLocation(to); Location location = BukkitUtil.getLocation(to);
pp.setMeta(PlotPlayer.META_LOCATION, location); pp.setMeta(PlotPlayer.META_LOCATION, location);
@ -872,7 +883,9 @@ public class PlayerEvents extends PlotListener implements Listener {
Player player = event.getPlayer(); Player player = event.getPlayer();
BukkitPlayer pp = BukkitUtil.getPlayer(player); BukkitPlayer pp = BukkitUtil.getPlayer(player);
// Cancel teleport // Cancel teleport
TaskManager.TELEPORT_QUEUE.remove(pp.getName()); if (TaskManager.TELEPORT_QUEUE.remove(pp.getName())) {
MainUtil.sendMessage(pp, Captions.TELEPORT_FAILED);
}
// Set last location // Set last location
Location location = BukkitUtil.getLocation(to); Location location = BukkitUtil.getLocation(to);
pp.setMeta(PlotPlayer.META_LOCATION, location); pp.setMeta(PlotPlayer.META_LOCATION, location);
@ -1329,8 +1342,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;
} }
@ -1390,6 +1403,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);
@ -1434,7 +1452,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;
} }
@ -1495,7 +1514,63 @@ public class PlayerEvents extends PlotListener implements Listener {
return; return;
} }
for (Block block1 : event.getBlocks()) { for (Block block1 : event.getBlocks()) {
if (BukkitUtil.getLocation(block1.getLocation().add(relative)).isPlotArea()) { Location bloc = BukkitUtil.getLocation(block1.getLocation());
if (bloc.isPlotArea() || bloc.add(relative.getBlockX(),
relative.getBlockY(), relative.getBlockZ()).isPlotArea()) {
event.setCancelled(true);
return;
}
}
if (location.add(relative.getBlockX(), relative.getBlockY(), relative.getBlockZ())
.isPlotArea()) {
// Prevent pistons from extending if they are: bordering a plot
// area, facing inside plot area, and not pushing any blocks
event.setCancelled(true);
}
return;
}
Plot plot = area.getOwnedPlot(location);
if (plot == null) {
event.setCancelled(true);
return;
}
for (Block block1 : event.getBlocks()) {
Location bloc = BukkitUtil.getLocation(block1.getLocation());
if (!area.contains(bloc.getX(), bloc.getZ()) || !area
.contains(bloc.getX() + relative.getBlockX(), bloc.getZ() + relative.getBlockZ())) {
event.setCancelled(true);
return;
}
if (!plot.equals(area.getOwnedPlot(bloc)) || !plot.equals(area.getOwnedPlot(
bloc.add(relative.getBlockX(), relative.getBlockY(), relative.getBlockZ())))) {
event.setCancelled(true);
return;
}
}
if (!plot.equals(area.getOwnedPlot(location.add(
relative.getBlockX(), relative.getBlockY(), relative.getBlockZ())))) {
// This branch is only necessary to prevent pistons from extending
// if they are: on a plot edge, facing outside the plot, and not
// pushing any blocks
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlockPistonRetract(BlockPistonRetractEvent event) {
Block block = event.getBlock();
Location location = BukkitUtil.getLocation(block.getLocation());
BlockFace face = event.getDirection();
Vector relative = new Vector(face.getModX(), face.getModY(), face.getModZ());
PlotArea area = location.getPlotArea();
if (area == null) {
if (!PlotSquared.get().hasPlotArea(location.getWorld())) {
return;
}
for (Block block1 : event.getBlocks()) {
Location bloc = BukkitUtil.getLocation(block1.getLocation());
if (bloc.isPlotArea() || bloc.add(relative.getBlockX(),
relative.getBlockY(), relative.getBlockZ()).isPlotArea()) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
@ -1522,87 +1597,39 @@ public class PlayerEvents extends PlotListener implements Listener {
} }
} }
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlockPistonRetract(BlockPistonRetractEvent event) {
Block block = event.getBlock();
Location location = BukkitUtil.getLocation(block.getLocation());
PlotArea area = location.getPlotArea();
if (area == null) {
if (!PlotSquared.get().hasPlotArea(location.getWorld())) {
return;
}
if (this.pistonBlocks) {
try {
for (Block pulled : event.getBlocks()) {
location = BukkitUtil.getLocation(pulled.getLocation());
if (location.isPlotArea()) {
event.setCancelled(true);
return;
}
}
} catch (Throwable ignored) {
this.pistonBlocks = false;
}
}
if (!this.pistonBlocks && !block.getType().toString().contains("PISTON")) {
BlockFace dir = event.getDirection();
location = BukkitUtil.getLocation(block.getLocation()
.add(dir.getModX() * 2, dir.getModY() * 2, dir.getModZ() * 2));
if (location.isPlotArea()) {
event.setCancelled(true);
return;
}
}
return;
}
Plot plot = area.getOwnedPlot(location);
BlockFace dir = event.getDirection();
// Location head = location.add(-dir.getModX(), -dir.getModY(), -dir.getModZ());
//
// if (!Objects.equals(plot, area.getOwnedPlot(head))) {
// // FIXME: cancelling the event doesn't work here. See issue #1484
// event.setCancelled(true);
// return;
// }
if (this.pistonBlocks) {
try {
for (Block pulled : event.getBlocks()) {
Location from = BukkitUtil.getLocation(
pulled.getLocation().add(dir.getModX(), dir.getModY(), dir.getModZ()));
Location to = BukkitUtil.getLocation(pulled.getLocation());
if (!area.contains(to.getX(), to.getZ())) {
event.setCancelled(true);
return;
}
Plot fromPlot = area.getOwnedPlot(from);
Plot toPlot = area.getOwnedPlot(to);
if (!Objects.equals(fromPlot, toPlot)) {
event.setCancelled(true);
return;
}
}
} catch (Throwable ignored) {
this.pistonBlocks = false;
}
}
if (!this.pistonBlocks && !block.getType().toString().contains("PISTON")) {
location = BukkitUtil.getLocation(
block.getLocation().add(dir.getModX() * 2, dir.getModY() * 2, dir.getModZ() * 2));
if (!area.contains(location)) {
event.setCancelled(true);
return;
}
Plot newPlot = area.getOwnedPlot(location);
if (!Objects.equals(plot, newPlot)) {
event.setCancelled(true);
}
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlockDispense(BlockDispenseEvent event) { public void onBlockDispense(BlockDispenseEvent event) {
Material type = event.getItem().getType(); Material type = event.getItem().getType();
switch (type) { switch (type) {
case SHULKER_BOX:
case WHITE_SHULKER_BOX:
case ORANGE_SHULKER_BOX:
case MAGENTA_SHULKER_BOX:
case LIGHT_BLUE_SHULKER_BOX:
case YELLOW_SHULKER_BOX:
case LIME_SHULKER_BOX:
case PINK_SHULKER_BOX:
case GRAY_SHULKER_BOX:
case LIGHT_GRAY_SHULKER_BOX:
case CYAN_SHULKER_BOX:
case PURPLE_SHULKER_BOX:
case BLUE_SHULKER_BOX:
case BROWN_SHULKER_BOX:
case GREEN_SHULKER_BOX:
case RED_SHULKER_BOX:
case BLACK_SHULKER_BOX:
case CARVED_PUMPKIN:
case WITHER_SKELETON_SKULL:
case FLINT_AND_STEEL:
case BONE_MEAL:
case SHEARS:
case GLASS_BOTTLE:
case GLOWSTONE:
case COD_BUCKET:
case PUFFERFISH_BUCKET:
case SALMON_BUCKET:
case TROPICAL_FISH_BUCKET:
case BUCKET:
case WATER_BUCKET: case WATER_BUCKET:
case LAVA_BUCKET: { case LAVA_BUCKET: {
if (event.getBlock().getType() == Material.DROPPER) { if (event.getBlock().getType() == Material.DROPPER) {
@ -1715,13 +1742,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 =
new ItemStack(newItem.getType(), newItem.getAmount());
event.setCursor(newStack); event.setCursor(newStack);
plot.debug(player.getName() + " could not creative-copy an item because prevent-creative-copy = true"); 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;
} }
@ -1838,7 +1876,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);
} }
@ -1869,7 +1908,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");
} }
} }
} }
@ -2201,7 +2241,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)) {
if (plot != null) {
plot.debug("Block burning was cancelled because block-burn = false"); plot.debug("Block burning was cancelled because block-burn = false");
}
event.setCancelled(true); event.setCancelled(true);
} }
@ -2505,7 +2547,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 +2577,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 +2599,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())) || (plot == null && 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 +2706,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 +2809,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 +2846,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 +2881,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 +2907,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 +2971,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())) {
plot.debug(player.getName() + " could not attack " + entityType
+ " because pve = false OR animal-attack = false");
return true; return true;
} }
} else if (roadFlags && (area.getRoadFlag(AnimalAttackFlag.class) || area
.getFlag(PveFlag.class))) {
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);
return false; 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 +3019,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 +3111,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 +3126,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 +3148,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 +3174,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) {
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); event.setKeepInventory(true);
} }
} }
}
} }

View File

@ -26,15 +26,16 @@
package com.plotsquared.bukkit.placeholder; package com.plotsquared.bukkit.placeholder;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
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.flag.GlobalFlagContainer;
import com.plotsquared.core.plot.flag.PlotFlag;
import com.plotsquared.core.util.MainUtil;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
public class Placeholders extends PlaceholderExpansion { public class Placeholders extends PlaceholderExpansion {
@ -59,7 +60,7 @@ public class Placeholders extends PlaceholderExpansion {
} }
@Override public String getVersion() { @Override public String getVersion() {
return "2.4"; return "2.5";
} }
@Override public String onPlaceholderRequest(Player p, String identifier) { @Override public String onPlaceholderRequest(Player p, String identifier) {
@ -70,20 +71,20 @@ public class Placeholders extends PlaceholderExpansion {
} }
if (identifier.startsWith("has_plot_")) { if (identifier.startsWith("has_plot_")) {
if (identifier.split("has_plot_").length != 2) identifier = identifier.substring("has_plot_".length());
if (identifier.isEmpty())
return ""; return "";
identifier = identifier.split("has_plot_")[1];
return pl.getPlotCount(identifier) > 0 ? return pl.getPlotCount(identifier) > 0 ?
PlaceholderAPIPlugin.booleanTrue() : PlaceholderAPIPlugin.booleanTrue() :
PlaceholderAPIPlugin.booleanFalse(); PlaceholderAPIPlugin.booleanFalse();
} }
if (identifier.startsWith("plot_count_")) { if (identifier.startsWith("plot_count_")) {
if (identifier.split("plot_count_").length != 2) identifier = identifier.substring("plot_count_".length());
if (identifier.isEmpty())
return ""; return "";
identifier = identifier.split("plot_count_")[1];
return String.valueOf(pl.getPlotCount(identifier)); return String.valueOf(pl.getPlotCount(identifier));
} }
@ -115,23 +116,16 @@ public class Placeholders extends PlaceholderExpansion {
return plot.getAlias(); return plot.getAlias();
} }
case "currentplot_owner": { case "currentplot_owner": {
final Set<UUID> o = plot.getOwners(); final UUID plotOwner = plot.getOwnerAbs();
if (o == null || o.isEmpty()) { if (plotOwner == null) {
return "";
}
final UUID uid = (UUID) o.toArray()[0];
if (uid == null) {
return ""; return "";
} }
String name = PlotSquared.get().getImpromptuUUIDPipeline() .getSingle(uid, try {
Settings.UUID.BLOCKING_TIMEOUT); return MainUtil.getName(plotOwner, false);
} catch (final Exception ignored) {}
if (name != null) { final String name = Bukkit.getOfflinePlayer(plotOwner).getName();
return name;
}
name = Bukkit.getOfflinePlayer(uid).getName();
return name != null ? name : "unknown"; return name != null ? name : "unknown";
} }
case "currentplot_members": { case "currentplot_members": {
@ -181,6 +175,39 @@ public class Placeholders extends PlaceholderExpansion {
default: default:
break; break;
} }
if (identifier.startsWith("currentplot_localflag_")) {
return getFlagValue(plot, identifier.substring("currentplot_localflag_".length()),
false);
}
if (identifier.startsWith("currentplot_flag_")) {
return getFlagValue(plot, identifier.substring("currentplot_flag_".length()), true);
}
return ""; return "";
} }
/**
* Return the flag value from its name on the current plot.
* If the flag doesn't exist it returns an empty string.
* If the flag exists but it is not set on current plot and the parameter inherit is set to true,
* it returns the default value.
*
* @param plot Current plot where the player is
* @param flagName Name of flag to get from current plot
* @param inherit Define if it returns only the flag set on currentplot or also inherited flag
* @return The value of flag serialized in string
*/
private String getFlagValue(final Plot plot, final String flagName, final boolean inherit) {
if (flagName.isEmpty())
return "";
final PlotFlag<?, ?> flag = GlobalFlagContainer.getInstance().getFlagFromString(flagName);
if (flag == null)
return "";
if (inherit) {
return plot.getFlag(flag).toString();
} else {
final PlotFlag<?, ?> plotFlag = plot.getFlagContainer().queryLocal(flag.getClass());
return (plotFlag != null) ? plotFlag.getValue().toString() : "";
}
}
} }

View File

@ -155,8 +155,8 @@ public class BukkitPlayer extends PlotPlayer<Player> {
} }
@Override public boolean hasPermission(final String permission) { @Override public boolean hasPermission(final String permission) {
if (this.offline && EconHandler.manager != null) { if (this.offline && EconHandler.getEconHandler() != null) {
return EconHandler.manager.hasPermission(getName(), permission); return EconHandler.getEconHandler().hasPermission(getName(), permission);
} }
return this.player.hasPermission(permission); return this.player.hasPermission(permission);
} }

View File

@ -27,49 +27,39 @@ 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
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 boolean setupPermissions() { private void setupEconomy() {
RegisteredServiceProvider<Permission> permissionProvider =
Bukkit.getServer().getServicesManager().getRegistration(Permission.class);
if (permissionProvider != null) {
this.perms = permissionProvider.getProvider();
}
return this.perms != null;
}
private boolean setupEconomy() {
if (Bukkit.getServer().getPluginManager().getPlugin("Vault") == null) { if (Bukkit.getServer().getPluginManager().getPlugin("Vault") == null) {
return false; return;
} }
RegisteredServiceProvider<Economy> economyProvider = RegisteredServiceProvider<Economy> economyProvider =
Bukkit.getServer().getServicesManager().getRegistration(Economy.class); Bukkit.getServer().getServicesManager().getRegistration(Economy.class);
if (economyProvider != null) { if (economyProvider != null) {
this.econ = economyProvider.getProvider(); this.econ = economyProvider.getProvider();
} }
return this.econ != null;
} }
@Override public double getMoney(PlotPlayer player) { @Override public double getMoney(PlotPlayer<?> player) {
double bal = super.getMoney(player); double bal = super.getMoney(player);
if (Double.isNaN(bal)) { if (Double.isNaN(bal)) {
return this.econ.getBalance(((BukkitPlayer) player).player); return this.econ.getBalance(((BukkitPlayer) player).player);
@ -77,11 +67,11 @@ public class BukkitEconHandler extends EconHandler {
return bal; return bal;
} }
@Override public void withdrawMoney(PlotPlayer player, double amount) { @Override public void withdrawMoney(PlotPlayer<?> player, double amount) {
this.econ.withdrawPlayer(((BukkitPlayer) player).player, amount); this.econ.withdrawPlayer(((BukkitPlayer) player).player, amount);
} }
@Override public void depositMoney(PlotPlayer player, double amount) { @Override public void depositMoney(PlotPlayer<?> player, double amount) {
this.econ.depositPlayer(((BukkitPlayer) player).player, amount); this.econ.depositPlayer(((BukkitPlayer) player).player, amount);
} }
@ -89,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());
} }
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

@ -31,6 +31,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;
@ -110,6 +111,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

@ -26,6 +26,8 @@
package com.plotsquared.bukkit.uuid; package com.plotsquared.bukkit.uuid;
import com.google.common.util.concurrent.RateLimiter; import com.google.common.util.concurrent.RateLimiter;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.uuid.UUIDMapping; import com.plotsquared.core.uuid.UUIDMapping;
import com.plotsquared.core.uuid.UUIDService; import com.plotsquared.core.uuid.UUIDService;
import com.sk89q.squirrelid.Profile; import com.sk89q.squirrelid.Profile;
@ -35,6 +37,7 @@ import org.jetbrains.annotations.NotNull;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@ -64,10 +67,29 @@ public class SquirrelIdUUIDService implements UUIDService {
@Override @NotNull public List<UUIDMapping> getNames(@NotNull final List<UUID> uuids) { @Override @NotNull public List<UUIDMapping> getNames(@NotNull final List<UUID> uuids) {
final List<UUIDMapping> results = new ArrayList<>(uuids.size()); final List<UUIDMapping> results = new ArrayList<>(uuids.size());
this.rateLimiter.acquire(uuids.size()); this.rateLimiter.acquire(uuids.size());
try {
try { try {
for (final Profile profile : this.profileService.findAllById(uuids)) { for (final Profile profile : this.profileService.findAllById(uuids)) {
results.add(new UUIDMapping(profile.getUniqueId(), profile.getName())); results.add(new UUIDMapping(profile.getUniqueId(), profile.getName()));
} }
} catch (final IllegalArgumentException illegalArgumentException) {
//
// This means that the UUID was invalid for whatever reason, we'll try to
// go through them one by one
//
if (uuids.size() >= 2) {
PlotSquared.debug(Captions.PREFIX + "(UUID) Found invalid UUID in batch. Will try each UUID individually.");
for (final UUID uuid : uuids) {
final List<UUIDMapping> result = this.getNames(Collections.singletonList(uuid));
if (result.isEmpty()) {
continue;
}
results.add(result.get(0));
}
} else if (uuids.size() == 1) {
PlotSquared.debug(Captions.PREFIX + "(UUID) Found invalid UUID: " + uuids.get(0));
}
}
} catch (IOException | InterruptedException e) { } catch (IOException | InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -35,6 +35,7 @@ import com.plotsquared.core.util.ChatManager;
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;
@ -174,11 +175,18 @@ public interface IPlotMain<P> extends ILogger {
boolean initWorldEdit(); boolean initWorldEdit();
/** /**
* Gets the economy provider. * Gets the economy provider, if there is one
* *
* @return the PlotSquared economy manager * @return the PlotSquared economy manager
*/ */
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

@ -154,12 +154,10 @@ public class PlotSquared {
public File styleFile; public File styleFile;
public File configFile; public File configFile;
public File worldsFile; public File worldsFile;
public File commandsFile;
public File translationFile; public File translationFile;
public YamlConfiguration style; public YamlConfiguration style;
public YamlConfiguration worlds; public YamlConfiguration worlds;
public YamlConfiguration storage; public YamlConfiguration storage;
public YamlConfiguration commands;
// Temporary hold the plots/clusters before the worlds load // Temporary hold the plots/clusters before the worlds load
public HashMap<String, Set<PlotCluster>> clusters_tmp; public HashMap<String, Set<PlotCluster>> clusters_tmp;
public HashMap<String, HashMap<PlotId, Plot>> plots_tmp; public HashMap<String, HashMap<PlotId, Plot>> plots_tmp;
@ -258,6 +256,7 @@ public class PlotSquared {
if (Settings.Enabled_Components.CHUNK_PROCESSOR) { if (Settings.Enabled_Components.CHUNK_PROCESSOR) {
this.IMP.registerChunkProcessor(); this.IMP.registerChunkProcessor();
} }
startExpiryTasks();
// Create Event utility class // Create Event utility class
eventDispatcher = new EventDispatcher(); eventDispatcher = new EventDispatcher();
// create Hybrid utility class // create Hybrid utility class
@ -300,8 +299,7 @@ public class PlotSquared {
} }
// Economy // Economy
if (Settings.Enabled_Components.ECONOMY) { if (Settings.Enabled_Components.ECONOMY) {
TaskManager TaskManager.runTask(() -> EconHandler.initializeEconHandler());
.runTask(() -> EconHandler.manager = PlotSquared.this.IMP.getEconomyHandler());
} }
if (Settings.Enabled_Components.COMPONENT_PRESETS) { if (Settings.Enabled_Components.COMPONENT_PRESETS) {

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,12 +145,12 @@ 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)
.anyMatch()) {
MainUtil.sendMessage(player, Captions.ALIAS_IS_TAKEN); MainUtil.sendMessage(player, Captions.ALIAS_IS_TAKEN);
return; return;
} }
}
PlotSquared.get().getImpromptuUUIDPipeline().getSingle(alias, ((uuid, throwable) -> { PlotSquared.get().getImpromptuUUIDPipeline().getSingle(alias, ((uuid, throwable) -> {
if (throwable instanceof TimeoutException) { if (throwable instanceof TimeoutException) {
MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT); MainUtil.sendMessage(player, Captions.FETCHING_PLAYERS_TIMEOUT);
@ -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

@ -157,9 +157,9 @@ public class Auto extends SubCommand {
@Override public boolean onCommand(final PlotPlayer<?> player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
PlotArea plotarea = player.getApplicablePlotArea(); PlotArea plotarea = player.getApplicablePlotArea();
if (plotarea == null) { if (plotarea == null) {
if (EconHandler.manager != null) { if (EconHandler.getEconHandler() != null) {
for (PlotArea area : PlotSquared.get().getPlotAreaManager().getAllPlotAreas()) { for (PlotArea area : PlotSquared.get().getPlotAreaManager().getAllPlotAreas()) {
if (EconHandler.manager if (EconHandler.getEconHandler()
.hasPermission(area.getWorldName(), player.getName(), "plots.auto")) { .hasPermission(area.getWorldName(), player.getName(), "plots.auto")) {
if (plotarea != null) { if (plotarea != null) {
plotarea = null; plotarea = null;
@ -253,18 +253,18 @@ public class Auto extends SubCommand {
return true; return true;
} }
} }
if (EconHandler.manager != null && plotarea.useEconomy()) { if (EconHandler.getEconHandler() != null && plotarea.useEconomy()) {
Expression<Double> costExp = plotarea.getPrices().get("claim"); Expression<Double> costExp = plotarea.getPrices().get("claim");
double cost = costExp.evaluate((double) (Settings.Limit.GLOBAL ? double cost = costExp.evaluate((double) (Settings.Limit.GLOBAL ?
player.getPlotCount() : player.getPlotCount() :
player.getPlotCount(plotarea.getWorldName()))); player.getPlotCount(plotarea.getWorldName())));
cost = (size_x * size_z) * cost; cost = (size_x * size_z) * cost;
if (cost > 0d) { if (cost > 0d) {
if (!force && EconHandler.manager.getMoney(player) < cost) { if (!force && EconHandler.getEconHandler().getMoney(player) < cost) {
sendMessage(player, Captions.CANNOT_AFFORD_PLOT, "" + cost); sendMessage(player, Captions.CANNOT_AFFORD_PLOT, "" + cost);
return true; return true;
} }
EconHandler.manager.withdrawMoney(player, cost); EconHandler.getEconHandler().withdrawMoney(player, cost);
sendMessage(player, Captions.REMOVED_BALANCE, cost + ""); sendMessage(player, Captions.REMOVED_BALANCE, cost + "");
} }
} }

View File

@ -58,7 +58,7 @@ public class Buy extends Command {
RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal3<Command, Runnable, Runnable> confirm,
final RunnableVal2<Command, CommandResult> whenDone) { final RunnableVal2<Command, CommandResult> whenDone) {
check(EconHandler.manager, Captions.ECON_DISABLED); check(EconHandler.getEconHandler(), Captions.ECON_DISABLED);
final Plot plot; final Plot plot;
if (args.length != 0) { if (args.length != 0) {
checkTrue(args.length == 1, Captions.COMMAND_SYNTAX, getUsage()); checkTrue(args.length == 1, Captions.COMMAND_SYNTAX, getUsage());
@ -82,7 +82,7 @@ public class Buy extends Command {
confirm.run(this, () -> { confirm.run(this, () -> {
Captions.REMOVED_BALANCE.send(player, price); Captions.REMOVED_BALANCE.send(player, price);
EconHandler.manager.depositMoney(PlotSquared.imp().getPlayerManager().getOfflinePlayer(plot.getOwnerAbs()), price); EconHandler.getEconHandler().depositMoney(PlotSquared.imp().getPlayerManager().getOfflinePlayer(plot.getOwnerAbs()), price);
PlotPlayer owner = PlotSquared.imp().getPlayerManager().getPlayerIfExists(plot.getOwnerAbs()); PlotPlayer owner = PlotSquared.imp().getPlayerManager().getPlayerIfExists(plot.getOwnerAbs());
if (owner != null) { if (owner != null) {

View File

@ -109,14 +109,14 @@ public class Claim extends SubCommand {
} }
} }
} }
if ((EconHandler.manager != null) && area.useEconomy() && !force) { if ((EconHandler.getEconHandler() != null) && area.useEconomy() && !force) {
Expression<Double> costExr = area.getPrices().get("claim"); Expression<Double> costExr = area.getPrices().get("claim");
double cost = costExr.evaluate((double) currentPlots); double cost = costExr.evaluate((double) currentPlots);
if (cost > 0d) { if (cost > 0d) {
if (EconHandler.manager.getMoney(player) < cost) { if (EconHandler.getEconHandler().getMoney(player) < cost) {
return sendMessage(player, Captions.CANNOT_AFFORD_PLOT, "" + cost); return sendMessage(player, Captions.CANNOT_AFFORD_PLOT, "" + cost);
} }
EconHandler.manager.withdrawMoney(player, cost); EconHandler.getEconHandler().withdrawMoney(player, cost);
sendMessage(player, Captions.REMOVED_BALANCE, cost + ""); sendMessage(player, Captions.REMOVED_BALANCE, cost + "");
} }
} }

View File

@ -25,9 +25,7 @@
*/ */
package com.plotsquared.core.command; package com.plotsquared.core.command;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.file.YamlConfiguration;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.message.PlotMessage; import com.plotsquared.core.plot.message.PlotMessage;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
@ -40,7 +38,6 @@ import com.plotsquared.core.util.task.RunnableVal3;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
@ -190,36 +187,16 @@ public abstract class Command {
this.permission = declaration.permission(); this.permission = declaration.permission();
this.required = declaration.requiredType(); this.required = declaration.requiredType();
this.category = declaration.category(); this.category = declaration.category();
List<String> aliasOptions = new ArrayList<>(); List<String> aliasOptions = new ArrayList<>();
aliasOptions.add(this.id); aliasOptions.add(this.id);
aliasOptions.addAll(Arrays.asList(declaration.aliases())); aliasOptions.addAll(Arrays.asList(declaration.aliases()));
HashMap<String, Object> options = new HashMap<>();
options.put("aliases", aliasOptions);
options.put("description", declaration.description());
options.put("usage", declaration.usage());
options.put("confirmation", declaration.confirmation());
boolean set = false;
YamlConfiguration commands =
PlotSquared.get() == null ? new YamlConfiguration() : PlotSquared.get().commands;
for (Map.Entry<String, Object> entry : options.entrySet()) {
String key = this.getFullId() + "." + entry.getKey();
if (!commands.contains(key)) {
commands.set(key, entry.getValue());
set = true;
}
}
if (set && PlotSquared.get() != null) {
try {
commands.save(PlotSquared.get().commandsFile);
} catch (IOException e) {
e.printStackTrace();
} this.aliases = aliasOptions;
} this.description = declaration.description();
this.aliases = commands.getStringList(this.getFullId() + ".aliases"); this.usage = declaration.usage();
this.description = commands.getString(this.getFullId() + ".description"); this.confirmation = declaration.confirmation();
this.usage = commands.getString(this.getFullId() + ".usage");
this.confirmation = commands.getBoolean(this.getFullId() + ".confirmation");
if (this.parent != null) { if (this.parent != null) {
this.parent.register(this); this.parent.register(this);
} }

View File

@ -171,7 +171,7 @@ public class DebugExec extends SubCommand {
this.scope.put("BlockManager", WorldUtil.IMP); this.scope.put("BlockManager", WorldUtil.IMP);
this.scope.put("SetupUtils", SetupUtils.manager); this.scope.put("SetupUtils", SetupUtils.manager);
this.scope.put("EventUtil", PlotSquared.get().getEventDispatcher()); this.scope.put("EventUtil", PlotSquared.get().getEventDispatcher());
this.scope.put("EconHandler", EconHandler.manager); this.scope.put("EconHandler", EconHandler.getEconHandler());
this.scope.put("DBFunc", DBFunc.dbManager); this.scope.put("DBFunc", DBFunc.dbManager);
this.scope.put("HybridUtils", HybridUtils.manager); this.scope.put("HybridUtils", HybridUtils.manager);
this.scope.put("IMP", PlotSquared.get().IMP); this.scope.put("IMP", PlotSquared.get().IMP);

View File

@ -86,11 +86,11 @@ public class Delete extends SubCommand {
final long start = System.currentTimeMillis(); final long start = System.currentTimeMillis();
boolean result = plot.deletePlot(() -> { boolean result = plot.deletePlot(() -> {
plot.removeRunning(); plot.removeRunning();
if ((EconHandler.manager != null) && plotArea.useEconomy()) { if ((EconHandler.getEconHandler() != null) && plotArea.useEconomy()) {
Expression<Double> valueExr = plotArea.getPrices().get("sell"); Expression<Double> valueExr = plotArea.getPrices().get("sell");
double value = plots.size() * valueExr.evaluate((double) currentPlots); double value = plots.size() * valueExr.evaluate((double) currentPlots);
if (value > 0d) { if (value > 0d) {
EconHandler.manager.depositMoney(player, value); EconHandler.getEconHandler().depositMoney(player, value);
sendMessage(player, Captions.ADDED_BALANCE, String.valueOf(value)); sendMessage(player, Captions.ADDED_BALANCE, String.valueOf(value));
} }
} }

View File

@ -0,0 +1,208 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* 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);
}
@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;
boolean basePlotOnly = true;
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
basePlotOnly = false;
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
basePlotOnly = false;
query.withPlot(plot);
break;
case 0:
query.withSortingStrategy(SortingStrategy.SORT_BY_CREATION);
break;
}
if (basePlotOnly) {
query.whereBasePlot();
}
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

@ -71,7 +71,7 @@ public class ListCmd extends SubCommand {
private String[] getArgumentList(PlotPlayer player) { private String[] getArgumentList(PlotPlayer player) {
List<String> args = new ArrayList<>(); List<String> args = new ArrayList<>();
if (EconHandler.manager != null && Permissions if (EconHandler.getEconHandler() != null && Permissions
.hasPermission(player, Captions.PERMISSION_LIST_FOR_SALE)) { .hasPermission(player, Captions.PERMISSION_LIST_FOR_SALE)) {
args.add("forsale"); args.add("forsale");
} }
@ -264,7 +264,7 @@ public class ListCmd extends SubCommand {
Captions.PERMISSION_LIST_FOR_SALE); Captions.PERMISSION_LIST_FOR_SALE);
return false; return false;
} }
if (EconHandler.manager == null) { if (EconHandler.getEconHandler() == null) {
break; break;
} }
plotConsumer.accept(PlotQuery.newQuery().allPlots().thatPasses(plot -> plot.getFlag(PriceFlag.class) > 0)); plotConsumer.accept(PlotQuery.newQuery().allPlots().thatPasses(plot -> plot.getFlag(PriceFlag.class) > 0));
@ -404,7 +404,7 @@ public class ListCmd extends SubCommand {
@Override public Collection<Command> tab(PlotPlayer player, String[] args, boolean space) { @Override public Collection<Command> tab(PlotPlayer player, String[] args, boolean space) {
final List<String> completions = new LinkedList<>(); final List<String> completions = new LinkedList<>();
if (EconHandler.manager != null && Permissions if (EconHandler.getEconHandler() != null && Permissions
.hasPermission(player, Captions.PERMISSION_LIST_FOR_SALE)) { .hasPermission(player, Captions.PERMISSION_LIST_FOR_SALE)) {
completions.add("forsale"); completions.add("forsale");
} }

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();
@ -164,14 +165,14 @@ public class MainCommand extends Command {
public void run(final Command cmd, final Runnable success, final Runnable failure) { public void run(final Command cmd, final Runnable success, final Runnable failure) {
if (cmd.hasConfirmation(player)) { if (cmd.hasConfirmation(player)) {
CmdConfirm.addPending(player, cmd.getUsage(), () -> { CmdConfirm.addPending(player, cmd.getUsage(), () -> {
if (EconHandler.manager != null) { if (EconHandler.getEconHandler() != null) {
PlotArea area = player.getApplicablePlotArea(); PlotArea area = player.getApplicablePlotArea();
if (area != null) { if (area != null) {
Expression<Double> priceEval = Expression<Double> priceEval =
area.getPrices().get(cmd.getFullId()); area.getPrices().get(cmd.getFullId());
Double price = priceEval != null ? priceEval.evaluate(0d) : 0d; Double price = priceEval != null ? priceEval.evaluate(0d) : 0d;
if (price != null if (price != null
&& EconHandler.manager.getMoney(player) < price) { && EconHandler.getEconHandler().getMoney(player) < price) {
if (failure != null) { if (failure != null) {
failure.run(); failure.run();
} }
@ -185,12 +186,12 @@ public class MainCommand extends Command {
}); });
return; return;
} }
if (EconHandler.manager != null) { if (EconHandler.getEconHandler() != null) {
PlotArea area = player.getApplicablePlotArea(); PlotArea area = player.getApplicablePlotArea();
if (area != null) { if (area != null) {
Expression<Double> priceEval = area.getPrices().get(cmd.getFullId()); Expression<Double> priceEval = area.getPrices().get(cmd.getFullId());
Double price = priceEval != null ? priceEval.evaluate(0d) : 0d; Double price = priceEval != null ? priceEval.evaluate(0d) : 0d;
if (price != 0d && EconHandler.manager.getMoney(player) < price) { if (price != 0d && EconHandler.getEconHandler().getMoney(player) < price) {
if (failure != null) { if (failure != null) {
failure.run(); failure.run();
} }
@ -252,14 +253,14 @@ public class MainCommand extends Command {
if ("f".equals(args[0].substring(1))) { if ("f".equals(args[0].substring(1))) {
confirm = new RunnableVal3<Command, Runnable, Runnable>() { confirm = new RunnableVal3<Command, Runnable, Runnable>() {
@Override public void run(Command cmd, Runnable success, Runnable failure) { @Override public void run(Command cmd, Runnable success, Runnable failure) {
if (EconHandler.manager != null) { if (EconHandler.getEconHandler() != null) {
PlotArea area = player.getApplicablePlotArea(); PlotArea area = player.getApplicablePlotArea();
if (area != null) { if (area != null) {
Expression<Double> priceEval = Expression<Double> priceEval =
area.getPrices().get(cmd.getFullId()); area.getPrices().get(cmd.getFullId());
Double price = priceEval != null ? priceEval.evaluate(0d) : 0d; Double price = priceEval != null ? priceEval.evaluate(0d) : 0d;
if (price != 0d if (price != 0d
&& EconHandler.manager.getMoney(player) < price) { && EconHandler.getEconHandler().getMoney(player) < price) {
if (failure != null) { if (failure != null) {
failure.run(); failure.run();
} }

View File

@ -156,8 +156,8 @@ public class Merge extends SubCommand {
return true; return true;
} }
if (plot.autoMerge(Direction.ALL, maxSize, uuid, terrain)) { if (plot.autoMerge(Direction.ALL, maxSize, uuid, terrain)) {
if (EconHandler.manager != null && plotArea.useEconomy() && price > 0d) { if (EconHandler.getEconHandler() != null && plotArea.useEconomy() && price > 0d) {
EconHandler.manager.withdrawMoney(player, price); EconHandler.getEconHandler().withdrawMoney(player, price);
sendMessage(player, Captions.REMOVED_BALANCE, String.valueOf(price)); sendMessage(player, Captions.REMOVED_BALANCE, String.valueOf(price));
} }
MainUtil.sendMessage(player, Captions.SUCCESS_MERGE); MainUtil.sendMessage(player, Captions.SUCCESS_MERGE);
@ -174,8 +174,8 @@ public class Merge extends SubCommand {
uuid = plot.getOwnerAbs(); uuid = plot.getOwnerAbs();
} }
} }
if (!force && EconHandler.manager != null && plotArea.useEconomy() && price > 0d if (!force && EconHandler.getEconHandler() != null && plotArea.useEconomy() && price > 0d
&& EconHandler.manager.getMoney(player) < price) { && EconHandler.getEconHandler().getMoney(player) < price) {
sendMessage(player, Captions.CANNOT_AFFORD_MERGE, String.valueOf(price)); sendMessage(player, Captions.CANNOT_AFFORD_MERGE, String.valueOf(price));
return false; return false;
} }
@ -192,8 +192,8 @@ public class Merge extends SubCommand {
return true; return true;
} }
if (plot.autoMerge(direction, maxSize - size, uuid, terrain)) { if (plot.autoMerge(direction, maxSize - size, uuid, terrain)) {
if (EconHandler.manager != null && plotArea.useEconomy() && price > 0d) { if (EconHandler.getEconHandler() != null && plotArea.useEconomy() && price > 0d) {
EconHandler.manager.withdrawMoney(player, price); EconHandler.getEconHandler().withdrawMoney(player, price);
sendMessage(player, Captions.REMOVED_BALANCE, String.valueOf(price)); sendMessage(player, Captions.REMOVED_BALANCE, String.valueOf(price));
} }
MainUtil.sendMessage(player, Captions.SUCCESS_MERGE); MainUtil.sendMessage(player, Captions.SUCCESS_MERGE);
@ -226,12 +226,12 @@ public class Merge extends SubCommand {
sendMessage(accepter, Captions.MERGE_NOT_VALID); sendMessage(accepter, Captions.MERGE_NOT_VALID);
return; return;
} }
if (EconHandler.manager != null && plotArea.useEconomy() && price > 0d) { if (EconHandler.getEconHandler() != null && plotArea.useEconomy() && price > 0d) {
if (!force && EconHandler.manager.getMoney(player) < price) { if (!force && EconHandler.getEconHandler().getMoney(player) < price) {
sendMessage(player, Captions.CANNOT_AFFORD_MERGE, String.valueOf(price)); sendMessage(player, Captions.CANNOT_AFFORD_MERGE, String.valueOf(price));
return; return;
} }
EconHandler.manager.withdrawMoney(player, price); EconHandler.getEconHandler().withdrawMoney(player, price);
sendMessage(player, Captions.REMOVED_BALANCE, String.valueOf(price)); sendMessage(player, Captions.REMOVED_BALANCE, String.valueOf(price));
} }
MainUtil.sendMessage(player, Captions.SUCCESS_MERGE); MainUtil.sendMessage(player, Captions.SUCCESS_MERGE);

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,41 +202,16 @@ 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 {
if (finalPage == Integer.MIN_VALUE && MathMan.isInteger(finalArgs[0])) {
// The argument was a number, so we assume it's the page number
int parsedPage;
try {
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 { } else {
// Try to parse a plot // Try to parse a plot
final Plot plot = MainUtil.getPlotFromString(player, finalArgs[0], true); final Plot plot = MainUtil.getPlotFromString(player, finalArgs[0], true);
@ -256,37 +219,44 @@ public class Visit extends Command {
this.visit(player, PlotQuery.newQuery().withPlot(plot), null, confirm, whenDone, 1); 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

@ -172,12 +172,12 @@ public class ComponentPresetManager {
return false; return false;
} }
if (componentPreset.getCost() > 0.0D && EconHandler.manager != null && plot.getArea().useEconomy()) { if (componentPreset.getCost() > 0.0D && EconHandler.getEconHandler() != null && plot.getArea().useEconomy()) {
if (EconHandler.manager.getMoney(player) < componentPreset.getCost()) { if (EconHandler.getEconHandler().getMoney(player) < componentPreset.getCost()) {
Captions.PRESET_CANNOT_AFFORD.send(player); Captions.PRESET_CANNOT_AFFORD.send(player);
return false; return false;
} else { } else {
EconHandler.manager.withdrawMoney(player, componentPreset.getCost()); EconHandler.getEconHandler().withdrawMoney(player, componentPreset.getCost());
Captions.REMOVED_BALANCE.send(player, componentPreset.getCost() + ""); Captions.REMOVED_BALANCE.send(player, componentPreset.getCost() + "");
} }
} }
@ -198,7 +198,7 @@ public class ComponentPresetManager {
for (int i = 0; i < allowedPresets.size(); i++) { for (int i = 0; i < allowedPresets.size(); i++) {
final ComponentPreset preset = allowedPresets.get(i); final ComponentPreset preset = allowedPresets.get(i);
final List<String> lore = new ArrayList<>(); final List<String> lore = new ArrayList<>();
if (preset.getCost() > 0 && EconHandler.manager != null && plot.getArea().useEconomy()){ if (preset.getCost() > 0 && EconHandler.getEconHandler() != null && plot.getArea().useEconomy()){
lore.add(Captions.PRESET_LORE_COST.getTranslated().replace("%cost%", lore.add(Captions.PRESET_LORE_COST.getTranslated().replace("%cost%",
String.format("%.2f", preset.getCost()))); String.format("%.2f", preset.getCost())));
} }

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;
} }
@ -385,6 +388,9 @@ public class Settings extends Config {
@Comment( @Comment(
"Whether schematic based generation should paste schematic on top of plots, or from Y=1") "Whether schematic based generation should paste schematic on top of plots, or from Y=1")
public static boolean PASTE_ON_TOP = true; public static boolean PASTE_ON_TOP = true;
@Comment(
"Whether schematic based road generation should paste schematic on top of roads, or from Y=1")
public static boolean PASTE_ROAD_ON_TOP = true;
} }
@ -527,6 +533,13 @@ public class Settings extends Config {
public static int TARGET_TIME = 65; public static int TARGET_TIME = 65;
} }
@Comment("Settings related to tab completion")
public static final class Tab_Completions {
@Comment({"The time in seconds how long tab completions should remain in cache.",
"0 will disable caching. Lower values may be less performant."})
public static int CACHE_EXPIRATION = 15;
}
@Comment({"Enable or disable parts of the plugin", @Comment({"Enable or disable parts of the plugin",
"Note: A cache will use some memory if enabled"}) "Note: A cache will use some memory if enabled"})

View File

@ -47,7 +47,8 @@ public class HybridGen extends IndependentPlotGenerator {
private void placeSchem(HybridPlotWorld world, ScopedLocalBlockQueue result, short relativeX, private void placeSchem(HybridPlotWorld world, ScopedLocalBlockQueue result, short relativeX,
short relativeZ, int x, int z, boolean isRoad) { short relativeZ, int x, int z, boolean isRoad) {
int minY; // Math.min(world.PLOT_HEIGHT, world.ROAD_HEIGHT); int minY; // Math.min(world.PLOT_HEIGHT, world.ROAD_HEIGHT);
if (isRoad || Settings.Schematics.PASTE_ON_TOP) { if ((isRoad && Settings.Schematics.PASTE_ROAD_ON_TOP) || (!isRoad
&& Settings.Schematics.PASTE_ON_TOP)) {
minY = world.SCHEM_Y; minY = world.SCHEM_Y;
} else { } else {
minY = 1; minY = 1;

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);
@ -110,15 +112,17 @@ public class HybridPlotManager extends ClassicPlotManager {
return true; return true;
} }
LocalBlockQueue queue = hybridPlotWorld.getQueue(false); LocalBlockQueue queue = hybridPlotWorld.getQueue(false);
createSchemAbs(queue, pos1, pos2); createSchemAbs(queue, pos1, pos2, true);
queue.enqueue(); queue.enqueue();
return true; return true;
} }
private void createSchemAbs(LocalBlockQueue queue, Location pos1, Location pos2) { private void createSchemAbs(LocalBlockQueue queue, Location pos1, Location pos2,
boolean isRoad) {
int size = hybridPlotWorld.SIZE; int size = hybridPlotWorld.SIZE;
int minY; int minY;
if (Settings.Schematics.PASTE_ON_TOP) { if ((isRoad && Settings.Schematics.PASTE_ROAD_ON_TOP) || (!isRoad
&& Settings.Schematics.PASTE_ON_TOP)) {
minY = hybridPlotWorld.SCHEM_Y; minY = hybridPlotWorld.SCHEM_Y;
} else { } else {
minY = 1; minY = 1;
@ -170,7 +174,7 @@ public class HybridPlotManager extends ClassicPlotManager {
return true; return true;
} }
LocalBlockQueue queue = hybridPlotWorld.getQueue(false); LocalBlockQueue queue = hybridPlotWorld.getQueue(false);
createSchemAbs(queue, pos1, pos2); createSchemAbs(queue, pos1, pos2, true);
queue.enqueue(); queue.enqueue();
return true; return true;
} }
@ -184,9 +188,9 @@ public class HybridPlotManager extends ClassicPlotManager {
pos1.setY(0); pos1.setY(0);
pos2.setY(Math.min(getWorldHeight(), 255)); pos2.setY(Math.min(getWorldHeight(), 255));
LocalBlockQueue queue = hybridPlotWorld.getQueue(false); LocalBlockQueue queue = hybridPlotWorld.getQueue(false);
createSchemAbs(queue, pos1, pos2); createSchemAbs(queue, pos1, pos2, true);
if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
createSchemAbs(queue, pos1, pos2); createSchemAbs(queue, pos1, pos2, true);
} }
return queue.enqueue(); return queue.enqueue();
} }
@ -199,6 +203,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();
@ -259,7 +269,7 @@ public class HybridPlotManager extends ClassicPlotManager {
if (!hybridPlotWorld.PLOT_SCHEMATIC) { if (!hybridPlotWorld.PLOT_SCHEMATIC) {
return; return;
} }
createSchemAbs(queue, bottom, top); createSchemAbs(queue, bottom, top, false);
} }
/** /**

View File

@ -49,6 +49,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 org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -71,6 +72,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(),
@ -339,7 +340,7 @@ public class HybridPlotWorld extends ClassicPlotWorld {
(short) (z - shift), id, false, h2); (short) (z - shift), id, false, h2);
} }
} }
BiomeType biome = blockArrayClipboard1 BiomeType biome = blockArrayClipboard2
.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ())); .getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ()));
addOverlayBiome((short) (x - shift), (short) (z - shift), biome); addOverlayBiome((short) (x - shift), (short) (z - shift), biome);
} }

View File

@ -87,6 +87,11 @@ public abstract class HybridUtils {
public static PlotArea area; public static PlotArea area;
public static boolean UPDATE = false; public static boolean UPDATE = false;
public static boolean regeneratePlotWalls(final PlotArea area) {
PlotManager plotManager = area.getPlotManager();
return plotManager.regenerateAllPlotWalls();
}
public void analyzeRegion(final String world, final CuboidRegion region, public void analyzeRegion(final String world, final CuboidRegion region,
final RunnableVal<PlotAnalysis> whenDone) { final RunnableVal<PlotAnalysis> whenDone) {
// int diff, int variety, int vertices, int rotation, int height_sd // int diff, int variety, int vertices, int rotation, int height_sd
@ -503,7 +508,7 @@ public abstract class HybridUtils {
PlotManager plotManager = plotworld.getPlotManager(); PlotManager plotManager = plotworld.getPlotManager();
int sx = bot.getX() - plotworld.ROAD_WIDTH + 1; int sx = bot.getX() - plotworld.ROAD_WIDTH + 1;
int sz = bot.getZ() + 1; int sz = bot.getZ() + 1;
int sy = plotworld.ROAD_HEIGHT; int sy = Settings.Schematics.PASTE_ROAD_ON_TOP ? plotworld.ROAD_HEIGHT : 1;
int ex = bot.getX(); int ex = bot.getX();
int ez = top.getZ(); int ez = top.getZ();
int ey = get_ey(plotManager, queue, sx, ex, sz, ez, sy); int ey = get_ey(plotManager, queue, sx, ex, sz, ez, sy);
@ -623,10 +628,7 @@ public abstract class HybridUtils {
} }
if (condition) { if (condition) {
BaseBlock[] blocks = plotWorld.G_SCH.get(MathMan.pair(absX, absZ)); BaseBlock[] blocks = plotWorld.G_SCH.get(MathMan.pair(absX, absZ));
int minY = plotWorld.SCHEM_Y; int minY = Settings.Schematics.PASTE_ROAD_ON_TOP ? plotWorld.SCHEM_Y : 1;
if (!Settings.Schematics.PASTE_ON_TOP) {
minY = 1;
}
int maxY = Math.max(extend, blocks.length); int maxY = Math.max(extend, blocks.length);
for (int y = 0; y < maxY; y++) { for (int y = 0; y < maxY; y++) {
if (y > blocks.length - 1) { if (y > blocks.length - 1) {
@ -661,9 +663,4 @@ public abstract class HybridUtils {
} }
return false; return false;
} }
public static boolean regeneratePlotWalls(final PlotArea area) {
PlotManager plotManager = area.getPlotManager();
return plotManager.regenerateAllPlotWalls();
}
} }

View File

@ -34,6 +34,7 @@ import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.jetbrains.annotations.NotNull;
import org.khelekore.prtree.MBR; import org.khelekore.prtree.MBR;
import org.khelekore.prtree.SimpleMBR; import org.khelekore.prtree.SimpleMBR;
@ -103,6 +104,16 @@ public class Location implements Cloneable, Comparable<Location> {
} }
} }
/**
* Return a copy of the location. This will pass {@link #equals(Object)}
* but will have a different identity.
*
* @return Copy of the location
*/
@NotNull public Location copy() {
return new Location(this.world, this.x, this.y, this.z, this.yaw, this.pitch);
}
public PlotArea getPlotArea() { public PlotArea getPlotArea() {
return PlotSquared.get().getPlotAreaAbs(this); return PlotSquared.get().getPlotAreaAbs(this);
} }
@ -179,6 +190,7 @@ public class Location implements Cloneable, Comparable<Location> {
this.x += x; this.x += x;
this.y += y; this.y += y;
this.z += z; this.z += z;
this.blockVector3 = BlockVector3.at(this.x, this.y, this.z);
return this; return this;
} }
@ -220,6 +232,7 @@ public class Location implements Cloneable, Comparable<Location> {
this.x -= x; this.x -= x;
this.y -= y; this.y -= y;
this.z -= z; this.z -= z;
this.blockVector3 = BlockVector3.at(this.x, this.y, this.z);
return this; return this;
} }

View File

@ -371,7 +371,7 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer
@NotNull public Location getLocation() { @NotNull public Location getLocation() {
Location location = getMeta("location"); Location location = getMeta("location");
if (location != null) { if (location != null) {
return location; return location.copy(); // Always return a copy of the location
} }
return getLocationFull(); return getLocationFull();
} }
@ -760,18 +760,18 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer
* The amount of money this Player has. * The amount of money this Player has.
*/ */
public double getMoney() { public double getMoney() {
return EconHandler.manager == null ? 0 : EconHandler.manager.getMoney(this); return EconHandler.getEconHandler() == null ? 0 : EconHandler.getEconHandler().getMoney(this);
} }
public void withdraw(double amount) { public void withdraw(double amount) {
if (EconHandler.manager != null) { if (EconHandler.getEconHandler() != null) {
EconHandler.manager.withdrawMoney(this, amount); EconHandler.getEconHandler().withdrawMoney(this, amount);
} }
} }
public void deposit(double amount) { public void deposit(double amount) {
if (EconHandler.manager != null) { if (EconHandler.getEconHandler() != null) {
EconHandler.manager.depositMoney(this, amount); EconHandler.getEconHandler().depositMoney(this, amount);
} }
} }

View File

@ -1751,6 +1751,7 @@ public class Plot {
} }
} else { } else {
area.addPlot(this); area.addPlot(this);
updateWorldBorder();
} }
setSign(player.getName()); setSign(player.getName());
MainUtil.sendMessage(player, Captions.CLAIMED); MainUtil.sendMessage(player, Captions.CLAIMED);
@ -2998,11 +2999,9 @@ public class Plot {
final String name = player.getName(); final String name = player.getName();
TaskManager.TELEPORT_QUEUE.add(name); TaskManager.TELEPORT_QUEUE.add(name);
TaskManager.runTaskLater(() -> { TaskManager.runTaskLater(() -> {
if (!TaskManager.TELEPORT_QUEUE.contains(name)) { if (!TaskManager.TELEPORT_QUEUE.remove(name)) {
MainUtil.sendMessage(player, Captions.TELEPORT_FAILED);
return; return;
} }
TaskManager.TELEPORT_QUEUE.remove(name);
if (player.isOnline()) { if (player.isOnline()) {
MainUtil.sendMessage(player, Captions.TELEPORTED_TO_PLOT); MainUtil.sendMessage(player, Captions.TELEPORTED_TO_PLOT);
player.teleport(location, cause); player.teleport(location, cause);

View File

@ -122,6 +122,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;
@ -131,7 +132,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,
@ -373,6 +376,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);
} }
@ -416,6 +453,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());
@ -437,6 +475,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() {
@ -1074,4 +1115,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

@ -25,42 +25,67 @@
*/ */
package com.plotsquared.core.util; package com.plotsquared.core.util;
import com.plotsquared.core.IPlotMain;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.player.ConsolePlayer; import com.plotsquared.core.player.ConsolePlayer;
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 org.jetbrains.annotations.Nullable;
public abstract class EconHandler { public abstract class EconHandler {
public static EconHandler manager; /**
private static boolean initialized; * @deprecated This will be removed in the future,
* call {@link IPlotMain#getEconomyHandler()} instead.
*/
@Deprecated @Nullable public static EconHandler manager;
public static EconHandler getEconHandler() { /**
if (initialized) { * Initialize the economy handler using {@link IPlotMain#getEconomyHandler()}
* @deprecated Call {@link #init} instead or use {@link IPlotMain#getEconomyHandler()}
* which does this already.
*/
@Deprecated public static void initializeEconHandler() {
manager = PlotSquared.get().IMP.getEconomyHandler();
}
/**
* Return the econ handler instance, if one exists
*
* @return Economy handler instance
* @deprecated Call {@link IPlotMain#getEconomyHandler()} instead
*/
@Deprecated @Nullable public static EconHandler getEconHandler() {
manager = PlotSquared.get().IMP.getEconomyHandler();
return manager; return manager;
} }
initialized = true;
return manager = PlotSquared.get().IMP.getEconomyHandler();
}
public double getMoney(PlotPlayer player) { public abstract boolean init();
public double getMoney(PlotPlayer<?> player) {
if (player instanceof ConsolePlayer) { if (player instanceof ConsolePlayer) {
return Double.MAX_VALUE; return Double.MAX_VALUE;
} }
return getBalance(player); return getBalance(player);
} }
public abstract double getBalance(PlotPlayer player); public abstract double getBalance(PlotPlayer<?> player);
public abstract void withdrawMoney(PlotPlayer player, double amount); public abstract void withdrawMoney(PlotPlayer<?> player, double amount);
public abstract void depositMoney(PlotPlayer player, double amount); public abstract void depositMoney(PlotPlayer<?> player, double amount);
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

@ -373,10 +373,21 @@ public class MainUtil {
/** /**
* Get the name from a UUID. * Get the name from a UUID.
* *
* @param owner * @param owner Owner UUID
* @return The player's name, None, Everyone or Unknown * @return The player's name, None, Everyone or Unknown
*/ */
@NotNull public static String getName(UUID owner) { @NotNull public static String getName(@Nullable UUID owner) {
return getName(owner, true);
}
/**
* Get the name from a UUID.
*
* @param owner Owner UUID
* @param blocking Whether or not the operation can be blocking
* @return The player's name, None, Everyone or Unknown
*/
@NotNull public static String getName(@Nullable final UUID owner, final boolean blocking) {
if (owner == null) { if (owner == null) {
return Captions.NONE.getTranslated(); return Captions.NONE.getTranslated();
} }
@ -386,7 +397,17 @@ public class MainUtil {
if (owner.equals(DBFunc.SERVER)) { if (owner.equals(DBFunc.SERVER)) {
return Captions.SERVER.getTranslated(); return Captions.SERVER.getTranslated();
} }
String name = PlotSquared.get().getImpromptuUUIDPipeline().getSingle(owner, Settings.UUID.BLOCKING_TIMEOUT); final String name;
if (blocking) {
name = PlotSquared.get().getImpromptuUUIDPipeline().getSingle(owner, Settings.UUID.BLOCKING_TIMEOUT);
} else {
final UUIDMapping uuidMapping = PlotSquared.get().getImpromptuUUIDPipeline().getImmediately(owner);
if (uuidMapping != null) {
name = uuidMapping.getUsername();
} else {
name = null;
}
}
if (name == null) { if (name == null) {
return Captions.UNKNOWN.getTranslated(); return Captions.UNKNOWN.getTranslated();
} }

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;
@ -167,6 +168,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

@ -134,8 +134,7 @@ public abstract class SchematicHandler {
name = name =
plot.getId().x + ";" + plot.getId().y + ',' + plot.getArea() + ',' + owner; plot.getId().x + ";" + plot.getId().y + ',' + plot.getArea() + ',' + owner;
} else { } else {
name = namingScheme name = namingScheme.replaceAll("%id%", plot.getId().toString())
.replaceAll("%id%", plot.getId().toString())
.replaceAll("%idx%", plot.getId().x + "") .replaceAll("%idx%", plot.getId().x + "")
.replaceAll("%idy%", plot.getId().y + "") .replaceAll("%idy%", plot.getId().y + "")
.replaceAll("%world%", plot.getArea().toString()); .replaceAll("%world%", plot.getArea().toString());
@ -552,34 +551,42 @@ public abstract class SchematicHandler {
final int p2z = pos2.getZ(); final int p2z = pos2.getZ();
final int ey = pos2.getY(); final int ey = pos2.getY();
Iterator<Integer> yiter = IntStream.range(sy, ey + 1).iterator(); Iterator<Integer> yiter = IntStream.range(sy, ey + 1).iterator();
final Runnable yTask = () -> { final Runnable yTask = new Runnable() {
@Override public void run() {
long ystart = System.currentTimeMillis(); long ystart = System.currentTimeMillis();
while (yiter.hasNext() && System.currentTimeMillis() - ystart < 20) { while (yiter.hasNext() && System.currentTimeMillis() - ystart < 20) {
final int y = yiter.next(); final int y = yiter.next();
Iterator<Integer> ziter = IntStream.range(p1z, p2z + 1).iterator(); Iterator<Integer> ziter = IntStream.range(p1z, p2z + 1).iterator();
final Runnable zTask = () -> { final Runnable zTask = new Runnable() {
@Override public void run() {
long zstart = System.currentTimeMillis(); long zstart = System.currentTimeMillis();
while (ziter.hasNext() while (ziter.hasNext()
&& System.currentTimeMillis() - zstart < 20) { && System.currentTimeMillis() - zstart < 20) {
final int z = ziter.next(); final int z = ziter.next();
Iterator<Integer> xiter = Iterator<Integer> xiter =
IntStream.range(p1x, p2x + 1).iterator(); IntStream.range(p1x, p2x + 1).iterator();
final Runnable xTask = () -> { final Runnable xTask = new Runnable() {
@Override public void run() {
long xstart = System.currentTimeMillis(); long xstart = System.currentTimeMillis();
final int ry = y - sy; final int ry = y - sy;
final int rz = z - p1z; final int rz = z - p1z;
while (xiter.hasNext() while (xiter.hasNext()
&& System.currentTimeMillis() - xstart < 20) { && System.currentTimeMillis() - xstart
< 20) {
final int x = xiter.next(); final int x = xiter.next();
final int rx = x - p1x; final int rx = x - p1x;
BlockVector3 point = BlockVector3.at(x, y, z); BlockVector3 point =
BaseBlock block = BlockVector3.at(x, y, z);
cuboidRegion.getWorld().getFullBlock(point); BaseBlock block = cuboidRegion.getWorld()
.getFullBlock(point);
if (block.getNbtData() != null) { if (block.getNbtData() != null) {
Map<String, Tag> values = new HashMap<>(); Map<String, Tag> values =
new HashMap<>();
for (Map.Entry<String, Tag> entry : block for (Map.Entry<String, Tag> entry : block
.getNbtData().getValue().entrySet()) { .getNbtData().getValue()
values.put(entry.getKey(), entry.getValue()); .entrySet()) {
values.put(entry.getKey(),
entry.getValue());
} }
// Remove 'id' if it exists. We want 'Id' // Remove 'id' if it exists. We want 'Id'
values.remove("id"); values.remove("id");
@ -589,11 +596,13 @@ public abstract class SchematicHandler {
values.remove("y"); values.remove("y");
values.remove("z"); values.remove("z");
values.put("Id", new StringTag(block.getNbtId())); values.put("Id",
values.put("Pos", new StringTag(block.getNbtId()));
new IntArrayTag(new int[] {rx, ry, rz})); values.put("Pos", new IntArrayTag(
new int[] {rx, ry, rz}));
tileEntities.add(new CompoundTag(values)); tileEntities
.add(new CompoundTag(values));
} }
String blockKey = String blockKey =
block.toImmutableState().getAsString(); block.toImmutableState().getAsString();
@ -615,7 +624,8 @@ public abstract class SchematicHandler {
continue; continue;
} }
BlockVector2 pt = BlockVector2.at(x, z); BlockVector2 pt = BlockVector2.at(x, z);
BiomeType biome = cuboidRegion.getWorld().getBiome(pt); BiomeType biome =
cuboidRegion.getWorld().getBiome(pt);
String biomeStr = biome.getId(); String biomeStr = biome.getId();
int biomeId; int biomeId;
if (biomePalette.containsKey(biomeStr)) { if (biomePalette.containsKey(biomeStr)) {
@ -633,12 +643,14 @@ public abstract class SchematicHandler {
if (xiter.hasNext()) { if (xiter.hasNext()) {
this.run(); this.run();
} }
}
}; };
xTask.run(); xTask.run();
} }
if (ziter.hasNext()) { if (ziter.hasNext()) {
this.run(); this.run();
} }
}
}; };
zTask.run(); zTask.run();
} }
@ -647,6 +659,7 @@ public abstract class SchematicHandler {
} else { } else {
regionTask.run(); regionTask.run();
} }
}
}; };
yTask.run(); yTask.run();
} }

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;
@ -56,7 +57,9 @@ import java.util.stream.Collectors;
public class TabCompletions { public class TabCompletions {
private final Cache<String, List<String>> cachedCompletionValues = private final Cache<String, List<String>> cachedCompletionValues =
CacheBuilder.newBuilder().expireAfterWrite(15, TimeUnit.SECONDS).build(); CacheBuilder.newBuilder()
.expireAfterWrite(Settings.Tab_Completions.CACHE_EXPIRATION, TimeUnit.SECONDS)
.build();
private final Command booleanTrueCompletion = new Command(null, false, "true", "", private final Command booleanTrueCompletion = new Command(null, false, "true", "",
RequiredType.NONE, null) {}; RequiredType.NONE, null) {};
@ -134,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.5"
def versuffix = "" def versuffix = ""
ext { ext {
if (project.hasProperty("versionsuffix")) { if (project.hasProperty("versionsuffix")) {
@ -76,6 +76,8 @@ subprojects {
delete("../target") delete("../target")
} }
javadoc.options.encoding = 'UTF-8'
dependencies { dependencies {
compile group: 'org.json', name: 'json', version: '20200518' compile group: 'org.json', name: 'json', version: '20200518'

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