mirror of
				https://github.com/GayPizzaSpecifications/foundation.git
				synced 2025-11-04 03:39:37 +00:00 
			
		
		
		
	Bifrost: Debug mode, air-gap development mode, and fix chat message encoding.
This commit is contained in:
		@ -9,12 +9,13 @@ import net.dv8tion.jda.api.EmbedBuilder
 | 
				
			|||||||
import net.dv8tion.jda.api.JDA
 | 
					import net.dv8tion.jda.api.JDA
 | 
				
			||||||
import net.dv8tion.jda.api.JDABuilder
 | 
					import net.dv8tion.jda.api.JDABuilder
 | 
				
			||||||
import net.dv8tion.jda.api.MessageBuilder
 | 
					import net.dv8tion.jda.api.MessageBuilder
 | 
				
			||||||
 | 
					import net.dv8tion.jda.api.entities.Message
 | 
				
			||||||
import net.dv8tion.jda.api.entities.TextChannel
 | 
					import net.dv8tion.jda.api.entities.TextChannel
 | 
				
			||||||
import net.dv8tion.jda.api.events.GenericEvent
 | 
					import net.dv8tion.jda.api.events.GenericEvent
 | 
				
			||||||
import net.dv8tion.jda.api.events.ReadyEvent
 | 
					import net.dv8tion.jda.api.events.ReadyEvent
 | 
				
			||||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent
 | 
					import net.dv8tion.jda.api.events.message.MessageReceivedEvent
 | 
				
			||||||
import net.kyori.adventure.text.Component
 | 
					import net.kyori.adventure.text.Component
 | 
				
			||||||
import net.kyori.adventure.text.TextComponent
 | 
					import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
 | 
				
			||||||
import org.bukkit.event.EventHandler
 | 
					import org.bukkit.event.EventHandler
 | 
				
			||||||
import org.bukkit.event.EventPriority
 | 
					import org.bukkit.event.EventPriority
 | 
				
			||||||
import org.bukkit.event.entity.PlayerDeathEvent
 | 
					import org.bukkit.event.entity.PlayerDeathEvent
 | 
				
			||||||
