Add temporary VCs
This commit is contained in:
parent
5a95138861
commit
af65dcc06b
|
@ -1,19 +1,20 @@
|
||||||
package moe.kageru.kagebot.features
|
package moe.kageru.kagebot.features
|
||||||
|
|
||||||
class Features(val welcome: WelcomeFeature?, val timeout: TimeoutFeature?) {
|
class Features(val welcome: WelcomeFeature?, val timeout: TimeoutFeature?, vc: TempVCFeature = TempVCFeature(null)) {
|
||||||
private val debug = DebugFeature()
|
private val debug = DebugFeature()
|
||||||
private val help = HelpFeature()
|
private val help = HelpFeature()
|
||||||
private val getConfig = GetConfigFeature()
|
private val getConfig = GetConfigFeature()
|
||||||
private val setConfig = SetConfigFeature()
|
private val setConfig = SetConfigFeature()
|
||||||
|
|
||||||
private val all = listOf(welcome, debug, help, getConfig, setConfig, timeout)
|
private val all = listOf(welcome, debug, help, getConfig, setConfig, timeout, vc)
|
||||||
private val featureMap = mapOf(
|
private val featureMap = mapOf(
|
||||||
"help" to help,
|
"help" to help,
|
||||||
"debug" to debug,
|
"debug" to debug,
|
||||||
"welcome" to welcome,
|
"welcome" to welcome,
|
||||||
"getConfig" to getConfig,
|
"getConfig" to getConfig,
|
||||||
"setConfig" to setConfig,
|
"setConfig" to setConfig,
|
||||||
"timeout" to timeout
|
"timeout" to timeout,
|
||||||
|
"vc" to vc
|
||||||
)
|
)
|
||||||
|
|
||||||
fun findByString(feature: String) = featureMap[feature]
|
fun findByString(feature: String) = featureMap[feature]
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
package moe.kageru.kagebot.features
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import moe.kageru.kagebot.Log
|
||||||
|
import moe.kageru.kagebot.Util.failed
|
||||||
|
import moe.kageru.kagebot.config.Config
|
||||||
|
import moe.kageru.kagebot.persistence.Dao
|
||||||
|
import org.javacord.api.DiscordApi
|
||||||
|
import org.javacord.api.entity.channel.ChannelCategory
|
||||||
|
import org.javacord.api.entity.channel.ServerVoiceChannel
|
||||||
|
import org.javacord.api.event.message.MessageCreateEvent
|
||||||
|
import java.util.concurrent.CompletionException
|
||||||
|
|
||||||
|
class TempVCFeature(@JsonProperty("category") category: String? = null) : EventFeature, MessageFeature {
|
||||||
|
private val category: ChannelCategory? =
|
||||||
|
category?.let { Config.server.getChannelCategoriesByNameIgnoreCase(it).first() }
|
||||||
|
|
||||||
|
override fun handle(message: MessageCreateEvent) {
|
||||||
|
if (" " !in message.readableMessageContent) {
|
||||||
|
message.channel.sendMessage("Invalid syntax, expected 2 arguments")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val (_, limit) = message.readableMessageContent.split(" ", limit = 2)
|
||||||
|
limit.toLongOrNull()?.let { parsedLimit ->
|
||||||
|
if (parsedLimit > 99) {
|
||||||
|
message.channel.sendMessage("You can’t create a channel with that many users.")
|
||||||
|
}
|
||||||
|
createChannel(message, parsedLimit)
|
||||||
|
message.channel.sendMessage("Done")
|
||||||
|
} ?: message.channel.sendMessage("Invalid syntax, expected a number, got $limit")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun register(api: DiscordApi) {
|
||||||
|
api.addServerVoiceChannelMemberLeaveListener { event ->
|
||||||
|
println("asdsad")
|
||||||
|
if (event.channel.connectedUsers.isEmpty() && Dao.isTemporaryVC(event.channel.idAsString)) {
|
||||||
|
deleteChannel(event.channel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun deleteChannel(channel: ServerVoiceChannel) {
|
||||||
|
val deletion = channel.delete("Empty temporary channel")
|
||||||
|
if (deletion.failed()) {
|
||||||
|
Log.warn("Attempted to delete temporary VC without the necessary permissions")
|
||||||
|
} else {
|
||||||
|
Dao.removeTemporaryVC(channel.idAsString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createChannel(message: MessageCreateEvent, limit: Long) {
|
||||||
|
val creation = Config.server.createVoiceChannelBuilder().apply {
|
||||||
|
setUserlimit(limit.toInt())
|
||||||
|
setName(generateChannelName(message))
|
||||||
|
setAuditLogReason("Created temporary VC for user ${message.messageAuthor.discriminatedName}")
|
||||||
|
category?.let { setCategory(it) }
|
||||||
|
}.create()
|
||||||
|
try {
|
||||||
|
val channel = creation.join()
|
||||||
|
Dao.addTemporaryVC(channel.idAsString)
|
||||||
|
} catch (e: CompletionException) {
|
||||||
|
Log.warn("Attempted to create temporary VC without the necessary permissions")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateChannelName(message: MessageCreateEvent): String {
|
||||||
|
return "${message.messageAuthor.name}’s volatile corner"
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ object Dao {
|
||||||
private val db = DBMaker.fileDB("kagebot.db").fileMmapEnable().closeOnJvmShutdown().make()
|
private val db = DBMaker.fileDB("kagebot.db").fileMmapEnable().closeOnJvmShutdown().make()
|
||||||
private val prisoners = db.hashMap("timeout", Serializer.LONG, Serializer.LONG_ARRAY).createOrOpen()
|
private val prisoners = db.hashMap("timeout", Serializer.LONG, Serializer.LONG_ARRAY).createOrOpen()
|
||||||
private val commands = db.hashMap("commands", Serializer.STRING, Serializer.INTEGER).createOrOpen()
|
private val commands = db.hashMap("commands", Serializer.STRING, Serializer.INTEGER).createOrOpen()
|
||||||
|
private val tempVcs = db.hashSet("vcs", Serializer.STRING).createOrOpen()
|
||||||
|
|
||||||
fun saveTimeout(releaseTime: Long, roles: List<Long>) {
|
fun saveTimeout(releaseTime: Long, roles: List<Long>) {
|
||||||
prisoners[releaseTime] = roles.toLongArray()
|
prisoners[releaseTime] = roles.toLongArray()
|
||||||
|
@ -27,4 +28,16 @@ object Dao {
|
||||||
prisoners.remove(releaseTime)
|
prisoners.remove(releaseTime)
|
||||||
return timeout
|
return timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isTemporaryVC(channel: String): Boolean {
|
||||||
|
return channel in tempVcs
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addTemporaryVC(channel: String) {
|
||||||
|
tempVcs.add(channel)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeTemporaryVC(channel: String) {
|
||||||
|
tempVcs.remove(channel)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,3 +123,7 @@ feature = "setConfig"
|
||||||
[[command]]
|
[[command]]
|
||||||
trigger = "!prison"
|
trigger = "!prison"
|
||||||
feature = "timeout"
|
feature = "timeout"
|
||||||
|
|
||||||
|
[[command]]
|
||||||
|
trigger = "!vc"
|
||||||
|
feature = "vc"
|
||||||
|
|
|
@ -19,6 +19,7 @@ import org.javacord.api.event.message.MessageCreateEvent
|
||||||
import org.javacord.core.entity.message.embed.EmbedBuilderDelegateImpl
|
import org.javacord.core.entity.message.embed.EmbedBuilderDelegateImpl
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import java.util.concurrent.CompletableFuture
|
||||||
|
|
||||||
object TestUtil {
|
object TestUtil {
|
||||||
private val TIMEOUT_ROLE = mockk<Role> {
|
private val TIMEOUT_ROLE = mockk<Role> {
|
||||||
|
@ -58,6 +59,7 @@ object TestUtil {
|
||||||
every { messageAuthor.isYourself } returns isBot
|
every { messageAuthor.isYourself } returns isBot
|
||||||
every { messageAuthor.isBotOwner } returns false
|
every { messageAuthor.isBotOwner } returns false
|
||||||
every { messageAuthor.asUser() } returns Optional.of(messageableAuthor(replyEmbeds))
|
every { messageAuthor.asUser() } returns Optional.of(messageableAuthor(replyEmbeds))
|
||||||
|
every { messageAuthor.name } returns "kageru"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,13 +87,18 @@ object TestUtil {
|
||||||
every { sendMessage(capture(sentMessages)) } returns mockk(relaxed = true)
|
every { sendMessage(capture(sentMessages)) } returns mockk(relaxed = true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val api = mockk<DiscordApi> {
|
val api = mockk<DiscordApi>(relaxed = true) {
|
||||||
every { getServerById(any<String>()) } returns Optional.of(mockk {
|
every { getServerById(any<String>()) } returns Optional.of(mockk(relaxed = true) {
|
||||||
every { icon.ifPresent(any()) } just Runs
|
every { icon.ifPresent(any()) } just Runs
|
||||||
every { getTextChannelById(any<String>()) } returns channel
|
every { getTextChannelById(any<String>()) } returns channel
|
||||||
every { getTextChannelsByName(any()) } returns listOf(channel.get())
|
every { getTextChannelsByName(any()) } returns listOf(channel.get())
|
||||||
every { getRolesByNameIgnoreCase("testrole") } returns listOf(TEST_ROLE)
|
every { getRolesByNameIgnoreCase("testrole") } returns listOf(TEST_ROLE)
|
||||||
every { getRolesByNameIgnoreCase("timeout") } returns listOf(TIMEOUT_ROLE)
|
every { getRolesByNameIgnoreCase("timeout") } returns listOf(TIMEOUT_ROLE)
|
||||||
|
every { getChannelCategoriesByNameIgnoreCase(any()) } returns listOf(mockk())
|
||||||
|
every { createVoiceChannelBuilder().create() } returns mockk {
|
||||||
|
every { isCompletedExceptionally } returns false
|
||||||
|
every { join().idAsString } returns "12345"
|
||||||
|
}
|
||||||
every { getMembersByName(any()) } returns listOf(mockk(relaxed = true) {
|
every { getMembersByName(any()) } returns listOf(mockk(relaxed = true) {
|
||||||
every { id } returns 123
|
every { id } returns 123
|
||||||
every { getRoles(any()) } returns listOf(TEST_ROLE)
|
every { getRoles(any()) } returns listOf(TEST_ROLE)
|
||||||
|
@ -102,6 +109,8 @@ object TestUtil {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Globals.api = api
|
Globals.api = api
|
||||||
|
// write our mocked server to the config
|
||||||
|
Config.server = api.getServerById("").get()
|
||||||
ConfigParser.initialLoad("testconfig.toml")
|
ConfigParser.initialLoad("testconfig.toml")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import moe.kageru.kagebot.Util
|
||||||
import moe.kageru.kagebot.config.Config
|
import moe.kageru.kagebot.config.Config
|
||||||
import moe.kageru.kagebot.config.Config.localization
|
import moe.kageru.kagebot.config.Config.localization
|
||||||
import moe.kageru.kagebot.config.LocalizationSpec
|
import moe.kageru.kagebot.config.LocalizationSpec
|
||||||
|
import moe.kageru.kagebot.persistence.Dao
|
||||||
import org.javacord.api.entity.message.embed.EmbedBuilder
|
import org.javacord.api.entity.message.embed.EmbedBuilder
|
||||||
import org.javacord.api.entity.permission.Role
|
import org.javacord.api.entity.permission.Role
|
||||||
import org.javacord.api.entity.user.User
|
import org.javacord.api.entity.user.User
|
||||||
|
@ -292,4 +293,29 @@ class CommandTest : StringSpec({
|
||||||
roles shouldBe mutableListOf(Util.findRole("testrole"))
|
roles shouldBe mutableListOf(Util.findRole("testrole"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
"should create VC" {
|
||||||
|
withCommands(
|
||||||
|
"""
|
||||||
|
[[command]]
|
||||||
|
trigger = "!vc"
|
||||||
|
feature = "vc"
|
||||||
|
""".trimIndent()
|
||||||
|
) {
|
||||||
|
testMessageSuccess("!vc 2", "Done")
|
||||||
|
Dao.isTemporaryVC("12345") shouldBe true
|
||||||
|
Dao.removeTemporaryVC("12345")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"should reject invalid vc command" {
|
||||||
|
withCommands(
|
||||||
|
"""
|
||||||
|
[[command]]
|
||||||
|
trigger = "!vc"
|
||||||
|
feature = "vc"
|
||||||
|
""".trimIndent()
|
||||||
|
) {
|
||||||
|
testMessageSuccess("!vc asd", "Invalid syntax, expected a number, got asd")
|
||||||
|
Dao.isTemporaryVC("12345") shouldBe false
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -21,6 +21,9 @@ content = [
|
||||||
[feature.timeout]
|
[feature.timeout]
|
||||||
role = "timeout"
|
role = "timeout"
|
||||||
|
|
||||||
|
[feature.vc]
|
||||||
|
category = "testcategory"
|
||||||
|
|
||||||
[[command]]
|
[[command]]
|
||||||
trigger = "!debug"
|
trigger = "!debug"
|
||||||
feature = "debug"
|
feature = "debug"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user