summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDico <dico.karssiens@gmail.com>2018-09-27 02:58:06 +0100
committerDico <dico.karssiens@gmail.com>2018-09-27 02:58:06 +0100
commitcdaba0ebd5b48d1f2d4579c873d83fdf6ea1a074 (patch)
treecc3b3743e5908c25f530542b8bb8f6082cc01400
parentc486e99f1aa1cf02e3d5ffea4b13916010578cee (diff)
Fix privileges of *
-rw-r--r--dicore3/command/src/main/java/io/dico/dicore/command/predef/DefaultGroupCommand.java4
-rw-r--r--src/main/kotlin/io/dico/parcels2/Parcel.kt8
-rw-r--r--src/main/kotlin/io/dico/parcels2/PlayerProfile.kt5
-rw-r--r--src/main/kotlin/io/dico/parcels2/Privilege.kt122
-rw-r--r--src/main/kotlin/io/dico/parcels2/Privileges.kt64
-rw-r--r--src/main/kotlin/io/dico/parcels2/blockvisitor/RegionTraverser.kt6
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt9
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/CommandsAdminPrivilegesGlobal.kt110
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesGlobal.kt65
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesLocal.kt68
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt16
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/ParcelCommandReceivers.kt5
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt5
-rw-r--r--src/main/kotlin/io/dico/parcels2/defaultimpl/GlobalPrivilegesManagerImpl.kt23
-rw-r--r--src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt110
-rw-r--r--src/main/kotlin/io/dico/parcels2/listener/WorldEditListener.kt1
-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.kt13
18 files changed, 388 insertions, 250 deletions
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/predef/DefaultGroupCommand.java b/dicore3/command/src/main/java/io/dico/dicore/command/predef/DefaultGroupCommand.java
index 6b389e3..6c03d8e 100644
--- a/dicore3/command/src/main/java/io/dico/dicore/command/predef/DefaultGroupCommand.java
+++ b/dicore3/command/src/main/java/io/dico/dicore/command/predef/DefaultGroupCommand.java
@@ -17,6 +17,10 @@ public class DefaultGroupCommand extends PredefinedCommand<DefaultGroupCommand>
this.modifiable = modifiable;
}
+ public DefaultGroupCommand() {
+ this(true);
+ }
+
@Override
protected DefaultGroupCommand newModifiableInstance() {
return new DefaultGroupCommand(true);
diff --git a/src/main/kotlin/io/dico/parcels2/Parcel.kt b/src/main/kotlin/io/dico/parcels2/Parcel.kt
index 75f963f..22ec0df 100644
--- a/src/main/kotlin/io/dico/parcels2/Parcel.kt
+++ b/src/main/kotlin/io/dico/parcels2/Parcel.kt
@@ -38,7 +38,7 @@ interface Parcel : ParcelData, Privileges {
val homeLocation: Location get() = world.blockManager.getHomeLocation(id)
}
-interface ParcelData : PrivilegesMinimal {
+interface ParcelData : RawPrivileges {
var owner: PlayerProfile?
val lastClaimTime: DateTime?
var ownerSignOutdated: Boolean
@@ -60,12 +60,6 @@ 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 var interactableConfig: InteractableConfiguration = BitmaskInteractableConfiguration()
}
diff --git a/src/main/kotlin/io/dico/parcels2/PlayerProfile.kt b/src/main/kotlin/io/dico/parcels2/PlayerProfile.kt
index 53e2d76..ae73639 100644
--- a/src/main/kotlin/io/dico/parcels2/PlayerProfile.kt
+++ b/src/main/kotlin/io/dico/parcels2/PlayerProfile.kt
@@ -115,7 +115,10 @@ interface PlayerProfile {
}
object Star : BaseImpl(), Real {
- override val name: String = "*"
+ override val name get() = "*"
+ override val nameOrBukkitName get() = name
+ override val notNullName get() = name
+
// hopefully nobody will have this random UUID :)
override val uuid: UUID = UUID.fromString("7d09c4c6-117d-4f36-9778-c4d24618cee1")
diff --git a/src/main/kotlin/io/dico/parcels2/Privilege.kt b/src/main/kotlin/io/dico/parcels2/Privilege.kt
index 72878a9..bc16f77 100644
--- a/src/main/kotlin/io/dico/parcels2/Privilege.kt
+++ b/src/main/kotlin/io/dico/parcels2/Privilege.kt
@@ -1,12 +1,17 @@
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
+import io.dico.parcels2.Privilege.DEFAULT
+import java.util.Collections
+
+typealias PrivilegeKey = PlayerProfile.Real
+typealias PrivilegeMap = Map<PrivilegeKey, Privilege>
+typealias MutablePrivilegeMap = MutableMap<PrivilegeKey, Privilege>
+
+@Suppress("FunctionName")
+fun MutablePrivilegeMap(): MutablePrivilegeMap = hashMapOf()
+
+@Suppress("UNCHECKED_CAST")
+val EmptyPrivilegeMap = Collections.emptyMap<Any, Any>() as MutablePrivilegeMap
enum class Privilege(
val number: Int,
@@ -21,7 +26,7 @@ enum class Privilege(
ADMIN(-1, transient = true);
fun isDistanceGrEq(other: Privilege): Boolean =
- when { // used for example when disallowBuild is called and CAN_MANAGE is the privilege.
+ when {
other > DEFAULT -> this >= other
other == DEFAULT -> this == other
else -> this <= other
@@ -38,12 +43,6 @@ enum class Privilege(
return this
}
- /*
- fun canEnter() = this >= BANNED
- fun canBuild() = this >= CAN_BUILD
- fun canManage() = this >= CAN_MANAGE
- */
-
companion object {
fun getByNumber(id: Int) =
when (id) {
@@ -56,95 +55,44 @@ enum class Privilege(
}
}
-typealias PrivilegeKey = PlayerProfile.Real
-typealias MutablePrivilegeMap = MutableMap<PrivilegeKey, Privilege>
-typealias PrivilegeMap = Map<PrivilegeKey, Privilege>
-
-@Suppress("FunctionName")
-fun MutablePrivilegeMap(): MutablePrivilegeMap = hashMapOf()
-
-interface PrivilegesMinimal {
+interface RawPrivileges {
val privilegeMap: 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): Privilege {
- val key = player.privilegeKey
- return if (key == keyOfOwner) OWNER
- else getStoredPrivilege(key)
- }
-
- 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
+ fun getRawStoredPrivilege(key: PrivilegeKey): Privilege
+ fun setRawStoredPrivilege(key: PrivilegeKey, privilege: Privilege): Boolean
}
-enum class PrivilegeChangeResult {
- SUCCESS, FAIL, FAIL_OWNER
-}
+open class PrivilegesHolder(override var privilegeMap: MutablePrivilegeMap = EmptyPrivilegeMap) : RawPrivileges {
+ private var _privilegeOfStar: Privilege = DEFAULT
-val OfflinePlayer.privilegeKey: PrivilegeKey
- inline get() = PlayerProfile.nameless(this)
+ override var privilegeOfStar: Privilege
+ get() = _privilegeOfStar
+ set(value) = run { _privilegeOfStar = value }
-open class PrivilegesHolder(override var privilegeMap: MutablePrivilegeMap = MutablePrivilegeMap()) : PrivilegesMinimal {
- private var privilegeOfStar: Privilege = DEFAULT
+ protected val isEmpty
+ inline get() = privilegeMap === EmptyPrivilegeMap
- override fun getStoredPrivilege(key: PrivilegeKey) =
- if (key.isStar) privilegeOfStar
- else privilegeMap.getOrDefault(key, privilegeOfStar)
+ override fun getRawStoredPrivilege(key: PrivilegeKey) =
+ if (key.isStar) _privilegeOfStar
+ else privilegeMap.getOrDefault(key, _privilegeOfStar)
- override fun setStoredPrivilege(key: PrivilegeKey, privilege: Privilege): Boolean {
+ override fun setRawStoredPrivilege(key: PrivilegeKey, privilege: Privilege): Boolean {
privilege.requireNonTransient()
if (key.isStar) {
- if (privilegeOfStar == privilege) return false
- privilegeOfStar = privilege
+ if (_privilegeOfStar == privilege) return false
+ _privilegeOfStar = privilege
return true
}
+ if (isEmpty) {
+ if (privilege == DEFAULT) return false
+ privilegeMap = MutablePrivilegeMap()
+ }
+
return if (privilege == DEFAULT) privilegeMap.remove(key) != null
else privilegeMap.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
new file mode 100644
index 0000000..632f1a4
--- /dev/null
+++ b/src/main/kotlin/io/dico/parcels2/Privileges.kt
@@ -0,0 +1,64 @@
+package io.dico.parcels2
+
+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
+
+interface Privileges : RawPrivileges {
+ val keyOfOwner: PlayerProfile.Real?
+
+ fun getStoredPrivilege(key: PrivilegeKey): Privilege {
+ return if (key == keyOfOwner) Privilege.OWNER
+ else getRawStoredPrivilege(key)
+ }
+
+ override var privilegeOfStar: Privilege
+ get() = getStoredPrivilege(PlayerProfile.Star)
+ set(value) {
+ setRawStoredPrivilege(PlayerProfile.Star, value)
+ }
+}
+
+val OfflinePlayer.privilegeKey: PrivilegeKey
+ inline get() = PlayerProfile.nameless(this)
+
+fun Privileges.getEffectivePrivilege(player: OfflinePlayer, adminPerm: String): Privilege =
+ if (player is Player && player.hasPermission(adminPerm)) Privilege.ADMIN
+ else getStoredPrivilege(player.privilegeKey)
+
+fun Privileges.canManage(player: OfflinePlayer) = getEffectivePrivilege(player, PERM_ADMIN_MANAGE) >= Privilege.CAN_MANAGE
+fun Privileges.canManageFast(player: OfflinePlayer) = getStoredPrivilege(player.privilegeKey) >= Privilege.CAN_MANAGE
+fun Privileges.canBuild(player: OfflinePlayer) = getEffectivePrivilege(player, PERM_BUILD_ANYWHERE) >= Privilege.CAN_BUILD
+fun Privileges.canBuildFast(player: OfflinePlayer) = getStoredPrivilege(player.privilegeKey) >= Privilege.CAN_BUILD
+fun Privileges.canEnter(player: OfflinePlayer) = getEffectivePrivilege(player, PERM_BAN_BYPASS) >= Privilege.DEFAULT
+fun Privileges.canEnterFast(player: OfflinePlayer) = getStoredPrivilege(player.privilegeKey) >= Privilege.DEFAULT
+
+enum class PrivilegeChangeResult {
+ SUCCESS, FAIL, FAIL_OWNER
+}
+
+fun Privileges.changePrivilege(key: PrivilegeKey, positive: Boolean, update: Privilege): PrivilegeChangeResult =
+ when {
+ key == keyOfOwner -> FAIL_OWNER
+ getRawStoredPrivilege(key).isChangeInDirection(positive, update) && setRawStoredPrivilege(key, update) -> SUCCESS
+ else -> FAIL
+ }
+
+fun Privileges.allowManage(key: PrivilegeKey) = changePrivilege(key, true, Privilege.CAN_MANAGE)
+fun Privileges.disallowManage(key: PrivilegeKey) = changePrivilege(key, false, Privilege.CAN_BUILD)
+fun Privileges.allowBuild(key: PrivilegeKey) = changePrivilege(key, true, Privilege.CAN_BUILD)
+fun Privileges.disallowBuild(key: PrivilegeKey) = changePrivilege(key, false, Privilege.DEFAULT)
+fun Privileges.allowEnter(key: PrivilegeKey) = changePrivilege(key, true, Privilege.DEFAULT)
+fun Privileges.disallowEnter(key: PrivilegeKey) = changePrivilege(key, false, Privilege.BANNED)
+
+interface GlobalPrivileges : RawPrivileges, 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/blockvisitor/RegionTraverser.kt b/src/main/kotlin/io/dico/parcels2/blockvisitor/RegionTraverser.kt
index c49faa2..feab318 100644
--- a/src/main/kotlin/io/dico/parcels2/blockvisitor/RegionTraverser.kt
+++ b/src/main/kotlin/io/dico/parcels2/blockvisitor/RegionTraverser.kt
@@ -83,9 +83,9 @@ sealed class RegionTraverser {
private fun slice(region: Region, atY: Int): Pair<Region, Region?> {
if (atY < region.size.y + 1) {
- val first = Region(region.origin, region.size.withY(atY + 1))
- val second = Region(region.origin.withY(atY), region.size.addY(-atY - 1))
- return first to second
+ val bottom = Region(region.origin, region.size.withY(atY + 1))
+ val top = Region(region.origin.withY(atY + 1), region.size.addY(-atY - 1))
+ return bottom to top
}
return region to null
}
diff --git a/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt b/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt
index 6d62729..a660fc0 100644
--- a/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt
@@ -4,6 +4,8 @@ import io.dico.dicore.command.*
import io.dico.parcels2.ParcelWorld
import io.dico.parcels2.ParcelsPlugin
import io.dico.parcels2.PlayerProfile
+import io.dico.parcels2.PlayerProfile.*
+import io.dico.parcels2.PrivilegeKey
import io.dico.parcels2.blockvisitor.Worker
import io.dico.parcels2.util.ext.hasPermAdminManage
import io.dico.parcels2.util.ext.parcelLimit
@@ -37,6 +39,13 @@ abstract class AbstractParcelCommands(val plugin: ParcelsPlugin) : ICommandRecei
}
}
+ protected suspend fun toPrivilegeKey(profile: PlayerProfile): PrivilegeKey = when (profile) {
+ is Real -> profile
+ is Unresolved -> profile.tryResolveSuspendedly(plugin.storage)
+ ?: throw CommandException()
+ else -> throw CommandException()
+ }
+
protected fun areYouSureMessage(context: ExecutionContext) = "Are you sure? You cannot undo this action!\n" +
"Run \"/${context.route.joinToString(" ")} -sure\" if you want to go through with this."
diff --git a/src/main/kotlin/io/dico/parcels2/command/CommandsAdminPrivilegesGlobal.kt b/src/main/kotlin/io/dico/parcels2/command/CommandsAdminPrivilegesGlobal.kt
new file mode 100644
index 0000000..1bd42e8
--- /dev/null
+++ b/src/main/kotlin/io/dico/parcels2/command/CommandsAdminPrivilegesGlobal.kt
@@ -0,0 +1,110 @@
+@file:Suppress("NON_EXHAUSTIVE_WHEN")
+
+package io.dico.parcels2.command
+
+import io.dico.dicore.command.ExecutionContext
+import io.dico.dicore.command.Validate
+import io.dico.dicore.command.annotation.Cmd
+import io.dico.dicore.command.annotation.Desc
+import io.dico.parcels2.*
+import io.dico.parcels2.PrivilegeChangeResult.*
+import io.dico.parcels2.util.ext.PERM_ADMIN_MANAGE
+import io.dico.parcels2.util.ext.hasPermAdminManage
+import org.bukkit.OfflinePlayer
+import org.bukkit.command.CommandSender
+import org.bukkit.entity.Player
+
+class CommandsAdminPrivilegesGlobal(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
+ private val data
+ inline get() = plugin.globalPrivileges
+
+ private fun checkContext(context: ExecutionContext, owner: OfflinePlayer): OfflinePlayer {
+ val sender = context.sender
+ if (sender !== owner) {
+ Validate.isAuthorized(sender, PERM_ADMIN_MANAGE)
+ }
+ return owner
+ }
+
+ @Cmd("entrust")
+ @Desc(
+ "Allows a player to manage globally",
+ shortVersion = "allows a player to manage globally"
+ )
+ suspend fun cmdEntrust(context: ExecutionContext, owner: OfflinePlayer, player: PlayerProfile): Any? =
+ when (data[checkContext(context, owner)].allowManage(toPrivilegeKey(player))) {
+ FAIL_OWNER -> err("The target cannot be the owner themselves")
+ FAIL -> err("${player.name} is already allowed to manage globally")
+ SUCCESS -> "${player.name} is now allowed to manage globally"
+ }
+
+ @Cmd("distrust")
+ @Desc(
+ "Disallows a player to manage globally,",
+ "they will still be able to build",
+ shortVersion = "disallows a player to manage globally"
+ )
+ suspend fun cmdDistrust(context: ExecutionContext, owner: OfflinePlayer, player: PlayerProfile): Any? =
+ when (data[checkContext(context, owner)].disallowManage(toPrivilegeKey(player))) {
+ FAIL_OWNER -> err("The target cannot be the owner themselves")
+ FAIL -> err("${player.name} is not currently allowed to manage globally")
+ SUCCESS -> "${player.name} is not allowed to manage globally anymore"
+ }
+
+ @Cmd("allow", aliases = ["add", "permit"])
+ @Desc(
+ "Globally allows a player to build on all",
+ "the parcels that you own.",
+ shortVersion = "globally allows a player to build on your parcels"
+ )
+ suspend fun cmdAllow(context: ExecutionContext, owner: OfflinePlayer, player: PlayerProfile): Any? =
+ when (data[checkContext(context, owner)].allowBuild(toPrivilegeKey(player))) {
+ FAIL_OWNER -> err("The target cannot be the owner themselves")
+ FAIL -> err("${player.name} is already allowed globally")
+ SUCCESS -> "${player.name} is now allowed to build globally"
+ }
+
+ @Cmd("disallow", aliases = ["remove", "forbid"])
+ @Desc(
+ "Globally disallows a player to build on",
+ "the parcels that you own.",
+ "If the player is allowed to build on specific",
+ "parcels, they can still build there.",
+ shortVersion = "globally disallows a player to build on your parcels"
+ )
+ suspend fun cmdDisallow(context: ExecutionContext, owner: OfflinePlayer, player: PlayerProfile): Any? =
+ when (data[checkContext(context, owner)].disallowBuild(toPrivilegeKey(player))) {
+ FAIL_OWNER -> err("The target cannot be the owner themselves")
+ FAIL -> err("${player.name} is not currently allowed globally")
+ SUCCESS -> "${player.name} is not allowed to build globally anymore"
+ }
+
+ @Cmd("ban", aliases = ["deny"])
+ @Desc(
+ "Globally bans a player from all the parcels",
+ "that you own, making them unable to enter.",
+ shortVersion = "globally bans a player from your parcels"
+ )
+ suspend fun cmdBan(context: ExecutionContext, owner: OfflinePlayer, player: PlayerProfile): Any? =
+ when (data[checkContext(context, owner)].disallowEnter(toPrivilegeKey(player))) {
+ FAIL_OWNER -> err("The target cannot be the owner themselves")
+ FAIL -> err("${player.name} is already banned globally")
+ SUCCESS -> "${player.name} is now banned globally"
+ }
+
+ @Cmd("unban", aliases = ["undeny"])
+ @Desc(
+ "Globally unbans a player from all the parcels",
+ "that you own, they can enter again.",
+ "If the player is banned from specific parcels,",
+ "they will still be banned there.",
+ shortVersion = "globally unbans a player from your parcels"
+ )
+ suspend fun cmdUnban(context: ExecutionContext, owner: OfflinePlayer, player: PlayerProfile): Any? =
+ when (data[checkContext(context, owner)].allowEnter(toPrivilegeKey(player))) {
+ FAIL_OWNER -> err("The target cannot be the owner themselves")
+ FAIL -> err("${player.name} is not currently banned globally")
+ SUCCESS -> "${player.name} is not banned globally anymore"
+ }
+
+} \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesGlobal.kt b/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesGlobal.kt
index e225cb5..9e3ac23 100644
--- a/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesGlobal.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesGlobal.kt
@@ -1,29 +1,21 @@
-@file:Suppress("NON_EXHAUSTIVE_WHEN")
-
package io.dico.parcels2.command
+import io.dico.dicore.command.ExecutionContext
import io.dico.dicore.command.annotation.Cmd
import io.dico.dicore.command.annotation.Desc
import io.dico.parcels2.ParcelsPlugin
-import io.dico.parcels2.PrivilegeChangeResult.*
-import org.bukkit.OfflinePlayer
+import io.dico.parcels2.PlayerProfile
import org.bukkit.entity.Player
-class CommandsPrivilegesGlobal(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
- private val data
- inline get() = plugin.globalPrivileges
-
+class CommandsPrivilegesGlobal(plugin: ParcelsPlugin,
+ val adminVersion: CommandsAdminPrivilegesGlobal) : AbstractParcelCommands(plugin) {
@Cmd("entrust")
@Desc(
- "Allows a player to manage this parcel",
- shortVersion = "allows a player to manage this parcel"
+ "Allows a player to manage globally",
+ shortVersion = "allows a player to manage globally"
)
- fun cmdEntrust(sender: Player, player: OfflinePlayer): Any? =
- when (data[sender].allowManage(player)) {
- FAIL_OWNER -> err("The target cannot be yourself")
- FAIL -> err("${player.name} is already allowed to manage globally")
- SUCCESS -> "${player.name} is now allowed to manage globally"
- }
+ suspend fun cmdEntrust(sender: Player, context: ExecutionContext, player: PlayerProfile) =
+ adminVersion.cmdEntrust(context, sender, player)
@Cmd("distrust")
@Desc(
@@ -31,12 +23,8 @@ class CommandsPrivilegesGlobal(plugin: ParcelsPlugin) : AbstractParcelCommands(p
"they will still be able to build",
shortVersion = "disallows a player to manage globally"
)
- fun cmdDistrust(sender: Player, player: OfflinePlayer): Any? =
- when (data[sender].disallowManage(player)) {
- FAIL_OWNER -> err("The target cannot be yourself")
- FAIL -> err("${player.name} is not currently allowed to manage globally")
- SUCCESS -> "${player.name} is not allowed to manage globally anymore"
- }
+ suspend fun cmdDistrust(sender: Player, context: ExecutionContext, player: PlayerProfile) =
+ adminVersion.cmdDistrust(context, sender, player)
@Cmd("allow", aliases = ["add", "permit"])
@Desc(
@@ -44,12 +32,8 @@ class CommandsPrivilegesGlobal(plugin: ParcelsPlugin) : AbstractParcelCommands(p
"the parcels that you own.",
shortVersion = "globally allows a player to build on your parcels"
)
- fun cmdAllow(sender: Player, player: OfflinePlayer): Any? =
- when (data[sender].allowBuild(player)) {
- FAIL_OWNER -> err("The target cannot be yourself")
- FAIL -> err("${player.name} is already allowed globally")
- SUCCESS -> "${player.name} is now allowed to build on all your parcels"
- }
+ suspend fun cmdAllow(sender: Player, context: ExecutionContext, player: PlayerProfile) =
+ adminVersion.cmdAllow(context, sender, player)
@Cmd("disallow", aliases = ["remove", "forbid"])
@Desc(
@@ -59,12 +43,8 @@ class CommandsPrivilegesGlobal(plugin: ParcelsPlugin) : AbstractParcelCommands(p
"parcels, they can still build there.",
shortVersion = "globally disallows a player to build on your parcels"
)
- fun cmdDisallow(sender: Player, player: OfflinePlayer): Any? =
- when (data[sender].disallowBuild(player)) {
- FAIL_OWNER -> err("The target cannot be yourself")
- FAIL -> err("${player.name} is not currently allowed globally")
- SUCCESS -> "${player.name} is not allowed to build on all your parcels anymore"
- }
+ suspend fun cmdDisallow(sender: Player, context: ExecutionContext, player: PlayerProfile) =
+ adminVersion.cmdDisallow(context, sender, player)
@Cmd("ban", aliases = ["deny"])
@Desc(
@@ -72,12 +52,8 @@ class CommandsPrivilegesGlobal(plugin: ParcelsPlugin) : AbstractParcelCommands(p
"that you own, making them unable to enter.",
shortVersion = "globally bans a player from your parcels"
)
- fun cmdBan(sender: Player, player: OfflinePlayer): Any? =
- when (data[sender].ban(player)) {
- FAIL_OWNER -> err("The target cannot be yourself")
- FAIL -> err("${player.name} is already banned from all your parcels")
- SUCCESS -> "${player.name} is now banned from all your parcels"
- }
+ suspend fun cmdBan(sender: Player, context: ExecutionContext, player: PlayerProfile) =
+ adminVersion.cmdBan(context, sender, player)
@Cmd("unban", aliases = ["undeny"])
@Desc(
@@ -87,11 +63,6 @@ class CommandsPrivilegesGlobal(plugin: ParcelsPlugin) : AbstractParcelCommands(p
"they will still be banned there.",
shortVersion = "globally unbans a player from your parcels"
)
- fun cmdUnban(sender: Player, player: OfflinePlayer): Any? =
- when (data[sender].unban(player)) {
- FAIL_OWNER -> err("The target cannot be yourself")
- FAIL -> err("${player.name} is not currently banned from all your parcels")
- SUCCESS -> "${player.name} is not banned from all your parcels anymore"
- }
-
+ suspend fun cmdUnban(sender: Player, context: ExecutionContext, player: PlayerProfile) =
+ adminVersion.cmdUnban(context, sender, player)
} \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesLocal.kt b/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesLocal.kt
index 5202683..f347f06 100644
--- a/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesLocal.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesLocal.kt
@@ -3,20 +3,22 @@ package io.dico.parcels2.command
import io.dico.dicore.command.Validate
import io.dico.dicore.command.annotation.Cmd
import io.dico.dicore.command.annotation.Desc
-import io.dico.parcels2.ParcelsPlugin
-import io.dico.parcels2.Privilege
+import io.dico.parcels2.*
import io.dico.parcels2.PrivilegeChangeResult.*
+import io.dico.parcels2.util.ext.PERM_ADMIN_MANAGE
import io.dico.parcels2.util.ext.hasPermAdminManage
-import org.bukkit.OfflinePlayer
import org.bukkit.entity.Player
class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
- private fun ParcelScope.checkPrivilege(sender: Player, player: OfflinePlayer) {
- if (!sender.hasPermAdminManage) {
- Validate.isTrue(parcel.owner != null, "This parcel is unowned")
- Validate.isTrue(parcel.privilege(sender) > parcel.privilege(player), "You may not change the privilege of ${player.name}")
- }
+ private fun ParcelScope.checkPrivilege(sender: Player, key: PrivilegeKey) {
+ val senderPrivilege = parcel.getEffectivePrivilege(sender, PERM_ADMIN_MANAGE)
+ val targetPrivilege = parcel.getStoredPrivilege(key)
+ Validate.isTrue(senderPrivilege > targetPrivilege, "You may not change the privilege of ${key.notNullName}")
+ }
+
+ private fun ParcelScope.checkOwned(sender: Player) {
+ Validate.isTrue(parcel.owner != null || sender.hasPermAdminManage, "This parcel is unowned")
}
@Cmd("entrust")
@@ -25,10 +27,11 @@ class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(pl
shortVersion = "allows a player to manage this parcel"
)
@RequireParcelPrivilege(Privilege.OWNER)
- fun ParcelScope.cmdEntrust(sender: Player, player: OfflinePlayer): Any? {
- Validate.isTrue(parcel.owner != null || sender.hasPermAdminManage, "This parcel is unowned")
+ suspend fun ParcelScope.cmdEntrust(sender: Player, player: PlayerProfile): Any? {
+ checkOwned(sender)
- return when (parcel.allowManage(player)) {
+ val key = toPrivilegeKey(player)
+ return when (parcel.allowManage(key)) {
FAIL_OWNER -> err("The target already owns the parcel")
FAIL -> err("${player.name} is already allowed to manage this parcel")
SUCCESS -> "${player.name} is now allowed to manage this parcel"
@@ -42,10 +45,11 @@ class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(pl
shortVersion = "disallows a player to manage this parcel"
)
@RequireParcelPrivilege(Privilege.OWNER)
- fun ParcelScope.cmdDistrust(sender: Player, player: OfflinePlayer): Any? {
- Validate.isTrue(parcel.owner != null || sender.hasPermAdminManage, "This parcel is unowned")
+ suspend fun ParcelScope.cmdDistrust(sender: Player, player: PlayerProfile): Any? {
+ checkOwned(sender)
- return when (parcel.disallowManage(player)) {
+ val key = toPrivilegeKey(player)
+ return when (parcel.disallowManage(key)) {
FAIL_OWNER -> err("The target owns the parcel and can't be distrusted")
FAIL -> err("${player.name} is not currently allowed to manage this parcel")
SUCCESS -> "${player.name} is not allowed to manage this parcel anymore"
@@ -58,10 +62,13 @@ class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(pl
shortVersion = "allows a player to build on this parcel"
)
@RequireParcelPrivilege(Privilege.CAN_MANAGE)
- fun ParcelScope.cmdAllow(sender: Player, player: OfflinePlayer): Any? {
- checkPrivilege(sender, player)
+ suspend fun ParcelScope.cmdAllow(sender: Player, player: PlayerProfile): Any? {
+ checkOwned(sender)
+
+ val key = toPrivilegeKey(player)
+ checkPrivilege(sender, key)
- return when (parcel.allowBuild(player)) {
+ return when (parcel.allowBuild(key)) {
FAIL_OWNER -> err("The target already owns the parcel")
FAIL -> err("${player.name} is already allowed to build on this parcel")
SUCCESS -> "${player.name} is now allowed to build on this parcel"
@@ -75,10 +82,13 @@ class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(pl
shortVersion = "disallows a player to build on this parcel"
)
@RequireParcelPrivilege(Privilege.CAN_MANAGE)
- fun ParcelScope.cmdDisallow(sender: Player, player: OfflinePlayer): Any? {
- checkPrivilege(sender, player)
+ suspend fun ParcelScope.cmdDisallow(sender: Player, player: PlayerProfile): Any? {
+ checkOwned(sender)
+
+ val key = toPrivilegeKey(player)
+ checkPrivilege(sender, key)
- return when (parcel.disallowBuild(player)) {
+ return when (parcel.disallowBuild(key)) {
FAIL_OWNER -> err("The target owns the parcel")
FAIL -> err("${player.name} is not currently allowed to build on this parcel")
SUCCESS -> "${player.name} is not allowed to build on this parcel anymore"
@@ -92,10 +102,13 @@ class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(pl
shortVersion = "bans a player from this parcel"
)
@RequireParcelPrivilege(Privilege.CAN_MANAGE)
- fun ParcelScope.cmdBan(sender: Player, player: OfflinePlayer): Any? {
- checkPrivilege(sender, player)
+ suspend fun ParcelScope.cmdBan(sender: Player, player: PlayerProfile): Any? {
+ checkOwned(sender)
- return when (parcel.disallowBuild(player)) {
+ val key = toPrivilegeKey(player)
+ checkPrivilege(sender, key)
+
+ return when (parcel.disallowEnter(key)) {
FAIL_OWNER -> err("The target owns the parcel")
FAIL -> err("${player.name} is already banned from this parcel")
SUCCESS -> "${player.name} is now banned from this parcel"
@@ -109,10 +122,13 @@ class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(pl
shortVersion = "unbans a player from this parcel"
)
@RequireParcelPrivilege(Privilege.CAN_MANAGE)
- fun ParcelScope.cmdUnban(sender: Player, player: OfflinePlayer): Any? {
- checkPrivilege(sender, player)
+ suspend fun ParcelScope.cmdUnban(sender: Player, player: PlayerProfile): Any? {
+ checkOwned(sender)
+
+ val key = toPrivilegeKey(player)
+ checkPrivilege(sender, key)
- return when (parcel.disallowBuild(player)) {
+ return when (parcel.allowEnter(key)) {
FAIL_OWNER -> err("The target owns the parcel")
FAIL -> err("${player.name} is not currently banned from this parcel")
SUCCESS -> "${player.name} is not banned from this parcel anymore"
diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt
index e7d8663..40e5253 100644
--- a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt
@@ -1,10 +1,13 @@
package io.dico.parcels2.command
import io.dico.dicore.command.*
+import io.dico.dicore.command.predef.DefaultGroupCommand
import io.dico.dicore.command.registration.reflect.ReflectiveRegistration
import io.dico.parcels2.Interactables
import io.dico.parcels2.ParcelsPlugin
import io.dico.parcels2.logger
+import io.dico.parcels2.util.ext.hasPermAdminManage
+import org.bukkit.command.CommandSender
import java.util.LinkedList
import java.util.Queue
@@ -37,12 +40,19 @@ fun getParcelCommands(plugin: ParcelsPlugin): ICommandDispatcher = CommandBuilde
}
}
+ val adminPrivilegesGlobal = CommandsAdminPrivilegesGlobal(plugin)
+
group("global", "g") {
- registerCommands(CommandsPrivilegesGlobal(plugin))
+ registerCommands(CommandsPrivilegesGlobal(plugin, adminVersion = adminPrivilegesGlobal))
}
group("admin", "a") {
+ setCommand(AdminGroupCommand())
registerCommands(CommandsAdmin(plugin))
+
+ group("global", "g") {
+ registerCommands(adminPrivilegesGlobal)
+ }
}
if (!logger.isDebugEnabled) return@group
@@ -118,3 +128,7 @@ class SpecialCommandAddress : ChildCommandAddress() {
}
}
+
+private class AdminGroupCommand : DefaultGroupCommand() {
+ override fun isVisibleTo(sender: CommandSender) = sender.hasPermAdminManage
+}
diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandReceivers.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandReceivers.kt
index 0ef5264..8f6dabc 100644
--- a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandReceivers.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandReceivers.kt
@@ -4,10 +4,7 @@ import io.dico.dicore.command.CommandException
import io.dico.dicore.command.ExecutionContext
import io.dico.dicore.command.ICommandReceiver
import io.dico.dicore.command.Validate
-import io.dico.parcels2.Parcel
-import io.dico.parcels2.ParcelProvider
-import io.dico.parcels2.ParcelWorld
-import io.dico.parcels2.Privilege
+import io.dico.parcels2.*
import io.dico.parcels2.Privilege.*
import io.dico.parcels2.util.ext.hasPermAdminManage
import io.dico.parcels2.util.ext.uuid
diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt
index e7c4e48..8beef7f 100644
--- a/src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt
@@ -4,10 +4,7 @@ import io.dico.dicore.command.CommandException
import io.dico.dicore.command.parameter.ArgumentBuffer
import io.dico.dicore.command.parameter.Parameter
import io.dico.dicore.command.parameter.type.ParameterType
-import io.dico.parcels2.Parcel
-import io.dico.parcels2.ParcelProvider
-import io.dico.parcels2.ParcelWorld
-import io.dico.parcels2.PlayerProfile
+import io.dico.parcels2.*
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
diff --git a/src/main/kotlin/io/dico/parcels2/defaultimpl/GlobalPrivilegesManagerImpl.kt b/src/main/kotlin/io/dico/parcels2/defaultimpl/GlobalPrivilegesManagerImpl.kt
index 2324fac..769cee6 100644
--- a/src/main/kotlin/io/dico/parcels2/defaultimpl/GlobalPrivilegesManagerImpl.kt
+++ b/src/main/kotlin/io/dico/parcels2/defaultimpl/GlobalPrivilegesManagerImpl.kt
@@ -13,27 +13,16 @@ class GlobalPrivilegesManagerImpl(val plugin: ParcelsPlugin) : GlobalPrivilegesM
return map[owner] ?: GlobalPrivilegesImpl(owner).also { map[owner] = it }
}
- private inner class GlobalPrivilegesImpl(
- override val keyOfOwner: PlayerProfile.Real,
- data: MutablePrivilegeMap = emptyData
- ) : PrivilegesHolder(data), GlobalPrivileges {
+ private inner class GlobalPrivilegesImpl(override val keyOfOwner: PlayerProfile.Real) : PrivilegesHolder(), GlobalPrivileges {
+ override var privilegeOfStar: Privilege
+ get() = super<GlobalPrivileges>.privilegeOfStar
+ set(value) = run { super<GlobalPrivileges>.privilegeOfStar = value }
- private inline var data get() = privilegeMap; set(value) = run { privilegeMap = value }
- private inline val isEmpty get() = data === emptyData
-
- override fun setStoredPrivilege(key: PrivilegeKey, privilege: Privilege): Boolean {
- if (isEmpty) {
- if (privilege == Privilege.DEFAULT) return false
- data = mutableMapOf()
- }
- return super.setStoredPrivilege(key, privilege).alsoIfTrue {
+ override fun setRawStoredPrivilege(key: PrivilegeKey, privilege: Privilege): Boolean {
+ return super.setRawStoredPrivilege(key, privilege).alsoIfTrue {
plugin.storage.setGlobalPrivilege(keyOfOwner, key, privilege)
}
}
}
- private companion object {
- val emptyData = Collections.emptyMap<Any, Any>() as MutablePrivilegeMap
- }
-
} \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt
index bfaeb09..243ec19 100644
--- a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt
+++ b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt
@@ -6,7 +6,6 @@ import io.dico.parcels2.Privilege.*
import io.dico.parcels2.util.Vec2i
import io.dico.parcels2.util.ext.alsoIfTrue
import org.bukkit.Material
-import org.bukkit.OfflinePlayer
import org.joda.time.DateTime
import java.util.concurrent.atomic.AtomicInteger
@@ -36,25 +35,19 @@ class ParcelImpl(
world.storage.setParcelData(this, null)
}
- override val privilegeMap: PrivilegeMap get() = data.privilegeMap
- 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 var owner: PlayerProfile?
+ get() = data.owner
+ set(value) {
+ if (data.owner != value) {
+ world.storage.setParcelOwner(this, value)
+ world.blockManager.setOwnerBlock(this, value)
+ data.owner = value
+ }
}
- }
-
- 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 val globalPrivileges: GlobalPrivileges?
- get() = keyOfOwner?.let { world.globalPrivileges[it] }
-
- override val lastClaimTime: DateTime? get() = data.lastClaimTime
+ override val lastClaimTime: DateTime?
+ get() = data.lastClaimTime
override var ownerSignOutdated: Boolean
get() = data.ownerSignOutdated
@@ -65,21 +58,32 @@ class ParcelImpl(
}
}
- override var owner: PlayerProfile?
- get() = data.owner
- set(value) {
- if (data.owner != value) {
- world.storage.setParcelOwner(this, value)
- world.blockManager.setOwnerBlock(this, value)
- data.owner = value
- }
+
+ override val privilegeMap: PrivilegeMap
+ get() = data.privilegeMap
+
+ override val globalPrivileges: GlobalPrivileges?
+ get() = keyOfOwner?.let { world.globalPrivileges[it] }
+
+ override fun getRawStoredPrivilege(key: PrivilegeKey) = data.getRawStoredPrivilege(key)
+
+ override fun setRawStoredPrivilege(key: PrivilegeKey, privilege: Privilege) =
+ data.setRawStoredPrivilege(key, privilege).alsoIfTrue {
+ world.storage.setLocalPrivilege(this, key, privilege)
}
+ override fun getStoredPrivilege(key: PrivilegeKey): Privilege =
+ super.getStoredPrivilege(key).takeIf { it != DEFAULT }
+ ?: globalPrivileges?.getStoredPrivilege(key)
+ ?: DEFAULT
+
+
+ private var _interactableConfig: InteractableConfiguration? = null
+
private fun updateInteractableConfigStorage() {
world.storage.setParcelOptionsInteractConfig(this, data.interactableConfig)
}
- private var _interactableConfig: InteractableConfiguration? = null
override var interactableConfig: InteractableConfiguration
get() {
if (_interactableConfig == null) {
@@ -103,6 +107,7 @@ class ParcelImpl(
}
}
+
private var blockVisitors = AtomicInteger(0)
override suspend fun withBlockVisitorPermit(block: suspend () -> Unit) {
@@ -117,9 +122,6 @@ class ParcelImpl(
override fun toString() = toStringExt()
}
-private operator fun Formatting.plus(other: Formatting) = toString() + other
-private operator fun Formatting.plus(other: String) = toString() + other
-
private object ParcelInfoStringComputer {
val infoStringColor1 = Formatting.GREEN
val infoStringColor2 = Formatting.AQUA
@@ -148,20 +150,34 @@ private object ParcelInfoStringComputer {
}, value)
}
- private fun StringBuilder.appendAddedList(local: PrivilegeMap, global: PrivilegeMap, privilege: Privilege, fieldName: String) {
- // local takes precedence over global
+ private fun processPrivileges(local: RawPrivileges, global: RawPrivileges?,
+ privilege: Privilege): Pair<LinkedHashMap<PrivilegeKey, Privilege>, Int> {
+ val map = linkedMapOf<PrivilegeKey, Privilege>()
+ local.privilegeOfStar.takeIf { it != DEFAULT }?.let { map[PlayerProfile.Star] = it }
+ map.values.retainAll { it.isDistanceGrEq(privilege) }
+ val localCount = map.size
+
+ if (global != null) {
+ global.privilegeMap.forEach {
+ if (it.value.isDistanceGrEq(privilege))
+ map.putIfAbsent(it.key, it.value)
+ }
+
+ global.privilegeOfStar.takeIf { it != DEFAULT && it.isDistanceGrEq(privilege) }
+ ?.let { map.putIfAbsent(PlayerProfile.Star, it) }
+ }
- val localFiltered = local.filterValues { it.isDistanceGrEq(privilege) }
- // global keys are dropped here when merged with the local ones
- val all = localFiltered + global.filterValues { it.isDistanceGrEq(privilege) }
- if (all.isEmpty()) return
+ return map to localCount
+ }
- appendFieldWithCount(fieldName, all.size) {
- val separator = "$infoStringColor1, $infoStringColor2"
+ private fun StringBuilder.appendAddedList(local: RawPrivileges, global: RawPrivileges?, privilege: Privilege, fieldName: String) {
+ val (map, localCount) = processPrivileges(local, global, privilege)
+ if (map.isEmpty()) return
+ appendFieldWithCount(fieldName, map.size) {
// first [localCount] entries are local
- val localCount = localFiltered.size
- val iterator = all.iterator()
+ val separator = "$infoStringColor1, $infoStringColor2"
+ val iterator = map.iterator()
if (localCount != 0) {
appendPrivilegeEntry(false, iterator.next().toPair())
@@ -185,17 +201,17 @@ private object ParcelInfoStringComputer {
private fun StringBuilder.appendPrivilegeEntry(global: Boolean, pair: Pair<PrivilegeKey, Privilege>) {
val (key, priv) = pair
- // prefix. Maybe T should be M for mod or something. T means they have CAN_MANAGE privilege.
+ append(key.notNullName)
+
+ // suffix. Maybe T should be M for mod or something. T means they have CAN_MANAGE privilege.
append(
when {
- global && priv == CAN_MANAGE -> "(GT)"
- global -> "(G)"
- priv == CAN_MANAGE -> "(T)"
+ global && priv == CAN_MANAGE -> " (G) (T)"
+ global -> " (G)"
+ priv == CAN_MANAGE -> " (T)"
else -> ""
}
)
-
- append(key.notNullName)
}
fun getInfoString(parcel: Parcel): String = buildString {
@@ -219,8 +235,8 @@ private object ParcelInfoStringComputer {
append('\n')
- val local = parcel.privilegeMap
- val global = parcel.globalPrivileges?.privilegeMap ?: emptyMap()
+ val local: RawPrivileges = parcel.data
+ val global = parcel.globalPrivileges
appendAddedList(local, global, CAN_BUILD, "Allowed") // includes CAN_MANAGE privilege
append('\n')
appendAddedList(local, global, BANNED, "Banned")
diff --git a/src/main/kotlin/io/dico/parcels2/listener/WorldEditListener.kt b/src/main/kotlin/io/dico/parcels2/listener/WorldEditListener.kt
index 77d754a..4d35a53 100644
--- a/src/main/kotlin/io/dico/parcels2/listener/WorldEditListener.kt
+++ b/src/main/kotlin/io/dico/parcels2/listener/WorldEditListener.kt
@@ -14,6 +14,7 @@ import com.sk89q.worldedit.world.biome.BaseBiome
import com.sk89q.worldedit.world.block.BlockStateHolder
import io.dico.parcels2.ParcelWorld
import io.dico.parcels2.ParcelsPlugin
+import io.dico.parcels2.canBuildFast
import io.dico.parcels2.util.ext.hasPermBuildAnywhere
import io.dico.parcels2.util.ext.sendParcelMessage
import org.bukkit.entity.Player
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 c09cd86..e4c2b4c 100644
--- a/src/main/kotlin/io/dico/parcels2/util/ext/Misc.kt
+++ b/src/main/kotlin/io/dico/parcels2/util/ext/Misc.kt
@@ -1,5 +1,6 @@
package io.dico.parcels2.util.ext
+import io.dico.dicore.Formatting
import io.dico.parcels2.logger
import java.io.File
@@ -70,3 +71,6 @@ class EditLoopScope<T, U>(val _map: MutableMap<T, U>) {
}
}
+
+operator fun Formatting.plus(other: Formatting) = toString() + other
+operator fun Formatting.plus(other: String) = toString() + other
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 1d3117e..1875ff8 100644
--- a/src/main/kotlin/io/dico/parcels2/util/ext/Player.kt
+++ b/src/main/kotlin/io/dico/parcels2/util/ext/Player.kt
@@ -5,6 +5,7 @@ import io.dico.parcels2.ParcelsPlugin
import io.dico.parcels2.logger
import org.bukkit.OfflinePlayer
import org.bukkit.entity.Player
+import org.bukkit.permissions.Permissible
import org.bukkit.plugin.java.JavaPlugin
inline val OfflinePlayer.uuid get() = uniqueId
@@ -17,12 +18,12 @@ 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(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")
+inline val Permissible.hasPermBanBypass get() = hasPermission(PERM_BAN_BYPASS)
+inline val Permissible.hasPermGamemodeBypass get() = hasPermission("parcels.admin.bypass.gamemode")
+inline val Permissible.hasPermBuildAnywhere get() = hasPermission(PERM_BUILD_ANYWHERE)
+inline val Permissible.hasPermAdminManage get() = hasPermission(PERM_ADMIN_MANAGE)
+inline val Permissible.hasParcelHomeOthers get() = hasPermission("parcels.command.home.others")
+inline val Permissible.hasPermRandomSpecific get() = hasPermission("parcels.command.random.specific")
val Player.parcelLimit: Int
get() {
for (info in effectivePermissions) {