1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
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 privilegeMap: PrivilegeMap
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
}
enum class PrivilegeChangeResult {
SUCCESS, FAIL, FAIL_OWNER
}
val OfflinePlayer.privilegeKey: PrivilegeKey
inline get() = PlayerProfile.nameless(this)
open class PrivilegesHolder(override var privilegeMap: MutablePrivilegeMap = MutablePrivilegeMap()) : PrivilegesMinimal {
private var privilegeOfStar: Privilege = DEFAULT
override fun getStoredPrivilege(key: PrivilegeKey) =
if (key.isStar) privilegeOfStar
else privilegeMap.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) 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)
}
|