Remove custom command handling and start slash commands
They don't work yet, but show up on Discord so that's something
This commit is contained in:
parent
cafd8096fa
commit
2a985509fb
6 changed files with 49 additions and 149 deletions
|
@ -1,5 +1,6 @@
|
|||
package buttondevteam.discordplugin
|
||||
|
||||
import buttondevteam.discordplugin.DiscordPlugin.dc
|
||||
import buttondevteam.discordplugin.announcer.AnnouncerModule
|
||||
import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule
|
||||
import buttondevteam.discordplugin.commands.*
|
||||
|
@ -84,7 +85,7 @@ import java.util.Optional
|
|||
var commandChannel: ReadOnlyConfigData[Snowflake] = DPUtils.snowflakeData(getIConfig, "commandChannel", 0L)
|
||||
/**
|
||||
* The role that allows using mod-only Discord commands.
|
||||
* If empty (''), then it will only allow for the owner.
|
||||
* If empty (''), then it will only allow for the owner.
|
||||
*/
|
||||
var modRole: ReadOnlyConfigData[SMono[Role]] = null
|
||||
/**
|
||||
|
@ -204,19 +205,19 @@ import java.util.Optional
|
|||
Component.registerComponent(this, new AnnouncerModule)
|
||||
Component.registerComponent(this, new FunModule)
|
||||
ChromaBot.updatePlayerList() //The MCChatModule is tested to be enabled
|
||||
manager.registerCommand(new VersionCommand)
|
||||
manager.registerCommand(new UserinfoCommand)
|
||||
manager.registerCommand(new HelpCommand)
|
||||
manager.registerCommand(new DebugCommand)
|
||||
manager.registerCommand(new ConnectCommand)
|
||||
val applicationId = dc.getRestClient.getApplicationId.block()
|
||||
val guildId = Some(DiscordPlugin.mainServer.getId.asLong())
|
||||
manager.registerCommand(new VersionCommand, applicationId, guildId)
|
||||
manager.registerCommand(new UserinfoCommand, applicationId, guildId)
|
||||
manager.registerCommand(new HelpCommand, applicationId, guildId)
|
||||
manager.registerCommand(new DebugCommand, applicationId, guildId)
|
||||
manager.registerCommand(new ConnectCommand, applicationId, guildId)
|
||||
TBMCCoreAPI.SendUnsentExceptions()
|
||||
TBMCCoreAPI.SendUnsentDebugMessages()
|
||||
val blw = new BukkitLogWatcher
|
||||
blw.start()
|
||||
LogManager.getRootLogger.asInstanceOf[Logger].addAppender(blw)
|
||||
logWatcher = blw
|
||||
Interactions.create().onCommand("teszt", Interactions.createHandler()
|
||||
.guild(gi => gi.acknowledge().withFollowup(_.createFollowupMessage("Teszt"))).build());
|
||||
if (!TBMCCoreAPI.IsTestServer) DiscordPlugin.dc.updatePresence(ClientPresence.online(ClientActivity.playing("Minecraft"))).subscribe()
|
||||
else DiscordPlugin.dc.updatePresence(ClientPresence.online(ClientActivity.playing("testing"))).subscribe()
|
||||
getLogger.info("Loaded!")
|
||||
|
|
|
@ -46,11 +46,11 @@ abstract class DiscordSenderBase protected(var user: User, var channel: MessageC
|
|||
val sendmsg = DPUtils.sanitizeString(message)
|
||||
this synchronized {
|
||||
msgtosend += "\n" + sendmsg
|
||||
if (sendtask == null) sendtask = Bukkit.getScheduler.runTaskLaterAsynchronously(DiscordPlugin.plugin, () => {
|
||||
if (sendtask == null) sendtask = Bukkit.getScheduler.runTaskLaterAsynchronously(DiscordPlugin.plugin, (() => {
|
||||
channel.createMessage((if (user != null) user.getMention + "\n" else "") + msgtosend.trim).subscribe()
|
||||
sendtask = null
|
||||
msgtosend = ""
|
||||
}, 4) // Waits a 0.2 second to gather all/most of the different messages
|
||||
}): Runnable, 4) // Waits a 0.2 second to gather all/most of the different messages
|
||||
}
|
||||
} catch {
|
||||
case e: Exception =>
|
||||
|
|
|
@ -2,12 +2,36 @@ package buttondevteam.discordplugin.commands
|
|||
|
||||
import buttondevteam.discordplugin.DiscordPlugin
|
||||
import buttondevteam.lib.chat.Command2
|
||||
import discord4j.common.util.Snowflake
|
||||
import discord4j.core.`object`.command.ApplicationCommandOption
|
||||
import discord4j.discordjson.json.{ApplicationCommandOptionData, ApplicationCommandRequest}
|
||||
|
||||
import java.lang.reflect.Method
|
||||
|
||||
class Command2DC extends Command2[ICommand2DC, Command2DCSender] {
|
||||
override def registerCommand(command: ICommand2DC): Unit =
|
||||
override def registerCommand(command: ICommand2DC): Unit = {
|
||||
registerCommand(command, DiscordPlugin.dc.getApplicationInfo.block().getId.asLong())
|
||||
}
|
||||
|
||||
def registerCommand(command: ICommand2DC, appId: Long, guildId: Option[Long] = None): Unit = {
|
||||
super.registerCommand(command, DiscordPlugin.getPrefix) //Needs to be configurable for the helps
|
||||
val greetCmdRequest = ApplicationCommandRequest.builder()
|
||||
.name(command.getCommandPath) //TODO: Main path
|
||||
.description("A ChromaBot command.") //TODO: Description
|
||||
.addOption(ApplicationCommandOptionData.builder()
|
||||
.name("name")
|
||||
.description("Your name")
|
||||
.`type`(ApplicationCommandOption.Type.STRING.getValue)
|
||||
.required(true)
|
||||
.build()
|
||||
).build()
|
||||
val service = DiscordPlugin.dc.getRestClient.getApplicationService
|
||||
guildId match {
|
||||
case Some(id) => service.createGuildApplicationCommand(appId, id, greetCmdRequest).subscribe()
|
||||
case None => service.createGlobalApplicationCommand(appId, greetCmdRequest).subscribe()
|
||||
}
|
||||
}
|
||||
|
||||
override def hasPermission(sender: Command2DCSender, command: ICommand2DC, method: Method): Boolean = {
|
||||
//return !command.isModOnly() || sender.getMessage().getAuthor().hasRole(DiscordPlugin.plugin.modRole().get()); //TODO: modRole may be null; more customisable way?
|
||||
true
|
||||
|
|
|
@ -1,110 +0,0 @@
|
|||
package buttondevteam.discordplugin.listeners
|
||||
|
||||
import buttondevteam.discordplugin.commands.Command2DCSender
|
||||
import buttondevteam.discordplugin.{DPUtils, DiscordPlugin}
|
||||
import buttondevteam.lib.TBMCCoreAPI
|
||||
import discord4j.common.util.Snowflake
|
||||
import discord4j.core.`object`.entity.channel.{MessageChannel, PrivateChannel}
|
||||
import discord4j.core.`object`.entity.{Member, Message, Role, User}
|
||||
import reactor.core.scala.publisher.{SFlux, SMono}
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
object CommandListener {
|
||||
/**
|
||||
* Runs a ChromaBot command. If mentionedonly is false, it will only execute the command if it was in #bot with the correct prefix or in private.
|
||||
*
|
||||
* @param message The Discord message
|
||||
* @param mentionedonly Only run the command if ChromaBot is mentioned at the start of the message
|
||||
* @return Whether it <b>did not run</b> the command
|
||||
*/
|
||||
def runCommand(message: Message, commandChannelID: Snowflake, mentionedonly: Boolean): SMono[Boolean] = {
|
||||
val timings = CommonListeners.timings
|
||||
val ret = SMono.just(true)
|
||||
if (message.getContent.isEmpty) return ret //Pin messages and such, let the mcchat listener deal with it
|
||||
val content = message.getContent
|
||||
timings.printElapsed("A")
|
||||
SMono(message.getChannel).flatMap((channel: MessageChannel) => {
|
||||
def foo(channel: MessageChannel): SMono[Boolean] = {
|
||||
var tmp = ret
|
||||
if (!mentionedonly) { //mentionedonly conditions are in CommonListeners
|
||||
timings.printElapsed("B")
|
||||
if (!channel.isInstanceOf[PrivateChannel] && !(content.charAt(0) == DiscordPlugin.getPrefix && channel.getId.asLong == commandChannelID.asLong)) { //
|
||||
return ret
|
||||
}
|
||||
timings.printElapsed("C")
|
||||
tmp = ret.`then`(SMono(channel.`type`)).`then`(ret) // Fun (this true is ignored - x)
|
||||
}
|
||||
val cmdwithargs = new StringBuilder(content)
|
||||
val gotmention = new AtomicBoolean
|
||||
timings.printElapsed("Before self")
|
||||
tmp.flatMapMany((_: Boolean) => SMono(DiscordPlugin.dc.getSelf)
|
||||
.flatMap((self: User) => SMono(self.asMember(DiscordPlugin.mainServer.getId)))
|
||||
.flatMapMany((self: Member) => {
|
||||
def foo(self: Member) = {
|
||||
timings.printElapsed("D")
|
||||
gotmention.set(checkanddeletemention(cmdwithargs, self.getMention, message))
|
||||
gotmention.set(checkanddeletemention(cmdwithargs, self.getNicknameMention, message) || gotmention.get)
|
||||
val mentions = SFlux(message.getRoleMentions)
|
||||
SFlux(self.getRoles).filterWhen((r: Role) => mentions.any((rr: Role) => rr.getName == r.getName)).map(_.getMention)
|
||||
}
|
||||
|
||||
foo(self)
|
||||
}).map((mentionRole: String) => {
|
||||
def foo(mentionRole: String): Boolean = {
|
||||
timings.printElapsed("E")
|
||||
gotmention.set(checkanddeletemention(cmdwithargs, mentionRole, message) || gotmention.get) // Delete all mentions
|
||||
!mentionedonly || gotmention.get //Stops here if false
|
||||
}
|
||||
|
||||
foo(mentionRole)
|
||||
}).switchIfEmpty(SMono.fromCallable(() => !mentionedonly || gotmention.get))).filter(b => b)
|
||||
.last(Option(false)).filter(b => b)
|
||||
.doOnNext(_ => channel.`type`.subscribe).flatMap(_ => {
|
||||
def foo(): SMono[Boolean] = {
|
||||
val cmdwithargsString = cmdwithargs.toString
|
||||
try {
|
||||
timings.printElapsed("F")
|
||||
if (!DiscordPlugin.plugin.manager.handleCommand(new Command2DCSender(message), cmdwithargsString))
|
||||
return DPUtils.reply(message, channel, "unknown command. Do " + DiscordPlugin.getPrefix + "help for help.").map(_ => false)
|
||||
} catch {
|
||||
case e: Exception =>
|
||||
TBMCCoreAPI.SendException("Failed to process Discord command: " + cmdwithargsString, e, DiscordPlugin.plugin)
|
||||
}
|
||||
SMono.just(false) //If the command succeeded or there was an error, return false
|
||||
}
|
||||
|
||||
foo()
|
||||
}).defaultIfEmpty(true)
|
||||
}
|
||||
|
||||
foo(channel)
|
||||
})
|
||||
}
|
||||
|
||||
private def checkanddeletemention(cmdwithargs: StringBuilder, mention: String, message: Message): Boolean = {
|
||||
val prefix = DiscordPlugin.getPrefix
|
||||
if (message.getContent.startsWith(mention)) { // TODO: Resolve mentions: Compound arguments, either a mention or text
|
||||
if (cmdwithargs.length > mention.length + 1) {
|
||||
var i = cmdwithargs.indexOf(" ", mention.length)
|
||||
if (i == -1) i = mention.length
|
||||
else { //noinspection StatementWithEmptyBody
|
||||
while ( {
|
||||
i < cmdwithargs.length && cmdwithargs.charAt(i) == ' '
|
||||
}) { //Removes any space before the command
|
||||
i += 1
|
||||
}
|
||||
}
|
||||
cmdwithargs.delete(0, i)
|
||||
cmdwithargs.insert(0, prefix) //Always use the prefix for processing
|
||||
}
|
||||
else cmdwithargs.replace(0, cmdwithargs.length, prefix + "help")
|
||||
}
|
||||
else {
|
||||
if (cmdwithargs.isEmpty) cmdwithargs.replace(0, 0, prefix + "help")
|
||||
else if (cmdwithargs.charAt(0) != prefix) cmdwithargs.insert(0, prefix)
|
||||
return false //Don't treat / as mention, mentions can be used in public mcchat
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
|
@ -11,29 +11,26 @@ import discord4j.core.`object`.entity.Message
|
|||
import discord4j.core.`object`.entity.channel.{MessageChannel, PrivateChannel}
|
||||
import discord4j.core.event.EventDispatcher
|
||||
import discord4j.core.event.domain.PresenceUpdateEvent
|
||||
import discord4j.core.event.domain.interaction.{ChatInputInteractionEvent, MessageInteractionEvent}
|
||||
import discord4j.core.event.domain.message.MessageCreateEvent
|
||||
import discord4j.core.event.domain.role.{RoleCreateEvent, RoleDeleteEvent, RoleUpdateEvent}
|
||||
import reactor.core.Disposable
|
||||
import reactor.core.publisher.Mono
|
||||
import reactor.core.scala.publisher.{SFlux, SMono}
|
||||
|
||||
object CommonListeners {
|
||||
val timings = new Timings
|
||||
|
||||
/*
|
||||
MentionEvent:
|
||||
- CommandListener (starts with mention, only 'channelcon' and not in #bot)
|
||||
|
||||
MessageReceivedEvent:
|
||||
- v CommandListener (starts with mention, in #bot or a connected chat)
|
||||
- Minecraft chat (is enabled in the channel and message isn't [/]mcchat)
|
||||
- CommandListener (with the correct prefix in #bot, or in private)
|
||||
*/
|
||||
def register(dispatcher: EventDispatcher): Unit = {
|
||||
dispatcher.on(classOf[MessageCreateEvent]).flatMap((event: MessageCreateEvent) => {
|
||||
SMono.just(event.getMessage).filter(_ => !DiscordPlugin.SafeMode)
|
||||
.filter(message => message.getAuthor.filter(!_.isBot).isPresent)
|
||||
.filter(message => !FunModule.executeMemes(message))
|
||||
.flatMap(handleMessage(event))
|
||||
.filterWhen(message => {
|
||||
Option(Component.getComponents.get(classOf[MinecraftChatModule])).filter(_.isEnabled)
|
||||
.map(_.asInstanceOf[MinecraftChatModule].getListener.handleDiscord(event))
|
||||
.getOrElse(SMono.just(true)) //Wasn't handled, continue
|
||||
})
|
||||
}).onErrorContinue((err, _) => TBMCCoreAPI.SendException("An error occured while handling a message!", err, DiscordPlugin.plugin)).subscribe()
|
||||
dispatcher.on(classOf[PresenceUpdateEvent]).subscribe((event: PresenceUpdateEvent) => {
|
||||
if (!DiscordPlugin.SafeMode)
|
||||
|
@ -42,6 +39,12 @@ object CommonListeners {
|
|||
SFlux(dispatcher.on(classOf[RoleCreateEvent])).subscribe(GameRoleModule.handleRoleEvent)
|
||||
SFlux(dispatcher.on(classOf[RoleDeleteEvent])).subscribe(GameRoleModule.handleRoleEvent)
|
||||
SFlux(dispatcher.on(classOf[RoleUpdateEvent])).subscribe(GameRoleModule.handleRoleEvent)
|
||||
SFlux(dispatcher.on(classOf[ChatInputInteractionEvent], event => {
|
||||
if(event.getCommandName() eq "help")
|
||||
event.reply("Hello there")
|
||||
else
|
||||
Mono.empty()
|
||||
})).subscribe()
|
||||
}
|
||||
|
||||
var debug = false
|
||||
|
@ -49,20 +52,4 @@ object CommonListeners {
|
|||
def debug(debug: String): Unit = if (CommonListeners.debug) { //Debug
|
||||
DPUtils.getLogger.info(debug)
|
||||
}
|
||||
|
||||
private def handleMessage(event: MessageCreateEvent) = {
|
||||
(message: Message) => {
|
||||
val commandChannel = Option(DiscordPlugin.plugin.commandChannel.get)
|
||||
SMono(message.getChannel).filter(mch => commandChannel.isDefined && mch.getId.asLong() == commandChannel.get.asLong() //If mentioned, that's higher than chat
|
||||
|| mch.isInstanceOf[PrivateChannel] || message.getContent.contains("channelcon")).flatMap(_ => { //Only 'channelcon' is allowed in other channels
|
||||
//Only continue if this doesn't handle the event
|
||||
CommandListener.runCommand(message, commandChannel.get, mentionedonly = true) //#bot is handled here
|
||||
}).`then`(SMono.just(true)) //The condition is only for the first command execution, not mcchat
|
||||
.filterWhen(_ => {
|
||||
Option(Component.getComponents.get(classOf[MinecraftChatModule])).filter(_.isEnabled)
|
||||
.map(_.asInstanceOf[MinecraftChatModule].getListener.handleDiscord(event)) //Also runs Discord commands in chat channels
|
||||
.getOrElse(SMono.just(true)) //Wasn't handled, continue
|
||||
}).filterWhen(_ => CommandListener.runCommand(event.getMessage, commandChannel.get, mentionedonly = false))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,6 @@ package buttondevteam.discordplugin.mcchat
|
|||
import buttondevteam.core.ComponentManager
|
||||
import buttondevteam.discordplugin.*
|
||||
import buttondevteam.discordplugin.DPUtils.SpecExtensions
|
||||
import buttondevteam.discordplugin.listeners.CommandListener
|
||||
import buttondevteam.discordplugin.playerfaker.{VanillaCommandListener, VanillaCommandListener14, VanillaCommandListener15}
|
||||
import buttondevteam.lib.*
|
||||
import buttondevteam.lib.chat.{ChatMessage, TBMCChatAPI}
|
||||
|
@ -251,7 +250,6 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
|
|||
SMono(ev.getMessage.getChannel)
|
||||
.filter(channel => isChatEnabled(channel, author, hasCustomChat))
|
||||
.filter(channel => !isRunningMCChatCommand(channel, ev.getMessage.getContent, prefix))
|
||||
.filterWhen(_ => CommandListener.runCommand(ev.getMessage, DiscordPlugin.plugin.commandChannel.get, mentionedonly = true)) //Allow running commands in chat channels
|
||||
.filter(channel => {
|
||||
MCChatUtils.resetLastMessage(channel)
|
||||
recevents.add(ev)
|
||||
|
|
Loading…
Reference in a new issue