Skip to content

Commit cd48321

Browse files
committed
feat: conversations
1 parent 5156968 commit cd48321

1 file changed

Lines changed: 93 additions & 0 deletions

File tree

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package cc.modlabs.kpaper.utils
2+
3+
import cc.modlabs.kpaper.main.PluginInstance
4+
import net.kyori.adventure.text.Component
5+
import org.bukkit.conversations.ConversationContext
6+
import org.bukkit.conversations.ConversationFactory
7+
import org.bukkit.conversations.Prompt
8+
import org.bukkit.conversations.StringPrompt
9+
import org.bukkit.entity.Player
10+
11+
class ConversationAPI(private val player: Player) {
12+
13+
private val questions = mutableListOf<Question>()
14+
private val inputs = mutableMapOf<String, String>()
15+
16+
// Define a question class to hold the question and its validation
17+
data class Question(
18+
val identifier: String,
19+
val prompt: Component,
20+
val validator: (String) -> Boolean
21+
)
22+
23+
// DSL Entry point
24+
fun conversation(init: ConversationBuilder.() -> Unit) {
25+
val builder = ConversationBuilder()
26+
builder.init()
27+
builder.build()
28+
}
29+
30+
// DSL builder class
31+
inner class ConversationBuilder {
32+
private val questionList = mutableListOf<Question>()
33+
private lateinit var onDone: (Map<String, String>) -> Unit
34+
35+
// Add a question to the conversation
36+
fun question(identifier: String, prompt: Component, validator: (String) -> Boolean) {
37+
questionList.add(Question(identifier, prompt, validator))
38+
}
39+
40+
// Define the done function to finalize the conversation
41+
fun done(onComplete: (Map<String, String>) -> Unit) {
42+
onDone = onComplete
43+
}
44+
45+
// Build and start the conversation
46+
fun build() {
47+
questions.addAll(questionList)
48+
startBukkitConversation()
49+
}
50+
51+
// Start the Bukkit conversation
52+
private fun startBukkitConversation() {
53+
val conversationFactory = ConversationFactory(PluginInstance)
54+
.withModality(true)
55+
.withFirstPrompt(createPrompt(0))
56+
.withEscapeSequence("cancel")
57+
.thatExcludesNonPlayersWithMessage("Only players can use this!")
58+
59+
val conversation = conversationFactory.buildConversation(player)
60+
conversation.begin()
61+
}
62+
63+
// Create a prompt for each question
64+
private fun createPrompt(index: Int): Prompt {
65+
return object : StringPrompt() {
66+
override fun getPromptText(context: ConversationContext): String {
67+
return questions[index].prompt.toString() // Convert Component to String
68+
}
69+
70+
override fun acceptInput(context: ConversationContext, input: String?): Prompt? {
71+
val userInput = input ?: ""
72+
val question = questions[index]
73+
74+
// Validate the input using true/false logic
75+
val isValid = question.validator(userInput)
76+
if (isValid) {
77+
inputs[question.identifier] = userInput
78+
} else {
79+
return createPrompt(index) // Retry the current prompt on failure
80+
}
81+
82+
// Proceed to the next question or end the conversation
83+
return if (index + 1 < questions.size) {
84+
createPrompt(index + 1)
85+
} else {
86+
onDone(inputs) // Call the done function with all inputs
87+
null // End conversation
88+
}
89+
}
90+
}
91+
}
92+
}
93+
}

0 commit comments

Comments
 (0)