From 0d59dff86e3ec997eb212fbb3500d889578f21e3 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Fri, 30 Jun 2023 02:29:01 +0200 Subject: [PATCH] Reverted back to Scala 2.13 - The IntelliJ plugin still isn't working properly after 2 years so it's really annoying to dev using Scala 3 - (Probably) fixed DPUtils.reply not sending a message if a Mono.empty() was passed as a channel - Moved the Discord user property from LastMessageData to CustomLMD as we don't need the user anymore to check permissions (we don't need to create a fake sender) - ...even if we do, it should store the sender itself maybe - Spent hours reverting and debugging Scala 2 issues because apaprently that's also very buggy - Implemented Player interface directly in some senders because it was required for... reasons - Moved the commenter to a separate class after a looot of debugging (API was provided) --- build.sbt | 99 +------------------ project/Commenter.scala | 96 ++++++++++++++++++ project/build.properties | 2 +- project/build.sbt | 3 +- .../discordplugin/ChromaBot.scala | 6 +- .../buttondevteam/discordplugin/DPUtils.scala | 58 ++++++----- .../discordplugin/DiscordPlugin.scala | 24 ++--- .../announcer/AnnouncerModule.scala | 7 +- .../discordplugin/commands/DebugCommand.scala | 12 +-- .../commands/UserinfoCommand.scala | 7 +- .../exceptions/DebugMessageListener.scala | 3 +- .../exceptions/ExceptionListenerModule.scala | 20 ++-- .../discordplugin/fun/FunModule.scala | 25 +++-- .../listeners/CommonListeners.scala | 26 ++--- .../discordplugin/listeners/MCListener.scala | 7 +- .../mcchat/ChannelconCommand.scala | 31 +++--- .../discordplugin/mcchat/MCChatCustom.scala | 4 +- .../discordplugin/mcchat/MCChatListener.scala | 28 +++--- .../discordplugin/mcchat/MCChatPrivate.scala | 2 +- .../discordplugin/mcchat/MCChatUtils.scala | 80 ++++++++------- .../discordplugin/mcchat/MCListener.scala | 32 +++--- .../mcchat/MinecraftChatModule.scala | 23 +++-- .../sender/DiscordConnectedPlayer.scala | 15 +-- .../mcchat/sender/DiscordPlayerSender.scala | 8 +- .../mcchat/sender/DiscordSender.scala | 8 +- .../mcchat/sender/DiscordSenderBase.scala | 4 +- .../mcchat/sender/DiscordUser.scala | 9 ++ .../mccommands/DiscordMCCommand.scala | 9 +- .../discordplugin/role/GameRoleModule.scala | 59 ++++++----- .../discordplugin/role/RoleCommand.scala | 8 +- 30 files changed, 388 insertions(+), 327 deletions(-) create mode 100644 project/Commenter.scala diff --git a/build.sbt b/build.sbt index 3f327b6..b8197e1 100644 --- a/build.sbt +++ b/build.sbt @@ -1,16 +1,9 @@ -import org.bukkit.configuration.file.YamlConfiguration - -import java.util.regex.Pattern -import scala.io.Source -import scala.util.Using - name := "Chroma-Discord" version := "1.1" -scalaVersion := "3.3.0" +scalaVersion := "2.13.0" -resolvers += "spigot-repo" at "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" resolvers += "jitpack.io" at "https://jitpack.io" resolvers += "paper-repo" at "https://papermc.io/repo/repository/maven-public/" resolvers += Resolver.mavenLocal @@ -23,10 +16,10 @@ libraryDependencies ++= Seq( "com.discord4j" % "discord4j-core" % "3.2.3", "com.vdurmont" % "emoji-java" % "5.1.1", "org.mockito" % "mockito-core" % "5.2.0", + "io.projectreactor" % "reactor-scala-extensions_2.13" % "0.8.0", "com.github.TBMCPlugins.ChromaCore" % "Chroma-Core" % "v2.0.0-SNAPSHOT" % Provided, "net.ess3" % "EssentialsX" % "2.17.1" % Provided, - "net.luckperms" % "api" % "5.4" % Provided, // https://mvnrepository.com/artifact/com.mojang/brigadier "com.mojang" % "brigadier" % "1.0.500" % "provided", // https://mvnrepository.com/artifact/net.kyori/examination-api @@ -52,93 +45,7 @@ assembly / assemblyMergeStrategy := { val saveConfigComments = TaskKey[Seq[File]]("saveConfigComments") saveConfigComments := { - val sv = (Compile / sources).value - val cdataRegex = Pattern.compile("(?:def|val|var) (\\w+)(?::[^=]+)? = (?:getI?Config|DPUtils.\\w+Data)") //Hack: DPUtils - val clRegex = Pattern.compile("class (\\w+).* extends ((?:\\w|\\d)+)") - val objRegex = Pattern.compile("object (\\w+)") - val subRegex = Pattern.compile("def `?(\\w+)`?") - val subParamRegex = Pattern.compile("((?:\\w|\\d)+): ((?:\\w|\\d)+)") - val configConfig = new YamlConfiguration() - val commandConfig = new YamlConfiguration() - - def getConfigComments(line: String, clKey: String, comment: String, justCommented: Boolean): (String, String, Boolean) = { - val clMatcher = clRegex.matcher(line) - if (clKey == null && clMatcher.find()) { //First occurrence - (if (clMatcher.group(2).contains("Component")) - "components." + clMatcher.group(1) - else "global", comment, justCommented) - } else if (line.contains("/**")) { - (clKey, "", false) - } else if (line.contains("*/") && comment != null) - (clKey, comment, true) - else if (comment != null) { - if (justCommented) { - if (clKey != null) { - val matcher = cdataRegex.matcher(line) - if (matcher.find()) - configConfig.set(s"$clKey.${matcher.group(1)}", comment.trim) - } - else { - val matcher = objRegex.matcher(line) - if (matcher.find()) { - val clName = matcher.group(1) - val compKey = if (clName.contains("Module")) s"component.$clName" - else if (clName.contains("Plugin")) "global" - else null - if (compKey != null) - configConfig.set(s"$compKey.generalDescriptionInsteadOfAConfig", comment.trim) - } - } - (clKey, null, false) - } - else (clKey, comment + line.replaceFirst("^\\s*\\*\\s+", "") + "\n", justCommented) - } - else (clKey, comment, justCommented) - } - - for (file <- sv) { - Using(Source.fromFile(file)) { src => - var clKey: String = null - var comment: String = null - var justCommented: Boolean = false - - var subCommand = false - var pkg: String = null - var clName: String = null - for (line <- src.getLines) { - val (clk, c, jc) = getConfigComments(line, clKey, comment, justCommented) - clKey = clk; comment = c; justCommented = jc - - val objMatcher = objRegex.matcher(line) - val clMatcher = clRegex.matcher(line) - if (pkg == null && line.startsWith("package ")) - pkg = line.substring("package ".length) - else if (clName == null && objMatcher.find()) - clName = objMatcher.group(1) - else if (clName == null && clMatcher.find()) - clName = clMatcher.group(1) - val subMatcher = subRegex.matcher(line) - val subParamMatcher = subParamRegex.matcher(line) - val sub = line.contains("@Subcommand") || line.contains("@Command2.Subcommand") - if (sub) subCommand = true - else if (line.contains("}")) subCommand = false - if (subCommand && subMatcher.find()) { - /*val groups = (2 to subMatcher.groupCount()).map(subMatcher.group) - val pairs = for (i <- groups.indices by 2) yield (groups(i), groups(i + 1))*/ - val mname = subMatcher.group(1) - val params = Iterator.continually(()).takeWhile(_ => subParamMatcher.find()) - .map(_ => subParamMatcher.group(1)).drop(1) - val section = commandConfig.createSection(s"$pkg.$clName.$mname") - section.set("method", s"$mname()") - section.set("params", params.mkString(" ")) - subCommand = false - } - } - configConfig.save("target/configHelp.yml") - commandConfig.save("target/commands.yml") - }.recover[Unit]({ case t => t.printStackTrace() }) - } - Seq(file("target/configHelp.yml"), file("target/commands.yml")) + Commenter.saveConfigComments((Compile / sources).value) } Compile / resourceGenerators += saveConfigComments diff --git a/project/Commenter.scala b/project/Commenter.scala new file mode 100644 index 0000000..0dd6996 --- /dev/null +++ b/project/Commenter.scala @@ -0,0 +1,96 @@ +import java.util.regex.Pattern +import sbt.* +import org.bukkit.configuration.file.YamlConfiguration +import scala.io.Source +import scala.util.Using + +object Commenter { + def saveConfigComments(sv: Seq[File]): Seq[File] = { + val cdataRegex = Pattern.compile("(?:def|val|var) (\\w+)(?::[^=]+)? = (?:getI?Config|DPUtils.\\w+Data)") //Hack: DPUtils + val clRegex = Pattern.compile("class (\\w+).* extends ((?:\\w|\\d)+)") + val objRegex = Pattern.compile("object (\\w+)") + val subRegex = Pattern.compile("def `?(\\w+)`?") + val subParamRegex = Pattern.compile("((?:\\w|\\d)+): ((?:\\w|\\d)+)") + val configConfig = new YamlConfiguration() + val commandConfig = new YamlConfiguration() + + def getConfigComments(line: String, clKey: String, comment: String, justCommented: Boolean): (String, String, Boolean) = { + val clMatcher = clRegex.matcher(line) + if (clKey == null && clMatcher.find()) { //First occurrence + (if (clMatcher.group(2).contains("Component")) + "components." + clMatcher.group(1) + else "global", comment, justCommented) + } else if (line.contains("/**")) { + (clKey, "", false) + } else if (line.contains("*/") && comment != null) + (clKey, comment, true) + else if (comment != null) { + if (justCommented) { + if (clKey != null) { + val matcher = cdataRegex.matcher(line) + if (matcher.find()) + configConfig.set(s"$clKey.${matcher.group(1)}", comment.trim) + } + else { + val matcher = objRegex.matcher(line) + if (matcher.find()) { + val clName = matcher.group(1) + val compKey = if (clName.contains("Module")) s"component.$clName" + else if (clName.contains("Plugin")) "global" + else null + if (compKey != null) + configConfig.set(s"$compKey.generalDescriptionInsteadOfAConfig", comment.trim) + } + } + (clKey, null, false) + } + else (clKey, comment + line.replaceFirst("^\\s*\\*\\s+", "") + "\n", justCommented) + } + else (clKey, comment, justCommented) + } + + for (file <- sv) { + Using(Source.fromFile(file)) { src => + var clKey: String = null + var comment: String = null + var justCommented: Boolean = false + + var subCommand = false + var pkg: String = null + var clName: String = null + for (line <- src.getLines) { + val (clk, c, jc) = getConfigComments(line, clKey, comment, justCommented) + clKey = clk; comment = c; justCommented = jc + + val objMatcher = objRegex.matcher(line) + val clMatcher = clRegex.matcher(line) + if (pkg == null && line.startsWith("package ")) + pkg = line.substring("package ".length) + else if (clName == null && objMatcher.find()) + clName = objMatcher.group(1) + else if (clName == null && clMatcher.find()) + clName = clMatcher.group(1) + val subMatcher = subRegex.matcher(line) + val subParamMatcher = subParamRegex.matcher(line) + val sub = line.contains("@Subcommand") || line.contains("@Command2.Subcommand") + if (sub) subCommand = true + else if (line.contains("}")) subCommand = false + if (subCommand && subMatcher.find()) { + /*val groups = (2 to subMatcher.groupCount()).map(subMatcher.group) + val pairs = for (i <- groups.indices by 2) yield (groups(i), groups(i + 1))*/ + val mname = subMatcher.group(1) + val params = Iterator.continually(()).takeWhile(_ => subParamMatcher.find()) + .map(_ => subParamMatcher.group(1)).drop(1) + val section = commandConfig.createSection(s"$pkg.$clName.$mname") + section.set("method", s"$mname()") + section.set("params", params.mkString(" ")) + subCommand = false + } + } + configConfig.save("target/configHelp.yml") + commandConfig.save("target/commands.yml") + }.recover[Unit]({ case t => t.printStackTrace() }) + } + Seq(file("target/configHelp.yml"), file("target/commands.yml")) + } +} diff --git a/project/build.properties b/project/build.properties index fb0fc7f..2003f65 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1,2 +1,2 @@ sbt.version=1.8.2 -scala.version=3.0.0 \ No newline at end of file +scala.version=2.13.0 \ No newline at end of file diff --git a/project/build.sbt b/project/build.sbt index 95ec632..5a1fefe 100644 --- a/project/build.sbt +++ b/project/build.sbt @@ -2,5 +2,6 @@ //lazy val root = (project in file(".")).dependsOn(commenter) resolvers += Resolver.mavenLocal +resolvers += "paper-repo" at "https://papermc.io/repo/repository/maven-public/" -libraryDependencies += "org.spigotmc" % "spigot-api" % "1.19.4-R0.1-SNAPSHOT" +libraryDependencies += "io.papermc.paper" % "paper-api" % "1.19.4-R0.1-SNAPSHOT" % Compile diff --git a/src/main/scala/buttondevteam/discordplugin/ChromaBot.scala b/src/main/scala/buttondevteam/discordplugin/ChromaBot.scala index 86a230c..af6ae9f 100644 --- a/src/main/scala/buttondevteam/discordplugin/ChromaBot.scala +++ b/src/main/scala/buttondevteam/discordplugin/ChromaBot.scala @@ -4,7 +4,7 @@ import buttondevteam.discordplugin.ChannelconBroadcast.ChannelconBroadcast import buttondevteam.discordplugin.mcchat.MCChatUtils import discord4j.core.`object`.entity.Message import discord4j.core.`object`.entity.channel.MessageChannel -import reactor.core.publisher.Mono +import reactor.core.scala.publisher.SMono import javax.annotation.Nullable @@ -20,7 +20,7 @@ object ChromaBot { * * @param message The message to send, duh (use [[MessageChannel.createMessage]]) */ - def sendMessage(message: Mono[MessageChannel] => Mono[Message]): Unit = + def sendMessage(message: SMono[MessageChannel] => SMono[Message]): Unit = MCChatUtils.forPublicPrivateChat(message).subscribe() /** @@ -29,7 +29,7 @@ object ChromaBot { * @param message The message to send, duh * @param toggle The toggle type for channelcon */ - def sendMessageCustomAsWell(message: Mono[MessageChannel] => Mono[Message], @Nullable toggle: ChannelconBroadcast): Unit = + def sendMessageCustomAsWell(message: SMono[MessageChannel] => SMono[Message], @Nullable toggle: ChannelconBroadcast): Unit = MCChatUtils.forCustomAndAllMCChat(message.apply, toggle, hookmsg = false).subscribe() def updatePlayerList(): Unit = diff --git a/src/main/scala/buttondevteam/discordplugin/DPUtils.scala b/src/main/scala/buttondevteam/discordplugin/DPUtils.scala index 89d13bc..491c614 100644 --- a/src/main/scala/buttondevteam/discordplugin/DPUtils.scala +++ b/src/main/scala/buttondevteam/discordplugin/DPUtils.scala @@ -9,6 +9,7 @@ import discord4j.core.`object`.entity.{Guild, Message, Role} import discord4j.core.spec.EmbedCreateSpec import discord4j.core.spec.legacy.{LegacyEmbedCreateSpec, LegacySpec} import reactor.core.publisher.{Flux, Mono} +import reactor.core.scala.publisher.{SFlux, SMono} import java.util import java.util.Comparator @@ -69,21 +70,21 @@ object DPUtils { else DiscordPlugin.plugin.getLogger } - def channelData(config: IHaveConfig, key: String): IConfigData[Mono[MessageChannel]] = + def channelData(config: IHaveConfig, key: String): IConfigData[SMono[MessageChannel]] = config.getData(key, id => getMessageChannel(key, Snowflake.of(id.asInstanceOf[Long])), - (_: Mono[MessageChannel]) => 0L, 0L, true) //We can afford to search for the channel in the cache once (instead of using mainServer) + (_: SMono[MessageChannel]) => 0L, 0L, true) //We can afford to search for the channel in the cache once (instead of using mainServer) - def roleData(config: IHaveConfig, key: String, defName: String): IConfigData[Mono[Role]] = - roleData(config, key, defName, Mono.just(DiscordPlugin.mainServer)) + def roleData(config: IHaveConfig, key: String, defName: String): IConfigData[SMono[Role]] = + roleData(config, key, defName, SMono.just(DiscordPlugin.mainServer)) /** * Needs to be a [[ConfigData]] for checking if it's set */ - def roleData(config: IHaveConfig, key: String, defName: String, guild: Mono[Guild]): IConfigData[Mono[Role]] = config.getData(key, name => { - if (!name.isInstanceOf[String] || name.asInstanceOf[String].isEmpty) Mono.empty[Role] + def roleData(config: IHaveConfig, key: String, defName: String, guild: SMono[Guild]): IConfigData[SMono[Role]] = config.getData(key, name => { + if (!name.isInstanceOf[String] || name.asInstanceOf[String].isEmpty) SMono.empty[Role] else guild.flatMapMany(_.getRoles).filter(_.getName == name).onErrorResume(e => { getLogger.warning("Failed to get role data for " + key + "=" + name + " - " + e.getMessage) - Mono.empty[Role] + SMono.empty[Role] }).next }, _ => defName, defName, true) @@ -125,7 +126,7 @@ object DPUtils { */ def disableIfConfigErrorRes(@Nullable component: Component[DiscordPlugin], config: IConfigData[_], result: Any): Boolean = { //noinspection ConstantConditions - if (result == null || (result.isInstanceOf[Mono[_]] && !result.asInstanceOf[Mono[_]].hasElement.block())) { + if (result == null || (result.isInstanceOf[SMono[_]] && !result.asInstanceOf[SMono[_]].hasElement.block())) { var path: String = null try { if (component != null) Component.setComponentEnabled(component, false) @@ -145,26 +146,29 @@ object DPUtils { } /** - * Send a response in the form of "@User, message". Use Mono.empty() if you don't have a channel object. + * Send a response in the form of "@User, message". Use SMono.empty() if you don't have a channel object. * * @param original The original message to reply to * @param channel The channel to send the message in, defaults to the original * @param message The message to send * @return A mono to send the message */ - def reply(original: Message, @Nullable channel: MessageChannel, message: String): Mono[Message] = { - val ch = if (channel == null) original.getChannel - else Mono.just(channel) + @deprecated("Use reply(Message, SMono, String) instead", since = "1.1.0") + def reply(original: Message, @Nullable channel: MessageChannel, message: String): SMono[Message] = { + val ch = if (channel == null) original.getChannel.^^() + else SMono.just(channel) reply(original, ch, message) } /** * @see #reply(Message, MessageChannel, String) */ - def reply(original: Message, ch: Mono[MessageChannel], message: String): Mono[Message] = - ch.flatMap(channel => channel.createMessage((if (original.getAuthor.isPresent) - original.getAuthor.get.getMention + ", " - else "") + message)) + def reply(original: Message, ch: SMono[MessageChannel], message: String): SMono[Message] = + ch.switchIfEmpty(original.getChannel().^^()).flatMap(channel => channel.createMessage(( + if (original.getAuthor.isPresent) + original.getAuthor.get.getMention + ", " + else "" + ) + message).^^()) def nickMention(userId: Snowflake): String = "<@!" + userId.asString + ">" @@ -177,19 +181,27 @@ object DPUtils { * @param id The channel ID * @return A message channel */ - def getMessageChannel(key: String, id: Snowflake): Mono[MessageChannel] = { - if (id.asLong == 0L) return Mono.empty[MessageChannel] + def getMessageChannel(key: String, id: Snowflake): SMono[MessageChannel] = { + if (id.asLong == 0L) return SMono.empty[MessageChannel] - DiscordPlugin.dc.getChannelById(id).onErrorResume(e => { + DiscordPlugin.dc.getChannelById(id).^^().onErrorResume(e => { getLogger.warning(s"Failed to get channel data for $key=$id - ${e.getMessage}") - Mono.empty[Channel] - }).filter(ch => ch.isInstanceOf[MessageChannel]).cast(classOf[MessageChannel]) + SMono.empty[Channel] + }).filter(ch => ch.isInstanceOf[MessageChannel]).cast[MessageChannel] } - def getMessageChannel(config: IConfigData[Snowflake]): Mono[MessageChannel] = + def getMessageChannel(config: IConfigData[Snowflake]): SMono[MessageChannel] = getMessageChannel(config.getPath, config.get) - def ignoreError[T](mono: Mono[T]): Mono[T] = mono.onErrorResume((_: Throwable) => Mono.empty) + def ignoreError[T](mono: SMono[T]): SMono[T] = mono.onErrorResume((_: Throwable) => SMono.empty) + + implicit class MonoExtensions[T](mono: Mono[T]) { + def ^^(): SMono[T] = SMono(mono) + } + + implicit class FluxExtensions[T](flux: Flux[T]) { + def ^^(): SFlux[T] = SFlux(flux) + } implicit class SpecExtensions[T <: LegacySpec[_]](spec: T) { def ^^(): Unit = () diff --git a/src/main/scala/buttondevteam/discordplugin/DiscordPlugin.scala b/src/main/scala/buttondevteam/discordplugin/DiscordPlugin.scala index b8837af..7ff1aeb 100644 --- a/src/main/scala/buttondevteam/discordplugin/DiscordPlugin.scala +++ b/src/main/scala/buttondevteam/discordplugin/DiscordPlugin.scala @@ -1,19 +1,20 @@ package buttondevteam.discordplugin +import buttondevteam.discordplugin.DPUtils.{FluxExtensions, MonoExtensions} import buttondevteam.discordplugin.DiscordPlugin.dc import buttondevteam.discordplugin.announcer.AnnouncerModule import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule -import buttondevteam.discordplugin.commands.* +import buttondevteam.discordplugin.commands._ import buttondevteam.discordplugin.exceptions.ExceptionListenerModule import buttondevteam.discordplugin.fun.FunModule import buttondevteam.discordplugin.listeners.{CommonListeners, MCListener} import buttondevteam.discordplugin.mcchat.MinecraftChatModule -import buttondevteam.discordplugin.mcchat.sender.{DiscordUser, DiscordSenderBase} +import buttondevteam.discordplugin.mcchat.sender.{DiscordSenderBase, DiscordUser} import buttondevteam.discordplugin.mccommands.DiscordMCCommand import buttondevteam.discordplugin.role.GameRoleModule import buttondevteam.discordplugin.util.{DPState, Timings} import buttondevteam.lib.TBMCCoreAPI -import buttondevteam.lib.architecture.* +import buttondevteam.lib.architecture._ import buttondevteam.lib.architecture.config.IConfigData import buttondevteam.lib.player.ChromaGamerBase import com.google.common.io.Files @@ -32,11 +33,12 @@ import org.bukkit.configuration.file.YamlConfiguration import org.mockito.internal.util.MockUtil import reactor.core.Disposable import reactor.core.publisher.Mono +import reactor.core.scala.publisher.SMono import java.io.File import java.nio.charset.StandardCharsets import java.util.Optional -import scala.jdk.OptionConverters.* +import scala.jdk.OptionConverters._ @ButtonPlugin.ConfigOpts(disableConfigGen = true) object DiscordPlugin { private[discordplugin] var dc: GatewayDiscordClient = null @@ -66,14 +68,14 @@ import scala.jdk.OptionConverters.* /** * The main server where the roles and other information is pulled from. It's automatically set to the first server the bot's invited to. */ - private def mainServer = getIConfig.getData("mainServer", id => { //It attempts to get the default as well + private def mainServer = getIConfig.getData("mainServer", (id: Any) => { //It attempts to get the default as well if (id.asInstanceOf[Long] == 0L) Option.empty - else DiscordPlugin.dc.getGuildById(Snowflake.of(id.asInstanceOf[Long])) + else DiscordPlugin.dc.getGuildById(Snowflake.of(id.asInstanceOf[Long])).^^() .onErrorResume(t => { getLogger.warning("Failed to get guild: " + t.getMessage) - Mono.empty - }).blockOptional().toScala - }, g => g.map(_.getId.asLong).getOrElse(0L), 0L, true) + SMono.empty + }).blockOption() + }, (g: Option[Guild]) => g.map(_.getId.asLong).getOrElse(0L), 0L, true) /** * The (bot) channel to use for Discord commands like /role. @@ -83,7 +85,7 @@ import scala.jdk.OptionConverters.* * The role that allows using mod-only Discord commands. * If empty (''), then it will only allow for the owner. */ - def modRole: IConfigData[Mono[Role]] = DPUtils.roleData(getIConfig, "modRole", "Moderator") + def modRole: IConfigData[SMono[Role]] = DPUtils.roleData(getIConfig, "modRole", "Moderator") /** * The invite link to show by /discord invite. If empty, it defaults to the first invite if the bot has access. */ @@ -133,7 +135,7 @@ import scala.jdk.OptionConverters.* foo(t) }).subscribe((dc: GatewayDiscordClient) => { DiscordPlugin.dc = dc //Set to gateway client - dc.on(classOf[ReadyEvent]).map(_.getGuilds.size).flatMap(dc.on(classOf[GuildCreateEvent]).take(_).collectList) + dc.on(classOf[ReadyEvent]).^^().map(_.getGuilds.size).flatMap(dc.on(classOf[GuildCreateEvent]).take(_).collectList) .doOnError(_ => stopStarting()).subscribe(this.handleReady _) // Take all received GuildCreateEvents and make it a List () }) /* All guilds have been received, client is fully connected */ diff --git a/src/main/scala/buttondevteam/discordplugin/announcer/AnnouncerModule.scala b/src/main/scala/buttondevteam/discordplugin/announcer/AnnouncerModule.scala index 0a016de..9f41156 100644 --- a/src/main/scala/buttondevteam/discordplugin/announcer/AnnouncerModule.scala +++ b/src/main/scala/buttondevteam/discordplugin/announcer/AnnouncerModule.scala @@ -1,5 +1,6 @@ package buttondevteam.discordplugin.announcer +import buttondevteam.discordplugin.DPUtils.MonoExtensions import buttondevteam.discordplugin.mcchat.sender.DiscordUser import buttondevteam.discordplugin.{DPUtils, DiscordPlugin} import buttondevteam.lib.TBMCCoreAPI @@ -7,7 +8,7 @@ import buttondevteam.lib.architecture.{Component, ComponentMetadata} import buttondevteam.lib.player.ChromaGamerBase import com.google.gson.JsonParser import discord4j.core.`object`.entity.channel.MessageChannel -import reactor.core.publisher.Mono +import reactor.core.scala.publisher.SMono import scala.annotation.tailrec import scala.collection.mutable @@ -86,8 +87,8 @@ import scala.collection.mutable } } - def sendMsg(ch: Mono[MessageChannel], msg: String) = - ch.flatMap(c => c.createMessage(msg)).flatMap(_.pin).subscribe() + def sendMsg(ch: SMono[MessageChannel], msg: String) = + ch.flatMap(c => c.createMessage(msg).^^()).flatMap(_.pin.^^()).subscribe() if (msgsb.nonEmpty) sendMsg(channel.get(), msgsb.toString()) if (modmsgsb.nonEmpty) sendMsg(modChannel.get(), modmsgsb.toString()) diff --git a/src/main/scala/buttondevteam/discordplugin/commands/DebugCommand.scala b/src/main/scala/buttondevteam/discordplugin/commands/DebugCommand.scala index bc00edd..ffcdf21 100644 --- a/src/main/scala/buttondevteam/discordplugin/commands/DebugCommand.scala +++ b/src/main/scala/buttondevteam/discordplugin/commands/DebugCommand.scala @@ -1,24 +1,24 @@ package buttondevteam.discordplugin.commands +import buttondevteam.discordplugin.DPUtils.MonoExtensions import buttondevteam.discordplugin.DiscordPlugin import buttondevteam.discordplugin.listeners.CommonListeners import buttondevteam.lib.chat.{Command2, CommandClass} import discord4j.common.util.Snowflake import discord4j.core.`object`.entity.{Member, User} -import reactor.core.publisher.Mono -import scala.jdk.OptionConverters._ +import reactor.core.scala.publisher.SMono @CommandClass(helpText = Array("Switches debug mode.")) class DebugCommand extends ICommand2DC { @Command2.Subcommand override def `def`(sender: Command2DCSender): Boolean = { - Mono.justOrEmpty(sender.authorAsMember.orNull) + SMono.justOrEmpty(sender.authorAsMember.orNull) .switchIfEmpty(Option(sender.author) //Support DMs - .map((u: User) => u.asMember(DiscordPlugin.mainServer.getId)).toJava.orElse(Mono.empty[Member])) + .map((u: User) => u.asMember(DiscordPlugin.mainServer.getId).^^()).getOrElse(SMono.empty[Member])) .flatMap((m: Member) => DiscordPlugin.plugin.modRole.get .map(mr => m.getRoleIds.stream.anyMatch((r: Snowflake) => r == mr.getId)) - .switchIfEmpty(Mono.fromCallable(() => DiscordPlugin.mainServer.getOwnerId.asLong == m.getId.asLong))) - .onErrorResume(_ => Mono.just(false)) //Role not found + .switchIfEmpty(SMono.fromCallable(() => DiscordPlugin.mainServer.getOwnerId.asLong == m.getId.asLong))) + .onErrorResume(_ => SMono.just(false)) //Role not found .subscribe(success => { if (success) { CommonListeners.debug = !CommonListeners.debug diff --git a/src/main/scala/buttondevteam/discordplugin/commands/UserinfoCommand.scala b/src/main/scala/buttondevteam/discordplugin/commands/UserinfoCommand.scala index 739f982..a21eb94 100644 --- a/src/main/scala/buttondevteam/discordplugin/commands/UserinfoCommand.scala +++ b/src/main/scala/buttondevteam/discordplugin/commands/UserinfoCommand.scala @@ -1,11 +1,12 @@ package buttondevteam.discordplugin.commands +import buttondevteam.discordplugin.DPUtils.FluxExtensions import buttondevteam.discordplugin.DiscordPlugin import buttondevteam.discordplugin.mcchat.sender.DiscordUser import buttondevteam.lib.chat.{Command2, CommandClass} import buttondevteam.lib.player.ChromaGamerBase import buttondevteam.lib.player.ChromaGamerBase.InfoTarget -import discord4j.core.`object`.entity.{Message, User} +import discord4j.core.`object`.entity.{Member, Message, User} import scala.jdk.CollectionConverters.ListHasAsScala @@ -33,9 +34,9 @@ class UserinfoCommand extends ICommand2DC { private def getUsers(message: Message, args: String) = { val guild = message.getGuild.block if (guild == null) { //Private channel - DiscordPlugin.dc.getUsers.filter(u => u.getUsername.equalsIgnoreCase(args)).collectList().block() + DiscordPlugin.dc.getUsers.^^().filter(u => u.getUsername.equalsIgnoreCase(args)).collectSeq().block() } else - guild.getMembers.filter(_.getUsername.equalsIgnoreCase(args)).map(_.asInstanceOf[User]).collectList().block() + guild.getMembers.^^().filter(_.getUsername.equalsIgnoreCase(args)).map(_.asInstanceOf[User]).collectSeq().block() } } \ No newline at end of file diff --git a/src/main/scala/buttondevteam/discordplugin/exceptions/DebugMessageListener.scala b/src/main/scala/buttondevteam/discordplugin/exceptions/DebugMessageListener.scala index cca550d..0054c98 100644 --- a/src/main/scala/buttondevteam/discordplugin/exceptions/DebugMessageListener.scala +++ b/src/main/scala/buttondevteam/discordplugin/exceptions/DebugMessageListener.scala @@ -1,6 +1,7 @@ package buttondevteam.discordplugin.exceptions import buttondevteam.core.ComponentManager +import buttondevteam.discordplugin.DPUtils.MonoExtensions import buttondevteam.discordplugin.DiscordPlugin import buttondevteam.lib.TBMCDebugMessageEvent import discord4j.core.`object`.entity.channel.MessageChannel @@ -16,7 +17,7 @@ object DebugMessageListener { sb.append("```").append("\n") sb.append(if (message.length > 2000) message.substring(0, 2000) else message).append("\n") sb.append("```") - mc.flatMap((ch: MessageChannel) => ch.createMessage(sb.toString)).subscribe() + mc.flatMap((ch: MessageChannel) => ch.createMessage(sb.toString).^^()).subscribe() } catch { case ex: Exception => ex.printStackTrace() diff --git a/src/main/scala/buttondevteam/discordplugin/exceptions/ExceptionListenerModule.scala b/src/main/scala/buttondevteam/discordplugin/exceptions/ExceptionListenerModule.scala index 254d546..bb706ab 100644 --- a/src/main/scala/buttondevteam/discordplugin/exceptions/ExceptionListenerModule.scala +++ b/src/main/scala/buttondevteam/discordplugin/exceptions/ExceptionListenerModule.scala @@ -1,15 +1,16 @@ package buttondevteam.discordplugin.exceptions import buttondevteam.core.ComponentManager +import buttondevteam.discordplugin.DPUtils.MonoExtensions import buttondevteam.discordplugin.{DPUtils, DiscordPlugin} import buttondevteam.lib.architecture.Component import buttondevteam.lib.{TBMCCoreAPI, TBMCExceptionEvent} +import discord4j.core.`object`.entity.Guild import discord4j.core.`object`.entity.channel.{GuildChannel, MessageChannel} -import discord4j.core.`object`.entity.{Guild, Role} import org.apache.commons.lang.exception.ExceptionUtils import org.bukkit.Bukkit import org.bukkit.event.{EventHandler, Listener} -import reactor.core.publisher.Mono +import reactor.core.scala.publisher.SMono import java.util import java.util.stream.Collectors @@ -22,11 +23,10 @@ object ExceptionListenerModule { if (instance == null) return () try getChannel.flatMap(channel => { val coderRole = channel match { - case ch: GuildChannel => instance.pingRole(ch.getGuild).get - case _ => Mono.empty + case ch: GuildChannel => instance.pingRole(ch.getGuild.^^()).get + case _ => SMono.empty } - coderRole.map((role: Role) => if (TBMCCoreAPI.IsTestServer) new StringBuilder - else new StringBuilder(role.getMention).append("\n")) + coderRole.map(role => if (TBMCCoreAPI.IsTestServer) new StringBuilder else new StringBuilder(role.getMention).append("\n")) // Ping if prod server .defaultIfEmpty(new StringBuilder).flatMap(sb => { sb.append(sourcemessage).append("\n") sb.append("```").append("\n") @@ -36,7 +36,7 @@ object ExceptionListenerModule { if (sb.length + stackTrace.length >= 1980) stackTrace = stackTrace.substring(0, 1980 - sb.length) sb.append(stackTrace).append("\n") sb.append("```") - channel.createMessage(sb.toString) + channel.createMessage(sb.toString).^^() }) }).subscribe() catch { @@ -47,9 +47,9 @@ object ExceptionListenerModule { private var instance: ExceptionListenerModule = null - def getChannel: Mono[MessageChannel] = { + def getChannel: SMono[MessageChannel] = { if (instance != null) return instance.channel.get - Mono.empty + SMono.empty } } @@ -80,7 +80,7 @@ class ExceptionListenerModule extends Component[DiscordPlugin] with Listener { /** * The role to ping if an error occurs. Set to empty ('') to disable. */ - private def pingRole(guild: Mono[Guild]) = DPUtils.roleData(getConfig, "pingRole", "Coder", guild) + private def pingRole(guild: SMono[Guild]) = DPUtils.roleData(getConfig, "pingRole", "Coder", guild) override protected def enable(): Unit = { if (DPUtils.disableIfConfigError(this, channel)) return () diff --git a/src/main/scala/buttondevteam/discordplugin/fun/FunModule.scala b/src/main/scala/buttondevteam/discordplugin/fun/FunModule.scala index 36f642e..673d2bf 100644 --- a/src/main/scala/buttondevteam/discordplugin/fun/FunModule.scala +++ b/src/main/scala/buttondevteam/discordplugin/fun/FunModule.scala @@ -1,6 +1,7 @@ package buttondevteam.discordplugin.fun import buttondevteam.core.ComponentManager +import buttondevteam.discordplugin.DPUtils.{FluxExtensions, MonoExtensions} import buttondevteam.discordplugin.{DPUtils, DiscordPlugin} import buttondevteam.lib.TBMCCoreAPI import buttondevteam.lib.architecture.config.IConfigData @@ -10,11 +11,13 @@ import discord4j.core.`object`.entity.channel.{GuildChannel, MessageChannel} import discord4j.core.`object`.entity.{Guild, Message} import discord4j.core.`object`.presence.Status import discord4j.core.event.domain.PresenceUpdateEvent +import discord4j.core.spec.{EmbedCreateSpec, MessageCreateSpec} import discord4j.core.spec.legacy.{LegacyEmbedCreateSpec, LegacyMessageCreateSpec} import org.bukkit.Bukkit import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.event.{EventHandler, Listener} import reactor.core.publisher.Mono +import reactor.core.scala.publisher.SMono import java.util import java.util.Calendar @@ -53,7 +56,7 @@ object FunModule { ListC += 1 ListC - 1 } > 2) { // Lowered already - DPUtils.reply(message, Mono.empty, "stop it. You know the answer.").subscribe() + DPUtils.reply(message, SMono.empty, "stop it. You know the answer.").subscribe() lastlist = 0 lastlistp = Bukkit.getOnlinePlayers.size.toShort return true //Handled @@ -63,7 +66,7 @@ object FunModule { var next = 0 if (usableServerReadyStrings.size == 0) fm.createUsableServerReadyStrings() next = usableServerReadyStrings.remove(serverReadyRandom.nextInt(usableServerReadyStrings.size)) - DPUtils.reply(message, Mono.empty, fm.serverReadyAnswers.get.get(next)).subscribe() + DPUtils.reply(message, SMono.empty, fm.serverReadyAnswers.get.get(next)).subscribe() return false //Still process it as a command/mcchat if needed } false @@ -79,17 +82,20 @@ object FunModule { || event.getCurrent.getStatus == Status.OFFLINE) return () //If it's not an offline -> online change fm.fullHouseChannel.get.filter((ch: MessageChannel) => ch.isInstanceOf[GuildChannel]) - .flatMap(channel => fm.fullHouseDevRole(channel.asInstanceOf[GuildChannel].getGuild).get - .filterWhen(devrole => event.getMember - .flatMap(m => m.getRoles.any(_.getId.asLong == devrole.getId.asLong))) - .filterWhen(devrole => event.getGuild + .flatMap(channel => fm.fullHouseDevRole(channel.asInstanceOf[GuildChannel].getGuild.^^()).get + .filterWhen(devrole => event.getMember.^^() + .flatMap(m => m.getRoles.^^().any(_.getId.asLong == devrole.getId.asLong))) + .filterWhen(devrole => event.getGuild.^^() .flatMapMany(g => g.getMembers.filter(_.getRoleIds.stream.anyMatch(_ == devrole.getId))) .flatMap(_.getPresence).all(_.getStatus != Status.OFFLINE)) .filter(_ => lasttime + 10 < TimeUnit.NANOSECONDS.toHours(System.nanoTime)) //This should stay so it checks this last .flatMap(_ => { lasttime = TimeUnit.NANOSECONDS.toHours(System.nanoTime) - channel.createMessage(_.setContent("Full house!") - .setEmbed((ecs: LegacyEmbedCreateSpec) => ecs.setImage("https://cdn.discordapp.com/attachments/249295547263877121/249687682618359808/poker-hand-full-house-aces-kings-playing-cards-15553791.png"))) + channel.createMessage(MessageCreateSpec.builder().content("Full house!") + .addEmbed(EmbedCreateSpec.builder() + .image("https://cdn.discordapp.com/attachments/249295547263877121/249687682618359808/poker-hand-full-house-aces-kings-playing-cards-15553791.png") + .build()) + .build()).^^() })).subscribe() } } @@ -104,6 +110,7 @@ class FunModule extends Component[DiscordPlugin] with Listener { "when will the server be done", "when will the server be complete", "when will the server be finished", "when's the server ready", "when's the server open", "vhen vill ze server be open?")) + /** * Answers for a recognized question. Selected randomly. */ @@ -126,7 +133,7 @@ class FunModule extends Component[DiscordPlugin] with Listener { /** * If all of the people who have this role are online, the bot will post a full house. */ - private def fullHouseDevRole(guild: Mono[Guild]) = DPUtils.roleData(getConfig, "fullHouseDevRole", "Developer", guild) + private def fullHouseDevRole(guild: SMono[Guild]) = DPUtils.roleData(getConfig, "fullHouseDevRole", "Developer", guild) /** * The channel to post the full house to. diff --git a/src/main/scala/buttondevteam/discordplugin/listeners/CommonListeners.scala b/src/main/scala/buttondevteam/discordplugin/listeners/CommonListeners.scala index d2c6a6f..8667d60 100644 --- a/src/main/scala/buttondevteam/discordplugin/listeners/CommonListeners.scala +++ b/src/main/scala/buttondevteam/discordplugin/listeners/CommonListeners.scala @@ -1,5 +1,6 @@ package buttondevteam.discordplugin.listeners +import buttondevteam.discordplugin.DPUtils.FluxExtensions import buttondevteam.discordplugin.commands.{Command2DCSender, ConnectCommand} import buttondevteam.discordplugin.fun.FunModule import buttondevteam.discordplugin.mcchat.MinecraftChatModule @@ -17,35 +18,34 @@ 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.SMono object CommonListeners { val timings = new Timings def register(dispatcher: EventDispatcher): Unit = { dispatcher.on(classOf[MessageCreateEvent]).flatMap((event: MessageCreateEvent) => { - Mono.just(event.getMessage).filter(_ => !DiscordPlugin.SafeMode) + SMono.just(event.getMessage).filter(_ => !DiscordPlugin.SafeMode) .filter(message => message.getAuthor.filter(!_.isBot).isPresent) .filter(message => !FunModule.executeMemes(message)) .filterWhen(message => { Option(Component.getComponents.get(classOf[MinecraftChatModule])).filter(_.isEnabled) - .map(_.asInstanceOf[MinecraftChatModule].getListener.handleDiscord(event).asInstanceOf[Mono[java.lang.Boolean]]) - .getOrElse(Mono.just(true)) //Wasn't handled, continue + .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) FunModule.handleFullHouse(event) }) - dispatcher.on(classOf[RoleCreateEvent]).subscribe(GameRoleModule.handleRoleEvent) - dispatcher.on(classOf[RoleDeleteEvent]).subscribe(GameRoleModule.handleRoleEvent) - dispatcher.on(classOf[RoleUpdateEvent]).subscribe(GameRoleModule.handleRoleEvent) - dispatcher.on(classOf[ChatInputInteractionEvent], event => { - if(event.getCommandName() equals "connect") { - val asd = Mono.just(new ConnectCommand().`def`(new Command2DCSender(event), event.getOption("name").get.getValue.get.asString)) - asd - } else - Mono.empty() - }).subscribe() + dispatcher.on(classOf[RoleCreateEvent]).^^().subscribe(GameRoleModule.handleRoleEvent _) + dispatcher.on(classOf[RoleDeleteEvent]).^^().subscribe(GameRoleModule.handleRoleEvent _) + dispatcher.on(classOf[RoleUpdateEvent]).^^().subscribe(GameRoleModule.handleRoleEvent _) + dispatcher.on(classOf[ChatInputInteractionEvent]).^^().subscribe((event: ChatInputInteractionEvent) => { + if (event.getCommandName equals "connect") { + new ConnectCommand().`def`(new Command2DCSender(event), event.getOption("name").get.getValue.get.asString) + } + }) } var debug = false diff --git a/src/main/scala/buttondevteam/discordplugin/listeners/MCListener.scala b/src/main/scala/buttondevteam/discordplugin/listeners/MCListener.scala index 9179864..63335e5 100644 --- a/src/main/scala/buttondevteam/discordplugin/listeners/MCListener.scala +++ b/src/main/scala/buttondevteam/discordplugin/listeners/MCListener.scala @@ -1,5 +1,6 @@ package buttondevteam.discordplugin.listeners +import buttondevteam.discordplugin.DPUtils.MonoExtensions import buttondevteam.discordplugin.commands.ConnectCommand import buttondevteam.discordplugin.mcchat.MinecraftChatModule import buttondevteam.discordplugin.util.DPState @@ -11,6 +12,8 @@ import discord4j.common.util.Snowflake import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.event.{EventHandler, Listener} import reactor.core.publisher.Mono +import reactor.core.scala.publisher.SMono + import scala.jdk.OptionConverters._ class MCListener extends Listener { @@ -25,12 +28,12 @@ class MCListener extends Listener { @EventHandler def onGetInfo(e: TBMCPlayerGetInfoEvent): Unit = { Option(DiscordPlugin.SafeMode).filterNot(identity).flatMap(_ => Option(e.getPlayer.getAs(classOf[DiscordUser]))) .flatMap(dp => Option(dp.getDiscordID)).filter(_.nonEmpty) - .map(Snowflake.of).flatMap(id => DiscordPlugin.dc.getUserById(id).onErrorResume(_ => Mono.empty).blockOptional().toScala) + .map(Snowflake.of).flatMap(id => DiscordPlugin.dc.getUserById(id).^^().onErrorResume(_ => SMono.empty).blockOption()) .map(user => { e.addInfo("Discord tag: " + user.getUsername + "#" + user.getDiscriminator) user }) - .flatMap(user => user.asMember(DiscordPlugin.mainServer.getId).onErrorResume(t => Mono.empty).blockOptional().toScala) + .flatMap(user => user.asMember(DiscordPlugin.mainServer.getId).^^().onErrorResume(t => SMono.empty).blockOption()) .flatMap(member => member.getPresence.blockOptional().toScala) .map(pr => { e.addInfo(pr.getStatus.toString) diff --git a/src/main/scala/buttondevteam/discordplugin/mcchat/ChannelconCommand.scala b/src/main/scala/buttondevteam/discordplugin/mcchat/ChannelconCommand.scala index 0071ef2..78020a9 100644 --- a/src/main/scala/buttondevteam/discordplugin/mcchat/ChannelconCommand.scala +++ b/src/main/scala/buttondevteam/discordplugin/mcchat/ChannelconCommand.scala @@ -1,26 +1,27 @@ package buttondevteam.discordplugin.mcchat import buttondevteam.core.component.channel.{Channel, ChatRoom} -import buttondevteam.discordplugin.* import buttondevteam.discordplugin.ChannelconBroadcast.ChannelconBroadcast +import buttondevteam.discordplugin.DPUtils.MonoExtensions +import buttondevteam.discordplugin._ import buttondevteam.discordplugin.commands.{Command2DCSender, ICommand2DC} import buttondevteam.discordplugin.mcchat.sender.{DiscordConnectedPlayer, DiscordUser} import buttondevteam.lib.TBMCSystemChatEvent -import buttondevteam.lib.architecture.config.IConfigData import buttondevteam.lib.chat.{Command2, CommandClass} import buttondevteam.lib.player.{ChromaGamerBase, TBMCPlayer} import discord4j.core.`object`.entity.Message import discord4j.core.`object`.entity.channel.{GuildChannel, MessageChannel} import discord4j.rest.util.{Permission, PermissionSet} import org.bukkit.Bukkit -import reactor.core.publisher.Mono +import reactor.core.scala.publisher.SMono import java.lang.reflect.Method -import java.util import java.util.function.Supplier -import java.util.stream.Collectors import java.util.{Objects, Optional} import javax.annotation.Nullable +import scala.jdk.Accumulator +import scala.jdk.OptionConverters.RichOptional +import scala.jdk.StreamConverters.StreamHasToScala @SuppressWarnings(Array("SimplifyOptionalCallChains")) //Java 11 @CommandClass(helpText = Array("Channel connect", // @@ -38,9 +39,9 @@ class ChannelconCommand(private val module: MinecraftChatModule) extends IComman val message: Message = null // TODO if (checkPerms(message, null)) return true else if (MCChatCustom.removeCustomChat(message.getChannelId)) - DPUtils.reply(message, Mono.empty, "channel connection removed.").subscribe() + DPUtils.reply(message, SMono.empty, "channel connection removed.").subscribe() else - DPUtils.reply(message, Mono.empty, "this channel isn't connected.").subscribe() + DPUtils.reply(message, SMono.empty, "this channel isn't connected.").subscribe() true } @@ -56,11 +57,11 @@ class ChannelconCommand(private val module: MinecraftChatModule) extends IComman val togglesString: Supplier[String] = () => ChannelconBroadcast.values .map(t => t.toString.toLowerCase + ": " + (if ((cc.toggles & (1 << t.id)) == 0) "disabled" else "enabled")) .mkString("\n") + "\n\n" + - TBMCSystemChatEvent.BroadcastTarget.stream.map((target: TBMCSystemChatEvent.BroadcastTarget) => - target.getName + ": " + (if (cc.brtoggles.contains(target)) "enabled" else "disabled")) - .collect(Collectors.joining("\n")) + TBMCSystemChatEvent.BroadcastTarget.stream.toScala(Accumulator) + .map(target => s"${target.getName}: ${if (cc.brtoggles.contains(target)) "enabled" else "disabled"}") + .mkString("\n") if (toggle == null) { - DPUtils.reply(message, Mono.empty, "toggles:\n" + togglesString.get).subscribe() + DPUtils.reply(message, SMono.empty, "toggles:\n" + togglesString.get).subscribe() return true } val arg: String = toggle.toUpperCase @@ -68,7 +69,7 @@ class ChannelconCommand(private val module: MinecraftChatModule) extends IComman if (b.isEmpty) { val bt: TBMCSystemChatEvent.BroadcastTarget = TBMCSystemChatEvent.BroadcastTarget.get(arg) if (bt == null) { - DPUtils.reply(message, Mono.empty, "cannot find toggle. Toggles:\n" + togglesString.get).subscribe() + DPUtils.reply(message, SMono.empty, "cannot find toggle. Toggles:\n" + togglesString.get).subscribe() return true } val add: Boolean = !cc.brtoggles.contains(bt) @@ -88,7 +89,7 @@ class ChannelconCommand(private val module: MinecraftChatModule) extends IComman //1 1 | 0 // XOR cc.toggles ^= (1 << b.get.id) - DPUtils.reply(message, Mono.empty, "'" + b.get.toString.toLowerCase + "' " + DPUtils.reply(message, SMono.empty, "'" + b.get.toString.toLowerCase + "' " + (if ((cc.toggles & (1 << b.get.id)) == 0) "disabled" else "enabled")).subscribe() true } @@ -157,7 +158,7 @@ class ChannelconCommand(private val module: MinecraftChatModule) extends IComman return true } //noinspection OptionalGetWithoutIsPresent - val perms: PermissionSet = (channel.asInstanceOf[GuildChannel]).getEffectivePermissions(message.getAuthor.map(_.getId).get).block + val perms: PermissionSet = (channel.asInstanceOf[GuildChannel]).getEffectivePermissions(message.getAuthor.toScala.map(_.getId).get).block if (!(perms.contains(Permission.ADMINISTRATOR)) && !(perms.contains(Permission.MANAGE_CHANNELS))) { DPUtils.reply(message, channel, "you need to have manage permissions for this channel!").subscribe() return true @@ -176,6 +177,6 @@ class ChannelconCommand(private val module: MinecraftChatModule) extends IComman "To remove a connection use @ChromaBot channelcon remove in the channel.", "Mentioning the bot is needed in this case because the " + DiscordPlugin.getPrefix + " prefix only works in " + DPUtils.botmention + ".", "Invite link: info.getId.asString).blockOption().getOrElse("Unknown") + "&scope=bot&permissions=268509264>") } \ No newline at end of file diff --git a/src/main/scala/buttondevteam/discordplugin/mcchat/MCChatCustom.scala b/src/main/scala/buttondevteam/discordplugin/mcchat/MCChatCustom.scala index 2ae259b..b88b91c 100644 --- a/src/main/scala/buttondevteam/discordplugin/mcchat/MCChatCustom.scala +++ b/src/main/scala/buttondevteam/discordplugin/mcchat/MCChatCustom.scala @@ -59,9 +59,9 @@ object MCChatCustom { def getCustomChats: List[CustomLMD] = lastmsgCustom.toList // TODO: Store Chroma user only - class CustomLMD private[mcchat](channel: MessageChannel, user: User, val groupID: String, + class CustomLMD private[mcchat](channel: MessageChannel, val dcUser: User, val groupID: String, mcchannel: Channel, val dcp: DiscordConnectedPlayer, var toggles: Int, - var brtoggles: Set[TBMCSystemChatEvent.BroadcastTarget]) extends MCChatUtils.LastMsgData(channel, user, mcchannel) { + var brtoggles: Set[TBMCSystemChatEvent.BroadcastTarget]) extends MCChatUtils.LastMsgData(channel, mcchannel, dcp.getChromaUser) { } } \ No newline at end of file diff --git a/src/main/scala/buttondevteam/discordplugin/mcchat/MCChatListener.scala b/src/main/scala/buttondevteam/discordplugin/mcchat/MCChatListener.scala index 3cbc9ac..6ab38d2 100644 --- a/src/main/scala/buttondevteam/discordplugin/mcchat/MCChatListener.scala +++ b/src/main/scala/buttondevteam/discordplugin/mcchat/MCChatListener.scala @@ -1,10 +1,10 @@ package buttondevteam.discordplugin.mcchat import buttondevteam.core.ComponentManager -import buttondevteam.discordplugin.* -import buttondevteam.discordplugin.DPUtils.SpecExtensions -import buttondevteam.discordplugin.mcchat.sender.{DiscordUser, DiscordSender, DiscordSenderBase} -import buttondevteam.lib.* +import buttondevteam.discordplugin._ +import buttondevteam.discordplugin.DPUtils.{MonoExtensions, SpecExtensions} +import buttondevteam.discordplugin.mcchat.sender.{DiscordSender, DiscordSenderBase, DiscordUser} +import buttondevteam.lib._ import buttondevteam.lib.chat.{ChatMessage, TBMCChatAPI} import buttondevteam.lib.player.TBMCPlayer import com.vdurmont.emoji.EmojiParser @@ -22,6 +22,7 @@ import org.bukkit.entity.Player import org.bukkit.event.{EventHandler, Listener} import org.bukkit.scheduler.BukkitTask import reactor.core.publisher.Mono +import reactor.core.scala.publisher.SMono import java.time.Instant import java.util @@ -148,7 +149,7 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener { } for (data <- MCChatPrivate.lastmsgPerUser) { - if ((e.isFromCommand || isdifferentchannel.test(data.channel.getId)) && e.shouldSendTo(MCChatUtils.getSender(data.channel.getId, data.user))) { + if ((e.isFromCommand || isdifferentchannel.test(data.channel.getId)) && e.shouldSendTo(data.user)) { doit(data) } } @@ -254,11 +255,11 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener { private var recthread: Thread = null // Discord - def handleDiscord(ev: MessageCreateEvent): Mono[Boolean] = { + def handleDiscord(ev: MessageCreateEvent): SMono[Boolean] = { val author = Option(ev.getMessage.getAuthor.orElse(null)) val hasCustomChat = MCChatCustom.hasCustomChat(ev.getMessage.getChannelId) val prefix = DiscordPlugin.getPrefix - ev.getMessage.getChannel + ev.getMessage.getChannel.^^() .filter(channel => isChatEnabled(channel, author, hasCustomChat)) .filter(channel => !isRunningMCChatCommand(channel, ev.getMessage.getContent, prefix)) .filter(channel => { @@ -311,8 +312,8 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener { def replaceUserMentions(): Unit = { for (u <- event.getMessage.getUserMentions.asScala) { //TODO: Role mentions dmessage = dmessage.replace(u.getMention, "@" + u.getUsername) // TODO: IG Formatting - val m = u.asMember(DiscordPlugin.mainServer.getId).onErrorResume(_ => Mono.empty).blockOptional - if (m.isPresent) { + val m = u.asMember(DiscordPlugin.mainServer.getId).^^().onErrorResume(_ => SMono.empty).blockOption() + if (m.nonEmpty) { val mm: Member = m.get val nick: String = mm.getDisplayName dmessage = dmessage.replace(mm.getNicknameMention, "@" + nick) @@ -418,8 +419,7 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener { def notWhitelisted(cmd: String) = module.whitelistedCommands.get.stream .noneMatch(s => cmd == s || cmd.startsWith(s + " ")) - def whitelistedCommands = module.whitelistedCommands.get.stream - .map("/" + _).collect(Collectors.joining(", ")) + def whitelistedCommands = module.whitelistedCommands.get.asScala.map("/" + _).mkString(", ") if (!isPrivate) event.getMessage.delete.subscribe() @@ -469,9 +469,9 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener { */ private def runCustomCommand(dsender: DiscordSenderBase, cmdlowercased: String): Boolean = { if (cmdlowercased.startsWith("list")) { - val players = Bukkit.getOnlinePlayers - dsender.sendMessage("There are " + players.stream.filter(MCChatUtils.checkEssentials).count + " out of " + Bukkit.getMaxPlayers + " players online.") - dsender.sendMessage("Players: " + players.stream.filter(MCChatUtils.checkEssentials).map(_.getDisplayName).collect(Collectors.joining(", "))) + val players = Bukkit.getOnlinePlayers.asScala + dsender.sendMessage("There are " + players.count(MCChatUtils.checkEssentials) + " out of " + Bukkit.getMaxPlayers + " players online.") + dsender.sendMessage("Players: " + players.filter(MCChatUtils.checkEssentials).map(_.getDisplayName).mkString(", ")) true } else false diff --git a/src/main/scala/buttondevteam/discordplugin/mcchat/MCChatPrivate.scala b/src/main/scala/buttondevteam/discordplugin/mcchat/MCChatPrivate.scala index 00451a5..7601c49 100644 --- a/src/main/scala/buttondevteam/discordplugin/mcchat/MCChatPrivate.scala +++ b/src/main/scala/buttondevteam/discordplugin/mcchat/MCChatPrivate.scala @@ -54,7 +54,7 @@ object MCChatPrivate { // ---- PermissionsEx warning is normal on logout ---- } if (!start) MCChatUtils.lastmsgfromd.remove(channel.getId.asLong) - if (start) lastmsgPerUser += new MCChatUtils.LastMsgData(channel, user) // Doesn't support group DMs + if (start) lastmsgPerUser += new MCChatUtils.LastMsgData(channel, dp) // Doesn't support group DMs else lastmsgPerUser.filterInPlace(_.channel.getId.asLong != channel.getId.asLong) //Remove } } diff --git a/src/main/scala/buttondevteam/discordplugin/mcchat/MCChatUtils.scala b/src/main/scala/buttondevteam/discordplugin/mcchat/MCChatUtils.scala index db206cc..3ae653c 100644 --- a/src/main/scala/buttondevteam/discordplugin/mcchat/MCChatUtils.scala +++ b/src/main/scala/buttondevteam/discordplugin/mcchat/MCChatUtils.scala @@ -1,27 +1,25 @@ package buttondevteam.discordplugin.mcchat import buttondevteam.core.{ComponentManager, MainPlugin, component} -import buttondevteam.discordplugin.* import buttondevteam.discordplugin.ChannelconBroadcast.ChannelconBroadcast -import buttondevteam.discordplugin.DPUtils.SpecExtensions +import buttondevteam.discordplugin.DPUtils.MonoExtensions +import buttondevteam.discordplugin._ import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule import buttondevteam.discordplugin.mcchat.MCChatCustom.CustomLMD import buttondevteam.discordplugin.mcchat.sender.{DiscordConnectedPlayer, DiscordPlayerSender, DiscordSender, DiscordSenderBase} -import buttondevteam.lib.player.{ChromaGamerBase, TBMCPlayerBase} +import buttondevteam.lib.player.ChromaGamerBase import buttondevteam.lib.{TBMCCoreAPI, TBMCSystemChatEvent} import com.google.common.collect.Sets import discord4j.common.util.Snowflake import discord4j.core.`object`.entity.channel.{Channel, MessageChannel, PrivateChannel, TextChannel} import discord4j.core.`object`.entity.{Message, User} -import discord4j.core.spec.legacy.LegacyTextChannelEditSpec import io.netty.util.collection.LongObjectHashMap import org.bukkit.Bukkit -import org.bukkit.command.CommandSender import org.bukkit.entity.Player import org.bukkit.event.Event import org.bukkit.event.player.{AsyncPlayerPreLoginEvent, PlayerJoinEvent, PlayerLoginEvent, PlayerQuitEvent} import org.bukkit.plugin.AuthorNagException -import reactor.core.publisher.{Flux, Mono} +import reactor.core.scala.publisher.SMono import java.net.InetAddress import java.util @@ -31,12 +29,11 @@ import java.util.concurrent.atomic.AtomicInteger import java.util.logging.Level import java.util.stream.Collectors import javax.annotation.Nullable -import scala.collection.{concurrent, mutable} import scala.collection.convert.ImplicitConversions.`map AsJavaMap` import scala.collection.mutable.ListBuffer -import scala.jdk.CollectionConverters.{CollectionHasAsScala, SeqHasAsJava} +import scala.collection.{concurrent, mutable} +import scala.jdk.CollectionConverters.CollectionHasAsScala import scala.jdk.javaapi.CollectionConverters.asScala -import scala.jdk.javaapi.OptionConverters.* object MCChatUtils { /** @@ -84,7 +81,7 @@ object MCChatUtils { gid = buttondevteam.core.component.channel.Channel.GROUP_EVERYONE // (Though it's a public chat then rn) } val C = new AtomicInteger - s(s.length - 1) = "Players: " + Bukkit.getOnlinePlayers.stream.filter(p => if (lmd.mcchannel == null) { + s(s.length - 1) = "Players: " + Bukkit.getOnlinePlayers.asScala.filter(p => if (lmd.mcchannel == null) { gid == buttondevteam.core.component.channel.Channel.GROUP_EVERYONE //If null, allow if public (custom chats will have their channel stored anyway) } else { @@ -92,7 +89,7 @@ object MCChatUtils { } ).filter(MCChatUtils.checkEssentials) //If they can see it .filter(_ => C.incrementAndGet > 0) //Always true - .map((p) => DPUtils.sanitizeString(p.getDisplayName)).collect(Collectors.joining(", ")) + .map((p) => DPUtils.sanitizeString(p.getDisplayName)).mkString(", ") s(0) = s"$C player${if (C.get != 1) "s" else ""} online" lmd.channel.asInstanceOf[TextChannel].edit().withTopic(String.join("\n----\n", s: _*)).withReason("Player list update").subscribe() //Don't wait } @@ -126,11 +123,11 @@ object MCChatUtils { else null.asInstanceOf } - def forPublicPrivateChat(action: Mono[MessageChannel] => Mono[_]): Mono[_] = { - if (notEnabled) return Mono.empty - val list = MCChatPrivate.lastmsgPerUser.map(data => action(Mono.just(data.channel))) + def forPublicPrivateChat(action: SMono[MessageChannel] => SMono[_]): SMono[_] = { + if (notEnabled) return SMono.empty + val list = MCChatPrivate.lastmsgPerUser.map(data => action(SMono.just(data.channel))) .prepend(action(module.chatChannelMono)) - Mono.whenDelayError(list.asJava) + SMono.whenDelayError(list) } /** @@ -140,14 +137,14 @@ object MCChatUtils { * @param toggle The toggle to check * @param hookmsg Whether the message is also sent from the hook */ - def forCustomAndAllMCChat(action: Mono[MessageChannel] => Mono[_], @Nullable toggle: ChannelconBroadcast, hookmsg: Boolean): Mono[_] = { - if (notEnabled) return Mono.empty + def forCustomAndAllMCChat(action: SMono[MessageChannel] => SMono[_], @Nullable toggle: ChannelconBroadcast, hookmsg: Boolean): SMono[_] = { + if (notEnabled) return SMono.empty val list = List(if (!GeneralEventBroadcasterModule.isHooked || !hookmsg) - forPublicPrivateChat(action) else Mono.empty) ++ + forPublicPrivateChat(action) else SMono.empty) ++ (if (toggle == null) MCChatCustom.lastmsgCustom else MCChatCustom.lastmsgCustom.filter(cc => (cc.toggles & (1 << toggle.id)) != 0)) - .map(_.channel).map(Mono.just).map(action) - Mono.whenDelayError(list.asJava) + .map(_.channel).map(SMono.just).map(action) + SMono.whenDelayError(list) } /** @@ -157,15 +154,15 @@ object MCChatUtils { * @param permUser The user to check perms of or null to send to all that has it toggled * @param toggle The toggle to check or null to send to all allowed */ - def forAllowedCustomMCChat(action: Mono[MessageChannel] => Mono[_], @Nullable permUser: ChromaGamerBase, @Nullable toggle: ChannelconBroadcast): Mono[_] = { - if (notEnabled) return Mono.empty + def forAllowedCustomMCChat(action: SMono[MessageChannel] => SMono[_], @Nullable permUser: ChromaGamerBase, @Nullable toggle: ChannelconBroadcast): SMono[_] = { + if (notEnabled) return SMono.empty val st = MCChatCustom.lastmsgCustom.filter(clmd => { //new TBMCChannelConnectFakeEvent(sender, clmd.mcchannel).shouldSendTo(clmd.dcp) - Thought it was this simple hehe - Wait, it *should* be this simple if (toggle != null && ((clmd.toggles & (1 << toggle.id)) == 0)) false //If null then allow else if (permUser == null) true else clmd.groupID.equals(clmd.mcchannel.getGroupID(permUser)) - }).map(cc => action.apply(Mono.just(cc.channel))) //TODO: Send error messages on channel connect - //Mono.whenDelayError((() => st.iterator).asInstanceOf[java.lang.Iterable[Mono[_]]]) //Can't convert as an iterator or inside the stream, but I can convert it as a stream - Mono.whenDelayError(st.asJava) + }).map(cc => action.apply(SMono.just(cc.channel))) //TODO: Send error messages on channel connect + //Mono.whenDelayError((() => st.iterator).asInstanceOf[java.lang.Iterable[SMono[_]]]) //Can't convert as an iterator or inside the stream, but I can convert it as a stream + SMono.whenDelayError(st) } /** @@ -176,38 +173,38 @@ object MCChatUtils { * @param toggle The toggle to check or null to send to all allowed * @param hookmsg Whether the message is also sent from the hook */ - def forAllowedCustomAndAllMCChat(action: Mono[MessageChannel] => Mono[_], @Nullable permUser: ChromaGamerBase, @Nullable toggle: ChannelconBroadcast, hookmsg: Boolean): Mono[_] = { - if (notEnabled) return Mono.empty + def forAllowedCustomAndAllMCChat(action: SMono[MessageChannel] => SMono[_], @Nullable permUser: ChromaGamerBase, @Nullable toggle: ChannelconBroadcast, hookmsg: Boolean): SMono[_] = { + if (notEnabled) return SMono.empty val cc = forAllowedCustomMCChat(action, permUser, toggle) - if (!GeneralEventBroadcasterModule.isHooked || !hookmsg) return Mono.whenDelayError(forPublicPrivateChat(action), cc) - Mono.whenDelayError(cc) + if (!GeneralEventBroadcasterModule.isHooked || !hookmsg) return SMono.whenDelayError(List(forPublicPrivateChat(action), cc)) + SMono.whenDelayError(List(cc)) } - def send(message: String): Mono[MessageChannel] => Mono[_] = _.flatMap((mc: MessageChannel) => { + def send(message: String): SMono[MessageChannel] => SMono[_] = _.flatMap((mc: MessageChannel) => { resetLastMessage(mc) - mc.createMessage(DPUtils.sanitizeString(message)) + mc.createMessage(DPUtils.sanitizeString(message)).^^() }) - def forAllowedMCChat(action: Mono[MessageChannel] => Mono[_], event: TBMCSystemChatEvent): Mono[_] = { - if (notEnabled) return Mono.empty - val list = new ListBuffer[Mono[_]] + def forAllowedMCChat(action: SMono[MessageChannel] => SMono[_], event: TBMCSystemChatEvent): SMono[_] = { + if (notEnabled) return SMono.empty + val list = new ListBuffer[SMono[_]] if (event.getChannel.isGlobal) list.append(action(module.chatChannelMono)) for (data <- MCChatPrivate.lastmsgPerUser) - if (event.shouldSendTo(getSender(data.channel.getId, data.user))) - list.append(action(Mono.just(data.channel))) //TODO: Only store ID? + if (event.shouldSendTo(data.user)) + list.append(action(SMono.just(data.channel))) //TODO: Only store ID? MCChatCustom.lastmsgCustom.filter(clmd => clmd.brtoggles.contains(event.getTarget) && event.shouldSendTo(clmd.dcp.getChromaUser)) - .map(clmd => action(Mono.just(clmd.channel))).foreach(elem => { + .map(clmd => action(SMono.just(clmd.channel))).foreach(elem => { list.append(elem) () }) - Mono.whenDelayError(list.asJava) + SMono.whenDelayError(list) } /** * This method will find the best sender to use: if the player is online, use that, if not but connected then use that etc. */ - private[mcchat] def getSender(channel: Snowflake, author: User): DiscordSenderBase = { //noinspection OptionalGetWithoutIsPresent + private[mcchat] def getSender(channel: Snowflake, author: User): DiscordSenderBase = { Option(getSenderFrom(OnlineSenders, channel, author)) // Find first non-null .orElse(Option(getSenderFrom(ConnectedSenders, channel, author))) // This doesn't support the public chat, but it'll always return null for it .orElse(Option(getSenderFrom(UnconnectedSenders, channel, author))) // @@ -347,13 +344,14 @@ object MCChatUtils { private[mcchat] def callEventSync(event: Event) = Bukkit.getScheduler.runTask(DiscordPlugin.plugin, () => callEventExcludingSome(event)) - class LastMsgData(val channel: MessageChannel, val user: User) { + class LastMsgData(val channel: MessageChannel, @Nullable val user: ChromaGamerBase) { + var message: Message = null var time = 0L var content: String = null var mcchannel: component.channel.Channel = null - protected def this(channel: MessageChannel, user: User, mcchannel: component.channel.Channel) = { + protected def this(channel: MessageChannel, mcchannel: component.channel.Channel, user: ChromaGamerBase) = { this(channel, user) this.mcchannel = mcchannel } diff --git a/src/main/scala/buttondevteam/discordplugin/mcchat/MCListener.scala b/src/main/scala/buttondevteam/discordplugin/mcchat/MCListener.scala index a3a9d85..f7907c3 100644 --- a/src/main/scala/buttondevteam/discordplugin/mcchat/MCListener.scala +++ b/src/main/scala/buttondevteam/discordplugin/mcchat/MCListener.scala @@ -1,7 +1,8 @@ package buttondevteam.discordplugin.mcchat -import buttondevteam.discordplugin.* -import buttondevteam.discordplugin.mcchat.sender.{DiscordConnectedPlayer, DiscordUser, DiscordPlayerSender} +import buttondevteam.discordplugin.DPUtils.{FluxExtensions, MonoExtensions} +import buttondevteam.discordplugin._ +import buttondevteam.discordplugin.mcchat.sender.{DiscordConnectedPlayer, DiscordPlayerSender, DiscordUser} import buttondevteam.lib.TBMCSystemChatEvent import buttondevteam.lib.player.{ChromaGamerBase, TBMCPlayer, TBMCPlayerBase, TBMCYEEHAWEvent} import discord4j.common.util.Snowflake @@ -11,11 +12,12 @@ import net.ess3.api.events.{AfkStatusChangeEvent, MuteStatusChangeEvent, NickCha import org.bukkit.Bukkit import org.bukkit.entity.Player import org.bukkit.event.entity.PlayerDeathEvent -import org.bukkit.event.player.* import org.bukkit.event.player.PlayerLoginEvent.Result +import org.bukkit.event.player._ import org.bukkit.event.server.{BroadcastMessageEvent, TabCompleteEvent} import org.bukkit.event.{EventHandler, EventPriority, Listener} -import reactor.core.publisher.{Flux, Mono} +import reactor.core.publisher.Flux +import reactor.core.scala.publisher.SMono class MCListener(val module: MinecraftChatModule) extends Listener { final private val muteRole = DPUtils.roleData(module.getConfig, "muteRole", "Muted") @@ -34,11 +36,11 @@ class MCListener(val module: MinecraftChatModule) extends Listener { val p = e.getPlayer val dp = TBMCPlayerBase.getPlayer(p.getUniqueId, classOf[TBMCPlayer]).getAs(classOf[DiscordUser]) if (dp != null) - DiscordPlugin.dc.getUserById(Snowflake.of(dp.getDiscordID)).flatMap(user => - user.getPrivateChannel.flatMap(chan => module.chatChannelMono.flatMap(cc => { + DiscordPlugin.dc.getUserById(Snowflake.of(dp.getDiscordID)).^^().flatMap(user => + user.getPrivateChannel.^^().flatMap(chan => module.chatChannelMono.flatMap(cc => { MCChatUtils.addSenderTo(MCChatUtils.OnlineSenders, dp.getDiscordID, DiscordPlayerSender.create(user, chan, p, module)) MCChatUtils.addSenderTo(MCChatUtils.OnlineSenders, dp.getDiscordID, DiscordPlayerSender.create(user, cc, p, module)) //Stored per-channel - Mono.empty + SMono.empty }))).subscribe() val message = e.getJoinMessage sendJoinLeaveMessage(message, e.getPlayer) @@ -86,17 +88,17 @@ class MCListener(val module: MinecraftChatModule) extends Listener { if (!source.isPlayer) return () val p = TBMCPlayerBase.getPlayer(source.getPlayer.getUniqueId, classOf[TBMCPlayer]).getAs(classOf[DiscordUser]) if (p == null) return () - DPUtils.ignoreError(DiscordPlugin.dc.getUserById(Snowflake.of(p.getDiscordID)) - .flatMap(user => user.asMember(DiscordPlugin.mainServer.getId)) + DPUtils.ignoreError(DiscordPlugin.dc.getUserById(Snowflake.of(p.getDiscordID)).^^() + .flatMap(user => user.asMember(DiscordPlugin.mainServer.getId).^^()) .flatMap(user => role.flatMap((r: Role) => { - def foo(r: Role): Mono[_] = { + def foo(r: Role): SMono[_] = { if (e.getValue) user.addRole(r.getId) else user.removeRole(r.getId) val modlog = module.modlogChannel.get val msg = s"${(if (e.getValue) "M" else "Unm")}uted user: ${user.getUsername}#${user.getDiscriminator}" module.log(msg) - if (modlog != null) return modlog.flatMap((ch: MessageChannel) => ch.createMessage(msg)) - Mono.empty + if (modlog != null) return modlog.flatMap((ch: MessageChannel) => ch.createMessage(msg).^^()) + SMono.empty } foo(r) @@ -111,13 +113,13 @@ class MCListener(val module: MinecraftChatModule) extends Listener { MCChatUtils.forCustomAndAllMCChat(MCChatUtils.send(event.getMessage), ChannelconBroadcast.BROADCAST, hookmsg = false).subscribe() } - @EventHandler def onYEEHAW(event: TBMCYEEHAWEvent): Unit = { //TODO: Inherit from the chat event base to have channel support + @EventHandler def onYEEHAW(event: TBMCYEEHAWEvent): Unit = { //TODO: Implement as a colored system message to have channel support val name = event.getSender match { case player: Player => player.getDisplayName case _ => event.getSender.getName } //Channel channel = ChromaGamerBase.getFromSender(event.getSender()).channel().get(); - TODO - DiscordPlugin.mainServer.getEmojis.filter(e => "YEEHAW" == e.getName).take(1).singleOrEmpty + DiscordPlugin.mainServer.getEmojis.^^().filter(e => "YEEHAW" == e.getName).take(1).singleOrEmpty .map(Option.apply).defaultIfEmpty(Option.empty) .flatMap(yeehaw => MCChatUtils.forPublicPrivateChat(MCChatUtils.send(name + yeehaw.map(guildEmoji => " <:YEEHAW:" + guildEmoji.getId.asString + ">s").getOrElse(" YEEHAWs")))).subscribe() @@ -130,7 +132,7 @@ class MCListener(val module: MinecraftChatModule) extends Listener { val t = event.getBuffer.substring(i + 1) //0 if not found if (!t.startsWith("@")) return () val token = t.substring(1) - val x = DiscordPlugin.mainServer.getMembers.flatMap(m => Flux.just(m.getUsername, m.getNickname.orElse(""))) + val x = DiscordPlugin.mainServer.getMembers.^^().flatMap(m => Flux.just(m.getUsername, m.getNickname.orElse(""))) .filter(_.startsWith(token)).map("@" + _).doOnNext(event.getCompletions.add(_)).blockLast() } diff --git a/src/main/scala/buttondevteam/discordplugin/mcchat/MinecraftChatModule.scala b/src/main/scala/buttondevteam/discordplugin/mcchat/MinecraftChatModule.scala index 142d49d..b1ce7d8 100644 --- a/src/main/scala/buttondevteam/discordplugin/mcchat/MinecraftChatModule.scala +++ b/src/main/scala/buttondevteam/discordplugin/mcchat/MinecraftChatModule.scala @@ -1,6 +1,7 @@ package buttondevteam.discordplugin.mcchat import buttondevteam.core.component.channel.Channel +import buttondevteam.discordplugin.DPUtils.MonoExtensions import buttondevteam.discordplugin.mcchat.sender.DiscordConnectedPlayer import buttondevteam.discordplugin.util.DPState import buttondevteam.discordplugin.{ChannelconBroadcast, DPUtils, DiscordPlugin} @@ -10,9 +11,11 @@ import buttondevteam.lib.{TBMCCoreAPI, TBMCSystemChatEvent} import com.google.common.collect.Lists import discord4j.common.util.Snowflake import discord4j.core.`object`.entity.channel.MessageChannel +import discord4j.core.spec.EmbedCreateSpec import discord4j.rest.util.Color import org.bukkit.Bukkit import reactor.core.publisher.Mono +import reactor.core.scala.publisher.SMono import java.util import java.util.stream.Collectors @@ -46,12 +49,12 @@ class MinecraftChatModule extends Component[DiscordPlugin] { */ def chatChannel: IConfigData[Snowflake] = DPUtils.snowflakeData(getConfig, "chatChannel", 0L) - def chatChannelMono: Mono[MessageChannel] = DPUtils.getMessageChannel(chatChannel.getPath, chatChannel.get) + def chatChannelMono: SMono[MessageChannel] = DPUtils.getMessageChannel(chatChannel.getPath, chatChannel.get) /** * The channel where the plugin can log when it mutes a player on Discord because of a Minecraft mute */ - def modlogChannel: IConfigData[Mono[MessageChannel]] = DPUtils.channelData(getConfig, "modlogChannel") + def modlogChannel: IConfigData[SMono[MessageChannel]] = DPUtils.channelData(getConfig, "modlogChannel") /** * The plugins to exclude from fake player events used for the 'mcchat' command - some plugins may crash, add them here */ @@ -167,7 +170,7 @@ class MinecraftChatModule extends Component[DiscordPlugin] { } else { val kickmsg = if (Bukkit.getOnlinePlayers.size > 0) - DPUtils.sanitizeString(Bukkit.getOnlinePlayers.stream.map(_.getDisplayName).collect(Collectors.joining(", "))) + + DPUtils.sanitizeString(Bukkit.getOnlinePlayers.asScala.map(_.getDisplayName).mkString(", ")) + (if (Bukkit.getOnlinePlayers.size == 1) " was " else " were ") + "thrown out" //TODO: Make configurable else "" if (MinecraftChatModule.state eq DPState.RESTARTING_SERVER) sendStateMessage(Color.ORANGE, "Server restarting", kickmsg) @@ -190,7 +193,7 @@ class MinecraftChatModule extends Component[DiscordPlugin] { val chconc = chconsc.createSection(chcon.channel.getId.asString) chconc.set("mcchid", chcon.mcchannel.getIdentifier) chconc.set("chid", chcon.channel.getId.asLong) - chconc.set("did", chcon.user.getId.asLong) + chconc.set("did", chcon.dcUser.getId.asLong) chconc.set("mcuid", chcon.dcp.getUniqueId.toString) chconc.set("mcname", chcon.dcp.getName) chconc.set("groupid", chcon.groupID) @@ -209,14 +212,14 @@ class MinecraftChatModule extends Component[DiscordPlugin] { * It will block to make sure all messages are sent */ private def sendStateMessage(color: Color, message: String) = - MCChatUtils.forCustomAndAllMCChat(_.flatMap( - _.createEmbed(_.setColor(color).setTitle(message)) - .onErrorResume(_ => Mono.empty) + MCChatUtils.forCustomAndAllMCChat(_.flatMap(ch => ch.createMessage( + EmbedCreateSpec.builder().color(color).title(message).build()).^^() + .onErrorResume(_ => SMono.empty) ), ChannelconBroadcast.RESTART, hookmsg = false).block() private def sendStateMessage(color: Color, message: String, extra: String) = - MCChatUtils.forCustomAndAllMCChat(_.flatMap( - _.createEmbed(_.setColor(color).setTitle(message).setDescription(extra)) - .onErrorResume(_ => Mono.empty) + MCChatUtils.forCustomAndAllMCChat(_.flatMap(ch => ch.createMessage( + EmbedCreateSpec.builder().color(color).title(message).description(extra).build()).^^() + .onErrorResume(_ => SMono.empty) ), ChannelconBroadcast.RESTART, hookmsg = false).block() } \ No newline at end of file diff --git a/src/main/scala/buttondevteam/discordplugin/mcchat/sender/DiscordConnectedPlayer.scala b/src/main/scala/buttondevteam/discordplugin/mcchat/sender/DiscordConnectedPlayer.scala index f23e510..1393102 100644 --- a/src/main/scala/buttondevteam/discordplugin/mcchat/sender/DiscordConnectedPlayer.scala +++ b/src/main/scala/buttondevteam/discordplugin/mcchat/sender/DiscordConnectedPlayer.scala @@ -4,7 +4,7 @@ import buttondevteam.discordplugin.mcchat.MinecraftChatModule import discord4j.core.`object`.entity.User import discord4j.core.`object`.entity.channel.MessageChannel import net.kyori.adventure.text.Component -import org.bukkit.* +import org.bukkit._ import org.bukkit.attribute.{Attribute, AttributeInstance, AttributeModifier} import org.bukkit.entity.{Entity, Player} import org.bukkit.event.inventory.InventoryType @@ -18,7 +18,7 @@ import org.mockito.{MockSettings, Mockito} import java.lang.reflect.Modifier import java.util -import java.util.* +import java.util._ object DiscordConnectedPlayer { def create(user: User, channel: MessageChannel, uuid: UUID, mcname: String, module: MinecraftChatModule): DiscordConnectedPlayer = @@ -53,9 +53,9 @@ object DiscordConnectedPlayer { * @param playerName The Minecraft name of the player. * @param module The MinecraftChatModule or null if testing. */ -abstract class DiscordConnectedPlayer(user: User, channel: MessageChannel, val uniqueId: UUID, val playerName: String, val module: MinecraftChatModule) extends DiscordSenderBase(user, channel) with IMCPlayer[DiscordConnectedPlayer] { +abstract class DiscordConnectedPlayer(user: User, channel: MessageChannel, val uniqueId: UUID, val playerName: String, val module: MinecraftChatModule) extends DiscordSenderBase(user, channel) with IMCPlayer[DiscordConnectedPlayer] with Player { private var loggedIn = false - private var displayName: String = playerName + private var dispName: String = playerName private var location: Location = if (module == null) null else Bukkit.getWorlds.get(0).getSpawnLocation private val basePlayer: OfflinePlayer = if (module == null) null else Bukkit.getOfflinePlayer(uniqueId) @@ -93,7 +93,7 @@ abstract class DiscordConnectedPlayer(user: User, channel: MessageChannel, val u def setPerm(perm: PermissibleBase): Unit = this.perm = perm - override def setDisplayName(displayName: String): Unit = this.displayName = displayName + override def setDisplayName(displayName: String): Unit = this.dispName = displayName override def getVanillaCmdListener = this.vanillaCmdListener @@ -107,7 +107,7 @@ abstract class DiscordConnectedPlayer(user: User, channel: MessageChannel, val u override def getUniqueId: UUID = this.uniqueId - override def getDisplayName: String = this.displayName + override def getDisplayName: String = this.dispName /** * For testing @@ -191,6 +191,9 @@ abstract class DiscordConnectedPlayer(user: User, channel: MessageChannel, val u override def getValue: Double = getDefaultValue override def getDefaultValue: Double = 20 //Works for max health, should be okay for the rest + + override def addTransientModifier(modifier: AttributeModifier): Unit = { + } } override def getGameMode = GameMode.SPECTATOR diff --git a/src/main/scala/buttondevteam/discordplugin/mcchat/sender/DiscordPlayerSender.scala b/src/main/scala/buttondevteam/discordplugin/mcchat/sender/DiscordPlayerSender.scala index edc1e27..80a3685 100644 --- a/src/main/scala/buttondevteam/discordplugin/mcchat/sender/DiscordPlayerSender.scala +++ b/src/main/scala/buttondevteam/discordplugin/mcchat/sender/DiscordPlayerSender.scala @@ -23,7 +23,7 @@ object DiscordPlayerSender { }).useConstructor(user, channel, player, module)) } -abstract class DiscordPlayerSender(user: User, channel: MessageChannel, var player: Player, val module: Nothing) extends DiscordSenderBase(user, channel) with IMCPlayer[DiscordPlayerSender] { +abstract class DiscordPlayerSender(user: User, channel: MessageChannel, var player: Player, val module: Nothing) extends DiscordSenderBase(user, channel) with IMCPlayer[DiscordPlayerSender] with Player { override def getVanillaCmdListener = null @@ -32,8 +32,8 @@ abstract class DiscordPlayerSender(user: User, channel: MessageChannel, var play super.sendMessage(message) } - override def sendMessage(messages: Array[? <: String]): Unit = { - player.sendMessage(messages*) - super.sendMessage(messages) + override def sendMessage(messages: String*): Unit = { + player.sendMessage(messages: _*) + super.sendMessage(messages: _*) } } \ No newline at end of file diff --git a/src/main/scala/buttondevteam/discordplugin/mcchat/sender/DiscordSender.scala b/src/main/scala/buttondevteam/discordplugin/mcchat/sender/DiscordSender.scala index f6d6c00..61f8c74 100644 --- a/src/main/scala/buttondevteam/discordplugin/mcchat/sender/DiscordSender.scala +++ b/src/main/scala/buttondevteam/discordplugin/mcchat/sender/DiscordSender.scala @@ -1,5 +1,6 @@ package buttondevteam.discordplugin.mcchat.sender +import buttondevteam.discordplugin.DPUtils.MonoExtensions import buttondevteam.discordplugin.DiscordPlugin import discord4j.core.`object`.entity.User import discord4j.core.`object`.entity.channel.MessageChannel @@ -9,15 +10,16 @@ import org.bukkit.permissions.{PermissibleBase, Permission, PermissionAttachment import org.bukkit.plugin.Plugin import org.bukkit.{Bukkit, Server} import reactor.core.publisher.Mono +import reactor.core.scala.publisher.SMono -import scala.jdk.OptionConverters.* +import scala.jdk.OptionConverters._ import java.util class DiscordSender(user: User, channel: MessageChannel, pname: String) extends DiscordSenderBase(user, channel) with CommandSender { private val perm = new PermissibleBase(this) private val senderName: String = Option(pname) - .orElse(Option(user).flatMap(u => u.asMember(DiscordPlugin.mainServer.getId) - .onErrorResume(_ => Mono.empty).blockOptional().toScala + .orElse(Option(user).flatMap(u => u.asMember(DiscordPlugin.mainServer.getId).^^() + .onErrorResume(_ => SMono.empty).blockOption() .map(u => u.getDisplayName))) .getOrElse("Discord user") diff --git a/src/main/scala/buttondevteam/discordplugin/mcchat/sender/DiscordSenderBase.scala b/src/main/scala/buttondevteam/discordplugin/mcchat/sender/DiscordSenderBase.scala index 0caa0b9..77a958a 100644 --- a/src/main/scala/buttondevteam/discordplugin/mcchat/sender/DiscordSenderBase.scala +++ b/src/main/scala/buttondevteam/discordplugin/mcchat/sender/DiscordSenderBase.scala @@ -64,8 +64,8 @@ abstract class DiscordSenderBase protected(var user: User, var channel: MessageC TBMCCoreAPI.SendException("An error occured while sending message to DiscordSender", e, DiscordPlugin.plugin) } - override def sendMessage(messages: Array[? <: String]): Unit = sendMessage(String.join("\n", messages: _*)) + override def sendMessage(messages: String*): Unit = sendMessage(messages.mkString("\n")) override def sendMessage(sender: UUID, message: String): Unit = sendMessage(message) - override def sendMessage(sender: UUID, messages: Array[? <: String]): Unit = sendMessage(messages) + override def sendMessage(sender: UUID, messages: String*): Unit = sendMessage(messages : _*) } \ No newline at end of file diff --git a/src/main/scala/buttondevteam/discordplugin/mcchat/sender/DiscordUser.scala b/src/main/scala/buttondevteam/discordplugin/mcchat/sender/DiscordUser.scala index 28b5135..fe8b030 100644 --- a/src/main/scala/buttondevteam/discordplugin/mcchat/sender/DiscordUser.scala +++ b/src/main/scala/buttondevteam/discordplugin/mcchat/sender/DiscordUser.scala @@ -1,5 +1,6 @@ package buttondevteam.discordplugin.mcchat.sender +import buttondevteam.core.component.channel.Channel import buttondevteam.discordplugin.DiscordPlugin import buttondevteam.discordplugin.mcchat.MCChatPrivate import buttondevteam.lib.player.{ChromaGamerBase, UserClass} @@ -26,4 +27,12 @@ import discord4j.core.`object`.entity.User * [[MCChatPrivate.privateMCChat]] */ def isMinecraftChatEnabled: Boolean = MCChatPrivate.isMinecraftChatEnabled(this) + + override def checkChannelInGroup(s: String): Channel.RecipientTestResult = ??? + + override def sendMessage(message: String): Unit = ??? // TODO: Somehow check which message is this a response to + + override def sendMessage(message: Array[String]): Unit = ??? + + override def getName: String = ??? } \ No newline at end of file diff --git a/src/main/scala/buttondevteam/discordplugin/mccommands/DiscordMCCommand.scala b/src/main/scala/buttondevteam/discordplugin/mccommands/DiscordMCCommand.scala index 149bcb3..10abf95 100644 --- a/src/main/scala/buttondevteam/discordplugin/mccommands/DiscordMCCommand.scala +++ b/src/main/scala/buttondevteam/discordplugin/mccommands/DiscordMCCommand.scala @@ -1,7 +1,8 @@ package buttondevteam.discordplugin.mccommands +import buttondevteam.discordplugin.DPUtils.FluxExtensions import buttondevteam.discordplugin.commands.{ConnectCommand, VersionCommand} -import buttondevteam.discordplugin.mcchat.sender.{DiscordUser, DiscordSenderBase} +import buttondevteam.discordplugin.mcchat.sender.{DiscordSenderBase, DiscordUser} import buttondevteam.discordplugin.mcchat.{MCChatUtils, MinecraftChatModule} import buttondevteam.discordplugin.util.DPState import buttondevteam.discordplugin.{DPUtils, DiscordPlugin} @@ -96,7 +97,7 @@ import java.lang.reflect.Method "Version command", "Prints the plugin version")) def version(sender: CommandSender): Unit = { - sender.sendMessage(VersionCommand.getVersion*) + sender.sendMessage(VersionCommand.getVersion: _*) } @Command2.Subcommand(helpText = Array( @@ -112,9 +113,9 @@ import java.lang.reflect.Method sender.sendMessage("§bInvite link: " + invi) return () } - DiscordPlugin.mainServer.getInvites.limitRequest(1) + DiscordPlugin.mainServer.getInvites.^^().take(1) .switchIfEmpty(Mono.fromRunnable(() => sender.sendMessage("§cNo invites found for the server."))) - .subscribe((inv: ExtendedInvite) => sender.sendMessage("§bInvite link: https://discord.gg/" + inv.getCode), _ => sender.sendMessage("§cThe invite link is not set and the bot has no permission to get it.")) + .subscribe((inv: ExtendedInvite) => sender.sendMessage("§bInvite link: https://discord.gg/" + inv.getCode), Some(_ => sender.sendMessage("§cThe invite link is not set and the bot has no permission to get it."))) } override def getHelpText(method: Method, ann: Command2.Subcommand): Array[String] = { diff --git a/src/main/scala/buttondevteam/discordplugin/role/GameRoleModule.scala b/src/main/scala/buttondevteam/discordplugin/role/GameRoleModule.scala index 7369b56..3088e3b 100644 --- a/src/main/scala/buttondevteam/discordplugin/role/GameRoleModule.scala +++ b/src/main/scala/buttondevteam/discordplugin/role/GameRoleModule.scala @@ -1,6 +1,7 @@ package buttondevteam.discordplugin.role import buttondevteam.core.ComponentManager +import buttondevteam.discordplugin.DPUtils.{FluxExtensions, MonoExtensions} import buttondevteam.discordplugin.{DPUtils, DiscordPlugin} import buttondevteam.lib.architecture.{Component, ComponentMetadata} import discord4j.core.`object`.entity.Role @@ -9,8 +10,11 @@ import discord4j.core.event.domain.role.{RoleCreateEvent, RoleDeleteEvent, RoleE import discord4j.rest.util.Color import org.bukkit.Bukkit import reactor.core.publisher.Mono +import reactor.core.scala.publisher.SMono import java.util.Collections +import scala.collection.mutable +import scala.collection.mutable.ListBuffer import scala.jdk.CollectionConverters.SeqHasAsJava /** @@ -24,19 +28,26 @@ import scala.jdk.CollectionConverters.SeqHasAsJava val GameRoles = grm.GameRoles val logChannel = grm.logChannel.get val notMainServer = (_: Role).getGuildId.asLong != DiscordPlugin.mainServer.getId.asLong + + def removeFromList = (name: String) => { + val c = GameRoles.size + GameRoles.subtractOne(name) + c > GameRoles.size + } + roleEvent match { case roleCreateEvent: RoleCreateEvent => Bukkit.getScheduler.runTaskLaterAsynchronously(DiscordPlugin.plugin, () => { val role = roleCreateEvent.getRole if (!notMainServer(role)) { grm.isGameRole(role).flatMap(b => { - if (!b) Mono.empty //Deleted or not a game role + if (!b) SMono.empty //Deleted or not a game role else { - GameRoles.add(role.getName) + GameRoles.addOne(role.getName) if (logChannel != null) logChannel.flatMap(_.createMessage("Added " + role.getName + " as game role." + - " If you don't want this, change the role's color from the game role color.")) + " If you don't want this, change the role's color from the game role color.").^^()) else - Mono.empty + SMono.empty } }).subscribe() () @@ -46,8 +57,8 @@ import scala.jdk.CollectionConverters.SeqHasAsJava val role = roleDeleteEvent.getRole.orElse(null) if (role == null) return () if (notMainServer(role)) return () - if (GameRoles.remove(role.getName) && logChannel != null) - logChannel.flatMap(_.createMessage("Removed " + role.getName + " as a game role.")).subscribe() + if (removeFromList(role.getName) && logChannel != null) + logChannel.flatMap(_.createMessage("Removed " + role.getName + " as a game role.").^^()).subscribe() case roleUpdateEvent: RoleUpdateEvent => if (!roleUpdateEvent.getOld.isPresent) { grm.logWarn("Old role not stored, cannot update game role!") @@ -58,22 +69,22 @@ import scala.jdk.CollectionConverters.SeqHasAsJava val cr = roleUpdateEvent.getCurrent grm.isGameRole(cr).flatMap(isGameRole => { if (!isGameRole) - if (GameRoles.remove(or.getName) && logChannel != null) - logChannel.flatMap(_.createMessage("Removed " + or.getName + " as a game role because its color changed.")) + if (removeFromList(or.getName) && logChannel != null) + logChannel.flatMap(_.createMessage("Removed " + or.getName + " as a game role because its color changed.").^^()) else - Mono.empty + SMono.empty else if (GameRoles.contains(or.getName) && or.getName == cr.getName) - Mono.empty + SMono.empty else { - val removed = GameRoles.remove(or.getName) //Regardless of whether it was a game role - GameRoles.add(cr.getName) //Add it because it has no color + val removed = removeFromList(or.getName) //Regardless of whether it was a game role + GameRoles.addOne(cr.getName) //Add it because it has no color if (logChannel != null) if (removed) - logChannel.flatMap((ch: MessageChannel) => ch.createMessage("Changed game role from " + or.getName + " to " + cr.getName + ".")) + logChannel.flatMap((ch: MessageChannel) => ch.createMessage("Changed game role from " + or.getName + " to " + cr.getName + ".").^^()) else - logChannel.flatMap((ch: MessageChannel) => ch.createMessage("Added " + cr.getName + " as game role because it has the color of one.")) + logChannel.flatMap((ch: MessageChannel) => ch.createMessage("Added " + cr.getName + " as game role because it has the color of one.").^^()) else - Mono.empty + SMono.empty } }).subscribe() case _ => @@ -82,12 +93,12 @@ import scala.jdk.CollectionConverters.SeqHasAsJava } @ComponentMetadata(enabledByDefault = false) class GameRoleModule extends Component[DiscordPlugin] { - var GameRoles: java.util.List[String] = null + var GameRoles: mutable.Buffer[String] = null final private val command = new RoleCommand(this) override protected def enable(): Unit = { getPlugin.manager.registerCommand(command) - GameRoles = DiscordPlugin.mainServer.getRoles.filterWhen(this.isGameRole).map(_.getName).collectList().block() + GameRoles = DiscordPlugin.mainServer.getRoles.^^().filterWhen(this.isGameRole).map(_.getName).collectSeq().block().toBuffer } override protected def disable(): Unit = getPlugin.manager.unregisterCommand(command) @@ -101,15 +112,15 @@ import scala.jdk.CollectionConverters.SeqHasAsJava * Defaults to the second to last in the upper row - #95a5a6. */ final private def roleColor = getConfig.getData("roleColor", Color.of(149, 165, 166), - rgb => Color.of(Integer.parseInt(rgb.asInstanceOf[String].substring(1), 16)), - color => String.format("#%08x", color.getRGB), true) + (rgb: Any) => Color.of(Integer.parseInt(rgb.asInstanceOf[String].substring(1), 16)), + (color: Color) => String.format("#%08x", color.getRGB), true) - private def isGameRole(r: Role): Mono[java.lang.Boolean] = { - if (r.getGuildId.asLong != DiscordPlugin.mainServer.getId.asLong) return Mono.just(false) //Only allow on the main server + private def isGameRole(r: Role): SMono[Boolean] = { + if (r.getGuildId.asLong != DiscordPlugin.mainServer.getId.asLong) return SMono.just(false) //Only allow on the main server val rc = roleColor.get if (r.getColor equals rc) - DiscordPlugin.dc.getSelf.flatMap(u => u.asMember(DiscordPlugin.mainServer.getId)) - .flatMap(_.hasHigherRoles(Collections.singleton(r.getId))).defaultIfEmpty(false) //Below one of our roles - else Mono.just(false) + DiscordPlugin.dc.getSelf.^^().flatMap(u => u.asMember(DiscordPlugin.mainServer.getId).^^()) + .flatMap(_.hasHigherRoles(Collections.singleton(r.getId)).^^()).cast[Boolean].defaultIfEmpty(false) //Below one of our roles + else SMono.just(false) } } \ No newline at end of file diff --git a/src/main/scala/buttondevteam/discordplugin/role/RoleCommand.scala b/src/main/scala/buttondevteam/discordplugin/role/RoleCommand.scala index 4295250..0b0a661 100644 --- a/src/main/scala/buttondevteam/discordplugin/role/RoleCommand.scala +++ b/src/main/scala/buttondevteam/discordplugin/role/RoleCommand.scala @@ -41,7 +41,7 @@ import reactor.core.publisher.Mono @Command2.Subcommand def list(sender: Command2DCSender): Unit = { val sb = new StringBuilder var b = false - for (role <- grm.GameRoles.stream.sorted.iterator.asInstanceOf[Iterable[String]]) { + for (role <- grm.GameRoles.sorted.iterator.asInstanceOf[Iterable[String]]) { sb.append(role) if (!b) for (_ <- 0 until Math.max(1, 20 - role.length)) { sb.append(" ") @@ -56,8 +56,8 @@ import reactor.core.publisher.Mono private def checkAndGetRole(sender: Command2DCSender, rolename: String): Role = { var rname = rolename if (!grm.GameRoles.contains(rolename)) { //If not found as-is, correct case - val orn = grm.GameRoles.stream.filter(r => r.equalsIgnoreCase(rolename)).findAny - if (!orn.isPresent) { + val orn = grm.GameRoles.find(r => r.equalsIgnoreCase(rolename)) + if (orn.isEmpty) { sender.sendMessage("that role cannot be found.") list(sender) return null @@ -72,7 +72,7 @@ import reactor.core.publisher.Mono } if (roles.size == 0) { sender.sendMessage("the specified role cannot be found on Discord! Removing from the list.") - grm.GameRoles.remove(rolename) + grm.GameRoles.subtractOne(rolename) return null } if (roles.size > 1) {