summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDico <dico.karssiens@gmail.com>2018-09-24 08:38:25 +0100
committerDico <dico.karssiens@gmail.com>2018-09-24 08:38:25 +0100
commit68a0bb0539bd0fde46bdeeaa4c6a9fe49ec1958a (patch)
treee82a2beea1e7e337d502c8c2a48e33dec083b135
parenta61e1d69b201434f3a4e83c877a041393a340001 (diff)
Cleanup of privilege and listeners
-rw-r--r--build.gradle.kts5
-rw-r--r--old-build.gradle.kts206
-rw-r--r--src/main/kotlin/io/dico/parcels2/Parcel.kt22
-rw-r--r--src/main/kotlin/io/dico/parcels2/Privilege.kt146
-rw-r--r--src/main/kotlin/io/dico/parcels2/Privileges.kt128
-rw-r--r--src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelGenerator.kt6
-rw-r--r--src/main/kotlin/io/dico/parcels2/defaultimpl/GlobalPrivilegesManagerImpl.kt10
-rw-r--r--src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt52
-rw-r--r--src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt133
-rw-r--r--src/main/kotlin/io/dico/parcels2/listener/WorldEditListener.kt2
-rw-r--r--src/main/kotlin/io/dico/parcels2/storage/exposed/ListTables.kt4
-rw-r--r--src/main/kotlin/io/dico/parcels2/util/ext/Misc.kt4
-rw-r--r--src/main/kotlin/io/dico/parcels2/util/ext/Player.kt10
13 files changed, 278 insertions, 450 deletions
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<KotlinPlatformJvmPlugin>()
- 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 <reified T : Plugin<out Project>> Project.apply() =
- (this as PluginAware).apply<T>()
-
-allprojects {
- apply<JavaPlugin>()
-
- 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<KotlinPlatformJvmPlugin>()
-
- 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<PrivilegeKey, Privilege>
+typealias PrivilegeMap = Map<PrivilegeKey, Privilege>
+
+@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<PrivilegeKey, Privilege>
-typealias PrivilegeMap = Map<PrivilegeKey, Privilege>
-
-@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<PlayerProfile, GlobalPrivileges>()
- 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<PrivilegesHolder>.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<ParcelWorld, Parcel?>? {
+ private fun getWorldAndArea(block: Block): Pair<ParcelWorld, Parcel?>? {
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<BlockBreakEvent> 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<BlockPlaceEvent> 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<Block>) {
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<ExplosionPrimeEvent> 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<EntityExplodeEvent> 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<BlockFromToEvent> 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<PlayerInteractEntityEvent> 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<EntityChangeBlockEvent> 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<PlayerDropItemEvent> 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<EntityPickupItemEvent> 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<InventoryInteractEvent> 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<BlockFormEvent> 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<VehicleMoveEvent> 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<HangingBreakByEntityEvent> 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<HangingPlaceEvent> 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<StructureGrowEvent> 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<ItemSpawnEvent> 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<EntityTeleportEvent> 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<ProjectileLaunchEvent> 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<ParcelId>("parcels_added_local", ParcelsT)
-object PrivilegesGlobalT : PrivilegesTable<PlayerProfile>("parcels_added_global", ProfilesT)
+object PrivilegesLocalT : PrivilegesTable<ParcelId>("parcels_privilege_local", ParcelsT)
+object PrivilegesGlobalT : PrivilegesTable<PlayerProfile>("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 <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?.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
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