From 68a0bb0539bd0fde46bdeeaa4c6a9fe49ec1958a Mon Sep 17 00:00:00 2001 From: Dico Date: Mon, 24 Sep 2018 08:38:25 +0100 Subject: Cleanup of privilege and listeners --- build.gradle.kts | 5 +- old-build.gradle.kts | 206 --------------------- src/main/kotlin/io/dico/parcels2/Parcel.kt | 22 ++- src/main/kotlin/io/dico/parcels2/Privilege.kt | 146 +++++++++++++++ src/main/kotlin/io/dico/parcels2/Privileges.kt | 128 ------------- .../parcels2/defaultimpl/DefaultParcelGenerator.kt | 6 +- .../defaultimpl/GlobalPrivilegesManagerImpl.kt | 10 +- .../io/dico/parcels2/defaultimpl/ParcelImpl.kt | 52 +++--- .../io/dico/parcels2/listener/ParcelListeners.kt | 133 ++++++------- .../io/dico/parcels2/listener/WorldEditListener.kt | 2 +- .../io/dico/parcels2/storage/exposed/ListTables.kt | 4 +- src/main/kotlin/io/dico/parcels2/util/ext/Misc.kt | 4 +- .../kotlin/io/dico/parcels2/util/ext/Player.kt | 10 +- 13 files changed, 278 insertions(+), 450 deletions(-) delete mode 100644 old-build.gradle.kts create mode 100644 src/main/kotlin/io/dico/parcels2/Privilege.kt delete mode 100644 src/main/kotlin/io/dico/parcels2/Privileges.kt diff --git a/build.gradle.kts b/build.gradle.kts index 098f1af..7fb3ede 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,6 @@ @file:Suppress("RemoveRedundantBackticks", "IMPLICIT_CAST_TO_ANY", "UNUSED_VARIABLE") import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar -import org.jetbrains.kotlin.gradle.dsl.Coroutines.ENABLE import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformJvmPlugin import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import java.io.PrintWriter @@ -31,7 +30,7 @@ allprojects { } dependencies { - val spigotVersion = "1.13-R0.1-SNAPSHOT" + val spigotVersion = "1.13.1-R0.1-SNAPSHOT" c.provided("org.bukkit:bukkit:$spigotVersion") { isTransitive = false } c.provided("org.spigotmc:spigot-api:$spigotVersion") { isTransitive = false } @@ -46,7 +45,6 @@ allprojects { project(":dicore3:dicore3-command") { apply() - kotlin.experimental.coroutines = ENABLE dependencies { c.kotlinStd(kotlin("stdlib-jdk8")) @@ -70,6 +68,7 @@ dependencies { // not on sk89q maven repo yet compileClasspath(files("$rootDir/debug/plugins/worldedit-bukkit-7.0.0-beta-01.jar")) + compileClasspath(files("$rootDir/debug/lib/spigot-1.13.1.jar")) compile("org.jetbrains.exposed:exposed:0.10.5") { isTransitive = false } compile("joda-time:joda-time:2.10") diff --git a/old-build.gradle.kts b/old-build.gradle.kts deleted file mode 100644 index fa79c4d..0000000 --- a/old-build.gradle.kts +++ /dev/null @@ -1,206 +0,0 @@ -@file:Suppress("UNUSED_VARIABLE") - -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar -import org.jetbrains.kotlin.gradle.dsl.Coroutines.ENABLE -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformJvmPlugin -import java.io.PrintWriter - -val firstImport = false -val stdout = PrintWriter(File("$rootDir/gradle-output.txt")) - -buildscript { - dependencies { - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.51") - } -} - -group = "io.dico" -version = "0.1" - -inline fun > Project.apply() = - (this as PluginAware).apply() - -allprojects { - apply() - - repositories { - mavenCentral() - maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots") - maven("https://hub.spigotmc.org/nexus/content/repositories/sonatype-nexus-snapshots") - } - dependencies { - val spigotVersion = "1.13-R0.1-SNAPSHOT" - compile("org.bukkit:bukkit:$spigotVersion") { isTransitive = false } - compile("org.spigotmc:spigot-api:$spigotVersion") { isTransitive = false } - - compile("net.sf.trove4j:trove4j:3.0.3") - testCompile("junit:junit:4.12") - } -} - -project(":dicore3:dicore3-command") { - apply() - - kotlin.experimental.coroutines = ENABLE - - dependencies { - compile("org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.4") - compile(kotlin("reflect", version = "1.2.50")) - compile(kotlin("stdlib-jdk8", version = "1.2.51")) - compile(project(":dicore3:dicore3-core")) - compile("com.thoughtworks.paranamer:paranamer:2.8") - } -} - - -plugins { - kotlin("jvm") version "1.2.51" - id("com.github.johnrengelman.plugin-shadow") version "2.0.3" -} - -kotlin.experimental.coroutines = ENABLE - -repositories { - maven("https://dl.bintray.com/kotlin/exposed") -} - -dependencies { - compile(project(":dicore3:dicore3-core")) - compile(project(":dicore3:dicore3-command")) - compile(kotlin("stdlib-jdk8")) - - compile("org.jetbrains.exposed:exposed:0.10.3") - compile("org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.4") - compile("com.zaxxer:HikariCP:3.2.0") - compile("com.h2database:h2:1.4.197") - - val jacksonVersion = "2.9.6" - compile("com.fasterxml.jackson.core:jackson-core:$jacksonVersion") - compile("com.fasterxml.jackson.core:jackson-databind:$jacksonVersion") - compile("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonVersion") - compile("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:$jacksonVersion") - //compile("org.yaml:snakeyaml:1.19") - - compile("org.slf4j:slf4j-api:1.7.25") - compile("ch.qos.logback:logback-classic:1.2.3") -} - -tasks { - val serverDir = "$rootDir/debug" - val jar by getting(Jar::class) - val kotlinStdlibJar by creating(Jar::class) { - destinationDir = file("$serverDir/lib") - archiveName = "kotlin-stdlib.jar" - packageDependencies("kotlin-stdlib-jdk8") - } - - val debugEnvironment by creating(Exec::class) { - - } - - val releaseJar by creating(ShadowJar::class) { - destinationDir = file("$serverDir/plugins") - baseName = "parcels2-release" - - with(jar) - - packageArtifacts( - "jackson-core", - "jackson-databind", - "jackson-module-kotlin", - "jackson-annotations", - "jackson-dataformat-yaml", - "snakeyaml", - - "slf4j-api", - "logback-core", - "logback-classic", - - //"h2", - "HikariCP", - "kotlinx-coroutines-core", - "kotlinx-coroutines-core-common", - "atomicfu-common", - "exposed", - - "dicore3-core", - "dicore3-command", - "paranamer", - - "trove4j", - "joda-time", - - "annotations", - "kotlin-stdlib-common", - "kotlin-stdlib", - "kotlin-stdlib-jdk7", - "kotlin-stdlib-jdk8", - "kotlin-reflect" - ) - - relocate("org.yaml.snakeyaml", "io.dico.parcels2.util.snakeyaml") - - manifest.attributes["Class-Path"] = "lib/kotlin-stdlib.jar" - dependsOn(kotlinStdlibJar) - } - -} - -allprojects { - tasks.filter { it is Jar }.forEach { it.group = "artifacts" } -} - -stdout.flush() -stdout.close() - -fun Jar.packageDependencies(vararg names: String) { - if (!firstImport) { - from(*project.configurations.compile.resolvedConfiguration.firstLevelModuleDependencies - .filter { it.moduleName in names } - .flatMap { it.allModuleArtifacts } - .map { it.file } - .map(::zipTree) - .toTypedArray() - ) - } -} - -fun Jar.packageDependency(name: String, configure: ModuleDependency.() -> Unit) { - if (!firstImport) { - val configuration = project.configurations.compile.copyRecursive() - - configuration.dependencies.removeIf { - if (it is ModuleDependency && it.name == name) { - it.configure() - false - } else true - } - - from(*configuration.resolvedConfiguration.resolvedArtifacts - .map { it.file } - .map(::zipTree) - .toTypedArray()) - } -} - -@Suppress("IMPLICIT_CAST_TO_ANY") -fun Jar.packageArtifacts(vararg names: String) { - if (!firstImport) { - from(*project.configurations.compile.resolvedConfiguration.firstLevelModuleDependencies - .flatMap { dep -> dep.allModuleArtifacts.map { dep to it } } - .filter { pair -> - val (dep, art) = pair - val id = art.moduleVersion.id - (id.name in names).also { - val artName = art.moduleVersion.id.let {"${it.group}:${it.name}:${it.version}"} - val depName = dep.let { "${it.moduleGroup}:${it.moduleName}:${it.moduleVersion}" } - val name = "$artName \n from $depName" - stdout.println("${if (it) "Including" else "Not including"} artifact $name") - } - } - .map { pair -> pair.second.file } - .map { if (it.isDirectory()) it else zipTree(it) } - .toTypedArray()) - } -} diff --git a/src/main/kotlin/io/dico/parcels2/Parcel.kt b/src/main/kotlin/io/dico/parcels2/Parcel.kt index 6ec6121..75f963f 100644 --- a/src/main/kotlin/io/dico/parcels2/Parcel.kt +++ b/src/main/kotlin/io/dico/parcels2/Parcel.kt @@ -1,10 +1,7 @@ package io.dico.parcels2 import io.dico.parcels2.util.Vec2i -import io.dico.parcels2.util.ext.hasPermBuildAnywhere import org.bukkit.Location -import org.bukkit.OfflinePlayer -import org.bukkit.entity.Player import org.joda.time.DateTime import java.util.UUID @@ -16,7 +13,7 @@ import java.util.UUID * However, this implementation is intentionally not thread-safe. * Therefore, database query callbacks should schedule their updates using the bukkit scheduler. */ -interface Parcel : ParcelData { +interface Parcel : ParcelData, Privileges { val id: ParcelId val world: ParcelWorld val pos: Vec2i @@ -25,6 +22,10 @@ interface Parcel : ParcelData { val data: ParcelData val infoString: String val hasBlockVisitors: Boolean + val globalPrivileges: GlobalPrivileges? + + override val keyOfOwner: PlayerProfile.Real? + get() = owner as? PlayerProfile.Real fun copyDataIgnoringDatabase(data: ParcelData) @@ -37,13 +38,13 @@ interface Parcel : ParcelData { val homeLocation: Location get() = world.blockManager.getHomeLocation(id) } -interface ParcelData : Privileges { +interface ParcelData : PrivilegesMinimal { var owner: PlayerProfile? val lastClaimTime: DateTime? var ownerSignOutdated: Boolean var interactableConfig: InteractableConfiguration - fun canBuild(player: OfflinePlayer, checkAdmin: Boolean = true, checkGlobal: Boolean = true): Boolean + //fun canBuild(player: OfflinePlayer, checkAdmin: Boolean = true, checkGlobal: Boolean = true): Boolean fun isOwner(uuid: UUID): Boolean { return owner?.uuid == uuid @@ -59,10 +60,11 @@ class ParcelDataHolder(addedMap: MutablePrivilegeMap = mutableMapOf()) override var owner: PlayerProfile? = null override var lastClaimTime: DateTime? = null override var ownerSignOutdated = false - override fun canBuild(player: OfflinePlayer, checkAdmin: Boolean, checkGlobal: Boolean) = - hasPrivilegeToBuild(player) - || owner.let { it != null && it.matches(player, allowNameMatch = false) } - || (checkAdmin && player is Player && player.hasPermBuildAnywhere) + + //override fun canBuild(player: OfflinePlayer, checkAdmin: Boolean, checkGlobal: Boolean) = + // hasPrivilegeToBuild(player) + // || owner.let { it != null && it.matches(player, allowNameMatch = false) } + // || (checkAdmin && player is Player && player.hasPermBuildAnywhere) override var interactableConfig: InteractableConfiguration = BitmaskInteractableConfiguration() } diff --git a/src/main/kotlin/io/dico/parcels2/Privilege.kt b/src/main/kotlin/io/dico/parcels2/Privilege.kt new file mode 100644 index 0000000..ab9db33 --- /dev/null +++ b/src/main/kotlin/io/dico/parcels2/Privilege.kt @@ -0,0 +1,146 @@ +package io.dico.parcels2 + +import io.dico.parcels2.Privilege.* +import io.dico.parcels2.PrivilegeChangeResult.* +import io.dico.parcels2.util.ext.PERM_ADMIN_MANAGE +import io.dico.parcels2.util.ext.PERM_BAN_BYPASS +import io.dico.parcels2.util.ext.PERM_BUILD_ANYWHERE +import org.bukkit.OfflinePlayer +import org.bukkit.entity.Player + +enum class Privilege( + val number: Int, + val transient: Boolean = false +) { + BANNED(1), + DEFAULT(2), + CAN_BUILD(3), + CAN_MANAGE(4), + + OWNER(-1, transient = true), + ADMIN(-1, transient = true); + + fun isDistanceGrEq(other: Privilege): Boolean = + when { // used for example when disallowBuild is called and CAN_MANAGE is the privilege. + other > DEFAULT -> this >= other + other == DEFAULT -> this == other + else -> this <= other + } + + fun isChangeInDirection(positiveDirection: Boolean, update: Privilege): Boolean = + if (positiveDirection) update > this + else update < this + + fun requireNonTransient(): Privilege { + if (transient) { + throw IllegalArgumentException("Transient privilege $this is invalid") + } + return this + } + + /* + fun canEnter() = this >= BANNED + fun canBuild() = this >= CAN_BUILD + fun canManage() = this >= CAN_MANAGE + */ + + companion object { + fun getByNumber(id: Int) = + when (id) { + 1 -> BANNED + 2 -> DEFAULT + 3 -> CAN_BUILD + 4 -> CAN_MANAGE + else -> null + } + } +} + +typealias PrivilegeKey = PlayerProfile.Real +typealias MutablePrivilegeMap = MutableMap +typealias PrivilegeMap = Map + +@Suppress("FunctionName") +fun MutablePrivilegeMap(): MutablePrivilegeMap = hashMapOf() + +interface PrivilegesMinimal { + val map: PrivilegeMap + var privilegeOfStar: Privilege + + fun getStoredPrivilege(key: PrivilegeKey): Privilege + fun setStoredPrivilege(key: PrivilegeKey, privilege: Privilege): Boolean +} + +interface Privileges : PrivilegesMinimal { + val keyOfOwner: PlayerProfile.Real? + + fun privilege(player: OfflinePlayer, adminPerm: String): Privilege = + if (player is Player && player.hasPermission(adminPerm)) ADMIN + else { + val key = player.privilegeKey + if (key == keyOfOwner) OWNER + else getStoredPrivilege(key) + } + + fun changePrivilege(key: PrivilegeKey, positive: Boolean, update: Privilege): PrivilegeChangeResult = + if (key != keyOfOwner) FAIL_OWNER + else if (getStoredPrivilege(key).isChangeInDirection(positive, update) + && setStoredPrivilege(key, update) + ) SUCCESS + else FAIL + + fun canManage(player: OfflinePlayer) = privilege(player, PERM_ADMIN_MANAGE) >= CAN_MANAGE + fun allowManage(player: OfflinePlayer) = changePrivilege(player.privilegeKey, true, CAN_MANAGE) + fun disallowManage(player: OfflinePlayer) = changePrivilege(player.privilegeKey, false, CAN_BUILD) + + fun canBuild(player: OfflinePlayer) = privilege(player, PERM_BUILD_ANYWHERE) >= CAN_BUILD + fun allowBuild(player: OfflinePlayer) = changePrivilege(player.privilegeKey, true, CAN_BUILD) + fun disallowBuild(player: OfflinePlayer) = changePrivilege(player.privilegeKey, false, DEFAULT) + + fun canEnter(player: OfflinePlayer) = privilege(player, PERM_BAN_BYPASS) >= DEFAULT + fun ban(player: OfflinePlayer) = changePrivilege(player.privilegeKey, false, BANNED) + fun unban(player: OfflinePlayer) = changePrivilege(player.privilegeKey, true, DEFAULT) + + /** + * same as [canBuild] but doesn't perform a permission check for admin perms + */ + fun canBuildFast(player: OfflinePlayer) = player.privilegeKey.let { if (it == keyOfOwner) OWNER else getStoredPrivilege(it)} >= CAN_BUILD +} + +enum class PrivilegeChangeResult { + SUCCESS, FAIL, FAIL_OWNER +} + +val OfflinePlayer.privilegeKey: PrivilegeKey + inline get() = PlayerProfile.nameless(this) + +open class PrivilegesHolder(override var map: MutablePrivilegeMap = MutablePrivilegeMap()) : PrivilegesMinimal { + override var privilegeOfStar: Privilege = DEFAULT + set(value) = run { field = value.requireNonTransient() } + + override fun getStoredPrivilege(key: PrivilegeKey) = + if (key.isStar) privilegeOfStar + else map.getOrDefault(key, privilegeOfStar) + + override fun setStoredPrivilege(key: PrivilegeKey, privilege: Privilege): Boolean { + privilege.requireNonTransient() + + if (key.isStar) { + if (privilegeOfStar == privilege) return false + privilegeOfStar = privilege + return true + } + + return if (privilege == DEFAULT) map.remove(key) != null + else map.put(key, privilege) != privilege + } +} + +interface GlobalPrivileges : Privileges { + override val keyOfOwner: PlayerProfile.Real +} + +interface GlobalPrivilegesManager { + operator fun get(owner: PlayerProfile.Real): GlobalPrivileges + operator fun get(owner: OfflinePlayer): GlobalPrivileges = get(owner.privilegeKey) +} diff --git a/src/main/kotlin/io/dico/parcels2/Privileges.kt b/src/main/kotlin/io/dico/parcels2/Privileges.kt deleted file mode 100644 index 1aad3f6..0000000 --- a/src/main/kotlin/io/dico/parcels2/Privileges.kt +++ /dev/null @@ -1,128 +0,0 @@ -package io.dico.parcels2 - -import io.dico.parcels2.Privilege.* -import org.bukkit.OfflinePlayer - -enum class Privilege( - val number: Int, - val transient: Boolean = false -) { - BANNED(1), - DEFAULT(2), - CAN_BUILD(3), - CAN_MANAGE(4), - - OWNER(-1, transient = true), - ADMIN(-1, transient = true); - - fun isDistanceGrEq(other: Privilege): Boolean = - when { // used for example when disallowBuild is called and CAN_MANAGE is the privilege. - other > DEFAULT -> this >= other - other == DEFAULT -> this == other - else -> this <= other - } - - fun requireNonTransient(): Privilege { - if (transient) { - throw IllegalArgumentException("Transient privilege $this is invalid") - } - return this - } - - /* - fun canEnter() = this >= BANNED - fun canBuild() = this >= CAN_BUILD - fun canManage() = this >= CAN_MANAGE - */ - - companion object { - fun getByNumber(id: Int) = - when (id) { - 1 -> BANNED - 2 -> DEFAULT - 3 -> CAN_BUILD - 4 -> CAN_MANAGE - else -> null - } - } -} - -typealias PrivilegeKey = PlayerProfile.Real -typealias MutablePrivilegeMap = MutableMap -typealias PrivilegeMap = Map - -@Suppress("FunctionName") -fun MutablePrivilegeMap(): MutablePrivilegeMap = hashMapOf() - -/** - * Privileges object never returns a transient privilege. - */ -interface Privileges { - val map: PrivilegeMap - var privilegeOfStar: Privilege - - fun privilege(key: PrivilegeKey): Privilege - fun privilege(player: OfflinePlayer) = privilege(player.privilegeKey) - fun setPrivilege(key: PrivilegeKey, privilege: Privilege): Boolean - fun setPrivilege(player: OfflinePlayer, privilege: Privilege) = setPrivilege(player.privilegeKey, privilege) - fun changePrivilege(key: PrivilegeKey, expect: Privilege, update: Privilege): Boolean = - privilege(key).isDistanceGrEq(expect) && setPrivilege(key, update) - - fun hasPrivilegeToManage(key: PrivilegeKey) = privilege(key) >= CAN_MANAGE - fun allowManage(key: PrivilegeKey) = setPrivilege(key, CAN_MANAGE) - fun disallowManage(key: PrivilegeKey) = changePrivilege(key, CAN_MANAGE, CAN_BUILD) - - fun hasPrivilegeToBuild(key: PrivilegeKey) = privilege(key) >= CAN_BUILD - fun allowBuild(key: PrivilegeKey) = setPrivilege(key, CAN_BUILD) - fun disallowBuild(key: PrivilegeKey) = changePrivilege(key, CAN_BUILD, DEFAULT) - - fun isBanned(key: PrivilegeKey) = privilege(key) == BANNED - fun ban(key: PrivilegeKey) = setPrivilege(key, BANNED) - fun unban(key: PrivilegeKey) = changePrivilege(key, BANNED, DEFAULT) - - /* OfflinePlayer overloads */ - - fun hasPrivilegeToManage(player: OfflinePlayer) = hasPrivilegeToManage(player.privilegeKey) - fun allowManage(player: OfflinePlayer) = allowManage(player.privilegeKey) - fun disallowManage(player: OfflinePlayer) = disallowManage(player.privilegeKey) - - fun hasPrivilegeToBuild(player: OfflinePlayer) = hasPrivilegeToBuild(player.privilegeKey) - fun allowBuild(player: OfflinePlayer) = allowBuild(player.privilegeKey) - fun disallowBuild(player: OfflinePlayer) = disallowBuild(player.privilegeKey) - - fun isBanned(player: OfflinePlayer) = isBanned(player.privilegeKey) - fun ban(player: OfflinePlayer) = ban(player.privilegeKey) - fun unban(player: OfflinePlayer) = unban(player.privilegeKey) -} - -val OfflinePlayer.privilegeKey: PrivilegeKey - inline get() = PlayerProfile.nameless(this) - -open class PrivilegesHolder(override var map: MutablePrivilegeMap = MutablePrivilegeMap()) : Privileges { - override var privilegeOfStar: Privilege = DEFAULT - set(value) = run { field = value.requireNonTransient() } - - override fun privilege(key: PrivilegeKey): Privilege = map.getOrDefault(key, privilegeOfStar) - - override fun setPrivilege(key: PrivilegeKey, privilege: Privilege): Boolean { - privilege.requireNonTransient() - - if (key.isStar) { - if (privilegeOfStar == privilege) return false - privilegeOfStar = privilege - return true - } - - return if (privilege == DEFAULT) map.remove(key) != null - else map.put(key, privilege) != privilege - } -} - -interface GlobalPrivileges : Privileges { - val owner: PlayerProfile -} - -interface GlobalPrivilegesManager { - operator fun get(owner: PlayerProfile): GlobalPrivileges - operator fun get(owner: OfflinePlayer): GlobalPrivileges = get(owner.privilegeKey) -} diff --git a/src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelGenerator.kt b/src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelGenerator.kt index 08d5f2f..84324f7 100644 --- a/src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelGenerator.kt +++ b/src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelGenerator.kt @@ -20,9 +20,8 @@ import org.bukkit.block.Biome import org.bukkit.block.BlockFace import org.bukkit.block.Skull import org.bukkit.block.data.BlockData -import org.bukkit.block.data.type.Sign import org.bukkit.block.data.type.Slab -import java.lang.IllegalArgumentException +import org.bukkit.block.data.type.WallSign import java.util.Random private val airType = Bukkit.createBlockData(Material.AIR) @@ -201,8 +200,7 @@ class DefaultParcelGenerator( o.wallType wallBlock.blockData = wallBlockType - - signBlock.blockData = (Bukkit.createBlockData(Material.WALL_SIGN) as Sign).apply { rotation = BlockFace.NORTH } + signBlock.blockData = (Bukkit.createBlockData(Material.WALL_SIGN) as WallSign).apply { facing = BlockFace.NORTH } val sign = signBlock.state as org.bukkit.block.Sign sign.setLine(0, "${parcel.x},${parcel.z}") diff --git a/src/main/kotlin/io/dico/parcels2/defaultimpl/GlobalPrivilegesManagerImpl.kt b/src/main/kotlin/io/dico/parcels2/defaultimpl/GlobalPrivilegesManagerImpl.kt index de9476b..5f8c4be 100644 --- a/src/main/kotlin/io/dico/parcels2/defaultimpl/GlobalPrivilegesManagerImpl.kt +++ b/src/main/kotlin/io/dico/parcels2/defaultimpl/GlobalPrivilegesManagerImpl.kt @@ -9,25 +9,25 @@ import java.util.Collections class GlobalPrivilegesManagerImpl(val plugin: ParcelsPlugin) : GlobalPrivilegesManager { private val map = mutableMapOf() - override fun get(owner: PlayerProfile): GlobalPrivileges { + override fun get(owner: PlayerProfile.Real): GlobalPrivileges { return map[owner] ?: GlobalPrivilegesImpl(owner).also { map[owner] = it } } private inner class GlobalPrivilegesImpl( - override val owner: PlayerProfile, + override val keyOfOwner: PlayerProfile.Real, data: MutablePrivilegeMap = emptyData ) : PrivilegesHolder(data), GlobalPrivileges { private inline var data get() = map; set(value) = run { map = value } private inline val isEmpty get() = data === emptyData - override fun setPrivilege(key: PrivilegeKey, privilege: Privilege): Boolean { + override fun setStoredPrivilege(key: PrivilegeKey, privilege: Privilege): Boolean { if (isEmpty) { if (privilege == Privilege.DEFAULT) return false data = mutableMapOf() } - return super.setPrivilege(key, privilege).alsoIfTrue { - plugin.storage.setGlobalPrivilege(owner, key, privilege) + return super.setStoredPrivilege(key, privilege).alsoIfTrue { + plugin.storage.setGlobalPrivilege(keyOfOwner, key, privilege) } } } diff --git a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt index f592724..d8dd3a8 100644 --- a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt +++ b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt @@ -2,6 +2,7 @@ package io.dico.parcels2.defaultimpl import io.dico.dicore.Formatting import io.dico.parcels2.* +import io.dico.parcels2.Privilege.* import io.dico.parcels2.util.Vec2i import io.dico.parcels2.util.ext.alsoIfTrue import org.bukkit.Material @@ -36,19 +37,26 @@ class ParcelImpl( } override val map: PrivilegeMap get() = data.map - override fun privilege(key: PrivilegeKey) = data.privilege(key) - override fun isBanned(key: PrivilegeKey) = data.isBanned(key) - override fun hasPrivilegeToBuild(key: PrivilegeKey) = data.hasPrivilegeToBuild(key) - override fun canBuild(player: OfflinePlayer, checkAdmin: Boolean, checkGlobal: Boolean): Boolean { - return (data.canBuild(player, checkAdmin, false)) - || checkGlobal && world.globalPrivileges[owner ?: return false].hasPrivilegeToBuild(player) + override fun getStoredPrivilege(key: PrivilegeKey) = data.getStoredPrivilege(key) + + override fun setStoredPrivilege(key: PrivilegeKey, privilege: Privilege): Boolean { + return data.setStoredPrivilege(key, privilege).alsoIfTrue { + world.storage.setLocalPrivilege(this, key, privilege) + } + } + + override fun privilege(player: OfflinePlayer, adminPerm: String): Privilege { + val privilege = super.privilege(player, adminPerm) + return if (privilege == DEFAULT) globalPrivileges?.privilege(player, adminPerm) ?: DEFAULT + else privilege } override var privilegeOfStar: Privilege - get() = data.privilegeOfStar - set(value) = run { setPrivilege(PlayerProfile.Star, value) } + get() = data.privilegeOfStar.let { if (it == DEFAULT) globalPrivileges?.privilegeOfStar ?: DEFAULT else it } + set(value) = run { setStoredPrivilege(PlayerProfile.Star, value) } - val globalAddedMap: PrivilegeMap? get() = owner?.let { world.globalPrivileges[it].map } + override val globalPrivileges: GlobalPrivileges? + get() = keyOfOwner?.let { world.globalPrivileges[it] } override val lastClaimTime: DateTime? get() = data.lastClaimTime @@ -71,12 +79,6 @@ class ParcelImpl( } } - override fun setPrivilege(key: PrivilegeKey, privilege: Privilege): Boolean { - return data.setPrivilege(key, privilege).alsoIfTrue { - world.storage.setLocalPrivilege(this, key, privilege) - } - } - private fun updateInteractableConfigStorage() { world.storage.setParcelOptionsInteractConfig(this, data.interactableConfig) } @@ -188,12 +190,14 @@ private object ParcelInfoStringComputer { val (key, priv) = pair // prefix. Maybe T should be M for mod or something. T means they have CAN_MANAGE privilege. - append(when { - global && priv == Privilege.CAN_MANAGE -> "(GT)" - global -> "(G)" - priv == Privilege.CAN_MANAGE -> "(T)" - else -> "" - }) + append( + when { + global && priv == CAN_MANAGE -> "(GT)" + global -> "(G)" + priv == CAN_MANAGE -> "(T)" + else -> "" + } + ) append(key.notNullName) } @@ -219,11 +223,11 @@ private object ParcelInfoStringComputer { append('\n') - val global = owner?.let { parcel.world.globalPrivileges[owner].map } ?: emptyMap() val local = parcel.map - appendAddedList(local, global, Privilege.CAN_BUILD, "Allowed") // includes CAN_MANAGE privilege + val global = parcel.globalPrivileges?.map ?: emptyMap() + appendAddedList(local, global, CAN_BUILD, "Allowed") // includes CAN_MANAGE privilege append('\n') - appendAddedList(local, global, Privilege.BANNED, "Banned") + appendAddedList(local, global, BANNED, "Banned") if (!parcel.interactableConfig.isDefault()) { val interactables = parcel.interactableConfig.interactableClasses diff --git a/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt b/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt index c8e64d3..9805f40 100644 --- a/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt +++ b/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt @@ -1,6 +1,7 @@ package io.dico.parcels2.listener import gnu.trove.TLongCollection +import gnu.trove.set.hash.TLongHashSet import io.dico.dicore.ListenerMarker import io.dico.dicore.RegistratorListener import io.dico.parcels2.* @@ -30,21 +31,23 @@ import org.bukkit.event.world.StructureGrowEvent import org.bukkit.inventory.InventoryHolder import java.util.EnumSet -@Suppress("NOTHING_TO_INLINE") class ParcelListeners( val parcelProvider: ParcelProvider, val entityTracker: ParcelEntityTracker, val storage: Storage ) { - private inline fun Parcel?.canBuildN(user: Player) = isPresentAnd { canBuild(user) } || user.hasPermBuildAnywhere + private fun canBuildOnArea(user: Player, area: Parcel?) = + if (area == null) user.hasPermBuildAnywhere else area.canBuild(user) + + private fun canInteract(user: Player, area: Parcel?, interactClass: String) = + canBuildOnArea(user, area) || (area != null && area.interactableConfig(interactClass)) /** * 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 + * the parcel is nullable, and often named area because that means path. + * returns null if not in a registered parcel world - should always return in that case to not affect other worlds. */ - private fun getWoAndPPa(block: Block): Pair? { + private fun getWorldAndArea(block: Block): Pair? { val world = parcelProvider.getWorld(block.world) ?: return null return world to world.getParcelAt(block) } @@ -57,7 +60,7 @@ class ParcelListeners( val user = event.player if (user.hasPermBanBypass) return@l val parcel = parcelProvider.getParcelAt(event.to) ?: return@l - if (parcel.isBanned(user.privilegeKey)) { + if (!parcel.canEnter(user)) { parcelProvider.getParcelAt(event.from)?.also { user.teleport(it.homeLocation) user.sendParcelMessage(nopermit = true, message = "You are banned from this parcel") @@ -71,12 +74,12 @@ class ParcelListeners( */ @field:ListenerMarker(priority = NORMAL) val onBlockBreakEvent = RegistratorListener l@{ event -> - val (wo, ppa) = getWoAndPPa(event.block) ?: return@l - if (!event.player.hasPermBuildAnywhere && ppa.isNullOr { !canBuild(event.player) }) { + val (world, area) = getWorldAndArea(event.block) ?: return@l + if (!canBuildOnArea(event.player, area)) { event.isCancelled = true; return@l } - if (!wo.options.dropEntityItems) { + if (!world.options.dropEntityItems) { val state = event.block.state if (state is InventoryHolder) { state.inventory.clear() @@ -90,8 +93,8 @@ class ParcelListeners( */ @field:ListenerMarker(priority = NORMAL) val onBlockPlaceEvent = RegistratorListener l@{ event -> - val (wo, ppa) = getWoAndPPa(event.block) ?: return@l - if (!event.player.hasPermBuildAnywhere && ppa.isNullOr { !canBuild(event.player) }) { + val (_, area) = getWorldAndArea(event.block) ?: return@l + if (!canBuildOnArea(event.player, area)) { event.isCancelled = true } } @@ -120,7 +123,7 @@ class ParcelListeners( private fun checkPistonMovement(event: BlockPistonEvent, blocks: List) { val world = parcelProvider.getWorld(event.block.world) ?: return val direction = event.direction - val columns = gnu.trove.set.hash.TLongHashSet(blocks.size * 2) + val columns = TLongHashSet(blocks.size * 2) blocks.forEach { columns.add(Column(it.x, it.z)) @@ -128,8 +131,8 @@ class ParcelListeners( } columns.troveForEach { - val ppa = world.getParcelAt(it.columnX, it.columnZ) - if (ppa.isNullOr { hasBlockVisitors }) { + val area = world.getParcelAt(it.columnX, it.columnZ) + if (area == null || area.hasBlockVisitors) { event.isCancelled = true return } @@ -141,10 +144,10 @@ class ParcelListeners( */ @field:ListenerMarker(priority = NORMAL) val onExplosionPrimeEvent = RegistratorListener l@{ event -> - val (wo, ppa) = getWoAndPPa(event.entity.location.block) ?: return@l - if (ppa?.hasBlockVisitors == true) { + val (world, area) = getWorldAndArea(event.entity.location.block) ?: return@l + if (area != null && area.hasBlockVisitors) { event.radius = 0F; event.isCancelled = true - } else if (wo.options.disableExplosions) { + } else if (world.options.disableExplosions) { event.radius = 0F } } @@ -156,18 +159,18 @@ class ParcelListeners( val onEntityExplodeEvent = RegistratorListener l@{ event -> entityTracker.untrack(event.entity) val world = parcelProvider.getWorld(event.entity.world) ?: return@l - if (world.options.disableExplosions || world.getParcelAt(event.entity).isPresentAnd { hasBlockVisitors }) { + if (world.options.disableExplosions || world.getParcelAt(event.entity).let { it != null && it.hasBlockVisitors }) { event.isCancelled = true } } /* - * Prevents creepers and tnt minecarts from exploding if explosions are disabled + * Prevents liquids from flowing out of plots */ @field:ListenerMarker(priority = NORMAL) val onBlockFromToEvent = RegistratorListener l@{ event -> - val (wo, ppa) = getWoAndPPa(event.toBlock) ?: return@l - if (ppa.isNullOr { hasBlockVisitors }) event.isCancelled = true + val (_, area) = getWorldAndArea(event.toBlock) ?: return@l + if (area == null || area.hasBlockVisitors) event.isCancelled = true } private val bedTypes = EnumSet.copyOf(getMaterialsWithWoolColorPrefix("BED").toList()) @@ -185,7 +188,7 @@ class ParcelListeners( val clickedBlock = event.clickedBlock val parcel = clickedBlock?.let { world.getParcelAt(it) } - if (!user.hasPermBuildAnywhere && parcel.isPresentAnd { isBanned(user.privilegeKey) }) { + if (!user.hasPermBuildAnywhere && parcel != null && !parcel.canEnter(user)) { user.sendParcelMessage(nopermit = true, message = "You cannot interact with parcels you're banned from") event.isCancelled = true; return@l } @@ -193,7 +196,8 @@ class ParcelListeners( when (event.action) { Action.RIGHT_CLICK_BLOCK -> run { val type = clickedBlock.type - val interactable = parcel.effectiveInteractableConfig.isInteractable(type) || parcel.isPresentAnd { canBuild(user) } + val interactable = Interactables.listedMaterials.containsKey(type) + && (parcel.effectiveInteractableConfig.isInteractable(type) || (parcel != null && parcel.canBuild(user))) if (!interactable) { val interactableClassName = Interactables[type]!!.name user.sendParcelMessage(nopermit = true, message = "You cannot interact with $interactableClassName in this parcel") @@ -206,19 +210,24 @@ class ParcelListeners( val head = if (bed == Bed.Part.FOOT) clickedBlock.getRelative(bed.facing) else clickedBlock when (head.biome) { Biome.NETHER, Biome.THE_END -> { - if (world.options.disableExplosions || parcel.isNullOr { !canBuild(user) }) { + if (world.options.disableExplosions) { user.sendParcelMessage(nopermit = true, message = "You cannot use this bed because it would explode") event.isCancelled = true; return@l } } } + + if (!canBuildOnArea(user, parcel)) { + user.sendParcelMessage(nopermit = true, message = "You may not sleep here") + event.isCancelled = true; return@l + } } onPlayerInteractEvent_RightClick(event, world, parcel) } Action.RIGHT_CLICK_AIR -> onPlayerInteractEvent_RightClick(event, world, parcel) - Action.PHYSICAL -> if (!user.hasPermBuildAnywhere && !parcel.isPresentAnd { canBuild(user) || interactableConfig("pressure_plates") }) { + Action.PHYSICAL -> if (!canBuildOnArea(user, parcel) && !(parcel != null && parcel.interactableConfig("pressure_plates"))) { user.sendParcelMessage(nopermit = true, message = "You cannot use inputs in this parcel") event.isCancelled = true; return@l } @@ -234,7 +243,7 @@ class ParcelListeners( event.isCancelled = true; return } - if (!parcel.canBuildN(event.player)) { + if (!canBuildOnArea(event.player, parcel)) { when (item) { LAVA_BUCKET, WATER_BUCKET, BUCKET, FLINT_AND_STEEL -> event.isCancelled = true } @@ -249,8 +258,8 @@ class ParcelListeners( @Suppress("NON_EXHAUSTIVE_WHEN") @field:ListenerMarker(priority = NORMAL) val onPlayerInteractEntityEvent = RegistratorListener l@{ event -> - val (wo, ppa) = getWoAndPPa(event.rightClicked.location.block) ?: return@l - if (ppa.canBuildN(event.player)) return@l + val (_, area) = getWorldAndArea(event.rightClicked.location.block) ?: return@l + if (canBuildOnArea(event.player, area)) return@l when (event.rightClicked.type) { EntityType.BOAT, EntityType.MINECART, @@ -281,14 +290,14 @@ class ParcelListeners( */ @field:ListenerMarker(priority = NORMAL) val onEntityChangeBlockEvent = RegistratorListener l@{ event -> - val (wo, ppa) = getWoAndPPa(event.block) ?: return@l - if (event.entity.type == EntityType.ENDERMAN || ppa.isNullOr { hasBlockVisitors }) { + val (_, area) = getWorldAndArea(event.block) ?: return@l + if (event.entity.type == EntityType.ENDERMAN || area == null || area.hasBlockVisitors) { event.isCancelled = true; return@l } if (event.entity.type == EntityType.FALLING_BLOCK) { // a sand block started falling. Track it and delete it if it gets out of this parcel. - entityTracker.track(event.entity, ppa) + entityTracker.track(event.entity, area) } } @@ -306,8 +315,8 @@ class ParcelListeners( */ @field:ListenerMarker(priority = NORMAL) val onPlayerDropItemEvent = RegistratorListener l@{ event -> - val (wo, ppa) = getWoAndPPa(event.itemDrop.location.block) ?: return@l - if (!ppa.canBuildN(event.player) && !ppa.isPresentAnd { interactableConfig("containers") }) event.isCancelled = true + val (_, area) = getWorldAndArea(event.itemDrop.location.block) ?: return@l + if (!canInteract(event.player, area, "containers")) event.isCancelled = true } /* @@ -316,8 +325,8 @@ class ParcelListeners( @field:ListenerMarker(priority = NORMAL) val onEntityPickupItemEvent = RegistratorListener l@{ event -> val user = event.entity as? Player ?: return@l - val (wo, ppa) = getWoAndPPa(event.item.location.block) ?: return@l - if (!ppa.canBuildN(user)) event.isCancelled = true + val (_, area) = getWorldAndArea(event.item.location.block) ?: return@l + if (!canInteract(user, area, "containers")) event.isCancelled = true } /* @@ -327,8 +336,8 @@ class ParcelListeners( val onInventoryClickEvent = RegistratorListener l@{ event -> val user = event.whoClicked as? Player ?: return@l if ((event.inventory ?: return@l).holder === user) return@l // inventory null: hotbar - val (wo, ppa) = getWoAndPPa(event.inventory.location.block) ?: return@l - if (ppa.isNullOr { !canBuild(user) && !interactableConfig("containers") }) { + val (_, area) = getWorldAndArea(event.inventory.location.block) ?: return@l + if (!canInteract(user, area, "containers")) { event.isCancelled = true } } @@ -358,10 +367,10 @@ class ParcelListeners( @ListenerMarker(priority = NORMAL) val onBlockFormEvent = RegistratorListener l@{ event -> val block = event.block - val (wo, ppa) = getWoAndPPa(block) ?: return@l + val (world, area) = getWorldAndArea(block) ?: return@l // prevent any generation whatsoever on paths - if (ppa == null) { + if (area == null) { event.isCancelled = true; return@l } @@ -371,10 +380,10 @@ class ParcelListeners( val cancel: Boolean = when (event.newState.type) { // prevent ice generation from Frost Walkers enchantment - FROSTED_ICE -> player != null && !ppa.canBuild(player) + FROSTED_ICE -> player != null && !area.canBuild(player) // prevent snow generation from weather - SNOW -> !hasEntity && wo.options.preventWeatherBlockChanges + SNOW -> !hasEntity && world.options.preventWeatherBlockChanges else -> false } @@ -392,7 +401,7 @@ class ParcelListeners( val world = parcelProvider.getWorld(event.entity.world) ?: return@l if (event.entity is Creature && world.options.blockMobSpawning) { event.isCancelled = true - } else if (world.getParcelAt(event.entity).isPresentAnd { hasBlockVisitors }) { + } else if (world.getParcelAt(event.entity).let { it != null && it.hasBlockVisitors }) { event.isCancelled = true } } @@ -402,8 +411,8 @@ class ParcelListeners( */ @field:ListenerMarker(priority = NORMAL) val onVehicleMoveEvent = RegistratorListener l@{ event -> - val (wo, ppa) = getWoAndPPa(event.to.block) ?: return@l - if (ppa == null) { + val (_, area) = getWorldAndArea(event.to.block) ?: return@l + if (area == null) { event.vehicle.passengers.forEach { if (it.type == EntityType.PLAYER) { (it as Player).sendParcelMessage(except = true, message = "Your ride ends here") @@ -411,7 +420,7 @@ class ParcelListeners( } event.vehicle.eject() event.vehicle.remove() - } else if (ppa.hasBlockVisitors) { + } else if (area.hasBlockVisitors) { event.to.subtract(event.to).add(event.from) } } @@ -432,7 +441,7 @@ class ParcelListeners( ?: (event.damager as? Projectile)?.let { it.shooter as? Player } ?: return@l - if (!world.getParcelAt(event.entity).canBuildN(user)) { + if (!canBuildOnArea(user, world.getParcelAt(event.entity))) { event.isCancelled = true } } @@ -444,7 +453,7 @@ class ParcelListeners( event.isCancelled = true; return@l } - if (world.getParcelAt(event.entity).isPresentAnd { hasBlockVisitors }) { + if (world.getParcelAt(event.entity).let { it != null && it.hasBlockVisitors }) { event.isCancelled = true } } @@ -457,7 +466,7 @@ class ParcelListeners( val onHangingBreakByEntityEvent = RegistratorListener l@{ event -> val world = parcelProvider.getWorld(event.entity.world) ?: return@l val user = event.remover as? Player ?: return@l - if (!world.getParcelAt(event.entity).canBuildN(user)) { + if (!canBuildOnArea(user, world.getParcelAt(event.entity))) { event.isCancelled = true } } @@ -469,7 +478,7 @@ class ParcelListeners( val onHangingPlaceEvent = RegistratorListener l@{ event -> val world = parcelProvider.getWorld(event.entity.world) ?: return@l val block = event.block.getRelative(event.blockFace) - if (!world.getParcelAt(block).canBuildN(event.player)) { + if (!canBuildOnArea(event.player, world.getParcelAt(block))) { event.isCancelled = true } } @@ -479,16 +488,16 @@ class ParcelListeners( */ @field:ListenerMarker(priority = NORMAL) val onStructureGrowEvent = RegistratorListener l@{ event -> - val (wo, ppa) = getWoAndPPa(event.location.block) ?: return@l - if (ppa == null) { + val (world, area) = getWorldAndArea(event.location.block) ?: return@l + if (area == null) { event.isCancelled = true; return@l } - if (!event.player.hasPermBuildAnywhere && !ppa.canBuild(event.player)) { + if (!event.player.hasPermBuildAnywhere && !area.canBuild(event.player)) { event.isCancelled = true; return@l } - event.blocks.removeIf { wo.getParcelAt(it.block) !== ppa } + event.blocks.removeIf { world.getParcelAt(it.block) !== area } } /* @@ -511,9 +520,9 @@ class ParcelListeners( */ @field:ListenerMarker(priority = NORMAL) val onItemSpawnEvent = RegistratorListener l@{ event -> - val (wo, ppa) = getWoAndPPa(event.location.block) ?: return@l - if (ppa == null) event.isCancelled = true - else entityTracker.track(event.entity, ppa) + val (_, area) = getWorldAndArea(event.location.block) ?: return@l + if (area == null) event.isCancelled = true + else entityTracker.track(event.entity, area) } /* @@ -521,8 +530,8 @@ class ParcelListeners( */ @field:ListenerMarker(priority = NORMAL) val onEntityTeleportEvent = RegistratorListener l@{ event -> - val (wo, ppa) = getWoAndPPa(event.from.block) ?: return@l - if (ppa !== wo.getParcelAt(event.to)) { + val (world, area) = getWorldAndArea(event.from.block) ?: return@l + if (area !== world.getParcelAt(event.to)) { event.isCancelled = true } } @@ -533,11 +542,11 @@ class ParcelListeners( */ @field:ListenerMarker(priority = NORMAL) val onProjectileLaunchEvent = RegistratorListener l@{ event -> - val (wo, ppa) = getWoAndPPa(event.entity.location.block) ?: return@l - if (ppa == null || (event.entity.shooter as? Player)?.let { !ppa.canBuildN(it) } == true) { + val (_, area) = getWorldAndArea(event.entity.location.block) ?: return@l + if (area == null || (event.entity.shooter as? Player)?.let { !canBuildOnArea(it, area) } == true) { event.isCancelled = true } else { - entityTracker.track(event.entity, ppa) + entityTracker.track(event.entity, area) } } diff --git a/src/main/kotlin/io/dico/parcels2/listener/WorldEditListener.kt b/src/main/kotlin/io/dico/parcels2/listener/WorldEditListener.kt index b279d2d..77d754a 100644 --- a/src/main/kotlin/io/dico/parcels2/listener/WorldEditListener.kt +++ b/src/main/kotlin/io/dico/parcels2/listener/WorldEditListener.kt @@ -43,7 +43,7 @@ class WorldEditListener(val parcels: ParcelsPlugin, val worldEdit: WorldEdit) { private fun canBuild(x: Int, z: Int): Boolean { world.getParcelAt(x, z)?.let { parcel -> - if (parcel.canBuild(player, checkAdmin = false)) { + if (parcel.canBuildFast(player)) { return true } } diff --git a/src/main/kotlin/io/dico/parcels2/storage/exposed/ListTables.kt b/src/main/kotlin/io/dico/parcels2/storage/exposed/ListTables.kt index 302d88d..d22316a 100644 --- a/src/main/kotlin/io/dico/parcels2/storage/exposed/ListTables.kt +++ b/src/main/kotlin/io/dico/parcels2/storage/exposed/ListTables.kt @@ -7,8 +7,8 @@ import io.dico.parcels2.Privilege.DEFAULT import kotlinx.coroutines.channels.SendChannel import org.jetbrains.exposed.sql.* -object PrivilegesLocalT : PrivilegesTable("parcels_added_local", ParcelsT) -object PrivilegesGlobalT : PrivilegesTable("parcels_added_global", ProfilesT) +object PrivilegesLocalT : PrivilegesTable("parcels_privilege_local", ParcelsT) +object PrivilegesGlobalT : PrivilegesTable("parcels_privilege_global", ProfilesT) object ParcelOptionsT : Table("parcel_options") { val parcel_id = integer("parcel_id").primaryKey().references(ParcelsT.id, ReferenceOption.CASCADE) 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 d7feabf..c09cd86 100644 --- a/src/main/kotlin/io/dico/parcels2/util/ext/Misc.kt +++ b/src/main/kotlin/io/dico/parcels2/util/ext/Misc.kt @@ -20,8 +20,8 @@ inline fun Boolean.alsoIfFalse(block: () -> Unit): Boolean = also { if (!it) blo inline fun Any.synchronized(block: () -> R): R = synchronized(this, block) -inline fun T?.isNullOr(condition: T.() -> Boolean): Boolean = this == null || condition() -inline fun T?.isPresentAnd(condition: T.() -> Boolean): Boolean = this != null && condition() +//inline fun T?.isNullOr(condition: T.() -> Boolean): Boolean = this == null || condition() +//inline fun T?.isPresentAnd(condition: T.() -> Boolean): Boolean = this != null && condition() inline fun T?.ifNullRun(block: () -> Unit): T? { if (this == null) block() return this 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 83bcaf2..1d3117e 100644 --- a/src/main/kotlin/io/dico/parcels2/util/ext/Player.kt +++ b/src/main/kotlin/io/dico/parcels2/util/ext/Player.kt @@ -13,10 +13,14 @@ inline val OfflinePlayer.uuid get() = uniqueId inline val OfflinePlayer.isValid get() = isOnline() || hasPlayedBefore() -inline val Player.hasPermBanBypass get() = hasPermission("parcels.admin.bypass.ban") +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 Player.hasPermBanBypass get() = hasPermission(PERM_BAN_BYPASS) inline val Player.hasPermGamemodeBypass get() = hasPermission("parcels.admin.bypass.gamemode") -inline val Player.hasPermBuildAnywhere get() = hasPermission("parcels.admin.bypass.build") -inline val Player.hasPermAdminManage get() = hasPermission("parcels.admin.manage") +inline val Player.hasPermBuildAnywhere get() = hasPermission(PERM_BUILD_ANYWHERE) +inline val Player.hasPermAdminManage get() = hasPermission(PERM_ADMIN_MANAGE) inline val Player.hasParcelHomeOthers get() = hasPermission("parcels.command.home.others") inline val Player.hasPermRandomSpecific get() = hasPermission("parcels.command.random.specific") val Player.parcelLimit: Int -- cgit v1.2.3