diff --git a/src/main/java/buttondevteam/discordplugin/DiscordSender.scala b/src/main/java/buttondevteam/discordplugin/DiscordSender.scala
index dadb809..4dca813 100644
--- a/src/main/java/buttondevteam/discordplugin/DiscordSender.scala
+++ b/src/main/java/buttondevteam/discordplugin/DiscordSender.scala
@@ -13,7 +13,7 @@ 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 name: String = Option(pname)
- .orElse(Option(user).map(u => SMono(u.asMember(DiscordPlugin.mainServer.getId))
+ .orElse(Option(user).flatMap(u => SMono(u.asMember(DiscordPlugin.mainServer.getId))
.onErrorResume(_ => SMono.empty).blockOption()
.map(u => u.getDisplayName)))
.getOrElse("Discord user")
diff --git a/src/main/java/buttondevteam/discordplugin/DiscordSenderBase.scala b/src/main/java/buttondevteam/discordplugin/DiscordSenderBase.scala
index 83121aa..63592fa 100644
--- a/src/main/java/buttondevteam/discordplugin/DiscordSenderBase.scala
+++ b/src/main/java/buttondevteam/discordplugin/DiscordSenderBase.scala
@@ -44,21 +44,23 @@ abstract class DiscordSenderBase protected(var user: User, var channel: MessageC
return
}
val sendmsg = DPUtils.sanitizeString(message)
- this synchronized msgtosend += "\n" + sendmsg
- if (sendtask == null) sendtask = Bukkit.getScheduler.runTaskLaterAsynchronously(DiscordPlugin.plugin, () => {
- def foo(): Unit = {
- channel.createMessage((if (user != null) user.getMention + "\n"
- else "") + msgtosend.trim).subscribe
- sendtask = null
- msgtosend = ""
- }
+ this synchronized {
+ msgtosend += "\n" + sendmsg
+ if (sendtask == null) sendtask = Bukkit.getScheduler.runTaskLaterAsynchronously(DiscordPlugin.plugin, () => {
+ def foo(): Unit = {
+ channel.createMessage((if (user != null) user.getMention + "\n"
+ else "") + msgtosend.trim).subscribe
+ sendtask = null
+ msgtosend = ""
+ }
- foo()
- }, 4) // Waits a 0.2 second to gather all/most of the different messages
+ foo()
+ }, 4) // Waits a 0.2 second to gather all/most of the different messages
+ }
} catch {
case e: Exception =>
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: Array[String]): Unit = sendMessage(String.join("\n", messages: _*))
}
\ No newline at end of file
diff --git a/src/main/java/buttondevteam/discordplugin/announcer/AnnouncerModule.scala b/src/main/java/buttondevteam/discordplugin/announcer/AnnouncerModule.scala
index e54764b..31cb524 100644
--- a/src/main/java/buttondevteam/discordplugin/announcer/AnnouncerModule.scala
+++ b/src/main/java/buttondevteam/discordplugin/announcer/AnnouncerModule.scala
@@ -5,9 +5,10 @@ import buttondevteam.lib.TBMCCoreAPI
import buttondevteam.lib.architecture.{Component, ComponentMetadata}
import buttondevteam.lib.player.ChromaGamerBase
import com.google.gson.JsonParser
-import discord4j.core.`object`.entity.Message
import discord4j.core.`object`.entity.channel.MessageChannel
-import reactor.core.publisher.Flux
+import reactor.core.scala.publisher.SMono
+
+import scala.annotation.tailrec
/**
* Posts new posts from Reddit to the specified channel(s). It will pin the regular posts (not the mod posts).
@@ -39,23 +40,19 @@ import reactor.core.publisher.Flux
override protected def enable(): Unit = {
if (DPUtils.disableIfConfigError(this, channel, modChannel)) return
AnnouncerModule.stop = false //If not the first time
- val kp = keepPinned.get
- if (kp eq 0) return
- val msgs: Flux[Message] = channel.get.flatMapMany(_.getPinnedMessages).takeLast(kp)
+ val kp: Short = keepPinned.get
+ if (kp <= 0) return
+ val msgs = channel.get.flatMapMany(_.getPinnedMessages).takeLast(kp)
msgs.subscribe(_.unpin)
new Thread(() => this.AnnouncementGetterThreadMethod()).start()
}
override protected def disable(): Unit = AnnouncerModule.stop = true
- private def AnnouncementGetterThreadMethod(): Unit = while ( {
- !AnnouncerModule.stop
- }) {
- try {
- if (!isEnabled) { //noinspection BusyWait
- Thread.sleep(10000)
- continue //todo: continue is not supported
- }
+ @tailrec
+ private def AnnouncementGetterThreadMethod() {
+ if (AnnouncerModule.stop) return
+ if (isEnabled) try { //If not enabled, just wait
val body = TBMCCoreAPI.DownloadString(subredditURL.get + "/new/.json?limit=10")
val json = new JsonParser().parse(body).getAsJsonObject.get("data").getAsJsonObject.get("children").getAsJsonArray
val msgsb = new StringBuilder
@@ -66,30 +63,32 @@ import reactor.core.publisher.Flux
val data = item.get("data").getAsJsonObject
var author = data.get("author").getAsString
val distinguishedjson = data.get("distinguished")
- var distinguished = null
- if (distinguishedjson.isJsonNull) distinguished = null
- else distinguished = distinguishedjson.getAsString
+ val distinguished = if (distinguishedjson.isJsonNull) null else distinguishedjson.getAsString
val permalink = "https://www.reddit.com" + data.get("permalink").getAsString
val date = data.get("created_utc").getAsLong
if (date > lastSeenTime.get) lastSeenTime.set(date)
else if (date > lastAnnouncementTime.get) { //noinspection ConstantConditions
- do {
+ {
val reddituserclass = ChromaGamerBase.getTypeForFolder("reddit")
- if (reddituserclass == null) break //todo: break is not supported
- val user = ChromaGamerBase.getUser(author, reddituserclass)
- val id = user.getConnectedID(classOf[DiscordPlayer])
- if (id != null) author = "<@" + id + ">"
- } while ( {
- false
- })
+ if (reddituserclass != null) {
+ val user = ChromaGamerBase.getUser(author, reddituserclass)
+ val id = user.getConnectedID(classOf[DiscordPlayer])
+ if (id != null) author = "<@" + id + ">"
+ }
+ }
if (!author.startsWith("<")) author = "/u/" + author
- (if (distinguished != null && distinguished == "moderator") modmsgsb
- else msgsb).append("A new post was submitted to the subreddit by ").append(author).append("\n").append(permalink).append("\n")
+ (if (distinguished != null && distinguished == "moderator") modmsgsb else msgsb)
+ .append("A new post was submitted to the subreddit by ").append(author).append("\n")
+ .append(permalink).append("\n")
lastanntime = date
}
}
- if (msgsb.length > 0) channel.get.flatMap((ch: MessageChannel) => ch.createMessage(msgsb.toString)).flatMap(Message.pin).subscribe
- if (modmsgsb.length > 0) modChannel.get.flatMap((ch: MessageChannel) => ch.createMessage(modmsgsb.toString)).flatMap(Message.pin).subscribe
+
+ def sendMsg(ch: SMono[MessageChannel], msg: String) =
+ ch.asJava().flatMap(c => c.createMessage(msg)).flatMap(_.pin).subscribe
+
+ if (msgsb.nonEmpty) sendMsg(channel.get(), msgsb.toString())
+ if (modmsgsb.nonEmpty) sendMsg(modChannel.get(), modmsgsb.toString())
if (lastAnnouncementTime.get ne lastanntime) lastAnnouncementTime.set(lastanntime) // If sending succeeded
} catch {
case e: Exception =>
@@ -100,5 +99,6 @@ import reactor.core.publisher.Flux
case ex: InterruptedException =>
Thread.currentThread.interrupt()
}
+ AnnouncementGetterThreadMethod()
}
}
\ No newline at end of file
diff --git a/src/main/java/buttondevteam/discordplugin/commands/Command2DCSender.scala b/src/main/java/buttondevteam/discordplugin/commands/Command2DCSender.scala
index f898fe8..6b7a4f9 100644
--- a/src/main/java/buttondevteam/discordplugin/commands/Command2DCSender.scala
+++ b/src/main/java/buttondevteam/discordplugin/commands/Command2DCSender.scala
@@ -16,7 +16,7 @@ import lombok.RequiredArgsConstructor
this.message.getChannel.flatMap((ch: MessageChannel) => ch.createMessage(this.message.getAuthor.map((u: User) => DPUtils.nickMention(u.getId) + ", ").orElse("") + msg)).subscribe
}
- override def sendMessage(message: Array[String]): Unit = sendMessage(String.join("\n", message))
+ override def sendMessage(message: Array[String]): Unit = sendMessage(String.join("\n", message: _*))
- override def getName = message.getAuthor.map(_.getUsername).orElse("Discord")
+ override def getName: String = Option(message.getAuthor.orElse(null)).map(_.getUsername).getOrElse("Discord")
}
\ No newline at end of file
diff --git a/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.scala b/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.scala
index db1d9a9..09a51ad 100644
--- a/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.scala
+++ b/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.scala
@@ -7,8 +7,9 @@ import com.google.common.collect.HashBiMap
import org.bukkit.Bukkit
import org.bukkit.entity.Player
-@CommandClass(helpText = Array(Array("Connect command", //
- "This command lets you connect your account with a Minecraft account. This allows using the private Minecraft chat and other things."))) object ConnectCommand {
+@CommandClass(helpText = Array("Connect command", //
+ "This command lets you connect your account with a Minecraft account." +
+ " This allows using the private Minecraft chat and other things.")) object ConnectCommand {
/**
* Key: Minecraft name
* Value: Discord ID
diff --git a/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.scala b/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.scala
index 67fee6e..79f3d9c 100644
--- a/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.scala
+++ b/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.scala
@@ -3,24 +3,27 @@ package buttondevteam.discordplugin.commands
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 reactor.core.scala.publisher.SMono
-@CommandClass(helpText = Array(Array("Switches debug mode.")))
+@CommandClass(helpText = Array("Switches debug mode."))
class DebugCommand extends ICommand2DC {
@Command2.Subcommand
override def `def`(sender: Command2DCSender): Boolean = {
- sender.getMessage.getAuthorAsMember.switchIfEmpty(sender.getMessage.getAuthor.map //Support DMs
- ((u: User) => u.asMember(DiscordPlugin.mainServer.getId)).orElse(Mono.empty)).flatMap((m: Member) => DiscordPlugin.plugin.modRole.get.map((mr) => m.getRoleIds.stream.anyMatch((r: Snowflake) => r == mr.getId)).switchIfEmpty(Mono.fromSupplier(() => DiscordPlugin.mainServer.getOwnerId.asLong eq m.getId.asLong)))
- .onErrorReturn(false) //Role not found
- .subscribe((success: Any) => {
- def foo(success: Any) = {
- if (success) sender.sendMessage("debug " + (if (CommonListeners.debug) "enabled"
- else "disabled"))
- else sender.sendMessage("you need to be a moderator to use this command.")
- }
-
- foo(success)
+ SMono(sender.getMessage.getAuthorAsMember)
+ .switchIfEmpty(Option(sender.getMessage.getAuthor.orElse(null)) //Support DMs
+ .map((u: User) => SMono(u.asMember(DiscordPlugin.mainServer.getId))).getOrElse(SMono.empty))
+ .flatMap((m: Member) => DiscordPlugin.plugin.modRole.get
+ .map(mr => m.getRoleIds.stream.anyMatch((r: Snowflake) => r == mr.getId))
+ .switchIfEmpty(SMono.fromCallable(() => DiscordPlugin.mainServer.getOwnerId.asLong eq m.getId.asLong)))
+ .onErrorResume(_ => SMono.just(false)) //Role not found
+ .subscribe(success => {
+ if (success) {
+ CommonListeners.debug = !CommonListeners.debug;
+ sender.sendMessage("debug " + (if (CommonListeners.debug) "enabled" else "disabled"))
+ } else
+ sender.sendMessage("you need to be a moderator to use this command.")
})
true
}
diff --git a/src/main/java/buttondevteam/discordplugin/commands/HelpCommand.scala b/src/main/java/buttondevteam/discordplugin/commands/HelpCommand.scala
index c3d1029..77d51df 100644
--- a/src/main/java/buttondevteam/discordplugin/commands/HelpCommand.scala
+++ b/src/main/java/buttondevteam/discordplugin/commands/HelpCommand.scala
@@ -2,8 +2,8 @@ package buttondevteam.discordplugin.commands
import buttondevteam.lib.chat.{Command2, CommandClass}
-@CommandClass(helpText = Array(Array("Help command", //
- "Shows some info about a command or lists the available commands.")))
+@CommandClass(helpText = Array("Help command", //
+ "Shows some info about a command or lists the available commands."))
class HelpCommand extends ICommand2DC {
@Command2.Subcommand
def `def`(sender: Command2DCSender, @Command2.TextArg @Command2.OptionalArg args: String): Boolean = {
diff --git a/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.scala b/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.scala
index c9e7203..7768b44 100644
--- a/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.scala
+++ b/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.scala
@@ -4,13 +4,12 @@ import buttondevteam.discordplugin.{DiscordPlayer, DiscordPlugin}
import buttondevteam.lib.chat.{Command2, CommandClass}
import buttondevteam.lib.player.ChromaGamerBase
import buttondevteam.lib.player.ChromaGamerBase.InfoTarget
-import discord4j.core.`object`.entity.{Member, Message, User}
+import discord4j.core.`object`.entity.{Message, User}
+import reactor.core.scala.publisher.SFlux
-import java.util
-
-@CommandClass(helpText = Array(Array("User information", //
+@CommandClass(helpText = Array("User information", //
"Shows some information about users, from Discord, from Minecraft or from Reddit if they have these accounts connected.",
- "If used without args, shows your info.")))
+ "If used without args, shows your info."))
class UserinfoCommand extends ICommand2DC {
@Command2.Subcommand
def `def`(sender: Command2DCSender, @Command2.OptionalArg @Command2.TextArg user: String): Boolean = {
@@ -25,16 +24,11 @@ class UserinfoCommand extends ICommand2DC {
else if (user.contains("#")) {
val targettag = user.split("#")
val targets = getUsers(message, targettag(0))
- if (targets.size == 0) {
+ if (targets.isEmpty) {
channel.createMessage("The user cannot be found (by name): " + user).subscribe
return true
}
- for (ptarget <- targets) {
- if (ptarget.getDiscriminator.equalsIgnoreCase(targettag(1))) {
- target = ptarget
- break //todo: break is not supported
- }
- }
+ targets.collectFirst(_.getDiscriminator.equalsIgnoreCase(targettag(1)))
if (target == null) {
channel.createMessage("The user cannot be found (by discriminator): " + user + "(Found " + targets.size + " users with the name.)").subscribe
return true
@@ -42,7 +36,7 @@ class UserinfoCommand extends ICommand2DC {
}
else {
val targets = getUsers(message, user)
- if (targets.size == 0) {
+ if (targets.isEmpty) {
channel.createMessage("The user cannot be found on Discord: " + user).subscribe
return true
}
@@ -50,7 +44,7 @@ class UserinfoCommand extends ICommand2DC {
channel.createMessage("Multiple users found with that (nick)name. Please specify the whole tag, like ChromaBot#6338 or use a ping.").subscribe
return true
}
- target = targets.get(0)
+ target = targets.head
}
}
if (target == null) {
@@ -65,12 +59,11 @@ class UserinfoCommand extends ICommand2DC {
}
private def getUsers(message: Message, args: String) = {
- var targets: util.List[User]
val guild = message.getGuild.block
if (guild == null) { //Private channel
- targets = DiscordPlugin.dc.getUsers.filter((u) => u.getUsername.equalsIgnoreCase(args)).collectList.block
+ SFlux(DiscordPlugin.dc.getUsers).filter(u => u.getUsername.equalsIgnoreCase(args)).collectSeq().block()
}
- else targets = guild.getMembers.filter((m: Member) => m.getUsername.equalsIgnoreCase(args)).map((m: Member) => m.asInstanceOf[User]).collectList.block
- targets
+ else
+ SFlux(guild.getMembers).filter(_.getUsername.equalsIgnoreCase(args)).map(_.asInstanceOf[User]).collectSeq().block()
}
}
\ No newline at end of file
diff --git a/src/main/java/buttondevteam/discordplugin/commands/VersionCommand.scala b/src/main/java/buttondevteam/discordplugin/commands/VersionCommand.scala
index 137f869..9f8544c 100644
--- a/src/main/java/buttondevteam/discordplugin/commands/VersionCommand.scala
+++ b/src/main/java/buttondevteam/discordplugin/commands/VersionCommand.scala
@@ -3,7 +3,7 @@ package buttondevteam.discordplugin.commands
import buttondevteam.discordplugin.DiscordPlugin
import buttondevteam.lib.chat.{Command2, CommandClass}
-@CommandClass(helpText = Array(Array("Version", "Returns the plugin's version")))
+@CommandClass(helpText = Array("Version", "Returns the plugin's version"))
object VersionCommand {
def getVersion: Array[String] = {
val desc = DiscordPlugin.plugin.getDescription
@@ -11,7 +11,7 @@ object VersionCommand {
}
}
-@CommandClass(helpText = Array(Array("Version", "Returns the plugin's version")))
+@CommandClass(helpText = Array("Version", "Returns the plugin's version"))
class VersionCommand extends ICommand2DC {
@Command2.Subcommand override def `def`(sender: Command2DCSender): Boolean = {
sender.sendMessage(VersionCommand.getVersion)
diff --git a/src/main/java/buttondevteam/discordplugin/exceptions/ExceptionListenerModule.scala b/src/main/java/buttondevteam/discordplugin/exceptions/ExceptionListenerModule.scala
index 14b9ba5..fdf04ca 100644
--- a/src/main/java/buttondevteam/discordplugin/exceptions/ExceptionListenerModule.scala
+++ b/src/main/java/buttondevteam/discordplugin/exceptions/ExceptionListenerModule.scala
@@ -9,7 +9,7 @@ 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
@@ -20,29 +20,24 @@ import java.util.stream.Collectors
object ExceptionListenerModule {
private def SendException(e: Throwable, sourcemessage: String): Unit = {
if (instance == null) return
- try getChannel.flatMap((channel: MessageChannel) => {
- def foo(channel: MessageChannel) = {
- var coderRole: Mono[Role] = channel match {
- case ch: GuildChannel => instance.pingRole(ch.getGuild).get
- case _ => Mono.empty
- }
- coderRole.map((role: Role) => if (TBMCCoreAPI.IsTestServer) new StringBuilder
- else new StringBuilder(role.getMention).append("\n")).defaultIfEmpty(new StringBuilder).flatMap((sb: StringBuilder) => {
- def foo(sb: StringBuilder) = {
- sb.append(sourcemessage).append("\n")
- sb.append("```").append("\n")
- var stackTrace = util.Arrays.stream(ExceptionUtils.getStackTrace(e).split("\\n")).filter((s: String) => !s.contains("\tat ") || s.contains("\tat buttondevteam.")).collect(Collectors.joining("\n"))
- if (sb.length + stackTrace.length >= 1980) stackTrace = stackTrace.substring(0, 1980 - sb.length)
- sb.append(stackTrace).append("\n")
- sb.append("```")
- channel.createMessage(sb.toString)
- }
-
- foo(sb)
- })
+ try getChannel.flatMap(channel => {
+ val coderRole = channel match {
+ case ch: GuildChannel => instance.pingRole(SMono(ch.getGuild)).get
+ case _ => SMono.empty
}
-
- foo(channel)
+ coderRole.map((role: Role) => if (TBMCCoreAPI.IsTestServer) new StringBuilder
+ else new StringBuilder(role.getMention).append("\n"))
+ .defaultIfEmpty(new StringBuilder).flatMap(sb => {
+ sb.append(sourcemessage).append("\n")
+ sb.append("```").append("\n")
+ var stackTrace = util.Arrays.stream(ExceptionUtils.getStackTrace(e).split("\\n"))
+ .filter(s => !s.contains("\tat ") || s.contains("\tat buttondevteam."))
+ .collect(Collectors.joining("\n"))
+ if (sb.length + stackTrace.length >= 1980) stackTrace = stackTrace.substring(0, 1980 - sb.length)
+ sb.append(stackTrace).append("\n")
+ sb.append("```")
+ SMono(channel.createMessage(sb.toString))
+ })
}).subscribe
catch {
case ex: Exception =>
@@ -52,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
}
}
@@ -64,13 +59,12 @@ class ExceptionListenerModule extends Component[DiscordPlugin] with Listener {
@EventHandler def onException(e: TBMCExceptionEvent): Unit = {
if (DiscordPlugin.SafeMode || !ComponentManager.isEnabled(getClass)) return
- if (lastthrown.stream.anyMatch((ex: Throwable) => util.Arrays.equals(e.getException.getStackTrace, ex.getStackTrace) && (if (e.getException.getMessage == null) ex.getMessage == null
- else e.getException.getMessage == ex.getMessage)) // e.Exception.Message==ex.Message
+ if (lastthrown.stream.anyMatch(ex => e.getException.getStackTrace.sameElements(ex.getStackTrace)
+ && (if (e.getException.getMessage == null) ex.getMessage == null else e.getException.getMessage == ex.getMessage))
&& lastsourcemsg.contains(e.getSourceMessage)) {
return
}
- ExceptionListenerModule
- .SendException(e.getException, e.getSourceMessage)
+ ExceptionListenerModule.SendException(e.getException, e.getSourceMessage)
if (lastthrown.size >= 10) lastthrown.remove(0)
if (lastsourcemsg.size >= 10) lastsourcemsg.remove(0)
lastthrown.add(e.getException)
@@ -86,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/java/buttondevteam/discordplugin/fun/FunModule.scala b/src/main/java/buttondevteam/discordplugin/fun/FunModule.scala
index 4b71d87..f919932 100644
--- a/src/main/java/buttondevteam/discordplugin/fun/FunModule.scala
+++ b/src/main/java/buttondevteam/discordplugin/fun/FunModule.scala
@@ -5,16 +5,15 @@ import buttondevteam.discordplugin.{DPUtils, DiscordPlugin}
import buttondevteam.lib.TBMCCoreAPI
import buttondevteam.lib.architecture.{Component, ConfigData}
import com.google.common.collect.Lists
-import discord4j.common.util.Snowflake
import discord4j.core.`object`.entity.channel.{GuildChannel, MessageChannel}
-import discord4j.core.`object`.entity.{Guild, Member, Message, Role}
-import discord4j.core.`object`.presence.{Presence, Status}
+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 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.{SFlux, SMono}
import java.util
import java.util.Calendar
@@ -50,41 +49,47 @@ object FunModule {
lastlist = 0
}
if (msglowercased == "/list" && Bukkit.getOnlinePlayers.size == lastlistp && {
- ListC += 1;
+ 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
}
lastlistp = Bukkit.getOnlinePlayers.size.toShort //Didn't handle
- if (!TBMCCoreAPI.IsTestServer && util.Arrays.stream(fm.serverReady).get.anyMatch(msglowercased.contains _)) {
+ if (!TBMCCoreAPI.IsTestServer && fm.serverReady.get.exists(msglowercased.contains)) {
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
+ false
}
- private var lasttime = 0
+ private var lasttime: Long = 0
def handleFullHouse(event: PresenceUpdateEvent): Unit = {
val fm = ComponentManager.getIfEnabled(classOf[FunModule])
if (fm == null) return
if (Calendar.getInstance.get(Calendar.DAY_OF_MONTH) % 5 != 0) return
+ if (!Option(event.getOld.orElse(null)).exists(_.getStatus == Status.OFFLINE)
+ || 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: MessageChannel) => fm.fullHouseDevRole(channel.asInstanceOf[GuildChannel].getGuild).get.filter((role: Role) => event.getOld.map((p: Presence) => p.getStatus == Status.OFFLINE).orElse(false)).filter((role: Role) => !(event.getCurrent.getStatus == Status.OFFLINE)).filterWhen((devrole: Role) => event.getMember.flatMap((m: Member) => m.getRoles.any((r: Role) => r.getId.asLong == devrole.getId.asLong))).filterWhen((devrole: Role) => event.getGuild.flatMapMany((g: Guild) => g.getMembers.filter((m: Member) => m.getRoleIds.stream.anyMatch((s: Snowflake) => s == devrole.getId))).flatMap(Member.getPresence).all((pr: Presence) => !(pr.getStatus == Status.OFFLINE))).filter((devrole: Role) => lasttime + 10 < TimeUnit.NANOSECONDS.toHours(System.nanoTime)).flatMap //This should stay so it checks this last
- ((devrole: Role) => {
- def foo(devrole: Role) = {
+ .flatMap(channel => fm.fullHouseDevRole(SMono(channel.asInstanceOf[GuildChannel].getGuild)).get
+ .filterWhen(devrole => SMono(event.getMember)
+ .flatMap(m => SFlux(m.getRoles).any(_.getId.asLong == devrole.getId.asLong)))
+ .filterWhen(devrole => SMono(event.getGuild)
+ .flatMapMany(g => SFlux(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((mcs: MessageCreateSpec) => mcs.setContent("Full house!").setEmbed((ecs: EmbedCreateSpec) => ecs.setImage("https://cdn.discordapp.com/attachments/249295547263877121/249687682618359808/poker-hand-full-house-aces-kings-playing-cards-15553791.png")))
- }
-
- foo(devrole)
- })).subscribe
+ SMono(channel.createMessage((mcs: MessageCreateSpec) => mcs.setContent("Full house!")
+ .setEmbed((ecs: EmbedCreateSpec) => ecs.setImage("https://cdn.discordapp.com/attachments/249295547263877121/249687682618359808/poker-hand-full-house-aces-kings-playing-cards-15553791.png"))))
+ })).subscribe
}
}
@@ -109,14 +114,18 @@ class FunModule extends Component[DiscordPlugin] with Listener {
override protected def enable(): Unit = registerListener(this)
- override protected def disable(): Unit = FunModule.lastlist = FunModule.lastlistp = FunModule.ListC = 0
+ override protected def disable(): Unit = {
+ FunModule.lastlist = 0
+ FunModule.lastlistp = 0
+ FunModule.ListC = 0
+ }
@EventHandler def onPlayerJoin(event: PlayerJoinEvent): Unit = FunModule.ListC = 0
/**
* 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/java/buttondevteam/discordplugin/listeners/CommonListeners.scala b/src/main/java/buttondevteam/discordplugin/listeners/CommonListeners.scala
index 57f6d8b..5c776ca 100644
--- a/src/main/java/buttondevteam/discordplugin/listeners/CommonListeners.scala
+++ b/src/main/java/buttondevteam/discordplugin/listeners/CommonListeners.scala
@@ -12,7 +12,7 @@ import discord4j.core.event.EventDispatcher
import discord4j.core.event.domain.PresenceUpdateEvent
import discord4j.core.event.domain.message.MessageCreateEvent
import discord4j.core.event.domain.role.{RoleCreateEvent, RoleDeleteEvent, RoleUpdateEvent}
-import reactor.core.scala.publisher.SMono
+import reactor.core.scala.publisher.{SFlux, SMono}
object CommonListeners {
val timings = new Timings
@@ -56,25 +56,19 @@ object CommonListeners {
}
foo(event)
- }).onErrorContinue((err: Throwable, obj: Any) => TBMCCoreAPI.SendException("An error occured while handling a message!", err, DiscordPlugin.plugin)).subscribe
+ }).onErrorContinue((err: Throwable, _) => TBMCCoreAPI.SendException("An error occured while handling a message!", err, DiscordPlugin.plugin)).subscribe
dispatcher.on(classOf[PresenceUpdateEvent]).subscribe((event: PresenceUpdateEvent) => {
- def foo(event: PresenceUpdateEvent) = {
- if (DiscordPlugin.SafeMode) return
+ if (!DiscordPlugin.SafeMode)
FunModule.handleFullHouse(event)
- }
-
- foo(event)
})
- dispatcher.on(classOf[RoleCreateEvent]).subscribe(GameRoleModule.handleRoleEvent _)
- dispatcher.on(classOf[RoleDeleteEvent]).subscribe(GameRoleModule.handleRoleEvent _)
- dispatcher.on(classOf[RoleUpdateEvent]).subscribe(GameRoleModule.handleRoleEvent _)
+ SFlux(dispatcher.on(classOf[RoleCreateEvent])).subscribe(GameRoleModule.handleRoleEvent _)
+ SFlux(dispatcher.on(classOf[RoleDeleteEvent])).subscribe(GameRoleModule.handleRoleEvent _)
+ SFlux(dispatcher.on(classOf[RoleUpdateEvent])).subscribe(GameRoleModule.handleRoleEvent _)
}
- private var debug = false
+ var debug = false
def debug(debug: String): Unit = if (CommonListeners.debug) { //Debug
DPUtils.getLogger.info(debug)
}
-
- def debug(): Unit = debug = !debug
}
\ No newline at end of file
diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/ChannelconCommand.scala b/src/main/java/buttondevteam/discordplugin/mcchat/ChannelconCommand.scala
index 94ad744..e69fb53 100644
--- a/src/main/java/buttondevteam/discordplugin/mcchat/ChannelconCommand.scala
+++ b/src/main/java/buttondevteam/discordplugin/mcchat/ChannelconCommand.scala
@@ -21,7 +21,7 @@ import java.util.{Objects, Optional}
import javax.annotation.Nullable
@SuppressWarnings(Array("SimplifyOptionalCallChains")) //Java 11
-@CommandClass(helpText = Array(Array("Channel connect", //
+@CommandClass(helpText = Array("Channel connect", //
"This command allows you to connect a Minecraft channel to a Discord channel (just like how the global chat is connected to #minecraft-chat).",
"You need to have access to the MC channel and have manage permissions on the Discord channel.",
"You also need to have your Minecraft account connected. In #bot use /connect .",
@@ -30,7 +30,7 @@ import javax.annotation.Nullable
"To remove a connection use @ChromaBot channelcon remove in the channel.",
"Mentioning the bot is needed in this case because the / prefix only works in #bot.",
"Invite link: " //
-)))
+))
class ChannelconCommand(private val module: MinecraftChatModule) extends ICommand2DC {
@Command2.Subcommand def remove(sender: Command2DCSender): Boolean = {
val message = sender.getMessage
diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.scala b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.scala
index 7b76572..78e7085 100644
--- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.scala
+++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.scala
@@ -1,17 +1,17 @@
package buttondevteam.discordplugin.mcchat
-import buttondevteam.discordplugin.{DPUtils, DiscordPlayer, DiscordPlugin}
import buttondevteam.discordplugin.commands.{Command2DCSender, ICommand2DC}
+import buttondevteam.discordplugin.{DPUtils, DiscordPlayer, DiscordPlugin}
import buttondevteam.lib.chat.{Command2, CommandClass}
import buttondevteam.lib.player.ChromaGamerBase
import discord4j.core.`object`.entity.channel.PrivateChannel
-@CommandClass(helpText = Array(Array(
+@CommandClass(helpText = Array(
"MC Chat",
"This command enables or disables the Minecraft chat in private messages.", //
"It can be useful if you don't want your messages to be visible, for example when talking in a private channel.",
"You can also run all of the ingame commands you have access to using this command, if you have your accounts connected." //
-)))
+))
class MCChatCommand(private val module: MinecraftChatModule) extends ICommand2DC {
@Command2.Subcommand override def `def`(sender: Command2DCSender): Boolean = {
if (!(module.allowPrivateChat.get)) {
diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCustom.scala b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCustom.scala
index 25eb781..163b6ec 100644
--- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCustom.scala
+++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCustom.scala
@@ -8,15 +8,14 @@ import discord4j.core.`object`.entity.User
import discord4j.core.`object`.entity.channel.MessageChannel
import lombok.NonNull
-import java.util
-import java.util.Collections
import javax.annotation.Nullable
+import scala.collection.mutable.ListBuffer
object MCChatCustom {
/**
* Used for town or nation chats or anything else
*/
- private[mcchat] val lastmsgCustom = new util.ArrayList[MCChatCustom.CustomLMD]
+ private[mcchat] val lastmsgCustom = new ListBuffer[MCChatCustom.CustomLMD]
def addCustomChat(channel: MessageChannel, groupid: String, mcchannel: Channel, user: User, dcp: DiscordConnectedPlayer, toggles: Int, brtoggles: Set[TBMCSystemChatEvent.BroadcastTarget]): Boolean = {
lastmsgCustom synchronized {
@@ -29,34 +28,32 @@ object MCChatCustom {
gid = groupid
}
val lmd = new MCChatCustom.CustomLMD(channel, user, gid, mcchannel, dcp, toggles, brtoggles)
- lastmsgCustom.add(lmd)
+ lastmsgCustom += lmd
}
true
}
def hasCustomChat(channel: Snowflake): Boolean =
- lastmsgCustom.stream.anyMatch((lmd: MCChatCustom.CustomLMD) => lmd.channel.getId.asLong == channel.asLong)
+ lastmsgCustom.exists(_.channel.getId.asLong == channel.asLong)
@Nullable def getCustomChat(channel: Snowflake): CustomLMD =
- lastmsgCustom.stream.filter((lmd: MCChatCustom.CustomLMD) => lmd.channel.getId.asLong == channel.asLong).findAny.orElse(null)
+ lastmsgCustom.find(_.channel.getId.asLong == channel.asLong).orNull
- def removeCustomChat(channel: Snowflake): Boolean = {
- lastmsgCustom synchronized MCChatUtils.lastmsgfromd.remove(channel.asLong)
- lastmsgCustom.removeIf((lmd: MCChatCustom.CustomLMD) => {
- def foo(lmd: MCChatCustom.CustomLMD): Boolean = {
- if (lmd.channel.getId.asLong != channel.asLong) return false
+ def removeCustomChat(channel: Snowflake): Unit = {
+ lastmsgCustom synchronized {
+ MCChatUtils.lastmsgfromd.remove(channel.asLong)
+ lastmsgCustom.filterInPlace(lmd => {
+ if (lmd.channel.getId.asLong != channel.asLong) return true
lmd.mcchannel match {
case room: ChatRoom => room.leaveRoom(lmd.dcp)
case _ =>
}
- true
- }
-
- foo(lmd)
- })
+ false
+ })
+ }
}
- def getCustomChats: util.List[CustomLMD] = Collections.unmodifiableList(lastmsgCustom)
+ def getCustomChats: List[CustomLMD] = lastmsgCustom.toList
class CustomLMD private[mcchat](@NonNull channel: MessageChannel, @NonNull user: User, val groupID: String,
@NonNull mcchannel: Channel, val dcp: DiscordConnectedPlayer, var toggles: Int,
diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatListener.scala b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatListener.scala
index d4c837b..c5bd052 100644
--- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatListener.scala
+++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatListener.scala
@@ -28,6 +28,7 @@ import java.util.Optional
import java.util.concurrent.{LinkedBlockingQueue, TimeoutException}
import java.util.function.{Consumer, Function, Predicate}
import java.util.stream.Collectors
+import scala.jdk.OptionConverters.RichOptional
object MCChatListener {
@@ -111,21 +112,21 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
foo(ecs)
}
val nanoTime: Long = System.nanoTime
- val doit: MCChatListener.InterruptibleConsumer[MCChatUtils.LastMsgData] = (lastmsgdata: MCChatUtils.LastMsgData) => {
- def foo(lastmsgdata: MCChatUtils.LastMsgData): Unit = {
- if (lastmsgdata.message == null || !(authorPlayer == lastmsgdata.message.getEmbeds.get(0).getAuthor.map(_.getName).orElse(null)) || lastmsgdata.time / 1000000000f < nanoTime / 1000000000f - 120 || !(lastmsgdata.mcchannel.ID == e.getChannel.ID) || lastmsgdata.content.length + e.getMessage.length + 1 > 2048) {
- lastmsgdata.message = lastmsgdata.channel.createEmbed(embed).block
- lastmsgdata.time = nanoTime
- lastmsgdata.mcchannel = e.getChannel
- lastmsgdata.content = e.getMessage
- }
- else {
- lastmsgdata.content = lastmsgdata.content + "\n" + e.getMessage // The message object doesn't get updated
- lastmsgdata.message.edit((mes: MessageEditSpec) => mes.setEmbed(embed.andThen((ecs: EmbedCreateSpec) => ecs.setDescription(lastmsgdata.content)))).block
- }
+ val doit = (lastmsgdata: MCChatUtils.LastMsgData) => {
+ if (lastmsgdata.message == null
+ || authorPlayer != lastmsgdata.message.getEmbeds.get(0).getAuthor.toScala.map(_.getName).orNull
+ || lastmsgdata.time / 1000000000f < nanoTime / 1000000000f - 120
+ || !(lastmsgdata.mcchannel.ID == e.getChannel.ID)
+ || lastmsgdata.content.length + e.getMessage.length + 1 > 2048) {
+ lastmsgdata.message = lastmsgdata.channel.createEmbed(embed).block
+ lastmsgdata.time = nanoTime
+ lastmsgdata.mcchannel = e.getChannel
+ lastmsgdata.content = e.getMessage
+ }
+ else {
+ lastmsgdata.content = lastmsgdata.content + "\n" + e.getMessage // The message object doesn't get updated
+ lastmsgdata.message.edit((mes: MessageEditSpec) => mes.setEmbed(embed.andThen((ecs: EmbedCreateSpec) => ecs.setDescription(lastmsgdata.content)))).block
}
-
- foo(lastmsgdata)
}
// Checks if the given channel is different than where the message was sent from
// Or if it was from MC
@@ -133,31 +134,29 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
if (e.getChannel.isGlobal && (e.isFromCommand || isdifferentchannel.test(module.chatChannel.get))) {
if (MCChatUtils.lastmsgdata == null)
MCChatUtils.lastmsgdata = new MCChatUtils.LastMsgData(module.chatChannelMono.block, null)
- doit.accept(MCChatUtils.lastmsgdata)
+ doit(MCChatUtils.lastmsgdata)
}
for (data <- MCChatPrivate.lastmsgPerUser) {
if ((e.isFromCommand || isdifferentchannel.test(data.channel.getId)) && e.shouldSendTo(MCChatUtils.getSender(data.channel.getId, data.user))) {
- doit.accept(data)
+ doit(data)
}
}
- MCChatCustom.lastmsgCustom synchronized
- val iterator = MCChatCustom.lastmsgCustom.iterator
- while ( {
- iterator.hasNext
- }) {
- val lmd = iterator.next
- if ((e.isFromCommand || isdifferentchannel.test(lmd.channel.getId)) //Test if msg is from Discord
- && e.getChannel.ID == lmd.mcchannel.ID //If it's from a command, the command msg has been deleted, so we need to send it
- && e.getGroupID == lmd.groupID) { //Check if this is the group we want to test - #58
- if (e.shouldSendTo(lmd.dcp)) { //Check original user's permissions
- doit.accept(lmd)
+ MCChatCustom.lastmsgCustom synchronized {
+ MCChatCustom.lastmsgCustom.filterInPlace(lmd => {
+ if ((e.isFromCommand || isdifferentchannel.test(lmd.channel.getId)) //Test if msg is from Discord
+ && e.getChannel.ID == lmd.mcchannel.ID //If it's from a command, the command msg has been deleted, so we need to send it
+ && e.getGroupID == lmd.groupID) { //Check if this is the group we want to test - #58
+ if (e.shouldSendTo(lmd.dcp)) { //Check original user's permissions
+ doit(lmd)
+ }
+ else {
+ lmd.channel.createMessage("The user no longer has permission to view the channel, connection removed.").subscribe
+ return false //If the user no longer has permission, remove the connection
+ }
}
- else {
- iterator.remove() //If the user no longer has permission, remove the connection
- lmd.channel.createMessage("The user no longer has permission to view the channel, connection removed.").subscribe
- }
- }
+ true
+ })
}
} catch {
case ex: InterruptedException =>
diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.scala b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.scala
index 1926cab..4f10b2d 100644
--- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.scala
+++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.scala
@@ -19,17 +19,20 @@ import org.bukkit.event.Event
import org.bukkit.event.player.{AsyncPlayerPreLoginEvent, PlayerJoinEvent, PlayerLoginEvent, PlayerQuitEvent}
import org.bukkit.plugin.AuthorNagException
import org.reactivestreams.Publisher
-import reactor.core.publisher.Mono
+import reactor.core.scala.publisher.SMono
import java.net.InetAddress
import java.util
import java.util._
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.atomic.AtomicInteger
-import java.util.function.Supplier
import java.util.logging.Level
-import java.util.stream.{Collectors, Stream}
+import java.util.stream.Collectors
import javax.annotation.Nullable
+import scala.collection.concurrent
+import scala.collection.convert.ImplicitConversions.`map AsJavaMap`
+import scala.collection.mutable.ListBuffer
+import scala.jdk.CollectionConverters.CollectionHasAsScala
import scala.jdk.javaapi.CollectionConverters.asScala
object MCChatUtils {
@@ -43,13 +46,13 @@ object MCChatUtils {
@Nullable private[mcchat] var lastmsgdata: MCChatUtils.LastMsgData = null
private[mcchat] val lastmsgfromd = new LongObjectHashMap[Message] // Last message sent by a Discord user, used for clearing checkmarks
private var module: MinecraftChatModule = null
- private val staticExcludedPlugins = new util.HashMap[Class[_ <: Event], util.HashSet[String]]
+ private val staticExcludedPlugins = Map[Class[_ <: Event], util.HashSet[String]]()
def updatePlayerList(): Unit = {
val mod = getModule
if (mod == null || !mod.showPlayerListOnDC.get) return
if (lastmsgdata != null) updatePL(lastmsgdata)
- MCChatCustom.lastmsgCustom.forEach(MCChatUtils.updatePL)
+ MCChatCustom.lastmsgCustom.foreach(MCChatUtils.updatePL)
}
private def notEnabled = (module == null || !module.disabling) && getModule == null //Allow using things while disabling the module
@@ -85,7 +88,8 @@ object MCChatUtils {
.filter(_ => C.incrementAndGet > 0) //Always true
.map((p) => DPUtils.sanitizeString(p.getDisplayName)).collect(Collectors.joining(", "))
s(0) = C + " player" + (if (C.get != 1) "s" else "") + " online"
- lmd.channel.asInstanceOf[TextChannel].edit((tce: TextChannelEditSpec) => tce.setTopic(String.join("\n----\n", s)).setReason("Player list update")).subscribe //Don't wait
+ lmd.channel.asInstanceOf[TextChannel].edit((tce: TextChannelEditSpec) =>
+ tce.setTopic(String.join("\n----\n", s: _*)).setReason("Player list update")).subscribe //Don't wait
}
private[mcchat] def checkEssentials(p: Player): Boolean = {
@@ -94,12 +98,12 @@ object MCChatUtils {
!ess.getUser(p).isHidden
}
- def addSender[T <: DiscordSenderBase](senders: ConcurrentHashMap[String, ConcurrentHashMap[Snowflake, T]], user: User, sender: T): T =
+ def addSender[T <: DiscordSenderBase](senders: concurrent.Map[String, ConcurrentHashMap[Snowflake, T]], user: User, sender: T): T =
addSender(senders, user.getId.asString, sender)
- def addSender[T <: DiscordSenderBase](senders: ConcurrentHashMap[String, ConcurrentHashMap[Snowflake, T]], did: String, sender: T): T = {
- var map = senders.get(did)
- if (map == null) map = new ConcurrentHashMap[Snowflake, T]
+ def addSender[T <: DiscordSenderBase](senders: concurrent.Map[String, ConcurrentHashMap[Snowflake, T]], did: String, sender: T): T = {
+ val origMap = senders.get(did)
+ val map = if (origMap.isEmpty) new ConcurrentHashMap[Snowflake, T] else origMap.get
map.put(sender.getChannel.getId, sender)
senders.put(did, map)
sender
@@ -117,15 +121,12 @@ object MCChatUtils {
else null.asInstanceOf
}
- def forPublicPrivateChat(action: Mono[MessageChannel] => Mono[_]): Mono[_] = {
- if (notEnabled) return Mono.empty
- val list = new util.ArrayList[Mono[_]]
- list.add(action.apply(module.chatChannelMono))
- for (data <- MCChatPrivate.lastmsgPerUser) {
- list.add(action.apply(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))
// lastmsgCustom.forEach(cc -> action.accept(cc.channel)); - Only send relevant messages to custom chat
- Mono.whenDelayError(list)
+ SMono.whenDelayError(list)
}
/**
@@ -135,14 +136,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
- val list = new util.ArrayList[Publisher[_]]
- if (!GeneralEventBroadcasterModule.isHooked || !hookmsg) list.add(forPublicPrivateChat(action))
- val customLMDFunction = (cc: MCChatCustom.CustomLMD) => action.apply(Mono.just(cc.channel))
- if (toggle == null) MCChatCustom.lastmsgCustom.stream.map(customLMDFunction).forEach(list.add(_))
- else MCChatCustom.lastmsgCustom.stream.filter((cc) => (cc.toggles & toggle.flag) ne 0).map(customLMDFunction).forEach(list.add(_))
- Mono.whenDelayError(list)
+ def forCustomAndAllMCChat(action: SMono[MessageChannel] => SMono[_], @Nullable toggle: ChannelconBroadcast, hookmsg: Boolean): SMono[_] = {
+ if (notEnabled) return SMono.empty
+ val list = new ListBuffer[Publisher[_]]
+ if (!GeneralEventBroadcasterModule.isHooked || !hookmsg) list.append(forPublicPrivateChat(action))
+ val customLMDFunction = (cc: MCChatCustom.CustomLMD) => action(SMono.just(cc.channel))
+ if (toggle == null) MCChatCustom.lastmsgCustom.map(customLMDFunction).foreach(list.append(_))
+ else MCChatCustom.lastmsgCustom.filter((cc) => (cc.toggles & (1 << toggle.id)) ne 0).map(customLMDFunction).foreach(list.append(_))
+ SMono.whenDelayError(list)
}
/**
@@ -152,18 +153,15 @@ object MCChatUtils {
* @param sender The sender 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 sender: CommandSender, @Nullable toggle: ChannelconBroadcast): Mono[_] = {
- if (notEnabled) return Mono.empty
- val st = MCChatCustom.lastmsgCustom.stream.filter((clmd) => {
- def foo(clmd: CustomLMD): Boolean = { //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)) eq 0)) return false //If null then allow
- if (sender == null) return true
- clmd.groupID.equals(clmd.mcchannel.getGroupID(sender))
- }
-
- foo(clmd)
- }).map((cc) => action.apply(Mono.just(cc.channel))) //TODO: Send error messages on channel connect
- Mono.whenDelayError(st.iterator) //Can't convert as an iterator or inside the stream, but I can convert it as a stream
+ def forAllowedCustomMCChat(action: SMono[MessageChannel] => SMono[_], @Nullable sender: CommandSender, @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)) eq 0)) false //If null then allow
+ else if (sender == null) true
+ else clmd.groupID.equals(clmd.mcchannel.getGroupID(sender))
+ }).map(cc => action.apply(SMono.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
+ SMono.whenDelayError(st)
}
/**
@@ -174,47 +172,45 @@ 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 sender: CommandSender, @Nullable toggle: ChannelconBroadcast, hookmsg: Boolean): Mono[_] = {
- if (notEnabled) return Mono.empty
+ def forAllowedCustomAndAllMCChat(action: SMono[MessageChannel] => SMono[_], @Nullable sender: CommandSender, @Nullable toggle: ChannelconBroadcast, hookmsg: Boolean): SMono[_] = {
+ if (notEnabled) return SMono.empty
val cc = forAllowedCustomMCChat(action, sender, toggle)
- if (!GeneralEventBroadcasterModule.isHooked || !hookmsg) return Mono.whenDelayError(forPublicPrivateChat(action), cc)
- Mono.whenDelayError(cc)
+ if (!GeneralEventBroadcasterModule.isHooked || !hookmsg) return SMono.whenDelayError(Array(forPublicPrivateChat(action), cc))
+ SMono.whenDelayError(Array(cc))
}
- def send(message: String): Mono[MessageChannel] => Mono[_] = (ch: Mono[MessageChannel]) => ch.flatMap((mc: MessageChannel) => {
- def foo(mc: MessageChannel) = {
- resetLastMessage(mc)
- mc.createMessage(DPUtils.sanitizeString(message))
- }
-
- foo(mc)
+ def send(message: String): SMono[MessageChannel] => SMono[_] = _.flatMap((mc: MessageChannel) => {
+ resetLastMessage(mc)
+ SMono(mc.createMessage(DPUtils.sanitizeString(message)))
})
- def forAllowedMCChat(action: Mono[MessageChannel] => Mono[_], event: TBMCSystemChatEvent): Mono[_] = {
- if (notEnabled) return Mono.empty
- val list = new util.ArrayList[Mono[_]]
- if (event.getChannel.isGlobal) list.add(action.apply(module.chatChannelMono))
+ 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.add(action.apply(Mono.just(data.channel))) //TODO: Only store ID?}
- MCChatCustom.lastmsgCustom.stream.filter((clmd) => {
- def foo(clmd: CustomLMD): Boolean = {
- clmd.brtoggles.contains(event.getTarget) && event.shouldSendTo(clmd.dcp)
- }
-
- foo(clmd)
- }).map((clmd) => action.apply(Mono.just(clmd.channel))).forEach(list.add(_))
- Mono.whenDelayError(list)
+ if (event.shouldSendTo(getSender(data.channel.getId, 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))
+ .map(clmd => action(SMono.just(clmd.channel))).forEach(elem => {
+ list.append(elem)
+ ()
+ })
+ 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) = { //noinspection OptionalGetWithoutIsPresent
- Stream.of[Supplier[Optional[DiscordSenderBase]]]( // https://stackoverflow.com/a/28833677/2703239
- () => Optional.ofNullable(getSender(OnlineSenders, channel, author)), // Find first non-null
- () => Optional.ofNullable(getSender(ConnectedSenders, channel, author)), // This doesn't support the public chat, but it'll always return null for it
- () => Optional.ofNullable(getSender(UnconnectedSenders, channel, author)), //
- () => Optional.of(addSender(UnconnectedSenders, author, new DiscordSender(author, DiscordPlugin.dc.getChannelById(channel).block.asInstanceOf[MessageChannel])))).map(_.get).filter(_.isPresent).map(_.get).findFirst.get
+ private[mcchat] def getSender(channel: Snowflake, author: User): DiscordSenderBase = { //noinspection OptionalGetWithoutIsPresent
+ List[() => DiscordSenderBase]( // https://stackoverflow.com/a/28833677/2703239
+ () => getSender[DiscordSenderBase](OnlineSenders, channel, author), // Find first non-null
+ () => getSender[DiscordSenderBase](ConnectedSenders, channel, author), // This doesn't support the public chat, but it'll always return null for it
+ () => getSender[DiscordSenderBase](UnconnectedSenders, channel, author), //
+ () => addSender[DiscordSenderBase](UnconnectedSenders, author,
+ new DiscordSender(author, SMono(DiscordPlugin.dc.getChannelById(channel)).block().asInstanceOf[MessageChannel])))
+ .map(_.apply()).find(sender => sender != null).get
}
/**
@@ -226,7 +222,7 @@ object MCChatUtils {
def resetLastMessage(channel: Channel): Unit = {
if (notEnabled) return
if (channel.getId.asLong == module.chatChannel.get.asLong) {
- if (lastmsgdata == null) lastmsgdata = new MCChatUtils.LastMsgData(module.chatChannelMono.block, null)
+ if (lastmsgdata == null) lastmsgdata = new MCChatUtils.LastMsgData(module.chatChannelMono.block(), null)
else lastmsgdata.message = null
return
} // Don't set the whole object to null, the player and channel information should be preserved
@@ -241,25 +237,23 @@ object MCChatUtils {
}
def addStaticExcludedPlugin(event: Class[_ <: Event], plugin: String): util.HashSet[String] =
- staticExcludedPlugins.compute(event, (e: Class[_ <: Event], hs: util.HashSet[String]) =>
+ staticExcludedPlugins.compute(event, (_, hs: util.HashSet[String]) =>
if (hs == null) Sets.newHashSet(plugin) else if (hs.add(plugin)) hs else hs)
def callEventExcludingSome(event: Event): Unit = {
if (notEnabled) return
val second = staticExcludedPlugins.get(event.getClass)
val first = module.excludedPlugins.get
- val both = if (second == null) first
+ val both = if (second.isEmpty) first
else util.Arrays.copyOf(first, first.length + second.size)
var i = first.length
- if (second != null) {
- for (plugin <- second) {
- both({
- i += 1;
- i - 1
- }) = plugin
+ if (second.nonEmpty) {
+ for (plugin <- second.get.asScala) {
+ both(i) = plugin
+ i += 1
}
}
- callEventExcluding(event, false, both)
+ callEventExcluding(event, false, both: _*)
}
/**
@@ -275,21 +269,18 @@ object MCChatUtils {
if (event.isAsynchronous) {
if (Thread.holdsLock(Bukkit.getPluginManager)) throw new IllegalStateException(event.getEventName + " cannot be triggered asynchronously from inside synchronized code.")
if (Bukkit.getServer.isPrimaryThread) throw new IllegalStateException(event.getEventName + " cannot be triggered asynchronously from primary server thread.")
- fireEventExcluding(event, only, plugins)
+ fireEventExcluding(event, only, plugins: _*)
}
- else Bukkit.getPluginManager synchronized fireEventExcluding(event, only, plugins)
+ else Bukkit.getPluginManager synchronized fireEventExcluding(event, only, plugins: _*)
}
private def fireEventExcluding(event: Event, only: Boolean, plugins: String*): Unit = {
val handlers = event.getHandlers // Code taken from SimplePluginManager in Spigot-API
val listeners = handlers.getRegisteredListeners
val server = Bukkit.getServer
- for (registration <- listeners) {
- if (!registration.getPlugin.isEnabled || util.Arrays.stream(plugins).anyMatch((p: String) => only ^ p.equalsIgnoreCase(registration.getPlugin.getName))) {
- continue //todo: continue is not supported
- // Modified to exclude plugins
- }
- try registration.callEvent(event)
+ for (registration <- listeners) { // Modified to exclude plugins
+ if (registration.getPlugin.isEnabled
+ && !plugins.exists(only ^ _.equalsIgnoreCase(registration.getPlugin.getName))) try registration.callEvent(event)
catch {
case ex: AuthorNagException =>
val plugin = registration.getPlugin
@@ -308,12 +299,8 @@ object MCChatUtils {
*/
def callLoginEvents(dcp: DiscordConnectedPlayer): Unit = {
val loginFail = (kickMsg: String) => {
- def foo(kickMsg: String): Unit = {
- dcp.sendMessage("Minecraft chat disabled, as the login failed: " + kickMsg)
- MCChatPrivate.privateMCChat(dcp.getChannel, start = false, dcp.getUser, dcp.getChromaUser)
- }
-
- foo(kickMsg)
+ dcp.sendMessage("Minecraft chat disabled, as the login failed: " + kickMsg)
+ MCChatPrivate.privateMCChat(dcp.getChannel, start = false, dcp.getUser, dcp.getChromaUser)
} //Probably also happens if the user is banned or so
val event = new AsyncPlayerPreLoginEvent(dcp.getName, InetAddress.getLoopbackAddress, dcp.getUniqueId)
callEventExcludingSome(event)
diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.scala b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.scala
index 5b8aa3f..f469019 100644
--- a/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.scala
+++ b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.scala
@@ -1,22 +1,23 @@
package buttondevteam.discordplugin.mcchat
import buttondevteam.core.component.channel.Channel
-import buttondevteam.discordplugin.{ChannelconBroadcast, DPUtils, DiscordConnectedPlayer, DiscordPlugin}
import buttondevteam.discordplugin.playerfaker.ServerWatcher
import buttondevteam.discordplugin.playerfaker.perm.LPInjector
import buttondevteam.discordplugin.util.DPState
-import buttondevteam.lib.{TBMCCoreAPI, TBMCSystemChatEvent}
+import buttondevteam.discordplugin.{ChannelconBroadcast, DPUtils, DiscordConnectedPlayer, DiscordPlugin}
import buttondevteam.lib.architecture.{Component, ConfigData, ReadOnlyConfigData}
+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.rest.util.Color
import org.bukkit.Bukkit
import reactor.core.publisher.Mono
+import reactor.core.scala.publisher.SMono
import java.util
-import java.util.{Objects, UUID}
import java.util.stream.Collectors
+import java.util.{Objects, UUID}
/**
* Provides Minecraft chat connection to Discord. Commands may be used either in a public chat (limited) or in a DM.
@@ -45,7 +46,7 @@ class MinecraftChatModule extends Component[DiscordPlugin] {
*/
val chatChannel: ReadOnlyConfigData[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