diff options
Diffstat (limited to 'src/main/kotlin/io/dico/parcels2/Privileges.kt')
-rw-r--r-- | src/main/kotlin/io/dico/parcels2/Privileges.kt | 134 |
1 files changed, 134 insertions, 0 deletions
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..11a1f84 --- /dev/null +++ b/src/main/kotlin/io/dico/parcels2/Privileges.kt @@ -0,0 +1,134 @@ +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 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(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) = + 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 = + (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) + + + 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) +} + +inline val OfflinePlayer.privilegeKey: PrivilegeKey + 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 +} |