Update config options and fix other issues and update Scala

This commit is contained in:
Norbi Peti 2023-06-29 02:10:20 +02:00
parent 6bd1de6217
commit 02e05e360e
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
16 changed files with 107 additions and 76 deletions

View file

@ -8,7 +8,7 @@ name := "Chroma-Discord"
version := "1.1" version := "1.1"
scalaVersion := "3.2.2" scalaVersion := "3.3.0"
resolvers += "spigot-repo" at "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" resolvers += "spigot-repo" at "https://hub.spigotmc.org/nexus/content/repositories/snapshots/"
resolvers += "jitpack.io" at "https://jitpack.io" resolvers += "jitpack.io" at "https://jitpack.io"

View file

@ -1,6 +1,7 @@
package buttondevteam.discordplugin package buttondevteam.discordplugin
import buttondevteam.lib.TBMCCoreAPI import buttondevteam.lib.TBMCCoreAPI
import buttondevteam.lib.architecture.config.IConfigData
import buttondevteam.lib.architecture.{Component, ConfigData, IHaveConfig} import buttondevteam.lib.architecture.{Component, ConfigData, IHaveConfig}
import discord4j.common.util.Snowflake import discord4j.common.util.Snowflake
import discord4j.core.`object`.entity.channel.{Channel, MessageChannel} import discord4j.core.`object`.entity.channel.{Channel, MessageChannel}
@ -68,17 +69,17 @@ object DPUtils {
else DiscordPlugin.plugin.getLogger else DiscordPlugin.plugin.getLogger
} }
def channelData(config: IHaveConfig, key: String): ConfigData[Mono[MessageChannel]] = def channelData(config: IHaveConfig, key: String): IConfigData[Mono[MessageChannel]] =
config.getData(key, id => getMessageChannel(key, Snowflake.of(id.asInstanceOf[Long])), config.getData(key, id => getMessageChannel(key, Snowflake.of(id.asInstanceOf[Long])),
(_: Mono[MessageChannel]) => 0L, 0L, true) //We can afford to search for the channel in the cache once (instead of using mainServer) (_: Mono[MessageChannel]) => 0L, 0L, true) //We can afford to search for the channel in the cache once (instead of using mainServer)
def roleData(config: IHaveConfig, key: String, defName: String): ConfigData[Mono[Role]] = def roleData(config: IHaveConfig, key: String, defName: String): IConfigData[Mono[Role]] =
roleData(config, key, defName, Mono.just(DiscordPlugin.mainServer)) roleData(config, key, defName, Mono.just(DiscordPlugin.mainServer))
/** /**
* Needs to be a [[ConfigData]] for checking if it's set * Needs to be a [[ConfigData]] for checking if it's set
*/ */
def roleData(config: IHaveConfig, key: String, defName: String, guild: Mono[Guild]): ConfigData[Mono[Role]] = config.getData(key, name => { def roleData(config: IHaveConfig, key: String, defName: String, guild: Mono[Guild]): IConfigData[Mono[Role]] = config.getData(key, name => {
if (!name.isInstanceOf[String] || name.asInstanceOf[String].isEmpty) Mono.empty[Role] if (!name.isInstanceOf[String] || name.asInstanceOf[String].isEmpty) Mono.empty[Role]
else guild.flatMapMany(_.getRoles).filter(_.getName == name).onErrorResume(e => { else guild.flatMapMany(_.getRoles).filter(_.getName == name).onErrorResume(e => {
getLogger.warning("Failed to get role data for " + key + "=" + name + " - " + e.getMessage) getLogger.warning("Failed to get role data for " + key + "=" + name + " - " + e.getMessage)
@ -86,7 +87,7 @@ object DPUtils {
}).next }).next
}, _ => defName, defName, true) }, _ => defName, defName, true)
def snowflakeData(config: IHaveConfig, key: String, defID: Long): ConfigData[Snowflake] = def snowflakeData(config: IHaveConfig, key: String, defID: Long): IConfigData[Snowflake] =
config.getData(key, id => Snowflake.of(id.asInstanceOf[Long]), _.asLong, defID, true) config.getData(key, id => Snowflake.of(id.asInstanceOf[Long]), _.asLong, defID, true)
/** /**
@ -106,7 +107,7 @@ object DPUtils {
* @param configs The configs to check for null * @param configs The configs to check for null
* @return Whether the component got disabled and a warning logged * @return Whether the component got disabled and a warning logged
*/ */
def disableIfConfigError(@Nullable component: Component[DiscordPlugin], configs: ConfigData[_]*): Boolean = { def disableIfConfigError(@Nullable component: Component[DiscordPlugin], configs: IConfigData[_]*): Boolean = {
for (config <- configs) { for (config <- configs) {
val v = config.get val v = config.get
if (disableIfConfigErrorRes(component, config, v)) return true if (disableIfConfigErrorRes(component, config, v)) return true
@ -122,7 +123,7 @@ object DPUtils {
* @param result The result of getting the value * @param result The result of getting the value
* @return Whether the component got disabled and a warning logged * @return Whether the component got disabled and a warning logged
*/ */
def disableIfConfigErrorRes(@Nullable component: Component[DiscordPlugin], config: ConfigData[_], result: Any): Boolean = { def disableIfConfigErrorRes(@Nullable component: Component[DiscordPlugin], config: IConfigData[_], result: Any): Boolean = {
//noinspection ConstantConditions //noinspection ConstantConditions
if (result == null || (result.isInstanceOf[Mono[_]] && !result.asInstanceOf[Mono[_]].hasElement.block())) { if (result == null || (result.isInstanceOf[Mono[_]] && !result.asInstanceOf[Mono[_]].hasElement.block())) {
var path: String = null var path: String = null
@ -185,7 +186,7 @@ object DPUtils {
}).filter(ch => ch.isInstanceOf[MessageChannel]).cast(classOf[MessageChannel]) }).filter(ch => ch.isInstanceOf[MessageChannel]).cast(classOf[MessageChannel])
} }
def getMessageChannel(config: ConfigData[Snowflake]): Mono[MessageChannel] = def getMessageChannel(config: IConfigData[Snowflake]): Mono[MessageChannel] =
getMessageChannel(config.getPath, config.get) getMessageChannel(config.getPath, config.get)
def ignoreError[T](mono: Mono[T]): Mono[T] = mono.onErrorResume((_: Throwable) => Mono.empty) def ignoreError[T](mono: Mono[T]): Mono[T] = mono.onErrorResume((_: Throwable) => Mono.empty)

View file

@ -14,6 +14,7 @@ import buttondevteam.discordplugin.role.GameRoleModule
import buttondevteam.discordplugin.util.{DPState, Timings} import buttondevteam.discordplugin.util.{DPState, Timings}
import buttondevteam.lib.TBMCCoreAPI import buttondevteam.lib.TBMCCoreAPI
import buttondevteam.lib.architecture.* import buttondevteam.lib.architecture.*
import buttondevteam.lib.architecture.config.IConfigData
import buttondevteam.lib.player.ChromaGamerBase 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
@ -77,16 +78,16 @@ import scala.jdk.OptionConverters.*
/** /**
* The (bot) channel to use for Discord commands like /role. * The (bot) channel to use for Discord commands like /role.
*/ */
def commandChannel: ConfigData[Snowflake] = DPUtils.snowflakeData(getIConfig, "commandChannel", 0L) def commandChannel: IConfigData[Snowflake] = DPUtils.snowflakeData(getIConfig, "commandChannel", 0L)
/** /**
* The role that allows using mod-only Discord commands. * The role that allows using mod-only Discord commands.
* If empty (&#39;&#39;), then it will only allow for the owner. * If empty (&#39;&#39;), then it will only allow for the owner.
*/ */
def modRole: ConfigData[Mono[Role]] = DPUtils.roleData(getIConfig, "modRole", "Moderator") def modRole: IConfigData[Mono[Role]] = DPUtils.roleData(getIConfig, "modRole", "Moderator")
/** /**
* The invite link to show by /discord invite. If empty, it defaults to the first invite if the bot has access. * The invite link to show by /discord invite. If empty, it defaults to the first invite if the bot has access.
*/ */
def inviteLink: ConfigData[String] = getIConfig.getData("inviteLink", "") def inviteLink: IConfigData[String] = getIConfig.getData("inviteLink", "")
override def onLoad(): Unit = { //Needed by ServerWatcher override def onLoad(): Unit = { //Needed by ServerWatcher
val thread = Thread.currentThread val thread = Thread.currentThread

View file

@ -15,9 +15,10 @@ class Command2DC extends Command2[ICommand2DC, Command2DCSender]('/', false) {
} }
def registerCommand(command: ICommand2DC, appId: Long, guildId: Option[Long] = None): Unit = { def registerCommand(command: ICommand2DC, appId: Long, guildId: Option[Long] = None): Unit = {
super.registerCommandSuper(command) //Needs to be configurable for the helps val mainNode = super.registerCommandSuper(command) //Needs to be configurable for the helps
// TODO: Go through all subcommands and register them
val greetCmdRequest = ApplicationCommandRequest.builder() val greetCmdRequest = ApplicationCommandRequest.builder()
.name(command.getCommandPath) //TODO: Main path .name(mainNode.getName)
.description("Connect your Minecraft account.") //TODO: Description .description("Connect your Minecraft account.") //TODO: Description
.addOption(ApplicationCommandOptionData.builder() .addOption(ApplicationCommandOptionData.builder()
.name("name") .name("name")

View file

@ -15,7 +15,7 @@ class Command2DCSender(val event: ChatInputInteractionEvent) extends Command2Sen
override def sendMessage(message: String): Unit = { override def sendMessage(message: String): Unit = {
if (message.isEmpty) return () if (message.isEmpty) return ()
//Some(message) map DPUtils.sanitizeString map { (msg: String) => Character.toLowerCase(msg.charAt(0)) + msg.substring(1) } foreach event.reply - don't even need this //Some(message) map DPUtils.sanitizeString map { (msg: String) => Character.toLowerCase(msg.charAt(0)) + msg.substring(1) } foreach event.reply - don't even need this
event.reply(message); event.reply(message)
} }
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

@ -3,6 +3,7 @@ package buttondevteam.discordplugin.fun
import buttondevteam.core.ComponentManager import buttondevteam.core.ComponentManager
import buttondevteam.discordplugin.{DPUtils, DiscordPlugin} import buttondevteam.discordplugin.{DPUtils, DiscordPlugin}
import buttondevteam.lib.TBMCCoreAPI import buttondevteam.lib.TBMCCoreAPI
import buttondevteam.lib.architecture.config.IConfigData
import buttondevteam.lib.architecture.{Component, ConfigData} import buttondevteam.lib.architecture.{Component, ConfigData}
import com.google.common.collect.Lists import com.google.common.collect.Lists
import discord4j.core.`object`.entity.channel.{GuildChannel, MessageChannel} import discord4j.core.`object`.entity.channel.{GuildChannel, MessageChannel}
@ -97,7 +98,7 @@ class FunModule extends Component[DiscordPlugin] with Listener {
/** /**
* Questions that the bot will choose a random answer to give to. * Questions that the bot will choose a random answer to give to.
*/ */
final private def serverReady: ConfigData[Array[String]] = final private def serverReady: IConfigData[Array[String]] =
getConfig.getData("serverReady", Array[String]( getConfig.getData("serverReady", Array[String](
"when will the server be open", "when will the server be ready", "when will the server be open", "when will the server be ready",
"when will the server be done", "when will the server be complete", "when will the server be done", "when will the server be complete",
@ -106,7 +107,7 @@ class FunModule extends Component[DiscordPlugin] with Listener {
/** /**
* Answers for a recognized question. Selected randomly. * Answers for a recognized question. Selected randomly.
*/ */
final private def serverReadyAnswers: ConfigData[util.ArrayList[String]] = final private def serverReadyAnswers: IConfigData[util.ArrayList[String]] =
getConfig.getData("serverReadyAnswers", Lists.newArrayList(FunModule.serverReadyStrings: _*)) getConfig.getData("serverReadyAnswers", Lists.newArrayList(FunModule.serverReadyStrings: _*))
private def createUsableServerReadyStrings(): Unit = private def createUsableServerReadyStrings(): Unit =

View file

@ -123,7 +123,7 @@ class ChannelconCommand(private val module: MinecraftChatModule) extends IComman
} }
val dcp: DiscordConnectedPlayer = DiscordConnectedPlayer.create(message.getAuthor.get, channel, chp.getUniqueId, Bukkit.getOfflinePlayer(chp.getUniqueId).getName, module) val dcp: DiscordConnectedPlayer = DiscordConnectedPlayer.create(message.getAuthor.get, channel, chp.getUniqueId, Bukkit.getOfflinePlayer(chp.getUniqueId).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(chp)
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

View file

@ -15,6 +15,7 @@ import discord4j.core.`object`.entity.channel.PrivateChannel
)) ))
class MCChatCommand(private val module: MinecraftChatModule) extends ICommand2DC { class MCChatCommand(private val module: MinecraftChatModule) extends ICommand2DC {
@Command2.Subcommand override def `def`(sender: Command2DCSender): Boolean = { @Command2.Subcommand override def `def`(sender: Command2DCSender): Boolean = {
// TODO: If the user is logged in, don't let the object be removed from the cache (test first)
if (!module.allowPrivateChat.get) { if (!module.allowPrivateChat.get) {
sender.sendMessage("Using the private chat is not allowed on this Minecraft server.") sender.sendMessage("Using the private chat is not allowed on this Minecraft server.")
return true return true

View file

@ -21,8 +21,8 @@ object MCChatCustom {
var gid: String = null var gid: String = null
mcchannel match { mcchannel match {
case room: ChatRoom => case room: ChatRoom =>
room.joinRoom(dcp) room.joinRoom(dcp.getChromaUser)
gid = if (groupid == null) mcchannel.getGroupID(dcp) else groupid gid = if (groupid == null) mcchannel.getGroupID(dcp.getChromaUser) else groupid
case _ => case _ =>
gid = groupid gid = groupid
} }
@ -46,7 +46,7 @@ object MCChatCustom {
if (lmd.channel.getId.asLong != channel.asLong) true if (lmd.channel.getId.asLong != channel.asLong) true
else { else {
lmd.mcchannel match { lmd.mcchannel match {
case room: ChatRoom => room.leaveRoom(lmd.dcp) case room: ChatRoom => room.leaveRoom(lmd.dcp.getChromaUser)
case _ => case _ =>
} }
false false
@ -58,6 +58,7 @@ object MCChatCustom {
def getCustomChats: List[CustomLMD] = lastmsgCustom.toList def getCustomChats: List[CustomLMD] = lastmsgCustom.toList
// TODO: Store Chroma user only
class CustomLMD private[mcchat](channel: MessageChannel, user: User, val groupID: String, class CustomLMD private[mcchat](channel: MessageChannel, user: User, val groupID: String,
mcchannel: Channel, val dcp: DiscordConnectedPlayer, var toggles: Int, mcchannel: Channel, val dcp: DiscordConnectedPlayer, var toggles: Int,
var brtoggles: Set[TBMCSystemChatEvent.BroadcastTarget]) extends MCChatUtils.LastMsgData(channel, user, mcchannel) { var brtoggles: Set[TBMCSystemChatEvent.BroadcastTarget]) extends MCChatUtils.LastMsgData(channel, user, mcchannel) {

View file

@ -14,7 +14,9 @@ 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 import discord4j.core.spec.EmbedCreateSpec
import discord4j.core.spec.legacy.{LegacyEmbedCreateSpec, LegacyMessageEditSpec} import discord4j.core.spec.legacy.{LegacyEmbedCreateSpec, LegacyMessageEditSpec}
import discord4j.rest.http.client.ClientException
import discord4j.rest.util.Color import discord4j.rest.util.Color
import io.netty.handler.codec.http.HttpResponseStatus
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.{EventHandler, Listener} import org.bukkit.event.{EventHandler, Listener}
@ -88,22 +90,22 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
time = se.getValue time = se.getValue
val authorPlayer: String = "[" + DPUtils.sanitizeStringNoEscape(e.getChannel.displayName.get) + "] " + // val authorPlayer: String = "[" + DPUtils.sanitizeStringNoEscape(e.getChannel.displayName.get) + "] " + //
(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(e.getUser.getName)
val color: chat.Color = e.getChannel.color.get val color: chat.Color = e.getChannel.color.get
val embed = () => { val embed = () => {
val ecs = EmbedCreateSpec.builder() val ecs = EmbedCreateSpec.builder()
ecs.description(e.getMessage).color(Color.of(color.getRed, color.getGreen, color.getBlue)) ecs.description(e.getMessage).color(Color.of(color.getRed, color.getGreen, color.getBlue))
val url: String = module.profileURL.get val url: String = module.profileURL.get
e.getSender match { e.getUser match {
case player: Player => case player: TBMCPlayer =>
DPUtils.embedWithHead(ecs, authorPlayer, e.getSender.getName, DPUtils.embedWithHead(ecs, authorPlayer, e.getUser.getName,
if (url.nonEmpty) url + "?type=minecraft&id=" + player.getUniqueId else null) if (url.nonEmpty) url + "?type=minecraft&id=" + player.getUniqueId else null)
case dsender: DiscordSenderBase => case dsender: DiscordPlayer =>
ecs.author(authorPlayer, ecs.author(authorPlayer,
if (url.nonEmpty) url + "?type=discord&id=" + dsender.getUser.getId.asString else null, if (url.nonEmpty) url + "?type=discord&id=" + dsender.getDiscordID else null,
dsender.getUser.getAvatarUrl) dsender.getDiscordUser.getAvatarUrl)
case _ => case _ =>
DPUtils.embedWithHead(ecs, authorPlayer, e.getSender.getName, null) DPUtils.embedWithHead(ecs, authorPlayer, e.getUser.getName, null)
} }
ecs.timestamp(time) ecs.timestamp(time)
} }
@ -120,13 +122,25 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
lastmsgdata.content = e.getMessage lastmsgdata.content = e.getMessage
} }
else { else {
//TODO: The editing shouldn't be blocking, this whole method should be reactive
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().withEmbeds(embed().description(lastmsgdata.content).build()).block try {
lastmsgdata.message.edit().withEmbeds(embed().description(lastmsgdata.content).build()).block
} catch {
case e: ClientException => {
// The message was deleted
if (e.getStatus ne HttpResponseStatus.NOT_FOUND) {
throw e
}
}
}
} }
} }
// 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
// Or if it was from MC // Or if it was from MC
val isdifferentchannel: Predicate[Snowflake] = (id: Snowflake) => !((e.getSender.isInstanceOf[DiscordSenderBase])) || (e.getSender.asInstanceOf[DiscordSenderBase]).getChannel.getId.asLong != id.asLong val isdifferentchannel: Predicate[Snowflake] = {
id => !e.getUser.isInstanceOf[DiscordPlayer] || e.getUser.asInstanceOf[DiscordSender].getChannel.getId.asLong != id.asLong
}
if (e.getChannel.isGlobal && (e.isFromCommand || isdifferentchannel.test(module.chatChannel.get))) { if (e.getChannel.isGlobal && (e.isFromCommand || isdifferentchannel.test(module.chatChannel.get))) {
if (MCChatUtils.lastmsgdata == null) if (MCChatUtils.lastmsgdata == null)
MCChatUtils.lastmsgdata = new MCChatUtils.LastMsgData(module.chatChannelMono.block(), null) MCChatUtils.lastmsgdata = new MCChatUtils.LastMsgData(module.chatChannelMono.block(), null)
@ -143,7 +157,7 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
if ((e.isFromCommand || isdifferentchannel.test(lmd.channel.getId)) //Test if msg is from Discord if ((e.isFromCommand || isdifferentchannel.test(lmd.channel.getId)) //Test if msg is from Discord
&& e.getChannel.getIdentifier == lmd.mcchannel.getIdentifier //If it's from a command, the command msg has been deleted, so we need to send it && e.getChannel.getIdentifier == lmd.mcchannel.getIdentifier //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 && 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 if (e.shouldSendTo(lmd.dcp.getChromaUser)) { //Check original user's permissions
doit(lmd) doit(lmd)
true true
} }
@ -370,8 +384,8 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
} }
if (event.getMessage.getType eq Message.Type.CHANNEL_PINNED_MESSAGE) { if (event.getMessage.getType eq Message.Type.CHANNEL_PINNED_MESSAGE) {
val mcchannel = if (clmd != null) clmd.mcchannel else dsender.getChromaUser.channel.get val mcchannel = if (clmd != null) clmd.mcchannel else dsender.getChromaUser.getChannel.get
val rtr = mcchannel getRTR (if (clmd != null) clmd.dcp else dsender) val rtr = mcchannel getRTR (if (clmd != null) clmd.dcp.getChromaUser else user)
TBMCChatAPI.SendSystemMessage(mcchannel, rtr, (dsender match { TBMCChatAPI.SendSystemMessage(mcchannel, rtr, (dsender match {
case player: Player => player.getDisplayName case player: Player => player.getDisplayName
case _ => dsender.getName case _ => dsender.getName
@ -379,9 +393,9 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
false false
} }
else { else {
val cmb = ChatMessage.builder(dsender, user, dmessage + getAttachmentText).fromCommand(false) val cmb = ChatMessage.builder(user, dmessage + getAttachmentText).fromCommand(false)
if (clmd != null) if (clmd != null)
TBMCChatAPI.sendChatMessage(cmb.permCheck(clmd.dcp).build, clmd.mcchannel) TBMCChatAPI.sendChatMessage(cmb.permCheck(clmd.dcp.getChromaUser).build, clmd.mcchannel)
else else
TBMCChatAPI.sendChatMessage(cmb.build) TBMCChatAPI.sendChatMessage(cmb.build)
true true
@ -422,8 +436,8 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
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.getChannel.get else clmd.mcchannel
val ev = new TBMCCommandPreprocessEvent(dsender, channel, dmessage, if (clmd == null) dsender else clmd.dcp) val ev = new TBMCCommandPreprocessEvent(user, channel, dmessage, if (clmd == null) user else clmd.dcp.getChromaUser)
Bukkit.getScheduler.runTask(DiscordPlugin.plugin, () => { //Commands need to be run sync Bukkit.getScheduler.runTask(DiscordPlugin.plugin, () => { //Commands need to be run sync
Bukkit.getPluginManager.callEvent(ev) Bukkit.getPluginManager.callEvent(ev)
if (!ev.isCancelled) if (!ev.isCancelled)

View file

@ -27,14 +27,14 @@ object MCChatPrivate {
val mcm = ComponentManager.getIfEnabled(classOf[MinecraftChatModule]) val mcm = ComponentManager.getIfEnabled(classOf[MinecraftChatModule])
if (start) { if (start) {
val sender = DiscordConnectedPlayer.create(user, channel, mcp.getUniqueId, op.getName, mcm) val sender = DiscordConnectedPlayer.create(user, channel, mcp.getUniqueId, op.getName, mcm)
MCChatUtils.addSender(MCChatUtils.ConnectedSenders, user, sender) MCChatUtils.addSenderTo(MCChatUtils.ConnectedSenders, user, sender)
MCChatUtils.LoggedInPlayers.put(mcp.getUniqueId, sender) MCChatUtils.LoggedInPlayers.put(mcp.getUniqueId, sender)
if (p == null) { // Player is offline - If the player is online, that takes precedence if (p == null) { // Player is offline - If the player is online, that takes precedence
MCChatUtils.callLoginEvents(sender) MCChatUtils.callLoginEvents(sender)
} }
} }
else { else {
val sender = MCChatUtils.removeSender(MCChatUtils.ConnectedSenders, channel.getId, user) val sender = MCChatUtils.removeSenderFrom(MCChatUtils.ConnectedSenders, channel.getId, user)
assert(sender != null) assert(sender != null)
Bukkit.getScheduler.runTask(DiscordPlugin.plugin, () => { Bukkit.getScheduler.runTask(DiscordPlugin.plugin, () => {
def foo(): Unit = { def foo(): Unit = {
@ -69,7 +69,7 @@ object MCChatPrivate {
MCChatUtils.ConnectedSenders synchronized { MCChatUtils.ConnectedSenders synchronized {
for ((_, userMap) <- MCChatUtils.ConnectedSenders) { for ((_, userMap) <- MCChatUtils.ConnectedSenders) {
for (valueEntry <- asScala(userMap.entrySet)) { for (valueEntry <- asScala(userMap.entrySet)) {
if (MCChatUtils.getSender(MCChatUtils.OnlineSenders, valueEntry.getKey, valueEntry.getValue.getUser) == null) { //If the player is online then the fake player was already logged out if (MCChatUtils.getSenderFrom(MCChatUtils.OnlineSenders, valueEntry.getKey, valueEntry.getValue.getUser) == null) { //If the player is online then the fake player was already logged out
MCChatUtils.callLogoutEvent(valueEntry.getValue, !Bukkit.isPrimaryThread) MCChatUtils.callLogoutEvent(valueEntry.getValue, !Bukkit.isPrimaryThread)
} }
} }

View file

@ -7,6 +7,7 @@ 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.discordplugin.mcchat.sender.{DiscordConnectedPlayer, DiscordPlayerSender, DiscordSender, DiscordSenderBase} import buttondevteam.discordplugin.mcchat.sender.{DiscordConnectedPlayer, DiscordPlayerSender, DiscordSender, DiscordSenderBase}
import buttondevteam.lib.player.{ChromaGamerBase, TBMCPlayerBase}
import buttondevteam.lib.{TBMCCoreAPI, TBMCSystemChatEvent} import buttondevteam.lib.{TBMCCoreAPI, TBMCSystemChatEvent}
import com.google.common.collect.Sets import com.google.common.collect.Sets
import discord4j.common.util.Snowflake import discord4j.common.util.Snowflake
@ -35,7 +36,7 @@ import scala.collection.convert.ImplicitConversions.`map AsJavaMap`
import scala.collection.mutable.ListBuffer import scala.collection.mutable.ListBuffer
import scala.jdk.CollectionConverters.{CollectionHasAsScala, SeqHasAsJava} import scala.jdk.CollectionConverters.{CollectionHasAsScala, SeqHasAsJava}
import scala.jdk.javaapi.CollectionConverters.asScala import scala.jdk.javaapi.CollectionConverters.asScala
import scala.jdk.javaapi.OptionConverters._ import scala.jdk.javaapi.OptionConverters.*
object MCChatUtils { object MCChatUtils {
/** /**
@ -87,7 +88,7 @@ object MCChatUtils {
gid == buttondevteam.core.component.channel.Channel.GROUP_EVERYONE //If null, allow if public (custom chats will have their channel stored anyway) gid == buttondevteam.core.component.channel.Channel.GROUP_EVERYONE //If null, allow if public (custom chats will have their channel stored anyway)
} }
else { else {
gid == lmd.mcchannel.getGroupID(p) gid == lmd.mcchannel.getGroupID(ChromaGamerBase.getFromSender(p))
} }
).filter(MCChatUtils.checkEssentials) //If they can see it ).filter(MCChatUtils.checkEssentials) //If they can see it
.filter(_ => C.incrementAndGet > 0) //Always true .filter(_ => C.incrementAndGet > 0) //Always true
@ -102,10 +103,10 @@ object MCChatUtils {
!ess.getUser(p).isHidden !ess.getUser(p).isHidden
} }
def addSender[T <: DiscordSenderBase](senders: concurrent.Map[String, ConcurrentHashMap[Snowflake, T]], user: User, sender: T): T = def addSenderTo[T <: DiscordSenderBase](senders: concurrent.Map[String, ConcurrentHashMap[Snowflake, T]], user: User, sender: T): T =
addSender(senders, user.getId.asString, sender) addSenderTo(senders, user.getId.asString, sender)
def addSender[T <: DiscordSenderBase](senders: concurrent.Map[String, ConcurrentHashMap[Snowflake, T]], did: String, sender: T): T = { def addSenderTo[T <: DiscordSenderBase](senders: concurrent.Map[String, ConcurrentHashMap[Snowflake, T]], did: String, sender: T): T = {
val mapOpt = senders.get(did) val mapOpt = senders.get(did)
val map = if (mapOpt.isEmpty) new ConcurrentHashMap[Snowflake, T] else mapOpt.get val map = if (mapOpt.isEmpty) new ConcurrentHashMap[Snowflake, T] else mapOpt.get
map.put(sender.getChannel.getId, sender) map.put(sender.getChannel.getId, sender)
@ -113,13 +114,13 @@ object MCChatUtils {
sender sender
} }
def getSender[T <: DiscordSenderBase](senders: concurrent.Map[String, ConcurrentHashMap[Snowflake, T]], channel: Snowflake, user: User): T = { def getSenderFrom[T <: DiscordSenderBase](senders: concurrent.Map[String, ConcurrentHashMap[Snowflake, T]], channel: Snowflake, user: User): T = {
val mapOpt = senders.get(user.getId.asString) val mapOpt = senders.get(user.getId.asString)
if (mapOpt.nonEmpty) mapOpt.get.get(channel) if (mapOpt.nonEmpty) mapOpt.get.get(channel)
else null.asInstanceOf else null.asInstanceOf
} }
def removeSender[T <: DiscordSenderBase](senders: concurrent.Map[String, ConcurrentHashMap[Snowflake, T]], channel: Snowflake, user: User): T = { def removeSenderFrom[T <: DiscordSenderBase](senders: concurrent.Map[String, ConcurrentHashMap[Snowflake, T]], channel: Snowflake, user: User): T = {
val mapOpt = senders.get(user.getId.asString) val mapOpt = senders.get(user.getId.asString)
if (mapOpt.nonEmpty) mapOpt.get.remove(channel) if (mapOpt.nonEmpty) mapOpt.get.remove(channel)
else null.asInstanceOf else null.asInstanceOf
@ -153,15 +154,15 @@ object MCChatUtils {
* Do the {@code action} for each custom chat the {@code sender} have access to and has that broadcast type enabled. * Do the {@code action} for each custom chat the {@code sender} have access to and has that broadcast type enabled.
* *
* @param action The action to do * @param action The action to do
* @param sender The sender to check perms of or null to send to all that has it toggled * @param permUser The user to check perms of or null to send to all that has it toggled
* @param toggle The toggle to check or null to send to all allowed * @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[_] = { def forAllowedCustomMCChat(action: Mono[MessageChannel] => Mono[_], @Nullable permUser: ChromaGamerBase, @Nullable toggle: ChannelconBroadcast): Mono[_] = {
if (notEnabled) return Mono.empty if (notEnabled) return Mono.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 val st = MCChatCustom.lastmsgCustom.filter(clmd => { //new TBMCChannelConnectFakeEvent(sender, clmd.mcchannel).shouldSendTo(clmd.dcp) - Thought it was this simple hehe - Wait, it *should* be this simple
if (toggle != null && ((clmd.toggles & (1 << toggle.id)) == 0)) false //If null then allow if (toggle != null && ((clmd.toggles & (1 << toggle.id)) == 0)) false //If null then allow
else if (sender == null) true else if (permUser == null) true
else clmd.groupID.equals(clmd.mcchannel.getGroupID(sender)) else clmd.groupID.equals(clmd.mcchannel.getGroupID(permUser))
}).map(cc => action.apply(Mono.just(cc.channel))) //TODO: Send error messages on channel connect }).map(cc => action.apply(Mono.just(cc.channel))) //TODO: Send error messages on channel connect
//Mono.whenDelayError((() => st.iterator).asInstanceOf[java.lang.Iterable[Mono[_]]]) //Can't convert as an iterator or inside the stream, but I can convert it as a stream //Mono.whenDelayError((() => st.iterator).asInstanceOf[java.lang.Iterable[Mono[_]]]) //Can't convert as an iterator or inside the stream, but I can convert it as a stream
Mono.whenDelayError(st.asJava) Mono.whenDelayError(st.asJava)
@ -171,13 +172,13 @@ object MCChatUtils {
* Do the {@code action} for each custom chat the {@code sender} have access to and has that broadcast type enabled. * Do the {@code action} for each custom chat the {@code sender} have access to and has that broadcast type enabled.
* *
* @param action The action to do * @param action The action to do
* @param sender The sender to check perms of or null to send to all that has it toggled * @param permUser The user to check perms of or null to send to all that has it toggled
* @param toggle The toggle to check or null to send to all allowed * @param toggle The toggle to check or null to send to all allowed
* @param hookmsg Whether the message is also sent from the hook * @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[_] = { def forAllowedCustomAndAllMCChat(action: Mono[MessageChannel] => Mono[_], @Nullable permUser: ChromaGamerBase, @Nullable toggle: ChannelconBroadcast, hookmsg: Boolean): Mono[_] = {
if (notEnabled) return Mono.empty if (notEnabled) return Mono.empty
val cc = forAllowedCustomMCChat(action, sender, toggle) val cc = forAllowedCustomMCChat(action, permUser, toggle)
if (!GeneralEventBroadcasterModule.isHooked || !hookmsg) return Mono.whenDelayError(forPublicPrivateChat(action), cc) if (!GeneralEventBroadcasterModule.isHooked || !hookmsg) return Mono.whenDelayError(forPublicPrivateChat(action), cc)
Mono.whenDelayError(cc) Mono.whenDelayError(cc)
} }
@ -195,7 +196,7 @@ object MCChatUtils {
if (event.shouldSendTo(getSender(data.channel.getId, data.user))) if (event.shouldSendTo(getSender(data.channel.getId, data.user)))
list.append(action(Mono.just(data.channel))) //TODO: Only store ID? list.append(action(Mono.just(data.channel))) //TODO: Only store ID?
MCChatCustom.lastmsgCustom.filter(clmd => MCChatCustom.lastmsgCustom.filter(clmd =>
clmd.brtoggles.contains(event.getTarget) && event.shouldSendTo(clmd.dcp)) clmd.brtoggles.contains(event.getTarget) && event.shouldSendTo(clmd.dcp.getChromaUser))
.map(clmd => action(Mono.just(clmd.channel))).foreach(elem => { .map(clmd => action(Mono.just(clmd.channel))).foreach(elem => {
list.append(elem) list.append(elem)
() ()
@ -207,10 +208,10 @@ object MCChatUtils {
* This method will find the best sender to use: if the player is online, use that, if not but connected then use that etc. * This method will find the best sender to use: if the player is online, use that, if not but connected then use that etc.
*/ */
private[mcchat] def getSender(channel: Snowflake, author: User): DiscordSenderBase = { //noinspection OptionalGetWithoutIsPresent private[mcchat] def getSender(channel: Snowflake, author: User): DiscordSenderBase = { //noinspection OptionalGetWithoutIsPresent
Option(getSender(OnlineSenders, channel, author)) // Find first non-null Option(getSenderFrom(OnlineSenders, channel, author)) // Find first non-null
.orElse(Option(getSender(ConnectedSenders, channel, author))) // This doesn't support the public chat, but it'll always return null for it .orElse(Option(getSenderFrom(ConnectedSenders, channel, author))) // This doesn't support the public chat, but it'll always return null for it
.orElse(Option(getSender(UnconnectedSenders, channel, author))) // .orElse(Option(getSenderFrom(UnconnectedSenders, channel, author))) //
.orElse(Option(addSender(UnconnectedSenders, author, .orElse(Option(addSenderTo(UnconnectedSenders, author,
new DiscordSender(author, DiscordPlugin.dc.getChannelById(channel).block().asInstanceOf[MessageChannel])))) new DiscordSender(author, DiscordPlugin.dc.getChannelById(channel).block().asInstanceOf[MessageChannel]))))
.get .get
} }

View file

@ -3,7 +3,7 @@ package buttondevteam.discordplugin.mcchat
import buttondevteam.discordplugin.* import buttondevteam.discordplugin.*
import buttondevteam.discordplugin.mcchat.sender.{DiscordConnectedPlayer, DiscordPlayer, DiscordPlayerSender} import buttondevteam.discordplugin.mcchat.sender.{DiscordConnectedPlayer, DiscordPlayer, DiscordPlayerSender}
import buttondevteam.lib.TBMCSystemChatEvent import buttondevteam.lib.TBMCSystemChatEvent
import buttondevteam.lib.player.{TBMCPlayer, TBMCPlayerBase, TBMCYEEHAWEvent} import buttondevteam.lib.player.{ChromaGamerBase, TBMCPlayer, TBMCPlayerBase, TBMCYEEHAWEvent}
import discord4j.common.util.Snowflake import discord4j.common.util.Snowflake
import discord4j.core.`object`.entity.Role import discord4j.core.`object`.entity.Role
import discord4j.core.`object`.entity.channel.MessageChannel import discord4j.core.`object`.entity.channel.MessageChannel
@ -36,8 +36,8 @@ class MCListener(val module: MinecraftChatModule) extends Listener {
if (dp != null) if (dp != null)
DiscordPlugin.dc.getUserById(Snowflake.of(dp.getDiscordID)).flatMap(user => DiscordPlugin.dc.getUserById(Snowflake.of(dp.getDiscordID)).flatMap(user =>
user.getPrivateChannel.flatMap(chan => module.chatChannelMono.flatMap(cc => { user.getPrivateChannel.flatMap(chan => module.chatChannelMono.flatMap(cc => {
MCChatUtils.addSender(MCChatUtils.OnlineSenders, dp.getDiscordID, DiscordPlayerSender.create(user, chan, p, module)) MCChatUtils.addSenderTo(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.addSenderTo(MCChatUtils.OnlineSenders, dp.getDiscordID, DiscordPlayerSender.create(user, cc, p, module)) //Stored per-channel
Mono.empty Mono.empty
}))).subscribe() }))).subscribe()
val message = e.getJoinMessage val message = e.getJoinMessage
@ -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), ChromaGamerBase.getFromSender(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,14 +69,14 @@ 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), ChromaGamerBase.getFromSender(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), ChromaGamerBase.getFromSender(base), ChannelconBroadcast.AFK, hookmsg = false).subscribe()
} }
@EventHandler def onPlayerMute(e: MuteStatusChangeEvent): Unit = { @EventHandler def onPlayerMute(e: MuteStatusChangeEvent): Unit = {

View file

@ -4,6 +4,7 @@ import buttondevteam.core.component.channel.Channel
import buttondevteam.discordplugin.mcchat.sender.DiscordConnectedPlayer import buttondevteam.discordplugin.mcchat.sender.DiscordConnectedPlayer
import buttondevteam.discordplugin.util.DPState import buttondevteam.discordplugin.util.DPState
import buttondevteam.discordplugin.{ChannelconBroadcast, DPUtils, DiscordPlugin} import buttondevteam.discordplugin.{ChannelconBroadcast, DPUtils, DiscordPlugin}
import buttondevteam.lib.architecture.config.IConfigData
import buttondevteam.lib.architecture.{Component, ConfigData} import buttondevteam.lib.architecture.{Component, ConfigData}
import buttondevteam.lib.{TBMCCoreAPI, TBMCSystemChatEvent} import buttondevteam.lib.{TBMCCoreAPI, TBMCSystemChatEvent}
import com.google.common.collect.Lists import com.google.common.collect.Lists
@ -37,56 +38,56 @@ class MinecraftChatModule extends Component[DiscordPlugin] {
/** /**
* A list of commands that can be used in public chats - Warning: Some plugins will treat players as OPs, always test before allowing a command! * A list of commands that can be used in public chats - Warning: Some plugins will treat players as OPs, always test before allowing a command!
*/ */
def whitelistedCommands: ConfigData[util.ArrayList[String]] = getConfig.getData("whitelistedCommands", def whitelistedCommands: IConfigData[util.ArrayList[String]] = getConfig.getData("whitelistedCommands",
Lists.newArrayList("list", "u", "shrug", "tableflip", "unflip", "mwiki", "yeehaw", "lenny", "rp", "plugins")) Lists.newArrayList("list", "u", "shrug", "tableflip", "unflip", "mwiki", "yeehaw", "lenny", "rp", "plugins"))
/** /**
* The channel to use as the public Minecraft chat - everything public gets broadcasted here * The channel to use as the public Minecraft chat - everything public gets broadcasted here
*/ */
def chatChannel: ConfigData[Snowflake] = DPUtils.snowflakeData(getConfig, "chatChannel", 0L) def chatChannel: IConfigData[Snowflake] = DPUtils.snowflakeData(getConfig, "chatChannel", 0L)
def chatChannelMono: Mono[MessageChannel] = DPUtils.getMessageChannel(chatChannel.getPath, chatChannel.get) def chatChannelMono: Mono[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 * The channel where the plugin can log when it mutes a player on Discord because of a Minecraft mute
*/ */
def modlogChannel: ConfigData[Mono[MessageChannel]] = DPUtils.channelData(getConfig, "modlogChannel") def modlogChannel: IConfigData[Mono[MessageChannel]] = DPUtils.channelData(getConfig, "modlogChannel")
/** /**
* The plugins to exclude from fake player events used for the 'mcchat' command - some plugins may crash, add them here * The plugins to exclude from fake player events used for the 'mcchat' command - some plugins may crash, add them here
*/ */
def excludedPlugins: ConfigData[Array[String]] = getConfig.getData("excludedPlugins", Array[String]("ProtocolLib", "LibsDisguises", "JourneyMapServer")) def excludedPlugins: IConfigData[Array[String]] = getConfig.getData("excludedPlugins", Array[String]("ProtocolLib", "LibsDisguises", "JourneyMapServer"))
/** /**
* If this setting is on then players logged in through the 'mcchat' command will be able to teleport using plugin commands. * If this setting is on then players logged in through the 'mcchat' command will be able to teleport using plugin commands.
* They can then use commands like /tpahere to teleport others to that place.<br /> * They can then use commands like /tpahere to teleport others to that place.<br />
* If this is off, then teleporting will have no effect. * If this is off, then teleporting will have no effect.
*/ */
def allowFakePlayerTeleports: ConfigData[Boolean] = getConfig.getData("allowFakePlayerTeleports", false) def allowFakePlayerTeleports: IConfigData[Boolean] = getConfig.getData("allowFakePlayerTeleports", false)
/** /**
* If this is on, each chat channel will have a player list in their description. * If this is on, each chat channel will have a player list in their description.
* It only gets added if there's no description yet or there are (at least) two lines of "----" following each other. * It only gets added if there's no description yet or there are (at least) two lines of "----" following each other.
* Note that it will replace <b>everything</b> above the first and below the last "----" but it will only detect exactly four dashes. * Note that it will replace <b>everything</b> above the first and below the last "----" but it will only detect exactly four dashes.
* So if you want to use dashes for something else in the description, make sure it's either less or more dashes in one line. * So if you want to use dashes for something else in the description, make sure it's either less or more dashes in one line.
*/ */
def showPlayerListOnDC: ConfigData[Boolean] = getConfig.getData("showPlayerListOnDC", true) def showPlayerListOnDC: IConfigData[Boolean] = getConfig.getData("showPlayerListOnDC", true)
/** /**
* This setting controls whether custom chat connections can be <i>created</i> (existing connections will always work). * This setting controls whether custom chat connections can be <i>created</i> (existing connections will always work).
* Custom chat connections can be created using the channelcon command and they allow players to display town chat in a Discord channel for example. * Custom chat connections can be created using the channelcon command and they allow players to display town chat in a Discord channel for example.
* See the channelcon command for more details. * See the channelcon command for more details.
*/ */
def allowCustomChat: ConfigData[Boolean] = getConfig.getData("allowCustomChat", true) def allowCustomChat: IConfigData[Boolean] = getConfig.getData("allowCustomChat", true)
/** /**
* This setting allows you to control if players can DM the bot to log on the server from Discord. * This setting allows you to control if players can DM the bot to log on the server from Discord.
* This allows them to both chat and perform any command they can in-game. * This allows them to both chat and perform any command they can in-game.
*/ */
def allowPrivateChat: ConfigData[Boolean] = getConfig.getData("allowPrivateChat", true) def allowPrivateChat: IConfigData[Boolean] = getConfig.getData("allowPrivateChat", true)
/** /**
* If set, message authors appearing on Discord will link to this URL. A 'type' and 'id' parameter will be added with the user's platform (Discord, Minecraft, ...) and ID. * If set, message authors appearing on Discord will link to this URL. A 'type' and 'id' parameter will be added with the user's platform (Discord, Minecraft, ...) and ID.
*/ */
def profileURL: ConfigData[String] = getConfig.getData("profileURL", "") def profileURL: IConfigData[String] = getConfig.getData("profileURL", "")
/** /**
* Enables support for running vanilla commands through Discord, if you ever need it. * Enables support for running vanilla commands through Discord, if you ever need it.
*/ */
def enableVanillaCommands: ConfigData[Boolean] = getConfig.getData("enableVanillaCommands", true) def enableVanillaCommands: IConfigData[Boolean] = getConfig.getData("enableVanillaCommands", true)
/** /**
* Whether players logged on from Discord (mcchat command) should be recognised by other plugins. Some plugins might break if it's turned off. * Whether players logged on from Discord (mcchat command) should be recognised by other plugins. Some plugins might break if it's turned off.
* But it's really hacky. * But it's really hacky.

View file

@ -1,10 +1,14 @@
package buttondevteam.discordplugin.mcchat.sender package buttondevteam.discordplugin.mcchat.sender
import buttondevteam.discordplugin.DiscordPlugin
import buttondevteam.discordplugin.mcchat.MCChatPrivate import buttondevteam.discordplugin.mcchat.MCChatPrivate
import buttondevteam.lib.player.{ChromaGamerBase, UserClass} import buttondevteam.lib.player.{ChromaGamerBase, UserClass}
import discord4j.common.util.Snowflake
import discord4j.core.`object`.entity.User
@UserClass(foldername = "discord") class DiscordPlayer() extends ChromaGamerBase { @UserClass(foldername = "discord") class DiscordPlayer() extends ChromaGamerBase {
private var did: String = null private var did: String = null
private var discordUser: User = null
// private @Getter @Setter boolean minecraftChatEnabled; // private @Getter @Setter boolean minecraftChatEnabled;
def getDiscordID: String = { def getDiscordID: String = {
@ -12,6 +16,11 @@ import buttondevteam.lib.player.{ChromaGamerBase, UserClass}
did did
} }
def getDiscordUser: User = {
if (discordUser == null) discordUser = DiscordPlugin.dc.getUserById(Snowflake.of(getDiscordID)).block() // TODO: Don't do it blocking
discordUser
}
/** /**
* Returns true if player has the private Minecraft chat enabled. For setting the value, see * Returns true if player has the private Minecraft chat enabled. For setting the value, see
* [[MCChatPrivate.privateMCChat]] * [[MCChatPrivate.privateMCChat]]

View file

@ -17,7 +17,7 @@ import java.util.UUID
* @param user May be null. * @param user May be null.
* @param channel May not be null. * @param channel May not be null.
*/ */
abstract class DiscordSenderBase protected(var user: User, var channel: MessageChannel) extends CommandSender { abstract class DiscordSenderBase protected(var user: User, var channel: MessageChannel) extends CommandSender { // TODO: Move most of this to DiscordUser
private var msgtosend = "" private var msgtosend = ""
private var sendtask: BukkitTask = null private var sendtask: BukkitTask = null