Update config options and fix other issues and update Scala
This commit is contained in:
parent
6bd1de6217
commit
02e05e360e
16 changed files with 107 additions and 76 deletions
|
@ -8,7 +8,7 @@ name := "Chroma-Discord"
|
|||
|
||||
version := "1.1"
|
||||
|
||||
scalaVersion := "3.2.2"
|
||||
scalaVersion := "3.3.0"
|
||||
|
||||
resolvers += "spigot-repo" at "https://hub.spigotmc.org/nexus/content/repositories/snapshots/"
|
||||
resolvers += "jitpack.io" at "https://jitpack.io"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package buttondevteam.discordplugin
|
||||
|
||||
import buttondevteam.lib.TBMCCoreAPI
|
||||
import buttondevteam.lib.architecture.config.IConfigData
|
||||
import buttondevteam.lib.architecture.{Component, ConfigData, IHaveConfig}
|
||||
import discord4j.common.util.Snowflake
|
||||
import discord4j.core.`object`.entity.channel.{Channel, MessageChannel}
|
||||
|
@ -68,17 +69,17 @@ object DPUtils {
|
|||
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])),
|
||||
(_: 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))
|
||||
|
||||
/**
|
||||
* 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]
|
||||
else guild.flatMapMany(_.getRoles).filter(_.getName == name).onErrorResume(e => {
|
||||
getLogger.warning("Failed to get role data for " + key + "=" + name + " - " + e.getMessage)
|
||||
|
@ -86,7 +87,7 @@ object DPUtils {
|
|||
}).next
|
||||
}, _ => 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)
|
||||
|
||||
/**
|
||||
|
@ -106,7 +107,7 @@ object DPUtils {
|
|||
* @param configs The configs to check for null
|
||||
* @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) {
|
||||
val v = config.get
|
||||
if (disableIfConfigErrorRes(component, config, v)) return true
|
||||
|
@ -122,7 +123,7 @@ object DPUtils {
|
|||
* @param result The result of getting the value
|
||||
* @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
|
||||
if (result == null || (result.isInstanceOf[Mono[_]] && !result.asInstanceOf[Mono[_]].hasElement.block())) {
|
||||
var path: String = null
|
||||
|
@ -185,7 +186,7 @@ object DPUtils {
|
|||
}).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)
|
||||
|
||||
def ignoreError[T](mono: Mono[T]): Mono[T] = mono.onErrorResume((_: Throwable) => Mono.empty)
|
||||
|
|
|
@ -14,6 +14,7 @@ import buttondevteam.discordplugin.role.GameRoleModule
|
|||
import buttondevteam.discordplugin.util.{DPState, Timings}
|
||||
import buttondevteam.lib.TBMCCoreAPI
|
||||
import buttondevteam.lib.architecture.*
|
||||
import buttondevteam.lib.architecture.config.IConfigData
|
||||
import buttondevteam.lib.player.ChromaGamerBase
|
||||
import com.google.common.io.Files
|
||||
import discord4j.common.util.Snowflake
|
||||
|
@ -77,16 +78,16 @@ import scala.jdk.OptionConverters.*
|
|||
/**
|
||||
* 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.
|
||||
* If empty (''), 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.
|
||||
*/
|
||||
def inviteLink: ConfigData[String] = getIConfig.getData("inviteLink", "")
|
||||
def inviteLink: IConfigData[String] = getIConfig.getData("inviteLink", "")
|
||||
|
||||
override def onLoad(): Unit = { //Needed by ServerWatcher
|
||||
val thread = Thread.currentThread
|
||||
|
|
|
@ -15,9 +15,10 @@ class Command2DC extends Command2[ICommand2DC, Command2DCSender]('/', false) {
|
|||
}
|
||||
|
||||
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()
|
||||
.name(command.getCommandPath) //TODO: Main path
|
||||
.name(mainNode.getName)
|
||||
.description("Connect your Minecraft account.") //TODO: Description
|
||||
.addOption(ApplicationCommandOptionData.builder()
|
||||
.name("name")
|
||||
|
|
|
@ -15,7 +15,7 @@ class Command2DCSender(val event: ChatInputInteractionEvent) extends Command2Sen
|
|||
override def sendMessage(message: String): Unit = {
|
||||
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
|
||||
event.reply(message);
|
||||
event.reply(message)
|
||||
}
|
||||
|
||||
override def sendMessage(message: Array[String]): Unit = sendMessage(String.join("\n", message: _*))
|
||||
|
|
|
@ -3,6 +3,7 @@ package buttondevteam.discordplugin.fun
|
|||
import buttondevteam.core.ComponentManager
|
||||
import buttondevteam.discordplugin.{DPUtils, DiscordPlugin}
|
||||
import buttondevteam.lib.TBMCCoreAPI
|
||||
import buttondevteam.lib.architecture.config.IConfigData
|
||||
import buttondevteam.lib.architecture.{Component, ConfigData}
|
||||
import com.google.common.collect.Lists
|
||||
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.
|
||||
*/
|
||||
final private def serverReady: ConfigData[Array[String]] =
|
||||
final private def serverReady: IConfigData[Array[String]] =
|
||||
getConfig.getData("serverReady", Array[String](
|
||||
"when will the server be open", "when will the server be ready",
|
||||
"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.
|
||||
*/
|
||||
final private def serverReadyAnswers: ConfigData[util.ArrayList[String]] =
|
||||
final private def serverReadyAnswers: IConfigData[util.ArrayList[String]] =
|
||||
getConfig.getData("serverReadyAnswers", Lists.newArrayList(FunModule.serverReadyStrings: _*))
|
||||
|
||||
private def createUsableServerReadyStrings(): Unit =
|
||||
|
|
|
@ -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)
|
||||
//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
|
||||
DPUtils.reply(message, channel, "sorry, you cannot use that Minecraft channel.").subscribe()
|
||||
return true
|
||||
|
|
|
@ -15,6 +15,7 @@ import discord4j.core.`object`.entity.channel.PrivateChannel
|
|||
))
|
||||
class MCChatCommand(private val module: MinecraftChatModule) extends ICommand2DC {
|
||||
@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) {
|
||||
sender.sendMessage("Using the private chat is not allowed on this Minecraft server.")
|
||||
return true
|
||||
|
|
|
@ -21,8 +21,8 @@ object MCChatCustom {
|
|||
var gid: String = null
|
||||
mcchannel match {
|
||||
case room: ChatRoom =>
|
||||
room.joinRoom(dcp)
|
||||
gid = if (groupid == null) mcchannel.getGroupID(dcp) else groupid
|
||||
room.joinRoom(dcp.getChromaUser)
|
||||
gid = if (groupid == null) mcchannel.getGroupID(dcp.getChromaUser) else groupid
|
||||
case _ =>
|
||||
gid = groupid
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ object MCChatCustom {
|
|||
if (lmd.channel.getId.asLong != channel.asLong) true
|
||||
else {
|
||||
lmd.mcchannel match {
|
||||
case room: ChatRoom => room.leaveRoom(lmd.dcp)
|
||||
case room: ChatRoom => room.leaveRoom(lmd.dcp.getChromaUser)
|
||||
case _ =>
|
||||
}
|
||||
false
|
||||
|
@ -58,6 +58,7 @@ object MCChatCustom {
|
|||
|
||||
def getCustomChats: List[CustomLMD] = lastmsgCustom.toList
|
||||
|
||||
// TODO: Store Chroma user only
|
||||
class CustomLMD private[mcchat](channel: MessageChannel, user: User, val groupID: String,
|
||||
mcchannel: Channel, val dcp: DiscordConnectedPlayer, var toggles: Int,
|
||||
var brtoggles: Set[TBMCSystemChatEvent.BroadcastTarget]) extends MCChatUtils.LastMsgData(channel, user, mcchannel) {
|
||||
|
|
|
@ -14,7 +14,9 @@ import discord4j.core.`object`.entity.{Member, Message, User}
|
|||
import discord4j.core.event.domain.message.MessageCreateEvent
|
||||
import discord4j.core.spec.EmbedCreateSpec
|
||||
import discord4j.core.spec.legacy.{LegacyEmbedCreateSpec, LegacyMessageEditSpec}
|
||||
import discord4j.rest.http.client.ClientException
|
||||
import discord4j.rest.util.Color
|
||||
import io.netty.handler.codec.http.HttpResponseStatus
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.{EventHandler, Listener}
|
||||
|
@ -88,22 +90,22 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
|
|||
time = se.getValue
|
||||
val authorPlayer: String = "[" + DPUtils.sanitizeStringNoEscape(e.getChannel.displayName.get) + "] " + //
|
||||
(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 embed = () => {
|
||||
val ecs = EmbedCreateSpec.builder()
|
||||
ecs.description(e.getMessage).color(Color.of(color.getRed, color.getGreen, color.getBlue))
|
||||
val url: String = module.profileURL.get
|
||||
e.getSender match {
|
||||
case player: Player =>
|
||||
DPUtils.embedWithHead(ecs, authorPlayer, e.getSender.getName,
|
||||
e.getUser match {
|
||||
case player: TBMCPlayer =>
|
||||
DPUtils.embedWithHead(ecs, authorPlayer, e.getUser.getName,
|
||||
if (url.nonEmpty) url + "?type=minecraft&id=" + player.getUniqueId else null)
|
||||
case dsender: DiscordSenderBase =>
|
||||
case dsender: DiscordPlayer =>
|
||||
ecs.author(authorPlayer,
|
||||
if (url.nonEmpty) url + "?type=discord&id=" + dsender.getUser.getId.asString else null,
|
||||
dsender.getUser.getAvatarUrl)
|
||||
if (url.nonEmpty) url + "?type=discord&id=" + dsender.getDiscordID else null,
|
||||
dsender.getDiscordUser.getAvatarUrl)
|
||||
case _ =>
|
||||
DPUtils.embedWithHead(ecs, authorPlayer, e.getSender.getName, null)
|
||||
DPUtils.embedWithHead(ecs, authorPlayer, e.getUser.getName, null)
|
||||
}
|
||||
ecs.timestamp(time)
|
||||
}
|
||||
|
@ -120,13 +122,25 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
|
|||
lastmsgdata.content = e.getMessage
|
||||
}
|
||||
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
|
||||
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
|
||||
// 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 (MCChatUtils.lastmsgdata == 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
|
||||
&& 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
|
||||
if (e.shouldSendTo(lmd.dcp)) { //Check original user's permissions
|
||||
if (e.shouldSendTo(lmd.dcp.getChromaUser)) { //Check original user's permissions
|
||||
doit(lmd)
|
||||
true
|
||||
}
|
||||
|
@ -370,8 +384,8 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
|
|||
}
|
||||
|
||||
if (event.getMessage.getType eq Message.Type.CHANNEL_PINNED_MESSAGE) {
|
||||
val mcchannel = if (clmd != null) clmd.mcchannel else dsender.getChromaUser.channel.get
|
||||
val rtr = mcchannel getRTR (if (clmd != null) clmd.dcp else dsender)
|
||||
val mcchannel = if (clmd != null) clmd.mcchannel else dsender.getChromaUser.getChannel.get
|
||||
val rtr = mcchannel getRTR (if (clmd != null) clmd.dcp.getChromaUser else user)
|
||||
TBMCChatAPI.SendSystemMessage(mcchannel, rtr, (dsender match {
|
||||
case player: Player => player.getDisplayName
|
||||
case _ => dsender.getName
|
||||
|
@ -379,9 +393,9 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
|
|||
false
|
||||
}
|
||||
else {
|
||||
val cmb = ChatMessage.builder(dsender, user, dmessage + getAttachmentText).fromCommand(false)
|
||||
val cmb = ChatMessage.builder(user, dmessage + getAttachmentText).fromCommand(false)
|
||||
if (clmd != null)
|
||||
TBMCChatAPI.sendChatMessage(cmb.permCheck(clmd.dcp).build, clmd.mcchannel)
|
||||
TBMCChatAPI.sendChatMessage(cmb.permCheck(clmd.dcp.getChromaUser).build, clmd.mcchannel)
|
||||
else
|
||||
TBMCChatAPI.sendChatMessage(cmb.build)
|
||||
true
|
||||
|
@ -422,8 +436,8 @@ class MCChatListener(val module: MinecraftChatModule) extends Listener {
|
|||
if (dsender.isInstanceOf[DiscordSender] && runCustomCommand(dsender, cmdlowercased)) {
|
||||
return ()
|
||||
}
|
||||
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 channel = if (clmd == null) user.getChannel.get else clmd.mcchannel
|
||||
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.getPluginManager.callEvent(ev)
|
||||
if (!ev.isCancelled)
|
||||
|
|
|
@ -27,14 +27,14 @@ object MCChatPrivate {
|
|||
val mcm = ComponentManager.getIfEnabled(classOf[MinecraftChatModule])
|
||||
if (start) {
|
||||
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)
|
||||
if (p == null) { // Player is offline - If the player is online, that takes precedence
|
||||
MCChatUtils.callLoginEvents(sender)
|
||||
}
|
||||
}
|
||||
else {
|
||||
val sender = MCChatUtils.removeSender(MCChatUtils.ConnectedSenders, channel.getId, user)
|
||||
val sender = MCChatUtils.removeSenderFrom(MCChatUtils.ConnectedSenders, channel.getId, user)
|
||||
assert(sender != null)
|
||||
Bukkit.getScheduler.runTask(DiscordPlugin.plugin, () => {
|
||||
def foo(): Unit = {
|
||||
|
@ -69,7 +69,7 @@ object MCChatPrivate {
|
|||
MCChatUtils.ConnectedSenders synchronized {
|
||||
for ((_, userMap) <- MCChatUtils.ConnectedSenders) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import buttondevteam.discordplugin.DPUtils.SpecExtensions
|
|||
import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule
|
||||
import buttondevteam.discordplugin.mcchat.MCChatCustom.CustomLMD
|
||||
import buttondevteam.discordplugin.mcchat.sender.{DiscordConnectedPlayer, DiscordPlayerSender, DiscordSender, DiscordSenderBase}
|
||||
import buttondevteam.lib.player.{ChromaGamerBase, TBMCPlayerBase}
|
||||
import buttondevteam.lib.{TBMCCoreAPI, TBMCSystemChatEvent}
|
||||
import com.google.common.collect.Sets
|
||||
import discord4j.common.util.Snowflake
|
||||
|
@ -35,7 +36,7 @@ import scala.collection.convert.ImplicitConversions.`map AsJavaMap`
|
|||
import scala.collection.mutable.ListBuffer
|
||||
import scala.jdk.CollectionConverters.{CollectionHasAsScala, SeqHasAsJava}
|
||||
import scala.jdk.javaapi.CollectionConverters.asScala
|
||||
import scala.jdk.javaapi.OptionConverters._
|
||||
import scala.jdk.javaapi.OptionConverters.*
|
||||
|
||||
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)
|
||||
}
|
||||
else {
|
||||
gid == lmd.mcchannel.getGroupID(p)
|
||||
gid == lmd.mcchannel.getGroupID(ChromaGamerBase.getFromSender(p))
|
||||
}
|
||||
).filter(MCChatUtils.checkEssentials) //If they can see it
|
||||
.filter(_ => C.incrementAndGet > 0) //Always true
|
||||
|
@ -102,10 +103,10 @@ object MCChatUtils {
|
|||
!ess.getUser(p).isHidden
|
||||
}
|
||||
|
||||
def addSender[T <: DiscordSenderBase](senders: concurrent.Map[String, ConcurrentHashMap[Snowflake, T]], user: User, sender: T): T =
|
||||
addSender(senders, user.getId.asString, sender)
|
||||
def addSenderTo[T <: DiscordSenderBase](senders: concurrent.Map[String, ConcurrentHashMap[Snowflake, T]], user: User, sender: T): T =
|
||||
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 map = if (mapOpt.isEmpty) new ConcurrentHashMap[Snowflake, T] else mapOpt.get
|
||||
map.put(sender.getChannel.getId, sender)
|
||||
|
@ -113,13 +114,13 @@ object MCChatUtils {
|
|||
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)
|
||||
if (mapOpt.nonEmpty) mapOpt.get.get(channel)
|
||||
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)
|
||||
if (mapOpt.nonEmpty) mapOpt.get.remove(channel)
|
||||
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.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
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
|
||||
val st = MCChatCustom.lastmsgCustom.filter(clmd => { //new TBMCChannelConnectFakeEvent(sender, clmd.mcchannel).shouldSendTo(clmd.dcp) - Thought it was this simple hehe - Wait, it *should* be this simple
|
||||
if (toggle != null && ((clmd.toggles & (1 << toggle.id)) == 0)) false //If null then allow
|
||||
else if (sender == null) true
|
||||
else clmd.groupID.equals(clmd.mcchannel.getGroupID(sender))
|
||||
else if (permUser == null) true
|
||||
else clmd.groupID.equals(clmd.mcchannel.getGroupID(permUser))
|
||||
}).map(cc => action.apply(Mono.just(cc.channel))) //TODO: Send error messages on channel connect
|
||||
//Mono.whenDelayError((() => st.iterator).asInstanceOf[java.lang.Iterable[Mono[_]]]) //Can't convert as an iterator or inside the stream, but I can convert it as a stream
|
||||
Mono.whenDelayError(st.asJava)
|
||||
|
@ -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.
|
||||
*
|
||||
* @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 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
|
||||
val cc = forAllowedCustomMCChat(action, sender, toggle)
|
||||
val cc = forAllowedCustomMCChat(action, permUser, toggle)
|
||||
if (!GeneralEventBroadcasterModule.isHooked || !hookmsg) return Mono.whenDelayError(forPublicPrivateChat(action), cc)
|
||||
Mono.whenDelayError(cc)
|
||||
}
|
||||
|
@ -195,7 +196,7 @@ object MCChatUtils {
|
|||
if (event.shouldSendTo(getSender(data.channel.getId, data.user)))
|
||||
list.append(action(Mono.just(data.channel))) //TODO: Only store ID?
|
||||
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 => {
|
||||
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.
|
||||
*/
|
||||
private[mcchat] def getSender(channel: Snowflake, author: User): DiscordSenderBase = { //noinspection OptionalGetWithoutIsPresent
|
||||
Option(getSender(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(getSender(UnconnectedSenders, channel, author))) //
|
||||
.orElse(Option(addSender(UnconnectedSenders, author,
|
||||
Option(getSenderFrom(OnlineSenders, channel, author)) // Find first non-null
|
||||
.orElse(Option(getSenderFrom(ConnectedSenders, channel, author))) // This doesn't support the public chat, but it'll always return null for it
|
||||
.orElse(Option(getSenderFrom(UnconnectedSenders, channel, author))) //
|
||||
.orElse(Option(addSenderTo(UnconnectedSenders, author,
|
||||
new DiscordSender(author, DiscordPlugin.dc.getChannelById(channel).block().asInstanceOf[MessageChannel]))))
|
||||
.get
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package buttondevteam.discordplugin.mcchat
|
|||
import buttondevteam.discordplugin.*
|
||||
import buttondevteam.discordplugin.mcchat.sender.{DiscordConnectedPlayer, DiscordPlayer, DiscordPlayerSender}
|
||||
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.core.`object`.entity.Role
|
||||
import discord4j.core.`object`.entity.channel.MessageChannel
|
||||
|
@ -36,8 +36,8 @@ class MCListener(val module: MinecraftChatModule) extends Listener {
|
|||
if (dp != null)
|
||||
DiscordPlugin.dc.getUserById(Snowflake.of(dp.getDiscordID)).flatMap(user =>
|
||||
user.getPrivateChannel.flatMap(chan => module.chatChannelMono.flatMap(cc => {
|
||||
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.addSenderTo(MCChatUtils.OnlineSenders, dp.getDiscordID, DiscordPlayerSender.create(user, chan, p, module))
|
||||
MCChatUtils.addSenderTo(MCChatUtils.OnlineSenders, dp.getDiscordID, DiscordPlayerSender.create(user, cc, p, module)) //Stored per-channel
|
||||
Mono.empty
|
||||
}))).subscribe()
|
||||
val message = e.getJoinMessage
|
||||
|
@ -51,7 +51,7 @@ class MCListener(val module: MinecraftChatModule) extends Listener {
|
|||
|
||||
private def sendJoinLeaveMessage(message: String, player: Player): Unit =
|
||||
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 = {
|
||||
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 =
|
||||
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 = {
|
||||
val base = e.getAffected.getBase
|
||||
if (e.isCancelled || !base.isOnline) return ()
|
||||
val msg = base.getDisplayName + " is " + (if (e.getValue) "now"
|
||||
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 = {
|
||||
|
|
|
@ -4,6 +4,7 @@ import buttondevteam.core.component.channel.Channel
|
|||
import buttondevteam.discordplugin.mcchat.sender.DiscordConnectedPlayer
|
||||
import buttondevteam.discordplugin.util.DPState
|
||||
import buttondevteam.discordplugin.{ChannelconBroadcast, DPUtils, DiscordPlugin}
|
||||
import buttondevteam.lib.architecture.config.IConfigData
|
||||
import buttondevteam.lib.architecture.{Component, ConfigData}
|
||||
import buttondevteam.lib.{TBMCCoreAPI, TBMCSystemChatEvent}
|
||||
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!
|
||||
*/
|
||||
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"))
|
||||
|
||||
/**
|
||||
* 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)
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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.
|
||||
* They can then use commands like /tpahere to teleport others to that place.<br />
|
||||
* 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.
|
||||
* 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.
|
||||
* 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).
|
||||
* 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.
|
||||
*/
|
||||
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 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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
* But it's really hacky.
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
package buttondevteam.discordplugin.mcchat.sender
|
||||
|
||||
import buttondevteam.discordplugin.DiscordPlugin
|
||||
import buttondevteam.discordplugin.mcchat.MCChatPrivate
|
||||
import buttondevteam.lib.player.{ChromaGamerBase, UserClass}
|
||||
import discord4j.common.util.Snowflake
|
||||
import discord4j.core.`object`.entity.User
|
||||
|
||||
@UserClass(foldername = "discord") class DiscordPlayer() extends ChromaGamerBase {
|
||||
private var did: String = null
|
||||
private var discordUser: User = null
|
||||
|
||||
// private @Getter @Setter boolean minecraftChatEnabled;
|
||||
def getDiscordID: String = {
|
||||
|
@ -12,6 +16,11 @@ import buttondevteam.lib.player.{ChromaGamerBase, UserClass}
|
|||
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
|
||||
* [[MCChatPrivate.privateMCChat]]
|
||||
|
|
|
@ -17,7 +17,7 @@ import java.util.UUID
|
|||
* @param user May 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 sendtask: BukkitTask = null
|
||||
|
||||
|
|
Loading…
Reference in a new issue