diff options
Diffstat (limited to 'src/main/kotlin/io/dico/parcels2/util')
13 files changed, 429 insertions, 411 deletions
diff --git a/src/main/kotlin/io/dico/parcels2/util/BukkitUtil.kt b/src/main/kotlin/io/dico/parcels2/util/BukkitUtil.kt index 618eaed..c7d813b 100644 --- a/src/main/kotlin/io/dico/parcels2/util/BukkitUtil.kt +++ b/src/main/kotlin/io/dico/parcels2/util/BukkitUtil.kt @@ -3,6 +3,7 @@ package io.dico.parcels2.util import io.dico.parcels2.util.ext.isValid import org.bukkit.Bukkit import org.bukkit.OfflinePlayer +import java.lang.IllegalArgumentException import java.util.UUID fun getPlayerName(uuid: UUID): String? = getOfflinePlayer(uuid)?.name @@ -12,3 +13,11 @@ fun getOfflinePlayer(uuid: UUID): OfflinePlayer? = Bukkit.getOfflinePlayer(uuid) fun getOfflinePlayer(name: String): OfflinePlayer? = Bukkit.getOfflinePlayer(name).takeIf { it.isValid } fun isServerThread(): Boolean = Thread.currentThread().name == "Server thread" + +fun isPlayerNameValid(name: String): Boolean = + name.length in 3..16 + && name.find { it !in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_" } == null + +fun checkPlayerNameValid(name: String) { + if (!isPlayerNameValid(name)) throw IllegalArgumentException("Invalid player name: $name") +} diff --git a/src/main/kotlin/io/dico/parcels2/util/MainThreadDispatcher.kt b/src/main/kotlin/io/dico/parcels2/util/MainThreadDispatcher.kt index 3eb2e81..3904026 100644 --- a/src/main/kotlin/io/dico/parcels2/util/MainThreadDispatcher.kt +++ b/src/main/kotlin/io/dico/parcels2/util/MainThreadDispatcher.kt @@ -1,43 +1,43 @@ -package io.dico.parcels2.util - -import kotlinx.coroutines.CancellableContinuation -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.Delay -import kotlinx.coroutines.Runnable -import kotlinx.coroutines.timeunit.TimeUnit -import org.bukkit.plugin.Plugin -import kotlin.coroutines.CoroutineContext - -abstract class MainThreadDispatcher : CoroutineDispatcher(), Delay { - abstract val mainThread: Thread - abstract fun runOnMainThread(task: Runnable) -} - -@Suppress("FunctionName") -fun MainThreadDispatcher(plugin: Plugin): MainThreadDispatcher { - return object : MainThreadDispatcher() { - override val mainThread: Thread = Thread.currentThread() - - override fun dispatch(context: CoroutineContext, block: Runnable) { - doDispatch(block) - } - - override fun runOnMainThread(task: Runnable) { - doDispatch(task) - } - - private fun doDispatch(task: Runnable) { - if (Thread.currentThread() === mainThread) task.run() - else plugin.server.scheduler.runTaskLater(plugin, task, 0) - } - - override fun scheduleResumeAfterDelay(time: Long, unit: TimeUnit, continuation: CancellableContinuation<Unit>) { - val task = Runnable { - with (continuation) { resumeUndispatched(Unit) } - } - - val millis = unit.toMillis(time) - plugin.server.scheduler.runTaskLater(plugin, task, (millis + 25) / 50 - 1) - } - } +package io.dico.parcels2.util
+
+import kotlinx.coroutines.CancellableContinuation
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Delay
+import kotlinx.coroutines.Runnable
+import kotlinx.coroutines.timeunit.TimeUnit
+import org.bukkit.plugin.Plugin
+import kotlin.coroutines.CoroutineContext
+
+abstract class MainThreadDispatcher : CoroutineDispatcher(), Delay {
+ abstract val mainThread: Thread
+ abstract fun runOnMainThread(task: Runnable)
+}
+
+@Suppress("FunctionName")
+fun MainThreadDispatcher(plugin: Plugin): MainThreadDispatcher {
+ return object : MainThreadDispatcher() {
+ override val mainThread: Thread = Thread.currentThread()
+
+ override fun dispatch(context: CoroutineContext, block: Runnable) {
+ doDispatch(block)
+ }
+
+ override fun runOnMainThread(task: Runnable) {
+ doDispatch(task)
+ }
+
+ private fun doDispatch(task: Runnable) {
+ if (Thread.currentThread() === mainThread) task.run()
+ else plugin.server.scheduler.runTaskLater(plugin, task, 0)
+ }
+
+ override fun scheduleResumeAfterDelay(time: Long, unit: TimeUnit, continuation: CancellableContinuation<Unit>) {
+ val task = Runnable {
+ with (continuation) { resumeUndispatched(Unit) }
+ }
+
+ val millis = unit.toMillis(time)
+ plugin.server.scheduler.runTaskLater(plugin, task, (millis + 25) / 50 - 1)
+ }
+ }
}
\ No newline at end of file diff --git a/src/main/kotlin/io/dico/parcels2/util/PluginAware.kt b/src/main/kotlin/io/dico/parcels2/util/PluginAware.kt new file mode 100644 index 0000000..b55f991 --- /dev/null +++ b/src/main/kotlin/io/dico/parcels2/util/PluginAware.kt @@ -0,0 +1,19 @@ +@file:Suppress("RedundantLambdaArrow") + +package io.dico.parcels2.util + +import org.bukkit.plugin.Plugin +import org.bukkit.scheduler.BukkitTask + +interface PluginAware { + val plugin: Plugin +} + +inline fun PluginAware.schedule(delay: Int = 0, crossinline task: () -> Unit): BukkitTask { + return plugin.server.scheduler.runTaskLater(plugin, { -> task() }, delay.toLong()) +} + +inline fun PluginAware.scheduleRepeating(interval: Int, delay: Int = 0, crossinline task: () -> Unit): BukkitTask { + return plugin.server.scheduler.runTaskTimer(plugin, { -> task() }, delay.toLong(), interval.toLong()) +} + diff --git a/src/main/kotlin/io/dico/parcels2/util/PluginScheduler.kt b/src/main/kotlin/io/dico/parcels2/util/PluginScheduler.kt deleted file mode 100644 index f29ba2b..0000000 --- a/src/main/kotlin/io/dico/parcels2/util/PluginScheduler.kt +++ /dev/null @@ -1,20 +0,0 @@ -package io.dico.parcels2.util - -import org.bukkit.plugin.Plugin -import org.bukkit.scheduler.BukkitTask - -interface PluginScheduler { - val plugin: Plugin - - fun schedule(delay: Int, task: () -> Unit): BukkitTask { - return plugin.server.scheduler.runTaskLater(plugin, task, delay.toLong()) - } - - fun scheduleRepeating(delay: Int, interval: Int, task: () -> Unit): BukkitTask { - return plugin.server.scheduler.runTaskTimer(plugin, task, delay.toLong(), interval.toLong()) - } -} - -@Suppress("NOTHING_TO_INLINE") -inline fun PluginScheduler.schedule(noinline task: () -> Unit) = schedule(0, task) - diff --git a/src/main/kotlin/io/dico/parcels2/util/ext/Material.kt b/src/main/kotlin/io/dico/parcels2/util/ext/Material.kt index e160e55..1351b5d 100644 --- a/src/main/kotlin/io/dico/parcels2/util/ext/Material.kt +++ b/src/main/kotlin/io/dico/parcels2/util/ext/Material.kt @@ -1,108 +1,108 @@ -package io.dico.parcels2.util.ext - -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 - } - -private fun getMaterialPrefixed(prefix: String, name: String): Material { - return Material.getMaterial("${prefix}_$name") ?: throw IllegalArgumentException("Material ${prefix}_$name doesn't exist") -} - -fun getMaterialsWithWoodTypePrefix(name: String) = arrayOf( - getMaterialPrefixed("OAK", name), - getMaterialPrefixed("BIRCH", name), - getMaterialPrefixed("SPRUCE", name), - getMaterialPrefixed("JUNGLE", name), - getMaterialPrefixed("ACACIA", name), - getMaterialPrefixed("DARK_OAK", name) -) - -fun getMaterialsWithWoolColorPrefix(name: String) = arrayOf( - getMaterialPrefixed("WHITE", name), - getMaterialPrefixed("ORANGE", name), - getMaterialPrefixed("MAGENTA", name), - getMaterialPrefixed("LIGHT_BLUE", name), - getMaterialPrefixed("YELLOW", name), - getMaterialPrefixed("LIME", name), - getMaterialPrefixed("PINK", name), - getMaterialPrefixed("GRAY", name), - getMaterialPrefixed("LIGHT_GRAY", name), - getMaterialPrefixed("CYAN", name), - getMaterialPrefixed("PURPLE", name), - getMaterialPrefixed("BLUE", name), - getMaterialPrefixed("BROWN", name), - getMaterialPrefixed("GREEN", name), - getMaterialPrefixed("RED", name), - getMaterialPrefixed("BLACK", name) +package io.dico.parcels2.util.ext
+
+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
+ }
+
+private fun getMaterialPrefixed(prefix: String, name: String): Material {
+ return Material.getMaterial("${prefix}_$name") ?: throw IllegalArgumentException("Material ${prefix}_$name doesn't exist")
+}
+
+fun getMaterialsWithWoodTypePrefix(name: String) = arrayOf(
+ getMaterialPrefixed("OAK", name),
+ getMaterialPrefixed("BIRCH", name),
+ getMaterialPrefixed("SPRUCE", name),
+ getMaterialPrefixed("JUNGLE", name),
+ getMaterialPrefixed("ACACIA", name),
+ getMaterialPrefixed("DARK_OAK", name)
+)
+
+fun getMaterialsWithWoolColorPrefix(name: String) = arrayOf(
+ getMaterialPrefixed("WHITE", name),
+ getMaterialPrefixed("ORANGE", name),
+ getMaterialPrefixed("MAGENTA", name),
+ getMaterialPrefixed("LIGHT_BLUE", name),
+ getMaterialPrefixed("YELLOW", name),
+ getMaterialPrefixed("LIME", name),
+ getMaterialPrefixed("PINK", name),
+ getMaterialPrefixed("GRAY", name),
+ getMaterialPrefixed("LIGHT_GRAY", name),
+ getMaterialPrefixed("CYAN", name),
+ getMaterialPrefixed("PURPLE", name),
+ getMaterialPrefixed("BLUE", name),
+ getMaterialPrefixed("BROWN", name),
+ getMaterialPrefixed("GREEN", name),
+ getMaterialPrefixed("RED", name),
+ getMaterialPrefixed("BLACK", name)
)
\ No newline at end of file diff --git a/src/main/kotlin/io/dico/parcels2/util/ext/Misc.kt b/src/main/kotlin/io/dico/parcels2/util/ext/Misc.kt index 75aba35..e5e8aa9 100644 --- a/src/main/kotlin/io/dico/parcels2/util/ext/Misc.kt +++ b/src/main/kotlin/io/dico/parcels2/util/ext/Misc.kt @@ -1,81 +1,81 @@ -package io.dico.parcels2.util.ext - -import io.dico.dicore.Formatting -import io.dico.parcels2.logger -import java.io.File - -fun File.tryCreate(): Boolean { - if (exists()) { - return !isDirectory - } - val parent = parentFile - if (parent == null || !(parent.exists() || parent.mkdirs()) || !createNewFile()) { - logger.warn("Failed to create file $canonicalPath") - return false - } - return true -} - -inline fun Boolean.alsoIfTrue(block: () -> Unit): Boolean = also { if (it) block() } -inline fun Boolean.alsoIfFalse(block: () -> Unit): Boolean = also { if (!it) block() } - -inline fun <R> Any.synchronized(block: () -> R): R = synchronized(this, block) - -//inline fun <T> T?.isNullOr(condition: T.() -> Boolean): Boolean = this == null || condition() -//inline fun <T> T?.isPresentAnd(condition: T.() -> Boolean): Boolean = this != null && condition() -inline fun <T> T?.ifNullRun(block: () -> Unit): T? { - if (this == null) block() - return this -} - -inline fun <T, U> MutableMap<T, U>.editLoop(block: EditLoopScope<T, U>.(T, U) -> Unit) { - return EditLoopScope(this).doEditLoop(block) -} - -inline fun <T, U> MutableMap<T, U>.editLoop(block: EditLoopScope<T, U>.() -> Unit) { - return EditLoopScope(this).doEditLoop(block) -} - -class EditLoopScope<T, U>(val _map: MutableMap<T, U>) { - private var iterator: MutableIterator<MutableMap.MutableEntry<T, U>>? = null - lateinit var _entry: MutableMap.MutableEntry<T, U> - - inline val key get() = _entry.key - inline var value - get() = _entry.value - set(target) = run { _entry.setValue(target) } - - inline fun doEditLoop(block: EditLoopScope<T, U>.() -> Unit) { - val it = _initIterator() - while (it.hasNext()) { - _entry = it.next() - block() - } - } - - inline fun doEditLoop(block: EditLoopScope<T, U>.(T, U) -> Unit) { - val it = _initIterator() - while (it.hasNext()) { - val entry = it.next().also { _entry = it } - block(entry.key, entry.value) - } - } - - fun remove() { - iterator!!.remove() - } - - fun _initIterator(): MutableIterator<MutableMap.MutableEntry<T, U>> { - iterator?.let { throw IllegalStateException() } - return _map.entries.iterator().also { iterator = it } - } - -} - -operator fun Formatting.plus(other: Formatting) = toString() + other -operator fun Formatting.plus(other: String) = toString() + other - -inline fun <T> Pair<T, T>.forEach(block: (T) -> Unit) { - block(first) - block(second) -} +package io.dico.parcels2.util.ext
+
+import io.dico.dicore.Formatting
+import io.dico.parcels2.logger
+import java.io.File
+
+fun File.tryCreate(): Boolean {
+ if (exists()) {
+ return !isDirectory
+ }
+ val parent = parentFile
+ if (parent == null || !(parent.exists() || parent.mkdirs()) || !createNewFile()) {
+ logger.warn("Failed to create file $canonicalPath")
+ return false
+ }
+ return true
+}
+
+inline fun Boolean.alsoIfTrue(block: () -> Unit): Boolean = also { if (it) block() }
+inline fun Boolean.alsoIfFalse(block: () -> Unit): Boolean = also { if (!it) block() }
+
+inline fun <R> Any.synchronized(block: () -> R): R = synchronized(this, block)
+
+//inline fun <T> T?.isNullOr(condition: T.() -> Boolean): Boolean = this == null || condition()
+//inline fun <T> T?.isPresentAnd(condition: T.() -> Boolean): Boolean = this != null && condition()
+inline fun <T> T?.ifNullRun(block: () -> Unit): T? {
+ if (this == null) block()
+ return this
+}
+
+inline fun <T, U> MutableMap<T, U>.editLoop(block: EditLoopScope<T, U>.(T, U) -> Unit) {
+ return EditLoopScope(this).doEditLoop(block)
+}
+
+inline fun <T, U> MutableMap<T, U>.editLoop(block: EditLoopScope<T, U>.() -> Unit) {
+ return EditLoopScope(this).doEditLoop(block)
+}
+
+class EditLoopScope<T, U>(val _map: MutableMap<T, U>) {
+ private var iterator: MutableIterator<MutableMap.MutableEntry<T, U>>? = null
+ lateinit var _entry: MutableMap.MutableEntry<T, U>
+
+ inline val key get() = _entry.key
+ inline var value
+ get() = _entry.value
+ set(target) = run { _entry.setValue(target) }
+
+ inline fun doEditLoop(block: EditLoopScope<T, U>.() -> Unit) {
+ val it = _initIterator()
+ while (it.hasNext()) {
+ _entry = it.next()
+ block()
+ }
+ }
+
+ inline fun doEditLoop(block: EditLoopScope<T, U>.(T, U) -> Unit) {
+ val it = _initIterator()
+ while (it.hasNext()) {
+ val entry = it.next().also { _entry = it }
+ block(entry.key, entry.value)
+ }
+ }
+
+ fun remove() {
+ iterator!!.remove()
+ }
+
+ fun _initIterator(): MutableIterator<MutableMap.MutableEntry<T, U>> {
+ iterator?.let { throw IllegalStateException() }
+ return _map.entries.iterator().also { iterator = it }
+ }
+
+}
+
+operator fun Formatting.plus(other: Formatting) = toString() + other
+operator fun Formatting.plus(other: String) = toString() + other
+
+inline fun <T> Pair<T, T>.forEach(block: (T) -> Unit) {
+ block(first)
+ block(second)
+}
diff --git a/src/main/kotlin/io/dico/parcels2/util/ext/Player.kt b/src/main/kotlin/io/dico/parcels2/util/ext/Player.kt index a7f21c5..4c502a0 100644 --- a/src/main/kotlin/io/dico/parcels2/util/ext/Player.kt +++ b/src/main/kotlin/io/dico/parcels2/util/ext/Player.kt @@ -1,57 +1,57 @@ -package io.dico.parcels2.util.ext - -import io.dico.dicore.Formatting -import io.dico.parcels2.ParcelsPlugin -import io.dico.parcels2.logger -import org.bukkit.OfflinePlayer -import org.bukkit.entity.Player -import org.bukkit.permissions.Permissible -import org.bukkit.plugin.java.JavaPlugin - -inline val OfflinePlayer.uuid get() = uniqueId - -@Suppress("UsePropertyAccessSyntax") -inline val OfflinePlayer.isValid - get() = isOnline() || hasPlayedBefore() - -const val PERM_BAN_BYPASS = "parcels.admin.bypass.ban" -const val PERM_BUILD_ANYWHERE = "parcels.admin.bypass.build" -const val PERM_ADMIN_MANAGE = "parcels.admin.manage" - -inline val Permissible.hasPermBanBypass get() = hasPermission(PERM_BAN_BYPASS) -inline val Permissible.hasPermGamemodeBypass get() = hasPermission("parcels.admin.bypass.gamemode") -inline val Permissible.hasPermBuildAnywhere get() = hasPermission(PERM_BUILD_ANYWHERE) -inline val Permissible.hasPermAdminManage get() = hasPermission(PERM_ADMIN_MANAGE) -inline val Permissible.hasParcelHomeOthers get() = hasPermission("parcels.command.home.others") -inline val Permissible.hasPermRandomSpecific get() = hasPermission("parcels.command.random.specific") -val Player.parcelLimit: Int - get() { - for (info in effectivePermissions) { - val perm = info.permission - if (perm.startsWith("parcels.limit.")) { - val limitString = perm.substring("parcels.limit.".length) - if (limitString == "*") { - return Int.MAX_VALUE - } - return limitString.toIntOrNull() ?: DEFAULT_LIMIT.also { - logger.warn("$name has permission '$perm'. The suffix can not be parsed to an integer (or *).") - } - } - } - return DEFAULT_LIMIT - } - -private const val DEFAULT_LIMIT = 1 -private val prefix = Formatting.translateChars('&', "&4[&c${JavaPlugin.getPlugin(ParcelsPlugin::class.java).name}&4] &a") - -fun Player.sendParcelMessage(except: Boolean = false, nopermit: Boolean = false, message: String) { - if (except) { - sendMessage(prefix + Formatting.YELLOW + Formatting.translateChars('&', message)) - } else if (nopermit) { - sendMessage(prefix + Formatting.RED + Formatting.translateChars('&', message)) - } else { - sendMessage(prefix + Formatting.translateChars('&', message)) - } -} - -const val PLAYER_NAME_PLACEHOLDER = ":unknown_name:" +package io.dico.parcels2.util.ext
+
+import io.dico.dicore.Formatting
+import io.dico.parcels2.ParcelsPlugin
+import io.dico.parcels2.logger
+import org.bukkit.OfflinePlayer
+import org.bukkit.entity.Player
+import org.bukkit.permissions.Permissible
+import org.bukkit.plugin.java.JavaPlugin
+
+inline val OfflinePlayer.uuid get() = uniqueId
+
+@Suppress("UsePropertyAccessSyntax")
+inline val OfflinePlayer.isValid
+ get() = isOnline() || hasPlayedBefore()
+
+const val PERM_BAN_BYPASS = "parcels.admin.bypass.ban"
+const val PERM_BUILD_ANYWHERE = "parcels.admin.bypass.build"
+const val PERM_ADMIN_MANAGE = "parcels.admin.manage"
+
+inline val Permissible.hasPermBanBypass get() = hasPermission(PERM_BAN_BYPASS)
+inline val Permissible.hasPermGamemodeBypass get() = hasPermission("parcels.admin.bypass.gamemode")
+inline val Permissible.hasPermBuildAnywhere get() = hasPermission(PERM_BUILD_ANYWHERE)
+inline val Permissible.hasPermAdminManage get() = hasPermission(PERM_ADMIN_MANAGE)
+inline val Permissible.hasParcelHomeOthers get() = hasPermission("parcels.command.home.others")
+inline val Permissible.hasPermRandomSpecific get() = hasPermission("parcels.command.random.specific")
+val Player.parcelLimit: Int
+ get() {
+ for (info in effectivePermissions) {
+ val perm = info.permission
+ if (perm.startsWith("parcels.limit.")) {
+ val limitString = perm.substring("parcels.limit.".length)
+ if (limitString == "*") {
+ return Int.MAX_VALUE
+ }
+ return limitString.toIntOrNull() ?: DEFAULT_LIMIT.also {
+ logger.warn("$name has permission '$perm'. The suffix can not be parsed to an integer (or *).")
+ }
+ }
+ }
+ return DEFAULT_LIMIT
+ }
+
+private const val DEFAULT_LIMIT = 1
+private val prefix = Formatting.translateChars('&', "&4[&c${JavaPlugin.getPlugin(ParcelsPlugin::class.java).name}&4] &a")
+
+fun Player.sendParcelMessage(except: Boolean = false, nopermit: Boolean = false, message: String) {
+ if (except) {
+ sendMessage(prefix + Formatting.YELLOW + Formatting.translateChars('&', message))
+ } else if (nopermit) {
+ sendMessage(prefix + Formatting.RED + Formatting.translateChars('&', message))
+ } else {
+ sendMessage(prefix + Formatting.translateChars('&', message))
+ }
+}
+
+const val PLAYER_NAME_PLACEHOLDER = ":unknown_name:"
diff --git a/src/main/kotlin/io/dico/parcels2/util/math/Dimension.kt b/src/main/kotlin/io/dico/parcels2/util/math/Dimension.kt index cf67148..5b16860 100644 --- a/src/main/kotlin/io/dico/parcels2/util/math/Dimension.kt +++ b/src/main/kotlin/io/dico/parcels2/util/math/Dimension.kt @@ -1,19 +1,19 @@ -package io.dico.parcels2.util.math - -enum class Dimension { - X, - Y, - Z; - - val otherDimensions - get() = when (this) { - X -> Y to Z - Y -> X to Z - Z -> X to Y - } - - companion object { - private val values = values() - operator fun get(ordinal: Int) = values[ordinal] - } +package io.dico.parcels2.util.math
+
+enum class Dimension {
+ X,
+ Y,
+ Z;
+
+ val otherDimensions
+ get() = when (this) {
+ X -> Y to Z
+ Y -> X to Z
+ Z -> X to Y
+ }
+
+ companion object {
+ private val values = values()
+ operator fun get(ordinal: Int) = values[ordinal]
+ }
}
\ No newline at end of file diff --git a/src/main/kotlin/io/dico/parcels2/util/math/Math.kt b/src/main/kotlin/io/dico/parcels2/util/math/Math.kt index 12c3e9f..5f8deef 100644 --- a/src/main/kotlin/io/dico/parcels2/util/math/Math.kt +++ b/src/main/kotlin/io/dico/parcels2/util/math/Math.kt @@ -1,42 +1,42 @@ -package io.dico.parcels2.util.math - -fun Double.floor(): Int { - val down = toInt() - if (down.toDouble() != this && (java.lang.Double.doubleToRawLongBits(this).ushr(63).toInt()) == 1) { - return down - 1 - } - return down -} - -infix fun Int.umod(divisor: Int): Int { - val out = this % divisor - if (out < 0) { - return out + divisor - } - return out -} - -val Int.even: Boolean get() = and(1) == 0 - -fun IntRange.clamp(min: Int, max: Int): IntRange { - if (first < min) { - if (last > max) { - return IntRange(min, max) - } - return IntRange(min, last) - } - if (last > max) { - return IntRange(first, max) - } - return this -} - -// the name coerceAtMost is bad -fun Int.clampMax(max: Int) = coerceAtMost(max) -fun Double.clampMin(min: Double) = coerceAtLeast(min) -fun Double.clampMax(max: Double) = coerceAtMost(max) - -// Why does this not exist? -infix fun Int.ceilDiv(divisor: Int): Int { - return -Math.floorDiv(-this, divisor) +package io.dico.parcels2.util.math
+
+fun Double.floor(): Int {
+ val down = toInt()
+ if (down.toDouble() != this && (java.lang.Double.doubleToRawLongBits(this).ushr(63).toInt()) == 1) {
+ return down - 1
+ }
+ return down
+}
+
+infix fun Int.umod(divisor: Int): Int {
+ val out = this % divisor
+ if (out < 0) {
+ return out + divisor
+ }
+ return out
+}
+
+val Int.even: Boolean get() = and(1) == 0
+
+fun IntRange.clamp(min: Int, max: Int): IntRange {
+ if (first < min) {
+ if (last > max) {
+ return IntRange(min, max)
+ }
+ return IntRange(min, last)
+ }
+ if (last > max) {
+ return IntRange(first, max)
+ }
+ return this
+}
+
+// the name coerceAtMost is bad
+fun Int.clampMax(max: Int) = coerceAtMost(max)
+fun Double.clampMin(min: Double) = coerceAtLeast(min)
+fun Double.clampMax(max: Double) = coerceAtMost(max)
+
+// Why does this not exist?
+infix fun Int.ceilDiv(divisor: Int): Int {
+ return -Math.floorDiv(-this, divisor)
}
\ No newline at end of file diff --git a/src/main/kotlin/io/dico/parcels2/util/math/Region.kt b/src/main/kotlin/io/dico/parcels2/util/math/Region.kt index cdbd497..cdcbe0e 100644 --- a/src/main/kotlin/io/dico/parcels2/util/math/Region.kt +++ b/src/main/kotlin/io/dico/parcels2/util/math/Region.kt @@ -1,37 +1,37 @@ -package io.dico.parcels2.util.math - -data class Region(val origin: Vec3i, val size: Vec3i) { - val blockCount: Int get() = size.x * size.y * size.z - - val center: Vec3d - get() { - val x = (origin.x + size.x) / 2.0 - val y = (origin.y + size.y) / 2.0 - val z = (origin.z + size.z) / 2.0 - return Vec3d(x, y, z) - } - - val end: Vec3i - get() = origin + size - - val max: Vec3i - get() = Vec3i(origin.x + size.x - 1, origin.y + size.y - 1, origin.z + size.z - 1) - - fun withSize(size: Vec3i): Region { - if (size == this.size) return this - return Region(origin, size) - } - - operator fun contains(loc: Vec3i): Boolean = getFirstUncontainedDimensionOf(loc) == null - - fun getFirstUncontainedDimensionOf(loc: Vec3i): Dimension? { - val max = max - return when { - loc.x !in origin.x..max.x -> Dimension.X - loc.z !in origin.z..max.z -> Dimension.Z - loc.y !in origin.y..max.y -> Dimension.Y - else -> null - } - } - +package io.dico.parcels2.util.math
+
+data class Region(val origin: Vec3i, val size: Vec3i) {
+ val blockCount: Int get() = size.x * size.y * size.z
+
+ val center: Vec3d
+ get() {
+ val x = (origin.x + size.x) / 2.0
+ val y = (origin.y + size.y) / 2.0
+ val z = (origin.z + size.z) / 2.0
+ return Vec3d(x, y, z)
+ }
+
+ val end: Vec3i
+ get() = origin + size
+
+ val max: Vec3i
+ get() = Vec3i(origin.x + size.x - 1, origin.y + size.y - 1, origin.z + size.z - 1)
+
+ fun withSize(size: Vec3i): Region {
+ if (size == this.size) return this
+ return Region(origin, size)
+ }
+
+ operator fun contains(loc: Vec3i): Boolean = getFirstUncontainedDimensionOf(loc) == null
+
+ fun getFirstUncontainedDimensionOf(loc: Vec3i): Dimension? {
+ val max = max
+ return when {
+ loc.x !in origin.x..max.x -> Dimension.X
+ loc.z !in origin.z..max.z -> Dimension.Z
+ loc.y !in origin.y..max.y -> Dimension.Y
+ else -> null
+ }
+ }
+
}
\ No newline at end of file diff --git a/src/main/kotlin/io/dico/parcels2/util/math/Vec2i.kt b/src/main/kotlin/io/dico/parcels2/util/math/Vec2i.kt index 5945120..3b25526 100644 --- a/src/main/kotlin/io/dico/parcels2/util/math/Vec2i.kt +++ b/src/main/kotlin/io/dico/parcels2/util/math/Vec2i.kt @@ -1,9 +1,9 @@ -package io.dico.parcels2.util.math - -data class Vec2i( - val x: Int, - val z: Int -) { - fun add(ox: Int, oz: Int) = Vec2i(x + ox, z + oz) - fun toChunk() = Vec2i(x shr 4, z shr 4) -} +package io.dico.parcels2.util.math
+
+data class Vec2i(
+ val x: Int,
+ val z: Int
+) {
+ fun add(ox: Int, oz: Int) = Vec2i(x + ox, z + oz)
+ fun toChunk() = Vec2i(x shr 4, z shr 4)
+}
diff --git a/src/main/kotlin/io/dico/parcels2/util/math/Vec3d.kt b/src/main/kotlin/io/dico/parcels2/util/math/Vec3d.kt index 787f46c..2c3512f 100644 --- a/src/main/kotlin/io/dico/parcels2/util/math/Vec3d.kt +++ b/src/main/kotlin/io/dico/parcels2/util/math/Vec3d.kt @@ -11,6 +11,8 @@ data class Vec3d( constructor(loc: Location) : this(loc.x, loc.y, loc.z) operator fun plus(o: Vec3d) = Vec3d(x + o.x, y + o.y, z + o.z) + operator fun plus(o: Vec3i) = Vec3d(x + o.x, y + o.y, z + o.z) + operator fun minus(o: Vec3d) = Vec3d(x - o.x, y - o.y, z - o.z) operator fun minus(o: Vec3i) = Vec3d(x - o.x, y - o.y, z - o.z) infix fun addX(o: Double) = Vec3d(x + o, y, z) infix fun addY(o: Double) = Vec3d(x, y + o, z) @@ -50,4 +52,10 @@ data class Vec3d( Dimension.Y -> addY(value) Dimension.Z -> addZ(value) } + + fun copyInto(loc: Location) { + loc.x = x + loc.y = y + loc.z = z + } }
\ No newline at end of file diff --git a/src/main/kotlin/io/dico/parcels2/util/math/Vec3i.kt b/src/main/kotlin/io/dico/parcels2/util/math/Vec3i.kt index b25764e..b3ba169 100644 --- a/src/main/kotlin/io/dico/parcels2/util/math/Vec3i.kt +++ b/src/main/kotlin/io/dico/parcels2/util/math/Vec3i.kt @@ -15,7 +15,9 @@ data class Vec3i( fun toVec2i() = Vec2i(x, z) operator fun plus(o: Vec3i) = Vec3i(x + o.x, y + o.y, z + o.z) + operator fun plus(o: Vec3d) = Vec3d(x + o.x, y + o.y, z + o.z) operator fun minus(o: Vec3i) = Vec3i(x - o.x, y - o.y, z - o.z) + operator fun minus(o: Vec3d) = Vec3d(x - o.x, y - o.y, z - o.z) infix fun addX(o: Int) = Vec3i(x + o, y, z) infix fun addY(o: Int) = Vec3i(x, y + o, z) infix fun addZ(o: Int) = Vec3i(x, y, z + o) |