blob: 42f143d89218d8da89d9ae88bdd04538b5c3dc66 (
plain)
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
|
package moe.nea.firmament.commands
import com.mojang.brigadier.StringReader
import com.mojang.brigadier.arguments.ArgumentType
import com.mojang.brigadier.context.CommandContext
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType
import com.mojang.brigadier.suggestion.Suggestions
import com.mojang.brigadier.suggestion.SuggestionsBuilder
import java.util.concurrent.CompletableFuture
import java.util.function.Function
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds
import kotlin.time.DurationUnit
import kotlin.time.toDuration
import moe.nea.firmament.util.tr
object DurationArgumentType : ArgumentType<Duration> {
val unknownTimeCode = DynamicCommandExceptionType { timeCode ->
tr("firmament.command-argument.duration.error",
"Unknown time code '$timeCode'")
}
override fun parse(reader: StringReader): Duration {
val start = reader.cursor
val string = reader.readUnquotedString()
val matcher = regex.matcher(string)
var s = 0
var time = 0.seconds
fun createError(till: Int) {
throw unknownTimeCode.createWithContext(
reader.also { it.cursor = start + s },
string.substring(s, till))
}
while (matcher.find()) {
if (matcher.start() != s) {
createError(matcher.start())
}
s = matcher.end()
val amount = matcher.group("count").toDouble()
val what = timeSuffixes[matcher.group("what").single()]!!
time += amount.toDuration(what)
}
if (string.length != s) {
createError(string.length)
}
return time
}
override fun <S : Any?> listSuggestions(
context: CommandContext<S>,
builder: SuggestionsBuilder
): CompletableFuture<Suggestions> {
val remaining = builder.remainingLowerCase.substringBefore(' ')
if (remaining.isEmpty()) return super.listSuggestions(context, builder)
if (remaining.last().isDigit()) {
for (timeSuffix in timeSuffixes.keys) {
builder.suggest(remaining + timeSuffix)
}
}
return builder.buildFuture()
}
val timeSuffixes = mapOf(
'm' to DurationUnit.MINUTES,
's' to DurationUnit.SECONDS,
'h' to DurationUnit.HOURS,
)
val regex = "(?<count>[0-9]+)(?<what>[${timeSuffixes.keys.joinToString("")}])".toPattern()
override fun getExamples(): Collection<String> {
return listOf("3m", "20s", "1h45m")
}
}
|