Start adding listeners as per RedstonerServer/Parcels
This commit is contained in:
@@ -0,0 +1,19 @@
|
|||||||
|
package io.dico.dicore;
|
||||||
|
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
public @interface ListenerMarker {
|
||||||
|
|
||||||
|
String[] events() default {};
|
||||||
|
|
||||||
|
EventPriority priority() default EventPriority.HIGHEST;
|
||||||
|
|
||||||
|
boolean ignoreCancelled() default true;
|
||||||
|
}
|
||||||
@@ -11,10 +11,6 @@ import org.bukkit.plugin.EventExecutor;
|
|||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.plugin.RegisteredListener;
|
import org.bukkit.plugin.RegisteredListener;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@@ -434,22 +430,6 @@ public final class Registrator {
|
|||||||
// # Public types
|
// # Public types
|
||||||
// ############################################
|
// ############################################
|
||||||
|
|
||||||
public interface IEventListener<T extends Event> extends Consumer<T> {
|
|
||||||
@Override
|
|
||||||
void accept(T event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.FIELD)
|
|
||||||
public @interface ListenerInfo {
|
|
||||||
|
|
||||||
String[] events() default {};
|
|
||||||
|
|
||||||
EventPriority priority() default EventPriority.HIGHEST;
|
|
||||||
|
|
||||||
boolean ignoreCancelled() default true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Registration extends RegisteredListener {
|
public static class Registration extends RegisteredListener {
|
||||||
|
|
||||||
private final EventExecutor executor;
|
private final EventExecutor executor;
|
||||||
@@ -658,17 +638,17 @@ public final class Registrator {
|
|||||||
fieldLoop:
|
fieldLoop:
|
||||||
for (Field f : fields) {
|
for (Field f : fields) {
|
||||||
if (isStatic != Modifier.isStatic(f.getModifiers())
|
if (isStatic != Modifier.isStatic(f.getModifiers())
|
||||||
|| !f.isAnnotationPresent(ListenerInfo.class)) {
|
|| !f.isAnnotationPresent(ListenerMarker.class)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IEventListener.class.isAssignableFrom(f.getType())) {
|
if (!RegistratorListener.class.isAssignableFrom(f.getType())) {
|
||||||
handleListenerFieldError(new ListenerFieldError(f, "Field type cannot be assigned to IEventListener: " + f.getGenericType().getTypeName()));
|
handleListenerFieldError(new ListenerFieldError(f, "Field type cannot be assigned to RegistratorListener: " + f.getGenericType().getTypeName()));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Type eventType = null;
|
Type eventType = null;
|
||||||
if (f.getType() == IEventListener.class) {
|
if (f.getType() == RegistratorListener.class) {
|
||||||
|
|
||||||
Type[] typeArgs;
|
Type[] typeArgs;
|
||||||
if (!(f.getGenericType() instanceof ParameterizedType)
|
if (!(f.getGenericType() instanceof ParameterizedType)
|
||||||
@@ -681,7 +661,7 @@ public final class Registrator {
|
|||||||
eventType = typeArgs[0];
|
eventType = typeArgs[0];
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// field type is subtype of IEventListener.
|
// field type is subtype of RegistratorListener.
|
||||||
// TODO: link type arguments from field declaration (f.getGenericType()) to matching TypeVariables
|
// TODO: link type arguments from field declaration (f.getGenericType()) to matching TypeVariables
|
||||||
Type[] interfaces = f.getType().getGenericInterfaces();
|
Type[] interfaces = f.getType().getGenericInterfaces();
|
||||||
for (Type itf : interfaces) {
|
for (Type itf : interfaces) {
|
||||||
@@ -702,7 +682,7 @@ public final class Registrator {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itfClass == IEventListener.class) {
|
if (itfClass == RegistratorListener.class) {
|
||||||
if (arguments == null || arguments.length != 1) {
|
if (arguments == null || arguments.length != 1) {
|
||||||
// Log a warning or throw an exception
|
// Log a warning or throw an exception
|
||||||
handleListenerFieldError(new ListenerFieldError(f, ""));
|
handleListenerFieldError(new ListenerFieldError(f, ""));
|
||||||
@@ -749,7 +729,7 @@ public final class Registrator {
|
|||||||
|
|
||||||
Class<? extends Event> baseEventClass = (Class<? extends Event>) eventType;
|
Class<? extends Event> baseEventClass = (Class<? extends Event>) eventType;
|
||||||
|
|
||||||
ListenerInfo anno = f.getAnnotation(ListenerInfo.class);
|
ListenerMarker anno = f.getAnnotation(ListenerMarker.class);
|
||||||
String[] eventClassNames = anno.events();
|
String[] eventClassNames = anno.events();
|
||||||
if (eventClassNames.length > 0) {
|
if (eventClassNames.length > 0) {
|
||||||
|
|
||||||
@@ -844,9 +824,9 @@ public final class Registrator {
|
|||||||
private static final class ListenerFieldInfo {
|
private static final class ListenerFieldInfo {
|
||||||
final Class<? extends Event> eventClass;
|
final Class<? extends Event> eventClass;
|
||||||
final Consumer<? super Event> lambda;
|
final Consumer<? super Event> lambda;
|
||||||
final ListenerInfo anno;
|
final ListenerMarker anno;
|
||||||
|
|
||||||
ListenerFieldInfo(Class<? extends Event> eventClass, Consumer<? super Event> lambda, ListenerInfo anno) {
|
ListenerFieldInfo(Class<? extends Event> eventClass, Consumer<? super Event> lambda, ListenerMarker anno) {
|
||||||
this.eventClass = eventClass;
|
this.eventClass = eventClass;
|
||||||
this.lambda = lambda;
|
this.lambda = lambda;
|
||||||
this.anno = anno;
|
this.anno = anno;
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package io.dico.dicore;
|
||||||
|
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public interface RegistratorListener<T extends Event> extends Consumer<T> {
|
||||||
|
@Override
|
||||||
|
void accept(T event);
|
||||||
|
}
|
||||||
@@ -90,6 +90,8 @@ class Parcel(val world: ParcelWorld, val pos: Vec2i) : ParcelData {
|
|||||||
world.storage.setParcelAllowsInteractInventory(this, value)
|
world.storage.setParcelAllowsInteractInventory(this, value)
|
||||||
data.allowInteractInventory = value
|
data.allowInteractInventory = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hasBlockVisitors: Boolean = false; private set
|
||||||
}
|
}
|
||||||
|
|
||||||
class ParcelDataHolder : ParcelData {
|
class ParcelDataHolder : ParcelData {
|
||||||
|
|||||||
@@ -36,12 +36,9 @@ class ParcelCommands(val plugin: ParcelsPlugin) : ICommandReceiver.Factory {
|
|||||||
"and gives it to you",
|
"and gives it to you",
|
||||||
shortVersion = "sets you up with a fresh, unclaimed parcel")
|
shortVersion = "sets you up with a fresh, unclaimed parcel")
|
||||||
suspend fun WorldScope.cmdAuto(player: Player): Any? {
|
suspend fun WorldScope.cmdAuto(player: Player): Any? {
|
||||||
logger.info("cmdAuto thread before await: ${Thread.currentThread().name}")
|
|
||||||
val numOwnedParcels = plugin.storage.getNumParcels(ParcelOwner(uuid = player.uuid)).await()
|
val numOwnedParcels = plugin.storage.getNumParcels(ParcelOwner(uuid = player.uuid)).await()
|
||||||
logger.info("cmdAuto thread before await: ${Thread.currentThread().name}")
|
|
||||||
|
|
||||||
val limit = player.parcelLimit
|
val limit = player.parcelLimit
|
||||||
|
|
||||||
if (numOwnedParcels >= limit) {
|
if (numOwnedParcels >= limit) {
|
||||||
error("You have enough plots for now")
|
error("You have enough plots for now")
|
||||||
}
|
}
|
||||||
@@ -67,15 +64,12 @@ class ParcelCommands(val plugin: ParcelsPlugin) : ICommandReceiver.Factory {
|
|||||||
shortVersion = "teleports you to parcels")
|
shortVersion = "teleports you to parcels")
|
||||||
@RequireParameters(0)
|
@RequireParameters(0)
|
||||||
suspend fun cmdHome(player: Player,
|
suspend fun cmdHome(player: Player,
|
||||||
@NamedParcelDefault(FIRST_OWNED) target: NamedParcelTarget): Any?
|
@NamedParcelDefault(FIRST_OWNED) target: NamedParcelTarget): Any? {
|
||||||
{
|
|
||||||
if (player !== target.player && !player.hasParcelHomeOthers) {
|
if (player !== target.player && !player.hasParcelHomeOthers) {
|
||||||
error("You do not have permission to teleport to other people's parcels")
|
error("You do not have permission to teleport to other people's parcels")
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("cmdHome thread before await: ${Thread.currentThread().name}")
|
|
||||||
val ownedParcelsResult = plugin.storage.getOwnedParcels(ParcelOwner(uuid = target.player.uuid)).await()
|
val ownedParcelsResult = plugin.storage.getOwnedParcels(ParcelOwner(uuid = target.player.uuid)).await()
|
||||||
logger.info("cmdHome thread after await: ${Thread.currentThread().name}")
|
|
||||||
|
|
||||||
val uuid = target.player.uuid
|
val uuid = target.player.uuid
|
||||||
val ownedParcels = ownedParcelsResult
|
val ownedParcels = ownedParcelsResult
|
||||||
|
|||||||
248
src/main/kotlin/io/dico/parcels2/listener/ParcelEditListener.kt
Normal file
248
src/main/kotlin/io/dico/parcels2/listener/ParcelEditListener.kt
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
package io.dico.parcels2.listener
|
||||||
|
|
||||||
|
import gnu.trove.TLongCollection
|
||||||
|
import io.dico.dicore.ListenerMarker
|
||||||
|
import io.dico.dicore.RegistratorListener
|
||||||
|
import io.dico.parcels2.Parcel
|
||||||
|
import io.dico.parcels2.ParcelWorld
|
||||||
|
import io.dico.parcels2.Worlds
|
||||||
|
import io.dico.parcels2.util.hasBanBypass
|
||||||
|
import io.dico.parcels2.util.hasBuildAnywhere
|
||||||
|
import io.dico.parcels2.util.sendParcelMessage
|
||||||
|
import io.dico.parcels2.util.uuid
|
||||||
|
import org.bukkit.Material.*
|
||||||
|
import org.bukkit.block.Biome
|
||||||
|
import org.bukkit.block.Block
|
||||||
|
import org.bukkit.block.data.type.Bed
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.EventPriority.NORMAL
|
||||||
|
import org.bukkit.event.block.*
|
||||||
|
import org.bukkit.event.entity.EntityExplodeEvent
|
||||||
|
import org.bukkit.event.entity.ExplosionPrimeEvent
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent
|
||||||
|
import org.bukkit.event.player.PlayerMoveEvent
|
||||||
|
import org.bukkit.inventory.InventoryHolder
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
class ParcelEditListener(val worlds: Worlds) {
|
||||||
|
val entityTracker = ParcelEntityTracker()
|
||||||
|
|
||||||
|
private inline fun <T> T?.isNullOr(condition: T.() -> Boolean): Boolean = this == null || condition()
|
||||||
|
private inline fun <T> T?.isPresentAnd(condition: T.() -> Boolean): Boolean = this != null && condition()
|
||||||
|
private inline fun
|
||||||
|
fun Parcel?.canBuildN(user: Player) = isPresentAnd { canBuild(user) } || user.hasBuildAnywhere
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the world and parcel that the block resides in
|
||||||
|
* wo is the world, ppa is the parcel
|
||||||
|
* ppa for possibly a parcel - it will be null if not in an existing parcel
|
||||||
|
* returns null if not in a registered parcel world
|
||||||
|
*/
|
||||||
|
private fun getWoAndPPa(block: Block): Pair<ParcelWorld, Parcel?>? {
|
||||||
|
val world = worlds.getWorld(block.world) ?: return null
|
||||||
|
return world to world.parcelAt(block)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prevents players from entering plots they are banned from
|
||||||
|
*/
|
||||||
|
@ListenerMarker(priority = NORMAL)
|
||||||
|
val onPlayerMove = RegistratorListener<PlayerMoveEvent> l@{ event ->
|
||||||
|
val user = event.player
|
||||||
|
if (user.hasBanBypass) return@l
|
||||||
|
val parcel = worlds.getParcelAt(event.to) ?: return@l
|
||||||
|
if (parcel.isBanned(user.uuid)) {
|
||||||
|
worlds.getParcelAt(event.from)?.also {
|
||||||
|
user.teleport(it.homeLocation)
|
||||||
|
user.sendParcelMessage(nopermit = true, message = "You are banned from this parcel")
|
||||||
|
} ?: run { event.to = event.from }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prevents players from breaking blocks outside of their parcels
|
||||||
|
* Prevents containers from dropping their contents when broken, if configured
|
||||||
|
*/
|
||||||
|
@ListenerMarker(priority = NORMAL)
|
||||||
|
val onBlockBreak = RegistratorListener<BlockBreakEvent> l@{ event ->
|
||||||
|
val (wo, ppa) = getWoAndPPa(event.block) ?: return@l
|
||||||
|
if (!event.player.hasBuildAnywhere && ppa.isNullOr { !canBuild(event.player) }) {
|
||||||
|
event.isCancelled = true; return@l
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wo.options.dropEntityItems) {
|
||||||
|
val state = event.block.state
|
||||||
|
if (state is InventoryHolder) {
|
||||||
|
state.inventory.clear()
|
||||||
|
state.update()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prevents players from placing blocks outside of their parcels
|
||||||
|
*/
|
||||||
|
@ListenerMarker(priority = NORMAL)
|
||||||
|
val onBlockPlace = RegistratorListener<BlockBreakEvent> l@{ event ->
|
||||||
|
val (wo, ppa) = getWoAndPPa(event.block) ?: return@l
|
||||||
|
if (!event.player.hasBuildAnywhere && !ppa.isNullOr { !canBuild(event.player) }) {
|
||||||
|
event.isCancelled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Control pistons
|
||||||
|
*/
|
||||||
|
@ListenerMarker(priority = NORMAL)
|
||||||
|
val onBlockPistonExtend = RegistratorListener<BlockPistonExtendEvent> l@{ event ->
|
||||||
|
checkPistonMovement(event, event.blocks)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ListenerMarker(priority = NORMAL)
|
||||||
|
val onBlockPistonRetractEvent = RegistratorListener<BlockPistonRetractEvent> l@{ event ->
|
||||||
|
checkPistonMovement(event, event.blocks)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Doing some unnecessary optimizations here..
|
||||||
|
//@formatter:off
|
||||||
|
private inline fun Column(x: Int, z: Int): Long = x.toLong() or (z.toLong().shl(32))
|
||||||
|
|
||||||
|
private inline val Long.columnX get() = and(0xFFFF_FFFFL).toInt()
|
||||||
|
private inline val Long.columnZ get() = ushr(32).and(0xFFFF_FFFFL).toInt()
|
||||||
|
private inline fun TLongCollection.forEachInline(block: (Long) -> Unit) = iterator().let { while (it.hasNext()) block(it.next()) }
|
||||||
|
//@formatter:on
|
||||||
|
private fun checkPistonMovement(event: BlockPistonEvent, blocks: List<Block>) {
|
||||||
|
val world = worlds.getWorld(event.block.world) ?: return
|
||||||
|
val direction = event.direction
|
||||||
|
val columns = gnu.trove.set.hash.TLongHashSet(blocks.size * 2)
|
||||||
|
|
||||||
|
blocks.forEach {
|
||||||
|
columns.add(Column(it.x, it.z))
|
||||||
|
it.getRelative(direction).let { columns.add(Column(it.x, it.z)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
columns.forEachInline {
|
||||||
|
val ppa = world.parcelAt(it.columnX, it.columnZ)
|
||||||
|
if (ppa.isNullOr { hasBlockVisitors }) {
|
||||||
|
event.isCancelled = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prevents explosions if enabled by the configs for that world
|
||||||
|
*/
|
||||||
|
@ListenerMarker(priority = NORMAL)
|
||||||
|
val onExplosionPrimeEvent = RegistratorListener<ExplosionPrimeEvent> l@{ event ->
|
||||||
|
val (wo, ppa) = getWoAndPPa(event.entity.location.block) ?: return@l
|
||||||
|
if (ppa?.hasBlockVisitors == true) {
|
||||||
|
event.radius = 0F; event.isCancelled = true
|
||||||
|
} else if (wo.options.disableExplosions) {
|
||||||
|
event.radius = 0F
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prevents creepers and tnt minecarts from exploding if explosions are disabled
|
||||||
|
*/
|
||||||
|
@ListenerMarker(priority = NORMAL)
|
||||||
|
val onEntityExplodeEvent = RegistratorListener<EntityExplodeEvent> l@{ event ->
|
||||||
|
entityTracker.untrack(event.entity)
|
||||||
|
val world = worlds.getWorld(event.entity.world) ?: return@l
|
||||||
|
if (world.options.disableExplosions || world.parcelAt(event.entity).isPresentAnd { hasBlockVisitors }) {
|
||||||
|
event.isCancelled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prevents creepers and tnt minecarts from exploding if explosions are disabled
|
||||||
|
*/
|
||||||
|
@ListenerMarker(priority = NORMAL)
|
||||||
|
val onBlockFromToEvent = RegistratorListener<BlockFromToEvent> l@{ event ->
|
||||||
|
val (wo, ppa) = getWoAndPPa(event.toBlock) ?: return@l
|
||||||
|
if (ppa.isNullOr { hasBlockVisitors }) event.isCancelled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prevents players from placing liquids, using flint and steel, changing redstone components,
|
||||||
|
* using inputs (unless allowed by the plot),
|
||||||
|
* and using items disabled in the configuration for that world.
|
||||||
|
* Prevents player from using beds in HELL or SKY biomes if explosions are disabled.
|
||||||
|
*/
|
||||||
|
@Suppress("NON_EXHAUSTIVE_WHEN")
|
||||||
|
@ListenerMarker(priority = NORMAL)
|
||||||
|
val onPlayerInteractEvent = RegistratorListener<PlayerInteractEvent> l@{ event ->
|
||||||
|
val user = event.player
|
||||||
|
val world = worlds.getWorld(user.world) ?: return@l
|
||||||
|
val clickedBlock = event.clickedBlock
|
||||||
|
val parcel = clickedBlock?.let { world.parcelAt(it) }
|
||||||
|
|
||||||
|
if (!user.hasBuildAnywhere && parcel.isPresentAnd { isBanned(user.uuid) }) {
|
||||||
|
user.sendParcelMessage(nopermit = true, message = "You cannot interact with parcels you're banned from")
|
||||||
|
event.isCancelled = true; return@l
|
||||||
|
}
|
||||||
|
|
||||||
|
when (event.action) {
|
||||||
|
Action.RIGHT_CLICK_BLOCK -> when (clickedBlock.type) {
|
||||||
|
REPEATER,
|
||||||
|
COMPARATOR -> run {
|
||||||
|
if (!parcel.canBuildN(user)) {
|
||||||
|
event.isCancelled = true; return@l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LEVER,
|
||||||
|
STONE_BUTTON,
|
||||||
|
ANVIL,
|
||||||
|
TRAPPED_CHEST,
|
||||||
|
OAK_BUTTON, BIRCH_BUTTON, SPRUCE_BUTTON, JUNGLE_BUTTON, ACACIA_BUTTON, DARK_OAK_BUTTON,
|
||||||
|
OAK_FENCE_GATE, BIRCH_FENCE_GATE, SPRUCE_FENCE_GATE, JUNGLE_FENCE_GATE, ACACIA_FENCE_GATE, DARK_OAK_FENCE_GATE,
|
||||||
|
OAK_DOOR, BIRCH_DOOR, SPRUCE_DOOR, JUNGLE_DOOR, ACACIA_DOOR, DARK_OAK_DOOR,
|
||||||
|
OAK_TRAPDOOR, BIRCH_TRAPDOOR, SPRUCE_TRAPDOOR, JUNGLE_TRAPDOOR, ACACIA_TRAPDOOR, DARK_OAK_TRAPDOOR
|
||||||
|
-> run {
|
||||||
|
if (!user.hasBuildAnywhere && !parcel.isNullOr { canBuild(user) || allowInteractInputs }) {
|
||||||
|
user.sendParcelMessage(nopermit = true, message = "You cannot use inputs in this parcel")
|
||||||
|
event.isCancelled = true; return@l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WHITE_BED, ORANGE_BED, MAGENTA_BED, LIGHT_BLUE_BED, YELLOW_BED, LIME_BED, PINK_BED, GRAY_BED, LIGHT_GRAY_BED, CYAN_BED, PURPLE_BED, BLUE_BED, BROWN_BED, GREEN_BED, RED_BED, BLACK_BED
|
||||||
|
-> run {
|
||||||
|
if (world.options.disableExplosions) {
|
||||||
|
val bed = clickedBlock.blockData as Bed
|
||||||
|
val head = if (bed == Bed.Part.FOOT) clickedBlock.getRelative(bed.facing) else clickedBlock
|
||||||
|
when (head.biome) {
|
||||||
|
Biome.NETHER, Biome.THE_END -> run {
|
||||||
|
user.sendParcelMessage(nopermit = true, message = "You cannot use this bed because it would explode")
|
||||||
|
event.isCancelled = true; return@l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Action.RIGHT_CLICK_AIR -> if (event.hasItem()) {
|
||||||
|
val item = event.item.type
|
||||||
|
if (world.options.blockedItems.contains(item)) {
|
||||||
|
user.sendParcelMessage(nopermit = true, message = "You cannot use this bed because it would explode")
|
||||||
|
event.isCancelled = true; return@l
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parcel.canBuildN(user)) {
|
||||||
|
when (item) {
|
||||||
|
LAVA_BUCKET, WATER_BUCKET, BUCKET, FLINT_AND_STEEL -> event.isCancelled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Action.PHYSICAL -> if (!user.hasBuildAnywhere && !parcel.isPresentAnd { canBuild(user) || allowInteractInputs }) {
|
||||||
|
event.isCancelled = true; return@l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package io.dico.parcels2.listener
|
||||||
|
|
||||||
|
import io.dico.parcels2.Parcel
|
||||||
|
import org.bukkit.entity.Entity
|
||||||
|
|
||||||
|
class ParcelEntityTracker {
|
||||||
|
val map = mutableMapOf<Entity, Parcel>()
|
||||||
|
|
||||||
|
fun untrack(entity: Entity) {
|
||||||
|
map.remove(entity)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
92
src/main/kotlin/io/dico/parcels2/util/MaterialExtensions.kt
Normal file
92
src/main/kotlin/io/dico/parcels2/util/MaterialExtensions.kt
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
package io.dico.parcels2.util
|
||||||
|
|
||||||
|
import org.bukkit.Material
|
||||||
|
import org.bukkit.Material.*
|
||||||
|
|
||||||
|
/*
|
||||||
|
colors:
|
||||||
|
WHITE_$,
|
||||||
|
ORANGE_$,
|
||||||
|
MAGENTA_$,
|
||||||
|
LIGHT_BLUE_$,
|
||||||
|
YELLOW_$,
|
||||||
|
LIME_$,
|
||||||
|
PINK_$,
|
||||||
|
GRAY_$,
|
||||||
|
LIGHT_GRAY_$,
|
||||||
|
CYAN_$,
|
||||||
|
PURPLE_$,
|
||||||
|
BLUE_$,
|
||||||
|
BROWN_$,
|
||||||
|
GREEN_$,
|
||||||
|
RED_$,
|
||||||
|
BLACK_$,
|
||||||
|
|
||||||
|
wood:
|
||||||
|
OAK_$,
|
||||||
|
BIRCH_$,
|
||||||
|
SPRUCE_$,
|
||||||
|
JUNGLE_$,
|
||||||
|
ACACIA_$,
|
||||||
|
DARK_OAK_$,
|
||||||
|
*/
|
||||||
|
|
||||||
|
val Material.isBed get() = when(this) {
|
||||||
|
WHITE_BED,
|
||||||
|
ORANGE_BED,
|
||||||
|
MAGENTA_BED,
|
||||||
|
LIGHT_BLUE_BED,
|
||||||
|
YELLOW_BED,
|
||||||
|
LIME_BED,
|
||||||
|
PINK_BED,
|
||||||
|
GRAY_BED,
|
||||||
|
LIGHT_GRAY_BED,
|
||||||
|
CYAN_BED,
|
||||||
|
PURPLE_BED,
|
||||||
|
BLUE_BED,
|
||||||
|
BROWN_BED,
|
||||||
|
GREEN_BED,
|
||||||
|
RED_BED,
|
||||||
|
BLACK_BED -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
|
val Material.isWoodDoor get() = when(this) {
|
||||||
|
OAK_DOOR,
|
||||||
|
BIRCH_DOOR,
|
||||||
|
SPRUCE_DOOR,
|
||||||
|
JUNGLE_DOOR,
|
||||||
|
ACACIA_DOOR,
|
||||||
|
DARK_OAK_DOOR -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
|
val Material.isWoodTrapdoor get() = when(this) {
|
||||||
|
OAK_TRAPDOOR,
|
||||||
|
BIRCH_TRAPDOOR,
|
||||||
|
SPRUCE_TRAPDOOR,
|
||||||
|
JUNGLE_TRAPDOOR,
|
||||||
|
ACACIA_TRAPDOOR,
|
||||||
|
DARK_OAK_TRAPDOOR -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
|
val Material.isWoodFenceGate get() = when(this) {
|
||||||
|
OAK_FENCE_GATE,
|
||||||
|
BIRCH_FENCE_GATE,
|
||||||
|
SPRUCE_FENCE_GATE,
|
||||||
|
JUNGLE_FENCE_GATE,
|
||||||
|
ACACIA_FENCE_GATE,
|
||||||
|
DARK_OAK_FENCE_GATE -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
|
val Material.isWoodButton get() = when(this) {
|
||||||
|
OAK_BUTTON,
|
||||||
|
BIRCH_BUTTON,
|
||||||
|
SPRUCE_BUTTON,
|
||||||
|
JUNGLE_BUTTON,
|
||||||
|
ACACIA_BUTTON,
|
||||||
|
DARK_OAK_BUTTON -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
@@ -9,8 +9,8 @@ import org.bukkit.plugin.java.JavaPlugin
|
|||||||
|
|
||||||
inline val OfflinePlayer.uuid get() = uniqueId
|
inline val OfflinePlayer.uuid get() = uniqueId
|
||||||
inline val Player.hasBanBypass get() = hasPermission("parcels.admin.bypass.ban")
|
inline val Player.hasBanBypass get() = hasPermission("parcels.admin.bypass.ban")
|
||||||
inline val Player.hasBuildAnywhere get() = hasPermission("parcels.admin.bypass.build")
|
|
||||||
inline val Player.hasGamemodeBypass get() = hasPermission("parcels.admin.bypass.gamemode")
|
inline val Player.hasGamemodeBypass get() = hasPermission("parcels.admin.bypass.gamemode")
|
||||||
|
inline val Player.hasBuildAnywhere get() = hasPermission("parcels.admin.bypass.build")
|
||||||
inline val Player.hasAdminManage get() = hasPermission("parcels.admin.manage")
|
inline val Player.hasAdminManage get() = hasPermission("parcels.admin.manage")
|
||||||
inline val Player.hasParcelHomeOthers get() = hasPermission("parcels.command.home.others")
|
inline val Player.hasParcelHomeOthers get() = hasPermission("parcels.command.home.others")
|
||||||
inline val Player.hasRandomSpecific get() = hasPermission("parcels.command.random.specific")
|
inline val Player.hasRandomSpecific get() = hasPermission("parcels.command.random.specific")
|
||||||
|
|||||||
Reference in New Issue
Block a user