@ -28,7 +29,7 @@ import org.bukkit.event.Listener as BukkitEventListener
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class FoundationBifrostPlugin : JavaPlugin(), DiscordEventListener, BukkitEventListener {
 | 
					class FoundationBifrostPlugin : JavaPlugin(), DiscordEventListener, BukkitEventListener {
 | 
				
			||||||
  private lateinit var config: BifrostConfig
 | 
					  private lateinit var config: BifrostConfig
 | 
				
			||||||
  private lateinit var jda: JDA
 | 
					  private var jda: JDA? = null
 | 
				
			||||||
  private var isDev = false
 | 
					  private var isDev = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  override fun onEnable() {
 | 
					  override fun onEnable() {
 | 
				
			||||||
@ -44,13 +45,12 @@ class FoundationBifrostPlugin : JavaPlugin(), DiscordEventListener, BukkitEventL
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
    config = Yaml.default.decodeFromStream(BifrostConfig.serializer(), configPath.inputStream())
 | 
					    config = Yaml.default.decodeFromStream(BifrostConfig.serializer(), configPath.inputStream())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    server.pluginManager.registerEvents(this, this)
 | 
				
			||||||
    if (config.authentication.token.isEmpty()) {
 | 
					    if (config.authentication.token.isEmpty()) {
 | 
				
			||||||
      slF4JLogger.warn("Token empty, will not start Bifrost.")
 | 
					      slF4JLogger.warn("Token empty, Bifrost will not connect to Discord.")
 | 
				
			||||||
      return
 | 
					      return
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    server.pluginManager.registerEvents(this, this)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    jda = JDABuilder
 | 
					    jda = JDABuilder
 | 
				
			||||||
      .createDefault(config.authentication.token)
 | 
					      .createDefault(config.authentication.token)
 | 
				
			||||||
      .addEventListeners(this)
 | 
					      .addEventListeners(this)
 | 
				
			||||||
@ -59,13 +59,13 @@ class FoundationBifrostPlugin : JavaPlugin(), DiscordEventListener, BukkitEventL
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  override fun onDisable() {
 | 
					  override fun onDisable() {
 | 
				
			||||||
    // Plugin was not initialized, don't do anything.
 | 
					    // Plugin was not initialized, don't do anything.
 | 
				
			||||||
    if (!::jda.isInitialized) return
 | 
					    if (jda == null) return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    onServerStop()
 | 
					    onServerStop()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    logger.info("Shutting down JDA")
 | 
					    logger.info("Shutting down JDA")
 | 
				
			||||||
    jda.shutdown()
 | 
					    jda?.shutdown()
 | 
				
			||||||
    while (jda.status != JDA.Status.SHUTDOWN) {
 | 
					    while (jda != null && jda!!.status != JDA.Status.SHUTDOWN) {
 | 
				
			||||||
      Thread.sleep(100)
 | 
					      Thread.sleep(100)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -78,7 +78,7 @@ class FoundationBifrostPlugin : JavaPlugin(), DiscordEventListener, BukkitEventL
 | 
				
			|||||||
      is MessageReceivedEvent -> {
 | 
					      is MessageReceivedEvent -> {
 | 
				
			||||||
        if (!config.channel.bridge) return
 | 
					        if (!config.channel.bridge) return
 | 
				
			||||||
        // Prevent this bot from receiving its own messages and creating a feedback loop.
 | 
					        // Prevent this bot from receiving its own messages and creating a feedback loop.
 | 
				
			||||||
        if (e.author.id == jda.selfUser.id) return
 | 
					        if (e.author.id == jda?.selfUser?.id) return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Only forward messages from the configured channel.
 | 
					        // Only forward messages from the configured channel.
 | 
				
			||||||
        if (e.channel.id != config.channel.id) return
 | 
					        if (e.channel.id != config.channel.id) return
 | 
				
			||||||
@ -91,8 +91,12 @@ class FoundationBifrostPlugin : JavaPlugin(), DiscordEventListener, BukkitEventL
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private fun getChannel(): TextChannel? {
 | 
					  private fun getTextChannel(): TextChannel? {
 | 
				
			||||||
    val channel = jda.getTextChannelById(config.channel.id)
 | 
					    if (jda == null) {
 | 
				
			||||||
 | 
					      return null
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    val channel = jda?.getTextChannelById(config.channel.id)
 | 
				
			||||||
    if (channel == null) {
 | 
					    if (channel == null) {
 | 
				
			||||||
      slF4JLogger.error("Failed to retrieve channel ${config.channel.id}")
 | 
					      slF4JLogger.error("Failed to retrieve channel ${config.channel.id}")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -104,69 +108,70 @@ class FoundationBifrostPlugin : JavaPlugin(), DiscordEventListener, BukkitEventL
 | 
				
			|||||||
    setEmbeds(EmbedBuilder().apply(f).build())
 | 
					    setEmbeds(EmbedBuilder().apply(f).build())
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private fun sendChannelMessage(message: Message, debug: () -> String) {
 | 
				
			||||||
 | 
					    val channel = getTextChannel()
 | 
				
			||||||
 | 
					    channel?.sendMessage(message)?.queue()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (config.enableDebugLog) {
 | 
				
			||||||
 | 
					      slF4JLogger.info("Send '${debug()}' to Discord")
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private fun sendChannelMessage(message: String): Unit = sendChannelMessage(message {
 | 
				
			||||||
 | 
					    setContent(message)
 | 
				
			||||||
 | 
					  }) { message }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private fun sendEmbedMessage(color: Color, message: String): Unit = sendChannelMessage(message {
 | 
				
			||||||
 | 
					    embed {
 | 
				
			||||||
 | 
					      setAuthor(message)
 | 
				
			||||||
 | 
					      setColor(color)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }) { "[rgb:${color.rgb}] $message" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @EventHandler(priority = EventPriority.MONITOR)
 | 
					  @EventHandler(priority = EventPriority.MONITOR)
 | 
				
			||||||
  private fun onPlayerJoin(e: PlayerJoinEvent) {
 | 
					  private fun onPlayerJoin(e: PlayerJoinEvent) {
 | 
				
			||||||
    if (!config.channel.sendPlayerJoin) return
 | 
					    if (!config.channel.sendPlayerJoin) return
 | 
				
			||||||
    val channel = getChannel() ?: return
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    channel.sendMessage(message {
 | 
					    sendEmbedMessage(Color.GREEN, "${e.player.name} joined the server")
 | 
				
			||||||
      embed {
 | 
					 | 
				
			||||||
        setAuthor("${e.player.name} joined the server")
 | 
					 | 
				
			||||||
        setColor(Color.GREEN)
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }).queue()
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @EventHandler(priority = EventPriority.MONITOR)
 | 
					  @EventHandler(priority = EventPriority.MONITOR)
 | 
				
			||||||
  private fun onPlayerQuit(e: PlayerQuitEvent) {
 | 
					  private fun onPlayerQuit(e: PlayerQuitEvent) {
 | 
				
			||||||
    if (!config.channel.sendPlayerQuit) return
 | 
					    if (!config.channel.sendPlayerQuit) return
 | 
				
			||||||
    val channel = getChannel() ?: return
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    channel.sendMessage(message {
 | 
					    sendEmbedMessage(Color.RED, "${e.player.name} left the server")
 | 
				
			||||||
      embed {
 | 
					 | 
				
			||||||
        setAuthor("${e.player.name} left the server")
 | 
					 | 
				
			||||||
        setColor(Color.RED)
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }).queue()
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @EventHandler(priority = EventPriority.MONITOR)
 | 
					  @EventHandler(priority = EventPriority.MONITOR)
 | 
				
			||||||
  private fun onPlayerChat(e: AsyncChatEvent) {
 | 
					  private fun onPlayerChat(e: AsyncChatEvent) {
 | 
				
			||||||
    if (!config.channel.bridge) return
 | 
					    if (!config.channel.bridge) return
 | 
				
			||||||
    val channel = getChannel() ?: return
 | 
					 | 
				
			||||||
    val message = e.message()
 | 
					    val message = e.message()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (message is TextComponent) {
 | 
					    val messageAsText = LegacyComponentSerializer.legacySection().serialize(message)
 | 
				
			||||||
      channel.sendMessage("${e.player.name}: ${message.content()}").queue()
 | 
					    sendChannelMessage("${e.player.name}: $messageAsText")
 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      slF4JLogger.error("Not sure what to do here, message != TextComponent: ${message.javaClass}")
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @EventHandler(priority = EventPriority.MONITOR)
 | 
					  @EventHandler(priority = EventPriority.MONITOR)
 | 
				
			||||||
  private fun onPlayerDeath(e: PlayerDeathEvent) {
 | 
					  private fun onPlayerDeath(e: PlayerDeathEvent) {
 | 
				
			||||||
    if (!config.channel.sendPlayerDeath) return
 | 
					    if (!config.channel.sendPlayerDeath) return
 | 
				
			||||||
    val channel = getChannel() ?: return
 | 
					    val deathMessage = e.deathMessage()
 | 
				
			||||||
 | 
					    val message = if (deathMessage != null) {
 | 
				
			||||||
    channel.sendMessage(message {
 | 
					      LegacyComponentSerializer.legacySection().serialize(deathMessage)
 | 
				
			||||||
      embed {
 | 
					    } else {
 | 
				
			||||||
        setAuthor("${e.player.name} died")
 | 
					      "died"
 | 
				
			||||||
        setColor(Color.RED)
 | 
					    }
 | 
				
			||||||
      }
 | 
					    sendEmbedMessage(Color.YELLOW, "${e.player.name} $message")
 | 
				
			||||||
    }).queue()
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private fun onDiscordReady() {
 | 
					  private fun onDiscordReady() {
 | 
				
			||||||
    if (!config.channel.sendStart) return
 | 
					    if (!config.channel.sendStart) return
 | 
				
			||||||
    val channel = getChannel() ?: return
 | 
					 | 
				
			||||||
    if (isDev) return
 | 
					    if (isDev) return
 | 
				
			||||||
    channel.sendMessage(":white_check_mark: Server is ready!").queue()
 | 
					    sendChannelMessage(":white_check_mark: Server is ready!")
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private fun onServerStop() {
 | 
					  private fun onServerStop() {
 | 
				
			||||||
    if (!config.channel.sendShutdown) return
 | 
					    if (!config.channel.sendShutdown) return
 | 
				
			||||||
    val channel = getChannel() ?: return
 | 
					 | 
				
			||||||
    if (isDev) return
 | 
					    if (isDev) return
 | 
				
			||||||
    channel.sendMessage(":octagonal_sign: Server is stopping!").queue()
 | 
					    sendChannelMessage(":octagonal_sign: Server is stopping!")
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -6,6 +6,7 @@ import kotlinx.serialization.Serializable
 | 
				
			|||||||
data class BifrostConfig(
 | 
					data class BifrostConfig(
 | 
				
			||||||
  val authentication: BifrostAuthentication,
 | 
					  val authentication: BifrostAuthentication,
 | 
				
			||||||
  val channel: BifrostChannel,
 | 
					  val channel: BifrostChannel,
 | 
				
			||||||
 | 
					  val enableDebugLog: Boolean = false
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Serializable
 | 
					@Serializable
 | 
				
			||||||
 | 
				
			|||||||
@ -18,4 +18,6 @@ channel:
 | 
				
			|||||||
  sendShutdown: true
 | 
					  sendShutdown: true
 | 
				
			||||||
  sendPlayerJoin: true
 | 
					  sendPlayerJoin: true
 | 
				
			||||||
  sendPlayerQuit: true
 | 
					  sendPlayerQuit: true
 | 
				
			||||||
  sendPlayerDeath: true
 | 
					
 | 
				
			||||||
 | 
					# Enables logging of what is sent to Discord.
 | 
				
			||||||
 | 
					enableDebugLog: false
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user