From 8c1bb296a65ba15cb0d211577c7001c5d5fd5b82 Mon Sep 17 00:00:00 2001 From: Dico Date: Mon, 24 Sep 2018 04:24:34 +0100 Subject: Implement parcel infoString with new privilege system --- src/main/kotlin/io/dico/parcels2/Privileges.kt | 32 +++++------- .../parcels2/command/CommandsPrivilegesGlobal.kt | 5 +- .../io/dico/parcels2/defaultimpl/ParcelImpl.kt | 60 +++++++++++++++++----- .../io/dico/parcels2/storage/exposed/ListTables.kt | 4 +- 4 files changed, 65 insertions(+), 36 deletions(-) diff --git a/src/main/kotlin/io/dico/parcels2/Privileges.kt b/src/main/kotlin/io/dico/parcels2/Privileges.kt index 11a1f84..1aad3f6 100644 --- a/src/main/kotlin/io/dico/parcels2/Privileges.kt +++ b/src/main/kotlin/io/dico/parcels2/Privileges.kt @@ -15,6 +15,13 @@ enum class Privilege( 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") @@ -29,13 +36,7 @@ enum class Privilege( */ companion object { - fun getByNumber(number: Int) = safeGetByNumber(number) - ?: throw IllegalArgumentException( - if (number == -1) "Transient privileges are not stored" - else "Privilege with number $number doesn't exist" - ) - - fun safeGetByNumber(id: Int) = + fun getByNumber(id: Int) = when (id) { 1 -> BANNED 2 -> DEFAULT @@ -62,18 +63,10 @@ interface Privileges { 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 = - (when { // if CAN_BUILD is expected, CAN_MANAGE is valid. - expect > DEFAULT -> privilege(key) >= expect - expect == DEFAULT -> privilege(key) == expect - else -> privilege(key) <= expect - }) - && setPrivilege(key, update) - + privilege(key).isDistanceGrEq(expect) && setPrivilege(key, update) fun hasPrivilegeToManage(key: PrivilegeKey) = privilege(key) >= CAN_MANAGE fun allowManage(key: PrivilegeKey) = setPrivilege(key, CAN_MANAGE) @@ -88,8 +81,8 @@ interface Privileges { fun unban(key: PrivilegeKey) = changePrivilege(key, BANNED, DEFAULT) /* OfflinePlayer overloads */ - fun hasPrivilegeToManage(player: OfflinePlayer) = hasPrivilegeToManage(player.privilegeKey) + fun hasPrivilegeToManage(player: OfflinePlayer) = hasPrivilegeToManage(player.privilegeKey) fun allowManage(player: OfflinePlayer) = allowManage(player.privilegeKey) fun disallowManage(player: OfflinePlayer) = disallowManage(player.privilegeKey) @@ -102,8 +95,8 @@ interface Privileges { fun unban(player: OfflinePlayer) = unban(player.privilegeKey) } -inline val OfflinePlayer.privilegeKey: PrivilegeKey - get() = PlayerProfile.nameless(this) +val OfflinePlayer.privilegeKey: PrivilegeKey + inline get() = PlayerProfile.nameless(this) open class PrivilegesHolder(override var map: MutablePrivilegeMap = MutablePrivilegeMap()) : Privileges { override var privilegeOfStar: Privilege = DEFAULT @@ -131,4 +124,5 @@ interface GlobalPrivileges : Privileges { interface GlobalPrivilegesManager { operator fun get(owner: PlayerProfile): GlobalPrivileges + operator fun get(owner: OfflinePlayer): GlobalPrivileges = get(owner.privilegeKey) } diff --git a/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesGlobal.kt b/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesGlobal.kt index 91b8272..3c83afc 100644 --- a/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesGlobal.kt +++ b/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesGlobal.kt @@ -11,9 +11,8 @@ import org.bukkit.OfflinePlayer import org.bukkit.entity.Player class CommandsPrivilegesGlobal(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) { - private inline val data get() = plugin.globalPrivileges - @Suppress("NOTHING_TO_INLINE") - private inline operator fun GlobalPrivilegesManager.get(player: OfflinePlayer): GlobalPrivileges = this[PlayerProfile(player)] + private val data + inline get() = plugin.globalPrivileges @Cmd("entrust") @Desc( diff --git a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt index 1580cf1..041e529 100644 --- a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt +++ b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt @@ -118,6 +118,9 @@ 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 @@ -140,28 +143,61 @@ private object ParcelInfoStringComputer { append(' ') } - private fun StringBuilder.appendAddedList(local: PrivilegeMap, global: PrivilegeMap, status: Privilege, fieldName: String) { - val globalSet = global.filterValues { it == status }.keys - val localList = local.filterValues { it == status }.keys.filter { it !in globalSet } - val stringList = globalSet.map(PrivilegeKey::notNullName).map { "(G)$it" } + localList.map(PrivilegeKey::notNullName) - if (stringList.isEmpty()) return + private fun StringBuilder.appendAddedList(local: PrivilegeMap, global: PrivilegeMap, privilege: Privilege, fieldName: String) { + // local takes precedence over global + + 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 appendField({ append(fieldName) append('(') append(infoStringColor2) - append(stringList.size) + append(all.size) append(infoStringColor1) append(')') }) { - stringList.joinTo( - this, - separator = infoStringColor1.toString() + ", " + infoStringColor2, - limit = 150 - ) + val separator = "$infoStringColor1, $infoStringColor2" + + // first [localCount] entries are local + val localCount = localFiltered.size + val iterator = all.iterator() + + if (localCount != 0) { + appendPrivilegeEntry(false, iterator.next().toPair()) + repeat(localCount - 1) { + append(separator) + appendPrivilegeEntry(false, iterator.next().toPair()) + } + + } else if (iterator.hasNext()) { + // ensure there is never a leading or trailing separator + appendPrivilegeEntry(true, iterator.next().toPair()) + } + + iterator.forEach { next -> + append(separator) + appendPrivilegeEntry(true, next.toPair()) + } } } + private fun StringBuilder.appendPrivilegeEntry(global: Boolean, pair: Pair) { + val (key, priv) = pair + + // prefix. Maybe T should be M for mod or something. T means they have CAN_MANAGE privilege. + append(when { + global && priv == Privilege.CAN_MANAGE -> "(GT)" + global -> "(G)" + priv == Privilege.CAN_MANAGE -> "(T)" + else -> "" + }) + + append(key.notNullName) + } + fun getInfoString(parcel: Parcel): String = buildString { appendField("ID") { append(parcel.x) @@ -185,7 +221,7 @@ private object ParcelInfoStringComputer { val global = owner?.let { parcel.world.globalPrivileges[owner].map } ?: emptyMap() val local = parcel.map - appendAddedList(local, global, Privilege.CAN_BUILD, "Allowed") + appendAddedList(local, global, Privilege.CAN_BUILD, "Allowed") // includes CAN_MANAGE privilege append('\n') appendAddedList(local, global, Privilege.BANNED, "Banned") diff --git a/src/main/kotlin/io/dico/parcels2/storage/exposed/ListTables.kt b/src/main/kotlin/io/dico/parcels2/storage/exposed/ListTables.kt index 600255e..302d88d 100644 --- a/src/main/kotlin/io/dico/parcels2/storage/exposed/ListTables.kt +++ b/src/main/kotlin/io/dico/parcels2/storage/exposed/ListTables.kt @@ -48,7 +48,7 @@ sealed class PrivilegesTable(name: String, val idTable: IdTransactionsT val result = MutablePrivilegeMap() for (row in list) { val profile = ProfilesT.getRealItem(row[profile_id]) ?: continue - result[profile] = Privilege.safeGetByNumber(row[privilege]) ?: continue + result[profile] = Privilege.getByNumber(row[privilege]) ?: continue } return result } @@ -90,7 +90,7 @@ sealed class PrivilegesTable(name: String, val idTable: IdTransactionsT } val profile = ProfilesT.getRealItem(row[profile_id]) ?: continue - val privilege = Privilege.safeGetByNumber(row[privilege]) ?: continue + val privilege = Privilege.getByNumber(row[privilege]) ?: continue map!![profile] = privilege } -- cgit v1.2.3