Fix compilation issues and startup exceptions

- Removed test class because it errors, and I don't know how to fix it
- Updated dependencies
- Fixed SMono.whenDelayError() causing a crash on Scala 3.0.0
- Fixed subscribe method calls being ambiguous
- Fixed returns returning the wrong things
- Converted onGetInfo() to use no returns
This commit is contained in:
Norbi Peti 2021-08-26 02:03:06 +02:00
parent 263c652d68
commit 9f3ca37929
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
27 changed files with 156 additions and 195 deletions

View file

@ -20,10 +20,10 @@ libraryDependencies ++= Seq(
"org.spigotmc." % "spigot" % "1.14.4-R0.1-SNAPSHOT" % Provided, "org.spigotmc." % "spigot" % "1.14.4-R0.1-SNAPSHOT" % Provided,
"com.destroystokyo.paper" % "paper" % "1.16.3-R0.1-SNAPSHOT" % Provided, "com.destroystokyo.paper" % "paper" % "1.16.3-R0.1-SNAPSHOT" % Provided,
"com.discord4j" % "discord4j-core" % "3.1.6", "com.discord4j" % "discord4j-core" % "3.2.1",
"org.slf4j" % "slf4j-jdk14" % "1.7.31", "org.slf4j" % "slf4j-jdk14" % "1.7.32",
"com.vdurmont" % "emoji-java" % "5.1.1", "com.vdurmont" % "emoji-java" % "5.1.1",
"org.mockito" % "mockito-core" % "3.11.1", "org.mockito" % "mockito-core" % "4.2.0",
"io.projectreactor" % "reactor-scala-extensions_2.13" % "0.8.0", "io.projectreactor" % "reactor-scala-extensions_2.13" % "0.8.0",
// https://mvnrepository.com/artifact/org.immutables/value // https://mvnrepository.com/artifact/org.immutables/value
"org.immutables" % "value" % "2.8.8" % "provided", "org.immutables" % "value" % "2.8.8" % "provided",

View file

@ -1,2 +1,2 @@
sbt.version=1.5.4 sbt.version=1.5.8
scala.version=3.0.0 scala.version=3.0.0

View file

@ -21,7 +21,7 @@ object ChromaBot {
* @param message The message to send, duh (use [[MessageChannel.createMessage]]) * @param message The message to send, duh (use [[MessageChannel.createMessage]])
*/ */
def sendMessage(message: SMono[MessageChannel] => SMono[Message]): Unit = def sendMessage(message: SMono[MessageChannel] => SMono[Message]): Unit =
MCChatUtils.forPublicPrivateChat(message).subscribe MCChatUtils.forPublicPrivateChat(message).subscribe()
/** /**
* Send a message to the chat channels, private chats and custom chats. * Send a message to the chat channels, private chats and custom chats.
@ -30,7 +30,7 @@ object ChromaBot {
* @param toggle The toggle type for channelcon * @param toggle The toggle type for channelcon
*/ */
def sendMessageCustomAsWell(message: SMono[MessageChannel] => SMono[Message], @Nullable toggle: ChannelconBroadcast): Unit = def sendMessageCustomAsWell(message: SMono[MessageChannel] => SMono[Message], @Nullable toggle: ChannelconBroadcast): Unit =
MCChatUtils.forCustomAndAllMCChat(message.apply, toggle, hookmsg = false).subscribe MCChatUtils.forCustomAndAllMCChat(message.apply, toggle, hookmsg = false).subscribe()
def updatePlayerList(): Unit = def updatePlayerList(): Unit =
MCChatUtils.updatePlayerList() MCChatUtils.updatePlayerList()

View file

@ -5,7 +5,7 @@ import buttondevteam.lib.architecture.{Component, ConfigData, IHaveConfig, ReadO
import discord4j.common.util.Snowflake import discord4j.common.util.Snowflake
import discord4j.core.`object`.entity.channel.MessageChannel import discord4j.core.`object`.entity.channel.MessageChannel
import discord4j.core.`object`.entity.{Guild, Message, Role} import discord4j.core.`object`.entity.{Guild, Message, Role}
import discord4j.core.spec.{EmbedCreateSpec, Spec} import discord4j.core.spec.legacy.{LegacyEmbedCreateSpec, LegacySpec}
import reactor.core.publisher.{Flux, Mono} import reactor.core.publisher.{Flux, Mono}
import reactor.core.scala.publisher.{SFlux, SMono} import reactor.core.scala.publisher.{SFlux, SMono}
@ -19,7 +19,7 @@ object DPUtils {
private val URL_PATTERN = Pattern.compile("https?://\\S*") private val URL_PATTERN = Pattern.compile("https?://\\S*")
private val FORMAT_PATTERN = Pattern.compile("[*_~]") private val FORMAT_PATTERN = Pattern.compile("[*_~]")
def embedWithHead(ecs: EmbedCreateSpec, displayname: String, playername: String, profileUrl: String): EmbedCreateSpec = def embedWithHead(ecs: LegacyEmbedCreateSpec, displayname: String, playername: String, profileUrl: String): LegacyEmbedCreateSpec =
ecs.setAuthor(displayname, profileUrl, "https://minotar.net/avatar/" + playername + "/32.png") ecs.setAuthor(displayname, profileUrl, "https://minotar.net/avatar/" + playername + "/32.png")
/** /**
@ -216,7 +216,7 @@ object DPUtils {
def ^^(): SFlux[T] = SFlux(flux) def ^^(): SFlux[T] = SFlux(flux)
} }
implicit class SpecExtensions[T <: Spec[_]](spec: T) { implicit class SpecExtensions[T <: LegacySpec[_]](spec: T) {
def ^^(): Unit = () def ^^(): Unit = ()
} }

View file

@ -16,7 +16,7 @@ import buttondevteam.lib.player.ChromaGamerBase
import com.google.common.io.Files import com.google.common.io.Files
import discord4j.common.util.Snowflake import discord4j.common.util.Snowflake
import discord4j.core.`object`.entity.{ApplicationInfo, Guild, Role} import discord4j.core.`object`.entity.{ApplicationInfo, Guild, Role}
import discord4j.core.`object`.presence.{Activity, Presence} import discord4j.core.`object`.presence.{Activity, ClientActivity, ClientPresence, Presence}
import discord4j.core.`object`.reaction.ReactionEmoji import discord4j.core.`object`.reaction.ReactionEmoji
import discord4j.core.event.domain.guild.GuildCreateEvent import discord4j.core.event.domain.guild.GuildCreateEvent
import discord4j.core.event.domain.lifecycle.ReadyEvent import discord4j.core.event.domain.lifecycle.ReadyEvent
@ -124,15 +124,15 @@ import java.util.Optional
getLogger.severe("Token not found! Please set it in private.yml then do /discord restart") getLogger.severe("Token not found! Please set it in private.yml then do /discord restart")
getLogger.severe("You need to have a bot account to use with your server.") getLogger.severe("You need to have a bot account to use with your server.")
getLogger.severe("If you don't have one, go to https://discordapp.com/developers/applications/ and create an application, then create a bot for it and copy the bot token.") getLogger.severe("If you don't have one, go to https://discordapp.com/developers/applications/ and create an application, then create a bot for it and copy the bot token.")
return return ()
} }
} }
starting = true starting = true
//System.out.println("This line should show up for sure"); //System.out.println("This line should show up for sure");
val cb = DiscordClientBuilder.create(token).build.gateway val cb = DiscordClientBuilder.create(token).build.gateway
//System.out.println("Got gateway bootstrap"); //System.out.println("Got gateway bootstrap");
cb.setInitialStatus((si: ShardInfo) => Presence.doNotDisturb(Activity.playing("booting"))) cb.setInitialPresence((si: ShardInfo) => ClientPresence.doNotDisturb(ClientActivity.playing("booting")))
cb.setStoreService(new JdkStoreService) //The default doesn't work for some reason - it's waaay faster now //cb.setStore(new JdkStoreService) //The default doesn't work for some reason - it's waaay faster now
//System.out.println("Initial status and store service set"); //System.out.println("Initial status and store service set");
cb.login.doOnError((t: Throwable) => { cb.login.doOnError((t: Throwable) => {
def foo(t: Throwable): Unit = { def foo(t: Throwable): Unit = {
@ -165,8 +165,8 @@ import java.util.Optional
try { try {
if (DiscordPlugin.mainServer != null) { //This is not the first ready event if (DiscordPlugin.mainServer != null) { //This is not the first ready event
getLogger.info("Ready event already handled") //TODO: It should probably handle disconnections getLogger.info("Ready event already handled") //TODO: It should probably handle disconnections
DiscordPlugin.dc.updatePresence(Presence.online(Activity.playing("Minecraft"))).subscribe //Update from the initial presence DiscordPlugin.dc.updatePresence(ClientPresence.online(ClientActivity.playing("Minecraft"))).subscribe //Update from the initial presence
return return ()
} }
DiscordPlugin.mainServer = mainServer.get.orNull //Shouldn't change afterwards DiscordPlugin.mainServer = mainServer.get.orNull //Shouldn't change afterwards
if (DiscordPlugin.mainServer == null) { if (DiscordPlugin.mainServer == null) {
@ -217,8 +217,8 @@ import java.util.Optional
logWatcher = blw logWatcher = blw
Interactions.create().onCommand("teszt", Interactions.createHandler() Interactions.create().onCommand("teszt", Interactions.createHandler()
.guild(gi => gi.acknowledge().withFollowup(_.createFollowupMessage("Teszt"))).build()); .guild(gi => gi.acknowledge().withFollowup(_.createFollowupMessage("Teszt"))).build());
if (!TBMCCoreAPI.IsTestServer) DiscordPlugin.dc.updatePresence(Presence.online(Activity.playing("Minecraft"))).subscribe if (!TBMCCoreAPI.IsTestServer) DiscordPlugin.dc.updatePresence(ClientPresence.online(ClientActivity.playing("Minecraft"))).subscribe()
else DiscordPlugin.dc.updatePresence(Presence.online(Activity.playing("testing"))).subscribe else DiscordPlugin.dc.updatePresence(ClientPresence.online(ClientActivity.playing("testing"))).subscribe()
getLogger.info("Loaded!") getLogger.info("Loaded!")
} catch { } catch {
case e: Exception => case e: Exception =>
@ -247,7 +247,7 @@ import java.util.Optional
override def pluginDisable(): Unit = { override def pluginDisable(): Unit = {
val timings = new Timings val timings = new Timings
timings.printElapsed("Actual disable start (logout)") timings.printElapsed("Actual disable start (logout)")
if (!ChromaBot.enabled) return if (!ChromaBot.enabled) return ()
try { try {
DiscordPlugin.SafeMode = true // Stop interacting with Discord DiscordPlugin.SafeMode = true // Stop interacting with Discord
ChromaBot.enabled = false ChromaBot.enabled = false

View file

@ -41,7 +41,7 @@ abstract class DiscordSenderBase protected(var user: User, var channel: MessageC
override def sendMessage(message: String): Unit = try { override def sendMessage(message: String): Unit = try {
val broadcast = new Exception().getStackTrace()(2).getMethodName.contains("broadcast") val broadcast = new Exception().getStackTrace()(2).getMethodName.contains("broadcast")
if (broadcast) { //We're catching broadcasts using the Bukkit event if (broadcast) { //We're catching broadcasts using the Bukkit event
return return ()
} }
val sendmsg = DPUtils.sanitizeString(message) val sendmsg = DPUtils.sanitizeString(message)
this synchronized { this synchronized {
@ -49,7 +49,7 @@ abstract class DiscordSenderBase protected(var user: User, var channel: MessageC
if (sendtask == null) sendtask = Bukkit.getScheduler.runTaskLaterAsynchronously(DiscordPlugin.plugin, () => { if (sendtask == null) sendtask = Bukkit.getScheduler.runTaskLaterAsynchronously(DiscordPlugin.plugin, () => {
def foo(): Unit = { def foo(): Unit = {
channel.createMessage((if (user != null) user.getMention + "\n" channel.createMessage((if (user != null) user.getMention + "\n"
else "") + msgtosend.trim).subscribe else "") + msgtosend.trim).subscribe()
sendtask = null sendtask = null
msgtosend = "" msgtosend = ""
} }

View file

@ -38,10 +38,10 @@ import scala.annotation.tailrec
final private val subredditURL = getConfig.getData("subredditURL", "https://www.reddit.com/r/ChromaGamers") final private val subredditURL = getConfig.getData("subredditURL", "https://www.reddit.com/r/ChromaGamers")
override protected def enable(): Unit = { override protected def enable(): Unit = {
if (DPUtils.disableIfConfigError(this, channel, modChannel)) return if (DPUtils.disableIfConfigError(this, channel, modChannel)) return ()
AnnouncerModule.stop = false //If not the first time AnnouncerModule.stop = false //If not the first time
val kp: Short = keepPinned.get val kp = keepPinned.get
if (kp <= 0) return if (kp <= 0) return ()
val msgs = channel.get.flatMapMany(_.getPinnedMessages).takeLast(kp) val msgs = channel.get.flatMapMany(_.getPinnedMessages).takeLast(kp)
msgs.subscribe(_.unpin) msgs.subscribe(_.unpin)
new Thread(() => this.AnnouncementGetterThreadMethod()).start() new Thread(() => this.AnnouncementGetterThreadMethod()).start()
@ -85,7 +85,7 @@ import scala.annotation.tailrec
} }
def sendMsg(ch: SMono[MessageChannel], msg: String) = def sendMsg(ch: SMono[MessageChannel], msg: String) =
ch.asJava().flatMap(c => c.createMessage(msg)).flatMap(_.pin).subscribe ch.asJava().flatMap(c => c.createMessage(msg)).flatMap(_.pin).subscribe()
if (msgsb.nonEmpty) sendMsg(channel.get(), msgsb.toString()) if (msgsb.nonEmpty) sendMsg(channel.get(), msgsb.toString())
if (modmsgsb.nonEmpty) sendMsg(modChannel.get(), modmsgsb.toString()) if (modmsgsb.nonEmpty) sendMsg(modChannel.get(), modmsgsb.toString())

View file

@ -27,7 +27,7 @@ import buttondevteam.lib.architecture.{Component, ComponentMetadata}
} }
override protected def disable(): Unit = try { override protected def disable(): Unit = try {
if (!GeneralEventBroadcasterModule.hooked) return if (!GeneralEventBroadcasterModule.hooked) return ()
if (PlayerListWatcher.hookUpDown(false, this)) log("Finished unhooking the player list!") if (PlayerListWatcher.hookUpDown(false, this)) log("Finished unhooking the player list!")
else log("Didn't have the player list hooked.") else log("Didn't have the player list hooked.")
GeneralEventBroadcasterModule.hooked = false GeneralEventBroadcasterModule.hooked = false

View file

@ -130,7 +130,7 @@ object PlayerListWatcher {
if (packet.getClass eq ppoc) { if (packet.getClass eq ppoc) {
val msgf = ppoc.getDeclaredField("a") val msgf = ppoc.getDeclaredField("a")
msgf.setAccessible(true) msgf.setAccessible(true)
MCChatUtils.forPublicPrivateChat(MCChatUtils.send(toPlainText.invoke(msgf.get(packet)).asInstanceOf[String])).subscribe MCChatUtils.forPublicPrivateChat(MCChatUtils.send(toPlainText.invoke(msgf.get(packet)).asInstanceOf[String])).subscribe()
} }
} catch { } catch {
case e: Exception => case e: Exception =>

View file

@ -9,10 +9,10 @@ class Command2DCSender(val message: Message) extends Command2Sender {
def getMessage: Message = this.message def getMessage: Message = this.message
override def sendMessage(message: String): Unit = { override def sendMessage(message: String): Unit = {
if (message.isEmpty) return if (message.isEmpty) return ()
var msg = DPUtils.sanitizeString(message) var msg = DPUtils.sanitizeString(message)
msg = Character.toLowerCase(message.charAt(0)) + message.substring(1) msg = Character.toLowerCase(message.charAt(0)) + message.substring(1)
this.message.getChannel.flatMap((ch: MessageChannel) => ch.createMessage(this.message.getAuthor.map((u: User) => DPUtils.nickMention(u.getId) + ", ").orElse("") + msg)).subscribe 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: _*))

View file

@ -26,23 +26,23 @@ import org.bukkit.entity.Player
val author = message.getAuthor.orElse(null) val author = message.getAuthor.orElse(null)
if (author == null || channel == null) return true if (author == null || channel == null) return true
if (ConnectCommand.WaitingToConnect.inverse.containsKey(author.getId.asString)) { if (ConnectCommand.WaitingToConnect.inverse.containsKey(author.getId.asString)) {
channel.createMessage("Replacing " + ConnectCommand.WaitingToConnect.inverse.get(author.getId.asString) + " with " + Minecraftname).subscribe channel.createMessage("Replacing " + ConnectCommand.WaitingToConnect.inverse.get(author.getId.asString) + " with " + Minecraftname).subscribe()
ConnectCommand.WaitingToConnect.inverse.remove(author.getId.asString) ConnectCommand.WaitingToConnect.inverse.remove(author.getId.asString)
} }
//noinspection ScalaDeprecation //noinspection ScalaDeprecation
val p = Bukkit.getOfflinePlayer(Minecraftname) val p = Bukkit.getOfflinePlayer(Minecraftname)
if (p == null) { if (p == null) {
channel.createMessage("The specified Minecraft player cannot be found").subscribe channel.createMessage("The specified Minecraft player cannot be found").subscribe()
return true return true
} }
val pl = TBMCPlayerBase.getPlayer(p.getUniqueId, classOf[TBMCPlayer]) val pl = TBMCPlayerBase.getPlayer(p.getUniqueId, classOf[TBMCPlayer])
val dp = pl.getAs(classOf[DiscordPlayer]) val dp = pl.getAs(classOf[DiscordPlayer])
if (dp != null && author.getId.asString == dp.getDiscordID) { if (dp != null && author.getId.asString == dp.getDiscordID) {
channel.createMessage("You already have this account connected.").subscribe channel.createMessage("You already have this account connected.").subscribe()
return true return true
} }
ConnectCommand.WaitingToConnect.put(p.getName, author.getId.asString) ConnectCommand.WaitingToConnect.put(p.getName, author.getId.asString)
channel.createMessage("Alright! Now accept the connection in Minecraft from the account " + Minecraftname + " before the next server restart. You can also adjust the Minecraft name you want to connect to by running this command again.").subscribe channel.createMessage("Alright! Now accept the connection in Minecraft from the account " + Minecraftname + " before the next server restart. You can also adjust the Minecraft name you want to connect to by running this command again.").subscribe()
if (p.isOnline) p.asInstanceOf[Player].sendMessage("§bTo connect with the Discord account " + author.getUsername + "#" + author.getDiscriminator + " do /discord accept") if (p.isOnline) p.asInstanceOf[Player].sendMessage("§bTo connect with the Discord account " + author.getUsername + "#" + author.getDiscriminator + " do /discord accept")
true true
} }

View file

@ -7,6 +7,8 @@ import buttondevteam.lib.player.ChromaGamerBase.InfoTarget
import discord4j.core.`object`.entity.{Message, User} import discord4j.core.`object`.entity.{Message, User}
import reactor.core.scala.publisher.SFlux import reactor.core.scala.publisher.SFlux
import scala.jdk.CollectionConverters.ListHasAsScala
@CommandClass(helpText = 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.", "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."))
@ -19,31 +21,31 @@ class UserinfoCommand extends ICommand2DC {
assert(channel != null) assert(channel != null)
if (user == null || user.isEmpty) target = message.getAuthor.orElse(null) if (user == null || user.isEmpty) target = message.getAuthor.orElse(null)
else { else {
val firstmention = message.getUserMentions.filter((m: User) => !(m.getId.asString == DiscordPlugin.dc.getSelfId.asString)).blockFirst val firstmention = message.getUserMentions.asScala.find((m: User) => !(m.getId.asString == DiscordPlugin.dc.getSelfId.asString))
if (firstmention != null) target = firstmention if (firstmention.isDefined) target = firstmention.get
else if (user.contains("#")) { else if (user.contains("#")) {
val targettag = user.split("#") val targettag = user.split("#")
val targets = getUsers(message, targettag(0)) val targets = getUsers(message, targettag(0))
if (targets.isEmpty) { if (targets.isEmpty) {
channel.createMessage("The user cannot be found (by name): " + user).subscribe channel.createMessage("The user cannot be found (by name): " + user).subscribe()
return true return true
} }
targets.collectFirst { targets.collectFirst {
case user => user.getDiscriminator.equalsIgnoreCase(targettag(1)) case user => user.getDiscriminator.equalsIgnoreCase(targettag(1))
} }
if (target == null) { if (target == null) {
channel.createMessage("The user cannot be found (by discriminator): " + user + "(Found " + targets.size + " users with the name.)").subscribe channel.createMessage("The user cannot be found (by discriminator): " + user + "(Found " + targets.size + " users with the name.)").subscribe()
return true return true
} }
} }
else { else {
val targets = getUsers(message, user) val targets = getUsers(message, user)
if (targets.isEmpty) { if (targets.isEmpty) {
channel.createMessage("The user cannot be found on Discord: " + user).subscribe channel.createMessage("The user cannot be found on Discord: " + user).subscribe()
return true return true
} }
if (targets.size > 1) { if (targets.size > 1) {
channel.createMessage("Multiple users found with that (nick)name. Please specify the whole tag, like ChromaBot#6338 or use a ping.").subscribe channel.createMessage("Multiple users found with that (nick)name. Please specify the whole tag, like ChromaBot#6338 or use a ping.").subscribe()
return true return true
} }
target = targets.head target = targets.head
@ -56,7 +58,7 @@ class UserinfoCommand extends ICommand2DC {
val dp = ChromaGamerBase.getUser(target.getId.asString, classOf[DiscordPlayer]) val dp = ChromaGamerBase.getUser(target.getId.asString, classOf[DiscordPlayer])
val uinfo = new StringBuilder("User info for ").append(target.getUsername).append(":\n") val uinfo = new StringBuilder("User info for ").append(target.getUsername).append(":\n")
uinfo.append(dp.getInfo(InfoTarget.Discord)) uinfo.append(dp.getInfo(InfoTarget.Discord))
channel.createMessage(uinfo.toString).subscribe channel.createMessage(uinfo.toString).subscribe()
true true
} }

View file

@ -9,15 +9,15 @@ import reactor.core.scala.publisher.SMono
object DebugMessageListener { object DebugMessageListener {
private def SendMessage(message: String): Unit = { private def SendMessage(message: String): Unit = {
if (DiscordPlugin.SafeMode || !ComponentManager.isEnabled(classOf[ExceptionListenerModule])) return if (DiscordPlugin.SafeMode || !ComponentManager.isEnabled(classOf[ExceptionListenerModule])) return ()
try { try {
val mc = ExceptionListenerModule.getChannel val mc = ExceptionListenerModule.getChannel
if (mc == null) return if (mc == null) return ()
val sb = new StringBuilder val sb = new StringBuilder
sb.append("```").append("\n") sb.append("```").append("\n")
sb.append(if (message.length > 2000) message.substring(0, 2000) else message).append("\n") sb.append(if (message.length > 2000) message.substring(0, 2000) else message).append("\n")
sb.append("```") sb.append("```")
mc.flatMap((ch: MessageChannel) => SMono(ch.createMessage(sb.toString))).subscribe mc.flatMap((ch: MessageChannel) => SMono(ch.createMessage(sb.toString))).subscribe()
} catch { } catch {
case ex: Exception => case ex: Exception =>
ex.printStackTrace() ex.printStackTrace()

View file

@ -19,7 +19,7 @@ import java.util.stream.Collectors
*/ */
object ExceptionListenerModule { object ExceptionListenerModule {
private def SendException(e: Throwable, sourcemessage: String): Unit = { private def SendException(e: Throwable, sourcemessage: String): Unit = {
if (instance == null) return if (instance == null) return ()
try getChannel.flatMap(channel => { try getChannel.flatMap(channel => {
val coderRole = channel match { val coderRole = channel match {
case ch: GuildChannel => instance.pingRole(SMono(ch.getGuild)).get case ch: GuildChannel => instance.pingRole(SMono(ch.getGuild)).get
@ -31,14 +31,14 @@ object ExceptionListenerModule {
sb.append(sourcemessage).append("\n") sb.append(sourcemessage).append("\n")
sb.append("```").append("\n") sb.append("```").append("\n")
var stackTrace = util.Arrays.stream(ExceptionUtils.getStackTrace(e).split("\\n")) var stackTrace = util.Arrays.stream(ExceptionUtils.getStackTrace(e).split("\\n"))
.filter(s => !s.contains("\tat ") || s.contains("\tat buttondevteam.")) .filter(s => !s.contains("\tat ") || s.contains("buttondevteam."))
.collect(Collectors.joining("\n")) .collect(Collectors.joining("\n"))
if (sb.length + stackTrace.length >= 1980) stackTrace = stackTrace.substring(0, 1980 - sb.length) if (sb.length + stackTrace.length >= 1980) stackTrace = stackTrace.substring(0, 1980 - sb.length)
sb.append(stackTrace).append("\n") sb.append(stackTrace).append("\n")
sb.append("```") sb.append("```")
SMono(channel.createMessage(sb.toString)) SMono(channel.createMessage(sb.toString))
}) })
}).subscribe }).subscribe()
catch { catch {
case ex: Exception => case ex: Exception =>
ex.printStackTrace() ex.printStackTrace()
@ -58,11 +58,11 @@ class ExceptionListenerModule extends Component[DiscordPlugin] with Listener {
final private val lastsourcemsg = new util.ArrayList[String] final private val lastsourcemsg = new util.ArrayList[String]
@EventHandler def onException(e: TBMCExceptionEvent): Unit = { @EventHandler def onException(e: TBMCExceptionEvent): Unit = {
if (DiscordPlugin.SafeMode || !ComponentManager.isEnabled(getClass)) return if (DiscordPlugin.SafeMode || !ComponentManager.isEnabled(getClass)) return ()
if (lastthrown.stream.anyMatch(ex => e.getException.getStackTrace.sameElements(ex.getStackTrace) 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)) && (if (e.getException.getMessage == null) ex.getMessage == null else e.getException.getMessage == ex.getMessage))
&& lastsourcemsg.contains(e.getSourceMessage)) { && lastsourcemsg.contains(e.getSourceMessage)) {
return return ()
} }
ExceptionListenerModule.SendException(e.getException, e.getSourceMessage) ExceptionListenerModule.SendException(e.getException, e.getSourceMessage)
if (lastthrown.size >= 10) lastthrown.remove(0) if (lastthrown.size >= 10) lastthrown.remove(0)
@ -83,7 +83,7 @@ class ExceptionListenerModule extends Component[DiscordPlugin] with Listener {
private def pingRole(guild: SMono[Guild]) = DPUtils.roleData(getConfig, "pingRole", "Coder", guild) private def pingRole(guild: SMono[Guild]) = DPUtils.roleData(getConfig, "pingRole", "Coder", guild)
override protected def enable(): Unit = { override protected def enable(): Unit = {
if (DPUtils.disableIfConfigError(this, channel)) return if (DPUtils.disableIfConfigError(this, channel)) return ()
ExceptionListenerModule.instance = this ExceptionListenerModule.instance = this
Bukkit.getPluginManager.registerEvents(new ExceptionListenerModule, getPlugin) Bukkit.getPluginManager.registerEvents(new ExceptionListenerModule, getPlugin)
TBMCCoreAPI.RegisterEventsForExceptions(new DebugMessageListener, getPlugin) TBMCCoreAPI.RegisterEventsForExceptions(new DebugMessageListener, getPlugin)

View file

@ -9,7 +9,7 @@ import discord4j.core.`object`.entity.channel.{GuildChannel, MessageChannel}
import discord4j.core.`object`.entity.{Guild, Message} import discord4j.core.`object`.entity.{Guild, Message}
import discord4j.core.`object`.presence.Status import discord4j.core.`object`.presence.Status
import discord4j.core.event.domain.PresenceUpdateEvent 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.Bukkit
import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.event.player.PlayerJoinEvent
import org.bukkit.event.{EventHandler, Listener} import org.bukkit.event.{EventHandler, Listener}
@ -52,7 +52,7 @@ object FunModule {
ListC += 1 ListC += 1
ListC - 1 ListC - 1
} > 2) { // Lowered already } > 2) { // Lowered already
DPUtils.reply(message, SMono.empty, "stop it. You know the answer.").subscribe DPUtils.reply(message, SMono.empty, "stop it. You know the answer.").subscribe()
lastlist = 0 lastlist = 0
lastlistp = Bukkit.getOnlinePlayers.size.toShort lastlistp = Bukkit.getOnlinePlayers.size.toShort
return true //Handled return true //Handled
@ -62,7 +62,7 @@ object FunModule {
var next = 0 var next = 0
if (usableServerReadyStrings.size == 0) fm.createUsableServerReadyStrings() if (usableServerReadyStrings.size == 0) fm.createUsableServerReadyStrings()
next = usableServerReadyStrings.remove(serverReadyRandom.nextInt(usableServerReadyStrings.size)) next = usableServerReadyStrings.remove(serverReadyRandom.nextInt(usableServerReadyStrings.size))
DPUtils.reply(message, SMono.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 return false //Still process it as a command/mcchat if needed
} }
false false
@ -72,11 +72,11 @@ object FunModule {
def handleFullHouse(event: PresenceUpdateEvent): Unit = { def handleFullHouse(event: PresenceUpdateEvent): Unit = {
val fm = ComponentManager.getIfEnabled(classOf[FunModule]) val fm = ComponentManager.getIfEnabled(classOf[FunModule])
if (fm == null) return if (fm == null) return ()
if (Calendar.getInstance.get(Calendar.DAY_OF_MONTH) % 5 != 0) return if (Calendar.getInstance.get(Calendar.DAY_OF_MONTH) % 5 != 0) return ()
if (!Option(event.getOld.orElse(null)).exists(_.getStatus == Status.OFFLINE) if (!Option(event.getOld.orElse(null)).exists(_.getStatus == Status.OFFLINE)
|| event.getCurrent.getStatus == Status.OFFLINE) || event.getCurrent.getStatus == Status.OFFLINE)
return //If it's not an offline -> online change return () //If it's not an offline -> online change
fm.fullHouseChannel.get.filter((ch: MessageChannel) => ch.isInstanceOf[GuildChannel]) fm.fullHouseChannel.get.filter((ch: MessageChannel) => ch.isInstanceOf[GuildChannel])
.flatMap(channel => fm.fullHouseDevRole(SMono(channel.asInstanceOf[GuildChannel].getGuild)).get .flatMap(channel => fm.fullHouseDevRole(SMono(channel.asInstanceOf[GuildChannel].getGuild)).get
.filterWhen(devrole => SMono(event.getMember) .filterWhen(devrole => SMono(event.getMember)
@ -88,8 +88,8 @@ object FunModule {
.flatMap(_ => { .flatMap(_ => {
lasttime = TimeUnit.NANOSECONDS.toHours(System.nanoTime) lasttime = TimeUnit.NANOSECONDS.toHours(System.nanoTime)
SMono(channel.createMessage(_.setContent("Full house!") SMono(channel.createMessage(_.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")))) .setEmbed((ecs: LegacyEmbedCreateSpec) => ecs.setImage("https://cdn.discordapp.com/attachments/249295547263877121/249687682618359808/poker-hand-full-house-aces-kings-playing-cards-15553791.png"))))
})).subscribe })).subscribe()
} }
} }

View file

@ -56,7 +56,7 @@ object CommonListeners {
} }
foo(event) foo(event)
}).onErrorContinue((err: Throwable, _) => 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) => { dispatcher.on(classOf[PresenceUpdateEvent]).subscribe((event: PresenceUpdateEvent) => {
if (!DiscordPlugin.SafeMode) if (!DiscordPlugin.SafeMode)
FunModule.handleFullHouse(event) FunModule.handleFullHouse(event)

View file

@ -10,35 +10,32 @@ import discord4j.common.util.Snowflake
import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.event.player.PlayerJoinEvent
import org.bukkit.event.{EventHandler, Listener} import org.bukkit.event.{EventHandler, Listener}
import reactor.core.publisher.Mono import reactor.core.publisher.Mono
import reactor.core.scala.publisher.javaOptional2ScalaOption
class MCListener extends Listener { class MCListener extends Listener {
@EventHandler def onPlayerJoin(e: PlayerJoinEvent): Unit = @EventHandler def onPlayerJoin(e: PlayerJoinEvent): Unit =
if (ConnectCommand.WaitingToConnect.containsKey(e.getPlayer.getName)) { if (ConnectCommand.WaitingToConnect.containsKey(e.getPlayer.getName)) {
@SuppressWarnings(Array("ConstantConditions")) val user = DiscordPlugin.dc.getUserById(Snowflake.of(ConnectCommand.WaitingToConnect.get(e.getPlayer.getName))).block @SuppressWarnings(Array("ConstantConditions")) val user = DiscordPlugin.dc.getUserById(Snowflake.of(ConnectCommand.WaitingToConnect.get(e.getPlayer.getName))).block
if (user == null) return if (user == null) return ()
e.getPlayer.sendMessage("§bTo connect with the Discord account @" + user.getUsername + "#" + user.getDiscriminator + " do /discord accept") e.getPlayer.sendMessage("§bTo connect with the Discord account @" + user.getUsername + "#" + user.getDiscriminator + " do /discord accept")
e.getPlayer.sendMessage("§bIf it wasn't you, do /discord decline") e.getPlayer.sendMessage("§bIf it wasn't you, do /discord decline")
} }
@EventHandler def onGetInfo(e: TBMCPlayerGetInfoEvent): Unit = { @EventHandler def onGetInfo(e: TBMCPlayerGetInfoEvent): Unit = {
if (DiscordPlugin.SafeMode) return Option(DiscordPlugin.SafeMode).filterNot(identity).flatMap(_ => Option(e.getPlayer.getAs(classOf[DiscordPlayer])))
val dp = e.getPlayer.getAs(classOf[DiscordPlayer]) .flatMap(dp => Option(dp.getDiscordID)).filter(_.nonEmpty)
if (dp == null || dp.getDiscordID == null || dp.getDiscordID == "") return .map(Snowflake.of).flatMap(id => DiscordPlugin.dc.getUserById(id).onErrorResume(_ => Mono.empty).blockOptional())
val userOpt = DiscordPlugin.dc.getUserById(Snowflake.of(dp.getDiscordID)).onErrorResume(_ => Mono.empty).blockOptional .map(user => {
if (!userOpt.isPresent) return
val user = userOpt.get
e.addInfo("Discord tag: " + user.getUsername + "#" + user.getDiscriminator) e.addInfo("Discord tag: " + user.getUsername + "#" + user.getDiscriminator)
val memberOpt = user.asMember(DiscordPlugin.mainServer.getId).onErrorResume((t: Throwable) => Mono.empty).blockOptional user
if (!memberOpt.isPresent) return })
val member = memberOpt.get .flatMap(user => user.asMember(DiscordPlugin.mainServer.getId).onErrorResume(t => Mono.empty).blockOptional())
val prOpt = member.getPresence.blockOptional .flatMap(member => member.getPresence.blockOptional())
if (!prOpt.isPresent) return .map(pr => {
val pr = prOpt.get
e.addInfo(pr.getStatus.toString) e.addInfo(pr.getStatus.toString)
if (pr.getActivity.isPresent) { pr
val activity = pr.getActivity.get })
e.addInfo(s"${activity.getType}: ${activity.getName}") .flatMap(_.getActivity).foreach(activity => e.addInfo(s"${activity.getType}: ${activity.getName}"))
}
} }
/*@EventHandler /*@EventHandler

View file

@ -1,8 +1,8 @@
package buttondevteam.discordplugin.mcchat package buttondevteam.discordplugin.mcchat
import buttondevteam.core.component.channel.{Channel, ChatRoom} import buttondevteam.core.component.channel.{Channel, ChatRoom}
import buttondevteam.discordplugin.*
import buttondevteam.discordplugin.ChannelconBroadcast.ChannelconBroadcast import buttondevteam.discordplugin.ChannelconBroadcast.ChannelconBroadcast
import buttondevteam.discordplugin._
import buttondevteam.discordplugin.commands.{Command2DCSender, ICommand2DC} import buttondevteam.discordplugin.commands.{Command2DCSender, ICommand2DC}
import buttondevteam.lib.TBMCSystemChatEvent import buttondevteam.lib.TBMCSystemChatEvent
import buttondevteam.lib.chat.{Command2, CommandClass} import buttondevteam.lib.chat.{Command2, CommandClass}
@ -36,9 +36,9 @@ class ChannelconCommand(private val module: MinecraftChatModule) extends IComman
val message = sender.getMessage val message = sender.getMessage
if (checkPerms(message, null)) return true if (checkPerms(message, null)) return true
else if (MCChatCustom.removeCustomChat(message.getChannelId)) else if (MCChatCustom.removeCustomChat(message.getChannelId))
DPUtils.reply(message, SMono.empty, "channel connection removed.").subscribe DPUtils.reply(message, SMono.empty, "channel connection removed.").subscribe()
else else
DPUtils.reply(message, SMono.empty, "this channel isn't connected.").subscribe DPUtils.reply(message, SMono.empty, "this channel isn't connected.").subscribe()
true true
} }
@ -58,7 +58,7 @@ class ChannelconCommand(private val module: MinecraftChatModule) extends IComman
target.getName + ": " + (if (cc.brtoggles.contains(target)) "enabled" else "disabled")) target.getName + ": " + (if (cc.brtoggles.contains(target)) "enabled" else "disabled"))
.collect(Collectors.joining("\n")) .collect(Collectors.joining("\n"))
if (toggle == null) { if (toggle == null) {
DPUtils.reply(message, SMono.empty, "toggles:\n" + togglesString.get).subscribe DPUtils.reply(message, SMono.empty, "toggles:\n" + togglesString.get).subscribe()
return true return true
} }
val arg: String = toggle.toUpperCase val arg: String = toggle.toUpperCase
@ -66,7 +66,7 @@ class ChannelconCommand(private val module: MinecraftChatModule) extends IComman
if (b.isEmpty) { if (b.isEmpty) {
val bt: TBMCSystemChatEvent.BroadcastTarget = TBMCSystemChatEvent.BroadcastTarget.get(arg) val bt: TBMCSystemChatEvent.BroadcastTarget = TBMCSystemChatEvent.BroadcastTarget.get(arg)
if (bt == null) { if (bt == null) {
DPUtils.reply(message, SMono.empty, "cannot find toggle. Toggles:\n" + togglesString.get).subscribe DPUtils.reply(message, SMono.empty, "cannot find toggle. Toggles:\n" + togglesString.get).subscribe()
return true return true
} }
val add: Boolean = !(cc.brtoggles.contains(bt)) val add: Boolean = !(cc.brtoggles.contains(bt))
@ -87,7 +87,7 @@ class ChannelconCommand(private val module: MinecraftChatModule) extends IComman
// XOR // XOR
cc.toggles ^= (1 << b.get.id) cc.toggles ^= (1 << b.get.id)
DPUtils.reply(message, SMono.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 + (if ((cc.toggles & (1 << b.get.id)) == 0) "disabled" else "enabled")).subscribe()
true true
} }
@ -106,7 +106,7 @@ class ChannelconCommand(private val module: MinecraftChatModule) extends IComman
} }
val chan: Optional[Channel] = Channel.getChannels.filter((ch: Channel) => ch.ID.equalsIgnoreCase(channelID) || (util.Arrays.stream(ch.IDs.get).anyMatch((cid: String) => cid.equalsIgnoreCase(channelID)))).findAny val chan: Optional[Channel] = Channel.getChannels.filter((ch: Channel) => ch.ID.equalsIgnoreCase(channelID) || (util.Arrays.stream(ch.IDs.get).anyMatch((cid: String) => cid.equalsIgnoreCase(channelID)))).findAny
if (!(chan.isPresent)) { //TODO: Red embed that disappears over time (kinda like the highlight messages in OW) if (!(chan.isPresent)) { //TODO: Red embed that disappears over time (kinda like the highlight messages in OW)
DPUtils.reply(message, channel, "MC channel with ID '" + channelID + "' not found! The ID is the command for it without the /.").subscribe DPUtils.reply(message, channel, "MC channel with ID '" + channelID + "' not found! The ID is the command for it without the /.").subscribe()
return true return true
} }
if (!(message.getAuthor.isPresent)) { if (!(message.getAuthor.isPresent)) {
@ -116,18 +116,18 @@ class ChannelconCommand(private val module: MinecraftChatModule) extends IComman
val dp: DiscordPlayer = ChromaGamerBase.getUser(author.getId.asString, classOf[DiscordPlayer]) val dp: DiscordPlayer = ChromaGamerBase.getUser(author.getId.asString, classOf[DiscordPlayer])
val chp: TBMCPlayer = dp.getAs(classOf[TBMCPlayer]) val chp: TBMCPlayer = dp.getAs(classOf[TBMCPlayer])
if (chp == null) { if (chp == null) {
DPUtils.reply(message, channel, "you need to connect your Minecraft account. On the main server in " + DPUtils.botmention + " do " + DiscordPlugin.getPrefix + "connect <MCname>").subscribe DPUtils.reply(message, channel, "you need to connect your Minecraft account. On the main server in " + DPUtils.botmention + " do " + DiscordPlugin.getPrefix + "connect <MCname>").subscribe()
return true return true
} }
val dcp: DiscordConnectedPlayer = DiscordConnectedPlayer.create(message.getAuthor.get, channel, chp.getUUID, Bukkit.getOfflinePlayer(chp.getUUID).getName, module) val dcp: DiscordConnectedPlayer = DiscordConnectedPlayer.create(message.getAuthor.get, channel, chp.getUUID, Bukkit.getOfflinePlayer(chp.getUUID).getName, module)
//Using a fake player with no login/logout, should be fine for this event //Using a fake player with no login/logout, should be fine for this event
val groupid: String = chan.get.getGroupID(dcp) val groupid: String = chan.get.getGroupID(dcp)
if (groupid == null && !((chan.get.isInstanceOf[ChatRoom]))) { //ChatRooms don't allow it unless the user joins, which happens later if (groupid == null && !((chan.get.isInstanceOf[ChatRoom]))) { //ChatRooms don't allow it unless the user joins, which happens later
DPUtils.reply(message, channel, "sorry, you cannot use that Minecraft channel.").subscribe DPUtils.reply(message, channel, "sorry, you cannot use that Minecraft channel.").subscribe()
return true return true
} }
if (chan.get.isInstanceOf[ChatRoom]) { //ChatRooms don't work well if (chan.get.isInstanceOf[ChatRoom]) { //ChatRooms don't work well
DPUtils.reply(message, channel, "chat rooms are not supported yet.").subscribe DPUtils.reply(message, channel, "chat rooms are not supported yet.").subscribe()
return true return true
} }
/*if (MCChatListener.getCustomChats().stream().anyMatch(cc -> cc.groupID.equals(groupid) && cc.mcchannel.ID.equals(chan.get().ID))) { /*if (MCChatListener.getCustomChats().stream().anyMatch(cc -> cc.groupID.equals(groupid) && cc.mcchannel.ID.equals(chan.get().ID))) {
@ -137,10 +137,10 @@ class ChannelconCommand(private val module: MinecraftChatModule) extends IComman
//TODO: "Channel admins" that can connect channels? //TODO: "Channel admins" that can connect channels?
MCChatCustom.addCustomChat(channel, groupid, chan.get, author, dcp, 0, Set()) MCChatCustom.addCustomChat(channel, groupid, chan.get, author, dcp, 0, Set())
if (chan.get.isInstanceOf[ChatRoom]) { if (chan.get.isInstanceOf[ChatRoom]) {
DPUtils.reply(message, channel, "alright, connection made to the room!").subscribe DPUtils.reply(message, channel, "alright, connection made to the room!").subscribe()
} }
else { else {
DPUtils.reply(message, channel, "alright, connection made to group `" + groupid + "`!").subscribe DPUtils.reply(message, channel, "alright, connection made to group `" + groupid + "`!").subscribe()
} }
true true
} }
@ -151,13 +151,13 @@ class ChannelconCommand(private val module: MinecraftChatModule) extends IComman
return checkPerms(message, message.getChannel.block) return checkPerms(message, message.getChannel.block)
} }
if (!((channel.isInstanceOf[GuildChannel]))) { if (!((channel.isInstanceOf[GuildChannel]))) {
DPUtils.reply(message, channel, "you can only use this command in a server!").subscribe DPUtils.reply(message, channel, "you can only use this command in a server!").subscribe()
return true return true
} }
//noinspection OptionalGetWithoutIsPresent //noinspection OptionalGetWithoutIsPresent
val perms: PermissionSet = (channel.asInstanceOf[GuildChannel]).getEffectivePermissions(message.getAuthor.map(_.getId).get).block val perms: PermissionSet = (channel.asInstanceOf[GuildChannel]).getEffectivePermissions(message.getAuthor.map(_.getId).get).block
if (!(perms.contains(Permission.ADMINISTRATOR)) && !(perms.contains(Permission.MANAGE_CHANNELS))) { if (!(perms.contains(Permission.ADMINISTRATOR)) && !(perms.contains(Permission.MANAGE_CHANNELS))) {
DPUtils.reply(message, channel, "you need to have manage permissions for this channel!").subscribe DPUtils.reply(message, channel, "you need to have manage permissions for this channel!").subscribe()
return true return true
} }
false false

View file

@ -22,7 +22,7 @@ class MCChatCommand(private val module: MinecraftChatModule) extends ICommand2DC
val channel = message.getChannel.block val channel = message.getChannel.block
@SuppressWarnings(Array("OptionalGetWithoutIsPresent")) val author = message.getAuthor.get @SuppressWarnings(Array("OptionalGetWithoutIsPresent")) val author = message.getAuthor.get
if (!((channel.isInstanceOf[PrivateChannel]))) { if (!((channel.isInstanceOf[PrivateChannel]))) {
DPUtils.reply(message, channel, "this command can only be issued in a direct message with the bot.").subscribe DPUtils.reply(message, channel, "this command can only be issued in a direct message with the bot.").subscribe()
return true return true
} }
val user: DiscordPlayer = ChromaGamerBase.getUser(author.getId.asString, classOf[DiscordPlayer]) val user: DiscordPlayer = ChromaGamerBase.getUser(author.getId.asString, classOf[DiscordPlayer])
@ -30,7 +30,7 @@ class MCChatCommand(private val module: MinecraftChatModule) extends ICommand2DC
MCChatPrivate.privateMCChat(channel, mcchat, author, user) MCChatPrivate.privateMCChat(channel, mcchat, author, user)
DPUtils.reply(message, channel, "Minecraft chat " + DPUtils.reply(message, channel, "Minecraft chat " +
(if (mcchat) "enabled. Use '" + DiscordPlugin.getPrefix + "mcchat' again to turn it off." (if (mcchat) "enabled. Use '" + DiscordPlugin.getPrefix + "mcchat' again to turn it off."
else "disabled.")).subscribe else "disabled.")).subscribe()
true true
// TODO: Pin channel switching to indicate the current channel // TODO: Pin channel switching to indicate the current channel
} }

View file

@ -2,6 +2,7 @@ package buttondevteam.discordplugin.mcchat
import buttondevteam.core.ComponentManager import buttondevteam.core.ComponentManager
import buttondevteam.discordplugin.* import buttondevteam.discordplugin.*
import buttondevteam.discordplugin.DPUtils.SpecExtensions
import buttondevteam.discordplugin.listeners.CommandListener import buttondevteam.discordplugin.listeners.CommandListener
import buttondevteam.discordplugin.playerfaker.{VanillaCommandListener, VanillaCommandListener14, VanillaCommandListener15} import buttondevteam.discordplugin.playerfaker.{VanillaCommandListener, VanillaCommandListener14, VanillaCommandListener15}
import buttondevteam.lib.* import buttondevteam.lib.*
@ -12,7 +13,7 @@ import discord4j.common.util.Snowflake
import discord4j.core.`object`.entity.channel.{MessageChannel, PrivateChannel} import discord4j.core.`object`.entity.channel.{MessageChannel, PrivateChannel}
import discord4j.core.`object`.entity.{Member, Message, User} import discord4j.core.`object`.entity.{Member, Message, User}
import discord4j.core.event.domain.message.MessageCreateEvent import discord4j.core.event.domain.message.MessageCreateEvent
import discord4j.core.spec.{EmbedCreateSpec, MessageEditSpec} import discord4j.core.spec.legacy.{LegacyEmbedCreateSpec, LegacyMessageEditSpec}
import discord4j.rest.util.Color import discord4j.rest.util.Color
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.entity.Player import org.bukkit.entity.Player
@ -26,7 +27,7 @@ import java.util
import java.util.concurrent.{LinkedBlockingQueue, TimeoutException} import java.util.concurrent.{LinkedBlockingQueue, TimeoutException}
import java.util.function.{Consumer, Predicate} import java.util.function.{Consumer, Predicate}
import java.util.stream.Collectors import java.util.stream.Collectors
import scala.jdk.CollectionConverters.SetHasAsScala import scala.jdk.CollectionConverters.{ListHasAsScala, SetHasAsScala}
import scala.jdk.OptionConverters.RichOptional import scala.jdk.OptionConverters.RichOptional
object MCChatListener { object MCChatListener {
@ -58,12 +59,12 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
@EventHandler // Minecraft @EventHandler // Minecraft
def onMCChat(ev: TBMCChatEvent): Unit = { def onMCChat(ev: TBMCChatEvent): Unit = {
if (!(ComponentManager.isEnabled(classOf[MinecraftChatModule])) || ev.isCancelled) { //SafeMode: Needed so it doesn't restart after server shutdown if (!(ComponentManager.isEnabled(classOf[MinecraftChatModule])) || ev.isCancelled) { //SafeMode: Needed so it doesn't restart after server shutdown
return return ()
} }
sendevents.add(new util.AbstractMap.SimpleEntry[TBMCChatEvent, Instant](ev, Instant.now)) sendevents.add(new util.AbstractMap.SimpleEntry[TBMCChatEvent, Instant](ev, Instant.now))
if (sendtask != null) { if (sendtask != null) {
return return ()
} }
sendrunnable = () => { sendrunnable = () => {
def foo(): Unit = { def foo(): Unit = {
@ -90,8 +91,8 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
(if ("Minecraft" == e.getOrigin) "" else "[" + e.getOrigin.charAt(0) + "]") + (if ("Minecraft" == e.getOrigin) "" else "[" + e.getOrigin.charAt(0) + "]") +
DPUtils.sanitizeStringNoEscape(ChromaUtils.getDisplayName(e.getSender)) DPUtils.sanitizeStringNoEscape(ChromaUtils.getDisplayName(e.getSender))
val color: chat.Color = e.getChannel.Color.get val color: chat.Color = e.getChannel.Color.get
val embed: Consumer[EmbedCreateSpec] = (ecs: EmbedCreateSpec) => { val embed: Consumer[LegacyEmbedCreateSpec] = (ecs: LegacyEmbedCreateSpec) => {
def foo(ecs: EmbedCreateSpec) = { def foo(ecs: LegacyEmbedCreateSpec) = {
ecs.setDescription(e.getMessage).setColor(Color.of(color.getRed, color.getGreen, color.getBlue)) ecs.setDescription(e.getMessage).setColor(Color.of(color.getRed, color.getGreen, color.getBlue))
val url: String = module.profileURL.get val url: String = module.profileURL.get
e.getSender match { e.getSender match {
@ -113,7 +114,7 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
val nanoTime: Long = System.nanoTime val nanoTime: Long = System.nanoTime
val doit = (lastmsgdata: MCChatUtils.LastMsgData) => { val doit = (lastmsgdata: MCChatUtils.LastMsgData) => {
if (lastmsgdata.message == null if (lastmsgdata.message == null
|| authorPlayer != lastmsgdata.message.getEmbeds.get(0).getAuthor.toScala.map(_.getName).orNull || authorPlayer != lastmsgdata.message.getEmbeds.get(0).getAuthor.toScala.flatMap(_.getName.toScala).orNull
|| lastmsgdata.time / 1000000000f < nanoTime / 1000000000f - 120 || lastmsgdata.time / 1000000000f < nanoTime / 1000000000f - 120
|| !(lastmsgdata.mcchannel.ID == e.getChannel.ID) || !(lastmsgdata.mcchannel.ID == e.getChannel.ID)
|| lastmsgdata.content.length + e.getMessage.length + 1 > 2048) { || lastmsgdata.content.length + e.getMessage.length + 1 > 2048) {
@ -124,7 +125,7 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
} }
else { else {
lastmsgdata.content = lastmsgdata.content + "\n" + e.getMessage // The message object doesn't get updated 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 lastmsgdata.message.edit((mes: LegacyMessageEditSpec) => mes.setEmbed(embed.andThen((ecs: LegacyEmbedCreateSpec) => ecs.setDescription(lastmsgdata.content))).^^()).block
} }
} }
// Checks if the given channel is different than where the message was sent from // Checks if the given channel is different than where the message was sent from
@ -151,7 +152,7 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
true true
} }
else { else {
lmd.channel.createMessage("The user no longer has permission to view the channel, connection removed.").subscribe lmd.channel.createMessage("The user no longer has permission to view the channel, connection removed.").subscribe()
false //If the user no longer has permission, remove the connection false //If the user no longer has permission, remove the connection
} }
} }
@ -175,7 +176,7 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
}) { }) {
val mid: Int = event.getMessage.indexOf('#', start + 1) val mid: Int = event.getMessage.indexOf('#', start + 1)
if (mid == -1) { if (mid == -1) {
return return ()
} }
var end_ = event.getMessage.indexOf(' ', mid + 1) var end_ = event.getMessage.indexOf(' ', mid + 1)
if (end_ == -1) { if (end_ == -1) {
@ -290,7 +291,7 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
catch { catch {
case _: InterruptedException => case _: InterruptedException =>
rectask.cancel() rectask.cancel()
return return ()
} }
val sender: User = event.getMessage.getAuthor.orElse(null) val sender: User = event.getMessage.getAuthor.orElse(null)
var dmessage: String = event.getMessage.getContent var dmessage: String = event.getMessage.getContent
@ -299,7 +300,7 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
val user: DiscordPlayer = dsender.getChromaUser val user: DiscordPlayer = dsender.getChromaUser
def replaceUserMentions(): Unit = { def replaceUserMentions(): Unit = {
for (u <- SFlux(event.getMessage.getUserMentions).toIterable()) { //TODO: Role mentions for (u <- event.getMessage.getUserMentions.asScala) { //TODO: Role mentions
dmessage = dmessage.replace(u.getMention, "@" + u.getUsername) // TODO: IG Formatting dmessage = dmessage.replace(u.getMention, "@" + u.getUsername) // TODO: IG Formatting
val m = u.asMember(DiscordPlugin.mainServer.getId).onErrorResume(_ => Mono.empty).blockOptional val m = u.asMember(DiscordPlugin.mainServer.getId).onErrorResume(_ => Mono.empty).blockOptional
if (m.isPresent) { if (m.isPresent) {
@ -341,7 +342,7 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
TBMCCoreAPI.SendException("An error occured while removing reactions from chat!", e, module) TBMCCoreAPI.SendException("An error occured while removing reactions from chat!", e, module)
} }
MCChatUtils.lastmsgfromd.put(event.getMessage.getChannelId.asLong, event.getMessage) MCChatUtils.lastmsgfromd.put(event.getMessage.getChannelId.asLong, event.getMessage)
event.getMessage.addReaction(DiscordPlugin.DELIVERED_REACTION).subscribe event.getMessage.addReaction(DiscordPlugin.DELIVERED_REACTION).subscribe()
} }
if (dmessage.startsWith("/")) // Ingame command if (dmessage.startsWith("/")) // Ingame command
@ -412,7 +413,7 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
.map("/" + _).collect(Collectors.joining(", ")) .map("/" + _).collect(Collectors.joining(", "))
if (!isPrivate) if (!isPrivate)
event.getMessage.delete.subscribe event.getMessage.delete.subscribe()
val cmd = dmessage.substring(1) val cmd = dmessage.substring(1)
val cmdlowercased = cmd.toLowerCase val cmdlowercased = cmd.toLowerCase
if (dsender.isInstanceOf[DiscordSender] && notWhitelisted(cmdlowercased)) { // Command not whitelisted if (dsender.isInstanceOf[DiscordSender] && notWhitelisted(cmdlowercased)) { // Command not whitelisted
@ -420,11 +421,11 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
(if (user.getConnectedID(classOf[TBMCPlayer]) == null) (if (user.getConnectedID(classOf[TBMCPlayer]) == null)
"\nTo access your commands, first please connect your accounts, using /connect in " + DPUtils.botmention "\nTo access your commands, first please connect your accounts, using /connect in " + DPUtils.botmention
+ "\nThen y" else "\nY") + "ou can access all of your regular commands (even offline) in private chat: DM me `mcchat`!") + "\nThen y" else "\nY") + "ou can access all of your regular commands (even offline) in private chat: DM me `mcchat`!")
return return ()
} }
module.log(dsender.getName + " ran from DC: /" + cmd) module.log(dsender.getName + " ran from DC: /" + cmd)
if (dsender.isInstanceOf[DiscordSender] && runCustomCommand(dsender, cmdlowercased)) { if (dsender.isInstanceOf[DiscordSender] && runCustomCommand(dsender, cmdlowercased)) {
return return ()
} }
val channel = if (clmd == null) user.channel.get else clmd.mcchannel val channel = if (clmd == null) user.channel.get else clmd.mcchannel
val ev = new TBMCCommandPreprocessEvent(dsender, channel, dmessage, if (clmd == null) dsender else clmd.dcp) val ev = new TBMCCommandPreprocessEvent(dsender, channel, dmessage, if (clmd == null) dsender else clmd.dcp)

View file

@ -3,6 +3,7 @@ package buttondevteam.discordplugin.mcchat
import buttondevteam.core.{ComponentManager, MainPlugin, component} import buttondevteam.core.{ComponentManager, MainPlugin, component}
import buttondevteam.discordplugin.* import buttondevteam.discordplugin.*
import buttondevteam.discordplugin.ChannelconBroadcast.ChannelconBroadcast import buttondevteam.discordplugin.ChannelconBroadcast.ChannelconBroadcast
import buttondevteam.discordplugin.DPUtils.SpecExtensions
import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule
import buttondevteam.discordplugin.mcchat.MCChatCustom.CustomLMD import buttondevteam.discordplugin.mcchat.MCChatCustom.CustomLMD
import buttondevteam.lib.{TBMCCoreAPI, TBMCSystemChatEvent} import buttondevteam.lib.{TBMCCoreAPI, TBMCSystemChatEvent}
@ -10,7 +11,7 @@ import com.google.common.collect.Sets
import discord4j.common.util.Snowflake import discord4j.common.util.Snowflake
import discord4j.core.`object`.entity.channel.{Channel, MessageChannel, PrivateChannel, TextChannel} import discord4j.core.`object`.entity.channel.{Channel, MessageChannel, PrivateChannel, TextChannel}
import discord4j.core.`object`.entity.{Message, User} import discord4j.core.`object`.entity.{Message, User}
import discord4j.core.spec.TextChannelEditSpec import discord4j.core.spec.legacy.LegacyTextChannelEditSpec
import io.netty.util.collection.LongObjectHashMap import io.netty.util.collection.LongObjectHashMap
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
@ -18,6 +19,7 @@ import org.bukkit.entity.Player
import org.bukkit.event.Event import org.bukkit.event.Event
import org.bukkit.event.player.{AsyncPlayerPreLoginEvent, PlayerJoinEvent, PlayerLoginEvent, PlayerQuitEvent} import org.bukkit.event.player.{AsyncPlayerPreLoginEvent, PlayerJoinEvent, PlayerLoginEvent, PlayerQuitEvent}
import org.bukkit.plugin.AuthorNagException import org.bukkit.plugin.AuthorNagException
import reactor.core.publisher.{Flux as JFlux, Mono as JMono}
import reactor.core.scala.publisher.SMono import reactor.core.scala.publisher.SMono
import java.net.InetAddress import java.net.InetAddress
@ -31,7 +33,7 @@ import javax.annotation.Nullable
import scala.collection.concurrent import scala.collection.concurrent
import scala.collection.convert.ImplicitConversions.`map AsJavaMap` import scala.collection.convert.ImplicitConversions.`map AsJavaMap`
import scala.collection.mutable.ListBuffer import scala.collection.mutable.ListBuffer
import scala.jdk.CollectionConverters.CollectionHasAsScala import scala.jdk.CollectionConverters.{CollectionHasAsScala, SeqHasAsJava}
import scala.jdk.javaapi.CollectionConverters.asScala import scala.jdk.javaapi.CollectionConverters.asScala
object MCChatUtils { object MCChatUtils {
@ -65,12 +67,12 @@ object MCChatUtils {
private def updatePL(lmd: MCChatUtils.LastMsgData): Unit = { private def updatePL(lmd: MCChatUtils.LastMsgData): Unit = {
if (!lmd.channel.isInstanceOf[TextChannel]) { if (!lmd.channel.isInstanceOf[TextChannel]) {
TBMCCoreAPI.SendException("Failed to update player list for channel " + lmd.channel.getId, new Exception("The channel isn't a (guild) text channel."), getModule) TBMCCoreAPI.SendException("Failed to update player list for channel " + lmd.channel.getId, new Exception("The channel isn't a (guild) text channel."), getModule)
return return ()
} }
var topic = lmd.channel.asInstanceOf[TextChannel].getTopic.orElse("") var topic = lmd.channel.asInstanceOf[TextChannel].getTopic.orElse("")
if (topic.isEmpty) topic = ".\n----\nMinecraft chat\n----\n." if (topic.isEmpty) topic = ".\n----\nMinecraft chat\n----\n."
val s = topic.split("\\n----\\n") val s = topic.split("\\n----\\n")
if (s.length < 3) return if (s.length < 3) return ()
var gid: String = null var gid: String = null
lmd match { lmd match {
case clmd: CustomLMD => gid = clmd.groupID case clmd: CustomLMD => gid = clmd.groupID
@ -88,8 +90,8 @@ object MCChatUtils {
.filter(_ => C.incrementAndGet > 0) //Always true .filter(_ => C.incrementAndGet > 0) //Always true
.map((p) => DPUtils.sanitizeString(p.getDisplayName)).collect(Collectors.joining(", ")) .map((p) => DPUtils.sanitizeString(p.getDisplayName)).collect(Collectors.joining(", "))
s(0) = s"$C player${if (C.get != 1) "s" else ""} online" s(0) = s"$C player${if (C.get != 1) "s" else ""} online"
lmd.channel.asInstanceOf[TextChannel].edit((tce: TextChannelEditSpec) => lmd.channel.asInstanceOf[TextChannel].edit((tce: LegacyTextChannelEditSpec) =>
tce.setTopic(String.join("\n----\n", s: _*)).setReason("Player list update")).subscribe //Don't wait tce.setTopic(String.join("\n----\n", s: _*)).setReason("Player list update").^^()).subscribe //Don't wait
} }
private[mcchat] def checkEssentials(p: Player): Boolean = { private[mcchat] def checkEssentials(p: Player): Boolean = {
@ -125,8 +127,7 @@ object MCChatUtils {
if (notEnabled) return SMono.empty if (notEnabled) return SMono.empty
val list = MCChatPrivate.lastmsgPerUser.map(data => action(SMono.just(data.channel))) val list = MCChatPrivate.lastmsgPerUser.map(data => action(SMono.just(data.channel)))
.prepend(action(module.chatChannelMono)) .prepend(action(module.chatChannelMono))
// lastmsgCustom.forEach(cc -> action.accept(cc.channel)); - Only send relevant messages to custom chat SMono(JMono.whenDelayError(list.asJava))
SMono.whenDelayError(list)
} }
/** /**
@ -143,7 +144,7 @@ object MCChatUtils {
(if (toggle == null) MCChatCustom.lastmsgCustom (if (toggle == null) MCChatCustom.lastmsgCustom
else MCChatCustom.lastmsgCustom.filter(cc => (cc.toggles & (1 << toggle.id)) != 0)) else MCChatCustom.lastmsgCustom.filter(cc => (cc.toggles & (1 << toggle.id)) != 0))
.map(_.channel).map(SMono.just).map(action) .map(_.channel).map(SMono.just).map(action)
SMono.whenDelayError(list) SMono(JMono.whenDelayError(list.asJava))
} }
/** /**
@ -223,13 +224,13 @@ object MCChatUtils {
if (channel.getId.asLong == module.chatChannel.get.asLong) { 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 else lastmsgdata.message = null
return return ()
} // Don't set the whole object to null, the player and channel information should be preserved } // Don't set the whole object to null, the player and channel information should be preserved
for (data <- if (channel.isInstanceOf[PrivateChannel]) MCChatPrivate.lastmsgPerUser for (data <- if (channel.isInstanceOf[PrivateChannel]) MCChatPrivate.lastmsgPerUser
else MCChatCustom.lastmsgCustom) { else MCChatCustom.lastmsgCustom) {
if (data.channel.getId.asLong == channel.getId.asLong) { if (data.channel.getId.asLong == channel.getId.asLong) {
data.message = null data.message = null
return return ()
} }
} }
//If it gets here, it's sending a message to a non-chat channel //If it gets here, it's sending a message to a non-chat channel
@ -240,7 +241,7 @@ object MCChatUtils {
if (hs == null) Sets.newHashSet(plugin) else if (hs.add(plugin)) hs else hs) if (hs == null) Sets.newHashSet(plugin) else if (hs.add(plugin)) hs else hs)
def callEventExcludingSome(event: Event): Unit = { def callEventExcludingSome(event: Event): Unit = {
if (notEnabled) return if (notEnabled) return ()
val second = staticExcludedPlugins.get(event.getClass) val second = staticExcludedPlugins.get(event.getClass)
val first = module.excludedPlugins.get val first = module.excludedPlugins.get
val both = if (second.isEmpty) first val both = if (second.isEmpty) first
@ -305,7 +306,7 @@ object MCChatUtils {
callEventExcludingSome(event) callEventExcludingSome(event)
if (event.getLoginResult ne AsyncPlayerPreLoginEvent.Result.ALLOWED) { if (event.getLoginResult ne AsyncPlayerPreLoginEvent.Result.ALLOWED) {
loginFail(event.getKickMessage) loginFail(event.getKickMessage)
return return ()
} }
Bukkit.getScheduler.runTask(DiscordPlugin.plugin, () => { Bukkit.getScheduler.runTask(DiscordPlugin.plugin, () => {
def foo(): Unit = { def foo(): Unit = {
@ -313,7 +314,7 @@ object MCChatUtils {
callEventExcludingSome(ev) callEventExcludingSome(ev)
if (ev.getResult ne PlayerLoginEvent.Result.ALLOWED) { if (ev.getResult ne PlayerLoginEvent.Result.ALLOWED) {
loginFail(ev.getKickMessage) loginFail(ev.getKickMessage)
return return ()
} }
callEventExcludingSome(new PlayerJoinEvent(dcp, "")) callEventExcludingSome(new PlayerJoinEvent(dcp, ""))
dcp.setLoggedIn(true) dcp.setLoggedIn(true)
@ -334,7 +335,7 @@ object MCChatUtils {
* @param needsSync Whether we're in an async thread * @param needsSync Whether we're in an async thread
*/ */
def callLogoutEvent(dcp: DiscordConnectedPlayer, needsSync: Boolean): Unit = { def callLogoutEvent(dcp: DiscordConnectedPlayer, needsSync: Boolean): Unit = {
if (!dcp.isLoggedIn) return if (!dcp.isLoggedIn) return ()
val event = new PlayerQuitEvent(dcp, "") val event = new PlayerQuitEvent(dcp, "")
if (needsSync) callEventSync(event) if (needsSync) callEventSync(event)
else callEventExcludingSome(event) else callEventExcludingSome(event)

View file

@ -1,7 +1,7 @@
package buttondevteam.discordplugin.mcchat package buttondevteam.discordplugin.mcchat
import buttondevteam.discordplugin.*
import buttondevteam.discordplugin.DPUtils.{FluxExtensions, MonoExtensions} import buttondevteam.discordplugin.DPUtils.{FluxExtensions, MonoExtensions}
import buttondevteam.discordplugin._
import buttondevteam.lib.TBMCSystemChatEvent import buttondevteam.lib.TBMCSystemChatEvent
import buttondevteam.lib.player.{TBMCPlayer, TBMCPlayerBase, TBMCYEEHAWEvent} import buttondevteam.lib.player.{TBMCPlayer, TBMCPlayerBase, TBMCYEEHAWEvent}
import discord4j.common.util.Snowflake import discord4j.common.util.Snowflake
@ -11,8 +11,8 @@ import net.ess3.api.events.{AfkStatusChangeEvent, MuteStatusChangeEvent, NickCha
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.entity.PlayerDeathEvent import org.bukkit.event.entity.PlayerDeathEvent
import org.bukkit.event.player.*
import org.bukkit.event.player.PlayerLoginEvent.Result import org.bukkit.event.player.PlayerLoginEvent.Result
import org.bukkit.event.player._
import org.bukkit.event.server.{BroadcastMessageEvent, TabCompleteEvent} import org.bukkit.event.server.{BroadcastMessageEvent, TabCompleteEvent}
import org.bukkit.event.{EventHandler, EventPriority, Listener} import org.bukkit.event.{EventHandler, EventPriority, Listener}
import reactor.core.scala.publisher.{SFlux, SMono} import reactor.core.scala.publisher.{SFlux, SMono}
@ -21,8 +21,8 @@ class MCListener(val module: MinecraftChatModule) extends Listener {
final private val muteRole = DPUtils.roleData(module.getConfig, "muteRole", "Muted") final private val muteRole = DPUtils.roleData(module.getConfig, "muteRole", "Muted")
@EventHandler(priority = EventPriority.HIGHEST) def onPlayerLogin(e: PlayerLoginEvent): Unit = { @EventHandler(priority = EventPriority.HIGHEST) def onPlayerLogin(e: PlayerLoginEvent): Unit = {
if (e.getResult ne Result.ALLOWED) return if (e.getResult ne Result.ALLOWED) return ()
if (e.getPlayer.isInstanceOf[DiscordConnectedPlayer]) return if (e.getPlayer.isInstanceOf[DiscordConnectedPlayer]) return ()
val dcp = MCChatUtils.LoggedInPlayers.get(e.getPlayer.getUniqueId) val dcp = MCChatUtils.LoggedInPlayers.get(e.getPlayer.getUniqueId)
if (dcp.nonEmpty) MCChatUtils.callLogoutEvent(dcp.get, needsSync = false) if (dcp.nonEmpty) MCChatUtils.callLogoutEvent(dcp.get, needsSync = false)
} }
@ -39,7 +39,7 @@ class MCListener(val module: MinecraftChatModule) extends Listener {
MCChatUtils.addSender(MCChatUtils.OnlineSenders, dp.getDiscordID, DiscordPlayerSender.create(user, chan, p, module)) MCChatUtils.addSender(MCChatUtils.OnlineSenders, dp.getDiscordID, DiscordPlayerSender.create(user, chan, p, module))
MCChatUtils.addSender(MCChatUtils.OnlineSenders, dp.getDiscordID, DiscordPlayerSender.create(user, cc, p, module)) //Stored per-channel MCChatUtils.addSender(MCChatUtils.OnlineSenders, dp.getDiscordID, DiscordPlayerSender.create(user, cc, p, module)) //Stored per-channel
SMono.empty SMono.empty
}))).subscribe }))).subscribe()
val message = e.getJoinMessage val message = e.getJoinMessage
sendJoinLeaveMessage(message, e.getPlayer) sendJoinLeaveMessage(message, e.getPlayer)
ChromaBot.updatePlayerList() ChromaBot.updatePlayerList()
@ -51,7 +51,7 @@ class MCListener(val module: MinecraftChatModule) extends Listener {
private def sendJoinLeaveMessage(message: String, player: Player): Unit = private def sendJoinLeaveMessage(message: String, player: Player): Unit =
if (message != null && message.trim.nonEmpty) if (message != null && message.trim.nonEmpty)
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(message), player, ChannelconBroadcast.JOINLEAVE, hookmsg = true).subscribe MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(message), player, ChannelconBroadcast.JOINLEAVE, hookmsg = true).subscribe()
@EventHandler(priority = EventPriority.MONITOR) def onPlayerLeave(e: PlayerQuitEvent): Unit = { @EventHandler(priority = EventPriority.MONITOR) def onPlayerLeave(e: PlayerQuitEvent): Unit = {
if (e.getPlayer.isInstanceOf[DiscordConnectedPlayer]) return // Only care about real users if (e.getPlayer.isInstanceOf[DiscordConnectedPlayer]) return // Only care about real users
@ -69,23 +69,23 @@ class MCListener(val module: MinecraftChatModule) extends Listener {
} }
@EventHandler(priority = EventPriority.LOW) def onPlayerDeath(e: PlayerDeathEvent): Unit = @EventHandler(priority = EventPriority.LOW) def onPlayerDeath(e: PlayerDeathEvent): Unit =
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(e.getDeathMessage), e.getEntity, ChannelconBroadcast.DEATH, hookmsg = true).subscribe MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(e.getDeathMessage), e.getEntity, ChannelconBroadcast.DEATH, hookmsg = true).subscribe()
@EventHandler def onPlayerAFK(e: AfkStatusChangeEvent): Unit = { @EventHandler def onPlayerAFK(e: AfkStatusChangeEvent): Unit = {
val base = e.getAffected.getBase val base = e.getAffected.getBase
if (e.isCancelled || !base.isOnline) return if (e.isCancelled || !base.isOnline) return ()
val msg = base.getDisplayName + " is " + (if (e.getValue) "now" val msg = base.getDisplayName + " is " + (if (e.getValue) "now"
else "no longer") + " AFK." else "no longer") + " AFK."
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(msg), base, ChannelconBroadcast.AFK, hookmsg = false).subscribe MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(msg), base, ChannelconBroadcast.AFK, hookmsg = false).subscribe()
} }
@EventHandler def onPlayerMute(e: MuteStatusChangeEvent): Unit = { @EventHandler def onPlayerMute(e: MuteStatusChangeEvent): Unit = {
val role = muteRole.get val role = muteRole.get
if (role == null) return if (role == null) return ()
val source = e.getAffected.getSource val source = e.getAffected.getSource
if (!source.isPlayer) return if (!source.isPlayer) return ()
val p = TBMCPlayerBase.getPlayer(source.getPlayer.getUniqueId, classOf[TBMCPlayer]).getAs(classOf[DiscordPlayer]) val p = TBMCPlayerBase.getPlayer(source.getPlayer.getUniqueId, classOf[TBMCPlayer]).getAs(classOf[DiscordPlayer])
if (p == null) return if (p == null) return ()
DPUtils.ignoreError(SMono(DiscordPlugin.dc.getUserById(Snowflake.of(p.getDiscordID))) DPUtils.ignoreError(SMono(DiscordPlugin.dc.getUserById(Snowflake.of(p.getDiscordID)))
.flatMap(user => SMono(user.asMember(DiscordPlugin.mainServer.getId))) .flatMap(user => SMono(user.asMember(DiscordPlugin.mainServer.getId)))
.flatMap(user => role.flatMap((r: Role) => { .flatMap(user => role.flatMap((r: Role) => {
@ -101,14 +101,14 @@ class MCListener(val module: MinecraftChatModule) extends Listener {
} }
foo(r) foo(r)
}))).subscribe }))).subscribe()
} }
@EventHandler def onChatSystemMessage(event: TBMCSystemChatEvent): Unit = @EventHandler def onChatSystemMessage(event: TBMCSystemChatEvent): Unit =
MCChatUtils.forAllowedMCChat(MCChatUtils.send(event.getMessage), event).subscribe MCChatUtils.forAllowedMCChat(MCChatUtils.send(event.getMessage), event).subscribe()
@EventHandler def onBroadcastMessage(event: BroadcastMessageEvent): Unit = @EventHandler def onBroadcastMessage(event: BroadcastMessageEvent): Unit =
MCChatUtils.forCustomAndAllMCChat(MCChatUtils.send(event.getMessage), ChannelconBroadcast.BROADCAST, hookmsg = false).subscribe 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: Inherit from the chat event base to have channel support
val name = event.getSender match { val name = event.getSender match {
@ -119,7 +119,7 @@ class MCListener(val module: MinecraftChatModule) extends Listener {
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) .map(Option.apply).defaultIfEmpty(Option.empty)
.flatMap(yeehaw => MCChatUtils.forPublicPrivateChat(MCChatUtils.send(name + .flatMap(yeehaw => MCChatUtils.forPublicPrivateChat(MCChatUtils.send(name +
yeehaw.map(guildEmoji => " <:YEEHAW:" + guildEmoji.getId.asString + ">s").getOrElse(" YEEHAWs")))).subscribe yeehaw.map(guildEmoji => " <:YEEHAW:" + guildEmoji.getId.asString + ">s").getOrElse(" YEEHAWs")))).subscribe()
} }
@EventHandler def onNickChange(event: NickChangeEvent): Unit = MCChatUtils.updatePlayerList() @EventHandler def onNickChange(event: NickChangeEvent): Unit = MCChatUtils.updatePlayerList()
@ -127,7 +127,7 @@ class MCListener(val module: MinecraftChatModule) extends Listener {
@EventHandler def onTabComplete(event: TabCompleteEvent): Unit = { @EventHandler def onTabComplete(event: TabCompleteEvent): Unit = {
val i = event.getBuffer.lastIndexOf(' ') val i = event.getBuffer.lastIndexOf(' ')
val t = event.getBuffer.substring(i + 1) //0 if not found val t = event.getBuffer.substring(i + 1) //0 if not found
if (!t.startsWith("@")) return if (!t.startsWith("@")) return ()
val token = t.substring(1) val token = t.substring(1)
val x = DiscordPlugin.mainServer.getMembers.^^().flatMap(m => SFlux.just(m.getUsername, m.getNickname.orElse(""))) val x = DiscordPlugin.mainServer.getMembers.^^().flatMap(m => SFlux.just(m.getUsername, m.getNickname.orElse("")))
.filter(_.startsWith(token)).map("@" + _).doOnNext(event.getCompletions.add(_)).blockLast() .filter(_.startsWith(token)).map("@" + _).doOnNext(event.getCompletions.add(_)).blockLast()
@ -136,7 +136,7 @@ class MCListener(val module: MinecraftChatModule) extends Listener {
@EventHandler def onCommandSend(event: PlayerCommandSendEvent): Boolean = event.getCommands.add("g") @EventHandler def onCommandSend(event: PlayerCommandSendEvent): Boolean = event.getCommands.add("g")
@EventHandler def onVanish(event: VanishStatusChangeEvent): Unit = { @EventHandler def onVanish(event: VanishStatusChangeEvent): Unit = {
if (event.isCancelled) return if (event.isCancelled) return ()
Bukkit.getScheduler.runTask(DiscordPlugin.plugin, () => MCChatUtils.updatePlayerList()) Bukkit.getScheduler.runTask(DiscordPlugin.plugin, () => MCChatUtils.updatePlayerList())
} }
} }

View file

@ -220,7 +220,7 @@ class MinecraftChatModule extends Component[DiscordPlugin] {
*/ */
private def sendStateMessage(color: Color, message: String) = private def sendStateMessage(color: Color, message: String) =
MCChatUtils.forCustomAndAllMCChat(_.flatMap( MCChatUtils.forCustomAndAllMCChat(_.flatMap(
_.createEmbed(_.setColor(color).setTitle(message)).^^() _.createEmbed(_.setColor(color).setTitle(message).^^()).^^()
.onErrorResume(_ => SMono.empty) .onErrorResume(_ => SMono.empty)
), ChannelconBroadcast.RESTART, hookmsg = false).block() ), ChannelconBroadcast.RESTART, hookmsg = false).block()

View file

@ -60,7 +60,7 @@ import java.lang.reflect.Method
def foo(): Unit = { def foo(): Unit = {
if (!DiscordPlugin.plugin.tryReloadConfig) { if (!DiscordPlugin.plugin.tryReloadConfig) {
sender.sendMessage("§cFailed to reload config so not restarting. Check the console.") sender.sendMessage("§cFailed to reload config so not restarting. Check the console.")
return return ()
} }
MinecraftChatModule.state = DPState.RESTARTING_PLUGIN //Reset in MinecraftChatModule MinecraftChatModule.state = DPState.RESTARTING_PLUGIN //Reset in MinecraftChatModule
sender.sendMessage("§bDisabling DiscordPlugin...") sender.sendMessage("§bDisabling DiscordPlugin...")
@ -95,12 +95,12 @@ import java.lang.reflect.Method
"Shows an invite link to the server" "Shows an invite link to the server"
)) def invite(sender: CommandSender): Unit = { )) def invite(sender: CommandSender): Unit = {
if (checkSafeMode(sender)) { if (checkSafeMode(sender)) {
return return ()
} }
val invi: String = DiscordPlugin.plugin.inviteLink.get val invi: String = DiscordPlugin.plugin.inviteLink.get
if (invi.nonEmpty) { if (invi.nonEmpty) {
sender.sendMessage("§bInvite link: " + invi) sender.sendMessage("§bInvite link: " + invi)
return return ()
} }
DiscordPlugin.mainServer.getInvites.limitRequest(1) DiscordPlugin.mainServer.getInvites.limitRequest(1)
.switchIfEmpty(Mono.fromRunnable(() => sender.sendMessage("§cNo invites found for the server."))) .switchIfEmpty(Mono.fromRunnable(() => sender.sendMessage("§cNo invites found for the server.")))

View file

@ -21,7 +21,7 @@ import scala.jdk.CollectionConverters.SeqHasAsJava
@ComponentMetadata(enabledByDefault = false) object GameRoleModule { @ComponentMetadata(enabledByDefault = false) object GameRoleModule {
def handleRoleEvent(roleEvent: RoleEvent): Unit = { def handleRoleEvent(roleEvent: RoleEvent): Unit = {
val grm = ComponentManager.getIfEnabled(classOf[GameRoleModule]) val grm = ComponentManager.getIfEnabled(classOf[GameRoleModule])
if (grm == null) return if (grm == null) return ()
val GameRoles = grm.GameRoles val GameRoles = grm.GameRoles
val logChannel = grm.logChannel.get val logChannel = grm.logChannel.get
val notMainServer = (_: Role).getGuildId.asLong != DiscordPlugin.mainServer.getId.asLong val notMainServer = (_: Role).getGuildId.asLong != DiscordPlugin.mainServer.getId.asLong
@ -39,23 +39,23 @@ import scala.jdk.CollectionConverters.SeqHasAsJava
else else
SMono.empty SMono.empty
} }
}).subscribe }).subscribe()
() ()
} }
}, 100) }, 100)
case roleDeleteEvent: RoleDeleteEvent => case roleDeleteEvent: RoleDeleteEvent =>
val role = roleDeleteEvent.getRole.orElse(null) val role = roleDeleteEvent.getRole.orElse(null)
if (role == null) return if (role == null) return ()
if (notMainServer(role)) return if (notMainServer(role)) return ()
if (GameRoles.remove(role.getName) && logChannel != null) if (GameRoles.remove(role.getName) && logChannel != null)
logChannel.flatMap(_.createMessage("Removed " + role.getName + " as a game role.").^^()).subscribe logChannel.flatMap(_.createMessage("Removed " + role.getName + " as a game role.").^^()).subscribe()
case roleUpdateEvent: RoleUpdateEvent => case roleUpdateEvent: RoleUpdateEvent =>
if (!roleUpdateEvent.getOld.isPresent) { if (!roleUpdateEvent.getOld.isPresent) {
grm.logWarn("Old role not stored, cannot update game role!") grm.logWarn("Old role not stored, cannot update game role!")
return return ()
} }
val or = roleUpdateEvent.getOld.get val or = roleUpdateEvent.getOld.get
if (notMainServer(or)) return if (notMainServer(or)) return ()
val cr = roleUpdateEvent.getCurrent val cr = roleUpdateEvent.getCurrent
grm.isGameRole(cr).flatMap(isGameRole => { grm.isGameRole(cr).flatMap(isGameRole => {
if (!isGameRole) if (!isGameRole)
@ -76,7 +76,7 @@ import scala.jdk.CollectionConverters.SeqHasAsJava
else else
SMono.empty SMono.empty
} }
}).subscribe }).subscribe()
case _ => case _ =>
} }
} }

View file

@ -14,7 +14,7 @@ import reactor.core.publisher.Mono
)) def add(sender: Command2DCSender, @Command2.TextArg rolename: String): Boolean = { )) def add(sender: Command2DCSender, @Command2.TextArg rolename: String): Boolean = {
val role = checkAndGetRole(sender, rolename) val role = checkAndGetRole(sender, rolename)
if (role == null) return true if (role == null) return true
try sender.getMessage.getAuthorAsMember.flatMap(m => m.addRole(role.getId).switchIfEmpty(Mono.fromRunnable(() => sender.sendMessage("added role.")))).subscribe try sender.getMessage.getAuthorAsMember.flatMap(m => m.addRole(role.getId).switchIfEmpty(Mono.fromRunnable(() => sender.sendMessage("added role.")))).subscribe()
catch { catch {
case e: Exception => case e: Exception =>
TBMCCoreAPI.SendException("Error while adding role!", e, grm) TBMCCoreAPI.SendException("Error while adding role!", e, grm)
@ -29,7 +29,7 @@ import reactor.core.publisher.Mono
)) def remove(sender: Command2DCSender, @Command2.TextArg rolename: String): Boolean = { )) def remove(sender: Command2DCSender, @Command2.TextArg rolename: String): Boolean = {
val role = checkAndGetRole(sender, rolename) val role = checkAndGetRole(sender, rolename)
if (role == null) return true if (role == null) return true
try sender.getMessage.getAuthorAsMember.flatMap(m => m.removeRole(role.getId).switchIfEmpty(Mono.fromRunnable(() => sender.sendMessage("removed role.")))).subscribe try sender.getMessage.getAuthorAsMember.flatMap(m => m.removeRole(role.getId).switchIfEmpty(Mono.fromRunnable(() => sender.sendMessage("removed role.")))).subscribe()
catch { catch {
case e: Exception => case e: Exception =>
TBMCCoreAPI.SendException("Error while removing role!", e, grm) TBMCCoreAPI.SendException("Error while removing role!", e, grm)

View file

@ -1,40 +0,0 @@
package buttondevteam.DiscordPlugin;
import buttondevteam.discordplugin.DiscordConnectedPlayer;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.bukkit.attribute.Attribute;
import org.bukkit.entity.Player;
/**
* Unit test for simple App.
*/
public class AppTest extends TestCase {
/**
* Create the test case
*
* @param testName
* name of the test case
*/
public AppTest(String testName) {
super(testName);
}
/**
* @return the suite of tests being tested
*/
public static Test suite() {
return new TestSuite(AppTest.class);
}
/**
* Rigourous Test :-)
*/
public void testApp() {
Player dcp = DiscordConnectedPlayer.createTest();
double h = dcp.getAttribute(Attribute.GENERIC_MAX_HEALTH).getDefaultValue(); ; ;
System.out.println(h);
}
}