add role command

remove code block fraud thingie
master
Julius de Jeu 2018-11-05 22:10:19 +01:00
parent 02dde3ee71
commit 28dd85db0b
9 changed files with 198 additions and 93 deletions

View File

@ -7,7 +7,7 @@ import net.dv8tion.jda.core.hooks.ListenerAdapter
object Events : ListenerAdapter() {
override fun onMessageReceived(event: MessageReceivedEvent) {
if ((event.message.contentStripped.toLowerCase().contains("fraud") or event.message.contentRaw.contains(Regex("`(\\w+|\\s+|\\W)+`")))
if ((event.message.contentStripped.toLowerCase().contains("fraud"))
and (event.author != event.jda.selfUser)
) {
val e = event.message.guild.getEmotesByName("fr00d", true).firstOrNull()

View File

@ -9,7 +9,6 @@ import net.dv8tion.jda.core.JDABuilder
import nl.voidcorp.dbot.commands.*
import nl.voidcorp.dbot.music.initMusic
import org.slf4j.LoggerFactory
import kotlin.concurrent.thread
val playerManager = DefaultAudioPlayerManager()
@ -25,7 +24,7 @@ fun main(args: Array<String>) {
playerManager.registerSourceManager(SoundCloudAudioSourceManager(true))
commands.addAll(helloCommand, pingCommand, helpCommand)
commands.addAll(helloCommand, pingCommand, helpCommand, joinRoleCommand, removeRoleCommand)
initMusic()
@ -41,9 +40,9 @@ fun main(args: Array<String>) {
bot = JDABuilder(args[0]).addEventListener(custom).addEventListener(nl.voidcorp.dbot.Events)
.setAudioSendFactory(NativeAudioSendFactory()).build()
Runtime.getRuntime().addShutdownHook(thread(start = false) {
/*Runtime.getRuntime().addShutdownHook(thread(start = false) {
custom.shutdown()
})
})*/
}

View File

@ -11,6 +11,7 @@ fun initAdmin() {
commands += SetPrefix
commands += ListPrefixes
commands += RemovePrefix
commands += AddRoleCommand
/*commands += MuteCommand
commands += LuaExec*/
}
@ -71,6 +72,34 @@ object MuteCommand : UnityCommand("mute", "Mutes a member of this guild", AdminC
}
)
object AddRoleCommand : UnityCommand(
"addrole",
"Add a role to the Role picker",
AdminCategory,
howTo = "addrole Rolename,rolekey",
exec = { ce ->
val args = ce.args.split(",").map { it.trim() }
if (args.size != 2) {
ce.reply("Ehm, that is not how this is supposed to work, the args have to be `Rolename,rolekey`\nWith Rolename the actual name in discord and rolekey the key you want to assign.")
} else {
val gs = GSM.getSettings(ce.guild)
val role = ce.guild.getRolesByName(args[0], true).firstOrNull()
val key = args[1]
if (role == null) {
ce.reply("Ehm, that is not how this is supposed to work, the args have to be `Rolename,rolekey`\nWith Rolename the actual name in discord and rolekey the key you want to assign.")
ce.reply("Also, the discord role you provided is not existing?")
} else {
if (gs.roleMap.containsKey(key)) {
ce.reply("First remove the key $key and then add it again, this is to prevent accidental overrides...")
} else {
gs.roleMap[key] = role.idLong
ce.reply("Added role ${role.name} with key `$key`")
}
}
}
})
object LuaExec : UnityCommand("luaexec", "Executes a bit of lua code", AdminCategory, exec = { ce ->
ce.message.delete().queue()

View File

@ -4,6 +4,7 @@ import net.dv8tion.jda.core.EmbedBuilder
import net.dv8tion.jda.core.MessageBuilder
import net.dv8tion.jda.core.entities.ChannelType
import net.dv8tion.jda.core.entities.MessageEmbed
import net.dv8tion.jda.core.managers.GuildController
import nl.voidcorp.dbot.catMap
import nl.voidcorp.dbot.commands
import nl.voidcorp.dbot.emptyOr
@ -13,7 +14,7 @@ import java.time.temporal.ChronoUnit
import kotlin.random.Random
val helloCommand = UnityCommand("hello", "Say hello to Andy!", aliases = *arrayOf()) {
val helloCommand = UnityCommand("hello", "Say hello to Andy!") {
val i = Random.nextInt(10)
if (i > 8) {
it.reply("Can you speak up or I'll throw you a microphone")
@ -24,7 +25,7 @@ val helloCommand = UnityCommand("hello", "Say hello to Andy!", aliases = *arrayO
val pingCommand =
UnityCommand("ping", help = "Check the bot's ping", aliases = *arrayOf("pong"), cooldown = 10) { event ->
UnityCommand("ping", help = "Check the bot's ping", aliases = mutableListOf("pong"), cooldown = 10) { event ->
event.reply("Ping: ...") { m ->
val ping = event.message.creationTime.until(m.creationTime, ChronoUnit.MILLIS)
m.editMessage("Ping: " + ping + "ms | Websocket: " + event.jda.ping + "ms").queue()
@ -36,6 +37,8 @@ val replies =
val helpCommand =
UnityCommand("help", "Guess what?", category = object : UnityCategory("hidden") {
override fun test(ce: UnityCommandEvent): Boolean {
if (ce.member.roles.firstOrNull { it.name.equals("admin", true) } != null) return true
if (channels.all { ce.guild.getTextChannelsByName(it, true).firstOrNull() == null }) return true
val s = (ce.channelType == ChannelType.TEXT) and (ce.textChannel!!.name.toLowerCase().run {
contains("bot") or (ce.guild.textChannels.none {
it.name.contains(
@ -56,7 +59,7 @@ val helpCommand =
val prefix = GSM.getSettings(event.guild).primaryPrefix
eb.setTitle(greeting)
.appendDescription("My name is ${event.selfMember.effectiveName}, and I am definitely the best Discord bot around!\n\nUse `${prefix}help command` for a chance that I have more info about a command!")
.appendDescription("My name is OttoBot, and I am definitely the best Discord bot around!\n\nUse `${prefix}help command` for a chance that I have more info about a command!")
.setColor(event.selfMember.color)
.setFooter("Requested by ${event.member.effectiveName}", event.author.effectiveAvatarUrl)
.setTimestamp(LocalDateTime.now())
@ -89,7 +92,11 @@ val helpCommand =
.setFooter("Requested by ${event.member.effectiveName}", event.author.effectiveAvatarUrl)
.setTimestamp(LocalDateTime.now())
if (cmd.aliases.isNotEmpty()) eb.addField("Aliases", cmd.aliases.joinToString { "`$it`" }, true)
eb.addField("Usage", "`!${cmd.howTo.emptyOr(cmd.name)}`", true)
eb.addField(
"Usage",
"`${GSM.getSettings(event.guild).primaryPrefix}${cmd.howTo.emptyOr(cmd.name)}`",
true
)
val cat = cmd.category
if (cat.roles.isNotEmpty())
eb.addField("Roles", cat.roles.joinToString { "`$it`" }, true)
@ -109,3 +116,72 @@ val helpCommand =
}
val joinRoleCommand = UnityCommand(
"role",
"Join the role specified, use without parameters for a list!",
aliases = mutableListOf("joinrole", "jr")
) { ce ->
val gm = GSM.getSettings(ce.guild)
val eb = EmbedBuilder().setColor(ce.selfMember.color)
.setFooter("Requested by ${ce.member.effectiveName}", ce.author.effectiveAvatarUrl)
.setTimestamp(LocalDateTime.now())
if (!ce.hasArgs) {
val field = MessageEmbed.Field(
"Roles",
gm.roleMap.entries.map { it.key to ce.guild.getRoleById(it.value)!! }.joinToString { "`${it.first}`: ${it.second.name}" },
false
)
eb.addField(field)
eb.setTitle("Here's a list of all this servers roles, ${ce.member.effectiveName}!")
} else {
if (!gm.roleMap.containsKey(ce.args)) {
eb.setTitle("There was an error")
eb.setDescription("This role does not exist?\nUse `${gm.primaryPrefix}joinrole` to find the available roles!")
} else {
val id = gm.roleMap[ce.args]!!
val r = ce.guild.getRoleById(id)!!
GuildController(ce.guild).addSingleRoleToMember(ce.member, r).queue()
eb.setTitle("Have fun with your new role!")
eb.setDescription("I have given you the role ${r.name}!")
}
}
ce.reply(eb.build())
}
val removeRoleCommand =
UnityCommand("removerole", "Remove the role specified, if you have it!", aliases = mutableListOf("rr")) { ce ->
val gm = GSM.getSettings(ce.guild)
val eb = EmbedBuilder().setColor(ce.selfMember.color)
.setFooter("Requested by ${ce.member.effectiveName}", ce.author.effectiveAvatarUrl)
.setTimestamp(LocalDateTime.now())
if (!ce.hasArgs) {
val roles = gm.roleMap.map { it.key to ce.guild.getRoleById(it.value)!! }
.filter { ce.member.roles.contains(it.second) }
val field = MessageEmbed.Field(
"Roles",
roles.joinToString { "`${it.first}`: ${it.second.name}" },
false
)
eb.addField(field)
eb.setTitle("Here's a list of all your removable roles, ${ce.member.effectiveName}!")
} else {
if (!gm.roleMap.containsKey(ce.args)) {
eb.setTitle("There was an error")
eb.setDescription("This role does not exist?\nUse `${gm.primaryPrefix}removerole` to find the removable roles!")
} else {
val id = gm.roleMap[ce.args]!!
val r = ce.guild.getRoleById(id)!!
if (ce.member.roles.contains(r)) {
GuildController(ce.guild).removeSingleRoleFromMember(ce.member, r).queue()
eb.setTitle("Have fun (?) without the role?")
eb.setDescription("I have removed the role ${r.name}!")
} else {
eb.setTitle("Yeah this wont work don't you think?")
eb.setDescription("You need to have the role you are trying to remove to be able to remove it...\nHonestly what did you expect?")
}
}
}
ce.reply(eb.build())
}

View File

@ -0,0 +1,48 @@
package nl.voidcorp.dbot.commands
import com.github.salomonbrys.kotson.fromJson
import net.dv8tion.jda.core.entities.Guild
import nl.voidcorp.dbot.gson
import nl.voidcorp.dbot.storage.GuildSettings
import java.io.File
import kotlin.concurrent.fixedRateTimer
object GSM {
private val f = File("settings.json")
private var lastHC = -1
private val gmap = mutableMapOf<Long, GuildSettings>()
fun getSettings(it: Guild): GuildSettings {
val res = gmap[it.idLong]
return if (res != null) {
res
} else {
val gm = GuildSettings()
gmap[it.idLong] = gm
gm
}
}
fun init() {
if (f.exists()) {
try {
val m = gson.fromJson<Map<Long, GuildSettings>>(f.readText())
gmap.putAll(m)
} catch (ex: IllegalStateException) {
}
}
fixedRateTimer("FileSaveThing", period = 1000 * 30, initialDelay = 1000 * 30) {
if (lastHC != gmap.hashCode()) {
lastHC = gmap.hashCode()
val br = f.bufferedWriter()
gson.toJson(gmap, br)
br.close()
}
}
}
}

View File

@ -13,7 +13,7 @@ enum class CooldownType {
open class UnityCommand(
val name: String, val help: String = "",
val category: UnityCategory = GeneralCategory,
val arguments: String = "", vararg val aliases: String = arrayOf(), val howTo: String = "",
val arguments: String = "", val aliases: MutableList<String> = mutableListOf(), val howTo: String = "",
val cooldown: Int = 0, val cooldownType: CooldownType = CooldownType.USER,
val exec: (event: UnityCommandEvent) -> Unit
) /*: Command()*/ {
@ -58,10 +58,10 @@ open class UnityCommand(
class UnityMusicCommand(
name: String, help: String = "",
category: UnityCategory = MusicCategory,
arguments: String = "", vararg aliases: String = arrayOf(name.first().toString()),
arguments: String = "", aliases: MutableList<String> = mutableListOf(name.first().toString()),
howTo: String = "",
val mExec: (event: UnityCommandEvent, scheduler: TrackScheduler) -> Unit
) : UnityCommand(name, help, category, arguments, *aliases, howTo = howTo, exec = {}) {
) : UnityCommand(name, help, category, arguments, aliases, howTo = howTo, exec = {}) {
override fun execute(event: UnityCommandEvent) {
val scheduler = if (guildMusicMap.containsKey(event.guild.idLong)) guildMusicMap[event.guild.idLong]!! else {
val channel = event.guild.voiceChannels.firstOrNull { it.members.contains(event.member) }

View File

@ -1,6 +1,5 @@
package nl.voidcorp.dbot.commands
import com.github.salomonbrys.kotson.fromJson
import net.dv8tion.jda.core.EmbedBuilder
import net.dv8tion.jda.core.OnlineStatus
import net.dv8tion.jda.core.entities.ChannelType
@ -10,61 +9,14 @@ import net.dv8tion.jda.core.events.ReadyEvent
import net.dv8tion.jda.core.events.message.MessageReceivedEvent
import net.dv8tion.jda.core.hooks.ListenerAdapter
import nl.voidcorp.dbot.bot
import nl.voidcorp.dbot.gson
import nl.voidcorp.dbot.log
import nl.voidcorp.dbot.storage.CommandString
import nl.voidcorp.dbot.storage.GuildSettings
import java.io.File
import java.time.LocalDateTime
import java.time.OffsetDateTime
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.ScheduledThreadPoolExecutor
import kotlin.concurrent.fixedRateTimer
import kotlin.math.absoluteValue
val gmap = mutableMapOf<Long, GuildSettings>()
object GSM {
private val f = File("settings.json")
private var lastHC = -1
fun getSettings(it: Guild): GuildSettings {
val res = gmap[it.idLong]
return if (res != null) {
res
} else {
val gm = GuildSettings()
gmap[it.idLong] = gm
gm
}
}
fun init() {
if (f.exists()) {
try {
val m = gson.fromJson<Map<Long, GuildSettings>>(f.readText())
gmap.putAll(m)
} catch (ex: IllegalStateException) {
}
}
fixedRateTimer("FileSaveThing", period = 1000 * 30) {
if (lastHC != gmap.hashCode()) {
lastHC = gmap.hashCode()
val br = f.bufferedWriter()
gson.toJson(gmap, br)
br.close()
}
}
}
fun shutdown() {
gson.toJson(gmap, f.bufferedWriter())
}
}
data class UnityCommandClient(
private val prefix: String,
private val commands: MutableList<UnityCommand> = mutableListOf()
@ -107,11 +59,6 @@ data class UnityCommandClient(
return ""
}
private val ses = ScheduledThreadPoolExecutor(8)
fun getScheduleExecutor(): ScheduledExecutorService = ses
fun getWarning(): String = "⚠️"
fun addCommand(command: UnityCommand) {
@ -153,12 +100,6 @@ data class UnityCommandClient(
fun getCommandUses(name: String): Int = usageMap[name] ?: 0
fun shutdown() {
ses.shutdown()
GSM.shutdown()
}
fun usesLinkedDeletion(): Boolean = false
fun getTextualPrefix(): String = prefix
@ -181,12 +122,14 @@ data class UnityCommandClient(
var unknownCommandHandler: (MessageReceivedEvent, String?) -> Unit = { event, command ->
val eb = EmbedBuilder().setTitle("Something went wrong...")
.addField("Unknown command: `$command`", "I don't know this command...", false)
.setColor(event.guild.selfMember.color)
.setFooter("Requested by ${event.member.effectiveName}", event.author.effectiveAvatarUrl)
.setTimestamp(LocalDateTime.now())
event.textChannel.sendMessage(eb.build()).queue()
if (event.textChannel.name.contains("bot")) {
val eb = EmbedBuilder().setTitle("Something went wrong...")
.addField("Unknown command: `$command`", "I don't know this command...", false)
.setColor(event.guild.selfMember.color)
.setFooter("Requested by ${event.member.effectiveName}", event.author.effectiveAvatarUrl)
.setTimestamp(LocalDateTime.now())
event.textChannel.sendMessage(eb.build()).queue()
}
}
override fun onMessageReceived(event: MessageReceivedEvent) {
@ -219,8 +162,8 @@ data class UnityCommandClient(
}
}
if (commandString != null)
//starts with valid prefix
if ((commandString != null) && (commandString.command.isNotBlank()))
//starts with valid prefix and is not blank
{
if ((event.channel.type == ChannelType.PRIVATE) or event.textChannel.canTalk()) {
var command: UnityCommand?// this will be null if it's not a command

View File

@ -25,8 +25,8 @@ fun initMusic() {
val queueCommand = UnityMusicCommand(
"queue",
aliases = *arrayOf("q"),
"play",
aliases = mutableListOf("p", "queue", "q"),
help = "Use this command to queue a song, if you don't add a link it will search on youtube with the specified arguments\n\nExecute with no arguments to view the current queue!",
howTo = "q [link]"
) { event, scheduler ->
@ -67,7 +67,7 @@ fun initMusic() {
val ytCommand = UnityMusicCommand(
"youtube",
aliases = *arrayOf("yt"),
aliases = mutableListOf("yt"),
help = "Search YouTube for a song!",
howTo = "youtube <search term or link>"
) { event, scheduler ->
@ -102,7 +102,7 @@ fun initMusic() {
val soundcloudCommand = UnityMusicCommand(
"soundcloud",
help = "Play a song via SoundCloud!",
aliases = *arrayOf("sc"),
aliases = mutableListOf("sc"),
howTo = "sc <link or search term>"
) { event, scheduler ->
if (event.args.isEmpty()) {
@ -135,9 +135,9 @@ fun initMusic() {
}
val playCommand = UnityMusicCommand(
"play",
"fplay",
"Force this song to be the next!",
aliases = *arrayOf("p"),
aliases = mutableListOf("fp"),
howTo = "play <url>",
category = MusicCategoryPrivate
) { event, scheduler ->
@ -152,6 +152,8 @@ fun initMusic() {
override fun trackLoaded(track: AudioTrack) {
scheduler.insertFront(track, event.member)
if (!scheduler.isQueueEmpty())
scheduler.skip()
}
override fun noMatches() {
@ -173,7 +175,7 @@ fun initMusic() {
val skipCommand = UnityCommand(
"fskip",
help = "Force skips the current song, admin only",
aliases = *arrayOf("fs", "ffs"),
aliases = mutableListOf("fs", "ffs"),
category = MusicCategoryPrivate
) { event ->
val scheduler = guildMusicMap[event.guild.idLong]
@ -187,7 +189,7 @@ fun initMusic() {
val voteSkipCommand = UnityMusicCommand(
"vskip",
help = "Starts a vote to skip the current song",
aliases = *arrayOf("voteskip", "skip", "vs", "s")
aliases = mutableListOf("voteskip", "skip", "vs", "s")
) { event, scheduler ->
val ss = scheduler.shouldSkip()
@ -201,7 +203,7 @@ fun initMusic() {
val npCommand = UnityMusicCommand(
"nowplaying",
aliases = *arrayOf("np"),
aliases = mutableListOf("np"),
help = "Show the currently playing song"
) { event, scheduler ->
if (!scheduler.isSongPlaying()) {
@ -215,7 +217,7 @@ fun initMusic() {
val attachmentPlay = UnityMusicCommand(
"attachment",
help = "Play any attached song, if it is in a normal format that is...\n\n`just drag and drop the song on your Discord window and in the optional comment add !attach(ment)`",
aliases = *arrayOf("attach")
aliases = mutableListOf("attach")
) { event, scheduler ->
val attach = event.message.attachments.firstOrNull()
if (attach == null) {
@ -277,8 +279,11 @@ fun getLinkFromSearch(
}
override fun trackLoaded(track: AudioTrack) {
if (shouldInsertFront)
if (shouldInsertFront) {
scheduler.insertFront(track, event.member)
if (!scheduler.isQueueEmpty())
scheduler.skip()
}
else
scheduler.queue(track, event.member)
/*event.reply(
@ -296,9 +301,12 @@ fun getLinkFromSearch(
override fun playlistLoaded(playlist: AudioPlaylist) {
if (!playlist.isSearchResult)
for (t in playlist.tracks) {
if (shouldInsertFront)
if (shouldInsertFront) {
scheduler.insertFront(t, event.member)
else
if (!scheduler.isQueueEmpty())
scheduler.skip()
} else
scheduler.queue(t, event.member)
}
else {

View File

@ -7,7 +7,8 @@ import java.time.LocalDateTime
data class GuildSettings(
val prefixes: MutableList<String> = mutableListOf(),
val muted: MutableMap<LocalDateTime, MutableList<MuteInfo>> = mutableMapOf()
val muted: MutableMap<LocalDateTime, MutableList<MuteInfo>> = mutableMapOf(),
val roleMap: MutableMap<String, Long> = mutableMapOf()
) {
fun getPrefixes(): MutableCollection<String> {
return prefixes
@ -16,6 +17,7 @@ data class GuildSettings(
val primaryPrefix: String
get() = prefixes.firstOrNull() ?: "!"
}
fun Guild.settings(): GuildSettings {