Cleanup of privilege and listeners
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
@file:Suppress("RemoveRedundantBackticks", "IMPLICIT_CAST_TO_ANY", "UNUSED_VARIABLE")
|
@file:Suppress("RemoveRedundantBackticks", "IMPLICIT_CAST_TO_ANY", "UNUSED_VARIABLE")
|
||||||
|
|
||||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
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.plugin.KotlinPlatformJvmPlugin
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
@@ -31,7 +30,7 @@ allprojects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
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.bukkit:bukkit:$spigotVersion") { isTransitive = false }
|
||||||
c.provided("org.spigotmc:spigot-api:$spigotVersion") { isTransitive = false }
|
c.provided("org.spigotmc:spigot-api:$spigotVersion") { isTransitive = false }
|
||||||
|
|
||||||
@@ -46,7 +45,6 @@ allprojects {
|
|||||||
|
|
||||||
project(":dicore3:dicore3-command") {
|
project(":dicore3:dicore3-command") {
|
||||||
apply<KotlinPlatformJvmPlugin>()
|
apply<KotlinPlatformJvmPlugin>()
|
||||||
kotlin.experimental.coroutines = ENABLE
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
c.kotlinStd(kotlin("stdlib-jdk8"))
|
c.kotlinStd(kotlin("stdlib-jdk8"))
|
||||||
@@ -70,6 +68,7 @@ dependencies {
|
|||||||
|
|
||||||
// not on sk89q maven repo yet
|
// not on sk89q maven repo yet
|
||||||
compileClasspath(files("$rootDir/debug/plugins/worldedit-bukkit-7.0.0-beta-01.jar"))
|
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("org.jetbrains.exposed:exposed:0.10.5") { isTransitive = false }
|
||||||
compile("joda-time:joda-time:2.10")
|
compile("joda-time:joda-time:2.10")
|
||||||
|
|||||||
@@ -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())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,7 @@
|
|||||||
package io.dico.parcels2
|
package io.dico.parcels2
|
||||||
|
|
||||||
import io.dico.parcels2.util.Vec2i
|
import io.dico.parcels2.util.Vec2i
|
||||||
import io.dico.parcels2.util.ext.hasPermBuildAnywhere
|
|
||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
import org.bukkit.OfflinePlayer
|
|
||||||
import org.bukkit.entity.Player
|
|
||||||
import org.joda.time.DateTime
|
import org.joda.time.DateTime
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
@@ -16,7 +13,7 @@ import java.util.UUID
|
|||||||
* However, this implementation is intentionally not thread-safe.
|
* However, this implementation is intentionally not thread-safe.
|
||||||
* Therefore, database query callbacks should schedule their updates using the bukkit scheduler.
|
* Therefore, database query callbacks should schedule their updates using the bukkit scheduler.
|
||||||
*/
|
*/
|
||||||
interface Parcel : ParcelData {
|
interface Parcel : ParcelData, Privileges {
|
||||||
val id: ParcelId
|
val id: ParcelId
|
||||||
val world: ParcelWorld
|
val world: ParcelWorld
|
||||||
val pos: Vec2i
|
val pos: Vec2i
|
||||||
@@ -25,6 +22,10 @@ interface Parcel : ParcelData {
|
|||||||
val data: ParcelData
|
val data: ParcelData
|
||||||
val infoString: String
|
val infoString: String
|
||||||
val hasBlockVisitors: Boolean
|
val hasBlockVisitors: Boolean
|
||||||
|
val globalPrivileges: GlobalPrivileges?
|
||||||
|
|
||||||
|
override val keyOfOwner: PlayerProfile.Real?
|
||||||
|
get() = owner as? PlayerProfile.Real
|
||||||
|
|
||||||
fun copyDataIgnoringDatabase(data: ParcelData)
|
fun copyDataIgnoringDatabase(data: ParcelData)
|
||||||
|
|
||||||
@@ -37,13 +38,13 @@ interface Parcel : ParcelData {
|
|||||||
val homeLocation: Location get() = world.blockManager.getHomeLocation(id)
|
val homeLocation: Location get() = world.blockManager.getHomeLocation(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ParcelData : Privileges {
|
interface ParcelData : PrivilegesMinimal {
|
||||||
var owner: PlayerProfile?
|
var owner: PlayerProfile?
|
||||||
val lastClaimTime: DateTime?
|
val lastClaimTime: DateTime?
|
||||||
var ownerSignOutdated: Boolean
|
var ownerSignOutdated: Boolean
|
||||||
var interactableConfig: InteractableConfiguration
|
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 {
|
fun isOwner(uuid: UUID): Boolean {
|
||||||
return owner?.uuid == uuid
|
return owner?.uuid == uuid
|
||||||
@@ -59,10 +60,11 @@ class ParcelDataHolder(addedMap: MutablePrivilegeMap = mutableMapOf())
|
|||||||
override var owner: PlayerProfile? = null
|
override var owner: PlayerProfile? = null
|
||||||
override var lastClaimTime: DateTime? = null
|
override var lastClaimTime: DateTime? = null
|
||||||
override var ownerSignOutdated = false
|
override var ownerSignOutdated = false
|
||||||
override fun canBuild(player: OfflinePlayer, checkAdmin: Boolean, checkGlobal: Boolean) =
|
|
||||||
hasPrivilegeToBuild(player)
|
//override fun canBuild(player: OfflinePlayer, checkAdmin: Boolean, checkGlobal: Boolean) =
|
||||||
|| owner.let { it != null && it.matches(player, allowNameMatch = false) }
|
// hasPrivilegeToBuild(player)
|
||||||
|| (checkAdmin && player is Player && player.hasPermBuildAnywhere)
|
// || owner.let { it != null && it.matches(player, allowNameMatch = false) }
|
||||||
|
// || (checkAdmin && player is Player && player.hasPermBuildAnywhere)
|
||||||
|
|
||||||
override var interactableConfig: InteractableConfiguration = BitmaskInteractableConfiguration()
|
override var interactableConfig: InteractableConfiguration = BitmaskInteractableConfiguration()
|
||||||
}
|
}
|
||||||
|
|||||||
146
src/main/kotlin/io/dico/parcels2/Privilege.kt
Normal file
146
src/main/kotlin/io/dico/parcels2/Privilege.kt
Normal file
@@ -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)
|
||||||
|
}
|
||||||
@@ -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)
|
|
||||||
}
|
|
||||||
@@ -20,9 +20,8 @@ import org.bukkit.block.Biome
|
|||||||
import org.bukkit.block.BlockFace
|
import org.bukkit.block.BlockFace
|
||||||
import org.bukkit.block.Skull
|
import org.bukkit.block.Skull
|
||||||
import org.bukkit.block.data.BlockData
|
import org.bukkit.block.data.BlockData
|
||||||
import org.bukkit.block.data.type.Sign
|
|
||||||
import org.bukkit.block.data.type.Slab
|
import org.bukkit.block.data.type.Slab
|
||||||
import java.lang.IllegalArgumentException
|
import org.bukkit.block.data.type.WallSign
|
||||||
import java.util.Random
|
import java.util.Random
|
||||||
|
|
||||||
private val airType = Bukkit.createBlockData(Material.AIR)
|
private val airType = Bukkit.createBlockData(Material.AIR)
|
||||||
@@ -201,8 +200,7 @@ class DefaultParcelGenerator(
|
|||||||
o.wallType
|
o.wallType
|
||||||
|
|
||||||
wallBlock.blockData = wallBlockType
|
wallBlock.blockData = wallBlockType
|
||||||
|
signBlock.blockData = (Bukkit.createBlockData(Material.WALL_SIGN) as WallSign).apply { facing = BlockFace.NORTH }
|
||||||
signBlock.blockData = (Bukkit.createBlockData(Material.WALL_SIGN) as Sign).apply { rotation = BlockFace.NORTH }
|
|
||||||
|
|
||||||
val sign = signBlock.state as org.bukkit.block.Sign
|
val sign = signBlock.state as org.bukkit.block.Sign
|
||||||
sign.setLine(0, "${parcel.x},${parcel.z}")
|
sign.setLine(0, "${parcel.x},${parcel.z}")
|
||||||
|
|||||||
@@ -9,25 +9,25 @@ import java.util.Collections
|
|||||||
class GlobalPrivilegesManagerImpl(val plugin: ParcelsPlugin) : GlobalPrivilegesManager {
|
class GlobalPrivilegesManagerImpl(val plugin: ParcelsPlugin) : GlobalPrivilegesManager {
|
||||||
private val map = mutableMapOf<PlayerProfile, GlobalPrivileges>()
|
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 }
|
return map[owner] ?: GlobalPrivilegesImpl(owner).also { map[owner] = it }
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class GlobalPrivilegesImpl(
|
private inner class GlobalPrivilegesImpl(
|
||||||
override val owner: PlayerProfile,
|
override val keyOfOwner: PlayerProfile.Real,
|
||||||
data: MutablePrivilegeMap = emptyData
|
data: MutablePrivilegeMap = emptyData
|
||||||
) : PrivilegesHolder(data), GlobalPrivileges {
|
) : PrivilegesHolder(data), GlobalPrivileges {
|
||||||
|
|
||||||
private inline var data get() = map; set(value) = run { map = value }
|
private inline var data get() = map; set(value) = run { map = value }
|
||||||
private inline val isEmpty get() = data === emptyData
|
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 (isEmpty) {
|
||||||
if (privilege == Privilege.DEFAULT) return false
|
if (privilege == Privilege.DEFAULT) return false
|
||||||
data = mutableMapOf()
|
data = mutableMapOf()
|
||||||
}
|
}
|
||||||
return super<PrivilegesHolder>.setPrivilege(key, privilege).alsoIfTrue {
|
return super.setStoredPrivilege(key, privilege).alsoIfTrue {
|
||||||
plugin.storage.setGlobalPrivilege(owner, key, privilege)
|
plugin.storage.setGlobalPrivilege(keyOfOwner, key, privilege)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package io.dico.parcels2.defaultimpl
|
|||||||
|
|
||||||
import io.dico.dicore.Formatting
|
import io.dico.dicore.Formatting
|
||||||
import io.dico.parcels2.*
|
import io.dico.parcels2.*
|
||||||
|
import io.dico.parcels2.Privilege.*
|
||||||
import io.dico.parcels2.util.Vec2i
|
import io.dico.parcels2.util.Vec2i
|
||||||
import io.dico.parcels2.util.ext.alsoIfTrue
|
import io.dico.parcels2.util.ext.alsoIfTrue
|
||||||
import org.bukkit.Material
|
import org.bukkit.Material
|
||||||
@@ -36,19 +37,26 @@ class ParcelImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override val map: PrivilegeMap get() = data.map
|
override val map: PrivilegeMap get() = data.map
|
||||||
override fun privilege(key: PrivilegeKey) = data.privilege(key)
|
override fun getStoredPrivilege(key: PrivilegeKey) = data.getStoredPrivilege(key)
|
||||||
override fun isBanned(key: PrivilegeKey) = data.isBanned(key)
|
|
||||||
override fun hasPrivilegeToBuild(key: PrivilegeKey) = data.hasPrivilegeToBuild(key)
|
override fun setStoredPrivilege(key: PrivilegeKey, privilege: Privilege): Boolean {
|
||||||
override fun canBuild(player: OfflinePlayer, checkAdmin: Boolean, checkGlobal: Boolean): Boolean {
|
return data.setStoredPrivilege(key, privilege).alsoIfTrue {
|
||||||
return (data.canBuild(player, checkAdmin, false))
|
world.storage.setLocalPrivilege(this, key, privilege)
|
||||||
|| checkGlobal && world.globalPrivileges[owner ?: return false].hasPrivilegeToBuild(player)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
override var privilegeOfStar: Privilege
|
||||||
get() = data.privilegeOfStar
|
get() = data.privilegeOfStar.let { if (it == DEFAULT) globalPrivileges?.privilegeOfStar ?: DEFAULT else it }
|
||||||
set(value) = run { setPrivilege(PlayerProfile.Star, value) }
|
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
|
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() {
|
private fun updateInteractableConfigStorage() {
|
||||||
world.storage.setParcelOptionsInteractConfig(this, data.interactableConfig)
|
world.storage.setParcelOptionsInteractConfig(this, data.interactableConfig)
|
||||||
}
|
}
|
||||||
@@ -188,12 +190,14 @@ private object ParcelInfoStringComputer {
|
|||||||
val (key, priv) = pair
|
val (key, priv) = pair
|
||||||
|
|
||||||
// prefix. Maybe T should be M for mod or something. T means they have CAN_MANAGE privilege.
|
// prefix. Maybe T should be M for mod or something. T means they have CAN_MANAGE privilege.
|
||||||
append(when {
|
append(
|
||||||
global && priv == Privilege.CAN_MANAGE -> "(GT)"
|
when {
|
||||||
global -> "(G)"
|
global && priv == CAN_MANAGE -> "(GT)"
|
||||||
priv == Privilege.CAN_MANAGE -> "(T)"
|
global -> "(G)"
|
||||||
else -> ""
|
priv == CAN_MANAGE -> "(T)"
|
||||||
})
|
else -> ""
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
append(key.notNullName)
|
append(key.notNullName)
|
||||||
}
|
}
|
||||||
@@ -219,11 +223,11 @@ private object ParcelInfoStringComputer {
|
|||||||
|
|
||||||
append('\n')
|
append('\n')
|
||||||
|
|
||||||
val global = owner?.let { parcel.world.globalPrivileges[owner].map } ?: emptyMap()
|
|
||||||
val local = parcel.map
|
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')
|
append('\n')
|
||||||
appendAddedList(local, global, Privilege.BANNED, "Banned")
|
appendAddedList(local, global, BANNED, "Banned")
|
||||||
|
|
||||||
if (!parcel.interactableConfig.isDefault()) {
|
if (!parcel.interactableConfig.isDefault()) {
|
||||||
val interactables = parcel.interactableConfig.interactableClasses
|
val interactables = parcel.interactableConfig.interactableClasses
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package io.dico.parcels2.listener
|
package io.dico.parcels2.listener
|
||||||
|
|
||||||
import gnu.trove.TLongCollection
|
import gnu.trove.TLongCollection
|
||||||
|
import gnu.trove.set.hash.TLongHashSet
|
||||||
import io.dico.dicore.ListenerMarker
|
import io.dico.dicore.ListenerMarker
|
||||||
import io.dico.dicore.RegistratorListener
|
import io.dico.dicore.RegistratorListener
|
||||||
import io.dico.parcels2.*
|
import io.dico.parcels2.*
|
||||||
@@ -30,21 +31,23 @@ import org.bukkit.event.world.StructureGrowEvent
|
|||||||
import org.bukkit.inventory.InventoryHolder
|
import org.bukkit.inventory.InventoryHolder
|
||||||
import java.util.EnumSet
|
import java.util.EnumSet
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
class ParcelListeners(
|
class ParcelListeners(
|
||||||
val parcelProvider: ParcelProvider,
|
val parcelProvider: ParcelProvider,
|
||||||
val entityTracker: ParcelEntityTracker,
|
val entityTracker: ParcelEntityTracker,
|
||||||
val storage: Storage
|
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
|
* Get the world and parcel that the block resides in
|
||||||
* wo is the world, ppa is the parcel
|
* the parcel is nullable, and often named area because that means path.
|
||||||
* ppa for possibly a parcel - it will be null if not in an existing parcel
|
* returns null if not in a registered parcel world - should always return in that case to not affect other worlds.
|
||||||
* returns null if not in a registered parcel world
|
|
||||||
*/
|
*/
|
||||||
private fun getWoAndPPa(block: Block): Pair<ParcelWorld, Parcel?>? {
|
private fun getWorldAndArea(block: Block): Pair<ParcelWorld, Parcel?>? {
|
||||||
val world = parcelProvider.getWorld(block.world) ?: return null
|
val world = parcelProvider.getWorld(block.world) ?: return null
|
||||||
return world to world.getParcelAt(block)
|
return world to world.getParcelAt(block)
|
||||||
}
|
}
|
||||||
@@ -57,7 +60,7 @@ class ParcelListeners(
|
|||||||
val user = event.player
|
val user = event.player
|
||||||
if (user.hasPermBanBypass) return@l
|
if (user.hasPermBanBypass) return@l
|
||||||
val parcel = parcelProvider.getParcelAt(event.to) ?: return@l
|
val parcel = parcelProvider.getParcelAt(event.to) ?: return@l
|
||||||
if (parcel.isBanned(user.privilegeKey)) {
|
if (!parcel.canEnter(user)) {
|
||||||
parcelProvider.getParcelAt(event.from)?.also {
|
parcelProvider.getParcelAt(event.from)?.also {
|
||||||
user.teleport(it.homeLocation)
|
user.teleport(it.homeLocation)
|
||||||
user.sendParcelMessage(nopermit = true, message = "You are banned from this parcel")
|
user.sendParcelMessage(nopermit = true, message = "You are banned from this parcel")
|
||||||
@@ -71,12 +74,12 @@ class ParcelListeners(
|
|||||||
*/
|
*/
|
||||||
@field:ListenerMarker(priority = NORMAL)
|
@field:ListenerMarker(priority = NORMAL)
|
||||||
val onBlockBreakEvent = RegistratorListener<BlockBreakEvent> l@{ event ->
|
val onBlockBreakEvent = RegistratorListener<BlockBreakEvent> l@{ event ->
|
||||||
val (wo, ppa) = getWoAndPPa(event.block) ?: return@l
|
val (world, area) = getWorldAndArea(event.block) ?: return@l
|
||||||
if (!event.player.hasPermBuildAnywhere && ppa.isNullOr { !canBuild(event.player) }) {
|
if (!canBuildOnArea(event.player, area)) {
|
||||||
event.isCancelled = true; return@l
|
event.isCancelled = true; return@l
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wo.options.dropEntityItems) {
|
if (!world.options.dropEntityItems) {
|
||||||
val state = event.block.state
|
val state = event.block.state
|
||||||
if (state is InventoryHolder) {
|
if (state is InventoryHolder) {
|
||||||
state.inventory.clear()
|
state.inventory.clear()
|
||||||
@@ -90,8 +93,8 @@ class ParcelListeners(
|
|||||||
*/
|
*/
|
||||||
@field:ListenerMarker(priority = NORMAL)
|
@field:ListenerMarker(priority = NORMAL)
|
||||||
val onBlockPlaceEvent = RegistratorListener<BlockPlaceEvent> l@{ event ->
|
val onBlockPlaceEvent = RegistratorListener<BlockPlaceEvent> l@{ event ->
|
||||||
val (wo, ppa) = getWoAndPPa(event.block) ?: return@l
|
val (_, area) = getWorldAndArea(event.block) ?: return@l
|
||||||
if (!event.player.hasPermBuildAnywhere && ppa.isNullOr { !canBuild(event.player) }) {
|
if (!canBuildOnArea(event.player, area)) {
|
||||||
event.isCancelled = true
|
event.isCancelled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,7 +123,7 @@ class ParcelListeners(
|
|||||||
private fun checkPistonMovement(event: BlockPistonEvent, blocks: List<Block>) {
|
private fun checkPistonMovement(event: BlockPistonEvent, blocks: List<Block>) {
|
||||||
val world = parcelProvider.getWorld(event.block.world) ?: return
|
val world = parcelProvider.getWorld(event.block.world) ?: return
|
||||||
val direction = event.direction
|
val direction = event.direction
|
||||||
val columns = gnu.trove.set.hash.TLongHashSet(blocks.size * 2)
|
val columns = TLongHashSet(blocks.size * 2)
|
||||||
|
|
||||||
blocks.forEach {
|
blocks.forEach {
|
||||||
columns.add(Column(it.x, it.z))
|
columns.add(Column(it.x, it.z))
|
||||||
@@ -128,8 +131,8 @@ class ParcelListeners(
|
|||||||
}
|
}
|
||||||
|
|
||||||
columns.troveForEach {
|
columns.troveForEach {
|
||||||
val ppa = world.getParcelAt(it.columnX, it.columnZ)
|
val area = world.getParcelAt(it.columnX, it.columnZ)
|
||||||
if (ppa.isNullOr { hasBlockVisitors }) {
|
if (area == null || area.hasBlockVisitors) {
|
||||||
event.isCancelled = true
|
event.isCancelled = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -141,10 +144,10 @@ class ParcelListeners(
|
|||||||
*/
|
*/
|
||||||
@field:ListenerMarker(priority = NORMAL)
|
@field:ListenerMarker(priority = NORMAL)
|
||||||
val onExplosionPrimeEvent = RegistratorListener<ExplosionPrimeEvent> l@{ event ->
|
val onExplosionPrimeEvent = RegistratorListener<ExplosionPrimeEvent> l@{ event ->
|
||||||
val (wo, ppa) = getWoAndPPa(event.entity.location.block) ?: return@l
|
val (world, area) = getWorldAndArea(event.entity.location.block) ?: return@l
|
||||||
if (ppa?.hasBlockVisitors == true) {
|
if (area != null && area.hasBlockVisitors) {
|
||||||
event.radius = 0F; event.isCancelled = true
|
event.radius = 0F; event.isCancelled = true
|
||||||
} else if (wo.options.disableExplosions) {
|
} else if (world.options.disableExplosions) {
|
||||||
event.radius = 0F
|
event.radius = 0F
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,18 +159,18 @@ class ParcelListeners(
|
|||||||
val onEntityExplodeEvent = RegistratorListener<EntityExplodeEvent> l@{ event ->
|
val onEntityExplodeEvent = RegistratorListener<EntityExplodeEvent> l@{ event ->
|
||||||
entityTracker.untrack(event.entity)
|
entityTracker.untrack(event.entity)
|
||||||
val world = parcelProvider.getWorld(event.entity.world) ?: return@l
|
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
|
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)
|
@field:ListenerMarker(priority = NORMAL)
|
||||||
val onBlockFromToEvent = RegistratorListener<BlockFromToEvent> l@{ event ->
|
val onBlockFromToEvent = RegistratorListener<BlockFromToEvent> l@{ event ->
|
||||||
val (wo, ppa) = getWoAndPPa(event.toBlock) ?: return@l
|
val (_, area) = getWorldAndArea(event.toBlock) ?: return@l
|
||||||
if (ppa.isNullOr { hasBlockVisitors }) event.isCancelled = true
|
if (area == null || area.hasBlockVisitors) event.isCancelled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
private val bedTypes = EnumSet.copyOf(getMaterialsWithWoolColorPrefix("BED").toList())
|
private val bedTypes = EnumSet.copyOf(getMaterialsWithWoolColorPrefix("BED").toList())
|
||||||
@@ -185,7 +188,7 @@ class ParcelListeners(
|
|||||||
val clickedBlock = event.clickedBlock
|
val clickedBlock = event.clickedBlock
|
||||||
val parcel = clickedBlock?.let { world.getParcelAt(it) }
|
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")
|
user.sendParcelMessage(nopermit = true, message = "You cannot interact with parcels you're banned from")
|
||||||
event.isCancelled = true; return@l
|
event.isCancelled = true; return@l
|
||||||
}
|
}
|
||||||
@@ -193,7 +196,8 @@ class ParcelListeners(
|
|||||||
when (event.action) {
|
when (event.action) {
|
||||||
Action.RIGHT_CLICK_BLOCK -> run {
|
Action.RIGHT_CLICK_BLOCK -> run {
|
||||||
val type = clickedBlock.type
|
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) {
|
if (!interactable) {
|
||||||
val interactableClassName = Interactables[type]!!.name
|
val interactableClassName = Interactables[type]!!.name
|
||||||
user.sendParcelMessage(nopermit = true, message = "You cannot interact with $interactableClassName in this parcel")
|
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
|
val head = if (bed == Bed.Part.FOOT) clickedBlock.getRelative(bed.facing) else clickedBlock
|
||||||
when (head.biome) {
|
when (head.biome) {
|
||||||
Biome.NETHER, Biome.THE_END -> {
|
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")
|
user.sendParcelMessage(nopermit = true, message = "You cannot use this bed because it would explode")
|
||||||
event.isCancelled = true; return@l
|
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)
|
onPlayerInteractEvent_RightClick(event, world, parcel)
|
||||||
}
|
}
|
||||||
|
|
||||||
Action.RIGHT_CLICK_AIR -> 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")
|
user.sendParcelMessage(nopermit = true, message = "You cannot use inputs in this parcel")
|
||||||
event.isCancelled = true; return@l
|
event.isCancelled = true; return@l
|
||||||
}
|
}
|
||||||
@@ -234,7 +243,7 @@ class ParcelListeners(
|
|||||||
event.isCancelled = true; return
|
event.isCancelled = true; return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parcel.canBuildN(event.player)) {
|
if (!canBuildOnArea(event.player, parcel)) {
|
||||||
when (item) {
|
when (item) {
|
||||||
LAVA_BUCKET, WATER_BUCKET, BUCKET, FLINT_AND_STEEL -> event.isCancelled = true
|
LAVA_BUCKET, WATER_BUCKET, BUCKET, FLINT_AND_STEEL -> event.isCancelled = true
|
||||||
}
|
}
|
||||||
@@ -249,8 +258,8 @@ class ParcelListeners(
|
|||||||
@Suppress("NON_EXHAUSTIVE_WHEN")
|
@Suppress("NON_EXHAUSTIVE_WHEN")
|
||||||
@field:ListenerMarker(priority = NORMAL)
|
@field:ListenerMarker(priority = NORMAL)
|
||||||
val onPlayerInteractEntityEvent = RegistratorListener<PlayerInteractEntityEvent> l@{ event ->
|
val onPlayerInteractEntityEvent = RegistratorListener<PlayerInteractEntityEvent> l@{ event ->
|
||||||
val (wo, ppa) = getWoAndPPa(event.rightClicked.location.block) ?: return@l
|
val (_, area) = getWorldAndArea(event.rightClicked.location.block) ?: return@l
|
||||||
if (ppa.canBuildN(event.player)) return@l
|
if (canBuildOnArea(event.player, area)) return@l
|
||||||
when (event.rightClicked.type) {
|
when (event.rightClicked.type) {
|
||||||
EntityType.BOAT,
|
EntityType.BOAT,
|
||||||
EntityType.MINECART,
|
EntityType.MINECART,
|
||||||
@@ -281,14 +290,14 @@ class ParcelListeners(
|
|||||||
*/
|
*/
|
||||||
@field:ListenerMarker(priority = NORMAL)
|
@field:ListenerMarker(priority = NORMAL)
|
||||||
val onEntityChangeBlockEvent = RegistratorListener<EntityChangeBlockEvent> l@{ event ->
|
val onEntityChangeBlockEvent = RegistratorListener<EntityChangeBlockEvent> l@{ event ->
|
||||||
val (wo, ppa) = getWoAndPPa(event.block) ?: return@l
|
val (_, area) = getWorldAndArea(event.block) ?: return@l
|
||||||
if (event.entity.type == EntityType.ENDERMAN || ppa.isNullOr { hasBlockVisitors }) {
|
if (event.entity.type == EntityType.ENDERMAN || area == null || area.hasBlockVisitors) {
|
||||||
event.isCancelled = true; return@l
|
event.isCancelled = true; return@l
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.entity.type == EntityType.FALLING_BLOCK) {
|
if (event.entity.type == EntityType.FALLING_BLOCK) {
|
||||||
// a sand block started falling. Track it and delete it if it gets out of this parcel.
|
// 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)
|
@field:ListenerMarker(priority = NORMAL)
|
||||||
val onPlayerDropItemEvent = RegistratorListener<PlayerDropItemEvent> l@{ event ->
|
val onPlayerDropItemEvent = RegistratorListener<PlayerDropItemEvent> l@{ event ->
|
||||||
val (wo, ppa) = getWoAndPPa(event.itemDrop.location.block) ?: return@l
|
val (_, area) = getWorldAndArea(event.itemDrop.location.block) ?: return@l
|
||||||
if (!ppa.canBuildN(event.player) && !ppa.isPresentAnd { interactableConfig("containers") }) event.isCancelled = true
|
if (!canInteract(event.player, area, "containers")) event.isCancelled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -316,8 +325,8 @@ class ParcelListeners(
|
|||||||
@field:ListenerMarker(priority = NORMAL)
|
@field:ListenerMarker(priority = NORMAL)
|
||||||
val onEntityPickupItemEvent = RegistratorListener<EntityPickupItemEvent> l@{ event ->
|
val onEntityPickupItemEvent = RegistratorListener<EntityPickupItemEvent> l@{ event ->
|
||||||
val user = event.entity as? Player ?: return@l
|
val user = event.entity as? Player ?: return@l
|
||||||
val (wo, ppa) = getWoAndPPa(event.item.location.block) ?: return@l
|
val (_, area) = getWorldAndArea(event.item.location.block) ?: return@l
|
||||||
if (!ppa.canBuildN(user)) event.isCancelled = true
|
if (!canInteract(user, area, "containers")) event.isCancelled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -327,8 +336,8 @@ class ParcelListeners(
|
|||||||
val onInventoryClickEvent = RegistratorListener<InventoryInteractEvent> l@{ event ->
|
val onInventoryClickEvent = RegistratorListener<InventoryInteractEvent> l@{ event ->
|
||||||
val user = event.whoClicked as? Player ?: return@l
|
val user = event.whoClicked as? Player ?: return@l
|
||||||
if ((event.inventory ?: return@l).holder === user) return@l // inventory null: hotbar
|
if ((event.inventory ?: return@l).holder === user) return@l // inventory null: hotbar
|
||||||
val (wo, ppa) = getWoAndPPa(event.inventory.location.block) ?: return@l
|
val (_, area) = getWorldAndArea(event.inventory.location.block) ?: return@l
|
||||||
if (ppa.isNullOr { !canBuild(user) && !interactableConfig("containers") }) {
|
if (!canInteract(user, area, "containers")) {
|
||||||
event.isCancelled = true
|
event.isCancelled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -358,10 +367,10 @@ class ParcelListeners(
|
|||||||
@ListenerMarker(priority = NORMAL)
|
@ListenerMarker(priority = NORMAL)
|
||||||
val onBlockFormEvent = RegistratorListener<BlockFormEvent> l@{ event ->
|
val onBlockFormEvent = RegistratorListener<BlockFormEvent> l@{ event ->
|
||||||
val block = event.block
|
val block = event.block
|
||||||
val (wo, ppa) = getWoAndPPa(block) ?: return@l
|
val (world, area) = getWorldAndArea(block) ?: return@l
|
||||||
|
|
||||||
// prevent any generation whatsoever on paths
|
// prevent any generation whatsoever on paths
|
||||||
if (ppa == null) {
|
if (area == null) {
|
||||||
event.isCancelled = true; return@l
|
event.isCancelled = true; return@l
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,10 +380,10 @@ class ParcelListeners(
|
|||||||
val cancel: Boolean = when (event.newState.type) {
|
val cancel: Boolean = when (event.newState.type) {
|
||||||
|
|
||||||
// prevent ice generation from Frost Walkers enchantment
|
// 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
|
// prevent snow generation from weather
|
||||||
SNOW -> !hasEntity && wo.options.preventWeatherBlockChanges
|
SNOW -> !hasEntity && world.options.preventWeatherBlockChanges
|
||||||
|
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
@@ -392,7 +401,7 @@ class ParcelListeners(
|
|||||||
val world = parcelProvider.getWorld(event.entity.world) ?: return@l
|
val world = parcelProvider.getWorld(event.entity.world) ?: return@l
|
||||||
if (event.entity is Creature && world.options.blockMobSpawning) {
|
if (event.entity is Creature && world.options.blockMobSpawning) {
|
||||||
event.isCancelled = true
|
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
|
event.isCancelled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -402,8 +411,8 @@ class ParcelListeners(
|
|||||||
*/
|
*/
|
||||||
@field:ListenerMarker(priority = NORMAL)
|
@field:ListenerMarker(priority = NORMAL)
|
||||||
val onVehicleMoveEvent = RegistratorListener<VehicleMoveEvent> l@{ event ->
|
val onVehicleMoveEvent = RegistratorListener<VehicleMoveEvent> l@{ event ->
|
||||||
val (wo, ppa) = getWoAndPPa(event.to.block) ?: return@l
|
val (_, area) = getWorldAndArea(event.to.block) ?: return@l
|
||||||
if (ppa == null) {
|
if (area == null) {
|
||||||
event.vehicle.passengers.forEach {
|
event.vehicle.passengers.forEach {
|
||||||
if (it.type == EntityType.PLAYER) {
|
if (it.type == EntityType.PLAYER) {
|
||||||
(it as Player).sendParcelMessage(except = true, message = "Your ride ends here")
|
(it as Player).sendParcelMessage(except = true, message = "Your ride ends here")
|
||||||
@@ -411,7 +420,7 @@ class ParcelListeners(
|
|||||||
}
|
}
|
||||||
event.vehicle.eject()
|
event.vehicle.eject()
|
||||||
event.vehicle.remove()
|
event.vehicle.remove()
|
||||||
} else if (ppa.hasBlockVisitors) {
|
} else if (area.hasBlockVisitors) {
|
||||||
event.to.subtract(event.to).add(event.from)
|
event.to.subtract(event.to).add(event.from)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -432,7 +441,7 @@ class ParcelListeners(
|
|||||||
?: (event.damager as? Projectile)?.let { it.shooter as? Player }
|
?: (event.damager as? Projectile)?.let { it.shooter as? Player }
|
||||||
?: return@l
|
?: return@l
|
||||||
|
|
||||||
if (!world.getParcelAt(event.entity).canBuildN(user)) {
|
if (!canBuildOnArea(user, world.getParcelAt(event.entity))) {
|
||||||
event.isCancelled = true
|
event.isCancelled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -444,7 +453,7 @@ class ParcelListeners(
|
|||||||
event.isCancelled = true; return@l
|
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
|
event.isCancelled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -457,7 +466,7 @@ class ParcelListeners(
|
|||||||
val onHangingBreakByEntityEvent = RegistratorListener<HangingBreakByEntityEvent> l@{ event ->
|
val onHangingBreakByEntityEvent = RegistratorListener<HangingBreakByEntityEvent> l@{ event ->
|
||||||
val world = parcelProvider.getWorld(event.entity.world) ?: return@l
|
val world = parcelProvider.getWorld(event.entity.world) ?: return@l
|
||||||
val user = event.remover as? Player ?: 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
|
event.isCancelled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -469,7 +478,7 @@ class ParcelListeners(
|
|||||||
val onHangingPlaceEvent = RegistratorListener<HangingPlaceEvent> l@{ event ->
|
val onHangingPlaceEvent = RegistratorListener<HangingPlaceEvent> l@{ event ->
|
||||||
val world = parcelProvider.getWorld(event.entity.world) ?: return@l
|
val world = parcelProvider.getWorld(event.entity.world) ?: return@l
|
||||||
val block = event.block.getRelative(event.blockFace)
|
val block = event.block.getRelative(event.blockFace)
|
||||||
if (!world.getParcelAt(block).canBuildN(event.player)) {
|
if (!canBuildOnArea(event.player, world.getParcelAt(block))) {
|
||||||
event.isCancelled = true
|
event.isCancelled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -479,16 +488,16 @@ class ParcelListeners(
|
|||||||
*/
|
*/
|
||||||
@field:ListenerMarker(priority = NORMAL)
|
@field:ListenerMarker(priority = NORMAL)
|
||||||
val onStructureGrowEvent = RegistratorListener<StructureGrowEvent> l@{ event ->
|
val onStructureGrowEvent = RegistratorListener<StructureGrowEvent> l@{ event ->
|
||||||
val (wo, ppa) = getWoAndPPa(event.location.block) ?: return@l
|
val (world, area) = getWorldAndArea(event.location.block) ?: return@l
|
||||||
if (ppa == null) {
|
if (area == null) {
|
||||||
event.isCancelled = true; return@l
|
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.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)
|
@field:ListenerMarker(priority = NORMAL)
|
||||||
val onItemSpawnEvent = RegistratorListener<ItemSpawnEvent> l@{ event ->
|
val onItemSpawnEvent = RegistratorListener<ItemSpawnEvent> l@{ event ->
|
||||||
val (wo, ppa) = getWoAndPPa(event.location.block) ?: return@l
|
val (_, area) = getWorldAndArea(event.location.block) ?: return@l
|
||||||
if (ppa == null) event.isCancelled = true
|
if (area == null) event.isCancelled = true
|
||||||
else entityTracker.track(event.entity, ppa)
|
else entityTracker.track(event.entity, area)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -521,8 +530,8 @@ class ParcelListeners(
|
|||||||
*/
|
*/
|
||||||
@field:ListenerMarker(priority = NORMAL)
|
@field:ListenerMarker(priority = NORMAL)
|
||||||
val onEntityTeleportEvent = RegistratorListener<EntityTeleportEvent> l@{ event ->
|
val onEntityTeleportEvent = RegistratorListener<EntityTeleportEvent> l@{ event ->
|
||||||
val (wo, ppa) = getWoAndPPa(event.from.block) ?: return@l
|
val (world, area) = getWorldAndArea(event.from.block) ?: return@l
|
||||||
if (ppa !== wo.getParcelAt(event.to)) {
|
if (area !== world.getParcelAt(event.to)) {
|
||||||
event.isCancelled = true
|
event.isCancelled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -533,11 +542,11 @@ class ParcelListeners(
|
|||||||
*/
|
*/
|
||||||
@field:ListenerMarker(priority = NORMAL)
|
@field:ListenerMarker(priority = NORMAL)
|
||||||
val onProjectileLaunchEvent = RegistratorListener<ProjectileLaunchEvent> l@{ event ->
|
val onProjectileLaunchEvent = RegistratorListener<ProjectileLaunchEvent> l@{ event ->
|
||||||
val (wo, ppa) = getWoAndPPa(event.entity.location.block) ?: return@l
|
val (_, area) = getWorldAndArea(event.entity.location.block) ?: return@l
|
||||||
if (ppa == null || (event.entity.shooter as? Player)?.let { !ppa.canBuildN(it) } == true) {
|
if (area == null || (event.entity.shooter as? Player)?.let { !canBuildOnArea(it, area) } == true) {
|
||||||
event.isCancelled = true
|
event.isCancelled = true
|
||||||
} else {
|
} else {
|
||||||
entityTracker.track(event.entity, ppa)
|
entityTracker.track(event.entity, area)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class WorldEditListener(val parcels: ParcelsPlugin, val worldEdit: WorldEdit) {
|
|||||||
|
|
||||||
private fun canBuild(x: Int, z: Int): Boolean {
|
private fun canBuild(x: Int, z: Int): Boolean {
|
||||||
world.getParcelAt(x, z)?.let { parcel ->
|
world.getParcelAt(x, z)?.let { parcel ->
|
||||||
if (parcel.canBuild(player, checkAdmin = false)) {
|
if (parcel.canBuildFast(player)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import io.dico.parcels2.Privilege.DEFAULT
|
|||||||
import kotlinx.coroutines.channels.SendChannel
|
import kotlinx.coroutines.channels.SendChannel
|
||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
|
|
||||||
object PrivilegesLocalT : PrivilegesTable<ParcelId>("parcels_added_local", ParcelsT)
|
object PrivilegesLocalT : PrivilegesTable<ParcelId>("parcels_privilege_local", ParcelsT)
|
||||||
object PrivilegesGlobalT : PrivilegesTable<PlayerProfile>("parcels_added_global", ProfilesT)
|
object PrivilegesGlobalT : PrivilegesTable<PlayerProfile>("parcels_privilege_global", ProfilesT)
|
||||||
|
|
||||||
object ParcelOptionsT : Table("parcel_options") {
|
object ParcelOptionsT : Table("parcel_options") {
|
||||||
val parcel_id = integer("parcel_id").primaryKey().references(ParcelsT.id, ReferenceOption.CASCADE)
|
val parcel_id = integer("parcel_id").primaryKey().references(ParcelsT.id, ReferenceOption.CASCADE)
|
||||||
|
|||||||
@@ -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 <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?.isNullOr(condition: T.() -> Boolean): Boolean = this == null || condition()
|
||||||
inline fun <T> T?.isPresentAnd(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? {
|
inline fun <T> T?.ifNullRun(block: () -> Unit): T? {
|
||||||
if (this == null) block()
|
if (this == null) block()
|
||||||
return this
|
return this
|
||||||
|
|||||||
@@ -13,10 +13,14 @@ inline val OfflinePlayer.uuid get() = uniqueId
|
|||||||
inline val OfflinePlayer.isValid
|
inline val OfflinePlayer.isValid
|
||||||
get() = isOnline() || hasPlayedBefore()
|
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.hasPermGamemodeBypass get() = hasPermission("parcels.admin.bypass.gamemode")
|
||||||
inline val Player.hasPermBuildAnywhere get() = hasPermission("parcels.admin.bypass.build")
|
inline val Player.hasPermBuildAnywhere get() = hasPermission(PERM_BUILD_ANYWHERE)
|
||||||
inline val Player.hasPermAdminManage get() = hasPermission("parcels.admin.manage")
|
inline val Player.hasPermAdminManage get() = hasPermission(PERM_ADMIN_MANAGE)
|
||||||
inline val Player.hasParcelHomeOthers get() = hasPermission("parcels.command.home.others")
|
inline val Player.hasParcelHomeOthers get() = hasPermission("parcels.command.home.others")
|
||||||
inline val Player.hasPermRandomSpecific get() = hasPermission("parcels.command.random.specific")
|
inline val Player.hasPermRandomSpecific get() = hasPermission("parcels.command.random.specific")
|
||||||
val Player.parcelLimit: Int
|
val Player.parcelLimit: Int
|
||||||
|
|||||||
Reference in New Issue
Block a user