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
|
package io.dico.parcels2
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,
val transient: Boolean = false
) {
BANNED(1),
DEFAULT(2),
CAN_BUILD(3),
CAN_MANAGE(4),
OWNER(-1, transient = true),
ADMIN(-1, transient = true);
fun implies(other: Privilege): Boolean =
when {
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
}
companion object {
fun getByNumber(id: Int) =
when (id) {
1 -> BANNED
2 -> DEFAULT
3 -> CAN_BUILD
4 -> CAN_MANAGE
else -> null
}
}
}
interface RawPrivileges {
val privilegeMap: PrivilegeMap
var privilegeOfStar: Privilege
fun getRawStoredPrivilege(key: PrivilegeKey): Privilege
fun setRawStoredPrivilege(key: PrivilegeKey, privilege: Privilege): Boolean
fun hasAnyDeclaredPrivileges(): Boolean
}
open class PrivilegesHolder(override var privilegeMap: MutablePrivilegeMap = EmptyPrivilegeMap) : RawPrivileges {
private var _privilegeOfStar: Privilege = DEFAULT
override /*open*/ var privilegeOfStar: Privilege
get() = _privilegeOfStar
set(value) = run { _privilegeOfStar = value }
protected val isEmpty
inline get() = privilegeMap === EmptyPrivilegeMap
override fun getRawStoredPrivilege(key: PrivilegeKey) =
if (key.isStar) _privilegeOfStar
else privilegeMap.getOrDefault(key, _privilegeOfStar)
override fun setRawStoredPrivilege(key: PrivilegeKey, privilege: Privilege): Boolean {
privilege.requireNonTransient()
if (key.isStar) {
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
}
override fun hasAnyDeclaredPrivileges(): Boolean {
return privilegeMap.isNotEmpty() || privilegeOfStar != DEFAULT
}
fun copyPrivilegesFrom(other: PrivilegesHolder) {
privilegeMap = other.privilegeMap
privilegeOfStar = other.privilegeOfStar
}
}
private fun <K, V> MutableMap<K, V>.put(key: K, value: V, override: Boolean) {
if (override) this[key] = value
else putIfAbsent(key, value)
}
fun RawPrivileges.filterProfilesWithPrivilegeTo(map: MutableMap<PrivilegeKey, Privilege>, privilege: Privilege) {
if (privilegeOfStar.implies(privilege)) {
map.putIfAbsent(PlayerProfile.Star, privilegeOfStar)
}
for ((profile, declaredPrivilege) in privilegeMap) {
if (declaredPrivilege.implies(privilege)) {
map.putIfAbsent(profile, declaredPrivilege)
}
}
}
|